From 0f4a3977712f8456aa32641151efda31fdb84052 Mon Sep 17 00:00:00 2001 From: Steve Passe <fsmp@FreeBSD.org> Date: Wed, 19 Mar 1997 19:10:45 +0000 Subject: [PATCH] additions for table-driven frequency calculation. addition of colorbar ioctl. removed unneeded disable_intr()/enable_intr() wrappers in i2c code. minor cleanup. --- sys/dev/bktr/bktr_core.c | 398 ++++++++++++++++++++------------------- sys/pci/brooktree848.c | 398 ++++++++++++++++++++------------------- 2 files changed, 404 insertions(+), 392 deletions(-) diff --git a/sys/dev/bktr/bktr_core.c b/sys/dev/bktr/bktr_core.c index 3ad9425ca09e..1c4f7a37b148 100644 --- a/sys/dev/bktr/bktr_core.c +++ b/sys/dev/bktr/bktr_core.c @@ -188,6 +188,17 @@ options DEFAULT_TUNERTYPE=2 # TUNERTYPE_CABLEIRC */ #define MULTIPLE_OPENS +/* XXX Fixme: remove me??? */ +#define ORIGINAL_DELAYS_NOT + +/* XXX Fixme: anomolies still exist in the i2c code */ +#define EXTRA_START +#define FUNNY_HI +#define REALLY_ACK + +/* XXX attempt to hold sync on marginal signals, experimental */ +#define LOW_SYNC_NOT + #include "pci.h" #if NPCI > 0 @@ -1084,7 +1095,7 @@ get_bktr_mem( int unit, unsigned size ) /* - * Initialize the 7116, 7196 and the RGB module. + * what should we do here? */ static void bktr_init ( bktr_reg_t *bktr ) @@ -1115,7 +1126,6 @@ bktr_attach( pcici_t tag, int unit ) return ; } - bktr->tag = tag; pci_map_mem(tag, PCI_MAP_REG_START, (vm_offset_t *) &bktr->base, &bktr->phys_base); @@ -1129,7 +1139,7 @@ bktr_attach( pcici_t tag, int unit ) printf("bktr%d: attach: irq changed from %d to %d\n", unit, (old_irq & 0xff), (new_irq & 0xff)); #endif - /* setup the interrupt handling routine */ + /* setup the interrupt handling routine */ pci_map_int(tag, bktr_intr, (void*) bktr, &net_imask); /* @@ -1191,17 +1201,24 @@ end of setup up dma risc program METEOR_RGB16; #endif /* amancio */ - bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE | METEOR_DEV0 | METEOR_RGB16; + bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE | + METEOR_DEV0 | METEOR_RGB16; bktr->dma_prog_loaded = 0; bktr->cols = 640; bktr->rows = 480; bktr->depth = 2; /* two bytes per pixel */ - bktr->frames = 1; /* one frame */ + bktr->frames = 1; /* one frame */ bt848 = bktr->base; btl_reg = (u_long *) &bt848[BKTR_INT_MASK]; *btl_reg = 0; bt848[BKTR_GPIO_DMA_CTL] = 0; } + + /* defaults for the tuner section of the card */ + bktr->tuner.frequency = 0; + bktr->tuner.channel = 0; + bktr->tuner.tunertype = DEFAULT_TUNERTYPE; + #ifdef DEVFS bktr->devfs_token = devfs_add_devswf(&bktr_cdevsw, unit, DV_CHR, 0, 0, 0644, "brooktree"); @@ -1219,6 +1236,9 @@ end of setup up dma risc program */ +/* + * + */ int bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) { @@ -1230,7 +1250,7 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) volatile u_long *btl_reg; unit = UNIT(minor(dev)); - if (unit >= NBKTR) /* unit out of range */ + if (unit >= NBKTR) /* unit out of range */ return(ENXIO); bktr = &(brooktree[unit]); @@ -1251,12 +1271,17 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) bt848 = bktr->base; /* dump_bt848(bt848); */ - *bt848 = 0x3; + *bt848 = 0x3; /* bt848[ 0 ] */ *bt848 = 0xc0; +#if defined( LOW_SYNC ) + bt848[BKTR_ADC] = 0xa1; +#else bt848[BKTR_ADC] = 0x81; +#endif /* LOW_SYNC */ bt848[BKTR_IFORM] = 0x69; + bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0; bt848[BKTR_COLOR_CTL] = 0x20; @@ -1272,7 +1297,6 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) bt848[BKTR_VBI_PACK_DEL] = 0; bzero((u_char *) bktr->bigbuf, 640*480*4); - bktr->flags |= METEOR_OPEN; bktr->fifo_errors = 0; bktr->dma_errors = 0; bktr->frames_captured = 0; @@ -1285,16 +1309,16 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) bktr->video.banksize = 0; bktr->video.ramsize = 0; - /* defaults for the tuner section of the card */ - bktr->tuner.frequency = 0; - bktr->tuner.tunertype = DEFAULT_TUNERTYPE; - btl_reg = (u_long *) &bt848[BKTR_INT_MASK]; *btl_reg = 1 << 23; return(0); } + +/* + * + */ int bktr_close( dev_t dev, int flags, int fmt, struct proc *p ) { @@ -1307,7 +1331,7 @@ bktr_close( dev_t dev, int flags, int fmt, struct proc *p ) int temp; #endif unit = UNIT(minor(dev)); - if (unit >= NBKTR) /* unit out of range */ + if (unit >= NBKTR) /* unit out of range */ return(ENXIO); bktr = &(brooktree[unit]); @@ -1428,7 +1452,8 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr ) case TVTUNER_SETCHNL: temp = tv_channel( bktr, (int)*(unsigned long *)arg ); - if ( temp < 0 ) return EIO; + if ( temp < 0 ) + return EINVAL; *(unsigned long *)arg = temp; break; @@ -1437,7 +1462,10 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr ) break; case TVTUNER_SETTYPE: - bktr->tuner.tunertype = *(unsigned long *)arg; + temp = *(unsigned long *)arg; + if ( (temp < TUNERTYPE_MIN) || (temp > TUNERTYPE_MAX) ) + return EINVAL; + bktr->tuner.tunertype = temp; break; case TVTUNER_GETTYPE: @@ -1451,7 +1479,8 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr ) case TVTUNER_SETFREQ: temp = tv_freq( bktr, (int)*(unsigned long *)arg ); - if ( temp < 0 ) return EIO; + if ( temp < 0 ) + return EINVAL; *(unsigned long *)arg = temp; break; @@ -1747,6 +1776,14 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr ) *(int*)arg = tmp_int; break; + case BT848_SCBARS: /* set colorbar output */ + bt848[BKTR_COLOR_CTL] |= 0x40; + break; + + case BT848_CCBARS: /* clear colorbar output */ + bt848[BKTR_COLOR_CTL] &= ~0x40; + break; + case METEORSSIGNAL: bktr->signal = *(int *) arg; bktr->proc = pr; @@ -2020,16 +2057,11 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr ) *btl_reg = 1 << 23 | 2 | 1; } } - break; - default: -#if 0 -/* XXX */ - error = ENOTTY; - break; -#else + /* end of METEORSETGEO */ + + default: return ENODEV; -#endif /* 0 */ } return 0; @@ -2066,13 +2098,15 @@ bktr_mmap( dev_t dev, int offset, int nprot ) * tuner specific routines: */ -/** XXX FIXME: this should be a kernel option */ -#define IF_FREQUENCY 4575 /* M/N IF frequency */ - /* guaranteed address for any TSA5522 */ #define TSA5522_WADDR 0xc2 #define TSA5522_RADDR 0xc3 +/* EEProm */ +#define X24C01_WADDR 0xae /* STB */ +#define X24C01_RADDR 0xaf + + /* * bit 7: CONTROL BYTE = 1 * bit 6: CP = 0 moderate speed tuning, better FM @@ -2107,15 +2141,6 @@ bktr_mmap( dev_t dev, int offset, int nprot ) #endif /* XXXXXX_TUNER */ -/* scaling factor for frequencies expressed as ints */ -#define TEST_A_NOT - -#if defined( TEST_A ) -#define FREQFACTOR 16 -#else -#define FREQFACTOR 100 -#endif - /******************************* i2c primitives ******************************/ @@ -2179,20 +2204,20 @@ static int i2cWrite( i2c_regptr_t, u_char ); /* * start an I2C bus transaction */ -static void +static int i2cStart( i2c_regptr_t bti2c, int address ) { - -#if 1 +#if defined( EXTRA_START ) /* ensure the proper starting state */ DataHi_ClockLo( bti2c, LDELAY ); /* release data */ DataHi_ClockHi( bti2c, LDELAY ); /* release clock */ -#endif +#endif /* EXTRA_START */ + DataLo_ClockHi( bti2c, LDELAY ); /* lower data */ DataLo_ClockLo( bti2c, LDELAY ); /* lower clock */ /* send the address of the device */ - i2cWrite( bti2c, address ); + return i2cWrite( bti2c, address ); } /* @@ -2201,6 +2226,7 @@ i2cStart( i2c_regptr_t bti2c, int address ) static void i2cStop( i2c_regptr_t bti2c ) { + DELAY( LDELAY ); DataLo_ClockLo( bti2c, LDELAY ); /* lower clock & data */ DataLo_ClockHi( bti2c, LDELAY ); /* release clock */ DataHi_ClockHi( bti2c, LDELAY ); /* release data */ @@ -2278,9 +2304,13 @@ i2cRead( i2c_regptr_t bti2c, int ack ) DataHi_ClockLo( bti2c, SDELAY ); /* release clock */ } +#if defined( FUNNY_HI ) + i2cHi( bti2c ); +#endif /* FUNNY_HI */ +#if defined( REALLY_ACK ) if ( ack ) i2cGrantAck( bti2c ); /* Grant ACK */ - +#endif /* REALLY_ACK */ return byte; } @@ -2304,11 +2334,134 @@ i2cWrite( i2c_regptr_t bti2c, u_char byte ) #undef SDELAY #undef LDELAY + /*************************** end of i2c primitives ***************************/ #define I2C_REGADDR() (i2c_regptr_t)&bktr->base[ BKTR_I2C_CONTROL ] + +/* scaling factor for frequencies expressed as ints */ +#define FREQFACTOR 16 + +/* + * Format: + * entry 0: MAX legal channel + * entry 1: IF frequency + * expressed as fi{mHz} * 16, + * eg 45.75mHz == 45.75 * 16 = 732 + * entry 2: [place holder/future] + * entry 3: base of channel record 0 + * entry 3 + (x*3): base of channel record 'x' + * entry LAST: NULL channel entry marking end of records + * + * Record: + * int 0: base channel + * int 1: frequency of base channel, + * expressed as fb{mHz} * 16, + * int 2: offset frequency between channels, + * expressed as fo{mHz} * 16, + */ + +/* + * North American Broadcast Channels: + * + * 2: 55.25 mHz - 4: 67.25 mHz + * 5: 77.25 mHz - 6: 83.25 mHz + * 7: 175.25 mHz - 13: 211.25 mHz + * 14: 471.25 mHz - 83: 885.25 mHz + * + * IF freq: 45.75 mHz + */ +int nabcst[] = { + 83, (int)( 45.75 * FREQFACTOR), 0, + 14, (int)(471.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 7, (int)(175.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 5, (int)( 77.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 2, (int)( 55.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 0 +}; + +/* + * North American Cable Channels, IRC: + * + * 2: 55.25 mHz - 4: 67.25 mHz + * 5: 77.25 mHz - 6: 83.25 mHz + * 7: 175.25 mHz - 13: 211.25 mHz + * 14: 121.25 mHz - 22: 169.25 mHz + * 23: 217.25 mHz - 94: 643.25 mHz + * 95: 91.25 mHz - 99: 115.25 mHz + * + * IF freq: 45.75 mHz + */ +int irccable[] = { + 99, (int)( 45.75 * FREQFACTOR), 0, + 95, (int)( 91.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 23, (int)(217.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 14, (int)(121.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 7, (int)(175.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 5, (int)( 77.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 2, (int)( 55.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 0 +}; + +/* + * North American Cable Channels, HRC: + * + */ +int hrccable[] = { + 0, 0, 0, + 0 +}; + +/* + * Western European channels: + * + */ +int weurope[] = { + 0, 0, 0, + 0 +}; + +int* freqTable[] = { + NULL, + nabcst, + irccable, + hrccable, + weurope +}; + + +#define TBL_CHNL freqTable[ bktr->tuner.tunertype ][ x ] +#define TBL_BASE_FREQ freqTable[ bktr->tuner.tunertype ][ x + 1 ] +#define TBL_OFFSET freqTable[ bktr->tuner.tunertype ][ x + 2 ] +static int +frequency_lookup( bktr_reg_t* bktr, int channel ) +{ + int x; + + /* check for "> MAX channel" */ + x = 0; + if ( channel > TBL_CHNL ) + return -1; + + /* search the table for data */ + for ( x = 3; TBL_CHNL; x += 3 ) { + if ( channel >= TBL_CHNL ) { + return + (TBL_BASE_FREQ + ((channel-TBL_CHNL) * TBL_OFFSET)); + } + } + + /* not found, must be below the MIN channel */ + return -1; +} +#undef TBL_OFFSET +#undef TBL_BASE_FREQ +#undef TBL_CHNL + + +#define TBL_IF freqTable[ bktr->tuner.tunertype ][ 1 ] /* * set the frequency of the tuner */ @@ -2332,23 +2485,15 @@ tv_freq( bktr_reg_t* bktr, int frequency ) * N = 16 * { fRF(pc) + fIF(pc) } * where: * pc is picture carrier, fRF & fIF are in mHz - */ -#if defined( TEST_A ) - /* + * * frequency is mHz * 16, eg. 55.25 mHz * 16 == 884 */ - N = (frequency + 732 /* 45.75 * 16 */); -#else - /* - * frequency is mHz to 2 decimal places, ie. 5525 == 55.25 mHz, - */ - N = 16 * ((frequency + IF_FREQUENCY) / FREQFACTOR); -#endif + N = frequency + TBL_IF; + /* get the i2c register address */ bti2c = I2C_REGADDR(); /* send the data to the TSA5522 */ - disable_intr(); i2cStart( bti2c, TSA5522_WADDR ); /* the data sheet wants the order set according to direction */ @@ -2366,132 +2511,12 @@ tv_freq( bktr_reg_t* bktr, int frequency ) } i2cStop( bti2c ); - enable_intr(); bktr->tuner.frequency = frequency; return 0; } - - -/* - * North American Broadcast Channels: - * - * IF freq: 45.75 mHz - * - * Chnl Freq - * 2 55.25 mHz - * 3 61.25 mHz - * 4 67.25 mHz - * - * 5 77.25 mHz - * 6 83.25 mHz - * - * 7 175.25 mHz - * 13 211.25 mHz - * - * 14 471.25 mHz - * 83 885.25 mHz - */ -static int -frequency_nabcst( int channel ) -{ - /* legal channels are 2 thru 83 */ - if ( channel > 83 ) - return -1; - - /* channels 14 thru 83 */ - if ( channel >= 14 ) -#if defined( TEST_A ) - return 7540 + ((channel-14) * 96 ); -#else - return 47125 + ((channel-14) * 600 ); -#endif - /* channels 7 thru 13 */ - if ( channel >= 7 ) -#if defined( TEST_A ) - return 2804 + ((channel-7) * 96 ); -#else - return 17525 + ((channel-7) * 600 ); -#endif - /* channels 5 thru 6 */ - if ( channel >= 5 ) -#if defined( TEST_A ) - return 1236 + ((channel-5) * 96 ); -#else - return 7725 + ((channel-5) * 600 ); -#endif - /* channels 2 thru 4 */ - if ( channel >= 2 ) -#if defined( TEST_A ) - return 884 + ((channel-2) * 96 ); -#else - return 5525 + ((channel-2) * 600 ); -#endif - /* legal channels are 2 thru 83 */ - return -1; -} - - -/* - * North American Cable Channels, IRC(?): - * - * IF freq: 45.75 mHz - * - * Chnl Freq - * 2 55.25 mHz - * 3 61.25 mHz - * 4 67.25 mHz - * - * 5 77.25 mHz - * 6 83.25 mHz - * - * 7 175.25 mHz - * 13 211.25 mHz - * - * 14 121.25 mHz - * 22 169.25 mHz - * - * 23 217.25 mHz - * 94 643.25 mHz - * - * 95 91.25 mHz - * 99 115.25 mHz - */ -static int -frequency_irccable( int channel ) -{ - /* legal channels are 2 thru 99 */ - if ( channel > 99 ) - return -1; - - /* channels 95 thru 99 */ - if ( channel >= 95 ) - return 9125 + ((channel-95) * 600 ); - - /* channels 23 thru 94 */ - if ( channel >= 23 ) - return 21725 + ((channel-23) * 600 ); - - /* channels 14 thru 22 */ - if ( channel >= 14 ) - return 12125 + ((channel-14) * 600 ); - - /* channels 7 thru 13 */ - if ( channel >= 7 ) - return 17525 + ((channel-7) * 600 ); - - /* channels 5 thru 6 */ - if ( channel >= 5 ) - return 7725 + ((channel-5) * 600 ); - - /* channels 2 thru 4 */ - if ( channel >= 2 ) - return 5525 + ((channel-2) * 600 ); - - /* legal channels are 2 thru 99 */ - return -1; -} +#undef TBL_IF /* @@ -2500,27 +2525,10 @@ frequency_irccable( int channel ) static int tv_channel( bktr_reg_t* bktr, int channel ) { - int frequency, status; + int frequency; /* calculate the frequency according to tuner type */ - switch ( bktr->tuner.tunertype ) { - case TUNERTYPE_NABCST: - frequency = frequency_nabcst( channel ); - break; - - case TUNERTYPE_CABLEIRC: - frequency = frequency_irccable( channel ); - break; - - /* FIXME: */ - case TUNERTYPE_CABLEHRC: - case TUNERTYPE_WEUROPE: - default: - return -1; - } - - /* check the result of channel to frequency conversion */ - if ( frequency < 0 ) + if ( (frequency = frequency_lookup( bktr, channel )) < 0 ) return -1; /* set the new frequency */ @@ -2535,7 +2543,7 @@ tv_channel( bktr_reg_t* bktr, int channel ) /* - * set the channel of the tuner + * get the status of the tuner */ static int tuner_status( bktr_reg_t* bktr ) @@ -2547,13 +2555,11 @@ tuner_status( bktr_reg_t* bktr ) bti2c = I2C_REGADDR(); /* send the request to the TSA5522 */ - disable_intr(); i2cStart( bti2c, TSA5522_RADDR ); status = i2cRead( bti2c, 0 ); /* no ACK */ i2cStop( bti2c ); - enable_intr(); return status; } diff --git a/sys/pci/brooktree848.c b/sys/pci/brooktree848.c index 3ad9425ca09e..1c4f7a37b148 100644 --- a/sys/pci/brooktree848.c +++ b/sys/pci/brooktree848.c @@ -188,6 +188,17 @@ options DEFAULT_TUNERTYPE=2 # TUNERTYPE_CABLEIRC */ #define MULTIPLE_OPENS +/* XXX Fixme: remove me??? */ +#define ORIGINAL_DELAYS_NOT + +/* XXX Fixme: anomolies still exist in the i2c code */ +#define EXTRA_START +#define FUNNY_HI +#define REALLY_ACK + +/* XXX attempt to hold sync on marginal signals, experimental */ +#define LOW_SYNC_NOT + #include "pci.h" #if NPCI > 0 @@ -1084,7 +1095,7 @@ get_bktr_mem( int unit, unsigned size ) /* - * Initialize the 7116, 7196 and the RGB module. + * what should we do here? */ static void bktr_init ( bktr_reg_t *bktr ) @@ -1115,7 +1126,6 @@ bktr_attach( pcici_t tag, int unit ) return ; } - bktr->tag = tag; pci_map_mem(tag, PCI_MAP_REG_START, (vm_offset_t *) &bktr->base, &bktr->phys_base); @@ -1129,7 +1139,7 @@ bktr_attach( pcici_t tag, int unit ) printf("bktr%d: attach: irq changed from %d to %d\n", unit, (old_irq & 0xff), (new_irq & 0xff)); #endif - /* setup the interrupt handling routine */ + /* setup the interrupt handling routine */ pci_map_int(tag, bktr_intr, (void*) bktr, &net_imask); /* @@ -1191,17 +1201,24 @@ end of setup up dma risc program METEOR_RGB16; #endif /* amancio */ - bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE | METEOR_DEV0 | METEOR_RGB16; + bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE | + METEOR_DEV0 | METEOR_RGB16; bktr->dma_prog_loaded = 0; bktr->cols = 640; bktr->rows = 480; bktr->depth = 2; /* two bytes per pixel */ - bktr->frames = 1; /* one frame */ + bktr->frames = 1; /* one frame */ bt848 = bktr->base; btl_reg = (u_long *) &bt848[BKTR_INT_MASK]; *btl_reg = 0; bt848[BKTR_GPIO_DMA_CTL] = 0; } + + /* defaults for the tuner section of the card */ + bktr->tuner.frequency = 0; + bktr->tuner.channel = 0; + bktr->tuner.tunertype = DEFAULT_TUNERTYPE; + #ifdef DEVFS bktr->devfs_token = devfs_add_devswf(&bktr_cdevsw, unit, DV_CHR, 0, 0, 0644, "brooktree"); @@ -1219,6 +1236,9 @@ end of setup up dma risc program */ +/* + * + */ int bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) { @@ -1230,7 +1250,7 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) volatile u_long *btl_reg; unit = UNIT(minor(dev)); - if (unit >= NBKTR) /* unit out of range */ + if (unit >= NBKTR) /* unit out of range */ return(ENXIO); bktr = &(brooktree[unit]); @@ -1251,12 +1271,17 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) bt848 = bktr->base; /* dump_bt848(bt848); */ - *bt848 = 0x3; + *bt848 = 0x3; /* bt848[ 0 ] */ *bt848 = 0xc0; +#if defined( LOW_SYNC ) + bt848[BKTR_ADC] = 0xa1; +#else bt848[BKTR_ADC] = 0x81; +#endif /* LOW_SYNC */ bt848[BKTR_IFORM] = 0x69; + bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0; bt848[BKTR_COLOR_CTL] = 0x20; @@ -1272,7 +1297,6 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) bt848[BKTR_VBI_PACK_DEL] = 0; bzero((u_char *) bktr->bigbuf, 640*480*4); - bktr->flags |= METEOR_OPEN; bktr->fifo_errors = 0; bktr->dma_errors = 0; bktr->frames_captured = 0; @@ -1285,16 +1309,16 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) bktr->video.banksize = 0; bktr->video.ramsize = 0; - /* defaults for the tuner section of the card */ - bktr->tuner.frequency = 0; - bktr->tuner.tunertype = DEFAULT_TUNERTYPE; - btl_reg = (u_long *) &bt848[BKTR_INT_MASK]; *btl_reg = 1 << 23; return(0); } + +/* + * + */ int bktr_close( dev_t dev, int flags, int fmt, struct proc *p ) { @@ -1307,7 +1331,7 @@ bktr_close( dev_t dev, int flags, int fmt, struct proc *p ) int temp; #endif unit = UNIT(minor(dev)); - if (unit >= NBKTR) /* unit out of range */ + if (unit >= NBKTR) /* unit out of range */ return(ENXIO); bktr = &(brooktree[unit]); @@ -1428,7 +1452,8 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr ) case TVTUNER_SETCHNL: temp = tv_channel( bktr, (int)*(unsigned long *)arg ); - if ( temp < 0 ) return EIO; + if ( temp < 0 ) + return EINVAL; *(unsigned long *)arg = temp; break; @@ -1437,7 +1462,10 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr ) break; case TVTUNER_SETTYPE: - bktr->tuner.tunertype = *(unsigned long *)arg; + temp = *(unsigned long *)arg; + if ( (temp < TUNERTYPE_MIN) || (temp > TUNERTYPE_MAX) ) + return EINVAL; + bktr->tuner.tunertype = temp; break; case TVTUNER_GETTYPE: @@ -1451,7 +1479,8 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr ) case TVTUNER_SETFREQ: temp = tv_freq( bktr, (int)*(unsigned long *)arg ); - if ( temp < 0 ) return EIO; + if ( temp < 0 ) + return EINVAL; *(unsigned long *)arg = temp; break; @@ -1747,6 +1776,14 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr ) *(int*)arg = tmp_int; break; + case BT848_SCBARS: /* set colorbar output */ + bt848[BKTR_COLOR_CTL] |= 0x40; + break; + + case BT848_CCBARS: /* clear colorbar output */ + bt848[BKTR_COLOR_CTL] &= ~0x40; + break; + case METEORSSIGNAL: bktr->signal = *(int *) arg; bktr->proc = pr; @@ -2020,16 +2057,11 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr ) *btl_reg = 1 << 23 | 2 | 1; } } - break; - default: -#if 0 -/* XXX */ - error = ENOTTY; - break; -#else + /* end of METEORSETGEO */ + + default: return ENODEV; -#endif /* 0 */ } return 0; @@ -2066,13 +2098,15 @@ bktr_mmap( dev_t dev, int offset, int nprot ) * tuner specific routines: */ -/** XXX FIXME: this should be a kernel option */ -#define IF_FREQUENCY 4575 /* M/N IF frequency */ - /* guaranteed address for any TSA5522 */ #define TSA5522_WADDR 0xc2 #define TSA5522_RADDR 0xc3 +/* EEProm */ +#define X24C01_WADDR 0xae /* STB */ +#define X24C01_RADDR 0xaf + + /* * bit 7: CONTROL BYTE = 1 * bit 6: CP = 0 moderate speed tuning, better FM @@ -2107,15 +2141,6 @@ bktr_mmap( dev_t dev, int offset, int nprot ) #endif /* XXXXXX_TUNER */ -/* scaling factor for frequencies expressed as ints */ -#define TEST_A_NOT - -#if defined( TEST_A ) -#define FREQFACTOR 16 -#else -#define FREQFACTOR 100 -#endif - /******************************* i2c primitives ******************************/ @@ -2179,20 +2204,20 @@ static int i2cWrite( i2c_regptr_t, u_char ); /* * start an I2C bus transaction */ -static void +static int i2cStart( i2c_regptr_t bti2c, int address ) { - -#if 1 +#if defined( EXTRA_START ) /* ensure the proper starting state */ DataHi_ClockLo( bti2c, LDELAY ); /* release data */ DataHi_ClockHi( bti2c, LDELAY ); /* release clock */ -#endif +#endif /* EXTRA_START */ + DataLo_ClockHi( bti2c, LDELAY ); /* lower data */ DataLo_ClockLo( bti2c, LDELAY ); /* lower clock */ /* send the address of the device */ - i2cWrite( bti2c, address ); + return i2cWrite( bti2c, address ); } /* @@ -2201,6 +2226,7 @@ i2cStart( i2c_regptr_t bti2c, int address ) static void i2cStop( i2c_regptr_t bti2c ) { + DELAY( LDELAY ); DataLo_ClockLo( bti2c, LDELAY ); /* lower clock & data */ DataLo_ClockHi( bti2c, LDELAY ); /* release clock */ DataHi_ClockHi( bti2c, LDELAY ); /* release data */ @@ -2278,9 +2304,13 @@ i2cRead( i2c_regptr_t bti2c, int ack ) DataHi_ClockLo( bti2c, SDELAY ); /* release clock */ } +#if defined( FUNNY_HI ) + i2cHi( bti2c ); +#endif /* FUNNY_HI */ +#if defined( REALLY_ACK ) if ( ack ) i2cGrantAck( bti2c ); /* Grant ACK */ - +#endif /* REALLY_ACK */ return byte; } @@ -2304,11 +2334,134 @@ i2cWrite( i2c_regptr_t bti2c, u_char byte ) #undef SDELAY #undef LDELAY + /*************************** end of i2c primitives ***************************/ #define I2C_REGADDR() (i2c_regptr_t)&bktr->base[ BKTR_I2C_CONTROL ] + +/* scaling factor for frequencies expressed as ints */ +#define FREQFACTOR 16 + +/* + * Format: + * entry 0: MAX legal channel + * entry 1: IF frequency + * expressed as fi{mHz} * 16, + * eg 45.75mHz == 45.75 * 16 = 732 + * entry 2: [place holder/future] + * entry 3: base of channel record 0 + * entry 3 + (x*3): base of channel record 'x' + * entry LAST: NULL channel entry marking end of records + * + * Record: + * int 0: base channel + * int 1: frequency of base channel, + * expressed as fb{mHz} * 16, + * int 2: offset frequency between channels, + * expressed as fo{mHz} * 16, + */ + +/* + * North American Broadcast Channels: + * + * 2: 55.25 mHz - 4: 67.25 mHz + * 5: 77.25 mHz - 6: 83.25 mHz + * 7: 175.25 mHz - 13: 211.25 mHz + * 14: 471.25 mHz - 83: 885.25 mHz + * + * IF freq: 45.75 mHz + */ +int nabcst[] = { + 83, (int)( 45.75 * FREQFACTOR), 0, + 14, (int)(471.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 7, (int)(175.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 5, (int)( 77.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 2, (int)( 55.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 0 +}; + +/* + * North American Cable Channels, IRC: + * + * 2: 55.25 mHz - 4: 67.25 mHz + * 5: 77.25 mHz - 6: 83.25 mHz + * 7: 175.25 mHz - 13: 211.25 mHz + * 14: 121.25 mHz - 22: 169.25 mHz + * 23: 217.25 mHz - 94: 643.25 mHz + * 95: 91.25 mHz - 99: 115.25 mHz + * + * IF freq: 45.75 mHz + */ +int irccable[] = { + 99, (int)( 45.75 * FREQFACTOR), 0, + 95, (int)( 91.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 23, (int)(217.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 14, (int)(121.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 7, (int)(175.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 5, (int)( 77.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 2, (int)( 55.25 * FREQFACTOR), (int)(6.00 * FREQFACTOR), + 0 +}; + +/* + * North American Cable Channels, HRC: + * + */ +int hrccable[] = { + 0, 0, 0, + 0 +}; + +/* + * Western European channels: + * + */ +int weurope[] = { + 0, 0, 0, + 0 +}; + +int* freqTable[] = { + NULL, + nabcst, + irccable, + hrccable, + weurope +}; + + +#define TBL_CHNL freqTable[ bktr->tuner.tunertype ][ x ] +#define TBL_BASE_FREQ freqTable[ bktr->tuner.tunertype ][ x + 1 ] +#define TBL_OFFSET freqTable[ bktr->tuner.tunertype ][ x + 2 ] +static int +frequency_lookup( bktr_reg_t* bktr, int channel ) +{ + int x; + + /* check for "> MAX channel" */ + x = 0; + if ( channel > TBL_CHNL ) + return -1; + + /* search the table for data */ + for ( x = 3; TBL_CHNL; x += 3 ) { + if ( channel >= TBL_CHNL ) { + return + (TBL_BASE_FREQ + ((channel-TBL_CHNL) * TBL_OFFSET)); + } + } + + /* not found, must be below the MIN channel */ + return -1; +} +#undef TBL_OFFSET +#undef TBL_BASE_FREQ +#undef TBL_CHNL + + +#define TBL_IF freqTable[ bktr->tuner.tunertype ][ 1 ] /* * set the frequency of the tuner */ @@ -2332,23 +2485,15 @@ tv_freq( bktr_reg_t* bktr, int frequency ) * N = 16 * { fRF(pc) + fIF(pc) } * where: * pc is picture carrier, fRF & fIF are in mHz - */ -#if defined( TEST_A ) - /* + * * frequency is mHz * 16, eg. 55.25 mHz * 16 == 884 */ - N = (frequency + 732 /* 45.75 * 16 */); -#else - /* - * frequency is mHz to 2 decimal places, ie. 5525 == 55.25 mHz, - */ - N = 16 * ((frequency + IF_FREQUENCY) / FREQFACTOR); -#endif + N = frequency + TBL_IF; + /* get the i2c register address */ bti2c = I2C_REGADDR(); /* send the data to the TSA5522 */ - disable_intr(); i2cStart( bti2c, TSA5522_WADDR ); /* the data sheet wants the order set according to direction */ @@ -2366,132 +2511,12 @@ tv_freq( bktr_reg_t* bktr, int frequency ) } i2cStop( bti2c ); - enable_intr(); bktr->tuner.frequency = frequency; return 0; } - - -/* - * North American Broadcast Channels: - * - * IF freq: 45.75 mHz - * - * Chnl Freq - * 2 55.25 mHz - * 3 61.25 mHz - * 4 67.25 mHz - * - * 5 77.25 mHz - * 6 83.25 mHz - * - * 7 175.25 mHz - * 13 211.25 mHz - * - * 14 471.25 mHz - * 83 885.25 mHz - */ -static int -frequency_nabcst( int channel ) -{ - /* legal channels are 2 thru 83 */ - if ( channel > 83 ) - return -1; - - /* channels 14 thru 83 */ - if ( channel >= 14 ) -#if defined( TEST_A ) - return 7540 + ((channel-14) * 96 ); -#else - return 47125 + ((channel-14) * 600 ); -#endif - /* channels 7 thru 13 */ - if ( channel >= 7 ) -#if defined( TEST_A ) - return 2804 + ((channel-7) * 96 ); -#else - return 17525 + ((channel-7) * 600 ); -#endif - /* channels 5 thru 6 */ - if ( channel >= 5 ) -#if defined( TEST_A ) - return 1236 + ((channel-5) * 96 ); -#else - return 7725 + ((channel-5) * 600 ); -#endif - /* channels 2 thru 4 */ - if ( channel >= 2 ) -#if defined( TEST_A ) - return 884 + ((channel-2) * 96 ); -#else - return 5525 + ((channel-2) * 600 ); -#endif - /* legal channels are 2 thru 83 */ - return -1; -} - - -/* - * North American Cable Channels, IRC(?): - * - * IF freq: 45.75 mHz - * - * Chnl Freq - * 2 55.25 mHz - * 3 61.25 mHz - * 4 67.25 mHz - * - * 5 77.25 mHz - * 6 83.25 mHz - * - * 7 175.25 mHz - * 13 211.25 mHz - * - * 14 121.25 mHz - * 22 169.25 mHz - * - * 23 217.25 mHz - * 94 643.25 mHz - * - * 95 91.25 mHz - * 99 115.25 mHz - */ -static int -frequency_irccable( int channel ) -{ - /* legal channels are 2 thru 99 */ - if ( channel > 99 ) - return -1; - - /* channels 95 thru 99 */ - if ( channel >= 95 ) - return 9125 + ((channel-95) * 600 ); - - /* channels 23 thru 94 */ - if ( channel >= 23 ) - return 21725 + ((channel-23) * 600 ); - - /* channels 14 thru 22 */ - if ( channel >= 14 ) - return 12125 + ((channel-14) * 600 ); - - /* channels 7 thru 13 */ - if ( channel >= 7 ) - return 17525 + ((channel-7) * 600 ); - - /* channels 5 thru 6 */ - if ( channel >= 5 ) - return 7725 + ((channel-5) * 600 ); - - /* channels 2 thru 4 */ - if ( channel >= 2 ) - return 5525 + ((channel-2) * 600 ); - - /* legal channels are 2 thru 99 */ - return -1; -} +#undef TBL_IF /* @@ -2500,27 +2525,10 @@ frequency_irccable( int channel ) static int tv_channel( bktr_reg_t* bktr, int channel ) { - int frequency, status; + int frequency; /* calculate the frequency according to tuner type */ - switch ( bktr->tuner.tunertype ) { - case TUNERTYPE_NABCST: - frequency = frequency_nabcst( channel ); - break; - - case TUNERTYPE_CABLEIRC: - frequency = frequency_irccable( channel ); - break; - - /* FIXME: */ - case TUNERTYPE_CABLEHRC: - case TUNERTYPE_WEUROPE: - default: - return -1; - } - - /* check the result of channel to frequency conversion */ - if ( frequency < 0 ) + if ( (frequency = frequency_lookup( bktr, channel )) < 0 ) return -1; /* set the new frequency */ @@ -2535,7 +2543,7 @@ tv_channel( bktr_reg_t* bktr, int channel ) /* - * set the channel of the tuner + * get the status of the tuner */ static int tuner_status( bktr_reg_t* bktr ) @@ -2547,13 +2555,11 @@ tuner_status( bktr_reg_t* bktr ) bti2c = I2C_REGADDR(); /* send the request to the TSA5522 */ - disable_intr(); i2cStart( bti2c, TSA5522_RADDR ); status = i2cRead( bti2c, 0 ); /* no ACK */ i2cStop( bti2c ); - enable_intr(); return status; }