Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / video / savage / savagefb-i2c.c
index 024a0ce..21debed 100644 (file)
@@ -49,7 +49,7 @@
 
 static void savage4_gpio_setscl(void *data, int val)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
        unsigned int r;
 
        r = readl(chan->ioaddr + chan->reg);
@@ -63,7 +63,7 @@ static void savage4_gpio_setscl(void *data, int val)
 
 static void savage4_gpio_setsda(void *data, int val)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
 
        unsigned int r;
        r = readl(chan->ioaddr + chan->reg);
@@ -77,21 +77,21 @@ static void savage4_gpio_setsda(void *data, int val)
 
 static int savage4_gpio_getscl(void *data)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
 
        return (0 != (readl(chan->ioaddr + chan->reg) & SAVAGE4_I2C_SCL_IN));
 }
 
 static int savage4_gpio_getsda(void *data)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
 
        return (0 != (readl(chan->ioaddr + chan->reg) & SAVAGE4_I2C_SDA_IN));
 }
 
 static void prosavage_gpio_setscl(void* data, int val)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
        u32                       r;
 
        SET_CR_IX(chan->ioaddr, chan->reg);
@@ -107,7 +107,7 @@ static void prosavage_gpio_setscl(void* data, int val)
 
 static void prosavage_gpio_setsda(void* data, int val)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
        unsigned int r;
 
        SET_CR_IX(chan->ioaddr, chan->reg);
@@ -123,7 +123,7 @@ static void prosavage_gpio_setsda(void* data, int val)
 
 static int prosavage_gpio_getscl(void* data)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
 
        SET_CR_IX(chan->ioaddr, chan->reg);
        return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SCL_IN));
@@ -131,23 +131,21 @@ static int prosavage_gpio_getscl(void* data)
 
 static int prosavage_gpio_getsda(void* data)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
 
        SET_CR_IX(chan->ioaddr, chan->reg);
        return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SDA_IN));
 }
 
-#define I2C_ALGO_SAVAGE   0x0f0000
 static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
                                const char *name)
 {
-       int (*add_bus)(struct i2c_adapter *) = symbol_get(i2c_bit_add_bus);
        int rc = 0;
 
-       if (add_bus && chan->par) {
+       if (chan->par) {
                strcpy(chan->adapter.name, name);
                chan->adapter.owner             = THIS_MODULE;
-               chan->adapter.id                = I2C_ALGO_SAVAGE;
+               chan->adapter.id                = I2C_HW_B_SAVAGE;
                chan->adapter.algo_data         = &chan->algo;
                chan->adapter.dev.parent        = &chan->par->pcidev->dev;
                chan->algo.udelay               = 40;
@@ -162,7 +160,7 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
                chan->algo.setscl(chan, 1);
                udelay(20);
 
-               rc = add_bus(&chan->adapter);
+               rc = i2c_bit_add_bus(&chan->adapter);
 
                if (rc == 0)
                        dev_dbg(&chan->par->pcidev->dev,
@@ -170,8 +168,6 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
                else
                        dev_warn(&chan->par->pcidev->dev,
                                 "Failed to register I2C bus %s.\n", name);
-
-               symbol_put(i2c_bit_add_bus);
        } else
                chan->par = NULL;
 
@@ -180,7 +176,7 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
 
 void savagefb_create_i2c_busses(struct fb_info *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
        par->chan.par   = par;
 
        switch(info->fix.accel) {
@@ -194,6 +190,7 @@ void savagefb_create_i2c_busses(struct fb_info *info)
                par->chan.algo.getscl = prosavage_gpio_getscl;
                break;
        case FB_ACCEL_SAVAGE4:
+       case FB_ACCEL_SAVAGE2000:
                par->chan.reg         = 0xff20;
                par->chan.ioaddr      = par->mmio.vbase;
                par->chan.algo.setsda = savage4_gpio_setsda;
@@ -210,14 +207,10 @@ void savagefb_create_i2c_busses(struct fb_info *info)
 
 void savagefb_delete_i2c_busses(struct fb_info *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
-       int (*del_bus)(struct i2c_adapter *) =
-               symbol_get(i2c_bit_del_bus);
+       struct savagefb_par *par = info->par;
 
-       if (del_bus && par->chan.par) {
-               del_bus(&par->chan.adapter);
-               symbol_put(i2c_bit_del_bus);
-       }
+       if (par->chan.par)
+               i2c_bit_del_bus(&par->chan.adapter);
 
        par->chan.par = NULL;
 }
@@ -225,8 +218,6 @@ void savagefb_delete_i2c_busses(struct fb_info *info)
 static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan)
 {
        u8 start = 0x0;
-       int (*transfer)(struct i2c_adapter *, struct i2c_msg *, int) =
-               symbol_get(i2c_transfer);
        struct i2c_msg msgs[] = {
                {
                        .addr   = SAVAGE_DDC,
@@ -240,28 +231,27 @@ static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan)
        };
        u8 *buf = NULL;
 
-       if (transfer && chan->par) {
+       if (chan->par) {
                buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
 
                if (buf) {
                        msgs[1].buf = buf;
 
-                       if (transfer(&chan->adapter, msgs, 2) != 2) {
+                       if (i2c_transfer(&chan->adapter, msgs, 2) != 2) {
                                dev_dbg(&chan->par->pcidev->dev,
                                        "Unable to read EDID block.\n");
                                kfree(buf);
                                buf = NULL;
                        }
                }
-
-               symbol_put(i2c_transfer);
        }
 
        return buf;
 }
 
-int savagefb_probe_i2c_connector(struct savagefb_par *par, u8 **out_edid)
+int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid)
 {
+       struct savagefb_par *par = info->par;
        u8 *edid = NULL;
        int i;
 
@@ -271,12 +261,21 @@ int savagefb_probe_i2c_connector(struct savagefb_par *par, u8 **out_edid)
                if (edid)
                        break;
        }
-       if (out_edid)
-               *out_edid = edid;
-       if (!edid)
-               return 1;
 
-       return 0;
+       if (!edid) {
+               /* try to get from firmware */
+               const u8 *e = fb_firmware_edid(info->device);
+
+               if (e) {
+                       edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+                       if (edid)
+                               memcpy(edid, e, EDID_LENGTH);
+               }
+       }
+
+       *out_edid = edid;
+
+       return (edid) ? 0 : 1;
 }
 
 MODULE_LICENSE("GPL");