Subversion Repositories Kolibri OS

Rev

Rev 3031 | Rev 6084 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3031 Rev 4104
1
/**************************************************************************
1
/**************************************************************************
2
 
2
 
3
Copyright © 2006 Dave Airlie
3
Copyright © 2006 Dave Airlie
4
 
4
 
5
All Rights Reserved.
5
All Rights Reserved.
6
 
6
 
7
Permission is hereby granted, free of charge, to any person obtaining a
7
Permission is hereby granted, free of charge, to any person obtaining a
8
copy of this software and associated documentation files (the
8
copy of this software and associated documentation files (the
9
"Software"), to deal in the Software without restriction, including
9
"Software"), to deal in the Software without restriction, including
10
without limitation the rights to use, copy, modify, merge, publish,
10
without limitation the rights to use, copy, modify, merge, publish,
11
distribute, sub license, and/or sell copies of the Software, and to
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
12
permit persons to whom the Software is furnished to do so, subject to
13
the following conditions:
13
the following conditions:
14
 
14
 
15
The above copyright notice and this permission notice (including the
15
The above copyright notice and this permission notice (including the
16
next paragraph) shall be included in all copies or substantial portions
16
next paragraph) shall be included in all copies or substantial portions
17
of the Software.
17
of the Software.
18
 
18
 
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
22
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
23
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
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
24
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
 
26
 
27
**************************************************************************/
27
**************************************************************************/
28
 
28
 
29
#include "dvo.h"
29
#include "dvo.h"
30
 
30
 
31
#define CH7xxx_REG_VID		0x4a
31
#define CH7xxx_REG_VID		0x4a
32
#define CH7xxx_REG_DID		0x4b
32
#define CH7xxx_REG_DID		0x4b
33
 
33
 
34
#define CH7011_VID		0x83 /* 7010 as well */
34
#define CH7011_VID		0x83 /* 7010 as well */
-
 
35
#define CH7010B_VID		0x05
35
#define CH7009A_VID		0x84
36
#define CH7009A_VID		0x84
36
#define CH7009B_VID		0x85
37
#define CH7009B_VID		0x85
37
#define CH7301_VID		0x95
38
#define CH7301_VID		0x95
38
 
39
 
39
#define CH7xxx_VID		0x84
40
#define CH7xxx_VID		0x84
40
#define CH7xxx_DID		0x17
41
#define CH7xxx_DID		0x17
-
 
42
#define CH7010_DID		0x16
41
 
43
 
42
#define CH7xxx_NUM_REGS		0x4c
44
#define CH7xxx_NUM_REGS		0x4c
43
 
45
 
44
#define CH7xxx_CM		0x1c
46
#define CH7xxx_CM		0x1c
45
#define CH7xxx_CM_XCM		(1<<0)
47
#define CH7xxx_CM_XCM		(1<<0)
46
#define CH7xxx_CM_MCP		(1<<2)
48
#define CH7xxx_CM_MCP		(1<<2)
47
#define CH7xxx_INPUT_CLOCK	0x1d
49
#define CH7xxx_INPUT_CLOCK	0x1d
48
#define CH7xxx_GPIO		0x1e
50
#define CH7xxx_GPIO		0x1e
49
#define CH7xxx_GPIO_HPIR	(1<<3)
51
#define CH7xxx_GPIO_HPIR	(1<<3)
50
#define CH7xxx_IDF		0x1f
52
#define CH7xxx_IDF		0x1f
51
 
53
 
52
#define CH7xxx_IDF_HSP		(1<<3)
54
#define CH7xxx_IDF_HSP		(1<<3)
53
#define CH7xxx_IDF_VSP		(1<<4)
55
#define CH7xxx_IDF_VSP		(1<<4)
54
 
56
 
55
#define CH7xxx_CONNECTION_DETECT 0x20
57
#define CH7xxx_CONNECTION_DETECT 0x20
56
#define CH7xxx_CDET_DVI		(1<<5)
58
#define CH7xxx_CDET_DVI		(1<<5)
57
 
59
 
58
#define CH7301_DAC_CNTL		0x21
60
#define CH7301_DAC_CNTL		0x21
59
#define CH7301_HOTPLUG		0x23
61
#define CH7301_HOTPLUG		0x23
60
#define CH7xxx_TCTL		0x31
62
#define CH7xxx_TCTL		0x31
61
#define CH7xxx_TVCO		0x32
63
#define CH7xxx_TVCO		0x32
62
#define CH7xxx_TPCP		0x33
64
#define CH7xxx_TPCP		0x33
63
#define CH7xxx_TPD		0x34
65
#define CH7xxx_TPD		0x34
64
#define CH7xxx_TPVT		0x35
66
#define CH7xxx_TPVT		0x35
65
#define CH7xxx_TLPF		0x36
67
#define CH7xxx_TLPF		0x36
66
#define CH7xxx_TCT		0x37
68
#define CH7xxx_TCT		0x37
67
#define CH7301_TEST_PATTERN	0x48
69
#define CH7301_TEST_PATTERN	0x48
68
 
70
 
69
#define CH7xxx_PM		0x49
71
#define CH7xxx_PM		0x49
70
#define CH7xxx_PM_FPD		(1<<0)
72
#define CH7xxx_PM_FPD		(1<<0)
71
#define CH7301_PM_DACPD0	(1<<1)
73
#define CH7301_PM_DACPD0	(1<<1)
72
#define CH7301_PM_DACPD1	(1<<2)
74
#define CH7301_PM_DACPD1	(1<<2)
73
#define CH7301_PM_DACPD2	(1<<3)
75
#define CH7301_PM_DACPD2	(1<<3)
74
#define CH7xxx_PM_DVIL		(1<<6)
76
#define CH7xxx_PM_DVIL		(1<<6)
75
#define CH7xxx_PM_DVIP		(1<<7)
77
#define CH7xxx_PM_DVIP		(1<<7)
76
 
78
 
77
#define CH7301_SYNC_POLARITY	0x56
79
#define CH7301_SYNC_POLARITY	0x56
78
#define CH7301_SYNC_RGB_YUV	(1<<0)
80
#define CH7301_SYNC_RGB_YUV	(1<<0)
79
#define CH7301_SYNC_POL_DVI	(1<<5)
81
#define CH7301_SYNC_POL_DVI	(1<<5)
80
 
82
 
81
/** @file
83
/** @file
82
 * driver for the Chrontel 7xxx DVI chip over DVO.
84
 * driver for the Chrontel 7xxx DVI chip over DVO.
83
 */
85
 */
84
 
86
 
85
static struct ch7xxx_id_struct {
87
static struct ch7xxx_id_struct {
86
	uint8_t vid;
88
	uint8_t vid;
87
	char *name;
89
	char *name;
88
} ch7xxx_ids[] = {
90
} ch7xxx_ids[] = {
89
	{ CH7011_VID, "CH7011" },
91
	{ CH7011_VID, "CH7011" },
-
 
92
	{ CH7010B_VID, "CH7010B" },
90
	{ CH7009A_VID, "CH7009A" },
93
	{ CH7009A_VID, "CH7009A" },
91
	{ CH7009B_VID, "CH7009B" },
94
	{ CH7009B_VID, "CH7009B" },
92
	{ CH7301_VID, "CH7301" },
95
	{ CH7301_VID, "CH7301" },
93
};
96
};
-
 
97
 
-
 
98
static struct ch7xxx_did_struct {
-
 
99
	uint8_t did;
-
 
100
	char *name;
-
 
101
} ch7xxx_dids[] = {
-
 
102
	{ CH7xxx_DID, "CH7XXX" },
-
 
103
	{ CH7010_DID, "CH7010B" },
-
 
104
};
94
 
105
 
95
struct ch7xxx_priv {
106
struct ch7xxx_priv {
96
	bool quiet;
107
	bool quiet;
97
};
108
};
98
 
109
 
99
static char *ch7xxx_get_id(uint8_t vid)
110
static char *ch7xxx_get_id(uint8_t vid)
100
{
111
{
101
	int i;
112
	int i;
102
 
113
 
103
	for (i = 0; i < ARRAY_SIZE(ch7xxx_ids); i++) {
114
	for (i = 0; i < ARRAY_SIZE(ch7xxx_ids); i++) {
104
		if (ch7xxx_ids[i].vid == vid)
115
		if (ch7xxx_ids[i].vid == vid)
105
			return ch7xxx_ids[i].name;
116
			return ch7xxx_ids[i].name;
106
	}
117
	}
107
 
118
 
108
	return NULL;
119
	return NULL;
109
}
120
}
-
 
121
 
-
 
122
static char *ch7xxx_get_did(uint8_t did)
-
 
123
{
-
 
124
	int i;
-
 
125
 
-
 
126
	for (i = 0; i < ARRAY_SIZE(ch7xxx_dids); i++) {
-
 
127
		if (ch7xxx_dids[i].did == did)
-
 
128
			return ch7xxx_dids[i].name;
-
 
129
	}
-
 
130
 
-
 
131
	return NULL;
-
 
132
}
110
 
133
 
111
/** Reads an 8 bit register */
134
/** Reads an 8 bit register */
112
static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
135
static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
113
{
136
{
114
	struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
137
	struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
115
	struct i2c_adapter *adapter = dvo->i2c_bus;
138
	struct i2c_adapter *adapter = dvo->i2c_bus;
116
	u8 out_buf[2];
139
	u8 out_buf[2];
117
	u8 in_buf[2];
140
	u8 in_buf[2];
118
 
141
 
119
	struct i2c_msg msgs[] = {
142
	struct i2c_msg msgs[] = {
120
		{
143
		{
121
			.addr = dvo->slave_addr,
144
			.addr = dvo->slave_addr,
122
			.flags = 0,
145
			.flags = 0,
123
			.len = 1,
146
			.len = 1,
124
			.buf = out_buf,
147
			.buf = out_buf,
125
		},
148
		},
126
		{
149
		{
127
			.addr = dvo->slave_addr,
150
			.addr = dvo->slave_addr,
128
			.flags = I2C_M_RD,
151
			.flags = I2C_M_RD,
129
			.len = 1,
152
			.len = 1,
130
			.buf = in_buf,
153
			.buf = in_buf,
131
		}
154
		}
132
	};
155
	};
133
 
156
 
134
	out_buf[0] = addr;
157
	out_buf[0] = addr;
135
	out_buf[1] = 0;
158
	out_buf[1] = 0;
136
 
159
 
137
	if (i2c_transfer(adapter, msgs, 2) == 2) {
160
	if (i2c_transfer(adapter, msgs, 2) == 2) {
138
		*ch = in_buf[0];
161
		*ch = in_buf[0];
139
		return true;
162
		return true;
140
	};
163
	};
141
 
164
 
142
	if (!ch7xxx->quiet) {
165
	if (!ch7xxx->quiet) {
143
		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
166
		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
144
			  addr, adapter->name, dvo->slave_addr);
167
			  addr, adapter->name, dvo->slave_addr);
145
	}
168
	}
146
	return false;
169
	return false;
147
}
170
}
148
 
171
 
149
/** Writes an 8 bit register */
172
/** Writes an 8 bit register */
150
static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
173
static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
151
{
174
{
152
	struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
175
	struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
153
	struct i2c_adapter *adapter = dvo->i2c_bus;
176
	struct i2c_adapter *adapter = dvo->i2c_bus;
154
	uint8_t out_buf[2];
177
	uint8_t out_buf[2];
155
	struct i2c_msg msg = {
178
	struct i2c_msg msg = {
156
		.addr = dvo->slave_addr,
179
		.addr = dvo->slave_addr,
157
		.flags = 0,
180
		.flags = 0,
158
		.len = 2,
181
		.len = 2,
159
		.buf = out_buf,
182
		.buf = out_buf,
160
	};
183
	};
161
 
184
 
162
	out_buf[0] = addr;
185
	out_buf[0] = addr;
163
	out_buf[1] = ch;
186
	out_buf[1] = ch;
164
 
187
 
165
	if (i2c_transfer(adapter, &msg, 1) == 1)
188
	if (i2c_transfer(adapter, &msg, 1) == 1)
166
		return true;
189
		return true;
167
 
190
 
168
	if (!ch7xxx->quiet) {
191
	if (!ch7xxx->quiet) {
169
		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
192
		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
170
			  addr, adapter->name, dvo->slave_addr);
193
			  addr, adapter->name, dvo->slave_addr);
171
	}
194
	}
172
 
195
 
173
	return false;
196
	return false;
174
}
197
}
175
 
198
 
176
static bool ch7xxx_init(struct intel_dvo_device *dvo,
199
static bool ch7xxx_init(struct intel_dvo_device *dvo,
177
			struct i2c_adapter *adapter)
200
			struct i2c_adapter *adapter)
178
{
201
{
179
	/* this will detect the CH7xxx chip on the specified i2c bus */
202
	/* this will detect the CH7xxx chip on the specified i2c bus */
180
	struct ch7xxx_priv *ch7xxx;
203
	struct ch7xxx_priv *ch7xxx;
181
	uint8_t vendor, device;
204
	uint8_t vendor, device;
182
	char *name;
205
	char *name, *devid;
183
 
206
 
184
	ch7xxx = kzalloc(sizeof(struct ch7xxx_priv), GFP_KERNEL);
207
	ch7xxx = kzalloc(sizeof(struct ch7xxx_priv), GFP_KERNEL);
185
	if (ch7xxx == NULL)
208
	if (ch7xxx == NULL)
186
		return false;
209
		return false;
187
 
210
 
188
	dvo->i2c_bus = adapter;
211
	dvo->i2c_bus = adapter;
189
	dvo->dev_priv = ch7xxx;
212
	dvo->dev_priv = ch7xxx;
190
	ch7xxx->quiet = true;
213
	ch7xxx->quiet = true;
191
 
214
 
192
	if (!ch7xxx_readb(dvo, CH7xxx_REG_VID, &vendor))
215
	if (!ch7xxx_readb(dvo, CH7xxx_REG_VID, &vendor))
193
		goto out;
216
		goto out;
194
 
217
 
195
	name = ch7xxx_get_id(vendor);
218
	name = ch7xxx_get_id(vendor);
196
	if (!name) {
219
	if (!name) {
197
		DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
220
		DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
198
				"slave %d.\n",
221
				"slave %d.\n",
199
			  vendor, adapter->name, dvo->slave_addr);
222
			  vendor, adapter->name, dvo->slave_addr);
200
		goto out;
223
		goto out;
201
	}
224
	}
202
 
225
 
203
 
226
 
204
	if (!ch7xxx_readb(dvo, CH7xxx_REG_DID, &device))
227
	if (!ch7xxx_readb(dvo, CH7xxx_REG_DID, &device))
205
		goto out;
228
		goto out;
-
 
229
 
206
 
230
	devid = ch7xxx_get_did(device);
207
	if (device != CH7xxx_DID) {
231
	if (!devid) {
208
		DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
232
		DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
209
				"slave %d.\n",
233
				"slave %d.\n",
210
			  vendor, adapter->name, dvo->slave_addr);
234
			  vendor, adapter->name, dvo->slave_addr);
211
		goto out;
235
		goto out;
212
	}
236
	}
213
 
237
 
214
	ch7xxx->quiet = false;
238
	ch7xxx->quiet = false;
215
	DRM_DEBUG_KMS("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
239
	DRM_DEBUG_KMS("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
216
		  name, vendor, device);
240
		  name, vendor, device);
217
	return true;
241
	return true;
218
out:
242
out:
219
	kfree(ch7xxx);
243
	kfree(ch7xxx);
220
	return false;
244
	return false;
221
}
245
}
222
 
246
 
223
static enum drm_connector_status ch7xxx_detect(struct intel_dvo_device *dvo)
247
static enum drm_connector_status ch7xxx_detect(struct intel_dvo_device *dvo)
224
{
248
{
225
	uint8_t cdet, orig_pm, pm;
249
	uint8_t cdet, orig_pm, pm;
226
 
250
 
227
	ch7xxx_readb(dvo, CH7xxx_PM, &orig_pm);
251
	ch7xxx_readb(dvo, CH7xxx_PM, &orig_pm);
228
 
252
 
229
	pm = orig_pm;
253
	pm = orig_pm;
230
	pm &= ~CH7xxx_PM_FPD;
254
	pm &= ~CH7xxx_PM_FPD;
231
	pm |= CH7xxx_PM_DVIL | CH7xxx_PM_DVIP;
255
	pm |= CH7xxx_PM_DVIL | CH7xxx_PM_DVIP;
232
 
256
 
233
	ch7xxx_writeb(dvo, CH7xxx_PM, pm);
257
	ch7xxx_writeb(dvo, CH7xxx_PM, pm);
234
 
258
 
235
	ch7xxx_readb(dvo, CH7xxx_CONNECTION_DETECT, &cdet);
259
	ch7xxx_readb(dvo, CH7xxx_CONNECTION_DETECT, &cdet);
236
 
260
 
237
	ch7xxx_writeb(dvo, CH7xxx_PM, orig_pm);
261
	ch7xxx_writeb(dvo, CH7xxx_PM, orig_pm);
238
 
262
 
239
	if (cdet & CH7xxx_CDET_DVI)
263
	if (cdet & CH7xxx_CDET_DVI)
240
		return connector_status_connected;
264
		return connector_status_connected;
241
	return connector_status_disconnected;
265
	return connector_status_disconnected;
242
}
266
}
243
 
267
 
244
static enum drm_mode_status ch7xxx_mode_valid(struct intel_dvo_device *dvo,
268
static enum drm_mode_status ch7xxx_mode_valid(struct intel_dvo_device *dvo,
245
					      struct drm_display_mode *mode)
269
					      struct drm_display_mode *mode)
246
{
270
{
247
	if (mode->clock > 165000)
271
	if (mode->clock > 165000)
248
		return MODE_CLOCK_HIGH;
272
		return MODE_CLOCK_HIGH;
249
 
273
 
250
	return MODE_OK;
274
	return MODE_OK;
251
}
275
}
252
 
276
 
253
static void ch7xxx_mode_set(struct intel_dvo_device *dvo,
277
static void ch7xxx_mode_set(struct intel_dvo_device *dvo,
254
			    struct drm_display_mode *mode,
278
			    struct drm_display_mode *mode,
255
			    struct drm_display_mode *adjusted_mode)
279
			    struct drm_display_mode *adjusted_mode)
256
{
280
{
257
	uint8_t tvco, tpcp, tpd, tlpf, idf;
281
	uint8_t tvco, tpcp, tpd, tlpf, idf;
258
 
282
 
259
	if (mode->clock <= 65000) {
283
	if (mode->clock <= 65000) {
260
		tvco = 0x23;
284
		tvco = 0x23;
261
		tpcp = 0x08;
285
		tpcp = 0x08;
262
		tpd = 0x16;
286
		tpd = 0x16;
263
		tlpf = 0x60;
287
		tlpf = 0x60;
264
	} else {
288
	} else {
265
		tvco = 0x2d;
289
		tvco = 0x2d;
266
		tpcp = 0x06;
290
		tpcp = 0x06;
267
		tpd = 0x26;
291
		tpd = 0x26;
268
		tlpf = 0xa0;
292
		tlpf = 0xa0;
269
	}
293
	}
270
 
294
 
271
	ch7xxx_writeb(dvo, CH7xxx_TCTL, 0x00);
295
	ch7xxx_writeb(dvo, CH7xxx_TCTL, 0x00);
272
	ch7xxx_writeb(dvo, CH7xxx_TVCO, tvco);
296
	ch7xxx_writeb(dvo, CH7xxx_TVCO, tvco);
273
	ch7xxx_writeb(dvo, CH7xxx_TPCP, tpcp);
297
	ch7xxx_writeb(dvo, CH7xxx_TPCP, tpcp);
274
	ch7xxx_writeb(dvo, CH7xxx_TPD, tpd);
298
	ch7xxx_writeb(dvo, CH7xxx_TPD, tpd);
275
	ch7xxx_writeb(dvo, CH7xxx_TPVT, 0x30);
299
	ch7xxx_writeb(dvo, CH7xxx_TPVT, 0x30);
276
	ch7xxx_writeb(dvo, CH7xxx_TLPF, tlpf);
300
	ch7xxx_writeb(dvo, CH7xxx_TLPF, tlpf);
277
	ch7xxx_writeb(dvo, CH7xxx_TCT, 0x00);
301
	ch7xxx_writeb(dvo, CH7xxx_TCT, 0x00);
278
 
302
 
279
	ch7xxx_readb(dvo, CH7xxx_IDF, &idf);
303
	ch7xxx_readb(dvo, CH7xxx_IDF, &idf);
280
 
304
 
281
	idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP);
305
	idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP);
282
	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
306
	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
283
		idf |= CH7xxx_IDF_HSP;
307
		idf |= CH7xxx_IDF_HSP;
284
 
308
 
285
	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
309
	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
286
		idf |= CH7xxx_IDF_HSP;
310
		idf |= CH7xxx_IDF_VSP;
287
 
311
 
288
	ch7xxx_writeb(dvo, CH7xxx_IDF, idf);
312
	ch7xxx_writeb(dvo, CH7xxx_IDF, idf);
289
}
313
}
290
 
314
 
291
/* set the CH7xxx power state */
315
/* set the CH7xxx power state */
292
static void ch7xxx_dpms(struct intel_dvo_device *dvo, bool enable)
316
static void ch7xxx_dpms(struct intel_dvo_device *dvo, bool enable)
293
{
317
{
294
	if (enable)
318
	if (enable)
295
		ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP);
319
		ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP);
296
	else
320
	else
297
		ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD);
321
		ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD);
298
}
322
}
299
 
323
 
300
static bool ch7xxx_get_hw_state(struct intel_dvo_device *dvo)
324
static bool ch7xxx_get_hw_state(struct intel_dvo_device *dvo)
301
{
325
{
302
	u8 val;
326
	u8 val;
303
 
327
 
304
	ch7xxx_readb(dvo, CH7xxx_PM, &val);
328
	ch7xxx_readb(dvo, CH7xxx_PM, &val);
305
 
329
 
306
	if (val & (CH7xxx_PM_DVIL | CH7xxx_PM_DVIP))
330
	if (val & (CH7xxx_PM_DVIL | CH7xxx_PM_DVIP))
307
		return true;
331
		return true;
308
	else
332
	else
309
		return false;
333
		return false;
310
}
334
}
311
 
335
 
312
static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
336
static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
313
{
337
{
314
	int i;
338
	int i;
315
 
339
 
316
	for (i = 0; i < CH7xxx_NUM_REGS; i++) {
340
	for (i = 0; i < CH7xxx_NUM_REGS; i++) {
317
		uint8_t val;
341
		uint8_t val;
318
		if ((i % 8) == 0)
342
		if ((i % 8) == 0)
319
			DRM_LOG_KMS("\n %02X: ", i);
343
			DRM_LOG_KMS("\n %02X: ", i);
320
		ch7xxx_readb(dvo, i, &val);
344
		ch7xxx_readb(dvo, i, &val);
321
		DRM_LOG_KMS("%02X ", val);
345
		DRM_LOG_KMS("%02X ", val);
322
	}
346
	}
323
}
347
}
324
 
348
 
325
static void ch7xxx_destroy(struct intel_dvo_device *dvo)
349
static void ch7xxx_destroy(struct intel_dvo_device *dvo)
326
{
350
{
327
	struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
351
	struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
328
 
352
 
329
	if (ch7xxx) {
353
	if (ch7xxx) {
330
		kfree(ch7xxx);
354
		kfree(ch7xxx);
331
		dvo->dev_priv = NULL;
355
		dvo->dev_priv = NULL;
332
	}
356
	}
333
}
357
}
334
 
358
 
335
struct intel_dvo_dev_ops ch7xxx_ops = {
359
struct intel_dvo_dev_ops ch7xxx_ops = {
336
	.init = ch7xxx_init,
360
	.init = ch7xxx_init,
337
	.detect = ch7xxx_detect,
361
	.detect = ch7xxx_detect,
338
	.mode_valid = ch7xxx_mode_valid,
362
	.mode_valid = ch7xxx_mode_valid,
339
	.mode_set = ch7xxx_mode_set,
363
	.mode_set = ch7xxx_mode_set,
340
	.dpms = ch7xxx_dpms,
364
	.dpms = ch7xxx_dpms,
341
	.get_hw_state = ch7xxx_get_hw_state,
365
	.get_hw_state = ch7xxx_get_hw_state,
342
	.dump_regs = ch7xxx_dump_regs,
366
	.dump_regs = ch7xxx_dump_regs,
343
	.destroy = ch7xxx_destroy,
367
	.destroy = ch7xxx_destroy,
344
};
368
};
345
 
369
 
346
/**>
370
/**>
347
 
371
 
348
/**>
372
/**>
349
#define>
373
#define>
350
#define>
374
#define>
351
 
375
 
352
#define>
376
#define>
353
 
377
 
354
#define>
378
#define>
355
#define>
379
#define>
356
#define>
380
#define>
357
#define>
381
#define>
358
#define>
382
#define>
359
#define>
383
#define>
360
#define>
384
#define>
361
#define>
385
#define>
362
#define>
386
#define>
363
#define>
387
#define>
364
#define>
388
#define>
365
 
389
 
366
#define>
390
#define>
367
 
391
 
368
#define>
392
#define>
369
 
393
 
370
#define>
394
#define>
371
 
395
 
372
#define>
396
#define>
373
#define>
397
#define>
374
#define>
398
#define>
375
#define>
399
#define>
376
#define>
400
#define>
377
#define>
401
#define>
378
#define>
402
#define>
379
#define>
403
#define>
380
#define>
404
#define>