cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pinctrl-spmi-mpp.c (25812B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
      4 */
      5
      6#include <linux/gpio/driver.h>
      7#include <linux/module.h>
      8#include <linux/of.h>
      9#include <linux/of_irq.h>
     10#include <linux/pinctrl/pinconf-generic.h>
     11#include <linux/pinctrl/pinconf.h>
     12#include <linux/pinctrl/pinmux.h>
     13#include <linux/platform_device.h>
     14#include <linux/regmap.h>
     15#include <linux/slab.h>
     16#include <linux/types.h>
     17
     18#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
     19
     20#include "../core.h"
     21#include "../pinctrl-utils.h"
     22
     23#define PMIC_MPP_ADDRESS_RANGE			0x100
     24
     25/*
     26 * Pull Up Values - it indicates whether a pull-up should be
     27 * applied for bidirectional mode only. The hardware ignores the
     28 * configuration when operating in other modes.
     29 */
     30#define PMIC_MPP_PULL_UP_0P6KOHM		0
     31#define PMIC_MPP_PULL_UP_10KOHM			1
     32#define PMIC_MPP_PULL_UP_30KOHM			2
     33#define PMIC_MPP_PULL_UP_OPEN			3
     34
     35/* type registers base address bases */
     36#define PMIC_MPP_REG_TYPE			0x4
     37#define PMIC_MPP_REG_SUBTYPE			0x5
     38
     39/* mpp peripheral type and subtype values */
     40#define PMIC_MPP_TYPE				0x11
     41#define PMIC_MPP_SUBTYPE_4CH_NO_ANA_OUT		0x3
     42#define PMIC_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT	0x4
     43#define PMIC_MPP_SUBTYPE_4CH_NO_SINK		0x5
     44#define PMIC_MPP_SUBTYPE_ULT_4CH_NO_SINK	0x6
     45#define PMIC_MPP_SUBTYPE_4CH_FULL_FUNC		0x7
     46#define PMIC_MPP_SUBTYPE_8CH_FULL_FUNC		0xf
     47
     48#define PMIC_MPP_REG_RT_STS			0x10
     49#define PMIC_MPP_REG_RT_STS_VAL_MASK		0x1
     50
     51/* control register base address bases */
     52#define PMIC_MPP_REG_MODE_CTL			0x40
     53#define PMIC_MPP_REG_DIG_VIN_CTL		0x41
     54#define PMIC_MPP_REG_DIG_PULL_CTL		0x42
     55#define PMIC_MPP_REG_DIG_IN_CTL			0x43
     56#define PMIC_MPP_REG_EN_CTL			0x46
     57#define PMIC_MPP_REG_AOUT_CTL			0x48
     58#define PMIC_MPP_REG_AIN_CTL			0x4a
     59#define PMIC_MPP_REG_SINK_CTL			0x4c
     60
     61/* PMIC_MPP_REG_MODE_CTL */
     62#define PMIC_MPP_REG_MODE_VALUE_MASK		0x1
     63#define PMIC_MPP_REG_MODE_FUNCTION_SHIFT	1
     64#define PMIC_MPP_REG_MODE_FUNCTION_MASK		0x7
     65#define PMIC_MPP_REG_MODE_DIR_SHIFT		4
     66#define PMIC_MPP_REG_MODE_DIR_MASK		0x7
     67
     68/* PMIC_MPP_REG_DIG_VIN_CTL */
     69#define PMIC_MPP_REG_VIN_SHIFT			0
     70#define PMIC_MPP_REG_VIN_MASK			0x7
     71
     72/* PMIC_MPP_REG_DIG_PULL_CTL */
     73#define PMIC_MPP_REG_PULL_SHIFT			0
     74#define PMIC_MPP_REG_PULL_MASK			0x7
     75
     76/* PMIC_MPP_REG_EN_CTL */
     77#define PMIC_MPP_REG_MASTER_EN_SHIFT		7
     78
     79/* PMIC_MPP_REG_AIN_CTL */
     80#define PMIC_MPP_REG_AIN_ROUTE_SHIFT		0
     81#define PMIC_MPP_REG_AIN_ROUTE_MASK		0x7
     82
     83#define PMIC_MPP_MODE_DIGITAL_INPUT		0
     84#define PMIC_MPP_MODE_DIGITAL_OUTPUT		1
     85#define PMIC_MPP_MODE_DIGITAL_BIDIR		2
     86#define PMIC_MPP_MODE_ANALOG_BIDIR		3
     87#define PMIC_MPP_MODE_ANALOG_INPUT		4
     88#define PMIC_MPP_MODE_ANALOG_OUTPUT		5
     89#define PMIC_MPP_MODE_CURRENT_SINK		6
     90
     91#define PMIC_MPP_SELECTOR_NORMAL		0
     92#define PMIC_MPP_SELECTOR_PAIRED		1
     93#define PMIC_MPP_SELECTOR_DTEST_FIRST		4
     94
     95#define PMIC_MPP_PHYSICAL_OFFSET		1
     96
     97/* Qualcomm specific pin configurations */
     98#define PMIC_MPP_CONF_AMUX_ROUTE		(PIN_CONFIG_END + 1)
     99#define PMIC_MPP_CONF_ANALOG_LEVEL		(PIN_CONFIG_END + 2)
    100#define PMIC_MPP_CONF_DTEST_SELECTOR		(PIN_CONFIG_END + 3)
    101#define PMIC_MPP_CONF_PAIRED			(PIN_CONFIG_END + 4)
    102
    103/**
    104 * struct pmic_mpp_pad - keep current MPP settings
    105 * @base: Address base in SPMI device.
    106 * @is_enabled: Set to false when MPP should be put in high Z state.
    107 * @out_value: Cached pin output value.
    108 * @output_enabled: Set to true if MPP output logic is enabled.
    109 * @input_enabled: Set to true if MPP input buffer logic is enabled.
    110 * @paired: Pin operates in paired mode
    111 * @has_pullup: Pin has support to configure pullup
    112 * @num_sources: Number of power-sources supported by this MPP.
    113 * @power_source: Current power-source used.
    114 * @amux_input: Set the source for analog input.
    115 * @aout_level: Analog output level
    116 * @pullup: Pullup resistor value. Valid in Bidirectional mode only.
    117 * @function: See pmic_mpp_functions[].
    118 * @drive_strength: Amount of current in sink mode
    119 * @dtest: DTEST route selector
    120 */
    121struct pmic_mpp_pad {
    122	u16		base;
    123	bool		is_enabled;
    124	bool		out_value;
    125	bool		output_enabled;
    126	bool		input_enabled;
    127	bool		paired;
    128	bool		has_pullup;
    129	unsigned int	num_sources;
    130	unsigned int	power_source;
    131	unsigned int	amux_input;
    132	unsigned int	aout_level;
    133	unsigned int	pullup;
    134	unsigned int	function;
    135	unsigned int	drive_strength;
    136	unsigned int	dtest;
    137};
    138
    139struct pmic_mpp_state {
    140	struct device	*dev;
    141	struct regmap	*map;
    142	struct pinctrl_dev *ctrl;
    143	struct gpio_chip chip;
    144	struct irq_chip irq;
    145};
    146
    147static const struct pinconf_generic_params pmic_mpp_bindings[] = {
    148	{"qcom,amux-route",	PMIC_MPP_CONF_AMUX_ROUTE,	0},
    149	{"qcom,analog-level",	PMIC_MPP_CONF_ANALOG_LEVEL,	0},
    150	{"qcom,dtest",		PMIC_MPP_CONF_DTEST_SELECTOR,	0},
    151	{"qcom,paired",		PMIC_MPP_CONF_PAIRED,		0},
    152};
    153
    154#ifdef CONFIG_DEBUG_FS
    155static const struct pin_config_item pmic_conf_items[] = {
    156	PCONFDUMP(PMIC_MPP_CONF_AMUX_ROUTE, "analog mux", NULL, true),
    157	PCONFDUMP(PMIC_MPP_CONF_ANALOG_LEVEL, "analog level", NULL, true),
    158	PCONFDUMP(PMIC_MPP_CONF_DTEST_SELECTOR, "dtest", NULL, true),
    159	PCONFDUMP(PMIC_MPP_CONF_PAIRED, "paired", NULL, false),
    160};
    161#endif
    162
    163static const char *const pmic_mpp_groups[] = {
    164	"mpp1", "mpp2", "mpp3", "mpp4", "mpp5", "mpp6", "mpp7", "mpp8",
    165};
    166
    167#define PMIC_MPP_DIGITAL	0
    168#define PMIC_MPP_ANALOG		1
    169#define PMIC_MPP_SINK		2
    170
    171static const char *const pmic_mpp_functions[] = {
    172	"digital", "analog", "sink"
    173};
    174
    175static int pmic_mpp_read(struct pmic_mpp_state *state,
    176			 struct pmic_mpp_pad *pad, unsigned int addr)
    177{
    178	unsigned int val;
    179	int ret;
    180
    181	ret = regmap_read(state->map, pad->base + addr, &val);
    182	if (ret < 0)
    183		dev_err(state->dev, "read 0x%x failed\n", addr);
    184	else
    185		ret = val;
    186
    187	return ret;
    188}
    189
    190static int pmic_mpp_write(struct pmic_mpp_state *state,
    191			  struct pmic_mpp_pad *pad, unsigned int addr,
    192			  unsigned int val)
    193{
    194	int ret;
    195
    196	ret = regmap_write(state->map, pad->base + addr, val);
    197	if (ret < 0)
    198		dev_err(state->dev, "write 0x%x failed\n", addr);
    199
    200	return ret;
    201}
    202
    203static int pmic_mpp_get_groups_count(struct pinctrl_dev *pctldev)
    204{
    205	/* Every PIN is a group */
    206	return pctldev->desc->npins;
    207}
    208
    209static const char *pmic_mpp_get_group_name(struct pinctrl_dev *pctldev,
    210					   unsigned pin)
    211{
    212	return pctldev->desc->pins[pin].name;
    213}
    214
    215static int pmic_mpp_get_group_pins(struct pinctrl_dev *pctldev,
    216				   unsigned pin,
    217				   const unsigned **pins, unsigned *num_pins)
    218{
    219	*pins = &pctldev->desc->pins[pin].number;
    220	*num_pins = 1;
    221	return 0;
    222}
    223
    224static const struct pinctrl_ops pmic_mpp_pinctrl_ops = {
    225	.get_groups_count	= pmic_mpp_get_groups_count,
    226	.get_group_name		= pmic_mpp_get_group_name,
    227	.get_group_pins		= pmic_mpp_get_group_pins,
    228	.dt_node_to_map		= pinconf_generic_dt_node_to_map_group,
    229	.dt_free_map		= pinctrl_utils_free_map,
    230};
    231
    232static int pmic_mpp_get_functions_count(struct pinctrl_dev *pctldev)
    233{
    234	return ARRAY_SIZE(pmic_mpp_functions);
    235}
    236
    237static const char *pmic_mpp_get_function_name(struct pinctrl_dev *pctldev,
    238					      unsigned function)
    239{
    240	return pmic_mpp_functions[function];
    241}
    242
    243static int pmic_mpp_get_function_groups(struct pinctrl_dev *pctldev,
    244					unsigned function,
    245					const char *const **groups,
    246					unsigned *const num_qgroups)
    247{
    248	*groups = pmic_mpp_groups;
    249	*num_qgroups = pctldev->desc->npins;
    250	return 0;
    251}
    252
    253static int pmic_mpp_write_mode_ctl(struct pmic_mpp_state *state,
    254				   struct pmic_mpp_pad *pad)
    255{
    256	unsigned int mode;
    257	unsigned int sel;
    258	unsigned int val;
    259	unsigned int en;
    260
    261	switch (pad->function) {
    262	case PMIC_MPP_ANALOG:
    263		if (pad->input_enabled && pad->output_enabled)
    264			mode = PMIC_MPP_MODE_ANALOG_BIDIR;
    265		else if (pad->input_enabled)
    266			mode = PMIC_MPP_MODE_ANALOG_INPUT;
    267		else
    268			mode = PMIC_MPP_MODE_ANALOG_OUTPUT;
    269		break;
    270	case PMIC_MPP_DIGITAL:
    271		if (pad->input_enabled && pad->output_enabled)
    272			mode = PMIC_MPP_MODE_DIGITAL_BIDIR;
    273		else if (pad->input_enabled)
    274			mode = PMIC_MPP_MODE_DIGITAL_INPUT;
    275		else
    276			mode = PMIC_MPP_MODE_DIGITAL_OUTPUT;
    277		break;
    278	case PMIC_MPP_SINK:
    279	default:
    280		mode = PMIC_MPP_MODE_CURRENT_SINK;
    281		break;
    282	}
    283
    284	if (pad->dtest)
    285		sel = PMIC_MPP_SELECTOR_DTEST_FIRST + pad->dtest - 1;
    286	else if (pad->paired)
    287		sel = PMIC_MPP_SELECTOR_PAIRED;
    288	else
    289		sel = PMIC_MPP_SELECTOR_NORMAL;
    290
    291	en = !!pad->out_value;
    292
    293	val = mode << PMIC_MPP_REG_MODE_DIR_SHIFT |
    294	      sel << PMIC_MPP_REG_MODE_FUNCTION_SHIFT |
    295	      en;
    296
    297	return pmic_mpp_write(state, pad, PMIC_MPP_REG_MODE_CTL, val);
    298}
    299
    300static int pmic_mpp_set_mux(struct pinctrl_dev *pctldev, unsigned function,
    301				unsigned pin)
    302{
    303	struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev);
    304	struct pmic_mpp_pad *pad;
    305	unsigned int val;
    306	int ret;
    307
    308	pad = pctldev->desc->pins[pin].drv_data;
    309
    310	pad->function = function;
    311
    312	ret = pmic_mpp_write_mode_ctl(state, pad);
    313	if (ret < 0)
    314		return ret;
    315
    316	val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT;
    317
    318	return pmic_mpp_write(state, pad, PMIC_MPP_REG_EN_CTL, val);
    319}
    320
    321static const struct pinmux_ops pmic_mpp_pinmux_ops = {
    322	.get_functions_count	= pmic_mpp_get_functions_count,
    323	.get_function_name	= pmic_mpp_get_function_name,
    324	.get_function_groups	= pmic_mpp_get_function_groups,
    325	.set_mux		= pmic_mpp_set_mux,
    326};
    327
    328static int pmic_mpp_config_get(struct pinctrl_dev *pctldev,
    329			       unsigned int pin, unsigned long *config)
    330{
    331	unsigned param = pinconf_to_config_param(*config);
    332	struct pmic_mpp_pad *pad;
    333	unsigned arg = 0;
    334
    335	pad = pctldev->desc->pins[pin].drv_data;
    336
    337	switch (param) {
    338	case PIN_CONFIG_BIAS_DISABLE:
    339		if (pad->pullup != PMIC_MPP_PULL_UP_OPEN)
    340			return -EINVAL;
    341		arg = 1;
    342		break;
    343	case PIN_CONFIG_BIAS_PULL_UP:
    344		switch (pad->pullup) {
    345		case PMIC_MPP_PULL_UP_0P6KOHM:
    346			arg = 600;
    347			break;
    348		case PMIC_MPP_PULL_UP_10KOHM:
    349			arg = 10000;
    350			break;
    351		case PMIC_MPP_PULL_UP_30KOHM:
    352			arg = 30000;
    353			break;
    354		default:
    355			return -EINVAL;
    356		}
    357		break;
    358	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
    359		if (pad->is_enabled)
    360			return -EINVAL;
    361		arg = 1;
    362		break;
    363	case PIN_CONFIG_POWER_SOURCE:
    364		arg = pad->power_source;
    365		break;
    366	case PIN_CONFIG_INPUT_ENABLE:
    367		if (!pad->input_enabled)
    368			return -EINVAL;
    369		arg = 1;
    370		break;
    371	case PIN_CONFIG_OUTPUT:
    372		arg = pad->out_value;
    373		break;
    374	case PMIC_MPP_CONF_DTEST_SELECTOR:
    375		arg = pad->dtest;
    376		break;
    377	case PMIC_MPP_CONF_AMUX_ROUTE:
    378		arg = pad->amux_input;
    379		break;
    380	case PMIC_MPP_CONF_PAIRED:
    381		if (!pad->paired)
    382			return -EINVAL;
    383		arg = 1;
    384		break;
    385	case PIN_CONFIG_DRIVE_STRENGTH:
    386		arg = pad->drive_strength;
    387		break;
    388	case PMIC_MPP_CONF_ANALOG_LEVEL:
    389		arg = pad->aout_level;
    390		break;
    391	default:
    392		return -EINVAL;
    393	}
    394
    395	/* Convert register value to pinconf value */
    396	*config = pinconf_to_config_packed(param, arg);
    397	return 0;
    398}
    399
    400static int pmic_mpp_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
    401			       unsigned long *configs, unsigned nconfs)
    402{
    403	struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev);
    404	struct pmic_mpp_pad *pad;
    405	unsigned param, arg;
    406	unsigned int val;
    407	int i, ret;
    408
    409	pad = pctldev->desc->pins[pin].drv_data;
    410
    411	/* Make it possible to enable the pin, by not setting high impedance */
    412	pad->is_enabled = true;
    413
    414	for (i = 0; i < nconfs; i++) {
    415		param = pinconf_to_config_param(configs[i]);
    416		arg = pinconf_to_config_argument(configs[i]);
    417
    418		switch (param) {
    419		case PIN_CONFIG_BIAS_DISABLE:
    420			pad->pullup = PMIC_MPP_PULL_UP_OPEN;
    421			break;
    422		case PIN_CONFIG_BIAS_PULL_UP:
    423			switch (arg) {
    424			case 600:
    425				pad->pullup = PMIC_MPP_PULL_UP_0P6KOHM;
    426				break;
    427			case 10000:
    428				pad->pullup = PMIC_MPP_PULL_UP_10KOHM;
    429				break;
    430			case 30000:
    431				pad->pullup = PMIC_MPP_PULL_UP_30KOHM;
    432				break;
    433			default:
    434				return -EINVAL;
    435			}
    436			break;
    437		case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
    438			pad->is_enabled = false;
    439			break;
    440		case PIN_CONFIG_POWER_SOURCE:
    441			if (arg >= pad->num_sources)
    442				return -EINVAL;
    443			pad->power_source = arg;
    444			break;
    445		case PIN_CONFIG_INPUT_ENABLE:
    446			pad->input_enabled = arg ? true : false;
    447			break;
    448		case PIN_CONFIG_OUTPUT:
    449			pad->output_enabled = true;
    450			pad->out_value = arg;
    451			break;
    452		case PMIC_MPP_CONF_DTEST_SELECTOR:
    453			pad->dtest = arg;
    454			break;
    455		case PIN_CONFIG_DRIVE_STRENGTH:
    456			pad->drive_strength = arg;
    457			break;
    458		case PMIC_MPP_CONF_AMUX_ROUTE:
    459			if (arg >= PMIC_MPP_AMUX_ROUTE_ABUS4)
    460				return -EINVAL;
    461			pad->amux_input = arg;
    462			break;
    463		case PMIC_MPP_CONF_ANALOG_LEVEL:
    464			pad->aout_level = arg;
    465			break;
    466		case PMIC_MPP_CONF_PAIRED:
    467			pad->paired = !!arg;
    468			break;
    469		default:
    470			return -EINVAL;
    471		}
    472	}
    473
    474	val = pad->power_source << PMIC_MPP_REG_VIN_SHIFT;
    475
    476	ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_DIG_VIN_CTL, val);
    477	if (ret < 0)
    478		return ret;
    479
    480	if (pad->has_pullup) {
    481		val = pad->pullup << PMIC_MPP_REG_PULL_SHIFT;
    482
    483		ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_DIG_PULL_CTL,
    484				     val);
    485		if (ret < 0)
    486			return ret;
    487	}
    488
    489	val = pad->amux_input & PMIC_MPP_REG_AIN_ROUTE_MASK;
    490
    491	ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_AIN_CTL, val);
    492	if (ret < 0)
    493		return ret;
    494
    495	ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_AOUT_CTL, pad->aout_level);
    496	if (ret < 0)
    497		return ret;
    498
    499	ret = pmic_mpp_write_mode_ctl(state, pad);
    500	if (ret < 0)
    501		return ret;
    502
    503	ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_SINK_CTL, pad->drive_strength);
    504	if (ret < 0)
    505		return ret;
    506
    507	val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT;
    508
    509	return pmic_mpp_write(state, pad, PMIC_MPP_REG_EN_CTL, val);
    510}
    511
    512static void pmic_mpp_config_dbg_show(struct pinctrl_dev *pctldev,
    513				     struct seq_file *s, unsigned pin)
    514{
    515	struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev);
    516	struct pmic_mpp_pad *pad;
    517	int ret;
    518
    519	static const char *const biases[] = {
    520		"0.6kOhm", "10kOhm", "30kOhm", "Disabled"
    521	};
    522
    523	pad = pctldev->desc->pins[pin].drv_data;
    524
    525	seq_printf(s, " mpp%-2d:", pin + PMIC_MPP_PHYSICAL_OFFSET);
    526
    527	if (!pad->is_enabled) {
    528		seq_puts(s, " ---");
    529	} else {
    530
    531		if (pad->input_enabled) {
    532			ret = pmic_mpp_read(state, pad, PMIC_MPP_REG_RT_STS);
    533			if (ret < 0)
    534				return;
    535
    536			ret &= PMIC_MPP_REG_RT_STS_VAL_MASK;
    537			pad->out_value = ret;
    538		}
    539
    540		seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in");
    541		seq_printf(s, " %-7s", pmic_mpp_functions[pad->function]);
    542		seq_printf(s, " vin-%d", pad->power_source);
    543		seq_printf(s, " %d", pad->aout_level);
    544		if (pad->has_pullup)
    545			seq_printf(s, " %-8s", biases[pad->pullup]);
    546		seq_printf(s, " %-4s", pad->out_value ? "high" : "low");
    547		if (pad->dtest)
    548			seq_printf(s, " dtest%d", pad->dtest);
    549		if (pad->paired)
    550			seq_puts(s, " paired");
    551	}
    552}
    553
    554static const struct pinconf_ops pmic_mpp_pinconf_ops = {
    555	.is_generic = true,
    556	.pin_config_group_get		= pmic_mpp_config_get,
    557	.pin_config_group_set		= pmic_mpp_config_set,
    558	.pin_config_group_dbg_show	= pmic_mpp_config_dbg_show,
    559};
    560
    561static int pmic_mpp_direction_input(struct gpio_chip *chip, unsigned pin)
    562{
    563	struct pmic_mpp_state *state = gpiochip_get_data(chip);
    564	unsigned long config;
    565
    566	config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1);
    567
    568	return pmic_mpp_config_set(state->ctrl, pin, &config, 1);
    569}
    570
    571static int pmic_mpp_direction_output(struct gpio_chip *chip,
    572				     unsigned pin, int val)
    573{
    574	struct pmic_mpp_state *state = gpiochip_get_data(chip);
    575	unsigned long config;
    576
    577	config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val);
    578
    579	return pmic_mpp_config_set(state->ctrl, pin, &config, 1);
    580}
    581
    582static int pmic_mpp_get(struct gpio_chip *chip, unsigned pin)
    583{
    584	struct pmic_mpp_state *state = gpiochip_get_data(chip);
    585	struct pmic_mpp_pad *pad;
    586	int ret;
    587
    588	pad = state->ctrl->desc->pins[pin].drv_data;
    589
    590	if (pad->input_enabled) {
    591		ret = pmic_mpp_read(state, pad, PMIC_MPP_REG_RT_STS);
    592		if (ret < 0)
    593			return ret;
    594
    595		pad->out_value = ret & PMIC_MPP_REG_RT_STS_VAL_MASK;
    596	}
    597
    598	return !!pad->out_value;
    599}
    600
    601static void pmic_mpp_set(struct gpio_chip *chip, unsigned pin, int value)
    602{
    603	struct pmic_mpp_state *state = gpiochip_get_data(chip);
    604	unsigned long config;
    605
    606	config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value);
    607
    608	pmic_mpp_config_set(state->ctrl, pin, &config, 1);
    609}
    610
    611static int pmic_mpp_of_xlate(struct gpio_chip *chip,
    612			     const struct of_phandle_args *gpio_desc,
    613			     u32 *flags)
    614{
    615	if (chip->of_gpio_n_cells < 2)
    616		return -EINVAL;
    617
    618	if (flags)
    619		*flags = gpio_desc->args[1];
    620
    621	return gpio_desc->args[0] - PMIC_MPP_PHYSICAL_OFFSET;
    622}
    623
    624static void pmic_mpp_dbg_show(struct seq_file *s, struct gpio_chip *chip)
    625{
    626	struct pmic_mpp_state *state = gpiochip_get_data(chip);
    627	unsigned i;
    628
    629	for (i = 0; i < chip->ngpio; i++) {
    630		pmic_mpp_config_dbg_show(state->ctrl, s, i);
    631		seq_puts(s, "\n");
    632	}
    633}
    634
    635static const struct gpio_chip pmic_mpp_gpio_template = {
    636	.direction_input	= pmic_mpp_direction_input,
    637	.direction_output	= pmic_mpp_direction_output,
    638	.get			= pmic_mpp_get,
    639	.set			= pmic_mpp_set,
    640	.request		= gpiochip_generic_request,
    641	.free			= gpiochip_generic_free,
    642	.of_xlate		= pmic_mpp_of_xlate,
    643	.dbg_show		= pmic_mpp_dbg_show,
    644};
    645
    646static int pmic_mpp_populate(struct pmic_mpp_state *state,
    647			     struct pmic_mpp_pad *pad)
    648{
    649	int type, subtype, val, dir;
    650	unsigned int sel;
    651
    652	type = pmic_mpp_read(state, pad, PMIC_MPP_REG_TYPE);
    653	if (type < 0)
    654		return type;
    655
    656	if (type != PMIC_MPP_TYPE) {
    657		dev_err(state->dev, "incorrect block type 0x%x at 0x%x\n",
    658			type, pad->base);
    659		return -ENODEV;
    660	}
    661
    662	subtype = pmic_mpp_read(state, pad, PMIC_MPP_REG_SUBTYPE);
    663	if (subtype < 0)
    664		return subtype;
    665
    666	switch (subtype) {
    667	case PMIC_MPP_SUBTYPE_4CH_NO_ANA_OUT:
    668	case PMIC_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT:
    669	case PMIC_MPP_SUBTYPE_4CH_NO_SINK:
    670	case PMIC_MPP_SUBTYPE_ULT_4CH_NO_SINK:
    671	case PMIC_MPP_SUBTYPE_4CH_FULL_FUNC:
    672		pad->num_sources = 4;
    673		break;
    674	case PMIC_MPP_SUBTYPE_8CH_FULL_FUNC:
    675		pad->num_sources = 8;
    676		break;
    677	default:
    678		dev_err(state->dev, "unknown MPP type 0x%x at 0x%x\n",
    679			subtype, pad->base);
    680		return -ENODEV;
    681	}
    682
    683	val = pmic_mpp_read(state, pad, PMIC_MPP_REG_MODE_CTL);
    684	if (val < 0)
    685		return val;
    686
    687	pad->out_value = val & PMIC_MPP_REG_MODE_VALUE_MASK;
    688
    689	dir = val >> PMIC_MPP_REG_MODE_DIR_SHIFT;
    690	dir &= PMIC_MPP_REG_MODE_DIR_MASK;
    691
    692	switch (dir) {
    693	case PMIC_MPP_MODE_DIGITAL_INPUT:
    694		pad->input_enabled = true;
    695		pad->output_enabled = false;
    696		pad->function = PMIC_MPP_DIGITAL;
    697		break;
    698	case PMIC_MPP_MODE_DIGITAL_OUTPUT:
    699		pad->input_enabled = false;
    700		pad->output_enabled = true;
    701		pad->function = PMIC_MPP_DIGITAL;
    702		break;
    703	case PMIC_MPP_MODE_DIGITAL_BIDIR:
    704		pad->input_enabled = true;
    705		pad->output_enabled = true;
    706		pad->function = PMIC_MPP_DIGITAL;
    707		break;
    708	case PMIC_MPP_MODE_ANALOG_BIDIR:
    709		pad->input_enabled = true;
    710		pad->output_enabled = true;
    711		pad->function = PMIC_MPP_ANALOG;
    712		break;
    713	case PMIC_MPP_MODE_ANALOG_INPUT:
    714		pad->input_enabled = true;
    715		pad->output_enabled = false;
    716		pad->function = PMIC_MPP_ANALOG;
    717		break;
    718	case PMIC_MPP_MODE_ANALOG_OUTPUT:
    719		pad->input_enabled = false;
    720		pad->output_enabled = true;
    721		pad->function = PMIC_MPP_ANALOG;
    722		break;
    723	case PMIC_MPP_MODE_CURRENT_SINK:
    724		pad->input_enabled = false;
    725		pad->output_enabled = true;
    726		pad->function = PMIC_MPP_SINK;
    727		break;
    728	default:
    729		dev_err(state->dev, "unknown MPP direction\n");
    730		return -ENODEV;
    731	}
    732
    733	sel = val >> PMIC_MPP_REG_MODE_FUNCTION_SHIFT;
    734	sel &= PMIC_MPP_REG_MODE_FUNCTION_MASK;
    735
    736	if (sel >= PMIC_MPP_SELECTOR_DTEST_FIRST)
    737		pad->dtest = sel + 1;
    738	else if (sel == PMIC_MPP_SELECTOR_PAIRED)
    739		pad->paired = true;
    740
    741	val = pmic_mpp_read(state, pad, PMIC_MPP_REG_DIG_VIN_CTL);
    742	if (val < 0)
    743		return val;
    744
    745	pad->power_source = val >> PMIC_MPP_REG_VIN_SHIFT;
    746	pad->power_source &= PMIC_MPP_REG_VIN_MASK;
    747
    748	if (subtype != PMIC_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT &&
    749	    subtype != PMIC_MPP_SUBTYPE_ULT_4CH_NO_SINK) {
    750		val = pmic_mpp_read(state, pad, PMIC_MPP_REG_DIG_PULL_CTL);
    751		if (val < 0)
    752			return val;
    753
    754		pad->pullup = val >> PMIC_MPP_REG_PULL_SHIFT;
    755		pad->pullup &= PMIC_MPP_REG_PULL_MASK;
    756		pad->has_pullup = true;
    757	}
    758
    759	val = pmic_mpp_read(state, pad, PMIC_MPP_REG_AIN_CTL);
    760	if (val < 0)
    761		return val;
    762
    763	pad->amux_input = val >> PMIC_MPP_REG_AIN_ROUTE_SHIFT;
    764	pad->amux_input &= PMIC_MPP_REG_AIN_ROUTE_MASK;
    765
    766	val = pmic_mpp_read(state, pad, PMIC_MPP_REG_SINK_CTL);
    767	if (val < 0)
    768		return val;
    769
    770	pad->drive_strength = val;
    771
    772	val = pmic_mpp_read(state, pad, PMIC_MPP_REG_AOUT_CTL);
    773	if (val < 0)
    774		return val;
    775
    776	pad->aout_level = val;
    777
    778	val = pmic_mpp_read(state, pad, PMIC_MPP_REG_EN_CTL);
    779	if (val < 0)
    780		return val;
    781
    782	pad->is_enabled = !!val;
    783
    784	return 0;
    785}
    786
    787static int pmic_mpp_domain_translate(struct irq_domain *domain,
    788				      struct irq_fwspec *fwspec,
    789				      unsigned long *hwirq,
    790				      unsigned int *type)
    791{
    792	struct pmic_mpp_state *state = container_of(domain->host_data,
    793						     struct pmic_mpp_state,
    794						     chip);
    795
    796	if (fwspec->param_count != 2 ||
    797	    fwspec->param[0] < 1 || fwspec->param[0] > state->chip.ngpio)
    798		return -EINVAL;
    799
    800	*hwirq = fwspec->param[0] - PMIC_MPP_PHYSICAL_OFFSET;
    801	*type = fwspec->param[1];
    802
    803	return 0;
    804}
    805
    806static unsigned int pmic_mpp_child_offset_to_irq(struct gpio_chip *chip,
    807						  unsigned int offset)
    808{
    809	return offset + PMIC_MPP_PHYSICAL_OFFSET;
    810}
    811
    812static int pmic_mpp_child_to_parent_hwirq(struct gpio_chip *chip,
    813					   unsigned int child_hwirq,
    814					   unsigned int child_type,
    815					   unsigned int *parent_hwirq,
    816					   unsigned int *parent_type)
    817{
    818	*parent_hwirq = child_hwirq + 0xc0;
    819	*parent_type = child_type;
    820
    821	return 0;
    822}
    823
    824static int pmic_mpp_probe(struct platform_device *pdev)
    825{
    826	struct irq_domain *parent_domain;
    827	struct device_node *parent_node;
    828	struct device *dev = &pdev->dev;
    829	struct pinctrl_pin_desc *pindesc;
    830	struct pinctrl_desc *pctrldesc;
    831	struct pmic_mpp_pad *pad, *pads;
    832	struct pmic_mpp_state *state;
    833	struct gpio_irq_chip *girq;
    834	int ret, npins, i;
    835	u32 reg;
    836
    837	ret = of_property_read_u32(dev->of_node, "reg", &reg);
    838	if (ret < 0) {
    839		dev_err(dev, "missing base address");
    840		return ret;
    841	}
    842
    843	npins = (uintptr_t) device_get_match_data(&pdev->dev);
    844
    845	BUG_ON(npins > ARRAY_SIZE(pmic_mpp_groups));
    846
    847	state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
    848	if (!state)
    849		return -ENOMEM;
    850
    851	platform_set_drvdata(pdev, state);
    852
    853	state->dev = &pdev->dev;
    854	state->map = dev_get_regmap(dev->parent, NULL);
    855
    856	pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL);
    857	if (!pindesc)
    858		return -ENOMEM;
    859
    860	pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL);
    861	if (!pads)
    862		return -ENOMEM;
    863
    864	pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL);
    865	if (!pctrldesc)
    866		return -ENOMEM;
    867
    868	pctrldesc->pctlops = &pmic_mpp_pinctrl_ops;
    869	pctrldesc->pmxops = &pmic_mpp_pinmux_ops;
    870	pctrldesc->confops = &pmic_mpp_pinconf_ops;
    871	pctrldesc->owner = THIS_MODULE;
    872	pctrldesc->name = dev_name(dev);
    873	pctrldesc->pins = pindesc;
    874	pctrldesc->npins = npins;
    875
    876	pctrldesc->num_custom_params = ARRAY_SIZE(pmic_mpp_bindings);
    877	pctrldesc->custom_params = pmic_mpp_bindings;
    878#ifdef CONFIG_DEBUG_FS
    879	pctrldesc->custom_conf_items = pmic_conf_items;
    880#endif
    881
    882	for (i = 0; i < npins; i++, pindesc++) {
    883		pad = &pads[i];
    884		pindesc->drv_data = pad;
    885		pindesc->number = i;
    886		pindesc->name = pmic_mpp_groups[i];
    887
    888		pad->base = reg + i * PMIC_MPP_ADDRESS_RANGE;
    889
    890		ret = pmic_mpp_populate(state, pad);
    891		if (ret < 0)
    892			return ret;
    893	}
    894
    895	state->chip = pmic_mpp_gpio_template;
    896	state->chip.parent = dev;
    897	state->chip.base = -1;
    898	state->chip.ngpio = npins;
    899	state->chip.label = dev_name(dev);
    900	state->chip.of_gpio_n_cells = 2;
    901	state->chip.can_sleep = false;
    902
    903	state->ctrl = devm_pinctrl_register(dev, pctrldesc, state);
    904	if (IS_ERR(state->ctrl))
    905		return PTR_ERR(state->ctrl);
    906
    907	parent_node = of_irq_find_parent(state->dev->of_node);
    908	if (!parent_node)
    909		return -ENXIO;
    910
    911	parent_domain = irq_find_host(parent_node);
    912	of_node_put(parent_node);
    913	if (!parent_domain)
    914		return -ENXIO;
    915
    916	state->irq.name = "spmi-mpp",
    917	state->irq.irq_ack = irq_chip_ack_parent,
    918	state->irq.irq_mask = irq_chip_mask_parent,
    919	state->irq.irq_unmask = irq_chip_unmask_parent,
    920	state->irq.irq_set_type = irq_chip_set_type_parent,
    921	state->irq.irq_set_wake = irq_chip_set_wake_parent,
    922	state->irq.flags = IRQCHIP_MASK_ON_SUSPEND,
    923
    924	girq = &state->chip.irq;
    925	girq->chip = &state->irq;
    926	girq->default_type = IRQ_TYPE_NONE;
    927	girq->handler = handle_level_irq;
    928	girq->fwnode = of_node_to_fwnode(state->dev->of_node);
    929	girq->parent_domain = parent_domain;
    930	girq->child_to_parent_hwirq = pmic_mpp_child_to_parent_hwirq;
    931	girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_fourcell;
    932	girq->child_offset_to_irq = pmic_mpp_child_offset_to_irq;
    933	girq->child_irq_domain_ops.translate = pmic_mpp_domain_translate;
    934
    935	ret = gpiochip_add_data(&state->chip, state);
    936	if (ret) {
    937		dev_err(state->dev, "can't add gpio chip\n");
    938		return ret;
    939	}
    940
    941	ret = gpiochip_add_pin_range(&state->chip, dev_name(dev), 0, 0, npins);
    942	if (ret) {
    943		dev_err(dev, "failed to add pin range\n");
    944		goto err_range;
    945	}
    946
    947	return 0;
    948
    949err_range:
    950	gpiochip_remove(&state->chip);
    951	return ret;
    952}
    953
    954static int pmic_mpp_remove(struct platform_device *pdev)
    955{
    956	struct pmic_mpp_state *state = platform_get_drvdata(pdev);
    957
    958	gpiochip_remove(&state->chip);
    959	return 0;
    960}
    961
    962static const struct of_device_id pmic_mpp_of_match[] = {
    963	{ .compatible = "qcom,pm8019-mpp", .data = (void *) 6 },
    964	{ .compatible = "qcom,pm8226-mpp", .data = (void *) 8 },
    965	{ .compatible = "qcom,pm8841-mpp", .data = (void *) 4 },
    966	{ .compatible = "qcom,pm8916-mpp", .data = (void *) 4 },
    967	{ .compatible = "qcom,pm8941-mpp", .data = (void *) 8 },
    968	{ .compatible = "qcom,pm8950-mpp", .data = (void *) 4 },
    969	{ .compatible = "qcom,pmi8950-mpp", .data = (void *) 4 },
    970	{ .compatible = "qcom,pm8994-mpp", .data = (void *) 8 },
    971	{ .compatible = "qcom,pma8084-mpp", .data = (void *) 8 },
    972	{ .compatible = "qcom,pmi8994-mpp", .data = (void *) 4 },
    973	{ },
    974};
    975
    976MODULE_DEVICE_TABLE(of, pmic_mpp_of_match);
    977
    978static struct platform_driver pmic_mpp_driver = {
    979	.driver = {
    980		   .name = "qcom-spmi-mpp",
    981		   .of_match_table = pmic_mpp_of_match,
    982	},
    983	.probe	= pmic_mpp_probe,
    984	.remove = pmic_mpp_remove,
    985};
    986
    987module_platform_driver(pmic_mpp_driver);
    988
    989MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
    990MODULE_DESCRIPTION("Qualcomm SPMI PMIC MPP pin control driver");
    991MODULE_ALIAS("platform:qcom-spmi-mpp");
    992MODULE_LICENSE("GPL v2");