Lines Matching +full:pin +full:- +full:val
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Realtek DHC pin controller driver
15 #include <linux/pinctrl/pinconf-generic.h>
23 #include "../pinctrl-utils.h"
24 #include "pinctrl-rtd.h"
41 {"realtek,drive-strength-p", RTD_DRIVE_STRENGH_P, 0},
42 {"realtek,drive-strength-n", RTD_DRIVE_STRENGH_N, 0},
43 {"realtek,duty-cycle", RTD_DUTY_CYCLE, 0},
50 return data->info->num_groups; in rtd_pinctrl_get_groups_count()
58 return data->info->groups[selector].name; in rtd_pinctrl_get_group_name()
68 *pins = data->info->groups[selector].pins; in rtd_pinctrl_get_group_pins()
69 *num_pins = data->info->groups[selector].num_pins; in rtd_pinctrl_get_group_pins()
79 const struct rtd_pin_desc *mux = &data->info->muxes[offset]; in rtd_pinctrl_dbg_show()
81 u32 val; in rtd_pinctrl_dbg_show() local
86 if (!mux->name) { in rtd_pinctrl_dbg_show()
90 val = readl_relaxed(data->base + mux->mux_offset); in rtd_pinctrl_dbg_show()
91 mask = mux->mux_mask; in rtd_pinctrl_dbg_show()
92 pin_val = val & mask; in rtd_pinctrl_dbg_show()
95 func = &mux->functions[0]; in rtd_pinctrl_dbg_show()
97 while (func->name) { in rtd_pinctrl_dbg_show()
98 if (func->mux_value == pin_val) { in rtd_pinctrl_dbg_show()
100 seq_printf(s, "[%s] ", func->name); in rtd_pinctrl_dbg_show()
102 seq_printf(s, "%s ", func->name); in rtd_pinctrl_dbg_show()
123 return data->info->num_functions; in rtd_pinctrl_get_functions_count()
131 return data->info->functions[selector].name; in rtd_pinctrl_get_function_name()
141 *groups = data->info->functions[selector].groups; in rtd_pinctrl_get_function_groups()
142 *num_groups = data->info->functions[selector].num_groups; in rtd_pinctrl_get_function_groups()
147 static const struct rtd_pin_desc *rtd_pinctrl_find_mux(struct rtd_pinctrl *data, unsigned int pin) in rtd_pinctrl_find_mux() argument
149 if (data->info->muxes[pin].name) in rtd_pinctrl_find_mux()
150 return &data->info->muxes[pin]; in rtd_pinctrl_find_mux()
156 unsigned int pin, const char *func_name) in rtd_pinctrl_set_one_mux() argument
163 mux = rtd_pinctrl_find_mux(data, pin); in rtd_pinctrl_set_one_mux()
167 if (!mux->functions) { in rtd_pinctrl_set_one_mux()
168 if (!mux->name) in rtd_pinctrl_set_one_mux()
169 dev_err(pcdev->dev, "NULL pin has no functions\n"); in rtd_pinctrl_set_one_mux()
171 dev_err(pcdev->dev, "No functions available for pin %s\n", mux->name); in rtd_pinctrl_set_one_mux()
172 return -ENOTSUPP; in rtd_pinctrl_set_one_mux()
175 for (i = 0; mux->functions[i].name; i++) { in rtd_pinctrl_set_one_mux()
176 if (strcmp(mux->functions[i].name, func_name) != 0) in rtd_pinctrl_set_one_mux()
178 ret = regmap_update_bits(data->regmap_pinctrl, mux->mux_offset, mux->mux_mask, in rtd_pinctrl_set_one_mux()
179 mux->functions[i].mux_value); in rtd_pinctrl_set_one_mux()
183 if (!mux->name) { in rtd_pinctrl_set_one_mux()
184 dev_err(pcdev->dev, "NULL pin provided for function %s\n", func_name); in rtd_pinctrl_set_one_mux()
185 return -EINVAL; in rtd_pinctrl_set_one_mux()
188 dev_err(pcdev->dev, "No function %s available for pin %s\n", func_name, mux->name); in rtd_pinctrl_set_one_mux()
190 return -EINVAL; in rtd_pinctrl_set_one_mux()
203 func_name = data->info->functions[function].name; in rtd_pinctrl_set_mux()
204 group_name = data->info->groups[group].name; in rtd_pinctrl_set_mux()
208 dev_err(pcdev->dev, "Getting pins for group %s failed\n", group_name); in rtd_pinctrl_set_mux()
241 for (i = 0; i < data->info->num_pins; i++) { in rtd_pinctrl_get_pin_by_number()
242 if (data->info->pins[i].number == number) in rtd_pinctrl_get_pin_by_number()
243 return &data->info->pins[i]; in rtd_pinctrl_get_pin_by_number()
250 *rtd_pinctrl_find_config(struct rtd_pinctrl *data, unsigned int pin) in rtd_pinctrl_find_config() argument
252 if (data->info->configs[pin].name) in rtd_pinctrl_find_config()
253 return &data->info->configs[pin]; in rtd_pinctrl_find_config()
259 unsigned int pin) in rtd_pinctrl_find_sconfig() argument
265 pin_desc = rtd_pinctrl_get_pin_by_number(data, pin); in rtd_pinctrl_find_sconfig()
269 pin_name = pin_desc->name; in rtd_pinctrl_find_sconfig()
271 for (i = 0; i < data->info->num_sconfigs; i++) { in rtd_pinctrl_find_sconfig()
272 if (strcmp(data->info->sconfigs[i].name, pin_name) == 0) in rtd_pinctrl_find_sconfig()
273 return &data->info->sconfigs[i]; in rtd_pinctrl_find_sconfig()
288 u32 val; in rtd_pconf_parse_conf() local
291 const char *name = data->info->pins[pinnr].name; in rtd_pconf_parse_conf()
296 dev_err(data->dev, "Not support pin config for pin: %s\n", name); in rtd_pconf_parse_conf()
297 return -ENOTSUPP; in rtd_pconf_parse_conf()
302 if (config_desc->smt_offset == NA) { in rtd_pconf_parse_conf()
303 dev_err(data->dev, "Not support input schmitt for pin: %s\n", name); in rtd_pconf_parse_conf()
304 return -ENOTSUPP; in rtd_pconf_parse_conf()
306 smt_off = config_desc->base_bit + config_desc->smt_offset; in rtd_pconf_parse_conf()
307 reg_off = config_desc->reg_offset; in rtd_pconf_parse_conf()
311 val = set_val ? BIT(smt_off) : 0; in rtd_pconf_parse_conf()
315 if (config_desc->pud_en_offset == NA) { in rtd_pconf_parse_conf()
316 dev_err(data->dev, "Not support push pull for pin: %s\n", name); in rtd_pconf_parse_conf()
317 return -ENOTSUPP; in rtd_pconf_parse_conf()
319 pulen_off = config_desc->base_bit + config_desc->pud_en_offset; in rtd_pconf_parse_conf()
320 reg_off = config_desc->reg_offset; in rtd_pconf_parse_conf()
323 val = 0; in rtd_pconf_parse_conf()
327 if (config_desc->pud_en_offset == NA) { in rtd_pconf_parse_conf()
328 dev_err(data->dev, "Not support bias disable for pin: %s\n", name); in rtd_pconf_parse_conf()
329 return -ENOTSUPP; in rtd_pconf_parse_conf()
331 pulen_off = config_desc->base_bit + config_desc->pud_en_offset; in rtd_pconf_parse_conf()
332 reg_off = config_desc->reg_offset; in rtd_pconf_parse_conf()
335 val = 0; in rtd_pconf_parse_conf()
339 if (config_desc->pud_en_offset == NA) { in rtd_pconf_parse_conf()
340 dev_err(data->dev, "Not support bias pull up for pin:%s\n", name); in rtd_pconf_parse_conf()
341 return -ENOTSUPP; in rtd_pconf_parse_conf()
343 pulen_off = config_desc->base_bit + config_desc->pud_en_offset; in rtd_pconf_parse_conf()
344 pulsel_off = config_desc->base_bit + config_desc->pud_sel_offset; in rtd_pconf_parse_conf()
345 reg_off = config_desc->reg_offset; in rtd_pconf_parse_conf()
348 val = mask; in rtd_pconf_parse_conf()
352 if (config_desc->pud_en_offset == NA) { in rtd_pconf_parse_conf()
353 dev_err(data->dev, "Not support bias pull down for pin: %s\n", name); in rtd_pconf_parse_conf()
354 return -ENOTSUPP; in rtd_pconf_parse_conf()
356 pulen_off = config_desc->base_bit + config_desc->pud_en_offset; in rtd_pconf_parse_conf()
357 pulsel_off = config_desc->base_bit + config_desc->pud_sel_offset; in rtd_pconf_parse_conf()
358 reg_off = config_desc->reg_offset; in rtd_pconf_parse_conf()
361 val = BIT(pulen_off); in rtd_pconf_parse_conf()
365 curr_off = config_desc->base_bit + config_desc->curr_offset; in rtd_pconf_parse_conf()
366 reg_off = config_desc->reg_offset; in rtd_pconf_parse_conf()
368 val = 0; in rtd_pconf_parse_conf()
369 switch (config_desc->curr_type) { in rtd_pconf_parse_conf()
372 val = 0; in rtd_pconf_parse_conf()
374 val = BIT(curr_off); in rtd_pconf_parse_conf()
376 return -EINVAL; in rtd_pconf_parse_conf()
380 val = 0; in rtd_pconf_parse_conf()
382 val = BIT(curr_off); in rtd_pconf_parse_conf()
384 return -EINVAL; in rtd_pconf_parse_conf()
387 dev_err(data->dev, "Not support drive strength for pin: %s\n", name); in rtd_pconf_parse_conf()
388 return -ENOTSUPP; in rtd_pconf_parse_conf()
390 return -EINVAL; in rtd_pconf_parse_conf()
396 if (config_desc->power_offset == NA) { in rtd_pconf_parse_conf()
397 dev_err(data->dev, "Not support power source for pin: %s\n", name); in rtd_pconf_parse_conf()
398 return -ENOTSUPP; in rtd_pconf_parse_conf()
400 reg_off = config_desc->reg_offset; in rtd_pconf_parse_conf()
401 pow_off = config_desc->base_bit + config_desc->power_offset; in rtd_pconf_parse_conf()
404 pow_off -= 32; in rtd_pconf_parse_conf()
408 val = set_val ? mask : 0; in rtd_pconf_parse_conf()
414 dev_err(data->dev, "Not support P driving for pin: %s\n", name); in rtd_pconf_parse_conf()
415 return -ENOTSUPP; in rtd_pconf_parse_conf()
418 reg_off = sconfig_desc->reg_offset; in rtd_pconf_parse_conf()
419 p_off = sconfig_desc->pdrive_offset; in rtd_pconf_parse_conf()
422 p_off -= 32; in rtd_pconf_parse_conf()
424 mask = GENMASK(p_off + sconfig_desc->pdrive_maskbits - 1, p_off); in rtd_pconf_parse_conf()
425 val = set_val << p_off; in rtd_pconf_parse_conf()
431 dev_err(data->dev, "Not support N driving for pin: %s\n", name); in rtd_pconf_parse_conf()
432 return -ENOTSUPP; in rtd_pconf_parse_conf()
435 reg_off = sconfig_desc->reg_offset; in rtd_pconf_parse_conf()
436 n_off = sconfig_desc->ndrive_offset; in rtd_pconf_parse_conf()
439 n_off -= 32; in rtd_pconf_parse_conf()
441 mask = GENMASK(n_off + sconfig_desc->ndrive_maskbits - 1, n_off); in rtd_pconf_parse_conf()
442 val = set_val << n_off; in rtd_pconf_parse_conf()
447 if (!sconfig_desc || sconfig_desc->dcycle_offset == NA) { in rtd_pconf_parse_conf()
448 dev_err(data->dev, "Not support duty cycle for pin: %s\n", name); in rtd_pconf_parse_conf()
449 return -ENOTSUPP; in rtd_pconf_parse_conf()
452 reg_off = config_desc->reg_offset; in rtd_pconf_parse_conf()
453 mask = GENMASK(sconfig_desc->dcycle_offset + in rtd_pconf_parse_conf()
454 sconfig_desc->dcycle_maskbits - 1, sconfig_desc->dcycle_offset); in rtd_pconf_parse_conf()
455 val = set_val << sconfig_desc->dcycle_offset; in rtd_pconf_parse_conf()
459 dev_err(data->dev, "unsupported pinconf: %d\n", (u32)param); in rtd_pconf_parse_conf()
460 return -EINVAL; in rtd_pconf_parse_conf()
463 ret = regmap_update_bits(data->regmap_pinctrl, reg_off, mask, val); in rtd_pconf_parse_conf()
465 dev_err(data->dev, "could not update pinconf(%d) for pin(%s)\n", (u32)param, name); in rtd_pconf_parse_conf()
478 return -ENOTSUPP; in rtd_pin_config_get()
512 group_name = data->info->groups[group].name; in rtd_pin_config_group_set()
516 dev_err(pcdev->dev, "Getting pins for group %s failed\n", group_name); in rtd_pin_config_group_set()
548 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); in rtd_pinctrl_probe()
550 return -ENOMEM; in rtd_pinctrl_probe()
552 data->base = of_iomap(pdev->dev.of_node, 0); in rtd_pinctrl_probe()
553 if (!data->base) in rtd_pinctrl_probe()
554 return -ENOMEM; in rtd_pinctrl_probe()
556 data->dev = &pdev->dev; in rtd_pinctrl_probe()
557 data->info = desc; in rtd_pinctrl_probe()
558 data->desc.name = dev_name(&pdev->dev); in rtd_pinctrl_probe()
559 data->desc.pins = data->info->pins; in rtd_pinctrl_probe()
560 data->desc.npins = data->info->num_pins; in rtd_pinctrl_probe()
561 data->desc.pctlops = &rtd_pinctrl_ops; in rtd_pinctrl_probe()
562 data->desc.pmxops = &rtd_pinmux_ops; in rtd_pinctrl_probe()
563 data->desc.confops = &rtd_pinconf_ops; in rtd_pinctrl_probe()
564 data->desc.custom_params = rtd_custom_bindings; in rtd_pinctrl_probe()
565 data->desc.num_custom_params = ARRAY_SIZE(rtd_custom_bindings); in rtd_pinctrl_probe()
566 data->desc.owner = THIS_MODULE; in rtd_pinctrl_probe()
567 data->regmap_pinctrl = devm_regmap_init_mmio(data->dev, data->base, in rtd_pinctrl_probe()
570 if (IS_ERR(data->regmap_pinctrl)) { in rtd_pinctrl_probe()
571 dev_err(data->dev, "failed to init regmap: %ld\n", in rtd_pinctrl_probe()
572 PTR_ERR(data->regmap_pinctrl)); in rtd_pinctrl_probe()
573 ret = PTR_ERR(data->regmap_pinctrl); in rtd_pinctrl_probe()
577 data->pcdev = pinctrl_register(&data->desc, &pdev->dev, data); in rtd_pinctrl_probe()
578 if (IS_ERR(data->pcdev)) { in rtd_pinctrl_probe()
579 ret = PTR_ERR(data->pcdev); in rtd_pinctrl_probe()
585 dev_dbg(&pdev->dev, "probed\n"); in rtd_pinctrl_probe()
590 iounmap(data->base); in rtd_pinctrl_probe()