Commit | Line | Data |
---|---|---|
6ac73095 BG |
1 | /* |
2 | * Pin controller and GPIO driver for Amlogic Meson SoCs | |
3 | * | |
4 | * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License | |
8 | * version 2 as published by the Free Software Foundation. | |
9 | * | |
10 | * You should have received a copy of the GNU General Public License | |
11 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
12 | */ | |
13 | ||
14 | #include <linux/gpio.h> | |
15 | #include <linux/pinctrl/pinctrl.h> | |
16 | #include <linux/regmap.h> | |
17 | #include <linux/types.h> | |
18 | ||
19 | /** | |
20 | * struct meson_pmx_group - a pinmux group | |
21 | * | |
22 | * @name: group name | |
23 | * @pins: pins in the group | |
24 | * @num_pins: number of pins in the group | |
25 | * @is_gpio: whether the group is a single GPIO group | |
26 | * @reg: register offset for the group in the domain mux registers | |
27 | * @bit bit index enabling the group | |
28 | * @domain: index of the domain this group belongs to | |
29 | */ | |
30 | struct meson_pmx_group { | |
31 | const char *name; | |
32 | const unsigned int *pins; | |
33 | unsigned int num_pins; | |
34 | bool is_gpio; | |
35 | unsigned int reg; | |
36 | unsigned int bit; | |
37 | unsigned int domain; | |
38 | }; | |
39 | ||
40 | /** | |
41 | * struct meson_pmx_func - a pinmux function | |
42 | * | |
43 | * @name: function name | |
44 | * @groups: groups in the function | |
45 | * @num_groups: number of groups in the function | |
46 | */ | |
47 | struct meson_pmx_func { | |
48 | const char *name; | |
49 | const char * const *groups; | |
50 | unsigned int num_groups; | |
51 | }; | |
52 | ||
53 | /** | |
54 | * struct meson_reg_desc - a register descriptor | |
55 | * | |
56 | * @reg: register offset in the regmap | |
57 | * @bit: bit index in register | |
58 | * | |
59 | * The structure describes the information needed to control pull, | |
60 | * pull-enable, direction, etc. for a single pin | |
61 | */ | |
62 | struct meson_reg_desc { | |
63 | unsigned int reg; | |
64 | unsigned int bit; | |
65 | }; | |
66 | ||
67 | /** | |
68 | * enum meson_reg_type - type of registers encoded in @meson_reg_desc | |
69 | */ | |
70 | enum meson_reg_type { | |
71 | REG_PULLEN, | |
72 | REG_PULL, | |
73 | REG_DIR, | |
74 | REG_OUT, | |
75 | REG_IN, | |
76 | NUM_REG, | |
77 | }; | |
78 | ||
79 | /** | |
80 | * struct meson bank | |
81 | * | |
82 | * @name: bank name | |
83 | * @first: first pin of the bank | |
84 | * @last: last pin of the bank | |
85 | * @regs: array of register descriptors | |
86 | * | |
87 | * A bank represents a set of pins controlled by a contiguous set of | |
88 | * bits in the domain registers. The structure specifies which bits in | |
89 | * the regmap control the different functionalities. Each member of | |
90 | * the @regs array refers to the first pin of the bank. | |
91 | */ | |
92 | struct meson_bank { | |
93 | const char *name; | |
94 | unsigned int first; | |
95 | unsigned int last; | |
96 | struct meson_reg_desc regs[NUM_REG]; | |
97 | }; | |
98 | ||
99 | /** | |
100 | * struct meson_domain_data - domain platform data | |
101 | * | |
102 | * @name: name of the domain | |
103 | * @banks: set of banks belonging to the domain | |
104 | * @num_banks: number of banks in the domain | |
105 | */ | |
106 | struct meson_domain_data { | |
107 | const char *name; | |
108 | struct meson_bank *banks; | |
109 | unsigned int num_banks; | |
110 | unsigned int pin_base; | |
111 | unsigned int num_pins; | |
112 | }; | |
113 | ||
114 | /** | |
115 | * struct meson_domain | |
116 | * | |
117 | * @reg_mux: registers for mux settings | |
118 | * @reg_pullen: registers for pull-enable settings | |
119 | * @reg_pull: registers for pull settings | |
120 | * @reg_gpio: registers for gpio settings | |
121 | * @chip: gpio chip associated with the domain | |
122 | * @data; platform data for the domain | |
123 | * @node: device tree node for the domain | |
124 | * | |
125 | * A domain represents a set of banks controlled by the same set of | |
126 | * registers. | |
127 | */ | |
128 | struct meson_domain { | |
129 | struct regmap *reg_mux; | |
130 | struct regmap *reg_pullen; | |
131 | struct regmap *reg_pull; | |
132 | struct regmap *reg_gpio; | |
133 | ||
134 | struct gpio_chip chip; | |
135 | struct meson_domain_data *data; | |
136 | struct device_node *of_node; | |
137 | }; | |
138 | ||
139 | struct meson_pinctrl_data { | |
140 | const struct pinctrl_pin_desc *pins; | |
141 | struct meson_pmx_group *groups; | |
142 | struct meson_pmx_func *funcs; | |
143 | struct meson_domain_data *domain_data; | |
144 | unsigned int num_pins; | |
145 | unsigned int num_groups; | |
146 | unsigned int num_funcs; | |
147 | unsigned int num_domains; | |
148 | }; | |
149 | ||
150 | struct meson_pinctrl { | |
151 | struct device *dev; | |
152 | struct pinctrl_dev *pcdev; | |
153 | struct pinctrl_desc desc; | |
154 | struct meson_pinctrl_data *data; | |
155 | struct meson_domain *domains; | |
156 | }; | |
157 | ||
0cf6f3c2 CC |
158 | #define PIN(x, b) (b + x) |
159 | ||
6ac73095 BG |
160 | #define GROUP(grp, r, b) \ |
161 | { \ | |
162 | .name = #grp, \ | |
163 | .pins = grp ## _pins, \ | |
164 | .num_pins = ARRAY_SIZE(grp ## _pins), \ | |
165 | .reg = r, \ | |
166 | .bit = b, \ | |
167 | .domain = 0, \ | |
168 | } | |
169 | ||
0cf6f3c2 | 170 | #define GPIO_GROUP(gpio, b) \ |
6ac73095 BG |
171 | { \ |
172 | .name = #gpio, \ | |
0cf6f3c2 | 173 | .pins = (const unsigned int[]){ PIN(gpio, b) }, \ |
6ac73095 BG |
174 | .num_pins = 1, \ |
175 | .is_gpio = true, \ | |
176 | } | |
177 | ||
178 | #define GROUP_AO(grp, r, b) \ | |
179 | { \ | |
180 | .name = #grp, \ | |
181 | .pins = grp ## _pins, \ | |
182 | .num_pins = ARRAY_SIZE(grp ## _pins), \ | |
183 | .reg = r, \ | |
184 | .bit = b, \ | |
185 | .domain = 1, \ | |
186 | } | |
187 | ||
188 | #define FUNCTION(fn) \ | |
189 | { \ | |
190 | .name = #fn, \ | |
191 | .groups = fn ## _groups, \ | |
192 | .num_groups = ARRAY_SIZE(fn ## _groups), \ | |
193 | } | |
194 | ||
195 | #define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib) \ | |
196 | { \ | |
197 | .name = n, \ | |
198 | .first = f, \ | |
199 | .last = l, \ | |
200 | .regs = { \ | |
201 | [REG_PULLEN] = { per, peb }, \ | |
202 | [REG_PULL] = { pr, pb }, \ | |
203 | [REG_DIR] = { dr, db }, \ | |
204 | [REG_OUT] = { or, ob }, \ | |
205 | [REG_IN] = { ir, ib }, \ | |
206 | }, \ | |
207 | } | |
208 | ||
0cf6f3c2 | 209 | #define MESON_PIN(x, b) PINCTRL_PIN(PIN(x, b), #x) |
6ac73095 BG |
210 | |
211 | extern struct meson_pinctrl_data meson8_pinctrl_data; | |
0fefcb68 | 212 | extern struct meson_pinctrl_data meson8b_pinctrl_data; |