summaryrefslogtreecommitdiffstats
path: root/sys/dev/bktr
diff options
context:
space:
mode:
authorfsmp <fsmp@FreeBSD.org>1997-03-21 17:33:03 +0000
committerfsmp <fsmp@FreeBSD.org>1997-03-21 17:33:03 +0000
commit6990917d46c2e169f423de9bca182a376abd2b2a (patch)
tree75a6aaa80aaca06d4286b536bf1d57e60270c9e6 /sys/dev/bktr
parent9329489ce3a0d2b0490c39d2ab0978e93f51956b (diff)
downloadFreeBSD-src-6990917d46c2e169f423de9bca182a376abd2b2a.zip
FreeBSD-src-6990917d46c2e169f423de9bca182a376abd2b2a.tar.gz
Submitted by: Michael Petry <petry@netwolf.NetMasters.com>
Michael submitted code to activate the audio muxes. fsmp: extended those changes for different boards. auto-detection of board types. auto-detection of tuner types. auto-detection of stereo option.
Diffstat (limited to 'sys/dev/bktr')
-rw-r--r--sys/dev/bktr/bktr_core.c1947
-rw-r--r--sys/dev/bktr/bktr_reg.h137
2 files changed, 1256 insertions, 828 deletions
diff --git a/sys/dev/bktr/bktr_core.c b/sys/dev/bktr/bktr_core.c
index 1c4f7a3..1b10e50 100644
--- a/sys/dev/bktr/bktr_core.c
+++ b/sys/dev/bktr/bktr_core.c
@@ -113,6 +113,19 @@
new bt848 specific versions of hue/bright/
contrast/satu/satv.
Amancio's patch to fix "screen freeze" problem.
+
+1.6 3/19/97 fsmp@freefall.org
+ new table-driven frequency lookup.
+ removed disable_intr()/enable_intr() calls from i2c.
+ misc. cleanup.
+
+1.7 3/19/97 fsmp@freefall.org
+ added audio support submitted by:
+ Michael Petry <petry@netwolf.NetMasters.com>
+1.8 3/20/97 fsmp@freefall.org
+ extended audio support.
+ card auto-detection.
+ major cleanup, order of routines, declarations, etc.
*/
#include "bktr.h"
@@ -143,45 +156,37 @@
#include <vm/pmap.h>
#include <vm/vm_extern.h>
-/*
- * XXX: include code to support specific tuners.
- * once we add auto-probe code to detect tuner types this can go away.
- *
- * the STB card has a TEMIC tuner, others(?) have the PHILIPS tuner.
- * check the label on the metal can to be sure!
- *
- * in your kernel config file set one of:
-options TEMIC_TUNER # STB TV PCI
-options PHILIPS_TUNER # WinCast/TV
- *
- * alternately, in this file, you can select one of:
- *
-#define TEMIC_TUNER
-#define PHILIPS_TUNER
- */
-#if !defined( TEMIC_TUNER ) && !defined( PHILIPS_TUNER )
-#define PHILIPS_TUNER
-#endif
/*
- * XXX: the 'options' aspect of this is a REAL KLUDGE, fix it!
+ * This is for start-up convenience only, NOT mandatory.
* XXX: we need to support additional sets of frequencies.
*
* this selects the set of frequencies used by the tuner.
* in your kernel config file set one of:
-options DEFAULT_TUNERTYPE=1 # TUNERTYPE_NABCST
-options DEFAULT_TUNERTYPE=2 # TUNERTYPE_CABLEIRC
+options DEFAULT_CHNLSET=1 # CHNLSET_NABCST
+options DEFAULT_CHNLSET=2 # CHNLSET_CABLEIRC
*
* alternately, in this file, you can select one of:
*
-#define DEFAULT_TUNERTYPE TUNERTYPE_NABCST
-#define DEFAULT_TUNERTYPE TUNERTYPE_CABLEIRC
+#define DEFAULT_CHNLSET CHNLSET_NABCST
+#define DEFAULT_CHNLSET CHNLSET_CABLEIRC
*/
-#if !defined( DEFAULT_TUNERTYPE )
-#define DEFAULT_TUNERTYPE TUNERTYPE_NABCST
+#if !defined( DEFAULT_CHNLSET )
+#define DEFAULT_CHNLSET CHNLSET_NABCST
#endif
/*
+ * the recognized cards.
+ * used as indexes of several tables.
+ */
+#define CARD_UNKNOWN 0
+#define CARD_MIRO 1
+#define CARD_HAUPPAUGE 2
+#define CARD_STB 3
+#define CARD_INTEL 4
+
+
+/*
* XXX: hack to allow multiple programs to open the device,
* ie., a tv client and a remote control
* we need to make this a MINOR UNIT type thing someday...
@@ -199,6 +204,9 @@ options DEFAULT_TUNERTYPE=2 # TUNERTYPE_CABLEIRC
/* XXX attempt to hold sync on marginal signals, experimental */
#define LOW_SYNC_NOT
+/* srart of audio support */
+#define AUDIO_SUPPORT
+
#include "pci.h"
#if NPCI > 0
@@ -211,19 +219,13 @@ options DEFAULT_TUNERTYPE=2 # TUNERTYPE_CABLEIRC
#include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
#include <pci/brktree_reg.h>
-/*
- * tuner specific functions
- */
-static int tv_channel __P(( bktr_reg_t* bktr, int channel ));
-static int tv_freq __P(( bktr_reg_t* bktr, int frequency ));
-static int tuner_status __P(( bktr_reg_t* bktr ));
-
#define METPRI (PZERO+8)|PCATCH
-static void bktr_intr __P((void *arg));
-static bt_enable_cnt;
-static u_long btl_status_prev;
+static void bktr_intr __P((void *arg));
+static bt_enable_cnt;
+static u_long btl_status_prev;
+
/*
* Allocate enough memory for:
* 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
@@ -232,30 +234,19 @@ static u_long btl_status_prev;
* kernel configuration file.
*/
#ifndef BROOKTREE_ALLOC_PAGES
-#define BROOKTREE_ALLOC_PAGES 217*4
+#define BROOKTREE_ALLOC_PAGES 217*4
#endif
-#define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
+#define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
static bktr_reg_t brooktree[NBKTR];
#define BROOKTRE_NUM(mtr) ((bktr - &brooktree[0])/sizeof(bktr_reg_t))
#define BKTRPRI (PZERO+8)|PCATCH
-static char* bktr_probe (pcici_t tag, pcidi_t type);
-static void bktr_attach(pcici_t tag, int unit);
-int dump_bt848( volatile u_char *bt848 );
-
-void yuvpack_prog( bktr_reg_t * bktr, char i_flag, int cols,
- int rows, int interlace) ;
-
-void yuv422_prog( bktr_reg_t * bktr, char i_flag, int cols,
- int rows, int interlace);
-void rgb_prog( bktr_reg_t * bktr, char i_flag, int cols,
- int rows, int pixel_width, int interlace) ;
-void start_capture(bktr_reg_t *bktr, unsigned type);
-void build_dma_prog( bktr_reg_t * bktr, char i_flag);
+static char* bktr_probe( pcici_t tag, pcidi_t type );
+static void bktr_attach( pcici_t tag, int unit );
-static u_long bktr_count;
+static u_long bktr_count;
static struct pci_device bktr_device = {
"bktr",
@@ -284,7 +275,60 @@ static struct cdevsw bktr_cdevsw =
/*
- *
+ * misc. support routines.
+ */
+struct CARDTYPE {
+ char* name;
+ u_char tuner;
+ u_char dbx;
+ u_char audiomuxs[4]; /* tuner, external, internal/unused, mute */
+};
+static struct CARDTYPE card_types[];
+static int probe_card( bktr_reg_t *bktr, int verbose );
+static vm_offset_t get_bktr_mem( int unit, unsigned size );
+
+
+/*
+ * bt848 RISC programming routines.
+ */
+static int dump_bt848( volatile u_char *bt848 );
+
+static void yuvpack_prog( bktr_reg_t * bktr, char i_flag, int cols,
+ int rows, int interlace) ;
+
+static void yuv422_prog( bktr_reg_t * bktr, char i_flag, int cols,
+ int rows, int interlace);
+static void rgb_prog( bktr_reg_t * bktr, char i_flag, int cols,
+ int rows, int pixel_width, int interlace) ;
+static void build_dma_prog( bktr_reg_t * bktr, char i_flag);
+
+
+/*
+ * video & video capture specific routines.
+ */
+static void start_capture( bktr_reg_t *bktr, unsigned type );
+static void set_fps( bktr_reg_t *bktr, u_short fps );
+
+
+/*
+ * tuner specific functions.
+ */
+static int tv_channel( bktr_reg_t* bktr, int channel );
+static int tv_freq( bktr_reg_t* bktr, int frequency );
+static int tuner_status( bktr_reg_t* bktr );
+
+
+#if defined( AUDIO_SUPPORT )
+/*
+ * audio specific functions.
+ */
+static int set_audio( bktr_reg_t * bktr, int mode );
+static int set_BTSC( bktr_reg_t * bktr, int control );
+#endif /* AUDIO_SUPPORT */
+
+
+/*
+ * the boot time probe routine.
*/
static char*
bktr_probe( pcici_t tag, pcidi_t type )
@@ -299,7 +343,7 @@ bktr_probe( pcici_t tag, pcidi_t type )
/*
- * interrupt handling routine complete meteor_read() if using interrupts
+ * interrupt handling routine complete bktr_read() if using interrupts.
*/
static void
bktr_intr( void *arg )
@@ -453,648 +497,6 @@ bktr_intr( void *arg )
/*
- *
- */
-int
-dump_bt848( volatile u_char *bt848 )
-{
- u_long *bt_long;
- u_short *bt_short;
- int r[60]={
- 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
- 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
- 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
- 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
- 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
- 0, 0, 0, 0
- };
- int i;
-
- for (i = 0; i < 40; i+=4) {
- printf(" Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
- r[i], bt848[r[i]],
- r[i+1], bt848[r[i+1]],
- r[i+2], bt848[r[i+2]],
- r[i+3], bt848[r[i+3]]);
- }
-
- bt_long = (u_long *) &bt848[BKTR_INT_STAT];
- printf(" Reg 100 %x \n", *bt_long);
-
- bt_long = (u_long *) &bt848[BKTR_INT_MASK];
- printf(" Reg 104 %x \n", *bt_long);
-
- bt_long = (u_long *) &bt848[BKTR_GPIO_DMA_CTL];
- printf(" Reg 10C %x \n", *bt_long);
-
- return 0;
-}
-
-
-/*
- * build write instruction
- */
-#define BKTR_FM1 0x6
-#define BKTR_FM3 0xe
-#define BKTR_VRE 0x4
-#define BKTR_VRO 0xC
-#define BKTR_PXV 0x0
-#define BKTR_EOL 0x1
-#define BKTR_SOL 0x2
-
-#define OP_WRITE 0x1 << 28
-#define OP_WRITEC 0x5 << 28
-#define OP_JUMP 0x7 << 28
-#define OP_SYNC 0x8 << 28
-#define OP_WRITE123 0x9 << 28
-#define OP_WRITES123 0xb << 28
-#define OP_SOL 1 << 27
-#define OP_EOL 1 << 26
-
-void
-rgb_prog( bktr_reg_t * bktr, char i_flag, int cols,
- int rows, int pixel_width, int interlace )
-{
- int i;
- int byte_count;
- volatile unsigned int inst;
- volatile unsigned int inst2;
- volatile unsigned int inst3;
- volatile u_long target_buffer, buffer;
- volatile u_char *bt848, *bt_reg;
- volatile u_short *bts_reg;
- volatile u_long pitch;
- volatile u_long *dma_prog, *foo, *btl_reg, *t_test;
- int b, c;
-
- bt848 = bktr->base;
-
- /* color format : rgb32 */
- if (bktr->depth == 4)
- bt848[BKTR_COLOR_FMT] = 0;
- else
- bt848[BKTR_COLOR_FMT] = 0x33;
-
- bt848[BKTR_COLOR_CTL] = 0x40;
- bt848[BKTR_COLOR_CTL] = 0x10;
-
-#if 0
- bt848[0x10] = 0x1C;
- bt848[0x90] = 0x1C;
-#endif
-
- bt848[BKTR_VBI_PACK_SIZE] = 0;
- bt848[BKTR_VBI_PACK_DEL] = 0;
-
- bt848[BKTR_ADC] = 0x81;
- bt848[BKTR_COLOR_CTL] = 0x20;
-
- bt848[BKTR_E_VSCALE_HI] |= 0xc0;
- bt848[BKTR_O_VSCALE_HI] |= 0xc0;
-
- bktr->capcontrol = 3 << 2 | 3;
-
- dma_prog = (u_long *) bktr->dma_prog;
-
- /* Construct Write */
- bt_enable_cnt = 0;
-
- b = (cols * pixel_width ) / 2;
-
- /* write, sol, eol */
- inst = OP_WRITE | OP_SOL | bt_enable_cnt << 12 | (b);
- inst2 = OP_WRITE | bt_enable_cnt << 12 | (cols * pixel_width/2);
- /* write , sol, eol */
- inst3 = OP_WRITE | OP_EOL | bt_enable_cnt << 12 | (b);
-
- if (bktr->video.addr) {
- target_buffer = (u_long) bktr->video.addr;
- pitch = bktr->video.width;
- }
- else {
- target_buffer = (u_long) vtophys(bktr->bigbuf);
- pitch = cols*pixel_width;
- }
-
- buffer = target_buffer;
-
- /* contruct sync : for video packet format */
- *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 15 | BKTR_FM1;
-
- /* sync, mode indicator packed data */
- *dma_prog++ = 0; /* NULL WORD */
-
- for (i = 0; i < (rows/interlace); i++) {
- *dma_prog++ = inst;
- *dma_prog++ = target_buffer;
- *dma_prog++ = inst3;
- *dma_prog++ = target_buffer + b;
- target_buffer += interlace*pitch;
- }
-
- switch (i_flag) {
- case 1:
- /* sync vre */
- *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRE;
- *dma_prog++ = 0; /* NULL WORD */
-
- *dma_prog++ = OP_JUMP | 0xC << 24;
- *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
- return;
-
- case 2:
- /* sync vre */
- *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 20 | BKTR_VRO;
- *dma_prog++ = 0; /* NULL WORD */
-
- *dma_prog++ = OP_JUMP;
- *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
- return;
-
- case 3:
- /* sync vre */
- *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | 1 << 15 | BKTR_VRO;
- *dma_prog++ = 0; /* NULL WORD */
- *dma_prog++ = OP_JUMP | 0xc << 24 ;
- *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
- break;
- }
-
- if (interlace == 2) {
-
- target_buffer = (u_long) buffer + pitch;
-
- dma_prog = (u_long *) bktr->odd_dma_prog;
-
- /* sync vre IRQ bit */
- *dma_prog++ = OP_SYNC | 0xc << 24 | 1 << 15 | BKTR_FM1;
- *dma_prog++ = 0; /* NULL WORD */
-
- for (i = 0; i < (rows/interlace); i++) {
- *dma_prog++ = inst;
- *dma_prog++ = target_buffer;
- *dma_prog++ = inst3;
- *dma_prog++ = target_buffer + b;
- target_buffer += interlace * pitch;
- }
- }
-
- /* sync vre IRQ bit */
- *dma_prog++ = OP_SYNC | 0xc << 24 | 1 << 24 | 1 << 15 | BKTR_VRE;
- *dma_prog++ = 0; /* NULL WORD */
- *dma_prog++ = OP_JUMP | 0xc << 24;
- *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
- *dma_prog++ = 0; /* NULL WORD */
-}
-
-
-/*
- *
- */
-void
-yuvpack_prog( bktr_reg_t *bktr, char i_flag, int cols, int rows, int interlace)
-{
- int i;
- int byte_count;
- volatile unsigned int inst;
- volatile unsigned int inst2;
- volatile unsigned int inst3;
- volatile u_long target_buffer, buffer;
- volatile u_char *bt848, *bt_reg;
- volatile u_short *bts_reg;
- volatile u_long *dma_prog, *foo, *btl_reg;
- int b;
-
- bt848 = bktr->base;
-
- /* color format : yuvpack */
- bt848[BKTR_COLOR_FMT] = 0x44;
-
- bt848[BKTR_E_SCLOOP] |= 0x40; /* enable chroma comb */
- bt848[BKTR_O_SCLOOP] |= 0x40;
-
- bt848[BKTR_COLOR_CTL] = 0x30;
- bt848[BKTR_ADC] = 0x81;
-
- bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
- bktr->capcontrol = 1 << 5 | 1 << 4 | 1 << 2 | 3;
-
- dma_prog = (u_long *) bktr->dma_prog;
-
- /* Construct Write */
- bt_enable_cnt = 0;
-
- /* write , sol, eol */
- inst = OP_WRITE | OP_SOL | 0xf << 16 | bt_enable_cnt << 12 | (cols*2);
- /* write , sol, eol */
- inst3 = OP_WRITE | OP_EOL | 0xf << 16 | bt_enable_cnt << 12 | (cols);
- inst2 = OP_WRITE | bt_enable_cnt << 12 | (cols );
-
- if (bktr->video.addr)
- target_buffer = (u_long) bktr->video.addr;
- else
- target_buffer = (u_long) vtophys(bktr->bigbuf);
-
- buffer = target_buffer;
-
- /* contruct sync : for video packet format */
- /* sync, mode indicator packed data */
- *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_FM1;
- *dma_prog++ = 0; /* NULL WORD */
-
- b = cols;
-
- for (i = 0; i < (rows/interlace); i++) {
- *dma_prog++ = inst;
- *dma_prog++ = target_buffer;
- *dma_prog++ = inst3;
- *dma_prog++ = target_buffer + b;
- target_buffer += interlace*(cols * 2);
- }
-
- switch (i_flag) {
- case 1:
- /* sync vre */
- *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
- *dma_prog++ = 0; /* NULL WORD */
-
- *dma_prog++ = OP_JUMP;
- *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
- return;
-
- case 2:
- /* sync vre */
- *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 20 | BKTR_VRO;
- *dma_prog++ = 0; /* NULL WORD */
- *dma_prog++ = OP_JUMP;
- *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
- return;
-
- case 3:
- /* sync vre */
- *dma_prog++ = OP_SYNC | 1 << 24 | 0xf << 16 | BKTR_VRE;
- *dma_prog++ = 0; /* NULL WORD */
- *dma_prog++ = OP_JUMP ;
- *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
- break;
- }
-
- if (interlace == 2) {
-
- target_buffer = (u_long) buffer + cols*2;
-
- dma_prog = (u_long * ) bktr->odd_dma_prog;
-
- /* sync vre */
- *dma_prog++ = OP_SYNC | 1 << 24 | 0xf << 16 | 1 << 15 | BKTR_FM1;
- *dma_prog++ = 0; /* NULL WORD */
-
- for (i = 0; i < (rows/interlace) ; i++) {
- *dma_prog++ = inst;
- *dma_prog++ = target_buffer;
- *dma_prog++ = inst3;
- *dma_prog++ = target_buffer + b;
- target_buffer += interlace * ( cols*2);
- }
- }
-
- /* sync vre IRQ bit */
- *dma_prog++ = OP_SYNC | 1 << 24 | 0xf << 16 | BKTR_VRO;
- *dma_prog++ = 0; /* NULL WORD */
- *dma_prog++ = OP_JUMP | 0xf << 16;
- *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
-
- *dma_prog++ = OP_JUMP;
- *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
- *dma_prog++ = 0; /* NULL WORD */
-}
-
-
-/*
- *
- */
-void
-yuv422_prog( bktr_reg_t * bktr, char i_flag, int cols,
- int rows, int interlace)
-{
- int i, j;
- int byte_count;
- volatile unsigned int inst;
- volatile unsigned int inst2;
- volatile unsigned int instskip, instskip2, instskip3;
- volatile unsigned int inst3;
- volatile u_long target_buffer, t1, buffer;
- volatile u_char *bt848, *bt_reg;
- volatile u_short *bts_reg;
- volatile u_long *dma_prog, *foo, *btl_reg;
- int b, b1;
-
- bt848 = bktr->base;
- dma_prog = (u_long *) bktr->dma_prog;
-
- bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
-
- bt848[BKTR_ADC] = 0x81 ;
- bt848[BKTR_OFORM] = 0x00;
-
- bt848[BKTR_E_CONTROL] |= 0x20; /* disable luma decimation */
- bt848[BKTR_O_CONTROL] |= 0x20;
-
- bt848[BKTR_E_SCLOOP] |= 0x40; /* chroma agc enable */
- bt848[BKTR_O_SCLOOP] |= 0x40;
-
- bt848[BKTR_E_VSCALE_HI] |= 0xc0; /* luma comb and comb enable */
- bt848[BKTR_O_VSCALE_HI] |= 0xc0;
-
- bt848[BKTR_COLOR_FMT] = 0x88;
-
- bt848[BKTR_COLOR_CTL] = 0x10; /* disable gamma correction */
-
- bt_enable_cnt = 0;
-
- /* Construct Write */
- inst = OP_WRITE123 | OP_SOL | OP_EOL | bt_enable_cnt << 12 | (cols);
- inst2 = OP_WRITES123 | OP_SOL | OP_EOL | bt_enable_cnt << 12 | (cols);
-
- if (bktr->video.addr)
- target_buffer = (u_long) bktr->video.addr;
- else
- target_buffer = (u_long) vtophys(bktr->bigbuf);
-
- buffer = target_buffer;
-
- t1 = target_buffer;
-
- /* contruct sync : for video packet format */
- *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
- *dma_prog++ = 0; /* NULL WORD */
-
- for (i = 0; i < (rows/interlace ) ; i++) {
- *dma_prog++ = inst;
- *dma_prog++ = cols/2 | cols/2 << 16;
- *dma_prog++ = target_buffer;
- *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
- *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
- target_buffer += interlace*cols;
- }
-
- switch (i_flag) {
- case 1:
- *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRE; /*sync vre*/
- *dma_prog++ = 0; /* NULL WORD */
-
- *dma_prog++ = OP_JUMP | 0xc << 24;
- *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
- return;
- break;
- case 2:
- *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRO; /*sync vre*/
- *dma_prog++ = 0; /* NULL WORD */
-
- *dma_prog++ = OP_JUMP;
- *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
- return;
- break;
- case 3:
- *dma_prog++ = OP_SYNC | 0xc << 24 | 1 << 15 | BKTR_VRO;
- *dma_prog++ = 0; /* NULL WORD */
-
- *dma_prog++ = OP_JUMP | 0xc << 24 ;
- *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
- break;
- }
-
- if (interlace == 2) {
-
- dma_prog = (u_long * ) bktr->odd_dma_prog;
-
- target_buffer = (u_long) buffer + cols;
- t1 = target_buffer + cols/2;
- *dma_prog++ = OP_SYNC | 0xc << 24 | 1 << 24 | 1 << 15 | BKTR_FM3;
- *dma_prog++ = 0; /* NULL WORD */
-
- for (i = 0; i < (rows/interlace ) ; i++) {
- *dma_prog++ = inst;
- *dma_prog++ = cols/2 | cols/2 << 16;
- *dma_prog++ = target_buffer;
- *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
- *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
- target_buffer += interlace*cols;
- }
- }
-
- *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRE;
- *dma_prog++ = 0; /* NULL WORD */
- *dma_prog++ = OP_JUMP | 0xC << 24;;
- *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
- *dma_prog++ = 0; /* NULL WORD */
-}
-
-
-/*
- *
- */
-void
-build_dma_prog( bktr_reg_t * bktr, char i_flag)
-{
- int i;
- int pixel_width, rows, cols, byte_count, interlace;
- volatile unsigned int inst;
- volatile unsigned int inst2;
- volatile unsigned int inst3;
- volatile u_long target_buffer;
- volatile u_char *bt848, *bt_reg;
- volatile u_short *bts_reg;
- volatile u_long * dma_prog, *foo, *btl_reg;
- int b;
-
- bt848 = bktr->base;
- btl_reg = (u_long *) &bt848[BKTR_INT_MASK] ;
- *btl_reg = 0;
-
- bts_reg = (u_short * ) &bt848[BKTR_GPIO_DMA_CTL];
- *bts_reg &= ~3;
-
- /* capture control */
- switch (i_flag) {
- case 1:
- bktr->bktr_cap_ctl = 0x11;
- bt848[BKTR_CAP_CTL] = 0x11;
- bt848[BKTR_E_VSCALE_HI] &= ~0x20;
- bt848[BKTR_O_VSCALE_HI] &= ~0x20;
- interlace = 1;
- break;
- case 2:
- bktr->bktr_cap_ctl = 0x12;
- bt848[BKTR_CAP_CTL] = 0x12;
- bt848[BKTR_E_VSCALE_HI] &= ~0x20;
- bt848[BKTR_O_VSCALE_HI] &= ~0x20;
- interlace = 1;
- break;
- default:
- bktr->bktr_cap_ctl = 0x13;
- bt848[BKTR_CAP_CTL] = 0x13;
- bt848[BKTR_E_VSCALE_HI] |= 0x20;
- bt848[BKTR_O_VSCALE_HI] |= 0x20;
- interlace = 2;
- break;
- }
-
- btl_reg = (u_long *) &bt848[BKTR_RISC_STRT_ADD] ;
- *btl_reg = vtophys(bktr->dma_prog);
-
- pixel_width = bktr->depth;
- rows = bktr->rows;
- cols = bktr->cols;
-
- if (bktr->format == METEOR_GEO_RGB24 ||
- bktr->format == METEOR_GEO_RGB16) {
- rgb_prog(bktr, i_flag, cols, rows, pixel_width, interlace);
- return;
- }
-
- if (bktr->format == METEOR_GEO_YUV_422 ){
- yuv422_prog(bktr, i_flag, cols, rows, interlace);
- return;
- }
-
- if (bktr->format == METEOR_GEO_YUV_PACKED ){
- yuvpack_prog(bktr, i_flag, cols, rows, interlace);
- return;
- }
-
- return;
-}
-
-
-/*
- *
- */
-void
-start_capture(bktr_reg_t *bktr, unsigned type)
-{
- volatile u_char * bt848, *bt_reg, i_flag;
- volatile u_short *bts_reg;
- volatile u_long *btl_reg;
- bt848 = (u_char *) bktr->base;
-
- *bt848 = 0;
- btl_reg = (u_long *) &bt848[BKTR_INT_STAT];
- *btl_reg = *btl_reg;
-
- bktr->flags |= type;
- switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
- case METEOR_ONLY_EVEN_FIELDS:
- bktr->flags |= METEOR_WANT_EVEN;
- i_flag = 1;
- break;
- case METEOR_ONLY_ODD_FIELDS:
- bktr->flags |= METEOR_WANT_ODD;
- i_flag = 2;
- break;
- default:
- bktr->flags |= METEOR_WANT_MASK;
- i_flag = 3;
- break;
- }
-
- if (!bktr->dma_prog_loaded) {
- build_dma_prog(bktr, i_flag);
- bktr->dma_prog_loaded = 1;
- }
-
-/*XXX
- switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
- default:
- *bts_reg |= 0xb;
- }
-*/
-
- btl_reg = (u_long *) &bt848[BKTR_RISC_STRT_ADD];
- *btl_reg = vtophys(bktr->dma_prog);
-
-/*XXX
- bts_reg = (u_short *) &bt848[BKTR_GPIO_DMA_CTL];
- *bts_reg = 0x3;
-*/
-
-}
-
-/*
- *
- */
-static void
-set_fps(bktr_reg_t *bktr, u_short fps)
-{
- volatile u_char * bt848, *bt_reg;
- volatile u_long * btl_reg;
- volatile u_short * bts_reg;
- bt848 = (u_char *) bktr->base;
-
- bts_reg = (u_short *) &bt848[BKTR_GPIO_DMA_CTL];
- *bts_reg = 0;
- btl_reg = (u_long *) &bt848[BKTR_INT_STAT];
- *btl_reg = 0xffffffff;
-
- bktr->fps = fps;
-
- if ( fps == 30 ) {
- bt848[BKTR_TDEC] = 0;
- return;
- } else {
- bt848[BKTR_TDEC] = (int) (((float) fps / 30.0) * 60.0) & 0x3f;
- bt848[BKTR_TDEC] |= 0x80;
- }
-
- if ( bktr->flags & METEOR_CAP_MASK ) {
-
- btl_reg = (u_long *) &bt848[BKTR_INT_STAT];
- *btl_reg = 0xffffffff;
- btl_reg = (u_long *) &bt848[BKTR_RISC_STRT_ADD];
- *btl_reg = vtophys(bktr->dma_prog);
-
- bts_reg = (u_short *) &bt848[BKTR_GPIO_DMA_CTL];
- *bts_reg = 1;
- *bts_reg = bktr->capcontrol;
- btl_reg = (u_long *) &bt848[BKTR_INT_MASK];
- *btl_reg = 1 << 11 | 2 | 1;
- }
-
- return;
-
-}
-
-
-/*
- * There is also a problem with range checking on the 7116.
- * It seems to only work for 22 bits, so the max size we can allocate
- * is 22 bits long or 4194304 bytes assuming that we put the beginning
- * of the buffer on a 2^24 bit boundary. The range registers will use
- * the top 8 bits of the dma start registers along with the bottom 22
- * bits of the range register to determine if we go out of range.
- * This makes getting memory a real kludge.
- *
- */
-
-#define RANGE_BOUNDARY (1<<22)
-static vm_offset_t
-get_bktr_mem( int unit, unsigned size )
-{
- vm_offset_t addr = 0;
-
- addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff, 1<<24);
- if (addr == 0)
- addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff,
- PAGE_SIZE);
- if (addr == 0) {
- printf("meteor%d: Unable to allocate %d bytes of memory.\n",
- unit, size);
- }
- return addr;
-}
-
-
-/*
* what should we do here?
*/
static void
@@ -1104,21 +506,26 @@ bktr_init ( bktr_reg_t *bktr )
}
+/*
+ * the attach routine.
+ */
static void
bktr_attach( pcici_t tag, int unit )
{
- bktr_reg_t *bktr;
- volatile u_char *bt848;
- volatile u_long *btl_reg;
+ bktr_reg_t *bktr;
+ volatile u_char *bt848;
+ volatile u_long *btl_reg;
#ifdef BROOKTREE_IRQ
- u_long old_irq, new_irq;
+ u_long old_irq, new_irq;
#endif
- u_char *test;
- vm_offset_t buf;
- u_long latency;
- u_long foo,fun;
+ u_char *test;
+ vm_offset_t buf;
+ u_long latency;
+ u_long fun;
+
bt_enable_cnt = 0;
bktr = &brooktree[unit];
+
if (unit >= NBKTR) {
printf("brooktree%d: attach: only %d units configured.\n",
unit, NBKTR);
@@ -1145,7 +552,6 @@ bktr_attach( pcici_t tag, int unit )
/*
* PCI latency timer. 32 is a good value for 4 bus mastering slots, if
* you have more than for, then 16 would probably be a better value.
- *
*/
#ifndef BROOKTREE_DEF_LATENCY_VALUE
#define BROOKTREE_DEF_LATENCY_VALUE 10
@@ -1217,7 +623,9 @@ end of setup up dma risc program
/* defaults for the tuner section of the card */
bktr->tuner.frequency = 0;
bktr->tuner.channel = 0;
- bktr->tuner.tunertype = DEFAULT_TUNERTYPE;
+ bktr->tuner.chnlset = DEFAULT_CHNLSET;
+
+ probe_card( bktr, 1 );
#ifdef DEVFS
bktr->devfs_token = devfs_add_devswf(&bktr_cdevsw, unit,
@@ -1242,12 +650,12 @@ end of setup up dma risc program
int
bktr_open( dev_t dev, int flags, int fmt, struct proc *p )
{
- bktr_reg_t *bktr;
- int unit;
- int i;
- volatile u_char *bt848;
- volatile u_char *bt_reg;
- volatile u_long *btl_reg;
+ bktr_reg_t *bktr;
+ int unit;
+ int i;
+ volatile u_char *bt848;
+ volatile u_char *bt_reg;
+ volatile u_long *btl_reg;
unit = UNIT(minor(dev));
if (unit >= NBKTR) /* unit out of range */
@@ -1270,7 +678,10 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p )
bt848 = bktr->base;
- /* dump_bt848(bt848); */
+#if 0
+ dump_bt848( bt848 );
+#endif /* 0 */
+
*bt848 = 0x3; /* bt848[ 0 ] */
*bt848 = 0xc0;
@@ -1312,6 +723,12 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p )
btl_reg = (u_long *) &bt848[BKTR_INT_MASK];
*btl_reg = 1 << 23;
+#if defined( AUDIO_SUPPORT )
+ set_audio( bktr, AUDIO_UNMUTE );
+ if ( card_types[ bktr->card_type ].dbx )
+ set_BTSC( bktr, 0 ); /* enable the stereo chip */
+#endif /* AUDIO_SUPPORT */
+
return(0);
}
@@ -1330,6 +747,7 @@ bktr_close( dev_t dev, int flags, int fmt, struct proc *p )
#ifdef METEOR_DEALLOC_ABOVE
int temp;
#endif
+
unit = UNIT(minor(dev));
if (unit >= NBKTR) /* unit out of range */
return(ENXIO);
@@ -1353,6 +771,11 @@ bktr_close( dev_t dev, int flags, int fmt, struct proc *p )
btl_reg = (u_long *) &bt848[BKTR_INT_STAT] ;
*btl_reg = 0xffffffff;
+#if defined( AUDIO_SUPPORT )
+ /* mute the audio by switching the mux */
+ set_audio( bktr, AUDIO_MUTE );
+#endif /* AUDIO_SUPPORT */
+
return(0);
}
@@ -1435,7 +858,6 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr )
struct meteor_geomet *geo;
struct meteor_counts *cnt;
struct meteor_video *video;
- u_long *foo;
vm_offset_t buf;
unit = UNIT(minor(dev));
@@ -1451,7 +873,13 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr )
switch (cmd) {
case TVTUNER_SETCHNL:
+#if defined( AUDIO_SUPPORT )
+ set_audio( bktr, AUDIO_MUTE );
+#endif /* AUDIO_SUPPORT */
temp = tv_channel( bktr, (int)*(unsigned long *)arg );
+#if defined( AUDIO_SUPPORT )
+ set_audio( bktr, AUDIO_UNMUTE );
+#endif /* AUDIO_SUPPORT */
if ( temp < 0 )
return EINVAL;
*(unsigned long *)arg = temp;
@@ -1463,13 +891,13 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr )
case TVTUNER_SETTYPE:
temp = *(unsigned long *)arg;
- if ( (temp < TUNERTYPE_MIN) || (temp > TUNERTYPE_MAX) )
+ if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
return EINVAL;
- bktr->tuner.tunertype = temp;
+ bktr->tuner.chnlset = temp;
break;
case TVTUNER_GETTYPE:
- *(unsigned long *)arg = bktr->tuner.tunertype;
+ *(unsigned long *)arg = bktr->tuner.chnlset;
break;
case TVTUNER_GETSTATUS:
@@ -1478,7 +906,13 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr )
break;
case TVTUNER_SETFREQ:
+#if defined( AUDIO_SUPPORT_XXX )
+ set_audio( bktr, AUDIO_MUTE );
+#endif /* AUDIO_SUPPORT */
temp = tv_freq( bktr, (int)*(unsigned long *)arg );
+#if defined( AUDIO_SUPPORT_XXX )
+ set_audio( bktr, AUDIO_UNMUTE );
+#endif /* AUDIO_SUPPORT */
if ( temp < 0 )
return EINVAL;
*(unsigned long *)arg = temp;
@@ -1498,6 +932,8 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr )
case METEORSINPUT: /* set input device */
switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
+
+ /* this is the RCA video input */
case 0: /* default */
case METEOR_INPUT_DEV0:
bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
@@ -1506,8 +942,14 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr )
bt848[BKTR_IFORM] |= 0x60;
bt848[BKTR_E_CONTROL] &= ~0x40;
bt848[BKTR_O_CONTROL] &= ~0x40;
+#if defined( AUDIO_SUPPORT )
+ set_audio( bktr, AUDIO_MUTE );
+ set_audio( bktr, AUDIO_EXTERN );
+ set_audio( bktr, AUDIO_UNMUTE );
+#endif /* AUDIO_SUPPORT */
break;
+ /* this is the tuner input */
case METEOR_INPUT_DEV1:
bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
| METEOR_DEV1;
@@ -1515,17 +957,15 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr )
bt848[BKTR_IFORM] |= 0x40;
bt848[BKTR_E_CONTROL] &= ~0x40;
bt848[BKTR_O_CONTROL] &= ~0x40;
+#if defined( AUDIO_SUPPORT )
+ set_audio( bktr, AUDIO_MUTE );
+ set_audio( bktr, AUDIO_TUNER );
+ set_audio( bktr, AUDIO_UNMUTE );
+#endif /* AUDIO_SUPPORT */
break;
+ /* this is the S-VHS input */
case METEOR_INPUT_DEV2:
- bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
- | METEOR_DEV2;
- bt848[BKTR_IFORM] &= ~0x60;
- bt848[BKTR_IFORM] |= 0x20;
- bt848[BKTR_E_CONTROL] |= 0x40;
- bt848[BKTR_O_CONTROL] |= 0x40;
- break;
-
case METEOR_INPUT_DEV_SVIDEO:
bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
| METEOR_DEV2;
@@ -1533,6 +973,11 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr )
bt848[BKTR_IFORM] |= 0x20;
bt848[BKTR_E_CONTROL] |= 0x40;
bt848[BKTR_O_CONTROL] |= 0x40;
+#if defined( AUDIO_SUPPORT )
+ set_audio( bktr, AUDIO_MUTE );
+ set_audio( bktr, AUDIO_EXTERN );
+ set_audio( bktr, AUDIO_UNMUTE );
+#endif /* AUDIO_SUPPORT */
break;
default:
@@ -1784,6 +1229,25 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr )
bt848[BKTR_COLOR_CTL] &= ~0x40;
break;
+#if defined( AUDIO_SUPPORT )
+ case BT848_SAUDIO: /* set audio channel */
+ if ( set_audio( bktr, *(int*)arg ) < 0 )
+ return EIO;
+ break;
+
+ case BT848_GAUDIO: /* get audio channel */
+ temp = bktr->audio_mux_select;
+ if ( bktr->audio_mute_state == TRUE )
+ temp |= AUDIO_MUTE;
+ *(int*)arg = temp;
+ break;
+
+ case BT848_SBTSC: /* set audio channel */
+ if ( set_BTSC( bktr, *(int*)arg ) < 0 )
+ return EIO;
+ break;
+#endif /* AUDIO_SUPPORT */
+
case METEORSSIGNAL:
bktr->signal = *(int *) arg;
bktr->proc = pr;
@@ -1853,7 +1317,10 @@ bktr_ioctl( dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr )
btl_reg = (u_long *) &bt848[BKTR_INT_MASK];
*btl_reg = 1 << 23 | 1 << 11 | 2 | 1;
- /* dump_bt848(bt848); */
+#if 0
+ dump_bt848( bt848 );
+#endif /* 0 */
+
break;
case METEOR_CAP_STOP_CONT:
@@ -2095,54 +1562,664 @@ bktr_mmap( dev_t dev, int offset, int nprot )
/******************************************************************************
- * tuner specific routines:
+ * bt848 RISC programming routines:
*/
-/* guaranteed address for any TSA5522 */
-#define TSA5522_WADDR 0xc2
-#define TSA5522_RADDR 0xc3
-/* EEProm */
-#define X24C01_WADDR 0xae /* STB */
-#define X24C01_RADDR 0xaf
+/*
+ *
+ */
+static int
+dump_bt848( volatile u_char *bt848 )
+{
+ u_long *bt_long;
+ u_short *bt_short;
+ int r[60]={
+ 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
+ 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
+ 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
+ 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
+ 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
+ 0, 0, 0, 0
+ };
+ int i;
+
+ for (i = 0; i < 40; i+=4) {
+ printf(" Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
+ r[i], bt848[r[i]],
+ r[i+1], bt848[r[i+1]],
+ r[i+2], bt848[r[i+2]],
+ r[i+3], bt848[r[i+3]]);
+ }
+
+ bt_long = (u_long *) &bt848[BKTR_INT_STAT];
+ printf(" Reg 100 %x \n", *bt_long);
+
+ bt_long = (u_long *) &bt848[BKTR_INT_MASK];
+ printf(" Reg 104 %x \n", *bt_long);
+
+ bt_long = (u_long *) &bt848[BKTR_GPIO_DMA_CTL];
+ printf(" Reg 10C %x \n", *bt_long);
+
+ return 0;
+}
/*
- * bit 7: CONTROL BYTE = 1
- * bit 6: CP = 0 moderate speed tuning, better FM
- * bit 5: T2 = 0 normal operation
- * bit 4: T1 = 0 normal operation
- * bit 3: T0 = 1 normal operation
- * bit 2: RSA = 1 62.5kHz
- * bit 1: RSB = 1 62.5kHz
- * bit 0: OS = 0 normal operation
+ * build write instruction
*/
-#if defined( TEMIC_TUNER )
-#define TSA5522_CONTROL 0xce
-#else
-#define TSA5522_CONTROL 0x8e
+#define BKTR_FM1 0x6
+#define BKTR_FM3 0xe
+#define BKTR_VRE 0x4
+#define BKTR_VRO 0xC
+#define BKTR_PXV 0x0
+#define BKTR_EOL 0x1
+#define BKTR_SOL 0x2
+
+#define OP_WRITE 0x1 << 28
+#define OP_WRITEC 0x5 << 28
+#define OP_JUMP 0x7 << 28
+#define OP_SYNC 0x8 << 28
+#define OP_WRITE123 0x9 << 28
+#define OP_WRITES123 0xb << 28
+#define OP_SOL 1 << 27
+#define OP_EOL 1 << 26
+
+static void
+rgb_prog( bktr_reg_t * bktr, char i_flag, int cols,
+ int rows, int pixel_width, int interlace )
+{
+ int i;
+ int byte_count;
+ volatile unsigned int inst;
+ volatile unsigned int inst2;
+ volatile unsigned int inst3;
+ volatile u_long target_buffer, buffer;
+ volatile u_char *bt848, *bt_reg;
+ volatile u_short *bts_reg;
+ volatile u_long pitch;
+ volatile u_long *dma_prog, *btl_reg, *t_test;
+ int b, c;
+
+ bt848 = bktr->base;
+
+ /* color format : rgb32 */
+ if (bktr->depth == 4)
+ bt848[BKTR_COLOR_FMT] = 0;
+ else
+ bt848[BKTR_COLOR_FMT] = 0x33;
+
+ bt848[BKTR_COLOR_CTL] = 0x40;
+ bt848[BKTR_COLOR_CTL] = 0x10;
+
+#if 0
+ bt848[0x10] = 0x1C;
+ bt848[0x90] = 0x1C;
#endif
-#if defined( TEMIC_TUNER )
+ bt848[BKTR_VBI_PACK_SIZE] = 0;
+ bt848[BKTR_VBI_PACK_DEL] = 0;
+
+ bt848[BKTR_ADC] = 0x81;
+ bt848[BKTR_COLOR_CTL] = 0x20;
-#define TSA5522_BANDA 0x02
-#define TSA5522_BANDB 0x04
-#define TSA5522_BANDC 0x01
+ bt848[BKTR_E_VSCALE_HI] |= 0xc0;
+ bt848[BKTR_O_VSCALE_HI] |= 0xc0;
-#elif defined( PHILIPS_TUNER )
+ bktr->capcontrol = 3 << 2 | 3;
-#define TSA5522_BANDA 0xa0
-#define TSA5522_BANDB 0x90
-#define TSA5522_BANDC 0x30
+ dma_prog = (u_long *) bktr->dma_prog;
-#else
+ /* Construct Write */
+ bt_enable_cnt = 0;
+
+ b = (cols * pixel_width ) / 2;
+
+ /* write, sol, eol */
+ inst = OP_WRITE | OP_SOL | bt_enable_cnt << 12 | (b);
+ inst2 = OP_WRITE | bt_enable_cnt << 12 | (cols * pixel_width/2);
+ /* write , sol, eol */
+ inst3 = OP_WRITE | OP_EOL | bt_enable_cnt << 12 | (b);
+
+ if (bktr->video.addr) {
+ target_buffer = (u_long) bktr->video.addr;
+ pitch = bktr->video.width;
+ }
+ else {
+ target_buffer = (u_long) vtophys(bktr->bigbuf);
+ pitch = cols*pixel_width;
+ }
+
+ buffer = target_buffer;
+
+ /* contruct sync : for video packet format */
+ *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 15 | BKTR_FM1;
+
+ /* sync, mode indicator packed data */
+ *dma_prog++ = 0; /* NULL WORD */
+
+ for (i = 0; i < (rows/interlace); i++) {
+ *dma_prog++ = inst;
+ *dma_prog++ = target_buffer;
+ *dma_prog++ = inst3;
+ *dma_prog++ = target_buffer + b;
+ target_buffer += interlace*pitch;
+ }
+
+ switch (i_flag) {
+ case 1:
+ /* sync vre */
+ *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRE;
+ *dma_prog++ = 0; /* NULL WORD */
+
+ *dma_prog++ = OP_JUMP | 0xC << 24;
+ *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
+ return;
+
+ case 2:
+ /* sync vre */
+ *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 20 | BKTR_VRO;
+ *dma_prog++ = 0; /* NULL WORD */
+
+ *dma_prog++ = OP_JUMP;
+ *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
+ return;
+
+ case 3:
+ /* sync vre */
+ *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | 1 << 15 | BKTR_VRO;
+ *dma_prog++ = 0; /* NULL WORD */
+ *dma_prog++ = OP_JUMP | 0xc << 24 ;
+ *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
+ break;
+ }
+
+ if (interlace == 2) {
+
+ target_buffer = (u_long) buffer + pitch;
+
+ dma_prog = (u_long *) bktr->odd_dma_prog;
+
+ /* sync vre IRQ bit */
+ *dma_prog++ = OP_SYNC | 0xc << 24 | 1 << 15 | BKTR_FM1;
+ *dma_prog++ = 0; /* NULL WORD */
+
+ for (i = 0; i < (rows/interlace); i++) {
+ *dma_prog++ = inst;
+ *dma_prog++ = target_buffer;
+ *dma_prog++ = inst3;
+ *dma_prog++ = target_buffer + b;
+ target_buffer += interlace * pitch;
+ }
+ }
+
+ /* sync vre IRQ bit */
+ *dma_prog++ = OP_SYNC | 0xc << 24 | 1 << 24 | 1 << 15 | BKTR_VRE;
+ *dma_prog++ = 0; /* NULL WORD */
+ *dma_prog++ = OP_JUMP | 0xc << 24;
+ *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
+ *dma_prog++ = 0; /* NULL WORD */
+}
+
+
+/*
+ *
+ */
+static void
+yuvpack_prog( bktr_reg_t *bktr, char i_flag,
+ int cols, int rows, int interlace )
+{
+ int i;
+ int byte_count;
+ volatile unsigned int inst;
+ volatile unsigned int inst2;
+ volatile unsigned int inst3;
+ volatile u_long target_buffer, buffer;
+ volatile u_char *bt848, *bt_reg;
+ volatile u_short *bts_reg;
+ volatile u_long *dma_prog, *btl_reg;
+ int b;
+
+ bt848 = bktr->base;
+
+ /* color format : yuvpack */
+ bt848[BKTR_COLOR_FMT] = 0x44;
+
+ bt848[BKTR_E_SCLOOP] |= 0x40; /* enable chroma comb */
+ bt848[BKTR_O_SCLOOP] |= 0x40;
+
+ bt848[BKTR_COLOR_CTL] = 0x30;
+ bt848[BKTR_ADC] = 0x81;
+
+ bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
+ bktr->capcontrol = 1 << 5 | 1 << 4 | 1 << 2 | 3;
+
+ dma_prog = (u_long *) bktr->dma_prog;
+
+ /* Construct Write */
+ bt_enable_cnt = 0;
+
+ /* write , sol, eol */
+ inst = OP_WRITE | OP_SOL | 0xf << 16 | bt_enable_cnt << 12 | (cols*2);
+ /* write , sol, eol */
+ inst3 = OP_WRITE | OP_EOL | 0xf << 16 | bt_enable_cnt << 12 | (cols);
+ inst2 = OP_WRITE | bt_enable_cnt << 12 | (cols );
+
+ if (bktr->video.addr)
+ target_buffer = (u_long) bktr->video.addr;
+ else
+ target_buffer = (u_long) vtophys(bktr->bigbuf);
+
+ buffer = target_buffer;
+
+ /* contruct sync : for video packet format */
+ /* sync, mode indicator packed data */
+ *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_FM1;
+ *dma_prog++ = 0; /* NULL WORD */
+
+ b = cols;
+
+ for (i = 0; i < (rows/interlace); i++) {
+ *dma_prog++ = inst;
+ *dma_prog++ = target_buffer;
+ *dma_prog++ = inst3;
+ *dma_prog++ = target_buffer + b;
+ target_buffer += interlace*(cols * 2);
+ }
+
+ switch (i_flag) {
+ case 1:
+ /* sync vre */
+ *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
+ *dma_prog++ = 0; /* NULL WORD */
+
+ *dma_prog++ = OP_JUMP;
+ *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
+ return;
+
+ case 2:
+ /* sync vre */
+ *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 20 | BKTR_VRO;
+ *dma_prog++ = 0; /* NULL WORD */
+ *dma_prog++ = OP_JUMP;
+ *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
+ return;
-#error you must define a tuner type
+ case 3:
+ /* sync vre */
+ *dma_prog++ = OP_SYNC | 1 << 24 | 0xf << 16 | BKTR_VRE;
+ *dma_prog++ = 0; /* NULL WORD */
+ *dma_prog++ = OP_JUMP ;
+ *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
+ break;
+ }
+
+ if (interlace == 2) {
+
+ target_buffer = (u_long) buffer + cols*2;
+
+ dma_prog = (u_long * ) bktr->odd_dma_prog;
+
+ /* sync vre */
+ *dma_prog++ = OP_SYNC | 1 << 24 | 0xf << 16 | 1 << 15
+ | BKTR_FM1;
+ *dma_prog++ = 0; /* NULL WORD */
+
+ for (i = 0; i < (rows/interlace) ; i++) {
+ *dma_prog++ = inst;
+ *dma_prog++ = target_buffer;
+ *dma_prog++ = inst3;
+ *dma_prog++ = target_buffer + b;
+ target_buffer += interlace * ( cols*2);
+ }
+ }
-#endif /* XXXXXX_TUNER */
+ /* sync vre IRQ bit */
+ *dma_prog++ = OP_SYNC | 1 << 24 | 0xf << 16 | BKTR_VRO;
+ *dma_prog++ = 0; /* NULL WORD */
+ *dma_prog++ = OP_JUMP | 0xf << 16;
+ *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
+ *dma_prog++ = OP_JUMP;
+ *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
+ *dma_prog++ = 0; /* NULL WORD */
+}
-/******************************* i2c primitives ******************************/
+
+/*
+ *
+ */
+static void
+yuv422_prog( bktr_reg_t * bktr, char i_flag,
+ int cols, int rows, int interlace ){
+
+ int i, j;
+ int byte_count;
+ volatile unsigned int inst;
+ volatile unsigned int inst2;
+ volatile unsigned int instskip, instskip2, instskip3;
+ volatile unsigned int inst3;
+ volatile u_long target_buffer, t1, buffer;
+ volatile u_char *bt848, *bt_reg;
+ volatile u_short *bts_reg;
+ volatile u_long *dma_prog, *btl_reg;
+ int b, b1;
+
+ bt848 = bktr->base;
+ dma_prog = (u_long *) bktr->dma_prog;
+
+ bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
+
+ bt848[BKTR_ADC] = 0x81 ;
+ bt848[BKTR_OFORM] = 0x00;
+
+ bt848[BKTR_E_CONTROL] |= 0x20; /* disable luma decimation */
+ bt848[BKTR_O_CONTROL] |= 0x20;
+
+ bt848[BKTR_E_SCLOOP] |= 0x40; /* chroma agc enable */
+ bt848[BKTR_O_SCLOOP] |= 0x40;
+
+ bt848[BKTR_E_VSCALE_HI] |= 0xc0; /* luma comb and comb enable */
+ bt848[BKTR_O_VSCALE_HI] |= 0xc0;
+
+ bt848[BKTR_COLOR_FMT] = 0x88;
+
+ bt848[BKTR_COLOR_CTL] = 0x10; /* disable gamma correction */
+
+ bt_enable_cnt = 0;
+
+ /* Construct Write */
+ inst = OP_WRITE123 | OP_SOL | OP_EOL | bt_enable_cnt << 12 | (cols);
+ inst2 = OP_WRITES123 | OP_SOL | OP_EOL | bt_enable_cnt << 12 | (cols);
+
+ if (bktr->video.addr)
+ target_buffer = (u_long) bktr->video.addr;
+ else
+ target_buffer = (u_long) vtophys(bktr->bigbuf);
+
+ buffer = target_buffer;
+
+ t1 = target_buffer;
+
+ /* contruct sync : for video packet format */
+ *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
+ *dma_prog++ = 0; /* NULL WORD */
+
+ for (i = 0; i < (rows/interlace ); i++) {
+ *dma_prog++ = inst;
+ *dma_prog++ = cols/2 | cols/2 << 16;
+ *dma_prog++ = target_buffer;
+ *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
+ *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
+ target_buffer += interlace*cols;
+ }
+
+ switch (i_flag) {
+ case 1:
+ *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRE; /*sync vre*/
+ *dma_prog++ = 0; /* NULL WORD */
+
+ *dma_prog++ = OP_JUMP | 0xc << 24;
+ *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
+ return;
+ break;
+ case 2:
+ *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRO; /*sync vre*/
+ *dma_prog++ = 0; /* NULL WORD */
+
+ *dma_prog++ = OP_JUMP;
+ *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
+ return;
+ break;
+ case 3:
+ *dma_prog++ = OP_SYNC | 0xc << 24 | 1 << 15 | BKTR_VRO;
+ *dma_prog++ = 0; /* NULL WORD */
+
+ *dma_prog++ = OP_JUMP | 0xc << 24 ;
+ *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
+ break;
+ }
+
+ if (interlace == 2) {
+
+ dma_prog = (u_long * ) bktr->odd_dma_prog;
+
+ target_buffer = (u_long) buffer + cols;
+ t1 = target_buffer + cols/2;
+ *dma_prog++ = OP_SYNC | 0xc << 24 | 1 << 24 | 1 << 15 | BKTR_FM3;
+ *dma_prog++ = 0; /* NULL WORD */
+
+ for (i = 0; i < (rows/interlace ) ; i++) {
+ *dma_prog++ = inst;
+ *dma_prog++ = cols/2 | cols/2 << 16;
+ *dma_prog++ = target_buffer;
+ *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
+ *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
+ target_buffer += interlace*cols;
+ }
+ }
+
+ *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRE;
+ *dma_prog++ = 0; /* NULL WORD */
+ *dma_prog++ = OP_JUMP | 0xC << 24;;
+ *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
+ *dma_prog++ = 0; /* NULL WORD */
+}
+
+
+/*
+ *
+ */
+static void
+build_dma_prog( bktr_reg_t * bktr, char i_flag )
+{
+ int i;
+ int pixel_width, rows, cols, byte_count, interlace;
+ volatile unsigned int inst;
+ volatile unsigned int inst2;
+ volatile unsigned int inst3;
+ volatile u_long target_buffer;
+ volatile u_char *bt848, *bt_reg;
+ volatile u_short *bts_reg;
+ volatile u_long *dma_prog, *btl_reg;
+ int b;
+
+ bt848 = bktr->base;
+ btl_reg = (u_long *) &bt848[BKTR_INT_MASK] ;
+ *btl_reg = 0;
+
+ bts_reg = (u_short * ) &bt848[BKTR_GPIO_DMA_CTL];
+ *bts_reg &= ~3;
+
+ /* capture control */
+ switch (i_flag) {
+ case 1:
+ bktr->bktr_cap_ctl = 0x11;
+ bt848[BKTR_CAP_CTL] = 0x11;
+ bt848[BKTR_E_VSCALE_HI] &= ~0x20;
+ bt848[BKTR_O_VSCALE_HI] &= ~0x20;
+ interlace = 1;
+ break;
+ case 2:
+ bktr->bktr_cap_ctl = 0x12;
+ bt848[BKTR_CAP_CTL] = 0x12;
+ bt848[BKTR_E_VSCALE_HI] &= ~0x20;
+ bt848[BKTR_O_VSCALE_HI] &= ~0x20;
+ interlace = 1;
+ break;
+ default:
+ bktr->bktr_cap_ctl = 0x13;
+ bt848[BKTR_CAP_CTL] = 0x13;
+ bt848[BKTR_E_VSCALE_HI] |= 0x20;
+ bt848[BKTR_O_VSCALE_HI] |= 0x20;
+ interlace = 2;
+ break;
+ }
+
+ btl_reg = (u_long *) &bt848[BKTR_RISC_STRT_ADD] ;
+ *btl_reg = vtophys(bktr->dma_prog);
+
+ pixel_width = bktr->depth;
+ rows = bktr->rows;
+ cols = bktr->cols;
+
+ if (bktr->format == METEOR_GEO_RGB24 ||
+ bktr->format == METEOR_GEO_RGB16) {
+ rgb_prog(bktr, i_flag, cols, rows, pixel_width, interlace);
+ return;
+ }
+
+ if (bktr->format == METEOR_GEO_YUV_422 ){
+ yuv422_prog(bktr, i_flag, cols, rows, interlace);
+ return;
+ }
+
+ if (bktr->format == METEOR_GEO_YUV_PACKED ){
+ yuvpack_prog(bktr, i_flag, cols, rows, interlace);
+ return;
+ }
+
+ return;
+}
+
+
+/******************************************************************************
+ * video & video capture specific routines:
+ */
+
+
+/*
+ *
+ */
+static void
+start_capture( bktr_reg_t *bktr, unsigned type )
+{
+ volatile u_char *bt848, *bt_reg, i_flag;
+ volatile u_short *bts_reg;
+ volatile u_long *btl_reg;
+
+ bt848 = (u_char *) bktr->base;
+
+ *bt848 = 0;
+ btl_reg = (u_long *) &bt848[BKTR_INT_STAT];
+ *btl_reg = *btl_reg;
+
+ bktr->flags |= type;
+ switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
+ case METEOR_ONLY_EVEN_FIELDS:
+ bktr->flags |= METEOR_WANT_EVEN;
+ i_flag = 1;
+ break;
+ case METEOR_ONLY_ODD_FIELDS:
+ bktr->flags |= METEOR_WANT_ODD;
+ i_flag = 2;
+ break;
+ default:
+ bktr->flags |= METEOR_WANT_MASK;
+ i_flag = 3;
+ break;
+ }
+
+ if (!bktr->dma_prog_loaded) {
+ build_dma_prog(bktr, i_flag);
+ bktr->dma_prog_loaded = 1;
+ }
+
+/*XXX
+ switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
+ default:
+ *bts_reg |= 0xb;
+ }
+*/
+
+ btl_reg = (u_long *) &bt848[BKTR_RISC_STRT_ADD];
+ *btl_reg = vtophys(bktr->dma_prog);
+
+/*XXX
+ bts_reg = (u_short *) &bt848[BKTR_GPIO_DMA_CTL];
+ *bts_reg = 0x3;
+*/
+
+}
+
+/*
+ *
+ */
+static void
+set_fps( bktr_reg_t *bktr, u_short fps )
+{
+ volatile u_char *bt848, *bt_reg;
+ volatile u_long *btl_reg;
+ volatile u_short *bts_reg;
+
+ bt848 = (u_char *) bktr->base;
+
+ bts_reg = (u_short *) &bt848[BKTR_GPIO_DMA_CTL];
+ *bts_reg = 0;
+ btl_reg = (u_long *) &bt848[BKTR_INT_STAT];
+ *btl_reg = 0xffffffff;
+
+ bktr->fps = fps;
+
+ if ( fps == 30 ) {
+ bt848[BKTR_TDEC] = 0;
+ return;
+ } else {
+ bt848[BKTR_TDEC] = (int) (((float) fps / 30.0) * 60.0) & 0x3f;
+ bt848[BKTR_TDEC] |= 0x80;
+ }
+
+ if ( bktr->flags & METEOR_CAP_MASK ) {
+
+ btl_reg = (u_long *) &bt848[BKTR_INT_STAT];
+ *btl_reg = 0xffffffff;
+ btl_reg = (u_long *) &bt848[BKTR_RISC_STRT_ADD];
+ *btl_reg = vtophys(bktr->dma_prog);
+
+ bts_reg = (u_short *) &bt848[BKTR_GPIO_DMA_CTL];
+ *bts_reg = 1;
+ *bts_reg = bktr->capcontrol;
+ btl_reg = (u_long *) &bt848[BKTR_INT_MASK];
+ *btl_reg = 1 << 11 | 2 | 1;
+ }
+
+ return;
+}
+
+
+/*
+ * There is also a problem with range checking on the 7116.
+ * It seems to only work for 22 bits, so the max size we can allocate
+ * is 22 bits long or 4194304 bytes assuming that we put the beginning
+ * of the buffer on a 2^24 bit boundary. The range registers will use
+ * the top 8 bits of the dma start registers along with the bottom 22
+ * bits of the range register to determine if we go out of range.
+ * This makes getting memory a real kludge.
+ *
+ */
+
+#define RANGE_BOUNDARY (1<<22)
+static vm_offset_t
+get_bktr_mem( int unit, unsigned size )
+{
+ vm_offset_t addr = 0;
+
+ addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff, 1<<24);
+ if (addr == 0)
+ addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff,
+ PAGE_SIZE);
+ if (addr == 0) {
+ printf("meteor%d: Unable to allocate %d bytes of memory.\n",
+ unit, size);
+ }
+
+ return addr;
+}
+
+
+/******************************************************************************
+ * i2c primitives:
+ */
/* delays for the I2C bus transactions */
#define NDELAY 0
@@ -2335,10 +2412,208 @@ i2cWrite( i2c_regptr_t bti2c, u_char byte )
#undef LDELAY
-/*************************** end of i2c primitives ***************************/
+#define I2C_REGADDR() (i2c_regptr_t)&bktr->base[ BKTR_I2C_CONTROL ]
-#define I2C_REGADDR() (i2c_regptr_t)&bktr->base[ BKTR_I2C_CONTROL ]
+/******************************************************************************
+ * card probe
+ */
+
+
+/* guaranteed address for any TSA5522 (PLL on all(?) tuners) */
+#define TSA5522_WADDR 0xc2
+#define TSA5522_RADDR 0xc3
+
+/* address of BTSC/SAP decoder chip */
+#define TDA9850_WADDR 0xb6
+#define TDA9850_RADDR 0xb7
+
+/* EEProm (128 * 8) on an STB card */
+#define X24C01_WADDR 0xae
+#define X24C01_RADDR 0xaf
+
+/* EEProm (256 * 8) on a Hauppauge card */
+#define PFC8582_WADDR 0xa0
+#define PFC8582_RADDR 0xa1
+
+/*
+ * the data for each type of card
+ */
+
+#define NO_TUNER 0
+#define TEMIC_TUNER 1
+#define PHILIPS_TUNER 2
+
+
+/*
+ * Note:
+ * these entried MUST be kept in the order defined by the CARD_XXX defines!
+ */
+struct CARDTYPE card_types[] = {
+
+ /* CARD_UNKNOWN */
+ { "Unknown",
+ NO_TUNER,
+ 0,
+ { 0, 0, 0, 0 } },
+
+ /* CARD_MIRO */
+ { "Miro TV",
+ NO_TUNER, /** TEMIC_TUNER ??? */
+ 0,
+ { 0x02, 0x01, 0x00, 0x00 } }, /* XXX ??? */
+
+ /* CARD_HAUPPAUGE */
+ { "Hauppauge WinCast/TV",
+ PHILIPS_TUNER,
+ 0,
+ { 0x00, 0x02, 0x01, 0x01 } },
+
+ /* CARD_STB */
+ { "STB TV/PCI",
+ TEMIC_TUNER,
+ 0,
+ { 0x00, 0x01, 0x02, 0x02 } },
+
+ /* CARD_INTEL */
+ { "Intel Smart Video III",
+ NO_TUNER,
+ 0,
+ { 0, 0, 0, 0 } }
+};
+
+/*
+ * If probe_card() fails to detect the proper card on boot you can
+ * override it by setting the following define to the card you are using:
+ *
+#define OVERRIDE_CARD <card type>
+ *
+ * where <card type> is one of the card defines in the above array.
+ */
+#define PRESENT 0
+#define ABSENT 1
+static int
+probe_card( bktr_reg_t *bktr, int verbose )
+{
+ i2c_regptr_t bti2c;
+ int status;
+
+#if defined( OVERRIDE_CARD )
+ bktr->card_type = OVERRIDE_CARD;
+ goto end;
+#endif
+ /* get the i2c register address */
+ bti2c = I2C_REGADDR();
+
+ /* look for a tuner */
+ status = i2cStart( bti2c, TSA5522_WADDR );
+ i2cStop( bti2c );
+ if ( status == ABSENT ) {
+ bktr->card_type = CARD_INTEL;
+ goto checkDBX;
+ }
+
+ /* look for a hauppauge card */
+ status = i2cStart( bti2c, PFC8582_WADDR );
+ i2cStop( bti2c );
+ if ( status == PRESENT ) {
+ bktr->card_type = CARD_HAUPPAUGE;
+ goto checkTuner;
+ }
+
+ /* look for an STB card */
+ status = i2cStart( bti2c, X24C01_WADDR );
+ i2cStop( bti2c );
+ if ( status == PRESENT ) {
+ bktr->card_type = CARD_STB;
+ goto checkTuner;
+ }
+
+ /* XXX FIXME: (how do I) look for a Miro card */
+ bktr->card_type = CARD_MIRO;
+
+checkTuner:
+ /**
+ * XXX FIXME: how can we differentiate TEMIC vs. PHILIPS tuners ???
+ */
+ status = i2cStart( bti2c, 0xc0 );
+ i2cStop( bti2c );
+ if ( status == PRESENT ) {
+ card_types[ bktr->card_type ].tuner = TEMIC_TUNER;
+ goto checkDBX;
+ }
+
+ status = i2cStart( bti2c, 0xc6 );
+ i2cStop( bti2c );
+ if ( status == PRESENT ) {
+ card_types[ bktr->card_type ].tuner = PHILIPS_TUNER;
+ goto checkDBX;
+ }
+
+ card_types[ bktr->card_type ].tuner = NO_TUNER;
+
+checkDBX:
+ /*
+ * probe for BTSC (dbx) chips.
+ */
+ status = i2cStart( bti2c, TDA9850_WADDR );
+ i2cStop( bti2c );
+ if ( status == PRESENT )
+ card_types[ bktr->card_type ].dbx = 1;
+
+end:
+ if ( verbose ) {
+ printf( "%s", card_types[ bktr->card_type ].name );
+
+ if ( card_types[ bktr->card_type ].tuner )
+ printf( ", %s tuner",
+ card_types[ bktr->card_type ].tuner
+ == TEMIC_TUNER ? "Temic" : "Philips" );
+
+ if ( card_types[ bktr->card_type ].dbx )
+ printf( ", dbx stereo" );
+
+ printf( "\n" );
+ }
+ return bktr->card_type;
+}
+#undef ABSENT
+#undef PRESENT
+
+
+#define TSA5522_BANDA band_addrs[card_types[bktr->card_type].tuner-1][0]
+#define TSA5522_BANDB band_addrs[card_types[bktr->card_type].tuner-1][1]
+#define TSA5522_BANDC band_addrs[card_types[bktr->card_type].tuner-1][2]
+
+u_char band_addrs[][3] = {
+ /* BANDA BANDB BANDC */
+ { 0x02, 0x04, 0x01 }, /* TEMIC */
+ { 0xa0, 0x90, 0x30 } /* PHILIPS */
+};
+
+
+/******************************************************************************
+ * tuner specific routines:
+ */
+
+
+/*
+ * bit 7: CONTROL BYTE = 1
+ * bit 6: CP = 0 moderate speed tuning, better FM
+ * bit 5: T2 = 0 normal operation
+ * bit 4: T1 = 0 normal operation
+ * bit 3: T0 = 1 normal operation
+ * bit 2: RSA = 1 62.5kHz
+ * bit 1: RSB = 1 62.5kHz
+ * bit 0: OS = 0 normal operation
+ *
+ * FIXME: create defines for the above bitfields.
+ */
+#if 0
+#define TSA5522_CONTROL 0xce
+#else
+#define TSA5522_CONTROL 0x8e
+#endif
/* scaling factor for frequencies expressed as ints */
@@ -2373,14 +2648,16 @@ i2cWrite( i2c_regptr_t bti2c, u_char byte )
*
* IF freq: 45.75 mHz
*/
+#define OFFSET 6.00
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),
+ 14, (int)(471.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
+ 7, (int)(175.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
+ 5, (int)( 77.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
+ 2, (int)( 55.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
0
};
+#undef OFFSET
/*
* North American Cable Channels, IRC:
@@ -2394,16 +2671,18 @@ int nabcst[] = {
*
* IF freq: 45.75 mHz
*/
+#define OFFSET 6.00
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),
+ 95, (int)( 91.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
+ 23, (int)(217.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
+ 14, (int)(121.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
+ 7, (int)(175.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
+ 5, (int)( 77.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
+ 2, (int)( 55.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
0
};
+#undef OFFSET
/*
* North American Cable Channels, HRC:
@@ -2432,9 +2711,9 @@ int* freqTable[] = {
};
-#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 ]
+#define TBL_CHNL freqTable[ bktr->tuner.chnlset ][ x ]
+#define TBL_BASE_FREQ freqTable[ bktr->tuner.chnlset ][ x + 1 ]
+#define TBL_OFFSET freqTable[ bktr->tuner.chnlset ][ x + 2 ]
static int
frequency_lookup( bktr_reg_t* bktr, int channel )
{
@@ -2461,7 +2740,7 @@ frequency_lookup( bktr_reg_t* bktr, int channel )
#undef TBL_CHNL
-#define TBL_IF freqTable[ bktr->tuner.tunertype ][ 1 ]
+#define TBL_IF freqTable[ bktr->tuner.chnlset ][ 1 ]
/*
* set the frequency of the tuner
*/
@@ -2473,7 +2752,11 @@ tv_freq( bktr_reg_t* bktr, int frequency )
int N;
int order;
- /* select the band based on frequency */
+ /*
+ * select the band based on frequency
+ * FIXME: do the cross-over points need to be set on a
+ * tuner by tuner basis?
+ */
if ( frequency < (160 * FREQFACTOR) )
band = TSA5522_BANDA;
else if ( frequency < (454 * FREQFACTOR) )
@@ -2486,7 +2769,7 @@ tv_freq( bktr_reg_t* bktr, int frequency )
* where:
* pc is picture carrier, fRF & fIF are in mHz
*
- * frequency is mHz * 16, eg. 55.25 mHz * 16 == 884
+ * frequency was passed in as mHz * 16
*/
N = frequency + TBL_IF;
@@ -2565,9 +2848,123 @@ tuner_status( bktr_reg_t* bktr )
}
+#if defined( AUDIO_SUPPORT )
+/******************************************************************************
+ * audio specific routines:
+ */
+
+
/*
*
*/
+#define AUDIOMUX_DISCOVER_NOT
+static int
+set_audio( bktr_reg_t *bktr, int cmd )
+{
+ volatile u_char *bt848;
+ volatile u_char temp;
+ volatile u_char idx;
+
+#if defined( AUDIOMUX_DISCOVER )
+ if ( cmd >= 200 )
+ cmd -= 200;
+ else
+#endif /* AUDIOMUX_DISCOVER */
+
+ switch (cmd) {
+ case AUDIO_TUNER:
+ bktr->audio_mux_select = 0;
+ break;
+ case AUDIO_EXTERN:
+ bktr->audio_mux_select = 1;
+ break;
+ case AUDIO_INTERN:
+ bktr->audio_mux_select = 2;
+ break;
+ case AUDIO_MUTE:
+ bktr->audio_mute_state = TRUE; /* set mute */
+ break;
+ case AUDIO_UNMUTE:
+ bktr->audio_mute_state = FALSE; /* clear mute */
+ break;
+ default:
+ printf("bktr: audio cmd error %02x\n", cmd);
+ return -1;
+ }
+
+ bt848 = bktr->base;
+
+ /*
+ * Leave the upper bits of the GPIO port alone in case they control
+ * something like the dbx or teletext chips. This doesn't guarantee
+ * success, but follows the rule of least astonishment.
+ */
+ bt848[BKTR_GPIO_OUT_EN] = 0x07; /* drive low 3 bits */
+ bt848[BKTR_GPIO_REG_INP] = 0xf8; /* read state of others */
+
+#if defined( AUDIOMUX_DISCOVER )
+ printf("cmd: %d\n", cmd );
+
+ temp = bt848[BKTR_GPIO_DATA] & ~7;
+ bt848[BKTR_GPIO_DATA] = temp | (cmd & 0xff);
+
+ return 0;
+#endif /* AUDIOMUX_DISCOVER */
+
+ if ( bktr->audio_mute_state == TRUE )
+ idx = 3;
+ else
+ idx = bktr->audio_mux_select;
+
+ temp = bt848[BKTR_GPIO_DATA] & ~7; /* mask off lower three bits */
+ bt848[BKTR_GPIO_DATA] =
+ temp | card_types[bktr->card_type].audiomuxs[idx];
+
+ return 0;
+}
+
+
+/*
+ *
+ */
+#define CON1ADDR 0x04
+#define CON2ADDR 0x05
+#define CON3ADDR 0x06
+#define CON4ADDR 0x07
+
+static int
+set_BTSC( bktr_reg_t *bktr, int control )
+{
+ i2c_regptr_t bti2c;
+
+ /* get the i2c register address */
+ bti2c = I2C_REGADDR();
+
+ /* send the data to the TDA9850 BTSC */
+ if ( i2cStart( bti2c, TDA9850_WADDR ) )
+ goto fubar;
+
+ if ( i2cWrite( bti2c, CON3ADDR ) )
+ goto fubar;
+
+ if ( i2cWrite( bti2c, control ) )
+ goto fubar;
+
+ i2cStop( bti2c );
+ return 0;
+
+ fubar:
+ i2cStop( bti2c );
+ return -1;
+}
+#endif /* AUDIO_SUPPORT */
+
+
+/******************************************************************************
+ * magic:
+ */
+
+
static bktr_devsw_installed = 0;
static void
diff --git a/sys/dev/bktr/bktr_reg.h b/sys/dev/bktr/bktr_reg.h
index 281577f..85c6016 100644
--- a/sys/dev/bktr/bktr_reg.h
+++ b/sys/dev/bktr/bktr_reg.h
@@ -40,58 +40,86 @@
typedef volatile u_int breg_t;
-#define BKTR_DSTATUS 0x000
-#define BKTR_IFORM 0x004
-#define BKTR_TDEC 0x008
-#define BKTR_EVEN_CROP 0x00C
-#define BKTR_ODD_CROP 0x08C
-#define BKTR_E_VDELAY_LO 0x010
-#define BKTR_O_VDELAY_LO 0x090
-#define BKTR_E_VACTIVE_LO 0x014
-#define BKTR_O_VACTIVE_LO 0x094
-#define BKTR_E_DELAY_LO 0x018
-#define BKTR_O_DELAY_LO 0x098
-#define BKTR_E_HACTIVE_LO 0x01C
-#define BKTR_O_HACTIVE_LO 0x09C
-#define BKTR_E_HSCALE_HI 0x020
-#define BKTR_O_HSCALE_HI 0x0A0
-#define BKTR_E_HSCALE_LO 0x024
-#define BKTR_O_HSCALE_LO 0x0A4
-#define BKTR_BRIGHT 0x028
-#define BKTR_E_CONTROL 0x02C
-#define BKTR_O_CONTROL 0x0AC
-#define BKTR_CONTRAST_LO 0x030
-#define BKTR_SAT_U_LO 0x034
-#define BKTR_SAT_V_LO 0x038
-#define BKTR_HUE 0x03C
-#define BKTR_E_SCLOOP 0x040
-#define BKTR_O_SCLOOP 0x0C0
-#define BKTR_OFORM 0x048
-#define BKTR_E_VSCALE_HI 0x04C
-#define BKTR_O_VSCALE_HI 0x0CC
-#define BKTR_E_VSCALE_LO 0x050
-#define BKTR_O_VSCALE_LO 0x0D0
-#define BKTR_TEST 0x054
-#define BKTR_ADELAY 0x060
-#define BKTR_BDELAY 0x064
-#define BKTR_ADC 0x068
-#define BKTR_E_VTC 0x06C
-#define BKTR_O_VTC 0x0EC
-#define BKTR_SRESET 0x07C
-#define BKTR_COLOR_FMT 0x0D4
-#define BKTR_COLOR_CTL 0x0D8
-#define BKTR_CAP_CTL 0x0DC
-#define BKTR_VBI_PACK_SIZE 0x0E0
-#define BKTR_VBI_PACK_DEL 0x0E4
-#define BKTR_INT_STAT 0x100
-#define BKTR_INT_MASK 0x104
-#define BKTR_RISC_COUNT 0x120
-#define BKTR_RISC_STRT_ADD 0x114
-#define BKTR_GPIO_DMA_CTL 0x10C
-#define BKTR_GPIO_OUT_EN 0x118
-#define BKTR_GPIO_REG_INP 0x11C
-#define BKTR_GPIO_DATA 0x200
-#define BKTR_I2C_CONTROL 0x110
+#define BKTR_DSTATUS 0x000
+# define BT848_DSTATUS_PRES (1<<7)
+# define BT848_DSTATUS_HLOC (1<<6)
+# define BT848_DSTATUS_FIELD (1<<5)
+# define BT848_DSTATUS_NUML (1<<4)
+# define BT848_DSTATUS_CSEL (1<<3)
+# define BT848_DSTATUS_LOF (1<<1)
+# define BT848_DSTATUS_COF (1<<0)
+#define BKTR_IFORM 0x004
+#define BKTR_TDEC 0x008
+#define BKTR_EVEN_CROP 0x00C
+#define BKTR_ODD_CROP 0x08C
+#define BKTR_E_VDELAY_LO 0x010
+#define BKTR_O_VDELAY_LO 0x090
+#define BKTR_E_VACTIVE_LO 0x014
+#define BKTR_O_VACTIVE_LO 0x094
+#define BKTR_E_DELAY_LO 0x018
+#define BKTR_O_DELAY_LO 0x098
+#define BKTR_E_HACTIVE_LO 0x01C
+#define BKTR_O_HACTIVE_LO 0x09C
+#define BKTR_E_HSCALE_HI 0x020
+#define BKTR_O_HSCALE_HI 0x0A0
+#define BKTR_E_HSCALE_LO 0x024
+#define BKTR_O_HSCALE_LO 0x0A4
+#define BKTR_BRIGHT 0x028
+#define BKTR_E_CONTROL 0x02C
+#define BKTR_O_CONTROL 0x0AC
+#define BKTR_CONTRAST_LO 0x030
+#define BKTR_SAT_U_LO 0x034
+#define BKTR_SAT_V_LO 0x038
+#define BKTR_HUE 0x03C
+#define BKTR_E_SCLOOP 0x040
+#define BKTR_O_SCLOOP 0x0C0
+#define BKTR_OFORM 0x048
+#define BKTR_E_VSCALE_HI 0x04C
+#define BKTR_O_VSCALE_HI 0x0CC
+#define BKTR_E_VSCALE_LO 0x050
+#define BKTR_O_VSCALE_LO 0x0D0
+#define BKTR_TEST 0x054
+#define BKTR_ADELAY 0x060
+#define BKTR_BDELAY 0x064
+#define BKTR_ADC 0x068
+#define BKTR_E_VTC 0x06C
+#define BKTR_O_VTC 0x0EC
+#define BKTR_SRESET 0x07C
+#define BKTR_COLOR_FMT 0x0D4
+#define BKTR_COLOR_CTL 0x0D8
+#define BKTR_CAP_CTL 0x0DC
+#define BKTR_VBI_PACK_SIZE 0x0E0
+#define BKTR_VBI_PACK_DEL 0x0E4
+#define BKTR_INT_STAT 0x100
+#define BKTR_INT_MASK 0x104
+# define BT848_INT_RISCS (0xf<<28)
+# define BT848_INT_RISC_EN (1<<27)
+# define BT848_INT_RACK (1<<25)
+# define BT848_INT_FIELD (1<<24)
+# define BT848_INT_SCERR (1<<19)
+# define BT848_INT_OCERR (1<<18)
+# define BT848_INT_PABORT (1<<17)
+# define BT848_INT_RIPERR (1<<16)
+# define BT848_INT_PPERR (1<<15)
+# define BT848_INT_FDSR (1<<14)
+# define BT848_INT_FTRGT (1<<13)
+# define BT848_INT_FBUS (1<<12)
+# define BT848_INT_RISCI (1<<11)
+# define BT848_INT_GPINT (1<<9)
+# define BT848_INT_I2CDONE (1<<8)
+# define BT848_INT_VPRES (1<<5)
+# define BT848_INT_HLOCK (1<<4)
+# define BT848_INT_OFLOW (1<<3)
+# define BT848_INT_HSYNC (1<<2)
+# define BT848_INT_VSYNC (1<<1)
+# define BT848_INT_FMTCHG (1<<0)
+#define BKTR_RISC_COUNT 0x120
+#define BKTR_RISC_STRT_ADD 0x114
+#define BKTR_GPIO_DMA_CTL 0x10C
+#define BKTR_GPIO_OUT_EN 0x118
+#define BKTR_GPIO_REG_INP 0x11C
+#define BKTR_GPIO_DATA 0x200
+#define BKTR_I2C_CONTROL 0x110
/*
@@ -99,7 +127,7 @@ typedef volatile u_int breg_t;
*/
struct tvtuner {
int frequency;
- u_char tunertype;
+ u_char chnlset;
u_char channel;
u_char band;
};
@@ -182,6 +210,9 @@ typedef struct bktr_softc {
#endif
struct meteor_video video;
struct tvtuner tuner;
+ u_char card_type; /* brand of card */
+ u_char audio_mux_select; /* current mode of the audio */
+ u_char audio_mute_state; /* mute state of the audio */
} bktr_reg_t;
OpenPOWER on IntegriCloud