Commit | Line | Data |
---|---|---|
37c646dc HC |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * PEF2256 also known as FALC56 driver | |
4 | * | |
5 | * Copyright 2023 CS GROUP France | |
6 | * | |
7 | * Author: Herve Codina <herve.codina@bootlin.com> | |
8 | */ | |
9 | ||
10 | #include <linux/bitfield.h> | |
11 | #include <linux/framer/pef2256.h> | |
12 | #include <linux/module.h> | |
13 | #include <linux/of.h> | |
14 | #include <linux/pinctrl/pinctrl.h> | |
15 | #include <linux/pinctrl/pinconf-generic.h> | |
16 | #include <linux/pinctrl/pinmux.h> | |
17 | #include <linux/platform_device.h> | |
18 | #include <linux/regmap.h> | |
19 | #include <linux/slab.h> | |
20 | ||
21 | /* Port Configuration 1..4 */ | |
22 | #define PEF2256_PC1 0x80 | |
23 | #define PEF2256_PC2 0x81 | |
24 | #define PEF2256_PC3 0x82 | |
25 | #define PEF2256_PC4 0x83 | |
26 | #define PEF2256_12_PC_RPC_MASK GENMASK(6, 4) | |
27 | #define PEF2256_12_PC_RPC_SYPR FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x0) | |
28 | #define PEF2256_12_PC_RPC_RFM FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x1) | |
29 | #define PEF2256_12_PC_RPC_RFMB FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x2) | |
30 | #define PEF2256_12_PC_RPC_RSIGM FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x3) | |
31 | #define PEF2256_12_PC_RPC_RSIG FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x4) | |
32 | #define PEF2256_12_PC_RPC_DLR FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x5) | |
33 | #define PEF2256_12_PC_RPC_FREEZE FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x6) | |
34 | #define PEF2256_12_PC_RPC_RFSP FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x7) | |
35 | #define PEF2256_12_PC_XPC_MASK GENMASK(4, 0) | |
36 | #define PEF2256_12_PC_XPC_SYPX FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x0) | |
37 | #define PEF2256_12_PC_XPC_XFMS FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x1) | |
38 | #define PEF2256_12_PC_XPC_XSIG FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x2) | |
39 | #define PEF2256_12_PC_XPC_TCLK FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x3) | |
40 | #define PEF2256_12_PC_XPC_XMFB FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x4) | |
41 | #define PEF2256_12_PC_XPC_XSIGM FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x5) | |
42 | #define PEF2256_12_PC_XPC_DLX FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x6) | |
43 | #define PEF2256_12_PC_XPC_XCLK FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x7) | |
44 | #define PEF2256_12_PC_XPC_XLT FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x8) | |
45 | #define PEF2256_2X_PC_RPC_MASK GENMASK(7, 4) | |
46 | #define PEF2256_2X_PC_RPC_SYPR FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x0) | |
47 | #define PEF2256_2X_PC_RPC_RFM FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x1) | |
48 | #define PEF2256_2X_PC_RPC_RFMB FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x2) | |
49 | #define PEF2256_2X_PC_RPC_RSIGM FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x3) | |
50 | #define PEF2256_2X_PC_RPC_RSIG FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x4) | |
51 | #define PEF2256_2X_PC_RPC_DLR FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x5) | |
52 | #define PEF2256_2X_PC_RPC_FREEZE FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x6) | |
53 | #define PEF2256_2X_PC_RPC_RFSP FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x7) | |
54 | #define PEF2256_2X_PC_RPC_GPI FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x9) | |
55 | #define PEF2256_2X_PC_RPC_GPOH FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0xa) | |
56 | #define PEF2256_2X_PC_RPC_GPOL FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0xb) | |
57 | #define PEF2256_2X_PC_RPC_LOS FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0xc) | |
58 | #define PEF2256_2X_PC_XPC_MASK GENMASK(3, 0) | |
59 | #define PEF2256_2X_PC_XPC_SYPX FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x0) | |
60 | #define PEF2256_2X_PC_XPC_XFMS FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x1) | |
61 | #define PEF2256_2X_PC_XPC_XSIG FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x2) | |
62 | #define PEF2256_2X_PC_XPC_TCLK FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x3) | |
63 | #define PEF2256_2X_PC_XPC_XMFB FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x4) | |
64 | #define PEF2256_2X_PC_XPC_XSIGM FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x5) | |
65 | #define PEF2256_2X_PC_XPC_DLX FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x6) | |
66 | #define PEF2256_2X_PC_XPC_XCLK FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x7) | |
67 | #define PEF2256_2X_PC_XPC_XLT FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x8) | |
68 | #define PEF2256_2X_PC_XPC_GPI FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x9) | |
69 | #define PEF2256_2X_PC_XPC_GPOH FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0xa) | |
70 | #define PEF2256_2X_PC_XPC_GPOL FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0xb) | |
71 | ||
72 | struct pef2256_pinreg_desc { | |
73 | int offset; | |
74 | u8 mask; | |
75 | }; | |
76 | ||
77 | struct pef2256_function_desc { | |
78 | const char *name; | |
79 | const char * const*groups; | |
80 | unsigned int ngroups; | |
81 | u8 func_val; | |
82 | }; | |
83 | ||
84 | struct pef2256_pinctrl { | |
85 | struct device *dev; | |
86 | struct regmap *regmap; | |
87 | enum pef2256_version version; | |
88 | struct pinctrl_desc pctrl_desc; | |
89 | const struct pef2256_function_desc *functions; | |
90 | unsigned int nfunctions; | |
91 | }; | |
92 | ||
93 | static int pef2256_get_groups_count(struct pinctrl_dev *pctldev) | |
94 | { | |
95 | struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev); | |
96 | ||
97 | /* We map 1 group <-> 1 pin */ | |
98 | return pef2256->pctrl_desc.npins; | |
99 | } | |
100 | ||
101 | static const char *pef2256_get_group_name(struct pinctrl_dev *pctldev, | |
102 | unsigned int selector) | |
103 | { | |
104 | struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev); | |
105 | ||
106 | /* We map 1 group <-> 1 pin */ | |
107 | return pef2256->pctrl_desc.pins[selector].name; | |
108 | } | |
109 | ||
110 | static int pef2256_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector, | |
111 | const unsigned int **pins, | |
112 | unsigned int *num_pins) | |
113 | { | |
114 | struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev); | |
115 | ||
116 | /* We map 1 group <-> 1 pin */ | |
117 | *pins = &pef2256->pctrl_desc.pins[selector].number; | |
118 | *num_pins = 1; | |
119 | ||
120 | return 0; | |
121 | } | |
122 | ||
123 | static const struct pinctrl_ops pef2256_pctlops = { | |
124 | .get_groups_count = pef2256_get_groups_count, | |
125 | .get_group_name = pef2256_get_group_name, | |
126 | .get_group_pins = pef2256_get_group_pins, | |
127 | .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, | |
128 | .dt_free_map = pinconf_generic_dt_free_map, | |
129 | }; | |
130 | ||
131 | static int pef2256_get_functions_count(struct pinctrl_dev *pctldev) | |
132 | { | |
133 | struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev); | |
134 | ||
135 | return pef2256->nfunctions; | |
136 | } | |
137 | ||
138 | static const char *pef2256_get_function_name(struct pinctrl_dev *pctldev, | |
139 | unsigned int selector) | |
140 | { | |
141 | struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev); | |
142 | ||
143 | return pef2256->functions[selector].name; | |
144 | } | |
145 | ||
146 | static int pef2256_get_function_groups(struct pinctrl_dev *pctldev, unsigned int selector, | |
147 | const char * const **groups, | |
148 | unsigned * const num_groups) | |
149 | { | |
150 | struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev); | |
151 | ||
152 | *groups = pef2256->functions[selector].groups; | |
153 | *num_groups = pef2256->functions[selector].ngroups; | |
154 | return 0; | |
155 | } | |
156 | ||
157 | static int pef2256_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, | |
158 | unsigned int group_selector) | |
159 | { | |
160 | struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev); | |
161 | const struct pef2256_pinreg_desc *pinreg_desc; | |
162 | u8 func_val; | |
163 | ||
164 | /* We map 1 group <-> 1 pin */ | |
165 | pinreg_desc = pef2256->pctrl_desc.pins[group_selector].drv_data; | |
166 | func_val = pef2256->functions[func_selector].func_val; | |
167 | ||
168 | return regmap_update_bits(pef2256->regmap, pinreg_desc->offset, | |
169 | pinreg_desc->mask, func_val); | |
170 | } | |
171 | ||
172 | static const struct pinmux_ops pef2256_pmxops = { | |
173 | .get_functions_count = pef2256_get_functions_count, | |
174 | .get_function_name = pef2256_get_function_name, | |
175 | .get_function_groups = pef2256_get_function_groups, | |
176 | .set_mux = pef2256_set_mux, | |
177 | }; | |
178 | ||
179 | #define PEF2256_PINCTRL_PIN(_number, _name, _offset, _mask) { \ | |
180 | .number = _number, \ | |
181 | .name = _name, \ | |
182 | .drv_data = &(struct pef2256_pinreg_desc) { \ | |
183 | .offset = _offset, \ | |
184 | .mask = _mask, \ | |
185 | }, \ | |
186 | } | |
187 | ||
188 | static const struct pinctrl_pin_desc pef2256_v12_pins[] = { | |
189 | PEF2256_PINCTRL_PIN(0, "RPA", PEF2256_PC1, PEF2256_12_PC_RPC_MASK), | |
190 | PEF2256_PINCTRL_PIN(1, "RPB", PEF2256_PC2, PEF2256_12_PC_RPC_MASK), | |
191 | PEF2256_PINCTRL_PIN(2, "RPC", PEF2256_PC3, PEF2256_12_PC_RPC_MASK), | |
192 | PEF2256_PINCTRL_PIN(3, "RPD", PEF2256_PC4, PEF2256_12_PC_RPC_MASK), | |
193 | PEF2256_PINCTRL_PIN(4, "XPA", PEF2256_PC1, PEF2256_12_PC_XPC_MASK), | |
194 | PEF2256_PINCTRL_PIN(5, "XPB", PEF2256_PC2, PEF2256_12_PC_XPC_MASK), | |
195 | PEF2256_PINCTRL_PIN(6, "XPC", PEF2256_PC3, PEF2256_12_PC_XPC_MASK), | |
196 | PEF2256_PINCTRL_PIN(7, "XPD", PEF2256_PC4, PEF2256_12_PC_XPC_MASK), | |
197 | }; | |
198 | ||
199 | static const struct pinctrl_pin_desc pef2256_v2x_pins[] = { | |
200 | PEF2256_PINCTRL_PIN(0, "RPA", PEF2256_PC1, PEF2256_2X_PC_RPC_MASK), | |
201 | PEF2256_PINCTRL_PIN(1, "RPB", PEF2256_PC2, PEF2256_2X_PC_RPC_MASK), | |
202 | PEF2256_PINCTRL_PIN(2, "RPC", PEF2256_PC3, PEF2256_2X_PC_RPC_MASK), | |
203 | PEF2256_PINCTRL_PIN(3, "RPD", PEF2256_PC4, PEF2256_2X_PC_RPC_MASK), | |
204 | PEF2256_PINCTRL_PIN(4, "XPA", PEF2256_PC1, PEF2256_2X_PC_XPC_MASK), | |
205 | PEF2256_PINCTRL_PIN(5, "XPB", PEF2256_PC2, PEF2256_2X_PC_XPC_MASK), | |
206 | PEF2256_PINCTRL_PIN(6, "XPC", PEF2256_PC3, PEF2256_2X_PC_XPC_MASK), | |
207 | PEF2256_PINCTRL_PIN(7, "XPD", PEF2256_PC4, PEF2256_2X_PC_XPC_MASK), | |
208 | }; | |
209 | ||
210 | static const char *const pef2256_rp_groups[] = { "RPA", "RPB", "RPC", "RPD" }; | |
211 | static const char *const pef2256_xp_groups[] = { "XPA", "XPB", "XPC", "XPD" }; | |
212 | static const char *const pef2256_all_groups[] = { "RPA", "RPB", "RPC", "RPD", | |
213 | "XPA", "XPB", "XPC", "XPD" }; | |
214 | ||
215 | #define PEF2256_FUNCTION(_name, _func_val, _groups) { \ | |
216 | .name = _name, \ | |
217 | .groups = _groups, \ | |
218 | .ngroups = ARRAY_SIZE(_groups), \ | |
219 | .func_val = _func_val, \ | |
220 | } | |
221 | ||
222 | static const struct pef2256_function_desc pef2256_v2x_functions[] = { | |
223 | PEF2256_FUNCTION("SYPR", PEF2256_2X_PC_RPC_SYPR, pef2256_rp_groups), | |
224 | PEF2256_FUNCTION("RFM", PEF2256_2X_PC_RPC_RFM, pef2256_rp_groups), | |
225 | PEF2256_FUNCTION("RFMB", PEF2256_2X_PC_RPC_RFMB, pef2256_rp_groups), | |
226 | PEF2256_FUNCTION("RSIGM", PEF2256_2X_PC_RPC_RSIGM, pef2256_rp_groups), | |
227 | PEF2256_FUNCTION("RSIG", PEF2256_2X_PC_RPC_RSIG, pef2256_rp_groups), | |
228 | PEF2256_FUNCTION("DLR", PEF2256_2X_PC_RPC_DLR, pef2256_rp_groups), | |
229 | PEF2256_FUNCTION("FREEZE", PEF2256_2X_PC_RPC_FREEZE, pef2256_rp_groups), | |
230 | PEF2256_FUNCTION("RFSP", PEF2256_2X_PC_RPC_RFSP, pef2256_rp_groups), | |
231 | PEF2256_FUNCTION("LOS", PEF2256_2X_PC_RPC_LOS, pef2256_rp_groups), | |
232 | ||
233 | PEF2256_FUNCTION("SYPX", PEF2256_2X_PC_XPC_SYPX, pef2256_xp_groups), | |
234 | PEF2256_FUNCTION("XFMS", PEF2256_2X_PC_XPC_XFMS, pef2256_xp_groups), | |
235 | PEF2256_FUNCTION("XSIG", PEF2256_2X_PC_XPC_XSIG, pef2256_xp_groups), | |
236 | PEF2256_FUNCTION("TCLK", PEF2256_2X_PC_XPC_TCLK, pef2256_xp_groups), | |
237 | PEF2256_FUNCTION("XMFB", PEF2256_2X_PC_XPC_XMFB, pef2256_xp_groups), | |
238 | PEF2256_FUNCTION("XSIGM", PEF2256_2X_PC_XPC_XSIGM, pef2256_xp_groups), | |
239 | PEF2256_FUNCTION("DLX", PEF2256_2X_PC_XPC_DLX, pef2256_xp_groups), | |
240 | PEF2256_FUNCTION("XCLK", PEF2256_2X_PC_XPC_XCLK, pef2256_xp_groups), | |
241 | PEF2256_FUNCTION("XLT", PEF2256_2X_PC_XPC_XLT, pef2256_xp_groups), | |
242 | ||
243 | PEF2256_FUNCTION("GPI", PEF2256_2X_PC_RPC_GPI | PEF2256_2X_PC_XPC_GPI, | |
244 | pef2256_all_groups), | |
245 | PEF2256_FUNCTION("GPOH", PEF2256_2X_PC_RPC_GPOH | PEF2256_2X_PC_XPC_GPOH, | |
246 | pef2256_all_groups), | |
247 | PEF2256_FUNCTION("GPOL", PEF2256_2X_PC_RPC_GPOL | PEF2256_2X_PC_XPC_GPOL, | |
248 | pef2256_all_groups), | |
249 | }; | |
250 | ||
251 | static const struct pef2256_function_desc pef2256_v12_functions[] = { | |
252 | PEF2256_FUNCTION("SYPR", PEF2256_12_PC_RPC_SYPR, pef2256_rp_groups), | |
253 | PEF2256_FUNCTION("RFM", PEF2256_12_PC_RPC_RFM, pef2256_rp_groups), | |
254 | PEF2256_FUNCTION("RFMB", PEF2256_12_PC_RPC_RFMB, pef2256_rp_groups), | |
255 | PEF2256_FUNCTION("RSIGM", PEF2256_12_PC_RPC_RSIGM, pef2256_rp_groups), | |
256 | PEF2256_FUNCTION("RSIG", PEF2256_12_PC_RPC_RSIG, pef2256_rp_groups), | |
257 | PEF2256_FUNCTION("DLR", PEF2256_12_PC_RPC_DLR, pef2256_rp_groups), | |
258 | PEF2256_FUNCTION("FREEZE", PEF2256_12_PC_RPC_FREEZE, pef2256_rp_groups), | |
259 | PEF2256_FUNCTION("RFSP", PEF2256_12_PC_RPC_RFSP, pef2256_rp_groups), | |
260 | ||
261 | PEF2256_FUNCTION("SYPX", PEF2256_12_PC_XPC_SYPX, pef2256_xp_groups), | |
262 | PEF2256_FUNCTION("XFMS", PEF2256_12_PC_XPC_XFMS, pef2256_xp_groups), | |
263 | PEF2256_FUNCTION("XSIG", PEF2256_12_PC_XPC_XSIG, pef2256_xp_groups), | |
264 | PEF2256_FUNCTION("TCLK", PEF2256_12_PC_XPC_TCLK, pef2256_xp_groups), | |
265 | PEF2256_FUNCTION("XMFB", PEF2256_12_PC_XPC_XMFB, pef2256_xp_groups), | |
266 | PEF2256_FUNCTION("XSIGM", PEF2256_12_PC_XPC_XSIGM, pef2256_xp_groups), | |
267 | PEF2256_FUNCTION("DLX", PEF2256_12_PC_XPC_DLX, pef2256_xp_groups), | |
268 | PEF2256_FUNCTION("XCLK", PEF2256_12_PC_XPC_XCLK, pef2256_xp_groups), | |
269 | PEF2256_FUNCTION("XLT", PEF2256_12_PC_XPC_XLT, pef2256_xp_groups), | |
270 | }; | |
271 | ||
272 | static int pef2256_register_pinctrl(struct pef2256_pinctrl *pef2256) | |
273 | { | |
274 | struct pinctrl_dev *pctrl; | |
275 | ||
276 | pef2256->pctrl_desc.name = dev_name(pef2256->dev); | |
277 | pef2256->pctrl_desc.owner = THIS_MODULE; | |
278 | pef2256->pctrl_desc.pctlops = &pef2256_pctlops; | |
279 | pef2256->pctrl_desc.pmxops = &pef2256_pmxops; | |
280 | if (pef2256->version == PEF2256_VERSION_1_2) { | |
281 | pef2256->pctrl_desc.pins = pef2256_v12_pins; | |
282 | pef2256->pctrl_desc.npins = ARRAY_SIZE(pef2256_v12_pins); | |
283 | pef2256->functions = pef2256_v12_functions; | |
284 | pef2256->nfunctions = ARRAY_SIZE(pef2256_v12_functions); | |
285 | } else { | |
286 | pef2256->pctrl_desc.pins = pef2256_v2x_pins; | |
287 | pef2256->pctrl_desc.npins = ARRAY_SIZE(pef2256_v2x_pins); | |
288 | pef2256->functions = pef2256_v2x_functions; | |
289 | pef2256->nfunctions = ARRAY_SIZE(pef2256_v2x_functions); | |
290 | } | |
291 | ||
292 | pctrl = devm_pinctrl_register(pef2256->dev, &pef2256->pctrl_desc, pef2256); | |
293 | if (IS_ERR(pctrl)) | |
294 | return dev_err_probe(pef2256->dev, PTR_ERR(pctrl), | |
295 | "pinctrl driver registration failed\n"); | |
296 | ||
297 | return 0; | |
298 | } | |
299 | ||
300 | static void pef2256_reset_pinmux(struct pef2256_pinctrl *pef2256) | |
301 | { | |
302 | u8 val; | |
303 | /* | |
304 | * Reset values cannot be used. | |
305 | * They define the SYPR/SYPX pin mux for all the RPx and XPx pins and | |
306 | * Only one pin can be muxed to SYPR and one pin can be muxed to SYPX. | |
307 | * Choose here an other reset value. | |
308 | */ | |
309 | if (pef2256->version == PEF2256_VERSION_1_2) | |
310 | val = PEF2256_12_PC_XPC_XCLK | PEF2256_12_PC_RPC_RFSP; | |
311 | else | |
312 | val = PEF2256_2X_PC_XPC_GPI | PEF2256_2X_PC_RPC_GPI; | |
313 | ||
314 | regmap_write(pef2256->regmap, PEF2256_PC1, val); | |
315 | regmap_write(pef2256->regmap, PEF2256_PC2, val); | |
316 | regmap_write(pef2256->regmap, PEF2256_PC3, val); | |
317 | regmap_write(pef2256->regmap, PEF2256_PC4, val); | |
318 | } | |
319 | ||
320 | static int pef2256_pinctrl_probe(struct platform_device *pdev) | |
321 | { | |
322 | struct pef2256_pinctrl *pef2256_pinctrl; | |
323 | struct pef2256 *pef2256; | |
324 | int ret; | |
325 | ||
326 | pef2256_pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pef2256_pinctrl), GFP_KERNEL); | |
327 | if (!pef2256_pinctrl) | |
328 | return -ENOMEM; | |
329 | ||
330 | device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent)); | |
331 | ||
332 | pef2256 = dev_get_drvdata(pdev->dev.parent); | |
333 | ||
334 | pef2256_pinctrl->dev = &pdev->dev; | |
335 | pef2256_pinctrl->regmap = pef2256_get_regmap(pef2256); | |
336 | pef2256_pinctrl->version = pef2256_get_version(pef2256); | |
337 | ||
338 | platform_set_drvdata(pdev, pef2256_pinctrl); | |
339 | ||
340 | pef2256_reset_pinmux(pef2256_pinctrl); | |
341 | ret = pef2256_register_pinctrl(pef2256_pinctrl); | |
342 | if (ret) | |
343 | return ret; | |
344 | ||
345 | return 0; | |
346 | } | |
347 | ||
348 | static struct platform_driver pef2256_pinctrl_driver = { | |
349 | .driver = { | |
350 | .name = "lantiq-pef2256-pinctrl", | |
351 | }, | |
352 | .probe = pef2256_pinctrl_probe, | |
353 | }; | |
354 | module_platform_driver(pef2256_pinctrl_driver); | |
355 | ||
356 | MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>"); | |
357 | MODULE_DESCRIPTION("PEF2256 pin controller driver"); | |
358 | MODULE_LICENSE("GPL"); |