Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.1-rc4 449 lines 11 kB view raw
1/* 2 * Copyright (C) 2017 Sanechips Technology Co., Ltd. 3 * Copyright 2017 Linaro Ltd. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9 10#include <linux/io.h> 11#include <linux/of.h> 12#include <linux/of_address.h> 13#include <linux/of_device.h> 14#include <linux/pinctrl/pinctrl.h> 15#include <linux/pinctrl/pinconf-generic.h> 16#include <linux/pinctrl/pinmux.h> 17#include <linux/platform_device.h> 18#include <linux/slab.h> 19 20#include "../core.h" 21#include "../pinctrl-utils.h" 22#include "../pinmux.h" 23#include "pinctrl-zx.h" 24 25#define ZX_PULL_DOWN BIT(0) 26#define ZX_PULL_UP BIT(1) 27#define ZX_INPUT_ENABLE BIT(3) 28#define ZX_DS_SHIFT 4 29#define ZX_DS_MASK (0x7 << ZX_DS_SHIFT) 30#define ZX_DS_VALUE(x) (((x) << ZX_DS_SHIFT) & ZX_DS_MASK) 31#define ZX_SLEW BIT(8) 32 33struct zx_pinctrl { 34 struct pinctrl_dev *pctldev; 35 struct device *dev; 36 void __iomem *base; 37 void __iomem *aux_base; 38 spinlock_t lock; 39 struct zx_pinctrl_soc_info *info; 40}; 41 42static int zx_dt_node_to_map(struct pinctrl_dev *pctldev, 43 struct device_node *np_config, 44 struct pinctrl_map **map, u32 *num_maps) 45{ 46 return pinconf_generic_dt_node_to_map(pctldev, np_config, map, 47 num_maps, PIN_MAP_TYPE_INVALID); 48} 49 50static const struct pinctrl_ops zx_pinctrl_ops = { 51 .dt_node_to_map = zx_dt_node_to_map, 52 .dt_free_map = pinctrl_utils_free_map, 53 .get_groups_count = pinctrl_generic_get_group_count, 54 .get_group_name = pinctrl_generic_get_group_name, 55 .get_group_pins = pinctrl_generic_get_group_pins, 56}; 57 58#define NONAON_MVAL 2 59 60static int zx_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, 61 unsigned int group_selector) 62{ 63 struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev); 64 struct zx_pinctrl_soc_info *info = zpctl->info; 65 const struct pinctrl_pin_desc *pindesc = info->pins + group_selector; 66 struct zx_pin_data *data = pindesc->drv_data; 67 struct zx_mux_desc *mux; 68 u32 mask, offset, bitpos; 69 struct function_desc *func; 70 unsigned long flags; 71 u32 val, mval; 72 73 /* Skip reserved pin */ 74 if (!data) 75 return -EINVAL; 76 77 mux = data->muxes; 78 mask = (1 << data->width) - 1; 79 offset = data->offset; 80 bitpos = data->bitpos; 81 82 func = pinmux_generic_get_function(pctldev, func_selector); 83 if (!func) 84 return -EINVAL; 85 86 while (mux->name) { 87 if (strcmp(mux->name, func->name) == 0) 88 break; 89 mux++; 90 } 91 92 /* Found mux value to be written */ 93 mval = mux->muxval; 94 95 spin_lock_irqsave(&zpctl->lock, flags); 96 97 if (data->aon_pin) { 98 /* 99 * It's an AON pin, whose mux register offset and bit position 100 * can be caluculated from pin number. Each register covers 16 101 * pins, and each pin occupies 2 bits. 102 */ 103 u16 aoffset = pindesc->number / 16 * 4; 104 u16 abitpos = (pindesc->number % 16) * 2; 105 106 if (mval & AON_MUX_FLAG) { 107 /* 108 * This is a mux value that needs to be written into 109 * AON pinmux register. Write it and then we're done. 110 */ 111 val = readl(zpctl->aux_base + aoffset); 112 val &= ~(0x3 << abitpos); 113 val |= (mval & 0x3) << abitpos; 114 writel(val, zpctl->aux_base + aoffset); 115 } else { 116 /* 117 * It's a mux value that needs to be written into TOP 118 * pinmux register. 119 */ 120 val = readl(zpctl->base + offset); 121 val &= ~(mask << bitpos); 122 val |= (mval & mask) << bitpos; 123 writel(val, zpctl->base + offset); 124 125 /* 126 * In this case, the AON pinmux register needs to be 127 * set up to select non-AON function. 128 */ 129 val = readl(zpctl->aux_base + aoffset); 130 val &= ~(0x3 << abitpos); 131 val |= NONAON_MVAL << abitpos; 132 writel(val, zpctl->aux_base + aoffset); 133 } 134 135 } else { 136 /* 137 * This is a TOP pin, and we only need to set up TOP pinmux 138 * register and then we're done with it. 139 */ 140 val = readl(zpctl->base + offset); 141 val &= ~(mask << bitpos); 142 val |= (mval & mask) << bitpos; 143 writel(val, zpctl->base + offset); 144 } 145 146 spin_unlock_irqrestore(&zpctl->lock, flags); 147 148 return 0; 149} 150 151static const struct pinmux_ops zx_pinmux_ops = { 152 .get_functions_count = pinmux_generic_get_function_count, 153 .get_function_name = pinmux_generic_get_function_name, 154 .get_function_groups = pinmux_generic_get_function_groups, 155 .set_mux = zx_set_mux, 156}; 157 158static int zx_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin, 159 unsigned long *config) 160{ 161 struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev); 162 struct zx_pinctrl_soc_info *info = zpctl->info; 163 const struct pinctrl_pin_desc *pindesc = info->pins + pin; 164 struct zx_pin_data *data = pindesc->drv_data; 165 enum pin_config_param param = pinconf_to_config_param(*config); 166 u32 val; 167 168 /* Skip reserved pin */ 169 if (!data) 170 return -EINVAL; 171 172 val = readl(zpctl->aux_base + data->coffset); 173 val = val >> data->cbitpos; 174 175 switch (param) { 176 case PIN_CONFIG_BIAS_PULL_DOWN: 177 val &= ZX_PULL_DOWN; 178 val = !!val; 179 if (val == 0) 180 return -EINVAL; 181 break; 182 case PIN_CONFIG_BIAS_PULL_UP: 183 val &= ZX_PULL_UP; 184 val = !!val; 185 if (val == 0) 186 return -EINVAL; 187 break; 188 case PIN_CONFIG_INPUT_ENABLE: 189 val &= ZX_INPUT_ENABLE; 190 val = !!val; 191 if (val == 0) 192 return -EINVAL; 193 break; 194 case PIN_CONFIG_DRIVE_STRENGTH: 195 val &= ZX_DS_MASK; 196 val = val >> ZX_DS_SHIFT; 197 break; 198 case PIN_CONFIG_SLEW_RATE: 199 val &= ZX_SLEW; 200 val = !!val; 201 break; 202 default: 203 return -ENOTSUPP; 204 } 205 206 *config = pinconf_to_config_packed(param, val); 207 208 return 0; 209} 210 211static int zx_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin, 212 unsigned long *configs, unsigned int num_configs) 213{ 214 struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev); 215 struct zx_pinctrl_soc_info *info = zpctl->info; 216 const struct pinctrl_pin_desc *pindesc = info->pins + pin; 217 struct zx_pin_data *data = pindesc->drv_data; 218 enum pin_config_param param; 219 u32 val, arg; 220 int i; 221 222 /* Skip reserved pin */ 223 if (!data) 224 return -EINVAL; 225 226 val = readl(zpctl->aux_base + data->coffset); 227 228 for (i = 0; i < num_configs; i++) { 229 param = pinconf_to_config_param(configs[i]); 230 arg = pinconf_to_config_argument(configs[i]); 231 232 switch (param) { 233 case PIN_CONFIG_BIAS_PULL_DOWN: 234 val |= ZX_PULL_DOWN << data->cbitpos; 235 break; 236 case PIN_CONFIG_BIAS_PULL_UP: 237 val |= ZX_PULL_UP << data->cbitpos; 238 break; 239 case PIN_CONFIG_INPUT_ENABLE: 240 val |= ZX_INPUT_ENABLE << data->cbitpos; 241 break; 242 case PIN_CONFIG_DRIVE_STRENGTH: 243 val &= ~(ZX_DS_MASK << data->cbitpos); 244 val |= ZX_DS_VALUE(arg) << data->cbitpos; 245 break; 246 case PIN_CONFIG_SLEW_RATE: 247 if (arg) 248 val |= ZX_SLEW << data->cbitpos; 249 else 250 val &= ~ZX_SLEW << data->cbitpos; 251 break; 252 default: 253 return -ENOTSUPP; 254 } 255 } 256 257 writel(val, zpctl->aux_base + data->coffset); 258 return 0; 259} 260 261static const struct pinconf_ops zx_pinconf_ops = { 262 .pin_config_set = zx_pin_config_set, 263 .pin_config_get = zx_pin_config_get, 264 .is_generic = true, 265}; 266 267static int zx_pinctrl_build_state(struct platform_device *pdev) 268{ 269 struct zx_pinctrl *zpctl = platform_get_drvdata(pdev); 270 struct zx_pinctrl_soc_info *info = zpctl->info; 271 struct pinctrl_dev *pctldev = zpctl->pctldev; 272 struct function_desc *functions; 273 int nfunctions; 274 struct group_desc *groups; 275 int ngroups; 276 int i; 277 278 /* Every single pin composes a group */ 279 ngroups = info->npins; 280 groups = devm_kcalloc(&pdev->dev, ngroups, sizeof(*groups), 281 GFP_KERNEL); 282 if (!groups) 283 return -ENOMEM; 284 285 for (i = 0; i < ngroups; i++) { 286 const struct pinctrl_pin_desc *pindesc = info->pins + i; 287 struct group_desc *group = groups + i; 288 289 group->name = pindesc->name; 290 group->pins = (int *) &pindesc->number; 291 group->num_pins = 1; 292 radix_tree_insert(&pctldev->pin_group_tree, i, group); 293 } 294 295 pctldev->num_groups = ngroups; 296 297 /* Build function list from pin mux functions */ 298 functions = kcalloc(info->npins, sizeof(*functions), GFP_KERNEL); 299 if (!functions) 300 return -ENOMEM; 301 302 nfunctions = 0; 303 for (i = 0; i < info->npins; i++) { 304 const struct pinctrl_pin_desc *pindesc = info->pins + i; 305 struct zx_pin_data *data = pindesc->drv_data; 306 struct zx_mux_desc *mux; 307 308 /* Reserved pins do not have a drv_data at all */ 309 if (!data) 310 continue; 311 312 /* Loop over all muxes for the pin */ 313 mux = data->muxes; 314 while (mux->name) { 315 struct function_desc *func = functions; 316 317 /* Search function list for given mux */ 318 while (func->name) { 319 if (strcmp(mux->name, func->name) == 0) { 320 /* Function exists */ 321 func->num_group_names++; 322 break; 323 } 324 func++; 325 } 326 327 if (!func->name) { 328 /* New function */ 329 func->name = mux->name; 330 func->num_group_names = 1; 331 radix_tree_insert(&pctldev->pin_function_tree, 332 nfunctions++, func); 333 } 334 335 mux++; 336 } 337 } 338 339 pctldev->num_functions = nfunctions; 340 functions = krealloc(functions, nfunctions * sizeof(*functions), 341 GFP_KERNEL); 342 343 /* Find pin groups for every single function */ 344 for (i = 0; i < info->npins; i++) { 345 const struct pinctrl_pin_desc *pindesc = info->pins + i; 346 struct zx_pin_data *data = pindesc->drv_data; 347 struct zx_mux_desc *mux; 348 349 if (!data) 350 continue; 351 352 mux = data->muxes; 353 while (mux->name) { 354 struct function_desc *func; 355 const char **group; 356 int j; 357 358 /* Find function for given mux */ 359 for (j = 0; j < nfunctions; j++) 360 if (strcmp(functions[j].name, mux->name) == 0) 361 break; 362 363 func = functions + j; 364 if (!func->group_names) { 365 func->group_names = devm_kcalloc(&pdev->dev, 366 func->num_group_names, 367 sizeof(*func->group_names), 368 GFP_KERNEL); 369 if (!func->group_names) { 370 kfree(functions); 371 return -ENOMEM; 372 } 373 } 374 375 group = func->group_names; 376 while (*group) 377 group++; 378 *group = pindesc->name; 379 380 mux++; 381 } 382 } 383 384 return 0; 385} 386 387int zx_pinctrl_init(struct platform_device *pdev, 388 struct zx_pinctrl_soc_info *info) 389{ 390 struct pinctrl_desc *pctldesc; 391 struct zx_pinctrl *zpctl; 392 struct device_node *np; 393 struct resource *res; 394 int ret; 395 396 zpctl = devm_kzalloc(&pdev->dev, sizeof(*zpctl), GFP_KERNEL); 397 if (!zpctl) 398 return -ENOMEM; 399 400 spin_lock_init(&zpctl->lock); 401 402 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 403 zpctl->base = devm_ioremap_resource(&pdev->dev, res); 404 if (IS_ERR(zpctl->base)) 405 return PTR_ERR(zpctl->base); 406 407 np = of_parse_phandle(pdev->dev.of_node, "zte,auxiliary-controller", 0); 408 if (!np) { 409 dev_err(&pdev->dev, "failed to find auxiliary controller\n"); 410 return -ENODEV; 411 } 412 413 zpctl->aux_base = of_iomap(np, 0); 414 if (!zpctl->aux_base) 415 return -ENOMEM; 416 417 zpctl->dev = &pdev->dev; 418 zpctl->info = info; 419 420 pctldesc = devm_kzalloc(&pdev->dev, sizeof(*pctldesc), GFP_KERNEL); 421 if (!pctldesc) 422 return -ENOMEM; 423 424 pctldesc->name = dev_name(&pdev->dev); 425 pctldesc->owner = THIS_MODULE; 426 pctldesc->pins = info->pins; 427 pctldesc->npins = info->npins; 428 pctldesc->pctlops = &zx_pinctrl_ops; 429 pctldesc->pmxops = &zx_pinmux_ops; 430 pctldesc->confops = &zx_pinconf_ops; 431 432 zpctl->pctldev = devm_pinctrl_register(&pdev->dev, pctldesc, zpctl); 433 if (IS_ERR(zpctl->pctldev)) { 434 ret = PTR_ERR(zpctl->pctldev); 435 dev_err(&pdev->dev, "failed to register pinctrl: %d\n", ret); 436 return ret; 437 } 438 439 platform_set_drvdata(pdev, zpctl); 440 441 ret = zx_pinctrl_build_state(pdev); 442 if (ret) { 443 dev_err(&pdev->dev, "failed to build state: %d\n", ret); 444 return ret; 445 } 446 447 dev_info(&pdev->dev, "initialized pinctrl driver\n"); 448 return 0; 449}