1 /* 2 * Broadcom specific AMBA 3 * GPIO driver 4 * 5 * Copyright 2011, Broadcom Corporation 6 * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de> 7 * 8 * Licensed under the GNU/GPL. See COPYING for details. 9 */ 10 11 #include <linux/gpio.h> 12 #include <linux/export.h> 13 #include <linux/bcma/bcma.h> 14 15 #include "bcma_private.h" 16 17 static inline struct bcma_drv_cc *bcma_gpio_get_cc(struct gpio_chip *chip) 18 { 19 return container_of(chip, struct bcma_drv_cc, gpio); 20 } 21 22 static int bcma_gpio_get_value(struct gpio_chip *chip, unsigned gpio) 23 { 24 struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 25 26 return !!bcma_chipco_gpio_in(cc, 1 << gpio); 27 } 28 29 static void bcma_gpio_set_value(struct gpio_chip *chip, unsigned gpio, 30 int value) 31 { 32 struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 33 34 bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0); 35 } 36 37 static int bcma_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) 38 { 39 struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 40 41 bcma_chipco_gpio_outen(cc, 1 << gpio, 0); 42 return 0; 43 } 44 45 static int bcma_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, 46 int value) 47 { 48 struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 49 50 bcma_chipco_gpio_outen(cc, 1 << gpio, 1 << gpio); 51 bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0); 52 return 0; 53 } 54 55 static int bcma_gpio_request(struct gpio_chip *chip, unsigned gpio) 56 { 57 struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 58 59 bcma_chipco_gpio_control(cc, 1 << gpio, 0); 60 /* clear pulldown */ 61 bcma_chipco_gpio_pulldown(cc, 1 << gpio, 0); 62 /* Set pullup */ 63 bcma_chipco_gpio_pullup(cc, 1 << gpio, 1 << gpio); 64 65 return 0; 66 } 67 68 static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio) 69 { 70 struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 71 72 /* clear pullup */ 73 bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); 74 } 75 76 int bcma_gpio_init(struct bcma_drv_cc *cc) 77 { 78 struct gpio_chip *chip = &cc->gpio; 79 80 chip->label = "bcma_gpio"; 81 chip->owner = THIS_MODULE; 82 chip->request = bcma_gpio_request; 83 chip->free = bcma_gpio_free; 84 chip->get = bcma_gpio_get_value; 85 chip->set = bcma_gpio_set_value; 86 chip->direction_input = bcma_gpio_direction_input; 87 chip->direction_output = bcma_gpio_direction_output; 88 chip->ngpio = 16; 89 /* There is just one SoC in one device and its GPIO addresses should be 90 * deterministic to address them more easily. The other buses could get 91 * a random base number. */ 92 if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) 93 chip->base = 0; 94 else 95 chip->base = -1; 96 97 return gpiochip_add(chip); 98 } 99