pinconf.c 14.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 * Core driver for the pin config portions of the pin control subsystem
 *
 * Copyright (C) 2011 ST-Ericsson SA
 * Written on behalf of Linaro for ST-Ericsson
 *
 * Author: Linus Walleij <linus.walleij@linaro.org>
 *
 * License terms: GNU General Public License (GPL) version 2
 */
#define pr_fmt(fmt) "pinconfig core: " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include "core.h"
#include "pinconf.h"

26 27 28 29 30
int pinconf_check_ops(struct pinctrl_dev *pctldev)
{
	const struct pinconf_ops *ops = pctldev->desc->confops;

	/* We must be able to read out pin status */
31 32 33
	if (!ops->pin_config_get && !ops->pin_config_group_get) {
		dev_err(pctldev->dev,
			"pinconf must be able to read out pin status\n");
34
		return -EINVAL;
35
	}
36
	/* We have to be able to config the pins in SOME way */
37 38 39
	if (!ops->pin_config_set && !ops->pin_config_group_set) {
		dev_err(pctldev->dev,
			"pinconf has to be able to set a pins config\n");
40
		return -EINVAL;
41
	}
42 43 44
	return 0;
}

45 46 47 48 49 50 51 52
int pinconf_validate_map(struct pinctrl_map const *map, int i)
{
	if (!map->data.configs.group_or_pin) {
		pr_err("failed to register map %s (%d): no group/pin given\n",
		       map->name, i);
		return -EINVAL;
	}

53
	if (!map->data.configs.num_configs ||
54
			!map->data.configs.configs) {
55
		pr_err("failed to register map %s (%d): no configs given\n",
56 57 58 59 60 61 62
		       map->name, i);
		return -EINVAL;
	}

	return 0;
}

63
int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
64 65 66 67 68
			   unsigned long *config)
{
	const struct pinconf_ops *ops = pctldev->desc->confops;

	if (!ops || !ops->pin_config_get) {
69
		dev_err(pctldev->dev, "cannot get pin configuration, missing "
70 71 72 73 74 75 76 77 78
			"pin_config_get() function in driver\n");
		return -EINVAL;
	}

	return ops->pin_config_get(pctldev, pin, config);
}

/**
 * pin_config_get() - get the configuration of a single pin parameter
79
 * @dev_name: name of the pin controller device for this pin
80 81 82 83 84
 * @name: name of the pin to get the config for
 * @config: the config pointed to by this argument will be filled in with the
 *	current pin state, it can be used directly by drivers as a numeral, or
 *	it can be dereferenced to any struct.
 */
85
int pin_config_get(const char *dev_name, const char *name,
86 87
			  unsigned long *config)
{
88
	struct pinctrl_dev *pctldev;
89 90
	int pin;

91 92
	mutex_lock(&pinctrl_mutex);

93
	pctldev = get_pinctrl_dev_from_devname(dev_name);
94 95 96 97
	if (!pctldev) {
		pin = -EINVAL;
		goto unlock;
	}
98

99 100
	pin = pin_get_from_name(pctldev, name);
	if (pin < 0)
101
		goto unlock;
102

103 104 105 106 107
	pin = pin_config_get_for_pin(pctldev, pin, config);

unlock:
	mutex_unlock(&pinctrl_mutex);
	return pin;
108 109 110
}
EXPORT_SYMBOL(pin_config_get);

111
static int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
112 113 114 115 116 117
			   unsigned long config)
{
	const struct pinconf_ops *ops = pctldev->desc->confops;
	int ret;

	if (!ops || !ops->pin_config_set) {
118
		dev_err(pctldev->dev, "cannot configure pin, missing "
119 120 121 122 123 124
			"config function in driver\n");
		return -EINVAL;
	}

	ret = ops->pin_config_set(pctldev, pin, config);
	if (ret) {
125
		dev_err(pctldev->dev,
126 127 128 129 130 131 132 133 134
			"unable to set pin configuration on pin %d\n", pin);
		return ret;
	}

	return 0;
}

/**
 * pin_config_set() - set the configuration of a single pin parameter
135
 * @dev_name: name of pin controller device for this pin
136 137 138 139 140
 * @name: name of the pin to set the config for
 * @config: the config in this argument will contain the desired pin state, it
 *	can be used directly by drivers as a numeral, or it can be dereferenced
 *	to any struct.
 */
141
int pin_config_set(const char *dev_name, const char *name,
142 143
		   unsigned long config)
{
144
	struct pinctrl_dev *pctldev;
145 146 147
	int pin, ret;

	mutex_lock(&pinctrl_mutex);
148

149
	pctldev = get_pinctrl_dev_from_devname(dev_name);
150 151 152 153
	if (!pctldev) {
		ret = -EINVAL;
		goto unlock;
	}
154

155
	pin = pin_get_from_name(pctldev, name);
156 157 158 159 160 161
	if (pin < 0) {
		ret = pin;
		goto unlock;
	}

	ret = pin_config_set_for_pin(pctldev, pin, config);
162

163 164 165
unlock:
	mutex_unlock(&pinctrl_mutex);
	return ret;
166 167 168
}
EXPORT_SYMBOL(pin_config_set);

169
int pin_config_group_get(const char *dev_name, const char *pin_group,
170 171
			 unsigned long *config)
{
172 173
	struct pinctrl_dev *pctldev;
	const struct pinconf_ops *ops;
174 175 176
	int selector, ret;

	mutex_lock(&pinctrl_mutex);
177

178
	pctldev = get_pinctrl_dev_from_devname(dev_name);
179 180 181 182
	if (!pctldev) {
		ret = -EINVAL;
		goto unlock;
	}
183 184
	ops = pctldev->desc->confops;

185
	if (!ops || !ops->pin_config_group_get) {
186
		dev_err(pctldev->dev, "cannot get configuration for pin "
187 188
			"group, missing group config get function in "
			"driver\n");
189 190
		ret = -EINVAL;
		goto unlock;
191 192 193
	}

	selector = pinctrl_get_group_selector(pctldev, pin_group);
194 195 196 197
	if (selector < 0) {
		ret = selector;
		goto unlock;
	}
198

199 200 201 202 203
	ret = ops->pin_config_group_get(pctldev, selector, config);

unlock:
	mutex_unlock(&pinctrl_mutex);
	return ret;
204 205 206
}
EXPORT_SYMBOL(pin_config_group_get);

207
int pin_config_group_set(const char *dev_name, const char *pin_group,
208 209
			 unsigned long config)
{
210 211 212
	struct pinctrl_dev *pctldev;
	const struct pinconf_ops *ops;
	const struct pinctrl_ops *pctlops;
213 214 215 216 217 218
	int selector;
	const unsigned *pins;
	unsigned num_pins;
	int ret;
	int i;

219 220
	mutex_lock(&pinctrl_mutex);

221
	pctldev = get_pinctrl_dev_from_devname(dev_name);
222 223 224 225
	if (!pctldev) {
		ret = -EINVAL;
		goto unlock;
	}
226 227 228
	ops = pctldev->desc->confops;
	pctlops = pctldev->desc->pctlops;

229
	if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) {
230
		dev_err(pctldev->dev, "cannot configure pin group, missing "
231
			"config function in driver\n");
232 233
		ret = -EINVAL;
		goto unlock;
234 235 236
	}

	selector = pinctrl_get_group_selector(pctldev, pin_group);
237 238 239 240
	if (selector < 0) {
		ret = selector;
		goto unlock;
	}
241 242 243

	ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins);
	if (ret) {
244
		dev_err(pctldev->dev, "cannot configure pin group, error "
245
			"getting pins\n");
246
		goto unlock;
247 248 249 250 251 252 253 254 255 256 257 258 259
	}

	/*
	 * If the pin controller supports handling entire groups we use that
	 * capability.
	 */
	if (ops->pin_config_group_set) {
		ret = ops->pin_config_group_set(pctldev, selector, config);
		/*
		 * If the pin controller prefer that a certain group be handled
		 * pin-by-pin as well, it returns -EAGAIN.
		 */
		if (ret != -EAGAIN)
260
			goto unlock;
261 262 263 264 265 266
	}

	/*
	 * If the controller cannot handle entire groups, we configure each pin
	 * individually.
	 */
267 268 269 270
	if (!ops->pin_config_set) {
		ret = 0;
		goto unlock;
	}
271 272 273 274

	for (i = 0; i < num_pins; i++) {
		ret = ops->pin_config_set(pctldev, pins[i], config);
		if (ret < 0)
275
			goto unlock;
276 277
	}

278 279 280 281 282 283
	ret = 0;

unlock:
	mutex_unlock(&pinctrl_mutex);

	return ret;
284 285 286
}
EXPORT_SYMBOL(pin_config_group_set);

287 288 289 290
int pinconf_map_to_setting(struct pinctrl_map const *map,
			  struct pinctrl_setting *setting)
{
	struct pinctrl_dev *pctldev = setting->pctldev;
291
	int pin;
292 293 294

	switch (setting->type) {
	case PIN_MAP_TYPE_CONFIGS_PIN:
295 296 297 298 299 300 301 302
		pin = pin_get_from_name(pctldev,
					map->data.configs.group_or_pin);
		if (pin < 0) {
			dev_err(pctldev->dev, "could not map pin config for \"%s\"",
				map->data.configs.group_or_pin);
			return pin;
		}
		setting->data.configs.group_or_pin = pin;
303 304
		break;
	case PIN_MAP_TYPE_CONFIGS_GROUP:
305 306 307 308 309 310 311 312
		pin = pinctrl_get_group_selector(pctldev,
					 map->data.configs.group_or_pin);
		if (pin < 0) {
			dev_err(pctldev->dev, "could not map group config for \"%s\"",
				map->data.configs.group_or_pin);
			return pin;
		}
		setting->data.configs.group_or_pin = pin;
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
		break;
	default:
		return -EINVAL;
	}

	setting->data.configs.num_configs = map->data.configs.num_configs;
	setting->data.configs.configs = map->data.configs.configs;

	return 0;
}

void pinconf_free_setting(struct pinctrl_setting const *setting)
{
}

int pinconf_apply_setting(struct pinctrl_setting const *setting)
{
	struct pinctrl_dev *pctldev = setting->pctldev;
	const struct pinconf_ops *ops = pctldev->desc->confops;
	int i, ret;

	if (!ops) {
		dev_err(pctldev->dev, "missing confops\n");
		return -EINVAL;
	}

	switch (setting->type) {
	case PIN_MAP_TYPE_CONFIGS_PIN:
		if (!ops->pin_config_set) {
			dev_err(pctldev->dev, "missing pin_config_set op\n");
			return -EINVAL;
		}
		for (i = 0; i < setting->data.configs.num_configs; i++) {
			ret = ops->pin_config_set(pctldev,
					setting->data.configs.group_or_pin,
					setting->data.configs.configs[i]);
			if (ret < 0) {
				dev_err(pctldev->dev,
					"pin_config_set op failed for pin %d config %08lx\n",
					setting->data.configs.group_or_pin,
					setting->data.configs.configs[i]);
				return ret;
			}
		}
		break;
	case PIN_MAP_TYPE_CONFIGS_GROUP:
		if (!ops->pin_config_group_set) {
			dev_err(pctldev->dev,
				"missing pin_config_group_set op\n");
			return -EINVAL;
		}
		for (i = 0; i < setting->data.configs.num_configs; i++) {
			ret = ops->pin_config_group_set(pctldev,
					setting->data.configs.group_or_pin,
					setting->data.configs.configs[i]);
			if (ret < 0) {
				dev_err(pctldev->dev,
					"pin_config_group_set op failed for group %d config %08lx\n",
					setting->data.configs.group_or_pin,
					setting->data.configs.configs[i]);
				return ret;
			}
		}
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

384 385
#ifdef CONFIG_DEBUG_FS

386 387
void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
{
388 389
	struct pinctrl_dev *pctldev;
	const struct pinconf_ops *confops;
390 391
	int i;

392 393 394 395 396 397
	pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
	if (pctldev)
		confops = pctldev->desc->confops;
	else
		confops = NULL;

398 399 400 401 402 403 404 405 406 407 408 409 410
	switch (map->type) {
	case PIN_MAP_TYPE_CONFIGS_PIN:
		seq_printf(s, "pin ");
		break;
	case PIN_MAP_TYPE_CONFIGS_GROUP:
		seq_printf(s, "group ");
		break;
	default:
		break;
	}

	seq_printf(s, "%s\n", map->data.configs.group_or_pin);

411 412 413 414 415 416 417 418 419
	for (i = 0; i < map->data.configs.num_configs; i++) {
		seq_printf(s, "config ");
		if (confops && confops->pin_config_config_dbg_show)
			confops->pin_config_config_dbg_show(pctldev, s,
						map->data.configs.configs[i]);
		else
			seq_printf(s, "%08lx", map->data.configs.configs[i]);
		seq_printf(s, "\n");
	}
420 421 422 423 424 425 426
}

void pinconf_show_setting(struct seq_file *s,
			  struct pinctrl_setting const *setting)
{
	struct pinctrl_dev *pctldev = setting->pctldev;
	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
427
	const struct pinconf_ops *confops = pctldev->desc->confops;
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
	struct pin_desc *desc;
	int i;

	switch (setting->type) {
	case PIN_MAP_TYPE_CONFIGS_PIN:
		desc = pin_desc_get(setting->pctldev,
				    setting->data.configs.group_or_pin);
		seq_printf(s, "pin %s (%d)",
			   desc->name ? desc->name : "unnamed",
			   setting->data.configs.group_or_pin);
		break;
	case PIN_MAP_TYPE_CONFIGS_GROUP:
		seq_printf(s, "group %s (%d)",
			   pctlops->get_group_name(pctldev,
					setting->data.configs.group_or_pin),
			   setting->data.configs.group_or_pin);
		break;
	default:
		break;
	}

	/*
	 * FIXME: We should really get the pin controler to dump the config
	 * values, so they can be decoded to something meaningful.
	 */
453 454 455 456 457 458 459 460 461
	for (i = 0; i < setting->data.configs.num_configs; i++) {
		seq_printf(s, " ");
		if (confops && confops->pin_config_config_dbg_show)
			confops->pin_config_config_dbg_show(pctldev, s,
				setting->data.configs.configs[i]);
		else
			seq_printf(s, "%08lx",
				   setting->data.configs.configs[i]);
	}
462 463 464 465

	seq_printf(s, "\n");
}

466 467 468 469 470
static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
			     struct seq_file *s, int pin)
{
	const struct pinconf_ops *ops = pctldev->desc->confops;

471 472
	/* no-op when not using generic pin config */
	pinconf_generic_dump_pin(pctldev, s, pin);
473 474 475 476 477 478 479
	if (ops && ops->pin_config_dbg_show)
		ops->pin_config_dbg_show(pctldev, s, pin);
}

static int pinconf_pins_show(struct seq_file *s, void *what)
{
	struct pinctrl_dev *pctldev = s->private;
480
	const struct pinconf_ops *ops = pctldev->desc->confops;
481
	unsigned i, pin;
482

483 484 485
	if (!ops || !ops->pin_config_get)
		return 0;

486
	seq_puts(s, "Pin config settings per pin\n");
487
	seq_puts(s, "Format: pin (name): configs\n");
488

489 490
	mutex_lock(&pinctrl_mutex);

491
	/* The pin number can be retrived from the pin controller descriptor */
492
	for (i = 0; i < pctldev->desc->npins; i++) {
493 494
		struct pin_desc *desc;

495
		pin = pctldev->desc->pins[i].number;
496
		desc = pin_desc_get(pctldev, pin);
497
		/* Skip if we cannot search the pin */
498 499 500 501 502 503 504 505 506 507 508
		if (desc == NULL)
			continue;

		seq_printf(s, "pin %d (%s):", pin,
			   desc->name ? desc->name : "unnamed");

		pinconf_dump_pin(pctldev, s, pin);

		seq_printf(s, "\n");
	}

509 510
	mutex_unlock(&pinctrl_mutex);

511 512 513 514 515 516 517 518 519
	return 0;
}

static void pinconf_dump_group(struct pinctrl_dev *pctldev,
			       struct seq_file *s, unsigned selector,
			       const char *gname)
{
	const struct pinconf_ops *ops = pctldev->desc->confops;

520 521
	/* no-op when not using generic pin config */
	pinconf_generic_dump_group(pctldev, s, gname);
522 523 524 525 526 527 528 529 530
	if (ops && ops->pin_config_group_dbg_show)
		ops->pin_config_group_dbg_show(pctldev, s, selector);
}

static int pinconf_groups_show(struct seq_file *s, void *what)
{
	struct pinctrl_dev *pctldev = s->private;
	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
	const struct pinconf_ops *ops = pctldev->desc->confops;
531
	unsigned ngroups = pctlops->get_groups_count(pctldev);
532 533 534 535 536 537
	unsigned selector = 0;

	if (!ops || !ops->pin_config_group_get)
		return 0;

	seq_puts(s, "Pin config settings per pin group\n");
538
	seq_puts(s, "Format: group (name): configs\n");
539

540 541
	mutex_lock(&pinctrl_mutex);

542
	while (selector < ngroups) {
543 544 545 546
		const char *gname = pctlops->get_group_name(pctldev, selector);

		seq_printf(s, "%u (%s):", selector, gname);
		pinconf_dump_group(pctldev, s, selector, gname);
547 548
		seq_printf(s, "\n");

549 550 551
		selector++;
	}

552 553
	mutex_unlock(&pinctrl_mutex);

554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
	return 0;
}

static int pinconf_pins_open(struct inode *inode, struct file *file)
{
	return single_open(file, pinconf_pins_show, inode->i_private);
}

static int pinconf_groups_open(struct inode *inode, struct file *file)
{
	return single_open(file, pinconf_groups_show, inode->i_private);
}

static const struct file_operations pinconf_pins_ops = {
	.open		= pinconf_pins_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static const struct file_operations pinconf_groups_ops = {
	.open		= pinconf_groups_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

void pinconf_init_device_debugfs(struct dentry *devroot,
			 struct pinctrl_dev *pctldev)
{
	debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO,
			    devroot, pctldev, &pinconf_pins_ops);
	debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
			    devroot, pctldev, &pinconf_groups_ops);
}

#endif