mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 06:01:53 +02:00
intel-gpio for v5.11-1
* Refactor GPIO library to support bias and debounce ACPI settings The following is an automated git shortlog grouped by driver: gpiolib: - acpi: Make Intel GPIO tree official for GPIO ACPI work - acpi: Use BIT() macro to increase readability - acpi: Convert pin_index to be u16 - acpi: Extract acpi_request_own_gpiod() helper - acpi: Make acpi_gpio_to_gpiod_flags() usable for GpioInt() - acpi: Set initial value for output pin based on bias and polarity - acpi: Move acpi_gpio_to_gpiod_flags() upper in the code - acpi: Move non-critical code outside of critical section - acpi: Take into account debounce settings - acpi: Use named item for enum gpiod_flags variable - acpi: Respect bias settings for GpioInt() resource - Introduce gpio_set_debounce_timeout() for internal use - Extract gpio_set_config_with_argument_optional() helper - move bias related code from gpio_set_config() to gpio_set_bias() - Extract gpio_set_config_with_argument() for future use - use proper API to pack pin configuration parameters - add missed break statement - Replace unsigned by unsigned int Merge tag 'intel-pinctrl-v5.10-2' into HEAD: - Merge tag 'intel-pinctrl-v5.10-2' into HEAD pinctrl: - intel: Set default bias in case no particular value given - intel: Fix 2 kOhm bias which is 833 Ohm -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEqaflIX74DDDzMJJtb7wzTHR8rCgFAl+ymNoACgkQb7wzTHR8 rCg4hA//ehlYJqZZHccn6DCqk5n6K8jbSI7duuYMYLs4yapn1M+eJEfdDjLZdz8n aEFH+qyE2q/PiiRa2ZssvNvrH+nQIdFulADvM1El9BZAYE2CX1z5160JHl6iY1sj eENwCMM5N5Ob1KgRFHSnbVBYlcyeXyjp8ZZQPdOXH3CsFqc6SK4K3fEx+DkW3ctr QM0/jA1JA+Y+jNRpYmH4oheLwWKhezJ+nwVmi6Uw0iUpzqSSfl09JGFltWKAzNBP nEF3i8CakPx66NEjHkfKQnueqDWrdgapXDxcHTZ1O4UQJaNWPKxcU7ulQMULYC4W nlgiD9Td3/I8jsIjqrKy/SfrOrDZOjCgUAkKctCGOZ4xmvK0nYRrIq+Mt70782fK 3XZh4/KVDh4nhqjCRbLOZokmlwuQN1xOcxTOLMRX6UZ2BHcYn+dPP2q8RxUSnTQS ttlysCgT5oZcMzbNAzYZGcWjN6WuQTvbIebVS1q/6lG6cvbkehn3DcPb4CX8GSjU Srn8TUFh2B7dBOyZI2DXZLvNzs+QFzfJy1N9WIMo5pEIZ8I+rBb00OlP7HGONAx9 5jWxDREIHO+2Qy7yqewE88QtnDK9xIwtE5vL2mzHBx2zUX56nUDWYU8VuydzaZuH gBmNw3hue0xgDl64vSdSHoLJ1Ob8za0mEOnbF5mD4KAylnH3qf4= =YamF -----END PGP SIGNATURE----- Merge tag 'intel-gpio-v5.11-1' of gitolite.kernel.org:pub/scm/linux/kernel/git/andy/linux-gpio-intel into devel intel-gpio for v5.11-1 * Refactor GPIO library to support bias and debounce ACPI settings The following is an automated git shortlog grouped by driver: gpiolib: - acpi: Make Intel GPIO tree official for GPIO ACPI work - acpi: Use BIT() macro to increase readability - acpi: Convert pin_index to be u16 - acpi: Extract acpi_request_own_gpiod() helper - acpi: Make acpi_gpio_to_gpiod_flags() usable for GpioInt() - acpi: Set initial value for output pin based on bias and polarity - acpi: Move acpi_gpio_to_gpiod_flags() upper in the code - acpi: Move non-critical code outside of critical section - acpi: Take into account debounce settings - acpi: Use named item for enum gpiod_flags variable - acpi: Respect bias settings for GpioInt() resource - Introduce gpio_set_debounce_timeout() for internal use - Extract gpio_set_config_with_argument_optional() helper - move bias related code from gpio_set_config() to gpio_set_bias() - Extract gpio_set_config_with_argument() for future use - use proper API to pack pin configuration parameters - add missed break statement - Replace unsigned by unsigned int Merge tag 'intel-pinctrl-v5.10-2' into HEAD: - Merge tag 'intel-pinctrl-v5.10-2' into HEAD pinctrl: - intel: Set default bias in case no particular value given - intel: Fix 2 kOhm bias which is 833 Ohm
This commit is contained in:
commit
dc80a2717e
|
|
@ -7480,6 +7480,7 @@ M: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
|||
L: linux-gpio@vger.kernel.org
|
||||
L: linux-acpi@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git
|
||||
F: Documentation/firmware-guide/acpi/gpio-properties.rst
|
||||
F: drivers/gpio/gpiolib-acpi.c
|
||||
F: drivers/gpio/gpiolib-acpi.h
|
||||
|
|
|
|||
|
|
@ -205,6 +205,67 @@ static void acpi_gpiochip_request_irqs(struct acpi_gpio_chip *acpi_gpio)
|
|||
acpi_gpiochip_request_irq(acpi_gpio, event);
|
||||
}
|
||||
|
||||
static enum gpiod_flags
|
||||
acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio, int polarity)
|
||||
{
|
||||
/* GpioInt() implies input configuration */
|
||||
if (agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT)
|
||||
return GPIOD_IN;
|
||||
|
||||
switch (agpio->io_restriction) {
|
||||
case ACPI_IO_RESTRICT_INPUT:
|
||||
return GPIOD_IN;
|
||||
case ACPI_IO_RESTRICT_OUTPUT:
|
||||
/*
|
||||
* ACPI GPIO resources don't contain an initial value for the
|
||||
* GPIO. Therefore we deduce that value from the pull field
|
||||
* and the polarity instead. If the pin is pulled up we assume
|
||||
* default to be high, if it is pulled down we assume default
|
||||
* to be low, otherwise we leave pin untouched. For active low
|
||||
* polarity values will be switched. See also
|
||||
* Documentation/firmware-guide/acpi/gpio-properties.rst.
|
||||
*/
|
||||
switch (agpio->pin_config) {
|
||||
case ACPI_PIN_CONFIG_PULLUP:
|
||||
return polarity == GPIO_ACTIVE_LOW ? GPIOD_OUT_LOW : GPIOD_OUT_HIGH;
|
||||
case ACPI_PIN_CONFIG_PULLDOWN:
|
||||
return polarity == GPIO_ACTIVE_LOW ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume that the BIOS has configured the direction and pull
|
||||
* accordingly.
|
||||
*/
|
||||
return GPIOD_ASIS;
|
||||
}
|
||||
|
||||
static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip,
|
||||
struct acpi_resource_gpio *agpio,
|
||||
unsigned int index,
|
||||
const char *label)
|
||||
{
|
||||
int polarity = GPIO_ACTIVE_HIGH;
|
||||
enum gpiod_flags flags = acpi_gpio_to_gpiod_flags(agpio, polarity);
|
||||
unsigned int pin = agpio->pin_table[index];
|
||||
struct gpio_desc *desc;
|
||||
int ret;
|
||||
|
||||
desc = gpiochip_request_own_desc(chip, pin, label, polarity, flags);
|
||||
if (IS_ERR(desc))
|
||||
return desc;
|
||||
|
||||
ret = gpio_set_debounce_timeout(desc, agpio->debounce_timeout);
|
||||
if (ret)
|
||||
gpiochip_free_own_desc(desc);
|
||||
|
||||
return ret ? ERR_PTR(ret) : desc;
|
||||
}
|
||||
|
||||
static bool acpi_gpio_in_ignore_list(const char *controller_in, int pin_in)
|
||||
{
|
||||
const char *controller, *pin_str;
|
||||
|
|
@ -290,8 +351,7 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
|
|||
if (!handler)
|
||||
return AE_OK;
|
||||
|
||||
desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event",
|
||||
GPIO_ACTIVE_HIGH, GPIOD_IN);
|
||||
desc = acpi_request_own_gpiod(chip, agpio, 0, "ACPI:Event");
|
||||
if (IS_ERR(desc)) {
|
||||
dev_err(chip->parent,
|
||||
"Failed to request GPIO for pin 0x%04X, err %ld\n",
|
||||
|
|
@ -526,39 +586,6 @@ static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
|
|||
return false;
|
||||
}
|
||||
|
||||
static enum gpiod_flags
|
||||
acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio)
|
||||
{
|
||||
switch (agpio->io_restriction) {
|
||||
case ACPI_IO_RESTRICT_INPUT:
|
||||
return GPIOD_IN;
|
||||
case ACPI_IO_RESTRICT_OUTPUT:
|
||||
/*
|
||||
* ACPI GPIO resources don't contain an initial value for the
|
||||
* GPIO. Therefore we deduce that value from the pull field
|
||||
* instead. If the pin is pulled up we assume default to be
|
||||
* high, if it is pulled down we assume default to be low,
|
||||
* otherwise we leave pin untouched.
|
||||
*/
|
||||
switch (agpio->pin_config) {
|
||||
case ACPI_PIN_CONFIG_PULLUP:
|
||||
return GPIOD_OUT_HIGH;
|
||||
case ACPI_PIN_CONFIG_PULLDOWN:
|
||||
return GPIOD_OUT_LOW;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume that the BIOS has configured the direction and pull
|
||||
* accordingly.
|
||||
*/
|
||||
return GPIOD_ASIS;
|
||||
}
|
||||
|
||||
static int
|
||||
__acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update)
|
||||
{
|
||||
|
|
@ -633,7 +660,7 @@ int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
|
|||
struct acpi_gpio_lookup {
|
||||
struct acpi_gpio_info info;
|
||||
int index;
|
||||
int pin_index;
|
||||
u16 pin_index;
|
||||
bool active_low;
|
||||
struct gpio_desc *desc;
|
||||
int n;
|
||||
|
|
@ -649,7 +676,7 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data)
|
|||
if (!lookup->desc) {
|
||||
const struct acpi_resource_gpio *agpio = &ares->data.gpio;
|
||||
bool gpioint = agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
|
||||
int pin_index;
|
||||
u16 pin_index;
|
||||
|
||||
if (lookup->info.quirks & ACPI_GPIO_QUIRK_ONLY_GPIOIO && gpioint)
|
||||
lookup->index++;
|
||||
|
|
@ -664,6 +691,7 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data)
|
|||
lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
|
||||
agpio->pin_table[pin_index]);
|
||||
lookup->info.pin_config = agpio->pin_config;
|
||||
lookup->info.debounce = agpio->debounce_timeout;
|
||||
lookup->info.gpioint = gpioint;
|
||||
|
||||
/*
|
||||
|
|
@ -674,13 +702,13 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data)
|
|||
* - ACPI_ACTIVE_HIGH == GPIO_ACTIVE_HIGH
|
||||
*/
|
||||
if (lookup->info.gpioint) {
|
||||
lookup->info.flags = GPIOD_IN;
|
||||
lookup->info.polarity = agpio->polarity;
|
||||
lookup->info.triggering = agpio->triggering;
|
||||
} else {
|
||||
lookup->info.flags = acpi_gpio_to_gpiod_flags(agpio);
|
||||
lookup->info.polarity = lookup->active_low;
|
||||
}
|
||||
|
||||
lookup->info.flags = acpi_gpio_to_gpiod_flags(agpio, lookup->info.polarity);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
@ -794,7 +822,7 @@ static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
|
|||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
dev_dbg(&adev->dev, "GPIO: _DSD returned %s %d %d %u\n",
|
||||
dev_dbg(&adev->dev, "GPIO: _DSD returned %s %d %u %u\n",
|
||||
dev_name(&lookup.info.adev->dev), lookup.index,
|
||||
lookup.pin_index, lookup.active_low);
|
||||
} else {
|
||||
|
|
@ -942,6 +970,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
|
|||
|
||||
if (info.gpioint && idx++ == index) {
|
||||
unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
|
||||
enum gpiod_flags dflags = GPIOD_ASIS;
|
||||
char label[32];
|
||||
int irq;
|
||||
|
||||
|
|
@ -952,11 +981,18 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
|
|||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
acpi_gpio_update_gpiod_flags(&dflags, &info);
|
||||
acpi_gpio_update_gpiod_lookup_flags(&lflags, &info);
|
||||
|
||||
snprintf(label, sizeof(label), "GpioInt() %d", index);
|
||||
ret = gpiod_configure_flags(desc, label, lflags, info.flags);
|
||||
ret = gpiod_configure_flags(desc, label, lflags, dflags);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = gpio_set_debounce_timeout(desc, info.debounce);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
irq_flags = acpi_dev_get_irq_type(info.triggering,
|
||||
info.polarity);
|
||||
|
||||
|
|
@ -982,7 +1018,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
|
|||
struct gpio_chip *chip = achip->chip;
|
||||
struct acpi_resource_gpio *agpio;
|
||||
struct acpi_resource *ares;
|
||||
int pin_index = (int)address;
|
||||
u16 pin_index = address;
|
||||
acpi_status status;
|
||||
int length;
|
||||
int i;
|
||||
|
|
@ -1005,7 +1041,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
|
|||
return AE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
length = min(agpio->pin_table_length, (u16)(pin_index + bits));
|
||||
length = min_t(u16, agpio->pin_table_length, pin_index + bits);
|
||||
for (i = pin_index; i < length; ++i) {
|
||||
int pin = agpio->pin_table[i];
|
||||
struct acpi_gpio_connection *conn;
|
||||
|
|
@ -1042,23 +1078,18 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
|
|||
}
|
||||
|
||||
if (!found) {
|
||||
enum gpiod_flags flags = acpi_gpio_to_gpiod_flags(agpio);
|
||||
const char *label = "ACPI:OpRegion";
|
||||
|
||||
desc = gpiochip_request_own_desc(chip, pin, label,
|
||||
GPIO_ACTIVE_HIGH,
|
||||
flags);
|
||||
desc = acpi_request_own_gpiod(chip, agpio, i, "ACPI:OpRegion");
|
||||
if (IS_ERR(desc)) {
|
||||
status = AE_ERROR;
|
||||
mutex_unlock(&achip->conn_lock);
|
||||
status = AE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
conn = kzalloc(sizeof(*conn), GFP_KERNEL);
|
||||
if (!conn) {
|
||||
status = AE_NO_MEMORY;
|
||||
gpiochip_free_own_desc(desc);
|
||||
mutex_unlock(&achip->conn_lock);
|
||||
status = AE_NO_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -1070,8 +1101,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
|
|||
mutex_unlock(&achip->conn_lock);
|
||||
|
||||
if (function == ACPI_WRITE)
|
||||
gpiod_set_raw_value_cansleep(desc,
|
||||
!!((1 << i) & *value));
|
||||
gpiod_set_raw_value_cansleep(desc, !!(*value & BIT(i)));
|
||||
else
|
||||
*value |= (u64)gpiod_get_raw_value_cansleep(desc) << i;
|
||||
}
|
||||
|
|
@ -1132,7 +1162,7 @@ acpi_gpiochip_parse_own_gpio(struct acpi_gpio_chip *achip,
|
|||
int ret;
|
||||
|
||||
*lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
|
||||
*dflags = 0;
|
||||
*dflags = GPIOD_ASIS;
|
||||
*name = NULL;
|
||||
|
||||
ret = fwnode_property_read_u32_array(fwnode, "gpios", gpios,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ struct acpi_device;
|
|||
* @pin_config: pin bias as provided by ACPI
|
||||
* @polarity: interrupt polarity as provided by ACPI
|
||||
* @triggering: triggering type as provided by ACPI
|
||||
* @debounce: debounce timeout as provided by ACPI
|
||||
* @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping
|
||||
*/
|
||||
struct acpi_gpio_info {
|
||||
|
|
@ -27,6 +28,7 @@ struct acpi_gpio_info {
|
|||
int pin_config;
|
||||
int polarity;
|
||||
int triggering;
|
||||
unsigned int debounce;
|
||||
unsigned int quirks;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ static int gpiochip_find_base(int ngpio)
|
|||
int gpiod_get_direction(struct gpio_desc *desc)
|
||||
{
|
||||
struct gpio_chip *gc;
|
||||
unsigned offset;
|
||||
unsigned int offset;
|
||||
int ret;
|
||||
|
||||
gc = gpiod_to_chip(desc);
|
||||
|
|
@ -1333,7 +1333,7 @@ void gpiochip_irq_domain_deactivate(struct irq_domain *domain,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(gpiochip_irq_domain_deactivate);
|
||||
|
||||
static int gpiochip_to_irq(struct gpio_chip *gc, unsigned offset)
|
||||
static int gpiochip_to_irq(struct gpio_chip *gc, unsigned int offset)
|
||||
{
|
||||
struct irq_domain *domain = gc->irq.domain;
|
||||
|
||||
|
|
@ -1635,7 +1635,7 @@ static inline void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gc)
|
|||
* @gc: the gpiochip owning the GPIO
|
||||
* @offset: the offset of the GPIO to request for GPIO function
|
||||
*/
|
||||
int gpiochip_generic_request(struct gpio_chip *gc, unsigned offset)
|
||||
int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset)
|
||||
{
|
||||
#ifdef CONFIG_PINCTRL
|
||||
if (list_empty(&gc->gpiodev->pin_ranges))
|
||||
|
|
@ -1651,7 +1651,7 @@ EXPORT_SYMBOL_GPL(gpiochip_generic_request);
|
|||
* @gc: the gpiochip to request the gpio function for
|
||||
* @offset: the offset of the GPIO to free from GPIO function
|
||||
*/
|
||||
void gpiochip_generic_free(struct gpio_chip *gc, unsigned offset)
|
||||
void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset)
|
||||
{
|
||||
pinctrl_gpio_free(gc->gpiodev->base + offset);
|
||||
}
|
||||
|
|
@ -1663,7 +1663,7 @@ EXPORT_SYMBOL_GPL(gpiochip_generic_free);
|
|||
* @offset: the offset of the GPIO to apply the configuration
|
||||
* @config: the configuration to be applied
|
||||
*/
|
||||
int gpiochip_generic_config(struct gpio_chip *gc, unsigned offset,
|
||||
int gpiochip_generic_config(struct gpio_chip *gc, unsigned int offset,
|
||||
unsigned long config)
|
||||
{
|
||||
return pinctrl_gpio_set_config(gc->gpiodev->base + offset, config);
|
||||
|
|
@ -1993,7 +1993,7 @@ void gpiod_free(struct gpio_desc *desc)
|
|||
* help with diagnostics, and knowing that the signal is used as a GPIO
|
||||
* can help avoid accidentally multiplexing it to another controller.
|
||||
*/
|
||||
const char *gpiochip_is_requested(struct gpio_chip *gc, unsigned offset)
|
||||
const char *gpiochip_is_requested(struct gpio_chip *gc, unsigned int offset)
|
||||
{
|
||||
struct gpio_desc *desc;
|
||||
|
||||
|
|
@ -2093,30 +2093,49 @@ static int gpio_do_set_config(struct gpio_chip *gc, unsigned int offset,
|
|||
return gc->set_config(gc, offset, config);
|
||||
}
|
||||
|
||||
static int gpio_set_config(struct gpio_desc *desc, enum pin_config_param mode)
|
||||
static int gpio_set_config_with_argument(struct gpio_desc *desc,
|
||||
enum pin_config_param mode,
|
||||
u32 argument)
|
||||
{
|
||||
struct gpio_chip *gc = desc->gdev->chip;
|
||||
unsigned long config;
|
||||
unsigned arg;
|
||||
|
||||
config = pinconf_to_config_packed(mode, argument);
|
||||
return gpio_do_set_config(gc, gpio_chip_hwgpio(desc), config);
|
||||
}
|
||||
|
||||
static int gpio_set_config_with_argument_optional(struct gpio_desc *desc,
|
||||
enum pin_config_param mode,
|
||||
u32 argument)
|
||||
{
|
||||
struct device *dev = &desc->gdev->dev;
|
||||
int gpio = gpio_chip_hwgpio(desc);
|
||||
int ret;
|
||||
|
||||
ret = gpio_set_config_with_argument(desc, mode, argument);
|
||||
if (ret != -ENOTSUPP)
|
||||
return ret;
|
||||
|
||||
switch (mode) {
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
arg = 1;
|
||||
case PIN_CONFIG_PERSIST_STATE:
|
||||
dev_dbg(dev, "Persistence not supported for GPIO %d\n", gpio);
|
||||
break;
|
||||
|
||||
default:
|
||||
arg = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
config = PIN_CONF_PACKED(mode, arg);
|
||||
return gpio_do_set_config(gc, gpio_chip_hwgpio(desc), config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_set_config(struct gpio_desc *desc, enum pin_config_param mode)
|
||||
{
|
||||
return gpio_set_config_with_argument(desc, mode, 0);
|
||||
}
|
||||
|
||||
static int gpio_set_bias(struct gpio_desc *desc)
|
||||
{
|
||||
enum pin_config_param bias;
|
||||
int ret;
|
||||
unsigned int arg;
|
||||
|
||||
if (test_bit(FLAG_BIAS_DISABLE, &desc->flags))
|
||||
bias = PIN_CONFIG_BIAS_DISABLE;
|
||||
|
|
@ -2127,11 +2146,25 @@ static int gpio_set_bias(struct gpio_desc *desc)
|
|||
else
|
||||
return 0;
|
||||
|
||||
ret = gpio_set_config(desc, bias);
|
||||
if (ret != -ENOTSUPP)
|
||||
return ret;
|
||||
switch (bias) {
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
arg = 1;
|
||||
break;
|
||||
|
||||
return 0;
|
||||
default:
|
||||
arg = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return gpio_set_config_with_argument_optional(desc, bias, arg);
|
||||
}
|
||||
|
||||
int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce)
|
||||
{
|
||||
return gpio_set_config_with_argument_optional(desc,
|
||||
PIN_CONFIG_INPUT_DEBOUNCE,
|
||||
debounce);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2353,7 +2386,7 @@ EXPORT_SYMBOL_GPL(gpiod_set_config);
|
|||
* 0 on success, %-ENOTSUPP if the controller doesn't support setting the
|
||||
* debounce time.
|
||||
*/
|
||||
int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
|
||||
int gpiod_set_debounce(struct gpio_desc *desc, unsigned int debounce)
|
||||
{
|
||||
unsigned long config;
|
||||
|
||||
|
|
@ -2372,11 +2405,6 @@ EXPORT_SYMBOL_GPL(gpiod_set_debounce);
|
|||
*/
|
||||
int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
|
||||
{
|
||||
struct gpio_chip *gc;
|
||||
unsigned long packed;
|
||||
int gpio;
|
||||
int rc;
|
||||
|
||||
VALIDATE_DESC(desc);
|
||||
/*
|
||||
* Handle FLAG_TRANSITORY first, enabling queries to gpiolib for
|
||||
|
|
@ -2385,21 +2413,9 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
|
|||
assign_bit(FLAG_TRANSITORY, &desc->flags, transitory);
|
||||
|
||||
/* If the driver supports it, set the persistence state now */
|
||||
gc = desc->gdev->chip;
|
||||
if (!gc->set_config)
|
||||
return 0;
|
||||
|
||||
packed = pinconf_to_config_packed(PIN_CONFIG_PERSIST_STATE,
|
||||
!transitory);
|
||||
gpio = gpio_chip_hwgpio(desc);
|
||||
rc = gpio_do_set_config(gc, gpio, packed);
|
||||
if (rc == -ENOTSUPP) {
|
||||
dev_dbg(&desc->gdev->dev, "Persistence not supported for GPIO %d\n",
|
||||
gpio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return gpio_set_config_with_argument_optional(desc,
|
||||
PIN_CONFIG_PERSIST_STATE,
|
||||
!transitory);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpiod_set_transitory);
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ int gpiod_request(struct gpio_desc *desc, const char *label);
|
|||
void gpiod_free(struct gpio_desc *desc);
|
||||
int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
|
||||
unsigned long lflags, enum gpiod_flags dflags);
|
||||
int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce);
|
||||
int gpiod_hog(struct gpio_desc *desc, const char *name,
|
||||
unsigned long lflags, enum gpiod_flags dflags);
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ int gpiod_set_raw_array_value_cansleep(unsigned int array_size,
|
|||
unsigned long *value_bitmap);
|
||||
|
||||
int gpiod_set_config(struct gpio_desc *desc, unsigned long config);
|
||||
int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
|
||||
int gpiod_set_debounce(struct gpio_desc *desc, unsigned int debounce);
|
||||
int gpiod_set_transitory(struct gpio_desc *desc, bool transitory);
|
||||
void gpiod_toggle_active_low(struct gpio_desc *desc);
|
||||
|
||||
|
|
@ -481,7 +481,7 @@ static inline int gpiod_set_config(struct gpio_desc *desc, unsigned long config)
|
|||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
|
||||
static inline int gpiod_set_debounce(struct gpio_desc *desc, unsigned int debounce)
|
||||
{
|
||||
/* GPIO can never have been requested */
|
||||
WARN_ON(desc);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user