blob: e33b77e5a447fef5c3a2c8592b60bbf4423819b2 [file] [log] [blame]
/******************************************************************************
Copyright (c) 2006-2015 Lantiq Deutschland GmbH
Copyright (c) 2015 Lantiq Beteiligungs-GmbH & Co.KG
Copyright 2018, Intel Corporation.
For licensing information, see the file 'LICENSE' in the root folder of
this software module.
******************************************************************************/
/**
\file dxs_gpio.c
Implementation of GPIO functions.
*/
/* ========================================================================== */
/* Includes */
/* ========================================================================== */
#include "dxs_config.h"
#ifdef DXS_FEAT_GPIO
#include "dxs.h"
#include "dxs_fw_cmd.h"
#include "dxs_errno.h"
#include "dxs_error.h"
/* ========================================================================== */
/* Macro definitions */
/* ========================================================================== */
/* ========================================================================== */
/* Type definitions */
/* ========================================================================== */
/** Data structure for GPIO configuration firmware command */
typedef struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
CMD_HEAD_BE;
/** Reserved */
uint32_t Res02 : 4;
/** Enable GPIO Pull-up Resistor */
uint32_t GPIO_PULL_UP : 4;
/** Reserved */
uint32_t Res03 : 4;
/** Direction of GPIO Bits */
uint32_t GPIO_DIR : 4;
/** Reserved */
uint32_t Res04 : 16;
#else
CMD_HEAD_LE;
/** Reserved */
uint32_t Res04 : 16;
/** Direction of GPIO Bits */
uint32_t GPIO_DIR : 4;
/** Reserved */
uint32_t Res03 : 4;
/** Enable GPIO Pull-up Resistor */
uint32_t GPIO_PULL_UP : 4;
/** Reserved */
uint32_t Res02 : 4;
#endif
} __attribute__ ((packed)) DXS_FW_GPIO_Config_t;
#define DXS_FW_GPIO_Config_ECMD 2
#define DXS_FW_GPIO_Config_LENGTH 4
/** Data structure for GPIO control firmware command */
typedef struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
CMD_HEAD_BE;
/** Reserved */
uint32_t Res02 : 4;
/** Write Mask for GPIO */
uint32_t GPIO_WR_MSK : 4;
/** Reserved */
uint32_t Res03 : 4;
/** Value of GPIO Bits */
uint32_t GPIO_VAL : 4;
/** Reserved */
uint32_t Res04 : 16;
#else
CMD_HEAD_LE;
/** Reserved */
uint32_t Res04 : 16;
/** Value of GPIO Bits */
uint32_t GPIO_VAL : 4;
/** Reserved */
uint32_t Res03 : 4;
/** Write Mask for GPIO */
uint32_t GPIO_WR_MSK : 4;
/** Reserved */
uint32_t Res02 : 4;
#endif
} __attribute__ ((packed)) DXS_FW_GPIO_Data_t;
#define DXS_FW_GPIO_Data_ECMD 3
#define DXS_FW_GPIO_Data_LENGTH 4
/** GPIO device resource structure */
typedef struct
{
/** status flag */
uint32_t flag;
#define GPIO_DEV_INITIALIZED 0x00000001
#define GPIO_CTRL_CONFIGURED 0x80000000
/** DXS_FW_GPIO_Config command */
DXS_FW_GPIO_Config_t cfg;
/** DXS_FW_GPIO_Data command */
DXS_FW_GPIO_Data_t data;
} DXS_GPIO_Dev_Resource_t;
/* ========================================================================== */
/* Global variables */
/* ========================================================================== */
static DXS_GPIO_Dev_Resource_t gpio_devs[DXS_MAX_DEVICES] = {0};
/* ========================================================================== */
/* Function prototypes */
/* ========================================================================== */
/* ========================================================================== */
/* Function implementation */
/* ========================================================================== */
/**
Function to initialize GPIO device resource
\param devnum - device number
*/
void *DXS_GPIO_DevInit(uint8_t devnum)
{
DXS_GPIO_Dev_Resource_t *p;
if (devnum >= DXS_MAX_DEVICES)
return (void *)NULL;
p = &gpio_devs[devnum];
p->flag = 0;
p->cfg.CMD = CMD_EOP;
p->cfg.MOD = MOD_EOP_GPIO;
p->cfg.ECMD = DXS_FW_GPIO_Config_ECMD;
p->cfg.LENGTH = DXS_FW_GPIO_Config_LENGTH;
p->data.CMD = CMD_EOP;
p->data.MOD = MOD_EOP_GPIO;
p->data.ECMD = DXS_FW_GPIO_Data_ECMD;
p->data.LENGTH = DXS_FW_GPIO_Data_LENGTH;
p->flag |= GPIO_DEV_INITIALIZED;
return (void *)p;
}
/**
Function to configure GPIO
\param pDev - pointer to DXS device structure
\param pGpioConf - pointer to GPIO config structure
\return
- DXS_status_t
*/
int32_t DXS_GPIO_Config(DXS_DEVICE_t *pDev, DXS_GpioConfig_t *pGpioConf)
{
int32_t err = DXS_statusOk;
DXS_GPIO_Dev_Resource_t *p;
uint8_t new_gpio_PU, new_gpio_dir, param_check;
if (pDev == NULL || pGpioConf == NULL)
{
DXS_RETURN(DXS_statusInvalidParam);
}
p = (DXS_GPIO_Dev_Resource_t *)pDev->gpio;
if (!(p->flag & GPIO_DEV_INITIALIZED))
{
DXS_RETURN(DXS_statusNotInitResource);
}
param_check = (pGpioConf->gpio0_PU | pGpioConf->gpio1_PU |
pGpioConf->gpio2_PU | pGpioConf->gpio3_PU |
pGpioConf->gpio0_DIR | pGpioConf->gpio1_DIR |
pGpioConf->gpio2_DIR | pGpioConf->gpio3_DIR);
if (param_check > 1)
{
DXS_RETURN(DXS_statusParamsOutRange);
}
if (!(p->flag & GPIO_CTRL_CONFIGURED))
{
/* read configuration from the device */
err = DXS_CmdRead(pDev, (uint32_t *)&p->cfg, (uint32_t *)&p->cfg);
if (err)
{
DXS_RETURN(err);
}
}
/* Set the parameters */
new_gpio_PU = 0xF & (pGpioConf->gpio0_PU | (pGpioConf->gpio1_PU << 1) |
(pGpioConf->gpio2_PU << 2) | (pGpioConf->gpio3_PU << 3));
new_gpio_dir = 0xF & (pGpioConf->gpio0_DIR | (pGpioConf->gpio1_DIR << 1) |
(pGpioConf->gpio2_DIR << 2) | (pGpioConf->gpio3_DIR << 3));
if (new_gpio_PU != p->cfg.GPIO_PULL_UP || new_gpio_dir != p->cfg.GPIO_DIR)
{
/* write new values */
p->cfg.GPIO_PULL_UP = new_gpio_PU;
p->cfg.GPIO_DIR = new_gpio_dir;
err = CmdWrite(pDev, (uint32_t *)&p->cfg);
if (err)
{
DXS_RETURN(err);
}
}
p->flag |= GPIO_CTRL_CONFIGURED;
DXS_RETURN(err);
}
/**
Function DXS_GPIO_Write
\param pDev - pointer to DXS device structure
\param pin - pin number
\param val - value
\return
- DXS_status_t
*/
int32_t DXS_GPIO_Write(DXS_DEVICE_t *pDev, uint8_t pin, uint8_t val)
{
int32_t err = DXS_statusOk;
DXS_GPIO_Dev_Resource_t *p;
uint8_t pin_mask;
if (pDev == NULL)
{
DXS_RETURN(DXS_statusInvalidParam);
}
p = (DXS_GPIO_Dev_Resource_t *)pDev->gpio;
if (!(p->flag & GPIO_DEV_INITIALIZED))
{
DXS_RETURN(DXS_statusNotInitResource);
}
if (!(p->flag & GPIO_CTRL_CONFIGURED))
{
/* GPIO port not configured yet */
DXS_RETURN(DXS_statusGpioNotConfigured);
}
pin_mask = 1 << pin;
/* If the specified pin is configured as input - return error */
if (p->cfg.GPIO_DIR & pin_mask)
{
DXS_RETURN(DXS_statusGpioWriteAccessIgnored);
}
/* Set the parameters */
p->data.GPIO_WR_MSK = ~pin_mask;
if (val)
p->data.GPIO_VAL = 0xF;
else
p->data.GPIO_VAL = 0;
/* write new values */
err = CmdWrite(pDev, (uint32_t *)&p->data);
DXS_RETURN(err);
}
/**
Function DXS_GPIO_Read
\param pDev - pointer to DXS device structure
\param pin - pin number
\param pVal - pointer to value
\return
- DXS_status_t
*/
int32_t DXS_GPIO_Read(DXS_DEVICE_t *pDev, uint8_t pin, uint8_t *pVal)
{
int32_t err = DXS_statusOk;
DXS_GPIO_Dev_Resource_t *p;
if (pDev == NULL)
{
DXS_RETURN(DXS_statusInvalidParam);
}
p = (DXS_GPIO_Dev_Resource_t *)pDev->gpio;
if (!(p->flag & GPIO_DEV_INITIALIZED))
{
DXS_RETURN(DXS_statusNotInitResource);
}
if (!(p->flag & GPIO_CTRL_CONFIGURED))
{
/* GPIO port not configured yet */
DXS_RETURN(DXS_statusGpioNotConfigured);
}
err = DXS_CmdRead(pDev, (uint32_t *)&p->data, (uint32_t *)&p->data);
if (err)
{
DXS_RETURN(err);
}
/* Set the parameters */
if (p->data.GPIO_VAL & (1 << pin))
*pVal = 1;
else
*pVal = 0;
DXS_RETURN(err);
}
#endif /* DXS_FEAT_GPIO */