/* * 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 #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) { return 0; } DEVICE_AND_API_INIT(pmux_dev, CONFIG_PINMUX_DEV_NAME, &pinmux_dev_init, NULL, NULL, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &api_funcs);