Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.9.4.
  1/*
  2 *
  3 * Copyright (c) 2012 Gilles Dartiguelongue, Thomas Richter
  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 "dvo.h"
 30#include "i915_reg.h"
 31#include "i915_drv.h"
 32
 33#define NS2501_VID 0x1305
 34#define NS2501_DID 0x6726
 35
 36#define NS2501_VID_LO 0x00
 37#define NS2501_VID_HI 0x01
 38#define NS2501_DID_LO 0x02
 39#define NS2501_DID_HI 0x03
 40#define NS2501_REV 0x04
 41#define NS2501_RSVD 0x05
 42#define NS2501_FREQ_LO 0x06
 43#define NS2501_FREQ_HI 0x07
 44
 45#define NS2501_REG8 0x08
 46#define NS2501_8_VEN (1<<5)
 47#define NS2501_8_HEN (1<<4)
 48#define NS2501_8_DSEL (1<<3)
 49#define NS2501_8_BPAS (1<<2)
 50#define NS2501_8_RSVD (1<<1)
 51#define NS2501_8_PD (1<<0)
 52
 53#define NS2501_REG9 0x09
 54#define NS2501_9_VLOW (1<<7)
 55#define NS2501_9_MSEL_MASK (0x7<<4)
 56#define NS2501_9_TSEL (1<<3)
 57#define NS2501_9_RSEN (1<<2)
 58#define NS2501_9_RSVD (1<<1)
 59#define NS2501_9_MDI (1<<0)
 60
 61#define NS2501_REGC 0x0c
 62
 63struct ns2501_priv {
 64	//I2CDevRec d;
 65	bool quiet;
 66	int reg_8_shadow;
 67	int reg_8_set;
 68	// Shadow registers for i915
 69	int dvoc;
 70	int pll_a;
 71	int srcdim;
 72	int fw_blc;
 73};
 74
 75#define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr))
 76
 77/*
 78 * For reasons unclear to me, the ns2501 at least on the Fujitsu/Siemens
 79 * laptops does not react on the i2c bus unless
 80 * both the PLL is running and the display is configured in its native
 81 * resolution.
 82 * This function forces the DVO on, and stores the registers it touches.
 83 * Afterwards, registers are restored to regular values.
 84 *
 85 * This is pretty much a hack, though it works.
 86 * Without that, ns2501_readb and ns2501_writeb fail
 87 * when switching the resolution.
 88 */
 89
 90/*
 91** Read a register from the ns2501.
 92** Returns true if successful, false otherwise.
 93** If it returns false, it might be wise to enable the
 94** DVO with the above function.
 95*/
 96static bool ns2501_readb(struct intel_dvo_device *dvo, int addr, uint8_t * ch)
 97{
 98	struct ns2501_priv *ns = dvo->dev_priv;
 99	struct i2c_adapter *adapter = dvo->i2c_bus;
100	u8 out_buf[2];
101	u8 in_buf[2];
102
103	struct i2c_msg msgs[] = {
104		{
105		 .addr = dvo->slave_addr,
106		 .flags = 0,
107		 .len = 1,
108		 .buf = out_buf,
109		 },
110		{
111		 .addr = dvo->slave_addr,
112		 .flags = I2C_M_RD,
113		 .len = 1,
114		 .buf = in_buf,
115		 }
116	};
117
118	out_buf[0] = addr;
119	out_buf[1] = 0;
120
121	if (i2c_transfer(adapter, msgs, 2) == 2) {
122		*ch = in_buf[0];
123		return true;
124	};
125
126	if (!ns->quiet) {
127		DRM_DEBUG_KMS
128		    ("Unable to read register 0x%02x from %s:0x%02x.\n", addr,
129		     adapter->name, dvo->slave_addr);
130	}
131
132	return false;
133}
134
135/*
136** Write a register to the ns2501.
137** Returns true if successful, false otherwise.
138** If it returns false, it might be wise to enable the
139** DVO with the above function.
140*/
141static bool ns2501_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
142{
143	struct ns2501_priv *ns = dvo->dev_priv;
144	struct i2c_adapter *adapter = dvo->i2c_bus;
145	uint8_t out_buf[2];
146
147	struct i2c_msg msg = {
148		.addr = dvo->slave_addr,
149		.flags = 0,
150		.len = 2,
151		.buf = out_buf,
152	};
153
154	out_buf[0] = addr;
155	out_buf[1] = ch;
156
157	if (i2c_transfer(adapter, &msg, 1) == 1) {
158		return true;
159	}
160
161	if (!ns->quiet) {
162		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d\n",
163			      addr, adapter->name, dvo->slave_addr);
164	}
165
166	return false;
167}
168
169/* National Semiconductor 2501 driver for chip on i2c bus
170 * scan for the chip on the bus.
171 * Hope the VBIOS initialized the PLL correctly so we can
172 * talk to it. If not, it will not be seen and not detected.
173 * Bummer!
174 */
175static bool ns2501_init(struct intel_dvo_device *dvo,
176			struct i2c_adapter *adapter)
177{
178	/* this will detect the NS2501 chip on the specified i2c bus */
179	struct ns2501_priv *ns;
180	unsigned char ch;
181
182	ns = kzalloc(sizeof(struct ns2501_priv), GFP_KERNEL);
183	if (ns == NULL)
184		return false;
185
186	dvo->i2c_bus = adapter;
187	dvo->dev_priv = ns;
188	ns->quiet = true;
189
190	if (!ns2501_readb(dvo, NS2501_VID_LO, &ch))
191		goto out;
192
193	if (ch != (NS2501_VID & 0xff)) {
194		DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
195			      ch, adapter->name, dvo->slave_addr);
196		goto out;
197	}
198
199	if (!ns2501_readb(dvo, NS2501_DID_LO, &ch))
200		goto out;
201
202	if (ch != (NS2501_DID & 0xff)) {
203		DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
204			      ch, adapter->name, dvo->slave_addr);
205		goto out;
206	}
207	ns->quiet = false;
208	ns->reg_8_set = 0;
209	ns->reg_8_shadow =
210	    NS2501_8_PD | NS2501_8_BPAS | NS2501_8_VEN | NS2501_8_HEN;
211
212	DRM_DEBUG_KMS("init ns2501 dvo controller successfully!\n");
213	return true;
214
215out:
216	kfree(ns);
217	return false;
218}
219
220static enum drm_connector_status ns2501_detect(struct intel_dvo_device *dvo)
221{
222	/*
223	 * This is a Laptop display, it doesn't have hotplugging.
224	 * Even if not, the detection bit of the 2501 is unreliable as
225	 * it only works for some display types.
226	 * It is even more unreliable as the PLL must be active for
227	 * allowing reading from the chiop.
228	 */
229	return connector_status_connected;
230}
231
232static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo,
233					      struct drm_display_mode *mode)
234{
235	DRM_DEBUG_KMS
236	    ("%s: is mode valid (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d)\n",
237	     __FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay,
238	     mode->vtotal);
239
240	/*
241	 * Currently, these are all the modes I have data from.
242	 * More might exist. Unclear how to find the native resolution
243	 * of the panel in here so we could always accept it
244	 * by disabling the scaler.
245	 */
246	if ((mode->hdisplay == 800 && mode->vdisplay == 600) ||
247	    (mode->hdisplay == 640 && mode->vdisplay == 480) ||
248	    (mode->hdisplay == 1024 && mode->vdisplay == 768)) {
249		return MODE_OK;
250	} else {
251		return MODE_ONE_SIZE;	/* Is this a reasonable error? */
252	}
253}
254
255static void ns2501_mode_set(struct intel_dvo_device *dvo,
256			    struct drm_display_mode *mode,
257			    struct drm_display_mode *adjusted_mode)
258{
259	bool ok;
260	int retries = 10;
261	struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
262
263	DRM_DEBUG_KMS
264	    ("%s: set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n",
265	     __FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay,
266	     mode->vtotal);
267
268	/*
269	 * Where do I find the native resolution for which scaling is not required???
270	 *
271	 * First trigger the DVO on as otherwise the chip does not appear on the i2c
272	 * bus.
273	 */
274	do {
275		ok = true;
276
277		if (mode->hdisplay == 800 && mode->vdisplay == 600) {
278			/* mode 277 */
279			ns->reg_8_shadow &= ~NS2501_8_BPAS;
280			DRM_DEBUG_KMS("%s: switching to 800x600\n",
281				      __FUNCTION__);
282
283			/*
284			 * No, I do not know where this data comes from.
285			 * It is just what the video bios left in the DVO, so
286			 * I'm just copying it here over.
287			 * This also means that I cannot support any other modes
288			 * except the ones supported by the bios.
289			 */
290			ok &= ns2501_writeb(dvo, 0x11, 0xc8);	// 0xc7 also works.
291			ok &= ns2501_writeb(dvo, 0x1b, 0x19);
292			ok &= ns2501_writeb(dvo, 0x1c, 0x62);	// VBIOS left 0x64 here, but 0x62 works nicer
293			ok &= ns2501_writeb(dvo, 0x1d, 0x02);
294
295			ok &= ns2501_writeb(dvo, 0x34, 0x03);
296			ok &= ns2501_writeb(dvo, 0x35, 0xff);
297
298			ok &= ns2501_writeb(dvo, 0x80, 0x27);
299			ok &= ns2501_writeb(dvo, 0x81, 0x03);
300			ok &= ns2501_writeb(dvo, 0x82, 0x41);
301			ok &= ns2501_writeb(dvo, 0x83, 0x05);
302
303			ok &= ns2501_writeb(dvo, 0x8d, 0x02);
304			ok &= ns2501_writeb(dvo, 0x8e, 0x04);
305			ok &= ns2501_writeb(dvo, 0x8f, 0x00);
306
307			ok &= ns2501_writeb(dvo, 0x90, 0xfe);	/* vertical. VBIOS left 0xff here, but 0xfe works better */
308			ok &= ns2501_writeb(dvo, 0x91, 0x07);
309			ok &= ns2501_writeb(dvo, 0x94, 0x00);
310			ok &= ns2501_writeb(dvo, 0x95, 0x00);
311
312			ok &= ns2501_writeb(dvo, 0x96, 0x00);
313
314			ok &= ns2501_writeb(dvo, 0x99, 0x00);
315			ok &= ns2501_writeb(dvo, 0x9a, 0x88);
316
317			ok &= ns2501_writeb(dvo, 0x9c, 0x23);	/* Looks like first and last line of the image. */
318			ok &= ns2501_writeb(dvo, 0x9d, 0x00);
319			ok &= ns2501_writeb(dvo, 0x9e, 0x25);
320			ok &= ns2501_writeb(dvo, 0x9f, 0x03);
321
322			ok &= ns2501_writeb(dvo, 0xa4, 0x80);
323
324			ok &= ns2501_writeb(dvo, 0xb6, 0x00);
325
326			ok &= ns2501_writeb(dvo, 0xb9, 0xc8);	/* horizontal? */
327			ok &= ns2501_writeb(dvo, 0xba, 0x00);	/* horizontal? */
328
329			ok &= ns2501_writeb(dvo, 0xc0, 0x05);	/* horizontal? */
330			ok &= ns2501_writeb(dvo, 0xc1, 0xd7);
331
332			ok &= ns2501_writeb(dvo, 0xc2, 0x00);
333			ok &= ns2501_writeb(dvo, 0xc3, 0xf8);
334
335			ok &= ns2501_writeb(dvo, 0xc4, 0x03);
336			ok &= ns2501_writeb(dvo, 0xc5, 0x1a);
337
338			ok &= ns2501_writeb(dvo, 0xc6, 0x00);
339			ok &= ns2501_writeb(dvo, 0xc7, 0x73);
340			ok &= ns2501_writeb(dvo, 0xc8, 0x02);
341
342		} else if (mode->hdisplay == 640 && mode->vdisplay == 480) {
343			/* mode 274 */
344			DRM_DEBUG_KMS("%s: switching to 640x480\n",
345				      __FUNCTION__);
346			/*
347			 * No, I do not know where this data comes from.
348			 * It is just what the video bios left in the DVO, so
349			 * I'm just copying it here over.
350			 * This also means that I cannot support any other modes
351			 * except the ones supported by the bios.
352			 */
353			ns->reg_8_shadow &= ~NS2501_8_BPAS;
354
355			ok &= ns2501_writeb(dvo, 0x11, 0xa0);
356			ok &= ns2501_writeb(dvo, 0x1b, 0x11);
357			ok &= ns2501_writeb(dvo, 0x1c, 0x54);
358			ok &= ns2501_writeb(dvo, 0x1d, 0x03);
359
360			ok &= ns2501_writeb(dvo, 0x34, 0x03);
361			ok &= ns2501_writeb(dvo, 0x35, 0xff);
362
363			ok &= ns2501_writeb(dvo, 0x80, 0xff);
364			ok &= ns2501_writeb(dvo, 0x81, 0x07);
365			ok &= ns2501_writeb(dvo, 0x82, 0x3d);
366			ok &= ns2501_writeb(dvo, 0x83, 0x05);
367
368			ok &= ns2501_writeb(dvo, 0x8d, 0x02);
369			ok &= ns2501_writeb(dvo, 0x8e, 0x10);
370			ok &= ns2501_writeb(dvo, 0x8f, 0x00);
371
372			ok &= ns2501_writeb(dvo, 0x90, 0xff);	/* vertical */
373			ok &= ns2501_writeb(dvo, 0x91, 0x07);
374			ok &= ns2501_writeb(dvo, 0x94, 0x00);
375			ok &= ns2501_writeb(dvo, 0x95, 0x00);
376
377			ok &= ns2501_writeb(dvo, 0x96, 0x05);
378
379			ok &= ns2501_writeb(dvo, 0x99, 0x00);
380			ok &= ns2501_writeb(dvo, 0x9a, 0x88);
381
382			ok &= ns2501_writeb(dvo, 0x9c, 0x24);
383			ok &= ns2501_writeb(dvo, 0x9d, 0x00);
384			ok &= ns2501_writeb(dvo, 0x9e, 0x25);
385			ok &= ns2501_writeb(dvo, 0x9f, 0x03);
386
387			ok &= ns2501_writeb(dvo, 0xa4, 0x84);
388
389			ok &= ns2501_writeb(dvo, 0xb6, 0x09);
390
391			ok &= ns2501_writeb(dvo, 0xb9, 0xa0);	/* horizontal? */
392			ok &= ns2501_writeb(dvo, 0xba, 0x00);	/* horizontal? */
393
394			ok &= ns2501_writeb(dvo, 0xc0, 0x05);	/* horizontal? */
395			ok &= ns2501_writeb(dvo, 0xc1, 0x90);
396
397			ok &= ns2501_writeb(dvo, 0xc2, 0x00);
398			ok &= ns2501_writeb(dvo, 0xc3, 0x0f);
399
400			ok &= ns2501_writeb(dvo, 0xc4, 0x03);
401			ok &= ns2501_writeb(dvo, 0xc5, 0x16);
402
403			ok &= ns2501_writeb(dvo, 0xc6, 0x00);
404			ok &= ns2501_writeb(dvo, 0xc7, 0x02);
405			ok &= ns2501_writeb(dvo, 0xc8, 0x02);
406
407		} else if (mode->hdisplay == 1024 && mode->vdisplay == 768) {
408			/* mode 280 */
409			DRM_DEBUG_KMS("%s: switching to 1024x768\n",
410				      __FUNCTION__);
411			/*
412			 * This might or might not work, actually. I'm silently
413			 * assuming here that the native panel resolution is
414			 * 1024x768. If not, then this leaves the scaler disabled
415			 * generating a picture that is likely not the expected.
416			 *
417			 * Problem is that I do not know where to take the panel
418			 * dimensions from.
419			 *
420			 * Enable the bypass, scaling not required.
421			 *
422			 * The scaler registers are irrelevant here....
423			 *
424			 */
425			ns->reg_8_shadow |= NS2501_8_BPAS;
426			ok &= ns2501_writeb(dvo, 0x37, 0x44);
427		} else {
428			/*
429			 * Data not known. Bummer!
430			 * Hopefully, the code should not go here
431			 * as mode_OK delivered no other modes.
432			 */
433			ns->reg_8_shadow |= NS2501_8_BPAS;
434		}
435		ok &= ns2501_writeb(dvo, NS2501_REG8, ns->reg_8_shadow);
436	} while (!ok && retries--);
437}
438
439/* set the NS2501 power state */
440static bool ns2501_get_hw_state(struct intel_dvo_device *dvo)
441{
442	unsigned char ch;
443
444	if (!ns2501_readb(dvo, NS2501_REG8, &ch))
445		return false;
446
447	if (ch & NS2501_8_PD)
448		return true;
449	else
450		return false;
451}
452
453/* set the NS2501 power state */
454static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
455{
456	bool ok;
457	int retries = 10;
458	struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
459	unsigned char ch;
460
461	DRM_DEBUG_KMS("%s: Trying set the dpms of the DVO to %i\n",
462		      __FUNCTION__, enable);
463
464	ch = ns->reg_8_shadow;
465
466	if (enable)
467		ch |= NS2501_8_PD;
468	else
469		ch &= ~NS2501_8_PD;
470
471	if (ns->reg_8_set == 0 || ns->reg_8_shadow != ch) {
472		ns->reg_8_set = 1;
473		ns->reg_8_shadow = ch;
474
475		do {
476			ok = true;
477			ok &= ns2501_writeb(dvo, NS2501_REG8, ch);
478			ok &=
479			    ns2501_writeb(dvo, 0x34,
480					  enable ? 0x03 : 0x00);
481			ok &=
482			    ns2501_writeb(dvo, 0x35,
483					  enable ? 0xff : 0x00);
484		} while (!ok && retries--);
485	}
486}
487
488static void ns2501_dump_regs(struct intel_dvo_device *dvo)
489{
490	uint8_t val;
491
492	ns2501_readb(dvo, NS2501_FREQ_LO, &val);
493	DRM_DEBUG_KMS("NS2501_FREQ_LO: 0x%02x\n", val);
494	ns2501_readb(dvo, NS2501_FREQ_HI, &val);
495	DRM_DEBUG_KMS("NS2501_FREQ_HI: 0x%02x\n", val);
496	ns2501_readb(dvo, NS2501_REG8, &val);
497	DRM_DEBUG_KMS("NS2501_REG8: 0x%02x\n", val);
498	ns2501_readb(dvo, NS2501_REG9, &val);
499	DRM_DEBUG_KMS("NS2501_REG9: 0x%02x\n", val);
500	ns2501_readb(dvo, NS2501_REGC, &val);
501	DRM_DEBUG_KMS("NS2501_REGC: 0x%02x\n", val);
502}
503
504static void ns2501_destroy(struct intel_dvo_device *dvo)
505{
506	struct ns2501_priv *ns = dvo->dev_priv;
507
508	if (ns) {
509		kfree(ns);
510		dvo->dev_priv = NULL;
511	}
512}
513
514struct intel_dvo_dev_ops ns2501_ops = {
515	.init = ns2501_init,
516	.detect = ns2501_detect,
517	.mode_valid = ns2501_mode_valid,
518	.mode_set = ns2501_mode_set,
519	.dpms = ns2501_dpms,
520	.get_hw_state = ns2501_get_hw_state,
521	.dump_regs = ns2501_dump_regs,
522	.destroy = ns2501_destroy,
523};