1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2020 TOSHIBA CORPORATION
4 * Copyright (c) 2020 Toshiba Electronic Devices & Storage Corporation
5 * Copyright (c) 2020 Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
8 #include <linux/init.h>
11 #include <linux/platform_device.h>
12 #include <linux/pinctrl/pinctrl.h>
13 #include <linux/pinctrl/pinmux.h>
14 #include <linux/pinctrl/pinconf.h>
15 #include <linux/pinctrl/pinconf-generic.h>
16 #include "pinctrl-common.h"
18 #include "../pinconf.h"
19 #include "../pinctrl-utils.h"
21 #define DSEL_MASK GENMASK(3, 0)
24 struct visconti_pinctrl
{
27 struct pinctrl_dev
*pctl
;
28 struct pinctrl_desc pctl_desc
;
30 const struct visconti_pinctrl_devdata
*devdata
;
32 spinlock_t lock
; /* protect pinctrl register */
36 static int visconti_pin_config_set(struct pinctrl_dev
*pctldev
,
38 unsigned long *configs
,
39 unsigned int num_configs
)
41 struct visconti_pinctrl
*priv
= pinctrl_dev_get_drvdata(pctldev
);
42 const struct visconti_desc_pin
*pin
= &priv
->devdata
->pins
[_pin
];
43 enum pin_config_param param
;
46 unsigned int val
, set_val
, pude_val
;
49 dev_dbg(priv
->dev
, "%s: pin = %d (%s)\n", __func__
, _pin
, pin
->pin
.name
);
51 spin_lock_irqsave(&priv
->lock
, flags
);
53 for (i
= 0; i
< num_configs
; i
++) {
57 param
= pinconf_to_config_param(configs
[i
]);
59 case PIN_CONFIG_BIAS_PULL_UP
:
62 case PIN_CONFIG_BIAS_PULL_DOWN
:
63 /* update pudsel setting */
64 val
= readl(priv
->base
+ pin
->pudsel_offset
);
65 val
&= ~BIT(pin
->pud_shift
);
66 val
|= set_val
<< pin
->pud_shift
;
67 writel(val
, priv
->base
+ pin
->pudsel_offset
);
70 case PIN_CONFIG_BIAS_DISABLE
:
71 /* update pude setting */
72 val
= readl(priv
->base
+ pin
->pude_offset
);
73 val
&= ~BIT(pin
->pud_shift
);
74 val
|= pude_val
<< pin
->pud_shift
;
75 writel(val
, priv
->base
+ pin
->pude_offset
);
76 dev_dbg(priv
->dev
, "BIAS(%d): off = 0x%x val = 0x%x\n",
77 param
, pin
->pude_offset
, val
);
80 case PIN_CONFIG_DRIVE_STRENGTH
:
81 arg
= pinconf_to_config_argument(configs
[i
]);
82 dev_dbg(priv
->dev
, "DRV_STR arg = %d\n", arg
);
91 * I/O drive capacity setting:
99 set_val
= DIV_ROUND_CLOSEST(arg
, 2) - 1;
105 /* update drive setting */
106 val
= readl(priv
->base
+ pin
->dsel_offset
);
107 val
&= ~(DSEL_MASK
<< pin
->dsel_shift
);
108 val
|= set_val
<< pin
->dsel_shift
;
109 writel(val
, priv
->base
+ pin
->dsel_offset
);
118 spin_unlock_irqrestore(&priv
->lock
, flags
);
122 static int visconti_pin_config_group_set(struct pinctrl_dev
*pctldev
,
123 unsigned int selector
,
124 unsigned long *configs
,
125 unsigned int num_configs
)
127 struct visconti_pinctrl
*priv
= pinctrl_dev_get_drvdata(pctldev
);
128 const unsigned int *pins
;
129 unsigned int num_pins
;
132 pins
= priv
->devdata
->groups
[selector
].pins
;
133 num_pins
= priv
->devdata
->groups
[selector
].nr_pins
;
135 dev_dbg(priv
->dev
, "%s: select = %d, n_pin = %d, n_config = %d\n",
136 __func__
, selector
, num_pins
, num_configs
);
138 for (i
= 0; i
< num_pins
; i
++) {
139 ret
= visconti_pin_config_set(pctldev
, pins
[i
],
140 configs
, num_configs
);
147 static const struct pinconf_ops visconti_pinconf_ops
= {
149 .pin_config_set
= visconti_pin_config_set
,
150 .pin_config_group_set
= visconti_pin_config_group_set
,
151 .pin_config_config_dbg_show
= pinconf_generic_dump_config
,
155 static int visconti_get_groups_count(struct pinctrl_dev
*pctldev
)
157 struct visconti_pinctrl
*priv
= pinctrl_dev_get_drvdata(pctldev
);
159 return priv
->devdata
->nr_groups
;
162 static const char *visconti_get_group_name(struct pinctrl_dev
*pctldev
,
163 unsigned int selector
)
165 struct visconti_pinctrl
*priv
= pinctrl_dev_get_drvdata(pctldev
);
167 return priv
->devdata
->groups
[selector
].name
;
170 static int visconti_get_group_pins(struct pinctrl_dev
*pctldev
,
171 unsigned int selector
,
172 const unsigned int **pins
,
173 unsigned int *num_pins
)
175 struct visconti_pinctrl
*priv
= pinctrl_dev_get_drvdata(pctldev
);
177 *pins
= priv
->devdata
->groups
[selector
].pins
;
178 *num_pins
= priv
->devdata
->groups
[selector
].nr_pins
;
183 static const struct pinctrl_ops visconti_pinctrl_ops
= {
184 .get_groups_count
= visconti_get_groups_count
,
185 .get_group_name
= visconti_get_group_name
,
186 .get_group_pins
= visconti_get_group_pins
,
187 .dt_node_to_map
= pinconf_generic_dt_node_to_map_group
,
188 .dt_free_map
= pinctrl_utils_free_map
,
192 static int visconti_get_functions_count(struct pinctrl_dev
*pctldev
)
194 struct visconti_pinctrl
*priv
= pinctrl_dev_get_drvdata(pctldev
);
196 return priv
->devdata
->nr_functions
;
199 static const char *visconti_get_function_name(struct pinctrl_dev
*pctldev
,
200 unsigned int selector
)
202 struct visconti_pinctrl
*priv
= pinctrl_dev_get_drvdata(pctldev
);
204 return priv
->devdata
->functions
[selector
].name
;
207 static int visconti_get_function_groups(struct pinctrl_dev
*pctldev
,
208 unsigned int selector
,
209 const char * const **groups
,
210 unsigned * const num_groups
)
212 struct visconti_pinctrl
*priv
= pinctrl_dev_get_drvdata(pctldev
);
214 *groups
= priv
->devdata
->functions
[selector
].groups
;
215 *num_groups
= priv
->devdata
->functions
[selector
].nr_groups
;
220 static int visconti_set_mux(struct pinctrl_dev
*pctldev
,
221 unsigned int function
, unsigned int group
)
223 struct visconti_pinctrl
*priv
= pinctrl_dev_get_drvdata(pctldev
);
224 const struct visconti_pin_function
*func
= &priv
->devdata
->functions
[function
];
225 const struct visconti_pin_group
*grp
= &priv
->devdata
->groups
[group
];
226 const struct visconti_mux
*mux
= &grp
->mux
;
230 dev_dbg(priv
->dev
, "%s: function = %d(%s) group = %d(%s)\n", __func__
,
231 function
, func
->name
, group
, grp
->name
);
233 spin_lock_irqsave(&priv
->lock
, flags
);
236 val
= readl(priv
->base
+ mux
->offset
);
239 writel(val
, priv
->base
+ mux
->offset
);
241 spin_unlock_irqrestore(&priv
->lock
, flags
);
243 dev_dbg(priv
->dev
, "[%x]: 0x%x\n", mux
->offset
, val
);
248 static int visconti_gpio_request_enable(struct pinctrl_dev
*pctldev
,
249 struct pinctrl_gpio_range
*range
,
252 struct visconti_pinctrl
*priv
= pinctrl_dev_get_drvdata(pctldev
);
253 const struct visconti_mux
*gpio_mux
= &priv
->devdata
->gpio_mux
[pin
];
257 dev_dbg(priv
->dev
, "%s: pin = %d\n", __func__
, pin
);
260 spin_lock_irqsave(&priv
->lock
, flags
);
261 val
= readl(priv
->base
+ gpio_mux
->offset
);
262 val
&= ~gpio_mux
->mask
;
263 val
|= gpio_mux
->val
;
264 writel(val
, priv
->base
+ gpio_mux
->offset
);
265 spin_unlock_irqrestore(&priv
->lock
, flags
);
270 static const struct pinmux_ops visconti_pinmux_ops
= {
271 .get_functions_count
= visconti_get_functions_count
,
272 .get_function_name
= visconti_get_function_name
,
273 .get_function_groups
= visconti_get_function_groups
,
274 .set_mux
= visconti_set_mux
,
275 .gpio_request_enable
= visconti_gpio_request_enable
,
279 int visconti_pinctrl_probe(struct platform_device
*pdev
,
280 const struct visconti_pinctrl_devdata
*devdata
)
282 struct device
*dev
= &pdev
->dev
;
283 struct visconti_pinctrl
*priv
;
284 struct pinctrl_pin_desc
*pins
;
287 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
292 priv
->devdata
= devdata
;
293 spin_lock_init(&priv
->lock
);
295 priv
->base
= devm_platform_ioremap_resource(pdev
, 0);
296 if (IS_ERR(priv
->base
)) {
297 dev_err(dev
, "unable to map I/O space\n");
298 return PTR_ERR(priv
->base
);
301 pins
= devm_kcalloc(dev
, devdata
->nr_pins
,
302 sizeof(*pins
), GFP_KERNEL
);
306 for (i
= 0; i
< devdata
->nr_pins
; i
++)
307 pins
[i
] = devdata
->pins
[i
].pin
;
309 priv
->pctl_desc
.name
= dev_name(dev
);
310 priv
->pctl_desc
.owner
= THIS_MODULE
;
311 priv
->pctl_desc
.pins
= pins
;
312 priv
->pctl_desc
.npins
= devdata
->nr_pins
;
313 priv
->pctl_desc
.confops
= &visconti_pinconf_ops
;
314 priv
->pctl_desc
.pctlops
= &visconti_pinctrl_ops
;
315 priv
->pctl_desc
.pmxops
= &visconti_pinmux_ops
;
317 ret
= devm_pinctrl_register_and_init(dev
, &priv
->pctl_desc
,
320 dev_err(dev
, "couldn't register pinctrl: %d\n", ret
);
325 devdata
->unlock(priv
->base
);
327 return pinctrl_enable(priv
->pctl
);