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> 17170c6152STony Prisk #include <linux/gpio.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 134170c6152STony Prisk static int wmt_pmx_enable(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_disable(struct pinctrl_dev *pctldev, 145170c6152STony Prisk unsigned func_selector, 146170c6152STony Prisk unsigned group_selector) 147170c6152STony Prisk { 148170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 149170c6152STony Prisk u32 pinnum = data->pins[group_selector].number; 150170c6152STony Prisk 151170c6152STony Prisk /* disable by setting GPIO_IN */ 152170c6152STony Prisk wmt_set_pinmux(data, WMT_FSEL_GPIO_IN, pinnum); 153170c6152STony Prisk } 154170c6152STony Prisk 155170c6152STony Prisk static void wmt_pmx_gpio_disable_free(struct pinctrl_dev *pctldev, 156170c6152STony Prisk struct pinctrl_gpio_range *range, 157170c6152STony Prisk unsigned offset) 158170c6152STony Prisk { 159170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 160170c6152STony Prisk 161170c6152STony Prisk /* disable by setting GPIO_IN */ 162170c6152STony Prisk wmt_set_pinmux(data, WMT_FSEL_GPIO_IN, offset); 163170c6152STony Prisk } 164170c6152STony Prisk 165170c6152STony Prisk static int wmt_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, 166170c6152STony Prisk struct pinctrl_gpio_range *range, 167170c6152STony Prisk unsigned offset, 168170c6152STony Prisk bool input) 169170c6152STony Prisk { 170170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 171170c6152STony Prisk 172170c6152STony Prisk wmt_set_pinmux(data, (input ? WMT_FSEL_GPIO_IN : WMT_FSEL_GPIO_OUT), 173170c6152STony Prisk offset); 174170c6152STony Prisk 175170c6152STony Prisk return 0; 176170c6152STony Prisk } 177170c6152STony Prisk 178170c6152STony Prisk static struct pinmux_ops wmt_pinmux_ops = { 179170c6152STony Prisk .get_functions_count = wmt_pmx_get_functions_count, 180170c6152STony Prisk .get_function_name = wmt_pmx_get_function_name, 181170c6152STony Prisk .get_function_groups = wmt_pmx_get_function_groups, 182170c6152STony Prisk .enable = wmt_pmx_enable, 183170c6152STony Prisk .disable = wmt_pmx_disable, 184170c6152STony Prisk .gpio_disable_free = wmt_pmx_gpio_disable_free, 185170c6152STony Prisk .gpio_set_direction = wmt_pmx_gpio_set_direction, 186170c6152STony Prisk }; 187170c6152STony Prisk 188170c6152STony Prisk static int wmt_get_groups_count(struct pinctrl_dev *pctldev) 189170c6152STony Prisk { 190170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 191170c6152STony Prisk 192170c6152STony Prisk return data->ngroups; 193170c6152STony Prisk } 194170c6152STony Prisk 195170c6152STony Prisk static const char *wmt_get_group_name(struct pinctrl_dev *pctldev, 196170c6152STony Prisk unsigned selector) 197170c6152STony Prisk { 198170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 199170c6152STony Prisk 200170c6152STony Prisk return data->groups[selector]; 201170c6152STony Prisk } 202170c6152STony Prisk 203170c6152STony Prisk static int wmt_get_group_pins(struct pinctrl_dev *pctldev, 204170c6152STony Prisk unsigned selector, 205170c6152STony Prisk const unsigned **pins, 206170c6152STony Prisk unsigned *num_pins) 207170c6152STony Prisk { 208170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 209170c6152STony Prisk 210170c6152STony Prisk *pins = &data->pins[selector].number; 211170c6152STony Prisk *num_pins = 1; 212170c6152STony Prisk 213170c6152STony Prisk return 0; 214170c6152STony Prisk } 215170c6152STony Prisk 216170c6152STony Prisk static int wmt_pctl_find_group_by_pin(struct wmt_pinctrl_data *data, u32 pin) 217170c6152STony Prisk { 218170c6152STony Prisk int i; 219170c6152STony Prisk 220170c6152STony Prisk for (i = 0; i < data->npins; i++) { 221170c6152STony Prisk if (data->pins[i].number == pin) 222170c6152STony Prisk return i; 223170c6152STony Prisk } 224170c6152STony Prisk 225170c6152STony Prisk return -EINVAL; 226170c6152STony Prisk } 227170c6152STony Prisk 228170c6152STony Prisk static int wmt_pctl_dt_node_to_map_func(struct wmt_pinctrl_data *data, 229170c6152STony Prisk struct device_node *np, 230170c6152STony Prisk u32 pin, u32 fnum, 231170c6152STony Prisk struct pinctrl_map **maps) 232170c6152STony Prisk { 233170c6152STony Prisk int group; 234170c6152STony Prisk struct pinctrl_map *map = *maps; 235170c6152STony Prisk 236170c6152STony Prisk if (fnum >= ARRAY_SIZE(wmt_functions)) { 237170c6152STony Prisk dev_err(data->dev, "invalid wm,function %d\n", fnum); 238170c6152STony Prisk return -EINVAL; 239170c6152STony Prisk } 240170c6152STony Prisk 241170c6152STony Prisk group = wmt_pctl_find_group_by_pin(data, pin); 242170c6152STony Prisk if (group < 0) { 243170c6152STony Prisk dev_err(data->dev, "unable to match pin %d to group\n", pin); 244170c6152STony Prisk return group; 245170c6152STony Prisk } 246170c6152STony Prisk 247170c6152STony Prisk map->type = PIN_MAP_TYPE_MUX_GROUP; 248170c6152STony Prisk map->data.mux.group = data->groups[group]; 249170c6152STony Prisk map->data.mux.function = wmt_functions[fnum]; 250170c6152STony Prisk (*maps)++; 251170c6152STony Prisk 252170c6152STony Prisk return 0; 253170c6152STony Prisk } 254170c6152STony Prisk 255170c6152STony Prisk static int wmt_pctl_dt_node_to_map_pull(struct wmt_pinctrl_data *data, 256170c6152STony Prisk struct device_node *np, 257170c6152STony Prisk u32 pin, u32 pull, 258170c6152STony Prisk struct pinctrl_map **maps) 259170c6152STony Prisk { 260170c6152STony Prisk int group; 261170c6152STony Prisk unsigned long *configs; 262170c6152STony Prisk struct pinctrl_map *map = *maps; 263170c6152STony Prisk 264170c6152STony Prisk if (pull > 2) { 265170c6152STony Prisk dev_err(data->dev, "invalid wm,pull %d\n", pull); 266170c6152STony Prisk return -EINVAL; 267170c6152STony Prisk } 268170c6152STony Prisk 269170c6152STony Prisk group = wmt_pctl_find_group_by_pin(data, pin); 270170c6152STony Prisk if (group < 0) { 271170c6152STony Prisk dev_err(data->dev, "unable to match pin %d to group\n", pin); 272170c6152STony Prisk return group; 273170c6152STony Prisk } 274170c6152STony Prisk 275170c6152STony Prisk configs = kzalloc(sizeof(*configs), GFP_KERNEL); 276170c6152STony Prisk if (!configs) 277170c6152STony Prisk return -ENOMEM; 278170c6152STony Prisk 279170c6152STony Prisk configs[0] = pull; 280170c6152STony Prisk 281170c6152STony Prisk map->type = PIN_MAP_TYPE_CONFIGS_PIN; 282170c6152STony Prisk map->data.configs.group_or_pin = data->groups[group]; 283170c6152STony Prisk map->data.configs.configs = configs; 284170c6152STony Prisk map->data.configs.num_configs = 1; 285170c6152STony Prisk (*maps)++; 286170c6152STony Prisk 287170c6152STony Prisk return 0; 288170c6152STony Prisk } 289170c6152STony Prisk 290170c6152STony Prisk static void wmt_pctl_dt_free_map(struct pinctrl_dev *pctldev, 291170c6152STony Prisk struct pinctrl_map *maps, 292170c6152STony Prisk unsigned num_maps) 293170c6152STony Prisk { 294170c6152STony Prisk int i; 295170c6152STony Prisk 296170c6152STony Prisk for (i = 0; i < num_maps; i++) 297170c6152STony Prisk if (maps[i].type == PIN_MAP_TYPE_CONFIGS_PIN) 298170c6152STony Prisk kfree(maps[i].data.configs.configs); 299170c6152STony Prisk 300170c6152STony Prisk kfree(maps); 301170c6152STony Prisk } 302170c6152STony Prisk 303170c6152STony Prisk static int wmt_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, 304170c6152STony Prisk struct device_node *np, 305170c6152STony Prisk struct pinctrl_map **map, 306170c6152STony Prisk unsigned *num_maps) 307170c6152STony Prisk { 308170c6152STony Prisk struct pinctrl_map *maps, *cur_map; 309170c6152STony Prisk struct property *pins, *funcs, *pulls; 310170c6152STony Prisk u32 pin, func, pull; 311170c6152STony Prisk int num_pins, num_funcs, num_pulls, maps_per_pin; 312170c6152STony Prisk int i, err; 313170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 314170c6152STony Prisk 315170c6152STony Prisk pins = of_find_property(np, "wm,pins", NULL); 316170c6152STony Prisk if (!pins) { 317170c6152STony Prisk dev_err(data->dev, "missing wmt,pins property\n"); 318170c6152STony Prisk return -EINVAL; 319170c6152STony Prisk } 320170c6152STony Prisk 321170c6152STony Prisk funcs = of_find_property(np, "wm,function", NULL); 322170c6152STony Prisk pulls = of_find_property(np, "wm,pull", NULL); 323170c6152STony Prisk 324170c6152STony Prisk if (!funcs && !pulls) { 325170c6152STony Prisk dev_err(data->dev, "neither wm,function nor wm,pull specified\n"); 326170c6152STony Prisk return -EINVAL; 327170c6152STony Prisk } 328170c6152STony Prisk 329170c6152STony Prisk /* 330170c6152STony Prisk * The following lines calculate how many values are defined for each 331170c6152STony Prisk * of the properties. 332170c6152STony Prisk */ 333170c6152STony Prisk num_pins = pins->length / sizeof(u32); 334170c6152STony Prisk num_funcs = funcs ? (funcs->length / sizeof(u32)) : 0; 335170c6152STony Prisk num_pulls = pulls ? (pulls->length / sizeof(u32)) : 0; 336170c6152STony Prisk 337170c6152STony Prisk if (num_funcs > 1 && num_funcs != num_pins) { 338170c6152STony Prisk dev_err(data->dev, "wm,function must have 1 or %d entries\n", 339170c6152STony Prisk num_pins); 340170c6152STony Prisk return -EINVAL; 341170c6152STony Prisk } 342170c6152STony Prisk 343170c6152STony Prisk if (num_pulls > 1 && num_pulls != num_pins) { 344170c6152STony Prisk dev_err(data->dev, "wm,pull must have 1 or %d entries\n", 345170c6152STony Prisk num_pins); 346170c6152STony Prisk return -EINVAL; 347170c6152STony Prisk } 348170c6152STony Prisk 349170c6152STony Prisk maps_per_pin = 0; 350170c6152STony Prisk if (num_funcs) 351170c6152STony Prisk maps_per_pin++; 352170c6152STony Prisk if (num_pulls) 353170c6152STony Prisk maps_per_pin++; 354170c6152STony Prisk 355170c6152STony Prisk cur_map = maps = kzalloc(num_pins * maps_per_pin * sizeof(*maps), 356170c6152STony Prisk GFP_KERNEL); 357170c6152STony Prisk if (!maps) 358170c6152STony Prisk return -ENOMEM; 359170c6152STony Prisk 360170c6152STony Prisk for (i = 0; i < num_pins; i++) { 361170c6152STony Prisk err = of_property_read_u32_index(np, "wm,pins", i, &pin); 362170c6152STony Prisk if (err) 363170c6152STony Prisk goto fail; 364170c6152STony Prisk 365170c6152STony Prisk if (pin >= (data->nbanks * 32)) { 366170c6152STony Prisk dev_err(data->dev, "invalid wm,pins value\n"); 367170c6152STony Prisk err = -EINVAL; 368170c6152STony Prisk goto fail; 369170c6152STony Prisk } 370170c6152STony Prisk 371170c6152STony Prisk if (num_funcs) { 372170c6152STony Prisk err = of_property_read_u32_index(np, "wm,function", 373170c6152STony Prisk (num_funcs > 1 ? i : 0), &func); 374170c6152STony Prisk if (err) 375170c6152STony Prisk goto fail; 376170c6152STony Prisk 377170c6152STony Prisk err = wmt_pctl_dt_node_to_map_func(data, np, pin, func, 378170c6152STony Prisk &cur_map); 379170c6152STony Prisk if (err) 380170c6152STony Prisk goto fail; 381170c6152STony Prisk } 382170c6152STony Prisk 383170c6152STony Prisk if (num_pulls) { 384170c6152STony Prisk err = of_property_read_u32_index(np, "wm,pull", 385170c6152STony Prisk (num_pulls > 1 ? i : 0), &pull); 386170c6152STony Prisk if (err) 387170c6152STony Prisk goto fail; 388170c6152STony Prisk 389170c6152STony Prisk err = wmt_pctl_dt_node_to_map_pull(data, np, pin, pull, 390170c6152STony Prisk &cur_map); 391170c6152STony Prisk if (err) 392170c6152STony Prisk goto fail; 393170c6152STony Prisk } 394170c6152STony Prisk } 395170c6152STony Prisk *map = maps; 396170c6152STony Prisk *num_maps = num_pins * maps_per_pin; 397170c6152STony Prisk return 0; 398170c6152STony Prisk 399170c6152STony Prisk /* 400170c6152STony Prisk * The fail path removes any maps that have been allocated. The fail path is 401170c6152STony Prisk * only called from code after maps has been kzalloc'd. It is also safe to 402170c6152STony Prisk * pass 'num_pins * maps_per_pin' as the map count even though we probably 403170c6152STony Prisk * failed before all the mappings were read as all maps are allocated at once, 404170c6152STony Prisk * and configs are only allocated for .type = PIN_MAP_TYPE_CONFIGS_PIN - there 405170c6152STony Prisk * is no failpath where a config can be allocated without .type being set. 406170c6152STony Prisk */ 407170c6152STony Prisk fail: 408170c6152STony Prisk wmt_pctl_dt_free_map(pctldev, maps, num_pins * maps_per_pin); 409170c6152STony Prisk return err; 410170c6152STony Prisk } 411170c6152STony Prisk 412170c6152STony Prisk static struct pinctrl_ops wmt_pctl_ops = { 413170c6152STony Prisk .get_groups_count = wmt_get_groups_count, 414170c6152STony Prisk .get_group_name = wmt_get_group_name, 415170c6152STony Prisk .get_group_pins = wmt_get_group_pins, 416170c6152STony Prisk .dt_node_to_map = wmt_pctl_dt_node_to_map, 417170c6152STony Prisk .dt_free_map = wmt_pctl_dt_free_map, 418170c6152STony Prisk }; 419170c6152STony Prisk 420170c6152STony Prisk static int wmt_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, 421170c6152STony Prisk unsigned long *config) 422170c6152STony Prisk { 423170c6152STony Prisk return -ENOTSUPP; 424170c6152STony Prisk } 425170c6152STony Prisk 426170c6152STony Prisk static int wmt_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, 427170c6152STony Prisk unsigned long config) 428170c6152STony Prisk { 429170c6152STony Prisk struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); 430170c6152STony Prisk enum pin_config_param param = pinconf_to_config_param(config); 431170c6152STony Prisk u16 arg = pinconf_to_config_argument(config); 432170c6152STony Prisk u32 bank = WMT_BANK_FROM_PIN(pin); 433170c6152STony Prisk u32 bit = WMT_BIT_FROM_PIN(pin); 434170c6152STony Prisk u32 reg_pull_en = data->banks[bank].reg_pull_en; 435170c6152STony Prisk u32 reg_pull_cfg = data->banks[bank].reg_pull_cfg; 436170c6152STony Prisk 437170c6152STony Prisk if ((reg_pull_en == NO_REG) || (reg_pull_cfg == NO_REG)) { 438170c6152STony Prisk dev_err(data->dev, "bias functions not supported on pin %d\n", 439170c6152STony Prisk pin); 440170c6152STony Prisk return -EINVAL; 441170c6152STony Prisk } 442170c6152STony Prisk 443170c6152STony Prisk if ((param == PIN_CONFIG_BIAS_PULL_DOWN) || 444170c6152STony Prisk (param == PIN_CONFIG_BIAS_PULL_UP)) { 445170c6152STony Prisk if (arg == 0) 446170c6152STony Prisk param = PIN_CONFIG_BIAS_DISABLE; 447170c6152STony Prisk } 448170c6152STony Prisk 449170c6152STony Prisk switch (param) { 450170c6152STony Prisk case PIN_CONFIG_BIAS_DISABLE: 451170c6152STony Prisk wmt_clearbits(data, reg_pull_en, BIT(bit)); 452170c6152STony Prisk break; 453170c6152STony Prisk case PIN_CONFIG_BIAS_PULL_DOWN: 454170c6152STony Prisk wmt_clearbits(data, reg_pull_cfg, BIT(bit)); 455170c6152STony Prisk wmt_setbits(data, reg_pull_en, BIT(bit)); 456170c6152STony Prisk break; 457170c6152STony Prisk case PIN_CONFIG_BIAS_PULL_UP: 458170c6152STony Prisk wmt_setbits(data, reg_pull_cfg, BIT(bit)); 459170c6152STony Prisk wmt_setbits(data, reg_pull_en, BIT(bit)); 460170c6152STony Prisk break; 461170c6152STony Prisk default: 462170c6152STony Prisk dev_err(data->dev, "unknown pinconf param\n"); 463170c6152STony Prisk return -EINVAL; 464170c6152STony Prisk } 465170c6152STony Prisk 466170c6152STony Prisk return 0; 467170c6152STony Prisk } 468170c6152STony Prisk 469170c6152STony Prisk static struct pinconf_ops wmt_pinconf_ops = { 470170c6152STony Prisk .pin_config_get = wmt_pinconf_get, 471170c6152STony Prisk .pin_config_set = wmt_pinconf_set, 472170c6152STony Prisk }; 473170c6152STony Prisk 474170c6152STony Prisk static struct pinctrl_desc wmt_desc = { 475170c6152STony Prisk .owner = THIS_MODULE, 476170c6152STony Prisk .name = "pinctrl-wmt", 477170c6152STony Prisk .pctlops = &wmt_pctl_ops, 478170c6152STony Prisk .pmxops = &wmt_pinmux_ops, 479170c6152STony Prisk .confops = &wmt_pinconf_ops, 480170c6152STony Prisk }; 481170c6152STony Prisk 482170c6152STony Prisk static int wmt_gpio_request(struct gpio_chip *chip, unsigned offset) 483170c6152STony Prisk { 484170c6152STony Prisk return pinctrl_request_gpio(chip->base + offset); 485170c6152STony Prisk } 486170c6152STony Prisk 487170c6152STony Prisk static void wmt_gpio_free(struct gpio_chip *chip, unsigned offset) 488170c6152STony Prisk { 489170c6152STony Prisk pinctrl_free_gpio(chip->base + offset); 490170c6152STony Prisk } 491170c6152STony Prisk 492170c6152STony Prisk static int wmt_gpio_get_direction(struct gpio_chip *chip, unsigned offset) 493170c6152STony Prisk { 494170c6152STony Prisk struct wmt_pinctrl_data *data = dev_get_drvdata(chip->dev); 495170c6152STony Prisk u32 bank = WMT_BANK_FROM_PIN(offset); 496170c6152STony Prisk u32 bit = WMT_BIT_FROM_PIN(offset); 497170c6152STony Prisk u32 reg_dir = data->banks[bank].reg_dir; 498170c6152STony Prisk u32 val; 499170c6152STony Prisk 500170c6152STony Prisk val = readl_relaxed(data->base + reg_dir); 501170c6152STony Prisk if (val & BIT(bit)) 502170c6152STony Prisk return GPIOF_DIR_OUT; 503170c6152STony Prisk else 504170c6152STony Prisk return GPIOF_DIR_IN; 505170c6152STony Prisk } 506170c6152STony Prisk 507170c6152STony Prisk static int wmt_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 508170c6152STony Prisk { 509170c6152STony Prisk return pinctrl_gpio_direction_input(chip->base + offset); 510170c6152STony Prisk } 511170c6152STony Prisk 512170c6152STony Prisk static int wmt_gpio_direction_output(struct gpio_chip *chip, unsigned offset, 513170c6152STony Prisk int value) 514170c6152STony Prisk { 515170c6152STony Prisk return pinctrl_gpio_direction_output(chip->base + offset); 516170c6152STony Prisk } 517170c6152STony Prisk 518170c6152STony Prisk static int wmt_gpio_get_value(struct gpio_chip *chip, unsigned offset) 519170c6152STony Prisk { 520170c6152STony Prisk struct wmt_pinctrl_data *data = dev_get_drvdata(chip->dev); 521170c6152STony Prisk u32 bank = WMT_BANK_FROM_PIN(offset); 522170c6152STony Prisk u32 bit = WMT_BIT_FROM_PIN(offset); 523170c6152STony Prisk u32 reg_data_in = data->banks[bank].reg_data_in; 524170c6152STony Prisk 525170c6152STony Prisk if (reg_data_in == NO_REG) { 526170c6152STony Prisk dev_err(data->dev, "no data in register defined\n"); 527170c6152STony Prisk return -EINVAL; 528170c6152STony Prisk } 529170c6152STony Prisk 530170c6152STony Prisk return !!(readl_relaxed(data->base + reg_data_in) & BIT(bit)); 531170c6152STony Prisk } 532170c6152STony Prisk 533170c6152STony Prisk static void wmt_gpio_set_value(struct gpio_chip *chip, unsigned offset, 534170c6152STony Prisk int val) 535170c6152STony Prisk { 536170c6152STony Prisk struct wmt_pinctrl_data *data = dev_get_drvdata(chip->dev); 537170c6152STony Prisk u32 bank = WMT_BANK_FROM_PIN(offset); 538170c6152STony Prisk u32 bit = WMT_BIT_FROM_PIN(offset); 539170c6152STony Prisk u32 reg_data_out = data->banks[bank].reg_data_out; 540170c6152STony Prisk 541170c6152STony Prisk if (reg_data_out == NO_REG) { 542170c6152STony Prisk dev_err(data->dev, "no data out register defined\n"); 543170c6152STony Prisk return; 544170c6152STony Prisk } 545170c6152STony Prisk 546170c6152STony Prisk if (val) 547170c6152STony Prisk wmt_setbits(data, reg_data_out, BIT(bit)); 548170c6152STony Prisk else 549170c6152STony Prisk wmt_clearbits(data, reg_data_out, BIT(bit)); 550170c6152STony Prisk } 551170c6152STony Prisk 552170c6152STony Prisk static struct gpio_chip wmt_gpio_chip = { 553170c6152STony Prisk .label = "gpio-wmt", 554170c6152STony Prisk .owner = THIS_MODULE, 555170c6152STony Prisk .request = wmt_gpio_request, 556170c6152STony Prisk .free = wmt_gpio_free, 557170c6152STony Prisk .get_direction = wmt_gpio_get_direction, 558170c6152STony Prisk .direction_input = wmt_gpio_direction_input, 559170c6152STony Prisk .direction_output = wmt_gpio_direction_output, 560170c6152STony Prisk .get = wmt_gpio_get_value, 561170c6152STony Prisk .set = wmt_gpio_set_value, 562170c6152STony Prisk .can_sleep = 0, 563170c6152STony Prisk }; 564170c6152STony Prisk 565170c6152STony Prisk int wmt_pinctrl_probe(struct platform_device *pdev, 566170c6152STony Prisk struct wmt_pinctrl_data *data) 567170c6152STony Prisk { 568170c6152STony Prisk int err; 569170c6152STony Prisk struct resource *res; 570170c6152STony Prisk 571170c6152STony Prisk res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 57276cda6ecSLaurent Navet data->base = devm_ioremap_resource(&pdev->dev, res); 5732207a4e1SWei Yongjun if (IS_ERR(data->base)) 57476cda6ecSLaurent Navet return PTR_ERR(data->base); 575170c6152STony Prisk 576170c6152STony Prisk wmt_desc.pins = data->pins; 577170c6152STony Prisk wmt_desc.npins = data->npins; 578170c6152STony Prisk 579170c6152STony Prisk data->gpio_chip = wmt_gpio_chip; 580170c6152STony Prisk data->gpio_chip.dev = &pdev->dev; 581170c6152STony Prisk data->gpio_chip.of_node = pdev->dev.of_node; 582170c6152STony Prisk data->gpio_chip.ngpio = data->nbanks * 32; 583170c6152STony Prisk 584170c6152STony Prisk platform_set_drvdata(pdev, data); 585170c6152STony Prisk 586170c6152STony Prisk data->dev = &pdev->dev; 587170c6152STony Prisk 588170c6152STony Prisk data->pctl_dev = pinctrl_register(&wmt_desc, &pdev->dev, data); 5891f1a7357SAxel Lin if (!data->pctl_dev) { 590170c6152STony Prisk dev_err(&pdev->dev, "Failed to register pinctrl\n"); 591170c6152STony Prisk return -EINVAL; 592170c6152STony Prisk } 593170c6152STony Prisk 594170c6152STony Prisk err = gpiochip_add(&data->gpio_chip); 595170c6152STony Prisk if (err) { 596170c6152STony Prisk dev_err(&pdev->dev, "could not add GPIO chip\n"); 597170c6152STony Prisk goto fail_gpio; 598170c6152STony Prisk } 599170c6152STony Prisk 600170c6152STony Prisk err = gpiochip_add_pin_range(&data->gpio_chip, dev_name(data->dev), 601170c6152STony Prisk 0, 0, data->nbanks * 32); 602170c6152STony Prisk if (err) 603170c6152STony Prisk goto fail_range; 604170c6152STony Prisk 605170c6152STony Prisk dev_info(&pdev->dev, "Pin controller initialized\n"); 606170c6152STony Prisk 607170c6152STony Prisk return 0; 608170c6152STony Prisk 609170c6152STony Prisk fail_range: 61097fc4637SAxel Lin if (gpiochip_remove(&data->gpio_chip)) 611170c6152STony Prisk dev_err(&pdev->dev, "failed to remove gpio chip\n"); 612170c6152STony Prisk fail_gpio: 613170c6152STony Prisk pinctrl_unregister(data->pctl_dev); 614170c6152STony Prisk return err; 615170c6152STony Prisk } 616170c6152STony Prisk 617170c6152STony Prisk int wmt_pinctrl_remove(struct platform_device *pdev) 618170c6152STony Prisk { 619170c6152STony Prisk struct wmt_pinctrl_data *data = platform_get_drvdata(pdev); 620170c6152STony Prisk int err; 621170c6152STony Prisk 622170c6152STony Prisk err = gpiochip_remove(&data->gpio_chip); 623170c6152STony Prisk if (err) 624170c6152STony Prisk dev_err(&pdev->dev, "failed to remove gpio chip\n"); 625170c6152STony Prisk 626170c6152STony Prisk pinctrl_unregister(data->pctl_dev); 627170c6152STony Prisk 628170c6152STony Prisk return 0; 629170c6152STony Prisk } 630