1170c6152STony Prisk /* 2170c6152STony Prisk * Pinctrl driver for the Wondermedia SoC's 3170c6152STony Prisk * 4170c6152STony Prisk * Copyright (c) 2013 Tony Prisk <linux@prisktech.co.nz> 5170c6152STony Prisk * 6170c6152STony Prisk * This program is free software; you can redistribute it and/or modify it 7170c6152STony Prisk * under the terms and conditions of the GNU General Public License, 8170c6152STony Prisk * version 2, as published by the Free Software Foundation. 9170c6152STony Prisk * 10170c6152STony Prisk * This program is distributed in the hope it will be useful, but WITHOUT 11170c6152STony Prisk * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12170c6152STony Prisk * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13170c6152STony Prisk * more details. 14170c6152STony Prisk */ 15170c6152STony Prisk 16170c6152STony Prisk #include <linux/err.h> 175c809c63SLinus Walleij #include <linux/gpio/driver.h> 18170c6152STony Prisk #include <linux/interrupt.h> 19170c6152STony Prisk #include <linux/io.h> 20170c6152STony Prisk #include <linux/irq.h> 21170c6152STony Prisk #include <linux/module.h> 22170c6152STony Prisk #include <linux/of.h> 23170c6152STony Prisk #include <linux/of_irq.h> 24170c6152STony Prisk #include <linux/pinctrl/consumer.h> 25170c6152STony Prisk #include <linux/pinctrl/machine.h> 26170c6152STony Prisk #include <linux/pinctrl/pinconf.h> 27170c6152STony Prisk #include <linux/pinctrl/pinconf-generic.h> 28170c6152STony Prisk #include <linux/pinctrl/pinctrl.h> 29170c6152STony Prisk #include <linux/pinctrl/pinmux.h> 30170c6152STony Prisk #include <linux/platform_device.h> 31170c6152STony Prisk #include <linux/slab.h> 32170c6152STony Prisk 33170c6152STony Prisk #include "pinctrl-wmt.h" 34170c6152STony Prisk 35170c6152STony Prisk static inline void wmt_setbits(struct wmt_pinctrl_data *data, u32 reg, 36170c6152STony Prisk u32 mask) 37170c6152STony Prisk { 38170c6152STony Prisk u32 val; 39170c6152STony Prisk 40170c6152STony Prisk val = readl_relaxed(data->base + reg); 41170c6152STony Prisk val |= mask; 42170c6152STony Prisk writel_relaxed(val, data->base + reg); 43170c6152STony Prisk } 44170c6152STony Prisk 45170c6152STony Prisk static inline void wmt_clearbits(struct wmt_pinctrl_data *data, u32 reg, 46170c6152STony Prisk u32 mask) 47170c6152STony Prisk { 48170c6152STony Prisk u32 val; 49170c6152STony Prisk 50170c6152STony Prisk val = readl_relaxed(data->base + reg); 51170c6152STony Prisk val &= ~mask; 52170c6152STony Prisk writel_relaxed(val, data->base + reg); 53170c6152STony Prisk } 54170c6152STony Prisk 55170c6152STony Prisk enum wmt_func_sel { 56170c6152STony Prisk WMT_FSEL_GPIO_IN = 0, 57170c6152STony Prisk WMT_FSEL_GPIO_OUT = 1, 58170c6152STony Prisk WMT_FSEL_ALT = 2, 59170c6152STony Prisk WMT_FSEL_COUNT = 3, 60170c6152STony Prisk }; 61170c6152STony Prisk 62170c6152STony Prisk static const char * const wmt_functions[WMT_FSEL_COUNT] = { 63170c6152STony Prisk [WMT_FSEL_GPIO_IN] = "gpio_in", 64170c6152STony Prisk [WMT_FSEL_GPIO_OUT] = "gpio_out", 65170c6152STony Prisk [WMT_FSEL_ALT] = "alt", 66170c6152STony Prisk }; 67170c6152STony Prisk 68170c6152STony Prisk static int wmt_pmx_get_functions_count(struct pinctrl_dev *pctldev) 69170c6152STony Prisk { 70170c6152STony Prisk return WMT_FSEL_COUNT; 71170c6152STony Prisk } 72170c6152STony Prisk 73170c6152STony Prisk static const char *wmt_pmx_get_function_name(struct pinctrl_dev *pctldev, 74170c6152STony Prisk unsigned selector) 75170c6152STony Prisk { 76170c6152STony Prisk return wmt_functions[selector]; 77170c6152STony Prisk } 78170c6152STony Prisk 79170c6152STony Prisk static int wmt_pmx_get_function_groups(struct pinctrl_dev *pctldev, 80170c6152STony Prisk unsigned selector, 81170c6152STony Prisk const char * const **groups, 82170c6152STony Prisk unsigned * const num_groups) 83170c6152STony Prisk { 84170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 85170c6152STony Prisk 86170c6152STony Prisk /* every pin does every function */ 87170c6152STony Prisk *groups = data->groups; 88170c6152STony Prisk *num_groups = data->ngroups; 89170c6152STony Prisk 90170c6152STony Prisk return 0; 91170c6152STony Prisk } 92170c6152STony Prisk 93170c6152STony Prisk static int wmt_set_pinmux(struct wmt_pinctrl_data *data, unsigned func, 94170c6152STony Prisk unsigned pin) 95170c6152STony Prisk { 96170c6152STony Prisk u32 bank = WMT_BANK_FROM_PIN(pin); 97170c6152STony Prisk u32 bit = WMT_BIT_FROM_PIN(pin); 98170c6152STony Prisk u32 reg_en = data->banks[bank].reg_en; 99170c6152STony Prisk u32 reg_dir = data->banks[bank].reg_dir; 100170c6152STony Prisk 101170c6152STony Prisk if (reg_dir == NO_REG) { 102170c6152STony Prisk dev_err(data->dev, "pin:%d no direction register defined\n", 103170c6152STony Prisk pin); 104170c6152STony Prisk return -EINVAL; 105170c6152STony Prisk } 106170c6152STony Prisk 107170c6152STony Prisk /* 108170c6152STony Prisk * If reg_en == NO_REG, we assume it is a dedicated GPIO and cannot be 109170c6152STony Prisk * disabled (as on VT8500) and that no alternate function is available. 110170c6152STony Prisk */ 111170c6152STony Prisk switch (func) { 112170c6152STony Prisk case WMT_FSEL_GPIO_IN: 113170c6152STony Prisk if (reg_en != NO_REG) 114170c6152STony Prisk wmt_setbits(data, reg_en, BIT(bit)); 115170c6152STony Prisk wmt_clearbits(data, reg_dir, BIT(bit)); 116170c6152STony Prisk break; 117170c6152STony Prisk case WMT_FSEL_GPIO_OUT: 118170c6152STony Prisk if (reg_en != NO_REG) 119170c6152STony Prisk wmt_setbits(data, reg_en, BIT(bit)); 120170c6152STony Prisk wmt_setbits(data, reg_dir, BIT(bit)); 121170c6152STony Prisk break; 122170c6152STony Prisk case WMT_FSEL_ALT: 123170c6152STony Prisk if (reg_en == NO_REG) { 124170c6152STony Prisk dev_err(data->dev, "pin:%d no alt function available\n", 125170c6152STony Prisk pin); 126170c6152STony Prisk return -EINVAL; 127170c6152STony Prisk } 128170c6152STony Prisk wmt_clearbits(data, reg_en, BIT(bit)); 129170c6152STony Prisk } 130170c6152STony Prisk 131170c6152STony Prisk return 0; 132170c6152STony Prisk } 133170c6152STony Prisk 13403e9f0caSLinus Walleij static int wmt_pmx_set_mux(struct pinctrl_dev *pctldev, 135170c6152STony Prisk unsigned func_selector, 136170c6152STony Prisk unsigned group_selector) 137170c6152STony Prisk { 138170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 139170c6152STony Prisk u32 pinnum = data->pins[group_selector].number; 140170c6152STony Prisk 141170c6152STony Prisk return wmt_set_pinmux(data, func_selector, pinnum); 142170c6152STony Prisk } 143170c6152STony Prisk 144170c6152STony Prisk static void wmt_pmx_gpio_disable_free(struct pinctrl_dev *pctldev, 145170c6152STony Prisk struct pinctrl_gpio_range *range, 146170c6152STony Prisk unsigned offset) 147170c6152STony Prisk { 148170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 149170c6152STony Prisk 150170c6152STony Prisk /* disable by setting GPIO_IN */ 151170c6152STony Prisk wmt_set_pinmux(data, WMT_FSEL_GPIO_IN, offset); 152170c6152STony Prisk } 153170c6152STony Prisk 154170c6152STony Prisk static int wmt_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, 155170c6152STony Prisk struct pinctrl_gpio_range *range, 156170c6152STony Prisk unsigned offset, 157170c6152STony Prisk bool input) 158170c6152STony Prisk { 159170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 160170c6152STony Prisk 161170c6152STony Prisk wmt_set_pinmux(data, (input ? WMT_FSEL_GPIO_IN : WMT_FSEL_GPIO_OUT), 162170c6152STony Prisk offset); 163170c6152STony Prisk 164170c6152STony Prisk return 0; 165170c6152STony Prisk } 166170c6152STony Prisk 167170c6152STony Prisk static struct pinmux_ops wmt_pinmux_ops = { 168170c6152STony Prisk .get_functions_count = wmt_pmx_get_functions_count, 169170c6152STony Prisk .get_function_name = wmt_pmx_get_function_name, 170170c6152STony Prisk .get_function_groups = wmt_pmx_get_function_groups, 17103e9f0caSLinus Walleij .set_mux = wmt_pmx_set_mux, 172170c6152STony Prisk .gpio_disable_free = wmt_pmx_gpio_disable_free, 173170c6152STony Prisk .gpio_set_direction = wmt_pmx_gpio_set_direction, 174170c6152STony Prisk }; 175170c6152STony Prisk 176170c6152STony Prisk static int wmt_get_groups_count(struct pinctrl_dev *pctldev) 177170c6152STony Prisk { 178170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 179170c6152STony Prisk 180170c6152STony Prisk return data->ngroups; 181170c6152STony Prisk } 182170c6152STony Prisk 183170c6152STony Prisk static const char *wmt_get_group_name(struct pinctrl_dev *pctldev, 184170c6152STony Prisk unsigned selector) 185170c6152STony Prisk { 186170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 187170c6152STony Prisk 188170c6152STony Prisk return data->groups[selector]; 189170c6152STony Prisk } 190170c6152STony Prisk 191170c6152STony Prisk static int wmt_get_group_pins(struct pinctrl_dev *pctldev, 192170c6152STony Prisk unsigned selector, 193170c6152STony Prisk const unsigned **pins, 194170c6152STony Prisk unsigned *num_pins) 195170c6152STony Prisk { 196170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 197170c6152STony Prisk 198170c6152STony Prisk *pins = &data->pins[selector].number; 199170c6152STony Prisk *num_pins = 1; 200170c6152STony Prisk 201170c6152STony Prisk return 0; 202170c6152STony Prisk } 203170c6152STony Prisk 204170c6152STony Prisk static int wmt_pctl_find_group_by_pin(struct wmt_pinctrl_data *data, u32 pin) 205170c6152STony Prisk { 206170c6152STony Prisk int i; 207170c6152STony Prisk 208170c6152STony Prisk for (i = 0; i < data->npins; i++) { 209170c6152STony Prisk if (data->pins[i].number == pin) 210170c6152STony Prisk return i; 211170c6152STony Prisk } 212170c6152STony Prisk 213170c6152STony Prisk return -EINVAL; 214170c6152STony Prisk } 215170c6152STony Prisk 216170c6152STony Prisk static int wmt_pctl_dt_node_to_map_func(struct wmt_pinctrl_data *data, 217170c6152STony Prisk struct device_node *np, 218170c6152STony Prisk u32 pin, u32 fnum, 219170c6152STony Prisk struct pinctrl_map **maps) 220170c6152STony Prisk { 221170c6152STony Prisk int group; 222170c6152STony Prisk struct pinctrl_map *map = *maps; 223170c6152STony Prisk 224170c6152STony Prisk if (fnum >= ARRAY_SIZE(wmt_functions)) { 225170c6152STony Prisk dev_err(data->dev, "invalid wm,function %d\n", fnum); 226170c6152STony Prisk return -EINVAL; 227170c6152STony Prisk } 228170c6152STony Prisk 229170c6152STony Prisk group = wmt_pctl_find_group_by_pin(data, pin); 230170c6152STony Prisk if (group < 0) { 231170c6152STony Prisk dev_err(data->dev, "unable to match pin %d to group\n", pin); 232170c6152STony Prisk return group; 233170c6152STony Prisk } 234170c6152STony Prisk 235170c6152STony Prisk map->type = PIN_MAP_TYPE_MUX_GROUP; 236170c6152STony Prisk map->data.mux.group = data->groups[group]; 237170c6152STony Prisk map->data.mux.function = wmt_functions[fnum]; 238170c6152STony Prisk (*maps)++; 239170c6152STony Prisk 240170c6152STony Prisk return 0; 241170c6152STony Prisk } 242170c6152STony Prisk 243170c6152STony Prisk static int wmt_pctl_dt_node_to_map_pull(struct wmt_pinctrl_data *data, 244170c6152STony Prisk struct device_node *np, 245170c6152STony Prisk u32 pin, u32 pull, 246170c6152STony Prisk struct pinctrl_map **maps) 247170c6152STony Prisk { 248170c6152STony Prisk int group; 249170c6152STony Prisk unsigned long *configs; 250170c6152STony Prisk struct pinctrl_map *map = *maps; 251170c6152STony Prisk 252170c6152STony Prisk if (pull > 2) { 253170c6152STony Prisk dev_err(data->dev, "invalid wm,pull %d\n", pull); 254170c6152STony Prisk return -EINVAL; 255170c6152STony Prisk } 256170c6152STony Prisk 257170c6152STony Prisk group = wmt_pctl_find_group_by_pin(data, pin); 258170c6152STony Prisk if (group < 0) { 259170c6152STony Prisk dev_err(data->dev, "unable to match pin %d to group\n", pin); 260170c6152STony Prisk return group; 261170c6152STony Prisk } 262170c6152STony Prisk 263170c6152STony Prisk configs = kzalloc(sizeof(*configs), GFP_KERNEL); 264170c6152STony Prisk if (!configs) 265170c6152STony Prisk return -ENOMEM; 266170c6152STony Prisk 267f17248edSTony Prisk switch (pull) { 268f17248edSTony Prisk case 0: 269f17248edSTony Prisk configs[0] = PIN_CONFIG_BIAS_DISABLE; 270f17248edSTony Prisk break; 271f17248edSTony Prisk case 1: 272f17248edSTony Prisk configs[0] = PIN_CONFIG_BIAS_PULL_DOWN; 273f17248edSTony Prisk break; 274f17248edSTony Prisk case 2: 275f17248edSTony Prisk configs[0] = PIN_CONFIG_BIAS_PULL_UP; 276f17248edSTony Prisk break; 277f17248edSTony Prisk default: 278f17248edSTony Prisk configs[0] = PIN_CONFIG_BIAS_DISABLE; 279f17248edSTony Prisk dev_err(data->dev, "invalid pull state %d - disabling\n", pull); 280f17248edSTony Prisk } 281170c6152STony Prisk 282170c6152STony Prisk map->type = PIN_MAP_TYPE_CONFIGS_PIN; 283170c6152STony Prisk map->data.configs.group_or_pin = data->groups[group]; 284170c6152STony Prisk map->data.configs.configs = configs; 285170c6152STony Prisk map->data.configs.num_configs = 1; 286170c6152STony Prisk (*maps)++; 287170c6152STony Prisk 288170c6152STony Prisk return 0; 289170c6152STony Prisk } 290170c6152STony Prisk 291170c6152STony Prisk static void wmt_pctl_dt_free_map(struct pinctrl_dev *pctldev, 292170c6152STony Prisk struct pinctrl_map *maps, 293170c6152STony Prisk unsigned num_maps) 294170c6152STony Prisk { 295170c6152STony Prisk int i; 296170c6152STony Prisk 297170c6152STony Prisk for (i = 0; i < num_maps; i++) 298170c6152STony Prisk if (maps[i].type == PIN_MAP_TYPE_CONFIGS_PIN) 299170c6152STony Prisk kfree(maps[i].data.configs.configs); 300170c6152STony Prisk 301170c6152STony Prisk kfree(maps); 302170c6152STony Prisk } 303170c6152STony Prisk 304170c6152STony Prisk static int wmt_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, 305170c6152STony Prisk struct device_node *np, 306170c6152STony Prisk struct pinctrl_map **map, 307170c6152STony Prisk unsigned *num_maps) 308170c6152STony Prisk { 309170c6152STony Prisk struct pinctrl_map *maps, *cur_map; 310170c6152STony Prisk struct property *pins, *funcs, *pulls; 311170c6152STony Prisk u32 pin, func, pull; 312170c6152STony Prisk int num_pins, num_funcs, num_pulls, maps_per_pin; 313170c6152STony Prisk int i, err; 314170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 315170c6152STony Prisk 316170c6152STony Prisk pins = of_find_property(np, "wm,pins", NULL); 317170c6152STony Prisk if (!pins) { 318170c6152STony Prisk dev_err(data->dev, "missing wmt,pins property\n"); 319170c6152STony Prisk return -EINVAL; 320170c6152STony Prisk } 321170c6152STony Prisk 322170c6152STony Prisk funcs = of_find_property(np, "wm,function", NULL); 323170c6152STony Prisk pulls = of_find_property(np, "wm,pull", NULL); 324170c6152STony Prisk 325170c6152STony Prisk if (!funcs && !pulls) { 326170c6152STony Prisk dev_err(data->dev, "neither wm,function nor wm,pull specified\n"); 327170c6152STony Prisk return -EINVAL; 328170c6152STony Prisk } 329170c6152STony Prisk 330170c6152STony Prisk /* 331170c6152STony Prisk * The following lines calculate how many values are defined for each 332170c6152STony Prisk * of the properties. 333170c6152STony Prisk */ 334170c6152STony Prisk num_pins = pins->length / sizeof(u32); 335170c6152STony Prisk num_funcs = funcs ? (funcs->length / sizeof(u32)) : 0; 336170c6152STony Prisk num_pulls = pulls ? (pulls->length / sizeof(u32)) : 0; 337170c6152STony Prisk 338170c6152STony Prisk if (num_funcs > 1 && num_funcs != num_pins) { 339170c6152STony Prisk dev_err(data->dev, "wm,function must have 1 or %d entries\n", 340170c6152STony Prisk num_pins); 341170c6152STony Prisk return -EINVAL; 342170c6152STony Prisk } 343170c6152STony Prisk 344170c6152STony Prisk if (num_pulls > 1 && num_pulls != num_pins) { 345170c6152STony Prisk dev_err(data->dev, "wm,pull must have 1 or %d entries\n", 346170c6152STony Prisk num_pins); 347170c6152STony Prisk return -EINVAL; 348170c6152STony Prisk } 349170c6152STony Prisk 350170c6152STony Prisk maps_per_pin = 0; 351170c6152STony Prisk if (num_funcs) 352170c6152STony Prisk maps_per_pin++; 353170c6152STony Prisk if (num_pulls) 354170c6152STony Prisk maps_per_pin++; 355170c6152STony Prisk 356170c6152STony Prisk cur_map = maps = kzalloc(num_pins * maps_per_pin * sizeof(*maps), 357170c6152STony Prisk GFP_KERNEL); 358170c6152STony Prisk if (!maps) 359170c6152STony Prisk return -ENOMEM; 360170c6152STony Prisk 361170c6152STony Prisk for (i = 0; i < num_pins; i++) { 362170c6152STony Prisk err = of_property_read_u32_index(np, "wm,pins", i, &pin); 363170c6152STony Prisk if (err) 364170c6152STony Prisk goto fail; 365170c6152STony Prisk 366170c6152STony Prisk if (pin >= (data->nbanks * 32)) { 367170c6152STony Prisk dev_err(data->dev, "invalid wm,pins value\n"); 368170c6152STony Prisk err = -EINVAL; 369170c6152STony Prisk goto fail; 370170c6152STony Prisk } 371170c6152STony Prisk 372170c6152STony Prisk if (num_funcs) { 373170c6152STony Prisk err = of_property_read_u32_index(np, "wm,function", 374170c6152STony Prisk (num_funcs > 1 ? i : 0), &func); 375170c6152STony Prisk if (err) 376170c6152STony Prisk goto fail; 377170c6152STony Prisk 378170c6152STony Prisk err = wmt_pctl_dt_node_to_map_func(data, np, pin, func, 379170c6152STony Prisk &cur_map); 380170c6152STony Prisk if (err) 381170c6152STony Prisk goto fail; 382170c6152STony Prisk } 383170c6152STony Prisk 384170c6152STony Prisk if (num_pulls) { 385170c6152STony Prisk err = of_property_read_u32_index(np, "wm,pull", 386170c6152STony Prisk (num_pulls > 1 ? i : 0), &pull); 387170c6152STony Prisk if (err) 388170c6152STony Prisk goto fail; 389170c6152STony Prisk 390170c6152STony Prisk err = wmt_pctl_dt_node_to_map_pull(data, np, pin, pull, 391170c6152STony Prisk &cur_map); 392170c6152STony Prisk if (err) 393170c6152STony Prisk goto fail; 394170c6152STony Prisk } 395170c6152STony Prisk } 396170c6152STony Prisk *map = maps; 397170c6152STony Prisk *num_maps = num_pins * maps_per_pin; 398170c6152STony Prisk return 0; 399170c6152STony Prisk 400170c6152STony Prisk /* 401170c6152STony Prisk * The fail path removes any maps that have been allocated. The fail path is 402170c6152STony Prisk * only called from code after maps has been kzalloc'd. It is also safe to 403170c6152STony Prisk * pass 'num_pins * maps_per_pin' as the map count even though we probably 404170c6152STony Prisk * failed before all the mappings were read as all maps are allocated at once, 405170c6152STony Prisk * and configs are only allocated for .type = PIN_MAP_TYPE_CONFIGS_PIN - there 406170c6152STony Prisk * is no failpath where a config can be allocated without .type being set. 407170c6152STony Prisk */ 408170c6152STony Prisk fail: 409170c6152STony Prisk wmt_pctl_dt_free_map(pctldev, maps, num_pins * maps_per_pin); 410170c6152STony Prisk return err; 411170c6152STony Prisk } 412170c6152STony Prisk 413170c6152STony Prisk static struct pinctrl_ops wmt_pctl_ops = { 414170c6152STony Prisk .get_groups_count = wmt_get_groups_count, 415170c6152STony Prisk .get_group_name = wmt_get_group_name, 416170c6152STony Prisk .get_group_pins = wmt_get_group_pins, 417170c6152STony Prisk .dt_node_to_map = wmt_pctl_dt_node_to_map, 418170c6152STony Prisk .dt_free_map = wmt_pctl_dt_free_map, 419170c6152STony Prisk }; 420170c6152STony Prisk 421170c6152STony Prisk static int wmt_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, 422170c6152STony Prisk unsigned long *config) 423170c6152STony Prisk { 424170c6152STony Prisk return -ENOTSUPP; 425170c6152STony Prisk } 426170c6152STony Prisk 427170c6152STony Prisk static int wmt_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, 42803b054e9SSherman Yin unsigned long *configs, unsigned num_configs) 429170c6152STony Prisk { 430170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 43103b054e9SSherman Yin enum pin_config_param param; 43203b054e9SSherman Yin u16 arg; 433170c6152STony Prisk u32 bank = WMT_BANK_FROM_PIN(pin); 434170c6152STony Prisk u32 bit = WMT_BIT_FROM_PIN(pin); 435170c6152STony Prisk u32 reg_pull_en = data->banks[bank].reg_pull_en; 436170c6152STony Prisk u32 reg_pull_cfg = data->banks[bank].reg_pull_cfg; 43703b054e9SSherman Yin int i; 438170c6152STony Prisk 439170c6152STony Prisk if ((reg_pull_en == NO_REG) || (reg_pull_cfg == NO_REG)) { 440170c6152STony Prisk dev_err(data->dev, "bias functions not supported on pin %d\n", 441170c6152STony Prisk pin); 442170c6152STony Prisk return -EINVAL; 443170c6152STony Prisk } 444170c6152STony Prisk 44503b054e9SSherman Yin for (i = 0; i < num_configs; i++) { 44603b054e9SSherman Yin param = pinconf_to_config_param(configs[i]); 44703b054e9SSherman Yin arg = pinconf_to_config_argument(configs[i]); 44803b054e9SSherman Yin 449170c6152STony Prisk if ((param == PIN_CONFIG_BIAS_PULL_DOWN) || 450170c6152STony Prisk (param == PIN_CONFIG_BIAS_PULL_UP)) { 451170c6152STony Prisk if (arg == 0) 452170c6152STony Prisk param = PIN_CONFIG_BIAS_DISABLE; 453170c6152STony Prisk } 454170c6152STony Prisk 455170c6152STony Prisk switch (param) { 456170c6152STony Prisk case PIN_CONFIG_BIAS_DISABLE: 457170c6152STony Prisk wmt_clearbits(data, reg_pull_en, BIT(bit)); 458170c6152STony Prisk break; 459170c6152STony Prisk case PIN_CONFIG_BIAS_PULL_DOWN: 460170c6152STony Prisk wmt_clearbits(data, reg_pull_cfg, BIT(bit)); 461170c6152STony Prisk wmt_setbits(data, reg_pull_en, BIT(bit)); 462170c6152STony Prisk break; 463170c6152STony Prisk case PIN_CONFIG_BIAS_PULL_UP: 464170c6152STony Prisk wmt_setbits(data, reg_pull_cfg, BIT(bit)); 465170c6152STony Prisk wmt_setbits(data, reg_pull_en, BIT(bit)); 466170c6152STony Prisk break; 467170c6152STony Prisk default: 468170c6152STony Prisk dev_err(data->dev, "unknown pinconf param\n"); 469170c6152STony Prisk return -EINVAL; 470170c6152STony Prisk } 47103b054e9SSherman Yin } /* for each config */ 472170c6152STony Prisk 473170c6152STony Prisk return 0; 474170c6152STony Prisk } 475170c6152STony Prisk 476170c6152STony Prisk static struct pinconf_ops wmt_pinconf_ops = { 477170c6152STony Prisk .pin_config_get = wmt_pinconf_get, 478170c6152STony Prisk .pin_config_set = wmt_pinconf_set, 479170c6152STony Prisk }; 480170c6152STony Prisk 481170c6152STony Prisk static struct pinctrl_desc wmt_desc = { 482170c6152STony Prisk .owner = THIS_MODULE, 483170c6152STony Prisk .name = "pinctrl-wmt", 484170c6152STony Prisk .pctlops = &wmt_pctl_ops, 485170c6152STony Prisk .pmxops = &wmt_pinmux_ops, 486170c6152STony Prisk .confops = &wmt_pinconf_ops, 487170c6152STony Prisk }; 488170c6152STony Prisk 489170c6152STony Prisk static int wmt_gpio_get_direction(struct gpio_chip *chip, unsigned offset) 490170c6152STony Prisk { 4915c809c63SLinus Walleij struct wmt_pinctrl_data *data = gpiochip_get_data(chip); 492170c6152STony Prisk u32 bank = WMT_BANK_FROM_PIN(offset); 493170c6152STony Prisk u32 bit = WMT_BIT_FROM_PIN(offset); 494170c6152STony Prisk u32 reg_dir = data->banks[bank].reg_dir; 495170c6152STony Prisk u32 val; 496170c6152STony Prisk 497170c6152STony Prisk val = readl_relaxed(data->base + reg_dir); 498170c6152STony Prisk if (val & BIT(bit)) 499170c6152STony Prisk return GPIOF_DIR_OUT; 500170c6152STony Prisk else 501170c6152STony Prisk return GPIOF_DIR_IN; 502170c6152STony Prisk } 503170c6152STony Prisk 504170c6152STony Prisk static int wmt_gpio_get_value(struct gpio_chip *chip, unsigned offset) 505170c6152STony Prisk { 5065c809c63SLinus Walleij struct wmt_pinctrl_data *data = gpiochip_get_data(chip); 507170c6152STony Prisk u32 bank = WMT_BANK_FROM_PIN(offset); 508170c6152STony Prisk u32 bit = WMT_BIT_FROM_PIN(offset); 509170c6152STony Prisk u32 reg_data_in = data->banks[bank].reg_data_in; 510170c6152STony Prisk 511170c6152STony Prisk if (reg_data_in == NO_REG) { 512170c6152STony Prisk dev_err(data->dev, "no data in register defined\n"); 513170c6152STony Prisk return -EINVAL; 514170c6152STony Prisk } 515170c6152STony Prisk 516170c6152STony Prisk return !!(readl_relaxed(data->base + reg_data_in) & BIT(bit)); 517170c6152STony Prisk } 518170c6152STony Prisk 519170c6152STony Prisk static void wmt_gpio_set_value(struct gpio_chip *chip, unsigned offset, 520170c6152STony Prisk int val) 521170c6152STony Prisk { 5225c809c63SLinus Walleij struct wmt_pinctrl_data *data = gpiochip_get_data(chip); 523170c6152STony Prisk u32 bank = WMT_BANK_FROM_PIN(offset); 524170c6152STony Prisk u32 bit = WMT_BIT_FROM_PIN(offset); 525170c6152STony Prisk u32 reg_data_out = data->banks[bank].reg_data_out; 526170c6152STony Prisk 527170c6152STony Prisk if (reg_data_out == NO_REG) { 528170c6152STony Prisk dev_err(data->dev, "no data out register defined\n"); 529170c6152STony Prisk return; 530170c6152STony Prisk } 531170c6152STony Prisk 532170c6152STony Prisk if (val) 533170c6152STony Prisk wmt_setbits(data, reg_data_out, BIT(bit)); 534170c6152STony Prisk else 535170c6152STony Prisk wmt_clearbits(data, reg_data_out, BIT(bit)); 536170c6152STony Prisk } 537170c6152STony Prisk 5387ea45643SAlexey Charkov static int wmt_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 5397ea45643SAlexey Charkov { 5407ea45643SAlexey Charkov return pinctrl_gpio_direction_input(chip->base + offset); 5417ea45643SAlexey Charkov } 5427ea45643SAlexey Charkov 5437ea45643SAlexey Charkov static int wmt_gpio_direction_output(struct gpio_chip *chip, unsigned offset, 5447ea45643SAlexey Charkov int value) 5457ea45643SAlexey Charkov { 5467ea45643SAlexey Charkov wmt_gpio_set_value(chip, offset, value); 5477ea45643SAlexey Charkov return pinctrl_gpio_direction_output(chip->base + offset); 5487ea45643SAlexey Charkov } 5497ea45643SAlexey Charkov 550170c6152STony Prisk static struct gpio_chip wmt_gpio_chip = { 551170c6152STony Prisk .label = "gpio-wmt", 552170c6152STony Prisk .owner = THIS_MODULE, 55398c85d58SJonas Gorski .request = gpiochip_generic_request, 55498c85d58SJonas Gorski .free = gpiochip_generic_free, 555170c6152STony Prisk .get_direction = wmt_gpio_get_direction, 556170c6152STony Prisk .direction_input = wmt_gpio_direction_input, 557170c6152STony Prisk .direction_output = wmt_gpio_direction_output, 558170c6152STony Prisk .get = wmt_gpio_get_value, 559170c6152STony Prisk .set = wmt_gpio_set_value, 5609fb1f39eSLinus Walleij .can_sleep = false, 561170c6152STony Prisk }; 562170c6152STony Prisk 563170c6152STony Prisk int wmt_pinctrl_probe(struct platform_device *pdev, 564170c6152STony Prisk struct wmt_pinctrl_data *data) 565170c6152STony Prisk { 566170c6152STony Prisk int err; 567170c6152STony Prisk struct resource *res; 568170c6152STony Prisk 569170c6152STony Prisk res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 57076cda6ecSLaurent Navet data->base = devm_ioremap_resource(&pdev->dev, res); 5712207a4e1SWei Yongjun if (IS_ERR(data->base)) 57276cda6ecSLaurent Navet return PTR_ERR(data->base); 573170c6152STony Prisk 574170c6152STony Prisk wmt_desc.pins = data->pins; 575170c6152STony Prisk wmt_desc.npins = data->npins; 576170c6152STony Prisk 577170c6152STony Prisk data->gpio_chip = wmt_gpio_chip; 57858383c78SLinus Walleij data->gpio_chip.parent = &pdev->dev; 579170c6152STony Prisk data->gpio_chip.of_node = pdev->dev.of_node; 580170c6152STony Prisk data->gpio_chip.ngpio = data->nbanks * 32; 581170c6152STony Prisk 582170c6152STony Prisk platform_set_drvdata(pdev, data); 583170c6152STony Prisk 584170c6152STony Prisk data->dev = &pdev->dev; 585170c6152STony Prisk 586170c6152STony Prisk data->pctl_dev = pinctrl_register(&wmt_desc, &pdev->dev, data); 587323de9efSMasahiro Yamada if (IS_ERR(data->pctl_dev)) { 588170c6152STony Prisk dev_err(&pdev->dev, "Failed to register pinctrl\n"); 589323de9efSMasahiro Yamada return PTR_ERR(data->pctl_dev); 590170c6152STony Prisk } 591170c6152STony Prisk 5925c809c63SLinus Walleij err = gpiochip_add_data(&data->gpio_chip, data); 593170c6152STony Prisk if (err) { 594170c6152STony Prisk dev_err(&pdev->dev, "could not add GPIO chip\n"); 595170c6152STony Prisk goto fail_gpio; 596170c6152STony Prisk } 597170c6152STony Prisk 598170c6152STony Prisk err = gpiochip_add_pin_range(&data->gpio_chip, dev_name(data->dev), 599170c6152STony Prisk 0, 0, data->nbanks * 32); 600170c6152STony Prisk if (err) 601170c6152STony Prisk goto fail_range; 602170c6152STony Prisk 603170c6152STony Prisk dev_info(&pdev->dev, "Pin controller initialized\n"); 604170c6152STony Prisk 605170c6152STony Prisk return 0; 606170c6152STony Prisk 607170c6152STony Prisk fail_range: 608b4e7c55dSabdoulaye berthe gpiochip_remove(&data->gpio_chip); 609170c6152STony Prisk fail_gpio: 610170c6152STony Prisk pinctrl_unregister(data->pctl_dev); 611170c6152STony Prisk return err; 612170c6152STony Prisk } 613170c6152STony Prisk 614170c6152STony Prisk int wmt_pinctrl_remove(struct platform_device *pdev) 615170c6152STony Prisk { 616170c6152STony Prisk struct wmt_pinctrl_data *data = platform_get_drvdata(pdev); 617170c6152STony Prisk 618b4e7c55dSabdoulaye berthe gpiochip_remove(&data->gpio_chip); 619170c6152STony Prisk pinctrl_unregister(data->pctl_dev); 620170c6152STony Prisk 621170c6152STony Prisk return 0; 622170c6152STony Prisk } 623