|
13 | 13 | #include <linux/mfd/syscon.h>
|
14 | 14 | #include <linux/module.h>
|
15 | 15 | #include <linux/of.h>
|
| 16 | +#include <linux/pinctrl/pinctrl.h> |
| 17 | +#include <linux/pinctrl/pinconf-generic.h> |
| 18 | +#include <linux/pinctrl/pinmux.h> |
16 | 19 | #include <linux/platform_device.h>
|
17 | 20 | #include <linux/pm_wakeirq.h>
|
18 | 21 | #include <linux/regmap.h>
|
|
107 | 110 | /* STM32 RTC driver time helpers */
|
108 | 111 | #define SEC_PER_DAY (24 * 60 * 60)
|
109 | 112 |
|
| 113 | +/* STM32 RTC pinctrl helpers */ |
| 114 | +#define STM32_RTC_PINMUX(_name, _action, ...) { \ |
| 115 | + .name = (_name), \ |
| 116 | + .action = (_action), \ |
| 117 | + .groups = ((const char *[]){ __VA_ARGS__ }), \ |
| 118 | + .num_groups = ARRAY_SIZE(((const char *[]){ __VA_ARGS__ })), \ |
| 119 | +} |
| 120 | + |
110 | 121 | struct stm32_rtc;
|
111 | 122 |
|
112 | 123 | struct stm32_rtc_registers {
|
@@ -171,6 +182,106 @@ static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
|
171 | 182 | writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);
|
172 | 183 | }
|
173 | 184 |
|
| 185 | +enum stm32_rtc_pin_name { |
| 186 | + NONE, |
| 187 | + OUT1, |
| 188 | + OUT2, |
| 189 | + OUT2_RMP |
| 190 | +}; |
| 191 | + |
| 192 | +static const struct pinctrl_pin_desc stm32_rtc_pinctrl_pins[] = { |
| 193 | + PINCTRL_PIN(OUT1, "out1"), |
| 194 | + PINCTRL_PIN(OUT2, "out2"), |
| 195 | + PINCTRL_PIN(OUT2_RMP, "out2_rmp"), |
| 196 | +}; |
| 197 | + |
| 198 | +static int stm32_rtc_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) |
| 199 | +{ |
| 200 | + return ARRAY_SIZE(stm32_rtc_pinctrl_pins); |
| 201 | +} |
| 202 | + |
| 203 | +static const char *stm32_rtc_pinctrl_get_group_name(struct pinctrl_dev *pctldev, |
| 204 | + unsigned int selector) |
| 205 | +{ |
| 206 | + return stm32_rtc_pinctrl_pins[selector].name; |
| 207 | +} |
| 208 | + |
| 209 | +static int stm32_rtc_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, |
| 210 | + unsigned int selector, |
| 211 | + const unsigned int **pins, |
| 212 | + unsigned int *num_pins) |
| 213 | +{ |
| 214 | + *pins = &stm32_rtc_pinctrl_pins[selector].number; |
| 215 | + *num_pins = 1; |
| 216 | + return 0; |
| 217 | +} |
| 218 | + |
| 219 | +static const struct pinctrl_ops stm32_rtc_pinctrl_ops = { |
| 220 | + .dt_node_to_map = pinconf_generic_dt_node_to_map_all, |
| 221 | + .dt_free_map = pinconf_generic_dt_free_map, |
| 222 | + .get_groups_count = stm32_rtc_pinctrl_get_groups_count, |
| 223 | + .get_group_name = stm32_rtc_pinctrl_get_group_name, |
| 224 | + .get_group_pins = stm32_rtc_pinctrl_get_group_pins, |
| 225 | +}; |
| 226 | + |
| 227 | +struct stm32_rtc_pinmux_func { |
| 228 | + const char *name; |
| 229 | + const char * const *groups; |
| 230 | + const unsigned int num_groups; |
| 231 | + int (*action)(struct pinctrl_dev *pctl_dev, unsigned int pin); |
| 232 | +}; |
| 233 | + |
| 234 | +static const struct stm32_rtc_pinmux_func stm32_rtc_pinmux_functions[] = { |
| 235 | +}; |
| 236 | + |
| 237 | +static int stm32_rtc_pinmux_get_functions_count(struct pinctrl_dev *pctldev) |
| 238 | +{ |
| 239 | + return ARRAY_SIZE(stm32_rtc_pinmux_functions); |
| 240 | +} |
| 241 | + |
| 242 | +static const char *stm32_rtc_pinmux_get_fname(struct pinctrl_dev *pctldev, unsigned int selector) |
| 243 | +{ |
| 244 | + return stm32_rtc_pinmux_functions[selector].name; |
| 245 | +} |
| 246 | + |
| 247 | +static int stm32_rtc_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned int selector, |
| 248 | + const char * const **groups, unsigned int * const num_groups) |
| 249 | +{ |
| 250 | + *groups = stm32_rtc_pinmux_functions[selector].groups; |
| 251 | + *num_groups = stm32_rtc_pinmux_functions[selector].num_groups; |
| 252 | + return 0; |
| 253 | +} |
| 254 | + |
| 255 | +static int stm32_rtc_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int selector, |
| 256 | + unsigned int group) |
| 257 | +{ |
| 258 | + struct stm32_rtc_pinmux_func selected_func = stm32_rtc_pinmux_functions[selector]; |
| 259 | + struct pinctrl_pin_desc pin = stm32_rtc_pinctrl_pins[group]; |
| 260 | + |
| 261 | + /* Call action */ |
| 262 | + if (selected_func.action) |
| 263 | + return selected_func.action(pctldev, pin.number); |
| 264 | + |
| 265 | + return -EINVAL; |
| 266 | +} |
| 267 | + |
| 268 | +static const struct pinmux_ops stm32_rtc_pinmux_ops = { |
| 269 | + .get_functions_count = stm32_rtc_pinmux_get_functions_count, |
| 270 | + .get_function_name = stm32_rtc_pinmux_get_fname, |
| 271 | + .get_function_groups = stm32_rtc_pinmux_get_groups, |
| 272 | + .set_mux = stm32_rtc_pinmux_set_mux, |
| 273 | + .strict = true, |
| 274 | +}; |
| 275 | + |
| 276 | +static struct pinctrl_desc stm32_rtc_pdesc = { |
| 277 | + .name = DRIVER_NAME, |
| 278 | + .pins = stm32_rtc_pinctrl_pins, |
| 279 | + .npins = ARRAY_SIZE(stm32_rtc_pinctrl_pins), |
| 280 | + .owner = THIS_MODULE, |
| 281 | + .pctlops = &stm32_rtc_pinctrl_ops, |
| 282 | + .pmxops = &stm32_rtc_pinmux_ops, |
| 283 | +}; |
| 284 | + |
174 | 285 | static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
|
175 | 286 | {
|
176 | 287 | const struct stm32_rtc_registers *regs = &rtc->data->regs;
|
@@ -791,6 +902,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
|
791 | 902 | {
|
792 | 903 | struct stm32_rtc *rtc;
|
793 | 904 | const struct stm32_rtc_registers *regs;
|
| 905 | + struct pinctrl_dev *pctl; |
794 | 906 | int ret;
|
795 | 907 |
|
796 | 908 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
|
@@ -912,6 +1024,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
|
912 | 1024 | goto err;
|
913 | 1025 | }
|
914 | 1026 |
|
| 1027 | + ret = devm_pinctrl_register_and_init(&pdev->dev, &stm32_rtc_pdesc, rtc, &pctl); |
| 1028 | + if (ret) |
| 1029 | + return dev_err_probe(&pdev->dev, ret, "pinctrl register failed"); |
| 1030 | + |
| 1031 | + ret = pinctrl_enable(pctl); |
| 1032 | + if (ret) |
| 1033 | + return dev_err_probe(&pdev->dev, ret, "pinctrl enable failed"); |
| 1034 | + |
915 | 1035 | /*
|
916 | 1036 | * If INITS flag is reset (calendar year field set to 0x00), calendar
|
917 | 1037 | * must be initialized
|
|
0 commit comments