brintos

brintos / linux-shallow public Read only

0
0
Text · 14.3 KiB · 868ea33 Raw
359 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * PEF2256 also known as FALC56 driver4 *5 * Copyright 2023 CS GROUP France6 *7 * Author: Herve Codina <herve.codina@bootlin.com>8 */9 10#include <linux/bitfield.h>11#include <linux/framer/pef2256.h>12#include <linux/module.h>13#include <linux/of.h>14#include <linux/pinctrl/pinctrl.h>15#include <linux/pinctrl/pinconf-generic.h>16#include <linux/pinctrl/pinmux.h>17#include <linux/platform_device.h>18#include <linux/regmap.h>19#include <linux/slab.h>20 21/* Port Configuration 1..4 */22#define PEF2256_PC1		  0x8023#define PEF2256_PC2		  0x8124#define PEF2256_PC3		  0x8225#define PEF2256_PC4		  0x8326#define PEF2256_12_PC_RPC_MASK	  GENMASK(6, 4)27#define PEF2256_12_PC_RPC_SYPR	  FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x0)28#define PEF2256_12_PC_RPC_RFM	  FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x1)29#define PEF2256_12_PC_RPC_RFMB	  FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x2)30#define PEF2256_12_PC_RPC_RSIGM	  FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x3)31#define PEF2256_12_PC_RPC_RSIG	  FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x4)32#define PEF2256_12_PC_RPC_DLR	  FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x5)33#define PEF2256_12_PC_RPC_FREEZE  FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x6)34#define PEF2256_12_PC_RPC_RFSP	  FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x7)35#define PEF2256_12_PC_XPC_MASK    GENMASK(4, 0)36#define PEF2256_12_PC_XPC_SYPX	  FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x0)37#define PEF2256_12_PC_XPC_XFMS	  FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x1)38#define PEF2256_12_PC_XPC_XSIG	  FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x2)39#define PEF2256_12_PC_XPC_TCLK	  FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x3)40#define PEF2256_12_PC_XPC_XMFB	  FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x4)41#define PEF2256_12_PC_XPC_XSIGM	  FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x5)42#define PEF2256_12_PC_XPC_DLX	  FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x6)43#define PEF2256_12_PC_XPC_XCLK	  FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x7)44#define PEF2256_12_PC_XPC_XLT	  FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x8)45#define PEF2256_2X_PC_RPC_MASK	  GENMASK(7, 4)46#define PEF2256_2X_PC_RPC_SYPR	  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x0)47#define PEF2256_2X_PC_RPC_RFM	  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x1)48#define PEF2256_2X_PC_RPC_RFMB	  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x2)49#define PEF2256_2X_PC_RPC_RSIGM	  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x3)50#define PEF2256_2X_PC_RPC_RSIG	  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x4)51#define PEF2256_2X_PC_RPC_DLR	  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x5)52#define PEF2256_2X_PC_RPC_FREEZE  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x6)53#define PEF2256_2X_PC_RPC_RFSP	  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x7)54#define PEF2256_2X_PC_RPC_GPI	  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x9)55#define PEF2256_2X_PC_RPC_GPOH	  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0xa)56#define PEF2256_2X_PC_RPC_GPOL	  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0xb)57#define PEF2256_2X_PC_RPC_LOS	  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0xc)58#define PEF2256_2X_PC_XPC_MASK	  GENMASK(3, 0)59#define PEF2256_2X_PC_XPC_SYPX	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x0)60#define PEF2256_2X_PC_XPC_XFMS	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x1)61#define PEF2256_2X_PC_XPC_XSIG	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x2)62#define PEF2256_2X_PC_XPC_TCLK	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x3)63#define PEF2256_2X_PC_XPC_XMFB	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x4)64#define PEF2256_2X_PC_XPC_XSIGM	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x5)65#define PEF2256_2X_PC_XPC_DLX	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x6)66#define PEF2256_2X_PC_XPC_XCLK	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x7)67#define PEF2256_2X_PC_XPC_XLT	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x8)68#define PEF2256_2X_PC_XPC_GPI	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x9)69#define PEF2256_2X_PC_XPC_GPOH	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0xa)70#define PEF2256_2X_PC_XPC_GPOL	  FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0xb)71 72struct pef2256_pinreg_desc {73	int offset;74	u8 mask;75};76 77struct pef2256_function_desc {78	const char *name;79	const char * const*groups;80	unsigned int ngroups;81	u8 func_val;82};83 84struct pef2256_pinctrl {85	struct device *dev;86	struct regmap *regmap;87	enum pef2256_version version;88	struct pinctrl_desc pctrl_desc;89	const struct pef2256_function_desc *functions;90	unsigned int nfunctions;91};92 93static int pef2256_get_groups_count(struct pinctrl_dev *pctldev)94{95	struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);96 97	/* We map 1 group <-> 1 pin */98	return pef2256->pctrl_desc.npins;99}100 101static const char *pef2256_get_group_name(struct pinctrl_dev *pctldev,102					  unsigned int selector)103{104	struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);105 106	/* We map 1 group <-> 1 pin */107	return pef2256->pctrl_desc.pins[selector].name;108}109 110static int pef2256_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,111				  const unsigned int **pins,112				  unsigned int *num_pins)113{114	struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);115 116	/* We map 1 group <-> 1 pin */117	*pins = &pef2256->pctrl_desc.pins[selector].number;118	*num_pins = 1;119 120	return 0;121}122 123static const struct pinctrl_ops pef2256_pctlops = {124	.get_groups_count	= pef2256_get_groups_count,125	.get_group_name		= pef2256_get_group_name,126	.get_group_pins		= pef2256_get_group_pins,127	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,128	.dt_free_map		= pinconf_generic_dt_free_map,129};130 131static int pef2256_get_functions_count(struct pinctrl_dev *pctldev)132{133	struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);134 135	return pef2256->nfunctions;136}137 138static const char *pef2256_get_function_name(struct pinctrl_dev *pctldev,139					     unsigned int selector)140{141	struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);142 143	return pef2256->functions[selector].name;144}145 146static int pef2256_get_function_groups(struct pinctrl_dev *pctldev, unsigned int selector,147				       const char * const **groups,148				       unsigned * const num_groups)149{150	struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);151 152	*groups = pef2256->functions[selector].groups;153	*num_groups = pef2256->functions[selector].ngroups;154	return 0;155}156 157static int pef2256_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,158			   unsigned int group_selector)159{160	struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);161	const struct pef2256_pinreg_desc *pinreg_desc;162	u8 func_val;163 164	/* We map 1 group <-> 1 pin */165	pinreg_desc = pef2256->pctrl_desc.pins[group_selector].drv_data;166	func_val = pef2256->functions[func_selector].func_val;167 168	return regmap_update_bits(pef2256->regmap, pinreg_desc->offset,169				  pinreg_desc->mask, func_val);170}171 172static const struct pinmux_ops pef2256_pmxops = {173	.get_functions_count	= pef2256_get_functions_count,174	.get_function_name	= pef2256_get_function_name,175	.get_function_groups	= pef2256_get_function_groups,176	.set_mux		= pef2256_set_mux,177};178 179#define PEF2256_PINCTRL_PIN(_number, _name, _offset, _mask) { \180	.number = _number, \181	.name = _name, \182	.drv_data = &(struct pef2256_pinreg_desc) { \183		.offset = _offset, \184		.mask = _mask, \185	}, \186}187 188static const struct pinctrl_pin_desc pef2256_v12_pins[] = {189	PEF2256_PINCTRL_PIN(0, "RPA", PEF2256_PC1, PEF2256_12_PC_RPC_MASK),190	PEF2256_PINCTRL_PIN(1, "RPB", PEF2256_PC2, PEF2256_12_PC_RPC_MASK),191	PEF2256_PINCTRL_PIN(2, "RPC", PEF2256_PC3, PEF2256_12_PC_RPC_MASK),192	PEF2256_PINCTRL_PIN(3, "RPD", PEF2256_PC4, PEF2256_12_PC_RPC_MASK),193	PEF2256_PINCTRL_PIN(4, "XPA", PEF2256_PC1, PEF2256_12_PC_XPC_MASK),194	PEF2256_PINCTRL_PIN(5, "XPB", PEF2256_PC2, PEF2256_12_PC_XPC_MASK),195	PEF2256_PINCTRL_PIN(6, "XPC", PEF2256_PC3, PEF2256_12_PC_XPC_MASK),196	PEF2256_PINCTRL_PIN(7, "XPD", PEF2256_PC4, PEF2256_12_PC_XPC_MASK),197};198 199static const struct pinctrl_pin_desc pef2256_v2x_pins[] = {200	PEF2256_PINCTRL_PIN(0, "RPA", PEF2256_PC1, PEF2256_2X_PC_RPC_MASK),201	PEF2256_PINCTRL_PIN(1, "RPB", PEF2256_PC2, PEF2256_2X_PC_RPC_MASK),202	PEF2256_PINCTRL_PIN(2, "RPC", PEF2256_PC3, PEF2256_2X_PC_RPC_MASK),203	PEF2256_PINCTRL_PIN(3, "RPD", PEF2256_PC4, PEF2256_2X_PC_RPC_MASK),204	PEF2256_PINCTRL_PIN(4, "XPA", PEF2256_PC1, PEF2256_2X_PC_XPC_MASK),205	PEF2256_PINCTRL_PIN(5, "XPB", PEF2256_PC2, PEF2256_2X_PC_XPC_MASK),206	PEF2256_PINCTRL_PIN(6, "XPC", PEF2256_PC3, PEF2256_2X_PC_XPC_MASK),207	PEF2256_PINCTRL_PIN(7, "XPD", PEF2256_PC4, PEF2256_2X_PC_XPC_MASK),208};209 210static const char *const pef2256_rp_groups[] = { "RPA", "RPB", "RPC", "RPD" };211static const char *const pef2256_xp_groups[] = { "XPA", "XPB", "XPC", "XPD" };212static const char *const pef2256_all_groups[] = { "RPA", "RPB", "RPC", "RPD",213						  "XPA", "XPB", "XPC", "XPD" };214 215#define PEF2256_FUNCTION(_name, _func_val, _groups) { \216	.name = _name, \217	.groups = _groups, \218	.ngroups = ARRAY_SIZE(_groups), \219	.func_val = _func_val, \220}221 222static const struct pef2256_function_desc pef2256_v2x_functions[] = {223	PEF2256_FUNCTION("SYPR",   PEF2256_2X_PC_RPC_SYPR,   pef2256_rp_groups),224	PEF2256_FUNCTION("RFM",    PEF2256_2X_PC_RPC_RFM,    pef2256_rp_groups),225	PEF2256_FUNCTION("RFMB",   PEF2256_2X_PC_RPC_RFMB,   pef2256_rp_groups),226	PEF2256_FUNCTION("RSIGM",  PEF2256_2X_PC_RPC_RSIGM,  pef2256_rp_groups),227	PEF2256_FUNCTION("RSIG",   PEF2256_2X_PC_RPC_RSIG,   pef2256_rp_groups),228	PEF2256_FUNCTION("DLR",    PEF2256_2X_PC_RPC_DLR,    pef2256_rp_groups),229	PEF2256_FUNCTION("FREEZE", PEF2256_2X_PC_RPC_FREEZE, pef2256_rp_groups),230	PEF2256_FUNCTION("RFSP",   PEF2256_2X_PC_RPC_RFSP,   pef2256_rp_groups),231	PEF2256_FUNCTION("LOS",    PEF2256_2X_PC_RPC_LOS,    pef2256_rp_groups),232 233	PEF2256_FUNCTION("SYPX",  PEF2256_2X_PC_XPC_SYPX,  pef2256_xp_groups),234	PEF2256_FUNCTION("XFMS",  PEF2256_2X_PC_XPC_XFMS,  pef2256_xp_groups),235	PEF2256_FUNCTION("XSIG",  PEF2256_2X_PC_XPC_XSIG,  pef2256_xp_groups),236	PEF2256_FUNCTION("TCLK",  PEF2256_2X_PC_XPC_TCLK,  pef2256_xp_groups),237	PEF2256_FUNCTION("XMFB",  PEF2256_2X_PC_XPC_XMFB,  pef2256_xp_groups),238	PEF2256_FUNCTION("XSIGM", PEF2256_2X_PC_XPC_XSIGM, pef2256_xp_groups),239	PEF2256_FUNCTION("DLX",   PEF2256_2X_PC_XPC_DLX,   pef2256_xp_groups),240	PEF2256_FUNCTION("XCLK",  PEF2256_2X_PC_XPC_XCLK,  pef2256_xp_groups),241	PEF2256_FUNCTION("XLT",   PEF2256_2X_PC_XPC_XLT,   pef2256_xp_groups),242 243	PEF2256_FUNCTION("GPI",  PEF2256_2X_PC_RPC_GPI | PEF2256_2X_PC_XPC_GPI,244			 pef2256_all_groups),245	PEF2256_FUNCTION("GPOH", PEF2256_2X_PC_RPC_GPOH | PEF2256_2X_PC_XPC_GPOH,246			 pef2256_all_groups),247	PEF2256_FUNCTION("GPOL", PEF2256_2X_PC_RPC_GPOL | PEF2256_2X_PC_XPC_GPOL,248			 pef2256_all_groups),249};250 251static const struct pef2256_function_desc pef2256_v12_functions[] = {252	PEF2256_FUNCTION("SYPR",   PEF2256_12_PC_RPC_SYPR,   pef2256_rp_groups),253	PEF2256_FUNCTION("RFM",    PEF2256_12_PC_RPC_RFM,    pef2256_rp_groups),254	PEF2256_FUNCTION("RFMB",   PEF2256_12_PC_RPC_RFMB,   pef2256_rp_groups),255	PEF2256_FUNCTION("RSIGM",  PEF2256_12_PC_RPC_RSIGM,  pef2256_rp_groups),256	PEF2256_FUNCTION("RSIG",   PEF2256_12_PC_RPC_RSIG,   pef2256_rp_groups),257	PEF2256_FUNCTION("DLR",    PEF2256_12_PC_RPC_DLR,    pef2256_rp_groups),258	PEF2256_FUNCTION("FREEZE", PEF2256_12_PC_RPC_FREEZE, pef2256_rp_groups),259	PEF2256_FUNCTION("RFSP",   PEF2256_12_PC_RPC_RFSP,   pef2256_rp_groups),260 261	PEF2256_FUNCTION("SYPX",  PEF2256_12_PC_XPC_SYPX,  pef2256_xp_groups),262	PEF2256_FUNCTION("XFMS",  PEF2256_12_PC_XPC_XFMS,  pef2256_xp_groups),263	PEF2256_FUNCTION("XSIG",  PEF2256_12_PC_XPC_XSIG,  pef2256_xp_groups),264	PEF2256_FUNCTION("TCLK",  PEF2256_12_PC_XPC_TCLK,  pef2256_xp_groups),265	PEF2256_FUNCTION("XMFB",  PEF2256_12_PC_XPC_XMFB,  pef2256_xp_groups),266	PEF2256_FUNCTION("XSIGM", PEF2256_12_PC_XPC_XSIGM, pef2256_xp_groups),267	PEF2256_FUNCTION("DLX",   PEF2256_12_PC_XPC_DLX,   pef2256_xp_groups),268	PEF2256_FUNCTION("XCLK",  PEF2256_12_PC_XPC_XCLK,  pef2256_xp_groups),269	PEF2256_FUNCTION("XLT",   PEF2256_12_PC_XPC_XLT,   pef2256_xp_groups),270};271 272static int pef2256_register_pinctrl(struct pef2256_pinctrl *pef2256)273{274	struct pinctrl_dev	*pctrl;275 276	pef2256->pctrl_desc.name    = dev_name(pef2256->dev);277	pef2256->pctrl_desc.owner   = THIS_MODULE;278	pef2256->pctrl_desc.pctlops = &pef2256_pctlops;279	pef2256->pctrl_desc.pmxops  = &pef2256_pmxops;280	if (pef2256->version == PEF2256_VERSION_1_2) {281		pef2256->pctrl_desc.pins  = pef2256_v12_pins;282		pef2256->pctrl_desc.npins = ARRAY_SIZE(pef2256_v12_pins);283		pef2256->functions  = pef2256_v12_functions;284		pef2256->nfunctions = ARRAY_SIZE(pef2256_v12_functions);285	} else {286		pef2256->pctrl_desc.pins  = pef2256_v2x_pins;287		pef2256->pctrl_desc.npins = ARRAY_SIZE(pef2256_v2x_pins);288		pef2256->functions  = pef2256_v2x_functions;289		pef2256->nfunctions = ARRAY_SIZE(pef2256_v2x_functions);290	}291 292	pctrl = devm_pinctrl_register(pef2256->dev, &pef2256->pctrl_desc, pef2256);293	if (IS_ERR(pctrl))294		return dev_err_probe(pef2256->dev, PTR_ERR(pctrl),295				     "pinctrl driver registration failed\n");296 297	return 0;298}299 300static void pef2256_reset_pinmux(struct pef2256_pinctrl *pef2256)301{302	u8 val;303	/*304	 * Reset values cannot be used.305	 * They define the SYPR/SYPX pin mux for all the RPx and XPx pins and306	 * Only one pin can be muxed to SYPR and one pin can be muxed to SYPX.307	 * Choose here an other reset value.308	 */309	if (pef2256->version == PEF2256_VERSION_1_2)310		val = PEF2256_12_PC_XPC_XCLK | PEF2256_12_PC_RPC_RFSP;311	else312		val = PEF2256_2X_PC_XPC_GPI | PEF2256_2X_PC_RPC_GPI;313 314	regmap_write(pef2256->regmap, PEF2256_PC1, val);315	regmap_write(pef2256->regmap, PEF2256_PC2, val);316	regmap_write(pef2256->regmap, PEF2256_PC3, val);317	regmap_write(pef2256->regmap, PEF2256_PC4, val);318}319 320static int pef2256_pinctrl_probe(struct platform_device *pdev)321{322	struct pef2256_pinctrl *pef2256_pinctrl;323	struct pef2256 *pef2256;324	int ret;325 326	pef2256_pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pef2256_pinctrl), GFP_KERNEL);327	if (!pef2256_pinctrl)328		return -ENOMEM;329 330	device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent));331 332	pef2256 = dev_get_drvdata(pdev->dev.parent);333 334	pef2256_pinctrl->dev = &pdev->dev;335	pef2256_pinctrl->regmap = pef2256_get_regmap(pef2256);336	pef2256_pinctrl->version = pef2256_get_version(pef2256);337 338	platform_set_drvdata(pdev, pef2256_pinctrl);339 340	pef2256_reset_pinmux(pef2256_pinctrl);341	ret = pef2256_register_pinctrl(pef2256_pinctrl);342	if (ret)343		return ret;344 345	return 0;346}347 348static struct platform_driver pef2256_pinctrl_driver = {349	.driver = {350		.name = "lantiq-pef2256-pinctrl",351	},352	.probe = pef2256_pinctrl_probe,353};354module_platform_driver(pef2256_pinctrl_driver);355 356MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");357MODULE_DESCRIPTION("PEF2256 pin controller driver");358MODULE_LICENSE("GPL");359