Commit 779e52df authored by Michael Hunold's avatar Michael Hunold Committed by Linus Torvalds

[PATCH] DVB: frontend updates

- [DVB] all: replace dvb_unregister_frontend_new() with
  dvb_unregister_frontend()

- [DVB] sp887x: fix firmware download, patch by Jose Alberto Reguero

- [DVB] tda1004x: add firmware loading via firmware_class()

- [DVB] dvb_frontend: without hierachical coding, code_rate_LP is
  irrelevant, so we tolerate the otherwise invalid FEC_NONE setting

- [DVB] ves1x93: fixed dropouts on older DVB cards, fix tuning issues
  (Andreas Share / Gregoire Favre), 
Signed-off-by: default avatarMichael Hunold <hunold@linuxtv.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 29ad5b6c
......@@ -762,6 +762,13 @@ static int dvb_frontend_ioctl (struct inode *inode, struct file *file,
fe->parameters.inversion = INVERSION_AUTO;
fetunesettings.parameters.inversion = INVERSION_AUTO;
}
if (fe->info->type == FE_OFDM) {
/* without hierachical coding code_rate_LP is irrelevant,
* so we tolerate the otherwise invalid FEC_NONE setting */
if (fe->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
fe->parameters.u.ofdm.code_rate_LP == FEC_NONE)
fe->parameters.u.ofdm.code_rate_LP = FEC_AUTO;
}
/* get frontend-specific tuning settings */
if (dvb_frontend_internal_ioctl(&fe->frontend, FE_GET_TUNE_SETTINGS,
......@@ -1180,7 +1187,7 @@ dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend,
return 0;
}
int dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
int dvb_unregister_frontend (int (*ioctl) (struct dvb_frontend *frontend,
unsigned int cmd, void *arg),
struct dvb_adapter *dvb_adapter)
{
......
......@@ -42,6 +42,8 @@
#define I2C_DRIVERID_DVBFE_ALPS_TDMB7 I2C_DRIVERID_EXP2
#define I2C_DRIVERID_DVBFE_AT76C651 I2C_DRIVERID_EXP2
#define I2C_DRIVERID_DVBFE_CX24110 I2C_DRIVERID_EXP2
#define I2C_DRIVERID_DVBFE_CX22702 I2C_DRIVERID_EXP2
#define I2C_DRIVERID_DVBFE_DIB3000MB I2C_DRIVERID_EXP2
#define I2C_DRIVERID_DVBFE_DST I2C_DRIVERID_EXP2
#define I2C_DRIVERID_DVBFE_DUMMY I2C_DRIVERID_EXP2
#define I2C_DRIVERID_DVBFE_L64781 I2C_DRIVERID_EXP2
......@@ -102,7 +104,7 @@ dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend,
struct module *module);
extern int
dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
dvb_unregister_frontend (int (*ioctl) (struct dvb_frontend *frontend,
unsigned int cmd, void *arg),
struct dvb_adapter *dvb_adapter);
......
......@@ -24,7 +24,7 @@ EXPORT_SYMBOL(dvbdmx_connect_frontend);
EXPORT_SYMBOL(dvbdmx_disconnect_frontend);
EXPORT_SYMBOL(dvb_register_frontend);
EXPORT_SYMBOL(dvb_unregister_frontend_new);
EXPORT_SYMBOL(dvb_unregister_frontend);
EXPORT_SYMBOL(dvb_add_frontend_ioctls);
EXPORT_SYMBOL(dvb_remove_frontend_ioctls);
EXPORT_SYMBOL(dvb_add_frontend_notifier);
......
......@@ -470,7 +470,7 @@ static int detach_client (struct i2c_client *client)
dprintk ("%s\n", __FUNCTION__);
dvb_unregister_frontend_new (tdmb7_ioctl, state->dvb);
dvb_unregister_frontend (tdmb7_ioctl, state->dvb);
i2c_detach_client(client);
BUG_ON(state->dvb);
kfree(client);
......
......@@ -514,7 +514,7 @@ static int detach_client(struct i2c_client *client)
{
struct at76c651_state *state = i2c_get_clientdata(client);
dvb_unregister_frontend_new(at76c651_ioctl, state->dvb);
dvb_unregister_frontend(at76c651_ioctl, state->dvb);
i2c_detach_client(client);
BUG_ON(state->dvb);
kfree(client);
......
......@@ -708,7 +708,7 @@ static int detach_client (struct i2c_client *client)
{
struct cx24110_state *state = i2c_get_clientdata(client);
dvb_unregister_frontend_new(cx24110_ioctl, state->dvb);
dvb_unregister_frontend(cx24110_ioctl, state->dvb);
i2c_detach_client(client);
BUG_ON(state->dvb);
kfree(client);
......
......@@ -207,7 +207,7 @@ static int dvbdummyfe_detach_client(struct i2c_client *client)
{
struct dvb_adapter *dvb = i2c_get_clientdata(client);
dvb_unregister_frontend_new(dvbdummyfe_ioctl, dvb);
dvb_unregister_frontend(dvbdummyfe_ioctl, dvb);
i2c_detach_client(client);
kfree(client);
return 0;
......
......@@ -684,7 +684,7 @@ static int l64781_detach_client(struct i2c_client *client)
{
struct l64781_state *state = i2c_get_clientdata(client);
dvb_unregister_frontend_new(l64781_ioctl, state->dvb);
dvb_unregister_frontend(l64781_ioctl, state->dvb);
i2c_detach_client(client);
BUG_ON(state->dvb);
kfree(client);
......
......@@ -492,7 +492,7 @@ static int tda8083_detach_client(struct i2c_client *client)
{
struct tda8083_state *state = i2c_get_clientdata(client);
dvb_unregister_frontend_new (tda8083_ioctl, state->dvb);
dvb_unregister_frontend (tda8083_ioctl, state->dvb);
i2c_detach_client(client);
BUG_ON(state->dvb);
kfree(client);
......
......@@ -845,7 +845,7 @@ static int mt312_detach_client(struct i2c_client *client)
dprintk ("%s\n", __FUNCTION__);
dvb_unregister_frontend_new (mt312_ioctl, state->dvb);
dvb_unregister_frontend (mt312_ioctl, state->dvb);
i2c_detach_client(client);
BUG_ON(state->dvb);
kfree(client);
......
......@@ -840,7 +840,7 @@ static int mt352_detach_client(struct i2c_client *client)
{
struct mt352_state *state = i2c_get_clientdata(client);
dvb_unregister_frontend_new (mt352_ioctl, state->dvb);
dvb_unregister_frontend (mt352_ioctl, state->dvb);
i2c_detach_client(client);
BUG_ON(state->dvb);
kfree(client);
......
......@@ -872,7 +872,7 @@ static int attach_adapter(struct i2c_adapter *adapter)
static int detach_client(struct i2c_client *client)
{
struct nxt6000_config *state = (struct nxt6000_config *) i2c_get_clientdata(client);
dvb_unregister_frontend_new(nxt6000_ioctl, state->dvb);
dvb_unregister_frontend(nxt6000_ioctl, state->dvb);
i2c_detach_client(client);
BUG_ON(state->dvb);
kfree(client);
......
......@@ -1414,7 +1414,7 @@ static int detach_client(struct i2c_client *client)
{
struct stv0299_state *state = (struct stv0299_state*)i2c_get_clientdata(client);
dvb_unregister_frontend_new (uni0299_ioctl, state->dvb);
dvb_unregister_frontend (uni0299_ioctl, state->dvb);
i2c_detach_client(client);
kfree(client);
kfree(state);
......
......@@ -578,7 +578,7 @@ static int attach_adapter(struct i2c_adapter *adapter)
static int detach_client(struct i2c_client *client)
{
struct ves1820_state *state = (struct ves1820_state *) i2c_get_clientdata(client);
dvb_unregister_frontend_new(ves1820_ioctl, state->dvb);
dvb_unregister_frontend(ves1820_ioctl, state->dvb);
device_remove_file(&client->dev, &dev_attr_client_name);
i2c_detach_client(client);
BUG_ON(state->dvb);
......
......@@ -28,6 +28,7 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include "dvb_frontend.h"
......@@ -48,7 +49,7 @@ static struct dvb_frontend_info ves1x93_info = {
.type = FE_QPSK,
.frequency_min = 950000,
.frequency_max = 2150000,
.frequency_stepsize = 250, /* kHz for QPSK frontends */
.frequency_stepsize = 125, /* kHz for QPSK frontends */
.frequency_tolerance = 29500,
.symbol_rate_min = 1000000,
.symbol_rate_max = 45000000,
......@@ -170,10 +171,26 @@ static int tuner_write (struct i2c_adapter *i2c, u8 *data, u8 len)
* set up the downconverter frequency divisor for a
* reference clock comparision frequency of 125 kHz.
*/
static int sp5659_set_tv_freq (struct i2c_adapter *i2c, u32 freq, u8 pwr)
static int sp5659_set_tv_freq (struct i2c_adapter *i2c, u32 freq)
{
u8 pwr = 0;
u8 buf[4];
u32 div = (freq + 479500) / 125;
u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, 0x95, (pwr << 5) | 0x30 };
if (freq > 2000000) pwr = 3;
else if (freq > 1800000) pwr = 2;
else if (freq > 1600000) pwr = 1;
else if (freq > 1200000) pwr = 0;
else if (freq >= 1100000) pwr = 1;
else pwr = 2;
buf[0] = (div >> 8) & 0x7f;
buf[1] = div & 0xff;
buf[2] = ((div & 0x18000) >> 10) | 0x95;
buf[3] = (pwr << 6) | 0x30;
// NOTE: since we're using a prescaler of 2, we set the
// divisor frequency to 62.5kHz and divide by 125 above
return tuner_write (i2c, buf, sizeof(buf));
}
......@@ -195,10 +212,10 @@ static int tsa5059_set_tv_freq (struct i2c_adapter *i2c, u32 freq)
}
static int tuner_set_tv_freq (struct i2c_adapter *i2c, u32 freq, u8 pwr)
static int tuner_set_tv_freq (struct i2c_adapter *i2c, u32 freq)
{
if ((demod_type == DEMOD_VES1893) && (board_type == BOARD_SIEMENS_PCI))
return sp5659_set_tv_freq (i2c, freq, pwr);
return sp5659_set_tv_freq (i2c, freq);
else if (demod_type == DEMOD_VES1993)
return tsa5059_set_tv_freq (i2c, freq);
......@@ -252,17 +269,10 @@ static int ves1x93_init (struct i2c_adapter *i2c)
static int ves1x93_clr_bit (struct i2c_adapter *i2c)
{
msleep(10);
ves1x93_writereg (i2c, 0, init_1x93_tab[0] & 0xfe);
ves1x93_writereg (i2c, 0, init_1x93_tab[0]);
msleep(5);
return 0;
}
static int ves1x93_init_aquire (struct i2c_adapter *i2c)
{
ves1x93_writereg (i2c, 3, 0x00);
ves1x93_writereg (i2c, 3, init_1x93_tab[3]);
msleep(5);
msleep(50);
return 0;
}
......@@ -414,26 +424,6 @@ static int ves1x93_set_symbolrate (struct i2c_adapter *i2c, u32 srate)
return 0;
}
static int ves1x93_afc (struct i2c_adapter *i2c, u32 freq, u32 srate)
{
int afc;
afc = ((int)((ves1x93_readreg (i2c, 0x0a) << 1) & 0xff))/2;
afc = (afc * (int)(srate/1000/8))/16;
if (afc) {
freq -= afc;
tuner_set_tv_freq (i2c, freq, 0);
ves1x93_init_aquire (i2c);
}
return 0;
}
static int ves1x93_set_voltage (struct i2c_adapter *i2c, fe_sec_voltage_t voltage)
{
switch (voltage) {
......@@ -464,6 +454,21 @@ static int ves1x93_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
fe_status_t *status = arg;
u8 sync = ves1x93_readreg (i2c, 0x0e);
/*
* The ves1893 sometimes returns sync values that make no sense,
* because, e.g., the SIGNAL bit is 0, while some of the higher
* bits are 1 (and how can there be a CARRIER w/o a SIGNAL?).
* Tests showed that the the VITERBI and SYNC bits are returned
* reliably, while the SIGNAL and CARRIER bits ar sometimes wrong.
* If such a case occurs, we read the value again, until we get a
* valid value.
*/
int maxtry = 10; /* just for safety - let's not get stuck here */
while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) {
msleep(10);
sync = ves1x93_readreg (i2c, 0x0e);
}
*status = 0;
if (sync & 1)
......@@ -525,11 +530,10 @@ static int ves1x93_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
struct dvb_frontend_parameters *p = arg;
tuner_set_tv_freq (i2c, p->frequency, 0);
tuner_set_tv_freq (i2c, p->frequency);
ves1x93_set_inversion (i2c, p->inversion);
ves1x93_set_fec (i2c, p->u.qpsk.fec_inner);
ves1x93_set_symbolrate (i2c, p->u.qpsk.symbol_rate);
ves1x93_afc (i2c, p->frequency, p->u.qpsk.symbol_rate);
state->inversion = p->inversion;
break;
}
......@@ -650,7 +654,7 @@ static int attach_adapter(struct i2c_adapter *adapter)
static int detach_client(struct i2c_client *client)
{
struct ves1x93_state *state = (struct ves1x93_state*)i2c_get_clientdata(client);
dvb_unregister_frontend_new(ves1x93_ioctl, state->dvb);
dvb_unregister_frontend(ves1x93_ioctl, state->dvb);
i2c_detach_client(client);
BUG_ON(state->dvb);
kfree(client);
......
......@@ -1689,7 +1689,7 @@ static void ttusb_dec_init_frontend(struct ttusb_dec *dec)
static void ttusb_dec_exit_frontend(struct ttusb_dec *dec)
{
dvb_unregister_frontend_new(dec->frontend_ioctl, dec->adapter);
dvb_unregister_frontend(dec->frontend_ioctl, dec->adapter);
}
static void ttusb_dec_init_filters(struct ttusb_dec *dec)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment