diff --git a/drivers/pinmux/Kconfig b/drivers/pinmux/Kconfig index 943644320e4..c2b489fe12c 100644 --- a/drivers/pinmux/Kconfig +++ b/drivers/pinmux/Kconfig @@ -25,6 +25,8 @@ menuconfig PINMUX if PINMUX +source "drivers/pinmux/dev/Kconfig" + config PINMUX_BASE hex "Base Address" depends on PINMUX diff --git a/drivers/pinmux/Makefile b/drivers/pinmux/Makefile index 3e3bf5f8482..a40d160efca 100644 --- a/drivers/pinmux/Makefile +++ b/drivers/pinmux/Makefile @@ -1,5 +1,6 @@ ccflags-y +=-I$(srctree)/drivers +# Board initialization obj-$(CONFIG_PINMUX_K64) += frdm_k64f/pinmux_k64.o frdm_k64f/pinmux_board_frdm_k64f.o obj-$(CONFIG_PINMUX_STM32) += pinmux_stm32.o obj-$(CONFIG_BOARD_ARDUINO_101) += quark_mcu/pinmux_board_arduino_101.o @@ -7,3 +8,7 @@ obj-$(CONFIG_BOARD_ARDUINO_DUE) += sam3x/pinmux_board_arduino_due.o obj-$(CONFIG_BOARD_GALILEO) += galileo/pinmux_board_galileo.o galileo/pinmux_galileo.o obj-$(CONFIG_BOARD_QUARK_D2000_CRB) += quark_mcu/pinmux_board_quark_d2000_crb.o obj-$(CONFIG_BOARD_QUARK_SE_DEVBOARD) += quark_mcu/pinmux_board_quark_se_dev.o + +# "runtime" pinmux +obj-$(CONFIG_PINMUX_DEV) += dev/ + diff --git a/drivers/pinmux/dev/Kconfig b/drivers/pinmux/dev/Kconfig new file mode 100644 index 00000000000..29d6c38392d --- /dev/null +++ b/drivers/pinmux/dev/Kconfig @@ -0,0 +1,41 @@ +# Kconfig - Pinmux Dev configuration options + +# +# Copyright (c) 2016 Intel Corporation +# +# 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. +# + +config PINMUX_DEV + bool "Configure pinmux for early board testing" + depends on PINMUX + default n + help + Enables the use of the pinmux_set and pinmux_get functions for early + prototyping on new hardware. WARNING: When using these options, it + is possible to permanently damage the hardware. + +config PINMUX_DEV_NAME + string "Configure pinmux for early board testing" + depends on PINMUX + default "pmux_dev" + help + The name of the pinmux dev driver. + +config PINMUX_DEV_ATMEL_SAM3X + bool "Enable pinmux dev driver for Atmel SAM3X boards" + depends on PINMUX_DEV && SOC_ATMEL_SAM3X8E + help + Enables the pinmux dev driver for boards based on the + Atmel SAM3X family of microcontrollers. + default n diff --git a/drivers/pinmux/dev/Makefile b/drivers/pinmux/dev/Makefile new file mode 100644 index 00000000000..035fa38c9bd --- /dev/null +++ b/drivers/pinmux/dev/Makefile @@ -0,0 +1,3 @@ +ccflags-$(CONFIG_PINMUX_DEV) +=-I$(srctree)/drivers + +obj-$(CONFIG_PINMUX_DEV_ATMEL_SAM3X) += pinmux_dev_atmel_sam3x.o diff --git a/drivers/pinmux/dev/pinmux_dev_atmel_sam3x.c b/drivers/pinmux/dev/pinmux_dev_atmel_sam3x.c new file mode 100644 index 00000000000..082ba2dff94 --- /dev/null +++ b/drivers/pinmux/dev/pinmux_dev_atmel_sam3x.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * 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 +#include + +#include +#include +#include +#include +#include + +static volatile struct __pio *_get_port(uint32_t pin) +{ + uint32_t port_num = pin / 32; + + switch (port_num) { + case 0: + return __PIOA; + case 1: + return __PIOB; + case 2: + return __PIOC; + case 3: + return __PIOD; + default: + /* return null if pin is outside range */ + return NULL; + } +} + +static int pinmux_set(struct device *dev, uint32_t pin, uint32_t func) +{ + volatile struct __pio *port = _get_port(pin); + uint32_t tmp; + + ARG_UNUSED(dev); + + if (!port) { + return -EINVAL; + } + + tmp = port->absr; + if (func) { + tmp |= (1 << (pin % 32)); + } else { + tmp &= ~(1 << (pin % 32)); + } + port->absr = tmp; + + return 0; +} + +static int pinmux_get(struct device *dev, uint32_t pin, uint32_t *func) +{ + volatile struct __pio *port = _get_port(pin); + + ARG_UNUSED(dev); + + if (!port) { + return -EINVAL; + } + + *func = (port->absr & (1 << (pin % 32))) ? 1 : 0; + + return 0; +} + +static int pinmux_pullup(struct device *dev, uint32_t pin, uint8_t func) +{ + volatile struct __pio *port = _get_port(pin); + + ARG_UNUSED(dev); + + if (!port) { + return -EINVAL; + } + + if (func) { + port->puer = (1 << (pin % 32)); + } else { + port->pudr = (1 << (pin % 32)); + } + + return 0; +} +static int pinmux_input(struct device *dev, uint32_t pin, uint8_t func) +{ + volatile struct __pio *port = _get_port(pin); + + ARG_UNUSED(dev); + + if (!port) { + return -EINVAL; + } + + if (func) { + port->odr = (1 << (pin % 32)); + } else { + port->oer = (1 << (pin % 32)); + } + + return 0; +} + +static struct pinmux_driver_api api_funcs = { + .set = pinmux_set, + .get = pinmux_get, + .pullup = pinmux_pullup, + .input = pinmux_input +}; + +static int pinmux_dev_init(struct device *port) +{ + port->driver_api = &api_funcs; + + return 0; +} + +DEVICE_INIT(pmux_dev, CONFIG_PINMUX_DEV_NAME, &pinmux_dev_init, NULL, NULL, + PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);