• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14 
15 #include <linux/export.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/pinctrl/pinconf.h>
18 #include <linux/pinctrl/pinconf-generic.h>
19 #include <linux/pinctrl/pinctrl.h>
20 #include <linux/pinctrl/pinmux.h>
21 #include <linux/platform_device.h>
22 #include <linux/regmap.h>
23 
24 #include "../core.h"
25 #include "../pinctrl-utils.h"
26 #include "pinctrl-uniphier.h"
27 
28 struct uniphier_pinctrl_priv {
29 	struct pinctrl_dev *pctldev;
30 	struct regmap *regmap;
31 	struct uniphier_pinctrl_socdata *socdata;
32 };
33 
uniphier_pctl_get_groups_count(struct pinctrl_dev * pctldev)34 static int uniphier_pctl_get_groups_count(struct pinctrl_dev *pctldev)
35 {
36 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
37 
38 	return priv->socdata->groups_count;
39 }
40 
uniphier_pctl_get_group_name(struct pinctrl_dev * pctldev,unsigned selector)41 static const char *uniphier_pctl_get_group_name(struct pinctrl_dev *pctldev,
42 						unsigned selector)
43 {
44 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
45 
46 	return priv->socdata->groups[selector].name;
47 }
48 
uniphier_pctl_get_group_pins(struct pinctrl_dev * pctldev,unsigned selector,const unsigned ** pins,unsigned * num_pins)49 static int uniphier_pctl_get_group_pins(struct pinctrl_dev *pctldev,
50 					unsigned selector,
51 					const unsigned **pins,
52 					unsigned *num_pins)
53 {
54 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
55 
56 	*pins = priv->socdata->groups[selector].pins;
57 	*num_pins = priv->socdata->groups[selector].num_pins;
58 
59 	return 0;
60 }
61 
62 #ifdef CONFIG_DEBUG_FS
uniphier_pctl_pin_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned offset)63 static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
64 				       struct seq_file *s, unsigned offset)
65 {
66 	const struct pinctrl_pin_desc *pin = &pctldev->desc->pins[offset];
67 	const char *pull_dir, *drv_str;
68 
69 	switch (uniphier_pin_get_pull_dir(pin->drv_data)) {
70 	case UNIPHIER_PIN_PULL_UP:
71 		pull_dir = "UP";
72 		break;
73 	case UNIPHIER_PIN_PULL_DOWN:
74 		pull_dir = "DOWN";
75 		break;
76 	case UNIPHIER_PIN_PULL_UP_FIXED:
77 		pull_dir = "UP(FIXED)";
78 		break;
79 	case UNIPHIER_PIN_PULL_DOWN_FIXED:
80 		pull_dir = "DOWN(FIXED)";
81 		break;
82 	case UNIPHIER_PIN_PULL_NONE:
83 		pull_dir = "NONE";
84 		break;
85 	default:
86 		BUG();
87 	}
88 
89 	switch (uniphier_pin_get_drv_str(pin->drv_data)) {
90 	case UNIPHIER_PIN_DRV_4_8:
91 		drv_str = "4/8(mA)";
92 		break;
93 	case UNIPHIER_PIN_DRV_8_12_16_20:
94 		drv_str = "8/12/16/20(mA)";
95 		break;
96 	case UNIPHIER_PIN_DRV_FIXED_4:
97 		drv_str = "4(mA)";
98 		break;
99 	case UNIPHIER_PIN_DRV_FIXED_5:
100 		drv_str = "5(mA)";
101 		break;
102 	case UNIPHIER_PIN_DRV_FIXED_8:
103 		drv_str = "8(mA)";
104 		break;
105 	case UNIPHIER_PIN_DRV_NONE:
106 		drv_str = "NONE";
107 		break;
108 	default:
109 		BUG();
110 	}
111 
112 	seq_printf(s, " PULL_DIR=%s  DRV_STR=%s", pull_dir, drv_str);
113 }
114 #endif
115 
116 static const struct pinctrl_ops uniphier_pctlops = {
117 	.get_groups_count = uniphier_pctl_get_groups_count,
118 	.get_group_name = uniphier_pctl_get_group_name,
119 	.get_group_pins = uniphier_pctl_get_group_pins,
120 #ifdef CONFIG_DEBUG_FS
121 	.pin_dbg_show = uniphier_pctl_pin_dbg_show,
122 #endif
123 	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
124 	.dt_free_map = pinctrl_utils_dt_free_map,
125 };
126 
uniphier_conf_pin_bias_get(struct pinctrl_dev * pctldev,const struct pinctrl_pin_desc * pin,enum pin_config_param param)127 static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev,
128 				      const struct pinctrl_pin_desc *pin,
129 				      enum pin_config_param param)
130 {
131 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
132 	enum uniphier_pin_pull_dir pull_dir =
133 				uniphier_pin_get_pull_dir(pin->drv_data);
134 	unsigned int pupdctrl, reg, shift, val;
135 	unsigned int expected = 1;
136 	int ret;
137 
138 	switch (param) {
139 	case PIN_CONFIG_BIAS_DISABLE:
140 		if (pull_dir == UNIPHIER_PIN_PULL_NONE)
141 			return 0;
142 		if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED ||
143 		    pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED)
144 			return -EINVAL;
145 		expected = 0;
146 		break;
147 	case PIN_CONFIG_BIAS_PULL_UP:
148 		if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED)
149 			return 0;
150 		if (pull_dir != UNIPHIER_PIN_PULL_UP)
151 			return -EINVAL;
152 		break;
153 	case PIN_CONFIG_BIAS_PULL_DOWN:
154 		if (pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED)
155 			return 0;
156 		if (pull_dir != UNIPHIER_PIN_PULL_DOWN)
157 			return -EINVAL;
158 		break;
159 	default:
160 		BUG();
161 	}
162 
163 	pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data);
164 
165 	reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
166 	shift = pupdctrl % 32;
167 
168 	ret = regmap_read(priv->regmap, reg, &val);
169 	if (ret)
170 		return ret;
171 
172 	val = (val >> shift) & 1;
173 
174 	return (val == expected) ? 0 : -EINVAL;
175 }
176 
uniphier_conf_pin_drive_get(struct pinctrl_dev * pctldev,const struct pinctrl_pin_desc * pin,u16 * strength)177 static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev,
178 				       const struct pinctrl_pin_desc *pin,
179 				       u16 *strength)
180 {
181 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
182 	enum uniphier_pin_drv_str drv_str =
183 				uniphier_pin_get_drv_str(pin->drv_data);
184 	const unsigned int strength_4_8[] = {4, 8};
185 	const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20};
186 	const unsigned int *supported_strength;
187 	unsigned int drvctrl, reg, shift, mask, width, val;
188 	int ret;
189 
190 	switch (drv_str) {
191 	case UNIPHIER_PIN_DRV_4_8:
192 		supported_strength = strength_4_8;
193 		width = 1;
194 		break;
195 	case UNIPHIER_PIN_DRV_8_12_16_20:
196 		supported_strength = strength_8_12_16_20;
197 		width = 2;
198 		break;
199 	case UNIPHIER_PIN_DRV_FIXED_4:
200 		*strength = 4;
201 		return 0;
202 	case UNIPHIER_PIN_DRV_FIXED_5:
203 		*strength = 5;
204 		return 0;
205 	case UNIPHIER_PIN_DRV_FIXED_8:
206 		*strength = 8;
207 		return 0;
208 	default:
209 		/* drive strength control is not supported for this pin */
210 		return -EINVAL;
211 	}
212 
213 	drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
214 	drvctrl *= width;
215 
216 	reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
217 			     UNIPHIER_PINCTRL_DRVCTRL_BASE;
218 
219 	reg += drvctrl / 32 * 4;
220 	shift = drvctrl % 32;
221 	mask = (1U << width) - 1;
222 
223 	ret = regmap_read(priv->regmap, reg, &val);
224 	if (ret)
225 		return ret;
226 
227 	*strength = supported_strength[(val >> shift) & mask];
228 
229 	return 0;
230 }
231 
uniphier_conf_pin_input_enable_get(struct pinctrl_dev * pctldev,const struct pinctrl_pin_desc * pin)232 static int uniphier_conf_pin_input_enable_get(struct pinctrl_dev *pctldev,
233 					const struct pinctrl_pin_desc *pin)
234 {
235 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
236 	unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data);
237 	unsigned int val;
238 	int ret;
239 
240 	if (iectrl == UNIPHIER_PIN_IECTRL_NONE)
241 		/* This pin is always input-enabled. */
242 		return 0;
243 
244 	ret = regmap_read(priv->regmap, UNIPHIER_PINCTRL_IECTRL, &val);
245 	if (ret)
246 		return ret;
247 
248 	return val & BIT(iectrl) ? 0 : -EINVAL;
249 }
250 
uniphier_conf_pin_config_get(struct pinctrl_dev * pctldev,unsigned pin,unsigned long * configs)251 static int uniphier_conf_pin_config_get(struct pinctrl_dev *pctldev,
252 					unsigned pin,
253 					unsigned long *configs)
254 {
255 	const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin];
256 	enum pin_config_param param = pinconf_to_config_param(*configs);
257 	bool has_arg = false;
258 	u16 arg;
259 	int ret;
260 
261 	switch (param) {
262 	case PIN_CONFIG_BIAS_DISABLE:
263 	case PIN_CONFIG_BIAS_PULL_UP:
264 	case PIN_CONFIG_BIAS_PULL_DOWN:
265 		ret = uniphier_conf_pin_bias_get(pctldev, pin_desc, param);
266 		break;
267 	case PIN_CONFIG_DRIVE_STRENGTH:
268 		ret = uniphier_conf_pin_drive_get(pctldev, pin_desc, &arg);
269 		has_arg = true;
270 		break;
271 	case PIN_CONFIG_INPUT_ENABLE:
272 		ret = uniphier_conf_pin_input_enable_get(pctldev, pin_desc);
273 		break;
274 	default:
275 		/* unsupported parameter */
276 		ret = -EINVAL;
277 		break;
278 	}
279 
280 	if (ret == 0 && has_arg)
281 		*configs = pinconf_to_config_packed(param, arg);
282 
283 	return ret;
284 }
285 
uniphier_conf_pin_bias_set(struct pinctrl_dev * pctldev,const struct pinctrl_pin_desc * pin,enum pin_config_param param,u16 arg)286 static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev,
287 				      const struct pinctrl_pin_desc *pin,
288 				      enum pin_config_param param,
289 				      u16 arg)
290 {
291 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
292 	enum uniphier_pin_pull_dir pull_dir =
293 				uniphier_pin_get_pull_dir(pin->drv_data);
294 	unsigned int pupdctrl, reg, shift;
295 	unsigned int val = 1;
296 
297 	switch (param) {
298 	case PIN_CONFIG_BIAS_DISABLE:
299 		if (pull_dir == UNIPHIER_PIN_PULL_NONE)
300 			return 0;
301 		if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED ||
302 		    pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED) {
303 			dev_err(pctldev->dev,
304 				"can not disable pull register for pin %u (%s)\n",
305 				pin->number, pin->name);
306 			return -EINVAL;
307 		}
308 		val = 0;
309 		break;
310 	case PIN_CONFIG_BIAS_PULL_UP:
311 		if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED && arg != 0)
312 			return 0;
313 		if (pull_dir != UNIPHIER_PIN_PULL_UP) {
314 			dev_err(pctldev->dev,
315 				"pull-up is unsupported for pin %u (%s)\n",
316 				pin->number, pin->name);
317 			return -EINVAL;
318 		}
319 		if (arg == 0) {
320 			dev_err(pctldev->dev, "pull-up can not be total\n");
321 			return -EINVAL;
322 		}
323 		break;
324 	case PIN_CONFIG_BIAS_PULL_DOWN:
325 		if (pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED && arg != 0)
326 			return 0;
327 		if (pull_dir != UNIPHIER_PIN_PULL_DOWN) {
328 			dev_err(pctldev->dev,
329 				"pull-down is unsupported for pin %u (%s)\n",
330 				pin->number, pin->name);
331 			return -EINVAL;
332 		}
333 		if (arg == 0) {
334 			dev_err(pctldev->dev, "pull-down can not be total\n");
335 			return -EINVAL;
336 		}
337 		break;
338 	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
339 		if (pull_dir == UNIPHIER_PIN_PULL_NONE) {
340 			dev_err(pctldev->dev,
341 				"pull-up/down is unsupported for pin %u (%s)\n",
342 				pin->number, pin->name);
343 			return -EINVAL;
344 		}
345 
346 		if (arg == 0)
347 			return 0; /* configuration ingored */
348 		break;
349 	default:
350 		BUG();
351 	}
352 
353 	pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data);
354 
355 	reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
356 	shift = pupdctrl % 32;
357 
358 	return regmap_update_bits(priv->regmap, reg, 1 << shift, val << shift);
359 }
360 
uniphier_conf_pin_drive_set(struct pinctrl_dev * pctldev,const struct pinctrl_pin_desc * pin,u16 strength)361 static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev,
362 				       const struct pinctrl_pin_desc *pin,
363 				       u16 strength)
364 {
365 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
366 	enum uniphier_pin_drv_str drv_str =
367 				uniphier_pin_get_drv_str(pin->drv_data);
368 	const unsigned int strength_4_8[] = {4, 8, -1};
369 	const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20, -1};
370 	const unsigned int *supported_strength;
371 	unsigned int drvctrl, reg, shift, mask, width, val;
372 
373 	switch (drv_str) {
374 	case UNIPHIER_PIN_DRV_4_8:
375 		supported_strength = strength_4_8;
376 		width = 1;
377 		break;
378 	case UNIPHIER_PIN_DRV_8_12_16_20:
379 		supported_strength = strength_8_12_16_20;
380 		width = 2;
381 		break;
382 	default:
383 		dev_err(pctldev->dev,
384 			"cannot change drive strength for pin %u (%s)\n",
385 			pin->number, pin->name);
386 		return -EINVAL;
387 	}
388 
389 	for (val = 0; supported_strength[val] > 0; val++) {
390 		if (supported_strength[val] > strength)
391 			break;
392 	}
393 
394 	if (val == 0) {
395 		dev_err(pctldev->dev,
396 			"unsupported drive strength %u mA for pin %u (%s)\n",
397 			strength, pin->number, pin->name);
398 		return -EINVAL;
399 	}
400 
401 	val--;
402 
403 	drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
404 	drvctrl *= width;
405 
406 	reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
407 			     UNIPHIER_PINCTRL_DRVCTRL_BASE;
408 
409 	reg += drvctrl / 32 * 4;
410 	shift = drvctrl % 32;
411 	mask = (1U << width) - 1;
412 
413 	return regmap_update_bits(priv->regmap, reg,
414 				  mask << shift, val << shift);
415 }
416 
uniphier_conf_pin_input_enable(struct pinctrl_dev * pctldev,const struct pinctrl_pin_desc * pin,u16 enable)417 static int uniphier_conf_pin_input_enable(struct pinctrl_dev *pctldev,
418 					  const struct pinctrl_pin_desc *pin,
419 					  u16 enable)
420 {
421 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
422 	unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data);
423 
424 	if (enable == 0) {
425 		/*
426 		 * Multiple pins share one input enable, so per-pin disabling
427 		 * is impossible.
428 		 */
429 		dev_err(pctldev->dev, "unable to disable input\n");
430 		return -EINVAL;
431 	}
432 
433 	if (iectrl == UNIPHIER_PIN_IECTRL_NONE)
434 		/* This pin is always input-enabled. nothing to do. */
435 		return 0;
436 
437 	return regmap_update_bits(priv->regmap, UNIPHIER_PINCTRL_IECTRL,
438 				  BIT(iectrl), BIT(iectrl));
439 }
440 
uniphier_conf_pin_config_set(struct pinctrl_dev * pctldev,unsigned pin,unsigned long * configs,unsigned num_configs)441 static int uniphier_conf_pin_config_set(struct pinctrl_dev *pctldev,
442 					unsigned pin,
443 					unsigned long *configs,
444 					unsigned num_configs)
445 {
446 	const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin];
447 	int i, ret;
448 
449 	for (i = 0; i < num_configs; i++) {
450 		enum pin_config_param param =
451 					pinconf_to_config_param(configs[i]);
452 		u16 arg = pinconf_to_config_argument(configs[i]);
453 
454 		switch (param) {
455 		case PIN_CONFIG_BIAS_DISABLE:
456 		case PIN_CONFIG_BIAS_PULL_UP:
457 		case PIN_CONFIG_BIAS_PULL_DOWN:
458 		case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
459 			ret = uniphier_conf_pin_bias_set(pctldev, pin_desc,
460 							 param, arg);
461 			break;
462 		case PIN_CONFIG_DRIVE_STRENGTH:
463 			ret = uniphier_conf_pin_drive_set(pctldev, pin_desc,
464 							  arg);
465 			break;
466 		case PIN_CONFIG_INPUT_ENABLE:
467 			ret = uniphier_conf_pin_input_enable(pctldev,
468 							     pin_desc, arg);
469 			break;
470 		default:
471 			dev_err(pctldev->dev,
472 				"unsupported configuration parameter %u\n",
473 				param);
474 			return -EINVAL;
475 		}
476 
477 		if (ret)
478 			return ret;
479 	}
480 
481 	return 0;
482 }
483 
uniphier_conf_pin_config_group_set(struct pinctrl_dev * pctldev,unsigned selector,unsigned long * configs,unsigned num_configs)484 static int uniphier_conf_pin_config_group_set(struct pinctrl_dev *pctldev,
485 					      unsigned selector,
486 					      unsigned long *configs,
487 					      unsigned num_configs)
488 {
489 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
490 	const unsigned *pins = priv->socdata->groups[selector].pins;
491 	unsigned num_pins = priv->socdata->groups[selector].num_pins;
492 	int i, ret;
493 
494 	for (i = 0; i < num_pins; i++) {
495 		ret = uniphier_conf_pin_config_set(pctldev, pins[i],
496 						   configs, num_configs);
497 		if (ret)
498 			return ret;
499 	}
500 
501 	return 0;
502 }
503 
504 static const struct pinconf_ops uniphier_confops = {
505 	.is_generic = true,
506 	.pin_config_get = uniphier_conf_pin_config_get,
507 	.pin_config_set = uniphier_conf_pin_config_set,
508 	.pin_config_group_set = uniphier_conf_pin_config_group_set,
509 };
510 
uniphier_pmx_get_functions_count(struct pinctrl_dev * pctldev)511 static int uniphier_pmx_get_functions_count(struct pinctrl_dev *pctldev)
512 {
513 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
514 
515 	return priv->socdata->functions_count;
516 }
517 
uniphier_pmx_get_function_name(struct pinctrl_dev * pctldev,unsigned selector)518 static const char *uniphier_pmx_get_function_name(struct pinctrl_dev *pctldev,
519 						  unsigned selector)
520 {
521 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
522 
523 	return priv->socdata->functions[selector].name;
524 }
525 
uniphier_pmx_get_function_groups(struct pinctrl_dev * pctldev,unsigned selector,const char * const ** groups,unsigned * num_groups)526 static int uniphier_pmx_get_function_groups(struct pinctrl_dev *pctldev,
527 					    unsigned selector,
528 					    const char * const **groups,
529 					    unsigned *num_groups)
530 {
531 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
532 
533 	*groups = priv->socdata->functions[selector].groups;
534 	*num_groups = priv->socdata->functions[selector].num_groups;
535 
536 	return 0;
537 }
538 
uniphier_pmx_set_one_mux(struct pinctrl_dev * pctldev,unsigned pin,unsigned muxval)539 static int uniphier_pmx_set_one_mux(struct pinctrl_dev *pctldev, unsigned pin,
540 				    unsigned muxval)
541 {
542 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
543 	unsigned mux_bits = priv->socdata->mux_bits;
544 	unsigned reg_stride = priv->socdata->reg_stride;
545 	unsigned reg, reg_end, shift, mask;
546 	int ret;
547 
548 	/* some pins need input-enabling */
549 	ret = uniphier_conf_pin_input_enable(pctldev,
550 					     &pctldev->desc->pins[pin], 1);
551 	if (ret)
552 		return ret;
553 
554 	reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
555 	reg_end = reg + reg_stride;
556 	shift = pin * mux_bits % 32;
557 	mask = (1U << mux_bits) - 1;
558 
559 	/*
560 	 * If reg_stride is greater than 4, the MSB of each pinsel shall be
561 	 * stored in the offset+4.
562 	 */
563 	for (; reg < reg_end; reg += 4) {
564 		ret = regmap_update_bits(priv->regmap, reg,
565 					 mask << shift, muxval << shift);
566 		if (ret)
567 			return ret;
568 		muxval >>= mux_bits;
569 	}
570 
571 	if (priv->socdata->load_pinctrl) {
572 		ret = regmap_write(priv->regmap,
573 				   UNIPHIER_PINCTRL_LOAD_PINMUX, 1);
574 		if (ret)
575 			return ret;
576 	}
577 
578 	return 0;
579 }
580 
uniphier_pmx_set_mux(struct pinctrl_dev * pctldev,unsigned func_selector,unsigned group_selector)581 static int uniphier_pmx_set_mux(struct pinctrl_dev *pctldev,
582 				unsigned func_selector,
583 				unsigned group_selector)
584 {
585 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
586 	const struct uniphier_pinctrl_group *grp =
587 					&priv->socdata->groups[group_selector];
588 	int i;
589 	int ret;
590 
591 	for (i = 0; i < grp->num_pins; i++) {
592 		ret = uniphier_pmx_set_one_mux(pctldev, grp->pins[i],
593 					       grp->muxvals[i]);
594 		if (ret)
595 			return ret;
596 	}
597 
598 	return 0;
599 }
600 
uniphier_pmx_gpio_request_enable(struct pinctrl_dev * pctldev,struct pinctrl_gpio_range * range,unsigned offset)601 static int uniphier_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
602 					    struct pinctrl_gpio_range *range,
603 					    unsigned offset)
604 {
605 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
606 	const struct uniphier_pinctrl_group *groups = priv->socdata->groups;
607 	int groups_count = priv->socdata->groups_count;
608 	enum uniphier_pinmux_gpio_range_type range_type;
609 	int i, j;
610 
611 	if (strstr(range->name, "irq"))
612 		range_type = UNIPHIER_PINMUX_GPIO_RANGE_IRQ;
613 	else
614 		range_type = UNIPHIER_PINMUX_GPIO_RANGE_PORT;
615 
616 	for (i = 0; i < groups_count; i++) {
617 		if (groups[i].range_type != range_type)
618 			continue;
619 
620 		for (j = 0; j < groups[i].num_pins; j++)
621 			if (groups[i].pins[j] == offset)
622 				goto found;
623 	}
624 
625 	dev_err(pctldev->dev, "pin %u does not support GPIO\n", offset);
626 	return -EINVAL;
627 
628 found:
629 	return uniphier_pmx_set_one_mux(pctldev, offset, groups[i].muxvals[j]);
630 }
631 
632 static const struct pinmux_ops uniphier_pmxops = {
633 	.get_functions_count = uniphier_pmx_get_functions_count,
634 	.get_function_name = uniphier_pmx_get_function_name,
635 	.get_function_groups = uniphier_pmx_get_function_groups,
636 	.set_mux = uniphier_pmx_set_mux,
637 	.gpio_request_enable = uniphier_pmx_gpio_request_enable,
638 	.strict = true,
639 };
640 
uniphier_pinctrl_probe(struct platform_device * pdev,struct pinctrl_desc * desc,struct uniphier_pinctrl_socdata * socdata)641 int uniphier_pinctrl_probe(struct platform_device *pdev,
642 			   struct pinctrl_desc *desc,
643 			   struct uniphier_pinctrl_socdata *socdata)
644 {
645 	struct device *dev = &pdev->dev;
646 	struct uniphier_pinctrl_priv *priv;
647 
648 	if (!socdata ||
649 	    !socdata->groups ||
650 	    !socdata->groups_count ||
651 	    !socdata->functions ||
652 	    !socdata->functions_count ||
653 	    !socdata->mux_bits ||
654 	    !socdata->reg_stride) {
655 		dev_err(dev, "pinctrl socdata lacks necessary members\n");
656 		return -EINVAL;
657 	}
658 
659 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
660 	if (!priv)
661 		return -ENOMEM;
662 
663 	priv->regmap = syscon_node_to_regmap(dev->of_node);
664 	if (IS_ERR(priv->regmap)) {
665 		dev_err(dev, "failed to get regmap\n");
666 		return PTR_ERR(priv->regmap);
667 	}
668 
669 	priv->socdata = socdata;
670 	desc->pctlops = &uniphier_pctlops;
671 	desc->pmxops = &uniphier_pmxops;
672 	desc->confops = &uniphier_confops;
673 
674 	priv->pctldev = pinctrl_register(desc, dev, priv);
675 	if (IS_ERR(priv->pctldev)) {
676 		dev_err(dev, "failed to register UniPhier pinctrl driver\n");
677 		return PTR_ERR(priv->pctldev);
678 	}
679 
680 	platform_set_drvdata(pdev, priv);
681 
682 	return 0;
683 }
684 EXPORT_SYMBOL_GPL(uniphier_pinctrl_probe);
685 
uniphier_pinctrl_remove(struct platform_device * pdev)686 int uniphier_pinctrl_remove(struct platform_device *pdev)
687 {
688 	struct uniphier_pinctrl_priv *priv = platform_get_drvdata(pdev);
689 
690 	pinctrl_unregister(priv->pctldev);
691 
692 	return 0;
693 }
694 EXPORT_SYMBOL_GPL(uniphier_pinctrl_remove);
695