File: | dev/pci/drm/i915/display/dvo_sil164.c |
Warning: | line 250, column 2 3rd function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /************************************************************************** | |||
2 | ||||
3 | Copyright © 2006 Dave Airlie | |||
4 | ||||
5 | All Rights Reserved. | |||
6 | ||||
7 | Permission is hereby granted, free of charge, to any person obtaining a | |||
8 | copy of this software and associated documentation files (the | |||
9 | "Software"), to deal in the Software without restriction, including | |||
10 | without limitation the rights to use, copy, modify, merge, publish, | |||
11 | distribute, sub license, and/or sell copies of the Software, and to | |||
12 | permit persons to whom the Software is furnished to do so, subject to | |||
13 | the following conditions: | |||
14 | ||||
15 | The above copyright notice and this permission notice (including the | |||
16 | next paragraph) shall be included in all copies or substantial portions | |||
17 | of the Software. | |||
18 | ||||
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
20 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | |||
22 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||
23 | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
26 | ||||
27 | **************************************************************************/ | |||
28 | ||||
29 | #include "intel_display_types.h" | |||
30 | #include "intel_dvo_dev.h" | |||
31 | ||||
32 | #define SIL164_VID0x0001 0x0001 | |||
33 | #define SIL164_DID0x0006 0x0006 | |||
34 | ||||
35 | #define SIL164_VID_LO0x00 0x00 | |||
36 | #define SIL164_VID_HI0x01 0x01 | |||
37 | #define SIL164_DID_LO0x02 0x02 | |||
38 | #define SIL164_DID_HI0x03 0x03 | |||
39 | #define SIL164_REV0x04 0x04 | |||
40 | #define SIL164_RSVD0x05 0x05 | |||
41 | #define SIL164_FREQ_LO0x06 0x06 | |||
42 | #define SIL164_FREQ_HI0x07 0x07 | |||
43 | ||||
44 | #define SIL164_REG80x08 0x08 | |||
45 | #define SIL164_8_VEN(1<<5) (1<<5) | |||
46 | #define SIL164_8_HEN(1<<4) (1<<4) | |||
47 | #define SIL164_8_DSEL(1<<3) (1<<3) | |||
48 | #define SIL164_8_BSEL(1<<2) (1<<2) | |||
49 | #define SIL164_8_EDGE(1<<1) (1<<1) | |||
50 | #define SIL164_8_PD(1<<0) (1<<0) | |||
51 | ||||
52 | #define SIL164_REG90x09 0x09 | |||
53 | #define SIL164_9_VLOW(1<<7) (1<<7) | |||
54 | #define SIL164_9_MSEL_MASK(0x7<<4) (0x7<<4) | |||
55 | #define SIL164_9_TSEL(1<<3) (1<<3) | |||
56 | #define SIL164_9_RSEN(1<<2) (1<<2) | |||
57 | #define SIL164_9_HTPLG(1<<1) (1<<1) | |||
58 | #define SIL164_9_MDI(1<<0) (1<<0) | |||
59 | ||||
60 | #define SIL164_REGC0x0c 0x0c | |||
61 | ||||
62 | struct sil164_priv { | |||
63 | //I2CDevRec d; | |||
64 | bool_Bool quiet; | |||
65 | }; | |||
66 | ||||
67 | #define SILPTR(d)((SIL164Ptr)(d->DriverPrivate.ptr)) ((SIL164Ptr)(d->DriverPrivate.ptr)) | |||
68 | ||||
69 | static bool_Bool sil164_readb(struct intel_dvo_device *dvo, int addr, u8 *ch) | |||
70 | { | |||
71 | struct sil164_priv *sil = dvo->dev_priv; | |||
72 | struct i2c_adapter *adapter = dvo->i2c_bus; | |||
73 | u8 out_buf[2]; | |||
74 | u8 in_buf[2]; | |||
75 | ||||
76 | struct i2c_msg msgs[] = { | |||
77 | { | |||
78 | .addr = dvo->slave_addr, | |||
79 | .flags = 0, | |||
80 | .len = 1, | |||
81 | .buf = out_buf, | |||
82 | }, | |||
83 | { | |||
84 | .addr = dvo->slave_addr, | |||
85 | .flags = I2C_M_RD0x0001, | |||
86 | .len = 1, | |||
87 | .buf = in_buf, | |||
88 | } | |||
89 | }; | |||
90 | ||||
91 | out_buf[0] = addr; | |||
92 | out_buf[1] = 0; | |||
93 | ||||
94 | if (i2c_transfer(adapter, msgs, 2) == 2) { | |||
95 | *ch = in_buf[0]; | |||
96 | return true1; | |||
97 | } | |||
98 | ||||
99 | if (!sil->quiet) { | |||
100 | DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",__drm_dbg(DRM_UT_KMS, "Unable to read register 0x%02x from %s:%02x.\n" , addr, adapter->name, dvo->slave_addr) | |||
101 | addr, adapter->name, dvo->slave_addr)__drm_dbg(DRM_UT_KMS, "Unable to read register 0x%02x from %s:%02x.\n" , addr, adapter->name, dvo->slave_addr); | |||
102 | } | |||
103 | return false0; | |||
104 | } | |||
105 | ||||
106 | static bool_Bool sil164_writeb(struct intel_dvo_device *dvo, int addr, u8 ch) | |||
107 | { | |||
108 | struct sil164_priv *sil = dvo->dev_priv; | |||
109 | struct i2c_adapter *adapter = dvo->i2c_bus; | |||
110 | u8 out_buf[2]; | |||
111 | struct i2c_msg msg = { | |||
112 | .addr = dvo->slave_addr, | |||
113 | .flags = 0, | |||
114 | .len = 2, | |||
115 | .buf = out_buf, | |||
116 | }; | |||
117 | ||||
118 | out_buf[0] = addr; | |||
119 | out_buf[1] = ch; | |||
120 | ||||
121 | if (i2c_transfer(adapter, &msg, 1) == 1) | |||
122 | return true1; | |||
123 | ||||
124 | if (!sil->quiet) { | |||
125 | DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",__drm_dbg(DRM_UT_KMS, "Unable to write register 0x%02x to %s:%d.\n" , addr, adapter->name, dvo->slave_addr) | |||
126 | addr, adapter->name, dvo->slave_addr)__drm_dbg(DRM_UT_KMS, "Unable to write register 0x%02x to %s:%d.\n" , addr, adapter->name, dvo->slave_addr); | |||
127 | } | |||
128 | ||||
129 | return false0; | |||
130 | } | |||
131 | ||||
132 | /* Silicon Image 164 driver for chip on i2c bus */ | |||
133 | static bool_Bool sil164_init(struct intel_dvo_device *dvo, | |||
134 | struct i2c_adapter *adapter) | |||
135 | { | |||
136 | /* this will detect the SIL164 chip on the specified i2c bus */ | |||
137 | struct sil164_priv *sil; | |||
138 | unsigned char ch; | |||
139 | ||||
140 | sil = kzalloc(sizeof(struct sil164_priv), GFP_KERNEL(0x0001 | 0x0004)); | |||
141 | if (sil == NULL((void *)0)) | |||
142 | return false0; | |||
143 | ||||
144 | dvo->i2c_bus = adapter; | |||
145 | dvo->dev_priv = sil; | |||
146 | sil->quiet = true1; | |||
147 | ||||
148 | if (!sil164_readb(dvo, SIL164_VID_LO0x00, &ch)) | |||
149 | goto out; | |||
150 | ||||
151 | if (ch != (SIL164_VID0x0001 & 0xff)) { | |||
152 | DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n",__drm_dbg(DRM_UT_KMS, "sil164 not detected got %d: from %s Slave %d.\n" , ch, adapter->name, dvo->slave_addr) | |||
153 | ch, adapter->name, dvo->slave_addr)__drm_dbg(DRM_UT_KMS, "sil164 not detected got %d: from %s Slave %d.\n" , ch, adapter->name, dvo->slave_addr); | |||
154 | goto out; | |||
155 | } | |||
156 | ||||
157 | if (!sil164_readb(dvo, SIL164_DID_LO0x02, &ch)) | |||
158 | goto out; | |||
159 | ||||
160 | if (ch != (SIL164_DID0x0006 & 0xff)) { | |||
161 | DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n",__drm_dbg(DRM_UT_KMS, "sil164 not detected got %d: from %s Slave %d.\n" , ch, adapter->name, dvo->slave_addr) | |||
162 | ch, adapter->name, dvo->slave_addr)__drm_dbg(DRM_UT_KMS, "sil164 not detected got %d: from %s Slave %d.\n" , ch, adapter->name, dvo->slave_addr); | |||
163 | goto out; | |||
164 | } | |||
165 | sil->quiet = false0; | |||
166 | ||||
167 | DRM_DEBUG_KMS("init sil164 dvo controller successfully!\n")__drm_dbg(DRM_UT_KMS, "init sil164 dvo controller successfully!\n" ); | |||
168 | return true1; | |||
169 | ||||
170 | out: | |||
171 | kfree(sil); | |||
172 | return false0; | |||
173 | } | |||
174 | ||||
175 | static enum drm_connector_status sil164_detect(struct intel_dvo_device *dvo) | |||
176 | { | |||
177 | u8 reg9; | |||
178 | ||||
179 | sil164_readb(dvo, SIL164_REG90x09, ®9); | |||
180 | ||||
181 | if (reg9 & SIL164_9_HTPLG(1<<1)) | |||
182 | return connector_status_connected; | |||
183 | else | |||
184 | return connector_status_disconnected; | |||
185 | } | |||
186 | ||||
187 | static enum drm_mode_status sil164_mode_valid(struct intel_dvo_device *dvo, | |||
188 | struct drm_display_mode *mode) | |||
189 | { | |||
190 | return MODE_OK; | |||
191 | } | |||
192 | ||||
193 | static void sil164_mode_set(struct intel_dvo_device *dvo, | |||
194 | const struct drm_display_mode *mode, | |||
195 | const struct drm_display_mode *adjusted_mode) | |||
196 | { | |||
197 | /* As long as the basics are set up, since we don't have clock | |||
198 | * dependencies in the mode setup, we can just leave the | |||
199 | * registers alone and everything will work fine. | |||
200 | */ | |||
201 | /* recommended programming sequence from doc */ | |||
202 | /*sil164_writeb(sil, 0x08, 0x30); | |||
203 | sil164_writeb(sil, 0x09, 0x00); | |||
204 | sil164_writeb(sil, 0x0a, 0x90); | |||
205 | sil164_writeb(sil, 0x0c, 0x89); | |||
206 | sil164_writeb(sil, 0x08, 0x31);*/ | |||
207 | /* don't do much */ | |||
208 | return; | |||
209 | } | |||
210 | ||||
211 | /* set the SIL164 power state */ | |||
212 | static void sil164_dpms(struct intel_dvo_device *dvo, bool_Bool enable) | |||
213 | { | |||
214 | int ret; | |||
215 | unsigned char ch; | |||
216 | ||||
217 | ret = sil164_readb(dvo, SIL164_REG80x08, &ch); | |||
218 | if (ret == false0) | |||
219 | return; | |||
220 | ||||
221 | if (enable) | |||
222 | ch |= SIL164_8_PD(1<<0); | |||
223 | else | |||
224 | ch &= ~SIL164_8_PD(1<<0); | |||
225 | ||||
226 | sil164_writeb(dvo, SIL164_REG80x08, ch); | |||
227 | return; | |||
228 | } | |||
229 | ||||
230 | static bool_Bool sil164_get_hw_state(struct intel_dvo_device *dvo) | |||
231 | { | |||
232 | int ret; | |||
233 | unsigned char ch; | |||
234 | ||||
235 | ret = sil164_readb(dvo, SIL164_REG80x08, &ch); | |||
236 | if (ret == false0) | |||
237 | return false0; | |||
238 | ||||
239 | if (ch & SIL164_8_PD(1<<0)) | |||
240 | return true1; | |||
241 | else | |||
242 | return false0; | |||
243 | } | |||
244 | ||||
245 | static void sil164_dump_regs(struct intel_dvo_device *dvo) | |||
246 | { | |||
247 | u8 val; | |||
| ||||
248 | ||||
249 | sil164_readb(dvo, SIL164_FREQ_LO0x06, &val); | |||
250 | DRM_DEBUG_KMS("SIL164_FREQ_LO: 0x%02x\n", val)__drm_dbg(DRM_UT_KMS, "SIL164_FREQ_LO: 0x%02x\n", val); | |||
| ||||
251 | sil164_readb(dvo, SIL164_FREQ_HI0x07, &val); | |||
252 | DRM_DEBUG_KMS("SIL164_FREQ_HI: 0x%02x\n", val)__drm_dbg(DRM_UT_KMS, "SIL164_FREQ_HI: 0x%02x\n", val); | |||
253 | sil164_readb(dvo, SIL164_REG80x08, &val); | |||
254 | DRM_DEBUG_KMS("SIL164_REG8: 0x%02x\n", val)__drm_dbg(DRM_UT_KMS, "SIL164_REG8: 0x%02x\n", val); | |||
255 | sil164_readb(dvo, SIL164_REG90x09, &val); | |||
256 | DRM_DEBUG_KMS("SIL164_REG9: 0x%02x\n", val)__drm_dbg(DRM_UT_KMS, "SIL164_REG9: 0x%02x\n", val); | |||
257 | sil164_readb(dvo, SIL164_REGC0x0c, &val); | |||
258 | DRM_DEBUG_KMS("SIL164_REGC: 0x%02x\n", val)__drm_dbg(DRM_UT_KMS, "SIL164_REGC: 0x%02x\n", val); | |||
259 | } | |||
260 | ||||
261 | static void sil164_destroy(struct intel_dvo_device *dvo) | |||
262 | { | |||
263 | struct sil164_priv *sil = dvo->dev_priv; | |||
264 | ||||
265 | if (sil) { | |||
266 | kfree(sil); | |||
267 | dvo->dev_priv = NULL((void *)0); | |||
268 | } | |||
269 | } | |||
270 | ||||
271 | const struct intel_dvo_dev_ops sil164_ops = { | |||
272 | .init = sil164_init, | |||
273 | .detect = sil164_detect, | |||
274 | .mode_valid = sil164_mode_valid, | |||
275 | .mode_set = sil164_mode_set, | |||
276 | .dpms = sil164_dpms, | |||
277 | .get_hw_state = sil164_get_hw_state, | |||
278 | .dump_regs = sil164_dump_regs, | |||
279 | .destroy = sil164_destroy, | |||
280 | }; |