Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pinctrl-spear.c
Go to the documentation of this file.
1 /*
2  * Driver for the ST Microelectronics SPEAr pinmux
3  *
4  * Copyright (C) 2012 ST Microelectronics
5  * Viresh Kumar <[email protected]>
6  *
7  * Inspired from:
8  * - U300 Pinctl drivers
9  * - Tegra Pinctl drivers
10  *
11  * This file is licensed under the terms of the GNU General Public
12  * License version 2. This program is licensed "as is" without any
13  * warranty of any kind, whether express or implied.
14  */
15 
16 #include <linux/err.h>
17 #include <linux/io.h>
18 #include <linux/module.h>
19 #include <linux/of.h>
20 #include <linux/of_address.h>
21 #include <linux/pinctrl/machine.h>
22 #include <linux/pinctrl/pinctrl.h>
23 #include <linux/pinctrl/pinmux.h>
24 #include <linux/platform_device.h>
25 #include <linux/slab.h>
26 
27 #include "pinctrl-spear.h"
28 
29 #define DRIVER_NAME "spear-pinmux"
30 
31 static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg)
32 {
33  return readl_relaxed(pmx->vbase + reg);
34 }
35 
36 static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg)
37 {
38  writel_relaxed(val, pmx->vbase + reg);
39 }
40 
41 static int set_mode(struct spear_pmx *pmx, int mode)
42 {
43  struct spear_pmx_mode *pmx_mode = NULL;
44  int i;
45  u32 val;
46 
47  if (!pmx->machdata->pmx_modes || !pmx->machdata->npmx_modes)
48  return -EINVAL;
49 
50  for (i = 0; i < pmx->machdata->npmx_modes; i++) {
51  if (pmx->machdata->pmx_modes[i]->mode == (1 << mode)) {
52  pmx_mode = pmx->machdata->pmx_modes[i];
53  break;
54  }
55  }
56 
57  if (!pmx_mode)
58  return -EINVAL;
59 
60  val = pmx_readl(pmx, pmx_mode->reg);
61  val &= ~pmx_mode->mask;
62  val |= pmx_mode->val;
63  pmx_writel(pmx, val, pmx_mode->reg);
64 
65  pmx->machdata->mode = pmx_mode->mode;
66  dev_info(pmx->dev, "Configured Mode: %s with id: %x\n\n",
67  pmx_mode->name ? pmx_mode->name : "no_name",
68  pmx_mode->reg);
69 
70  return 0;
71 }
72 
74 {
75  struct spear_pingroup *pgroup;
76  struct spear_modemux *modemux;
77  int i, j, group;
78 
79  for (group = 0; group < machdata->ngroups; group++) {
80  pgroup = machdata->groups[group];
81 
82  for (i = 0; i < pgroup->nmodemuxs; i++) {
83  modemux = &pgroup->modemuxs[i];
84 
85  for (j = 0; j < modemux->nmuxregs; j++)
86  if (modemux->muxregs[j].reg == 0xFFFF)
87  modemux->muxregs[j].reg = reg;
88  }
89  }
90 }
91 
92 static int spear_pinctrl_get_groups_cnt(struct pinctrl_dev *pctldev)
93 {
94  struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
95 
96  return pmx->machdata->ngroups;
97 }
98 
99 static const char *spear_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
100  unsigned group)
101 {
102  struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
103 
104  return pmx->machdata->groups[group]->name;
105 }
106 
107 static int spear_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
108  unsigned group, const unsigned **pins, unsigned *num_pins)
109 {
110  struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
111 
112  *pins = pmx->machdata->groups[group]->pins;
113  *num_pins = pmx->machdata->groups[group]->npins;
114 
115  return 0;
116 }
117 
118 static void spear_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
119  struct seq_file *s, unsigned offset)
120 {
121  seq_printf(s, " " DRIVER_NAME);
122 }
123 
125  struct device_node *np_config,
126  struct pinctrl_map **map, unsigned *num_maps)
127 {
128  struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
129  struct device_node *np;
130  struct property *prop;
131  const char *function, *group;
132  int ret, index = 0, count = 0;
133 
134  /* calculate number of maps required */
135  for_each_child_of_node(np_config, np) {
136  ret = of_property_read_string(np, "st,function", &function);
137  if (ret < 0)
138  return ret;
139 
140  ret = of_property_count_strings(np, "st,pins");
141  if (ret < 0)
142  return ret;
143 
144  count += ret;
145  }
146 
147  if (!count) {
148  dev_err(pmx->dev, "No child nodes passed via DT\n");
149  return -ENODEV;
150  }
151 
152  *map = kzalloc(sizeof(**map) * count, GFP_KERNEL);
153  if (!*map)
154  return -ENOMEM;
155 
156  for_each_child_of_node(np_config, np) {
157  of_property_read_string(np, "st,function", &function);
158  of_property_for_each_string(np, "st,pins", prop, group) {
159  (*map)[index].type = PIN_MAP_TYPE_MUX_GROUP;
160  (*map)[index].data.mux.group = group;
161  (*map)[index].data.mux.function = function;
162  index++;
163  }
164  }
165 
166  *num_maps = count;
167 
168  return 0;
169 }
170 
172  struct pinctrl_map *map, unsigned num_maps)
173 {
174  kfree(map);
175 }
176 
177 static struct pinctrl_ops spear_pinctrl_ops = {
178  .get_groups_count = spear_pinctrl_get_groups_cnt,
179  .get_group_name = spear_pinctrl_get_group_name,
180  .get_group_pins = spear_pinctrl_get_group_pins,
181  .pin_dbg_show = spear_pinctrl_pin_dbg_show,
182  .dt_node_to_map = spear_pinctrl_dt_node_to_map,
183  .dt_free_map = spear_pinctrl_dt_free_map,
184 };
185 
186 static int spear_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
187 {
188  struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
189 
190  return pmx->machdata->nfunctions;
191 }
192 
193 static const char *spear_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
194  unsigned function)
195 {
196  struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
197 
198  return pmx->machdata->functions[function]->name;
199 }
200 
201 static int spear_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
202  unsigned function, const char *const **groups,
203  unsigned * const ngroups)
204 {
205  struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
206 
207  *groups = pmx->machdata->functions[function]->groups;
208  *ngroups = pmx->machdata->functions[function]->ngroups;
209 
210  return 0;
211 }
212 
213 static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
214  unsigned function, unsigned group, bool enable)
215 {
216  struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
217  const struct spear_pingroup *pgroup;
218  const struct spear_modemux *modemux;
219  struct spear_muxreg *muxreg;
220  u32 val, temp;
221  int i, j;
222  bool found = false;
223 
224  pgroup = pmx->machdata->groups[group];
225 
226  for (i = 0; i < pgroup->nmodemuxs; i++) {
227  modemux = &pgroup->modemuxs[i];
228 
229  /* SoC have any modes */
230  if (pmx->machdata->modes_supported) {
231  if (!(pmx->machdata->mode & modemux->modes))
232  continue;
233  }
234 
235  found = true;
236  for (j = 0; j < modemux->nmuxregs; j++) {
237  muxreg = &modemux->muxregs[j];
238 
239  val = pmx_readl(pmx, muxreg->reg);
240  val &= ~muxreg->mask;
241 
242  if (enable)
243  temp = muxreg->val;
244  else
245  temp = ~muxreg->val;
246 
247  val |= muxreg->mask & temp;
248  pmx_writel(pmx, val, muxreg->reg);
249  }
250  }
251 
252  if (!found) {
253  dev_err(pmx->dev, "pinmux group: %s not supported\n",
254  pgroup->name);
255  return -ENODEV;
256  }
257 
258  return 0;
259 }
260 
261 static int spear_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
262  unsigned group)
263 {
264  return spear_pinctrl_endisable(pctldev, function, group, true);
265 }
266 
267 static void spear_pinctrl_disable(struct pinctrl_dev *pctldev,
268  unsigned function, unsigned group)
269 {
270  spear_pinctrl_endisable(pctldev, function, group, false);
271 }
272 
273 static struct pinmux_ops spear_pinmux_ops = {
274  .get_functions_count = spear_pinctrl_get_funcs_count,
275  .get_function_name = spear_pinctrl_get_func_name,
276  .get_function_groups = spear_pinctrl_get_func_groups,
277  .enable = spear_pinctrl_enable,
278  .disable = spear_pinctrl_disable,
279 };
280 
281 static struct pinctrl_desc spear_pinctrl_desc = {
282  .name = DRIVER_NAME,
283  .pctlops = &spear_pinctrl_ops,
284  .pmxops = &spear_pinmux_ops,
285  .owner = THIS_MODULE,
286 };
287 
289  struct spear_pinctrl_machdata *machdata)
290 {
291  struct device_node *np = pdev->dev.of_node;
292  struct resource *res;
293  struct spear_pmx *pmx;
294 
295  if (!machdata)
296  return -ENODEV;
297 
298  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
299  if (!res)
300  return -EINVAL;
301 
302  pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
303  if (!pmx) {
304  dev_err(&pdev->dev, "Can't alloc spear_pmx\n");
305  return -ENOMEM;
306  }
307 
308  pmx->vbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
309  if (!pmx->vbase) {
310  dev_err(&pdev->dev, "Couldn't ioremap at index 0\n");
311  return -ENODEV;
312  }
313 
314  pmx->dev = &pdev->dev;
315  pmx->machdata = machdata;
316 
317  /* configure mode, if supported by SoC */
318  if (machdata->modes_supported) {
319  int mode = 0;
320 
321  if (of_property_read_u32(np, "st,pinmux-mode", &mode)) {
322  dev_err(&pdev->dev, "OF: pinmux mode not passed\n");
323  return -EINVAL;
324  }
325 
326  if (set_mode(pmx, mode)) {
327  dev_err(&pdev->dev, "OF: Couldn't configure mode: %x\n",
328  mode);
329  return -EINVAL;
330  }
331  }
332 
333  platform_set_drvdata(pdev, pmx);
334 
335  spear_pinctrl_desc.pins = machdata->pins;
336  spear_pinctrl_desc.npins = machdata->npins;
337 
338  pmx->pctl = pinctrl_register(&spear_pinctrl_desc, &pdev->dev, pmx);
339  if (!pmx->pctl) {
340  dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
341  return -ENODEV;
342  }
343 
344  return 0;
345 }
346 
348 {
349  struct spear_pmx *pmx = platform_get_drvdata(pdev);
350 
351  pinctrl_unregister(pmx->pctl);
352 
353  return 0;
354 }