mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-04 14:01:54 +00:00
These commands, like other users of GPIOs should be able to use the public GPIO API, and thus do not need to be coupled directly to the GPIO common code. Signed-off-by: Anton Staaf <robotboy@chromium.org> BRANCH=None BUG=None TEST=make buildall -j Manually verified console commands on discovery board Change-Id: I6e38b9d103590d4f7c72813a33437067716a858c Reviewed-on: https://chromium-review.googlesource.com/329992 Commit-Ready: Anton Staaf <robotboy@chromium.org> Tested-by: Anton Staaf <robotboy@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
140 lines
3.4 KiB
C
140 lines
3.4 KiB
C
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
/* GPIO common functionality for Chrome EC */
|
|
|
|
#include "common.h"
|
|
#include "gpio.h"
|
|
#include "registers.h"
|
|
#include "util.h"
|
|
|
|
/* GPIO alternate function structure */
|
|
struct gpio_alt_func {
|
|
/* Port base address */
|
|
uint32_t port;
|
|
|
|
/* Bitmask on that port (multiple bits allowed) */
|
|
uint32_t mask;
|
|
|
|
/* Alternate function number */
|
|
uint8_t func;
|
|
|
|
/* Module ID (as uint8_t, since enum would be 32-bit) */
|
|
uint8_t module_id;
|
|
|
|
/* Flags (GPIO_*; see above). */
|
|
uint16_t flags;
|
|
};
|
|
|
|
/*
|
|
* Construct the gpio_alt_funcs array. This array is used by gpio_config_module
|
|
* to enable and disable GPIO alternate functions on a module by module basis.
|
|
*/
|
|
#define ALTERNATE(pinmask, function, module, flags) \
|
|
{GPIO_##pinmask, function, module, flags},
|
|
|
|
static const struct gpio_alt_func gpio_alt_funcs[] = {
|
|
#include "gpio.wrap"
|
|
};
|
|
|
|
/*
|
|
* GPIO_CONFIG_ALL_PORTS signifies a "don't care" for the GPIO port. This is
|
|
* used in gpio_config_pins(). When the port parameter is set to this, the
|
|
* pin_mask parameter is ignored.
|
|
*/
|
|
#define GPIO_CONFIG_ALL_PORTS 0xFFFFFFFF
|
|
|
|
static int gpio_config_pins(enum module_id id,
|
|
uint32_t port,
|
|
uint32_t pin_mask,
|
|
int enable)
|
|
{
|
|
const struct gpio_alt_func *af;
|
|
int rv = EC_ERROR_INVAL;
|
|
|
|
/* Find pins and set to alternate functions */
|
|
for (af = gpio_alt_funcs;
|
|
af < gpio_alt_funcs + ARRAY_SIZE(gpio_alt_funcs);
|
|
af++) {
|
|
if (af->module_id != id)
|
|
continue; /* Pins for some other module */
|
|
|
|
/* Check to see if the requested port matches. */
|
|
if ((port != GPIO_CONFIG_ALL_PORTS) && (port != af->port))
|
|
continue;
|
|
|
|
/* If we don't care which port, enable all applicable pins. */
|
|
if (port == GPIO_CONFIG_ALL_PORTS)
|
|
pin_mask = af->mask;
|
|
|
|
if ((af->mask & pin_mask) == pin_mask) {
|
|
if (!(af->flags & GPIO_DEFAULT))
|
|
gpio_set_flags_by_mask(
|
|
af->port,
|
|
(af->mask & pin_mask),
|
|
enable ? af->flags : GPIO_INPUT);
|
|
gpio_set_alternate_function(
|
|
af->port,
|
|
(af->mask & pin_mask),
|
|
enable ? af->func : -1);
|
|
rv = EC_SUCCESS;
|
|
/* We're done here if we were just setting one port. */
|
|
if (port != GPIO_CONFIG_ALL_PORTS)
|
|
break;
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* GPIO API */
|
|
|
|
int gpio_config_module(enum module_id id, int enable)
|
|
{
|
|
/* Set all the alternate functions for this module. */
|
|
return gpio_config_pins(id, GPIO_CONFIG_ALL_PORTS, 0, enable);
|
|
}
|
|
|
|
int gpio_config_pin(enum module_id id, enum gpio_signal signal, int enable)
|
|
{
|
|
return gpio_config_pins(id,
|
|
gpio_list[signal].port,
|
|
gpio_list[signal].mask,
|
|
enable);
|
|
}
|
|
|
|
void gpio_set_flags(enum gpio_signal signal, int flags)
|
|
{
|
|
const struct gpio_info *g = gpio_list + signal;
|
|
|
|
gpio_set_flags_by_mask(g->port, g->mask, flags);
|
|
}
|
|
|
|
int gpio_get_default_flags(enum gpio_signal signal)
|
|
{
|
|
return gpio_list[signal].flags;
|
|
}
|
|
|
|
void gpio_reset(enum gpio_signal signal)
|
|
{
|
|
const struct gpio_info *g = gpio_list + signal;
|
|
|
|
gpio_set_flags_by_mask(g->port, g->mask, g->flags);
|
|
gpio_set_alternate_function(g->port, g->mask, -1);
|
|
}
|
|
|
|
const char *gpio_get_name(enum gpio_signal signal)
|
|
{
|
|
return gpio_list[signal].name;
|
|
}
|
|
|
|
int gpio_is_implemented(enum gpio_signal signal)
|
|
{
|
|
return !!gpio_list[signal].mask;
|
|
}
|
|
|
|
/*****************************************************************************/
|