uboot/drivers/pinctrl/broadcom/pinctrl-bcm6838.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2
   3#include <common.h>
   4#include <dm.h>
   5#include <regmap.h>
   6#include <syscon.h>
   7#include <dm/device_compat.h>
   8#include <dm/pinctrl.h>
   9
  10#define BCM6838_CMD_LOAD_MUX            0x21
  11
  12#define BCM6838_FUNC_OFFS               12
  13#define BCM6838_FUNC_MASK               (0x37 << BCM6838_FUNC_OFFS)
  14#define BCM6838_PIN_OFFS                 0
  15#define BCM6838_PIN_MASK                (0xfff << BCM6838_PIN_OFFS)
  16
  17#define BCM6838_MAX_PIN_NAME_LEN         8
  18static char bcm6838_pin_name[BCM6838_MAX_PIN_NAME_LEN];
  19
  20#define BCM6838_MAX_FUNC_NAME_LEN        8
  21static char bcm6838_func_name[BCM6838_MAX_FUNC_NAME_LEN];
  22
  23struct bcm6838_test_port_hw {
  24        unsigned long port_blk_data1;
  25        unsigned long port_blk_data2;
  26        unsigned long port_command;
  27};
  28
  29static const struct bcm6838_test_port_hw bcm6838_hw = {
  30        .port_blk_data1 = 0x10,
  31        .port_blk_data2 = 0x14,
  32        .port_command   = 0x18
  33};
  34
  35struct bcm6838_pinctrl_priv {
  36        const struct bcm6838_test_port_hw *hw;
  37        struct regmap *regmap;
  38        u32 pins_count;
  39        u32 functions_count;
  40};
  41
  42int bcm6838_pinctrl_get_pins_count(struct udevice *dev)
  43{
  44        struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev);
  45
  46        return priv->pins_count;
  47}
  48
  49const char *bcm6838_pinctrl_get_pin_name(struct udevice *dev,
  50                                         unsigned int selector)
  51{
  52        snprintf(bcm6838_pin_name, BCM6838_MAX_PIN_NAME_LEN, "%u", selector);
  53        return bcm6838_pin_name;
  54}
  55
  56int bcm6838_pinctrl_get_functions_count(struct udevice *dev)
  57{
  58        struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev);
  59
  60        return priv->functions_count;
  61}
  62
  63const char *bcm6838_pinctrl_get_function_name(struct udevice *dev,
  64                                              unsigned int selector)
  65{
  66        snprintf(bcm6838_func_name, BCM6838_MAX_FUNC_NAME_LEN, "%u", selector);
  67        return bcm6838_func_name;
  68}
  69
  70int bcm6838_pinctrl_pinmux_set(struct udevice *dev,
  71                               unsigned int pin_selector,
  72                               unsigned int func_selector)
  73{
  74        struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev);
  75        const struct bcm6838_test_port_hw *hw = priv->hw;
  76        unsigned int data;
  77
  78        regmap_write(priv->regmap, hw->port_blk_data1, 0);
  79        data = (func_selector << BCM6838_FUNC_OFFS) & BCM6838_FUNC_MASK;
  80        data |= (pin_selector << BCM6838_PIN_OFFS) & BCM6838_PIN_MASK;
  81        regmap_write(priv->regmap, hw->port_blk_data2, data);
  82        regmap_write(priv->regmap, hw->port_command, BCM6838_CMD_LOAD_MUX);
  83
  84        return 0;
  85}
  86
  87int bcm6838_pinctrl_probe(struct udevice *dev)
  88{
  89        struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev);
  90        const struct bcm6838_test_port_hw *hw =
  91                (const struct bcm6838_test_port_hw *)dev_get_driver_data(dev);
  92        int err;
  93        u32 phandle;
  94        ofnode node;
  95
  96        err = ofnode_read_u32(dev_ofnode(dev), "regmap", &phandle);
  97        if (err) {
  98                dev_err(dev, "%s: unable to read regmap\n", __func__);
  99                goto out;
 100        }
 101
 102        node = ofnode_get_by_phandle(phandle);
 103        if (!ofnode_valid(node)) {
 104                dev_err(dev, "%s: unable to find node\n", __func__);
 105                err = -EINVAL;
 106                goto out;
 107        }
 108
 109        priv->regmap = syscon_node_to_regmap(node);
 110        if (!priv->regmap) {
 111                dev_err(dev, "%s: unable to find regmap\n", __func__);
 112                err = -ENODEV;
 113                goto out;
 114        }
 115
 116        err = ofnode_read_u32(dev_ofnode(dev), "brcm,pins-count",
 117                              &priv->pins_count);
 118        if (err) {
 119                dev_err(dev, "%s: unable to read brcm,pins-count\n",
 120                        __func__);
 121                goto out;
 122        }
 123
 124        err = ofnode_read_u32(dev_ofnode(dev), "brcm,functions-count",
 125                              &priv->functions_count);
 126        if (err) {
 127                dev_err(dev, "%s: unable to read brcm,functions-count\n",
 128                        __func__);
 129                goto out;
 130        }
 131
 132        priv->hw = hw;
 133
 134 out:
 135        return err;
 136}
 137
 138const struct pinctrl_ops bcm6838_pinctrl_ops = {
 139        .set_state = pinctrl_generic_set_state,
 140        .get_pins_count = bcm6838_pinctrl_get_pins_count,
 141        .get_pin_name = bcm6838_pinctrl_get_pin_name,
 142        .get_functions_count = bcm6838_pinctrl_get_functions_count,
 143        .get_function_name = bcm6838_pinctrl_get_function_name,
 144        .pinmux_set = bcm6838_pinctrl_pinmux_set,
 145};
 146
 147static const struct udevice_id bcm6838_pinctrl_match[] = {
 148        {
 149                .compatible = "brcm,bcm6838-pinctrl",
 150                .data = (ulong)&bcm6838_hw,
 151        },
 152        { /* sentinel */ }
 153};
 154
 155U_BOOT_DRIVER(bcm6838_pinctrl) = {
 156        .name = "bcm6838_pinctrl",
 157        .id = UCLASS_PINCTRL,
 158        .of_match = bcm6838_pinctrl_match,
 159        .ops = &bcm6838_pinctrl_ops,
 160        .priv_auto_alloc_size = sizeof(struct bcm6838_pinctrl_priv),
 161        .probe = bcm6838_pinctrl_probe,
 162};
 163