1133 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Spreadtrum pin controller driver4 * Copyright (C) 2017 Spreadtrum - http://www.spreadtrum.com5 */6 7#include <linux/debugfs.h>8#include <linux/err.h>9#include <linux/init.h>10#include <linux/io.h>11#include <linux/kernel.h>12#include <linux/module.h>13#include <linux/of.h>14#include <linux/platform_device.h>15#include <linux/seq_file.h>16#include <linux/slab.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 "../core.h"26#include "../pinmux.h"27#include "../pinconf.h"28#include "../pinctrl-utils.h"29#include "pinctrl-sprd.h"30 31#define PINCTRL_BIT_MASK(width) (~(~0UL << (width)))32#define PINCTRL_REG_OFFSET 0x2033#define PINCTRL_REG_MISC_OFFSET 0x402034#define PINCTRL_REG_LEN 0x435 36#define PIN_FUNC_MASK (BIT(4) | BIT(5))37#define PIN_FUNC_SEL_1 ~PIN_FUNC_MASK38#define PIN_FUNC_SEL_2 BIT(4)39#define PIN_FUNC_SEL_3 BIT(5)40#define PIN_FUNC_SEL_4 PIN_FUNC_MASK41 42#define AP_SLEEP_MODE BIT(13)43#define PUBCP_SLEEP_MODE BIT(14)44#define TGLDSP_SLEEP_MODE BIT(15)45#define AGDSP_SLEEP_MODE BIT(16)46#define CM4_SLEEP_MODE BIT(17)47#define SLEEP_MODE_MASK GENMASK(5, 0)48#define SLEEP_MODE_SHIFT 1349 50#define SLEEP_INPUT BIT(1)51#define SLEEP_INPUT_MASK 0x152#define SLEEP_INPUT_SHIFT 153 54#define SLEEP_OUTPUT BIT(0)55#define SLEEP_OUTPUT_MASK 0x156#define SLEEP_OUTPUT_SHIFT 057 58#define DRIVE_STRENGTH_MASK GENMASK(3, 0)59#define DRIVE_STRENGTH_SHIFT 1960 61#define SLEEP_PULL_DOWN BIT(2)62#define SLEEP_PULL_DOWN_MASK 0x163#define SLEEP_PULL_DOWN_SHIFT 264 65#define PULL_DOWN BIT(6)66#define PULL_DOWN_MASK 0x167#define PULL_DOWN_SHIFT 668 69#define SLEEP_PULL_UP BIT(3)70#define SLEEP_PULL_UP_MASK 0x171#define SLEEP_PULL_UP_SHIFT 372 73#define PULL_UP_4_7K (BIT(12) | BIT(7))74#define PULL_UP_20K BIT(7)75#define PULL_UP_MASK 0x2176#define PULL_UP_SHIFT 777 78#define INPUT_SCHMITT BIT(11)79#define INPUT_SCHMITT_MASK 0x180#define INPUT_SCHMITT_SHIFT 1181 82enum pin_sleep_mode {83 AP_SLEEP = BIT(0),84 PUBCP_SLEEP = BIT(1),85 TGLDSP_SLEEP = BIT(2),86 AGDSP_SLEEP = BIT(3),87 CM4_SLEEP = BIT(4),88};89 90enum pin_func_sel {91 PIN_FUNC_1,92 PIN_FUNC_2,93 PIN_FUNC_3,94 PIN_FUNC_4,95 PIN_FUNC_MAX,96};97 98/**99 * struct sprd_pin: represent one pin's description100 * @name: pin name101 * @number: pin number102 * @type: pin type, can be GLOBAL_CTRL_PIN/COMMON_PIN/MISC_PIN103 * @reg: pin register address104 * @bit_offset: bit offset in pin register105 * @bit_width: bit width in pin register106 */107struct sprd_pin {108 const char *name;109 unsigned int number;110 enum pin_type type;111 unsigned long reg;112 unsigned long bit_offset;113 unsigned long bit_width;114};115 116/**117 * struct sprd_pin_group: represent one group's description118 * @name: group name119 * @npins: pin numbers of this group120 * @pins: pointer to pins array121 */122struct sprd_pin_group {123 const char *name;124 unsigned int npins;125 unsigned int *pins;126};127 128/**129 * struct sprd_pinctrl_soc_info: represent the SoC's pins description130 * @groups: pointer to groups of pins131 * @ngroups: group numbers of the whole SoC132 * @pins: pointer to pins description133 * @npins: pin numbers of the whole SoC134 * @grp_names: pointer to group names array135 */136struct sprd_pinctrl_soc_info {137 struct sprd_pin_group *groups;138 unsigned int ngroups;139 struct sprd_pin *pins;140 unsigned int npins;141 const char **grp_names;142};143 144/**145 * struct sprd_pinctrl: represent the pin controller device146 * @dev: pointer to the device structure147 * @pctl: pointer to the pinctrl handle148 * @base: base address of the controller149 * @info: pointer to SoC's pins description information150 */151struct sprd_pinctrl {152 struct device *dev;153 struct pinctrl_dev *pctl;154 void __iomem *base;155 struct sprd_pinctrl_soc_info *info;156};157 158#define SPRD_PIN_CONFIG_CONTROL (PIN_CONFIG_END + 1)159#define SPRD_PIN_CONFIG_SLEEP_MODE (PIN_CONFIG_END + 2)160 161static int sprd_pinctrl_get_id_by_name(struct sprd_pinctrl *sprd_pctl,162 const char *name)163{164 struct sprd_pinctrl_soc_info *info = sprd_pctl->info;165 int i;166 167 for (i = 0; i < info->npins; i++) {168 if (!strcmp(info->pins[i].name, name))169 return info->pins[i].number;170 }171 172 return -ENODEV;173}174 175static struct sprd_pin *176sprd_pinctrl_get_pin_by_id(struct sprd_pinctrl *sprd_pctl, unsigned int id)177{178 struct sprd_pinctrl_soc_info *info = sprd_pctl->info;179 struct sprd_pin *pin = NULL;180 int i;181 182 for (i = 0; i < info->npins; i++) {183 if (info->pins[i].number == id) {184 pin = &info->pins[i];185 break;186 }187 }188 189 return pin;190}191 192static const struct sprd_pin_group *193sprd_pinctrl_find_group_by_name(struct sprd_pinctrl *sprd_pctl,194 const char *name)195{196 struct sprd_pinctrl_soc_info *info = sprd_pctl->info;197 const struct sprd_pin_group *grp = NULL;198 int i;199 200 for (i = 0; i < info->ngroups; i++) {201 if (!strcmp(info->groups[i].name, name)) {202 grp = &info->groups[i];203 break;204 }205 }206 207 return grp;208}209 210static int sprd_pctrl_group_count(struct pinctrl_dev *pctldev)211{212 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);213 struct sprd_pinctrl_soc_info *info = pctl->info;214 215 return info->ngroups;216}217 218static const char *sprd_pctrl_group_name(struct pinctrl_dev *pctldev,219 unsigned int selector)220{221 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);222 struct sprd_pinctrl_soc_info *info = pctl->info;223 224 return info->groups[selector].name;225}226 227static int sprd_pctrl_group_pins(struct pinctrl_dev *pctldev,228 unsigned int selector,229 const unsigned int **pins,230 unsigned int *npins)231{232 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);233 struct sprd_pinctrl_soc_info *info = pctl->info;234 235 if (selector >= info->ngroups)236 return -EINVAL;237 238 *pins = info->groups[selector].pins;239 *npins = info->groups[selector].npins;240 241 return 0;242}243 244static int sprd_dt_node_to_map(struct pinctrl_dev *pctldev,245 struct device_node *np,246 struct pinctrl_map **map,247 unsigned int *num_maps)248{249 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);250 const struct sprd_pin_group *grp;251 unsigned long *configs = NULL;252 unsigned int num_configs = 0;253 unsigned int reserved_maps = 0;254 unsigned int reserve = 0;255 const char *function;256 enum pinctrl_map_type type;257 int ret;258 259 grp = sprd_pinctrl_find_group_by_name(pctl, np->name);260 if (!grp) {261 dev_err(pctl->dev, "unable to find group for node %s\n",262 of_node_full_name(np));263 return -EINVAL;264 }265 266 ret = of_property_count_strings(np, "pins");267 if (ret < 0)268 return ret;269 270 if (ret == 1)271 type = PIN_MAP_TYPE_CONFIGS_PIN;272 else273 type = PIN_MAP_TYPE_CONFIGS_GROUP;274 275 ret = of_property_read_string(np, "function", &function);276 if (ret < 0) {277 if (ret != -EINVAL)278 dev_err(pctl->dev,279 "%s: could not parse property function\n",280 of_node_full_name(np));281 function = NULL;282 }283 284 ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,285 &num_configs);286 if (ret < 0) {287 dev_err(pctl->dev, "%s: could not parse node property\n",288 of_node_full_name(np));289 return ret;290 }291 292 *map = NULL;293 *num_maps = 0;294 295 if (function != NULL)296 reserve++;297 if (num_configs)298 reserve++;299 300 ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps,301 num_maps, reserve);302 if (ret < 0)303 goto out;304 305 if (function) {306 ret = pinctrl_utils_add_map_mux(pctldev, map,307 &reserved_maps, num_maps,308 grp->name, function);309 if (ret < 0)310 goto out;311 }312 313 if (num_configs) {314 const char *group_or_pin;315 unsigned int pin_id;316 317 if (type == PIN_MAP_TYPE_CONFIGS_PIN) {318 pin_id = grp->pins[0];319 group_or_pin = pin_get_name(pctldev, pin_id);320 } else {321 group_or_pin = grp->name;322 }323 324 ret = pinctrl_utils_add_map_configs(pctldev, map,325 &reserved_maps, num_maps,326 group_or_pin, configs,327 num_configs, type);328 }329 330out:331 kfree(configs);332 return ret;333}334 335static void sprd_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,336 unsigned int offset)337{338 seq_printf(s, "%s", dev_name(pctldev->dev));339}340 341static const struct pinctrl_ops sprd_pctrl_ops = {342 .get_groups_count = sprd_pctrl_group_count,343 .get_group_name = sprd_pctrl_group_name,344 .get_group_pins = sprd_pctrl_group_pins,345 .pin_dbg_show = sprd_pctrl_dbg_show,346 .dt_node_to_map = sprd_dt_node_to_map,347 .dt_free_map = pinctrl_utils_free_map,348};349 350static int sprd_pmx_get_function_count(struct pinctrl_dev *pctldev)351{352 return PIN_FUNC_MAX;353}354 355static const char *sprd_pmx_get_function_name(struct pinctrl_dev *pctldev,356 unsigned int selector)357{358 switch (selector) {359 case PIN_FUNC_1:360 return "func1";361 case PIN_FUNC_2:362 return "func2";363 case PIN_FUNC_3:364 return "func3";365 case PIN_FUNC_4:366 return "func4";367 default:368 return "null";369 }370}371 372static int sprd_pmx_get_function_groups(struct pinctrl_dev *pctldev,373 unsigned int selector,374 const char * const **groups,375 unsigned int * const num_groups)376{377 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);378 struct sprd_pinctrl_soc_info *info = pctl->info;379 380 *groups = info->grp_names;381 *num_groups = info->ngroups;382 383 return 0;384}385 386static int sprd_pmx_set_mux(struct pinctrl_dev *pctldev,387 unsigned int func_selector,388 unsigned int group_selector)389{390 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);391 struct sprd_pinctrl_soc_info *info = pctl->info;392 struct sprd_pin_group *grp = &info->groups[group_selector];393 unsigned int i, grp_pins = grp->npins;394 unsigned long reg;395 unsigned int val = 0;396 397 if (group_selector >= info->ngroups)398 return -EINVAL;399 400 switch (func_selector) {401 case PIN_FUNC_1:402 val &= PIN_FUNC_SEL_1;403 break;404 case PIN_FUNC_2:405 val |= PIN_FUNC_SEL_2;406 break;407 case PIN_FUNC_3:408 val |= PIN_FUNC_SEL_3;409 break;410 case PIN_FUNC_4:411 val |= PIN_FUNC_SEL_4;412 break;413 default:414 break;415 }416 417 for (i = 0; i < grp_pins; i++) {418 unsigned int pin_id = grp->pins[i];419 struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);420 421 if (!pin || pin->type != COMMON_PIN)422 continue;423 424 reg = readl((void __iomem *)pin->reg);425 reg &= ~PIN_FUNC_MASK;426 reg |= val;427 writel(reg, (void __iomem *)pin->reg);428 }429 430 return 0;431}432 433static const struct pinmux_ops sprd_pmx_ops = {434 .get_functions_count = sprd_pmx_get_function_count,435 .get_function_name = sprd_pmx_get_function_name,436 .get_function_groups = sprd_pmx_get_function_groups,437 .set_mux = sprd_pmx_set_mux,438};439 440static int sprd_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin_id,441 unsigned long *config)442{443 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);444 struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);445 unsigned int param = pinconf_to_config_param(*config);446 unsigned int reg, arg;447 448 if (!pin)449 return -EINVAL;450 451 if (pin->type == GLOBAL_CTRL_PIN) {452 reg = (readl((void __iomem *)pin->reg) >>453 pin->bit_offset) & PINCTRL_BIT_MASK(pin->bit_width);454 } else {455 reg = readl((void __iomem *)pin->reg);456 }457 458 if (pin->type == GLOBAL_CTRL_PIN &&459 param == SPRD_PIN_CONFIG_CONTROL) {460 arg = reg;461 } else if (pin->type == COMMON_PIN || pin->type == MISC_PIN) {462 switch (param) {463 case SPRD_PIN_CONFIG_SLEEP_MODE:464 arg = (reg >> SLEEP_MODE_SHIFT) & SLEEP_MODE_MASK;465 break;466 case PIN_CONFIG_INPUT_ENABLE:467 arg = (reg >> SLEEP_INPUT_SHIFT) & SLEEP_INPUT_MASK;468 break;469 case PIN_CONFIG_OUTPUT_ENABLE:470 arg = reg & SLEEP_OUTPUT_MASK;471 break;472 case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:473 if ((reg & SLEEP_OUTPUT) || (reg & SLEEP_INPUT))474 return -EINVAL;475 476 arg = 1;477 break;478 case PIN_CONFIG_DRIVE_STRENGTH:479 arg = (reg >> DRIVE_STRENGTH_SHIFT) &480 DRIVE_STRENGTH_MASK;481 break;482 case PIN_CONFIG_BIAS_PULL_DOWN:483 /* combine sleep pull down and pull down config */484 arg = ((reg >> SLEEP_PULL_DOWN_SHIFT) &485 SLEEP_PULL_DOWN_MASK) << 16;486 arg |= (reg >> PULL_DOWN_SHIFT) & PULL_DOWN_MASK;487 break;488 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:489 arg = (reg >> INPUT_SCHMITT_SHIFT) & INPUT_SCHMITT_MASK;490 break;491 case PIN_CONFIG_BIAS_PULL_UP:492 /* combine sleep pull up and pull up config */493 arg = ((reg >> SLEEP_PULL_UP_SHIFT) &494 SLEEP_PULL_UP_MASK) << 16;495 arg |= (reg >> PULL_UP_SHIFT) & PULL_UP_MASK;496 break;497 case PIN_CONFIG_BIAS_DISABLE:498 if ((reg & (SLEEP_PULL_DOWN | SLEEP_PULL_UP)) ||499 (reg & (PULL_DOWN | PULL_UP_4_7K | PULL_UP_20K)))500 return -EINVAL;501 502 arg = 1;503 break;504 case PIN_CONFIG_SLEEP_HARDWARE_STATE:505 arg = 0;506 break;507 default:508 return -ENOTSUPP;509 }510 } else {511 return -ENOTSUPP;512 }513 514 *config = pinconf_to_config_packed(param, arg);515 return 0;516}517 518static unsigned int sprd_pinconf_drive(unsigned int mA)519{520 unsigned int val = 0;521 522 switch (mA) {523 case 2:524 break;525 case 4:526 val |= BIT(19);527 break;528 case 6:529 val |= BIT(20);530 break;531 case 8:532 val |= BIT(19) | BIT(20);533 break;534 case 10:535 val |= BIT(21);536 break;537 case 12:538 val |= BIT(21) | BIT(19);539 break;540 case 14:541 val |= BIT(21) | BIT(20);542 break;543 case 16:544 val |= BIT(19) | BIT(20) | BIT(21);545 break;546 case 20:547 val |= BIT(22);548 break;549 case 21:550 val |= BIT(22) | BIT(19);551 break;552 case 24:553 val |= BIT(22) | BIT(20);554 break;555 case 25:556 val |= BIT(22) | BIT(20) | BIT(19);557 break;558 case 27:559 val |= BIT(22) | BIT(21);560 break;561 case 29:562 val |= BIT(22) | BIT(21) | BIT(19);563 break;564 case 31:565 val |= BIT(22) | BIT(21) | BIT(20);566 break;567 case 33:568 val |= BIT(22) | BIT(21) | BIT(20) | BIT(19);569 break;570 default:571 break;572 }573 574 return val;575}576 577static bool sprd_pinctrl_check_sleep_config(unsigned long *configs,578 unsigned int num_configs)579{580 unsigned int param;581 int i;582 583 for (i = 0; i < num_configs; i++) {584 param = pinconf_to_config_param(configs[i]);585 if (param == PIN_CONFIG_SLEEP_HARDWARE_STATE)586 return true;587 }588 589 return false;590}591 592static int sprd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin_id,593 unsigned long *configs, unsigned int num_configs)594{595 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);596 struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);597 bool is_sleep_config;598 unsigned long reg;599 int i;600 601 if (!pin)602 return -EINVAL;603 604 is_sleep_config = sprd_pinctrl_check_sleep_config(configs, num_configs);605 606 for (i = 0; i < num_configs; i++) {607 unsigned int param, arg, shift, mask, val;608 609 param = pinconf_to_config_param(configs[i]);610 arg = pinconf_to_config_argument(configs[i]);611 612 val = 0;613 shift = 0;614 mask = 0;615 if (pin->type == GLOBAL_CTRL_PIN &&616 param == SPRD_PIN_CONFIG_CONTROL) {617 val = arg;618 } else if (pin->type == COMMON_PIN || pin->type == MISC_PIN) {619 switch (param) {620 case SPRD_PIN_CONFIG_SLEEP_MODE:621 if (arg & AP_SLEEP)622 val |= AP_SLEEP_MODE;623 if (arg & PUBCP_SLEEP)624 val |= PUBCP_SLEEP_MODE;625 if (arg & TGLDSP_SLEEP)626 val |= TGLDSP_SLEEP_MODE;627 if (arg & AGDSP_SLEEP)628 val |= AGDSP_SLEEP_MODE;629 if (arg & CM4_SLEEP)630 val |= CM4_SLEEP_MODE;631 632 mask = SLEEP_MODE_MASK;633 shift = SLEEP_MODE_SHIFT;634 break;635 case PIN_CONFIG_INPUT_ENABLE:636 if (is_sleep_config == true) {637 if (arg > 0)638 val |= SLEEP_INPUT;639 else640 val &= ~SLEEP_INPUT;641 642 mask = SLEEP_INPUT_MASK;643 shift = SLEEP_INPUT_SHIFT;644 }645 break;646 case PIN_CONFIG_OUTPUT_ENABLE:647 if (is_sleep_config == true) {648 if (arg > 0)649 val |= SLEEP_OUTPUT;650 else651 val &= ~SLEEP_OUTPUT;652 653 mask = SLEEP_OUTPUT_MASK;654 shift = SLEEP_OUTPUT_SHIFT;655 }656 break;657 case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:658 if (is_sleep_config == true) {659 val = shift = 0;660 mask = SLEEP_OUTPUT | SLEEP_INPUT;661 }662 break;663 case PIN_CONFIG_DRIVE_STRENGTH:664 if (arg < 2 || arg > 60)665 return -EINVAL;666 667 val = sprd_pinconf_drive(arg);668 mask = DRIVE_STRENGTH_MASK;669 shift = DRIVE_STRENGTH_SHIFT;670 break;671 case PIN_CONFIG_BIAS_PULL_DOWN:672 if (is_sleep_config == true) {673 val |= SLEEP_PULL_DOWN;674 mask = SLEEP_PULL_DOWN_MASK;675 shift = SLEEP_PULL_DOWN_SHIFT;676 } else {677 val |= PULL_DOWN;678 mask = PULL_DOWN_MASK;679 shift = PULL_DOWN_SHIFT;680 }681 break;682 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:683 if (arg > 0)684 val |= INPUT_SCHMITT;685 else686 val &= ~INPUT_SCHMITT;687 688 mask = INPUT_SCHMITT_MASK;689 shift = INPUT_SCHMITT_SHIFT;690 break;691 case PIN_CONFIG_BIAS_PULL_UP:692 if (is_sleep_config) {693 val |= SLEEP_PULL_UP;694 mask = SLEEP_PULL_UP_MASK;695 shift = SLEEP_PULL_UP_SHIFT;696 } else {697 if (arg == 20000)698 val |= PULL_UP_20K;699 else if (arg == 4700)700 val |= PULL_UP_4_7K;701 702 mask = PULL_UP_MASK;703 shift = PULL_UP_SHIFT;704 }705 break;706 case PIN_CONFIG_BIAS_DISABLE:707 if (is_sleep_config == true) {708 val = shift = 0;709 mask = SLEEP_PULL_DOWN | SLEEP_PULL_UP;710 } else {711 val = shift = 0;712 mask = PULL_DOWN | PULL_UP_20K |713 PULL_UP_4_7K;714 }715 break;716 case PIN_CONFIG_SLEEP_HARDWARE_STATE:717 continue;718 default:719 return -ENOTSUPP;720 }721 } else {722 return -ENOTSUPP;723 }724 725 if (pin->type == GLOBAL_CTRL_PIN) {726 reg = readl((void __iomem *)pin->reg);727 reg &= ~(PINCTRL_BIT_MASK(pin->bit_width)728 << pin->bit_offset);729 reg |= (val & PINCTRL_BIT_MASK(pin->bit_width))730 << pin->bit_offset;731 writel(reg, (void __iomem *)pin->reg);732 } else {733 reg = readl((void __iomem *)pin->reg);734 reg &= ~(mask << shift);735 reg |= val;736 writel(reg, (void __iomem *)pin->reg);737 }738 }739 740 return 0;741}742 743static int sprd_pinconf_group_get(struct pinctrl_dev *pctldev,744 unsigned int selector, unsigned long *config)745{746 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);747 struct sprd_pinctrl_soc_info *info = pctl->info;748 struct sprd_pin_group *grp;749 unsigned int pin_id;750 751 if (selector >= info->ngroups)752 return -EINVAL;753 754 grp = &info->groups[selector];755 pin_id = grp->pins[0];756 757 return sprd_pinconf_get(pctldev, pin_id, config);758}759 760static int sprd_pinconf_group_set(struct pinctrl_dev *pctldev,761 unsigned int selector,762 unsigned long *configs,763 unsigned int num_configs)764{765 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);766 struct sprd_pinctrl_soc_info *info = pctl->info;767 struct sprd_pin_group *grp;768 int ret, i;769 770 if (selector >= info->ngroups)771 return -EINVAL;772 773 grp = &info->groups[selector];774 775 for (i = 0; i < grp->npins; i++) {776 unsigned int pin_id = grp->pins[i];777 778 ret = sprd_pinconf_set(pctldev, pin_id, configs, num_configs);779 if (ret)780 return ret;781 }782 783 return 0;784}785 786static int sprd_pinconf_get_config(struct pinctrl_dev *pctldev,787 unsigned int pin_id,788 unsigned long *config)789{790 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);791 struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);792 793 if (!pin)794 return -EINVAL;795 796 if (pin->type == GLOBAL_CTRL_PIN) {797 *config = (readl((void __iomem *)pin->reg) >>798 pin->bit_offset) & PINCTRL_BIT_MASK(pin->bit_width);799 } else {800 *config = readl((void __iomem *)pin->reg);801 }802 803 return 0;804}805 806static void sprd_pinconf_dbg_show(struct pinctrl_dev *pctldev,807 struct seq_file *s, unsigned int pin_id)808{809 unsigned long config;810 int ret;811 812 ret = sprd_pinconf_get_config(pctldev, pin_id, &config);813 if (ret)814 return;815 816 seq_printf(s, "0x%lx", config);817}818 819static void sprd_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,820 struct seq_file *s,821 unsigned int selector)822{823 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);824 struct sprd_pinctrl_soc_info *info = pctl->info;825 struct sprd_pin_group *grp;826 unsigned long config;827 const char *name;828 int i, ret;829 830 if (selector >= info->ngroups)831 return;832 833 grp = &info->groups[selector];834 835 seq_putc(s, '\n');836 for (i = 0; i < grp->npins; i++, config++) {837 unsigned int pin_id = grp->pins[i];838 839 name = pin_get_name(pctldev, pin_id);840 ret = sprd_pinconf_get_config(pctldev, pin_id, &config);841 if (ret)842 return;843 844 seq_printf(s, "%s: 0x%lx ", name, config);845 }846}847 848static const struct pinconf_ops sprd_pinconf_ops = {849 .is_generic = true,850 .pin_config_get = sprd_pinconf_get,851 .pin_config_set = sprd_pinconf_set,852 .pin_config_group_get = sprd_pinconf_group_get,853 .pin_config_group_set = sprd_pinconf_group_set,854 .pin_config_dbg_show = sprd_pinconf_dbg_show,855 .pin_config_group_dbg_show = sprd_pinconf_group_dbg_show,856};857 858static const struct pinconf_generic_params sprd_dt_params[] = {859 {"sprd,control", SPRD_PIN_CONFIG_CONTROL, 0},860 {"sprd,sleep-mode", SPRD_PIN_CONFIG_SLEEP_MODE, 0},861};862 863#ifdef CONFIG_DEBUG_FS864static const struct pin_config_item sprd_conf_items[] = {865 PCONFDUMP(SPRD_PIN_CONFIG_CONTROL, "global control", NULL, true),866 PCONFDUMP(SPRD_PIN_CONFIG_SLEEP_MODE, "sleep mode", NULL, true),867};868#endif869 870static struct pinctrl_desc sprd_pinctrl_desc = {871 .pctlops = &sprd_pctrl_ops,872 .pmxops = &sprd_pmx_ops,873 .confops = &sprd_pinconf_ops,874 .num_custom_params = ARRAY_SIZE(sprd_dt_params),875 .custom_params = sprd_dt_params,876#ifdef CONFIG_DEBUG_FS877 .custom_conf_items = sprd_conf_items,878#endif879 .owner = THIS_MODULE,880};881 882static int sprd_pinctrl_parse_groups(struct device_node *np,883 struct sprd_pinctrl *sprd_pctl,884 struct sprd_pin_group *grp)885{886 struct property *prop;887 const char *pin_name;888 int ret, i = 0;889 890 ret = of_property_count_strings(np, "pins");891 if (ret < 0)892 return ret;893 894 grp->name = np->name;895 grp->npins = ret;896 grp->pins = devm_kcalloc(sprd_pctl->dev,897 grp->npins, sizeof(unsigned int),898 GFP_KERNEL);899 if (!grp->pins)900 return -ENOMEM;901 902 of_property_for_each_string(np, "pins", prop, pin_name) {903 ret = sprd_pinctrl_get_id_by_name(sprd_pctl, pin_name);904 if (ret >= 0)905 grp->pins[i++] = ret;906 }907 908 for (i = 0; i < grp->npins; i++) {909 dev_dbg(sprd_pctl->dev,910 "Group[%s] contains [%d] pins: id = %d\n",911 grp->name, grp->npins, grp->pins[i]);912 }913 914 return 0;915}916 917static unsigned int sprd_pinctrl_get_groups(struct device_node *np)918{919 struct device_node *child;920 unsigned int group_cnt, cnt;921 922 group_cnt = of_get_child_count(np);923 924 for_each_child_of_node(np, child) {925 cnt = of_get_child_count(child);926 if (cnt > 0)927 group_cnt += cnt;928 }929 930 return group_cnt;931}932 933static int sprd_pinctrl_parse_dt(struct sprd_pinctrl *sprd_pctl)934{935 struct sprd_pinctrl_soc_info *info = sprd_pctl->info;936 struct device_node *np = sprd_pctl->dev->of_node;937 struct sprd_pin_group *grp;938 const char **temp;939 int ret;940 941 if (!np)942 return -ENODEV;943 944 info->ngroups = sprd_pinctrl_get_groups(np);945 if (!info->ngroups)946 return 0;947 948 info->groups = devm_kcalloc(sprd_pctl->dev,949 info->ngroups,950 sizeof(struct sprd_pin_group),951 GFP_KERNEL);952 if (!info->groups)953 return -ENOMEM;954 955 info->grp_names = devm_kcalloc(sprd_pctl->dev,956 info->ngroups, sizeof(char *),957 GFP_KERNEL);958 if (!info->grp_names)959 return -ENOMEM;960 961 temp = info->grp_names;962 grp = info->groups;963 964 for_each_child_of_node_scoped(np, child) {965 ret = sprd_pinctrl_parse_groups(child, sprd_pctl, grp);966 if (ret)967 return ret;968 969 *temp++ = grp->name;970 grp++;971 972 if (of_get_child_count(child) > 0) {973 for_each_child_of_node_scoped(child, sub_child) {974 ret = sprd_pinctrl_parse_groups(sub_child,975 sprd_pctl, grp);976 if (ret)977 return ret;978 979 *temp++ = grp->name;980 grp++;981 }982 }983 }984 985 return 0;986}987 988static int sprd_pinctrl_add_pins(struct sprd_pinctrl *sprd_pctl,989 struct sprd_pins_info *sprd_soc_pin_info,990 int pins_cnt)991{992 struct sprd_pinctrl_soc_info *info = sprd_pctl->info;993 unsigned int ctrl_pin = 0, com_pin = 0;994 struct sprd_pin *pin;995 int i;996 997 info->npins = pins_cnt;998 info->pins = devm_kcalloc(sprd_pctl->dev,999 info->npins, sizeof(struct sprd_pin),1000 GFP_KERNEL);1001 if (!info->pins)1002 return -ENOMEM;1003 1004 for (i = 0, pin = info->pins; i < info->npins; i++, pin++) {1005 unsigned int reg;1006 1007 pin->name = sprd_soc_pin_info[i].name;1008 pin->type = sprd_soc_pin_info[i].type;1009 pin->number = sprd_soc_pin_info[i].num;1010 reg = sprd_soc_pin_info[i].reg;1011 if (pin->type == GLOBAL_CTRL_PIN) {1012 pin->reg = (unsigned long)sprd_pctl->base +1013 PINCTRL_REG_LEN * reg;1014 pin->bit_offset = sprd_soc_pin_info[i].bit_offset;1015 pin->bit_width = sprd_soc_pin_info[i].bit_width;1016 ctrl_pin++;1017 } else if (pin->type == COMMON_PIN) {1018 pin->reg = (unsigned long)sprd_pctl->base +1019 PINCTRL_REG_OFFSET + PINCTRL_REG_LEN *1020 (i - ctrl_pin);1021 com_pin++;1022 } else if (pin->type == MISC_PIN) {1023 pin->reg = (unsigned long)sprd_pctl->base +1024 PINCTRL_REG_MISC_OFFSET + PINCTRL_REG_LEN *1025 (i - ctrl_pin - com_pin);1026 }1027 }1028 1029 for (i = 0, pin = info->pins; i < info->npins; pin++, i++) {1030 dev_dbg(sprd_pctl->dev, "pin name[%s-%d], type = %d, "1031 "bit offset = %ld, bit width = %ld, reg = 0x%lx\n",1032 pin->name, pin->number, pin->type,1033 pin->bit_offset, pin->bit_width, pin->reg);1034 }1035 1036 return 0;1037}1038 1039int sprd_pinctrl_core_probe(struct platform_device *pdev,1040 struct sprd_pins_info *sprd_soc_pin_info,1041 int pins_cnt)1042{1043 struct sprd_pinctrl *sprd_pctl;1044 struct sprd_pinctrl_soc_info *pinctrl_info;1045 struct pinctrl_pin_desc *pin_desc;1046 int ret, i;1047 1048 sprd_pctl = devm_kzalloc(&pdev->dev, sizeof(struct sprd_pinctrl),1049 GFP_KERNEL);1050 if (!sprd_pctl)1051 return -ENOMEM;1052 1053 sprd_pctl->base = devm_platform_ioremap_resource(pdev, 0);1054 if (IS_ERR(sprd_pctl->base))1055 return PTR_ERR(sprd_pctl->base);1056 1057 pinctrl_info = devm_kzalloc(&pdev->dev,1058 sizeof(struct sprd_pinctrl_soc_info),1059 GFP_KERNEL);1060 if (!pinctrl_info)1061 return -ENOMEM;1062 1063 sprd_pctl->info = pinctrl_info;1064 sprd_pctl->dev = &pdev->dev;1065 platform_set_drvdata(pdev, sprd_pctl);1066 1067 ret = sprd_pinctrl_add_pins(sprd_pctl, sprd_soc_pin_info, pins_cnt);1068 if (ret) {1069 dev_err(&pdev->dev, "fail to add pins information\n");1070 return ret;1071 }1072 1073 ret = sprd_pinctrl_parse_dt(sprd_pctl);1074 if (ret) {1075 dev_err(&pdev->dev, "fail to parse dt properties\n");1076 return ret;1077 }1078 1079 pin_desc = devm_kcalloc(&pdev->dev,1080 pinctrl_info->npins,1081 sizeof(struct pinctrl_pin_desc),1082 GFP_KERNEL);1083 if (!pin_desc)1084 return -ENOMEM;1085 1086 for (i = 0; i < pinctrl_info->npins; i++) {1087 pin_desc[i].number = pinctrl_info->pins[i].number;1088 pin_desc[i].name = pinctrl_info->pins[i].name;1089 pin_desc[i].drv_data = pinctrl_info;1090 }1091 1092 sprd_pinctrl_desc.pins = pin_desc;1093 sprd_pinctrl_desc.name = dev_name(&pdev->dev);1094 sprd_pinctrl_desc.npins = pinctrl_info->npins;1095 1096 sprd_pctl->pctl = pinctrl_register(&sprd_pinctrl_desc,1097 &pdev->dev, (void *)sprd_pctl);1098 if (IS_ERR(sprd_pctl->pctl)) {1099 dev_err(&pdev->dev, "could not register pinctrl driver\n");1100 return PTR_ERR(sprd_pctl->pctl);1101 }1102 1103 return 0;1104}1105EXPORT_SYMBOL_GPL(sprd_pinctrl_core_probe);1106 1107void sprd_pinctrl_remove(struct platform_device *pdev)1108{1109 struct sprd_pinctrl *sprd_pctl = platform_get_drvdata(pdev);1110 1111 pinctrl_unregister(sprd_pctl->pctl);1112}1113EXPORT_SYMBOL_GPL(sprd_pinctrl_remove);1114 1115void sprd_pinctrl_shutdown(struct platform_device *pdev)1116{1117 struct pinctrl *pinctl;1118 struct pinctrl_state *state;1119 1120 pinctl = devm_pinctrl_get(&pdev->dev);1121 if (IS_ERR(pinctl))1122 return;1123 state = pinctrl_lookup_state(pinctl, "shutdown");1124 if (IS_ERR(state))1125 return;1126 pinctrl_select_state(pinctl, state);1127}1128EXPORT_SYMBOL_GPL(sprd_pinctrl_shutdown);1129 1130MODULE_DESCRIPTION("SPREADTRUM Pin Controller Driver");1131MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>");1132MODULE_LICENSE("GPL v2");1133