]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/pinctrl/pinconf.c
pinctrl: remove an unnecessary cast
[karo-tx-linux.git] / drivers / pinctrl / pinconf.c
1 /*
2  * Core driver for the pin config portions of the pin control subsystem
3  *
4  * Copyright (C) 2011 ST-Ericsson SA
5  * Written on behalf of Linaro for ST-Ericsson
6  *
7  * Author: Linus Walleij <linus.walleij@linaro.org>
8  *
9  * License terms: GNU General Public License (GPL) version 2
10  */
11 #define pr_fmt(fmt) "pinconfig core: " fmt
12
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/device.h>
17 #include <linux/slab.h>
18 #include <linux/debugfs.h>
19 #include <linux/seq_file.h>
20 #include <linux/uaccess.h>
21 #include <linux/pinctrl/machine.h>
22 #include <linux/pinctrl/pinctrl.h>
23 #include <linux/pinctrl/pinconf.h>
24 #include "core.h"
25 #include "pinconf.h"
26
27 int pinconf_check_ops(struct pinctrl_dev *pctldev)
28 {
29         const struct pinconf_ops *ops = pctldev->desc->confops;
30
31         /* We must be able to read out pin status */
32         if (!ops->pin_config_get && !ops->pin_config_group_get) {
33                 dev_err(pctldev->dev,
34                         "pinconf must be able to read out pin status\n");
35                 return -EINVAL;
36         }
37         /* We have to be able to config the pins in SOME way */
38         if (!ops->pin_config_set && !ops->pin_config_group_set) {
39                 dev_err(pctldev->dev,
40                         "pinconf has to be able to set a pins config\n");
41                 return -EINVAL;
42         }
43         return 0;
44 }
45
46 int pinconf_validate_map(struct pinctrl_map const *map, int i)
47 {
48         if (!map->data.configs.group_or_pin) {
49                 pr_err("failed to register map %s (%d): no group/pin given\n",
50                        map->name, i);
51                 return -EINVAL;
52         }
53
54         if (!map->data.configs.num_configs ||
55                         !map->data.configs.configs) {
56                 pr_err("failed to register map %s (%d): no configs given\n",
57                        map->name, i);
58                 return -EINVAL;
59         }
60
61         return 0;
62 }
63
64 int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
65                            unsigned long *config)
66 {
67         const struct pinconf_ops *ops = pctldev->desc->confops;
68
69         if (!ops || !ops->pin_config_get) {
70                 dev_err(pctldev->dev, "cannot get pin configuration, missing "
71                         "pin_config_get() function in driver\n");
72                 return -EINVAL;
73         }
74
75         return ops->pin_config_get(pctldev, pin, config);
76 }
77
78 int pin_config_group_get(const char *dev_name, const char *pin_group,
79                          unsigned long *config)
80 {
81         struct pinctrl_dev *pctldev;
82         const struct pinconf_ops *ops;
83         int selector, ret;
84
85         pctldev = get_pinctrl_dev_from_devname(dev_name);
86         if (!pctldev) {
87                 ret = -EINVAL;
88                 return ret;
89         }
90
91         mutex_lock(&pctldev->mutex);
92
93         ops = pctldev->desc->confops;
94
95         if (!ops || !ops->pin_config_group_get) {
96                 dev_err(pctldev->dev, "cannot get configuration for pin "
97                         "group, missing group config get function in "
98                         "driver\n");
99                 ret = -EINVAL;
100                 goto unlock;
101         }
102
103         selector = pinctrl_get_group_selector(pctldev, pin_group);
104         if (selector < 0) {
105                 ret = selector;
106                 goto unlock;
107         }
108
109         ret = ops->pin_config_group_get(pctldev, selector, config);
110
111 unlock:
112         mutex_unlock(&pctldev->mutex);
113         return ret;
114 }
115
116 int pinconf_map_to_setting(struct pinctrl_map const *map,
117                           struct pinctrl_setting *setting)
118 {
119         struct pinctrl_dev *pctldev = setting->pctldev;
120         int pin;
121
122         switch (setting->type) {
123         case PIN_MAP_TYPE_CONFIGS_PIN:
124                 pin = pin_get_from_name(pctldev,
125                                         map->data.configs.group_or_pin);
126                 if (pin < 0) {
127                         dev_err(pctldev->dev, "could not map pin config for \"%s\"",
128                                 map->data.configs.group_or_pin);
129                         return pin;
130                 }
131                 setting->data.configs.group_or_pin = pin;
132                 break;
133         case PIN_MAP_TYPE_CONFIGS_GROUP:
134                 pin = pinctrl_get_group_selector(pctldev,
135                                          map->data.configs.group_or_pin);
136                 if (pin < 0) {
137                         dev_err(pctldev->dev, "could not map group config for \"%s\"",
138                                 map->data.configs.group_or_pin);
139                         return pin;
140                 }
141                 setting->data.configs.group_or_pin = pin;
142                 break;
143         default:
144                 return -EINVAL;
145         }
146
147         setting->data.configs.num_configs = map->data.configs.num_configs;
148         setting->data.configs.configs = map->data.configs.configs;
149
150         return 0;
151 }
152
153 void pinconf_free_setting(struct pinctrl_setting const *setting)
154 {
155 }
156
157 int pinconf_apply_setting(struct pinctrl_setting const *setting)
158 {
159         struct pinctrl_dev *pctldev = setting->pctldev;
160         const struct pinconf_ops *ops = pctldev->desc->confops;
161         int ret;
162
163         if (!ops) {
164                 dev_err(pctldev->dev, "missing confops\n");
165                 return -EINVAL;
166         }
167
168         switch (setting->type) {
169         case PIN_MAP_TYPE_CONFIGS_PIN:
170                 if (!ops->pin_config_set) {
171                         dev_err(pctldev->dev, "missing pin_config_set op\n");
172                         return -EINVAL;
173                 }
174                 ret = ops->pin_config_set(pctldev,
175                                 setting->data.configs.group_or_pin,
176                                 setting->data.configs.configs,
177                                 setting->data.configs.num_configs);
178                 if (ret < 0) {
179                         dev_err(pctldev->dev,
180                                 "pin_config_set op failed for pin %d\n",
181                                 setting->data.configs.group_or_pin);
182                         return ret;
183                 }
184                 break;
185         case PIN_MAP_TYPE_CONFIGS_GROUP:
186                 if (!ops->pin_config_group_set) {
187                         dev_err(pctldev->dev,
188                                 "missing pin_config_group_set op\n");
189                         return -EINVAL;
190                 }
191                 ret = ops->pin_config_group_set(pctldev,
192                                 setting->data.configs.group_or_pin,
193                                 setting->data.configs.configs,
194                                 setting->data.configs.num_configs);
195                 if (ret < 0) {
196                         dev_err(pctldev->dev,
197                                 "pin_config_group_set op failed for group %d\n",
198                                 setting->data.configs.group_or_pin);
199                         return ret;
200                 }
201                 break;
202         default:
203                 return -EINVAL;
204         }
205
206         return 0;
207 }
208
209 #ifdef CONFIG_DEBUG_FS
210
211 void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
212 {
213         struct pinctrl_dev *pctldev;
214         const struct pinconf_ops *confops;
215         int i;
216
217         pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
218         if (pctldev)
219                 confops = pctldev->desc->confops;
220         else
221                 confops = NULL;
222
223         switch (map->type) {
224         case PIN_MAP_TYPE_CONFIGS_PIN:
225                 seq_printf(s, "pin ");
226                 break;
227         case PIN_MAP_TYPE_CONFIGS_GROUP:
228                 seq_printf(s, "group ");
229                 break;
230         default:
231                 break;
232         }
233
234         seq_printf(s, "%s\n", map->data.configs.group_or_pin);
235
236         for (i = 0; i < map->data.configs.num_configs; i++) {
237                 seq_printf(s, "config ");
238                 if (confops && confops->pin_config_config_dbg_show)
239                         confops->pin_config_config_dbg_show(pctldev, s,
240                                                 map->data.configs.configs[i]);
241                 else
242                         seq_printf(s, "%08lx", map->data.configs.configs[i]);
243                 seq_printf(s, "\n");
244         }
245 }
246
247 void pinconf_show_setting(struct seq_file *s,
248                           struct pinctrl_setting const *setting)
249 {
250         struct pinctrl_dev *pctldev = setting->pctldev;
251         const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
252         const struct pinconf_ops *confops = pctldev->desc->confops;
253         struct pin_desc *desc;
254         int i;
255
256         switch (setting->type) {
257         case PIN_MAP_TYPE_CONFIGS_PIN:
258                 desc = pin_desc_get(setting->pctldev,
259                                     setting->data.configs.group_or_pin);
260                 seq_printf(s, "pin %s (%d)",
261                            desc->name ? desc->name : "unnamed",
262                            setting->data.configs.group_or_pin);
263                 break;
264         case PIN_MAP_TYPE_CONFIGS_GROUP:
265                 seq_printf(s, "group %s (%d)",
266                            pctlops->get_group_name(pctldev,
267                                         setting->data.configs.group_or_pin),
268                            setting->data.configs.group_or_pin);
269                 break;
270         default:
271                 break;
272         }
273
274         /*
275          * FIXME: We should really get the pin controler to dump the config
276          * values, so they can be decoded to something meaningful.
277          */
278         for (i = 0; i < setting->data.configs.num_configs; i++) {
279                 seq_printf(s, " ");
280                 if (confops && confops->pin_config_config_dbg_show)
281                         confops->pin_config_config_dbg_show(pctldev, s,
282                                 setting->data.configs.configs[i]);
283                 else
284                         seq_printf(s, "%08lx",
285                                    setting->data.configs.configs[i]);
286         }
287
288         seq_printf(s, "\n");
289 }
290
291 static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
292                              struct seq_file *s, int pin)
293 {
294         const struct pinconf_ops *ops = pctldev->desc->confops;
295
296         /* no-op when not using generic pin config */
297         pinconf_generic_dump_pin(pctldev, s, pin);
298         if (ops && ops->pin_config_dbg_show)
299                 ops->pin_config_dbg_show(pctldev, s, pin);
300 }
301
302 static int pinconf_pins_show(struct seq_file *s, void *what)
303 {
304         struct pinctrl_dev *pctldev = s->private;
305         const struct pinconf_ops *ops = pctldev->desc->confops;
306         unsigned i, pin;
307
308         if (!ops || !ops->pin_config_get)
309                 return 0;
310
311         seq_puts(s, "Pin config settings per pin\n");
312         seq_puts(s, "Format: pin (name): configs\n");
313
314         mutex_lock(&pctldev->mutex);
315
316         /* The pin number can be retrived from the pin controller descriptor */
317         for (i = 0; i < pctldev->desc->npins; i++) {
318                 struct pin_desc *desc;
319
320                 pin = pctldev->desc->pins[i].number;
321                 desc = pin_desc_get(pctldev, pin);
322                 /* Skip if we cannot search the pin */
323                 if (desc == NULL)
324                         continue;
325
326                 seq_printf(s, "pin %d (%s):", pin,
327                            desc->name ? desc->name : "unnamed");
328
329                 pinconf_dump_pin(pctldev, s, pin);
330
331                 seq_printf(s, "\n");
332         }
333
334         mutex_unlock(&pctldev->mutex);
335
336         return 0;
337 }
338
339 static void pinconf_dump_group(struct pinctrl_dev *pctldev,
340                                struct seq_file *s, unsigned selector,
341                                const char *gname)
342 {
343         const struct pinconf_ops *ops = pctldev->desc->confops;
344
345         /* no-op when not using generic pin config */
346         pinconf_generic_dump_group(pctldev, s, gname);
347         if (ops && ops->pin_config_group_dbg_show)
348                 ops->pin_config_group_dbg_show(pctldev, s, selector);
349 }
350
351 static int pinconf_groups_show(struct seq_file *s, void *what)
352 {
353         struct pinctrl_dev *pctldev = s->private;
354         const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
355         const struct pinconf_ops *ops = pctldev->desc->confops;
356         unsigned ngroups = pctlops->get_groups_count(pctldev);
357         unsigned selector = 0;
358
359         if (!ops || !ops->pin_config_group_get)
360                 return 0;
361
362         seq_puts(s, "Pin config settings per pin group\n");
363         seq_puts(s, "Format: group (name): configs\n");
364
365         while (selector < ngroups) {
366                 const char *gname = pctlops->get_group_name(pctldev, selector);
367
368                 seq_printf(s, "%u (%s):", selector, gname);
369                 pinconf_dump_group(pctldev, s, selector, gname);
370                 seq_printf(s, "\n");
371
372                 selector++;
373         }
374
375         return 0;
376 }
377
378 static int pinconf_pins_open(struct inode *inode, struct file *file)
379 {
380         return single_open(file, pinconf_pins_show, inode->i_private);
381 }
382
383 static int pinconf_groups_open(struct inode *inode, struct file *file)
384 {
385         return single_open(file, pinconf_groups_show, inode->i_private);
386 }
387
388 static const struct file_operations pinconf_pins_ops = {
389         .open           = pinconf_pins_open,
390         .read           = seq_read,
391         .llseek         = seq_lseek,
392         .release        = single_release,
393 };
394
395 static const struct file_operations pinconf_groups_ops = {
396         .open           = pinconf_groups_open,
397         .read           = seq_read,
398         .llseek         = seq_lseek,
399         .release        = single_release,
400 };
401
402 #define MAX_NAME_LEN 15
403
404 struct dbg_cfg {
405         enum pinctrl_map_type map_type;
406         char dev_name[MAX_NAME_LEN+1];
407         char state_name[MAX_NAME_LEN+1];
408         char pin_name[MAX_NAME_LEN+1];
409 };
410
411 /*
412  * Goal is to keep this structure as global in order to simply read the
413  * pinconf-config file after a write to check config is as expected
414  */
415 static struct dbg_cfg pinconf_dbg_conf;
416
417 /**
418  * pinconf_dbg_config_print() - display the pinctrl config from the pinctrl
419  * map, of the dev/pin/state that was last written to pinconf-config file.
420  * @s: string filled in  with config description
421  * @d: not used
422  */
423 static int pinconf_dbg_config_print(struct seq_file *s, void *d)
424 {
425         struct pinctrl_maps *maps_node;
426         const struct pinctrl_map *map;
427         const struct pinctrl_map *found = NULL;
428         struct pinctrl_dev *pctldev;
429         const struct pinconf_ops *confops = NULL;
430         struct dbg_cfg *dbg = &pinconf_dbg_conf;
431         int i, j;
432         unsigned long config;
433
434         mutex_lock(&pinctrl_maps_mutex);
435
436         /* Parse the pinctrl map and look for the elected pin/state */
437         for_each_maps(maps_node, i, map) {
438                 if (map->type != dbg->map_type)
439                         continue;
440                 if (strcmp(map->dev_name, dbg->dev_name))
441                         continue;
442                 if (strcmp(map->name, dbg->state_name))
443                         continue;
444
445                 for (j = 0; j < map->data.configs.num_configs; j++) {
446                         if (!strcmp(map->data.configs.group_or_pin,
447                                         dbg->pin_name)) {
448                                 /* We found the right pin / state */
449                                 found = map;
450                                 break;
451                         }
452                 }
453         }
454
455         if (!found) {
456                 seq_printf(s, "No config found for dev/state/pin, expected:\n");
457                 seq_printf(s, "Searched dev:%s\n", dbg->dev_name);
458                 seq_printf(s, "Searched state:%s\n", dbg->state_name);
459                 seq_printf(s, "Searched pin:%s\n", dbg->pin_name);
460                 seq_printf(s, "Use: modify config_pin <devname> "\
461                                 "<state> <pinname> <value>\n");
462                 goto exit;
463         }
464
465         pctldev = get_pinctrl_dev_from_devname(found->ctrl_dev_name);
466         config = *found->data.configs.configs;
467         seq_printf(s, "Dev %s has config of %s in state %s: 0x%08lX\n",
468                         dbg->dev_name, dbg->pin_name,
469                         dbg->state_name, config);
470
471         if (pctldev)
472                 confops = pctldev->desc->confops;
473
474         if (confops && confops->pin_config_config_dbg_show)
475                 confops->pin_config_config_dbg_show(pctldev, s, config);
476
477 exit:
478         mutex_unlock(&pinctrl_maps_mutex);
479
480         return 0;
481 }
482
483 /**
484  * pinconf_dbg_config_write() - modify the pinctrl config in the pinctrl
485  * map, of a dev/pin/state entry based on user entries to pinconf-config
486  * @user_buf: contains the modification request with expected format:
487  *     modify config_pin <devicename> <state> <pinname> <newvalue>
488  * modify is literal string, alternatives like add/delete not supported yet
489  * config_pin is literal, alternatives like config_mux not supported yet
490  * <devicename> <state> <pinname> are values that should match the pinctrl-maps
491  * <newvalue> reflects the new config and is driver dependant
492  */
493 static ssize_t pinconf_dbg_config_write(struct file *file,
494         const char __user *user_buf, size_t count, loff_t *ppos)
495 {
496         struct pinctrl_maps *maps_node;
497         const struct pinctrl_map *map;
498         const struct pinctrl_map *found = NULL;
499         struct pinctrl_dev *pctldev;
500         const struct pinconf_ops *confops = NULL;
501         struct dbg_cfg *dbg = &pinconf_dbg_conf;
502         const struct pinctrl_map_configs *configs;
503         char config[MAX_NAME_LEN+1];
504         char buf[128];
505         char *b = &buf[0];
506         int buf_size;
507         char *token;
508         int i;
509
510         /* Get userspace string and assure termination */
511         buf_size = min(count, sizeof(buf) - 1);
512         if (copy_from_user(buf, user_buf, buf_size))
513                 return -EFAULT;
514         buf[buf_size] = 0;
515
516         /*
517          * need to parse entry and extract parameters:
518          * modify configs_pin devicename state pinname newvalue
519          */
520
521         /* Get arg: 'modify' */
522         token = strsep(&b, " ");
523         if (!token)
524                 return -EINVAL;
525         if (strcmp(token, "modify"))
526                 return -EINVAL;
527
528         /* Get arg type: "config_pin" type supported so far */
529         token = strsep(&b, " ");
530         if (!token)
531                 return -EINVAL;
532         if (strcmp(token, "config_pin"))
533                 return -EINVAL;
534         dbg->map_type = PIN_MAP_TYPE_CONFIGS_PIN;
535
536         /* get arg 'device_name' */
537         token = strsep(&b, " ");
538         if (token == NULL)
539                 return -EINVAL;
540         if (strlen(token) >= MAX_NAME_LEN)
541                 return -EINVAL;
542         strncpy(dbg->dev_name, token, MAX_NAME_LEN);
543
544         /* get arg 'state_name' */
545         token = strsep(&b, " ");
546         if (token == NULL)
547                 return -EINVAL;
548         if (strlen(token) >= MAX_NAME_LEN)
549                 return -EINVAL;
550         strncpy(dbg->state_name, token, MAX_NAME_LEN);
551
552         /* get arg 'pin_name' */
553         token = strsep(&b, " ");
554         if (token == NULL)
555                 return -EINVAL;
556         if (strlen(token) >= MAX_NAME_LEN)
557                 return -EINVAL;
558         strncpy(dbg->pin_name, token, MAX_NAME_LEN);
559
560         /* get new_value of config' */
561         token = strsep(&b, " ");
562         if (token == NULL)
563                 return -EINVAL;
564         if (strlen(token) >= MAX_NAME_LEN)
565                 return -EINVAL;
566         strncpy(config, token, MAX_NAME_LEN);
567
568         mutex_lock(&pinctrl_maps_mutex);
569
570         /* Parse the pinctrl map and look for the selected dev/state/pin */
571         for_each_maps(maps_node, i, map) {
572                 if (strcmp(map->dev_name, dbg->dev_name))
573                         continue;
574                 if (map->type != dbg->map_type)
575                         continue;
576                 if (strcmp(map->name, dbg->state_name))
577                         continue;
578
579                 /*  we found the right pin / state, so overwrite config */
580                 if (!strcmp(map->data.configs.group_or_pin, dbg->pin_name)) {
581                         found = map;
582                         break;
583                 }
584         }
585
586         if (!found) {
587                 count = -EINVAL;
588                 goto exit;
589         }
590
591         pctldev = get_pinctrl_dev_from_devname(found->ctrl_dev_name);
592         if (pctldev)
593                 confops = pctldev->desc->confops;
594
595         if (confops && confops->pin_config_dbg_parse_modify) {
596                 configs = &found->data.configs;
597                 for (i = 0; i < configs->num_configs; i++) {
598                         confops->pin_config_dbg_parse_modify(pctldev,
599                                                      config,
600                                                      &configs->configs[i]);
601                 }
602         }
603
604 exit:
605         mutex_unlock(&pinctrl_maps_mutex);
606
607         return count;
608 }
609
610 static int pinconf_dbg_config_open(struct inode *inode, struct file *file)
611 {
612         return single_open(file, pinconf_dbg_config_print, inode->i_private);
613 }
614
615 static const struct file_operations pinconf_dbg_pinconfig_fops = {
616         .open = pinconf_dbg_config_open,
617         .write = pinconf_dbg_config_write,
618         .read = seq_read,
619         .llseek = seq_lseek,
620         .release = single_release,
621         .owner = THIS_MODULE,
622 };
623
624 void pinconf_init_device_debugfs(struct dentry *devroot,
625                          struct pinctrl_dev *pctldev)
626 {
627         debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO,
628                             devroot, pctldev, &pinconf_pins_ops);
629         debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
630                             devroot, pctldev, &pinconf_groups_ops);
631         debugfs_create_file("pinconf-config",  (S_IRUGO | S_IWUSR | S_IWGRP),
632                             devroot, pctldev, &pinconf_dbg_pinconfig_fops);
633 }
634
635 #endif