Linux Audio

Check our new training course

Loading...
/*
 * Copyright (c) 2018 Google LLC.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <drivers/pinmux.h>
#include <soc.h>

struct pinmux_sam0_config {
	PortGroup *regs;
};

static int pinmux_sam0_set(struct device *dev, u32_t pin, u32_t func)
{
	const struct pinmux_sam0_config *cfg = dev->config->config_info;
	bool odd_pin = pin & 1;
	int idx = pin / 2U;

	/* Each pinmux register holds the config for two pins.  The
	 * even numbered pin goes in the bits 0..3 and the odd
	 * numbered pin in bits 4..7.
	 */
	if (odd_pin) {
		cfg->regs->PMUX[idx].bit.PMUXO = func;
	} else {
		cfg->regs->PMUX[idx].bit.PMUXE = func;
	}
	cfg->regs->PINCFG[pin].bit.PMUXEN = 1;

	return 0;
}

static int pinmux_sam0_get(struct device *dev, u32_t pin, u32_t *func)
{
	const struct pinmux_sam0_config *cfg = dev->config->config_info;
	bool odd_pin = pin & 1;
	int idx = pin / 2U;

	if (odd_pin) {
		*func = cfg->regs->PMUX[idx].bit.PMUXO;
	} else {
		*func = cfg->regs->PMUX[idx].bit.PMUXE;
	}

	return 0;
}

static int pinmux_sam0_pullup(struct device *dev, u32_t pin, u8_t func)
{
	return -ENOTSUP;
}

static int pinmux_sam0_input(struct device *dev, u32_t pin, u8_t func)
{
	return -ENOTSUP;
}

static int pinmux_sam0_init(struct device *dev)
{
	/* Nothing to do.  The GPIO clock is enabled at reset. */
	return 0;
}

const struct pinmux_driver_api pinmux_sam0_api = {
	.set = pinmux_sam0_set,
	.get = pinmux_sam0_get,
	.pullup = pinmux_sam0_pullup,
	.input = pinmux_sam0_input,
};

#if DT_ATMEL_SAM0_PINMUX_PINMUX_A_BASE_ADDRESS
static const struct pinmux_sam0_config pinmux_sam0_config_0 = {
	.regs = (PortGroup *)DT_ATMEL_SAM0_PINMUX_PINMUX_A_BASE_ADDRESS,
};

DEVICE_AND_API_INIT(pinmux_sam0_0, DT_ATMEL_SAM0_PINMUX_PINMUX_A_LABEL,
		    pinmux_sam0_init, NULL, &pinmux_sam0_config_0,
		    PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY,
		    &pinmux_sam0_api);
#endif

#if DT_ATMEL_SAM0_PINMUX_PINMUX_B_BASE_ADDRESS
static const struct pinmux_sam0_config pinmux_sam0_config_1 = {
	.regs = (PortGroup *)DT_ATMEL_SAM0_PINMUX_PINMUX_B_BASE_ADDRESS,
};

DEVICE_AND_API_INIT(pinmux_sam0_1, DT_ATMEL_SAM0_PINMUX_PINMUX_B_LABEL,
		    pinmux_sam0_init, NULL, &pinmux_sam0_config_1,
		    PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY,
		    &pinmux_sam0_api);
#endif

#if DT_ATMEL_SAM0_PINMUX_PINMUX_C_BASE_ADDRESS
static const struct pinmux_sam0_config pinmux_sam0_config_2 = {
	.regs = (PortGroup *)DT_ATMEL_SAM0_PINMUX_PINMUX_C_BASE_ADDRESS,
};

DEVICE_AND_API_INIT(pinmux_sam0_2, DT_ATMEL_SAM0_PINMUX_PINMUX_C_LABEL,
		    pinmux_sam0_init, NULL, &pinmux_sam0_config_2,
		    PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY,
		    &pinmux_sam0_api);
#endif

#if DT_ATMEL_SAM0_PINMUX_PINMUX_D_BASE_ADDRESS
static const struct pinmux_sam0_config pinmux_sam0_config_3 = {
	.regs = (PortGroup *)DT_ATMEL_SAM0_PINMUX_PINMUX_D_BASE_ADDRESS,
};

DEVICE_AND_API_INIT(pinmux_sam0_3, DT_ATMEL_SAM0_PINMUX_PINMUX_D_LABEL,
		    pinmux_sam0_init, NULL, &pinmux_sam0_config_3,
		    PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY,
		    &pinmux_sam0_api);
#endif