2 * 1. Redistributions of source code must retain the
3 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Amancio Hasty and
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
33 * $FreeBSD: src/sys/dev/bktr/bktr_os.c,v 1.54 2007/02/23 12:18:34 piso Exp $
34 * $DragonFly: src/sys/dev/video/bktr/bktr_os.c,v 1.21 2008/05/18 03:02:53 pavalos Exp $
38 * This is part of the Driver for Video Capture Cards (Frame grabbers)
39 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
41 * Copyright Roger Hardiman and Amancio Hasty.
43 * bktr_os : This has all the Operating System dependant code,
44 * probe/attach and open/close/ioctl/read/mmap
49 #include "opt_bktr.h" /* include any kernel config options */
51 #define FIFO_RISC_DISABLED 0
52 #define ALL_INTS_DISABLED 0
54 #include <sys/param.h>
55 #include <sys/systm.h>
57 #include <sys/device.h>
59 #include <sys/kernel.h>
60 #include <sys/signalvar.h>
61 #include <sys/malloc.h>
64 #include <sys/select.h>
67 #include <sys/thread2.h>
68 #include <sys/selinfo.h>
71 #include <vm/vm_kern.h>
73 #include <vm/vm_extern.h>
75 #include <bus/pci/pcivar.h>
76 #include <bus/pci/pcireg.h>
77 #include <bus/pci/pcidevs.h>
79 #include <sys/sysctl.h>
82 int bt848_reverse_mute
= -1;
83 int bt848_format
= -1;
84 int bt848_slow_msp_audio
= -1;
85 #ifdef BKTR_NEW_MSP34XX_DRIVER
86 int bt848_stereo_once
= 0; /* no continuous stereo monitoring */
87 int bt848_amsound
= 0; /* hard-wire AM sound at 6.5 Hz (france),
88 the autoscan seems work well only with FM... */
92 SYSCTL_NODE(_hw
, OID_AUTO
, bt848
, CTLFLAG_RW
, 0, "Bt848 Driver mgmt");
93 SYSCTL_INT(_hw_bt848
, OID_AUTO
, card
, CTLFLAG_RW
, &bt848_card
, -1, "");
94 SYSCTL_INT(_hw_bt848
, OID_AUTO
, tuner
, CTLFLAG_RW
, &bt848_tuner
, -1, "");
95 SYSCTL_INT(_hw_bt848
, OID_AUTO
, reverse_mute
, CTLFLAG_RW
, &bt848_reverse_mute
, -1, "");
96 SYSCTL_INT(_hw_bt848
, OID_AUTO
, format
, CTLFLAG_RW
, &bt848_format
, -1, "");
97 SYSCTL_INT(_hw_bt848
, OID_AUTO
, slow_msp_audio
, CTLFLAG_RW
, &bt848_slow_msp_audio
, -1, "");
98 #ifdef BKTR_NEW_MSP34XX_DRIVER
99 SYSCTL_INT(_hw_bt848
, OID_AUTO
, stereo_once
, CTLFLAG_RW
, &bt848_stereo_once
, 0, "");
100 SYSCTL_INT(_hw_bt848
, OID_AUTO
, amsound
, CTLFLAG_RW
, &bt848_amsound
, 0, "");
101 SYSCTL_INT(_hw_bt848
, OID_AUTO
, dolby
, CTLFLAG_RW
, &bt848_dolby
, 0, "");
104 #include <dev/video/meteor/ioctl_meteor.h>
105 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
106 #include <dev/video/bktr/bktr_reg.h>
107 #include <dev/video/bktr/bktr_tuner.h>
108 #include <dev/video/bktr/bktr_card.h>
109 #include <dev/video/bktr/bktr_audio.h>
110 #include <dev/video/bktr/bktr_core.h>
111 #include <dev/video/bktr/bktr_os.h>
113 #if defined(BKTR_USE_FREEBSD_SMBUS)
114 #include <dev/video/bktr/bktr_i2c.h>
116 #include "iicbb_if.h"
117 #include "smbus_if.h"
120 static int bktr_probe( device_t dev
);
121 static int bktr_attach( device_t dev
);
122 static int bktr_detach( device_t dev
);
123 static int bktr_shutdown( device_t dev
);
124 static void bktr_intr(void *arg
) { common_bktr_intr(arg
); }
126 static device_method_t bktr_methods
[] = {
127 /* Device interface */
128 DEVMETHOD(device_probe
, bktr_probe
),
129 DEVMETHOD(device_attach
, bktr_attach
),
130 DEVMETHOD(device_detach
, bktr_detach
),
131 DEVMETHOD(device_shutdown
, bktr_shutdown
),
133 #if defined(BKTR_USE_FREEBSD_SMBUS)
134 /* iicbb interface */
135 DEVMETHOD(iicbb_callback
, bti2c_iic_callback
),
136 DEVMETHOD(iicbb_setsda
, bti2c_iic_setsda
),
137 DEVMETHOD(iicbb_setscl
, bti2c_iic_setscl
),
138 DEVMETHOD(iicbb_getsda
, bti2c_iic_getsda
),
139 DEVMETHOD(iicbb_getscl
, bti2c_iic_getscl
),
140 DEVMETHOD(iicbb_reset
, bti2c_iic_reset
),
142 /* smbus interface */
143 DEVMETHOD(smbus_callback
, bti2c_smb_callback
),
144 DEVMETHOD(smbus_writeb
, bti2c_smb_writeb
),
145 DEVMETHOD(smbus_writew
, bti2c_smb_writew
),
146 DEVMETHOD(smbus_readb
, bti2c_smb_readb
),
152 static driver_t bktr_driver
= {
155 sizeof(struct bktr_softc
),
158 static devclass_t bktr_devclass
;
160 static d_open_t bktr_open
;
161 static d_close_t bktr_close
;
162 static d_read_t bktr_read
;
163 static d_write_t bktr_write
;
164 static d_ioctl_t bktr_ioctl
;
165 static d_mmap_t bktr_mmap
;
166 static d_poll_t bktr_poll
;
168 #define CDEV_MAJOR 92
169 static struct dev_ops bktr_ops
= {
170 { "bktr", CDEV_MAJOR
, 0 },
172 .d_close
= bktr_close
,
174 .d_write
= bktr_write
,
175 .d_ioctl
= bktr_ioctl
,
180 DRIVER_MODULE(bktr
, pci
, bktr_driver
, bktr_devclass
, 0, 0);
181 MODULE_DEPEND(bktr
, bktr_mem
, 1,1,1);
182 MODULE_VERSION(bktr
, 1);
185 * the boot time probe routine.
188 bktr_probe( device_t dev
)
190 unsigned int type
= pci_get_devid(dev
);
191 unsigned int rev
= pci_get_revid(dev
);
193 if (PCI_VENDOR(type
) == PCI_VENDOR_BROOKTREE
)
195 switch (PCI_PRODUCT(type
)) {
196 case PCI_PRODUCT_BROOKTREE_BT848
:
198 device_set_desc(dev
, "BrookTree 848A");
200 device_set_desc(dev
, "BrookTree 848");
201 return BUS_PROBE_DEFAULT
;
202 case PCI_PRODUCT_BROOKTREE_BT849
:
203 device_set_desc(dev
, "BrookTree 849A");
204 return BUS_PROBE_DEFAULT
;
205 case PCI_PRODUCT_BROOKTREE_BT878
:
206 device_set_desc(dev
, "BrookTree 878");
207 return BUS_PROBE_DEFAULT
;
208 case PCI_PRODUCT_BROOKTREE_BT879
:
209 device_set_desc(dev
, "BrookTree 879");
210 return BUS_PROBE_DEFAULT
;
219 * the attach routine.
222 bktr_attach( device_t dev
)
231 u_long old_irq
, new_irq
;
234 struct bktr_softc
*bktr
= device_get_softc(dev
);
236 unit
= device_get_unit(dev
);
238 /* build the device name for bktr_name() */
239 ksnprintf(bktr
->bktr_xname
, sizeof(bktr
->bktr_xname
), "bktr%d",unit
);
242 * Enable bus mastering and Memory Mapped device
244 val
= pci_read_config(dev
, PCIR_COMMAND
, 4);
245 val
|= (PCIM_CMD_MEMEN
|PCIM_CMD_BUSMASTEREN
);
246 pci_write_config(dev
, PCIR_COMMAND
, val
, 4);
249 * Map control/status registers.
251 bktr
->mem_rid
= PCIR_BAR(0);
252 bktr
->res_mem
= bus_alloc_resource_any(dev
, SYS_RES_MEMORY
,
253 &bktr
->mem_rid
, RF_ACTIVE
);
255 if (!bktr
->res_mem
) {
256 device_printf(dev
, "could not map memory\n");
260 bktr
->memt
= rman_get_bustag(bktr
->res_mem
);
261 bktr
->memh
= rman_get_bushandle(bktr
->res_mem
);
265 * Disable the brooktree device
267 OUTL(bktr
, BKTR_INT_MASK
, ALL_INTS_DISABLED
);
268 OUTW(bktr
, BKTR_GPIO_DMA_CTL
, FIFO_RISC_DISABLED
);
271 #ifdef BROOKTREE_IRQ /* from the configuration file */
272 old_irq
= pci_conf_read(tag
, PCI_INTERRUPT_REG
);
273 pci_conf_write(tag
, PCI_INTERRUPT_REG
, BROOKTREE_IRQ
);
274 new_irq
= pci_conf_read(tag
, PCI_INTERRUPT_REG
);
275 kprintf("bktr%d: attach: irq changed from %d to %d\n",
276 unit
, (old_irq
& 0xff), (new_irq
& 0xff));
280 * Allocate our interrupt.
283 bktr
->res_irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
,
284 &bktr
->irq_rid
, RF_SHAREABLE
| RF_ACTIVE
);
285 if (bktr
->res_irq
== NULL
) {
286 device_printf(dev
, "could not map interrupt\n");
291 error
= bus_setup_intr(dev
, bktr
->res_irq
, 0,
292 bktr_intr
, bktr
, &bktr
->res_ih
, NULL
);
294 device_printf(dev
, "could not setup irq\n");
300 /* Update the Device Control Register */
301 /* on Bt878 and Bt879 cards */
302 fun
= pci_read_config( dev
, 0x40, 2);
303 fun
= fun
| 1; /* Enable writes to the sub-system vendor ID */
305 #if defined( BKTR_430_FX_MODE )
306 if (bootverbose
) kprintf("Using 430 FX chipset compatibilty mode\n");
307 fun
= fun
| 2; /* Enable Intel 430 FX compatibility mode */
310 #if defined( BKTR_SIS_VIA_MODE )
311 if (bootverbose
) kprintf("Using SiS/VIA chipset compatibilty mode\n");
312 fun
= fun
| 4; /* Enable SiS/VIA compatibility mode (useful for
313 OPTi chipset motherboards too */
315 pci_write_config(dev
, 0x40, fun
, 2);
317 #if defined(BKTR_USE_FREEBSD_SMBUS)
318 if (bt848_i2c_attach(dev
))
319 kprintf("bktr%d: i2c_attach: can't attach\n", unit
);
323 * PCI latency timer. 32 is a good value for 4 bus mastering slots, if
324 * you have more than four, then 16 would probably be a better value.
326 #ifndef BROOKTREE_DEF_LATENCY_VALUE
327 #define BROOKTREE_DEF_LATENCY_VALUE 10
329 latency
= pci_read_config(dev
, PCI_LATENCY_TIMER
, 4);
330 latency
= (latency
>> 8) & 0xff;
333 kprintf("brooktree%d: PCI bus latency is", unit
);
335 kprintf("brooktree%d: PCI bus latency was 0 changing to",
339 latency
= BROOKTREE_DEF_LATENCY_VALUE
;
340 pci_write_config(dev
, PCI_LATENCY_TIMER
, latency
<<8, 4);
343 kprintf(" %d.\n", (int) latency
);
346 /* read the pci device id and revision id */
347 fun
= pci_get_devid(dev
);
348 rev
= pci_get_revid(dev
);
350 /* call the common attach code */
351 common_bktr_attach( bktr
, unit
, fun
, rev
);
353 /* make the device entries */
354 make_dev(&bktr_ops
, unit
, 0, 0, 0444, "bktr%d", unit
);
355 make_dev(&bktr_ops
, unit
+16, 0, 0, 0444, "tuner%d", unit
);
356 make_dev(&bktr_ops
, unit
+32, 0, 0, 0444, "vbi%d" , unit
);
362 bus_release_resource(dev
, SYS_RES_IRQ
, bktr
->irq_rid
, bktr
->res_irq
);
364 bus_release_resource(dev
, SYS_RES_IRQ
, bktr
->mem_rid
, bktr
->res_mem
);
370 * the detach routine.
373 bktr_detach( device_t dev
)
375 struct bktr_softc
*bktr
= device_get_softc(dev
);
377 #ifdef BKTR_NEW_MSP34XX_DRIVER
378 /* Disable the soundchip and kernel thread */
379 if (bktr
->msp3400c_info
!= NULL
)
383 /* Disable the brooktree device */
384 OUTL(bktr
, BKTR_INT_MASK
, ALL_INTS_DISABLED
);
385 OUTW(bktr
, BKTR_GPIO_DMA_CTL
, FIFO_RISC_DISABLED
);
387 #if defined(BKTR_USE_FREEBSD_SMBUS)
388 if (bt848_i2c_detach(dev
))
389 kprintf("bktr%d: i2c_attach: can't attach\n",
390 device_get_unit(dev
));
393 mtx_destroy(&bktr
->vbimutex
);
396 /* Note: We do not free memory for RISC programs, grab buffer, vbi buffers */
397 /* The memory is retained by the bktr_mem module so we can unload and */
398 /* then reload the main bktr driver module */
400 /* removing the ops automatically destroys all related devices */
401 dev_ops_remove_minor(&bktr_ops
, /*0x0f, */device_get_unit(dev
));
404 * Deallocate resources.
406 bus_teardown_intr(dev
, bktr
->res_irq
, bktr
->res_ih
);
407 bus_release_resource(dev
, SYS_RES_IRQ
, bktr
->irq_rid
, bktr
->res_irq
);
408 bus_release_resource(dev
, SYS_RES_MEMORY
, bktr
->mem_rid
, bktr
->res_mem
);
414 * the shutdown routine.
417 bktr_shutdown( device_t dev
)
419 struct bktr_softc
*bktr
= device_get_softc(dev
);
421 /* Disable the brooktree device */
422 OUTL(bktr
, BKTR_INT_MASK
, ALL_INTS_DISABLED
);
423 OUTW(bktr
, BKTR_GPIO_DMA_CTL
, FIFO_RISC_DISABLED
);
430 * Special Memory Allocation
433 get_bktr_mem( int unit
, unsigned size
)
435 vm_offset_t addr
= 0;
437 addr
= (vm_offset_t
)contigmalloc(size
, M_DEVBUF
, M_NOWAIT
, 0,
438 0xffffffff, 1<<24, 0);
440 addr
= (vm_offset_t
)contigmalloc(size
, M_DEVBUF
, M_NOWAIT
, 0,
441 0xffffffff, PAGE_SIZE
, 0);
443 kprintf("bktr%d: Unable to allocate %d bytes of memory.\n",
451 /*---------------------------------------------------------
453 ** BrookTree 848 character device driver routines
455 **---------------------------------------------------------
458 #define VIDEO_DEV 0x00
459 #define TUNER_DEV 0x01
462 #define UNIT(x) ((x) & 0x0f)
463 #define FUNCTION(x) (x >> 4)
469 bktr_open(struct dev_open_args
*ap
)
471 cdev_t dev
= ap
->a_head
.a_dev
;
476 unit
= UNIT( minor(dev
) );
478 /* Get the device data */
479 bktr
= (struct bktr_softc
*)devclass_get_softc(bktr_devclass
, unit
);
481 /* the device is no longer valid/functioning */
485 if (!(bktr
->flags
& METEOR_INITALIZED
)) /* device not found */
488 /* Record that the device is now busy */
489 device_busy(devclass_get_device(bktr_devclass
, unit
));
492 if (bt848_card
!= -1) {
493 if ((bt848_card
>> 8 == unit
) &&
494 ( (bt848_card
& 0xff) < Bt848_MAX_CARD
)) {
495 if ( bktr
->bt848_card
!= (bt848_card
& 0xff) ) {
496 bktr
->bt848_card
= (bt848_card
& 0xff);
497 probeCard(bktr
, FALSE
, unit
);
502 if (bt848_tuner
!= -1) {
503 if ((bt848_tuner
>> 8 == unit
) &&
504 ( (bt848_tuner
& 0xff) < Bt848_MAX_TUNER
)) {
505 if ( bktr
->bt848_tuner
!= (bt848_tuner
& 0xff) ) {
506 bktr
->bt848_tuner
= (bt848_tuner
& 0xff);
507 probeCard(bktr
, FALSE
, unit
);
512 if (bt848_reverse_mute
!= -1) {
513 if ((bt848_reverse_mute
>> 8) == unit
) {
514 bktr
->reverse_mute
= bt848_reverse_mute
& 0xff;
518 if (bt848_slow_msp_audio
!= -1) {
519 if ((bt848_slow_msp_audio
>> 8) == unit
) {
520 bktr
->slow_msp_audio
= (bt848_slow_msp_audio
& 0xff);
524 #ifdef BKTR_NEW_MSP34XX_DRIVER
525 if (bt848_stereo_once
!= 0) {
526 if ((bt848_stereo_once
>> 8) == unit
) {
527 bktr
->stereo_once
= (bt848_stereo_once
& 0xff);
531 if (bt848_amsound
!= -1) {
532 if ((bt848_amsound
>> 8) == unit
) {
533 bktr
->amsound
= (bt848_amsound
& 0xff);
537 if (bt848_dolby
!= -1) {
538 if ((bt848_dolby
>> 8) == unit
) {
539 bktr
->dolby
= (bt848_dolby
& 0xff);
544 switch ( FUNCTION( minor(dev
) ) ) {
546 result
= video_open( bktr
);
549 result
= tuner_open( bktr
);
552 result
= vbi_open( bktr
);
559 /* If there was an error opening the device, undo the busy status */
561 device_unbusy(devclass_get_device(bktr_devclass
, unit
));
570 bktr_close(struct dev_close_args
*ap
)
572 cdev_t dev
= ap
->a_head
.a_dev
;
577 unit
= UNIT( minor(dev
) );
579 /* Get the device data */
580 bktr
= (struct bktr_softc
*)devclass_get_softc(bktr_devclass
, unit
);
582 /* the device is no longer valid/functioning */
586 switch ( FUNCTION( minor(dev
) ) ) {
588 result
= video_close( bktr
);
591 result
= tuner_close( bktr
);
594 result
= vbi_close( bktr
);
601 device_unbusy(devclass_get_device(bktr_devclass
, unit
));
610 bktr_read(struct dev_read_args
*ap
)
612 cdev_t dev
= ap
->a_head
.a_dev
;
616 unit
= UNIT(minor(dev
));
618 /* Get the device data */
619 bktr
= (struct bktr_softc
*)devclass_get_softc(bktr_devclass
, unit
);
621 /* the device is no longer valid/functioning */
625 switch ( FUNCTION( minor(dev
) ) ) {
627 return( video_read( bktr
, unit
, dev
, ap
->a_uio
) );
629 return( vbi_read( bktr
, ap
->a_uio
, ap
->a_ioflag
) );
639 bktr_write(struct dev_write_args
*ap
)
641 return( EINVAL
); /* XXX or ENXIO ? */
649 bktr_ioctl(struct dev_ioctl_args
*ap
)
651 cdev_t dev
= ap
->a_head
.a_dev
;
652 u_long cmd
= ap
->a_cmd
;
656 unit
= UNIT(minor(dev
));
658 /* Get the device data */
659 bktr
= (struct bktr_softc
*)devclass_get_softc(bktr_devclass
, unit
);
661 /* the device is no longer valid/functioning */
665 #ifdef BKTR_GPIO_ACCESS
666 if (bktr
->bigbuf
== 0 && cmd
!= BT848_GPIO_GET_EN
&&
667 cmd
!= BT848_GPIO_SET_EN
&& cmd
!= BT848_GPIO_GET_DATA
&&
668 cmd
!= BT848_GPIO_SET_DATA
) /* no frame buffer allocated (ioctl failed) */
671 if (bktr
->bigbuf
== 0) /* no frame buffer allocated (ioctl failed) */
675 switch ( FUNCTION( minor(dev
) ) ) {
677 return( video_ioctl( bktr
, unit
, cmd
, ap
->a_data
, curthread
) );
679 return( tuner_ioctl( bktr
, unit
, cmd
, ap
->a_data
, curthread
) );
690 bktr_mmap(struct dev_mmap_args
*ap
)
692 cdev_t dev
= ap
->a_head
.a_dev
;
696 unit
= UNIT(minor(dev
));
698 if (FUNCTION(minor(dev
)) > 0) /* only allow mmap on /dev/bktr[n] */
701 /* Get the device data */
702 bktr
= (struct bktr_softc
*)devclass_get_softc(bktr_devclass
, unit
);
704 /* the device is no longer valid/functioning */
708 if (ap
->a_nprot
& PROT_EXEC
)
711 if (ap
->a_offset
< 0)
714 if (ap
->a_offset
>= bktr
->alloc_pages
* PAGE_SIZE
)
717 ap
->a_result
= atop(vtophys(bktr
->bigbuf
) + ap
->a_offset
);
722 bktr_poll(struct dev_poll_args
*ap
)
724 cdev_t dev
= ap
->a_head
.a_dev
;
729 unit
= UNIT(minor(dev
));
731 /* Get the device data */
732 bktr
= (struct bktr_softc
*)devclass_get_softc(bktr_devclass
, unit
);
734 /* the device is no longer valid/functioning */
741 if (ap
->a_events
& (POLLIN
| POLLRDNORM
)) {
743 switch ( FUNCTION( minor(dev
) ) ) {
745 if(bktr
->vbisize
== 0)
746 selrecord(curthread
, &bktr
->vbi_select
);
748 revents
|= ap
->a_events
& (POLLIN
| POLLRDNORM
);
756 ap
->a_events
= revents
;