<commit_before>/*
 * Copyright (c) 2016, Texas Instruments Incorporated
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <errno.h>

#include <device.h>
#include <drivers/gpio.h>
#include <init.h>
#include <kernel.h>
#include <sys/sys_io.h>

/* Driverlib includes */
#include <inc/hw_types.h>
#include <inc/hw_memmap.h>
#include <inc/hw_ints.h>
#include <inc/hw_gpio.h>
#include <driverlib/rom.h>
#include <driverlib/pin.h>
#undef __GPIO_H__  /* Zephyr and CC32XX SDK gpio.h conflict */
#include <driverlib/gpio.h>
#include <driverlib/rom_map.h>
#include <driverlib/interrupt.h>

#include "gpio_utils.h"

/* Reserved */
#define PIN_XX  0xFF

static const u8_t pinTable[] = {
	/* 00     01      02      03      04      05      06      07  */
	PIN_50, PIN_55, PIN_57, PIN_58, PIN_59, PIN_60, PIN_61, PIN_62,
	/* 08     09      10      11      12      13      14      15  */
	PIN_63, PIN_64, PIN_01, PIN_02, PIN_03, PIN_04, PIN_05, PIN_06,
	/* 16     17      18      19      20      21      22      23  */
	PIN_07, PIN_08, PIN_XX, PIN_XX, PIN_XX, PIN_XX, PIN_15, PIN_16,
	/* 24     25      26      27      28      29      30      31  */
	PIN_17, PIN_21, PIN_29, PIN_30, PIN_18, PIN_20, PIN_53, PIN_45,
	/* 32 */
	PIN_52
};

struct gpio_cc32xx_config {
	/* base address of GPIO port */
	unsigned long port_base;
	/* GPIO IRQ number */
	unsigned long irq_num;
	/* GPIO port number */
	u8_t port_num;
};

struct gpio_cc32xx_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;
	/* list of registered callbacks */
	sys_slist_t callbacks;
	/* callback enable pin bitmask */
	u32_t pin_callback_enables;
};

#define DEV_CFG(dev) \
	((const struct gpio_cc32xx_config *)(dev)->config->config_info)
#define DEV_DATA(dev) \
	((struct gpio_cc32xx_data *)(dev)->driver_data)

static int gpio_cc32xx_port_set_bits_raw(struct device *port, u32_t mask);
static int gpio_cc32xx_port_clear_bits_raw(struct device *port, u32_t mask);

static inline int gpio_cc32xx_config(struct device *port,
				   int access_op, u32_t pin, int flags)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	if (((flags & GPIO_INPUT) != 0) && ((flags & GPIO_OUTPUT) != 0)) {
		return -ENOTSUP;
	}

	if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == 0) {
		return -ENOTSUP;
	}

	if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) {
		return -ENOTSUP;
	}

	if (access_op != GPIO_ACCESS_BY_PIN) {
		return -ENOTSUP;
	}

	MAP_PinTypeGPIO(pinTable[gpio_config->port_num * 8 + pin],
		PIN_MODE_0, false);
	if (flags & GPIO_OUTPUT) {
		MAP_GPIODirModeSet(port_base, (1 << pin), GPIO_DIR_MODE_OUT);
		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
			gpio_cc32xx_port_set_bits_raw(port, BIT(pin));
		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
			gpio_cc32xx_port_clear_bits_raw(port, BIT(pin));
		}
	} else {
		MAP_GPIODirModeSet(port_base, (1 << pin), GPIO_DIR_MODE_IN);
	}

	return 0;
}

static inline int gpio_cc32xx_write(struct device *port,
				    int access_op, u32_t pin, u32_t value)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	if (access_op == GPIO_ACCESS_BY_PIN) {
		value = value << pin;
		/* Bitpack external GPIO pin number for GPIOPinWrite API: */
		pin = 1 << pin;

		MAP_GPIOPinWrite(port_base, (unsigned char)pin,
			(unsigned char)value);
	} else {
		return -ENOTSUP;
	}

	return 0;
}

static inline int gpio_cc32xx_read(struct device *port,
				   int access_op, u32_t pin, u32_t *value)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;
	long status;
	unsigned char pin_packed;

	if (access_op == GPIO_ACCESS_BY_PIN) {
		/* Bitpack external GPIO pin number for GPIOPinRead API: */
		pin_packed = 1 << pin;
		status =  MAP_GPIOPinRead(port_base, pin_packed);
		*value = status >> pin;
	} else {
		return -ENOTSUP;
	}

	return 0;
}

static int gpio_cc32xx_port_get_raw(struct device *port, u32_t *value)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;
	unsigned char pin_packed = 0xFF;

	*value = MAP_GPIOPinRead(port_base, pin_packed);

	return 0;
}

static int gpio_cc32xx_port_set_masked_raw(struct device *port, u32_t mask,
					  u32_t value)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	MAP_GPIOPinWrite(port_base, (unsigned char)mask, (unsigned char)value);

	return 0;
}

static int gpio_cc32xx_port_set_bits_raw(struct device *port, u32_t mask)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	MAP_GPIOPinWrite(port_base, (unsigned char)mask, (unsigned char)mask);

	return 0;
}

static int gpio_cc32xx_port_clear_bits_raw(struct device *port, u32_t mask)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	MAP_GPIOPinWrite(port_base, (unsigned char)mask, (unsigned char)~mask);

	return 0;
}

static int gpio_cc32xx_port_toggle_bits(struct device *port, u32_t mask)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;
	long value;

	value = MAP_GPIOPinRead(port_base, mask);

	MAP_GPIOPinWrite(port_base, (unsigned char)mask,
		(unsigned char)~value);

	return 0;
}

static int gpio_cc32xx_pin_interrupt_configure(struct device *port,
		unsigned int pin, enum gpio_int_mode mode,
		enum gpio_int_trig trig)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	struct gpio_cc32xx_data *data = DEV_DATA(port);
	unsigned long port_base = gpio_config->port_base;
	unsigned long int_type;

	if (mode != GPIO_INT_MODE_DISABLED) {
		if (mode == GPIO_INT_MODE_EDGE) {
			if (trig == GPIO_INT_TRIG_BOTH) {
				int_type = GPIO_BOTH_EDGES;
			} else if (trig == GPIO_INT_TRIG_HIGH) {
				int_type = GPIO_RISING_EDGE;
			} else {
				int_type = GPIO_FALLING_EDGE;
			}
		} else { /* GPIO_INT_LEVEL */
			if (trig == GPIO_INT_TRIG_HIGH) {
				int_type = GPIO_HIGH_LEVEL;
			} else {
				int_type = GPIO_LOW_LEVEL;
			}
		}
		MAP_GPIOIntTypeSet(port_base, (1 << pin), int_type);
		MAP_GPIOIntClear(port_base, (1 << pin));
		MAP_GPIOIntEnable(port_base, (1 << pin));

		WRITE_BIT(data->pin_callback_enables, pin,
			mode != GPIO_INT_MODE_DISABLED);
	} else {
		MAP_GPIOIntDisable(port_base, (1 << pin));
	}

	return 0;
}

static int gpio_cc32xx_manage_callback(struct device *dev,
				    struct gpio_callback *callback, bool set)
{
	struct gpio_cc32xx_data *data = DEV_DATA(dev);

	return gpio_manage_callback(&data->callbacks, callback, set);
}


static int gpio_cc32xx_enable_callback(struct device *dev,
				    int access_op, u32_t pin)
{
	struct gpio_cc32xx_data *data = DEV_DATA(dev);

	if (access_op == GPIO_ACCESS_BY_PIN) {
		data->pin_callback_enables |= (1 << pin);
	} else {
		data->pin_callback_enables = 0xFFFFFFFF;
	}

	return 0;
}


static int gpio_cc32xx_disable_callback(struct device *dev,
				     int access_op, u32_t pin)
{
	struct gpio_cc32xx_data *data = DEV_DATA(dev);

	if (access_op == GPIO_ACCESS_BY_PIN) {
		data->pin_callback_enables &= ~(1 << pin);
	} else {
		data->pin_callback_enables = 0U;
	}

	return 0;
}

static void gpio_cc32xx_port_isr(void *arg)
{
	struct device *dev = arg;
	const struct gpio_cc32xx_config *config = DEV_CFG(dev);
	struct gpio_cc32xx_data *data = DEV_DATA(dev);
	u32_t enabled_int, int_status;

	/* See which interrupts triggered: */
	int_status  = (u32_t)MAP_GPIOIntStatus(config->port_base, 1);

	enabled_int = int_status & data->pin_callback_enables;

	/* Clear and Disable GPIO Interrupt */
	MAP_GPIOIntDisable(config->port_base, int_status);
	MAP_GPIOIntClear(config->port_base, int_status);

	/* Call the registered callbacks */
	gpio_fire_callbacks(&data->callbacks, (struct device *)dev,<commit_msg>drivers: gpio: cc32xx: add assertions to check number of pins<commit_after>/*
 * Copyright (c) 2016, Texas Instruments Incorporated
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <errno.h>

#include <device.h>
#include <drivers/gpio.h>
#include <init.h>
#include <kernel.h>
#include <sys/sys_io.h>

/* Driverlib includes */
#include <inc/hw_types.h>
#include <inc/hw_memmap.h>
#include <inc/hw_ints.h>
#include <inc/hw_gpio.h>
#include <driverlib/rom.h>
#include <driverlib/pin.h>
#undef __GPIO_H__  /* Zephyr and CC32XX SDK gpio.h conflict */
#include <driverlib/gpio.h>
#include <driverlib/rom_map.h>
#include <driverlib/interrupt.h>

#include "gpio_utils.h"

/* Reserved */
#define PIN_XX  0xFF

static const u8_t pinTable[] = {
	/* 00     01      02      03      04      05      06      07  */
	PIN_50, PIN_55, PIN_57, PIN_58, PIN_59, PIN_60, PIN_61, PIN_62,
	/* 08     09      10      11      12      13      14      15  */
	PIN_63, PIN_64, PIN_01, PIN_02, PIN_03, PIN_04, PIN_05, PIN_06,
	/* 16     17      18      19      20      21      22      23  */
	PIN_07, PIN_08, PIN_XX, PIN_XX, PIN_XX, PIN_XX, PIN_15, PIN_16,
	/* 24     25      26      27      28      29      30      31  */
	PIN_17, PIN_21, PIN_29, PIN_30, PIN_18, PIN_20, PIN_53, PIN_45,
	/* 32 */
	PIN_52
};

struct gpio_cc32xx_config {
	/* base address of GPIO port */
	unsigned long port_base;
	/* GPIO IRQ number */
	unsigned long irq_num;
	/* GPIO port number */
	u8_t port_num;
};

struct gpio_cc32xx_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;
	/* list of registered callbacks */
	sys_slist_t callbacks;
	/* callback enable pin bitmask */
	u32_t pin_callback_enables;
};

#define DEV_CFG(dev) \
	((const struct gpio_cc32xx_config *)(dev)->config->config_info)
#define DEV_DATA(dev) \
	((struct gpio_cc32xx_data *)(dev)->driver_data)

static int gpio_cc32xx_port_set_bits_raw(struct device *port, u32_t mask);
static int gpio_cc32xx_port_clear_bits_raw(struct device *port, u32_t mask);

static inline int gpio_cc32xx_config(struct device *port,
				   int access_op, u32_t pin, int flags)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	if (((flags & GPIO_INPUT) != 0) && ((flags & GPIO_OUTPUT) != 0)) {
		return -ENOTSUP;
	}

	if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == 0) {
		return -ENOTSUP;
	}

	if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) {
		return -ENOTSUP;
	}

	if (access_op != GPIO_ACCESS_BY_PIN) {
		return -ENOTSUP;
	}

	MAP_PinTypeGPIO(pinTable[gpio_config->port_num * 8 + pin],
		PIN_MODE_0, false);
	if (flags & GPIO_OUTPUT) {
		MAP_GPIODirModeSet(port_base, (1 << pin), GPIO_DIR_MODE_OUT);
		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
			gpio_cc32xx_port_set_bits_raw(port, BIT(pin));
		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
			gpio_cc32xx_port_clear_bits_raw(port, BIT(pin));
		}
	} else {
		MAP_GPIODirModeSet(port_base, (1 << pin), GPIO_DIR_MODE_IN);
	}

	return 0;
}

static inline int gpio_cc32xx_write(struct device *port,
				    int access_op, u32_t pin, u32_t value)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	__ASSERT(pin < 8, "Invalid pin number - only 8 pins per port");

	if (access_op == GPIO_ACCESS_BY_PIN) {
		value = value << pin;
		/* Bitpack external GPIO pin number for GPIOPinWrite API: */
		pin = 1 << pin;

		MAP_GPIOPinWrite(port_base, (unsigned char)pin,
			(unsigned char)value);
	} else {
		return -ENOTSUP;
	}

	return 0;
}

static inline int gpio_cc32xx_read(struct device *port,
				   int access_op, u32_t pin, u32_t *value)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;
	long status;
	unsigned char pin_packed;

	__ASSERT(pin < 8, "Invalid pin number - only 8 pins per port");

	if (access_op == GPIO_ACCESS_BY_PIN) {
		/* Bitpack external GPIO pin number for GPIOPinRead API: */
		pin_packed = 1 << pin;
		status =  MAP_GPIOPinRead(port_base, pin_packed);
		*value = status >> pin;
	} else {
		return -ENOTSUP;
	}

	return 0;
}

static int gpio_cc32xx_port_get_raw(struct device *port, u32_t *value)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;
	unsigned char pin_packed = 0xFF;

	*value = MAP_GPIOPinRead(port_base, pin_packed);

	return 0;
}

static int gpio_cc32xx_port_set_masked_raw(struct device *port, u32_t mask,
					  u32_t value)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	MAP_GPIOPinWrite(port_base, (unsigned char)mask, (unsigned char)value);

	return 0;
}

static int gpio_cc32xx_port_set_bits_raw(struct device *port, u32_t mask)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	MAP_GPIOPinWrite(port_base, (unsigned char)mask, (unsigned char)mask);

	return 0;
}

static int gpio_cc32xx_port_clear_bits_raw(struct device *port, u32_t mask)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	MAP_GPIOPinWrite(port_base, (unsigned char)mask, (unsigned char)~mask);

	return 0;
}

static int gpio_cc32xx_port_toggle_bits(struct device *port, u32_t mask)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;
	long value;

	value = MAP_GPIOPinRead(port_base, mask);

	MAP_GPIOPinWrite(port_base, (unsigned char)mask,
		(unsigned char)~value);

	return 0;
}

static int gpio_cc32xx_pin_interrupt_configure(struct device *port,
		unsigned int pin, enum gpio_int_mode mode,
		enum gpio_int_trig trig)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	struct gpio_cc32xx_data *data = DEV_DATA(port);
	unsigned long port_base = gpio_config->port_base;
	unsigned long int_type;

	__ASSERT(pin < 8, "Invalid pin number - only 8 pins per port");

	if (mode != GPIO_INT_MODE_DISABLED) {
		if (mode == GPIO_INT_MODE_EDGE) {
			if (trig == GPIO_INT_TRIG_BOTH) {
				int_type = GPIO_BOTH_EDGES;
			} else if (trig == GPIO_INT_TRIG_HIGH) {
				int_type = GPIO_RISING_EDGE;
			} else {
				int_type = GPIO_FALLING_EDGE;
			}
		} else { /* GPIO_INT_LEVEL */
			if (trig == GPIO_INT_TRIG_HIGH) {
				int_type = GPIO_HIGH_LEVEL;
			} else {
				int_type = GPIO_LOW_LEVEL;
			}
		}
		MAP_GPIOIntTypeSet(port_base, (1 << pin), int_type);
		MAP_GPIOIntClear(port_base, (1 << pin));
		MAP_GPIOIntEnable(port_base, (1 << pin));

		WRITE_BIT(data->pin_callback_enables, pin,
			mode != GPIO_INT_MODE_DISABLED);
	} else {
		MAP_GPIOIntDisable(port_base, (1 << pin));
	}

	return 0;
}

static int gpio_cc32xx_manage_callback(struct device *dev,
				    struct gpio_callback *callback, bool set)
{
	struct gpio_cc32xx_data *data = DEV_DATA(dev);

	return gpio_manage_callback(&data->callbacks, callback, set);
}


static int gpio_cc32xx_enable_callback(struct device *dev,
				    int access_op, u32_t pin)
{
	struct gpio_cc32xx_data *data = DEV_DATA(dev);

	__ASSERT(pin < 8, "Invalid pin number - only 8 pins per port");

	if (access_op == GPIO_ACCESS_BY_PIN) {
		data->pin_callback_enables |= (1 << pin);
	} else {
		data->pin_callback_enables = 0xFFFFFFFF;
	}

	return 0;
}


static int gpio_cc32xx_disable_callback(struct device *dev,
				     int access_op, u32_t pin)
{
	struct gpio_cc32xx_data *data = DEV_DATA(dev);

	__ASSERT(pin < 8, "Invalid pin number - only 8 pins per port");

	if (access_op == GPIO_ACCESS_BY_PIN) {
		data->pin_callback_enables &= ~(1 << pin);
	} else {
		data->pin_callback_enables = 0U;
	}

	return 0;
}

static void gpio_cc32xx_port_isr(void *arg)
{
	struct device *dev = arg;
	const struct gpio_cc32xx_config *config = DEV_CFG(dev);
	struct gpio_cc32xx_data *data = DEV_DATA(dev);
	u32_t enabled_int, int_status;

	/* See which interrupts triggered: */
	int_status  = (u32_t)MAP_GPIOIntStatus(config->port_base, 1);

	enabled_int = int_status & data->pin_callback_enables;

	/* Clear and Disable GPIO Interrupt */
	MAP_GPIOIntDisable(config->port_base, int_status);
	MAP_GPIOIntClear(config->port_base, int_status);

	/* Call the registered callbacks */
	gpio_fire_callbacks(&data->callbacks, (struct device *)dev,
{'fraction_non_alphanumeric': 0.11244608749229822, 'fraction_numerical': 0.03475046210720887, 'mean_word_length': 4.261264181523501, 'pattern_counts': {'":': 0, '<': 82, '<?xml version=': 0, '>': 85, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '89745', 'n_tokens_mistral': 6965, 'n_tokens_neox': 6254, 'n_words': 1438}