Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | /*
* SPDX-License-Identifier: Apache-2.0
*
* Driver for the I/O controller (pinmux) for
* Texas Instrument's CC2650 SoC.
*
* For these SoCs, available pin functions are as follows:
*
* 0x00 - GPIO
* 0x07 - AON 32 Khz clock
* 0x08 - AUX IO
* 0x09 - SSI0 RX
* 0x0A - SSI0 TX
* 0x0B - SSI0 FSS
* 0x0C - SSI0 CLK
* 0x0D - I2C SDA
* 0x0E - I2C SCL
* 0x0F - UART0 RX
* 0x10 - UART0 TX
* 0x11 - UART0 CTS
* 0x12 - UART0 RTS
* 0x17 - Port event 0
* 0x18 - Port event 1
* 0x19 - Port event 2
* 0x1A - Port event 3
* 0x1B - Port event 4
* 0x1C - Port event 5
* 0x1D - Port event 6
* 0x1E - Port event 7
* 0x20 - CPU SWV
* 0x21 - SSI1 RX
* 0x22 - SSI1 TX
* 0x23 - SSI1 FSS
* 0x24 - SSI1 CLK
* 0x25 - I2S data 0
* 0x26 - I2S data 1
* 0x27 - I2S WCLK
* 0x28 - I2S BCLK
* 0x29 - I2S MCLK
* 0x2E - RF Core Trace
* 0x2F - RF Core data out 0
* 0x30 - RF Core data out 1
* 0x31 - RF Core data out 2
* 0x32 - RF Core data out 3
* 0x33 - RF Core data in 0
* 0x34 - RF Core data in 1
* 0x35 - RF Core SMI data link out
* 0x36 - RF Core SMI data link in
* 0x37 - RF Core SMI command link out
* 0x38 - RF Core SMI command link in
*/
#include <sys/__assert.h>
#include <sys/util.h>
#include <toolchain.h>
#include <device.h>
#include <drivers/pinmux.h>
#include <soc.h>
#include <sys/sys_io.h>
#define IOCFG_REG(Func) \
REG_ADDR(DT_TI_CC2650_PINMUX_40081000_BASE_ADDRESS, \
CC2650_IOC_IOCFG0 + 0x4 * Func)
static int pinmux_cc2650_init(struct device *dev)
{
/* Do nothing */
ARG_UNUSED(dev);
return 0;
}
static int pinmux_cc2650_set(struct device *dev, u32_t pin,
u32_t func)
{
const u32_t iocfg = IOCFG_REG(pin);
u32_t conf = sys_read32(iocfg);
conf &= ~CC2650_IOC_IOCFGX_PORT_ID_MASK;
conf |= func & CC2650_IOC_IOCFGX_PORT_ID_MASK;
sys_write32(conf, iocfg);
return 0;
};
static int pinmux_cc2650_get(struct device *dev, u32_t pin,
u32_t *func)
{
const u32_t iocfg = IOCFG_REG(pin);
u32_t conf = sys_read32(iocfg);
*func = conf & CC2650_IOC_IOCFGX_PORT_ID_MASK;
return 0;
}
static int pinmux_cc2650_pullup(struct device *dev, u32_t pin,
u8_t func)
{
__ASSERT((func == PINMUX_PULLUP_ENABLE) |
(func == PINMUX_PULLUP_DISABLE),
"Pullup mode is invalid");
const u32_t iocfg = IOCFG_REG(pin);
u32_t conf = sys_read32(iocfg);
conf &= ~CC2650_IOC_IOCFGX_PULL_CTL_MASK;
if (func == PINMUX_PULLUP_ENABLE) {
conf |= CC2650_IOC_PULL_UP;
} else {
conf |= CC2650_IOC_NO_PULL;
}
sys_write32(conf, iocfg);
return 0;
}
static int pinmux_cc2650_input(struct device *dev, u32_t pin,
u8_t func)
{
__ASSERT((func == PINMUX_INPUT_ENABLED) |
(func == PINMUX_OUTPUT_ENABLED),
"I/O mode is invalid");
const u32_t iocfg = IOCFG_REG(pin);
const u32_t gpio_doe = DT_TI_CC2650_GPIO_40022000_BASE_ADDRESS +
CC2650_GPIO_DOE31_0;
u32_t iocfg_conf = sys_read32(iocfg);
u32_t gpio_doe_conf = sys_read32(gpio_doe);
iocfg_conf &= ~CC2650_IOC_IOCFGX_IE_MASK;
if (func == PINMUX_INPUT_ENABLED) {
iocfg_conf |= CC2650_IOC_INPUT_ENABLED;
gpio_doe_conf &= ~BIT(pin);
} else {
iocfg_conf |= CC2650_IOC_INPUT_DISABLED;
gpio_doe_conf |= BIT(pin);
}
sys_write32(iocfg_conf, iocfg);
sys_write32(gpio_doe_conf, gpio_doe);
return 0;
}
const struct pinmux_driver_api pinmux_cc2650_funcs = {
.set = pinmux_cc2650_set,
.get = pinmux_cc2650_get,
.pullup = pinmux_cc2650_pullup,
.input = pinmux_cc2650_input
};
DEVICE_AND_API_INIT(pinmux_cc2650_0, CONFIG_PINMUX_NAME,
pinmux_cc2650_init, NULL, NULL,
PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY,
&pinmux_cc2650_funcs);
|