Upgrade the bktr driver from 2.07 to 2.10.

- The driver now uses bus_space() and runs on NetBSD 1.4.2
   Submitted by Thomas Klausner <wiz@danbala.ifoer.tuwien.ac.at>

 - Remove startup quirks for video and vbi capture for PAL users.
   PAL TV users can now run FXTV and Alevt in any order.

 - Add support for cable channels >100
   Submitted by Scott Presnell <srp@zgi.com>

 - New MSP3410/3415 setup code added. This is experimental.
   Please set the sysctl hw.bt848.slow_msp_audio to 1 for this.
   Submitted by Frank Nobis<fn@radio-do.de>
This commit is contained in:
Roger Hardiman 2000-04-04 16:54:13 +00:00
parent bcc862e397
commit 24cf43ae21
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=59014
11 changed files with 1333 additions and 637 deletions

View File

@ -442,10 +442,34 @@
2.07 24 Jan 2000 Update i2c code to build on FreeBSD 3.x and 4.x machines.
Added GPIO audio values for the Askey/Dynalink TV card
taken from postings on the V4L mailing list.
taken from postings on the V4L mailing list.
Update Australian Channel Set. Submitted by
John Birrell <jb@cimlogic.com.au>
John Birrell <jb@cimlogic.com.au>
Add new Channel Set for France. Submitted by
Daniel Dagneaux <dagneaux@lure.u-psud.fr>
Daniel Dagneaux <dagneaux@lure.u-psud.fr>
2.08 6 Mar 2000 Reinstate rgb_vbi_prog as the default RISC program for
PAL video. This does not want to work for NTSC, which will
continue to use the rgb_prog RISC program.
Add support for cable channels above channel 100.
Submitted by Scott Presnell <srp@zgi.com>
New MSP3410/3415 setup code submitted by
Frank Nobis<fn@radio-do.de>. This is experimental and is
enabled by setting the sysctl, hw.bt848.slow_msp_audio to 1
before starting FXTV (or before opening /dev/bktrN)
2.09 20 Mar 2000 Thomas Klausner <wiz@danbala.ifoer.tuwien.ac.at> submitted
patches to include the NetBSD and OpenBSD support from driver
1.74 into the new 2.xx driver. NetBSD is tested. OpenBSD is
untested.
Also fixed coding error in bktr_audio.c spotted by Thomas.
Change xxx_ioctl functions to use ioctl_cmd_t for the cmd
parameter. Found by looking at OpenBSDs change logs.
Delete PROT_EXEC from OpenBSD (as per OpenBSD cvs logs).
2.10 4 Apr 2000 Convert to using bus_space() to access the Bt848/878 registers
rather than using a memory mapped structure. This makes the
driver portable to other architectures, like Alpha and PPC.
This was done by Thomas Klausner <wiz@netbsd.org> and
myself Roger Hardiman <roger@freebsd.org>

View File

@ -50,13 +50,29 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
#ifdef __NetBSD__
#include <sys/proc.h>
static int bootverbose = 1;
#endif
#ifdef __FreeBSD__
#include <machine/clock.h> /* for DELAY */
#include <pci/pcivar.h>
#endif
#include <machine/ioctl_meteor.h>
#if (__FreeBSD_version >=300000)
#include <machine/bus_memio.h> /* for bus space */
#include <machine/bus.h>
#include <sys/bus.h>
#endif
#ifdef __NetBSD__
#include <dev/ic/ioctl_meteor.h> /* NetBSD location of .h files */
#include <dev/ic/ioctl_bt848.h>
#else
#include <machine/ioctl_meteor.h> /* Traditional location of .h files */
#include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
#endif
#include <dev/bktr/bktr_reg.h>
#include <dev/bktr/bktr_core.h>
#include <dev/bktr/bktr_tuner.h>
@ -101,7 +117,6 @@ void init_audio_devices( bktr_ptr_t bktr ) {
int
set_audio( bktr_ptr_t bktr, int cmd )
{
bt848_ptr_t bt848;
u_long temp;
volatile u_char idx;
@ -160,8 +175,6 @@ set_audio( bktr_ptr_t bktr, int cmd )
* of Bt848 cards.
*/
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
@ -184,13 +197,12 @@ set_audio( bktr_ptr_t bktr, int cmd )
else
idx = bktr->audio_mux_select;
temp = bt848->gpio_data & ~bktr->card.gpio_mux_bits;
bt848->gpio_data =
temp = INL(bktr, BKTR_GPIO_DATA) & ~bktr->card.gpio_mux_bits;
#if defined( AUDIOMUX_DISCOVER )
bt848->gpio_data = temp | (cmd & 0xff);
printf("cmd: %d audio mux %x temp %x \n", cmd,bktr->card.audiomuxs[ idx ], temp );
OUTL(bktr, BKTR_GPIO_DATA, temp | (cmd & 0xff));
printf("cmd: %d audio mux %x temp %x \n", cmd,bktr->card.audiomuxs[ idx ], temp );
#else
temp | bktr->card.audiomuxs[ idx ];
OUTL(bktr, BKTR_GPIO_DATA, temp | bktr->card.audiomuxs[ idx ]);
#endif /* AUDIOMUX_DISCOVER */
return( 0 );
@ -328,7 +340,6 @@ set_bctv_audio( bktr_ptr_t bktr )
void
bctv_gpio_write( bktr_ptr_t bktr, int port, int val )
{
bt848_ptr_t bt848 = bktr->base;
u_long data, outbits;
port &= BCTV_GPIO_PORT_MASK;
@ -343,23 +354,22 @@ bctv_gpio_write( bktr_ptr_t bktr, int port, int val )
default:
return;
}
bt848->gpio_out_en = 0;
bt848->gpio_data = data;
bt848->gpio_out_en = outbits;
OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
OUTL(bktr, BKTR_GPIO_DATA, data);
OUTL(bktr, BKTR_GPIO_OUT_EN, outbits);
DELAY(BCTV_BITS);
bt848->gpio_data = data & ~BCTV_GPIO_WE;
OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV_GPIO_WE);
DELAY(BCTV_BITS);
bt848->gpio_data = data;
OUTL(bktr, BKTR_GPIO_DATA, data);
DELAY(BCTV_BITS);
bt848->gpio_data = ~0;
bt848->gpio_out_en = 0;
OUTL(bktr, BKTR_GPIO_DATA, ~0);
OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
}
/* Not yet used
int
bctv_gpio_read( bktr_ptr_t bktr, int port )
{
bt848_ptr_t bt848 = bktr->base;
u_long data, outbits, ret;
port &= BCTV_GPIO_PORT_MASK;
@ -373,18 +383,18 @@ bctv_gpio_read( bktr_ptr_t bktr, int port )
default:
return( -1 );
}
bt848->gpio_out_en = 0;
bt848->gpio_data = data;
bt848->gpio_out_en = outbits;
OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
OUTL(bktr, BKTR_GPIO_DATA, data);
OUTL(bktr, BKTR_GPIO_OUT_EN, outbits);
DELAY(BCTV_BITS);
bt848->gpio_data = data & ~BCTV_GPIO_OE;
OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV_GPIO_OE);
DELAY(BCTV_BITS);
ret = bt848->gpio_data;
ret = INL(bktr, BKTR_GPIO_DATA);
DELAY(BCTV_BITS);
bt848->gpio_data = data;
OUTL(bktr, BKTR_GPIO_DATA, data);
DELAY(BCTV_BITS);
bt848->gpio_data = ~0;
bt848->gpio_out_en = 0;
OUTL(bktr, BKTR_GPIO_DATA, ~0);
OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
return( (ret & BCTV_GPIO_VAL_MASK) >> BCTV_GPIO_VAL_SHIFT );
}
*/
@ -409,28 +419,121 @@ void msp_read_id( bktr_ptr_t bktr ){
}
/* Configure the MSP chip to Auto-detect the audio format */
/* Configure the MSP chip to Auto-detect the audio format.
* For the MSP3430G, we use fast autodetect mode
* For the MSP3410/3415 there are two schemes for this
* a) Fast autodetection - the chip is put into autodetect mode, and the function
* returns immediatly. This works in most cases and is the Default Mode.
* b) Slow mode. The function sets the MSP3410/3415 chip, then waits for feedback from
* the chip and re-programs it if needed.
*/
void msp_autodetect( bktr_ptr_t bktr ) {
int auto_detect, loops;
int stereo;
printf("MSP autodetect\n");
/* MSP3430G - countries with mono and DBX stereo */
if (strncmp("3430G", bktr->msp_version_string, 5) == 0){
/* For MSP3430G - countries with mono and DBX stereo */
msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0030,0x2003);/* Enable Auto format detection */
msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0020);/* Standard Select Reg. = BTSC-Stereo*/
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000E,0x2403);/* darned if I know */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0320);/* Source select = (St or A) */
/* & Ch. Matrix = St */
/* & Ch. Matrix = St */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
}
} else {
/* For MSP3410 / 3415 - countries with mono, stereo using 2 FM channels
and NICAM */
/* MSP3410/MSP3415 - countries with mono, stereo using 2 FM channels and NICAM */
/* FAST sound scheme */
if ( (strncmp("3430G", bktr->msp_version_string, 5) != 0)
&& (bktr->slow_msp_audio == 0) ){
if(bootverbose)printf("inside fast MSP autodetect code\n");
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */
msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */
}
/* MSP3410/MSP3415 - European Countries where the fast MSP3410/3415 programming fails */
/* SLOW sound scheme */
if ( (strncmp("3430G", bktr->msp_version_string, 5) != 0)
&& (bktr->slow_msp_audio == 1) ){
if (bootverbose)printf("inside slow MSP autodetect code\n");
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */
/* wait for 0.5s max for terrestrial sound autodetection */
loops = 10;
do {
DELAY(100000);
auto_detect = msp_dpl_read(bktr, bktr->msp_addr, 0x10, 0x007e);
loops++;
} while (auto_detect > 0xff && loops < 50);
if (bootverbose)printf ("Result of autodetect after %dms: %d\n", loops*10, auto_detect);
/* Now set the audio baseband processing */
switch (auto_detect) {
case 0: /* no TV sound standard detected */
break;
case 2: /* M Dual FM */
break;
case 3: /* B/G Dual FM; German stereo */
/* Read the stereo detection value from DSP reg 0x0018 */
DELAY(20000);
stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
if (bootverbose)printf ("Stereo reg 0x18 a: %d\n", stereo);
DELAY(20000);
stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
if (bootverbose)printf ("Stereo reg 0x18 b: %d\n", stereo);
DELAY(20000);
stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
if (bootverbose)printf ("Stereo reg 0x18 c: %d\n", stereo);
if (stereo > 0x0100 && stereo < 0x8000) { /* Seems to be stereo */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker set stereo*/
/*
set spatial effect strength to 50% enlargement
set spatial effect mode b, stereo basewidth enlargment only
*/
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f28);
} else if (stereo > 0x8000) { /* bilingual mode */
if (bootverbose) printf ("Bilingual mode detected\n");
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0000);/* Loudspeaker */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x0000);/* all spatial effects off */
} else { /* must be mono */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0030);/* Loudspeaker */
/*
set spatial effect strength to 50% enlargement
set spatial effect mode a, stereo basewidth enlargment
and pseudo stereo effect with automatic high-pass filter
*/
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f08);
}
#if 0
/* The reset value for Channel matrix mode is FM/AM and SOUNDA/LEFT */
/* We would like STEREO instead val: 0x0020 */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0009,0x0020);/* Headphone */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000a,0x0020);/* SCART1 */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0041,0x0020);/* SCART2 */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000b,0x0020);/* I2S */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000c,0x0020);/* Quasi-Peak Detector Source */
msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000e,0x0001);
#endif
break;
case 8: /* B/G FM NICAM */
msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */
break;
case 9: /* L_AM NICAM or D/K*/
case 10: /* i-FM NICAM */
break;
default:
if (bootverbose) printf ("Unkown autodetection result value: %d\n", auto_detect);
}
}
/* uncomment the following line to enable the MSP34xx 1Khz Tone Generator */
/* turn your speaker volume down low before trying this */
/* msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0014, 0x7f40); */

View File

@ -47,24 +47,40 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "opt_bktr.h"
#include "opt_bktr.h" /* Include any kernel config options */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/vnode.h>
#ifdef __FreeBSD__
#include <machine/clock.h> /* for DELAY */
#include <pci/pcivar.h>
#endif
#include <machine/ioctl_meteor.h>
#if (__FreeBSD_version >=300000)
#include <machine/bus_memio.h> /* for bus space */
#include <machine/bus.h>
#include <sys/bus.h>
#endif
#ifdef __NetBSD__
#include <dev/ic/ioctl_meteor.h> /* NetBSD location for .h files */
#include <dev/ic/ioctl_bt848.h>
#else
#include <machine/ioctl_meteor.h> /* Traditional location for .h files */
#include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
#endif
#include <dev/bktr/bktr_reg.h>
#include <dev/bktr/bktr_core.h>
#include <dev/bktr/bktr_tuner.h>
#include <dev/bktr/bktr_card.h>
#include <dev/bktr/bktr_audio.h>
#ifdef __NetBSD__
static int bootverbose = 1;
#endif
/* Various defines */
#define HAUP_REMOTE_INT_WADDR 0x30
#define HAUP_REMOTE_INT_RADDR 0x31
@ -301,9 +317,20 @@ static const struct CARDTYPE cards[] = {
0, /* EEProm type */
0, /* EEProm size */
/* Tuner, Extern, Intern, Mute, Enabled */
{ 0x621000, 0x621000, 0x621000, 0xE21000, 1 }, /* audio MUX values */
{ 0x621000, 0x621000, 0x621000, 0xE21000, 1 }, /* audio MUX values */
0xfff000 }, /* GPIO mask */
{ CARD_TERRATVPLUS, /* the card id */
"TerraTVplus", /* the 'name' */
NULL, /* the tuner */
0,
0,
0,
0,
0, /* EEProm type */
0, /* EEProm size */
{ 0x20000, 0x00000, 0x30000, 0x40000, 1 }, /* audio MUX values*/
0x70000 }, /* GPIO mask */
};
@ -504,7 +531,6 @@ probeCard( bktr_ptr_t bktr, int verbose, int unit )
{
int card, i,j, card_found;
int status;
bt848_ptr_t bt848;
u_char probe_signature[128], *probe_temp;
int any_i2c_devices;
u_char eeprom[256];
@ -512,24 +538,22 @@ probeCard( bktr_ptr_t bktr, int verbose, int unit )
int tuner_i2c_address = -1;
int eeprom_i2c_address = -1;
bt848 = bktr->base;
/* Select all GPIO bits as inputs */
bt848->gpio_out_en = 0;
OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
if (bootverbose)
printf("bktr: GPIO is 0x%08x\n", bt848->gpio_data);
printf("bktr: GPIO is 0x%08x\n", INL(bktr, BKTR_GPIO_DATA));
#ifdef HAUPPAUGE_MSP_RESET
/* Reset the MSP34xx audio chip. This resolves bootup card
* detection problems with old Bt848 based Hauppauge cards with
* MSP34xx stereo audio chips. This must be user enabled because
* at this point the probe function does not know the card type. */
bt848->gpio_out_en = bt848->gpio_out_en | (1<<5);
bt848->gpio_data = bt848->gpio_data | (1<<5); /* write '1' */
OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | (1<<5));
OUTL(bktr, BKTR_GPIO_DATA, INL(bktr, BKTR_GPIO_DATA) | (1<<5)); /* write '1' */
DELAY(2500); /* wait 2.5ms */
bt848->gpio_data = bt848->gpio_data & ~(1<<5); /* write '0' */
OUTL(bktr, BKTR_GPIO_DATA, INL(bktr, BKTR_GPIO_DATA) & ~(1<<5)); /* write '0' */
DELAY(2500); /* wait 2.5ms */
bt848->gpio_data = bt848->gpio_data | (1<<5); /* write '1' */
OUTL(bktr, BKTR_GPIO_DATA, INL(bktr, BKTR_GPIO_DATA) | (1<<5)); /* write '1' */
DELAY(2500); /* wait 2.5ms */
#endif
@ -581,8 +605,8 @@ probeCard( bktr_ptr_t bktr, int verbose, int unit )
subsystem_vendor_id = (byte_254 << 8) | byte_255;
if ( bootverbose )
printf("subsytem 0x%04x 0x%04x\n",subsystem_vendor_id,
subsystem_id);
printf("subsystem 0x%04x 0x%04x\n",
subsystem_vendor_id, subsystem_id);
if (subsystem_vendor_id == VENDOR_AVER_MEDIA) {
bktr->card = cards[ (card = CARD_AVER_MEDIA) ];
@ -778,7 +802,7 @@ probeCard( bktr_ptr_t bktr, int verbose, int unit )
switch (card) {
case CARD_MIRO:
switch (((bt848->gpio_data >> 10)-1)&7) {
switch (((INL(bktr, BKTR_GPIO_DATA) >> 10)-1)&7) {
case 0: select_tuner( bktr, TEMIC_PAL ); break;
case 1: select_tuner( bktr, PHILIPS_PAL ); break;
case 2: select_tuner( bktr, PHILIPS_NTSC ); break;
@ -974,6 +998,7 @@ probeCard( bktr_ptr_t bktr, int verbose, int unit )
tuner_make, tuner_format);
}
break;
case CARD_LEADTEK:
#if BROOKTREE_SYSTEM_DEFAULT == BROOKTREE_PAL
select_tuner( bktr, PHILIPS_FR1216_PAL );
@ -1038,12 +1063,12 @@ probeCard( bktr_ptr_t bktr, int verbose, int unit )
#ifndef BKTR_NO_MSP_RESET
if (card == CARD_HAUPPAUGE) {
bt848->gpio_out_en = bt848->gpio_out_en | (1<<5);
bt848->gpio_data = bt848->gpio_data | (1<<5); /* write '1' */
OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | (1<<5));
OUTL(bktr, BKTR_GPIO_DATA, INL(bktr, BKTR_GPIO_DATA) | (1<<5)); /* write '1' */
DELAY(2500); /* wait 2.5ms */
bt848->gpio_data = bt848->gpio_data & ~(1<<5); /* write '0' */
OUTL(bktr, BKTR_GPIO_DATA, INL(bktr, BKTR_GPIO_DATA) & ~(1<<5)); /* write '0' */
DELAY(2500); /* wait 2.5ms */
bt848->gpio_data = bt848->gpio_data | (1<<5); /* write '1' */
OUTL(bktr, BKTR_GPIO_DATA, INL(bktr, BKTR_GPIO_DATA) | (1<<5)); /* write '1' */
DELAY(2500); /* wait 2.5ms */
}
#endif
@ -1080,12 +1105,10 @@ probeCard( bktr_ptr_t bktr, int verbose, int unit )
if (bktr->card.dpl3518a) {
bktr->dpl_addr = DPL3518A_WADDR;
/* dpl_read_id( bktr );
dpl_read_id( bktr );
printf("bktr%d: Detected a DPL%s at 0x%x\n", unit,
bktr->dpl_version_string,
bktr->dpl_addr);
*/
}
/* Start of Check Remote */

View File

@ -75,7 +75,8 @@
#define CARD_VIDEO_HIGHWAY_XTREME 13
#define CARD_ASKEY_DYNALINK_MAGIC_TVIEW 14
#define CARD_LEADTEK 15
#define Bt848_MAX_CARD 16
#define CARD_TERRATVPLUS 16
#define Bt848_MAX_CARD 17
int signCard( bktr_ptr_t bktr, int offset, int count, u_char* sig );

File diff suppressed because it is too large Load Diff

View File

@ -79,13 +79,13 @@ int video_open( bktr_ptr_t bktr );
int video_close( bktr_ptr_t bktr );
int video_read( bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio );
int video_ioctl( bktr_ptr_t bktr, int unit,
int cmd, caddr_t arg, struct proc* pr );
ioctl_cmd_t cmd, caddr_t arg, struct proc* pr );
int tuner_open( bktr_ptr_t bktr );
int tuner_close( bktr_ptr_t bktr );
int tuner_ioctl( bktr_ptr_t bktr, int unit,
int cmd, caddr_t arg, struct proc* pr );
ioctl_cmd_t cmd, caddr_t arg, struct proc* pr );
int vbi_open( bktr_ptr_t bktr );
int vbi_close( bktr_ptr_t bktr );

View File

@ -48,6 +48,12 @@
#include <machine/clock.h>
#if (__FreeBSD_version >=300000)
#include <machine/bus_memio.h> /* for bus space */
#include <machine/bus.h>
#include <sys/bus.h>
#endif
#include <pci/pcivar.h>
#include <pci/pcireg.h>
#include <machine/ioctl_meteor.h>
@ -73,7 +79,8 @@ static int bti2c_debug = 0;
struct bti2c_softc {
bt848_ptr_t base;
bus_space_tag_t memt; /* Bus space register access */
bus_space_handle_t memh; /* Bus space register access */
int iic_owned; /* 1 if we own the iicbus */
int smb_owned; /* 1 if we own the smbbus */
@ -83,7 +90,8 @@ struct bti2c_softc {
};
struct bt_data {
bt848_ptr_t base;
bus_space_tag_t memt;
bus_space_handle_t memh;
};
struct bt_data btdata[NBKTR];
@ -144,16 +152,17 @@ static driver_t bti2c_driver = {
#endif
/*
* Call this to pass the base address of the bktr device to the
* Call this to pass the address of the bktr device to the
* bti2c_i2c layer and initialize all the I2C bus architecture
*/
int
bt848_i2c_attach(int unit, bt848_ptr_t base, struct bktr_i2c_softc *i2c_sc)
bt848_i2c_attach(int unit, struct bktr_softc * bktr, struct bktr_i2c_softc *i2c_sc)
{
device_t interface;
device_t bitbang;
btdata[unit].base = base;
btdata[unit].memh = bktr->memh;
btdata[unit].memt = bktr->memt;
/* XXX add the I2C interface to the root_bus until pcibus is ready */
#if (__FreeBSD_version < 400000)
@ -205,7 +214,8 @@ bti2c_attach(device_t dev)
/* XXX should use ivars with pcibus or pcibus methods to access
* onboard memory */
sc->base = btdata[device_get_unit(dev)].base;
sc->memh = btdata[device_get_unit(dev)].memh;
sc->memt = btdata[device_get_unit(dev)].memt;
return (0);
}
@ -297,11 +307,8 @@ static void
bti2c_iic_setlines(device_t dev, int ctrl, int data)
{
struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
bt848_ptr_t bti2c;
bti2c = sc->base;
bti2c->i2c_data_ctl = (ctrl << 1) | data;
OUTL(sc, BKTR_I2C_DATA_CTL, (ctrl << 1) | data);;
DELAY(I2C_DELAY);
return;
@ -311,36 +318,33 @@ static int
bti2c_iic_getdataline(device_t dev)
{
struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
bt848_ptr_t bti2c;
bti2c = sc->base;
return (bti2c->i2c_data_ctl & 0x1);
return ( INL(sc,BKTR_I2C_DATA_CTL) & 0x1);
}
static int
bti2c_write(bt848_ptr_t bti2c, u_long data)
bti2c_write(struct bti2c_softc* bti2c_sc, u_long data)
{
u_long x;
/* clear status bits */
bti2c->int_stat = (BT848_INT_RACK | BT848_INT_I2CDONE);
OUTL(bti2c_sc, BKTR_INT_STAT, (BT848_INT_RACK | BT848_INT_I2CDONE));
BTI2C_DEBUG(printf("w%lx", data));
/* write the address and data */
bti2c->i2c_data_ctl = data;
OUTL(bti2c_sc, BKTR_I2C_DATA_CTL, data);
/* wait for completion */
for ( x = 0x7fffffff; x; --x ) { /* safety valve */
if ( bti2c->int_stat & BT848_INT_I2CDONE )
if ( INL(bti2c_sc, BKTR_INT_STAT) & BT848_INT_I2CDONE )
break;
}
/* check for ACK */
if ( !x || !(bti2c->int_stat & BT848_INT_RACK) ) {
if ( !x || !( INL(bti2c_sc, BKTR_INT_STAT) & BT848_INT_RACK) ) {
BTI2C_DEBUG(printf("%c%c", (!x)?'+':'-',
(!(bti2c->int_stat & BT848_INT_RACK))?'+':'-'));
(!( INL(bti2c_sc, BKTR_INT_STAT) & BT848_INT_RACK))?'+':'-'));
return (SMB_ENOACK);
}
BTI2C_DEBUG(printf("+"));
@ -357,7 +361,7 @@ bti2c_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
data = ((slave & 0xff) << 24) | ((byte & 0xff) << 16) | (u_char)cmd;
return (bti2c_write(sc->base, data));
return (bti2c_write(sc, data));
}
/*
@ -377,7 +381,7 @@ bti2c_smb_writew(device_t dev, u_char slave, char cmd, short word)
data = ((slave & 0xff) << 24) | ((low & 0xff) << 16) |
((high & 0xff) << 8) | BT848_DATA_CTL_I2CW3B | (u_char)cmd;
return (bti2c_write(sc->base, data));
return (bti2c_write(sc, data));
}
/*
@ -387,32 +391,29 @@ static int
bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
{
struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
bt848_ptr_t bti2c;
u_long x;
bti2c = sc->base;
/* clear status bits */
bti2c->int_stat = (BT848_INT_RACK | BT848_INT_I2CDONE);
OUTL(sc,BKTR_INT_STAT, (BT848_INT_RACK | BT848_INT_I2CDONE));
bti2c->i2c_data_ctl = ((slave & 0xff) << 24) | (u_char)cmd;
OUTL(sc,BKTR_I2C_DATA_CTL, ((slave & 0xff) << 24) | (u_char)cmd);;
BTI2C_DEBUG(printf("r%lx/", (u_long)(((slave & 0xff) << 24) | (u_char)cmd)));
/* wait for completion */
for ( x = 0x7fffffff; x; --x ) { /* safety valve */
if ( bti2c->int_stat & BT848_INT_I2CDONE )
if ( INL(sc,BKTR_INT_STAT) & BT848_INT_I2CDONE )
break;
}
/* check for ACK */
if ( !x || !(bti2c->int_stat & BT848_INT_RACK) ) {
if ( !x || !(INL(sc,BKTR_INT_STAT) & BT848_INT_RACK) ) {
BTI2C_DEBUG(printf("r%c%c", (!x)?'+':'-',
(!(bti2c->int_stat & BT848_INT_RACK))?'+':'-'));
(!( INL(sc,BKTR_INT_STAT) & BT848_INT_RACK))?'+':'-'));
return (SMB_ENOACK);
}
*byte = (char)((bti2c->i2c_data_ctl >> 8) & 0xff);
*byte = (char)((INL(sc,BKTR_I2C_DATA_CTL) >> 8) & 0xff);
BTI2C_DEBUG(printf("r%x+", *byte));
return (0);

View File

@ -29,6 +29,6 @@
#ifndef _BT848_I2C_H
#define _BT848_I2C_H
extern int bt848_i2c_attach(int, bt848_ptr_t, struct bktr_i2c_softc *);
extern int bt848_i2c_attach(int, struct bktr_softc *bktr, struct bktr_i2c_softc *);
#endif

View File

@ -50,14 +50,10 @@
#ifdef __FreeBSD__
#include "bktr.h"
#include "opt_bktr.h"
#include "opt_devfs.h"
#endif /* __FreeBSD__ */
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include "bktr.h"
#include "pci.h"
#endif /* __NetBSD__ || __OpenBSD__ */
#include "opt_bktr.h" /* include any kernel config options */
#define FIFO_RISC_DISABLED 0
#define ALL_INTS_DISABLED 0
@ -93,18 +89,30 @@
#include <sys/bus.h> /* used by smbus and newbus */
#endif
#if (__FreeBSD_version >=300000)
#include <machine/bus_memio.h> /* used by bus space */
#include <machine/bus.h> /* used by bus space and newbus */
#include <sys/bus.h>
#endif
#if (__FreeBSD_version >=400000)
#include <machine/bus.h> /* used by newbus */
#include <sys/rman.h> /* used by newbus */
#include <machine/resource.h> /* used by newbus */
#endif
#include <machine/clock.h> /* for DELAY */
#include <pci/pcivar.h>
#include <pci/pcireg.h>
#endif
#ifdef __NetBSD__
#include <dev/ic/ioctl_meteor.h> /* NetBSD location for .h files */
#include <dev/ic/ioctl_bt848.h>
#else /* Traditional location for .h files */
#include <machine/ioctl_meteor.h>
#include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
#endif
#include <dev/bktr/bktr_reg.h>
#include <dev/bktr/bktr_tuner.h>
#include <dev/bktr/bktr_card.h>
@ -112,6 +120,7 @@
#include <dev/bktr/bktr_core.h>
#include <dev/bktr/bktr_os.h>
#if defined(__FreeBSD__)
#if (NSMBUS > 0)
#include <dev/bktr/bktr_i2c.h>
#endif
@ -121,22 +130,19 @@ int bt848_card = -1;
int bt848_tuner = -1;
int bt848_reverse_mute = -1;
int bt848_format = -1;
int bt848_slow_msp_audio = -1;
SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt");
SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, "");
SYSCTL_INT(_hw_bt848, OID_AUTO, tuner, CTLFLAG_RW, &bt848_tuner, -1, "");
SYSCTL_INT(_hw_bt848, OID_AUTO, reverse_mute, CTLFLAG_RW, &bt848_reverse_mute, -1, "");
SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, "");
#if (__FreeBSD_version >= 300000)
typedef u_long ioctl_cmd_t;
SYSCTL_INT(_hw_bt848, OID_AUTO, slow_msp_audio, CTLFLAG_RW, &bt848_slow_msp_audio, -1, "");
#endif
#if (__FreeBSD__ == 2)
typedef int ioctl_cmd_t;
#define PCIR_REVID PCI_CLASS_REG
#endif
#endif /* __FreeBSD__ */
/****************/
@ -150,6 +156,21 @@ typedef int ioctl_cmd_t;
/* *** OpenBSD/NetBSD *** */
/**************************/
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/device.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcidevs.h>
static int bootverbose = 1;
#define BKTR_DEBUG
#ifdef BKTR_DEBUG
int bktr_debug = 0;
#define DPR(x) (bktr_debug ? printf x : 0)
#else
#define DPR(x)
#endif
#endif /* __NetBSD__ || __OpenBSD__ */
@ -247,7 +268,6 @@ bktr_probe( device_t dev )
static int
bktr_attach( device_t dev )
{
bt848_ptr_t bt848;
u_long latency;
u_long fun;
u_long val;
@ -282,14 +302,15 @@ bktr_attach( device_t dev )
error = ENXIO;
goto fail;
}
bktr->base = rman_get_virtual(bktr->res_mem); /* XXX use bus_space */
bktr->memt = rman_get_bustag(bktr->res_mem);
bktr->memh = rman_get_bushandle(bktr->res_mem);
/*
* Disable the brooktree device
*/
bt848 = bktr->base;
bt848->int_mask = ALL_INTS_DISABLED;
bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
#ifdef BROOKTREE_IRQ /* from the configuration file */
@ -341,7 +362,7 @@ bktr_attach( device_t dev )
/* XXX call bt848_i2c dependent attach() routine */
#if (NSMBUS > 0)
if (bt848_i2c_attach(unit, bktr->base, &bktr->i2c_sc))
if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc))
printf("bktr%d: i2c_attach: can't attach\n", unit);
#endif
@ -395,12 +416,10 @@ static int
bktr_detach( device_t dev )
{
struct bktr_softc *bktr = device_get_softc(dev);
bt848_ptr_t bt848;
/* Disable the brooktree device */
bt848 = bktr->base;
bt848->int_mask = ALL_INTS_DISABLED;
bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
/* FIXME - Free memory for RISC programs, grab buffer, vbi buffers */
@ -421,12 +440,10 @@ static int
bktr_shutdown( device_t dev )
{
struct bktr_softc *bktr = device_get_softc(dev);
bt848_ptr_t bt848;
/* Disable the brooktree device */
bt848 = bktr->base;
bt848->int_mask = ALL_INTS_DISABLED;
bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
return 0;
}
@ -513,10 +530,14 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p )
}
if (bt848_reverse_mute != -1) {
if (((bt848_reverse_mute >> 8) == unit ) &&
((bt848_reverse_mute & 0xff) < Bt848_MAX_TUNER) ) {
if ((bt848_reverse_mute >> 8) == unit ) {
bktr->reverse_mute = bt848_reverse_mute & 0xff;
bt848_reverse_mute = -1;
}
}
if (bt848_slow_msp_audio != -1) {
if ((bt848_slow_msp_audio >> 8) == unit ) {
bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff);
}
}
@ -806,10 +827,10 @@ static void
bktr_attach( pcici_t tag, int unit )
{
bktr_ptr_t bktr;
bt848_ptr_t bt848;
u_long latency;
u_long fun;
unsigned int rev;
unsigned long base;
#ifdef BROOKTREE_IRQ
u_long old_irq, new_irq;
#endif
@ -837,15 +858,18 @@ bktr_attach( pcici_t tag, int unit )
/*
* Map control/status registers
*/
pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &bktr->base,
pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &base,
&bktr->phys_base );
#if (__FreeBSD_version >= 300000)
bktr->memt = I386_BUS_SPACE_MEM; /* XXX should use proper bus space */
bktr->memh = (bus_space_handle_t)base; /* XXX functions here */
#endif
/*
* Disable the brooktree device
*/
bt848 = bktr->base;
bt848->int_mask = ALL_INTS_DISABLED;
bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
#ifdef BROOKTREE_IRQ /* from the configuration file */
old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
@ -881,7 +905,7 @@ bktr_attach( pcici_t tag, int unit )
/* XXX call bt848_i2c dependent attach() routine */
#if (NSMBUS > 0)
if (bt848_i2c_attach(unit, bktr->base, &bktr->i2c_sc))
if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc))
printf("bktr%d: i2c_attach: can't attach\n", unit);
#endif
@ -1005,13 +1029,16 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p )
}
if (bt848_reverse_mute != -1) {
if (((bt848_reverse_mute >> 8) == unit ) &&
((bt848_reverse_mute & 0xff) < Bt848_MAX_TUNER) ) {
if ((bt848_reverse_mute >> 8) == unit ) {
bktr->reverse_mute = bt848_reverse_mute & 0xff;
bt848_reverse_mute = -1;
}
}
if (bt848_slow_msp_audio != -1) {
if ((bt848_slow_msp_audio >> 8) == unit ) {
bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff);
}
}
switch ( FUNCTION( minor(dev) ) ) {
case VIDEO_DEV:
@ -1192,5 +1219,485 @@ int bktr_poll( dev_t dev, int events, struct proc *p)
/* *** OpenBSD / NetBSD *** */
/*****************************/
#if defined(__NetBSD__) || defined(__OpenBSD__)
#endif /* __NetBSD__ || __OpenBSD__ */
#define IPL_VIDEO IPL_BIO /* XXX */
static int bktr_intr(void *arg) { return common_bktr_intr(arg); }
#define bktr_open bktropen
#define bktr_close bktrclose
#define bktr_read bktrread
#define bktr_write bktrwrite
#define bktr_ioctl bktrioctl
#define bktr_mmap bktrmmap
int bktr_open __P((dev_t, int, int, struct proc *));
int bktr_close __P((dev_t, int, int, struct proc *));
int bktr_read __P((dev_t, struct uio *, int));
int bktr_write __P((dev_t, struct uio *, int));
int bktr_ioctl __P((dev_t, ioctl_cmd_t, caddr_t, int, struct proc*));
int bktr_mmap __P((dev_t, vm_offset_t, int));
vm_offset_t vm_page_alloc_contig(vm_offset_t, vm_offset_t,
vm_offset_t, vm_offset_t);
#if defined(__BROKEN_INDIRECT_CONFIG) || defined(__OpenBSD__)
static int bktr_probe __P((struct device *, void *, void *));
#else
static int bktr_probe __P((struct device *, struct cfdata *, void *));
#endif
static void bktr_attach __P((struct device *, struct device *, void *));
struct cfattach bktr_ca = {
sizeof(struct bktr_softc), bktr_probe, bktr_attach
};
#if defined(__NetBSD__)
extern struct cfdriver bktr_cd;
#else
struct cfdriver bktr_cd = {
NULL, "bktr", DV_DULL
};
#endif
int bktr_probe(parent, match, aux)
struct device *parent;
#if defined(__BROKEN_INDIRECT_CONFIG) || defined(__OpenBSD__)
void *match;
#else
struct cfdata *match;
#endif
void *aux;
{
struct pci_attach_args *pa = aux;
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROOKTREE &&
(PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT848 ||
PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT849 ||
PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT878 ||
PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT879))
return 1;
return 0;
}
/*
* the attach routine.
*/
static void
bktr_attach __P((struct device *parent, struct device *self, void *aux))
{
bktr_ptr_t bktr;
u_long latency;
u_long fun;
unsigned int rev;
#if defined(__OpenBSD__)
struct pci_attach_args *pa = aux;
pci_chipset_tag_t pc = pa->pa_pc;
pci_intr_handle_t ih;
const char *intrstr;
int retval;
int unit;
bktr = (bktr_ptr_t)self;
unit = bktr->bktr_dev.dv_unit;
bktr->pc = pa->pa_pc;
bktr->tag = pa->pa_tag;
bktr->dmat = pa->pa_dmat;
/*
* map memory
*/
bktr->memt = pa->pa_memt;
retval = pci_mem_find(pc, pa->pa_tag, PCI_MAPREG_START,
&bktr->phys_base, &bktr->obmemsz, NULL);
if (!retval)
retval = bus_space_map(pa->pa_memt, bktr->phys_base,
bktr->obmemsz, 0, &bktr->memh);
if (retval) {
printf(": couldn't map memory\n");
return;
}
/*
* map interrupt
*/
if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
pa->pa_intrline, &ih)) {
printf(": couldn't map interrupt\n");
return;
}
intrstr = pci_intr_string(pa->pa_pc, ih);
bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO,
bktr_intr, bktr, bktr->bktr_dev.dv_xname);
if (bktr->ih == NULL) {
printf(": couldn't establish interrupt");
if (intrstr != NULL)
printf(" at %s", intrstr);
printf("\n");
return;
}
if (intrstr != NULL)
printf(": %s\n", intrstr);
#endif /* __OpenBSD__ */
#if defined(__NetBSD__)
struct pci_attach_args *pa = aux;
pci_intr_handle_t ih;
const char *intrstr;
int retval;
int unit;
bktr = (bktr_ptr_t)self;
unit = bktr->bktr_dev.dv_unit;
bktr->dmat = pa->pa_dmat;
printf("\n");
/*
* map memory
*/
retval = pci_mapreg_map(pa, PCI_MAPREG_START,
PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
&bktr->memt, &bktr->memh, &bktr->phys_base,
&bktr->obmemsz);
DPR(("pci_mapreg_map: memt %x, memh %x, base %x, size %x\n",
bktr->memt, (u_int)bktr->memh,
(u_int)bktr->phys_base, (u_int)bktr->obmemsz));
if (retval) {
printf("%s: couldn't map memory\n", bktr->bktr_dev.dv_xname);
return;
}
/*
* Disable the brooktree device
*/
OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
/*
* map interrupt
*/
if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
pa->pa_intrline, &ih)) {
printf("%s: couldn't map interrupt\n", bktr->bktr_dev.dv_xname);
return;
}
intrstr = pci_intr_string(pa->pa_pc, ih);
bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO,
bktr_intr, bktr);
if (bktr->ih == NULL) {
printf("%s: couldn't establish interrupt",
bktr->bktr_dev.dv_xname);
if (intrstr != NULL)
printf(" at %s", intrstr);
printf("\n");
return;
}
if (intrstr != NULL)
printf("%s: interrupting at %s\n", bktr->bktr_dev.dv_xname,
intrstr);
#endif /* __NetBSD__ */
/*
* PCI latency timer. 32 is a good value for 4 bus mastering slots, if
* you have more than four, then 16 would probably be a better value.
*/
#ifndef BROOKTREE_DEF_LATENCY_VALUE
#define BROOKTREE_DEF_LATENCY_VALUE 10
#endif
latency = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_LATENCY_TIMER);
latency = (latency >> 8) & 0xff;
if ( !latency ) {
if ( bootverbose ) {
printf("%s: PCI bus latency was 0 changing to %d",
bktr->bktr_dev.dv_xname,
BROOKTREE_DEF_LATENCY_VALUE);
}
latency = BROOKTREE_DEF_LATENCY_VALUE;
pci_conf_write(pa->pa_pc, pa->pa_tag,
PCI_LATENCY_TIMER, latency<<8);
}
/* Enabled Bus Master and Memory Mapping */
fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, fun | 2);
fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, fun | 4);
/* read the pci id and determine the card type */
fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG);
rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0x000000ff;
common_bktr_attach( bktr, unit, fun, rev );
}
/*
* Special Memory Allocation
*/
vm_offset_t
get_bktr_mem(bktr, dmapp, size)
bktr_ptr_t bktr;
bus_dmamap_t *dmapp;
unsigned int size;
{
bus_dma_tag_t dmat = bktr->dmat;
bus_dma_segment_t seg;
bus_size_t align;
int rseg;
caddr_t kva;
/*
* Allocate a DMA area
*/
align = 1 << 24;
if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1,
&rseg, BUS_DMA_NOWAIT)) {
align = PAGE_SIZE;
if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1,
&rseg, BUS_DMA_NOWAIT)) {
printf("bktr%d: Unable to dmamem_alloc of %d bytes\n",
bktr->bktr_dev.dv_unit, size);
return 0;
}
}
if (bus_dmamem_map(dmat, &seg, rseg, size,
&kva, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
printf("bktr%d: Unable to dmamem_map of %d bytes\n",
bktr->bktr_dev.dv_unit, size);
bus_dmamem_free(dmat, &seg, rseg);
return 0;
}
#ifdef __OpenBSD__
bktr->dm_mapsize = size;
#endif
/*
* Create and locd the DMA map for the DMA area
*/
if (bus_dmamap_create(dmat, size, 1, size, 0, BUS_DMA_NOWAIT, dmapp)) {
printf("bktr%d: Unable to dmamap_create of %d bytes\n",
bktr->bktr_dev.dv_unit, size);
bus_dmamem_unmap(dmat, kva, size);
bus_dmamem_free(dmat, &seg, rseg);
return 0;
}
if (bus_dmamap_load(dmat, *dmapp, kva, size, NULL, BUS_DMA_NOWAIT)) {
printf("bktr%d: Unable to dmamap_load of %d bytes\n",
bktr->bktr_dev.dv_unit, size);
bus_dmamem_unmap(dmat, kva, size);
bus_dmamem_free(dmat, &seg, rseg);
bus_dmamap_destroy(dmat, *dmapp);
return 0;
}
return (vm_offset_t)kva;
}
void
free_bktr_mem(bktr, dmap, kva)
bktr_ptr_t bktr;
bus_dmamap_t dmap;
vm_offset_t kva;
{
bus_dma_tag_t dmat = bktr->dmat;
#ifdef __NetBSD__
bus_dmamem_unmap(dmat, (caddr_t)kva, dmap->dm_mapsize);
#else
bus_dmamem_unmap(dmat, (caddr_t)kva, bktr->dm_mapsize);
#endif
bus_dmamem_free(dmat, dmap->dm_segs, 1);
bus_dmamap_destroy(dmat, dmap);
}
/*---------------------------------------------------------
**
** BrookTree 848 character device driver routines
**
**---------------------------------------------------------
*/
#define VIDEO_DEV 0x00
#define TUNER_DEV 0x01
#define VBI_DEV 0x02
#define UNIT(x) ((x) & 0x0f)
#define FUNCTION(x) ((x >> 4) & 0x0f)
/*
*
*/
int
bktr_open( dev_t dev, int flags, int fmt, struct proc *p )
{
bktr_ptr_t bktr;
int unit;
unit = UNIT( minor(dev) );
/* unit out of range */
if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL))
return( ENXIO );
bktr = bktr_cd.cd_devs[unit];
if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
return( ENXIO );
switch ( FUNCTION( minor(dev) ) ) {
case VIDEO_DEV:
return( video_open( bktr ) );
case TUNER_DEV:
return( tuner_open( bktr ) );
case VBI_DEV:
return( vbi_open( bktr ) );
}
return( ENXIO );
}
/*
*
*/
int
bktr_close( dev_t dev, int flags, int fmt, struct proc *p )
{
bktr_ptr_t bktr;
int unit;
unit = UNIT( minor(dev) );
/* unit out of range */
if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL))
return( ENXIO );
bktr = bktr_cd.cd_devs[unit];
switch ( FUNCTION( minor(dev) ) ) {
case VIDEO_DEV:
return( video_close( bktr ) );
case TUNER_DEV:
return( tuner_close( bktr ) );
case VBI_DEV:
return( vbi_close( bktr ) );
}
return( ENXIO );
}
/*
*
*/
int
bktr_read( dev_t dev, struct uio *uio, int ioflag )
{
bktr_ptr_t bktr;
int unit;
unit = UNIT(minor(dev));
/* unit out of range */
if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL))
return( ENXIO );
bktr = bktr_cd.cd_devs[unit];
switch ( FUNCTION( minor(dev) ) ) {
case VIDEO_DEV:
return( video_read( bktr, unit, dev, uio ) );
case VBI_DEV:
return( vbi_read( bktr, uio, ioflag ) );
}
return( ENXIO );
}
/*
*
*/
int
bktr_write( dev_t dev, struct uio *uio, int ioflag )
{
/* operation not supported */
return( EOPNOTSUPP );
}
/*
*
*/
int
bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct proc* pr )
{
bktr_ptr_t bktr;
int unit;
unit = UNIT(minor(dev));
/* unit out of range */
if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL))
return( ENXIO );
bktr = bktr_cd.cd_devs[unit];
if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
return( ENOMEM );
switch ( FUNCTION( minor(dev) ) ) {
case VIDEO_DEV:
return( video_ioctl( bktr, unit, cmd, arg, pr ) );
case TUNER_DEV:
return( tuner_ioctl( bktr, unit, cmd, arg, pr ) );
}
return( ENXIO );
}
/*
*
*/
int
bktr_mmap( dev_t dev, vm_offset_t offset, int nprot )
{
int unit;
bktr_ptr_t bktr;
unit = UNIT(minor(dev));
/* unit out of range */
if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL))
return( -1 );
if (FUNCTION(minor(dev)) > 0)
return( -1 );
bktr = bktr_cd.cd_devs[unit];
if (offset < 0)
return( -1 );
if (offset >= bktr->alloc_pages * PAGE_SIZE)
return( -1 );
#ifdef __NetBSD__
return (bus_dmamem_mmap(bktr->dmat, bktr->dm_mem->dm_segs, 1,
offset, nprot, BUS_DMA_WAITOK));
#else
return( i386_btop(vtophys(bktr->bigbuf) + offset) );
#endif
}
#endif /* __NetBSD__ || __OpenBSD__ */

View File

@ -35,12 +35,20 @@
*/
#ifdef __FreeBSD__
#if (__FreeBSD_version >= 310000)
#include <sys/bus.h>
#include "smbus.h"
# if (__FreeBSD_version >= 310000)
# include <sys/bus.h>
# include "smbus.h"
# else
# define NSMBUS 0 /* FreeBSD before 3.1 does not have SMBUS */
# endif
#else
#define NSMBUS 0
# define NSMBUS 0 /* Non FreeBSD systems do not have SMBUS */
#endif
#ifdef __NetBSD__
#include <machine/bus.h> /* struct device */
#include <sys/device.h>
#include <sys/select.h> /* struct selinfo */
#endif
#ifndef PCI_LATENCY_TIMER
@ -172,7 +180,7 @@ struct bt848_registers {
#define BT848_O_CONTROL_CON_MSB (1<<2)
#define BT848_O_CONTROL_SAT_U_MSB (1<<1)
#define BT848_O_CONTROL_SAT_V_MSB (1<<0)
u_char fillter1[16];
u_char fillter4[16];
BTBYTE (o_scloop); /* c0, c1,c2,c3 */
#define BT848_O_SCLOOP_RSVD1 (1<<7)
#define BT848_O_SCLOOP_CAGC (1<<6)
@ -197,6 +205,10 @@ struct bt848_registers {
bregister_t color_ctl_rgb_ded :1;
bregister_t color_ctl_color_bars :1;
bregister_t color_ctl_ext_frmrate :1;
#define BT848_COLOR_CTL_GAMMA (1<<4)
#define BT848_COLOR_CTL_RGB_DED (1<<5)
#define BT848_COLOR_CTL_COLOR_BARS (1<<6)
#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7)
int :24; /* d9,da,db */
BTBYTE (cap_ctl); /* dc, dd,de,df */
#define BT848_CAP_CTL_DITH_FRAME (1<<4)
@ -270,17 +282,12 @@ struct bt848_registers {
BTLONG (gpio_data); /* 200, 201,202,203 */ /* really 24 bits */
};
typedef volatile struct bt848_registers* bt848_ptr_t;
#if 0
/* force people to be aware of the new struct */
#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_CROP 0x00C
#define BKTR_O_CROP 0x08C
#define BKTR_E_VDELAY_LO 0x010
#define BKTR_O_VDELAY_LO 0x090
#define BKTR_E_VACTIVE_LO 0x014
@ -327,9 +334,11 @@ typedef volatile struct bt848_registers* bt848_ptr_t;
#define BKTR_GPIO_OUT_EN 0x118
#define BKTR_GPIO_REG_INP 0x11C
#define BKTR_GPIO_DATA 0x200
#define BKTR_I2C_CONTROL 0x110
#endif /* 0 */
#define BKTR_I2C_DATA_CTL 0x110
#define BKTR_TGCTRL 0x084
#define BKTR_PLL_F_LO 0x0F0
#define BKTR_PLL_F_HI 0x0F4
#define BKTR_PLL_F_XCI 0x0F8
/*
* device support for onboard tv tuners
@ -400,6 +409,31 @@ struct bktr_i2c_softc {
};
#endif
/* Bt848/878 register access
* The registers can either be access via a memory mapped structure
* or accessed via bus_space.
* bus_0pace access allows cross platform support, where as the
* memory mapped structure method only works on 32 bit processors
* with the right type of endianness.
*/
#if defined(__NetBSD__) || ( defined(__FreeBSD__) && (__FreeBSD_version >=300000) )
#define INB(bktr,offset) bus_space_read_1((bktr)->memt,(bktr)->memh,(offset))
#define INW(bktr,offset) bus_space_read_2((bktr)->memt,(bktr)->memh,(offset))
#define INL(bktr,offset) bus_space_read_4((bktr)->memt,(bktr)->memh,(offset))
#define OUTB(bktr,offset,value) bus_space_write_1((bktr)->memt,(bktr)->memh,(offset),(value))
#define OUTW(bktr,offset,value) bus_space_write_2((bktr)->memt,(bktr)->memh,(offset),(value))
#define OUTL(bktr,offset,value) bus_space_write_4((bktr)->memt,(bktr)->memh,(offset),(value))
#else
#define INB(bktr,offset) *(volatile unsigned char*) ((int)((bktr)->memh)+(offset))
#define INW(bktr,offset) *(volatile unsigned short*)((int)((bktr)->memh)+(offset))
#define INL(bktr,offset) *(volatile unsigned int*) ((int)((bktr)->memh)+(offset))
#define OUTB(bktr,offset,value) *(volatile unsigned char*) ((int)((bktr)->memh)+(offset)) = (value)
#define OUTW(bktr,offset,value) *(volatile unsigned short*)((int)((bktr)->memh)+(offset)) = (value)
#define OUTL(bktr,offset,value) *(volatile unsigned int*) ((int)((bktr)->memh)+(offset)) = (value)
#endif
typedef struct bktr_clip bktr_clip_t;
/*
@ -468,13 +502,17 @@ struct bktr_softc {
struct resource *res_irq; /* 4.x resource descriptor for interrupt */
void *res_ih; /* 4.x newbus interrupt handler cookie */
#endif
#if (__FreeBSD_version >= 310000)
bus_space_tag_t memt; /* Bus space register access functions */
bus_space_handle_t memh; /* Bus space register access functions */
bus_size_t obmemsz;/* Size of card (bytes) */
#endif
#if (NSMBUS > 0)
struct bktr_i2c_softc i2c_sc; /* bt848_i2c device */
#endif
#endif
/* the following definitions are common over all platforms */
bt848_ptr_t base; /* Bt848 register physical address */
vm_offset_t bigbuf; /* buffer that holds the captured image */
int alloc_pages; /* number of pages in bigbuf */
@ -585,7 +623,7 @@ struct bktr_softc {
int yclip2;
int max_clip_node;
bktr_clip_t clip_list[100];
int reverse_mute;
int reverse_mute; /* Swap the GPIO values for Mute and TV Audio */
int bt848_tuner;
int bt848_card;
u_long id;
@ -598,6 +636,8 @@ struct bktr_softc {
int msp_addr; /* MSP i2c address */
char dpl_version_string[9]; /* DPL version string 35xxx-xx */
int dpl_addr; /* DPL i2c address */
int slow_msp_audio; /* 0 = use fast MSP3410/3415 programming sequence */
/* 1 = use slow MSP3410/3415 programming sequence */
};
@ -611,3 +651,24 @@ struct bt848_card_sig {
int tuner;
u_char signature[Bt848_MAX_SIGN];
};
/***********************************************************/
/* ioctl_cmd_t int on old versions, u_long on new versions */
/***********************************************************/
#if (__FreeBSD__ == 2)
typedef int ioctl_cmd_t;
#endif
#if defined(__FreeBSD__)
#if (__FreeBSD_version >= 300000)
typedef u_long ioctl_cmd_t;
#endif
#endif
#if defined(__NetBSD__) || defined(__OpenBSD__)
typedef u_long ioctl_cmd_t;
#endif

View File

@ -49,13 +49,28 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
#ifdef __NetBSD__
#include <sys/proc.h>
#endif
#ifdef __FreeBSD__
#include <machine/clock.h> /* for DELAY */
#include <pci/pcivar.h>
#endif
#include <machine/ioctl_meteor.h>
#if (__FreeBSD_version >=300000)
#include <machine/bus_memio.h> /* for bus space */
#include <machine/bus.h>
#include <sys/bus.h>
#endif
#ifdef __NetBSD__
#include <dev/ic/ioctl_meteor.h> /* NetBSD .h file location */
#include <dev/ic/ioctl_bt848.h>
#else
#include <machine/ioctl_meteor.h> /* Traditional .h file location */
#include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
#endif
#include <dev/bktr/bktr_reg.h>
#include <dev/bktr/bktr_tuner.h>
#include <dev/bktr/bktr_card.h>
@ -317,7 +332,8 @@ static int nabcst[] = {
*/
#define OFFSET 6.00
static int irccable[] = {
99, (int)( 45.75 * FREQFACTOR), 0,
116, (int)( 45.75 * FREQFACTOR), 0,
100, (int)(649.25 * FREQFACTOR), (int)(OFFSET * 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),
@ -342,7 +358,8 @@ static int irccable[] = {
*/
#define OFFSET 6.00
static int hrccable[] = {
99, (int)( 45.75 * FREQFACTOR), 0,
116, (int)( 45.75 * FREQFACTOR), 0,
100, (int)(648.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
95, (int)( 90.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
23, (int)(216.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
14, (int)(120.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),