102 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/* Copyright (C) 2019 IBM Corp. */3 4/* Pieces to enable drivers to implement the .set callback */5 6#include "pinmux-aspeed.h"7 8static const char *const aspeed_pinmux_ips[] = {9 [ASPEED_IP_SCU] = "SCU",10 [ASPEED_IP_GFX] = "GFX",11 [ASPEED_IP_LPC] = "LPC",12};13 14static inline void aspeed_sig_desc_print_val(15 const struct aspeed_sig_desc *desc, bool enable, u32 rv)16{17 pr_debug("Want %s%X[0x%08X]=0x%X, got 0x%X from 0x%08X\n",18 aspeed_pinmux_ips[desc->ip], desc->reg,19 desc->mask, enable ? desc->enable : desc->disable,20 (rv & desc->mask) >> __ffs(desc->mask), rv);21}22 23/**24 * aspeed_sig_desc_eval() - Query the enabled or disabled state of a signal25 * descriptor.26 *27 * @desc: The signal descriptor of interest28 * @enabled: True to query the enabled state, false to query disabled state29 * @map: The IP block's regmap instance30 *31 * Return: 1 if the descriptor's bitfield is configured to the state32 * selected by @enabled, 0 if not, and less than zero if an unrecoverable33 * failure occurred34 *35 * Evaluation of descriptor state is non-trivial in that it is not a binary36 * outcome: The bitfields can be greater than one bit in size and thus can take37 * a value that is neither the enabled nor disabled state recorded in the38 * descriptor (typically this means a different function to the one of interest39 * is enabled). Thus we must explicitly test for either condition as required.40 */41int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,42 bool enabled, struct regmap *map)43{44 int ret;45 unsigned int raw;46 u32 want;47 48 if (!map)49 return -ENODEV;50 51 ret = regmap_read(map, desc->reg, &raw);52 if (ret)53 return ret;54 55 aspeed_sig_desc_print_val(desc, enabled, raw);56 want = enabled ? desc->enable : desc->disable;57 58 return ((raw & desc->mask) >> __ffs(desc->mask)) == want;59}60 61/**62 * aspeed_sig_expr_eval - Query the enabled or disabled state for a63 * mux function's signal on a pin64 *65 * @ctx: The driver context for the pinctrl IP66 * @expr: An expression controlling the signal for a mux function on a pin67 * @enabled: True to query the enabled state, false to query disabled state68 *69 * Return: 1 if the expression composed by @enabled evaluates true, 0 if not,70 * and less than zero if an unrecoverable failure occurred.71 *72 * A mux function is enabled or disabled if the function's signal expression73 * for each pin in the function's pin group evaluates true for the desired74 * state. An signal expression evaluates true if all of its associated signal75 * descriptors evaluate true for the desired state.76 *77 * If an expression's state is described by more than one bit, either through78 * multi-bit bitfields in a single signal descriptor or through multiple signal79 * descriptors of a single bit then it is possible for the expression to be in80 * neither the enabled nor disabled state. Thus we must explicitly test for81 * either condition as required.82 */83int aspeed_sig_expr_eval(struct aspeed_pinmux_data *ctx,84 const struct aspeed_sig_expr *expr, bool enabled)85{86 int ret;87 int i;88 89 if (ctx->ops->eval)90 return ctx->ops->eval(ctx, expr, enabled);91 92 for (i = 0; i < expr->ndescs; i++) {93 const struct aspeed_sig_desc *desc = &expr->descs[i];94 95 ret = aspeed_sig_desc_eval(desc, enabled, ctx->maps[desc->ip]);96 if (ret <= 0)97 return ret;98 }99 100 return 1;101}102