blob: 0fa016dd769f0f589f2ecc555cbe769f42b380d6 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/***********************************************************************
2* Copyright (C) 2001, ZTE Corporation.
3*
4* File Name: si_adt.c
5* File Mark:
6* Description: siliconlab lib adapter.
7* History :
8* Date : 2010-04-07
9* Version :1.0
10* Author : duanzhw 182073
11* Modification:
12
13**********************************************************************/
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/timer.h>
17#include <linux/fs.h>
18#include <linux/sched.h>
19#include <linux/wait.h>
20#include <linux/init.h>
21#include <linux/fcntl.h>
22#include <linux/list.h>
23#include <linux/slab.h>
24#include <linux/signal.h>
25//#include <linux/smp_lock.h>
26#include <asm/uaccess.h>
27#include <linux/delay.h>
28
29#include "si_voice_datatypes.h"
30#include "proslic_mlt.h"
31#include "proslic_mlt_math.h"
32
33#include "timer_adt.h"
34#ifdef SI3217X
35#include "si3217x.h"
36#include "si3217x_constants.h"
37#endif
38#ifdef SI3218X
39#include "si3218x.h"
40#include "si3218x_constants.h"
41#endif
42#include "112.h"
43#include "usr_line.h"
44
45//#include "generic-ability.h"
46
47/**************************port map****************************/
48static USL_PORT_MAP port_map[MAX_PORT_NUM] = {
49 /*flg, cs , chan, port , type, tx, rx*/
50 {0, 0, 0, 0, 0, 0, 0}
51 // {0, 0, 0, 0, 0, 1, 1},
52 // {0, 0, 0, 0, 0, 2, 2},
53 // {0, 0, 0, 0, 0, 3, 3},
54};
55
56/**************************************************************/
57ctrl_S spiGciObj[MAX_PORT_NUM]; /* User¡¯s control interface object, can be consider as the port number */
58systemTimer_S timerObj; /* User¡¯s timer object */
59
60controlInterfaceType *ProHWIntf[MAX_PORT_NUM];
61/* Define array of ProSLIC device objects */
62ProslicDeviceType *ProSLICDevices[MAX_PORT_NUM];
63/* Define array of ProSLIC channel object pointers */
64proslicChanType_ptr arrayOfProslicChans[MAX_PORT_NUM];
65
66
67/* 112 test */
68//ProSLICMLTType SLICMLT;
69//ProSLIC_mlt_foreign_voltages_state vState;
70//ProSLIC_mlt_rmeas_state rMeas;
71//ProSLIC_mlt_capacitance_state CapState;
72//ProSLIC_mlt_ren_state RenState;
73long RingVol[MAX_RING_CNT]= {0}, RingCnt = 0;
74
75//TestResult_t ResBuf;
76
77/* board cfg */
78static SILAB_CFG_CHIP_t BoardCfg[MAX_PORT_NUM] = {{0}};
79
80/* As for one board, using one signal to avoid the conflict */
81static const u8 pcmcfg[] = {0x4,0x1,0x3};
82static Port_t ports[MAX_PORT_NUM];
83
84//extern u8 init_flg;
85extern slic_state current_state;
86extern USL_PORT *pstUslPort;
87extern int dtmf_mute;
88extern u8 slic_offhook;
89
90static s8 si_signal_ctrl(Port_t *pPort, const void *signal_attr,const u8 flag);
91static s8 si_timeslot_set(Port_t *pPort, const u8 TxTs, const u8 RxTs);
92static s8 si_timeslot_release(Port_t *pPort);
93static s8 si_chip_reset(Port_t *pPort, u16 port);
94static s8 si_polarity_reverse(Port_t *pPort, const u16 port);
95static s8 si_parm_set(Port_t *pPort, u8 *parm, const u8 size);
96static s8 si_parm_get(Port_t *pPort, u8 *parm, const u8 size );
97static s8 si_ram_set(Port_t *pPort, u8 *parm, const u8 size);
98static s8 si_ram_get(Port_t *pPort, u8 *parm, const u8 size );
99static s8 si_time_cfg(Port_t *pPort, const USL_CONFIG *Slc_Time_Cfg);
100static s8 si_slctool_time_cfg(Port_t *pPort, SLIC_IOCTL_CMD cmd, u16 wTime);
101static s8 si_time_print(Port_t *pPort);
102static s8 si_dial_set(Port_t *pPort, u8 bDialEn);
103static s8 si_electric_set(Port_t *pPort, const u16 port, const ELECTRIC_CFG_CUSTOMIZED *buf);
104static s8 si_start_test(Port_t *pPort, const WriteCmd_t *Cmd);
105static s8 si_stop_test(Port_t *pPort );
106static s8 si_read_result(Port_t *pPort, TestResult_t *pstResult);
107
108static void ScanSiBoard(USL_PORT *pUslPort);
109
110static void StartSiLineTest(Port_t *pPort, uInt8 TestId);
111static s8 StartLineConnectTest(Port_t *pPort);
112static void SiScanSignals(USL_PORT *usl_port, u8 hook);
113static void SiUpdatePort(Port_t *data, u16 port, u8 event);
114
115static s8 si_update_dcpara(SILAB_CFG_CHIP_t *ptOldCfg, u8 vol_param, u8 cur_param);
116static s8 si_update_ringpara(SILAB_CFG_CHIP_t *ptOldCfg, u8 ringvol_param);
117static int setUserMode (proslicChanType_ptr hProslic, BOOLEAN on);
118
119USL_PORT_MAP *get_port_item(u8 port, u8 type);
120int InitSiliconBoard(void);
121int SiRemoveBoard(void);
122void InitSiliconChip(Port_t *pPort);
123int SiSetSemaphore(void *pHCtrl, int s);
124int ProSLIC_PCMEnable(proslicChanType_ptr hProslic, u8 enable);
125int ProSLIC_GetLinefeedStatus (proslicChanType_ptr hProslic, uInt8 *pLinefeed);
126int VerifyChipID(ctrl_S *hCtrl, u8 chan);
127void MLTClearSettings(ProSLICMLTType *pProSLICMLT);
128void MLTClearResults(ProSLICMLTType *pProSLICMLT);
129void SiMltScan(Port_t *pPort);
130void SiSendResultVol(Port_t *pPort, ProSLICMLTType *pMlt);
131void SiSendResultCap(Port_t *pPort, ProSLICMLTType *pMlt);
132void SiSendResultRes(Port_t *pPort, ProSLICMLTType *pMlt);
133void SiSendResultDCFeedSt(Port_t *pPort);
134void SiSendResultBatteryVol(Port_t *pPort);
135void SiSendResultRingtouser(Port_t *pPort);
136void SiRen(Port_t *pPort, ProSLICMLTType *pMlt);
137void SiSendResultHook(Port_t *pPort);
138long ChangeData(unsigned long n);
139long lldivde(long long x, long y);
140long longfabs(long x);
141
142#define FSK_DEPTH_TRIG 4
143#define DISABLE_FSK_CID
144
145//extern int spi_chipid_get(u8 port, u8 *cs, u8 *ch);
146//extern const s8 *board_type_acquire(u32 *type);
147/***************************************************************************/
148static CODEC_OPS si_ops = {
149 .codec_signal_ctrl = si_signal_ctrl,
150 .codec_timeslot_set = si_timeslot_set,
151 .codec_timeslot_release = si_timeslot_release,
152 .codec_reset = si_chip_reset,
153 .codec_polarity_reverse = si_polarity_reverse,
154 .codec_parm_cfg = si_parm_set,
155 .codec_parm_get = si_parm_get,
156 .codec_ram_cfg = si_ram_set,
157 .codec_ram_get = si_ram_get,
158 .codec_time_cfg = si_time_cfg,
159 .codec_slctool_time_cfg = si_slctool_time_cfg,
160 .codec_time_print = si_time_print,
161 .codec_dial_set = si_dial_set,
162 .codec_electric_cfg = si_electric_set,
163 .codec_start_test = si_start_test,
164 .codec_stop_test = si_stop_test,
165 .codec_read_reslult = si_read_result,
166
167 .codec_scan = ScanSiBoard,
168};
169
170/****************** public func *******************/
171USL_PORT_MAP * get_port_item(u8 port, u8 type)
172{
173 u8 i = 0;
174
175 for( i = 0; i < MAX_PORT_NUM; i++ )
176 {
177 if( port_map[i].flg == 0 ) continue;
178
179 if( port == port_map[i].port && type == port_map[i].type )
180 {
181
182 return &port_map[i];
183 }
184 }
185
186 return NULL;
187}
188
189void make_port_map(void)
190{
191 u8 cs = 0, chan = 0;
192 u8 i = 0;
193 int ret = 0;
194 for( i = 0; i < MAX_PORT_NUM; i++ )
195 {
196 //ret = spi_chipid_get(i, &cs, &chan);
197 if( 0 == ret )
198 {
199 #ifdef DEBUG_SLIC_ON
200 USLPUT0("Find a port:%d with chan %d cs %d\n", i, chan, cs);
201 #endif
202 port_map[i].flg = 1;
203 port_map[i].cs = cs;
204 port_map[i].chan = chan;
205 port_map[i].port = i;
206 port_map[i].type = SLIC_PORT_TYPE;
207 port_map[i].tx = i;
208 port_map[i].rx = i;
209 }
210 else
211 {
212 #ifdef DEBUG_SLIC_ON
213 USLPUT0("cann't Find a port:%d\n", i);
214 #endif
215 port_map[i].flg = 0;
216 }
217 }
218}
219
220void SlicCfgParaBasedBoardType(void)
221{
222 //u32 dwBoardType = 0;
223 u32 dwPort = 0;
224
225 //board_type_acquire(&dwBoardType);
226 for (dwPort=0; dwPort<MAX_PORT_NUM; dwPort++)
227 {
228#ifdef SI3217X
229 /*switch(dwBoardType)
230 {
231
232 default:
233 USLPUT0("Board default NO PTC\n");*/
234 BoardCfg[dwPort].ePTC = NOPTC;
235 // break;
236 //}
237//#if defined (SILAB_SUPPORT_BUCKBOOST)
238// BoardCfg[dwPort].generel_cfg = 0;
239//#elif defined (SILAB_SUPPORT_LCQC)
240// BoardCfg[dwPort].generel_cfg = 3;
241//#else
242 BoardCfg[dwPort].generel_cfg = 2;
243//#endif
244 BoardCfg[dwPort].ring = RING_F20_45VRMS_0VDC_LPR_SHORTTIME;//RING_F20_45VRMS_0VDC_LPR;
245 BoardCfg[dwPort].dc = DCFEED_48V_20MA;
246 BoardCfg[dwPort].tone = TONEGEN_FCC_DIAL;
247 BoardCfg[dwPort].Impe = ZSYN_600_0_0_30_0;
248 BoardCfg[dwPort].meter = DEFAULT_PULSE_METERING;
249 BoardCfg[dwPort].bLineOpen100msEn = 0;
250 BoardCfg[dwPort].bDisablePowerSave = 0;
251 BoardCfg[dwPort].a_u_law = PCM_16LIN;
252 BoardCfg[dwPort].cid = ITU_FSK;
253 BoardCfg[dwPort].linestaus = LF_FWD_ACTIVE;
254 BoardCfg[dwPort].wide = 2;
255 BoardCfg[dwPort].offset = 1;
256 BoardCfg[dwPort].rxgain = 0;
257 BoardCfg[dwPort].txgain = 0;
258#endif
259#ifdef SI3218X
260 BoardCfg[dwPort].ePTC = NOPTC;
261 BoardCfg[dwPort].generel_cfg = 0;
262 BoardCfg[dwPort].ring = RING_F20_45VRMS_0VDC_LPR;//RING_F20_45VRMS_0VDC_LPR;RING_F20_45VRMS_0VDC_LPR_SHORTTIME
263 BoardCfg[dwPort].dc = DCFEED_48V_20MA;
264 BoardCfg[dwPort].tone = TONEGEN_FCC_DIAL;
265 BoardCfg[dwPort].Impe = ZSYN_600_0_0_30_0;
266 BoardCfg[dwPort].meter = DEFAULT_PULSE_METERING;
267 BoardCfg[dwPort].bLineOpen100msEn = 0;
268 BoardCfg[dwPort].bDisablePowerSave = 0;
269 BoardCfg[dwPort].a_u_law = PCM_16LIN;
270 BoardCfg[dwPort].cid = ITU_FSK;
271 BoardCfg[dwPort].linestaus = LF_FWD_ACTIVE;
272 BoardCfg[dwPort].wide = 2;
273 BoardCfg[dwPort].offset = 1;
274 BoardCfg[dwPort].rxgain = 0;
275 BoardCfg[dwPort].txgain = 0;
276#endif
277 }
278
279 return;
280}
281
282int InitSlicChip(void)
283{
284 int ret = 0;
285 make_port_map();
286 ret = InitSiliconBoard();
287
288 return ret;
289}
290
291void DeinitSlicChip(void)
292{
293 SiRemoveBoard();
294
295 return;
296}
297
298void SendErrorTest(Port_t *pPort, int err)
299{
300 USLPUT2(" Test Error %d.\n", err );
301
302 pPort->stLineTestPara.pstResult->flg = TEST_ERROR;
303 pPort->stLineTestPara.pstResult->err_num = err; /*´íÎóºÅ*/
304 usrline_report(pPort->stLineTestPara.pstResult->port, EV_FXS_TEST_DONE, 0, 0);
305
306 return;
307}
308
309void slic_inf_precfg(SLCINF_CFG *ptCfg)
310{
311 if (NULL == ptCfg)
312 {
313 USLPUT0("%s ptCfg NULL \n", __FUNCTION__);
314 return;
315 }
316
317 if (ptCfg->bPort >= MAX_PORT_NUM)
318 {
319 USLPUT0("%s port:%d is bigger than MAX_PORT_NUM:%d\n", __FUNCTION__, ptCfg->bPort, MAX_PORT_NUM);
320 return;
321 }
322
323 si_update_dcpara(&BoardCfg[ptCfg->bPort], ptCfg->bCusDcVol, ptCfg->bCusDcLoopCurr);
324 si_update_ringpara(&BoardCfg[ptCfg->bPort], ptCfg->bCusRingVpk);
325
326 BoardCfg[ptCfg->bPort].bLineOpen100msEn = ptCfg->bLineOpen100msEn;
327 BoardCfg[ptCfg->bPort].bDisablePowerSave = ptCfg->bDisablePowerSave;
328
329 switch(ptCfg->dwImpe)
330 {
331 #if 0
332 case 600:
333 BoardCfg[ptCfg->bPort].Impe = ZSYN_600+BoardCfg[ptCfg->bPort].ePTC;
334 break;
335 case 680:
336 BoardCfg[ptCfg->bPort].Impe = ZSYN_200_680+BoardCfg[ptCfg->bPort].ePTC;
337 break;
338 #endif
339 default:
340 BoardCfg[ptCfg->bPort].Impe = ZSYN_600_0_0_30_0;
341 break;
342 }
343
344 BoardCfg[ptCfg->bPort].rxgain = ptCfg->i32Rxgain;
345 BoardCfg[ptCfg->bPort].txgain = ptCfg->i32Txgain;
346
347 USLPUT3("port:%d Dc:%d U:%d A:%d Ring:%d VPK:%d 100msEn:%d, DisPowerSave:%d impe:%d ePTC:%d dwImpe:%d rxgain(D-A):%d, txgain(A-D):%d\n",
348 ptCfg->bPort,
349 BoardCfg[ptCfg->bPort].dc, ptCfg->bCusDcVol, ptCfg->bCusDcLoopCurr,
350 BoardCfg[ptCfg->bPort].ring, ptCfg->bCusRingVpk,
351 BoardCfg[ptCfg->bPort].bLineOpen100msEn, BoardCfg[ptCfg->bPort].bDisablePowerSave,
352 BoardCfg[ptCfg->bPort].Impe, BoardCfg[ptCfg->bPort].ePTC, ptCfg->dwImpe,
353 BoardCfg[ptCfg->bPort].rxgain, BoardCfg[ptCfg->bPort].txgain);
354
355 return;
356}
357/****************** end *******************/
358
359/****************** func for si_ops ****************/
360static void si_tone_init(Port_t *pPort, SIGNAL_DATA *signal_attr)
361{
362 u8 bToneIndex = signal_attr->tone_type;
363 u8 bOscillator2En = 0;
364
365 /* modified by zhanghuan for new SIGNAL_DATA struct */
366#if 0
367 if (0 != signal_attr->cadence[0].freq2)
368 {
369 bOscillator2En = 1;
370 }
371
372 switch(signal_attr->cadence[0].freq1)
373 {
374 default:
375 bToneIndex = TONEGEN_450_N18DB_350_N18DB;
376 break;
377 }
378#endif
379 /* modified by zhanghuan for new SIGNAL_DATA struct */
380
381 /*use preset tone type */
382 printk("ProSLIC_ToneGenSetup %d \n", bToneIndex);
383 ProSLIC_ToneGenSetup(pPort->ProObj, bToneIndex);
384
385 return;
386}
387
388uInt8 checkSum(char *str)
389{
390 int i=0;
391 uInt8 sum = 0;
392
393 while(str[i] != 0)
394 {
395 sum += str[i++];
396 }
397
398 return -sum;
399}
400
401
402/*****************************************************************************************************/
403/* Wait for FSK buffer to be available... */
404void waitForCIDDone(SiVoiceChanType_ptr pChan)
405{
406 int tmp = 0;
407
408 do
409 {
410 ProSLIC_CheckCIDBuffer(pChan, &tmp);
411 }
412 while(tmp == 0);
413
414}
415
416void sendFSKData(proslicChanType_ptr hProslic, char *stream, int preamble_enable)
417{
418 uInt8 csum;
419 int buff_timeout;
420 int cid_remainder;
421 int baud_rate = 1200;
422 int bits = 10; /* 1 start + 8 data + 1 stop */
423 int i;
424 const uInt8 cid_preamble[] = {'U','U','U','U','U','U','U','U'};
425
426 buff_timeout = ((8 - FSK_DEPTH_TRIG) * (10000*bits)/baud_rate)/10;
427 /*
428 ** SEND CID HERE
429 */
430
431 /* Clear FSK buffer */
432 if((stream[1]+3)%FSK_DEPTH_TRIG)
433 {
434 cid_remainder = 1;
435 }
436 else
437 {
438 cid_remainder = 0;
439 }
440
441 ProSLIC_EnableCID(hProslic);
442 msleep(133); /* > 130ms of mark bits */
443
444 /* Enable FSKBUF interrupt so we can check it later. */
445 SiVoice_WriteReg(hProslic,PROSLIC_REG_IRQEN1,0x40);
446 (void)SiVoice_ReadReg(hProslic,
447 PROSLIC_REG_IRQ1); /* Clear IRQ1 */
448 printk("howard fsk cid send preamble\n");
449 if(preamble_enable)
450 {
451 /* Send preamble */
452 for(i=0; i<30; i+=FSK_DEPTH_TRIG)
453 {
454 if(i >= 8) /* The FIFO depth is 8 bytes, start waiting for it to empty */
455 {
456 waitForCIDDone(hProslic);
457 }
458 ProSLIC_SendCID(hProslic,cid_preamble,FSK_DEPTH_TRIG);
459 }
460 if (30%FSK_DEPTH_TRIG)
461 {
462 waitForCIDDone(hProslic);
463 }
464 ProSLIC_SendCID(hProslic,cid_preamble,30%FSK_DEPTH_TRIG);
465 waitForCIDDone(hProslic);
466
467 /* Delay > 130ms for idle mark bits */
468 msleep(133);
469 }
470
471 /* Send Message */
472 printk("howard fsk cid send message\n");
473 csum = checkSum(stream);
474 stream[stream[1]+2] = csum;
475
476 for(i=0; i<(stream[1]+3); i+=FSK_DEPTH_TRIG)
477 {
478 if(i>=8)
479 {
480 waitForCIDDone(hProslic);
481 }
482
483 ProSLIC_SendCID(hProslic,&(stream[i]),FSK_DEPTH_TRIG);
484 }
485
486 if(cid_remainder)
487 {
488 waitForCIDDone(hProslic);
489
490 ProSLIC_SendCID(hProslic,
491 &(stream[((stream[1]+3)/FSK_DEPTH_TRIG)*FSK_DEPTH_TRIG]),
492 (stream[1]+3)%FSK_DEPTH_TRIG);
493 }
494
495 waitForCIDDone(hProslic);
496
497 /* Make sure the last byte is shifted out prior to disabling CID */
498 msleep(buff_timeout);
499 ProSLIC_DisableCID(hProslic);
500
501}
502
503
504/*****************************************************************************************************/
505/*
506** Sequential (blocking) example of CID transmission
507*/
508void sendCIDStream(proslicChanType_ptr hProslic)
509{
510
511 char cid_msg[] =
512 "\x80" /* MDMF Type */
513 "\x27" /* Message Length */
514 "\x01" /* Date/Time Param */
515 "\x08" /* 8-byte Date/Time */
516 "07040815" /* July 4th 08:15 am */
517 "\x02" /* Calling Number Param */
518 "\x0A" /* 10-byte Calling Number */
519 "5124168500" /* Phone Number */
520 "\x07" /* Calling Name Param */
521 "\x0F" /* 15-byte Calling Name */
522 "Nice" /* Calling Name */
523 "\x20" /* Calling Name (whitespace) */
524 "ProSLIC!!!" /* Calling Name */
525 "\x00" /* Placeholder for Checksum */
526 "\x00" /* Markout */
527 ;
528 uInt8 reg_tmp;
529
530 ProSLIC_FSKSetup(hProslic,0);
531
532 ProSLIC_RingSetup(hProslic,1);
533 reg_tmp =SiVoice_ReadReg(hProslic,PROSLIC_REG_RINGCON);
534 SiVoice_WriteReg(hProslic,PROSLIC_REG_RINGCON,reg_tmp&0xF0);
535
536 /* Ensure OFFHOOK Active */
537 //ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
538 //msleep(500);
539
540 /* 1st Ring Burst */
541 ProSLIC_SetLinefeedStatus(hProslic,LF_RINGING);
542 msleep(2500);
543
544 /* OHT - the alternative is to have the configuration for ringing set OHT mode automatically... */
545 //ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_OHT); /* no need if RINGCON is set to 0x58*/
546 //msleep(500); /* Delay 250 to 3600ms */
547 sendFSKData(hProslic, cid_msg, 1);
548}
549
550
551static s8 si_signal_ctrl(Port_t *pPort, const void *signal_attr,const u8 flag)
552{
553 static unsigned long int jiffies_save;
554 int ret = -1;
555
556 if(NULL == pPort)
557 {
558 USLPUT0("si_signal_ctrl pPort NULL \n");
559 return -1;
560 }
561
562 switch(flag)
563 {
564 /* play ring */
565 case RING_SIGNAL_INIT:
566 jiffies_save = jiffies;
567 USLPUT3("RING_SIGNAL_INIT\n");
568 break;
569 case RING_SIGNAL_ON:
570 //printk("start play ring ProSLIC_Init_MultiBOM\n");
571 //ProSLIC_Init_MultiBOM(&(pPort->ProObj),1,3);
572 /* ring and cid is moved to ioctl */
573 #if 0
574 printk("start play ring\n");
575 #ifdef DISABLE_FSK_CID
576 pPort->ProObj->channelType = PROSLIC;
577 ret = ProSLIC_SetLinefeedStatus( pPort->ProObj, LF_RINGING);
578 USLPUT3("RING_SIGNAL_ON %lu, ret %d\n", jiffies - jiffies_save, ret);
579 jiffies_save = jiffies;
580 #else
581 /* add by zhanghuan for FSK CID */
582 sendCIDStream(pPort->ProObj);
583 #endif
584 current_state = RINGING;
585 #endif
586 break;
587 case RING_SIGNAL_OFF:
588 ProSLIC_SetLinefeedStatus( pPort->ProObj, LF_FWD_OHT);
589 USLPUT3("RING_SIGNAL_OFF %lu\n", jiffies - jiffies_save);
590 jiffies_save = jiffies;
591 current_state = NONE;
592 break;
593 case RING_SIGNAL_OFF_REVERSED:
594 ProSLIC_SetLinefeedStatus( pPort->ProObj, LF_REV_OHT);
595 USLPUT3("RING_SIGNAL_OFF_REVERSED %lu\n", jiffies - jiffies_save);
596 jiffies_save = jiffies;
597 break;
598 case RING_SIGNAL_CLEAN_OFF:
599 case RING_SIGNAL_CLEAN_ON:
600 ProSLIC_SetLinefeedStatus( pPort->ProObj, LF_FWD_ACTIVE);
601 USLPUT3("RING_SIGNAL_CLEAN_ON %lu\n", jiffies - jiffies_save);
602 jiffies_save = jiffies;
603 current_state = NONE;
604 break;
605 /* play tone */
606 case TONE_SIGNAL_INIT:
607 ProSLIC_ToneGenStop(pPort->ProObj);
608 current_state = NONE;
609 si_tone_init(pPort, (SIGNAL_DATA *)signal_attr);
610 break;
611 case TONE_SIGNAL_ON:
612 printk("start play tone\n");
613 if(TONE_DIAL != ((SIGNAL_DATA *)signal_attr)->tone_type)
614 {
615 ProSLIC_ToneGenStart(pPort->ProObj, 1); // Only DIAL TONE play continusely
616 }
617 else
618 {
619 ProSLIC_ToneGenStart(pPort->ProObj, 0);
620 }
621 current_state = PLAYING_TONE;
622 break;
623 case TONE_SIGNAL_OFF:
624 ProSLIC_ToneGenStop(pPort->ProObj);
625 current_state = NONE;
626 break;
627 case TONE_SIGNAL_CLEAN:
628 ProSLIC_ToneGenStop(pPort->ProObj);
629 current_state = NONE;
630 break;
631
632 default:
633 break;
634 }
635 return 0;
636}
637
638static s8 si_timeslot_set(Port_t *pPort, const u8 TxTs, const u8 RxTs)
639{
640 u16 tx = 0;
641 u16 rx = 0;
642
643 if( NULL == pPort )
644 {
645 USLPUT0("leg_timeslot_set pPort NULL \n");
646 return -1;
647 }
648
649 tx = TxTs * 8 * pPort->pPreCfg->wide + pPort->pPreCfg->offset;
650 rx = RxTs * 8 * pPort->pPreCfg->wide + pPort->pPreCfg->offset;
651
652 USLPUT2("si_timeslot_set tx %d rx %d. \n",tx,rx);
653 ProSLIC_PCMTimeSlotSetup( pPort->ProObj, rx , tx );
654 ProSLIC_PCMEnable( pPort->ProObj, 1);
655 return 0;
656}
657
658static s8 si_timeslot_release(Port_t *pPort)
659{
660 if( NULL == pPort )
661 {
662 USLPUT0("si_timeslot_release line NULL \n");
663 return -1;
664 }
665
666 ProSLIC_PCMEnable( pPort->ProObj, 0);
667 ProSLIC_PCMTimeSlotSetup( pPort->ProObj, MAX_PORT_NUM * 8 , MAX_PORT_NUM * 8 );
668 return 0;
669}
670
671static s8 si_chip_reset(Port_t *pPort, u16 port)
672{
673 if( NULL == pPort )
674 {
675 USLPUT0("si_chip_reset pPort NULL \n");
676 return -1;
677 }
678
679 if( HOOKOFF == pPort->hook_state )
680 {
681 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_FWD_ACTIVE);
682 USLPUT3("ProSLIC_SetLinefeedStatus %d LF_FWD_ACTIVE\n",port);
683 usrline_report(port, EV_FXS_HOOKON, 0 , 0);
684 }
685 pPort->hook_state = HOOKON;
686 pPort->pulse_dig = 0;
687 pPort->stLineTestPara.si_item = 0xff;
688 pPort->stLineTestPara.test_flg = NOT_TEST;
689 pPort->stLineTestPara.cnt = 0;
690 pPort->low_len = 0;
691 pPort->high_len = 0;
692 pPort->bDialEn = EV_DIAL_STOP;
693
694 return 0;
695}
696
697static s8 si_polarity_reverse(Port_t *pPort, const u16 port)
698{
699 u8 state = 0;
700 u8 new_state = 0;
701
702 if( NULL == pPort )
703 {
704 USLPUT0("si_polarity_reverse pPort NULL \n");
705 return -1;
706 }
707
708 ProSLIC_GetLinefeedStatus(pPort->ProObj, &state);
709 switch(state)
710 {
711 case LF_REV_ACTIVE:
712 case LF_FWD_ACTIVE:
713 case LF_FWD_OHT:
714 case LF_REV_OHT:
715 new_state = state ^ 0x4 ;
716 break;
717 default:
718 USLPUT0("reverse error at state% d\n",state);
719 return -1;
720 }
721
722
723 if((1 == pPort->pPreCfg->bLineOpen100msEn)&& (LF_REV_ACTIVE == state))
724 {
725 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_OPEN);
726 msleep(100);
727 USLPUT2("SLIC set line feed status from OPEN to %d\n",new_state);
728 }
729
730 ProSLIC_SetLinefeedStatus( pPort->ProObj, new_state );
731
732 return 0;
733}
734
735static s8 si_parm_set( Port_t *pPort, u8 *parm, const u8 size)
736{
737 if( NULL == pPort )
738 {
739 USLPUT0("si_parm_set pPort NULL \n");
740 return -1;
741 }
742
743 ctrl_WriteRegisterWrapper( pPort->ProObj->deviceId->ctrlInterface->hCtrl, pPort->ProObj->channel,parm[0],parm[1]);
744
745 return 0;
746}
747
748static s8 si_parm_get( Port_t *pPort, u8 *parm, const u8 size )
749{
750 u8 addr = 0;
751
752 if( NULL == pPort )
753 {
754 USLPUT0("si_parm_get pPort NULL \n");
755 return -1;
756 }
757
758 addr = parm[0];
759
760 *parm = ctrl_ReadRegisterWrapper( pPort->ProObj->deviceId->ctrlInterface->hCtrl, pPort->ProObj->channel, addr);
761 USLPUT3("addr %d, data 0x%x\n", addr, parm[0]);
762 return 0;
763}
764
765static s8 si_ram_set( Port_t *pPort, u8 *parm, const u8 size)
766{
767 u8 *temp_p = NULL;
768 u32 ram = 0;
769 u32 write_value = 0;
770 u32 read_value = 0;
771
772
773 if((NULL == pPort) || (NULL == parm))
774 {
775 USLPUT0("si_ram_set pPort/parm NULL \n");
776 return -1;
777 }
778
779 temp_p = (u8*) parm;
780 ram = *temp_p & 0xff;
781 temp_p++;
782 ram = ram | ((u8)(*temp_p)<<8);
783
784 temp_p++;
785 write_value = *temp_p;
786 temp_p++;
787 write_value = write_value | ((u8)(*temp_p)<<8);
788 temp_p++;
789 write_value = write_value | ((u8)(*temp_p)<<16);
790 temp_p++;
791 write_value = write_value | ((u8)(*temp_p)<<24);
792 USLPUT3("write: ram:%d value:0x%x.\n", ram, write_value);
793
794 setUserMode(pPort->ProObj, TRUE);
795 ctrl_WriteRAMWrapper (pPort->ProObj->deviceId->ctrlInterface->hCtrl, pPort->ProObj->channel, ram, write_value);
796 read_value = ctrl_ReadRAMWrapper(pPort->ProObj->deviceId->ctrlInterface->hCtrl, pPort->ProObj->channel, ram);
797 setUserMode(pPort->ProObj, FALSE);
798 USLPUT3("read: ram:%d value:0x%x.\n", ram, read_value);
799
800 return 0;
801}
802
803static s8 si_ram_get( Port_t *pPort, u8 *parm, const u8 size)
804{
805 u32 temp = 0;
806 u16 addr = 0;
807
808 if(NULL == pPort)
809 {
810 USLPUT0("si_ram_get pPort NULL \n");
811 return -1;
812 }
813
814 addr = *(u16 *)parm;
815 printk("SLIC read ram %d\n", addr);
816 setUserMode(pPort->ProObj, TRUE);
817 temp = ctrl_ReadRAMWrapper(pPort->ProObj->deviceId->ctrlInterface->hCtrl, pPort->ProObj->channel, addr);
818 *((u32 *)parm) = temp;
819 setUserMode(pPort->ProObj, FALSE);
820
821 USLPUT3("addr %d, data 0x%x\n", addr, temp);
822
823 return 0;
824}
825
826static s8 si_update_ringpara(SILAB_CFG_CHIP_t *ptOldCfg, u8 ringvol_param)
827{
828 u32 dwNewRing = RING_F20_45VRMS_0VDC_LPR;
829
830 switch (ringvol_param)
831 {
832#if 0
833 case RING_VOLTAGE_55VPK:
834 dwNewRing = RING_F25_40VRMS_0VDC_BAL; /* 40vrms */
835 break;
836 case RING_VOLTAGE_65VPK:
837 dwNewRing = RING_F25_45VRMS_0VDC_BAL; /* 45vrms */
838 break;
839 case RING_VOLTAGE_70VPK:
840 dwNewRing = RING_F25_50VRMS_0VDC_BAL; /* 50vrms */
841 break;
842 case RING_VOLTAGE_75VPK:
843 dwNewRing = RING_F25_55VRMS_0VDC_BAL; /* 55vrms */
844 break;
845 case RING_VOLTAGE_85VPK:
846 dwNewRing = RING_F25_60VRMS_0VDC_BAL; /* 60vrms */
847 break;
848#endif
849 default:
850 dwNewRing = RING_F20_45VRMS_0VDC_LPR; /* 50vrms */
851 break;
852 }
853
854 if (dwNewRing != ptOldCfg->ring)
855 {
856 ptOldCfg->ring = dwNewRing;
857 return 1;
858 }
859
860 return 0;
861}
862
863static s8 si_ring_cfg(Port_t *pPort, u8 ringvol_param)
864{
865 if(NULL == pPort)
866 {
867 USLPUT0("si3217x cfg ringvpk with NULL pointer pPort!\n");
868 return -1;
869 }
870
871 if (1 == si_update_ringpara(pPort->pPreCfg, ringvol_param))
872 {
873 ProSLIC_RingSetup(pPort->ProObj, pPort->pPreCfg->ring);
874 }
875
876 return 0;
877}
878
879static s8 si_update_dcpara(SILAB_CFG_CHIP_t *ptOldCfg, u8 vol_param, u8 cur_param)
880{
881 u32 dwNewDc = DCFEED_48V_20MA;
882
883 switch (vol_param)
884 {
885 case DC_VOLTAGE_48V:
886 switch (cur_param)
887 {
888#if 0
889 case DC_CURRENT_20MA:
890 dwNewDc = DCFEED_48V_20MA; /* 48v20mA */
891 break;
892 case DC_CURRENT_24MA:
893 dwNewDc = DCFEED_48V_24MA; /* 48v24mA */
894 break;
895 case DC_CURRENT_28MA:
896 dwNewDc = DCFEED_48V_28MA; /* 48v28mA */
897 break;
898 case DC_CURRENT_32MA:
899 dwNewDc = DCFEED_48V_32MA; /* 48v32mA */
900 break;
901#endif
902 default:
903 dwNewDc = DCFEED_48V_25MA; /* 48v25mA */
904 break;
905 }
906 break;
907 case DC_VOLTAGE_52V:
908 switch (cur_param)
909 {
910#if 0
911 case DC_CURRENT_20MA:
912 dwNewDc = DCFEED_52V_20MA; /* 52v20mA */
913 break;
914 case DC_CURRENT_24MA:
915 dwNewDc = DCFEED_52V_24MA; /* 52v24mA */
916 break;
917 case DC_CURRENT_28MA:
918 dwNewDc = DCFEED_52V_28MA; /* 52v28mA */
919 break;
920 case DC_CURRENT_32MA:
921 dwNewDc = DCFEED_52V_32MA; /* 52v32mA */
922 break;
923#endif
924 default:
925 dwNewDc = DCFEED_48V_25MA; /* 48v25mA */
926 break;
927 }
928 break;
929 default:
930 dwNewDc = DCFEED_48V_25MA; /* 48v25mA */
931 break;
932 }
933
934 if (dwNewDc != ptOldCfg->dc)
935 {
936 ptOldCfg->dc = dwNewDc;
937 return 1;
938 }
939
940 return 0;
941}
942
943static s8 si_dcfeed_cfg(Port_t *pPort, u8 vol_param, u8 cur_param)
944{
945 if(pPort == NULL)
946 {
947 USLPUT0("si3217x cfg dcfeed with NULL pointer pPort!\n");
948 return -1;
949 }
950
951 if (1 == si_update_dcpara(pPort->pPreCfg, vol_param, cur_param))
952 {
953 ProSLIC_DCFeedSetup(pPort->ProObj, pPort->pPreCfg->dc);
954 }
955
956 return 0;
957}
958
959static s8 si_disable_powersave(Port_t *pPort)
960{
961 u8 bData = 0;
962
963 bData = ctrl_ReadRegisterWrapper(pPort->ProObj->deviceId->ctrlInterface->hCtrl, pPort->ProObj->channel, SI3217X_COM_REG_ENHANCE);
964 bData &= ~0x10;
965 ctrl_WriteRegisterWrapper(pPort->ProObj->deviceId->ctrlInterface->hCtrl, pPort->ProObj->channel,SI3217X_COM_REG_ENHANCE, bData);
966
967 return 0;
968}
969
970static s8 si_electric_set(Port_t *pPort, const u16 port, const ELECTRIC_CFG_CUSTOMIZED *buf)
971{
972 s8 ret = 0;
973
974 u8 bRingVol = 0;
975 u8 bDcVol = 0;
976 u8 bDcCur = 0;
977
978 if((NULL == pPort) || (buf == NULL))
979 {
980 USLPUT0("si_electric_set pPort/buf NULL \n");
981 return -1;
982 }
983
984 bRingVol = buf->bCusRingVpk;
985 bDcVol = buf->bCusDcVol;
986 bDcCur = buf->bCusDcLoopCurr;
987
988#if 0
989 switch(buf->bScene)
990 {
991 case DB_SLC_SINGLEPHONE_SHORTLOOP:
992 bRingVol = RING_VOLTAGE_70VPK;
993 bDcVol = DC_VOLTAGE_48V;
994 bDcCur = DC_CURRENT_20MA;
995 break;
996 case DB_SLC_MULTIPHONES_SHORTLOOP:
997 bRingVol = RING_VOLTAGE_70VPK;
998 bDcVol = DC_VOLTAGE_48V;
999 bDcCur = DC_CURRENT_32MA;
1000 break;
1001 case DB_SLC_LONGLOOP:
1002 bRingVol = RING_VOLTAGE_85VPK;
1003 bDcVol = DC_VOLTAGE_52V;
1004 bDcCur = DC_CURRENT_20MA;
1005 break;
1006 case DB_SLC_ORIGINAL_FACTORY:
1007 bRingVol = RING_VOLTAGE_70VPK;
1008 bDcVol = DC_VOLTAGE_48V;
1009 bDcCur = DC_CURRENT_20MA;
1010 break;
1011 case DB_SLC_CUSTOMIZED:
1012 /* use customized parameters */
1013 break;
1014 default:
1015 USLPUT0("\n Not support scence:%d \n", buf->bScene);
1016 break;
1017 }
1018#endif
1019
1020 USLPUT3("si_electric_set Ring_vol: %d Dc_vol: %d Dc_cur: %d\n", bRingVol, bDcVol, bDcCur);
1021
1022 ret = si_dcfeed_cfg(pPort, bDcVol, bDcCur);
1023 if(ret)
1024 {
1025 USLPUT0("si_dcfeed_cfg fail !!! \n");
1026 }
1027
1028 ret = si_ring_cfg(pPort, bRingVol);
1029 if(ret)
1030 {
1031 USLPUT0("si_ring_cfg fail !!! \n");
1032 }
1033
1034 return 0;
1035}
1036
1037static s8 si_time_cfg(Port_t *pPort, const USL_CONFIG *Slc_Time_Cfg)
1038{
1039 if((NULL == pPort) || (NULL == Slc_Time_Cfg))
1040 {
1041 USLPUT0("si_time_cfg pPort/Slc_Time_Cfg NULL \n");
1042 return -1;
1043 }
1044
1045 pPort->stUslConf.hookonmin = MS2JIFF(Slc_Time_Cfg->hookonmin, 10) + 2;
1046 pPort->stUslConf.hookoffmin = MS2JIFF(Slc_Time_Cfg->hookoffmin, 10) - 2;
1047 pPort->stUslConf.prehookoff = MS2JIFF(Slc_Time_Cfg->prehookoff, 10) - 2;
1048 pPort->stUslConf.flash_low_min = MS2JIFF(Slc_Time_Cfg->flash_low_min, 10) - 2;
1049 pPort->stUslConf.flash_low_max = MS2JIFF(Slc_Time_Cfg->hookonmin, 10) + 2;
1050 pPort->stUslConf.flash_high_fix = MS2JIFF(Slc_Time_Cfg->flash_high_fix, 10) - 2;
1051 pPort->stUslConf.dial_high_min = MS2JIFF(Slc_Time_Cfg->dial_high_min, 10) - 2;
1052 pPort->stUslConf.dial_high_max = MS2JIFF(Slc_Time_Cfg->dial_high_max, 10) + 2;
1053 pPort->stUslConf.dial_low_min = MS2JIFF(Slc_Time_Cfg->dial_low_min, 10) - 2;
1054 pPort->stUslConf.dial_low_max = MS2JIFF(Slc_Time_Cfg->dial_low_max, 10) + 2;
1055
1056 return 0;
1057}
1058
1059static s8 si_slctool_time_cfg(Port_t *pPort, SLIC_IOCTL_CMD cmd, u16 wTime)
1060{
1061 if(NULL == pPort)
1062 {
1063 USLPUT0("si_slctool_time_cfg pPort NULL \n");
1064 return -1;
1065 }
1066
1067 switch(cmd)
1068 {
1069 case SLIC_CFG_HOOK_LOWLEN:
1070 case SLIC_CFG_FLASH_LMAX:
1071 pPort->stUslConf.hookonmin = MS2JIFF(wTime, 10) + 2;
1072 pPort->stUslConf.flash_low_max = MS2JIFF(wTime, 10) + 2;
1073 break;
1074
1075 case SLIC_CFG_HOOK_HIGLEN:
1076 pPort->stUslConf.hookoffmin = MS2JIFF(wTime, 10) - 2;
1077 break;
1078 case SLIC_CFG_PREHOOK_HIGLEN:
1079 pPort->stUslConf.prehookoff = MS2JIFF(wTime, 10) - 2;
1080 break;
1081 case SLIC_CFG_FLASH_LMIN:
1082 pPort->stUslConf.flash_low_min = MS2JIFF(wTime, 10) - 2;
1083 break;
1084 case SLIC_CFG_FLASH_HFIX:
1085 pPort->stUslConf.flash_high_fix = MS2JIFF(wTime, 10) - 2;
1086 break;
1087 case SLIC_CFG_DIAL_HMIN:
1088 pPort->stUslConf.dial_high_min = MS2JIFF(wTime, 10) - 2;
1089 break;
1090 case SLIC_CFG_DIAL_HMAX:
1091 pPort->stUslConf.dial_high_max = MS2JIFF(wTime, 10) + 2;
1092 break;
1093 case SLIC_CFG_DIAL_LMIN:
1094 pPort->stUslConf.dial_low_min = MS2JIFF(wTime, 10) - 2;
1095 break;
1096 case SLIC_CFG_DIAL_LMAX:
1097 pPort->stUslConf.dial_low_max = MS2JIFF(wTime, 10) + 2;
1098 break;
1099 default:
1100 USLPUT0("cmd=%d not found!\n", cmd);
1101 break;
1102 }
1103
1104 return 0;
1105}
1106
1107static void InitPortsData(int port)
1108{
1109 if (port >= MAX_PORT_NUM)
1110 {
1111 USLPUT0("InitPortsData port %d fail\n", port);
1112 return;
1113 }
1114
1115 ports[port].hook_state = HOOKON;
1116 ports[port].pulse_dig = 0;
1117 ports[port].stLineTestPara.si_item = 0xff;
1118 ports[port].stLineTestPara.test_flg = NOT_TEST;
1119 ports[port].stLineTestPara.cnt = 0;
1120 ports[port].low_len = 0;
1121 ports[port].high_len = 0;
1122
1123 ports[port].stUslConf.hookonmin = MS2JIFF(100, 10)/10;
1124 ports[port].stUslConf.hookoffmin = MS2JIFF(10, 10)/10;
1125 ports[port].stUslConf.prehookoff = MS2JIFF(6, 10)/10;
1126 ports[port].stUslConf.flash_low_min = MS2JIFF(4, 10)/10;
1127 ports[port].stUslConf.flash_low_max = MS2JIFF(40, 10)/10;
1128 ports[port].stUslConf.flash_high_fix = MS2JIFF(25, 10)/10;
1129 ports[port].stUslConf.dial_high_min = MS2JIFF(3, 10)/10;
1130 ports[port].stUslConf.dial_high_max = MS2JIFF(12, 10)/10;
1131 ports[port].stUslConf.dial_low_min = MS2JIFF(4, 10)/10;
1132 ports[port].stUslConf.dial_low_max = MS2JIFF(15, 10)/10;
1133
1134 /* add slic inf pre cfg to port struct */
1135 ports[port].pPreCfg = &BoardCfg[port];
1136
1137 return;
1138}
1139
1140int InitSiliconBoard(void)
1141{
1142 int i = 0;
1143 int dwInitCh = 0;
1144 int devtpye = -1;
1145 int ret = 0;
1146 USL_PORT_MAP *p = NULL;
1147
1148 SlicHardReset();
1149
1150 for(i = 0; i < MAX_PORT_NUM; i++)
1151 {
1152 p = get_port_item(i, SLIC_PORT_TYPE );
1153
1154 if(NULL != p)
1155 {
1156 #ifdef DEBUG_SLIC_ON
1157 USLPUT0("Init port %d\n", i);
1158 #endif
1159 spiGciObj[i].port = p->cs;
1160
1161 ProSLIC_createControlInterface(&ProHWIntf[i]);
1162 ProSLIC_createDevice(&(ProSLICDevices[i]));
1163 ProSLIC_createChannel(&ports[i].ProObj);
1164 devtpye = VerifyChipID(&spiGciObj[i], p->chan);
1165 if(-1 != devtpye)
1166 {
1167 ProSLIC_SWInitChan(ports[i].ProObj,p->chan,devtpye,ProSLICDevices[i],ProHWIntf[i]);
1168 ProSLIC_setSWDebugMode(ports[i].ProObj,true); /* optional */
1169
1170 ProSLIC_setControlInterfaceCtrlObj (ProHWIntf[i], &spiGciObj[i]);
1171 ProSLIC_setControlInterfaceReset (ProHWIntf[i], ctrl_ResetWrapper);
1172 ProSLIC_setControlInterfaceWriteRegister (ProHWIntf[i], ctrl_WriteRegisterWrapper);
1173 ProSLIC_setControlInterfaceReadRegister (ProHWIntf[i], ctrl_ReadRegisterWrapper);
1174 ProSLIC_setControlInterfaceWriteRAM (ProHWIntf[i], ctrl_WriteRAMWrapper);
1175 ProSLIC_setControlInterfaceReadRAM (ProHWIntf[i], ctrl_ReadRAMWrapper);
1176 ProSLIC_setControlInterfaceTimerObj (ProHWIntf[i], &timerObj);
1177 ProSLIC_setControlInterfaceDelay (ProHWIntf[i], time_DelayWrapper);
1178 ProSLIC_setControlInterfaceTimeElapsed (ProHWIntf[i], time_TimeElapsedWrapper);
1179 ProSLIC_setControlInterfaceGetTime (ProHWIntf[i], time_GetTimeWrapper);
1180 ProSLIC_setControlInterfaceSemaphore (ProHWIntf[i], SiSetSemaphore);
1181
1182 ProSLIC_Reset(ports[i].ProObj);
1183 arrayOfProslicChans[i] = ports[i].ProObj;
1184#ifdef SI3218X
1185 (arrayOfProslicChans[i])->deviceId->chipType=SI32185;
1186#endif
1187 dwInitCh++;
1188 }
1189 else
1190 {
1191 #ifdef DEBUG_SLIC_ON
1192 USLPUT0("No Siliconlab chip was found!!\n");
1193 #endif
1194 }
1195 }
1196 }
1197
1198 if (0 == dwInitCh)
1199 {
1200 USLPUT0("No Siliconlab chip need to be initialized!!\n");
1201 return -1;
1202 }
1203
1204#ifdef SIVOICE_MULTI_BOM_SUPPORT
1205printk("ProSLIC_Init_MultiBOM\n");
1206 ret = ProSLIC_Init_MultiBOM(arrayOfProslicChans,dwInitCh,BoardCfg[0].generel_cfg);
1207#else
1208printk("ProSLIC_Init\n");
1209
1210 ret = ProSLIC_Init(arrayOfProslicChans,dwInitCh);
1211#endif
1212 if(0 != ret)
1213 {
1214 printk("howard ProSLIC_Init_MultiBOM return %d\n", ret);
1215 return ret;
1216 }
1217 /* as to 32260 can make some phone crash, and no need to do this for short subscriber line, so don't use it again */
1218 //ProSLIC_LBCal(arrayOfProslicChans,dwInitCh);
1219
1220 for(i = 0; i < dwInitCh; i++)
1221 {
1222 USLPUT3("get_port_item port:%d.\n",i);
1223 p = get_port_item(i, SLIC_PORT_TYPE );
1224
1225 if (NULL != p)
1226 {
1227 USLPUT3("channelEnable:%d.\n",ports[i].ProObj->channelEnable);
1228 if( 1 == ports[i].ProObj->channelEnable )
1229 {
1230 USLPUT3("Register the port:%d.\n",i);
1231 InitPortsData(i);
1232 InitSiliconChip(&ports[i]);
1233 usrline_port_register(p->port, p->type, &si_ops, &ports[i]);
1234 }
1235 else
1236 {
1237 USLPUT0("port:%d disabled.\n",i);
1238 return -1;
1239 }
1240 }
1241 }
1242 //init_flg = 1;
1243 return 0;
1244}
1245
1246int SiSetSemaphore(void *pHCtrl, int s)
1247{
1248 /* Only slic use spi */
1249 return 1;
1250}
1251
1252/* handle the event */
1253int HandleSiEvent(Port_t *pPort, proslicIntType *pIntData)
1254{
1255 int i = 0;
1256 ProslicInt IntData ;
1257
1258 i = pIntData->number;
1259 while(i--)
1260 {
1261 IntData = pIntData->irqs[i];
1262 #ifdef DEBUG_SLIC_ON
1263 switch(IntData)
1264 {
1265 case IRQ_VBAT:
1266 /* The sensed battery voltage differs from the nominal VBAT value by an amount exceeding a programmed threshold. */
1267 USLPUT2(" Error:VBAT_IA.\n");
1268 break;
1269 case IRQ_RING_TRIP:
1270 break;
1271 case IRQ_LOOP_STATUS:
1272 /* Hookoff */
1273 break;
1274 case IRQ_LONG_STAT:
1275 /* LONG_HI_IA */
1276 USLPUT2(" Error: LONG_HI_IA.\n");
1277 break;
1278 case IRQ_VOC_TRACK:
1279 /* The sensed battery voltage cannot support the programmed differential voltage. */
1280 USLPUT2(" Error: VOC_TRACK_IA.\n");
1281 break;
1282 case IRQ_MADC_FS:
1283 break;
1284 case IRQ_P_HVIC:
1285 /* a hardware power alarm based on the total chip power dissipation by the HVIC. */
1286 USLPUT2(" Error:IRQ_P_HVIC.\n");
1287 break;
1288 case IRQ_P_THERM:
1289 /* A hardware power alarm. */
1290 USLPUT2(" Error:P_THERM_IA.\n");
1291 break;
1292 case IRQ_OSC1_T1:
1293 case IRQ_OSC1_T2:
1294 case IRQ_OSC2_T1:
1295 case IRQ_OSC2_T2:
1296 case IRQ_RING_T1:
1297 case IRQ_RING_T2:
1298 case IRQ_PM_T1:
1299 case IRQ_PM_T2:
1300 case IRQ_FSKBUF_AVAIL:
1301 case IRQ_P_OFFLD:
1302 case IRQ_DTMF:
1303 case IRQ_INDIRECT:
1304 case IRQ_TXMDM:
1305 case IRQ_RXMDM:
1306 case IRQ_PQ1:
1307 case IRQ_PQ2:
1308 case IRQ_PQ3:
1309 case IRQ_PQ4:
1310 case IRQ_PQ5:
1311 case IRQ_PQ6:
1312 case IRQ_RING_FAIL:
1313 case IRQ_CM_BAL:
1314 case IRQ_USER_0:
1315 case IRQ_USER_1:
1316 case IRQ_USER_2:
1317 case IRQ_USER_3:
1318 case IRQ_USER_4:
1319 case IRQ_USER_5:
1320 case IRQ_USER_6:
1321 case IRQ_USER_7:
1322 case IRQ_DSP:
1323 break;
1324 default:
1325 break;
1326 }
1327 #endif
1328 }
1329
1330 return 0;
1331}
1332
1333void SiScanSignals(USL_PORT *usl_port, u8 hook)
1334{
1335 Port_t *data = usl_port->pLine;
1336
1337 SiUpdatePort(data, usl_port->port, hook);
1338 switch(data->hook_state)
1339 {
1340 case HOOKON:
1341 break;
1342 case HOOKOFFING:
1343 if ( data->high_len == data->stUslConf.prehookoff )
1344 {
1345 /* User Pre HookOff! report */
1346
1347 }
1348 if ( data->high_len < data->stUslConf.hookoffmin )
1349 {
1350 return;
1351 }
1352 //usrline_report(usl_port->port, EV_FXS_PRE_HOOKOFF, 0, usl_port->event_mask);
1353 /* Finished. change state to HOOKOFF */
1354 data->hook_state = HOOKOFF;
1355 /* User HookOff! report */
1356 //ProSLIC_SetLinefeedStatus( data->ProObj, LF_FWD_ACTIVE );??
1357
1358 usrline_report(usl_port->port,EV_FXS_HOOKOFF,0, usl_port->event_mask);
1359 slic_offhook = 1;
1360
1361 break;
1362 case HOOKOFF:
1363 if (data->high_len == data->stUslConf.flash_high_fix &&
1364 data->low_len < data->stUslConf.hookonmin && data->low_len >= data->stUslConf.dial_low_min )
1365 {
1366 if (data->pulse_dig == FLASH_EV_FLG)
1367 {
1368 USLPUT2("EV_FXS_FLASH: line=%d,low=%d. high %d\n",usl_port->port, data->low_len,data->high_len);
1369 usrline_report(usl_port->port,EV_FXS_FLASH,0, usl_port->event_mask);
1370 }
1371 else if (( 1 <= data->pulse_dig ) && ( 10 >= data->pulse_dig ))
1372 {
1373 USLPUT2("EV_FXS_COLLECT_DIG: line=%d,low=%d. high %d\n",usl_port->port, data->low_len,data->high_len);
1374 usrline_report(usl_port->port,EV_FXS_COLLECT_DIG,data->pulse_dig%10, usl_port->event_mask);
1375 }
1376 else
1377 {
1378 USLPUT2("drop dig:%d! line=%d, low %d, high %d\n", usl_port->port, data->pulse_dig, data->low_len, data->high_len);
1379 }
1380 data->pulse_dig = 0;
1381 }
1382
1383 break;
1384 case HOOKONING:
1385 if (data->low_len < data->stUslConf.hookonmin)
1386 {
1387 //printk("low_len %d < hookonmin %d, return\n", data->low_len, data->stUslConf.hookonmin);
1388 return;
1389 }
1390 /* Finished. change state to HOOKON */
1391 //printk("low_len %d < hookonmin %d\n", data->low_len, data->stUslConf.hookonmin);
1392 data->hook_state = HOOKON;
1393 /* User HookOn! report */
1394 data->pulse_dig = 0;
1395 data->bDialEn = EV_DIAL_STOP;
1396 usrline_report(usl_port->port,EV_FXS_HOOKON,0,usl_port->event_mask);
1397 slic_offhook = 0;
1398
1399 break;
1400 default:
1401 break;
1402 }
1403}
1404
1405void SiUpdatePort(Port_t *data, u16 port, u8 event)
1406{
1407 if (event == EV_LOW)
1408 {
1409 data->low_len++;
1410 switch (data->hook_state)
1411 {
1412 case HOOKOFFING:
1413 /* short pulse filter */
1414 if (data->low_len > PULSE_FILTER_TIME)
1415 {
1416 data->hook_state = HOOKON;
1417 data->low_len = 0;
1418 }
1419 else
1420 {
1421 data->high_len++;
1422 }
1423 break;
1424 case HOOKOFF:
1425 if (data->low_len > PULSE_FILTER_TIME)
1426 {
1427 data->hook_state = HOOKONING;
1428 data->low_len = 0;
1429 }
1430 else
1431 {
1432 data->high_len++;
1433 }
1434 break;
1435 default:
1436 break;
1437 }
1438 }
1439 else
1440 {
1441 data->high_len++;
1442 switch (data->hook_state)
1443 {
1444 case HOOKON:
1445 if (data->high_len > PULSE_FILTER_TIME)
1446 {
1447 data->hook_state = HOOKOFFING;
1448 data->high_len = 0;
1449 }
1450 else
1451 {
1452 data->low_len++;
1453 }
1454 break;
1455 case HOOKONING:
1456 if (data->high_len > PULSE_FILTER_TIME)
1457 {
1458 data->hook_state = HOOKOFF;
1459 /* To Judge if there is a pulse occured */
1460 if((EV_DIAL_START == data->bDialEn) && (data->low_len >= data->stUslConf.dial_low_min) &&
1461 (data->low_len < data->stUslConf.dial_low_max))
1462 {
1463 data->pulse_dig++;
1464 USLPUT3("port:%d pulse_dig++! low %d, high %d, dig %d\n", port, data->low_len, data->high_len, data->pulse_dig);
1465 }
1466 else if(data->low_len >= data->stUslConf.flash_low_min)
1467 {
1468 data->pulse_dig = FLASH_EV_FLG;
1469 USLPUT3("port:%d Flash! low %d, high %d\n", port, data->low_len, data->high_len);
1470 }
1471 else
1472 {
1473 USLPUT3("port:%d Pulse not dientfied! low %d, high %d\n", port, data->low_len, data->high_len);
1474 }
1475 data->high_len = 0;
1476 }
1477 else
1478 {
1479 data->low_len++;
1480 }
1481 break;
1482 default:
1483 break;
1484 }
1485 }
1486}
1487
1488void InitSiliconChip(Port_t *pPort)
1489{
1490
1491 /* DC */
1492 ProSLIC_DCFeedSetup(pPort->ProObj, pPort->pPreCfg->dc);
1493 //ProSLIC_SetLinefeedStatus(pPort->ProObj, pPort->pPreCfg->linestaus);
1494
1495 /* Ring init */
1496 ProSLIC_RingSetup(pPort->ProObj, pPort->pPreCfg->ring);
1497 /* PCM init */
1498 ProSLIC_PCMSetup(pPort->ProObj, pPort->pPreCfg->a_u_law);
1499 ProSLIC_PCMTimeSlotSetup(pPort->ProObj,0x1,0x1);
1500
1501 ProSLIC_ZsynthSetup(pPort->ProObj, pPort->pPreCfg->Impe);
1502 ProSLIC_ToneGenSetup(pPort->ProObj, pPort->pPreCfg->tone);
1503
1504 /* Meter init */
1505 //ProSLIC_PulseMeterSetup(pPort->ProObj, pPort->pPreCfg->meter);
1506
1507 ProSLIC_FSKSetup(pPort->ProObj, ITU_FSK);
1508 ProSLIC_AudioGainSetup(pPort->ProObj, pPort->pPreCfg->rxgain, pPort->pPreCfg->txgain, pPort->pPreCfg->Impe);
1509
1510 /* Active the line */
1511 ProSLIC_EnableInterrupts(pPort->ProObj);
1512 ProSLIC_SetLinefeedStatus(pPort->ProObj,LF_FWD_ACTIVE);
1513
1514
1515 if (1 == pPort->pPreCfg->bDisablePowerSave)
1516 {
1517 si_disable_powersave(pPort);
1518 }
1519
1520 return;
1521}
1522
1523int SiRemoveBoard(void)
1524{
1525 int i = 0;
1526 USL_PORT_MAP *p = NULL;
1527
1528 for( i = 0; i <MAX_PORT_NUM; i++ )
1529 {
1530 p = get_port_item(i, SLIC_PORT_TYPE);
1531
1532 if(p != NULL)
1533 {
1534 if (1 == ports[i].ProObj->channelEnable)
1535 {
1536 USLPUT3("shutdown port:%d, ch:%d\n", i, ports[i].ProObj->channel);
1537 /* reset chip */
1538 ProSLIC_Reset(ports[i].ProObj);
1539 }
1540
1541 p->cs = 0;
1542 p->chan = 0;
1543 p->port = 0;
1544
1545 /* free chip related memory */
1546 ProSLIC_destroyChannel(&ports[i].ProObj);
1547 ProSLIC_destroyDevice(&(ProSLICDevices[i]));
1548 ProSLIC_destroyControlInterface(&ProHWIntf[i]);
1549 }
1550 }
1551
1552 return 0;
1553}
1554
1555int ProSLIC_DTMFValid (proslicChanType_ptr pProslic)
1556{
1557 int valid_tone = 0;
1558 if(pProslic->channelType != PROSLIC)
1559 {
1560 return RC_IGNORE;
1561 }
1562 valid_tone = ctrl_ReadRegisterWrapper( pProslic->deviceId->ctrlInterface->hCtrl,
1563 pProslic->channel,PROSLIC_REG_TONDTMF ) & 0x10;
1564 if(valid_tone)
1565 return 1;
1566 else
1567 return 0;
1568}
1569
1570void ScanSiBoard(USL_PORT *pUslPort)
1571{
1572 u8 hook = 0;
1573 int ret = 0;
1574 switch (pUslPort->pLine->stLineTestPara.test_flg)
1575 {
1576 case NOT_TEST:
1577 if(dtmf_mute)
1578 {
1579 ret = ProSLIC_DTMFValid(pUslPort->pLine->ProObj);
1580 if(!ret)
1581 {
1582 //ProSLIC_SetMuteStatus(pUslPort->pLine->ProObj,PROSLIC_MUTE_NONE);
1583 dtmf_mute = 0;
1584 }
1585 }
1586 //ProSLIC_ReadHookStatus(pUslPort->pLine->ProObj,&hook);
1587 hook = slic_offhook;
1588 SiScanSignals(pUslPort, hook);
1589 break;
1590 case TEST_STARTING:
1591 case TEST_STOPING:
1592 USLPUT3("change state:%d,do nothing\n", pUslPort->pLine->stLineTestPara.test_flg);
1593 break;
1594 case TESTING:
1595 SiMltScan(pUslPort->pLine);
1596 break;
1597 default:
1598 USLPUT0("unknow test state:%d\n", pUslPort->pLine->stLineTestPara.test_flg);
1599 break;
1600 }
1601
1602 return;
1603}
1604
1605int VerifyChipID(ctrl_S *hCtrl, u8 chan)
1606{
1607 u8 id = 0;
1608 int devtype = 0;
1609
1610 id = ctrl_ReadRegisterWrapper(hCtrl, chan,SI3217X_COM_REG_ID);
1611 printk("Siliconlab chip cs:%d ch:%d id! 0x%x \n",hCtrl->port, chan, id);
1612 USLPUT0("Siliconlab chip cs:%d ch:%d id! 0x%x \n", hCtrl->port, chan, id);
1613#if 0
1614 if (0xFF == id)
1615 {
1616 USLPUT0("Siliconlab chip cs:%d ch:%d id error! 0x%x \n", hCtrl->port, chan, id);
1617 return devtype;
1618 }
1619
1620 switch(id&0xc0)
1621 {
1622 case 0x80:
1623 devtype = SI3217X_TYPE;
1624 USLPUT0("Siliconlab chip Si3217x found! id:0x%x\n", id);
1625 break;
1626 case 0xc0:
1627 devtype = SI3226X_TYPE;
1628 USLPUT0("Siliconlab chip Si3226x found! id:0x%x\n", id);
1629 break;
1630 default:
1631 USLPUT0("Siliconlab chip id error! 0x%x \n",id);
1632 break;
1633 }
1634#endif
1635#if 0
1636 switch( (id & 0x38) >> 3 )
1637 {
1638
1639 case 0:/* Si32171 */
1640 #ifdef DEBUG_SLIC_ON
1641 printk("Siliconlab chip Si32171 found!\n");
1642 #endif
1643 break;
1644 case 3:/* Si32175 */
1645 #ifdef DEBUG_SLIC_ON
1646 printk("Siliconlab chip Si32175 found!\n");
1647 #endif
1648 break;
1649 case 4:/* Si32176 */
1650 #ifdef DEBUG_SLIC_ON
1651 printk("Siliconlab chip Si32176 found!\n");
1652 #endif
1653 break;
1654 case 5:/* Si32177 */
1655 #ifdef DEBUG_SLIC_ON
1656 printk("Siliconlab chip Si32177 found!\n");
1657 #endif
1658 break;
1659 case 6:/* Si32178 */
1660 #ifdef DEBUG_SLIC_ON
1661 printk("Siliconlab chip Si32178 found!\n");
1662 #endif
1663 break;
1664 default:
1665 printk("Siliconlab chip id error! 0x%x \n",id);
1666 return -1;
1667 }
1668#endif
1669
1670 return SI3217X_TYPE;
1671}
1672
1673int ProSLIC_PCMCfg (proslicChanType_ptr hProslic,u8 preset)
1674{
1675 ctrl_WriteRegisterWrapper(hProslic->deviceId->ctrlInterface->hCtrl,hProslic->channel,SI3217X_COM_REG_PCMMODE,pcmcfg[preset]);
1676 return 0;
1677}
1678
1679int ProSLIC_PCMEnable (proslicChanType_ptr hProslic, u8 enable )
1680{
1681 u8 data = 0;
1682
1683 data = ctrl_ReadRegisterWrapper( hProslic->deviceId->ctrlInterface->hCtrl,hProslic->channel,SI3217X_COM_REG_PCMMODE );
1684
1685 if( enable )
1686 {
1687 data |= 0x10;
1688 }
1689 else
1690 {
1691 data &= 0xef;
1692 }
1693 ctrl_WriteRegisterWrapper(hProslic->deviceId->ctrlInterface->hCtrl,hProslic->channel,SI3217X_COM_REG_PCMMODE, data);
1694 return 0;
1695}
1696
1697int ProSLIC_GetLinefeedStatus (proslicChanType_ptr hProslic, uInt8 *pLinefeed)
1698{
1699 u8 data = 0;
1700
1701 data = ctrl_ReadRegisterWrapper(hProslic->deviceId->ctrlInterface->hCtrl,hProslic->channel,SI3217X_COM_REG_LINEFEED);
1702 *pLinefeed = data&0xf;
1703
1704 return 1;
1705}
1706
1707static int setUserMode (proslicChanType_ptr hProslic, BOOLEAN on)
1708{
1709 u8 data;
1710
1711 data = ctrl_ReadRegisterWrapper(hProslic->deviceId->ctrlInterface->hCtrl,hProslic->channel,SI3217X_COM_REG_TEST_CNTL);
1712 if (((data&1) != 0) == on)
1713 return 0;
1714 ctrl_WriteRegisterWrapper(hProslic->deviceId->ctrlInterface->hCtrl,hProslic->channel,SI3217X_COM_REG_TEST_CNTL, 2);
1715 ctrl_WriteRegisterWrapper(hProslic->deviceId->ctrlInterface->hCtrl,hProslic->channel,SI3217X_COM_REG_TEST_CNTL, 8);
1716 ctrl_WriteRegisterWrapper(hProslic->deviceId->ctrlInterface->hCtrl,hProslic->channel,SI3217X_COM_REG_TEST_CNTL, 0xe);
1717 ctrl_WriteRegisterWrapper(hProslic->deviceId->ctrlInterface->hCtrl,hProslic->channel,SI3217X_COM_REG_TEST_CNTL, 0);
1718
1719 return 0;
1720}
1721
1722static void StartSiLineTest(Port_t *pPort, uInt8 TestId)
1723{
1724 if(NULL == pPort)
1725 {
1726 USLPUT0("StartSiLineTest error input NULL pointer.\n");
1727 return;
1728 }
1729
1730 USLPUT2("StartSiLineTest: line %d item %d!\n", pPort->stLineTestPara.pstResult->port, TestId);
1731
1732 pPort->stLineTestPara.pstMlt->Mlt.pProslic = pPort->ProObj;
1733 MLTClearSettings(&pPort->stLineTestPara.pstMlt->Mlt);
1734 MLTClearResults(&pPort->stLineTestPara.pstMlt->Mlt);
1735 switch(TestId)
1736 {
1737 case TI_LineVolt:
1738 /* Call test state initalization function */
1739 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_OPEN);
1740 pPort->stLineTestPara.si_item = TI_LineVolt;
1741 ProSLIC_mlt_init_foreign_voltages(&pPort->stLineTestPara.pstMlt->vState,30);
1742 pPort->stLineTestPara.test_flg = TESTING;
1743 break;
1744 /*case ROH_TEST:
1745 id = LT_TID_ROH; Receiver Off-Hook indication
1746 break; */
1747 case TI_LineCap:
1748 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_OPEN);
1749 pPort->stLineTestPara.si_item = TI_LineCap;
1750 ProSLIC_mlt_init_capacitance(&pPort->stLineTestPara.pstMlt->CapState);
1751 pPort->stLineTestPara.test_flg = TESTING;
1752 break;
1753 case TI_LineRes:
1754 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_OPEN);
1755 pPort->stLineTestPara.si_item = TI_LineRes; /* Resistive Fault */
1756 /* Call test state initalization function */
1757 ProSLIC_mlt_init_resistive_faults(&pPort->stLineTestPara.pstMlt->rMeas);
1758 pPort->stLineTestPara.test_flg = TESTING;
1759 break;
1760 case TI_LineRes_reverse:
1761 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_OPEN);
1762 pPort->stLineTestPara.si_item = TI_LineRes_reverse; /* Resistive Fault */
1763 /* Call test state initalization function */
1764 ProSLIC_mlt_init_resistive_faults(&pPort->stLineTestPara.pstMlt->rMeas);
1765 pPort->stLineTestPara.test_flg = TESTING;
1766 break;/**/
1767 /*case GR_909:
1768 id = LT_TID_ALL_GR_909; All GR-909 fault tests in predefined order
1769 break;*/
1770 /*case LOOP_BACK:
1771 id = LT_TID_LOOPBACK; Loopback test
1772 break;*/
1773 case TI_LoopCircuitAndRes:
1774 pPort->stLineTestPara.si_item = TI_LoopCircuitAndRes;
1775 /* DC Feed Self Test */
1776 pPort->stLineTestPara.test_flg = TEST_STOPING;
1777 SiSendResultDCFeedSt(pPort);
1778 break;
1779 case TI_InLoopCurrent:
1780 pPort->stLineTestPara.si_item = TI_InLoopCurrent;
1781 /* DC Feed Self Test */
1782 pPort->stLineTestPara.test_flg = TEST_STOPING;
1783 SiSendResultDCFeedSt(pPort);
1784 break;
1785 case TI_BatteryVolt:
1786 /* DC VOLTAGE Test */
1787 pPort->stLineTestPara.si_item = TI_BatteryVolt;
1788 pPort->stLineTestPara.test_flg = TEST_STOPING;
1789 SiSendResultBatteryVol(pPort);
1790 break;
1791 case TI_RingVolt:
1792 /* Ringing Self Test */
1793 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_RINGING);
1794 pPort->stLineTestPara.si_item = TI_RingVolt;
1795 pPort->stLineTestPara.test_flg = TESTING;
1796 RingCnt = 0;
1797 /**/
1798 break;
1799 case ROH_TEST:
1800 /* On/Off hook Self Test */
1801 pPort->stLineTestPara.si_item = TI_Hook;
1802 pPort->stLineTestPara.test_flg = TEST_STOPING;
1803 SiSendResultHook(pPort);
1804 break;
1805 case TI_REN:
1806 ProSLIC_mlt_init_ren(&pPort->stLineTestPara.pstMlt->RenState);
1807 ProSLIC_mlt_init_ren_cal(&pPort->stLineTestPara.pstMlt->Mlt);
1808 pPort->stLineTestPara.si_item = TI_REN;
1809 pPort->stLineTestPara.test_flg = TESTING;
1810 break;
1811 /*case QUICKTEST:
1812 id = LT_TID_PRE_LINE_V; Pre Line Voltage Test
1813 break;*/
1814 /*case 13:
1815 id = LT_TID_FLT_DSCRM; Fault Discrimination Test
1816 break;*/
1817 case TI_Outside12:
1818 /*step 1: Line Voltage Test */
1819 /* Call test state initalization function */
1820 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_OPEN);
1821 pPort->stLineTestPara.si_item = TI_LineVolt;
1822 ProSLIC_mlt_init_foreign_voltages(&pPort->stLineTestPara.pstMlt->vState,30);
1823 pPort->stLineTestPara.test_flg = TESTING;
1824 break;
1825 case TI_LineConnect:
1826 /*Line Connectivity Test */
1827 StartLineConnectTest(pPort);
1828 break;
1829 default:
1830 USLPUT1("The item is not surpported!\n");
1831 SendErrorTest(pPort, NOT_SURPPORT);
1832 return;
1833 }
1834
1835 return;
1836}
1837
1838static s8 si_start_test(Port_t *pPort, const WriteCmd_t *Cmd)
1839{
1840 if((NULL == pPort) || (NULL == Cmd))
1841 {
1842 USLPUT0("si_start_test pPort/Cmd NULL pointer.\n");
1843 return -1;
1844 }
1845
1846 if (TEST_STARTING == pPort->stLineTestPara.test_flg || TESTING == pPort->stLineTestPara.test_flg)
1847 {
1848 USLPUT0("%s is under testing item:%d\n",__FUNCTION__, pPort->stLineTestPara.si_item);
1849 return 0;
1850 }
1851
1852 /* get test result memory */
1853 pPort->stLineTestPara.pstResult = (TestResult_t *)kmalloc(sizeof(TestResult_t), GFP_KERNEL);
1854 if (NULL == pPort->stLineTestPara.pstResult)
1855 {
1856 USLPUT0("%s port %d get TestResult memory failed!\n",__FUNCTION__, Cmd->port);
1857 return -1;
1858 }
1859 memset(pPort->stLineTestPara.pstResult, 0, sizeof(TestResult_t));
1860
1861 /* save test message */
1862 pPort->stLineTestPara.pstResult->port = Cmd->port;
1863 pPort->stLineTestPara.pstResult->port_type = Cmd->port_type;
1864 pPort->stLineTestPara.pstResult->item = Cmd->item;
1865 pPort->stLineTestPara.pstResult->obligate = Cmd->obligate;
1866 pPort->stLineTestPara.pstResult->num = Cmd->num;
1867 pPort->stLineTestPara.pstResult->omci_item = Cmd->omci_item;
1868 pPort->stLineTestPara.pstResult->flg = TEST_SUCC;
1869
1870 pPort->stLineTestPara.cnt = 0;
1871
1872
1873 if((HOOKOFF == pPort->hook_state) && (0 == pPort->stLineTestPara.pstResult->obligate))
1874 {
1875 USLPUT1("The user is bust now!\n");
1876 SendErrorTest(pPort, TEST_USER_BUSY);
1877 return -1;
1878 }
1879
1880 /* get memory to save testing data */
1881 pPort->stLineTestPara.pstMlt = (ProSLICMLT *)kmalloc(sizeof(ProSLICMLT), GFP_KERNEL);
1882 if (NULL == pPort->stLineTestPara.pstMlt)
1883 {
1884 USLPUT0("%s port %d get Mlt memory failed!\n",__FUNCTION__, Cmd->port);
1885 kfree(pPort->stLineTestPara.pstResult);
1886 pPort->stLineTestPara.pstResult = NULL;
1887 return -1;
1888 }
1889 memset(pPort->stLineTestPara.pstMlt, 0, sizeof(ProSLICMLT));
1890
1891 pPort->stLineTestPara.test_flg = TEST_STARTING;
1892
1893 StartSiLineTest(pPort, pPort->stLineTestPara.pstResult->item);
1894
1895 return 0;
1896}
1897
1898static s8 si_stop_test(Port_t *pPort)
1899{
1900 if(NULL == pPort)
1901 {
1902 USLPUT0("si_stop_test pPort NULL \n");
1903 return -1;
1904 }
1905
1906 if (TESTING == pPort->stLineTestPara.test_flg)
1907 {
1908 pPort->stLineTestPara.test_flg = TEST_STOPING;
1909 InitSiliconChip(pPort);
1910 }
1911
1912 if (NULL != pPort->stLineTestPara.pstMlt)
1913 {
1914 kfree(pPort->stLineTestPara.pstMlt);
1915 }
1916 pPort->stLineTestPara.pstMlt = NULL;
1917
1918 if (NULL != pPort->stLineTestPara.pstResult)
1919 {
1920 kfree(pPort->stLineTestPara.pstResult);
1921 }
1922 pPort->stLineTestPara.pstResult = NULL;
1923
1924 pPort->stLineTestPara.test_flg = NOT_TEST;
1925
1926 return 0;
1927}
1928
1929static s8 si_read_result(Port_t *pPort, TestResult_t *pstResult)
1930{
1931 if((NULL == pPort) || (NULL == pstResult))
1932 {
1933 USLPUT0("leg_read_result pPort/pstResult NULL pointer.\n");
1934 return -1;
1935 }
1936
1937 if (NULL != pPort->stLineTestPara.pstMlt)
1938 {
1939 kfree(pPort->stLineTestPara.pstMlt);
1940 }
1941 pPort->stLineTestPara.pstMlt = NULL;
1942
1943 if (NULL != pPort->stLineTestPara.pstResult)
1944 {
1945 memcpy(pstResult, pPort->stLineTestPara.pstResult, sizeof(TestResult_t));
1946 kfree(pPort->stLineTestPara.pstResult);
1947 }
1948 pPort->stLineTestPara.pstResult = NULL;
1949
1950 pPort->stLineTestPara.test_flg = NOT_TEST;
1951 USLPUT3("\npPort->stLineTestPara.cnt=%d\n", pPort->stLineTestPara.cnt);
1952
1953 return 0;
1954}
1955
1956static s8 StartLineConnectTest(Port_t *pPort)
1957{
1958 if(NULL == pPort)
1959 {
1960 USLPUT1("StartLineConnectTest pPort NULL.\n");
1961 return -1;
1962 }
1963
1964 if(HOOKOFF == pPort->hook_state)//Õª»ú£¬Ôò±¨Óл°»ú
1965 {
1966 pPort->stLineTestPara.pstResult->user_flg = 1;
1967 usrline_report(pPort->stLineTestPara.pstResult->port,EV_FXS_TEST_DONE,0,0);
1968 }
1969 else //¹Ò»ú£¬Ôò²âREN
1970 {
1971 pPort->stLineTestPara.pstResult->user_flg = 0;
1972 ProSLIC_mlt_init_ren(&pPort->stLineTestPara.pstMlt->RenState);
1973 ProSLIC_mlt_init_ren_cal(&pPort->stLineTestPara.pstMlt->Mlt);
1974 pPort->stLineTestPara.si_item = TI_REN;
1975 pPort->stLineTestPara.test_flg = TESTING;
1976 }
1977
1978 return 0;
1979}
1980
1981static s8 si_time_print(Port_t *pLine)
1982{
1983 USLPUT0("si32xxx times:\n");
1984 USLPUT0("hookonmin: %d\n",pLine->stUslConf.hookonmin);
1985 USLPUT0("hookoffmin: %d\n",pLine->stUslConf.hookoffmin);
1986 USLPUT0("prehookoff: %d\n",pLine->stUslConf.prehookoff);
1987 USLPUT0("flash_low_min: %d\n",pLine->stUslConf.flash_low_min);
1988 USLPUT0("flash_high_fix:%d\n",pLine->stUslConf.flash_high_fix);
1989 USLPUT0("dial_high_min: %d\n",pLine->stUslConf.dial_high_min);
1990 USLPUT0("dial_high_max: %d\n",pLine->stUslConf.dial_high_max);
1991 USLPUT0("dial_low_min: %d\n",pLine->stUslConf.dial_low_min);
1992 USLPUT0("dial_low_max: %d\n",pLine->stUslConf.dial_low_max);
1993 USLPUT0("dial_enable: %d\n",pLine->bDialEn);
1994
1995 return 0;
1996}
1997
1998static s8 si_dial_set(Port_t *pPort, u8 bDialEn)
1999{
2000 if(NULL == pPort)
2001 {
2002 USLPUT1("si_dial_set pPort NULL.\n");
2003 return -1;
2004 }
2005
2006 pPort->bDialEn = bDialEn;
2007
2008 return 0;
2009}
2010
2011
2012/*
2013** Clears REN cal flag
2014*/
2015 void MLTClearSettings(ProSLICMLTType *pProSLICMLT)
2016{
2017 pProSLICMLT->ren.renCalFlag = 0;
2018}
2019
2020/*
2021** Clears any previous GR909 test results CDP move this to proslic_mlt.c
2022*/
2023void MLTClearResults(ProSLICMLTType *pProSLICMLT)
2024{
2025 pProSLICMLT->hazVAC.measTG = 0;
2026 pProSLICMLT->hazVAC.measTR = 0;
2027 pProSLICMLT->hazVAC.measRG = 0;
2028 pProSLICMLT->hazVAC.resultsValid = 0;
2029
2030 pProSLICMLT->hazVDC.measTG = 0;
2031 pProSLICMLT->hazVDC.measTR = 0;
2032 pProSLICMLT->hazVDC.measRG = 0;
2033 pProSLICMLT->hazVDC.resultsValid = 0;
2034
2035 pProSLICMLT->resFaults.measTG = 10000000;
2036 pProSLICMLT->resFaults.measTR = 10000000;
2037 pProSLICMLT->resFaults.measRG = 10000000;
2038 pProSLICMLT->resFaults.resultsValid = 0;
2039
2040 pProSLICMLT->roh.rohTrue = RC_MLT_ROH_NOFAULT;
2041 pProSLICMLT->roh.resultsValid = 0;
2042
2043 pProSLICMLT->ren.renValue = 0;
2044 pProSLICMLT->ren.resultsValid = 0;
2045}
2046
2047void SiMltScan(Port_t *pPort)
2048{
2049 int done = 0;
2050
2051 pPort->stLineTestPara.cnt++;
2052 if( pPort->stLineTestPara.cnt > MAX_TEST_TIMEOUT ) /* Test time out */
2053 {
2054 pPort->stLineTestPara.test_flg = TEST_STOPING;
2055 InitSiliconChip(pPort);
2056 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_FWD_ACTIVE);
2057 SendErrorTest(pPort, TESTITEM_TIMEOVER);
2058 return;
2059 }
2060 switch( pPort->stLineTestPara.si_item )
2061 {
2062 case TI_LineVolt:
2063 /* Call test function - will return 1 when complete */
2064 done = ProSLIC_mlt_foreign_voltages(&pPort->stLineTestPara.pstMlt->Mlt,&pPort->stLineTestPara.pstMlt->vState);
2065 if(1 == done)
2066 {
2067 pPort->stLineTestPara.test_flg = TEST_STOPING;
2068 /* */
2069 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_FWD_ACTIVE);
2070 msleep(200); /* need more than 150ms to normal feed state */
2071 SiSendResultVol(pPort, &pPort->stLineTestPara.pstMlt->Mlt);
2072 }
2073
2074 break;
2075
2076 case TI_LineCap:
2077 done = ProSLIC_mlt_capacitance(&pPort->stLineTestPara.pstMlt->Mlt,&pPort->stLineTestPara.pstMlt->CapState);
2078 if(1 == done)
2079 {
2080 pPort->stLineTestPara.test_flg = TEST_STOPING;
2081 #ifdef DEBUG_SLIC_ON
2082 USLPUT2("InitSiChip port: %d.\n",pPort->stLineTestPara.pstResult->port);
2083 #endif
2084 InitSiliconChip(pPort); //added by fandi,because after the cap test, dsp can't receive 1 4 7 5 8.
2085 if(HOOKOFF == pPort->hook_state)//Õª»ú״̬£¬ÖØÐÂÉèÖÃʱ϶
2086 {
2087 si_timeslot_set(pPort, pPort->stLineTestPara.pstResult->port, pPort->stLineTestPara.pstResult->port);
2088 }
2089 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_FWD_ACTIVE);
2090 msleep(200); /* need more than 150ms to normal feed state */
2091 SiSendResultCap(pPort, &pPort->stLineTestPara.pstMlt->Mlt); /* Ringers test per FCC Part 68 REN def.*/
2092 }
2093 break;
2094 case TI_LineRes:
2095 case TI_LineRes_reverse:
2096 /* Call test function - will return 1 when complete */
2097 done = ProSLIC_mlt_resistive_faults(&pPort->stLineTestPara.pstMlt->Mlt,&pPort->stLineTestPara.pstMlt->rMeas);
2098 if(1 == done)
2099 {
2100 pPort->stLineTestPara.test_flg = TEST_STOPING;
2101 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_FWD_ACTIVE);
2102 msleep(200); /* need more than 150ms to normal feed state */
2103 SiSendResultRes(pPort, &pPort->stLineTestPara.pstMlt->Mlt);
2104 }
2105 break;
2106
2107 case TI_LoopCircuitAndRes:
2108 case TI_InLoopCurrent:
2109
2110 break;
2111 case TI_BatteryVolt:
2112
2113 break;
2114 case TI_RingVolt:
2115 USLPUT1("%s: %d .\n", __FUNCTION__, __LINE__);
2116 RingVol[RingCnt%MAX_RING_CNT] = ctrl_ReadRAMWrapper(pPort->ProObj->deviceId->ctrlInterface->hCtrl,pPort->ProObj->channel,SI3217X_COM_RAM_MADC_VBAT);
2117 RingCnt++;
2118 if( RingCnt > (MAX_RING_CNT - 1))
2119 {
2120 RingCnt = 0;
2121 pPort->stLineTestPara.test_flg = TEST_STOPING;
2122 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_FWD_ACTIVE);
2123 SiSendResultRingtouser(pPort);
2124 }
2125 break;
2126 case TI_Hook:
2127
2128 break;
2129 case TI_REN:
2130 done = ProSLIC_mlt_ren(&pPort->stLineTestPara.pstMlt->Mlt, &pPort->stLineTestPara.pstMlt->RenState);
2131 if( 1 == done )
2132 {
2133 pPort->stLineTestPara.test_flg = TEST_STOPING;
2134 ProSLIC_SetLinefeedStatus(pPort->ProObj, LF_FWD_ACTIVE);
2135 SiRen(pPort, &pPort->stLineTestPara.pstMlt->Mlt);
2136 }
2137 break;
2138/* case POWER_SUP_VOLT:
2139
2140 break;*/
2141 case TI_Outside12:
2142
2143 break;
2144 case TI_LineConnect:
2145
2146 break;
2147 default:
2148 return ;
2149 }
2150}
2151
2152void SiSendResultVol(Port_t *pPort, ProSLICMLTType *pMlt)
2153{
2154 USLPUT2("V_TR:DC %d, AC %d\n",pMlt->hazVDC.measTR , (pMlt->hazVAC.measTR) / 10);
2155 USLPUT2("V_TG:DC %d, AC %d\n",pMlt->hazVDC.measTG , (pMlt->hazVAC.measTG) / 10);
2156 USLPUT2("V_RG:DC %d, AC %d\n",pMlt->hazVDC.measRG , (pMlt->hazVAC.measRG) / 10);
2157 pPort->stLineTestPara.pstResult->vac_tr = pMlt->hazVAC.measTR;
2158 pPort->stLineTestPara.pstResult->vac_tg = pMlt->hazVAC.measTG;
2159 pPort->stLineTestPara.pstResult->vac_rg = pMlt->hazVAC.measRG;
2160 pPort->stLineTestPara.pstResult->vdc_tr = pMlt->hazVDC.measTR;
2161 pPort->stLineTestPara.pstResult->vdc_tg = pMlt->hazVDC.measTG;
2162 pPort->stLineTestPara.pstResult->vdc_rg = pMlt->hazVDC.measRG;
2163
2164 if(TI_Outside12 == pPort->stLineTestPara.pstResult->item)
2165 {
2166 StartSiLineTest(pPort, TI_LineCap);
2167 }
2168 else
2169 {
2170 usrline_report(pPort->stLineTestPara.pstResult->port,EV_FXS_TEST_DONE,0, 0);
2171 }
2172}
2173
2174void SiSendResultCap(Port_t *pPort, ProSLICMLTType *pMlt)
2175{
2176 USLPUT2 ("RG Capacitance = %d.%d nF ***\n",pMlt->capFaults.measRG/10,pMlt->capFaults.measRG%10);
2177 USLPUT2 ("TG Capacitance = %d.%d nF ***\n",pMlt->capFaults.measTG/10,pMlt->capFaults.measTG%10);
2178 USLPUT2 ("TR Capacitance = %d.%d nF ***\n",pMlt->capFaults.measTR/10,pMlt->capFaults.measTR%10);
2179 pPort->stLineTestPara.pstResult->cap_tr = pMlt->capFaults.measTR/10;
2180 pPort->stLineTestPara.pstResult->cap_tg = pMlt->capFaults.measTG/10;
2181 pPort->stLineTestPara.pstResult->cap_rg = pMlt->capFaults.measRG/10;
2182
2183 if(TI_Outside12 == pPort->stLineTestPara.pstResult->item)
2184 {
2185 StartSiLineTest(pPort, TI_LineRes);
2186 }
2187 else
2188 {
2189 usrline_report(pPort->stLineTestPara.pstResult->port, EV_FXS_TEST_DONE,0, 0);
2190 }
2191}
2192
2193void SiSendResultRes(Port_t *pPort, ProSLICMLTType *pMlt)
2194{
2195 signed long temp;
2196
2197 temp = pMlt->resFaults.measTR;
2198 USLPUT2("tr = %ld.%ld Ohm\n",temp/10, temp % 10);
2199 temp = pMlt->resFaults.measRG;
2200 USLPUT2("rg = %ld.%ld Ohm\n",temp/10, temp % 10);
2201 temp = pMlt->resFaults.measTG;
2202 USLPUT2("tg = %ld.%ld Ohm\n",temp/10, temp % 10);
2203 pPort->stLineTestPara.pstResult->res_tr = pMlt->resFaults.measTR/10;
2204 pPort->stLineTestPara.pstResult->res_tg = pMlt->resFaults.measTG/10;
2205 pPort->stLineTestPara.pstResult->res_rg = pMlt->resFaults.measRG/10;
2206
2207 usrline_report(pPort->stLineTestPara.pstResult->port, EV_FXS_TEST_DONE, 0, 0);
2208}
2209
2210void SiSendResultDCFeedSt( Port_t *pPort )
2211{
2212 signed long data = 0, temp = 0;
2213 long long vtr = 0, iloop = 0;
2214
2215 temp = ctrl_ReadRAMWrapper(pPort->ProObj->deviceId->ctrlInterface->hCtrl,pPort->ProObj->channel,SI3217X_COM_RAM_MADC_ILOOP);
2216 USLPUT2(" battary %ld.\n", temp);
2217 data = ChangeData(temp);
2218
2219 iloop = data;
2220 iloop = iloop * 1676;
2221 USLPUT2(" iloop %lld \n", iloop);
2222 data = lldivde( iloop, 1000000000); /* mA */
2223 USLPUT2(" iloop %ld \n", data);
2224 pPort->stLineTestPara.pstResult->loop_curent = data;
2225
2226 temp = ctrl_ReadRAMWrapper(pPort->ProObj->deviceId->ctrlInterface->hCtrl,pPort->ProObj->channel,SI3217X_COM_RAM_VDIFF_SENSE);
2227 data = ChangeData(temp);
2228
2229 vtr = data;
2230 vtr = vtr * 931323;
2231 USLPUT2(" Vol %lld \n", vtr);
2232 data = lldivde( vtr, 1000000000 ); /* mV */
2233 USLPUT2(" Vol %ld \n", data);
2234
2235 if( 0 != pPort->stLineTestPara.pstResult->loop_curent )
2236 {
2237 pPort->stLineTestPara.pstResult->loop_res = longfabs(data/pPort->stLineTestPara.pstResult->loop_curent);
2238 }
2239 else
2240 {
2241 pPort->stLineTestPara.pstResult->loop_res = 100000000;/* consider the res as 100M ohm */
2242 }
2243
2244 if(TI_InLoopCurrent == pPort->stLineTestPara.si_item)
2245 {
2246 pPort->stLineTestPara.pstResult->loop_res = 0;
2247 }
2248
2249 usrline_report(pPort->stLineTestPara.pstResult->port,EV_FXS_TEST_DONE,0,0);
2250}
2251
2252void SiSendResultBatteryVol(Port_t *pPort)
2253{
2254 signed long data = 0, temp = 0;
2255 long long vtr = 0;
2256
2257 temp = ctrl_ReadRAMWrapper(pPort->ProObj->deviceId->ctrlInterface->hCtrl,pPort->ProObj->channel,SI3217X_COM_RAM_MADC_VBAT);
2258 USLPUT2(" battary %ld.%d\n", temp, sizeof(temp));
2259 data = ChangeData(temp);
2260 USLPUT2(" battary %ld.\n", data);
2261 vtr = data;
2262 vtr = vtr * 931323;
2263 USLPUT2(" vtr %lld.\n", vtr);
2264 data = lldivde( vtr, 1000000000 ); /* mV */
2265
2266 pPort->stLineTestPara.pstResult->battary = data;
2267 USLPUT2(" battary %ld.\n", data);
2268 usrline_report(pPort->stLineTestPara.pstResult->port, EV_FXS_TEST_DONE,0,0);
2269}
2270
2271void SiSendResultHook( Port_t *pPort )
2272{
2273 if( pPort->hook_state == HOOKOFF )
2274 {
2275 pPort->stLineTestPara.pstResult->user_flg = 1;
2276 }
2277 else
2278 {
2279 pPort->stLineTestPara.pstResult->user_flg = 0;
2280 }
2281
2282 usrline_report(pPort->stLineTestPara.pstResult->port,EV_FXS_TEST_DONE,0,0);
2283}
2284
2285void SiSendResultRingtouser( Port_t *pPort )
2286{
2287 long data = 0, vtr = 0;
2288 long long temp = 0, vtr2 = 0;
2289 u8 i = 0;
2290
2291 for( i = 0; i < MAX_RING_CNT; i++ )
2292 {
2293 data = ChangeData(RingVol[i]);
2294 temp = data;
2295 temp = temp * 931323;
2296 USLPUT2("Ring[%d] = %ld, tem %lld\n", i, data, temp);
2297
2298 data = lldivde( temp, 1000000000 );
2299 USLPUT2("Ring[%d] = %ld\n", i, data);
2300 vtr += data;
2301 vtr2 += data;
2302 }
2303 USLPUT2("vtr = %ld, vtr2 = %lld\n", vtr, vtr2);
2304 vtr = vtr * 1000 / MAX_RING_CNT/ 1414;
2305
2306 pPort->stLineTestPara.pstResult->ring_vol = vtr;
2307 USLPUT2(" vol %ld.\n", vtr);
2308 usrline_report(pPort->stLineTestPara.pstResult->port,EV_FXS_TEST_DONE,0,0);
2309}
2310
2311void SiRen( Port_t *pPort, ProSLICMLTType *pMlt )
2312{
2313 USLPUT2(" REN %d.\n", pMlt->ren.renValue);
2314 pPort->stLineTestPara.pstResult->ren = pMlt->ren.renValue;
2315 if(TI_LineConnect == pPort->stLineTestPara.pstResult->item)
2316 {
2317 pPort->stLineTestPara.pstResult->user_flg = pPort->hook_state;
2318 USLPUT2(" user_flg %d.\n", pPort->stLineTestPara.pstResult->user_flg);
2319 }
2320
2321 usrline_report(pPort->stLineTestPara.pstResult->port,EV_FXS_TEST_DONE,0,0);
2322}
2323
2324
2325long ChangeData(unsigned long n)
2326{
2327 long t = 0;
2328 unsigned long m = 0;
2329
2330 if( 0x1 & n>>28 )
2331 {
2332 m = (~n & 0x1fffffff) + 1;
2333 t = -m;
2334 }
2335 else
2336 {
2337 t = n;
2338 }
2339
2340 return t;
2341}
2342
2343
2344long lldivde(long long x, long y)
2345{
2346 int s = 1;
2347 long n = 0;
2348 long long m = 0;
2349
2350 m = x;
2351
2352 if( m < 0 )
2353 {
2354 s = -1;
2355 m = -m;
2356 }
2357
2358 while(1)
2359 {
2360 m = m - y ;
2361 if( m < 0 ) break;
2362 n++;
2363 }
2364
2365 return n*s ;
2366}
2367
2368long longfabs( long x )
2369{
2370 if( x < 0 ) return -x;
2371
2372 return x;
2373}