[Armadillo:04136] SVGA表示時にディスプレイにて両端が切れる

山内 洋典 email@hidden
2009年 3月 20日 (金) 13:38:14 JST


NTTDMSEの山内です。
いつもお世話になっております。

Quixunのタッチパネル QT-802-AV-TPをArmadillo-500に接続し、
以下の手順にて動作させることが出来ましたが、
ディスプレイ側のOSDから水平位置等を調節しても
表示領域の両端が切れてしまいます。
(directFBのプログラムdf_inputで確認しております。)

directfbrc, mxcfbドライバ等いじりながら探っておりますが、
表示内容には変化がありません。
このあたりの問題をLinuxとして解決したい場合には
どのあたりのソースをいじるのが妥当なのでしょうか?


○作業内容

※対象カーネルソースはAtmark-dist。
 CFカード上のDebian環境でも、カーネルイメージに同じものを使えば動作しました。

・directfbをカーネルに組込み
参考URL:http://armadillo.atmark-techno.com/articles/sd-a500-embedded-course-ch4

・USB touchscreenドライバに手を入れる
参考URL:http://armadillo.atmark-techno.com/articles/sd-a500-embedded-course-ch4

上記の対応に加えていくつか対応を入れる。

・全てのドライバをカーネル組込みにするとusbtouchscreenよりusbhidが優先されるので、
 USB HIDに認識されないようにHID_QUIRK_IGNOREフラグを設定。
 参考URL:http://www.netfort.gr.jp/~dancer/diary/200709.html

drivers/usb/input/hid-core.c
	/* ##### 2009.03.17 added */
	//ignore EGALAX DEVICES
	{ 0x3823, 0x0001, HID_QUIRK_IGNORE },
	{ 0x0123, 0x0001, HID_QUIRK_IGNORE },
	{ 0x0eef, 0x0001, HID_QUIRK_IGNORE },
	{ 0x0eef, 0x0002, HID_QUIRK_IGNORE },

・データフォーマットが想定と違うためusbtouchscreen.cでドロップされている様なので対応

 ドライバは画面をタッチ時に0x80または0x81から始まる5byteが読み出されることを想定しているが、
 usbtouchscreen.c egalax_process()にprintk()を追加して確認したところ、
 実際にQT802を接続時には以下の様な6byte(例:02 03 58 00 84 00)が読み取れる。
	/* pkt
	 * [0]   02(fixed)
	 * [1]   03 press 02 release
	 * [2-3] X
	 * [4-5] Y
	 */
drivers/usb/input/usbtouchscreen.c に以下の様な対応を追加。

static int egalax_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press)
{
	//printk(KERN_INFO "egalax_read_data: pkt %02X %02X %02X %02X %02X %02X\n", pkt[0], pkt[1], pkt[2], pkt[3], pkt[4], pkt[5]);

/* pkt
 * [0]   02(fixed)
 * [1]   03 press 02 release
 * [2-3] X 48-1932
 * [4-5] Y 128-1900
 */
	int _x, _y;
	_x = (pkt[3] << 8) | (pkt[2] & 0xFF);
	_y = (pkt[5] << 8) | (pkt[4] & 0xFF);
	_x = 1932 - _x;
	_y = 1900 - _y;
	if( _x < 0 ){ _x = 0; }
	if( _y < 0 ){ _y = 0; }

	*x = (int)( (CONFIG_INPUT_TSDEV_SCREEN_X * _x ) / (1932-48));
	*y = (int)( (CONFIG_INPUT_TSDEV_SCREEN_Y * _y ) / (1900-128));
	if(pkt[1] == 0x02)
	{
		*touch = 0x01;
	}
	else
	{
		*touch = 0x00;
	}

	printk(KERN_INFO "egalax_read_data: x=%d y=%d touch=%d\n", *x, *y, *touch);

//	if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
//		return 0;

//#if !defined(CONFIG_USB_TOUCHSCREEN_EGALAX_QT701AVS)
//	*x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F);
//	*y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F);
//#else
//	{
//		int _x, _y, _x2, _y2;
//		_x = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F);
//		_y = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F);
//		                                                          
//		_x2 = ((_x - 90) < 0 ? 0 : (_x - 90));
//		_y2 = ((1900 - _y) < 0 ? 0 : (1900 - _y));
//		
//		printk(KERN_ERR "egalax_read_data: _x,_y %d %d _x2,_y2 %d %d\n", _x, _y, _x2, _y2);
//		
//		*x = (int)((CONFIG_INPUT_TSDEV_SCREEN_X * _x2) / 1850);
//		*y = (int)((CONFIG_INPUT_TSDEV_SCREEN_Y * _y2) / 1750);
//	}
//#endif
//
//	*touch = pkt[0] & 0x01;

	return 1;

}

static int egalax_get_pkt_len(unsigned char *buf)
{
	switch (buf[0] & EGALAX_PKT_TYPE_MASK) {
	case EGALAX_PKT_TYPE_REPT:
		return 5;

	case EGALAX_PKT_TYPE_DIAG:
		return buf[1] + 2;

	//##### 2009.03.17 added
	case 0x02:
		return 6;
	}

	return 0;
}

・tsdev evdev usbhid usbtouchscreenをカーネル組込みで設定。

Device Drivers --->
	input device support --->
		<*> Touchscreen interface
		(800) Horizontal screen resolution
		(600) Vertical screen resolution
		<*> Event interface
	USB support --->
		<*> USB Human Interface Device(full HID) support
		<*> USB Touchscreen Drfiver
			[*] eGalax device support

⇒この時点でQT802のタッチパネルが一応動作する。


以上、よろしくお願いします。
============================================================
山内 洋典 <email@hidden>




armadillo メーリングリストの案内