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 v3.6 234 lines 6.2 kB view raw
1/* 2 * linux/drivers/pinctrl/pinctrl-pxa3xx.c 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * publishhed by the Free Software Foundation. 7 * 8 * Copyright (C) 2011, Marvell Technology Group Ltd. 9 * 10 * Author: Haojian Zhuang <haojian.zhuang@marvell.com> 11 * 12 */ 13 14#include <linux/module.h> 15#include <linux/device.h> 16#include <linux/io.h> 17#include <linux/platform_device.h> 18#include <linux/slab.h> 19#include "pinctrl-pxa3xx.h" 20 21static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = { 22 .name = "PXA3xx GPIO", 23 .id = 0, 24 .base = 0, 25 .pin_base = 0, 26}; 27 28static int pxa3xx_get_groups_count(struct pinctrl_dev *pctrldev) 29{ 30 struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); 31 32 return info->num_grps; 33} 34 35static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev, 36 unsigned selector) 37{ 38 struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); 39 40 return info->grps[selector].name; 41} 42 43static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev, 44 unsigned selector, 45 const unsigned **pins, 46 unsigned *num_pins) 47{ 48 struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); 49 50 *pins = info->grps[selector].pins; 51 *num_pins = info->grps[selector].npins; 52 return 0; 53} 54 55static struct pinctrl_ops pxa3xx_pctrl_ops = { 56 .get_groups_count = pxa3xx_get_groups_count, 57 .get_group_name = pxa3xx_get_group_name, 58 .get_group_pins = pxa3xx_get_group_pins, 59}; 60 61static int pxa3xx_pmx_get_funcs_count(struct pinctrl_dev *pctrldev) 62{ 63 struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); 64 65 return info->num_funcs; 66} 67 68static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev, 69 unsigned func) 70{ 71 struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); 72 return info->funcs[func].name; 73} 74 75static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func, 76 const char * const **groups, 77 unsigned * const num_groups) 78{ 79 struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); 80 *groups = info->funcs[func].groups; 81 *num_groups = info->funcs[func].num_groups; 82 return 0; 83} 84 85/* Return function number. If failure, return negative value. */ 86static int match_mux(struct pxa3xx_mfp_pin *mfp, unsigned mux) 87{ 88 int i; 89 for (i = 0; i < PXA3xx_MAX_MUX; i++) { 90 if (mfp->func[i] == mux) 91 break; 92 } 93 if (i >= PXA3xx_MAX_MUX) 94 return -EINVAL; 95 return i; 96} 97 98/* check whether current pin configuration is valid. Negative for failure */ 99static int match_group_mux(struct pxa3xx_pin_group *grp, 100 struct pxa3xx_pinmux_info *info, 101 unsigned mux) 102{ 103 int i, pin, ret = 0; 104 for (i = 0; i < grp->npins; i++) { 105 pin = grp->pins[i]; 106 ret = match_mux(&info->mfp[pin], mux); 107 if (ret < 0) { 108 dev_err(info->dev, "Can't find mux %d on pin%d\n", 109 mux, pin); 110 break; 111 } 112 } 113 return ret; 114} 115 116static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func, 117 unsigned group) 118{ 119 struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); 120 struct pxa3xx_pin_group *pin_grp = &info->grps[group]; 121 unsigned int data; 122 int i, mfpr, pin, pin_func; 123 124 if (!pin_grp->npins || 125 (match_group_mux(pin_grp, info, pin_grp->mux) < 0)) { 126 dev_err(info->dev, "Failed to set the pin group: %d\n", group); 127 return -EINVAL; 128 } 129 for (i = 0; i < pin_grp->npins; i++) { 130 pin = pin_grp->pins[i]; 131 pin_func = match_mux(&info->mfp[pin], pin_grp->mux); 132 mfpr = info->mfp[pin].mfpr; 133 data = readl_relaxed(info->virt_base + mfpr); 134 data &= ~MFPR_FUNC_MASK; 135 data |= pin_func; 136 writel_relaxed(data, info->virt_base + mfpr); 137 } 138 return 0; 139} 140 141static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev, 142 struct pinctrl_gpio_range *range, 143 unsigned pin) 144{ 145 struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); 146 unsigned int data; 147 int pin_func, mfpr; 148 149 pin_func = match_mux(&info->mfp[pin], PXA3xx_MUX_GPIO); 150 if (pin_func < 0) { 151 dev_err(info->dev, "No GPIO function on pin%d (%s)\n", 152 pin, info->pads[pin].name); 153 return -EINVAL; 154 } 155 mfpr = info->mfp[pin].mfpr; 156 /* write gpio function into mfpr register */ 157 data = readl_relaxed(info->virt_base + mfpr) & ~MFPR_FUNC_MASK; 158 data |= pin_func; 159 writel_relaxed(data, info->virt_base + mfpr); 160 return 0; 161} 162 163static struct pinmux_ops pxa3xx_pmx_ops = { 164 .get_functions_count = pxa3xx_pmx_get_funcs_count, 165 .get_function_name = pxa3xx_pmx_get_func_name, 166 .get_function_groups = pxa3xx_pmx_get_groups, 167 .enable = pxa3xx_pmx_enable, 168 .gpio_request_enable = pxa3xx_pmx_request_gpio, 169}; 170 171int pxa3xx_pinctrl_register(struct platform_device *pdev, 172 struct pxa3xx_pinmux_info *info) 173{ 174 struct pinctrl_desc *desc; 175 struct resource *res; 176 int ret = 0; 177 178 if (!info || !info->cputype) 179 return -EINVAL; 180 desc = info->desc; 181 desc->pins = info->pads; 182 desc->npins = info->num_pads; 183 desc->pctlops = &pxa3xx_pctrl_ops; 184 desc->pmxops = &pxa3xx_pmx_ops; 185 info->dev = &pdev->dev; 186 pxa3xx_pinctrl_gpio_range.npins = info->num_gpio; 187 188 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 189 if (!res) 190 return -ENOENT; 191 info->phy_base = res->start; 192 info->phy_size = resource_size(res); 193 info->virt_base = ioremap(info->phy_base, info->phy_size); 194 if (!info->virt_base) 195 return -ENOMEM; 196 info->pctrl = pinctrl_register(desc, &pdev->dev, info); 197 if (!info->pctrl) { 198 dev_err(&pdev->dev, "failed to register PXA pinmux driver\n"); 199 ret = -EINVAL; 200 goto err; 201 } 202 pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range); 203 platform_set_drvdata(pdev, info); 204 return 0; 205err: 206 iounmap(info->virt_base); 207 return ret; 208} 209 210int pxa3xx_pinctrl_unregister(struct platform_device *pdev) 211{ 212 struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev); 213 214 pinctrl_unregister(info->pctrl); 215 iounmap(info->virt_base); 216 platform_set_drvdata(pdev, NULL); 217 return 0; 218} 219 220static int __init pxa3xx_pinctrl_init(void) 221{ 222 pr_info("pxa3xx-pinctrl: PXA3xx pinctrl driver initializing\n"); 223 return 0; 224} 225core_initcall_sync(pxa3xx_pinctrl_init); 226 227static void __exit pxa3xx_pinctrl_exit(void) 228{ 229} 230module_exit(pxa3xx_pinctrl_exit); 231 232MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 233MODULE_DESCRIPTION("PXA3xx pin control driver"); 234MODULE_LICENSE("GPL v2");