@@ -256,8 +256,9 @@
};
static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
static int xc4000_TunerReset(struct dvb_frontend *fe);
+static void xc_debug_dump(struct xc4000_priv *priv);
static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
{
struct i2c_msg msg = { .addr = priv->i2c_props.addr,
@@ -332,12 +333,14 @@
(i2c_sequence[index + 1] != 0xFF)) {
len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
if (len == 0x0000) {
/* RESET command */
- result = xc4000_TunerReset(fe);
index += 2;
+#if 0 /* not needed, as already called by check_firmware() */
+ result = xc4000_TunerReset(fe);
if (result != XC_RESULT_SUCCESS)
return result;
+#endif
} else if (len & 0x8000) {
/* WAIT command */
xc_wait(len & 0x7FFF);
index += 2;
@@ -472,14 +475,8 @@
return 0;
}
-/* WAS THERE
-static int xc_get_buildversion(struct xc4000_priv *priv, u16 *buildrev)
-{
- return xc4000_readreg(priv, XREG_BUILD, buildrev);
-}*/
-
static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
{
u16 regData;
int result;
@@ -516,14 +513,12 @@
}
return lockState;
}
-#define XC_TUNE_ANALOG 0
-#define XC_TUNE_DIGITAL 1
-static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz, int mode)
+static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz)
{
- int found = 0;
- int result = 0;
+ int found = 1;
+ int result;
dprintk(1, "%s(%u)\n", __func__, freq_hz);
/* Don't complain when the request fails because of i2c stretching */
@@ -533,13 +528,23 @@
if (result != XC_RESULT_SUCCESS)
return 0;
- if (mode == XC_TUNE_ANALOG) {
- if (WaitForLock(priv) == 1)
- found = 1;
+ /* wait for lock only in analog TV mode */
+ if ((priv->cur_fw.type & (FM | DTV6 | DTV7 | DTV78 | DTV8)) == 0) {
+ if (WaitForLock(priv) == 0)
+ found = 0;
}
+ /* Wait for stats to stabilize.
+ * Frame Lines needs two frame times after initial lock
+ * before it is valid.
+ */
+ xc_wait(debug ? 100 : 10);
+
+ if (debug)
+ xc_debug_dump(priv);
+
return found;
}
static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
@@ -1108,17 +1113,8 @@
u16 quality;
u8 hw_majorversion = 0, hw_minorversion = 0;
u8 fw_majorversion = 0, fw_minorversion = 0;
- if (!(priv->cur_fw.type & BASE))
- return;
-
- /* Wait for stats to stabilize.
- * Frame Lines needs two frame times after initial lock
- * before it is valid.
- */
- xc_wait(100);
-
xc_get_ADC_Envelope(priv, &adc_envelope);
dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
xc_get_frequency_error(priv, &freq_error_hz);
@@ -1269,12 +1265,10 @@
/* goto fail; */
}
}
- xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
+ xc_tune_channel(priv, priv->freq_hz);
- if (debug)
- xc_debug_dump(priv);
ret = 0;
fail:
mutex_unlock(&priv->lock);
@@ -1470,12 +1464,10 @@
goto fail;
}
}
- xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
+ xc_tune_channel(priv, priv->freq_hz);
- if (debug)
- xc_debug_dump(priv);
ret = 0;
fail:
mutex_unlock(&priv->lock);
@@ -1549,9 +1541,9 @@
mutex_lock(&priv->lock);
/* Avoid firmware reload on slow devices */
- if (!no_poweroff && priv->cur_fw.type != XC_POWERED_DOWN) {
+ if (!no_poweroff && (priv->cur_fw.type & BASE) != 0) {
/* force reset and firmware reload */
priv->cur_fw.type = XC_POWERED_DOWN;
if (xc_write_reg(priv, XREG_POWER_DOWN, 0)
@@ -1560,8 +1552,9 @@
"xc4000: %s() unable to shutdown tuner\n",
__func__);
ret = -EREMOTEIO;
}
+ xc_wait(20);
}
mutex_unlock(&priv->lock);
@@ -1638,9 +1631,10 @@
instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
hybrid_tuner_instance_list,
i2c, cfg->i2c_address, "xc4000");
- priv->card_type = cfg->card_type;
+ if (cfg->card_type != XC4000_CARD_GENERIC)
+ priv->card_type = cfg->card_type;
switch (instance) {
case 0:
goto fail;
break;
@@ -1703,12 +1697,21 @@
memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
sizeof(struct dvb_tuner_ops));
+ if (instance == 1) {
+ int ret;
+ mutex_lock(&priv->lock);
+ ret = xc4000_fwupload(fe);
+ mutex_unlock(&priv->lock);
+ if (ret != XC_RESULT_SUCCESS)
+ goto fail2;
+ }
+
return fe;
fail:
mutex_unlock(&xc4000_list_mutex);
-
+fail2:
xc4000_release(fe);
return NULL;
}
EXPORT_SYMBOL(xc4000_attach);
@@ -441,8 +441,9 @@
break;
}
case TUNER_XC4000:
{
+ xc4000_cfg.card_type = XC4000_CARD_GENERIC;
xc4000_cfg.i2c_address = t->i2c->addr;
/* if_khz will be set when the digital dvb_attach() occurs */
xc4000_cfg.if_khz = 0;
if (!dvb_attach(xc4000_attach,