brintos

brintos / linux-shallow public Read only

0
0
Text · 18.2 KiB · 5f6af93 Raw
576 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Pinctrl driver for the Mobileye EyeQ5 platform.4 *5 * The registers are located in a syscon region called OLB. There are two pin6 * banks, each being controlled by 5 registers (see enum eq5p_regs) for7 * pull-down, pull-up, drive strength and muxing.8 *9 * For each pin, muxing is between two functions: (0) GPIO or (1) another one10 * that is pin-dependent. Functions are declared statically in this driver.11 *12 * We create pinctrl groups that are 1:1 equivalent to pins: each group has a13 * single pin, and its index/selector is the pin number.14 *15 * We use eq5p_ as prefix, as-in "EyeQ5 Pinctrl", but way shorter.16 *17 * Copyright (C) 2024 Mobileye Vision Technologies Ltd.18 */19 20#include <linux/array_size.h>21#include <linux/auxiliary_bus.h>22#include <linux/bits.h>23#include <linux/bug.h>24#include <linux/device.h>25#include <linux/err.h>26#include <linux/errno.h>27#include <linux/io.h>28#include <linux/mod_devicetable.h>29#include <linux/seq_file.h>30#include <linux/slab.h>31#include <linux/types.h>32 33#include <linux/pinctrl/pinconf-generic.h>34#include <linux/pinctrl/pinconf.h>35#include <linux/pinctrl/pinctrl.h>36#include <linux/pinctrl/pinmux.h>37 38#include "core.h"39#include "pinctrl-utils.h"40 41struct eq5p_pinctrl {42	struct pinctrl_desc	desc;43	void __iomem		*base;44};45 46enum eq5p_bank {47	EQ5P_BANK_A,48	EQ5P_BANK_B,49 50	EQ5P_BANK_COUNT,51};52 53enum eq5p_regs {54	EQ5P_PD,55	EQ5P_PU,56	EQ5P_DS_LOW,57	EQ5P_DS_HIGH,58	EQ5P_IOCR,59 60	EQ5P_REG_COUNT,61};62 63static const unsigned int eq5p_regs[EQ5P_BANK_COUNT][EQ5P_REG_COUNT] = {64	[EQ5P_BANK_A] = {0x0C0, 0x0C4, 0x0D0, 0x0D4, 0x0B0},65	[EQ5P_BANK_B] = {0x0C8, 0x0CC, 0x0D8, 0x0DC, 0x0B4},66};67 68/*69 * Drive strength; two bits per pin.70 */71#define EQ5P_DS_MASK	GENMASK(1, 0)72 73/*74 * Comments to the right of each pin are the "signal name" in the datasheet.75 */76static const struct pinctrl_pin_desc eq5p_pins[] = {77	/* Bank A */78	PINCTRL_PIN(0,  "PA0"),  /* A0_TIMER0_CK */79	PINCTRL_PIN(1,  "PA1"),  /* A1_TIMER0_EOC */80	PINCTRL_PIN(2,  "PA2"),  /* A2_TIMER1_CK */81	PINCTRL_PIN(3,  "PA3"),  /* A3_TIMER1_EOC */82	PINCTRL_PIN(4,  "PA4"),  /* A4_TIMER2_CK */83	PINCTRL_PIN(5,  "PA5"),  /* A5_TIMER2_EOC */84	PINCTRL_PIN(6,  "PA6"),  /* A6_TIMER5_EXT_INCAP1 */85	PINCTRL_PIN(7,  "PA7"),  /* A7_TIMER5_EXT_INCAP2 */86	PINCTRL_PIN(8,  "PA8"),  /* A8_TIMER5_EXT_OUTCMP1 */87	PINCTRL_PIN(9,  "PA9"),  /* A9_TIMER5_EXT_OUTCMP2 */88	PINCTRL_PIN(10, "PA10"), /* A10_UART_0_TX */89	PINCTRL_PIN(11, "PA11"), /* A11_UART_0_RX */90	PINCTRL_PIN(12, "PA12"), /* A12_UART_1_TX */91	PINCTRL_PIN(13, "PA13"), /* A13_UART_1_RX */92	PINCTRL_PIN(14, "PA14"), /* A14_CAN_0_TX */93	PINCTRL_PIN(15, "PA15"), /* A15_CAN_0_RX */94	PINCTRL_PIN(16, "PA16"), /* A16_CAN_1_TX */95	PINCTRL_PIN(17, "PA17"), /* A17_CAN_1_RX */96	PINCTRL_PIN(18, "PA18"), /* A18_SPI_0_DO */97	PINCTRL_PIN(19, "PA19"), /* A19_SPI_0_DI */98	PINCTRL_PIN(20, "PA20"), /* A20_SPI_0_CK */99	PINCTRL_PIN(21, "PA21"), /* A21_SPI_0_CS0 */100	PINCTRL_PIN(22, "PA22"), /* A22_SPI_0_CS1 */101	PINCTRL_PIN(23, "PA23"), /* A23_SPI_1_DO */102	PINCTRL_PIN(24, "PA24"), /* A24_SPI_1_DI */103	PINCTRL_PIN(25, "PA25"), /* A25_SPI_1_CK */104	PINCTRL_PIN(26, "PA26"), /* A26_SPI_1_CS0 */105	PINCTRL_PIN(27, "PA27"), /* A27_SPI_1_CS1 */106	PINCTRL_PIN(28, "PA28"), /* A28_REF_CLK0 */107 108#define EQ5P_PIN_OFFSET_BANK_B	29109 110	/* Bank B */111	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 0,  "PB0"),  /* B0_TIMER3_CK */112	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 1,  "PB1"),  /* B1_TIMER3_EOC */113	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 2,  "PB2"),  /* B2_TIMER4_CK */114	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 3,  "PB3"),  /* B3_TIMER4_EOC */115	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 4,  "PB4"),  /* B4_TIMER6_EXT_INCAP1 */116	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 5,  "PB5"),  /* B5_TIMER6_EXT_INCAP2 */117	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 6,  "PB6"),  /* B6_TIMER6_EXT_OUTCMP1 */118	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 7,  "PB7"),  /* B7_TIMER6_EXT_OUTCMP2 */119	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 8,  "PB8"),  /* B8_UART_2_TX */120	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 9,  "PB9"),  /* B9_UART_2_RX */121	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 10, "PB10"), /* B10_CAN_2_TX */122	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 11, "PB11"), /* B11_CAN_2_RX */123	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 12, "PB12"), /* B12_SPI_2_DO */124	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 13, "PB13"), /* B13_SPI_2_DI */125	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 14, "PB14"), /* B14_SPI_2_CK */126	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 15, "PB15"), /* B15_SPI_2_CS0 */127	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 16, "PB16"), /* B16_SPI_2_CS1 */128	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 17, "PB17"), /* B17_SPI_3_DO */129	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 18, "PB18"), /* B18_SPI_3_DI */130	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 19, "PB19"), /* B19_SPI_3_CK */131	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 20, "PB20"), /* B20_SPI_3_CS0 */132	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 21, "PB21"), /* B21_SPI_3_CS1 */133	PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 22, "PB22"), /* B22_MCLK0 */134};135 136static const char * const gpio_groups[] = {137	/* Bank A */138	"PA0",  "PA1",  "PA2",  "PA3",  "PA4",  "PA5",  "PA6",  "PA7",139	"PA8",  "PA9",  "PA10", "PA11", "PA12", "PA13", "PA14", "PA15",140	"PA16", "PA17", "PA18", "PA19", "PA20", "PA21", "PA22", "PA23",141	"PA24", "PA25", "PA26", "PA27", "PA28",142 143	/* Bank B */144	"PB0",  "PB1",  "PB2",  "PB3",  "PB4",  "PB5",  "PB6",  "PB7",145	"PB8",  "PB9",  "PB10", "PB11", "PB12", "PB13", "PB14", "PB15",146	"PB16", "PB17", "PB18", "PB19", "PB20", "PB21", "PB22",147};148 149/* Groups of functions on bank A */150static const char * const timer0_groups[] = { "PA0", "PA1" };151static const char * const timer1_groups[] = { "PA2", "PA3" };152static const char * const timer2_groups[] = { "PA4", "PA5" };153static const char * const timer5_groups[] = { "PA6", "PA7", "PA8", "PA9" };154static const char * const uart0_groups[] = { "PA10", "PA11" };155static const char * const uart1_groups[] = { "PA12", "PA13" };156static const char * const can0_groups[] = { "PA14", "PA15" };157static const char * const can1_groups[] = { "PA16", "PA17" };158static const char * const spi0_groups[] = { "PA18", "PA19", "PA20", "PA21", "PA22" };159static const char * const spi1_groups[] = { "PA23", "PA24", "PA25", "PA26", "PA27" };160static const char * const refclk0_groups[] = { "PA28" };161 162/* Groups of functions on bank B */163static const char * const timer3_groups[] = { "PB0", "PB1" };164static const char * const timer4_groups[] = { "PB2", "PB3" };165static const char * const timer6_groups[] = { "PB4", "PB5", "PB6", "PB7" };166static const char * const uart2_groups[] = { "PB8", "PB9" };167static const char * const can2_groups[] = { "PB10", "PB11" };168static const char * const spi2_groups[] = { "PB12", "PB13", "PB14", "PB15", "PB16" };169static const char * const spi3_groups[] = { "PB17", "PB18", "PB19", "PB20", "PB21" };170static const char * const mclk0_groups[] = { "PB22" };171 172static const struct pinfunction eq5p_functions[] = {173	/* GPIO having a fixed index is depended upon, see GPIO_FUNC_SELECTOR. */174	PINCTRL_PINFUNCTION("gpio", gpio_groups, ARRAY_SIZE(gpio_groups)),175#define GPIO_FUNC_SELECTOR 0176 177	/* Bank A functions */178	PINCTRL_PINFUNCTION("timer0", timer0_groups, ARRAY_SIZE(timer0_groups)),179	PINCTRL_PINFUNCTION("timer1", timer1_groups, ARRAY_SIZE(timer1_groups)),180	PINCTRL_PINFUNCTION("timer2", timer2_groups, ARRAY_SIZE(timer2_groups)),181	PINCTRL_PINFUNCTION("timer5", timer5_groups, ARRAY_SIZE(timer5_groups)),182	PINCTRL_PINFUNCTION("uart0", uart0_groups, ARRAY_SIZE(uart0_groups)),183	PINCTRL_PINFUNCTION("uart1", uart1_groups, ARRAY_SIZE(uart1_groups)),184	PINCTRL_PINFUNCTION("can0", can0_groups, ARRAY_SIZE(can0_groups)),185	PINCTRL_PINFUNCTION("can1", can1_groups, ARRAY_SIZE(can1_groups)),186	PINCTRL_PINFUNCTION("spi0", spi0_groups, ARRAY_SIZE(spi0_groups)),187	PINCTRL_PINFUNCTION("spi1", spi1_groups, ARRAY_SIZE(spi1_groups)),188	PINCTRL_PINFUNCTION("refclk0", refclk0_groups, ARRAY_SIZE(refclk0_groups)),189 190	/* Bank B functions */191	PINCTRL_PINFUNCTION("timer3", timer3_groups, ARRAY_SIZE(timer3_groups)),192	PINCTRL_PINFUNCTION("timer4", timer4_groups, ARRAY_SIZE(timer4_groups)),193	PINCTRL_PINFUNCTION("timer6", timer6_groups, ARRAY_SIZE(timer6_groups)),194	PINCTRL_PINFUNCTION("uart2", uart2_groups, ARRAY_SIZE(uart2_groups)),195	PINCTRL_PINFUNCTION("can2", can2_groups, ARRAY_SIZE(can2_groups)),196	PINCTRL_PINFUNCTION("spi2", spi2_groups, ARRAY_SIZE(spi2_groups)),197	PINCTRL_PINFUNCTION("spi3", spi3_groups, ARRAY_SIZE(spi3_groups)),198	PINCTRL_PINFUNCTION("mclk0", mclk0_groups, ARRAY_SIZE(mclk0_groups)),199};200 201static void eq5p_update_bits(const struct eq5p_pinctrl *pctrl,202			     enum eq5p_bank bank, enum eq5p_regs reg,203			     u32 mask, u32 val)204{205	void __iomem *ptr = pctrl->base + eq5p_regs[bank][reg];206 207	writel((readl(ptr) & ~mask) | (val & mask), ptr);208}209 210static bool eq5p_test_bit(const struct eq5p_pinctrl *pctrl,211			  enum eq5p_bank bank, enum eq5p_regs reg, int offset)212{213	u32 val = readl(pctrl->base + eq5p_regs[bank][reg]);214 215	if (WARN_ON(offset > 31))216		return false;217 218	return (val & BIT(offset)) != 0;219}220 221static enum eq5p_bank eq5p_pin_to_bank(unsigned int pin)222{223	if (pin < EQ5P_PIN_OFFSET_BANK_B)224		return EQ5P_BANK_A;225	else226		return EQ5P_BANK_B;227}228 229static unsigned int eq5p_pin_to_offset(unsigned int pin)230{231	if (pin < EQ5P_PIN_OFFSET_BANK_B)232		return pin;233	else234		return pin - EQ5P_PIN_OFFSET_BANK_B;235}236 237static int eq5p_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)238{239	return ARRAY_SIZE(eq5p_pins);240}241 242static const char *eq5p_pinctrl_get_group_name(struct pinctrl_dev *pctldev,243					       unsigned int selector)244{245	return pctldev->desc->pins[selector].name;246}247 248static int eq5p_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,249				       unsigned int selector,250				       const unsigned int **pins,251				       unsigned int *num_pins)252{253	*pins = &pctldev->desc->pins[selector].number;254	*num_pins = 1;255	return 0;256}257 258static int eq5p_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,259			    unsigned long *config)260{261	enum pin_config_param param = pinconf_to_config_param(*config);262	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);263	unsigned int offset = eq5p_pin_to_offset(pin);264	enum eq5p_bank bank = eq5p_pin_to_bank(pin);265	u32 val_ds, arg;266	bool pd, pu;267 268	pd = eq5p_test_bit(pctrl, bank, EQ5P_PD, offset);269	pu = eq5p_test_bit(pctrl, bank, EQ5P_PU, offset);270 271	switch (param) {272	case PIN_CONFIG_BIAS_DISABLE:273		arg = !(pd || pu);274		break;275	case PIN_CONFIG_BIAS_PULL_DOWN:276		arg = pd;277		break;278	case PIN_CONFIG_BIAS_PULL_UP:279		arg = pu;280		break;281	case PIN_CONFIG_DRIVE_STRENGTH:282		offset *= 2; /* two bits per pin */283		if (offset >= 32) {284			val_ds = readl(pctrl->base + eq5p_regs[bank][EQ5P_DS_HIGH]);285			offset -= 32;286		} else {287			val_ds = readl(pctrl->base + eq5p_regs[bank][EQ5P_DS_LOW]);288		}289		arg = (val_ds >> offset) & EQ5P_DS_MASK;290		break;291	default:292		return -ENOTSUPP;293	}294 295	*config = pinconf_to_config_packed(param, arg);296	return 0;297}298 299static void eq5p_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,300				      struct seq_file *s,301				      unsigned int pin)302{303	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);304	const char *pin_name = pctrl->desc.pins[pin].name;305	unsigned int offset = eq5p_pin_to_offset(pin);306	enum eq5p_bank bank = eq5p_pin_to_bank(pin);307	const char *func_name, *bias;308	unsigned long ds_config;309	u32 drive_strength;310	bool pd, pu;311	int i, j;312 313	/*314	 * First, let's get the function name. All pins have only two functions:315	 * GPIO (IOCR == 0) and something else (IOCR == 1).316	 */317	if (eq5p_test_bit(pctrl, bank, EQ5P_IOCR, offset)) {318		func_name = NULL;319		for (i = 0; i < ARRAY_SIZE(eq5p_functions); i++) {320			if (i == GPIO_FUNC_SELECTOR)321				continue;322 323			for (j = 0; j < eq5p_functions[i].ngroups; j++) {324				/* Groups and pins are the same thing for us. */325				const char *x = eq5p_functions[i].groups[j];326 327				if (strcmp(x, pin_name) == 0) {328					func_name = eq5p_functions[i].name;329					break;330				}331			}332 333			if (func_name)334				break;335		}336 337		/*338		 * We have not found the function attached to this pin, this339		 * should never occur as all pins have exactly two functions.340		 */341		if (!func_name)342			func_name = "unknown";343	} else {344		func_name = eq5p_functions[GPIO_FUNC_SELECTOR].name;345	}346 347	/* Second, we retrieve the bias. */348	pd = eq5p_test_bit(pctrl, bank, EQ5P_PD, offset);349	pu = eq5p_test_bit(pctrl, bank, EQ5P_PU, offset);350	if (pd && pu)351		bias = "both";352	else if (pd && !pu)353		bias = "pulldown";354	else if (!pd && pu)355		bias = "pullup";356	else357		bias = "none";358 359	/* Third, we get the drive strength. */360	ds_config = pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH, 0);361	eq5p_pinconf_get(pctldev, pin, &ds_config);362	drive_strength = pinconf_to_config_argument(ds_config);363 364	seq_printf(s, "function=%s bias=%s drive_strength=%d",365		   func_name, bias, drive_strength);366}367 368static const struct pinctrl_ops eq5p_pinctrl_ops = {369	.get_groups_count	= eq5p_pinctrl_get_groups_count,370	.get_group_name		= eq5p_pinctrl_get_group_name,371	.get_group_pins		= eq5p_pinctrl_get_group_pins,372	.pin_dbg_show		= eq5p_pinctrl_pin_dbg_show,373	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,374	.dt_free_map		= pinctrl_utils_free_map,375};376 377static int eq5p_pinmux_get_functions_count(struct pinctrl_dev *pctldev)378{379	return ARRAY_SIZE(eq5p_functions);380}381 382static const char *eq5p_pinmux_get_function_name(struct pinctrl_dev *pctldev,383						 unsigned int selector)384{385	return eq5p_functions[selector].name;386}387 388static int eq5p_pinmux_get_function_groups(struct pinctrl_dev *pctldev,389					   unsigned int selector,390					   const char * const **groups,391					   unsigned int *num_groups)392{393	*groups = eq5p_functions[selector].groups;394	*num_groups = eq5p_functions[selector].ngroups;395	return 0;396}397 398static int eq5p_pinmux_set_mux(struct pinctrl_dev *pctldev,399			       unsigned int func_selector, unsigned int pin)400{401	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);402	const char *func_name = eq5p_functions[func_selector].name;403	const char *group_name = pctldev->desc->pins[pin].name;404	bool is_gpio = func_selector == GPIO_FUNC_SELECTOR;405	unsigned int offset = eq5p_pin_to_offset(pin);406	enum eq5p_bank bank = eq5p_pin_to_bank(pin);407	u32 mask, val;408 409	dev_dbg(pctldev->dev, "func=%s group=%s\n", func_name, group_name);410 411	mask = BIT(offset);412	val = is_gpio ? 0 : mask;413	eq5p_update_bits(pctrl, bank, EQ5P_IOCR, mask, val);414	return 0;415}416 417static int eq5p_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,418					   struct pinctrl_gpio_range *range,419					   unsigned int pin)420{421	/* Pin numbers and group selectors are the same thing in our case. */422	return eq5p_pinmux_set_mux(pctldev, GPIO_FUNC_SELECTOR, pin);423}424 425static const struct pinmux_ops eq5p_pinmux_ops = {426	.get_functions_count	= eq5p_pinmux_get_functions_count,427	.get_function_name	= eq5p_pinmux_get_function_name,428	.get_function_groups	= eq5p_pinmux_get_function_groups,429	.set_mux		= eq5p_pinmux_set_mux,430	.gpio_request_enable	= eq5p_pinmux_gpio_request_enable,431	.strict			= true,432};433 434static int eq5p_pinconf_set_drive_strength(struct pinctrl_dev *pctldev,435					   unsigned int pin, u32 arg)436{437	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);438	unsigned int offset = eq5p_pin_to_offset(pin);439	enum eq5p_bank bank = eq5p_pin_to_bank(pin);440	unsigned int reg;441	u32 mask, val;442 443	if (arg & ~EQ5P_DS_MASK) {444		dev_err(pctldev->dev, "Unsupported drive strength: %u\n", arg);445		return -EINVAL;446	}447 448	offset *= 2; /* two bits per pin */449 450	if (offset >= 32) {451		reg = EQ5P_DS_HIGH;452		offset -= 32;453	} else {454		reg = EQ5P_DS_LOW;455	}456 457	mask = EQ5P_DS_MASK << offset;458	val = arg << offset;459	eq5p_update_bits(pctrl, bank, reg, mask, val);460	return 0;461}462 463static int eq5p_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,464			    unsigned long *configs, unsigned int num_configs)465{466	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);467	const char *pin_name = pctldev->desc->pins[pin].name;468	unsigned int offset = eq5p_pin_to_offset(pin);469	enum eq5p_bank bank = eq5p_pin_to_bank(pin);470	struct device *dev = pctldev->dev;471	u32 val = BIT(offset);472	unsigned int i;473 474	for (i = 0; i < num_configs; i++) {475		enum pin_config_param param = pinconf_to_config_param(configs[i]);476		u32 arg = pinconf_to_config_argument(configs[i]);477 478		switch (param) {479		case PIN_CONFIG_BIAS_DISABLE:480			dev_dbg(dev, "pin=%s bias_disable\n", pin_name);481 482			eq5p_update_bits(pctrl, bank, EQ5P_PD, val, 0);483			eq5p_update_bits(pctrl, bank, EQ5P_PU, val, 0);484			break;485 486		case PIN_CONFIG_BIAS_PULL_DOWN:487			dev_dbg(dev, "pin=%s bias_pull_down arg=%u\n",488				pin_name, arg);489 490			if (arg == 0) /* cannot connect to GND */491				return -ENOTSUPP;492 493			eq5p_update_bits(pctrl, bank, EQ5P_PD, val, val);494			eq5p_update_bits(pctrl, bank, EQ5P_PU, val, 0);495			break;496 497		case PIN_CONFIG_BIAS_PULL_UP:498			dev_dbg(dev, "pin=%s bias_pull_up arg=%u\n",499				pin_name, arg);500 501			if (arg == 0) /* cannot connect to VDD */502				return -ENOTSUPP;503 504			eq5p_update_bits(pctrl, bank, EQ5P_PD, val, 0);505			eq5p_update_bits(pctrl, bank, EQ5P_PU, val, val);506			break;507 508		case PIN_CONFIG_DRIVE_STRENGTH:509			dev_dbg(dev, "pin=%s drive_strength arg=%u\n",510				pin_name, arg);511 512			eq5p_pinconf_set_drive_strength(pctldev, pin, arg);513			break;514 515		default:516			dev_err(dev, "Unsupported pinconf %u\n", param);517			return -ENOTSUPP;518		}519	}520 521	return 0;522}523 524static const struct pinconf_ops eq5p_pinconf_ops = {525	.is_generic = true,526	.pin_config_get = eq5p_pinconf_get,527	.pin_config_set = eq5p_pinconf_set,528	/* Pins and groups are equivalent in this driver. */529	.pin_config_group_get = eq5p_pinconf_get,530	.pin_config_group_set = eq5p_pinconf_set,531};532 533static int eq5p_probe(struct auxiliary_device *adev,534		      const struct auxiliary_device_id *id)535{536	struct device *dev = &adev->dev;537	struct pinctrl_dev *pctldev;538	struct eq5p_pinctrl *pctrl;539	int ret;540 541	pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);542	if (!pctrl)543		return -ENOMEM;544 545	pctrl->base = (void __iomem *)dev_get_platdata(dev);546	pctrl->desc.name = dev_name(dev);547	pctrl->desc.pins = eq5p_pins;548	pctrl->desc.npins = ARRAY_SIZE(eq5p_pins);549	pctrl->desc.pctlops = &eq5p_pinctrl_ops;550	pctrl->desc.pmxops = &eq5p_pinmux_ops;551	pctrl->desc.confops = &eq5p_pinconf_ops;552	pctrl->desc.owner = THIS_MODULE;553 554	ret = devm_pinctrl_register_and_init(dev, &pctrl->desc, pctrl, &pctldev);555	if (ret)556		return dev_err_probe(dev, ret, "failed registering pinctrl device\n");557 558	ret = pinctrl_enable(pctldev);559	if (ret)560		return dev_err_probe(dev, ret, "failed enabling pinctrl device\n");561 562	return 0;563}564 565static const struct auxiliary_device_id eq5p_id_table[] = {566	{ .name = "clk_eyeq.pinctrl" },567	{}568};569MODULE_DEVICE_TABLE(auxiliary, eq5p_id_table);570 571static struct auxiliary_driver eq5p_driver = {572	.probe = eq5p_probe,573	.id_table = eq5p_id_table,574};575module_auxiliary_driver(eq5p_driver);576