linux/drivers/pinctrl/samsung/pinctrl-samsung.c

// SPDX-License-Identifier: GPL-2.0+
//
// pin-controller/pin-mux/pin-config/gpio-driver for Samsung's SoC's.
//
// Copyright (c) 2012 Samsung Electronics Co., Ltd.
//		http://www.samsung.com
// Copyright (c) 2012 Linaro Ltd
//		http://www.linaro.org
//
// Author: Thomas Abraham <[email protected]>
//
// This driver implements the Samsung pinctrl driver. It supports setting up of
// pinmux and pinconf configurations. The gpiolib interface is also included.
// External interrupt (gpio and wakeup) support are not included in this driver
// but provides extensions to which platform specific implementation of the gpio
// and wakeup interrupts can be hooked to.

#include <linux/clk.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

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

/* maximum number of the memory resources */
#define SAMSUNG_PINCTRL_NUM_RESOURCES

/* list of all possible config options supported */
static struct pin_config {} cfg_params[] =;

static int samsung_get_group_count(struct pinctrl_dev *pctldev)
{}

static const char *samsung_get_group_name(struct pinctrl_dev *pctldev,
						unsigned group)
{}

static int samsung_get_group_pins(struct pinctrl_dev *pctldev,
					unsigned group,
					const unsigned **pins,
					unsigned *num_pins)
{}

static int reserve_map(struct device *dev, struct pinctrl_map **map,
		       unsigned *reserved_maps, unsigned *num_maps,
		       unsigned reserve)
{}

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

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

static int add_config(struct device *dev, unsigned long **configs,
		      unsigned *num_configs, unsigned long config)
{}

static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
				      struct pinctrl_map *map,
				      unsigned num_maps)
{}

static int samsung_dt_subnode_to_map(struct samsung_pinctrl_drv_data *drvdata,
				     struct device *dev,
				     struct device_node *np,
				     struct pinctrl_map **map,
				     unsigned *reserved_maps,
				     unsigned *num_maps)
{}

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

#ifdef CONFIG_DEBUG_FS
/* Forward declaration which can be used by samsung_pin_dbg_show */
static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
					unsigned long *config);
static const char * const reg_names[] =;

static void samsung_pin_dbg_show(struct pinctrl_dev *pctldev,
				struct seq_file *s, unsigned int pin)
{}
#endif

/* list of pinctrl callbacks for the pinctrl core */
static const struct pinctrl_ops samsung_pctrl_ops =;

/* check if the selector is a valid pin function selector */
static int samsung_get_functions_count(struct pinctrl_dev *pctldev)
{}

/* return the name of the pin function specified */
static const char *samsung_pinmux_get_fname(struct pinctrl_dev *pctldev,
						unsigned selector)
{}

/* return the groups associated for the specified function selector */
static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev,
		unsigned selector, const char * const **groups,
		unsigned * const num_groups)
{}

/*
 * given a pin number that is local to a pin controller, find out the pin bank
 * and the register base of the pin bank.
 */
static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
			unsigned pin, void __iomem **reg, u32 *offset,
			struct samsung_pin_bank **bank)
{}

/* enable or disable a pinmux function */
static int samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
				unsigned group)
{}

/* enable a specified pinmux by writing to registers */
static int samsung_pinmux_set_mux(struct pinctrl_dev *pctldev,
				  unsigned selector,
				  unsigned group)
{}

/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
static const struct pinmux_ops samsung_pinmux_ops =;

/* set or get the pin config settings for a specified pin */
static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
				unsigned long *config, bool set)
{}

/* set the pin config settings for a specified pin */
static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
				unsigned long *configs, unsigned num_configs)
{}

/* get the pin config settings for a specified pin */
static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
					unsigned long *config)
{}

/* set the pin config settings for a specified pin group */
static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
			unsigned group, unsigned long *configs,
			unsigned num_configs)
{}

/* get the pin config settings for a specified pin group */
static int samsung_pinconf_group_get(struct pinctrl_dev *pctldev,
				unsigned int group, unsigned long *config)
{}

/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
static const struct pinconf_ops samsung_pinconf_ops =;

/*
 * The samsung_gpio_set_vlaue() should be called with "bank->slock" held
 * to avoid race condition.
 */
static void samsung_gpio_set_value(struct gpio_chip *gc,
					  unsigned offset, int value)
{}

/* gpiolib gpio_set callback function */
static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
{}

/* gpiolib gpio_get callback function */
static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
{}

/*
 * The samsung_gpio_set_direction() should be called with "bank->slock" held
 * to avoid race condition.
 * The calls to gpio_direction_output() and gpio_direction_input()
 * leads to this function call.
 */
static int samsung_gpio_set_direction(struct gpio_chip *gc,
					     unsigned offset, bool input)
{}

/* gpiolib gpio_direction_input callback function. */
static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
{}

/* gpiolib gpio_direction_output callback function. */
static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
							int value)
{}

/*
 * gpiod_to_irq() callback function. Creates a mapping between a GPIO pin
 * and a virtual IRQ, if not already present.
 */
static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
{}

static int samsung_add_pin_ranges(struct gpio_chip *gc)
{}

static struct samsung_pin_group *samsung_pinctrl_create_groups(
				struct device *dev,
				struct samsung_pinctrl_drv_data *drvdata,
				unsigned int *cnt)
{}

static int samsung_pinctrl_create_function(struct device *dev,
				struct samsung_pinctrl_drv_data *drvdata,
				struct device_node *func_np,
				struct samsung_pmx_func *func)
{}

static struct samsung_pmx_func *samsung_pinctrl_create_functions(
				struct device *dev,
				struct samsung_pinctrl_drv_data *drvdata,
				unsigned int *cnt)
{}

/*
 * Parse the information about all the available pin groups and pin functions
 * from device node of the pin-controller. A pin group is formed with all
 * the pins listed in the "samsung,pins" property.
 */

static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
				    struct samsung_pinctrl_drv_data *drvdata)
{}

/* register the pinctrl interface with the pinctrl subsystem */
static int samsung_pinctrl_register(struct platform_device *pdev,
				    struct samsung_pinctrl_drv_data *drvdata)
{}

/* unregister the pinctrl interface with the pinctrl subsystem */
static int samsung_pinctrl_unregister(struct platform_device *pdev,
				      struct samsung_pinctrl_drv_data *drvdata)
{}

static void samsung_pud_value_init(struct samsung_pinctrl_drv_data *drvdata)
{}

/*
 * Enable or Disable the pull-down and pull-up for the gpio pins in the
 * PUD register.
 */
static void samsung_gpio_set_pud(struct gpio_chip *gc, unsigned int offset,
				 unsigned int value)
{}

/*
 * Identify the type of PUD config based on the gpiolib request to enable
 * or disable the PUD config.
 */
static int samsung_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
				   unsigned long config)
{}

static const struct gpio_chip samsung_gpiolib_chip =;

/* register the gpiolib interface with the gpiolib subsystem */
static int samsung_gpiolib_register(struct platform_device *pdev,
				    struct samsung_pinctrl_drv_data *drvdata)
{}

static const struct samsung_pin_ctrl *
samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev)
{}

static void samsung_banks_node_put(struct samsung_pinctrl_drv_data *d)
{}

/*
 * Iterate over all driver pin banks to find one matching the name of node,
 * skipping optional "-gpio" node suffix. When found, assign node to the bank.
 */
static void samsung_banks_node_get(struct device *dev, struct samsung_pinctrl_drv_data *d)
{}

/* retrieve the soc specific data */
static const struct samsung_pin_ctrl *
samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
			     struct platform_device *pdev)
{}

static int samsung_pinctrl_probe(struct platform_device *pdev)
{}

/*
 * samsung_pinctrl_suspend - save pinctrl state for suspend
 *
 * Save data for all banks handled by this device.
 */
static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
{}

/*
 * samsung_pinctrl_resume - restore pinctrl state from suspend
 *
 * Restore one of the banks that was saved during suspend.
 *
 * We don't bother doing anything complicated to avoid glitching lines since
 * we're called before pad retention is turned off.
 */
static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
{}

static const struct of_device_id samsung_pinctrl_dt_match[] =;

static const struct dev_pm_ops samsung_pinctrl_pm_ops =;

static struct platform_driver samsung_pinctrl_driver =;

static int __init samsung_pinctrl_drv_register(void)
{}
postcore_initcall(samsung_pinctrl_drv_register);