Review Board 1.7.16


Generate VMWI neon pulses from FXS module to light NEON lamp on older 'non intellegent phones'

Review Request #1144 - Created March 16, 2011 and updated

Alec Davis
dahdi/linux
14261
Reviewers
asterisk-dev
sruffell
DAHDI
Implement same code as for wcdtm
13/04/12
Tested with mwisendtype=lrev,hvac
at 2 different phones on same FXS port, one a real neon phone, and another a led+zener phone.
Left messages, and neon would flash as expected.

Diff revision 6

This is not the most recent revision of the diff. The latest diff is revision 7. See what's changed.

1 2 3 4 5 6 7
1 2 3 4 5 6 7

  1. linux/trunk/drivers/dahdi/wctdm24xxp/base.c: Loading...
  2. linux/trunk/drivers/dahdi/wctdm24xxp/wctdm24xxp.h: Loading...
linux/trunk/drivers/dahdi/wctdm24xxp/base.c
Revision 10660 New Change
[20] 106 lines
[+20] [+] static int loopcurrent = 20;
107
 * 	polarity reversal for the port,
107
 * 	polarity reversal for the port,
108
 * 	and the state of the line reversal MWI indicator
108
 * 	and the state of the line reversal MWI indicator
109
 */
109
 */
110
#define POLARITY_XOR(fxs) \
110
#define POLARITY_XOR(fxs) \
111
	((reversepolarity != 0) ^ ((fxs)->reversepolarity != 0) ^ \
111
	((reversepolarity != 0) ^ ((fxs)->reversepolarity != 0) ^ \
112
	((fxs)->vmwi_linereverse != 0))
112
	((fxs)->vmwi_linereverse != 0) ^ (((fxs)->vmwisetting.vmwi_type & DAHDI_VMWI_HVAC) != 0))
113

    
   
113

   
114
static int reversepolarity = 0;
114
static int reversepolarity = 0;
115

    
   
115

   
116
static alpha  indirect_regs[] =
116
static alpha  indirect_regs[] =
117
{
117
{
[+20] [20] 159 lines
[+20] [+] static const struct dahdi_echocan_ops vpm_ec_ops = {
277

    
   
277

   
278
static int
278
static int
279
wctdm_init_proslic(struct wctdm *wc, struct wctdm_module *const mod, int fast,
279
wctdm_init_proslic(struct wctdm *wc, struct wctdm_module *const mod, int fast,
280
		   int manual, int sane);
280
		   int manual, int sane);
281

    
   
281

   

    
   
282
static int

    
   
283
wctdm_init_ring_generator_mode(struct wctdm *wc, struct wctdm_module *const mod);

    
   
284

   

    
   
285
static int

    
   
286
wctdm_set_ring_generator_mode(struct wctdm *wc, struct wctdm_module *const mod, int mode);

    
   
287

   
282
static void set_offsets(struct wctdm_module *const mod, int altcs)
288
static void set_offsets(struct wctdm_module *const mod, int altcs)
283
{
289
{
284
	int card = mod->card;
290
	int card = mod->card;
285
	int bit;
291
	int bit;
286

    
   
292

   
[+20] [20] 1263 lines
[+20] [+] static unsigned char translate_3215(unsigned char address)
1550
	}
1556
	}
1551
	return address;
1557
	return address;
1552
}
1558
}
1553

    
   
1559

   
1554
static int
1560
static int

    
   
1561
wctdm_proslic_setreg_indirect_intr(struct wctdm *wc, struct wctdm_module *const mod,

    
   
1562
			      unsigned char address, unsigned short data)

    
   
1563
{

    
   
1564
	int res = -1;

    
   
1565

   

    
   
1566
	address = translate_3215(address);

    
   
1567
	if (address == 255)

    
   
1568
		return 0;

    
   
1569

   

    
   
1570
//	if (!wait_access(wc, mod)) {

    
   
1571
		wctdm_setreg_intr(wc, mod, IDA_LO, (u8)(data & 0xFF));

    
   
1572
		wctdm_setreg_intr(wc, mod, IDA_HI, (u8)((data & 0xFF00)>>8));

    
   
1573
		wctdm_setreg_intr(wc, mod, IAA, address);

    
   
1574
		res = 0;

    
   
1575
//	};

    
   
1576
	return res;

    
   
1577
}

    
   
1578

   

    
   
1579
static int
1555
wctdm_proslic_setreg_indirect(struct wctdm *wc, struct wctdm_module *const mod,
1580
wctdm_proslic_setreg_indirect(struct wctdm *wc, struct wctdm_module *const mod,
1556
			      unsigned char address, unsigned short data)
1581
			      unsigned char address, unsigned short data)
1557
{
1582
{
1558
	int res = -1;
1583
	int res = -1;
1559

    
   
1584

   
[+20] [20] 179 lines
[+20] [+] wctdm_proslic_recheck_sanity(struct wctdm *wc, struct wctdm_module *const mod)
1739
				   "Power alarm on module %d, resetting!\n",
1764
				   "Power alarm on module %d, resetting!\n",
1740
				   mod->card + 1);
1765
				   mod->card + 1);
1741
			if (fxs->lasttxhook == SLIC_LF_RINGING) {
1766
			if (fxs->lasttxhook == SLIC_LF_RINGING) {
1742
				fxs->lasttxhook = POLARITY_XOR(fxs) ?
1767
				fxs->lasttxhook = POLARITY_XOR(fxs) ?
1743
							SLIC_LF_ACTIVE_REV :
1768
							SLIC_LF_ACTIVE_REV :
1744
							SLIC_LF_ACTIVE_FWD;;
1769
							SLIC_LF_ACTIVE_FWD;
1745
			}
1770
			}
1746
			fxs->lasttxhook |= SLIC_LF_OPPENDING;
1771
			fxs->lasttxhook |= SLIC_LF_OPPENDING;
1747
			mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook);
1772
			mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook);
1748
			fxs->oppending_timeout = wc->framecount + 100;
1773
			fxs->oppending_timeout = wc->framecount + 100;
1749

    
   
1774

   
[+20] [20] 511 lines
[+20] [+] wctdm_fxs_hooksig(struct wctdm *wc, struct wctdm_module *const mod,
2261
		case DAHDI_SIG_FXOGS:
2286
		case DAHDI_SIG_FXOGS:
2262
			x = (POLARITY_XOR(fxs)) ?
2287
			x = (POLARITY_XOR(fxs)) ?
2263
					SLIC_LF_RING_OPEN :
2288
					SLIC_LF_RING_OPEN :
2264
					SLIC_LF_TIP_OPEN;
2289
					SLIC_LF_TIP_OPEN;
2265
			break;
2290
			break;
2266
		case DAHDI_SIG_EM:

   
2267
		case DAHDI_SIG_FXOKS:
2291
		case DAHDI_SIG_FXOKS:
2268
		case DAHDI_SIG_FXOLS:
2292
		case DAHDI_SIG_FXOLS:

    
   
2293
			/* Can't change Ring Generator during OHT */

    
   
2294
			if (!fxs->ohttimer) {

    
   
2295
				wctdm_set_ring_generator_mode(wc, mod, fxs->vmwi_hvac);

    
   
2296
				x = fxs->vmwi_hvac ?

    
   
2297
					SLIC_LF_RINGING :

    
   
2298
					fxs->idletxhookstate;

    
   
2299
			} else

    
   
2300
				x = fxs->idletxhookstate;

    
   
2301
			break;

    
   
2302
		case DAHDI_SIG_EM:
2269
		default:
2303
		default:
2270
			x = fxs->idletxhookstate;
2304
			x = fxs->idletxhookstate;
2271
			break;
2305
			break;
2272
		}
2306
		}
2273
		break;
2307
		break;
2274
	case DAHDI_TXSIG_OFFHOOK:
2308
	case DAHDI_TXSIG_OFFHOOK:
2275
		switch (get_dahdi_chan(wc, mod)->sig) {
2309
		switch (get_dahdi_chan(wc, mod)->sig) {
2276
		case DAHDI_SIG_EM:
2310
		case DAHDI_SIG_EM:
2277
			x = (POLARITY_XOR(fxs)) ?
2311
			x = POLARITY_XOR(fxs) ?
2278
					SLIC_LF_ACTIVE_FWD :
2312
					SLIC_LF_ACTIVE_FWD :
2279
					SLIC_LF_ACTIVE_REV;
2313
					SLIC_LF_ACTIVE_REV;
2280
			break;
2314
			break;
2281
		default:
2315
		default:
2282
			x = fxs->idletxhookstate;
2316
			x = fxs->idletxhookstate;
2283
			break;
2317
			break;
2284
		}
2318
		}
2285
		break;
2319
		break;
2286
	case DAHDI_TXSIG_START:
2320
	case DAHDI_TXSIG_START:

    
   
2321
		wctdm_set_ring_generator_mode(wc, mod, 0); /* Set ringer mode */
2287
		x = SLIC_LF_RINGING;
2322
		x = SLIC_LF_RINGING;
2288
		break;
2323
		break;
2289
	case DAHDI_TXSIG_KEWL:
2324
	case DAHDI_TXSIG_KEWL:
2290
		x = SLIC_LF_OPEN;
2325
		x = SLIC_LF_OPEN;
2291
		break;
2326
		break;
[+20] [20] 163 lines
[+20] [+] static void wctdm_isr_misc_fxs(struct wctdm *wc, struct wctdm_module *const mod)
2455
	if (time_after(wc->framecount, fxs->check_proslic)) {
2490
	if (time_after(wc->framecount, fxs->check_proslic)) {
2456
		fxs->check_proslic = wc->framecount + 250; /* every 250ms */
2491
		fxs->check_proslic = wc->framecount + 250; /* every 250ms */
2457
		wctdm_proslic_recheck_sanity(wc, mod);
2492
		wctdm_proslic_recheck_sanity(wc, mod);
2458
	}
2493
	}
2459

    
   
2494

   
2460
	if (SLIC_LF_RINGING == fxs->lasttxhook) {
2495
	if ((SLIC_LF_RINGING == fxs->lasttxhook) && fxs->neonringing) {

    
   
2496

   
2461
		/* RINGing, prepare for OHT */
2497
		/* RINGing, prepare for OHT */
2462
		fxs->ohttimer = wc->framecount + OHT_TIMER;
2498
		fxs->ohttimer = wc->framecount + OHT_TIMER;
2463
		/* OHT mode when idle */
2499
		/* OHT mode when idle */
2464
		fxs->idletxhookstate = POLARITY_XOR(fxs) ? SLIC_LF_OHTRAN_REV :
2500
		fxs->idletxhookstate = POLARITY_XOR(fxs) ? SLIC_LF_OHTRAN_REV :
2465
							    SLIC_LF_OHTRAN_FWD;
2501
							    SLIC_LF_OHTRAN_FWD;
[+20] [20] 5 lines
[+20] static void wctdm_isr_misc_fxs(struct wctdm *wc, struct wctdm_module *const mod)
2471

    
   
2507

   
2472
			/* Switch to active */
2508
			/* Switch to active */
2473
			fxs->idletxhookstate = POLARITY_XOR(fxs) ? SLIC_LF_ACTIVE_REV :
2509
			fxs->idletxhookstate = POLARITY_XOR(fxs) ? SLIC_LF_ACTIVE_REV :
2474
								    SLIC_LF_ACTIVE_FWD;
2510
								    SLIC_LF_ACTIVE_FWD;
2475
			spin_lock(&wc->reglock);
2511
			spin_lock(&wc->reglock);
2476
			if (SLIC_LF_OHTRAN_FWD == fxs->lasttxhook) {
2512
			if ((SLIC_LF_OHTRAN_FWD == fxs->lasttxhook) ||
2477
				/* Apply the change if appropriate */
2513
				(SLIC_LF_OHTRAN_REV == fxs->lasttxhook)) {
2478
				fxs->lasttxhook = SLIC_LF_OPPENDING | SLIC_LF_ACTIVE_FWD;
2514
				if (fxs->vmwi_hvac) {
2479
				/* Data enqueued here */
2515
					/* force idle polarity Forward if ringing */
2480
				mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook);
2516
					fxs->idletxhookstate = SLIC_LF_ACTIVE_FWD;
2481
				if (debug & DEBUG_CARD) {
2517
					/* Set ring generator for neon */
2482
					dev_info(&wc->vb.pdev->dev,
2518
					wctdm_set_ring_generator_mode(wc, mod, 1);
2483
						 "Channel %d OnHookTransfer "
2519
					fxs->lasttxhook = (SLIC_LF_OPPENDING |
2484
						 "stop\n", mod->card);
2520
							SLIC_LF_RINGING);
2485
				}
2521
				} else
2486
			} else if (SLIC_LF_OHTRAN_REV == fxs->lasttxhook) {
2522
					fxs->lasttxhook = (SLIC_LF_OPPENDING |
2487
				/* Apply the change if appropriate */
2523
							fxs->idletxhookstate);
2488
				fxs->lasttxhook = SLIC_LF_OPPENDING | SLIC_LF_ACTIVE_REV;
2524

   
2489
				/* Data enqueued here */
2525
				/* Data enqueued here */
2490
				mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook);
2526
				mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook);
2491
				if (debug & DEBUG_CARD) {
2527
				if (debug & DEBUG_CARD) {
2492
					dev_info(&wc->vb.pdev->dev,
2528
					dev_info(&wc->vb.pdev->dev,
2493
						 "Channel %d OnHookTransfer "
2529
						 "Channel %d OnHookTransfer "
[+20] [20] 510 lines
[+20] [+] static int set_lasttxhook_interruptible(struct wctdm *wc, struct fxs *fxs,
3004
static int set_vmwi(struct wctdm *wc, struct wctdm_module *const mod)
3040
static int set_vmwi(struct wctdm *wc, struct wctdm_module *const mod)
3005
{
3041
{
3006
	int x;
3042
	int x;
3007
	struct fxs *const fxs = &mod->mod.fxs;
3043
	struct fxs *const fxs = &mod->mod.fxs;
3008

    
   
3044

   
3009
	/* Presently only supports line reversal MWI */
3045
	/* Presently supports line reversal MWI and NEON dc pulses */
3010
	if ((fxs->vmwi_active_messages) &&
3046
	if (fxs->vmwi_active_messages) {
3011
	    (fxs->vmwisetting.vmwi_type & DAHDI_VMWI_LREV))
3047
		fxs->vmwi_linereverse = (fxs->vmwisetting.vmwi_type & DAHDI_VMWI_LREV) ? 1 : 0;
3012
		fxs->vmwi_linereverse = 1;
3048
		fxs->vmwi_hvac = (fxs->vmwisetting.vmwi_type & DAHDI_VMWI_HVAC) ? 1 : 0;
3013
	else
3049
	} else {
3014
		fxs->vmwi_linereverse = 0;
3050
		fxs->vmwi_linereverse = 0;

    
   
3051
		fxs->vmwi_hvac = 0;

    
   
3052
	}

    
   
3053

   

    
   
3054
	if (fxs->vmwi_hvac) {

    
   
3055
		/* Can't change ring generator while On Hook Transfer might be happening */

    
   
3056
		if (!fxs->ohttimer) {

    
   
3057
			/* Set line polarity for new VMWI state */

    
   
3058
			if (POLARITY_XOR(fxs))

    
   
3059
				fxs->idletxhookstate |= SLIC_LF_REVMASK;

    
   
3060
			else

    
   
3061
				fxs->idletxhookstate &= ~SLIC_LF_REVMASK;

    
   
3062

   

    
   
3063
			/* Set ring generator for neon */

    
   
3064
			wctdm_set_ring_generator_mode(wc, mod, 1);

    
   
3065
			set_lasttxhook_interruptible(wc, fxs, fxs->lasttxhook, &mod->sethook);

    
   
3066
		}

    
   
3067
	} else {

    
   
3068
		if (fxs->neonringing) {

    
   
3069
			/* Set ring generator for normal ringer */

    
   
3070
			wctdm_set_ring_generator_mode(wc, mod, 0);

    
   
3071
			/* ACTIVE, polarity determined later */

    
   
3072
			fxs->lasttxhook = SLIC_LF_ACTIVE_FWD;

    
   
3073
		} else {

    
   
3074
			/* Can't change polarity while ringing or when open */

    
   
3075
			if ((fxs->lasttxhook == SLIC_LF_RINGING) ||

    
   
3076
				(fxs->lasttxhook == SLIC_LF_OPEN)) {

    
   
3077
				/* Set line polarity for new VMWI state */

    
   
3078
				if (POLARITY_XOR(fxs))

    
   
3079
					fxs->idletxhookstate |= SLIC_LF_REVMASK;

    
   
3080
				else

    
   
3081
					fxs->idletxhookstate &= ~SLIC_LF_REVMASK;

    
   
3082

   

    
   
3083
				dev_info(&wc->vb.pdev->dev,

    
   
3084
					"Unable to change polarity on channel %d, lasttxhook=0x%X\n",

    
   
3085
					mod->card,

    
   
3086
					fxs->lasttxhook

    
   
3087
					);

    
   
3088
				return 0;

    
   
3089
			}

    
   
3090
		}
3015

    
   
3091

   
3016
	/* Set line polarity for new VMWI state */
3092
		/* Set line polarity for new VMWI state */
3017
	if (POLARITY_XOR(fxs)) {
3093
		if (POLARITY_XOR(fxs)) {
3018
		fxs->idletxhookstate |= SLIC_LF_REVMASK;
3094
			fxs->idletxhookstate |= SLIC_LF_REVMASK;
3019
		/* Do not set while currently ringing or open */

   
3020
		if (((fxs->lasttxhook & SLIC_LF_SETMASK) != SLIC_LF_RINGING)  &&

   
3021
		    ((fxs->lasttxhook & SLIC_LF_SETMASK) != SLIC_LF_OPEN)) {

   
3022
			x = fxs->lasttxhook;
3095
			x = fxs->lasttxhook;
3023
			x |= SLIC_LF_REVMASK;
3096
			x |= SLIC_LF_REVMASK;
3024
			set_lasttxhook_interruptible(wc, fxs, x, &mod->sethook);

   
3025
		}

   
3026
	} else {
3097
		} else {
3027
		fxs->idletxhookstate &= ~SLIC_LF_REVMASK;
3098
			fxs->idletxhookstate &= ~SLIC_LF_REVMASK;
3028
		/* Do not set while currently ringing or open */

   
3029
		if (((fxs->lasttxhook & SLIC_LF_SETMASK) != SLIC_LF_RINGING) &&

   
3030
		    ((fxs->lasttxhook & SLIC_LF_SETMASK) != SLIC_LF_OPEN)) {

   
3031
			x = fxs->lasttxhook;
3099
			x = fxs->lasttxhook;
3032
			x &= ~SLIC_LF_REVMASK;
3100
			x &= ~SLIC_LF_REVMASK;
3033
			set_lasttxhook_interruptible(wc, fxs, x, &mod->sethook);

   
3034
		}
3101
		}

    
   
3102
		set_lasttxhook_interruptible(wc, fxs, x, &mod->sethook);
3035
	}
3103
	}
3036
	if (debug) {
3104
	if (debug) {
3037
		dev_info(&wc->vb.pdev->dev,
3105
		dev_info(&wc->vb.pdev->dev,
3038
			 "Setting VMWI on channel %d, messages=%d, lrev=%d\n",
3106
			"Setting VMWI on channel %d, messages=%d, lrev=%d hvac=%d\n",
3039
			 mod->card, fxs->vmwi_active_messages,
3107
			mod->card, fxs->vmwi_active_messages,
3040
			 fxs->vmwi_linereverse);
3108
			fxs->vmwi_linereverse, fxs->vmwi_hvac);

    
   
3109

   
3041
	}
3110
	}
3042
	return 0;
3111
	return 0;
3043
}
3112
}
3044

    
   
3113

   
3045
static void
3114
static void
[+20] [20] 354 lines
[+20] [+] wctdm_init_proslic(struct wctdm *wc, struct wctdm_module *const mod,
3400
    wctdm_setreg(wc, card, 14, 0x0);
3469
    wctdm_setreg(wc, card, 14, 0x0);
3401
    wctdm_setreg(wc, card, 64, 0x0);
3470
    wctdm_setreg(wc, card, 64, 0x0);
3402
    wctdm_setreg(wc, card, 1, 0x08);
3471
    wctdm_setreg(wc, card, 1, 0x08);
3403
#endif
3472
#endif
3404

    
   
3473

   
3405
	if (fastringer) {
3474
	if (wctdm_init_ring_generator_mode(wc, mod))
3406
		/* Speed up Ringer */

   
3407
		wctdm_proslic_setreg_indirect(wc, mod, 20, 0x7e6d);

   
3408
		wctdm_proslic_setreg_indirect(wc, mod, 21, 0x01b9);

   
3409
		/* Beef up Ringing voltage to 89V */
Moved to 4271

   
3410
		if (boostringer) {
Moved to 4272

   
3411
			wctdm_setreg(wc, mod, 74, 0x3f);

   
3412
			if (wctdm_proslic_setreg_indirect(wc, mod, 21, 0x247))

   
3413
				return -1;

   
3414
			dev_info(&wc->vb.pdev->dev,

   
3415
				 "Boosting fast ringer on slot %d (89V peak)\n",

   
3416
				 mod->card + 1);

   
3417
		} else if (lowpower) {

   
3418
			if (wctdm_proslic_setreg_indirect(wc, mod, 21, 0x14b))

   
3419
				return -1;

   
3420
			dev_info(&wc->vb.pdev->dev,

   
3421
				 "Reducing fast ring power on slot %d "

   
3422
				 "(50V peak)\n", mod->card + 1);

   
3423
		} else

   
3424
			dev_info(&wc->vb.pdev->dev,

   
3425
				 "Speeding up ringer on slot %d (25Hz)\n",

   
3426
				 mod->card + 1);

   
3427
	} else {

   
3428
		/* Beef up Ringing voltage to 89V */

   
3429
		if (boostringer) {

   
3430
			wctdm_setreg(wc, mod, 74, 0x3f);

   
3431
			if (wctdm_proslic_setreg_indirect(wc, mod, 21, 0x1d1))

   
3432
				return -1;

   
3433
			dev_info(&wc->vb.pdev->dev,

   
3434
				 "Boosting ringer on slot %d (89V peak)\n",

   
3435
				 mod->card + 1);

   
3436
		} else if (lowpower) {

   
3437
			if (wctdm_proslic_setreg_indirect(wc, mod, 21, 0x108))

   
3438
				return -1;
3475
		return -1;
3439
			dev_info(&wc->vb.pdev->dev,

   
3440
				 "Reducing ring power on slot %d "

   
3441
				 "(50V peak)\n", mod->card + 1);

   
3442
		}

   
3443
	}

   
3444

    
   
3476

   
3445
	if (fxstxgain || fxsrxgain) {
3477
	if (fxstxgain || fxsrxgain) {
3446
		r9 = wctdm_getreg(wc, mod, 9);
3478
		r9 = wctdm_getreg(wc, mod, 9);
3447
		switch (fxstxgain) {
3479
		switch (fxstxgain) {
3448
		
3480
		
[+20] [20] 276 lines
[+20] [+] static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
3725
		/* Active mode when idle */
3757
		/* Active mode when idle */
3726
		fxs->idletxhookstate = POLARITY_XOR(fxs) ?
3758
		fxs->idletxhookstate = POLARITY_XOR(fxs) ?
3727
						SLIC_LF_ACTIVE_REV :
3759
						SLIC_LF_ACTIVE_REV :
3728
						SLIC_LF_ACTIVE_FWD;
3760
						SLIC_LF_ACTIVE_FWD;
3729

    
   
3761

   

    
   
3762
		if (fxs->neonringing) {

    
   
3763
			/* keep same Forward polarity */

    
   
3764
			fxs->lasttxhook = SLIC_LF_OHTRAN_FWD;

    
   
3765
			set_lasttxhook_interruptible(wc, fxs, fxs->lasttxhook, &mod->sethook);

    
   
3766
		} else {
3730
		if (((fxs->lasttxhook & SLIC_LF_SETMASK) == SLIC_LF_ACTIVE_FWD) ||
3767
			if (((fxs->lasttxhook & SLIC_LF_SETMASK) == SLIC_LF_ACTIVE_FWD) ||
3731
		    ((fxs->lasttxhook & SLIC_LF_SETMASK) == SLIC_LF_ACTIVE_REV)) {
3768
			    ((fxs->lasttxhook & SLIC_LF_SETMASK) == SLIC_LF_ACTIVE_REV)) {
3732
			int res;
3769
				int res;
3733

    
   
3770

   
3734
			res = set_lasttxhook_interruptible(wc, fxs,
3771
				res = set_lasttxhook_interruptible(wc, fxs,
[+20] [20] 11 lines
[+20] static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
3746
					dev_info(&wc->vb.pdev->dev,
3783
						dev_info(&wc->vb.pdev->dev,
3747
						 "Channel %d OnHookTransfer "
3784
							 "Channel %d OnHookTransfer "
3748
						 "start\n", chan->chanpos - 1);
3785
							 "start\n", chan->chanpos - 1);
3749
				}
3786
					}
3750
			}
3787
				}
3751

    
   

   
3752
		}
3788
			}

    
   
3789
		}
3753

    
   
3790

   
3754
		fxs->ohttimer = wc->framecount + x;
3791
		fxs->ohttimer = wc->framecount + x;
3755
		fxs->oht_active = 1;
3792
		fxs->oht_active = 1;
3756

    
   
3793

   
3757
		break;
3794
		break;
[+20] [20] 369 lines
[+20] [+] static int wctdm_close(struct dahdi_chan *chan)
4127
	}
4164
	}
4128

    
   
4165

   
4129
	return 0;
4166
	return 0;
4130
}
4167
}
4131

    
   
4168

   

    
   
4169
static int wctdm_init_ring_generator_mode(struct wctdm *wc, struct wctdm_module *const mod)

    
   
4170
{

    
   
4171
	unsigned long flags;

    
   
4172

   

    
   
4173
	wctdm_setreg(wc, mod, RING_OSC_CTL, 0x00);		/* Ringing Osc. Control */

    
   
4174

   

    
   
4175
								/* neon trapezoid timers */

    
   
4176
	wctdm_setreg(wc, mod, RING_ON__LO, 0xe0);		/* Active Timer low byte */

    
   
4177
	wctdm_setreg(wc, mod, RING_ON_HI, 0x01);		/* Active Timer high byte */

    
   
4178
	wctdm_setreg(wc, mod, RING_OFF_LO, 0xf0);		/* Inactive Timer low byte */

    
   
4179
	wctdm_setreg(wc, mod, RING_OFF_HI, 0x05);		/* Inactive Timer high byte */

    
   
4180

   

    
   
4181
	spin_lock_irqsave(&wc->reglock, flags);

    
   
4182
	wctdm_set_ring_generator_mode(wc, mod, 0);

    
   
4183
	spin_unlock_irqrestore(&wc->reglock, flags);

    
   
4184

   

    
   
4185
	return 0;

    
   
4186
}

    
   
4187

   

    
   
4188
/* Must be called with wc.reglock held and local interrupts disabled */

    
   
4189
static int wctdm_set_ring_generator_mode(struct wctdm *wc, struct wctdm_module *const mod, int mode)

    
   
4190
{

    
   
4191
	struct fxs *const fxs = &mod->mod.fxs;

    
   
4192
	int reg20,reg21,reg74; /* RCO, RNGX, VBATH */

    
   
4193

   

    
   
4194
	fxs->neonringing = mode;   /* track ring generator mode */

    
   
4195

   

    
   
4196
	if (mode) { /* Neon */

    
   
4197
		if (debug) {

    
   
4198
			dev_info(&wc->vb.pdev->dev,

    
   
4199
				"Neon ring on channel %d, lasttxhook was 0x%x\n",

    
   
4200
				mod->card,

    
   
4201
				fxs->lasttxhook

    
   
4202
				);

    
   
4203
		}

    
   
4204

   

    
   
4205
		/* Must be in FORWARD ACTIVE before setting up ringer */

    
   
4206
		fxs->lasttxhook = SLIC_LF_ACTIVE_FWD;

    
   
4207
		wctdm_setreg_intr(wc, mod, LINE_STATE, fxs->lasttxhook);

    
   
4208

   

    
   
4209
		wctdm_proslic_setreg_indirect_intr(wc, mod, RING_Y, 0x03e8);		/* 4 HZ */

    
   
4210
		wctdm_proslic_setreg_indirect_intr(wc, mod, RING_X, 0x7bef);		/* 91.5Vpk */

    
   
4211
		wctdm_proslic_setreg_indirect_intr(wc, mod, RING_OSC_COEF, 0x009f);	/* (RNGX, t rise) */

    
   
4212

   

    
   
4213
		wctdm_setreg_intr(wc, mod, RING_OSC_CTL, 0x19);				/* Ringing Osc. Control */

    
   
4214
		wctdm_setreg_intr(wc, mod, BAT_V_HI, 0x3f);				/* 94.5V */

    
   
4215
		wctdm_proslic_setreg_indirect_intr(wc, mod, RING_TRIP_THRESH, 0x4600);

    
   
4216
		/* A write of 0x04 to register LINE_STATE(64) will turn on the VM neon */

    
   
4217

   

    
   
4218
	} else {

    
   
4219
		if (debug) {

    
   
4220
			dev_info(&wc->vb.pdev->dev,

    
   
4221
				"Normal ring on channel %d, lasttxhook was 0x%x\n",

    
   
4222
				mod->card,

    
   
4223
				fxs->lasttxhook

    
   
4224
				);

    
   
4225
		}

    
   
4226

   

    
   
4227
		wctdm_setreg_intr(wc, mod, RING_OSC_CTL, 0x00);				/* Ringing Osc. Control */

    
   
4228
		wctdm_proslic_setreg_indirect_intr(wc, mod, RING_Y, 0x0000);		/* RNGY Initial Phase */

    
   
4229
		wctdm_proslic_setreg_indirect_intr(wc, mod, RING_TRIP_THRESH, 0x3600);	/* RPTP */

    
   
4230
		/* A write of 0x04 to register LINE_STATE(64) will turn on the ringer */

    
   
4231

   

    
   
4232
		if (fastringer) {

    
   
4233
			/* Speed up Ringer */

    
   
4234
			reg20 =  0x7e6d;

    
   
4235

   

    
   
4236
			reg74 = 0x32;	/* Default */
Moved from 3409

    
   
4237
			/* Beef up Ringing voltage to 89V */
Moved from 3410

    
   
4238
			if (boostringer) {

    
   
4239
				reg74 = 0x3f;

    
   
4240
				reg21 = 0x0247; /* RNGX */

    
   
4241
				if (debug)

    
   
4242
					printk(KERN_DEBUG "Boosting fast ringer on channel %d (89V peak)\n", mod->card);

    
   
4243
			} else if (lowpower) {

    
   
4244
				reg21 = 0x014b; /* RNGX */

    
   
4245
				if (debug)

    
   
4246
					printk(KERN_DEBUG "Reducing fast ring power on channel %d (50V peak)\n", mod->card);

    
   
4247
			} else if (fxshonormode && fxo_modes[_opermode].ring_x) {

    
   
4248
				reg21 = fxo_modes[_opermode].ring_x;

    
   
4249
				if (debug)

    
   
4250
					printk(KERN_DEBUG "fxshonormode: fast ring_x power on channel %d\n", mod->card);

    
   
4251
			} else {

    
   
4252
				reg21 = 0x01b9;

    
   
4253
				if (debug)

    
   
4254
					printk(KERN_DEBUG "Speeding up ringer on channel %d (25Hz)\n", mod->card);

    
   
4255
			}

    
   
4256
			wctdm_setreg_intr(wc, mod, BAT_V_HI, reg74);

    
   
4257
			wctdm_proslic_setreg_indirect_intr(wc, mod, RING_OSC_COEF, reg20);

    
   
4258
			wctdm_proslic_setreg_indirect_intr(wc, mod, RING_X, reg21);

    
   
4259

   

    
   
4260
		} else {

    
   
4261
			/* Ringer Speed */

    
   
4262
			if (fxshonormode && fxo_modes[_opermode].ring_osc) {

    
   
4263
				reg20 = fxo_modes[_opermode].ring_osc;

    
   
4264
				if (debug)

    
   
4265
					printk(KERN_DEBUG "fxshonormode: ring_osc speed on channel %d\n", mod->card);

    
   
4266
			} else {

    
   
4267
				reg20 = 0x7ef0; /* Default */

    
   
4268
			}

    
   
4269

   

    
   
4270
			reg74 = 0x32;   /* Default */
Moved from 3409

    
   
4271
			/* Beef up Ringing voltage to 89V */
Moved from 3410

    
   
4272
			if (boostringer) {

    
   
4273
				reg74 = 0x3f;

    
   
4274
				reg21 = 0x1d1;

    
   
4275
				if (debug)

    
   
4276
					printk(KERN_DEBUG "Boosting ringer on channel %d (89V peak)\n", mod->card);

    
   
4277
			} else if (lowpower) {

    
   
4278
				reg21 = 0x108;

    
   
4279
				if (debug)

    
   
4280
					printk(KERN_DEBUG "Reducing ring power on channel %d (50V peak)\n", mod->card);

    
   
4281
			} else if (fxshonormode && fxo_modes[_opermode].ring_x) {

    
   
4282
				reg21 = fxo_modes[_opermode].ring_x;

    
   
4283
				if (debug)

    
   
4284
					printk(KERN_DEBUG "fxshonormode: ring_x power on channel %d\n", mod->card);

    
   
4285
			} else {

    
   
4286
				reg21 = 0x160;

    
   
4287
				if (debug)

    
   
4288
					printk(KERN_DEBUG "Normal ring power on channel %d\n", mod->card);

    
   
4289
			}

    
   
4290
			wctdm_setreg_intr(wc, mod, BAT_V_HI, reg74);

    
   
4291
			wctdm_proslic_setreg_indirect_intr(wc, mod, RING_OSC_COEF, reg20);

    
   
4292
			wctdm_proslic_setreg_indirect_intr(wc, mod, RING_X, reg21);

    
   
4293
		}

    
   
4294
	}

    
   
4295
	return 0;

    
   
4296
}

    
   
4297

   

    
   
4298

   
4132
static int wctdm_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
4299
static int wctdm_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
4133
{
4300
{
4134
	struct wctdm *wc = chan->pvt;
4301
	struct wctdm *wc = chan->pvt;
4135
	int reg = 0;
4302
	int reg = 0;
4136
	struct wctdm_module *const mod = &wc->mods[chan->chanpos - 1];
4303
	struct wctdm_module *const mod = &wc->mods[chan->chanpos - 1];
[+20] [20] 2098 lines
linux/trunk/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
Revision 10660 New Change
 
  1. linux/trunk/drivers/dahdi/wctdm24xxp/base.c: Loading...
  2. linux/trunk/drivers/dahdi/wctdm24xxp/wctdm24xxp.h: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.