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

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

Revision 1.2, Sat Nov 24 19:07:07 2007 UTC (16 years, 5 months ago) by nbrk
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +11 -14 lines

change sapio to use register defined in at91sam7.h;
this eliminates ioaddr in sapio_dd

/*
 * $Id: sapio.c,v 1.2 2007/11/24 19:07:07 nbrk Exp $
 */
#include <sys/types.h>
#include <sys/device.h>
#include <sys/bus.h>
#include <sys/gpio.h>

#include <arch/sam7s64/dev/at91sam7.h>
#include <arch/sam7s64/dev/sapiovar.h>

/*
 * Parallel Input Output controller.
 */

int 			sapio_attach(struct device *, uint32_t, uint8_t);
uint8_t 		sapio_pinread(void *selfdd, uint32_t pin);
void 			sapio_pinwrite(void *selfdd, uint32_t pin, uint8_t data);
void 			sapio_pinset(void *selfdd, struct gpio_pin pin);
struct gpio_pin	sapio_pinget(void *selfdd, uint32_t pin);


struct driver sapio_dr = {
	sizeof(struct sapio_dd),
	sapio_attach,
	NULL,
	NULL
};


int
sapio_attach(struct device *self, uint32_t loc, uint8_t flags)
{
	struct sapio_dd *ddp = self->dv_devdata;
	struct gpio_controller *gcp = &ddp->pio_gc;

	/* acquire bus_handle from parent */
	ddp->pio_bhp = self->dv_parent->dv_aux;

	gcp->gc_pinread 	= sapio_pinread;
	gcp->gc_pinwrite 	= sapio_pinwrite;
	gcp->gc_pinset 		= sapio_pinset;
	gcp->gc_pinget 		= sapio_pinget;
	gcp->gc_npins 		= SAPIO_NPINS;
	gcp->gc_selfdd 		= ddp;

	/* export gpio_controller */
	self->dv_aux = gcp;

	printf("SAM7 Parallel Input/Output controller, %d pins\n", SAPIO_NPINS);
	
	return(0);
}


uint8_t
sapio_pinread(void *selfdd, uint32_t pin)
{
	/* TODO */
	return(0);
}


void
sapio_pinwrite(void *selfdd, uint32_t pin, uint8_t data)
{
	/* TODO */
}


void
sapio_pinset(void *selfdd, struct gpio_pin pin)
{
	struct sapio_dd *sdd = (struct sapio_dd *)selfdd;
	/*
	 * Configure pin.
	 */

	/* see if this i/o line is correct for us */
	if (sdd->pio_gc.gc_npins < (pin.gp_pinno + 1)) {
		/* out of range */
		printf("sapio_pinset: WARNING: pin no. %d doesn't present on this controller\n", pin.gp_pinno);

		return;
	}

	/* PIO or Periph. ? */
	if (pin.gp_pio == 0)
		bus_write_4(sdd->pio_bhp, (uint32_t)AT91C_PIOA_PDR, 1 << pin.gp_pinno);
	else
		bus_write_4(sdd->pio_bhp, (uint32_t)AT91C_PIOA_PER, 1 << pin.gp_pinno);

	/* flags */
	if (pin.gp_flags & GPIO_PIN_OUTPUT)
		/* enable output */
		bus_write_4(sdd->pio_bhp, (uint32_t)AT91C_PIOA_OER, 1 << pin.gp_pinno);
	else
		/* disable output */
		bus_write_4(sdd->pio_bhp, (uint32_t)AT91C_PIOA_ODR, 1 << pin.gp_pinno);

	/* data */
	if (pin.gp_value == 1)
		bus_write_4(sdd->pio_bhp, (uint32_t)AT91C_PIOA_SODR, 1 << pin.gp_pinno);
	else
		bus_write_4(sdd->pio_bhp, (uint32_t)AT91C_PIOA_CODR, 1 << pin.gp_pinno);
}


struct gpio_pin
sapio_pinget(void *selfdd, uint32_t pin)
{
	struct gpio_pin gp;
	struct sapio_dd *sdd = (struct sapio_dd *)selfdd;
	/*
	 * Get pin configuration.
	 */

	gp.gp_pinno = pin;

	/* see if this pin belongs to Peripherals (0) or to PIO (1) */
	gp.gp_pio = bus_read_4(sdd->pio_bhp, (uint32_t)AT91C_PIOA_PSR) & (1 << pin);

	/* get state through Output Status Register */
	gp.gp_flags = (bus_read_4(sdd->pio_bhp, (uint32_t)AT91C_PIOA_OSR) & (1 << pin)) ? 
					GPIO_PIN_INPUT | GPIO_PIN_OUTPUT : GPIO_PIN_INPUT; /* XXX how to determine input flag? */

	/* read value in Pin Data Status Register */
	gp.gp_value = bus_read_4(sdd->pio_bhp, (uint32_t)AT91C_PIOA_PDSR) & (1 << pin);

	return(gp);
}