aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authormokopatches <mokopatches@openmoko.org>2008-11-19 17:03:18 +0000
committerwarmcat <andy@warmcat.com>2008-11-19 17:03:18 +0000
commit4be3b6cddde0dbf2d66493466f00a1ea930bdfaf (patch)
treed714a215bd70753d104da31606d78bec0c9ac858 /arch
parent81487a2b118cee39ed13586b17c394935d799216 (diff)
introduce-fiq-migrate-vibrator-gta02-only.patch
On GTA02 we use FIQ to manage the vibrator IO now. That is necessary because we stole timer3 from doing hw pwm for vibrator. This keeps the same UI in /sys but does "bitbang pwm" on the same vibrator GPIO From: Andy Green <andy@openmoko.com> Signed-off-by: Andy Green <andy@openmoko.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-s3c2440/fiq_c_isr.c13
-rw-r--r--arch/arm/mach-s3c2440/mach-gta02.c38
2 files changed, 46 insertions, 5 deletions
diff --git a/arch/arm/mach-s3c2440/fiq_c_isr.c b/arch/arm/mach-s3c2440/fiq_c_isr.c
index a71a234d86c..38692fcebf2 100644
--- a/arch/arm/mach-s3c2440/fiq_c_isr.c
+++ b/arch/arm/mach-s3c2440/fiq_c_isr.c
@@ -79,6 +79,7 @@ u16 _fiq_timer_divisor;
*/
extern void __attribute__ ((naked)) s3c2440_fiq_isr(void);
+
/* this is copied into the hard FIQ vector during init */
static void __attribute__ ((naked)) s3c2440_FIQ_Branch(void)
@@ -128,7 +129,7 @@ static int fiq_init_irq_source(int irq_index_fiq)
_fiq_irq = irq_index_fiq;
_fiq_ack_mask = 1 << (irq_index_fiq - S3C2410_CPUIRQ_OFFSET);
- timer_index = (irq_index_fiq - IRQ_TIMER0);
+ _fiq_timer_index = (irq_index_fiq - IRQ_TIMER0);
/* set up the timer to operate as a pwm device */
@@ -136,12 +137,11 @@ static int fiq_init_irq_source(int irq_index_fiq)
if (rc)
goto bail;
- pwm_timer_fiq.timerid = PWM0 + timer_index;
+ pwm_timer_fiq.timerid = PWM0 + _fiq_timer_index;
pwm_timer_fiq.prescaler = (6 - 1) / 2;
pwm_timer_fiq.divider = S3C2410_TCFG1_MUX3_DIV2;
/* default rate == ~32us */
- pwm_timer_fiq.counter = pwm_timer_fiq.comparer =
- timer_divisor = 64;
+ pwm_timer_fiq.counter = pwm_timer_fiq.comparer = 3000;
rc = s3c2410_pwm_enable(&pwm_timer_fiq);
if (rc)
@@ -149,6 +149,8 @@ static int fiq_init_irq_source(int irq_index_fiq)
s3c2410_pwm_start(&pwm_timer_fiq);
+ _fiq_timer_divisor = 0xffff; /* so kick will work initially */
+
/* let our selected interrupt be a magic FIQ interrupt */
__raw_writel(_fiq_ack_mask, S3C2410_INTMOD);
@@ -189,7 +191,7 @@ void fiq_kick(void)
S3C2410_INTMSK);
tcon = __raw_readl(S3C2410_TCON) & ~S3C2410_TCON_T3START;
/* fake the timer to a count of 1 */
- __raw_writel(1, S3C2410_TCNTB(timer_index));
+ __raw_writel(1, S3C2410_TCNTB(_fiq_timer_index));
__raw_writel(tcon | S3C2410_TCON_T3MANUALUPD, S3C2410_TCON);
__raw_writel(tcon | S3C2410_TCON_T3MANUALUPD | S3C2410_TCON_T3START,
S3C2410_TCON);
@@ -207,6 +209,7 @@ static int __init sc32440_fiq_probe(struct platform_device *pdev)
if (!r)
return -EIO;
+
/* configure for the interrupt we are meant to use */
printk(KERN_INFO"Enabling FIQ using irq %d\n", r->start);
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
index cb839b24b6d..8c7bbe733d9 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -95,12 +95,50 @@ static spinlock_t motion_irq_lock;
struct fiq_ipc fiq_ipc;
EXPORT_SYMBOL(fiq_ipc);
+#define DIVISOR_FROM_US(x) ((x) << 1)
+
+#define FIQ_DIVISOR_VIBRATOR DIVISOR_FROM_US(100)
+
/* define FIQ ISR */
FIQ_HANDLER_START()
/* define your locals here -- no initializers though */
+ u16 divisor;
FIQ_HANDLER_ENTRY(256, 512)
/* Your ISR here :-) */
+ divisor = 0xffff;
+
+ /* Vibrator servicing */
+
+ if (fiq_ipc.vib_pwm_latched || fiq_ipc.vib_pwm) { /* not idle */
+ if (((u8)_fiq_count_fiqs) == fiq_ipc.vib_pwm_latched)
+ s3c2410_gpio_setpin(fiq_ipc.vib_gpio_pin, 0);
+ if (((u8)_fiq_count_fiqs) == 0) {
+ fiq_ipc.vib_pwm_latched = fiq_ipc.vib_pwm;
+ if (fiq_ipc.vib_pwm_latched)
+ s3c2410_gpio_setpin(fiq_ipc.vib_gpio_pin, 1);
+ }
+ divisor = FIQ_DIVISOR_VIBRATOR;
+ }
+
+ /* TODO: HDQ servicing */
+
+
+
+ /* disable further timer interrupts if nobody has any work
+ * or adjust rate according to who still has work
+ *
+ * CAUTION: it means forground code must disable FIQ around
+ * its own non-atomic S3C2410_INTMSK changes... not common
+ * thankfully and taken care of by the fiq-basis patch
+ */
+ if (divisor == 0xffff) /* mask the fiq irq source */
+ __raw_writel(__raw_readl(S3C2410_INTMSK) | _fiq_ack_mask,
+ S3C2410_INTMSK);
+ else /* still working, maybe at a different rate */
+ __raw_writel(divisor, S3C2410_TCNTB(_fiq_timer_index));
+ _fiq_timer_divisor = divisor;
+
FIQ_HANDLER_END()