1379bc100SJani Nikula /**************************************************************************
2379bc100SJani Nikula
3379bc100SJani Nikula Copyright © 2006 Dave Airlie
4379bc100SJani Nikula
5379bc100SJani Nikula All Rights Reserved.
6379bc100SJani Nikula
7379bc100SJani Nikula Permission is hereby granted, free of charge, to any person obtaining a
8379bc100SJani Nikula copy of this software and associated documentation files (the
9379bc100SJani Nikula "Software"), to deal in the Software without restriction, including
10379bc100SJani Nikula without limitation the rights to use, copy, modify, merge, publish,
11379bc100SJani Nikula distribute, sub license, and/or sell copies of the Software, and to
12379bc100SJani Nikula permit persons to whom the Software is furnished to do so, subject to
13379bc100SJani Nikula the following conditions:
14379bc100SJani Nikula
15379bc100SJani Nikula The above copyright notice and this permission notice (including the
16379bc100SJani Nikula next paragraph) shall be included in all copies or substantial portions
17379bc100SJani Nikula of the Software.
18379bc100SJani Nikula
19379bc100SJani Nikula THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20379bc100SJani Nikula OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21379bc100SJani Nikula MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22379bc100SJani Nikula IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
23379bc100SJani Nikula ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24379bc100SJani Nikula TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25379bc100SJani Nikula SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26379bc100SJani Nikula
27379bc100SJani Nikula **************************************************************************/
28379bc100SJani Nikula
291d455f8dSJani Nikula #include "intel_display_types.h"
30379bc100SJani Nikula #include "intel_dvo_dev.h"
31379bc100SJani Nikula
32379bc100SJani Nikula #define CH7xxx_REG_VID 0x4a
33379bc100SJani Nikula #define CH7xxx_REG_DID 0x4b
34379bc100SJani Nikula
35379bc100SJani Nikula #define CH7011_VID 0x83 /* 7010 as well */
36379bc100SJani Nikula #define CH7010B_VID 0x05
37379bc100SJani Nikula #define CH7009A_VID 0x84
38379bc100SJani Nikula #define CH7009B_VID 0x85
39379bc100SJani Nikula #define CH7301_VID 0x95
40379bc100SJani Nikula
41379bc100SJani Nikula #define CH7xxx_VID 0x84
42379bc100SJani Nikula #define CH7xxx_DID 0x17
43379bc100SJani Nikula #define CH7010_DID 0x16
44379bc100SJani Nikula
45379bc100SJani Nikula #define CH7xxx_NUM_REGS 0x4c
46379bc100SJani Nikula
47379bc100SJani Nikula #define CH7xxx_CM 0x1c
48379bc100SJani Nikula #define CH7xxx_CM_XCM (1<<0)
49379bc100SJani Nikula #define CH7xxx_CM_MCP (1<<2)
50379bc100SJani Nikula #define CH7xxx_INPUT_CLOCK 0x1d
51379bc100SJani Nikula #define CH7xxx_GPIO 0x1e
52379bc100SJani Nikula #define CH7xxx_GPIO_HPIR (1<<3)
53379bc100SJani Nikula
54*6ad0571bSVille Syrjälä #define CH7xxx_IDF 0x1f
55*6ad0571bSVille Syrjälä #define CH7xxx_IDF_IBS (1<<7)
56*6ad0571bSVille Syrjälä #define CH7xxx_IDF_DES (1<<6)
57379bc100SJani Nikula #define CH7xxx_IDF_HSP (1<<3)
58379bc100SJani Nikula #define CH7xxx_IDF_VSP (1<<4)
59379bc100SJani Nikula
60379bc100SJani Nikula #define CH7xxx_CONNECTION_DETECT 0x20
61379bc100SJani Nikula #define CH7xxx_CDET_DVI (1<<5)
62379bc100SJani Nikula
63*6ad0571bSVille Syrjälä #define CH7xxx_DAC_CNTL 0x21
64*6ad0571bSVille Syrjälä #define CH7xxx_SYNCO_MASK (3 << 3)
65*6ad0571bSVille Syrjälä #define CH7xxx_SYNCO_VGA_HSYNC (1 << 3)
66*6ad0571bSVille Syrjälä
67*6ad0571bSVille Syrjälä #define CH7xxx_CLOCK_OUTPUT 0x22
68*6ad0571bSVille Syrjälä #define CH7xxx_BCOEN (1 << 4)
69*6ad0571bSVille Syrjälä #define CH7xxx_BCOP (1 << 3)
70*6ad0571bSVille Syrjälä #define CH7xxx_BCO_MASK (7 << 0)
71*6ad0571bSVille Syrjälä #define CH7xxx_BCO_VGA_VSYNC (6 << 0)
72*6ad0571bSVille Syrjälä
73379bc100SJani Nikula #define CH7301_HOTPLUG 0x23
74379bc100SJani Nikula #define CH7xxx_TCTL 0x31
75379bc100SJani Nikula #define CH7xxx_TVCO 0x32
76379bc100SJani Nikula #define CH7xxx_TPCP 0x33
77379bc100SJani Nikula #define CH7xxx_TPD 0x34
78379bc100SJani Nikula #define CH7xxx_TPVT 0x35
79379bc100SJani Nikula #define CH7xxx_TLPF 0x36
80379bc100SJani Nikula #define CH7xxx_TCT 0x37
81379bc100SJani Nikula #define CH7301_TEST_PATTERN 0x48
82379bc100SJani Nikula
83379bc100SJani Nikula #define CH7xxx_PM 0x49
84379bc100SJani Nikula #define CH7xxx_PM_FPD (1<<0)
85379bc100SJani Nikula #define CH7301_PM_DACPD0 (1<<1)
86379bc100SJani Nikula #define CH7301_PM_DACPD1 (1<<2)
87379bc100SJani Nikula #define CH7301_PM_DACPD2 (1<<3)
88379bc100SJani Nikula #define CH7xxx_PM_DVIL (1<<6)
89379bc100SJani Nikula #define CH7xxx_PM_DVIP (1<<7)
90379bc100SJani Nikula
91379bc100SJani Nikula #define CH7301_SYNC_POLARITY 0x56
92379bc100SJani Nikula #define CH7301_SYNC_RGB_YUV (1<<0)
93379bc100SJani Nikula #define CH7301_SYNC_POL_DVI (1<<5)
94379bc100SJani Nikula
95379bc100SJani Nikula /** @file
96379bc100SJani Nikula * driver for the Chrontel 7xxx DVI chip over DVO.
97379bc100SJani Nikula */
98379bc100SJani Nikula
99379bc100SJani Nikula static struct ch7xxx_id_struct {
100379bc100SJani Nikula u8 vid;
101379bc100SJani Nikula char *name;
102379bc100SJani Nikula } ch7xxx_ids[] = {
103379bc100SJani Nikula { CH7011_VID, "CH7011" },
104379bc100SJani Nikula { CH7010B_VID, "CH7010B" },
105379bc100SJani Nikula { CH7009A_VID, "CH7009A" },
106379bc100SJani Nikula { CH7009B_VID, "CH7009B" },
107379bc100SJani Nikula { CH7301_VID, "CH7301" },
108379bc100SJani Nikula };
109379bc100SJani Nikula
110379bc100SJani Nikula static struct ch7xxx_did_struct {
111379bc100SJani Nikula u8 did;
112379bc100SJani Nikula char *name;
113379bc100SJani Nikula } ch7xxx_dids[] = {
114379bc100SJani Nikula { CH7xxx_DID, "CH7XXX" },
115379bc100SJani Nikula { CH7010_DID, "CH7010B" },
116379bc100SJani Nikula };
117379bc100SJani Nikula
118379bc100SJani Nikula struct ch7xxx_priv {
119379bc100SJani Nikula bool quiet;
120379bc100SJani Nikula };
121379bc100SJani Nikula
ch7xxx_get_id(u8 vid)122379bc100SJani Nikula static char *ch7xxx_get_id(u8 vid)
123379bc100SJani Nikula {
124379bc100SJani Nikula int i;
125379bc100SJani Nikula
126379bc100SJani Nikula for (i = 0; i < ARRAY_SIZE(ch7xxx_ids); i++) {
127379bc100SJani Nikula if (ch7xxx_ids[i].vid == vid)
128379bc100SJani Nikula return ch7xxx_ids[i].name;
129379bc100SJani Nikula }
130379bc100SJani Nikula
131379bc100SJani Nikula return NULL;
132379bc100SJani Nikula }
133379bc100SJani Nikula
ch7xxx_get_did(u8 did)134379bc100SJani Nikula static char *ch7xxx_get_did(u8 did)
135379bc100SJani Nikula {
136379bc100SJani Nikula int i;
137379bc100SJani Nikula
138379bc100SJani Nikula for (i = 0; i < ARRAY_SIZE(ch7xxx_dids); i++) {
139379bc100SJani Nikula if (ch7xxx_dids[i].did == did)
140379bc100SJani Nikula return ch7xxx_dids[i].name;
141379bc100SJani Nikula }
142379bc100SJani Nikula
143379bc100SJani Nikula return NULL;
144379bc100SJani Nikula }
145379bc100SJani Nikula
146379bc100SJani Nikula /** Reads an 8 bit register */
ch7xxx_readb(struct intel_dvo_device * dvo,int addr,u8 * ch)147379bc100SJani Nikula static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, u8 *ch)
148379bc100SJani Nikula {
149379bc100SJani Nikula struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
150379bc100SJani Nikula struct i2c_adapter *adapter = dvo->i2c_bus;
151379bc100SJani Nikula u8 out_buf[2];
152379bc100SJani Nikula u8 in_buf[2];
153379bc100SJani Nikula
154379bc100SJani Nikula struct i2c_msg msgs[] = {
155379bc100SJani Nikula {
156379bc100SJani Nikula .addr = dvo->slave_addr,
157379bc100SJani Nikula .flags = 0,
158379bc100SJani Nikula .len = 1,
159379bc100SJani Nikula .buf = out_buf,
160379bc100SJani Nikula },
161379bc100SJani Nikula {
162379bc100SJani Nikula .addr = dvo->slave_addr,
163379bc100SJani Nikula .flags = I2C_M_RD,
164379bc100SJani Nikula .len = 1,
165379bc100SJani Nikula .buf = in_buf,
166379bc100SJani Nikula }
167379bc100SJani Nikula };
168379bc100SJani Nikula
169379bc100SJani Nikula out_buf[0] = addr;
170379bc100SJani Nikula out_buf[1] = 0;
171379bc100SJani Nikula
172379bc100SJani Nikula if (i2c_transfer(adapter, msgs, 2) == 2) {
173379bc100SJani Nikula *ch = in_buf[0];
174379bc100SJani Nikula return true;
175379bc100SJani Nikula }
176379bc100SJani Nikula
177379bc100SJani Nikula if (!ch7xxx->quiet) {
178379bc100SJani Nikula DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
179379bc100SJani Nikula addr, adapter->name, dvo->slave_addr);
180379bc100SJani Nikula }
181379bc100SJani Nikula return false;
182379bc100SJani Nikula }
183379bc100SJani Nikula
184379bc100SJani Nikula /** Writes an 8 bit register */
ch7xxx_writeb(struct intel_dvo_device * dvo,int addr,u8 ch)185379bc100SJani Nikula static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, u8 ch)
186379bc100SJani Nikula {
187379bc100SJani Nikula struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
188379bc100SJani Nikula struct i2c_adapter *adapter = dvo->i2c_bus;
189379bc100SJani Nikula u8 out_buf[2];
190379bc100SJani Nikula struct i2c_msg msg = {
191379bc100SJani Nikula .addr = dvo->slave_addr,
192379bc100SJani Nikula .flags = 0,
193379bc100SJani Nikula .len = 2,
194379bc100SJani Nikula .buf = out_buf,
195379bc100SJani Nikula };
196379bc100SJani Nikula
197379bc100SJani Nikula out_buf[0] = addr;
198379bc100SJani Nikula out_buf[1] = ch;
199379bc100SJani Nikula
200379bc100SJani Nikula if (i2c_transfer(adapter, &msg, 1) == 1)
201379bc100SJani Nikula return true;
202379bc100SJani Nikula
203379bc100SJani Nikula if (!ch7xxx->quiet) {
204379bc100SJani Nikula DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
205379bc100SJani Nikula addr, adapter->name, dvo->slave_addr);
206379bc100SJani Nikula }
207379bc100SJani Nikula
208379bc100SJani Nikula return false;
209379bc100SJani Nikula }
210379bc100SJani Nikula
ch7xxx_init(struct intel_dvo_device * dvo,struct i2c_adapter * adapter)211379bc100SJani Nikula static bool ch7xxx_init(struct intel_dvo_device *dvo,
212379bc100SJani Nikula struct i2c_adapter *adapter)
213379bc100SJani Nikula {
214379bc100SJani Nikula /* this will detect the CH7xxx chip on the specified i2c bus */
215379bc100SJani Nikula struct ch7xxx_priv *ch7xxx;
216379bc100SJani Nikula u8 vendor, device;
217379bc100SJani Nikula char *name, *devid;
218379bc100SJani Nikula
219379bc100SJani Nikula ch7xxx = kzalloc(sizeof(struct ch7xxx_priv), GFP_KERNEL);
220379bc100SJani Nikula if (ch7xxx == NULL)
221379bc100SJani Nikula return false;
222379bc100SJani Nikula
223379bc100SJani Nikula dvo->i2c_bus = adapter;
224379bc100SJani Nikula dvo->dev_priv = ch7xxx;
225379bc100SJani Nikula ch7xxx->quiet = true;
226379bc100SJani Nikula
227379bc100SJani Nikula if (!ch7xxx_readb(dvo, CH7xxx_REG_VID, &vendor))
228379bc100SJani Nikula goto out;
229379bc100SJani Nikula
230379bc100SJani Nikula name = ch7xxx_get_id(vendor);
231379bc100SJani Nikula if (!name) {
232379bc100SJani Nikula DRM_DEBUG_KMS("ch7xxx not detected; got VID 0x%02x from %s slave %d.\n",
233379bc100SJani Nikula vendor, adapter->name, dvo->slave_addr);
234379bc100SJani Nikula goto out;
235379bc100SJani Nikula }
236379bc100SJani Nikula
237379bc100SJani Nikula
238379bc100SJani Nikula if (!ch7xxx_readb(dvo, CH7xxx_REG_DID, &device))
239379bc100SJani Nikula goto out;
240379bc100SJani Nikula
241379bc100SJani Nikula devid = ch7xxx_get_did(device);
242379bc100SJani Nikula if (!devid) {
243379bc100SJani Nikula DRM_DEBUG_KMS("ch7xxx not detected; got DID 0x%02x from %s slave %d.\n",
244379bc100SJani Nikula device, adapter->name, dvo->slave_addr);
245379bc100SJani Nikula goto out;
246379bc100SJani Nikula }
247379bc100SJani Nikula
248379bc100SJani Nikula ch7xxx->quiet = false;
249379bc100SJani Nikula DRM_DEBUG_KMS("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
250379bc100SJani Nikula name, vendor, device);
251379bc100SJani Nikula return true;
252379bc100SJani Nikula out:
253379bc100SJani Nikula kfree(ch7xxx);
254379bc100SJani Nikula return false;
255379bc100SJani Nikula }
256379bc100SJani Nikula
ch7xxx_detect(struct intel_dvo_device * dvo)257379bc100SJani Nikula static enum drm_connector_status ch7xxx_detect(struct intel_dvo_device *dvo)
258379bc100SJani Nikula {
259379bc100SJani Nikula u8 cdet, orig_pm, pm;
260379bc100SJani Nikula
261379bc100SJani Nikula ch7xxx_readb(dvo, CH7xxx_PM, &orig_pm);
262379bc100SJani Nikula
263379bc100SJani Nikula pm = orig_pm;
264379bc100SJani Nikula pm &= ~CH7xxx_PM_FPD;
265379bc100SJani Nikula pm |= CH7xxx_PM_DVIL | CH7xxx_PM_DVIP;
266379bc100SJani Nikula
267379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_PM, pm);
268379bc100SJani Nikula
269379bc100SJani Nikula ch7xxx_readb(dvo, CH7xxx_CONNECTION_DETECT, &cdet);
270379bc100SJani Nikula
271379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_PM, orig_pm);
272379bc100SJani Nikula
273379bc100SJani Nikula if (cdet & CH7xxx_CDET_DVI)
274379bc100SJani Nikula return connector_status_connected;
275379bc100SJani Nikula return connector_status_disconnected;
276379bc100SJani Nikula }
277379bc100SJani Nikula
ch7xxx_mode_valid(struct intel_dvo_device * dvo,struct drm_display_mode * mode)278379bc100SJani Nikula static enum drm_mode_status ch7xxx_mode_valid(struct intel_dvo_device *dvo,
279379bc100SJani Nikula struct drm_display_mode *mode)
280379bc100SJani Nikula {
281379bc100SJani Nikula if (mode->clock > 165000)
282379bc100SJani Nikula return MODE_CLOCK_HIGH;
283379bc100SJani Nikula
284379bc100SJani Nikula return MODE_OK;
285379bc100SJani Nikula }
286379bc100SJani Nikula
ch7xxx_mode_set(struct intel_dvo_device * dvo,const struct drm_display_mode * mode,const struct drm_display_mode * adjusted_mode)287379bc100SJani Nikula static void ch7xxx_mode_set(struct intel_dvo_device *dvo,
288379bc100SJani Nikula const struct drm_display_mode *mode,
289379bc100SJani Nikula const struct drm_display_mode *adjusted_mode)
290379bc100SJani Nikula {
291379bc100SJani Nikula u8 tvco, tpcp, tpd, tlpf, idf;
292379bc100SJani Nikula
293379bc100SJani Nikula if (mode->clock <= 65000) {
294379bc100SJani Nikula tvco = 0x23;
295379bc100SJani Nikula tpcp = 0x08;
296379bc100SJani Nikula tpd = 0x16;
297379bc100SJani Nikula tlpf = 0x60;
298379bc100SJani Nikula } else {
299379bc100SJani Nikula tvco = 0x2d;
300379bc100SJani Nikula tpcp = 0x06;
301379bc100SJani Nikula tpd = 0x26;
302379bc100SJani Nikula tlpf = 0xa0;
303379bc100SJani Nikula }
304379bc100SJani Nikula
305379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_TCTL, 0x00);
306379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_TVCO, tvco);
307379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_TPCP, tpcp);
308379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_TPD, tpd);
309379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_TPVT, 0x30);
310379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_TLPF, tlpf);
311379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_TCT, 0x00);
312379bc100SJani Nikula
313379bc100SJani Nikula ch7xxx_readb(dvo, CH7xxx_IDF, &idf);
314379bc100SJani Nikula
315*6ad0571bSVille Syrjälä idf |= CH7xxx_IDF_IBS;
316*6ad0571bSVille Syrjälä
317379bc100SJani Nikula idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP);
318379bc100SJani Nikula if (mode->flags & DRM_MODE_FLAG_PHSYNC)
319379bc100SJani Nikula idf |= CH7xxx_IDF_HSP;
320379bc100SJani Nikula
321379bc100SJani Nikula if (mode->flags & DRM_MODE_FLAG_PVSYNC)
322379bc100SJani Nikula idf |= CH7xxx_IDF_VSP;
323379bc100SJani Nikula
324379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_IDF, idf);
325*6ad0571bSVille Syrjälä
326*6ad0571bSVille Syrjälä ch7xxx_writeb(dvo, CH7xxx_DAC_CNTL,
327*6ad0571bSVille Syrjälä CH7xxx_SYNCO_VGA_HSYNC);
328*6ad0571bSVille Syrjälä ch7xxx_writeb(dvo, CH7xxx_CLOCK_OUTPUT,
329*6ad0571bSVille Syrjälä CH7xxx_BCOEN | CH7xxx_BCO_VGA_VSYNC);
330379bc100SJani Nikula }
331379bc100SJani Nikula
332379bc100SJani Nikula /* set the CH7xxx power state */
ch7xxx_dpms(struct intel_dvo_device * dvo,bool enable)333379bc100SJani Nikula static void ch7xxx_dpms(struct intel_dvo_device *dvo, bool enable)
334379bc100SJani Nikula {
335379bc100SJani Nikula if (enable)
336379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP);
337379bc100SJani Nikula else
338379bc100SJani Nikula ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD);
339379bc100SJani Nikula }
340379bc100SJani Nikula
ch7xxx_get_hw_state(struct intel_dvo_device * dvo)341379bc100SJani Nikula static bool ch7xxx_get_hw_state(struct intel_dvo_device *dvo)
342379bc100SJani Nikula {
343379bc100SJani Nikula u8 val;
344379bc100SJani Nikula
345379bc100SJani Nikula ch7xxx_readb(dvo, CH7xxx_PM, &val);
346379bc100SJani Nikula
347379bc100SJani Nikula if (val & (CH7xxx_PM_DVIL | CH7xxx_PM_DVIP))
348379bc100SJani Nikula return true;
349379bc100SJani Nikula else
350379bc100SJani Nikula return false;
351379bc100SJani Nikula }
352379bc100SJani Nikula
ch7xxx_dump_regs(struct intel_dvo_device * dvo)353379bc100SJani Nikula static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
354379bc100SJani Nikula {
355379bc100SJani Nikula int i;
356379bc100SJani Nikula
357379bc100SJani Nikula for (i = 0; i < CH7xxx_NUM_REGS; i++) {
358379bc100SJani Nikula u8 val;
359379bc100SJani Nikula if ((i % 8) == 0)
360379bc100SJani Nikula DRM_DEBUG_KMS("\n %02X: ", i);
361379bc100SJani Nikula ch7xxx_readb(dvo, i, &val);
362379bc100SJani Nikula DRM_DEBUG_KMS("%02X ", val);
363379bc100SJani Nikula }
364379bc100SJani Nikula }
365379bc100SJani Nikula
ch7xxx_destroy(struct intel_dvo_device * dvo)366379bc100SJani Nikula static void ch7xxx_destroy(struct intel_dvo_device *dvo)
367379bc100SJani Nikula {
368379bc100SJani Nikula struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
369379bc100SJani Nikula
370379bc100SJani Nikula if (ch7xxx) {
371379bc100SJani Nikula kfree(ch7xxx);
372379bc100SJani Nikula dvo->dev_priv = NULL;
373379bc100SJani Nikula }
374379bc100SJani Nikula }
375379bc100SJani Nikula
376379bc100SJani Nikula const struct intel_dvo_dev_ops ch7xxx_ops = {
377379bc100SJani Nikula .init = ch7xxx_init,
378379bc100SJani Nikula .detect = ch7xxx_detect,
379379bc100SJani Nikula .mode_valid = ch7xxx_mode_valid,
380379bc100SJani Nikula .mode_set = ch7xxx_mode_set,
381379bc100SJani Nikula .dpms = ch7xxx_dpms,
382379bc100SJani Nikula .get_hw_state = ch7xxx_get_hw_state,
383379bc100SJani Nikula .dump_regs = ch7xxx_dump_regs,
384379bc100SJani Nikula .destroy = ch7xxx_destroy,
385379bc100SJani Nikula };
386