1 /* 2 * Copyright (c) 2016 Adam Barth 3 * 4 * Use of this source code is governed by a MIT-style 5 * license that can be found in the LICENSE file or at 6 * https://opensource.org/licenses/MIT 7 */ 8 #include <dev/gpio.h> 9 #include <errno.h> 10 #include <platform/bcm28xx.h> 11 #include <lk/reg.h> 12 13 #define NUM_PINS 54 14 #define BITS_PER_REG 32 15 #define BITS_PER_PIN 3 16 #define PINS_PER_REG (BITS_PER_REG / BITS_PER_PIN) 17 #define GPIOREG(base, nr) (REG32(base) + (nr / BITS_PER_REG)) 18 gpio_config(unsigned nr,unsigned flags)19int gpio_config(unsigned nr, unsigned flags) { 20 unsigned mask = 0x7; 21 if (nr >= NUM_PINS || flags & ~mask) 22 return -EINVAL; 23 unsigned register_number = nr / PINS_PER_REG; 24 unsigned offset = (nr % PINS_PER_REG) * BITS_PER_PIN; 25 unsigned shifted_mask = mask << offset; 26 volatile uint32_t *reg = REG32(GPIO_GPFSEL0) + register_number; 27 *reg = (*reg & ~shifted_mask) | (flags << offset); 28 return 0; 29 } 30 gpio_set(unsigned nr,unsigned on)31void gpio_set(unsigned nr, unsigned on) { 32 unsigned offset = nr % BITS_PER_REG; 33 *GPIOREG(on ? GPIO_GPSET0 : GPIO_GPCLR0, nr) = 1 << offset; 34 } 35 gpio_get(unsigned nr)36int gpio_get(unsigned nr) { 37 unsigned offset = nr % BITS_PER_REG; 38 return (*GPIOREG(GPIO_GPLEV0, nr) & (1 << offset)) >> offset; 39 } 40