blob: 7a75cc8a2c0d22a11be6c1d3ec471b2d59208543 [file] [log] [blame]
developere0cea0f2021-12-16 16:08:26 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Distributed by:
4 * Silicon Laboratories, Inc
5 *
6 * This file contains proprietary information.
7 * No dissemination allowed without prior written permission from
8 * Silicon Laboratories, Inc.
9 *
10 * File Description:
11 * This is the generic interface file for the ProSLIC drivers.
12 *
13 * Customers should be calling this level for ProSLIC specific
14 * functions (vs. chipset specific versions of the code)
15 *
16 */
17
18#include "../config_inc/si_voice_datatypes.h"
19#include "../inc/si_voice_ctrl.h"
20#include "../inc/si_voice_timer_intf.h"
21#include "../inc/proslic.h"
22#include "../config_inc/proslic_api_config.h"
23
24#ifdef ENABLE_DEBUG
25#define LOGPRINT_PREFIX "ProSLIC:"
26#endif
27
28#ifdef SI3217X
29#include "si3217x.h"
30#include "si3217x_intf.h"
31extern Si3217x_General_Cfg Si3217x_General_Configuration;
32#ifndef DISABLE_FSK_SETUP
33extern ProSLIC_FSK_Cfg Si3217x_FSK_Presets[];
34#endif
35#ifndef DISABLE_TONE_SETUP
36extern ProSLIC_Tone_Cfg Si3217x_Tone_Presets[];
37#endif
38
39#endif /* 17X */
40
41#ifdef SI3218X
42#include "../inc/si3218x.h"
43#include "../inc/si3218x_intf.h"
44extern Si3218x_General_Cfg Si3218x_General_Configuration;
45#ifndef DISABLE_FSK_SETUP
46extern ProSLIC_FSK_Cfg Si3218x_FSK_Presets[];
47#endif
48#ifndef DISABLE_TONE_SETUP
49extern ProSLIC_Tone_Cfg Si3218x_Tone_Presets[];
50#endif
51#endif /* 18X */
52
53#ifdef SI3219X
54#include "si3219x.h"
55#include "si3219x_intf.h"
56extern Si3219x_General_Cfg Si3219x_General_Configuration;
57#ifndef DISABLE_FSK_SETUP
58extern ProSLIC_FSK_Cfg Si3219x_FSK_Presets[];
59#endif
60#ifndef DISABLE_TONE_SETUP
61extern ProSLIC_Tone_Cfg Si3219x_Tone_Presets[];
62#endif
63#endif /* 19X */
64
65#ifdef SI3226X
66#include "si3226x.h"
67#include "si3226x_intf.h"
68extern Si3226x_General_Cfg Si3226x_General_Configuration;
69#ifndef DISABLE_FSK_SETUP
70extern ProSLIC_FSK_Cfg Si3226x_FSK_Presets[];
71#endif
72#ifndef DISABLE_TONE_SETUP
73extern ProSLIC_Tone_Cfg Si3226x_Tone_Presets[];
74#endif
75#endif /* 26X */
76
77#ifdef SI3228X
78#include "si3228x.h"
79#include "si3228x_intf.h"
80extern Si3228x_General_Cfg Si3228x_General_Configuration;
81#ifndef DISABLE_FSK_SETUP
82extern ProSLIC_FSK_Cfg Si3228x_FSK_Presets[];
83#endif
84#ifndef DISABLE_TONE_SETUP
85extern ProSLIC_Tone_Cfg Si3228x_Tone_Presets[];
86#endif
87
88#endif /* 28X */
89
90#define pCtrl(X) (X)->deviceId->ctrlInterface
91#define pProHW(X) pCtrl((X))->hCtrl
92#define WriteRAM(PCHAN, CHANNEL, RAMADDR, RAMDATA) (PCHAN)->deviceId->ctrlInterface->WriteRAM_fptr(pProHW(PCHAN), (CHANNEL), (RAMADDR), (RAMDATA))
93#define ReadRAM(PCHAN, CHANNEL, RAMADDR) (PCHAN)->deviceId->ctrlInterface->ReadRAM_fptr(pProHW(PCHAN), (CHANNEL), (RAMADDR))
94#define SetSemaphore(X) (X)->deviceId->ctrlInterface->Semaphore_fptr
95#define ReadReg(PCHAN, CHANNEL, REGADDR) (PCHAN)->deviceId->ctrlInterface->ReadRegister_fptr(pProHW(PCHAN), (CHANNEL), (REGADDR))
96#define WriteReg(PCHAN, CHANNEL, REGADDR, REGDATA) (PCHAN)->deviceId->ctrlInterface->WriteRegister_fptr(pProHW(PCHAN), (CHANNEL), (REGADDR), (REGDATA))
97
98/*
99** Timers
100*/
101#define TimeElapsed pProslic->deviceId->ctrlInterface->timeElapsed_fptr
102#define getTime pProslic->deviceId->ctrlInterface->getTime_fptr
103#define pProTimer pProslic->deviceId->ctrlInterface->hTimer
104#define Delay pProslic->deviceId->ctrlInterface->Delay_fptr
105#define pProTimerX(X) ((X)->deviceId->ctrlInterface->hTimer)
106#define DelayX(X,Y) ((X)->deviceId->ctrlInterface->Delay_fptr(pProTimerX(X),Y))
107
108#define PROSLIC_TIMEOUT_DCDC_DOWN 200 /* Number of 10 mSec ticks */
109
110/*****************************************************************************************************/
111int32 ProSLIC_ReadMADCScaled(proslicChanType_ptr hProslic,uInt16 addr,
112 int32 scale)
113{
114 TRACEPRINT(hProslic,"addr: %u scale: %ld\n", addr, scale);
115#ifdef SI3217X
116 if (hProslic->deviceId->chipType >= SI32171
117 && hProslic->deviceId->chipType <= SI32179)
118 {
119 return Si3217x_ReadMADCScaled(hProslic,addr,scale);
120 }
121#endif
122
123#ifdef SI3218X
124 if (hProslic->deviceId->chipType >= SI32180
125 && hProslic->deviceId->chipType <= SI32189)
126 {
127 return Si3218x_ReadMADCScaled(hProslic,addr,scale);
128 }
129#endif
130
131#ifdef SI3219X
132 if ( IS_SI3219X(hProslic->deviceId) )
133 {
134 return Si3219x_ReadMADCScaled(hProslic,addr,scale);
135 }
136#endif
137
138#ifdef SI3226X
139 if (hProslic->deviceId->chipType >= SI32260
140 && hProslic->deviceId->chipType <= SI32269)
141 {
142 return Si3226x_ReadMADCScaled(hProslic,addr,scale);
143 }
144#endif
145
146#ifdef SI3228X
147 if (hProslic->deviceId->chipType >= SI32280
148 && hProslic->deviceId->chipType <= SI32289)
149 {
150 return Si3228x_ReadMADCScaled(hProslic,addr,scale);
151 }
152#endif
153
154 return -1;
155}
156
157/*****************************************************************************************************/
158ramData ProSLIC_ReadRAM(proslicChanType_ptr hProslic,uInt16 addr)
159{
160 TRACEPRINT(hProslic, "addr: %u\n", addr);
161 if(hProslic->channelType != PROSLIC)
162 {
163 return RC_IGNORE;
164 }
165 return (ReadRAM(hProslic, hProslic->channel, addr));
166}
167
168/*****************************************************************************************************/
169int ProSLIC_WriteRAM(proslicChanType_ptr hProslic,uInt16 addr, ramData data)
170{
171 TRACEPRINT(hProslic, "addr: %u data: 0x%04X\n", addr, data);
172 if(hProslic->channelType != PROSLIC)
173 {
174 return RC_IGNORE;
175 }
176 return (WriteRAM(hProslic, hProslic->channel, addr,data));
177}
178
179/*****************************************************************************************************/
180int ProSLIC_PrintDebugData(proslicChanType_ptr hProslic)
181{
182 TRACEPRINT(hProslic, "\n", NULL);
183#ifdef ENABLE_DEBUG
184 ProSLIC_PrintDebugReg(hProslic);
185 return ProSLIC_PrintDebugRAM(hProslic);
186#else
187 SILABS_UNREFERENCED_PARAMETER(hProslic);
188 return RC_NONE;
189#endif
190}
191
192/*****************************************************************************************************/
193int ProSLIC_PrintDebugReg(proslicChanType_ptr hProslic)
194{
195#ifdef ENABLE_DEBUG
196 uInt8 regAddr;
197 TRACEPRINT(hProslic, "\n", NULL);
198
199 /*
200 NOTE: Not all ProSLICs have defined values after location 99
201 (and have 1 location after that), but for simplicity, we print them anyway...
202 */
203 for(regAddr = 0; regAddr < 127; regAddr++)
204 {
205 LOGPRINT("%sRegister %03u = 0x%02X\n", LOGPRINT_PREFIX, regAddr,
206 ReadReg(hProslic, hProslic->channel, regAddr));
207 }
208#else
209 SILABS_UNREFERENCED_PARAMETER(hProslic);
210#endif
211
212 return RC_NONE;
213}
214
215/*****************************************************************************************************/
216/* NOTE: locations above 1024 are protected, the API disables protection during initialization, but if this
217 function is called prior to initialization, then UAM is not set and will impact the ReadRAM call...
218 Upper limit is based upon chipset type...
219*/
220int ProSLIC_PrintDebugRAM(proslicChanType_ptr hProslic)
221{
222#ifdef ENABLE_DEBUG
223 uInt16 ramAddr;
224 uInt16 maxAddr= 0;
225 TRACEPRINT(hProslic, "\n",NULL);
226
227 if(hProslic->channelType != PROSLIC)
228 {
229 return RC_IGNORE;
230 }
231
232#ifdef SI3217X
233 if (hProslic->deviceId->chipType >= SI32171
234 && hProslic->deviceId->chipType <= SI32179)
235 {
236 maxAddr = 1596;
237 }
238#endif
239
240#ifdef SI3218X
241 if (hProslic->deviceId->chipType >= SI32180
242 && hProslic->deviceId->chipType <= SI32189)
243 {
244 maxAddr = 1644;
245 }
246#endif
247
248#ifdef SI3219X
249 if ( IS_SI3219X(hProslic->deviceId) )
250 {
251 maxAddr = 1644;
252 }
253#endif
254
255#ifdef SI3226X
256 if (hProslic->deviceId->chipType >= SI32260
257 && hProslic->deviceId->chipType <= SI32269)
258 {
259 maxAddr = 1646;
260 }
261#endif
262
263#ifdef SI3228X
264 if (hProslic->deviceId->chipType >= SI32280
265 && hProslic->deviceId->chipType <= SI32289)
266 {
267 maxAddr = 1646;
268 }
269#endif
270
271 for(ramAddr = 0; ramAddr < maxAddr; ramAddr++)
272 {
273 LOGPRINT("%sRAM %04u = 0x%08X\n", LOGPRINT_PREFIX, ramAddr,
274 (unsigned int)(ReadRAM(hProslic, hProslic->channel, ramAddr)));
275 }
276#else
277 SILABS_UNREFERENCED_PARAMETER(hProslic);
278#endif /* ENABLE_DEBUG */
279 return RC_NONE;
280}
281
282/*****************************************************************************************************/
283/*
284** Function: isVerifiedProslic
285**
286** Description:
287** Determine if DAA or ProSLIC present
288**
289** Input Parameters:
290** pProslic: pointer to PROSLIC channel object
291**
292** Return:
293** channelType
294*/
295int ProSLIC_identifyChannelType(proslicChanType *pProslic)
296{
297 uInt8 data;
298 TRACEPRINT(pProslic, "\n",NULL);
299 /*
300 ** Register 13 (DAA) always has bits 0:1 set to 0 and bit 6 set to 1
301 ** Register 13 (PROSLIC) can have bits 0:1, and 4 set, while all others are undefined
302 ** Write 0x13 to Reg 13. The following return values are expected -
303 **
304 ** 0x00 or 0xFF : No device present
305 ** 0x4X : DAA
306 ** 0x13 : PROSLIC
307 */
308
309 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI,0x13);
310 Delay(pProTimer,5);
311
312 /* Now check if the value took */
313 data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI);
314
315 if( data == 0x13)
316 {
317 return PROSLIC;
318 }
319 else if (data == 0x40)
320 {
321 return DAA;
322 }
323 else
324 {
325 return UNKNOWN;
326 }
327}
328
329/*****************************************************************************************************/
330int ProSLIC_VerifyControlInterface(proslicChanType_ptr hProslic)
331{
332 TRACEPRINT(hProslic, "\n",NULL);
333 if (ProSLIC_identifyChannelType(hProslic) != PROSLIC)
334 {
335 return RC_CHANNEL_TYPE_ERR;
336 }
337
338 /* Note: ProSLIC_identifyChannelType() did a register w/r test earlier */
339
340 /* Verify RAM rd/wr with innocuous RAM location */
341 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VERIFY_IO,0x12345678L);
342 if (ReadRAM(hProslic,hProslic->channel, PROSLIC_RAM_VERIFY_IO) != 0x12345678L)
343 {
344 hProslic->error = RC_SPI_FAIL;
345 DEBUG_PRINT(hProslic, "%sProslic %d RAM not communicating. RAM access fail.\n",
346 LOGPRINT_PREFIX, hProslic->channel);
347 return RC_SPI_FAIL;
348 }
349 return RC_NONE;
350}
351
352/*****************************************************************************************************/
353int ProSLIC_VerifyMasterStat(proslicChanType_ptr pProslic)
354{
355 uInt8 regData;
356
357 TRACEPRINT(pProslic, "\n", NULL);
358 WriteReg(pProslic,pProslic->channel, PROSLIC_REG_MSTRSTAT,
359 0xFF); /* Clear Master status */
360 regData = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_MSTRSTAT);
361
362 if( regData != 0x1F )
363 {
364 return RC_SPI_FAIL;
365 }
366 else
367 {
368 return RC_NONE;
369 }
370}
371
372/*****************************************************************************************************/
373#ifdef SIVOICE_MULTI_BOM_SUPPORT
374int ProSLIC_Init_MultiBOM (proslicChanType_ptr *hProslic,int size, int preset)
375{
376 TRACEPRINT(*hProslic, "size: %d preset: %d\n", size, preset);
377#ifdef SI3217X
378 if ((*hProslic)->deviceId->chipType >= SI32171
379 && (*hProslic)->deviceId->chipType <= SI32179)
380 {
381 return Si3217x_Init_MultiBOM(hProslic,size,preset);
382 }
383#endif
384
385#ifdef SI3218X
386 if ((*hProslic)->deviceId->chipType >= SI32180
387 && (*hProslic)->deviceId->chipType <= SI32189)
388 {
389 return Si3218x_Init_MultiBOM(hProslic,size,preset);
390 }
391#endif
392
393#ifdef SI3219X
394 if ( IS_SI3219X((*hProslic)->deviceId) )
395 {
396 return Si3219x_Init_MultiBOM(hProslic,size,preset);
397 }
398#endif
399
400#ifdef SI3226X
401 if ((*hProslic)->deviceId->chipType >= SI32260
402 && (*hProslic)->deviceId->chipType <= SI32269)
403 {
404 return Si3226x_Init_MultiBOM(hProslic,size,preset);
405 }
406#endif
407
408#ifdef SI3228X
409 if ((*hProslic)->deviceId->chipType >= SI32280
410 && (*hProslic)->deviceId->chipType <= SI32289)
411 {
412 return Si3228x_Init_MultiBOM(hProslic,size,preset);
413 }
414#endif
415
416 return RC_COMPLETE_NO_ERR;
417}
418#endif
419
420/*****************************************************************************************************/
421int ProSLIC_Init (proslicChanType_ptr *hProslic,int size)
422{
423 TRACEPRINT(*hProslic, "size: %d\n", size);
424 return ProSLIC_Init_with_Options(hProslic, size, INIT_NO_OPT);
425}
426
427/*****************************************************************************************************/
428int ProSLIC_Reinit (proslicChanType_ptr *hProslic,int size)
429{
430 TRACEPRINT(*hProslic, "size: %d\n", size);
431 return ProSLIC_Init_with_Options(hProslic, size, INIT_REINIT);
432}
433
434/*****************************************************************************************************/
435int ProSLIC_Init_with_Options (proslicChanType_ptr *hProslic,int size,
436 int option)
437{
438 TRACEPRINT(*hProslic, "size: %d option: %d\n", size, option);
439#ifdef SI3226X
440 if ((*hProslic)->deviceId->chipType >= SI32260
441 && (*hProslic)->deviceId->chipType <= SI32269)
442 {
443 return Si3226x_Init_with_Options(hProslic,size, option);
444 }
445#endif
446
447#ifdef SI3228X
448 if ((*hProslic)->deviceId->chipType >= SI32280
449 && (*hProslic)->deviceId->chipType <= SI32289)
450 {
451 return Si3228x_Init_with_Options(hProslic,size, option);
452 }
453#endif
454
455#ifdef SI3217X
456 if ((*hProslic)->deviceId->chipType >= SI32171
457 && (*hProslic)->deviceId->chipType <= SI32179)
458 {
459 return Si3217x_Init_with_Options(hProslic,size, option);
460 }
461#endif
462
463#ifdef SI3218X
464 if ((*hProslic)->deviceId->chipType >= SI32180
465 && (*hProslic)->deviceId->chipType <= SI32189)
466 {
467 return Si3218x_Init_with_Options(hProslic,size, option);
468 }
469#endif
470
471#ifdef SI3219X
472 if ( IS_SI3219X((*hProslic)->deviceId) )
473 {
474 return Si3219x_Init_with_Options(hProslic,size, option);
475 }
476#endif
477
478 return RC_IGNORE;
479}
480
481/*****************************************************************************************************/
482#if defined(SI3217X) || defined(SI3218X) || defined SI3226X || defined SI3228X || defined(SI3219X)
483/* Check patch data - returns TRUE if no error.*/
484static BOOLEAN ProSLIC_VerifyPatchData(proslicChanType *pProslic,
485 const ramData *data, uInt16 maxCount )
486{
487 int loop;
488 ramData read_data;
489 TRACEPRINT(pProslic, "dataptr: %p, count: %d\n", data, maxCount);
490
491 for(loop = 0; loop < maxCount; loop++)
492 {
493 if(*data)
494 {
495 read_data = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_PRAM_DATA);
496 if( ((*data) << 9) != read_data)
497 {
498 return FALSE;
499 }
500 }
501 else
502 {
503 break;
504 }
505 data++;
506 }
507 return TRUE;
508}
509
510/* Check if the jump table is written correctly.. */
511static BOOLEAN ProSLIC_VerifyPatchJMPLow(proslicChanType *pProslic,
512 const uInt16 *data)
513{
514 uInt8 address = PATCH_JMPTBL_START_ADDR;
515 int regData;
516
517 TRACEPRINT(pProslic, "dataptr: %p\n", data);
518 for(address = PATCH_JMPTBL_START_ADDR;
519 address < (PATCH_JMPTBL_START_ADDR+(2*PATCH_NUM_LOW_ENTRIES)); address++)
520 {
521 if(*data)
522 {
523 regData = ReadReg(pProslic, pProslic->channel, address);
524 if(regData != ((*data) & 0xFF))
525 {
526 return FALSE;
527 }
528
529 address++;
530
531 regData = ReadReg(pProslic, pProslic->channel, address);
532 if(regData != (((*data)>>8) & 0xFF))
533 {
534 return FALSE;
535 }
536
537 data++;
538 }
539 else
540 {
541 break;
542 }
543 }
544 return TRUE;
545}
546
547#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
548/* For chipsets supporting more than 8 jump entries, verify them */
549static BOOLEAN ProSLIC_VerifyPatchJMPHigh(proslicChanType *pProslic,
550 const uInt16 *data)
551{
552 uInt16 address = PATCH_JMPTBL_HIGH_ADDR;
553 ramData read_data;
554
555 TRACEPRINT(pProslic, "dataptr: %p\n", data);
556 for(address = PATCH_JMPTBL_HIGH_ADDR;
557 address < (PATCH_JMPTBL_HIGH_ADDR+PATCH_NUM_HIGH_ENTRIES); address++)
558 {
559 read_data = (ReadRAM(pProslic, pProslic->channel, address) & 0x1FFFL);
560 if(*data != read_data)
561 {
562 return FALSE;
563
564 }
565 data++;
566 }
567 return TRUE;
568}
569#endif /* SI3226X, SI3228X, SI3218X, SI3219X */
570
571static BOOLEAN ProSLIC_VerifyPatchSupportRAM(proslicChanType *pProslic,
572 const uInt16 *ramAddr, const ramData *ramData)
573{
574 int i;
575
576 for(i = 0; ramAddr[i]; i++)
577 {
578 if( ReadRAM(pProslic, pProslic->channel, ramAddr[i]) != ramData[i])
579 {
580 return FALSE;
581 }
582 }
583
584 return TRUE;
585}
586
587/* Load the first 8 jump table entries */
588static void ProSLIC_LoadPatchJMPLow(proslicChanType *pProslic, uInt8 channel,
589 const uInt16 *data)
590{
591 uInt8 address;
592
593 TRACEPRINT(pProslic, "chan: %d dataptr: %p\n", channel, data);
594
595 for(address = PATCH_JMPTBL_START_ADDR;
596 address < (PATCH_JMPTBL_START_ADDR+(2*PATCH_NUM_LOW_ENTRIES)); address++)
597 {
598 WriteReg(pProslic, channel, address,((*data) & 0xFF));
599 address++;
600 WriteReg(pProslic, channel, address,(((*data)>>8) & 0xFF));
601 data++;
602 }
603}
604
605/* Load Patch data */
606static void ProSLIC_LoadPatchData(proslicChanType *pProslic, uInt8 channel,
607 const ramData *data)
608{
609 int loop;
610
611 TRACEPRINT(pProslic, "chan: %d dataptr: %p\n", channel, data);
612 WriteRAM(pProslic, channel, PROSLIC_RAM_PRAM_ADDR, 0);
613
614 for(loop = 0; loop < PATCH_MAX_SIZE; loop++)
615 {
616 if(*data)
617 {
618 /* Can we take advantage of auto increment, if not, set the address */
619 if( (pProslic->deviceId->chipRev < 3)
620 && (channel == PROSLIC_CHAN_BROADCAST))
621 {
622 WriteRAM(pProslic, channel, PROSLIC_RAM_PRAM_ADDR, loop << 19);
623 }
624
625 WriteRAM(pProslic, channel, PROSLIC_RAM_PRAM_DATA, (*data) << 9);
626 }
627 else
628 {
629 return;
630 }
631 data++;
632 }
633}
634
635/* Load Support RAM - basically RAM address/data pairs to be written as part of the Patch process - do not call directly */
636void ProSLIC_LoadSupportRAM(proslicChanType *pProslic, uInt8 channel,
637 const uInt16 *address, const ramData *data)
638{
639 TRACEPRINT(pProslic, "chan: %d addressptr: %p dataptr: %p\n", channel, address,
640 data);
641 while( *address )
642 {
643 WriteRAM(pProslic, channel, *address, *data);
644 address++;
645 data++;
646 }
647}
648
649#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
650/* Load Jump table high for chipsets supporting more than 8 jump entries */
651static void ProSLIC_LoadJMPHigh(proslicChanType *pProslic, uInt8 channel,
652 const uInt16 *data)
653{
654 uInt16 loop;
655 TRACEPRINT(pProslic, "chan: %d dataptr: %p\n", channel, data);
656 for(loop = PATCH_JMPTBL_HIGH_ADDR;
657 loop < (PATCH_JMPTBL_HIGH_ADDR+PATCH_NUM_HIGH_ENTRIES); loop++)
658 {
659 WriteRAM(pProslic, channel, loop, ((*data) & 0x1FFFL) );
660 data++;
661 }
662}
663#endif /* SI3226X, SI3228X, SI3218X, SI3219X */
664
665/* Code assumes ProSLIC_LoadPatch has verified chip type. This is NOT meant to be called
666 * by the user directly.
667 */
668BOOLEAN ProSLIC_LoadPatch_extended(proslicChanType *pProslic,
669 const proslicPatch *pPatch,
670 BOOLEAN is_broadcast, BOOLEAN is_second_chan)
671{
672 uInt8 channel;
673 const uInt16 jmp_disable[PATCH_NUM_LOW_ENTRIES] = {0,0,0,0,0,0,0,0};
674
675#if defined SI3226X || defined SI3228X || defined SI3218X ||defined SI3219X
676 BOOLEAN hasJmpTableHigh = FALSE;
677 const uInt16 jmphigh_disable[PATCH_NUM_HIGH_ENTRIES] = {0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL};
678#endif
679
680 TRACEPRINT(pProslic, "patchptr: %p bcast: %d\n", pPatch, is_broadcast);
681
682 if(pPatch == NULL)
683 {
684 return RC_NONE;
685 }
686
687 if(is_broadcast == TRUE)
688 {
689 channel = PROSLIC_CHAN_BROADCAST;
690 }
691 else
692 {
693 channel = pProslic->channel;
694 }
695
696 ProSLIC_SetUserMode(pProslic,TRUE, is_broadcast);
697
698 /* Disable Patch */
699 WriteReg(pProslic, channel, PROSLIC_REG_JMPEN, 0);
700 if(is_second_chan == FALSE)
701 {
702 DEBUG_PRINT(pProslic, "%sloading patch: %08lx\n", LOGPRINT_PREFIX,
703 (long unsigned int)pPatch->patchSerial);
704
705 ProSLIC_LoadPatchJMPLow(pProslic, channel, jmp_disable);
706
707#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
708 if( 0
709#ifdef SI3226X
710 || (pProslic->deviceId->chipType >= SI32260
711 && pProslic->deviceId->chipType <= SI32269)
712#endif
713#ifdef SI3228X
714 || (pProslic->deviceId->chipType >= SI32280
715 && pProslic->deviceId->chipType <= SI32289)
716#endif
717#ifdef SI3218X
718 || (pProslic->deviceId->chipType >= SI32180
719 && pProslic->deviceId->chipType <= SI32189)
720#endif
721#ifdef SI3219X
722 || ( IS_SI3219X(pProslic->deviceId) )
723#endif
724 )
725 {
726 hasJmpTableHigh = TRUE;
727 ProSLIC_LoadJMPHigh(pProslic, channel, jmphigh_disable);
728 }
729#endif
730
731 ProSLIC_LoadPatchData(pProslic, channel, pPatch->patchData);
732
733 WriteReg(pProslic, channel, PROSLIC_REG_RAM_ADDR_HI, 0);
734
735 ProSLIC_LoadPatchJMPLow(pProslic, channel, pPatch->patchEntries);
736
737#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
738 if(hasJmpTableHigh == TRUE)
739 {
740 ProSLIC_LoadJMPHigh(pProslic, channel,
741 &(pPatch->patchEntries[PATCH_NUM_LOW_ENTRIES]));
742 }
743#endif
744 WriteRAM(pProslic, channel, PROSLIC_RAM_PATCHID,
745 pPatch->patchSerial); /* write the patch ID */
746 } /* !second channel */
747
748 ProSLIC_LoadSupportRAM(pProslic, channel, pPatch->psRamAddr, pPatch->psRamData);
749
750 return RC_NONE;
751
752}
753
754#endif /* patch helper functions */
755
756int ProSLIC_LoadPatch (proslicChanType_ptr pProslic,const proslicPatch *pPatch)
757{
758 int rc;
759
760 if(pProslic->channelType != PROSLIC)
761 {
762 return RC_IGNORE;
763 }
764
765 if( (rc = ProSLIC_LoadPatch_extended(pProslic, pPatch, FALSE, FALSE) ) == RC_NONE)
766 {
767#ifdef DISABLE_VERIFY_PATCH
768 return WriteReg(pProslic, pProslic->channel, PROSLIC_REG_JMPEN, 1);
769#endif
770 }
771
772 return rc;
773}
774
775/*****************************************************************************************************/
776int ProSLIC_VerifyPatch (proslicChanType_ptr hProslic,const proslicPatch *pPatch)
777{
778 TRACEPRINT(hProslic, "patchptr: %p\n", pPatch);
779 if(hProslic->channelType != PROSLIC)
780 {
781 return RC_IGNORE;
782 }
783 if(pPatch == NULL)
784 {
785 return RC_NONE;
786 }
787
788 WriteReg(hProslic, hProslic->channel, PROSLIC_REG_JMPEN, 0);
789 WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PRAM_ADDR, 0);
790
791 if(ProSLIC_VerifyPatchData(hProslic, pPatch->patchData,
792 PATCH_MAX_SIZE) == FALSE)
793 {
794 DEBUG_PRINT(hProslic, "%sPatch data corrupted: channel %d\n",LOGPRINT_PREFIX,
795 hProslic->channel);
796 WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
797 0UL); /* Mark patch as invalid */
798 return RC_PATCH_RAM_VERIFY_FAIL;
799 }
800
801 /*zero out RAM_ADDR_HI*/
802 WriteReg (hProslic, hProslic->channel, PROSLIC_REG_RAM_ADDR_HI,0);
803
804 if( ProSLIC_VerifyPatchJMPLow(hProslic, pPatch->patchEntries) == FALSE)
805 {
806 DEBUG_PRINT(hProslic,"%sPatch jumptable corrupted: channel %d\n",
807 LOGPRINT_PREFIX,hProslic->channel);
808 WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
809 0UL); /* Mark patch as invalid */
810 return RC_PATCH_RAM_VERIFY_FAIL;
811 }
812
813#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
814 if( 0
815#ifdef SI3226X
816 || (hProslic->deviceId->chipType >= SI32260
817 && hProslic->deviceId->chipType <= SI32269)
818#endif
819#ifdef SI3228X
820 || (hProslic->deviceId->chipType >= SI32280
821 && hProslic->deviceId->chipType <= SI32289)
822#endif
823#ifdef SI3218X
824 || (hProslic->deviceId->chipType >= SI32180
825 && hProslic->deviceId->chipType <= SI32189)
826#endif
827#ifdef SI3219X
828 || ( IS_SI3219X(hProslic->deviceId) )
829#endif
830 )
831
832 {
833 if( ProSLIC_VerifyPatchJMPHigh(hProslic,
834 &(pPatch->patchEntries[PATCH_NUM_LOW_ENTRIES])) == FALSE)
835 {
836 DEBUG_PRINT(hProslic,"%sPatch jumptable high corrupted: channel %d\n",
837 LOGPRINT_PREFIX,hProslic->channel);
838 WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
839 0UL); /* Mark patch as invalid */
840 return RC_PATCH_ENTRY_VERIFY_FAIL;
841 }
842 }
843
844#endif
845
846 if( ProSLIC_VerifyPatchSupportRAM( hProslic, pPatch->psRamAddr, pPatch->psRamData) == FALSE)
847 {
848 DEBUG_PRINT(hProslic,"%sPatch init data corrupted: channel %d\n",
849 LOGPRINT_PREFIX,hProslic->channel);
850 WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
851 0UL); /* Mark patch as invalid */
852 return RC_PATCH_ENTRY_VERIFY_FAIL;
853 }
854
855 WriteReg (hProslic, hProslic->channel, PROSLIC_REG_JMPEN,
856 1); /*enable the patch*/
857
858 return RC_NONE;
859}
860
861/*****************************************************************************************************/
862int ProSLIC_SetMuteStatus (proslicChanType_ptr pProslic,
863 ProslicMuteModes muteEn)
864{
865
866 uInt8 regTemp;
867 uInt8 newRegValue;
868 TRACEPRINT(pProslic, "muteEn: %d\n", muteEn);
869
870 if(pProslic->channelType != PROSLIC)
871 {
872 return RC_IGNORE;
873 }
874
875 regTemp = ReadReg (pProslic,pProslic->channel,PROSLIC_REG_DIGCON);
876
877 WriteReg (pProslic,pProslic->channel,PROSLIC_REG_DIGCON,regTemp&~(0x3));
878 newRegValue = regTemp &~(0x3);
879
880 if (muteEn & PROSLIC_MUTE_RX)
881 {
882 newRegValue |= 1;
883 }
884
885 if (muteEn & PROSLIC_MUTE_TX)
886 {
887 newRegValue |= 2;
888 }
889
890 if(newRegValue != regTemp)
891 {
892 return WriteReg (pProslic,pProslic->channel,PROSLIC_REG_DIGCON,newRegValue);
893 }
894
895 return RC_COMPLETE_NO_ERR;
896}
897
898/*****************************************************************************************************/
899int ProSLIC_SetLoopbackMode (proslicChanType_ptr pProslic,
900 ProslicLoopbackModes newMode)
901{
902 uInt8 regTemp, newValue;
903 TRACEPRINT(pProslic, "mode: %d\n", newMode);
904
905 if(pProslic->channelType != PROSLIC)
906 {
907 return RC_IGNORE;
908 }
909
910 newValue = regTemp = ReadReg (pProslic,pProslic->channel,PROSLIC_REG_LOOPBACK);
911
912 switch (newMode)
913 {
914 case PROSLIC_LOOPBACK_NONE:
915 newValue &= ~(0x11);
916 break;
917
918 case PROSLIC_LOOPBACK_DIG:
919 newValue |= 1;
920 break;
921
922 case PROSLIC_LOOPBACK_ANA:
923 newValue |= 0x10;
924 break;
925 }
926
927 if(newValue != regTemp)
928 {
929 return WriteReg (pProslic,pProslic->channel,PROSLIC_REG_LOOPBACK, newValue);
930 }
931 return RC_COMPLETE_NO_ERR;
932}
933
934/*****************************************************************************************************/
935int ProSLIC_EnableInterrupts (proslicChanType_ptr hProslic)
936{
937 TRACEPRINT(hProslic, "\n", NULL);
938 if(hProslic->channelType != PROSLIC)
939 {
940 return RC_IGNORE;
941 }
942#ifdef SI3217X
943 if (hProslic->deviceId->chipType >= SI32171
944 && hProslic->deviceId->chipType <= SI32179)
945 {
946 return Si3217x_EnableInterrupts(hProslic);
947 }
948#endif
949
950#ifdef SI3218X
951 if (hProslic->deviceId->chipType >= SI32180
952 && hProslic->deviceId->chipType <= SI32189)
953 {
954 return Si3218x_EnableInterrupts(hProslic);
955 }
956#endif
957
958#ifdef SI3219X
959 if ( IS_SI3219X(hProslic->deviceId) )
960 {
961 return Si3219x_EnableInterrupts(hProslic);
962 }
963#endif
964
965#ifdef SI3226X
966 if (hProslic->deviceId->chipType >= SI32260
967 && hProslic->deviceId->chipType <= SI32269)
968 {
969 return Si3226x_EnableInterrupts(hProslic);
970 }
971#endif
972
973#ifdef SI3228X
974 if (hProslic->deviceId->chipType >= SI32280
975 && hProslic->deviceId->chipType <= SI32289)
976 {
977 return Si3228x_EnableInterrupts(hProslic);
978 }
979#endif
980
981 return RC_COMPLETE_NO_ERR;
982}
983
984
985/*****************************************************************************************************/
986int ProSLIC_DisableInterrupts (proslicChanType_ptr hProslic)
987{
988#ifdef GCI_MODE
989 uInt8 data;
990#endif
991 uInt8 i;
992 TRACEPRINT(hProslic, "\n", NULL);
993
994 if(hProslic->channelType != PROSLIC)
995 {
996 return RC_IGNORE;
997 }
998
999 for(i = PROSLIC_REG_IRQEN1; i < PROSLIC_REG_IRQEN4; i++)
1000 {
1001 /* Disable the interrupts */
1002 WriteReg(hProslic, hProslic->channel, i, 0);
1003 }
1004
1005 /* Clear the pending interrupts */
1006 for(i = PROSLIC_REG_IRQ1; i < PROSLIC_REG_IRQ4; i++)
1007 {
1008#ifdef GCI_MODE
1009 data = ReadReg(hProslic, hProslic->channel, i);
1010 WriteReg( hProslic, hProslic->channel, i, data);
1011#else
1012 (void)ReadReg(hProslic, hProslic->channel, i);
1013#endif
1014 }
1015 return RC_NONE;
1016}
1017
1018/*****************************************************************************************************/
1019int ProSLIC_RingSetup (proslicChanType_ptr hProslic,int preset)
1020{
1021 TRACEPRINT(hProslic, "preset: %d\n", preset);
1022#ifndef DISABLE_RING_SETUP
1023 if(hProslic->channelType != PROSLIC)
1024 {
1025 return RC_IGNORE;
1026 }
1027#ifdef SI3217X
1028 if (hProslic->deviceId->chipType >= SI32171
1029 && hProslic->deviceId->chipType <= SI32179)
1030 {
1031 return Si3217x_RingSetup(hProslic,preset);
1032 }
1033#endif
1034
1035#ifdef SI3218X
1036 if (hProslic->deviceId->chipType >= SI32180
1037 && hProslic->deviceId->chipType <= SI32189)
1038 {
1039 return Si3218x_RingSetup(hProslic,preset);
1040 }
1041#endif
1042
1043#ifdef SI3219X
1044 if ( IS_SI3219X(hProslic->deviceId) )
1045 {
1046 return Si3219x_RingSetup(hProslic,preset);
1047 }
1048#endif
1049
1050#ifdef SI3226X
1051 if (hProslic->deviceId->chipType >= SI32260
1052 && hProslic->deviceId->chipType <= SI32269)
1053 {
1054 return Si3226x_RingSetup(hProslic,preset);
1055 }
1056#endif
1057#ifdef SI3228X
1058 if (hProslic->deviceId->chipType >= SI32280
1059 && hProslic->deviceId->chipType <= SI32289)
1060 {
1061 return Si3228x_RingSetup(hProslic,preset);
1062 }
1063#endif
1064#else
1065 SILABS_UNREFERENCED_PARAMETER(hProslic);
1066 SILABS_UNREFERENCED_PARAMETER(preset);
1067#endif /*DISABLE_RING_SETUP*/
1068 return RC_COMPLETE_NO_ERR;
1069}
1070
1071/*****************************************************************************************************/
1072int ProSLIC_ToneGenSetup (proslicChanType_ptr hProslic,int preset)
1073{
1074 TRACEPRINT(hProslic, "preset: %d\n", preset);
1075#ifndef DISABLE_TONE_SETUP
1076 if(hProslic->channelType != PROSLIC)
1077 {
1078 return RC_IGNORE;
1079 }
1080#ifdef SI3217X
1081 if (hProslic->deviceId->chipType >= SI32171
1082 && hProslic->deviceId->chipType <= SI32179)
1083 {
1084 return ProSLIC_ToneGenSetupPtr(hProslic,&(Si3217x_Tone_Presets[preset]));
1085 }
1086#endif
1087
1088#ifdef SI3218X
1089 if (hProslic->deviceId->chipType >= SI32180
1090 && hProslic->deviceId->chipType <= SI32189)
1091 {
1092 return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3218x_Tone_Presets[preset]));
1093 }
1094#endif
1095
1096#ifdef SI3219X
1097 if ( IS_SI3219X(hProslic->deviceId) )
1098 {
1099 return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3219x_Tone_Presets[preset]));
1100 }
1101#endif
1102
1103#ifdef SI3226X
1104 if (hProslic->deviceId->chipType >= SI32260
1105 && hProslic->deviceId->chipType <= SI32269)
1106 {
1107 return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3226x_Tone_Presets[preset]));
1108 }
1109#endif
1110#ifdef SI3228X
1111 if (hProslic->deviceId->chipType >= SI32280
1112 && hProslic->deviceId->chipType <= SI32289)
1113 {
1114 return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3228x_Tone_Presets[preset]));
1115 }
1116#endif
1117#else
1118 SILABS_UNREFERENCED_PARAMETER(hProslic);
1119 SILABS_UNREFERENCED_PARAMETER(preset);
1120#endif /*DISABLE_TONE_SETUP*/
1121 return RC_COMPLETE_NO_ERR;
1122}
1123
1124/*****************************************************************************************************/
1125int ProSLIC_FSKSetup (proslicChanType_ptr hProslic,int preset)
1126{
1127 TRACEPRINT(hProslic, "preset: %d\n", preset);
1128#ifndef DISABLE_FSK_SETUP
1129 if(hProslic->channelType != PROSLIC)
1130 {
1131 return RC_IGNORE;
1132 }
1133#ifdef SI3217X
1134 if (hProslic->deviceId->chipType >= SI32171
1135 && hProslic->deviceId->chipType <= SI32179)
1136 {
1137 return ProSLIC_FSKSetupPtr(hProslic, &Si3217x_FSK_Presets[preset]);
1138 }
1139#endif
1140
1141#ifdef SI3218X
1142 if (hProslic->deviceId->chipType >= SI32180
1143 && hProslic->deviceId->chipType <= SI32189)
1144 {
1145 return ProSLIC_FSKSetupPtr(hProslic, &Si3218x_FSK_Presets[preset]);
1146 }
1147#endif
1148
1149#ifdef SI3219X
1150 if ( IS_SI3219X(hProslic->deviceId) )
1151 {
1152 return ProSLIC_FSKSetupPtr(hProslic, &Si3219x_FSK_Presets[preset]);
1153 }
1154#endif
1155
1156#ifdef SI3226X
1157 if (hProslic->deviceId->chipType >= SI32260
1158 && hProslic->deviceId->chipType <= SI32269)
1159 {
1160 return ProSLIC_FSKSetupPtr(hProslic, &Si3226x_FSK_Presets[preset]);
1161 }
1162#endif
1163
1164#ifdef SI3228X
1165 if (hProslic->deviceId->chipType >= SI32280
1166 && hProslic->deviceId->chipType <= SI32289)
1167 {
1168 return ProSLIC_FSKSetupPtr(hProslic,&Si3228x_FSK_Presets[preset]);
1169 }
1170#endif
1171#else
1172 SILABS_UNREFERENCED_PARAMETER(hProslic);
1173 SILABS_UNREFERENCED_PARAMETER(preset);
1174#endif /*DISABLE_FSK_SETUP*/
1175 return RC_COMPLETE_NO_ERR;
1176}
1177
1178/*****************************************************************************************************/
1179int ProSLIC_ZsynthSetup (proslicChanType_ptr hProslic,int preset)
1180{
1181 TRACEPRINT(hProslic, "preset: %d\n", preset);
1182#ifndef DISABLE_ZSYNTH_SETUP
1183 if(hProslic->channelType != PROSLIC)
1184 {
1185 return RC_IGNORE;
1186 }
1187#ifdef SI3217X
1188 if (hProslic->deviceId->chipType >= SI32171
1189 && hProslic->deviceId->chipType <= SI32179)
1190 {
1191 return Si3217x_ZsynthSetup(hProslic,preset);
1192 }
1193#endif
1194
1195#ifdef SI3218X
1196 if (hProslic->deviceId->chipType >= SI32180
1197 && hProslic->deviceId->chipType <= SI32189)
1198 {
1199 return Si3218x_ZsynthSetup(hProslic,preset);
1200 }
1201#endif
1202
1203#ifdef SI3219X
1204 if ( IS_SI3219X(hProslic->deviceId) )
1205 {
1206 return Si3219x_ZsynthSetup(hProslic,preset);
1207 }
1208#endif
1209
1210#ifdef SI3226X
1211 if (hProslic->deviceId->chipType >= SI32260
1212 && hProslic->deviceId->chipType <= SI32269)
1213 {
1214 return Si3226x_ZsynthSetup(hProslic,preset);
1215 }
1216#endif
1217
1218#ifdef SI3228X
1219 if (hProslic->deviceId->chipType >= SI32280
1220 && hProslic->deviceId->chipType <= SI32289)
1221 {
1222 return Si3228x_ZsynthSetup(hProslic,preset);
1223 }
1224#endif
1225#else
1226 SILABS_UNREFERENCED_PARAMETER(hProslic);
1227 SILABS_UNREFERENCED_PARAMETER(preset);
1228#endif /*DISABLE_ZSYNTH_SETUP*/
1229 return RC_COMPLETE_NO_ERR;
1230}
1231
1232/*****************************************************************************************************/
1233#ifndef DISABLE_CI_SETUP
1234int ProSLIC_GciCISetup (proslicChanType_ptr hProslic,int preset)
1235{
1236 TRACEPRINT(hProslic, "preset: %d\n", preset);
1237 if(hProslic->channelType != PROSLIC)
1238 {
1239 return RC_IGNORE;
1240 }
1241#ifdef SI3217X
1242 if (hProslic->deviceId->chipType >= SI32171
1243 && hProslic->deviceId->chipType <= SI32179)
1244 {
1245 return Si3217x_GciCISetup(hProslic,preset);
1246 }
1247#endif
1248
1249#ifdef SI3226X
1250 if (hProslic->deviceId->chipType >= SI32260
1251 && hProslic->deviceId->chipType <= SI32269)
1252 {
1253 return Si3226x_GciCISetup(hProslic,preset);
1254 }
1255#endif
1256
1257#if !defined(SI3217X) && !defined(SI3226X)
1258 SILABS_UNREFERENCED_PARAMETER(hProslic);
1259 SILABS_UNREFERENCED_PARAMETER(preset);
1260#endif
1261
1262 return RC_COMPLETE_NO_ERR;
1263}
1264#endif /*DISABLE_CI_SETUP*/
1265
1266/*****************************************************************************************************/
1267int ProSLIC_TXAudioGainSetup (proslicChanType_ptr hProslic,int preset)
1268{
1269 TRACEPRINT(hProslic, "preset: %d\n", preset);
1270#ifndef DISABLE_AUDIOGAIN_SETUP
1271 if(hProslic->channelType != PROSLIC)
1272 {
1273 return RC_IGNORE;
1274 }
1275
1276#ifdef SI3217X
1277 if (hProslic->deviceId->chipType >= SI32171
1278 && hProslic->deviceId->chipType <= SI32179)
1279 {
1280 return Si3217x_TXAudioGainSetup(hProslic,preset);
1281 }
1282#endif
1283
1284#ifdef SI3218X
1285 if (hProslic->deviceId->chipType >= SI32180
1286 && hProslic->deviceId->chipType <= SI32189)
1287 {
1288 return Si3218x_TXAudioGainSetup(hProslic,preset);
1289 }
1290#endif
1291
1292#ifdef SI3219X
1293 if ( IS_SI3219X(hProslic->deviceId) )
1294 {
1295 return Si3219x_TXAudioGainSetup(hProslic,preset);
1296 }
1297#endif
1298
1299#ifdef SI3226X
1300 if (hProslic->deviceId->chipType >= SI32260
1301 && hProslic->deviceId->chipType <= SI32269)
1302 {
1303 return Si3226x_TXAudioGainSetup(hProslic,preset);
1304 }
1305#endif
1306
1307#ifdef SI3228X
1308 if (hProslic->deviceId->chipType >= SI32280
1309 && hProslic->deviceId->chipType <= SI32289)
1310 {
1311 return Si3228x_TXAudioGainSetup(hProslic,preset);
1312 }
1313#endif
1314#else
1315 SILABS_UNREFERENCED_PARAMETER(hProslic);
1316 SILABS_UNREFERENCED_PARAMETER(preset);
1317
1318#endif /*DISABLE_AUDIOGAIN_SETUP*/
1319 return RC_COMPLETE_NO_ERR;
1320}
1321
1322/*****************************************************************************************************/
1323int ProSLIC_RXAudioGainSetup (proslicChanType_ptr hProslic,int preset)
1324{
1325 TRACEPRINT(hProslic, "preset: %d\n", preset);
1326#ifndef DISABLE_AUDIOGAIN_SETUP
1327 if(hProslic->channelType != PROSLIC)
1328 {
1329 return RC_IGNORE;
1330 }
1331
1332#ifdef SI3217X
1333 if (hProslic->deviceId->chipType >= SI32171
1334 && hProslic->deviceId->chipType <= SI32179)
1335 {
1336 return Si3217x_RXAudioGainSetup(hProslic,preset);
1337 }
1338#endif
1339
1340#ifdef SI3218X
1341 if (hProslic->deviceId->chipType >= SI32180
1342 && hProslic->deviceId->chipType <= SI32189)
1343 {
1344 return Si3218x_RXAudioGainSetup(hProslic,preset);
1345 }
1346#endif
1347
1348#ifdef SI3219X
1349 if ( IS_SI3219X(hProslic->deviceId) )
1350 {
1351 return Si3219x_RXAudioGainSetup(hProslic,preset);
1352 }
1353#endif
1354
1355
1356#ifdef SI3226X
1357 if (hProslic->deviceId->chipType >= SI32260
1358 && hProslic->deviceId->chipType <= SI32269)
1359 {
1360 return Si3226x_RXAudioGainSetup(hProslic,preset);
1361 }
1362#endif
1363
1364#ifdef SI3228X
1365 if (hProslic->deviceId->chipType >= SI32280
1366 && hProslic->deviceId->chipType <= SI32289)
1367 {
1368 return Si3228x_RXAudioGainSetup(hProslic,preset);
1369 }
1370#endif
1371
1372#else
1373 SILABS_UNREFERENCED_PARAMETER(hProslic);
1374 SILABS_UNREFERENCED_PARAMETER(preset);
1375#endif /*DISABLE_AUDIOGAIN_SETUP*/
1376 return RC_COMPLETE_NO_ERR;
1377}
1378
1379/*****************************************************************************************************/
1380int ProSLIC_TXAudioGainScale (proslicChanType_ptr hProslic,int preset,
1381 uInt32 pga_scale, uInt32 eq_scale)
1382{
1383 TRACEPRINT(hProslic, "preset: %d pga_scale: %u eq_scale: %u\n", preset,
1384 pga_scale, eq_scale);
1385#ifndef DISABLE_AUDIOGAIN_SETUP
1386 if(hProslic->channelType != PROSLIC)
1387 {
1388 return RC_IGNORE;
1389 }
1390
1391#ifdef SI3217X
1392 if (hProslic->deviceId->chipType >= SI32171
1393 && hProslic->deviceId->chipType <= SI32179)
1394 {
1395 return Si3217x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
1396 }
1397#endif
1398
1399#ifdef SI3218X
1400 if (hProslic->deviceId->chipType >= SI32180
1401 && hProslic->deviceId->chipType <= SI32189)
1402 {
1403 return Si3218x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
1404 }
1405#endif
1406
1407#ifdef SI3219X
1408 if ( IS_SI3219X(hProslic->deviceId) )
1409 {
1410 return Si3219x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
1411 }
1412#endif
1413
1414#ifdef SI3226X
1415 if (hProslic->deviceId->chipType >= SI32260
1416 && hProslic->deviceId->chipType <= SI32269)
1417 {
1418 return Si3226x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
1419 }
1420#endif
1421
1422#ifdef SI3228X
1423 if (hProslic->deviceId->chipType >= SI32280
1424 && hProslic->deviceId->chipType <= SI32289)
1425 {
1426 return Si3228x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
1427 }
1428#endif
1429
1430#else
1431 SILABS_UNREFERENCED_PARAMETER(hProslic);
1432 SILABS_UNREFERENCED_PARAMETER(preset);
1433#endif /*DISABLE_AUDIOGAIN_SETUP*/
1434 return RC_COMPLETE_NO_ERR;
1435}
1436
1437/*****************************************************************************************************/
1438int ProSLIC_RXAudioGainScale (proslicChanType_ptr hProslic,int preset,
1439 uInt32 pga_scale, uInt32 eq_scale)
1440{
1441 TRACEPRINT(hProslic, "preset: %d pga_scale: %u eq_scale: %u\n", preset,
1442 pga_scale, eq_scale);
1443#ifndef DISABLE_AUDIOGAIN_SETUP
1444 if(hProslic->channelType != PROSLIC)
1445 {
1446 return RC_IGNORE;
1447 }
1448#ifdef SI3217X
1449 if (hProslic->deviceId->chipType >= SI32171
1450 && hProslic->deviceId->chipType <= SI32179)
1451 {
1452 return Si3217x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
1453 }
1454#endif
1455
1456#ifdef SI3218X
1457 if (hProslic->deviceId->chipType >= SI32180
1458 && hProslic->deviceId->chipType <= SI32189)
1459 {
1460 return Si3218x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
1461 }
1462#endif
1463
1464#ifdef SI3219X
1465 if ( IS_SI3219X(hProslic->deviceId) )
1466 {
1467 return Si3219x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
1468 }
1469#endif
1470
1471#ifdef SI3226X
1472 if (hProslic->deviceId->chipType >= SI32260
1473 && hProslic->deviceId->chipType <= SI32269)
1474 {
1475 return Si3226x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
1476 }
1477#endif
1478
1479#ifdef SI3228X
1480 if (hProslic->deviceId->chipType >= SI32280
1481 && hProslic->deviceId->chipType <= SI32289)
1482 {
1483 return Si3228x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
1484 }
1485#endif
1486
1487#else
1488 SILABS_UNREFERENCED_PARAMETER(hProslic);
1489 SILABS_UNREFERENCED_PARAMETER(preset);
1490#endif /*DISABLE_AUDIOGAIN_SETUP*/
1491 return RC_COMPLETE_NO_ERR;
1492}
1493
1494/*****************************************************************************************************/
1495int ProSLIC_AudioGainSetup (proslicChanType_ptr pProslic,int32 rxgain,
1496 int32 txgain,int preset)
1497{
1498 int rc;
1499#ifndef DISABLE_AUDIOGAIN_SETUP
1500 int atx_preset = TXACGAIN_SEL;
1501 int arx_preset = RXACGAIN_SEL;
1502 TRACEPRINT(pProslic, "rxgain: %d txgain: %d preset: %d\n", rxgain, txgain,
1503 preset);
1504
1505 rc = ProSLIC_dbgSetTXGain(pProslic,txgain,preset,atx_preset);
1506
1507 if( rc == RC_NONE)
1508 {
1509 rc = ProSLIC_TXAudioGainSetup(pProslic,TXACGAIN_SEL);
1510 }
1511
1512 if( rc == RC_NONE)
1513 {
1514 rc = ProSLIC_dbgSetRXGain(pProslic,rxgain,preset,arx_preset);
1515 }
1516
1517 if( rc == RC_NONE)
1518 {
1519 rc = ProSLIC_RXAudioGainSetup(pProslic,RXACGAIN_SEL);
1520 }
1521 return rc;
1522#else
1523 SILABS_UNREFERENCED_PARAMETER(pProslic);
1524 SILABS_UNREFERENCED_PARAMETER(preset);
1525 return RC_IGNORE;
1526#endif /*DISABLE_AUDIOGAIN_SETUP*/
1527}
1528
1529/*****************************************************************************************************/
1530int ProSLIC_DCFeedSetup (proslicChanType_ptr hProslic,int preset)
1531{
1532 TRACEPRINT(hProslic, "preset: %d\n", preset);
1533#ifndef DISABLE_DCFEED_SETUP
1534 if(hProslic->channelType != PROSLIC)
1535 {
1536 return RC_IGNORE;
1537 }
1538
1539#ifdef SI3217X
1540 if (hProslic->deviceId->chipType >= SI32171
1541 && hProslic->deviceId->chipType <= SI32179)
1542 {
1543 return Si3217x_DCFeedSetup(hProslic,preset);
1544 }
1545#endif
1546
1547#ifdef SI3218X
1548 if (hProslic->deviceId->chipType >= SI32180
1549 && hProslic->deviceId->chipType <= SI32189)
1550 {
1551 return Si3218x_DCFeedSetup(hProslic,preset);
1552 }
1553#endif
1554
1555#ifdef SI3219X
1556 if ( IS_SI3219X(hProslic->deviceId) )
1557 {
1558 return Si3219x_DCFeedSetupCfg(hProslic, Si3219x_DCfeed_Presets, preset);
1559 }
1560#endif
1561
1562#ifdef SI3226X
1563 if (hProslic->deviceId->chipType >= SI32260
1564 && hProslic->deviceId->chipType <= SI32269)
1565 {
1566 return Si3226x_DCFeedSetup(hProslic,preset);
1567 }
1568#endif
1569
1570#ifdef SI3228X
1571 if (hProslic->deviceId->chipType >= SI32280
1572 && hProslic->deviceId->chipType <= SI32289)
1573 {
1574 return Si3228x_DCFeedSetup(hProslic,preset);
1575 }
1576#endif
1577#else
1578 SILABS_UNREFERENCED_PARAMETER(hProslic);
1579 SILABS_UNREFERENCED_PARAMETER(preset);
1580#endif /*DISABLE_DCFEED_SETUP*/
1581 return RC_COMPLETE_NO_ERR;
1582}
1583
1584/*****************************************************************************************************/
1585int ProSLIC_DCFeedSetupCfg (proslicChanType_ptr hProslic,
1586 ProSLIC_DCfeed_Cfg *cfg, int preset)
1587{
1588 TRACEPRINT(hProslic, "cfgPtr = %p preset = %d\n", cfg, preset);
1589#ifndef DISABLE_DCFEED_SETUP
1590 if(hProslic->channelType != PROSLIC)
1591 {
1592 return RC_IGNORE;
1593 }
1594
1595#ifdef SI3217X
1596 if (hProslic->deviceId->chipType >= SI32171
1597 && hProslic->deviceId->chipType <= SI32179)
1598 {
1599 return Si3217x_DCFeedSetupCfg(hProslic,cfg,preset);
1600 }
1601#endif
1602
1603#ifdef SI3218X
1604 if (hProslic->deviceId->chipType >= SI32180
1605 && hProslic->deviceId->chipType <= SI32189)
1606 {
1607 return Si3218x_DCFeedSetupCfg(hProslic,cfg,preset);
1608 }
1609#endif
1610
1611#ifdef SI3219X
1612 if ( IS_SI3219X(hProslic->deviceId) )
1613 {
1614 return Si3219x_DCFeedSetupCfg(hProslic,cfg,preset);
1615 }
1616#endif
1617
1618#ifdef SI3226X
1619 if (hProslic->deviceId->chipType >= SI32260
1620 && hProslic->deviceId->chipType <= SI32269)
1621 {
1622 return Si3226x_DCFeedSetupCfg(hProslic,cfg,preset);
1623 }
1624#endif
1625
1626#ifdef SI3228X
1627 if (hProslic->deviceId->chipType >= SI32280
1628 && hProslic->deviceId->chipType <= SI32289)
1629 {
1630 return Si3228x_DCFeedSetupCfg(hProslic,cfg,preset);
1631 }
1632#endif
1633
1634#else
1635 SILABS_UNREFERENCED_PARAMETER(hProslic);
1636 SILABS_UNREFERENCED_PARAMETER(preset);
1637 SILABS_UNREFERENCED_PARAMETER(cfg);
1638#endif /*DISABLE_DCFEED_SETUP*/
1639 return RC_COMPLETE_NO_ERR;
1640}
1641
1642/*****************************************************************************************************/
1643int ProSLIC_GPIOSetup (proslicChanType_ptr hProslic)
1644{
1645 TRACEPRINT(hProslic, "\n", NULL);
1646#ifndef DISABLE_GPIO_SETUP
1647 if(hProslic->channelType != PROSLIC)
1648 {
1649 return RC_IGNORE;
1650 }
1651
1652#ifdef SI3217X
1653 if (hProslic->deviceId->chipType >= SI32171
1654 && hProslic->deviceId->chipType <= SI32179)
1655 {
1656 return Si3217x_GPIOSetup(hProslic);
1657 }
1658#endif
1659
1660#ifdef SI3226X
1661 if (hProslic->deviceId->chipType >= SI32260
1662 && hProslic->deviceId->chipType <= SI32269)
1663 {
1664 return Si3226x_GPIOSetup(hProslic);
1665 }
1666#endif
1667
1668#else
1669 SILABS_UNREFERENCED_PARAMETER(hProslic);
1670#endif /*DISABLE_GPIO_SETUP*/
1671 return RC_COMPLETE_NO_ERR;
1672}
1673
1674/*****************************************************************************************************/
1675#ifndef DISABLE_PULSEMETERING
1676int ProSLIC_PulseMeterSetup (proslicChanType_ptr hProslic,int preset)
1677{
1678 TRACEPRINT(hProslic, "preset = %d\n", preset);
1679#ifndef DISABLE_PULSE_SETUP
1680 if(hProslic->channelType != PROSLIC)
1681 {
1682 return RC_IGNORE;
1683 }
1684
1685#ifdef SI3217X
1686 if (hProslic->deviceId->chipType >= SI32171
1687 && hProslic->deviceId->chipType <= SI32179)
1688 {
1689 return Si3217x_PulseMeterSetup(hProslic,preset);
1690 }
1691#endif
1692
1693#ifdef SI3218X
1694 if (hProslic->deviceId->chipType >= SI32180
1695 && hProslic->deviceId->chipType <= SI32189)
1696 {
1697 return Si3218x_PulseMeterSetup(hProslic,preset);
1698 }
1699#endif
1700
1701#ifdef SI3219X
1702 if ( IS_SI3219X(hProslic->deviceId) )
1703 {
1704 return Si3219x_PulseMeterSetup(hProslic,preset);
1705 }
1706#endif
1707
1708#ifdef SI3226X
1709 if (hProslic->deviceId->chipType >= SI32260
1710 && hProslic->deviceId->chipType <= SI32269)
1711 {
1712 return Si3226x_PulseMeterSetup(hProslic,preset);
1713 }
1714#endif
1715
1716#ifdef SI3228X
1717 if (hProslic->deviceId->chipType >= SI32280
1718 && hProslic->deviceId->chipType <= SI32289)
1719 {
1720 return Si3228x_PulseMeterSetup(hProslic,preset);
1721 }
1722#endif
1723
1724#else
1725 SILABS_UNREFERENCED_PARAMETER(hProslic);
1726 SILABS_UNREFERENCED_PARAMETER(preset);
1727#endif /*DISABLE_PULSE_SETUP*/
1728 return RC_COMPLETE_NO_ERR;
1729}
1730#endif
1731
1732/*****************************************************************************************************/
1733int ProSLIC_PCMSetup (proslicChanType_ptr hProslic,int preset)
1734{
1735 TRACEPRINT(hProslic, "preset = %d\n", preset);
1736#ifndef DISABLE_PCM_SETUP
1737 if(hProslic->channelType != PROSLIC)
1738 {
1739 return RC_IGNORE;
1740 }
1741
1742#ifdef SI3217X
1743 if (hProslic->deviceId->chipType >= SI32171
1744 && hProslic->deviceId->chipType <= SI32179)
1745 {
1746 return Si3217x_PCMSetup(hProslic,preset);
1747 }
1748#endif
1749
1750#ifdef SI3218X
1751 if (hProslic->deviceId->chipType >= SI32180
1752 && hProslic->deviceId->chipType <= SI32189)
1753 {
1754 return Si3218x_PCMSetup(hProslic,preset);
1755 }
1756#endif
1757
1758#ifdef SI3219X
1759 if ( IS_SI3219X(hProslic->deviceId) )
1760 {
1761 return Si3219x_PCMSetup(hProslic,preset);
1762 }
1763#endif
1764
1765#ifdef SI3226X
1766 if (hProslic->deviceId->chipType >= SI32260
1767 && hProslic->deviceId->chipType <= SI32269)
1768 {
1769 return Si3226x_PCMSetup(hProslic,preset);
1770 }
1771#endif
1772
1773#ifdef SI3228X
1774 if (hProslic->deviceId->chipType >= SI32280
1775 && hProslic->deviceId->chipType <= SI32289)
1776 {
1777 return Si3228x_PCMSetup(hProslic,preset);
1778 }
1779#endif
1780#else
1781 SILABS_UNREFERENCED_PARAMETER(hProslic);
1782 SILABS_UNREFERENCED_PARAMETER(preset);
1783#endif /*DISABLE_PCM_SETUP*/
1784 return RC_COMPLETE_NO_ERR;
1785}
1786
1787/*****************************************************************************************************/
1788int ProSLIC_PCMTimeSlotSetup (proslicChanType_ptr pProslic, uInt16 rxcount,
1789 uInt16 txcount)
1790{
1791 uInt8 data;
1792 TRACEPRINT(pProslic, "rx = %u tx = %u\n", rxcount, txcount);
1793
1794 if(pProslic->channelType != PROSLIC)
1795 {
1796 return RC_IGNORE;
1797 }
1798
1799 data = txcount & 0xff;
1800 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXLO,data);
1801
1802 data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI);
1803 data &= 0x10; /* keep TX_EDGE bit */
1804 data |= ((txcount >> 8)&0x03) ;
1805 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI,data);
1806
1807 data = rxcount & 0xff;
1808 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMRXLO,data);
1809
1810 data = (rxcount >> 8) & 0x3; /* PCMRXHI has only 2 bits for timeslot */
1811 /* add to the calculated timeslot values the non timeslot bits */
1812 data |= (ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMRXHI) & 0xFC);
1813 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMRXHI,data);
1814
1815 return RC_NONE;
1816}
1817
1818/*****************************************************************************************************/
1819typedef ProslicInt proslicIntTypeMap[SI_MAX_INTERRUPTS][8];
1820
1821static int ProSLIC_ReadInterruptsHelper(proslicChanType_ptr pProslic,
1822 uInt8 *regData, uInt8 numChannels)
1823{
1824 uInt8 i;
1825 uInt8 intsActive;
1826 uInt8 *currentData = regData;
1827 SILABS_UNREFERENCED_PARAMETER(numChannels);
1828
1829 intsActive = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_IRQ0);
1830
1831#ifdef PROSLIC_OPTIMIZE_INTERRUPTS
1832 /* For dual channel devices, we need to shift the upper nibble for the second channel
1833 if the caller requested the second channel. We determine this by channel ID being
1834 even or odd. If this is NOT true - for example a Si3217x and then a Si3226x chipset
1835 configuration on the same daisychain, then this optimization logic will not work */
1836#if defined(SI3226X) || defined(SI3228X)
1837 if( (numChannels != 0) && ((pProslic->channel) & 0x1))
1838 {
1839 intsActive = intsActive >> 4;
1840 }
1841#endif /* Multichannel devices */
1842#endif
1843
1844 /* If there are no interrupts, stop... return back to calling function */
1845 if((intsActive &0xF) == 0)
1846 {
1847 return RC_IGNORE;
1848 }
1849
1850 for(i = PROSLIC_REG_IRQ1; i <= PROSLIC_REG_IRQ4; i++)
1851 {
1852#ifdef PROSLIC_OPTIMIZE_INTERRUPTS
1853 /* Read IRQn Register only if IRQ0 states there was an interrupt pending, otherwise
1854 skip it. This eliminates unneeded SPI transactions.
1855 */
1856 if( (intsActive & (1<<(i-PROSLIC_REG_IRQ1))) == 0)
1857 {
1858 *currentData++ = 0;
1859 continue;
1860 }
1861#endif
1862 *currentData = (uInt8)ReadReg(pProslic, pProslic->channel, i);
1863#ifdef GCI_MODDE
1864 WriteReg(pProslic, pProslic->channel, i, *current_data);
1865#endif
1866 currentData++;
1867 } /* for loop */
1868
1869 return RC_COMPLETE_NO_ERR;
1870}
1871
1872/*
1873 Reads IRQ0 to determine if an interrupt has occurred for the particular device,
1874 if so, reads the interrupt register(s) that fired the interrupt and then
1875 maps the interrupt(s) to the generic interrupt value to return to the caller.
1876
1877 Code assumes normal chipset/compatibility testing has already been done.
1878*/
1879static int ProSLIC_GetInterruptHelper(proslicChanType_ptr pProslic,
1880 const proslicIntTypeMap intMap, proslicIntType *pIntData, uInt8 numChannels)
1881{
1882 int i,j;
1883 uInt8 intData[SI_MAX_INTERRUPTS];
1884 uInt8 *currentData;
1885 uInt8 map, intCount;
1886 BOOLEAN safetyInt = FALSE;
1887
1888 /* Initialize interrupt count to 0 */
1889 pIntData-> number = 0;
1890
1891 if( ProSLIC_ReadInterruptsHelper(pProslic, intData, numChannels) == RC_IGNORE)
1892 {
1893 /* No interrupts for the given channel. */
1894 return RC_NONE;
1895 }
1896
1897 /* At this point we've collected all the registers, now decode the data */
1898 currentData = intData;
1899 intCount = 0;
1900
1901 for(i = 0; i < SI_MAX_INTERRUPTS; i++)
1902 {
1903 if(*currentData)
1904 {
1905 for(j = 0; j < 8; j++)
1906 {
1907 if( *currentData & (1<<j) )
1908 {
1909 map = intMap[i][j];
1910 pIntData->irqs[intCount] = map;
1911
1912 if( (map == IRQ_P_HVIC)
1913 || (map == IRQ_P_THERM) )
1914 {
1915 safetyInt = TRUE;
1916 }
1917
1918 intCount++;
1919 }
1920 }
1921 }
1922 currentData++;
1923 }
1924
1925 pIntData->number = intCount;
1926
1927 if( safetyInt == TRUE)
1928 {
1929 if(ProSLIC_isReinitRequired(pProslic))
1930 {
1931 return RC_REINIT_REQUIRED;
1932 }
1933 }
1934
1935 return pIntData->number;
1936}
1937
1938
1939int ProSLIC_GetInterrupts (proslicChanType_ptr hProslic,
1940 proslicIntType *pIntData)
1941{
1942 const proslicIntTypeMap interruptMap =
1943 {
1944 {IRQ_OSC1_T1, IRQ_OSC1_T2, IRQ_OSC2_T1, IRQ_OSC2_T2, IRQ_RING_T1, IRQ_RING_T2, IRQ_FSKBUF_AVAIL, IRQ_VBAT},
1945 {IRQ_RING_TRIP, IRQ_LOOP_STATUS, IRQ_LONG_STAT, IRQ_VOC_TRACK, IRQ_DTMF, IRQ_INDIRECT, IRQ_RXMDM, IRQ_TXMDM},
1946 {IRQ_P_HVIC, IRQ_P_THERM, IRQ_PQ3, IRQ_PQ4, IRQ_PQ5, IRQ_PQ6, IRQ_DSP, IRQ_MADC_FS},
1947 {IRQ_USER_0, IRQ_USER_1, IRQ_USER_2, IRQ_USER_3, IRQ_USER_4, IRQ_USER_5, IRQ_USER_6, IRQ_USER_7}
1948 };
1949
1950 pIntData->number=0;
1951 /* TRACEPRINT(hProslic, "\n", NULL); */
1952 if(hProslic->channelType != PROSLIC)
1953 {
1954 return RC_IGNORE;
1955 }
1956#if defined (SI3217X) || defined (SI3218X) || defined(SI3219X)
1957 if (0
1958#ifdef SI3217X
1959 || (hProslic->deviceId->chipType >= SI32171
1960 && hProslic->deviceId->chipType <= SI32179)
1961#endif
1962#ifdef SI3218X
1963 || (hProslic->deviceId->chipType >= SI32180
1964 && hProslic->deviceId->chipType <= SI32189)
1965#endif
1966#ifdef SI3219X
1967 || ( IS_SI3219X(hProslic->deviceId) )
1968#endif
1969 )
1970 {
1971 return ProSLIC_GetInterruptHelper(hProslic, interruptMap, pIntData, 1);
1972 }
1973#endif
1974#if defined (SI3226X) || defined (SI3228X)
1975 if( 0
1976#ifdef SI3226X
1977 || (hProslic->deviceId->chipType >= SI32260
1978 && hProslic->deviceId->chipType <= SI32269)
1979#endif
1980#ifdef SI3228X
1981 || (hProslic->deviceId->chipType >= SI32280
1982 && hProslic->deviceId->chipType <= SI32289)
1983#endif
1984 )
1985 {
1986 return ProSLIC_GetInterruptHelper(hProslic, interruptMap, pIntData, 2);
1987 }
1988#endif
1989 return RC_COMPLETE_NO_ERR;
1990}
1991
1992/*****************************************************************************************************/
1993int ProSLIC_ReadHookStatus (proslicChanType_ptr pProslic,uInt8 *pHookStat)
1994{
1995 TRACEPRINT(pProslic, "\n", NULL);
1996 *pHookStat = PROSLIC_ONHOOK;
1997
1998 if(pProslic->channelType != PROSLIC)
1999 {
2000 return RC_IGNORE;
2001 }
2002 if (ReadReg(pProslic,pProslic->channel,PROSLIC_REG_LCRRTP) & 2)
2003 {
2004 *pHookStat=PROSLIC_OFFHOOK;
2005 }
2006 return RC_NONE;
2007}
2008
2009/*****************************************************************************************************/
2010int ProSLIC_SetLinefeedStatus (proslicChanType_ptr pProslic, uInt8 newLinefeed)
2011{
2012 uInt8 lfState;
2013 uInt8 irqen1=0;
2014 TRACEPRINT(pProslic, "linefeed = %u\n", newLinefeed);
2015
2016 if(pProslic->channelType != PROSLIC)
2017 {
2018 return RC_IGNORE;
2019 }
2020
2021 /* Get the irqen1 setting - used to determine if vbat interrupt was set... */
2022#ifdef SI3217X
2023 if (pProslic->deviceId->chipType >= SI32171
2024 && pProslic->deviceId->chipType <= SI32179)
2025 {
2026 irqen1 = Si3217x_General_Configuration.irqen1;
2027 }
2028#endif
2029
2030#ifdef SI3218X
2031 if (pProslic->deviceId->chipType >= SI32180
2032 && pProslic->deviceId->chipType <= SI32189)
2033 {
2034 irqen1 = Si3218x_General_Configuration.irqen1;
2035 }
2036#endif
2037
2038#ifdef SI3219X
2039 if ( IS_SI3219X(pProslic->deviceId) )
2040 {
2041 irqen1 = Si3219x_General_Configuration.irqen1;
2042 }
2043#endif
2044
2045#ifdef SI3226X
2046 if (pProslic->deviceId->chipType >= SI32260
2047 && pProslic->deviceId->chipType <= SI32269)
2048 {
2049 irqen1 = Si3226x_General_Configuration.irqen1;
2050 }
2051#endif
2052
2053#ifdef SI3228X
2054 if (pProslic->deviceId->chipType >= SI32280
2055 && pProslic->deviceId->chipType <= SI32289)
2056 {
2057 irqen1 = Si3228x_General_Configuration.irqen1;
2058 }
2059#endif
2060
2061 if( (newLinefeed& 0xF) == LF_RINGING )
2062 {
2063 uInt8 regTemp;
2064
2065 lfState = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED);
2066
2067 /* Only change to ringing state if not ringing... */
2068 if( (lfState & 0xF) != LF_RINGING )
2069 {
2070 if(irqen1 & 0x80)
2071 {
2072 /*disable vbat interrupt during ringing*/
2073 regTemp = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_IRQEN1 );
2074 WriteReg (pProslic, pProslic->channel, PROSLIC_REG_IRQEN1, regTemp&(~0x80));
2075 }
2076
2077 WriteReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED, LF_RINGING);
2078 }
2079 else
2080 {
2081 return RC_IGNORE;
2082 }
2083 }
2084 else
2085 {
2086 uInt8 autord;
2087
2088 /* Preserve the auto register so we can restore it at the end */
2089 autord = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD );
2090 WriteReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD, (autord & 0xFB) ); /* Disable AutoRD */
2091
2092 lfState = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED);
2093
2094 if( (lfState & 0xF) == LF_RINGING )
2095 {
2096 WriteReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED, newLinefeed);
2097 }
2098 else
2099 {
2100 /* We are already doing a state transition, abort request */
2101 if( ((lfState & 0xF0) == (LF_RINGING << 4) )
2102 && ( (lfState & 0xF) != LF_RINGING) )
2103 {
2104 WriteReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD, autord ); /* restore the autord bit */
2105 return RC_IGNORE;
2106 }
2107
2108 WriteReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED, newLinefeed);
2109 }
2110 /* Restore autord */
2111 WriteReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD, autord );
2112
2113 /* Restore IRQEN1 to what the user specified - if we changed it.. */
2114 if(irqen1 & 0x80)
2115 {
2116 WriteReg (pProslic, pProslic->channel, PROSLIC_REG_IRQEN1, irqen1);
2117 }
2118 }
2119 return RC_NONE;
2120}
2121
2122/*****************************************************************************************************/
2123int ProSLIC_SetLinefeedStatusBroadcast (proslicChanType_ptr hProslic,
2124 uInt8 newLinefeed)
2125{
2126 TRACEPRINT(hProslic, "linefeed = %u\n", newLinefeed);
2127 if(hProslic->channelType != PROSLIC)
2128 {
2129 return RC_IGNORE;
2130 }
2131
2132 WriteReg(hProslic, PROSLIC_CHAN_BROADCAST, PROSLIC_REG_LINEFEED, newLinefeed);
2133 return RC_COMPLETE_NO_ERR;
2134}
2135
2136/*****************************************************************************************************/
2137int ProSLIC_PolRev (proslicChanType_ptr pProslic,uInt8 abrupt,
2138 uInt8 newPolRevState)
2139{
2140 uInt8 data = 0;
2141 TRACEPRINT(pProslic, "abrupt = %u newPolRevState = %u\n", abrupt,
2142 newPolRevState);
2143 if(pProslic->channelType != PROSLIC)
2144 {
2145 return RC_IGNORE;
2146 }
2147
2148 switch (newPolRevState)
2149 {
2150 case POLREV_STOP:
2151 data = 0;
2152 break;
2153 case POLREV_START:
2154 data = 2;
2155 break;
2156 case WINK_START:
2157 data = 6;
2158 break;
2159 case WINK_STOP:
2160 data = 4;
2161 break;
2162 }
2163
2164 /* Cannot polrev/wink while low power mode is active */
2165 ProSLIC_SetPowersaveMode(pProslic,PWRSAVE_DISABLE);
2166
2167 if (abrupt)
2168 {
2169 data |= 1;
2170 }
2171
2172 WriteReg(pProslic, pProslic->channel, PROSLIC_REG_POLREV,data);
2173
2174 return RC_NONE;
2175}
2176
2177/*****************************************************************************************************/
2178int ProSLIC_GPIOControl (proslicChanType_ptr pProslic,uInt8 *pGpioData,
2179 uInt8 read)
2180{
2181 TRACEPRINT(pProslic, "\n", NULL);
2182 if(pProslic->channelType != PROSLIC)
2183 {
2184 return RC_IGNORE;
2185 }
2186#if defined(SI3217X) || defined (SI3226X)
2187 if( 0
2188#ifdef SI3217X
2189 || (pProslic->deviceId->chipType >= SI32171
2190 && pProslic->deviceId->chipType <= SI32179)
2191#endif
2192#ifdef SI3226X
2193 || (pProslic->deviceId->chipType >= SI32260
2194 && pProslic->deviceId->chipType <= SI32269)
2195#endif
2196 )
2197 {
2198 if (read)
2199 {
2200 *pGpioData = 0xf & ReadReg(pProslic,pProslic->channel,PROSLIC_REG_GPIO);
2201 }
2202 else
2203 {
2204 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_GPIO,
2205 (*pGpioData)|(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_GPIO)&0xf0));
2206 }
2207 return RC_NONE;
2208 }
2209#else
2210 SILABS_UNREFERENCED_PARAMETER(read);
2211 SILABS_UNREFERENCED_PARAMETER(pGpioData);
2212#endif
2213 return RC_COMPLETE_NO_ERR;
2214}
2215
2216/*****************************************************************************************************/
2217/*
2218** Optional Neon Message Waiting Support
2219*/
2220#ifdef SIVOICE_NEON_MWI_SUPPORT
2221int ProSLIC_MWISetV (proslicChanType_ptr hProslic, uInt16 vpk_mag)
2222{
2223 uInt32 ram_val;
2224 uInt8 max;
2225
2226 TRACEPRINT(hProslic, "vpk_mag = %u\n", vpk_mag);
2227 if(hProslic->channelType != PROSLIC)
2228 {
2229 return RC_IGNORE;
2230 }
2231
2232 /* Set the maximum MWI voltage according to the chipset */
2233#if defined (SI3217X) || defined (SI3226X)
2234 if( 0
2235#ifdef SI3217X
2236 || (hProslic->deviceId->chipType >= SI32171
2237 && hProslic->deviceId->chipType <= SI32179)
2238#endif
2239#ifdef SI3226X
2240 || (hProslic->deviceId->chipType >= SI32260
2241 && hProslic->deviceId->chipType <= SI32269)
2242#endif
2243 )
2244 {
2245 max = SIL_MWI_VPK_MAX;
2246 }
2247#endif /*17x/26x */
2248
2249#if defined (SI3218X) || defined (SI3228X) || defined(SI3219X)
2250 if( 0
2251#ifdef SI3218X
2252 || (hProslic->deviceId->chipType >= SI32180
2253 && hProslic->deviceId->chipType <= SI32189)
2254#endif
2255
2256#ifdef SI3228X
2257 || (hProslic->deviceId->chipType >= SI32280
2258 && hProslic->deviceId->chipType <= SI32289)
2259#endif
2260
2261#ifdef SI3219X
2262 || IS_SI3219X(hProslic->deviceId)
2263#endif
2264
2265#ifdef SI3228X
2266 || (hProslic->deviceId->chipType >= SI32280
2267 && hProslic->deviceId->chipType <= SI32289)
2268#endif
2269 )
2270 {
2271 max = SIL_MWI_VPK_MAX_LO;
2272 }
2273#endif /* 18x, 28x, 19x */
2274
2275 /* Voltage mod */
2276 if(vpk_mag > 0) /* Skip if 0 passed */
2277 {
2278 /* Clamp supplied value to allowable range */
2279 if(vpk_mag > max)
2280 {
2281 vpk_mag = max;
2282 }
2283 if(vpk_mag < SIL_MWI_VPK_MIN)
2284 {
2285 vpk_mag = SIL_MWI_VPK_MIN;
2286 }
2287 ram_val = vpk_mag * SCALE_R_MADC * 1000L;
2288 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_MWI_V,ram_val);
2289 }
2290 return RC_COMPLETE_NO_ERR;
2291}
2292#endif
2293
2294/*****************************************************************************************************/
2295#ifdef SIVOICE_NEON_MWI_SUPPORT
2296int ProSLIC_MWIEnable (proslicChanType_ptr hProslic)
2297{
2298 uInt8 val;
2299 ramData ram_val;
2300
2301 TRACEPRINT(hProslic, "\n", NULL);
2302
2303 /*
2304 ** Check for conditions that would prevent enabling MWI
2305 */
2306 ProSLIC_ReadHookStatus(hProslic,&val);
2307 if(val != PROSLIC_ONHOOK)
2308 {
2309 return RC_MWI_ENABLE_FAIL;
2310 }
2311
2312 val = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT);
2313
2314 /* Check if PROSLIC and disabled MWI, if not, ignore this request. */
2315 if( (hProslic->channelType != PROSLIC)
2316 || (val & SIL_MWI_USTAT_SET ) )
2317 {
2318 return RC_IGNORE;
2319 }
2320
2321 /* Save parameters */
2322 hProslic->mwiSave.ringof = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGOF);
2323 hProslic->mwiSave.ringamp = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGAMP);
2324 hProslic->mwiSave.vbatr_expect = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_VBATR_EXPECT);
2325 hProslic->mwiSave.vov_ring_bat = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_BAT);
2326 hProslic->mwiSave.vov_ring_gnd = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_GND);
2327 hProslic->mwiSave.rtacth = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTACTH);
2328 hProslic->mwiSave.rtdcth = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCTH);
2329 hProslic->mwiSave.iring_lim = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_IRING_LIM);
2330 hProslic->mwiSave.dcdc_rngtype = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_RNGTYPE);
2331 hProslic->mwiSave.slope_ring = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_SLOPE_RING);
2332 hProslic->mwiSave.rtper = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTPER);
2333 hProslic->mwiSave.ringfr = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGFR);
2334 hProslic->mwiSave.rtdcdb = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCDB);
2335 hProslic->mwiSave.lcrmask = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_LCRMASK);
2336 hProslic->mwiSave.dcdc_oithresh_lo = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_LO);
2337 hProslic->mwiSave.enhance = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
2338 hProslic->mwiSave.ringcon = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_RINGCON);
2339 hProslic->mwiSave.userstat = val;
2340 hProslic->mwiSave.linefeed = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_LINEFEED);
2341
2342 /* Modify parameters */
2343 ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
2344 ram_val = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_MWI_V);
2345 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGOF,ram_val);
2346 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGAMP,0x0L);
2347
2348 /* Set the VBATR_EXPECT according to the chipset */
2349#if defined (SI3217X) || defined (SI3226X)
2350 if( 0
2351#ifdef SI3217X
2352 || (hProslic->deviceId->chipType >= SI32171
2353 && hProslic->deviceId->chipType <= SI32179)
2354#endif
2355#ifdef SI3226X
2356 || (hProslic->deviceId->chipType >= SI32260
2357 && hProslic->deviceId->chipType <= SI32269)
2358#endif
2359 )
2360 {
2361 ram_val = 0x7FFFFC2L;
2362 }
2363#endif
2364
2365#if defined (SI3218X) || defined (SI3228X) || defined(SI3219X)
2366 if( 0
2367#ifdef SI3218X
2368 || (hProslic->deviceId->chipType >= SI32180
2369 && hProslic->deviceId->chipType <= SI32189)
2370#endif
2371
2372#ifdef SI3228X
2373 || (hProslic->deviceId->chipType >= SI32280
2374 && hProslic->deviceId->chipType <= SI32289)
2375#endif
2376
2377#ifdef SI3219X
2378 || IS_SI3219X(hProslic->deviceId)
2379#endif
2380 )
2381 {
2382 ram_val = 0x06866635L;
2383 }
2384#endif /* 18x,28x, 19x */
2385
2386 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VBATR_EXPECT,ram_val);
2387 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_BAT,0x0L);
2388 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_GND,0x051EB80L);
2389 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTACTH,0x0FFFFFFFL);
2390 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCTH,0x38E38EL);
2391 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_IRING_LIM,0x380000L);
2392 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_RNGTYPE,0x100000L);
2393 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_SLOPE_RING,0x15E5200EL);
2394 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTPER,0x50000L);
2395 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGFR,0x07EFE000L);
2396 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCDB,0x0000A000L);
2397 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_LCRMASK,0x000F0000L);
2398 ram_val = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_HI);
2399 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_LO,ram_val);
2400 WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,hProslic->mwiSave.enhance&0xEF);
2401 WriteReg(hProslic,hProslic->channel,PROSLIC_REG_RINGCON,0x00);
2402 WriteReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT,0x0C);
2403
2404 return RC_COMPLETE_NO_ERR;
2405}
2406#endif
2407
2408/*****************************************************************************************************/
2409#ifdef SIVOICE_NEON_MWI_SUPPORT
2410int ProSLIC_MWIDisable (proslicChanType_ptr hProslic)
2411{
2412 TRACEPRINT(hProslic, "\n", NULL);
2413
2414 /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
2415 if( (hProslic->channelType != PROSLIC)
2416 || !(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
2417 {
2418 return RC_IGNORE;
2419 }
2420
2421 ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
2422 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGOF,hProslic->mwiSave.ringof);
2423 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGAMP,hProslic->mwiSave.ringamp);
2424 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VBATR_EXPECT,hProslic->mwiSave.vbatr_expect);
2425 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_BAT,hProslic->mwiSave.vov_ring_bat);
2426 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_GND,hProslic->mwiSave.vov_ring_gnd);
2427 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTACTH,hProslic->mwiSave.rtacth);
2428 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCTH,hProslic->mwiSave.rtdcth);
2429 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_IRING_LIM,hProslic->mwiSave.iring_lim);
2430 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_RNGTYPE,hProslic->mwiSave.dcdc_rngtype);
2431 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_SLOPE_RING,hProslic->mwiSave.slope_ring);
2432 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTPER,hProslic->mwiSave.rtper);
2433 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGFR,hProslic->mwiSave.ringfr);
2434 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCDB,hProslic->mwiSave.rtdcdb);
2435 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_LCRMASK,hProslic->mwiSave.lcrmask);
2436 WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_LO,hProslic->mwiSave.dcdc_oithresh_lo);
2437 WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,hProslic->mwiSave.enhance);
2438 WriteReg(hProslic,hProslic->channel,PROSLIC_REG_RINGCON,hProslic->mwiSave.ringcon);
2439 WriteReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT,hProslic->mwiSave.userstat);
2440 ProSLIC_SetLinefeedStatus(hProslic,hProslic->mwiSave.linefeed);
2441
2442 return RC_COMPLETE_NO_ERR;
2443}
2444#endif
2445
2446/*****************************************************************************************************/
2447#ifdef SIVOICE_NEON_MWI_SUPPORT
2448int ProSLIC_SetMWIState (proslicChanType_ptr hProslic,uInt8 flash_on)
2449{
2450 TRACEPRINT(hProslic, "flash_on = %u\n", flash_on);
2451 /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
2452 if( (hProslic->channelType != PROSLIC)
2453 || !(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
2454 {
2455 return RC_IGNORE;
2456 }
2457
2458 if(flash_on)
2459 {
2460 ProSLIC_SetLinefeedStatus(hProslic,LF_RINGING);
2461 }
2462 else
2463 {
2464 ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
2465 }
2466
2467 return RC_COMPLETE_NO_ERR;
2468}
2469#endif
2470
2471/*****************************************************************************************************/
2472#ifdef SIVOICE_NEON_MWI_SUPPORT
2473int ProSLIC_GetMWIState (proslicChanType_ptr hProslic)
2474{
2475 TRACEPRINT(hProslic, "\n", NULL);
2476 /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
2477 if( (hProslic->channelType != PROSLIC)
2478 || !(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
2479 {
2480 return RC_IGNORE;
2481 }
2482
2483 if(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_LINEFEED) == 0x44)
2484 {
2485 return SIL_MWI_FLASH_ON;
2486 }
2487 else
2488 {
2489 return SIL_MWI_FLASH_OFF;
2490 }
2491
2492 return RC_COMPLETE_NO_ERR;
2493}
2494#endif
2495
2496/******************************************************************************/
2497#ifdef SIVOICE_NEON_MWI_SUPPORT
2498int ProSLIC_MWIRampPoll(proslicChanType_ptr pProslic)
2499{
2500 uInt32 mwi_voltage;
2501
2502 /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
2503 if( (pProslic->channelType != PROSLIC)
2504 || !(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
2505 {
2506 return RC_IGNORE;
2507 }
2508
2509 switch(pProslic->mwiState.state)
2510 {
2511 case PROSLIC_MWI_RAMP_ON:
2512 {
2513 if(pProslic->mwiState.ticks == pProslic->mwiState.poll.steps)
2514 {
2515 mwi_voltage = pProslic->mwiState.poll.voff + pProslic->mwiState.poll.step_size;
2516 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
2517 ProSLIC_SetLinefeedStatus(pProslic,LF_RINGING);
2518 }
2519 else if(pProslic->mwiState.ticks == 0)
2520 {
2521 mwi_voltage = pProslic->mwiState.poll.von;
2522 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
2523 pProslic->mwiState.ticks = pProslic->mwiState.poll.onTime+1;
2524 pProslic->mwiState.state = PROSLIC_MWI_ON;
2525 }
2526 else
2527 {
2528 mwi_voltage = pProslic->mwiState.poll.voff + pProslic->mwiState.poll.step_size*(pProslic->mwiState.poll.steps - pProslic->mwiState.ticks + 1);
2529 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
2530 }
2531 }
2532 break;
2533
2534 case PROSLIC_MWI_RAMP_OFF:
2535 {
2536 if(pProslic->mwiState.ticks == 0)
2537 {
2538 pProslic->mwiState.ticks = pProslic->mwiState.poll.offTime+1;
2539 pProslic->mwiState.state = PROSLIC_MWI_OFF;
2540 ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
2541 }
2542 else
2543 {
2544 mwi_voltage = pProslic->mwiState.poll.von - (pProslic->mwiState.poll.steps - pProslic->mwiState.ticks + 1)*pProslic->mwiState.poll.step_size;
2545 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
2546 }
2547 break;
2548 }
2549
2550 case PROSLIC_MWI_ON:
2551 if(pProslic->mwiState.ticks == 0)
2552 {
2553 pProslic->mwiState.ticks = pProslic->mwiState.poll.steps+1;
2554 pProslic->mwiState.state = PROSLIC_MWI_RAMP_OFF;
2555 }
2556 break;
2557
2558 case PROSLIC_MWI_OFF:
2559 if(pProslic->mwiState.ticks == 0)
2560 {
2561 pProslic->mwiState.ticks = pProslic->mwiState.poll.steps+1;
2562 pProslic->mwiState.state = PROSLIC_MWI_RAMP_ON;
2563 }
2564 break;
2565
2566 default:
2567 /* Do nothing */
2568 break;
2569 }
2570 (pProslic->mwiState.ticks)--;
2571
2572 return RC_COMPLETE_NO_ERR;
2573}
2574#endif
2575
2576/******************************************************************************/
2577#ifdef SIVOICE_NEON_MWI_SUPPORT
2578int ProSLIC_MWIRampStart(proslicChanType_ptr pProslic, uInt32 steps, uInt32 onTime, uInt32 offTime)
2579{
2580 /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
2581 if( (pProslic->channelType != PROSLIC)
2582 || !(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
2583 {
2584 return RC_IGNORE;
2585 }
2586
2587 pProslic->mwiState.poll.steps = steps-1;
2588 pProslic->mwiState.poll.onTime = onTime;
2589 pProslic->mwiState.poll.offTime = offTime;
2590
2591 pProslic->mwiState.poll.von = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_MWI_V);
2592 pProslic->mwiState.poll.voff = (ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_V_VLIM)*5)/6;
2593 pProslic->mwiState.poll.step_size = (pProslic->mwiState.poll.von - pProslic->mwiState.poll.voff)/steps;
2594
2595 pProslic->mwiState.state = PROSLIC_MWI_RAMP_ON;
2596 pProslic->mwiState.ticks = pProslic->mwiState.poll.steps;
2597
2598 return RC_COMPLETE_NO_ERR;
2599}
2600#endif
2601
2602/******************************************************************************/
2603#ifdef SIVOICE_NEON_MWI_SUPPORT
2604int ProSLIC_MWIRampStop(proslicChanType_ptr pProslic)
2605{
2606 /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
2607 if( (pProslic->channelType != PROSLIC)
2608 || !(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
2609 {
2610 return RC_IGNORE;
2611 }
2612 pProslic->mwiState.state = PROSLIC_MWI_OFF;
2613
2614 return RC_COMPLETE_NO_ERR;
2615}
2616#endif
2617
2618/*****************************************************************************************************/
2619int ProSLIC_ToneGenStart (proslicChanType_ptr pProslic,uInt8 timerEn)
2620{
2621 uInt8 data;
2622 TRACEPRINT(pProslic, "timerEn = %u\n", timerEn);
2623 if(pProslic->channelType != PROSLIC)
2624 {
2625 return RC_IGNORE;
2626 }
2627 DEBUG_PRINT(pProslic, "%s%s on channel %d\n",LOGPRINT_PREFIX, __FUNCTION__,
2628 pProslic->channel);
2629
2630 data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OCON);
2631 data |= 0x11 + (timerEn ? 0x66 : 0);
2632 return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,data);
2633}
2634
2635/*****************************************************************************************************/
2636int ProSLIC_ToneGenStop (proslicChanType_ptr pProslic)
2637{
2638 uInt8 data;
2639 TRACEPRINT(pProslic, "\n", NULL);
2640 if(pProslic->channelType != PROSLIC)
2641 {
2642 return RC_IGNORE;
2643 }
2644 DEBUG_PRINT(pProslic,"%s%s on channel %d\n",LOGPRINT_PREFIX, __FUNCTION__,
2645 pProslic->channel);
2646 data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OCON);
2647 data &= ~(0x77);
2648 return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,data);
2649}
2650
2651/*****************************************************************************************************/
2652int ProSLIC_RingStart (proslicChanType_ptr pProslic)
2653{
2654 TRACEPRINT(pProslic, "\n", NULL);
2655 return(ProSLIC_SetLinefeedStatus(pProslic, LF_RINGING));
2656}
2657
2658/*****************************************************************************************************/
2659int ProSLIC_RingStop (proslicChanType_ptr pProslic)
2660{
2661 TRACEPRINT(pProslic, "\n", NULL);
2662 return(ProSLIC_SetLinefeedStatus(pProslic, LF_FWD_ACTIVE));
2663}
2664
2665#ifndef DISABLE_FSK_SETUP
2666/*****************************************************************************************************/
2667int ProSLIC_CheckCIDBuffer (proslicChanType_ptr pProslic, uInt8 *fsk_buf_avail)
2668{
2669 uInt8 data;
2670 TRACEPRINT(pProslic, "\n", NULL);
2671 if(pProslic->channelType != PROSLIC)
2672 {
2673 return RC_IGNORE;
2674 }
2675
2676 data = ReadReg(pProslic,pProslic->channel, PROSLIC_REG_IRQ1);
2677#ifdef GCI_MODE
2678 WriteReg(pProslic,pProslic->channel, PROSLIC_REG_IRQ1,data); /*clear (for GCI)*/
2679#endif
2680 *fsk_buf_avail = (data&0x40) ? 1 : 0;
2681 return RC_NONE;
2682}
2683
2684/*****************************************************************************************************/
2685int ProSLIC_EnableCID (proslicChanType_ptr pProslic)
2686{
2687 uInt8 data;
2688 TRACEPRINT(pProslic, "\n", NULL);
2689 if(pProslic->channelType != PROSLIC)
2690 {
2691 return RC_IGNORE;
2692 }
2693 DEBUG_PRINT(pProslic, "%sEnableCID on channel %d\n",LOGPRINT_PREFIX,
2694 pProslic->channel);
2695 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,0);
2696
2697 data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
2698 data |= 0xA;
2699 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data);
2700
2701 return(WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,0x5));
2702}
2703
2704/*****************************************************************************************************/
2705int ProSLIC_DisableCID (proslicChanType_ptr pProslic)
2706{
2707 uInt8 data;
2708 TRACEPRINT(pProslic, "\n", NULL);
2709
2710 if(pProslic->channelType != PROSLIC)
2711 {
2712 return RC_IGNORE;
2713 }
2714 DEBUG_PRINT(pProslic, "%sDisableCID on channel %d\n",LOGPRINT_PREFIX,
2715 pProslic->channel);
2716 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,0);
2717 data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
2718 data &= ~(0x8);
2719
2720 return(WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data));
2721}
2722
2723/*****************************************************************************************************/
2724int ProSLIC_SendCID (proslicChanType_ptr pProslic, uInt8 *buffer,
2725 uInt8 numBytes)
2726{
2727 TRACEPRINT(pProslic, "numBytes = %u\n", numBytes);
2728
2729 if(pProslic->channelType != PROSLIC)
2730 {
2731 return RC_IGNORE;
2732 }
2733 DEBUG_PRINT (pProslic, "%sSendCID on channel %d\n",LOGPRINT_PREFIX,
2734 pProslic->channel);
2735 while (numBytes-- > 0)
2736 {
2737 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_FSKDAT,*(buffer++));
2738 }
2739 return RC_NONE;
2740}
2741
2742/*****************************************************************************************************/
2743int ProSLIC_ModifyCIDStartBits(proslicChanType_ptr pProslic,
2744 uInt8 enable_startStop)
2745{
2746 uInt8 data;
2747 TRACEPRINT(pProslic, "enable_startStop = %u\n", enable_startStop);
2748
2749 if(pProslic->channelType != PROSLIC)
2750 {
2751 return RC_CHANNEL_TYPE_ERR;
2752 }
2753
2754 data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
2755
2756 if(enable_startStop == FALSE)
2757 {
2758 data &= ~0x80;
2759 }
2760 else
2761 {
2762 data |= 0x80;
2763 }
2764
2765 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data);
2766
2767 return RC_NONE;
2768}
2769#endif /* DISABLE_FSK_SETUP */
2770/*****************************************************************************************************/
2771int ProSLIC_PCMStart (proslicChanType_ptr pProslic)
2772{
2773 uInt8 data;
2774 TRACEPRINT(pProslic, "\n", NULL);
2775
2776 if(pProslic->channelType != PROSLIC)
2777 {
2778 return RC_IGNORE;
2779 }
2780 DEBUG_PRINT(pProslic, "%sPCMStart\n", LOGPRINT_PREFIX);
2781 data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE);
2782 data |= 0x10;
2783
2784 return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE,data);
2785}
2786
2787/*****************************************************************************************************/
2788int ProSLIC_PCMStop (proslicChanType_ptr pProslic)
2789{
2790 uInt8 data;
2791 TRACEPRINT(pProslic, "\n", NULL);
2792
2793 if(pProslic->channelType != PROSLIC)
2794 {
2795 return RC_IGNORE;
2796 }
2797
2798 DEBUG_PRINT(pProslic, "%sPCMStart\n", LOGPRINT_PREFIX);
2799 data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE);
2800 data &= ~0x10;
2801
2802 return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE,data);
2803}
2804
2805#ifndef DISABLE_HOOKCHANGE
2806/*****************************************************************************************************/
2807/*
2808** Function: ProSLIC_ResetDialPulseDetect
2809**
2810** Description:
2811** reset dial pulse detection state machine (helper function for
2812** ProSLIC_InitializeHookChangeDetect.
2813*/
2814static void ProSLIC_ResetDialPulseDetect(hookChangeType *pPulse)
2815{
2816 pPulse->currentPulseDigit = 0;
2817 pPulse->lookingForTimeout = 0;
2818}
2819
2820/*****************************************************************************************************/
2821/*
2822** Function: ProSLIC_InitializeHookChangeDetect
2823**
2824** Description:
2825** Initialize dial pulse detection parameters
2826*/
2827int ProSLIC_InitializeHookChangeDetect(hookChangeType *pPulse,void *hookTime)
2828{
2829 TRACEPRINT_NOCHAN("\n", NULL);
2830 pPulse->hookTime = hookTime;
2831 pPulse->last_state_reported = SI_HC_NO_ACTIVITY;
2832 ProSLIC_ResetDialPulseDetect(pPulse);
2833 return RC_NONE;
2834}
2835
2836/*****************************************************************************************************/
2837/*
2838** Function: ProSLIC_HookChangeDetect
2839**
2840** Description:
2841** implements pulse dial detection and should be called at every hook transition
2842*/
2843uInt8 ProSLIC_HookChangeDetect (proslicChanType *pProslic,
2844 hookChange_Cfg *pHookChangeCfg, hookChangeType *pHookChangeData)
2845{
2846 uInt8 hookStat;
2847 int delta_time;
2848
2849 TRACEPRINT(pProslic, "\n", NULL);
2850 if(pProslic->channelType != PROSLIC)
2851 {
2852 return RC_IGNORE;
2853 }
2854
2855 TimeElapsed(pProTimer,pHookChangeData->hookTime,&delta_time);
2856 ProSLIC_ReadHookStatus(pProslic,&hookStat);
2857
2858 /* Did we have a hook state change? */
2859 if(hookStat != pHookChangeData->last_hook_state)
2860 {
2861 pHookChangeData->last_hook_state = hookStat;
2862 getTime(pProTimer,pHookChangeData->hookTime);
2863 pHookChangeData->lookingForTimeout = 1;
2864 if (hookStat == PROSLIC_OFFHOOK)
2865 {
2866 if ((delta_time >= (pHookChangeCfg->minOnHook))
2867 && (delta_time <= (pHookChangeCfg->maxOnHook)))
2868 {
2869 pHookChangeData->currentPulseDigit++;
2870 }
2871 else
2872 {
2873 /* Did we see a hook flash? */
2874 if( (delta_time >= pHookChangeCfg->minHookFlash)
2875 && (delta_time <= pHookChangeCfg->maxHookFlash) )
2876 {
2877 pHookChangeData->last_state_reported = SI_HC_HOOKFLASH;
2878 ProSLIC_ResetDialPulseDetect(pHookChangeData);
2879 return SI_HC_HOOKFLASH;
2880 }
2881 }
2882 }
2883
2884 return SI_HC_NEED_MORE_POLLS;
2885 }
2886
2887 if( (pHookChangeData->lookingForTimeout == 1)
2888 && (delta_time >= pHookChangeCfg->minInterDigit) )
2889 {
2890
2891 if(delta_time > pHookChangeCfg->minHook)
2892 {
2893 if(pHookChangeData->last_hook_state == PROSLIC_ONHOOK)
2894 {
2895 ProSLIC_ResetDialPulseDetect(pHookChangeData);
2896 pHookChangeData->last_state_reported = SI_HC_ONHOOK_TIMEOUT;
2897 return SI_HC_ONHOOK_TIMEOUT;
2898 }
2899
2900 if(pHookChangeData->last_hook_state == PROSLIC_OFFHOOK)
2901 {
2902 ProSLIC_ResetDialPulseDetect(pHookChangeData);
2903
2904 /* Check if we saw either a pulse digit or hook flash prior to this,
2905 * if so, we're already offhook, so do not report a offhook event,
2906 * just stop polling.
2907 */
2908 if((pHookChangeData->last_state_reported == SI_HC_ONHOOK_TIMEOUT)
2909 || (pHookChangeData->last_state_reported == SI_HC_NO_ACTIVITY) )
2910 {
2911 pHookChangeData->last_state_reported = SI_HC_OFFHOOK_TIMEOUT;
2912 return SI_HC_OFFHOOK_TIMEOUT;
2913 }
2914 else
2915 {
2916 return SI_HC_NO_ACTIVITY;
2917 }
2918 }
2919 }
2920 else
2921 {
2922 uInt8 last_digit = pHookChangeData->currentPulseDigit;
2923
2924 if(last_digit)
2925 {
2926 pHookChangeData->last_state_reported = last_digit;
2927 ProSLIC_ResetDialPulseDetect(pHookChangeData);
2928 return last_digit;
2929 }
2930 }
2931 return SI_HC_NEED_MORE_POLLS;
2932 }
2933
2934 return SI_HC_NEED_MORE_POLLS;
2935}
2936#endif /* DISABLE_HOOKCHANGE */
2937
2938/*****************************************************************************************************/
2939int ProSLIC_DTMFReadDigit (proslicChanType_ptr pProslic,uInt8 *pDigit)
2940{
2941 TRACEPRINT(pProslic, "\n", NULL);
2942
2943 if(pProslic->channelType != PROSLIC)
2944 {
2945 return RC_IGNORE;
2946 }
2947
2948 DEBUG_PRINT(pProslic, "%sDTMFReadDigit on channel %d\n",LOGPRINT_PREFIX,
2949 pProslic->channel);
2950 *pDigit = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_TONDTMF) & 0xf;
2951
2952 return RC_NONE;
2953}
2954
2955/*****************************************************************************************************/
2956int ProSLIC_PLLFreeRunStart (proslicChanType_ptr hProslic)
2957{
2958 uInt8 tmp;
2959 TRACEPRINT(hProslic, "\n", NULL);
2960
2961 if(hProslic->channelType != PROSLIC)
2962 {
2963 return RC_IGNORE;
2964 }
2965
2966 WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ZCAL_EN,0x00);
2967 tmp = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
2968
2969 return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,tmp|0x4));
2970}
2971
2972/*****************************************************************************************************/
2973int ProSLIC_PLLFreeRunStop (proslicChanType_ptr hProslic)
2974{
2975 uInt8 tmp;
2976 TRACEPRINT(hProslic, "\n", NULL);
2977
2978 if(hProslic->channelType != PROSLIC)
2979 {
2980 return RC_IGNORE;
2981 }
2982
2983 tmp = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
2984 WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,tmp&~(0x4));
2985
2986 return WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ZCAL_EN,0x04);
2987}
2988
2989/*****************************************************************************************************/
2990int ProSLIC_GetPLLFreeRunStatus (proslicChanType_ptr hProslic)
2991{
2992 uInt8 tmp;
2993 TRACEPRINT(hProslic, "\n", NULL);
2994
2995 if(hProslic->channelType != PROSLIC)
2996 {
2997 return RC_IGNORE;
2998 }
2999
3000 tmp = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
3001
3002 if(tmp & 0x02)
3003 {
3004 return RC_PLL_FREERUN_ACTIVE;
3005 }
3006
3007 return RC_NONE;
3008}
3009
3010/*****************************************************************************************************/
3011#ifndef DISABLE_PULSEMETERING
3012int ProSLIC_PulseMeterEnable (proslicChanType_ptr hProslic)
3013{
3014 uInt8 widebandEn;
3015 TRACEPRINT(hProslic, "\n", NULL);
3016
3017 if(hProslic->channelType != PROSLIC)
3018 {
3019 return RC_IGNORE;
3020 }
3021
3022 widebandEn = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE) & 0x01;
3023
3024 if (widebandEn)
3025 {
3026 DEBUG_PRINT (hProslic,
3027 "%s Pulse Metering is not supported while Wideband Mode is enabled.\n",
3028 LOGPRINT_PREFIX);
3029 }
3030
3031#if defined (SI3217X) || defined (SI3218X) || defined (SI3226X) || defined (SI3228X) || defined(SI3219X)
3032 if(!widebandEn && (0
3033#ifdef SI3217X
3034 || (hProslic->deviceId->chipType >= SI32171
3035 && hProslic->deviceId->chipType <= SI32179)
3036#endif
3037#ifdef SI3218X
3038 ||(hProslic->deviceId->chipType >= SI32180
3039 && hProslic->deviceId->chipType <= SI32189)
3040#endif
3041#ifdef SI3219X
3042 || (IS_SI3219X(hProslic->deviceId) )
3043#endif
3044#ifdef SI3226X
3045 || (hProslic->deviceId->chipType >= SI32260
3046 && hProslic->deviceId->chipType <= SI32269)
3047#endif
3048#ifdef SI3228X
3049 || (hProslic->deviceId->chipType >= SI32280
3050 && hProslic->deviceId->chipType <= SI32289 )
3051#endif
3052 ))
3053 {
3054 return WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
3055 hProslic->channel,PROSLIC_REG_PMCON) | (0x01));
3056 }
3057#endif
3058 return RC_COMPLETE_NO_ERR;
3059}
3060
3061/*****************************************************************************************************/
3062int ProSLIC_PulseMeterDisable (proslicChanType_ptr hProslic)
3063{
3064 TRACEPRINT(hProslic, "\n", NULL);
3065
3066 if(hProslic->channelType != PROSLIC)
3067 {
3068 return RC_IGNORE;
3069 }
3070
3071 return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
3072 hProslic->channel,PROSLIC_REG_PMCON) & ~(0x05)));
3073}
3074
3075/*****************************************************************************************************/
3076int ProSLIC_PulseMeterStart (proslicChanType_ptr hProslic)
3077{
3078 TRACEPRINT(hProslic, "\n", NULL);
3079
3080 if(hProslic->channelType != PROSLIC)
3081 {
3082 return RC_IGNORE;
3083 }
3084
3085 return WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
3086 hProslic->channel,PROSLIC_REG_PMCON) | (0x5));
3087}
3088
3089/*****************************************************************************************************/
3090int ProSLIC_PulseMeterStop (proslicChanType_ptr hProslic)
3091{
3092 TRACEPRINT(hProslic, "\n", NULL);
3093
3094 if(hProslic->channelType != PROSLIC)
3095 {
3096 return RC_IGNORE;
3097 }
3098
3099#ifdef SI3217X
3100 if (hProslic->deviceId->chipType >= SI32171
3101 && hProslic->deviceId->chipType <= SI32179)
3102 {
3103 return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
3104 hProslic->channel,PROSLIC_REG_PMCON) & ~(0x04)));
3105 }
3106#endif
3107
3108#ifdef SI3218X
3109 if (hProslic->deviceId->chipType >= SI32180
3110 && hProslic->deviceId->chipType <= SI32189)
3111 {
3112 return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
3113 hProslic->channel,PROSLIC_REG_PMCON) & ~(0x04)));
3114 }
3115#endif
3116
3117#ifdef SI3219X
3118 if ( IS_SI3219X(hProslic->deviceId) )
3119 {
3120 return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
3121 hProslic->channel,PROSLIC_REG_PMCON) & ~(0x04)));
3122 }
3123#endif
3124
3125#ifdef SI3226X
3126 if (hProslic->deviceId->chipType >= SI32260
3127 && hProslic->deviceId->chipType <= SI32269)
3128 {
3129 return ProSLIC_PulseMeterDisable(hProslic);
3130 }
3131#endif
3132
3133#ifdef SI3228X
3134 if (hProslic->deviceId->chipType >= SI32280
3135 && hProslic->deviceId->chipType <= SI32289)
3136 {
3137 return ProSLIC_PulseMeterDisable(hProslic);
3138 }
3139#endif
3140
3141 return RC_COMPLETE_NO_ERR;
3142}
3143#endif /* DISABLE_PULSEMETERING */
3144/*****************************************************************************************************/
3145int ProSLIC_SetDCDCInversionFlag (proslicChanType_ptr hProslic, uInt8 flag)
3146{
3147 TRACEPRINT(hProslic, "flag = %u\n", flag);
3148
3149 if(hProslic->channelType != PROSLIC)
3150 {
3151 return RC_IGNORE;
3152 }
3153
3154 hProslic->dcdc_polarity_invert = flag;
3155
3156 return RC_COMPLETE_NO_ERR;
3157}
3158
3159
3160int ProSLIC_PowerUpConverter (proslicChanType_ptr hProslic)
3161{
3162 if(hProslic->channelType != PROSLIC)
3163 {
3164 return RC_IGNORE;
3165 }
3166
3167#ifdef SI3217X
3168 if (hProslic->deviceId->chipType >= SI32171
3169 && hProslic->deviceId->chipType <= SI32179)
3170 {
3171 return Si3217x_PowerUpConverter(hProslic);
3172 }
3173#endif
3174
3175#ifdef SI3218X
3176 if (hProslic->deviceId->chipType >= SI32180
3177 && hProslic->deviceId->chipType <= SI32189)
3178 {
3179 return Si3218x_PowerUpConverter(hProslic);
3180 }
3181#endif
3182
3183#ifdef SI3219X
3184 if ( IS_SI3219X(hProslic->deviceId) )
3185 {
3186 return Si3219x_PowerUpConverter(hProslic);
3187 }
3188#endif
3189
3190#ifdef SI3226X
3191 if (hProslic->deviceId->chipType >= SI32260
3192 && hProslic->deviceId->chipType <= SI32269)
3193 {
3194 return Si3226x_PowerUpConverter(hProslic);
3195 }
3196#endif
3197
3198#ifdef SI3228X
3199 if (hProslic->deviceId->chipType >= SI32280
3200 && hProslic->deviceId->chipType <= SI32289)
3201 {
3202 return Si3228x_PowerUpConverter(hProslic);
3203 }
3204#endif
3205
3206 return RC_COMPLETE_NO_ERR;
3207}
3208/*****************************************************************************************************/
3209static int ProSLIC_GetBatType(proslicChanType_ptr hProslic)
3210{
3211#ifdef SI3226X
3212 if (hProslic->deviceId->chipType >= SI32260
3213 && hProslic->deviceId->chipType <= SI32269)
3214 {
3215 return Si3226x_General_Configuration.batType;
3216 }
3217#endif
3218
3219#ifdef SI3228X
3220 if (hProslic->deviceId->chipType >= SI32280
3221 && hProslic->deviceId->chipType <= SI32289)
3222 {
3223 return Si3228x_General_Configuration.batType;
3224 }
3225#endif
3226
3227#if !defined(SI3226X) && !defined(SI3228X)
3228 SILABS_UNREFERENCED_PARAMETER(hProslic);
3229#endif
3230 return BO_DCDC_UNKNOWN;
3231}
3232
3233/*****************************************************************************************************/
3234int ProSLIC_PowerDownConverter (proslicChanType_ptr pProslic)
3235{
3236 errorCodeType error = RC_NONE;
3237 int32 vbat;
3238 int timer = 0;
3239
3240 TRACEPRINT(pProslic, "\n", NULL);
3241
3242 if(pProslic->channelType != PROSLIC)
3243 {
3244 return RC_IGNORE;
3245 }
3246
3247 /* Force channel out of powersavings mode and then put it in open state */
3248 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_LINEFEED,LF_FWD_OHT);
3249 Delay(pProTimer,10);
3250 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_LINEFEED, LF_OPEN);
3251 Delay(pProTimer,50);
3252
3253 /* Don't try to shutdown converter if we're using external supplies or if the
3254 converter is already shutdown.
3255 */
3256 if((ProSLIC_GetBatType(pProslic) == BO_DCDC_EXTERNAL) ||
3257 (ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_PD_DCDC) & 0x100000) )
3258 {
3259 return RC_NONE;
3260 }
3261
3262 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_PD_DCDC,0x900000L);
3263 Delay(pProTimer,50);
3264
3265 do
3266 {
3267 vbat = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_MADC_VBAT);
3268 if(vbat & 0x10000000L)
3269 {
3270 vbat |= 0xF0000000L;
3271 }
3272 Delay(pProTimer,10);
3273 }
3274 while((vbat > COMP_5V) && (timer++ < PROSLIC_TIMEOUT_DCDC_DOWN));
3275
3276 DEBUG_PRINT(pProslic, "%s VBAT Down = %d.%d v\n", LOGPRINT_PREFIX,
3277 (int)((vbat/SCALE_V_MADC)/1000),
3278 SIVOICE_ABS(((vbat/SCALE_V_MADC) - (vbat/SCALE_V_MADC)/1000*1000)));
3279
3280 if(timer > PROSLIC_TIMEOUT_DCDC_DOWN)
3281 {
3282 /* Error handling - shutdown converter, disable channel, set error tag */
3283 pProslic->channelEnable = 0;
3284 pProslic->error = error = RC_VBAT_DOWN_TIMEOUT;
3285 DEBUG_PRINT(pProslic, "%sDCDC Power Down timeout channel %d\n", LOGPRINT_PREFIX,
3286 pProslic->channel);
3287 }
3288 return error;
3289}
3290
3291/*****************************************************************************************************/
3292int ProSLIC_LBCal (proslicChanType_ptr *pProslic, int size)
3293{
3294 int k;
3295 int timeout;
3296 uInt8 data;
3297 uInt8 lfState, enhance_value;
3298 TRACEPRINT(*pProslic, "size = %d\n", size);
3299
3300 if((*pProslic)->channelType != PROSLIC)
3301 {
3302 return RC_IGNORE;
3303 }
3304
3305 /* For all channels, save settings, initiate LBCAL */
3306 for(k = 0; k < size; k++)
3307 {
3308 if( (pProslic[k]->channelEnable) && (pProslic[k]->channelType == PROSLIC) )
3309 {
3310 DEBUG_PRINT(pProslic[k], "%sStarting LB Cal on channel %d\n", LOGPRINT_PREFIX,
3311 pProslic[k]->channel);
3312 /* Preserve old settings */
3313 lfState = ReadReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_LINEFEED);
3314 enhance_value = ReadReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_ENHANCE);
3315 ProSLIC_SetPowersaveMode(pProslic[k], PWRSAVE_DISABLE);
3316 ProSLIC_SetLinefeedStatus(pProslic[k], LF_FWD_ACTIVE);
3317 WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_CALR0, CAL_LB_ALL);
3318 WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_CALR3, 0x80);
3319 pProslic[k]->error = RC_CAL_TIMEOUT; /* Assume failure */
3320
3321 timeout = 0;
3322 do
3323 {
3324 data = ReadReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_CALR3);
3325 DelayX(*pProslic, 10);
3326 timeout++;
3327 }
3328 while((data & 0x80) && (timeout < TIMEOUT_LB_CAL));
3329
3330 if( (data & 0x80) )
3331 {
3332 DEBUG_PRINT(pProslic[k], "%sLB Cal timeout on channel %d\n", LOGPRINT_PREFIX,
3333 pProslic[k]->channel);
3334 WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_LINEFEED, LF_OPEN);
3335 return RC_CAL_TIMEOUT;
3336 }
3337 else
3338 {
3339 WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_LINEFEED, lfState);
3340 WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_ENHANCE, enhance_value);
3341 pProslic[k]->error = RC_NONE;
3342 }
3343 }
3344 }
3345 return RC_NONE;
3346}
3347
3348/*****************************************************************************************************/
3349#define PROSLIC_RAM_CMDAC_FWD 1476
3350#define PROSLIC_RAM_CMDAC_REV 1477
3351#define PROSLIC_RAM_CAL_TRNRD_DACT 1458
3352#define PROSLIC_RAM_CAL_TRNRD_DACR 1459
3353
3354int ProSLIC_GetLBCalResult (proslicChanType *pProslic,int32 *result1,
3355 int32 *result2, int32 *result3, int32 *result4)
3356{
3357 TRACEPRINT(pProslic, "\n", NULL);
3358
3359 if(pProslic->channelType != PROSLIC)
3360 {
3361 return RC_IGNORE;
3362 }
3363
3364 *result1 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CMDAC_FWD);
3365 *result2 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CMDAC_REV);
3366 *result3 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CAL_TRNRD_DACT);
3367 *result4 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CAL_TRNRD_DACR);
3368
3369 return RC_NONE;
3370}
3371
3372/*****************************************************************************************************/
3373int ProSLIC_GetLBCalResultPacked (proslicChanType *pProslic,int32 *result)
3374{
3375 int32 results[4];
3376 int rc;
3377 TRACEPRINT(pProslic, "\n", NULL);
3378
3379 if(pProslic->channelType != PROSLIC)
3380 {
3381 return RC_IGNORE;
3382 }
3383
3384 rc = ProSLIC_GetLBCalResult(pProslic, &(results[0]), &(results[1]),
3385 &(results[2]), &(results[3]));
3386 if(rc == RC_NONE)
3387 {
3388 /*
3389 Bits 31:24 CMDAC_FWD[25:18]
3390 Bits 23:16 CMDAC_REV[25:18]
3391 Bits 15:8 CAL_TRNRD_DACT[20:13]
3392 Bits 7:0 CAL_TRNRD_DACR[20:13]
3393 */
3394 *result = (results[0]<<6) & 0xff000000L;
3395 *result |=(results[1]>>1) & 0x00ff0000L;
3396 *result |=(results[2]>>5) & 0x0000ff00L;
3397 *result |=(results[3]>>13)& 0x000000ffL;
3398 }
3399
3400 return rc;
3401}
3402
3403/*****************************************************************************************************/
3404int ProSLIC_LoadPreviousLBCal (proslicChanType *pProslic,int32 result1,
3405 int32 result2,int32 result3,int32 result4)
3406{
3407 TRACEPRINT(pProslic, "\n", NULL);
3408 if(pProslic->channelType != PROSLIC)
3409 {
3410 return RC_IGNORE;
3411 }
3412
3413 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CMDAC_FWD,result1);
3414 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CMDAC_REV,result2);
3415 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACT,result3);
3416 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACR,result4);
3417
3418#ifdef API_TEST
3419 ramVal = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_CMDAC_FWD);
3420 LOGPRINT ("%s UNPACKED CMDAC_FWD = %08x\n", LOGPRINT_PREFIX, ramVal);
3421 ramVal = ReadRAM(pProslic, pProslic->channel,PROSLIC_RAM_CMDAC_REV);
3422 LOGPRINT ("%s UNPACKED CMDAC_REF = %08x\n", LOGPRINT_PREFIX, ramVal);
3423 ramVal = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACT);
3424 LOGPRINT ("%s UNPACKED CAL_TRNRD_DACT = %08x\n", LOGPRINT_PREFIX, ramVal);
3425 ramVal = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACR);
3426 LOGPRINT ("%s UNPACKED CAL_TRNRD_DACR = %08x\n", LOGPRINT_PREFIX, ramVal);
3427#endif
3428
3429 return RC_NONE;
3430}
3431
3432/*****************************************************************************************************/
3433int ProSLIC_LoadPreviousLBCalPacked (proslicChanType *pProslic,int32 *result)
3434{
3435 ramData ramVal[4];
3436 TRACEPRINT(pProslic, "\n", NULL);
3437
3438 if(pProslic->channelType != PROSLIC)
3439 {
3440 return RC_IGNORE;
3441 }
3442 ramVal[0] = (*result&0xff000000L)>>6;
3443 ramVal[1] = (*result&0x00ff0000L)<<1;
3444 ramVal[2] = (*result&0x0000ff00L)<<5;
3445 ramVal[3] = (*result&0x000000ffL)<<13;
3446
3447 return ProSLIC_LoadPreviousLBCal(pProslic, ramVal[0], ramVal[1], ramVal[2],
3448 ramVal[3]);
3449}
3450
3451/*****************************************************************************************************/
3452int ProSLIC_dbgSetDCFeedVopen (proslicChanType *pProslic, uInt32 v_vlim_val,
3453 int32 preset)
3454{
3455 TRACEPRINT(pProslic, "v_vlim_val = %u preset = %d\n", v_vlim_val, preset);
3456 if(pProslic->channelType != PROSLIC)
3457 {
3458 return RC_IGNORE;
3459 }
3460#ifdef SI3217X
3461 if (pProslic->deviceId->chipType >= SI32171
3462 && pProslic->deviceId->chipType <= SI32179)
3463 {
3464 return Si3217x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
3465 }
3466#endif
3467
3468#ifdef SI3218X
3469 if (pProslic->deviceId->chipType >= SI32180
3470 && pProslic->deviceId->chipType <= SI32189)
3471 {
3472 return Si3218x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
3473 }
3474#endif
3475
3476#ifdef SI3219X
3477 if ( IS_SI3219X(pProslic->deviceId) )
3478 {
3479 return Si3219x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
3480 }
3481#endif
3482
3483#ifdef SI3226X
3484 if (pProslic->deviceId->chipType >= SI32260
3485 && pProslic->deviceId->chipType <= SI32269)
3486 {
3487 return Si3226x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
3488 }
3489#endif
3490
3491#ifdef SI3228X
3492 if (pProslic->deviceId->chipType >= SI32280
3493 && pProslic->deviceId->chipType <= SI32289)
3494 {
3495 return Si3228x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
3496 }
3497#endif
3498
3499 return RC_COMPLETE_NO_ERR;
3500}
3501
3502/*****************************************************************************************************/
3503int ProSLIC_dbgSetDCFeedIloop (proslicChanType *pProslic, uInt32 i_ilim_val,
3504 int32 preset)
3505{
3506 TRACEPRINT(pProslic, "i_ilim_val = %u preset = %d\n", i_ilim_val, preset);
3507
3508 if(pProslic->channelType != PROSLIC)
3509 {
3510 return RC_IGNORE;
3511 }
3512#ifdef SI3217X
3513 if (pProslic->deviceId->chipType >= SI32171
3514 && pProslic->deviceId->chipType <= SI32179)
3515 {
3516 return Si3217x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
3517 }
3518#endif
3519
3520#ifdef SI3218X
3521 if (pProslic->deviceId->chipType >= SI32180
3522 && pProslic->deviceId->chipType <= SI32189)
3523 {
3524 return Si3218x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
3525 }
3526#endif
3527
3528#ifdef SI3219X
3529 if ( IS_SI3219X(pProslic->deviceId) )
3530 {
3531 return Si3219x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
3532 }
3533#endif
3534
3535#ifdef SI3226X
3536 if (pProslic->deviceId->chipType >= SI32260
3537 && pProslic->deviceId->chipType <= SI32269)
3538 {
3539 return Si3226x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
3540 }
3541#endif
3542
3543#ifdef SI3228X
3544 if (pProslic->deviceId->chipType >= SI32280
3545 && pProslic->deviceId->chipType <= SI32289)
3546 {
3547 return Si3228x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
3548 }
3549#endif
3550
3551 return RC_COMPLETE_NO_ERR;
3552}
3553
3554/*****************************************************************************************************/
3555int ProSLIC_dbgSetRinging (proslicChanType *pProslic,
3556 ProSLIC_dbgRingCfg *ringCfg, int preset)
3557{
3558 TRACEPRINT(pProslic, "preset = %d\n", preset);
3559
3560 if(pProslic->channelType != PROSLIC)
3561 {
3562 return RC_IGNORE;
3563 }
3564
3565#ifdef SI3217X
3566 if (pProslic->deviceId->chipType >= SI32171
3567 && pProslic->deviceId->chipType <= SI32179)
3568 {
3569 return Si3217x_dbgSetRinging (pProslic,ringCfg,preset);
3570 }
3571#endif
3572
3573#ifdef SI3218X
3574 if (pProslic->deviceId->chipType >= SI32180
3575 && pProslic->deviceId->chipType <= SI32189)
3576 {
3577 return Si3218x_dbgSetRinging (pProslic,ringCfg,preset);
3578 }
3579#endif
3580
3581#ifdef SI3219X
3582 if ( IS_SI3219X(pProslic->deviceId) )
3583 {
3584 return Si3219x_dbgSetRinging (pProslic,ringCfg,preset);
3585 }
3586#endif
3587
3588#ifdef SI3226X
3589 if (pProslic->deviceId->chipType >= SI32260
3590 && pProslic->deviceId->chipType <= SI32269)
3591 {
3592 return Si3226x_dbgSetRinging (pProslic,ringCfg,preset);
3593 }
3594#endif
3595
3596#ifdef SI3228X
3597 if (pProslic->deviceId->chipType >= SI32280
3598 && pProslic->deviceId->chipType <= SI32289)
3599 {
3600 return Si3228x_dbgSetRinging (pProslic,ringCfg,preset);
3601 }
3602#endif
3603
3604 return RC_COMPLETE_NO_ERR;
3605}
3606
3607/*****************************************************************************************************/
3608int ProSLIC_dbgSetRXGain (proslicChanType *pProslic, int32 gain,
3609 int impedance_preset, int audio_gain_preset)
3610{
3611 TRACEPRINT(pProslic, "gain = %d imp_preset = %d audio_gain_preset = %d\n", gain,
3612 impedance_preset, audio_gain_preset);
3613 if(pProslic->channelType != PROSLIC)
3614 {
3615 return RC_IGNORE;
3616 }
3617
3618#ifdef SI3217X
3619 if (pProslic->deviceId->chipType >= SI32171
3620 && pProslic->deviceId->chipType <= SI32179)
3621 {
3622 return Si3217x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
3623 }
3624#endif
3625
3626#ifdef SI3218X
3627 if (pProslic->deviceId->chipType >= SI32180
3628 && pProslic->deviceId->chipType <= SI32189)
3629 {
3630 return Si3218x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
3631 }
3632#endif
3633
3634#ifdef SI3219X
3635 if ( IS_SI3219X(pProslic->deviceId) )
3636 {
3637 return Si3219x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
3638 }
3639#endif
3640
3641#ifdef SI3226X
3642 if (pProslic->deviceId->chipType >= SI32260
3643 && pProslic->deviceId->chipType <= SI32269)
3644 {
3645 return Si3226x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
3646 }
3647#endif
3648
3649#ifdef SI3228X
3650 if (pProslic->deviceId->chipType >= SI32280
3651 && pProslic->deviceId->chipType <= SI32289)
3652 {
3653 return Si3228x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
3654 }
3655#endif
3656
3657 return RC_COMPLETE_NO_ERR;
3658}
3659
3660/*****************************************************************************************************/
3661int ProSLIC_dbgSetTXGain (proslicChanType *pProslic, int32 gain,
3662 int impedance_preset, int audio_gain_preset)
3663{
3664 TRACEPRINT(pProslic, "gain = %d imp_preset = %d audio_gain_preset = %d\n", gain,
3665 impedance_preset, audio_gain_preset);
3666
3667 if(pProslic->channelType != PROSLIC)
3668 {
3669 return RC_IGNORE;
3670 }
3671
3672#ifdef SI3217X
3673 if (pProslic->deviceId->chipType >= SI32171
3674 && pProslic->deviceId->chipType <= SI32179)
3675 {
3676 return Si3217x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
3677 }
3678#endif
3679
3680#ifdef SI3218X
3681 if (pProslic->deviceId->chipType >= SI32180
3682 && pProslic->deviceId->chipType <= SI32189)
3683 {
3684 return Si3218x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
3685 }
3686#endif
3687
3688#ifdef SI3219X
3689 if ( IS_SI3219X(pProslic->deviceId) )
3690 {
3691 return Si3219x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
3692 }
3693#endif
3694
3695#ifdef SI3226X
3696 if (pProslic->deviceId->chipType >= SI32260
3697 && pProslic->deviceId->chipType <= SI32269)
3698 {
3699 return Si3226x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
3700 }
3701#endif
3702
3703#ifdef SI3228X
3704 if (pProslic->deviceId->chipType >= SI32280
3705 && pProslic->deviceId->chipType <= SI32289)
3706 {
3707 return Si3228x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
3708 }
3709#endif
3710
3711 return RC_COMPLETE_NO_ERR;
3712}
3713
3714/*****************************************************************************************************/
3715/*
3716** Function: ProSLIC_LineMonitor
3717**
3718** Description:
3719** Generic monitoring function
3720**
3721** Returns:
3722** 0
3723*/
3724
3725int ProSLIC_LineMonitor (proslicChanType *pProslic, proslicMonitorType *monitor)
3726{
3727 TRACEPRINT(pProslic, "\n", NULL);
3728
3729 if(pProslic->channelType != PROSLIC)
3730 {
3731 return RC_IGNORE;
3732 }
3733
3734#ifdef SI3217X
3735 if (pProslic->deviceId->chipType >= SI32171
3736 && pProslic->deviceId->chipType <= SI32179)
3737 {
3738 return Si3217x_LineMonitor (pProslic, monitor);
3739 }
3740#endif
3741
3742#ifdef SI3218X
3743 if (pProslic->deviceId->chipType >= SI32180
3744 && pProslic->deviceId->chipType <= SI32189)
3745 {
3746 return Si3218x_LineMonitor (pProslic, monitor);
3747 }
3748#endif
3749
3750#ifdef SI3219X
3751 if ( IS_SI3219X(pProslic->deviceId) )
3752 {
3753 return Si3219x_LineMonitor (pProslic, monitor);
3754 }
3755#endif
3756
3757#ifdef SI3226X
3758 if (pProslic->deviceId->chipType >= SI32260
3759 && pProslic->deviceId->chipType <= SI32269)
3760 {
3761 return Si3226x_LineMonitor (pProslic, monitor);
3762 }
3763#endif
3764
3765#ifdef SI3228X
3766 if (pProslic->deviceId->chipType >= SI32280
3767 && pProslic->deviceId->chipType <= SI32289)
3768 {
3769 return Si3228x_LineMonitor (pProslic, monitor);
3770 }
3771#endif
3772
3773 return RC_COMPLETE_NO_ERR;
3774}
3775
3776/*****************************************************************************************************/
3777/*
3778** Function: ProSLIC_PSTNCheck
3779**
3780** Description:
3781** Monitor for excessive longitudinal current, which
3782** would be present if a live pstn line was connected
3783** to the port.
3784**
3785** Returns:
3786** 0 - no pstn detected
3787** 1 - pstn detected
3788*/
3789int ProSLIC_PSTNCheck (proslicChanType *pProslic,
3790 proslicPSTNCheckObjType *pPSTNCheck)
3791{
3792 TRACEPRINT(pProslic, "\n", NULL);
3793 if(pProslic->channelType != PROSLIC)
3794 {
3795 return RC_IGNORE;
3796 }
3797
3798#ifdef SI3217X
3799 if (pProslic->deviceId->chipType >= SI32171
3800 && pProslic->deviceId->chipType <= SI32179)
3801 {
3802 return Si3217x_PSTNCheck (pProslic,pPSTNCheck);
3803 }
3804#endif
3805
3806#ifdef SI3218X
3807 if (pProslic->deviceId->chipType >= SI32180
3808 && pProslic->deviceId->chipType <= SI32189)
3809 {
3810 return Si3218x_PSTNCheck (pProslic,pPSTNCheck);
3811 }
3812#endif
3813
3814#ifdef SI3219X
3815 if ( IS_SI3219X(pProslic->deviceId) )
3816 {
3817 return Si3219x_PSTNCheck (pProslic,pPSTNCheck);
3818 }
3819#endif
3820
3821#ifdef SI3226X
3822 if (pProslic->deviceId->chipType >= SI32260
3823 && pProslic->deviceId->chipType <= SI32269)
3824 {
3825 return Si3226x_PSTNCheck (pProslic,pPSTNCheck);
3826 }
3827#endif
3828
3829#ifdef SI3228X
3830 if (pProslic->deviceId->chipType >= SI32280
3831 && pProslic->deviceId->chipType <= SI32289)
3832 {
3833 return Si3228x_PSTNCheck (pProslic,pPSTNCheck);
3834 }
3835#endif
3836
3837 return RC_COMPLETE_NO_ERR;
3838}
3839
3840/*****************************************************************************************************/
3841/*
3842** Function: ProSLIC_DiffPSTNCheck
3843**
3844** Description:
3845** Monitor for excessive longitudinal current, which
3846** would be present if a live pstn line was connected
3847** to the port.
3848**
3849** Returns:
3850** RC_NONE - test in progress
3851** RC_IGNORE - non-ProSLIC channel
3852** RC_COMPLETE_NO_ERR - ProSLIC does not support feature.
3853** RC_PSTN_OPEN_FEMF | RC_COMPLETE_NO_ERR - test completed.
3854**
3855*/
3856#ifdef PSTN_DET_ENABLE
3857int ProSLIC_DiffPSTNCheck (proslicChanType *pProslic,
3858 proslicDiffPSTNCheckObjType *pPSTNCheck)
3859{
3860 TRACEPRINT(pProslic, "\n", NULL);
3861
3862 if(pProslic->channelType != PROSLIC)
3863 {
3864 return RC_IGNORE;
3865 }
3866
3867#ifdef SI3217X
3868 if (pProslic->deviceId->chipType >= SI32171
3869 && pProslic->deviceId->chipType <= SI32179)
3870 {
3871 return Si3217x_DiffPSTNCheck (pProslic,pPSTNCheck);
3872 }
3873#endif
3874
3875#ifdef SI3218X
3876 if (pProslic->deviceId->chipType >= SI32180
3877 && pProslic->deviceId->chipType <= SI32189)
3878 {
3879 return Si3218x_DiffPSTNCheck (pProslic,pPSTNCheck);
3880 }
3881#endif
3882
3883#ifdef SI3219X
3884 if ( IS_SI3219X(pProslic->deviceId) )
3885 {
3886 return Si3219x_DiffPSTNCheck (pProslic,pPSTNCheck);
3887 }
3888#endif
3889
3890#ifdef SI3226X
3891 if (pProslic->deviceId->chipType >= SI32260
3892 && pProslic->deviceId->chipType <= SI32269)
3893 {
3894 return Si3226x_DiffPSTNCheck (pProslic,pPSTNCheck);
3895 }
3896#endif
3897
3898#ifdef SI3228X
3899 if (pProslic->deviceId->chipType >= SI32280
3900 && pProslic->deviceId->chipType <= SI32289)
3901 {
3902 return Si3228x_DiffPSTNCheck (pProslic,pPSTNCheck);
3903 }
3904#endif
3905
3906 return RC_COMPLETE_NO_ERR;
3907}
3908#endif
3909
3910/*****************************************************************************************************/
3911/*
3912** Function: ProSLIC_CreatePSTNCheckObj
3913**
3914** Description:
3915** Allocate memory for pstnCheckObj
3916**
3917** Returns:
3918** RC_NONE
3919** RC_NO_MEM if failed to allocate memory.
3920** RC_UNSUPPORTED_FEATER if malloc disabled
3921*/
3922int ProSLIC_CreatePSTNCheckObjs(proslicPSTNCheckObjType_ptr *pstnCheckObj,
3923 unsigned int num_objs)
3924{
3925 TRACEPRINT_NOCHAN("num_objs = %u\n", num_objs);
3926#ifndef DISABLE_MALLOC
3927 *pstnCheckObj = SIVOICE_CALLOC(sizeof(proslicPSTNCheckObjType),num_objs);
3928 if(*pstnCheckObj == NULL)
3929 {
3930#ifdef ENABLE_DEBUG
3931 LOGPRINT("%s: %s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
3932#endif
3933 return RC_NO_MEM;
3934 }
3935 return RC_NONE;
3936#else
3937 SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
3938 SILABS_UNREFERENCED_PARAMETER(num_objs);
3939 return RC_UNSUPPORTED_FEATURE;
3940#endif
3941}
3942
3943/*****************************************************************************************************/
3944/*
3945** Function: ProSLIC_CreateDiffPSTNCheckObjs
3946**
3947** Description:
3948** Allocate memory for proslicDiffPstnCheckObjs
3949**
3950** Returns:
3951** RC_NONE
3952** RC_NO_MEM if failed to allocate memory.
3953** RC_UNSUPPORTED_FEATURE if malloc disabled
3954*/
3955
3956#ifdef PSTN_DET_ENABLE
3957int ProSLIC_CreateDiffPSTNCheckObjs(proslicDiffPSTNCheckObjType_ptr
3958 *pstnCheckObj, unsigned int num_objs)
3959{
3960 TRACEPRINT_NOCHAN("num_objs = %u\n", num_objs);
3961
3962#ifndef DISABLE_MALLOC
3963 *pstnCheckObj = SIVOICE_CALLOC(sizeof(proslicDiffPSTNCheckObjType),num_objs);
3964 if(*pstnCheckObj == NULL)
3965 {
3966#ifdef ENABLE_DEBUG
3967 LOGPRINT("%s: %s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
3968#endif
3969 return RC_NO_MEM;
3970 }
3971 return RC_NONE;
3972#else
3973 SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
3974 SILABS_UNREFERENCED_PARAMETER(num_objs);
3975 return RC_UNSUPPORTED_FEATURE;
3976#endif
3977}
3978#endif
3979
3980/*****************************************************************************************************/
3981/*
3982** Function: ProSLIC_DestroyPSTNCheckObjs
3983**
3984** Description:
3985** Free memory for pstnCheckObj
3986**
3987** Returns:
3988** RC_NONE
3989** RC_UNSUPPORTED_FEATER if malloc disabled
3990*/
3991int ProSLIC_DestroyPSTNCheckObjs(proslicPSTNCheckObjType_ptr *pstnCheckObj)
3992{
3993 TRACEPRINT_NOCHAN("\n", NULL);
3994
3995#ifndef DISABLE_MALLOC
3996 if(pstnCheckObj)
3997 {
3998 SIVOICE_FREE((proslicPSTNCheckObjType_ptr)*pstnCheckObj);
3999 }
4000
4001 return RC_NONE;
4002
4003#else
4004 SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
4005 return RC_UNSUPPORTED_FEATURE;
4006#endif
4007}
4008
4009/*****************************************************************************************************/
4010/*
4011** Function: ProSLIC_DestroyDiffPSTNCheckObjs
4012**
4013** Description:
4014** Free memory for pstnDiffCheckObj
4015**
4016** Returns:
4017** RC_NONE
4018** RC_UNSUPPORTED_FEATER if malloc disabled
4019*/
4020#ifdef PSTN_DET_ENABLE
4021int ProSLIC_DestroyDiffPSTNCheckObjs(proslicDiffPSTNCheckObjType_ptr
4022 *pstnCheckObj)
4023{
4024 TRACEPRINT_NOCHAN("\n", NULL);
4025
4026#ifndef DISABLE_MALLOC
4027 if(pstnCheckObj)
4028 {
4029 SIVOICE_FREE((proslicDiffPSTNCheckObjType_ptr)*pstnCheckObj);
4030 }
4031 return RC_NONE;
4032#else
4033 SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
4034 return RC_UNSUPPORTED_FEATURE;
4035#endif
4036}
4037#endif
4038
4039/*****************************************************************************************************/
4040/*
4041** Function: ProSLIC_InitPSTNCheckObj
4042**
4043** Description:
4044** Initialize pstnCheckObj structure members
4045**
4046** Returns:
4047** RC_NONE
4048*/
4049int ProSLIC_InitPSTNCheckObj(proslicPSTNCheckObjType_ptr pstnCheckObj,
4050 int32 avgThresh, int32 singleThresh, uInt8 samples)
4051{
4052 TRACEPRINT_NOCHAN("avgThres = %d singleThresh = %d samples = %u\n", avgThresh,
4053 avgThresh, samples);
4054
4055 pstnCheckObj->avgThresh = avgThresh;
4056 pstnCheckObj->singleThresh = singleThresh;
4057 pstnCheckObj->samples = samples;
4058 pstnCheckObj->avgIlong = 0;
4059 pstnCheckObj->count = 0;
4060 pstnCheckObj->buffFull = 0;
4061
4062 return RC_NONE;
4063}
4064
4065/*****************************************************************************************************/
4066/*
4067** Function: ProSLIC_InitDiffPSTNCheckObj
4068**
4069** Description:
4070** Initialize pstnCheckObj structure members
4071**
4072** Returns:
4073** RC_NONE
4074*/
4075#ifdef PSTN_DET_ENABLE
4076int ProSLIC_InitDiffPSTNCheckObj(proslicDiffPSTNCheckObjType_ptr
4077 pstnDiffCheckObj,
4078 int preset1,
4079 int preset2,
4080 int entry_preset,
4081 int femf_enable)
4082{
4083 TRACEPRINT_NOCHAN("p1 = %d p2 = %d ep = %d femf_enable = %d\n", preset1,
4084 preset2, entry_preset, femf_enable);
4085
4086 pstnDiffCheckObj->samples = PSTN_DET_DIFF_SAMPLES;
4087 pstnDiffCheckObj->max_femf_vopen = PSTN_DET_MAX_FEMF;
4088 pstnDiffCheckObj->entryDCFeedPreset = entry_preset;
4089 pstnDiffCheckObj->dcfPreset1 = preset1;
4090 pstnDiffCheckObj->dcfPreset2 = preset2;
4091 pstnDiffCheckObj->femf_enable = femf_enable;
4092 pstnDiffCheckObj->pState.stage = 0;
4093 pstnDiffCheckObj->pState.sampleIterations = 0;
4094 pstnDiffCheckObj->pState.waitIterations = 0;
4095
4096 return RC_NONE;
4097}
4098#endif
4099
4100/*****************************************************************************************************/
4101/*
4102** Function: ProSLIC_SetPwrsaveMode
4103**
4104** Description:
4105** Enable or disable powersave mode
4106**
4107** Returns:
4108** RC_NONE
4109*/
4110#define PROSLIC_REG_ENHANCE 47
4111
4112int ProSLIC_SetPowersaveMode (proslicChanType *pProslic, int pwrsave)
4113{
4114 uInt8 regData;
4115 TRACEPRINT(pProslic, "pwrsave = %d\n", pwrsave);
4116
4117 if(pProslic->channelType != PROSLIC)
4118 {
4119 return RC_IGNORE;
4120 }
4121
4122 regData = ReadReg(pProslic,pProslic->channel, PROSLIC_REG_ENHANCE);
4123
4124 if(pwrsave == PWRSAVE_DISABLE)
4125 {
4126#ifdef SI3217X
4127 if (pProslic->deviceId->chipType >= SI32171
4128 && pProslic->deviceId->chipType <= SI32179)
4129 {
4130 regData &= 0x27;
4131 }
4132 else
4133 {
4134#endif
4135 regData &= 0x07;
4136#ifdef SI3217X
4137 }
4138#endif
4139 }
4140 else
4141 {
4142 regData |= 0x10;
4143 }
4144
4145 return WriteReg(pProslic,pProslic->channel, PROSLIC_REG_ENHANCE, regData);
4146}
4147
4148/*****************************************************************************************************/
4149/*
4150** Function: ProSLIC_SetDAAEnable
4151**
4152** Description:
4153** Enable or disable adjacent FXO (Si32178 only)
4154**
4155** Returns:
4156** RC_NONE
4157*/
4158int ProSLIC_SetDAAEnable (proslicChanType *pProslic, int enable)
4159{
4160 TRACEPRINT(pProslic, "\n", NULL);
4161
4162 if(pProslic->channelType != PROSLIC)
4163 {
4164 return RC_IGNORE;
4165 }
4166
4167#ifdef SI3217X
4168 return Si3217x_SetDAAEnable (pProslic,enable);
4169#else
4170 SILABS_UNREFERENCED_PARAMETER(enable);
4171 return RC_NONE;
4172#endif
4173}
4174
4175/*****************************************************************************************************/
4176/*
4177** Function: ProSLIC_SetUserMode
4178**
4179** Description: Enables User Access Mode (UAM) if the part supports it.
4180**
4181** Returns:
4182** RC_NONE if successful.
4183*/
4184#define PROSLIC_REG_USERMODE_ENABLE 126
4185
4186int ProSLIC_SetUserMode(proslicChanType *pProslic,BOOLEAN isEnabled,
4187 BOOLEAN isBcast)
4188{
4189 uInt8 data;
4190 uInt8 channel;
4191
4192 TRACEPRINT(pProslic, "enable = %d bcast = %d\n", (int)isEnabled, (int)isBcast);
4193
4194 if(isEnabled == FALSE)
4195 {
4196 return RC_NONE;
4197 }
4198
4199 if( pProslic->channelType != PROSLIC )
4200 {
4201 return RC_UNSUPPORTED_FEATURE;
4202 }
4203
4204 if(isBcast == TRUE)
4205 {
4206 channel = PROSLIC_CHAN_BROADCAST;
4207 }
4208 else
4209 {
4210 channel = pProslic->channel;
4211 }
4212
4213 data = ReadReg(pProslic,pProslic->channel,
4214 PROSLIC_REG_USERMODE_ENABLE); /*we check first channel. we assume all channels same user mode state for broadcast */
4215
4216 if (((data&1) != 0) == isEnabled)
4217 {
4218 return RC_NONE;
4219 }
4220
4221 WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,2);
4222 WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,8);
4223 WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,0xe);
4224 return WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,0);
4225}
4226
4227/*****************************************************************************************************/
4228/*
4229** Function: ProSLIC_isReinitRequired
4230**
4231** Description:
4232** Checks for improper ring exit
4233**
4234** Returns:
4235** RC_NONE - Reinit not required
4236** RC_REINIT_REQUIRED - Corrupted state machine - reinit required
4237**
4238*/
4239
4240int ProSLIC_isReinitRequired(proslicChanType *pProslic)
4241{
4242 uInt8 lf;
4243 ramData rkdc_sum;
4244 TRACEPRINT(pProslic, "\n", NULL);
4245
4246 if( pProslic->channelType != PROSLIC)
4247 {
4248 return RC_IGNORE;
4249 }
4250
4251 /* Check for improper ring exit which may cause dcfeed corruption */
4252
4253 lf = ReadReg(pProslic, pProslic->channel,PROSLIC_REG_LINEFEED);
4254 rkdc_sum = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_RDC_SUM);
4255 DEBUG_PRINT(pProslic, "%sisReinitRequired: Linefeed = 0x%02X RDC_SUM = %d\n",
4256 LOGPRINT_PREFIX, (int)lf, (int) rkdc_sum);
4257 if((rkdc_sum & 0x400000)&&(lf != 0x44))
4258 {
4259 return RC_REINIT_REQUIRED;
4260 }
4261 else
4262 {
4263 return RC_NONE;
4264 }
4265}
4266
4267/*****************************************************************************************************/
4268/*
4269** Function: LoadRegTable
4270**
4271** Description:
4272** Generic function to load register/RAM with predefined addr/value
4273*/
4274int ProSLIC_LoadRegTable (proslicChanType *pProslic,
4275 const ProslicRAMInit *pRamTable,
4276 const ProslicRegInit *pRegTable,
4277 int broadcast)
4278{
4279 uInt16 i;
4280 uInt8 channel;
4281
4282 TRACEPRINT(pProslic, "bcast = %d\n", broadcast);
4283 /* DAA doesn't have a RAM table.. skip it... */
4284 if( (pRamTable != 0)
4285 && (pProslic->channelType != PROSLIC) )
4286 {
4287 return RC_IGNORE;
4288 }
4289
4290 if (broadcast)
4291 {
4292 channel = PROSLIC_CHAN_BROADCAST;
4293 }
4294 else
4295 {
4296 channel = pProslic->channel;
4297 }
4298
4299 i=0;
4300 if (pRamTable != 0)
4301 {
4302 while (pRamTable[i].address != 0xffff)
4303 {
4304 WriteRAM(pProslic,channel,pRamTable[i].address,pRamTable[i].initValue);
4305 i++;
4306 }
4307 }
4308 i=0;
4309 if (pRegTable != 0)
4310 {
4311 while (pRegTable[i].address != 0xff)
4312 {
4313 WriteReg(pProslic,channel,pRegTable[i].address,pRegTable[i].initValue);
4314 i++;
4315 }
4316 }
4317
4318 return RC_NONE;
4319}
4320
4321/*****************************************************************************************************/
4322/*
4323** Function: LoadRegTables
4324**
4325** Description:
4326** Generic function to load register/RAM with predefined addr/value
4327*/
4328
4329int ProSLIC_LoadRegTables(proslicChanType_ptr *pProslic,
4330 const ProslicRAMInit *pRamTable, const ProslicRegInit *pRegTable, int size)
4331{
4332 int i;
4333 TRACEPRINT(*pProslic, "size = %d\n", size);
4334 for (i=0; i<size; i++)
4335 {
4336 if (pProslic[i]->channelEnable)
4337 {
4338 ProSLIC_LoadRegTable(pProslic[i],pRamTable,pRegTable,FALSE);
4339 }
4340 }
4341 return RC_NONE;
4342}
4343
4344/*****************************************************************************************************/
4345int ProSLIC_UnsupportedFeatureNoArg(proslicChanType_ptr pProslic,
4346 const char *function_name)
4347{
4348#ifdef ENABLE_DEBUG
4349 LOGPRINT("%s: unsupported %s was called on channel %d\n", LOGPRINT_PREFIX,
4350 function_name, pProslic->channel);
4351#else
4352 SILABS_UNREFERENCED_PARAMETER(pProslic);
4353 SILABS_UNREFERENCED_PARAMETER(function_name);
4354#endif
4355 return RC_UNSUPPORTED_FEATURE;
4356}
4357
4358/*****************************************************************************************************/
4359/*
4360** Function: ProSLIC_PSTN_delay_poll
4361**
4362** Description:
4363** Delay function called within PSTN detection functions
4364**
4365** Return Value:
4366** none
4367*/
4368#ifdef PSTN_DET_ENABLE
4369void ProSLIC_PSTN_delay_poll(proslicTestStateType *pState, uInt16 delay)
4370{
4371 uInt16 delayCount;
4372
4373 if((delay/PSTN_DET_POLL_RATE) < 2)
4374 {
4375 delayCount = 0;
4376 }
4377 else
4378 {
4379 delayCount = (delay/PSTN_DET_POLL_RATE) - 2;
4380 }
4381
4382 pState->waitIterations++;
4383 if((pState->waitIterations == delayCount) || (delayCount == 0))
4384 {
4385 pState->waitIterations = 0;
4386 pState->stage++;
4387 }
4388}
4389#endif
4390
4391/*****************************************************************************************************/
4392/*
4393** Function: ProSLIC_Calibrate
4394**
4395** Description:
4396** Performs calibration based on passed ptr to array of
4397** desired CALRn settings.
4398**
4399** Starts calibration on all channels sequentially (not broadcast)
4400** and continuously polls for completion. Return error code if
4401** CAL_EN does not clear for each enabled channel within the passed
4402** timeout period.
4403*/
4404int ProSLIC_Calibrate(proslicChanType_ptr *pProslic, int maxChan, uInt8 *calr,
4405 int maxTime)
4406{
4407 int i,j, cal_en;
4408 int cal_en_chan = 0;
4409 int timer = 0;
4410
4411 TRACEPRINT(*pProslic, "maxChan = %d time = %d\n", maxChan, maxTime );
4412
4413 if ((*pProslic)->channelType != PROSLIC)
4414 {
4415 return RC_CHANNEL_TYPE_ERR;
4416 }
4417
4418 for(i = 0; i < maxChan; i++)
4419 {
4420 if((pProslic[i]->channelEnable)&&(pProslic[i]->channelType == PROSLIC))
4421 {
4422 for(j = 0; j < 4; j++)
4423 {
4424 WriteReg(pProslic[i], pProslic[i]->channel, (PROSLIC_REG_CALR0+j), calr[j]);
4425 }
4426 }
4427 }
4428
4429 /* Wait for calibration to complete */
4430 do
4431 {
4432 cal_en = 0;
4433 DelayX(*pProslic, 10);
4434 for(i = 0; i < maxChan; i++)
4435 {
4436 if( (pProslic[i]->channelEnable) && (pProslic[i]->channelType == PROSLIC))
4437 {
4438 cal_en_chan = ReadReg(pProslic[i], pProslic[i]->channel, PROSLIC_REG_CALR3);
4439 if( (cal_en_chan & 0x80) && (timer == maxTime) )
4440 {
4441 DEBUG_PRINT(pProslic[i], "%sCalibration timed out on channel %d\n",
4442 LOGPRINT_PREFIX, pProslic[i]->channel);
4443 pProslic[i]->channelEnable = 0;
4444 pProslic[i]->error = RC_CAL_TIMEOUT;
4445 }
4446 cal_en |= cal_en_chan;
4447 }
4448 }
4449 }
4450 while( (timer++ <= maxTime) && (cal_en & 0x80) );
4451
4452 if(timer <= maxTime)
4453 {
4454 return RC_NONE;
4455 }
4456 else
4457 {
4458 return RC_CAL_TIMEOUT;
4459 }
4460}
4461/*****************************************************************************************************/
4462/* This function is used by the xxxx_Init_with_Options - do not call this directly... */
4463int ProSLIC_ReInit_helper(proslicChanType_ptr *pProslic, int size,
4464 initOptionsType init_option, int numChanPerDevice)
4465{
4466 int i;
4467
4468 /* Preserve linefeed state.. */
4469 for(i = 0; i < size; i++)
4470 {
4471 pProslic[i]->scratch = ReadReg( pProslic[i], pProslic[i]->channel,
4472 PROSLIC_REG_LINEFEED);
4473 ProSLIC_PowerDownConverter( pProslic[i] );
4474
4475 /* Clear MSTRSTAT on a device basis */
4476 if( (numChanPerDevice == 1)
4477 || ((numChanPerDevice == 2) && ((i&1) == 0) ) )
4478 {
4479 ProSLIC_WriteReg(pProslic[i], PROSLIC_REG_MSTRSTAT, 0xFF); /* Clear master status register */
4480 }
4481 }
4482
4483 DelayX(*pProslic, 10); /* Wait to ensure system is powered down... */
4484
4485 /* Do a soft reset if reinit is requested...*/
4486 if(init_option == INIT_REINIT)
4487 {
4488 for(i = 0; i < size; i++)
4489 {
4490 if(numChanPerDevice == 2)
4491 {
4492 WriteReg(pProslic[i], (pProslic[i])->channel, PROSLIC_REG_RESET,
4493 (((pProslic[i])->channel)&1)+1); /* reset 1 channel at a time */
4494 }
4495 else
4496 {
4497 WriteReg(pProslic[i], (pProslic[i])->channel, PROSLIC_REG_RESET, 1);
4498 }
4499
4500 pProslic[i]->error = RC_NONE; /* Clear any errors we may have seen in powering down the converter */
4501 }
4502 DelayX(*pProslic, 100); /* Wait for a soft reset */
4503
4504 }
4505 return RC_NONE;
4506}
4507
4508/*****************************************************************************************************/
4509int ProSLIC_SoftReset(proslicChanType_ptr pProslic, uInt16 resetOptions)
4510{
4511 uInt8 data;
4512
4513 TRACEPRINT(pProslic, "reset option: %d\n",resetOptions);
4514
4515 /* We can't use channelType since it may not been set. We assume at least
4516 * SWInit was called... */
4517 if( pProslic->deviceId->chipType == SI3050 )
4518 {
4519 return RC_CHANNEL_TYPE_ERR;
4520 }
4521
4522 /* Check if we're in free-run mode, if so abort */
4523 data = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_ENHANCE);
4524
4525 if(data & 0x6)
4526 {
4527 return RC_PLL_FREERUN_ACTIVE;
4528 }
4529
4530 if(resetOptions & PROSLIC_BCAST_RESET)
4531 {
4532 return WriteReg(pProslic, PROSLIC_CHAN_BROADCAST, PROSLIC_REG_RESET, (uInt8)(resetOptions & 0xFF));
4533 }
4534 else
4535 {
4536 return WriteReg(pProslic, pProslic->channel, PROSLIC_REG_RESET, (uInt8)(resetOptions & 0xFF));
4537 }
4538}
4539
4540/*****************************************************************************************************/
4541#ifndef DISABLE_TONE_SETUP
4542int ProSLIC_ToneGenSetupPtr(proslicChanType_ptr pProslic, ProSLIC_Tone_Cfg *cfg)
4543{
4544 TRACEPRINT(pProslic, "\n",NULL);
4545
4546 if(pProslic->channelType != PROSLIC)
4547 {
4548 return RC_CHANNEL_TYPE_ERR;
4549 }
4550
4551 WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC1FREQ, cfg->osc1.freq);
4552 WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC1AMP, cfg->osc1.amp);
4553 WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC1PHAS, cfg->osc1.phas);
4554 WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TAHI,cfg->osc1.tahi);
4555 WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TALO,cfg->osc1.talo);
4556 WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TIHI,cfg->osc1.tihi);
4557 WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TILO,cfg->osc1.tilo);
4558
4559 WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC2FREQ, cfg->osc2.freq);
4560 WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC2AMP, cfg->osc2.amp);
4561 WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC2PHAS, cfg->osc2.phas);
4562 WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TAHI,cfg->osc2.tahi);
4563 WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TALO,cfg->osc2.talo);
4564 WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TIHI,cfg->osc2.tihi);
4565 WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TILO,cfg->osc2.tilo);
4566
4567
4568 WriteReg(pProslic, pProslic->channel,PROSLIC_REG_OMODE,cfg->omode);
4569 return RC_NONE;
4570}
4571#endif /* DISABLE_TONE_SETUP */
4572
4573/*****************************************************************************************************/
4574#ifndef DISABLE_FSK_SETUP
4575int ProSLIC_FSKSetupPtr (proslicChanType_ptr pProslic, ProSLIC_FSK_Cfg *cfg)
4576{
4577 uInt8 data;
4578 int i;
4579
4580 TRACEPRINT(pProslic, "\n",NULL);
4581
4582 if(pProslic->channelType != PROSLIC)
4583 {
4584 return RC_CHANNEL_TYPE_ERR;
4585 }
4586
4587 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_FSKDEPTH,
4588 0x08); /* Clear Buffer */
4589 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TAHI,0);
4590 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TIHI,0);
4591 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TILO,0);
4592 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TALO,0x13);
4593
4594 data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
4595 if (cfg->eightBit)
4596 {
4597 data |= 0x80;
4598 }
4599 else
4600 {
4601 data &= ~(0x80);
4602 }
4603 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_FSKDEPTH,cfg->fskdepth);
4604 WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data);
4605
4606 for(i = 0; i < 2; i++)
4607 {
4608 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_FSK01+i,cfg->fsk[i]);
4609 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_FSKAMP0+i,cfg->fskamp[i]);
4610 WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_FSKFREQ0+i,cfg->fskfreq[i]);
4611 }
4612 return RC_NONE;
4613}
4614#endif
4615
4616/*****************************************************************************************************/
4617int ProSLIC_EnableFastRingStart(proslicChanType_ptr pProslic, BOOLEAN isEnabled)
4618{
4619 uInt8 data;
4620
4621 TRACEPRINT(pProslic, "\n",NULL);
4622
4623 if(pProslic->channelType != PROSLIC)
4624 {
4625 return RC_CHANNEL_TYPE_ERR;
4626 }
4627#if defined(SI3217X) && !defined(Si3217X_REVC_ONLY)
4628 if (pProslic->deviceId->chipType >= SI32171
4629 && pProslic->deviceId->chipType <= SI32179)
4630 {
4631 if(pProslic->deviceId->chipRev < 2)
4632 {
4633 return RC_UNSUPPORTED_FEATURE;
4634 }
4635 }
4636#endif
4637
4638 data = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_USERSTAT);
4639
4640 if( isEnabled )
4641 {
4642 data |= 8;
4643 }
4644 else
4645 {
4646 data &= ~8;
4647 }
4648
4649 return WriteReg(pProslic, pProslic->channel, PROSLIC_REG_USERSTAT, data);
4650}
4651