Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
dd68fd71
Commit
dd68fd71
authored
Jul 31, 2002
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SPARC: Move of move to generic input layer for kbd/mouse.
parent
40b4cd90
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
0 additions
and
2229 deletions
+0
-2229
drivers/sbus/char/Makefile
drivers/sbus/char/Makefile
+0
-3
drivers/sbus/char/pcikbd.c
drivers/sbus/char/pcikbd.c
+0
-1430
drivers/sbus/char/pcikbd.h
drivers/sbus/char/pcikbd.h
+0
-123
drivers/sbus/char/sunkbdmap.c
drivers/sbus/char/sunkbdmap.c
+0
-33
drivers/sbus/char/sunkeymap.c
drivers/sbus/char/sunkeymap.c
+0
-265
drivers/sbus/char/sunkeymap.map
drivers/sbus/char/sunkeymap.map
+0
-375
No files found.
drivers/sbus/char/Makefile
View file @
dd68fd71
...
@@ -8,13 +8,10 @@
...
@@ -8,13 +8,10 @@
#
#
export-objs
:=
bbc_i2c.o
export-objs
:=
bbc_i2c.o
obj-y
:=
sunkbdmap.o
vfc-objs
:=
vfc_dev.o vfc_i2c.o
vfc-objs
:=
vfc_dev.o vfc_i2c.o
bbc-objs
:=
bbc_i2c.o bbc_envctrl.o
bbc-objs
:=
bbc_i2c.o bbc_envctrl.o
obj-$(CONFIG_PCI)
+=
pcikbd.o
obj-$(CONFIG_ENVCTRL)
+=
envctrl.o
obj-$(CONFIG_ENVCTRL)
+=
envctrl.o
obj-$(CONFIG_DISPLAY7SEG)
+=
display7seg.o
obj-$(CONFIG_DISPLAY7SEG)
+=
display7seg.o
obj-$(CONFIG_WATCHDOG_CP1XXX)
+=
cpwatchdog.o
obj-$(CONFIG_WATCHDOG_CP1XXX)
+=
cpwatchdog.o
...
...
drivers/sbus/char/pcikbd.c
deleted
100644 → 0
View file @
40b4cd90
/* $Id: pcikbd.c,v 1.61 2001/08/18 09:40:46 davem Exp $
* pcikbd.c: Ultra/AX PC keyboard support.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
* JavaStation support by Pete A. Zaitcev.
*
* This code is mainly put together from various places in
* drivers/char, please refer to these sources for credits
* to the original authors.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/random.h>
#include <linux/miscdevice.h>
#include <linux/kbd_ll.h>
#include <linux/kbd_kern.h>
#include <linux/vt_kern.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/ebus.h>
#if defined(CONFIG_USB) && defined(CONFIG_SPARC64)
#include <asm/isa.h>
#endif
#include <asm/oplib.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/uaccess.h>
/*
* Different platforms provide different permutations of names.
* AXi - kb_ps2, kdmouse.
* MrCoffee - keyboard, mouse.
* Espresso - keyboard, kdmouse.
*/
#define PCI_KB_NAME1 "kb_ps2"
#define PCI_KB_NAME2 "keyboard"
#define PCI_MS_NAME1 "kdmouse"
#define PCI_MS_NAME2 "mouse"
#include "pcikbd.h"
#include "sunserial.h"
#ifndef __sparc_v9__
static
int
pcikbd_mrcoffee
=
0
;
#else
#define pcikbd_mrcoffee 0
extern
void
(
*
prom_keyboard
)(
void
);
#endif
static
unsigned
long
pcikbd_iobase
=
0
;
static
unsigned
int
pcikbd_irq
=
0
;
/* used only by send_data - set by keyboard_interrupt */
static
volatile
unsigned
char
reply_expected
=
0
;
static
volatile
unsigned
char
acknowledge
=
0
;
static
volatile
unsigned
char
resend
=
0
;
static
spinlock_t
pcikbd_lock
=
SPIN_LOCK_UNLOCKED
;
static
void
pcikbd_write
(
int
address
,
int
data
);
static
int
pcikbd_wait_for_input
(
void
);
unsigned
char
pckbd_read_mask
=
KBD_STAT_OBF
;
extern
int
pcikbd_init
(
void
);
extern
void
pci_compute_shiftstate
(
void
);
extern
int
pci_setkeycode
(
unsigned
int
,
unsigned
int
);
extern
int
pci_getkeycode
(
unsigned
int
);
extern
void
pci_setledstate
(
struct
kbd_struct
*
,
unsigned
int
);
extern
unsigned
char
pci_getledstate
(
void
);
#define pcikbd_inb(x) inb(x)
#define pcikbd_outb(v,x) outb(v,x)
/* Wait for keyboard controller input buffer to drain.
* Must be invoked under the pcikbd_lock.
*/
static
void
kb_wait
(
void
)
{
unsigned
long
timeout
=
250
;
do
{
if
(
!
(
pcikbd_inb
(
pcikbd_iobase
+
KBD_STATUS_REG
)
&
KBD_STAT_IBF
))
return
;
mdelay
(
1
);
}
while
(
--
timeout
);
}
/*
* Translation of escaped scancodes to keycodes.
* This is now user-settable.
* The keycodes 1-88,96-111,119 are fairly standard, and
* should probably not be changed - changing might confuse X.
* X also interprets scancode 0x5d (KEY_Begin).
*
* For 1-88 keycode equals scancode.
*/
#define E0_KPENTER 96
#define E0_RCTRL 97
#define E0_KPSLASH 98
#define E0_PRSCR 99
#define E0_RALT 100
#define E0_BREAK 101
/* (control-pause) */
#define E0_HOME 102
#define E0_UP 103
#define E0_PGUP 104
#define E0_LEFT 105
#define E0_RIGHT 106
#define E0_END 107
#define E0_DOWN 108
#define E0_PGDN 109
#define E0_INS 110
#define E0_DEL 111
#define E1_PAUSE 119
/*
* The keycodes below are randomly located in 89-95,112-118,120-127.
* They could be thrown away (and all occurrences below replaced by 0),
* but that would force many users to use the `setkeycodes' utility, where
* they needed not before. It does not matter that there are duplicates, as
* long as no duplication occurs for any single keyboard.
*/
#define SC_LIM 89
#define FOCUS_PF1 85
/* actual code! */
#define FOCUS_PF2 89
#define FOCUS_PF3 90
#define FOCUS_PF4 91
#define FOCUS_PF5 92
#define FOCUS_PF6 93
#define FOCUS_PF7 94
#define FOCUS_PF8 95
#define FOCUS_PF9 120
#define FOCUS_PF10 121
#define FOCUS_PF11 122
#define FOCUS_PF12 123
#define JAP_86 124
/* tfj@olivia.ping.dk:
* The four keys are located over the numeric keypad, and are
* labelled A1-A4. It's an rc930 keyboard, from
* Regnecentralen/RC International, Now ICL.
* Scancodes: 59, 5a, 5b, 5c.
*/
#define RGN1 124
#define RGN2 125
#define RGN3 126
#define RGN4 127
static
unsigned
char
high_keys
[
128
-
SC_LIM
]
=
{
RGN1
,
RGN2
,
RGN3
,
RGN4
,
0
,
0
,
0
,
/* 0x59-0x5f */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0x60-0x67 */
0
,
0
,
0
,
0
,
0
,
FOCUS_PF11
,
0
,
FOCUS_PF12
,
/* 0x68-0x6f */
0
,
0
,
0
,
FOCUS_PF2
,
FOCUS_PF9
,
0
,
0
,
FOCUS_PF3
,
/* 0x70-0x77 */
FOCUS_PF4
,
FOCUS_PF5
,
FOCUS_PF6
,
FOCUS_PF7
,
/* 0x78-0x7b */
FOCUS_PF8
,
JAP_86
,
FOCUS_PF10
,
0
/* 0x7c-0x7f */
};
/* BTC */
#define E0_MACRO 112
/* LK450 */
#define E0_F13 113
#define E0_F14 114
#define E0_HELP 115
#define E0_DO 116
#define E0_F17 117
#define E0_KPMINPLUS 118
/*
* My OmniKey generates e0 4c for the "OMNI" key and the
* right alt key does nada. [kkoller@nyx10.cs.du.edu]
*/
#define E0_OK 124
/*
* New microsoft keyboard is rumoured to have
* e0 5b (left window button), e0 5c (right window button),
* e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
* [or: Windows_L, Windows_R, TaskMan]
*/
#define E0_MSLW 125
#define E0_MSRW 126
#define E0_MSTM 127
static
unsigned
char
e0_keys
[
128
]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0x00-0x07 */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0x08-0x0f */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0x10-0x17 */
0
,
0
,
0
,
0
,
E0_KPENTER
,
E0_RCTRL
,
0
,
0
,
/* 0x18-0x1f */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0x20-0x27 */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0x28-0x2f */
0
,
0
,
0
,
0
,
0
,
E0_KPSLASH
,
0
,
E0_PRSCR
,
/* 0x30-0x37 */
E0_RALT
,
0
,
0
,
0
,
0
,
E0_F13
,
E0_F14
,
E0_HELP
,
/* 0x38-0x3f */
E0_DO
,
E0_F17
,
0
,
0
,
0
,
0
,
E0_BREAK
,
E0_HOME
,
/* 0x40-0x47 */
E0_UP
,
E0_PGUP
,
0
,
E0_LEFT
,
E0_OK
,
E0_RIGHT
,
E0_KPMINPLUS
,
E0_END
,
/* 0x48-0x4f */
E0_DOWN
,
E0_PGDN
,
E0_INS
,
E0_DEL
,
0
,
0
,
0
,
0
,
/* 0x50-0x57 */
0
,
0
,
0
,
E0_MSLW
,
E0_MSRW
,
E0_MSTM
,
0
,
0
,
/* 0x58-0x5f */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0x60-0x67 */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
E0_MACRO
,
/* 0x68-0x6f */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0x70-0x77 */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
/* 0x78-0x7f */
};
/* Simple translation table for the SysRq keys */
#ifdef CONFIG_MAGIC_SYSRQ
unsigned
char
pcikbd_sysrq_xlate
[
128
]
=
"
\000\033
1234567890-=
\177\t
"
/* 0x00 - 0x0f */
"qwertyuiop[]
\r\000
as"
/* 0x10 - 0x1f */
"dfghjkl;'`
\000\\
zxcv"
/* 0x20 - 0x2f */
"bnm,./
\000
*
\000
\000\201\202\203\204\205
"
/* 0x30 - 0x3f */
"
\206\207\210\211\212\000\000
789-456+1"
/* 0x40 - 0x4f */
"230
\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000
"
/* 0x50 - 0x5f */
"
\r\000
/"
;
/* 0x60 - 0x6f */
#endif
#define DEFAULT_KEYB_REP_DELAY 250
#define DEFAULT_KEYB_REP_RATE 30
/* cps */
static
struct
kbd_repeat
kbdrate
=
{
DEFAULT_KEYB_REP_DELAY
,
DEFAULT_KEYB_REP_RATE
};
static
unsigned
char
parse_kbd_rate
(
struct
kbd_repeat
*
r
);
static
int
write_kbd_rate
(
unsigned
char
r
);
int
pcikbd_setkeycode
(
unsigned
int
scancode
,
unsigned
int
keycode
)
{
if
(
scancode
<
SC_LIM
||
scancode
>
255
||
keycode
>
127
)
return
-
EINVAL
;
if
(
scancode
<
128
)
high_keys
[
scancode
-
SC_LIM
]
=
keycode
;
else
e0_keys
[
scancode
-
128
]
=
keycode
;
return
0
;
}
int
pcikbd_getkeycode
(
unsigned
int
scancode
)
{
return
(
scancode
<
SC_LIM
||
scancode
>
255
)
?
-
EINVAL
:
(
scancode
<
128
)
?
high_keys
[
scancode
-
SC_LIM
]
:
e0_keys
[
scancode
-
128
];
}
static
int
do_acknowledge
(
unsigned
char
scancode
)
{
if
(
reply_expected
)
{
if
(
scancode
==
KBD_REPLY_ACK
)
{
acknowledge
=
1
;
reply_expected
=
0
;
return
0
;
}
else
if
(
scancode
==
KBD_REPLY_RESEND
)
{
resend
=
1
;
reply_expected
=
0
;
return
0
;
}
}
return
1
;
}
#ifdef __sparc_v9__
static
void
pcikbd_enter_prom
(
void
)
{
pcikbd_write
(
KBD_DATA_REG
,
KBD_CMD_DISABLE
);
if
(
pcikbd_wait_for_input
()
!=
KBD_REPLY_ACK
)
printk
(
"Prom Enter: Disable keyboard: no ACK
\n
"
);
/* Disable PC scancode translation */
pcikbd_write
(
KBD_CNTL_REG
,
KBD_CCMD_WRITE_MODE
);
pcikbd_write
(
KBD_DATA_REG
,
KBD_MODE_SYS
);
pcikbd_write
(
KBD_DATA_REG
,
KBD_CMD_ENABLE
);
if
(
pcikbd_wait_for_input
()
!=
KBD_REPLY_ACK
)
printk
(
"Prom Enter: Enable Keyboard: no ACK
\n
"
);
}
#endif
static
void
ctrl_break
(
void
)
{
extern
int
stop_a_enabled
;
unsigned
long
timeout
;
int
status
,
data
;
int
mode
;
if
(
!
stop_a_enabled
)
return
;
pcikbd_write
(
KBD_DATA_REG
,
KBD_CMD_DISABLE
);
if
(
pcikbd_wait_for_input
()
!=
KBD_REPLY_ACK
)
printk
(
"Prom Enter: Disable keyboard: no ACK
\n
"
);
/* Save current mode register settings */
pcikbd_write
(
KBD_CNTL_REG
,
KBD_CCMD_READ_MODE
);
if
((
mode
=
pcikbd_wait_for_input
())
==
-
1
)
printk
(
"Prom Enter: Read Mode: no ACK
\n
"
);
/* Disable PC scancode translation */
pcikbd_write
(
KBD_CNTL_REG
,
KBD_CCMD_WRITE_MODE
);
pcikbd_write
(
KBD_DATA_REG
,
mode
&
~
(
KBD_MODE_KCC
));
pcikbd_write
(
KBD_DATA_REG
,
KBD_CMD_ENABLE
);
if
(
pcikbd_wait_for_input
()
!=
KBD_REPLY_ACK
)
printk
(
"Prom Enter: Enable Keyboard: no ACK
\n
"
);
/* Drop into OBP.
* Note that we must flush the user windows
* first before giving up control.
*/
flush_user_windows
();
prom_cmdline
();
/* Read prom's key up event (use short timeout) */
do
{
timeout
=
10
;
do
{
mdelay
(
1
);
status
=
pcikbd_inb
(
pcikbd_iobase
+
KBD_STATUS_REG
);
if
(
!
(
status
&
KBD_STAT_OBF
))
continue
;
data
=
pcikbd_inb
(
pcikbd_iobase
+
KBD_DATA_REG
);
if
(
status
&
(
KBD_STAT_GTO
|
KBD_STAT_PERR
))
continue
;
break
;
}
while
(
--
timeout
>
0
);
}
while
(
timeout
>
0
);
/* Reenable PC scancode translation */
pcikbd_write
(
KBD_DATA_REG
,
KBD_CMD_DISABLE
);
if
(
pcikbd_wait_for_input
()
!=
KBD_REPLY_ACK
)
printk
(
"Prom Leave: Disable keyboard: no ACK
\n
"
);
pcikbd_write
(
KBD_CNTL_REG
,
KBD_CCMD_WRITE_MODE
);
pcikbd_write
(
KBD_DATA_REG
,
mode
);
pcikbd_write
(
KBD_DATA_REG
,
KBD_CMD_ENABLE
);
if
(
pcikbd_wait_for_input
()
!=
KBD_REPLY_ACK
)
printk
(
"Prom Leave: Enable Keyboard: no ACK
\n
"
);
/* Reset keyboard rate */
write_kbd_rate
(
parse_kbd_rate
(
&
kbdrate
));
}
int
pcikbd_translate
(
unsigned
char
scancode
,
unsigned
char
*
keycode
,
char
raw_mode
)
{
static
int
prev_scancode
=
0
;
int
down
=
scancode
&
0x80
?
0
:
1
;
if
(
scancode
==
0xe0
||
scancode
==
0xe1
)
{
prev_scancode
=
scancode
;
return
0
;
}
if
(
scancode
==
0x00
||
scancode
==
0xff
)
{
prev_scancode
=
0
;
return
0
;
}
scancode
&=
0x7f
;
if
(
prev_scancode
)
{
if
(
prev_scancode
!=
0xe0
)
{
if
(
prev_scancode
==
0xe1
&&
scancode
==
0x1d
)
{
prev_scancode
=
0x100
;
return
0
;
}
else
if
(
prev_scancode
==
0x100
&&
scancode
==
0x45
)
{
*
keycode
=
E1_PAUSE
;
prev_scancode
=
0
;
}
else
{
prev_scancode
=
0
;
return
0
;
}
}
else
{
prev_scancode
=
0
;
if
(
scancode
==
0x2a
||
scancode
==
0x36
)
return
0
;
if
(
e0_keys
[
scancode
])
*
keycode
=
e0_keys
[
scancode
];
else
return
0
;
}
}
else
if
(
scancode
>=
SC_LIM
)
{
*
keycode
=
high_keys
[
scancode
-
SC_LIM
];
if
(
!*
keycode
)
return
0
;
}
else
*
keycode
=
scancode
;
if
(
*
keycode
==
E0_BREAK
)
{
if
(
down
)
return
0
;
/* Handle ctrl-break event */
ctrl_break
();
/* Send ctrl up event to the keyboard driver */
*
keycode
=
0x1d
;
}
return
1
;
}
char
pcikbd_unexpected_up
(
unsigned
char
keycode
)
{
if
(
keycode
>=
SC_LIM
||
keycode
==
85
)
return
0
;
else
return
0200
;
}
static
void
pcikbd_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
unsigned
long
flags
;
unsigned
char
status
;
spin_lock_irqsave
(
&
pcikbd_lock
,
flags
);
kbd_pt_regs
=
regs
;
status
=
pcikbd_inb
(
pcikbd_iobase
+
KBD_STATUS_REG
);
do
{
unsigned
char
scancode
;
if
(
status
&
pckbd_read_mask
&
KBD_STAT_MOUSE_OBF
)
break
;
scancode
=
pcikbd_inb
(
pcikbd_iobase
+
KBD_DATA_REG
);
if
((
status
&
KBD_STAT_OBF
)
&&
do_acknowledge
(
scancode
))
handle_scancode
(
scancode
,
!
(
scancode
&
0x80
));
status
=
pcikbd_inb
(
pcikbd_iobase
+
KBD_STATUS_REG
);
}
while
(
status
&
KBD_STAT_OBF
);
tasklet_schedule
(
&
keyboard_tasklet
);
spin_unlock_irqrestore
(
&
pcikbd_lock
,
flags
);
}
static
int
send_data
(
unsigned
char
data
)
{
int
retries
=
3
;
unsigned
long
flags
;
do
{
unsigned
long
timeout
=
1000
;
spin_lock_irqsave
(
&
pcikbd_lock
,
flags
);
kb_wait
();
acknowledge
=
0
;
resend
=
0
;
reply_expected
=
1
;
pcikbd_outb
(
data
,
pcikbd_iobase
+
KBD_DATA_REG
);
spin_unlock_irqrestore
(
&
pcikbd_lock
,
flags
);
do
{
if
(
acknowledge
)
return
1
;
if
(
resend
)
break
;
mdelay
(
1
);
}
while
(
--
timeout
);
if
(
timeout
==
0
)
break
;
}
while
(
retries
--
>
0
);
return
0
;
}
void
pcikbd_leds
(
unsigned
char
leds
)
{
if
(
!
pcikbd_iobase
)
return
;
if
(
!
send_data
(
KBD_CMD_SET_LEDS
)
||
!
send_data
(
leds
))
send_data
(
KBD_CMD_ENABLE
);
}
static
unsigned
char
parse_kbd_rate
(
struct
kbd_repeat
*
r
)
{
static
struct
r2v
{
int
rate
;
unsigned
char
val
;
}
kbd_rates
[]
=
{
{
5
,
0x14
},
{
7
,
0x10
},
{
10
,
0x0c
},
{
15
,
0x08
},
{
20
,
0x04
},
{
25
,
0x02
},
{
30
,
0x00
}
};
static
struct
d2v
{
int
delay
;
unsigned
char
val
;
}
kbd_delays
[]
=
{
{
250
,
0
},
{
500
,
1
},
{
750
,
2
},
{
1000
,
3
}
};
int
rate
=
0
,
delay
=
0
;
if
(
r
!=
NULL
)
{
int
i
,
new_rate
=
30
,
new_delay
=
250
;
if
(
r
->
rate
<=
0
)
r
->
rate
=
kbdrate
.
rate
;
if
(
r
->
delay
<=
0
)
r
->
delay
=
kbdrate
.
delay
;
for
(
i
=
0
;
i
<
sizeof
(
kbd_rates
)
/
sizeof
(
struct
r2v
);
i
++
)
{
if
(
kbd_rates
[
i
].
rate
==
r
->
rate
)
{
new_rate
=
kbd_rates
[
i
].
rate
;
rate
=
kbd_rates
[
i
].
val
;
break
;
}
}
for
(
i
=
0
;
i
<
sizeof
(
kbd_delays
)
/
sizeof
(
struct
d2v
);
i
++
)
{
if
(
kbd_delays
[
i
].
delay
==
r
->
delay
)
{
new_delay
=
kbd_delays
[
i
].
delay
;
delay
=
kbd_delays
[
i
].
val
;
break
;
}
}
r
->
rate
=
new_rate
;
r
->
delay
=
new_delay
;
}
return
(
delay
<<
5
)
|
rate
;
}
static
int
write_kbd_rate
(
unsigned
char
r
)
{
if
(
!
send_data
(
KBD_CMD_SET_RATE
)
||
!
send_data
(
r
))
{
/* re-enable kbd if any errors */
send_data
(
KBD_CMD_ENABLE
);
return
0
;
}
return
1
;
}
static
int
pcikbd_rate
(
struct
kbd_repeat
*
rep
)
{
unsigned
char
r
;
struct
kbd_repeat
old_rep
;
if
(
rep
==
NULL
)
return
-
EINVAL
;
r
=
parse_kbd_rate
(
rep
);
memcpy
(
&
old_rep
,
&
kbdrate
,
sizeof
(
struct
kbd_repeat
));
if
(
write_kbd_rate
(
r
))
{
memcpy
(
&
kbdrate
,
rep
,
sizeof
(
struct
kbd_repeat
));
memcpy
(
rep
,
&
old_rep
,
sizeof
(
struct
kbd_repeat
));
return
0
;
}
return
-
EIO
;
}
static
int
pcikbd_wait_for_input
(
void
)
{
int
status
,
data
;
unsigned
long
timeout
=
1000
;
do
{
mdelay
(
1
);
status
=
pcikbd_inb
(
pcikbd_iobase
+
KBD_STATUS_REG
);
if
(
!
(
status
&
KBD_STAT_OBF
))
continue
;
data
=
pcikbd_inb
(
pcikbd_iobase
+
KBD_DATA_REG
);
if
(
status
&
(
KBD_STAT_GTO
|
KBD_STAT_PERR
))
continue
;
return
(
data
&
0xff
);
}
while
(
--
timeout
>
0
);
return
-
1
;
}
static
void
pcikbd_write
(
int
address
,
int
data
)
{
int
status
;
do
{
status
=
pcikbd_inb
(
pcikbd_iobase
+
KBD_STATUS_REG
);
}
while
(
status
&
KBD_STAT_IBF
);
pcikbd_outb
(
data
,
pcikbd_iobase
+
address
);
}
#ifdef __sparc_v9__
static
unsigned
long
pcibeep_iobase
=
0
;
/* Timer routine to turn off the beep after the interval expires. */
static
void
pcikbd_kd_nosound
(
unsigned
long
__unused
)
{
if
(
pcibeep_iobase
&
0x2UL
)
outb
(
0
,
pcibeep_iobase
);
else
outl
(
0
,
pcibeep_iobase
);
}
/*
* Initiate a keyboard beep. If the frequency is zero, then we stop
* the beep. Any other frequency will start a monotone beep. The beep
* will be stopped by a timer after "ticks" jiffies. If ticks is 0,
* then we do not start a timer.
*/
static
void
pcikbd_kd_mksound
(
unsigned
int
hz
,
unsigned
int
ticks
)
{
unsigned
long
flags
;
static
struct
timer_list
sound_timer
=
{
function
:
pcikbd_kd_nosound
};
save_flags
(
flags
);
cli
();
del_timer
(
&
sound_timer
);
if
(
hz
)
{
if
(
pcibeep_iobase
&
0x2UL
)
outb
(
1
,
pcibeep_iobase
);
else
outl
(
1
,
pcibeep_iobase
);
if
(
ticks
)
{
sound_timer
.
expires
=
jiffies
+
ticks
;
add_timer
(
&
sound_timer
);
}
}
else
{
if
(
pcibeep_iobase
&
0x2UL
)
outb
(
0
,
pcibeep_iobase
);
else
outl
(
0
,
pcibeep_iobase
);
}
restore_flags
(
flags
);
}
#if defined(CONFIG_USB) && defined(CONFIG_SPARC64)
static
void
isa_kd_nosound
(
unsigned
long
__unused
)
{
/* disable counter 2 */
outb
(
inb
(
pcibeep_iobase
+
0x61
)
&
0xFC
,
pcibeep_iobase
+
0x61
);
return
;
}
static
void
isa_kd_mksound
(
unsigned
int
hz
,
unsigned
int
ticks
)
{
static
struct
timer_list
sound_timer
=
{
function
:
isa_kd_nosound
};
unsigned
int
count
=
0
;
unsigned
long
flags
;
if
(
hz
>
20
&&
hz
<
32767
)
count
=
1193180
/
hz
;
save_flags
(
flags
);
cli
();
del_timer
(
&
sound_timer
);
if
(
count
)
{
/* enable counter 2 */
outb
(
inb
(
pcibeep_iobase
+
0x61
)
|
3
,
pcibeep_iobase
+
0x61
);
/* set command for counter 2, 2 byte write */
outb
(
0xB6
,
pcibeep_iobase
+
0x43
);
/* select desired HZ */
outb
(
count
&
0xff
,
pcibeep_iobase
+
0x42
);
outb
((
count
>>
8
)
&
0xff
,
pcibeep_iobase
+
0x42
);
if
(
ticks
)
{
sound_timer
.
expires
=
jiffies
+
ticks
;
add_timer
(
&
sound_timer
);
}
}
else
isa_kd_nosound
(
0
);
restore_flags
(
flags
);
return
;
}
#endif
#endif
static
void
nop_kd_mksound
(
unsigned
int
hz
,
unsigned
int
ticks
)
{
}
extern
void
(
*
kd_mksound
)(
unsigned
int
hz
,
unsigned
int
ticks
);
static
char
*
__init
do_pcikbd_init_hw
(
void
)
{
while
(
pcikbd_wait_for_input
()
!=
-
1
)
;
pcikbd_write
(
KBD_CNTL_REG
,
KBD_CCMD_SELF_TEST
);
if
(
pcikbd_wait_for_input
()
!=
0x55
)
return
"Keyboard failed self test"
;
pcikbd_write
(
KBD_CNTL_REG
,
KBD_CCMD_KBD_TEST
);
if
(
pcikbd_wait_for_input
()
!=
0x00
)
return
"Keyboard interface failed self test"
;
pcikbd_write
(
KBD_CNTL_REG
,
KBD_CCMD_KBD_ENABLE
);
pcikbd_write
(
KBD_DATA_REG
,
KBD_CMD_RESET
);
if
(
pcikbd_wait_for_input
()
!=
KBD_REPLY_ACK
)
return
"Keyboard reset failed, no ACK"
;
if
(
pcikbd_wait_for_input
()
!=
KBD_REPLY_POR
)
return
"Keyboard reset failed, no ACK"
;
pcikbd_write
(
KBD_DATA_REG
,
KBD_CMD_DISABLE
);
if
(
pcikbd_wait_for_input
()
!=
KBD_REPLY_ACK
)
return
"Disable keyboard: no ACK"
;
pcikbd_write
(
KBD_CNTL_REG
,
KBD_CCMD_WRITE_MODE
);
pcikbd_write
(
KBD_DATA_REG
,
(
KBD_MODE_KBD_INT
|
KBD_MODE_SYS
|
KBD_MODE_DISABLE_MOUSE
|
KBD_MODE_KCC
));
pcikbd_write
(
KBD_DATA_REG
,
KBD_CMD_ENABLE
);
if
(
pcikbd_wait_for_input
()
!=
KBD_REPLY_ACK
)
return
"Enable keyboard: no ACK"
;
write_kbd_rate
(
parse_kbd_rate
(
&
kbdrate
));
return
NULL
;
/* success */
}
void
__init
pcikbd_init_hw
(
void
)
{
struct
linux_ebus
*
ebus
;
struct
linux_ebus_device
*
edev
;
struct
linux_ebus_child
*
child
;
char
*
msg
;
if
(
pcikbd_mrcoffee
)
{
if
((
pcikbd_iobase
=
(
unsigned
long
)
ioremap
(
0x71300060
,
8
))
==
0
)
{
prom_printf
(
"pcikbd_init_hw: cannot map
\n
"
);
return
;
}
pcikbd_irq
=
13
|
0x20
;
if
(
request_irq
(
pcikbd_irq
,
&
pcikbd_interrupt
,
SA_SHIRQ
,
"keyboard"
,
(
void
*
)
pcikbd_iobase
))
{
printk
(
"8042: cannot register IRQ %x
\n
"
,
pcikbd_irq
);
return
;
}
printk
(
"8042(kbd): iobase[%x] irq[%x]
\n
"
,
(
unsigned
)
pcikbd_iobase
,
pcikbd_irq
);
}
else
{
for_each_ebus
(
ebus
)
{
for_each_ebusdev
(
edev
,
ebus
)
{
if
(
!
strcmp
(
edev
->
prom_name
,
"8042"
))
{
for_each_edevchild
(
edev
,
child
)
{
if
(
strcmp
(
child
->
prom_name
,
PCI_KB_NAME1
)
==
0
||
strcmp
(
child
->
prom_name
,
PCI_KB_NAME2
)
==
0
)
goto
found
;
}
}
}
}
#ifdef CONFIG_USB
/* We are being called for the sake of USB keyboard
* state initialization. So we should check for beeper
* device in this case.
*/
edev
=
0
;
for_each_ebus
(
ebus
)
{
for_each_ebusdev
(
edev
,
ebus
)
{
if
(
!
strcmp
(
edev
->
prom_name
,
"beep"
))
{
pcibeep_iobase
=
edev
->
resource
[
0
].
start
;
kd_mksound
=
pcikbd_kd_mksound
;
printk
(
"8042(speaker): iobase[%016lx]
\n
"
,
pcibeep_iobase
);
return
;
}
}
}
#ifdef CONFIG_SPARC64
/* Maybe we have one inside the ALI southbridge? */
{
struct
isa_bridge
*
isa_br
;
struct
isa_device
*
isa_dev
;
for_each_isa
(
isa_br
)
{
for_each_isadev
(
isa_dev
,
isa_br
)
{
/* This is a hack, the 'dma' device node has
* the base of the I/O port space for that PBM
* as it's resource, so we use that. -DaveM
*/
if
(
!
strcmp
(
isa_dev
->
prom_name
,
"dma"
))
{
pcibeep_iobase
=
isa_dev
->
resource
.
start
;
kd_mksound
=
isa_kd_mksound
;
printk
(
"isa(speaker): iobase[%016lx:%016lx]
\n
"
,
pcibeep_iobase
+
0x42
,
pcibeep_iobase
+
0x61
);
return
;
}
}
}
}
#endif
/* No beeper found, ok complain. */
#endif
printk
(
"pcikbd_init_hw: no 8042 found
\n
"
);
return
;
found:
pcikbd_iobase
=
child
->
resource
[
0
].
start
;
pcikbd_irq
=
child
->
irqs
[
0
];
if
(
request_irq
(
pcikbd_irq
,
&
pcikbd_interrupt
,
SA_SHIRQ
,
"keyboard"
,
(
void
*
)
pcikbd_iobase
))
{
printk
(
"8042: cannot register IRQ %s
\n
"
,
__irq_itoa
(
pcikbd_irq
));
return
;
}
printk
(
"8042(kbd) at 0x%lx (irq %s)
\n
"
,
pcikbd_iobase
,
__irq_itoa
(
pcikbd_irq
));
}
kd_mksound
=
nop_kd_mksound
;
kbd_rate
=
pcikbd_rate
;
#ifdef __sparc_v9__
edev
=
0
;
for_each_ebus
(
ebus
)
{
for_each_ebusdev
(
edev
,
ebus
)
{
if
(
!
strcmp
(
edev
->
prom_name
,
"beeper"
))
goto
ebus_done
;
}
}
ebus_done:
/*
* XXX: my 3.1.3 PROM does not give me the beeper node for the audio
* auxio register, though I know it is there... (ecd)
*
* JavaStations appear not to have beeper. --zaitcev
*/
if
(
!
edev
)
pcibeep_iobase
=
(
pcikbd_iobase
&
~
(
0xffffff
))
|
0x722000
;
else
pcibeep_iobase
=
edev
->
resource
[
0
].
start
;
kd_mksound
=
pcikbd_kd_mksound
;
printk
(
"8042(speaker): iobase[%016lx]%s
\n
"
,
pcibeep_iobase
,
edev
?
""
:
" (forced)"
);
prom_keyboard
=
pcikbd_enter_prom
;
#endif
disable_irq
(
pcikbd_irq
);
msg
=
do_pcikbd_init_hw
();
enable_irq
(
pcikbd_irq
);
if
(
msg
)
printk
(
"8042: keyboard init failure [%s]
\n
"
,
msg
);
}
/*
* Here begins the Mouse Driver.
*/
static
unsigned
long
pcimouse_iobase
=
0
;
static
unsigned
int
pcimouse_irq
;
#define AUX_BUF_SIZE 2048
struct
aux_queue
{
unsigned
long
head
;
unsigned
long
tail
;
wait_queue_head_t
proc_list
;
struct
fasync_struct
*
fasync
;
unsigned
char
buf
[
AUX_BUF_SIZE
];
};
static
struct
aux_queue
*
queue
;
static
int
aux_count
=
0
;
static
int
aux_present
=
0
;
#define pcimouse_inb(x) inb(x)
#define pcimouse_outb(v,x) outb(v,x)
/*
* Shared subroutines
*/
static
unsigned
int
get_from_queue
(
void
)
{
unsigned
int
result
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
pcikbd_lock
,
flags
);
result
=
queue
->
buf
[
queue
->
tail
];
queue
->
tail
=
(
queue
->
tail
+
1
)
&
(
AUX_BUF_SIZE
-
1
);
spin_unlock_irqrestore
(
&
pcikbd_lock
,
flags
);
return
result
;
}
static
inline
int
queue_empty
(
void
)
{
return
queue
->
head
==
queue
->
tail
;
}
static
int
aux_fasync
(
int
fd
,
struct
file
*
filp
,
int
on
)
{
int
retval
;
retval
=
fasync_helper
(
fd
,
filp
,
on
,
&
queue
->
fasync
);
if
(
retval
<
0
)
return
retval
;
return
0
;
}
/*
* PS/2 Aux Device
*/
#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | \
KBD_MODE_SYS | KBD_MODE_KBD_INT)
#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | \
KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
#define MAX_RETRIES 60
/* some aux operations take long time*/
/*
* Status polling
*/
static
int
poll_aux_status
(
void
)
{
int
retries
=
0
;
while
((
pcimouse_inb
(
pcimouse_iobase
+
KBD_STATUS_REG
)
&
(
KBD_STAT_IBF
|
KBD_STAT_OBF
))
&&
retries
<
MAX_RETRIES
)
{
if
((
pcimouse_inb
(
pcimouse_iobase
+
KBD_STATUS_REG
)
&
AUX_STAT_OBF
)
==
AUX_STAT_OBF
)
pcimouse_inb
(
pcimouse_iobase
+
KBD_DATA_REG
);
mdelay
(
5
);
retries
++
;
}
return
(
retries
<
MAX_RETRIES
);
}
/*
* Write to aux device
*/
static
void
aux_write_dev
(
int
val
)
{
poll_aux_status
();
pcimouse_outb
(
KBD_CCMD_WRITE_MOUSE
,
pcimouse_iobase
+
KBD_CNTL_REG
);
/* Write magic cookie */
poll_aux_status
();
pcimouse_outb
(
val
,
pcimouse_iobase
+
KBD_DATA_REG
);
/* Write data */
udelay
(
1
);
}
/*
* Write to device & handle returned ack
*/
static
int
__init
aux_write_ack
(
int
val
)
{
aux_write_dev
(
val
);
poll_aux_status
();
if
((
pcimouse_inb
(
pcimouse_iobase
+
KBD_STATUS_REG
)
&
AUX_STAT_OBF
)
==
AUX_STAT_OBF
)
return
(
pcimouse_inb
(
pcimouse_iobase
+
KBD_DATA_REG
));
return
0
;
}
/*
* Write aux device command
*/
static
void
aux_write_cmd
(
int
val
)
{
poll_aux_status
();
pcimouse_outb
(
KBD_CCMD_WRITE_MODE
,
pcimouse_iobase
+
KBD_CNTL_REG
);
poll_aux_status
();
pcimouse_outb
(
val
,
pcimouse_iobase
+
KBD_DATA_REG
);
}
/*
* Interrupt from the auxiliary device: a character
* is waiting in the keyboard/aux controller.
*/
void
pcimouse_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
unsigned
long
flags
;
int
head
,
maxhead
;
unsigned
char
val
;
spin_lock_irqsave
(
&
pcikbd_lock
,
flags
);
head
=
queue
->
head
;
maxhead
=
(
queue
->
tail
-
1
)
&
(
AUX_BUF_SIZE
-
1
);
if
((
pcimouse_inb
(
pcimouse_iobase
+
KBD_STATUS_REG
)
&
AUX_STAT_OBF
)
!=
AUX_STAT_OBF
)
{
spin_unlock_irqrestore
(
&
pcikbd_lock
,
flags
);
return
;
}
val
=
pcimouse_inb
(
pcimouse_iobase
+
KBD_DATA_REG
);
queue
->
buf
[
head
]
=
val
;
add_mouse_randomness
(
val
);
if
(
head
!=
maxhead
)
{
head
++
;
head
&=
AUX_BUF_SIZE
-
1
;
}
queue
->
head
=
head
;
spin_unlock_irqrestore
(
&
pcikbd_lock
,
flags
);
kill_fasync
(
&
queue
->
fasync
,
SIGIO
,
POLL_IN
);
wake_up_interruptible
(
&
queue
->
proc_list
);
}
static
int
aux_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
unsigned
long
flags
;
aux_fasync
(
-
1
,
file
,
0
);
spin_lock_irqsave
(
&
pcikbd_lock
,
flags
);
if
(
--
aux_count
)
goto
out
;
/* Disable controller ints */
aux_write_cmd
(
AUX_INTS_OFF
);
poll_aux_status
();
/* Disable Aux device */
pcimouse_outb
(
KBD_CCMD_MOUSE_DISABLE
,
pcimouse_iobase
+
KBD_CNTL_REG
);
poll_aux_status
();
out:
spin_unlock_irqrestore
(
&
pcikbd_lock
,
flags
);
return
0
;
}
/*
* Install interrupt handler.
* Enable auxiliary device.
*/
static
int
aux_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
unsigned
long
flags
;
if
(
!
aux_present
)
return
-
ENODEV
;
spin_lock_irqsave
(
&
pcikbd_lock
,
flags
);
if
(
aux_count
++
)
{
spin_unlock_irqrestore
(
&
pcikbd_lock
,
flags
);
return
0
;
}
if
(
!
poll_aux_status
())
{
aux_count
--
;
spin_unlock_irqrestore
(
&
pcikbd_lock
,
flags
);
return
-
EBUSY
;
}
queue
->
head
=
queue
->
tail
=
0
;
/* Flush input queue */
poll_aux_status
();
pcimouse_outb
(
KBD_CCMD_MOUSE_ENABLE
,
pcimouse_iobase
+
KBD_CNTL_REG
);
/* Enable Aux */
aux_write_dev
(
AUX_ENABLE_DEV
);
/* Enable aux device */
aux_write_cmd
(
AUX_INTS_ON
);
/* Enable controller ints */
poll_aux_status
();
spin_unlock_irqrestore
(
&
pcikbd_lock
,
flags
);
return
0
;
}
/*
* Write to the aux device.
*/
static
ssize_t
aux_write
(
struct
file
*
file
,
const
char
*
buffer
,
size_t
count
,
loff_t
*
ppos
)
{
ssize_t
retval
=
0
;
unsigned
long
flags
;
if
(
count
)
{
ssize_t
written
=
0
;
spin_lock_irqsave
(
&
pcikbd_lock
,
flags
);
do
{
char
c
;
spin_unlock_irqrestore
(
&
pcikbd_lock
,
flags
);
get_user
(
c
,
buffer
++
);
spin_lock_irqsave
(
&
pcikbd_lock
,
flags
);
if
(
!
poll_aux_status
())
break
;
pcimouse_outb
(
KBD_CCMD_WRITE_MOUSE
,
pcimouse_iobase
+
KBD_CNTL_REG
);
if
(
!
poll_aux_status
())
break
;
pcimouse_outb
(
c
,
pcimouse_iobase
+
KBD_DATA_REG
);
written
++
;
}
while
(
--
count
);
spin_unlock_irqrestore
(
&
pcikbd_lock
,
flags
);
retval
=
-
EIO
;
if
(
written
)
{
retval
=
written
;
file
->
f_dentry
->
d_inode
->
i_mtime
=
CURRENT_TIME
;
}
}
return
retval
;
}
/*
* Generic part continues...
*/
/*
* Put bytes from input queue to buffer.
*/
static
ssize_t
aux_read
(
struct
file
*
file
,
char
*
buffer
,
size_t
count
,
loff_t
*
ppos
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
ssize_t
i
=
count
;
unsigned
char
c
;
if
(
queue_empty
())
{
if
(
file
->
f_flags
&
O_NONBLOCK
)
return
-
EAGAIN
;
add_wait_queue
(
&
queue
->
proc_list
,
&
wait
);
repeat:
set_current_state
(
TASK_INTERRUPTIBLE
);
if
(
queue_empty
()
&&
!
signal_pending
(
current
))
{
schedule
();
goto
repeat
;
}
current
->
state
=
TASK_RUNNING
;
remove_wait_queue
(
&
queue
->
proc_list
,
&
wait
);
}
while
(
i
>
0
&&
!
queue_empty
())
{
c
=
get_from_queue
();
put_user
(
c
,
buffer
++
);
i
--
;
}
if
(
count
-
i
)
{
file
->
f_dentry
->
d_inode
->
i_atime
=
CURRENT_TIME
;
return
count
-
i
;
}
if
(
signal_pending
(
current
))
return
-
ERESTARTSYS
;
return
0
;
}
static
unsigned
int
aux_poll
(
struct
file
*
file
,
poll_table
*
wait
)
{
poll_wait
(
file
,
&
queue
->
proc_list
,
wait
);
if
(
!
queue_empty
())
return
POLLIN
|
POLLRDNORM
;
return
0
;
}
struct
file_operations
psaux_fops
=
{
.
owner
=
THIS_MODULE
,
.
read
=
aux_read
,
.
write
=
aux_write
,
.
poll
=
aux_poll
,
.
open
=
aux_open
,
.
release
=
aux_release
,
.
fasync
=
aux_fasync
,
};
static
int
aux_no_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
-
ENODEV
;
}
struct
file_operations
psaux_no_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
aux_no_open
,
};
static
struct
miscdevice
psaux_mouse
=
{
PSMOUSE_MINOR
,
"ps2aux"
,
&
psaux_fops
};
static
struct
miscdevice
psaux_no_mouse
=
{
PSMOUSE_MINOR
,
"ps2aux"
,
&
psaux_no_fops
};
int
__init
pcimouse_init
(
void
)
{
struct
linux_ebus
*
ebus
;
struct
linux_ebus_device
*
edev
;
struct
linux_ebus_child
*
child
;
if
(
pcikbd_mrcoffee
)
{
if
((
pcimouse_iobase
=
pcikbd_iobase
)
==
0
)
{
printk
(
"pcimouse_init: no 8042 given
\n
"
);
goto
do_enodev
;
}
pcimouse_irq
=
pcikbd_irq
;
}
else
{
for_each_ebus
(
ebus
)
{
for_each_ebusdev
(
edev
,
ebus
)
{
if
(
!
strcmp
(
edev
->
prom_name
,
"8042"
))
{
for_each_edevchild
(
edev
,
child
)
{
if
(
strcmp
(
child
->
prom_name
,
PCI_MS_NAME1
)
==
0
||
strcmp
(
child
->
prom_name
,
PCI_MS_NAME2
)
==
0
)
goto
found
;
}
}
}
}
printk
(
"pcimouse_init: no 8042 found
\n
"
);
goto
do_enodev
;
found:
pcimouse_iobase
=
child
->
resource
[
0
].
start
;
pcimouse_irq
=
child
->
irqs
[
0
];
}
queue
=
(
struct
aux_queue
*
)
kmalloc
(
sizeof
(
*
queue
),
GFP_KERNEL
);
if
(
!
queue
)
{
printk
(
"pcimouse_init: kmalloc(aux_queue) failed.
\n
"
);
return
-
ENOMEM
;
}
memset
(
queue
,
0
,
sizeof
(
*
queue
));
init_waitqueue_head
(
&
queue
->
proc_list
);
if
(
request_irq
(
pcimouse_irq
,
&
pcimouse_interrupt
,
SA_SHIRQ
,
"mouse"
,
(
void
*
)
pcimouse_iobase
))
{
printk
(
"8042: Cannot register IRQ %s
\n
"
,
__irq_itoa
(
pcimouse_irq
));
goto
do_enodev
;
}
printk
(
"8042(mouse) at %lx (irq %s)
\n
"
,
pcimouse_iobase
,
__irq_itoa
(
pcimouse_irq
));
printk
(
"8042: PS/2 auxiliary pointing device detected.
\n
"
);
aux_present
=
1
;
pckbd_read_mask
=
AUX_STAT_OBF
;
misc_register
(
&
psaux_mouse
);
spin_lock_irq
(
&
pcikbd_lock
);
pcimouse_outb
(
KBD_CCMD_MOUSE_ENABLE
,
pcimouse_iobase
+
KBD_CNTL_REG
);
aux_write_ack
(
AUX_RESET
);
aux_write_ack
(
AUX_SET_SAMPLE
);
aux_write_ack
(
100
);
aux_write_ack
(
AUX_SET_RES
);
aux_write_ack
(
3
);
aux_write_ack
(
AUX_SET_SCALE21
);
poll_aux_status
();
pcimouse_outb
(
KBD_CCMD_MOUSE_DISABLE
,
pcimouse_iobase
+
KBD_CNTL_REG
);
poll_aux_status
();
pcimouse_outb
(
KBD_CCMD_WRITE_MODE
,
pcimouse_iobase
+
KBD_CNTL_REG
);
poll_aux_status
();
pcimouse_outb
(
AUX_INTS_OFF
,
pcimouse_iobase
+
KBD_DATA_REG
);
poll_aux_status
();
spin_unlock_irq
(
&
pcikbd_lock
);
return
0
;
do_enodev:
misc_register
(
&
psaux_no_mouse
);
return
-
ENODEV
;
}
int
__init
pcimouse_no_init
(
void
)
{
misc_register
(
&
psaux_no_mouse
);
return
-
ENODEV
;
}
int
__init
ps2kbd_probe
(
void
)
{
int
pnode
,
enode
,
node
,
dnode
,
xnode
;
int
kbnode
=
0
,
msnode
=
0
,
bnode
=
0
;
int
devices
=
0
;
char
prop
[
128
];
int
len
;
#ifndef __sparc_v9__
/*
* MrCoffee has hardware but has no PROM nodes whatsoever.
*/
len
=
prom_getproperty
(
prom_root_node
,
"name"
,
prop
,
sizeof
(
prop
));
if
(
len
<
0
)
{
printk
(
"ps2kbd_probe: no name of root node
\n
"
);
goto
do_enodev
;
}
if
(
strncmp
(
prop
,
"SUNW,JavaStation-1"
,
len
)
==
0
)
{
pcikbd_mrcoffee
=
1
;
/* Brain damage detected */
goto
found
;
}
#endif
/*
* Get the nodes for keyboard and mouse from aliases on normal systems.
*/
node
=
prom_getchild
(
prom_root_node
);
node
=
prom_searchsiblings
(
node
,
"aliases"
);
if
(
!
node
)
goto
do_enodev
;
len
=
prom_getproperty
(
node
,
"keyboard"
,
prop
,
sizeof
(
prop
));
if
(
len
>
0
)
{
prop
[
len
]
=
0
;
kbnode
=
prom_finddevice
(
prop
);
}
if
(
!
kbnode
)
goto
do_enodev
;
len
=
prom_getproperty
(
node
,
"mouse"
,
prop
,
sizeof
(
prop
));
if
(
len
>
0
)
{
prop
[
len
]
=
0
;
msnode
=
prom_finddevice
(
prop
);
}
if
(
!
msnode
)
goto
do_enodev
;
/*
* Find matching EBus nodes...
*/
node
=
prom_getchild
(
prom_root_node
);
pnode
=
prom_searchsiblings
(
node
,
"pci"
);
/*
* Check for SUNW,sabre on Ultra5/10/AXi.
*/
len
=
prom_getproperty
(
pnode
,
"model"
,
prop
,
sizeof
(
prop
));
if
((
len
>
0
)
&&
!
strncmp
(
prop
,
"SUNW,sabre"
,
len
))
{
pnode
=
prom_getchild
(
pnode
);
pnode
=
prom_searchsiblings
(
pnode
,
"pci"
);
}
/*
* For each PCI bus...
*/
while
(
pnode
)
{
enode
=
prom_getchild
(
pnode
);
enode
=
prom_searchsiblings
(
enode
,
"ebus"
);
/*
* For each EBus on this PCI...
*/
while
(
enode
)
{
node
=
prom_getchild
(
enode
);
bnode
=
prom_searchsiblings
(
node
,
"beeper"
);
node
=
prom_getchild
(
enode
);
node
=
prom_searchsiblings
(
node
,
"8042"
);
/*
* For each '8042' on this EBus...
*/
while
(
node
)
{
dnode
=
prom_getchild
(
node
);
/*
* Does it match?
*/
if
((
xnode
=
prom_searchsiblings
(
dnode
,
PCI_KB_NAME1
))
==
kbnode
)
{
++
devices
;
}
else
if
((
xnode
=
prom_searchsiblings
(
dnode
,
PCI_KB_NAME2
))
==
kbnode
)
{
++
devices
;
}
if
((
xnode
=
prom_searchsiblings
(
dnode
,
PCI_MS_NAME1
))
==
msnode
)
{
++
devices
;
}
else
if
((
xnode
=
prom_searchsiblings
(
dnode
,
PCI_MS_NAME2
))
==
msnode
)
{
++
devices
;
}
/*
* Found everything we need?
*/
if
(
devices
==
2
)
goto
found
;
node
=
prom_getsibling
(
node
);
node
=
prom_searchsiblings
(
node
,
"8042"
);
}
enode
=
prom_getsibling
(
enode
);
enode
=
prom_searchsiblings
(
enode
,
"ebus"
);
}
pnode
=
prom_getsibling
(
pnode
);
pnode
=
prom_searchsiblings
(
pnode
,
"pci"
);
}
do_enodev:
sunkbd_setinitfunc
(
pcimouse_no_init
);
return
-
ENODEV
;
found:
sunkbd_setinitfunc
(
pcimouse_init
);
sunkbd_setinitfunc
(
pcikbd_init
);
kbd_ops
.
compute_shiftstate
=
pci_compute_shiftstate
;
kbd_ops
.
setledstate
=
pci_setledstate
;
kbd_ops
.
getledstate
=
pci_getledstate
;
kbd_ops
.
setkeycode
=
pci_setkeycode
;
kbd_ops
.
getkeycode
=
pci_getkeycode
;
return
0
;
}
drivers/sbus/char/pcikbd.h
deleted
100644 → 0
View file @
40b4cd90
/* $Id: pcikbd.h,v 1.2 1997/12/25 21:13:14 geert Exp $
* pcikbd.h: PCI/PC 8042 keyboard/mouse driver stuff. Mostly snarfed
* from the existing driver by Martin Mares.
*
* Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*
* Ultra/AX specific hacks are:
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*/
#ifndef __PCIKBD_H
#define __PCIKBD_H
/*
* Configuration Switches
*/
#define KBD_REPORT_ERR
/* Report keyboard errors */
#define KBD_REPORT_UNKN
/* Report unknown scan codes */
#define KBD_REPORT_TIMEOUTS
/* Report keyboard timeouts */
#define KBD_INIT_TIMEOUT HZ
/* Timeout for initializing the keyboard */
#define KBC_TIMEOUT (HZ/4)
/* Timeout for sending to keyboard controller */
#define KBD_TIMEOUT (HZ/4)
/* Timeout for keyboard command acknowledge */
/*
* Internal variables of the driver
*/
extern
unsigned
char
pckbd_read_mask
;
extern
unsigned
char
aux_device_present
;
extern
unsigned
long
pcikbd_iobase
;
extern
unsigned
int
pcikbd_irq
;
/*
* Keyboard Controller Registers
*
* NOTE: These are offsets from pcikbd_iobase, not absolute.
*/
#define KBD_STATUS_REG 0x04
#define KBD_CNTL_REG KBD_STATUS_REG
#define KBD_DATA_REG 0x00
/*
* Keyboard Controller Commands
*/
#define KBD_CCMD_READ_MODE 0x20
/* Read mode bits */
#define KBD_CCMD_WRITE_MODE 0x60
/* Write mode bits */
#define KBD_CCMD_GET_VERSION 0xA1
/* Get controller version */
#define KBD_CCMD_MOUSE_DISABLE 0xA7
/* Disable mouse interface */
#define KBD_CCMD_MOUSE_ENABLE 0xA8
/* Enable mouse interface */
#define KBD_CCMD_TEST_MOUSE 0xA9
/* Mouse interface test */
#define KBD_CCMD_SELF_TEST 0xAA
/* Controller self test */
#define KBD_CCMD_KBD_TEST 0xAB
/* Keyboard interface test */
#define KBD_CCMD_KBD_DISABLE 0xAD
/* Keyboard interface disable */
#define KBD_CCMD_KBD_ENABLE 0xAE
/* Keyboard interface enable */
#define KBD_CCMD_WRITE_MOUSE 0xD4
/* Write the following byte to the mouse */
/*
* Keyboard Commands
*/
#define KBD_CMD_SET_LEDS 0xED
/* Set keyboard leds */
#define KBD_CMD_SET_RATE 0xF3
/* Set typematic rate */
#define KBD_CMD_ENABLE 0xF4
/* Enable scanning */
#define KBD_CMD_DISABLE 0xF5
/* Disable scanning */
#define KBD_CMD_RESET 0xFF
/* Reset */
/*
* Keyboard Replies
*/
#define KBD_REPLY_POR 0xAA
/* Power on reset */
#define KBD_REPLY_ACK 0xFA
/* Command ACK */
#define KBD_REPLY_RESEND 0xFE
/* Command NACK, send the cmd again */
/*
* Status Register Bits
*/
#define KBD_STAT_OBF 0x01
/* Keyboard output buffer full */
#define KBD_STAT_IBF 0x02
/* Keyboard input buffer full */
#define KBD_STAT_SELFTEST 0x04
/* Self test successful */
#define KBD_STAT_CMD 0x08
/* Last write was a command write (0=data) */
#define KBD_STAT_UNLOCKED 0x10
/* Zero if keyboard locked */
#define KBD_STAT_MOUSE_OBF 0x20
/* Mouse output buffer full */
#define KBD_STAT_GTO 0x40
/* General receive/xmit timeout */
#define KBD_STAT_PERR 0x80
/* Parity error */
#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
/*
* Controller Mode Register Bits
*/
#define KBD_MODE_KBD_INT 0x01
/* Keyboard data generage IRQ1 */
#define KBD_MODE_MOUSE_INT 0x02
/* Mouse data generate IRQ12 */
#define KBD_MODE_SYS 0x04
/* The system flag (?) */
#define KBD_MODE_NO_KEYLOCK 0x08
/* The keylock doesn't affect the keyboard if set */
#define KBD_MODE_DISABLE_KBD 0x10
/* Disable keyboard interface */
#define KBD_MODE_DISABLE_MOUSE 0x20
/* Disable mouse interface */
#define KBD_MODE_KCC 0x40
/* Scan code conversion to PC format */
#define KBD_MODE_RFU 0x80
/*
* Mouse Commands
*/
#define AUX_SET_RES 0xE8
/* Set resolution */
#define AUX_SET_SCALE11 0xE6
/* Set 1:1 scaling */
#define AUX_SET_SCALE21 0xE7
/* Set 2:1 scaling */
#define AUX_GET_SCALE 0xE9
/* Get scaling factor */
#define AUX_SET_STREAM 0xEA
/* Set stream mode */
#define AUX_SET_SAMPLE 0xF3
/* Set sample rate */
#define AUX_ENABLE_DEV 0xF4
/* Enable aux device */
#define AUX_DISABLE_DEV 0xF5
/* Disable aux device */
#define AUX_RESET 0xFF
/* Reset aux device */
#endif
/* __PCIKBD_H */
drivers/sbus/char/sunkbdmap.c
deleted
100644 → 0
View file @
40b4cd90
/* $Id: sunkbdmap.c,v 1.1 1997/09/07 15:40:27 ecd Exp $
* sunkbdmap.c: Wrapper around sunkeymap.c to change table names.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
*/
#include <linux/config.h>
#ifdef CONFIG_PCI
#define func_buf sun_func_buf
#define func_table sun_func_table
#define funcbufsize sun_funcbufsize
#define funcbufleft sun_funcbufleft
#define funcbufptr sun_funcbufptr
#define accent_table sun_accent_table
#define accent_table_size sun_accent_table_size
#define key_maps sun_key_maps
#define keymap_count sun_keymap_count
#define plain_map sun_plain_map
#define shift_map sun_shift_map
#define ctrl_map sun_ctrl_map
#define alt_map sun_alt_map
#define altgr_map sun_altgr_map
#define shift_ctrl_map sun_shift_ctrl_map
#define ctrl_alt_map sun_ctrl_alt_map
#endif
/* CONFIG_PCI */
#include "sunkeymap.c"
drivers/sbus/char/sunkeymap.c
deleted
100644 → 0
View file @
40b4cd90
/* Do not edit this file! It was automatically generated by */
/* loadkeys --mktable defkeymap.map > defkeymap.c */
#include <linux/types.h>
#include <linux/keyboard.h>
#include <linux/kd.h>
u_short
plain_map
[
NR_KEYS
]
=
{
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf100
,
0xf101
,
0xf109
,
0xf102
,
0xf10a
,
0xf103
,
0xf10b
,
0xf104
,
0xf701
,
0xf105
,
0xf200
,
0xf106
,
0xf107
,
0xf108
,
0xf703
,
0xf603
,
0xf11d
,
0xf200
,
0xf209
,
0xf601
,
0xf200
,
0xf200
,
0xf600
,
0xf602
,
0xf01b
,
0xf031
,
0xf032
,
0xf033
,
0xf034
,
0xf035
,
0xf036
,
0xf037
,
0xf038
,
0xf039
,
0xf030
,
0xf02d
,
0xf03d
,
0xf060
,
0xf07f
,
0xf115
,
0xf03d
,
0xf30d
,
0xf30c
,
0xf200
,
0xf200
,
0xf310
,
0xf200
,
0xf114
,
0xf009
,
0xfb71
,
0xfb77
,
0xfb65
,
0xfb72
,
0xfb74
,
0xfb79
,
0xfb75
,
0xfb69
,
0xfb6f
,
0xfb70
,
0xf05b
,
0xf05d
,
0xf07f
,
0xf20e
,
0xf307
,
0xf308
,
0xf309
,
0xf30b
,
0xf200
,
0xf200
,
0xf117
,
0xf200
,
0xf702
,
0xfb61
,
0xfb73
,
0xfb64
,
0xfb66
,
0xfb67
,
0xfb68
,
0xfb6a
,
0xfb6b
,
0xfb6c
,
0xf03b
,
0xf027
,
0xf05c
,
0xf201
,
0xf30e
,
0xf304
,
0xf305
,
0xf306
,
0xf300
,
0xf200
,
0xf118
,
0xf200
,
0xf208
,
0xf700
,
0xfb7a
,
0xfb78
,
0xfb63
,
0xfb76
,
0xfb62
,
0xfb6e
,
0xfb6d
,
0xf02c
,
0xf02e
,
0xf02f
,
0xf700
,
0xf00a
,
0xf301
,
0xf302
,
0xf303
,
0xf200
,
0xf200
,
0xf200
,
0xf11b
,
0xf207
,
0xf200
,
0xf020
,
0xf200
,
0xf119
,
0xf200
,
0xf30a
,
0xf200
,
0xf200
,
};
u_short
shift_map
[
NR_KEYS
]
=
{
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf10a
,
0xf10b
,
0xf113
,
0xf10c
,
0xf10a
,
0xf10d
,
0xf10b
,
0xf10e
,
0xf701
,
0xf10f
,
0xf200
,
0xf110
,
0xf111
,
0xf112
,
0xf703
,
0xf603
,
0xf11d
,
0xf200
,
0xf203
,
0xf601
,
0xf200
,
0xf200
,
0xf600
,
0xf602
,
0xf01b
,
0xf021
,
0xf040
,
0xf023
,
0xf024
,
0xf025
,
0xf05e
,
0xf026
,
0xf02a
,
0xf028
,
0xf029
,
0xf05f
,
0xf02b
,
0xf07e
,
0xf07f
,
0xf115
,
0xf03d
,
0xf30d
,
0xf30c
,
0xf200
,
0xf200
,
0xf310
,
0xf200
,
0xf114
,
0xf009
,
0xfb51
,
0xfb57
,
0xfb45
,
0xfb52
,
0xfb54
,
0xfb59
,
0xfb55
,
0xfb49
,
0xfb4f
,
0xfb50
,
0xf07b
,
0xf07d
,
0xf07f
,
0xf20e
,
0xf307
,
0xf308
,
0xf309
,
0xf30b
,
0xf200
,
0xf200
,
0xf117
,
0xf200
,
0xf702
,
0xfb41
,
0xfb53
,
0xfb44
,
0xfb46
,
0xfb47
,
0xfb48
,
0xfb4a
,
0xfb4b
,
0xfb4c
,
0xf03a
,
0xf022
,
0xf07c
,
0xf201
,
0xf30e
,
0xf304
,
0xf305
,
0xf306
,
0xf300
,
0xf200
,
0xf20b
,
0xf200
,
0xf208
,
0xf700
,
0xfb5a
,
0xfb58
,
0xfb43
,
0xfb56
,
0xfb42
,
0xfb4e
,
0xfb4d
,
0xf03c
,
0xf03e
,
0xf03f
,
0xf700
,
0xf00a
,
0xf301
,
0xf302
,
0xf303
,
0xf200
,
0xf200
,
0xf200
,
0xf11b
,
0xf207
,
0xf200
,
0xf020
,
0xf200
,
0xf20a
,
0xf200
,
0xf30a
,
0xf200
,
0xf200
,
};
u_short
altgr_map
[
NR_KEYS
]
=
{
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf50c
,
0xf50d
,
0xf515
,
0xf50e
,
0xf516
,
0xf50f
,
0xf517
,
0xf510
,
0xf701
,
0xf511
,
0xf200
,
0xf512
,
0xf513
,
0xf514
,
0xf703
,
0xf603
,
0xf11d
,
0xf200
,
0xf202
,
0xf601
,
0xf200
,
0xf200
,
0xf600
,
0xf602
,
0xf200
,
0xf200
,
0xf040
,
0xf200
,
0xf024
,
0xf200
,
0xf200
,
0xf07b
,
0xf05b
,
0xf05d
,
0xf07d
,
0xf05c
,
0xf200
,
0xf200
,
0xf200
,
0xf115
,
0xf03d
,
0xf30d
,
0xf30c
,
0xf200
,
0xf200
,
0xf310
,
0xf200
,
0xf114
,
0xf200
,
0xfb71
,
0xfb77
,
0xf918
,
0xfb72
,
0xfb74
,
0xfb79
,
0xfb75
,
0xfb69
,
0xfb6f
,
0xfb70
,
0xf200
,
0xf07e
,
0xf200
,
0xf20e
,
0xf911
,
0xf912
,
0xf913
,
0xf30b
,
0xf200
,
0xf200
,
0xf117
,
0xf200
,
0xf702
,
0xf914
,
0xfb73
,
0xf917
,
0xf919
,
0xfb67
,
0xfb68
,
0xfb6a
,
0xfb6b
,
0xfb6c
,
0xf200
,
0xf200
,
0xf200
,
0xf201
,
0xf30e
,
0xf90e
,
0xf90f
,
0xf910
,
0xf90a
,
0xf200
,
0xf118
,
0xf200
,
0xf208
,
0xf700
,
0xfb7a
,
0xfb78
,
0xf916
,
0xfb76
,
0xf915
,
0xfb6e
,
0xfb6d
,
0xf200
,
0xf200
,
0xf200
,
0xf700
,
0xf00a
,
0xf90b
,
0xf90c
,
0xf90d
,
0xf200
,
0xf200
,
0xf200
,
0xf11b
,
0xf207
,
0xf200
,
0xf200
,
0xf200
,
0xf119
,
0xf200
,
0xf30a
,
0xf200
,
0xf200
,
};
u_short
ctrl_map
[
NR_KEYS
]
=
{
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf100
,
0xf101
,
0xf109
,
0xf102
,
0xf10a
,
0xf103
,
0xf10b
,
0xf104
,
0xf701
,
0xf105
,
0xf200
,
0xf106
,
0xf107
,
0xf108
,
0xf703
,
0xf603
,
0xf11d
,
0xf200
,
0xf204
,
0xf601
,
0xf200
,
0xf200
,
0xf600
,
0xf602
,
0xf200
,
0xf200
,
0xf000
,
0xf01b
,
0xf01c
,
0xf01d
,
0xf01e
,
0xf01f
,
0xf07f
,
0xf200
,
0xf200
,
0xf01f
,
0xf200
,
0xf000
,
0xf008
,
0xf115
,
0xf03d
,
0xf30d
,
0xf30c
,
0xf200
,
0xf200
,
0xf310
,
0xf200
,
0xf114
,
0xf200
,
0xf011
,
0xf017
,
0xf005
,
0xf012
,
0xf014
,
0xf019
,
0xf015
,
0xf009
,
0xf00f
,
0xf010
,
0xf01b
,
0xf01d
,
0xf008
,
0xf20e
,
0xf307
,
0xf308
,
0xf309
,
0xf30b
,
0xf200
,
0xf200
,
0xf117
,
0xf200
,
0xf702
,
0xf001
,
0xf013
,
0xf004
,
0xf006
,
0xf007
,
0xf008
,
0xf00a
,
0xf00b
,
0xf00c
,
0xf200
,
0xf007
,
0xf01c
,
0xf201
,
0xf30e
,
0xf304
,
0xf305
,
0xf306
,
0xf300
,
0xf200
,
0xf118
,
0xf200
,
0xf208
,
0xf700
,
0xf01a
,
0xf018
,
0xf003
,
0xf016
,
0xf002
,
0xf00e
,
0xf00d
,
0xf200
,
0xf20e
,
0xf07f
,
0xf700
,
0xf00a
,
0xf301
,
0xf302
,
0xf303
,
0xf200
,
0xf200
,
0xf200
,
0xf11b
,
0xf207
,
0xf200
,
0xf000
,
0xf200
,
0xf119
,
0xf200
,
0xf30a
,
0xf200
,
0xf200
,
};
u_short
shift_ctrl_map
[
NR_KEYS
]
=
{
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf701
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf703
,
0xf603
,
0xf11d
,
0xf200
,
0xf200
,
0xf601
,
0xf200
,
0xf200
,
0xf600
,
0xf602
,
0xf200
,
0xf200
,
0xf000
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf01f
,
0xf200
,
0xf200
,
0xf200
,
0xf115
,
0xf03d
,
0xf30d
,
0xf30c
,
0xf200
,
0xf200
,
0xf310
,
0xf200
,
0xf114
,
0xf200
,
0xf011
,
0xf017
,
0xf005
,
0xf012
,
0xf014
,
0xf019
,
0xf015
,
0xf009
,
0xf00f
,
0xf010
,
0xf200
,
0xf200
,
0xf200
,
0xf20e
,
0xf307
,
0xf308
,
0xf309
,
0xf30b
,
0xf200
,
0xf200
,
0xf117
,
0xf200
,
0xf702
,
0xf001
,
0xf013
,
0xf004
,
0xf006
,
0xf007
,
0xf008
,
0xf00a
,
0xf00b
,
0xf00c
,
0xf200
,
0xf200
,
0xf200
,
0xf201
,
0xf30e
,
0xf304
,
0xf305
,
0xf306
,
0xf300
,
0xf200
,
0xf118
,
0xf200
,
0xf208
,
0xf700
,
0xf01a
,
0xf018
,
0xf003
,
0xf016
,
0xf002
,
0xf00e
,
0xf00d
,
0xf200
,
0xf200
,
0xf200
,
0xf700
,
0xf00a
,
0xf301
,
0xf302
,
0xf303
,
0xf200
,
0xf200
,
0xf200
,
0xf11b
,
0xf207
,
0xf200
,
0xf200
,
0xf200
,
0xf119
,
0xf200
,
0xf30a
,
0xf200
,
0xf200
,
};
u_short
alt_map
[
NR_KEYS
]
=
{
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf500
,
0xf501
,
0xf509
,
0xf502
,
0xf50a
,
0xf503
,
0xf50b
,
0xf504
,
0xf701
,
0xf505
,
0xf200
,
0xf506
,
0xf507
,
0xf508
,
0xf703
,
0xf603
,
0xf11d
,
0xf200
,
0xf209
,
0xf210
,
0xf200
,
0xf200
,
0xf600
,
0xf211
,
0xf81b
,
0xf831
,
0xf832
,
0xf833
,
0xf834
,
0xf835
,
0xf836
,
0xf837
,
0xf838
,
0xf839
,
0xf830
,
0xf82d
,
0xf83d
,
0xf860
,
0xf87f
,
0xf115
,
0xf03d
,
0xf30d
,
0xf30c
,
0xf200
,
0xf200
,
0xf310
,
0xf200
,
0xf114
,
0xf809
,
0xf871
,
0xf877
,
0xf865
,
0xf872
,
0xf874
,
0xf879
,
0xf875
,
0xf869
,
0xf86f
,
0xf870
,
0xf85b
,
0xf85d
,
0xf87f
,
0xf20e
,
0xf907
,
0xf908
,
0xf909
,
0xf30b
,
0xf200
,
0xf200
,
0xf117
,
0xf200
,
0xf702
,
0xf861
,
0xf873
,
0xf864
,
0xf866
,
0xf867
,
0xf868
,
0xf86a
,
0xf86b
,
0xf86c
,
0xf83b
,
0xf827
,
0xf85c
,
0xf80d
,
0xf30e
,
0xf904
,
0xf905
,
0xf906
,
0xf900
,
0xf200
,
0xf118
,
0xf200
,
0xf208
,
0xf700
,
0xf87a
,
0xf878
,
0xf863
,
0xf876
,
0xf862
,
0xf86e
,
0xf86d
,
0xf82c
,
0xf82e
,
0xf82f
,
0xf700
,
0xf00a
,
0xf901
,
0xf902
,
0xf903
,
0xf200
,
0xf200
,
0xf200
,
0xf11b
,
0xf207
,
0xf200
,
0xf820
,
0xf200
,
0xf119
,
0xf200
,
0xf30a
,
0xf200
,
0xf200
,
};
u_short
ctrl_alt_map
[
NR_KEYS
]
=
{
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf500
,
0xf501
,
0xf509
,
0xf502
,
0xf50a
,
0xf503
,
0xf50b
,
0xf504
,
0xf701
,
0xf505
,
0xf200
,
0xf506
,
0xf507
,
0xf508
,
0xf703
,
0xf603
,
0xf11d
,
0xf200
,
0xf200
,
0xf601
,
0xf200
,
0xf200
,
0xf600
,
0xf602
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf200
,
0xf115
,
0xf03d
,
0xf30d
,
0xf30c
,
0xf200
,
0xf200
,
0xf20c
,
0xf200
,
0xf114
,
0xf200
,
0xf811
,
0xf817
,
0xf805
,
0xf812
,
0xf814
,
0xf819
,
0xf815
,
0xf809
,
0xf80f
,
0xf810
,
0xf200
,
0xf200
,
0xf20c
,
0xf20e
,
0xf307
,
0xf308
,
0xf309
,
0xf30b
,
0xf200
,
0xf200
,
0xf117
,
0xf200
,
0xf702
,
0xf801
,
0xf813
,
0xf804
,
0xf806
,
0xf807
,
0xf808
,
0xf80a
,
0xf80b
,
0xf80c
,
0xf200
,
0xf200
,
0xf200
,
0xf201
,
0xf30e
,
0xf304
,
0xf305
,
0xf306
,
0xf300
,
0xf200
,
0xf118
,
0xf200
,
0xf208
,
0xf700
,
0xf81a
,
0xf818
,
0xf803
,
0xf816
,
0xf802
,
0xf80e
,
0xf80d
,
0xf200
,
0xf200
,
0xf200
,
0xf700
,
0xf00a
,
0xf301
,
0xf302
,
0xf303
,
0xf200
,
0xf200
,
0xf200
,
0xf11b
,
0xf207
,
0xf200
,
0xf200
,
0xf200
,
0xf119
,
0xf200
,
0xf30a
,
0xf200
,
0xf200
,
};
ushort
*
key_maps
[
MAX_NR_KEYMAPS
]
=
{
plain_map
,
shift_map
,
altgr_map
,
0
,
ctrl_map
,
shift_ctrl_map
,
0
,
0
,
alt_map
,
0
,
0
,
0
,
ctrl_alt_map
,
0
};
unsigned
int
keymap_count
=
7
;
/*
* Philosophy: most people do not define more strings, but they who do
* often want quite a lot of string space. So, we statically allocate
* the default and allocate dynamically in chunks of 512 bytes.
*/
char
func_buf
[]
=
{
'\033'
,
'['
,
'['
,
'A'
,
0
,
'\033'
,
'['
,
'['
,
'B'
,
0
,
'\033'
,
'['
,
'['
,
'C'
,
0
,
'\033'
,
'['
,
'['
,
'D'
,
0
,
'\033'
,
'['
,
'['
,
'E'
,
0
,
'\033'
,
'['
,
'1'
,
'7'
,
'~'
,
0
,
'\033'
,
'['
,
'1'
,
'8'
,
'~'
,
0
,
'\033'
,
'['
,
'1'
,
'9'
,
'~'
,
0
,
'\033'
,
'['
,
'2'
,
'0'
,
'~'
,
0
,
'\033'
,
'['
,
'2'
,
'1'
,
'~'
,
0
,
'\033'
,
'['
,
'2'
,
'3'
,
'~'
,
0
,
'\033'
,
'['
,
'2'
,
'4'
,
'~'
,
0
,
'\033'
,
'['
,
'2'
,
'5'
,
'~'
,
0
,
'\033'
,
'['
,
'2'
,
'6'
,
'~'
,
0
,
'\033'
,
'['
,
'2'
,
'8'
,
'~'
,
0
,
'\033'
,
'['
,
'2'
,
'9'
,
'~'
,
0
,
'\033'
,
'['
,
'3'
,
'1'
,
'~'
,
0
,
'\033'
,
'['
,
'3'
,
'2'
,
'~'
,
0
,
'\033'
,
'['
,
'3'
,
'3'
,
'~'
,
0
,
'\033'
,
'['
,
'3'
,
'4'
,
'~'
,
0
,
'\033'
,
'['
,
'1'
,
'~'
,
0
,
'\033'
,
'['
,
'2'
,
'~'
,
0
,
'\033'
,
'['
,
'3'
,
'~'
,
0
,
'\033'
,
'['
,
'4'
,
'~'
,
0
,
'\033'
,
'['
,
'5'
,
'~'
,
0
,
'\033'
,
'['
,
'6'
,
'~'
,
0
,
'\033'
,
'['
,
'M'
,
0
,
'\033'
,
'['
,
'P'
,
0
,
};
char
*
funcbufptr
=
func_buf
;
int
funcbufsize
=
sizeof
(
func_buf
);
int
funcbufleft
=
0
;
/* space left */
char
*
func_table
[
MAX_NR_FUNC
]
=
{
func_buf
+
0
,
func_buf
+
5
,
func_buf
+
10
,
func_buf
+
15
,
func_buf
+
20
,
func_buf
+
25
,
func_buf
+
31
,
func_buf
+
37
,
func_buf
+
43
,
func_buf
+
49
,
func_buf
+
55
,
func_buf
+
61
,
func_buf
+
67
,
func_buf
+
73
,
func_buf
+
79
,
func_buf
+
85
,
func_buf
+
91
,
func_buf
+
97
,
func_buf
+
103
,
func_buf
+
109
,
func_buf
+
115
,
func_buf
+
120
,
func_buf
+
125
,
func_buf
+
130
,
func_buf
+
135
,
func_buf
+
140
,
func_buf
+
145
,
0
,
0
,
func_buf
+
149
,
0
,
};
struct
kbdiacr
accent_table
[
MAX_DIACR
]
=
{
{
'`'
,
'A'
,
'\300'
},
{
'`'
,
'a'
,
'\340'
},
{
'\''
,
'A'
,
'\301'
},
{
'\''
,
'a'
,
'\341'
},
{
'^'
,
'A'
,
'\302'
},
{
'^'
,
'a'
,
'\342'
},
{
'~'
,
'A'
,
'\303'
},
{
'~'
,
'a'
,
'\343'
},
{
'"'
,
'A'
,
'\304'
},
{
'"'
,
'a'
,
'\344'
},
{
'O'
,
'A'
,
'\305'
},
{
'o'
,
'a'
,
'\345'
},
{
'0'
,
'A'
,
'\305'
},
{
'0'
,
'a'
,
'\345'
},
{
'A'
,
'A'
,
'\305'
},
{
'a'
,
'a'
,
'\345'
},
{
'A'
,
'E'
,
'\306'
},
{
'a'
,
'e'
,
'\346'
},
{
','
,
'C'
,
'\307'
},
{
','
,
'c'
,
'\347'
},
{
'`'
,
'E'
,
'\310'
},
{
'`'
,
'e'
,
'\350'
},
{
'\''
,
'E'
,
'\311'
},
{
'\''
,
'e'
,
'\351'
},
{
'^'
,
'E'
,
'\312'
},
{
'^'
,
'e'
,
'\352'
},
{
'"'
,
'E'
,
'\313'
},
{
'"'
,
'e'
,
'\353'
},
{
'`'
,
'I'
,
'\314'
},
{
'`'
,
'i'
,
'\354'
},
{
'\''
,
'I'
,
'\315'
},
{
'\''
,
'i'
,
'\355'
},
{
'^'
,
'I'
,
'\316'
},
{
'^'
,
'i'
,
'\356'
},
{
'"'
,
'I'
,
'\317'
},
{
'"'
,
'i'
,
'\357'
},
{
'-'
,
'D'
,
'\320'
},
{
'-'
,
'd'
,
'\360'
},
{
'~'
,
'N'
,
'\321'
},
{
'~'
,
'n'
,
'\361'
},
{
'`'
,
'O'
,
'\322'
},
{
'`'
,
'o'
,
'\362'
},
{
'\''
,
'O'
,
'\323'
},
{
'\''
,
'o'
,
'\363'
},
{
'^'
,
'O'
,
'\324'
},
{
'^'
,
'o'
,
'\364'
},
{
'~'
,
'O'
,
'\325'
},
{
'~'
,
'o'
,
'\365'
},
{
'"'
,
'O'
,
'\326'
},
{
'"'
,
'o'
,
'\366'
},
{
'/'
,
'O'
,
'\330'
},
{
'/'
,
'o'
,
'\370'
},
{
'`'
,
'U'
,
'\331'
},
{
'`'
,
'u'
,
'\371'
},
{
'\''
,
'U'
,
'\332'
},
{
'\''
,
'u'
,
'\372'
},
{
'^'
,
'U'
,
'\333'
},
{
'^'
,
'u'
,
'\373'
},
{
'"'
,
'U'
,
'\334'
},
{
'"'
,
'u'
,
'\374'
},
{
'\''
,
'Y'
,
'\335'
},
{
'\''
,
'y'
,
'\375'
},
{
'T'
,
'H'
,
'\336'
},
{
't'
,
'h'
,
'\376'
},
{
's'
,
's'
,
'\337'
},
{
'"'
,
'y'
,
'\377'
},
{
's'
,
'z'
,
'\337'
},
{
'i'
,
'j'
,
'\377'
},
};
unsigned
int
accent_table_size
=
68
;
drivers/sbus/char/sunkeymap.map
deleted
100644 → 0
View file @
40b4cd90
# Keyboard map for the Sun Type4/Type5 keyboards
# found on SparcStations
keymaps 0-2,4-5,8,12
#
#
# Stop/L1
keycode 0x01 =
# SND_LOWER
keycode 0x02 =
# Again/L2
keycode 0x03 =
# SND_LOUDER
keycode 0x04 =
keycode 0x05 = F1 F11 Console_13
control keycode 0x05 = F1
alt keycode 0x05 = Console_1
control alt keycode 0x05 = Console_1
keycode 0x06 = F2 F12 Console_14
control keycode 0x06 = F2
alt keycode 0x06 = Console_2
control alt keycode 0x06 = Console_2
keycode 0x07 = F10 F20 Console_22
control keycode 0x07 = F10
alt keycode 0x07 = Console_10
control alt keycode 0x07 = Console_10
keycode 0x08 = F3 F13 Console_15
control keycode 0x08 = F3
alt keycode 0x08 = Console_3
control alt keycode 0x08 = Console_3
keycode 0x09 = F11 F11 Console_23
control keycode 0x09 = F11
alt keycode 0x09 = Console_11
control alt keycode 0x09 = Console_11
keycode 0x0a = F4 F14 Console_16
control keycode 0x0a = F4
alt keycode 0x0a = Console_4
control alt keycode 0x0a = Console_4
keycode 0x0b = F12 F12 Console_24
control keycode 0x0b = F12
alt keycode 0x0b = Console_12
control alt keycode 0x0b = Console_12
keycode 0x0c = F5 F15 Console_17
control Keycode 0x0c = F5
alt keycode 0x0c = Console_5
control alt keycode 0x0c = Console_5
keycode 0x0d = AltGr
keycode 0x0e = F6 F16 Console_18
control keycode 0x0e = F6
alt keycode 0x0e = Console_6
control alt keycode 0x0e = Console_6
# BLANK KEY on type 5 keyboards
keycode 0x0f =
keycode 0x10 = F7 F17 Console_19
control keycode 0x10 = F7
alt keycode 0x10 = Console_7
control alt keycode 0x10 = Console_7
keycode 0x11 = F8 F18 Console_20
control keycode 0x11 = F8
alt keycode 0x11 = Console_8
control alt keycode 0x11 = Console_8
keycode 0x12 = F9 F19 Console_21
control keycode 0x12 = F9
alt keycode 0x12 = Console_9
control alt keycode 0x12 = Console_9
keycode 0x13 = Alt
keycode 0x14 = Up
keycode 0x15 = Pause
# Print Screen
keycode 0x16 =
keycode 0x17 = Scroll_Lock Show_Memory Show_Registers
control keycode 0x17 = Show_State
alt keycode 0x17 = Scroll_Lock
keycode 0x18 = Left
alt keycode 0x18 = Decr_Console
# Props/L3
keycode 0x19 =
# UNDO/L4
keycode 0x1a =
keycode 0x1b = Down
keycode 0x1c = Right
alt keycode 0x1c = Incr_Console
keycode 0x1d = Escape Escape
alt keycode 0x1d = Meta_Escape
keycode 0x1e = one exclam
alt keycode 0x1e = Meta_one
keycode 0x1f = two at at
control keycode 0x1f = nul
shift control keycode 0x1f = nul
alt keycode 0x1f = Meta_two
keycode 0x20 = three numbersign
control keycode 0x20 = Escape
alt keycode 0x20 = Meta_three
keycode 0x21 = four dollar dollar
control keycode 0x21 = Control_backslash
alt keycode 0x21 = Meta_four
keycode 0x22 = five percent
control keycode 0x22 = Control_bracketright
alt keycode 0x22 = Meta_five
keycode 0x23 = six asciicircum
control keycode 0x23 = Control_asciicircum
alt keycode 0x23 = Meta_six
keycode 0x24 = seven ampersand braceleft
control keycode 0x24 = Control_underscore
alt keycode 0x24 = Meta_seven
keycode 0x25 = eight asterisk bracketleft
control keycode 0x25 = Delete
alt keycode 0x25 = Meta_eight
keycode 0x26 = nine parenleft bracketright
alt keycode 0x26 = Meta_nine
keycode 0x27 = zero parenright braceright
alt keycode 0x27 = Meta_zero
keycode 0x28 = minus underscore backslash
control keycode 0x28 = Control_underscore
shift control keycode 0x28 = Control_underscore
alt keycode 0x28 = Meta_minus
keycode 0x29 = equal plus
alt keycode 0x29 = Meta_equal
keycode 0x2a = grave asciitilde
control keycode 0x2a = nul
alt keycode 0x2a = Meta_grave
# Is marked as BackSpace but we define it as delete just like the i386
# keyboard maps does
keycode 0x2b = Delete Delete
control keycode 0x2b = BackSpace
alt keycode 0x2b = Meta_Delete
keycode 0x2c = Insert
# This is really keypad = on type 4 keyboards
keycode 0x2d = equal
keycode 0x2e = KP_Divide
keycode 0x2f = KP_Multiply
# Power ON/OFF key on type 5 keyboard
keycode 0x30 =
# FRONT/L5
keycode 0x31 =
keycode 0x32 = KP_Period
# altgr control keycode 0x32 = Boot
control alt keycode 0x32 = Boot
# COPY/L6
keycode 0x33 =
# Home key, same difference
keycode 0x34 = Find
keycode 0x35 = Tab Tab
alt keycode 0x35 = Meta_Tab
keycode 0x36 = q
keycode 0x37 = w
keycode 0x38 = e
altgr keycode 0x38 = Hex_E
keycode 0x39 = r
keycode 0x3a = t
keycode 0x3b = y
keycode 0x3c = u
keycode 0x3d = i
keycode 0x3e = o
keycode 0x3f = p
keycode 0x40 = bracketleft braceleft
control keycode 0x40 = Escape
alt keycode 0x40 = Meta_bracketleft
keycode 0x41 = bracketright braceright asciitilde
control keycode 0x41 = Control_bracketright
alt keycode 0x41 = Meta_bracketright
keycode 0x42 = Delete Delete
control keycode 0x42 = BackSpace
alt keycode 0x42 = Meta_Delete
control alt keycode 0x42 = Boot
keycode 0x43 = Compose
keycode 0x44 = KP_7
alt keycode 0x44 = Ascii_7
altgr keycode 0x44 = Hex_7
keycode 0x45 = KP_8
alt keycode 0x45 = Ascii_8
altgr keycode 0x45 = Hex_8
keycode 0x46 = KP_9
alt keycode 0x46 = Ascii_9
altgr keycode 0x46 = Hex_9
keycode 0x47 = KP_Subtract
# OPEN/L6
keycode 0x48 =
# PASTE/L8
keycode 0x49 =
keycode 0x4a = Select
# No key produces 0x4b to my knowledge
keycode 0x4b =
keycode 0x4c = Control
keycode 0x4d = a
altgr keycode 0x4d = Hex_A
keycode 0x4e = s
keycode 0x4f = d
altgr keycode 0x4f = Hex_D
keycode 0x50 = f
altgr keycode 0x50 = Hex_F
keycode 0x51 = g
keycode 0x52 = h
keycode 0x53 = j
keycode 0x54 = k
keycode 0x55 = l
keycode 0x56 = semicolon colon
alt keycode 0x56 = Meta_semicolon
keycode 0x57 = apostrophe quotedbl
control keycode 0x57 = Control_g
alt keycode 0x57 = Meta_apostrophe
keycode 0x58 = backslash bar
control keycode 0x58 = Control_backslash
alt keycode 0x58 = Meta_backslash
keycode 0x59 = Return
alt keycode 0x59 = Meta_Control_m
keycode 0x5a = KP_Enter
keycode 0x5b = KP_4
alt keycode 0x5b = Ascii_4
altgr keycode 0x5b = Hex_4
keycode 0x5c = KP_5
alt keycode 0x5c = Ascii_5
altgr keycode 0x5c = Hex_5
keycode 0x5d = KP_6
alt keycode 0x5d = Ascii_6
altgr keycode 0x5d = Hex_6
keycode 0x5e = KP_0
alt keycode 0x5e = Ascii_0
altgr keycode 0x5e = Hex_0
# FIND/L9
keycode 0x5f =
keycode 0x60 = Prior
shift keycode 0x60 = Scroll_Backward
# CUT/L10
keycode 0x61 =
keycode 0x62 = Num_Lock
# Linux/i386 console makes no distinction between right/left shift
# so neither do we.
keycode 0x63 = Shift
keycode 0x64 = z
keycode 0x65 = x
keycode 0x66 = c
altgr keycode 0x66 = Hex_C
keycode 0x67 = v
keycode 0x68 = b
altgr keycode 0x68 = Hex_B
keycode 0x69 = n
keycode 0x6a = m
keycode 0x6b = comma less
alt keycode 0x6b = Meta_comma
keycode 0x6c = period greater
control keycode 0x6c = Compose
alt keycode 0x6c = Meta_period
keycode 0x6d = slash question
control keycode 0x6d = Delete
alt keycode 0x6d = Meta_slash
keycode 0x6e = Shift
keycode 0x6f = Linefeed
keycode 0x70 = KP_1
alt keycode 0x70 = Ascii_1
altgr keycode 0x70 = Hex_1
keycode 0x71 = KP_2
alt keycode 0x71 = Ascii_2
altgr keycode 0x71 = Hex_2
keycode 0x72 = KP_3
alt keycode 0x72 = Ascii_3
altgr keycode 0x72 = Hex_3
# To my knowledge no key produces 0x73, 0x74, or 0x75
keycode 0x73 =
keycode 0x74 =
keycode 0x75 =
keycode 0x76 = Help
keycode 0x77 = Caps_Lock
# A True Meta-key, unused at this time
keycode 0x78 =
keycode 0x79 = space space
control keycode 0x79 = nul
alt keycode 0x79 = Meta_space
# Another real Meta-key, again unused
keycode 0x7a =
keycode 0x7b = Next
shift keycode 0x7b = Scroll_Forward
# No keys produce the following
keycode 0x7c =
keycode 0x7d = KP_Add
keycode 0x7e =
# keycode 0x7f is special and it means 'all keys released' and is
# taken care of within the sun keyboard driver itself
keycode 0x7f =
# That's all folks...
string F1 = "\033[[A"
string F2 = "\033[[B"
string F3 = "\033[[C"
string F4 = "\033[[D"
string F5 = "\033[[E"
string F6 = "\033[17~"
string F7 = "\033[18~"
string F8 = "\033[19~"
string F9 = "\033[20~"
string F10 = "\033[21~"
string F11 = "\033[23~"
string F12 = "\033[24~"
string F13 = "\033[25~"
string F14 = "\033[26~"
string F15 = "\033[28~"
string F16 = "\033[29~"
string F17 = "\033[31~"
string F18 = "\033[32~"
string F19 = "\033[33~"
string F20 = "\033[34~"
string Find = "\033[1~"
string Insert = "\033[2~"
string Remove = "\033[3~"
string Select = "\033[4~"
string Prior = "\033[5~"
string Next = "\033[6~"
string Macro = "\033[M"
string Pause = "\033[P"
compose '`' 'A' to ''
compose '`' 'a' to ''
compose '\'' 'A' to ''
compose '\'' 'a' to ''
compose '^' 'A' to ''
compose '^' 'a' to ''
compose '~' 'A' to ''
compose '~' 'a' to ''
compose '"' 'A' to ''
compose '"' 'a' to ''
compose 'O' 'A' to ''
compose 'o' 'a' to ''
compose '0' 'A' to ''
compose '0' 'a' to ''
compose 'A' 'A' to ''
compose 'a' 'a' to ''
compose 'A' 'E' to ''
compose 'a' 'e' to ''
compose ',' 'C' to ''
compose ',' 'c' to ''
compose '`' 'E' to ''
compose '`' 'e' to ''
compose '\'' 'E' to ''
compose '\'' 'e' to ''
compose '^' 'E' to ''
compose '^' 'e' to ''
compose '"' 'E' to ''
compose '"' 'e' to ''
compose '`' 'I' to ''
compose '`' 'i' to ''
compose '\'' 'I' to ''
compose '\'' 'i' to ''
compose '^' 'I' to ''
compose '^' 'i' to ''
compose '"' 'I' to ''
compose '"' 'i' to ''
compose '-' 'D' to ''
compose '-' 'd' to ''
compose '~' 'N' to ''
compose '~' 'n' to ''
compose '`' 'O' to ''
compose '`' 'o' to ''
compose '\'' 'O' to ''
compose '\'' 'o' to ''
compose '^' 'O' to ''
compose '^' 'o' to ''
compose '~' 'O' to ''
compose '~' 'o' to ''
compose '"' 'O' to ''
compose '"' 'o' to ''
compose '/' 'O' to ''
compose '/' 'o' to ''
compose '`' 'U' to ''
compose '`' 'u' to ''
compose '\'' 'U' to ''
compose '\'' 'u' to ''
compose '^' 'U' to ''
compose '^' 'u' to ''
compose '"' 'U' to ''
compose '"' 'u' to ''
compose '\'' 'Y' to ''
compose '\'' 'y' to ''
compose 'T' 'H' to ''
compose 't' 'h' to ''
compose 's' 's' to ''
compose '"' 'y' to ''
compose 's' 'z' to ''
compose 'i' 'j' to ''
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment