file: board.c

/* * This file contains the "board" software module. It contains constant * definitions and C functions that interface directly with the * SoundLight boards. */ # define __KERNEL__ #endif # define MODULE #endif #define __NO_VERSION__ #include <linux/module.h> #include <linux/version.h> #include <linux/kernel.h> #include <linux/ioport.h> #include <linux/delay.h> #include <linux/errno.h> #include <asm/io.h> /* local definitions */ #include "slh.h" /* prevent symbols from this file from * being accessed by any part of the * kernel outside of this driver. */ EXPORT_NO_SYMBOLS; /* macros to get high and low byte of address */ #define ADDR_HI( addr ) ( ((addr) >> 8) & 0xff ) #define ADDR_LO( addr ) ( (addr) & 0xff ) /* board RAM size */ #define SLH_RAM_SIZE 0xa00 /* first possible board port */ #define SLH_FIRST_PORT 0x100 /* board address for pumping */ #define SLH_PUMP_ADDR 0x000 /* board address for parameters */ #define SLH_PARMS_ADDR 0x3f0 /* board address for type */ #define SLH_BRD_TYPE_ADDR 0x3f9 /* board address of DMX send channels */ #define SLH_SND_CHAN_ADDR 0x400 /* board address of DMX receive channels */ #define SLH_RCV_CHAN_ADDR 0x800 /* test byte for board probing */ #define SLH_TEST_BYTE 0xaa /* board type for 1512C */ #define SLH_TYPE_1512C 0x04 /* board type for 1512C */ #define SLH_TYPE_1512CC 0x05 /* board type for 1512A or 1512B/LC */ #define SLH_TYPE_1512ABLC 0x80 /* board type for 1512B */ #define SLH_TYPE_1512B 0x01 /* board port number */ static unsigned long slh_board_port; /* board port number */ static unsigned char slh_board_parms[9]; int slh_board_mod_init() { /* initialize the "board" software module * (called when the slh driver is loaded). */ slh_board_port = 0; slh_board_parms[0] = 60; /* start sync duration */ slh_board_parms[1] = 0; /* start byte */ slh_board_parms[2] = 0; /* end idle time */ slh_board_parms[3] = ADDR_LO(512); /* number of chans (lo byte) */ slh_board_parms[4] = ADDR_HI(512); /* number of chans (hi byte) */ slh_board_parms[5] = 0; /* send repeat */ slh_board_parms[6] = 0; /* inter-digit time */ slh_board_parms[7] = 0; /* not used */ slh_board_parms[8] = 0; /* card mode (read/write) */ return ( 0 ); } void slh_board_mod_cleanup() { /* cleanup the "board" software module * (called when the slh driver is unloaded). */ /* stop the board (if running) */ slh_board_stop(); /* release the ISA ports */ release_region( slh_board_port, 4 ); slh_board_port = 0; } int slh_board_find() { /* find the Soundlight boards (if any) in the system */ register int i; unsigned char data; slh_board_port = 0; for ( i = 0; i < 4; i++ ) { unsigned port = SLH_FIRST_PORT + (0x20 * i); /* check if ports are registered to other apps */ if ( check_region(port, 4) < 0 ) { continue; } /* write the test byte to the port */ outb( (unsigned char)0, port ); outb( (unsigned char)0, port + 1 ); outb( (unsigned char)SLH_TEST_BYTE, port + 2 ); /* read the test byte back from the port */ outb( (unsigned char)0, port ); outb( (unsigned char)0, port + 1 ); data = inb( port + 2 ); /* check if the test byte was retrieved */ if ( data == SLH_TEST_BYTE ) { slh_board_port = port; /* register the ports */ request_region( slh_board_port, 4, "slh" ); return ( port ); } } return ( -1 ); } int slh_board_pump( unsigned char *data, unsigned long length ) { /* pump the firmware and parameters to the SoundLight board */ register unsigned long i; register unsigned long addr; register unsigned char test; if ( slh_board_port == 0 ) { return ( -1 ); } /* stop repetitive channel timer (if running) */ slh_channel_timer_stop(); /* load the board firmware */ for ( addr = SLH_PUMP_ADDR, i = 0; i < length; i++, addr++, data++ ) { /* write a firmware byte to the board */ outb( ADDR_LO(addr), slh_board_port ); outb( ADDR_HI(addr), slh_board_port + 1 ); outb( *data, slh_board_port + 2 ); /* read the firmware byte back from the board */ outb( ADDR_LO(addr), slh_board_port ); outb( ADDR_HI(addr), slh_board_port + 1 ); test = inb( slh_board_port + 2 ); /* verify that the firmware byte was written successfully */ if ( *data != test ) { "Board pump check failed! data=0x%x, actual=0x%x\n", (unsigned int)*data, (unsigned int)test ); return ( -1 ); } } /* zero the remaining board memory */ for ( ; i < SLH_RAM_SIZE; i++, addr++ ) { outb( ADDR_LO(addr), slh_board_port ); outb( ADDR_HI(addr), slh_board_port + 1 ); outb( (unsigned char)0, slh_board_port + 2 ); } /* load the board parameters */ slh_board_pump_parms(); /* start processor on board */ slh_board_start(); /* Wait 100us for the board to initialize. Measurements * indicate that it takes the 1512B about 56us to init. */ udelay( 100 ); /* check the board type */ outb( ADDR_LO(SLH_BRD_TYPE_ADDR), slh_board_port ); outb( ADDR_HI(SLH_BRD_TYPE_ADDR), slh_board_port + 1 ); test = inb( slh_board_port + 2 ); if ( test != SLH_TYPE_1512B ) { "Board type check failed! actual=0x%x\n", (unsigned int)test ); return ( -1 ); } /* start repetitive channel timer */ slh_channel_timer_start(); return ( 0 ); } int slh_board_pump_parms() { /* pump parameters to SoundLight board */ register unsigned long i; register unsigned long addr; if ( slh_board_port == 0 ) { return ( -1 ); } addr = SLH_PARMS_ADDR; for ( i = 0; i < sizeof(slh_board_parms); i++, addr++ ) { outb( ADDR_LO(addr), slh_board_port ); outb( ADDR_HI(addr), slh_board_port + 1 ); outb( slh_board_parms[i], slh_board_port + 2 ); } return ( 0 ); } #if 0 int slh_board_init_chans() { register unsigned long i; register unsigned long addr; if ( slh_board_port == 0 ) { return ( -1 ); } addr = SLH_SND_CHAN_ADDR; for ( i = 0; i < NUM_DMX_CHANS; i++, addr++ ) { outb( ADDR_LO(addr), slh_board_port ); outb( ADDR_HI(addr), slh_board_port + 1 ); outb( 0, slh_board_port + 2 ); } return ( 0 ); } #endif int slh_board_start() { /* start processor on Soundlight board */ if ( slh_board_port == 0 ) { return ( -1 ); } (void) inb( slh_board_port + 3 ); return ( 0 ); } int slh_board_stop() { /* stop processor on Soundlight board */ if ( slh_board_port == 0 ) { return ( -1 ); } outb( (unsigned char)0, slh_board_port ); return ( 0 ); } void slh_board_chan_set( unsigned long chan, unsigned long value ) { /* set a DMX-512 channel to a specified value */ unsigned long addr; if ( slh_board_port == 0 ) { return; } /* channel must be 0 to 511 */ if ( chan >= 512 ) { return; } /* calculate the board address of the DMX-512 channel */ addr = SLH_SND_CHAN_ADDR + chan; /* set the channel value */ outb( ADDR_LO(addr), slh_board_port ); outb( ADDR_HI(addr), slh_board_port + 1 ); outb( value, slh_board_port + 2 ); return; }


Back to Source File Index


C++ to HTML Conversion by ctoohtml