1 // SPDX-License-Identifier: GPL-2.0-only
3 * First generation of pinmux driver for Amlogic Meson SoCs
5 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
6 * Copyright (C) 2017 Jerome Brunet <jbrunet@baylibre.com>
9 /* For this first generation of pinctrl driver every pinmux group can be
10 * enabled by a specific bit in the first register range. When all groups for
11 * a given pin are disabled the pin acts as a GPIO.
13 #include <linux/device.h>
14 #include <linux/regmap.h>
15 #include <linux/pinctrl/pinctrl.h>
16 #include <linux/pinctrl/pinmux.h>
18 #include "pinctrl-meson.h"
19 #include "pinctrl-meson8-pmx.h"
22 * meson8_pmx_disable_other_groups() - disable other groups using a given pin
24 * @pc: meson pin controller device
25 * @pin: number of the pin
26 * @sel_group: index of the selected group, or -1 if none
28 * The function disables all pinmux groups using a pin except the
29 * selected one. If @sel_group is -1 all groups are disabled, leaving
30 * the pin in GPIO mode.
32 static void meson8_pmx_disable_other_groups(struct meson_pinctrl
*pc
,
33 unsigned int pin
, int sel_group
)
35 struct meson_pmx_group
*group
;
36 struct meson8_pmx_data
*pmx_data
;
39 for (i
= 0; i
< pc
->data
->num_groups
; i
++) {
40 group
= &pc
->data
->groups
[i
];
41 pmx_data
= (struct meson8_pmx_data
*)group
->data
;
42 if (pmx_data
->is_gpio
|| i
== sel_group
)
45 for (j
= 0; j
< group
->num_pins
; j
++) {
46 if (group
->pins
[j
] == pin
) {
47 /* We have found a group using the pin */
48 regmap_update_bits(pc
->reg_mux
,
50 BIT(pmx_data
->bit
), 0);
56 static int meson8_pmx_set_mux(struct pinctrl_dev
*pcdev
, unsigned func_num
,
59 struct meson_pinctrl
*pc
= pinctrl_dev_get_drvdata(pcdev
);
60 struct meson_pmx_func
*func
= &pc
->data
->funcs
[func_num
];
61 struct meson_pmx_group
*group
= &pc
->data
->groups
[group_num
];
62 struct meson8_pmx_data
*pmx_data
=
63 (struct meson8_pmx_data
*)group
->data
;
66 dev_dbg(pc
->dev
, "enable function %s, group %s\n", func
->name
,
70 * Disable groups using the same pin.
71 * The selected group is not disabled to avoid glitches.
73 for (i
= 0; i
< group
->num_pins
; i
++)
74 meson8_pmx_disable_other_groups(pc
, group
->pins
[i
], group_num
);
76 /* Function 0 (GPIO) doesn't need any additional setting */
78 ret
= regmap_update_bits(pc
->reg_mux
, pmx_data
->reg
* 4,
85 static int meson8_pmx_request_gpio(struct pinctrl_dev
*pcdev
,
86 struct pinctrl_gpio_range
*range
,
89 struct meson_pinctrl
*pc
= pinctrl_dev_get_drvdata(pcdev
);
91 meson8_pmx_disable_other_groups(pc
, offset
, -1);
96 const struct pinmux_ops meson8_pmx_ops
= {
97 .set_mux
= meson8_pmx_set_mux
,
98 .get_functions_count
= meson_pmx_get_funcs_count
,
99 .get_function_name
= meson_pmx_get_func_name
,
100 .get_function_groups
= meson_pmx_get_groups
,
101 .gpio_request_enable
= meson8_pmx_request_gpio
,
103 EXPORT_SYMBOL_GPL(meson8_pmx_ops
);
104 MODULE_LICENSE("GPL v2");