1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#pragma once 14 15#include <unistd.h> 16 17typedef ssize_t mux_feature_t; 18typedef struct mux_sys mux_sys_t; 19 20#include <utils/arith.h> 21 22typedef enum mux_gpio_dir { 23 MUX_DIR_NOT_A_GPIO = 0, 24 MUX_DIR_GPIO_IN = BIT(0), 25 MUX_DIR_GPIO_OUT = BIT(1), 26 MUX_DIR_GPIO_BOTH = (MUX_DIR_GPIO_IN | MUX_DIR_GPIO_OUT) 27} mux_gpio_dir_t; 28 29struct mux_sys { 30 int (*feature_enable)(const mux_sys_t *mux, mux_feature_t, enum mux_gpio_dir); 31 int (*feature_disable)(const mux_sys_t *mux, mux_feature_t); 32 void *(*get_mux_vaddr)(const mux_sys_t *mux); 33 void *priv; 34}; 35 36#include <platsupport/io.h> 37 38static inline int mux_sys_valid(const mux_sys_t *mux_sys) 39{ 40 return mux_sys && mux_sys->priv; 41} 42 43/** 44 * Returns the vaddr of the mux controller so a driver can directly 45 * access the MUX controller and bypass the muxc. 46 */ 47static inline void *mux_sys_get_vaddr(mux_sys_t *mux) 48{ 49 return (mux && mux->get_mux_vaddr) ? mux->get_mux_vaddr(mux) : NULL; 50} 51 52/** 53 * Initialise (IO)MUX sub systems 54 * @param[in] io_ops collection of IO operations for the subsystem to use. 55 * @param[out] mux On success, this will be filled with the appropriate 56 * subsystem data. 57 * @param[in] dependencies As an edge case, if this driver depends on some 58 * other set of drivers, you can pass in instances 59 * of those dependencies as a pointer or array of 60 * pointers here. 61 * @return 0 on success. 62 */ 63int mux_sys_init(ps_io_ops_t *io_ops, void *dependencies, mux_sys_t *mux); 64 65/** 66 * Enable a SoC feature via the IO MUX 67 * @param[in] mux A handle to the mux system 68 * @param[in] mux_feature A SoC specific feature to enable. 69 * @param[in] mux_gpio_dir If the signal being muxed out on the pin is a 70 * a GPIO signal, this might be required by your 71 * platform. For example, if your mux controller has 72 * input and output buffers, you would want to ensure 73 * that the output buffer on the pin is enabled if you 74 * plan to use the pin as a GPIO output. 75 * 76 * If the signal you're muxing out on the pin is not 77 * a GPIO controller, then you should use 78 * MUX_DIR_NOT_A_GPIO. 79 * @return 0 on success 80 */ 81static inline int mux_feature_enable(const mux_sys_t *mux, mux_feature_t mux_feature, 82 enum mux_gpio_dir mux_gpio_dir) 83{ 84 if (mux->feature_enable) { 85 return mux->feature_enable(mux, mux_feature, mux_gpio_dir); 86 } else { 87 return -ENOSYS; 88 } 89} 90 91/** 92 * Explicitly ensure that a certain controller's signals are not being driven 93 * out. 94 * 95 * This is useful if you need to ensure that no signals are output by the 96 * controller while it is being set up. In such a case you'd feature_disable() 97 * the signals, then initialize the controller, then feature_enable() the 98 * controller again. 99 * 100 * @param[in] mux A handle to the mux system 101 * @param[in] mux_feature A SoC specific feature to enable. 102 * @return 0 on success 103 */ 104static inline int mux_feature_disable(mux_sys_t *mux, mux_feature_t mux_feature) 105{ 106 if (mux->feature_disable) { 107 return mux->feature_disable(mux, mux_feature); 108 } else { 109 return -ENOSYS; 110 } 111} 112