summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/tuner-xc2028.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/tuner-xc2028.c')
-rw-r--r--linux/drivers/media/video/tuner-xc2028.c83
1 files changed, 47 insertions, 36 deletions
diff --git a/linux/drivers/media/video/tuner-xc2028.c b/linux/drivers/media/video/tuner-xc2028.c
index 0ab0cbeca..ce066dc97 100644
--- a/linux/drivers/media/video/tuner-xc2028.c
+++ b/linux/drivers/media/video/tuner-xc2028.c
@@ -1,6 +1,6 @@
/* tuner-xc2028
*
- * Copyright (c) 2007 Mauro Carvalho Chehab (mchehab@infradead.org)
+ * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
*
* Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
* - frontend interface
@@ -145,12 +145,12 @@ struct xc2028_data {
_rc; \
})
-static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val)
+static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val)
{
unsigned char buf[2];
unsigned char ibuf[2];
- tuner_dbg("%s %04x called\n", __FUNCTION__, reg);
+ tuner_dbg("%s %04x called\n", __func__, reg);
buf[0] = reg >> 8;
buf[1] = (unsigned char) reg;
@@ -250,6 +250,7 @@ static v4l2_std_id parse_audio_std_option(void)
static void free_firmware(struct xc2028_data *priv)
{
int i;
+ tuner_dbg("%s called\n", __func__);
if (!priv->firm)
return;
@@ -275,7 +276,7 @@ static int load_all_firmwares(struct dvb_frontend *fe)
char name[33];
char *fname;
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
if (!firmware_name[0])
fname = priv->ctrl.fname;
@@ -418,9 +419,9 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
{
struct xc2028_data *priv = fe->tuner_priv;
int i, best_i = -1, best_nr_matches = 0;
- unsigned int ign_firm_type_mask = 0;
+ unsigned int type_mask = 0;
- tuner_dbg("%s called, want type=", __FUNCTION__);
+ tuner_dbg("%s called, want type=", __func__);
if (debug) {
dump_firm_type(type);
printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
@@ -435,18 +436,23 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
*id = V4L2_STD_PAL;
if (type & BASE)
- type &= BASE_TYPES;
+ type_mask = BASE_TYPES;
else if (type & SCODE) {
type &= SCODE_TYPES;
- ign_firm_type_mask = HAS_IF;
+ type_mask = SCODE_TYPES &~ HAS_IF;
} else if (type & DTV_TYPES)
- type &= DTV_TYPES;
+ type_mask = DTV_TYPES;
else if (type & STD_SPECIFIC_TYPES)
- type &= STD_SPECIFIC_TYPES;
+ type_mask = STD_SPECIFIC_TYPES;
+
+ type &= type_mask;
+
+ if (!type & SCODE)
+ type_mask = ~0;
/* Seek for exact match */
for (i = 0; i < priv->firm_size; i++) {
- if ((type == (priv->firm[i].type & ~ign_firm_type_mask)) &&
+ if ((type == (priv->firm[i].type & type_mask)) &&
(*id == priv->firm[i].id))
goto found;
}
@@ -456,7 +462,7 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
v4l2_std_id match_mask;
int nr_matches;
- if (type != (priv->firm[i].type & ~ign_firm_type_mask))
+ if (type != (priv->firm[i].type & type_mask))
continue;
match_mask = *id & priv->firm[i].id;
@@ -506,7 +512,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type,
int pos, rc;
unsigned char *p, *endp, buf[priv->ctrl.max_len];
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
pos = seek_firmware(fe, type, id);
if (pos < 0)
@@ -609,7 +615,7 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type,
int pos, rc;
unsigned char *p;
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
if (!int_freq) {
pos = seek_firmware(fe, type, id);
@@ -673,7 +679,7 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type,
u16 version, hwmodel;
v4l2_std_id std0;
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
if (!priv->firm) {
if (!priv->ctrl.fname) {
@@ -793,10 +799,10 @@ check_device:
goto fail;
}
- tuner_info("Device is Xceive %d version %d.%d, "
- "firmware version %d.%d\n",
- hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8,
- (version & 0xf0) >> 4, version & 0xf);
+ tuner_dbg("Device is Xceive %d version %d.%d, "
+ "firmware version %d.%d\n",
+ hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8,
+ (version & 0xf0) >> 4, version & 0xf);
/* Check firmware version against what we downloaded. */
if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
@@ -847,7 +853,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
u16 frq_lock, signal = 0;
int rc;
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
mutex_lock(&priv->lock);
@@ -884,7 +890,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
unsigned char buf[4];
u32 div, offset = 0;
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
mutex_lock(&priv->lock);
@@ -967,7 +973,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe,
struct xc2028_data *priv = fe->tuner_priv;
unsigned int type=0;
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
if (p->mode == V4L2_TUNER_RADIO) {
type |= FM;
@@ -1000,7 +1006,7 @@ static int xc2028_set_params(struct dvb_frontend *fe,
fe_bandwidth_t bw = BANDWIDTH_8_MHZ;
u16 demod = 0;
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
if (priv->ctrl.d2633)
type |= D2633;
@@ -1065,12 +1071,16 @@ static int xc2028_set_params(struct dvb_frontend *fe,
T_DIGITAL_TV, type, 0, demod);
}
+#if 0
+/* This is needed at sleep (S1/S3), but not at fe_standby. Otherwise,
+ firmware will be loaded on every open()
+ */
static int xc2028_sleep(struct dvb_frontend *fe)
{
struct xc2028_data *priv = fe->tuner_priv;
int rc = 0;
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
mutex_lock(&priv->lock);
@@ -1085,13 +1095,13 @@ static int xc2028_sleep(struct dvb_frontend *fe)
return rc;
}
-
+#endif
static int xc2028_dvb_release(struct dvb_frontend *fe)
{
struct xc2028_data *priv = fe->tuner_priv;
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
mutex_lock(&xc2028_list_mutex);
@@ -1116,7 +1126,7 @@ static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct xc2028_data *priv = fe->tuner_priv;
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
*frequency = priv->frequency;
@@ -1129,25 +1139,25 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
struct xc2028_ctrl *p = priv_cfg;
int rc = 0;
- tuner_dbg("%s called\n", __FUNCTION__);
+ tuner_dbg("%s called\n", __func__);
mutex_lock(&priv->lock);
- kfree(priv->ctrl.fname);
- free_firmware(priv);
-
memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
- priv->ctrl.fname = NULL;
+ if (priv->ctrl.max_len < 9)
+ priv->ctrl.max_len = 13;
if (p->fname) {
+ if (priv->ctrl.fname && strcmp(p->fname, priv->ctrl.fname)) {
+ kfree(priv->ctrl.fname);
+ free_firmware(priv);
+ }
+
priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
if (priv->ctrl.fname == NULL)
rc = -ENOMEM;
}
- if (priv->ctrl.max_len < 9)
- priv->ctrl.max_len = 13;
-
mutex_unlock(&priv->lock);
return rc;
@@ -1167,8 +1177,9 @@ static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
.get_frequency = xc2028_get_frequency,
.get_rf_strength = xc2028_signal,
.set_params = xc2028_set_params,
+#if 0
.sleep = xc2028_sleep,
-
+#endif
#if 0
int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
int (*get_status)(struct dvb_frontend *fe, u32 *status);