summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/samsung/pinctrl-exynos.h
blob: 3ac52c2cf9984709df7a5f604acd6d45086f4c1b (plain)
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
171
172
173
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Exynos specific definitions for Samsung pinctrl and gpiolib driver.
 *
 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 * Copyright (c) 2012 Linaro Ltd
 *		http://www.linaro.org
 *
 * This file contains the Exynos specific definitions for the Samsung
 * pinctrl/gpiolib interface drivers.
 *
 * Author: Thomas Abraham <thomas.ab@samsung.com>
 */

#ifndef __PINCTRL_SAMSUNG_EXYNOS_H
#define __PINCTRL_SAMSUNG_EXYNOS_H

/* Values for the pin CON register */
#define EXYNOS_PIN_CON_FUNC_EINT	0xf

/* External GPIO and wakeup interrupt related definitions */
#define EXYNOS_GPIO_ECON_OFFSET		0x700
#define EXYNOS_GPIO_EFLTCON_OFFSET	0x800
#define EXYNOS_GPIO_EMASK_OFFSET	0x900
#define EXYNOS_GPIO_EPEND_OFFSET	0xA00
#define EXYNOS_WKUP_ECON_OFFSET		0xE00
#define EXYNOS_WKUP_EMASK_OFFSET	0xF00
#define EXYNOS_WKUP_EPEND_OFFSET	0xF40
#define EXYNOS7_WKUP_ECON_OFFSET	0x700
#define EXYNOS7_WKUP_EMASK_OFFSET	0x900
#define EXYNOS7_WKUP_EPEND_OFFSET	0xA00
#define EXYNOS_SVC_OFFSET		0xB08

/* helpers to access interrupt service register */
#define EXYNOS_SVC_GROUP_SHIFT		3
#define EXYNOS_SVC_GROUP_MASK		0x1f
#define EXYNOS_SVC_NUM_MASK		7
#define EXYNOS_SVC_GROUP(x)		((x >> EXYNOS_SVC_GROUP_SHIFT) & \
						EXYNOS_SVC_GROUP_MASK)

/* Exynos specific external interrupt trigger types */
#define EXYNOS_EINT_LEVEL_LOW		0
#define EXYNOS_EINT_LEVEL_HIGH		1
#define EXYNOS_EINT_EDGE_FALLING	2
#define EXYNOS_EINT_EDGE_RISING		3
#define EXYNOS_EINT_EDGE_BOTH		4
#define EXYNOS_EINT_CON_MASK		0xF
#define EXYNOS_EINT_CON_LEN		4

#define EXYNOS_EINT_MAX_PER_BANK	8
#define EXYNOS_EINT_NR_WKUP_EINT

#define EXYNOS_PIN_BANK_EINTN(pins, reg, id)		\
	{						\
		.type		= &bank_type_off,	\
		.pctl_offset	= reg,			\
		.nr_pins	= pins,			\
		.eint_type	= EINT_TYPE_NONE,	\
		.name		= id			\
	}

#define EXYNOS_PIN_BANK_EINTG(pins, reg, id, offs)	\
	{						\
		.type		= &bank_type_off,	\
		.pctl_offset	= reg,			\
		.nr_pins	= pins,			\
		.eint_type	= EINT_TYPE_GPIO,	\
		.eint_offset	= offs,			\
		.name		= id			\
	}

#define EXYNOS_PIN_BANK_EINTW(pins, reg, id, offs)	\
	{						\
		.type		= &bank_type_alive,	\
		.pctl_offset	= reg,			\
		.nr_pins	= pins,			\
		.eint_type	= EINT_TYPE_WKUP,	\
		.eint_offset	= offs,			\
		.name		= id			\
	}

#define EXYNOS5433_PIN_BANK_EINTG(pins, reg, id, offs)		\
	{							\
		.type		= &exynos5433_bank_type_off,	\
		.pctl_offset	= reg,				\
		.nr_pins	= pins,				\
		.eint_type	= EINT_TYPE_GPIO,		\
		.eint_offset	= offs,				\
		.name		= id				\
	}

#define EXYNOS5433_PIN_BANK_EINTW(pins, reg, id, offs)		\
	{							\
		.type		= &exynos5433_bank_type_alive,	\
		.pctl_offset	= reg,				\
		.nr_pins	= pins,				\
		.eint_type	= EINT_TYPE_WKUP,		\
		.eint_offset	= offs,				\
		.name		= id				\
	}

#define EXYNOS5433_PIN_BANK_EINTW_EXT(pins, reg, id, offs, pctl_idx) \
	{							\
		.type           = &exynos5433_bank_type_off,	\
		.pctl_offset    = reg,				\
		.nr_pins        = pins,				\
		.eint_type      = EINT_TYPE_WKUP,		\
		.eint_offset    = offs,				\
		.name           = id,				\
		.pctl_res_idx   = pctl_idx,			\
	}							\

#define EXYNOS850_PIN_BANK_EINTN(pins, reg, id)			\
	{							\
		.type		= &exynos850_bank_type_alive,	\
		.pctl_offset	= reg,				\
		.nr_pins	= pins,				\
		.eint_type	= EINT_TYPE_NONE,		\
		.name		= id				\
	}

#define EXYNOS850_PIN_BANK_EINTG(pins, reg, id, offs)		\
	{							\
		.type		= &exynos850_bank_type_off,	\
		.pctl_offset	= reg,				\
		.nr_pins	= pins,				\
		.eint_type	= EINT_TYPE_GPIO,		\
		.eint_offset	= offs,				\
		.name		= id				\
	}

#define EXYNOS850_PIN_BANK_EINTW(pins, reg, id, offs)		\
	{							\
		.type		= &exynos850_bank_type_alive,	\
		.pctl_offset	= reg,				\
		.nr_pins	= pins,				\
		.eint_type	= EINT_TYPE_WKUP,		\
		.eint_offset	= offs,				\
		.name		= id				\
	}

/**
 * struct exynos_weint_data: irq specific data for all the wakeup interrupts
 * generated by the external wakeup interrupt controller.
 * @irq: interrupt number within the domain.
 * @bank: bank responsible for this interrupt
 */
struct exynos_weint_data {
	unsigned int irq;
	struct samsung_pin_bank *bank;
};

/**
 * struct exynos_muxed_weint_data: irq specific data for muxed wakeup interrupts
 * generated by the external wakeup interrupt controller.
 * @nr_banks: count of banks being part of the mux
 * @banks: array of banks being part of the mux
 */
struct exynos_muxed_weint_data {
	unsigned int nr_banks;
	struct samsung_pin_bank *banks[] __counted_by(nr_banks);
};

int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d);
int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d);
void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata);
void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata);
struct samsung_retention_ctrl *
exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata,
		      const struct samsung_retention_data *data);

#endif /* __PINCTRL_SAMSUNG_EXYNOS_H */