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;
|
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 = {
|
static struct gpio_ops imx_gpio_ops = {
|
||||||
.direction_input = dw_gpio_direction_input,
|
.direction_input = dw_gpio_direction_input,
|
||||||
.direction_output = dw_gpio_direction_output,
|
.direction_output = dw_gpio_direction_output,
|
||||||
|
.get_direction = dw_gpio_get_direction,
|
||||||
.get = dw_gpio_get,
|
.get = dw_gpio_get,
|
||||||
.set = dw_gpio_set,
|
.set = dw_gpio_set,
|
||||||
};
|
};
|
||||||
|
|
|
@ -85,6 +85,72 @@ void gpio_free(unsigned gpio)
|
||||||
free(gi->label);
|
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)
|
void gpio_set_value(unsigned gpio, int value)
|
||||||
{
|
{
|
||||||
struct gpio_info *gi = gpio_to_desc(gpio);
|
struct gpio_info *gi = gpio_to_desc(gpio);
|
||||||
|
@ -228,16 +294,34 @@ static int do_gpiolib(int argc, char *argv[])
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
printf("gpiolib: gpio lists\n");
|
printf("gpiolib: gpio lists\n");
|
||||||
printf("%*crequested label\n", 11, ' ');
|
|
||||||
|
|
||||||
for (i = 0; i < ARCH_NR_GPIOS; i++) {
|
for (i = 0; i < ARCH_NR_GPIOS; i++) {
|
||||||
struct gpio_info *gi = &gpio_desc[i];
|
struct gpio_info *gi = &gpio_desc[i];
|
||||||
|
int val = -1, dir = -1;
|
||||||
|
|
||||||
if (!gi->chip)
|
if (!gi->chip)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
printf("gpio %*d: %*s %s\n", 4,
|
/* print chip information and header on first gpio */
|
||||||
i, 9, gi->requested ? "true" : "false",
|
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 : "");
|
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++) {
|
for (i = 0; i < ARRAY_SIZE(triggers); i++) {
|
||||||
struct led_trg *trg = &triggers[i];
|
struct led_trg *trg = &triggers[i];
|
||||||
if (!strcmp(trg->str, trigger)) {
|
if (!strcmp(trg->str, trigger)) {
|
||||||
|
/* disable LED before installing trigger */
|
||||||
|
led_set(led, 0);
|
||||||
led_set_trigger(trg->trg, led);
|
led_set_trigger(trg->trg, led);
|
||||||
return;
|
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",
|
dev_dbg(dev, "register led %s on gpio%d, active_low = %d\n",
|
||||||
gled->led.name, gled->gpio, gled->active_low);
|
gled->led.name, gled->gpio, gled->active_low);
|
||||||
|
|
||||||
led_of_parse_trigger(&gled->led, child);
|
|
||||||
led_gpio_register(gled);
|
led_gpio_register(gled);
|
||||||
|
led_of_parse_trigger(&gled->led, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -3,6 +3,28 @@
|
||||||
|
|
||||||
#include <asm/gpio.h>
|
#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
|
#ifndef CONFIG_GPIOLIB
|
||||||
static inline int gpio_request(unsigned gpio, const char *label)
|
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 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
|
#else
|
||||||
int gpio_request(unsigned gpio, const char *label);
|
int gpio_request(unsigned gpio, const char *label);
|
||||||
void gpio_free(unsigned gpio);
|
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
|
#endif
|
||||||
|
|
||||||
struct gpio_chip;
|
struct gpio_chip;
|
||||||
|
@ -24,6 +66,7 @@ struct gpio_ops {
|
||||||
void (*free)(struct gpio_chip *chip, unsigned offset);
|
void (*free)(struct gpio_chip *chip, unsigned offset);
|
||||||
int (*direction_input)(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 (*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);
|
int (*get)(struct gpio_chip *chip, unsigned offset);
|
||||||
void (*set)(struct gpio_chip *chip, unsigned offset, int value);
|
void (*set)(struct gpio_chip *chip, unsigned offset, int value);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue