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