/* * $Id: sapio.c,v 1.2 2007/11/24 19:07:07 nbrk Exp $ */ #include #include #include #include #include #include /* * 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); }