GPIO driver module for Jetway NF98 board
Josh Cartwright
joshc at linux.com
Wed Dec 21 20:21:54 EST 2011
(resend, sorry for spam)
On Wed, Dec 21, 2011 at 06:34:58PM +0100, Joan Pau Beltran wrote:
> Hi everyone,
>
> I did not find any existing driver for the GPIO port of the Jetway
> NF98 mini-itx board, so I would like to write a module for that,
> using the gpiolib interface.
>
> Since the board documentation does not include any information about
> the GPIOs, I contacted the Jetway support team. However, the only
> answer was the attached code for Windows (NF98GPIO.c).
> As you can see, it seems clear how to set the pin states for output,
> but not how to read them in input mode. I asked again and the
> response was (literally):
> >input sample code:
> >{
> >data= ISA_RW(GPIO_BASE[pin]+0x2,highlow<<pin,1,~(1<<pin));
> >}
> >//final exit SIO
> >outp(INDEX_PORT,0xaa);
> >return data;
> It makes no sense, and it is very upsetting.
> I would try to read from the same address used for output, but this
> is just an idea to be tested.
I think you're on the right track. In researching this board a little
more, I was able to uncover some information. For the sake of
learning, I've included my steps to discovery here:
>From Jetway's website (http://www.jetwaycomputer.com/NF98.html), I found
that the chipset used in the board is an Intel QM57.
Searching for datasheets for the Intel QM57 brought me to Intel's site
(http://www.intel.com/content/www/us/en/chipsets/5-chipset-3400-chipset-datasheet.html).
Searching the document for GPIO, I found section 5.15.4, "GPIO Registers
Lockdown". The content of the text portion of the section didn't seem
all that relevant, but there is a description of a register set that
seems to match up with the values in your attached example:
00h: GPIO_USE_SEL[31:0]
04h: GP_IO_SEL[31:0]
0Ch: GP_LVL[31:0]
28h: GPI_NMI_EN[15:0]
2Ch: GPI_INV[31:0]
30h: GPIO_USE_SEL2[63:32]
34h: GPI_IO_SEL2[63:32]
38h: GP_LVL2[63:32]
40h: GPIO_USE_SEL3[95:64]
44h: GPI_IO_SEL3[95:64]
48h: GP_LVL3[95:64]
60h: GP_RST_SEL[31:0]
64h: GP_RST_SEL2[63:32]
68h: GP_RST_SEL3[95:64]
Searching for the symbolic names brings up this document, which looks
like it may describe in more detail how to use this GPIO interface:
http://download.intel.com/embedded/chipsets/appnote/322174.pdf
> Since I have not written any kernel module before, after reading the
> pertinent documentation about memory management, i/o port access, and
> gpiolib, I have some questions.
>
> 1. How should I request/release the ports mentioned in the attached
> file? Should I use the request_region/release_region functions from
> linux/ioport.h? In such case, what should I do with the returned
> struct resource?
>
> 2. I suppose that I should use the same addresses given by the
> support team, although their code is for windows. Is it ok?
The above document seemed to insinuate that the actual IO region used
for GPIO access isn't statically allocated, but rather allocated during
PCI enumeration for a LPC device. If this is the case, you have an
additional question you need answered:
- What is the best way to get the base address for accessing these
GPIOs?
(the example code provided in the above document uses pci_get_device
which sounds clunky...)
Actually, with some further grepping I found that a lot of this
infrastructure may already be available to you. See
drivers/mfd/lpc_sch.c and drivers/gpio/sch_gpio.c. Not sure what it
would take to get it working with your setup, but it should give you a
good starting point.
> 3. Should/could I use the test_bit, set_bit, clear_bit functions to
> get, set the bit in the needed read/write functions I am writing? Or
> should I use the sequence 'inb - mask the value properly - outb' ?
Nope, as far as I know these bitops only work with memory operands.
> The second file attached is an skeleton of the module I am trying to
> write, any comments or suggestions are welcome.
(in the future, please inline any code you'd like reviewed)
Good luck!
--
joshc
More information about the Kernelnewbies
mailing list