brintos

brintos / linux-shallow public Read only

0
0
Text · 22.3 KiB · 29d16c9 Raw
933 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * SuperH Pin Function Controller pinmux support.4 *5 * Copyright (C) 2012  Paul Mundt6 */7 8#define DRV_NAME "sh-pfc"9 10#include <linux/device.h>11#include <linux/err.h>12#include <linux/io.h>13#include <linux/module.h>14#include <linux/of.h>15#include <linux/seq_file.h>16#include <linux/slab.h>17#include <linux/spinlock.h>18 19#include <linux/pinctrl/consumer.h>20#include <linux/pinctrl/machine.h>21#include <linux/pinctrl/pinconf-generic.h>22#include <linux/pinctrl/pinconf.h>23#include <linux/pinctrl/pinctrl.h>24#include <linux/pinctrl/pinmux.h>25 26#include "core.h"27#include "../core.h"28#include "../pinconf.h"29 30struct sh_pfc_pin_config {31	u16 gpio_enabled:1;32	u16 mux_mark:15;33};34 35struct sh_pfc_pinctrl {36	struct pinctrl_dev *pctl;37	struct pinctrl_desc pctl_desc;38 39	struct sh_pfc *pfc;40 41	struct pinctrl_pin_desc *pins;42	struct sh_pfc_pin_config *configs;43};44 45static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev)46{47	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);48 49	return pmx->pfc->info->nr_groups;50}51 52static const char *sh_pfc_get_group_name(struct pinctrl_dev *pctldev,53					 unsigned selector)54{55	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);56 57	return pmx->pfc->info->groups[selector].name;58}59 60static int sh_pfc_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,61				 const unsigned **pins, unsigned *num_pins)62{63	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);64 65	*pins = pmx->pfc->info->groups[selector].pins;66	*num_pins = pmx->pfc->info->groups[selector].nr_pins;67 68	return 0;69}70 71static void sh_pfc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,72				unsigned offset)73{74	seq_puts(s, DRV_NAME);75}76 77#ifdef CONFIG_OF78static int sh_pfc_map_add_config(struct pinctrl_map *map,79				 const char *group_or_pin,80				 enum pinctrl_map_type type,81				 unsigned long *configs,82				 unsigned int num_configs)83{84	unsigned long *cfgs;85 86	cfgs = kmemdup_array(configs, num_configs, sizeof(*cfgs), GFP_KERNEL);87	if (cfgs == NULL)88		return -ENOMEM;89 90	map->type = type;91	map->data.configs.group_or_pin = group_or_pin;92	map->data.configs.configs = cfgs;93	map->data.configs.num_configs = num_configs;94 95	return 0;96}97 98static int sh_pfc_dt_subnode_to_map(struct pinctrl_dev *pctldev,99				    struct device_node *np,100				    struct pinctrl_map **map,101				    unsigned int *num_maps, unsigned int *index)102{103	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);104	struct device *dev = pmx->pfc->dev;105	struct pinctrl_map *maps = *map;106	unsigned int nmaps = *num_maps;107	unsigned int idx = *index;108	unsigned int num_configs;109	const char *function = NULL;110	unsigned long *configs;111	struct property *prop;112	unsigned int num_groups;113	unsigned int num_pins;114	const char *group;115	const char *pin;116	int ret;117 118	/* Parse the function and configuration properties. At least a function119	 * or one configuration must be specified.120	 */121	ret = of_property_read_string(np, "function", &function);122	if (ret < 0 && ret != -EINVAL) {123		dev_err(dev, "Invalid function in DT\n");124		return ret;125	}126 127	ret = pinconf_generic_parse_dt_config(np, NULL, &configs, &num_configs);128	if (ret < 0)129		return ret;130 131	if (!function && num_configs == 0) {132		dev_err(dev,133			"DT node must contain at least a function or config\n");134		ret = -ENODEV;135		goto done;136	}137 138	/* Count the number of pins and groups and reallocate mappings. */139	ret = of_property_count_strings(np, "pins");140	if (ret == -EINVAL) {141		num_pins = 0;142	} else if (ret < 0) {143		dev_err(dev, "Invalid pins list in DT\n");144		goto done;145	} else {146		num_pins = ret;147	}148 149	ret = of_property_count_strings(np, "groups");150	if (ret == -EINVAL) {151		num_groups = 0;152	} else if (ret < 0) {153		dev_err(dev, "Invalid pin groups list in DT\n");154		goto done;155	} else {156		num_groups = ret;157	}158 159	if (!num_pins && !num_groups) {160		dev_err(dev, "No pin or group provided in DT node\n");161		ret = -ENODEV;162		goto done;163	}164 165	if (function)166		nmaps += num_groups;167	if (configs)168		nmaps += num_pins + num_groups;169 170	maps = krealloc(maps, sizeof(*maps) * nmaps, GFP_KERNEL);171	if (maps == NULL) {172		ret = -ENOMEM;173		goto done;174	}175 176	*map = maps;177	*num_maps = nmaps;178 179	/* Iterate over pins and groups and create the mappings. */180	of_property_for_each_string(np, "groups", prop, group) {181		if (function) {182			maps[idx].type = PIN_MAP_TYPE_MUX_GROUP;183			maps[idx].data.mux.group = group;184			maps[idx].data.mux.function = function;185			idx++;186		}187 188		if (configs) {189			ret = sh_pfc_map_add_config(&maps[idx], group,190						    PIN_MAP_TYPE_CONFIGS_GROUP,191						    configs, num_configs);192			if (ret < 0)193				goto done;194 195			idx++;196		}197	}198 199	if (!configs) {200		ret = 0;201		goto done;202	}203 204	of_property_for_each_string(np, "pins", prop, pin) {205		ret = sh_pfc_map_add_config(&maps[idx], pin,206					    PIN_MAP_TYPE_CONFIGS_PIN,207					    configs, num_configs);208		if (ret < 0)209			goto done;210 211		idx++;212	}213 214done:215	*index = idx;216	kfree(configs);217	return ret;218}219 220static void sh_pfc_dt_free_map(struct pinctrl_dev *pctldev,221			       struct pinctrl_map *map, unsigned num_maps)222{223	unsigned int i;224 225	if (map == NULL)226		return;227 228	for (i = 0; i < num_maps; ++i) {229		if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP ||230		    map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)231			kfree(map[i].data.configs.configs);232	}233 234	kfree(map);235}236 237static int sh_pfc_dt_node_to_map(struct pinctrl_dev *pctldev,238				 struct device_node *np,239				 struct pinctrl_map **map, unsigned *num_maps)240{241	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);242	struct device *dev = pmx->pfc->dev;243	unsigned int index;244	int ret;245 246	*map = NULL;247	*num_maps = 0;248	index = 0;249 250	for_each_child_of_node_scoped(np, child) {251		ret = sh_pfc_dt_subnode_to_map(pctldev, child, map, num_maps,252					       &index);253		if (ret < 0)254			goto done;255	}256 257	/* If no mapping has been found in child nodes try the config node. */258	if (*num_maps == 0) {259		ret = sh_pfc_dt_subnode_to_map(pctldev, np, map, num_maps,260					       &index);261		if (ret < 0)262			goto done;263	}264 265	if (*num_maps)266		return 0;267 268	dev_err(dev, "no mapping found in node %pOF\n", np);269	ret = -EINVAL;270 271done:272	if (ret < 0)273		sh_pfc_dt_free_map(pctldev, *map, *num_maps);274 275	return ret;276}277#endif /* CONFIG_OF */278 279static const struct pinctrl_ops sh_pfc_pinctrl_ops = {280	.get_groups_count	= sh_pfc_get_groups_count,281	.get_group_name		= sh_pfc_get_group_name,282	.get_group_pins		= sh_pfc_get_group_pins,283	.pin_dbg_show		= sh_pfc_pin_dbg_show,284#ifdef CONFIG_OF285	.dt_node_to_map		= sh_pfc_dt_node_to_map,286	.dt_free_map		= sh_pfc_dt_free_map,287#endif288};289 290static int sh_pfc_get_functions_count(struct pinctrl_dev *pctldev)291{292	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);293 294	return pmx->pfc->info->nr_functions;295}296 297static const char *sh_pfc_get_function_name(struct pinctrl_dev *pctldev,298					    unsigned selector)299{300	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);301 302	return pmx->pfc->info->functions[selector].name;303}304 305static int sh_pfc_get_function_groups(struct pinctrl_dev *pctldev,306				      unsigned selector,307				      const char * const **groups,308				      unsigned * const num_groups)309{310	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);311 312	*groups = pmx->pfc->info->functions[selector].groups;313	*num_groups = pmx->pfc->info->functions[selector].nr_groups;314 315	return 0;316}317 318static int sh_pfc_func_set_mux(struct pinctrl_dev *pctldev, unsigned selector,319			       unsigned group)320{321	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);322	struct sh_pfc *pfc = pmx->pfc;323	const struct sh_pfc_pin_group *grp = &pfc->info->groups[group];324	unsigned long flags;325	unsigned int i;326	int ret = 0;327 328	dev_dbg(pctldev->dev, "Configuring pin group %s\n", grp->name);329 330	spin_lock_irqsave(&pfc->lock, flags);331 332	for (i = 0; i < grp->nr_pins; ++i) {333		int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);334		struct sh_pfc_pin_config *cfg = &pmx->configs[idx];335 336		/*337		 * This driver cannot manage both gpio and mux when the gpio338		 * pin is already enabled. So, this function fails.339		 */340		if (cfg->gpio_enabled) {341			ret = -EBUSY;342			goto done;343		}344 345		ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION);346		if (ret < 0)347			goto done;348	}349 350	/* All group pins are configured, mark the pins as muxed */351	for (i = 0; i < grp->nr_pins; ++i) {352		int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);353		struct sh_pfc_pin_config *cfg = &pmx->configs[idx];354 355		cfg->mux_mark = grp->mux[i];356	}357 358done:359	spin_unlock_irqrestore(&pfc->lock, flags);360	return ret;361}362 363static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,364				      struct pinctrl_gpio_range *range,365				      unsigned offset)366{367	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);368	struct sh_pfc *pfc = pmx->pfc;369	int idx = sh_pfc_get_pin_index(pfc, offset);370	struct sh_pfc_pin_config *cfg = &pmx->configs[idx];371	unsigned long flags;372	int ret;373 374	spin_lock_irqsave(&pfc->lock, flags);375 376	if (!pfc->gpio && !cfg->mux_mark) {377		/* If GPIOs are handled externally the pin mux type needs to be378		 * set to GPIO here.379		 */380		const struct sh_pfc_pin *pin = &pfc->info->pins[idx];381 382		ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO);383		if (ret < 0)384			goto done;385	}386 387	cfg->gpio_enabled = true;388 389	ret = 0;390 391done:392	spin_unlock_irqrestore(&pfc->lock, flags);393 394	return ret;395}396 397static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev,398				     struct pinctrl_gpio_range *range,399				     unsigned offset)400{401	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);402	struct sh_pfc *pfc = pmx->pfc;403	int idx = sh_pfc_get_pin_index(pfc, offset);404	struct sh_pfc_pin_config *cfg = &pmx->configs[idx];405	unsigned long flags;406 407	spin_lock_irqsave(&pfc->lock, flags);408	cfg->gpio_enabled = false;409	/* If mux is already set, this configures it here */410	if (cfg->mux_mark)411		sh_pfc_config_mux(pfc, cfg->mux_mark, PINMUX_TYPE_FUNCTION);412	spin_unlock_irqrestore(&pfc->lock, flags);413}414 415#ifdef CONFIG_PINCTRL_SH_PFC_GPIO416static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev,417				     struct pinctrl_gpio_range *range,418				     unsigned offset, bool input)419{420	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);421	struct sh_pfc *pfc = pmx->pfc;422	int new_type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT;423	int idx = sh_pfc_get_pin_index(pfc, offset);424	const struct sh_pfc_pin *pin = &pfc->info->pins[idx];425	unsigned long flags;426	unsigned int dir;427	int ret;428 429	/* Check if the requested direction is supported by the pin. Not all430	 * SoCs provide pin config data, so perform the check conditionally.431	 */432	if (pin->configs) {433		dir = input ? SH_PFC_PIN_CFG_INPUT : SH_PFC_PIN_CFG_OUTPUT;434		if (!(pin->configs & dir))435			return -EINVAL;436	}437 438	spin_lock_irqsave(&pfc->lock, flags);439	ret = sh_pfc_config_mux(pfc, pin->enum_id, new_type);440	spin_unlock_irqrestore(&pfc->lock, flags);441	return ret;442}443#else444#define sh_pfc_gpio_set_direction	NULL445#endif446 447static const struct pinmux_ops sh_pfc_pinmux_ops = {448	.get_functions_count	= sh_pfc_get_functions_count,449	.get_function_name	= sh_pfc_get_function_name,450	.get_function_groups	= sh_pfc_get_function_groups,451	.set_mux		= sh_pfc_func_set_mux,452	.gpio_request_enable	= sh_pfc_gpio_request_enable,453	.gpio_disable_free	= sh_pfc_gpio_disable_free,454	.gpio_set_direction	= sh_pfc_gpio_set_direction,455};456 457static u32 sh_pfc_pinconf_find_drive_strength_reg(struct sh_pfc *pfc,458		unsigned int pin, unsigned int *offset, unsigned int *size)459{460	const struct pinmux_drive_reg_field *field;461	const struct pinmux_drive_reg *reg;462	unsigned int i;463 464	for (reg = pfc->info->drive_regs; reg->reg; ++reg) {465		for (i = 0; i < ARRAY_SIZE(reg->fields); ++i) {466			field = &reg->fields[i];467 468			if (field->size && field->pin == pin) {469				*offset = field->offset;470				*size = field->size;471 472				return reg->reg;473			}474		}475	}476 477	return 0;478}479 480static int sh_pfc_pinconf_get_drive_strength(struct sh_pfc *pfc,481					     unsigned int pin)482{483	unsigned int offset;484	unsigned int size;485	u32 reg;486	u32 val;487 488	reg = sh_pfc_pinconf_find_drive_strength_reg(pfc, pin, &offset, &size);489	if (!reg)490		return -EINVAL;491 492	val = (sh_pfc_read(pfc, reg) >> offset) & GENMASK(size - 1, 0);493 494	/* Convert the value to mA based on a full drive strength value of 24mA.495	 * We can make the full value configurable later if needed.496	 */497	return (val + 1) * (size == 2 ? 6 : 3);498}499 500static int sh_pfc_pinconf_set_drive_strength(struct sh_pfc *pfc,501					     unsigned int pin, u16 strength)502{503	unsigned long flags;504	unsigned int offset;505	unsigned int size;506	unsigned int step;507	u32 reg;508	u32 val;509 510	reg = sh_pfc_pinconf_find_drive_strength_reg(pfc, pin, &offset, &size);511	if (!reg)512		return -EINVAL;513 514	step = size == 2 ? 6 : 3;515 516	if (strength < step || strength > 24)517		return -EINVAL;518 519	/* Convert the value from mA based on a full drive strength value of520	 * 24mA. We can make the full value configurable later if needed.521	 */522	strength = strength / step - 1;523 524	spin_lock_irqsave(&pfc->lock, flags);525 526	val = sh_pfc_read(pfc, reg);527	val &= ~GENMASK(offset + size - 1, offset);528	val |= strength << offset;529 530	sh_pfc_write(pfc, reg, val);531 532	spin_unlock_irqrestore(&pfc->lock, flags);533 534	return 0;535}536 537/* Check whether the requested parameter is supported for a pin. */538static bool sh_pfc_pinconf_validate(struct sh_pfc *pfc, unsigned int _pin,539				    enum pin_config_param param)540{541	int idx = sh_pfc_get_pin_index(pfc, _pin);542	const struct sh_pfc_pin *pin = &pfc->info->pins[idx];543 544	switch (param) {545	case PIN_CONFIG_BIAS_DISABLE:546		return pin->configs & SH_PFC_PIN_CFG_PULL_UP_DOWN;547 548	case PIN_CONFIG_BIAS_PULL_UP:549		return pin->configs & SH_PFC_PIN_CFG_PULL_UP;550 551	case PIN_CONFIG_BIAS_PULL_DOWN:552		return pin->configs & SH_PFC_PIN_CFG_PULL_DOWN;553 554	case PIN_CONFIG_DRIVE_STRENGTH:555		return pin->configs & SH_PFC_PIN_CFG_DRIVE_STRENGTH;556 557	case PIN_CONFIG_POWER_SOURCE:558		return pin->configs & SH_PFC_PIN_CFG_IO_VOLTAGE_MASK;559 560	default:561		return false;562	}563}564 565static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,566			      unsigned long *config)567{568	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);569	struct sh_pfc *pfc = pmx->pfc;570	enum pin_config_param param = pinconf_to_config_param(*config);571	unsigned long flags;572	unsigned int arg;573 574	if (!sh_pfc_pinconf_validate(pfc, _pin, param))575		return -ENOTSUPP;576 577	switch (param) {578	case PIN_CONFIG_BIAS_DISABLE:579	case PIN_CONFIG_BIAS_PULL_UP:580	case PIN_CONFIG_BIAS_PULL_DOWN: {581		unsigned int bias;582 583		if (!pfc->info->ops || !pfc->info->ops->get_bias)584			return -ENOTSUPP;585 586		spin_lock_irqsave(&pfc->lock, flags);587		bias = pfc->info->ops->get_bias(pfc, _pin);588		spin_unlock_irqrestore(&pfc->lock, flags);589 590		if (bias != param)591			return -EINVAL;592 593		arg = 0;594		break;595	}596 597	case PIN_CONFIG_DRIVE_STRENGTH: {598		int ret;599 600		ret = sh_pfc_pinconf_get_drive_strength(pfc, _pin);601		if (ret < 0)602			return ret;603 604		arg = ret;605		break;606	}607 608	case PIN_CONFIG_POWER_SOURCE: {609		int idx = sh_pfc_get_pin_index(pfc, _pin);610		const struct sh_pfc_pin *pin = &pfc->info->pins[idx];611		unsigned int mode, lo, hi;612		u32 pocctrl, val;613		int bit;614 615		if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl)616			return -ENOTSUPP;617 618		bit = pfc->info->ops->pin_to_pocctrl(_pin, &pocctrl);619		if (WARN(bit < 0, "invalid pin %#x", _pin))620			return bit;621 622		val = sh_pfc_read(pfc, pocctrl);623 624		mode = pin->configs & SH_PFC_PIN_CFG_IO_VOLTAGE_MASK;625		lo = mode <= SH_PFC_PIN_CFG_IO_VOLTAGE_18_33 ? 1800 : 2500;626		hi = mode >= SH_PFC_PIN_CFG_IO_VOLTAGE_18_33 ? 3300 : 2500;627 628		arg = (val & BIT(bit)) ? hi : lo;629		break;630	}631 632	default:633		return -ENOTSUPP;634	}635 636	*config = pinconf_to_config_packed(param, arg);637	return 0;638}639 640static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin,641			      unsigned long *configs, unsigned num_configs)642{643	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);644	struct sh_pfc *pfc = pmx->pfc;645	enum pin_config_param param;646	unsigned long flags;647	unsigned int i;648 649	for (i = 0; i < num_configs; i++) {650		param = pinconf_to_config_param(configs[i]);651 652		if (!sh_pfc_pinconf_validate(pfc, _pin, param))653			return -ENOTSUPP;654 655		switch (param) {656		case PIN_CONFIG_BIAS_PULL_UP:657		case PIN_CONFIG_BIAS_PULL_DOWN:658		case PIN_CONFIG_BIAS_DISABLE:659			if (!pfc->info->ops || !pfc->info->ops->set_bias)660				return -ENOTSUPP;661 662			spin_lock_irqsave(&pfc->lock, flags);663			pfc->info->ops->set_bias(pfc, _pin, param);664			spin_unlock_irqrestore(&pfc->lock, flags);665 666			break;667 668		case PIN_CONFIG_DRIVE_STRENGTH: {669			unsigned int arg =670				pinconf_to_config_argument(configs[i]);671			int ret;672 673			ret = sh_pfc_pinconf_set_drive_strength(pfc, _pin, arg);674			if (ret < 0)675				return ret;676 677			break;678		}679 680		case PIN_CONFIG_POWER_SOURCE: {681			unsigned int mV = pinconf_to_config_argument(configs[i]);682			int idx = sh_pfc_get_pin_index(pfc, _pin);683			const struct sh_pfc_pin *pin = &pfc->info->pins[idx];684			unsigned int mode, lo, hi;685			u32 pocctrl, val;686			int bit;687 688			if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl)689				return -ENOTSUPP;690 691			bit = pfc->info->ops->pin_to_pocctrl(_pin, &pocctrl);692			if (WARN(bit < 0, "invalid pin %#x", _pin))693				return bit;694 695			mode = pin->configs & SH_PFC_PIN_CFG_IO_VOLTAGE_MASK;696			lo = mode <= SH_PFC_PIN_CFG_IO_VOLTAGE_18_33 ? 1800 : 2500;697			hi = mode >= SH_PFC_PIN_CFG_IO_VOLTAGE_18_33 ? 3300 : 2500;698 699			if (mV != lo && mV != hi)700				return -EINVAL;701 702			spin_lock_irqsave(&pfc->lock, flags);703			val = sh_pfc_read(pfc, pocctrl);704			if (mV == hi)705				val |= BIT(bit);706			else707				val &= ~BIT(bit);708			sh_pfc_write(pfc, pocctrl, val);709			spin_unlock_irqrestore(&pfc->lock, flags);710 711			break;712		}713 714		default:715			return -ENOTSUPP;716		}717	} /* for each config */718 719	return 0;720}721 722static int sh_pfc_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned group,723				    unsigned long *configs,724				    unsigned num_configs)725{726	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);727	const unsigned int *pins;728	unsigned int num_pins;729	unsigned int i, ret;730 731	pins = pmx->pfc->info->groups[group].pins;732	num_pins = pmx->pfc->info->groups[group].nr_pins;733 734	for (i = 0; i < num_pins; ++i) {735		ret = sh_pfc_pinconf_set(pctldev, pins[i], configs, num_configs);736		if (ret)737			return ret;738	}739 740	return 0;741}742 743static const struct pinconf_ops sh_pfc_pinconf_ops = {744	.is_generic			= true,745	.pin_config_get			= sh_pfc_pinconf_get,746	.pin_config_set			= sh_pfc_pinconf_set,747	.pin_config_group_set		= sh_pfc_pinconf_group_set,748	.pin_config_config_dbg_show	= pinconf_generic_dump_config,749};750 751/* PFC ranges -> pinctrl pin descs */752static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)753{754	unsigned int i;755 756	/* Allocate and initialize the pins and configs arrays. */757	pmx->pins = devm_kcalloc(pfc->dev,758				 pfc->info->nr_pins, sizeof(*pmx->pins),759				 GFP_KERNEL);760	if (unlikely(!pmx->pins))761		return -ENOMEM;762 763	pmx->configs = devm_kcalloc(pfc->dev,764				    pfc->info->nr_pins, sizeof(*pmx->configs),765				    GFP_KERNEL);766	if (unlikely(!pmx->configs))767		return -ENOMEM;768 769	for (i = 0; i < pfc->info->nr_pins; ++i) {770		const struct sh_pfc_pin *info = &pfc->info->pins[i];771		struct pinctrl_pin_desc *pin = &pmx->pins[i];772 773		/* If the pin number is equal to -1 all pins are considered */774		pin->number = info->pin != (u16)-1 ? info->pin : i;775		pin->name = info->name;776	}777 778	return 0;779}780 781int sh_pfc_register_pinctrl(struct sh_pfc *pfc)782{783	struct sh_pfc_pinctrl *pmx;784	int ret;785 786	pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL);787	if (unlikely(!pmx))788		return -ENOMEM;789 790	pmx->pfc = pfc;791 792	ret = sh_pfc_map_pins(pfc, pmx);793	if (ret < 0)794		return ret;795 796	pmx->pctl_desc.name = DRV_NAME;797	pmx->pctl_desc.owner = THIS_MODULE;798	pmx->pctl_desc.pctlops = &sh_pfc_pinctrl_ops;799	pmx->pctl_desc.pmxops = &sh_pfc_pinmux_ops;800	pmx->pctl_desc.confops = &sh_pfc_pinconf_ops;801	pmx->pctl_desc.pins = pmx->pins;802	pmx->pctl_desc.npins = pfc->info->nr_pins;803 804	ret = devm_pinctrl_register_and_init(pfc->dev, &pmx->pctl_desc, pmx,805					     &pmx->pctl);806	if (ret) {807		dev_err(pfc->dev, "could not register: %i\n", ret);808 809		return ret;810	}811 812	return pinctrl_enable(pmx->pctl);813}814 815const struct pinmux_bias_reg *816rcar_pin_to_bias_reg(const struct sh_pfc_soc_info *info, unsigned int pin,817		     unsigned int *bit)818{819	unsigned int i, j;820 821	for (i = 0; info->bias_regs[i].puen || info->bias_regs[i].pud; i++) {822		for (j = 0; j < ARRAY_SIZE(info->bias_regs[i].pins); j++) {823			if (info->bias_regs[i].pins[j] == pin) {824				*bit = j;825				return &info->bias_regs[i];826			}827		}828	}829 830	WARN_ONCE(1, "Pin %u is not in bias info list\n", pin);831 832	return NULL;833}834 835unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin)836{837	const struct pinmux_bias_reg *reg;838	unsigned int bit;839 840	reg = rcar_pin_to_bias_reg(pfc->info, pin, &bit);841	if (!reg)842		return PIN_CONFIG_BIAS_DISABLE;843 844	if (reg->puen) {845		if (!(sh_pfc_read(pfc, reg->puen) & BIT(bit)))846			return PIN_CONFIG_BIAS_DISABLE;847		else if (!reg->pud || (sh_pfc_read(pfc, reg->pud) & BIT(bit)))848			return PIN_CONFIG_BIAS_PULL_UP;849		else850			return PIN_CONFIG_BIAS_PULL_DOWN;851	} else {852		if (sh_pfc_read(pfc, reg->pud) & BIT(bit))853			return PIN_CONFIG_BIAS_PULL_DOWN;854		else855			return PIN_CONFIG_BIAS_DISABLE;856	}857}858 859void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,860			  unsigned int bias)861{862	const struct pinmux_bias_reg *reg;863	u32 enable, updown;864	unsigned int bit;865 866	reg = rcar_pin_to_bias_reg(pfc->info, pin, &bit);867	if (!reg)868		return;869 870	if (reg->puen) {871		enable = sh_pfc_read(pfc, reg->puen) & ~BIT(bit);872		if (bias != PIN_CONFIG_BIAS_DISABLE) {873			enable |= BIT(bit);874 875			if (reg->pud) {876				updown = sh_pfc_read(pfc, reg->pud) & ~BIT(bit);877				if (bias == PIN_CONFIG_BIAS_PULL_UP)878					updown |= BIT(bit);879 880				sh_pfc_write(pfc, reg->pud, updown);881			}882		}883		sh_pfc_write(pfc, reg->puen, enable);884	} else {885		enable = sh_pfc_read(pfc, reg->pud) & ~BIT(bit);886		if (bias == PIN_CONFIG_BIAS_PULL_DOWN)887			enable |= BIT(bit);888 889		sh_pfc_write(pfc, reg->pud, enable);890	}891}892 893#define PORTnCR_PULMD_OFF	(0 << 6)894#define PORTnCR_PULMD_DOWN	(2 << 6)895#define PORTnCR_PULMD_UP	(3 << 6)896#define PORTnCR_PULMD_MASK	(3 << 6)897 898unsigned int rmobile_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin)899{900	void __iomem *reg = pfc->windows->virt +901			    pfc->info->ops->pin_to_portcr(pin);902	u32 value = ioread8(reg) & PORTnCR_PULMD_MASK;903 904	switch (value) {905	case PORTnCR_PULMD_UP:906		return PIN_CONFIG_BIAS_PULL_UP;907	case PORTnCR_PULMD_DOWN:908		return PIN_CONFIG_BIAS_PULL_DOWN;909	case PORTnCR_PULMD_OFF:910	default:911		return PIN_CONFIG_BIAS_DISABLE;912	}913}914 915void rmobile_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,916			     unsigned int bias)917{918	void __iomem *reg = pfc->windows->virt +919			    pfc->info->ops->pin_to_portcr(pin);920	u32 value = ioread8(reg) & ~PORTnCR_PULMD_MASK;921 922	switch (bias) {923	case PIN_CONFIG_BIAS_PULL_UP:924		value |= PORTnCR_PULMD_UP;925		break;926	case PIN_CONFIG_BIAS_PULL_DOWN:927		value |= PORTnCR_PULMD_DOWN;928		break;929	}930 931	iowrite8(value, reg);932}933