766 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Sophgo CV18XX SoCs pinctrl driver.4 *5 * Copyright (C) 2024 Inochi Amaoto <inochiama@outlook.com>6 *7 */8 9#include <linux/bitfield.h>10#include <linux/export.h>11#include <linux/io.h>12#include <linux/of.h>13#include <linux/platform_device.h>14#include <linux/bsearch.h>15#include <linux/seq_file.h>16#include <linux/spinlock.h>17 18#include <linux/pinctrl/consumer.h>19#include <linux/pinctrl/machine.h>20#include <linux/pinctrl/pinconf-generic.h>21#include <linux/pinctrl/pinconf.h>22#include <linux/pinctrl/pinctrl.h>23#include <linux/pinctrl/pinmux.h>24 25#include <dt-bindings/pinctrl/pinctrl-cv18xx.h>26 27#include "../core.h"28#include "../pinctrl-utils.h"29#include "../pinconf.h"30#include "../pinmux.h"31#include "pinctrl-cv18xx.h"32 33struct cv1800_pinctrl {34 struct device *dev;35 struct pinctrl_dev *pctl_dev;36 const struct cv1800_pinctrl_data *data;37 struct pinctrl_desc pdesc;38 u32 *power_cfg;39 40 struct mutex mutex;41 raw_spinlock_t lock;42 43 void __iomem *regs[2];44};45 46struct cv1800_pin_mux_config {47 struct cv1800_pin *pin;48 u32 config;49};50 51static unsigned int cv1800_dt_get_pin(u32 value)52{53 return value & GENMASK(15, 0);54}55 56static unsigned int cv1800_dt_get_pin_mux(u32 value)57{58 return (value >> 16) & GENMASK(7, 0);59}60 61static unsigned int cv1800_dt_get_pin_mux2(u32 value)62{63 return (value >> 24) & GENMASK(7, 0);64}65 66#define cv1800_pinctrl_get_component_addr(pctrl, _comp) \67 ((pctrl)->regs[(_comp)->area] + (_comp)->offset)68 69static int cv1800_cmp_pin(const void *key, const void *pivot)70{71 const struct cv1800_pin *pin = pivot;72 int pin_id = (long)key;73 int pivid = pin->pin;74 75 return pin_id - pivid;76}77 78static int cv1800_set_power_cfg(struct cv1800_pinctrl *pctrl,79 u8 domain, u32 cfg)80{81 if (domain >= pctrl->data->npd)82 return -ENOTSUPP;83 84 if (pctrl->power_cfg[domain] && pctrl->power_cfg[domain] != cfg)85 return -EINVAL;86 87 pctrl->power_cfg[domain] = cfg;88 89 return 0;90}91 92static int cv1800_get_power_cfg(struct cv1800_pinctrl *pctrl,93 u8 domain)94{95 return pctrl->power_cfg[domain];96}97 98static struct cv1800_pin *cv1800_get_pin(struct cv1800_pinctrl *pctrl,99 unsigned long pin)100{101 return bsearch((void *)pin, pctrl->data->pindata, pctrl->data->npins,102 sizeof(struct cv1800_pin), cv1800_cmp_pin);103}104 105#define PIN_BGA_ID_OFFSET 8106#define PIN_BGA_ID_MASK 0xff107 108static const char *const io_type_desc[] = {109 "1V8",110 "18OD33",111 "AUDIO",112 "ETH"113};114 115static const char *cv1800_get_power_cfg_desc(struct cv1800_pinctrl *pctrl,116 u8 domain)117{118 return pctrl->data->pdnames[domain];119}120 121static void cv1800_pctrl_dbg_show(struct pinctrl_dev *pctldev,122 struct seq_file *seq, unsigned int pin_id)123{124 struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);125 struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);126 enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);127 u32 value;128 void __iomem *reg;129 130 if (pin->pin >> PIN_BGA_ID_OFFSET)131 seq_printf(seq, "pos: %c%u ",132 'A' + (pin->pin >> PIN_BGA_ID_OFFSET) - 1,133 pin->pin & PIN_BGA_ID_MASK);134 else135 seq_printf(seq, "pos: %u ", pin->pin);136 137 seq_printf(seq, "power-domain: %s ",138 cv1800_get_power_cfg_desc(pctrl, pin->power_domain));139 seq_printf(seq, "type: %s ", io_type_desc[type]);140 141 reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux);142 value = readl(reg);143 seq_printf(seq, "mux: 0x%08x ", value);144 145 if (pin->flags & CV1800_PIN_HAVE_MUX2) {146 reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux2);147 value = readl(reg);148 seq_printf(seq, "mux2: 0x%08x ", value);149 }150 151 if (type == IO_TYPE_1V8_ONLY || type == IO_TYPE_1V8_OR_3V3) {152 reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->conf);153 value = readl(reg);154 seq_printf(seq, "conf: 0x%08x ", value);155 }156}157 158static int cv1800_verify_pinmux_config(const struct cv1800_pin_mux_config *config)159{160 unsigned int mux = cv1800_dt_get_pin_mux(config->config);161 unsigned int mux2 = cv1800_dt_get_pin_mux2(config->config);162 163 if (mux > config->pin->mux.max)164 return -EINVAL;165 166 if (config->pin->flags & CV1800_PIN_HAVE_MUX2) {167 if (mux != config->pin->mux2.pfunc)168 return -EINVAL;169 170 if (mux2 > config->pin->mux2.max)171 return -EINVAL;172 } else {173 if (mux2 != PIN_MUX_INVALD)174 return -ENOTSUPP;175 }176 177 return 0;178}179 180static int cv1800_verify_pin_group(const struct cv1800_pin_mux_config *mux,181 unsigned long npins)182{183 enum cv1800_pin_io_type type;184 u8 power_domain;185 int i;186 187 if (npins == 1)188 return 0;189 190 type = cv1800_pin_io_type(mux[0].pin);191 power_domain = mux[0].pin->power_domain;192 193 for (i = 0; i < npins; i++) {194 if (type != cv1800_pin_io_type(mux[i].pin) ||195 power_domain != mux[i].pin->power_domain)196 return -ENOTSUPP;197 }198 199 return 0;200}201 202static int cv1800_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,203 struct device_node *np,204 struct pinctrl_map **maps,205 unsigned int *num_maps)206{207 struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);208 struct device *dev = pctrl->dev;209 struct device_node *child;210 struct pinctrl_map *map;211 const char **grpnames;212 const char *grpname;213 int ngroups = 0;214 int nmaps = 0;215 int ret;216 217 for_each_available_child_of_node(np, child)218 ngroups += 1;219 220 grpnames = devm_kcalloc(dev, ngroups, sizeof(*grpnames), GFP_KERNEL);221 if (!grpnames)222 return -ENOMEM;223 224 map = kcalloc(ngroups * 2, sizeof(*map), GFP_KERNEL);225 if (!map)226 return -ENOMEM;227 228 ngroups = 0;229 mutex_lock(&pctrl->mutex);230 for_each_available_child_of_node(np, child) {231 int npins = of_property_count_u32_elems(child, "pinmux");232 unsigned int *pins;233 struct cv1800_pin_mux_config *pinmuxs;234 u32 config, power;235 int i;236 237 if (npins < 1) {238 dev_err(dev, "invalid pinctrl group %pOFn.%pOFn\n",239 np, child);240 ret = -EINVAL;241 goto dt_failed;242 }243 244 grpname = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn",245 np, child);246 if (!grpname) {247 ret = -ENOMEM;248 goto dt_failed;249 }250 251 grpnames[ngroups++] = grpname;252 253 pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);254 if (!pins) {255 ret = -ENOMEM;256 goto dt_failed;257 }258 259 pinmuxs = devm_kcalloc(dev, npins, sizeof(*pinmuxs), GFP_KERNEL);260 if (!pinmuxs) {261 ret = -ENOMEM;262 goto dt_failed;263 }264 265 for (i = 0; i < npins; i++) {266 ret = of_property_read_u32_index(child, "pinmux",267 i, &config);268 if (ret)269 goto dt_failed;270 271 pins[i] = cv1800_dt_get_pin(config);272 pinmuxs[i].config = config;273 pinmuxs[i].pin = cv1800_get_pin(pctrl, pins[i]);274 275 if (!pinmuxs[i].pin) {276 dev_err(dev, "failed to get pin %d\n", pins[i]);277 ret = -ENODEV;278 goto dt_failed;279 }280 281 ret = cv1800_verify_pinmux_config(&pinmuxs[i]);282 if (ret) {283 dev_err(dev, "group %s pin %d is invalid\n",284 grpname, i);285 goto dt_failed;286 }287 }288 289 ret = cv1800_verify_pin_group(pinmuxs, npins);290 if (ret) {291 dev_err(dev, "group %s is invalid\n", grpname);292 goto dt_failed;293 }294 295 ret = of_property_read_u32(child, "power-source", &power);296 if (ret)297 goto dt_failed;298 299 if (!(power == PIN_POWER_STATE_3V3 || power == PIN_POWER_STATE_1V8)) {300 dev_err(dev, "group %s have unsupported power: %u\n",301 grpname, power);302 ret = -ENOTSUPP;303 goto dt_failed;304 }305 306 ret = cv1800_set_power_cfg(pctrl, pinmuxs[0].pin->power_domain,307 power);308 if (ret)309 goto dt_failed;310 311 map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;312 map[nmaps].data.mux.function = np->name;313 map[nmaps].data.mux.group = grpname;314 nmaps += 1;315 316 ret = pinconf_generic_parse_dt_config(child, pctldev,317 &map[nmaps].data.configs.configs,318 &map[nmaps].data.configs.num_configs);319 if (ret) {320 dev_err(dev, "failed to parse pin config of group %s: %d\n",321 grpname, ret);322 goto dt_failed;323 }324 325 ret = pinctrl_generic_add_group(pctldev, grpname,326 pins, npins, pinmuxs);327 if (ret < 0) {328 dev_err(dev, "failed to add group %s: %d\n", grpname, ret);329 goto dt_failed;330 }331 332 /* don't create a map if there are no pinconf settings */333 if (map[nmaps].data.configs.num_configs == 0)334 continue;335 336 map[nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;337 map[nmaps].data.configs.group_or_pin = grpname;338 nmaps += 1;339 }340 341 ret = pinmux_generic_add_function(pctldev, np->name,342 grpnames, ngroups, NULL);343 if (ret < 0) {344 dev_err(dev, "error adding function %s: %d\n", np->name, ret);345 goto function_failed;346 }347 348 *maps = map;349 *num_maps = nmaps;350 mutex_unlock(&pctrl->mutex);351 352 return 0;353 354dt_failed:355 of_node_put(child);356function_failed:357 pinctrl_utils_free_map(pctldev, map, nmaps);358 mutex_unlock(&pctrl->mutex);359 return ret;360}361 362static const struct pinctrl_ops cv1800_pctrl_ops = {363 .get_groups_count = pinctrl_generic_get_group_count,364 .get_group_name = pinctrl_generic_get_group_name,365 .get_group_pins = pinctrl_generic_get_group_pins,366 .pin_dbg_show = cv1800_pctrl_dbg_show,367 .dt_node_to_map = cv1800_pctrl_dt_node_to_map,368 .dt_free_map = pinctrl_utils_free_map,369};370 371static int cv1800_pmx_set_mux(struct pinctrl_dev *pctldev,372 unsigned int fsel, unsigned int gsel)373{374 struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);375 const struct group_desc *group;376 const struct cv1800_pin_mux_config *configs;377 unsigned int i;378 379 group = pinctrl_generic_get_group(pctldev, gsel);380 if (!group)381 return -EINVAL;382 383 configs = group->data;384 385 for (i = 0; i < group->grp.npins; i++) {386 const struct cv1800_pin *pin = configs[i].pin;387 u32 value = configs[i].config;388 void __iomem *reg_mux;389 void __iomem *reg_mux2;390 unsigned long flags;391 u32 mux;392 u32 mux2;393 394 reg_mux = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux);395 reg_mux2 = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux2);396 mux = cv1800_dt_get_pin_mux(value);397 mux2 = cv1800_dt_get_pin_mux2(value);398 399 raw_spin_lock_irqsave(&pctrl->lock, flags);400 writel_relaxed(mux, reg_mux);401 if (mux2 != PIN_MUX_INVALD)402 writel_relaxed(mux2, reg_mux2);403 raw_spin_unlock_irqrestore(&pctrl->lock, flags);404 }405 406 return 0;407}408 409static const struct pinmux_ops cv1800_pmx_ops = {410 .get_functions_count = pinmux_generic_get_function_count,411 .get_function_name = pinmux_generic_get_function_name,412 .get_function_groups = pinmux_generic_get_function_groups,413 .set_mux = cv1800_pmx_set_mux,414 .strict = true,415};416 417#define PIN_IO_PULLUP BIT(2)418#define PIN_IO_PULLDOWN BIT(3)419#define PIN_IO_DRIVE GENMASK(7, 5)420#define PIN_IO_SCHMITT GENMASK(9, 8)421#define PIN_IO_BUS_HOLD BIT(10)422#define PIN_IO_OUT_FAST_SLEW BIT(11)423 424static u32 cv1800_pull_down_typical_resistor(struct cv1800_pinctrl *pctrl,425 struct cv1800_pin *pin)426{427 return pctrl->data->vddio_ops->get_pull_down(pin, pctrl->power_cfg);428}429 430static u32 cv1800_pull_up_typical_resistor(struct cv1800_pinctrl *pctrl,431 struct cv1800_pin *pin)432{433 return pctrl->data->vddio_ops->get_pull_up(pin, pctrl->power_cfg);434}435 436static int cv1800_pinctrl_oc2reg(struct cv1800_pinctrl *pctrl,437 struct cv1800_pin *pin, u32 target)438{439 const u32 *map;440 int i, len;441 442 len = pctrl->data->vddio_ops->get_oc_map(pin, pctrl->power_cfg, &map);443 if (len < 0)444 return len;445 446 for (i = 0; i < len; i++) {447 if (map[i] >= target)448 return i;449 }450 451 return -EINVAL;452}453 454static int cv1800_pinctrl_reg2oc(struct cv1800_pinctrl *pctrl,455 struct cv1800_pin *pin, u32 reg)456{457 const u32 *map;458 int len;459 460 len = pctrl->data->vddio_ops->get_oc_map(pin, pctrl->power_cfg, &map);461 if (len < 0)462 return len;463 464 if (reg >= len)465 return -EINVAL;466 467 return map[reg];468}469 470static int cv1800_pinctrl_schmitt2reg(struct cv1800_pinctrl *pctrl,471 struct cv1800_pin *pin, u32 target)472{473 const u32 *map;474 int i, len;475 476 len = pctrl->data->vddio_ops->get_schmitt_map(pin, pctrl->power_cfg,477 &map);478 if (len < 0)479 return len;480 481 for (i = 0; i < len; i++) {482 if (map[i] == target)483 return i;484 }485 486 return -EINVAL;487}488 489static int cv1800_pinctrl_reg2schmitt(struct cv1800_pinctrl *pctrl,490 struct cv1800_pin *pin, u32 reg)491{492 const u32 *map;493 int len;494 495 len = pctrl->data->vddio_ops->get_schmitt_map(pin, pctrl->power_cfg,496 &map);497 if (len < 0)498 return len;499 500 if (reg >= len)501 return -EINVAL;502 503 return map[reg];504}505 506static int cv1800_pconf_get(struct pinctrl_dev *pctldev,507 unsigned int pin_id, unsigned long *config)508{509 struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);510 int param = pinconf_to_config_param(*config);511 struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);512 enum cv1800_pin_io_type type;513 u32 value;514 u32 arg;515 bool enabled;516 int ret;517 518 if (!pin)519 return -EINVAL;520 521 type = cv1800_pin_io_type(pin);522 if (type == IO_TYPE_ETH || type == IO_TYPE_AUDIO)523 return -ENOTSUPP;524 525 value = readl(cv1800_pinctrl_get_component_addr(pctrl, &pin->conf));526 527 switch (param) {528 case PIN_CONFIG_BIAS_PULL_DOWN:529 enabled = FIELD_GET(PIN_IO_PULLDOWN, value);530 arg = cv1800_pull_down_typical_resistor(pctrl, pin);531 break;532 case PIN_CONFIG_BIAS_PULL_UP:533 enabled = FIELD_GET(PIN_IO_PULLUP, value);534 arg = cv1800_pull_up_typical_resistor(pctrl, pin);535 break;536 case PIN_CONFIG_DRIVE_STRENGTH_UA:537 enabled = true;538 arg = FIELD_GET(PIN_IO_DRIVE, value);539 ret = cv1800_pinctrl_reg2oc(pctrl, pin, arg);540 if (ret < 0)541 return ret;542 arg = ret;543 break;544 case PIN_CONFIG_INPUT_SCHMITT_UV:545 arg = FIELD_GET(PIN_IO_SCHMITT, value);546 ret = cv1800_pinctrl_reg2schmitt(pctrl, pin, arg);547 if (ret < 0)548 return ret;549 arg = ret;550 enabled = arg != 0;551 break;552 case PIN_CONFIG_POWER_SOURCE:553 enabled = true;554 arg = cv1800_get_power_cfg(pctrl, pin->power_domain);555 break;556 case PIN_CONFIG_SLEW_RATE:557 enabled = true;558 arg = FIELD_GET(PIN_IO_OUT_FAST_SLEW, value);559 break;560 case PIN_CONFIG_BIAS_BUS_HOLD:561 arg = FIELD_GET(PIN_IO_BUS_HOLD, value);562 enabled = arg != 0;563 break;564 default:565 return -ENOTSUPP;566 }567 568 *config = pinconf_to_config_packed(param, arg);569 570 return enabled ? 0 : -EINVAL;571}572 573static int cv1800_pinconf_compute_config(struct cv1800_pinctrl *pctrl,574 struct cv1800_pin *pin,575 unsigned long *configs,576 unsigned int num_configs,577 u32 *value)578{579 int i;580 u32 v = 0;581 enum cv1800_pin_io_type type;582 int ret;583 584 if (!pin)585 return -EINVAL;586 587 type = cv1800_pin_io_type(pin);588 if (type == IO_TYPE_ETH || type == IO_TYPE_AUDIO)589 return -ENOTSUPP;590 591 for (i = 0; i < num_configs; i++) {592 int param = pinconf_to_config_param(configs[i]);593 u32 arg = pinconf_to_config_argument(configs[i]);594 595 switch (param) {596 case PIN_CONFIG_BIAS_PULL_DOWN:597 v &= ~PIN_IO_PULLDOWN;598 v |= FIELD_PREP(PIN_IO_PULLDOWN, arg);599 break;600 case PIN_CONFIG_BIAS_PULL_UP:601 v &= ~PIN_IO_PULLUP;602 v |= FIELD_PREP(PIN_IO_PULLUP, arg);603 break;604 case PIN_CONFIG_DRIVE_STRENGTH_UA:605 ret = cv1800_pinctrl_oc2reg(pctrl, pin, arg);606 if (ret < 0)607 return ret;608 v &= ~PIN_IO_DRIVE;609 v |= FIELD_PREP(PIN_IO_DRIVE, ret);610 break;611 case PIN_CONFIG_INPUT_SCHMITT_UV:612 ret = cv1800_pinctrl_schmitt2reg(pctrl, pin, arg);613 if (ret < 0)614 return ret;615 v &= ~PIN_IO_SCHMITT;616 v |= FIELD_PREP(PIN_IO_SCHMITT, ret);617 break;618 case PIN_CONFIG_POWER_SOURCE:619 /* Ignore power source as it is always fixed */620 break;621 case PIN_CONFIG_SLEW_RATE:622 v &= ~PIN_IO_OUT_FAST_SLEW;623 v |= FIELD_PREP(PIN_IO_OUT_FAST_SLEW, arg);624 break;625 case PIN_CONFIG_BIAS_BUS_HOLD:626 v &= ~PIN_IO_BUS_HOLD;627 v |= FIELD_PREP(PIN_IO_BUS_HOLD, arg);628 break;629 default:630 return -ENOTSUPP;631 }632 }633 634 *value = v;635 636 return 0;637}638 639static int cv1800_pin_set_config(struct cv1800_pinctrl *pctrl,640 unsigned int pin_id,641 u32 value)642{643 struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);644 unsigned long flags;645 void __iomem *addr;646 647 if (!pin)648 return -EINVAL;649 650 addr = cv1800_pinctrl_get_component_addr(pctrl, &pin->conf);651 652 raw_spin_lock_irqsave(&pctrl->lock, flags);653 writel(value, addr);654 raw_spin_unlock_irqrestore(&pctrl->lock, flags);655 656 return 0;657}658 659static int cv1800_pconf_set(struct pinctrl_dev *pctldev,660 unsigned int pin_id, unsigned long *configs,661 unsigned int num_configs)662{663 struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);664 struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);665 u32 value;666 667 if (!pin)668 return -ENODEV;669 670 if (cv1800_pinconf_compute_config(pctrl, pin,671 configs, num_configs, &value))672 return -ENOTSUPP;673 674 return cv1800_pin_set_config(pctrl, pin_id, value);675}676 677static int cv1800_pconf_group_set(struct pinctrl_dev *pctldev,678 unsigned int gsel,679 unsigned long *configs,680 unsigned int num_configs)681{682 struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);683 const struct group_desc *group;684 const struct cv1800_pin_mux_config *pinmuxs;685 u32 value;686 int i;687 688 group = pinctrl_generic_get_group(pctldev, gsel);689 if (!group)690 return -EINVAL;691 692 pinmuxs = group->data;693 694 if (cv1800_pinconf_compute_config(pctrl, pinmuxs[0].pin,695 configs, num_configs, &value))696 return -ENOTSUPP;697 698 for (i = 0; i < group->grp.npins; i++)699 cv1800_pin_set_config(pctrl, group->grp.pins[i], value);700 701 return 0;702}703 704static const struct pinconf_ops cv1800_pconf_ops = {705 .pin_config_get = cv1800_pconf_get,706 .pin_config_set = cv1800_pconf_set,707 .pin_config_group_set = cv1800_pconf_group_set,708 .is_generic = true,709};710 711int cv1800_pinctrl_probe(struct platform_device *pdev)712{713 struct device *dev = &pdev->dev;714 struct cv1800_pinctrl *pctrl;715 const struct cv1800_pinctrl_data *pctrl_data;716 int ret;717 718 pctrl_data = device_get_match_data(dev);719 if (!pctrl_data)720 return -ENODEV;721 722 if (pctrl_data->npins == 0 || pctrl_data->npd == 0)723 return dev_err_probe(dev, -EINVAL, "invalid pin data\n");724 725 pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);726 if (!pctrl)727 return -ENOMEM;728 729 pctrl->power_cfg = devm_kcalloc(dev, pctrl_data->npd,730 sizeof(u32), GFP_KERNEL);731 if (!pctrl->power_cfg)732 return -ENOMEM;733 734 pctrl->regs[0] = devm_platform_ioremap_resource_byname(pdev, "sys");735 if (IS_ERR(pctrl->regs[0]))736 return PTR_ERR(pctrl->regs[0]);737 738 pctrl->regs[1] = devm_platform_ioremap_resource_byname(pdev, "rtc");739 if (IS_ERR(pctrl->regs[1]))740 return PTR_ERR(pctrl->regs[1]);741 742 pctrl->pdesc.name = dev_name(dev);743 pctrl->pdesc.pins = pctrl_data->pins;744 pctrl->pdesc.npins = pctrl_data->npins;745 pctrl->pdesc.pctlops = &cv1800_pctrl_ops;746 pctrl->pdesc.pmxops = &cv1800_pmx_ops;747 pctrl->pdesc.confops = &cv1800_pconf_ops;748 pctrl->pdesc.owner = THIS_MODULE;749 750 pctrl->data = pctrl_data;751 pctrl->dev = dev;752 raw_spin_lock_init(&pctrl->lock);753 mutex_init(&pctrl->mutex);754 755 platform_set_drvdata(pdev, pctrl);756 757 ret = devm_pinctrl_register_and_init(dev, &pctrl->pdesc,758 pctrl, &pctrl->pctl_dev);759 if (ret)760 return dev_err_probe(dev, ret,761 "fail to register pinctrl driver\n");762 763 return pinctrl_enable(pctrl->pctl_dev);764}765EXPORT_SYMBOL_GPL(cv1800_pinctrl_probe);766