brintos

brintos / linux-shallow public Read only

0
0
Text · 13.4 KiB · 2cb0b47 Raw
588 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Intel Tangier pinctrl driver4 *5 * Copyright (C) 2016, 2023 Intel Corporation6 *7 * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>8 *          Raag Jadav <raag.jadav@intel.com>9 */10 11#include <linux/bits.h>12#include <linux/cleanup.h>13#include <linux/device.h>14#include <linux/err.h>15#include <linux/errno.h>16#include <linux/export.h>17#include <linux/io.h>18#include <linux/module.h>19#include <linux/overflow.h>20#include <linux/platform_device.h>21#include <linux/property.h>22#include <linux/seq_file.h>23#include <linux/spinlock.h>24#include <linux/types.h>25 26#include <linux/pinctrl/pinconf-generic.h>27#include <linux/pinctrl/pinconf.h>28#include <linux/pinctrl/pinctrl.h>29#include <linux/pinctrl/pinmux.h>30 31#include "../core.h"32#include "pinctrl-intel.h"33#include "pinctrl-tangier.h"34 35#define SLEW_OFFSET			0x00036#define BUFCFG_OFFSET			0x10037#define MISC_OFFSET			0x30038 39#define BUFCFG_PINMODE_SHIFT		040#define BUFCFG_PINMODE_MASK		GENMASK(2, 0)41#define BUFCFG_PINMODE_GPIO		042#define BUFCFG_PUPD_VAL_SHIFT		443#define BUFCFG_PUPD_VAL_MASK		GENMASK(5, 4)44#define BUFCFG_PUPD_VAL_2K		045#define BUFCFG_PUPD_VAL_20K		146#define BUFCFG_PUPD_VAL_50K		247#define BUFCFG_PUPD_VAL_910		348#define BUFCFG_PU_EN			BIT(8)49#define BUFCFG_PD_EN			BIT(9)50#define BUFCFG_Px_EN_MASK		GENMASK(9, 8)51#define BUFCFG_SLEWSEL			BIT(10)52#define BUFCFG_OVINEN			BIT(12)53#define BUFCFG_OVINEN_EN		BIT(13)54#define BUFCFG_OVINEN_MASK		GENMASK(13, 12)55#define BUFCFG_OVOUTEN			BIT(14)56#define BUFCFG_OVOUTEN_EN		BIT(15)57#define BUFCFG_OVOUTEN_MASK		GENMASK(15, 14)58#define BUFCFG_INDATAOV_VAL		BIT(16)59#define BUFCFG_INDATAOV_EN		BIT(17)60#define BUFCFG_INDATAOV_MASK		GENMASK(17, 16)61#define BUFCFG_OUTDATAOV_VAL		BIT(18)62#define BUFCFG_OUTDATAOV_EN		BIT(19)63#define BUFCFG_OUTDATAOV_MASK		GENMASK(19, 18)64#define BUFCFG_OD_EN			BIT(21)65 66#define pin_to_bufno(f, p)		((p) - (f)->pin_base)67 68static const struct tng_family *tng_get_family(struct tng_pinctrl *tp,69					       unsigned int pin)70{71	const struct tng_family *family;72	unsigned int i;73 74	for (i = 0; i < tp->nfamilies; i++) {75		family = &tp->families[i];76		if (pin >= family->pin_base &&77		    pin < family->pin_base + family->npins)78			return family;79	}80 81	dev_warn(tp->dev, "failed to find family for pin %u\n", pin);82	return NULL;83}84 85static bool tng_buf_available(struct tng_pinctrl *tp, unsigned int pin)86{87	const struct tng_family *family;88 89	family = tng_get_family(tp, pin);90	if (!family)91		return false;92 93	return !family->protected;94}95 96static void __iomem *tng_get_bufcfg(struct tng_pinctrl *tp, unsigned int pin)97{98	const struct tng_family *family;99	unsigned int bufno;100 101	family = tng_get_family(tp, pin);102	if (!family)103		return NULL;104 105	bufno = pin_to_bufno(family, pin);106	return family->regs + BUFCFG_OFFSET + bufno * 4;107}108 109static int tng_read_bufcfg(struct tng_pinctrl *tp, unsigned int pin, u32 *value)110{111	void __iomem *bufcfg;112 113	if (!tng_buf_available(tp, pin))114		return -EBUSY;115 116	bufcfg = tng_get_bufcfg(tp, pin);117	*value = readl(bufcfg);118 119	return 0;120}121 122static void tng_update_bufcfg(struct tng_pinctrl *tp, unsigned int pin,123			      u32 bits, u32 mask)124{125	void __iomem *bufcfg;126	u32 value;127 128	bufcfg = tng_get_bufcfg(tp, pin);129 130	value = readl(bufcfg);131	value = (value & ~mask) | (bits & mask);132	writel(value, bufcfg);133}134 135static int tng_get_groups_count(struct pinctrl_dev *pctldev)136{137	struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);138 139	return tp->ngroups;140}141 142static const char *tng_get_group_name(struct pinctrl_dev *pctldev,143				      unsigned int group)144{145	struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);146 147	return tp->groups[group].grp.name;148}149 150static int tng_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group,151			      const unsigned int **pins, unsigned int *npins)152{153	struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);154 155	*pins = tp->groups[group].grp.pins;156	*npins = tp->groups[group].grp.npins;157	return 0;158}159 160static void tng_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,161			     unsigned int pin)162{163	struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);164	u32 value, mode;165	int ret;166 167	ret = tng_read_bufcfg(tp, pin, &value);168	if (ret) {169		seq_puts(s, "not available");170		return;171	}172 173	mode = (value & BUFCFG_PINMODE_MASK) >> BUFCFG_PINMODE_SHIFT;174	if (mode == BUFCFG_PINMODE_GPIO)175		seq_puts(s, "GPIO ");176	else177		seq_printf(s, "mode %d ", mode);178 179	seq_printf(s, "0x%08x", value);180}181 182static const struct pinctrl_ops tng_pinctrl_ops = {183	.get_groups_count = tng_get_groups_count,184	.get_group_name = tng_get_group_name,185	.get_group_pins = tng_get_group_pins,186	.pin_dbg_show = tng_pin_dbg_show,187};188 189static int tng_get_functions_count(struct pinctrl_dev *pctldev)190{191	struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);192 193	return tp->nfunctions;194}195 196static const char *tng_get_function_name(struct pinctrl_dev *pctldev,197					 unsigned int function)198{199	struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);200 201	return tp->functions[function].func.name;202}203 204static int tng_get_function_groups(struct pinctrl_dev *pctldev,205				   unsigned int function,206				   const char * const **groups,207				   unsigned int * const ngroups)208{209	struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);210 211	*groups = tp->functions[function].func.groups;212	*ngroups = tp->functions[function].func.ngroups;213	return 0;214}215 216static int tng_pinmux_set_mux(struct pinctrl_dev *pctldev,217			      unsigned int function,218			      unsigned int group)219{220	struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);221	const struct intel_pingroup *grp = &tp->groups[group];222	u32 bits = grp->mode << BUFCFG_PINMODE_SHIFT;223	u32 mask = BUFCFG_PINMODE_MASK;224	unsigned int i;225 226	/*227	 * All pins in the groups needs to be accessible and writable228	 * before we can enable the mux for this group.229	 */230	for (i = 0; i < grp->grp.npins; i++) {231		if (!tng_buf_available(tp, grp->grp.pins[i]))232			return -EBUSY;233	}234 235	guard(raw_spinlock_irqsave)(&tp->lock);236 237	/* Now enable the mux setting for each pin in the group */238	for (i = 0; i < grp->grp.npins; i++)239		tng_update_bufcfg(tp, grp->grp.pins[i], bits, mask);240 241	return 0;242}243 244static int tng_gpio_request_enable(struct pinctrl_dev *pctldev,245				   struct pinctrl_gpio_range *range,246				   unsigned int pin)247{248	struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);249	u32 bits = BUFCFG_PINMODE_GPIO << BUFCFG_PINMODE_SHIFT;250	u32 mask = BUFCFG_PINMODE_MASK;251 252	if (!tng_buf_available(tp, pin))253		return -EBUSY;254 255	guard(raw_spinlock_irqsave)(&tp->lock);256 257	tng_update_bufcfg(tp, pin, bits, mask);258 259	return 0;260}261 262static const struct pinmux_ops tng_pinmux_ops = {263	.get_functions_count = tng_get_functions_count,264	.get_function_name = tng_get_function_name,265	.get_function_groups = tng_get_function_groups,266	.set_mux = tng_pinmux_set_mux,267	.gpio_request_enable = tng_gpio_request_enable,268};269 270static int tng_config_get(struct pinctrl_dev *pctldev, unsigned int pin,271			  unsigned long *config)272{273	struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);274	enum pin_config_param param = pinconf_to_config_param(*config);275	u32 value, term;276	u16 arg = 0;277	int ret;278 279	ret = tng_read_bufcfg(tp, pin, &value);280	if (ret)281		return -ENOTSUPP;282 283	term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT;284 285	switch (param) {286	case PIN_CONFIG_BIAS_DISABLE:287		if (value & BUFCFG_Px_EN_MASK)288			return -EINVAL;289		break;290 291	case PIN_CONFIG_BIAS_PULL_UP:292		if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PU_EN)293			return -EINVAL;294 295		switch (term) {296		case BUFCFG_PUPD_VAL_910:297			arg = 910;298			break;299		case BUFCFG_PUPD_VAL_2K:300			arg = 2000;301			break;302		case BUFCFG_PUPD_VAL_20K:303			arg = 20000;304			break;305		case BUFCFG_PUPD_VAL_50K:306			arg = 50000;307			break;308		}309 310		break;311 312	case PIN_CONFIG_BIAS_PULL_DOWN:313		if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PD_EN)314			return -EINVAL;315 316		switch (term) {317		case BUFCFG_PUPD_VAL_910:318			arg = 910;319			break;320		case BUFCFG_PUPD_VAL_2K:321			arg = 2000;322			break;323		case BUFCFG_PUPD_VAL_20K:324			arg = 20000;325			break;326		case BUFCFG_PUPD_VAL_50K:327			arg = 50000;328			break;329		}330 331		break;332 333	case PIN_CONFIG_DRIVE_PUSH_PULL:334		if (value & BUFCFG_OD_EN)335			return -EINVAL;336		break;337 338	case PIN_CONFIG_DRIVE_OPEN_DRAIN:339		if (!(value & BUFCFG_OD_EN))340			return -EINVAL;341		break;342 343	case PIN_CONFIG_SLEW_RATE:344		if (value & BUFCFG_SLEWSEL)345			arg = 1;346		break;347 348	default:349		return -ENOTSUPP;350	}351 352	*config = pinconf_to_config_packed(param, arg);353	return 0;354}355 356static int tng_config_set_pin(struct tng_pinctrl *tp, unsigned int pin,357			      unsigned long config)358{359	unsigned int param = pinconf_to_config_param(config);360	unsigned int arg = pinconf_to_config_argument(config);361	u32 mask, term, value = 0;362 363	switch (param) {364	case PIN_CONFIG_BIAS_DISABLE:365		mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;366		break;367 368	case PIN_CONFIG_BIAS_PULL_UP:369		switch (arg) {370		case 50000:371			term = BUFCFG_PUPD_VAL_50K;372			break;373		case 1: /* Set default strength value in case none is given */374		case 20000:375			term = BUFCFG_PUPD_VAL_20K;376			break;377		case 2000:378			term = BUFCFG_PUPD_VAL_2K;379			break;380		case 910:381			term = BUFCFG_PUPD_VAL_910;382			break;383		default:384			return -EINVAL;385		}386 387		mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;388		value = BUFCFG_PU_EN | (term << BUFCFG_PUPD_VAL_SHIFT);389		break;390 391	case PIN_CONFIG_BIAS_PULL_DOWN:392		switch (arg) {393		case 50000:394			term = BUFCFG_PUPD_VAL_50K;395			break;396		case 1: /* Set default strength value in case none is given */397		case 20000:398			term = BUFCFG_PUPD_VAL_20K;399			break;400		case 2000:401			term = BUFCFG_PUPD_VAL_2K;402			break;403		case 910:404			term = BUFCFG_PUPD_VAL_910;405			break;406		default:407			return -EINVAL;408		}409 410		mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;411		value = BUFCFG_PD_EN | (term << BUFCFG_PUPD_VAL_SHIFT);412		break;413 414	case PIN_CONFIG_DRIVE_PUSH_PULL:415		mask = BUFCFG_OD_EN;416		break;417 418	case PIN_CONFIG_DRIVE_OPEN_DRAIN:419		mask = BUFCFG_OD_EN;420		value = BUFCFG_OD_EN;421		break;422 423	case PIN_CONFIG_SLEW_RATE:424		mask = BUFCFG_SLEWSEL;425		if (arg)426			value = BUFCFG_SLEWSEL;427		break;428 429	default:430		return -EINVAL;431	}432 433	guard(raw_spinlock_irqsave)(&tp->lock);434 435	tng_update_bufcfg(tp, pin, value, mask);436 437	return 0;438}439 440static int tng_config_set(struct pinctrl_dev *pctldev, unsigned int pin,441			  unsigned long *configs, unsigned int nconfigs)442{443	struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);444	unsigned int i;445	int ret;446 447	if (!tng_buf_available(tp, pin))448		return -ENOTSUPP;449 450	for (i = 0; i < nconfigs; i++) {451		switch (pinconf_to_config_param(configs[i])) {452		case PIN_CONFIG_BIAS_DISABLE:453		case PIN_CONFIG_BIAS_PULL_UP:454		case PIN_CONFIG_BIAS_PULL_DOWN:455		case PIN_CONFIG_DRIVE_PUSH_PULL:456		case PIN_CONFIG_DRIVE_OPEN_DRAIN:457		case PIN_CONFIG_SLEW_RATE:458			ret = tng_config_set_pin(tp, pin, configs[i]);459			if (ret)460				return ret;461			break;462 463		default:464			return -ENOTSUPP;465		}466	}467 468	return 0;469}470 471static int tng_config_group_get(struct pinctrl_dev *pctldev,472				unsigned int group, unsigned long *config)473{474	const unsigned int *pins;475	unsigned int npins;476	int ret;477 478	ret = tng_get_group_pins(pctldev, group, &pins, &npins);479	if (ret)480		return ret;481 482	return tng_config_get(pctldev, pins[0], config);483}484 485static int tng_config_group_set(struct pinctrl_dev *pctldev,486				unsigned int group, unsigned long *configs,487				unsigned int num_configs)488{489	const unsigned int *pins;490	unsigned int npins;491	int i, ret;492 493	ret = tng_get_group_pins(pctldev, group, &pins, &npins);494	if (ret)495		return ret;496 497	for (i = 0; i < npins; i++) {498		ret = tng_config_set(pctldev, pins[i], configs, num_configs);499		if (ret)500			return ret;501	}502 503	return 0;504}505 506static const struct pinconf_ops tng_pinconf_ops = {507	.is_generic = true,508	.pin_config_get = tng_config_get,509	.pin_config_set = tng_config_set,510	.pin_config_group_get = tng_config_group_get,511	.pin_config_group_set = tng_config_group_set,512};513 514static const struct pinctrl_desc tng_pinctrl_desc = {515	.pctlops = &tng_pinctrl_ops,516	.pmxops = &tng_pinmux_ops,517	.confops = &tng_pinconf_ops,518	.owner = THIS_MODULE,519};520 521static int tng_pinctrl_probe(struct platform_device *pdev,522			     const struct tng_pinctrl *data)523{524	struct device *dev = &pdev->dev;525	struct tng_family *families;526	struct tng_pinctrl *tp;527	size_t families_len;528	void __iomem *regs;529	unsigned int i;530 531	tp = devm_kmemdup(dev, data, sizeof(*data), GFP_KERNEL);532	if (!tp)533		return -ENOMEM;534 535	tp->dev = dev;536	raw_spin_lock_init(&tp->lock);537 538	regs = devm_platform_ioremap_resource(pdev, 0);539	if (IS_ERR(regs))540		return PTR_ERR(regs);541 542	/*543	 * Make a copy of the families which we can use to hold pointers544	 * to the registers.545	 */546	families_len = size_mul(sizeof(*families), tp->nfamilies);547	families = devm_kmemdup(dev, tp->families, families_len, GFP_KERNEL);548	if (!families)549		return -ENOMEM;550 551	/* Splice memory resource by chunk per family */552	for (i = 0; i < tp->nfamilies; i++) {553		struct tng_family *family = &families[i];554 555		family->regs = regs + family->barno * TNG_FAMILY_LEN;556	}557 558	tp->families = families;559	tp->pctldesc = tng_pinctrl_desc;560	tp->pctldesc.name = dev_name(dev);561	tp->pctldesc.pins = tp->pins;562	tp->pctldesc.npins = tp->npins;563 564	tp->pctldev = devm_pinctrl_register(dev, &tp->pctldesc, tp);565	if (IS_ERR(tp->pctldev))566		return dev_err_probe(dev, PTR_ERR(tp->pctldev),567				     "failed to register pinctrl driver\n");568 569	return 0;570}571 572int devm_tng_pinctrl_probe(struct platform_device *pdev)573{574	const struct tng_pinctrl *data;575 576	data = device_get_match_data(&pdev->dev);577	if (!data)578		return -ENODATA;579 580	return tng_pinctrl_probe(pdev, data);581}582EXPORT_SYMBOL_NS_GPL(devm_tng_pinctrl_probe, PINCTRL_TANGIER);583 584MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");585MODULE_AUTHOR("Raag Jadav <raag.jadav@intel.com>");586MODULE_DESCRIPTION("Intel Tangier pinctrl driver");587MODULE_LICENSE("GPL");588