rivafb-i2c.c (3689B)
1/* 2 * linux/drivers/video/riva/fbdev-i2c.c - nVidia i2c 3 * 4 * Maintained by Ani Joshi <ajoshi@shell.unixbox.com> 5 * 6 * Copyright 2004 Antonino A. Daplas <adaplas @pol.net> 7 * 8 * Based on radeonfb-i2c.c 9 * 10 * This file is subject to the terms and conditions of the GNU General Public 11 * License. See the file COPYING in the main directory of this archive 12 * for more details. 13 */ 14 15#include <linux/module.h> 16#include <linux/kernel.h> 17#include <linux/delay.h> 18#include <linux/pci.h> 19#include <linux/fb.h> 20#include <linux/jiffies.h> 21 22#include <asm/io.h> 23 24#include "rivafb.h" 25#include "../edid.h" 26 27static void riva_gpio_setscl(void* data, int state) 28{ 29 struct riva_i2c_chan *chan = data; 30 struct riva_par *par = chan->par; 31 u32 val; 32 33 VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1); 34 val = VGA_RD08(par->riva.PCIO, 0x3d5) & 0xf0; 35 36 if (state) 37 val |= 0x20; 38 else 39 val &= ~0x20; 40 41 VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1); 42 VGA_WR08(par->riva.PCIO, 0x3d5, val | 0x1); 43} 44 45static void riva_gpio_setsda(void* data, int state) 46{ 47 struct riva_i2c_chan *chan = data; 48 struct riva_par *par = chan->par; 49 u32 val; 50 51 VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1); 52 val = VGA_RD08(par->riva.PCIO, 0x3d5) & 0xf0; 53 54 if (state) 55 val |= 0x10; 56 else 57 val &= ~0x10; 58 59 VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1); 60 VGA_WR08(par->riva.PCIO, 0x3d5, val | 0x1); 61} 62 63static int riva_gpio_getscl(void* data) 64{ 65 struct riva_i2c_chan *chan = data; 66 struct riva_par *par = chan->par; 67 u32 val = 0; 68 69 VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base); 70 if (VGA_RD08(par->riva.PCIO, 0x3d5) & 0x04) 71 val = 1; 72 73 return val; 74} 75 76static int riva_gpio_getsda(void* data) 77{ 78 struct riva_i2c_chan *chan = data; 79 struct riva_par *par = chan->par; 80 u32 val = 0; 81 82 VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base); 83 if (VGA_RD08(par->riva.PCIO, 0x3d5) & 0x08) 84 val = 1; 85 86 return val; 87} 88 89static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name, 90 unsigned int i2c_class) 91{ 92 int rc; 93 94 strcpy(chan->adapter.name, name); 95 chan->adapter.owner = THIS_MODULE; 96 chan->adapter.class = i2c_class; 97 chan->adapter.algo_data = &chan->algo; 98 chan->adapter.dev.parent = &chan->par->pdev->dev; 99 chan->algo.setsda = riva_gpio_setsda; 100 chan->algo.setscl = riva_gpio_setscl; 101 chan->algo.getsda = riva_gpio_getsda; 102 chan->algo.getscl = riva_gpio_getscl; 103 chan->algo.udelay = 40; 104 chan->algo.timeout = msecs_to_jiffies(2); 105 chan->algo.data = chan; 106 107 i2c_set_adapdata(&chan->adapter, chan); 108 109 /* Raise SCL and SDA */ 110 riva_gpio_setsda(chan, 1); 111 riva_gpio_setscl(chan, 1); 112 udelay(20); 113 114 rc = i2c_bit_add_bus(&chan->adapter); 115 if (rc == 0) 116 dev_dbg(&chan->par->pdev->dev, "I2C bus %s registered.\n", name); 117 else { 118 dev_warn(&chan->par->pdev->dev, 119 "Failed to register I2C bus %s.\n", name); 120 chan->par = NULL; 121 } 122 123 return rc; 124} 125 126void riva_create_i2c_busses(struct riva_par *par) 127{ 128 par->chan[0].par = par; 129 par->chan[1].par = par; 130 par->chan[2].par = par; 131 132 par->chan[0].ddc_base = 0x36; 133 par->chan[1].ddc_base = 0x3e; 134 par->chan[2].ddc_base = 0x50; 135 riva_setup_i2c_bus(&par->chan[0], "BUS1", I2C_CLASS_HWMON); 136 riva_setup_i2c_bus(&par->chan[1], "BUS2", 0); 137 riva_setup_i2c_bus(&par->chan[2], "BUS3", 0); 138} 139 140void riva_delete_i2c_busses(struct riva_par *par) 141{ 142 int i; 143 144 for (i = 0; i < 3; i++) { 145 if (!par->chan[i].par) 146 continue; 147 i2c_del_adapter(&par->chan[i].adapter); 148 par->chan[i].par = NULL; 149 } 150} 151 152int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid) 153{ 154 u8 *edid = NULL; 155 156 if (par->chan[conn].par) 157 edid = fb_ddc_read(&par->chan[conn].adapter); 158 159 if (out_edid) 160 *out_edid = edid; 161 if (!edid) 162 return 1; 163 164 return 0; 165} 166