Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Pin controller and GPIO driver for Amlogic Meson SoCs
0004  *
0005  * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
0006  */
0007 
0008 #include <linux/gpio/driver.h>
0009 #include <linux/pinctrl/pinctrl.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/regmap.h>
0012 #include <linux/types.h>
0013 #include <linux/module.h>
0014 
0015 struct meson_pinctrl;
0016 
0017 /**
0018  * struct meson_pmx_group - a pinmux group
0019  *
0020  * @name:   group name
0021  * @pins:   pins in the group
0022  * @num_pins:   number of pins in the group
0023  * @is_gpio:    whether the group is a single GPIO group
0024  * @reg:    register offset for the group in the domain mux registers
0025  * @bit     bit index enabling the group
0026  * @domain: index of the domain this group belongs to
0027  */
0028 struct meson_pmx_group {
0029     const char *name;
0030     const unsigned int *pins;
0031     unsigned int num_pins;
0032     const void *data;
0033 };
0034 
0035 /**
0036  * struct meson_pmx_func - a pinmux function
0037  *
0038  * @name:   function name
0039  * @groups: groups in the function
0040  * @num_groups: number of groups in the function
0041  */
0042 struct meson_pmx_func {
0043     const char *name;
0044     const char * const *groups;
0045     unsigned int num_groups;
0046 };
0047 
0048 /**
0049  * struct meson_reg_desc - a register descriptor
0050  *
0051  * @reg:    register offset in the regmap
0052  * @bit:    bit index in register
0053  *
0054  * The structure describes the information needed to control pull,
0055  * pull-enable, direction, etc. for a single pin
0056  */
0057 struct meson_reg_desc {
0058     unsigned int reg;
0059     unsigned int bit;
0060 };
0061 
0062 /**
0063  * enum meson_reg_type - type of registers encoded in @meson_reg_desc
0064  */
0065 enum meson_reg_type {
0066     MESON_REG_PULLEN,
0067     MESON_REG_PULL,
0068     MESON_REG_DIR,
0069     MESON_REG_OUT,
0070     MESON_REG_IN,
0071     MESON_REG_DS,
0072     MESON_NUM_REG,
0073 };
0074 
0075 /**
0076  * enum meson_pinconf_drv - value of drive-strength supported
0077  */
0078 enum meson_pinconf_drv {
0079     MESON_PINCONF_DRV_500UA,
0080     MESON_PINCONF_DRV_2500UA,
0081     MESON_PINCONF_DRV_3000UA,
0082     MESON_PINCONF_DRV_4000UA,
0083 };
0084 
0085 /**
0086  * struct meson bank
0087  *
0088  * @name:   bank name
0089  * @first:  first pin of the bank
0090  * @last:   last pin of the bank
0091  * @irq:    hwirq base number of the bank
0092  * @regs:   array of register descriptors
0093  *
0094  * A bank represents a set of pins controlled by a contiguous set of
0095  * bits in the domain registers. The structure specifies which bits in
0096  * the regmap control the different functionalities. Each member of
0097  * the @regs array refers to the first pin of the bank.
0098  */
0099 struct meson_bank {
0100     const char *name;
0101     unsigned int first;
0102     unsigned int last;
0103     int irq_first;
0104     int irq_last;
0105     struct meson_reg_desc regs[MESON_NUM_REG];
0106 };
0107 
0108 struct meson_pinctrl_data {
0109     const char *name;
0110     const struct pinctrl_pin_desc *pins;
0111     struct meson_pmx_group *groups;
0112     struct meson_pmx_func *funcs;
0113     unsigned int num_pins;
0114     unsigned int num_groups;
0115     unsigned int num_funcs;
0116     struct meson_bank *banks;
0117     unsigned int num_banks;
0118     const struct pinmux_ops *pmx_ops;
0119     void *pmx_data;
0120     int (*parse_dt)(struct meson_pinctrl *pc);
0121 };
0122 
0123 struct meson_pinctrl {
0124     struct device *dev;
0125     struct pinctrl_dev *pcdev;
0126     struct pinctrl_desc desc;
0127     struct meson_pinctrl_data *data;
0128     struct regmap *reg_mux;
0129     struct regmap *reg_pullen;
0130     struct regmap *reg_pull;
0131     struct regmap *reg_gpio;
0132     struct regmap *reg_ds;
0133     struct gpio_chip chip;
0134     struct device_node *of_node;
0135 };
0136 
0137 #define FUNCTION(fn)                            \
0138     {                               \
0139         .name = #fn,                        \
0140         .groups = fn ## _groups,                \
0141         .num_groups = ARRAY_SIZE(fn ## _groups),        \
0142     }
0143 
0144 #define BANK_DS(n, f, l, fi, li, per, peb, pr, pb, dr, db, or, ob, ir, ib,     \
0145         dsr, dsb)                                                      \
0146     {                               \
0147         .name       = n,                    \
0148         .first      = f,                    \
0149         .last       = l,                    \
0150         .irq_first  = fi,                   \
0151         .irq_last   = li,                   \
0152         .regs = {                       \
0153             [MESON_REG_PULLEN]  = { per, peb },     \
0154             [MESON_REG_PULL]    = { pr, pb },       \
0155             [MESON_REG_DIR]     = { dr, db },       \
0156             [MESON_REG_OUT]     = { or, ob },       \
0157             [MESON_REG_IN]      = { ir, ib },       \
0158             [MESON_REG_DS]      = { dsr, dsb },     \
0159         },                          \
0160      }
0161 
0162 #define BANK(n, f, l, fi, li, per, peb, pr, pb, dr, db, or, ob, ir, ib) \
0163     BANK_DS(n, f, l, fi, li, per, peb, pr, pb, dr, db, or, ob, ir, ib, 0, 0)
0164 
0165 #define MESON_PIN(x) PINCTRL_PIN(x, #x)
0166 
0167 /* Common pmx functions */
0168 int meson_pmx_get_funcs_count(struct pinctrl_dev *pcdev);
0169 const char *meson_pmx_get_func_name(struct pinctrl_dev *pcdev,
0170                     unsigned selector);
0171 int meson_pmx_get_groups(struct pinctrl_dev *pcdev,
0172              unsigned selector,
0173              const char * const **groups,
0174              unsigned * const num_groups);
0175 
0176 /* Common probe function */
0177 int meson_pinctrl_probe(struct platform_device *pdev);
0178 /* Common ao groups extra dt parse function for SoCs before g12a  */
0179 int meson8_aobus_parse_dt_extra(struct meson_pinctrl *pc);
0180 /* Common extra dt parse function for SoCs like A1  */
0181 int meson_a1_parse_dt_extra(struct meson_pinctrl *pc);