Commit 335611b8 authored by Russell King's avatar Russell King

Add support for Stork machine type to ARM architecture.

parent 8afb2b63
......@@ -657,6 +657,10 @@ CONFIG_SA1100_SHANNON
platform with a 640x480 LCD, touchscreen, CIR keyboard, PCMCIA slots,
and a telco interface.
CONFIG_SA1100_STORK
Say Y here if you intend to run this kernel on the Stork
handheld computer.
CONFIG_SA1100_VICTOR
Say Y here if you are using a Visu Aide Intel(R) StrongARM(R)
SA-1100 based Victor Digital Talking Book Reader. See
......
......@@ -108,6 +108,7 @@ dep_bool ' Tulsa' CONFIG_SA1100_PFS168 $CONFIG_ARCH_SA1100
dep_bool ' Victor' CONFIG_SA1100_VICTOR $CONFIG_ARCH_SA1100
dep_bool ' XP860' CONFIG_SA1100_XP860 $CONFIG_ARCH_SA1100
dep_bool ' Yopy' CONFIG_SA1100_YOPY $CONFIG_ARCH_SA1100
dep_bool ' Stork' CONFIG_SA1100_STORK $CONFIG_ARCH_SA1100
# Determine if SA1111 support is required
if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \
......
This diff is collapsed.
/*
* linux/arch/arm/mach-sa1100/stork.c
*
* Copyright (C) 2001 Ken Gordon
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <asm/hardware.h>
#include <asm/setup.h>
#include <asm/keyboard.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/serial_sa1100.h>
#include <linux/serial_core.h>
#include "generic.h"
#define STORK_VM_BASE_CS1 0xf0000000 /* where we get mapped (virtual) */
#define STORK_VM_OFF_CS1 0x08000000 /* where we started mapping (physical) */
#define STORK_VM_ADJUST_CS1 (STORK_VM_BASE_CS1-STORK_VM_OFF_CS1) /* add to the phys to get virt */
#define STORK_VM_BASE_CS2 0xf1000000 /* where we get mapped (virtual) */
#define STORK_VM_OFF_CS2 0x10000000 /* where we started mapping (physical) */
#define STORK_VM_ADJUST_CS2 (STORK_VM_BASE_CS2-STORK_VM_OFF_CS2) /* add to the phys to get virt */
static int debug = 0;
static int storkLatchA = 0;
static int storkLatchB = 0;
static int storkLCDCPLD[4] = { 0, 0, 0, 0};
int
storkSetLatchA(int bits)
{
int ret = storkLatchA;
volatile unsigned int *latch = (unsigned int *)(STORK_LATCH_A_ADDR+STORK_VM_ADJUST_CS1);
storkLatchA |= bits;
*latch = storkLatchA;
return ret;
}
int
storkClearLatchA(int bits)
{
int ret = storkLatchA;
volatile unsigned int *latch = (unsigned int *)(STORK_LATCH_A_ADDR+STORK_VM_ADJUST_CS1);
storkLatchA &= ~bits;
*latch = storkLatchA;
return ret;
}
int
storkSetLCDCPLD(int which, int bits)
{
int ret = storkLCDCPLD[which];
volatile unsigned int *latch = (unsigned int *)(STORK_LCDCPLD_BASE_ADDR+STORK_VM_ADJUST_CS2 + 0x20*which);
storkLCDCPLD[which] |= bits;
*latch = storkLCDCPLD[which];
return ret;
}
/* NB we don't shadow these 'cos there is no relation between the data written and the data read */
/* ie the read registers are read only and the write registers write only */
int
storkGetLCDCPLD(int which)
{
volatile unsigned int *latch = (unsigned int *)(STORK_LCDCPLD_BASE_ADDR+STORK_VM_ADJUST_CS2 + 0x20*which);
return *latch;
}
int
storkClearLCDCPLD(int which, int bits)
{
int ret = storkLCDCPLD[which];
volatile unsigned int *latch = (unsigned int *)(STORK_LCDCPLD_BASE_ADDR+STORK_VM_ADJUST_CS2 + 0x20*which);
storkLCDCPLD[which] &= ~bits;
*latch = storkLCDCPLD[which];
return ret;
}
int
storkSetLatchB(int bits)
{
int ret = storkLatchB;
char buf[100];
volatile unsigned int *latch = (unsigned int *)(STORK_LATCH_B_ADDR+STORK_VM_ADJUST_CS1);
sprintf(buf, "%s: bits %04x\n", __FUNCTION__, bits);
if (debug) printk(buf);
storkLatchB |= bits;
*latch = storkLatchB;
return ret;
}
int
storkClearLatchB(int bits)
{
int ret = storkLatchB;
char buf[100];
volatile unsigned int *latch = (unsigned int *)(STORK_LATCH_B_ADDR+STORK_VM_ADJUST_CS1);
sprintf(buf, "%s: bits %04x\n", __FUNCTION__, bits);
if (debug) printk(buf);
storkLatchB &= ~bits;
*latch = storkLatchB;
return ret;
}
void
storkSetGPIO(int bits)
{
char buf[100];
sprintf(buf, "%s: bits %04x\n", __FUNCTION__, bits);
if (debug) printk(buf);
GPSR = bits;
}
void
storkClearGPIO(int bits)
{
char buf[100];
sprintf(buf, "%s: bits %04x\n", __FUNCTION__, bits);
if (debug) printk(buf);
GPCR = bits;
}
int
storkGetGPIO()
{
char buf[100];
int bits = GPLR;
sprintf(buf, "%s: bits %04x\n", __FUNCTION__, bits);
if (debug) printk(buf);
return bits;
}
/* this will return the current state of the hardware ANDED with the given bits
so NE => at least one bit was set, but maybe not all of them! */
int
storkTestGPIO(int bits)
{
int val = storkGetGPIO();
char buf[100];
sprintf(buf, "%s: bits %04x val %04x\n", __FUNCTION__, bits, val);
if (debug) printk(buf);
return (val & bits);
}
/* NB the touch screen and the d to a use the same data and clock out pins */
static void storkClockTS(void)
{
storkSetLatchB(STORK_TOUCH_SCREEN_DCLK);
udelay(10); /* hmm wait 200ns (min) - ok this ought to be udelay(1) but that doesn't get */
/* consistant values so I'm using 10 (urgh) */
storkClearLatchB(STORK_TOUCH_SCREEN_DCLK);
udelay(10);
}
int /* there is always a 12 bit read after the write! */
storkClockByteToTS(int byte)
{
int timeout = 10000; /* stuff is meant to happen in 60ns */
int bit;
int result = 0;
if (debug) printk("storkClockByteToTS: %02x\n", byte);
storkClearLatchB(STORK_TOUCH_SCREEN_CS); /* slect touch screen */
while (timeout-- > 0)
if (storkTestGPIO(GPIO_STORK_TOUCH_SCREEN_BUSY) == 0)
break;
if (timeout < 0) {
printk("storkClockBitToTS: GPIO_STORK_TOUCH_SCREEN_BUSY didn't go low!\n\r");
/* ignore error for now return; */
}
/* clock out the given byte */
for (bit = 0x80; bit > 0; bit = bit >> 1) {
if ((bit & byte) == 0)
storkClearLatchB(STORK_TOUCH_SCREEN_DIN);
else
storkSetLatchB(STORK_TOUCH_SCREEN_DIN);
storkClockTS();
}
storkClockTS(); /* will be busy for at a clock (at least) */
for (timeout = 10000; timeout >= 0; timeout--)
if (storkTestGPIO(GPIO_STORK_TOUCH_SCREEN_BUSY) == 0)
break;
if (timeout < 0) {
printk("storkClockBitToTS: 2nd GPIO_STORK_TOUCH_SCREEN_BUSY didn't go low!\n\r");
/* ignore error for now return; */
}
/* clock in the result */
for (bit = 0x0800; bit > 0; bit = bit >> 1) {
if (storkTestGPIO(GPIO_STORK_TOUCH_SCREEN_DATA))
result |= bit;
storkClockTS();
}
storkSetLatchB(STORK_TOUCH_SCREEN_CS); /* unselect touch screen */
return result;
}
void
storkClockShortToDtoA(int word)
{
int bit;
storkClearLatchB(STORK_DA_CS); /* select D to A */
/* clock out the given byte */
for (bit = 0x8000; bit > 0; bit = bit >> 1) {
if ((bit & word) == 0)
storkClearLatchB(STORK_TOUCH_SCREEN_DIN);
else
storkSetLatchB(STORK_TOUCH_SCREEN_DIN);
storkClockTS();
}
storkSetLatchB(STORK_DA_CS); /* unselect D to A */
/* set DTOA#_LOAD low then high (min 20ns) to transfer value to D to A */
storkClearLatchB(STORK_DA_LD);
storkSetLatchB(STORK_DA_LD);
}
void
storkInitTSandDtoA(void)
{
storkClearLatchB(STORK_TOUCH_SCREEN_DCLK | STORK_TOUCH_SCREEN_DIN);
storkSetLatchB(STORK_TOUCH_SCREEN_CS | STORK_DA_CS | STORK_DA_LD);
storkClockByteToTS(0xE2); /* turn on the reference */
storkClockShortToDtoA(0x8D00); /* turn on the contrast */
storkClockShortToDtoA(0x0A00); /* turn on the brightness */
}
/* see asm-arm/keyboard.h - there are a bunch of basically virtual functions required */
/* we have to fill in for them or else we can't call handle_scancode when we see a button pressed */
static int
stork_kbd_translate(unsigned char scancode, unsigned char *keycode, char rawmode)
{
if (keycode)
*keycode = scancode;
return 1;
}
static char
stork_kbd_unexpected_up(unsigned char code)
{
return 0;
}
struct map_desc stork_io_desc[] __initdata = {
/* virtual physical length domain r w c b */
{ 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
{ STORK_VM_BASE_CS1, STORK_VM_OFF_CS1, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* EGPIO 0 */
{ 0xf1000000, 0x10000000, 0x02800000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 2 */
{ 0xf3800000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 4 */
LAST_DESC
};
int __init
stork_map_io(void)
{
sa1100_map_io();
iotable_init(stork_io_desc);
sa1100_register_uart(0, 1); /* com port */
sa1100_register_uart(1, 2);
sa1100_register_uart(2, 3);
printk("Stork driver initing latches\r\n");
storkClearLatchB(STORK_RED_LED); /* let's have the red LED on please */
storkSetLatchB(STORK_YELLOW_LED);
storkSetLatchB(STORK_GREEN_LED);
storkSetLatchA(STORK_BATTERY_CHARGER_ON);
storkSetLatchA(STORK_LCD_5V_POWER_ON);
storkSetLatchA(STORK_LCD_3V3_POWER_ON);
storkInitTSandDtoA();
k_translate = stork_kbd_translate;
k_unexpected_up = stork_kbd_unexpected_up;
return 0;
}
MACHINE_START(STORK, "Stork Technologies prototype")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
BOOT_PARAMS(0xc0000100)
MAPIO(stork_map_io)
INITIRQ(sa1100_init_irq)
MACHINE_END
EXPORT_SYMBOL(storkTestGPIO);
EXPORT_SYMBOL(storkSetGPIO);
EXPORT_SYMBOL(storkClearGPIO);
EXPORT_SYMBOL(storkSetLatchA);
EXPORT_SYMBOL(storkClearLatchA);
EXPORT_SYMBOL(storkSetLatchB);
EXPORT_SYMBOL(storkClearLatchB);
EXPORT_SYMBOL(storkClockByteToTS);
EXPORT_SYMBOL(storkClockShortToDtoA);
EXPORT_SYMBOL(storkGetLCDCPLD);
EXPORT_SYMBOL(storkSetLCDCPLD);
......@@ -165,6 +165,8 @@ typedef struct { volatile u32 offset[4096]; } __regbase;
#include "adsbitsy.h"
#endif
#include "stork.h"
#include "system3.h"
#ifdef CONFIG_SA1101
......
/*
stork.h
*/
#ifndef STORK_SA1100_H
#define STORK_SA1100_H
/* ugly - this will make sure we build sa1100fb for the Nec display not the Kyocera */
#define STORK_TFT 1
#define GPIO_STORK_SWITCH_1 (1 << 0) /* Switch 1 - input */
#define GPIO_STORK_SWITCH_2 (1 << 1) /* Switch 2 - input */
#define GPIO_STORK_TOUCH_SCREEN_BUSY (1 << 10) /* TOUCH_SCREEN_BUSY - input */
#define GPIO_STORK_TOUCH_SCREEN_DATA (1 << 11) /* TOUCH_SCREEN_DATA - input */
#define GPIO_STORK_CODEC_AGCSTAT (1 << 12) /* CODEC_AGCSTAT -input */
#define GPIO_STORK_RS232_ON (1 << 13) /* enable RS232 (UART1) */
#define GPIO_STORK_TEST_POINT (1 << 14) /* to test point */
#define GPIO_STORK_L3_I2C_SDA (1 << 15) /* L3_I2C_SDA - bidirectional */
#define GPIO_STORK_PSU_SYNC_MODE (1 << 16) /* PSU_SYNC_MODE - output */
#define GPIO_STORK_L3_MODE (1 << 17) /* L3 mode - output (??) */
#define GPIO_STORK_L3_I2C_SCL (1 << 18) /* L3_I2C_SCL - bidirectional */
#define GPIO_STORK_AUDIO_CLK (1 << 19) /* SSP external clock (Audio clock) - input */
#define GPIO_STORK_PCMCIA_A_CARD_DETECT (1 << 20) /* PCMCIA_A_CARD_DETECT - input */
#define GPIO_STORK_PCMCIA_B_CARD_DETECT (1 << 21) /* PCMCIA_B_CARD_DETECT - input */
#define GPIO_STORK_PCMCIA_A_RDY (1 << 22) /* PCMCIA_A_RDY - input */
#define GPIO_STORK_PCMCIA_B_RDY (1 << 23) /* PCMCIA_B_RDY - input */
#define GPIO_STORK_SWITCH_EXTRA_IRQ (1 << 24) /* Extra IRQ from switch detect logic - input */
#define GPIO_STORK_SWITCH_IRQ (1 << 25) /* Sitch irq - input */
#define GPIO_STORK_BATTERY_LOW_IRQ (1 << 26) /* BATTERY_LOW_IRQ - input */
#define GPIO_STORK_TOUCH_SCREEN_PEN_IRQ (1 << 27) /* TOUCH_SCREEN_PEN_IRQ -input */
#define IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT IRQ_GPIO20 /* PCMCIA_A_CARD_DETECT - input */
#define IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT IRQ_GPIO21 /* PCMCIA_B_CARD_DETECT - input */
#define IRQ_GPIO_STORK_SWITCH_1 IRQ_GPIO0 /* Switch 1 - input - active low */
#define IRQ_GPIO_STORK_SWITCH_2 IRQ_GPIO1 /* Switch 2 - input - active low */
#define IRQ_GPIO_STORK_SWITCH_EXTRA_IRQ IRQ_GPIO24 /* Extra IRQ from switch detect logic - input - active low */
#define IRQ_GPIO_STORK_SWITCH_IRQ IRQ_GPIO25 /* Switch irq - input- active low */
#define IRQ_GPIO_STORK_BATTERY_LOW_IRQ IRQ_GPIO26 /* BATTERY_LOW_IRQ - input - active low */
#define IRQ_GPIO_STORK_TOUCH_SCREEN_PEN_IRQ IRQ_GPIO27 /* TOUCH_SCREEN_PEN_IRQ -input - goes low when it happens */
/* this may be bogus - no it's not the RDY line becomes the IRQ line when we're up as an IO device */
#define IRQ_GPIO_STORK_PCMCIA_A_RDY IRQ_GPIO22 /* PCMCIA_A_RDY - input */
#define IRQ_GPIO_STORK_PCMCIA_B_RDY IRQ_GPIO23 /* PCMCIA_B_RDY - input */
/* the default outputs, others are optional - I'll set these in the bootldr for now */
#define GPIO_STORK_OUTPUT_BITS (GPIO_STORK_RS232_ON | GPIO_STORK_PSU_SYNC_MODE | GPIO_STORK_L3_MODE)
#define STORK_LATCH_A_ADDR 0x08000000 /* cs1 A5 = 0 */
#define STORK_LATCH_B_ADDR 0x08000020 /* cs1 A5 = 1 */
#define STORK_LCDCPLD_BASE_ADDR 0x10000000 /* cs2 A5 = 0 */
/* bit defs for latch A - these are write only and will need to be mirrored! */
#define STORK_TEMP_IC_POWER_ON (1 << 0)
#define STORK_SED1386_POWER_ON (1 << 1)
#define STORK_LCD_3V3_POWER_ON (1 << 2)
#define STORK_LCD_5V_POWER_ON (1 << 3)
#define STORK_LCD_BACKLIGHT_INVERTER_ON (1 << 4)
#define STORK_PCMCIA_PULL_UPS_POWER_ON (1 << 5)
#define STORK_PCMCIA_A_POWER_ON (1 << 6)
#define STORK_PCMCIA_B_POWER_ON (1 << 7)
#define STORK_AUDIO_POWER_ON (1 << 8)
#define STORK_AUDIO_AMP_ON (1 << 9)
#define STORK_BAR_CODE_POWER_ON (1 << 10)
#define STORK_BATTERY_CHARGER_ON (1 << 11)
#define STORK_SED1386_RESET (1 << 12)
#define STORK_IRDA_FREQUENCY_SELECT (1 << 13)
#define STORK_IRDA_MODE_0 (1 << 14)
#define STORK_IRDA_MODE_1 (1 << 15)
/* and for B */
#define STORK_AUX_AD_SEL_0 (1 << 0)
#define STORK_AUX_AD_SEL_1 (1 << 1)
#define STORK_TOUCH_SCREEN_DCLK (1 << 2)
#define STORK_TOUCH_SCREEN_DIN (1 << 3)
#define STORK_TOUCH_SCREEN_CS (1 << 4)
#define STORK_DA_CS (1 << 5)
#define STORK_DA_LD (1 << 6)
#define STORK_RED_LED (1 << 7) /* active LOW */
#define STORK_GREEN_LED (1 << 8) /* active LOW */
#define STORK_YELLOW_LED (1 << 9) /* active LOW */
#define STORK_PCMCIA_B_RESET (1 << 10)
#define STORK_PCMCIA_A_RESET (1 << 11)
#define STORK_AUDIO_CODEC_RESET (1 << 12)
#define STORK_CODEC_QMUTE (1 << 13)
#define STORK_AUDIO_CLOCK_SEL0 (1 << 14)
#define STORK_AUDIO_CLOCK_SEL1 (1 << 15)
/*
There are 8 control bits in the touch screen controller (AD7873)
S A2 A1 A0 MODE SER/DFR# PD1 PD0
S Start bit, always one.
A2 - A0 Channel select bits
MODE 0 => 12 bit resolution, 1 => 8 bit
SER/DFR# Single ender/Differential Reference Select bit
PD1, PD0 Power management bits (usually 10)
From Table 1.
A2-A0
0 Temp0 (SER must be 1)
1 X+ (is this a typo? - is this X- really?)
2 VBAT,
3 read X+ (Z1),
4 read Y- (Z2), 5 => read Y+,
*/
#define AD7873_START 0x80 /* all commands need this to be set */
#define AD7873_ADDR_BITS 4 /* ie shift by this */
#define AD7873_8BITMODE 0x08 /* 0 => 12 bit convertions */
#define AD7873_SER_DFR 0x04
#define AD7873_PD1 0x02
#define AD7873_PD0 0x01
#define AD7873_TEMP0 AD7873_SER_DFR
#define AD7873_X (1 << AD7873_ADDR_BITS)
#define AD7873_VBAT ((2 << AD7873_ADDR_BITS) | AD7873_SER_DFR)
#define AD7873_X_Z1 (3 << AD7873_ADDR_BITS)
#define AD7873_Y_Z2 (4 << AD7873_ADDR_BITS)
#define AD7873_Y (5 << AD7873_ADDR_BITS)
#define AD7873_AUX ((6 << AD7873_ADDR_BITS) | AD7873_SER_DFR)
#define AD7873_TEMP1 ((7 << AD7873_ADDR_BITS) | AD7873_SER_DFR)
#ifndef __ASSEMBLY__
extern int storkSetLatchA(int bits);
extern int storkClearLatchA(int bits);
extern int storkSetLatchB(int bits);
extern int storkClearLatchB(int bits);
extern int storkSetLCDCPLD(int which, int bits);
extern int storkClearLCDCPLD(int which, int bits);
extern void storkSetGPIO(int bits);
extern void storkClearGPIO(int bits);
extern int storkGetGPIO(void);
extern void storkClockShortToDtoA(int word);
extern int storkClockByteToTS(int byte);
/* this will return the current state of the hardware ANDED with the given bits
so NE => at least one bit was set, but maybe not all of them! */
extern int storkTestGPIO(int bits);
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment