File Index
Files and directories
Sign in
FILE

pinctrl-madera-core.c

File preview with syntax highlighting.

linux-6.19.14/drivers/pinctrl/cirrus/pinctrl-madera-core.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Pinctrl for Cirrus Logic Madera codecs
   4 *
   5 * Copyright (C) 2016-2018 Cirrus Logic
   6 */
   7
   8#include <linux/err.h>
   9#include <linux/module.h>
  10#include <linux/platform_device.h>
  11#include <linux/property.h>
  12#include <linux/regmap.h>
  13#include <linux/seq_file.h>
  14#include <linux/slab.h>
  15
  16#include <linux/pinctrl/machine.h>
  17#include <linux/pinctrl/pinconf-generic.h>
  18#include <linux/pinctrl/pinconf.h>
  19#include <linux/pinctrl/pinctrl.h>
  20#include <linux/pinctrl/pinmux.h>
  21
  22#include <linux/mfd/madera/core.h>
  23#include <linux/mfd/madera/registers.h>
  24
  25#include "../pinctrl-utils.h"
  26
  27#include "pinctrl-madera.h"
  28
  29/*
  30 * Use pin GPIO names for consistency
  31 * NOTE: IDs are zero-indexed for coding convenience
  32 */
  33static const struct pinctrl_pin_desc madera_pins[] = {
  34	PINCTRL_PIN(0, "gpio1"),
  35	PINCTRL_PIN(1, "gpio2"),
  36	PINCTRL_PIN(2, "gpio3"),
  37	PINCTRL_PIN(3, "gpio4"),
  38	PINCTRL_PIN(4, "gpio5"),
  39	PINCTRL_PIN(5, "gpio6"),
  40	PINCTRL_PIN(6, "gpio7"),
  41	PINCTRL_PIN(7, "gpio8"),
  42	PINCTRL_PIN(8, "gpio9"),
  43	PINCTRL_PIN(9, "gpio10"),
  44	PINCTRL_PIN(10, "gpio11"),
  45	PINCTRL_PIN(11, "gpio12"),
  46	PINCTRL_PIN(12, "gpio13"),
  47	PINCTRL_PIN(13, "gpio14"),
  48	PINCTRL_PIN(14, "gpio15"),
  49	PINCTRL_PIN(15, "gpio16"),
  50	PINCTRL_PIN(16, "gpio17"),
  51	PINCTRL_PIN(17, "gpio18"),
  52	PINCTRL_PIN(18, "gpio19"),
  53	PINCTRL_PIN(19, "gpio20"),
  54	PINCTRL_PIN(20, "gpio21"),
  55	PINCTRL_PIN(21, "gpio22"),
  56	PINCTRL_PIN(22, "gpio23"),
  57	PINCTRL_PIN(23, "gpio24"),
  58	PINCTRL_PIN(24, "gpio25"),
  59	PINCTRL_PIN(25, "gpio26"),
  60	PINCTRL_PIN(26, "gpio27"),
  61	PINCTRL_PIN(27, "gpio28"),
  62	PINCTRL_PIN(28, "gpio29"),
  63	PINCTRL_PIN(29, "gpio30"),
  64	PINCTRL_PIN(30, "gpio31"),
  65	PINCTRL_PIN(31, "gpio32"),
  66	PINCTRL_PIN(32, "gpio33"),
  67	PINCTRL_PIN(33, "gpio34"),
  68	PINCTRL_PIN(34, "gpio35"),
  69	PINCTRL_PIN(35, "gpio36"),
  70	PINCTRL_PIN(36, "gpio37"),
  71	PINCTRL_PIN(37, "gpio38"),
  72	PINCTRL_PIN(38, "gpio39"),
  73	PINCTRL_PIN(39, "gpio40"),
  74};
  75
  76/*
  77 * All single-pin functions can be mapped to any GPIO, however pinmux applies
  78 * functions to pin groups and only those groups declared as supporting that
  79 * function. To make this work we must put each pin in its own dummy group so
  80 * that the functions can be described as applying to all pins.
  81 * Since these do not correspond to anything in the actual hardware - they are
  82 * merely an adaptation to pinctrl's view of the world - we use the same name
  83 * as the pin to avoid confusion when comparing with datasheet instructions
  84 */
  85static const char * const madera_pin_single_group_names[] = {
  86	"gpio1",  "gpio2",  "gpio3",  "gpio4",  "gpio5",  "gpio6",  "gpio7",
  87	"gpio8",  "gpio9",  "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
  88	"gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
  89	"gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
  90	"gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
  91	"gpio36", "gpio37", "gpio38", "gpio39", "gpio40",
  92};
  93
  94/* set of pin numbers for single-pin groups, zero-indexed */
  95static const unsigned int madera_pin_single_group_pins[] = {
  96	  0,  1,  2,  3,  4,  5,  6,
  97	  7,  8,  9, 10, 11, 12, 13,
  98	 14, 15, 16, 17, 18, 19, 20,
  99	 21, 22, 23, 24, 25, 26, 27,
 100	 28, 29, 30, 31, 32, 33, 34,
 101	 35, 36, 37, 38, 39,
 102};
 103
 104static const char * const madera_aif1_group_names[] = { "aif1" };
 105static const char * const madera_aif2_group_names[] = { "aif2" };
 106static const char * const madera_aif3_group_names[] = { "aif3" };
 107static const char * const madera_aif4_group_names[] = { "aif4" };
 108static const char * const madera_mif1_group_names[] = { "mif1" };
 109static const char * const madera_mif2_group_names[] = { "mif2" };
 110static const char * const madera_mif3_group_names[] = { "mif3" };
 111static const char * const madera_dmic3_group_names[] = { "dmic3" };
 112static const char * const madera_dmic4_group_names[] = { "dmic4" };
 113static const char * const madera_dmic5_group_names[] = { "dmic5" };
 114static const char * const madera_dmic6_group_names[] = { "dmic6" };
 115static const char * const madera_spk1_group_names[] = { "pdmspk1" };
 116static const char * const madera_spk2_group_names[] = { "pdmspk2" };
 117
 118/*
 119 * alt-functions always apply to a single pin group, other functions always
 120 * apply to all pins
 121 */
 122static const struct {
 123	const char *name;
 124	const char * const *group_names;
 125	u32 func;
 126} madera_mux_funcs[] = {
 127	{
 128		.name = "aif1",
 129		.group_names = madera_aif1_group_names,
 130		.func = 0x000
 131	},
 132	{
 133		.name = "aif2",
 134		.group_names = madera_aif2_group_names,
 135		.func = 0x000
 136	},
 137	{
 138		.name = "aif3",
 139		.group_names = madera_aif3_group_names,
 140		.func = 0x000
 141	},
 142	{
 143		.name = "aif4",
 144		.group_names = madera_aif4_group_names,
 145		.func = 0x000
 146	},
 147	{
 148		.name = "mif1",
 149		.group_names = madera_mif1_group_names,
 150		.func = 0x000
 151	},
 152	{
 153		.name = "mif2",
 154		.group_names = madera_mif2_group_names,
 155		.func = 0x000
 156	},
 157	{
 158		.name = "mif3",
 159		.group_names = madera_mif3_group_names,
 160		.func = 0x000
 161	},
 162	{
 163		.name = "dmic3",
 164		.group_names = madera_dmic3_group_names,
 165		.func = 0x000
 166	},
 167	{
 168		.name = "dmic4",
 169		.group_names = madera_dmic4_group_names,
 170		.func = 0x000
 171	},
 172	{
 173		.name = "dmic5",
 174		.group_names = madera_dmic5_group_names,
 175		.func = 0x000
 176	},
 177	{
 178		.name = "dmic6",
 179		.group_names = madera_dmic6_group_names,
 180		.func = 0x000
 181	},
 182	{
 183		.name = "pdmspk1",
 184		.group_names = madera_spk1_group_names,
 185		.func = 0x000
 186	},
 187	{
 188		.name = "pdmspk2",
 189		.group_names = madera_spk2_group_names,
 190		.func = 0x000
 191	},
 192	{
 193		.name = "io",
 194		.group_names = madera_pin_single_group_names,
 195		.func = 0x001
 196	},
 197	{
 198		.name = "dsp-gpio",
 199		.group_names = madera_pin_single_group_names,
 200		.func = 0x002
 201	},
 202	{
 203		.name = "irq1",
 204		.group_names = madera_pin_single_group_names,
 205		.func = 0x003
 206	},
 207	{
 208		.name = "irq2",
 209		.group_names = madera_pin_single_group_names,
 210		.func = 0x004
 211	},
 212	{
 213		.name = "fll1-clk",
 214		.group_names = madera_pin_single_group_names,
 215		.func = 0x010
 216	},
 217	{
 218		.name = "fll2-clk",
 219		.group_names = madera_pin_single_group_names,
 220		.func = 0x011
 221	},
 222	{
 223		.name = "fll3-clk",
 224		.group_names = madera_pin_single_group_names,
 225		.func = 0x012
 226	},
 227	{
 228		.name = "fllao-clk",
 229		.group_names = madera_pin_single_group_names,
 230		.func = 0x013
 231	},
 232	{
 233		.name = "fll1-lock",
 234		.group_names = madera_pin_single_group_names,
 235		.func = 0x018
 236	},
 237	{
 238		.name = "fll2-lock",
 239		.group_names = madera_pin_single_group_names,
 240		.func = 0x019
 241	},
 242	{
 243		.name = "fll3-lock",
 244		.group_names = madera_pin_single_group_names,
 245		.func = 0x01a
 246	},
 247	{
 248		.name = "fllao-lock",
 249		.group_names = madera_pin_single_group_names,
 250		.func = 0x01b
 251	},
 252	{
 253		.name = "opclk",
 254		.group_names = madera_pin_single_group_names,
 255		.func = 0x040
 256	},
 257	{
 258		.name = "opclk-async",
 259		.group_names = madera_pin_single_group_names,
 260		.func = 0x041
 261	},
 262	{
 263		.name = "pwm1",
 264		.group_names = madera_pin_single_group_names,
 265		.func = 0x048
 266	},
 267	{
 268		.name = "pwm2",
 269		.group_names = madera_pin_single_group_names,
 270		.func = 0x049
 271	},
 272	{
 273		.name = "spdif",
 274		.group_names = madera_pin_single_group_names,
 275		.func = 0x04c
 276	},
 277	{
 278		.name = "asrc1-in1-lock",
 279		.group_names = madera_pin_single_group_names,
 280		.func = 0x088
 281	},
 282	{
 283		.name = "asrc1-in2-lock",
 284		.group_names = madera_pin_single_group_names,
 285		.func = 0x089
 286	},
 287	{
 288		.name = "asrc2-in1-lock",
 289		.group_names = madera_pin_single_group_names,
 290		.func = 0x08a
 291	},
 292	{
 293		.name = "asrc2-in2-lock",
 294		.group_names = madera_pin_single_group_names,
 295		.func = 0x08b
 296	},
 297	{
 298		.name = "spkl-short-circuit",
 299		.group_names = madera_pin_single_group_names,
 300		.func = 0x0b6
 301	},
 302	{
 303		.name = "spkr-short-circuit",
 304		.group_names = madera_pin_single_group_names,
 305		.func = 0x0b7
 306	},
 307	{
 308		.name = "spk-shutdown",
 309		.group_names = madera_pin_single_group_names,
 310		.func = 0x0e0
 311	},
 312	{
 313		.name = "spk-overheat-shutdown",
 314		.group_names = madera_pin_single_group_names,
 315		.func = 0x0e1
 316	},
 317	{
 318		.name = "spk-overheat-warn",
 319		.group_names = madera_pin_single_group_names,
 320		.func = 0x0e2
 321	},
 322	{
 323		.name = "timer1-sts",
 324		.group_names = madera_pin_single_group_names,
 325		.func = 0x140
 326	},
 327	{
 328		.name = "timer2-sts",
 329		.group_names = madera_pin_single_group_names,
 330		.func = 0x141
 331	},
 332	{
 333		.name = "timer3-sts",
 334		.group_names = madera_pin_single_group_names,
 335		.func = 0x142
 336	},
 337	{
 338		.name = "timer4-sts",
 339		.group_names = madera_pin_single_group_names,
 340		.func = 0x143
 341	},
 342	{
 343		.name = "timer5-sts",
 344		.group_names = madera_pin_single_group_names,
 345		.func = 0x144
 346	},
 347	{
 348		.name = "timer6-sts",
 349		.group_names = madera_pin_single_group_names,
 350		.func = 0x145
 351	},
 352	{
 353		.name = "timer7-sts",
 354		.group_names = madera_pin_single_group_names,
 355		.func = 0x146
 356	},
 357	{
 358		.name = "timer8-sts",
 359		.group_names = madera_pin_single_group_names,
 360		.func = 0x147
 361	},
 362	{
 363		.name = "log1-fifo-ne",
 364		.group_names = madera_pin_single_group_names,
 365		.func = 0x150
 366	},
 367	{
 368		.name = "log2-fifo-ne",
 369		.group_names = madera_pin_single_group_names,
 370		.func = 0x151
 371	},
 372	{
 373		.name = "log3-fifo-ne",
 374		.group_names = madera_pin_single_group_names,
 375		.func = 0x152
 376	},
 377	{
 378		.name = "log4-fifo-ne",
 379		.group_names = madera_pin_single_group_names,
 380		.func = 0x153
 381	},
 382	{
 383		.name = "log5-fifo-ne",
 384		.group_names = madera_pin_single_group_names,
 385		.func = 0x154
 386	},
 387	{
 388		.name = "log6-fifo-ne",
 389		.group_names = madera_pin_single_group_names,
 390		.func = 0x155
 391	},
 392	{
 393		.name = "log7-fifo-ne",
 394		.group_names = madera_pin_single_group_names,
 395		.func = 0x156
 396	},
 397	{
 398		.name = "log8-fifo-ne",
 399		.group_names = madera_pin_single_group_names,
 400		.func = 0x157
 401	},
 402	{
 403		.name = "aux-pdm-clk",
 404		.group_names = madera_pin_single_group_names,
 405		.func = 0x280
 406	},
 407	{
 408		.name = "aux-pdm-dat",
 409		.group_names = madera_pin_single_group_names,
 410		.func = 0x281
 411	},
 412};
 413
 414static u16 madera_pin_make_drv_str(struct madera_pin_private *priv,
 415				      unsigned int milliamps)
 416{
 417	switch (milliamps) {
 418	case 4:
 419		return 0;
 420	case 8:
 421		return 2 << MADERA_GP1_DRV_STR_SHIFT;
 422	default:
 423		break;
 424	}
 425
 426	dev_warn(priv->dev, "%u mA not a valid drive strength", milliamps);
 427
 428	return 0;
 429}
 430
 431static unsigned int madera_pin_unmake_drv_str(struct madera_pin_private *priv,
 432					      u16 regval)
 433{
 434	regval = (regval & MADERA_GP1_DRV_STR_MASK) >> MADERA_GP1_DRV_STR_SHIFT;
 435
 436	switch (regval) {
 437	case 0:
 438		return 4;
 439	case 2:
 440		return 8;
 441	default:
 442		return 0;
 443	}
 444}
 445
 446static int madera_get_groups_count(struct pinctrl_dev *pctldev)
 447{
 448	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 449
 450	/* Number of alt function groups plus number of single-pin groups */
 451	return priv->chip->n_pin_groups + priv->chip->n_pins;
 452}
 453
 454static const char *madera_get_group_name(struct pinctrl_dev *pctldev,
 455					 unsigned int selector)
 456{
 457	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 458
 459	if (selector < priv->chip->n_pin_groups)
 460		return priv->chip->pin_groups[selector].name;
 461
 462	selector -= priv->chip->n_pin_groups;
 463	return madera_pin_single_group_names[selector];
 464}
 465
 466static int madera_get_group_pins(struct pinctrl_dev *pctldev,
 467				 unsigned int selector,
 468				 const unsigned int **pins,
 469				 unsigned int *num_pins)
 470{
 471	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 472
 473	if (selector < priv->chip->n_pin_groups) {
 474		*pins = priv->chip->pin_groups[selector].pins;
 475		*num_pins = priv->chip->pin_groups[selector].n_pins;
 476	} else {
 477		/* return the dummy group for a single pin */
 478		selector -= priv->chip->n_pin_groups;
 479		*pins = &madera_pin_single_group_pins[selector];
 480		*num_pins = 1;
 481	}
 482	return 0;
 483}
 484
 485static void madera_pin_dbg_show_fn(struct madera_pin_private *priv,
 486				   struct seq_file *s,
 487				   unsigned int pin, unsigned int fn)
 488{
 489	const struct madera_pin_chip *chip = priv->chip;
 490	int i, g_pin;
 491
 492	if (fn != 0) {
 493		for (i = 0; i < ARRAY_SIZE(madera_mux_funcs); ++i) {
 494			if (madera_mux_funcs[i].func == fn) {
 495				seq_printf(s, " FN=%s",
 496					   madera_mux_funcs[i].name);
 497				return;
 498			}
 499		}
 500		return;	/* ignore unknown function values */
 501	}
 502
 503	/* alt function */
 504	for (i = 0; i < chip->n_pin_groups; ++i) {
 505		for (g_pin = 0; g_pin < chip->pin_groups[i].n_pins; ++g_pin) {
 506			if (chip->pin_groups[i].pins[g_pin] == pin) {
 507				seq_printf(s, " FN=%s",
 508					   chip->pin_groups[i].name);
 509				return;
 510			}
 511		}
 512	}
 513}
 514
 515static void __maybe_unused madera_pin_dbg_show(struct pinctrl_dev *pctldev,
 516					       struct seq_file *s,
 517					       unsigned int pin)
 518{
 519	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 520	unsigned int conf[2];
 521	unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
 522	unsigned int fn;
 523	int ret;
 524
 525	ret = regmap_read(priv->madera->regmap, reg, &conf[0]);
 526	if (ret)
 527		return;
 528
 529	ret = regmap_read(priv->madera->regmap, reg + 1, &conf[1]);
 530	if (ret)
 531		return;
 532
 533	seq_printf(s, "%04x:%04x", conf[0], conf[1]);
 534
 535	fn = (conf[0] & MADERA_GP1_FN_MASK) >> MADERA_GP1_FN_SHIFT;
 536	madera_pin_dbg_show_fn(priv, s, pin, fn);
 537
 538	/* State of direction bit is only relevant if function==1 */
 539	if (fn == 1) {
 540		if (conf[1] & MADERA_GP1_DIR_MASK)
 541			seq_puts(s, " IN");
 542		else
 543			seq_puts(s, " OUT");
 544	}
 545
 546	if (conf[1] & MADERA_GP1_PU_MASK)
 547		seq_puts(s, " PU");
 548
 549	if (conf[1] & MADERA_GP1_PD_MASK)
 550		seq_puts(s, " PD");
 551
 552	if (conf[0] & MADERA_GP1_DB_MASK)
 553		seq_puts(s, " DB");
 554
 555	if (conf[0] & MADERA_GP1_OP_CFG_MASK)
 556		seq_puts(s, " OD");
 557	else
 558		seq_puts(s, " CMOS");
 559
 560	seq_printf(s, " DRV=%umA", madera_pin_unmake_drv_str(priv, conf[1]));
 561
 562	if (conf[0] & MADERA_GP1_IP_CFG_MASK)
 563		seq_puts(s, " SCHMITT");
 564}
 565
 566static const struct pinctrl_ops madera_pin_group_ops = {
 567	.get_groups_count = madera_get_groups_count,
 568	.get_group_name = madera_get_group_name,
 569	.get_group_pins = madera_get_group_pins,
 570#if IS_ENABLED(CONFIG_OF)
 571	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
 572	.dt_free_map = pinctrl_utils_free_map,
 573#endif
 574#if IS_ENABLED(CONFIG_DEBUG_FS)
 575	.pin_dbg_show = madera_pin_dbg_show,
 576#endif
 577};
 578
 579static int madera_mux_get_funcs_count(struct pinctrl_dev *pctldev)
 580{
 581	return ARRAY_SIZE(madera_mux_funcs);
 582}
 583
 584static const char *madera_mux_get_func_name(struct pinctrl_dev *pctldev,
 585					    unsigned int selector)
 586{
 587	return madera_mux_funcs[selector].name;
 588}
 589
 590static int madera_mux_get_groups(struct pinctrl_dev *pctldev,
 591				 unsigned int selector,
 592				 const char * const **groups,
 593				 unsigned int * const num_groups)
 594{
 595	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 596
 597	*groups = madera_mux_funcs[selector].group_names;
 598
 599	if (madera_mux_funcs[selector].func == 0) {
 600		/* alt func always maps to a single group */
 601		*num_groups = 1;
 602	} else {
 603		/* other funcs map to all available gpio pins */
 604		*num_groups = priv->chip->n_pins;
 605	}
 606
 607	return 0;
 608}
 609
 610static int madera_mux_set_mux(struct pinctrl_dev *pctldev,
 611			      unsigned int selector,
 612			      unsigned int group)
 613{
 614	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 615	struct madera *madera = priv->madera;
 616	const struct madera_pin_groups *pin_group = priv->chip->pin_groups;
 617	unsigned int n_chip_groups = priv->chip->n_pin_groups;
 618	const char *func_name = madera_mux_funcs[selector].name;
 619	unsigned int reg;
 620	int i, ret = 0;
 621
 622	dev_dbg(priv->dev, "%s selecting %u (%s) for group %u (%s)\n",
 623		__func__, selector, func_name, group,
 624		madera_get_group_name(pctldev, group));
 625
 626	if (madera_mux_funcs[selector].func == 0) {
 627		/* alt func pin assignments are codec-specific */
 628		for (i = 0; i < n_chip_groups; ++i) {
 629			if (strcmp(func_name, pin_group->name) == 0)
 630				break;
 631
 632			++pin_group;
 633		}
 634
 635		if (i == n_chip_groups)
 636			return -EINVAL;
 637
 638		for (i = 0; i < pin_group->n_pins; ++i) {
 639			reg = MADERA_GPIO1_CTRL_1 + (2 * pin_group->pins[i]);
 640
 641			dev_dbg(priv->dev, "%s setting 0x%x func bits to 0\n",
 642				__func__, reg);
 643
 644			ret = regmap_update_bits(madera->regmap, reg,
 645						 MADERA_GP1_FN_MASK, 0);
 646			if (ret)
 647				break;
 648
 649		}
 650	} else {
 651		/*
 652		 * for other funcs the group will be the gpio number and will
 653		 * be offset by the number of chip-specific functions at the
 654		 * start of the group list
 655		 */
 656		group -= n_chip_groups;
 657		reg = MADERA_GPIO1_CTRL_1 + (2 * group);
 658
 659		dev_dbg(priv->dev, "%s setting 0x%x func bits to 0x%x\n",
 660			__func__, reg, madera_mux_funcs[selector].func);
 661
 662		ret = regmap_update_bits(madera->regmap,
 663					 reg,
 664					 MADERA_GP1_FN_MASK,
 665					 madera_mux_funcs[selector].func);
 666	}
 667
 668	if (ret)
 669		dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
 670
 671	return ret;
 672}
 673
 674static int madera_gpio_set_direction(struct pinctrl_dev *pctldev,
 675				     struct pinctrl_gpio_range *range,
 676				     unsigned int offset,
 677				     bool input)
 678{
 679	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 680	struct madera *madera = priv->madera;
 681	unsigned int reg = MADERA_GPIO1_CTRL_2 + (2 * offset);
 682	unsigned int val;
 683	int ret;
 684
 685	if (input)
 686		val = MADERA_GP1_DIR;
 687	else
 688		val = 0;
 689
 690	ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_DIR_MASK, val);
 691	if (ret)
 692		dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
 693
 694	return ret;
 695}
 696
 697static int madera_gpio_request_enable(struct pinctrl_dev *pctldev,
 698				      struct pinctrl_gpio_range *range,
 699				      unsigned int offset)
 700{
 701	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 702	struct madera *madera = priv->madera;
 703	unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * offset);
 704	int ret;
 705
 706	/* put the pin into GPIO mode */
 707	ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_FN_MASK, 1);
 708	if (ret)
 709		dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
 710
 711	return ret;
 712}
 713
 714static void madera_gpio_disable_free(struct pinctrl_dev *pctldev,
 715				     struct pinctrl_gpio_range *range,
 716				     unsigned int offset)
 717{
 718	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 719	struct madera *madera = priv->madera;
 720	unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * offset);
 721	int ret;
 722
 723	/* disable GPIO by setting to GPIO IN */
 724	madera_gpio_set_direction(pctldev, range, offset, true);
 725
 726	ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_FN_MASK, 1);
 727	if (ret)
 728		dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
 729}
 730
 731static const struct pinmux_ops madera_pin_mux_ops = {
 732	.get_functions_count = madera_mux_get_funcs_count,
 733	.get_function_name = madera_mux_get_func_name,
 734	.get_function_groups = madera_mux_get_groups,
 735	.set_mux = madera_mux_set_mux,
 736	.gpio_request_enable = madera_gpio_request_enable,
 737	.gpio_disable_free = madera_gpio_disable_free,
 738	.gpio_set_direction = madera_gpio_set_direction,
 739	.strict = true, /* GPIO and other functions are exclusive */
 740};
 741
 742static int madera_pin_conf_get(struct pinctrl_dev *pctldev, unsigned int pin,
 743			       unsigned long *config)
 744{
 745	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 746	unsigned int param = pinconf_to_config_param(*config);
 747	unsigned int result = 0;
 748	unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
 749	unsigned int conf[2];
 750	int ret;
 751
 752	ret = regmap_read(priv->madera->regmap, reg, &conf[0]);
 753	if (!ret)
 754		ret = regmap_read(priv->madera->regmap, reg + 1, &conf[1]);
 755
 756	if (ret) {
 757		dev_err(priv->dev, "Failed to read GP%d conf (%d)\n",
 758			pin + 1, ret);
 759		return ret;
 760	}
 761
 762	switch (param) {
 763	case PIN_CONFIG_BIAS_BUS_HOLD:
 764		conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
 765		if (conf[1] == (MADERA_GP1_PU | MADERA_GP1_PD))
 766			result = 1;
 767		break;
 768	case PIN_CONFIG_BIAS_DISABLE:
 769		conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
 770		if (!conf[1])
 771			result = 1;
 772		break;
 773	case PIN_CONFIG_BIAS_PULL_DOWN:
 774		conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
 775		if (conf[1] == MADERA_GP1_PD_MASK)
 776			result = 1;
 777		break;
 778	case PIN_CONFIG_BIAS_PULL_UP:
 779		conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
 780		if (conf[1] == MADERA_GP1_PU_MASK)
 781			result = 1;
 782		break;
 783	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
 784		if (conf[0] & MADERA_GP1_OP_CFG_MASK)
 785			result = 1;
 786		break;
 787	case PIN_CONFIG_DRIVE_PUSH_PULL:
 788		if (!(conf[0] & MADERA_GP1_OP_CFG_MASK))
 789			result = 1;
 790		break;
 791	case PIN_CONFIG_DRIVE_STRENGTH:
 792		result = madera_pin_unmake_drv_str(priv, conf[1]);
 793		break;
 794	case PIN_CONFIG_INPUT_DEBOUNCE:
 795		if (conf[0] & MADERA_GP1_DB_MASK)
 796			result = 1;
 797		break;
 798	case PIN_CONFIG_INPUT_ENABLE:
 799		if (conf[0] & MADERA_GP1_DIR_MASK)
 800			result = 1;
 801		break;
 802	case PIN_CONFIG_INPUT_SCHMITT:
 803	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
 804		if (conf[0] & MADERA_GP1_IP_CFG_MASK)
 805			result = 1;
 806		break;
 807	case PIN_CONFIG_LEVEL:
 808		if ((conf[1] & MADERA_GP1_DIR_MASK) &&
 809		    (conf[0] & MADERA_GP1_LVL_MASK))
 810			result = 1;
 811		break;
 812	default:
 813		return -ENOTSUPP;
 814	}
 815
 816	*config = pinconf_to_config_packed(param, result);
 817
 818	return 0;
 819}
 820
 821static int madera_pin_conf_set(struct pinctrl_dev *pctldev, unsigned int pin,
 822			       unsigned long *configs, unsigned int num_configs)
 823{
 824	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 825	u16 conf[2] = {0, 0};
 826	u16 mask[2] = {0, 0};
 827	unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
 828	unsigned int val;
 829	int ret;
 830
 831	while (num_configs) {
 832		dev_dbg(priv->dev, "%s config 0x%lx\n", __func__, *configs);
 833
 834		switch (pinconf_to_config_param(*configs)) {
 835		case PIN_CONFIG_BIAS_BUS_HOLD:
 836			mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
 837			conf[1] |= MADERA_GP1_PU | MADERA_GP1_PD;
 838			break;
 839		case PIN_CONFIG_BIAS_DISABLE:
 840			mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
 841			conf[1] &= ~(MADERA_GP1_PU | MADERA_GP1_PD);
 842			break;
 843		case PIN_CONFIG_BIAS_PULL_DOWN:
 844			mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
 845			conf[1] |= MADERA_GP1_PD;
 846			conf[1] &= ~MADERA_GP1_PU;
 847			break;
 848		case PIN_CONFIG_BIAS_PULL_UP:
 849			mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
 850			conf[1] |= MADERA_GP1_PU;
 851			conf[1] &= ~MADERA_GP1_PD;
 852			break;
 853		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
 854			mask[0] |= MADERA_GP1_OP_CFG_MASK;
 855			conf[0] |= MADERA_GP1_OP_CFG;
 856			break;
 857		case PIN_CONFIG_DRIVE_PUSH_PULL:
 858			mask[0] |= MADERA_GP1_OP_CFG_MASK;
 859			conf[0] &= ~MADERA_GP1_OP_CFG;
 860			break;
 861		case PIN_CONFIG_DRIVE_STRENGTH:
 862			val = pinconf_to_config_argument(*configs);
 863			mask[1] |= MADERA_GP1_DRV_STR_MASK;
 864			conf[1] &= ~MADERA_GP1_DRV_STR_MASK;
 865			conf[1] |= madera_pin_make_drv_str(priv, val);
 866			break;
 867		case PIN_CONFIG_INPUT_DEBOUNCE:
 868			mask[0] |= MADERA_GP1_DB_MASK;
 869
 870			/*
 871			 * we can't configure debounce time per-pin so value
 872			 * is just a flag
 873			 */
 874			val = pinconf_to_config_argument(*configs);
 875			if (val)
 876				conf[0] |= MADERA_GP1_DB;
 877			else
 878				conf[0] &= ~MADERA_GP1_DB;
 879			break;
 880		case PIN_CONFIG_INPUT_ENABLE:
 881			val = pinconf_to_config_argument(*configs);
 882			mask[1] |= MADERA_GP1_DIR_MASK;
 883			if (val)
 884				conf[1] |= MADERA_GP1_DIR;
 885			else
 886				conf[1] &= ~MADERA_GP1_DIR;
 887			break;
 888		case PIN_CONFIG_INPUT_SCHMITT:
 889			val = pinconf_to_config_argument(*configs);
 890			mask[0] |= MADERA_GP1_IP_CFG;
 891			if (val)
 892				conf[0] |= MADERA_GP1_IP_CFG;
 893			else
 894				conf[0] &= ~MADERA_GP1_IP_CFG;
 895
 896			mask[1] |= MADERA_GP1_DIR_MASK;
 897			conf[1] |= MADERA_GP1_DIR;
 898			break;
 899		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
 900			mask[0] |= MADERA_GP1_IP_CFG;
 901			conf[0] |= MADERA_GP1_IP_CFG;
 902			mask[1] |= MADERA_GP1_DIR_MASK;
 903			conf[1] |= MADERA_GP1_DIR;
 904			break;
 905		case PIN_CONFIG_LEVEL:
 906			val = pinconf_to_config_argument(*configs);
 907			mask[0] |= MADERA_GP1_LVL_MASK;
 908			if (val)
 909				conf[0] |= MADERA_GP1_LVL;
 910			else
 911				conf[0] &= ~MADERA_GP1_LVL;
 912
 913			mask[1] |= MADERA_GP1_DIR_MASK;
 914			conf[1] &= ~MADERA_GP1_DIR;
 915			break;
 916		default:
 917			return -ENOTSUPP;
 918		}
 919
 920		++configs;
 921		--num_configs;
 922	}
 923
 924	dev_dbg(priv->dev,
 925		"%s gpio%d 0x%x:0x%x 0x%x:0x%x\n",
 926		__func__, pin + 1, reg, conf[0], reg + 1, conf[1]);
 927
 928	ret = regmap_update_bits(priv->madera->regmap, reg, mask[0], conf[0]);
 929	if (ret)
 930		goto err;
 931
 932	++reg;
 933	ret = regmap_update_bits(priv->madera->regmap, reg, mask[1], conf[1]);
 934	if (ret)
 935		goto err;
 936
 937	return 0;
 938
 939err:
 940	dev_err(priv->dev,
 941		"Failed to write GPIO%d conf (%d) reg 0x%x\n",
 942		pin + 1, ret, reg);
 943
 944	return ret;
 945}
 946
 947static int madera_pin_conf_group_set(struct pinctrl_dev *pctldev,
 948				     unsigned int selector,
 949				     unsigned long *configs,
 950				     unsigned int num_configs)
 951{
 952	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
 953	const struct madera_pin_groups *pin_group;
 954	unsigned int n_groups = priv->chip->n_pin_groups;
 955	int i, ret;
 956
 957	dev_dbg(priv->dev, "%s setting group %s\n", __func__,
 958		madera_get_group_name(pctldev, selector));
 959
 960	if (selector >= n_groups) {
 961		/* group is a single pin, convert to pin number and set */
 962		return madera_pin_conf_set(pctldev,
 963					   selector - n_groups,
 964					   configs,
 965					   num_configs);
 966	} else {
 967		pin_group = &priv->chip->pin_groups[selector];
 968
 969		for (i = 0; i < pin_group->n_pins; ++i) {
 970			ret = madera_pin_conf_set(pctldev,
 971						  pin_group->pins[i],
 972						  configs,
 973						  num_configs);
 974			if (ret)
 975				return ret;
 976		}
 977	}
 978
 979	return 0;
 980}
 981
 982static const struct pinconf_ops madera_pin_conf_ops = {
 983	.is_generic = true,
 984	.pin_config_get = madera_pin_conf_get,
 985	.pin_config_set = madera_pin_conf_set,
 986	.pin_config_group_set = madera_pin_conf_group_set,
 987};
 988
 989static struct pinctrl_desc madera_pin_desc = {
 990	.name = "madera-pinctrl",
 991	.pins = madera_pins,
 992	.pctlops = &madera_pin_group_ops,
 993	.pmxops = &madera_pin_mux_ops,
 994	.confops = &madera_pin_conf_ops,
 995	.owner = THIS_MODULE,
 996};
 997
 998static int madera_pin_probe(struct platform_device *pdev)
 999{
1000	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
1001	const struct madera_pdata *pdata = &madera->pdata;
1002	struct madera_pin_private *priv;
1003	int ret;
1004
1005	BUILD_BUG_ON(ARRAY_SIZE(madera_pin_single_group_names) !=
1006		     ARRAY_SIZE(madera_pin_single_group_pins));
1007
1008	dev_dbg(&pdev->dev, "%s\n", __func__);
1009
1010	device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent));
1011
1012	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1013	if (!priv)
1014		return -ENOMEM;
1015
1016	priv->dev = &pdev->dev;
1017	priv->madera = madera;
1018
1019	switch (madera->type) {
1020	case CS47L15:
1021		if (IS_ENABLED(CONFIG_PINCTRL_CS47L15))
1022			priv->chip = &cs47l15_pin_chip;
1023		break;
1024	case CS47L35:
1025		if (IS_ENABLED(CONFIG_PINCTRL_CS47L35))
1026			priv->chip = &cs47l35_pin_chip;
1027		break;
1028	case CS47L85:
1029	case WM1840:
1030		if (IS_ENABLED(CONFIG_PINCTRL_CS47L85))
1031			priv->chip = &cs47l85_pin_chip;
1032		break;
1033	case CS47L90:
1034	case CS47L91:
1035		if (IS_ENABLED(CONFIG_PINCTRL_CS47L90))
1036			priv->chip = &cs47l90_pin_chip;
1037		break;
1038	case CS42L92:
1039	case CS47L92:
1040	case CS47L93:
1041		if (IS_ENABLED(CONFIG_PINCTRL_CS47L92))
1042			priv->chip = &cs47l92_pin_chip;
1043		break;
1044	default:
1045		break;
1046	}
1047
1048	if (!priv->chip)
1049		return -ENODEV;
1050
1051	madera_pin_desc.npins = priv->chip->n_pins;
1052
1053	ret = devm_pinctrl_register_and_init(&pdev->dev,
1054					     &madera_pin_desc,
1055					     priv,
1056					     &priv->pctl);
1057	if (ret) {
1058		dev_err(priv->dev, "Failed pinctrl register (%d)\n", ret);
1059		return ret;
1060	}
1061
1062	/* if the configuration is provided through pdata, apply it */
1063	if (pdata->gpio_configs) {
1064		ret = devm_pinctrl_register_mappings(priv->dev,
1065						     pdata->gpio_configs,
1066						     pdata->n_gpio_configs);
1067		if (ret)
1068			return dev_err_probe(priv->dev, ret,
1069						"Failed to register pdata mappings\n");
1070	}
1071
1072	ret = pinctrl_enable(priv->pctl);
1073	if (ret) {
1074		dev_err(priv->dev, "Failed to enable pinctrl (%d)\n", ret);
1075		return ret;
1076	}
1077
1078	platform_set_drvdata(pdev, priv);
1079
1080	dev_dbg(priv->dev, "pinctrl probed ok\n");
1081
1082	return 0;
1083}
1084
1085static struct platform_driver madera_pin_driver = {
1086	.probe = madera_pin_probe,
1087	.driver = {
1088		.name = "madera-pinctrl",
1089	},
1090};
1091
1092module_platform_driver(madera_pin_driver);
1093
1094MODULE_DESCRIPTION("Madera pinctrl driver");
1095MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
1096MODULE_LICENSE("GPL v2");
~/ Read-only file preview.