Merge branch 'for-next/gpio'
This commit is contained in:
commit
2789ccd18f
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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 : "");
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue