From a35cc233ff737682baf5b8ab84f699ac61fc9281 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Sat, 15 May 2004 17:54:13 +0000 Subject: [PATCH] Update bktr(4) to FreeBSD current's version. This most importantly includes a new msp driver based on the Linux Brooktree driver. Add support for Terratec TValue submitted by Patrick Mauritz . The ioctl headers are moved into the MI dev/ tree, symlinks for compatibiliy are added in a separate commit. --- sys/conf/files | 9 +- sys/conf/options | 7 +- sys/config/LINT | 8 +- sys/dev/video/bktr/CHANGELOG.TXT | 4 +- sys/dev/video/bktr/bktr_audio.c | 80 +- sys/dev/video/bktr/bktr_audio.h | 14 +- sys/dev/video/bktr/bktr_card.c | 113 +- sys/dev/video/bktr/bktr_card.h | 10 +- sys/dev/video/bktr/bktr_core.c | 356 ++--- sys/dev/video/bktr/bktr_core.h | 8 +- sys/dev/video/bktr/bktr_i2c.c | 330 ++--- sys/dev/video/bktr/bktr_i2c.h | 24 +- sys/dev/video/bktr/bktr_mem.c | 20 +- sys/dev/video/bktr/bktr_mem.h | 5 +- sys/dev/video/bktr/bktr_os.c | 1218 ++-------------- sys/dev/video/bktr/bktr_os.h | 23 +- sys/dev/video/bktr/bktr_reg.h | 142 +- sys/dev/video/bktr/bktr_tuner.c | 55 +- sys/dev/video/bktr/bktr_tuner.h | 4 +- .../include => dev/video/bktr}/ioctl_bt848.h | 11 +- sys/dev/video/bktr/msp34xx.c | 1259 +++++++++++++++++ .../video/meteor}/ioctl_meteor.h | 11 +- sys/dev/video/meteor/meteor.c | 6 +- sys/i386/conf/LINT | 8 +- sys/platform/pc32/include/ioctl_bt848.h | 299 ---- sys/platform/pc32/include/ioctl_meteor.h | 188 --- 26 files changed, 1848 insertions(+), 2364 deletions(-) rename sys/{i386/include => dev/video/bktr}/ioctl_bt848.h (97%) create mode 100644 sys/dev/video/bktr/msp34xx.c rename sys/{i386/include => dev/video/meteor}/ioctl_meteor.h (96%) delete mode 100644 sys/platform/pc32/include/ioctl_bt848.h delete mode 100644 sys/platform/pc32/include/ioctl_meteor.h diff --git a/sys/conf/files b/sys/conf/files index a4ce98f85c..e2e6f3f863 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,5 +1,5 @@ # $FreeBSD: src/sys/conf/files,v 1.340.2.137 2003/06/04 17:10:30 sam Exp $ -# $DragonFly: src/sys/conf/files,v 1.60 2004/04/17 03:57:22 drhodus Exp $ +# $DragonFly: src/sys/conf/files,v 1.61 2004/05/15 17:54:12 joerg Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -1088,12 +1088,13 @@ dev/netif/awi/awi.c optional awi dev/netif/awi/awi_wep.c optional awi dev/netif/awi/awi_wicfg.c optional awi dev/netif/awi/if_awi_pccard.c optional awi pccard +dev/video/bktr/bktr_audio.c optional bktr pci +dev/video/bktr/bktr_card.c optional bktr pci dev/video/bktr/bktr_core.c optional bktr pci dev/video/bktr/bktr_i2c.c optional bktr pci smbus -dev/video/bktr/bktr_card.c optional bktr pci -dev/video/bktr/bktr_tuner.c optional bktr pci -dev/video/bktr/bktr_audio.c optional bktr pci dev/video/bktr/bktr_os.c optional bktr pci +dev/video/bktr/bktr_tuner.c optional bktr pci +dev/video/bktr/msp34xx.c optional bktr pci dev/serial/cy/cy_pci.c optional cy pci dev/netif/dc/if_dc.c optional dc dev/netif/de/if_de.c optional de diff --git a/sys/conf/options b/sys/conf/options index 0d242bd4f5..9511bcdee0 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -1,5 +1,5 @@ # $FreeBSD: src/sys/conf/options,v 1.191.2.53 2003/06/04 17:56:58 sam Exp $ -# $DragonFly: src/sys/conf/options,v 1.19 2004/04/17 03:57:22 drhodus Exp $ +# $DragonFly: src/sys/conf/options,v 1.20 2004/05/15 17:54:12 joerg Exp $ # # On the handling of kernel options # @@ -446,10 +446,6 @@ NFS_NOSERVER opt_nfs.h NFS_DEBUG opt_nfs.h # For the Bt848/Bt848A/Bt849/Bt878/Bt879 driver -OVERRIDE_CARD opt_bktr.h -OVERRIDE_TUNER opt_bktr.h -OVERRIDE_DBX opt_bktr.h -OVERRIDE_MSP opt_bktr.h BROOKTREE_SYSTEM_DEFAULT opt_bktr.h BROOKTREE_ALLOC_PAGES opt_bktr.h BKTR_OVERRIDE_CARD opt_bktr.h @@ -463,6 +459,7 @@ BKTR_GPIO_ACCESS opt_bktr.h BKTR_NO_MSP_RESET opt_bktr.h BKTR_430_FX_MODE opt_bktr.h BKTR_SIS_VIA_MODE opt_bktr.h +BKTR_NEW_MSP34XX_DRIVER opt_bktr.h # meteor opt_meteor.h METEOR_ALLOC_PAGES opt_meteor.h diff --git a/sys/config/LINT b/sys/config/LINT index bfcd227894..14b4e4bee4 100644 --- a/sys/config/LINT +++ b/sys/config/LINT @@ -3,7 +3,7 @@ # as much of the source tree as it can. # # $FreeBSD: src/sys/i386/conf/LINT,v 1.749.2.144 2003/06/04 17:56:59 sam Exp $ -# $DragonFly: src/sys/config/LINT,v 1.28 2004/04/29 12:11:16 joerg Exp $ +# $DragonFly: src/sys/config/LINT,v 1.29 2004/05/15 17:54:13 joerg Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -1962,6 +1962,11 @@ options AHD_REG_PRETTY_PRINT # motherboards and motherboards with bad or incomplete PCI 2.1 support. # As a rough guess, old = before 1998 # +# options BKTR_NEW_MSP34XX_DRIVER +# Use new, more complete initialization scheme for the msp34* soundchip. +# Should fix stereo autodetection if the old driver does only output +# mono sound. +# # # The oltr driver supports the following Olicom PCI token-ring adapters # OC-3136, OC-3137, OC-3139, OC-3140, OC-3141, OC-3540, OC-3250 @@ -2051,6 +2056,7 @@ device meteor # I2C slaves connected to the external connector of some cards. # device bktr +options BKTR_NEW_MSP34XX_DRIVER # # PCCARD/PCMCIA diff --git a/sys/dev/video/bktr/CHANGELOG.TXT b/sys/dev/video/bktr/CHANGELOG.TXT index 321b007400..b1e991d3b5 100644 --- a/sys/dev/video/bktr/CHANGELOG.TXT +++ b/sys/dev/video/bktr/CHANGELOG.TXT @@ -1,5 +1,5 @@ -/* $FreeBSD: src/sys/dev/bktr/CHANGELOG.TXT,v 1.8.2.4 2000/11/01 09:36:14 roger Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/CHANGELOG.TXT,v 1.3 2004/01/08 18:39:17 asmodai Exp $ */ +/* $FreeBSD: src/sys/dev/bktr/CHANGELOG.TXT,v 1.19 2002/05/16 22:43:18 eric Exp $ */ +/* $DragonFly: src/sys/dev/video/bktr/CHANGELOG.TXT,v 1.4 2004/05/15 17:54:12 joerg Exp $ */ /* * MAINTAINER = Roger Hardiman */ diff --git a/sys/dev/video/bktr/bktr_audio.c b/sys/dev/video/bktr/bktr_audio.c index 03870428bd..96c5cd0ab6 100644 --- a/sys/dev/video/bktr/bktr_audio.c +++ b/sys/dev/video/bktr/bktr_audio.c @@ -1,19 +1,3 @@ -/* $FreeBSD: src/sys/dev/bktr/bktr_audio.c,v 1.2.2.5 2003/02/08 02:04:57 orion Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_audio.c,v 1.5 2004/02/13 01:45:15 joerg Exp $ */ -/* - * This is part of the Driver for Video Capture Cards (Frame grabbers) - * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 - * chipset. - * Copyright Roger Hardiman and Amancio Hasty. - * - * bktr_audio : This deals with controlling the audio on TV cards, - * controlling the Audio Multiplexer (audio source selector). - * controlling any MSP34xx stereo audio decoders. - * controlling any DPL35xx dolby surroud sound audio decoders. - * initialising TDA98xx audio devices. - * - */ - /* * 1. Redistributions of source code must retain the * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman @@ -45,45 +29,43 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/dev/bktr/bktr_audio.c,v 1.13 2003/12/08 07:59:18 obrien Exp $ + * $DragonFly: src/sys/dev/video/bktr/bktr_audio.c,v 1.6 2004/05/15 17:54:12 joerg Exp $ */ +/* + * This is part of the Driver for Video Capture Cards (Frame grabbers) + * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 + * chipset. + * Copyright Roger Hardiman and Amancio Hasty. + * + * bktr_audio : This deals with controlling the audio on TV cards, + * controlling the Audio Multiplexer (audio source selector). + * controlling any MSP34xx stereo audio decoders. + * controlling any DPL35xx dolby surroud sound audio decoders. + * initialising TDA98xx audio devices. + * + */ + +#include "opt_bktr.h" /* Include any kernel config options */ + #include #include #include #include -#if defined(__DragonFly__) || defined(__FreeBSD__) - -#if defined(__DragonFly__) || (__FreeBSD_version < 500000) -#include /* for DELAY */ -#endif - #include - -#if defined(__DragonFly__) || (__FreeBSD_version >=300000) #include /* for bus space */ #include #include -#endif -#endif - -#ifdef __NetBSD__ -#include -#include /* NetBSD location of .h files */ -#include -#include -#include -#include -#include -#else -#include /* Traditional location of .h files */ -#include /* extensions to ioctl_meteor.h */ -#include "bktr_reg.h" -#include "bktr_core.h" -#include "bktr_tuner.h" -#include "bktr_card.h" -#include "bktr_audio.h" -#endif +#include +#include /* extensions to ioctl_meteor.h */ +#include +#include +#include +#include +#include /* * Prototypes for the GV_BCTV2 specific functions. @@ -473,6 +455,13 @@ void msp_read_id( bktr_ptr_t bktr ){ * the chip and re-programs it if needed. */ void msp_autodetect( bktr_ptr_t bktr ) { + +#ifdef BKTR_NEW_MSP34XX_DRIVER + + /* Just wake up the (maybe) sleeping thread, it'll do everything for us */ + msp_wake_thread(bktr); + +#else int auto_detect, loops; int stereo; @@ -597,6 +586,8 @@ void msp_autodetect( bktr_ptr_t bktr ) { /* 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); */ + +#endif /* BKTR_NEW_MSP34XX_DRIVER */ } /* Read the DPL version string */ @@ -629,4 +620,3 @@ void dpl_autodetect( bktr_ptr_t bktr ) { recommended with PANORAMA mode in 0x0040 set to panorama */ } - diff --git a/sys/dev/video/bktr/bktr_audio.h b/sys/dev/video/bktr/bktr_audio.h index b6f96f2da5..d0e5da51fb 100644 --- a/sys/dev/video/bktr/bktr_audio.h +++ b/sys/dev/video/bktr/bktr_audio.h @@ -1,6 +1,5 @@ -/* $FreeBSD: src/sys/dev/bktr/bktr_audio.h,v 1.2 1999/10/28 13:58:14 roger Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_audio.h,v 1.2 2003/06/17 04:28:23 dillon Exp $ */ - +/* $FreeBSD: src/sys/dev/bktr/bktr_audio.h,v 1.3 2003/08/12 09:45:34 alex Exp $ */ +/* $DragonFly: src/sys/dev/video/bktr/bktr_audio.h,v 1.3 2004/05/15 17:54:12 joerg Exp $ */ /* * This is part of the Driver for Video Capture Cards (Frame grabbers) * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 @@ -66,6 +65,12 @@ void init_audio_devices( bktr_ptr_t bktr ); */ void msp_autodetect( bktr_ptr_t bktr ); void msp_read_id( bktr_ptr_t bktr ); +#ifdef BKTR_NEW_MSP34XX_DRIVER +int msp_attach(bktr_ptr_t bktr); +int msp_detach(bktr_ptr_t bktr); +void msp_wake_thread(bktr_ptr_t bktr); +void msp_halt_thread(bktr_ptr_t bktr); +#endif /* @@ -80,6 +85,3 @@ void dpl_read_id( bktr_ptr_t bktr ); */ void init_BTSC( bktr_ptr_t bktr ); int set_BTSC( bktr_ptr_t bktr, int control ); - - - diff --git a/sys/dev/video/bktr/bktr_card.c b/sys/dev/video/bktr/bktr_card.c index cc8e82a875..ee2744c86d 100644 --- a/sys/dev/video/bktr/bktr_card.c +++ b/sys/dev/video/bktr/bktr_card.c @@ -1,20 +1,3 @@ -/* $FreeBSD: src/sys/dev/bktr/bktr_card.c,v 1.9.2.5 2003/02/08 02:04:57 orion Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_card.c,v 1.5 2004/04/05 05:34:36 dillon Exp $ */ - -/* - * This is part of the Driver for Video Capture Cards (Frame grabbers) - * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 - * chipset. - * Copyright Roger Hardiman and Amancio Hasty. - * - * bktr_card : This deals with identifying TV cards. - * trying to find the card make and model of card. - * trying to find the type of tuner fitted. - * reading the configuration EEPROM. - * locating i2c devices. - * - */ - /* * 1. Redistributions of source code must retain the * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman @@ -46,6 +29,22 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/dev/bktr/bktr_card.c,v 1.23 2003/12/08 07:59:18 obrien Exp $ + * $DragonFly: src/sys/dev/video/bktr/bktr_card.c,v 1.6 2004/05/15 17:54:12 joerg Exp $ + */ + +/* + * This is part of the Driver for Video Capture Cards (Frame grabbers) + * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 + * chipset. + * Copyright Roger Hardiman and Amancio Hasty. + * + * bktr_card : This deals with identifying TV cards. + * trying to find the card make and model of card. + * trying to find the type of tuner fitted. + * reading the configuration EEPROM. + * locating i2c devices. */ #include "opt_bktr.h" /* Include any kernel config options */ @@ -54,43 +53,21 @@ #include #include -#if defined(__DragonFly__) || defined(__FreeBSD__) - -#if defined(__DragonFly__) || (__FreeBSD_version < 500000) -#include /* for DELAY */ -#endif - #include - -#if defined(__DragonFly__) || (__FreeBSD_version >=300000) #include /* for bus space */ #include #include -#endif -#endif -#ifdef __NetBSD__ -#include /* NetBSD location for .h files */ -#include -#include -#include -#include -#include -#else -#include /* Traditional location for .h files */ -#include /* extensions to ioctl_meteor.h */ -#include "bktr_reg.h" -#include "bktr_core.h" -#include "bktr_tuner.h" -#include "bktr_card.h" -#include "bktr_audio.h" -#endif +#include +#include /* extensions to ioctl_meteor.h */ +#include +#include +#include +#include +#include -/* Include the PCI Vendor definitions */ -#ifdef __NetBSD__ -#include -#include -#endif +#include +#include /* Various defines */ #define HAUP_REMOTE_INT_WADDR 0x30 @@ -356,6 +333,19 @@ static const struct CARDTYPE cards[] = { { 0x10000, 0, 0x10000, 0, 1 }, /* audio MUX values */ 0x10f00 }, /* GPIO mask */ + { CARD_TERRATEC_TVALUE, /* the card id */ + "Terratec TerraTValue Bt878", /* the 'name' */ + NULL, /* the tuner */ + 0, /* the tuner i2c address */ + 0, /* dbx is optional */ + 0, + 0, + 0, /* EEProm type */ + 0, /* EEProm size */ + /* Tuner, Extern, Intern, Mute, Enabled */ + { 0x500, 0, 0x300, 0x900, 0x900 }, /* audio MUX values */ + 0x10f00 }, /* GPIO mask */ + }; struct bt848_card_sig bt848_card_signature[1]= { @@ -542,12 +532,7 @@ static int locate_eeprom_address( bktr_ptr_t bktr) { * configuration EEPROM used on Bt878/879 cards. They should match the * number assigned to the company by the PCI Special Interest Group */ -#ifndef __NetBSD__ -#define PCI_VENDOR_HAUPPAUGE 0x0070 -#define PCI_VENDOR_AVERMEDIA 0x1461 -#define PCI_VENDOR_STB 0x10B4 -#define PCI_VENDOR_ASKEY 0x144F -#endif + /* Following not confirmed with http://members.hyperlink.net.au/~chart, so not added to NetBSD's pcidevs */ #define PCI_VENDOR_LEADTEK_ALT 0x6606 @@ -678,10 +663,9 @@ probeCard( bktr_ptr_t bktr, int verbose, int unit ) goto checkTuner; } - if (subsystem_vendor_id == PCI_VENDOR_LEADTEK_ALT || - subsystem_vendor_id == PCI_VENDOR_LEADTEK_ALT_2 || - subsystem_vendor_id == PCI_VENDOR_LEADTEK_ALT_3 - ) { + if ((subsystem_vendor_id == PCI_VENDOR_LEADTEK_ALT) + || (subsystem_vendor_id == PCI_VENDOR_LEADTEK_ALT_2) + || (subsystem_vendor_id == PCI_VENDOR_LEADTEK_ALT_3)) { bktr->card = cards[ (card = CARD_LEADTEK) ]; bktr->card.eepromAddr = eeprom_i2c_address; bktr->card.eepromSize = (u_char)(256 / EEPROMBLOCKSIZE); @@ -703,6 +687,14 @@ probeCard( bktr_ptr_t bktr, int verbose, int unit ) goto checkTuner; } + if (subsystem_vendor_id == PCI_VENDOR_TERRATEC && + subsystem_id == 0x1118) { + bktr->card = cards[ (card = CARD_TERRATEC_TVALUE) ]; + bktr->card.eepromAddr = eeprom_i2c_address; + bktr->card.eepromSize = (u_char)(256 / EEPROMBLOCKSIZE); + goto checkTuner; + } + /* Vendor is unknown. We will use the standard probe code */ /* which may not give best results */ printf("%s: Warning - card vendor 0x%04x (model 0x%04x) unknown.\n", @@ -1120,6 +1112,11 @@ checkTuner: goto checkDBX; break; + case CARD_TERRATEC_TVALUE: + select_tuner( bktr, PHILIPS_PAL ); + goto checkDBX; + break; + } /* end switch(card) */ diff --git a/sys/dev/video/bktr/bktr_card.h b/sys/dev/video/bktr/bktr_card.h index ec509a8fde..e86e191d6c 100644 --- a/sys/dev/video/bktr/bktr_card.h +++ b/sys/dev/video/bktr/bktr_card.h @@ -1,5 +1,5 @@ -/* $FreeBSD: src/sys/dev/bktr/bktr_card.h,v 1.2.4.3 2003/02/08 02:04:57 orion Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_card.h,v 1.2 2003/06/17 04:28:23 dillon Exp $ */ +/* $FreeBSD: src/sys/dev/bktr/bktr_card.h,v 1.6 2003/02/02 17:46:00 orion Exp $ */ +/* $DragonFly: src/sys/dev/video/bktr/bktr_card.h,v 1.3 2004/05/15 17:54:12 joerg Exp $ */ /* * This is part of the Driver for Video Capture Cards (Frame grabbers) @@ -55,7 +55,7 @@ * eg options BKTR_OVERRIDE CARD=1 * * or using the sysclt hw.bt848.card - * eg sysctl -w hw.bt848.card=1 + * eg sysctl hw.bt848.card=1 * * where is one of the following card defines. */ @@ -78,7 +78,8 @@ #define CARD_LEADTEK 15 #define CARD_TERRATVPLUS 16 #define CARD_IO_BCTV3 17 -#define Bt848_MAX_CARD 18 +#define CARD_TERRATEC_TVALUE 18 +#define Bt848_MAX_CARD 19 #define CARD_IO_GV CARD_IO_BCTV2 @@ -87,4 +88,3 @@ void probeCard( bktr_ptr_t bktr, int verbose, int unit); int writeEEProm( bktr_ptr_t bktr, int offset, int count, u_char *data ); int readEEProm( bktr_ptr_t bktr, int offset, int count, u_char *data ); - diff --git a/sys/dev/video/bktr/bktr_core.c b/sys/dev/video/bktr/bktr_core.c index b6907a9c43..3841501000 100644 --- a/sys/dev/video/bktr/bktr_core.c +++ b/sys/dev/video/bktr/bktr_core.c @@ -1,32 +1,3 @@ -/* $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.103.2.4 2000/11/01 09:36:14 roger Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_core.c,v 1.12 2004/04/12 00:50:40 dillon Exp $ */ - -/* - * This is part of the Driver for Video Capture Cards (Frame grabbers) - * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 - * chipset. - * Copyright Roger Hardiman and Amancio Hasty. - * - * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber, - * Handles all the open, close, ioctl and read userland calls. - * Sets the Bt848 registers and generates RISC pograms. - * Controls the i2c bus and GPIO interface. - * Contains the interface to the kernel. - * (eg probe/attach and open/close/ioctl) - * - */ - - /* - The Brooktree BT848 Driver driver is based upon Mark Tinguely and - Jim Lowe's driver for the Matrox Meteor PCI card . The - Philips SAA 7116 and SAA 7196 are very different chipsets than - the BT848. - - The original copyright notice by Mark and Jim is included mostly - to honor their fantastic work in the Matrox Meteor driver! - - */ - /* * 1. Redistributions of source code must retain the * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman @@ -59,11 +30,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ - - - - -/* +/*- * 1. Redistributions of source code must retain the * Copyright (c) 1995 Mark Tinguely and Jim Lowe * All rights reserved. @@ -93,30 +60,42 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.133 2003/12/08 07:59:18 obrien Exp $ + * $DragonFly: src/sys/dev/video/bktr/bktr_core.c,v 1.13 2004/05/15 17:54:12 joerg Exp $ */ -#include "opt_bktr.h" /* Include any kernel config options */ - -#if defined(__DragonFly__) || defined(__FreeBSD__) -#include "use_bktr.h" -#endif /* __FreeBSD__ */ +/* + * This is part of the Driver for Video Capture Cards (Frame grabbers) + * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 + * chipset. + * Copyright Roger Hardiman and Amancio Hasty. + * + * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber, + * Handles all the open, close, ioctl and read userland calls. + * Sets the Bt848 registers and generates RISC pograms. + * Controls the i2c bus and GPIO interface. + * Contains the interface to the kernel. + * (eg probe/attach and open/close/ioctl) + */ -#if ( \ - (defined(__DragonFly__) || (defined(__FreeBSD__)) && (NBKTR > 0)) \ - || (defined(__bsdi__)) \ - || (defined(__OpenBSD__)) \ - || (defined(__NetBSD__)) \ - ) + /* + The Brooktree BT848 Driver driver is based upon Mark Tinguely and + Jim Lowe's driver for the Matrox Meteor PCI card . The + Philips SAA 7116 and SAA 7196 are very different chipsets than + the BT848. + The original copyright notice by Mark and Jim is included mostly + to honor their fantastic work in the Matrox Meteor driver! + */ -/*******************/ -/* *** FreeBSD *** */ -/*******************/ -#if defined(__DragonFly__) || defined(__FreeBSD__) +#include "opt_bktr.h" /* Include any kernel config options */ #include #include #include +#include +#include #include #include @@ -125,36 +104,31 @@ #include #include -#if defined(__DragonFly__) || (__FreeBSD_version >=400000) || (NSMBUS > 0) #include /* used by smbus and newbus */ -#endif - -#if defined(__DragonFly__) || (__FreeBSD_version < 500000) -#include /* for DELAY */ -#endif +#define PROC_LOCK(p) +#define PROC_UNLOCK(p) #include +#include -#if defined(__DragonFly__) || (__FreeBSD_version >=300000) #include /* for bus space */ #include #include -#endif -#include -#include /* extensions to ioctl_meteor.h */ -#include "bktr_reg.h" -#include "bktr_tuner.h" -#include "bktr_card.h" -#include "bktr_audio.h" -#include "bktr_os.h" -#include "bktr_core.h" +#include +#include /* extensions to ioctl_meteor.h */ +#include +#include +#include +#include +#include +#include #if defined(BKTR_FREEBSD_MODULE) -#include "bktr_mem.h" +#include #endif #if defined(BKTR_USE_FREEBSD_SMBUS) -#include "bktr_i2c.h" +#include #include #include #include "smbus_if.h" @@ -167,63 +141,12 @@ bktr_name(bktr_ptr_t bktr) return bktr->bktr_xname; } +typedef u_char bool_t; -#if defined(__FreeBSD__) && (__FreeBSD__ == 2) -typedef unsigned int uintptr_t; -#endif -#endif /* __FreeBSD__ */ - - -/****************/ -/* *** BSDI *** */ -/****************/ -#ifdef __bsdi__ -#endif /* __bsdi__ */ - - -/**************************/ -/* *** OpenBSD/NetBSD *** */ -/**************************/ -#if defined(__NetBSD__) || defined(__OpenBSD__) - -#include -#include -#include -#include -#include - -#ifdef __NetBSD__ -#include -#else -#include -#include -#include -#include -#endif - -#include /* uintptr_t */ -#include -#include -#include -#include -#include -#include -#include - -static int bt848_format = -1; - -const char * -bktr_name(bktr_ptr_t bktr) -{ - return (bktr->bktr_dev.dv_xname); -} - -#endif /* __NetBSD__ || __OpenBSD__ */ - +#define BKTRPRI PCATCH +#define VBIPRI PCATCH -typedef u_char bool_t; - /* * memory allocated for DMA programs */ @@ -465,32 +388,10 @@ common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev ) { vm_offset_t buf = 0; int need_to_allocate_memory = 1; - -/***************************************/ -/* *** OS Specific memory routines *** */ -/***************************************/ -#if defined(__NetBSD__) || defined(__OpenBSD__) - /* allocate space for dma program */ - bktr->dma_prog = get_bktr_mem(bktr, &bktr->dm_prog, - DMA_PROG_ALLOC); - bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog, - DMA_PROG_ALLOC); - - /* allocate space for the VBI buffer */ - bktr->vbidata = get_bktr_mem(bktr, &bktr->dm_vbidata, - VBI_DATA_SIZE); - bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer, - VBI_BUFFER_SIZE); - - /* allocate space for pixel buffer */ - if ( BROOKTREE_ALLOC ) - buf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC); - else - buf = 0; +#ifdef BKTR_NEW_MSP34XX_DRIVER + int err; #endif -#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__bsdi__) - /* If this is a module, check if there is any currently saved contiguous memory */ #if defined(BKTR_FREEBSD_MODULE) if (bktr_has_stored_addresses(unit) == 1) { @@ -519,8 +420,10 @@ common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev ) else buf = 0; } -#endif /* FreeBSD or BSDi */ +#ifdef USE_VBIMUTEX + mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF); +#endif /* If this is a module, save the current contiguous memory */ #if defined(BKTR_FREEBSD_MODULE) @@ -534,7 +437,7 @@ bktr_store_address(unit, BKTR_MEM_BUF, buf); if ( bootverbose ) { printf("%s: buffer size %d, addr %p\n", - bktr_name(bktr), BROOKTREE_ALLOC, + bktr_name(bktr), BROOKTREE_ALLOC, (void *)(uintptr_t)vtophys(buf)); } @@ -606,11 +509,27 @@ bktr_store_address(unit, BKTR_MEM_BUF, buf); bktr->msp_source_selected = -1; bktr->audio_mux_present = 1; +#ifdef BKTR_NEW_MSP34XX_DRIVER + /* get hint on short programming of the msp34xx, so we know */ + /* if the decision what thread to start should be overwritten */ + if ( (err = resource_int_value("bktr", unit, "mspsimple", + &(bktr->mspsimple)) ) != 0 ) + bktr->mspsimple = -1; /* fall back to default */ +#endif + probeCard( bktr, TRUE, unit ); /* Initialise any MSP34xx or TDA98xx audio chips */ init_audio_devices( bktr ); +#ifdef BKTR_NEW_MSP34XX_DRIVER + /* setup the kenrel thread */ + err = msp_attach( bktr ); + if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */ + bktr->card.msp3400c = 0; +#endif + + } @@ -784,6 +703,7 @@ common_bktr_intr( void *arg ) * both Odd and Even VBI data is captured. Therefore we do this * in the Even field interrupt handler. */ + LOCK_VBI(bktr); if ( (bktr->vbiflags & VBI_CAPTURE) &&(bktr->vbiflags & VBI_OPEN) &&(field==EVEN_F)) { @@ -803,7 +723,7 @@ common_bktr_intr( void *arg ) } - + UNLOCK_VBI(bktr); /* * Register the completed field @@ -893,9 +813,10 @@ common_bktr_intr( void *arg ) * let them know the frame is complete. */ - if (bktr->proc && (bktr->signal & ~METEOR_SIG_MODE_MASK)) { - psignal(bktr->proc, - bktr->signal & ~METEOR_SIG_MODE_MASK ); + if (bktr->proc != NULL) { + PROC_LOCK(bktr->proc); + psignal( bktr->proc, bktr->signal); + PROC_UNLOCK(bktr->proc); } /* @@ -1022,7 +943,7 @@ video_open( bktr_ptr_t bktr ) bktr->frames_captured = 0; bktr->even_fields_captured = 0; bktr->odd_fields_captured = 0; - bktr->proc = (struct proc *)0; + bktr->proc = NULL; set_fps(bktr, frame_rate); bktr->video.addr = 0; bktr->video.width = 0; @@ -1043,8 +964,13 @@ video_open( bktr_ptr_t bktr ) int vbi_open( bktr_ptr_t bktr ) { - if (bktr->vbiflags & VBI_OPEN) /* device is busy */ + + LOCK_VBI(bktr); + + if (bktr->vbiflags & VBI_OPEN) { /* device is busy */ + UNLOCK_VBI(bktr); return( EBUSY ); + } bktr->vbiflags |= VBI_OPEN; @@ -1058,6 +984,8 @@ vbi_open( bktr_ptr_t bktr ) bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE); bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE); + UNLOCK_VBI(bktr); + return( 0 ); } @@ -1143,8 +1071,12 @@ int vbi_close( bktr_ptr_t bktr ) { + LOCK_VBI(bktr); + bktr->vbiflags &= ~VBI_OPEN; + UNLOCK_VBI(bktr); + return( 0 ); } @@ -1187,7 +1119,7 @@ video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio) BT848_INT_FMTCHG); - status = tsleep(BKTR_SLEEP, PCATCH, "captur", 0); + status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0); if (!status) /* successful capture */ status = uiomove((caddr_t)bktr->bigbuf, count, uio); else @@ -1212,16 +1144,29 @@ vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag) int readsize, readsize2, start; int status; + /* + * XXX - vbi_read() should be protected against being re-entered + * while it is unlocked for the uiomove. + */ + LOCK_VBI(bktr); while(bktr->vbisize == 0) { if (ioflag & IO_NDELAY) { - return EWOULDBLOCK; + status = EWOULDBLOCK; + goto out; } bktr->vbi_read_blocked = TRUE; - if ((status = tsleep(VBI_SLEEP, PCATCH, "vbi", 0))) { - return status; +#ifdef USE_VBIMUTEX + if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi", + 0))) { + goto out; } +#else + if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) { + goto out; + } +#endif } /* Now we have some data to give to the user */ @@ -1239,15 +1184,19 @@ vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag) /* We need to wrap around */ readsize2 = VBI_BUFFER_SIZE - bktr->vbistart; - start = bktr->vbistart; + start = bktr->vbistart; + UNLOCK_VBI(bktr); status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio); if (status == 0) status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio); } else { + UNLOCK_VBI(bktr); /* We do not need to wrap around */ status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio); } + LOCK_VBI(bktr); + /* Update the number of bytes left to read */ bktr->vbisize -= readsize; @@ -1255,6 +1204,9 @@ vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag) bktr->vbistart += readsize; bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */ +out: + UNLOCK_VBI(bktr); + return( status ); } @@ -1265,7 +1217,7 @@ vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag) * video ioctls */ int -video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread *td) +video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td ) { volatile u_char c_temp; unsigned int temp; @@ -1550,17 +1502,15 @@ video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thr case METEORSSIGNAL: sig = *(int *)arg; - /* - * Historically, applications used METEOR_SIG_MODE_MASK + /* Historically, applications used METEOR_SIG_MODE_MASK * to reset signal delivery. */ if (sig == METEOR_SIG_MODE_MASK) sig = 0; if (sig < 0 || sig > _SIG_MAXSIG) - return( EINVAL ); - KKASSERT(td->td_proc != NULL); + return (EINVAL); bktr->signal = sig; - bktr->proc = td->td_proc; + bktr->proc = sig ? td->td_proc : NULL; break; case METEORGSIGNAL: @@ -1593,7 +1543,7 @@ video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thr BT848_INT_FMTCHG); OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl); - error = tsleep(BKTR_SLEEP, PCATCH, "captur", hz); + error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz); if (error && (error != ERESTART)) { /* Here if we didn't get complete frame */ #ifdef DIAGNOSTIC @@ -1732,25 +1682,10 @@ video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thr if ((int) temp > bktr->alloc_pages && bktr->video.addr == 0) { -/*****************************/ -/* *** OS Dependant code *** */ -/*****************************/ -#if defined(__NetBSD__) || defined(__OpenBSD__) - bus_dmamap_t dmamap; - - buf = get_bktr_mem(bktr, &dmamap, - temp * PAGE_SIZE); - if (buf != 0) { - free_bktr_mem(bktr, bktr->dm_mem, - bktr->bigbuf); - bktr->dm_mem = dmamap; - -#else buf = get_bktr_mem(unit, temp*PAGE_SIZE); if (buf != 0) { kmem_free(kernel_map, bktr->bigbuf, (bktr->alloc_pages * PAGE_SIZE)); -#endif bktr->bigbuf = buf; bktr->alloc_pages = temp; @@ -1881,7 +1816,7 @@ video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thr * tuner ioctls */ int -tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread *td) +tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td ) { int tmp_int; unsigned int temp, temp1; @@ -2765,7 +2700,7 @@ rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) /* Wait for the VRE sync marking the end of the Even and * the start of the Odd field. Resync here. */ - *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_VRE; + *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE; *dma_prog++ = 0; loop_point = dma_prog; @@ -2791,20 +2726,20 @@ rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) if ( notclipped(bktr, i, width)) { split(bktr, (volatile u_long **) &dma_prog, bktr->y2 - bktr->y, OP_WRITE, - Bpp, (volatile u_char **) &target, cols); + Bpp, (volatile u_char **)(uintptr_t)&target, cols); } else { while(getline(bktr, i)) { if (bktr->y != bktr->y2 ) { split(bktr, (volatile u_long **) &dma_prog, bktr->y2 - bktr->y, OP_WRITE, - Bpp, (volatile u_char **) &target, cols); + Bpp, (volatile u_char **)(uintptr_t)&target, cols); } if (bktr->yclip != bktr->yclip2 ) { split(bktr,(volatile u_long **) &dma_prog, bktr->yclip2 - bktr->yclip, OP_SKIP, - Bpp, (volatile u_char **) &target, cols); + Bpp, (volatile u_char **)(uintptr_t)&target, cols); } } @@ -2848,19 +2783,19 @@ rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) if ( notclipped(bktr, i, width)) { split(bktr, (volatile u_long **) &dma_prog, bktr->y2 - bktr->y, OP_WRITE, - Bpp, (volatile u_char **) &target, cols); + Bpp, (volatile u_char **)(uintptr_t)&target, cols); } else { while(getline(bktr, i)) { if (bktr->y != bktr->y2 ) { split(bktr, (volatile u_long **) &dma_prog, bktr->y2 - bktr->y, OP_WRITE, - Bpp, (volatile u_char **) &target, + Bpp, (volatile u_char **)(uintptr_t)&target, cols); } if (bktr->yclip != bktr->yclip2 ) { split(bktr, (volatile u_long **) &dma_prog, bktr->yclip2 - bktr->yclip, OP_SKIP, - Bpp, (volatile u_char **) &target, cols); + Bpp, (volatile u_char **)(uintptr_t) &target, cols); } } @@ -2945,20 +2880,20 @@ rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) if ( notclipped(bktr, i, width)) { split(bktr, (volatile u_long **) &dma_prog, bktr->y2 - bktr->y, OP_WRITE, - Bpp, (volatile u_char **) &target, cols); + Bpp, (volatile u_char **)(uintptr_t)&target, cols); } else { while(getline(bktr, i)) { if (bktr->y != bktr->y2 ) { split(bktr, (volatile u_long **) &dma_prog, bktr->y2 - bktr->y, OP_WRITE, - Bpp, (volatile u_char **) &target, cols); + Bpp, (volatile u_char **)(uintptr_t)&target, cols); } if (bktr->yclip != bktr->yclip2 ) { split(bktr,(volatile u_long **) &dma_prog, bktr->yclip2 - bktr->yclip, OP_SKIP, - Bpp, (volatile u_char **) &target, cols); + Bpp, (volatile u_char **)(uintptr_t)&target, cols); } } @@ -3011,19 +2946,19 @@ rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) if ( notclipped(bktr, i, width)) { split(bktr, (volatile u_long **) &dma_prog, bktr->y2 - bktr->y, OP_WRITE, - Bpp, (volatile u_char **) &target, cols); + Bpp, (volatile u_char **)(uintptr_t)&target, cols); } else { while(getline(bktr, i)) { if (bktr->y != bktr->y2 ) { split(bktr, (volatile u_long **) &dma_prog, bktr->y2 - bktr->y, OP_WRITE, - Bpp, (volatile u_char **) &target, + Bpp, (volatile u_char **)(uintptr_t)&target, cols); } if (bktr->yclip != bktr->yclip2 ) { split(bktr, (volatile u_long **) &dma_prog, bktr->yclip2 - bktr->yclip, OP_SKIP, - Bpp, (volatile u_char **) &target, cols); + Bpp, (volatile u_char **)(uintptr_t)&target, cols); } } @@ -3121,7 +3056,7 @@ yuvpack_prog( bktr_ptr_t bktr, char i_flag, case 3: /* sync vro */ - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | 1 << 15 | BKTR_VRO; + *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO; *dma_prog++ = 0; /* NULL WORD */ *dma_prog++ = OP_JUMP ; *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); @@ -3148,7 +3083,7 @@ yuvpack_prog( bktr_ptr_t bktr, char i_flag, } /* sync vro IRQ bit */ - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE; + *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE; *dma_prog++ = 0; /* NULL WORD */ *dma_prog++ = OP_JUMP ; *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); @@ -3207,7 +3142,7 @@ yuv422_prog( bktr_ptr_t bktr, char i_flag, t1 = buffer; /* contruct sync : for video packet format */ - *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM3; /*sync, mode indicator packed data*/ + *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/ *dma_prog++ = 0; /* NULL WORD */ for (i = 0; i < (rows/interlace ) ; i++) { @@ -3221,7 +3156,7 @@ yuv422_prog( bktr_ptr_t bktr, char i_flag, switch (i_flag) { case 1: - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE; /*sync vre*/ + *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/ *dma_prog++ = 0; /* NULL WORD */ *dma_prog++ = OP_JUMP ; @@ -3229,7 +3164,7 @@ yuv422_prog( bktr_ptr_t bktr, char i_flag, return; case 2: - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO; /*sync vre*/ + *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/ *dma_prog++ = 0; /* NULL WORD */ *dma_prog++ = OP_JUMP; @@ -3237,7 +3172,7 @@ yuv422_prog( bktr_ptr_t bktr, char i_flag, return; case 3: - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO; + *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; *dma_prog++ = 0; /* NULL WORD */ *dma_prog++ = OP_JUMP ; @@ -3251,7 +3186,7 @@ yuv422_prog( bktr_ptr_t bktr, char i_flag, target_buffer = (u_long) buffer + cols; t1 = buffer + cols/2; - *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM3; + *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; *dma_prog++ = 0; /* NULL WORD */ for (i = 0; i < (rows/interlace ) ; i++) { @@ -3264,7 +3199,7 @@ yuv422_prog( bktr_ptr_t bktr, char i_flag, } } - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE; + *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; *dma_prog++ = 0; /* NULL WORD */ *dma_prog++ = OP_JUMP ; *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ; @@ -3290,7 +3225,7 @@ yuv12_prog( bktr_ptr_t bktr, char i_flag, dma_prog = (u_long *) bktr->dma_prog; - bktr->capcontrol = 1 << 6 | 1 << 4 | 3; + bktr->capcontrol = 1 << 6 | 1 << 4 | 3; OUTB(bktr, BKTR_ADC, SYNC_LEVEL); OUTB(bktr, BKTR_OFORM, 0x0); @@ -3306,7 +3241,7 @@ yuv12_prog( bktr_ptr_t bktr, char i_flag, buffer = target_buffer; t1 = buffer; - *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM3; /*sync, mode indicator packed data*/ + *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/ *dma_prog++ = 0; /* NULL WORD */ for (i = 0; i < (rows/interlace )/2 ; i++) { @@ -3325,7 +3260,7 @@ yuv12_prog( bktr_ptr_t bktr, char i_flag, switch (i_flag) { case 1: - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE; /*sync vre*/ + *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/ *dma_prog++ = 0; /* NULL WORD */ *dma_prog++ = OP_JUMP; @@ -3333,7 +3268,7 @@ yuv12_prog( bktr_ptr_t bktr, char i_flag, return; case 2: - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO; /*sync vro*/ + *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/ *dma_prog++ = 0; /* NULL WORD */ *dma_prog++ = OP_JUMP; @@ -3341,7 +3276,7 @@ yuv12_prog( bktr_ptr_t bktr, char i_flag, return; case 3: - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO; + *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; *dma_prog++ = 0; /* NULL WORD */ *dma_prog++ = OP_JUMP ; *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); @@ -3354,7 +3289,7 @@ yuv12_prog( bktr_ptr_t bktr, char i_flag, target_buffer = (u_long) buffer + cols; t1 = buffer + cols/2; - *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM3; + *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; *dma_prog++ = 0; /* NULL WORD */ for (i = 0; i < ((rows/interlace )/2 ) ; i++) { @@ -3374,7 +3309,7 @@ yuv12_prog( bktr_ptr_t bktr, char i_flag, } - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE; + *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; *dma_prog++ = 0; /* NULL WORD */ *dma_prog++ = OP_JUMP; *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); @@ -4258,6 +4193,3 @@ i2cProbe( bktr_ptr_t bktr, int addr ) #define ABSENT (-1) - -#endif /* FreeBSD, BSDI, NetBSD, OpenBSD */ - diff --git a/sys/dev/video/bktr/bktr_core.h b/sys/dev/video/bktr/bktr_core.h index f386a19634..04fc1bf1c7 100644 --- a/sys/dev/video/bktr/bktr_core.h +++ b/sys/dev/video/bktr/bktr_core.h @@ -1,5 +1,5 @@ -/* $FreeBSD: src/sys/dev/bktr/bktr_core.h,v 1.2.2.2 2000/09/11 07:59:57 roger Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_core.h,v 1.3 2003/06/23 17:55:30 dillon Exp $ */ +/* $FreeBSD: src/sys/dev/bktr/bktr_core.h,v 1.5 2001/09/12 08:37:02 julian Exp $ */ +/* $DragonFly: src/sys/dev/video/bktr/bktr_core.h,v 1.4 2004/05/15 17:54:12 joerg Exp $ */ /* * This is part of the Driver for Video Capture Cards (Frame grabbers) @@ -83,13 +83,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, - ioctl_cmd_t cmd, caddr_t arg, struct thread *td); + ioctl_cmd_t cmd, caddr_t arg, struct thread* pr ); int tuner_open( bktr_ptr_t bktr ); int tuner_close( bktr_ptr_t bktr ); int tuner_ioctl( bktr_ptr_t bktr, int unit, - ioctl_cmd_t cmd, caddr_t arg, struct thread *td); + ioctl_cmd_t cmd, caddr_t arg, struct thread* pr ); int vbi_open( bktr_ptr_t bktr ); int vbi_close( bktr_ptr_t bktr ); diff --git a/sys/dev/video/bktr/bktr_i2c.c b/sys/dev/video/bktr/bktr_i2c.c index 3fb8afb505..a117aa6d63 100644 --- a/sys/dev/video/bktr/bktr_i2c.c +++ b/sys/dev/video/bktr/bktr_i2c.c @@ -1,5 +1,5 @@ -/*- - * Copyright (c) 1998 Nicolas Souchu +/* + * Copyright (c) 1998, 2001 Nicolas Souchu * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,9 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/bktr/bktr_i2c.c,v 1.13.2.3 2000/10/26 16:38:46 roger Exp $ - * $DragonFly: src/sys/dev/video/bktr/bktr_i2c.c,v 1.4 2004/02/13 01:45:15 joerg Exp $ - * + * $FreeBSD: src/sys/dev/bktr/bktr_i2c.c,v 1.25 2003/12/08 07:59:18 obrien Exp $ + * $DragonFly: src/sys/dev/video/bktr/bktr_i2c.c,v 1.5 2004/05/15 17:54:12 joerg Exp $ */ /* @@ -34,220 +33,107 @@ * From brooktree848.c */ -#include "use_bktr.h" +#include "opt_bktr.h" #include #include +#include #include #include #include #include + #include -#if defined(__DragonFly__) || (__FreeBSD_version < 500000) -#include /* for DELAY */ -#endif +#include +#include -#if defined(__DragonFly__) || (__FreeBSD_version >=300000) #include /* for bus space */ #include #include -#endif -#include -#include -#include -#include /* extensions to ioctl_meteor.h */ -#include "bktr_reg.h" - -#include "bktr_i2c.h" - -#include -#include +#include +#include /* extensions to ioctl_meteor.h */ +#include +#include #include - -#include "iicbb_if.h" -#include "smbus_if.h" - - +#include #define I2C_DELAY 40 +/* Compilation is void if BKTR_USE_FREEBSD_SMBUS is not + * defined. This allows bktr owners to have smbus active for there + * motherboard and still use their bktr without smbus. + */ +#if defined(BKTR_USE_FREEBSD_SMBUS) + #define BTI2C_DEBUG(x) if (bti2c_debug) (x) static int bti2c_debug = 0; -struct bti2c_softc { - - 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 */ - - device_t smbus; - device_t iicbus; -}; - -struct bt_data { - bus_space_tag_t memt; - bus_space_handle_t memh; -}; -struct bt_data btdata[NBKTR]; - -static int bti2c_probe(device_t); -static int bti2c_attach(device_t); - -static int bti2c_iic_callback(device_t, int, caddr_t *); -static void bti2c_iic_setlines(device_t, int, int); -static int bti2c_iic_getdataline(device_t); -static int bti2c_iic_reset(device_t, u_char, u_char, u_char *); - -static int bti2c_smb_callback(device_t, int, caddr_t *); -static int bti2c_smb_writeb(device_t dev, u_char slave, char cmd, char byte); -static int bti2c_smb_writew(device_t dev, u_char slave, char cmd, short word); -static int bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte); - -static devclass_t bti2c_devclass; - -static device_method_t bti2c_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, bti2c_probe), - DEVMETHOD(device_attach, bti2c_attach), - - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - - /* iicbb interface */ - DEVMETHOD(iicbb_callback, bti2c_iic_callback), - DEVMETHOD(iicbb_setlines, bti2c_iic_setlines), - DEVMETHOD(iicbb_getdataline, bti2c_iic_getdataline), - DEVMETHOD(iicbb_reset, bti2c_iic_reset), - - /* smbus interface */ - DEVMETHOD(smbus_callback, bti2c_smb_callback), - DEVMETHOD(smbus_writeb, bti2c_smb_writeb), - DEVMETHOD(smbus_writew, bti2c_smb_writew), - DEVMETHOD(smbus_readb, bti2c_smb_readb), - - { 0, 0 } -}; - -#if defined(__FreeBSD__) && (__FreeBSD_version < 400000) -/* FreeBSD 3.x needs DRIVER_TYPE_MISC */ -static driver_t bti2c_driver = { - "bti2c", - bti2c_methods, - DRIVER_TYPE_MISC, - sizeof(struct bti2c_softc), -}; -#endif - -#if defined(__DragonFly__) || (__FreeBSD_version >=400000) - static driver_t bti2c_driver = { - "bti2c", - bti2c_methods, - sizeof(struct bti2c_softc), -}; -#endif - /* * 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, struct bktr_softc * bktr, struct bktr_i2c_softc *i2c_sc) +int bt848_i2c_attach(device_t dev) { - device_t interface; - device_t bitbang; - - btdata[unit].memh = bktr->memh; - btdata[unit].memt = bktr->memt; - - /* XXX add the I2C interface to the root_bus until pcibus is ready */ -#if defined(__FreeBSD__) && (__FreeBSD_version < 400000) - interface = device_add_child(root_bus, "bti2c", unit, NULL); -#else - interface = device_add_child(root_bus, "bti2c", unit); -#endif - - /* add bit-banging generic code onto bti2c interface */ -#if defined(__FreeBSD__) && (__FreeBSD_version < 400000) - bitbang = device_add_child(interface, "iicbb", -1, NULL); -#else - bitbang = device_add_child(interface, "iicbb", -1); -#endif - - /* probe and attach the interface, we need it NOW - * bit-banging code is also probed and attached */ - device_probe_and_attach(interface); - device_probe_and_attach(bitbang); - - /* smb and i2c interfaces are available for the bt848 chip - * connect bit-banging generic code to an iicbus */ - if ((i2c_sc->iicbus = iicbus_alloc_bus(bitbang))) - device_probe_and_attach(i2c_sc->iicbus); - - /* hardware i2c is actually smb over the bti2c interface */ - if ((i2c_sc->smbus = smbus_alloc_bus(interface))) - device_probe_and_attach(i2c_sc->smbus); + struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev); + struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc; + + sc->smbus = device_add_child(dev, "smbus", -1); + sc->iicbb = device_add_child(dev, "iicbb", -1); + + if (!sc->iicbb || !sc->smbus) + return ENXIO; + + bus_generic_attach(dev); return (0); }; -/* - * Not a real probe, we know the device exists since the device has - * been added after the successfull pci probe. - */ -static int -bti2c_probe(device_t dev) +int bt848_i2c_detach(device_t dev) { - device_set_desc(dev, "bt848 Hard/Soft I2C controller"); + struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev); + struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc; + int error = 0; - return (0); -} + if ((error = bus_generic_detach(dev))) + goto error; -static int -bti2c_attach(device_t dev) -{ - struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev); + if (sc->iicbb && (error = device_delete_child(dev, sc->iicbb))) + goto error; - /* XXX should use ivars with pcibus or pcibus methods to access - * onboard memory */ - sc->memh = btdata[device_get_unit(dev)].memh; - sc->memt = btdata[device_get_unit(dev)].memt; + if (sc->smbus && (error = device_delete_child(dev, sc->smbus))) + goto error; - return (0); +error: + return (error); } -static int -bti2c_smb_callback(device_t dev, int index, caddr_t *data) +int bti2c_smb_callback(device_t dev, int index, caddr_t *data) { - struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev); + struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev); + struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc; int error = 0; - int how; /* test each time if we already have/haven't the iicbus * to avoid deadlocks */ switch (index) { case SMB_REQUEST_BUS: - if (!sc->iic_owned) { - /* request the iicbus */ - how = *(int *)data; - error = iicbus_request_bus(sc->iicbus, dev, how); - if (!error) - sc->iic_owned = 1; - } + /* XXX test & set */ + if (!sc->bus_owned) { + sc->bus_owned = 1; + } else + error = EWOULDBLOCK; break; case SMB_RELEASE_BUS: - if (sc->iic_owned) { - /* release the iicbus */ - error = iicbus_release_bus(sc->iicbus, dev); - if (!error) - sc->iic_owned = 0; - } + /* XXX test & set */ + if (sc->bus_owned) { + sc->bus_owned = 0; + } else + error = EINVAL; break; default: @@ -257,34 +143,30 @@ bti2c_smb_callback(device_t dev, int index, caddr_t *data) return (error); } -static int -bti2c_iic_callback(device_t dev, int index, caddr_t *data) +int bti2c_iic_callback(device_t dev, int index, caddr_t *data) { - struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev); + struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev); + struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc; int error = 0; - int how; /* test each time if we already have/haven't the smbus * to avoid deadlocks */ switch (index) { case IIC_REQUEST_BUS: - if (!sc->smb_owned) { - /* request the smbus */ - how = *(int *)data; - error = smbus_request_bus(sc->smbus, dev, how); - if (!error) - sc->smb_owned = 1; - } + /* XXX test & set */ + if (!sc->bus_owned) { + sc->bus_owned = 1; + } else + error = EWOULDBLOCK; break; case IIC_RELEASE_BUS: - if (sc->smb_owned) { - /* release the smbus */ - error = smbus_release_bus(sc->smbus, dev); - if (!error) - sc->smb_owned = 0; - } + /* XXX test & set */ + if (sc->bus_owned) { + sc->bus_owned = 0; + } else + error = EINVAL; break; default: @@ -294,8 +176,7 @@ bti2c_iic_callback(device_t dev, int index, caddr_t *data) return (error); } -static int -bti2c_iic_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr) +int bti2c_iic_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr) { if (oldaddr) *oldaddr = 0; /* XXX */ @@ -303,48 +184,77 @@ bti2c_iic_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr) return (IIC_ENOADDR); } -static void -bti2c_iic_setlines(device_t dev, int ctrl, int data) +void bti2c_iic_setsda(device_t dev, int val) { - struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev); + struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); + int clock; + + clock = INL(sc, BKTR_I2C_DATA_CTL) & 0x2; + + if (val) + OUTL(sc, BKTR_I2C_DATA_CTL, clock | 1); + else + OUTL(sc, BKTR_I2C_DATA_CTL, clock); - OUTL(sc, BKTR_I2C_DATA_CTL, (ctrl << 1) | data);; DELAY(I2C_DELAY); return; } -static int -bti2c_iic_getdataline(device_t dev) +void bti2c_iic_setscl(device_t dev, int val) +{ + struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); + int data; + + data = INL(sc, BKTR_I2C_DATA_CTL) & 0x1; + + if (val) + OUTL(sc, BKTR_I2C_DATA_CTL, 0x2 | data); + else + OUTL(sc, BKTR_I2C_DATA_CTL, data); + + DELAY(I2C_DELAY); + + return; +} + +int +bti2c_iic_getsda(device_t dev) { - struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev); + struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); - return ( INL(sc,BKTR_I2C_DATA_CTL) & 0x1); + return (INL(sc,BKTR_I2C_DATA_CTL) & 0x1); +} + +int +bti2c_iic_getscl(device_t dev) +{ + return (0); } static int -bti2c_write(struct bti2c_softc* bti2c_sc, u_long data) +bti2c_write(struct bktr_softc *sc, u_long data) { u_long x; /* clear status bits */ - OUTL(bti2c_sc, BKTR_INT_STAT, (BT848_INT_RACK | BT848_INT_I2CDONE)); + OUTL(sc, BKTR_INT_STAT, (BT848_INT_RACK | BT848_INT_I2CDONE)); BTI2C_DEBUG(printf("w%lx", data)); /* write the address and data */ - OUTL(bti2c_sc, BKTR_I2C_DATA_CTL, data); + OUTL(sc, BKTR_I2C_DATA_CTL, data); /* wait for completion */ for ( x = 0x7fffffff; x; --x ) { /* safety valve */ - if ( INL(bti2c_sc, BKTR_INT_STAT) & BT848_INT_I2CDONE ) + if ( INL(sc, BKTR_INT_STAT) & BT848_INT_I2CDONE ) break; } /* check for ACK */ - if ( !x || !( INL(bti2c_sc, BKTR_INT_STAT) & BT848_INT_RACK) ) { + if ( !x || !( INL(sc, BKTR_INT_STAT) & BT848_INT_RACK) ) { BTI2C_DEBUG(printf("%c%c", (!x)?'+':'-', - (!( INL(bti2c_sc, BKTR_INT_STAT) & BT848_INT_RACK))?'+':'-')); + (!( INL(sc, BKTR_INT_STAT) & BT848_INT_RACK))?'+':'-')); return (SMB_ENOACK); } BTI2C_DEBUG(printf("+")); @@ -353,10 +263,10 @@ bti2c_write(struct bti2c_softc* bti2c_sc, u_long data) return( 0 ); } -static int +int bti2c_smb_writeb(device_t dev, u_char slave, char cmd, char byte) { - struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev); + struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); u_long data; data = ((slave & 0xff) << 24) | ((byte & 0xff) << 16) | (u_char)cmd; @@ -368,10 +278,10 @@ bti2c_smb_writeb(device_t dev, u_char slave, char cmd, char byte) * byte1 becomes low byte of word * byte2 becomes high byte of word */ -static int +int bti2c_smb_writew(device_t dev, u_char slave, char cmd, short word) { - struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev); + struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); u_long data; char low, high; @@ -387,10 +297,10 @@ bti2c_smb_writew(device_t dev, u_char slave, char cmd, short word) /* * The Bt878 and Bt879 differed on the treatment of i2c commands */ -static int +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); + struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); u_long x; /* clear status bits */ @@ -419,4 +329,4 @@ bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte) return (0); } -DRIVER_MODULE(bti2c, root, bti2c_driver, bti2c_devclass, 0, 0); +#endif /* defined(BKTR_USE_FREEBSD_SMBUS) */ diff --git a/sys/dev/video/bktr/bktr_i2c.h b/sys/dev/video/bktr/bktr_i2c.h index a50c467b15..a7924538d1 100644 --- a/sys/dev/video/bktr/bktr_i2c.h +++ b/sys/dev/video/bktr/bktr_i2c.h @@ -1,5 +1,5 @@ -/*- - * Copyright (c) 1998 Nicolas Souchu +/* + * Copyright (c) 1998, 2001 Nicolas Souchu * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,13 +23,25 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/bktr/bktr_i2c.h,v 1.2.4.2 2000/09/11 07:59:57 roger Exp $ - * $DragonFly: src/sys/dev/video/bktr/bktr_i2c.h,v 1.2 2003/06/17 04:28:23 dillon Exp $ - * + * $FreeBSD: src/sys/dev/bktr/bktr_i2c.h,v 1.4 2002/03/23 15:47:08 nsouch Exp $ + * $DragonFly: src/sys/dev/video/bktr/bktr_i2c.h,v 1.3 2004/05/15 17:54:12 joerg Exp $ */ #ifndef _BT848_I2C_H #define _BT848_I2C_H -extern int bt848_i2c_attach(int, struct bktr_softc *bktr, struct bktr_i2c_softc *); +extern int bt848_i2c_attach(device_t); +extern int bt848_i2c_detach(device_t); + +extern int bti2c_iic_callback(device_t, int, caddr_t *); +extern void bti2c_iic_setsda(device_t, int); +extern void bti2c_iic_setscl(device_t, int); +extern int bti2c_iic_getsda(device_t); +extern int bti2c_iic_getscl(device_t); +extern int bti2c_iic_reset(device_t, u_char, u_char, u_char *); + +extern int bti2c_smb_callback(device_t, int, caddr_t *); +extern int bti2c_smb_writeb(device_t dev, u_char slave, char cmd, char byte); +extern int bti2c_smb_writew(device_t dev, u_char slave, char cmd, short word); +extern int bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte); #endif diff --git a/sys/dev/video/bktr/bktr_mem.c b/sys/dev/video/bktr/bktr_mem.c index ec61e663c4..3defaba752 100644 --- a/sys/dev/video/bktr/bktr_mem.c +++ b/sys/dev/video/bktr/bktr_mem.c @@ -1,5 +1,5 @@ -/* $FreeBSD: src/sys/dev/bktr/bktr_mem.c,v 1.2.2.4 2001/10/09 04:08:41 jlemon Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_mem.c,v 1.4 2003/08/07 21:17:15 dillon Exp $ */ +/* $FreeBSD: src/sys/dev/bktr/bktr_mem.c,v 1.7 2003/08/24 17:46:02 obrien Exp $ */ +/* $DragonFly: src/sys/dev/video/bktr/bktr_mem.c,v 1.5 2004/05/15 17:54:12 joerg Exp $ */ /* * This is prt of the Driver for Video Capture Cards (Frame grabbers) @@ -48,9 +48,9 @@ #include -#include #include -#include "bktr_mem.h" +#include +#include struct memory_pointers { int addresses_stored; @@ -72,17 +72,7 @@ bktr_mem_modevent(module_t mod, int type, void *unused){ case MOD_LOAD: { printf("bktr_mem: memory holder loaded\n"); -/* - * bzero causes a panic. - bzero((caddr_t)memory_list, sizeof(memory_list)); - * So use a simple for loop for now. -*/ - {int x; - unsigned char *d = (unsigned char *)memory_list; - for (x=0; x< sizeof(memory_list); x++) { - d[x]=0; - } - } + bzero(memory_list, sizeof(memory_list)); return 0; } case MOD_UNLOAD: diff --git a/sys/dev/video/bktr/bktr_mem.h b/sys/dev/video/bktr/bktr_mem.h index 7e79e75835..d50af92780 100644 --- a/sys/dev/video/bktr/bktr_mem.h +++ b/sys/dev/video/bktr/bktr_mem.h @@ -1,5 +1,5 @@ -/* $FreeBSD: src/sys/dev/bktr/bktr_mem.h,v 1.1.2.1 2000/09/11 08:24:41 roger Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_mem.h,v 1.2 2003/06/17 04:28:23 dillon Exp $ */ +/* $FreeBSD: src/sys/dev/bktr/bktr_mem.h,v 1.1 2000/09/10 14:34:08 roger Exp $ */ +/* $DragonFly: src/sys/dev/video/bktr/bktr_mem.h,v 1.3 2004/05/15 17:54:12 joerg Exp $ */ /* * This is prt of the Driver for Video Capture Cards (Frame grabbers) @@ -61,4 +61,3 @@ int bktr_has_stored_addresses(int unit); void bktr_store_address(int unit, int type, vm_offset_t addr); vm_offset_t bktr_retrieve_address(int unit, int type); - diff --git a/sys/dev/video/bktr/bktr_os.c b/sys/dev/video/bktr/bktr_os.c index 4800207aa3..8e9fc1f6b5 100644 --- a/sys/dev/video/bktr/bktr_os.c +++ b/sys/dev/video/bktr/bktr_os.c @@ -1,20 +1,3 @@ -/* $FreeBSD: src/sys/dev/bktr/bktr_os.c,v 1.4.2.3 2000/10/27 00:46:09 jhb Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_os.c,v 1.8 2004/05/13 23:49:22 dillon Exp $ */ - -/* - * This is part of the Driver for Video Capture Cards (Frame grabbers) - * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 - * chipset. - * Copyright Roger Hardiman and Amancio Hasty. - * - * bktr_os : This has all the Operating System dependant code, - * probe/attach and open/close/ioctl/read/mmap - * memory allocation - * PCI bus interfacing - * - * - */ - /* * 1. Redistributions of source code must retain the * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman @@ -46,30 +29,35 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/dev/bktr/bktr_os.c,v 1.45 2004/03/17 17:50:28 njl Exp $ + * $DragonFly: src/sys/dev/video/bktr/bktr_os.c,v 1.9 2004/05/15 17:54:12 joerg Exp $ */ - -#if defined(__DragonFly__) || defined(__FreeBSD__) -#include "use_bktr.h" -#endif /* __FreeBSD__ */ +/* + * This is part of the Driver for Video Capture Cards (Frame grabbers) + * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 + * chipset. + * Copyright Roger Hardiman and Amancio Hasty. + * + * bktr_os : This has all the Operating System dependant code, + * probe/attach and open/close/ioctl/read/mmap + * memory allocation + * PCI bus interfacing + */ #include "opt_bktr.h" /* include any kernel config options */ #define FIFO_RISC_DISABLED 0 #define ALL_INTS_DISABLED 0 - -/*******************/ -/* *** FreeBSD *** */ -/*******************/ -#if defined(__DragonFly__) || defined(__FreeBSD__) - #include #include #include #include #include #include +#include #include #include #include @@ -80,27 +68,17 @@ #include #include -#if defined(__DragonFly__) || (__FreeBSD_version >=400000) || (NSMBUS > 0) #include /* used by smbus and newbus */ -#endif -#if defined(__DragonFly__) || (__FreeBSD_version >=300000) #include /* used by bus space */ #include /* used by bus space and newbus */ #include -#endif -#if defined(__DragonFly__) || (__FreeBSD_version >=400000) #include /* used by newbus */ #include /* used by newbus */ -#endif - -#if defined(__DragonFly__) || (__FreeBSD_version < 500000) -#include /* for DELAY */ -#endif - #include #include +#include #include int bt848_card = -1; @@ -108,6 +86,12 @@ int bt848_tuner = -1; int bt848_reverse_mute = -1; int bt848_format = -1; int bt848_slow_msp_audio = -1; +#ifdef BKTR_NEW_MSP34XX_DRIVER +int bt848_stereo_once = 0; /* no continuous stereo monitoring */ +int bt848_amsound = 0; /* hard-wire AM sound at 6.5 Hz (france), + the autoscan seems work well only with FM... */ +int bt848_dolby = 0; +#endif SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt"); SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, ""); @@ -115,89 +99,27 @@ 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, ""); SYSCTL_INT(_hw_bt848, OID_AUTO, slow_msp_audio, CTLFLAG_RW, &bt848_slow_msp_audio, -1, ""); - -#if defined(__FreeBSD__) && (__FreeBSD__ == 2) -#define PCIR_REVID PCI_CLASS_REG +#ifdef BKTR_NEW_MSP34XX_DRIVER +SYSCTL_INT(_hw_bt848, OID_AUTO, stereo_once, CTLFLAG_RW, &bt848_stereo_once, 0, ""); +SYSCTL_INT(_hw_bt848, OID_AUTO, amsound, CTLFLAG_RW, &bt848_amsound, 0, ""); +SYSCTL_INT(_hw_bt848, OID_AUTO, dolby, CTLFLAG_RW, &bt848_dolby, 0, ""); #endif -#endif /* end freebsd section */ - - - -/****************/ -/* *** BSDI *** */ -/****************/ -#ifdef __bsdi__ -#endif /* __bsdi__ */ - - -/**************************/ -/* *** OpenBSD/NetBSD *** */ -/**************************/ -#if defined(__NetBSD__) || defined(__OpenBSD__) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifndef __NetBSD__ -#include -#include -#include -#endif +#include +#include /* extensions to ioctl_meteor.h */ +#include +#include +#include +#include +#include +#include -#include -#include -#include -#include - -#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__ */ - - -#ifdef __NetBSD__ -#include /* NetBSD location for .h files */ -#include -#include -#include -#include -#include -#include -#else /* Traditional location for .h files */ -#include -#include /* extensions to ioctl_meteor.h */ -#include "bktr_reg.h" -#include "bktr_tuner.h" -#include "bktr_card.h" -#include "bktr_audio.h" -#include "bktr_core.h" -#include "bktr_os.h" #if defined(BKTR_USE_FREEBSD_SMBUS) -#include "bktr_i2c.h" -#endif -#endif - +#include - -/****************************/ -/* *** FreeBSD 4.x code *** */ -/****************************/ -#if defined(__DragonFly__) || (__FreeBSD_version >= 400000) +#include "iicbb_if.h" +#include "smbus_if.h" +#endif static int bktr_probe( device_t dev ); static int bktr_attach( device_t dev ); @@ -212,6 +134,22 @@ static device_method_t bktr_methods[] = { DEVMETHOD(device_detach, bktr_detach), DEVMETHOD(device_shutdown, bktr_shutdown), +#if defined(BKTR_USE_FREEBSD_SMBUS) + /* iicbb interface */ + DEVMETHOD(iicbb_callback, bti2c_iic_callback), + DEVMETHOD(iicbb_setsda, bti2c_iic_setsda), + DEVMETHOD(iicbb_setscl, bti2c_iic_setscl), + DEVMETHOD(iicbb_getsda, bti2c_iic_getsda), + DEVMETHOD(iicbb_getscl, bti2c_iic_getscl), + DEVMETHOD(iicbb_reset, bti2c_iic_reset), + + /* smbus interface */ + DEVMETHOD(smbus_callback, bti2c_smb_callback), + DEVMETHOD(smbus_writeb, bti2c_smb_writeb), + DEVMETHOD(smbus_writew, bti2c_smb_writew), + DEVMETHOD(smbus_readb, bti2c_smb_readb), +#endif + { 0, 0 } }; @@ -252,11 +190,8 @@ static struct cdevsw bktr_cdevsw = { }; DRIVER_MODULE(bktr, pci, bktr_driver, bktr_devclass, 0, 0); -#if defined(__DragonFly__) || (__FreeBSD_version > 410000) MODULE_DEPEND(bktr, bktr_mem, 1,1,1); MODULE_VERSION(bktr, 1); -#endif - /* * the boot time probe routine. @@ -325,10 +260,9 @@ bktr_attach( device_t dev ) /* * Map control/status registers. */ - bktr->mem_rid = PCIR_MAPS; - bktr->res_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &bktr->mem_rid, - 0, ~0, 1, RF_ACTIVE); - + bktr->mem_rid = PCIR_BAR(0); + bktr->res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &bktr->mem_rid, RF_ACTIVE); if (!bktr->res_mem) { device_printf(dev, "could not map memory\n"); @@ -358,8 +292,8 @@ bktr_attach( device_t dev ) * Allocate our interrupt. */ bktr->irq_rid = 0; - bktr->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &bktr->irq_rid, - 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); + bktr->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &bktr->irq_rid, RF_SHAREABLE | RF_ACTIVE); if (bktr->res_irq == NULL) { device_printf(dev, "could not map interrupt\n"); error = ENXIO; @@ -392,14 +326,11 @@ bktr_attach( device_t dev ) #endif pci_write_config(dev, 0x40, fun, 2); - - /* XXX call bt848_i2c dependent attach() routine */ #if defined(BKTR_USE_FREEBSD_SMBUS) - if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc)) + if (bt848_i2c_attach(dev)) printf("bktr%d: i2c_attach: can't attach\n", unit); #endif - /* * 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. @@ -440,16 +371,6 @@ bktr_attach( device_t dev ) 0, 0, 0444, "vbi%d" , unit); - /* if this is unit 0 (/dev/bktr0, /dev/tuner0, /dev/vbi0) then make */ - /* alias entries to /dev/bktr /dev/tuner and /dev/vbi */ -#if defined(__FreeBSD__) && (__FreeBSD_version >=500000) - if (unit == 0) { - bktr->bktrdev_alias = make_dev_alias(bktr->bktrdev, "bktr"); - bktr->tunerdev_alias= make_dev_alias(bktr->tunerdev, "tuner"); - bktr->vbidev_alias = make_dev_alias(bktr->vbidev, "vbi"); - } -#endif - return 0; fail: @@ -467,34 +388,37 @@ fail: static int bktr_detach( device_t dev ) { - unsigned int unit; - struct bktr_softc *bktr = device_get_softc(dev); - unit = device_get_unit(dev); +#ifdef BKTR_NEW_MSP34XX_DRIVER + /* Disable the soundchip and kernel thread */ + if (bktr->msp3400c_info != NULL) + msp_detach(bktr); +#endif /* Disable the brooktree device */ OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); +#if defined(BKTR_USE_FREEBSD_SMBUS) + if (bt848_i2c_detach(dev)) + printf("bktr%d: i2c_attach: can't attach\n", + device_get_unit(dev)); +#endif +#ifdef USE_VBIMUTEX + mtx_destroy(&bktr->vbimutex); +#endif + /* Note: We do not free memory for RISC programs, grab buffer, vbi buffers */ /* The memory is retained by the bktr_mem module so we can unload and */ /* then reload the main bktr driver module */ - /* Unregister the /dev/bktrN, tunerN and vbiN devices */ + /* Unregister the /dev/bktrN, tunerN and vbiN devices, + * the aliases for unit 0 are automatically destroyed */ destroy_dev(bktr->vbidev); destroy_dev(bktr->tunerdev); destroy_dev(bktr->bktrdev); - /* If this is unit 0, then destroy the alias entries too */ -#if defined(__FreeBSD__) && (__FreeBSD_version >=500000) - if (unit == 0) { - destroy_dev(bktr->vbidev_alias); - destroy_dev(bktr->tunerdev_alias); - destroy_dev(bktr->bktrdev_alias); - } -#endif - /* * Deallocate resources. */ @@ -529,9 +453,11 @@ get_bktr_mem( int unit, unsigned size ) { vm_offset_t addr = 0; - addr = vm_page_alloc_contig(size, 0, 0xffffffff, 1<<24); + addr = (vm_offset_t)contigmalloc(size, M_DEVBUF, M_NOWAIT, 0, + 0xffffffff, 1<<24, 0); if (addr == 0) - addr = vm_page_alloc_contig(size, 0, 0xffffffff, PAGE_SIZE); + addr = (vm_offset_t)contigmalloc(size, M_DEVBUF, M_NOWAIT, 0, + 0xffffffff, PAGE_SIZE, 0); if (addr == 0) { printf("bktr%d: Unable to allocate %d bytes of memory.\n", unit, size); @@ -558,8 +484,8 @@ get_bktr_mem( int unit, unsigned size ) /* * */ -int -bktr_open( dev_t dev, int flags, int fmt, d_thread_t *td) +static int +bktr_open( dev_t dev, int flags, int fmt, struct thread *td ) { bktr_ptr_t bktr; int unit; @@ -613,6 +539,26 @@ bktr_open( dev_t dev, int flags, int fmt, d_thread_t *td) } } +#ifdef BKTR_NEW_MSP34XX_DRIVER + if (bt848_stereo_once != 0) { + if ((bt848_stereo_once >> 8) == unit ) { + bktr->stereo_once = (bt848_stereo_once & 0xff); + } + } + + if (bt848_amsound != -1) { + if ((bt848_amsound >> 8) == unit ) { + bktr->amsound = (bt848_amsound & 0xff); + } + } + + if (bt848_dolby != -1) { + if ((bt848_dolby >> 8) == unit ) { + bktr->dolby = (bt848_dolby & 0xff); + } + } +#endif + switch ( FUNCTION( minor(dev) ) ) { case VIDEO_DEV: result = video_open( bktr ); @@ -638,8 +584,8 @@ bktr_open( dev_t dev, int flags, int fmt, d_thread_t *td) /* * */ -int -bktr_close( dev_t dev, int flags, int fmt, d_thread_t *td) +static int +bktr_close( dev_t dev, int flags, int fmt, struct thread *td ) { bktr_ptr_t bktr; int unit; @@ -677,7 +623,7 @@ bktr_close( dev_t dev, int flags, int fmt, d_thread_t *td) /* * */ -int +static int bktr_read( dev_t dev, struct uio *uio, int ioflag ) { bktr_ptr_t bktr; @@ -705,7 +651,7 @@ bktr_read( dev_t dev, struct uio *uio, int ioflag ) /* * */ -int +static int bktr_write( dev_t dev, struct uio *uio, int ioflag ) { return( EINVAL ); /* XXX or ENXIO ? */ @@ -715,8 +661,8 @@ bktr_write( dev_t dev, struct uio *uio, int ioflag ) /* * */ -int -bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, d_thread_t *td) +static int +bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct thread *td ) { bktr_ptr_t bktr; int unit; @@ -747,7 +693,7 @@ bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, d_thread_t *td) /* * */ -int +static int bktr_mmap( dev_t dev, vm_offset_t offset, int nprot ) { int unit; @@ -774,10 +720,11 @@ bktr_mmap( dev_t dev, vm_offset_t offset, int nprot ) if (offset >= bktr->alloc_pages * PAGE_SIZE) return( -1 ); - return( atop(vtophys(bktr->bigbuf) + offset) ); + return(atop(vtophys(bktr->bigbuf) + offset)); } -int bktr_poll( dev_t dev, int events, d_thread_t *td) +static int +bktr_poll( dev_t dev, int events, struct thread *td) { int unit; bktr_ptr_t bktr; @@ -793,6 +740,7 @@ int bktr_poll( dev_t dev, int events, d_thread_t *td) return (ENXIO); } + LOCK_VBI(bktr); DISABLE_INTR(s); if (events & (POLLIN | POLLRDNORM)) { @@ -808,945 +756,7 @@ int bktr_poll( dev_t dev, int events, d_thread_t *td) } ENABLE_INTR(s); + UNLOCK_VBI(bktr); return (revents); } - -#endif /* FreeBSD 4.x specific kernel interface routines */ - -/**********************************/ -/* *** FreeBSD 2.2.x and 3.x *** */ -/**********************************/ - -#if defined(__FreeBSD__) && (((__FreeBSD__ == 2) || (__FreeBSD__ == 3))) - -static bktr_reg_t brooktree[ NBKTR ]; - -static const char* bktr_probe( pcici_t tag, pcidi_t type ); -static void bktr_attach( pcici_t tag, int unit ); -static void bktr_intr(void *arg) { common_bktr_intr(arg); } - -static u_long bktr_count; - -static struct pci_device bktr_device = { - "bktr", - bktr_probe, - bktr_attach, - &bktr_count -}; - -DATA_SET (pcidevice_set, bktr_device); - -static d_open_t bktr_open; -static d_close_t bktr_close; -static d_read_t bktr_read; -static d_write_t bktr_write; -static d_ioctl_t bktr_ioctl; -static d_mmap_t bktr_mmap; -static d_poll_t bktr_poll; - -#define CDEV_MAJOR 92 -static struct cdevsw bktr_cdevsw = -{ - bktr_open, bktr_close, bktr_read, bktr_write, - bktr_ioctl, nostop, nullreset, nodevtotty, - bktr_poll, bktr_mmap, NULL, "bktr", - NULL, -1 -}; - -static int bktr_devsw_installed; - -static void -bktr_drvinit( void *unused ) -{ - dev_t dev; - - if ( ! bktr_devsw_installed ) { - dev = makedev(CDEV_MAJOR, 0); - cdevsw_add(&dev,&bktr_cdevsw, NULL); - bktr_devsw_installed = 1; - } -} - -SYSINIT(bktrdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bktr_drvinit,NULL) - -/* - * the boot time probe routine. - */ -static const char* -bktr_probe( pcici_t tag, pcidi_t type ) -{ - unsigned int rev = pci_conf_read( tag, PCIR_REVID) & 0x000000ff; - - if (PCI_VENDOR(type) == PCI_VENDOR_BROOKTREE) - { - switch (PCI_PRODUCT(type)) { - case PCI_PRODUCT_BROOKTREE_BT848: - if (rev == 0x12) return("BrookTree 848A"); - else return("BrookTree 848"); - case PCI_PRODUCT_BROOKTREE_BT849: - return("BrookTree 849A"); - case PCI_PRODUCT_BROOKTREE_BT878: - return("BrookTree 878"); - case PCI_PRODUCT_BROOKTREE_BT879: - return("BrookTree 879"); - } - }; - - return ((char *)0); -} - -/* - * the attach routine. - */ -static void -bktr_attach( pcici_t tag, int unit ) -{ - bktr_ptr_t bktr; - u_long latency; - u_long fun; - unsigned int rev; - unsigned long base; -#ifdef BROOKTREE_IRQ - u_long old_irq, new_irq; -#endif - - bktr = &brooktree[unit]; - - if (unit >= NBKTR) { - printf("brooktree%d: attach: only %d units configured.\n", - unit, NBKTR); - printf("brooktree%d: attach: invalid unit number.\n", unit); - return; - } - - /* build the device name for bktr_name() */ - snprintf(bktr->bktr_xname, sizeof(bktr->bktr_xname), "bktr%d",unit); - - /* Enable Memory Mapping */ - fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG); - pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 2); - - /* Enable Bus Mastering */ - fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG); - pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 4); - - bktr->tag = tag; - - - /* - * Map control/status registers - */ - pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &base, - &bktr->phys_base ); -#if defined(__DragonFly__) || (__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 - */ - 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); - pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ); - new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG); - printf("bktr%d: attach: irq changed from %d to %d\n", - unit, (old_irq & 0xff), (new_irq & 0xff)); -#endif - - /* - * setup the interrupt handling routine - */ - pci_map_int(tag, bktr_intr, (void*) bktr, &tty_imask); - - - /* Update the Device Control Register */ - /* on Bt878 and Bt879 cards */ - fun = pci_conf_read(tag, 0x40); - fun = fun | 1; /* Enable writes to the sub-system vendor ID */ - -#if defined( BKTR_430_FX_MODE ) - if (bootverbose) printf("Using 430 FX chipset compatibilty mode\n"); - fun = fun | 2; /* Enable Intel 430 FX compatibility mode */ -#endif - -#if defined( BKTR_SIS_VIA_MODE ) - if (bootverbose) printf("Using SiS/VIA chipset compatibilty mode\n"); - fun = fun | 4; /* Enable SiS/VIA compatibility mode (usefull for - OPTi chipset motherboards too */ -#endif - pci_conf_write(tag, 0x40, fun); - - - /* XXX call bt848_i2c dependent attach() routine */ -#if defined(BKTR_USE_FREEBSD_SMBUS) - if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc)) - printf("bktr%d: i2c_attach: can't attach\n", unit); -#endif - - -/* - * 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(tag, PCI_LATENCY_TIMER); - latency = (latency >> 8) & 0xff; - if ( bootverbose ) { - if (latency) - printf("brooktree%d: PCI bus latency is", unit); - else - printf("brooktree%d: PCI bus latency was 0 changing to", - unit); - } - if ( !latency ) { - latency = BROOKTREE_DEF_LATENCY_VALUE; - pci_conf_write(tag, PCI_LATENCY_TIMER, latency<<8); - } - if ( bootverbose ) { - printf(" %d.\n", (int) latency); - } - - - /* read the pci device id and revision id */ - fun = pci_conf_read(tag, PCI_ID_REG); - rev = pci_conf_read(tag, PCIR_REVID) & 0x000000ff; - - /* call the common attach code */ - common_bktr_attach( bktr, unit, fun, rev ); - -} - - -/* - * Special Memory Allocation - */ -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("bktr%d: Unable to allocate %d bytes of memory.\n", - unit, size); - } - - return( addr ); -} - -/*--------------------------------------------------------- -** -** 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, d_thread_t *td) -{ - bktr_ptr_t bktr; - int unit; - - unit = UNIT( minor(dev) ); - if (unit >= NBKTR) /* unit out of range */ - return( ENXIO ); - - bktr = &(brooktree[ unit ]); - - if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */ - return( ENXIO ); - - - if (bt848_card != -1) { - if ((bt848_card >> 8 == unit ) && - ( (bt848_card & 0xff) < Bt848_MAX_CARD )) { - if ( bktr->bt848_card != (bt848_card & 0xff) ) { - bktr->bt848_card = (bt848_card & 0xff); - probeCard(bktr, FALSE, unit); - } - } - } - - if (bt848_tuner != -1) { - if ((bt848_tuner >> 8 == unit ) && - ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) { - if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) { - bktr->bt848_tuner = (bt848_tuner & 0xff); - probeCard(bktr, FALSE, unit); - } - } - } - - if (bt848_reverse_mute != -1) { - if ((bt848_reverse_mute >> 8) == unit ) { - bktr->reverse_mute = bt848_reverse_mute & 0xff; - } - } - - 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: - 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, d_thread_t *td) -{ - bktr_ptr_t bktr; - int unit; - - unit = UNIT( minor(dev) ); - if (unit >= NBKTR) /* unit out of range */ - return( ENXIO ); - - bktr = &(brooktree[ 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)); - if (unit >= NBKTR) /* unit out of range */ - return( ENXIO ); - - bktr = &(brooktree[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 ) -{ - return( EINVAL ); /* XXX or ENXIO ? */ -} - -/* - * - */ -int -bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, d_thread_t *td) -{ - bktr_ptr_t bktr; - int unit; - - unit = UNIT(minor(dev)); - if (unit >= NBKTR) /* unit out of range */ - return( ENXIO ); - - bktr = &(brooktree[ 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, td ) ); - case TUNER_DEV: - return( tuner_ioctl( bktr, unit, cmd, arg, td ) ); - } - - return( ENXIO ); -} - -/* - * bktr_mmap. - * Note: 2.2.5/2.2.6/2.2.7/3.0 users must manually - * edit the line below and change "vm_offset_t" to "int" - */ -int bktr_mmap( dev_t dev, vm_offset_t offset, int nprot ) - -{ - int unit; - bktr_ptr_t bktr; - - unit = UNIT(minor(dev)); - - if (unit >= NBKTR || FUNCTION(minor(dev)) > 0) - return( -1 ); - - bktr = &(brooktree[ unit ]); - - if (nprot & PROT_EXEC) - return( -1 ); - - if (offset < 0) - return( -1 ); - - if (offset >= bktr->alloc_pages * PAGE_SIZE) - return( -1 ); - - return( i386_btop(vtophys(bktr->bigbuf) + offset) ); -} - -int bktr_poll( dev_t dev, int events, d_thread_t *td) -{ - int unit; - bktr_ptr_t bktr; - int revents = 0; - - unit = UNIT(minor(dev)); - - if (unit >= NBKTR) - return( -1 ); - - bktr = &(brooktree[ unit ]); - - disable_intr(); - - if (events & (POLLIN | POLLRDNORM)) { - - switch ( FUNCTION( minor(dev) ) ) { - case VBI_DEV: - if(bktr->vbisize == 0) - selrecord(p, &bktr->vbi_select); - else - revents |= events & (POLLIN | POLLRDNORM); - break; - } - } - - enable_intr(); - - return (revents); -} - - -#endif /* FreeBSD 2.2.x and 3.x specific kernel interface routines */ - - -/*****************/ -/* *** BSDI *** */ -/*****************/ - -#if defined(__bsdi__) -#endif /* __bsdi__ BSDI specific kernel interface routines */ - - -/*****************************/ -/* *** OpenBSD / NetBSD *** */ -/*****************************/ -#if defined(__NetBSD__) || defined(__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 - -vm_offset_t vm_page_alloc_contig(vm_offset_t, vm_offset_t, - vm_offset_t, vm_offset_t); - -#if defined(__OpenBSD__) -static int bktr_probe (struct device *, void *, void *); -#else -static int bktr_probe (struct device *, struct cfdata *, void *); -#endif -static void bktr_attach (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(__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(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, NULL, - &bktr->obmemsz); - DPR(("pci_mapreg_map: memt %x, memh %x, size %x\n", - bktr->memt, (u_int)bktr->memh, (u_int)bktr->obmemsz)); - if (retval) { - printf("%s: couldn't map memory\n", bktr_name(bktr)); - 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_name(bktr)); - 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_name(bktr)); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - return; - } - if (intrstr != NULL) - printf("%s: interrupting at %s\n", bktr_name(bktr), - 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_name(bktr), 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 - XXX: check if all old DMA is stopped first (e.g. after warm - boot) */ - 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 | PCI_COMMAND_MASTER_ENABLE); - - /* 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("%s: Unable to dmamem_alloc of %d bytes\n", - bktr_name(bktr), size); - return 0; - } - } - if (bus_dmamem_map(dmat, &seg, rseg, size, - &kva, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) { - printf("%s: Unable to dmamem_map of %d bytes\n", - bktr_name(bktr), 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("%s: Unable to dmamap_create of %d bytes\n", - bktr_name(bktr), 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("%s: Unable to dmamap_load of %d bytes\n", - bktr_name(bktr), 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) (minor((x) & 0x0f)) -#define FUNCTION(x) (minor((x >> 4) & 0x0f)) - -/* - * - */ -int -bktr_open(dev_t dev, int flags, int fmt, d_thread_t *td) -{ - bktr_ptr_t bktr; - int unit; - - unit = UNIT(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(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, d_thread_t *td) -{ - bktr_ptr_t bktr; - int unit; - - unit = UNIT(dev); - - bktr = bktr_cd.cd_devs[unit]; - - switch (FUNCTION(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(dev); - - bktr = bktr_cd.cd_devs[unit]; - - switch (FUNCTION(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, d_thread_t *td) -{ - bktr_ptr_t bktr; - int unit; - - unit = UNIT(dev); - - bktr = bktr_cd.cd_devs[unit]; - - if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */ - return(ENOMEM); - - switch (FUNCTION(dev)) { - case VIDEO_DEV: - return(video_ioctl(bktr, unit, cmd, arg, td)); - case TUNER_DEV: - return(tuner_ioctl(bktr, unit, cmd, arg, td)); - } - - return(ENXIO); -} - -/* - * - */ -paddr_t -bktr_mmap(dev_t dev, off_t offset, int nprot) -{ - int unit; - bktr_ptr_t bktr; - - unit = UNIT(dev); - - if (FUNCTION(dev) > 0) /* only allow mmap on /dev/bktr[n] */ - return(-1); - - bktr = bktr_cd.cd_devs[unit]; - - if ((vaddr_t)offset < 0) - return(-1); - - if ((vaddr_t)offset >= bktr->alloc_pages * PAGE_SIZE) - return(-1); - -#ifdef __NetBSD__ - return (bus_dmamem_mmap(bktr->dmat, bktr->dm_mem->dm_segs, 1, - (vaddr_t)offset, nprot, BUS_DMA_WAITOK)); -#else - return(i386_btop(vtophys(bktr->bigbuf) + offset)); -#endif -} - -#endif /* __NetBSD__ || __OpenBSD__ */ diff --git a/sys/dev/video/bktr/bktr_os.h b/sys/dev/video/bktr/bktr_os.h index 039c89d2db..9f2e7c3b92 100644 --- a/sys/dev/video/bktr/bktr_os.h +++ b/sys/dev/video/bktr/bktr_os.h @@ -1,5 +1,5 @@ -/* $FreeBSD: src/sys/dev/bktr/bktr_os.h,v 1.1.4.2 2000/09/11 07:59:57 roger Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_os.h,v 1.3 2004/02/13 01:45:15 joerg Exp $ */ +/* $FreeBSD: src/sys/dev/bktr/bktr_os.h,v 1.7 2003/12/01 19:03:50 truckman Exp $ */ +/* $DragonFly: src/sys/dev/video/bktr/bktr_os.h,v 1.4 2004/05/15 17:54:13 joerg Exp $ */ /* * This is part of the Driver for Video Capture Cards (Frame grabbers) @@ -48,26 +48,19 @@ /******************************/ /* *** Memory Allocation *** */ /******************************/ -#if defined(__DragonFly__) || (defined(__FreeBSD__) || defined(__bsdi__)) vm_offset_t get_bktr_mem( int unit, unsigned size ); -#endif - -#if (defined(__NetBSD__) || defined(__OpenBSD__)) -vm_offset_t get_bktr_mem(bktr_ptr_t, bus_dmamap_t *, unsigned size); -void free_bktr_mem(bktr_ptr_t, bus_dmamap_t, vm_offset_t); -#endif /************************************/ /* *** Interrupt Enable/Disable *** */ /************************************/ -#if defined(__DragonFly__) || defined(__FreeBSD__) #define DECLARE_INTR_MASK(s) intrmask_t s #define DISABLE_INTR(s) s=spltty() #define ENABLE_INTR(s) splx(s) + +#ifdef USE_VBIMUTEX +#define LOCK_VBI(bktr) mtx_lock(&bktr->vbimutex) +#define UNLOCK_VBI(bktr) mtx_unlock(&bktr->vbimutex) #else -#define DECLARE_INTR_MASK(s) /* no need to declare 's' */ -#define DISABLE_INTR(s) disable_intr() -#define ENABLE_INTR(s) enable_intr() +#define LOCK_VBI(bktr) +#define UNLOCK_VBI(bktr) #endif - - diff --git a/sys/dev/video/bktr/bktr_reg.h b/sys/dev/video/bktr/bktr_reg.h index 672bb351fa..0cacff81c0 100644 --- a/sys/dev/video/bktr/bktr_reg.h +++ b/sys/dev/video/bktr/bktr_reg.h @@ -1,6 +1,6 @@ /* - * $FreeBSD: src/sys/dev/bktr/bktr_reg.h,v 1.36.2.4 2000/11/01 09:36:14 roger Exp $ - * $DragonFly: src/sys/dev/video/bktr/bktr_reg.h,v 1.4 2004/02/13 01:45:15 joerg Exp $ + * $FreeBSD: src/sys/dev/bktr/bktr_reg.h,v 1.46 2003/12/01 19:03:50 truckman Exp $ + * $DragonFly: src/sys/dev/video/bktr/bktr_reg.h,v 1.5 2004/05/15 17:54:13 joerg Exp $ * * Copyright (c) 1999 Roger Hardiman * Copyright (c) 1998 Amancio Hasty @@ -35,34 +35,11 @@ * */ -#if defined(__DragonFly__) || defined(__FreeBSD__) -# if defined(__DragonFly__) || (__FreeBSD_version >= 310000) -# include "use_smbus.h" -# else -# define NSMBUS 0 /* FreeBSD before 3.1 does not have SMBUS */ -# endif -# if (NSMBUS > 0) -# define BKTR_USE_FREEBSD_SMBUS -# endif -#endif - -#ifdef __NetBSD__ -#include /* struct device */ -#include -#include /* struct selinfo */ -# ifdef DEBUG -# define bootverbose 1 -# else -# define bootverbose 0 -# endif -#endif - /* * The kernel options for the driver now all begin with BKTR. * Support the older kernel options on FreeBSD and OpenBSD. * */ -#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) #if defined(BROOKTREE_ALLOC_PAGES) #define BKTR_ALLOC_PAGES BROOKTREE_ALLOC_PAGES #endif @@ -87,9 +64,6 @@ #define BKTR_OVERRIDE_MSP OVERRIDE_MSP #endif -#endif - - #ifndef PCI_LATENCY_TIMER #define PCI_LATENCY_TIMER 0x0c /* pci timer register */ #endif @@ -97,7 +71,6 @@ /* * Definitions for the Brooktree 848/878 video capture to pci interface. */ -#ifndef __NetBSD__ #define PCI_VENDOR_SHIFT 0 #define PCI_VENDOR_MASK 0xffff #define PCI_VENDOR(id) \ @@ -108,15 +81,6 @@ #define PCI_PRODUCT(id) \ (((id) >> PCI_PRODUCT_SHIFT) & PCI_PRODUCT_MASK) -/* PCI vendor ID */ -#define PCI_VENDOR_BROOKTREE 0x109e /* Brooktree */ -/* Brooktree products */ -#define PCI_PRODUCT_BROOKTREE_BT848 0x0350 /* Bt848 Video Capture */ -#define PCI_PRODUCT_BROOKTREE_BT849 0x0351 /* Bt849 Video Capture */ -#define PCI_PRODUCT_BROOKTREE_BT878 0x036e /* Bt878 Video Capture */ -#define PCI_PRODUCT_BROOKTREE_BT879 0x036f /* Bt879 Video Capture */ -#endif - #define BROOKTREE_848 1 #define BROOKTREE_848A 2 #define BROOKTREE_849A 3 @@ -458,7 +422,9 @@ struct format_params { #if defined(BKTR_USE_FREEBSD_SMBUS) struct bktr_i2c_softc { - device_t iicbus; + int bus_owned; + + device_t iicbb; device_t smbus; }; #endif @@ -471,22 +437,12 @@ struct bktr_i2c_softc { * memory mapped structure method only works on 32 bit processors * with the right type of endianness. */ -#if defined(__DragonFly__) || 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; @@ -494,52 +450,6 @@ typedef struct bktr_clip bktr_clip_t; * BrookTree 848 info structure, one per bt848 card installed. */ struct bktr_softc { - -#if defined (__bsdi__) - struct device bktr_dev; /* base device */ - struct isadev bktr_id; /* ISA device */ - struct intrhand bktr_ih; /* interrupt vectoring */ - #define pcici_t pci_devaddr_t -#endif - -#if defined(__NetBSD__) - struct device bktr_dev; /* base device */ - bus_dma_tag_t dmat; /* DMA tag */ - bus_space_tag_t memt; - bus_space_handle_t memh; - bus_size_t obmemsz; /* size of en card (bytes) */ - void *ih; - bus_dmamap_t dm_prog; - bus_dmamap_t dm_oprog; - bus_dmamap_t dm_mem; - bus_dmamap_t dm_vbidata; - bus_dmamap_t dm_vbibuffer; -#endif - -#if defined(__OpenBSD__) - struct device bktr_dev; /* base device */ - bus_dma_tag_t dmat; /* DMA tag */ - bus_space_tag_t memt; - bus_space_handle_t memh; - bus_size_t obmemsz; /* size of en card (bytes) */ - void *ih; - bus_dmamap_t dm_prog; - bus_dmamap_t dm_oprog; - bus_dmamap_t dm_mem; - bus_dmamap_t dm_vbidata; - bus_dmamap_t dm_vbibuffer; - size_t dm_mapsize; - pci_chipset_tag_t pc; /* Opaque PCI chipset tag */ - pcitag_t tag; /* PCI tag, for doing PCI commands */ - vm_offset_t phys_base; /* Bt848 register physical address */ -#endif - -#if defined(__DragonFly__) || defined (__FreeBSD__) -# if defined(__FreeBSD__) && (__FreeBSD_version < 400000) - vm_offset_t phys_base; /* 2.x Bt848 register physical address */ - pcici_t tag; /* 2.x PCI tag, for doing PCI commands */ -# endif -# if defined(__DragonFly__) || (__FreeBSD_version >= 400000) int mem_rid; /* 4.x resource id */ struct resource *res_mem; /* 4.x resource descriptor for registers */ int irq_rid; /* 4.x resource id */ @@ -551,34 +461,19 @@ struct bktr_softc { dev_t bktrdev_alias; /* alias /dev/bktr to /dev/bktr0 */ dev_t tunerdev_alias; /* alias /dev/tuner to /dev/tuner0 */ dev_t vbidev_alias; /* alias /dev/vbi to /dev/vbi0 */ - #endif -# if defined(__DragonFly__) || (__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) +#if defined(BKTR_USE_FREEBSD_SMBUS) struct bktr_i2c_softc i2c_sc; /* bt848_i2c device */ -# endif - char bktr_xname[7]; /* device name and unit number */ #endif + char bktr_xname[7]; /* device name and unit number */ - - /* The following definitions are for the contiguous memory */ -#ifdef __NetBSD__ - vaddr_t bigbuf; /* buffer that holds the captured image */ - vaddr_t vbidata; /* RISC program puts VBI data from the current frame here */ - vaddr_t vbibuffer; /* Circular buffer holding VBI data for the user */ - vaddr_t dma_prog; /* RISC prog for single and/or even field capture*/ - vaddr_t odd_dma_prog; /* RISC program for Odd field capture */ -#else vm_offset_t bigbuf; /* buffer that holds the captured image */ vm_offset_t vbidata; /* RISC program puts VBI data from the current frame here */ vm_offset_t vbibuffer; /* Circular buffer holding VBI data for the user */ vm_offset_t dma_prog; /* RISC prog for single and/or even field capture*/ vm_offset_t odd_dma_prog;/* RISC program for Odd field capture */ -#endif - /* the following definitions are common over all platforms */ int alloc_pages; /* number of pages in bigbuf */ @@ -705,6 +600,15 @@ struct bktr_softc { int audio_mux_present; /* 1 = has audio mux on GPIO lines, 0 = no audio mux */ int msp_source_selected; /* 0 = TV source, 1 = Line In source, 2 = FM Radio Source */ +#ifdef BKTR_NEW_MSP34XX_DRIVER + /* msp3400c related data */ + void * msp3400c_info; + int stereo_once; + int amsound; + int mspsimple; + int dolby; +#endif + }; typedef struct bktr_softc bktr_reg_t; @@ -723,18 +627,4 @@ struct bt848_card_sig { /* ioctl_cmd_t int on old versions, u_long on new versions */ /***********************************************************/ -#if defined(__FreeBSD__) && (__FreeBSD__ == 2) -typedef int ioctl_cmd_t; -#endif - -#if defined(__DragonFly__) || defined(__FreeBSD__) -#if defined(__DragonFly__) || (__FreeBSD_version >= 300000) typedef u_long ioctl_cmd_t; -#endif -#endif - -#if defined(__NetBSD__) || defined(__OpenBSD__) -typedef u_long ioctl_cmd_t; -#endif - - diff --git a/sys/dev/video/bktr/bktr_tuner.c b/sys/dev/video/bktr/bktr_tuner.c index 770d914551..8383a2db97 100644 --- a/sys/dev/video/bktr/bktr_tuner.c +++ b/sys/dev/video/bktr/bktr_tuner.c @@ -1,16 +1,3 @@ -/* $FreeBSD: src/sys/dev/bktr/bktr_tuner.c,v 1.5.2.3 2000/10/26 16:38:46 roger Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_tuner.c,v 1.5 2004/02/13 01:45:15 joerg Exp $ */ - -/* - * This is part of the Driver for Video Capture Cards (Frame grabbers) - * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 - * chipset. - * Copyright Roger Hardiman and Amancio Hasty. - * - * bktr_tuner : This deals with controlling the tuner fitted to TV cards. - * - */ - /* * 1. Redistributions of source code must retain the * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman @@ -42,46 +29,38 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/dev/bktr/bktr_tuner.c,v 1.12 2003/12/08 07:59:18 obrien Exp $ + * $DragonFly: src/sys/dev/video/bktr/bktr_tuner.c,v 1.6 2004/05/15 17:54:13 joerg Exp $ */ +/* + * This is part of the Driver for Video Capture Cards (Frame grabbers) + * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 + * chipset. + * Copyright Roger Hardiman and Amancio Hasty. + * + * bktr_tuner : This deals with controlling the tuner fitted to TV cards. + */ #include #include #include #include -#ifdef __NetBSD__ -#include -#endif -#if defined(__DragonFly__) || defined(__FreeBSD__) #include -#if defined(__DragonFly__) || (__FreeBSD_version < 500000) -#include /* for DELAY */ -#endif - -#if defined(__DragonFly__) || (__FreeBSD_version >=300000) #include /* for bus space */ #include #include -#endif -#endif -#ifdef __NetBSD__ -#include /* NetBSD .h file location */ -#include -#include -#include -#include -#else -#include /* Traditional .h file location */ -#include /* extensions to ioctl_meteor.h */ -#include "bktr_reg.h" -#include "bktr_tuner.h" -#include "bktr_card.h" -#include "bktr_core.h" -#endif +#include +#include /* extensions to ioctl_meteor.h */ +#include +#include +#include +#include diff --git a/sys/dev/video/bktr/bktr_tuner.h b/sys/dev/video/bktr/bktr_tuner.h index 75e369a037..3eb451e850 100644 --- a/sys/dev/video/bktr/bktr_tuner.h +++ b/sys/dev/video/bktr/bktr_tuner.h @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/dev/bktr/bktr_tuner.h,v 1.1 1999/09/26 22:06:20 roger Exp $ */ -/* $DragonFly: src/sys/dev/video/bktr/bktr_tuner.h,v 1.2 2003/06/17 04:28:23 dillon Exp $ */ +/* $DragonFly: src/sys/dev/video/bktr/bktr_tuner.h,v 1.3 2004/05/15 17:54:13 joerg Exp $ */ /* * This is part of the Driver for Video Capture Cards (Frame grabbers) @@ -100,5 +100,3 @@ int do_afc( bktr_ptr_t bktr, int addr, int frequency ); #if !defined( DEFAULT_CHNLSET ) #define DEFAULT_CHNLSET CHNLSET_WEUROPE #endif - - diff --git a/sys/i386/include/ioctl_bt848.h b/sys/dev/video/bktr/ioctl_bt848.h similarity index 97% rename from sys/i386/include/ioctl_bt848.h rename to sys/dev/video/bktr/ioctl_bt848.h index 0b712db949..6378d80876 100644 --- a/sys/i386/include/ioctl_bt848.h +++ b/sys/dev/video/bktr/ioctl_bt848.h @@ -1,12 +1,12 @@ /* * extensions to ioctl_meteor.h for the bt848 cards * - * $FreeBSD: src/sys/i386/include/ioctl_bt848.h,v 1.25.2.3 2000/10/31 14:31:27 roger Exp $ - * $DragonFly: src/sys/i386/include/Attic/ioctl_bt848.h,v 1.2 2003/06/17 04:28:35 dillon Exp $ + * $FreeBSD: src/sys/dev/bktr/ioctl_bt848.h,v 1.30 2003/12/20 17:12:25 obrien Exp $ + * $DragonFly: src/sys/dev/video/bktr/ioctl_bt848.h,v 1.1 2004/05/15 17:54:13 joerg Exp $ */ -#ifndef _MACHINE_IOCTL_BT848_H_ -#define _MACHINE_IOCTL_BT848_H_ +#ifndef _DEV_BKTR_IOCTL_BT848_H_ +#define _DEV_BKTR_IOCTL_BT848_H_ /* * frequency sets @@ -295,5 +295,4 @@ struct bktr_remote { # define BT848_IFORM_F_AUTO (0x0) -#endif /* _MACHINE_IOCTL_BT848_H_ */ - +#endif /* _DEV_BKTR_IOCTL_BT848_H_ */ diff --git a/sys/dev/video/bktr/msp34xx.c b/sys/dev/video/bktr/msp34xx.c new file mode 100644 index 0000000000..50bcb96c69 --- /dev/null +++ b/sys/dev/video/bktr/msp34xx.c @@ -0,0 +1,1259 @@ +/* + * Copyright (c) 1997-2001 Gerd Knorr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/dev/bktr/msp34xx.c,v 1.3 2003/12/12 21:18:04 rwatson Exp $ + * $DragonFly: src/sys/dev/video/bktr/msp34xx.c,v 1.1 2004/05/15 17:54:13 joerg Exp $ + */ + +/* + * programming the msp34* sound processor family + * + * (c) 1997-2001 Gerd Knorr + * + * what works and what doesn't: + * + * AM-Mono + * Support for Hauppauge cards added (decoding handled by tuner) added by + * Frederic Crozat + * + * FM-Mono + * should work. The stereo modes are backward compatible to FM-mono, + * therefore FM-Mono should be allways available. + * + * FM-Stereo (B/G, used in germany) + * should work, with autodetect + * + * FM-Stereo (satellite) + * should work, no autodetect (i.e. default is mono, but you can + * switch to stereo -- untested) + * + * NICAM (B/G, L , used in UK, Scandinavia, Spain and France) + * should work, with autodetect. Support for NICAM was added by + * Pekka Pietikainen + * + * + * TODO: + * - better SAT support + * + * + * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch) + * using soundcore instead of OSS + * + * + * The FreeBSD modifications by Alexander Langer + * are in the public domain. Please contact me (Alex) and not Gerd for + * any problems you encounter under FreeBSD. + * + * FreeBSD TODO: + * - mutex handling (currently not mp-safe) + * - the various options here as loader tunables or compile time or whatever + * - how does the new dolby flag work with the current dpl_* stuff? + * Maybe it's just enough to set the dolby flag to 1 and it works. + * As I don't have a dolby card myself, I can't test it, though. + */ + +#include "opt_bktr.h" /* Include any kernel config options */ +#ifdef BKTR_NEW_MSP34XX_DRIVER /* file only needed for new driver */ + +#include +#include +#include +#include + +#include +#include +#include + +#include /* required by bktr_reg.h */ + +#include +#include /* extensions to ioctl_meteor.h */ +#include +#include +#include +#include + +#define VIDEO_MODE_PAL 0 +#define VIDEO_MODE_NTSC 1 +#define VIDEO_MODE_SECAM 2 +#define VIDEO_MODE_AUTO 3 + +#define VIDEO_SOUND_MONO 1 +#define VIDEO_SOUND_STEREO 2 +#define VIDEO_SOUND_LANG1 4 +#define VIDEO_SOUND_LANG2 8 + +#define DFP_COUNT 0x41 +static const int bl_dfp[] = { + 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a, + 0x0b, 0x0d, 0x0e, 0x10 +}; + +struct msp3400c { + int simple; + int nicam; + int mode; + int norm; + int stereo; + int nicam_on; + int acb; + int main, second; /* sound carrier */ + int input; + + int muted; + int left, right; /* volume */ + int bass, treble; + + /* shadow register set */ + int dfp_regs[DFP_COUNT]; + + /* thread */ + struct proc *kthread; + char *threaddesc; + + int active,restart,rmmod; + + int watch_stereo; + int halt_thread; +}; + +#define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */ + +/* ---------------------------------------------------------------------- */ + +#define dprintk(args) do { \ + if (bootverbose) { \ + printf("%s: ", bktr_name(client)); \ + printf args; \ + } \ +} while (0) + +/* ---------------------------------------------------------------------- */ + +#define I2C_MSP3400C 0x80 +#define I2C_MSP3400C_DEM 0x10 +#define I2C_MSP3400C_DFP 0x12 + +/* ----------------------------------------------------------------------- */ +/* functions for talking to the MSP3400C Sound processor */ + +static int msp3400c_reset(bktr_ptr_t client) +{ + /* use our own which handles config(8) options */ + msp_dpl_reset(client, client->msp_addr); + + return 0; +} + +static int +msp3400c_read(bktr_ptr_t client, int dev, int addr) +{ + /* use our own */ + return(msp_dpl_read(client, client->msp_addr, dev, addr)); +} + +static int +msp3400c_write(bktr_ptr_t client, int dev, int addr, int val) +{ + /* use our own */ + msp_dpl_write(client, client->msp_addr, dev, addr, val); + + return(0); +} + +/* ------------------------------------------------------------------------ */ + +/* This macro is allowed for *constants* only, gcc must calculate it + at compile time. Remember -- no floats in kernel mode */ +#define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24))) + +#define MSP_MODE_AM_DETECT 0 +#define MSP_MODE_FM_RADIO 2 +#define MSP_MODE_FM_TERRA 3 +#define MSP_MODE_FM_SAT 4 +#define MSP_MODE_FM_NICAM1 5 +#define MSP_MODE_FM_NICAM2 6 +#define MSP_MODE_AM_NICAM 7 +#define MSP_MODE_BTSC 8 +#define MSP_MODE_EXTERN 9 + +static struct MSP_INIT_DATA_DEM { + int fir1[6]; + int fir2[6]; + int cdo1; + int cdo2; + int ad_cv; + int mode_reg; + int dfp_src; + int dfp_matrix; +} msp_init_data[] = { + /* AM (for carrier detect / msp3400) */ + { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 }, + MSP_CARRIER(5.5), MSP_CARRIER(5.5), + 0x00d0, 0x0500, 0x0020, 0x3000}, + + /* AM (for carrier detect / msp3410) */ + { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 }, + MSP_CARRIER(5.5), MSP_CARRIER(5.5), + 0x00d0, 0x0100, 0x0020, 0x3000}, + + /* FM Radio */ + { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 }, + MSP_CARRIER(10.7), MSP_CARRIER(10.7), + 0x00d0, 0x0480, 0x0020, 0x3000 }, + + /* Terrestial FM-mono + FM-stereo */ + { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 }, + MSP_CARRIER(5.5), MSP_CARRIER(5.5), + 0x00d0, 0x0480, 0x0030, 0x3000}, + + /* Sat FM-mono */ + { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 }, + MSP_CARRIER(6.5), MSP_CARRIER(6.5), + 0x00c6, 0x0480, 0x0000, 0x3000}, + + /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ + { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 }, + MSP_CARRIER(5.5), MSP_CARRIER(5.5), + 0x00d0, 0x0040, 0x0120, 0x3000}, + + /* NICAM/FM -- I (6.0/6.552) */ + { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 }, + MSP_CARRIER(6.0), MSP_CARRIER(6.0), + 0x00d0, 0x0040, 0x0120, 0x3000}, + + /* NICAM/AM -- L (6.5/5.85) */ + { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 }, + MSP_CARRIER(6.5), MSP_CARRIER(6.5), + 0x00c6, 0x0140, 0x0120, 0x7c03}, +}; + +struct CARRIER_DETECT { + int cdo; + char *name; +}; + +static struct CARRIER_DETECT carrier_detect_main[] = { + /* main carrier */ + { MSP_CARRIER(4.5), "4.5 NTSC" }, + { MSP_CARRIER(5.5), "5.5 PAL B/G" }, + { MSP_CARRIER(6.0), "6.0 PAL I" }, + { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" } +}; + +static struct CARRIER_DETECT carrier_detect_55[] = { + /* PAL B/G */ + { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" }, + { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" } +}; + +static struct CARRIER_DETECT carrier_detect_65[] = { + /* PAL SAT / SECAM */ + { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" }, + { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" }, + { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" }, + { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" }, + { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" }, + { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" }, +}; + +#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) + +/* ----------------------------------------------------------------------- */ + +#define SCART_MASK 0 +#define SCART_IN1 1 +#define SCART_IN2 2 +#define SCART_IN1_DA 3 +#define SCART_IN2_DA 4 +#define SCART_IN3 5 +#define SCART_IN4 6 +#define SCART_MONO 7 +#define SCART_MUTE 8 + +static int scarts[3][9] = { + /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ + { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, + { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, + { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, +}; + +static char *scart_names[] = { + "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" +}; + +static void +msp3400c_set_scart(bktr_ptr_t client, int in, int out) +{ + struct msp3400c *msp = client->msp3400c_info; + + if (-1 == scarts[out][in]) + return; + + dprintk(("msp34xx: scart switch: %s => %d\n", scart_names[in], out)); + msp->acb &= ~scarts[out][SCART_MASK]; + msp->acb |= scarts[out][in]; + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb); +} + +/* ------------------------------------------------------------------------ */ + +static void msp3400c_setcarrier(bktr_ptr_t client, int cdo1, int cdo2) +{ + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff); + msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12); + msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff); + msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12); + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/ +} + +static void msp3400c_setvolume(bktr_ptr_t client, + int muted, int left, int right) +{ + int vol = 0,val = 0,balance = 0; + + if (!muted) { + vol = (left > right) ? left : right; + val = (vol * 0x73 / 65535) << 8; + } + if (vol > 0) { + balance = ((right-left) * 127) / vol; + } + + dprintk(("msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", + muted ? "on" : "off", left, right, val>>8, balance)); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ + /* scart - on/off only */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, val ? 0x4000 : 0); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, balance << 8); +} + +static void msp3400c_setbass(bktr_ptr_t client, int bass) +{ + int val = ((bass-32768) * 0x60 / 65535) << 8; + + dprintk(("msp34xx: setbass: %d 0x%02x\n",bass, val>>8)); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ +} + +static void msp3400c_settreble(bktr_ptr_t client, int treble) +{ + int val = ((treble-32768) * 0x60 / 65535) << 8; + + dprintk(("msp34xx: settreble: %d 0x%02x\n",treble, val>>8)); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ +} + +static void msp3400c_setmode(bktr_ptr_t client, int type) +{ + struct msp3400c *msp = client->msp3400c_info; + int i; + + dprintk(("msp3400: setmode: %d\n",type)); + msp->mode = type; + msp->stereo = VIDEO_SOUND_MONO; + + msp3400c_write(client,I2C_MSP3400C_DEM, 0x00bb, /* ad_cv */ + msp_init_data[type].ad_cv); + + for (i = 5; i >= 0; i--) /* fir 1 */ + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0001, + msp_init_data[type].fir1[i]); + + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */ + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0040); + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0000); + for (i = 5; i >= 0; i--) + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, + msp_init_data[type].fir2[i]); + + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0083, /* MODE_REG */ + msp_init_data[type].mode_reg); + + msp3400c_setcarrier(client, msp_init_data[type].cdo1, + msp_init_data[type].cdo2); + + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/ + + if (client->dolby) { + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008, + 0x0520); /* I2S1 */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009, + 0x0620); /* I2S2 */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b, + msp_init_data[type].dfp_src); + } else { + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008, + msp_init_data[type].dfp_src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009, + msp_init_data[type].dfp_src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b, + msp_init_data[type].dfp_src); + } + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a, + msp_init_data[type].dfp_src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, + msp_init_data[type].dfp_matrix); + + if (msp->nicam) { + /* nicam prescale */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */ + } +} + +/* turn on/off nicam + stereo */ +static void msp3400c_setstereo(bktr_ptr_t client, int mode) +{ + static char *strmode[] = { "0", "mono", "stereo", "3", + "lang1", "5", "6", "7", "lang2" }; + struct msp3400c *msp = client->msp3400c_info; + int nicam=0; /* channel source: FM/AM or nicam */ + int src=0; + + /* switch demodulator */ + switch (msp->mode) { + case MSP_MODE_FM_TERRA: + dprintk(("msp3400: FM setstereo: %s\n",strmode[mode])); + msp3400c_setcarrier(client,msp->second,msp->main); + switch (mode) { + case VIDEO_SOUND_STEREO: + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); + break; + case VIDEO_SOUND_MONO: + case VIDEO_SOUND_LANG1: + case VIDEO_SOUND_LANG2: + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000); + break; + } + break; + case MSP_MODE_FM_SAT: + dprintk(("msp3400: SAT setstereo: %s\n",strmode[mode])); + switch (mode) { + case VIDEO_SOUND_MONO: + msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); + break; + case VIDEO_SOUND_STEREO: + msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); + break; + case VIDEO_SOUND_LANG1: + msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); + break; + case VIDEO_SOUND_LANG2: + msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); + break; + } + break; + case MSP_MODE_FM_NICAM1: + case MSP_MODE_FM_NICAM2: + case MSP_MODE_AM_NICAM: + dprintk(("msp3400: NICAM setstereo: %s\n",strmode[mode])); + msp3400c_setcarrier(client,msp->second,msp->main); + if (msp->nicam_on) + nicam=0x0100; + break; + case MSP_MODE_BTSC: + dprintk(("msp3400: BTSC setstereo: %s\n",strmode[mode])); + nicam=0x0300; + break; + case MSP_MODE_EXTERN: + dprintk(("msp3400: extern setstereo: %s\n",strmode[mode])); + nicam = 0x0200; + break; + case MSP_MODE_FM_RADIO: + dprintk(("msp3400: FM-Radio setstereo: %s\n",strmode[mode])); + break; + default: + dprintk(("msp3400: mono setstereo\n")); + return; + } + + /* switch audio */ + switch (mode) { + case VIDEO_SOUND_STEREO: + src = 0x0020 | nicam; +#if 0 + /* spatial effect */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0005,0x4000); +#endif + break; + case VIDEO_SOUND_MONO: + if (msp->mode == MSP_MODE_AM_NICAM) { + dprintk(("msp3400: switching to AM mono\n")); + /* AM mono decoding is handled by tuner, not MSP chip */ + /* SCART switching control register */ + msp3400c_set_scart(client,SCART_MONO,0); + src = 0x0200; + break; + } + case VIDEO_SOUND_LANG1: + src = 0x0000 | nicam; + break; + case VIDEO_SOUND_LANG2: + src = 0x0010 | nicam; + break; + } + dprintk(("msp3400: setstereo final source/matrix = 0x%x\n", src)); + + if (client->dolby) { + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src); + } else { + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src); + } +} + +static void +msp3400c_print_mode(struct msp3400c *msp) +{ + if (msp->main == msp->second) { + printf("bktr: msp3400: mono sound carrier: %d.%03d MHz\n", + msp->main/910000,(msp->main/910)%1000); + } else { + printf("bktr: msp3400: main sound carrier: %d.%03d MHz\n", + msp->main/910000,(msp->main/910)%1000); + } + if (msp->mode == MSP_MODE_FM_NICAM1 || + msp->mode == MSP_MODE_FM_NICAM2) + printf("bktr: msp3400: NICAM/FM carrier : %d.%03d MHz\n", + msp->second/910000,(msp->second/910)%1000); + if (msp->mode == MSP_MODE_AM_NICAM) + printf("bktr: msp3400: NICAM/AM carrier : %d.%03d MHz\n", + msp->second/910000,(msp->second/910)%1000); + if (msp->mode == MSP_MODE_FM_TERRA && + msp->main != msp->second) { + printf("bktr: msp3400: FM-stereo carrier : %d.%03d MHz\n", + msp->second/910000,(msp->second/910)%1000); + } +} + +static void +msp3400c_restore_dfp(bktr_ptr_t client) +{ + struct msp3400c *msp = (struct msp3400c*)client->msp3400c_info; + int i; + + for (i = 0; i < DFP_COUNT; i++) { + if (-1 == msp->dfp_regs[i]) + continue; + msp3400c_write(client,I2C_MSP3400C_DFP, i, msp->dfp_regs[i]); + } +} + +/* ----------------------------------------------------------------------- */ + +struct REGISTER_DUMP { + int addr; + char *name; +}; + +struct REGISTER_DUMP d1[] = { + { 0x007e, "autodetect" }, + { 0x0023, "C_AD_BITS " }, + { 0x0038, "ADD_BITS " }, + { 0x003e, "CIB_BITS " }, + { 0x0057, "ERROR_RATE" }, +}; + +static int +autodetect_stereo(bktr_ptr_t client) +{ + struct msp3400c *msp = (struct msp3400c*)client->msp3400c_info; + int val; + int newstereo = msp->stereo; + int newnicam = msp->nicam_on; + int update = 0; + + switch (msp->mode) { + case MSP_MODE_FM_TERRA: + val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); + if (val > 32767) + val -= 65536; + dprintk(("msp34xx: stereo detect register: %d\n",val)); + + if (val > 4096) { + newstereo = VIDEO_SOUND_STEREO | VIDEO_SOUND_MONO; + } else if (val < -4096) { + newstereo = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; + } else { + newstereo = VIDEO_SOUND_MONO; + } + newnicam = 0; + break; + case MSP_MODE_FM_NICAM1: + case MSP_MODE_FM_NICAM2: + case MSP_MODE_AM_NICAM: + val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); + dprintk(("msp34xx: nicam sync=%d, mode=%d\n", + val & 1, (val & 0x1e) >> 1)); + + if (val & 1) { + /* nicam synced */ + switch ((val & 0x1e) >> 1) { + case 0: + case 8: + newstereo = VIDEO_SOUND_STEREO; + break; + case 1: + case 9: + newstereo = VIDEO_SOUND_MONO + | VIDEO_SOUND_LANG1; + break; + case 2: + case 10: + newstereo = VIDEO_SOUND_MONO + | VIDEO_SOUND_LANG1 + | VIDEO_SOUND_LANG2; + break; + default: + newstereo = VIDEO_SOUND_MONO; + break; + } + newnicam=1; + } else { + newnicam = 0; + newstereo = VIDEO_SOUND_MONO; + } + break; + case MSP_MODE_BTSC: + val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); + dprintk(("msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n", + val, + (val & 0x0002) ? "no" : "yes", + (val & 0x0004) ? "no" : "yes", + (val & 0x0040) ? "stereo" : "mono", + (val & 0x0080) ? ", nicam 2nd mono" : "", + (val & 0x0100) ? ", bilingual/SAP" : "")); + newstereo = VIDEO_SOUND_MONO; + if (val & 0x0040) newstereo |= VIDEO_SOUND_STEREO; + if (val & 0x0100) newstereo |= VIDEO_SOUND_LANG1; + break; + } + if (newstereo != msp->stereo) { + update = 1; + dprintk(("msp34xx: watch: stereo %d => %d\n", + msp->stereo,newstereo)); + msp->stereo = newstereo; + } + if (newnicam != msp->nicam_on) { + update = 1; + dprintk(("msp34xx: watch: nicam %d => %d\n", + msp->nicam_on,newnicam)); + msp->nicam_on = newnicam; + } + return update; +} + +/* + * A kernel thread for msp3400 control -- we don't want to block the + * in the ioctl while doing the sound carrier & stereo detect + */ + +/* stereo/multilang monitoring */ +static void watch_stereo(bktr_ptr_t client) +{ + struct msp3400c *msp = (struct msp3400c*)client->msp3400c_info; + + if (autodetect_stereo(client)) { + if (msp->stereo & VIDEO_SOUND_STEREO) + msp3400c_setstereo(client,VIDEO_SOUND_STEREO); + else if (msp->stereo & VIDEO_SOUND_LANG1) + msp3400c_setstereo(client,VIDEO_SOUND_LANG1); + else + msp3400c_setstereo(client,VIDEO_SOUND_MONO); + } + if (client->stereo_once) + msp->watch_stereo = 0; + +} + +static void msp3400c_thread(void *data) +{ + bktr_ptr_t client = data; + struct msp3400c *msp = (struct msp3400c*)client->msp3400c_info; + + struct CARRIER_DETECT *cd; + int count, max1,max2,val1,val2, val,this; + + dprintk(("msp3400: thread started\n")); + + for (;;) { + if (msp->rmmod) + goto done; + tsleep(msp->kthread, 0, "idle", 0); + if (msp->rmmod) + goto done; + if (msp->halt_thread) { + msp->watch_stereo = 0; + msp->halt_thread = 0; + continue; + } + + if (VIDEO_MODE_RADIO == msp->norm || + MSP_MODE_EXTERN == msp->mode) + continue; /* nothing to do */ + + msp->active = 1; + + if (msp->watch_stereo) { + watch_stereo(client); + msp->active = 0; + continue; + } + + /* some time for the tuner to sync */ + tsleep(msp->kthread, 0, "tuner sync", hz/2); + + restart: + if (VIDEO_MODE_RADIO == msp->norm || + MSP_MODE_EXTERN == msp->mode) + continue; /* nothing to do */ + msp->restart = 0; + msp3400c_setvolume(client, msp->muted, 0, 0); + msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ ); + val1 = val2 = 0; + max1 = max2 = -1; + msp->watch_stereo = 0; + + /* carrier detect pass #1 -- main carrier */ + cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main); + + if (client->amsound && (msp->norm == VIDEO_MODE_SECAM)) { + /* autodetect doesn't work well with AM ... */ + max1 = 3; + count = 0; + dprintk(("msp3400: AM sound override\n")); + } + + for (this = 0; this < count; this++) { + msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); + + tsleep(msp->kthread, 0, "carrier detect", hz/100); + + if (msp->restart) + msp->restart = 0; + + val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b); + if (val > 32767) + val -= 65536; + if (val1 < val) + val1 = val, max1 = this; + dprintk(("msp3400: carrier1 val: %5d / %s\n", val, + cd[this].name)); + } + + /* carrier detect pass #2 -- second (stereo) carrier */ + switch (max1) { + case 1: /* 5.5 */ + cd = carrier_detect_55; count = CARRIER_COUNT(carrier_detect_55); + break; + case 3: /* 6.5 */ + cd = carrier_detect_65; count = CARRIER_COUNT(carrier_detect_65); + break; + case 0: /* 4.5 */ + case 2: /* 6.0 */ + default: + cd = NULL; count = 0; + break; + } + + if (client->amsound && (msp->norm == VIDEO_MODE_SECAM)) { + /* autodetect doesn't work well with AM ... */ + cd = NULL; count = 0; max2 = 0; + } + for (this = 0; this < count; this++) { + msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); + + tsleep(msp->kthread, 0, "carrier detection", hz/100); + if (msp->restart) + goto restart; + + val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b); + if (val > 32767) + val -= 65536; + if (val2 < val) + val2 = val, max2 = this; + dprintk(("msp3400: carrier2 val: %5d / %s\n", val, + cd[this].name)); + } + + /* programm the msp3400 according to the results */ + msp->main = carrier_detect_main[max1].cdo; + switch (max1) { + case 1: /* 5.5 */ + if (max2 == 0) { + /* B/G FM-stereo */ + msp->second = carrier_detect_55[max2].cdo; + msp3400c_setmode(client, MSP_MODE_FM_TERRA); + msp->nicam_on = 0; + /* XXX why mono? this probably can do stereo... - Alex*/ + msp3400c_setstereo(client, VIDEO_SOUND_MONO); + msp->watch_stereo = 1; + } else if (max2 == 1 && msp->nicam) { + /* B/G NICAM */ + msp->second = carrier_detect_55[max2].cdo; + msp3400c_setmode(client, MSP_MODE_FM_NICAM1); + msp->nicam_on = 1; + msp3400c_setcarrier(client, msp->second, msp->main); + msp->watch_stereo = 1; + } else { + goto no_second; + } + break; + case 2: /* 6.0 */ + /* PAL I NICAM */ + msp->second = MSP_CARRIER(6.552); + msp3400c_setmode(client, MSP_MODE_FM_NICAM2); + msp->nicam_on = 1; + msp3400c_setcarrier(client, msp->second, msp->main); + msp->watch_stereo = 1; + break; + case 3: /* 6.5 */ + if (max2 == 1 || max2 == 2) { + /* D/K FM-stereo */ + msp->second = carrier_detect_65[max2].cdo; + msp3400c_setmode(client, MSP_MODE_FM_TERRA); + msp->nicam_on = 0; + msp3400c_setstereo(client, VIDEO_SOUND_MONO); + msp->watch_stereo = 1; + } else if (max2 == 0 && + msp->norm == VIDEO_MODE_SECAM) { + /* L NICAM or AM-mono */ + msp->second = carrier_detect_65[max2].cdo; + msp3400c_setmode(client, MSP_MODE_AM_NICAM); + msp->nicam_on = 0; + msp3400c_setstereo(client, VIDEO_SOUND_MONO); + msp3400c_setcarrier(client, msp->second, msp->main); + /* volume prescale for SCART (AM mono input) */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); + msp->watch_stereo = 1; + } else if (max2 == 0 && msp->nicam) { + /* D/K NICAM */ + msp->second = carrier_detect_65[max2].cdo; + msp3400c_setmode(client, MSP_MODE_FM_NICAM1); + msp->nicam_on = 1; + msp3400c_setcarrier(client, msp->second, msp->main); + msp->watch_stereo = 1; + } else { + goto no_second; + } + break; + case 0: /* 4.5 */ + default: + no_second: + msp->second = carrier_detect_main[max1].cdo; + msp3400c_setmode(client, MSP_MODE_FM_TERRA); + msp->nicam_on = 0; + msp3400c_setcarrier(client, msp->second, msp->main); + msp->stereo = VIDEO_SOUND_MONO; + msp3400c_setstereo(client, VIDEO_SOUND_MONO); + break; + } + + if (msp->watch_stereo) + watch_stereo(client); + + /* unmute + restore dfp registers */ + msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + msp3400c_restore_dfp(client); + + if (bootverbose) + msp3400c_print_mode(msp); + + msp->active = 0; + } + +done: + dprintk(("msp3400: thread: exit\n")); + msp->active = 0; + + msp->kthread = NULL; + wakeup(&msp->kthread); + + kthread_exit(); +} + +/* ----------------------------------------------------------------------- */ +/* this one uses the automatic sound standard detection of newer */ +/* msp34xx chip versions */ + +static struct MODES { + int retval; + int main, second; + char *name; +} modelist[] = { + { 0x0000, 0, 0, "ERROR" }, + { 0x0001, 0, 0, "autodetect start" }, + { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" }, + { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" }, + { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" }, + { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" }, + { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" }, + { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" }, + { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" }, + { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" }, + { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" }, + { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" }, + { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" }, + { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" }, + { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" }, + { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" }, + { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" }, + { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" }, + { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" }, + { -1, 0, 0, NULL }, /* EOF */ +}; + +static void msp3410d_thread(void *data) +{ + bktr_ptr_t client = data; + struct msp3400c *msp = (struct msp3400c*)client->msp3400c_info; + int mode,val,i,std; + int timo = 0; + + dprintk(("msp3410: thread started\n")); + + for (;;) { + if (msp->rmmod) + goto done; + if (!msp->watch_stereo) + timo = 0; + else + timo = 10*hz; + tsleep(msp->kthread, 0, "idle", timo); + if (msp->rmmod) + goto done; + if (msp->halt_thread) { + msp->watch_stereo = 0; + msp->halt_thread = 0; + dprintk(("msp3410: thread halted\n")); + continue; + } + + if (msp->mode == MSP_MODE_EXTERN) + continue; + + msp->active = 1; + + if (msp->watch_stereo) { + watch_stereo(client); + msp->active = 0; + continue; + } + + /* some time for the tuner to sync */ + tsleep(msp->kthread, 0, "tuner sync", hz/2); + + restart: + if (msp->mode == MSP_MODE_EXTERN) + continue; + msp->restart = 0; + msp->watch_stereo = 0; + + /* put into sane state (and mute) */ + msp3400c_reset(client); + + /* start autodetect */ + switch (msp->norm) { + case VIDEO_MODE_PAL: + mode = 0x1003; + std = 1; + break; + case VIDEO_MODE_NTSC: /* BTSC */ + mode = 0x2003; + std = 0x0020; + break; + case VIDEO_MODE_SECAM: + mode = 0x0003; + std = 1; + break; + case VIDEO_MODE_RADIO: + mode = 0x0003; + std = 0x0040; + break; + default: + mode = 0x0003; + std = 1; + break; + } + msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode); + msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std); + + if (bootverbose) { + int i; + for (i = 0; modelist[i].name != NULL; i++) + if (modelist[i].retval == std) + break; + dprintk(("msp3410: setting mode: %s (0x%04x)\n", + modelist[i].name ? modelist[i].name : "unknown", + std)); + } + + if (std != 1) { + /* programmed some specific mode */ + val = std; + } else { + /* triggered autodetect */ + for (;;) { + tsleep(msp->kthread, 0, "autodetection", hz/10); + if (msp->restart) + goto restart; + + /* check results */ + val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); + if (val < 0x07ff) + break; + dprintk(("msp3410: detection still in progress\n")); + } + } + for (i = 0; modelist[i].name != NULL; i++) + if (modelist[i].retval == val) + break; + dprintk(("msp3410: current mode: %s (0x%04x)\n", + modelist[i].name ? modelist[i].name : "unknown", + val)); + msp->main = modelist[i].main; + msp->second = modelist[i].second; + + if (client->amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { + /* autodetection has failed, let backup */ + dprintk(("msp3410: autodetection failed, switching to backup mode: %s (0x%04x)\n", + modelist[8].name ? modelist[8].name : "unknown",val)); + val = 0x0009; + msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val); + } + + /* set various prescales */ + msp3400c_write(client, I2C_MSP3400C_DFP, 0x0d, 0x1900); /* scart */ + msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM */ + msp3400c_write(client, I2C_MSP3400C_DFP, 0x10, 0x5a00); /* nicam */ + + /* set stereo */ + switch (val) { + case 0x0008: /* B/G NICAM */ + case 0x000a: /* I NICAM */ + if (val == 0x0008) + msp->mode = MSP_MODE_FM_NICAM1; + else + msp->mode = MSP_MODE_FM_NICAM2; + /* just turn on stereo */ + msp->stereo = VIDEO_SOUND_STEREO; + msp->nicam_on = 1; + msp->watch_stereo = 1; + msp3400c_setstereo(client,VIDEO_SOUND_STEREO); + break; + case 0x0009: + msp->mode = MSP_MODE_AM_NICAM; + msp->stereo = VIDEO_SOUND_MONO; + msp->nicam_on = 1; + msp3400c_setstereo(client,VIDEO_SOUND_MONO); + msp->watch_stereo = 1; + break; + case 0x0020: /* BTSC */ + /* just turn on stereo */ + msp->mode = MSP_MODE_BTSC; + msp->stereo = VIDEO_SOUND_STEREO; + msp->nicam_on = 0; + msp->watch_stereo = 1; + msp3400c_setstereo(client,VIDEO_SOUND_STEREO); + break; + case 0x0040: /* FM radio */ + msp->mode = MSP_MODE_FM_RADIO; + msp->stereo = VIDEO_SOUND_STEREO; + msp->nicam_on = 0; + msp->watch_stereo = 0; + /* scart routing */ + msp3400c_set_scart(client,SCART_IN2,0); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0220); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0220); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0220); + break; + case 0x0003: + msp->mode = MSP_MODE_FM_TERRA; + msp->stereo = VIDEO_SOUND_STEREO; + msp->nicam_on = 0; + msp->watch_stereo = 1; + msp3400c_setstereo(client,VIDEO_SOUND_STEREO); + break; + } + + if (msp->watch_stereo) + watch_stereo(client); + + /* unmute + restore dfp registers */ + msp3400c_setbass(client, msp->bass); + msp3400c_settreble(client, msp->treble); + msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + msp3400c_restore_dfp(client); + + msp->active = 0; + } + +done: + dprintk(("msp3410: thread: exit\n")); + msp->active = 0; + + msp->kthread = NULL; + wakeup(&msp->kthread); + + kthread_exit(); +} + +int msp_attach(bktr_ptr_t bktr) +{ + struct msp3400c *msp; + int rev1,rev2,i; + int err; + char buf[20]; + + msp = (struct msp3400c *) malloc(sizeof(struct msp3400c), M_DEVBUF, M_NOWAIT); + if (msp == NULL) + return ENOMEM; + bktr->msp3400c_info = msp; + + memset(msp,0,sizeof(struct msp3400c)); + msp->left = 65535; + msp->right = 65535; + msp->bass = 32768; + msp->treble = 32768; + msp->input = -1; + msp->threaddesc = malloc(15 * sizeof(char), M_DEVBUF, M_NOWAIT); + if (msp->threaddesc == NULL) { + free(msp, M_DEVBUF); + return ENOMEM; + } + snprintf(msp->threaddesc, 14, "%s_msp34xx_thread", bktr->bktr_xname); + + for (i = 0; i < DFP_COUNT; i++) + msp->dfp_regs[i] = -1; + + msp3400c_reset(bktr); + + rev1 = msp3400c_read(bktr, I2C_MSP3400C_DFP, 0x1e); + if (-1 != rev1) + rev2 = msp3400c_read(bktr, I2C_MSP3400C_DFP, 0x1f); + if ((-1 == rev1) || (0 == rev1 && 0 == rev2)) { + free(msp->threaddesc, M_DEVBUF); + free(msp, M_DEVBUF); + bktr->msp3400c_info = NULL; + printf("%s: msp3400: error while reading chip version\n", bktr_name(bktr)); + return ENXIO; + } + +#if 0 + /* this will turn on a 1kHz beep - might be useful for debugging... */ + msp3400c_write(bktr,I2C_MSP3400C_DFP, 0x0014, 0x1040); +#endif + + sprintf(buf,"MSP34%02d%c-%c%d", + (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f); + msp->nicam = (((rev2>>8)&0xff) != 00) ? 1 : 0; + + if (bktr->mspsimple == -1) { + /* default mode */ + /* msp->simple = (((rev2>>8)&0xff) == 0) ? 0 : 1; */ + msp->simple = ((rev1&0xff)+'@' > 'C'); + } else { + /* use kenv value */ + msp->simple = bktr->mspsimple; + } + + /* hello world :-) */ + if (bootverbose) { + printf("%s: msp34xx: init: chip=%s", bktr_name(bktr), buf); + if (msp->nicam) + printf(", has NICAM support"); + printf("\n"); + } + + /* startup control thread */ + err = kthread_create(msp->simple ? msp3410d_thread : msp3400c_thread, + bktr, &msp->kthread, msp->threaddesc); + if (err) { + printf("%s: Error returned by kthread_create: %d", bktr_name(bktr), err); + free(msp->threaddesc, M_DEVBUF); + free(msp, M_DEVBUF); + bktr->msp3400c_info = NULL; + return ENXIO; + } + wakeup(msp->kthread); + + /* done */ + return 0; +} + +int msp_detach(bktr_ptr_t client) +{ + struct msp3400c *msp = (struct msp3400c*)client->msp3400c_info; + + /* shutdown control thread */ + if (msp->kthread) + { + /* XXX mutex lock required */ + msp->rmmod = 1; + msp->watch_stereo = 0; + wakeup(msp->kthread); + + while (msp->kthread) + tsleep(&msp->kthread, 0, "wait for kthread", hz/10); + } + + if (client->msp3400c_info != NULL) { + free(client->msp3400c_info, M_DEVBUF); + client->msp3400c_info = NULL; + } + + msp3400c_reset(client); + + return 0; +} + +void msp_wake_thread(bktr_ptr_t client) +{ + struct msp3400c *msp = (struct msp3400c*)client->msp3400c_info; + + msp3400c_setvolume(client,msp->muted,0,0); + msp->watch_stereo=0; + if (msp->active) + msp->restart = 1; + wakeup(msp->kthread); +} + +void msp_halt_thread(bktr_ptr_t client) +{ + struct msp3400c *msp = (struct msp3400c*)client->msp3400c_info; + + msp3400c_setvolume(client,msp->muted,0,0); + if (msp->active) + msp->restart = 1; + msp->halt_thread = 1; + wakeup(msp->kthread); +} +#endif /* BKTR_NEW_MSP34XX_DRIVER */ diff --git a/sys/i386/include/ioctl_meteor.h b/sys/dev/video/meteor/ioctl_meteor.h similarity index 96% rename from sys/i386/include/ioctl_meteor.h rename to sys/dev/video/meteor/ioctl_meteor.h index 62e6156afe..a1f90b4ec8 100644 --- a/sys/i386/include/ioctl_meteor.h +++ b/sys/dev/video/meteor/ioctl_meteor.h @@ -28,15 +28,16 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/i386/include/ioctl_meteor.h,v 1.11 1999/12/29 04:33:02 peter Exp $ - * $DragonFly: src/sys/i386/include/Attic/ioctl_meteor.h,v 1.2 2003/06/17 04:28:35 dillon Exp $ + * $FreeBSD: src/sys/dev/bktr/ioctl_meteor.h,v 1.15 2003/12/20 17:12:25 obrien Exp $ + * $DragonFly: src/sys/dev/video/meteor/ioctl_meteor.h,v 1.1 2004/05/15 17:54:13 joerg Exp $ */ + /* * ioctl constants for Matrox Meteor Capture card. */ -#ifndef _MACHINE_IOCTL_METEOR_H_ -#define _MACHINE_IOCTL_METEOR_H_ +#ifndef _DEV_BKTR_IOCTL_METEOR_H_ +#define _DEV_BKTR_IOCTL_METEOR_H_ #ifndef _KERNEL #include @@ -185,4 +186,4 @@ struct meteor_mem { caddr_t buf; /* The real space (virtual addr) */ } ; -#endif /* !_MACHINE_IOCTL_METEOR_H_ */ +#endif /* !_DEV_BKTR_IOCTL_METEOR_H_ */ diff --git a/sys/dev/video/meteor/meteor.c b/sys/dev/video/meteor/meteor.c index ddb9fdccd4..536e67c959 100644 --- a/sys/dev/video/meteor/meteor.c +++ b/sys/dev/video/meteor/meteor.c @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/pci/meteor.c,v 1.49 1999/09/25 18:24:41 phk Exp $ - * $DragonFly: src/sys/dev/video/meteor/meteor.c,v 1.11 2004/05/13 23:49:22 dillon Exp $ + * $DragonFly: src/sys/dev/video/meteor/meteor.c,v 1.12 2004/05/15 17:54:13 joerg Exp $ */ /* Change History: @@ -168,8 +168,8 @@ #include #include -#include -#include "meteor_reg.h" +#include +#include static void meteor_intr (void *arg); diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT index b5c3fe6cf8..ed099a002c 100644 --- a/sys/i386/conf/LINT +++ b/sys/i386/conf/LINT @@ -3,7 +3,7 @@ # as much of the source tree as it can. # # $FreeBSD: src/sys/i386/conf/LINT,v 1.749.2.144 2003/06/04 17:56:59 sam Exp $ -# $DragonFly: src/sys/i386/conf/Attic/LINT,v 1.28 2004/04/29 12:11:16 joerg Exp $ +# $DragonFly: src/sys/i386/conf/Attic/LINT,v 1.29 2004/05/15 17:54:13 joerg Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -1962,6 +1962,11 @@ options AHD_REG_PRETTY_PRINT # motherboards and motherboards with bad or incomplete PCI 2.1 support. # As a rough guess, old = before 1998 # +# options BKTR_NEW_MSP34XX_DRIVER +# Use new, more complete initialization scheme for the msp34* soundchip. +# Should fix stereo autodetection if the old driver does only output +# mono sound. +# # # The oltr driver supports the following Olicom PCI token-ring adapters # OC-3136, OC-3137, OC-3139, OC-3140, OC-3141, OC-3540, OC-3250 @@ -2051,6 +2056,7 @@ device meteor # I2C slaves connected to the external connector of some cards. # device bktr +options BKTR_NEW_MSP34XX_DRIVER # # PCCARD/PCMCIA diff --git a/sys/platform/pc32/include/ioctl_bt848.h b/sys/platform/pc32/include/ioctl_bt848.h deleted file mode 100644 index 8b7c3ff601..0000000000 --- a/sys/platform/pc32/include/ioctl_bt848.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * extensions to ioctl_meteor.h for the bt848 cards - * - * $FreeBSD: src/sys/i386/include/ioctl_bt848.h,v 1.25.2.3 2000/10/31 14:31:27 roger Exp $ - * $DragonFly: src/sys/platform/pc32/include/Attic/ioctl_bt848.h,v 1.2 2003/06/17 04:28:35 dillon Exp $ - */ - -#ifndef _MACHINE_IOCTL_BT848_H_ -#define _MACHINE_IOCTL_BT848_H_ - -/* - * frequency sets - */ -#define CHNLSET_NABCST 1 -#define CHNLSET_CABLEIRC 2 -#define CHNLSET_CABLEHRC 3 -#define CHNLSET_WEUROPE 4 -#define CHNLSET_JPNBCST 5 -#define CHNLSET_JPNCABLE 6 -#define CHNLSET_XUSSR 7 -#define CHNLSET_AUSTRALIA 8 -#define CHNLSET_FRANCE 9 -#define CHNLSET_MIN CHNLSET_NABCST -#define CHNLSET_MAX CHNLSET_FRANCE - - -/* - * constants for various tuner registers - */ -#define BT848_HUEMIN (-90) -#define BT848_HUEMAX 90 -#define BT848_HUECENTER 0 -#define BT848_HUERANGE 179.3 -#define BT848_HUEREGMIN (-128) -#define BT848_HUEREGMAX 127 -#define BT848_HUESTEPS 256 - -#define BT848_BRIGHTMIN (-50) -#define BT848_BRIGHTMAX 50 -#define BT848_BRIGHTCENTER 0 -#define BT848_BRIGHTRANGE 99.6 -#define BT848_BRIGHTREGMIN (-128) -#define BT848_BRIGHTREGMAX 127 -#define BT848_BRIGHTSTEPS 256 - -#define BT848_CONTRASTMIN 0 -#define BT848_CONTRASTMAX 237 -#define BT848_CONTRASTCENTER 100 -#define BT848_CONTRASTRANGE 236.57 -#define BT848_CONTRASTREGMIN 0 -#define BT848_CONTRASTREGMAX 511 -#define BT848_CONTRASTSTEPS 512 - -#define BT848_CHROMAMIN 0 -#define BT848_CHROMAMAX 284 -#define BT848_CHROMACENTER 100 -#define BT848_CHROMARANGE 283.89 -#define BT848_CHROMAREGMIN 0 -#define BT848_CHROMAREGMAX 511 -#define BT848_CHROMASTEPS 512 - -#define BT848_SATUMIN 0 -#define BT848_SATUMAX 202 -#define BT848_SATUCENTER 100 -#define BT848_SATURANGE 201.18 -#define BT848_SATUREGMIN 0 -#define BT848_SATUREGMAX 511 -#define BT848_SATUSTEPS 512 - -#define BT848_SATVMIN 0 -#define BT848_SATVMAX 284 -#define BT848_SATVCENTER 100 -#define BT848_SATVRANGE 283.89 -#define BT848_SATVREGMIN 0 -#define BT848_SATVREGMAX 511 -#define BT848_SATVSTEPS 512 - - -/* - * audio stuff - */ -#define AUDIO_TUNER 0x00 /* command for the audio routine */ -#define AUDIO_EXTERN 0x01 /* don't confuse them with bit */ -#define AUDIO_INTERN 0x02 /* settings */ -#define AUDIO_MUTE 0x80 -#define AUDIO_UNMUTE 0x81 - - -/* - * EEProm stuff - */ -struct eeProm { - short offset; - short count; - u_char bytes[ 256 ]; -}; - - -/* - * XXX: this is a hack, should be in ioctl_meteor.h - * here to avoid touching that file for now... - */ -#define TVTUNER_SETCHNL _IOW('x', 32, unsigned int) /* set channel */ -#define TVTUNER_GETCHNL _IOR('x', 32, unsigned int) /* get channel */ -#define TVTUNER_SETTYPE _IOW('x', 33, unsigned int) /* set tuner type */ -#define TVTUNER_GETTYPE _IOR('x', 33, unsigned int) /* get tuner type */ -#define TVTUNER_GETSTATUS _IOR('x', 34, unsigned int) /* get tuner status */ -#define TVTUNER_SETFREQ _IOW('x', 35, unsigned int) /* set frequency */ -#define TVTUNER_GETFREQ _IOR('x', 36, unsigned int) /* get frequency */ - - -#define BT848_SHUE _IOW('x', 37, int) /* set hue */ -#define BT848_GHUE _IOR('x', 37, int) /* get hue */ -#define BT848_SBRIG _IOW('x', 38, int) /* set brightness */ -#define BT848_GBRIG _IOR('x', 38, int) /* get brightness */ -#define BT848_SCSAT _IOW('x', 39, int) /* set chroma sat */ -#define BT848_GCSAT _IOR('x', 39, int) /* get UV saturation */ -#define BT848_SCONT _IOW('x', 40, int) /* set contrast */ -#define BT848_GCONT _IOR('x', 40, int) /* get contrast */ -#define BT848_SVSAT _IOW('x', 41, int) /* set chroma V sat */ -#define BT848_GVSAT _IOR('x', 41, int) /* get V saturation */ -#define BT848_SUSAT _IOW('x', 42, int) /* set chroma U sat */ -#define BT848_GUSAT _IOR('x', 42, int) /* get U saturation */ - -#define BT848_SCBARS _IOR('x', 43, int) /* set colorbar */ -#define BT848_CCBARS _IOR('x', 44, int) /* clear colorbar */ - - -#define BT848_SAUDIO _IOW('x', 46, int) /* set audio channel */ -#define BT848_GAUDIO _IOR('x', 47, int) /* get audio channel */ -#define BT848_SBTSC _IOW('x', 48, int) /* set audio channel */ - -#define BT848_GSTATUS _IOR('x', 49, unsigned int) /* reap status */ - -#define BT848_WEEPROM _IOWR('x', 50, struct eeProm) /* write to EEProm */ -#define BT848_REEPROM _IOWR('x', 51, struct eeProm) /* read from EEProm */ - -#define BT848_SIGNATURE _IOWR('x', 52, struct eeProm) /* read card sig */ - -#define TVTUNER_SETAFC _IOW('x', 53, int) /* turn AFC on/off */ -#define TVTUNER_GETAFC _IOR('x', 54, int) /* query AFC on/off */ -#define BT848_SLNOTCH _IOW('x', 55, int) /* set luma notch */ -#define BT848_GLNOTCH _IOR('x', 56, int) /* get luma notch */ - -/* Read/Write the BT848's I2C bus directly - * b7-b0: data (read/write) - * b15-b8: internal peripheral register (write) - * b23-b16: i2c addr (write) - * b31-b24: 1 = write, 0 = read - */ -#define BT848_I2CWR _IOWR('x', 57, u_long) /* i2c read-write */ - -struct bktr_msp_control { - unsigned char function; - unsigned int address; - unsigned int data; -}; - -#define BT848_MSP_RESET _IO('x', 76) /* MSP chip reset */ -#define BT848_MSP_READ _IOWR('x', 77, struct bktr_msp_control) /* MSP chip read */ -#define BT848_MSP_WRITE _IOWR('x', 78, struct bktr_msp_control) /* MSP chip write */ - -/* Support for radio tuner */ -#define RADIO_SETMODE _IOW('x', 58, unsigned int) /* set radio modes */ -#define RADIO_GETMODE _IOR('x', 58, unsigned char) /* get radio modes */ -#define RADIO_AFC 0x01 /* These modes will probably not */ -#define RADIO_MONO 0x02 /* work on the FRxxxx. It does */ -#define RADIO_MUTE 0x08 /* work on the FMxxxx. */ -#define RADIO_SETFREQ _IOW('x', 59, unsigned int) /* set frequency */ -#define RADIO_GETFREQ _IOR('x', 59, unsigned int) /* set frequency */ - /* Argument is frequency*100MHz */ - -/* - * XXX: more bad magic, - * we need to fix the METEORGINPUT to return something public - * duplicate them here for now... - */ -#define METEOR_DEV0 0x00001000 -#define METEOR_DEV1 0x00002000 -#define METEOR_DEV2 0x00004000 -#define METEOR_DEV3 0x00008000 -#define METEOR_DEV_SVIDEO 0x00006000 -/* - * right now I don't know were to put these, but as they are suppose to be - * a part of a common video capture interface, these should be relocated to - * another place. Probably most of the METEOR_xxx defines need to be - * renamed and moved to a common header - */ - -typedef enum { METEOR_PIXTYPE_RGB, METEOR_PIXTYPE_YUV, - METEOR_PIXTYPE_YUV_PACKED, - METEOR_PIXTYPE_YUV_12 } METEOR_PIXTYPE; - - -struct meteor_pixfmt { - u_int index; /* Index in supported pixfmt list */ - METEOR_PIXTYPE type; /* What's the board gonna feed us */ - u_int Bpp; /* Bytes per pixel */ - u_long masks[3]; /* R,G,B or Y,U,V masks, respectively */ - unsigned swap_bytes :1; /* Bytes swapped within shorts */ - unsigned swap_shorts:1; /* Shorts swapped within longs */ -}; - - -struct bktr_clip { - int x_min; - int x_max; - int y_min; - int y_max; -}; - -#define BT848_MAX_CLIP_NODE 100 -struct _bktr_clip { - struct bktr_clip x[BT848_MAX_CLIP_NODE]; -}; - -/* - * I'm using METEOR_xxx just because that will be common to other interface - * and less of a surprise - */ -#define METEORSACTPIXFMT _IOW('x', 64, int ) -#define METEORGACTPIXFMT _IOR('x', 64, int ) -#define METEORGSUPPIXFMT _IOWR('x', 65, struct meteor_pixfmt) - -/* set clip list */ -#define BT848SCLIP _IOW('x', 66, struct _bktr_clip ) -#define BT848GCLIP _IOR('x', 66, struct _bktr_clip ) - - -/* set input format */ -#define BT848SFMT _IOW('x', 67, unsigned long ) -#define BT848GFMT _IOR('x', 67, unsigned long ) - -/* set clear-buffer-on-start */ -#define BT848SCBUF _IOW('x', 68, int) -#define BT848GCBUF _IOR('x', 68, int) - -/* set capture area */ -/* The capture area is the area of the video image which is grabbed */ -/* Usually the capture area is 640x480 (768x576 PAL) pixels */ -/* This area is then scaled to the dimensions the user requires */ -/* using the METEORGEO ioctl */ -/* However, the capture area could be 400x300 pixels from the top right */ -/* corner of the video image */ -struct bktr_capture_area { - int x_offset; - int y_offset; - int x_size; - int y_size; -}; -#define BT848_SCAPAREA _IOW('x', 69, struct bktr_capture_area) -#define BT848_GCAPAREA _IOR('x', 69, struct bktr_capture_area) - - -/* Get channel Set */ -#define BT848_MAX_CHNLSET_NAME_LEN 16 -struct bktr_chnlset { - short index; - short max_channel; - char name[BT848_MAX_CHNLSET_NAME_LEN]; -}; -#define TVTUNER_GETCHNLSET _IOWR('x', 70, struct bktr_chnlset) - - - -/* Infra Red Remote Control */ -struct bktr_remote { - unsigned char data[3]; -}; -#define REMOTE_GETKEY _IOR('x', 71, struct bktr_remote)/*read the remote */ - /*control receiver*/ - /*returns raw data*/ - - -/* - * Direct access to GPIO pins. You must add BKTR_GPIO_ACCESS to your kernel - * configuration file to use these - */ -#define BT848_GPIO_SET_EN _IOW('x', 72, int) /* set gpio_out_en */ -#define BT848_GPIO_GET_EN _IOR('x', 73, int) /* get gpio_out_en */ -#define BT848_GPIO_SET_DATA _IOW('x', 74, int) /* set gpio_data */ -#define BT848_GPIO_GET_DATA _IOR('x', 75, int) /* get gpio_data */ - - - -/* XXX - Copied from /sys/pci/brktree_reg.h */ -#define BT848_IFORM_FORMAT (0x7<<0) -# define BT848_IFORM_F_RSVD (0x7) -# define BT848_IFORM_F_SECAM (0x6) -# define BT848_IFORM_F_PALN (0x5) -# define BT848_IFORM_F_PALM (0x4) -# define BT848_IFORM_F_PALBDGHI (0x3) -# define BT848_IFORM_F_NTSCJ (0x2) -# define BT848_IFORM_F_NTSCM (0x1) -# define BT848_IFORM_F_AUTO (0x0) - - -#endif /* _MACHINE_IOCTL_BT848_H_ */ - diff --git a/sys/platform/pc32/include/ioctl_meteor.h b/sys/platform/pc32/include/ioctl_meteor.h deleted file mode 100644 index ca4b2ed6d9..0000000000 --- a/sys/platform/pc32/include/ioctl_meteor.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 1995 Mark Tinguely and Jim Lowe - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Mark Tinguely and Jim Lowe - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/sys/i386/include/ioctl_meteor.h,v 1.11 1999/12/29 04:33:02 peter Exp $ - * $DragonFly: src/sys/platform/pc32/include/Attic/ioctl_meteor.h,v 1.2 2003/06/17 04:28:35 dillon Exp $ - */ -/* - * ioctl constants for Matrox Meteor Capture card. - */ - -#ifndef _MACHINE_IOCTL_METEOR_H_ -#define _MACHINE_IOCTL_METEOR_H_ - -#ifndef _KERNEL -#include -#endif -#include - -struct meteor_capframe { - short command; /* see below for valid METEORCAPFRM commands */ - short lowat; /* start transfer if < this number */ - short hiwat; /* stop transfer if > this number */ -} ; - -/* structure for METEOR[GS]ETGEO - get/set geometry */ -struct meteor_geomet { - u_short rows; - u_short columns; - u_short frames; - u_long oformat; -} ; - -/* structure for METEORGCOUNT-get count of frames, fifo errors and dma errors */ -struct meteor_counts { - u_long fifo_errors; /* count of fifo errors since open */ - u_long dma_errors; /* count of dma errors since open */ - u_long frames_captured; /* count of frames captured since open */ - u_long even_fields_captured; /* count of even fields captured */ - u_long odd_fields_captured; /* count of odd fields captured */ -} ; - -/* structure for getting and setting direct transfers to vram */ -struct meteor_video { - u_long addr; /* Address of location to dma to */ - u_long width; /* Width of memory area */ - u_long banksize; /* Size of Vram bank */ - u_long ramsize; /* Size of Vram */ -}; - -#define METEORCAPTUR _IOW('x', 1, int) /* capture a frame */ -#define METEORCAPFRM _IOW('x', 2, struct meteor_capframe) /* sync capture */ -#define METEORSETGEO _IOW('x', 3, struct meteor_geomet) /* set geometry */ -#define METEORGETGEO _IOR('x', 4, struct meteor_geomet) /* get geometry */ -#define METEORSTATUS _IOR('x', 5, unsigned short) /* get status */ -#define METEORSHUE _IOW('x', 6, signed char) /* set hue */ -#define METEORGHUE _IOR('x', 6, signed char) /* get hue */ -#define METEORSFMT _IOW('x', 7, unsigned long) /* set format */ -#define METEORGFMT _IOR('x', 7, unsigned long) /* get format */ -#define METEORSINPUT _IOW('x', 8, unsigned long) /* set input dev */ -#define METEORGINPUT _IOR('x', 8, unsigned long) /* get input dev */ -#define METEORSCHCV _IOW('x', 9, unsigned char) /* set uv gain */ -#define METEORGCHCV _IOR('x', 9, unsigned char) /* get uv gain */ -#define METEORSCOUNT _IOW('x',10, struct meteor_counts) -#define METEORGCOUNT _IOR('x',10, struct meteor_counts) -#define METEORSFPS _IOW('x',11, unsigned short) /* set fps */ -#define METEORGFPS _IOR('x',11, unsigned short) /* get fps */ -#define METEORSSIGNAL _IOW('x', 12, unsigned int) /* set signal */ -#define METEORGSIGNAL _IOR('x', 12, unsigned int) /* get signal */ -#define METEORSVIDEO _IOW('x', 13, struct meteor_video) /* set video */ -#define METEORGVIDEO _IOR('x', 13, struct meteor_video) /* get video */ -#define METEORSBRIG _IOW('x', 14, unsigned char) /* set brightness */ -#define METEORGBRIG _IOR('x', 14, unsigned char) /* get brightness */ -#define METEORSCSAT _IOW('x', 15, unsigned char) /* set chroma sat */ -#define METEORGCSAT _IOR('x', 15, unsigned char) /* get uv saturation */ -#define METEORSCONT _IOW('x', 16, unsigned char) /* set contrast */ -#define METEORGCONT _IOR('x', 16, unsigned char) /* get contrast */ -#define METEORSBT254 _IOW('x', 17, unsigned short) /* set Bt254 reg */ -#define METEORGBT254 _IOR('x', 17, unsigned short) /* get Bt254 reg */ -#define METEORSHWS _IOW('x', 18, unsigned char) /* set hor start reg */ -#define METEORGHWS _IOR('x', 18, unsigned char) /* get hor start reg */ -#define METEORSVWS _IOW('x', 19, unsigned char) /* set vert start reg */ -#define METEORGVWS _IOR('x', 19, unsigned char) /* get vert start reg */ -#define METEORSTS _IOW('x', 20, unsigned char) /* set time stamp */ -#define METEORGTS _IOR('x', 20, unsigned char) /* get time stamp */ - -#define METEOR_STATUS_ID_MASK 0xf000 /* ID of 7196 */ -#define METEOR_STATUS_DIR 0x0800 /* Direction of Expansion port YUV */ -#define METEOR_STATUS_OEF 0x0200 /* Field detected: Even/Odd */ -#define METEOR_STATUS_SVP 0x0100 /* State of VRAM Port:inactive/active */ -#define METEOR_STATUS_STTC 0x0080 /* Time Constant: TV/VCR */ -#define METEOR_STATUS_HCLK 0x0040 /* Horiz PLL: locked/unlocked */ -#define METEOR_STATUS_FIDT 0x0020 /* Field detect: 50/60hz */ -#define METEOR_STATUS_ALTD 0x0002 /* Line alt: no line alt/line alt */ -#define METEOR_STATUS_CODE 0x0001 /* Colour info: no colour/colour */ - - /* METEORCAPTUR capture options */ -#define METEOR_CAP_SINGLE 0x0001 /* capture one frame */ -#define METEOR_CAP_CONTINOUS 0x0002 /* continuously capture */ -#define METEOR_CAP_STOP_CONT 0x0004 /* stop the continuous capture */ - - /* METEORCAPFRM capture commands */ -#define METEOR_CAP_N_FRAMES 0x0001 /* capture N frames */ -#define METEOR_CAP_STOP_FRAMES 0x0002 /* stop capture N frames */ -#define METEOR_HALT_N_FRAMES 0x0003 /* halt of capture N frames */ -#define METEOR_CONT_N_FRAMES 0x0004 /* continue after above halt */ - - /* valid video input formats: */ -#define METEOR_FMT_NTSC 0x00100 /* NTSC -- initialized default */ -#define METEOR_FMT_PAL 0x00200 /* PAL */ -#define METEOR_FMT_SECAM 0x00400 /* SECAM */ -#define METEOR_FMT_AUTOMODE 0x00800 /* auto-mode */ -#define METEOR_INPUT_DEV0 0x01000 /* camera input 0 -- default */ -#define METEOR_INPUT_DEV_RCA METEOR_INPUT_DEV0 -#define METEOR_INPUT_DEV1 0x02000 /* camera input 1 */ -#define METEOR_INPUT_DEV2 0x04000 /* camera input 2 */ -#define METEOR_INPUT_DEV3 0x08000 /* camera input 3 */ -#define METEOR_INPUT_DEV_RGB 0x0a000 /* for rgb version of meteor */ -#define METEOR_INPUT_DEV_SVIDEO 0x06000 /* S-video input port */ - - /* valid video output formats: */ -#define METEOR_GEO_RGB16 0x0010000 /* packed -- initialized default */ -#define METEOR_GEO_RGB24 0x0020000 /* RBG 24 bits packed */ - /* internally stored in 32 bits */ -#define METEOR_GEO_YUV_PACKED 0x0040000 /* 4-2-2 YUV 16 bits packed */ -#define METEOR_GEO_YUV_PLANAR 0x0080000 /* 4-2-2 YUV 16 bits planer */ -#define METEOR_GEO_YUV_PLANER METEOR_GEO_YUV_PLANAR -#define METEOR_GEO_UNSIGNED 0x0400000 /* unsigned uv outputs */ -#define METEOR_GEO_EVEN_ONLY 0x1000000 /* set for even only field capture */ -#define METEOR_GEO_ODD_ONLY 0x2000000 /* set for odd only field capture */ -#define METEOR_GEO_FIELD_MASK 0x3000000 -#define METEOR_GEO_YUV_422 0x4000000 /* 4-2-2 YUV in Y-U-V combined */ -#define METEOR_GEO_OUTPUT_MASK 0x40f0000 -#define METEOR_GEO_YUV_12 0x10000000 /* YUV 12 format */ -#define METEOR_GEO_YUV_9 0x40000000 /* YUV 9 format */ - -#define METEOR_FIELD_MODE 0x80000000 /* Field cap or Frame cap */ - -#define METEOR_SIG_MODE_MASK 0xffff0000 -#define METEOR_SIG_FRAME 0x00000000 /* signal every frame */ -#define METEOR_SIG_FIELD 0x00010000 /* signal every field */ - - /* following structure is used to coordinate the synchronous */ - -struct meteor_mem { - /* kernel write only */ - int frame_size; /* row*columns*depth */ - unsigned num_bufs; /* number of frames in buffer (1-32) */ - /* user and kernel change these */ - int lowat; /* kernel starts capture if < this number */ - int hiwat; /* kernel stops capture if > this number. - hiwat <= numbufs */ - unsigned active; /* bit mask of active frame buffers - kernel sets, user clears */ - int num_active_bufs; /* count of active frame buffer - kernel increments, user decrements */ - - /* reference to mmapped data */ - caddr_t buf; /* The real space (virtual addr) */ -} ; - -#endif /* !_MACHINE_IOCTL_METEOR_H_ */ -- 2.41.0