summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorKenneth Aafloy <devnull@localhost>2004-07-16 18:20:10 +0000
committerKenneth Aafloy <devnull@localhost>2004-07-16 18:20:10 +0000
commit2ae9e8fdd009dc568f8447b64c6e93bd95c26981 (patch)
tree8de345bc16fcbe4e01f8531a69c376123975cc10 /linux
parent1e5206f141b6df2b23ae88ba45d305f9e4cc6975 (diff)
downloadmediapointer-dvb-s2-2ae9e8fdd009dc568f8447b64c6e93bd95c26981.tar.gz
mediapointer-dvb-s2-2ae9e8fdd009dc568f8447b64c6e93bd95c26981.tar.bz2
- Conversion to Kernel I2C layer.
- MODULE_PARM* -> module_param* - Common name for I2C device and prefix for debug messages. NOTE: This needs testing by someone who has one of these frontends.
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/dvb/frontends/mt312.c244
-rw-r--r--linux/drivers/media/dvb/frontends/mt352.c263
-rw-r--r--linux/drivers/media/dvb/frontends/mt352.h16
3 files changed, 340 insertions, 183 deletions
diff --git a/linux/drivers/media/dvb/frontends/mt312.c b/linux/drivers/media/dvb/frontends/mt312.c
index 69ac22d5e..07e673a20 100644
--- a/linux/drivers/media/dvb/frontends/mt312.c
+++ b/linux/drivers/media/dvb/frontends/mt312.c
@@ -32,26 +32,27 @@
#include "dvb_frontend.h"
#include "mt312.h"
+#define FRONTEND_NAME "dvbfe_mt312"
+
+#define dprintk(args...) \
+ do { \
+ if (debug) printk(KERN_DEBUG FRONTEND_NAME ": " args); \
+ } while (0)
+
+static int debug;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+
#define I2C_ADDR_MT312 0x0e
#define I2C_ADDR_SL1935 0x61
#define I2C_ADDR_TSA5059 0x61
-#define MT312_DEBUG 0
-
#define MT312_SYS_CLK 90000000UL /* 90 MHz */
#define MT312_LPOWER_SYS_CLK 60000000UL /* 60 MHz */
#define MT312_PLL_CLK 10000000UL /* 10 MHz */
-/* number of active frontends */
-static int mt312_count = 0;
-
-#if MT312_DEBUG == 0
-#define dprintk(x...)
-#else
-static int debug = 0;
-#define dprintk if(debug == 1) printk
-#endif
-
static struct dvb_frontend_info mt312_info = {
.name = "Zarlink MT312",
.type = FE_QPSK,
@@ -70,7 +71,13 @@ static struct dvb_frontend_info mt312_info = {
FE_CAN_RECOVER
};
-static int mt312_read(struct dvb_i2c_bus *i2c,
+struct mt312_state {
+ struct i2c_adapter *i2c;
+ struct dvb_adapter *dvb;
+ int id;
+};
+
+static int mt312_read(struct i2c_adapter *i2c,
const enum mt312_reg_addr reg, void *buf,
const size_t count)
{
@@ -87,26 +94,25 @@ static int mt312_read(struct dvb_i2c_bus *i2c,
msg[1].buf = buf;
msg[1].len = count;
- ret = i2c->xfer(i2c, msg, 2);
+ ret = i2c_transfer(i2c, msg, 2);
- if ((ret != 2) && (mt312_count != 0)) {
+ if (ret != 2) {
printk(KERN_ERR "%s: ret == %d\n", __FUNCTION__, ret);
return -EREMOTEIO;
}
-#if MT312_DEBUG
+
if(debug) {
int i;
- printk(KERN_INFO "R(%d):", reg & 0x7f);
+ dprintk("R(%d):", reg & 0x7f);
for (i = 0; i < count; i++)
printk(" %02x", ((const u8 *) buf)[i]);
printk("\n");
}
-#endif
return 0;
}
-static int mt312_write(struct dvb_i2c_bus *i2c,
+static int mt312_write(struct i2c_adapter *i2c,
const enum mt312_reg_addr reg, const void *src,
const size_t count)
{
@@ -114,15 +120,13 @@ static int mt312_write(struct dvb_i2c_bus *i2c,
u8 buf[count + 1];
struct i2c_msg msg;
-#if MT312_DEBUG
if(debug) {
int i;
- printk(KERN_INFO "W(%d):", reg & 0x7f);
+ dprintk("W(%d):", reg & 0x7f);
for (i = 0; i < count; i++)
printk(" %02x", ((const u8 *) src)[i]);
printk("\n");
}
-#endif
buf[0] = reg;
memcpy(&buf[1], src, count);
@@ -132,29 +136,29 @@ static int mt312_write(struct dvb_i2c_bus *i2c,
msg.buf = buf;
msg.len = count + 1;
- ret = i2c->xfer(i2c, &msg, 1);
+ ret = i2c_transfer(i2c, &msg, 1);
if (ret != 1) {
- printk(KERN_ERR "%s: ret == %d\n", __FUNCTION__, ret);
+ dprintk("%s: ret == %d\n", __FUNCTION__, ret);
return -EREMOTEIO;
}
return 0;
}
-static inline int mt312_readreg(struct dvb_i2c_bus *i2c,
+static inline int mt312_readreg(struct i2c_adapter *i2c,
const enum mt312_reg_addr reg, u8 *val)
{
return mt312_read(i2c, reg, val, 1);
}
-static inline int mt312_writereg(struct dvb_i2c_bus *i2c,
+static inline int mt312_writereg(struct i2c_adapter *i2c,
const enum mt312_reg_addr reg, const u8 val)
{
return mt312_write(i2c, reg, &val, 1);
}
-static int mt312_pll_write(struct dvb_i2c_bus *i2c, const u8 addr,
+static int mt312_pll_write(struct i2c_adapter *i2c, const u8 addr,
u8 * buf, const u8 len)
{
int ret;
@@ -168,7 +172,7 @@ static int mt312_pll_write(struct dvb_i2c_bus *i2c, const u8 addr,
if ((ret = mt312_writereg(i2c, GPP_CTRL, 0x40)) < 0)
return ret;
- if ((ret = i2c->xfer(i2c, &msg, 1)) != 1)
+ if ((ret = i2c_transfer(i2c, &msg, 1)) != 1)
printk(KERN_ERR "%s: i/o error (ret == %d)\n", __FUNCTION__, ret);
if ((ret = mt312_writereg(i2c, GPP_CTRL, 0x00)) < 0)
@@ -182,7 +186,7 @@ static inline u32 mt312_div(u32 a, u32 b)
return (a + (b / 2)) / b;
}
-static int sl1935_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq, u32 sr)
+static int sl1935_set_tv_freq(struct i2c_adapter *i2c, u32 freq, u32 sr)
{
/* 155 uA, Baseband Path B */
u8 buf[4] = { 0x00, 0x00, 0x80, 0x00 };
@@ -219,7 +223,7 @@ static int sl1935_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq, u32 sr)
return mt312_pll_write(i2c, I2C_ADDR_SL1935, buf, sizeof(buf));
}
-static int tsa5059_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq, u32 sr)
+static int tsa5059_set_tv_freq(struct i2c_adapter *i2c, u32 freq, u32 sr)
{
u8 buf[4];
@@ -239,13 +243,14 @@ static int tsa5059_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq, u32 sr)
return mt312_pll_write(i2c, I2C_ADDR_TSA5059, buf, sizeof(buf));
}
-static int mt312_reset(struct dvb_i2c_bus *i2c, const u8 full)
+static int mt312_reset(struct i2c_adapter *i2c, const u8 full)
{
return mt312_writereg(i2c, RESET, full ? 0x80 : 0x40);
}
-static int mt312_init(struct dvb_i2c_bus *i2c, const long id, u8 pll)
+static int mt312_initfe(struct mt312_state *state, u8 pll)
{
+ struct i2c_adapter *i2c = state->i2c;
int ret;
u8 buf[2];
@@ -297,7 +302,7 @@ static int mt312_init(struct dvb_i2c_bus *i2c, const long id, u8 pll)
return 0;
}
-static int mt312_send_master_cmd(struct dvb_i2c_bus *i2c,
+static int mt312_send_master_cmd(struct i2c_adapter *i2c,
const struct dvb_diseqc_master_cmd *c)
{
int ret;
@@ -328,14 +333,14 @@ static int mt312_send_master_cmd(struct dvb_i2c_bus *i2c,
return 0;
}
-static int mt312_recv_slave_reply(struct dvb_i2c_bus *i2c,
+static int mt312_recv_slave_reply(struct i2c_adapter *i2c,
struct dvb_diseqc_slave_reply *r)
{
/* TODO */
return -EOPNOTSUPP;
}
-static int mt312_send_burst(struct dvb_i2c_bus *i2c, const fe_sec_mini_cmd_t c)
+static int mt312_send_burst(struct i2c_adapter *i2c, const fe_sec_mini_cmd_t c)
{
const u8 mini_tab[2] = { 0x02, 0x03 };
@@ -356,7 +361,7 @@ static int mt312_send_burst(struct dvb_i2c_bus *i2c, const fe_sec_mini_cmd_t c)
return 0;
}
-static int mt312_set_tone(struct dvb_i2c_bus *i2c, const fe_sec_tone_mode_t t)
+static int mt312_set_tone(struct i2c_adapter *i2c, const fe_sec_tone_mode_t t)
{
const u8 tone_tab[2] = { 0x01, 0x00 };
@@ -377,7 +382,7 @@ static int mt312_set_tone(struct dvb_i2c_bus *i2c, const fe_sec_tone_mode_t t)
return 0;
}
-static int mt312_set_voltage(struct dvb_i2c_bus *i2c, const fe_sec_voltage_t v)
+static int mt312_set_voltage(struct i2c_adapter *i2c, const fe_sec_voltage_t v)
{
const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
@@ -387,8 +392,9 @@ static int mt312_set_voltage(struct dvb_i2c_bus *i2c, const fe_sec_voltage_t v)
return mt312_writereg(i2c, DISEQC_MODE, volt_tab[v]);
}
-static int mt312_read_status(struct dvb_i2c_bus *i2c, fe_status_t *s, const long id)
+static int mt312_read_status(struct mt312_state *state, fe_status_t *s)
{
+ struct i2c_adapter *i2c = state->i2c;
int ret;
u8 status[3], vit_mode;
@@ -409,8 +415,9 @@ static int mt312_read_status(struct dvb_i2c_bus *i2c, fe_status_t *s, const long
*s |= FE_HAS_SYNC; /* byte align lock */
if (status[0] & 0x01)
*s |= FE_HAS_LOCK; /* qpsk lock */
+
// VP310 doesn't have AUTO, so we "implement it here" ACCJr
- if ((id == ID_VP310) && !(status[0] & 0x01)) {
+ if ((state->id == ID_VP310) && !(status[0] & 0x01)) {
if ((ret = mt312_readreg(i2c, VIT_MODE, &vit_mode)) < 0)
return ret;
vit_mode ^= 0x40;
@@ -423,7 +430,7 @@ static int mt312_read_status(struct dvb_i2c_bus *i2c, fe_status_t *s, const long
return 0;
}
-static int mt312_read_bercnt(struct dvb_i2c_bus *i2c, u32 *ber)
+static int mt312_read_bercnt(struct i2c_adapter *i2c, u32 *ber)
{
int ret;
u8 buf[3];
@@ -436,7 +443,7 @@ static int mt312_read_bercnt(struct dvb_i2c_bus *i2c, u32 *ber)
return 0;
}
-static int mt312_read_agc(struct dvb_i2c_bus *i2c, u16 *signal_strength)
+static int mt312_read_agc(struct i2c_adapter *i2c, u16 *signal_strength)
{
int ret;
u8 buf[3];
@@ -456,7 +463,7 @@ static int mt312_read_agc(struct dvb_i2c_bus *i2c, u16 *signal_strength)
return 0;
}
-static int mt312_read_snr(struct dvb_i2c_bus *i2c, u16 *snr)
+static int mt312_read_snr(struct i2c_adapter *i2c, u16 *snr)
{
int ret;
u8 buf[2];
@@ -469,7 +476,7 @@ static int mt312_read_snr(struct dvb_i2c_bus *i2c, u16 *snr)
return 0;
}
-static int mt312_read_ubc(struct dvb_i2c_bus *i2c, u32 *ubc)
+static int mt312_read_ubc(struct i2c_adapter *i2c, u32 *ubc)
{
int ret;
u8 buf[2];
@@ -482,10 +489,10 @@ static int mt312_read_ubc(struct dvb_i2c_bus *i2c, u32 *ubc)
return 0;
}
-static int mt312_set_frontend(struct dvb_i2c_bus *i2c,
- const struct dvb_frontend_parameters *p,
- const long id)
+static int mt312_set_frontend(struct mt312_state *state,
+ const struct dvb_frontend_parameters *p)
{
+ struct i2c_adapter *i2c = state->i2c;
int ret;
u8 buf[5], config_val;
u16 sr;
@@ -494,7 +501,7 @@ static int mt312_set_frontend(struct dvb_i2c_bus *i2c,
{ 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f };
const u8 inv_tab[3] = { 0x00, 0x40, 0x80 };
- int (*set_tv_freq)(struct dvb_i2c_bus *i2c, u32 freq, u32 sr);
+ int (*set_tv_freq)(struct i2c_adapter *i2c, u32 freq, u32 sr);
dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency);
@@ -518,7 +525,7 @@ static int mt312_set_frontend(struct dvb_i2c_bus *i2c,
|| (p->u.qpsk.fec_inner == FEC_8_9))
return -EINVAL;
- switch (id) {
+ switch (state->id) {
case ID_VP310:
// For now we will do this only for the VP310.
// It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03
@@ -527,13 +534,13 @@ static int mt312_set_frontend(struct dvb_i2c_bus *i2c,
if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz
{
if ((config_val & 0x0c) == 0x08) //We are running 60MHz
- if ((ret = mt312_init(i2c, id, (u8) 90)) < 0)
+ if ((ret = mt312_initfe(state, (u8) 90)) < 0)
return ret;
}
else
{
if ((config_val & 0x0c) == 0x0C) //We are running 90MHz
- if ((ret = mt312_init(i2c, id, (u8) 60)) < 0)
+ if ((ret = mt312_initfe(state, (u8) 60)) < 0)
return ret;
}
set_tv_freq = tsa5059_set_tv_freq;
@@ -575,7 +582,7 @@ static int mt312_set_frontend(struct dvb_i2c_bus *i2c,
return 0;
}
-static int mt312_get_inversion(struct dvb_i2c_bus *i2c,
+static int mt312_get_inversion(struct i2c_adapter *i2c,
fe_spectral_inversion_t *i)
{
int ret;
@@ -590,7 +597,7 @@ static int mt312_get_inversion(struct dvb_i2c_bus *i2c,
return 0;
}
-static int mt312_get_symbol_rate(struct dvb_i2c_bus *i2c, u32 *sr)
+static int mt312_get_symbol_rate(struct i2c_adapter *i2c, u32 *sr)
{
int ret;
u8 sym_rate_h;
@@ -637,7 +644,7 @@ static int mt312_get_symbol_rate(struct dvb_i2c_bus *i2c, u32 *sr)
return 0;
}
-static int mt312_get_code_rate(struct dvb_i2c_bus *i2c, fe_code_rate_t *cr)
+static int mt312_get_code_rate(struct i2c_adapter *i2c, fe_code_rate_t *cr)
{
const fe_code_rate_t fec_tab[8] =
{ FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8,
@@ -654,7 +661,7 @@ static int mt312_get_code_rate(struct dvb_i2c_bus *i2c, fe_code_rate_t *cr)
return 0;
}
-static int mt312_get_frontend(struct dvb_i2c_bus *i2c,
+static int mt312_get_frontend(struct i2c_adapter *i2c,
struct dvb_frontend_parameters *p)
{
int ret;
@@ -671,7 +678,7 @@ static int mt312_get_frontend(struct dvb_i2c_bus *i2c,
return 0;
}
-static int mt312_sleep(struct dvb_i2c_bus *i2c)
+static int mt312_sleep(struct i2c_adapter *i2c)
{
int ret;
u8 config;
@@ -692,7 +699,8 @@ static int mt312_sleep(struct dvb_i2c_bus *i2c)
static int mt312_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
- struct dvb_i2c_bus *i2c = fe->i2c;
+ struct mt312_state *state = fe->data;
+ struct i2c_adapter *i2c = state->i2c;
switch (cmd) {
case FE_GET_INFO:
@@ -706,7 +714,7 @@ static int mt312_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
return mt312_send_master_cmd(i2c, arg);
case FE_DISEQC_RECV_SLAVE_REPLY:
- if ((long) fe->data == ID_MT312)
+ if (state->id == ID_MT312)
return mt312_recv_slave_reply(i2c, arg);
else
return -EOPNOTSUPP;
@@ -724,7 +732,7 @@ static int mt312_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
return -EOPNOTSUPP;
case FE_READ_STATUS:
- return mt312_read_status(i2c, arg, (long) fe->data);
+ return mt312_read_status(state, arg);
case FE_READ_BER:
return mt312_read_bercnt(i2c, arg);
@@ -739,7 +747,7 @@ static int mt312_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
return mt312_read_ubc(i2c, arg);
case FE_SET_FRONTEND:
- return mt312_set_frontend(i2c, arg, (long) fe->data);
+ return mt312_set_frontend(state, arg);
case FE_GET_FRONTEND:
return mt312_get_frontend(i2c, arg);
@@ -751,12 +759,14 @@ static int mt312_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
return mt312_sleep(i2c);
case FE_INIT:
- //For the VP310 we should run at 60MHz when ever possible.
- //It should be better to run the mt312 ar lower speed when ever possible, but tunning will be slower. ACCJr 09/29/03
- if ((long)fe->data == ID_MT312)
- return mt312_init(i2c, (long) fe->data, (u8) 90);
+ /* For the VP310 we should run at 60MHz when ever possible.
+ * It should be better to run the mt312 ar lower speed when
+ * ever possible, but tunning will be slower. ACCJr 09/29/03
+ */
+ if (state->id == ID_MT312)
+ return mt312_initfe(state, (u8) 90);
else
- return mt312_init(i2c, (long) fe->data, (u8) 60);
+ return mt312_initfe(state, (u8) 60);
case FE_GET_TUNE_SETTINGS:
{
@@ -774,52 +784,124 @@ static int mt312_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
return 0;
}
-static int mt312_attach(struct dvb_i2c_bus *i2c, void **data)
+static struct i2c_client client_template;
+
+static int mt312_attach_adapter(struct i2c_adapter *adapter)
{
+ struct mt312_state *state;
+ struct i2c_client *client;
int ret;
u8 id;
- if ((ret = mt312_readreg(i2c, ID, &id)) < 0)
- return ret;
+ dprintk("Trying to attach to adapter 0x%x:%s.\n",
+ adapter->id, adapter->name);
+
+ if (mt312_readreg(adapter, ID, &id) < 0)
+ return -ENODEV;
if ((id != ID_VP310) && (id != ID_MT312))
return -ENODEV;
- if ((ret = dvb_register_frontend(mt312_ioctl, i2c,
- (void *)(long)id, &mt312_info)) < 0)
+ if ( !(state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL)) )
+ return -ENOMEM;
+
+ memset(state, 0, sizeof(struct mt312_state));
+ state->i2c = adapter;
+ state->id = id;
+
+ if ( !(client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)) ) {
+ kfree(state);
+ return -ENOMEM;
+ }
+
+ memcpy(client, &client_template, sizeof(struct i2c_client));
+ client->adapter = adapter;
+ client->addr = I2C_ADDR_MT312;
+ i2c_set_clientdata(client, state);
+
+ if ((ret = i2c_attach_client(client))) {
+ kfree(client);
+ kfree(state);
+ return ret;
+ }
+
+ BUG_ON(!state->dvb);
+
+ if ((ret = dvb_register_frontend_new(mt312_ioctl, state->dvb, state,
+ &mt312_info, THIS_MODULE))) {
+ i2c_detach_client(client);
+ kfree(client);
+ kfree(state);
return ret;
+ }
+
+ return 0;
+}
+
+static int mt312_detach_client(struct i2c_client *client)
+{
+ struct mt312_state *state = i2c_get_clientdata(client);
- mt312_count++;
+ dprintk ("%s\n", __FUNCTION__);
+ dvb_unregister_frontend_new (mt312_ioctl, state->dvb);
+ i2c_detach_client(client);
+ BUG_ON(state->dvb);
+ kfree(client);
+ kfree(state);
return 0;
}
-static void mt312_detach(struct dvb_i2c_bus *i2c, void *data)
+static int mt312_command (struct i2c_client *client, unsigned int cmd, void *arg)
{
- dvb_unregister_frontend(mt312_ioctl, i2c);
+ struct mt312_state *state = i2c_get_clientdata(client);
- if (mt312_count)
- mt312_count--;
+ 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 = FRONTEND_NAME,
+ .id = I2C_DRIVERID_DVBFE_MT312,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = mt312_attach_adapter,
+ .detach_client = mt312_detach_client,
+ .command = mt312_command,
+};
+
+static struct i2c_client client_template = {
+ .name = FRONTEND_NAME,
+ .flags = I2C_CLIENT_ALLOW_USE,
+ .driver = &driver,
+};
+
static int __init mt312_module_init(void)
{
- return dvb_register_i2c_device(THIS_MODULE, mt312_attach, mt312_detach);
+ return i2c_add_driver(&driver);
}
static void __exit mt312_module_exit(void)
{
- dvb_unregister_i2c_device(mt312_attach);
+ if (i2c_del_driver(&driver))
+ printk(KERN_ERR "mt312: driver deregistration failed.\n");
}
module_init(mt312_module_init);
module_exit(mt312_module_exit);
-#if MT312_DEBUG != 0
-MODULE_PARM(debug,"i");
-MODULE_PARM_DESC(debug, "enable verbose debug messages");
-#endif
-
MODULE_DESCRIPTION("MT312 Satellite Channel Decoder Driver");
MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
MODULE_LICENSE("GPL");
+
diff --git a/linux/drivers/media/dvb/frontends/mt352.c b/linux/drivers/media/dvb/frontends/mt352.c
index ab5f8b7ac..ff5c1a8d2 100644
--- a/linux/drivers/media/dvb/frontends/mt352.c
+++ b/linux/drivers/media/dvb/frontends/mt352.c
@@ -36,14 +36,37 @@
#include "dvb_frontend.h"
#include "mt352.h"
+#define FRONTEND_NAME "dvbfe_mt352"
+
+#define dprintk(args...) \
+ do { \
+ if (debug) printk(KERN_DEBUG FRONTEND_NAME ": " args); \
+ } while (0)
+
+static int debug;
static int force_card = -1;
-static u32 card_type = -1;
+static int card_type = -1;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+//FIXME: Should be an array.
+module_param(force_card, int, 0444);
+MODULE_PARM_DESC(force_card, "Force card type.\n\t(0 == AVDVBT771, 1 == TUA6034, "
+ "2 == TDTC9251DH01C).\n\tDefault is that AVDVBT771 is attempted "
+ "to be autodetected,\n\tif you do not have this card, you must "
+ "specify the card type here.");
+
+
+struct mt352_state {
+ struct i2c_adapter *i2c;
+ struct dvb_adapter *dvb;
+};
#define mt352_write(ibuf, ilen) \
do { \
struct i2c_msg msg = { .addr = I2C_MT352_ADDR, .flags = 0, \
.buf = ibuf, .len = ilen }; \
- int err = i2c->xfer(i2c, &msg, 1); \
+ int err = i2c_transfer(i2c, &msg, 1); \
if (err != 1) { \
printk(KERN_WARNING \
"mt352_write() failed (err = %d)!\n", err); \
@@ -51,23 +74,8 @@ do { \
} \
} while (0)
+// FIXME:
static struct _tuner_info tuner_info [] = {
- //TUA6034 tuner
- {
- .fe_frequency_min = 174000000,
- .fe_frequency_max = 862000000,
- .fe_frequency_stepsize = 166667,
- .coderate_hp_shift = 9,
- .coderate_lp_shift = 6,
- .constellation_shift = 14,
- .tx_mode_shift = 1,
- .guard_interval_shift = 3,
- .hierarchy_shift = 12,
- .read_reg_flag = I2C_M_NOSTART,
- .mt352_init = mt352_init_TUA6034,
- .mt352_charge_pump = mt352_cp_TUA6034,
- .mt352_band_select = mt352_bs_TUA6034
- },
//AVERMEDIA 771 board
{
.fe_frequency_min = 174000000,
@@ -84,6 +92,22 @@ static struct _tuner_info tuner_info [] = {
.mt352_charge_pump = mt352_cp_AVERMEDIA771,
.mt352_band_select = mt352_bs_AVERMEDIA771
},
+ //TUA6034 tuner
+ {
+ .fe_frequency_min = 174000000,
+ .fe_frequency_max = 862000000,
+ .fe_frequency_stepsize = 166667,
+ .coderate_hp_shift = 9,
+ .coderate_lp_shift = 6,
+ .constellation_shift = 14,
+ .tx_mode_shift = 1,
+ .guard_interval_shift = 3,
+ .hierarchy_shift = 12,
+ .read_reg_flag = I2C_M_NOSTART,
+ .mt352_init = mt352_init_TUA6034,
+ .mt352_charge_pump = mt352_cp_TUA6034,
+ .mt352_band_select = mt352_bs_TUA6034
+ },
//TDTC9251DH01C tuner
{
.fe_frequency_min = 474000000,
@@ -125,7 +149,7 @@ static struct dvb_frontend_info mt352_info = {
FE_CAN_MUTE_TS
};
-static int mt352_init_TUA6034(struct dvb_i2c_bus *i2c)
+static int mt352_init_TUA6034(struct i2c_adapter *i2c)
{
static u8 mt352_reset [] = { RESET, 0x80 };
static u8 mt352_clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
@@ -144,7 +168,7 @@ static int mt352_init_TUA6034(struct dvb_i2c_bus *i2c)
return 0;
}
-static int mt352_init_AVERMEDIA771(struct dvb_i2c_bus *i2c)
+static int mt352_init_AVERMEDIA771(struct i2c_adapter *i2c)
{
static u8 mt352_reset [] = { RESET, 0x80 };
static u8 mt352_clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
@@ -167,7 +191,7 @@ static int mt352_init_AVERMEDIA771(struct dvb_i2c_bus *i2c)
return 0;
}
-static int mt352_init_TDTC9251DH01C(struct dvb_i2c_bus *i2c)
+static int mt352_init_TDTC9251DH01C(struct i2c_adapter *i2c)
{
static u8 mt352_reset [] = { RESET, 0x80 };
static u8 mt352_clock_config [] = { CLOCK_CTL, 0x10, 0x2d };
@@ -286,7 +310,7 @@ static unsigned char mt352_bs_TDTC9251DH01C(u32 freq)
}
-static int mt352_detect_avermedia_771(struct dvb_i2c_bus *i2c)
+static int mt352_detect_avermedia_771(struct i2c_adapter *i2c)
{
int i;
u8 reg;
@@ -311,7 +335,7 @@ static int mt352_detect_avermedia_771(struct dvb_i2c_bus *i2c)
{
reg = i + 0xFC;
msg[1].buf = id + i;
- if (i2c->xfer(i2c,msg,2) != 2)
+ if (i2c_transfer(i2c,msg,2) != 2)
{
return 0;
}
@@ -320,30 +344,7 @@ static int mt352_detect_avermedia_771(struct dvb_i2c_bus *i2c)
return *((u32 *) id) == *((u32 *) pciid);
}
-static int mt352_detect_tdtc9251dh01c(struct dvb_i2c_bus *i2c)
-{
- /* detection code must be written */
-
- /* for Airstar2 DVB-T checking the PCI ID */
- /* is not enought because the one reported from */
- /* lspci is the one of Skystar2 */
-
- if (force_card == 2)
- return(1);
- else
- return(0);
-}
-
-static int mt352_detect_tua6034(struct dvb_i2c_bus *i2c)
-{
- /* detection code must be written */
- if (force_card == 0)
- return(1);
- else
- return(0);
-}
-
-static int mt352_init(struct dvb_i2c_bus *i2c)
+static int mt352_init(struct i2c_adapter *i2c)
{
/**
* all register write sequence have the register address of the
@@ -362,7 +363,7 @@ static int mt352_init(struct dvb_i2c_bus *i2c)
return(MT352_INIT(i2c));
}
-static int mt352_sleep(struct dvb_i2c_bus *i2c)
+static int mt352_sleep(struct i2c_adapter *i2c)
{
static u8 mt352_softdown[] = { 0x89, 0x20, 0x08 };
@@ -371,7 +372,7 @@ static int mt352_sleep(struct dvb_i2c_bus *i2c)
return 0;
}
-static int mt352_set_parameters(struct dvb_i2c_bus *i2c,
+static int mt352_set_parameters(struct i2c_adapter *i2c,
struct dvb_frontend_parameters *param)
{
unsigned char buf[14];
@@ -529,7 +530,7 @@ static int mt352_set_parameters(struct dvb_i2c_bus *i2c,
return 0;
}
-static u8 mt352_read_register(struct dvb_i2c_bus *i2c, u8 reg)
+static u8 mt352_read_register(struct i2c_adapter *i2c, u8 reg)
{
int ret;
u8 b0 [] = { reg };
@@ -541,7 +542,7 @@ static u8 mt352_read_register(struct dvb_i2c_bus *i2c, u8 reg)
.flags = I2C_M_RD,
.buf = b1, .len = 1 } };
- ret = i2c->xfer (i2c, msg, 2);
+ ret = i2c_transfer(i2c, msg, 2);
if (ret != 2)
printk(KERN_WARNING
@@ -551,7 +552,7 @@ static u8 mt352_read_register(struct dvb_i2c_bus *i2c, u8 reg)
}
-static int mt352_get_parameters(struct dvb_i2c_bus *i2c,
+static int mt352_get_parameters(struct i2c_adapter *i2c,
struct dvb_frontend_parameters *param)
{
u16 tps;
@@ -668,7 +669,8 @@ static int mt352_get_parameters(struct dvb_i2c_bus *i2c,
static int mt352_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
- struct dvb_i2c_bus *i2c = fe->i2c;
+ struct mt352_state *state = fe->data;
+ struct i2c_adapter *i2c = state->i2c;
u8 r,snr;
fe_status_t *status;
u16 signal;
@@ -750,72 +752,147 @@ static int mt352_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
return 0;
}
+static struct i2c_client client_template;
-static int mt352_attach(struct dvb_i2c_bus *i2c, void **data)
+static int mt352_attach_adapter(struct i2c_adapter *i2c)
{
+ struct mt352_state *state;
+ struct i2c_client *client;
static u8 mt352_reset_attach [] = { 0x50, 0xC0 };
+ int ret;
+
+ dprintk("Trying to attach to adapter 0x%x:%s.\n",
+ i2c->id, i2c->name);
/* set the proper MT352 frequency range */
mt352_info.frequency_min = FE_FREQ_MIN;
mt352_info.frequency_max = FE_FREQ_MAX;
mt352_info.frequency_stepsize = FE_FREQ_STEPSIZE;
- if (mt352_read_register(i2c, CHIP_ID) == ID_MT352)
- {
- if (mt352_detect_avermedia_771(i2c))
- {
- card_type = CARD_AVDVBT771;
- }
- else if (mt352_detect_tdtc9251dh01c(i2c))
- {
- card_type = CARD_TDTC9251DH01C;
- }
- else if (mt352_detect_tua6034(i2c))
- {
- card_type = CARD_TUA6034;
- }
- else
- {
- return -ENODEV;
- }
- /* Do a "hard" reset */
- mt352_write(mt352_reset_attach,sizeof(mt352_reset_attach));
- /* Don't waste power and (maybe) pci bandwidth */
- mt352_sleep(i2c);
- return dvb_register_frontend(mt352_ioctl, i2c, NULL,
- &mt352_info);
+ if (mt352_read_register(i2c, CHIP_ID) != ID_MT352)
+ return -ENODEV;
+
+ if ( !(state = kmalloc(sizeof(struct mt352_state), GFP_KERNEL)) )
+ return -ENOMEM;
+
+ memset(state, 0, sizeof(struct mt352_state));
+ state->i2c = i2c;
+
+ if (mt352_detect_avermedia_771(i2c)) {
+ card_type = CARD_AVDVBT771;
+ } else if (force_card < 0) {
+ dprintk("Avermedia 771 not detected, maybe you should try the "
+ "'force_card' module parameter?.\n");
+ kfree(state);
+ return -ENODEV;
}
- return -ENODEV;
-}
+ if (force_card > 0) {
+ if (card_type >= 0 && force_card != card_type)
+ printk(KERN_WARNING "dvbfe_mt352: Warning, overriding"
+ " detected card.\n");
+ card_type = force_card;
+ }
+ if (card_type == CARD_AVDVBT771)
+ printk(KERN_INFO FRONTEND_NAME ": Setup for Avermedia 771.\n");
+ else if (card_type == CARD_TUA6034)
+ printk(KERN_INFO FRONTEND_NAME ": Setup for TUA6034.\n");
+ else if (card_type == CARD_TDTC9251DH01C)
+ printk(KERN_INFO FRONTEND_NAME ": Setup for TDTC9251DH01C.\n");
-static void mt352_detach(struct dvb_i2c_bus *i2c, void *data)
-{
- mt352_sleep(i2c);
- dvb_unregister_frontend(mt352_ioctl, i2c);
+ /* Do a "hard" reset */
+ mt352_write(mt352_reset_attach, sizeof(mt352_reset_attach));
+
+ if ( !(client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)) ) {
+ kfree(state);
+ return -ENOMEM;
+ }
+
+ memcpy(client, &client_template, sizeof(struct i2c_client));
+ client->adapter = i2c;
+ client->addr = 0; // XXX
+ i2c_set_clientdata(client, state);
+
+ if ((ret = i2c_attach_client(client))) {
+ kfree(client);
+ kfree(state);
+ return ret;
+ }
+
+ BUG_ON(!state->dvb);
+
+ if ((ret = dvb_register_frontend_new(mt352_ioctl, state->dvb, state,
+ &mt352_info, THIS_MODULE))) {
+ i2c_detach_client(client);
+ kfree(client);
+ kfree(state);
+ return ret;
+ }
+
+ return 0;
}
+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);
+ i2c_detach_client(client);
+ BUG_ON(state->dvb);
+ kfree(client);
+ kfree(state);
+ return 0;
+}
-static int __init init_mt352(void)
+static int mt352_command (struct i2c_client *client, unsigned int cmd, void *arg)
{
- return dvb_register_i2c_device(NULL, mt352_attach, mt352_detach);
+ struct mt352_state *state = i2c_get_clientdata(client);
+
+ 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 = FRONTEND_NAME,
+ .id = I2C_DRIVERID_DVBFE_MT352,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = mt352_attach_adapter,
+ .detach_client = mt352_detach_client,
+ .command = mt352_command,
+};
-static void __exit exit_mt352(void)
+static struct i2c_client client_template = {
+ .name = FRONTEND_NAME,
+ .flags = I2C_CLIENT_ALLOW_USE,
+ .driver = &driver,
+};
+
+static int __init mt352_module_init(void)
{
- dvb_unregister_i2c_device(mt352_attach);
+ return i2c_add_driver(&driver);
}
+static void __exit mt352_module_exit(void)
+{
+ if (i2c_del_driver(&driver))
+ printk(KERN_ERR "mt352: driver deregistration failed.\n");
+}
-module_init(init_mt352);
-module_exit(exit_mt352);
-
+module_init(mt352_module_init);
+module_exit(mt352_module_exit);
MODULE_DESCRIPTION("DVB-T MT352 Zarlink");
MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
MODULE_LICENSE("GPL");
-MODULE_PARM(force_card, "i");
-MODULE_PARM_DESC(force_card, "<0: TUA6034 -- 1:AVDVBT771 -- 2: TDTC9251DH01C>");
diff --git a/linux/drivers/media/dvb/frontends/mt352.h b/linux/drivers/media/dvb/frontends/mt352.h
index 4a41ee6e0..81f896447 100644
--- a/linux/drivers/media/dvb/frontends/mt352.h
+++ b/linux/drivers/media/dvb/frontends/mt352.h
@@ -32,8 +32,8 @@
#define I2C_TUNER_ADDR 0xc2
#define ID_MT352 0x13
-#define CARD_TUA6034 0x00
-#define CARD_AVDVBT771 0x01
+#define CARD_AVDVBT771 0x00
+#define CARD_TUA6034 0x01
#define CARD_TDTC9251DH01C 0x02
#define msb(x) (((x) >> 8) & 0xff)
@@ -153,7 +153,7 @@ struct _tuner_info {
int read_reg_flag;
#define READ_REG_FLAG tuner_info[card_type].read_reg_flag
- int (* mt352_init) (struct dvb_i2c_bus *i2c);
+ int (* mt352_init) (struct i2c_adapter *i2c);
#define MT352_INIT tuner_info[card_type].mt352_init
unsigned char (* mt352_charge_pump) (u32 freq);
@@ -163,17 +163,15 @@ struct _tuner_info {
#define MT352_BAND_SELECT tuner_info[card_type].mt352_band_select
};
-static int mt352_init_TUA6034(struct dvb_i2c_bus *i2c);
-static int mt352_init_AVERMEDIA771(struct dvb_i2c_bus *i2c);
-static int mt352_init_TDTC9251DH01C(struct dvb_i2c_bus *i2c);
+static int mt352_init_TUA6034(struct i2c_adapter *i2c);
+static int mt352_init_AVERMEDIA771(struct i2c_adapter *i2c);
+static int mt352_init_TDTC9251DH01C(struct i2c_adapter *i2c);
static unsigned char mt352_cp_TUA6034(u32 freq);
static unsigned char mt352_cp_AVERMEDIA771(u32 freq);
static unsigned char mt352_cp_TDTC9251DH01C(u32 freq);
static unsigned char mt352_bs_TUA6034(u32 freq);
static unsigned char mt352_bs_AVERMEDIA771(u32 freq);
static unsigned char mt352_bs_TDTC9251DH01C(u32 freq);
-static int mt352_detect_avermedia_771(struct dvb_i2c_bus *i2c);
-static int mt352_detect_tdtc9251dh01c(struct dvb_i2c_bus *i2c);
-static int mt352_detect_tua6034(struct dvb_i2c_bus *i2c);
+static int mt352_detect_avermedia_771(struct i2c_adapter *i2c);
#endif /* _MT352_ */