blob: b45eb5cde1a6445a1b6bde7997bd0b3cd8c378ca [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*******************************************************************************
2* SUBSYSTEM£º User Line Driver
3* MOUDLE: USL
4* FILE NAME: usr_line.c
5* PURPOSE: To scan and control the user line(slic/daa).
6* Author: jiang.yuelong
7* Version£º 1.0
8* Date£º 24/12/2004
9*------------------------------------------------------------------------------
10* DEVELOPMENT HISTORY
11* Date Version Modifier Description of Mpdify
12* mm/dd/yyyy x.x X XX xxxxxxxxxxxxx
13*******************************************************************************/
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/sched.h>
17#include <linux/wait.h>
18#include <linux/init.h>
19#include <linux/list.h>
20#include <linux/slab.h>
21#include <linux/signal.h>
22//#include <linux/smp_lock.h>
23#include <linux/fs.h>
24#include <asm/uaccess.h>
25#include <linux/delay.h>
26#include <linux/version.h>
27#include <linux/interrupt.h>
28#include <linux/gpio.h>
29#include <mach/gpio.h>
30#include <linux/irqreturn.h>
31#include <mach/pcu.h>
32#include <linux/irq.h>
33#include <linux/platform_device.h>
34#include <linux/device.h>
35#include <linux/wakelock.h>
36#include <linux/soc/zte/pm/drv_idle.h>
37
38#include "usr_line.h"
39#include "si3217x_constants.h"
40//#include <linux/soc/zte/rpm/rpmsg.h>
41#include <mach/gpio_cfg.h>
42
43#include "i2s.h"
44
45/* ---- Public Variables ------------------------------------------------- */
46USL_PORT *pstUslPort = NULL; /* global USL_PORT pointer */
47u8 si_usl_debuglvl = 3; /* control whether to print message to serial port, init to enable printk */
48int dtmf_mute = 0;
49int slic_pcm_open = 0;
50struct spi_device *pslicSpi;
51static struct class *slic_dev_class;
52static struct device *slic_device;
53static int fskbuf_avail_flag = 0;
54/* ---- Private Variables ------------------------------------------------ */
55static u8 *pIoctlData = NULL; /* global pointer for ioctl parameters */
56
57static USL_MSG *msg_queue;
58static DECLARE_WAIT_QUEUE_HEAD(msg_wait_queue); /* for message report */
59
60static u8 timer_run = 1;
61static u8 scan_over = 0;
62static u8 self_test = 0;
63u8 slic_offhook = 0;
64
65u8 init_flg = 0;
66slic_state current_state = NONE;
67int irq_num = 0;
68
69#define MAX_INT_STRINGS 38
70#define FSK_DEPTH_TRIG 4
71#define SLIC_INT_GPIO ZX29_GPIO_53
72#define FNC_SLIC_INT_GPIO GPIO53_EXT_INT6
73#define SLIC_RST_GPIO ZX29_GPIO_122
74#define FNC_SLIC_RST_GPIO GPIO122_GPIO122
75static struct wake_lock slic_wakelock;
76
77static char *intMapStrings[] =
78{
79 "IRQ_OSC1_T1",
80 "IRQ_OSC1_T2",
81 "IRQ_OSC2_T1",
82 "IRQ_OSC2_T2",
83 "IRQ_RING_T1",
84 "IRQ_RING_T2",
85 "IRQ_PM_T1",
86 "IRQ_PM_T2",
87 "IRQ_FSKBUF_AVAIL", /**< FSK FIFO depth reached */
88 "IRQ_VBAT",
89 "IRQ_RING_TRIP", /**< Ring Trip detected */
90 "IRQ_LOOP_STATUS", /**< Loop Current changed */
91 "IRQ_LONG_STAT",
92 "IRQ_VOC_TRACK",
93 "IRQ_DTMF", /**< DTMF Detected - call @ref ProSLIC_DTMFReadDigit to decode the value */
94 "IRQ_INDIRECT", /**< Indirect/RAM access completed */
95 "IRQ_TXMDM",
96 "IRQ_RXMDM",
97 "IRQ_PQ1", /**< Power alarm 1 */
98 "IRQ_PQ2", /**< Power alarm 2 */
99 "IRQ_PQ3", /**< Power alarm 3 */
100 "IRQ_PQ4", /**< Power alarm 4 */
101 "IRQ_PQ5", /**< Power alarm 5 */
102 "IRQ_PQ6", /**< Power alarm 6 */
103 "IRQ_RING_FAIL",
104 "IRQ_CM_BAL",
105 "IRQ_USER_0",
106 "IRQ_USER_1",
107 "IRQ_USER_2",
108 "IRQ_USER_3",
109 "IRQ_USER_4",
110 "IRQ_USER_5",
111 "IRQ_USER_6",
112 "IRQ_USER_7",
113 "IRQ_DSP",
114 "IRQ_MADC_FS",
115 "IRQ_P_HVIC",
116 "IRQ_P_THERM", /**< Thermal alarm */
117 "IRQ_P_OFFLD"
118};
119
120
121/*--------extern variables---------------------------------------------*/
122
123
124/* ---- Public functions ------------------------------------------------- */
125
126
127/* ---- Private functions ------------------------------------------------ */
128static s8 SlicMallocMemory(void); /* */
129static void SlicFreeMemory(void); /* */
130static void zx29_i2s_tdm_pin_cfg(void);
131
132//volatile static T_ZDrvRpMsg_Msg icp_pMsg;
133volatile static int rpMsgBuf[8] = {1,2};
134
135
136/*--------extern functions---------------------------------------------*/
137
138
139
140
141
142/*---------------------func define--------------------------------*/
143
144/*
145*****************************************************************************
146** FUNCTION: SlicMallocMemory
147**
148** PURPOSE: request memory for global variables pstUslPort and pIoctlData,
149** used in si_usrline_init only
150**
151** PARAMETERS: none
152**
153** RETURNS: 0 on success, else -1
154**
155*****************************************************************************
156*/
157static s8 SlicMallocMemory(void)
158{
159 /* USL_PORT used */
160 pstUslPort = (USL_PORT *)kmalloc(sizeof(USL_PORT)*MAX_PORT_NUM, GFP_KERNEL);
161
162 if (NULL != pstUslPort)
163 {
164 memset(pstUslPort, 0, sizeof(USL_PORT)*MAX_PORT_NUM);
165 }
166 else
167 {
168 return -1;
169 }
170
171 /* ioctl used */
172 pIoctlData = (u8 *)kmalloc(512, GFP_KERNEL);
173
174 if (NULL != pIoctlData)
175 {
176 memset(pIoctlData, 0, 512);
177 }
178 else
179 {
180 kfree(pstUslPort);
181 return -1;
182 }
183
184 return 0;
185}
186
187/*
188*****************************************************************************
189** FUNCTION: SlicFreeMemory
190**
191** PURPOSE: free memory requested by SlicMallocMemory
192**
193** PARAMETERS: none
194**
195** RETURNS: none
196**
197*****************************************************************************
198*/
199static void SlicFreeMemory(void)
200{
201 if (NULL != pstUslPort)
202 {
203 kfree(pstUslPort);
204 }
205 pstUslPort = NULL;
206
207 if (NULL != pIoctlData)
208 {
209 kfree(pIoctlData);
210 }
211 pIoctlData = NULL;
212
213 if (NULL != msg_queue )
214 {
215 kfree(msg_queue);
216 }
217 msg_queue = NULL ;
218
219 return;
220}
221
222void CreatMsgQueue(void)
223{
224 msg_queue = kzalloc(sizeof(USL_MSG),GFP_KERNEL);
225}
226
227bool QueueEmpty(void)
228{
229 return msg_queue->tail == msg_queue->head;
230}
231
232bool QueueFull(void)
233{
234 return (msg_queue->tail + 1)%MSGMAX == msg_queue->head;
235}
236
237s8 usrline_report(const u16 port, const u8 event, const u32 payload,u16 mask)
238{
239 USLPUT1("->%s: port %d, ev %d, pay %d, mask %x.\n", __FUNCTION__, port, event, payload, mask );
240 if( GET_EV_MASK(event) & mask ) {
241 USLPUT1("ev %x, ~mask%x\n", GET_EV_MASK(event), mask );
242 return 0;
243 }
244 if (QueueFull())
245 {
246 USLPUT0(" usrline_report msgqueue full!!( event=%d,port=%d,payload=%d). \n", event, port, payload);
247 return -1;
248 }
249 /* add to queue tail */
250 //msg_queue->data[msg_queue->tail].port = port;
251 msg_queue->data[msg_queue->tail].msgid = event;
252 msg_queue->data[msg_queue->tail].payload = payload;
253 msg_queue->tail = (msg_queue->tail + 1)%MSGMAX;
254 /* wake up messages wait queue*/
255 wake_up_interruptible(&msg_wait_queue);
256 USLPUT1("\nevent:%d port:%d payload:0x%x\n", event, port, payload);
257
258 return 0;
259}
260
261static s8 usrline_ioctl_msg_rev(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
262{
263 printk("howard usrline_ioctl_msg_rev\n");
264 if (NULL == pstCmd)
265 {
266 USLPUT0("%s pstCmd NULL\n",__FUNCTION__);
267 return SLC_FAIL;
268 }
269
270 if (QueueEmpty()) /* no message. sleep */
271 {
272 interruptible_sleep_on(&msg_wait_queue);
273 }
274
275 while (self_test)
276 {
277 sleep_on_timeout(&msg_wait_queue, 10);
278 }
279
280 if (copy_to_user(pstCmd->data, &msg_queue->data[msg_queue->head], sizeof(MSG_DATA)) != 0)
281 {
282 USLPUT0("%s copy data to user fail!\n",__FUNCTION__);
283 }
284 msg_queue->head = (msg_queue->head + 1)%MSGMAX;
285
286 return SLC_SUCCESS;
287}
288
289
290static s8 usrline_ioctl_msg_clear(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
291{
292 if (NULL != msg_queue)
293 {
294 memset(msg_queue,0,sizeof(USL_MSG));
295 }
296
297 return SLC_SUCCESS;
298}
299
300s8 usrline_port_register( const u16 port, const u8 type,
301 CODEC_OPS *ops, Port_t *pchip)
302{
303
304 USL_PORT *ptr;
305
306 if (NULL == pstUslPort)
307 {
308 USLPUT0("usrline_port_register pstUslPort NULL!\n");
309 return -1;
310 }
311
312 if (port >= MAX_PORT_NUM)
313 {
314 USLPUT0("usrline_port_register port %d illegal\n", port);
315 return -1;
316 }
317
318 if ((NULL == ops) || (NULL == pchip))
319 {
320 USLPUT0("usrline_port_register input pointer NULL!\n");
321 return -1;
322 }
323
324 ptr = (USL_PORT *)&pstUslPort[port];
325
326 if (NULL == ptr)
327 {
328 USLPUT0("usrline_port_register get port Para NULL!\n");
329 return -1;
330 }
331
332 ptr->port = port;
333 ptr->port_type = type;
334 ptr->codec_ops = ops;
335
336 ptr->pLine = pchip;
337 ptr->event_mask = 0;
338 ptr->signal_flag = SIGNAL_PLAY_STOP;
339 ptr->signal_on = RING_SIGNAL_OFF;
340
341 /*added for ring queue*/
342 ptr->stRingQuenePara.dwRingStop = 0;
343 ptr->stRingQuenePara.dwNeedSort = 0;
344 ptr->stRingQuenePara.dwOffCountStart = 0;
345 ptr->stRingQuenePara.dwOffCount = 0;
346 ptr->stRingQuenePara.dwOffMaxCount = 0;
347 ptr->stRingQuenePara.RingQueneDelay = 10;
348
349 ptr->dwIsRevPol = 0;
350
351 ptr->dwInitOK = LINE_INITOK;
352 ptr->flag = LINE_ENABLE;
353
354 return 0;
355}
356
357static void uslput_sig(const SIGNAL_DATA *sig)
358{
359 USLPUT3("signal_type:%d cid:%s tone_type:%d\n",
360 sig->signal_type,sig->cid,sig->tone_type);
361}
362
363/* ================================================================== */
364static s8 usrline_ioctl_Inf_precfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
365{
366 if (NULL == pstCmd)
367 {
368 USLPUT0("%s pstCmd NULL\n",__FUNCTION__);
369 return -1;
370 }
371
372 if (copy_from_user(pIoctlData, pstCmd->data, pstCmd->data_size) != 0)
373 {
374 USLPUT0("%s copy data from user fail!\n",__FUNCTION__);
375 return -1;
376 }
377
378 slic_inf_precfg((SLCINF_CFG *)pIoctlData);
379
380 return 0;
381}
382
383static unsigned char checkBufSum(char *str, int nLen)
384{
385 int i=0;
386 uInt8 sum = 0;
387 for(i=0; i<nLen; i++)
388 {
389 sum += str[i];
390 LOGPRINT ("\nsum=%02X", sum);
391 }
392
393 return -sum;
394}
395
396static int WaitOnFSKBuffer (proslicChanType *pProslic){
397 uInt8 avail;
398 uInt32 i=0;
399 uInt8 hook_status = 0;
400 ProSLIC_ReadHookStatus(pProslic,&hook_status);
401 if(hook_status == PROSLIC_OFFHOOK)
402 {
403 ProSLIC_DisableCID(pProslic);
404 return -1;
405 }
406 do {
407 if (fskbuf_avail_flag == 1)
408 break;
409 ProSLIC_CheckCIDBuffer(pProslic,&avail);
410 i++;
411 }
412 while ((avail == 0)&& (i<20000));
413 fskbuf_avail_flag = 0;
414 if(i>=20000)
415 {
416 printk("\nWaitOnFSKBuffer Time = %d", i);
417 }
418 //return 0;
419}
420
421static int DoOnHookCallerIDEx (proslicChanType *pProslic, int8 *BufTel, int8 *BufTxt)
422{ //SI324X/26 example code--------
423 char sTime[] = "01020304";
424 unsigned char preamble[] ={'U','U','U','U','U','U','U','U'};
425 int i;uInt8 data;
426 int j;
427 unsigned char TxBuf[256];
428 unsigned char *pTxBuf=TxBuf;
429 int nTxLen;
430 int nNumLen = strlen(BufTel);
431 int nTxtLen = strlen(BufTxt);
432 uInt8 hook_status = 0;
433 // Êý¾Ý×é°ü
434 *pTxBuf++ = 0x80; //msg type: ¸´ºÏÊý¾Ý¸ñʽ
435 if(1)
436 {
437 if(nNumLen==0)
438 {
439 *pTxBuf++ = (2+8)+(2+nTxtLen); //msg length
440 }
441 else if(nTxtLen==0)
442 {
443 *pTxBuf++ = (2+8)+(2+nNumLen); //msg length
444 }
445 else
446 {
447 *pTxBuf++ = (2+8)+(2+nNumLen)+(2+nTxtLen); //msg length
448 }
449 *pTxBuf++ = 0x01;//²ÎÊýÀàÐÍ £ºÈÕÆÚʱ¼ä
450 *pTxBuf++ = 0x08;//ʱ¼ä³¤¶È
451 for(i=0; i<8; i++)
452 {
453 *pTxBuf++ = sTime[i];
454 }
455 }
456 else
457 {
458 //MSG_FATAL("-zja--Don't SENDING current_time",0,0,0);
459 *pTxBuf++ = (2+nNumLen)+(2+nTxtLen); //msg length
460 }
461 if(nNumLen!=0)
462 {
463 *pTxBuf++ =0x02; //²ÎÊýÀàÐÍ £ºµç»°ºÅÂë
464 *pTxBuf++ =nNumLen; //²ÎÊý³¤¶È
465 memcpy(pTxBuf, BufTel, nNumLen);
466 pTxBuf += nNumLen;
467 }
468 if(nTxtLen!=0)
469 {
470 *pTxBuf++=0x07; //²ÎÊýÀàÐÍ £ºÖ÷½ÐÐÅÏ¢
471 *pTxBuf++=nTxtLen; //²ÎÊýÀàÐÍ £ºµç»°ºÅÂë
472 memcpy(pTxBuf, BufTxt, nTxtLen);
473 pTxBuf += nTxtLen;
474 }
475 *pTxBuf++=(checkBufSum(TxBuf, pTxBuf-TxBuf));
476 nTxLen = pTxBuf-TxBuf;
477 printk("\n Len=%d", nTxLen);
478 for(i=0; i<nTxLen; i++)
479 {
480 if((i&0x0F)==0)
481 printk("\n");
482 printk("0x%02X ", TxBuf[i]);
483 }
484 printk("\n");
485 /* The setting for FSKDEPTH will depend on your system contraints*/
486 //fire interrupt when FSK_DEPTH_TRIG bytes of space, set FSKDEPTH to 8-FSK_DEPTH_TRIG
487
488 ProSLIC_ReadHookStatus(pProslic,&hook_status);
489 if(hook_status == PROSLIC_OFFHOOK)
490 {
491 return -1;
492 }
493
494 ProSLIC_FSKSetup (pProslic, 1);
495
496 if (pProslic->debugMode)
497 LOGPRINT ("\nSending CID to channel %d\n",pProslic->channel);
498 (pProslic->deviceId->ctrlInterface)->Delay_fptr((pProslic->deviceId->ctrlInterface)->hTimer,50);
499// (pProslic->deviceId->ctrlInterface)->Delay_fptr((pProslic->deviceId->ctrlInterface)->hTimer,130); //130ms of mark bits
500
501 ProSLIC_EnableCID(pProslic);
502
503
504 for (i=0;i<30;i+=FSK_DEPTH_TRIG)
505 {
506 /*if (WaitOnFSKBuffer (pProslic))
507 {
508 //printk("howard offhook during ONHOOK FSK CID\n");
509 return -1;
510 }*/
511 if(i>=4)
512 {
513 WaitOnFSKBuffer (pProslic);
514 }
515 ProSLIC_SendCID(pProslic,preamble,FSK_DEPTH_TRIG);
516 }
517
518 if (30%FSK_DEPTH_TRIG)
519 {
520 /*if (WaitOnFSKBuffer (pProslic))
521 {
522 //printk("howard offhook during ONHOOK FSK CID\n");
523 return -1;
524 }*/
525 WaitOnFSKBuffer (pProslic);
526 }
527
528 ProSLIC_SendCID(pProslic,preamble,30%FSK_DEPTH_TRIG);
529 WaitOnFSKBuffer (pProslic);
530 /*if (WaitOnFSKBuffer (pProslic))
531 {
532 //printk("howard offhook during ONHOOK FSK CID\n");
533 return -1;
534 }*/
535 (pProslic->deviceId->ctrlInterface)->Delay_fptr((pProslic->deviceId->ctrlInterface)->hTimer,140); //wait for 1 byte then 130ms +/- 25ms mark bits
536
537 for (i=0;i<nTxLen; i+=FSK_DEPTH_TRIG){
538 /*if (WaitOnFSKBuffer (pProslic))
539 {
540 //printk("howard offhook during ONHOOK FSK CID\n");
541 return -1;
542 }*/
543 ProSLIC_SendCID (pProslic,&(TxBuf[i]),FSK_DEPTH_TRIG);
544 WaitOnFSKBuffer (pProslic);
545
546 }
547 if (nTxLen%FSK_DEPTH_TRIG)
548 {
549 /*if (WaitOnFSKBuffer (pProslic))
550 {
551 //printk("howard offhook during ONHOOK FSK CID\n");
552 return -1;
553 }*/
554 ProSLIC_SendCID (pProslic,&(TxBuf[(nTxLen/FSK_DEPTH_TRIG)*FSK_DEPTH_TRIG]),nTxLen%FSK_DEPTH_TRIG);
555 WaitOnFSKBuffer (pProslic);
556 }
557
558
559 (pProslic->deviceId->ctrlInterface)->Delay_fptr((pProslic->deviceId->ctrlInterface)->hTimer,10*(FSK_DEPTH_TRIG));
560 (pProslic->deviceId->ctrlInterface)->Delay_fptr((pProslic->deviceId->ctrlInterface)->hTimer,50); //130ms of mark bits
561
562 ProSLIC_DisableCID(pProslic);
563}
564
565void ring_sendcid(proslicChanType_ptr hProslic, int8 *cid)
566{
567 /* Ensure OFFHOOK Active */
568 ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
569 msleep(500);
570 /* 1st Ring Burst */
571 ProSLIC_SetLinefeedStatus(hProslic,LF_RINGING);
572 msleep(2500);/* Delay 250 to 3600ms */
573
574 printk("ring_sendcid %s\n", cid);
575 DoOnHookCallerIDEx(hProslic, cid, "");
576 //DoOnHookCallerIDEx(hProslic, "15029909468", "");
577}
578
579static s8 usrline_ioctl_signal_start(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
580{
581 s8 i = 0;
582 USL_PORT *pPort = NULL;
583 SIGNAL_DATA *sig = NULL;
584 int use_cid=1;
585 int cid_len = 0;
586 //CANDENCE_ATTR *cadc = NULL;
587 printk("howard usrline_ioctl_signal_start\n");
588 if ((NULL == data) || (NULL == pstCmd))
589 {
590 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
591 return -1;
592 }
593
594 USLPUT2("%s: port %d \n",__FUNCTION__, data->port );
595 pPort = (USL_PORT *)&pstUslPort[(data->port+1)%2];
596 sig = (SIGNAL_DATA *) &(data->sig_data);
597 //cadc = sig->cadence;
598 if (copy_from_user(sig, pstCmd->data, pstCmd->data_size) != 0)
599 {
600 USLPUT0("%s copy data from user fail!\n",__FUNCTION__);
601 return -1;
602 }
603 uslput_sig(sig);
604 /* init signal data */
605 /*added for ring queue*/
606 //data->stRingQuenePara.dwOffMaxCount = cadc->cadence_off - cadc->cadence_on - data->stRingQuenePara.RingQueneDelay;
607
608 if (USL_RING_SIGNAL == sig->signal_type)
609 {
610 printk("ring singnal\n");
611 data->stRingQuenePara.dwRingStop = 0;
612 if((NULL == pPort) /* no other port */
613 || (USL_TONE_SIGNAL == pPort->sig_data.signal_type) /* other port is playing tone */
614 || ((USL_RING_SIGNAL == pPort->sig_data.signal_type) && (SIGNAL_PLAY_STOP == pPort->signal_flag))) /* other port is ringing in off state */
615 //|| (cadc->cadence_off < cadc->cadence_on + data->stRingQuenePara.RingQueneDelay*2)) /* not match quene rule */
616 {
617 data->codec_ops->codec_signal_ctrl(data->pLine, sig, RING_SIGNAL_INIT);
618 data->signal_flag = SIGNAL_PLAY_START;
619
620 }
621 else /* need quene to ring */
622 {
623 //USLPUT2("stRingQuenePara.dwOffMaxCount = %d\n", data->stRingQuenePara.dwOffMaxCount);
624 data->stRingQuenePara.dwNeedSort = 1;
625 }
626 printk("howard ring and send cid in ioctl\n");
627 //sendCIDStream(data->pLine->ProObj);
628
629 cid_len = strlen(sig->cid);
630 printk("cid_len %d\n", cid_len);
631 for (i=0; i < cid_len; i++)
632 {
633 if((sig->cid[i]<0x30) || (sig->cid[i]>0x39))
634 {
635 use_cid = 0;
636 break;
637 }
638 }
639 if((use_cid == 1) && (cid_len > 0))
640 ring_sendcid(data->pLine->ProObj, sig->cid);
641 else
642 ProSLIC_RingStart(data->pLine->ProObj);
643
644 current_state = RINGING;
645 } else {
646 printk("tone singnal\n");
647 data->codec_ops->codec_signal_ctrl(data->pLine, sig, TONE_SIGNAL_INIT);
648 data->signal_flag = SIGNAL_PLAY_START;
649 data->stRingQuenePara.dwRingStop = 0;
650 }
651 /*ring queue add*/
652
653
654 return 0;
655 }
656
657/*added for ring queue*/
658static s8 usrline_signal_start(USL_PORT *data)
659{
660 SIGNAL_DATA *sig = NULL;
661
662 if (NULL == data)
663 {
664 USLPUT0("%s data NULL\n",__FUNCTION__);
665 return -1;
666 }
667
668 sig = (SIGNAL_DATA *) &(data->sig_data);
669 USLPUT2("%s: port %d \n",__FUNCTION__, data->port );
670 data->codec_ops->codec_signal_ctrl(data->pLine, sig, RING_SIGNAL_INIT);
671 data->signal_flag = SIGNAL_PLAY_START;
672 data->stRingQuenePara.dwNeedSort = 0;
673 data->stRingQuenePara.dwOffCount = 0;
674 data->stRingQuenePara.dwOffCountStart = 0;
675
676 return 0;
677}
678/*ring queue add*/
679
680/*added for ring queue*/
681static s8 usrline_ioctl_signal_stop(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
682{
683 printk("howard usrline_ioctl_signal_stop\n");
684
685 if (NULL == data)
686 {
687 USLPUT0("%s data NULL\n",__FUNCTION__);
688 return -1;
689 }
690 USLPUT2("%s: port %d, signal type %d\n",__FUNCTION__, data->port, data->sig_data.signal_type);
691
692 if ((data->signal_flag == SIGNAL_PLAY_START)||(1==data->stRingQuenePara.dwNeedSort)) /* stop signal */
693 {
694 data->stRingQuenePara.dwNeedSort = 0;
695 data->stRingQuenePara.dwRingStop = 1;
696 }
697
698 return 0;
699}
700
701/*added for ring queue*/
702static s8 usrline_signal_stop(USL_PORT *data)
703{
704 u8 cmd = 0;
705 SIGNAL_DATA *sig = NULL;
706
707 if (NULL == data)
708 {
709 USLPUT0("%s data NULL\n",__FUNCTION__);
710 return -1;
711 }
712
713 sig = (SIGNAL_DATA *) &(data->sig_data);
714
715 data->signal_flag = SIGNAL_PLAY_STOP;
716
717 if (sig->signal_type == USL_RING_SIGNAL)
718 {
719 USLPUT0("ring singal stop\n");
720 data->signal_on = RING_SIGNAL_OFF;
721 cmd = RING_SIGNAL_CLEAN_OFF;
722 } else {
723 USLPUT0("tone singal stop\n");
724 cmd = TONE_SIGNAL_CLEAN;
725 }
726
727 data->codec_ops->codec_signal_ctrl(data->pLine, sig, cmd);
728 data->stRingQuenePara.dwRingStop = 0;
729 data->stRingQuenePara.dwNeedSort = 0;
730 data->stRingQuenePara.dwOffCountStart = 0;
731 data->stRingQuenePara.dwOffCount = 0;
732
733 return 0;
734}
735
736static s8 usrline_signal_play(USL_PORT *pdata)
737{
738 SIGNAL_DATA *data = (SIGNAL_DATA *) &(pdata->sig_data);
739 u16 port = pdata->port;
740 u16 signal_type = data->signal_type;
741 u32 delay;
742 u8 signal_clean, signal_on, signal_off;
743
744 //data->tick_count++;
745 if (signal_type == USL_RING_SIGNAL)
746 {
747 if (RINGING != current_state)
748 {
749 signal_on = RING_SIGNAL_ON;
750 signal_off = RING_SIGNAL_OFF;
751 signal_clean = RING_SIGNAL_CLEAN_ON;
752 pdata->codec_ops->codec_signal_ctrl(pdata->pLine, data, signal_on);
753 pdata->signal_on = signal_on;
754 }
755 } else {
756 if (PLAYING_TONE != current_state)
757 {
758 signal_on = TONE_SIGNAL_ON;
759 signal_off = TONE_SIGNAL_OFF;
760 signal_clean = TONE_SIGNAL_CLEAN;
761 pdata->codec_ops->codec_signal_ctrl(pdata->pLine, data, signal_on);
762 pdata->signal_on = signal_on;
763 }
764 }
765 return 0;
766}
767static s8 usrline_ioctl_pcm_open(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
768{
769 proslicChanType_ptr hProslic;
770 hProslic = data->pLine->ProObj;
771 printk("howard usrline_ioctl_pcm_open\n");
772 ProSLIC_PCMStart(hProslic);
773 slic_pcm_open = 1;
774 return 0;
775}
776static s8 usrline_ioctl_pcm_close(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
777{
778 proslicChanType_ptr hProslic;
779 hProslic = data->pLine->ProObj;
780 printk("howard usrline_ioctl_pcm_close\n");
781 ProSLIC_PCMStop(hProslic);
782 slic_pcm_open = 0;
783 return 0;
784}
785
786static s8 usrline_ioctl_pcm_set_nb(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
787{
788 proslicChanType_ptr hProslic;
789 hProslic = data->pLine->ProObj;
790 printk("howard usrline_ioctl_pcm_set nb\n");
791 ProSLIC_PCMSetup(hProslic, PCM_16LIN);
792 return 0;
793}
794
795
796static s8 usrline_ioctl_pcm_set_wb(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
797{
798 proslicChanType_ptr hProslic;
799 hProslic = data->pLine->ProObj;
800 printk("howard usrline_ioctl_pcm_set wb\n");
801 ProSLIC_PCMSetup(hProslic, PCM_16LIN_WB);
802 return 0;
803}
804
805
806
807
808static s8 usrline_ioctl_timeslot_set(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
809{
810 if ((NULL == data) || (NULL == pstCmd))
811 {
812 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
813 return -1;
814 }
815
816 //data->codec_ops->codec_timeslot_set(data->pLine, pstCmd->unPara.stTimeSlot.bTx, pstCmd->unPara.stTimeSlot.bRx);
817 return 0;
818}
819
820static s8 usrline_ioctl_timeslot_release(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
821{
822 if (NULL == data)
823 {
824 USLPUT0("%s data NULL\n",__FUNCTION__);
825 return -1;
826 }
827
828 USLPUT2("%s: port %d \n",__FUNCTION__, data->port );
829 data->codec_ops->codec_timeslot_release( data->pLine );
830
831 return 0;
832}
833
834static s8 usrline_ioctl_codec_config(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
835{
836 if ((NULL == data) || (NULL == pstCmd))
837 {
838 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
839 return -1;
840 }
841
842 if (copy_from_user(pIoctlData, pstCmd->data, pstCmd->data_size) != 0)
843 {
844 USLPUT0("%s copy data from user fail!\n",__FUNCTION__);
845 return -1;
846 }
847
848 data->codec_ops->codec_parm_cfg(data->pLine , pIoctlData, pstCmd->data_size);
849
850 return 0;
851}
852
853static s8 usrline_ioctl_codec_read(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
854{
855 if ((NULL == data) || (NULL == pstCmd))
856 {
857 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
858 return -1;
859 }
860
861 if (copy_from_user(pIoctlData, pstCmd->data, pstCmd->data_size) != 0)
862 {
863 USLPUT0("%s copy data from user fail!\n",__FUNCTION__);
864 return -1;
865 }
866
867 data->codec_ops->codec_parm_get(data->pLine, pIoctlData, pstCmd->data_size);
868 return 0;
869}
870
871static s8 usrline_ioctl_ram_config(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
872{
873 if ((NULL == data) || (NULL == pstCmd))
874 {
875 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
876 return -1;
877 }
878
879 if (copy_from_user(pIoctlData, pstCmd->data, pstCmd->data_size) != 0)
880 {
881 USLPUT0("%s copy data from user fail!\n",__FUNCTION__);
882 return -1;
883 }
884
885 data->codec_ops->codec_ram_cfg(data->pLine, pIoctlData, pstCmd->data_size);
886
887 return 0;
888}
889
890static s8 usrline_ioctl_mute(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
891{
892 proslicChanType_ptr hProslic;
893 hProslic = data->pLine->ProObj;
894 if ((NULL == data) || (NULL == pstCmd))
895 {
896 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
897 return -1;
898 }
899
900 if (copy_from_user(pIoctlData, pstCmd->data, pstCmd->data_size) != 0)
901 {
902 USLPUT0("%s copy data from user fail!\n",__FUNCTION__);
903 return -1;
904 }
905 printk("howard slic usrline_ioctl_mute %s\n", pIoctlData);
906 if(*pIoctlData == 't')
907 {
908 ProSLIC_SetMuteStatus(hProslic,PROSLIC_MUTE_TX);
909 printk("howard slic mute tx\n");
910 }
911 else if(*pIoctlData == 'r')
912 {
913 ProSLIC_SetMuteStatus(hProslic,PROSLIC_MUTE_RX);
914 printk("howard slic mute rx\n");
915 }
916 else if(*pIoctlData == 'n')
917 {
918 ProSLIC_SetMuteStatus(hProslic,PROSLIC_MUTE_NONE);
919 printk("howard slic mute none\n");
920 }
921
922 return 0;
923}
924
925static s8 usrline_ioctl_ram_read(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
926{
927 u16 addr = 0;
928
929 if ((NULL == data) || (NULL == pstCmd))
930 {
931 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
932 return -1;
933 }
934
935 if (copy_from_user(pIoctlData, pstCmd->data, pstCmd->data_size) != 0)
936 {
937 USLPUT0("%s copy data from user fail!\n",__FUNCTION__);
938 return -1;
939 }
940 addr = *(u16 *)pIoctlData;
941 printk("SLIC usrline_ioctl_ram_read addr %d,size %d\n", addr, pstCmd->data_size);
942 data->codec_ops->codec_ram_get(data->pLine, pIoctlData, pstCmd->data_size);
943
944 return 0;
945}
946extern void ctrl_ReadRegister(uInt8 cs, uInt8 channel, uInt8 regAddr, uInt8 *prdata);
947extern void ctrl_WriteRegister(uInt8 cs, uInt8 channel, uInt8 regAddr, uInt8 wdata);
948
949static s8 usrline_ioctl_dev_init(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
950{
951 int ret = 0;
952 printk("howard usrline_ioctl_dev_init\n");
953
954 if (0 == init_flg)
955 {
956 ret = InitSlicChip();
957 if (0 == ret)
958 {
959 init_flg = 1;
960 printk("SLIC init complete\n");
961 }
962 else
963 {
964 init_flg = 0;
965 printk("SLIC init NOT complete\n");
966 }
967 /* disable printk after init */
968 si_usl_debuglvl = 0;
969 }
970
971 return SLC_SUCCESS;
972}
973
974static s8 usrline_ioctl_port_reset(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
975{
976 if (NULL == data)
977 {
978 USLPUT0("%s data NULL\n",__FUNCTION__);
979 return -1;
980 }
981
982 USLPUT2("%s: port %d \n",__FUNCTION__, data->port );
983
984 usrline_ioctl_timeslot_release(data, pstCmd);
985
986 if ((data->signal_flag == SIGNAL_PLAY_START)||(1==data->stRingQuenePara.dwNeedSort)) /* stop signal */
987 {
988 //usrline_signal_stop(data);
989 data->stRingQuenePara.dwNeedSort = 0;
990 data->stRingQuenePara.dwRingStop = 1;
991 }
992 data->dwIsRevPol = 0;
993 data->flag = LINE_DISABLE;
994 data->codec_ops->codec_reset(data->pLine, data->port);
995 data->flag = LINE_ENABLE;
996 return SLC_SUCCESS;
997}
998
999/*added for slc time cfg*/
1000static s8 usrline_ioctl_time_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1001{
1002 if ((NULL == data) || (NULL == pstCmd))
1003 {
1004 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1005 return -1;
1006 }
1007
1008 if (copy_from_user(pIoctlData, pstCmd->data, pstCmd->data_size) != 0)
1009 {
1010 USLPUT0("%s copy data from user fail!\n",__FUNCTION__);
1011 return -1;
1012 }
1013
1014 /* first save the ring quene time */
1015 data->stRingQuenePara.RingQueneDelay = ((USL_CONFIG *)pIoctlData)->RingQueneDelay;
1016
1017 /* then save the chip related time parameters */
1018 data->codec_ops->codec_time_cfg(data->pLine, (USL_CONFIG *)pIoctlData);
1019
1020 return SLC_SUCCESS;
1021}
1022static s8 usrline_ioctl_slctool_hooklowlen_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1023{
1024 if ((NULL == data) || (NULL == pstCmd))
1025 {
1026 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1027 return -1;
1028 }
1029
1030 //data->codec_ops->codec_slctool_time_cfg(data->pLine, SLIC_CFG_HOOK_LOWLEN, pstCmd->unPara.wTime);
1031
1032 return 0;
1033}
1034
1035static s8 usrline_ioctl_slctool_hookhiglen_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1036{
1037 if ((NULL == data) || (NULL == pstCmd))
1038 {
1039 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1040 return -1;
1041 }
1042
1043 //data->codec_ops->codec_slctool_time_cfg(data->pLine, SLIC_CFG_HOOK_HIGLEN, pstCmd->unPara.wTime);
1044
1045 return 0;
1046}
1047static s8 usrline_ioctl_slctool_prehookhiglen_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1048{
1049 if ((NULL == data) || (NULL == pstCmd))
1050 {
1051 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1052 return -1;
1053 }
1054
1055 //data->codec_ops->codec_slctool_time_cfg(data->pLine, SLIC_CFG_PREHOOK_HIGLEN, pstCmd->unPara.wTime);
1056
1057 return 0;
1058}
1059static s8 usrline_ioctl_slctool_flashlowmin_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1060{
1061 if ((NULL == data) || (NULL == pstCmd))
1062 {
1063 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1064 return -1;
1065 }
1066
1067 //data->codec_ops->codec_slctool_time_cfg(data->pLine, SLIC_CFG_FLASH_LMIN, pstCmd->unPara.wTime);
1068
1069 return 0;
1070}
1071static s8 usrline_ioctl_slctool_flashlowmax_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1072{
1073 if ((NULL == data) || (NULL == pstCmd))
1074 {
1075 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1076 return -1;
1077 }
1078
1079 //data->codec_ops->codec_slctool_time_cfg(data->pLine, SLIC_CFG_FLASH_LMAX, pstCmd->unPara.wTime);
1080
1081 return 0;
1082}
1083
1084static s8 usrline_ioctl_slctool_flashhfix_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1085{
1086 if ((NULL == data) || (NULL == pstCmd))
1087 {
1088 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1089 return -1;
1090 }
1091
1092 //data->codec_ops->codec_slctool_time_cfg(data->pLine, SLIC_CFG_FLASH_HFIX, pstCmd->unPara.wTime);
1093
1094 return 0;
1095}
1096
1097static s8 usrline_ioctl_slctool_dialhmin_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1098{
1099 if ((NULL == data) || (NULL == pstCmd))
1100 {
1101 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1102 return -1;
1103 }
1104
1105 //data->codec_ops->codec_slctool_time_cfg(data->pLine, SLIC_CFG_DIAL_HMIN, pstCmd->unPara.wTime);
1106
1107 return 0;
1108}
1109
1110static s8 usrline_ioctl_slctool_dialhmax_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1111{
1112 if ((NULL == data) || (NULL == pstCmd))
1113 {
1114 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1115 return -1;
1116 }
1117
1118 //data->codec_ops->codec_slctool_time_cfg(data->pLine, SLIC_CFG_DIAL_HMAX, pstCmd->unPara.wTime);
1119
1120 return 0;
1121}
1122
1123static s8 usrline_ioctl_slctool_diallmin_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1124{
1125 if ((NULL == data) || (NULL == pstCmd))
1126 {
1127 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1128 return -1;
1129 }
1130
1131 //data->codec_ops->codec_slctool_time_cfg(data->pLine, SLIC_CFG_DIAL_LMIN, pstCmd->unPara.wTime);
1132
1133 return 0;
1134}
1135
1136static s8 usrline_ioctl_slctool_diallmax_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1137{
1138 if ((NULL == data) || (NULL == pstCmd))
1139 {
1140 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1141 return -1;
1142 }
1143
1144 //data->codec_ops->codec_slctool_time_cfg(data->pLine, SLIC_CFG_DIAL_LMAX, pstCmd->unPara.wTime);
1145
1146 return 0;
1147}
1148
1149
1150static s8 usrline_ioctl_dial_start(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1151{
1152 if (NULL == data)
1153 {
1154 USLPUT0("%s data NULL\n",__FUNCTION__);
1155 return -1;
1156 }
1157
1158 USLPUT3("%s port %d \n",__FUNCTION__,data->port);
1159 data->codec_ops->codec_dial_set(data->pLine, EV_DIAL_START);
1160
1161 return SLC_SUCCESS;
1162}
1163
1164static s8 usrline_ioctl_dial_stop(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1165{
1166 if (NULL == data)
1167 {
1168 USLPUT0("%s data NULL\n",__FUNCTION__);
1169 return -1;
1170 }
1171
1172 USLPUT3("%s port %d \n",__FUNCTION__,data->port);
1173 data->codec_ops->codec_dial_set(data->pLine, EV_DIAL_STOP);
1174
1175 return SLC_SUCCESS;
1176}
1177
1178#ifdef POWER_SUPPLY_05A
1179/*used for dinggasp deal*/
1180extern u8 (*slic_function)(void);
1181/*
1182function: return ring state
1183return : zero: not ring;
1184 none zero: is ring
1185*/
1186u8 slic_is_ring_state(void)
1187{
1188 USL_PORT *data = NULL;
1189 u8 done_line = 0;
1190 int i = 0;
1191 for ( i = 0; i < MAX_PORT_NUM; i++ )
1192 {
1193 data = (USL_PORT *)&pstUslPort[i];
1194
1195 if((NULL == data) || (LINE_DISABLE == data->flag))
1196 {
1197 continue;
1198 }
1199
1200 if (RING_SIGNAL_ON == data->signal_on)
1201 {
1202 data->stRingQuenePara.dwRingStop = 1;
1203 done_line++;
1204 }
1205 }
1206
1207 USLPUT3("done_line = %d.\n",done_line);
1208
1209 return done_line;
1210}
1211#endif
1212
1213static s8 usrline_ioctl_port_lock(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1214{
1215 if (NULL == data)
1216 {
1217 USLPUT0("%s data NULL\n",__FUNCTION__);
1218 return -1;
1219 }
1220
1221 USLPUT2("%s: port %d \n",__FUNCTION__, data->port);
1222 data->flag = LINE_DISABLE;
1223
1224 return 0;
1225}
1226
1227static s8 usrline_ioctl_port_unlock(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1228{
1229 if (NULL == data)
1230 {
1231 USLPUT0("%s data NULL\n",__FUNCTION__);
1232 return -1;
1233 }
1234
1235 USLPUT2("%s: port %d \n",__FUNCTION__, data->port);
1236 data->flag = LINE_ENABLE;
1237
1238 return 0;
1239}
1240
1241static s8 usrline_ioctl_polarity_reverse(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1242{
1243 if (NULL == data)
1244 {
1245 USLPUT0("%s data NULL\n",__FUNCTION__);
1246 return -1;
1247 }
1248
1249 USLPUT2("%s: port %d \n",__FUNCTION__, data->port);
1250 data->codec_ops->codec_polarity_reverse(data->pLine,data->port);
1251
1252 data->dwIsRevPol ^= 1;
1253
1254 return 0;
1255}
1256
1257static s8 usrline_ioctl_dtmf_start(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1258{
1259 if (NULL == data)
1260 {
1261 USLPUT0("%s data NULL\n",__FUNCTION__);
1262 return -1;
1263 }
1264
1265 data->codec_ops->codec_signal_ctrl(data->pLine, NULL, RING_SIGNAL_OFF_REVERSED);
1266
1267 USLPUT2("%s : port %d \n",__FUNCTION__, data->port);
1268
1269 return 0;
1270}
1271
1272static s8 usrline_ioctl_fsk_start(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1273{
1274 if (NULL == data)
1275 {
1276 USLPUT0("%s data NULL\n",__FUNCTION__);
1277 return -1;
1278 }
1279
1280 USLPUT2("%s : port %d ",__FUNCTION__, data->port);
1281 if (0 == data->dwIsRevPol)
1282 {
1283 USLPUT2("set fsk OHT\n");
1284 data->codec_ops->codec_signal_ctrl(data->pLine, NULL, RING_SIGNAL_OFF);
1285 }
1286 else
1287 {
1288 USLPUT2("set dtmf OHTREV\n");
1289 data->codec_ops->codec_signal_ctrl(data->pLine, NULL, RING_SIGNAL_OFF_REVERSED);
1290 }
1291
1292 return 0;
1293}
1294
1295static s8 usrline_ioctl_fsk_stop(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1296{
1297 if (NULL == data)
1298 {
1299 USLPUT0("%s data NULL\n",__FUNCTION__);
1300 return -1;
1301 }
1302
1303 USLPUT2("%s : port %d \n",__FUNCTION__, data->port);
1304 data->codec_ops->codec_signal_ctrl(data->pLine, NULL, RING_SIGNAL_CLEAN_ON);
1305
1306 return 0;
1307}
1308
1309static s8 usrline_ioctl_set_debuglvl(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1310{
1311 USL_PORT *pUslPort = NULL;
1312 int i = 0;
1313
1314 if (NULL == pstCmd)
1315 {
1316 USLPUT0("%s pstCmd NULL\n",__FUNCTION__);
1317 return -1;
1318 }
1319
1320 //si_usl_debuglvl = pstCmd->unPara.wLevel;
1321
1322 if(si_usl_debuglvl > 2)
1323 {
1324
1325 for ( i = 0; i < MAX_PORT_NUM; i++ )
1326 {
1327 pUslPort = (USL_PORT *)&pstUslPort[i];
1328
1329 if((NULL == pUslPort) || (LINE_DISABLE == pUslPort->flag))
1330 {
1331 continue;
1332 }
1333
1334 USLPUT0("port: %d\n",pUslPort->port);
1335 /* print the chip relative time parameters */
1336 pUslPort->codec_ops->codec_time_print(pUslPort->pLine);
1337
1338 USLPUT0("ring_quene: %d\n",pUslPort->stRingQuenePara.RingQueneDelay);
1339 }
1340
1341 }
1342
1343 return 0;
1344}
1345
1346static s8 usrline_ioctl_start_test(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1347{
1348 if ((NULL == data) || (NULL == pstCmd))
1349 {
1350 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1351 return -1;
1352 }
1353
1354 if (copy_from_user(pIoctlData, pstCmd->data, pstCmd->data_size) != 0)
1355 {
1356 USLPUT0("%s copy data from user fail!\n",__FUNCTION__);
1357 return -1;
1358 }
1359
1360 data->event_mask = ~(GET_EV_MASK(EV_FXS_TEST_DONE) | GET_EV_MASK(EV_FXS_TEST_ERROR));
1361
1362 if (-1 == data->codec_ops->codec_start_test(data->pLine, (WriteCmd_t *)pIoctlData))
1363 {
1364 data->event_mask = 0;
1365 USLPUT0("%s test start error\n",__FUNCTION__);
1366 }
1367
1368 return 0;
1369}
1370
1371static s8 usrline_ioctl_stop_test(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1372{
1373 if (NULL == data)
1374 {
1375 USLPUT0("%s data NULL\n",__FUNCTION__);
1376 return -1;
1377 }
1378
1379 data->codec_ops->codec_stop_test(data->pLine);
1380 data->event_mask = 0;
1381
1382 USLPUT2("%s:port %d.\n", __FUNCTION__, data->port);
1383
1384 return 0;
1385}
1386
1387static s8 usrline_ioctl_read_test_result(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1388{
1389 TestResult_t *stResult = (TestResult_t *)pIoctlData;
1390
1391 if ((NULL == data) || (NULL == pstCmd))
1392 {
1393 USLPUT0("%s data or pstResult NULL\n",__FUNCTION__);
1394 return -1;
1395 }
1396
1397 data->codec_ops->codec_read_reslult(data->pLine, stResult);
1398 data->event_mask = 0;
1399
1400 USLPUT3("%s:port %d.\n", __FUNCTION__, data->port);
1401
1402 USLPUT3("112 test result:");
1403 USLPUT3("port %d\n", stResult->port);
1404 USLPUT3("port_type %d\n", stResult->port_type);
1405 USLPUT3("item %d\n", stResult->item);
1406 USLPUT3("obligate %d\n", stResult->obligate);
1407 USLPUT3("num %ld\n", stResult->num);
1408 USLPUT3("omci_item %d\n", stResult->omci_item);
1409 USLPUT3("flg %d\n", stResult->flg);
1410 USLPUT3("user_flg %d\n", stResult->user_flg);
1411 USLPUT3("err_num %d\n", stResult->err_num);
1412 USLPUT3("Vac_tr %ld\n", stResult->vac_tr);
1413 USLPUT3("vac_tg %ld\n", stResult->vac_tg);
1414 USLPUT3("vac_rg %ld\n", stResult->vac_rg);
1415 USLPUT3("Vdc_tr %ld\n", stResult->vdc_tr);
1416 USLPUT3("vdc_tg %ld\n", stResult->vdc_tg);
1417 USLPUT3("vdc_rg %ld\n", stResult->vdc_rg);
1418 USLPUT3("res_tr %ld\n", stResult->res_tr);
1419 USLPUT3("res_tg %ld\n", stResult->res_tg);
1420 USLPUT3("res_rg %ld\n", stResult->res_rg);
1421 USLPUT3("cap_tr %ld\n", stResult->cap_tr);
1422 USLPUT3("cap_tg %ld\n", stResult->cap_tg);
1423 USLPUT3("cap_rg %ld\n", stResult->cap_rg);
1424 USLPUT3("ring_vol %ld\n", stResult->ring_vol);
1425 USLPUT3("Hz %ld\n", stResult->Hz);
1426 USLPUT3("ren %ld\n", stResult->ren);
1427 USLPUT3("loop_curent %ld\n",stResult->loop_curent);
1428 USLPUT3("loop_res %ld\n", stResult->loop_res);
1429 USLPUT3("battary %ld\n", stResult->battary);
1430
1431 if (copy_to_user(pstCmd->data, stResult, pstCmd->data_size) != 0)
1432 {
1433 USLPUT0("%s copy data to user fail!\n",__FUNCTION__);
1434 }
1435
1436 return 0;
1437}
1438
1439static s8 usrline_ioctl_electric_cfg(USL_PORT *data, SLIC_IOCTL_DATA *pstCmd)
1440{
1441 if ((NULL == data) || (NULL == pstCmd))
1442 {
1443 USLPUT0("%s data or pstCmd NULL\n",__FUNCTION__);
1444 return -1;
1445 }
1446
1447 if (copy_from_user(pIoctlData, pstCmd->data, pstCmd->data_size) != 0)
1448 {
1449 USLPUT0("%s copy data from user fail!\n",__FUNCTION__);
1450 return -1;
1451 }
1452
1453 data->codec_ops->codec_electric_cfg(data->pLine, data->port, (ELECTRIC_CFG_CUSTOMIZED *)pIoctlData);
1454
1455 return 0;
1456}
1457
1458/*ring queue add by chenjian*/
1459void usrline_ring_ctrl(USL_PORT *usl_port)
1460{
1461 USL_PORT *data = NULL;
1462 data = (USL_PORT *)&pstUslPort[(usl_port->port+1)%2];
1463
1464 if(1 == usl_port->stRingQuenePara.dwNeedSort)
1465 {
1466 if ((NULL == data) || (SIGNAL_PLAY_STOP == data->signal_flag))
1467 {
1468 usrline_signal_start(usl_port);
1469 }
1470 else if ((data->stRingQuenePara.RingQueneDelay <= data->stRingQuenePara.dwOffCount) && (data->stRingQuenePara.dwOffCount <= data->stRingQuenePara.dwOffMaxCount))
1471 {
1472 usrline_signal_start(usl_port);
1473 }
1474 }
1475
1476 if (1==usl_port->stRingQuenePara.dwRingStop)
1477 {
1478 usrline_signal_stop(usl_port);
1479 }
1480
1481 return;
1482}
1483/*ring queue add by chenjian*/
1484
1485
1486static int usrline_scan(void* info)
1487{
1488 USL_PORT *usl_port = NULL;
1489 sigset_t blocked;
1490 u16 port = 0;
1491
1492 //lock_kernel();
1493 sprintf(current->comm, "usl_scan"); /* comm is 16 bytes */
1494 daemonize("usl_scan");
1495#if 1
1496 /* Block and flush all signals */
1497 sigfillset(&blocked);
1498 sigprocmask(SIG_BLOCK, &blocked, NULL);
1499 flush_signals(current);
1500#endif
1501 /* real time task FIFO */
1502 current->policy = SCHED_FIFO;
1503 //unlock_kernel();
1504 printk("howard usrline_scan, HZ is %d\n", HZ);
1505 while (timer_run)
1506 {
1507 set_current_state(TASK_INTERRUPTIBLE);
1508 schedule_timeout(10);
1509 //if(slic_offhook){
1510
1511 //schedule_timeout(10);
1512 //printk("howard usrline_scan while\n");
1513
1514 for (port = 0; port < MAX_PORT_NUM; port++)
1515 {
1516 usl_port = (USL_PORT *)&pstUslPort[port];
1517
1518 if((NULL == usl_port) || (LINE_DISABLE == usl_port->flag))
1519 {
1520 continue;
1521 }
1522
1523 usrline_ring_ctrl(usl_port);
1524
1525 if (SIGNAL_PLAY_START == usl_port->signal_flag)
1526 {
1527 usrline_signal_play(usl_port);
1528 }
1529
1530 usl_port->codec_ops->codec_scan(usl_port);
1531 //}
1532 }
1533
1534 } /* while () */
1535
1536 USLPUT0("User Line scan thread exit\n\r");
1537 scan_over = 1;
1538
1539 return 0;
1540}
1541
1542/* ==================================================================== */
1543static int usrline_open(struct inode *inode, struct file *filp)
1544{
1545 //MOD_INC_USE_COUNT;
1546 return 0;
1547}
1548
1549static int usrline_release(struct inode *inode, struct file *filp)
1550{
1551 // MOD_DEC_USE_COUNT;
1552 return 0;
1553}
1554
1555static void irq_handle_interrupt(USL_PORT *data,
1556 ProslicInt interrupt, int *hook_det)
1557{
1558 proslicChanType_ptr hProslic;
1559 hProslic = data->pLine->ProObj;
1560
1561 switch(interrupt)
1562 {
1563 case IRQ_LOOP_STATUS:
1564 ProSLIC_ReadHookStatus(hProslic,hook_det);
1565 if(*hook_det == PROSLIC_OFFHOOK)
1566 {
1567 slic_offhook = 1;
1568 printk("OFFHOOK\n");
1569 }
1570 else
1571 {
1572 slic_offhook = 0;
1573 printk("ONHOOK\n");
1574 }
1575 break;
1576
1577 case IRQ_P_HVIC:
1578 case IRQ_P_THERM:
1579 printk("IRQ_P_HVIC or IRQ_P_THERM detect, set linefeed FWD_ACTIVE\n");
1580 ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
1581 break;
1582
1583 case IRQ_DTMF:
1584 {
1585 unsigned char digit;
1586 char digit_char;
1587 int ret = 0;
1588 //ProSLIC_SetMuteStatus(hProslic,PROSLIC_MUTE_TX);
1589 if(slic_pcm_open == 1)
1590 {
1591 //ret = zDrvRpMsg_Write(&icp_pMsg);
1592 CPPS_FUNC(cpps_callbacks, zDrvVp_SetDtmfMute_Wrap)();
1593 // printk("DTMF zDrvRpMsg_Write ret %d\n",ret);
1594 }
1595 dtmf_mute = 1;
1596 ProSLIC_DTMFReadDigit(hProslic, &digit);
1597 if( (digit >=1) && (digit <= 9 ) )
1598 {
1599 digit_char = digit + '0';
1600 }
1601 else
1602 {
1603 if(digit == 0)
1604 {
1605 digit_char = 'D';
1606 }
1607 else
1608 {
1609 char digit_decode[] = "0*#ABC";
1610 digit_char = digit_decode[digit - 10];
1611 }
1612 }
1613 printk("detected dtmf-%c\n", digit_char);
1614 usrline_report(data->port,EV_FXS_COLLECT_DIG,digit_char, data->event_mask);
1615 }
1616 break;
1617
1618 default:
1619 break;
1620 }
1621}
1622
1623static int irq_check_interrupts(USL_PORT *data, int *hook_det)
1624{
1625 proslicIntType irqs;
1626 ProslicInt arrayIrqs[MAX_PROSLIC_IRQS];
1627 proslicChanType_ptr hProslic;
1628 hProslic = data->pLine->ProObj;
1629
1630
1631 irqs.irqs = arrayIrqs;
1632
1633 if (ProSLIC_GetInterrupts(hProslic, &irqs) != 0)
1634 {
1635 unsigned int i;
1636 /* Iterate through the interrupts and handle */
1637 for(i=0 ; i<irqs.number; i++)
1638 {
1639 if (irqs.irqs[i] == 8)
1640 fskbuf_avail_flag = 1;
1641 /*
1642 if (irqs.irqs[i] < MAX_INT_STRINGS)
1643 {
1644 printk("detected: %s\n", intMapStrings[irqs.irqs[i]]);
1645 }
1646 */
1647 irq_handle_interrupt(data,irqs.irqs[i], hook_det);
1648 }
1649 }
1650 /*
1651 if (irqs.number)
1652 {
1653 printk("\n");
1654 }
1655 */
1656
1657 return irqs.number;
1658}
1659
1660static int slic_get_gpio_state(int gpioNum,
1661 unsigned int gpio_sel_gpio,unsigned int gpio_sel_int)
1662{
1663 unsigned int gpio_state = GPIO_HIGH;
1664
1665 zx29_gpio_config(gpioNum, gpio_sel_gpio);
1666 //pcu_clr_irq_pending(irq);
1667 zx29_gpio_set_direction(gpioNum,GPIO_IN);
1668 msleep(30);
1669 gpio_state = gpio_get_value(gpioNum);
1670 msleep(30);
1671 zx29_gpio_config(gpioNum, gpio_sel_int);/******qhf***int****/
1672 //pcu_clr_irq_pending(irq);
1673
1674 //printk(KERN_INFO "gpio state=%d.\n",gpio_state);
1675
1676 return gpio_state; /* 0: µÍµçƽ(press), 1:¸ßµçƽ(release) */
1677
1678}
1679
1680static irqreturn_t slic_int_irq(int irq, void *data)
1681{
1682 int ret = IRQ_HANDLED;
1683 int hook_changed = 0;
1684 //int gpio_state = 0;
1685 proslicChanType_ptr hProslic;
1686 hProslic = ((USL_PORT *)data)->pLine->ProObj;
1687
1688 //gpio_state = slic_get_gpio_state(SLIC_INT_GPIO, GPIO74_GPIO74, GPIO74_EXT_INT12);
1689 //printk("howard slic irq %d, clear pending\n", irq);
1690 pcu_clr_irq_pending(irq);
1691 if (1 == init_flg)
1692 irq_check_interrupts((USL_PORT *)data, &hook_changed);
1693
1694 /* To be done */
1695 return ret;
1696}
1697/*******************************************************************************
1698* Function: slic_int_irq_handler
1699* Description: clear irq , wake thread irq
1700* Parameters:
1701* Input:
1702* Output:
1703********************************************************************************/
1704static irqreturn_t slic_int_irq_handler(int irq, void *dev_id)
1705{
1706 //disable_irq_nosync(irq);
1707 //pcu_int_clear(irq);
1708 //printk("howard slic int handler irq=%d.\n", irq);
1709 pcu_clr_irq_pending(irq);
1710
1711 return IRQ_WAKE_THREAD;
1712}
1713#if 0
1714static int slic_create_rpmsg()
1715{
1716 int ret = 0;
1717 icp_pMsg.actorID = PS_ID;
1718 icp_pMsg.buf = rpMsgBuf;
1719 icp_pMsg.len = 8;
1720 icp_pMsg.chID = ICP_CHANNEL_DTMF;
1721 icp_pMsg.flag |= RPMSG_WRITE_INT;
1722 ret = zDrvRpMsg_CreateChannel(PS_ID, ICP_CHANNEL_DTMF, 0x10);
1723 printk("create_rpmsg ret %d\n", ret);
1724 return ret;
1725}
1726#endif
1727/*********************************************************************************
1728*{usrline_ioctl_xxxx},func deals ioctl cmd, if not realized, please fill {NULL},
1729*must corresponding to cmd one by one
1730*********************************************************************************/
1731static const USRLINE_IOCTL_FUNC_MAP IoctlFuncMap[] =
1732{
1733 {usrline_ioctl_dev_init}, /* SLIC_DEV_INIT */
1734 {usrline_ioctl_msg_rev}, /* SLIC_MSG_REV */
1735 {NULL}, /* SLIC_TEST */
1736 {usrline_ioctl_signal_start}, /* SLIC_SIGNAL_START */
1737 {usrline_ioctl_signal_stop}, /* SLIC_SIGNAL_STOP */
1738 {usrline_ioctl_pcm_open}, /* SLIC_PCM_OPEN */
1739 {usrline_ioctl_pcm_close}, /* SLIC_PCM_CLOSE */
1740 {usrline_ioctl_pcm_set_nb}, /* SLIC_PCM_SET_NB */
1741 {usrline_ioctl_pcm_set_wb}, /* SLIC_PCM_SET_WB */
1742
1743 {usrline_ioctl_Inf_precfg}, /* SLIC_INF_PRECFG */
1744
1745 {NULL}, /* SLIC_NOTUSED */
1746 {usrline_ioctl_port_reset}, /* SLIC_PORT_RESET */
1747
1748 {usrline_ioctl_msg_clear}, /* SLIC_MSG_CLR */
1749 {usrline_ioctl_dial_start}, /* SLIC_DIAL_START */
1750 {usrline_ioctl_dial_stop}, /* SLIC_DIAL_STOP */
1751
1752
1753 {usrline_ioctl_timeslot_set}, /* SLIC_TIMESLOT_SET */
1754 {usrline_ioctl_timeslot_release}, /* SLIC_TIMESLOT_RELEASE */
1755 {usrline_ioctl_port_lock}, /* SLIC_PORT_LOCK */
1756 {usrline_ioctl_port_unlock}, /* SLIC_PORT_UNLOCK */
1757 {usrline_ioctl_fsk_start}, /* SLIC_FSK_START */
1758 {usrline_ioctl_fsk_stop}, /* SLIC_FSK_STOP */
1759 {usrline_ioctl_polarity_reverse}, /* SLIC_POLARITY_REVERSE */
1760 {usrline_ioctl_dtmf_start}, /* SLIC_DTMFCID_START */
1761 {usrline_ioctl_start_test}, /* SLIC_LINE_TEST_START */
1762 {usrline_ioctl_stop_test}, /* SLIC_LINE_TEST_ABORT */
1763 {usrline_ioctl_read_test_result}, /* SLIC_LINE_TEST_READ */
1764 {usrline_ioctl_time_cfg}, /* SLIC_TIMEPARA_CFG */
1765 {usrline_ioctl_electric_cfg}, /* SLIC_ELECTRIC_CFG */
1766 {usrline_ioctl_set_debuglvl}, /* SLIC_DEBUG_LEVEL */
1767 {usrline_ioctl_slctool_hooklowlen_cfg}, /* SLIC_CFG_HOOK_LOWLEN */
1768 {usrline_ioctl_slctool_hookhiglen_cfg}, /* SLIC_CFG_HOOK_HIGLEN */
1769 {usrline_ioctl_slctool_flashlowmin_cfg}, /* SLIC_CFG_FLASH_LMIN */
1770 {usrline_ioctl_slctool_flashlowmax_cfg}, /* SLIC_CFG_FLASH_LMAX */
1771 {usrline_ioctl_slctool_flashhfix_cfg}, /* SLIC_CFG_FLASH_HFIX */
1772 {usrline_ioctl_slctool_dialhmin_cfg}, /* SLIC_CFG_DIAL_HMIN */
1773 {usrline_ioctl_slctool_dialhmax_cfg}, /* SLIC_CFG_DIAL_HMAX */
1774 {usrline_ioctl_slctool_diallmin_cfg}, /* SLIC_CFG_DIAL_LMIN */
1775 {usrline_ioctl_slctool_diallmax_cfg}, /* SLIC_CFG_DIAL_LMAX */
1776 {NULL}, /* SLIC_CFG_RINGCEASE */
1777 {usrline_ioctl_slctool_prehookhiglen_cfg}, /* SLIC_CFG_PREHOOK_HIGLEN */
1778 {NULL}, /* SLIC_CFG_QUEUE_DELAY */
1779 {usrline_ioctl_codec_read}, /* SLIC_CODEC_GET */
1780 {usrline_ioctl_codec_config}, /* SLIC_CODEC_SET */
1781 {usrline_ioctl_ram_read}, /* SLIC_RAM_GET */
1782 {usrline_ioctl_ram_config}, /* SLIC_RAM_SET */
1783 {usrline_ioctl_mute}, /* SLIC_RAM_SET */
1784 {NULL}, /* SLIC_CODEC_GETALL */
1785 {NULL}, /* SLIC_RAM_GETALL */
1786 {NULL}, /* SLIC_GET_CHIP_NAME */
1787};
1788
1789#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
1790static long usrline_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1791#else
1792static int usrline_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
1793#endif
1794{
1795 s8 rev = -1;
1796 USL_PORT *usl_port = NULL;
1797 SLIC_IOCTL_DATA stCmd = {0};
1798
1799 printk("howard usrline_ioctl cmd=%d\n", cmd);
1800
1801 if((0 == init_flg) && (SLIC_DEV_INIT != cmd) && (SLIC_MSG_REV != cmd))
1802 {
1803 printk("SLIC init NOT complete\n");
1804 return -1;
1805 }
1806
1807 if (NULL != (void *)arg)
1808 {
1809 if (copy_from_user(&stCmd, (SLIC_IOCTL_DATA *)arg, sizeof(SLIC_IOCTL_DATA)) != 0)
1810 {
1811 USLPUT0("usrline_ioctl copy data from user fail!\n");
1812 return rev;
1813 }
1814#if 0
1815 if (stCmd.port >= MAX_PORT_NUM)
1816 {
1817 USLPUT0("usrline_ioctl port:%d illegal, max:%d\n", stCmd.port, MAX_PORT_NUM-1);
1818 return rev;
1819 }
1820#endif
1821 usl_port = (USL_PORT *)&pstUslPort[0];
1822 //ProSLIC_Init_MultiBOM(&(pstUslPort->pLine->ProObj),1,3);
1823
1824 if (NULL == usl_port)
1825 {
1826 USLPUT0("usrline_ioctl usl_port NULL\n");
1827 return rev;
1828 }
1829
1830 if (LINE_DISABLE == usl_port->flag)
1831 {
1832 USLPUT0("usrline_ioctl port:0 is disable now!\n");
1833 switch (cmd)
1834 {
1835 case SLIC_INF_PRECFG:
1836 case SLIC_MSG_REV:
1837 rev = IoctlFuncMap[cmd].pIoctlFunc(usl_port, &stCmd);
1838 break;
1839 case SLIC_PORT_UNLOCK:
1840 if (LINE_INITOK == usl_port->dwInitOK)
1841 {
1842 rev = IoctlFuncMap[cmd].pIoctlFunc(usl_port, &stCmd);
1843 }
1844 break;
1845 default:
1846 rev = IoctlFuncMap[cmd].pIoctlFunc(usl_port, &stCmd);
1847 break;
1848 }
1849
1850 return rev;
1851 }
1852 }
1853
1854 if ((cmd >= 0) && (cmd < SLIC_IOCTL_CMD_MAX))
1855 {
1856 if (NULL != IoctlFuncMap[cmd].pIoctlFunc)
1857 {
1858 rev = IoctlFuncMap[cmd].pIoctlFunc(usl_port, &stCmd);
1859 }
1860 else
1861 {
1862 USLPUT0("cmd:%d not realized!\n", cmd);
1863 }
1864 }
1865 else
1866 {
1867 USLPUT0("cmd:%d not supprot!\n", cmd);
1868 }
1869
1870 return rev;
1871}
1872
1873static struct file_operations usrline_fops = {
1874#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
1875 unlocked_ioctl: usrline_ioctl,
1876#else
1877 ioctl: usrline_ioctl,
1878#endif
1879 open: usrline_open,
1880 release: usrline_release,
1881 owner: THIS_MODULE
1882};
1883
1884/* =================================================== */
1885int si_usrline_init(void)
1886{
1887 int rev;
1888
1889 init_waitqueue_head(&msg_wait_queue);
1890
1891 CreatMsgQueue();
1892 printk("howard si_usrline_init\n");
1893
1894 rev = register_chrdev(USL_MAJOR, USL_NAME, &usrline_fops);
1895 if (rev < 0) {
1896 USLPUT0("%s: can't get major %d\n", USL_NAME, USL_MAJOR);
1897 return rev;
1898 }
1899
1900 if (0 != SlicMallocMemory())
1901 {
1902 unregister_chrdev(USL_MAJOR, USL_NAME);
1903 USLPUT0("Can't get USL_PORT memory!\n");
1904 return -1;
1905 }
1906 slic_dev_class = class_create(THIS_MODULE, USL_NAME);
1907 if (IS_ERR(slic_dev_class))
1908 {
1909 printk("howard failed in creat slic class!\n");
1910 unregister_chrdev(USL_MAJOR, USL_NAME);
1911 return -1;
1912 }
1913 slic_device = device_create(slic_dev_class, NULL, MKDEV(USL_MAJOR, 0), NULL, USL_NAME);
1914 if (IS_ERR(slic_device))
1915 {
1916 printk("howard failed in creat slic device!\n");
1917 class_destroy(slic_dev_class);
1918 unregister_chrdev(USL_MAJOR, USL_NAME);
1919 return -1;
1920 }
1921 printk("howard kernel_thread\n");
1922 kernel_thread(usrline_scan, NULL, 0); /* fork the main thread */
1923
1924 SlicCfgParaBasedBoardType();
1925#ifdef POWER_SUPPLY_05A
1926 slic_function = slic_is_ring_state;
1927#endif
1928 SPI_Init();
1929
1930 //zx29_gpio_config(SLIC_POW_EN_GPIO, GPIO121_GPIO121); /* set SLIC 3.3V EN GPIO */
1931 //zx29_gpio_set_direction(SLIC_POW_EN_GPIO, GPIO_OUT);
1932 //gpio_direction_output(SLIC_POW_EN_GPIO, 1);
1933
1934/* add by zhanghuan for INT and RST GPIO */
1935 //zx29_gpio_config(SLIC_INT_GPIO, GPIO74_GPIO74); /* set SLIC_INT_GPIO as GPIO */
1936 //zx29_gpio_config(SLIC_RST_GPIO, GPIO77_GPIO77); /* set SLIC_RST_GPIO as GPIO */
1937 #if 0
1938 rev = gpio_is_valid(SLIC_INT_GPIO);
1939 if(rev < 0)
1940 {
1941 printk("SLIC_INT_GPIO is not valid\n");
1942 //return -1;
1943 };
1944 rev = gpio_request(SLIC_INT_GPIO, "slic int");
1945 if(rev < 0)
1946 {
1947 printk("SLIC_INT_GPIO is not valid\n");
1948 //return -1;
1949 };
1950 //gpio_direction_input(SLIC_INT_GPIO);
1951
1952 zx29_gpio_config(SLIC_INT_GPIO, GPIO74_GPIO74); /* set SLIC_INT_GPIO as GPIO */
1953 gpio_direction_input(SLIC_INT_GPIO);
1954 #endif
1955 //zx29_gpio_set_direction(SLIC_INT_GPIO, GPIO_IN);
1956 #if 1
1957 rev = gpio_request(SLIC_INT_GPIO, "slic_int");
1958 if (rev) {
1959 printk(KERN_INFO "slic_int gpio request error.\n");
1960 return rev;
1961 }
1962
1963 zx29_gpio_pd_pu_set(SLIC_INT_GPIO, IO_CFG_PULL_DISABLE);//IO_CFG_PULL_DISABLE
1964 rev = zx29_gpio_config(SLIC_INT_GPIO,FNC_SLIC_INT_GPIO);/********V3 GPIO53:0 /EXT_INT:6*******//********V2 GPIO74:0 /EXT_INT:12*******/
1965
1966 zx29_gpio_set_inttype(SLIC_INT_GPIO,IRQ_TYPE_EDGE_FALLING/*IRQ_TYPE_EDGE_FALLING/*IRQ_TYPE_EDGE_RISING*/); //INT_POSEDGE
1967 //zx29_gpio_pd_pu_set(SLIC_INT_GPIO, 0);
1968 irq_num = gpio_to_irq(SLIC_INT_GPIO);
1969 rev = irq_set_irq_wake(irq_num, 1);
1970 printk("howard irq_set_irq_wake irq_num %d, ret %d\n", irq_num, rev);
1971 pcu_clr_irq_pending(irq_num);
1972
1973 request_threaded_irq(irq_num, slic_int_irq_handler,
1974 slic_int_irq, IRQF_ONESHOT, "slic int", pstUslPort);
1975 #endif
1976 rev = gpio_is_valid(SLIC_RST_GPIO);
1977 if(rev < 0)
1978 {
1979 printk("SLIC_RST_GPIO is not valid\n");
1980 //return -1;
1981 };
1982 rev = gpio_request(SLIC_RST_GPIO, "slic reset");
1983 if(rev < 0)
1984 {
1985 printk("SLIC_RST_GPIO is not valid\n");
1986 //return -1;
1987 };
1988 zx29_gpio_config(SLIC_RST_GPIO, FNC_SLIC_RST_GPIO); /* set SLIC_RST_GPIO as GPIO */
1989
1990 //zx29_gpio_set_direction(SLIC_RST_GPIO, GPIO_OUT);
1991 gpio_direction_output(SLIC_RST_GPIO, 0);
1992 gpio_set_value(SLIC_RST_GPIO,1);
1993 //gpio_direction_output(SLIC_RST_GPIO, 1);
1994 //zx29_gpio_output_data(SLIC_RST_GPIO, 1);
1995 /* add by zhanghuan for SLIC wake lock */
1996 wake_lock_init(&slic_wakelock, WAKE_LOCK_SUSPEND, "slic_wakelock");
1997 wake_lock(&slic_wakelock);
1998 zx_cpuidle_set_busy(IDLE_FLAG_SLIC);
1999#if 0
2000 rev = slic_create_rpmsg();
2001 if(rev < 0)
2002 {
2003 printk("slic_create_rpmsg failed\n");
2004 };
2005#endif
2006 zx29_i2s_tdm_pin_cfg();
2007
2008 USLPUT0("howard:User SLIC Driver V3.0.0 Init Finish.\n\r");
2009 return 0;
2010}
2011
2012void si_usrline_cleanup(void)
2013{
2014 timer_run = 0; /* stop scan */
2015 while(!scan_over) /* wait scan thread exit */
2016 {
2017 schedule();
2018 }
2019 printk("howard si_usrline_cleanup\n");
2020 free_irq(irq_num, pstUslPort);
2021
2022 DeinitSlicChip();
2023 SlicFreeMemory();
2024
2025 SPI_Exit();
2026 gpio_free(SLIC_INT_GPIO);
2027 gpio_free(SLIC_RST_GPIO);
2028 printk("howard free irq\n");
2029 device_destroy(slic_dev_class, MKDEV(USL_MAJOR, 0));
2030 class_destroy(slic_dev_class);
2031 unregister_chrdev(USL_MAJOR, USL_NAME);
2032 wake_lock_destroy(&slic_wakelock);
2033 zx_cpuidle_set_free(IDLE_FLAG_SLIC);
2034 USLPUT0("SLC:User SLIC Driver remove OK!\n\r");
2035
2036 return;
2037}
2038static void zx29_i2s_tdm_pin_cfg(void)
2039{
2040 unsigned int regval = 0;
2041
2042 int ret = 0;
2043 printk("zx29_i2s_tdm_pin_cfg\n");
2044 //ret = zOss_NvItemRead(OS_FLASH_VOICE_DRV_RW_NONFAC_BASE_ADDR, ((UINT8 *)(&audionvflag)), sizeof(audionvflag));
2045
2046 printk("after zx29_i2s_tdm_pin_cfg\n");
2047 #if 0
2048 ret = gpio_request(PIN_TDM_FS, "i2s0_ws");
2049 if (ret < 0)
2050 BUG();
2051 ret = gpio_request(PIN_TDM_CLK, "i2s0_clk");
2052 if (ret < 0)
2053 BUG();
2054 ret = gpio_request(PIN_TDM_DIN, "i2s0_din");
2055 if (ret < 0)
2056 BUG();
2057 ret = gpio_request(PIN_TDM_DOUT, "i2s0_dout");
2058 if (ret < 0)
2059 BUG();
2060 zx29_gpio_config(PIN_TDM_FS, FUN_TDM_FS);
2061 zx29_gpio_config(PIN_TDM_CLK, FUN_TDM_CLK);
2062 zx29_gpio_config(PIN_TDM_DIN, FUN_TDM_DIN);
2063 zx29_gpio_config(PIN_TDM_DOUT, FUN_TDM_DOUT);
2064
2065
2066 //zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO,"vp_SetTopTdmConfig set top TDM,ARM_TDM_LOOP_SET=0x%x\n",ARM_TDM_LOOP_SET);
2067 // sel tdm wclk
2068 regval = zx_read_reg(ZX29_TDM_MOD_CLK_SEL);
2069 regval &= 0xfcffffff; //set mod_clk_sel bit 25:24 to select the tdm wclk, 0, main_clk;1,122.88m;2,mpll104m;3,mpll104m;
2070 zx_write_reg(ZX29_TDM_MOD_CLK_SEL, regval);
2071 //zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO,"vp_SetTopTdmConfig set top TDM,MOD_CLK_SEL=0x%x\n",TDM_MOD_CLK_SEL);
2072 //zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO,"vp_SetTopTdmConfig set top TDM,DMA_SEL_CFG=0x%x\n",DMA_SEL_CFG);
2073
2074 // sel tdm use dma
2075 regval = zx_read_reg(ZX29_I2S_DMA_SEL_CFG);
2076 regval &= 0xffffff87;
2077 regval |= 0x00000018; // bit3 1 tdmtx,bit4 1 tdmrx bit5 i2s1tx,bit6 i2s1rx
2078 zx_write_reg(ZX29_I2S_DMA_SEL_CFG, regval);
2079
2080 printk("slic cfg tdm gpio pin end !\n");
2081 #else
2082 ret = gpio_request(PIN_I2S0_WS, "i2s0_ws");
2083 if (ret < 0)
2084 BUG();
2085 ret = gpio_request(PIN_I2S0_CLK, "i2s0_clk");
2086 if (ret < 0)
2087 BUG();
2088 ret = gpio_request(PIN_I2S0_DIN, "i2s0_din");
2089 if (ret < 0)
2090 BUG();
2091 ret = gpio_request(PIN_I2S0_DOUT, "i2s0_dout");
2092 if (ret < 0)
2093 BUG();
2094 zx29_gpio_config(PIN_I2S0_WS, FUN_I2S0_WS);
2095 zx29_gpio_config(PIN_I2S0_CLK, FUN_I2S0_CLK);
2096 zx29_gpio_config(PIN_I2S0_DIN, FUN_I2S0_DIN);
2097 zx29_gpio_config(PIN_I2S0_DOUT, FUN_I2S0_DOUT);
2098
2099 // sel i2s0 use dma
2100 regval = zx_read_reg(ZX29_I2S_DMA_SEL_CFG);
2101 regval &= 0xffffff87; //bit3 1 i2s0tx,bit4 1 i2s0rx bit5 i2s1tx,bit6 i2s1rx
2102 zx_write_reg(ZX29_I2S_DMA_SEL_CFG, regval);
2103 printk("slic cfg i2s0 gpio pin end !\n");
2104
2105 #endif
2106 //top i2s1 cfg
2107 regval = zx_read_reg(ZX29_I2S_LOOP_CFG);
2108 regval &= 0xfffffff8;
2109 regval |= 0x00000001; // inter arm_i2s1--top i2s1
2110 zx_write_reg(ZX29_I2S_LOOP_CFG, regval);
2111
2112 // inter loop
2113 regval = zx_read_reg(ZX29_I2S_LOOP_CFG);
2114 regval &= 0xfffffe07;
2115 regval |= 0x000000a8; // inter arm_i2s2--afe i2s
2116 zx_write_reg(ZX29_I2S_LOOP_CFG, regval);
2117
2118 printk("slic cfg top gpio end !\n");
2119
2120
2121
2122}
2123/* =================================================== */
2124#ifdef USE_GPIO_SPI_SLIC
2125module_init(si_usrline_init);
2126module_exit(si_usrline_cleanup);
2127#endif
2128
2129#ifdef USE_STD_SPI_SLIC
2130/* É豸̽²âº¯Êý */
2131static int slic_probe(struct spi_device *spi)
2132{
2133 printk("howard slic_probe\n");
2134 pslicSpi =spi;
2135 si_usrline_init();
2136 return 0;
2137
2138}
2139static int slic_remove(struct spi_device *spi)
2140{
2141 printk("howard slic_remove\n");
2142 si_usrline_cleanup();
2143 return 0;
2144}
2145
2146static const struct spi_device_id slic_id[] = {
2147 {"slic_spi", 0 },
2148 { }
2149};
2150
2151MODULE_DEVICE_TABLE(spi, slic_id);
2152
2153static struct spi_driver slic_spi_driver = {
2154 .driver = {
2155 .name = "slic_spi",
2156 .owner = THIS_MODULE,
2157 },
2158 .probe = slic_probe,
2159 .remove = slic_remove,
2160 .id_table = slic_id,
2161};
2162
2163static int __init slic_spi_init(void)
2164{
2165 int ret;
2166 printk("howard slic_spi_init\n");
2167
2168 ret = spi_register_driver(&slic_spi_driver);
2169 if (ret != 0)
2170 {
2171 printk("howard slic Failed to register slic_spi_driver : %d\n", ret);
2172 }
2173
2174 return ret;
2175}
2176
2177static void __exit slic_spi_exit(void)
2178{
2179 printk("howard slic_spi_exit\n");
2180 spi_unregister_driver(&slic_spi_driver);
2181}
2182
2183module_init(slic_spi_init);
2184module_exit(slic_spi_exit);
2185#endif
2186MODULE_AUTHOR("zxic");
2187MODULE_DESCRIPTION("SLIC Driver");
2188MODULE_LICENSE("GPL");
2189