Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * linux/drivers/video/nvidia/nvidia-i2c.c - nVidia i2c
0003  *
0004  * Copyright 2004 Antonino A. Daplas <adaplas @pol.net>
0005  *
0006  * Based on rivafb-i2c.c
0007  *
0008  * This file is subject to the terms and conditions of the GNU General Public
0009  * License.  See the file COPYING in the main directory of this archive
0010  * for more details.
0011  */
0012 
0013 #include <linux/module.h>
0014 #include <linux/kernel.h>
0015 #include <linux/delay.h>
0016 #include <linux/gfp.h>
0017 #include <linux/pci.h>
0018 #include <linux/fb.h>
0019 
0020 #include <asm/io.h>
0021 
0022 #include "nv_type.h"
0023 #include "nv_local.h"
0024 #include "nv_proto.h"
0025 
0026 #include "../edid.h"
0027 
0028 static void nvidia_gpio_setscl(void *data, int state)
0029 {
0030     struct nvidia_i2c_chan *chan = data;
0031     struct nvidia_par *par = chan->par;
0032     u32 val;
0033 
0034     val = NVReadCrtc(par, chan->ddc_base + 1) & 0xf0;
0035 
0036     if (state)
0037         val |= 0x20;
0038     else
0039         val &= ~0x20;
0040 
0041     NVWriteCrtc(par, chan->ddc_base + 1, val | 0x01);
0042 }
0043 
0044 static void nvidia_gpio_setsda(void *data, int state)
0045 {
0046     struct nvidia_i2c_chan *chan = data;
0047     struct nvidia_par *par = chan->par;
0048     u32 val;
0049 
0050     val = NVReadCrtc(par, chan->ddc_base + 1) & 0xf0;
0051 
0052     if (state)
0053         val |= 0x10;
0054     else
0055         val &= ~0x10;
0056 
0057     NVWriteCrtc(par, chan->ddc_base + 1, val | 0x01);
0058 }
0059 
0060 static int nvidia_gpio_getscl(void *data)
0061 {
0062     struct nvidia_i2c_chan *chan = data;
0063     struct nvidia_par *par = chan->par;
0064     u32 val = 0;
0065 
0066     if (NVReadCrtc(par, chan->ddc_base) & 0x04)
0067         val = 1;
0068 
0069     return val;
0070 }
0071 
0072 static int nvidia_gpio_getsda(void *data)
0073 {
0074     struct nvidia_i2c_chan *chan = data;
0075     struct nvidia_par *par = chan->par;
0076     u32 val = 0;
0077 
0078     if (NVReadCrtc(par, chan->ddc_base) & 0x08)
0079         val = 1;
0080 
0081     return val;
0082 }
0083 
0084 static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name,
0085                 unsigned int i2c_class)
0086 {
0087     int rc;
0088 
0089     strscpy(chan->adapter.name, name, sizeof(chan->adapter.name));
0090     chan->adapter.owner = THIS_MODULE;
0091     chan->adapter.class = i2c_class;
0092     chan->adapter.algo_data = &chan->algo;
0093     chan->adapter.dev.parent = &chan->par->pci_dev->dev;
0094     chan->algo.setsda = nvidia_gpio_setsda;
0095     chan->algo.setscl = nvidia_gpio_setscl;
0096     chan->algo.getsda = nvidia_gpio_getsda;
0097     chan->algo.getscl = nvidia_gpio_getscl;
0098     chan->algo.udelay = 40;
0099     chan->algo.timeout = msecs_to_jiffies(2);
0100     chan->algo.data = chan;
0101 
0102     i2c_set_adapdata(&chan->adapter, chan);
0103 
0104     /* Raise SCL and SDA */
0105     nvidia_gpio_setsda(chan, 1);
0106     nvidia_gpio_setscl(chan, 1);
0107     udelay(20);
0108 
0109     rc = i2c_bit_add_bus(&chan->adapter);
0110     if (rc == 0)
0111         dev_dbg(&chan->par->pci_dev->dev,
0112             "I2C bus %s registered.\n", name);
0113     else {
0114         dev_warn(&chan->par->pci_dev->dev,
0115              "Failed to register I2C bus %s.\n", name);
0116         chan->par = NULL;
0117     }
0118 
0119     return rc;
0120 }
0121 
0122 void nvidia_create_i2c_busses(struct nvidia_par *par)
0123 {
0124     par->chan[0].par = par;
0125     par->chan[1].par = par;
0126     par->chan[2].par = par;
0127 
0128     par->chan[0].ddc_base = (par->reverse_i2c) ? 0x36 : 0x3e;
0129     nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0",
0130                  (par->reverse_i2c) ? I2C_CLASS_HWMON : 0);
0131 
0132     par->chan[1].ddc_base = (par->reverse_i2c) ? 0x3e : 0x36;
0133     nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1",
0134                  (par->reverse_i2c) ? 0 : I2C_CLASS_HWMON);
0135 
0136     par->chan[2].ddc_base = 0x50;
0137     nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2", 0);
0138 }
0139 
0140 void nvidia_delete_i2c_busses(struct nvidia_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 nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
0153 {
0154     struct nvidia_par *par = info->par;
0155     u8 *edid = NULL;
0156 
0157     if (par->chan[conn - 1].par)
0158         edid = fb_ddc_read(&par->chan[conn - 1].adapter);
0159 
0160     if (!edid && conn == 1) {
0161         /* try to get from firmware */
0162         const u8 *e = fb_firmware_edid(info->device);
0163 
0164         if (e != NULL)
0165             edid = kmemdup(e, EDID_LENGTH, GFP_KERNEL);
0166     }
0167 
0168     *out_edid = edid;
0169 
0170     return (edid) ? 0 : 1;
0171 }