All of lore.kernel.org
 help / color / mirror / Atom feed
From: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
To: linux-omap@vger.kernel.org
Cc: Tony Lindgren <tony@atomide.com>,
	linux-arm-kernel@lists.infradead.org, e3-hacking@earth.li
Subject: [RFC][PATCH v2 1/5] omap1: Amstrad Delta: add FIQ handler for serial keyboard port interrupt processing
Date: Mon, 29 Mar 2010 16:24:08 +0200	[thread overview]
Message-ID: <201003291624.10034.jkrzyszt@tis.icnet.pl> (raw)
In-Reply-To: <201003291619.25878.jkrzyszt@tis.icnet.pl>

This patch introduces a Fast Interrupt Request (FIQ) handler for Amstrad Delta
(E3) videophone. The handler's purpose is to process interrupts generated by a
GPIO line that a serial keyboard clock hangs off. It collects consecutive bits
into bytes, pushing them into a buffer, then requests a higher level interrupt
after one or more characters are ready for further processing by a keyboard
port driver.

The handler also processes interrupts generated by two other GPIO lines, used
by other on-board supported devices, by simply requesting a higher level
interrupt, that in turn should invoke those device's specific irq handlers.

32k timer IRQ line, not used for any purpose by the on-board hardware, has
been choosen as a higher level interrupt source.

Created and tested against linux-2.6.34-rc2.

Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
---
v2 changes:
- no functional changes,
- refresh against linux-2.6.34-rc2.

 arch/arm/mach-omap1/Kconfig                 |    8
 arch/arm/mach-omap1/Makefile                |    1
 arch/arm/mach-omap1/ams-delta-fiq-handler.S |  342 ++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/irqs.h      |    4
 4 files changed, 355 insertions(+)

diff -uprN git.orig/arch/arm/mach-omap1/Kconfig git/arch/arm/mach-omap1/Kconfig
--- git.orig/arch/arm/mach-omap1/Kconfig	2010-03-25 15:52:17.000000000 +0100
+++ git/arch/arm/mach-omap1/Kconfig	2010-03-28 23:28:44.000000000 +0200
@@ -152,6 +152,14 @@ config MACH_AMS_DELTA
 	  Support for the Amstrad E3 (codename Delta) videophone. Say Y here
 	  if you have such a device.
 
+config AMS_DELTA_FIQ
+	bool "Fast Interrupt Request (FIQ) support for the E3"
+	depends on MACH_AMS_DELTA
+	select FIQ
+	help
+	  Provide a FIQ handler for the E3. This redirects the gpio IRQ to FIQ
+	  And is required to use the E3 mailboard
+
 config MACH_OMAP_GENERIC
 	bool "Generic OMAP board"
 	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
diff -uprN git.orig/arch/arm/mach-omap1/Makefile git/arch/arm/mach-omap1/Makefile
--- git.orig/arch/arm/mach-omap1/Makefile	2010-03-25 15:52:17.000000000 +0100
+++ git/arch/arm/mach-omap1/Makefile	2010-03-28 23:28:44.000000000 +0200
@@ -37,6 +37,7 @@ obj-$(CONFIG_MACH_OMAP_PALMZ71)		+= boar
 obj-$(CONFIG_MACH_OMAP_PALMTT)		+= board-palmtt.o
 obj-$(CONFIG_MACH_NOKIA770)		+= board-nokia770.o
 obj-$(CONFIG_MACH_AMS_DELTA)		+= board-ams-delta.o
+obj-$(CONFIG_AMS_DELTA_FIQ)		+= ams-delta-fiq-handler.o
 obj-$(CONFIG_MACH_SX1)			+= board-sx1.o board-sx1-mmc.o
 obj-$(CONFIG_MACH_HERALD)		+= board-htcherald.o
 
diff -uprN git.orig/arch/arm/mach-omap1/ams-delta-fiq-handler.S git/arch/arm/mach-omap1/ams-delta-fiq-handler.S
--- git.orig/arch/arm/mach-omap1/ams-delta-fiq-handler.S	1970-01-01 01:00:00.000000000 +0100
+++ git/arch/arm/mach-omap1/ams-delta-fiq-handler.S	2010-03-28 23:28:44.000000000 +0200
@@ -0,0 +1,342 @@
+/*
+ *  linux/arch/arm/mach-omap1/ams-delta-fiq-handler.S
+ *
+ *  Based on  linux/arch/arm/lib/floppydma.S
+ *  Renamed and modified to work with 2.6 kernel by Matt Callow
+ *  Copyright (C) 1995, 1996 Russell King
+ *  Copyright (C) 2004 Pete Trapps
+ *  Copyright (C) 2006 Matt Callow
+ *  Copyright (C) 2009 Janusz Krzysztofik
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <plat/io.h>
+
+#define OMAP1510_TIMER1_BASE	0xfffec500
+#define OMAP1510_TIMER2_BASE	0xfffec600
+#define OMAP1510_TIMER3_BASE	0xfffec700
+#define OMAP1510_WATCHDOG_BASE	0xfffec800
+
+#define MAX_INTER_BIT_GAP	(6 * 200) 	/* 6 ticks/uSec => 200uSec */
+
+/* MPU Timer Register Offsets */
+#define CNTL_TIMER 		0
+#define LOAD_TIM   		4
+#define READ_TIM   		8
+
+#define MPU_L1_INTERRUPT_BASE	OMAP1_IO_ADDRESS(0xFFFECB00)
+#define MPU_L2_INTERRUPT_BASE	OMAP1_IO_ADDRESS(0xFFFE0000)
+
+#define ITR			0x00
+#define MIR			0x04
+#define SIR_IRQ_CODE 		0x10
+#define SIR_FIQ_CODE 		0x14
+#define CONTROL_REG		0x18
+#define ILR14			0x54
+#define ILR30			0x94
+#define ISR			0x9C
+
+#define T_BIT			0x20
+#define F_BIT			0x40
+#define I_BIT			0x80
+#define CC_V_BIT		(1 << 28)
+#define CC_C_BIT		(1 << 29)
+#define CC_Z_BIT		(1 << 30)
+#define CC_N_BIT		(1 << 31)
+#define PCMASK			0
+
+#define GPIO_BASE		OMAP1_IO_ADDRESS(0xFFFCE000)
+#define GPIO_DATA_INPUT 	0x00
+#define GPIO_DATA_OUTPUT	0x04
+#define GPIO_DIRECTION_CONTROL	0x08
+#define GPIO_INTERRUPT_CONTROL	0x0C
+#define GPIO_INTERRUPT_MASK 	0x10
+#define GPIO_INTERRUPT_STATUS	0x14
+#define GPIO_PIN_CONTROL	0x18
+
+/*
+ * GPIO_DATA_INPUT bit 0 is MBRD_DI_PROC
+ * GPIO_DATA_INPUT bit 1 is MBRD_CLK
+ */
+#define MBRD_DI_PROC_MASK	0x01
+#define MBRD_CLK_MASK		0x02
+#define MDM_MASK		0x04
+#define HKSW_MASK		0x10
+#define OTHERS_MASK		0x14
+
+#define INT_GPIO0    		 0
+#define INT_GPIO1   		 1
+#define INT_GPIO2   		 2
+#define INT_GPIO3   		 3
+#define INT_GPIO4   		 4
+#define INT_GPIO5   		 5
+#define INT_GPIO6   		 6
+#define INT_GPIO7   		 7
+#define INT_GPIO8   		 8
+#define INT_GPIO9   		 9
+#define INT_GPIO10  		10
+#define INT_GPIO11  		11
+#define INT_GPIO12  		12
+#define INT_GPIO13  		13
+#define INT_GPIO14  		14
+#define INT_GPIO15  		15
+
+#define GPIO6_HDW_IP_SCARD_0_MASK 0x40
+
+/* Driver buffer offsets */
+#define FIQ_MASK		 0
+#define FIQ_STATE		 4
+#define FIQ_CHAR_CNT		 8
+#define FIQ_FRNT_OFFSET		12
+#define FIQ_BACK_OFFSET		16
+#define FIQ_BUF_LEN		20
+#define FIQ_CHAR		24
+#define FIQ_MISSED_CHARS	28
+#define FIQ_BUFFER_START	32
+#define FIQ_GPIO_INT_MASK	36
+#define FIQ_CHAR_HICNT		40
+#define FIQ_IRQ_PEND		44
+#define FIQ_SIR_CODE_L1		48
+#define IRQ_SIR_CODE_L2		52
+#define FIQ_CNT_INT_00		56
+#define FIQ_CNT_INT_CHAR	60
+#define FIQ_CNT_INT_MDM		64
+#define FIQ_CNT_INT_FIQ		68
+#define FIQ_CNT_INT_04		72
+#define FIQ_CNT_INT_05		76
+#define FIQ_CNT_INT_KBD		80
+#define FIQ_CNT_INT_07		84
+#define FIQ_CNT_INT_08		88
+#define FIQ_CNT_INT_09		92
+#define FIQ_CNT_INT_10		96
+#define FIQ_CNT_INT_11		100
+#define FIQ_CNT_INT_12		104
+#define FIQ_CNT_INT_13		108
+#define FIQ_CNT_INT_14		112
+#define FIQ_CNT_INT_15		116
+#define FIQ_CIRC_BUFF		120	/*Start of circular buffer */
+
+#define TIMER_32k_MASK		0x400000
+#define GPIO_INT_MASK  		0x4000
+
+/*
+ * Register useage
+ * r8 -
+ * r9 - the driver buffer
+ * r10 -
+ * r11 -
+ * r12 -base pointers
+ * r13 -
+ */
+
+	.text
+
+	.global qwerty_fiqin_end
+
+ENTRY(qwerty_fiqin_start)
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@setup base pointer = MPU_L1_INTERRUPT_BASE 0xFFFECB00
+	ldr r12, mpu_l1_interrupt_base
+	ldr r11, [r12, #SIR_FIQ_CODE]		@read SIR to clear FIQ
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@setup base pointer = GPIO_BASE 0xFFFCE000
+	ldr r12, gpio_base
+
+key:	@Is it a keyboard interrupt?
+	ldr r11, [r12,#GPIO_INTERRUPT_STATUS]	@ get GPIO interrupt status
+	and r10, r11, #MBRD_CLK_MASK		@ reveal keyboard bit
+	cmp r10, #MBRD_CLK_MASK 		@ is keyboard bit low?
+	bne mdm					@ no - spurious - try mdm
+	mov r10, #MBRD_CLK_MASK
+	str r10, [r12,#GPIO_INTERRUPT_STATUS]	@ Set the bit to clear interrupt
+
+	ldr r10, [r9, #FIQ_CNT_INT_KBD]		@ get int count for IRQ handlers
+	add r10, r10, #1			@ increment it
+	str r10, [r9, #FIQ_CNT_INT_KBD]		@ save status for IRQ handlers
+
+	@@@@@@@@@@@@@@@@@@@@@@
+	@ start processing keyboard bitstream
+state:
+	ldr r10, [r9,#FIQ_STATE]
+	cmp r10, #0				@ are we expecting start bit?
+	bne data				@ no - in data processing state
+
+start:
+	ldr r11, [r12, #GPIO_DATA_INPUT]	@ get input
+	and r11, r11, #MBRD_DI_PROC_MASK	@ mask out other bits
+	cmp r11, #MBRD_DI_PROC_MASK		@ is kbd data in bit set?
+	bne exit				@ no - exit, wait for next irq
+	mov r10, #1				@ good start bit, change state
+						@ to data processing
+	str r10, [r9,#FIQ_STATE]
+	mov r10, #0x02				@ set mask to 0x02
+	str r10, [r9, #FIQ_MASK]
+	mov r10, #0				@ clear character byte
+	str r10, [r9, #FIQ_CHAR]
+
+	@@@@@@@@@ MASK OTHERS TILL KEY DONE @@@@@@@@@@@@@@
+	mov r10, #OTHERS_MASK
+	ldr r11, [r12, #GPIO_INTERRUPT_MASK]	@ get mask reg
+	str r11, [r9, #FIQ_GPIO_INT_MASK]	@ save it for later restore
+	orr r11, r11, r10			@ mask modem int
+	str r11, [r12, #GPIO_INTERRUPT_MASK]	@ write mask reg
+	@@@@@@@@@@ END @@@@@@@@@@@@@@@@@
+	b exit					@ exit, wait for first data bit
+
+data:	ldr r11, [r12, #GPIO_DATA_INPUT]	@ get input
+	and r11, r11, #MBRD_DI_PROC_MASK	@ mask out other bits
+	cmp r11, #0				@ is kbd data in clear?
+	bne shift
+	ldr r10, [r9, #FIQ_CHAR]
+	ldr r11, [r9, #FIQ_MASK]
+	orr r10, r11, r10			@ or mask and character byte
+	str r10, [r9, #FIQ_CHAR]
+
+shift:	ldr r10, [r9, #FIQ_MASK]
+	mov r10, r10, lsl #1			@ shift mask left
+	str r10, [r9, #FIQ_MASK]
+	cmp r10, #0x800				@ have we got all the bits?
+	bne exit				@ not yet - get more
+	mov r10, #0				@ yes set state to start
+	str r10, [r9, #FIQ_STATE]
+
+	@@@@@@@@@ KEY DONE - RESTORE INTERRUPT MASK @@@
+	ldr r11, [r9,#FIQ_GPIO_INT_MASK]
+	str r11, [r12, #GPIO_INTERRUPT_MASK]	@ write mask reg
+	@@@@@@@@@@ END @@@@@@@@@@@@@@@@@
+
+	@Add char to circular buffer
+	ldr r10, [r9, #FIQ_CHAR_CNT]		@ get char count
+	ldr r8, [r9, #FIQ_BUF_LEN]		@ get buffer size
+	cmp r10, r8				@ is buffer full?
+	bne not_full
+	ldr r10, [r9, #FIQ_MISSED_CHARS]	@ get missed char count
+	add r10, r10, #1			@ inc missed char count
+	str r10, [r9, #FIQ_MISSED_CHARS]	@ save missed char count
+	b int					@ force IRQ
+
+not_full:
+	ldr r10, [r9, #FIQ_FRNT_OFFSET]		@ get current front offset
+	ldr r11, [r9, #FIQ_BUF_LEN]		@ get buff size
+	cmp r10, 	r11			@ offset == buffer size?
+	bne store				@ no - so branch to front
+	mov r10, #0				@ set front offset = 0
+
+store:	ldr r12, [r9, #FIQ_BUFFER_START]	@ get start addr of circ buffer
+	add r12, r12, r10, LSL #2		@ add front offset to buff base
+	ldr r8, [r9, #FIQ_CHAR]			@ get latest character
+	str r8, [r12]				@ ####01 store in circ buffer
+	add r10, r10, #1			@ inc front offset
+	str r10, [r9, #FIQ_FRNT_OFFSET]		@ ####04 store front offset
+	ldr r8, [r9, #FIQ_CHAR_CNT]		@ get char count
+	add r8, r8, #1				@ inc count of chars in buffer
+	str r8, [r9, #FIQ_CHAR_CNT]		@ ####02 store char count
+
+	ldr r10, [r9, #FIQ_CHAR_HICNT]		@ get char count hi watermark
+	cmp r10, r8
+	bgt setstat				@ hi count bigger - don't change
+	str r8, [r9, #FIQ_CHAR_HICNT]		@ store char cnt in hi watermark
+setstat:
+	ldr r10, [r9, #FIQ_CNT_INT_CHAR]	@ get char cnt for IRQ handlers
+	add r10, r10, #1			@ increment it
+	str r10, [r9, #FIQ_CNT_INT_CHAR]	@ save status for IRQ handlers
+
+	@@@@@@@@@@@@@@@@@@@@@@@@
+	@ Force a INT_OS_32kHz_TIMER interrupt
+	@setup base pointer = MPU_L2_INTERRUPT_BASE	0xFFFE0000
+int:	ldr r12, mpu_l2_interrupt_base
+	mov r10, #TIMER_32k_MASK		@ set 32kHz_TIMER bit
+	str r10, [r12, #ISR] 			@ write ISR
+
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@setup base pointer = GPIO_BASE 0xFFFCE000
+	ldr r12, gpio_base
+
+mdm:	@Is it a modem interrupt?
+	ldr r11, [r12,#GPIO_INTERRUPT_MASK]	@ get GPIO interrupt mask
+	and r10, r11, #MDM_MASK 		@ reveal modem bit
+	cmp r10, #MDM_MASK			@ is mask bit set?
+	beq hksw				@ yes, next source
+
+	ldr r11, [r12,#GPIO_DATA_INPUT] 	@ get GPIO data line status
+	and r10, r11, #MDM_MASK 		@ reveal modem bit
+	cmp r10, #MDM_MASK			@ is modem bit set?
+	bne hksw				@ no, so skip mdm - next source
+
+	mov r10, #MDM_MASK			@ its a mdm interrupt
+	str r10, [r12,#GPIO_INTERRUPT_STATUS]	@ clear the modem interrupt
+
+	ldr r10, [r9, #FIQ_CNT_INT_MDM]		@ get modem interrupt count
+	add r10, r10, #1			@ increment it
+	str r10, [r9, #FIQ_CNT_INT_MDM]		@ save count for IRQ handlers
+
+	@@@@@@@@@@@@@@@@@@@@@@@@
+	@ Force a INT_OS_32kHz_TIMER interrupt
+	@setup base pointer = MPU_L2_INTERRUPT_BASE 0xFFFE0000
+	ldr r12, mpu_l2_interrupt_base
+	mov r10, #TIMER_32k_MASK		@ set 32kHz_TIMER bit
+	str r10, [r12, #ISR]			@ write ISR
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@setup base pointer = GPIO_BASE 0xFFFCE000
+	ldr r12, gpio_base
+
+hksw:	@Is it a hook switch interrupt?
+	ldr r11, [r12,#GPIO_INTERRUPT_MASK]	@ get GPIO interrupt mask
+	and r10, r11, #HKSW_MASK 		@ reveal hook switch bit
+	cmp r10, #HKSW_MASK			@ is mask bit set?
+	beq exit				@ yes, exit
+
+	ldr r11, [r12,#GPIO_INTERRUPT_STATUS] 	@ get GPIO interrupts status
+	and r10, r11, #HKSW_MASK 		@ reveal hook switch bit
+	cmp r10, #HKSW_MASK			@ is hook switch bit set?
+	bne exit				@ no, so skip hksw - exit
+
+	mov r10, #HKSW_MASK			@ it's a hooksw interrupt
+	str r10, [r12,#GPIO_INTERRUPT_STATUS]	@ clear hook switch interrupt
+
+	ldr r10, [r9, #FIQ_CNT_INT_04]		@ get hooksw inerrupt count
+	add r10, r10, #1			@ increment it
+	str r10, [r9, #FIQ_CNT_INT_04]		@ save count for IRQ handlers
+
+	@@@@@@@@@@@@@@@@@@@@@@@@
+	@ Force a INT_OS_32kHz_TIMER interrupt
+	@setup base pointer = MPU_L2_INTERRUPT_BASE 0xFFFE0000
+	ldr r12, mpu_l2_interrupt_base
+	mov r10, #TIMER_32k_MASK		@ set 32kHz_TIMER bit
+	str r10, [r12, #ISR]			@ write ISR
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@setup base pointer = MPU_L1_INTERRUPT_BASE 0xFFFECB00
+exit:	ldr r12, mpu_l1_interrupt_base
+	mov r10, # 0x2
+	str r10, [r12, #CONTROL_REG]		@ reset FIQ Agreement
+
+	subs	pc, lr, #4			@ return from FIQ
+
+/*
+ * Virtual addresses for IO
+ */
+mpu_l1_interrupt_base:
+	.word MPU_L1_INTERRUPT_BASE
+mpu_l2_interrupt_base:
+	.word MPU_L2_INTERRUPT_BASE
+gpio_base:
+	.word GPIO_BASE
+qwerty_fiqin_end:
+
+/*
+ * Check the size of the FIQ,
+ * it cannot go beyond 0xffff0200, and is copied to 0xffff001c
+ */
+.if (qwerty_fiqin_end - qwerty_fiqin_start) > (0x200 - 0x1c)
+	.err
+.endif
diff -uprN git.orig/arch/arm/plat-omap/include/plat/irqs.h git/arch/arm/plat-omap/include/plat/irqs.h
--- git.orig/arch/arm/plat-omap/include/plat/irqs.h	2010-03-25 15:52:38.000000000 +0100
+++ git/arch/arm/plat-omap/include/plat/irqs.h	2010-03-28 23:28:44.000000000 +0200
@@ -430,4 +430,8 @@ void omap3_intc_resume_idle(void);
 
 #include <mach/hardware.h>
 
+#ifdef CONFIG_FIQ
+#define FIQ_START		1024
+#endif
+
 #endif

WARNING: multiple messages have this Message-ID (diff)
From: jkrzyszt@tis.icnet.pl (Janusz Krzysztofik)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC][PATCH v2 1/5] omap1: Amstrad Delta: add FIQ handler for serial keyboard port interrupt processing
Date: Mon, 29 Mar 2010 16:24:08 +0200	[thread overview]
Message-ID: <201003291624.10034.jkrzyszt@tis.icnet.pl> (raw)
In-Reply-To: <201003291619.25878.jkrzyszt@tis.icnet.pl>

This patch introduces a Fast Interrupt Request (FIQ) handler for Amstrad Delta
(E3) videophone. The handler's purpose is to process interrupts generated by a
GPIO line that a serial keyboard clock hangs off. It collects consecutive bits
into bytes, pushing them into a buffer, then requests a higher level interrupt
after one or more characters are ready for further processing by a keyboard
port driver.

The handler also processes interrupts generated by two other GPIO lines, used
by other on-board supported devices, by simply requesting a higher level
interrupt, that in turn should invoke those device's specific irq handlers.

32k timer IRQ line, not used for any purpose by the on-board hardware, has
been choosen as a higher level interrupt source.

Created and tested against linux-2.6.34-rc2.

Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
---
v2 changes:
- no functional changes,
- refresh against linux-2.6.34-rc2.

 arch/arm/mach-omap1/Kconfig                 |    8
 arch/arm/mach-omap1/Makefile                |    1
 arch/arm/mach-omap1/ams-delta-fiq-handler.S |  342 ++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/irqs.h      |    4
 4 files changed, 355 insertions(+)

diff -uprN git.orig/arch/arm/mach-omap1/Kconfig git/arch/arm/mach-omap1/Kconfig
--- git.orig/arch/arm/mach-omap1/Kconfig	2010-03-25 15:52:17.000000000 +0100
+++ git/arch/arm/mach-omap1/Kconfig	2010-03-28 23:28:44.000000000 +0200
@@ -152,6 +152,14 @@ config MACH_AMS_DELTA
 	  Support for the Amstrad E3 (codename Delta) videophone. Say Y here
 	  if you have such a device.
 
+config AMS_DELTA_FIQ
+	bool "Fast Interrupt Request (FIQ) support for the E3"
+	depends on MACH_AMS_DELTA
+	select FIQ
+	help
+	  Provide a FIQ handler for the E3. This redirects the gpio IRQ to FIQ
+	  And is required to use the E3 mailboard
+
 config MACH_OMAP_GENERIC
 	bool "Generic OMAP board"
 	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
diff -uprN git.orig/arch/arm/mach-omap1/Makefile git/arch/arm/mach-omap1/Makefile
--- git.orig/arch/arm/mach-omap1/Makefile	2010-03-25 15:52:17.000000000 +0100
+++ git/arch/arm/mach-omap1/Makefile	2010-03-28 23:28:44.000000000 +0200
@@ -37,6 +37,7 @@ obj-$(CONFIG_MACH_OMAP_PALMZ71)		+= boar
 obj-$(CONFIG_MACH_OMAP_PALMTT)		+= board-palmtt.o
 obj-$(CONFIG_MACH_NOKIA770)		+= board-nokia770.o
 obj-$(CONFIG_MACH_AMS_DELTA)		+= board-ams-delta.o
+obj-$(CONFIG_AMS_DELTA_FIQ)		+= ams-delta-fiq-handler.o
 obj-$(CONFIG_MACH_SX1)			+= board-sx1.o board-sx1-mmc.o
 obj-$(CONFIG_MACH_HERALD)		+= board-htcherald.o
 
diff -uprN git.orig/arch/arm/mach-omap1/ams-delta-fiq-handler.S git/arch/arm/mach-omap1/ams-delta-fiq-handler.S
--- git.orig/arch/arm/mach-omap1/ams-delta-fiq-handler.S	1970-01-01 01:00:00.000000000 +0100
+++ git/arch/arm/mach-omap1/ams-delta-fiq-handler.S	2010-03-28 23:28:44.000000000 +0200
@@ -0,0 +1,342 @@
+/*
+ *  linux/arch/arm/mach-omap1/ams-delta-fiq-handler.S
+ *
+ *  Based on  linux/arch/arm/lib/floppydma.S
+ *  Renamed and modified to work with 2.6 kernel by Matt Callow
+ *  Copyright (C) 1995, 1996 Russell King
+ *  Copyright (C) 2004 Pete Trapps
+ *  Copyright (C) 2006 Matt Callow
+ *  Copyright (C) 2009 Janusz Krzysztofik
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <plat/io.h>
+
+#define OMAP1510_TIMER1_BASE	0xfffec500
+#define OMAP1510_TIMER2_BASE	0xfffec600
+#define OMAP1510_TIMER3_BASE	0xfffec700
+#define OMAP1510_WATCHDOG_BASE	0xfffec800
+
+#define MAX_INTER_BIT_GAP	(6 * 200) 	/* 6 ticks/uSec => 200uSec */
+
+/* MPU Timer Register Offsets */
+#define CNTL_TIMER 		0
+#define LOAD_TIM   		4
+#define READ_TIM   		8
+
+#define MPU_L1_INTERRUPT_BASE	OMAP1_IO_ADDRESS(0xFFFECB00)
+#define MPU_L2_INTERRUPT_BASE	OMAP1_IO_ADDRESS(0xFFFE0000)
+
+#define ITR			0x00
+#define MIR			0x04
+#define SIR_IRQ_CODE 		0x10
+#define SIR_FIQ_CODE 		0x14
+#define CONTROL_REG		0x18
+#define ILR14			0x54
+#define ILR30			0x94
+#define ISR			0x9C
+
+#define T_BIT			0x20
+#define F_BIT			0x40
+#define I_BIT			0x80
+#define CC_V_BIT		(1 << 28)
+#define CC_C_BIT		(1 << 29)
+#define CC_Z_BIT		(1 << 30)
+#define CC_N_BIT		(1 << 31)
+#define PCMASK			0
+
+#define GPIO_BASE		OMAP1_IO_ADDRESS(0xFFFCE000)
+#define GPIO_DATA_INPUT 	0x00
+#define GPIO_DATA_OUTPUT	0x04
+#define GPIO_DIRECTION_CONTROL	0x08
+#define GPIO_INTERRUPT_CONTROL	0x0C
+#define GPIO_INTERRUPT_MASK 	0x10
+#define GPIO_INTERRUPT_STATUS	0x14
+#define GPIO_PIN_CONTROL	0x18
+
+/*
+ * GPIO_DATA_INPUT bit 0 is MBRD_DI_PROC
+ * GPIO_DATA_INPUT bit 1 is MBRD_CLK
+ */
+#define MBRD_DI_PROC_MASK	0x01
+#define MBRD_CLK_MASK		0x02
+#define MDM_MASK		0x04
+#define HKSW_MASK		0x10
+#define OTHERS_MASK		0x14
+
+#define INT_GPIO0    		 0
+#define INT_GPIO1   		 1
+#define INT_GPIO2   		 2
+#define INT_GPIO3   		 3
+#define INT_GPIO4   		 4
+#define INT_GPIO5   		 5
+#define INT_GPIO6   		 6
+#define INT_GPIO7   		 7
+#define INT_GPIO8   		 8
+#define INT_GPIO9   		 9
+#define INT_GPIO10  		10
+#define INT_GPIO11  		11
+#define INT_GPIO12  		12
+#define INT_GPIO13  		13
+#define INT_GPIO14  		14
+#define INT_GPIO15  		15
+
+#define GPIO6_HDW_IP_SCARD_0_MASK 0x40
+
+/* Driver buffer offsets */
+#define FIQ_MASK		 0
+#define FIQ_STATE		 4
+#define FIQ_CHAR_CNT		 8
+#define FIQ_FRNT_OFFSET		12
+#define FIQ_BACK_OFFSET		16
+#define FIQ_BUF_LEN		20
+#define FIQ_CHAR		24
+#define FIQ_MISSED_CHARS	28
+#define FIQ_BUFFER_START	32
+#define FIQ_GPIO_INT_MASK	36
+#define FIQ_CHAR_HICNT		40
+#define FIQ_IRQ_PEND		44
+#define FIQ_SIR_CODE_L1		48
+#define IRQ_SIR_CODE_L2		52
+#define FIQ_CNT_INT_00		56
+#define FIQ_CNT_INT_CHAR	60
+#define FIQ_CNT_INT_MDM		64
+#define FIQ_CNT_INT_FIQ		68
+#define FIQ_CNT_INT_04		72
+#define FIQ_CNT_INT_05		76
+#define FIQ_CNT_INT_KBD		80
+#define FIQ_CNT_INT_07		84
+#define FIQ_CNT_INT_08		88
+#define FIQ_CNT_INT_09		92
+#define FIQ_CNT_INT_10		96
+#define FIQ_CNT_INT_11		100
+#define FIQ_CNT_INT_12		104
+#define FIQ_CNT_INT_13		108
+#define FIQ_CNT_INT_14		112
+#define FIQ_CNT_INT_15		116
+#define FIQ_CIRC_BUFF		120	/*Start of circular buffer */
+
+#define TIMER_32k_MASK		0x400000
+#define GPIO_INT_MASK  		0x4000
+
+/*
+ * Register useage
+ * r8 -
+ * r9 - the driver buffer
+ * r10 -
+ * r11 -
+ * r12 -base pointers
+ * r13 -
+ */
+
+	.text
+
+	.global qwerty_fiqin_end
+
+ENTRY(qwerty_fiqin_start)
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@setup base pointer = MPU_L1_INTERRUPT_BASE 0xFFFECB00
+	ldr r12, mpu_l1_interrupt_base
+	ldr r11, [r12, #SIR_FIQ_CODE]		@read SIR to clear FIQ
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@setup base pointer = GPIO_BASE 0xFFFCE000
+	ldr r12, gpio_base
+
+key:	@Is it a keyboard interrupt?
+	ldr r11, [r12,#GPIO_INTERRUPT_STATUS]	@ get GPIO interrupt status
+	and r10, r11, #MBRD_CLK_MASK		@ reveal keyboard bit
+	cmp r10, #MBRD_CLK_MASK 		@ is keyboard bit low?
+	bne mdm					@ no - spurious - try mdm
+	mov r10, #MBRD_CLK_MASK
+	str r10, [r12,#GPIO_INTERRUPT_STATUS]	@ Set the bit to clear interrupt
+
+	ldr r10, [r9, #FIQ_CNT_INT_KBD]		@ get int count for IRQ handlers
+	add r10, r10, #1			@ increment it
+	str r10, [r9, #FIQ_CNT_INT_KBD]		@ save status for IRQ handlers
+
+	@@@@@@@@@@@@@@@@@@@@@@
+	@ start processing keyboard bitstream
+state:
+	ldr r10, [r9,#FIQ_STATE]
+	cmp r10, #0				@ are we expecting start bit?
+	bne data				@ no - in data processing state
+
+start:
+	ldr r11, [r12, #GPIO_DATA_INPUT]	@ get input
+	and r11, r11, #MBRD_DI_PROC_MASK	@ mask out other bits
+	cmp r11, #MBRD_DI_PROC_MASK		@ is kbd data in bit set?
+	bne exit				@ no - exit, wait for next irq
+	mov r10, #1				@ good start bit, change state
+						@ to data processing
+	str r10, [r9,#FIQ_STATE]
+	mov r10, #0x02				@ set mask to 0x02
+	str r10, [r9, #FIQ_MASK]
+	mov r10, #0				@ clear character byte
+	str r10, [r9, #FIQ_CHAR]
+
+	@@@@@@@@@ MASK OTHERS TILL KEY DONE @@@@@@@@@@@@@@
+	mov r10, #OTHERS_MASK
+	ldr r11, [r12, #GPIO_INTERRUPT_MASK]	@ get mask reg
+	str r11, [r9, #FIQ_GPIO_INT_MASK]	@ save it for later restore
+	orr r11, r11, r10			@ mask modem int
+	str r11, [r12, #GPIO_INTERRUPT_MASK]	@ write mask reg
+	@@@@@@@@@@ END @@@@@@@@@@@@@@@@@
+	b exit					@ exit, wait for first data bit
+
+data:	ldr r11, [r12, #GPIO_DATA_INPUT]	@ get input
+	and r11, r11, #MBRD_DI_PROC_MASK	@ mask out other bits
+	cmp r11, #0				@ is kbd data in clear?
+	bne shift
+	ldr r10, [r9, #FIQ_CHAR]
+	ldr r11, [r9, #FIQ_MASK]
+	orr r10, r11, r10			@ or mask and character byte
+	str r10, [r9, #FIQ_CHAR]
+
+shift:	ldr r10, [r9, #FIQ_MASK]
+	mov r10, r10, lsl #1			@ shift mask left
+	str r10, [r9, #FIQ_MASK]
+	cmp r10, #0x800				@ have we got all the bits?
+	bne exit				@ not yet - get more
+	mov r10, #0				@ yes set state to start
+	str r10, [r9, #FIQ_STATE]
+
+	@@@@@@@@@ KEY DONE - RESTORE INTERRUPT MASK @@@
+	ldr r11, [r9,#FIQ_GPIO_INT_MASK]
+	str r11, [r12, #GPIO_INTERRUPT_MASK]	@ write mask reg
+	@@@@@@@@@@ END @@@@@@@@@@@@@@@@@
+
+	@Add char to circular buffer
+	ldr r10, [r9, #FIQ_CHAR_CNT]		@ get char count
+	ldr r8, [r9, #FIQ_BUF_LEN]		@ get buffer size
+	cmp r10, r8				@ is buffer full?
+	bne not_full
+	ldr r10, [r9, #FIQ_MISSED_CHARS]	@ get missed char count
+	add r10, r10, #1			@ inc missed char count
+	str r10, [r9, #FIQ_MISSED_CHARS]	@ save missed char count
+	b int					@ force IRQ
+
+not_full:
+	ldr r10, [r9, #FIQ_FRNT_OFFSET]		@ get current front offset
+	ldr r11, [r9, #FIQ_BUF_LEN]		@ get buff size
+	cmp r10, 	r11			@ offset == buffer size?
+	bne store				@ no - so branch to front
+	mov r10, #0				@ set front offset = 0
+
+store:	ldr r12, [r9, #FIQ_BUFFER_START]	@ get start addr of circ buffer
+	add r12, r12, r10, LSL #2		@ add front offset to buff base
+	ldr r8, [r9, #FIQ_CHAR]			@ get latest character
+	str r8, [r12]				@ ####01 store in circ buffer
+	add r10, r10, #1			@ inc front offset
+	str r10, [r9, #FIQ_FRNT_OFFSET]		@ ####04 store front offset
+	ldr r8, [r9, #FIQ_CHAR_CNT]		@ get char count
+	add r8, r8, #1				@ inc count of chars in buffer
+	str r8, [r9, #FIQ_CHAR_CNT]		@ ####02 store char count
+
+	ldr r10, [r9, #FIQ_CHAR_HICNT]		@ get char count hi watermark
+	cmp r10, r8
+	bgt setstat				@ hi count bigger - don't change
+	str r8, [r9, #FIQ_CHAR_HICNT]		@ store char cnt in hi watermark
+setstat:
+	ldr r10, [r9, #FIQ_CNT_INT_CHAR]	@ get char cnt for IRQ handlers
+	add r10, r10, #1			@ increment it
+	str r10, [r9, #FIQ_CNT_INT_CHAR]	@ save status for IRQ handlers
+
+	@@@@@@@@@@@@@@@@@@@@@@@@
+	@ Force a INT_OS_32kHz_TIMER interrupt
+	@setup base pointer = MPU_L2_INTERRUPT_BASE	0xFFFE0000
+int:	ldr r12, mpu_l2_interrupt_base
+	mov r10, #TIMER_32k_MASK		@ set 32kHz_TIMER bit
+	str r10, [r12, #ISR] 			@ write ISR
+
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@setup base pointer = GPIO_BASE 0xFFFCE000
+	ldr r12, gpio_base
+
+mdm:	@Is it a modem interrupt?
+	ldr r11, [r12,#GPIO_INTERRUPT_MASK]	@ get GPIO interrupt mask
+	and r10, r11, #MDM_MASK 		@ reveal modem bit
+	cmp r10, #MDM_MASK			@ is mask bit set?
+	beq hksw				@ yes, next source
+
+	ldr r11, [r12,#GPIO_DATA_INPUT] 	@ get GPIO data line status
+	and r10, r11, #MDM_MASK 		@ reveal modem bit
+	cmp r10, #MDM_MASK			@ is modem bit set?
+	bne hksw				@ no, so skip mdm - next source
+
+	mov r10, #MDM_MASK			@ its a mdm interrupt
+	str r10, [r12,#GPIO_INTERRUPT_STATUS]	@ clear the modem interrupt
+
+	ldr r10, [r9, #FIQ_CNT_INT_MDM]		@ get modem interrupt count
+	add r10, r10, #1			@ increment it
+	str r10, [r9, #FIQ_CNT_INT_MDM]		@ save count for IRQ handlers
+
+	@@@@@@@@@@@@@@@@@@@@@@@@
+	@ Force a INT_OS_32kHz_TIMER interrupt
+	@setup base pointer = MPU_L2_INTERRUPT_BASE 0xFFFE0000
+	ldr r12, mpu_l2_interrupt_base
+	mov r10, #TIMER_32k_MASK		@ set 32kHz_TIMER bit
+	str r10, [r12, #ISR]			@ write ISR
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@setup base pointer = GPIO_BASE 0xFFFCE000
+	ldr r12, gpio_base
+
+hksw:	@Is it a hook switch interrupt?
+	ldr r11, [r12,#GPIO_INTERRUPT_MASK]	@ get GPIO interrupt mask
+	and r10, r11, #HKSW_MASK 		@ reveal hook switch bit
+	cmp r10, #HKSW_MASK			@ is mask bit set?
+	beq exit				@ yes, exit
+
+	ldr r11, [r12,#GPIO_INTERRUPT_STATUS] 	@ get GPIO interrupts status
+	and r10, r11, #HKSW_MASK 		@ reveal hook switch bit
+	cmp r10, #HKSW_MASK			@ is hook switch bit set?
+	bne exit				@ no, so skip hksw - exit
+
+	mov r10, #HKSW_MASK			@ it's a hooksw interrupt
+	str r10, [r12,#GPIO_INTERRUPT_STATUS]	@ clear hook switch interrupt
+
+	ldr r10, [r9, #FIQ_CNT_INT_04]		@ get hooksw inerrupt count
+	add r10, r10, #1			@ increment it
+	str r10, [r9, #FIQ_CNT_INT_04]		@ save count for IRQ handlers
+
+	@@@@@@@@@@@@@@@@@@@@@@@@
+	@ Force a INT_OS_32kHz_TIMER interrupt
+	@setup base pointer = MPU_L2_INTERRUPT_BASE 0xFFFE0000
+	ldr r12, mpu_l2_interrupt_base
+	mov r10, #TIMER_32k_MASK		@ set 32kHz_TIMER bit
+	str r10, [r12, #ISR]			@ write ISR
+
+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+	@setup base pointer = MPU_L1_INTERRUPT_BASE 0xFFFECB00
+exit:	ldr r12, mpu_l1_interrupt_base
+	mov r10, # 0x2
+	str r10, [r12, #CONTROL_REG]		@ reset FIQ Agreement
+
+	subs	pc, lr, #4			@ return from FIQ
+
+/*
+ * Virtual addresses for IO
+ */
+mpu_l1_interrupt_base:
+	.word MPU_L1_INTERRUPT_BASE
+mpu_l2_interrupt_base:
+	.word MPU_L2_INTERRUPT_BASE
+gpio_base:
+	.word GPIO_BASE
+qwerty_fiqin_end:
+
+/*
+ * Check the size of the FIQ,
+ * it cannot go beyond 0xffff0200, and is copied to 0xffff001c
+ */
+.if (qwerty_fiqin_end - qwerty_fiqin_start) > (0x200 - 0x1c)
+	.err
+.endif
diff -uprN git.orig/arch/arm/plat-omap/include/plat/irqs.h git/arch/arm/plat-omap/include/plat/irqs.h
--- git.orig/arch/arm/plat-omap/include/plat/irqs.h	2010-03-25 15:52:38.000000000 +0100
+++ git/arch/arm/plat-omap/include/plat/irqs.h	2010-03-28 23:28:44.000000000 +0200
@@ -430,4 +430,8 @@ void omap3_intc_resume_idle(void);
 
 #include <mach/hardware.h>
 
+#ifdef CONFIG_FIQ
+#define FIQ_START		1024
+#endif
+
 #endif

  reply	other threads:[~2010-03-29 14:24 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-29 14:19 [RFC][PATCH v2 0/5] omap1: Amstrad Delta: add support for external keyboard Janusz Krzysztofik
2010-03-29 14:19 ` Janusz Krzysztofik
2010-03-29 14:24 ` Janusz Krzysztofik [this message]
2010-03-29 14:24   ` [RFC][PATCH v2 1/5] omap1: Amstrad Delta: add FIQ handler for serial keyboard port interrupt processing Janusz Krzysztofik
     [not found]   ` <20100329183211.F105C493B@blake.inputplus.co.uk>
2010-03-30 15:08     ` [E3-hacking] " Janusz Krzysztofik
2010-03-30 15:08       ` Janusz Krzysztofik
2010-03-31  0:06       ` Ralph Corderoy
2010-03-31  0:06         ` [E3-hacking] " Ralph Corderoy
2010-03-29 14:26 ` [RFC][PATCH v2 2/5] omap1: Amstrad Delta: add a handler for processing interrupts generated by the FIQ routine Janusz Krzysztofik
2010-03-29 14:26   ` Janusz Krzysztofik
2010-03-29 14:28 ` [RFC][PATCH v2 3/5] omap1: Amstrad Delta: use FIQ for processing GPIO interrupts Janusz Krzysztofik
2010-03-29 14:28   ` Janusz Krzysztofik
2010-03-29 14:30 ` [RFC][PATCH v2 4/5] input: serio: add support for Amstrad Delta serial keyboard port Janusz Krzysztofik
2010-03-30  6:56   ` Dmitry Torokhov
2010-03-30 10:23     ` Janusz Krzysztofik
2010-03-29 14:32 ` [RFC][PATCH v2 5/5] omap1: Amstrad Delta: modify defconfig for external keyboard support Janusz Krzysztofik
2010-03-29 19:58 ` [RFC][PATCH v2 0/5] omap1: Amstrad Delta: add support for external keyboard Janusz Krzysztofik
2010-04-12  3:16   ` Dmitry Torokhov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201003291624.10034.jkrzyszt@tis.icnet.pl \
    --to=jkrzyszt@tis.icnet.pl \
    --cc=e3-hacking@earth.li \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=tony@atomide.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.