2 * First generation of pinmux driver for Amlogic Meson SoCs
4 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
5 * Copyright (C) 2017 Jerome Brunet <jbrunet@baylibre.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
11 * You should have received a copy of the GNU General Public License
12 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 /* For this first generation of pinctrl driver every pinmux group can be
16 * enabled by a specific bit in the first register range. When all groups for
17 * a given pin are disabled the pin acts as a GPIO.
19 #include <linux/device.h>
20 #include <linux/regmap.h>
21 #include <linux/pinctrl/pinctrl.h>
22 #include <linux/pinctrl/pinmux.h>
24 #include "pinctrl-meson.h"
25 #include "pinctrl-meson8-pmx.h"
28 * meson8_pmx_disable_other_groups() - disable other groups using a given pin
30 * @pc: meson pin controller device
31 * @pin: number of the pin
32 * @sel_group: index of the selected group, or -1 if none
34 * The function disables all pinmux groups using a pin except the
35 * selected one. If @sel_group is -1 all groups are disabled, leaving
36 * the pin in GPIO mode.
38 static void meson8_pmx_disable_other_groups(struct meson_pinctrl
*pc
,
39 unsigned int pin
, int sel_group
)
41 struct meson_pmx_group
*group
;
42 struct meson8_pmx_data
*pmx_data
;
45 for (i
= 0; i
< pc
->data
->num_groups
; i
++) {
46 group
= &pc
->data
->groups
[i
];
47 pmx_data
= (struct meson8_pmx_data
*)group
->data
;
48 if (pmx_data
->is_gpio
|| i
== sel_group
)
51 for (j
= 0; j
< group
->num_pins
; j
++) {
52 if (group
->pins
[j
] == pin
) {
53 /* We have found a group using the pin */
54 regmap_update_bits(pc
->reg_mux
,
56 BIT(pmx_data
->bit
), 0);
62 static int meson8_pmx_set_mux(struct pinctrl_dev
*pcdev
, unsigned func_num
,
65 struct meson_pinctrl
*pc
= pinctrl_dev_get_drvdata(pcdev
);
66 struct meson_pmx_func
*func
= &pc
->data
->funcs
[func_num
];
67 struct meson_pmx_group
*group
= &pc
->data
->groups
[group_num
];
68 struct meson8_pmx_data
*pmx_data
=
69 (struct meson8_pmx_data
*)group
->data
;
72 dev_dbg(pc
->dev
, "enable function %s, group %s\n", func
->name
,
76 * Disable groups using the same pin.
77 * The selected group is not disabled to avoid glitches.
79 for (i
= 0; i
< group
->num_pins
; i
++)
80 meson8_pmx_disable_other_groups(pc
, group
->pins
[i
], group_num
);
82 /* Function 0 (GPIO) doesn't need any additional setting */
84 ret
= regmap_update_bits(pc
->reg_mux
, pmx_data
->reg
* 4,
91 static int meson8_pmx_request_gpio(struct pinctrl_dev
*pcdev
,
92 struct pinctrl_gpio_range
*range
,
95 struct meson_pinctrl
*pc
= pinctrl_dev_get_drvdata(pcdev
);
97 meson8_pmx_disable_other_groups(pc
, offset
, -1);
102 const struct pinmux_ops meson8_pmx_ops
= {
103 .set_mux
= meson8_pmx_set_mux
,
104 .get_functions_count
= meson_pmx_get_funcs_count
,
105 .get_function_name
= meson_pmx_get_func_name
,
106 .get_function_groups
= meson_pmx_get_groups
,
107 .gpio_request_enable
= meson8_pmx_request_gpio
,