Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.10.11.
  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
  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 signal
 25 * descriptor.
 26 *
 27 * @desc: The signal descriptor of interest
 28 * @enabled: True to query the enabled state, false to query disabled state
 29 * @map: The IP block's regmap instance
 30 *
 31 * Return: 1 if the descriptor's bitfield is configured to the state
 32 * selected by @enabled, 0 if not, and less than zero if an unrecoverable
 33 * failure occurred
 34 *
 35 * Evaluation of descriptor state is non-trivial in that it is not a binary
 36 * outcome: The bitfields can be greater than one bit in size and thus can take
 37 * a value that is neither the enabled nor disabled state recorded in the
 38 * descriptor (typically this means a different function to the one of interest
 39 * 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 a
 63 * mux function's signal on a pin
 64 *
 65 * @ctx: The driver context for the pinctrl IP
 66 * @expr: An expression controlling the signal for a mux function on a pin
 67 * @enabled: True to query the enabled state, false to query disabled state
 68 *
 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 expression
 73 * for each pin in the function's pin group evaluates true for the desired
 74 * state. An signal expression evaluates true if all of its associated signal
 75 * descriptors evaluate true for the desired state.
 76 *
 77 * If an expression's state is described by more than one bit, either through
 78 * multi-bit bitfields in a single signal descriptor or through multiple signal
 79 * descriptors of a single bit then it is possible for the expression to be in
 80 * neither the enabled nor disabled state. Thus we must explicitly test for
 81 * 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}