diff options
Diffstat (limited to 'linux/drivers/media/video/tuner-xc2028.c')
-rw-r--r-- | linux/drivers/media/video/tuner-xc2028.c | 83 |
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); |