ixj.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:219k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /*
  2.  *    ixj.c
  3.  *
  4.  *    Device Driver for the Internet PhoneJACK and
  5.  *    Internet LineJACK Telephony Cards.
  6.  *
  7.  *    (c) Copyright 1999 Quicknet Technologies, Inc.
  8.  *
  9.  *    This program is free software; you can redistribute it and/or
  10.  *    modify it under the terms of the GNU General Public License
  11.  *    as published by the Free Software Foundation; either version
  12.  *    2 of the License, or (at your option) any later version.
  13.  *
  14.  * Author:          Ed Okerson, <eokerson@quicknet.net>
  15.  *    
  16.  * Contributors:    Greg Herlein, <gherlein@quicknet.net>
  17.  *                  David W. Erhart, <derhart@quicknet.net>
  18.  *                  John Sellers, <jsellers@quicknet.net>
  19.  *                  Mike Preston, <mpreston@quicknet.net>
  20.  *
  21.  * Fixes:
  22.  *
  23.  * More information about the hardware related to this driver can be found
  24.  * at our website:    http://www.quicknet.net
  25.  *
  26.  * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
  27.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  28.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
  29.  * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30.  *
  31.  * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  32.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  33.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  34.  * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION 
  35.  * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  36.  */
  37. #ifndef __KERNEL__
  38. #define __KERNEL__
  39. #endif
  40. #ifndef MODULE
  41. #define MODULE
  42. #endif
  43. static char ixj_c_rcsid[] = "$Id: ixj.c,v 1.1 2000/01/07 22:49:59 ctam Exp $";
  44. //#define PERFMON_STATS
  45. #define IXJDEBUG 1
  46. #define MAXRINGS 5
  47. #include <linux/module.h>
  48. #include <linux/sched.h>
  49. #include <linux/kernel.h> /* printk() */
  50. #include <linux/fs.h> /* everything... */
  51. #include <linux/errno.h> /* error codes */
  52. #include <linux/malloc.h>
  53. #include <linux/mm.h>
  54. #include <linux/ioport.h>
  55. #include <linux/interrupt.h>
  56. #include <linux/tqueue.h>
  57. #include <linux/proc_fs.h>
  58. #include <linux/poll.h>
  59. #include <linux/timer.h>
  60. #include <linux/delay.h>
  61. #include <linux/pci.h>
  62. #include <asm/io.h>
  63. #include <asm/segment.h>
  64. #include <asm/uaccess.h>
  65. #ifdef CONFIG_ISAPNP
  66. #include "isapnp/pnpio.h"
  67. #include "isapnp/isapnp.h"
  68. #endif
  69. #include "ixj.h"
  70. #define TYPE(dev) (MINOR(dev) >> 4)
  71. #define NUM(dev) (MINOR(dev) & 0xf)
  72. static int ixjdebug = 0;
  73. static int hertz = HZ;
  74. static int samplerate = 100;
  75. MODULE_PARM(ixjdebug, "i");
  76. //static int ixj_major = 159;
  77. //static struct wait_queue *ixj_queue;
  78. static IXJ ixj[IXJMAX];
  79. static struct timer_list ixj_timer;
  80. int ixj_convert_loaded = 0;
  81. /************************************************************************
  82. *
  83. * These are function definitions to allow external modules to register
  84. * enhanced functionality call backs.
  85. *
  86. ************************************************************************/
  87. static int Stub(IXJ * J, unsigned long arg)
  88. {
  89. return 0;
  90. }
  91. static IXJ_REGFUNC ixj_DownloadG729 = &Stub;
  92. static IXJ_REGFUNC ixj_DownloadTS85 = &Stub;
  93. static IXJ_REGFUNC ixj_PreRead = &Stub;
  94. static IXJ_REGFUNC ixj_PostRead = &Stub;
  95. static IXJ_REGFUNC ixj_PreWrite = &Stub;
  96. static IXJ_REGFUNC ixj_PostWrite = &Stub;
  97. static IXJ_REGFUNC ixj_PreIoctl = &Stub;
  98. static IXJ_REGFUNC ixj_PostIoctl = &Stub;
  99. static void ixj_read_frame(int board);
  100. static void ixj_write_frame(int board);
  101. static void ixj_init_timer(void);
  102. static void ixj_timeout(unsigned long ptr);
  103. static int read_filters(int board);
  104. static int LineMonitor(int board);
  105. static int ixj_fasync(int fd, struct file *, int mode);
  106. static int ixj_hookstate(int board);
  107. static int ixj_record_start(int board);
  108. static void ixj_record_stop(int board);
  109. static int ixj_play_start(int board);
  110. static void ixj_play_stop(int board);
  111. static int ixj_set_tone_on(unsigned short arg, int board);
  112. static int ixj_set_tone_off(unsigned short, int board);
  113. static int ixj_play_tone(int board, char tone);
  114. static int idle(int board);
  115. static void ixj_ring_on(int board);
  116. static void ixj_ring_off(int board);
  117. static void aec_stop(int board);
  118. static void ixj_ringback(int board);
  119. static void ixj_busytone(int board);
  120. static void ixj_dialtone(int board);
  121. static void ixj_cpt_stop(int board);
  122. static char daa_int_read(int board);
  123. static int daa_set_mode(int board, int mode);
  124. static int ixj_linetest(int board);
  125. static int ixj_daa_cid_read(int board);
  126. static void DAA_Coeff_US(int board);
  127. static void DAA_Coeff_UK(int board);
  128. static void DAA_Coeff_France(int board);
  129. static void DAA_Coeff_Germany(int board);
  130. static void DAA_Coeff_Australia(int board);
  131. static void DAA_Coeff_Japan(int board);
  132. static int ixj_init_filter(int board, IXJ_FILTER * jf);
  133. static int ixj_init_tone(int board, IXJ_TONE * ti);
  134. static int ixj_build_cadence(int board, IXJ_CADENCE * cp);
  135. // Serial Control Interface funtions
  136. static int SCI_Control(int board, int control);
  137. static int SCI_Prepare(int board);
  138. static int SCI_WaitHighSCI(int board);
  139. static int SCI_WaitLowSCI(int board);
  140. static DWORD PCIEE_GetSerialNumber(WORD wAddress);
  141. /************************************************************************
  142. CT8020/CT8021 Host Programmers Model
  143. Host address Function Access
  144. DSPbase +
  145. 0-1 Aux Software Status Register (reserved) Read Only
  146. 2-3 Software Status Register Read Only
  147. 4-5 Aux Software Control Register (reserved) Read Write
  148. 6-7 Software Control Register Read Write
  149. 8-9 Hardware Status Register Read Only
  150. A-B Hardware Control Register Read Write
  151. C-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write Only
  152. E-F Host Recieve (Read) Data Buffer Access Port (buffer input) Read Only
  153. ************************************************************************/
  154. extern __inline__ void ixj_read_HSR(board)
  155. {
  156. ixj[board].hsr.bytes.low = inb_p(ixj[board].DSPbase + 8);
  157. ixj[board].hsr.bytes.high = inb_p(ixj[board].DSPbase + 9);
  158. }
  159. extern __inline__ int IsControlReady(int board)
  160. {
  161. ixj_read_HSR(board);
  162. return ixj[board].hsr.bits.controlrdy ? 1 : 0;
  163. }
  164. extern __inline__ int IsStatusReady(int board)
  165. {
  166. ixj_read_HSR(board);
  167. return ixj[board].hsr.bits.statusrdy ? 1 : 0;
  168. }
  169. extern __inline__ int IsRxReady(int board)
  170. {
  171. ixj_read_HSR(board);
  172. return ixj[board].hsr.bits.rxrdy ? 1 : 0;
  173. }
  174. extern __inline__ int IsTxReady(int board)
  175. {
  176. ixj_read_HSR(board);
  177. return ixj[board].hsr.bits.txrdy ? 1 : 0;
  178. }
  179. extern __inline__ BYTE SLIC_GetState(int board)
  180. {
  181. IXJ *j = &ixj[board];
  182. j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
  183. return j->pld_slicr.bits.state;
  184. }
  185. static BOOL SLIC_SetState(BYTE byState, int board)
  186. {
  187. BOOL fRetVal = FALSE;
  188. IXJ *j = &ixj[board];
  189. // Set the C1, C2, C3 & B2EN signals.
  190. switch (byState) {
  191. case PLD_SLIC_STATE_OC:
  192. j->pld_slicw.bits.c1 = 0;
  193. j->pld_slicw.bits.c2 = 0;
  194. j->pld_slicw.bits.c3 = 0;
  195. j->pld_slicw.bits.b2en = 0;
  196. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  197. fRetVal = TRUE;
  198. break;
  199. case PLD_SLIC_STATE_RINGING:
  200. j->pld_slicw.bits.c1 = 1;
  201. j->pld_slicw.bits.c2 = 0;
  202. j->pld_slicw.bits.c3 = 0;
  203. j->pld_slicw.bits.b2en = 1;
  204. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  205. fRetVal = TRUE;
  206. break;
  207. case PLD_SLIC_STATE_ACTIVE:
  208. j->pld_slicw.bits.c1 = 0;
  209. j->pld_slicw.bits.c2 = 1;
  210. j->pld_slicw.bits.c3 = 0;
  211. j->pld_slicw.bits.b2en = 0;
  212. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  213. fRetVal = TRUE;
  214. break;
  215. case PLD_SLIC_STATE_OHT: // On-hook transmit
  216. j->pld_slicw.bits.c1 = 1;
  217. j->pld_slicw.bits.c2 = 1;
  218. j->pld_slicw.bits.c3 = 0;
  219. j->pld_slicw.bits.b2en = 0;
  220. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  221. fRetVal = TRUE;
  222. break;
  223. case PLD_SLIC_STATE_TIPOPEN:
  224. j->pld_slicw.bits.c1 = 0;
  225. j->pld_slicw.bits.c2 = 0;
  226. j->pld_slicw.bits.c3 = 1;
  227. j->pld_slicw.bits.b2en = 0;
  228. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  229. fRetVal = TRUE;
  230. break;
  231. case PLD_SLIC_STATE_STANDBY:
  232. j->pld_slicw.bits.c1 = 1;
  233. j->pld_slicw.bits.c2 = 0;
  234. j->pld_slicw.bits.c3 = 1;
  235. j->pld_slicw.bits.b2en = 1;
  236. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  237. fRetVal = TRUE;
  238. break;
  239. case PLD_SLIC_STATE_APR: // Active polarity reversal
  240. j->pld_slicw.bits.c1 = 0;
  241. j->pld_slicw.bits.c2 = 1;
  242. j->pld_slicw.bits.c3 = 1;
  243. j->pld_slicw.bits.b2en = 0;
  244. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  245. fRetVal = TRUE;
  246. break;
  247. case PLD_SLIC_STATE_OHTPR: // OHT polarity reversal
  248. j->pld_slicw.bits.c1 = 1;
  249. j->pld_slicw.bits.c2 = 1;
  250. j->pld_slicw.bits.c3 = 1;
  251. j->pld_slicw.bits.b2en = 0;
  252. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  253. fRetVal = TRUE;
  254. break;
  255. default:
  256. fRetVal = FALSE;
  257. break;
  258. }
  259. return fRetVal;
  260. }
  261. int ixj_register(int index, IXJ_REGFUNC regfunc)
  262. {
  263. int cnt;
  264. int retval = 0;
  265. switch (index) {
  266. case G729LOADER:
  267. ixj_DownloadG729 = regfunc;
  268. for (cnt = 0; cnt < IXJMAX; cnt++)
  269. ixj_DownloadG729(&ixj[cnt], 0L);
  270. break;
  271. case TS85LOADER:
  272. ixj_DownloadTS85 = regfunc;
  273. for (cnt = 0; cnt < IXJMAX; cnt++)
  274. ixj_DownloadTS85(&ixj[cnt], 0L);
  275. break;
  276. case PRE_READ:
  277. ixj_PreRead = regfunc;
  278. break;
  279. case POST_READ:
  280. ixj_PostRead = regfunc;
  281. break;
  282. case PRE_WRITE:
  283. ixj_PreWrite = regfunc;
  284. break;
  285. case POST_WRITE:
  286. ixj_PostWrite = regfunc;
  287. break;
  288. case PRE_IOCTL:
  289. ixj_PreIoctl = regfunc;
  290. break;
  291. case POST_IOCTL:
  292. ixj_PostIoctl = regfunc;
  293. break;
  294. default:
  295. retval = 1;
  296. }
  297. return retval;
  298. }
  299. int ixj_unregister(int index)
  300. {
  301. int retval = 0;
  302. switch (index) {
  303. case G729LOADER:
  304. ixj_DownloadG729 = &Stub;
  305. break;
  306. case TS85LOADER:
  307. ixj_DownloadTS85 = &Stub;
  308. break;
  309. case PRE_READ:
  310. ixj_PreRead = &Stub;
  311. break;
  312. case POST_READ:
  313. ixj_PostRead = &Stub;
  314. break;
  315. case PRE_WRITE:
  316. ixj_PreWrite = &Stub;
  317. break;
  318. case POST_WRITE:
  319. ixj_PostWrite = &Stub;
  320. break;
  321. case PRE_IOCTL:
  322. ixj_PreIoctl = &Stub;
  323. break;
  324. case POST_IOCTL:
  325. ixj_PostIoctl = &Stub;
  326. break;
  327. default:
  328. retval = 1;
  329. }
  330. return retval;
  331. }
  332. void ixj_init_timer(void)
  333. {
  334. init_timer(&ixj_timer);
  335. ixj_timer.function = ixj_timeout;
  336. ixj_timer.data = (int) NULL;
  337. ixj_timer.expires = jiffies + (hertz / samplerate);
  338. add_timer(&ixj_timer);
  339. }
  340. static void ixj_timeout(unsigned long ptr)
  341. {
  342. int board;
  343. unsigned long jifon;
  344. IXJ *j;
  345. IXJ_TONE ti;
  346. static int mutex = 0;
  347. /* What is this trying to do ?? */
  348. /* This is a safeguard in case the loop does not complete before the
  349.    next timer tick.  Since all the work is done during this timer loop,
  350.    we do not want the next iteration of the loop to start before the
  351.    last one finished. */
  352. if (!mutex) {
  353. mutex++;
  354. for (board = 0; board < IXJMAX; board++) {
  355. j = &ixj[board];
  356. if (j->DSPbase) {
  357. #ifdef PERFMON_STATS
  358. j->timerchecks++;
  359. #endif
  360. if (j->tone_state) {
  361. if (!ixj_hookstate(board)) {
  362. ixj_cpt_stop(board);
  363. if (j->m_hook) {
  364. j->m_hook = 0;
  365. j->ex.bits.hookstate = 1;
  366. if (j->async_queue)
  367. kill_fasync(j->async_queue, SIGIO); // Send apps notice of change
  368. }
  369. goto timer_end;
  370. }
  371. if (j->tone_state == 1)
  372. jifon = (hertz * j->tone_on_time * 25 / 100000);
  373. else
  374. jifon = (hertz * j->tone_on_time * 25 / 100000) +
  375.     (hertz * j->tone_off_time * 25 / 100000);
  376. if (jiffies < j->tone_start_jif + jifon) {
  377. if (j->tone_state == 1) {
  378. ixj_play_tone(board, j->tone_index);
  379. if (j->dsp.low == 0x20) {
  380. goto timer_end;
  381. }
  382. } else {
  383. ixj_play_tone(board, 0);
  384. if (j->dsp.low == 0x20) {
  385. goto timer_end;
  386. }
  387. }
  388. } else {
  389. j->tone_state++;
  390. if (j->tone_state == 3) {
  391. j->tone_state = 0;
  392. if (j->cadence_t) {
  393. j->tone_cadence_state++;
  394. if (j->tone_cadence_state == j->cadence_t->elements_used) {
  395. switch (j->cadence_t->termination) {
  396. case PLAY_ONCE:
  397. ixj_cpt_stop(board);
  398. break;
  399. case REPEAT_LAST_ELEMENT:
  400. j->tone_cadence_state--;
  401. ixj_play_tone(board, j->cadence_t->ce[j->tone_cadence_state].index);
  402. break;
  403. case REPEAT_ALL:
  404. j->tone_cadence_state = 0;
  405. if (j->cadence_t->ce[j->tone_cadence_state].freq0) {
  406. ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
  407. ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
  408. ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
  409. ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
  410. ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
  411. ixj_init_tone(board, &ti);
  412. }
  413. ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, board);
  414. ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, board);
  415. ixj_play_tone(board, j->cadence_t->ce[0].index);
  416. break;
  417. }
  418. } else {
  419. if (j->cadence_t->ce[j->tone_cadence_state].gain0) {
  420. ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
  421. ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
  422. ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
  423. ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
  424. ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
  425. ixj_init_tone(board, &ti);
  426. }
  427. ixj_set_tone_on(j->cadence_t->ce[j->tone_cadence_state].tone_on_time, board);
  428. ixj_set_tone_off(j->cadence_t->ce[j->tone_cadence_state].tone_off_time, board);
  429. ixj_play_tone(board, j->cadence_t->ce[j->tone_cadence_state].index);
  430. }
  431. }
  432. }
  433. if (j->flags.dialtone) {
  434. ixj_dialtone(board);
  435. }
  436. if (j->flags.busytone) {
  437. ixj_busytone(board);
  438. if (j->dsp.low == 0x20) {
  439. goto timer_end;
  440. }
  441. }
  442. if (j->flags.ringback) {
  443. ixj_ringback(board);
  444. if (j->dsp.low == 0x20) {
  445. goto timer_end;
  446. }
  447. }
  448. if (!j->tone_state) {
  449. if (j->dsp.low == 0x20 || (j->play_mode == -1 && j->rec_mode == -1))
  450. idle(board);
  451. if (j->dsp.low == 0x20 && j->play_mode != -1)
  452. ixj_play_start(board);
  453. if (j->dsp.low == 0x20 && j->rec_mode != -1)
  454. ixj_record_start(board);
  455. }
  456. }
  457. }
  458. if (!j->tone_state || j->dsp.low != 0x20) {
  459. if (IsRxReady(board)) {
  460. ixj_read_frame(board);
  461. }
  462. if (IsTxReady(board)) {
  463. ixj_write_frame(board);
  464. }
  465. }
  466. if (j->flags.cringing) {
  467. if (ixj_hookstate(board) & 1) {
  468. j->flags.cringing = 0;
  469. ixj_ring_off(board);
  470. } else {
  471. if (jiffies - j->ring_cadence_jif >= (.5 * hertz)) {
  472. j->ring_cadence_t--;
  473. if (j->ring_cadence_t == -1)
  474. j->ring_cadence_t = 15;
  475. j->ring_cadence_jif = jiffies;
  476. }
  477. if (j->ring_cadence & 1 << j->ring_cadence_t) {
  478. ixj_ring_on(board);
  479. } else {
  480. ixj_ring_off(board);
  481. }
  482. goto timer_end;
  483. }
  484. }
  485. if (!j->flags.ringing) {
  486. if (ixj_hookstate(board)) {
  487. if (j->dsp.low == 0x21 &&
  488.     j->pld_slicr.bits.state != PLD_SLIC_STATE_ACTIVE)
  489.                 // Internet LineJACK
  490.  {
  491. SLIC_SetState(PLD_SLIC_STATE_ACTIVE, board);
  492. }
  493. LineMonitor(board);
  494. read_filters(board);
  495. ixj_WriteDSPCommand(0x511B, board);
  496. j->proc_load = j->ssr.high << 8 | j->ssr.low;
  497. if (!j->m_hook) {
  498. j->m_hook = j->ex.bits.hookstate = 1;
  499. if (j->async_queue)
  500. kill_fasync(j->async_queue, SIGIO); // Send apps notice of change
  501. }
  502. } else {
  503. if (j->dsp.low == 0x21 &&
  504.     j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE)
  505.                 // Internet LineJACK
  506.  {
  507. SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
  508. }
  509. if (j->ex.bits.dtmf_ready) {
  510. j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0;
  511. }
  512. if (j->m_hook) {
  513. j->m_hook = 0;
  514. j->ex.bits.hookstate = 1;
  515. if (j->async_queue)
  516. kill_fasync(j->async_queue, SIGIO); // Send apps notice of change
  517. }
  518. }
  519. }
  520. if (j->cardtype == 300) {
  521. if (j->flags.pstn_present) {
  522. j->pld_scrr.byte = inb_p(j->XILINXbase);
  523. if (jiffies >= j->pstn_sleeptil && j->pld_scrr.bits.daaflag) {
  524. daa_int_read(board);
  525. if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
  526. if (!j->flags.pstn_ringing) {
  527. j->flags.pstn_ringing = 1;
  528. if (j->daa_mode != SOP_PU_RINGING)
  529. daa_set_mode(board, SOP_PU_RINGING);
  530. }
  531. }
  532. if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
  533. j->pstn_winkstart = 0;
  534. if (j->flags.pstn_ringing && !j->pstn_envelope) {
  535. j->ex.bits.pstn_ring = 0;
  536. j->pstn_envelope = 1;
  537. j->pstn_ring_start = jiffies;
  538. }
  539. } else {
  540. if (j->flags.pstn_ringing && j->pstn_envelope &&
  541.     jiffies > j->pstn_ring_start + ((hertz * 15) / 10)) {
  542. j->ex.bits.pstn_ring = 1;
  543. j->pstn_envelope = 0;
  544. } else if (j->daa_mode == SOP_PU_CONVERSATION) {
  545. if (!j->pstn_winkstart) {
  546. j->pstn_winkstart = jiffies;
  547. } else if (jiffies > j->pstn_winkstart + (hertz * j->winktime / 1000)) {
  548. daa_set_mode(board, SOP_PU_SLEEP);
  549. j->pstn_winkstart = 0;
  550. j->ex.bits.pstn_wink = 1;
  551. }
  552. } else {
  553. j->ex.bits.pstn_ring = 0;
  554. }
  555. }
  556. if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) {
  557. if (j->daa_mode == SOP_PU_RINGING) {
  558. daa_set_mode(board, SOP_PU_SLEEP);
  559. j->flags.pstn_ringing = 0;
  560. j->ex.bits.pstn_ring = 0;
  561. }
  562. }
  563. if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) {
  564. if (j->daa_mode == SOP_PU_RINGING && j->flags.pstn_ringing) {
  565. j->pstn_cid_intr = 1;
  566. j->pstn_cid_recieved = jiffies;
  567. }
  568. }
  569. } else {
  570. if (j->pld_scrr.bits.daaflag) {
  571. daa_int_read(board);
  572. }
  573. j->ex.bits.pstn_ring = 0;
  574. if (j->pstn_cid_intr && jiffies > j->pstn_cid_recieved + (hertz * 3)) {
  575. if (j->daa_mode == SOP_PU_RINGING) {
  576. ixj_daa_cid_read(board);
  577. j->ex.bits.caller_id = 1;
  578. }
  579. j->pstn_cid_intr = 0;
  580. } else {
  581. j->ex.bits.caller_id = 0;
  582. }
  583. if (!j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
  584. if (j->flags.pstn_ringing && j->pstn_envelope) {
  585. j->ex.bits.pstn_ring = 1;
  586. j->pstn_envelope = 0;
  587. } else if (j->daa_mode == SOP_PU_CONVERSATION) {
  588. if (!j->pstn_winkstart) {
  589. j->pstn_winkstart = jiffies;
  590. } else if (jiffies > j->pstn_winkstart + (hertz * 320 / 1000)) {
  591. daa_set_mode(board, SOP_PU_SLEEP);
  592. j->pstn_winkstart = 0;
  593. j->ex.bits.pstn_wink = 1;
  594. }
  595. }
  596. }
  597. }
  598. }
  599. }
  600. if ((j->ex.bits.f0 || j->ex.bits.f1 || j->ex.bits.f2 || j->ex.bits.f3)
  601.     && j->filter_cadence) {
  602. }
  603. if (j->ex.bytes) {
  604. wake_up_interruptible(&j->poll_q); // Wake any blocked selects
  605. if (j->async_queue)
  606. kill_fasync(j->async_queue, SIGIO); // Send apps notice of change
  607. }
  608. } else {
  609. break;
  610. }
  611. }
  612. }
  613.       timer_end:
  614. if (mutex == 1) {
  615. ixj_init_timer();
  616. mutex--;
  617. }
  618. }
  619. static int ixj_status_wait(int board)
  620. {
  621. unsigned long jif;
  622. jif = jiffies;
  623. while (!IsStatusReady(board)) {
  624. if (jiffies - jif > (60 * (hertz / 100))) {
  625. return -1;
  626. }
  627. }
  628. return 0;
  629. }
  630. int ixj_WriteDSPCommand(unsigned short cmd, int board)
  631. {
  632. BYTES bytes;
  633. unsigned long jif;
  634. bytes.high = (cmd & 0xFF00) >> 8;
  635. bytes.low = cmd & 0x00FF;
  636. jif = jiffies;
  637. while (!IsControlReady(board)) {
  638. if (jiffies - jif > (60 * (hertz / 100))) {
  639. return -1;
  640. }
  641. }
  642. outb_p(bytes.low, ixj[board].DSPbase + 6);
  643. outb_p(bytes.high, ixj[board].DSPbase + 7);
  644. if (ixj_status_wait(board)) {
  645. ixj[board].ssr.low = 0xFF;
  646. ixj[board].ssr.high = 0xFF;
  647. return -1;
  648. }
  649. /* Read Software Status Register */
  650. ixj[board].ssr.low = inb_p(ixj[board].DSPbase + 2);
  651. ixj[board].ssr.high = inb_p(ixj[board].DSPbase + 3);
  652. return 0;
  653. }
  654. /***************************************************************************
  655. *
  656. *  General Purpose IO Register read routine
  657. *
  658. ***************************************************************************/
  659. extern __inline__ int ixj_gpio_read(board)
  660. {
  661. if (ixj_WriteDSPCommand(0x5143, board))
  662. return -1;
  663. ixj[board].gpio.bytes.low = ixj[board].ssr.low;
  664. ixj[board].gpio.bytes.high = ixj[board].ssr.high;
  665. return 0;
  666. }
  667. extern __inline__ void LED_SetState(int state, int board)
  668. {
  669. if (ixj[board].dsp.low == 0x21) {
  670. ixj[board].pld_scrw.bits.led1 = state & 0x1 ? 1 : 0;
  671. ixj[board].pld_scrw.bits.led2 = state & 0x2 ? 1 : 0;
  672. ixj[board].pld_scrw.bits.led3 = state & 0x4 ? 1 : 0;
  673. ixj[board].pld_scrw.bits.led4 = state & 0x8 ? 1 : 0;
  674. outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
  675. }
  676. }
  677. /*********************************************************************
  678. *  GPIO Pins are configured as follows on the Quicknet Internet
  679. *  PhoneJACK Telephony Cards
  680. * POTS Select        GPIO_6=0 GPIO_7=0
  681. * Mic/Speaker Select GPIO_6=0 GPIO_7=1
  682. * Handset Select     GPIO_6=1 GPIO_7=0
  683. *
  684. * SLIC Active        GPIO_1=0 GPIO_2=1 GPIO_5=0
  685. * SLIC Ringing       GPIO_1=1 GPIO_2=1 GPIO_5=0
  686. * SLIC Open Circuit  GPIO_1=0 GPIO_2=0 GPIO_5=0
  687. *
  688. * Hook Switch changes reported on GPIO_3
  689. *********************************************************************/
  690. static int ixj_set_port(int board, int arg)
  691. {
  692. IXJ *j = &ixj[board];
  693. if (j->cardtype == 400) {
  694. if (arg != PORT_POTS)
  695. return 10;
  696. else
  697. return 0;
  698. }
  699. switch (arg) {
  700. case PORT_POTS:
  701. j->port = PORT_POTS;
  702. switch (j->cardtype) {
  703. case 500:
  704. j->pld_slicw.pcib.mic = 0;
  705. j->pld_slicw.pcib.spk = 0;
  706. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  707. break;
  708. case 300:
  709. if (ixj_WriteDSPCommand(0xC528, board)) /* Write CODEC config to
  710.    Software Control Register */
  711. return 2;
  712. j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
  713. outb_p(j->pld_scrw.byte, j->XILINXbase);
  714. j->pld_clock.byte = 0;
  715. outb_p(j->pld_clock.byte, j->XILINXbase + 0x04);
  716. j->pld_slicw.bits.rly1 = 1;
  717. j->pld_slicw.bits.spken = 0;
  718. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  719. SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
  720. break;
  721. case 100:
  722. j->gpio.bytes.high = 0x0B;
  723. j->gpio.bits.gpio6 = 0;
  724. j->gpio.bits.gpio7 = 0;
  725. ixj_WriteDSPCommand(j->gpio.word, board);
  726. break;
  727. }
  728. break;
  729. case PORT_PSTN:
  730. if (j->cardtype == 300) {
  731. ixj_WriteDSPCommand(0xC534, board); /* Write CODEC config to Software Control Register */
  732. j->pld_slicw.bits.rly3 = 0;
  733. j->pld_slicw.bits.rly1 = 1;
  734. j->pld_slicw.bits.spken = 0;
  735. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  736. j->port = PORT_PSTN;
  737. } else {
  738. return 4;
  739. }
  740. break;
  741. case PORT_SPEAKER:
  742. j->port = PORT_SPEAKER;
  743. switch (j->cardtype) {
  744. case 500:
  745. j->pld_slicw.pcib.mic = 1;
  746. j->pld_slicw.pcib.spk = 1;
  747. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  748. break;
  749. case 300:
  750. break;
  751. case 100:
  752. j->gpio.bytes.high = 0x0B;
  753. j->gpio.bits.gpio6 = 0;
  754. j->gpio.bits.gpio7 = 1;
  755. ixj_WriteDSPCommand(j->gpio.word, board);
  756. break;
  757. }
  758. break;
  759. case PORT_HANDSET:
  760. if (j->cardtype == 300 || j->cardtype == 500) {
  761. return 5;
  762. } else {
  763. j->gpio.bytes.high = 0x0B;
  764. j->gpio.bits.gpio6 = 1;
  765. j->gpio.bits.gpio7 = 0;
  766. ixj_WriteDSPCommand(j->gpio.word, board);
  767. j->port = PORT_HANDSET;
  768. }
  769. break;
  770. default:
  771. return 6;
  772. break;
  773. }
  774. return 0;
  775. }
  776. static int ixj_set_pots(int board, int arg)
  777. {
  778. IXJ *j = &ixj[board];
  779. if (j->cardtype == 300) {
  780. if (arg) {
  781. if (j->port == PORT_PSTN) {
  782. j->pld_slicw.bits.rly1 = 0;
  783. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  784. return 1;
  785. } else {
  786. return 0;
  787. }
  788. } else {
  789. j->pld_slicw.bits.rly1 = 1;
  790. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  791. return 1;
  792. }
  793. } else {
  794. return 0;
  795. }
  796. }
  797. static void ixj_ring_on(int board)
  798. {
  799. IXJ *j = &ixj[board];
  800. if (j->dsp.low == 0x20) // Internet PhoneJACK
  801.  {
  802. if (ixjdebug > 0)
  803. printk(KERN_INFO "IXJ Ring On /dev/ixj%dn", board);
  804. j->gpio.bytes.high = 0x0B;
  805. j->gpio.bytes.low = 0x00;
  806. j->gpio.bits.gpio1 = 1;
  807. j->gpio.bits.gpio2 = 1;
  808. j->gpio.bits.gpio5 = 0;
  809. ixj_WriteDSPCommand(j->gpio.word, board); /* send the ring signal */
  810. } else //  Internet LineJACK, Internet PhoneJACK Lite or
  811.               //  Internet PhoneJACK PCI
  812.  {
  813. if (ixjdebug > 0)
  814. printk(KERN_INFO "IXJ Ring On /dev/phone%dn", board);
  815. SLIC_SetState(PLD_SLIC_STATE_RINGING, board);
  816. }
  817. }
  818. static int ixj_hookstate(int board)
  819. {
  820. unsigned long det;
  821. IXJ *j = &ixj[board];
  822. int fOffHook = 0;
  823. switch (j->cardtype) {
  824. case 100:
  825. ixj_gpio_read(board);
  826. fOffHook = j->gpio.bits.gpio3read ? 1 : 0;
  827. break;
  828. case 300:
  829. case 400:
  830. case 500:
  831. SLIC_GetState(board);
  832. if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
  833.     j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
  834. if (j->flags.ringing) {
  835. det = jiffies + (hertz / 50);
  836. while (time_before(jiffies, det)) {
  837. current->state = TASK_INTERRUPTIBLE;
  838. schedule_timeout(1);
  839. }
  840. SLIC_GetState(board);
  841. if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
  842. ixj_ring_on(board);
  843. }
  844. }
  845. if (j->cardtype == 500) {
  846. j->pld_scrr.byte = inb_p(j->XILINXbase);
  847. fOffHook = j->pld_scrr.pcib.det ? 1 : 0;
  848. } else
  849. fOffHook = j->pld_slicr.bits.det ? 1 : 0;
  850. }
  851. break;
  852. }
  853. if (j->r_hook != fOffHook) {
  854. j->r_hook = fOffHook;
  855. if (j->port != PORT_POTS) {
  856. j->ex.bits.hookstate = 1;
  857. if (j->async_queue)
  858. kill_fasync(j->async_queue, SIGIO); // Send apps notice of change
  859. }
  860. }
  861. if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION)
  862. fOffHook |= 2;
  863. if (j->port == PORT_SPEAKER)
  864. fOffHook |= 2;
  865. if (j->port == PORT_HANDSET)
  866. fOffHook |= 2;
  867. return fOffHook;
  868. }
  869. static void ixj_ring_off(board)
  870. {
  871. IXJ *j = &ixj[board];
  872. if (j->dsp.low == 0x20) // Internet PhoneJACK
  873.  {
  874. if (ixjdebug > 0)
  875. printk(KERN_INFO "IXJ Ring Offn");
  876. j->gpio.bytes.high = 0x0B;
  877. j->gpio.bytes.low = 0x00;
  878. j->gpio.bits.gpio1 = 0;
  879. j->gpio.bits.gpio2 = 1;
  880. j->gpio.bits.gpio5 = 0;
  881. ixj_WriteDSPCommand(j->gpio.word, board);
  882. } else // Internet LineJACK
  883.  {
  884. if (ixjdebug > 0)
  885. printk(KERN_INFO "IXJ Ring Offn");
  886. SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
  887. SLIC_GetState(board);
  888. }
  889. }
  890. static void ixj_ring_start(board)
  891. {
  892. IXJ *j = &ixj[board];
  893. j->flags.cringing = 1;
  894. if (ixj_hookstate(board) & 1) {
  895. if (j->port == PORT_POTS)
  896. ixj_ring_off(board);
  897. j->flags.cringing = 0;
  898. } else {
  899. j->ring_cadence_jif = jiffies;
  900. j->ring_cadence_t = 15;
  901. if (j->ring_cadence & 1 << j->ring_cadence_t) {
  902. ixj_ring_on(board);
  903. } else {
  904. ixj_ring_off(board);
  905. }
  906. }
  907. }
  908. static int ixj_ring(board)
  909. {
  910. char cntr;
  911. unsigned long jif, det;
  912. IXJ *j = &ixj[board];
  913. j->flags.ringing = 1;
  914. if (ixj_hookstate(board) & 1) {
  915. ixj_ring_off(board);
  916. j->flags.ringing = 0;
  917. return 1;
  918. }
  919. det = 0;
  920. for (cntr = 0; cntr < j->maxrings; cntr++) {
  921. jif = jiffies + (1 * hertz);
  922. ixj_ring_on(board);
  923. while (time_before(jiffies, jif)) {
  924. if (ixj_hookstate(board) & 1) {
  925. ixj_ring_off(board);
  926. j->flags.ringing = 0;
  927. return 1;
  928. }
  929. current->state = TASK_INTERRUPTIBLE;
  930. schedule_timeout(1);
  931. }
  932. jif = jiffies + (3 * hertz);
  933. ixj_ring_off(board);
  934. while (time_before(jiffies, jif)) {
  935. if (ixj_hookstate(board) & 1) {
  936. det = jiffies + (hertz / 100);
  937. while (time_before(jiffies, det)) {
  938. current->state = TASK_INTERRUPTIBLE;
  939. schedule_timeout(1);
  940. }
  941. if (ixj_hookstate(board) & 1) {
  942. j->flags.ringing = 0;
  943. return 1;
  944. }
  945. }
  946. current->state = TASK_INTERRUPTIBLE;
  947. schedule_timeout(1);
  948. }
  949. }
  950. ixj_ring_off(board);
  951. j->flags.ringing = 0;
  952. return 0;
  953. }
  954. int ixj_open(struct phone_device *p, struct file *file_p)
  955. {
  956. IXJ *j = &ixj[p->board];
  957. if (!j->DSPbase)
  958. return -ENODEV;
  959. if (file_p->f_mode & FMODE_READ)
  960. j->readers++;
  961. if (file_p->f_mode & FMODE_WRITE)
  962. j->writers++;
  963. MOD_INC_USE_COUNT;
  964. if (ixjdebug > 0)
  965. //    printk(KERN_INFO "Opening board %dn", NUM(inode->i_rdev));
  966. printk(KERN_INFO "Opening board %dn", p->board);
  967. return 0;
  968. }
  969. int ixj_release(struct inode *inode, struct file *file_p)
  970. {
  971. IXJ_TONE ti;
  972. int board = NUM(inode->i_rdev);
  973. IXJ *j = &ixj[board];
  974. if (ixjdebug > 0)
  975. printk(KERN_INFO "Closing board %dn", NUM(inode->i_rdev));
  976. daa_set_mode(board, SOP_PU_SLEEP);
  977. ixj_set_port(board, PORT_POTS);
  978. aec_stop(board);
  979. ixj_play_stop(board);
  980. ixj_record_stop(board);
  981. ti.tone_index = 10;
  982. ti.gain0 = 1;
  983. ti.freq0 = hz941;
  984. ti.gain1 = 0;
  985. ti.freq1 = hz1209;
  986. ti.tone_index = 11;
  987. ti.gain0 = 1;
  988. ti.freq0 = hz941;
  989. ti.gain1 = 0;
  990. ti.freq1 = hz1336;
  991. ti.tone_index = 12;
  992. ti.gain0 = 1;
  993. ti.freq0 = hz941;
  994. ti.gain1 = 0;
  995. ti.freq1 = hz1477;
  996. ti.tone_index = 13;
  997. ti.gain0 = 1;
  998. ti.freq0 = hz800;
  999. ti.gain1 = 0;
  1000. ti.freq1 = 0;
  1001. ixj_init_tone(board, &ti);
  1002. ti.tone_index = 14;
  1003. ti.gain0 = 1;
  1004. ti.freq0 = hz1000;
  1005. ti.gain1 = 0;
  1006. ti.freq1 = 0;
  1007. ixj_init_tone(board, &ti);
  1008. ti.tone_index = 15;
  1009. ti.gain0 = 1;
  1010. ti.freq0 = hz1250;
  1011. ti.gain1 = 0;
  1012. ti.freq1 = 0;
  1013. ixj_init_tone(board, &ti);
  1014. ti.tone_index = 16;
  1015. ti.gain0 = 1;
  1016. ti.freq0 = hz950;
  1017. ti.gain1 = 0;
  1018. ti.freq1 = 0;
  1019. ixj_init_tone(board, &ti);
  1020. ti.tone_index = 17;
  1021. ti.gain0 = 1;
  1022. ti.freq0 = hz1100;
  1023. ti.gain1 = 0;
  1024. ti.freq1 = 0;
  1025. ixj_init_tone(board, &ti);
  1026. ti.tone_index = 18;
  1027. ti.gain0 = 1;
  1028. ti.freq0 = hz1400;
  1029. ti.gain1 = 0;
  1030. ti.freq1 = 0;
  1031. ixj_init_tone(board, &ti);
  1032. ti.tone_index = 19;
  1033. ti.gain0 = 1;
  1034. ti.freq0 = hz1500;
  1035. ti.gain1 = 0;
  1036. ti.freq1 = 0;
  1037. ixj_init_tone(board, &ti);
  1038. ti.tone_index = 20;
  1039. ti.gain0 = 1;
  1040. ti.freq0 = hz1600;
  1041. ti.gain1 = 0;
  1042. ti.freq1 = 0;
  1043. ixj_init_tone(board, &ti);
  1044. ti.tone_index = 21;
  1045. ti.gain0 = 1;
  1046. ti.freq0 = hz1800;
  1047. ti.gain1 = 0;
  1048. ti.freq1 = 0;
  1049. ixj_init_tone(board, &ti);
  1050. ti.tone_index = 22;
  1051. ti.gain0 = 1;
  1052. ti.freq0 = hz2100;
  1053. ti.gain1 = 0;
  1054. ti.freq1 = 0;
  1055. ixj_init_tone(board, &ti);
  1056. ti.tone_index = 23;
  1057. ti.gain0 = 1;
  1058. ti.freq0 = hz1300;
  1059. ti.gain1 = 0;
  1060. ti.freq1 = 0;
  1061. ixj_init_tone(board, &ti);
  1062. ti.tone_index = 24;
  1063. ti.gain0 = 1;
  1064. ti.freq0 = hz2450;
  1065. ti.gain1 = 0;
  1066. ti.freq1 = 0;
  1067. ixj_init_tone(board, &ti);
  1068. ti.tone_index = 25;
  1069. ti.gain0 = 1;
  1070. ti.freq0 = hz350;
  1071. ti.gain1 = 0;
  1072. ti.freq1 = hz440;
  1073. ixj_init_tone(board, &ti);
  1074. ti.tone_index = 26;
  1075. ti.gain0 = 1;
  1076. ti.freq0 = hz440;
  1077. ti.gain1 = 0;
  1078. ti.freq1 = hz480;
  1079. ixj_init_tone(board, &ti);
  1080. ti.tone_index = 27;
  1081. ti.gain0 = 1;
  1082. ti.freq0 = hz480;
  1083. ti.gain1 = 0;
  1084. ti.freq1 = hz620;
  1085. ixj_init_tone(board, &ti);
  1086. idle(board);
  1087. if (file_p->f_mode & FMODE_READ)
  1088. j->readers--;
  1089. if (file_p->f_mode & FMODE_WRITE)
  1090. j->writers--;
  1091. if (j->read_buffer && !j->readers) {
  1092. kfree(j->read_buffer);
  1093. j->read_buffer = NULL;
  1094. j->read_buffer_size = 0;
  1095. }
  1096. if (j->write_buffer && !j->writers) {
  1097. kfree(j->write_buffer);
  1098. j->write_buffer = NULL;
  1099. j->write_buffer_size = 0;
  1100. }
  1101. j->rec_codec = j->play_codec = 0;
  1102. j->rec_frame_size = j->play_frame_size = 0;
  1103. ixj_fasync(-1, file_p, 0); // remove from list of async notification
  1104. MOD_DEC_USE_COUNT;
  1105. return 0;
  1106. }
  1107. static int read_filters(int board)
  1108. {
  1109. unsigned short fc, cnt;
  1110. IXJ *j = &ixj[board];
  1111. if (ixj_WriteDSPCommand(0x5144, board))
  1112. return -1;
  1113. fc = j->ssr.high << 8 | j->ssr.low;
  1114. if (fc == j->frame_count)
  1115. return 1;
  1116. j->frame_count = fc;
  1117. for (cnt = 0; cnt < 4; cnt++) {
  1118. if (ixj_WriteDSPCommand(0x5154 + cnt, board))
  1119. return -1;
  1120. if (ixj_WriteDSPCommand(0x515C, board))
  1121. return -1;
  1122. j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low;
  1123. if ((j->filter_hist[cnt] & 1 && !(j->filter_hist[cnt] & 2)) ||
  1124. (j->filter_hist[cnt] & 2 && !(j->filter_hist[cnt] & 1))) {
  1125. switch (cnt) {
  1126. case 0:
  1127. j->ex.bits.f0 = 1;
  1128. break;
  1129. case 1:
  1130. j->ex.bits.f1 = 1;
  1131. break;
  1132. case 2:
  1133. j->ex.bits.f2 = 1;
  1134. break;
  1135. case 3:
  1136. j->ex.bits.f3 = 1;
  1137. break;
  1138. }
  1139. }
  1140. }
  1141. return 0;
  1142. }
  1143. static int LineMonitor(int board)
  1144. {
  1145. IXJ *j = &ixj[board];
  1146. if (j->dtmf_proc) {
  1147. return -1;
  1148. }
  1149. j->dtmf_proc = 1;
  1150. if (ixj_WriteDSPCommand(0x7000, board)) // Line Monitor
  1151. return -1;
  1152. j->dtmf.bytes.high = j->ssr.high;
  1153. j->dtmf.bytes.low = j->ssr.low;
  1154. if (!j->dtmf_state && j->dtmf.bits.dtmf_valid) {
  1155. j->dtmf_state = 1;
  1156. j->dtmf_current = j->dtmf.bits.digit;
  1157. }
  1158. if (j->dtmf_state && !j->dtmf.bits.dtmf_valid) // && j->dtmf_wp != j->dtmf_rp)
  1159.  {
  1160. j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current;
  1161. j->dtmf_wp++;
  1162. if (j->dtmf_wp == 79)
  1163. j->dtmf_wp = 0;
  1164. j->ex.bits.dtmf_ready = 1;
  1165. j->dtmf_state = 0;
  1166. }
  1167. j->dtmf_proc = 0;
  1168. return 0;
  1169. }
  1170. ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
  1171. {
  1172. unsigned long i = *ppos;
  1173. IXJ *j = &ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
  1174. struct wait_queue wait =
  1175. {current, NULL};
  1176. add_wait_queue(&j->read_q, &wait);
  1177. current->state = TASK_INTERRUPTIBLE;
  1178. mb();
  1179. while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) {
  1180. ++j->read_wait;
  1181. if (file_p->f_flags & O_NONBLOCK) {
  1182. current->state = TASK_RUNNING;
  1183. remove_wait_queue(&j->read_q, &wait);
  1184. return -EAGAIN;
  1185. }
  1186. if (!ixj_hookstate(NUM(file_p->f_dentry->d_inode->i_rdev))) {
  1187. current->state = TASK_RUNNING;
  1188. remove_wait_queue(&j->read_q, &wait);
  1189. return 0;
  1190. }
  1191. interruptible_sleep_on(&j->read_q);
  1192. if (signal_pending(current)) {
  1193. current->state = TASK_RUNNING;
  1194. remove_wait_queue(&j->read_q, &wait);
  1195. return -EINTR;
  1196. }
  1197. }
  1198. remove_wait_queue(&j->read_q, &wait);
  1199. current->state = TASK_RUNNING;
  1200. /* Don't ever copy more than the user asks */
  1201. i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size));
  1202. j->read_buffer_ready = 0;
  1203. if (i)
  1204. return -EFAULT;
  1205. else
  1206. return min(length, j->read_buffer_size);
  1207. }
  1208. ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
  1209.   loff_t * ppos)
  1210. {
  1211. int pre_retval;
  1212. ssize_t read_retval = 0;
  1213. IXJ *j = &ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
  1214. pre_retval = ixj_PreRead(j, 0L);
  1215. switch (pre_retval) {
  1216. case NORMAL:
  1217. read_retval = ixj_read(file_p, buf, length, ppos);
  1218. ixj_PostRead(j, 0L);
  1219. break;
  1220. case NOPOST:
  1221. read_retval = ixj_read(file_p, buf, length, ppos);
  1222. break;
  1223. case POSTONLY:
  1224. ixj_PostRead(j, 0L);
  1225. break;
  1226. default:
  1227. read_retval = pre_retval;
  1228. }
  1229. return read_retval;
  1230. }
  1231. ssize_t ixj_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
  1232. {
  1233. unsigned long i = *ppos;
  1234. int board = NUM(file_p->f_dentry->d_inode->i_rdev);
  1235. IXJ *j = &ixj[board];
  1236. struct wait_queue wait =
  1237. {current, NULL};
  1238. add_wait_queue(&j->read_q, &wait);
  1239. current->state = TASK_INTERRUPTIBLE;
  1240. mb();
  1241. while (!j->write_buffers_empty) {
  1242. ++j->write_wait;
  1243. if (file_p->f_flags & O_NONBLOCK) {
  1244. current->state = TASK_RUNNING;
  1245. remove_wait_queue(&j->read_q, &wait);
  1246. return -EAGAIN;
  1247. }
  1248. if (!ixj_hookstate(NUM(file_p->f_dentry->d_inode->i_rdev))) {
  1249. current->state = TASK_RUNNING;
  1250. remove_wait_queue(&j->read_q, &wait);
  1251. return 0;
  1252. }
  1253. interruptible_sleep_on(&j->write_q);
  1254. if (signal_pending(current)) {
  1255. current->state = TASK_RUNNING;
  1256. remove_wait_queue(&j->read_q, &wait);
  1257. return -EINTR;
  1258. }
  1259. }
  1260. current->state = TASK_RUNNING;
  1261. remove_wait_queue(&j->read_q, &wait);
  1262. if (j->write_buffer_wp + count >= j->write_buffer_end)
  1263. j->write_buffer_wp = j->write_buffer;
  1264. i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size));
  1265. if (i)
  1266. return -EFAULT;
  1267. return min(count, j->write_buffer_size);
  1268. }
  1269. ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count,
  1270.    loff_t * ppos)
  1271. {
  1272. int pre_retval;
  1273. ssize_t write_retval = 0;
  1274. IXJ *j = &ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
  1275. pre_retval = ixj_PreWrite(j, 0L);
  1276. switch (pre_retval) {
  1277. case NORMAL:
  1278. write_retval = ixj_write(file_p, buf, count, ppos);
  1279. if (write_retval != -EFAULT) {
  1280. ixj_PostWrite(j, 0L);
  1281. j->write_buffer_wp += count;
  1282. j->write_buffers_empty--;
  1283. }
  1284. break;
  1285. case NOPOST:
  1286. write_retval = ixj_write(file_p, buf, count, ppos);
  1287. if (write_retval != -EFAULT) {
  1288. j->write_buffer_wp += count;
  1289. j->write_buffers_empty--;
  1290. }
  1291. break;
  1292. case POSTONLY:
  1293. ixj_PostWrite(j, 0L);
  1294. break;
  1295. default:
  1296. write_retval = pre_retval;
  1297. }
  1298. return write_retval;
  1299. }
  1300. static void ixj_read_frame(int board)
  1301. {
  1302. int cnt, dly;
  1303. IXJ *j = &ixj[board];
  1304. if (j->read_buffer) {
  1305. for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
  1306. if (!(cnt % 16) && !IsRxReady(board)) {
  1307. dly = 0;
  1308. while (!IsRxReady(board)) {
  1309. if (dly++ > 5) {
  1310. dly = 0;
  1311. break;
  1312. }
  1313. udelay(10);
  1314. }
  1315. }
  1316. // Throw away word 0 of the 8021 compressed format to get standard G.729.
  1317. if (j->rec_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) {
  1318. inb_p(j->DSPbase + 0x0E);
  1319. inb_p(j->DSPbase + 0x0F);
  1320. }
  1321. *(j->read_buffer + cnt) = inb_p(j->DSPbase + 0x0E);
  1322. *(j->read_buffer + cnt + 1) = inb_p(j->DSPbase + 0x0F);
  1323. }
  1324. #ifdef PERFMON_STATS
  1325. ++j->framesread;
  1326. #endif
  1327. if (j->intercom != -1) {
  1328. if (IsTxReady(j->intercom)) {
  1329. for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
  1330. if (!(cnt % 16) && !IsTxReady(board)) {
  1331. dly = 0;
  1332. while (!IsTxReady(board)) {
  1333. if (dly++ > 5) {
  1334. dly = 0;
  1335. break;
  1336. }
  1337. udelay(10);
  1338. }
  1339. }
  1340. outb_p(*(j->read_buffer + cnt), ixj[j->intercom].DSPbase + 0x0C);
  1341. outb_p(*(j->read_buffer + cnt + 1), ixj[j->intercom].DSPbase + 0x0D);
  1342. }
  1343. #ifdef PERFMON_STATS
  1344. ++ixj[j->intercom].frameswritten;
  1345. #endif
  1346. }
  1347. } else {
  1348. j->read_buffer_ready = 1;
  1349. wake_up_interruptible(&j->read_q); // Wake any blocked readers
  1350. wake_up_interruptible(&j->poll_q); // Wake any blocked selects
  1351. if (j->async_queue)
  1352. kill_fasync(j->async_queue, SIGIO); // Send apps notice of frame
  1353. }
  1354. }
  1355. }
  1356. static void ixj_write_frame(int board)
  1357. {
  1358. int cnt, frame_count, dly;
  1359. BYTES blankword;
  1360. IXJ *j = &ixj[board];
  1361. frame_count = 0;
  1362. if (j->write_buffer && j->write_buffers_empty < 2) {
  1363. if (j->write_buffer_wp > j->write_buffer_rp) {
  1364. frame_count =
  1365.     (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2);
  1366. }
  1367. if (j->write_buffer_rp > j->write_buffer_wp) {
  1368. frame_count =
  1369.     (j->write_buffer_wp - j->write_buffer) / (j->play_frame_size * 2) +
  1370.     (j->write_buffer_end - j->write_buffer_rp) / (j->play_frame_size * 2);
  1371. }
  1372. if (frame_count >= 1) {
  1373. if (j->ver.low == 0x12 && j->play_mode && j->flags.play_first_frame) {
  1374. switch (j->play_mode) {
  1375. case PLAYBACK_MODE_ULAW:
  1376. case PLAYBACK_MODE_ALAW:
  1377. blankword.low = blankword.high = 0xFF;
  1378. break;
  1379. case PLAYBACK_MODE_8LINEAR:
  1380. case PLAYBACK_MODE_16LINEAR:
  1381. blankword.low = blankword.high = 0x00;
  1382. break;
  1383. case PLAYBACK_MODE_8LINEAR_WSS:
  1384. blankword.low = blankword.high = 0x80;
  1385. break;
  1386. }
  1387. for (cnt = 0; cnt < 16; cnt++) {
  1388. if (!(cnt % 16) && !IsTxReady(board)) {
  1389. dly = 0;
  1390. while (!IsTxReady(board)) {
  1391. if (dly++ > 5) {
  1392. dly = 0;
  1393. break;
  1394. }
  1395. udelay(10);
  1396. }
  1397. }
  1398. outb_p((blankword.low), j->DSPbase + 0x0C);
  1399. outb_p((blankword.high), j->DSPbase + 0x0D);
  1400. }
  1401. j->flags.play_first_frame = 0;
  1402. }
  1403. for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) {
  1404. if (!(cnt % 16) && !IsTxReady(board)) {
  1405. dly = 0;
  1406. while (!IsTxReady(board)) {
  1407. if (dly++ > 5) {
  1408. dly = 0;
  1409. break;
  1410. }
  1411. udelay(10);
  1412. }
  1413. }
  1414. // Add word 0 to G.729 frames for the 8021.  Right now we don't do VAD/CNG 
  1415. // so all frames are type 1.
  1416. if (j->play_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) {
  1417. outb_p(0x01, j->DSPbase + 0x0C);
  1418. outb_p(0x00, j->DSPbase + 0x0D);
  1419. }
  1420. outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C);
  1421. outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D);
  1422. *(j->write_buffer_rp + cnt) = 0;
  1423. *(j->write_buffer_rp + cnt + 1) = 0;
  1424. }
  1425. j->write_buffer_rp += j->play_frame_size * 2;
  1426. if (j->write_buffer_rp >= j->write_buffer_end) {
  1427. j->write_buffer_rp = j->write_buffer;
  1428. }
  1429. j->write_buffers_empty++;
  1430. wake_up_interruptible(&(j->write_q)); // Wake any blocked writers
  1431. wake_up_interruptible(&j->poll_q); // Wake any blocked selects
  1432. if (j->async_queue)
  1433. kill_fasync(j->async_queue, SIGIO); // Send apps notice of empty buffer
  1434. #ifdef PERFMON_STATS
  1435. ++j->frameswritten;
  1436. #endif
  1437. }
  1438. } else {
  1439. j->drybuffer++;
  1440. }
  1441. }
  1442. static int idle(int board)
  1443. {
  1444. IXJ *j = &ixj[board];
  1445. if (ixj_WriteDSPCommand(0x0000, board)) // DSP Idle
  1446. return 0;
  1447. if (j->ssr.high || j->ssr.low)
  1448. return 0;
  1449. else
  1450. return 1;
  1451. }
  1452. static int set_base_frame(int board, int size)
  1453. {
  1454. unsigned short cmd;
  1455. int cnt;
  1456. IXJ *j = &ixj[board];
  1457. aec_stop(board);
  1458. for (cnt = 0; cnt < 10; cnt++) {
  1459. if (idle(board))
  1460. break;
  1461. }
  1462. if (j->ssr.high || j->ssr.low)
  1463. return -1;
  1464. if (j->dsp.low != 0x20) {
  1465. switch (size) {
  1466. case 30:
  1467. cmd = 0x07F0;
  1468. /* Set Base Frame Size to 240 pg9-10 8021 */
  1469. break;
  1470. case 20:
  1471. cmd = 0x07A0;
  1472. /* Set Base Frame Size to 160 pg9-10 8021 */
  1473. break;
  1474. case 10:
  1475. cmd = 0x0750;
  1476. /* Set Base Frame Size to 80 pg9-10 8021 */
  1477. break;
  1478. default:
  1479. return -1;
  1480. }
  1481. } else {
  1482. if (size == 30)
  1483. return size;
  1484. else
  1485. return -1;
  1486. }
  1487. if (ixj_WriteDSPCommand(cmd, board)) {
  1488. j->baseframe.high = j->baseframe.low = 0xFF;
  1489. return -1;
  1490. } else {
  1491. j->baseframe.high = j->ssr.high;
  1492. j->baseframe.low = j->ssr.low;
  1493. }
  1494. return size;
  1495. }
  1496. static int set_rec_codec(int board, int rate)
  1497. {
  1498. int retval = 0;
  1499. IXJ *j = &ixj[board];
  1500. j->rec_codec = rate;
  1501. switch (rate) {
  1502. case G723_63:
  1503. if (j->ver.low != 0x12 || ixj_convert_loaded) {
  1504. j->rec_frame_size = 12;
  1505. j->rec_mode = 0;
  1506. } else {
  1507. retval = 1;
  1508. }
  1509. break;
  1510. case G723_53:
  1511. if (j->ver.low != 0x12 || ixj_convert_loaded) {
  1512. j->rec_frame_size = 10;
  1513. j->rec_mode = 0;
  1514. } else {
  1515. retval = 1;
  1516. }
  1517. break;
  1518. case TS85:
  1519. if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
  1520. j->rec_frame_size = 16;
  1521. j->rec_mode = 0;
  1522. } else {
  1523. retval = 1;
  1524. }
  1525. break;
  1526. case TS48:
  1527. if (j->ver.low != 0x12 || ixj_convert_loaded) {
  1528. j->rec_frame_size = 9;
  1529. j->rec_mode = 0;
  1530. } else {
  1531. retval = 1;
  1532. }
  1533. break;
  1534. case TS41:
  1535. if (j->ver.low != 0x12 || ixj_convert_loaded) {
  1536. j->rec_frame_size = 8;
  1537. j->rec_mode = 0;
  1538. } else {
  1539. retval = 1;
  1540. }
  1541. break;
  1542. case G728:
  1543. if (j->dsp.low != 0x20) {
  1544. j->rec_frame_size = 48;
  1545. j->rec_mode = 0;
  1546. } else {
  1547. retval = 1;
  1548. }
  1549. break;
  1550. case G729:
  1551. if (j->dsp.low != 0x20) {
  1552. if (!j->flags.g729_loaded) {
  1553. retval = 1;
  1554. break;
  1555. }
  1556. switch (j->baseframe.low) {
  1557. case 0xA0:
  1558. j->rec_frame_size = 10;
  1559. break;
  1560. case 0x50:
  1561. j->rec_frame_size = 5;
  1562. break;
  1563. default:
  1564. j->rec_frame_size = 15;
  1565. break;
  1566. }
  1567. j->rec_mode = 0;
  1568. } else {
  1569. retval = 1;
  1570. }
  1571. break;
  1572. case ULAW:
  1573. switch (j->baseframe.low) {
  1574. case 0xA0:
  1575. j->rec_frame_size = 80;
  1576. break;
  1577. case 0x50:
  1578. j->rec_frame_size = 40;
  1579. break;
  1580. default:
  1581. j->rec_frame_size = 120;
  1582. break;
  1583. }
  1584. j->rec_mode = 4;
  1585. break;
  1586. case ALAW:
  1587. switch (j->baseframe.low) {
  1588. case 0xA0:
  1589. j->rec_frame_size = 80;
  1590. break;
  1591. case 0x50:
  1592. j->rec_frame_size = 40;
  1593. break;
  1594. default:
  1595. j->rec_frame_size = 120;
  1596. break;
  1597. }
  1598. j->rec_mode = 4;
  1599. break;
  1600. case LINEAR16:
  1601. switch (j->baseframe.low) {
  1602. case 0xA0:
  1603. j->rec_frame_size = 160;
  1604. break;
  1605. case 0x50:
  1606. j->rec_frame_size = 80;
  1607. break;
  1608. default:
  1609. j->rec_frame_size = 240;
  1610. break;
  1611. }
  1612. j->rec_mode = 5;
  1613. break;
  1614. case LINEAR8:
  1615. switch (j->baseframe.low) {
  1616. case 0xA0:
  1617. j->rec_frame_size = 80;
  1618. break;
  1619. case 0x50:
  1620. j->rec_frame_size = 40;
  1621. break;
  1622. default:
  1623. j->rec_frame_size = 120;
  1624. break;
  1625. }
  1626. j->rec_mode = 6;
  1627. break;
  1628. case WSS:
  1629. switch (j->baseframe.low) {
  1630. case 0xA0:
  1631. j->rec_frame_size = 80;
  1632. break;
  1633. case 0x50:
  1634. j->rec_frame_size = 40;
  1635. break;
  1636. default:
  1637. j->rec_frame_size = 120;
  1638. break;
  1639. }
  1640. j->rec_mode = 7;
  1641. break;
  1642. default:
  1643. j->rec_frame_size = 0;
  1644. j->rec_mode = -1;
  1645. if (j->read_buffer) {
  1646. kfree(j->read_buffer);
  1647. j->read_buffer = NULL;
  1648. j->read_buffer_size = 0;
  1649. }
  1650. retval = 1;
  1651. break;
  1652. }
  1653. return retval;
  1654. }
  1655. static int ixj_record_start(int board)
  1656. {
  1657. unsigned short cmd = 0x0000;
  1658. IXJ *j = &ixj[board];
  1659. if (!j->rec_mode) {
  1660. switch (j->rec_codec) {
  1661. case G723_63:
  1662. cmd = 0x5131;
  1663. break;
  1664. case G723_53:
  1665. cmd = 0x5132;
  1666. break;
  1667. case TS85:
  1668. cmd = 0x5130; // TrueSpeech 8.5
  1669. break;
  1670. case TS48:
  1671. cmd = 0x5133; // TrueSpeech 4.8
  1672. break;
  1673. case TS41:
  1674. cmd = 0x5134; // TrueSpeech 4.1
  1675. break;
  1676. case G728:
  1677. cmd = 0x5135;
  1678. break;
  1679. case G729:
  1680. cmd = 0x5136;
  1681. break;
  1682. default:
  1683. return 1;
  1684. }
  1685. if (ixj_WriteDSPCommand(cmd, board))
  1686. return -1;
  1687. }
  1688. if (!j->read_buffer) {
  1689. if (!j->read_buffer)
  1690. j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_KERNEL);
  1691. if (!j->read_buffer) {
  1692. printk("Read buffer allocation for ixj board %d failed!n", board);
  1693. return -ENOMEM;
  1694. }
  1695. }
  1696. j->read_buffer_size = j->rec_frame_size * 2;
  1697. if (ixj_WriteDSPCommand(0x5102, board)) // Set Poll sync mode
  1698. return -1;
  1699. switch (j->rec_mode) {
  1700. case 0:
  1701. cmd = 0x1C03; // Record C1
  1702. break;
  1703. case 4:
  1704. if (j->ver.low == 0x12) {
  1705. cmd = 0x1E03; // Record C1
  1706. } else {
  1707. cmd = 0x1E01; // Record C1
  1708. }
  1709. break;
  1710. case 5:
  1711. if (j->ver.low == 0x12) {
  1712. cmd = 0x1E83; // Record C1
  1713. } else {
  1714. cmd = 0x1E81; // Record C1
  1715. }
  1716. break;
  1717. case 6:
  1718. if (j->ver.low == 0x12) {
  1719. cmd = 0x1F03; // Record C1
  1720. } else {
  1721. cmd = 0x1F01; // Record C1
  1722. }
  1723. break;
  1724. case 7:
  1725. if (j->ver.low == 0x12) {
  1726. cmd = 0x1F83; // Record C1
  1727. } else {
  1728. cmd = 0x1F81; // Record C1
  1729. }
  1730. break;
  1731. }
  1732. if (ixj_WriteDSPCommand(cmd, board))
  1733. return -1;
  1734. return 0;
  1735. }
  1736. static void ixj_record_stop(int board)
  1737. {
  1738. IXJ *j = &ixj[board];
  1739. if (j->rec_mode > -1) {
  1740. ixj_WriteDSPCommand(0x5120, board);
  1741. j->rec_mode = -1;
  1742. }
  1743. }
  1744. static void set_rec_depth(int board, int depth)
  1745. {
  1746. if (depth > 60)
  1747. depth = 60;
  1748. if (depth < 0)
  1749. depth = 0;
  1750. ixj_WriteDSPCommand(0x5180 + depth, board);
  1751. }
  1752. static void set_rec_volume(int board, int volume)
  1753. {
  1754. ixj_WriteDSPCommand(0xCF03, board);
  1755. ixj_WriteDSPCommand(volume, board);
  1756. }
  1757. static int get_rec_level(int board)
  1758. {
  1759. IXJ *j = &ixj[board];
  1760. ixj_WriteDSPCommand(0xCF88, board);
  1761. return j->ssr.high << 8 | j->ssr.low;
  1762. }
  1763. static void ixj_aec_start(int board, int level)
  1764. {
  1765. IXJ *j = &ixj[board];
  1766. j->aec_level = level;
  1767. if (!level) {
  1768. ixj_WriteDSPCommand(0xB002, board);
  1769. } else {
  1770. if (j->rec_codec == G729 || j->play_codec == G729) {
  1771. ixj_WriteDSPCommand(0xE022, board); // Move AEC filter buffer
  1772. ixj_WriteDSPCommand(0x0300, board);
  1773. }
  1774. ixj_WriteDSPCommand(0xB001, board); // AEC On
  1775. ixj_WriteDSPCommand(0xE013, board); // Advanced AEC C1
  1776. switch (level) {
  1777. case 1:
  1778. ixj_WriteDSPCommand(0x0000, board); // Advanced AEC C2 = off
  1779. ixj_WriteDSPCommand(0xE011, board);
  1780. ixj_WriteDSPCommand(0xFFFF, board);
  1781. break;
  1782. case 2:
  1783. ixj_WriteDSPCommand(0x0600, board); // Advanced AEC C2 = on medium
  1784. ixj_WriteDSPCommand(0xE011, board);
  1785. ixj_WriteDSPCommand(0x0080, board);
  1786. break;
  1787. case 3:
  1788. ixj_WriteDSPCommand(0x0C00, board); // Advanced AEC C2 = on high
  1789. ixj_WriteDSPCommand(0xE011, board);
  1790. ixj_WriteDSPCommand(0x0080, board);
  1791. break;
  1792. }
  1793. }
  1794. }
  1795. static void aec_stop(int board)
  1796. {
  1797. IXJ *j = &ixj[board];
  1798. if (j->rec_codec == G729 || j->play_codec == G729) {
  1799. ixj_WriteDSPCommand(0xE022, board); // Move AEC filter buffer back
  1800. ixj_WriteDSPCommand(0x0700, board);
  1801. }
  1802. if (ixj[board].play_mode != -1 && ixj[board].rec_mode != -1);
  1803. {
  1804. ixj_WriteDSPCommand(0xB002, board); // AEC Stop
  1805. }
  1806. }
  1807. static int set_play_codec(int board, int rate)
  1808. {
  1809. int retval = 0;
  1810. IXJ *j = &ixj[board];
  1811. j->play_codec = rate;
  1812. switch (rate) {
  1813. case G723_63:
  1814. if (j->ver.low != 0x12 || ixj_convert_loaded) {
  1815. j->play_frame_size = 12;
  1816. j->play_mode = 0;
  1817. } else {
  1818. retval = 1;
  1819. }
  1820. break;
  1821. case G723_53:
  1822. if (j->ver.low != 0x12 || ixj_convert_loaded) {
  1823. j->play_frame_size = 10;
  1824. j->play_mode = 0;
  1825. } else {
  1826. retval = 1;
  1827. }
  1828. break;
  1829. case TS85:
  1830. if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
  1831. j->play_frame_size = 16;
  1832. j->play_mode = 0;
  1833. } else {
  1834. retval = 1;
  1835. }
  1836. break;
  1837. case TS48:
  1838. if (j->ver.low != 0x12 || ixj_convert_loaded) {
  1839. j->play_frame_size = 9;
  1840. j->play_mode = 0;
  1841. } else {
  1842. retval = 1;
  1843. }
  1844. break;
  1845. case TS41:
  1846. if (j->ver.low != 0x12 || ixj_convert_loaded) {
  1847. j->play_frame_size = 8;
  1848. j->play_mode = 0;
  1849. } else {
  1850. retval = 1;
  1851. }
  1852. break;
  1853. case G728:
  1854. if (j->dsp.low != 0x20) {
  1855. j->play_frame_size = 48;
  1856. j->play_mode = 0;
  1857. } else {
  1858. retval = 1;
  1859. }
  1860. break;
  1861. case G729:
  1862. if (j->dsp.low != 0x20) {
  1863. if (!j->flags.g729_loaded) {
  1864. retval = 1;
  1865. break;
  1866. }
  1867. switch (j->baseframe.low) {
  1868. case 0xA0:
  1869. j->play_frame_size = 10;
  1870. break;
  1871. case 0x50:
  1872. j->play_frame_size = 5;
  1873. break;
  1874. default:
  1875. j->play_frame_size = 15;
  1876. break;
  1877. }
  1878. j->play_mode = 0;
  1879. } else {
  1880. retval = 1;
  1881. }
  1882. break;
  1883. case ULAW:
  1884. switch (j->baseframe.low) {
  1885. case 0xA0:
  1886. j->play_frame_size = 80;
  1887. break;
  1888. case 0x50:
  1889. j->play_frame_size = 40;
  1890. break;
  1891. default:
  1892. j->play_frame_size = 120;
  1893. break;
  1894. }
  1895. j->play_mode = 2;
  1896. break;
  1897. case ALAW:
  1898. switch (j->baseframe.low) {
  1899. case 0xA0:
  1900. j->play_frame_size = 80;
  1901. break;
  1902. case 0x50:
  1903. j->play_frame_size = 40;
  1904. break;
  1905. default:
  1906. j->play_frame_size = 120;
  1907. break;
  1908. }
  1909. j->play_mode = 2;
  1910. break;
  1911. case LINEAR16:
  1912. switch (j->baseframe.low) {
  1913. case 0xA0:
  1914. j->play_frame_size = 160;
  1915. break;
  1916. case 0x50:
  1917. j->play_frame_size = 80;
  1918. break;
  1919. default:
  1920. j->play_frame_size = 240;
  1921. break;
  1922. }
  1923. j->play_mode = 6;
  1924. break;
  1925. case LINEAR8:
  1926. switch (j->baseframe.low) {
  1927. case 0xA0:
  1928. j->play_frame_size = 80;
  1929. break;
  1930. case 0x50:
  1931. j->play_frame_size = 40;
  1932. break;
  1933. default:
  1934. j->play_frame_size = 120;
  1935. break;
  1936. }
  1937. j->play_mode = 4;
  1938. break;
  1939. case WSS:
  1940. switch (j->baseframe.low) {
  1941. case 0xA0:
  1942. j->play_frame_size = 80;
  1943. break;
  1944. case 0x50:
  1945. j->play_frame_size = 40;
  1946. break;
  1947. default:
  1948. j->play_frame_size = 120;
  1949. break;
  1950. }
  1951. j->play_mode = 5;
  1952. break;
  1953. default:
  1954. j->play_frame_size = 0;
  1955. j->play_mode = -1;
  1956. if (j->write_buffer) {
  1957. kfree(j->write_buffer);
  1958. j->write_buffer = NULL;
  1959. j->write_buffer_size = 0;
  1960. }
  1961. retval = 1;
  1962. break;
  1963. }
  1964. return retval;
  1965. }
  1966. static int ixj_play_start(int board)
  1967. {
  1968. unsigned short cmd = 0x0000;
  1969. IXJ *j = &ixj[board];
  1970. j->flags.play_first_frame = 1;
  1971. j->drybuffer = 0;
  1972. if (!j->play_mode) {
  1973. switch (j->play_codec) {
  1974. case G723_63:
  1975. cmd = 0x5231;
  1976. break;
  1977. case G723_53:
  1978. cmd = 0x5232;
  1979. break;
  1980. case TS85:
  1981. cmd = 0x5230; // TrueSpeech 8.5
  1982. break;
  1983. case TS48:
  1984. cmd = 0x5233; // TrueSpeech 4.8
  1985. break;
  1986. case TS41:
  1987. cmd = 0x5234; // TrueSpeech 4.1
  1988. break;
  1989. case G728:
  1990. cmd = 0x5235;
  1991. break;
  1992. case G729:
  1993. cmd = 0x5236;
  1994. break;
  1995. default:
  1996. return 1;
  1997. }
  1998. if (ixj_WriteDSPCommand(cmd, board))
  1999. return -1;
  2000. }
  2001. if (!j->write_buffer) {
  2002. j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_KERNEL);
  2003. if (!j->write_buffer) {
  2004. printk("Write buffer allocation for ixj board %d failed!n", board);
  2005. return -ENOMEM;
  2006. }
  2007. }
  2008. j->write_buffers_empty = 2;
  2009. j->write_buffer_size = j->play_frame_size * 2;
  2010. j->write_buffer_end = j->write_buffer + j->play_frame_size * 2;
  2011. j->write_buffer_rp = j->write_buffer_wp = j->write_buffer;
  2012. if (ixj_WriteDSPCommand(0x5202, board)) // Set Poll sync mode
  2013. return -1;
  2014. switch (j->play_mode) {
  2015. case 0:
  2016. cmd = 0x2C03;
  2017. break;
  2018. case 2:
  2019. if (j->ver.low == 0x12) {
  2020. cmd = 0x2C23;
  2021. } else {
  2022. cmd = 0x2C21;
  2023. }
  2024. break;
  2025. case 4:
  2026. if (j->ver.low == 0x12) {
  2027. cmd = 0x2C43;
  2028. } else {
  2029. cmd = 0x2C41;
  2030. }
  2031. break;
  2032. case 5:
  2033. if (j->ver.low == 0x12) {
  2034. cmd = 0x2C53;
  2035. } else {
  2036. cmd = 0x2C51;
  2037. }
  2038. break;
  2039. case 6:
  2040. if (j->ver.low == 0x12) {
  2041. cmd = 0x2C63;
  2042. } else {
  2043. cmd = 0x2C61;
  2044. }
  2045. break;
  2046. }
  2047. if (ixj_WriteDSPCommand(cmd, board))
  2048. return -1;
  2049. if (ixj_WriteDSPCommand(0x2000, board)) // Playback C2
  2050. return -1;
  2051. if (ixj_WriteDSPCommand(0x2000 + ixj[board].play_frame_size, board)) // Playback C3
  2052. return -1;
  2053. return 0;
  2054. }
  2055. static void ixj_play_stop(int board)
  2056. {
  2057. IXJ *j = &ixj[board];
  2058. if (j->play_mode > -1) {
  2059. ixj_WriteDSPCommand(0x5221, board); // Stop playback
  2060. j->play_mode = -1;
  2061. }
  2062. }
  2063. extern __inline__ void set_play_depth(int board, int depth)
  2064. {
  2065. if (depth > 60)
  2066. depth = 60;
  2067. if (depth < 0)
  2068. depth = 0;
  2069. ixj_WriteDSPCommand(0x5280 + depth, board);
  2070. }
  2071. extern __inline__ void set_play_volume(int board, int volume)
  2072. {
  2073. ixj_WriteDSPCommand(0xCF02, board);
  2074. ixj_WriteDSPCommand(volume, board);
  2075. }
  2076. extern __inline__ int get_play_level(int board)
  2077. {
  2078. ixj_WriteDSPCommand(0xCF8F, board);
  2079. return ixj[board].ssr.high << 8 | ixj[board].ssr.low;
  2080. }
  2081. static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
  2082. {
  2083. unsigned int mask = 0;
  2084. IXJ *j = &ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
  2085. poll_wait(file_p, &(j->poll_q), wait);
  2086. if (j->read_buffer_ready > 0)
  2087. mask |= POLLIN | POLLRDNORM; /* readable */
  2088. if (j->write_buffers_empty > 0)
  2089. mask |= POLLOUT | POLLWRNORM; /* writable */
  2090. if (j->ex.bytes)
  2091. mask |= POLLPRI;
  2092. return mask;
  2093. }
  2094. static int ixj_play_tone(int board, char tone)
  2095. {
  2096. IXJ *j = &ixj[board];
  2097. if (!j->tone_state)
  2098. idle(board);
  2099. j->tone_index = tone;
  2100. if (ixj_WriteDSPCommand(0x6000 + j->tone_index, board))
  2101. return -1;
  2102. if (!j->tone_state) {
  2103. j->tone_start_jif = jiffies;
  2104. j->tone_state = 1;
  2105. }
  2106. return 0;
  2107. }
  2108. static int ixj_set_tone_on(unsigned short arg, int board)
  2109. {
  2110. IXJ *j = &ixj[board];
  2111. j->tone_on_time = arg;
  2112. if (ixj_WriteDSPCommand(0x6E04, board)) // Set Tone On Period
  2113. return -1;
  2114. if (ixj_WriteDSPCommand(arg, board))
  2115. return -1;
  2116. return 0;
  2117. }
  2118. static int SCI_WaitHighSCI(int board)
  2119. {
  2120. int cnt;
  2121. IXJ *j = &ixj[board];
  2122. j->pld_scrr.byte = inb_p(j->XILINXbase);
  2123. if (!j->pld_scrr.bits.sci) {
  2124. for (cnt = 0; cnt < 10; cnt++) {
  2125. udelay(32);
  2126. j->pld_scrr.byte = inb_p(j->XILINXbase);
  2127. if ((j->pld_scrr.bits.sci))
  2128. return 1;
  2129. }
  2130. if (ixjdebug > 1)
  2131. printk(KERN_INFO "SCI Wait High failed %xn", j->pld_scrr.byte);
  2132. return 0;
  2133. } else
  2134. return 1;
  2135. }
  2136. static int SCI_WaitLowSCI(int board)
  2137. {
  2138. int cnt;
  2139. IXJ *j = &ixj[board];
  2140. j->pld_scrr.byte = inb_p(j->XILINXbase);
  2141. if (j->pld_scrr.bits.sci) {
  2142. for (cnt = 0; cnt < 10; cnt++) {
  2143. udelay(32);
  2144. j->pld_scrr.byte = inb_p(j->XILINXbase);
  2145. if (!(j->pld_scrr.bits.sci))
  2146. return 1;
  2147. }
  2148. if (ixjdebug > 1)
  2149. printk(KERN_INFO "SCI Wait Low failed %xn", j->pld_scrr.byte);
  2150. return 0;
  2151. } else
  2152. return 1;
  2153. }
  2154. static int SCI_Control(int board, int control)
  2155. {
  2156. IXJ *j = &ixj[board];
  2157. switch (control) {
  2158. case SCI_End:
  2159. j->pld_scrw.bits.c0 = 0; // Set PLD Serial control interface
  2160. j->pld_scrw.bits.c1 = 0; // to no selection 
  2161. break;
  2162. case SCI_Enable_DAA:
  2163. j->pld_scrw.bits.c0 = 1; // Set PLD Serial control interface
  2164. j->pld_scrw.bits.c1 = 0; // to write to DAA
  2165. break;
  2166. case SCI_Enable_Mixer:
  2167. j->pld_scrw.bits.c0 = 0; // Set PLD Serial control interface
  2168. j->pld_scrw.bits.c1 = 1; // to write to mixer 
  2169. break;
  2170. case SCI_Enable_EEPROM:
  2171. j->pld_scrw.bits.c0 = 1; // Set PLD Serial control interface
  2172. j->pld_scrw.bits.c1 = 1; // to write to EEPROM 
  2173. break;
  2174. default:
  2175. return 0;
  2176. break;
  2177. }
  2178. outb_p(j->pld_scrw.byte, j->XILINXbase);
  2179. switch (control) {
  2180. case SCI_End:
  2181. return 1;
  2182. break;
  2183. case SCI_Enable_DAA:
  2184. case SCI_Enable_Mixer:
  2185. case SCI_Enable_EEPROM:
  2186. if (!SCI_WaitHighSCI(board))
  2187. return 0;
  2188. break;
  2189. default:
  2190. return 0;
  2191. break;
  2192. }
  2193. return 1;
  2194. }
  2195. static int SCI_Prepare(int board)
  2196. {
  2197. if (!SCI_Control(board, SCI_End))
  2198. return 0;
  2199. if (!SCI_WaitLowSCI(board))
  2200. return 0;
  2201. return 1;
  2202. }
  2203. static int ixj_mixer(long val, int board)
  2204. {
  2205. BYTES bytes;
  2206. IXJ *j = &ixj[board];
  2207. bytes.high = (val & 0xFF00) >> 8;
  2208. bytes.low = val & 0x00FF;
  2209. outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03); // Load Mixer Address
  2210. outb_p(bytes.low, j->XILINXbase + 0x02); // Load Mixer Data
  2211. SCI_Control(board, SCI_Enable_Mixer);
  2212. SCI_Control(board, SCI_End);
  2213. return 0;
  2214. }
  2215. static int daa_load(BYTES * p_bytes, int board)
  2216. {
  2217. IXJ *j = &ixj[board];
  2218. outb_p(p_bytes->high, j->XILINXbase + 0x03);
  2219. outb_p(p_bytes->low, j->XILINXbase + 0x02);
  2220. if (!SCI_Control(board, SCI_Enable_DAA))
  2221. return 0;
  2222. else
  2223. return 1;
  2224. }
  2225. static int ixj_daa_cr4(int board, char reg)
  2226. {
  2227. IXJ *j = &ixj[board];
  2228. BYTES bytes;
  2229. switch (j->daa_mode) {
  2230. case SOP_PU_SLEEP:
  2231. bytes.high = 0x14;
  2232. break;
  2233. case SOP_PU_RINGING:
  2234. bytes.high = 0x54;
  2235. break;
  2236. case SOP_PU_CONVERSATION:
  2237. bytes.high = 0x94;
  2238. break;
  2239. case SOP_PU_PULSEDIALING:
  2240. bytes.high = 0xD4;
  2241. break;
  2242. }
  2243. switch (j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGX) {
  2244. case 0:
  2245. j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 0;
  2246. break;
  2247. case 1:
  2248. j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 2;
  2249. break;
  2250. case 2:
  2251. j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 1;
  2252. break;
  2253. case 3:
  2254. j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 3;
  2255. break;
  2256. }
  2257. bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
  2258. if (!daa_load(&bytes, board))
  2259. return 0;
  2260. if (!SCI_Prepare(board))
  2261. return 0;
  2262. return 1;
  2263. }
  2264. static char daa_int_read(int board)
  2265. {
  2266. BYTES bytes;
  2267. IXJ *j = &ixj[board];
  2268. if (!SCI_Prepare(board))
  2269. return 0;
  2270. bytes.high = 0x38;
  2271. bytes.low = 0x00;
  2272. outb_p(bytes.high, j->XILINXbase + 0x03);
  2273. outb_p(bytes.low, j->XILINXbase + 0x02);
  2274. if (!SCI_Control(board, SCI_Enable_DAA))
  2275. return 0;
  2276. bytes.high = inb_p(j->XILINXbase + 0x03);
  2277. bytes.low = inb_p(j->XILINXbase + 0x02);
  2278. if (bytes.low != ALISDAA_ID_BYTE) {
  2279. if (ixjdebug > 0)
  2280. printk("Cannot read DAA ID Byte high = %d low = %dn", bytes.high, bytes.low);
  2281. return 0;
  2282. }
  2283. if (!SCI_Control(board, SCI_Enable_DAA))
  2284. return 0;
  2285. if (!SCI_Control(board, SCI_End))
  2286. return 0;
  2287. bytes.high = inb_p(j->XILINXbase + 0x03);
  2288. bytes.low = inb_p(j->XILINXbase + 0x02);
  2289. j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high;
  2290. return 1;
  2291. }
  2292. static int ixj_daa_cid_reset(int board)
  2293. {
  2294. int i;
  2295. BYTES bytes;
  2296. IXJ *j = &ixj[board];
  2297. if (!SCI_Prepare(board))
  2298. return 0;
  2299. bytes.high = 0x58;
  2300. bytes.low = 0x00;
  2301. outb_p(bytes.high, j->XILINXbase + 0x03);
  2302. outb_p(bytes.low, j->XILINXbase + 0x02);
  2303. if (!SCI_Control(board, SCI_Enable_DAA))
  2304. return 0;
  2305. if (!SCI_WaitHighSCI(board))
  2306. return 0;
  2307. for (i = 0; i < ALISDAA_CALLERID_SIZE - 1; i += 2) {
  2308. bytes.high = bytes.low = 0x00;
  2309. outb_p(bytes.high, j->XILINXbase + 0x03);
  2310. if (i < ALISDAA_CALLERID_SIZE - 1)
  2311. outb_p(bytes.low, j->XILINXbase + 0x02);
  2312. if (!SCI_Control(board, SCI_Enable_DAA))
  2313. return 0;
  2314. if (!SCI_WaitHighSCI(board))
  2315. return 0;
  2316. }
  2317. if (!SCI_Control(board, SCI_End))
  2318. return 0;
  2319. return 1;
  2320. }
  2321. static int ixj_daa_cid_read(int board)
  2322. {
  2323. int i;
  2324. BYTES bytes;
  2325. char CID[ALISDAA_CALLERID_SIZE], mContinue;
  2326. char *pIn, *pOut;
  2327. IXJ *j = &ixj[board];
  2328. if (!SCI_Prepare(board))
  2329. return 0;
  2330. bytes.high = 0x78;
  2331. bytes.low = 0x00;
  2332. outb_p(bytes.high, j->XILINXbase + 0x03);
  2333. outb_p(bytes.low, j->XILINXbase + 0x02);
  2334. if (!SCI_Control(board, SCI_Enable_DAA))
  2335. return 0;
  2336. if (!SCI_WaitHighSCI(board))
  2337. return 0;
  2338. bytes.high = inb_p(j->XILINXbase + 0x03);
  2339. bytes.low = inb_p(j->XILINXbase + 0x02);
  2340. if (bytes.low != ALISDAA_ID_BYTE) {
  2341. if (ixjdebug > 0)
  2342. printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %dn", bytes.high, bytes.low);
  2343. return 0;
  2344. }
  2345. for (i = 0; i < ALISDAA_CALLERID_SIZE; i += 2) {
  2346. bytes.high = bytes.low = 0x00;
  2347. outb_p(bytes.high, j->XILINXbase + 0x03);
  2348. outb_p(bytes.low, j->XILINXbase + 0x02);
  2349. if (!SCI_Control(board, SCI_Enable_DAA))
  2350. return 0;
  2351. if (!SCI_WaitHighSCI(board))
  2352. return 0;
  2353. CID[i + 0] = inb_p(j->XILINXbase + 0x03);
  2354. CID[i + 1] = inb_p(j->XILINXbase + 0x02);
  2355. }
  2356. if (!SCI_Control(board, SCI_End))
  2357. return 0;
  2358. pIn = CID;
  2359. pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID;
  2360. mContinue = 1;
  2361. while (mContinue) {
  2362. if ((pIn[1] & 0x03) == 0x01) {
  2363. pOut[0] = pIn[0];
  2364. }
  2365. if ((pIn[2] & 0x0c) == 0x04) {
  2366. pOut[1] = ((pIn[2] & 0x03) << 6) | ((pIn[1] & 0xfc) >> 2);
  2367. }
  2368. if ((pIn[3] & 0x30) == 0x10) {
  2369. pOut[2] = ((pIn[3] & 0x0f) << 4) | ((pIn[2] & 0xf0) >> 4);
  2370. }
  2371. if ((pIn[4] & 0xc0) == 0x40) {
  2372. pOut[3] = ((pIn[4] & 0x3f) << 2) | ((pIn[3] & 0xc0) >> 6);
  2373. } else {
  2374. mContinue = FALSE;
  2375. }
  2376. pIn += 5, pOut += 4;
  2377. }
  2378. memset(&j->cid, 0, sizeof(IXJ_CID));
  2379. pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID;
  2380. pOut += 4;
  2381. strncpy(j->cid.month, pOut, 2);
  2382. pOut += 2;
  2383. strncpy(j->cid.day, pOut, 2);
  2384. pOut += 2;
  2385. strncpy(j->cid.hour, pOut, 2);
  2386. pOut += 2;
  2387. strncpy(j->cid.min, pOut, 2);
  2388. pOut += 3;
  2389. j->cid.numlen = *pOut;
  2390. pOut += 1;
  2391. strncpy(j->cid.number, pOut, j->cid.numlen);
  2392. pOut += j->cid.numlen + 1;
  2393. j->cid.namelen = *pOut;
  2394. pOut += 1;
  2395. strncpy(j->cid.name, pOut, j->cid.namelen);
  2396. ixj_daa_cid_reset(board);
  2397. return 1;
  2398. }
  2399. static char daa_get_version(int board)
  2400. {
  2401. BYTES bytes;
  2402. IXJ *j = &ixj[board];
  2403. if (!SCI_Prepare(board))
  2404. return 0;
  2405. bytes.high = 0x35;
  2406. bytes.low = 0x00;
  2407. outb_p(bytes.high, j->XILINXbase + 0x03);
  2408. outb_p(bytes.low, j->XILINXbase + 0x02);
  2409. if (!SCI_Control(board, SCI_Enable_DAA))
  2410. return 0;
  2411. bytes.high = inb_p(j->XILINXbase + 0x03);
  2412. bytes.low = inb_p(j->XILINXbase + 0x02);
  2413. if (bytes.low != ALISDAA_ID_BYTE) {
  2414. if (ixjdebug > 0)
  2415. printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %dn", bytes.high, bytes.low);
  2416. return 0;
  2417. }
  2418. if (!SCI_Control(board, SCI_Enable_DAA))
  2419. return 0;
  2420. if (!SCI_Control(board, SCI_End))
  2421. return 0;
  2422. bytes.high = inb_p(j->XILINXbase + 0x03);
  2423. bytes.low = inb_p(j->XILINXbase + 0x02);
  2424. if (ixjdebug > 0)
  2425. printk("DAA CR5 Byte high = 0x%x low = 0x%xn", bytes.high, bytes.low);
  2426. j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = bytes.high;
  2427. return bytes.high;
  2428. }
  2429. static int daa_set_mode(int board, int mode)
  2430. {
  2431. // NOTE:
  2432. //      The DAA *MUST* be in the conversation mode if the
  2433. //      PSTN line is to be seized (PSTN line off-hook).
  2434. //      Taking the PSTN line off-hook while the DAA is in
  2435. //      a mode other than conversation mode will cause a
  2436. //      hardware failure of the ALIS-A part.
  2437. // NOTE:
  2438. //      The DAA can only go to SLEEP, RINGING or PULSEDIALING modes
  2439. //      if the PSTN line is on-hook.  Failure to have the PSTN line
  2440. //      in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE
  2441. //      ALIS-A part.
  2442. //
  2443. BYTES bytes;
  2444. IXJ *j = &ixj[board];
  2445. if (!SCI_Prepare(board))
  2446. return 0;
  2447. switch (mode) {
  2448. case SOP_PU_SLEEP:
  2449. j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
  2450. outb_p(j->pld_scrw.byte, j->XILINXbase);
  2451. j->pld_slicw.bits.rly2 = 0;
  2452. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  2453. bytes.high = 0x10;
  2454. bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
  2455. daa_load(&bytes, board);
  2456. if (!SCI_Prepare(board))
  2457. return 0;
  2458. j->daa_mode = SOP_PU_SLEEP;
  2459. j->flags.pstn_ringing = 0;
  2460. j->pstn_sleeptil = jiffies + (hertz * 3);
  2461. break;
  2462. case SOP_PU_RINGING:
  2463. j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
  2464. outb_p(j->pld_scrw.byte, j->XILINXbase);
  2465. j->pld_slicw.bits.rly2 = 0;
  2466. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  2467. bytes.high = 0x50;
  2468. bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
  2469. daa_load(&bytes, board);
  2470. if (!SCI_Prepare(board))
  2471. return 0;
  2472. j->daa_mode = SOP_PU_RINGING;
  2473. break;
  2474. case SOP_PU_CONVERSATION:
  2475. bytes.high = 0x90;
  2476. bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
  2477. daa_load(&bytes, board);
  2478. if (!SCI_Prepare(board))
  2479. return 0;
  2480. j->pld_slicw.bits.rly2 = 1;
  2481. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  2482. j->pld_scrw.bits.daafsyncen = 1; // Turn on DAA Frame Sync
  2483. outb_p(j->pld_scrw.byte, j->XILINXbase);
  2484. j->daa_mode = SOP_PU_CONVERSATION;
  2485. j->flags.pstn_ringing = 0;
  2486. j->ex.bits.pstn_ring = 0;
  2487. break;
  2488. case SOP_PU_PULSEDIALING:
  2489. j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
  2490. outb_p(j->pld_scrw.byte, j->XILINXbase);
  2491. j->pld_slicw.bits.rly2 = 0;
  2492. outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
  2493. bytes.high = 0xD0;
  2494. bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
  2495. daa_load(&bytes, board);
  2496. if (!SCI_Prepare(board))
  2497. return 0;
  2498. j->daa_mode = SOP_PU_PULSEDIALING;
  2499. break;
  2500. default:
  2501. break;
  2502. }
  2503. return 1;
  2504. }
  2505. static int ixj_daa_write(int board)
  2506. {
  2507. BYTES bytes;
  2508. IXJ *j = &ixj[board];
  2509. if (!SCI_Prepare(board))
  2510. return 0;
  2511. bytes.high = 0x14;
  2512. bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
  2513. if (!daa_load(&bytes, board))
  2514. return 0;
  2515. bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg;
  2516. bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg;
  2517. if (!daa_load(&bytes, board))
  2518. return 0;
  2519. bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg;
  2520. bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
  2521. if (!daa_load(&bytes, board))
  2522. return 0;
  2523. if (!SCI_Prepare(board))
  2524. return 0;
  2525. bytes.high = 0x1F;
  2526. bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg;
  2527. if (!daa_load(&bytes, board))
  2528. return 0;
  2529. bytes.high = j->m_DAAShadowRegs.XOP_xr6_W.reg;
  2530. bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg;
  2531. if (!daa_load(&bytes, board))
  2532. return 0;
  2533. bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg;
  2534. bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg;
  2535. if (!daa_load(&bytes, board))
  2536. return 0;
  2537. bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg;
  2538. bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg;
  2539. if (!daa_load(&bytes, board))
  2540. return 0;
  2541. bytes.high = j->m_DAAShadowRegs.XOP_xr0_W.reg;
  2542. bytes.low = 0x00;
  2543. if (!daa_load(&bytes, board))
  2544. return 0;
  2545. if (!SCI_Prepare(board))
  2546. return 0;
  2547. bytes.high = 0x00;
  2548. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7];
  2549. if (!daa_load(&bytes, board))
  2550. return 0;
  2551. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6];
  2552. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5];
  2553. if (!daa_load(&bytes, board))
  2554. return 0;
  2555. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4];
  2556. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3];
  2557. if (!daa_load(&bytes, board))
  2558. return 0;
  2559. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2];
  2560. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1];
  2561. if (!daa_load(&bytes, board))
  2562. return 0;
  2563. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0];
  2564. bytes.low = 0x00;
  2565. if (!daa_load(&bytes, board))
  2566. return 0;
  2567. if (!SCI_Control(board, SCI_End))
  2568. return 0;
  2569. if (!SCI_WaitLowSCI(board))
  2570. return 0;
  2571. bytes.high = 0x01;
  2572. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7];
  2573. if (!daa_load(&bytes, board))
  2574. return 0;
  2575. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6];
  2576. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5];
  2577. if (!daa_load(&bytes, board))
  2578. return 0;
  2579. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4];
  2580. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3];
  2581. if (!daa_load(&bytes, board))
  2582. return 0;
  2583. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2];
  2584. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1];
  2585. if (!daa_load(&bytes, board))
  2586. return 0;
  2587. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0];
  2588. bytes.low = 0x00;
  2589. if (!daa_load(&bytes, board))
  2590. return 0;
  2591. if (!SCI_Control(board, SCI_End))
  2592. return 0;
  2593. if (!SCI_WaitLowSCI(board))
  2594. return 0;
  2595. bytes.high = 0x02;
  2596. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7];
  2597. if (!daa_load(&bytes, board))
  2598. return 0;
  2599. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6];
  2600. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5];
  2601. if (!daa_load(&bytes, board))
  2602. return 0;
  2603. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4];
  2604. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3];
  2605. if (!daa_load(&bytes, board))
  2606. return 0;
  2607. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2];
  2608. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1];
  2609. if (!daa_load(&bytes, board))
  2610. return 0;
  2611. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0];
  2612. bytes.low = 0x00;
  2613. if (!daa_load(&bytes, board))
  2614. return 0;
  2615. if (!SCI_Control(board, SCI_End))
  2616. return 0;
  2617. if (!SCI_WaitLowSCI(board))
  2618. return 0;
  2619. bytes.high = 0x03;
  2620. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7];
  2621. if (!daa_load(&bytes, board))
  2622. return 0;
  2623. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6];
  2624. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5];
  2625. if (!daa_load(&bytes, board))
  2626. return 0;
  2627. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4];
  2628. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3];
  2629. if (!daa_load(&bytes, board))
  2630. return 0;
  2631. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2];
  2632. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1];
  2633. if (!daa_load(&bytes, board))
  2634. return 0;
  2635. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0];
  2636. bytes.low = 0x00;
  2637. if (!daa_load(&bytes, board))
  2638. return 0;
  2639. if (!SCI_Control(board, SCI_End))
  2640. return 0;
  2641. if (!SCI_WaitLowSCI(board))
  2642. return 0;
  2643. bytes.high = 0x04;
  2644. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7];
  2645. if (!daa_load(&bytes, board))
  2646. return 0;
  2647. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6];
  2648. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5];
  2649. if (!daa_load(&bytes, board))
  2650. return 0;
  2651. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4];
  2652. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3];
  2653. if (!daa_load(&bytes, board))
  2654. return 0;
  2655. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2];
  2656. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1];
  2657. if (!daa_load(&bytes, board))
  2658. return 0;
  2659. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0];
  2660. bytes.low = 0x00;
  2661. if (!daa_load(&bytes, board))
  2662. return 0;
  2663. if (!SCI_Control(board, SCI_End))
  2664. return 0;
  2665. if (!SCI_WaitLowSCI(board))
  2666. return 0;
  2667. bytes.high = 0x05;
  2668. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7];
  2669. if (!daa_load(&bytes, board))
  2670. return 0;
  2671. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6];
  2672. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5];
  2673. if (!daa_load(&bytes, board))
  2674. return 0;
  2675. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4];
  2676. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3];
  2677. if (!daa_load(&bytes, board))
  2678. return 0;
  2679. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2];
  2680. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1];
  2681. if (!daa_load(&bytes, board))
  2682. return 0;
  2683. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0];
  2684. bytes.low = 0x00;
  2685. if (!daa_load(&bytes, board))
  2686. return 0;
  2687. if (!SCI_Control(board, SCI_End))
  2688. return 0;
  2689. if (!SCI_WaitLowSCI(board))
  2690. return 0;
  2691. bytes.high = 0x06;
  2692. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7];
  2693. if (!daa_load(&bytes, board))
  2694. return 0;
  2695. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6];
  2696. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5];
  2697. if (!daa_load(&bytes, board))
  2698. return 0;
  2699. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4];
  2700. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3];
  2701. if (!daa_load(&bytes, board))
  2702. return 0;
  2703. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2];
  2704. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1];
  2705. if (!daa_load(&bytes, board))
  2706. return 0;
  2707. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0];
  2708. bytes.low = 0x00;
  2709. if (!daa_load(&bytes, board))
  2710. return 0;
  2711. if (!SCI_Control(board, SCI_End))
  2712. return 0;
  2713. if (!SCI_WaitLowSCI(board))
  2714. return 0;
  2715. bytes.high = 0x07;
  2716. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7];
  2717. if (!daa_load(&bytes, board))
  2718. return 0;
  2719. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6];
  2720. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5];
  2721. if (!daa_load(&bytes, board))
  2722. return 0;
  2723. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4];
  2724. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3];
  2725. if (!daa_load(&bytes, board))
  2726. return 0;
  2727. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2];
  2728. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1];
  2729. if (!daa_load(&bytes, board))
  2730. return 0;
  2731. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0];
  2732. bytes.low = 0x00;
  2733. if (!daa_load(&bytes, board))
  2734. return 0;
  2735. if (!SCI_Control(board, SCI_End))
  2736. return 0;
  2737. if (!SCI_WaitLowSCI(board))
  2738. return 0;
  2739. bytes.high = 0x08;
  2740. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7];
  2741. if (!daa_load(&bytes, board))
  2742. return 0;
  2743. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6];
  2744. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5];
  2745. if (!daa_load(&bytes, board))
  2746. return 0;
  2747. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4];
  2748. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3];
  2749. if (!daa_load(&bytes, board))
  2750. return 0;
  2751. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2];
  2752. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1];
  2753. if (!daa_load(&bytes, board))
  2754. return 0;
  2755. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0];
  2756. bytes.low = 0x00;
  2757. if (!daa_load(&bytes, board))
  2758. return 0;
  2759. if (!SCI_Control(board, SCI_End))
  2760. return 0;
  2761. if (!SCI_WaitLowSCI(board))
  2762. return 0;
  2763. bytes.high = 0x09;
  2764. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3];
  2765. if (!daa_load(&bytes, board))
  2766. return 0;
  2767. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2];
  2768. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1];
  2769. if (!daa_load(&bytes, board))
  2770. return 0;
  2771. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0];
  2772. bytes.low = 0x00;
  2773. if (!daa_load(&bytes, board))
  2774. return 0;
  2775. if (!SCI_Control(board, SCI_End))
  2776. return 0;
  2777. if (!SCI_WaitLowSCI(board))
  2778. return 0;
  2779. bytes.high = 0x0A;
  2780. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3];
  2781. if (!daa_load(&bytes, board))
  2782. return 0;
  2783. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2];
  2784. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1];
  2785. if (!daa_load(&bytes, board))
  2786. return 0;
  2787. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0];
  2788. bytes.low = 0x00;
  2789. if (!daa_load(&bytes, board))
  2790. return 0;
  2791. if (!SCI_Control(board, SCI_End))
  2792. return 0;
  2793. if (!SCI_WaitLowSCI(board))
  2794. return 0;
  2795. bytes.high = 0x0B;
  2796. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3];
  2797. if (!daa_load(&bytes, board))
  2798. return 0;
  2799. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2];
  2800. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1];
  2801. if (!daa_load(&bytes, board))
  2802. return 0;
  2803. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0];
  2804. bytes.low = 0x00;
  2805. if (!daa_load(&bytes, board))
  2806. return 0;
  2807. if (!SCI_Control(board, SCI_End))
  2808. return 0;
  2809. if (!SCI_WaitLowSCI(board))
  2810. return 0;
  2811. bytes.high = 0x0C;
  2812. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3];
  2813. if (!daa_load(&bytes, board))
  2814. return 0;
  2815. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2];
  2816. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1];
  2817. if (!daa_load(&bytes, board))
  2818. return 0;
  2819. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0];
  2820. bytes.low = 0x00;
  2821. if (!daa_load(&bytes, board))
  2822. return 0;
  2823. if (!SCI_Control(board, SCI_End))
  2824. return 0;
  2825. if (!SCI_WaitLowSCI(board))
  2826. return 0;
  2827. bytes.high = 0x0D;
  2828. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3];
  2829. if (!daa_load(&bytes, board))
  2830. return 0;
  2831. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2];
  2832. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1];
  2833. if (!daa_load(&bytes, board))
  2834. return 0;
  2835. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0];
  2836. bytes.low = 0x00;
  2837. if (!daa_load(&bytes, board))
  2838. return 0;
  2839. if (!SCI_Control(board, SCI_End))
  2840. return 0;
  2841. if (!SCI_WaitLowSCI(board))
  2842. return 0;
  2843. bytes.high = 0x0E;
  2844. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7];
  2845. if (!daa_load(&bytes, board))
  2846. return 0;
  2847. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6];
  2848. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5];
  2849. if (!daa_load(&bytes, board))
  2850. return 0;
  2851. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4];
  2852. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3];
  2853. if (!daa_load(&bytes, board))
  2854. return 0;
  2855. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2];
  2856. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1];
  2857. if (!daa_load(&bytes, board))
  2858. return 0;
  2859. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0];
  2860. bytes.low = 0x00;
  2861. if (!daa_load(&bytes, board))
  2862. return 0;
  2863. if (!SCI_Control(board, SCI_End))
  2864. return 0;
  2865. if (!SCI_WaitLowSCI(board))
  2866. return 0;
  2867. bytes.high = 0x0F;
  2868. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7];
  2869. if (!daa_load(&bytes, board))
  2870. return 0;
  2871. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6];
  2872. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5];
  2873. if (!daa_load(&bytes, board))
  2874. return 0;
  2875. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4];
  2876. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3];
  2877. if (!daa_load(&bytes, board))
  2878. return 0;
  2879. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2];
  2880. bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1];
  2881. if (!daa_load(&bytes, board))
  2882. return 0;
  2883. bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0];
  2884. bytes.low = 0x00;
  2885. if (!daa_load(&bytes, board))
  2886. return 0;
  2887. udelay(32);
  2888. j->pld_scrr.byte = inb_p(j->XILINXbase);
  2889. if (!SCI_Control(board, SCI_End))
  2890. return 0;
  2891. return 1;
  2892. }
  2893. int ixj_set_tone_off(unsigned short arg, int board)
  2894. {
  2895. ixj[board].tone_off_time = arg;
  2896. if (ixj_WriteDSPCommand(0x6E05, board)) // Set Tone Off Period
  2897. return -1;
  2898. if (ixj_WriteDSPCommand(arg, board))
  2899. return -1;
  2900. return 0;
  2901. }
  2902. static int ixj_get_tone_on(int board)
  2903. {
  2904. if (ixj_WriteDSPCommand(0x6E06, board)) // Get Tone On Period
  2905. return -1;
  2906. return 0;
  2907. }
  2908. static int ixj_get_tone_off(int board)
  2909. {
  2910. if (ixj_WriteDSPCommand(0x6E07, board)) // Get Tone Off Period
  2911. return -1;
  2912. return 0;
  2913. }
  2914. static void ixj_busytone(int board)
  2915. {
  2916. ixj[board].flags.ringback = 0;
  2917. ixj[board].flags.dialtone = 0;
  2918. ixj[board].flags.busytone = 1;
  2919. ixj_set_tone_on(0x07D0, board);
  2920. ixj_set_tone_off(0x07D0, board);
  2921. ixj_play_tone(board, 27);
  2922. }
  2923. static void ixj_dialtone(int board)
  2924. {
  2925. ixj[board].flags.ringback = 0;
  2926. ixj[board].flags.dialtone = 1;
  2927. ixj[board].flags.busytone = 0;
  2928. if (ixj[board].dsp.low == 0x20) {
  2929. return;
  2930. } else {
  2931. ixj_set_tone_on(0xFFFF, board);
  2932. ixj_set_tone_off(0x0000, board);
  2933. ixj_play_tone(board, 25);
  2934. }
  2935. }
  2936. static void ixj_cpt_stop(board)
  2937. {
  2938. IXJ *j = &ixj[board];
  2939. j->flags.dialtone = 0;
  2940. j->flags.busytone = 0;
  2941. j->flags.ringback = 0;
  2942. ixj_set_tone_on(0x0001, board);
  2943. ixj_set_tone_off(0x0000, board);
  2944. ixj_play_tone(board, 0);
  2945. j->tone_state = 0;
  2946. if (j->cadence_t) {
  2947. if (j->cadence_t->ce) {
  2948. kfree(j->cadence_t->ce);
  2949. }
  2950. kfree(j->cadence_t);
  2951. j->cadence_t = NULL;
  2952. }
  2953. if (j->dsp.low == 0x20 || (j->play_mode == -1 && j->rec_mode == -1))
  2954. idle(board);
  2955. if (j->play_mode != -1)
  2956. ixj_play_start(board);
  2957. if (j->rec_mode != -1)
  2958. ixj_record_start(board);
  2959. }
  2960. static void ixj_ringback(int board)
  2961. {
  2962. ixj[board].flags.busytone = 0;
  2963. ixj[board].flags.dialtone = 0;
  2964. ixj[board].flags.ringback = 1;
  2965. ixj_set_tone_on(0x0FA0, board);
  2966. ixj_set_tone_off(0x2EE0, board);
  2967. ixj_play_tone(board, 26);
  2968. }
  2969. static void ixj_testram(int board)
  2970. {
  2971. ixj_WriteDSPCommand(0x3001, board); /* Test External SRAM */
  2972. }
  2973. static int ixj_build_cadence(int board, IXJ_CADENCE * cp)
  2974. {
  2975. IXJ_CADENCE *lcp;
  2976. IXJ_CADENCE_ELEMENT *lcep;
  2977. IXJ_TONE ti;
  2978. IXJ *j = &ixj[board];
  2979. lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
  2980. if (lcp == NULL)
  2981. return -ENOMEM;
  2982. if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)))
  2983. return -EFAULT;
  2984. lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
  2985. if (lcep == NULL) {
  2986. kfree(lcp);
  2987. return -ENOMEM;
  2988. }
  2989. if (copy_from_user(lcep, lcp->ce, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
  2990. return -EFAULT;
  2991. lcp->ce = (void *) lcep;
  2992. j->cadence_t = lcp;
  2993. j->tone_cadence_state = 0;
  2994. ixj_set_tone_on(lcp->ce[0].tone_on_time, board);
  2995. ixj_set_tone_off(lcp->ce[0].tone_off_time, board);
  2996. if (j->cadence_t->ce[j->tone_cadence_state].freq0) {
  2997. ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
  2998. ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
  2999. ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
  3000. ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
  3001. ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
  3002. ixj_init_tone(board, &ti);
  3003. }
  3004. ixj_play_tone(board, lcp->ce[0].index);
  3005. return 1;
  3006. }
  3007. static void add_caps(int board)
  3008. {
  3009. IXJ *j = &ixj[board];
  3010. j->caps = 0;
  3011. j->caplist[j->caps].cap = vendor;
  3012. strcpy(j->caplist[j->caps].desc, "Quicknet Technologies, Inc. (www.quicknet.net)");
  3013. j->caplist[j->caps].captype = vendor;
  3014. j->caplist[j->caps].handle = j->caps++;
  3015. j->caplist[j->caps].captype = device;
  3016. switch (j->cardtype) {
  3017. case 100:
  3018. strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK");
  3019. j->caplist[j->caps].cap = 100;
  3020. break;
  3021. case 300:
  3022. strcpy(j->caplist[j->caps].desc, "Quicknet Internet LineJACK");
  3023. j->caplist[j->caps].cap = 300;
  3024. break;
  3025. case 400:
  3026. strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK Lite");
  3027. j->caplist[j->caps].cap = 400;
  3028. break;
  3029. case 500:
  3030. strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK PCI");
  3031. j->caplist[j->caps].cap = 500;
  3032. break;
  3033. }
  3034. j->caplist[j->caps].handle = j->caps++;
  3035. strcpy(j->caplist[j->caps].desc, "POTS");
  3036. j->caplist[j->caps].captype = port;
  3037. j->caplist[j->caps].cap = pots;
  3038. j->caplist[j->caps].handle = j->caps++;
  3039. switch (ixj[board].cardtype) {
  3040. case 100:
  3041. strcpy(j->caplist[j->caps].desc, "SPEAKER");
  3042. j->caplist[j->caps].captype = port;
  3043. j->caplist[j->caps].cap = speaker;
  3044. j->caplist[j->caps].handle = j->caps++;
  3045. strcpy(j->caplist[j->caps].desc, "HANDSET");
  3046. j->caplist[j->caps].captype = port;
  3047. j->caplist[j->caps].cap = handset;
  3048. j->caplist[j->caps].handle = j->caps++;
  3049. break;
  3050. case 300:
  3051. strcpy(j->caplist[j->caps].desc, "SPEAKER");
  3052. j->caplist[j->caps].captype = port;
  3053. j->caplist[j->caps].cap = speaker;
  3054. j->caplist[j->caps].handle = j->caps++;
  3055. strcpy(j->caplist[j->caps].desc, "PSTN");
  3056. j->caplist[j->caps].captype = port;
  3057. j->caplist[j->caps].cap = pstn;
  3058. j->caplist[j->caps].handle = j->caps++;
  3059. break;
  3060. }
  3061. strcpy(j->caplist[j->caps].desc, "ULAW");
  3062. j->caplist[j->caps].captype = codec;
  3063. j->caplist[j->caps].cap = ULAW;
  3064. j->caplist[j->caps].handle = j->caps++;
  3065. strcpy(j->caplist[j->caps].desc, "LINEAR 16 bit");
  3066. j->caplist[j->caps].captype = codec;
  3067. j->caplist[j->caps].cap = LINEAR16;
  3068. j->caplist[j->caps].handle = j->caps++;
  3069. strcpy(j->caplist[j->caps].desc, "LINEAR 8 bit");
  3070. j->caplist[j->caps].captype = codec;
  3071. j->caplist[j->caps].cap = LINEAR8;
  3072. j->caplist[j->caps].handle = j->caps++;
  3073. strcpy(j->caplist[j->caps].desc, "Windows Sound System");
  3074. j->caplist[j->caps].captype = codec;
  3075. j->caplist[j->caps].cap = WSS;
  3076. j->caplist[j->caps].handle = j->caps++;
  3077. if (j->ver.low != 0x12) {
  3078. strcpy(j->caplist[j->caps].desc, "G.723.1 6.3Kbps");
  3079. j->caplist[j->caps].captype = codec;
  3080. j->caplist[j->caps].cap = G723_63;
  3081. j->caplist[j->caps].handle = j->caps++;
  3082. strcpy(j->caplist[j->caps].desc, "G.723.1 5.3Kbps");
  3083. j->caplist[j->caps].captype = codec;
  3084. j->caplist[j->caps].cap = G723_53;
  3085. j->caplist[j->caps].handle = j->caps++;
  3086. strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8Kbps");
  3087. j->caplist[j->caps].captype = codec;
  3088. j->caplist[j->caps].cap = TS48;
  3089. j->caplist[j->caps].handle = j->caps++;
  3090. strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1Kbps");
  3091. j->caplist[j->caps].captype = codec;
  3092. j->caplist[j->caps].cap = TS41;
  3093. j->caplist[j->caps].handle = j->caps++;
  3094. }
  3095. if (j->cardtype == 100) {
  3096. strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5Kbps");
  3097. j->caplist[j->caps].captype = codec;
  3098. j->caplist[j->caps].cap = TS85;
  3099. j->caplist[j->caps].handle = j->caps++;
  3100. }
  3101. }
  3102. static int capabilities_check(int board, struct phone_capability *pcreq)
  3103. {
  3104. int cnt;
  3105. IXJ *j = &ixj[board];
  3106. int retval = 0;
  3107. for (cnt = 0; cnt < j->caps; cnt++) {
  3108. if (pcreq->captype == j->caplist[cnt].captype &&
  3109.     pcreq->cap == j->caplist[cnt].cap) {
  3110. retval = 1;
  3111. break;
  3112. }
  3113. }
  3114. return retval;
  3115. }
  3116. int ixj_ioctl(struct inode *inode, struct file *file_p,
  3117.       unsigned int cmd, unsigned long arg)
  3118. {
  3119. IXJ_TONE ti;
  3120. IXJ_FILTER jf;
  3121. unsigned int minor = MINOR(inode->i_rdev);
  3122. int board = NUM(inode->i_rdev);
  3123. IXJ *j = &ixj[NUM(inode->i_rdev)];
  3124. int retval = 0;
  3125. if (ixjdebug > 1)
  3126. printk(KERN_DEBUG "ixj%d ioctl, cmd: 0x%x, arg: 0x%lxn", minor, cmd, arg);
  3127. if (minor >= IXJMAX)
  3128. return -ENODEV;
  3129. /*
  3130.  *    Check ioctls only root can use.
  3131.  */
  3132. if (!capable(CAP_SYS_ADMIN)) {
  3133. switch (cmd) {
  3134. case IXJCTL_TESTRAM:
  3135. case IXJCTL_HZ:
  3136. return -EPERM;
  3137. }
  3138. }
  3139. switch (cmd) {
  3140. case IXJCTL_TESTRAM:
  3141. ixj_testram(board);
  3142. retval = (j->ssr.high << 8) + j->ssr.low;
  3143. break;
  3144. case IXJCTL_CARDTYPE:
  3145. retval = j->cardtype;
  3146. break;
  3147. case IXJCTL_SERIAL:
  3148. retval = j->serial;
  3149. break;
  3150. case PHONE_RING_CADENCE:
  3151. j->ring_cadence = arg;
  3152. break;
  3153. case PHONE_RING_START:
  3154. ixj_ring_start(board);
  3155. break;
  3156. case PHONE_RING_STOP:
  3157. j->flags.cringing = 0;
  3158. ixj_ring_off(board);
  3159. break;
  3160. case PHONE_RING:
  3161. retval = ixj_ring(board);
  3162. break;
  3163. case PHONE_EXCEPTION:
  3164. retval = j->ex.bytes;
  3165. j->ex.bytes &= 0x03;
  3166. break;
  3167. case PHONE_HOOKSTATE:
  3168. j->ex.bits.hookstate = 0;
  3169. retval = j->r_hook;
  3170. break;
  3171. case IXJCTL_SET_LED:
  3172. LED_SetState(arg, board);
  3173. break;
  3174. case PHONE_FRAME:
  3175. retval = set_base_frame(board, arg);
  3176. break;
  3177. case PHONE_REC_CODEC:
  3178. retval = set_rec_codec(board, arg);
  3179. break;
  3180. case PHONE_REC_START:
  3181. ixj_record_start(board);
  3182. break;
  3183. case PHONE_REC_STOP:
  3184. ixj_record_stop(board);
  3185. break;
  3186. case PHONE_REC_DEPTH:
  3187. set_rec_depth(board, arg);
  3188. break;
  3189. case PHONE_REC_VOLUME:
  3190. set_rec_volume(board, arg);
  3191. break;
  3192. case PHONE_REC_LEVEL:
  3193. retval = get_rec_level(board);
  3194. break;
  3195. case IXJCTL_AEC_START:
  3196. ixj_aec_start(board, arg);
  3197. break;
  3198. case IXJCTL_AEC_STOP:
  3199. aec_stop(board);
  3200. break;
  3201. case IXJCTL_AEC_GET_LEVEL:
  3202. retval = j->aec_level;
  3203. break;
  3204. case PHONE_PLAY_CODEC:
  3205. retval = set_play_codec(board, arg);
  3206. break;
  3207. case PHONE_PLAY_START:
  3208. ixj_play_start(board);
  3209. break;
  3210. case PHONE_PLAY_STOP:
  3211. ixj_play_stop(board);
  3212. break;
  3213. case PHONE_PLAY_DEPTH:
  3214. set_play_depth(board, arg);
  3215. break;
  3216. case PHONE_PLAY_VOLUME:
  3217. set_play_volume(board, arg);
  3218. break;
  3219. case PHONE_PLAY_LEVEL:
  3220. retval = get_play_level(board);
  3221. break;
  3222. case IXJCTL_DSP_TYPE:
  3223. retval = (j->dsp.high << 8) + j->dsp.low;
  3224. break;
  3225. case IXJCTL_DSP_VERSION:
  3226. retval = (j->ver.high << 8) + j->ver.low;
  3227. break;
  3228. case IXJCTL_HZ:
  3229. hertz = arg;
  3230. break;
  3231. case IXJCTL_RATE:
  3232. if (arg > hertz)
  3233. retval = -1;
  3234. else
  3235. samplerate = arg;
  3236. break;
  3237. case IXJCTL_DRYBUFFER_READ:
  3238. put_user(j->drybuffer, (unsigned long *) arg);
  3239. break;
  3240. case IXJCTL_DRYBUFFER_CLEAR:
  3241. j->drybuffer = 0;
  3242. break;
  3243. case IXJCTL_FRAMES_READ:
  3244. put_user(j->framesread, (unsigned long *) arg);
  3245. break;
  3246. case IXJCTL_FRAMES_WRITTEN:
  3247. put_user(j->frameswritten, (unsigned long *) arg);
  3248. break;
  3249. case IXJCTL_READ_WAIT:
  3250. put_user(j->read_wait, (unsigned long *) arg);
  3251. break;
  3252. case IXJCTL_WRITE_WAIT:
  3253. put_user(j->write_wait, (unsigned long *) arg);
  3254. break;
  3255. case PHONE_MAXRINGS:
  3256. j->maxrings = arg;
  3257. break;
  3258. case PHONE_SET_TONE_ON_TIME:
  3259. ixj_set_tone_on(arg, board);
  3260. break;
  3261. case PHONE_SET_TONE_OFF_TIME:
  3262. ixj_set_tone_off(arg, board);
  3263. break;
  3264. case PHONE_GET_TONE_ON_TIME:
  3265. if (ixj_get_tone_on(board)) {
  3266. retval = -1;
  3267. } else {
  3268. retval = (j->ssr.high << 8) + j->ssr.low;
  3269. }
  3270. break;
  3271. case PHONE_GET_TONE_OFF_TIME:
  3272. if (ixj_get_tone_off(board)) {
  3273. retval = -1;
  3274. } else {
  3275. retval = (j->ssr.high << 8) + j->ssr.low;
  3276. }
  3277. break;
  3278. case PHONE_PLAY_TONE:
  3279. if (!j->tone_state)
  3280. ixj_play_tone(board, arg);
  3281. break;
  3282. case PHONE_GET_TONE_STATE:
  3283. retval = j->tone_state;
  3284. break;
  3285. case PHONE_DTMF_READY:
  3286. retval = j->ex.bits.dtmf_ready;
  3287. break;
  3288. case PHONE_GET_DTMF:
  3289. if (ixj_hookstate(board)) {
  3290. if (j->dtmf_rp != j->dtmf_wp) {
  3291. retval = j->dtmfbuffer[j->dtmf_rp];
  3292. j->dtmf_rp++;
  3293. if (j->dtmf_rp == 79)
  3294. j->dtmf_rp = 0;
  3295. if (j->dtmf_rp == j->dtmf_wp) {
  3296. j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;
  3297. }
  3298. }
  3299. }
  3300. break;
  3301. case PHONE_GET_DTMF_ASCII:
  3302. if (ixj_hookstate(board)) {
  3303. if (j->dtmf_rp != j->dtmf_wp) {
  3304. switch (j->dtmfbuffer[j->dtmf_rp]) {
  3305. case 10:
  3306. retval = 42; //'*';
  3307. break;
  3308. case 11:
  3309. retval = 48; //'0';
  3310. break;
  3311. case 12:
  3312. retval = 35; //'#';
  3313. break;
  3314. case 28:
  3315. retval = 65; //'A';
  3316. break;
  3317. case 29:
  3318. retval = 66; //'B';
  3319. break;
  3320. case 30:
  3321. retval = 67; //'C';
  3322. break;
  3323. case 31:
  3324. retval = 68; //'D';
  3325. break;
  3326. default:
  3327. retval = 48 + j->dtmfbuffer[j->dtmf_rp];
  3328. break;
  3329. }
  3330. j->dtmf_rp++;
  3331. if (j->dtmf_rp == 79)
  3332. j->dtmf_rp = 0;
  3333. //          if(j->dtmf_rp == j->dtmf_wp)
  3334. {
  3335. j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;
  3336. }
  3337. }
  3338. }
  3339. break;
  3340. case PHONE_DTMF_OOB:
  3341. j->flags.dtmf_oob = arg;
  3342. break;
  3343. case PHONE_DIALTONE:
  3344. ixj_dialtone(board);
  3345. break;
  3346. case PHONE_BUSY:
  3347. ixj_busytone(board);
  3348. break;
  3349. case PHONE_RINGBACK:
  3350. ixj_ringback(board);
  3351. break;
  3352. case PHONE_CPT_STOP:
  3353. ixj_cpt_stop(board);
  3354. break;
  3355. case IXJCTL_DSP_IDLE:
  3356. idle(board);
  3357. break;
  3358. case IXJCTL_MIXER:
  3359. ixj_mixer(arg, board);
  3360. break;
  3361. case IXJCTL_DAA_COEFF_SET:
  3362. switch (arg) {
  3363. case DAA_US:
  3364. DAA_Coeff_US(board);
  3365. ixj_daa_write(board);
  3366. break;
  3367. case DAA_UK:
  3368. DAA_Coeff_UK(board);
  3369. ixj_daa_write(board);
  3370. break;
  3371. case DAA_FRANCE:
  3372. DAA_Coeff_France(board);
  3373. ixj_daa_write(board);
  3374. break;
  3375. case DAA_GERMANY:
  3376. DAA_Coeff_Germany(board);
  3377. ixj_daa_write(board);
  3378. break;
  3379. case DAA_AUSTRALIA:
  3380. DAA_Coeff_Australia(board);
  3381. ixj_daa_write(board);
  3382. break;
  3383. case DAA_JAPAN:
  3384. DAA_Coeff_Japan(board);
  3385. ixj_daa_write(board);
  3386. break;
  3387. default:
  3388. break;
  3389. }
  3390. break;
  3391. case IXJCTL_DAA_AGAIN:
  3392. ixj_daa_cr4(board, arg | 0x02);
  3393. break;
  3394. case IXJCTL_PSTN_LINETEST:
  3395. retval = ixj_linetest(board);
  3396. break;
  3397. case IXJCTL_CID:
  3398. if (copy_to_user((char *) arg, &j->cid, sizeof(IXJ_CID)))
  3399. return -EFAULT;
  3400. j->ex.bits.caller_id = 0;
  3401. break;
  3402. case IXJCTL_WINK_DURATION:
  3403. j->winktime = arg;
  3404. break;
  3405. case IXJCTL_PORT:
  3406. if (arg)
  3407. retval = ixj_set_port(board, arg);
  3408. else
  3409. retval = j->port;
  3410. break;
  3411. case IXJCTL_POTS_PSTN:
  3412. retval = ixj_set_pots(board, arg);
  3413. break;
  3414. case PHONE_CAPABILITIES:
  3415. retval = j->caps;
  3416. break;
  3417. case PHONE_CAPABILITIES_LIST:
  3418. if (copy_to_user((char *) arg, j->caplist, sizeof(struct phone_capability) * j->caps))
  3419. return -EFAULT;
  3420. break;
  3421. case PHONE_CAPABILITIES_CHECK:
  3422. retval = capabilities_check(board, (struct phone_capability *) arg);
  3423. break;
  3424. case PHONE_PSTN_SET_STATE:
  3425. daa_set_mode(board, arg);
  3426. break;
  3427. case PHONE_PSTN_GET_STATE:
  3428. retval = j->daa_mode;
  3429. j->ex.bits.pstn_ring = 0;
  3430. break;
  3431. case IXJCTL_SET_FILTER:
  3432. if (copy_from_user(&jf, (char *) arg, sizeof(ti)))
  3433. return -EFAULT;
  3434. retval = ixj_init_filter(board, &jf);
  3435. break;
  3436. case IXJCTL_GET_FILTER_HIST:
  3437. retval = j->filter_hist[arg];
  3438. break;
  3439. case IXJCTL_INIT_TONE:
  3440. copy_from_user(&ti, (char *) arg, sizeof(ti));
  3441. retval = ixj_init_tone(board, &ti);
  3442. break;
  3443. case IXJCTL_TONE_CADENCE:
  3444. retval = ixj_build_cadence(board, (IXJ_CADENCE *) arg);
  3445. break;
  3446. case IXJCTL_INTERCOM_STOP:
  3447. ixj[board].intercom = -1;
  3448. ixj[arg].intercom = -1;
  3449. ixj_record_stop(board);
  3450. ixj_record_stop(arg);