[BACK]Return to gpiobtn.c CVS log [TXT][DIR] Up to [local] / funnyos / arch / sam7s64 / dev

File: [local] / funnyos / arch / sam7s64 / dev / gpiobtn.c (download)

Revision 1.1, Sun Dec 16 23:08:46 2007 UTC (16 years, 5 months ago) by nbrk
Branch: MAIN
CVS Tags: HEAD

driver for onboard buttons which occupy PA19 and PA20 lines.
this is very simple driver - it configures gpio pin on input
and toggles LED on every interrupt (when pressed) using devctl.

driver uses 'flags' on attachment to distinguish what minor instance of 'gpioled'
it should toggle. this allows two buttons to drive two leds :)

/*
 * $Id: gpiobtn.c,v 1.1 2007/12/16 23:08:46 nbrk Exp $
 */
#include <sys/types.h>
#include <sys/device.h>
#include <sys/gpio.h>
#include <sys/devctl.h>

#include <arch/sam7s64/dev/gpioledvar.h> /* for DCGPIOLED_TOGGLE */

/*
 * AT91SAM7S64 buttons.
 * There are two buttons: below green led and below yellow led;
 * first is on PA19 (13 pin) and generates FIQ,
 * second is on PA20 (16 pin) and generates an IRQ to the core.
 */

int 	gpiobtn_attach(struct device *, uint32_t, uint8_t);
void 	gpiobtn_interrupt(struct device *);

struct gpiobtn_dd {
	/* minor of 'gpioled' device which we will control */
	uint8_t 	gd_gpioledminor;
};

struct driver gpiobtn_dr = {
	sizeof(struct gpiobtn_dd),
	gpiobtn_attach,
	NULL,
	gpiobtn_interrupt
};


int
gpiobtn_attach(struct device *self, uint32_t loc, uint8_t flags)
{
	struct gpiobtn_dd *ddp = self->dv_devdata;
	struct gpio_controller *gcp = self->dv_parent->dv_aux;
	struct gpio_pin pin;

	pin.gp_pinno = loc;
	pin.gp_pio = 1; 	/* PIO mode */
	pin.gp_flags = GPIO_PIN_INPUT;

	/*
	 * we are provided with hint on which 'gpioled' device we will control.
	 * this hint is passed to us by devconfig as 'flags'.
	 */
	ddp->gd_gpioledminor = flags;

	printf("p64 onboard button (pio pin %d)\n", pin.gp_pinno);

	/* talk to gpio controller */
	gcp->gc_pinset(gcp->gc_selfdd, pin);

	return(0);
}


void
gpiobtn_interrupt(struct device *self)
{
	struct gpiobtn_dd *ddp = self->dv_devdata;
	/*
	 * Use devctl to toggle gpioled.
	 */

	devctl("gpioled", ddp->gd_gpioledminor, DCGPIOLED_TOGGLE, NULL);
}