|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
| 2 | +/* |
| 3 | + * PEF2256 also known as FALC56 driver |
| 4 | + * |
| 5 | + * Copyright 2023 CS GROUP France |
| 6 | + * |
| 7 | + * Author: Herve Codina <[email protected]> |
| 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 0x80 |
| 23 | +#define PEF2256_PC2 0x81 |
| 24 | +#define PEF2256_PC3 0x82 |
| 25 | +#define PEF2256_PC4 0x83 |
| 26 | +#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 | + |
| 72 | +struct pef2256_pinreg_desc { |
| 73 | + int offset; |
| 74 | + u8 mask; |
| 75 | +}; |
| 76 | + |
| 77 | +struct pef2256_function_desc { |
| 78 | + const char *name; |
| 79 | + const char * const*groups; |
| 80 | + unsigned int ngroups; |
| 81 | + u8 func_val; |
| 82 | +}; |
| 83 | + |
| 84 | +struct 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 | + |
| 93 | +static 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 | + |
| 101 | +static 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 | + |
| 110 | +static 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 | + |
| 123 | +static 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 | + |
| 131 | +static 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 | + |
| 138 | +static 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 | + |
| 146 | +static 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 | + |
| 157 | +static 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 | + |
| 172 | +static 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 | + |
| 188 | +static 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 | + |
| 199 | +static 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 | + |
| 210 | +static const char *const pef2256_rp_groups[] = { "RPA", "RPB", "RPC", "RPD" }; |
| 211 | +static const char *const pef2256_xp_groups[] = { "XPA", "XPB", "XPC", "XPD" }; |
| 212 | +static 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 | + |
| 222 | +static 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 | + |
| 251 | +static 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 | + |
| 272 | +static 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 | + |
| 300 | +static 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 and |
| 306 | + * 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 | + else |
| 312 | + 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 | + |
| 320 | +static 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 | + |
| 348 | +static struct platform_driver pef2256_pinctrl_driver = { |
| 349 | + .driver = { |
| 350 | + .name = "lantiq-pef2256-pinctrl", |
| 351 | + }, |
| 352 | + .probe = pef2256_pinctrl_probe, |
| 353 | +}; |
| 354 | +module_platform_driver(pef2256_pinctrl_driver); |
| 355 | + |
| 356 | +MODULE_AUTHOR( "Herve Codina <[email protected]>"); |
| 357 | +MODULE_DESCRIPTION("PEF2256 pin controller driver"); |
| 358 | +MODULE_LICENSE("GPL"); |
0 commit comments