~xnox/debian/sid/dahdi-linux/nmu-659818

« back to all changes in this revision

Viewing changes to drivers/dahdi/xpp/init_card_1_30

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell, Tzafrir Cohen, Victor Seva
  • Date: 2009-05-20 07:22:46 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090520072246-y1ba8ofc81ykgf8z
Tags: 1:2.2.0~dfsg~rc4-1
* New upstream release

[ Tzafrir Cohen ]
* NOT RELEASED YET
* Dropped qozap as wcb4xxp provides that functionality.
* New upstream RC.
* Actually build OpenVox drivers.
* opvxa1200.c: rev. 1.4.12.4 (battery fixes and such)
* Fix '${match}' in udev rules file (hardwire).
* no_firmware_download: Disable downloading a binary kernel module at 
  build time.

[ Victor Seva ]
* fix debian/watch. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#
20
20
 
21
21
#
22
 
# $Id: init_card_1_30 5115 2008-10-22 08:42:22Z tzafrir $
 
22
# $Id: init_card_1_30 6407 2009-04-20 10:21:40Z tzafrir $
23
23
#
24
24
# Data format:
25
25
#       - A comment start with ';' or '#' until the end of line
47
47
 
48
48
my $program = basename("$0");
49
49
my $init_dir = dirname("$0");
50
 
BEGIN { $init_dir = dirname($0); unshift(@INC, "$init_dir", "$init_dir/zconf"); }
 
50
BEGIN { $init_dir = dirname($0); unshift(@INC, "$init_dir"); }
51
51
use XppConfig $init_dir;
52
52
my $unit_id;
53
53
my %opts;
70
70
# Arrange for error logging
71
71
if (-t STDERR) {
72
72
        $unit_id = 'Interactive';
73
 
        main::debug "Interactive startup";
 
73
        debug "Interactive startup";
74
74
} else {
75
75
        $unit_id = "$ENV{XBUS_NAME}/UNIT-$ENV{UNIT_NUMBER}";
76
76
        open (STDERR, "| logger -t $program -p kern.info") || die;
77
 
        main::debug "Non Interactive startup";
 
77
        debug "Non Interactive startup";
78
78
        foreach my $k (qw(
79
79
                        XBUS_NAME
80
80
                        XBUS_NUMBER
148
148
        
149
149
        write_to_slic_file(
150
150
                sprintf("%s R%s %02X", $read_slic, $direct, $read_reg));
151
 
        main::mysleep(0.005);
152
 
        open(SLICS,$chipregs) or 
153
 
                die("Failed reading from chipregs file $chipregs");
154
 
        #awk '/^SLIC_REPLY:/{print $5}' $SLICS | cut -dx -f2
155
 
        my @reply = ();
156
 
        while(<SLICS>){
157
 
                #if (/^ /) {
158
 
                #       main::debug "answer line: $_";
159
 
                #}
160
 
                s/#.*//;
161
 
                next unless /\S/;
162
 
                if (/^ \d*\s+[RW][DI]\s+[[:xdigit:]]+\s+([[:xdigit:]]+)\s+([[:xdigit:]]*)/){
163
 
                        @reply = (hex($1), hex($2)); 
164
 
                        #main::debug "got [$reply]";
165
 
                        last;
166
 
                } else {
167
 
                        main::logit("Got from '$chipregs' a non-matching line '$_'");
168
 
                }
 
151
        my $retries = 10;
 
152
        my @reply;
 
153
        # If the command queue is long, we may need to wait...
 
154
WAIT_RESULTS:
 
155
        {
 
156
                my @results;
 
157
 
 
158
                # The time to sleep is a tradeoff:
 
159
                #   - Too long is a waste of time.
 
160
                #   - Too short will cause many retries, wastes time.
 
161
                # So the current value (after trial and error) is...
 
162
                main::mysleep(0.013);
 
163
                open(SLICS,$chipregs) or 
 
164
                        die("Failed reading from chipregs file $chipregs");
 
165
                while(<SLICS>){
 
166
                        s/#.*//;
 
167
                        next unless /\S/;
 
168
                        @results = /^\s*(\d+)\s+[RW][DI]\s+([[:xdigit:]]+)\s+([[:xdigit:]]+)\s+([[:xdigit:]]*)/;
 
169
                        if(@results != 4) {
 
170
                                main::logit "Failed reading from '$chipregs' ($read_slic,$read_reg,$direct)";
 
171
                                die;
 
172
                        }
 
173
                }
 
174
                close(SLICS);
 
175
                my $reg = hex($results[1]);
 
176
                if($results[0] ne $read_slic || $reg ne $read_reg) {
 
177
                        # We read obsolete values, need to wait some more
 
178
                        if(--$retries) {
 
179
                                main::debug "$read_slic RD $read_reg -- retry ($results[0], $reg)";
 
180
                                redo WAIT_RESULTS;
 
181
                        } else {
 
182
                                main::logit "Failed: $read_slic RD $read_reg returned $results[0], $reg";
 
183
                                die;
 
184
                        }
 
185
                }
 
186
                # Good.
 
187
                @reply = (hex($results[2]), hex($results[3]));
 
188
 
169
189
        }
170
 
        close(SLICS);
171
 
        die("Failed reading from '$chipregs' ($read_slic,$read_reg,$direct)")
172
 
                unless @reply;
173
190
        if ($direct eq 'S') {
174
191
                return @reply;
175
192
        } else {
230
247
*       WS      1E      12      00      00
231
248
*       WS      1E      13      00      00
232
249
                          
233
 
*       WS      1E      14      F0      7E
234
 
*       WS      1E      15      C0      01
 
250
*       WS      1E      14      FD      7E
 
251
*       WS      1E      15      77      01
235
252
*       WS      1E      16      00      00
236
253
*       WS      1E      17      00      20
237
254
                          
246
263
*       WS      1E      1F      00      02
247
264
                          
248
265
*       WS      1E      20      C0      07
249
 
*       WS      1E      21      00      26
250
 
*       WS      1E      22      F4      0F
 
266
*       WS      1E      21      6F      37
 
267
*       WS      1E      22      80      1B
251
268
*       WS      1E      23      00      80
252
 
 
253
 
#*      WS      1E      24      20      03
254
 
#*      WS      1E      25      8C      08
255
 
#*      WS      1E      26      00      01
256
 
#*      WS      1E      27      10      00
257
269
                          
258
270
*       WS      1E      24      00      08
259
271
*       WS      1E      25      00      08
260
272
*       WS      1E      26      00      08
261
273
*       WS      1E      27      00      08
262
274
                          
263
 
*       WS      1E      28      00      0C
264
 
*       WS      1E      29      00      0C
265
 
*       WS      1E      2B      00      01
 
275
*       WS      1E      28      00      00
 
276
*       WS      1E      2B      00      08 # LCRTL = 5.08 mA
266
277
                          
267
278
*       WS      1E      63      DA      00
268
279
*       WS      1E      64      60      6B
277
288
sub init_early_direct_regs() {
278
289
        return write_to_slic_file("#
279
290
*       WD      08      00      # Audio Path Loopback Control
280
 
*       WD      4A      34      # High Battery Voltage
 
291
*       WD      6C      01
 
292
*       WD      4A      3F      # High Battery Voltage
281
293
*       WD      4B      10      # Low Battery Voltage
282
294
*       WD      40      00      # Line Feed Control
283
295
#")
310
322
sub manual_calibrate_loop($$) {
311
323
        my $write_reg = shift;
312
324
        my $read_reg = shift;
313
 
        
314
 
        # counters to count down to (at most) 0
315
 
        my @slic_counters = ();
316
 
        for my $i (0 .. $#SlicNums) {
317
 
                $slic_counters[$i] = 0x1F;
318
 
        }
319
 
        
320
 
        # start calibration:
321
 
        my $calibration_in_progress = 1;
322
 
        write_reg('*', $write_reg, 'D', 0x1F);
323
 
        main::mysleep $ManualCalibrationSleepTime;
324
 
        
 
325
        my @curr_slics = @SlicNums;
 
326
 
 
327
        # initialize counters
 
328
        my @slic_counters = map { 0x1F } @curr_slics;
 
329
 
325
330
        # wait until all slics have finished calibration, or for timeout
326
 
        while ($calibration_in_progress) {
327
 
                $calibration_in_progress = 0; # until proven otherwise
 
331
        while (@curr_slics) {
328
332
                my $debug_calib_str = "ManualCalib:: ";
329
 
                for my $slic(@SlicNums) {
 
333
                my @next_slics;
 
334
 
 
335
                for my $slic (@curr_slics) {
 
336
                        write_reg($slic,$write_reg,'D',$slic_counters[$slic]);
 
337
                }
 
338
                main::mysleep $ManualCalibrationSleepTime;
 
339
                for my $slic (@curr_slics) {
330
340
                        my $value = read_reg($slic, $read_reg, 'D');
331
 
                        $debug_calib_str .= " [$slic_counters[$slic]:$value]";
332
 
                        if ($value != 0 && $slic_counters[$slic] > 0) {
333
 
                                $calibration_in_progress = 1;
 
341
                        $debug_calib_str .= sprintf " [%d:%d:%X]",
 
342
                                $slic, $slic_counters[$slic], $value;
 
343
                        next if $value == 0;    # This one is calibrated.
 
344
                        if ($slic_counters[$slic] > 0) {
334
345
                                $slic_counters[$slic]--;
335
 
                                write_reg($slic,$write_reg,'D',$slic_counters[$slic]);
 
346
                                push(@next_slics, $slic);
 
347
                        } else {
 
348
                                main::logit("ERROR: SLIC $slic reached 0 during manual calibration");
336
349
                        }
337
350
                }
 
351
                @curr_slics = @next_slics;
338
352
                main::debug($debug_calib_str);
339
 
                # TODO: unnecessary sleep in the last round:
340
 
                main::mysleep $ManualCalibrationSleepTime;
341
353
        }
 
354
        main::debug("No more slics to calibrate");
342
355
}
343
356
 
344
357
sub manual_calibrate() {
352
365
 
353
366
        #log_calib_params();
354
367
        # start calibration:
355
 
        write_to_slic_file(
356
 
                sprintf
357
 
                        "* WD 60 %02X\n".
358
 
                        "* WD 61 %02X\n".
359
 
                        "", $calib_96, $calib_97
360
 
                        
361
 
        );
 
368
        for my $slic(@SlicNums) {
 
369
                write_to_slic_file(
 
370
                        sprintf
 
371
                                "$slic WD 61 %02X\n".
 
372
                                "$slic WD 60 %02X\n".
 
373
                                "", $calib_97, $calib_96
 
374
                                
 
375
                );
 
376
        }
 
377
 
362
378
        # wait until all slics have finished calibration, or for timeout
 
379
        # time periods in seconds:
 
380
        my $sleep_time = 0.001;
 
381
        my $timeout_time = 0.600; # Maximum from the spec
 
382
        my @curr_slics = @SlicNums;
363
383
        my $sleep_cnt = 0;
364
 
        # time periods in seconds:
365
 
        my $sleep_time = 0.1;
366
 
        my $timeout_time = 2; 
367
 
        CALIB_LOOP: for my $slic (@SlicNums) {
368
 
                main::debug("checking slic $slic");
369
 
                while(1) {
370
 
                        if ((read_reg($slic, 60, 'D')) == 0) {
371
 
                                # move to next register
372
 
                                main::debug("slic $slic calibrated");
373
 
                                last;
374
 
                        }
375
 
                        if ( $sleep_cnt > $timeout_time/$sleep_time) {
376
 
                                main::debug("Auto Calibration: Exiting on timeout: $timeout_time.");
377
 
                                last CALIB_LOOP;
378
 
                        }
379
 
                        main::debug("auto_calibrate not done yet: slic #$slic");
380
 
                        main::mysleep(0.1);
381
 
                        $sleep_cnt++;
382
 
                }
 
384
CALIB_LOOP:
 
385
        while(1) {
 
386
                main::mysleep($sleep_time);
 
387
                my @next_slics;
 
388
                for my $slic (@curr_slics) {
 
389
                        main::debug("checking slic $slic");
 
390
                        my $val = read_reg($slic, 96, 'D');
 
391
                        push(@next_slics, $slic) if $val != 0;
 
392
                }
 
393
                @curr_slics = @next_slics;
 
394
                last unless @curr_slics;
 
395
                if ($sleep_cnt * $sleep_time > $timeout_time) {
 
396
                        main::logit("Auto Calibration: Exiting on timeout: $timeout_time.");
 
397
                        last CALIB_LOOP;
 
398
                }
 
399
                main::debug("auto_calibrate not done yet($sleep_cnt): @curr_slics");
 
400
                $sleep_cnt++;
383
401
        }
384
402
        #log_calib_params();
385
403
}
386
404
 
387
405
sub calibrate_slics() {
388
 
        main::logit "Calibrating '$0'";
389
 
        auto_calibrate(0x47, 0x1E);
 
406
        main::debug "Calibrating '$0'";
 
407
        auto_calibrate(0x40, 0x1E);
390
408
        main::debug "after auto_calibrate";
391
409
        manual_calibrate();
392
410
        main::debug "after manul_calibrate";
393
411
        auto_calibrate(0x40, 0x01);
394
412
        main::debug "after auto_calibrate 2";
395
 
        main::logit "Continue '$0'";
 
413
        main::debug "Continue '$0'";
396
414
}
397
415
 
398
416
sub read_defaults() {
403
421
        }
404
422
}
405
423
 
 
424
# Try to identify which slics are valid
 
425
sub check_slics() {
 
426
        my @slics;
 
427
        foreach my $slic (0 .. 7) {
 
428
                my $value = read_reg($slic, 0, 'D');
 
429
                push(@slics, $slic) if $value != 0xFF;
 
430
        }
 
431
        main::logit "Found " . scalar(@slics) . " SLICS (@slics)";
 
432
        return @slics;
 
433
}
 
434
 
406
435
package main;
407
436
 
408
 
main::logit "Starting '$0'";
 
437
main::debug "Starting '$0'";
409
438
 
410
439
FXS::read_defaults;
 
440
@SlicNums = FXS::check_slics;
411
441
main::debug "before init_indirect_registers";
412
442
FXS::init_indirect_registers();
413
443
main::debug "after init_indirect_registers";
431
461
}
432
462
close REG;
433
463
 
434
 
main::logit "Ending '$0'";
 
464
main::debug "Ending '$0'";
435
465
close STDERR;
436
466
exit 0;
437
467
 
438
468
# ----------------------------------==== 8-channel FXS unit initialization ===-----------------------------------------
439
469
 
440
470
__DATA__
441
 
# Change SLICs states to "Open state"s  (Off,all transfers tristated to avoid data collision), Voltage sense
442
 
*       WD      40      00
443
471
 
444
472
# Flush out energy accumulators
445
473
*       WS      1E      58      00 00
450
478
*       WS      1E      5D      00 00
451
479
*       WS      1E      5E      00 00
452
480
*       WS      1E      5F      00 00
 
481
 
453
482
*       WS      1E      61      00 00
454
 
*       WS      1E      58      00 00
 
483
 
455
484
*       WS      1E      C1      00 00
456
485
*       WS      1E      C2      00 00
457
486
*       WS      1E      C3      00 00
471
500
*       WS      1E      D1      00 00
472
501
*       WS      1E      D2      00 00
473
502
*       WS      1E      D3      00 00
 
503
 
 
504
# Clear and disable interrupts
 
505
*       WD      12      FF
 
506
*       WD      13      FF
 
507
*       WD      14      FF
 
508
*       WD      15      00
 
509
*       WD      16      00
 
510
*       WD      17      00
474
511
                
 
512
## Mode(8-bit,u-Law,1 PCLK ) 
 
513
*       WD      01      08      # Disable PCM transfers
 
514
 
475
515
# Setting of SLICs offsets
476
516
# New card initialization
 
517
 
 
518
*       WD      03      00
 
519
*       WD      05      00
 
520
 
477
521
0       WD      02      00
478
522
0       WD      04      00
 
523
0       WD      01      28      # Enable PCM transfers
479
524
1       WD      02      08
480
525
1       WD      04      08
 
526
1       WD      01      28
481
527
2       WD      02      10
482
528
2       WD      04      10
 
529
2       WD      01      28
483
530
3       WD      02      18
484
531
3       WD      04      18
 
532
3       WD      01      28
485
533
4       WD      02      20
486
534
4       WD      04      20
 
535
4       WD      01      28
487
536
5       WD      02      28
488
537
5       WD      04      28
 
538
5       WD      01      28
489
539
6       WD      02      30
490
540
6       WD      04      30
 
541
6       WD      01      28
491
542
7       WD      02      38
492
543
7       WD      04      38
493
 
*       WD      03      00
494
 
*       WD      05      00
 
544
7       WD      01      28
495
545
 
496
546
# Audio path. (also initialize 0A and 0B here if necessary)
497
547
*       WD      08 00
498
548
*       WD      09 00
 
549
*       WD      0A 08
 
550
*       WD      0B 33
 
551
 
 
552
#------ Metering tone
 
553
*       WD      2C      00      # Timer dL
 
554
*       WD      2D      03      # Timer dH
 
555
*       WS      1E      17      61 15   # Amplitue Ramp-up
 
556
*       WS      1E      18      61 15   # Max Amplitude
 
557
*       WS      1E      19      FB 30   # Frequency
 
558
 
 
559
# Ring regs are set by driver
499
560
 
500
561
# Automatic/Manual Control: defaults but:
501
562
#       Cancel AOPN - Power Alarm
514
575
# Loop Current Limit
515
576
*       WD      47 00
516
577
 
517
 
# Ring VBath:
518
 
*       WD      4A 3F
519
 
 
520
 
 
521
 
*       WD      6C      01
 
578
# On-Hook Line Voltage (VOC)
 
579
*       WD      48 20
 
580
 
 
581
# Common Mode Voltage (VCM)
 
582
*       WD      49 03
522
583
 
523
584
*       WS      1E      23      00 80
524
585
*       WS      1E      24      20 03
525
 
*       WS      1E      25      8C 08
526
 
*       WS      1E      26      00 01
 
586
*       WS      1E      25      8C 00
 
587
*       WS      1E      26      00 00
527
588
*       WS      1E      27      10 00
528
589
 
529
 
#------ Metering tone
530
 
*       WS      1E      17      61 15   # Amplitue Ramp-up
531
 
*       WS      1E      18      61 15   # Max Amplitude
532
 
*       WS      1E      19      FB 30   # Frequency
533
 
*       WD      2C      00      # Timer dL
534
 
*       WD      2D      03      # Timer dH
535
 
 
536
 
# ------------------------------------- Initialization of direct registers --------------------------------------------
537
 
 
538
 
# Mode(8-bit,u-Law,1 PCLK ) setting, Loopbacks and Interrupts clear
539
 
 
540
 
*       WD      01      29
541
 
#*      WD      0E      00  
542
 
 
543
 
#*      WD      15 00
544
 
#*      WD      16 03
545
 
 
546
 
# Clear pending interrupts
547
 
*       WD      12 FF
548
 
*       WD      13 FF
549
 
*       WD      14 FF 
550
 
 
551
 
#*      WD      4A 34
552
 
#*      WD      4B 10
 
590
*       WD      0E 00