Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
[sfrench/cifs-2.6.git] / drivers / media / video / cx88 / cx88-i2c.c
index 9790d412f1927041713c0a23e78f2f83317632ea..27b5dbb2ca1a12d5ddb33a6249987f6f4947ea7a 100644 (file)
@@ -7,6 +7,9 @@
     (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
     (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
 
+    (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
+       - Multituner support and i2c address binding
+
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
@@ -30,6 +33,7 @@
 #include <asm/io.h>
 
 #include "cx88.h"
+#include <media/v4l2-common.h>
 
 static unsigned int i2c_debug = 0;
 module_param(i2c_debug, int, 0644);
@@ -39,6 +43,11 @@ static unsigned int i2c_scan = 0;
 module_param(i2c_scan, int, 0444);
 MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
 
+static unsigned int i2c_udelay = 5;
+module_param(i2c_udelay, int, 0644);
+MODULE_PARM_DESC(i2c_udelay,"i2c delay at insmod time, in usecs "
+               "(should be 5 or higher). Lower value means higher bus speed.");
+
 #define dprintk(level,fmt, arg...)     if (i2c_debug >= level) \
        printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
 
@@ -94,7 +103,7 @@ static int attach_inform(struct i2c_client *client)
        struct cx88_core *core = i2c_get_adapdata(client->adapter);
 
        dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
-               client->driver->name, client->addr, client->name);
+               client->driver->driver.name, client->addr, client->name);
        if (!client->driver->command)
                return 0;
 
@@ -135,7 +144,17 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
 {
        if (0 != core->i2c_rc)
                return;
-       i2c_clients_command(&core->i2c_adap, cmd, arg);
+
+       if (core->dvbdev) {
+               if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
+                       core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
+
+               i2c_clients_command(&core->i2c_adap, cmd, arg);
+
+               if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
+                       core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0);
+       } else
+               i2c_clients_command(&core->i2c_adap, cmd, arg);
 }
 
 static struct i2c_algo_bit_data cx8800_i2c_algo_template = {
@@ -144,7 +163,6 @@ static struct i2c_algo_bit_data cx8800_i2c_algo_template = {
        .getsda  = cx8800_bit_getsda,
        .getscl  = cx8800_bit_getscl,
        .udelay  = 16,
-       .mdelay  = 10,
        .timeout = 200,
 };
 
@@ -188,6 +206,11 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
 /* init + register i2c algo-bit adapter */
 int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
 {
+       /* Prevents usage of invalid delay values */
+       if (i2c_udelay<5)
+               i2c_udelay=5;
+       cx8800_i2c_algo_template.udelay=i2c_udelay;
+
        memcpy(&core->i2c_adap, &cx8800_i2c_adap_template,
               sizeof(core->i2c_adap));
        memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,
@@ -223,7 +246,6 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
 /* ----------------------------------------------------------------------- */
 
 EXPORT_SYMBOL(cx88_call_i2c_clients);
-EXPORT_SYMBOL(cx88_i2c_init);
 
 /*
  * Local variables: