zephyr/drivers/pinmux/pinmux_k64.c
Andre Guedes 024cfe754e drivers: Replace DEV_OK by 0
This patch replaces all occurences of the macro DEV_OK by the actual
value 0 at the driver level. So this patch touch the files under
drivers/, include/ and samples/drivers/.

This patch is part of the effort to transition from DEV_* codes to
errno.h codes.

Change-Id: I69980ecb9755f2fb026de5668ae9c21a4ae62d1e
Signed-off-by: Andre Guedes <andre.guedes@intel.com>
2016-03-16 19:30:04 -04:00

362 lines
7.6 KiB
C

/* pinmux_k64.c - pin out mapping for the Freescale FRDM-K64F board */
/*
* Copyright (c) 2016, Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdbool.h>
#include <nanokernel.h>
#include <device.h>
#include <init.h>
#include <sys_io.h>
#include <pinmux.h>
#include <i2c.h>
#include <gpio.h>
#include <pwm.h>
#include <gpio/gpio_k64.h>
#include <pinmux/pinmux.h>
#include <pinmux/pinmux_k64.h>
/* port pin number conversion from pin ID */
#define PIN_FROM_ID(pin_id) (pin_id % K64_PINMUX_NUM_PINS)
struct fsl_k64_data {
struct device *gpio_a; /* port A */
struct device *gpio_b; /* port B */
struct device *gpio_c; /* port C */
struct device *gpio_d; /* port D */
struct device *gpio_e; /* port E */
};
#ifdef CONFIG_GPIO_K64_A
static inline int config_port_a(mem_addr_t *addr)
{
*addr = CONFIG_PORT_K64_A_BASE_ADDR;
return 0;
}
#else
#define config_port_a(addr) DEV_NO_ACCESS
#endif
#ifdef CONFIG_GPIO_K64_B
static inline int config_port_b(mem_addr_t *addr)
{
*addr = CONFIG_PORT_K64_B_BASE_ADDR;
return 0;
}
#else
#define config_port_b(addr) DEV_NO_ACCESS
#endif
#ifdef CONFIG_GPIO_K64_C
static inline int config_port_c(mem_addr_t *addr)
{
*addr = CONFIG_PORT_K64_C_BASE_ADDR;
return 0;
}
#else
#define config_port_c(addr) DEV_NO_ACCESS
#endif
#ifdef CONFIG_GPIO_K64_D
static inline int config_port_d(mem_addr_t *addr)
{
*addr = CONFIG_PORT_K64_D_BASE_ADDR;
return 0;
}
#else
#define config_port_d(addr) DEV_NO_ACCESS
#endif
#ifdef CONFIG_GPIO_K64_E
static inline int config_port_e(mem_addr_t *addr)
{
*addr = CONFIG_PORT_K64_E_BASE_ADDR;
return 0;
}
#else
#define config_port_e(addr) DEV_NO_ACCESS
#endif
static int _fsl_k64_get_port_addr(uint8_t pin_id, mem_addr_t *port_addr_ptr)
{
/* determine the port base address associated with the pin identifier */
if (pin_id < K64_PIN_PTB0) { /* Port A pin */
return config_port_a(port_addr_ptr);
} else if (pin_id < K64_PIN_PTC0) { /* Port B pin */
return config_port_b(port_addr_ptr);
} else if (pin_id < K64_PIN_PTD0) { /* Port C pin */
return config_port_c(port_addr_ptr);
} else if (pin_id < K64_PIN_PTE0) { /* Port D pin */
return config_port_d(port_addr_ptr);
} else { /* Port E pin */
return config_port_e(port_addr_ptr);
}
}
static int _fsl_k64_get_gpio_dev(struct device *dev,
mem_addr_t port_base_addr,
struct device **gpio_dev_ptr)
{
struct fsl_k64_data * const data = dev->driver_data;
/* determine the gpio device associated with the port base address */
switch (port_base_addr) {
case CONFIG_PORT_K64_A_BASE_ADDR:
*gpio_dev_ptr = data->gpio_a;
break;
case CONFIG_PORT_K64_B_BASE_ADDR:
*gpio_dev_ptr = data->gpio_b;
break;
case CONFIG_PORT_K64_C_BASE_ADDR:
*gpio_dev_ptr = data->gpio_c;
break;
case CONFIG_PORT_K64_D_BASE_ADDR:
*gpio_dev_ptr = data->gpio_d;
break;
case CONFIG_PORT_K64_E_BASE_ADDR:
*gpio_dev_ptr = data->gpio_e;
break;
default:
return DEV_NO_ACCESS;
}
return 0;
}
static int _fsl_k64_set_pin(struct device *dev,
uint32_t pin_id,
uint32_t func)
{
mem_addr_t port_base_addr;
uint8_t port_pin;
uint32_t status;
struct device *gpio_dev = NULL;
bool is_gpio = false;
int gpio_setting;
if (pin_id >= CONFIG_PINMUX_NUM_PINS) {
return DEV_INVALID_OP;
}
if ((func & K64_PINMUX_ALT_MASK) == K64_PINMUX_FUNC_GPIO) {
is_gpio = true;
}
/* determine the pin's port register base address */
status = _fsl_k64_get_port_addr(pin_id, &port_base_addr);
if (status != 0) {
return status;
}
/* extract the pin number within its port */
port_pin = PIN_FROM_ID(pin_id);
if (is_gpio) {
/* set GPIO direction */
status = _fsl_k64_get_gpio_dev(dev, port_base_addr, &gpio_dev);
if (status != 0) {
return status;
} else if (gpio_dev == NULL) {
return DEV_NOT_CONFIG;
}
if (func & K64_PINMUX_GPIO_DIR_OUTPUT) {
gpio_setting = GPIO_DIR_OUT;
} else {
gpio_setting = GPIO_DIR_IN;
}
status = gpio_pin_configure(gpio_dev, port_pin, gpio_setting);
if (status != 0) {
return status;
}
/* remove GPIO direction info from the pin configuration */
func &= ~K64_PINMUX_GPIO_DIR_MASK;
}
/* set pin function and control settings */
sys_write32(func, port_base_addr + K64_PINMUX_CTRL_OFFSET(port_pin));
return 0;
}
static int _fsl_k64_get_pin(struct device *dev,
uint32_t pin_id,
uint32_t *func)
{
mem_addr_t port_base_addr;
uint8_t port_pin;
struct device *gpio_dev = NULL;
const struct gpio_k64_config *cfg;
uint32_t gpio_port_dir;
uint32_t status;
if (pin_id >= CONFIG_PINMUX_NUM_PINS) {
return DEV_INVALID_OP;
}
/* determine the pin's port register base address */
status = _fsl_k64_get_port_addr(pin_id, &port_base_addr);
if (status != 0) {
return status;
}
/* extract the pin number within its port */
port_pin = PIN_FROM_ID(pin_id);
/* get pin function and control settings */
*func = sys_read32(port_base_addr + K64_PINMUX_CTRL_OFFSET(port_pin));
/* get pin direction, if GPIO */
if ((*func & K64_PINMUX_ALT_MASK) == K64_PINMUX_FUNC_GPIO) {
status = _fsl_k64_get_gpio_dev(dev, port_base_addr, &gpio_dev);
if (status != 0) {
return status;
} else if (gpio_dev == NULL) {
return DEV_NOT_CONFIG;
}
cfg = gpio_dev->config->config_info;
gpio_port_dir = sys_read32(cfg->gpio_base_addr + GPIO_K64_DIR_OFFSET);
if (gpio_port_dir & (1 << port_pin)) {
*func |= K64_PINMUX_GPIO_DIR_OUTPUT;
}
}
return 0;
}
static int fsl_k64_dev_set(struct device *dev,
uint32_t pin,
uint32_t func)
{
return _fsl_k64_set_pin(dev, pin, func);
}
static int fsl_k64_dev_get(struct device *dev,
uint32_t pin,
uint32_t *func)
{
return _fsl_k64_get_pin(dev, pin, func);
}
static struct pinmux_driver_api api_funcs = {
.set = fsl_k64_dev_set,
.get = fsl_k64_dev_get
};
int pinmux_fsl_k64_initialize(struct device *port)
{
struct fsl_k64_data *data = port->driver_data;
port->driver_api = &api_funcs;
/* get the GPIO ports, by name */
#ifdef CONFIG_GPIO_K64_A
data->gpio_a = device_get_binding(CONFIG_PINMUX_K64_GPIO_A_NAME);
if (!data->gpio_a) {
return DEV_INVALID_CONF;
}
#endif
#ifdef CONFIG_GPIO_K64_B
data->gpio_b = device_get_binding(CONFIG_PINMUX_K64_GPIO_B_NAME);
if (!data->gpio_b) {
return DEV_INVALID_CONF;
}
#endif
#ifdef CONFIG_GPIO_K64_C
data->gpio_c = device_get_binding(CONFIG_PINMUX_K64_GPIO_C_NAME);
if (!data->gpio_c) {
return DEV_INVALID_CONF;
}
#endif
#ifdef CONFIG_GPIO_K64_D
data->gpio_d = device_get_binding(CONFIG_PINMUX_K64_GPIO_D_NAME);
if (!data->gpio_d) {
return DEV_INVALID_CONF;
}
#endif
#ifdef CONFIG_GPIO_K64_E
data->gpio_e = device_get_binding(CONFIG_PINMUX_K64_GPIO_E_NAME);
if (!data->gpio_e) {
return DEV_INVALID_CONF;
}
#endif
return 0;
}
struct pinmux_config fsl_k64_pmux = {
.base_address = 0x00000000,
};
struct fsl_k64_data fsl_k64_pinmux_driver = {
.gpio_a = NULL,
.gpio_b = NULL,
.gpio_c = NULL,
.gpio_d = NULL,
.gpio_e = NULL
};
/* must be initialized after GPIO */
DEVICE_INIT(pmux, PINMUX_NAME, &pinmux_fsl_k64_initialize,
&fsl_k64_pinmux_driver, &fsl_k64_pmux,
SECONDARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);