TWINTAIL (official product name is G4255EB) is an evaluation board

with Intel PXA255 processor from Genetec corp.  You can get some
information on the board from http://ad.genetec.co.jp/ but only in Japanese.
This commit is contained in:
bsh 2005-02-26 10:49:53 +00:00
parent 94b724fc67
commit 629db0b989
18 changed files with 4571 additions and 0 deletions

View File

@ -0,0 +1,388 @@
# $NetBSD: TWINTAIL,v 1.1 2005/02/26 10:49:53 bsh Exp $
#
# TWINTAIL -- Genetec corp. G4255EB-X002 Evaluation Board Kernel
#
include "arch/evbarm/conf/std.g42xxeb"
# estimated number of users
maxusers 32
options VERBOSE_ARM32
#options INTR_DEBUG
#options BOOTHOWTO=RB_SINGLE
options PCMCIADEBUG
options PCMCIACISDEBUG
# Standard system options
options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT
#options NTP # NTP phase/frequency locked loop
# CPU options
options CPU_XSCALE_PXA2X0 # Support the XScale core
#options XSCALE_CACHE_WRITE_THROUGH
options XSCALE_CACHE_READ_WRITE_ALLOCATE
makeoptions COPTS="-O2 -mcpu=xscale"
# Architecture options
# File systems
file-system FFS # UFS
#file-system LFS # log-structured file system
file-system MFS # memory file system
file-system NFS # Network file system
#file-system ADOSFS # AmigaDOS-compatible file system
#file-system EXT2FS # second extended file system (linux)
file-system CD9660 # ISO 9660 + Rock Ridge file system
file-system MSDOSFS # MS-DOS file system
file-system FDESC # /dev/fd
file-system KERNFS # /kern
file-system NULLFS # loopback file system
file-system PORTAL # portal filesystem (still experimental)
file-system PROCFS # /proc
#file-system UMAPFS # NULLFS + uid and gid remapping
file-system UNION # union file system
# File system options
#options QUOTA # UFS quotas
#options FFS_EI # FFS Endian Independant support
#options NFSSERVER
options SOFTDEP
#options FFS_NO_SNAPSHOT # ffs snapshots
# Networking options
#options GATEWAY # packet forwarding
options INET # IP + ICMP + TCP + UDP
options INET6 # IPV6
#options IPSEC # IP security
#options IPSEC_ESP # IP security (encryption part; define w/ IPSEC)
#options IPSEC_DEBUG # debug for IP security
#options MROUTING # IP multicast routing
#options NS # XNS
#options NSIP # XNS tunneling over IP
#options ISO,TPIP # OSI
#options EON # OSI tunneling over IP
#options CCITT,LLC,HDLC # X.25
#options NETATALK # AppleTalk networking
#options PFIL_HOOKS # pfil(9) packet filter hooks
#options PPP_BSDCOMP # BSD-Compress compression support for PPP
#options PPP_DEFLATE # Deflate compression support for PPP
#options PPP_FILTER # Active filter support for PPP (requires bpf)
#options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG
options NFS_BOOT_BOOTP
options NFS_BOOT_DHCP
#options NFS_BOOT_BOOTPARAM
# Compatibility options
#options COMPAT_43 # 4.3BSD compatibility.
options COMPAT_20 # NetBSD 2.0 compatibility.
options COMPAT_16 # NetBSD 1.6 compatibility.
#options COMPAT_15 # NetBSD 1.5 compatibility.
#options COMPAT_14 # NetBSD 1.4 compatibility.
#options COMPAT_13 # NetBSD 1.3 compatibility.
#options COMPAT_12 # NetBSD 1.2 compatibility.
#options COMPAT_11 # NetBSD 1.1 compatibility.
#options COMPAT_10 # NetBSD 1.0 compatibility.
#options COMPAT_09 # NetBSD 0.9 compatibility.
#options TCP_COMPAT_42 # 4.2BSD TCP/IP bug compat. Not recommended.
# Shared memory options
#options SYSVMSG # System V-like message queues
#options SYSVSEM # System V-like semaphores
#options SEMMNI=10 # number of semaphore identifiers
#options SEMMNS=60 # number of semaphores in system
#options SEMUME=10 # max number of undo entries per process
#options SEMMNU=30 # number of undo structures in system
#options SYSVSHM # System V-like memory sharing
#options SHMMAXPGS=1024 # 1024 pages is the default
# Device options
#options MEMORY_DISK_HOOKS # boottime setup of ramdisk
#options MEMORY_DISK_SIZE=3072 # Size in blocks
#options MEMORY_DISK_DYNAMIC
#options MINIROOTSIZE=1000 # Size in blocks
#options MEMORY_DISK_IS_ROOT # use memory disk as root
# Miscellaneous kernel options
options KTRACE # system call tracing, a la ktrace(1)
#options LKM # loadable kernel modules
#options KMEMSTATS # kernel memory statistics
options PCMCIAVERBOSE # verbose PCMCIA configuration messages
options USBVERBOSE # verbose USB device autoconfig messages
options SCSIVERBOSE # Verbose SCSI errors
#options MIIVERBOSE # Verbose MII autoconfuration messages
#options DDB_KEYCODE=0x40
#options USERCONF # userconf(4) support
# Development and Debugging options
options DIAGNOSTIC # internally consistency checks
#options DEBUG
#options PMAP_DEBUG # Enable pmap_debug_level code
#options VERBOSE_INIT_ARM # verbose bootstraping messages
#options DDB # in-kernel debugger
#options DDB_HISTORY_SIZE=100 # Enable history editing in DDB
#options KGDB
#options IPKDB
#options IPKDB_NE
#options IPKDBKEY="\"Debug_it_over_network\""
#options DEBUG_KGDB
makeoptions DEBUG="-g" # compile full symbol table
options SYMTAB_SPACE=200000
#options AUDIO_DEBUG=2
config netbsd root on ? type ?
config netbsd-ne0 root on ne0 type nfs
# The main bus device
mainbus0 at root
# The boot cpu
cpu0 at mainbus?
# integrated peripherals
pxaip0 at mainbus?
pxaintc0 at pxaip? # interrupt controller
pxagpio0 at pxaip? # GPIO
# cotulla integrated 16550 UARTs
options COM_PXA2X0
com0 at pxaip? addr 0x40100000 intr 22 # Full Function UART
com1 at pxaip? addr 0x40200000 intr 21 # BlueTootth UART
#com2 at pxaip? addr 0x40700000 intr 20 # Standard UART (for IrDA)
options FFUARTCONSOLE
options BTUARTCONSOLE
options KGDB_DEVNAME="\"ffuart\"" # ffuart or btuart
options KGDB_DEVRATE=115200
#aupxa0 at pxaip? # AC97 interface
# Audio support
#audio* at audiobus?
# FlashROM disk driver
# frd* at pxaip?
# On-board device support
obio0 at pxaip? intr 8
ne0 at obio? addr 0x0e000200 intr 5 # on-board Asix AX88796
# LCD
#device-major lcd char 37
lcd0 at obio?
wsdisplay* at lcd? console ?
options FONT_SONY8x16
#options FONT_VT220L8x8
options WSEMUL_VT100 # VT100 / VT220 emulation
options G4250_LCD_TOSHIBA_LTM035
#options G4250_LCD_NEC_NL3224BC35
kmkbd* at obio?
wskbd* at kmkbd? # console ?
# GB-225 option board
opio0 at obio? intr 2
# USB host
# slhci0 at opio0
# options SLHCI_DEBUG
# USB bus support
#usb* at slhci?
# USB Hubs
# uhub* at usb?
# uhub* at uhub? port ? configuration ? interface ?
# USB HID device
# uhidev* at uhub? port ? configuration ? interface ?
# USB Mice
# ums* at uhidev? reportid ?
# wsmouse* at ums? mux 0
# USB Keyboards
#ukbd* at uhidev? reportid ?
#wskbd* at ukbd? console ? mux 1
# USB Generic HID devices
# uhid* at uhidev? reportid ?
# USB Printer
#ulpt* at uhub? port ? configuration ? interface ?
# USB Modem
#umodem* at uhub? port ? configuration ?
#ucom* at umodem?
# USB Mass Storage
#umass* at uhub? port ? configuration ? interface ?
#wd* at umass?
# USB audio
#uaudio* at uhub? port ? configuration ?
# USB MIDI
#umidi* at uhub? port ? configuration ?
# USB IrDA
# USB-IrDA bridge spec
#uirda* at uhub? port ? configuration ? interface ?
#irframe* at uirda?
# SigmaTel STIr4200 USB/IrDA Bridge
#ustir* at uhub? port ?
#irframe* at ustir?
# USB Ethernet adapters
#aue* at uhub? port ? # ADMtek AN986 Pegasus based adapters
#cue* at uhub? port ? # CATC USB-EL1201A based adapters
#kue* at uhub? port ? # Kawasaki LSI KL5KUSB101B based adapters
#uax* at uhub? port ? # ASIX AX88172 based adapters
#url* at uhub? port ? # Realtek RTL8150L based adapters
# Prolific PL2301/PL2302 host-to-host adapter
#upl* at uhub? port ?
# Serial adapters
#ubsa* at uhub? port ? # Belkin serial adapter
#ucom* at ubsa? portno ?
#uftdi* at uhub? port ? # FTDI FT8U100AX serial adapter
#ucom* at uftdi? portno ?
#umct* at uhub? port ? # MCT USB-RS232 serial adapter
#ucom* at umct? portno ?
#uplcom* at uhub? port ? # I/O DATA USB-RSAQ2 serial adapter
#ucom* at uplcom? portno ?
#uvscom* at uhub? port ? # SUNTAC Slipper U VS-10U serial adapter
#ucom* at uvscom? portno ?
# Diamond Multimedia Rio 500
#urio* at uhub? port ?
# USB Handspring Visor
#uvisor* at uhub? port ?
#ucom* at uvisor?
# USB scanners
#uscanner* at uhub? port ?
# USB scanners that use SCSI emulation, e.g., HP5300
#usscanner* at uhub? port ?
# Y@P firmware loader
#uyap* at uhub? port ?
# D-Link DSB-R100 USB radio
#udsbr* at uhub? port ?
#radio* at udsbr?
# USB Generic driver
# ugen* at uhub? port ?
# PCMCIA/CF card
opcic0 at opio?
pcmcia* at opcic?
# PCMCIA serial interfaces
com* at pcmcia? function ? # Modems and serial cards
pcmcom* at pcmcia? function ? # PCMCIA multi-port serial cards
com* at pcmcom? slave ? # ...and the slave devices
# PCMCIA SCSI controllers
aic* at pcmcia? function ? # Adaptec APA-1460 SCSI
esp* at pcmcia? function ? # Qlogic ESP406/FAS408 SCSI
# SCSI bus support
scsibus* at scsi?
# SCSI devices
sd* at scsibus? target ? lun ? # SCSI disk drives
st* at scsibus? target ? lun ? # SCSI tape drives
cd* at scsibus? target ? lun ? # SCSI CD-ROM drives
ch* at scsibus? target ? lun ? # SCSI autochangers
ses* at scsibus? target ? lun ? # SCSI Enclosure Services devices
ss* at scsibus? target ? lun ? # SCSI scanners
uk* at scsibus? target ? lun ? # SCSI unknown
# PCMCIA IDE controllers
wdc* at pcmcia? function ?
atabus* at wdc? channel ?
wd* at atabus? drive ? flags 0x0000
# PCMCIA audio devices
#esl* at pcmcia? function ? # ESS 1688 AudioDrive
# PCMCIA network interfaces
an* at pcmcia? function ? # Aironet PC4500/PC4800 (802.11)
awi* at pcmcia? function ? # BayStack 650/660 (802.11FH/DS)
cnw* at pcmcia? function ? # Xircom/Netwave AirSurfer
ep* at pcmcia? function ? # 3Com 3c589 and 3c562 Ethernet
mbe* at pcmcia? function ? # MB8696x based Ethernet
ne* at pcmcia? function ? # NE2000-compatible Ethernet
ray* at pcmcia? function ? # Raytheon Raylink (802.11)
sm* at pcmcia? function ? # Megahertz Ethernet
# tr at pcmcia has problems with Cardbus bridges
tr* at pcmcia? function ? # TROPIC based Token-Ring
wi* at pcmcia? function ? # Lucent/Intersil WaveLan IEEE (802.11)
xirc* at pcmcia? function ? # Xircom CreditCard Ethernet
com* at xirc?
xi* at xirc?
mhzc* at pcmcia? function ? # Megahertz Ethernet/Modem combo cards
com* at mhzc?
sm* at mhzc?
# Pseudo-Devices
# disk/mass storage pseudo-devices
#pseudo-device md 1 # memory disk device (ramdisk)
#pseudo-device vnd 4 # disk-like interface to files
#pseudo-device fss 4 # file system snapshot device
# network pseudo-devices
pseudo-device bpfilter 4 # Berkeley packet filter
pseudo-device ipfilter # IP filter (firewall) and NAT
pseudo-device loop # network loopback
#pseudo-device kttcp # network loopback
#pseudo-device ppp 2 # Point-to-Point Protocol
#pseudo-device pppoe # PPP over Ethernet (RFC 2516)
#pseudo-device sl 2 # Serial Line IP
#pseudo-device strip 2 # Starmode Radio IP (Metricom)
#pseudo-device irframetty # IrDA frame line discipline
#pseudo-device tap # virtual Ethernet
#pseudo-device tun 2 # network tunneling over tty
#pseudo-device gre 2 # generic L3 over IP tunnel
#pseudo-device gif 4 # IPv[46] over IPv[46] tunnel (RFC1933)
#pseudo-device faith 1 # IPv[46] tcp relay translation i/f
#pseudo-device stf 1 # 6to4 IPv6 over IPv4 encapsulation
#pseudo-device vlan # IEEE 802.1q encapsulation
#pseudo-device bridge # simple inter-network bridging
#options BRIDGE_IPF # bridge uses IP/IPv6 pfil hooks too
#pseudo-device pf # PF packet filter
#pseudo-device pflog # PF log if
# miscellaneous pseudo-devices
pseudo-device pty # pseudo-terminals
pseudo-device rnd # /dev/random and in-kernel generator
pseudo-device clockctl # user control of clock subsystem
# wscons pseudo-devices
#pseudo-device wsmux # mouse & keyboard multiplexor
#pseudo-device wsfont
pseudo-device ksyms # /dev/ksyms

View File

@ -0,0 +1,10 @@
# $NetBSD: TWINTAIL_INSTALL,v 1.1 2005/02/26 10:49:53 bsh Exp $
#
# TWINTAIL_INSTALL -- TWINTAIL kernel with installation-sized
# ramdisk
#
include "arch/evbarm/conf/TWINTAIL"
include "arch/evbarm/conf/INSTALL"
options BOOTHOWTO=RB_SINGLE

View File

@ -0,0 +1,44 @@
# $NetBSD: files.g42xxeb,v 1.1 2005/02/26 10:49:53 bsh Exp $
#
# Genetec corp. G4255EB evaluation board configuration info
#
file arch/evbarm/g42xxeb/g42xxeb_machdep.c
# CPU support and integrated peripherals
include "arch/arm/xscale/files.pxa2x0"
# G4250EBX on-board devices (including CPLD)
device obio {[addr=-1], [intr=-1]}
attach obio at pxaip
file arch/evbarm/g42xxeb/obio.c obio
# LCD frame buffer
attach lcd at obio with lcd_obio
file arch/evbarm/g42xxeb/g42xxeb_lcd.c lcd_obio
defflag "opt_g42xxlcd.h" G4250_LCD_TOSHIBA_LTM035 G4250_LCD_NEC_NL3224BC35
device kmkbd: wskbddev
attach kmkbd at obio
file arch/evbarm/g42xxeb/g42xxeb_kmkbd.c kmkbd needs-flag
attach ne at obio with ne_obio
file arch/evbarm/g42xxeb/if_ne_obio.c ne_obio
# Peripherals on GB-225 option board
device opio {[addr=-1], [intr=-1]}
attach opio at obio
file arch/evbarm/g42xxeb/gb225.c opio
# PCMCIA
include "dev/pcmcia/files.pcmcia"
device opcic: pcmciabus
attach opcic at opio
file arch/arm/sa11x0/sa11xx_pcic.c opcic
file arch/evbarm/g42xxeb/gb225_pcic.c opcic
# Cypress SL811HS USB host controller
attach slhci at opio with slhci_opio
file arch/evbarm/g42xxeb/gb225_slhci.c slhci_opio

View File

@ -0,0 +1,16 @@
# $NetBSD: mk.g42xxeb,v 1.1 2005/02/26 10:49:53 bsh Exp $
SYSTEM_FIRST_OBJ= g42xxeb_start.o
SYSTEM_FIRST_SFILE= ${THISARM}/g42xxeb/g42xxeb_start.S
KERNEL_BASE_PHYS=0xa0200000
KERNEL_BASE_VIRT=0xc0200000
SYSTEM_LD_TAIL_EXTRA+=; \
echo ${OBJCOPY} -S -O binary $@ $@.bin; \
${OBJCOPY} -S -O binary $@ $@.bin; \
echo gzip \< $@.bin \> $@.bin.gz; \
gzip < $@.bin > $@.bin.gz
EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin@}
EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin.gz@}

View File

@ -0,0 +1,26 @@
# $NetBSD: std.g42xxeb,v 1.1 2005/02/26 10:49:53 bsh Exp $
#
# standard NetBSD/evbarm for TWINTAIL (G4255EB) options
machine evbarm arm
# Pull in LUBBOCK config definitions.
include "arch/evbarm/conf/files.g42xxeb"
options G42XXEB
options EXEC_ELF32
options EXEC_SCRIPT
# To support easy transit to ../arch/arm/arm32
options ARM32
makeoptions LOADADDRESS="0xc0200000"
makeoptions BOARDTYPE="g42xxeb"
makeoptions BOARDMKFRAG="${THISARM}/conf/mk.g42xxeb"
options ARM_INTR_IMPL="<arch/arm/xscale/pxa2x0_intr.h>"
# OS Timer
saost* at pxaip? addr 0x40a00000 size 0x20

View File

@ -0,0 +1,542 @@
/* $NetBSD: g42xxeb_kmkbd.c,v 1.1 2005/02/26 10:49:53 bsh Exp $ */
/*-
* Copyright (c) 2002, 2003, 2005 Genetec corp.
* All rights reserved.
*
* 4x5 matrix key switch driver for TWINTAIL.
* Written by Hiroyuki Bessho for Genetec corp.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Use on-board matrix switches as wskbd.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: g42xxeb_kmkbd.c,v 1.1 2005/02/26 10:49:53 bsh Exp $" );
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/ioctl.h>
#include <sys/callout.h>
#include <sys/kernel.h> /* for hz */
#include <machine/bus.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wskbdvar.h>
#include <dev/wscons/wsksymdef.h>
#include <dev/wscons/wsksymvar.h>
#include <arch/evbarm/g42xxeb/g42xxeb_var.h>
#include "locators.h"
/*#include "opt_pckbd_layout.h"*/
/*#include "opt_wsdisplay_compat.h"*/
#define DEBOUNCE_TICKS ((hz<=50)?1:hz/50) /* 20ms */
#define RELEASE_WATCH_TICKS (hz/10) /* 100ms */
struct kmkbd_softc {
struct device dev;
struct device *wskbddev;
void *ih; /* interrupt handler */
struct callout callout;
uint32_t notified_bits; /* reported state of keys */
uint32_t last_bits; /* used for debounce */
u_char debounce_counter;
#define DEBOUNCE_COUNT 3
u_char polling;
enum kmkbd_state {
ST_INIT,
ST_DISABLED,
ST_ALL_UP, /* waiting for interrupt */
ST_DEBOUNCE, /* doing debounce */
ST_KEY_PRESSED /* some keys are pressed */
} state;
};
int kmkbd_match(struct device *, struct cfdata *, void *);
void kmkbd_attach(struct device *, struct device *, void *);
CFATTACH_DECL(kmkbd, sizeof(struct kmkbd_softc),
kmkbd_match, kmkbd_attach, NULL, NULL);
static int kmkbd_enable(void *, int);
static void kmkbd_set_leds(void *, int);
static int kmkbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
const struct wskbd_accessops kmkbd_accessops = {
kmkbd_enable,
kmkbd_set_leds,
kmkbd_ioctl,
};
#if 0
void kmkbd_cngetc(void *, u_int *, int *);
void kmkbd_cnpollc(void *, int);
void kmkbd_cnbell(void *, u_int, u_int, u_int);
const struct wskbd_consops kmkbd_consops = {
kmkbd_cngetc,
kmkbd_cnpollc,
kmkbd_cnbell,
};
#endif
static const keysym_t kmkbd_keydesc_0[] = {
/* pos normal shifted */
KS_KEYCODE(0), KS_a, KS_A,
KS_KEYCODE(1), KS_b, KS_B,
KS_KEYCODE(2), KS_c, KS_C,
KS_KEYCODE(3), KS_d, KS_D,
KS_KEYCODE(4), KS_e, KS_E,
KS_KEYCODE(5), KS_f, KS_F,
KS_KEYCODE(6), KS_g, KS_G,
KS_KEYCODE(7), KS_h, KS_H,
KS_KEYCODE(8), KS_i, KS_I,
KS_KEYCODE(9), KS_j, KS_J,
KS_KEYCODE(10), KS_k, KS_K,
KS_KEYCODE(11), KS_l, KS_L,
KS_KEYCODE(12), KS_m, KS_M,
KS_KEYCODE(13), KS_n, KS_N,
KS_KEYCODE(14), KS_o, KS_O,
KS_KEYCODE(15), KS_p, KS_P,
KS_KEYCODE(16), KS_q, KS_Q,
KS_KEYCODE(17), KS_r, KS_R,
KS_KEYCODE(18), '\003', '\003',
KS_KEYCODE(19), KS_Return, KS_Linefeed,
};
#define KBD_MAP(name, base, map) \
{ name, base, sizeof(map)/sizeof(keysym_t), map }
static const struct wscons_keydesc kmkbd_keydesctab[] = {
KBD_MAP(KB_MACHDEP, 0, kmkbd_keydesc_0),
{0, 0, 0, 0}
};
const struct wskbd_mapdata kmkbd_keymapdata = {
kmkbd_keydesctab,
#ifdef KMKBD_LAYOUT
KMKBD_LAYOUT,
#else
KB_MACHDEP,
#endif
};
/*
* Hackish support for a bell on the PC Keyboard; when a suitable feeper
* is found, it attaches itself into the pckbd driver here.
*/
void (*kmkbd_bell_fn)(void *, u_int, u_int, u_int, int);
void *kmkbd_bell_fn_arg;
void kmkbd_bell(u_int, u_int, u_int, int);
void kmkbd_hookup_bell(void (* fn)(void *, u_int, u_int, u_int, int), void *arg);
static int kmkbd_intr(void *);
static void kmkbd_new_state(struct kmkbd_softc *, enum kmkbd_state);
/*struct kmkbd_internal kmkbd_consdata;*/
static int
kmkbd_is_console(void)
{
#if 0
return (kmkbd_consdata.t_isconsole &&
(tag == kmkbd_consdata.t_kbctag) &&
(slot == kmkbd_consdata.t_kbcslot));
#else
return 0;
#endif
}
int
kmkbd_match(struct device *parent, struct cfdata *cf, void *aux)
{
return 1;
}
void
kmkbd_attach(struct device *parent, struct device *self, void *aux)
{
struct kmkbd_softc *sc = (void *)self;
/*struct obio_attach_args *oa = aux;*/
int state0;
struct wskbddev_attach_args a;
struct obio_softc *osc = (struct obio_softc *)parent;
int s;
printf("\n");
sc->state = ST_INIT;
if (kmkbd_is_console()){
a.console = 1;
state0 = ST_ALL_UP;
} else {
a.console = 0;
state0 = ST_DISABLED;
}
callout_init(&sc->callout);
s = spltty();
sc->ih = obio_intr_establish(osc, G42XXEB_INT_KEY, IPL_TTY,
IST_EDGE_FALLING, kmkbd_intr, (void *)sc);
kmkbd_new_state(sc, state0);
splx(s);
a.keymap = &kmkbd_keymapdata;
a.accessops = &kmkbd_accessops;
a.accesscookie = sc;
/* Attach the wskbd. */
sc->wskbddev = config_found(self, &a, wskbddevprint);
}
static int
kmkbd_enable(void *v, int on)
{
struct kmkbd_softc *sc = v;
if (on) {
if (sc->state != ST_DISABLED) {
#ifdef DIAGNOSTIC
printf("kmkbd_enable: bad enable (state=%d)\n", sc->state);
#endif
return (EBUSY);
}
kmkbd_new_state(sc, ST_ALL_UP);
} else {
#if 0
if (sc->id->t_isconsole)
return (EBUSY);
#endif
kmkbd_new_state(sc, ST_DISABLED);
}
return (0);
}
static void
kmkbd_set_leds(void *v, int leds)
{
}
static int
kmkbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{
/*struct kmkbd_softc *sc = v;*/
switch (cmd) {
case WSKBDIO_GTYPE:
*(int *)data = WSKBD_TYPE_PC_XT; /* XXX */
return 0;
case WSKBDIO_COMPLEXBELL:
#define d ((struct wskbd_bell_data *)data)
/*
* Keyboard can't beep directly; we have an
* externally-provided global hook to do this.
*/
kmkbd_bell(d->pitch, d->period, d->volume, 0);
#undef d
return (0);
#ifdef WSDISPLAY_COMPAT_RAWKBD
case WSKBDIO_SETMODE:
sc->rawkbd = (*(int *)data == WSKBD_RAW);
return (0);
#endif
#if 0
case WSKBDIO_SETLEDS:
case WSKBDIO_GETLEDS:
/* no LED support */
#endif
}
return EPASSTHROUGH;
}
void
kmkbd_bell(u_int pitch, u_int period, u_int volume, int poll)
{
if (kmkbd_bell_fn != NULL)
(*kmkbd_bell_fn)(kmkbd_bell_fn_arg, pitch, period,
volume, poll);
}
void
kmkbd_hookup_bell(void (* fn)(void *, u_int, u_int, u_int, int), void *arg)
{
if (kmkbd_bell_fn == NULL) {
kmkbd_bell_fn = fn;
kmkbd_bell_fn_arg = arg;
}
}
#if 0
int
kmkbd_cnattach(kbctag, kbcslot)
pckbc_tag_t kbctag;
int kbcslot;
{
int res;
res = kmkbd_init(&kmkbd_consdata, kbctag, kbcslot, 1);
wskbd_cnattach(&kmkbd_consops, &kmkbd_consdata, &kmkbd_keymapdata);
return (0);
}
void
kmkbd_cngetc(void *v, u_int type, int *data)
{
struct kmkbd_internal *t = v;
int val;
for (;;) {
val = pckbc_poll_data(t->t_kbctag, t->t_kbcslot);
if ((val != -1) && kmkbd_decode(t, val, type, data))
return;
}
}
void
kmkbd_cnpollc(void *v, int on)
{
struct kmkbd_internal *t = v;
pckbc_set_poll(t->t_kbctag, t->t_kbcslot, on);
}
void
kmkbd_cnbell(void *v, u_int pitch, u_int period, u_int volume)
{
kmkbd_bell(pitch, period, volume, 1);
}
#endif
/*
* low level access to key matrix
*
* returns bitset of keys being pressed.
*/
static u_int
kmkbd_read_matrix(struct kmkbd_softc *sc)
{
int i;
u_int ret, data;
struct obio_softc *osc = (struct obio_softc *)(sc->dev.dv_parent);
bus_space_tag_t iot = osc->sc_iot;
bus_space_handle_t ioh = osc->sc_obioreg_ioh;
#define KMDELAY() delay(3)
bus_space_write_2( iot, ioh, G42XXEB_KEYSCAN, 0 );
KMDELAY();
data = KEYSCAN_SENSE_IN &
bus_space_read_2(iot, ioh, G42XXEB_KEYSCAN);
bus_space_write_2(iot, ioh, G42XXEB_KEYSCAN, KEYSCAN_SCAN_OUT);
if (data == KEYSCAN_SENSE_IN)
return 0;
ret = 0;
for( i=0; i<5; ++i ){
/* scan one line */
bus_space_write_2(iot, ioh, G42XXEB_KEYSCAN, ~(0x0100<<i));
KMDELAY();
data = bus_space_read_2(iot, ioh, G42XXEB_KEYSCAN );
data = ~data & KEYSCAN_SENSE_IN;
ret |= data << (i*4);
}
bus_space_write_2(iot, ioh, G42XXEB_KEYSCAN, KEYSCAN_SCAN_OUT);
return ret;
#undef KMDELAY
}
/*
* report key status change to wskbd subsystem.
*/
static void
kmkbd_report(struct kmkbd_softc *sc, u_int bitset)
{
u_int changed;
int i;
if (bitset == sc->notified_bits)
return;
if (sc->notified_bits && bitset == 0){
wskbd_input(sc->wskbddev, WSCONS_EVENT_ALL_KEYS_UP, 0);
sc->notified_bits = 0;
return;
}
changed = bitset ^ sc->notified_bits;
for( i=0; changed; ++i){
if ((changed & (1<<i)) == 0)
continue;
changed &= ~(1<<i);
wskbd_input(sc->wskbddev,
(bitset & (1<<i)) ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP,
i);
}
sc->notified_bits = bitset;
}
static int
kmkbd_intr(void *arg)
{
struct kmkbd_softc *sc = arg;
struct obio_softc *osc = (struct obio_softc *)(sc->dev.dv_parent);
if ( sc->state != ST_ALL_UP ){
printf("Spurious interrupt from key matrix\n");
obio_intr_mask(osc, sc->ih);
return 1;
}
kmkbd_new_state(sc, ST_DEBOUNCE);
return 1;
}
static void
kmkbd_debounce(void *arg)
{
struct kmkbd_softc *sc = arg;
u_int newbits;
enum kmkbd_state new_state = ST_DEBOUNCE;
int s = spltty();
newbits = kmkbd_read_matrix(sc);
if (newbits != sc->last_bits){
sc->last_bits = newbits;
sc->debounce_counter = 0;
}
else if( ++(sc->debounce_counter) >= DEBOUNCE_COUNT ){
new_state = newbits == 0 ? ST_ALL_UP : ST_KEY_PRESSED;
kmkbd_report(sc, newbits);
}
kmkbd_new_state(sc, new_state);
splx(s);
}
/* callout routine to watch key release */
static void
kmkbd_watch(void *arg)
{
int s = spltty();
struct kmkbd_softc *sc = arg;
u_int newbits;
int new_state = ST_KEY_PRESSED;
newbits = kmkbd_read_matrix(sc);
if (newbits != sc->last_bits){
/* some keys are released or new keys are pressed.
start debounce */
new_state = ST_DEBOUNCE;
sc->last_bits = newbits;
}
kmkbd_new_state(sc, new_state);
splx(s);
}
static void
kmkbd_new_state(struct kmkbd_softc *sc, enum kmkbd_state new_state)
{
struct obio_softc *osc = (struct obio_softc *)(sc->dev.dv_parent);
switch(new_state){
case ST_DISABLED:
if (sc->state != ST_DISABLED){
callout_stop(&sc->callout);
obio_intr_mask(osc,sc->ih);
}
break;
case ST_DEBOUNCE:
if (sc->state == ST_ALL_UP){
obio_intr_mask(osc, sc->ih);
sc->last_bits = kmkbd_read_matrix(sc);
}
if (sc->state != ST_DEBOUNCE)
sc->debounce_counter = 0;
/* start debounce timer */
callout_reset(&sc->callout, DEBOUNCE_TICKS, kmkbd_debounce, sc);
break;
case ST_KEY_PRESSED:
/* start timer to check key release */
callout_reset(&sc->callout, RELEASE_WATCH_TICKS, kmkbd_watch, sc);
break;
case ST_ALL_UP:
if (sc->state != ST_ALL_UP){
bus_space_tag_t iot = osc->sc_iot;
bus_space_handle_t ioh = osc->sc_obioreg_ioh;
obio_intr_unmask(osc, sc->ih);
bus_space_write_2(iot, ioh, G42XXEB_KEYSCAN, 0);
}
break;
case ST_INIT:
; /* Nothing to do */
}
sc->state = new_state;
}

View File

@ -0,0 +1,320 @@
/* $NetBSD: g42xxeb_lcd.c,v 1.1 2005/02/26 10:49:53 bsh Exp $ */
/*-
* Copyright (c) 2001, 2002, 2005 Genetec corp.
* All rights reserved.
*
* LCD driver for Genetec G4250EB-X002.
* Written by Hiroyuki Bessho for Genetec corp.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "opt_g42xxlcd.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/uio.h>
#include <sys/malloc.h>
#include <dev/cons.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/wscons/wscons_callbacks.h>
#include <machine/bus.h>
#include <arm/sa11x0/sa11x0_var.h>
#include <arm/xscale/pxa2x0var.h>
#include <arm/xscale/pxa2x0reg.h>
#include <arm/xscale/pxa2x0_lcd.h>
#include <arch/evbarm/g42xxeb/g42xxeb_reg.h>
#include <arch/evbarm/g42xxeb/g42xxeb_var.h>
#include "wsdisplay.h"
#include "ioconf.h"
int lcd_match( struct device *, struct cfdata *, void *);
void lcd_attach( struct device *, struct device *, void *);
int lcdintr(void *);
#if NWSDISPLAY > 0
/*
* wsdisplay glue
*/
struct pxa2x0_wsscreen_descr lcd_bpp16_screen = {
{
"bpp16", 0, 0,
&pxa2x0_lcd_emulops,
0, 0,
WSSCREEN_WSCOLORS,
},
16 /* bits per pixel */
}, lcd_bpp8_screen = {
{
"bpp8", 0, 0,
&pxa2x0_lcd_emulops,
0, 0,
WSSCREEN_WSCOLORS,
},
8 /* bits per pixel */
}, lcd_bpp4_screen = {
{
"bpp4", 0, 0,
&pxa2x0_lcd_emulops,
0, 0,
WSSCREEN_WSCOLORS,
},
4 /* bits per pixel */
};
static const struct wsscreen_descr *lcd_scr_descr[] = {
&lcd_bpp4_screen.c,
&lcd_bpp8_screen.c,
&lcd_bpp16_screen.c,
};
const struct wsscreen_list lcd_screen_list = {
sizeof lcd_scr_descr / sizeof lcd_scr_descr[0],
lcd_scr_descr
};
int lcd_ioctl(void *, u_long, caddr_t, int, struct proc *);
int lcd_show_screen(void *, void *, int,
void (*)(void *, int, int), void *);
const struct wsdisplay_accessops lcd_accessops = {
lcd_ioctl,
pxa2x0_lcd_mmap,
pxa2x0_lcd_alloc_screen,
pxa2x0_lcd_free_screen,
lcd_show_screen,
NULL, /* load_font */
};
#else
/*
* Interface to LCD framebuffer without wscons
*/
dev_type_open(lcdopen);
dev_type_close(lcdclose);
dev_type_ioctl(lcdioctl);
dev_type_mmap(lcdmmap);
const struct cdevsw lcd_cdevsw = {
lcdopen, lcdclose, noread, nowrite,
lcdioctl, nostop, notty, nopoll, lcdmmap, D_TTY
};
#endif
CFATTACH_DECL(lcd_obio, sizeof (struct pxa2x0_lcd_softc), lcd_match, lcd_attach,
NULL, NULL);
int
lcd_match( struct device *parent, struct cfdata *cf, void *aux )
{
return 1;
}
#ifdef G4250_LCD_NEC_NL3224BC35
/* NEC's QVGA LCD */
static const struct lcd_panel_geometry nec_NL3224BC35 =
{
320, /* Width */
240, /* Height */
0, /* No extra lines */
LCDPANEL_SINGLE|LCDPANEL_ACTIVE|LCDPANEL_PCP|
LCDPANEL_VSP|LCDPANEL_HSP,
7, /* clock divider, 6.25MHz at 100MHz */
0xff, /* AC bias pin freq */
6, /* horizontal sync pulse width */
70, /* BLW */
7, /* ELW */
10, /* vertical sync pulse width */
11, /* BFW */
1, /* EFW */
};
#endif
#ifdef G4250_LCD_TOSHIBA_LTM035
const struct lcd_panel_geometry toshiba_LTM035 =
{
240, /* Width */
320, /* Height */
0, /* No extra lines */
LCDPANEL_SINGLE|LCDPANEL_ACTIVE| /* LCDPANEL_PCP| */
LCDPANEL_VSP|LCDPANEL_HSP,
11, /* clock divider, 4.5MHz at 100Mhz */
/* required: 4.28..4.7 MHz */
0xff, /* AC bias pin freq */
4, /* horizontal sync pulse width */
8, /* BLW (back porch) */
4, /* ELW (front porch) */
2, /* vertical sync pulse width */
2, /* BFW (back porch) */
3, /* EFW (front porch) */
};
#endif /* G4250_LCD_TOSHIBA_LTM035 */
void lcd_attach( struct device *parent, struct device *self, void *aux )
{
struct pxa2x0_lcd_softc *sc = (struct pxa2x0_lcd_softc *)self;
#ifdef G4250_LCD_TOSHIBA_LTM035
# define PANEL toshiba_LTM035
#else
# define PANEL nec_NL3224BC35
#endif
pxa2x0_lcd_attach_sub(sc, aux, &PANEL);
#if NWSDISPLAY > 0
{
struct wsemuldisplaydev_attach_args aa;
/* make wsdisplay screen list */
pxa2x0_lcd_setup_wsscreen(&lcd_bpp16_screen, &PANEL, NULL);
pxa2x0_lcd_setup_wsscreen(&lcd_bpp8_screen, &PANEL, NULL);
pxa2x0_lcd_setup_wsscreen(&lcd_bpp4_screen, &PANEL, NULL);
aa.console = 0;
aa.scrdata = &lcd_screen_list;
aa.accessops = &lcd_accessops;
aa.accesscookie = sc;
printf("\n");
(void) config_found(self, &aa, wsemuldisplaydevprint);
}
#else
{
struct pxa2x0_lcd_screen *screen = pxa2x0_lcd_new_screen( sc, 16 );
if (screen) {
sc->active = screen;
pxa2x0_lcd_start_dma(sc, screen);
}
printf("\n");
}
#endif
#undef PANEL
}
#if NWSDISPLAY > 0
int
lcd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{
struct obio_softc *osc =
(struct obio_softc *)((struct device *)v)->dv_parent;
uint16_t reg;
switch (cmd) {
case WSDISPLAYIO_SVIDEO:
reg = bus_space_read_2(osc->sc_iot, osc->sc_obioreg_ioh,
G42XXEB_LCDCTL);
if (*(int *)data == WSDISPLAYIO_VIDEO_ON)
reg |= LCDCTL_BL_ON;
else
reg &= ~LCDCTL_BL_ON;
bus_space_write_2(osc->sc_iot, osc->sc_obioreg_ioh,
G42XXEB_LCDCTL, reg);
bus_space_write_1(osc->sc_iot, osc->sc_obioreg_ioh,
G42XXEB_LED, reg);
printf("LCD control: %x\n", reg);
break; /* turn on/off LCD controller */
}
return pxa2x0_lcd_ioctl(v, cmd, data, flag, p);
}
int
lcd_show_screen(void *v, void *cookie, int waitok,
void (*cb)(void *, int, int), void *cbarg)
{
struct obio_softc *osc =
(struct obio_softc *)((struct device *)v)->dv_parent;
uint16_t reg;
pxa2x0_lcd_show_screen(v,cookie,waitok,cb,cbarg);
/* Turn on LCD backlight.
XXX: with fixed blightness. want new ioctl to set blightness. */
reg = bus_space_read_2(osc->sc_iot, osc->sc_obioreg_ioh, G42XXEB_LCDCTL);
bus_space_write_2(osc->sc_iot, osc->sc_obioreg_ioh, G42XXEB_LCDCTL,
(reg & ~LCDCTL_BL_PWN) | 0x4000 | LCDCTL_BL_ON);
return 0;
}
#else /* NWSDISPLAY==0 */
int
lcdopen(dev_t dev, int oflags, int devtype, struct proc *p)
{
return 0;
}
int
lcdclose(dev_t dev, int fflag, int devtype, struct proc *p)
{
return 0;
}
paddr_t
lcdmmap(dev_t dev, off_t offset, int size)
{
struct pxa2x0_lcd_softc *sc = device_lookup(&lcd_cd, minor(dev));
struct pxa2x0_lcd_screen *scr = sc->active;
return bus_dmamem_mmap( &pxa2x0_bus_dma_tag, scr->segs, scr->nsegs,
offset, 0, BUS_DMA_WAITOK|BUS_DMA_COHERENT );
}
int
lcdioctl(dev_t dev, u_long cmd, caddr_t data,
int fflag, struct proc *p)
{
return EOPNOTSUPP;
}
#endif /* NWSDISPLAY>0 */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,124 @@
/*
* Copyright (c) 2002 Genetec corp. All rights reserved.
* Written by Hiroyuki Bessho for Genetec corp.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Genetec corp. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORP.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _EVBARM_G42XXEB_REG_H
#define _EVBARM_G42XXEB_REG_H
#include <arm/xscale/pxa2x0reg.h>
/* g42xxeb on-board IOs */
#define G42XXEB_PLDREG_BASE PXA2X0_CS3_START /* Phisical address */
#define G42XXEB_PLDREG_SIZE 0x00000100
#define G42XXEB_AX88796_PBASE (PXA2X0_CS3_START+0x02000000)
/*
* Logical mapping for onboard/integrated peripherals
* that are used while bootstrapping.
*/
#define G42XXEB_IO_AREA_VBASE 0xfd000000
#define G42XXEB_PLDREG_VBASE 0xfd000000
#define G42XXEB_INTCTL_VBASE 0xfd100000
#define G42XXEB_CLKMAN_VBASE 0xfd200000
#define G42XXEB_GPIO_VBASE 0xfd300000
#define G42XXEB_VBASE_FREE 0xfd400000
/* FFUART and/or BTUART are mapped to this area when
used for console or kgdb port */
/*
* Onboard register address
* (offset from G42XXEB_OBIO_PBASE)
*/
#define G42XXEB_INTSTS1 0x0a
#define G42XXEB_INTSTS2 0x0c
#define G42XXEB_INTCNTL 0x0e
#define G42XXEB_INTCNTH 0x10
#define G42XXEB_INTMASK 0x14
#define G42XXEB_INT_MMCSD 0
#define G42XXEB_INT_SDIO 1
#define G42XXEB_INT_EXT0 2
#define G42XXEB_INT_EXT1 3
#define G42XXEB_INT_USB 4
#define G42XXEB_INT_ETH 5
#define G42XXEB_INT_CODEC 6
#define G42XXEB_INT_EXT2 7
#define G42XXEB_INT_KEY 8
#define G42XXEB_INT_EXT3 9
#define G42XXEB_N_INTS 10
/* interrupt type */
#define G42XXEB_INT_LEVEL_LOW 0
#define G42XXEB_INT_LEVEL_HIGH 1
#define G42XXEB_INT_EDGE_FALLING 4
#define G42XXEB_INT_EDGE_RISING 5
#define G42XXEB_INT_EDGE_BOTH 6
#define G42XXEB_DIPSW 0x16
#define G42XXEB_LED 0x18
#define G42XXEB_RST 0x1a
#define RST_ASIX88796 (1<<0)
#define RST_EXT(n) (1<<((n)+1))
#define G42XXEB_EXTCTRL 0x1c
#define G42XXEB_OPTBRDID 0x20
#define G42XXEB_PLDVER 0x22
#define G42XXEB_LCDCTL 0x28
#define LCDCTL_BL_ON (1<<7)
#define LCDCTL_DPSH (1<<1)
#define LCDCTL_DPSV (1<<0)
#define LCDCTL_BL_PWM_SHIFT 8 /* Backlight blightness */
#define LCDCTL_BL_PWN (0xff<<LCDCTL_BL_PWM_SHIFT)
#define G42XXEB_KEYSCAN 0x2a
#define KEYSCAN_SCAN_OUT 0x1f00
#define KEYSCAN_SENSE_IN 0x0f
#define G42XXEB_WP 0x2c // SD/MMC write protect status
#define ioreg_read(a) (*(volatile unsigned *)(a))
#define ioreg_write(a,v) (*(volatile unsigned *)(a)=(v))
#define ioreg16_read(a) (*(volatile uint16_t *)(a))
#define ioreg16_write(a,v) (*(volatile uint16_t *)(a)=(v))
#define ioreg8_read(a) (*(volatile uint8_t *)(a))
#define ioreg8_write(a,v) (*(volatile uint8_t *)(a)=(v))
#define pldreg16_read(off) ioreg16_read(G42XXEB_PLDREG_VBASE+(off))
#define pldreg16_write(off,v) ioreg16_write(G42XXEB_PLDREG_VBASE+(off),v)
#define pldreg8_read(off) ioreg8_read(G42XXEB_PLDREG_VBASE+(off))
#define pldreg8_write(off,v) ioreg8_write(G42XXEB_PLDREG_VBASE+(off),v)
#endif /* _EVBARM_G42XXEB_REG_H */

View File

@ -0,0 +1,162 @@
/* $NetBSD: g42xxeb_start.S,v 1.1 2005/02/26 10:49:53 bsh Exp $ */
/*
* Copyright (c) 2002, 2003 Genetec Corporation. All rights reserved.
* Written by Hiroyuki Bessho for Genetec Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Genetec Corporation may not be used to endorse or
* promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/asm.h>
#include <arm/armreg.h>
#include <arm/arm32/pte.h>
#include <arm/arm32/pmap.h> /* for PMAP_DOMAIN_KERNEL */
#ifndef SDRAM_START
#define SDRAM_START 0xa0000000
#endif
/*
* CPWAIT -- Canonical method to wait for CP15 update.
* NOTE: Clobbers the specified temp reg.
* copied from arm/arm/cpufunc_asm_xscale.S
* XXX: better be in a common header file.
*/
#define CPWAIT_BRANCH \
sub pc, pc, #4
#define CPWAIT(tmp) \
mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\
mov tmp, tmp /* wait for it to complete */ ;\
CPWAIT_BRANCH /* branch to next insn */
/*
* Kernel start routine for G4255EB (TWINTAIL)
* this code is excuted at the very first after the kernel is loaded
* by RedBoot.
*/
.text
.global _C_LABEL(g42xxeb_start)
_C_LABEL(g42xxeb_start):
/* Are we running on ROM ? */
cmp pc, #0x06000000
bhi g42xxeb_start_ram
/* move me to RAM
* XXX: we can use memcpy if it is PIC
*/
ldr r1, Lcopy_size
adr r0, _C_LABEL(g42xxeb_start)
add r1, r1, #3
mov r1, r1, LSR #2
mov r2, #SDRAM_START
add r2, r2, #0x00200000
mov r4, r2
5: ldr r3,[r0],#4
str r3,[r2],#4
subs r1,r1,#1
bhi 5b
/* Jump to RAM */
ldr r0, Lstart_off
add pc, r4, r0
Lcopy_size: .word _edata-_C_LABEL(g42xxeb_start)
Lstart_off: .word g42xxeb_start_ram-_C_LABEL(g42xxeb_start)
g42xxeb_start_ram:
/*
* Kernel is loaded in SDRAM (0xa0200000..), and is expected to run
* in VA 0xc0200000..
*/
mrc p15, 0, r0, c2, c0, 0 /* get ttb prepared by redboot */
adr r4, mmu_init_table2
#ifdef BUILD_STARTUP_PAGETABLE
mrc p15, 0, r2, c1, c0, 0
tst r2, #CPU_CONTROL_MMU_ENABLE /* we already have a page table? */
bne 3f
/* build page table from scratch */
ldr r0, Lstartup_pagetable
adr r4, mmu_init_table
#endif
b 3f
2:
str r3, [r0, r2]
add r2, r2, #4
add r3, r3, #(L1_S_SIZE)
adds r1, r1, #-1
bhi 2b
3:
ldmia r4!, {r1,r2,r3} /* # of sections, PA|attr, VA */
cmp r1, #0
bne 2b
mcr p15, 0, r0, c2, c0, 0 /* Set TTB */
mcr p15, 0, r0, c8, c7, 0 /* Flush TLB */
/* Set the Domain Access register. Very important! */
mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
mcr p15, 0, r0, c3, c0, 0
/* Enable MMU */
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #CPU_CONTROL_MMU_ENABLE
mcr p15, 0, r0, c1, c0, 0
CPWAIT(r0)
/* Jump to kernel code in TRUE VA */
adr r0, Lstart
ldr pc, [r0]
Lstart:
.word start
#define MMU_INIT(va,pa,n_sec,attr) \
.word n_sec ; \
.word 4*((va)>>L1_S_SHIFT) ; \
.word (pa)|(attr) ;
#ifdef BUILD_STARTUP_PAGETABLE
#ifndef STARTUP_PAGETABLE_ADDR
#define STARTUP_PAGETABLE_ADDR 0xa0004000
#endif
Lstartup_pagetable .word STARTUP_PAGETABLE_ADDR
mmu_init_table:
/* fill all table VA==PA */
MMU_INIT(0x00000000, 0x00000000, 1<<(32-L1_S_SHIFT), L1_TYPE_S|L1_S_AP(AP_KRW))
/* map SDRAM VA==PA, WT cacheable */
MMU_INIT(SDRAM_START, SDRAM_START, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
#endif
mmu_init_table2:
/* map VA 0xc0000000..0xc3ffffff to PA 0xa0000000..0xa3ffffff */
MMU_INIT(0xc0000000, SDRAM_START, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
.word 0 /* end of table */

View File

@ -0,0 +1,94 @@
/*-
* Copyright (c) 2001, 2002, 2005 Genetec corp.
* All rights reserved.
*
* Written by Hiroyuki Bessho for Genetec corp.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _EVBARM_G42XXEB_VAR_H
#define _EVBARM_G42XXEB_VAR_H
#include <sys/conf.h>
#include <sys/device.h>
#include <machine/bus.h>
#include <evbarm/g42xxeb/g42xxeb_reg.h>
/*
* G42xxeb on-board IO bus
*/
struct obio_softc {
struct device sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_obioreg_ioh;
/* handle to PXA2x0's memory controller.
XXX: shouldn't be here. */
bus_space_handle_t sc_memctl_ioh;
void *sc_ih; /* interrupt handler for obio on pxaip */
void *sc_si; /* software interrupt handler */
int sc_intr;
uint16_t sc_intr_mask;
uint16_t sc_intr_pending;
int sc_ipl; /* Max ipl among sub interrupts */
struct obio_handler {
int (* func)(void *);
void *arg;
int level;
} sc_handler[G42XXEB_N_INTS];
};
typedef void *obio_chipset_tag_t;
struct obio_attach_args {
obio_chipset_tag_t oba_sc;
bus_space_tag_t oba_iot; /* Bus tag */
bus_addr_t oba_addr; /* i/o address */
int oba_intr;
};
/* on-board hex LED */
void hex_led( uint32_t value );
/*
* IRQ handler
*/
void *obio_intr_establish(struct obio_softc *, int, int, int,
int (*)(void *), void *);
void obio_intr_disestablish(struct obio_softc *, int, int (*)(void *));
void obio_intr_mask(struct obio_softc *, struct obio_handler *);
void obio_intr_unmask(struct obio_softc *, struct obio_handler *);
#define obio_update_intrmask(sc) \
bus_space_write_2( (sc)->sc_iot, (sc)->sc_obioreg_ioh, \
G42XXEB_INTMASK, (sc)->sc_intr_mask | (sc)->sc_intr_pending );
void obio_peripheral_reset(struct obio_softc *, int, int);
#endif /* _EVBARM_G42XXEB_VAR_H */

View File

@ -0,0 +1,301 @@
/* $NetBSD: gb225.c,v 1.1 2005/02/26 10:49:53 bsh Exp $ */
/*
* Copyright (c) 2002, 2003 Genetec corp. All rights reserved.
* Written by Hiroyuki Bessho for Genetec corp.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Genetec corp. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORP.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/reboot.h>
#include <machine/cpu.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <arm/cpufunc.h>
#include <arm/mainbus/mainbus.h>
#include <arm/xscale/pxa2x0reg.h>
#include <arm/xscale/pxa2x0var.h>
#include <arm/xscale/pxa2x0_gpio.h>
#include <arm/sa11x0/sa11x0_var.h>
#include <evbarm/g42xxeb/g42xxeb_reg.h>
#include <evbarm/g42xxeb/g42xxeb_var.h>
#include <evbarm/g42xxeb/gb225reg.h>
#include <evbarm/g42xxeb/gb225var.h>
#include "locators.h"
#define OPIO_INTR G42XXEB_INT_EXT3
#define DEBOUNCE_COUNT 2
#define DEBOUNCE_TICKS (hz/20) /* 50ms */
/* prototypes */
static int opio_match(struct device *, struct cfdata *, void *);
static void opio_attach(struct device *, struct device *, void *);
static int opio_search(struct device *, struct cfdata *, void *);
static int opio_print(void *, const char *);
#ifdef OPIO_INTR
static int opio_intr( void *arg );
static void opio_debounce(void *arg);
#endif
/* attach structures */
CFATTACH_DECL(opio, sizeof(struct opio_softc), opio_match, opio_attach,
NULL, NULL);
/*
* int opio_print(void *aux, const char *name)
* print configuration info for children
*/
static int
opio_print(void *aux, const char *name)
{
struct obio_attach_args *oba = (struct obio_attach_args*)aux;
if (oba->oba_addr != OPIOCF_ADDR_DEFAULT)
aprint_normal(" addr 0x%lx", oba->oba_addr);
return (UNCONF);
}
int
opio_match(struct device *parent, struct cfdata *match, void *aux)
{
struct obio_softc *psc = (struct obio_softc *)parent;
uint16_t optid;
optid = bus_space_read_2(psc->sc_iot, psc->sc_obioreg_ioh,
G42XXEB_OPTBRDID);
return optid == 0x01;
}
void
opio_attach(struct device *parent, struct device *self, void *aux)
{
struct opio_softc *sc = (struct opio_softc*)self;
struct obio_softc *bsc = (struct obio_softc *)parent;
struct obio_attach_args *oba = aux;
uint32_t reg;
int i;
bus_space_tag_t iot;
bus_space_handle_t memctl_ioh = bsc->sc_memctl_ioh;
iot = oba->oba_iot;
sc->sc_iot = iot;
sc->sc_memctl_ioh = memctl_ioh;
/* use 16bit access for CS4, 32bit for CS5 */
reg = bus_space_read_4(iot, memctl_ioh, MEMCTL_MSC2);
reg |= MSC_RBW;
reg &= ~(MSC_RBW<<16);
/* XXX: set access timing */
bus_space_write_4(iot, memctl_ioh, MEMCTL_MSC2, reg);
/* Set alternative function for GPIO pings 48..57 on PXA2X0 */
#if 0
reg = bus_space_read_4(iot, csc->saip.sc_gpioh, GPIO_GPDR1);
bus_space_write_4(iot, csc->saip.sc_gpioh, GPIO_GPDR1,
(reg & ~0x03ff0000) | 0x00ff0000);
reg = bus_space_read_4(iot, csc->saip.sc_gpioh, GPIO_GAFR1_U);
bus_space_write_4(iot, csc->saip.sc_gpioh, GPIO_GAFR1_U,
(reg & ~0x000fffff) | 0x0005aaaa );
#else
for (i=47; i <= 55; ++i)
pxa2x0_gpio_set_function(i, GPIO_ALT_FN_2_OUT);
pxa2x0_gpio_set_function(56, GPIO_ALT_FN_1_IN);
pxa2x0_gpio_set_function(57, GPIO_ALT_FN_1_IN);
#endif
/* Enable bus switch for option board */
reg = bus_space_read_2(iot, bsc->sc_obioreg_ioh, G42XXEB_EXTCTRL);
bus_space_write_2(iot, bsc->sc_obioreg_ioh, G42XXEB_EXTCTRL, reg | 3);
/* Map on-board FPGA registers */
if( bus_space_map( iot, GB225_PLDREG_BASE, GB225_PLDREG_SIZE,
0, &(sc->sc_ioh) ) ){
aprint_error("%s: can't map FPGA registers\n", self->dv_xname);
}
aprint_normal("\n");
callout_init(&sc->sc_callout);
for (i=0; i < N_OPIO_INTR; ++i) {
sc->sc_intr[i].func = NULL;
sc->sc_intr[i].reported_state = 0xff;
sc->sc_intr[i].last_state = 0xff;
}
#ifdef OPIO_INTR
sc->sc_ih = obio_intr_establish(bsc, OPIO_INTR, IPL_BIO,
IST_EDGE_FALLING, opio_intr, sc);
#endif
#ifdef DEBUG
printf("%s: CF_DET=%x PCMCIA_DET=%x\n",
self->dv_xname,
bus_space_read_1(sc->sc_iot, sc->sc_ioh, GB225_CFDET),
bus_space_read_1(sc->sc_iot, sc->sc_ioh, GB225_PCMCIADET));
#endif
/*
* Attach each devices
*/
config_search(opio_search, self, NULL);
}
int
opio_search(struct device *parent, struct cfdata *cf, void *aux)
{
struct opio_softc *sc = (struct opio_softc *)parent;
struct obio_attach_args oba;
oba.oba_sc = sc;
oba.oba_iot = sc->sc_iot;
oba.oba_addr = cf->cf_loc[OBIOCF_ADDR];
oba.oba_intr = cf->cf_loc[OBIOCF_INTR];
if (config_match(parent, cf, &oba) > 0)
config_attach(parent, cf, &oba, opio_print);
return 0;
}
void *
opio_intr_establish(struct opio_softc *sc, int intr, int ipl,
int (*func)(void *, int), void *arg)
{
sc->sc_intr[intr].arg = arg;
sc->sc_intr[intr].func = func;
return &sc->sc_intr[intr];
}
#ifdef OPIO_INTR
/*
* interrupt handler for option board. interrupt sources are:
* CF card insertion/removal.
* PCMCIA card insertion/removal.
* USB power failure.
* CF/PCMCIA power failure.
* We need to debounce for CF/PCMCIA card insertion/removal signal.
*/
static int
opio_intr( void *arg )
{
struct opio_softc *sc = (struct opio_softc *)arg;
struct obio_softc *bsc = (struct obio_softc *)sc->sc_dev.dv_parent;
/* avoid further interrupts while debouncing */
obio_intr_mask(bsc, sc->sc_ih);
printf("OPIO ");
if (sc->sc_debounce == ST_STABLE) {
/* start debounce timer */
callout_reset(&sc->sc_callout, DEBOUNCE_TICKS,
opio_debounce, sc);
sc->sc_debounce = ST_BOUNCING;
}
return 1;
}
static int
do_debounce(struct opio_softc *sc, int intr, int val, int count)
{
int s;
struct opio_intr_handler *p = &sc->sc_intr[intr];
if (p->last_state != val) {
p->debounce_count = 0;
p->last_state = val;
return 1;
}
else if (p->debounce_count++ < count)
return 1;
else {
/* debounce done. if status has changed, report it */
if (p->reported_state != val) {
p->reported_state = val;
if (p->func) {
s = _splraise(p->level);
p->func(p->arg, val);
splx(s);
}
}
return 0;
}
/*NOTREACHED*/
}
static void
opio_debounce(void *arg)
{
struct opio_softc *sc = arg;
struct obio_softc *osc = (struct obio_softc *)sc->sc_dev.dv_parent;
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
int flag = 0;
uint8_t reg;
reg = bus_space_read_1(iot, ioh, GB225_CFDET) & CARDDET_DET;
flag |= do_debounce(sc, OPIO_INTR_CF_INSERT, reg, DEBOUNCE_COUNT);
reg = bus_space_read_1(iot, ioh, GB225_PCMCIADET) & CARDDET_DET;
flag |= do_debounce(sc, OPIO_INTR_PCMCIA_INSERT, reg, DEBOUNCE_COUNT);
reg = bus_space_read_1(iot, ioh, GB225_DEVERROR);
flag |= do_debounce(sc, OPIO_INTR_USB_POWER, reg & DEVERROR_USB, 1);
flag |= do_debounce(sc, OPIO_INTR_CARD_POWER, reg & DEVERROR_CARD, 1);
if (flag) {
/* start debounce timer */
callout_reset(&sc->sc_callout, DEBOUNCE_TICKS,
opio_debounce, sc);
}
else {
sc->sc_debounce = ST_STABLE;
obio_intr_unmask(osc, sc->sc_ih);
}
}
#endif

View File

@ -0,0 +1,387 @@
/*
* Copyright (c) 2002, 2003, 2005 Genetec corp. All rights reserved.
*
* PCMCIA/CF support for TWINTAIL (G4255EB)
* Written by Hiroyuki Bessho for Genetec corp.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Genetec corp. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORP.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/callout.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/malloc.h>
#include <uvm/uvm.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <dev/pcmcia/pcmciareg.h>
#include <dev/pcmcia/pcmciavar.h>
#include <dev/pcmcia/pcmciachip.h>
#include <arch/arm/xscale/pxa2x0var.h>
#include <arch/arm/xscale/pxa2x0reg.h>
#include <arch/arm/sa11x0/sa11xx_pcicvar.h>
#include <arch/evbarm/g42xxeb/g42xxeb_reg.h>
#include <arch/evbarm/g42xxeb/g42xxeb_var.h>
#include <arch/evbarm/g42xxeb/gb225reg.h>
#include <arch/evbarm/g42xxeb/gb225var.h>
//#define DONT_USE_CARD_DETECT_INTR
#define PCMCIA_INT G42XXEB_INT_EXT1
#define CF_INT G42XXEB_INT_EXT0
#ifdef DEBUG
#define DPRINTF(arg) printf arg
#else
#define DPRINTF(arg)
#endif
struct opcic_softc;
struct opcic_socket {
struct sapcic_socket ss; /* inherit socket for sa11x0 pcic */
#if 0
int voltage; /* card power voltage selected by
upper layer */
#endif
};
struct opcic_softc {
struct sapcic_softc sc_pc; /* inherit SA11xx pcic */
struct opcic_socket sc_socket[2];
int sc_cards;
bus_space_handle_t sc_memctl_ioh;
};
static int opcic_match(struct device *, struct cfdata *, void *);
static void opcic_attach(struct device *, struct device *, void *);
static int opcic_print(void *, const char *);
static int opcic_submatch(struct device *, struct cfdata *, void *);
static int opcic_read(struct sapcic_socket *, int);
static void opcic_write(struct sapcic_socket *, int, int);
static void opcic_set_power(struct sapcic_socket *, int);
static void opcic_clear_intr(int);
static void *opcic_intr_establish(struct sapcic_socket *, int,
int (*)(void *), void *);
static void opcic_intr_disestablish(struct sapcic_socket *, void *);
#ifndef DONT_USE_CARD_DETECT_INTR
static int opcic_card_detect(void *, int);
#endif
CFATTACH_DECL(opcic, sizeof(struct opcic_softc),
opcic_match, opcic_attach, NULL, NULL);
static struct sapcic_tag opcic_tag = {
opcic_read,
opcic_write,
opcic_set_power,
opcic_clear_intr,
opcic_intr_establish,
opcic_intr_disestablish,
};
#define HAVE_CARD(r) (((r)&CARDDET_DET)==0)
static __inline uint8_t
opcic_read_card_status(struct opcic_socket *so)
{
struct opcic_softc *sc = (struct opcic_softc *)(so->ss.sc);
struct opio_softc *osc =
(struct opio_softc *)(sc->sc_pc.sc_dev.dv_parent);
return bus_space_read_1(osc->sc_iot, osc->sc_ioh,
GB225_CFDET + 2 * so->ss.socket);
}
static int
opcic_match(struct device *parent, struct cfdata *cf, void *aux)
{
return 1;
}
static void
opcic_attach(struct device *parent, struct device *self, void *aux)
{
int i;
struct pcmciabus_attach_args paa;
struct opcic_softc *sc = (struct opcic_softc *)self;
struct opio_softc *psc = (struct opio_softc *)parent;
struct obio_softc *bsc = (struct obio_softc *)parent->dv_parent;
bus_space_handle_t memctl_ioh = bsc->sc_memctl_ioh;
bus_space_tag_t iot = psc->sc_iot;
printf("\n");
/* tell PXA2X0 that we have two sockets */
#if 0
bus_space_write_4(iot, memctl_ioh, MEMCTL_MECR, MECR_NOS);
#else
bus_space_write_4(iot, memctl_ioh, MEMCTL_MECR, MECR_CIT|MECR_NOS);
#endif
sc->sc_pc.sc_iot = psc->sc_iot;
sc->sc_memctl_ioh = memctl_ioh;
sc->sc_cards = 0;
for(i = 0; i < 2; i++) {
sc->sc_socket[i].ss.sc = &sc->sc_pc;
sc->sc_socket[i].ss.socket = i;
sc->sc_socket[i].ss.pcictag_cookie = NULL;
sc->sc_socket[i].ss.pcictag = &opcic_tag;
sc->sc_socket[i].ss.event_thread = NULL;
sc->sc_socket[i].ss.event = 0;
sc->sc_socket[i].ss.laststatus = CARDDET_NOCARD;
sc->sc_socket[i].ss.shutdown = 0;
sc->sc_socket[i].ss.power_capability =
(SAPCIC_POWER_5V|SAPCIC_POWER_3V);
bus_space_write_4(iot, memctl_ioh, MEMCTL_MCIO(i),
MC_TIMING_VAL(1,1,1));
#if 0
bus_space_write_4(iot, memctl_ioh, MEMCTL_MCATT(i),
MC_TIMING_VAL(31,31,31));
#endif
paa.paa_busname = "pcmcia";
paa.pct = (pcmcia_chipset_tag_t)&sa11x0_pcmcia_functions;
paa.pch = (pcmcia_chipset_handle_t)&sc->sc_socket[i].ss;
paa.iobase = 0;
paa.iosize = 0x4000000;
sc->sc_socket[i].ss.pcmcia =
(struct device *)config_found_sm(&sc->sc_pc.sc_dev,
&paa, opcic_print, opcic_submatch);
#ifndef DONT_USE_CARD_DETECT_INTR
/* interrupt for card insertion/removal */
opio_intr_establish(psc,
i==0 ? OPIO_INTR_CF_INSERT : OPIO_INTR_PCMCIA_INSERT,
IPL_BIO, opcic_card_detect, &sc->sc_socket[i]);
#else
bus_space_write_4(iot, ioh, MEMCTL_MECR, MECR_NOS | MECR_CIT);
#endif
/* schedule kthread creation */
kthread_create(sapcic_kthread_create, &sc->sc_socket[i].ss);
}
}
static int
opcic_print(void *aux, const char *name)
{
return (UNCONF);
}
static int
opcic_submatch(struct device *parent, struct cfdata *cf, void *aux)
{
return config_match(parent, cf, aux);
}
#ifndef DONT_USE_CARD_DETECT_INTR
static int
opcic_card_detect(void *arg, int val)
{
struct opcic_socket *socket = arg;
struct opcic_softc *sc = (struct opcic_softc *)socket->ss.sc;
bus_space_tag_t iot = sc->sc_pc.sc_iot;
bus_space_handle_t memctl_ioh = sc->sc_memctl_ioh;
int sock_no = socket->ss.socket;
int last, s;
s = splbio();
last = sc->sc_cards;
if (HAVE_CARD(val)) {
sc->sc_cards |= 1<<sock_no;
/* if it is the first card, turn on expansion memory
* control. */
if (last == 0)
bus_space_write_4(iot, memctl_ioh, MEMCTL_MECR,
MECR_NOS | MECR_CIT);
}
else {
sc->sc_cards &= ~(1<<sock_no);
/* if we loast all cards, turn off expansion memory
* control. */
#if 0
if (sc->sc_cards == 0)
bus_space_write_4(iot, memctl_ioh,
MEMCTL_MECR, MECR_NOS);
#endif
}
splx(s);
DPRINTF(("%s: card %d %s\n", sc->sc_pc.sc_dev.dv_xname, sock_no,
HAVE_CARD(val) ? "inserted" : "removed"));
sapcic_intr(arg);
return 1;
}
#endif /* DONT_USE_CARD_DETECT_INTR */
static int
opcic_read(struct sapcic_socket *__so, int which)
{
struct opcic_socket *so = (struct opcic_socket *)__so;
uint8_t reg;
reg = opcic_read_card_status(so);
switch (which) {
case SAPCIC_STATUS_CARD:
return HAVE_CARD(reg) ?
SAPCIC_CARD_VALID : SAPCIC_CARD_INVALID;
case SAPCIC_STATUS_VS1:
return (reg & CARDDET_NVS1) == 0;
case SAPCIC_STATUS_VS2:
return (reg & CARDDET_NVS2) == 0;
case SAPCIC_STATUS_READY:
return 1;
default:
panic("%s: bogus register", __FUNCTION__);
}
}
static void
opcic_write(struct sapcic_socket *__so, int which, int arg)
{
struct opcic_socket *so = (struct opcic_socket *)__so;
struct opcic_softc *sc = (struct opcic_softc *)so->ss.sc;
struct opio_softc *psc =
(struct opio_softc *)sc->sc_pc.sc_dev.dv_parent;
struct obio_softc *bsc =
(struct obio_softc *)psc->sc_dev.dv_parent;
switch (which) {
case SAPCIC_CONTROL_RESET:
obio_peripheral_reset(bsc, so->ss.socket, arg);
delay(500*1000);
break;
case SAPCIC_CONTROL_LINEENABLE:
break;
case SAPCIC_CONTROL_WAITENABLE:
break;
case SAPCIC_CONTROL_POWERSELECT:
#if 0
so->voltage = arg;
#endif
break;
default:
panic("%s: bogus register", __FUNCTION__);
}
}
static void
opcic_set_power(struct sapcic_socket *__so, int arg)
{
struct opcic_socket *so = (struct opcic_socket *)__so;
struct opcic_softc *sc = (struct opcic_softc *)so->ss.sc;
struct opio_softc *psc =
(struct opio_softc *)sc->sc_pc.sc_dev.dv_parent;
int shift, save;
volatile uint8_t *p;
if( arg < 0 || SAPCIC_POWER_5V < arg )
panic("sacpcic_set_power: bogus arg\n");
DPRINTF(("card %d: DET=%x\n",
so->ss.socket,
bus_space_read_1(psc->sc_iot, psc->sc_ioh,
GB225_CFDET + 2*so->ss.socket)));
p = (volatile uint8_t *)bus_space_vaddr(psc->sc_iot, psc->sc_ioh)
+ GB225_CARDPOW;
shift = 4 * !so->ss.socket;
save = disable_interrupts(I32_bit);
*p = (*p & ~(0x0f << shift)) | ((CARDPOW_VPPVCC | (arg<<2)) << shift);
restore_interrupts(save);
DPRINTF(("card %d power: %x\n", so->ss.socket, *p));
}
static void
opcic_clear_intr(int arg)
{
}
static void *
opcic_intr_establish(struct sapcic_socket *so, int level,
int (* ih_fun)(void *), void *ih_arg)
{
struct opcic_softc *sc = (struct opcic_softc *)so->sc;
struct opio_softc *psc =
(struct opio_softc *)sc->sc_pc.sc_dev.dv_parent;
struct obio_softc *bsc =
(struct obio_softc *)psc->sc_dev.dv_parent;
int irq;
DPRINTF(("opcic_intr_establish %d\n", so->socket));
irq = so->socket ? PCMCIA_INT : CF_INT;
return obio_intr_establish(bsc, irq, level, IST_EDGE_FALLING,
ih_fun, ih_arg);
}
static void
opcic_intr_disestablish(struct sapcic_socket *so, void *ih)
{
struct opcic_softc *sc = (struct opcic_softc *)so->sc;
struct opio_softc *psc =
(struct opio_softc *)sc->sc_pc.sc_dev.dv_parent;
struct obio_softc *bsc =
(struct obio_softc *)psc->sc_dev.dv_parent;
int (* func)(void *) = ((struct obio_handler *)ih)->func;
int irq = so->socket ? PCMCIA_INT : CF_INT;
obio_intr_disestablish(bsc, irq, func);
}

View File

@ -0,0 +1,213 @@
/* $NetBSD: gb225_slhci.c,v 1.1 2005/02/26 10:49:53 bsh Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Tetsuya Isaki.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* SL811HS USB host controller for GB-225 Option board of G4250EBX.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
#include <dev/ic/sl811hsreg.h>
#include <dev/ic/sl811hsvar.h>
#include <arch/arm/xscale/pxa2x0reg.h>
#include <arch/arm/xscale/pxa2x0var.h>
#include <arch/evbarm/g42xxeb/g42xxeb_reg.h>
#include <arch/evbarm/g42xxeb/g42xxeb_var.h>
#include <arch/evbarm/g42xxeb/gb225reg.h>
#include <arch/evbarm/g42xxeb/gb225var.h>
struct slhci_opio_softc {
struct slhci_softc sc_sc;
void *sc_ih;
};
static int slhci_opio_match(struct device *, struct cfdata *, void *);
static void slhci_opio_attach(struct device *, struct device *, void *);
static void slhci_opio_enable_power(void *, int);
static void slhci_opio_enable_intr(void *, int);
static int slhci_opio_intr(void *);
CFATTACH_DECL(slhci_opio, sizeof(struct slhci_opio_softc),
slhci_opio_match, slhci_opio_attach, NULL, NULL);
#define PORTSIZE (SL11_PORTSIZE*4)
static int
slhci_opio_match(struct device *parent, struct cfdata *cf, void *aux)
{
struct obio_attach_args *oba = aux;
bus_space_tag_t iot = &pxa2x0_a4x_bs_tag; /* Use special BS funcs */
bus_space_handle_t ioh;
struct obio_softc *bsc = (struct obio_softc *)parent->dv_parent;
struct pxa2x0_softc *psc;
int type;
uint32_t reg;
struct slhci_softc sc;
obio_peripheral_reset(bsc, 2, 0);
psc = (struct pxa2x0_softc *)bsc->sc_dev.dv_parent;
reg = bus_space_read_4(psc->saip.sc_iot, psc->sc_memctl_ioh,
MEMCTL_MSC2);
#if 0
bus_space_write_4(psc->saip.sc_iot, psc->sc_memctl_ioh, MEMCTL_MSC2,xxx)
#endif
oba->oba_iot = iot;
if (oba->oba_addr == OBIOCF_ADDR_DEFAULT)
oba->oba_addr = PXA2X0_CS5_START;
if (oba->oba_intr == OBIOCF_INTR_DEFAULT)
oba->oba_intr = G4250EBX_INT_EXT2;
if (bus_space_map(iot, oba->oba_addr, PORTSIZE, 0, &ioh))
return 0;
/* construct fake softc to call sl811hs */
sc.sc_iot = iot;
sc.sc_ioh = ioh;
type = sl811hs_find(&sc);
bus_space_unmap(iot, ioh, PORTSIZE);
return type >= 0;
}
static void
slhci_opio_attach(struct device *parent, struct device *self, void *aux)
{
struct slhci_opio_softc *sc = (struct slhci_opio_softc *)self;
struct obio_attach_args *oba = aux;
struct opio_softc *psc = (struct opio_softc *)self->dv_parent;
struct obio_softc *bsc = (struct obio_softc *)psc->sc_dev.dv_parent;
bus_space_tag_t iot = oba->oba_iot;
bus_space_handle_t ioh;
printf("\n");
/* Map I/O space */
if (bus_space_map(iot, oba->oba_addr, PORTSIZE, 0, &ioh)) {
printf("%s: can't map I/O space\n",
sc->sc_sc.sc_bus.bdev.dv_xname);
return;
}
/* Initialize sc */
sc->sc_sc.sc_iot = iot;
sc->sc_sc.sc_ioh = ioh;
sc->sc_sc.sc_dmat = &pxa2x0_bus_dma_tag; /* XXX */
sc->sc_sc.sc_enable_power = slhci_opio_enable_power;
sc->sc_sc.sc_enable_intr = slhci_opio_enable_intr;
sc->sc_sc.sc_arg = sc;
/* Establish the interrupt handler */
sc->sc_ih = obio_intr_establish(bsc, oba->oba_intr, IPL_BIO,
IST_LEVEL_HIGH, slhci_opio_intr, sc);
if( sc->sc_ih == NULL) {
printf("%s: can't establish interrupt\n",
sc->sc_sc.sc_bus.bdev.dv_xname);
return;
}
#if 0
/* Reset controller */
obio_peripheral_reset(bsc, 2, 1);
delay(100);
obio_peripheral_reset(bsc, 2, 0);
delay(40000);
#endif
bus_space_write_1(iot, ioh, SL11_IDX_ADDR, SL11_CTRL);
bus_space_write_1(iot, ioh, SL11_IDX_DATA, 0x01);
/* Attach SL811HS/T */
if (slhci_attach(&sc->sc_sc, self))
return;
}
static void
slhci_opio_enable_power(void *arg, int mode)
{
#if 0
struct slhci_opio_softc *sc = arg;
bus_space_tag_t iot = sc->sc_sc.sc_iot;
u_int8_t r;
r = bus_space_read_1(iot, sc->sc_nch, NEREID_CTRL);
if (mode == POWER_ON)
bus_space_write_1(iot, sc->sc_nch, NEREID_CTRL,
r | NEREID_CTRL_POWER);
else
bus_space_write_1(iot, sc->sc_nch, NEREID_CTRL,
r & ~NEREID_CTRL_POWER);
#endif
}
static void
slhci_opio_enable_intr(void *arg, int mode)
{
struct slhci_opio_softc *sc = arg;
struct obio_softc *bsc;
bsc = (struct obio_softc *)sc->sc_sc.sc_bus.bdev.dv_parent->dv_parent;
if (mode == INTR_ON)
obio_intr_unmask(bsc, sc->sc_ih);
else
obio_intr_mask(bsc, sc->sc_ih);
}
static int
slhci_opio_intr(void *arg)
{
struct slhci_opio_softc *sc = arg;
return slhci_intr(&sc->sc_sc);
}

View File

@ -0,0 +1,75 @@
/* $NetBSD: gb225reg.h,v 1.1 2005/02/26 10:49:53 bsh Exp $ */
/*
* Copyright (c) 2002 Genetec corp. All rights reserved.
* Written by Hiroyuki Bessho for Genetec corp.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Genetec corp. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORP.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _EVBARM_GB225_REG_H
#define _EVBARM_GB225_REG_H
#include <arm/xscale/pxa2x0reg.h>
#define GB225_PLDREG_BASE PXA2X0_CS4_START
#define GB225_PLDREG_SIZE 0x0a
#define GB225_CFDET 0 /* CompactFlash slot card detect */
#define GB225_PCMCIADET 2 /* PCMCIA slot card detect */
#define CARDDET_DET 0x03
#define CARDDET_BVD1 (1<<2)
#define CARDDET_BVD2 (1<<3)
#define CARDDET_NVS1 (1<<4)
#define CARDDET_NVS2 (1<<5)
#define CARDDET_NOCARD 0x3f
#define GB225_CARDPOW 4 /* card power supply control */
#define CARDPOW_PCMCIA_SHIFT 0
#define CARDPOW_CF_SHIFT 4
#define CARDPOW_VPP0 0x00
#define CARDPOW_VPP12 0x01
#define CARDPOW_VPPVCC 0x02
#define CARDPOW_VPPHIZ 0x03
#define CARDPOW_VCC0 0x00
#define CARDPOW_VCC33 0x04 /* 3.3V */
#define CARDPOW_VCC5 0x08
#define CARDPOW_MASK 0x0f
#define CARDPOW_VPPMASK 0x03
#define CARDPOW_VCCMASK 0x0c
#define GB225_IRDA_CONT 6 /* IrDA control */
#define IRDACONT_SIRFULL 0
#define IRDACONT_SHUTDOWN 1
#define IRDACONT_SIR2 2 /* 2/3 */
#define IRDACONT_SIR1 3 /* 1/3 */
#define IRDACONT_FIRFULL 4
#define IRDACONT_FIR2 6 /* 2/3 */
#define IRDACONT_FIR1 7 /* 1/3 */
#define GB225_DEVERROR 8
#define DEVERROR_CARD (1<<0) /* CF/PCMCIA power failure */
#define DEVERROR_USB (1<<1) /* USB power failure */
#endif /* _EVBARM_GB225_REG_H */

View File

@ -0,0 +1,79 @@
/* $NetBSD: gb225var.h,v 1.1 2005/02/26 10:49:53 bsh Exp $ */
/*
* Copyright (c) 2002, 2003 Genetec corp. All rights reserved.
* Written by Hiroyuki Bessho for Genetec corp.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Genetec corp. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORP.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _EVBARM_GB225VAR_H
#define _EVBARM_GB225VAR_H
#include <sys/queue.h>
#include <sys/callout.h>
/*
* Interrupt sources for option baord CPLD.
*/
#define OPIO_INTR_CF_INSERT 0
#define OPIO_INTR_PCMCIA_INSERT 1
#define OPIO_INTR_USB_POWER 2 /* USB power fault */
#define OPIO_INTR_CARD_POWER 3 /* PCMCIA/CF power fault */
#define N_OPIO_INTR 4
struct opio_intr_handler;
struct opio_softc {
struct device sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
bus_space_handle_t sc_memctl_ioh; /* PXA2x0's memory controller */
void *sc_ih; /* interrupt handler */
/* callout for debounce */
struct callout sc_callout;
enum {ST_STABLE, ST_BOUNCING } sc_debounce;
struct opio_intr_handler {
int (* func)(void *, int);
void *arg;
int level;
uint8_t reported_state;
uint8_t last_state;
short debounce_count;
} sc_intr[N_OPIO_INTR];
};
void *opio_intr_establish(struct opio_softc *, int, int,
int (*)(void *, int), void *);
#endif /* _EVBARM_GB225VAR_H */

View File

@ -0,0 +1,261 @@
/* $NetBSD: if_ne_obio.c,v 1.1 2005/02/26 10:49:53 bsh Exp $ */
/*
* Copyright (c) 2002, 2003 Genetec corp. All rights reserved.
* Written by Hiroyuki Bessho for Genetec corp.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Genetec corp. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORP.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_ne_obio.c,v 1.1 2005/02/26 10:49:53 bsh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <sys/select.h>
#include <sys/device.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_ether.h>
#include <net/if_media.h>
#include <machine/intr.h>
#include <machine/bus.h>
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
#include <dev/ic/dp8390reg.h>
#include <dev/ic/dp8390var.h>
#include <dev/ic/ne2000reg.h>
#include <dev/ic/ne2000var.h>
#include <evbarm/g42xxeb/g42xxeb_var.h>
#include <arm/xscale/pxa2x0var.h>
struct ne_obio_softc {
struct ne2000_softc nsc;
void *sc_ih; /* interrupt handler */
int intr_no;
};
int ne_obio_match( struct device *, struct cfdata *, void * );
void ne_obio_attach( struct device *, struct device *, void * );
CFATTACH_DECL(ne_obio, sizeof (struct ne_obio_softc), ne_obio_match, ne_obio_attach,
NULL, NULL);
//#define DEBUG_GPIO 2
//#define DEBUG_GPIO2 5
#if 1
#define intr_handler dp8390_intr
#else
#define intr_handler ne_obio_intr
static int
ne_obio_intr(void *arg)
{
int rv=1;
#ifdef DEBUG_GPIO
//printf( "ne_obio_intr arg=%p\n", arg );
bus_space_write_4( pxa2x0_softc->saip.sc_iot,
pxa2x0_softc->saip.sc_gpioh,
GPIO_GPSR0, 1U<<DEBUG_GPIO );
#endif
#if 0
while( (rv = dp8390_intr(arg)) != 0)
/*continue*/;
#else
rv = dp8390_intr(arg);
#endif
#ifdef DEBUG_GPIO
bus_space_write_4( pxa2x0_softc->saip.sc_iot,
pxa2x0_softc->saip.sc_gpioh,
GPIO_GPCR0, 1U<<DEBUG_GPIO );
#endif
return rv;
}
#endif
static int
ne_obio_enable(struct dp8390_softc *dsc)
{
struct ne_obio_softc *sc = (struct ne_obio_softc *)dsc;
struct obio_softc *psc;
printf("%s: enabled\n", dsc->sc_dev.dv_xname);
psc = (struct obio_softc *)dsc->sc_dev.dv_parent;
/* Establish the interrupt handler. */
sc->sc_ih = obio_intr_establish(psc, sc->intr_no, IPL_NET,
IST_LEVEL_LOW,
intr_handler,
sc);
return 0;
}
int
ne_obio_match( struct device *parent, struct cfdata *match, void *aux )
{
/* XXX: probe? */
return 1;
}
void
ne_obio_attach( struct device *parent, struct device *self, void *aux )
{
struct ne_obio_softc *sc = (struct ne_obio_softc *)self;
struct obio_attach_args *oba = aux;
bus_space_tag_t iot = oba->oba_iot;
bus_space_handle_t nioh, aioh;
uint8_t my_ea[ETHER_ADDR_LEN];
int i;
printf("\n");
/* Map i/o space. */
if (bus_space_map(iot, oba->oba_addr, NE2000_NPORTS, 0, &nioh))
return;
if (bus_space_subregion(iot, nioh, NE2000_ASIC_OFFSET,
NE2000_ASIC_NPORTS, &aioh))
goto out2;
sc->nsc.sc_dp8390.sc_regt = iot;
sc->nsc.sc_dp8390.sc_regh = nioh;
sc->nsc.sc_asict = iot;
sc->nsc.sc_asich = aioh;
/*
* XXX:
* AX88796's reset register doesn't seem to work, and
* ne2000_detect() fails. We hardcord NIC type here.
*/
sc->nsc.sc_type = NE2000_TYPE_NE2000; /* XXX _AX88796 ? */
sc->nsc.sc_dp8390.sc_flags = DP8390_NO_REMOTE_DMA_COMPLETE;
/* DP8390_NO_MULTI_BUFFERING; XXX */
/* G4250EBX doesn't have EEPROM hooked to AX88796. Read MAC
* address set by Redboot and don't let ne2000_atthch() try to
* read MAC from hardware. (current ne2000 driver doesn't
* support AX88796's EEPROM interface)
*/
bus_space_write_1( iot, nioh, ED_P0_CR, ED_CR_RD2|ED_CR_PAGE_1 );
for( i=0; i < ETHER_ADDR_LEN; ++i )
my_ea[i] = bus_space_read_1( iot, nioh, ED_P1_PAR0+i );
bus_space_write_1( iot, nioh, ED_P0_CR, ED_CR_RD2|ED_CR_PAGE_0 );
/* disable all interrupts */
bus_space_write_1(iot, nioh, ED_P0_IMR, 0);
#ifdef DEBUG_GPIO
bus_space_write_4( pxa2x0_softc->saip.sc_iot,
pxa2x0_softc->saip.sc_gpioh,
GPIO_GPDR0, (0x01<<DEBUG_GPIO) | (0x01<<DEBUG_GPIO2) |
bus_space_read_4(pxa2x0_softc->saip.sc_iot, pxa2x0_softc->saip.sc_gpioh,
GPIO_GPDR0));
#endif
/* delay intr_establish until this IF is enabled
to avoid spurious interrupts. */
sc->nsc.sc_dp8390.sc_enabled = 0;
sc->nsc.sc_dp8390.sc_enable = ne_obio_enable;
sc->intr_no = oba->oba_intr;
if( ne2000_attach( &sc->nsc, my_ea ) )
goto out;
#ifndef ED_DCR_RDCR
#define ED_DCR_RDCR 0
#endif
bus_space_write_1(iot, nioh, ED_P0_DCR, ED_DCR_RDCR|ED_DCR_WTS);
return;
out:
bus_space_unmap( iot, aioh, NE2000_ASIC_NPORTS );
out2:
bus_space_unmap( iot, nioh, NE2000_NPORTS );
return;
}
#if 0
void debug_obio_ne(struct dp8390_softc *);
void
debug_obio_ne(struct dp8390_softc *sc)
{
struct obio_softc *osc = (struct obio_softc *)(sc->sc_dev.dv_parent);
struct pxa2x0_softc *psc = (struct pxa2x0_softc *)(osc->sc_dev.dv_parent);
printf( "ISR=%02x obio: pending=(%x,%x) mask=%x pending=%x mask=%x\n",
bus_space_read_1(sc->sc_regt, sc->sc_regh,
ED_P0_ISR ),
bus_space_read_2(osc->sc_iot, osc->sc_obioreg_ioh, G4250EBX_INTSTS1),
bus_space_read_2(osc->sc_iot, osc->sc_obioreg_ioh, G4250EBX_INTSTS2),
bus_space_read_2(osc->sc_iot, osc->sc_obioreg_ioh, G4250EBX_INTMASK),
osc->sc_intr_pending,
osc->sc_intr_mask );
printf( "intc: mask=%08x pending=%08x\n",
bus_space_read_4(psc->saip.sc_iot, psc->saip.sc_ioh, SAIPIC_MR ),
bus_space_read_4(psc->saip.sc_iot, psc->saip.sc_ioh, SAIPIC_IP ) );
}
#endif
#ifdef DEBUG_GPIO2
void dp8390_debug_overrun(void);
void dp8390_debug_overrun(void)
{
static int toggle=0;
//printf( "ne_obio_intr arg=%p\n", arg );
bus_space_write_4( pxa2x0_softc->saip.sc_iot,
pxa2x0_softc->saip.sc_gpioh,
toggle ? GPIO_GPCR0 : GPIO_GPSR0,
1U<<DEBUG_GPIO2 );
toggle ^= 1;
}
#endif

View File

@ -0,0 +1,421 @@
/* $NetBSD: obio.c,v 1.1 2005/02/26 10:49:53 bsh Exp $ */
/*
* Copyright (c) 2002, 2003, 2005 Genetec corp. All rights reserved.
* Written by Hiroyuki Bessho for Genetec corp.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Genetec corp. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORP.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/reboot.h>
#include <machine/cpu.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <arm/cpufunc.h>
#include <arm/mainbus/mainbus.h>
#include <arm/xscale/pxa2x0reg.h>
#include <arm/xscale/pxa2x0var.h>
#include <arm/xscale/pxa2x0_gpio.h>
#include <arm/sa11x0/sa11x0_var.h>
#include <evbarm/g42xxeb/g42xxeb_reg.h>
#include <evbarm/g42xxeb/g42xxeb_var.h>
#include "locators.h"
/* prototypes */
static int obio_match(struct device *, struct cfdata *, void *);
static void obio_attach(struct device *, struct device *, void *);
static int obio_search(struct device *, struct cfdata *, void *);
static int obio_print(void *, const char *);
/* attach structures */
CFATTACH_DECL(obio, sizeof(struct obio_softc), obio_match, obio_attach,
NULL, NULL);
static int
obio_spurious(void *arg)
{
int irqno = (int)arg;
printf("Spurious interrupt %d on On-board peripheral", irqno);
return 1;
}
/*
* interrupt handler for GPIO0 (on-board peripherals)
*
* On G4250ebx, 10 interrupts are ORed through on-board logic,
* and routed to GPIO0 of PXA250 processor.
*/
static int
obio_intr(void *arg)
{
int irqno, pending;
struct obio_softc *sc = (struct obio_softc *)arg;
int n=0;
#define get_pending(sc) \
(bus_space_read_2( sc->sc_iot, sc->sc_obioreg_ioh, G42XXEB_INTSTS1) \
& ~(sc->sc_intr_pending|sc->sc_intr_mask))
#ifdef DEBUG
printf("obio_intr: pend=%x, mask=%x, pend=%x, mask=%x\n",
bus_space_read_2(sc->sc_iot, sc->sc_obioreg_ioh, G42XXEB_INTSTS1),
bus_space_read_2(sc->sc_iot, sc->sc_obioreg_ioh, G42XXEB_INTMASK),
sc->sc_intr_pending,
sc->sc_intr_mask);
#endif
for (pending = get_pending(sc);
(irqno = find_first_bit(pending)) >= 0;
pending = get_pending(sc)) {
/* reset pending bit */
bus_space_write_2(sc->sc_iot, sc->sc_obioreg_ioh,
G42XXEB_INTSTS1, ~(1<<irqno));
#if 0
if (sc->sc_handler[irqno].level > saved_spl_level) {
int spl_save = _splraise(sc->sc_handler[irqno].level);
(* sc->sc_handler[irqno].func)(
sc->sc_handler[irqno].arg);
splx(spl_save);
}
else
#endif
{
int psw = disable_interrupts(I32_bit); /* XXX */
/* mask this interrupt until software
interrupt is handled. */
sc->sc_intr_pending |= (1U<<irqno);
obio_update_intrmask(sc);
restore_interrupts(psw);
++n;
}
#ifdef DIAGNOSTIC
if (n > 1000)
panic("obio_intr: stayed too long");
#endif
}
if (n > 0) {
/* handle it later */
softintr_schedule(sc->sc_si);
}
/* GPIO interrupt is edge triggered. make a pulse
to let Cotulla notice when other interrupts are
still pending */
bus_space_write_2(sc->sc_iot, sc->sc_obioreg_ioh,
G42XXEB_INTMASK, 0xffff);
obio_update_intrmask(sc);
return 1;
}
static void
obio_softintr(void *arg)
{
struct obio_softc *sc = (struct obio_softc *)arg;
int irqno;
int spl_save = current_spl_level;
int psw;
psw = disable_interrupts(I32_bit);
while ((irqno = find_first_bit(sc->sc_intr_pending)) >= 0) {
sc->sc_intr_pending &= ~(1U<<irqno);
restore_interrupts(psw);
_splraise(sc->sc_handler[irqno].level);
(* sc->sc_handler[irqno].func)(
sc->sc_handler[irqno].arg);
splx(spl_save);
psw = disable_interrupts(I32_bit);
}
/* assert(sc->sc_intr_pending==0) */
bus_space_write_2(sc->sc_iot, sc->sc_obioreg_ioh,
G42XXEB_INTMASK, 0xffff);
obio_update_intrmask(sc);
restore_interrupts(psw);
}
/*
* int obio_print(void *aux, const char *name)
* print configuration info for children
*/
static int
obio_print(void *aux, const char *name)
{
struct obio_attach_args *oba = (struct obio_attach_args*)aux;
if (oba->oba_addr != OBIOCF_ADDR_DEFAULT)
printf(" addr 0x%lx", oba->oba_addr);
if (oba->oba_intr > 0)
printf(" intr %d", oba->oba_intr);
return (UNCONF);
}
int
obio_match(struct device *parent, struct cfdata *match, void *aux)
{
return 1;
}
void
obio_attach(struct device *parent, struct device *self, void *aux)
{
struct obio_softc *sc = (struct obio_softc*)self;
struct sa11x0_attach_args *sa = (struct sa11x0_attach_args *)aux;
bus_space_tag_t iot = sa->sa_iot;
int i;
uint16_t reg;
/* tweak memory access timing for CS3.
the value set by redboot is too slow */
if (bus_space_map(iot, PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 0,
&sc->sc_memctl_ioh))
goto fail;
bus_space_write_4(iot, sc->sc_memctl_ioh, MEMCTL_MSC1,
(0xffff & bus_space_read_4(iot, sc->sc_memctl_ioh, MEMCTL_MSC1))
| (0x6888 << 16));
/* Map on-board FPGA registers */
sc->sc_iot = iot;
if (bus_space_map(iot, G42XXEB_PLDREG_BASE, G42XXEB_PLDREG_SIZE,
0, &(sc->sc_obioreg_ioh)))
goto fail;
/*
* Mask all interrupts.
* They are later unmasked at each device's attach routine.
*/
sc->sc_intr_mask = 0xffff;
bus_space_write_2(iot, sc->sc_obioreg_ioh, G42XXEB_INTMASK,
sc->sc_intr_mask );
#if 0
sc->sc_intr = 8; /* GPIO0 */
#endif
sc->sc_intr_pending = 0;
for (i=0; i < G42XXEB_N_INTS; ++i) {
sc->sc_handler[i].func = obio_spurious;
sc->sc_handler[i].arg = (void *)i;
}
obio_peripheral_reset(sc, 1, 0);
/*
* establish interrupt handler.
* level is very high to allow high priority sub-interrupts.
*/
sc->sc_ipl = IPL_AUDIO;
sc->sc_ih = pxa2x0_gpio_intr_establish(0, IST_EDGE_FALLING, sc->sc_ipl,
obio_intr, sc);
sc->sc_si = softintr_establish(IPL_SOFTNET, obio_softintr, sc);
reg = bus_space_read_2(iot, sc->sc_obioreg_ioh, G42XXEB_PLDVER);
aprint_normal(": board %d version %x\n", reg>>8, reg & 0xff);
/*
* Attach each devices
*/
config_search(obio_search, self, NULL);
return;
fail:
printf( "%s: can't map FPGA registers\n", self->dv_xname );
}
int
obio_search(struct device *parent, struct cfdata *cf, void *aux)
{
struct obio_softc *sc = (struct obio_softc *)parent;
struct obio_attach_args oba;
oba.oba_sc = sc;
oba.oba_iot = sc->sc_iot;
oba.oba_addr = cf->cf_loc[OBIOCF_ADDR];
oba.oba_intr = cf->cf_loc[OBIOCF_INTR];
if (config_match(parent, cf, &oba) > 0)
config_attach(parent, cf, &oba, obio_print);
return 0;
}
void *
obio_intr_establish(struct obio_softc *sc, int irq, int ipl,
int type, int (*func)(void *), void *arg)
{
int save;
int regidx, sft;
uint16_t reg;
static const uint8_t ist_code[] = {
0,
G42XXEB_INT_EDGE_FALLING, /* pulse */
G42XXEB_INT_EDGE_FALLING, /* IST_EDGE */
G42XXEB_INT_LEVEL_LOW, /* IST_LEVEL */
G42XXEB_INT_LEVEL_HIGH, /* IST_LEVEL_HIGH */
G42XXEB_INT_EDGE_RISING, /* IST_EDGE_RISING */
G42XXEB_INT_EDGE_BOTH, /* IST_EDGE_BOTH */
};
if (irq < 0 || G42XXEB_N_INTS <= irq)
panic("Bad irq no. for obio (%d)", irq);
if (type < 0 || IST_EDGE_BOTH < type)
panic("Bad interrupt type for obio (%d)", type);
regidx = G42XXEB_INTCNTL;
sft = 3 * irq;
if (irq >= 5) {
regidx = G42XXEB_INTCNTH;
sft -= 3*5;
}
save = disable_interrupts(I32_bit);
sc->sc_handler[irq].func = func;
sc->sc_handler[irq].arg = arg;
sc->sc_handler[irq].level = ipl;
/* set interrupt type */
reg = bus_space_read_2(sc->sc_iot, sc->sc_obioreg_ioh, regidx);
bus_space_write_2(sc->sc_iot, sc->sc_obioreg_ioh, regidx,
(reg & ~(7<<sft)) | (ist_code[type] << sft));
#ifdef DEBUG
printf("INTCTL=%x,%x\n",
bus_space_read_2(sc->sc_iot, sc->sc_obioreg_ioh, G42XXEB_INTCNTL),
bus_space_read_2(sc->sc_iot, sc->sc_obioreg_ioh, G42XXEB_INTCNTH));
#endif
sc->sc_intr_mask &= ~(1U << irq);
obio_update_intrmask(sc);
restore_interrupts(save);
#if 0
if (ipl > sc->sc_ipl) {
pxa2x0_update_intr_masks(sc->sc_intr, ipl);
sc->sc_ipl = ipl;
}
#endif
return &sc->sc_handler[irq];
}
void
obio_intr_disestablish(struct obio_softc *sc, int irq, int (* func)(void *))
{
int error = 0;
int save;
save = disable_interrupts(I32_bit);
if (sc->sc_handler[irq].func != func)
error = 1;
else {
sc->sc_handler[irq].func = obio_spurious;
sc->sc_handler[irq].level = IPL_NONE;
sc->sc_intr_pending &= ~(1U << irq);
sc->sc_intr_mask |= (1U << irq);
obio_update_intrmask(sc);
}
restore_interrupts(save);
if (error)
aprint_error("%s: bad intr_disestablish\n",
sc->sc_dev.dv_xname);
}
void
obio_intr_mask(struct obio_softc *sc, struct obio_handler *ih)
{
int irqno;
int save;
irqno = ih - sc->sc_handler;
#ifdef DIAGNOSTIC
if (ih == NULL || ih->func==NULL || irqno < 0 ||
irqno >= G42XXEB_N_INTS)
panic("Bad arg for obio_intr_mask");
#endif
save = disable_interrupts(I32_bit);
sc->sc_intr_mask |= 1U<<irqno;
obio_update_intrmask(sc);
restore_interrupts(save);
}
void
obio_intr_unmask(struct obio_softc *sc, struct obio_handler *ih)
{
int irqno;
int save;
irqno = ih - sc->sc_handler;
#ifdef DIAGNOSTIC
if (ih == NULL || ih->func==NULL || irqno < 0 ||
irqno >= G42XXEB_N_INTS)
panic("Bad arg for obio_intr_unmask");
#endif
save = disable_interrupts(I32_bit);
sc->sc_intr_mask &= ~(1U<<irqno);
obio_update_intrmask(sc);
restore_interrupts(save);
}
void
obio_peripheral_reset(struct obio_softc *bsc, int no, int onoff)
{
uint16_t reg;
reg = bus_space_read_2(bsc->sc_iot, bsc->sc_obioreg_ioh,
G42XXEB_RST);
bus_space_write_2(bsc->sc_iot, bsc->sc_obioreg_ioh, G42XXEB_RST,
onoff ? (reg & ~RST_EXT(no)) : (reg | RST_EXT(no)));
}