Commit 311a5ffe authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] CRIS architecture update

From: "Mikael Starvik" <mikael.starvik@axis.com>

- Lots of fixes from 2.4.

- Updated for 2.6.6.

- Added IDE driver
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 772213c8
...@@ -27,19 +27,11 @@ menu "General setup" ...@@ -27,19 +27,11 @@ menu "General setup"
source "fs/Kconfig.binfmt" source "fs/Kconfig.binfmt"
config ETRAX_KGDB config ETRAX_CMDLINE
bool "Use kernel gdb debugger" string "Kernel command line"
---help--- default "root=/dev/mtdblock3"
The CRIS version of gdb can be used to remotely debug a running help
Linux kernel via the serial debug port. Provided you have gdb-cris Pass additional commands to the kernel.
installed, run gdb-cris vmlinux, then type
(gdb) set remotebaud 115200 <- kgdb uses 115200 as default
(gdb) target remote /dev/ttyS0 <- maybe you use another port
This should connect you to your booted kernel (or boot it now if you
didn't before). The kernel halts when it boots, waiting for gdb if
this option is turned on!
config ETRAX_WATCHDOG config ETRAX_WATCHDOG
bool "Enable ETRAX watchdog" bool "Enable ETRAX watchdog"
...@@ -99,11 +91,6 @@ config SVINTO_SIM ...@@ -99,11 +91,6 @@ config SVINTO_SIM
help help
Support the xsim ETRAX Simulator. Support the xsim ETRAX Simulator.
config ETRAX200LX
bool "ETRAX-200LX-V32"
help
Support CRIS V32.
endchoice endchoice
config ETRAX_ARCH_V10 config ETRAX_ARCH_V10
...@@ -111,11 +98,6 @@ config ETRAX_ARCH_V10 ...@@ -111,11 +98,6 @@ config ETRAX_ARCH_V10
default y if ETRAX100LX || ETRAX100LX_V2 default y if ETRAX100LX || ETRAX100LX_V2
default n if !(ETRAX100LX || ETRAX100LX_V2) default n if !(ETRAX100LX || ETRAX100LX_V2)
config ETRAX_ARCH_V32
bool
default y if ETRAX200LX
default n if !(ETRAX200LX)
config ETRAX_DRAM_SIZE config ETRAX_DRAM_SIZE
int "DRAM size (dec, in MB)" int "DRAM size (dec, in MB)"
default "8" default "8"
...@@ -128,35 +110,18 @@ config ETRAX_FLASH_BUSWIDTH ...@@ -128,35 +110,18 @@ config ETRAX_FLASH_BUSWIDTH
help help
Width in bytes of the Flash bus (1, 2 or 4). Is usually 2. Width in bytes of the Flash bus (1, 2 or 4). Is usually 2.
config ETRAX_ROOT_DEVICE
string "Root device name"
default "/dev/mtdblock3"
help
Specifies the device that should be mounted as root file system
when booting from flash. The axisflashmap driver adds an additional
mtd partition for the appended root file system image, so this option
should normally be the mtdblock device for the partition after the
last partition in the partition table.
# duplicate choice configs are not yet supported, so the followinguse
# doesn't work:
source arch/cris/arch-v10/Kconfig source arch/cris/arch-v10/Kconfig
endmenu endmenu
# bring in ETRAX built-in drivers # bring in ETRAX built-in drivers
menu "Drivers for built-in interfaces" menu "Drivers for built-in interfaces"
source arch/cris/arch-v10/drivers/Kconfig source arch/cris/arch-v10/drivers/Kconfig
endmenu endmenu
source "drivers/base/Kconfig" source "drivers/base/Kconfig"
# bring in Etrax built-in drivers
source "arch/cris/drivers/Kconfig"
# standard linux drivers # standard linux drivers
source "drivers/mtd/Kconfig" source "drivers/mtd/Kconfig"
...@@ -212,6 +177,37 @@ config PROFILE_SHIFT ...@@ -212,6 +177,37 @@ config PROFILE_SHIFT
depends on PROFILE depends on PROFILE
default "2" default "2"
config ETRAX_KGDB
bool "Use kernel GDB debugger"
---help---
The CRIS version of gdb can be used to remotely debug a running
Linux kernel via the serial debug port. Provided you have gdb-cris
installed, run gdb-cris vmlinux, then type
(gdb) set remotebaud 115200 <- kgdb uses 115200 as default
(gdb) target remote /dev/ttyS0 <- maybe you use another port
This should connect you to your booted kernel (or boot it now if you
didn't before). The kernel halts when it boots, waiting for gdb if
this option is turned on!
config DEBUG_INFO
bool "Compile the kernel with debug info"
help
If you say Y here the resulting kernel image will include
debugging info resulting in a larger kernel image.
Say Y here only if you plan to use gdb to debug the kernel.
If you don't debug the kernel, you can say N.
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
help
If you say Y here the resulting kernel image will be slightly larger
and slower, but it will give very useful debugging information.
If you don't debug the kernel, you can say N, but we may not be able
to solve problems without frame pointers.
endmenu endmenu
source "security/Kconfig" source "security/Kconfig"
......
# $Id: Makefile,v 1.15 2003/07/04 12:47:53 tobiasa Exp $ # $Id: Makefile,v 1.20 2004/05/14 14:35:58 orjanf Exp $
# cris/Makefile # cris/Makefile
# #
# This file is included by the global makefile so that you can add your own # This file is included by the global makefile so that you can add your own
...@@ -34,7 +34,7 @@ AFLAGS += -mlinux ...@@ -34,7 +34,7 @@ AFLAGS += -mlinux
CFLAGS := $(CFLAGS) -mlinux -march=$(arch-y) -pipe CFLAGS := $(CFLAGS) -mlinux -march=$(arch-y) -pipe
ifdef CONFIG_ETRAX_KGDB ifdef CONFIG_FRAME_POINTER
CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g
CFLAGS += -fno-omit-frame-pointer CFLAGS += -fno-omit-frame-pointer
endif endif
...@@ -90,10 +90,14 @@ prepare: arch/$(ARCH)/.links include/asm-$(ARCH)/.arch \ ...@@ -90,10 +90,14 @@ prepare: arch/$(ARCH)/.links include/asm-$(ARCH)/.arch \
# Create some links to make all tools happy # Create some links to make all tools happy
arch/$(ARCH)/.links: arch/$(ARCH)/.links:
@rm -rf arch/$(ARCH)/drivers
@ln -sfn $(SARCH)/drivers arch/$(ARCH)/drivers @ln -sfn $(SARCH)/drivers arch/$(ARCH)/drivers
@rm -rf arch/$(ARCH)/boot
@ln -sfn $(SARCH)/boot arch/$(ARCH)/boot @ln -sfn $(SARCH)/boot arch/$(ARCH)/boot
@rm -rf arch/$(ARCH)/lib
@ln -sfn $(SARCH)/lib arch/$(ARCH)/lib @ln -sfn $(SARCH)/lib arch/$(ARCH)/lib
@ln -sfn $(SARCH)/vmlinux.lds.S arch/$(ARCH)/kernel/vmlinux.lds.S @ln -sfn $(SARCH) arch/$(ARCH)/arch
@ln -sfn ../$(SARCH)/vmlinux.lds.S arch/$(ARCH)/kernel/vmlinux.lds.S
@touch $@ @touch $@
# Create link to sub arch includes # Create link to sub arch includes
......
/* /*
* misc.c * misc.c
* *
* $Id: misc.c,v 1.4 2003/04/09 05:20:45 starvik Exp $ * $Id: misc.c,v 1.6 2003/10/27 08:04:31 starvik Exp $
* *
* This is a collection of several routines from gzip-1.0.3 * This is a collection of several routines from gzip-1.0.3
* adapted for Linux. * adapted for Linux.
...@@ -263,7 +263,7 @@ decompress_kernel() ...@@ -263,7 +263,7 @@ decompress_kernel()
__asm__ volatile ("move vr,%0" : "=rm" (revision)); __asm__ volatile ("move vr,%0" : "=rm" (revision));
if (revision < 10) if (revision < 10)
{ {
puts("You need an ETRAX 100LX to run linux 2.4\n"); puts("You need an ETRAX 100LX to run linux 2.6\n");
while(1); while(1);
} }
......
...@@ -267,6 +267,7 @@ CONFIG_INET=y ...@@ -267,6 +267,7 @@ CONFIG_INET=y
# CONFIG_BLK_DEV_ISAPNP is not set # CONFIG_BLK_DEV_ISAPNP is not set
# CONFIG_IDE_CHIPSETS is not set # CONFIG_IDE_CHIPSETS is not set
# CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
# #
# SCSI support # SCSI support
......
...@@ -11,29 +11,6 @@ config NET_ETHERNET ...@@ -11,29 +11,6 @@ config NET_ETHERNET
bool bool
depends on ETRAX_ETHERNET depends on ETRAX_ETHERNET
default y default y
---help---
Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
type of Local Area Network (LAN) in universities and companies.
Common varieties of Ethernet are: 10BASE-2 or Thinnet (10 Mbps over
coaxial cable, linking computers in a chain), 10BASE-T or twisted
pair (10 Mbps over twisted pair cable, linking computers to central
hubs), 10BASE-F (10 Mbps over optical fiber links, using hubs),
100BASE-TX (100 Mbps over two twisted pair cables, using hubs),
100BASE-T4 (100 Mbps over 4 standard voice-grade twisted pair
cables, using hubs), 100BASE-FX (100 Mbps over optical fiber links)
[the 100BASE varieties are also known as Fast Ethernet], and Gigabit
Ethernet (1 Gbps over optical fiber or short copper links).
If your Linux machine will be connected to an Ethernet and you have
an Ethernet network interface card (NIC) installed in your computer,
say Y here and read the Ethernet-HOWTO, available from
<http://www.tldp.org/docs.html#howto>. You will then also have
to say Y to the driver for your particular NIC.
Note that the answer to this question won't directly affect the
kernel: saying N will just cause the configurator to skip all
the questions about Ethernet network cards. If unsure, say N.
choice choice
prompt "Network LED behavior" prompt "Network LED behavior"
...@@ -109,6 +86,32 @@ config ETRAX_SERIAL_PORT0 ...@@ -109,6 +86,32 @@ config ETRAX_SERIAL_PORT0
Normally you want this on, unless you use external DMA 1 that uses Normally you want this on, unless you use external DMA 1 that uses
the same DMA channels. the same DMA channels.
choice
prompt "Ser0 DMA out assignment"
depends on ETRAX_SERIAL_PORT0
default ETRAX_SERIAL_PORT0_DMA6_OUT
config CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT
bool "No DMA out"
config CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT
bool "DMA 6"
endchoice
choice
prompt "Ser0 DMA in assignment"
depends on ETRAX_SERIAL_PORT0
default ETRAX_SERIAL_PORT0_DMA7_IN
config CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN
bool "No DMA in"
config CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN
bool "DMA 7"
endchoice
choice choice
prompt "Ser0 DTR, RI, DSR and CD assignment" prompt "Ser0 DTR, RI, DSR and CD assignment"
depends on ETRAX_SERIAL_PORT0 depends on ETRAX_SERIAL_PORT0
...@@ -197,6 +200,32 @@ config ETRAX_SERIAL_PORT1 ...@@ -197,6 +200,32 @@ config ETRAX_SERIAL_PORT1
help help
Enables the ETRAX 100 serial driver for ser1 (ttyS1). Enables the ETRAX 100 serial driver for ser1 (ttyS1).
choice
prompt "Ser1 DMA out assignment"
depends on ETRAX_SERIAL_PORT1
default ETRAX_SERIAL_PORT1_DMA8_OUT
config CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_OUT
bool "No DMA out"
config CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT
bool "DMA 8"
endchoice
choice
prompt "Ser1 DMA in assignment"
depends on ETRAX_SERIAL_PORT1
default ETRAX_SERIAL_PORT1_DMA9_IN
config CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_IN
bool "No DMA in"
config CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN
bool "DMA 9"
endchoice
choice choice
prompt "Ser1 DTR, RI, DSR and CD assignment" prompt "Ser1 DTR, RI, DSR and CD assignment"
depends on ETRAX_SERIAL_PORT1 depends on ETRAX_SERIAL_PORT1
...@@ -288,6 +317,32 @@ config ETRAX_SERIAL_PORT2 ...@@ -288,6 +317,32 @@ config ETRAX_SERIAL_PORT2
help help
Enables the ETRAX 100 serial driver for ser2 (ttyS2). Enables the ETRAX 100 serial driver for ser2 (ttyS2).
choice
prompt "Ser2 DMA out assignment"
depends on ETRAX_SERIAL_PORT2
default ETRAX_SERIAL_PORT2_DMA2_OUT
config CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT
bool "No DMA out"
config CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT
bool "DMA 2"
endchoice
choice
prompt "Ser2 DMA in assignment"
depends on ETRAX_SERIAL_PORT2
default ETRAX_SERIAL_PORT2_DMA3_IN
config CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN
bool "No DMA in"
config CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN
bool "DMA 3"
endchoice
choice choice
prompt "Ser2 DTR, RI, DSR and CD assignment" prompt "Ser2 DTR, RI, DSR and CD assignment"
depends on ETRAX_SERIAL_PORT2 depends on ETRAX_SERIAL_PORT2
...@@ -376,6 +431,32 @@ config ETRAX_SERIAL_PORT3 ...@@ -376,6 +431,32 @@ config ETRAX_SERIAL_PORT3
help help
Enables the ETRAX 100 serial driver for ser3 (ttyS3). Enables the ETRAX 100 serial driver for ser3 (ttyS3).
choice
prompt "Ser3 DMA out assignment"
depends on ETRAX_SERIAL_PORT3
default ETRAX_SERIAL_PORT3_DMA4_OUT
config CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_OUT
bool "No DMA out"
config CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT
bool "DMA 4"
endchoice
choice
prompt "Ser3 DMA in assignment"
depends on ETRAX_SERIAL_PORT3
default ETRAX_SERIAL_PORT3_DMA5_IN
config CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_IN
bool "No DMA in"
config CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN
bool "DMA 5"
endchoice
choice choice
prompt "Ser3 DTR, RI, DSR and CD assignment" prompt "Ser3 DTR, RI, DSR and CD assignment"
depends on ETRAX_SERIAL_PORT3 depends on ETRAX_SERIAL_PORT3
...@@ -466,6 +547,95 @@ config ETRAX_RS485_DISABLE_RECEIVER ...@@ -466,6 +547,95 @@ config ETRAX_RS485_DISABLE_RECEIVER
loopback. Not all products are able to do this in software only. loopback. Not all products are able to do this in software only.
Axis 2400/2401 must disable receiver. Axis 2400/2401 must disable receiver.
config ETRAX_IDE
bool "ATA/IDE support"
help
Enable this to get support for ATA/IDE.
You can't use parallell ports or SCSI ports
at the same time.
# here we should add the CONFIG_'s necessary to enable the basic
# general ide drivers so the common case does not need to go
# into that config submenu. enable disk and CD support. others
# need to go fiddle in the submenu..
config IDE
tristate
depends on ETRAX_IDE
default y
config BLK_DEV_IDE
tristate
depends on ETRAX_IDE
default y
config BLK_DEV_IDEDISK
tristate
depends on ETRAX_IDE
default y
config BLK_DEV_IDECD
tristate
depends on ETRAX_IDE
default y
config BLK_DEV_IDEDMA
bool
depends on ETRAX_IDE
default y
config DMA_NONPCI
bool
depends on ETRAX_IDE
default y
config ETRAX_IDE_DELAY
int "Delay for drives to regain consciousness"
depends on ETRAX_IDE
default 15
help
Number of seconds to wait for IDE drives to spin up after an IDE
reset.
choice
prompt "IDE reset pin"
depends on ETRAX_IDE
default ETRAX_IDE_PB7_RESET
config ETRAX_IDE_PB7_RESET
bool "Port_PB_Bit_7"
help
IDE reset on pin 7 on port B
config ETRAX_IDE_G27_RESET
bool "Port_G_Bit_27"
help
IDE reset on pin 27 on port G
endchoice
config ETRAX_USB_HOST
bool "USB host"
help
This option enables the host functionality of the ETRAX 100LX
built-in USB controller. In host mode the controller is designed
for CTRL and BULK traffic only, INTR traffic may work as well
however (depending on the requirements of timeliness).
config USB
tristate
depends on ETRAX_USB_HOST
default y
config ETRAX_USB_HOST_PORT1
bool " USB port 1 enabled"
depends on ETRAX_USB_HOST
default n
config ETRAX_USB_HOST_PORT2
bool " USB port 2 enabled"
depends on ETRAX_USB_HOST
default n
config ETRAX_AXISFLASHMAP config ETRAX_AXISFLASHMAP
bool "Axis flash-map support" bool "Axis flash-map support"
depends on ETRAX_ARCH_V10 depends on ETRAX_ARCH_V10
......
...@@ -10,5 +10,7 @@ obj-$(CONFIG_ETRAX_I2C_EEPROM) += eeprom.o ...@@ -10,5 +10,7 @@ obj-$(CONFIG_ETRAX_I2C_EEPROM) += eeprom.o
obj-$(CONFIG_ETRAX_GPIO) += gpio.o obj-$(CONFIG_ETRAX_GPIO) += gpio.o
obj-$(CONFIG_ETRAX_DS1302) += ds1302.o obj-$(CONFIG_ETRAX_DS1302) += ds1302.o
obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o
obj-$(CONFIG_ETRAX_IDE) += ide.o
obj-$(CONFIG_ETRAX_USB_HOST) += usb-host.o
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
* partition split defined below. * partition split defined below.
* *
* $Log: axisflashmap.c,v $ * $Log: axisflashmap.c,v $
* Revision 1.8 2004/05/14 07:58:03 starvik
* Merge of changes from 2.4
*
* Revision 1.6 2003/07/04 08:27:37 starvik * Revision 1.6 2003/07/04 08:27:37 starvik
* Merge of Linux 2.5.74 * Merge of Linux 2.5.74
* *
...@@ -153,6 +156,9 @@ ...@@ -153,6 +156,9 @@
/* From head.S */ /* From head.S */
extern unsigned long romfs_start, romfs_length, romfs_in_flash; extern unsigned long romfs_start, romfs_length, romfs_in_flash;
/* The master mtd for the entire flash. */
struct mtd_info* axisflash_mtd = NULL;
/* Map driver functions. */ /* Map driver functions. */
static __u8 flash_read8(struct map_info *map, unsigned long ofs) static __u8 flash_read8(struct map_info *map, unsigned long ofs)
...@@ -314,7 +320,8 @@ static struct mtd_info *probe_cs(struct map_info *map_cs) ...@@ -314,7 +320,8 @@ static struct mtd_info *probe_cs(struct map_info *map_cs)
{ {
struct mtd_info *mtd_cs = NULL; struct mtd_info *mtd_cs = NULL;
printk("%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n", printk(KERN_INFO
"%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
map_cs->name, map_cs->size, map_cs->map_priv_1); map_cs->name, map_cs->size, map_cs->map_priv_1);
#ifdef CONFIG_MTD_AMDSTD #ifdef CONFIG_MTD_AMDSTD
...@@ -398,7 +405,7 @@ static int __init init_axis_flash(void) ...@@ -398,7 +405,7 @@ static int __init init_axis_flash(void)
struct mtd_info *mymtd; struct mtd_info *mymtd;
int err = 0; int err = 0;
int pidx = 0; int pidx = 0;
struct partitiontable_head *ptable_head; struct partitiontable_head *ptable_head = NULL;
struct partitiontable_entry *ptable; struct partitiontable_entry *ptable;
int use_default_ptable = 1; /* Until proven otherwise. */ int use_default_ptable = 1; /* Until proven otherwise. */
const char *pmsg = " /dev/flash%d at 0x%08x, size 0x%08x\n"; const char *pmsg = " /dev/flash%d at 0x%08x, size 0x%08x\n";
...@@ -407,19 +414,22 @@ static int __init init_axis_flash(void) ...@@ -407,19 +414,22 @@ static int __init init_axis_flash(void)
/* There's no reason to use this module if no flash chip can /* There's no reason to use this module if no flash chip can
* be identified. Make sure that's understood. * be identified. Make sure that's understood.
*/ */
panic("axisflashmap found no flash chip!\n"); printk(KERN_INFO "axisflashmap: Found no flash chip.\n");
} else {
printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n",
mymtd->name, mymtd->size);
axisflash_mtd = mymtd;
} }
printk("%s: 0x%08x bytes of flash memory.\n", if (mymtd) {
mymtd->name, mymtd->size); mymtd->owner = THIS_MODULE;
ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR +
mymtd->owner = THIS_MODULE; CONFIG_ETRAX_PTABLE_SECTOR +
PARTITION_TABLE_OFFSET);
ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + }
CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET);
pidx++; /* First partition is always set to the default. */ pidx++; /* First partition is always set to the default. */
if ((ptable_head->magic == PARTITION_TABLE_MAGIC) if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC)
&& (ptable_head->size < && (ptable_head->size <
(MAX_PARTITIONS * sizeof(struct partitiontable_entry) + (MAX_PARTITIONS * sizeof(struct partitiontable_entry) +
PARTITIONTABLE_END_MARKER_SIZE)) PARTITIONTABLE_END_MARKER_SIZE))
...@@ -454,7 +464,7 @@ static int __init init_axis_flash(void) ...@@ -454,7 +464,7 @@ static int __init init_axis_flash(void)
ptable_ok = (csum == ptable_head->checksum); ptable_ok = (csum == ptable_head->checksum);
/* Read the entries and use/show the info. */ /* Read the entries and use/show the info. */
printk(" Found a%s partition table at 0x%p-0x%p.\n", printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n",
(ptable_ok ? " valid" : "n invalid"), ptable_head, (ptable_ok ? " valid" : "n invalid"), ptable_head,
max_addr); max_addr);
...@@ -486,22 +496,25 @@ static int __init init_axis_flash(void) ...@@ -486,22 +496,25 @@ static int __init init_axis_flash(void)
axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; axis_partitions[pidx].mask_flags |= MTD_WRITEABLE;
printk(" Adding readonly flash partition for romfs image:\n"); printk(KERN_INFO
" Adding readonly flash partition for romfs image:\n");
printk(pmsg, pidx, axis_partitions[pidx].offset, printk(pmsg, pidx, axis_partitions[pidx].offset,
axis_partitions[pidx].size); axis_partitions[pidx].size);
pidx++; pidx++;
} }
if (use_default_ptable) { if (mymtd) {
printk(" Using default partition table.\n"); if (use_default_ptable) {
err = add_mtd_partitions(mymtd, axis_default_partitions, printk(KERN_INFO " Using default partition table.\n");
NUM_DEFAULT_PARTITIONS); err = add_mtd_partitions(mymtd, axis_default_partitions,
} else { NUM_DEFAULT_PARTITIONS);
err = add_mtd_partitions(mymtd, axis_partitions, pidx); } else {
} err = add_mtd_partitions(mymtd, axis_partitions, pidx);
}
if (err) { if (err) {
panic("axisflashmap could not add MTD partitions!\n"); panic("axisflashmap could not add MTD partitions!\n");
}
} }
if (!romfs_in_flash) { if (!romfs_in_flash) {
...@@ -522,7 +535,7 @@ static int __init init_axis_flash(void) ...@@ -522,7 +535,7 @@ static int __init init_axis_flash(void)
"mtd_info!\n"); "mtd_info!\n");
} }
printk(" Adding RAM partition for romfs image:\n"); printk(KERN_INFO " Adding RAM partition for romfs image:\n");
printk(pmsg, pidx, romfs_start, romfs_length); printk(pmsg, pidx, romfs_start, romfs_length);
err = mtdram_init_device(mtd_ram, (void*)romfs_start, err = mtdram_init_device(mtd_ram, (void*)romfs_start,
...@@ -539,3 +552,5 @@ static int __init init_axis_flash(void) ...@@ -539,3 +552,5 @@ static int __init init_axis_flash(void)
/* This adds the above to the kernels init-call chain. */ /* This adds the above to the kernels init-call chain. */
module_init(init_axis_flash); module_init(init_axis_flash);
EXPORT_SYMBOL(axisflash_mtd);
...@@ -4,9 +4,18 @@ ...@@ -4,9 +4,18 @@
*! *!
*! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O *! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O
*! *!
*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init
*! *!
*! $Log: ds1302.c,v $ *! $Log: ds1302.c,v $
*! Revision 1.13 2004/05/28 09:26:59 starvik
*! Modified I2C initialization to work in 2.6.
*!
*! Revision 1.12 2004/05/14 07:58:03 starvik
*! Merge of changes from 2.4
*!
*! Revision 1.10 2004/02/04 09:25:12 starvik
*! Merge of Linux 2.6.2
*!
*! Revision 1.9 2003/07/04 08:27:37 starvik *! Revision 1.9 2003/07/04 08:27:37 starvik
*! Merge of Linux 2.5.74 *! Merge of Linux 2.5.74
*! *!
...@@ -114,7 +123,7 @@ ...@@ -114,7 +123,7 @@
*! *!
*! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN *! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN
*! *!
*! $Id: ds1302.c,v 1.9 2003/07/04 08:27:37 starvik Exp $ *! $Id: ds1302.c,v 1.13 2004/05/28 09:26:59 starvik Exp $
*! *!
*!***************************************************************************/ *!***************************************************************************/
...@@ -283,12 +292,23 @@ ds1302_readreg(int reg) ...@@ -283,12 +292,23 @@ ds1302_readreg(int reg)
void void
ds1302_writereg(int reg, unsigned char val) ds1302_writereg(int reg, unsigned char val)
{ {
ds1302_wenable(); #ifndef CONFIG_ETRAX_RTC_READONLY
start(); int do_writereg = 1;
out_byte(0x80 | (reg << 1)); /* write register */ #else
out_byte(val); int do_writereg = 0;
stop();
ds1302_wdisable(); if (reg == RTC_TRICKLECHARGER)
do_writereg = 1;
#endif
if (do_writereg) {
ds1302_wenable();
start();
out_byte(0x80 | (reg << 1)); /* write register */
out_byte(val);
stop();
ds1302_wdisable();
}
} }
void void
...@@ -426,20 +446,33 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -426,20 +446,33 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F); tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F);
ds1302_writereg(RTC_TRICKLECHARGER, tcs_val); ds1302_writereg(RTC_TRICKLECHARGER, tcs_val);
return 0; return 0;
} }
case RTC_VLOW_RD:
{
/* TODO:
* Implement voltage low detection support
*/
printk(KERN_WARNING "DS1302: RTC Voltage Low detection"
" is not supported\n");
return 0;
}
case RTC_VLOW_SET:
{
/* TODO:
* Nothing to do since Voltage Low detection is not supported
*/
return 0;
}
default: default:
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
} }
int static void
get_rtc_status(char *buf) print_rtc_status(void)
{ {
char *p;
struct rtc_time tm; struct rtc_time tm;
p = buf;
get_rtc_time(&tm); get_rtc_time(&tm);
/* /*
...@@ -447,16 +480,12 @@ get_rtc_status(char *buf) ...@@ -447,16 +480,12 @@ get_rtc_status(char *buf)
* time or for Universal Standard Time (GMT). Probably local though. * time or for Universal Standard Time (GMT). Probably local though.
*/ */
p += sprintf(p, printk(KERN_INFO "rtc_time\t: %02d:%02d:%02d\n",
"rtc_time\t: %02d:%02d:%02d\n" tm.tm_hour, tm.tm_min, tm.tm_sec);
"rtc_date\t: %04d-%02d-%02d\n", printk(KERN_INFO "rtc_date\t: %04d-%02d-%02d\n",
tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
return p - buf;
} }
/* The various file operations we support. */ /* The various file operations we support. */
static struct file_operations rtc_fops = { static struct file_operations rtc_fops = {
...@@ -487,11 +516,10 @@ ds1302_probe(void) ...@@ -487,11 +516,10 @@ ds1302_probe(void)
out_byte(0xc1); /* read RAM byte 0 */ out_byte(0xc1); /* read RAM byte 0 */
if((res = in_byte()) == MAGIC_PATTERN) { if((res = in_byte()) == MAGIC_PATTERN) {
char buf[100];
stop(); stop();
ds1302_wdisable(); ds1302_wdisable();
printk("%s: RTC found.\n", ds1302_name); printk(KERN_INFO "%s: RTC found.\n", ds1302_name);
printk("%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n", printk(KERN_INFO "%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n",
ds1302_name, ds1302_name,
CONFIG_ETRAX_DS1302_SDABIT, CONFIG_ETRAX_DS1302_SDABIT,
CONFIG_ETRAX_DS1302_SCLBIT, CONFIG_ETRAX_DS1302_SCLBIT,
...@@ -501,12 +529,10 @@ ds1302_probe(void) ...@@ -501,12 +529,10 @@ ds1302_probe(void)
"PB", "PB",
#endif #endif
CONFIG_ETRAX_DS1302_RSTBIT); CONFIG_ETRAX_DS1302_RSTBIT);
get_rtc_status(buf); print_rtc_status();
printk(buf);
retval = 1; retval = 1;
} else { } else {
stop(); stop();
printk("%s: RTC not found.\n", ds1302_name);
retval = 0; retval = 0;
} }
...@@ -518,7 +544,9 @@ ds1302_probe(void) ...@@ -518,7 +544,9 @@ ds1302_probe(void)
int __init int __init
ds1302_init(void) ds1302_init(void)
{ {
i2c_init();
if (!ds1302_probe()) { if (!ds1302_probe()) {
#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
#if CONFIG_ETRAX_DS1302_RSTBIT == 27 #if CONFIG_ETRAX_DS1302_RSTBIT == 27
...@@ -539,16 +567,20 @@ ds1302_init(void) ...@@ -539,16 +567,20 @@ ds1302_init(void)
(IO_STATE(R_GEN_CONFIG, g0dir, out))); (IO_STATE(R_GEN_CONFIG, g0dir, out)));
*R_GEN_CONFIG = genconfig_shadow; *R_GEN_CONFIG = genconfig_shadow;
#endif #endif
if (!ds1302_probe()) if (!ds1302_probe()) {
printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
return -1; return -1;
}
#else #else
printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
return -1; return -1;
#endif #endif
} }
/* Initialise trickle charger */ /* Initialise trickle charger */
ds1302_writereg(RTC_TRICKLECHARGER, ds1302_writereg(RTC_TRICKLECHARGER,
RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F)); RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F));
/* Start clock by resetting CLOCK_HALT */
ds1302_writereg(RTC_SECONDS, (ds1302_readreg(RTC_SECONDS) & 0x7F));
return 0; return 0;
} }
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
*! in the spin-lock. *! in the spin-lock.
*! *!
*! $Log: eeprom.c,v $ *! $Log: eeprom.c,v $
*! Revision 1.10 2003/09/11 07:29:48 starvik
*! Merge of Linux 2.6.0-test5
*!
*! Revision 1.9 2003/07/04 08:27:37 starvik *! Revision 1.9 2003/07/04 08:27:37 starvik
*! Merge of Linux 2.5.74 *! Merge of Linux 2.5.74
*! *!
...@@ -441,9 +444,9 @@ int __init eeprom_init(void) ...@@ -441,9 +444,9 @@ int __init eeprom_init(void)
static int eeprom_open(struct inode * inode, struct file * file) static int eeprom_open(struct inode * inode, struct file * file)
{ {
if(iminor(inode) != EEPROM_MINOR_NR) if(MINOR(inode->i_rdev) != EEPROM_MINOR_NR)
return -ENXIO; return -ENXIO;
if(imajor(inode) != EEPROM_MAJOR_NR) if(MAJOR(inode->i_rdev) != EEPROM_MAJOR_NR)
return -ENXIO; return -ENXIO;
if( eeprom.size > 0 ) if( eeprom.size > 0 )
......
This diff is collapsed.
/* $Id: gpio.c,v 1.8 2003/07/04 08:27:37 starvik Exp $ /* $Id: gpio.c,v 1.11 2004/05/14 07:58:03 starvik Exp $
* *
* Etrax general port I/O device * Etrax general port I/O device
* *
...@@ -9,6 +9,12 @@ ...@@ -9,6 +9,12 @@
* Johan Adolfsson (read/set directions, write, port G) * Johan Adolfsson (read/set directions, write, port G)
* *
* $Log: gpio.c,v $ * $Log: gpio.c,v $
* Revision 1.11 2004/05/14 07:58:03 starvik
* Merge of changes from 2.4
*
* Revision 1.9 2003/09/11 07:29:48 starvik
* Merge of Linux 2.6.0-test5
*
* Revision 1.8 2003/07/04 08:27:37 starvik * Revision 1.8 2003/07/04 08:27:37 starvik
* Merge of Linux 2.5.74 * Merge of Linux 2.5.74
* *
...@@ -183,6 +189,7 @@ struct gpio_private { ...@@ -183,6 +189,7 @@ struct gpio_private {
static struct gpio_private *alarmlist = 0; static struct gpio_private *alarmlist = 0;
static int gpio_some_alarms = 0; /* Set if someone uses alarm */ static int gpio_some_alarms = 0; /* Set if someone uses alarm */
static unsigned long gpio_pa_irq_enabled_mask = 0;
/* Port A and B use 8 bit access, but Port G is 32 bit */ /* Port A and B use 8 bit access, but Port G is 32 bit */
#define NUM_PORTS (GPIO_MINOR_B+1) #define NUM_PORTS (GPIO_MINOR_B+1)
...@@ -252,13 +259,19 @@ gpio_poll(struct file *file, ...@@ -252,13 +259,19 @@ gpio_poll(struct file *file,
unsigned long data; unsigned long data;
poll_wait(file, &priv->alarm_wq, wait); poll_wait(file, &priv->alarm_wq, wait);
if (priv->minor == GPIO_MINOR_A) { if (priv->minor == GPIO_MINOR_A) {
unsigned long flags;
unsigned long tmp; unsigned long tmp;
data = *R_PORT_PA_DATA; data = *R_PORT_PA_DATA;
/* PA has support for high level interrupt - /* PA has support for high level interrupt -
* lets activate for those low and with highalarm set * lets activate for those low and with highalarm set
*/ */
tmp = ~data & priv->highalarm & 0xFF; tmp = ~data & priv->highalarm & 0xFF;
*R_IRQ_MASK1_SET = (tmp << R_IRQ_MASK1_SET__pa0__BITNR); tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
save_flags(flags); cli();
gpio_pa_irq_enabled_mask |= tmp;
*R_IRQ_MASK1_SET = tmp;
restore_flags(flags);
} else if (priv->minor == GPIO_MINOR_B) } else if (priv->minor == GPIO_MINOR_B)
data = *R_PORT_PB_DATA; data = *R_PORT_PB_DATA;
else if (priv->minor == GPIO_MINOR_G) else if (priv->minor == GPIO_MINOR_G)
...@@ -312,12 +325,15 @@ gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -312,12 +325,15 @@ gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
unsigned long tmp; unsigned long tmp;
/* Find what PA interrupts are active */ /* Find what PA interrupts are active */
tmp = (*R_IRQ_READ1 >> R_IRQ_READ1__pa0__BITNR) & 0xFF; tmp = (*R_IRQ_READ1);
/* Find those that we have enabled */
tmp &= gpio_pa_irq_enabled_mask;
/* Clear them.. */ /* Clear them.. */
/* NOTE: Maybe we need to be more careful here if some other *R_IRQ_MASK1_CLR = tmp;
* driver uses PA interrupt as well? gpio_pa_irq_enabled_mask &= ~tmp;
*/
*R_IRQ_MASK1_CLR = (tmp << R_IRQ_MASK1_CLR__pa0__BITNR);
if (gpio_some_alarms) { if (gpio_some_alarms) {
return IRQ_RETVAL(etrax_gpio_wake_up_check()); return IRQ_RETVAL(etrax_gpio_wake_up_check());
} }
...@@ -386,7 +402,7 @@ static int ...@@ -386,7 +402,7 @@ static int
gpio_open(struct inode *inode, struct file *filp) gpio_open(struct inode *inode, struct file *filp)
{ {
struct gpio_private *priv; struct gpio_private *priv;
int p = iminor(inode); int p = MINOR(inode->i_rdev);
if (p > GPIO_MINOR_LAST) if (p > GPIO_MINOR_LAST)
return -EINVAL; return -EINVAL;
...@@ -479,6 +495,7 @@ unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) ...@@ -479,6 +495,7 @@ unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */ return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
} else if (priv->minor == GPIO_MINOR_G) { } else if (priv->minor == GPIO_MINOR_G) {
/* We must fiddle with R_GEN_CONFIG to change dir */ /* We must fiddle with R_GEN_CONFIG to change dir */
save_flags(flags); cli();
if (((arg & dir_g_in_bits) != arg) && if (((arg & dir_g_in_bits) != arg) &&
(arg & changeable_dir_g)) { (arg & changeable_dir_g)) {
arg &= changeable_dir_g; arg &= changeable_dir_g;
...@@ -503,16 +520,17 @@ unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) ...@@ -503,16 +520,17 @@ unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
dir_g_in_bits |= (1<<24); dir_g_in_bits |= (1<<24);
dir_g_out_bits &= ~(1<<24); dir_g_out_bits &= ~(1<<24);
} }
printk("gpio: SETINPUT on port G set " D(printk(KERN_INFO "gpio: SETINPUT on port G set "
"genconfig to 0x%08lX " "genconfig to 0x%08lX "
"in_bits: 0x%08lX " "in_bits: 0x%08lX "
"out_bits: 0x%08lX\n", "out_bits: 0x%08lX\n",
(unsigned long)genconfig_shadow, (unsigned long)genconfig_shadow,
dir_g_in_bits, dir_g_out_bits); dir_g_in_bits, dir_g_out_bits));
*R_GEN_CONFIG = genconfig_shadow; *R_GEN_CONFIG = genconfig_shadow;
/* Must be a >120 ns delay before writing this again */ /* Must be a >120 ns delay before writing this again */
} }
restore_flags(flags);
return dir_g_in_bits; return dir_g_in_bits;
} }
return 0; return 0;
...@@ -529,6 +547,7 @@ unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) ...@@ -529,6 +547,7 @@ unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
return *priv->dir_shadow; return *priv->dir_shadow;
} else if (priv->minor == GPIO_MINOR_G) { } else if (priv->minor == GPIO_MINOR_G) {
/* We must fiddle with R_GEN_CONFIG to change dir */ /* We must fiddle with R_GEN_CONFIG to change dir */
save_flags(flags); cli();
if (((arg & dir_g_out_bits) != arg) && if (((arg & dir_g_out_bits) != arg) &&
(arg & changeable_dir_g)) { (arg & changeable_dir_g)) {
/* Set bits in genconfig to set to output */ /* Set bits in genconfig to set to output */
...@@ -552,15 +571,16 @@ unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) ...@@ -552,15 +571,16 @@ unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
dir_g_out_bits |= (1<<24); dir_g_out_bits |= (1<<24);
dir_g_in_bits &= ~(1<<24); dir_g_in_bits &= ~(1<<24);
} }
printk("gpio: SETOUTPUT on port G set " D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
"genconfig to 0x%08lX " "genconfig to 0x%08lX "
"in_bits: 0x%08lX " "in_bits: 0x%08lX "
"out_bits: 0x%08lX\n", "out_bits: 0x%08lX\n",
(unsigned long)genconfig_shadow, (unsigned long)genconfig_shadow,
dir_g_in_bits, dir_g_out_bits); dir_g_in_bits, dir_g_out_bits));
*R_GEN_CONFIG = genconfig_shadow; *R_GEN_CONFIG = genconfig_shadow;
/* Must be a >120 ns delay before writing this again */ /* Must be a >120 ns delay before writing this again */
} }
restore_flags(flags);
return dir_g_out_bits & 0x7FFFFFFF; return dir_g_out_bits & 0x7FFFFFFF;
} }
return 0; return 0;
...@@ -625,6 +645,20 @@ gpio_ioctl(struct inode *inode, struct file *file, ...@@ -625,6 +645,20 @@ gpio_ioctl(struct inode *inode, struct file *file,
// clear alarm for bits with 1 in arg // clear alarm for bits with 1 in arg
priv->highalarm &= ~arg; priv->highalarm &= ~arg;
priv->lowalarm &= ~arg; priv->lowalarm &= ~arg;
{
/* Must update gpio_some_alarms */
struct gpio_private *p = alarmlist;
int some_alarms;
some_alarms = 0;
while (p) {
if (p->highalarm | p->lowalarm) {
some_alarms = 1;
break;
}
p = p->next;
}
gpio_some_alarms = some_alarms;
}
break; break;
case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
/* Read direction 0=input 1=output */ /* Read direction 0=input 1=output */
...@@ -844,9 +878,9 @@ static void __init gpio_init_port_g(void) ...@@ -844,9 +878,9 @@ static void __init gpio_init_port_g(void)
dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g); dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
printk("GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n", printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA); dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
printk("GPIO port G: dir: %08lX changeable: %08lX\n", printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
dir_g_shadow, changeable_dir_g); dir_g_shadow, changeable_dir_g);
} }
...@@ -883,7 +917,7 @@ gpio_init(void) ...@@ -883,7 +917,7 @@ gpio_init(void)
#endif #endif
gpio_init_port_g(); gpio_init_port_g();
printk("ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n"); printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n");
/* We call etrax_gpio_wake_up_check() from timer interrupt and /* We call etrax_gpio_wake_up_check() from timer interrupt and
* from cpu_idle() in kernel/process.c * from cpu_idle() in kernel/process.c
* The check in cpu_idle() reduces latency from ~15 ms to ~6 ms * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
...@@ -891,11 +925,11 @@ gpio_init(void) ...@@ -891,11 +925,11 @@ gpio_init(void)
*/ */
if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt, if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
SA_SHIRQ | SA_INTERRUPT,"gpio poll", NULL)) { SA_SHIRQ | SA_INTERRUPT,"gpio poll", NULL)) {
printk("err: timer0 irq for gpio\n"); printk(KERN_CRIT "err: timer0 irq for gpio\n");
} }
if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt, if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
SA_SHIRQ | SA_INTERRUPT,"gpio PA", NULL)) { SA_SHIRQ | SA_INTERRUPT,"gpio PA", NULL)) {
printk("err: PA irq for gpio\n"); printk(KERN_CRIT "err: PA irq for gpio\n");
} }
......
...@@ -12,6 +12,12 @@ ...@@ -12,6 +12,12 @@
*! don't use PB_I2C if DS1302 uses same bits, *! don't use PB_I2C if DS1302 uses same bits,
*! use PB. *! use PB.
*! $Log: i2c.c,v $ *! $Log: i2c.c,v $
*! Revision 1.7 2004/05/28 09:26:59 starvik
*! Modified I2C initialization to work in 2.6.
*!
*! Revision 1.6 2004/05/14 07:58:03 starvik
*! Merge of changes from 2.4
*!
*! Revision 1.4 2002/12/11 13:13:57 starvik *! Revision 1.4 2002/12/11 13:13:57 starvik
*! Added arch/ to v10 specific includes *! Added arch/ to v10 specific includes
*! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) *! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
...@@ -63,7 +69,7 @@ ...@@ -63,7 +69,7 @@
*! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
*! *!
*!***************************************************************************/ *!***************************************************************************/
/* $Id: i2c.c,v 1.4 2002/12/11 13:13:57 starvik Exp $ */ /* $Id: i2c.c,v 1.7 2004/05/28 09:26:59 starvik Exp $ */
/****************** INCLUDE FILES SECTION ***********************************/ /****************** INCLUDE FILES SECTION ***********************************/
...@@ -310,6 +316,12 @@ i2c_inbyte(void) ...@@ -310,6 +316,12 @@ i2c_inbyte(void)
} }
i2c_clk(I2C_CLOCK_HIGH); i2c_clk(I2C_CLOCK_HIGH);
i2c_delay(CLOCK_HIGH_TIME); i2c_delay(CLOCK_HIGH_TIME);
/*
* we leave the clock low, getbyte is usually followed
* by sendack/nack, they assume the clock to be low
*/
i2c_clk(I2C_CLOCK_LOW);
return aBitByte; return aBitByte;
} }
...@@ -371,6 +383,13 @@ i2c_getack(void) ...@@ -371,6 +383,13 @@ i2c_getack(void)
i2c_delay(CLOCK_HIGH_TIME/2); i2c_delay(CLOCK_HIGH_TIME/2);
} }
/*
* our clock is high now, make sure data is low
* before we enable our output. If we keep data high
* and enable output, we would generate a stop condition.
*/
i2c_data(I2C_DATA_LOW);
/* /*
* end clock pulse * end clock pulse
*/ */
...@@ -426,6 +445,37 @@ i2c_sendack(void) ...@@ -426,6 +445,37 @@ i2c_sendack(void)
i2c_dir_in(); i2c_dir_in();
} }
/*#---------------------------------------------------------------------------
*#
*# FUNCTION NAME: i2c_sendnack
*#
*# DESCRIPTION : Sends NACK on received data
*#
*#--------------------------------------------------------------------------*/
void
i2c_sendnack(void)
{
/*
* enable output
*/
i2c_delay(CLOCK_LOW_TIME);
i2c_dir_out();
/*
* set data high
*/
i2c_data(I2C_DATA_HIGH);
/*
* generate clock pulse
*/
i2c_delay(CLOCK_HIGH_TIME/6);
i2c_clk(I2C_CLOCK_HIGH);
i2c_delay(CLOCK_HIGH_TIME);
i2c_clk(I2C_CLOCK_LOW);
i2c_delay(CLOCK_LOW_TIME);
i2c_dir_in();
}
/*#--------------------------------------------------------------------------- /*#---------------------------------------------------------------------------
*# *#
*# FUNCTION NAME: i2c_writereg *# FUNCTION NAME: i2c_writereg
...@@ -489,7 +539,7 @@ i2c_writereg(unsigned char theSlave, unsigned char theReg, ...@@ -489,7 +539,7 @@ i2c_writereg(unsigned char theSlave, unsigned char theReg,
} while(error && cntr--); } while(error && cntr--);
i2c_delay(CLOCK_LOW_TIME); i2c_delay(CLOCK_LOW_TIME);
return -error; return -error;
} }
...@@ -557,7 +607,8 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) ...@@ -557,7 +607,8 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
*/ */
b = i2c_inbyte(); b = i2c_inbyte();
/* /*
* send Ack * last received byte needs to be nacked
* instead of acked
*/ */
i2c_sendack(); i2c_sendack();
/* /*
...@@ -634,11 +685,9 @@ static struct file_operations i2c_fops = { ...@@ -634,11 +685,9 @@ static struct file_operations i2c_fops = {
.release = i2c_release, .release = i2c_release,
}; };
static int __init int __init
i2c_init(void) i2c_init(void)
{ {
int res;
/* Setup and enable the Port B I2C interface */ /* Setup and enable the Port B I2C interface */
#ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C #ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
...@@ -656,21 +705,28 @@ i2c_init(void) ...@@ -656,21 +705,28 @@ i2c_init(void)
IO_STATE(R_PORT_PB_DIR, dir0, input) | IO_STATE(R_PORT_PB_DIR, dir0, input) |
IO_STATE(R_PORT_PB_DIR, dir1, output)); IO_STATE(R_PORT_PB_DIR, dir1, output));
/* register char device */ return 0;
}
static int __init
i2c_register(void)
{
int res;
res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops); i2c_init();
res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);
if(res < 0) { if(res < 0) {
printk(KERN_ERR "i2c: couldn't get a major number.\n"); printk(KERN_ERR "i2c: couldn't get a major number.\n");
return res; return res;
} }
printk("I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n"); printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n");
return 0; return 0;
} }
/* this makes sure that i2c_init is called during boot */ /* this makes sure that i2c_register is called during boot */
module_init(i2c_init); module_init(i2c_register);
/****************** END OF FILE i2c.c ********************************/ /****************** END OF FILE i2c.c ********************************/
/* $Id: i2c.h,v 1.2 2002/11/18 13:16:06 starvik Exp $ */ /* $Id: i2c.h,v 1.3 2004/05/28 09:26:59 starvik Exp $ */
int i2c_init(void);
/* High level I2C actions */ /* High level I2C actions */
int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue); int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue);
......
This diff is collapsed.
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* Author: Tobias Anderberg <tobiasa@axis.com>. * Author: Tobias Anderberg <tobiasa@axis.com>.
* *
* $Id: pcf8563.c,v 1.1 2002/12/12 08:27:26 starvik Exp $ * $Id: pcf8563.c,v 1.4 2004/05/28 09:26:59 starvik Exp $
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/bcd.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -39,7 +40,7 @@ ...@@ -39,7 +40,7 @@
#define PCF8563_MAJOR 121 /* Local major number. */ #define PCF8563_MAJOR 121 /* Local major number. */
#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */
#define PCF8563_NAME "PCF8563" #define PCF8563_NAME "PCF8563"
#define DRIVER_VERSION "$Revision: 1.1 $" #define DRIVER_VERSION "$Revision: 1.4 $"
/* I2C bus slave registers. */ /* I2C bus slave registers. */
#define RTC_I2C_READ 0xa3 #define RTC_I2C_READ 0xa3
...@@ -85,7 +86,12 @@ pcf8563_readreg(int reg) ...@@ -85,7 +86,12 @@ pcf8563_readreg(int reg)
void void
pcf8563_writereg(int reg, unsigned char val) pcf8563_writereg(int reg, unsigned char val)
{ {
i2c_writereg(RTC_I2C_WRITE,reg,val); #ifdef CONFIG_ETRAX_RTC_READONLY
if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
return;
#endif
rtc_write(reg, val);
} }
void void
...@@ -120,6 +126,9 @@ int __init ...@@ -120,6 +126,9 @@ int __init
pcf8563_init(void) pcf8563_init(void)
{ {
unsigned char ret; unsigned char ret;
i2c_init();
/* /*
* First of all we need to reset the chip. This is done by * First of all we need to reset the chip. This is done by
* clearing control1, control2 and clk freq, clear the * clearing control1, control2 and clk freq, clear the
...@@ -152,14 +161,6 @@ pcf8563_init(void) ...@@ -152,14 +161,6 @@ pcf8563_init(void)
if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0) if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0)
goto err; goto err;
if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n",
PCF8563_NAME, PCF8563_MAJOR);
return -1;
}
printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
/* Check for low voltage, and warn about it.. */ /* Check for low voltage, and warn about it.. */
if (rtc_read(RTC_SECONDS) & 0x80) if (rtc_read(RTC_SECONDS) & 0x80)
...@@ -210,9 +211,11 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned ...@@ -210,9 +211,11 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned
break; break;
case RTC_SET_TIME: case RTC_SET_TIME:
{ {
#ifdef CONFIG_ETRAX_RTC_READONLY
return -EPERM;
#else
int leap; int leap;
int century; int century;
unsigned long flags;
struct rtc_time tm; struct rtc_time tm;
memset(&tm, 0, sizeof (struct rtc_time)); memset(&tm, 0, sizeof (struct rtc_time));
...@@ -256,8 +259,35 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned ...@@ -256,8 +259,35 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned
rtc_write(RTC_SECONDS, tm.tm_sec); rtc_write(RTC_SECONDS, tm.tm_sec);
return 0; return 0;
#endif /* !CONFIG_ETRAX_RTC_READONLY */
} }
break;
case RTC_VLOW_RD:
{
int vl_bit = 0;
if (rtc_read(RTC_SECONDS) & 0x80) {
vl_bit = 1;
printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
"date/time information is no longer guaranteed!\n",
PCF8563_NAME);
}
if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
return -EFAULT;
return 0;
}
case RTC_VLOW_SET:
{
/* Clear the VL bit in the seconds register */
int ret = rtc_read(RTC_SECONDS);
rtc_write(RTC_SECONDS, (ret & 0x7F));
return 0;
}
default: default:
return -ENOTTY; return -ENOTTY;
} }
...@@ -265,5 +295,19 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned ...@@ -265,5 +295,19 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned
return 0; return 0;
} }
module_init(pcf8563_init); static int __init
pcf8563_register(void)
{
pcf8563_init();
if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n",
PCF8563_NAME, PCF8563_MAJOR);
return -1;
}
printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
return 0;
}
module_init(pcf8563_register);
module_exit(pcf8563_exit); module_exit(pcf8563_exit);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* $Id: setup.c,v 1.1 2002/12/11 15:42:02 starvik Exp $ /*
* *
* linux/arch/cris/arch-v10/kernel/setup.c * linux/arch/cris/arch-v10/kernel/setup.c
* *
...@@ -94,3 +94,10 @@ int show_cpuinfo(struct seq_file *m, void *v) ...@@ -94,3 +94,10 @@ int show_cpuinfo(struct seq_file *m, void *v)
} }
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
void
show_etrax_copyright(void)
{
printk(KERN_INFO
"Linux/CRIS port on ETRAX 100LX (c) 2001 Axis Communications AB\n");
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include <asm-generic/local.h>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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