Le 26/07/2023 à 17:02, Herve Codina a écrit :
> The Lantiq PEF2256 is a framer and line interface component designed to
> fulfill all required interfacing between an analog E1/T1/J1 line and the
> digital PCM system highway/H.100 bus.
> 
> This pinmux support handles the pin muxing part (pins RP(A..D) and pins
> XP(A..D)) of the PEF2256.
> 
> Signed-off-by: Herve Codina <herve.cod...@bootlin.com>

Reviewed-by: Christophe Leroy <christophe.le...@csgroup.eu>

> ---
>   drivers/pinctrl/Kconfig                |  14 ++
>   drivers/pinctrl/Makefile               |   1 +
>   drivers/pinctrl/pinctrl-pef2256-regs.h |  65 ++++++
>   drivers/pinctrl/pinctrl-pef2256.c      | 310 +++++++++++++++++++++++++
>   4 files changed, 390 insertions(+)
>   create mode 100644 drivers/pinctrl/pinctrl-pef2256-regs.h
>   create mode 100644 drivers/pinctrl/pinctrl-pef2256.c
> 
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 57d57af1f624..a3aa96b59c97 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -377,6 +377,20 @@ config PINCTRL_PALMAS
>         open drain configuration for the Palmas series devices like
>         TPS65913, TPS80036 etc.
>   
> +config PINCTRL_PEF2256
> +     tristate "Lantiq PEF2256 (FALC56) pin controller driver"
> +     depends on OF && FRAMER_PEF2256
> +     select PINMUX
> +     select GENERIC_PINCONF
> +     help
> +       This option enables the pin controller support for the Lantiq PEF2256
> +       framer, also known as FALC56.
> +
> +       If unsure, say N.
> +
> +       To compile this driver as a module, choose M here: the
> +       module will be called pinctrl-pef2256.
> +
>   config PINCTRL_PIC32
>       bool "Microchip PIC32 pin controller driver"
>       depends on OF
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> index 482b391b5deb..8f211f7671a8 100644
> --- a/drivers/pinctrl/Makefile
> +++ b/drivers/pinctrl/Makefile
> @@ -40,6 +40,7 @@ obj-$(CONFIG_PINCTRL_MLXBF3)        += pinctrl-mlxbf3.o
>   obj-$(CONFIG_PINCTRL_OCELOT)        += pinctrl-ocelot.o
>   obj-$(CONFIG_PINCTRL_OXNAS) += pinctrl-oxnas.o
>   obj-$(CONFIG_PINCTRL_PALMAS)        += pinctrl-palmas.o
> +obj-$(CONFIG_PINCTRL_PEF2256)        += pinctrl-pef2256.o
>   obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
>   obj-$(CONFIG_PINCTRL_PISTACHIO)     += pinctrl-pistachio.o
>   obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
> diff --git a/drivers/pinctrl/pinctrl-pef2256-regs.h 
> b/drivers/pinctrl/pinctrl-pef2256-regs.h
> new file mode 100644
> index 000000000000..586d94007e24
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-pef2256-regs.h
> @@ -0,0 +1,65 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * PEF2256 pinctrl registers definition
> + *
> + * Copyright 2023 CS GROUP France
> + *
> + * Author: Herve Codina <herve.cod...@bootlin.com>
> + */
> +#ifndef __PEF2256_PINCTRL_REGS_H__
> +#define __PEF2256_PINCTRL_REGS_H__
> +
> +#include "linux/bitfield.h"
> +
> +/* Port Configuration 1..4 */
> +#define PEF2256_PC1            0x80
> +#define PEF2256_PC2            0x81
> +#define PEF2256_PC3            0x82
> +#define PEF2256_PC4            0x83
> +#define PEF2256_12_PC_RPC_MASK         GENMASK(6, 4)
> +#define PEF2256_12_PC_RPC_SYPR         
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x0)
> +#define PEF2256_12_PC_RPC_RFM          
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x1)
> +#define PEF2256_12_PC_RPC_RFMB         
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x2)
> +#define PEF2256_12_PC_RPC_RSIGM        
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x3)
> +#define PEF2256_12_PC_RPC_RSIG         
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x4)
> +#define PEF2256_12_PC_RPC_DLR          
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x5)
> +#define PEF2256_12_PC_RPC_FREEZE  FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 
> 0x6)
> +#define PEF2256_12_PC_RPC_RFSP         
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x7)
> +#define PEF2256_12_PC_XPC_MASK    GENMASK(4, 0)
> +#define PEF2256_12_PC_XPC_SYPX         
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x0)
> +#define PEF2256_12_PC_XPC_XFMS         
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x1)
> +#define PEF2256_12_PC_XPC_XSIG         
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x2)
> +#define PEF2256_12_PC_XPC_TCLK         
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x3)
> +#define PEF2256_12_PC_XPC_XMFB         
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x4)
> +#define PEF2256_12_PC_XPC_XSIGM        
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x5)
> +#define PEF2256_12_PC_XPC_DLX          
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x6)
> +#define PEF2256_12_PC_XPC_XCLK         
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x7)
> +#define PEF2256_12_PC_XPC_XLT          
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x8)
> +#define PEF2256_2X_PC_RPC_MASK         GENMASK(7, 4)
> +#define PEF2256_2X_PC_RPC_SYPR         
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x0)
> +#define PEF2256_2X_PC_RPC_RFM          
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x1)
> +#define PEF2256_2X_PC_RPC_RFMB         
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x2)
> +#define PEF2256_2X_PC_RPC_RSIGM        
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x3)
> +#define PEF2256_2X_PC_RPC_RSIG         
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x4)
> +#define PEF2256_2X_PC_RPC_DLR          
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x5)
> +#define PEF2256_2X_PC_RPC_FREEZE  FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 
> 0x6)
> +#define PEF2256_2X_PC_RPC_RFSP         
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x7)
> +#define PEF2256_2X_PC_RPC_GPI          
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x9)
> +#define PEF2256_2X_PC_RPC_GPOH         
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0xa)
> +#define PEF2256_2X_PC_RPC_GPOL         
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0xb)
> +#define PEF2256_2X_PC_RPC_LOS          
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0xc)
> +#define PEF2256_2X_PC_XPC_MASK         GENMASK(3, 0)
> +#define PEF2256_2X_PC_XPC_SYPX         
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x0)
> +#define PEF2256_2X_PC_XPC_XFMS         
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x1)
> +#define PEF2256_2X_PC_XPC_XSIG         
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x2)
> +#define PEF2256_2X_PC_XPC_TCLK         
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x3)
> +#define PEF2256_2X_PC_XPC_XMFB         
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x4)
> +#define PEF2256_2X_PC_XPC_XSIGM        
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x5)
> +#define PEF2256_2X_PC_XPC_DLX          
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x6)
> +#define PEF2256_2X_PC_XPC_XCLK         
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x7)
> +#define PEF2256_2X_PC_XPC_XLT          
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x8)
> +#define PEF2256_2X_PC_XPC_GPI          
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0x9)
> +#define PEF2256_2X_PC_XPC_GPOH         
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0xa)
> +#define PEF2256_2X_PC_XPC_GPOL         
> FIELD_PREP_CONST(PEF2256_2X_PC_XPC_MASK, 0xb)
> +
> +#endif /* __PEF2256_PINCTRL_REGS_H__ */
> diff --git a/drivers/pinctrl/pinctrl-pef2256.c 
> b/drivers/pinctrl/pinctrl-pef2256.c
> new file mode 100644
> index 000000000000..90f611f6cc12
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-pef2256.c
> @@ -0,0 +1,310 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PEF2256 also known as FALC56 driver
> + *
> + * Copyright 2023 CS GROUP France
> + *
> + * Author: Herve Codina <herve.cod...@bootlin.com>
> + */
> +
> +#include <linux/framer/pef2256.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/pinctrl/pinconf-generic.h>
> +#include <linux/pinctrl/pinmux.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include "pinctrl-pef2256-regs.h"
> +
> +struct pef2256_pinreg_desc {
> +     int offset;
> +     u8 mask;
> +};
> +
> +struct pef2256_function_desc {
> +     const char *name;
> +     const char * const*groups;
> +     unsigned int ngroups;
> +     u8 func_val;
> +};
> +
> +struct pef2256_pinctrl {
> +     struct device *dev;
> +     struct regmap *regmap;
> +     enum pef2256_version version;
> +     struct {
> +             struct pinctrl_desc pctrl_desc;
> +             const struct pef2256_function_desc *functions;
> +             unsigned int nfunctions;
> +     } pinctrl;
> +};
> +
> +static int pef2256_get_groups_count(struct pinctrl_dev *pctldev)
> +{
> +     struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);
> +
> +     /* We map 1 group <-> 1 pin */
> +     return pef2256->pinctrl.pctrl_desc.npins;
> +}
> +
> +static const char *pef2256_get_group_name(struct pinctrl_dev *pctldev,
> +                                       unsigned int selector)
> +{
> +     struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);
> +
> +     /* We map 1 group <-> 1 pin */
> +     return pef2256->pinctrl.pctrl_desc.pins[selector].name;
> +}
> +
> +static int pef2256_get_group_pins(struct pinctrl_dev *pctldev, unsigned int 
> selector,
> +                               const unsigned int **pins,
> +                               unsigned int *num_pins)
> +{
> +     struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);
> +
> +     /* We map 1 group <-> 1 pin */
> +     *pins = &pef2256->pinctrl.pctrl_desc.pins[selector].number;
> +     *num_pins = 1;
> +
> +     return 0;
> +}
> +
> +static const struct pinctrl_ops pef2256_pctlops = {
> +     .get_groups_count       = pef2256_get_groups_count,
> +     .get_group_name         = pef2256_get_group_name,
> +     .get_group_pins         = pef2256_get_group_pins,
> +     .dt_node_to_map         = pinconf_generic_dt_node_to_map_pin,
> +     .dt_free_map            = pinconf_generic_dt_free_map,
> +};
> +
> +static int pef2256_get_functions_count(struct pinctrl_dev *pctldev)
> +{
> +     struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);
> +
> +     return pef2256->pinctrl.nfunctions;
> +}
> +
> +static const char *pef2256_get_function_name(struct pinctrl_dev *pctldev,
> +                                          unsigned int selector)
> +{
> +     struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);
> +
> +     return pef2256->pinctrl.functions[selector].name;
> +}
> +
> +static int pef2256_get_function_groups(struct pinctrl_dev *pctldev, unsigned 
> int selector,
> +                                    const char * const **groups,
> +                                    unsigned * const num_groups)
> +{
> +     struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);
> +
> +     *groups = pef2256->pinctrl.functions[selector].groups;
> +     *num_groups = pef2256->pinctrl.functions[selector].ngroups;
> +     return 0;
> +}
> +
> +static int pef2256_set_mux(struct pinctrl_dev *pctldev, unsigned int 
> func_selector,
> +                        unsigned int group_selector)
> +{
> +     struct pef2256_pinctrl *pef2256 = pinctrl_dev_get_drvdata(pctldev);
> +     const struct pef2256_pinreg_desc *pinreg_desc;
> +     u8 func_val;
> +
> +     /* We map 1 group <-> 1 pin */
> +     pinreg_desc = pef2256->pinctrl.pctrl_desc.pins[group_selector].drv_data;
> +     func_val = pef2256->pinctrl.functions[func_selector].func_val;
> +
> +     return regmap_update_bits(pef2256->regmap, pinreg_desc->offset,
> +                               pinreg_desc->mask, func_val);
> +}
> +
> +static const struct pinmux_ops pef2256_pmxops = {
> +     .get_functions_count    = pef2256_get_functions_count,
> +     .get_function_name      = pef2256_get_function_name,
> +     .get_function_groups    = pef2256_get_function_groups,
> +     .set_mux                = pef2256_set_mux,
> +};
> +
> +#define PEF2256_PINCTRL_PIN(_number, _name, _offset, _mask) { \
> +     .number = _number, \
> +     .name = _name, \
> +     .drv_data = &(struct pef2256_pinreg_desc) { \
> +             .offset = _offset, \
> +             .mask = _mask, \
> +     }, \
> +}
> +
> +static const struct pinctrl_pin_desc pef2256_v12_pins[] = {
> +     PEF2256_PINCTRL_PIN(0, "RPA", PEF2256_PC1, PEF2256_12_PC_RPC_MASK),
> +     PEF2256_PINCTRL_PIN(1, "RPB", PEF2256_PC2, PEF2256_12_PC_RPC_MASK),
> +     PEF2256_PINCTRL_PIN(2, "RPC", PEF2256_PC3, PEF2256_12_PC_RPC_MASK),
> +     PEF2256_PINCTRL_PIN(3, "RPD", PEF2256_PC4, PEF2256_12_PC_RPC_MASK),
> +     PEF2256_PINCTRL_PIN(4, "XPA", PEF2256_PC1, PEF2256_12_PC_XPC_MASK),
> +     PEF2256_PINCTRL_PIN(5, "XPB", PEF2256_PC2, PEF2256_12_PC_XPC_MASK),
> +     PEF2256_PINCTRL_PIN(6, "XPC", PEF2256_PC3, PEF2256_12_PC_XPC_MASK),
> +     PEF2256_PINCTRL_PIN(7, "XPD", PEF2256_PC4, PEF2256_12_PC_XPC_MASK),
> +};
> +
> +static const struct pinctrl_pin_desc pef2256_v2x_pins[] = {
> +     PEF2256_PINCTRL_PIN(0, "RPA", PEF2256_PC1, PEF2256_2X_PC_RPC_MASK),
> +     PEF2256_PINCTRL_PIN(1, "RPB", PEF2256_PC2, PEF2256_2X_PC_RPC_MASK),
> +     PEF2256_PINCTRL_PIN(2, "RPC", PEF2256_PC3, PEF2256_2X_PC_RPC_MASK),
> +     PEF2256_PINCTRL_PIN(3, "RPD", PEF2256_PC4, PEF2256_2X_PC_RPC_MASK),
> +     PEF2256_PINCTRL_PIN(4, "XPA", PEF2256_PC1, PEF2256_2X_PC_XPC_MASK),
> +     PEF2256_PINCTRL_PIN(5, "XPB", PEF2256_PC2, PEF2256_2X_PC_XPC_MASK),
> +     PEF2256_PINCTRL_PIN(6, "XPC", PEF2256_PC3, PEF2256_2X_PC_XPC_MASK),
> +     PEF2256_PINCTRL_PIN(7, "XPD", PEF2256_PC4, PEF2256_2X_PC_XPC_MASK),
> +};
> +
> +static const char *const pef2256_rp_groups[] = { "RPA", "RPB", "RPC", "RPD" 
> };
> +static const char *const pef2256_xp_groups[] = { "XPA", "XPB", "XPC", "XPD" 
> };
> +static const char *const pef2256_all_groups[] = { "RPA", "RPB", "RPC", "RPD",
> +                                               "XPA", "XPB", "XPC", "XPD" };
> +
> +#define PEF2256_FUNCTION(_name, _func_val, _groups) { \
> +     .name = _name, \
> +     .groups = _groups, \
> +     .ngroups = ARRAY_SIZE(_groups), \
> +     .func_val = _func_val, \
> +}
> +
> +static const struct pef2256_function_desc pef2256_v2x_functions[] = {
> +     PEF2256_FUNCTION("SYPR",   PEF2256_2X_PC_RPC_SYPR,   pef2256_rp_groups),
> +     PEF2256_FUNCTION("RFM",    PEF2256_2X_PC_RPC_RFM,    pef2256_rp_groups),
> +     PEF2256_FUNCTION("RFMB",   PEF2256_2X_PC_RPC_RFMB,   pef2256_rp_groups),
> +     PEF2256_FUNCTION("RSIGM",  PEF2256_2X_PC_RPC_RSIGM,  pef2256_rp_groups),
> +     PEF2256_FUNCTION("RSIG",   PEF2256_2X_PC_RPC_RSIG,   pef2256_rp_groups),
> +     PEF2256_FUNCTION("DLR",    PEF2256_2X_PC_RPC_DLR,    pef2256_rp_groups),
> +     PEF2256_FUNCTION("FREEZE", PEF2256_2X_PC_RPC_FREEZE, pef2256_rp_groups),
> +     PEF2256_FUNCTION("RFSP",   PEF2256_2X_PC_RPC_RFSP,   pef2256_rp_groups),
> +     PEF2256_FUNCTION("LOS",    PEF2256_2X_PC_RPC_LOS,    pef2256_rp_groups),
> +
> +     PEF2256_FUNCTION("SYPX",  PEF2256_2X_PC_XPC_SYPX,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("XFMS",  PEF2256_2X_PC_XPC_XFMS,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("XSIG",  PEF2256_2X_PC_XPC_XSIG,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("TCLK",  PEF2256_2X_PC_XPC_TCLK,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("XMFB",  PEF2256_2X_PC_XPC_XMFB,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("XSIGM", PEF2256_2X_PC_XPC_XSIGM, pef2256_xp_groups),
> +     PEF2256_FUNCTION("DLX",   PEF2256_2X_PC_XPC_DLX,   pef2256_xp_groups),
> +     PEF2256_FUNCTION("XCLK",  PEF2256_2X_PC_XPC_XCLK,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("XLT",   PEF2256_2X_PC_XPC_XLT,   pef2256_xp_groups),
> +
> +     PEF2256_FUNCTION("GPI",  PEF2256_2X_PC_RPC_GPI | PEF2256_2X_PC_XPC_GPI,
> +                      pef2256_all_groups),
> +     PEF2256_FUNCTION("GPOH", PEF2256_2X_PC_RPC_GPOH | 
> PEF2256_2X_PC_XPC_GPOH,
> +                      pef2256_all_groups),
> +     PEF2256_FUNCTION("GPOL", PEF2256_2X_PC_RPC_GPOL | 
> PEF2256_2X_PC_XPC_GPOL,
> +                      pef2256_all_groups),
> +};
> +
> +static const struct pef2256_function_desc pef2256_v12_functions[] = {
> +     PEF2256_FUNCTION("SYPR",   PEF2256_12_PC_RPC_SYPR,   pef2256_rp_groups),
> +     PEF2256_FUNCTION("RFM",    PEF2256_12_PC_RPC_RFM,    pef2256_rp_groups),
> +     PEF2256_FUNCTION("RFMB",   PEF2256_12_PC_RPC_RFMB,   pef2256_rp_groups),
> +     PEF2256_FUNCTION("RSIGM",  PEF2256_12_PC_RPC_RSIGM,  pef2256_rp_groups),
> +     PEF2256_FUNCTION("RSIG",   PEF2256_12_PC_RPC_RSIG,   pef2256_rp_groups),
> +     PEF2256_FUNCTION("DLR",    PEF2256_12_PC_RPC_DLR,    pef2256_rp_groups),
> +     PEF2256_FUNCTION("FREEZE", PEF2256_12_PC_RPC_FREEZE, pef2256_rp_groups),
> +     PEF2256_FUNCTION("RFSP",   PEF2256_12_PC_RPC_RFSP,   pef2256_rp_groups),
> +
> +     PEF2256_FUNCTION("SYPX",  PEF2256_12_PC_XPC_SYPX,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("XFMS",  PEF2256_12_PC_XPC_XFMS,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("XSIG",  PEF2256_12_PC_XPC_XSIG,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("TCLK",  PEF2256_12_PC_XPC_TCLK,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("XMFB",  PEF2256_12_PC_XPC_XMFB,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("XSIGM", PEF2256_12_PC_XPC_XSIGM, pef2256_xp_groups),
> +     PEF2256_FUNCTION("DLX",   PEF2256_12_PC_XPC_DLX,   pef2256_xp_groups),
> +     PEF2256_FUNCTION("XCLK",  PEF2256_12_PC_XPC_XCLK,  pef2256_xp_groups),
> +     PEF2256_FUNCTION("XLT",   PEF2256_12_PC_XPC_XLT,   pef2256_xp_groups),
> +};
> +
> +static int pef2256_register_pinctrl(struct pef2256_pinctrl *pef2256)
> +{
> +     struct pinctrl_dev      *pctrl;
> +
> +     pef2256->pinctrl.pctrl_desc.name    = dev_name(pef2256->dev);
> +     pef2256->pinctrl.pctrl_desc.owner   = THIS_MODULE;
> +     pef2256->pinctrl.pctrl_desc.pctlops = &pef2256_pctlops;
> +     pef2256->pinctrl.pctrl_desc.pmxops  = &pef2256_pmxops;
> +     if (pef2256->version == PEF2256_VERSION_1_2) {
> +             pef2256->pinctrl.pctrl_desc.pins  = pef2256_v12_pins;
> +             pef2256->pinctrl.pctrl_desc.npins = 
> ARRAY_SIZE(pef2256_v12_pins);
> +             pef2256->pinctrl.functions  = pef2256_v12_functions;
> +             pef2256->pinctrl.nfunctions = ARRAY_SIZE(pef2256_v12_functions);
> +     } else {
> +             pef2256->pinctrl.pctrl_desc.pins  = pef2256_v2x_pins;
> +             pef2256->pinctrl.pctrl_desc.npins = 
> ARRAY_SIZE(pef2256_v2x_pins);
> +             pef2256->pinctrl.functions  = pef2256_v2x_functions;
> +             pef2256->pinctrl.nfunctions = ARRAY_SIZE(pef2256_v2x_functions);
> +     }
> +
> +     pctrl = devm_pinctrl_register(pef2256->dev, 
> &pef2256->pinctrl.pctrl_desc, pef2256);
> +     if (IS_ERR(pctrl)) {
> +             dev_err(pef2256->dev, "pinctrl driver registration failed\n");
> +             return PTR_ERR(pctrl);
> +     }
> +
> +     return 0;
> +}
> +
> +static void pef2256_reset_pinmux(struct pef2256_pinctrl *pef2256)
> +{
> +     u8 val;
> +     /*
> +      * Reset values cannot be used.
> +      * They define the SYPR/SYPX pin mux for all the RPx and XPx pins and
> +      * Only one pin can be muxed to SYPR and one pin can be muxed to SYPX.
> +      * Choose here an other reset value.
> +      */
> +     if (pef2256->version == PEF2256_VERSION_1_2)
> +             val = PEF2256_12_PC_XPC_XCLK | PEF2256_12_PC_RPC_RFSP;
> +     else
> +             val = PEF2256_2X_PC_XPC_GPI | PEF2256_2X_PC_RPC_GPI;
> +
> +     regmap_write(pef2256->regmap, PEF2256_PC1, val);
> +     regmap_write(pef2256->regmap, PEF2256_PC2, val);
> +     regmap_write(pef2256->regmap, PEF2256_PC3, val);
> +     regmap_write(pef2256->regmap, PEF2256_PC4, val);
> +}
> +
> +static int pef2256_pinctrl_probe(struct platform_device *pdev)
> +{
> +     struct pef2256_pinctrl *pef2256_pinctrl;
> +     struct pef2256 *pef2256;
> +     int ret;
> +
> +     pef2256_pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pef2256_pinctrl), 
> GFP_KERNEL);
> +     if (!pef2256_pinctrl)
> +             return -ENOMEM;
> +
> +     device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent));
> +
> +     pef2256 = dev_get_drvdata(pdev->dev.parent);
> +
> +     pef2256_pinctrl->dev = &pdev->dev;
> +     pef2256_pinctrl->regmap = pef2256_get_regmap(pef2256);
> +     pef2256_pinctrl->version = pef2256_get_version(pef2256);
> +
> +     platform_set_drvdata(pdev, pef2256_pinctrl);
> +
> +     pef2256_reset_pinmux(pef2256_pinctrl);
> +     ret = pef2256_register_pinctrl(pef2256_pinctrl);
> +     if (ret)
> +             return ret;
> +
> +     return 0;
> +}
> +
> +static struct platform_driver pef2256_pinctrl_driver = {
> +     .driver = {
> +             .name = "lantiq-pef2256-pinctrl",
> +     },
> +     .probe = pef2256_pinctrl_probe,
> +};
> +module_platform_driver(pef2256_pinctrl_driver);
> +
> +MODULE_AUTHOR("Herve Codina <herve.cod...@bootlin.com>");
> +MODULE_DESCRIPTION("PEF2256 pin controller driver");
> +MODULE_LICENSE("GPL");

Reply via email to