Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] [PATCH 2/4] Frontend i2c conversion - mt312



Frontend conversion to kernel i2c, please check.

Kenneth

 mt312.c |  196 +++++++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 136 insertions(+), 60 deletions(-)
Index: mt312.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/mt312.c,v
retrieving revision 1.14
diff -u -r1.14 mt312.c
--- mt312.c	11 Mar 2004 18:40:44 -0000	1.14
+++ mt312.c	12 Jul 2004 17:08:51 -0000
@@ -42,9 +42,6 @@
 #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
@@ -70,7 +67,13 @@
             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,9 +90,9 @@
 	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;
 	}
@@ -106,7 +109,7 @@
 	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)
 {
@@ -132,29 +135,29 @@
 	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(KERN_ERR "%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 +171,7 @@
 	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 +185,7 @@
 	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 +222,7 @@
 	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 +242,14 @@
 	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 +301,7 @@
 	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 +332,14 @@
 	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 +360,7 @@
 	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 +381,7 @@
 	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 +391,9 @@
 	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 +414,9 @@
 		*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 +429,7 @@
 	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 +442,7 @@
 	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 +462,7 @@
 	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 +475,7 @@
 	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 +488,10 @@
 	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 +500,7 @@
 	    { 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 +524,7 @@
 	    || (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 +533,13 @@
 		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 +581,7 @@
 	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 +596,7 @@
 	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 +643,7 @@
 	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 +660,7 @@
 	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 +677,7 @@
 	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 +698,8 @@
 
 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 +713,7 @@
 		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 +731,7 @@
 		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 +746,7 @@
 		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 +758,14 @@
 		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,42 +783,109 @@
 	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)
+	if ((ret = mt312_readreg(adapter, ID, &id)) < 0)
 		return ret;
 
 	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)))
+		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)) < 0)
+		return ret;
+
+	return 0;
+}
 
-	mt312_count++;
+static int mt312_detach_client(struct i2c_client *client)
+{
+	struct mt312_state *state = i2c_get_clientdata(client);
+
+	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 		= "dvbfe_mt312",
+	.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 = {
+	I2C_DEVNAME("dvbfe_mt312"),
+	.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);

Home | Main Index | Thread Index