pinctrl-meson.c (277d14eb815fdfb95a72ea126bc09f75a2bd58fd) pinctrl-meson.c (ce385aa24a0dcccdc81dfcbc90cf7aa290d8b758)
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.

--- 17 unchanged lines hidden (view full) ---

26 * 1) pin muxing
27 * 2) pull enable/disable
28 * 3) pull up/down
29 * 4) GPIO direction, output value, input value
30 *
31 * In some cases the register ranges for pull enable and pull
32 * direction are the same and thus there are only 3 register ranges.
33 *
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.

--- 17 unchanged lines hidden (view full) ---

26 * 1) pin muxing
27 * 2) pull enable/disable
28 * 3) pull up/down
29 * 4) GPIO direction, output value, input value
30 *
31 * In some cases the register ranges for pull enable and pull
32 * direction are the same and thus there are only 3 register ranges.
33 *
34 * Every pinmux group can be enabled by a specific bit in the first
35 * register range; when all groups for a given pin are disabled the
36 * pin acts as a GPIO.
37 *
38 * For the pull and GPIO configuration every bank uses a contiguous
39 * set of bits in the register sets described above; the same register
40 * can be shared by more banks with different offsets.
41 *
42 * In addition to this there are some registers shared between all
43 * banks that control the IRQ functionality. This feature is not
44 * supported at the moment by the driver.
45 */

--- 97 unchanged lines hidden (view full) ---

143 .get_groups_count = meson_get_groups_count,
144 .get_group_name = meson_get_group_name,
145 .get_group_pins = meson_get_group_pins,
146 .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
147 .dt_free_map = pinctrl_utils_free_map,
148 .pin_dbg_show = meson_pin_dbg_show,
149};
150
34 * For the pull and GPIO configuration every bank uses a contiguous
35 * set of bits in the register sets described above; the same register
36 * can be shared by more banks with different offsets.
37 *
38 * In addition to this there are some registers shared between all
39 * banks that control the IRQ functionality. This feature is not
40 * supported at the moment by the driver.
41 */

--- 97 unchanged lines hidden (view full) ---

139 .get_groups_count = meson_get_groups_count,
140 .get_group_name = meson_get_group_name,
141 .get_group_pins = meson_get_group_pins,
142 .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
143 .dt_free_map = pinctrl_utils_free_map,
144 .pin_dbg_show = meson_pin_dbg_show,
145};
146
151/**
152 * meson_pmx_disable_other_groups() - disable other groups using a given pin
153 *
154 * @pc: meson pin controller device
155 * @pin: number of the pin
156 * @sel_group: index of the selected group, or -1 if none
157 *
158 * The function disables all pinmux groups using a pin except the
159 * selected one. If @sel_group is -1 all groups are disabled, leaving
160 * the pin in GPIO mode.
161 */
162static void meson_pmx_disable_other_groups(struct meson_pinctrl *pc,
163 unsigned int pin, int sel_group)
147int meson_pmx_get_funcs_count(struct pinctrl_dev *pcdev)
164{
148{
165 struct meson_pmx_group *group;
166 int i, j;
167
168 for (i = 0; i < pc->data->num_groups; i++) {
169 group = &pc->data->groups[i];
170 if (group->is_gpio || i == sel_group)
171 continue;
172
173 for (j = 0; j < group->num_pins; j++) {
174 if (group->pins[j] == pin) {
175 /* We have found a group using the pin */
176 regmap_update_bits(pc->reg_mux,
177 group->reg * 4,
178 BIT(group->bit), 0);
179 }
180 }
181 }
182}
183
184static int meson_pmx_set_mux(struct pinctrl_dev *pcdev, unsigned func_num,
185 unsigned group_num)
186{
187 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
149 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
188 struct meson_pmx_func *func = &pc->data->funcs[func_num];
189 struct meson_pmx_group *group = &pc->data->groups[group_num];
190 int i, ret = 0;
191
150
192 dev_dbg(pc->dev, "enable function %s, group %s\n", func->name,
193 group->name);
194
195 /*
196 * Disable groups using the same pin.
197 * The selected group is not disabled to avoid glitches.
198 */
199 for (i = 0; i < group->num_pins; i++)
200 meson_pmx_disable_other_groups(pc, group->pins[i], group_num);
201
202 /* Function 0 (GPIO) doesn't need any additional setting */
203 if (func_num)
204 ret = regmap_update_bits(pc->reg_mux, group->reg * 4,
205 BIT(group->bit), BIT(group->bit));
206
207 return ret;
208}
209
210static int meson_pmx_request_gpio(struct pinctrl_dev *pcdev,
211 struct pinctrl_gpio_range *range,
212 unsigned offset)
213{
214 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
215
216 meson_pmx_disable_other_groups(pc, offset, -1);
217
218 return 0;
219}
220
221static int meson_pmx_get_funcs_count(struct pinctrl_dev *pcdev)
222{
223 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
224
225 return pc->data->num_funcs;
226}
227
151 return pc->data->num_funcs;
152}
153
228static const char *meson_pmx_get_func_name(struct pinctrl_dev *pcdev,
229 unsigned selector)
154const char *meson_pmx_get_func_name(struct pinctrl_dev *pcdev,
155 unsigned selector)
230{
231 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
232
233 return pc->data->funcs[selector].name;
234}
235
156{
157 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
158
159 return pc->data->funcs[selector].name;
160}
161
236static int meson_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned selector,
237 const char * const **groups,
238 unsigned * const num_groups)
162int meson_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned selector,
163 const char * const **groups,
164 unsigned * const num_groups)
239{
240 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
241
242 *groups = pc->data->funcs[selector].groups;
243 *num_groups = pc->data->funcs[selector].num_groups;
244
245 return 0;
246}
247
165{
166 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
167
168 *groups = pc->data->funcs[selector].groups;
169 *num_groups = pc->data->funcs[selector].num_groups;
170
171 return 0;
172}
173
248static const struct pinmux_ops meson_pmx_ops = {
249 .set_mux = meson_pmx_set_mux,
250 .get_functions_count = meson_pmx_get_funcs_count,
251 .get_function_name = meson_pmx_get_func_name,
252 .get_function_groups = meson_pmx_get_groups,
253 .gpio_request_enable = meson_pmx_request_gpio,
254};
255
256static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
257 unsigned long *configs, unsigned num_configs)
258{
259 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
260 struct meson_bank *bank;
261 enum pin_config_param param;
262 unsigned int reg, bit;
263 int i, ret;

--- 340 unchanged lines hidden (view full) ---

604
605 ret = meson_pinctrl_parse_dt(pc, dev->of_node);
606 if (ret)
607 return ret;
608
609 pc->desc.name = "pinctrl-meson";
610 pc->desc.owner = THIS_MODULE;
611 pc->desc.pctlops = &meson_pctrl_ops;
174static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
175 unsigned long *configs, unsigned num_configs)
176{
177 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
178 struct meson_bank *bank;
179 enum pin_config_param param;
180 unsigned int reg, bit;
181 int i, ret;

--- 340 unchanged lines hidden (view full) ---

522
523 ret = meson_pinctrl_parse_dt(pc, dev->of_node);
524 if (ret)
525 return ret;
526
527 pc->desc.name = "pinctrl-meson";
528 pc->desc.owner = THIS_MODULE;
529 pc->desc.pctlops = &meson_pctrl_ops;
612 pc->desc.pmxops = &meson_pmx_ops;
530 pc->desc.pmxops = pc->data->pmx_ops;
613 pc->desc.confops = &meson_pinconf_ops;
614 pc->desc.pins = pc->data->pins;
615 pc->desc.npins = pc->data->num_pins;
616
617 pc->pcdev = devm_pinctrl_register(pc->dev, &pc->desc, pc);
618 if (IS_ERR(pc->pcdev)) {
619 dev_err(pc->dev, "can't register pinctrl device");
620 return PTR_ERR(pc->pcdev);
621 }
622
623 return meson_gpiolib_register(pc);
624}
531 pc->desc.confops = &meson_pinconf_ops;
532 pc->desc.pins = pc->data->pins;
533 pc->desc.npins = pc->data->num_pins;
534
535 pc->pcdev = devm_pinctrl_register(pc->dev, &pc->desc, pc);
536 if (IS_ERR(pc->pcdev)) {
537 dev_err(pc->dev, "can't register pinctrl device");
538 return PTR_ERR(pc->pcdev);
539 }
540
541 return meson_gpiolib_register(pc);
542}