aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralepulver <alepulver@FreeBSD.org>2006-10-06 08:23:21 +0800
committeralepulver <alepulver@FreeBSD.org>2006-10-06 08:23:21 +0800
commit6b17205a06641c3ef6f97433495f45294e66c639 (patch)
treea73cd5e278d1d6ee7c9586101d714690b0a26812
parentd071aba7187572f1265665ced58e4a310ebaa997 (diff)
downloadfreebsd-ports-gnome-6b17205a06641c3ef6f97433495f45294e66c639.tar.gz
freebsd-ports-gnome-6b17205a06641c3ef6f97433495f45294e66c639.tar.zst
freebsd-ports-gnome-6b17205a06641c3ef6f97433495f45294e66c639.zip
Add multimedia/pvrxxx, a patched version of pvr250 to support 150/500 cards.
PR: ports/102765 Submitted by: usleepless <usleepless@gmail.com>
-rw-r--r--multimedia/Makefile1
-rw-r--r--multimedia/pvrxxx/Makefile46
-rw-r--r--multimedia/pvrxxx/files/patch-cxm42
-rw-r--r--multimedia/pvrxxx/files/patch-cxm_iic14
-rw-r--r--multimedia/pvrxxx/files/patch-dev1427
-rw-r--r--multimedia/pvrxxx/files/patch-modules::cxm::cxm::Makefile9
-rw-r--r--multimedia/pvrxxx/files/patch-modules::cxm::cxm_iic::Makefile9
-rw-r--r--multimedia/pvrxxx/files/patch-pvr250-1.264
8 files changed, 1577 insertions, 35 deletions
diff --git a/multimedia/Makefile b/multimedia/Makefile
index c261a154b5ae..18893da9a073 100644
--- a/multimedia/Makefile
+++ b/multimedia/Makefile
@@ -180,6 +180,7 @@
SUBDIR += ppm2fli
SUBDIR += projectx
SUBDIR += pvr250
+ SUBDIR += pvrxxx
SUBDIR += pwcbsd
SUBDIR += py-gstreamer
SUBDIR += py-gstreamer80
diff --git a/multimedia/pvrxxx/Makefile b/multimedia/pvrxxx/Makefile
index 30c50351b59d..921229750447 100644
--- a/multimedia/pvrxxx/Makefile
+++ b/multimedia/pvrxxx/Makefile
@@ -1,29 +1,32 @@
-#
-# New ports collection makefile for: pvr250
-# Date created: 10 October 2004
-# Whom: Edwin Groothuis <edwin@mavetju.org>
+# New ports collection makefile for: pvrxxx
+# Date created: 22 August 2006
+# Whom: usleepless <usleepless@gmail.com>
#
# $FreeBSD$
#
-PORTNAME= pvr250
-PORTVERSION= 20051030
+PORTNAME= pvrxxx
+PORTVERSION= 20060822
CATEGORIES= multimedia
MASTER_SITES= http://www.mavetju.org/download/adopted/
-DISTFILES= ${CXMSHAR} hcwPVRP2.sys ${PVRTOOLS}.tar.gz
+DISTFILES= ${CXMSHAR} ${PVRTOOLS}.tar.gz hcwPVRP2.sys HcwMakoA.ROM pvrxxx_gpl.tgz
IGNOREFILES= hcwPVRP2.sys # Varies from month to month
-MAINTAINER= edwin@mavetju.org
-COMMENT= Hauppauge PVR-250/350 TV cards driver for the cxm device
+MAINTAINER= usleep@gmail.com
+COMMENT= Hauppauge PVR-150/500 TV cards driver for the cxm device, based on the pv250-port
+
+CONFLICTS= pvr250-*
PVRTOOLS= pvr250-1.2
-CXMSHAR= cxm-${PORTVERSION}.shar
+CXMSHAR= cxm-20051030.shar
WRKSRC= ${WRKDIR}
-NOFETCHFILES= hcwPVRP2.sys
+NOFETCHFILES= hcwPVRP2.sys HcwMakoA.ROM
-RESTRICTED_FILES= hcwPVRP2.sys
-RESTRICTED= "This port uses a binary driver which is owned by Hauppauge"
+RESTRICTED_FILES= hcwPVRP2.sys HcwMakoA.ROM
+RESTRICTED= This port uses a binary driver which is owned by Hauppauge
+NO_PACKAGE= ${RESTRICTED}
+NO_CDROM= ${RESTRICTED}
MAN4= cxm.4
MAN1= pvr250-setchannel.1
@@ -33,12 +36,17 @@ MAN1= pvr250-setchannel.1
.if ${OSVERSION} < 500000
MODULESDIR= /modules
.else
-MODULESDIR= /boot/kernel
+MODULESDIR= /boot/modules
.endif
PLIST_SUB= MODULESDIR=${MODULESDIR}
.if !exists(${DISTDIR}/hcwPVRP2.sys)
-IGNORE= You need the file hcwPVRP2.sys from the CD coming with the PVR-250/350 card. Please place this file in ${DISTDIR} and run make again.
+IGNORE= You need the file hcwPVRP2.sys from the CD coming with the PVR-150/500 card. Please place this file in ${DISTDIR} and run make again. Check http://ivtvdriver.org/index.php/Firmware for the recommended version.
+.endif
+
+.if !exists(${DISTDIR}/HcwMakoA.ROM)
+IGNORE= You need the file HcwMakoA.ROM from the CD coming with the PVR-150/500 card. Please place this file in ${DISTDIR} and run m
+ake again. Check http://ivtvdriver.org/index.php/Firmware for the recommended version.
.endif
.if !exists(/usr/src/sys/dev/iicbus/iicbb.c)
@@ -66,7 +74,9 @@ do-extract:
${MKDIR} ${WRKDIR}
cd ${WRKDIR}; \
${SH} ${DISTDIR}/${CXMSHAR}; \
- ${EXTRACT_CMD} ${EXTRACT_BEFORE_ARGS} ${_DISTDIR}/${PVRTOOLS}.tar.gz ${EXTRACT_AFTER_ARGS};
+ ${EXTRACT_CMD} ${EXTRACT_BEFORE_ARGS} ${_DISTDIR}/${PVRTOOLS}.tar.gz ${EXTRACT_AFTER_ARGS}; \
+ cd modules/cxm/cxm; \
+ ${EXTRACT_CMD} ${EXTRACT_BEFORE_ARGS} ${_DISTDIR}/pvrxxx_gpl.tgz ${EXTRACT_AFTER_ARGS};
post-patch:
.if ${OSVERSION} < 500000
@@ -82,7 +92,9 @@ post-patch:
do-configure:
cd ${WRKDIR}/dev/cxm; \
${CC} -Wall -o cxm_extract_fw cxm_extract_fw.c; \
- ./cxm_extract_fw ${DISTDIR}/hcwPVRP2.sys
+ ./cxm_extract_fw ${DISTDIR}/hcwPVRP2.sys; \
+ cd ../../modules/cxm/cxm; \
+ ../../../dev/cxm/cxm_extract_fw ${DISTDIR}/HcwMakoA.ROM;
do-build:
cd ${WRKDIR}/modules/cxm; ${MAKE}
diff --git a/multimedia/pvrxxx/files/patch-cxm b/multimedia/pvrxxx/files/patch-cxm
new file mode 100644
index 000000000000..8362ecde61b6
--- /dev/null
+++ b/multimedia/pvrxxx/files/patch-cxm
@@ -0,0 +1,42 @@
+Only in modules/cxm/cxm: @
+diff -ur ../work.orig/modules/cxm/cxm/Makefile modules/cxm/cxm/Makefile
+--- ../work.orig/modules/cxm/cxm/Makefile Fri Sep 1 23:10:08 2006
++++ modules/cxm/cxm/Makefile Wed Aug 23 15:21:41 2006
+@@ -1,7 +1,10 @@
+ .PATH: ${.CURDIR}/../../../dev/cxm
+ KMOD = cxm
+ SRCS = cxm.c cxm.h cxm_dec_fw.c cxm_enc_fw.c cxm_audio.c cxm_eeprom.c \
+- cxm_ir.c cxm_tuner.c cxm_video.c opt_cxm.h \
+- bus_if.h device_if.h iicbb_if.h pci_if.h vnode_if.h
++ cxm_ir.c cxm_tuner.c cxm_video.c \
++ tda9887.c fbsd-compat.c cx25840-core.c cx25840-audio.c cx25840-firmware.c cx25840_fw.c cx25840-vbi.c wm8775.c\
++ opt_cxm.h bus_if.h device_if.h iicbb_if.h pci_if.h vnode_if.h \
++ v4l2_ioctl_hook.h tda9887.h wm8775.h fbsd-compat.h
++CFLAGS+= -I../../..
+
+ .include <bsd.kmod.mk>
+Only in modules/cxm/cxm: asm
+Only in modules/cxm/cxm: audiochip.h
+Only in modules/cxm/cxm: cx25840-audio.c
+Only in modules/cxm/cxm: cx25840-core.c
+Only in modules/cxm/cxm: cx25840-firmware.c
+Only in modules/cxm/cxm: cx25840-vbi.c
+Only in modules/cxm/cxm: cx25840.h
+Only in modules/cxm/cxm: export_syms
+Only in modules/cxm/cxm: fbsd-compat.c
+Only in modules/cxm/cxm: fbsd-compat.h
+Only in modules/cxm/cxm: ivtv-compat.h
+Only in modules/cxm/cxm: linux
+Only in modules/cxm/cxm: machine
+Only in modules/cxm/cxm: opt_cxm.h
+Only in modules/cxm/cxm: tda9887.c
+Only in modules/cxm/cxm: tda9887.h
+Only in modules/cxm/cxm: tuner.h
+Only in modules/cxm/cxm: v4l2-common.h
+Only in modules/cxm/cxm: v4l2_ioctl_hook.c
+Only in modules/cxm/cxm: v4l2_ioctl_hook.h
+Only in modules/cxm/cxm: video_decoder.h
+Only in modules/cxm/cxm: videodev.h
+Only in modules/cxm/cxm: videodev2.h
+Only in modules/cxm/cxm: wm8775.c
+Only in modules/cxm/cxm: wm8775.h
diff --git a/multimedia/pvrxxx/files/patch-cxm_iic b/multimedia/pvrxxx/files/patch-cxm_iic
new file mode 100644
index 000000000000..5571a0472782
--- /dev/null
+++ b/multimedia/pvrxxx/files/patch-cxm_iic
@@ -0,0 +1,14 @@
+Only in modules/cxm/cxm_iic: @
+diff -ur ../work.orig/modules/cxm/cxm_iic/Makefile modules/cxm/cxm_iic/Makefile
+--- ../work.orig/modules/cxm/cxm_iic/Makefile Fri Sep 1 23:10:08 2006
++++ modules/cxm/cxm_iic/Makefile Tue Apr 25 20:35:23 2006
+@@ -2,5 +2,6 @@
+ KMOD = cxm_iic
+ SRCS = cxm_i2c.c cxm.h \
+ opt_cxm.h bus_if.h device_if.h iicbb_if.h pci_if.h
++CFLAGS += -I../../..
+
+ .include <bsd.kmod.mk>
+Only in modules/cxm/cxm_iic: export_syms
+Only in modules/cxm/cxm_iic: machine
+Only in modules/cxm/cxm_iic: opt_cxm.h
diff --git a/multimedia/pvrxxx/files/patch-dev b/multimedia/pvrxxx/files/patch-dev
new file mode 100644
index 000000000000..adbf2801f2eb
--- /dev/null
+++ b/multimedia/pvrxxx/files/patch-dev
@@ -0,0 +1,1427 @@
+diff -ur ../work.orig/dev/cxm/cxm.c dev/cxm/cxm.c
+--- ../work.orig/dev/cxm/cxm.c Fri Sep 1 23:10:08 2006
++++ dev/cxm/cxm.c Wed Aug 23 21:31:44 2006
+@@ -87,6 +87,9 @@
+
+ #include <dev/iicbus/iiconf.h>
+
++#include "v4l2_ioctl_hook.h"
++
++#include "wm8775.h"
+
+ /*
+ * Various supported device vendors/types and their names.
+@@ -353,6 +356,8 @@
+ &dvd_full_d1_pal_profile
+ };
+
++int jan_fps;
++
+
+ static unsigned int
+ cxm_queue_firmware_command( struct cxm_softc *sc,
+@@ -366,7 +371,7 @@
+ intrmask_t s;
+
+ if (nparameters > CXM_MBX_MAX_PARAMETERS) {
+- printf("%s: too many parameters for mailbox\n", sc->name);
++ log(LOG_DEBUG,"%s: too many parameters for mailbox\n", sc->name);
+ return -1;
+ }
+
+@@ -387,7 +392,8 @@
+ return -1;
+ }
+
+- s = spltty();
++ if(!sc->inint)
++ s = spltty();
+ for (i = 0; i < CXM_MBX_FW_CMD_MAILBOXES; i++) {
+ flags = CSR_READ_4(sc,
+ mailbox
+@@ -421,7 +427,8 @@
+ }
+
+ if (i >= CXM_MBX_FW_CMD_MAILBOXES) {
+- splx(s);
++ if(!sc->inint)
++ splx(s);
+ return -1;
+ }
+
+@@ -436,7 +443,8 @@
+
+ (void)CSR_READ_4(sc, mailbox + offsetof(struct cxm_mailbox, flags));
+
+- splx(s);
++ if(!sc->inint)
++ splx(s);
+
+ CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, command), cmd);
+ CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, timeout),
+@@ -448,12 +456,13 @@
+ + offsetof(struct cxm_mailbox, parameters)
+ + i * sizeof(u_int32_t),
+ *(parameters + i));
+-
++#ifdef _nuniet_
+ for ( ; i < CXM_MBX_MAX_PARAMETERS; i++)
+ CSR_WRITE_4(sc,
+ mailbox
+ + offsetof(struct cxm_mailbox, parameters)
+ + i * sizeof(u_int32_t), 0);
++#endif
+
+ CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags),
+ CXM_MBX_FLAG_IN_USE | CXM_MBX_FLAG_DRV_DONE);
+@@ -495,7 +504,7 @@
+ mailbox = cxm_queue_firmware_command(sc, mbx_name, cmd,
+ parameters, nparameters);
+ if (mailbox == -1) {
+- printf("%s: no free mailboxes\n", sc->name);
++ log(LOG_DEBUG,"%s: no free mailboxes\n", sc->name);
+ return -1;
+ }
+
+@@ -514,7 +523,7 @@
+ }
+
+ if (i >= 100) {
+- printf("%s: timeout\n", sc->name);
++ log(LOG_DEBUG,"%s: timeout\n", sc->name);
+ return -1;
+ }
+
+@@ -556,7 +565,7 @@
+ }
+
+ if (i >= 100) {
+- printf("%s: no free mailboxes\n", sc->name);
++ log(LOG_DEBUG,"%s: no free mailboxes\n", sc->name);
+ return -1;
+ }
+
+@@ -575,7 +584,7 @@
+ }
+
+ if (i >= 100) {
+- printf("%s: timeout\n", sc->name);
++ log(LOG_DEBUG,"%s: timeout\n", sc->name);
+ return -1;
+ }
+
+@@ -620,6 +629,7 @@
+ static void
+ cxm_set_irq_mask( struct cxm_softc *sc, u_int32_t mask )
+ {
++/* userland! */
+ intrmask_t s;
+
+ s = spltty();
+@@ -661,10 +671,12 @@
+ {
+
+ if (sc->cxm_iic) {
++#ifdef _nuniet_
+ if (cxm_saa7115_mute(sc) < 0)
+ return -1;
+ if (cxm_msp_mute(sc) < 0)
+ return -1;
++#endif
+ }
+
+ /* Halt the firmware */
+@@ -811,7 +823,7 @@
+ &parameter, 1) < 0)
+ return -1;
+
+- printf("%s: encoder firmware version %#x\n",
++ log(LOG_DEBUG,"%s: encoder firmware version %#x\n",
+ sc->name, (unsigned int)parameter);
+
+ /* Get decoder firmware version */
+@@ -822,14 +834,13 @@
+ &parameter, 1) < 0)
+ return -1;
+
+- printf("%s: decoder firmware version %#x\n",
++ log(LOG_DEBUG,"%s: decoder firmware version %#x\n",
+ sc->name, (unsigned int)parameter);
+ }
+
+ return 0;
+ }
+
+-
+ static int
+ cxm_configure_encoder( struct cxm_softc *sc )
+ {
+@@ -838,7 +849,7 @@
+ u_int32_t parameters[12];
+ const struct cxm_codec_profile *cpp;
+
+- if (sc->source == cxm_fm_source)
++ if (1 || sc->source == cxm_fm_source)
+ switch (cxm_tuner_selected_channel_set(sc)) {
+ case CHNLSET_NABCST:
+ case CHNLSET_CABLEIRC:
+@@ -854,8 +865,12 @@
+ else
+ fps = cxm_saa7115_detected_fps(sc);
+
++
+ if (fps < 0)
+- return -1;
++ {
++ log(LOG_DEBUG,"Could not detect FPS\n");
++ return -1;
++ }
+
+ if (sc->profile->fps != fps) {
+
+@@ -879,11 +894,12 @@
+ }
+
+ cpp = sc->profile;
+-
++/*
+ if (cxm_saa7115_configure(sc,
+ cpp->width, cpp->source_height, fps,
+ cpp->audio_sample_rate) < 0)
+ return -1;
++*/
+
+ /* assign dma block len */
+ parameters[0] = 1; /* Transfer block size = 1 */
+@@ -1090,17 +1106,26 @@
+ u_int32_t type;
+
+ if (sc->encoding)
++ {
++ log(LOG_DEBUG,"already encoding\n");
+ return 0;
++ }
+
+ if (cxm_configure_encoder(sc) < 0)
++ {
++ log(LOG_DEBUG,"could not config dec\n");
+ return -1;
++ }
+
+ /* Mute the video input if necessary. */
+ parameters[0] = sc->source == cxm_fm_source ? 1 : 0;
+ if (cxm_firmware_command(sc, cxm_enc_mailbox,
+ CXM_FW_CMD_MUTE_VIDEO_INPUT,
+ parameters, 1) != 0)
++ {
++ log(LOG_DEBUG,"could not mute vid inp\n");
+ return -1;
++ }
+
+ /* Clear pending encoder interrupts (which are currently masked) */
+ cxm_set_irq_status(sc, CXM_IRQ_ENC);
+@@ -1113,22 +1138,39 @@
+ if (cxm_firmware_command(sc, cxm_enc_mailbox,
+ CXM_FW_CMD_ENC_EVENT_NOTIFICATION,
+ parameters, 4) != 0)
++ {
++ log(LOG_DEBUG,"could not act evt not\n");
+ return -1;
++ }
+
++#ifdef _nuniet_
+ if (cxm_saa7115_mute(sc) < 0)
+ return -1;
+ if (cxm_msp_mute(sc) < 0)
+ return -1;
++#endif
+
+ if (cxm_firmware_command(sc, cxm_enc_mailbox,
+ CXM_FW_CMD_INITIALIZE_VIDEO_INPUT,
+ NULL, 0) < 0)
++ {
++ log(LOG_DEBUG,"could not init vid inp\n");
+ return -1;
++ }
+
++#ifdef _nuniet_
+ if (cxm_saa7115_unmute(sc) < 0)
+ return -1;
+ if (cxm_msp_unmute(sc) < 0)
+ return -1;
++#endif
++
++ cx25840_command(sc->iicbus, VIDIOC_STREAMOFF, NULL);
++
++cxm_firmware_command(sc,cxm_enc_mailbox, 0xcd, NULL, 0);
++
++ cx25840_command(sc->iicbus, VIDIOC_STREAMON, NULL);
++
+
+ /* Wait for 100ms */
+ (void)tsleep(&sc->encoding, PWAIT, "cxmce", hz / 10);
+@@ -1145,7 +1187,10 @@
+ parameters[1] = subtype;
+ if (cxm_firmware_command(sc, cxm_enc_mailbox,
+ CXM_FW_CMD_BEGIN_CAPTURE, parameters, 2) != 0)
++ {
++ log(LOG_DEBUG,"could not begin capt\n");
+ return -1;
++ }
+
+ sc->enc_pool.offset = 0;
+ sc->enc_pool.read = 0;
+@@ -1154,6 +1199,7 @@
+ sc->encoding_eos = 0;
+
+ sc->encoding = 1;
++ sc->inint = 0;
+
+ /* Enable interrupts */
+ cxm_set_irq_mask(sc, sc->irq_mask & ~CXM_IRQ_ENC);
+@@ -1165,10 +1211,12 @@
+ static int
+ cxm_stop_encoder( struct cxm_softc *sc )
+ {
++/* userland! */
+ u_int32_t parameters[4];
+ u_int32_t subtype;
+ u_int32_t type;
+ intrmask_t s;
++
+
+ if (! sc->encoding )
+ return 0;
+@@ -1191,11 +1239,13 @@
+ /* Wait for up to 1 second */
+ s = spltty();
+ if (! sc->encoding_eos )
++ {
+ (void)tsleep(&sc->encoding_eos, PWAIT, "cxmeos", hz);
++ }
+ splx(s);
+
+ if (sc->mpeg && ! sc->encoding_eos )
+- printf("%s: missing encoder EOS\n", sc->name);
++ log(LOG_DEBUG,"%s: missing encoder EOS\n", sc->name);
+
+ /* Disable event notification */
+ parameters[0] = 0; /* Event = 0 (refresh encoder input) */
+@@ -1257,9 +1307,9 @@
+ unsigned int macroblocks_per_line;
+ unsigned int scratch;
+ unsigned int words_per_line;
+- u_int32_t *ptr;
++ u_int32_t *ptr, *ptr_end;
+ u_int32_t *src;
+- size_t nbytes;
++ /* size_t nbytes; */
+
+ switch (sc->enc_pool.bufs[current].byte_order) {
+ case cxm_device_mpeg_byte_order:
+@@ -1267,17 +1317,23 @@
+ /*
+ * Convert each 32 bit word to the proper byte ordering.
+ */
+-
++#ifdef _nunieT_
+ for (nbytes = 0,
+ ptr = (u_int32_t *)sc->enc_pool.bufs[current].vaddr;
+ nbytes != sc->enc_pool.bufs[current].size;
+ nbytes += sizeof(*ptr), ptr++)
+ *ptr = bswap32(*ptr);
+-
++#else
++ ptr = (u_int32_t *)sc->enc_pool.bufs[current].vaddr ;
++ ptr_end = ptr + ( sc->enc_pool.bufs[current].size / sizeof(u_int32_t) );
++
++ for(;ptr < ptr_end;ptr++)
++ *ptr = bswap32(*ptr);
++#endif
+ break;
+
+ case cxm_device_yuv12_byte_order:
+-
++log(LOG_DEBUG,"yuv!\n");
+ /*
+ * Convert each macro block to planar using
+ * a scratch buffer (the buffer prior to the
+@@ -1349,12 +1405,12 @@
+ if (cxm_queue_firmware_command(sc, cxm_enc_mailbox,
+ CXM_FW_CMD_SCHED_DMA_TO_HOST,
+ parameters, 3) == -1) {
+- printf("%s: failed to discard encoder dma request\n",
++ log(LOG_DEBUG,"%s: failed to discard encoder dma request\n",
+ sc->name);
+ return;
+ }
+
+- sc->encoding_dma = -1;
++ sc->encoding_dma = 0; /* was -1 ?? */
+ }
+
+
+@@ -1363,10 +1419,11 @@
+ {
+ int buffers_pending;
+ u_int32_t status;
+- intrmask_t s;
++ /* unsigned int buffers_available; */
++ /* intrmask_t s; */
+
+ if (! sc->encoding_dma) {
+- printf("%s: encoder dma not already in progress\n",
++ log(LOG_DEBUG,"%s: encoder dma not already in progress\n",
+ sc->name);
+ return;
+ }
+@@ -1382,23 +1439,31 @@
+ if ((status
+ & (CXM_DMA_ERROR_LIST | CXM_DMA_ERROR_WRITE | CXM_DMA_SUCCESS))
+ != CXM_DMA_SUCCESS) {
+- printf("%s: encoder dma status %#x\n",
++ log(LOG_DEBUG,"%s: encoder dma status %#x\n",
+ sc->name, (unsigned int)status);
+ return;
+ }
+
+ /* Update the books (spl is used since mutex is not available) */
+- s = spltty();
++/* s = spltty(); */
+ sc->enc_pool.write = (sc->enc_pool.write + buffers_pending)
+ % CXM_SG_BUFFERS;
+- splx(s);
++ /* splx(s); */
+
+ /* signal anyone requesting notification */
+ if (sc->enc_proc)
+ psignal (sc->enc_proc, sc->enc_signal);
+
+- /* wakeup anyone waiting for data */
+- wakeup(&sc->enc_pool.read);
++ /* wakeup anyone waiting for data
++buffers_available = sc->enc_pool.write - sc->enc_pool.read;
++ if (buffers_available < 0)
++ buffers_available += CXM_SG_BUFFERS;
++
++ if(buffers_available >= sc->buffers_requested)
++ {
++ sc->buffers_requested = 0; */
++ wakeup(&sc->enc_pool.read);
++ /* } */
+
+ /* wakeup anyone polling for data */
+ selwakeup(&sc->enc_sel);
+@@ -1424,10 +1489,10 @@
+ size_t offset;
+ size_t size;
+ } requests[2];
+- intrmask_t s;
++ /* intrmask_t s; */
+
+ if (sc->encoding_dma) {
+- printf("%s: encoder dma already in progress\n",
++ log(LOG_DEBUG,"%s: encoder dma already in progress\n",
+ sc->name);
+ cxm_encoder_dma_discard(sc);
+ return;
+@@ -1436,12 +1501,11 @@
+ mailbox = sc->enc_mbx
+ + CXM_MBX_FW_DMA_MAILBOX * sizeof(struct cxm_mailbox);
+
+- for (i = 0; i < CXM_MBX_MAX_PARAMETERS; i++)
+- parameters[i]
++ parameters[0]
+ = CSR_READ_4(sc,
+ mailbox
+ + offsetof(struct cxm_mailbox, parameters)
+- + i * sizeof(u_int32_t));
++ + 0 * sizeof(u_int32_t));
+
+ byte_order = cxm_device_mpeg_byte_order;
+ max_sg_segment = CXM_SG_SEGMENT;
+@@ -1450,11 +1514,25 @@
+
+ switch (type) {
+ case 0: /* MPEG */
++ for (i = 1; i < 3/* CXM_MBX_MAX_PARAMETERS */; i++)
++ parameters[i]
++ = CSR_READ_4(sc,
++ mailbox
++ + offsetof(struct cxm_mailbox, parameters)
++ + i * sizeof(u_int32_t));
++
+ requests[nrequests].offset = parameters[1];
+ requests[nrequests++].size = parameters[2];
+ break;
+
+ case 1: /* YUV */
++ for (i = 1; i < 5/* CXM_MBX_MAX_PARAMETERS */; i++)
++ parameters[i]
++ = CSR_READ_4(sc,
++ mailbox
++ + offsetof(struct cxm_mailbox, parameters)
++ + i * sizeof(u_int32_t));
++
+ byte_order = cxm_device_yuv12_byte_order;
+
+ /*
+@@ -1482,7 +1560,7 @@
+ case 2: /* PCM (audio) */
+ case 3: /* VBI */
+ default:
+- printf("%s: encoder dma type %#x unsupported\n",
++ log(LOG_DEBUG,"%s: encoder dma type %#x unsupported\n",
+ sc->name, (unsigned int)type);
+ cxm_encoder_dma_discard(sc);
+ return;
+@@ -1492,11 +1570,11 @@
+ * Determine the number of buffers free at this * instant *
+ * taking into consideration that the ring buffer wraps.
+ */
+- s = spltty();
++ /* s = spltty(); */
+ buffers_free = sc->enc_pool.read - sc->enc_pool.write;
+ if (buffers_free <= 0)
+ buffers_free += CXM_SG_BUFFERS;
+- splx(s);
++ /* splx(s); */
+
+ /*
+ * Build the scatter / gather list taking in
+@@ -1508,10 +1586,11 @@
+
+ buffers_pending = 0;
+ current = sc->enc_pool.write;
++ /* splx(s); */
+
+ for (i = 0; i < nrequests; i++) {
+ if (! requests[i].size ) {
+- printf("%s: encoder dma size is zero\n", sc->name);
++ log(LOG_DEBUG,"%s: encoder dma size is zero\n", sc->name);
+ cxm_encoder_dma_discard(sc);
+ return;
+ }
+@@ -1536,7 +1615,7 @@
+ current = (current + 1) % CXM_SG_BUFFERS;
+
+ if (buffers_pending >= buffers_free) {
+- printf(
++ log(LOG_DEBUG,
+ "%s: encoder dma not enough buffer space free\n",
+ sc->name);
+ cxm_encoder_dma_discard(sc);
+@@ -1555,7 +1634,7 @@
+ if (cxm_queue_firmware_command(sc, cxm_enc_mailbox,
+ CXM_FW_CMD_SCHED_DMA_TO_HOST,
+ parameters, 3) == -1) {
+- printf("%s: failed to schedule encoder dma request\n",
++ log(LOG_DEBUG,"%s: failed to schedule encoder dma request\n",
+ sc->name);
+ return;
+ }
+@@ -1575,7 +1654,7 @@
+ static int
+ cxm_encoder_wait_for_lock( struct cxm_softc *sc )
+ {
+- int muted;
++ /* int muted; */
+ int locked;
+ int result;
+
+@@ -1590,6 +1669,7 @@
+ return result;
+ }
+
++#ifdef _nuniet_
+ /*
+ * Wait for the video decoder to lock.
+ */
+@@ -1616,6 +1696,7 @@
+ if (muted == 0 && cxm_msp_unmute(sc) < 0)
+ return -1;
+ }
++#endif
+
+ return locked;
+ }
+@@ -1678,6 +1759,8 @@
+ unit = device_get_unit(dev);
+
+ sc->type = cxm_iTVC15_type;
++ sc->inint =0;
++
+ switch(pci_get_device(dev)) {
+ case CXM_DEVICEID_CONEXANT_iTVC16:
+ sc->type = cxm_iTVC16_type;
+@@ -1737,6 +1820,7 @@
+ goto fail;
+ }
+
++
+ /*
+ * Initialize the tuner.
+ */
+@@ -1746,6 +1830,7 @@
+ goto fail;
+ }
+
++#ifdef _nuniet_
+ /*
+ * Initialize the SAA7115.
+ */
+@@ -1772,6 +1857,33 @@
+ error = ENXIO;
+ goto fail;
+ }
++#endif
++
++ cx25840_initialize(sc->iicbus,1);
++ tda9887_initialize(sc->iicbus);
++ wm8775_init(sc->iicbus);
++
++ { int jan = 0;
++
++ /* set the standard */
++ if(cxm_eeprom_get_std(sc))
++ {
++ device_printf(dev,"Eeprom NTSC\n");
++ jan = V4L2_STD_NTSC_M;
++ }
++ else
++ {
++ device_printf(dev,"Eeprom PAL\n");
++ jan = V4L2_STD_PAL;
++ }
++
++ tda9887_command(sc->iicbus, VIDIOC_S_STD , &jan);
++ cx25840_command(sc->iicbus, VIDIOC_S_STD , &jan);
++ }
++
++ DELAY(100000);
++
++ cx25840_command(sc->iicbus, VIDIOC_LOG_STATUS,NULL);
+
+ sc->dec_mbx = -1;
+ sc->enc_mbx = -1;
+@@ -1922,6 +2034,9 @@
+ goto fail;
+ }
+
++if(cxm_eeprom_get_std(sc))
++ sc->profile = &dvd_full_d1_pal_profile;
++else
+ sc->profile = &dvd_full_d1_ntsc_profile;
+
+ sc->source = cxm_tuner_source;
+@@ -2074,12 +2189,17 @@
+ /* Get the device data */
+ sc = (struct cxm_softc *)arg;
+
++ sc->inint = 1;
++
+ status = CSR_READ_4(sc, CXM_REG_IRQ_STATUS);
+
+ status &= ~sc->irq_mask;
+
+ if (! status )
++ {
++ sc->inint = 0;
+ return;
++ }
+
+ /* Process DMA done before handling a new DMA request or EOS */
+ if (status & CXM_IRQ_ENC_DMA_DONE)
+@@ -2093,6 +2213,8 @@
+ wakeup(&sc->encoding_eos);
+ }
+
++ sc->inint = 0;
++
+ cxm_set_irq_status(sc, status);
+ }
+
+@@ -2190,6 +2312,7 @@
+ int unit;
+ struct cxm_softc *sc;
+
++
+ unit = UNIT( minor(dev) );
+
+ /* Get the device data */
+@@ -2199,15 +2322,17 @@
+ return ENXIO;
+ }
+
+- if (sc->is_opened)
+- return EBUSY;
++ /* if (sc->is_opened)
++ return EBUSY; */
+
+- sc->is_opened = 1;
++ sc->is_opened++;
+ sc->mpeg = 1;
+
+ /* Record that the device is now busy */
+- device_busy(devclass_get_device(cxm_devclass, unit));
++ if(sc->is_opened==1)
++ device_busy(devclass_get_device(cxm_devclass, unit));
+
++log(LOG_DEBUG,"device %s opened\n", sc->name);
+ return 0;
+ }
+
+@@ -2254,12 +2379,16 @@
+ int
+ cxm_read( dev_t dev, struct uio *uio, int flag )
+ {
++/* userland! */
+ int buffers_available;
+ int buffers_read;
+ int error;
+ int unit;
+ unsigned int current;
+- unsigned int i;
++/* unsigned int i; */
++ unsigned int encread;
++/* unsigned int br; */
++ /*unsigned int uior; */
+ size_t nbytes;
+ size_t offset;
+ struct cxm_softc *sc;
+@@ -2277,38 +2406,50 @@
+ /* Only trigger the encoder if the ring buffer is empty */
+ if (! sc->encoding && sc->enc_pool.read == sc->enc_pool.write) {
+ if (cxm_start_encoder(sc) < 0)
++ {
++ log(LOG_DEBUG,"could not start encoder\n");
+ return ENXIO;
++ }
+ if (flag & IO_NDELAY)
+ return EWOULDBLOCK;
+ }
+-
++#ifdef _nuniet_
+ buffers_available = 0;
+
+- s = spltty();
+- while (sc->enc_pool.read == sc->enc_pool.write) {
++ s = spltty();
++
++ buffers_available = sc->enc_pool.write - sc->enc_pool.read;
++ if (buffers_available < 0)
++ buffers_available += CXM_SG_BUFFERS;
++
++ uior = uio->uio_resid;
++ br = sc->buffers_requested = uio->uio_resid / CXM_SG_SEGMENT;
++
++ while (buffers_available < sc->buffers_requested) { /* )sc->enc_pool.read = sc->enc_pool.write) { */
+ error = tsleep(&sc->enc_pool.read, PZERO | PCATCH, "cmxrd", 0);
++
++ buffers_available = sc->enc_pool.write - sc->enc_pool.read;
++ if (buffers_available < 0)
++ buffers_available += CXM_SG_BUFFERS;
++
+ if (error) {
+ splx(s);
+ return error;
+ }
+ }
+
+- /*
+- * Determine the number of buffers available at this * instant *
+- * taking in consideration that the ring buffer wraps.
+- */
+- buffers_available = sc->enc_pool.write - sc->enc_pool.read;
+- if (buffers_available < 0)
+- buffers_available += CXM_SG_BUFFERS;
++ offset = sc->enc_pool.offset;
++ encread = sc->enc_pool.read;
+ splx(s);
+
+- offset = sc->enc_pool.offset;
+-
+- for (buffers_read = 0, i = sc->enc_pool.read;
++ for (buffers_read = 0, i = encread;
+ buffers_read != buffers_available && uio->uio_resid;
+ buffers_read++, i = (i + 1) % CXM_SG_BUFFERS) {
+
+- current = cxm_encoder_fixup_byte_order (sc, i, offset);
++ if(!offset)
++ current = cxm_encoder_fixup_byte_order (sc, i, offset);
++ else
++ current = i;
+
+ nbytes = sc->enc_pool.bufs[current].size - offset;
+
+@@ -2328,20 +2469,85 @@
+ break;
+
+ offset = 0;
++ s = spltty();
++ sc->enc_pool.read = ( sc->enc_pool.read + 1 ) % CXM_SG_BUFFERS;
++ splx(s);
+ }
+-
+- sc->enc_pool.offset = offset;
++if(offset)
++ log(LOG_DEBUG,"offset = %d, bufs_req = %d, uio_req = %d\n",offset,br,uior);
+
+ /* Update the books (spl is used since mutex is not available) */
+- s = spltty();
+- sc->enc_pool.read = (sc->enc_pool.read + buffers_read)
+- % CXM_SG_BUFFERS;
+- splx(s);
++ /* s = spltty(); */
++ sc->enc_pool.offset = offset;
++
++ /* sc->enc_pool.read = (sc->enc_pool.read + buffers_read)
++ % CXM_SG_BUFFERS; */
++ /* splx(s); */
++#else
++ buffers_read = 0;
++ do {
++ s = spltty();
++ encread = sc->enc_pool.read = (sc->enc_pool.read + buffers_read) % CXM_SG_BUFFERS;
++ buffers_read = 0;
++ buffers_available = sc->enc_pool.write - sc->enc_pool.read;
++ offset = sc->enc_pool.offset;
++ splx(s);
++ if (buffers_available < 0)
++ buffers_available += CXM_SG_BUFFERS;
++
++ if(!uio->uio_resid)
++ {
++ break;
++ }
++
++ if(buffers_available == 0)
++ {
++ error = tsleep(&sc->enc_pool.read, PZERO | PCATCH, "cmxrd", 0);
++
++ if(error)
++ return error;
++ else
++ continue;
++ }
++ else
++ {
++ current = cxm_encoder_fixup_byte_order (sc, encread, offset);
++
++ nbytes = sc->enc_pool.bufs[current].size - offset;
++
++ /* Don't transfer more than requested */
++ if (nbytes > uio->uio_resid)
++ nbytes = uio->uio_resid;
++
++ error = uiomove(sc->enc_pool.bufs[current].vaddr + offset,
++ nbytes, uio);
++
++ if (error)
++ return error;
++
++ offset += nbytes;
++
++ /* Handle a partial read of a buffer */
++ if (! uio->uio_resid && offset != sc->enc_pool.bufs[current].size)
++ {
++ sc->enc_pool.offset = offset;
++ /* no need to update the books! */
++ break;
++ }
++
++ sc->enc_pool.offset = offset = 0;
++ buffers_read = 1;
++ }
++ } while(1);
++#endif
++
+
+ return 0;
+ }
+
+
++#include "v4l2_ioctl_hook.c"
++
+ /*
+ *
+ */
+@@ -2736,11 +2942,22 @@
+
+ switch (*(unsigned long *)arg & 0xf000) {
+ case METEOR_INPUT_DEV1:
++printf("tuner input\n");
+ source = cxm_tuner_source;
+ break;
+
+ case METEOR_INPUT_DEV2:
++{
++int arg;
+ source = cxm_line_in_source_composite;
++arg=AUDIO_EXTERN_1;
++cx25840_command(sc->iicbus, AUDC_SET_INPUT,&arg);
++wm8775_command(sc->iicbus, AUDC_SET_INPUT,&arg);
++
++
++arg=CX25840_COMPOSITE0;
++cx25840_command(sc->iicbus, VIDIOC_S_INPUT, &arg);
++}
+ break;
+
+ case METEOR_INPUT_DEV_SVIDEO:
+@@ -2766,11 +2983,12 @@
+
+ if (cxm_pause_encoder(sc) < 0)
+ return ENXIO;
+-
++/*
+ if (cxm_saa7115_select_source(sc, source) < 0)
+ return ENXIO;
+ if (cxm_msp_select_source(sc, source) < 0)
+ return ENXIO;
++*/
+
+ sc->source = source;
+
+@@ -2866,9 +3084,10 @@
+ break;
+
+ case TVTUNER_SETCHNL:
++/*
+ if (sc->source == cxm_tuner_source)
+ if (cxm_pause_encoder(sc) < 0)
+- return ENXIO;
++ return ENXIO; */
+
+ if (cxm_tuner_select_channel(sc, *(unsigned int *)arg) < 0)
+ return ENXIO;
+@@ -2881,6 +3100,7 @@
+ * Explicitly wait for the tuner lock so we
+ * can indicate if there's a station present.
+ */
++/*
+ if (cxm_tuner_wait_for_lock(sc) < 0)
+ return EINVAL;
+
+@@ -2888,11 +3108,11 @@
+ if (result < 0)
+ return ENXIO;
+ else if (result == 0)
+- return EINVAL;
+-
++ return EINVAL; */
++/*
+ if (sc->source == cxm_tuner_source)
+ if (cxm_unpause_encoder(sc) < 0)
+- return ENXIO;
++ return ENXIO; */
+ break;
+
+ case TVTUNER_GETFREQ:
+@@ -2930,6 +3150,8 @@
+ if (sc->source == cxm_tuner_source)
+ if (cxm_unpause_encoder(sc) < 0)
+ return ENXIO;
++
++ cx25840_command(sc->iicbus, VIDIOC_LOG_STATUS,NULL);
+ break;
+
+ case TVTUNER_GETSTATUS:
+@@ -2946,7 +3168,7 @@
+ break;
+
+ default:
+- return ENOTTY;
++ return v4l2_ioctl_hook(sc,cmd,arg);
+ }
+
+ return 0;
+diff -ur ../work.orig/dev/cxm/cxm.h dev/cxm/cxm.h
+--- ../work.orig/dev/cxm/cxm.h Fri Sep 1 23:10:08 2006
++++ dev/cxm/cxm.h Wed Aug 23 20:45:59 2006
+@@ -33,6 +33,15 @@
+ * Header file for the Conexant MPEG-2 Codec driver.
+ */
+
++#ifndef _cxm_h
++#define _cxm_h
++
++#if __FreeBSD_version >= 500014
++# include <sys/selinfo.h>
++#else
++# include <sys/select.h>
++#endif
++
+ #if __FreeBSD_version >= 503001
+ # define dev_t struct cdev *
+ #endif
+@@ -64,7 +73,7 @@
+ enum cxm_byte_order byte_order;
+ };
+
+-#define CXM_SG_BUFFERS 50
++#define CXM_SG_BUFFERS 16
+
+ struct cxm_buffer_pool {
+ bus_dma_tag_t dmat;
+@@ -183,7 +192,8 @@
+ * that the size of each piece must be a multiple of
+ * 256 and less than 64k.
+ */
+-#define CXM_SG_SEGMENT (0xff00 & ~(PAGE_SIZE - 1))
++#define CXM_SG_SEGMENT 32768
++/* (0xff00 & ~(PAGE_SIZE - 1)) */
+
+ struct cxm_sg_entry {
+ u_int32_t src;
+@@ -243,6 +253,8 @@
+
+ unsigned int dec_mbx;
+ unsigned int enc_mbx;
++ unsigned int inint;
++ unsigned int buffers_requested;
+
+ device_t cxm_iic;
+ device_t iicbus;
+@@ -266,6 +278,7 @@
+ int encoding;
+ int encoding_dma;
+ int encoding_eos;
++ int tuner_signal;
+ };
+
+ /*
+@@ -434,7 +447,7 @@
+ #define CXM_FW_CAPTURE_STREAM_PCM_AUDIO 0x00000002
+ #define CXM_FW_CAPTURE_STREAM_VBI 0x00000004
+
+-#define CXM_FW_STREAM_TYPE_DVD 0x0000000a
++#define CXM_FW_STREAM_TYPE_DVD 0x0000000e
+ #define CXM_FW_STREAM_TYPE_MPEG1 0x00000002
+ #define CXM_FW_STREAM_TYPE_MPEG2_PROGRAM 0x00000000
+ #define CXM_FW_STREAM_TYPE_SVCD 0x0000000c
+@@ -463,6 +476,7 @@
+ */
+ int cxm_eeprom_init( struct cxm_softc *sc );
+ int cxm_eeprom_tuner_type( struct cxm_softc *sc );
++int cxm_eeprom_get_std( struct cxm_softc *sc );
+
+ /*
+ * Infrared remote
+@@ -521,8 +535,9 @@
+ #define CXM_TUNER_LG_TAPE_H001F 18
+ #define CXM_TUNER_MICROTUNE_4049_FM5 19
+ #define CXM_TUNER_TCL_2002N_6A 20
++#define CXM_TUNER_SAMSUNG 21
+
+-#define CXM_TUNER_TYPES 21
++#define CXM_TUNER_TYPES 22
+
+ #define CXM_TUNER_AFC_MASK 0x07
+
+@@ -656,3 +671,5 @@
+ int cxm_saa7115_set_hue( struct cxm_softc *sc, unsigned char hue );
+ int cxm_saa7115_is_locked( struct cxm_softc *sc );
+ int cxm_saa7115_wait_for_lock( struct cxm_softc *sc );
++
++#endif /* cmx_h */
+diff -ur ../work.orig/dev/cxm/cxm_eeprom.c dev/cxm/cxm_eeprom.c
+--- ../work.orig/dev/cxm/cxm_eeprom.c Fri Sep 1 23:10:08 2006
++++ dev/cxm/cxm_eeprom.c Sun Aug 27 15:31:24 2006
+@@ -112,6 +112,16 @@
+ return 0;
+ }
+
++static unsigned int sup_std[4];
++
++int cxm_eeprom_get_std( struct cxm_softc *sc )
++{
++ int dev_num;
++
++ dev_num = device_get_unit(sc->iicbus);
++
++ return sup_std[dev_num] == 8; /* returns true if ntsc */
++}
+
+ int
+ cxm_eeprom_tuner_type( struct cxm_softc *sc )
+@@ -122,6 +132,11 @@
+ unsigned int subsystem_vendor_id;
+ unsigned int tuner_code;
+ int tuner_type;
++int dev_num;
++int beenhere;
++beenhere = 0;
++
++dev_num = device_get_unit(sc->iicbus);
+
+ if (cxm_eeprom_read(sc->iicbus, CXM_I2C_EEPROM,
+ eeprom, sizeof(eeprom), 0) != sizeof(eeprom))
+@@ -154,7 +169,7 @@
+ }
+ else if ((eeprom[i] & 0xf0) == 0x70) {
+ if (eeprom[i] & 0x08)
+- break;
++ break;
+ len = eeprom[i] & 0x07;
+ i++;
+ }
+@@ -174,11 +189,20 @@
+
+ switch (eeprom[i]) {
+ case 0x00:
+- tuner_code = eeprom[i + 6];
++ tuner_code = eeprom[i + 6];
++ sup_std[dev_num] = eeprom[i + 5];
+ break;
+
+ case 0x0a:
+- tuner_code = eeprom[i + 2];
++if(beenhere==0)
++{
++ tuner_code = eeprom[i + 2]; /* + 2 */
++ sup_std[dev_num] = eeprom[i + 1];
++beenhere = 1;
++}
++else
++printf("second(radio) tuner %d\n",(int)eeprom[i+2]);
++
+ break;
+
+ default:
+@@ -186,6 +210,8 @@
+ }
+ }
+
++printf("tuner code %d\n",tuner_code);
++
+ switch (tuner_code) {
+ case 0x03: /* Philips FI1216 */
+ case 0x08: /* Philips FI1216 MK2 */
+@@ -196,6 +222,8 @@
+ tuner_type = CXM_TUNER_PHILIPS_FQ1216ME;
+ break;
+
++case 0x69:
++case 0x5b:
+ case 0x37: /* Philips FQ1216ME MK3 */
+ tuner_type = CXM_TUNER_PHILIPS_FQ1216ME_MK3;
+ break;
+@@ -271,6 +299,9 @@
+ case 0x13: /* Philips FR1246 MK2 */
+ case 0x18: /* Philips FM1246 */
+ tuner_type = CXM_TUNER_PHILIPS_FM1246;
++ break;
++ case 0x57:
++ tuner_type = CXM_TUNER_SAMSUNG;
+ break;
+
+ default:
+diff -ur ../work.orig/dev/cxm/cxm_extract_fw.c dev/cxm/cxm_extract_fw.c
+--- ../work.orig/dev/cxm/cxm_extract_fw.c Fri Sep 1 23:10:08 2006
++++ dev/cxm/cxm_extract_fw.c Wed Aug 23 18:03:59 2006
+@@ -65,11 +65,18 @@
+ char outfile[MAXPATHLEN];
+ size_t i;
+
++#ifdef _nuniet_
+ if (nbytes < (256 * 1024)) {
+ fprintf (stderr, "%s: save_firmware -- firmware image isn't long enough\n",
+ MyName);
+ return -1;
+ }
++#endif
++
++ if(nbytes> ( 256*1024))
++ {
++ nbytes=256*1024;
++ }
+
+ if (snprintf (outfile, sizeof (outfile), "%s.c", name) >= sizeof (outfile)) {
+ fprintf (stderr, "%s: save_firmware -- firmware name is too long\n",
+@@ -86,10 +93,10 @@
+
+ fprintf (ofp, "#include <sys/types.h>\n"
+ "\n"
+- "const u_int8_t %s[] __attribute__ ((aligned(4))) = {",
++ "u_int8_t %s[] __attribute__ ((aligned(4))) = {",
+ name);
+
+- for (i = 0; i < (256 * 1024); i++) {
++ for (i = 0; i < nbytes; i++) {
+ if (i)
+ fputc (',', ofp);
+ if ((i % 8) == 0)
+@@ -167,6 +174,9 @@
+
+ close (fd);
+
++
++if(statbuf.st_size > 100000)
++{
+ decoder_fw_saved = 0;
+ encoder_fw_saved = 0;
+
+@@ -199,17 +209,23 @@
+ exit (1);
+ }
+ }
++}
++else
++{
++/* must be cx25840-file */
++save_firmware ("cx25840_fw", start, statbuf.st_size);
++}
+
+ munmap ((caddr_t)start, (size_t)statbuf.st_size);
+-
++/*
+ if (! decoder_fw_saved)
+ fprintf (stderr, "%s: decoder image not present\n", MyName);
+
+ if (! encoder_fw_saved)
+ fprintf (stderr, "%s: encoder image not present\n", MyName);
+-
+ if (! decoder_fw_saved || ! encoder_fw_saved)
+ exit (1);
++*/
+
+ exit (0);
+ }
+diff -ur ../work.orig/dev/cxm/cxm_i2c.c dev/cxm/cxm_i2c.c
+--- ../work.orig/dev/cxm/cxm_i2c.c Fri Sep 1 23:10:08 2006
++++ dev/cxm/cxm_i2c.c Wed Aug 23 21:13:52 2006
+@@ -375,6 +375,7 @@
+ */
+
+ (void)CSR_READ_4(sc, CXM_REG_I2C_SETSCL);
++
+ }
+
+
+@@ -396,6 +397,7 @@
+ */
+
+ (void)CSR_READ_4(sc, CXM_REG_I2C_SETSDA);
++
+ }
+
+
+@@ -408,6 +410,6 @@
+ cxm_iic_setsda(dev, data);
+
+ /* Wait for 10 usec */
+- DELAY(10);
++ DELAY(5);
+ }
+ #endif
+diff -ur ../work.orig/dev/cxm/cxm_tuner.c dev/cxm/cxm_tuner.c
+--- ../work.orig/dev/cxm/cxm_tuner.c Fri Sep 1 23:10:08 2006
++++ dev/cxm/cxm_tuner.c Wed Aug 23 22:56:51 2006
+@@ -1,5 +1,4 @@
+-/*
+- * Copyright (c) 2003, 2004, 2005
++ /* Copyright (c) 2003, 2004, 2005
+ * John Wehle <john@feith.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+@@ -314,6 +313,7 @@
+ 0, 0,
+ { 0 },
+ &l_air_channels },
++
+ { "Philips FQ1216ME MK3",
+ { CXM_TUNER_TV_SYSTEM_BG | CXM_TUNER_TV_SYSTEM_DK
+ | CXM_TUNER_TV_SYSTEM_I
+@@ -507,6 +507,15 @@
+ { 55250, { 0x8e, 0x01 } } },
+ 0, 0,
+ { 0 },
++ &us_cable_channels },
++ { "Samsung TCPN 2121P30A",
++ { CXM_TUNER_TV_SYSTEM_MN, cxm_none_system_code_style },
++ 55250, 801250,
++ { { 364500, { 0xce, 0x08 } },
++ { 130000, { 0xce, 0x02 } },
++ { 55250, { 0xce, 0x01 } } },
++ 0, 0,
++ { 0 },
+ &us_cable_channels }
+ };
+
+@@ -517,7 +526,7 @@
+ {
+ int received;
+
+- if (iicbus_start(iicbus, i2c_addr + 1, CXM_I2C_TIMEOUT) != 0)
++ if (iicbus_start(iicbus, i2c_addr + 1 , CXM_I2C_TIMEOUT) != 0)
+ return -1;
+
+ if (iicbus_read(iicbus, buf, len, &received, IIC_LAST_READ, 0) != 0)
+@@ -562,10 +571,14 @@
+ int tuner_type;
+
+ if (cxm_eeprom_init(sc) < 0)
++{
++printf("could not init tuner\n");
+ return -1;
++}
+
+ tuner_type = cxm_eeprom_tuner_type(sc);
+
++printf("tuner_type = %d\n",tuner_type);
+ if (tuner_type < 0 || tuner_type >= NUM_ELEMENTS(cxm_tuners))
+ return -1;
+
+@@ -575,10 +588,16 @@
+
+ if (cxm_tuner_read(sc->iicbus, CXM_I2C_TUNER, &status, sizeof(status))
+ != sizeof(status))
++{
++printf("could not read tuner\n");
+ return -1;
++}
+
+- if (cxm_tuner_select_channel(sc, 4) < 0)
++ if (cxm_tuner_select_channel(sc, 3) < 0)
++{
++printf("could not select channel\n");
+ return -1;
++}
+
+ printf("%s: %s tuner\n", sc->name, sc->tuner->name);
+
+@@ -737,18 +756,17 @@
+ for (band_code = sc->tuner->band_codes;
+ band_code->freq > freq; band_code++)
+ ;
+-
+ if (freq >= sc->tuner_freq) {
+- msg[0] = (unsigned char)(N >> 8);
+- msg[1] = (unsigned char)N;
++ msg[0] = (unsigned char)(N >> 8) & 0x7f;
++ msg[1] = (unsigned char)N & 0xff;
+ msg[2] = band_code->codes[0];
+ msg[3] = band_code->codes[1] | pb;
+ }
+ else {
+ msg[0] = band_code->codes[0];
+ msg[1] = band_code->codes[1] | pb;
+- msg[2] = (unsigned char)(N >> 8);
+- msg[3] = (unsigned char)N;
++ msg[2] = (unsigned char)(N >> 8) & 0x7f;
++ msg[3] = (unsigned char)N & 0xff;
+ }
+ msg[4] = aux;
+ break;
+@@ -758,25 +776,35 @@
+ }
+
+ if (N > 32767)
++{
++printf("N bigger than int\n");
+ return -1;
++}
+
+ if (cxm_tuner_write(sc->iicbus, CXM_I2C_TUNER, msg, tuner_msg_len)
+- != tuner_msg_len)
++ != (tuner_msg_len))
++{
++printf("write to tuner failed\n");
+ return -1;
++}
+
+ /*
+ * Program the IF processing after the tuner since some tuners
+ * use the control byte to set the address of the IF.
+ */
+
+- if (system_code) {
++ if (0 && system_code) {
++printf("sending system code\n");
+ msg[0] = 0x00;
+ msg[1] = system_code->codes[0];
+ msg[2] = system_code->codes[1];
+ msg[3] = system_code->codes[2];
+
+ if (cxm_tuner_write(sc->iicbus, CXM_I2C_TUNER_IF, msg, 4) != 4)
++{
++printf("system code sent failed\n");
+ return -1;
++}
+ }
+
+ sc->tuner_freq = freq;
+@@ -797,14 +825,20 @@
+ if (! channels
+ || channel < channels->min_channel
+ || channel > channels->max_channel)
++{
++printf("channel out of range\n");
+ return -1;
++}
+
+ for (assignments = channels->assignments;
+ assignments->channel > channel; assignments++)
+ ;
+
+ if (! assignments->freq)
++{
++printf("no freq\n");
+ return -1;
++}
+
+ freq = assignments->freq
+ + (channel - assignments->channel) * assignments->step;
+@@ -824,6 +858,7 @@
+ unsigned long prev_freq;
+ unsigned long step_size;
+
++printf("in afc\n");
+ if (cxm_tuner_wait_for_lock(sc) != 1)
+ return -1;
+
+@@ -835,13 +870,20 @@
+ step_size = 63;
+
+ for (i = 0; i < (max_offset / step_size); i++) {
++printf("afc stepping\n");
+ status = cxm_tuner_status(sc);
+
+ if (status == -1)
++{
++printf("afc sattus =1\n");
+ break;
++}
+
+ if (! (status & CXM_TUNER_PHASE_LOCKED) )
++{
++printf("afc pl\n");
+ break;
++}
+
+ switch (status & CXM_TUNER_AFC_MASK) {
+ case CXM_TUNER_AFC_FREQ_CENTERED:
+@@ -862,7 +904,11 @@
+ }
+
+ if (freq == prev_freq)
++{
++printf("afc terug bij af\n");
+ return 0;
++}
++
+ prev_freq = sc->tuner_freq;
+
+ if (cxm_tuner_select_frequency(sc, cxm_tuner_tv_freq_type,
+@@ -963,7 +1009,10 @@
+
+ if (cxm_tuner_read(sc->iicbus, CXM_I2C_TUNER, &status, sizeof(status))
+ != sizeof(status))
++{
++printf("no status read\n");
+ return -1;
++}
+
+ if (sc->tuner->systems.code_style == cxm_if_system_code_style
+ || sc->tuner->systems.code_style
diff --git a/multimedia/pvrxxx/files/patch-modules::cxm::cxm::Makefile b/multimedia/pvrxxx/files/patch-modules::cxm::cxm::Makefile
deleted file mode 100644
index b06e1e1445f7..000000000000
--- a/multimedia/pvrxxx/files/patch-modules::cxm::cxm::Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
---- modules/cxm/cxm/Makefile.orig Fri Oct 15 20:53:47 2004
-+++ modules/cxm/cxm/Makefile Fri Oct 15 20:55:03 2004
-@@ -3,5 +3,6 @@
- SRCS = cxm.c cxm.h cxm_dec_fw.c cxm_enc_fw.c cxm_audio.c cxm_eeprom.c \
- cxm_ir.c cxm_tuner.c cxm_video.c opt_cxm.h \
- bus_if.h device_if.h iicbb_if.h pci_if.h vnode_if.h
-+CFLAGS+= -I../../..
-
- .include <bsd.kmod.mk>
diff --git a/multimedia/pvrxxx/files/patch-modules::cxm::cxm_iic::Makefile b/multimedia/pvrxxx/files/patch-modules::cxm::cxm_iic::Makefile
deleted file mode 100644
index 8fd5589aa033..000000000000
--- a/multimedia/pvrxxx/files/patch-modules::cxm::cxm_iic::Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
---- modules/cxm/cxm_iic/Makefile.orig Fri Oct 15 20:55:23 2004
-+++ modules/cxm/cxm_iic/Makefile Fri Oct 15 20:55:43 2004
-@@ -2,5 +2,6 @@
- KMOD = cxm_iic
- SRCS = cxm_i2c.c cxm.h \
- opt_cxm.h bus_if.h device_if.h iicbb_if.h pci_if.h
-+CFLAGS += -I../../..
-
- .include <bsd.kmod.mk>
diff --git a/multimedia/pvrxxx/files/patch-pvr250-1.2 b/multimedia/pvrxxx/files/patch-pvr250-1.2
new file mode 100644
index 000000000000..3e0bf71f4b79
--- /dev/null
+++ b/multimedia/pvrxxx/files/patch-pvr250-1.2
@@ -0,0 +1,64 @@
+Only in pvr250-1.2: setchannel
+diff -ur ../work.orig/pvr250-1.2/setchannel.c pvr250-1.2/setchannel.c
+--- ../work.orig/pvr250-1.2/setchannel.c Mon May 2 02:03:12 2005
++++ pvr250-1.2/setchannel.c Thu Aug 17 11:51:31 2006
+@@ -58,6 +58,7 @@
+ printf("Usage: setchannel [-a {on|off}] [-c | -r | -s | -t] [-g geom] [-m chnl_set] [chnl | freq]\n"
+ " -a Enable / disable AFC.\n"
+ " -c Select composite input.\n"
++ " -d Select unit ( 0..x ). \n"
+ " -r Select radio input.\n"
+ " -s Select svideo input.\n"
+ " -t Select tuner.\n"
+@@ -93,6 +94,7 @@
+ int i;
+ int status;
+ int tfd;
++ int unit;
+ unsigned int channel;
+ unsigned int fraction;
+ unsigned int freq;
+@@ -107,11 +109,12 @@
+ channel_set = -1;
+ device = 0;
+ freq = 0;
++ unit = 0;
+ status = 0;
+ x_size = 0;
+ y_size = 0;
+
+- while ((c = getopt (argc, argv, "a:crstg:m:")) != -1)
++ while ((c = getopt (argc, argv, "a:crstg:m:d:")) != -1)
+ switch (c) {
+ case 'a':
+ if (strcasecmp (optarg, "on") == 0)
+@@ -124,6 +127,10 @@
+ }
+ break;
+
++ case 'd':
++ unit = atoi (optarg);
++ break;
++
+ case 'c':
+ device = METEOR_INPUT_DEV2;
+ audio = -1;
+@@ -208,11 +215,15 @@
+ exit (1);
+ }
+
+- tfd = open( "/dev/cxm0", O_RDONLY );
++{ char buf[255];
++ sprintf(buf,"/dev/cxm%d",unit);
++
++ tfd = open( buf, O_RDONLY );
+ if ( tfd < 0 ) {
+- perror( "open() of /dev/tuner0 failed." );
++ perror( "open() of /dev/cxm0 failed." );
+ exit(1);
+ }
++}
+
+ if (afc != -1)
+ if ( ioctl( tfd, TVTUNER_SETAFC, &afc ) < 0 ) {
+Only in pvr250-1.2: setchannel.c.bak