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