162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * SP7021 Pin Controller Driver. 462306a36Sopenharmony_ci * Copyright (C) Sunplus Tech / Tibbo Tech. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef __SPPCTL_H__ 862306a36Sopenharmony_ci#define __SPPCTL_H__ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/bits.h> 1162306a36Sopenharmony_ci#include <linux/gpio/driver.h> 1262306a36Sopenharmony_ci#include <linux/kernel.h> 1362306a36Sopenharmony_ci#include <linux/pinctrl/pinctrl.h> 1462306a36Sopenharmony_ci#include <linux/spinlock.h> 1562306a36Sopenharmony_ci#include <linux/types.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define SPPCTL_MODULE_NAME "sppctl_sp7021" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define SPPCTL_GPIO_OFF_FIRST 0x00 2062306a36Sopenharmony_ci#define SPPCTL_GPIO_OFF_MASTER 0x00 2162306a36Sopenharmony_ci#define SPPCTL_GPIO_OFF_OE 0x20 2262306a36Sopenharmony_ci#define SPPCTL_GPIO_OFF_OUT 0x40 2362306a36Sopenharmony_ci#define SPPCTL_GPIO_OFF_IN 0x60 2462306a36Sopenharmony_ci#define SPPCTL_GPIO_OFF_IINV 0x80 2562306a36Sopenharmony_ci#define SPPCTL_GPIO_OFF_OINV 0xa0 2662306a36Sopenharmony_ci#define SPPCTL_GPIO_OFF_OD 0xc0 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define SPPCTL_FULLY_PINMUX_MASK_MASK GENMASK(22, 16) 2962306a36Sopenharmony_ci#define SPPCTL_FULLY_PINMUX_SEL_MASK GENMASK(6, 0) 3062306a36Sopenharmony_ci#define SPPCTL_FULLY_PINMUX_UPPER_SHIFT 8 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* 3362306a36Sopenharmony_ci * Mask-fields and control-fields of MOON registers of SP7021 are 3462306a36Sopenharmony_ci * arranged as shown below: 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * register | mask-fields | control-fields 3762306a36Sopenharmony_ci * ----------+--------------+---------------- 3862306a36Sopenharmony_ci * base[0] | (31 : 16) | (15 : 0) 3962306a36Sopenharmony_ci * base[1] | (31 : 24) | (15 : 0) 4062306a36Sopenharmony_ci * base[2] | (31 : 24) | (15 : 0) 4162306a36Sopenharmony_ci * : | : | : 4262306a36Sopenharmony_ci * 4362306a36Sopenharmony_ci * where mask-fields are used to protect control-fields from write-in 4462306a36Sopenharmony_ci * accidentally. Set the corresponding bits in the mask-field before 4562306a36Sopenharmony_ci * you write a value into a control-field. 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_ci#define SPPCTL_MOON_REG_MASK_SHIFT 16 4862306a36Sopenharmony_ci#define SPPCTL_SET_MOON_REG_BIT(bit) (BIT((bit) + SPPCTL_MOON_REG_MASK_SHIFT) | BIT(bit)) 4962306a36Sopenharmony_ci#define SPPCTL_CLR_MOON_REG_BIT(bit) BIT((bit) + SPPCTL_MOON_REG_MASK_SHIFT) 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#define SPPCTL_IOP_CONFIGS 0xff 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define FNCE(n, r, o, bo, bl, g) { \ 5462306a36Sopenharmony_ci .name = n, \ 5562306a36Sopenharmony_ci .type = r, \ 5662306a36Sopenharmony_ci .roff = o, \ 5762306a36Sopenharmony_ci .boff = bo, \ 5862306a36Sopenharmony_ci .blen = bl, \ 5962306a36Sopenharmony_ci .grps = (g), \ 6062306a36Sopenharmony_ci .gnum = ARRAY_SIZE(g), \ 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci#define FNCN(n, r, o, bo, bl) { \ 6462306a36Sopenharmony_ci .name = n, \ 6562306a36Sopenharmony_ci .type = r, \ 6662306a36Sopenharmony_ci .roff = o, \ 6762306a36Sopenharmony_ci .boff = bo, \ 6862306a36Sopenharmony_ci .blen = bl, \ 6962306a36Sopenharmony_ci .grps = NULL, \ 7062306a36Sopenharmony_ci .gnum = 0, \ 7162306a36Sopenharmony_ci} 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci#define EGRP(n, v, p) { \ 7462306a36Sopenharmony_ci .name = n, \ 7562306a36Sopenharmony_ci .gval = (v), \ 7662306a36Sopenharmony_ci .pins = (p), \ 7762306a36Sopenharmony_ci .pnum = ARRAY_SIZE(p), \ 7862306a36Sopenharmony_ci} 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci/** 8162306a36Sopenharmony_ci * enum mux_first_reg - Define modes of access of FIRST register 8262306a36Sopenharmony_ci * @mux_f_mux: Set the corresponding pin to a fully-pinmux pin 8362306a36Sopenharmony_ci * @mux_f_gpio: Set the corresponding pin to a GPIO or IOP pin 8462306a36Sopenharmony_ci * @mux_f_keep: Don't change (keep intact) 8562306a36Sopenharmony_ci */ 8662306a36Sopenharmony_cienum mux_first_reg { 8762306a36Sopenharmony_ci mux_f_mux = 0, 8862306a36Sopenharmony_ci mux_f_gpio = 1, 8962306a36Sopenharmony_ci mux_f_keep = 2, 9062306a36Sopenharmony_ci}; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/** 9362306a36Sopenharmony_ci * enum mux_master_reg - Define modes of access of MASTER register 9462306a36Sopenharmony_ci * @mux_m_iop: Set the corresponding pin to an IO processor (IOP) pin 9562306a36Sopenharmony_ci * @mux_m_gpio: Set the corresponding pin to a digital GPIO pin 9662306a36Sopenharmony_ci * @mux_m_keep: Don't change (keep intact) 9762306a36Sopenharmony_ci */ 9862306a36Sopenharmony_cienum mux_master_reg { 9962306a36Sopenharmony_ci mux_m_iop = 0, 10062306a36Sopenharmony_ci mux_m_gpio = 1, 10162306a36Sopenharmony_ci mux_m_keep = 2, 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci/** 10562306a36Sopenharmony_ci * enum pinmux_type - Define types of pinmux pins 10662306a36Sopenharmony_ci * @pinmux_type_fpmx: A fully-pinmux pin 10762306a36Sopenharmony_ci * @pinmux_type_grp: A group-pinmux pin 10862306a36Sopenharmony_ci */ 10962306a36Sopenharmony_cienum pinmux_type { 11062306a36Sopenharmony_ci pinmux_type_fpmx, 11162306a36Sopenharmony_ci pinmux_type_grp, 11262306a36Sopenharmony_ci}; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci/** 11562306a36Sopenharmony_ci * struct grp2fp_map - A map storing indexes 11662306a36Sopenharmony_ci * @f_idx: an index to function table 11762306a36Sopenharmony_ci * @g_idx: an index to group table 11862306a36Sopenharmony_ci */ 11962306a36Sopenharmony_cistruct grp2fp_map { 12062306a36Sopenharmony_ci u16 f_idx; 12162306a36Sopenharmony_ci u16 g_idx; 12262306a36Sopenharmony_ci}; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistruct sppctl_gpio_chip; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistruct sppctl_pdata { 12762306a36Sopenharmony_ci void __iomem *moon2_base; /* MOON2 */ 12862306a36Sopenharmony_ci void __iomem *gpioxt_base; /* MASTER, OE, OUT, IN, I_INV, O_INV, OD */ 12962306a36Sopenharmony_ci void __iomem *first_base; /* FIRST */ 13062306a36Sopenharmony_ci void __iomem *moon1_base; /* MOON1 */ 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci struct pinctrl_desc pctl_desc; 13362306a36Sopenharmony_ci struct pinctrl_dev *pctl_dev; 13462306a36Sopenharmony_ci struct pinctrl_gpio_range pctl_grange; 13562306a36Sopenharmony_ci struct sppctl_gpio_chip *spp_gchip; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci char const **unq_grps; 13862306a36Sopenharmony_ci size_t unq_grps_sz; 13962306a36Sopenharmony_ci struct grp2fp_map *g2fp_maps; 14062306a36Sopenharmony_ci}; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cistruct sppctl_grp { 14362306a36Sopenharmony_ci const char * const name; 14462306a36Sopenharmony_ci const u8 gval; /* group number */ 14562306a36Sopenharmony_ci const unsigned * const pins; /* list of pins */ 14662306a36Sopenharmony_ci const unsigned int pnum; /* number of pins */ 14762306a36Sopenharmony_ci}; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistruct sppctl_func { 15062306a36Sopenharmony_ci const char * const name; 15162306a36Sopenharmony_ci const enum pinmux_type type; /* function type */ 15262306a36Sopenharmony_ci const u8 roff; /* register offset */ 15362306a36Sopenharmony_ci const u8 boff; /* bit offset */ 15462306a36Sopenharmony_ci const u8 blen; /* bit length */ 15562306a36Sopenharmony_ci const struct sppctl_grp * const grps; /* list of groups */ 15662306a36Sopenharmony_ci const unsigned int gnum; /* number of groups */ 15762306a36Sopenharmony_ci}; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ciextern const struct sppctl_func sppctl_list_funcs[]; 16062306a36Sopenharmony_ciextern const char * const sppctl_pmux_list_s[]; 16162306a36Sopenharmony_ciextern const char * const sppctl_gpio_list_s[]; 16262306a36Sopenharmony_ciextern const struct pinctrl_pin_desc sppctl_pins_all[]; 16362306a36Sopenharmony_ciextern const unsigned int sppctl_pins_gpio[]; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ciextern const size_t sppctl_list_funcs_sz; 16662306a36Sopenharmony_ciextern const size_t sppctl_pmux_list_sz; 16762306a36Sopenharmony_ciextern const size_t sppctl_gpio_list_sz; 16862306a36Sopenharmony_ciextern const size_t sppctl_pins_all_sz; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci#endif 171