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