Subject: Controlling the H5xxx vibrator

From: Bob Loader <bobloader_at_hotmail.com>
Date: Mon, 12 Jul 2004 13:08:05 -0700

What I've been trying to do is enable/disable the vibrator
on a H5xxx iPAQ (specfically H5555), from a kernel module
and then eventually from user space. If this already exists,
sorry for the annoyance, if not here's what I've tried so far.

I've check the mail archives, most matches are related
to reseting the device. I have pulled down CVS snapshots for the
bootldr, linux/kernel, and gpe hoping to find an example
of any usage of the vibrator (the bootldr is obvious).
A fair amount of grepping later and the only foothold
I had to start with was the bootldr code (specifically
bootldr.c), which contains the following:
     /* turn off the vibrator */
     if ( machine_is_h5400()) {
       putstr("poking gpdr to stop vibration\r\n");
       *(long*)0x40e00014 = 0x8000;
     }

I -think- I've figured out, that this code is performing an
assignment directly using the physical memory address of
the GPDR2 register of the PXA255 to set GPIO Pin 79 as an output pin,
effectively shutting it off and in the process turning
off the vibrator.

Initally I thought I might be able to simply flip the
pin direction from input/output to turn the vibrator on/off.
To test this, I wrote a simple kernel module which when
loaded dumps some of the register values to the log, sets
pin 79 as input and when removed set it as output.
It ran and appeared to do as expected. The value of GPDR2
changed from 0xafdf to 0x2fdf and back as expected (based
on what dmesg shows me), but no vibes.

-------------- BEGIN my module code ---------------------
#define MODULE
#include <linux/module.h>
#include <asm/arch/hardware.h>
#include <asm/arch/pxa-regs.h>

#define P79_MASK (0x00008000)
int init_module(void){
        printk("vib: Hello\n");
        printk("vib: Before GPDR2=0x%x, MASK=0x%x\n",GPDR2,~P79_MASK);

        GPDR2 &= ~P79_MASK; // Set as input pin

        printk("vib: On? GPDR2=0x%x\n",GPDR2);
}

void cleanup_module(void){
        GPDR2 |= P79_MASK; //Set as output pin
        printk("<1>vib: Off? GPDR2=0x%x\n",GPDR2);
        printk("<1>vib: Goodbye\n");
}
-------------- END my module code ---------------------

Next, I tried to figure out what the initial state of the pin
was based on the bootldr code, using boot-pxa.s. The H5400_InitGPIO
section appears to have the relevant information. From what
I understand the registers are initialized:
    GAFR2_L (aka. GAFR0z) -- For alternate functions
    GPDR2 (aka. GPDRz) -- For direction
    GPSR2 (aka. GPSRz) -- For setting output pins high
    GPCR2 (aka. GPCRz) -- For clearing output pins
For Pin79, the initial values (starting at line 1725 of boot-pxa.s) appear
to
_not_ enable alternate functions, set it as an input pin and
set the line level to high (although this is apparently
irrelevant when set as an input pin). I added some printk's to
my module to dump some of the other registers with the following
result (note, GPSR and GPCR are write only) ...

-------------- BEGIN SNIP from 'dmesg' dump ------------------
vib: Hello
vib: Before GAFR2_L=0xa0000800, MASK=0x0
vib: Before GEDR2=0x0, MASK=0x0
vib: Before GFER2=0x0, MASK=0x0
vib: Before GRER2=0x0, MASK=0x0
vib: Before GPDR2=0xafdf, MASK=0xffff7fff
vib: Before GPLR2=0x1c1ccff, MASK=0x0
vib: On? GPDR2=0xafdf
-------------- END SNIP from 'dmesg' dump ------------------

Everything seemed to match the initial values with the exception of
the direction which get changed by the bootldr (GPLR2 is read-only
and used to deteremine what the line level is set to -- high as expected).

I'm stuck and probably reinventing the wheel. Does this functionality
already exist and I'm just missing something obvious? Am I missing
something
fundamental?

Any help is greatly appreciated,
Wants-vibes

_________________________________________________________________
FREE pop-up blocking with the new MSN Toolbar – get it now!
http://toolbar.msn.click-url.com/go/onm00200415ave/direct/01/
Received on Mon Jul 12 2004 - 16:10:29 EDT

This archive was generated by hypermail 2.2.0 : Mon Jul 25 2005 - 17:20:10 EDT