Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | /* * Copyright (c) 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <kernel.h> #include <board.h> #include <device.h> #include <errno.h> #include <init.h> #include <pinmux.h> #include <soc.h> #include <misc/util.h> 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 const 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) { ARG_UNUSED(port); return 0; } DEVICE_AND_API_INIT(pmux_dev, CONFIG_PINMUX_DEV_NAME, &pinmux_dev_init, NULL, NULL, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &api_funcs); |