nv_i2c.c revision 094bb659f53b6d90aab6067268d6d14f1f352d30
1/* 2 * linux/drivers/video/nvidia/nvidia-i2c.c - nVidia i2c 3 * 4 * Copyright 2004 Antonino A. Daplas <adaplas @pol.net> 5 * 6 * Based on rivafb-i2c.c 7 * 8 * This file is subject to the terms and conditions of the GNU General Public 9 * License. See the file COPYING in the main directory of this archive 10 * for more details. 11 */ 12 13#include <linux/config.h> 14#include <linux/module.h> 15#include <linux/kernel.h> 16#include <linux/sched.h> 17#include <linux/delay.h> 18#include <linux/pci.h> 19#include <linux/fb.h> 20 21#include <asm/io.h> 22 23#include "nv_type.h" 24#include "nv_local.h" 25#include "nv_proto.h" 26 27#include "../edid.h" 28 29static void nvidia_gpio_setscl(void *data, int state) 30{ 31 struct nvidia_i2c_chan *chan = data; 32 struct nvidia_par *par = chan->par; 33 u32 val; 34 35 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); 36 val = VGA_RD08(par->PCIO, 0x3d5) & 0xf0; 37 38 if (state) 39 val |= 0x20; 40 else 41 val &= ~0x20; 42 43 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); 44 VGA_WR08(par->PCIO, 0x3d5, val | 0x1); 45} 46 47static void nvidia_gpio_setsda(void *data, int state) 48{ 49 struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; 50 struct nvidia_par *par = chan->par; 51 u32 val; 52 53 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); 54 val = VGA_RD08(par->PCIO, 0x3d5) & 0xf0; 55 56 if (state) 57 val |= 0x10; 58 else 59 val &= ~0x10; 60 61 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); 62 VGA_WR08(par->PCIO, 0x3d5, val | 0x1); 63} 64 65static int nvidia_gpio_getscl(void *data) 66{ 67 struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; 68 struct nvidia_par *par = chan->par; 69 u32 val = 0; 70 71 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base); 72 if (VGA_RD08(par->PCIO, 0x3d5) & 0x04) 73 val = 1; 74 75 val = VGA_RD08(par->PCIO, 0x3d5); 76 77 return val; 78} 79 80static int nvidia_gpio_getsda(void *data) 81{ 82 struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; 83 struct nvidia_par *par = chan->par; 84 u32 val = 0; 85 86 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base); 87 if (VGA_RD08(par->PCIO, 0x3d5) & 0x08) 88 val = 1; 89 90 return val; 91} 92 93static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name) 94{ 95 int rc; 96 97 strcpy(chan->adapter.name, name); 98 chan->adapter.owner = THIS_MODULE; 99 chan->adapter.id = I2C_HW_B_NVIDIA; 100 chan->adapter.algo_data = &chan->algo; 101 chan->adapter.dev.parent = &chan->par->pci_dev->dev; 102 chan->algo.setsda = nvidia_gpio_setsda; 103 chan->algo.setscl = nvidia_gpio_setscl; 104 chan->algo.getsda = nvidia_gpio_getsda; 105 chan->algo.getscl = nvidia_gpio_getscl; 106 chan->algo.udelay = 40; 107 chan->algo.timeout = msecs_to_jiffies(2); 108 chan->algo.data = chan; 109 110 i2c_set_adapdata(&chan->adapter, chan); 111 112 /* Raise SCL and SDA */ 113 nvidia_gpio_setsda(chan, 1); 114 nvidia_gpio_setscl(chan, 1); 115 udelay(20); 116 117 rc = i2c_bit_add_bus(&chan->adapter); 118 if (rc == 0) 119 dev_dbg(&chan->par->pci_dev->dev, 120 "I2C bus %s registered.\n", name); 121 else { 122 dev_warn(&chan->par->pci_dev->dev, 123 "Failed to register I2C bus %s.\n", name); 124 chan->par = NULL; 125 } 126 127 return rc; 128} 129 130void nvidia_create_i2c_busses(struct nvidia_par *par) 131{ 132 par->bus = 3; 133 134 par->chan[0].par = par; 135 par->chan[1].par = par; 136 par->chan[2].par = par; 137 138 par->chan[0].ddc_base = 0x3e; 139 nvidia_setup_i2c_bus(&par->chan[0], "BUS1"); 140 141 par->chan[1].ddc_base = 0x36; 142 nvidia_setup_i2c_bus(&par->chan[1], "BUS2"); 143 144 par->chan[2].ddc_base = 0x50; 145 nvidia_setup_i2c_bus(&par->chan[2], "BUS3"); 146} 147 148void nvidia_delete_i2c_busses(struct nvidia_par *par) 149{ 150 if (par->chan[0].par) 151 i2c_bit_del_bus(&par->chan[0].adapter); 152 par->chan[0].par = NULL; 153 154 if (par->chan[1].par) 155 i2c_bit_del_bus(&par->chan[1].adapter); 156 par->chan[1].par = NULL; 157 158 if (par->chan[2].par) 159 i2c_bit_del_bus(&par->chan[2].adapter); 160 par->chan[2].par = NULL; 161 162} 163 164static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan) 165{ 166 u8 start = 0x0; 167 struct i2c_msg msgs[] = { 168 { 169 .addr = 0x50, 170 .len = 1, 171 .buf = &start, 172 }, { 173 .addr = 0x50, 174 .flags = I2C_M_RD, 175 .len = EDID_LENGTH, 176 }, 177 }; 178 u8 *buf; 179 180 if (!chan->par) 181 return NULL; 182 183 buf = kmalloc(EDID_LENGTH, GFP_KERNEL); 184 if (!buf) { 185 dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n"); 186 return NULL; 187 } 188 msgs[1].buf = buf; 189 190 if (i2c_transfer(&chan->adapter, msgs, 2) == 2) 191 return buf; 192 dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n"); 193 kfree(buf); 194 return NULL; 195} 196 197int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) 198{ 199 struct nvidia_par *par = info->par; 200 u8 *edid = NULL; 201 int i; 202 203 for (i = 0; i < 3; i++) { 204 /* Do the real work */ 205 edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]); 206 if (edid) 207 break; 208 } 209 210 if (!edid && conn == 1) { 211 /* try to get from firmware */ 212 edid = kmalloc(EDID_LENGTH, GFP_KERNEL); 213 if (edid) 214 memcpy(edid, fb_firmware_edid(info->device), 215 EDID_LENGTH); 216 } 217 218 if (out_edid) 219 *out_edid = edid; 220 221 return (edid) ? 0 : 1; 222} 223