Mailing List archive

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

[linux-dvb] [PATCH 1/4] Frontend i2c conversion - cx24110



Frontend conversion to kernel i2c, please check.

Kenneth

 cx24110.c |  158 ++++++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 120 insertions(+), 38 deletions(-)
Index: cx24110.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/cx24110.c,v
retrieving revision 1.14
diff -u -r1.14 cx24110.c
--- cx24110.c	8 Apr 2004 15:10:52 -0000	1.14
+++ cx24110.c	12 Jul 2004 17:08:27 -0000
@@ -40,10 +40,9 @@
 #include "dvb_frontend.h"
 #include "dvb_functions.h"
 
-static int debug = 0;
+static int debug;
 #define dprintk	if (debug) printk
 
-
 static struct dvb_frontend_info cx24110_info = {
 	.name = "Conexant CX24110 with CX24108 tuner, aka HM1221/HM1811",
 	.type = FE_QPSK,
@@ -63,6 +62,10 @@
 };
 /* fixme: are these values correct? especially ..._tolerance and caps */
 
+struct cx24110_state {
+	struct i2c_adapter *i2c;
+	struct dvb_adapter *dvb;
+};
 
 static struct {u8 reg; u8 data;} cx24110_regdata[]=
                       /* Comments beginning with @ denote this value should
@@ -127,7 +130,7 @@
 	};
 
 
-static int cx24110_writereg (struct dvb_i2c_bus *i2c, int reg, int data)
+static int cx24110_writereg (struct i2c_adapter *i2c, int reg, int data)
 {
         u8 buf [] = { reg, data };
 	struct i2c_msg msg = { .addr = 0x55, .flags = 0, .buf = buf, .len = 2 };
@@ -135,7 +138,7 @@
    cx24110 might show up at any address */
 	int err;
 
-        if ((err = i2c->xfer (i2c, &msg, 1)) != 1) {
+        if ((err = i2c_transfer(i2c, &msg, 1)) != 1) {
 		dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
 		return -EREMOTEIO;
 	}
@@ -144,7 +147,7 @@
 }
 
 
-static u8 cx24110_readreg (struct dvb_i2c_bus *i2c, u8 reg)
+static u8 cx24110_readreg (struct i2c_adapter *i2c, u8 reg)
 {
 	int ret;
 	u8 b0 [] = { reg };
@@ -152,7 +155,7 @@
 	struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 },
 			   { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 /* fixme (medium): address might be different from 0x55 */
-	ret = i2c->xfer (i2c, msg, 2);
+	ret = i2c_transfer(i2c, msg, 2);
 
 	if (ret != 2)
 		dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
@@ -161,7 +164,7 @@
 }
 
 
-static int cx24108_write (struct dvb_i2c_bus *i2c, u32 data)
+static int cx24108_write (struct i2c_adapter *i2c, u32 data)
 {
 /* tuner data is 21 bits long, must be left-aligned in data */
 /* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
@@ -195,7 +198,7 @@
 }
 
 
-static int cx24108_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq)
+static int cx24108_set_tv_freq (struct i2c_adapter *i2c, u32 freq)
 {
 /* fixme (low): error handling */
         int i, a, n, pump;
@@ -259,9 +262,9 @@
 }
 
 
-static int cx24110_init (struct dvb_i2c_bus *i2c)
+static int cx24110_initfe(struct i2c_adapter *i2c)
 {
-/* fixme (low): error handling */
+	/* FIXME (low): error handling */
         int i;
 
 	dprintk("%s: init chip\n", __FUNCTION__);
@@ -274,7 +277,7 @@
 }
 
 
-static int cx24110_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion)
+static int cx24110_set_inversion (struct i2c_adapter *i2c, fe_spectral_inversion_t inversion)
 {
 /* fixme (low): error handling */
 
@@ -309,7 +312,7 @@
 }
 
 
-static int cx24110_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec)
+static int cx24110_set_fec (struct i2c_adapter *i2c, fe_code_rate_t fec)
 {
 /* fixme (low): error handling */
 
@@ -355,7 +358,7 @@
 }
 
 
-static fe_code_rate_t cx24110_get_fec (struct dvb_i2c_bus *i2c)
+static fe_code_rate_t cx24110_get_fec (struct i2c_adapter *i2c)
 {
 	int i;
 
@@ -372,7 +375,7 @@
 }
 
 
-static int cx24110_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate)
+static int cx24110_set_symbolrate (struct i2c_adapter *i2c, u32 srate)
 {
 /* fixme (low): add error handling */
         u32 ratio;
@@ -454,7 +457,7 @@
 }
 
 
-static int cx24110_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage)
+static int cx24110_set_voltage (struct i2c_adapter *i2c, fe_sec_voltage_t voltage)
 {
 	switch (voltage) {
 	case SEC_VOLTAGE_13:
@@ -466,16 +469,17 @@
 	};
 }
 
-static void sendDiSEqCMessage(struct dvb_i2c_bus *i2c, struct dvb_diseqc_master_cmd *pCmd)
+static void cx24110_send_diseqc_msg(struct i2c_adapter *i2c,
+				    struct dvb_diseqc_master_cmd *cmd)
 {
 	int i, rv;
 
-	for (i = 0; i < pCmd->msg_len; i++)
-		cx24110_writereg(i2c, 0x79 + i, pCmd->msg[i]);
+	for (i = 0; i < cmd->msg_len; i++)
+		cx24110_writereg(i2c, 0x79 + i, cmd->msg[i]);
 
 	rv = cx24110_readreg(i2c, 0x76);
 
-	cx24110_writereg(i2c, 0x76, ((rv & 0x90) | 0x40) | ((pCmd->msg_len-3) & 3));
+	cx24110_writereg(i2c, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
 	for (i=500; i-- > 0 && !(cx24110_readreg(i2c,0x76)&0x40);)
 		; /* wait for LNB ready */
 }
@@ -483,7 +487,8 @@
 
 static int cx24110_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
 {
-	struct dvb_i2c_bus *i2c = fe->i2c;
+	struct cx24110_state *state = fe->data;
+	struct i2c_adapter *i2c = state->i2c;
 	static int lastber=0, lastbyer=0,lastbler=0, lastesn0=0, sum_bler=0;
 
         switch (cmd) {
@@ -615,10 +620,12 @@
 	}
 
         case FE_SLEEP:
-/* cannot do this from the FE end. How to communicate this to the place where it can be done? */
+		/* cannot do this from the FE end.
+		 * How to communicate this to the place where it can be done?
+		 */
 		break;
         case FE_INIT:
-		return cx24110_init (i2c);
+		return cx24110_initfe(i2c);
 
 	case FE_SET_TONE:
 		return cx24110_writereg(i2c,0x76,(cx24110_readreg(i2c,0x76)&~0x10)|((((fe_sec_tone_mode_t) arg)==SEC_TONE_ON)?0x10:0));
@@ -626,7 +633,8 @@
 		return cx24110_set_voltage (i2c, (fe_sec_voltage_t) arg);
 
 	case FE_DISEQC_SEND_MASTER_CMD:
-		sendDiSEqCMessage(i2c, (struct dvb_diseqc_master_cmd*) arg);
+		// FIXME Status?
+		cx24110_send_diseqc_msg(i2c, (struct dvb_diseqc_master_cmd*) arg);
 		return 0;
 
 	default:
@@ -636,43 +644,117 @@
         return 0;
 }
 
+static struct i2c_client client_template;
 
-static int cx24110_attach (struct dvb_i2c_bus *i2c, void **data)
+static int attach_adapter (struct i2c_adapter *adapter)
 {
+	struct cx24110_state *state;
+	struct i2c_client *client;
+	int ret = 0;
 	u8 sig;
 
-	sig=cx24110_readreg (i2c, 0x00);
+	sig = cx24110_readreg (adapter, 0x00);
 	if ( sig != 0x5a && sig != 0x69 )
 		return -ENODEV;
 
-	return dvb_register_frontend (cx24110_ioctl, i2c, NULL, &cx24110_info);
-}
+	if (!(state = kmalloc(sizeof(struct cx24110_state), GFP_KERNEL)))
+		return -ENOMEM;
 
+	memset(state, 0, sizeof(struct cx24110_state));
+	state->i2c = adapter;
 
-static void cx24110_detach (struct dvb_i2c_bus *i2c, void *data)
-{
-	dvb_unregister_frontend (cx24110_ioctl, i2c);
+	if (!(client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)))
+		return -ENOMEM;
+
+	memcpy(client, &client_template, sizeof(struct i2c_client));
+	client->adapter = adapter;
+	client->addr = 0x55;
+	i2c_set_clientdata(client, state);
+
+	ret = i2c_attach_client(client);
+	if (ret) {
+		kfree(client);
+		kfree(state);
+		return ret;
+	}
+
+	BUG_ON(!state->dvb);
+
+	ret = dvb_register_frontend_new(cx24110_ioctl, state->dvb, state,
+					&cx24110_info, THIS_MODULE);
+	if (ret) {
+		i2c_detach_client(client);
+		kfree(client);
+		kfree(state);
+		return ret;
+	}
+
+	return 0;
 }
 
+static int detach_client (struct i2c_client *client)
+{
+	struct cx24110_state *state = i2c_get_clientdata(client);
+
+	dvb_unregister_frontend_new(cx24110_ioctl, state->dvb);
+	i2c_detach_client(client);
+	BUG_ON(state->dvb);
+	kfree(client);
+	kfree(state);
 
-static int __init init_cx24110 (void)
+	return 0;
+}
+
+static int command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
-	return dvb_register_i2c_device (THIS_MODULE, cx24110_attach, cx24110_detach);
+	struct cx24110_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		= "dvbfe_cx24110",
+	.id		= I2C_DRIVERID_DVBFE_CX24110,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= attach_adapter,
+	.detach_client	= detach_client,
+	.command	= command,
+};
+
+static struct i2c_client client_template = {
+	I2C_DEVNAME("dvbfe_cx24110"),
+	.flags		= I2C_CLIENT_ALLOW_USE,
+	.driver		= &driver,
+};
 
-static void __exit exit_cx24110 (void)
+static int __init cx24110_init(void)
 {
-	dvb_unregister_i2c_device (cx24110_attach);
+	return i2c_add_driver(&driver);
 }
 
+static void __exit cx24110_exit(void)
+{
+	if (i2c_del_driver(&driver))
+		printk(KERN_ERR "cx24110: driver deregistration failed.\n");
+}
 
-module_init(init_cx24110);
-module_exit(exit_cx24110);
-
+module_init(cx24110_init);
+module_exit(cx24110_exit);
+module_param(debug, int, 0);
 
 MODULE_DESCRIPTION("DVB Frontend driver module for the Conexant cx24108/cx24110 chipset");
 MODULE_AUTHOR("Peter Hettkamp");
 MODULE_LICENSE("GPL");
-MODULE_PARM(debug,"i");
 

Home | Main Index | Thread Index