xref: /linux/drivers/net/dsa/motorcomm/smi.h (revision e9423a64d382ba77a2906f365416714ede67328e)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright (c) 2026 David Yang
4  */
5 
6 #ifndef _YT_SMI_H
7 #define _YT_SMI_H
8 
9 #include <linux/types.h>
10 #include <linux/wordpart.h>
11 
12 struct yt921x_priv;
13 
14 int yt921x_reg_read(struct yt921x_priv *priv, u32 reg, u32 *valp);
15 int yt921x_reg_write(struct yt921x_priv *priv, u32 reg, u32 val);
16 int yt921x_reg_wait(struct yt921x_priv *priv, u32 reg, u32 mask, u32 *valp);
17 int yt921x_reg_update_bits(struct yt921x_priv *priv, u32 reg, u32 mask,
18 			   u32 val);
19 
20 static inline int
21 yt921x_reg_set_bits(struct yt921x_priv *priv, u32 reg, u32 mask)
22 {
23 	return yt921x_reg_update_bits(priv, reg, 0, mask);
24 }
25 
26 static inline int
27 yt921x_reg_clear_bits(struct yt921x_priv *priv, u32 reg, u32 mask)
28 {
29 	return yt921x_reg_update_bits(priv, reg, mask, 0);
30 }
31 
32 static inline int
33 yt921x_reg_toggle_bits(struct yt921x_priv *priv, u32 reg, u32 mask, bool set)
34 {
35 	return yt921x_reg_update_bits(priv, reg, mask, !set ? 0 : mask);
36 }
37 
38 /* Some multi-word registers, like VLANn_CTRL, should be treated as a single
39  * long register. More specifically, writes to parts of its words won't become
40  * visible, until the last word is written.
41  *
42  * Here we require full read and write operations over these registers to
43  * eliminate potential issues, although partial reads/writes are also possible.
44  */
45 
46 static inline void update_ctrls_unaligned(u32 *lo, u32 *hi, u64 mask, u64 val)
47 {
48 	*lo &= ~lower_32_bits(mask);
49 	*hi &= ~upper_32_bits(mask);
50 	*lo |= lower_32_bits(val);
51 	*hi |= upper_32_bits(val);
52 }
53 
54 int yt921x_reg64_write(struct yt921x_priv *priv, u32 reg, const u32 *vals);
55 int yt921x_reg64_update_bits(struct yt921x_priv *priv, u32 reg,
56 			     const u32 *masks, const u32 *vals);
57 int yt921x_reg64_clear_bits(struct yt921x_priv *priv, u32 reg,
58 			    const u32 *masks);
59 int yt921x_reg96_write(struct yt921x_priv *priv, u32 reg, const u32 *vals);
60 
61 #endif
62