V4L/DVB (4029): [PATCH] Genpix 8PSK->USB driver (Take 2)
authorAlan Nisota <alannisota@gmail.com>
Sun, 14 May 2006 16:23:56 +0000 (13:23 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Sun, 25 Jun 2006 05:00:32 +0000 (02:00 -0300)
This is a patch which includes support for the GENPIX 8PSK->USB module.  The
board supports QPSK, BPSK and 8PSK decoding (though I don't think it will be
DVB-S2 compliant) With the following patch, the boad is equivalent to a budget
card (no CA Module)
The patch which adds 8psk suppot will follow, but is seperate, as it requires
DVB-S2 support
More info on the board can be found at www.genpix-electronics.com (and they
host the requisite firmwares there as well)
Signed off by: Alan Nisota <alannisota@gmail.com>

Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/Makefile
drivers/media/dvb/dvb-usb/dvb-usb-ids.h
drivers/media/dvb/dvb-usb/gp8psk-fe.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb/gp8psk.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb/gp8psk.h [new file with mode: 0644]

index e388fb1567d6ec6d813158bc29516e07ecd8c496..5350e963c17b70dab0633252d731aefb26eb91d0 100644 (file)
@@ -130,6 +130,15 @@ config DVB_USB_VP702X
 
          DVB-S USB2.0 receivers.
 
+config DVB_USB_GP8PSK
+       tristate "GENPIX 8PSK->USB module support"
+       depends on DVB_USB
+       help
+         Say Y here to support the
+           GENPIX 8psk module
+
+         DVB-S USB2.0 receivers.
+
 config DVB_USB_NOVA_T_USB2
        tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
        depends on DVB_USB
index 2dc9aad9681e36825043ce1d0dd8628139fdaa3a..9643f56c7fe9a02e3f5e88e3d01bbd4875bf852a 100644 (file)
@@ -7,6 +7,9 @@ obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
 dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o
 obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
 
+dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o
+obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
+
 dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
 obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
 
index cb239049b09836dc46b0f058d961c638aa1333aa..95698918bc116878da6ae4ac96f2b77661cf127d 100644 (file)
@@ -31,6 +31,7 @@
 #define USB_VID_VISIONPLUS                                     0x13d3
 #define USB_VID_TWINHAN                                                0x1822
 #define USB_VID_ULTIMA_ELECTRONIC                      0x05d8
+#define USB_VID_GENPIX                                 0x09c0
 
 /* Product IDs */
 #define USB_PID_ADSTECH_USB2_COLD                      0xa333
 #define USB_PID_KYE_DVB_T_WARM                         0x701f
 #define USB_PID_PCTV_200E                                      0x020e
 #define USB_PID_PCTV_400E                                      0x020f
-
+#define USB_PID_GENPIX_8PSK_COLD                               0x0200
+#define USB_PID_GENPIX_8PSK_WARM                               0x0201
 #endif
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
new file mode 100644 (file)
index 0000000..6ccbdc9
--- /dev/null
@@ -0,0 +1,272 @@
+/* DVB USB compliant Linux driver for the
+ *  - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ *     This program is free software; you can redistribute it and/or modify it
+ *     under the terms of the GNU General Public License as published by the Free
+ *     Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "gp8psk.h"
+
+struct gp8psk_fe_state {
+       struct dvb_frontend fe;
+
+       struct dvb_usb_device *d;
+
+       u16 snr;
+
+       unsigned long next_snr_check;
+};
+
+static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
+{
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+       u8 lock;
+
+       if (gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0, 0, &lock,1))
+               return -EINVAL;
+
+       if (lock)
+               *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
+       else
+               *status = 0;
+
+       return 0;
+}
+
+/* not supported by this Frontend */
+static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+       (void) fe;
+       *ber = 0;
+       return 0;
+}
+
+/* not supported by this Frontend */
+static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+       (void) fe;
+       *unc = 0;
+       return 0;
+}
+
+static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+       u8 buf[2];
+
+       if (time_after(jiffies,st->next_snr_check)) {
+               gp8psk_usb_in_op(st->d,GET_SIGNAL_STRENGTH,0,0,buf,2);
+               *snr = (int)(buf[1]) << 8 | buf[0];
+               /* snr is reported in dBu*256 */
+               /* snr / 38.4 ~= 100% strength */
+               /* snr * 17 returns 100% strength as 65535 */
+               if (*snr <= 3855)
+                       *snr = (*snr<<4) + *snr; // snr * 17
+               else
+                       *snr = 65535;
+               st->next_snr_check = jiffies + (10*HZ)/1000;
+       } else {
+               *snr = st->snr;
+       }
+       return 0;
+}
+
+static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+       return gp8psk_fe_read_snr(fe, strength);
+}
+
+static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 800;
+       return 0;
+}
+
+static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
+                                 struct dvb_frontend_parameters *fep)
+{
+       struct gp8psk_fe_state *state = fe->demodulator_priv;
+       u8 cmd[10];
+       u32 freq = fep->frequency * 1000;
+
+       cmd[4] = freq         & 0xff;
+       cmd[5] = (freq >> 8)  & 0xff;
+       cmd[6] = (freq >> 16) & 0xff;
+       cmd[7] = (freq >> 24) & 0xff;
+
+       switch(fe->ops.info.type) {
+       case FE_QPSK:
+               cmd[0] =  fep->u.qpsk.symbol_rate        & 0xff;
+               cmd[1] = (fep->u.qpsk.symbol_rate >>  8) & 0xff;
+               cmd[2] = (fep->u.qpsk.symbol_rate >> 16) & 0xff;
+               cmd[3] = (fep->u.qpsk.symbol_rate >> 24) & 0xff;
+               cmd[8] = ADV_MOD_DVB_QPSK;
+               cmd[9] = 0x03; /*ADV_MOD_FEC_XXX*/
+               break;
+       default:
+               // other modes are unsuported right now
+               cmd[0] = 0;
+               cmd[1] = 0;
+               cmd[2] = 0;
+               cmd[3] = 0;
+               cmd[8] = 0;
+               cmd[9] = 0;
+               break;
+       }
+
+       gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10);
+
+       state->next_snr_check = jiffies;
+
+       return 0;
+}
+
+static int gp8psk_fe_get_frontend(struct dvb_frontend* fe,
+                                 struct dvb_frontend_parameters *fep)
+{
+       return 0;
+}
+
+
+static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
+                                   struct dvb_diseqc_master_cmd *m)
+{
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+
+       deb_fe("%s\n",__FUNCTION__);
+
+       if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
+                       m->msg, m->msg_len)) {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe,
+                                   fe_sec_mini_cmd_t burst)
+{
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+       u8 cmd;
+
+       deb_fe("%s\n",__FUNCTION__);
+
+       /* These commands are certainly wrong */
+       cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
+
+       if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
+                       &cmd, 0)) {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct gp8psk_fe_state* state = fe->demodulator_priv;
+
+       if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
+                (tone == SEC_TONE_ON), 0, NULL, 0)) {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct gp8psk_fe_state* state = fe->demodulator_priv;
+
+       if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
+                        voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
+{
+       struct gp8psk_fe_state* state = fe->demodulator_priv;
+       u8 cmd = sw_cmd & 0x7f;
+
+       if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
+                       NULL, 0)) {
+               return -EINVAL;
+       }
+       if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
+                       0, NULL, 0)) {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void gp8psk_fe_release(struct dvb_frontend* fe)
+{
+       struct gp8psk_fe_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops gp8psk_fe_ops;
+
+struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
+{
+       struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
+       if (s == NULL)
+               goto error;
+
+       s->d = d;
+       memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
+       s->fe.demodulator_priv = s;
+
+       goto success;
+error:
+       return NULL;
+success:
+       return &s->fe;
+}
+
+
+static struct dvb_frontend_ops gp8psk_fe_ops = {
+       .info = {
+               .name                   = "Genpix 8psk-USB DVB-S",
+               .type                   = FE_QPSK,
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 100,
+               .symbol_rate_min        = 1000000,
+               .symbol_rate_max        = 45000000,
+               .symbol_rate_tolerance  = 500,  /* ppm */
+               .caps = FE_CAN_INVERSION_AUTO |
+                               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                               FE_CAN_QPSK
+       },
+
+       .release = gp8psk_fe_release,
+
+       .init = NULL,
+       .sleep = NULL,
+
+       .set_frontend = gp8psk_fe_set_frontend,
+       .get_frontend = gp8psk_fe_get_frontend,
+       .get_tune_settings = gp8psk_fe_get_tune_settings,
+
+       .read_status = gp8psk_fe_read_status,
+       .read_ber = gp8psk_fe_read_ber,
+       .read_signal_strength = gp8psk_fe_read_signal_strength,
+       .read_snr = gp8psk_fe_read_snr,
+       .read_ucblocks = gp8psk_fe_read_unc_blocks,
+
+       .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg,
+       .diseqc_send_burst = gp8psk_fe_send_diseqc_burst,
+       .set_tone = gp8psk_fe_set_tone,
+       .set_voltage = gp8psk_fe_set_voltage,
+       .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd,
+};
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
new file mode 100644 (file)
index 0000000..d6771cb
--- /dev/null
@@ -0,0 +1,254 @@
+/* DVB USB compliant Linux driver for the
+ *  - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ *     This program is free software; you can redistribute it and/or modify it
+ *     under the terms of the GNU General Public License as published by the Free
+ *     Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "gp8psk.h"
+
+/* debug */
+static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
+int dvb_usb_gp8psk_debug;
+module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+{
+       int ret = 0,try = 0;
+
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
+               return ret;
+
+       while (ret >= 0 && ret != blen && try < 3) {
+               ret = usb_control_msg(d->udev,
+                       usb_rcvctrlpipe(d->udev,0),
+                       req,
+                       USB_TYPE_VENDOR | USB_DIR_IN,
+                       value,index,b,blen,
+                       2000);
+               deb_info("reading number %d (ret: %d)\n",try,ret);
+               try++;
+       }
+
+       if (ret < 0 || ret != blen) {
+               warn("usb in operation failed.");
+               ret = -EIO;
+       } else
+               ret = 0;
+
+       deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+       debug_dump(b,blen,deb_xfer);
+
+       mutex_unlock(&d->usb_mutex);
+
+       return ret;
+}
+
+int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+                            u16 index, u8 *b, int blen)
+{
+       int ret;
+
+       deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+       debug_dump(b,blen,deb_xfer);
+
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
+               return ret;
+
+       if (usb_control_msg(d->udev,
+                       usb_sndctrlpipe(d->udev,0),
+                       req,
+                       USB_TYPE_VENDOR | USB_DIR_OUT,
+                       value,index,b,blen,
+                       2000) != blen) {
+               warn("usb out operation failed.");
+               ret = -EIO;
+       } else
+               ret = 0;
+       mutex_unlock(&d->usb_mutex);
+
+       return ret;
+}
+
+static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
+{
+       int ret;
+       const struct firmware *fw = NULL;
+       u8 *ptr, *buf;
+       if ((ret = request_firmware(&fw, bcm4500_firmware,
+                                       &d->udev->dev)) != 0) {
+               err("did not find the bcm4500 firmware file. (%s) "
+                       "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
+                       bcm4500_firmware,ret);
+               return ret;
+       }
+
+       if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0)) {
+               release_firmware(fw);
+               return -EINVAL;
+       }
+
+       info("downloaidng bcm4500 firmware from file '%s'",bcm4500_firmware);
+
+       ptr = fw->data;
+       buf = (u8 *) kmalloc(512, GFP_KERNEL | GFP_DMA);
+
+       while (ptr[0] != 0xff) {
+               u16 buflen = ptr[0] + 4;
+               if (ptr + buflen >= fw->data + fw->size) {
+                       err("failed to load bcm4500 firmware.");
+                       release_firmware(fw);
+                       kfree(buf);
+                       return -EINVAL;
+               }
+               memcpy(buf, ptr, buflen);
+               if (dvb_usb_generic_write(d, buf, buflen)) {
+                       err("failed to load bcm4500 firmware.");
+                       release_firmware(fw);
+                       kfree(buf);
+                       return -EIO;
+               }
+               ptr += buflen;
+       }
+       release_firmware(fw);
+       kfree(buf);
+       return 0;
+}
+
+static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       u8 status, buf;
+       if (onoff) {
+               gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
+               if (! (status & 0x01))  /* started */
+                       if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
+                               return -EINVAL;
+
+               if (! (status & 0x02)) /* BCM4500 firmware loaded */
+                       if(gp8psk_load_bcm4500fw(d))
+                               return EINVAL;
+
+               if (! (status & 0x04)) /* LNB Power */
+                       if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
+                                       &buf, 1))
+                               return EINVAL;
+
+               /* Set DVB mode */
+               if(gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
+                       return -EINVAL;
+               gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
+       } else {
+               /* Turn off LNB power */
+               if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
+                       return EINVAL;
+               /* Turn off 8psk power */
+               if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
+                       return -EINVAL;
+
+       }
+       return 0;
+}
+
+
+static int gp8psk_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       return gp8psk_usb_out_op(d, ARM_TRANSFER, onoff, 0 , NULL, 0);
+}
+
+static int gp8psk_frontend_attach(struct dvb_usb_device *d)
+{
+       d->fe = gp8psk_fe_attach(d);
+
+       return 0;
+}
+
+static struct dvb_usb_properties gp8psk_properties;
+
+static int gp8psk_usb_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       return dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL);
+}
+
+static struct usb_device_id gp8psk_usb_table [] = {
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_COLD) },
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_WARM) },
+           { 0 },
+};
+MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
+
+static struct dvb_usb_properties gp8psk_properties = {
+       .caps = 0,
+
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-gp8psk-01.fw",
+
+       .streaming_ctrl   = gp8psk_streaming_ctrl,
+       .power_ctrl       = gp8psk_power_ctrl,
+       .frontend_attach  = gp8psk_frontend_attach,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+       /* parameter for the MPEG2-data transfer */
+       .urb = {
+               .type = DVB_USB_BULK,
+               .count = 7,
+               .endpoint = 0x82,
+               .u = {
+                       .bulk = {
+                               .buffersize = 8192,
+                       }
+               }
+       },
+
+       .num_device_descs = 1,
+       .devices = {
+               { .name = "Genpix 8PSK-USB DVB-S USB2.0 receiver",
+                 .cold_ids = { &gp8psk_usb_table[0], NULL },
+                 .warm_ids = { &gp8psk_usb_table[1], NULL },
+               },
+               { 0 },
+       }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver gp8psk_usb_driver = {
+       .name           = "dvb_usb_gp8psk",
+       .probe          = gp8psk_usb_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table       = gp8psk_usb_table,
+};
+
+/* module stuff */
+static int __init gp8psk_usb_module_init(void)
+{
+       int result;
+       if ((result = usb_register(&gp8psk_usb_driver))) {
+               err("usb_register failed. (%d)",result);
+               return result;
+       }
+
+       return 0;
+}
+
+static void __exit gp8psk_usb_module_exit(void)
+{
+       /* deregister this driver from the USB subsystem */
+       usb_deregister(&gp8psk_usb_driver);
+}
+
+module_init(gp8psk_usb_module_init);
+module_exit(gp8psk_usb_module_exit);
+
+MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
+MODULE_DESCRIPTION("Driver for Genpix 8psk-USB DVB-S USB2.0");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h
new file mode 100644 (file)
index 0000000..3eba706
--- /dev/null
@@ -0,0 +1,79 @@
+/* DVB USB compliant Linux driver for the
+ *  - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ *     This program is free software; you can redistribute it and/or modify it
+ *     under the terms of the GNU General Public License as published by the Free
+ *     Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_GP8PSK_H_
+#define _DVB_USB_GP8PSK_H_
+
+#define DVB_USB_LOG_PREFIX "gp8psk"
+#include "dvb-usb.h"
+
+extern int dvb_usb_gp8psk_debug;
+#define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
+#define deb_rc(args...)   dprintk(dvb_usb_gp8psk_debug,0x04,args)
+#define deb_fe(args...)   dprintk(dvb_usb_gp8psk_debug,0x08,args)
+/* gp8psk commands */
+
+/* Twinhan Vendor requests */
+#define TH_COMMAND_IN                     0xC0
+#define TH_COMMAND_OUT                    0xC1
+
+/* command bytes */
+#define GET_8PSK_CONFIG                 0x80
+#define SET_8PSK_CONFIG                 0x81
+#define ARM_TRANSFER                    0x85
+#define TUNE_8PSK                       0x86
+#define GET_SIGNAL_STRENGTH             0x87
+#define LOAD_BCM4500                    0x88
+#define BOOT_8PSK                       0x89
+#define START_INTERSIL                  0x8A
+#define SET_LNB_VOLTAGE                 0x8B
+#define SET_22KHZ_TONE                  0x8C
+#define SEND_DISEQC_COMMAND             0x8D
+#define SET_DVB_MODE                    0x8E
+#define SET_DN_SWITCH                   0x8F
+#define GET_SIGNAL_LOCK                 0x90
+
+/* Satellite modulation modes */
+#define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
+#define ADV_MOD_TURBO_QPSK 1   /* Turbo QPSK */
+#define ADV_MOD_TURBO_8PSK 2   /* Turbo 8PSK (also used for Trellis 8PSK) */
+#define ADV_MOD_TURBO_16QAM 3  /* Turbo 16QAM (also used for Trellis 8PSK) */
+
+#define ADV_MOD_DCII_C_QPSK 4  /* Digicipher II Combo */
+#define ADV_MOD_DCII_I_QPSK 5  /* Digicipher II I-stream */
+#define ADV_MOD_DCII_Q_QPSK 6  /* Digicipher II Q-stream */
+#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
+#define ADV_MOD_DSS_QPSK 8     /* DSS (DIRECTV) QPSK */
+#define ADV_MOD_DVB_BPSK 9     /* DVB-S BPSK */
+
+#define GET_USB_SPEED                     0x07
+ #define USB_SPEED_LOW                    0
+ #define USB_SPEED_FULL                   1
+ #define USB_SPEED_HIGH                   2
+
+#define RESET_FX2                         0x13
+
+#define FW_VERSION_READ                   0x0B
+#define VENDOR_STRING_READ                0x0C
+#define PRODUCT_STRING_READ               0x0D
+#define FW_BCD_VERSION_READ               0x14
+
+extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
+extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+                            u16 index, u8 *b, int blen);
+
+#endif