1#include "radeonfb.h" 2 3#include <linux/module.h> 4#include <linux/kernel.h> 5#include <linux/delay.h> 6#include <linux/fb.h> 7 8 9#include <linux/i2c.h> 10#include <linux/i2c-algo-bit.h> 11 12#include <asm/io.h> 13 14#include <video/radeon.h> 15#include "../edid.h" 16 17static void radeon_gpio_setscl(void* data, int state) 18{ 19 struct radeon_i2c_chan *chan = data; 20 struct radeonfb_info *rinfo = chan->rinfo; 21 u32 val; 22 23 val = INREG(chan->ddc_reg) & ~(VGA_DDC_CLK_OUT_EN); 24 if (!state) 25 val |= VGA_DDC_CLK_OUT_EN; 26 27 OUTREG(chan->ddc_reg, val); 28 (void)INREG(chan->ddc_reg); 29} 30 31static void radeon_gpio_setsda(void* data, int state) 32{ 33 struct radeon_i2c_chan *chan = data; 34 struct radeonfb_info *rinfo = chan->rinfo; 35 u32 val; 36 37 val = INREG(chan->ddc_reg) & ~(VGA_DDC_DATA_OUT_EN); 38 if (!state) 39 val |= VGA_DDC_DATA_OUT_EN; 40 41 OUTREG(chan->ddc_reg, val); 42 (void)INREG(chan->ddc_reg); 43} 44 45static int radeon_gpio_getscl(void* data) 46{ 47 struct radeon_i2c_chan *chan = data; 48 struct radeonfb_info *rinfo = chan->rinfo; 49 u32 val; 50 51 val = INREG(chan->ddc_reg); 52 53 return (val & VGA_DDC_CLK_INPUT) ? 1 : 0; 54} 55 56static int radeon_gpio_getsda(void* data) 57{ 58 struct radeon_i2c_chan *chan = data; 59 struct radeonfb_info *rinfo = chan->rinfo; 60 u32 val; 61 62 val = INREG(chan->ddc_reg); 63 64 return (val & VGA_DDC_DATA_INPUT) ? 1 : 0; 65} 66 67static int radeon_setup_i2c_bus(struct radeon_i2c_chan *chan, const char *name) 68{ 69 int rc; 70 71 snprintf(chan->adapter.name, sizeof(chan->adapter.name), 72 "radeonfb %s", name); 73 chan->adapter.owner = THIS_MODULE; 74 chan->adapter.algo_data = &chan->algo; 75 chan->adapter.dev.parent = &chan->rinfo->pdev->dev; 76 chan->algo.setsda = radeon_gpio_setsda; 77 chan->algo.setscl = radeon_gpio_setscl; 78 chan->algo.getsda = radeon_gpio_getsda; 79 chan->algo.getscl = radeon_gpio_getscl; 80 chan->algo.udelay = 10; 81 chan->algo.timeout = 20; 82 chan->algo.data = chan; 83 84 i2c_set_adapdata(&chan->adapter, chan); 85 86 /* Raise SCL and SDA */ 87 radeon_gpio_setsda(chan, 1); 88 radeon_gpio_setscl(chan, 1); 89 udelay(20); 90 91 rc = i2c_bit_add_bus(&chan->adapter); 92 if (rc == 0) 93 dev_dbg(&chan->rinfo->pdev->dev, "I2C bus %s registered.\n", name); 94 else 95 dev_warn(&chan->rinfo->pdev->dev, "Failed to register I2C bus %s.\n", name); 96 return rc; 97} 98 99void radeon_create_i2c_busses(struct radeonfb_info *rinfo) 100{ 101 rinfo->i2c[0].rinfo = rinfo; 102 rinfo->i2c[0].ddc_reg = GPIO_MONID; 103#ifndef CONFIG_PPC 104 rinfo->i2c[0].adapter.class = I2C_CLASS_HWMON; 105#endif 106 radeon_setup_i2c_bus(&rinfo->i2c[0], "monid"); 107 108 rinfo->i2c[1].rinfo = rinfo; 109 rinfo->i2c[1].ddc_reg = GPIO_DVI_DDC; 110 radeon_setup_i2c_bus(&rinfo->i2c[1], "dvi"); 111 112 rinfo->i2c[2].rinfo = rinfo; 113 rinfo->i2c[2].ddc_reg = GPIO_VGA_DDC; 114 radeon_setup_i2c_bus(&rinfo->i2c[2], "vga"); 115 116 rinfo->i2c[3].rinfo = rinfo; 117 rinfo->i2c[3].ddc_reg = GPIO_CRT2_DDC; 118 radeon_setup_i2c_bus(&rinfo->i2c[3], "crt2"); 119} 120 121void radeon_delete_i2c_busses(struct radeonfb_info *rinfo) 122{ 123 if (rinfo->i2c[0].rinfo) 124 i2c_del_adapter(&rinfo->i2c[0].adapter); 125 rinfo->i2c[0].rinfo = NULL; 126 127 if (rinfo->i2c[1].rinfo) 128 i2c_del_adapter(&rinfo->i2c[1].adapter); 129 rinfo->i2c[1].rinfo = NULL; 130 131 if (rinfo->i2c[2].rinfo) 132 i2c_del_adapter(&rinfo->i2c[2].adapter); 133 rinfo->i2c[2].rinfo = NULL; 134 135 if (rinfo->i2c[3].rinfo) 136 i2c_del_adapter(&rinfo->i2c[3].adapter); 137 rinfo->i2c[3].rinfo = NULL; 138} 139 140int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, 141 u8 **out_edid) 142{ 143 u8 *edid; 144 145 edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); 146 147 if (out_edid) 148 *out_edid = edid; 149 if (!edid) { 150 pr_debug("radeonfb: I2C (port %d) ... not found\n", conn); 151 return MT_NONE; 152 } 153 if (edid[0x14] & 0x80) { 154 /* Fix detection using BIOS tables */ 155 if (rinfo->is_mobility /*&& conn == ddc_dvi*/ && 156 (INREG(LVDS_GEN_CNTL) & LVDS_ON)) { 157 pr_debug("radeonfb: I2C (port %d) ... found LVDS panel\n", conn); 158 return MT_LCD; 159 } else { 160 pr_debug("radeonfb: I2C (port %d) ... found TMDS panel\n", conn); 161 return MT_DFP; 162 } 163 } 164 pr_debug("radeonfb: I2C (port %d) ... found CRT display\n", conn); 165 return MT_CRT; 166} 167 168