Gpio cleanup #2 (#1530)

* pin repository: PIN_USED size in now equal to brain_pin_e enum size

expect special values...

* smart gpios: register gpio chip to given base (no auto-allocation)

* drivers: gpio: core: add gpiochip_unregister()

* drivers: gpio: MC33810 intergation

* smart_gpio.cpp: cleanup ifdef mess, minor cleanups

* gpio: core: additional check for gpio ranges overlaps

* unit test: gpio chip: fixed and extended
This commit is contained in:
Andrey G 2021-01-07 02:29:47 +03:00 committed by GitHub
parent 034412ef53
commit f96ae7525f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 227 additions and 201 deletions

View File

@ -364,6 +364,7 @@
#define BOARD_MC33972_COUNT 0
#define BOARD_TLE8888_COUNT 0
#define BOARD_DRV8860_COUNT 1
#define BOARD_MC33810_COUNT 0
#define DRV8860_SS_PORT GPIOH
#define DRV8860_SS_PAD 11U

View File

@ -212,8 +212,6 @@ typedef enum __attribute__ ((__packed__)) {
GPIOK_14 = 176,
GPIOK_15 = 177,
// DRV8860 pins go right after on chips
//#define DRV8860_PIN(n) ((brain_pin_e)((int)BRAIN_PIN_LAST_ONCHIP + 1 + (n)))
DRV8860_PIN_1 = 178,
DRV8860_PIN_2 = 179,
DRV8860_PIN_3 = 180,
@ -234,7 +232,10 @@ typedef enum __attribute__ ((__packed__)) {
} brain_pin_e;
/* Plase keep updating this define */
#define BRAIN_PIN_LAST_ONCHIP GPIOK_15
#define BRAIN_PIN_ONCHIP_LAST GPIOK_15
#define BRAIN_PIN_ONCHIP_PINS (BRAIN_PIN_ONCHIP_LAST - GPIOA_0 + 1)
#define BRAIN_PIN_LAST DRV8860_PIN_16
#define BRAIN_PIN_TOTAL_PINS (BRAIN_PIN_LAST - GPIOA_0 + 1)
/* diagnostic for brain pins
* can be combination of few bits

View File

@ -329,6 +329,7 @@
#define BOARD_MC33972_COUNT 0
#define BOARD_TLE8888_COUNT 0
#define BOARD_DRV8860_COUNT 0
#define BOARD_MC33810_COUNT 0
#define TLE6240_SS_PORT GPIOB
#define TLE6240_SS_PAD 0U

View File

@ -140,8 +140,11 @@ typedef enum __attribute__ ((__packed__)) {
} brain_pin_e;
/* Plase keep updating this define */
#define BRAIN_PIN_LAST_ONCHIP GPIOE_17
/* Plase keep updating these defines */
#define BRAIN_PIN_ONCHIP_LAST GPIOE_17
#define BRAIN_PIN_ONCHIP_PINS (BRAIN_PIN_ONCHIP_LAST - GPIOA_0 + 1)
#define BRAIN_PIN_LAST TLE6240_PIN_16
#define BRAIN_PIN_TOTAL_PINS (BRAIN_PIN_LAST - GPIOA_0 + 1)
/* diagnostic for brain pins
* can be combination of few bits

View File

@ -73,6 +73,10 @@
#define BOARD_TLE8888_COUNT 0
#endif
#ifndef BOARD_MC33810_COUNT
#define BOARD_MC33810_COUNT 0
#endif
#undef EFI_CONSOLE_TX_BRAIN_PIN
#define EFI_CONSOLE_TX_BRAIN_PIN GPIOA_0

View File

@ -171,6 +171,10 @@
#define BOARD_DRV8860_COUNT 0
#endif
#ifndef BOARD_MC33810_COUNT
#define BOARD_MC33810_COUNT 0
#endif
#define EFI_ANALOG_SENSORS TRUE
#ifndef EFI_MAX_31855

View File

@ -50,6 +50,10 @@
#define BOARD_TLE8888_COUNT 1
#endif
#ifndef BOARD_MC33810_COUNT
#define BOARD_MC33810_COUNT 0
#endif
#undef EFI_CAN_SUPPORT
#define EFI_CAN_SUPPORT TRUE

View File

@ -216,8 +216,11 @@ typedef enum __attribute__ ((__packed__)) {
TLE8888_PIN_WAKE = 198,
} brain_pin_e;
/* Plase keep updating this define */
#define BRAIN_PIN_LAST_ONCHIP GPIOH_15
/* Plase keep updating these defines */
#define BRAIN_PIN_ONCHIP_LAST GPIOH_15
#define BRAIN_PIN_ONCHIP_PINS (BRAIN_PIN_ONCHIP_LAST - GPIOA_0 + 1)
#define BRAIN_PIN_LAST TLE8888_PIN_WAKE
#define BRAIN_PIN_TOTAL_PINS (BRAIN_PIN_LAST - GPIOA_0 + 1)
/* diagnostic for brain pins
* can be combination of few bits

View File

@ -20,10 +20,6 @@
/* Local definitions. */
/*==========================================================================*/
/* fist available gpio number after on-chip gpios */
#define EXT_GPIOS_FIRST (BRAIN_PIN_LAST_ONCHIP + 1)
static brain_pin_e gpio_base_free = EXT_GPIOS_FIRST;
/*==========================================================================*/
/* Exported variables. */
/*==========================================================================*/
@ -118,11 +114,6 @@ const char *gpiochips_getPinName(brain_pin_e pin)
return NULL;
}
void gpiochip_use_gpio_base(int size) {
gpio_base_free += size;
}
/**
* @brief Register gpiochip
* @details should be called from board file. Can be called before os ready.
@ -132,19 +123,34 @@ void gpiochip_use_gpio_base(int size) {
* else returns chip base
*/
int gpiochip_register(const char *name, struct gpiochip_ops *ops, size_t size, void *priv)
int gpiochip_register(brain_pin_e base, const char *name, struct gpiochip_ops *ops, size_t size, void *priv)
{
int i;
struct gpiochip *chip = NULL;
/* no ops provided, zero size? */
if ((!ops) || (!size))
return -1;
/* outside? */
if (((size_t)base + size - 1 > BRAIN_PIN_LAST) || (base <= BRAIN_PIN_ONCHIP_LAST))
return -1;
/* no 'writePad' and no 'readPad' implementation? return error code */
if ((!ops->writePad) && (!ops->readPad))
return -1;
/* check for overlap with other chips */
for (i = 0; i < BOARD_EXT_GPIOCHIPS; i++) {
if (chips[i].base != 0) {
#define in_range(a, b, c) (((a) > (b)) && ((a) < (c)))
if (in_range(base, chips[i].base, chips[i].base + chips[i].size))
return -1;
if (in_range(base + size, chips[i].base, chips[i].base + chips[i].size))
return -1;
}
}
struct gpiochip *chip = NULL;
/* find free gpiochip struct */
for (i = 0; i < BOARD_EXT_GPIOCHIPS; i++) {
if (chips[i].base == 0) {
@ -161,24 +167,52 @@ int gpiochip_register(const char *name, struct gpiochip_ops *ops, size_t size, v
/* register chip */
chip->name = name;
chip->ops = ops;
chip->base = gpio_base_free;
chip->base = base;
chip->size = size;
chip->gpio_names = NULL;
chip->priv = priv;
gpiochip_use_gpio_base(size);
return (chip->base);
}
/**
* @brief Unregister gpiochip
* @details removes chip from list
* TODO: call deinit?
*/
int gpiochip_unregister(brain_pin_e base)
{
struct gpiochip *chip = gpiochip_find(base);
if (!chip)
return -1;
/* gpiochip_find - returns chip if base within its range, but we need it to be base */
if (chip->base != base)
return -1;
/* unregister chip */
chip->name = NULL;
chip->ops = NULL;
chip->base = 0;
chip->size = 0;
chip->gpio_names = NULL;
chip->priv = NULL;
return 0;
}
/**
* @brief Set pins names for registered gpiochip
* @details should be called after chip registration. May be called several times
* Names array size should be aqual to chip gpio count
*/
int gpiochips_setPinNames(brain_pin_e pin, const char **names)
int gpiochips_setPinNames(brain_pin_e base, const char **names)
{
struct gpiochip *chip = gpiochip_find(pin);
struct gpiochip *chip = gpiochip_find(base);
if (!chip)
return -1;
@ -314,7 +348,19 @@ brain_pin_diag_e gpiochips_getDiag(brain_pin_e pin)
int gpiochips_get_total_pins(void)
{
return (gpio_base_free - EXT_GPIOS_FIRST);
int i;
int cnt = 0;
for (i = 0; i < BOARD_EXT_GPIOCHIPS; i++) {
struct gpiochip *chip = &chips[i];
if (!chip->base)
continue;
cnt += chip->size;
}
return cnt;
}
#else /* BOARD_EXT_GPIOCHIPS > 0 */
@ -337,14 +383,9 @@ const char *gpiochips_getPinName(brain_pin_e pin) {
return NULL;
}
void gpiochip_use_gpio_base(int size)
int gpiochip_register(brain_pin_e base, const char *name, struct gpiochip_ops *ops, size_t size, void *priv)
{
(void)size;
}
int gpiochip_register(const char *name, struct gpiochip_ops *ops, size_t size, void *priv)
{
(void)name; (void)ops; (void)size; (void)priv;
(void)base; (void)name; (void)ops; (void)size; (void)priv;
return 0;
}

View File

@ -252,7 +252,7 @@ struct gpiochip_ops drv8860_ops = {
* @details Checks for valid config
*/
int drv8860_add(unsigned int index, const struct drv8860_config *cfg) {
int drv8860_add(brain_pin_e base, unsigned int index, const struct drv8860_config *cfg) {
int i;
int ret;
struct drv8860_priv *chip;
@ -278,7 +278,9 @@ int drv8860_add(unsigned int index, const struct drv8860_config *cfg) {
chip->drv_state = DRV8860_WAIT_INIT;
/* register, return gpio chip base */
ret = gpiochip_register(DRIVER_NAME, &drv8860_ops, DRV8860_OUTPUTS, chip);
ret = gpiochip_register(base, DRIVER_NAME, &drv8860_ops, DRV8860_OUTPUTS, chip);
if (ret < 0)
return ret;
/* set default pin names, board init code can rewrite */
gpiochips_setPinNames(ret, drv8860_pin_names);
@ -288,8 +290,8 @@ int drv8860_add(unsigned int index, const struct drv8860_config *cfg) {
#else /* BOARD_DRV8860_COUNT > 0 */
int drv8860_add(unsigned int index, const struct drv8860_config *cfg) {
(void)index; (void)cfg;
int drv8860_add(brain_pin_e base, unsigned int index, const struct drv8860_config *cfg) {
(void)base; (void)index; (void)cfg;
return -1;
}

View File

@ -34,7 +34,7 @@ extern "C"
{
#endif /* __cplusplus */
int drv8860_add(unsigned int index, const struct drv8860_config *cfg);
int drv8860_add(brain_pin_e base, unsigned int index, const struct drv8860_config *cfg);
#ifdef __cplusplus
}

View File

@ -38,13 +38,12 @@ int gpiochips_getPinOffset(brain_pin_e pin);
const char *gpiochips_getChipName(brain_pin_e pin);
const char *gpiochips_getPinName(brain_pin_e pin);
/* register GPIO chip */
int gpiochip_register(const char *name, struct gpiochip_ops *ops, size_t size, void *priv);
void gpiochip_use_gpio_base(int size);
/* register/unregister GPIO chip */
int gpiochip_register(brain_pin_e base, const char *name, struct gpiochip_ops *ops, size_t size, void *priv);
int gpiochip_unregister(brain_pin_e base);
/* Set individual names for pins */
int gpiochips_setPinNames(brain_pin_e pin, const char **names);
int gpiochips_setPinNames(brain_pin_e base, const char **names);
/* gpio extenders subsystem init */
int gpiochips_init(void);

View File

@ -523,7 +523,7 @@ struct gpiochip_ops mc33810_ops = {
* @details Checks for valid config
*/
int mc33810_add(unsigned int index, const struct mc33810_config *cfg)
int mc33810_add(unsigned int index, const struct mc33810_config *cfg, brain_pin_e base)
{
int i;
int ret;
@ -560,7 +560,7 @@ int mc33810_add(unsigned int index, const struct mc33810_config *cfg)
return -1;
/* register, return gpio chip base */
ret = gpiochip_register(DRIVER_NAME, &mc33810_ops, MC33810_OUTPUTS, chip);
ret = gpiochip_register(base, DRIVER_NAME, &mc33810_ops, MC33810_OUTPUTS, chip);
if (ret < 0)
return ret;
@ -574,9 +574,9 @@ int mc33810_add(unsigned int index, const struct mc33810_config *cfg)
#else /* BOARD_MC33810_COUNT > 0 */
int mc33810_add(unsigned int index, const struct mc33810_config *cfg)
int mc33810_add(brain_pin_e base, unsigned int index, const struct mc33810_config *cfg)
{
(void)index; (void)cfg;
(void)base; (void)index; (void)cfg;
return -1;
}

View File

@ -40,7 +40,7 @@ extern "C"
{
#endif /* __cplusplus */
int mc33810_add(unsigned int index, const struct mc33810_config *cfg);
int mc33810_add(brain_pin_e base, unsigned int index, const struct mc33810_config *cfg);
#ifdef __cplusplus
}

View File

@ -332,7 +332,7 @@ struct gpiochip_ops mc33972_ops = {
* @details Checks for valid config
*/
int mc33972_add(unsigned int index, const struct mc33972_config *cfg)
int mc33972_add(brain_pin_e base, unsigned int index, const struct mc33972_config *cfg)
{
struct mc33972_priv *chip;
@ -357,14 +357,14 @@ int mc33972_add(unsigned int index, const struct mc33972_config *cfg)
chip->drv_state = MC33972_WAIT_INIT;
/* register, return gpio chip base */
return gpiochip_register(DRIVER_NAME, &mc33972_ops, MC33972_INPUTS, chip);
return gpiochip_register(base, DRIVER_NAME, &mc33972_ops, MC33972_INPUTS, chip);
}
#else /* BOARD_MC33972_COUNT > 0 */
int mc33972_add(unsigned int index, const struct mc33972_config *cfg)
int mc33972_add(brain_pin_e base, unsigned int index, const struct mc33972_config *cfg)
{
(void)index; (void)cfg;
(void)base; (void)index; (void)cfg;
return -1;
}

View File

@ -27,7 +27,7 @@ extern "C"
{
#endif /* __cplusplus */
int mc33972_add(unsigned int index, const struct mc33972_config *cfg);
int mc33972_add(brain_pin_e base, unsigned int index, const struct mc33972_config *cfg);
#ifdef __cplusplus
}

View File

@ -478,7 +478,7 @@ struct gpiochip_ops tle6240_ops = {
* @details Checks for valid config
*/
int tle6240_add(unsigned int index, const struct tle6240_config *cfg)
int tle6240_add(brain_pin_e base, unsigned int index, const struct tle6240_config *cfg)
{
int i;
int ret;
@ -512,19 +512,21 @@ int tle6240_add(unsigned int index, const struct tle6240_config *cfg)
chip->drv_state = TLE6240_WAIT_INIT;
/* register, return gpio chip base */
ret = gpiochip_register(DRIVER_NAME, &tle6240_ops, TLE6240_OUTPUTS, chip);
ret = gpiochip_register(base, DRIVER_NAME, &tle6240_ops, TLE6240_OUTPUTS, chip);
if (ret < 0)
return ret;
/* set default pin names, board init code can rewrite */
gpiochips_setPinNames(ret, tle6240_pin_names);
gpiochips_setPinNames(base, tle6240_pin_names);
return ret;
}
#else /* BOARD_TLE6240_COUNT > 0 */
int tle6240_add(unsigned int index, const struct tle6240_config *cfg)
int tle6240_add(brain_pin_e base, unsigned int index, const struct tle6240_config *cfg)
{
(void)index; (void)cfg;
(void)base; (void)index; (void)cfg;
return -1;
}

View File

@ -36,7 +36,7 @@ extern "C"
{
#endif /* __cplusplus */
int tle6240_add(unsigned int index, const struct tle6240_config *cfg);
int tle6240_add(brain_pin_e base, unsigned int index, const struct tle6240_config *cfg);
#ifdef __cplusplus
}

View File

@ -1237,7 +1237,7 @@ struct gpiochip_ops tle8888_ops = {
* @return return gpio chip base
*/
int tle8888_add(unsigned int index, const struct tle8888_config *cfg) {
int tle8888_add(brain_pin_e base, unsigned int index, const struct tle8888_config *cfg) {
efiAssert(OBD_PCM_Processor_Fault, cfg != NULL, "8888CFG", 0)
@ -1262,11 +1262,13 @@ int tle8888_add(unsigned int index, const struct tle8888_config *cfg) {
chip->o_data_cached = 0;
chip->drv_state = TLE8888_WAIT_INIT;
/* register, return gpio chip base */
int ret = gpiochip_register(DRIVER_NAME, &tle8888_ops, TLE8888_SIGNALS, chip);
/* register */
int ret = gpiochip_register(base, DRIVER_NAME, &tle8888_ops, TLE8888_OUTPUTS, chip);
if (ret < 0)
return ret;
/* set default pin names, board init code can rewrite */
gpiochips_setPinNames(ret, tle8888_pin_names);
gpiochips_setPinNames(base, tle8888_pin_names);
return ret;
}
@ -1291,9 +1293,9 @@ void tle8888_req_init(void)
#else /* BOARD_TLE8888_COUNT > 0 */
int tle8888_add(unsigned int index, const struct tle8888_config *cfg)
int tle8888_add(brain_pin_e base, unsigned int index, const struct tle8888_config *cfg)
{
(void)index; (void)cfg;
(void)base; (void)index; (void)cfg;
return -1;
}

View File

@ -78,7 +78,7 @@ extern "C"
/**
* @return return gpio chip base
*/
int tle8888_add(unsigned int index, const struct tle8888_config *cfg);
int tle8888_add(brain_pin_e base, unsigned int index, const struct tle8888_config *cfg);
/* debug */
void tle8888_read_reg(uint16_t reg, uint16_t *val);

View File

@ -27,64 +27,25 @@ static PinRepository pinRepository;
static int brainPin_to_index(brain_pin_e brainPin)
{
int index;
unsigned int i;
if (brainPin < GPIOA_0)
return -1;
index = brainPin - GPIOA_0;
i = brainPin - GPIOA_0;
if ((unsigned)index < getNumBrainPins())
return index;
/* gpiochips magic: skip gates for absent chips */
#ifdef TLE8888_PIN_1
if ((brainPin >= TLE8888_PIN_1) && (BOARD_TLE8888_COUNT == 0))
index -= (TLE8888_PIN_28 -TLE8888_PIN_1 + 1);
#endif
#ifdef MC33972_PIN_1
if ((brainPin >= MC33972_PIN_1) && (BOARD_MC33972_COUNT == 0))
index -= (MC33972_PIN_22 - MC33972_PIN_1 + 1);
#endif
#ifdef TLE6240_PIN_1
if ((brainPin >= TLE6240_PIN_1) && (BOARD_TLE6240_COUNT == 0))
index -= (TLE6240_PIN_16 - TLE6240_PIN_1 + 1);
#endif
/* if index outside array boundary */
if ((unsigned)index >= getNumBrainPins() + BOARD_EXT_PINREPOPINS)
if (i >= getBrainPinTotalNum())
return -1;
return index;
return i;
}
static brain_pin_e index_to_brainPin(unsigned int i)
{
brain_pin_e brainPin = (brain_pin_e)((int)GPIOA_0 + i);
if (i < getBrainPinTotalNum())
return (brain_pin_e)((int)GPIOA_0 + i);;
/* on-chip pins */
if (i < getNumBrainPins())
return brainPin;
/* gpiochips magic: skip absent chips */
#ifdef TLE6240_PIN_1
if (BOARD_TLE6240_COUNT == 0)
brainPin += (TLE6240_PIN_16 - TLE6240_PIN_1 + 1);
#endif
#ifdef MC33972_PIN_1
if (BOARD_MC33972_COUNT == 0)
brainPin += (MC33972_PIN_22 - MC33972_PIN_1 + 1);
#endif
#ifdef TLE8888_PIN_1
if (BOARD_TLE8888_COUNT == 0)
brainPin += (TLE8888_PIN_28 -TLE8888_PIN_1 + 1);
#endif
return brainPin;
return GPIO_INVALID;
}
static MemoryStream portNameStream;
@ -115,21 +76,21 @@ void tle8888_dump_regs(void)
#endif
static void reportPins(void) {
for (unsigned int i = 0; i < getNumBrainPins(); i++) {
for (unsigned int i = 0; i < getBrainPinOnchipNum(); i++) {
const char *pin_user = getBrainUsedPin(i);
/* show used pins */
if (pin_user != NULL) {
brain_pin_e brainPin = index_to_brainPin(i);
int pin = getBrainPinIndex(brainPin);
ioportid_t port = getBrainPort(brainPin);
ioportid_t port = getBrainPinPort(brainPin);
scheduleMsg(&logger, "pin %s%d: %s", portname(port), pin, pin_user);
}
}
#if (BOARD_EXT_GPIOCHIPS > 0)
for (unsigned int i = getNumBrainPins() ; i < getNumBrainPins() + BOARD_EXT_PINREPOPINS /* gpiochips_get_total_pins()*/ ; i++) {
for (unsigned int i = getBrainPinOnchipNum() ; i < getBrainPinTotalNum(); i++) {
static char pin_error[64];
const char *pin_name;
const char *pin_user;
@ -231,7 +192,7 @@ void initPinRepository(void) {
bool brain_pin_is_onchip(brain_pin_e brainPin)
{
if ((brainPin < GPIOA_0) || (brainPin > BRAIN_PIN_LAST_ONCHIP))
if ((brainPin < GPIOA_0) || (brainPin > BRAIN_PIN_ONCHIP_LAST))
return false;
return true;
@ -239,7 +200,7 @@ bool brain_pin_is_onchip(brain_pin_e brainPin)
bool brain_pin_is_ext(brain_pin_e brainPin)
{
if (brainPin > BRAIN_PIN_LAST_ONCHIP)
if (brainPin > BRAIN_PIN_ONCHIP_LAST)
return true;
return false;
@ -299,7 +260,7 @@ void brain_pin_markUnused(brain_pin_e brainPin) {
*/
bool gpio_pin_markUsed(ioportid_t port, ioportmask_t pin, const char *msg) {
int index = getBrainIndex(port, pin);
int index = getPortPinIndex(port, pin);
if (getBrainUsedPin(index) != NULL) {
/**
@ -321,7 +282,7 @@ bool gpio_pin_markUsed(ioportid_t port, ioportmask_t pin, const char *msg) {
*/
void gpio_pin_markUnused(ioportid_t port, ioportmask_t pin) {
int index = getBrainIndex(port, pin);
int index = getPortPinIndex(port, pin);
if (getBrainUsedPin(index) != NULL)
pinRepository.totalPinsUsed--;

View File

@ -49,10 +49,11 @@ EXTERNC void gpio_pin_markUnused(ioportid_t port, ioportmask_t pin);
#endif /* EFI_PROD_CODE*/
/* defined in ports/ */
int getBrainIndex(ioportid_t port, ioportmask_t pin);
ioportid_t getBrainPort(brain_pin_e brainPin);
int getPortPinIndex(ioportid_t port, ioportmask_t pin);
ioportid_t getBrainPinPort(brain_pin_e brainPin);
int getBrainPinIndex(brain_pin_e brainPin);
unsigned int getNumBrainPins(void);
unsigned int getBrainPinOnchipNum(void);
unsigned int getBrainPinTotalNum(void);
void initBrainUsedPins(void);
#ifdef __cplusplus

View File

@ -33,9 +33,8 @@ static brain_pin_e portMap[16] = {
GPIOA_0, GPIOB_0, GPIOC_0, GPIOD_0, GPIOE_0, GPIOF_0, GPIO_INVALID, GPIOG_0, GPIO_INVALID, GPIO_INVALID, GPIOH_0, GPIOI_0, GPIOJ_0, GPIO_INVALID, GPIO_INVALID, GPIOK_0
};
#define PIN_REPO_SIZE (sizeof(ports) / sizeof(ports[0])) * PORT_SIZE
// todo: move this into PinRepository class
static const char *PIN_USED[PIN_REPO_SIZE + BOARD_EXT_PINREPOPINS];
static const char *PIN_USED[BRAIN_PIN_TOTAL_PINS];
#include "pin_repository.h"
#include "io_pins.h"
@ -97,7 +96,7 @@ static int getPortIndex(ioportid_t port) {
return -1;
}
ioportid_t getBrainPort(brain_pin_e brainPin) {
ioportid_t getBrainPinPort(brain_pin_e brainPin) {
return ports[(brainPin - GPIOA_0) / PORT_SIZE];
}
@ -105,7 +104,7 @@ int getBrainPinIndex(brain_pin_e brainPin) {
return (brainPin - GPIOA_0) % PORT_SIZE;
}
int getBrainIndex(ioportid_t port, ioportmask_t pin) {
int getBrainPinIndex(ioportid_t port, ioportmask_t pin) {
int portIndex = getPortIndex(port);
return portIndex * PORT_SIZE + pin;
}
@ -113,7 +112,7 @@ int getBrainIndex(ioportid_t port, ioportmask_t pin) {
ioportid_t getHwPort(const char *msg, brain_pin_e brainPin) {
if (brainPin == GPIO_UNASSIGNED || brainPin == GPIO_INVALID)
return GPIO_NULL;
if (brainPin < GPIOA_0 || brainPin > BRAIN_PIN_LAST_ONCHIP) {
if (brainPin < GPIOA_0 || brainPin > BRAIN_PIN_ONCHIP_LAST) {
firmwareError(CUSTOM_ERR_INVALID_PIN, "%s: Invalid brain_pin_e: %d", msg, brainPin);
return GPIO_NULL;
}
@ -165,8 +164,12 @@ brain_pin_e parseBrainPin(const char *str) {
return (brain_pin_e)(basePin + pin);
}
unsigned int getNumBrainPins(void) {
return PIN_REPO_SIZE;
unsigned int getBrainPinOnchipNum(void) {
return BRAIN_PIN_ONCHIP_PINS;
}
unsigned int getBrainPinTotalNum(void) {
return BRAIN_PIN_TOTAL_PINS;
}
void initBrainUsedPins(void) {
@ -174,6 +177,8 @@ void initBrainUsedPins(void) {
}
const char* & getBrainUsedPin(unsigned int idx) {
/*if (idx >= getBrainPinTotalNum())
return NULL;*/
return PIN_USED[idx];
}

View File

@ -13,6 +13,9 @@
#if EFI_GPIO_HARDWARE
// todo: move this into PinRepository class
static const char *PIN_USED[BRAIN_PIN_TOTAL_PINS];
// This is the radical departure from STM32
#define PORT_SIZE 18
@ -23,10 +26,6 @@ static ioportid_t ports[] = {GPIOA,
GPIOE
};
#define PIN_REPO_SIZE (sizeof(ports) / sizeof(ports[0])) * PORT_SIZE
// todo: move this into PinRepository class
static const char *PIN_USED[PIN_REPO_SIZE + BOARD_EXT_PINREPOPINS];
#include "pin_repository.h"
#include "io_pins.h"
@ -63,7 +62,7 @@ static int getPortIndex(ioportid_t port) {
return -1;
}
ioportid_t getBrainPort(brain_pin_e brainPin) {
ioportid_t getBrainPinPort(brain_pin_e brainPin) {
return ports[(brainPin - GPIOA_0) / PORT_SIZE];
}
@ -71,7 +70,7 @@ int getBrainPinIndex(brain_pin_e brainPin) {
return (brainPin - GPIOA_0) % PORT_SIZE;
}
int getBrainIndex(ioportid_t port, ioportmask_t pin) {
int getPortPinIndex(ioportid_t port, ioportmask_t pin) {
int portIndex = getPortIndex(port);
return portIndex * PORT_SIZE + pin;
}
@ -79,7 +78,7 @@ int getBrainIndex(ioportid_t port, ioportmask_t pin) {
ioportid_t getHwPort(const char *msg, brain_pin_e brainPin) {
if (brainPin == GPIO_UNASSIGNED || brainPin == GPIO_INVALID)
return GPIO_NULL;
if (brainPin < GPIOA_0 || brainPin > BRAIN_PIN_LAST_ONCHIP) {
if (brainPin < GPIOA_0 || brainPin > BRAIN_PIN_ONCHIP_LAST) {
firmwareError(CUSTOM_ERR_INVALID_PIN, "%s: Invalid brain_pin_e: %d", msg, brainPin);
return GPIO_NULL;
}
@ -127,8 +126,12 @@ brain_pin_e parseBrainPin(const char *str) {
return (brain_pin_e)(basePin + pin);
}
unsigned int getNumBrainPins(void) {
return PIN_REPO_SIZE;
unsigned int getBrainPinOnchipNum(void) {
return BRAIN_PIN_ONCHIP_PINS;
}
unsigned int getBrainPinTotalNum(void) {
return BRAIN_PIN_TOTAL_PINS;
}
void initBrainUsedPins(void) {
@ -136,6 +139,8 @@ void initBrainUsedPins(void) {
}
const char* & getBrainUsedPin(unsigned int idx) {
/* if (idx >= getBrainPinTotalNum())
return NULL; */
return PIN_USED[idx];
}

View File

@ -15,6 +15,9 @@
#if EFI_GPIO_HARDWARE
// todo: move this into PinRepository class
static const char *PIN_USED[BRAIN_PIN_TOTAL_PINS];
#define PORT_SIZE 16
static ioportid_t ports[] = {GPIOA,
@ -43,10 +46,6 @@ static ioportid_t ports[] = {GPIOA,
#endif /* STM32_HAS_GPIOH */
};
#define PIN_REPO_SIZE (sizeof(ports) / sizeof(ports[0])) * PORT_SIZE
// todo: move this into PinRepository class
static const char *PIN_USED[PIN_REPO_SIZE + BOARD_EXT_PINREPOPINS];
/**
* @deprecated - use hwPortname() instead
*/
@ -108,7 +107,7 @@ static int getPortIndex(ioportid_t port) {
return -1;
}
ioportid_t getBrainPort(brain_pin_e brainPin) {
ioportid_t getBrainPinPort(brain_pin_e brainPin) {
return ports[(brainPin - GPIOA_0) / PORT_SIZE];
}
@ -116,7 +115,7 @@ int getBrainPinIndex(brain_pin_e brainPin) {
return (brainPin - GPIOA_0) % PORT_SIZE;
}
int getBrainIndex(ioportid_t port, ioportmask_t pin) {
int getPortPinIndex(ioportid_t port, ioportmask_t pin) {
int portIndex = getPortIndex(port);
return portIndex * PORT_SIZE + pin;
}
@ -124,7 +123,7 @@ int getBrainIndex(ioportid_t port, ioportmask_t pin) {
ioportid_t getHwPort(const char *msg, brain_pin_e brainPin) {
if (brainPin == GPIO_UNASSIGNED || brainPin == GPIO_INVALID)
return GPIO_NULL;
if (brainPin < GPIOA_0 || brainPin > BRAIN_PIN_LAST_ONCHIP) {
if (brainPin < GPIOA_0 || brainPin > BRAIN_PIN_ONCHIP_LAST) {
firmwareError(CUSTOM_ERR_INVALID_PIN, "%s: Invalid brain_pin_e: %d", msg, brainPin);
return GPIO_NULL;
}
@ -172,8 +171,12 @@ brain_pin_e parseBrainPin(const char *str) {
return (brain_pin_e)(basePin + pin);
}
unsigned int getNumBrainPins(void) {
return PIN_REPO_SIZE;
unsigned int getBrainPinOnchipNum(void) {
return BRAIN_PIN_ONCHIP_PINS;
}
unsigned int getBrainPinTotalNum(void) {
return BRAIN_PIN_TOTAL_PINS;
}
void initBrainUsedPins(void) {
@ -181,6 +184,8 @@ void initBrainUsedPins(void) {
}
const char* & getBrainUsedPin(unsigned int idx) {
/* if (idx >= getBrainPinTotalNum())
return NULL; */
return PIN_USED[idx];
}

View File

@ -22,11 +22,8 @@
#include "drivers/gpio/drv8860.h"
EXTERN_CONFIG;
static OutputPin tle8888Cs;
static OutputPin tle6240Cs;
static OutputPin mc33972Cs;
static OutputPin drv8860Cs;
#if (BOARD_TLE6240_COUNT > 0)
// todo: migrate to TS or board config
#ifndef TLE6240_RESET_PORT
#define TLE6240_RESET_PORT GPIOG
@ -52,9 +49,9 @@ static OutputPin drv8860Cs;
[7] = {.port = GPIOC, .pad = 7},
#endif /* TLE6240_DIRECT_IO */
#if (BOARD_TLE6240_COUNT > 0)
static OutputPin tle6240Cs;
struct tle6240_config tle6240 = {
.spi_bus = NULL /* TODO software lookup &SPID4 */,
.spi_bus = NULL,
.spi_config = {
.circular = false,
.end_cb = NULL,
@ -80,8 +77,9 @@ struct tle6240_config tle6240 = {
#endif /* (BOARD_TLE6240_COUNT > 0) */
#if (BOARD_MC33972_COUNT > 0)
static OutputPin mc33972Cs;
struct mc33972_config mc33972 = {
.spi_bus = NULL /* TODO software lookup &SPID4 */,
.spi_bus = NULL,
.spi_config = {
.circular = false,
.end_cb = NULL,
@ -103,6 +101,7 @@ struct mc33972_config mc33972 = {
#endif /* (BOARD_MC33972_COUNT > 0) */
#if (BOARD_TLE8888_COUNT > 0)
static OutputPin tle8888Cs;
struct tle8888_config tle8888_cfg = {
.spi_bus = NULL,
.spi_config = {
@ -154,8 +153,9 @@ struct tle8888_config tle8888_cfg = {
#endif
#if (BOARD_DRV8860_COUNT > 0)
static OutputPin drv8860Cs;
struct drv8860_config drv8860 = {
.spi_bus = NULL /* TODO software lookup &SPID4 */,
.spi_bus = NULL,
.spi_config = {
.circular = false,
.end_cb = NULL,
@ -176,23 +176,17 @@ struct drv8860_config drv8860 = {
#endif /* (BOARD_DRV8860_COUNT > 0) */
void initSmartGpio() {
#if (BOARD_EXT_GPIOCHIPS > 0)
startSmartCsPins();
#endif /* BOARD_EXT_GPIOCHIPS */
int ret = -1;
#if (BOARD_TLE6240_COUNT > 0)
if (engineConfiguration->tle6240_cs != GPIO_UNASSIGNED) {
tle6240.spi_config.ssport = getHwPort("tle6240 CS", engineConfiguration->tle6240_cs);
tle6240.spi_config.sspad = getHwPin("tle6240 CS", engineConfiguration->tle6240_cs);
tle6240.spi_bus = getSpiDevice(engineConfiguration->tle6240spiDevice);
ret = tle6240_add(0, &tle6240);
} else {
ret = -1;
int ret = tle6240_add(TLE6240_PIN_1, 0, &tle6240);
efiAssertVoid(OBD_PCM_Processor_Fault, ret == TLE6240_PIN_1, "tle6240");
}
if (ret < 0)
/* whenever chip is disabled or error returned - occupy its gpio range */
gpiochip_use_gpio_base(TLE6240_OUTPUTS);
#endif /* (BOARD_TLE6240_COUNT > 0) */
#if (BOARD_MC33972_COUNT > 0)
@ -202,19 +196,14 @@ void initSmartGpio() {
mc33972.spi_config.sspad = getHwPin("mc33972 CS", engineConfiguration->mc33972_cs);
mc33972.spi_bus = getSpiDevice(engineConfiguration->mc33972spiDevice);
// todo: propogate 'basePinOffset' parameter
ret = mc33972_add(0, &mc33972);
} else {
ret = -1;
int ret = mc33972_add(MC33972_PIN_1, 0, &mc33972);
efiAssertVoid(OBD_PCM_Processor_Fault, ret == MC33972_PIN_1, "mc33972");
}
if (ret < 0)
/* whenever chip is disabled or error returned - occupy its gpio range */
gpiochip_use_gpio_base(MC33972_INPUTS);
#endif /* (BOARD_MC33972_COUNT > 0) */
#if (BOARD_TLE8888_COUNT > 0)
if (engineConfiguration->tle8888_cs != GPIO_UNASSIGNED) {
// SPI pins are enabled in initSpiModules()
// todo: reuse initSpiCs method?
tle8888_cfg.spi_config.ssport = getHwPort("tle8888 CS", engineConfiguration->tle8888_cs);
tle8888_cfg.spi_config.sspad = getHwPin("tle8888 CS", engineConfiguration->tle8888_cs);
@ -224,15 +213,10 @@ void initSmartGpio() {
tle8888_cfg.stepper = engineConfiguration->useTLE8888_stepper;
/* spi_bus == null checked in _add function */
ret = tle8888_add(0, &tle8888_cfg);
int ret = tle8888_add(TLE8888_PIN_1, 0, &tle8888_cfg);
efiAssertVoid(OBD_PCM_Processor_Fault, ret == TLE8888_PIN_1, "tle8888");
} else {
ret = -1;
}
if (ret < 0)
/* whenever chip is disabled or error returned - occupy its gpio range */
gpiochip_use_gpio_base(TLE8888_SIGNALS);
#endif /* (BOARD_TLE8888_COUNT > 0) */
#if (BOARD_DRV8860_COUNT > 0)
@ -240,24 +224,20 @@ void initSmartGpio() {
drv8860.spi_config.ssport = getHwPort("drv8860 CS", engineConfiguration->drv8860_cs);
drv8860.spi_config.sspad = getHwPin("drv8860 CS", engineConfiguration->drv8860_cs);
drv8860.spi_bus = getSpiDevice(engineConfiguration->drv8860spiDevice);
ret = drv8860_add(0, &drv8860);
int ret = drv8860_add(DRV8860_PIN_1, 0, &drv8860);
efiAssertVoid(OBD_PCM_Processor_Fault, ret == DRV8860_PIN_1, "drv8860");
} else {
ret = -1;
}
if (ret < 0)
/* whenever chip is disabled or error returned - occupy its gpio range */
gpiochip_use_gpio_base(DRV8860_OUTPUTS);
#endif /* (BOARD_DRV8860_COUNT > 0) */
#if (BOARD_EXT_GPIOCHIPS > 0)
#if (BOARD_MC33810_COUNT > 0)
/* none of official boards has this IC */
#endif /* (BOARD_MC33810_COUNT > 0) */
/* external chip init */
gpiochips_init();
#endif /* (BOARD_EXT_GPIOCHIPS > 0) */
}
#if (BOARD_EXT_GPIOCHIPS > 0)
void stopSmartCsPins() {
#if (BOARD_TLE8888_COUNT > 0)
efiSetPadUnused(activeConfiguration.tle8888_cs);
@ -271,6 +251,9 @@ void stopSmartCsPins() {
#if (BOARD_DRV8860_COUNT > 0)
efiSetPadUnused(activeConfiguration.drv8860_cs);
#endif /* BOARD_DRV8860_COUNT */
#if (BOARD_MC33810_COUNT > 0)
/* none of official boards has this IC */
#endif /* (BOARD_MC33810_COUNT > 0) */
}
void startSmartCsPins() {
@ -294,7 +277,9 @@ void startSmartCsPins() {
&engineConfiguration->drv8860_csPinMode);
drv8860Cs.setValue(true);
#endif /* BOARD_DRV8860_COUNT */
#if (BOARD_MC33810_COUNT > 0)
/* none of official boards has this IC */
#endif /* (BOARD_MC33810_COUNT > 0) */
}
#endif /* (BOARD_EXT_GPIOCHIPS > 0) */
#endif /* EFI_PROD_CODE */

View File

@ -13,21 +13,12 @@
#include "drivers/gpio/mc33972.h"
#include "drivers/gpio/tle8888.h"
#include "drivers/gpio/drv8860.h"
#define BOARD_EXT_PINREPOPINS (\
BOARD_TLE6240_COUNT * TLE6240_OUTPUTS + \
BOARD_MC33972_COUNT * MC33972_INPUTS + \
BOARD_TLE8888_COUNT * TLE8888_OUTPUTS + \
BOARD_DRV8860_COUNT * DRV8860_OUTPUTS)
#else /* EFI_PROD_CODE */
#define BOARD_EXT_PINREPOPINS 0
#endif /* EFI_PROD_CODE */
#if EFI_UNIT_TEST
#define BOARD_EXT_GPIOCHIPS 3
#else
#define BOARD_EXT_GPIOCHIPS (BOARD_TLE6240_COUNT + BOARD_MC33972_COUNT + BOARD_TLE8888_COUNT + BOARD_DRV8860_COUNT)
#define BOARD_EXT_GPIOCHIPS (BOARD_TLE6240_COUNT + BOARD_MC33972_COUNT + BOARD_TLE8888_COUNT + BOARD_DRV8860_COUNT + BOARD_MC33810_COUNT)
#endif
void initSmartGpio(void);

View File

@ -97,21 +97,27 @@ TEST(gpioext, testGpioExt) {
printf("====================================================================================== testGpioExt\r\n");
/* should fail to register chip with no readPad and writePad */
EXPECT_FALSE(gpiochip_register("invalid", &testchip0, 16, NULL) > 0);
EXPECT_FALSE(gpiochip_register((brain_pin_e)(BRAIN_PIN_ONCHIP_LAST + 1), "invalid", &testchip0, 16, NULL) > 0);
/* should fail to register chip with zero gpios */
EXPECT_FALSE(gpiochip_register("invalid", &testchip1, 0, NULL) > 0);
EXPECT_FALSE(gpiochip_register((brain_pin_e)(BRAIN_PIN_ONCHIP_LAST + 1), "invalid", &testchip1, 0, NULL) > 0);
chip1_base = gpiochip_register("input only", &testchip1, 16, NULL);
/* should fail to register chip with base overlapig on-chip gpios */
EXPECT_FALSE(gpiochip_register((brain_pin_e)(BRAIN_PIN_ONCHIP_LAST - 1), "invalid", &testchip1, 0, NULL) > 0);
chip1_base = gpiochip_register((brain_pin_e)(BRAIN_PIN_ONCHIP_LAST + 1), "input only", &testchip1, 16, NULL);
EXPECT_TRUE(chip1_base > 0);
EXPECT_EQ(16, gpiochips_get_total_pins());
chip2_base = gpiochip_register("output only", &testchip2, 16, NULL);
/* should fail to register chip overlapping other one */
EXPECT_FALSE(gpiochip_register((brain_pin_e)(BRAIN_PIN_ONCHIP_LAST + 1 + 15), "output only", &testchip2, 16, NULL) > 0);
chip2_base = gpiochip_register((brain_pin_e)(BRAIN_PIN_ONCHIP_LAST + 1 + 16), "output only", &testchip2, 16, NULL);
EXPECT_TRUE(chip2_base > 0);
/* this chip will fail to init, but should be registered without errors */
chip3_base = gpiochip_register("failed chip", &testchip3, 16, NULL);
chip3_base = gpiochip_register((brain_pin_e)(BRAIN_PIN_ONCHIP_LAST + 1 + 16 + 16), "failed chip", &testchip3, 16, NULL);
EXPECT_TRUE(chip2_base > 0);
EXPECT_EQ(48, gpiochips_get_total_pins());