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} |