root/drivers/pinctrl/aspeed/pinmux-aspeed.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. aspeed_sig_desc_print_val
  2. aspeed_sig_desc_eval
  3. aspeed_sig_expr_eval

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /* Copyright (C) 2019 IBM Corp. */
   3 
   4 /* Pieces to enable drivers to implement the .set callback */
   5 
   6 #include "pinmux-aspeed.h"
   7 
   8 static const char *const aspeed_pinmux_ips[] = {
   9         [ASPEED_IP_SCU] = "SCU",
  10         [ASPEED_IP_GFX] = "GFX",
  11         [ASPEED_IP_LPC] = "LPC",
  12 };
  13 
  14 static 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  * Query the enabled or disabled state of a signal descriptor
  25  *
  26  * @desc: The signal descriptor of interest
  27  * @enabled: True to query the enabled state, false to query disabled state
  28  * @map: The IP block's regmap instance
  29  *
  30  * Return: 1 if the descriptor's bitfield is configured to the state
  31  * selected by @enabled, 0 if not, and less than zero if an unrecoverable
  32  * failure occurred
  33  *
  34  * Evaluation of descriptor state is non-trivial in that it is not a binary
  35  * outcome: The bitfields can be greater than one bit in size and thus can take
  36  * a value that is neither the enabled nor disabled state recorded in the
  37  * descriptor (typically this means a different function to the one of interest
  38  * is enabled). Thus we must explicitly test for either condition as required.
  39  */
  40 int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
  41                          bool enabled, struct regmap *map)
  42 {
  43         int ret;
  44         unsigned int raw;
  45         u32 want;
  46 
  47         if (!map)
  48                 return -ENODEV;
  49 
  50         ret = regmap_read(map, desc->reg, &raw);
  51         if (ret)
  52                 return ret;
  53 
  54         aspeed_sig_desc_print_val(desc, enabled, raw);
  55         want = enabled ? desc->enable : desc->disable;
  56 
  57         return ((raw & desc->mask) >> __ffs(desc->mask)) == want;
  58 }
  59 
  60 /**
  61  * Query the enabled or disabled state for a mux function's signal on a pin
  62  *
  63  * @ctx: The driver context for the pinctrl IP
  64  * @expr: An expression controlling the signal for a mux function on a pin
  65  * @enabled: True to query the enabled state, false to query disabled state
  66  *
  67  * Return: 1 if the expression composed by @enabled evaluates true, 0 if not,
  68  * and less than zero if an unrecoverable failure occurred.
  69  *
  70  * A mux function is enabled or disabled if the function's signal expression
  71  * for each pin in the function's pin group evaluates true for the desired
  72  * state. An signal expression evaluates true if all of its associated signal
  73  * descriptors evaluate true for the desired state.
  74  *
  75  * If an expression's state is described by more than one bit, either through
  76  * multi-bit bitfields in a single signal descriptor or through multiple signal
  77  * descriptors of a single bit then it is possible for the expression to be in
  78  * neither the enabled nor disabled state. Thus we must explicitly test for
  79  * either condition as required.
  80  */
  81 int aspeed_sig_expr_eval(struct aspeed_pinmux_data *ctx,
  82                          const struct aspeed_sig_expr *expr, bool enabled)
  83 {
  84         int ret;
  85         int i;
  86 
  87         if (ctx->ops->eval)
  88                 return ctx->ops->eval(ctx, expr, enabled);
  89 
  90         for (i = 0; i < expr->ndescs; i++) {
  91                 const struct aspeed_sig_desc *desc = &expr->descs[i];
  92 
  93                 ret = aspeed_sig_desc_eval(desc, enabled, ctx->maps[desc->ip]);
  94                 if (ret <= 0)
  95                         return ret;
  96         }
  97 
  98         return 1;
  99 }

/* [<][>][^][v][top][bottom][index][help] */