9
0
Fork 0

Merge branch 'for-next/gpio'

This commit is contained in:
Sascha Hauer 2013-12-06 08:22:48 +01:00
commit 2789ccd18f
4 changed files with 142 additions and 4 deletions

View File

@ -90,9 +90,18 @@ static int dw_gpio_direction_output(struct gpio_chip *gc,
return 0;
}
static int dw_gpio_get_direction(struct gpio_chip *gc, unsigned offset)
{
struct dw_gpio_instance *chip = to_dw_gpio(gc);
return (readl(chip->regs + DW_GPIO_DDR) & (1 << offset)) ?
GPIOF_DIR_OUT : GPIOF_DIR_IN;
}
static struct gpio_ops imx_gpio_ops = {
.direction_input = dw_gpio_direction_input,
.direction_output = dw_gpio_direction_output,
.get_direction = dw_gpio_get_direction,
.get = dw_gpio_get,
.set = dw_gpio_set,
};

View File

@ -85,6 +85,72 @@ void gpio_free(unsigned gpio)
free(gi->label);
}
/**
* gpio_request_one - request a single GPIO with initial configuration
* @gpio: the GPIO number
* @flags: GPIO configuration as specified by GPIOF_*
* @label: a literal description string of this GPIO
*/
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
{
int err;
err = gpio_request(gpio, label);
if (err)
return err;
if (flags & GPIOF_DIR_IN)
err = gpio_direction_input(gpio);
else
err = gpio_direction_output(gpio,
(flags & GPIOF_INIT_HIGH) ? 1 : 0);
if (err)
goto free_gpio;
return 0;
free_gpio:
gpio_free(gpio);
return err;
}
EXPORT_SYMBOL_GPL(gpio_request_one);
/**
* gpio_request_array - request multiple GPIOs in a single call
* @array: array of the 'struct gpio'
* @num: how many GPIOs in the array
*/
int gpio_request_array(const struct gpio *array, size_t num)
{
int i, err;
for (i = 0; i < num; i++, array++) {
err = gpio_request_one(array->gpio, array->flags, array->label);
if (err)
goto err_free;
}
return 0;
err_free:
while (i--)
gpio_free((--array)->gpio);
return err;
}
EXPORT_SYMBOL_GPL(gpio_request_array);
/**
* gpio_free_array - release multiple GPIOs in a single call
* @array: array of the 'struct gpio'
* @num: how many GPIOs in the array
*/
void gpio_free_array(const struct gpio *array, size_t num)
{
while (num--)
gpio_free((array++)->gpio);
}
EXPORT_SYMBOL_GPL(gpio_free_array);
void gpio_set_value(unsigned gpio, int value)
{
struct gpio_info *gi = gpio_to_desc(gpio);
@ -228,16 +294,34 @@ static int do_gpiolib(int argc, char *argv[])
int i;
printf("gpiolib: gpio lists\n");
printf("%*crequested label\n", 11, ' ');
for (i = 0; i < ARCH_NR_GPIOS; i++) {
struct gpio_info *gi = &gpio_desc[i];
int val = -1, dir = -1;
if (!gi->chip)
continue;
printf("gpio %*d: %*s %s\n", 4,
i, 9, gi->requested ? "true" : "false",
/* print chip information and header on first gpio */
if (gi->chip->base == i) {
printf("\ngpios %u-%u, chip %s:\n",
gi->chip->base,
gi->chip->base + gi->chip->ngpio - 1,
gi->chip->dev->name);
printf("%*cdir val requested label\n", 13, ' ');
}
if (gi->chip->ops->get_direction)
dir = gi->chip->ops->get_direction(gi->chip,
i - gi->chip->base);
if (gi->chip->ops->get)
val = gi->chip->ops->get(gi->chip,
i - gi->chip->base);
printf(" gpio %*d: %*s %*s %*s %s\n", 4, i,
3, (dir < 0) ? "unk" : ((dir == GPIOF_DIR_IN) ? "in" : "out"),
3, (val < 0) ? "unk" : ((val == 0) ? "lo" : "hi"),
9, gi->requested ? "true" : "false",
gi->label ? gi->label : "");
}

View File

@ -225,6 +225,8 @@ static void led_of_parse_trigger(struct led *led, struct device_node *np)
for (i = 0; i < ARRAY_SIZE(triggers); i++) {
struct led_trg *trg = &triggers[i];
if (!strcmp(trg->str, trigger)) {
/* disable LED before installing trigger */
led_set(led, 0);
led_set_trigger(trg->trg, led);
return;
}
@ -252,8 +254,8 @@ static int led_gpio_of_probe(struct device_d *dev)
dev_dbg(dev, "register led %s on gpio%d, active_low = %d\n",
gled->led.name, gled->gpio, gled->active_low);
led_of_parse_trigger(&gled->led, child);
led_gpio_register(gled);
led_of_parse_trigger(&gled->led, child);
}
return 0;

View File

@ -3,6 +3,28 @@
#include <asm/gpio.h>
#define GPIOF_DIR_OUT (0 << 0)
#define GPIOF_DIR_IN (1 << 0)
#define GPIOF_INIT_LOW (0 << 1)
#define GPIOF_INIT_HIGH (1 << 1)
#define GPIOF_IN (GPIOF_DIR_IN)
#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW)
#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
/**
* struct gpio - a structure describing a GPIO with configuration
* @gpio: the GPIO number
* @flags: GPIO configuration as specified by GPIOF_*
* @label: a literal description string of this GPIO
*/
struct gpio {
unsigned gpio;
unsigned long flags;
const char *label;
};
#ifndef CONFIG_GPIOLIB
static inline int gpio_request(unsigned gpio, const char *label)
{
@ -12,9 +34,29 @@ static inline int gpio_request(unsigned gpio, const char *label)
static inline void gpio_free(unsigned gpio)
{
}
static inline int gpio_request_one(unsigned gpio,
unsigned long flags, const char *label)
{
return -ENOSYS;
}
static inline int gpio_request_array(const struct gpio *array, size_t num)
{
return -ENOSYS;
}
static inline void gpio_free_array(const struct gpio *array, size_t num)
{
/* GPIO can never have been requested */
WARN_ON(1);
}
#else
int gpio_request(unsigned gpio, const char *label);
void gpio_free(unsigned gpio);
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
int gpio_request_array(const struct gpio *array, size_t num);
void gpio_free_array(const struct gpio *array, size_t num);
#endif
struct gpio_chip;
@ -24,6 +66,7 @@ struct gpio_ops {
void (*free)(struct gpio_chip *chip, unsigned offset);
int (*direction_input)(struct gpio_chip *chip, unsigned offset);
int (*direction_output)(struct gpio_chip *chip, unsigned offset, int value);
int (*get_direction)(struct gpio_chip *chip, unsigned offset);
int (*get)(struct gpio_chip *chip, unsigned offset);
void (*set)(struct gpio_chip *chip, unsigned offset, int value);
};