Skip to content

Instantly share code, notes, and snippets.

@jbmorley
Last active February 5, 2018 13:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbmorley/81b2f723207c7f52501df9a0239c7142 to your computer and use it in GitHub Desktop.
Save jbmorley/81b2f723207c7f52501df9a0239c7142 to your computer and use it in GitHub Desktop.
/*
* arch/arm/drivers/char/keyboard_psion.c - Keyboard Driver for Psion
*
* Copyright (C) 1998 Roger Gammans
* Copyright (C) 2001 Tony Lindgren <tony@atomide.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/config.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/arch/keyboard.h>
#include <linux/tqueue.h>
#include <linux/kbd_ll.h>
#include <linux/tty_flip.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/hardware/psionw.h>
#include "keyboard_psion.h"
/* callback function for auto sleep */
void (*psion_sleep_set_callback)(void);
extern void psionw_lcd_powerdown(int lock);
extern void psionw_lcd_powerup(int lock);
unsigned int kbd_delay[] = KB_DELAY;
static int keysdown = 0;
static struct tq_struct kbdhw_task;
#ifdef CONFIG_MAGIC_SYSRQ
unsigned char kbdpsion_sysrq_xlate[] =
"\000" "6" "5" "4" "3" "2" "1" "\000"
"\000" "'" "\000" "0" "9" "8" "7" "\000"
"\000" "y" "t" "r" "e" "w" "q" "\000"
"\000" "\012" "l" "p" "o" "i" "u" "\000"
"\000" "g" "f" "d" "s" "a" "\011" "\000"
"\000" "\000" "." "m" "k" "j" "h" "\000"
"\000" "n" "b" "v" "c" "x" "z" "\000"
"\000" "\000" "\000" "," "\000" " " "\000";
#endif
void psion_cleartable(void)
{
int key;
unsigned int t;
for (key = 0; key < NR_KEYCODES; key++) {
if (!kbdstate[key].in)
continue;
/*
* dont worry these ops are commutative and
* assoicative
*/
t = (jiffies - kbdstate[key].jif) & KB_JIFMASK;
if (t>KB_DEB_JIFFY) {
/* Keboard could have changed meanwhile */
kbdstate[key].in = 0;
keysdown--;
/* printk("Releasing key:%x\n",key); */
handle_scancode(key, 0);
}
}
}
static void kbd_press(int keycode)
{
unsigned char newpress = 0;
if (!kbdstate[keycode].in) {
keysdown++;
newpress = 1;
/* printk("Keycode: %d (0x%x)\n", keycode, keycode); */
}
/*
* We approximate a retriggable monostable
* action.
*/
kbdstate[keycode].in=1;
/* We only need to ensure keysdown consistent */
kbdstate[keycode].jif = jiffies & KB_JIFMASK;
if (newpress) {
handle_scancode(keycode, 1);
if (psion_sleep_set_callback != 0)
(*psion_sleep_set_callback)();
}
}
static void psion_tick(void* dummy)
{
int col,row;
int rowd;
int count=0;
unsigned char state;
/*
* Check if any keys are depressed
*/
for (col = 0; col < 8; col++) {
udelay(kbd_delay[8]);
state = psionw_readl(KSCAN);
state &= ~KBDSCAN;
state |= (KBSC_COL0 + col);
psionw_writel(state, KSCAN);
udelay(kbd_delay[col]);
rowd = psionw_readl(PADR) & 0xff;
if (!rowd)
continue;
for (row=0; row < KB_LASTROW; row++) {
if (rowd & KB_ROWMASK(row)) {
kbd_press(KEYCODE(row,col));
count++;
}
}
};
if (count != keysdown) {
psion_cleartable();
}
/*
* Re-queue ourselves
*/
queue_task(&kbdhw_task,&tq_timer);
}
void kbdpsion_hw_init(void)
{
kbdhw_task.routine = psion_tick;
kbdhw_task.sync = 0;
queue_task(&kbdhw_task,&tq_timer);
}
int kbdpsion_translate(unsigned char scancode, unsigned char *keycode_p)
{
*keycode_p = scancode & ~(KBDOWN | KBUP);
return 1;
}
#if defined(CONFIG_VT) && defined(CONFIG_MAGIC_SYSRQ)
extern int sysrq_pressed;
#endif
void psion_arch_handler(unsigned char value, char up_flag)
{
#if defined(CONFIG_VT) && defined(CONFIG_MAGIC_SYSRQ)
if (value == 1) {
sysrq_pressed = !up_flag;
return;
}
#endif
if (up_flag) return;
switch (value) {
#ifdef KBD_ARCHKEY_2
case 2:
KBD_ARCHKEY_2;
break;
#endif
#ifdef KBD_ARCHKEY_3
case 3:
KBD_ARCHKEY_3;
break;
#endif
#ifdef KBD_ARCHKEY_4
case 4:
KBD_ARCHKEY_4;
break;
#endif
#ifdef KBD_ARCHKEY_5
case 5:
KBD_ARCHKEY_5;
break;
#endif
#ifdef KBD_ARCHKEY_6
case 6:
KBD_ARCHKEY_6;
break;
#endif
#ifdef KBD_ARCHKEY_7
case 7:
KBD_ARCHKEY_7;
break;
#endif
#ifdef KBD_ARCHKEY_8
case 8:
KBD_ARCHKEY_8;
break;
#endif
#ifdef KBD_ARCHKEY_9
case 9:
KBD_ARCHKEY_9;
break;
#endif
#ifdef KBD_ARCHKEY_10
case 10:
KBD_ARCHKEY_10;
break;
#endif
#ifdef KBD_ARCHKEY_11
case 11:
KBD_ARCHKEY_11;
break;
#endif
default:
return;
}
}
void psion_toggle_backlight()
{
int pcdr;
long flags;
if ((psionw_readl(LCDCTL) & LCDCTL_EN) == 0)
psionw_lcd_powerup(1);
save_flags_cli(flags);
pcdr = psionw_readl(PCDR);
pcdr ^= PCDR_LIGHT;
psionw_writel(pcdr, PCDR);
restore_flags(flags);
}
/*
* Contrast table. Upper four bits: output value, lower four bits: direction
* (0 = in = Z)
*/
#define V0 0
#define V1 1
#define VZ 0
#define D0 1
#define D1 1
#define DZ 0
#define C(a,b,c,d) \
((V##a << 7) | (V##b << 6) | (V##c << 5) | (V##d << 4) | \
(D##a << 3) | (D##b << 2) | (D##c << 1) | D##d)
static __u8 contrast_table[] = {
C(1,1,1,1), C(1,1,1,Z), C(1,1,1,0), C(1,1,Z,1), /* 1- 4 */
C(1,1,Z,Z), C(1,1,0,1), C(1,1,Z,0), C(1,Z,1,1), /* 5- 8 */
C(1,1,0,0), C(1,Z,1,Z), C(1,Z,1,0), C(1,Z,Z,1), /* 9-12 */
C(1,0,1,1), C(1,Z,Z,Z), C(1,Z,0,1), C(1,0,1,Z), /* 13-16 */
C(1,0,1,0), C(1,0,Z,1), C(1,Z,0,0), C(Z,1,1,Z), /* 17-20 */
C(1,0,Z,Z), C(1,0,0,1), C(1,0,Z,0), C(1,0,0,Z), /* 21-24 */
C(Z,1,Z,Z), C(1,0,0,0), C(Z,1,Z,0), C(Z,1,0,Z), /* 25-28 */
C(Z,1,0,0), C(Z,Z,1,Z), C(Z,Z,1,0), C(Z,Z,Z,1), /* 29-32 */
C(0,1,1,0), C(0,1,Z,1), C(Z,Z,0,1), C(Z,0,1,Z), /* 33-36 */
C(0,1,Z,Z), C(Z,Z,0,Z), C(0,1,Z,0), C(Z,Z,0,0), /* 37-40 */
C(0,1,0,Z), C(Z,0,Z,Z), C(0,1,0,0), C(Z,0,Z,0), /* 41-44 */
C(0,Z,1,0), C(0,Z,Z,1), C(Z,0,0,0), C(0,0,1,1), /* 45-48 */
C(0,Z,Z,Z), C(0,Z,0,1), C(0,Z,Z,0), C(0,0,1,0), /* 49-52 */
C(0,0,Z,1), C(0,Z,0,0), C(0,0,Z,Z), C(0,0,0,1), /* 53-56 */
C(0,0,Z,0), C(0,0,0,Z), C(0,0,0,0) /* 57-60 */
};
static int contrast = 40;
int psion_get_contrast(void)
{
return contrast;
}
int psion_set_contrast(int new_contrast, int lock)
{
long flags = 0;
if ((new_contrast >= 0) && (new_contrast < sizeof(contrast_table))) {
contrast = new_contrast;
}
else {
printk("Bad contrast value: %i, should be between 0 - %d\n",
new_contrast, sizeof(contrast_table) - 1);
return -EINVAL;
}
if (lock)
save_flags_cli(flags);
psionw_writeb((psionw_readb(PBDR) & ~PBDR_VLD_MASK) |
((contrast_table[contrast] >> 4) << PBDR_VLD_SHIFT),
PBDR);
psionw_writeb((psionw_readb(PBDDR) & ~PBDR_VLD_MASK) |
((contrast_table[contrast] & 0xf) << PBDR_VLD_SHIFT),
PBDDR);
if (lock)
restore_flags(flags);
return 0;
}
void psion_contrast(int increase)
{
if (increase)
if (contrast == sizeof(contrast_table)-1) return;
else contrast++;
else if (!contrast) return;
else contrast--;
psion_set_contrast(contrast, 1);
}
void debug_gpio(void)
{
printk("\nPADR=0x%02x PBDR=0x%02x PCDR=0x%02x PDDR=0x%02x PEDR=0x%02x ",
psionw_readb(PADR),
psionw_readb(PBDR),
psionw_readb(PCDR),
psionw_readb(PDDR),
psionw_readb(PEDR));
printk("PADDR=0x%02x PBDDR=0x%02x\n",
psionw_readb(PADDR),
psionw_readb(PBDDR));
}
/*
* arch/arm/drivers/char/keyboard_psion.h
*
* Psion keyboard definitions.
*
* Copyright (C) 1998 Roger Gammans
* Copyright (C) 2000 Tony Lindgren <tony@atomide.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASM_ARCH_PSION_H
#define __ASM_ARCH_PSION_H
#include <asm/arch/hardware.h>
#define KBDSCAN 0x0000000f /* Keyboard scan */
#define KBSC_HI 0x0 /* All driven high */
#define KBSC_LO 0x1 /* All driven low */
#define KBSC_X 0x2 /* All high impedance */
#define KBSC_COL0 0x8 /* Col 0 high, others high impedance */
#define KBSC_COL1 0x9 /* Col 1 high, others high impedance */
#define KBSC_COL2 0xa /* Col 2 high, others high impedance */
#define KBSC_COL3 0xb /* Col 3 high, others high impedance */
#define KBSC_COL4 0xc /* Col 4 high, others high impedance */
#define KBSC_COL5 0xd /* Col 5 high, others high impedance */
#define KBSC_COL6 0xe /* Col 6 high, others high impedance */
#define KBSC_COL7 0xf /* Col 7 high, others high impedance */
#define KB_JIFMASK (127)
/*
* Arm's keyboard is active high row select...
* (must try to remember)
*/
#define KB_ALLCOLS KBSC_HI
#define KB_DISCHARGE KBSC_LO
#define KB_LASTROW 7
#define KBUP (0x80)
#define KBDOWN (0)
/*
* Later on we'll try a struct of
* two arrays then the existing keyboard.c can
* test our array directly but until then....
*/
typedef struct {
int in:1; /* If the key down */
int jif:7; /* how long has key been down for (approx) */
} kbd_keyinfo;
static kbd_keyinfo kbdstate[NR_KEYCODES];
#ifdef KB_DELAY
extern unsigned int kbd_delay[];
#endif
/*
* Be sure to change the if you increase the
* number of kbd rows...
*/
#define KEYCODE(r,c) ( ((c)<<3) + (r)+1)
#define KB_ROWMASK(r) (1 << (r))
/*
* KB_DELAY is used to allow the matrix
* to stabilize.., value is determined via
* experimentation.
*/
#define KB_DELAY {16 ,16 ,16 ,16 ,16 ,16 ,16 ,16 ,16}
/*
* Not sure whether this trick works yet!
*
*/
#undef KBD_SUPPORTS_WIREOR
/*
* treat debounce monostable as 30ms
*/
#define KB_DEB_JIFFY (30/HZ)
extern void psion_off(void);
void psion_toggle_backlight(void);
void psion_contrast(int increase);
void psion_debug_cf(void);
/*
* Architecture-specific keys. Value 0 is invalid. 1 is SysRq.
* Ctrl-Alt = Ctrl-Menu on Psion, For example: SysRq = Ctrl-Menu-,
*/
#define KBD_ARCHKEY_2 psion_off() /* Fn-Off */
#define KBD_ARCHKEY_3 psion_toggle_backlight() /* Fn-Space */
#define KBD_ARCHKEY_4 psion_contrast(0) /* Fn-- */
#define KBD_ARCHKEY_5 psion_contrast(1) /* Fn-+ */
/* KBD_ARCHKEY_6 to KBD_ARCHKEY_11 reserved for debugging */
#define KBD_ARCHKEY_6 0 /* Ctrl-Menu-z */
#ifdef CONFIG_PCMCIA_ETNA
extern void psion_debug_etna(void);
#define KBD_ARCHKEY_7 psion_debug_etna() /* Ctrl-Menu-x */
#else
#define KBD_ARCHKEY_7 debug_gpio() /* Ctrl-Menu-x */
#endif
#define KBD_ARCHKEY_8 0 /* Ctrl-Menu-c */
#define KBD_ARCHKEY_9 0 /* Ctrl-Menu-v */
#define KBD_ARCHKEY_8 0
#define KBD_ARCHKEY_9 0
#endif
# arch/arm/drivers/char/keymap_psion.map - UK (default) keyboard map
#
# Written 1998,1999 by Werner Almesberger
#
# based on keymap_geo.map, string and compose def's taken from
# drivers/char/defkeymap.map
#
# Special keys:
# F13 REC F14 STOP F15 PLAY
# F16 Contrast-- F17 Contrast++ F18 Backlight
# Default kernel keymap. This uses 7 modifier combinations.
keymaps 0-2,4-5,8,12
keycode 1 = six asciicircum
alt keycode 1 = Console_6
altgr keycode 1 = greater
control keycode 1 = Control_asciicircum
keycode 2 = five percent
alt keycode 2 = Console_5
altgr keycode 2 = less
keycode 3 = four dollar
alt keycode 3 = Console_4
altgr keycode 3 = at
keycode 4 = three sterling
alt keycode 4 = Console_3
altgr keycode 4 = backslash
control keycode 4 = Control_backslash
keycode 5 = two quotedbl
alt keycode 5 = Console_2
altgr keycode 5 = numbersign
keycode 6 = one exclam
alt keycode 6 = Console_1
altgr keycode 6 = underscore
control keycode 6 = Control_underscore
keycode 7 = F13 # REC
keycode 8 = VoidSymbol
keycode 9 = apostrophe asciitilde
altgr keycode 9 = colon
keycode 10 = Delete
alt keycode 10 = Remove
altgr keycode 10 = grave
control alt keycode 10 = Boot
keycode 11 = zero parenright
alt keycode 11 = Console_10
altgr keycode 11 = braceright
keycode 12 = nine parenleft
alt keycode 12 = Console_9
altgr keycode 12 = braceleft
keycode 13 = eight asterisk
alt keycode 13 = Console_8
altgr keycode 13 = bracketright
control keycode 13 = Control_bracketright
keycode 14 = seven ampersand
alt keycode 14 = Console_7
altgr keycode 14 = bracketleft
control keycode 14 = Escape
keycode 15 = F15 # PLAY
keycode 16 = VoidSymbol
keycode 17 = y
altgr keycode 17 = KP_Multiply
keycode 18 = t
altgr keycode 18 = bar
keycode 19 = r
keycode 20 = e
keycode 21 = w
keycode 22 = q
keycode 23 = Escape Escape
alt keycode 23 = Meta_Escape
altgr keycode 23 = 0xf02 # OFF
keycode 24 = VoidSymbol
keycode 25 = Return
keycode 26 = l
altgr keycode 26 = semicolon
keycode 27 = p
altgr keycode 27 = equal
keycode 28 = o
altgr keycode 28 = minus
keycode 29 = i
altgr keycode 29 = plus
keycode 30 = u
altgr keycode 30 = KP_Divide
keycode 31 = SAlt # Menu
keycode 32 = VoidSymbol
keycode 33 = g
keycode 34 = f
keycode 35 = d
keycode 36 = s
keycode 37 = a
keycode 38 = Tab
altgr keycode 38 = Caps_Lock
keycode 39 = SControl
keycode 40 = VoidSymbol
keycode 41 = Down Scroll_Backward
altgr keycode 41 = Prior
keycode 42 = period question
altgr keycode 42 = 0xf05 # Contrast++
keycode 43 = m
altgr keycode 43 = 0xf04 # Contrast--
keycode 44 = k
keycode 45 = j
keycode 46 = h
keycode 47 = SAltGr # Fn
keycode 48 = VoidSymbol
keycode 49 = n
control alt keycode 49 = 0xf0b # Debug 5
keycode 50 = b
control alt keycode 50 = 0xf0a # Debug 4
keycode 51 = v
control alt keycode 51 = 0xf09 # Debug 3
keycode 52 = c
control alt keycode 52 = 0xf08 # Debug 2
keycode 53 = x
control alt keycode 53 = 0xf07 # Debug 1
keycode 54 = z
control alt keycode 54 = 0xf06 # Debug 0
keycode 55 = SShift
keycode 56 = VoidSymbol
keycode 57 = Right
altgr keycode 57 = Select # End
keycode 58 = Left
altgr keycode 58 = Find # Home
keycode 59 = comma slash
control alt keycode 59 = 0xf01 # SysRq
keycode 60 = Up Scroll_Forward
altgr keycode 60 = Next
keycode 61 = space
altgr keycode 61 = 0xf03 # Backlight
keycode 62 = F14 # STOP
keycode 63 = SShift
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 'ÿ'
/*
* linux/include/asm-arm/hardware/psionw.h
*
* This file contains the hardware definitions of the PSIONW internal
* registers.
*
* Copyright (C) 2001 Tony Lindgren <tony@atomide.com>
* Copyright (C) 2001 Yuji Shinokawa <ysh@mob.or.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ************************ NOTE FOR DEVELOPERS ***************************
*
* Please see also the "Windermere Software Interface Specification"
* PDF file. (Series_5mx_specs.pdf)
*
* This file is not publicly available, but is available for Linux
* developers without a NDA. Thank you Psion!
*
* Please contact the PsiLinux mailing list at:
*
* linux-7110-psion@lists.sourceforge.net
*
* to get a copy of this file.
*
* ************************************************************************
*/
#ifndef __ASM_HARDWARE_PSIONW_H
#define __ASM_HARDWARE_PSIONW_H
#define PSIONW_PHYS_BASE (0x80000000)
#ifndef __ASSEMBLY__
#define psionw_readb(off) __raw_readb(PSIONW_BASE + (off))
#define psionw_readl(off) __raw_readl(PSIONW_BASE + (off))
#define psionw_writeb(val,off) __raw_writeb(val, PSIONW_BASE + (off))
#define psionw_writel(val,off) __raw_writel(val, PSIONW_BASE + (off))
#endif
/*
* LCD Controller
*/
#define PSION_HSW (0x02 << 10) /* Horiz sync pulse width */
#define PSION_HFP (0x01 << 16) /* Horiz front porch */
#define PSION_HBP (0x01 << 24) /* Horiz back porch */
#define PSION_VSW (0x02 << 10) /* Vert sync pulse width */
#define PSION_VFP (0x01 << 16) /* Vert front porch */
#define PSION_VBP (0x01 << 24) /* Vert back porch */
#if defined(CONFIG_PSIONW_REVO) || defined(CONFIG_PSIONW_REVOPLUS)
#define PSION_LCD_W 480 /* LCD width */
#define PSION_LCD_H 160 /* LCD heigth */
#define PSION_ACB (0xc << 8) /* AC-bias frequency */
#else
#define PSION_LCD_W 640 /* LCD width */
#define PSION_LCD_H 240 /* LCD height */
#define PSION_ACB (0xb << 8) /* AC-bias frequency */
#endif
#define PSION_LCD_OFF 0xd000 /* LCD memory start offset */
#define LCD_PAL_SIZE (0x20) /* LCD palette size */
#define LCD_BUF_SIZE (PSION_LCD_W*PSION_LCD_H*4/8) /* LCD buffer size */
#define LCD_MEM_SIZE (LCD_PAL_SIZE + LCD_BUF_SIZE) /* LCD memory size */
#define LCD_MEM_START PAGE_OFFSET + PSION_LCD_OFF /* LCD memory start offset */
#define LCD_PAL_START LCD_MEM_START /* LCD palette start offset */
#define LCD_BUF_START LCD_PAL_START + LCD_PAL_SIZE /* LCD buffer start offset */
#define LCDCTL (0x0200)
#define LCDCTL_EN (1 << 0)
#define LCDCTL_BW (1 << 1)
#define LCDCTL_DP (1 << 2)
#define LCDCTL_DONE (1 << 3)
#define LCDCTL_NEXT (1 << 4)
#define LCDCTL_ERR (1 << 5)
#define LCDCTL_TFT (1 << 7)
#define LCDCTL_M8B (1 << 8)
#define LCDST (0x0204)
#define LCDST_NEXT (1 << 1)
#define LCDST_BER (1 << 2)
#define LCDST_ABC (1 << 3)
#define LCDST_FUF (1 << 5)
#define LCD_DBAR1 (0x0210)
#define LCDT0 (0x0220)
#define LCDT1 (0x0224)
#define LCDT2 (0x0228)
#define LCDT2_IVS (1 << 20)
#define LCDT2_IHS (1 << 21)
#define LCDT2_IPC (1 << 22)
#define LCDT2_IEO (1 << 23)
#define LCD_DEF_CMASK (0x10) /* Default value for the LCD contrast */
/*
* ETNA PCMCIA Controller
*/
#if defined(CONFIG_PSIONW_5MXPRO24MB) || defined(CONFIG_PSIONW_5MXPRO32MB)
#define ETNA_P_BASE 0x50000000 /* ETNA controller physical base */
#else
#define ETNA_P_BASE 0x20000000 /* ETNA controller physical base */
#endif
#define ETNA_V_BASE 0xde000000 /* ETNA controller virtual base */
#define ETNA_SIZE 0x00100000 /* ETNA controller size */
#define ETNA_UNKNOWN_0 0x0 /* Seems to be always 0x0f */
#define ETNA_UNKNONW_1 0x1 /* Seems to be always 0x00 */
#define ETNA_UNKNOWN_2 0x2 /* Seems to be always 0x02 */
#define ETNA_UNKNOWN_3 0x3 /* Seems to be always 0x00 */
#define ETNA_UNKNOWN_4 0x4 /* Seems to be always 0x00 */
#define ETNA_UNKNOWN_5 0x5 /* Seems to be always 0x00 */
#define ETNA_INT_STATUS 0x6 /* ETNA interrupt Status */
#define ETNA_INT_MASK 0x7 /* ETNA interrupt Mask */
#define ETNA_INT_CLEAR 0x8 /* ETNA interrupt Clear */
#define ETNA_SKT_STATUS 0x9 /* Socket status ??? */
#define ETNA_SKT_CFG 0xa /* Socket config ??? */
#define ETNA_SKT_CTRL 0xb /* Enable socket ??? */
#define ETNA_WAKE_1 0xc /* Socket wake up; Usually 0x88, goes to 0x00 after STBY */
#define ETNA_SKT_ACTIVE 0xd /* Socket active ??? */
#define ETNA_UNKNOWN_E 0xe /* Seems to be always 0x00 */
#define ETNA_WAKE_2 0xf /* Socket wake up; Usually 0x10, goes to 0x00 after STBY */
#define SKT_BUSY (1 << 0) /* ETNA socket busy */
#define SKT_NOT_READY (1 << 1) /* ETNA socket not ready */
#define SKT_CARD_OUT (1 << 2) /* ETNA card out */
#define ETNA_CARD_INT (1 << 0) /* ETNA card interrupt */
#define ETNA_BUSY_INT (1 << 2) /* ETNA socket interrupt */
#define ETNA_SOCK_INT1 (1 << 4)
#define ETNA_SOCK_INT2 (1 << 5)
#define CARD_INT_MASK 0x05 /* Normal card interrupt = ETNA_CARD_INT | ETNA_BUSY_INT */
#define ETNA_CLEAR_MASK 0xff /* Clear ETNA interrupt */
#define ETNA_CF_IRQ 0x01 /* Enable ETNA Interrupt */
#if defined(CONFIG_PSIONW_5MXPRO24MB) || defined(CONFIG_PSIONW_5MXPRO32MB)
#define CF1_P_BASE 0x30000000 /* PCMCIA physical base */
#else
#define CF1_P_BASE 0x40000000 /* PCMCIA physical base */
#endif
#define CF1_V_BASE 0xe0000000 /* PCMCIA virtual base */
#define CF_SIZE 0x10000000 /* 4 areas of 64MB each */
#define CF_ATTR_BASE 0x00000000 /* This is needed, or it won't work!!! */
#define CF_MEM_BASE 0x04000000 /* Address bit 26 set */
#define CF_IO8_BASE 0x08000000 /* Address bit 27 set */
#define CF_IO16_BASE 0x0c000000 /* Address bits 26 & 27 set */
#define CF_CFG_REG 0x003c
#define CF_CFG_VAL 0x00730069 /* Epoc value from e 0x5801603c in ArLo */
#define CF_CUR_CFG 0x200
/*
* Boot EEPROM used by Epoc (Verified on 5mx Pro 32MB only)
*/
#define PSION_P_BR 0x00000000
#define PSION_V_BR 0xde200000
#define PSION_BR_SIZE (1024*128)
/*
* Boot Flash used by Epoc, not used in 5mx Pro (Not verified on 5mx)
*/
#define PSION_P_BF 0x10000000
#define PSION_V_BF 0xde300000
#define PSION_BF_SIZE (1024*1024*2)
/*
* GPIO/KBD Registers
*/
#define PADR (0x0e00)
#define PBDR (0x0e04)
#define PCDR (0x0e08)
#define PDDR (0x0e0c)
#define PADDR (0x0e10)
#define PBDDR (0x0e14)
#define PCDDR (0x0e18)
#define PDDDR (0x0e1c)
#define PEDR (0x0e20)
#define PEDDR (0x0e24)
#define KSCAN (0x0e28)
#define LCDMUX (0x0e2c)
/*
* Port A, Keyboard
*/
#define PADR_0 (1 << 0)
#define PADR_1 (1 << 1)
#define PADR_2 (1 << 2)
#define PADR_3 (1 << 3)
#define PADR_4 (1 << 4)
#define PADR_5 (1 << 5)
#define PADR_6 (1 << 6)
#define PADR_7 (1 << 7)
/*
* Port B, Data copied from Psion 5 code
*
* +--7--+--6--+--5--+--4--+--3--+--2--+--1--+--0--+
* |VPCEN|OPEN |VLDD3|VLDD2|VLDD1|VLDD0|EECLK|EECS |
* | out |in/ou|in/ou|in/ou|in/ou|in/ou| out | out |
* +-----+-----+-----+-----+-----+-----+-----+-----+
*/
#define PBDR_EECS (1 << 0) /* Ext clock?, NOT TESTED */
#define PBDR_EECLK (1 << 1) /* Ext clock?, NOT TESTED */
#define PBDR_VLDD0 (1 << 2) /* LCD contrast reg0 */
#define PBDR_VLDD1 (1 << 3) /* LCD contrast reg1 */
#define PBDR_VLDD2 (1 << 4) /* LCD contrast reg2 */
#define PBDR_VLDD3 (1 << 5) /* LCD contrast reg3 */
#define PBDR_OPEN (1 << 6) /* Case open/closed */
#define PBDR_VPCEN (1 << 7) /* ETNA CF power disabled */
#define PBDR_VLD_MASK 0x3c /* LCD contrast mask */
#define PBDR_VLD_SHIFT 2 /* LCD contrast shift */
/*
* Port C, Data copied from Psion 5 code
*
* +--7--+--6--+--5--+--4--+--3--+--2--+--1--+--0--+
* |ADICT|BBLD |UART1|LIGHT|UART2|PLED | DTR | RTS |
* | out | out | out | out | out | out | out | out |
* +-----+-----+-----+-----+-----+-----+-----+-----+
*/
#define PCDR_RTS (1 << 0) /* RS-232 RTS, NOT TESTED */
#define PCDR_DTR (1 << 1) /* RS-232 DTR toggle, NOT TESTED */
#define PCDR_PLED (1 << 2) /* Disable power LED, NOT TESTED */
#define PCDR_UART2 (1 << 3) /* Enable UART1 */
#define PCDR_LIGHT (1 << 4) /* LCD backlight */
#define PCDR_UART1 (1 << 5) /* Enable UART0 */
#define PCDR_ADICT (1 << 6) /* Set audio to dictaphone */
/*
* Port D, Data copied from Psion 5 code
*
* +--7--+--6--+--5--+--4--+--3--+--2--+--1--+--0--+
* | X2 |LCDLR|TRIX2|SLED |DORSW| LCD |AMPEN|CDEN |
* |in/ou| out | n/a | out | out | out | out | out |
* +-----+-----+-----+-----+-----+-----+-----+-----+
*/
#define PDDR_CDE (1 << 0) /* Codec enable, NOT TESTED */
#define PDDR_AMPEN (1 << 1) /* Audio amp enable, NOT TESTED */
#define PDDR_LCD_PWR (1 << 2) /* LCD power */
#define PDDR_ETNA_DOOR (1 << 3) /* ETNA door switch power, NOT TESTED */
#define PDDR_SLED (1 << 4) /* Front status LED on */
#define PDDR_PUMP_PWR2 (1 << 5) /* ETNA and LCD need this */
#define PDDR_PUMP_PWR1 (1 << 6) /* DC to DC converter power */
#define PDDR_ETNA_ERR (1 << 7) /* ETNA access error */
/*
* Port E, Data copied from Psion 5 code
*
* +--3--+--2--+--1--+--0--+
* |Y1EN |X1EN |Y2EN |X2EN |
* | out | out | out | out |
* +-----+-----+-----+-----+
*/
#define PEDR_X2EN (1 << 0) /* Digitiser X2 drive, NOT TESTED */
#define PEDR_Y2EN (1 << 1) /* Digitiser Y2 drive, NOT TESTED */
#define PEDR_X1EN (1 << 2) /* Digitiser X1 drive, NOT TESTED */
#define PEDR_Y1EN (1 << 3) /* Digitiser Y1 drive, NOT TESTED */
#define MEMCFG1 (0x0000) /* Memory configuration */
#define MEMCFG2 (0x0004) /* Memory configuration */
#define DRAM_CFG (0x0100) /* DRAM control register */
/*
* State and Power Controller
*/
#define PWRSR (0x0400) /* Power control state */
#define PWRCNT (0x0404) /* Clock/debug control status */
#define HALT (0x0408) /* Enter idle mode */
#define STBY (0x040c) /* Enter standby mode */
#define BLEOI (0x0410) /* Clear battery low interrupt, write only */
#define MCEOI (0x0414) /* Clear media changed interrupt, write only */
#define TEOI (0x0418) /* Clear tick interrupt, write only */
#define STFCLR (0x041c) /* Clear NBFLG, RSTFLG, PFFLG, CLDFLG, write only */
#define E2EOI (0x0420) /* Clear NEINT2, write only */
#define TC1EOI (0x0c0c) /* Clear timer 1 interrupt, write only */
#define TC2EOI (0x0c2c) /* Clear timer 2 interrupt, write only */
#define RTCEOI (0x0d10) /* Clear RTC interrupt, write only */
#define UMSEOI (0x0714) /* Clear UART 2 modem status interrupt, write only */
/*
* PWRSR Flags
*/
#define RTCDIV (1 << 0) /* 6 bits, 64Hz ticks since the increment of RTC, 32 counts ahead of RTC */
#define MCDR (1 << 6) /* Media changed direct read */
#define DCDET (1 << 7) /* Power from the mains adapter */
#define WUDR (1 << 8) /* Wake up direct read */
#define WUON (1 << 9) /* Wake up out of stanby, clear at HALT STDBY or STFCLR */
#define NBFLG (1 << 10) /* New battery flag, clear at STFCLR */
#define RSTFLG (1 << 11) /* Reset flag, clear at STFCLR */
#define PFFLG (1 << 12) /* Power fail flag, clear at STFCLR */
#define CLDFLG (1 << 13) /* Cold start flag, clear at STFCLR */
#define VERID (1 << 14) /* Windermere version id, two bits, 0 for first version */
/*
* PWRCNT Flags
*/
#define EXCKEN (1 << 0) /* External expansion clock enable, 1=on, 0=on only for bit 7 memcfg */
#define WAKEDIR (1 << 1) /* Disable waking up from STANDBY mode via the wakeup input */
#define CLKFLG (1 << 2) /* Clock speed, 1=36MHz, 0=18MHz */
#define ADCCLK (1 << 3) /* 8 bit to set the clock divider for ADCCLK output clock */
/*
* Interrupts
*/
#define INTSR (0x0500) /* Interrupt status after masking, read-only */
#define INTRSR (0x0504) /* Interrupt status before masking, read-only */
#define INTENS (0x0508) /* Interrupt enable, read-write */
#define INTENC (0x050c) /* Interrupt disable, write-only */
#define INTTEST1 (0x0514) /* Interrupt test register */
#define INTTEST2 (0x0518) /* Interrupt test register */
#define INT_EXTFIQ (1 << 0)
#define INT_BLINT (1 << 1)
#define INT_WEINT (1 << 2)
#define INT_MCINT (1 << 3)
#define INT_CSINT (1 << 4)
#define INT_EINT1 (1 << 5) /* PCMCIA/external interrupt 1 */
#define INT_EINT2 (1 << 6)
#define INT_EINT3 (1 << 7)
#define INT_TC1OI (1 << 8)
#define INT_TC2OI (1 << 9)
#define INT_RTCMI (1 << 10)
#define INT_TINT (1 << 11)
#define INT_UART1 (1 << 12)
#define INT_UART2 (1 << 13)
#define INT_LCDINT (1 << 14)
#define INT_SSEOTI (1 << 15)
/*
* Clock
*/
#define RTCTIME ((psionw_readl(RTCDRU) << 16) | (psionw_readl(RTCDRL) & 0xffff))
#define TC1LOAD (0x0c00)
#define TC1VAL (0x0c04)
#define TC1CTRL (0x0c08)
#define TC2LOAD (0x0c20)
#define TC2VAL (0x0c24)
#define TC2CTRL (0x0c28)
#define TC_BIT2 (1 << 2)
#define TC_CLKSEL (1 << 3)
#define TC_BIT4 (1 << 4)
#define TC_BIT5 (1 << 5)
#define TC_MODE (1 << 6)
#define TC_ENABLE (1 << 7)
#define BZCONT (0x0c40)
#define BZ_BZTOG (1 << 0)
#define BZ_BZMOD (1 << 1)
#define RTCDRL (0x0d00) /* RTC data register low */
#define RTCDRU (0x0d04) /* RTC data register high */
#define RTCMRL (0x0d08) /* RTC match register low */
#define RTCMRU (0x0d0c) /* RTC match register high */
/*
* SSI - Synchronous Serial Interface
*/
#define SSCR0 (0x0b00) /* Serial control register 0 */
#define SSCR1 (0x0b04) /* Serial control register 1 */
#define SSDR (0x0b0c) /* Data register */
#define SSSR (0x0b14) /* Status register */
/*
* DC to DC Converter
*/
#define PUMPCON (0x0900)
#define PUMP_RUN_VAL (0xbbb)
#define PUMP_STOP_VAL (0x0)
/*
* Codec
*/
#define CODR (0x0a00) /* Codec data register */
#define CONFG (0x0a04) /* Codec config register */
#define COLFG (0x0a08) /* Codec flag register */
#define COEOI (0x0a0c) /* Codec end of interrupt, write only */
#define COTEST (0x0a10) /* Codec test register */
#endif /* __ASM_HARDWARE_PSIONW_H */ \
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment