aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c101
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h87
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c16
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c91
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h3
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c8
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c1
8 files changed, 219 insertions, 94 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
new file mode 100644
index 000000000000..aebcb846de6a
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -0,0 +1,101 @@
+/*
+ *
+ * $Id$
+ *
+ * Copyright (C) 2007 Mike Isely <isely@pobox.com>
+ *
+ * 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; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/*
+
+This source file should encompass ALL per-device type information for the
+driver. To define a new device, add elements to the pvr2_device_table and
+pvr2_device_desc structures.
+
+*/
+
+#include "pvrusb2-devattr.h"
+#include <linux/usb.h>
+
+/* Known major hardware variants, keyed from device ID */
+#define PVR2_HDW_TYPE_29XXX 0
+#define PVR2_HDW_TYPE_24XXX 1
+
+struct usb_device_id pvr2_device_table[] = {
+ [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) },
+ [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) },
+ { }
+};
+
+/* Names of other client modules to request for 24xxx model hardware */
+static const char *pvr2_client_24xxx[] = {
+ "cx25840",
+ "tuner",
+ "wm8775",
+};
+
+/* Names of other client modules to request for 29xxx model hardware */
+static const char *pvr2_client_29xxx[] = {
+ "msp3400",
+ "saa7115",
+ "tuner",
+};
+
+/* Firmware file name(s) for 29xxx devices */
+static const char *pvr2_fw1_names_29xxx[] = {
+ "v4l-pvrusb2-29xxx-01.fw",
+};
+
+/* Firmware file name(s) for 29xxx devices */
+static const char *pvr2_fw1_names_24xxx[] = {
+ "v4l-pvrusb2-24xxx-01.fw",
+};
+
+const struct pvr2_device_desc pvr2_device_descriptions[] = {
+ [PVR2_HDW_TYPE_29XXX] = {
+ .description = "WinTV PVR USB2 Model Category 29xxxx",
+ .shortname = "29xxx",
+ .client_modules.lst = pvr2_client_29xxx,
+ .client_modules.cnt = ARRAY_SIZE(pvr2_client_29xxx),
+ .fx2_firmware.lst = pvr2_fw1_names_29xxx,
+ .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx),
+ },
+ [PVR2_HDW_TYPE_24XXX] = {
+ .description = "WinTV PVR USB2 Model Category 24xxxx",
+ .shortname = "24xxx",
+ .client_modules.lst = pvr2_client_24xxx,
+ .client_modules.cnt = ARRAY_SIZE(pvr2_client_24xxx),
+ .fx2_firmware.lst = pvr2_fw1_names_24xxx,
+ .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_24xxx),
+ .flag_has_cx25840 = !0,
+ .flag_has_wm8775 = !0,
+ },
+};
+
+const unsigned int pvr2_device_count = ARRAY_SIZE(pvr2_device_descriptions);
+
+MODULE_DEVICE_TABLE(usb, pvr2_device_table);
+
+
+/*
+ Stuff for Emacs to see, in order to encourage consistent editing style:
+ *** Local Variables: ***
+ *** mode: c ***
+ *** fill-column: 75 ***
+ *** tab-width: 8 ***
+ *** c-basic-offset: 8 ***
+ *** End: ***
+ */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
new file mode 100644
index 000000000000..6576aefd27c3
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -0,0 +1,87 @@
+/*
+ *
+ * $Id$
+ *
+ * Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *
+ * 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; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __PVRUSB2_DEVATTR_H
+#define __PVRUSB2_DEVATTR_H
+
+#include <linux/mod_devicetable.h>
+
+/*
+
+ This header defines structures used to describe attributes of a device.
+
+*/
+
+
+struct pvr2_string_table {
+ const char **lst;
+ unsigned int cnt;
+};
+
+
+/* This describes a particular hardware type (except for the USB device ID
+ which must live in a separate structure due to environmental
+ constraints). See the top of pvrusb2-hdw.c for where this is
+ instantiated. */
+struct pvr2_device_desc {
+ /* Single line text description of hardware */
+ const char *description;
+
+ /* Single token identifier for hardware */
+ const char *shortname;
+
+ /* List of additional client modules we need to load */
+ struct pvr2_string_table client_modules;
+
+ /* List of FX2 firmware file names we should search; if empty then
+ FX2 firmware check / load is skipped and we assume the device
+ was initialized from internal ROM. */
+ struct pvr2_string_table fx2_firmware;
+
+ /* If set, we don't bother trying to load cx23416 firmware. */
+ char flag_skip_cx23416_firmware;
+
+ /* Device does not require a powerup command to be issued. */
+ char flag_no_powerup;
+
+ /* Device has a cx25840 - this enables special additional logic to
+ handle it. */
+ char flag_has_cx25840;
+
+ /* Device has a wm8775 - this enables special additional logic to
+ ensure that it is found. */
+ char flag_has_wm8775;
+};
+
+extern const struct pvr2_device_desc pvr2_device_descriptions[];
+extern struct usb_device_id pvr2_device_table[];
+extern const unsigned int pvr2_device_count;
+
+#endif /* __PVRUSB2_HDW_INTERNAL_H */
+
+/*
+ Stuff for Emacs to see, in order to encourage consistent editing style:
+ *** Local Variables: ***
+ *** mode: c ***
+ *** fill-column: 75 ***
+ *** tab-width: 8 ***
+ *** c-basic-offset: 8 ***
+ *** End: ***
+ */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 5ca548cc7e7f..4271b4132664 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -370,13 +370,13 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
/* This ENC_MISC(3,encMisc3Arg) command is critical - without
it there will eventually be video corruption. Also, the
- 29xxx case is strange - the Windows driver is passing 1
- regardless of device type but if we have 1 for 29xxx device
- the video turns sluggish. */
- switch (hdw->hdw_type) {
- case PVR2_HDW_TYPE_24XXX: encMisc3Arg = 1; break;
- case PVR2_HDW_TYPE_29XXX: encMisc3Arg = 0; break;
- default: break;
+ saa7115 case is strange - the Windows driver is passing 1
+ regardless of device type but if we have 1 for saa7115
+ devices the video turns sluggish. */
+ if (hdw->hdw_desc->flag_has_cx25840) {
+ encMisc3Arg = 1;
+ } else {
+ encMisc3Arg = 0;
}
ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3,
encMisc3Arg,0,0);
@@ -434,7 +434,7 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw)
/* saa7115: 0xf0 */
val = 0xf0;
- if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+ if (hdw->hdw_desc->flag_has_cx25840) {
/* ivtv cx25840: 0x140 */
val = 0x140;
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 8ee4549b7a9f..8c2d222960f1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -40,6 +40,7 @@
#include "pvrusb2-hdw.h"
#include "pvrusb2-io.h"
#include <media/cx2341x.h>
+#include "pvrusb2-devattr.h"
/* Legal values for PVR2_CID_HSM */
#define PVR2_CVAL_HSM_FAIL 0
@@ -162,10 +163,6 @@ struct pvr2_decoder_ctrl {
#define FW1_STATE_RELOAD 3
#define FW1_STATE_OK 4
-/* Known major hardware variants, keyed from device ID */
-#define PVR2_HDW_TYPE_29XXX 0
-#define PVR2_HDW_TYPE_24XXX 1
-
typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16);
#define PVR2_I2C_FUNC_CNT 128
@@ -179,6 +176,7 @@ struct pvr2_hdw {
/* Device type, one of PVR2_HDW_TYPE_xxxxx */
unsigned int hdw_type;
+ const struct pvr2_device_desc *hdw_desc;
/* Kernel worker thread handling */
struct workqueue_struct *workqueue;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 4e55a2a84073..c56208456bc0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -41,47 +41,6 @@
#define TV_MIN_FREQ 55250000L
#define TV_MAX_FREQ 850000000L
-struct usb_device_id pvr2_device_table[] = {
- [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) },
- [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) },
- { }
-};
-
-MODULE_DEVICE_TABLE(usb, pvr2_device_table);
-
-static const char *pvr2_device_names[] = {
- [PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx",
- [PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx",
-};
-
-struct pvr2_string_table {
- const char **lst;
- unsigned int cnt;
-};
-
-// Names of other client modules to request for 24xxx model hardware
-static const char *pvr2_client_24xxx[] = {
- "cx25840",
- "tuner",
- "wm8775",
-};
-
-// Names of other client modules to request for 29xxx model hardware
-static const char *pvr2_client_29xxx[] = {
- "msp3400",
- "saa7115",
- "tuner",
-};
-
-static struct pvr2_string_table pvr2_client_lists[] = {
- [PVR2_HDW_TYPE_29XXX] = {
- pvr2_client_29xxx, ARRAY_SIZE(pvr2_client_29xxx)
- },
- [PVR2_HDW_TYPE_24XXX] = {
- pvr2_client_24xxx, ARRAY_SIZE(pvr2_client_24xxx)
- },
-};
-
static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
static DEFINE_MUTEX(pvr2_unit_mtx);
@@ -394,8 +353,8 @@ static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp)
{
- /* Actual minimum depends on device type. */
- if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+ /* Actual minimum depends on device digitizer type. */
+ if (cptr->hdw->hdw_desc->flag_has_cx25840) {
*vp = 75;
} else {
*vp = 17;
@@ -1131,23 +1090,8 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
unsigned int pipe;
int ret;
u16 address;
- static const char *fw_files_29xxx[] = {
- "v4l-pvrusb2-29xxx-01.fw",
- };
- static const char *fw_files_24xxx[] = {
- "v4l-pvrusb2-24xxx-01.fw",
- };
- static const struct pvr2_string_table fw_file_defs[] = {
- [PVR2_HDW_TYPE_29XXX] = {
- fw_files_29xxx, ARRAY_SIZE(fw_files_29xxx)
- },
- [PVR2_HDW_TYPE_24XXX] = {
- fw_files_24xxx, ARRAY_SIZE(fw_files_24xxx)
- },
- };
- if ((hdw->hdw_type >= ARRAY_SIZE(fw_file_defs)) ||
- (!fw_file_defs[hdw->hdw_type].lst)) {
+ if (!hdw->hdw_desc->fx2_firmware.cnt) {
hdw->fw1_state = FW1_STATE_OK;
return 0;
}
@@ -1157,8 +1101,8 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
trace_firmware("pvr2_upload_firmware1");
ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
- fw_file_defs[hdw->hdw_type].cnt,
- fw_file_defs[hdw->hdw_type].lst);
+ hdw->hdw_desc->fx2_firmware.cnt,
+ hdw->hdw_desc->fx2_firmware.lst);
if (ret < 0) {
if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
return ret;
@@ -1233,8 +1177,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
CX2341X_FIRM_ENC_FILENAME,
};
- if ((hdw->hdw_type != PVR2_HDW_TYPE_29XXX) &&
- (hdw->hdw_type != PVR2_HDW_TYPE_24XXX)) {
+ if (hdw->hdw_desc->flag_skip_cx23416_firmware) {
return 0;
}
@@ -1652,8 +1595,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
unsigned int idx;
struct pvr2_ctrl *cptr;
int reloadFl = 0;
- if ((hdw->hdw_type == PVR2_HDW_TYPE_29XXX) ||
- (hdw->hdw_type == PVR2_HDW_TYPE_24XXX)) {
+ if (hdw->hdw_desc->fx2_firmware.cnt) {
if (!reloadFl) {
reloadFl =
(hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
@@ -1689,17 +1631,11 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
}
if (!pvr2_hdw_dev_ok(hdw)) return;
- if (hdw->hdw_type < ARRAY_SIZE(pvr2_client_lists)) {
- for (idx = 0;
- idx < pvr2_client_lists[hdw->hdw_type].cnt;
- idx++) {
- request_module(
- pvr2_client_lists[hdw->hdw_type].lst[idx]);
- }
+ for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {
+ request_module(hdw->hdw_desc->client_modules.lst[idx]);
}
- if ((hdw->hdw_type == PVR2_HDW_TYPE_29XXX) ||
- (hdw->hdw_type == PVR2_HDW_TYPE_24XXX)) {
+ if (!hdw->hdw_desc->flag_no_powerup) {
pvr2_hdw_cmd_powerup(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
}
@@ -1857,20 +1793,22 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
unsigned int hdw_type;
int valid_std_mask;
struct pvr2_ctrl *cptr;
+ const struct pvr2_device_desc *hdw_desc;
__u8 ifnum;
struct v4l2_queryctrl qctrl;
struct pvr2_ctl_info *ciptr;
hdw_type = devid - pvr2_device_table;
- if (hdw_type >= ARRAY_SIZE(pvr2_device_names)) {
+ if (hdw_type >= pvr2_device_count) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"Bogus device type of %u reported",hdw_type);
return NULL;
}
+ hdw_desc = pvr2_device_descriptions + hdw_type;
hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
- hdw,pvr2_device_names[hdw_type]);
+ hdw,hdw_desc->description);
if (!hdw) goto fail;
init_timer(&hdw->quiescent_timer);
@@ -1894,6 +1832,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
GFP_KERNEL);
if (!hdw->controls) goto fail;
hdw->hdw_type = hdw_type;
+ hdw->hdw_desc = hdw_desc;
for (idx = 0; idx < hdw->control_cnt; idx++) {
cptr = hdw->controls + idx;
cptr->hdw = hdw;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 383685f7c81f..205fa03057e6 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -311,9 +311,6 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw);
a debugging aid. */
int pvr2_upload_firmware2(struct pvr2_hdw *hdw);
-/* List of device types that we can match */
-extern struct usb_device_id pvr2_device_table[];
-
#endif /* __PVRUSB2_HDW_H */
/*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index f8b7bd1e0d89..7721ec85d572 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -980,14 +980,16 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
printk(KERN_INFO "%s: IR disabled\n",hdw->name);
hdw->i2c_func[0x18] = i2c_black_hole;
} else if (ir_mode[hdw->unit_number] == 1) {
- if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+ if (hdw->hdw_desc->flag_has_cx25840) {
hdw->i2c_func[0x18] = i2c_24xxx_ir;
}
}
- if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
- hdw->i2c_func[0x1b] = i2c_hack_wm8775;
+ if (hdw->hdw_desc->flag_has_cx25840) {
hdw->i2c_func[0x44] = i2c_hack_cx25840;
}
+ if (hdw->hdw_desc->flag_has_wm8775) {
+ hdw->i2c_func[0x1b] = i2c_hack_wm8775;
+ }
// Configure the adapter and set up everything else related to it.
memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap));
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index 11b3b2e84b90..a8370737b503 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -28,6 +28,7 @@
#include <linux/videodev2.h>
#include "pvrusb2-hdw.h"
+#include "pvrusb2-devattr.h"
#include "pvrusb2-context.h"
#include "pvrusb2-debug.h"
#include "pvrusb2-v4l2.h"