デバイスの叩き方、マシン相互の互換性など。
ページ作成: 神木一也
typedef struct {
short pressure; // タップ中は 1.
short x;
short y;
short millisecs; // ポーリング時刻 (10ms 単位)
} TS_EVENT;
typedef struct {
long y;
long x;
long pressure; // Qte は 500 以上でタップと解釈。
long long millisecs; // ポーリング時刻 (10ms 単位)
} TS_EVENT;
Qte は 500 以上でタップと解釈している。
以下のように表記されている。x, y が逆になることに注意!
typedef struct {
long x; // 長軸
long y; // 短軸
long pressure;
long long millisecs;
} TS_EVENT;
typedef struct {
short pressure; // タップ中は 1.
short x; // 短軸
short y; // 長軸
short millisecs; // ポーリング時刻 (10ms 単位)
} TS_EVENT;
typedef struct {
long y;
long x;
long pressure; // 筆圧。Qte は 500 以上でタップと解釈。
long long millisecs; // ポーリング時刻 (10ms 単位)
} TS_EVENT;
typedef struct {
short pressure; // 押下時、筆圧取得モード時(Pressure=1)は筆圧、無視(Pressure=0)時は 1.
short x;
short y;
short millisecs; // ポーリング時刻 (10ms 単位)
} TS_EVENT;
r.x = ((raw_max_x - t.x) * res_x) / (raw_max_x - raw_min_x);
r.y = ((raw_max_y - t.y) * res_y) / (raw_max_y - raw_min_y);
X = (a * x + b * y + c) / s;
Y = (d * x + e * y + f) / s;
SL-A300 でサポートしないレートを指定すると 8000Hz になるが、
アプリからは指定したレートに見える。バグである :-)
B, C で 8kHz, 44.1kHz, 48kHz 以外のレートを設定してもカーネル内部ではこれらのレートが使用される。
ハードウエアがサポートしているのは signed 16bit だけで、それ以外はカーネル内部で
signed 16bit と相互変換しているだけ。
デフォルトは 8kB x 8, 最小で 16B x 2, 最大 128kB
再生側のデフォルトは 8kB x 8, 最小で 16B x 2, 最大 128kB
デフォルトは 8kB x 8, 最小で 32B x 2, 最大 256kB
サスペンドしていても指定時刻に起き出すという ioctl である。
/dev/rtc は atd が握りっぱなしなので使い辛いのが難点だが。
(きわめて紛らわしいが) void sharppda_get_actkey_gpio(void* dummy) は全く呼ばれていない。
だけでなく、連続する N キーに対してキーアップイベントは最後の一つにしかない。
Qt はカーネルレベルのリピートを無視していて、自前で実装しなおしている。
115: 右下方向
116: 左上方向
117: 右上方向
118: 左下方向
右矢印、左矢印の順に押すと、おそらく 115(make),117(make), 117(break), 115(break),
116(make), 118(make), 118(break), 116(break) のようなシーケンスの割り込みが発生する。
かなり冗長に思えるが、この割り込み(115 〜 118) は 20% 近く落ちるので、
これでも十分でない。break の発生しそこないが出ることがある。
以下のパッチは、最大6個のキーが同時に押せるようになるように修正したものです。
#実際には5個までしか押せませんが…。ハード的な制約かな?
これを使えばエミュレータでのゲームが快適に!?
--- linux.orig/drivers/char/corgi_logkey.c 2003-06-18 16:12:26.000000000 +0900
+++ linux/drivers/char/corgi_logkey.c 2004-01-28 15:05:24.000000000 +0900
@@ -605,6 +605,7 @@
#if CHECK_ROLLOVER
#define MAX_KEY_PRESS (6)
+#define MAX_KEY_PRESS_THRESHOLD (6 + 1)
#endif
void sharppda_scan_key_gpio(void* dummy)
@@ -707,8 +708,8 @@
if (ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_FUNCTION)) {
rollover_count--;
}
- if ((rollover_count > 3) ||
- ((rollover_count == 3) &&
+ if ((rollover_count > MAX_KEY_PRESS_THRESHOLD) ||
+ ((rollover_count == MAX_KEY_PRESS_THRESHOLD) &&
(!ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_TAB) ||
ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_DIRECT_ON)) &&
(!ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_VERTICAL) ||
320x240, 16bpp, packed pixel, true color のみ。
240x320 16bpp, packed pixel, true color のみ。
16bpp であるにもかかわらず、ioctl(FBIOGET_FSCREENINFO) は direct color でなく true color を返す。
Write_buffered_SA-1100_framebuffer
http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2002-November/012137.html
注意: メーカー設定に対してオーバークロック動作になるため、ハードウェアにダメージを与える恐れがあります
--- w100fb.c.orig Wed Jan 22 14:03:57 2003
+++ w100fb.c Sun May 11 10:15:29 2003
@@ -282,7 +282,11 @@
// remap the areas we're going to use
remapped_base = ioremap_nocache(W100_PHYS_ADDRESS, REMAPPED_CFG_LEN);
remapped_regs = ioremap_nocache(W100_REG_BASE, REMAPPED_MMR_LEN);
+#if 0
remapped_fbuf = ioremap_nocache(W100_FB_BASE, REMAPPED_FB_LEN);
+#else
+ remapped_fbuf = __ioremap(W100_FB_BASE, REMAPPED_FB_LEN, L_PTE_BUFFERABLE);
+#endif
isRemapped = 1;
}
@@ -2584,7 +2588,11 @@
break;
case LCD_SHARP_VGA:
w100_SetSlowSysClk(12); // use crystal -- 12.5MHz
+#if 0
w100_SetFastSysClk(75); // use PLL -- 75.0MHz
+#else
+ w100_SetFastSysClk(100); // use PLL -- 100.0MHz
+#endif
gPowerState.pclk_cntl.f.pclk_src_sel = 0x1;
gPowerState.pclk_cntl.f.pclk_post_div = 0x2;
writel((u32)(gPowerState.pclk_cntl.val), remapped_regs+mmPCLK_CNTL);
オプションポート16 に出ているシリアル。
xpa210_discovery_serial_power_on(); // B ではドライバ?の電源オン。C ではなにもしない。
if (xpa2X0_is_ff_uart(info->iomem_base)) { // ポートが FFUART であるか?
CKEN |= CKEN6_FFUART; // FFUART にクロック注入開始。
if (!change_power_mode(LOCK_FCS_FFUART, 1)){ // APM に FFUART の使用を宣言。
return -EAGAIN;
}
}
IrDA のハードウエア層について。IrCOMM などデータリンク〜トランスポート層より上については別項。 SL-A300 以降では、本質的に同じもの。
#if defined(CONFIG_ARCH_PXA_POODLE) #define MUX_CHL 6u /* channel of MUX */ #define BATT_CHL 2u /* channel of BATTery */ #elif defined(CONFIG_ARCH_PXA_CORGI) #define BATT_AD 4u /* channel of BATTery */ #define BATT_THM 2u /* channel of BATTery */ #define JK_VAD 6u /* channel of BATTery */ #endif
unsigned long ssp_get_dac_val(ulong data, int cs) int ssp_get_max1111_val(ulong data)
/*
* Translate Analog signal to Digital data
*/
int Get_DAC_Value(int channel)
{
unsigned long cmd;
unsigned int dummy;
int voltage;
#if defined(CONFIG_ARCH_PXA_POODLE)
/* translate ADC */
cmd = (1u << ADSCTRL_PD0_SH) | (1u << ADSCTRL_PD1_SH) |(1u << ADSCTRL_DFR_SH)|
(channel << ADSCTRL_ADR_SH) | (1u << ADSCTRL_STS_SH);
dummy = ads7846_rw_cli(cmd);
voltage = ads7846_rw_cli(cmd);
cmd &= ~(ADSCTRL_PD0_MSK | ADSCTRL_PD1_MSK);
dummy = ads7846_rw_cli(cmd);
#elif defined(CONFIG_ARCH_PXA_CORGI)
#if 1
cmd = (1u << MAXCTRL_PD0_SH) | (1u << MAXCTRL_PD1_SH) |
(1u << MAXCTRL_SGL_SH) | (1u << MAXCTRL_UNI_SH) |
(channel << MAXCTRL_SEL_SH) | (1u <<MAXCTRL_STR_SH);
voltage = ssp_get_max1111_val(cmd);
#else
...
#endif
return voltage;
}
#if defined(CONFIG_ARCH_PXA_CORGI)
int sharpsl_get_MainBattery(void)
{
...
voltage = Get_DAC_Value(BATT_AD);
...
return voltage;
}
#endif
int sharpsl_read_MainBattery(void)
{
...
#if defined(CONFIG_ARCH_PXA_POODLE)
voltage = Get_DAC_Value(BATT_CHL);
#elif defined(CONFIG_ARCH_PXA_CORGI)
voltage = Get_DAC_Value(BATT_AD);
#endif
...
return voltage;
}
#define SHARPSL_CNV_VALUE_NUM 10
static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
static int sharpsl_ad_index = 0;
/*** get adc *********************************************************************/
int sharpsl_cnv_value(int ad)
{
...
}
typedef struct BatteryThresh {
int voltage; //ADCから取得できる生の電圧値
int percentage; //ユーザに見せる残量(100%,75%,50%,25%,5%,0%)
int status; //バッテリ残量区分のシンボル(HIGH,LOW,VERYLOW,CRITICAL)
} BATTERY_THRESH;
...
BATTERY_THRESH sharpsl_main_battery_thresh_charge_nofl[] = {
{ 200, 100, SHARPSL_BATTERY_STATUS_HIGH},
{ 196, 75, SHARPSL_BATTERY_STATUS_HIGH},
{ 192, 50, SHARPSL_BATTERY_STATUS_HIGH},
{ 187, 25, SHARPSL_BATTERY_STATUS_LOW},
{ 171, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
{ 0, 0, SHARPSL_BATTERY_STATUS_CRITICAL},
};
...
BATTERY_THRESH *GetMainLevel( int Volt )
{
int i;
BATTERY_THRESH *thresh;
DPRINTK(" volt = %d \n",Volt);
if (counter_step_contrast)
thresh = sharpsl_main_battery_thresh_fl;
else
thresh = sharpsl_main_battery_thresh_nofl;
for (i = 0; thresh[i].voltage > 0; i++) {
if (Volt >= thresh[i].voltage)
return &thresh[i];
}
return &thresh[i];
}
int sharpsl_main_battery = SHARPSL_BATTERY_STATUS_HIGH;
int sharpsl_main_battery_percentage = 100;
int sharpsl_main_charge_battery = 100;
int sharpsl_ac_status = APM_AC_OFFLINE;
static int back_ac_status = -1;
static int back_battery_status = -1;
static int sharpsl_check_time = SHARPSL_BATCHK_TIME;
static int sharpsl_main_status_bk = SHARPSL_BATTERY_STATUS_HIGH;
static int sharpsl_main_percent_bk = 100;
static int sharpsl_check_ac_err = 0;
int sharpsl_main_bk_flag = 0;
int sharpsl_get_main_battery(void)
{
...
BATTERY_THRESH *thresh;
...
voltage = sharpsl_read_MainBattery();
...
voltage = sharpsl_cnv_value(voltage);
thresh = GetMainLevel(voltage);
// if battery is low , backlight driver become to save power.
if ( ( ( thresh->status == SHARPSL_BATTERY_STATUS_VERYLOW ) ||
( thresh->status == SHARPSL_BATTERY_STATUS_CRITICAL ) ||
( thresh->status == SHARPSL_BATTERY_STATUS_LOW ) ) &&
( !sharpsl_main_bk_flag ) ) {
SHARPSL_LIMIT_CONTRAST(SHARPSL_CAUTION_CONTRAST);
}
if ( sharpsl_main_bk_flag == 0 ) {
return sharpsl_main_battery;
}
sharpsl_main_battery = thresh->status;
sharpsl_main_battery_percentage = thresh->percentage;
sharpsl_main_charge_battery = GetMainChargePercent(voltage);
...
return sharpsl_main_battery;
}
/*** battery main thread ***********************************************************/
// waitms : waitms*10 msec wait
// flag : 0 : check battery w/o reflcting battery status.
// 1 : check battery w/ reflcting battery status.
// 2 : check battery w/ refresh battery status.
void sharpsl_kick_battery_check(int before_waitms,int after_waitms,int flag)
{
switch (flag) {
case 0:
sharpsl_battery_thread_main();
break;
case 1:
if ( sharpsl_main_bk_flag == 0 ) {
sharpsl_main_bk_flag = 1;
sharpsl_battery_thread_main();
sharpsl_main_bk_flag = 0;
} else {
sharpsl_battery_thread_main();
}
break;
case 2:
back_battery_status = -1;
sharpsl_battery_thread_main();
break;
}
// after check battery
mdelay(after_waitms*10);
}
if ( sharpsl_main_battery != back_battery_status ) {
状態遷移時の処理
}
static int sharpsl_battery_thread_main(void)
{
...
// get main battery
sharpsl_get_main_battery();
// if battery is low , backlight driver become to save power.
if ( ( ( sharpsl_main_battery == SHARPSL_BATTERY_STATUS_VERYLOW ) ||
( sharpsl_main_battery == SHARPSL_BATTERY_STATUS_CRITICAL ) ) &&
( sharpsl_main_battery != back_battery_status ) &&
( sharpsl_main_bk_flag ) ) {
SHARPSL_LIMIT_CONTRAST(SHARPSL_CAUTION_CONTRAST);
} else if ( sharpsl_main_battery != back_battery_status ) {
SHARPSL_LIMIT_CONTRAST(SHARPSL_RESET_CONTRAST);
}
back_battery_status = sharpsl_main_battery;
...
}
static int sharpsl_battery_thread(void* unused)
{
strcpy(current->comm, "sharpsl_bat");
sharpsl_check_time = SHARPSL_BATCHK_TIME;
while(1) {
interruptible_sleep_on_timeout((wait_queue_head_t*)&battery_queue, sharpsl_check_time );
#if !defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_SHARP_SL_J)
...
#endif
// check battery !
sharpsl_battery_thread_main();
}
return 0;
}
/*** Config & Setup **********************************************************/
void battery_init(void)
{
...
/* Make threads */
kernel_thread(sharpsl_charge_on, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
kernel_thread(sharpsl_charge_off, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
kernel_thread(sharpsl_battery_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
}
int sharpsl_read_Temp(void)
{
int temp;
battery_off_flag = 0;
#if defined(CONFIG_ARCH_PXA_POODLE)
...
temp = Get_DAC_Value(MUX_CHL);
...
#elif defined(CONFIG_ARCH_PXA_CORGI)
...
temp = Get_DAC_Value(BATT_THM);
...
#endif
if ( battery_off_flag )
temp = -1;
return temp;
}
情報提供や「こんな事が分からない」等のリクエストがあったら気軽に書き込んでください。