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