From mboxrd@z Thu Jan 1 00:00:00 1970 From: joshc@linux.com (Josh Cartwright) Date: Wed, 21 Dec 2011 20:21:54 -0500 Subject: GPIO driver module for Jetway NF98 board In-Reply-To: <4EF218C2.3090807@uib.cat> References: <4EF218C2.3090807@uib.cat> Message-ID: <20111222012154.GB14353@joshcartwright.net> To: kernelnewbies@lists.kernelnewbies.org List-Id: kernelnewbies.lists.kernelnewbies.org (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< >} > >//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