Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * linux/drivers/video/riva/fbdev-i2c.c - nVidia i2c
0003  *
0004  * Maintained by Ani Joshi <ajoshi@shell.unixbox.com>
0005  *
0006  * Copyright 2004 Antonino A. Daplas <adaplas @pol.net>
0007  *
0008  * Based on radeonfb-i2c.c
0009  *
0010  * This file is subject to the terms and conditions of the GNU General Public
0011  * License.  See the file COPYING in the main directory of this archive
0012  * for more details.
0013  */
0014 
0015 #include <linux/module.h>
0016 #include <linux/kernel.h>
0017 #include <linux/delay.h>
0018 #include <linux/pci.h>
0019 #include <linux/fb.h>
0020 #include <linux/jiffies.h>
0021 
0022 #include <asm/io.h>
0023 
0024 #include "rivafb.h"
0025 #include "../edid.h"
0026 
0027 static void riva_gpio_setscl(void* data, int state)
0028 {
0029     struct riva_i2c_chan    *chan = data;
0030     struct riva_par     *par = chan->par;
0031     u32         val;
0032 
0033     VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
0034     val = VGA_RD08(par->riva.PCIO, 0x3d5) & 0xf0;
0035 
0036     if (state)
0037         val |= 0x20;
0038     else
0039         val &= ~0x20;
0040 
0041     VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
0042     VGA_WR08(par->riva.PCIO, 0x3d5, val | 0x1);
0043 }
0044 
0045 static void riva_gpio_setsda(void* data, int state)
0046 {
0047     struct riva_i2c_chan    *chan = data;
0048     struct riva_par     *par = chan->par;
0049     u32         val;
0050 
0051     VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
0052     val = VGA_RD08(par->riva.PCIO, 0x3d5) & 0xf0;
0053 
0054     if (state)
0055         val |= 0x10;
0056     else
0057         val &= ~0x10;
0058 
0059     VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
0060     VGA_WR08(par->riva.PCIO, 0x3d5, val | 0x1);
0061 }
0062 
0063 static int riva_gpio_getscl(void* data)
0064 {
0065     struct riva_i2c_chan    *chan = data;
0066     struct riva_par     *par = chan->par;
0067     u32         val = 0;
0068 
0069     VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base);
0070     if (VGA_RD08(par->riva.PCIO, 0x3d5) & 0x04)
0071         val = 1;
0072 
0073     return val;
0074 }
0075 
0076 static int riva_gpio_getsda(void* data)
0077 {
0078     struct riva_i2c_chan    *chan = data;
0079     struct riva_par     *par = chan->par;
0080     u32         val = 0;
0081 
0082     VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base);
0083     if (VGA_RD08(par->riva.PCIO, 0x3d5) & 0x08)
0084         val = 1;
0085 
0086     return val;
0087 }
0088 
0089 static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name,
0090                   unsigned int i2c_class)
0091 {
0092     int rc;
0093 
0094     strcpy(chan->adapter.name, name);
0095     chan->adapter.owner     = THIS_MODULE;
0096     chan->adapter.class     = i2c_class;
0097     chan->adapter.algo_data     = &chan->algo;
0098     chan->adapter.dev.parent    = &chan->par->pdev->dev;
0099     chan->algo.setsda       = riva_gpio_setsda;
0100     chan->algo.setscl       = riva_gpio_setscl;
0101     chan->algo.getsda       = riva_gpio_getsda;
0102     chan->algo.getscl       = riva_gpio_getscl;
0103     chan->algo.udelay       = 40;
0104     chan->algo.timeout      = msecs_to_jiffies(2);
0105     chan->algo.data         = chan;
0106 
0107     i2c_set_adapdata(&chan->adapter, chan);
0108 
0109     /* Raise SCL and SDA */
0110     riva_gpio_setsda(chan, 1);
0111     riva_gpio_setscl(chan, 1);
0112     udelay(20);
0113 
0114     rc = i2c_bit_add_bus(&chan->adapter);
0115     if (rc == 0)
0116         dev_dbg(&chan->par->pdev->dev, "I2C bus %s registered.\n", name);
0117     else {
0118         dev_warn(&chan->par->pdev->dev,
0119              "Failed to register I2C bus %s.\n", name);
0120         chan->par = NULL;
0121     }
0122 
0123     return rc;
0124 }
0125 
0126 void riva_create_i2c_busses(struct riva_par *par)
0127 {
0128     par->chan[0].par    = par;
0129     par->chan[1].par    = par;
0130     par->chan[2].par        = par;
0131 
0132     par->chan[0].ddc_base = 0x36;
0133     par->chan[1].ddc_base = 0x3e;
0134     par->chan[2].ddc_base = 0x50;
0135     riva_setup_i2c_bus(&par->chan[0], "BUS1", I2C_CLASS_HWMON);
0136     riva_setup_i2c_bus(&par->chan[1], "BUS2", 0);
0137     riva_setup_i2c_bus(&par->chan[2], "BUS3", 0);
0138 }
0139 
0140 void riva_delete_i2c_busses(struct riva_par *par)
0141 {
0142     int i;
0143 
0144     for (i = 0; i < 3; i++) {
0145         if (!par->chan[i].par)
0146             continue;
0147         i2c_del_adapter(&par->chan[i].adapter);
0148         par->chan[i].par = NULL;
0149     }
0150 }
0151 
0152 int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
0153 {
0154     u8 *edid = NULL;
0155 
0156     if (par->chan[conn].par)
0157         edid = fb_ddc_read(&par->chan[conn].adapter);
0158 
0159     if (out_edid)
0160         *out_edid = edid;
0161     if (!edid)
0162         return 1;
0163 
0164     return 0;
0165 }
0166