uboot/arch/arm/mach-snapdragon/pinctrl-snapdragon.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * TLMM driver for Qualcomm APQ8016, APQ8096
   4 *
   5 * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
   6 *
   7 */
   8
   9#include <common.h>
  10#include <dm.h>
  11#include <errno.h>
  12#include <asm/io.h>
  13#include <dm/pinctrl.h>
  14#include <linux/bitops.h>
  15#include "pinctrl-snapdragon.h"
  16
  17struct msm_pinctrl_priv {
  18        phys_addr_t base;
  19        struct msm_pinctrl_data *data;
  20};
  21
  22#define GPIO_CONFIG_OFFSET(x)         ((x) * 0x1000)
  23#define TLMM_GPIO_PULL_MASK GENMASK(1, 0)
  24#define TLMM_FUNC_SEL_MASK GENMASK(5, 2)
  25#define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6)
  26#define TLMM_GPIO_DISABLE BIT(9)
  27
  28static const struct pinconf_param msm_conf_params[] = {
  29        { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 3 },
  30        { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
  31};
  32
  33static int msm_get_functions_count(struct udevice *dev)
  34{
  35        struct msm_pinctrl_priv *priv = dev_get_priv(dev);
  36
  37        return priv->data->functions_count;
  38}
  39
  40static int msm_get_pins_count(struct udevice *dev)
  41{
  42        struct msm_pinctrl_priv *priv = dev_get_priv(dev);
  43
  44        return priv->data->pin_count;
  45}
  46
  47static const char *msm_get_function_name(struct udevice *dev,
  48                                         unsigned int selector)
  49{
  50        struct msm_pinctrl_priv *priv = dev_get_priv(dev);
  51
  52        return priv->data->get_function_name(dev, selector);
  53}
  54
  55static int msm_pinctrl_probe(struct udevice *dev)
  56{
  57        struct msm_pinctrl_priv *priv = dev_get_priv(dev);
  58
  59        priv->base = dev_read_addr(dev);
  60        priv->data = (struct msm_pinctrl_data *)dev->driver_data;
  61
  62        return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
  63}
  64
  65static const char *msm_get_pin_name(struct udevice *dev, unsigned int selector)
  66{
  67        struct msm_pinctrl_priv *priv = dev_get_priv(dev);
  68
  69        return priv->data->get_pin_name(dev, selector);
  70}
  71
  72static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
  73                          unsigned int func_selector)
  74{
  75        struct msm_pinctrl_priv *priv = dev_get_priv(dev);
  76
  77        clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
  78                        TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
  79                        priv->data->get_function_mux(func_selector) << 2);
  80        return 0;
  81}
  82
  83static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
  84                           unsigned int param, unsigned int argument)
  85{
  86        struct msm_pinctrl_priv *priv = dev_get_priv(dev);
  87
  88        switch (param) {
  89        case PIN_CONFIG_DRIVE_STRENGTH:
  90                clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
  91                                TLMM_DRV_STRENGTH_MASK, argument << 6);
  92                break;
  93        case PIN_CONFIG_BIAS_DISABLE:
  94                clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
  95                             TLMM_GPIO_PULL_MASK);
  96                break;
  97        default:
  98                return 0;
  99        }
 100
 101        return 0;
 102}
 103
 104static struct pinctrl_ops msm_pinctrl_ops = {
 105        .get_pins_count = msm_get_pins_count,
 106        .get_pin_name = msm_get_pin_name,
 107        .set_state = pinctrl_generic_set_state,
 108        .pinmux_set = msm_pinmux_set,
 109        .pinconf_num_params = ARRAY_SIZE(msm_conf_params),
 110        .pinconf_params = msm_conf_params,
 111        .pinconf_set = msm_pinconf_set,
 112        .get_functions_count = msm_get_functions_count,
 113        .get_function_name = msm_get_function_name,
 114};
 115
 116static const struct udevice_id msm_pinctrl_ids[] = {
 117        { .compatible = "qcom,tlmm-apq8016", .data = (ulong)&apq8016_data },
 118        { .compatible = "qcom,tlmm-apq8096", .data = (ulong)&apq8096_data },
 119#ifdef CONFIG_SDM845
 120        { .compatible = "qcom,tlmm-sdm845", .data = (ulong)&sdm845_data },
 121#endif
 122        { }
 123};
 124
 125U_BOOT_DRIVER(pinctrl_snapdraon) = {
 126        .name           = "pinctrl_msm",
 127        .id             = UCLASS_PINCTRL,
 128        .of_match       = msm_pinctrl_ids,
 129        .priv_auto      = sizeof(struct msm_pinctrl_priv),
 130        .ops            = &msm_pinctrl_ops,
 131        .probe          = msm_pinctrl_probe,
 132};
 133