This source file includes following definitions.
- intelfb_gpio_setscl
- intelfb_gpio_setsda
- intelfb_gpio_getscl
- intelfb_gpio_getsda
- intelfb_setup_i2c_bus
- intelfb_create_i2c_busses
- intelfb_delete_i2c_busses
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/delay.h>
31 #include <linux/pci.h>
32 #include <linux/fb.h>
33
34 #include <linux/i2c.h>
35 #include <linux/i2c-algo-bit.h>
36
37 #include <asm/io.h>
38
39 #include "intelfb.h"
40 #include "intelfbhw.h"
41
42
43 #define SCL_DIR_MASK 0x0001
44 #define SCL_DIR 0x0002
45 #define SCL_VAL_MASK 0x0004
46 #define SCL_VAL_OUT 0x0008
47 #define SCL_VAL_IN 0x0010
48 #define SDA_DIR_MASK 0x0100
49 #define SDA_DIR 0x0200
50 #define SDA_VAL_MASK 0x0400
51 #define SDA_VAL_OUT 0x0800
52 #define SDA_VAL_IN 0x1000
53
54 static void intelfb_gpio_setscl(void *data, int state)
55 {
56 struct intelfb_i2c_chan *chan = data;
57 struct intelfb_info *dinfo = chan->dinfo;
58 u32 val;
59
60 OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) |
61 SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK);
62 val = INREG(chan->reg);
63 }
64
65 static void intelfb_gpio_setsda(void *data, int state)
66 {
67 struct intelfb_i2c_chan *chan = data;
68 struct intelfb_info *dinfo = chan->dinfo;
69 u32 val;
70
71 OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) |
72 SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK);
73 val = INREG(chan->reg);
74 }
75
76 static int intelfb_gpio_getscl(void *data)
77 {
78 struct intelfb_i2c_chan *chan = data;
79 struct intelfb_info *dinfo = chan->dinfo;
80 u32 val;
81
82 OUTREG(chan->reg, SCL_DIR_MASK);
83 OUTREG(chan->reg, 0);
84 val = INREG(chan->reg);
85 return ((val & SCL_VAL_IN) != 0);
86 }
87
88 static int intelfb_gpio_getsda(void *data)
89 {
90 struct intelfb_i2c_chan *chan = data;
91 struct intelfb_info *dinfo = chan->dinfo;
92 u32 val;
93
94 OUTREG(chan->reg, SDA_DIR_MASK);
95 OUTREG(chan->reg, 0);
96 val = INREG(chan->reg);
97 return ((val & SDA_VAL_IN) != 0);
98 }
99
100 static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
101 struct intelfb_i2c_chan *chan,
102 const u32 reg, const char *name,
103 int class)
104 {
105 int rc;
106
107 chan->dinfo = dinfo;
108 chan->reg = reg;
109 snprintf(chan->adapter.name, sizeof(chan->adapter.name),
110 "intelfb %s", name);
111 chan->adapter.class = class;
112 chan->adapter.owner = THIS_MODULE;
113 chan->adapter.algo_data = &chan->algo;
114 chan->adapter.dev.parent = &chan->dinfo->pdev->dev;
115 chan->algo.setsda = intelfb_gpio_setsda;
116 chan->algo.setscl = intelfb_gpio_setscl;
117 chan->algo.getsda = intelfb_gpio_getsda;
118 chan->algo.getscl = intelfb_gpio_getscl;
119 chan->algo.udelay = 40;
120 chan->algo.timeout = 20;
121 chan->algo.data = chan;
122
123 i2c_set_adapdata(&chan->adapter, chan);
124
125
126 intelfb_gpio_setsda(chan, 1);
127 intelfb_gpio_setscl(chan, 1);
128 udelay(20);
129
130 rc = i2c_bit_add_bus(&chan->adapter);
131 if (rc == 0)
132 DBG_MSG("I2C bus %s registered.\n", name);
133 else
134 WRN_MSG("Failed to register I2C bus %s.\n", name);
135 return rc;
136 }
137
138 void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
139 {
140 int i = 0;
141
142
143 dinfo->num_outputs = 1;
144 dinfo->output[i].type = INTELFB_OUTPUT_ANALOG;
145
146
147 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA,
148 "CRTDDC_A", I2C_CLASS_DDC);
149 i++;
150
151
152
153
154
155 switch(dinfo->chipset) {
156 case INTEL_830M:
157 case INTEL_845G:
158 case INTEL_854:
159 case INTEL_855GM:
160 case INTEL_865G:
161 dinfo->output[i].type = INTELFB_OUTPUT_DVO;
162 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus,
163 GPIOD, "DVODDC_D", I2C_CLASS_DDC);
164 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus,
165 GPIOE, "DVOI2C_E", 0);
166 i++;
167 break;
168 case INTEL_915G:
169 case INTEL_915GM:
170
171 case INTEL_945G:
172 case INTEL_945GM:
173 case INTEL_945GME:
174 case INTEL_965G:
175 case INTEL_965GM:
176
177 dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
178 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus,
179 GPIOE, "SDVOCTRL_E", 0);
180
181
182 i++;
183
184
185 dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
186 dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus;
187
188
189 i++;
190 break;
191 }
192 dinfo->num_outputs = i;
193 }
194
195 void intelfb_delete_i2c_busses(struct intelfb_info *dinfo)
196 {
197 int i;
198
199 for (i = 0; i < MAX_OUTPUTS; i++) {
200 if (dinfo->output[i].i2c_bus.dinfo) {
201 i2c_del_adapter(&dinfo->output[i].i2c_bus.adapter);
202 dinfo->output[i].i2c_bus.dinfo = NULL;
203 }
204 if (dinfo->output[i].ddc_bus.dinfo) {
205 i2c_del_adapter(&dinfo->output[i].ddc_bus.adapter);
206 dinfo->output[i].ddc_bus.dinfo = NULL;
207 }
208 }
209 }