blob: 8cb300398f99bcca1b45515e7ffb797b6cdfcc1d [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2** Copyright (c) 2007-2017 by Silicon Laboratories
3**
4** $Id: si_voice.c 6479 2017-05-03 02:50:19Z nizajerk $
5**
6** Author(s):
7** laj
8**
9** Distributed by:
10** Silicon Laboratories, Inc
11**
12** This file contains proprietary information.
13** No dissemination allowed without prior written permission from
14** Silicon Laboratories, Inc.
15**
16** File Description:
17** This file contains common (ProSIC + DAA) functions.
18**
19*/
20
21#include "si_voice_datatypes.h"
22#include "si_voice.h"
23#include "proslic_api_config.h"
24
25#ifdef ENABLE_DEBUG
26#define LOGPRINT_PREFIX "SiVoice: "
27#endif
28
29#ifdef SI3217X
30#include "si3217x.h"
31#include "si3217x_intf.h"
32#endif
33
34#ifdef SI3218X
35#include "si3218x.h"
36#include "si3218x_intf.h"
37#endif
38
39#ifdef SI3219X
40#include "si3219x.h"
41#include "si3219x_intf.h"
42#endif
43
44#ifdef SI3226X
45#include "si3226x.h"
46#include "si3226x_intf.h"
47#endif
48
49#ifdef SI3228X
50#include "si3228x.h"
51#include "si3228x_intf.h"
52#endif
53
54#define pCtrl(X) (X)->deviceId->ctrlInterface
55#define pProHW(X) pCtrl((X))->hCtrl
56#define ReadReg(PCHAN, CHANNEL, REGADDR) (PCHAN)->deviceId->ctrlInterface->ReadRegister_fptr(pProHW(PCHAN), (CHANNEL), (REGADDR))
57#define WriteReg(PCHAN, CHANNEL, REGADDR, REGDATA) (PCHAN)->deviceId->ctrlInterface->WriteRegister_fptr(pProHW(PCHAN), (CHANNEL), (REGADDR), (REGDATA))
58
59/*
60** Control object constructor/destructor
61*/
62int SiVoice_createControlInterfaces (SiVoiceControlInterfaceType **pCtrlIntf,
63 uInt32 interface_count)
64{
65 TRACEPRINT_NOCHAN("count = %lu\n", (unsigned long)interface_count);
66#ifndef DISABLE_MALLOC
67 *pCtrlIntf = SIVOICE_CALLOC(sizeof(SiVoiceControlInterfaceType),
68 interface_count);
69 if(*pCtrlIntf == NULL)
70 {
71#ifdef ENABLE_DEBUG
72 LOGPRINT("%s%s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
73#endif
74 return RC_NO_MEM;
75 }
76
77 return RC_NONE;
78#else
79 SILABS_UNREFERENCED_PARAMETER(pCtrlIntf);
80 SILABS_UNREFERENCED_PARAMETER(interface_count);
81 return RC_UNSUPPORTED_FEATURE;
82#endif
83}
84
85int SiVoice_destroyControlInterfaces ( SiVoiceControlInterfaceType **pCtrlIntf )
86{
87
88 TRACEPRINT_NOCHAN("\n",NULL);
89#ifndef DISABLE_MALLOC
90 if( pCtrlIntf && *pCtrlIntf)
91 {
92 SIVOICE_FREE ((SiVoiceControlInterfaceType *)*pCtrlIntf);
93 *pCtrlIntf = NULL;
94 }
95 return RC_NONE;
96#else
97 SILABS_UNREFERENCED_PARAMETER(pCtrlIntf);
98 return RC_UNSUPPORTED_FEATURE;
99#endif
100}
101
102/*
103** Device object constructor/destructor
104*/
105int SiVoice_createDevices (SiVoiceDeviceType **pDevice, uInt32 device_count)
106{
107
108 TRACEPRINT_NOCHAN("\n",NULL);
109#ifndef DISABLE_MALLOC
110 *pDevice = SIVOICE_CALLOC (sizeof(SiVoiceDeviceType), device_count);
111
112 if(*pDevice == NULL)
113 {
114#ifdef ENABLE_DEBUG
115 LOGPRINT("%s%s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
116#endif
117 return RC_NO_MEM;
118 }
119 return RC_NONE;
120#else
121 SILABS_UNREFERENCED_PARAMETER(pDevice);
122 SILABS_UNREFERENCED_PARAMETER(device_count);
123 return RC_UNSUPPORTED_FEATURE;
124#endif
125}
126
127int SiVoice_destroyDevices (SiVoiceDeviceType **pDevice)
128{
129
130 TRACEPRINT_NOCHAN("\n", NULL);
131#ifndef DISABLE_MALLOC
132 if(pDevice && *pDevice)
133 {
134 SIVOICE_FREE ((SiVoiceDeviceType *)*pDevice);
135 *pDevice = NULL;
136 }
137 return RC_NONE;
138#else
139 SILABS_UNREFERENCED_PARAMETER(pDevice);
140 return RC_UNSUPPORTED_FEATURE;
141#endif
142}
143
144/*
145** Channel object constructor/destructor
146*/
147int SiVoice_createChannels (SiVoiceChanType_ptr *pChan, uInt32 channel_count)
148{
149
150 TRACEPRINT_NOCHAN("count = %lu\n", (unsigned long) channel_count);
151#ifndef DISABLE_MALLOC
152 *pChan = SIVOICE_CALLOC(sizeof(SiVoiceChanType),channel_count);
153 if(*pChan == NULL)
154 {
155#ifdef ENABLE_DEBUG
156 LOGPRINT("%s%s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
157#endif
158 return RC_NO_MEM;
159 }
160 return RC_NONE;
161#else
162 SILABS_UNREFERENCED_PARAMETER(pChan);
163 SILABS_UNREFERENCED_PARAMETER(channel_count);
164 return RC_UNSUPPORTED_FEATURE;
165#endif
166}
167
168int SiVoice_destroyChannels (SiVoiceChanType_ptr *hProslic)
169{
170
171 TRACEPRINT_NOCHAN("\n",NULL);
172#ifndef DISABLE_MALLOC
173 if(hProslic && *hProslic)
174 {
175 SIVOICE_FREE ((SiVoiceChanType_ptr)*hProslic);
176 *hProslic = NULL;
177 }
178 return RC_NONE;
179#else
180 SILABS_UNREFERENCED_PARAMETER(hProslic);
181 return RC_UNSUPPORTED_FEATURE;
182#endif
183}
184
185/*
186** Host control linkage
187*/
188int SiVoice_setControlInterfaceCtrlObj (SiVoiceControlInterfaceType *pCtrlIntf,
189 void *hCtrl)
190{
191 TRACEPRINT_NOCHAN("\n",NULL);
192 pCtrlIntf->hCtrl = hCtrl;
193 return RC_NONE;
194}
195
196/*
197** Host reset linkage
198*/
199int SiVoice_setControlInterfaceReset (SiVoiceControlInterfaceType *pCtrlIntf,
200 ctrl_Reset_fptr Reset_fptr)
201{
202 TRACEPRINT_NOCHAN("\n",NULL);
203 pCtrlIntf->Reset_fptr = Reset_fptr;
204 return RC_NONE;
205}
206
207/*
208** Host register/RAM read/write linkage
209*/
210int SiVoice_setControlInterfaceWriteRegister (SiVoiceControlInterfaceType
211 *pCtrlIntf, ctrl_WriteRegister_fptr WriteRegister_fptr)
212{
213 TRACEPRINT_NOCHAN("\n",NULL);
214 pCtrlIntf->WriteRegister_fptr = WriteRegister_fptr;
215 return RC_NONE;
216}
217
218int SiVoice_setControlInterfaceReadRegister (SiVoiceControlInterfaceType
219 *pCtrlIntf, ctrl_ReadRegister_fptr ReadRegister_fptr)
220{
221 TRACEPRINT_NOCHAN("\n",NULL);
222 pCtrlIntf->ReadRegister_fptr = ReadRegister_fptr;
223 return RC_NONE;
224}
225
226int SiVoice_setControlInterfaceWriteRAM (SiVoiceControlInterfaceType *pCtrlIntf,
227 ctrl_WriteRAM_fptr WriteRAM_fptr)
228{
229 TRACEPRINT_NOCHAN("\n",NULL);
230 pCtrlIntf->WriteRAM_fptr = WriteRAM_fptr;
231 return RC_NONE;
232}
233
234int SiVoice_setControlInterfaceReadRAM (SiVoiceControlInterfaceType *pCtrlIntf,
235 ctrl_ReadRAM_fptr ReadRAM_fptr)
236{
237 TRACEPRINT_NOCHAN("\n",NULL);
238 pCtrlIntf->ReadRAM_fptr = ReadRAM_fptr;
239 return RC_NONE;
240}
241
242/*
243** Host timer linkage
244*/
245int SiVoice_setControlInterfaceTimerObj (SiVoiceControlInterfaceType *pCtrlIntf,
246 void *hTimer)
247{
248 TRACEPRINT_NOCHAN("\n",NULL);
249 pCtrlIntf->hTimer = hTimer;
250 return RC_NONE;
251}
252
253int SiVoice_setControlInterfaceDelay (SiVoiceControlInterfaceType *pCtrlIntf,
254 system_delay_fptr Delay_fptr)
255{
256 TRACEPRINT_NOCHAN("\n",NULL);
257 pCtrlIntf->Delay_fptr = Delay_fptr;
258 return RC_NONE;
259}
260
261int SiVoice_setControlInterfaceSemaphore (SiVoiceControlInterfaceType
262 *pCtrlIntf, ctrl_Semaphore_fptr semaphore_fptr)
263{
264 TRACEPRINT_NOCHAN("\n",NULL);
265 pCtrlIntf->Semaphore_fptr = semaphore_fptr;
266 return RC_NONE;
267}
268
269int SiVoice_setControlInterfaceTimeElapsed (SiVoiceControlInterfaceType
270 *pCtrlIntf, system_timeElapsed_fptr timeElapsed_fptr)
271{
272 TRACEPRINT_NOCHAN("\n",NULL);
273 pCtrlIntf->timeElapsed_fptr = timeElapsed_fptr;
274 return RC_NONE;
275}
276
277int SiVoice_setControlInterfaceGetTime (SiVoiceControlInterfaceType *pCtrlIntf,
278 system_getTime_fptr getTime_fptr)
279{
280 TRACEPRINT_NOCHAN("\n",NULL);
281 pCtrlIntf->getTime_fptr = getTime_fptr;
282 return RC_NONE;
283}
284
285/*
286** Channel object initialization
287*/
288int SiVoice_SWInitChan (SiVoiceChanType_ptr pChan,int channel,int chipType,
289 SiVoiceDeviceType *pDeviceObj, SiVoiceControlInterfaceType *pCtrlIntf)
290{
291 TRACEPRINT_NOCHAN( "channel = %d chipType = %d\n", channel, chipType);
292 pChan->channel = (uInt8)channel;
293 pChan->deviceId = pDeviceObj;
294 pChan->deviceId->ctrlInterface = pCtrlIntf;
295 pChan->channelEnable=1;
296 pChan->error = RC_NONE;
297 pChan->debugMode = 0;
298 pChan->dcdc_polarity_invert = 0;
299#ifdef PROSLIC_BOM_DEFAULT
300 pChan->bomOption = PROSLIC_BOM_DEFAULT;
301#else
302 pChan->bomOption = 0;
303#endif
304
305 switch (chipType)
306 {
307 case SI3217X_TYPE:
308 pChan->deviceId->chipType = SI32171;
309 break;
310
311 case SI3218X_TYPE:
312 pChan->deviceId->chipType = SI32180;
313 break;
314
315 case SI3219X_TYPE:
316 pChan->deviceId->chipType = SI32190;
317 break;
318
319 case SI3226X_TYPE:
320 pChan->deviceId->chipType = SI32260;
321 break;
322
323 case SI3228X_TYPE:
324 pChan->deviceId->chipType = SI32280;
325 break;
326
327 case SI3050_TYPE:
328 pChan->deviceId->chipType = SI3050;
329 break;
330
331 default:
332 return RC_UNSUPPORTED_FEATURE;
333 }
334 return RC_NONE;
335}
336
337/*
338** Reset control
339*/
340int SiVoice_Reset (SiVoiceChanType_ptr pChan)
341{
342 TRACEPRINT_NOCHAN( "\n", NULL);
343 /*
344 ** assert reset, wait 250ms, release reset, wait 250ms
345 */
346 pChan->deviceId->ctrlInterface->Reset_fptr(
347 pChan->deviceId->ctrlInterface->hCtrl,1);
348
349 pChan->deviceId->ctrlInterface->Delay_fptr(
350 pChan->deviceId->ctrlInterface->hTimer,250);
351
352 pChan->deviceId->ctrlInterface->Reset_fptr(
353 pChan->deviceId->ctrlInterface->hCtrl,0);
354
355 pChan->deviceId->ctrlInterface->Delay_fptr(
356 pChan->deviceId->ctrlInterface->hTimer,250);
357
358 return RC_NONE;
359}
360
361/*
362** Debug Mode Control
363*/
364int SiVoice_setSWDebugMode (SiVoiceChanType_ptr pChan, int debugEn)
365{
366#ifdef ENABLE_DEBUG
367 TRACEPRINT_NOCHAN( "debugEn %d\n", debugEn);
368 pChan->debugMode = (0xFE & pChan->debugMode) | (debugEn != 0);
369#else
370 SILABS_UNREFERENCED_PARAMETER(pChan);
371 SILABS_UNREFERENCED_PARAMETER(debugEn);
372#endif
373 return RC_NONE;
374}
375
376/*
377** Trace Mode Control
378*/
379int SiVoice_setTraceMode (SiVoiceChanType_ptr pChan, int traceEn)
380{
381#ifdef ENABLE_TRACES
382 TRACEPRINT_NOCHAN( "debugEn %d\n", traceEn);
383 pChan->debugMode = (0xFD & pChan->debugMode) | ((traceEn != 0)<<1);
384#else
385 SILABS_UNREFERENCED_PARAMETER(pChan);
386 SILABS_UNREFERENCED_PARAMETER(traceEn);
387#endif
388 return RC_NONE;
389}
390
391/*
392** Error status
393*/
394int SiVoice_getErrorFlag (SiVoiceChanType_ptr pChan, int *error)
395{
396 TRACEPRINT( pChan, "\n", NULL);
397 *error = pChan->error;
398 return RC_NONE;
399}
400
401int SiVoice_clearErrorFlag (SiVoiceChanType_ptr pChan)
402{
403 TRACEPRINT( pChan, "\n", NULL);
404 pChan->error = RC_NONE;
405 return RC_NONE;
406}
407
408/*
409** Channel status
410*/
411int SiVoice_setChannelEnable (SiVoiceChanType_ptr pChan, int chanEn)
412{
413 TRACEPRINT( pChan, "enable = %d\n", chanEn);
414 pChan->channelEnable = chanEn;
415 return RC_NONE;
416}
417
418int SiVoice_getChannelEnable (SiVoiceChanType_ptr pChan, int *chanEn)
419{
420 TRACEPRINT( pChan, "\n", NULL);
421 *chanEn = pChan->channelEnable;
422 return RC_NONE;
423}
424
425uInt8 SiVoice_ReadReg(SiVoiceChanType_ptr hProslic,uInt8 addr)
426{
427 TRACEPRINT( hProslic, "addr = %u\n", (unsigned int)addr);
428 return ReadReg(hProslic, hProslic->channel, addr);
429}
430
431int SiVoice_WriteReg(SiVoiceChanType_ptr hProslic,uInt8 addr,uInt8 data)
432{
433 TRACEPRINT( hProslic, "addr = %u data = 0x%02X\n", (unsigned int)addr,
434 (unsigned int) data);
435 return WriteReg(hProslic, hProslic->channel, addr, data);
436}
437
438/*****************************************************************************************************/
439#if defined(SI3217X) || defined(SI3218X) || defined(SI3219X) || defined(SI3226X) || defined(SI3228X)
440#include "proslic.h"
441
442/* Iterate through the number of channels to determine if it's a SLIC, DAA, or unknown. Rev ID and chiptype is
443 * also filled in.
444 */
445int SiVoice_IdentifyChannels(SiVoiceChanType_ptr *pProslic, int size,
446 int *slicCount, int *daaCount)
447{
448 int i;
449 int rc = RC_NONE;
450 SiVoiceChanType_ptr currentChannel;
451
452 TRACEPRINT( *pProslic, "size = %d\n", size);
453
454 if(slicCount)
455 {
456 *slicCount = 0;
457 }
458 if(daaCount)
459 {
460 *daaCount = 0;
461 }
462
463 for(i = 0; i < size; i++)
464 {
465 currentChannel = pProslic[i];
466 /* SiVoice_SWInitChan() fills in the chipType initially with something the user provided, fill it
467 * in with the correct info.. The GetChipInfo may probe registers to compare them with their
468 * initial values, so this function MUST only be called after a chipset reset.
469 */
470#ifdef SI3217X
471 if (currentChannel->deviceId->chipType >= SI32171
472 && currentChannel->deviceId->chipType <= SI32179)
473 {
474 rc = Si3217x_GetChipInfo(currentChannel);
475 }
476#endif
477
478#ifdef SI3218X
479 if (currentChannel->deviceId->chipType >= SI32180
480 && currentChannel->deviceId->chipType <= SI32189)
481 {
482 rc = Si3218x_GetChipInfo(currentChannel);
483 }
484#endif
485
486#ifdef SI3219X
487 if ( IS_SI3219X(currentChannel->deviceId) )
488 {
489 rc = Si3219x_GetChipInfo(currentChannel);
490 }
491#endif
492
493#ifdef SI3226X
494 if (currentChannel->deviceId->chipType >= SI32260
495 && currentChannel->deviceId->chipType <= SI32269)
496 {
497 rc = Si3226x_GetChipInfo(currentChannel);
498 }
499#endif
500
501#ifdef SI3228X
502 if (currentChannel->deviceId->chipType >= SI32280
503 && currentChannel->deviceId->chipType <= SI32289)
504 {
505 rc = Si3228x_GetChipInfo(currentChannel);
506 }
507#endif
508
509 if(rc != RC_NONE)
510 {
511 return rc;
512 }
513
514 currentChannel->channelType = ProSLIC_identifyChannelType(currentChannel);
515 if(currentChannel->channelType == PROSLIC)
516 {
517 if(slicCount)
518 {
519 (*slicCount)++;
520 }
521 }
522 else if(currentChannel->channelType == DAA)
523 {
524 if(daaCount)
525 {
526 (*daaCount)++;
527 }
528 }
529#ifdef ENABLE_DEBUG
530 {
531 const char *dev_type = "UNKNOWN";
532 if(currentChannel->channelType == PROSLIC)
533 {
534 dev_type = "PROSLIC";
535 }
536 else if(currentChannel->channelType == DAA)
537 {
538 dev_type = "DAA";
539 }
540 LOGPRINT("%sChannel %d: Type = %s Rev = %d\n",
541 LOGPRINT_PREFIX, currentChannel->channel, dev_type,
542 currentChannel->deviceId->chipRev);
543
544 }
545#endif /* ENABLE_DEBUG */
546 }
547 return RC_NONE;
548}
549#endif
550
551/*
552** Function: ProSLIC_Version
553**
554** Description:
555** Return API version
556**
557** Returns:
558** string of the API release.
559*/
560
561extern const char *SiVoiceAPIVersion;
562char *SiVoice_Version()
563{
564 return (char *)SiVoiceAPIVersion;
565}
566