summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/frontends
diff options
context:
space:
mode:
authorMichael Hunold <devnull@localhost>2004-06-22 13:53:59 +0000
committerMichael Hunold <devnull@localhost>2004-06-22 13:53:59 +0000
commit2ab054a9059005e514cd10e7c546dda722191c05 (patch)
treeb872226485da1d207cf506f2d48d87f6dd6c80f1 /linux/drivers/media/dvb/frontends
parenta2203e12db48c483f6c71fb1cc6b66711854873e (diff)
downloadmediapointer-dvb-s2-2ab054a9059005e514cd10e7c546dda722191c05.tar.gz
mediapointer-dvb-s2-2ab054a9059005e514cd10e7c546dda722191c05.tar.bz2
- convert to kernel i2c, thanks to Kenneth Aafløy <lists@kenneth.aafloy.net>
Note: this will probably break some of the drivers out there, which don't register properly to the kernel i2c subsystem yet.
Diffstat (limited to 'linux/drivers/media/dvb/frontends')
-rw-r--r--linux/drivers/media/dvb/frontends/alps_tdmb7.c156
-rw-r--r--linux/drivers/media/dvb/frontends/at76c651.c254
2 files changed, 269 insertions, 141 deletions
diff --git a/linux/drivers/media/dvb/frontends/alps_tdmb7.c b/linux/drivers/media/dvb/frontends/alps_tdmb7.c
index fc1a4791c..a5976bd0f 100644
--- a/linux/drivers/media/dvb/frontends/alps_tdmb7.c
+++ b/linux/drivers/media/dvb/frontends/alps_tdmb7.c
@@ -29,10 +29,11 @@
#include "dvb_frontend.h"
#include "dvb_functions.h"
-
static int debug = 0;
#define dprintk if (debug) printk
+// FIXME: Move to i2c-id.h
+#define I2C_DRIVERID_DVBFE_TDMB7 I2C_DRIVERID_EXP0
static struct dvb_frontend_info tdmb7_info = {
.name = "Alps TDMB7",
@@ -53,6 +54,10 @@ static struct dvb_frontend_info tdmb7_info = {
FE_CAN_RECOVER
};
+struct tdmb7_state {
+ struct i2c_adapter *i2c;
+ struct dvb_adapter *dvb;
+};
static u8 init_tab [] = {
0x04, 0x10,
@@ -75,8 +80,7 @@ static u8 init_tab [] = {
0x47, 0x05,
};
-
-static int cx22700_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data)
+static int cx22700_writereg (struct i2c_adapter *i2c, u8 reg, u8 data)
{
int ret;
u8 buf [] = { reg, data };
@@ -84,7 +88,7 @@ static int cx22700_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data)
dprintk ("%s\n", __FUNCTION__);
- ret = i2c->xfer (i2c, &msg, 1);
+ ret = i2c_transfer (i2c, &msg, 1);
if (ret != 1)
printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
@@ -93,8 +97,7 @@ static int cx22700_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data)
return (ret != 1) ? -1 : 0;
}
-
-static u8 cx22700_readreg (struct dvb_i2c_bus *i2c, u8 reg)
+static u8 cx22700_readreg (struct i2c_adapter *i2c, u8 reg)
{
int ret;
u8 b0 [] = { reg };
@@ -104,7 +107,7 @@ static u8 cx22700_readreg (struct dvb_i2c_bus *i2c, u8 reg)
dprintk ("%s\n", __FUNCTION__);
- ret = i2c->xfer (i2c, msg, 2);
+ ret = i2c_transfer (i2c, msg, 2);
if (ret != 2)
printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
@@ -112,14 +115,13 @@ static u8 cx22700_readreg (struct dvb_i2c_bus *i2c, u8 reg)
return b1[0];
}
-
-static int pll_write (struct dvb_i2c_bus *i2c, u8 data [4])
+static int pll_write (struct i2c_adapter *i2c, u8 data [4])
{
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 };
int ret;
cx22700_writereg (i2c, 0x0a, 0x00); /* open i2c bus switch */
- ret = i2c->xfer (i2c, &msg, 1);
+ ret = i2c_transfer (i2c, &msg, 1);
cx22700_writereg (i2c, 0x0a, 0x01); /* close i2c bus switch */
if (ret != 1)
@@ -128,12 +130,11 @@ static int pll_write (struct dvb_i2c_bus *i2c, u8 data [4])
return (ret != 1) ? -1 : 0;
}
-
/**
* set up the downconverter frequency divisor for a
* reference clock comparision frequency of 125 kHz.
*/
-static int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq)
+static int pll_set_tv_freq (struct i2c_adapter *i2c, u32 freq)
{
u32 div = (freq + 36166667) / 166667;
#if 1 //ALPS_SETTINGS
@@ -149,8 +150,7 @@ static int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq)
return pll_write (i2c, buf);
}
-
-static int cx22700_init (struct dvb_i2c_bus *i2c)
+static int cx22700_init (struct i2c_adapter *i2c)
{
int i;
@@ -169,8 +169,7 @@ static int cx22700_init (struct dvb_i2c_bus *i2c)
return 0;
}
-
-static int cx22700_set_inversion (struct dvb_i2c_bus *i2c, int inversion)
+static int cx22700_set_inversion (struct i2c_adapter *i2c, int inversion)
{
u8 val;
@@ -190,8 +189,7 @@ static int cx22700_set_inversion (struct dvb_i2c_bus *i2c, int inversion)
}
}
-
-static int cx22700_set_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters *p)
+static int cx22700_set_tps (struct i2c_adapter *i2c, struct dvb_ofdm_parameters *p)
{
static const u8 qam_tab [4] = { 0, 1, 0, 2 };
static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 };
@@ -253,8 +251,7 @@ static int cx22700_set_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters
return 0;
}
-
-static int cx22700_get_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters *p)
+static int cx22700_get_tps (struct i2c_adapter *i2c, struct dvb_ofdm_parameters *p)
{
static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 };
static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4,
@@ -278,7 +275,6 @@ static int cx22700_get_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters
else
p->constellation = qam_tab[(val >> 3) & 0x3];
-
val = cx22700_readreg (i2c, 0x02);
if (((val >> 3) & 0x07) > 4)
@@ -291,7 +287,6 @@ static int cx22700_get_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters
else
p->code_rate_LP = fec_tab[val & 0x07];
-
val = cx22700_readreg (i2c, 0x03);
p->guard_interval = GUARD_INTERVAL_1_32 + ((val >> 6) & 0x3);
@@ -300,10 +295,10 @@ static int cx22700_get_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters
return 0;
}
-
static int tdmb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
- struct dvb_i2c_bus *i2c = fe->i2c;
+ struct tdmb7_state *state = fe->data;
+ struct i2c_adapter *i2c = state->i2c;
dprintk ("%s\n", __FUNCTION__);
@@ -406,45 +401,118 @@ static int tdmb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
return 0;
}
+static struct i2c_client client_template;
-
-static int tdmb7_attach (struct dvb_i2c_bus *i2c, void **data)
+static int attach_adapter (struct i2c_adapter *adapter)
{
- u8 b0 [] = { 0x7 };
- u8 b1 [] = { 0 };
- struct i2c_msg msg [] = { { .addr = 0x43, .flags = 0, .buf = b0, .len = 1 },
- { .addr = 0x43, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+ struct tdmb7_state *state;
+ struct i2c_client *client;
+ int ret;
- dprintk ("%s\n", __FUNCTION__);
+ u8 b0 [] = { 0x7 };
+ u8 b1 [] = { 0 };
+ struct i2c_msg msg [] = { { .addr = 0x43, .flags = 0, .buf = b0, .len = 1 },
+ { .addr = 0x43, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
- if (i2c->xfer (i2c, msg, 2) != 2)
- return -ENODEV;
+ dprintk ("%s\n", __FUNCTION__);
- return dvb_register_frontend (tdmb7_ioctl, i2c, NULL, &tdmb7_info);
-}
+ if (i2c_transfer(adapter, msg, 2) != 2)
+ return -ENODEV;
+
+ if (NULL == (state = kmalloc(sizeof(struct tdmb7_state), GFP_KERNEL)))
+ return -ENOMEM;
+
+ state->i2c = adapter;
+
+ if (NULL == (client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
+ kfree(state);
+ return -ENOMEM;
+ }
+
+ memcpy(client, &client_template, sizeof(struct i2c_client));
+ client->adapter = adapter;
+ i2c_set_clientdata(client, state);
+
+ ret = i2c_attach_client(client);
+ if (ret) {
+ kfree(state);
+ kfree(client);
+ return ret;
+ }
+
+ BUG_ON(!state->dvb);
+ ret = dvb_register_frontend_new (tdmb7_ioctl, state->dvb, state, &tdmb7_info);
+ if (ret) {
+ i2c_detach_client(client);
+ kfree(state);
+ kfree(client);
+ return ret;
+ }
+
+ return 0;
+}
-static void tdmb7_detach (struct dvb_i2c_bus *i2c, void *data)
+static int detach_client (struct i2c_client *client)
{
+ struct tdmb7_state *state = i2c_get_clientdata(client);
+
dprintk ("%s\n", __FUNCTION__);
- dvb_unregister_frontend (tdmb7_ioctl, i2c);
+ dvb_unregister_frontend_new (tdmb7_ioctl, state->dvb);
+ i2c_detach_client(client);
+ BUG_ON(state->dvb);
+ kfree(client);
+ kfree(state);
+ return 0;
}
-
-static int __init init_tdmb7 (void)
+static int command (struct i2c_client *client,
+ unsigned int cmd, void *arg)
{
- dprintk ("%s\n", __FUNCTION__);
+ struct tdmb7_state *state = i2c_get_clientdata(client);
- return dvb_register_i2c_device (THIS_MODULE, tdmb7_attach, tdmb7_detach);
+ dprintk("%s\n", __FUNCTION__);
+
+ switch (cmd) {
+ case FE_REGISTER:
+ state->dvb = arg;
+ break;
+ case FE_UNREGISTER:
+ state->dvb = NULL;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
}
+static struct i2c_driver driver = {
+ .owner = THIS_MODULE,
+ .name = "alps_tdmb7",
+ .id = I2C_DRIVERID_DVBFE_TDMB7,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = attach_adapter,
+ .detach_client = detach_client,
+ .command = command,
+};
-static void __exit exit_tdmb7 (void)
+static struct i2c_client client_template = {
+ I2C_DEVNAME("alps_tdmb7"),
+ .flags = I2C_CLIENT_ALLOW_USE,
+ .driver = &driver,
+};
+
+static int __init init_tdmb7 (void)
{
- dprintk ("%s\n", __FUNCTION__);
+ return i2c_add_driver(&driver);
+}
- dvb_unregister_i2c_device (tdmb7_attach);
+static void __exit exit_tdmb7 (void)
+{
+ if (i2c_del_driver(&driver))
+ printk(KERN_ERR "alps_tdmb7: driver deregistration failed.\n");
}
module_init (init_tdmb7);
diff --git a/linux/drivers/media/dvb/frontends/at76c651.c b/linux/drivers/media/dvb/frontends/at76c651.c
index dd4cd35a8..51c9654e9 100644
--- a/linux/drivers/media/dvb/frontends/at76c651.c
+++ b/linux/drivers/media/dvb/frontends/at76c651.c
@@ -38,11 +38,12 @@
#include "dvb_functions.h"
static int debug = 0;
-static u8 at76c651_qam;
-static u8 at76c651_revision;
#define dprintk if (debug) printk
+//FIXME: Move to i2c-id.h
+#define I2C_DRIVERID_DVBFE_AT76C651 I2C_DRIVERID_EXP0
+
/*
* DAT7021
* -------
@@ -74,6 +75,13 @@ static struct dvb_frontend_info at76c651_info = {
FE_CAN_MUTE_TS | FE_CAN_QAM_256 | FE_CAN_RECOVER
};
+struct at76c651_state {
+ u8 revision;
+ u8 qam;
+ struct i2c_adapter *i2c;
+ struct dvb_adapter *dvb;
+};
+
#if ! defined(__powerpc__)
static __inline__ int __ilog2(unsigned long x)
{
@@ -89,14 +97,13 @@ static __inline__ int __ilog2(unsigned long x)
}
#endif
-static int at76c651_writereg(struct dvb_i2c_bus *i2c, u8 reg, u8 data)
+static int at76c651_writereg(struct i2c_adapter *i2c, u8 reg, u8 data)
{
-
int ret;
u8 buf[] = { reg, data };
struct i2c_msg msg = { .addr = 0x1a >> 1, .flags = 0, .buf = buf, .len = 2 };
- ret = i2c->xfer(i2c, &msg, 1);
+ ret = i2c_transfer(i2c, &msg, 1);
if (ret != 1)
dprintk("%s: writereg error "
@@ -106,43 +113,37 @@ static int at76c651_writereg(struct dvb_i2c_bus *i2c, u8 reg, u8 data)
dvb_delay(10);
return (ret != 1) ? -EREMOTEIO : 0;
-
}
-static u8 at76c651_readreg(struct dvb_i2c_bus *i2c, u8 reg)
+static u8 at76c651_readreg(struct i2c_adapter *i2c, u8 reg)
{
-
int ret;
u8 b0[] = { reg };
u8 b1[] = { 0 };
struct i2c_msg msg[] = { {.addr = 0x1a >> 1, .flags = 0, .buf = b0, .len = 1},
{.addr = 0x1a >> 1, .flags = I2C_M_RD, .buf = b1, .len = 1} };
- ret = i2c->xfer(i2c, msg, 2);
+ ret = i2c_transfer(i2c, msg, 2);
if (ret != 2)
dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
return b1[0];
-
}
-static int at76c651_reset(struct dvb_i2c_bus *i2c)
+static int at76c651_reset(struct i2c_adapter *i2c)
{
-
return at76c651_writereg(i2c, 0x07, 0x01);
-
}
-static int at76c651_disable_interrupts(struct dvb_i2c_bus *i2c)
+static int at76c651_disable_interrupts(struct i2c_adapter *i2c)
{
-
return at76c651_writereg(i2c, 0x0b, 0x00);
-
}
-static int at76c651_set_auto_config(struct dvb_i2c_bus *i2c)
+static int at76c651_set_auto_config(struct at76c651_state *state)
{
+ struct i2c_adapter *i2c = state->i2c;
/*
* Autoconfig
@@ -155,19 +156,19 @@ static int at76c651_set_auto_config(struct dvb_i2c_bus *i2c)
*/
at76c651_writereg(i2c, 0x10, 0x06);
- at76c651_writereg(i2c, 0x11, ((at76c651_qam == 5) || (at76c651_qam == 7)) ? 0x12 : 0x10);
+ at76c651_writereg(i2c, 0x11, ((state->qam == 5) || (state->qam == 7)) ? 0x12 : 0x10);
at76c651_writereg(i2c, 0x15, 0x28);
at76c651_writereg(i2c, 0x20, 0x09);
- at76c651_writereg(i2c, 0x24, ((at76c651_qam == 5) || (at76c651_qam == 7)) ? 0xC0 : 0x90);
+ at76c651_writereg(i2c, 0x24, ((state->qam == 5) || (state->qam == 7)) ? 0xC0 : 0x90);
at76c651_writereg(i2c, 0x30, 0x90);
- if (at76c651_qam == 5)
+ if (state->qam == 5)
at76c651_writereg(i2c, 0x35, 0x2A);
/*
* Initialize A/D-converter
*/
- if (at76c651_revision == 0x11) {
+ if (state->revision == 0x11) {
at76c651_writereg(i2c, 0x2E, 0x38);
at76c651_writereg(i2c, 0x2F, 0x13);
}
@@ -181,32 +182,25 @@ static int at76c651_set_auto_config(struct dvb_i2c_bus *i2c)
at76c651_reset(i2c);
return 0;
-
}
-static int at76c651_set_bbfreq(struct dvb_i2c_bus *i2c)
+static int at76c651_set_bbfreq(struct i2c_adapter *i2c)
{
-
at76c651_writereg(i2c, 0x04, 0x3f);
at76c651_writereg(i2c, 0x05, 0xee);
-
return 0;
-
}
-static int at76c651_switch_tuner_i2c(struct dvb_i2c_bus *i2c, u8 enable)
+static int at76c651_switch_tuner_i2c(struct i2c_adapter *i2c, u8 enable)
{
-
if (enable)
return at76c651_writereg(i2c, 0x0c, 0xc2 | 0x01);
else
return at76c651_writereg(i2c, 0x0c, 0xc2);
-
}
-static int dat7021_write(struct dvb_i2c_bus *i2c, u32 tw)
+static int dat7021_write(struct i2c_adapter *i2c, u32 tw)
{
-
int ret;
struct i2c_msg msg =
{ .addr = 0xc2 >> 1, .flags = 0, .buf = (u8 *) & tw, .len = sizeof (tw) };
@@ -217,7 +211,7 @@ static int dat7021_write(struct dvb_i2c_bus *i2c, u32 tw)
at76c651_switch_tuner_i2c(i2c, 1);
- ret = i2c->xfer(i2c, &msg, 1);
+ ret = i2c_transfer(i2c, &msg, 1);
at76c651_switch_tuner_i2c(i2c, 0);
@@ -227,12 +221,10 @@ static int dat7021_write(struct dvb_i2c_bus *i2c, u32 tw)
at76c651_reset(i2c);
return 0;
-
}
-static int dat7021_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq)
+static int dat7021_set_tv_freq(struct i2c_adapter *i2c, u32 freq)
{
-
u32 dw;
freq /= 1000;
@@ -255,12 +247,10 @@ static int dat7021_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq)
dw += 0x4E28E06;
return dat7021_write(i2c, dw);
-
}
-static int at76c651_set_symbolrate(struct dvb_i2c_bus *i2c, u32 symbolrate)
+static int at76c651_set_symbolrate(struct i2c_adapter *i2c, u32 symbolrate)
{
-
u8 exponent;
u32 mantissa;
@@ -281,37 +271,35 @@ static int at76c651_set_symbolrate(struct dvb_i2c_bus *i2c, u32 symbolrate)
at76c651_writereg(i2c, 0x02, (mantissa << 3) | exponent);
return 0;
-
}
-static int at76c651_set_qam(struct dvb_i2c_bus *i2c, fe_modulation_t qam)
+static int at76c651_set_qam(struct at76c651_state *state, fe_modulation_t qam)
{
-
switch (qam) {
case QPSK:
- at76c651_qam = 0x02;
+ state->qam = 0x02;
break;
case QAM_16:
- at76c651_qam = 0x04;
+ state->qam = 0x04;
break;
case QAM_32:
- at76c651_qam = 0x05;
+ state->qam = 0x05;
break;
case QAM_64:
- at76c651_qam = 0x06;
+ state->qam = 0x06;
break;
case QAM_128:
- at76c651_qam = 0x07;
+ state->qam = 0x07;
break;
case QAM_256:
- at76c651_qam = 0x08;
+ state->qam = 0x08;
break;
#if 0
case QAM_512:
- at76c651_qam = 0x09;
+ state->qam = 0x09;
break;
case QAM_1024:
- at76c651_qam = 0x0A;
+ state->qam = 0x0A;
break;
#endif
default:
@@ -319,14 +307,12 @@ static int at76c651_set_qam(struct dvb_i2c_bus *i2c, fe_modulation_t qam)
}
- return at76c651_writereg(i2c, 0x03, at76c651_qam);
-
+ return at76c651_writereg(state->i2c, 0x03, state->qam);
}
-static int at76c651_set_inversion(struct dvb_i2c_bus *i2c,
- fe_spectral_inversion_t inversion)
+static int at76c651_set_inversion(struct i2c_adapter *i2c,
+ fe_spectral_inversion_t inversion)
{
-
u8 feciqinv = at76c651_readreg(i2c, 0x60);
switch (inversion) {
@@ -348,36 +334,38 @@ static int at76c651_set_inversion(struct dvb_i2c_bus *i2c,
}
return at76c651_writereg(i2c, 0x60, feciqinv);
-
}
-static int at76c651_set_parameters(struct dvb_i2c_bus *i2c,
- struct dvb_frontend_parameters *p)
+static int at76c651_set_parameters(struct at76c651_state *state,
+ struct dvb_frontend_parameters *p)
{
+ struct i2c_adapter *i2c = state->i2c;
+
dat7021_set_tv_freq(i2c, p->frequency);
at76c651_set_symbolrate(i2c, p->u.qam.symbol_rate);
at76c651_set_inversion(i2c, p->inversion);
- at76c651_set_auto_config(i2c);
+ at76c651_set_auto_config(state);
at76c651_reset(i2c);
return 0;
-
}
-static int at76c651_set_defaults(struct dvb_i2c_bus *i2c)
+static int at76c651_set_defaults(struct at76c651_state *state)
{
+ struct i2c_adapter *i2c = state->i2c;
at76c651_set_symbolrate(i2c, 6900000);
- at76c651_set_qam(i2c, QAM_64);
+ at76c651_set_qam(state, QAM_64);
at76c651_set_bbfreq(i2c);
- at76c651_set_auto_config(i2c);
+ at76c651_set_auto_config(state);
return 0;
-
}
static int at76c651_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
+ struct at76c651_state *state = fe->data;
+ struct i2c_adapter *i2c = state->i2c;
switch (cmd) {
case FE_GET_INFO:
@@ -393,7 +381,7 @@ static int at76c651_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
/*
* Bits: FEC, CAR, EQU, TIM, AGC2, AGC1, ADC, PLL (PLL=0)
*/
- sync = at76c651_readreg(fe->i2c, 0x80);
+ sync = at76c651_readreg(i2c, 0x80);
*status = 0;
@@ -420,9 +408,9 @@ static int at76c651_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
u32 *ber = (u32 *) arg;
- *ber = (at76c651_readreg(fe->i2c, 0x81) & 0x0F) << 16;
- *ber |= at76c651_readreg(fe->i2c, 0x82) << 8;
- *ber |= at76c651_readreg(fe->i2c, 0x83);
+ *ber = (at76c651_readreg(i2c, 0x81) & 0x0F) << 16;
+ *ber |= at76c651_readreg(i2c, 0x82) << 8;
+ *ber |= at76c651_readreg(i2c, 0x83);
*ber *= 10;
break;
@@ -430,7 +418,7 @@ static int at76c651_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
case FE_READ_SIGNAL_STRENGTH:
{
- u8 gain = ~at76c651_readreg(fe->i2c, 0x91);
+ u8 gain = ~at76c651_readreg(i2c, 0x91);
*(u16 *) arg = (gain << 8) | gain;
break;
@@ -439,16 +427,16 @@ static int at76c651_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
case FE_READ_SNR:
*(u16 *) arg =
0xFFFF -
- ((at76c651_readreg(fe->i2c, 0x8F) << 8) |
- at76c651_readreg(fe->i2c, 0x90));
+ ((at76c651_readreg(i2c, 0x8F) << 8) |
+ at76c651_readreg(i2c, 0x90));
break;
case FE_READ_UNCORRECTED_BLOCKS:
- *(u32 *) arg = at76c651_readreg(fe->i2c, 0x82);
+ *(u32 *) arg = at76c651_readreg(i2c, 0x82);
break;
case FE_SET_FRONTEND:
- return at76c651_set_parameters(fe->i2c, arg);
+ return at76c651_set_parameters(state, arg);
case FE_GET_FRONTEND:
break;
@@ -457,11 +445,13 @@ static int at76c651_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
break;
case FE_INIT:
- return at76c651_set_defaults(fe->i2c);
+ return at76c651_set_defaults(state);
case FE_GET_TUNE_SETTINGS:
{
- struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg;
+ struct dvb_frontend_tune_settings* fesettings =
+ (struct dvb_frontend_tune_settings*) arg;
+
fesettings->min_delay_ms = 50;
fesettings->step_size = 0;
fesettings->max_drift = 0;
@@ -473,55 +463,125 @@ static int at76c651_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
}
return 0;
-
}
-static int at76c651_attach(struct dvb_i2c_bus *i2c, void **data)
+static struct i2c_client client_template;
+
+static int attach_adapter(struct i2c_adapter *adapter)
{
- if ( (at76c651_readreg(i2c, 0x0E) != 0x65) ||
- ( ( (at76c651_revision = at76c651_readreg(i2c, 0x0F)) & 0xFE) != 0x10) )
- {
+ struct at76c651_state *state;
+ struct i2c_client *client;
+ int ret;
+
+ if (NULL == (state = kmalloc(sizeof(struct at76c651_state), GFP_KERNEL)))
+ return -ENOMEM;
+
+ state->i2c = adapter;
+ state->revision = at76c651_readreg(adapter, 0x0F) & 0xFE;
+
+ if (state->revision == 0x10) {
+ dprintk("AT76C651A found\n");
+ strcpy(at76c651_info.name, "Atmel AT76C651A with DAT7021");
+ } else {
+ dprintk("AT76C651B found\n");
+ strcpy(at76c651_info.name, "Atmel AT76C651B with DAT7021");
+ }
+
+ if (at76c651_readreg(adapter, 0x0E) != 0x65 ||
+ state->revision != 0x10) {
dprintk("no AT76C651(B) found\n");
+ kfree(state);
return -ENODEV;
}
- if (at76c651_revision == 0x10)
- {
- dprintk("AT76C651A found\n");
- strcpy(at76c651_info.name,"Atmel AT76C651A with DAT7021");
+ if (NULL == (client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
+ kfree(state);
+ return -ENOMEM;
}
- else
- {
- strcpy(at76c651_info.name,"Atmel AT76C651B with DAT7021");
- dprintk("AT76C651B found\n");
+
+ memcpy(client, &client_template, sizeof(struct i2c_client));
+ client->adapter = adapter;
+ client->addr = 0x1a >> 1;
+ i2c_set_clientdata(client, state);
+
+ ret = i2c_attach_client(client);
+ if (ret) {
+ kfree(state);
+ kfree(client);
+ return ret;
}
- at76c651_set_defaults(i2c);
+ BUG_ON(!state->dvb);
- return dvb_register_frontend(at76c651_ioctl, i2c, NULL, &at76c651_info);
+ ret = dvb_register_frontend_new(at76c651_ioctl, state->dvb, state, &at76c651_info);
+ if (ret) {
+ i2c_detach_client(client);
+ kfree(client);
+ kfree(state);
+ return ret;
+ }
+ return 0;
}
-static void at76c651_detach(struct dvb_i2c_bus *i2c, void *data)
+static int detach_client(struct i2c_client *client)
{
+ struct at76c651_state *state = (struct at76c651_state*)i2c_get_clientdata(client);
- dvb_unregister_frontend(at76c651_ioctl, i2c);
+ dprintk ("%s\n", __FUNCTION__);
+ dvb_unregister_frontend_new(at76c651_ioctl, state->dvb);
+ i2c_detach_client(client);
+ BUG_ON(state->dvb);
+ kfree(client);
+ kfree(state);
+ return 0;
}
-static int __init at76c651_init(void)
+static int command (struct i2c_client *client, unsigned int cmd, void *arg)
{
+ struct at76c651_state *state = (struct at76c651_state*)i2c_get_clientdata(client);
- return dvb_register_i2c_device(THIS_MODULE, at76c651_attach,
- at76c651_detach);
+ dprintk ("%s\n", __FUNCTION__);
+ switch (cmd) {
+ case FE_REGISTER:
+ state->dvb = (struct dvb_adapter*)arg;
+ break;
+ case FE_UNREGISTER:
+ state->dvb = NULL;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
}
-static void __exit at76c651_exit(void)
-{
+static struct i2c_driver driver = {
+ .owner = THIS_MODULE,
+ .name = "at76c651",
+ .id = I2C_DRIVERID_DVBFE_AT76C651,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = attach_adapter,
+ .detach_client = detach_client,
+ .command = command,
+};
+
+static struct i2c_client client_template = {
+ I2C_DEVNAME("at76c651"),
+ .flags = I2C_CLIENT_ALLOW_USE,
+ .driver = &driver,
+};
- dvb_unregister_i2c_device(at76c651_attach);
+static int __init at76c651_init(void)
+{
+ return i2c_add_driver(&driver);
+}
+static void __exit at76c651_exit(void)
+{
+ if (i2c_del_driver(&driver))
+ printk(KERN_ERR "at76c651: driver deregistration failed.\n");
}
module_init(at76c651_init);