1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2024 Inochi Amaoto <inochiama@outlook.com>
4  */
5 
6 #ifndef _PINCTRL_SOPHGO_H
7 #define _PINCTRL_SOPHGO_H
8 
9 #include <linux/device.h>
10 #include <linux/mutex.h>
11 #include <linux/pinctrl/pinctrl.h>
12 #include <linux/platform_device.h>
13 #include <linux/spinlock.h>
14 
15 #include "../core.h"
16 
17 struct sophgo_pinctrl;
18 
19 struct sophgo_pin {
20 	u16				id;
21 	u16				flags;
22 };
23 
24 struct sophgo_pin_mux_config {
25 	const struct sophgo_pin	*pin;
26 	u32			config;
27 };
28 
29 /**
30  * struct sophgo_cfg_ops - pin configuration operations
31  *
32  * @pctrl_init: soc specific init callback
33  * @verify_pinmux_config: verify the pinmux config for a pin
34  * @verify_pin_group: verify the whole pinmux group
35  * @dt_node_to_map_post: post init for the pinmux config map
36  * @compute_pinconf_config: compute pinconf config
37  * @set_pinconf_config: set pinconf config (the caller holds lock)
38  * @set_pinmux_config: set mux config (the caller holds lock)
39  */
40 struct sophgo_cfg_ops {
41 	int (*pctrl_init)(struct platform_device *pdev,
42 			  struct sophgo_pinctrl *pctrl);
43 	int (*verify_pinmux_config)(const struct sophgo_pin_mux_config *config);
44 	int (*verify_pin_group)(const struct sophgo_pin_mux_config *pinmuxs,
45 				unsigned int npins);
46 	int (*dt_node_to_map_post)(struct device_node *cur,
47 				   struct sophgo_pinctrl *pctrl,
48 				   struct sophgo_pin_mux_config *pinmuxs,
49 				   unsigned int npins);
50 	int (*compute_pinconf_config)(struct sophgo_pinctrl *pctrl,
51 				      const struct sophgo_pin *sp,
52 				      unsigned long *configs,
53 				      unsigned int num_configs,
54 				      u32 *value, u32 *mask);
55 	int (*set_pinconf_config)(struct sophgo_pinctrl *pctrl,
56 				  const struct sophgo_pin *sp,
57 				  u32 value, u32 mask);
58 	void (*set_pinmux_config)(struct sophgo_pinctrl *pctrl,
59 				  const struct sophgo_pin *sp, u32 config);
60 };
61 
62 /**
63  * struct sophgo_vddio_cfg_ops - pin vddio operations
64  *
65  * @get_pull_up: get resistor for pull up;
66  * @get_pull_down: get resistor for pull down.
67  * @get_oc_map: get mapping for typical low level output current value to
68  *	register value map.
69  * @get_schmitt_map: get mapping for register value to typical schmitt
70  *	threshold.
71  */
72 struct sophgo_vddio_cfg_ops {
73 	int (*get_pull_up)(const struct sophgo_pin *pin, const u32 *psmap);
74 	int (*get_pull_down)(const struct sophgo_pin *pin, const u32 *psmap);
75 	int (*get_oc_map)(const struct sophgo_pin *pin, const u32 *psmap,
76 			  const u32 **map);
77 	int (*get_schmitt_map)(const struct sophgo_pin *pin, const u32 *psmap,
78 			       const u32 **map);
79 };
80 
81 struct sophgo_pinctrl_data {
82 	const struct pinctrl_pin_desc		*pins;
83 	const void				*pindata;
84 	const char				* const *pdnames;
85 	const struct sophgo_vddio_cfg_ops	*vddio_ops;
86 	const struct sophgo_cfg_ops		*cfg_ops;
87 	const struct pinctrl_ops		*pctl_ops;
88 	const struct pinmux_ops			*pmx_ops;
89 	const struct pinconf_ops		*pconf_ops;
90 	u16					npins;
91 	u16					npds;
92 	u16					pinsize;
93 };
94 
95 struct sophgo_pinctrl {
96 	struct device				*dev;
97 	struct pinctrl_dev			*pctrl_dev;
98 	const struct sophgo_pinctrl_data	*data;
99 	struct pinctrl_desc			pdesc;
100 
101 	struct mutex				mutex;
102 	raw_spinlock_t				lock;
103 	void					*priv_ctrl;
104 };
105 
106 const struct sophgo_pin *sophgo_get_pin(struct sophgo_pinctrl *pctrl,
107 					unsigned long pin_id);
108 int sophgo_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np,
109 				struct pinctrl_map **maps, unsigned int *num_maps);
110 int sophgo_pmx_set_mux(struct pinctrl_dev *pctldev,
111 		       unsigned int fsel, unsigned int gsel);
112 int sophgo_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin_id,
113 		     unsigned long *configs, unsigned int num_configs);
114 int sophgo_pconf_group_set(struct pinctrl_dev *pctldev, unsigned int gsel,
115 			   unsigned long *configs, unsigned int num_configs);
116 u32 sophgo_pinctrl_typical_pull_down(struct sophgo_pinctrl *pctrl,
117 				     const struct sophgo_pin *pin,
118 				     const u32 *power_cfg);
119 u32 sophgo_pinctrl_typical_pull_up(struct sophgo_pinctrl *pctrl,
120 				   const struct sophgo_pin *pin,
121 				   const u32 *power_cfg);
122 int sophgo_pinctrl_oc2reg(struct sophgo_pinctrl *pctrl,
123 			  const struct sophgo_pin *pin,
124 			  const u32 *power_cfg, u32 target);
125 int sophgo_pinctrl_reg2oc(struct sophgo_pinctrl *pctrl,
126 			  const struct sophgo_pin *pin,
127 			  const u32 *power_cfg, u32 reg);
128 int sophgo_pinctrl_schmitt2reg(struct sophgo_pinctrl *pctrl,
129 			       const struct sophgo_pin *pin,
130 			       const u32 *power_cfg, u32 target);
131 int sophgo_pinctrl_reg2schmitt(struct sophgo_pinctrl *pctrl,
132 			       const struct sophgo_pin *pin,
133 			       const u32 *power_cfg, u32 reg);
134 int sophgo_pinctrl_probe(struct platform_device *pdev);
135 
136 #endif /* _PINCTRL_SOPHGO_H */
137