^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) 2015, Sony Mobile Communications AB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2013, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^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/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/pinctrl/pinmux.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/pinconf-generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.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/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "../core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "../pinctrl-utils.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* MPP registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define SSBI_REG_ADDR_MPP_BASE 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SSBI_REG_ADDR_MPP(n) (SSBI_REG_ADDR_MPP_BASE + n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* MPP Type: type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define PM8XXX_MPP_TYPE_D_INPUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define PM8XXX_MPP_TYPE_D_OUTPUT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PM8XXX_MPP_TYPE_D_BI_DIR 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define PM8XXX_MPP_TYPE_A_INPUT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define PM8XXX_MPP_TYPE_A_OUTPUT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PM8XXX_MPP_TYPE_SINK 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PM8XXX_MPP_TYPE_DTEST_SINK 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PM8XXX_MPP_TYPE_DTEST_OUTPUT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* Digital Input: control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PM8XXX_MPP_DIN_TO_INT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define PM8XXX_MPP_DIN_TO_DBUS1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define PM8XXX_MPP_DIN_TO_DBUS2 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define PM8XXX_MPP_DIN_TO_DBUS3 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Digital Output: control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PM8XXX_MPP_DOUT_CTRL_LOW 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define PM8XXX_MPP_DOUT_CTRL_HIGH 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define PM8XXX_MPP_DOUT_CTRL_MPP 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define PM8XXX_MPP_DOUT_CTRL_INV_MPP 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* Bidirectional: control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define PM8XXX_MPP_BI_PULLUP_1KOHM 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PM8XXX_MPP_BI_PULLUP_OPEN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PM8XXX_MPP_BI_PULLUP_10KOHM 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define PM8XXX_MPP_BI_PULLUP_30KOHM 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Analog Output: control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define PM8XXX_MPP_AOUT_CTRL_DISABLE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define PM8XXX_MPP_AOUT_CTRL_ENABLE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define PM8XXX_MPP_AOUT_CTRL_MPP_HIGH_EN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define PM8XXX_MPP_AOUT_CTRL_MPP_LOW_EN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Current Sink: control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define PM8XXX_MPP_CS_CTRL_DISABLE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define PM8XXX_MPP_CS_CTRL_ENABLE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define PM8XXX_MPP_CS_CTRL_MPP_HIGH_EN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define PM8XXX_MPP_CS_CTRL_MPP_LOW_EN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* DTEST Current Sink: control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define PM8XXX_MPP_DTEST_CS_CTRL_EN1 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define PM8XXX_MPP_DTEST_CS_CTRL_EN2 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define PM8XXX_MPP_DTEST_CS_CTRL_EN3 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define PM8XXX_MPP_DTEST_CS_CTRL_EN4 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* DTEST Digital Output: control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define PM8XXX_MPP_DTEST_DBUS1 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define PM8XXX_MPP_DTEST_DBUS2 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define PM8XXX_MPP_DTEST_DBUS3 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define PM8XXX_MPP_DTEST_DBUS4 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* custom pinconf parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define PM8XXX_CONFIG_AMUX (PIN_CONFIG_END + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define PM8XXX_CONFIG_DTEST_SELECTOR (PIN_CONFIG_END + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define PM8XXX_CONFIG_ALEVEL (PIN_CONFIG_END + 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define PM8XXX_CONFIG_PAIRED (PIN_CONFIG_END + 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * struct pm8xxx_pin_data - dynamic configuration for a pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @reg: address of the control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @irq: IRQ from the PMIC interrupt controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @mode: operating mode for the pin (digital, analog or current sink)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @input: pin is input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * @output: pin is output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * @high_z: pin is floating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * @paired: mpp operates in paired mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * @output_value: logical output value of the mpp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * @power_source: selected power source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @dtest: DTEST route selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @amux: input muxing in analog mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @aout_level: selector of the output in analog mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @drive_strength: drive strength of the current sink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @pullup: pull up value, when in digital bidirectional mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct pm8xxx_pin_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) unsigned reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) bool input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) bool output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) bool high_z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) bool paired;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) bool output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u8 power_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u8 dtest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u8 amux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u8 aout_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u8 drive_strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned pullup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct pm8xxx_mpp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct pinctrl_dev *pctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct gpio_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct pinctrl_desc desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static const struct pinconf_generic_params pm8xxx_mpp_bindings[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {"qcom,amux-route", PM8XXX_CONFIG_AMUX, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {"qcom,analog-level", PM8XXX_CONFIG_ALEVEL, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {"qcom,dtest", PM8XXX_CONFIG_DTEST_SELECTOR, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {"qcom,paired", PM8XXX_CONFIG_PAIRED, 0},
^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) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static const struct pin_config_item pm8xxx_conf_items[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) PCONFDUMP(PM8XXX_CONFIG_AMUX, "analog mux", NULL, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) PCONFDUMP(PM8XXX_CONFIG_ALEVEL, "analog level", NULL, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) PCONFDUMP(PM8XXX_CONFIG_DTEST_SELECTOR, "dtest", NULL, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) PCONFDUMP(PM8XXX_CONFIG_PAIRED, "paired", NULL, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define PM8XXX_MAX_MPPS 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static const char * const pm8xxx_groups[PM8XXX_MAX_MPPS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) "mpp1", "mpp2", "mpp3", "mpp4", "mpp5", "mpp6", "mpp7", "mpp8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) "mpp9", "mpp10", "mpp11", "mpp12",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define PM8XXX_MPP_DIGITAL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define PM8XXX_MPP_ANALOG 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define PM8XXX_MPP_SINK 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static const char * const pm8xxx_mpp_functions[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) "digital", "analog", "sink",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static int pm8xxx_mpp_update(struct pm8xxx_mpp *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct pm8xxx_pin_data *pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsigned level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) switch (pin->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) case PM8XXX_MPP_DIGITAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (pin->dtest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) type = PM8XXX_MPP_TYPE_DTEST_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ctrl = pin->dtest - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) } else if (pin->input && pin->output) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) type = PM8XXX_MPP_TYPE_D_BI_DIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (pin->high_z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ctrl = PM8XXX_MPP_BI_PULLUP_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) else if (pin->pullup == 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ctrl = PM8XXX_MPP_BI_PULLUP_1KOHM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) else if (pin->pullup == 10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ctrl = PM8XXX_MPP_BI_PULLUP_10KOHM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ctrl = PM8XXX_MPP_BI_PULLUP_30KOHM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) } else if (pin->input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) type = PM8XXX_MPP_TYPE_D_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (pin->dtest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ctrl = pin->dtest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ctrl = PM8XXX_MPP_DIN_TO_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) type = PM8XXX_MPP_TYPE_D_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ctrl = !!pin->output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (pin->paired)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ctrl |= BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) level = pin->power_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) case PM8XXX_MPP_ANALOG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (pin->output) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) type = PM8XXX_MPP_TYPE_A_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) level = pin->aout_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ctrl = pin->output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (pin->paired)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ctrl |= BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) type = PM8XXX_MPP_TYPE_A_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) level = pin->amux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) case PM8XXX_MPP_SINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) level = (pin->drive_strength / 5) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (pin->dtest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) type = PM8XXX_MPP_TYPE_DTEST_SINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ctrl = pin->dtest - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) type = PM8XXX_MPP_TYPE_SINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ctrl = pin->output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (pin->paired)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ctrl |= BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) val = type << 5 | level << 2 | ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ret = regmap_write(pctrl->regmap, pin->reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dev_err(pctrl->dev, "failed to write register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int pm8xxx_get_groups_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct pm8xxx_mpp *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return pctrl->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static const char *pm8xxx_get_group_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return pm8xxx_groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^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 pm8xxx_get_group_pins(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) unsigned group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) const unsigned **pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) unsigned *num_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct pm8xxx_mpp *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *pins = &pctrl->desc.pins[group].number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) *num_pins = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static const struct pinctrl_ops pm8xxx_pinctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .get_groups_count = pm8xxx_get_groups_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .get_group_name = pm8xxx_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .get_group_pins = pm8xxx_get_group_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .dt_free_map = pinctrl_utils_free_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int pm8xxx_get_functions_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return ARRAY_SIZE(pm8xxx_mpp_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static const char *pm8xxx_get_function_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) unsigned function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return pm8xxx_mpp_functions[function];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int pm8xxx_get_function_groups(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) const char * const **groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) unsigned * const num_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct pm8xxx_mpp *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *groups = pm8xxx_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *num_groups = pctrl->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int pm8xxx_pinmux_set_mux(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct pm8xxx_mpp *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct pm8xxx_pin_data *pin = pctrl->desc.pins[group].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) pin->mode = function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) pm8xxx_mpp_update(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static const struct pinmux_ops pm8xxx_pinmux_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .get_functions_count = pm8xxx_get_functions_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .get_function_name = pm8xxx_get_function_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .get_function_groups = pm8xxx_get_function_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .set_mux = pm8xxx_pinmux_set_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static int pm8xxx_pin_config_get(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct pm8xxx_mpp *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned param = pinconf_to_config_param(*config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsigned arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) arg = pin->pullup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) arg = pin->high_z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case PIN_CONFIG_INPUT_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) arg = pin->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) case PIN_CONFIG_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) arg = pin->output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) case PIN_CONFIG_POWER_SOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) arg = pin->power_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) case PIN_CONFIG_DRIVE_STRENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) arg = pin->drive_strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) case PM8XXX_CONFIG_DTEST_SELECTOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) arg = pin->dtest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case PM8XXX_CONFIG_AMUX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) arg = pin->amux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) case PM8XXX_CONFIG_ALEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) arg = pin->aout_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case PM8XXX_CONFIG_PAIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) arg = pin->paired;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) *config = pinconf_to_config_packed(param, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static int pm8xxx_pin_config_set(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) unsigned long *configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) unsigned num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct pm8xxx_mpp *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) unsigned param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) for (i = 0; i < num_configs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) param = pinconf_to_config_param(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) arg = pinconf_to_config_argument(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) pin->pullup = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) pin->high_z = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) case PIN_CONFIG_INPUT_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) pin->input = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) case PIN_CONFIG_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) pin->output = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) pin->output_value = !!arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) case PIN_CONFIG_POWER_SOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) pin->power_source = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) case PIN_CONFIG_DRIVE_STRENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) pin->drive_strength = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) case PM8XXX_CONFIG_DTEST_SELECTOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) pin->dtest = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) case PM8XXX_CONFIG_AMUX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) pin->amux = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) case PM8XXX_CONFIG_ALEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) pin->aout_level = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) case PM8XXX_CONFIG_PAIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) pin->paired = !!arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) dev_err(pctrl->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) "unsupported config parameter: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) pm8xxx_mpp_update(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static const struct pinconf_ops pm8xxx_pinconf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .is_generic = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .pin_config_group_get = pm8xxx_pin_config_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .pin_config_group_set = pm8xxx_pin_config_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static const struct pinctrl_desc pm8xxx_pinctrl_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .name = "pm8xxx_mpp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .pctlops = &pm8xxx_pinctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .pmxops = &pm8xxx_pinmux_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .confops = &pm8xxx_pinconf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static int pm8xxx_mpp_direction_input(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct pm8xxx_mpp *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) switch (pin->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) case PM8XXX_MPP_DIGITAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) pin->input = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) case PM8XXX_MPP_ANALOG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) pin->input = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) pin->output = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) case PM8XXX_MPP_SINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) pm8xxx_mpp_update(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static int pm8xxx_mpp_direction_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) unsigned offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct pm8xxx_mpp *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) switch (pin->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) case PM8XXX_MPP_DIGITAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) pin->output = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) case PM8XXX_MPP_ANALOG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) pin->input = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) pin->output = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) case PM8XXX_MPP_SINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) pin->input = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pin->output = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) pm8xxx_mpp_update(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return 0;
^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) static int pm8xxx_mpp_get(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct pm8xxx_mpp *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) bool state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (!pin->input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return !!pin->output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret = irq_get_irqchip_state(pin->irq, IRQCHIP_STATE_LINE_LEVEL, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ret = !!state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static void pm8xxx_mpp_set(struct gpio_chip *chip, unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct pm8xxx_mpp *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) pin->output_value = !!value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) pm8xxx_mpp_update(pctrl, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static int pm8xxx_mpp_of_xlate(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) const struct of_phandle_args *gpio_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) u32 *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (chip->of_gpio_n_cells < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) *flags = gpio_desc->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return gpio_desc->args[0] - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int pm8xxx_mpp_to_irq(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct pm8xxx_mpp *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return pin->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static void pm8xxx_mpp_dbg_show_one(struct seq_file *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) unsigned offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) unsigned gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct pm8xxx_mpp *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static const char * const aout_lvls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) "1v25", "1v25_2", "0v625", "0v3125", "mpp", "abus1", "abus2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) "abus3"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static const char * const amuxs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) "amux5", "amux6", "amux7", "amux8", "amux9", "abus1", "abus2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) "abus3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) seq_printf(s, " mpp%-2d:", offset + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) switch (pin->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) case PM8XXX_MPP_DIGITAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) seq_puts(s, " digital ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (pin->dtest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) seq_printf(s, "dtest%d\n", pin->dtest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) } else if (pin->input && pin->output) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (pin->high_z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) seq_puts(s, "bi-dir high-z");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) seq_printf(s, "bi-dir %dOhm", pin->pullup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) } else if (pin->input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (pin->dtest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) seq_printf(s, "in dtest%d", pin->dtest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) seq_puts(s, "in gpio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) } else if (pin->output) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) seq_puts(s, "out ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (!pin->paired) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) seq_puts(s, pin->output_value ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) "high" : "low");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) seq_puts(s, pin->output_value ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) "inverted" : "follow");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) case PM8XXX_MPP_ANALOG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) seq_puts(s, " analog ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (pin->output) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) seq_printf(s, "out %s ", aout_lvls[pin->aout_level]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (!pin->paired) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) seq_puts(s, pin->output_value ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) "high" : "low");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) seq_puts(s, pin->output_value ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) "inverted" : "follow");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) seq_printf(s, "input mux %s", amuxs[pin->amux]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) case PM8XXX_MPP_SINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) seq_printf(s, " sink %dmA ", pin->drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (pin->dtest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) seq_printf(s, "dtest%d", pin->dtest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!pin->paired) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) seq_puts(s, pin->output_value ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) "high" : "low");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) seq_puts(s, pin->output_value ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) "inverted" : "follow");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static void pm8xxx_mpp_dbg_show(struct seq_file *s, struct gpio_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) unsigned gpio = chip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) for (i = 0; i < chip->ngpio; i++, gpio++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) pm8xxx_mpp_dbg_show_one(s, NULL, chip, i, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) seq_puts(s, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) #define pm8xxx_mpp_dbg_show NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static const struct gpio_chip pm8xxx_mpp_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .direction_input = pm8xxx_mpp_direction_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .direction_output = pm8xxx_mpp_direction_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) .get = pm8xxx_mpp_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .set = pm8xxx_mpp_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .of_xlate = pm8xxx_mpp_of_xlate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .to_irq = pm8xxx_mpp_to_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .dbg_show = pm8xxx_mpp_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static int pm8xxx_pin_populate(struct pm8xxx_mpp *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct pm8xxx_pin_data *pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) unsigned level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) unsigned ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) unsigned type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ret = regmap_read(pctrl->regmap, pin->reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) dev_err(pctrl->dev, "failed to read register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) type = (val >> 5) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) level = (val >> 2) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ctrl = (val) & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) case PM8XXX_MPP_TYPE_D_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) pin->mode = PM8XXX_MPP_DIGITAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) pin->input = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) pin->power_source = level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) pin->dtest = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) case PM8XXX_MPP_TYPE_D_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) pin->mode = PM8XXX_MPP_DIGITAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) pin->output = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) pin->power_source = level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) pin->output_value = !!(ctrl & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) pin->paired = !!(ctrl & BIT(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) case PM8XXX_MPP_TYPE_D_BI_DIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) pin->mode = PM8XXX_MPP_DIGITAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) pin->input = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) pin->output = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) pin->power_source = level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) switch (ctrl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) case PM8XXX_MPP_BI_PULLUP_1KOHM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) pin->pullup = 600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) case PM8XXX_MPP_BI_PULLUP_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) pin->high_z = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) case PM8XXX_MPP_BI_PULLUP_10KOHM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) pin->pullup = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) case PM8XXX_MPP_BI_PULLUP_30KOHM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) pin->pullup = 30000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) case PM8XXX_MPP_TYPE_A_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) pin->mode = PM8XXX_MPP_ANALOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) pin->input = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) pin->amux = level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) case PM8XXX_MPP_TYPE_A_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) pin->mode = PM8XXX_MPP_ANALOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) pin->output = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) pin->aout_level = level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) pin->output_value = !!(ctrl & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) pin->paired = !!(ctrl & BIT(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) case PM8XXX_MPP_TYPE_SINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) pin->mode = PM8XXX_MPP_SINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) pin->drive_strength = 5 * (level + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) pin->output_value = !!(ctrl & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) pin->paired = !!(ctrl & BIT(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) case PM8XXX_MPP_TYPE_DTEST_SINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) pin->mode = PM8XXX_MPP_SINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) pin->dtest = ctrl + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) pin->drive_strength = 5 * (level + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) case PM8XXX_MPP_TYPE_DTEST_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) pin->mode = PM8XXX_MPP_DIGITAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) pin->power_source = level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (ctrl >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) pin->dtest = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static const struct of_device_id pm8xxx_mpp_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) { .compatible = "qcom,pm8018-mpp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) { .compatible = "qcom,pm8038-mpp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) { .compatible = "qcom,pm8058-mpp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) { .compatible = "qcom,pm8917-mpp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) { .compatible = "qcom,pm8821-mpp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) { .compatible = "qcom,pm8921-mpp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) { .compatible = "qcom,ssbi-mpp" },
^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) MODULE_DEVICE_TABLE(of, pm8xxx_mpp_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) static int pm8xxx_mpp_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct pm8xxx_pin_data *pin_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct pinctrl_pin_desc *pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct pm8xxx_mpp *pctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) int i, npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (!pctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) pctrl->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) npins = platform_irq_count(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (!npins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (npins < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) pctrl->npins = npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (!pctrl->regmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) dev_err(&pdev->dev, "parent regmap unavailable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) pctrl->desc = pm8xxx_pinctrl_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) pctrl->desc.npins = pctrl->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) pins = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) pctrl->desc.npins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) sizeof(struct pinctrl_pin_desc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (!pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) pin_data = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) pctrl->desc.npins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) sizeof(struct pm8xxx_pin_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (!pin_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) for (i = 0; i < pctrl->desc.npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) pin_data[i].reg = SSBI_REG_ADDR_MPP(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) pin_data[i].irq = platform_get_irq(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (pin_data[i].irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return pin_data[i].irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) ret = pm8xxx_pin_populate(pctrl, &pin_data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) pins[i].number = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) pins[i].name = pm8xxx_groups[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) pins[i].drv_data = &pin_data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) pctrl->desc.pins = pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) pctrl->desc.num_custom_params = ARRAY_SIZE(pm8xxx_mpp_bindings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) pctrl->desc.custom_params = pm8xxx_mpp_bindings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) pctrl->desc.custom_conf_items = pm8xxx_conf_items;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &pctrl->desc, pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (IS_ERR(pctrl->pctrl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) dev_err(&pdev->dev, "couldn't register pm8xxx mpp driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return PTR_ERR(pctrl->pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) pctrl->chip = pm8xxx_mpp_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) pctrl->chip.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) pctrl->chip.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) pctrl->chip.of_node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) pctrl->chip.of_gpio_n_cells = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) pctrl->chip.label = dev_name(pctrl->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) pctrl->chip.ngpio = pctrl->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) ret = gpiochip_add_data(&pctrl->chip, pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) dev_err(&pdev->dev, "failed register gpiochip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) ret = gpiochip_add_pin_range(&pctrl->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) dev_name(pctrl->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 0, 0, pctrl->chip.ngpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) dev_err(pctrl->dev, "failed to add pin range\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) goto unregister_gpiochip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) platform_set_drvdata(pdev, pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) dev_dbg(&pdev->dev, "Qualcomm pm8xxx mpp driver probed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) unregister_gpiochip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) gpiochip_remove(&pctrl->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) static int pm8xxx_mpp_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct pm8xxx_mpp *pctrl = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) gpiochip_remove(&pctrl->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) static struct platform_driver pm8xxx_mpp_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) .name = "qcom-ssbi-mpp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) .of_match_table = pm8xxx_mpp_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) .probe = pm8xxx_mpp_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) .remove = pm8xxx_mpp_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) module_platform_driver(pm8xxx_mpp_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) MODULE_DESCRIPTION("Qualcomm PM8xxx MPP driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) MODULE_LICENSE("GPL v2");