Merge master.kernel.org:/pub/scm/linux/kernel/git/chrisw/lsm-2.6
[pandora-kernel.git] / drivers / video / aty / radeon_i2c.c
1 #include <linux/config.h>
2 #include <linux/module.h>
3 #include <linux/kernel.h>
4 #include <linux/sched.h>
5 #include <linux/delay.h>
6 #include <linux/pci.h>
7 #include <linux/fb.h>
8
9
10 #include <linux/i2c.h>
11 #include <linux/i2c-id.h>
12 #include <linux/i2c-algo-bit.h>
13
14 #include <asm/io.h>
15
16 #include <video/radeon.h>
17 #include "radeonfb.h"
18 #include "../edid.h"
19
20 #define RADEON_DDC      0x50
21
22 static void radeon_gpio_setscl(void* data, int state)
23 {
24         struct radeon_i2c_chan  *chan = data;
25         struct radeonfb_info    *rinfo = chan->rinfo;
26         u32                     val;
27         
28         val = INREG(chan->ddc_reg) & ~(VGA_DDC_CLK_OUT_EN);
29         if (!state)
30                 val |= VGA_DDC_CLK_OUT_EN;
31
32         OUTREG(chan->ddc_reg, val);
33         (void)INREG(chan->ddc_reg);
34 }
35
36 static void radeon_gpio_setsda(void* data, int state)
37 {
38         struct radeon_i2c_chan  *chan = data;
39         struct radeonfb_info    *rinfo = chan->rinfo;
40         u32                     val;
41         
42         val = INREG(chan->ddc_reg) & ~(VGA_DDC_DATA_OUT_EN);
43         if (!state)
44                 val |= VGA_DDC_DATA_OUT_EN;
45
46         OUTREG(chan->ddc_reg, val);
47         (void)INREG(chan->ddc_reg);
48 }
49
50 static int radeon_gpio_getscl(void* data)
51 {
52         struct radeon_i2c_chan  *chan = data;
53         struct radeonfb_info    *rinfo = chan->rinfo;
54         u32                     val;
55         
56         val = INREG(chan->ddc_reg);
57
58         return (val & VGA_DDC_CLK_INPUT) ? 1 : 0;
59 }
60
61 static int radeon_gpio_getsda(void* data)
62 {
63         struct radeon_i2c_chan  *chan = data;
64         struct radeonfb_info    *rinfo = chan->rinfo;
65         u32                     val;
66         
67         val = INREG(chan->ddc_reg);
68
69         return (val & VGA_DDC_DATA_INPUT) ? 1 : 0;
70 }
71
72 static int radeon_setup_i2c_bus(struct radeon_i2c_chan *chan, const char *name)
73 {
74         int rc;
75
76         strcpy(chan->adapter.name, name);
77         chan->adapter.owner             = THIS_MODULE;
78         chan->adapter.id                = I2C_HW_B_RADEON;
79         chan->adapter.algo_data         = &chan->algo;
80         chan->adapter.dev.parent        = &chan->rinfo->pdev->dev;
81         chan->algo.setsda               = radeon_gpio_setsda;
82         chan->algo.setscl               = radeon_gpio_setscl;
83         chan->algo.getsda               = radeon_gpio_getsda;
84         chan->algo.getscl               = radeon_gpio_getscl;
85         chan->algo.udelay               = 40;
86         chan->algo.timeout              = 20;
87         chan->algo.data                 = chan; 
88         
89         i2c_set_adapdata(&chan->adapter, chan);
90         
91         /* Raise SCL and SDA */
92         radeon_gpio_setsda(chan, 1);
93         radeon_gpio_setscl(chan, 1);
94         udelay(20);
95
96         rc = i2c_bit_add_bus(&chan->adapter);
97         if (rc == 0)
98                 dev_dbg(&chan->rinfo->pdev->dev, "I2C bus %s registered.\n", name);
99         else
100                 dev_warn(&chan->rinfo->pdev->dev, "Failed to register I2C bus %s.\n", name);
101         return rc;
102 }
103
104 void radeon_create_i2c_busses(struct radeonfb_info *rinfo)
105 {
106         rinfo->i2c[0].rinfo     = rinfo;
107         rinfo->i2c[0].ddc_reg   = GPIO_MONID;
108         radeon_setup_i2c_bus(&rinfo->i2c[0], "monid");
109
110         rinfo->i2c[1].rinfo     = rinfo;
111         rinfo->i2c[1].ddc_reg   = GPIO_DVI_DDC;
112         radeon_setup_i2c_bus(&rinfo->i2c[1], "dvi");
113
114         rinfo->i2c[2].rinfo     = rinfo;
115         rinfo->i2c[2].ddc_reg   = GPIO_VGA_DDC;
116         radeon_setup_i2c_bus(&rinfo->i2c[2], "vga");
117
118         rinfo->i2c[3].rinfo     = rinfo;
119         rinfo->i2c[3].ddc_reg   = GPIO_CRT2_DDC;
120         radeon_setup_i2c_bus(&rinfo->i2c[3], "crt2");
121 }
122
123 void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
124 {
125         if (rinfo->i2c[0].rinfo)
126                 i2c_bit_del_bus(&rinfo->i2c[0].adapter);
127         rinfo->i2c[0].rinfo = NULL;
128
129         if (rinfo->i2c[1].rinfo)
130                 i2c_bit_del_bus(&rinfo->i2c[1].adapter);
131         rinfo->i2c[1].rinfo = NULL;
132
133         if (rinfo->i2c[2].rinfo)
134                 i2c_bit_del_bus(&rinfo->i2c[2].adapter);
135         rinfo->i2c[2].rinfo = NULL;
136
137         if (rinfo->i2c[3].rinfo)
138                 i2c_bit_del_bus(&rinfo->i2c[3].adapter);
139         rinfo->i2c[3].rinfo = NULL;
140 }
141
142
143 static u8 *radeon_do_probe_i2c_edid(struct radeon_i2c_chan *chan)
144 {
145         u8 start = 0x0;
146         struct i2c_msg msgs[] = {
147                 {
148                         .addr   = RADEON_DDC,
149                         .len    = 1,
150                         .buf    = &start,
151                 }, {
152                         .addr   = RADEON_DDC,
153                         .flags  = I2C_M_RD,
154                         .len    = EDID_LENGTH,
155                 },
156         };
157         u8 *buf;
158
159         buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
160         if (!buf) {
161                 dev_warn(&chan->rinfo->pdev->dev, "Out of memory!\n");
162                 return NULL;
163         }
164         msgs[1].buf = buf;
165
166         if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
167                 return buf;
168         dev_dbg(&chan->rinfo->pdev->dev, "Unable to read EDID block.\n");
169         kfree(buf);
170         return NULL;
171 }
172
173
174 int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid)
175 {
176         u32 reg = rinfo->i2c[conn-1].ddc_reg;
177         u8 *edid = NULL;
178         int i, j;
179
180         OUTREG(reg, INREG(reg) & 
181                         ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
182
183         OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
184         (void)INREG(reg);
185
186         for (i = 0; i < 3; i++) {
187                 /* For some old monitors we need the
188                  * following process to initialize/stop DDC
189                  */
190                 OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
191                 (void)INREG(reg);
192                 msleep(13);
193
194                 OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
195                 (void)INREG(reg);
196                 for (j = 0; j < 5; j++) {
197                         msleep(10);
198                         if (INREG(reg) & VGA_DDC_CLK_INPUT)
199                                 break;
200                 }
201                 if (j == 5)
202                         continue;
203
204                 OUTREG(reg, INREG(reg) | VGA_DDC_DATA_OUT_EN);
205                 (void)INREG(reg);
206                 msleep(15);
207                 OUTREG(reg, INREG(reg) | VGA_DDC_CLK_OUT_EN);
208                 (void)INREG(reg);
209                 msleep(15);
210                 OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
211                 (void)INREG(reg);
212                 msleep(15);
213
214                 /* Do the real work */
215                 edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn-1]);
216
217                 OUTREG(reg, INREG(reg) | 
218                                 (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
219                 (void)INREG(reg);
220                 msleep(15);
221                 
222                 OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
223                 (void)INREG(reg);
224                 for (j = 0; j < 10; j++) {
225                         msleep(10);
226                         if (INREG(reg) & VGA_DDC_CLK_INPUT)
227                                 break;
228                 }
229
230                 OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
231                 (void)INREG(reg);
232                 msleep(15);
233                 OUTREG(reg, INREG(reg) |
234                                 (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
235                 (void)INREG(reg);
236                 if (edid)
237                         break;
238         }
239         /* Release the DDC lines when done or the Apple Cinema HD display
240          * will switch off
241          */
242         OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN | VGA_DDC_DATA_OUT_EN));
243         (void)INREG(reg);
244
245         if (out_edid)
246                 *out_edid = edid;
247         if (!edid) {
248                 RTRACE("radeonfb: I2C (port %d) ... not found\n", conn);
249                 return MT_NONE;
250         }
251         if (edid[0x14] & 0x80) {
252                 /* Fix detection using BIOS tables */
253                 if (rinfo->is_mobility /*&& conn == ddc_dvi*/ &&
254                     (INREG(LVDS_GEN_CNTL) & LVDS_ON)) {
255                         RTRACE("radeonfb: I2C (port %d) ... found LVDS panel\n", conn);
256                         return MT_LCD;
257                 } else {
258                         RTRACE("radeonfb: I2C (port %d) ... found TMDS panel\n", conn);
259                         return MT_DFP;
260                 }
261         }
262         RTRACE("radeonfb: I2C (port %d) ... found CRT display\n", conn);
263         return MT_CRT;
264 }
265