summaryrefslogtreecommitdiff
path: root/drivers/media/video/tuner-xc2028.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/tuner-xc2028.c')
-rw-r--r--drivers/media/video/tuner-xc2028.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c
index 50cf876f020f..098a9956a2bc 100644
--- a/drivers/media/video/tuner-xc2028.c
+++ b/drivers/media/video/tuner-xc2028.c
@@ -23,8 +23,6 @@
#include "dvb_frontend.h"
-#define PREFIX "xc2028"
-
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "enable verbose debug messages");
@@ -43,6 +41,11 @@ MODULE_PARM_DESC(audio_std,
"NICAM/A\n"
"NICAM/B\n");
+static char firmware_name[FIRMWARE_NAME_MAX];
+module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
+MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the "
+ "default firmware name\n");
+
static LIST_HEAD(xc2028_list);
static DEFINE_MUTEX(xc2028_list_mutex);
@@ -145,7 +148,7 @@ static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val)
}
#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
-void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
+static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
{
if (type & BASE)
printk("BASE ");
@@ -255,19 +258,24 @@ static int load_all_firmwares(struct dvb_frontend *fe)
int rc = 0;
int n, n_array;
char name[33];
+ char *fname;
tuner_dbg("%s called\n", __FUNCTION__);
- tuner_dbg("Reading firmware %s\n", priv->ctrl.fname);
- rc = request_firmware(&fw, priv->ctrl.fname,
- &priv->i2c_props.adap->dev);
+ if (!firmware_name[0])
+ fname = priv->ctrl.fname;
+ else
+ fname = firmware_name;
+
+ tuner_dbg("Reading firmware %s\n", fname);
+ rc = request_firmware(&fw, fname, &priv->i2c_props.adap->dev);
if (rc < 0) {
if (rc == -ENOENT)
tuner_err("Error: firmware %s not found.\n",
- priv->ctrl.fname);
+ fname);
else
tuner_err("Error %d while requesting firmware %s \n",
- rc, priv->ctrl.fname);
+ rc, fname);
return rc;
}
@@ -276,7 +284,7 @@ static int load_all_firmwares(struct dvb_frontend *fe)
if (fw->size < sizeof(name) - 1 + 2 + 2) {
tuner_err("Error: firmware file %s has invalid size!\n",
- priv->ctrl.fname);
+ fname);
goto corrupt;
}
@@ -291,7 +299,7 @@ static int load_all_firmwares(struct dvb_frontend *fe)
p += 2;
tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n",
- n_array, priv->ctrl.fname, name,
+ n_array, fname, name,
priv->firm_version >> 8, priv->firm_version & 0xff);
priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
@@ -906,9 +914,11 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
if (rc < 0)
goto ret;
- rc = priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1);
- if (rc < 0)
- goto ret;
+ /* Return code shouldn't be checked.
+ The reset CLK is needed only with tm6000.
+ Driver should work fine even if this fails.
+ */
+ priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1);
msleep(10);
@@ -1153,23 +1163,29 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
void *video_dev;
if (debug)
- printk(KERN_DEBUG PREFIX ": Xcv2028/3028 init called!\n");
+ printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n");
- if (NULL == cfg || NULL == cfg->video_dev)
+ if (NULL == cfg)
return NULL;
if (!fe) {
- printk(KERN_ERR PREFIX ": No frontend!\n");
+ printk(KERN_ERR "xc2028: No frontend!\n");
return NULL;
}
- video_dev = cfg->video_dev;
+ video_dev = cfg->i2c_adap->algo_data;
+
+ if (debug)
+ printk(KERN_DEBUG "xc2028: video_dev =%p\n", video_dev);
mutex_lock(&xc2028_list_mutex);
list_for_each_entry(priv, &xc2028_list, xc2028_list) {
- if (priv->video_dev == cfg->video_dev) {
+ if (&priv->i2c_props.adap->dev == &cfg->i2c_adap->dev) {
video_dev = NULL;
+ if (debug)
+ printk(KERN_DEBUG "xc2028: reusing device\n");
+
break;
}
}
@@ -1183,6 +1199,8 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
priv->i2c_props.addr = cfg->i2c_addr;
priv->i2c_props.adap = cfg->i2c_adap;
+ priv->i2c_props.name = "xc2028";
+
priv->video_dev = video_dev;
priv->tuner_callback = cfg->callback;
priv->ctrl.max_len = 13;
@@ -1195,6 +1213,9 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
fe->tuner_priv = priv;
priv->count++;
+ if (debug)
+ printk(KERN_DEBUG "xc2028: usage count is %i\n", priv->count);
+
memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops,
sizeof(xc2028_dvb_tuner_ops));