1129 lines · 31.7 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0/* * SP7021 Pin Controller Driver. * Copyright (C) Sunplus Tech / Tibbo Tech. */ #include <linux/cleanup.h>#include <linux/bitfield.h>#include <linux/device.h>#include <linux/err.h>#include <linux/gpio/driver.h>#include <linux/init.h>#include <linux/module.h>#include <linux/of.h>#include <linux/overflow.h>#include <linux/platform_device.h>#include <linux/seq_file.h>#include <linux/slab.h> #include <linux/pinctrl/pinconf.h>#include <linux/pinctrl/pinconf-generic.h>#include <linux/pinctrl/pinmux.h> #include <dt-bindings/pinctrl/sppctl-sp7021.h> #include "../core.h"#include "../pinctrl-utils.h" #include "sppctl.h" struct sppctl_gpio_chip {	void __iomem *gpioxt_base;	/* MASTER, OE, OUT, IN, I_INV, O_INV, OD */	void __iomem *first_base;	/* GPIO_FIRST                            */ 	struct gpio_chip chip;	spinlock_t lock;		/* lock for accessing OE register        */}; static inline u32 sppctl_first_readl(struct sppctl_gpio_chip *spp_gchip, u32 off){	return readl(spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST + off);} static inline void sppctl_first_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off){	writel(val, spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST + off);} static inline u32 sppctl_gpio_master_readl(struct sppctl_gpio_chip *spp_gchip, u32 off){	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + off);} static inline void sppctl_gpio_master_writel(struct sppctl_gpio_chip *spp_gchip, u32 val,					     u32 off){	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + off);} static inline u32 sppctl_gpio_oe_readl(struct sppctl_gpio_chip *spp_gchip, u32 off){	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OE + off);} static inline void sppctl_gpio_oe_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off){	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OE + off);} static inline void sppctl_gpio_out_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off){	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OUT + off);} static inline u32 sppctl_gpio_in_readl(struct sppctl_gpio_chip *spp_gchip, u32 off){	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IN + off);} static inline u32 sppctl_gpio_iinv_readl(struct sppctl_gpio_chip *spp_gchip, u32 off){	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IINV + off);} static inline void sppctl_gpio_iinv_writel(struct sppctl_gpio_chip *spp_gchip, u32 val,					   u32 off){	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IINV + off);} static inline u32 sppctl_gpio_oinv_readl(struct sppctl_gpio_chip *spp_gchip, u32 off){	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OINV + off);} static inline void sppctl_gpio_oinv_writel(struct sppctl_gpio_chip *spp_gchip, u32 val,					   u32 off){	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OINV + off);} static inline u32 sppctl_gpio_od_readl(struct sppctl_gpio_chip *spp_gchip, u32 off){	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OD + off);} static inline void sppctl_gpio_od_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off){	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OD + off);} static inline u32 sppctl_get_reg_and_bit_offset(unsigned int offset, u32 *reg_off){	u32 bit_off; 	/* Each register has 32 bits. */	*reg_off = (offset / 32) * 4;	bit_off = offset % 32; 	return bit_off;} static inline u32 sppctl_get_moon_reg_and_bit_offset(unsigned int offset, u32 *reg_off){	u32 bit_off; 	/*	 * Each MOON register has 32 bits. Upper 16-bit word are mask-fields.	 * The lower 16-bit word are the control-fields. The corresponding	 * bits in mask-field should be set then you can write something to	 * control-field.	 */	*reg_off = (offset / 16) * 4;	bit_off = offset % 16; 	return bit_off;} static inline u32 sppctl_prep_moon_reg_and_offset(unsigned int offset, u32 *reg_off, int val){	u32 bit_off; 	bit_off = sppctl_get_moon_reg_and_bit_offset(offset, reg_off);	if (val)		return SPPCTL_SET_MOON_REG_BIT(bit_off);	else		return SPPCTL_CLR_MOON_REG_BIT(bit_off);} /** * sppctl_func_set() - Set pin of fully-pinmux function. * * Mask-fields and control-fields of fully-pinmux function of SP7021 are * arranged as shown below: * *  func# | register |  mask-field  | control-field * -------+----------+--------------+--------------- *    0   | base[0]  |  (22 : 16)   |   ( 6 : 0) *    1   | base[0]  |  (30 : 24)   |   (14 : 8) *    2   | base[1]  |  (22 : 16)   |   ( 6 : 0) *    3   | baeg[1]  |  (30 : 24)   |   (14 : 8) *    :   |    :     |      :       |       : * * where mask-fields are used to protect control-fields from write-in * accidentally. Set the corresponding bits in the mask-field before * you write a value into a control-field. * * Control-fields are used to set where the function pin is going to * be routed to. * * Note that mask-fields and control-fields of even number of 'func' * are located at bits (22:16) and (6:0), while odd number of 'func's * are located at bits (30:24) and (14:8). */static void sppctl_func_set(struct sppctl_pdata *pctl, u8 func, u8 val){	u32 reg, offset; 	/*	 * Note that upper 16-bit word are mask-fields and lower 16-bit	 * word are the control-fields. Set corresponding bits in mask-	 * field before write to a control-field.	 */	reg = SPPCTL_FULLY_PINMUX_MASK_MASK | val; 	/*	 * MUXF_L2SW_CLK_OUT is the first fully-pinmux pin	 * and its register offset is 0.	 */	func -= MUXF_L2SW_CLK_OUT; 	/*	 * Check if 'func' is an odd number or not. Mask and control-	 * fields of odd number 'func' is located at upper portion of	 * a register. Extra shift is needed.	 */	if (func & BIT(0))		reg <<= SPPCTL_FULLY_PINMUX_UPPER_SHIFT; 	/* Convert func# to register offset w.r.t. base register. */	offset = func * 2;	offset &= GENMASK(31, 2); 	writel(reg, pctl->moon2_base + offset);} /** * sppctl_gmx_set() - Set pin of group-pinmux. * * Mask-fields and control-fields of group-pinmux function of SP7021 are * arranged as shown below: * *  register |  mask-fields | control-fields * ----------+--------------+---------------- *  base[0]  |  (31 : 16)   |   (15 : 0) *  base[1]  |  (31 : 24)   |   (15 : 0) *  base[2]  |  (31 : 24)   |   (15 : 0) *     :     |      :       |       : * * where mask-fields are used to protect control-fields from write-in * accidentally. Set the corresponding bits in the mask-field before * you write a value into a control-field. * * Control-fields are used to set where the function pin is going to * be routed to. A control-field consists of one or more bits. */static void sppctl_gmx_set(struct sppctl_pdata *pctl, u8 reg_off, u8 bit_off, u8 bit_sz,			   u8 val){	u32 mask, reg; 	/*	 * Note that upper 16-bit word are mask-fields and lower 16-bit	 * word are the control-fields. Set corresponding bits in mask-	 * field before write to a control-field.	 */	mask = GENMASK(bit_sz - 1, 0) << SPPCTL_MOON_REG_MASK_SHIFT;	reg = (mask | val) << bit_off; 	writel(reg, pctl->moon1_base + reg_off * 4);} /** * sppctl_first_get() - get bit of FIRST register. * * There are 4 FIRST registers. Each has 32 control-bits. * Totally, there are 4 * 32 = 128 control-bits. * Control-bits are arranged as shown below: * *  registers | control-bits * -----------+-------------- *  first[0]  |  (31 :  0) *  first[1]  |  (63 : 32) *  first[2]  |  (95 : 64) *  first[3]  | (127 : 96) * * Each control-bit sets type of a GPIO pin. *   0: a fully-pinmux pin *   1: a GPIO or IOP pin */static int sppctl_first_get(struct gpio_chip *chip, unsigned int offset){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, bit_off, reg; 	bit_off = sppctl_get_reg_and_bit_offset(offset, &reg_off);	reg = sppctl_first_readl(spp_gchip, reg_off); 	return (reg & BIT(bit_off)) ? 1 : 0;} /** * sppctl_master_get() - get bit of MASTER register. * * There are 8 MASTER registers. Each has 16 mask-bits and 16 control-bits. * Upper 16-bit of MASTER registers are mask-bits while lower 16-bit are * control-bits. Totally, there are 128 mask-bits and 128 control-bits. * They are arranged as shown below: * *  register  |  mask-bits  | control-bits * -----------+-------------+-------------- *  master[0] |  (15 :   0) |  (15 :   0) *  master[1] |  (31 :  16) |  (31 :  16) *  master[2] |  (47 :  32) |  (47 :  32) *     :      |      :      |      : *  master[7] | (127 : 112) | (127 : 112) * * where mask-bits are used to protect control-bits from write-in * accidentally. Set the corresponding mask-bit before you write * a value into a control-bit. * * Each control-bit sets type of a GPIO pin when FIRST bit is 1. *   0: a IOP pin *   1: a GPIO pin */static int sppctl_master_get(struct gpio_chip *chip, unsigned int offset){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, bit_off, reg; 	bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off);	reg = sppctl_gpio_master_readl(spp_gchip, reg_off);	return (reg & BIT(bit_off)) ? 1 : 0;} static void sppctl_first_master_set(struct gpio_chip *chip, unsigned int offset,				    enum mux_first_reg first, enum mux_master_reg master){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, bit_off, reg;	enum mux_first_reg val; 	/* FIRST register */	if (first != mux_f_keep) {		bit_off = sppctl_get_reg_and_bit_offset(offset, &reg_off);		reg = sppctl_first_readl(spp_gchip, reg_off);		val = (reg & BIT(bit_off)) ? mux_f_gpio : mux_f_mux; 		if (first != val)			switch (first) {			case mux_f_gpio:				reg |= BIT(bit_off);				sppctl_first_writel(spp_gchip, reg, reg_off);				break; 			case mux_f_mux:				reg &= ~BIT(bit_off);				sppctl_first_writel(spp_gchip, reg, reg_off);				break; 			case mux_f_keep:				break;			}	} 	/* MASTER register */	if (master != mux_m_keep) {		reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, (master == mux_m_gpio));		sppctl_gpio_master_writel(spp_gchip, reg, reg_off);	}} static void sppctl_gpio_input_inv_set(struct gpio_chip *chip, unsigned int offset){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, reg; 	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1);	sppctl_gpio_iinv_writel(spp_gchip, reg, reg_off);} static void sppctl_gpio_output_inv_set(struct gpio_chip *chip, unsigned int offset){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, reg; 	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1);	sppctl_gpio_oinv_writel(spp_gchip, reg, reg_off);} static int sppctl_gpio_output_od_get(struct gpio_chip *chip, unsigned int offset){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, bit_off, reg; 	bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off);	reg = sppctl_gpio_od_readl(spp_gchip, reg_off); 	return (reg & BIT(bit_off)) ? 1 : 0;} static void sppctl_gpio_output_od_set(struct gpio_chip *chip, unsigned int offset,				      unsigned int val){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, reg; 	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, val);	sppctl_gpio_od_writel(spp_gchip, reg, reg_off);} static int sppctl_gpio_get_direction(struct gpio_chip *chip, unsigned int offset){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, bit_off, reg; 	bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off);	reg = sppctl_gpio_oe_readl(spp_gchip, reg_off); 	return (reg & BIT(bit_off)) ? 0 : 1;} static int sppctl_gpio_inv_get(struct gpio_chip *chip, unsigned int offset){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, bit_off, reg;	unsigned long flags; 	bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off); 	spin_lock_irqsave(&spp_gchip->lock, flags); 	if (sppctl_gpio_get_direction(chip, offset))		reg = sppctl_gpio_iinv_readl(spp_gchip, reg_off);	else		reg = sppctl_gpio_oinv_readl(spp_gchip, reg_off); 	spin_unlock_irqrestore(&spp_gchip->lock, flags); 	return (reg & BIT(bit_off)) ? 1 : 0;} static int sppctl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	unsigned long flags;	u32 reg_off, reg; 	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 0); 	spin_lock_irqsave(&spp_gchip->lock, flags); 	sppctl_gpio_oe_writel(spp_gchip, reg, reg_off); 	spin_unlock_irqrestore(&spp_gchip->lock, flags);	return 0;} static int sppctl_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int val){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	unsigned long flags;	u32 reg_off, reg; 	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1); 	spin_lock_irqsave(&spp_gchip->lock, flags); 	sppctl_gpio_oe_writel(spp_gchip, reg, reg_off); 	if (val < 0) {		spin_unlock_irqrestore(&spp_gchip->lock, flags);		return 0;	} 	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, val);	sppctl_gpio_out_writel(spp_gchip, reg, reg_off); 	spin_unlock_irqrestore(&spp_gchip->lock, flags);	return 0;} static int sppctl_gpio_get(struct gpio_chip *chip, unsigned int offset){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, bit_off, reg; 	bit_off = sppctl_get_reg_and_bit_offset(offset, &reg_off);	reg = sppctl_gpio_in_readl(spp_gchip, reg_off); 	return (reg & BIT(bit_off)) ? 1 : 0;} static int sppctl_gpio_set(struct gpio_chip *chip, unsigned int offset, int val){	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, reg; 	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, val);	sppctl_gpio_out_writel(spp_gchip, reg, reg_off); 	return 0;} static int sppctl_gpio_set_config(struct gpio_chip *chip, unsigned int offset,				  unsigned long config){	enum pin_config_param param = pinconf_to_config_param(config);	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);	u32 reg_off, reg; 	switch (param) {	case PIN_CONFIG_DRIVE_OPEN_DRAIN:		reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1);		sppctl_gpio_od_writel(spp_gchip, reg, reg_off);		break; 	case PIN_CONFIG_INPUT_ENABLE:		break; 	case PIN_CONFIG_LEVEL:		return sppctl_gpio_direction_output(chip, offset, 0); 	case PIN_CONFIG_PERSIST_STATE:		return -ENOTSUPP; 	default:		return -EINVAL;	} 

Lines 1–500 of 1129.