Mailing List archive

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

[linux-dvb] Re: [PATCHES] Frontend kernel i2c conversion.



Hi Andreas,

On Saturday 17 July 2004 07:43, Andreas Witte wrote:
> Tried the latest cvs-grab and want to give you feedback for your work.
> It seems something is damaged with the mt352 frontend.
>
> Im also using the latest video4linux driver. I hope that the error isnt
> rooted here. With a cvs-grab 2 days ago the mt352 was working perfect.
>
> Below the feedback i got from dmesg while loading the mt352:
>
> ***
> Jul 17 07:37:59 GentooLinux dvbfe_mt352: Trying to attach to adapter
> 0x10005:bt878 #0 [hw].
> Jul 17 07:37:59 GentooLinux dvbfe_mt352: Setup for Avermedia 771.
> Jul 17 07:37:59 GentooLinux ------------[ cut here ]------------
> Jul 17 07:37:59 GentooLinux kernel BUG at
> drivers/media/dvb/frontends/mt352.c:823!
[snip]
> Is that any help for you?

It was expected, as the bt878 driver has not been updated yet. Anyways, I have 
had a look at the bttv driver and there's really no clean way of using the 
FE_REGISTER/FE_UNREGISTER i2c client commands. As I see it, ideally the 
frontends should not have to know about a dvb_adapter at all. I've attached a 
couple of patches for dvb-core, av7110 and stv0299 that implement this 
change. Is this an ok method of solving this problem?

Kenneth
Index: ttpci/av7110.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c,v
retrieving revision 1.132
diff -u -r1.132 av7110.c
--- ttpci/av7110.c	12 Jul 2004 18:15:36 -0000	1.132
+++ ttpci/av7110.c	17 Jul 2004 17:53:20 -0000
@@ -1450,8 +1450,6 @@
 		return ret;
 	}
 
-	dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, THIS_MODULE);
-
 	/* the Siemens DVB needs this if you want to have the i2c chips
 	   get recognized before the main driver is fully loaded */
 	saa7146_write(dev, GPIO_CTRL, 0x500000);
@@ -1465,6 +1463,10 @@
 		.class = I2C_CLASS_TV_DIGITAL,
 #endif
 	};
+
+	dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name,
+			     &av7110->i2c_adap, THIS_MODULE);
+
 	strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
 
 	saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
Index: dvb-core/dvb_frontend.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_frontend.c,v
retrieving revision 1.83
diff -u -r1.83 dvb_frontend.c
--- dvb-core/dvb_frontend.c	16 Jul 2004 19:24:59 -0000	1.83
+++ dvb-core/dvb_frontend.c	17 Jul 2004 17:50:23 -0000
@@ -1064,12 +1064,11 @@
 	.release	= dvb_frontend_release
 };
 
-int
-dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend,
-				     unsigned int cmd, void *arg),
-		       struct dvb_i2c_bus *i2c,
-		       void *data,
-		       struct dvb_frontend_info *info)
+int dvb_register_frontend(int (*ioctl) (struct dvb_frontend *frontend,
+					unsigned int cmd, void *arg),
+			  struct dvb_i2c_bus *i2c,
+			  void *data,
+			  struct dvb_frontend_info *info)
 {
 	struct list_head *entry;
 	struct dvb_frontend_data *fe;
@@ -1183,16 +1182,16 @@
 	return -EINVAL;
 }
 
-int
-dvb_register_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
-				     unsigned int cmd, void *arg),
-		       struct dvb_adapter *dvb_adapter,
-		       void *data,
-		       struct dvb_frontend_info *info,
-		       struct module *module)
+int dvb_register_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
+					     unsigned int cmd, void *arg),
+			       struct i2c_adapter *i2c_adapter,
+			       void *data,
+			       struct dvb_frontend_info *info,
+			       struct module *module)
 {
 	struct list_head *entry;
 	struct dvb_frontend_data *fe;
+	struct dvb_adapter *dvb_adapter;
 	static const struct dvb_device dvbdev_template = {
 		.users = ~0,
 		.writers = 1,
@@ -1206,6 +1205,11 @@
 	if (down_interruptible (&frontend_mutex))
 		return -ERESTARTSYS;
 
+	if (!(dvb_adapter = find_dvb_adapter(i2c_adapter))) {
+		up (&frontend_mutex);
+		return -EFAULT;
+	}
+
 	if (!(fe = kmalloc (sizeof (struct dvb_frontend_data), GFP_KERNEL))) {
 		up (&frontend_mutex);
 		return -ENOMEM;
@@ -1275,12 +1279,17 @@
 
 int dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
 					   unsigned int cmd, void *arg),
-			     struct dvb_adapter *dvb_adapter)
+				 struct i2c_adapter *i2c_adapter)
 {
+	struct dvb_adapter *dvb_adapter;
 	struct list_head *entry, *n;
 
 	dprintk ("%s\n", __FUNCTION__);
 
+	if (!(dvb_adapter = find_dvb_adapter(i2c_adapter))) {
+		return -EFAULT;
+	}
+
 	down (&frontend_mutex);
 
 	list_for_each_safe (entry, n, &frontend_list) {
Index: dvb-core/dvb_frontend.h
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_frontend.h,v
retrieving revision 1.12
diff -u -r1.12 dvb_frontend.h
--- dvb-core/dvb_frontend.h	12 Jul 2004 18:19:36 -0000	1.12
+++ dvb-core/dvb_frontend.h	17 Jul 2004 17:50:26 -0000
@@ -94,16 +94,16 @@
 
 extern int
 dvb_register_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
-				     unsigned int cmd, void *arg),
-		       struct dvb_adapter *dvb_adapter,
-		       void *data,
-		       struct dvb_frontend_info *info,
-		       struct module *module);
+					 unsigned int cmd, void *arg),
+			   struct i2c_adapter *i2c_adapter,
+			   void *data,
+			   struct dvb_frontend_info *info,
+			   struct module *module);
 
 extern int
 dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
-				       unsigned int cmd, void *arg),
-			 struct dvb_adapter *dvb_adapter);
+					   unsigned int cmd, void *arg),
+			     struct i2c_adapter *i2c_adapter);
 
 
 /**
Index: dvb-core/dvbdev.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.c,v
retrieving revision 1.28
diff -u -r1.28 dvbdev.c
--- dvb-core/dvbdev.c	3 May 2004 16:29:27 -0000	1.28
+++ dvb-core/dvbdev.c	17 Jul 2004 17:50:30 -0000
@@ -68,6 +68,19 @@
 	return NULL;
 }
 
+struct dvb_adapter* find_dvb_adapter(struct i2c_adapter *i2c_adapter)
+{
+	struct list_head *entry;
+
+	list_for_each (entry, &dvb_adapter_list) {
+		struct dvb_adapter *adap;
+		adap = list_entry (entry, struct dvb_adapter, list_head);
+		if (adap->i2c_adapter == i2c_adapter)
+			return adap;
+	}
+
+	return NULL;
+}
 
 static int dvb_device_open(struct inode *inode, struct file *file)
 {
@@ -260,7 +273,10 @@
 }
 
 
-int dvb_register_adapter(struct dvb_adapter **padap, const char *name, struct module *module)
+int dvb_register_adapter(struct dvb_adapter **padap,
+			 const char *name,
+			 struct i2c_adapter *i2c_adapter,
+			 struct module *module)
 {
 	struct dvb_adapter *adap;
 	int num;
@@ -287,6 +303,7 @@
 	adap->num = num;
 	adap->name = name;
 	adap->module = module;
+	adap->i2c_adapter = i2c_adapter;
 
 	list_add_tail (&adap->list_head, &dvb_adapter_list);
 
Index: dvb-core/dvbdev.h
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.h,v
retrieving revision 1.20
diff -u -r1.20 dvbdev.h
--- dvb-core/dvbdev.h	3 May 2004 16:29:27 -0000	1.20
+++ dvb-core/dvbdev.h	17 Jul 2004 17:50:31 -0000
@@ -47,6 +47,7 @@
 	struct list_head list_head;
 	struct list_head device_list;
 	const char *name;
+	struct i2c_adapter *i2c_adapter;
 	u8 proposed_mac [6];
 
 	struct module *module;
@@ -74,7 +75,12 @@
 };
 
 
-extern int dvb_register_adapter (struct dvb_adapter **padap, const char *name, struct module *module);
+extern struct dvb_adapter* find_dvb_adapter(struct i2c_adapter *i2c_adapter);
+extern int dvb_register_adapter (struct dvb_adapter **padap,
+				 const char *name,
+				 struct i2c_adapter *adapter,
+				 struct module *module);
+
 extern int dvb_unregister_adapter (struct dvb_adapter *adap);
 
 extern int dvb_register_device (struct dvb_adapter *adap,
Index: frontends/stv0299.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/stv0299.c,v
retrieving revision 1.53
diff -u -r1.53 stv0299.c
--- frontends/stv0299.c	17 Jul 2004 14:51:41 -0000	1.53
+++ frontends/stv0299.c	17 Jul 2004 17:52:57 -0000
@@ -118,7 +118,6 @@
 	u32 symbol_rate;
 	fe_code_rate_t fec_inner;
 	struct i2c_adapter *i2c;
-	struct dvb_adapter *dvb;
 };
 
 
@@ -1398,10 +1397,8 @@
 		kfree(state);
 		return -EFAULT;
 	}
-	
-	BUG_ON(!state->dvb);
 
-	ret = dvb_register_frontend_new(uni0299_ioctl, state->dvb, state,
+	ret = dvb_register_frontend_new(uni0299_ioctl, adapter, state,
 					&uni0299_info, THIS_MODULE);
 	if (ret) {
 		i2c_detach_client(client);
@@ -1417,33 +1414,13 @@
 {
 	struct stv0299_state *state = (struct stv0299_state*)i2c_get_clientdata(client);
 
-	dvb_unregister_frontend_new (uni0299_ioctl, state->dvb);
+	dvb_unregister_frontend_new (uni0299_ioctl, client->adapter);
 	i2c_detach_client(client);
 	kfree(client);
 	kfree(state);
 	return 0;
 }
 
-static int command (struct i2c_client *client, unsigned int cmd, void *arg)
-{
-	struct stv0299_state *data = (struct stv0299_state*)i2c_get_clientdata(client);
-	dprintk ("%s\n", __FUNCTION__);
-
-	switch (cmd) {
-	case FE_REGISTER: {
-		data->dvb = (struct dvb_adapter*)arg;
-		break;
-	}
-	case FE_UNREGISTER: {
-		data->dvb = NULL;
-		break;
-	}
-	default:
-		return -EOPNOTSUPP;
-	}
-	return 0;
-}
-
 static struct i2c_driver driver = {
 	.owner 		= THIS_MODULE,
 	.name 		= FRONTEND_NAME,
@@ -1451,7 +1428,6 @@
 	.flags 		= I2C_DF_NOTIFY,
 	.attach_adapter = attach_adapter,
 	.detach_client 	= detach_client,
-	.command 	= command,
 };
 
 static struct i2c_client client_template = {

Home | Main Index | Thread Index