aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/pinctrl/sunplus/sppctl.h
blob: 6210f22005869c115b314a83114ab10ace47cfb9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * SP7021 Pin Controller Driver.
 * Copyright (C) Sunplus Tech / Tibbo Tech.
 */

#ifndef __SPPCTL_H__
#define __SPPCTL_H__

#include <linux/bits.h>
#include <linux/gpio/driver.h>
#include <linux/kernel.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/spinlock.h>
#include <linux/types.h>

#define SPPCTL_MODULE_NAME		"sppctl_sp7021"

#define SPPCTL_GPIO_OFF_FIRST		0x00
#define SPPCTL_GPIO_OFF_MASTER		0x00
#define SPPCTL_GPIO_OFF_OE		0x20
#define SPPCTL_GPIO_OFF_OUT		0x40
#define SPPCTL_GPIO_OFF_IN		0x60
#define SPPCTL_GPIO_OFF_IINV		0x80
#define SPPCTL_GPIO_OFF_OINV		0xa0
#define SPPCTL_GPIO_OFF_OD		0xc0

#define SPPCTL_FULLY_PINMUX_MASK_MASK	GENMASK(22, 16)
#define SPPCTL_FULLY_PINMUX_SEL_MASK	GENMASK(6, 0)
#define SPPCTL_FULLY_PINMUX_UPPER_SHIFT	8

/*
 * Mask-fields and control-fields of MOON registers 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.
 */
#define SPPCTL_MOON_REG_MASK_SHIFT	16
#define SPPCTL_SET_MOON_REG_BIT(bit)	(BIT((bit) + SPPCTL_MOON_REG_MASK_SHIFT) | BIT(bit))
#define SPPCTL_CLR_MOON_REG_BIT(bit)	BIT((bit) + SPPCTL_MOON_REG_MASK_SHIFT)

#define SPPCTL_IOP_CONFIGS		0xff

#define FNCE(n, r, o, bo, bl, g) { \
	.name = n, \
	.type = r, \
	.roff = o, \
	.boff = bo, \
	.blen = bl, \
	.grps = (g), \
	.gnum = ARRAY_SIZE(g), \
}

#define FNCN(n, r, o, bo, bl) { \
	.name = n, \
	.type = r, \
	.roff = o, \
	.boff = bo, \
	.blen = bl, \
	.grps = NULL, \
	.gnum = 0, \
}

#define EGRP(n, v, p) { \
	.name = n, \
	.gval = (v), \
	.pins = (p), \
	.pnum = ARRAY_SIZE(p), \
}

/**
 * enum mux_first_reg - Define modes of access of FIRST register
 * @mux_f_mux:  Set the corresponding pin to a fully-pinmux pin
 * @mux_f_gpio: Set the corresponding pin to a GPIO or IOP pin
 * @mux_f_keep: Don't change (keep intact)
 */
enum mux_first_reg {
	mux_f_mux = 0,
	mux_f_gpio = 1,
	mux_f_keep = 2,
};

/**
 * enum mux_master_reg - Define modes of access of MASTER register
 * @mux_m_iop:  Set the corresponding pin to an IO processor (IOP) pin
 * @mux_m_gpio: Set the corresponding pin to a digital GPIO pin
 * @mux_m_keep: Don't change (keep intact)
 */
enum mux_master_reg {
	mux_m_iop = 0,
	mux_m_gpio = 1,
	mux_m_keep = 2,
};

/**
 * enum pinmux_type - Define types of pinmux pins
 * @pinmux_type_fpmx: A fully-pinmux pin
 * @pinmux_type_grp:  A group-pinmux pin
 */
enum pinmux_type {
	pinmux_type_fpmx,
	pinmux_type_grp,
};

/**
 * struct grp2fp_map - A map storing indexes
 * @f_idx: an index to function table
 * @g_idx: an index to group table
 */
struct grp2fp_map {
	u16 f_idx;
	u16 g_idx;
};

struct sppctl_gpio_chip;

struct sppctl_pdata {
	void __iomem *moon2_base;	/* MOON2                                 */
	void __iomem *gpioxt_base;	/* MASTER, OE, OUT, IN, I_INV, O_INV, OD */
	void __iomem *first_base;	/* FIRST                                 */
	void __iomem *moon1_base;	/* MOON1               */

	struct pinctrl_desc pctl_desc;
	struct pinctrl_dev *pctl_dev;
	struct pinctrl_gpio_range pctl_grange;
	struct sppctl_gpio_chip *spp_gchip;

	char const **unq_grps;
	size_t unq_grps_sz;
	struct grp2fp_map *g2fp_maps;
};

struct sppctl_grp {
	const char * const name;
	const u8 gval;                  /* group number   */
	const unsigned * const pins;    /* list of pins   */
	const unsigned int pnum;        /* number of pins */
};

struct sppctl_func {
	const char * const name;
	const enum pinmux_type type;    /* function type          */
	const u8 roff;                  /* register offset        */
	const u8 boff;                  /* bit offset             */
	const u8 blen;                  /* bit length             */
	const struct sppctl_grp * const grps; /* list of groups   */
	const unsigned int gnum;        /* number of groups       */
};

extern const struct sppctl_func sppctl_list_funcs[];
extern const char * const sppctl_pmux_list_s[];
extern const char * const sppctl_gpio_list_s[];
extern const struct pinctrl_pin_desc sppctl_pins_all[];
extern const unsigned int sppctl_pins_gpio[];

extern const size_t sppctl_list_funcs_sz;
extern const size_t sppctl_pmux_list_sz;
extern const size_t sppctl_gpio_list_sz;
extern const size_t sppctl_pins_all_sz;

#endif