xref: /dflybsd-src/sys/dev/drm/i915/dvo_tfp410.c (revision bf0175970ba1c394f8039834a26ca6d163b23d0e)
1ba55f2f5SFrançois Tigeot /*
2ba55f2f5SFrançois Tigeot  * Copyright © 2007 Dave Mueller
3ba55f2f5SFrançois Tigeot  *
4ba55f2f5SFrançois Tigeot  * Permission is hereby granted, free of charge, to any person obtaining a
5ba55f2f5SFrançois Tigeot  * copy of this software and associated documentation files (the "Software"),
6ba55f2f5SFrançois Tigeot  * to deal in the Software without restriction, including without limitation
7ba55f2f5SFrançois Tigeot  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8ba55f2f5SFrançois Tigeot  * and/or sell copies of the Software, and to permit persons to whom the
9ba55f2f5SFrançois Tigeot  * Software is furnished to do so, subject to the following conditions:
10ba55f2f5SFrançois Tigeot  *
11ba55f2f5SFrançois Tigeot  * The above copyright notice and this permission notice (including the next
12ba55f2f5SFrançois Tigeot  * paragraph) shall be included in all copies or substantial portions of the
13ba55f2f5SFrançois Tigeot  * Software.
14ba55f2f5SFrançois Tigeot  *
15ba55f2f5SFrançois Tigeot  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16ba55f2f5SFrançois Tigeot  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17ba55f2f5SFrançois Tigeot  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18ba55f2f5SFrançois Tigeot  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19ba55f2f5SFrançois Tigeot  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20ba55f2f5SFrançois Tigeot  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21ba55f2f5SFrançois Tigeot  * IN THE SOFTWARE.
22ba55f2f5SFrançois Tigeot  *
23ba55f2f5SFrançois Tigeot  * Authors:
24ba55f2f5SFrançois Tigeot  *    Dave Mueller <dave.mueller@gmx.ch>
25ba55f2f5SFrançois Tigeot  *
26ba55f2f5SFrançois Tigeot  */
27ba55f2f5SFrançois Tigeot 
28ba55f2f5SFrançois Tigeot #include "dvo.h"
29ba55f2f5SFrançois Tigeot 
30ba55f2f5SFrançois Tigeot /* register definitions according to the TFP410 data sheet */
31ba55f2f5SFrançois Tigeot #define TFP410_VID		0x014C
32ba55f2f5SFrançois Tigeot #define TFP410_DID		0x0410
33ba55f2f5SFrançois Tigeot 
34ba55f2f5SFrançois Tigeot #define TFP410_VID_LO		0x00
35ba55f2f5SFrançois Tigeot #define TFP410_VID_HI		0x01
36ba55f2f5SFrançois Tigeot #define TFP410_DID_LO		0x02
37ba55f2f5SFrançois Tigeot #define TFP410_DID_HI		0x03
38ba55f2f5SFrançois Tigeot #define TFP410_REV		0x04
39ba55f2f5SFrançois Tigeot 
40ba55f2f5SFrançois Tigeot #define TFP410_CTL_1		0x08
41ba55f2f5SFrançois Tigeot #define TFP410_CTL_1_TDIS	(1<<6)
42ba55f2f5SFrançois Tigeot #define TFP410_CTL_1_VEN	(1<<5)
43ba55f2f5SFrançois Tigeot #define TFP410_CTL_1_HEN	(1<<4)
44ba55f2f5SFrançois Tigeot #define TFP410_CTL_1_DSEL	(1<<3)
45ba55f2f5SFrançois Tigeot #define TFP410_CTL_1_BSEL	(1<<2)
46ba55f2f5SFrançois Tigeot #define TFP410_CTL_1_EDGE	(1<<1)
47ba55f2f5SFrançois Tigeot #define TFP410_CTL_1_PD		(1<<0)
48ba55f2f5SFrançois Tigeot 
49ba55f2f5SFrançois Tigeot #define TFP410_CTL_2		0x09
50ba55f2f5SFrançois Tigeot #define TFP410_CTL_2_VLOW	(1<<7)
51ba55f2f5SFrançois Tigeot #define TFP410_CTL_2_MSEL_MASK	(0x7<<4)
52ba55f2f5SFrançois Tigeot #define TFP410_CTL_2_MSEL	(1<<4)
53ba55f2f5SFrançois Tigeot #define TFP410_CTL_2_TSEL	(1<<3)
54ba55f2f5SFrançois Tigeot #define TFP410_CTL_2_RSEN	(1<<2)
55ba55f2f5SFrançois Tigeot #define TFP410_CTL_2_HTPLG	(1<<1)
56ba55f2f5SFrançois Tigeot #define TFP410_CTL_2_MDI	(1<<0)
57ba55f2f5SFrançois Tigeot 
58ba55f2f5SFrançois Tigeot #define TFP410_CTL_3		0x0A
59ba55f2f5SFrançois Tigeot #define TFP410_CTL_3_DK_MASK	(0x7<<5)
60ba55f2f5SFrançois Tigeot #define TFP410_CTL_3_DK		(1<<5)
61ba55f2f5SFrançois Tigeot #define TFP410_CTL_3_DKEN	(1<<4)
62ba55f2f5SFrançois Tigeot #define TFP410_CTL_3_CTL_MASK	(0x7<<1)
63ba55f2f5SFrançois Tigeot #define TFP410_CTL_3_CTL	(1<<1)
64ba55f2f5SFrançois Tigeot 
65ba55f2f5SFrançois Tigeot #define TFP410_USERCFG		0x0B
66ba55f2f5SFrançois Tigeot 
67ba55f2f5SFrançois Tigeot #define TFP410_DE_DLY		0x32
68ba55f2f5SFrançois Tigeot 
69ba55f2f5SFrançois Tigeot #define TFP410_DE_CTL		0x33
70ba55f2f5SFrançois Tigeot #define TFP410_DE_CTL_DEGEN	(1<<6)
71ba55f2f5SFrançois Tigeot #define TFP410_DE_CTL_VSPOL	(1<<5)
72ba55f2f5SFrançois Tigeot #define TFP410_DE_CTL_HSPOL	(1<<4)
73ba55f2f5SFrançois Tigeot #define TFP410_DE_CTL_DEDLY8	(1<<0)
74ba55f2f5SFrançois Tigeot 
75ba55f2f5SFrançois Tigeot #define TFP410_DE_TOP		0x34
76ba55f2f5SFrançois Tigeot 
77ba55f2f5SFrançois Tigeot #define TFP410_DE_CNT_LO	0x36
78ba55f2f5SFrançois Tigeot #define TFP410_DE_CNT_HI	0x37
79ba55f2f5SFrançois Tigeot 
80ba55f2f5SFrançois Tigeot #define TFP410_DE_LIN_LO	0x38
81ba55f2f5SFrançois Tigeot #define TFP410_DE_LIN_HI	0x39
82ba55f2f5SFrançois Tigeot 
83ba55f2f5SFrançois Tigeot #define TFP410_H_RES_LO		0x3A
84ba55f2f5SFrançois Tigeot #define TFP410_H_RES_HI		0x3B
85ba55f2f5SFrançois Tigeot 
86ba55f2f5SFrançois Tigeot #define TFP410_V_RES_LO		0x3C
87ba55f2f5SFrançois Tigeot #define TFP410_V_RES_HI		0x3D
88ba55f2f5SFrançois Tigeot 
89ba55f2f5SFrançois Tigeot struct tfp410_priv {
90ba55f2f5SFrançois Tigeot 	bool quiet;
91ba55f2f5SFrançois Tigeot };
92ba55f2f5SFrançois Tigeot 
tfp410_readb(struct intel_dvo_device * dvo,int addr,uint8_t * ch)93ba55f2f5SFrançois Tigeot static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
94ba55f2f5SFrançois Tigeot {
95ba55f2f5SFrançois Tigeot 	struct tfp410_priv *tfp = dvo->dev_priv;
96ba55f2f5SFrançois Tigeot 	struct i2c_adapter *adapter = dvo->i2c_bus;
97ba55f2f5SFrançois Tigeot 	u8 out_buf[2];
98ba55f2f5SFrançois Tigeot 	u8 in_buf[2];
99ba55f2f5SFrançois Tigeot 
100ba55f2f5SFrançois Tigeot 	struct i2c_msg msgs[] = {
101ba55f2f5SFrançois Tigeot 		{
1029f4ca867SFrançois Tigeot 			.addr = dvo->slave_addr,
103ba55f2f5SFrançois Tigeot 			.flags = 0,
104ba55f2f5SFrançois Tigeot 			.len = 1,
105ba55f2f5SFrançois Tigeot 			.buf = out_buf,
106ba55f2f5SFrançois Tigeot 		},
107ba55f2f5SFrançois Tigeot 		{
1089f4ca867SFrançois Tigeot 			.addr = dvo->slave_addr,
109ba55f2f5SFrançois Tigeot 			.flags = I2C_M_RD,
110ba55f2f5SFrançois Tigeot 			.len = 1,
111ba55f2f5SFrançois Tigeot 			.buf = in_buf,
112ba55f2f5SFrançois Tigeot 		}
113ba55f2f5SFrançois Tigeot 	};
114ba55f2f5SFrançois Tigeot 
115ba55f2f5SFrançois Tigeot 	out_buf[0] = addr;
116ba55f2f5SFrançois Tigeot 	out_buf[1] = 0;
117ba55f2f5SFrançois Tigeot 
1189f4ca867SFrançois Tigeot 	if (i2c_transfer(adapter, msgs, 2) == 2) {
119ba55f2f5SFrançois Tigeot 		*ch = in_buf[0];
120ba55f2f5SFrançois Tigeot 		return true;
121ba55f2f5SFrançois Tigeot 	}
122ba55f2f5SFrançois Tigeot 
123ba55f2f5SFrançois Tigeot 	if (!tfp->quiet) {
124ba55f2f5SFrançois Tigeot 		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
1259f4ca867SFrançois Tigeot 			  addr, adapter->name, dvo->slave_addr);
126ba55f2f5SFrançois Tigeot 	}
127ba55f2f5SFrançois Tigeot 	return false;
128ba55f2f5SFrançois Tigeot }
129ba55f2f5SFrançois Tigeot 
tfp410_writeb(struct intel_dvo_device * dvo,int addr,uint8_t ch)130ba55f2f5SFrançois Tigeot static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
131ba55f2f5SFrançois Tigeot {
132ba55f2f5SFrançois Tigeot 	struct tfp410_priv *tfp = dvo->dev_priv;
133ba55f2f5SFrançois Tigeot 	struct i2c_adapter *adapter = dvo->i2c_bus;
134ba55f2f5SFrançois Tigeot 	uint8_t out_buf[2];
135ba55f2f5SFrançois Tigeot 	struct i2c_msg msg = {
1369f4ca867SFrançois Tigeot 		.addr = dvo->slave_addr,
137ba55f2f5SFrançois Tigeot 		.flags = 0,
138ba55f2f5SFrançois Tigeot 		.len = 2,
139ba55f2f5SFrançois Tigeot 		.buf = out_buf,
140ba55f2f5SFrançois Tigeot 	};
141ba55f2f5SFrançois Tigeot 
142ba55f2f5SFrançois Tigeot 	out_buf[0] = addr;
143ba55f2f5SFrançois Tigeot 	out_buf[1] = ch;
144ba55f2f5SFrançois Tigeot 
1459f4ca867SFrançois Tigeot 	if (i2c_transfer(adapter, &msg, 1) == 1)
146ba55f2f5SFrançois Tigeot 		return true;
147ba55f2f5SFrançois Tigeot 
148ba55f2f5SFrançois Tigeot 	if (!tfp->quiet) {
149ba55f2f5SFrançois Tigeot 		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
1509f4ca867SFrançois Tigeot 			  addr, adapter->name, dvo->slave_addr);
151ba55f2f5SFrançois Tigeot 	}
152ba55f2f5SFrançois Tigeot 
153ba55f2f5SFrançois Tigeot 	return false;
154ba55f2f5SFrançois Tigeot }
155ba55f2f5SFrançois Tigeot 
tfp410_getid(struct intel_dvo_device * dvo,int addr)156ba55f2f5SFrançois Tigeot static int tfp410_getid(struct intel_dvo_device *dvo, int addr)
157ba55f2f5SFrançois Tigeot {
158ba55f2f5SFrançois Tigeot 	uint8_t ch1, ch2;
159ba55f2f5SFrançois Tigeot 
160ba55f2f5SFrançois Tigeot 	if (tfp410_readb(dvo, addr+0, &ch1) &&
161ba55f2f5SFrançois Tigeot 	    tfp410_readb(dvo, addr+1, &ch2))
162ba55f2f5SFrançois Tigeot 		return ((ch2 << 8) & 0xFF00) | (ch1 & 0x00FF);
163ba55f2f5SFrançois Tigeot 
164ba55f2f5SFrançois Tigeot 	return -1;
165ba55f2f5SFrançois Tigeot }
166ba55f2f5SFrançois Tigeot 
167ba55f2f5SFrançois Tigeot /* Ti TFP410 driver for chip on i2c bus */
tfp410_init(struct intel_dvo_device * dvo,struct i2c_adapter * adapter)168ba55f2f5SFrançois Tigeot static bool tfp410_init(struct intel_dvo_device *dvo,
169ba55f2f5SFrançois Tigeot 			struct i2c_adapter *adapter)
170ba55f2f5SFrançois Tigeot {
171ba55f2f5SFrançois Tigeot 	/* this will detect the tfp410 chip on the specified i2c bus */
172ba55f2f5SFrançois Tigeot 	struct tfp410_priv *tfp;
173ba55f2f5SFrançois Tigeot 	int id;
174ba55f2f5SFrançois Tigeot 
175ba55f2f5SFrançois Tigeot 	tfp = kzalloc(sizeof(struct tfp410_priv), GFP_KERNEL);
176ba55f2f5SFrançois Tigeot 	if (tfp == NULL)
177ba55f2f5SFrançois Tigeot 		return false;
178ba55f2f5SFrançois Tigeot 
179ba55f2f5SFrançois Tigeot 	dvo->i2c_bus = adapter;
180ba55f2f5SFrançois Tigeot 	dvo->dev_priv = tfp;
181ba55f2f5SFrançois Tigeot 	tfp->quiet = true;
182ba55f2f5SFrançois Tigeot 
183ba55f2f5SFrançois Tigeot 	if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) {
184ba55f2f5SFrançois Tigeot 		DRM_DEBUG_KMS("tfp410 not detected got VID %X: from %s "
185ba55f2f5SFrançois Tigeot 				"Slave %d.\n",
1869f4ca867SFrançois Tigeot 			  id, adapter->name, dvo->slave_addr);
187ba55f2f5SFrançois Tigeot 		goto out;
188ba55f2f5SFrançois Tigeot 	}
189ba55f2f5SFrançois Tigeot 
190ba55f2f5SFrançois Tigeot 	if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) {
191ba55f2f5SFrançois Tigeot 		DRM_DEBUG_KMS("tfp410 not detected got DID %X: from %s "
192ba55f2f5SFrançois Tigeot 				"Slave %d.\n",
1939f4ca867SFrançois Tigeot 			  id, adapter->name, dvo->slave_addr);
194ba55f2f5SFrançois Tigeot 		goto out;
195ba55f2f5SFrançois Tigeot 	}
196ba55f2f5SFrançois Tigeot 	tfp->quiet = false;
197ba55f2f5SFrançois Tigeot 	return true;
198ba55f2f5SFrançois Tigeot out:
199ba55f2f5SFrançois Tigeot 	kfree(tfp);
200ba55f2f5SFrançois Tigeot 	return false;
201ba55f2f5SFrançois Tigeot }
202ba55f2f5SFrançois Tigeot 
tfp410_detect(struct intel_dvo_device * dvo)203ba55f2f5SFrançois Tigeot static enum drm_connector_status tfp410_detect(struct intel_dvo_device *dvo)
204ba55f2f5SFrançois Tigeot {
205ba55f2f5SFrançois Tigeot 	enum drm_connector_status ret = connector_status_disconnected;
206ba55f2f5SFrançois Tigeot 	uint8_t ctl2;
207ba55f2f5SFrançois Tigeot 
208ba55f2f5SFrançois Tigeot 	if (tfp410_readb(dvo, TFP410_CTL_2, &ctl2)) {
209ba55f2f5SFrançois Tigeot 		if (ctl2 & TFP410_CTL_2_RSEN)
210ba55f2f5SFrançois Tigeot 			ret = connector_status_connected;
211ba55f2f5SFrançois Tigeot 		else
212ba55f2f5SFrançois Tigeot 			ret = connector_status_disconnected;
213ba55f2f5SFrançois Tigeot 	}
214ba55f2f5SFrançois Tigeot 
215ba55f2f5SFrançois Tigeot 	return ret;
216ba55f2f5SFrançois Tigeot }
217ba55f2f5SFrançois Tigeot 
tfp410_mode_valid(struct intel_dvo_device * dvo,struct drm_display_mode * mode)218ba55f2f5SFrançois Tigeot static enum drm_mode_status tfp410_mode_valid(struct intel_dvo_device *dvo,
219ba55f2f5SFrançois Tigeot 					      struct drm_display_mode *mode)
220ba55f2f5SFrançois Tigeot {
221ba55f2f5SFrançois Tigeot 	return MODE_OK;
222ba55f2f5SFrançois Tigeot }
223ba55f2f5SFrançois Tigeot 
tfp410_mode_set(struct intel_dvo_device * dvo,const struct drm_display_mode * mode,const struct drm_display_mode * adjusted_mode)224ba55f2f5SFrançois Tigeot static void tfp410_mode_set(struct intel_dvo_device *dvo,
225352ff8bdSFrançois Tigeot 			    const struct drm_display_mode *mode,
226352ff8bdSFrançois Tigeot 			    const struct drm_display_mode *adjusted_mode)
227ba55f2f5SFrançois Tigeot {
228ba55f2f5SFrançois Tigeot 	/* As long as the basics are set up, since we don't have clock dependencies
229ba55f2f5SFrançois Tigeot 	* in the mode setup, we can just leave the registers alone and everything
230ba55f2f5SFrançois Tigeot 	* will work fine.
231ba55f2f5SFrançois Tigeot 	*/
232ba55f2f5SFrançois Tigeot 	/* don't do much */
233ba55f2f5SFrançois Tigeot 	return;
234ba55f2f5SFrançois Tigeot }
235ba55f2f5SFrançois Tigeot 
236ba55f2f5SFrançois Tigeot /* set the tfp410 power state */
tfp410_dpms(struct intel_dvo_device * dvo,bool enable)237ba55f2f5SFrançois Tigeot static void tfp410_dpms(struct intel_dvo_device *dvo, bool enable)
238ba55f2f5SFrançois Tigeot {
239ba55f2f5SFrançois Tigeot 	uint8_t ctl1;
240ba55f2f5SFrançois Tigeot 
241ba55f2f5SFrançois Tigeot 	if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1))
242ba55f2f5SFrançois Tigeot 		return;
243ba55f2f5SFrançois Tigeot 
244ba55f2f5SFrançois Tigeot 	if (enable)
245ba55f2f5SFrançois Tigeot 		ctl1 |= TFP410_CTL_1_PD;
246ba55f2f5SFrançois Tigeot 	else
247ba55f2f5SFrançois Tigeot 		ctl1 &= ~TFP410_CTL_1_PD;
248ba55f2f5SFrançois Tigeot 
249ba55f2f5SFrançois Tigeot 	tfp410_writeb(dvo, TFP410_CTL_1, ctl1);
250ba55f2f5SFrançois Tigeot }
251ba55f2f5SFrançois Tigeot 
tfp410_get_hw_state(struct intel_dvo_device * dvo)252ba55f2f5SFrançois Tigeot static bool tfp410_get_hw_state(struct intel_dvo_device *dvo)
253ba55f2f5SFrançois Tigeot {
254ba55f2f5SFrançois Tigeot 	uint8_t ctl1;
255ba55f2f5SFrançois Tigeot 
256ba55f2f5SFrançois Tigeot 	if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1))
257ba55f2f5SFrançois Tigeot 		return false;
258ba55f2f5SFrançois Tigeot 
259ba55f2f5SFrançois Tigeot 	if (ctl1 & TFP410_CTL_1_PD)
260ba55f2f5SFrançois Tigeot 		return true;
261ba55f2f5SFrançois Tigeot 	else
262ba55f2f5SFrançois Tigeot 		return false;
263ba55f2f5SFrançois Tigeot }
264ba55f2f5SFrançois Tigeot 
tfp410_dump_regs(struct intel_dvo_device * dvo)265ba55f2f5SFrançois Tigeot static void tfp410_dump_regs(struct intel_dvo_device *dvo)
266ba55f2f5SFrançois Tigeot {
267ba55f2f5SFrançois Tigeot 	uint8_t val, val2;
268ba55f2f5SFrançois Tigeot 
269ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_REV, &val);
270ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_REV: 0x%02X\n", val);
271ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_CTL_1, &val);
272ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_CTL1: 0x%02X\n", val);
273ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_CTL_2, &val);
274ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_CTL2: 0x%02X\n", val);
275ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_CTL_3, &val);
276ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_CTL3: 0x%02X\n", val);
277ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_USERCFG, &val);
278ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_USERCFG: 0x%02X\n", val);
279ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_DE_DLY, &val);
280ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_DE_DLY: 0x%02X\n", val);
281ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_DE_CTL, &val);
282ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_DE_CTL: 0x%02X\n", val);
283ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_DE_TOP, &val);
284ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_DE_TOP: 0x%02X\n", val);
285ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_DE_CNT_LO, &val);
286ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_DE_CNT_HI, &val2);
287ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_DE_CNT: 0x%02X%02X\n", val2, val);
288ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_DE_LIN_LO, &val);
289ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_DE_LIN_HI, &val2);
290ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_DE_LIN: 0x%02X%02X\n", val2, val);
291ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_H_RES_LO, &val);
292ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_H_RES_HI, &val2);
293ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_H_RES: 0x%02X%02X\n", val2, val);
294ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_V_RES_LO, &val);
295ba55f2f5SFrançois Tigeot 	tfp410_readb(dvo, TFP410_V_RES_HI, &val2);
296ba55f2f5SFrançois Tigeot 	DRM_DEBUG_KMS("TFP410_V_RES: 0x%02X%02X\n", val2, val);
297ba55f2f5SFrançois Tigeot }
298ba55f2f5SFrançois Tigeot 
tfp410_destroy(struct intel_dvo_device * dvo)299ba55f2f5SFrançois Tigeot static void tfp410_destroy(struct intel_dvo_device *dvo)
300ba55f2f5SFrançois Tigeot {
301ba55f2f5SFrançois Tigeot 	struct tfp410_priv *tfp = dvo->dev_priv;
302ba55f2f5SFrançois Tigeot 
303ba55f2f5SFrançois Tigeot 	if (tfp) {
304ba55f2f5SFrançois Tigeot 		kfree(tfp);
305ba55f2f5SFrançois Tigeot 		dvo->dev_priv = NULL;
306ba55f2f5SFrançois Tigeot 	}
307ba55f2f5SFrançois Tigeot }
308ba55f2f5SFrançois Tigeot 
309*aee94f86SFrançois Tigeot const struct intel_dvo_dev_ops tfp410_ops = {
310ba55f2f5SFrançois Tigeot 	.init = tfp410_init,
311ba55f2f5SFrançois Tigeot 	.detect = tfp410_detect,
312ba55f2f5SFrançois Tigeot 	.mode_valid = tfp410_mode_valid,
313ba55f2f5SFrançois Tigeot 	.mode_set = tfp410_mode_set,
314ba55f2f5SFrançois Tigeot 	.dpms = tfp410_dpms,
315ba55f2f5SFrançois Tigeot 	.get_hw_state = tfp410_get_hw_state,
316ba55f2f5SFrançois Tigeot 	.dump_regs = tfp410_dump_regs,
317ba55f2f5SFrançois Tigeot 	.destroy = tfp410_destroy,
318ba55f2f5SFrançois Tigeot };
319