pinconf.c 13.4 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 31 32 33 34 35 36 37 38
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 */
	if (!ops->pin_config_get && !ops->pin_config_group_get)
		return -EINVAL;
	/* We have to be able to config the pins in SOME way */
	if (!ops->pin_config_set && !ops->pin_config_group_set)
		return -EINVAL;
	return 0;
}

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
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;
	}

	if (map->data.configs.num_configs &&
			!map->data.configs.configs) {
		pr_err("failed to register map %s (%d): no configs ptr given\n",
		       map->name, i);
		return -EINVAL;
	}

	return 0;
}

57
int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
58 59 60 61 62
			   unsigned long *config)
{
	const struct pinconf_ops *ops = pctldev->desc->confops;

	if (!ops || !ops->pin_config_get) {
63
		dev_err(pctldev->dev, "cannot get pin configuration, missing "
64 65 66 67 68 69 70 71 72
			"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
73
 * @dev_name: name of the pin controller device for this pin
74 75 76 77 78
 * @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.
 */
79
int pin_config_get(const char *dev_name, const char *name,
80 81
			  unsigned long *config)
{
82
	struct pinctrl_dev *pctldev;
83 84
	int pin;

85 86
	mutex_lock(&pinctrl_mutex);

87
	pctldev = get_pinctrl_dev_from_devname(dev_name);
88 89 90 91
	if (!pctldev) {
		pin = -EINVAL;
		goto unlock;
	}
92

93 94
	pin = pin_get_from_name(pctldev, name);
	if (pin < 0)
95
		goto unlock;
96

97 98 99 100 101
	pin = pin_config_get_for_pin(pctldev, pin, config);

unlock:
	mutex_unlock(&pinctrl_mutex);
	return pin;
102 103 104
}
EXPORT_SYMBOL(pin_config_get);

105
static int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
106 107 108 109 110 111
			   unsigned long config)
{
	const struct pinconf_ops *ops = pctldev->desc->confops;
	int ret;

	if (!ops || !ops->pin_config_set) {
112
		dev_err(pctldev->dev, "cannot configure pin, missing "
113 114 115 116 117 118
			"config function in driver\n");
		return -EINVAL;
	}

	ret = ops->pin_config_set(pctldev, pin, config);
	if (ret) {
119
		dev_err(pctldev->dev,
120 121 122 123 124 125 126 127 128
			"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
129
 * @dev_name: name of pin controller device for this pin
130 131 132 133 134
 * @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.
 */
135
int pin_config_set(const char *dev_name, const char *name,
136 137
		   unsigned long config)
{
138
	struct pinctrl_dev *pctldev;
139 140 141
	int pin, ret;

	mutex_lock(&pinctrl_mutex);
142

143
	pctldev = get_pinctrl_dev_from_devname(dev_name);
144 145 146 147
	if (!pctldev) {
		ret = -EINVAL;
		goto unlock;
	}
148

149
	pin = pin_get_from_name(pctldev, name);
150 151 152 153 154 155
	if (pin < 0) {
		ret = pin;
		goto unlock;
	}

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

157 158 159
unlock:
	mutex_unlock(&pinctrl_mutex);
	return ret;
160 161 162
}
EXPORT_SYMBOL(pin_config_set);

163
int pin_config_group_get(const char *dev_name, const char *pin_group,
164 165
			 unsigned long *config)
{
166 167
	struct pinctrl_dev *pctldev;
	const struct pinconf_ops *ops;
168 169 170
	int selector, ret;

	mutex_lock(&pinctrl_mutex);
171

172
	pctldev = get_pinctrl_dev_from_devname(dev_name);
173 174 175 176
	if (!pctldev) {
		ret = -EINVAL;
		goto unlock;
	}
177 178
	ops = pctldev->desc->confops;

179
	if (!ops || !ops->pin_config_group_get) {
180
		dev_err(pctldev->dev, "cannot get configuration for pin "
181 182
			"group, missing group config get function in "
			"driver\n");
183 184
		ret = -EINVAL;
		goto unlock;
185 186 187
	}

	selector = pinctrl_get_group_selector(pctldev, pin_group);
188 189 190 191
	if (selector < 0) {
		ret = selector;
		goto unlock;
	}
192

193 194 195 196 197
	ret = ops->pin_config_group_get(pctldev, selector, config);

unlock:
	mutex_unlock(&pinctrl_mutex);
	return ret;
198 199 200
}
EXPORT_SYMBOL(pin_config_group_get);

201
int pin_config_group_set(const char *dev_name, const char *pin_group,
202 203
			 unsigned long config)
{
204 205 206
	struct pinctrl_dev *pctldev;
	const struct pinconf_ops *ops;
	const struct pinctrl_ops *pctlops;
207 208 209 210 211 212
	int selector;
	const unsigned *pins;
	unsigned num_pins;
	int ret;
	int i;

213 214
	mutex_lock(&pinctrl_mutex);

215
	pctldev = get_pinctrl_dev_from_devname(dev_name);
216 217 218 219
	if (!pctldev) {
		ret = -EINVAL;
		goto unlock;
	}
220 221 222
	ops = pctldev->desc->confops;
	pctlops = pctldev->desc->pctlops;

223
	if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) {
224
		dev_err(pctldev->dev, "cannot configure pin group, missing "
225
			"config function in driver\n");
226 227
		ret = -EINVAL;
		goto unlock;
228 229 230
	}

	selector = pinctrl_get_group_selector(pctldev, pin_group);
231 232 233 234
	if (selector < 0) {
		ret = selector;
		goto unlock;
	}
235 236 237

	ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins);
	if (ret) {
238
		dev_err(pctldev->dev, "cannot configure pin group, error "
239
			"getting pins\n");
240
		goto unlock;
241 242 243 244 245 246 247 248 249 250 251 252 253
	}

	/*
	 * 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)
254
			goto unlock;
255 256 257 258 259 260
	}

	/*
	 * If the controller cannot handle entire groups, we configure each pin
	 * individually.
	 */
261 262 263 264
	if (!ops->pin_config_set) {
		ret = 0;
		goto unlock;
	}
265 266 267 268

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

272 273 274 275 276 277
	ret = 0;

unlock:
	mutex_unlock(&pinctrl_mutex);

	return ret;
278 279 280
}
EXPORT_SYMBOL(pin_config_group_set);

281 282 283 284
int pinconf_map_to_setting(struct pinctrl_map const *map,
			  struct pinctrl_setting *setting)
{
	struct pinctrl_dev *pctldev = setting->pctldev;
285
	int pin;
286 287 288

	switch (setting->type) {
	case PIN_MAP_TYPE_CONFIGS_PIN:
289 290 291 292 293 294 295 296
		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;
297 298
		break;
	case PIN_MAP_TYPE_CONFIGS_GROUP:
299 300 301 302 303 304 305 306
		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;
307 308 309 310 311 312 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
		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;
}

378 379
#ifdef CONFIG_DEBUG_FS

380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
{
	int i;

	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);

	for (i = 0; i < map->data.configs.num_configs; i++)
		seq_printf(s, "config %08lx\n", map->data.configs.configs[i]);
}

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;
	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.
	 */
	for (i = 0; i < setting->data.configs.num_configs; i++)
		seq_printf(s, " %08lx", setting->data.configs.configs[i]);

	seq_printf(s, "\n");
}

437 438 439 440 441
static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
			     struct seq_file *s, int pin)
{
	const struct pinconf_ops *ops = pctldev->desc->confops;

442 443
	/* no-op when not using generic pin config */
	pinconf_generic_dump_pin(pctldev, s, pin);
444 445 446 447 448 449 450
	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;
451
	unsigned i, pin;
452 453 454 455

	seq_puts(s, "Pin config settings per pin\n");
	seq_puts(s, "Format: pin (name): pinmux setting array\n");

456 457
	mutex_lock(&pinctrl_mutex);

458
	/* The pin number can be retrived from the pin controller descriptor */
459
	for (i = 0; i < pctldev->desc->npins; i++) {
460 461
		struct pin_desc *desc;

462
		pin = pctldev->desc->pins[i].number;
463
		desc = pin_desc_get(pctldev, pin);
464
		/* Skip if we cannot search the pin */
465 466 467 468 469 470 471 472 473 474 475
		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");
	}

476 477
	mutex_unlock(&pinctrl_mutex);

478 479 480 481 482 483 484 485 486
	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;

487 488
	/* no-op when not using generic pin config */
	pinconf_generic_dump_group(pctldev, s, gname);
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505
	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;
	unsigned selector = 0;

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

	seq_puts(s, "Pin config settings per pin group\n");
	seq_puts(s, "Format: group (name): pinmux setting array\n");

506 507
	mutex_lock(&pinctrl_mutex);

508 509 510 511 512
	while (pctlops->list_groups(pctldev, selector) >= 0) {
		const char *gname = pctlops->get_group_name(pctldev, selector);

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

515 516 517
		selector++;
	}

518 519
	mutex_unlock(&pinctrl_mutex);

520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
	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