linux/drivers/pinctrl/nomadik/pinctrl-nomadik.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Pinmux & pinconf driver for the IP block found in the Nomadik SoC. This
 * depends on gpio-nomadik and some handling is intertwined; see nmk_gpio_chips
 * which is used by this driver to access the GPIO banks array.
 *
 * Copyright (C) 2008,2009 STMicroelectronics
 * Copyright (C) 2009 Alessandro Rubini <[email protected]>
 *   Rewritten based on work by Prafulla WADASKAR <[email protected]>
 * Copyright (C) 2011-2013 Linus Walleij <[email protected]>
 */

#include <linux/bitops.h>
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/types.h>

/* Since we request GPIOs from ourself */
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>

#include "../core.h"
#include "../pinctrl-utils.h"

#include <linux/gpio/gpio-nomadik.h>

/*
 * pin configurations are represented by 32-bit integers:
 *
 *	bit  0.. 8 - Pin Number (512 Pins Maximum)
 *	bit  9..10 - Alternate Function Selection
 *	bit 11..12 - Pull up/down state
 *	bit     13 - Sleep mode behaviour
 *	bit     14 - Direction
 *	bit     15 - Value (if output)
 *	bit 16..18 - SLPM pull up/down state
 *	bit 19..20 - SLPM direction
 *	bit 21..22 - SLPM Value (if output)
 *	bit 23..25 - PDIS value (if input)
 *	bit	26 - Gpio mode
 *	bit	27 - Sleep mode
 *
 * to facilitate the definition, the following macros are provided
 *
 * PIN_CFG_DEFAULT - default config (0):
 *		     pull up/down = disabled
 *		     sleep mode = input/wakeup
 *		     direction = input
 *		     value = low
 *		     SLPM direction = same as normal
 *		     SLPM pull = same as normal
 *		     SLPM value = same as normal
 *
 * PIN_CFG	   - default config with alternate function
 */

#define PIN_NUM_MASK
#define PIN_NUM(x)

#define PIN_ALT_SHIFT
#define PIN_ALT_MASK
#define PIN_ALT(x)
#define PIN_GPIO
#define PIN_ALT_A
#define PIN_ALT_B
#define PIN_ALT_C

#define PIN_PULL_SHIFT
#define PIN_PULL_MASK
#define PIN_PULL(x)
#define PIN_PULL_NONE
#define PIN_PULL_UP
#define PIN_PULL_DOWN

#define PIN_SLPM_SHIFT
#define PIN_SLPM_MASK
#define PIN_SLPM(x)
#define PIN_SLPM_MAKE_INPUT
#define PIN_SLPM_NOCHANGE
/* These two replace the above in DB8500v2+ */
#define PIN_SLPM_WAKEUP_ENABLE
#define PIN_SLPM_WAKEUP_DISABLE
#define PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP

#define PIN_SLPM_GPIO
#define PIN_SLPM_ALTFUNC

#define PIN_DIR_SHIFT
#define PIN_DIR_MASK
#define PIN_DIR(x)
#define PIN_DIR_INPUT
#define PIN_DIR_OUTPUT

#define PIN_VAL_SHIFT
#define PIN_VAL_MASK
#define PIN_VAL(x)
#define PIN_VAL_LOW
#define PIN_VAL_HIGH

#define PIN_SLPM_PULL_SHIFT
#define PIN_SLPM_PULL_MASK
#define PIN_SLPM_PULL(x)
#define PIN_SLPM_PULL_NONE
#define PIN_SLPM_PULL_UP
#define PIN_SLPM_PULL_DOWN

#define PIN_SLPM_DIR_SHIFT
#define PIN_SLPM_DIR_MASK
#define PIN_SLPM_DIR(x)
#define PIN_SLPM_DIR_INPUT
#define PIN_SLPM_DIR_OUTPUT

#define PIN_SLPM_VAL_SHIFT
#define PIN_SLPM_VAL_MASK
#define PIN_SLPM_VAL(x)
#define PIN_SLPM_VAL_LOW
#define PIN_SLPM_VAL_HIGH

#define PIN_SLPM_PDIS_SHIFT
#define PIN_SLPM_PDIS_MASK
#define PIN_SLPM_PDIS(x)
#define PIN_SLPM_PDIS_NO_CHANGE
#define PIN_SLPM_PDIS_DISABLED
#define PIN_SLPM_PDIS_ENABLED

#define PIN_LOWEMI_SHIFT
#define PIN_LOWEMI_MASK
#define PIN_LOWEMI(x)
#define PIN_LOWEMI_DISABLED
#define PIN_LOWEMI_ENABLED

#define PIN_GPIOMODE_SHIFT
#define PIN_GPIOMODE_MASK
#define PIN_GPIOMODE(x)
#define PIN_GPIOMODE_DISABLED
#define PIN_GPIOMODE_ENABLED

#define PIN_SLEEPMODE_SHIFT
#define PIN_SLEEPMODE_MASK
#define PIN_SLEEPMODE(x)
#define PIN_SLEEPMODE_DISABLED
#define PIN_SLEEPMODE_ENABLED

/* Shortcuts.  Use these instead of separate DIR, PULL, and VAL.  */
#define PIN_INPUT_PULLDOWN
#define PIN_INPUT_PULLUP
#define PIN_INPUT_NOPULL
#define PIN_OUTPUT_LOW
#define PIN_OUTPUT_HIGH

#define PIN_SLPM_INPUT_PULLDOWN
#define PIN_SLPM_INPUT_PULLUP
#define PIN_SLPM_INPUT_NOPULL
#define PIN_SLPM_OUTPUT_LOW
#define PIN_SLPM_OUTPUT_HIGH

#define PIN_CFG_DEFAULT

#define PIN_CFG(num, alt)

#define PIN_CFG_INPUT(num, alt, pull)

#define PIN_CFG_OUTPUT(num, alt, val)

/**
 * struct nmk_pinctrl - state container for the Nomadik pin controller
 * @dev: containing device pointer
 * @pctl: corresponding pin controller device
 * @soc: SoC data for this specific chip
 * @prcm_base: PRCM register range virtual base
 */
struct nmk_pinctrl {};

/* See nmk_gpio_populate_chip() that fills this array. */
struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];

DEFINE_SPINLOCK();

static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
				unsigned int offset, int gpio_mode)
{}

static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
				unsigned int offset, enum nmk_gpio_pull pull)
{}

static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip,
				  unsigned int offset, bool lowemi)
{}

static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
				  unsigned int offset)
{}

static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
				     unsigned int offset, int gpio_mode,
				     bool glitch)
{}

static void
nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned int offset)
{}

static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value)
{}

static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
				    unsigned int offset, unsigned int alt_num)
{}

/*
 * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
 *  - Save SLPM registers
 *  - Set SLPM=0 for the IOs you want to switch and others to 1
 *  - Configure the GPIO registers for the IOs that are being switched
 *  - Set IOFORCE=1
 *  - Modify the AFLSA/B registers for the IOs that are being switched
 *  - Set IOFORCE=0
 *  - Restore SLPM registers
 *  - Any spurious wake up event during switch sequence to be ignored and
 *    cleared
 */
static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
{}

static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
{}

/* Only called by gpio-nomadik but requires knowledge of struct nmk_pinctrl. */
int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
{}

static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
{}

static const char *nmk_get_group_name(struct pinctrl_dev *pctldev,
				      unsigned int selector)
{}

static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
			      const unsigned int **pins,
			      unsigned int *num_pins)
{}

/* This makes the mapping from pin number to a GPIO chip. We also return the pin
 * offset in the GPIO chip for convenience (and to avoid a second loop).
 */
static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned int pin,
						    unsigned int *offset)
{}

static struct gpio_chip *find_gc_from_pin(unsigned int pin)
{}

static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
			     unsigned int offset)
{}

static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned int *reserved_maps,
			      unsigned int *num_maps, const char *group,
			      const char *function)
{}

static int nmk_dt_add_map_configs(struct pinctrl_map **map,
				  unsigned int *reserved_maps,
				  unsigned int *num_maps, const char *group,
				  unsigned long *configs, unsigned int num_configs)
{}

#define NMK_CONFIG_PIN(x, y)
#define NMK_CONFIG_PIN_ARRAY(x, y)

static const unsigned long nmk_pin_input_modes[] =;

static const unsigned long nmk_pin_output_modes[] =;

static const unsigned long nmk_pin_sleep_modes[] =;

static const unsigned long nmk_pin_sleep_input_modes[] =;

static const unsigned long nmk_pin_sleep_output_modes[] =;

static const unsigned long nmk_pin_sleep_wakeup_modes[] =;

static const unsigned long nmk_pin_gpio_modes[] =;

static const unsigned long nmk_pin_sleep_pdis_modes[] =;

struct nmk_cfg_param {};

static const struct nmk_cfg_param nmk_cfg_params[] =;

static int nmk_dt_pin_config(int index, int val, unsigned long *config)
{}

static const char *nmk_find_pin_name(struct pinctrl_dev *pctldev, const char *pin_name)
{}

static bool nmk_pinctrl_dt_get_config(struct device_node *np,
				      unsigned long *configs)
{}

static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
					 struct device_node *np,
					 struct pinctrl_map **map,
					 unsigned int *reserved_maps,
					 unsigned int *num_maps)
{}

static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
				      struct device_node *np_config,
				      struct pinctrl_map **map,
				      unsigned int *num_maps)
{}

static const struct pinctrl_ops nmk_pinctrl_ops =;

static int nmk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
{}

static const char *nmk_pmx_get_func_name(struct pinctrl_dev *pctldev,
					 unsigned int function)
{}

static int nmk_pmx_get_func_groups(struct pinctrl_dev *pctldev,
				   unsigned int function,
				   const char * const **groups,
				   unsigned * const num_groups)
{}

static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
		       unsigned int group)
{}

static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
				   struct pinctrl_gpio_range *range,
				   unsigned int pin)
{}

static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev,
				  struct pinctrl_gpio_range *range,
				  unsigned int pin)
{}

static const struct pinmux_ops nmk_pinmux_ops =;

static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
			      unsigned long *config)
{}

static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
			      unsigned long *configs, unsigned int num_configs)
{}

static const struct pinconf_ops nmk_pinconf_ops =;

static struct pinctrl_desc nmk_pinctrl_desc =;

static const struct of_device_id nmk_pinctrl_match[] =;

#ifdef CONFIG_PM_SLEEP
static int nmk_pinctrl_suspend(struct device *dev)
{}

static int nmk_pinctrl_resume(struct device *dev)
{}
#endif

static int nmk_pinctrl_probe(struct platform_device *pdev)
{}

static SIMPLE_DEV_PM_OPS(nmk_pinctrl_pm_ops,
			nmk_pinctrl_suspend,
			nmk_pinctrl_resume);

static struct platform_driver nmk_pinctrl_driver =;

static int __init nmk_pinctrl_init(void)
{}
core_initcall(nmk_pinctrl_init);