^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) * palmas-adc.c -- TI PALMAS GPADC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Pradeep Goudagunta <pgoudagunta@nvidia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_device.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/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mfd/palmas.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/iio/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/iio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define MOD_NAME "palmas-gpadc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define PALMAS_ADC_CONVERSION_TIMEOUT (msecs_to_jiffies(5000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define PALMAS_TO_BE_CALCULATED 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define PALMAS_GPADC_TRIMINVALID -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct palmas_gpadc_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* calibration codes and regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int x1; /* lower ideal code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int x2; /* higher ideal code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int v1; /* expected lower volt reading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int v2; /* expected higher volt reading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) u8 trim1_reg; /* register number for lower trim */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) u8 trim2_reg; /* register number for upper trim */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int gain; /* calculated from above (after reading trim regs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int offset; /* calculated from above (after reading trim regs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int gain_error; /* calculated from above (after reading trim regs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) bool is_uncalibrated; /* if channel has calibration data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PALMAS_ADC_INFO(_chan, _x1, _x2, _v1, _v2, _t1, _t2, _is_uncalibrated) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) [PALMAS_ADC_CH_##_chan] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .x1 = _x1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .x2 = _x2, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .v1 = _v1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .v2 = _v2, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .gain = PALMAS_TO_BE_CALCULATED, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .offset = PALMAS_TO_BE_CALCULATED, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .gain_error = PALMAS_TO_BE_CALCULATED, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .trim1_reg = PALMAS_GPADC_TRIM##_t1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .trim2_reg = PALMAS_GPADC_TRIM##_t2, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .is_uncalibrated = _is_uncalibrated \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static struct palmas_gpadc_info palmas_gpadc_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) PALMAS_ADC_INFO(IN0, 2064, 3112, 630, 950, 1, 2, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) PALMAS_ADC_INFO(IN1, 2064, 3112, 630, 950, 1, 2, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) PALMAS_ADC_INFO(IN2, 2064, 3112, 1260, 1900, 3, 4, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) PALMAS_ADC_INFO(IN3, 2064, 3112, 630, 950, 1, 2, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) PALMAS_ADC_INFO(IN4, 2064, 3112, 630, 950, 1, 2, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) PALMAS_ADC_INFO(IN5, 2064, 3112, 630, 950, 1, 2, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) PALMAS_ADC_INFO(IN6, 2064, 3112, 2520, 3800, 5, 6, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) PALMAS_ADC_INFO(IN7, 2064, 3112, 2520, 3800, 7, 8, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) PALMAS_ADC_INFO(IN8, 2064, 3112, 3150, 4750, 9, 10, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) PALMAS_ADC_INFO(IN9, 2064, 3112, 5670, 8550, 11, 12, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) PALMAS_ADC_INFO(IN10, 2064, 3112, 3465, 5225, 13, 14, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) PALMAS_ADC_INFO(IN11, 0, 0, 0, 0, INVALID, INVALID, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) PALMAS_ADC_INFO(IN12, 0, 0, 0, 0, INVALID, INVALID, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) PALMAS_ADC_INFO(IN13, 0, 0, 0, 0, INVALID, INVALID, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) PALMAS_ADC_INFO(IN14, 2064, 3112, 3645, 5225, 15, 16, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) PALMAS_ADC_INFO(IN15, 0, 0, 0, 0, INVALID, INVALID, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * struct palmas_gpadc - the palmas_gpadc structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @ch0_current: channel 0 current source setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * 0: 0 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * 1: 5 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * 2: 15 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * 3: 20 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * @ch3_current: channel 0 current source setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * 0: 0 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * 1: 10 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * 2: 400 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * 3: 800 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @extended_delay: enable the gpadc extended delay mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @auto_conversion_period: define the auto_conversion_period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * This is the palmas_gpadc structure to store run-time information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * and pointers for this driver instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct palmas_gpadc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct palmas *palmas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u8 ch0_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u8 ch3_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) bool extended_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int irq_auto_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int irq_auto_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct palmas_gpadc_info *adc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct completion conv_completion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct palmas_adc_wakeup_property wakeup1_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct palmas_adc_wakeup_property wakeup2_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) bool wakeup1_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) bool wakeup2_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int auto_conversion_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * GPADC lock issue in AUTO mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * Impact: In AUTO mode, GPADC conversion can be locked after disabling AUTO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * mode feature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * Details:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * When the AUTO mode is the only conversion mode enabled, if the AUTO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * mode feature is disabled with bit GPADC_AUTO_CTRL. AUTO_CONV1_EN = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * or bit GPADC_AUTO_CTRL. AUTO_CONV0_EN = 0 during a conversion, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * conversion mechanism can be seen as locked meaning that all following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * conversion will give 0 as a result. Bit GPADC_STATUS.GPADC_AVAILABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * will stay at 0 meaning that GPADC is busy. An RT conversion can unlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * the GPADC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * Workaround(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * To avoid the lock mechanism, the workaround to follow before any stop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * conversion request is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Force the GPADC state machine to be ON by using the GPADC_CTRL1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * GPADC_FORCE bit = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Shutdown the GPADC AUTO conversion using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * GPADC_AUTO_CTRL.SHUTDOWN_CONV[01] = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * After 100us, force the GPADC state machine to be OFF by using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * GPADC_CTRL1. GPADC_FORCE bit = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static int palmas_disable_auto_conversion(struct palmas_gpadc *adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) PALMAS_GPADC_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) PALMAS_GPADC_CTRL1_GPADC_FORCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) PALMAS_GPADC_CTRL1_GPADC_FORCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) PALMAS_GPADC_AUTO_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) dev_err(adc->dev, "AUTO_CTRL update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) PALMAS_GPADC_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) PALMAS_GPADC_CTRL1_GPADC_FORCE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static irqreturn_t palmas_gpadc_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct palmas_gpadc *adc = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) complete(&adc->conv_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static irqreturn_t palmas_gpadc_irq_auto(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct palmas_gpadc *adc = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) dev_dbg(adc->dev, "Threshold interrupt %d occurs\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) palmas_disable_auto_conversion(adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int palmas_gpadc_start_mask_interrupt(struct palmas_gpadc *adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) bool mask)
^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) if (!mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ret = palmas_update_bits(adc->palmas, PALMAS_INTERRUPT_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) PALMAS_INT3_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) PALMAS_INT3_MASK_GPADC_EOC_SW, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ret = palmas_update_bits(adc->palmas, PALMAS_INTERRUPT_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) PALMAS_INT3_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) PALMAS_INT3_MASK_GPADC_EOC_SW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) PALMAS_INT3_MASK_GPADC_EOC_SW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) dev_err(adc->dev, "GPADC INT MASK update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int palmas_gpadc_enable(struct palmas_gpadc *adc, int adc_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) unsigned int mask, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) val = (adc->extended_delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) << PALMAS_GPADC_RT_CTRL_EXTEND_DELAY_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) PALMAS_GPADC_RT_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) PALMAS_GPADC_RT_CTRL_EXTEND_DELAY, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) dev_err(adc->dev, "RT_CTRL update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) mask = (PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) PALMAS_GPADC_CTRL1_GPADC_FORCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) val = (adc->ch0_current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) << PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) val |= (adc->ch3_current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) << PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) val |= PALMAS_GPADC_CTRL1_GPADC_FORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) PALMAS_GPADC_CTRL1, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) "Failed to update current setting: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mask = (PALMAS_GPADC_SW_SELECT_SW_CONV0_SEL_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) PALMAS_GPADC_SW_SELECT_SW_CONV_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) val = (adc_chan | PALMAS_GPADC_SW_SELECT_SW_CONV_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) PALMAS_GPADC_SW_SELECT, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) dev_err(adc->dev, "SW_SELECT update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) PALMAS_GPADC_SW_SELECT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dev_err(adc->dev, "SW_SELECT write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) PALMAS_GPADC_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) PALMAS_GPADC_CTRL1_GPADC_FORCE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) dev_err(adc->dev, "CTRL1 update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int palmas_gpadc_read_prepare(struct palmas_gpadc *adc, int adc_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ret = palmas_gpadc_enable(adc, adc_chan, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return palmas_gpadc_start_mask_interrupt(adc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static void palmas_gpadc_read_done(struct palmas_gpadc *adc, int adc_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) palmas_gpadc_start_mask_interrupt(adc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) palmas_gpadc_enable(adc, adc_chan, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int palmas_gpadc_calibrate(struct palmas_gpadc *adc, int adc_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int d1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int d2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int x1 = adc->adc_info[adc_chan].x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int x2 = adc->adc_info[adc_chan].x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int v1 = adc->adc_info[adc_chan].v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) int v2 = adc->adc_info[adc_chan].v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ret = palmas_read(adc->palmas, PALMAS_TRIM_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) adc->adc_info[adc_chan].trim1_reg, &d1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dev_err(adc->dev, "TRIM read failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) goto scrub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ret = palmas_read(adc->palmas, PALMAS_TRIM_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) adc->adc_info[adc_chan].trim2_reg, &d2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) dev_err(adc->dev, "TRIM read failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) goto scrub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* gain error calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) k = (1000 + (1000 * (d2 - d1)) / (x2 - x1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* gain calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) gain = ((v2 - v1) * 1000) / (x2 - x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) adc->adc_info[adc_chan].gain_error = k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) adc->adc_info[adc_chan].gain = gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* offset Calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) adc->adc_info[adc_chan].offset = (d1 * 1000) - ((k - 1000) * x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) scrub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static int palmas_gpadc_start_conversion(struct palmas_gpadc *adc, int adc_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) init_completion(&adc->conv_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) PALMAS_GPADC_SW_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) PALMAS_GPADC_SW_SELECT_SW_START_CONV0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) PALMAS_GPADC_SW_SELECT_SW_START_CONV0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) dev_err(adc->dev, "SELECT_SW_START write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ret = wait_for_completion_timeout(&adc->conv_completion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) PALMAS_ADC_CONVERSION_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) dev_err(adc->dev, "conversion not completed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ret = palmas_bulk_read(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) PALMAS_GPADC_SW_CONV0_LSB, &val, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) dev_err(adc->dev, "SW_CONV0_LSB read failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ret = val & 0xFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static int palmas_gpadc_get_calibrated_code(struct palmas_gpadc *adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int adc_chan, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (!adc->adc_info[adc_chan].is_uncalibrated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) val = (val*1000 - adc->adc_info[adc_chan].offset) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) adc->adc_info[adc_chan].gain_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) dev_err(adc->dev, "Mismatch with calibration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) val = (val * adc->adc_info[adc_chan].gain) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int palmas_gpadc_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct iio_chan_spec const *chan, int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct palmas_gpadc *adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int adc_chan = chan->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (adc_chan > PALMAS_ADC_CH_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) mutex_lock(&indio_dev->mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) case IIO_CHAN_INFO_PROCESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = palmas_gpadc_read_prepare(adc, adc_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ret = palmas_gpadc_start_conversion(adc, adc_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) "ADC start conversion failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (mask == IIO_CHAN_INFO_PROCESSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ret = palmas_gpadc_get_calibrated_code(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) adc, adc_chan, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) mutex_unlock(&indio_dev->mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) palmas_gpadc_read_done(adc, adc_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) mutex_unlock(&indio_dev->mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return ret;
^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 iio_info palmas_gpadc_iio_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .read_raw = palmas_gpadc_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) #define PALMAS_ADC_CHAN_IIO(chan, _type, chan_info) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .datasheet_name = PALMAS_DATASHEET_NAME(chan), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .type = _type, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) BIT(chan_info), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .indexed = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .channel = PALMAS_ADC_CH_##chan, \
^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 const struct iio_chan_spec palmas_gpadc_iio_channel[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) PALMAS_ADC_CHAN_IIO(IN0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) PALMAS_ADC_CHAN_IIO(IN1, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) PALMAS_ADC_CHAN_IIO(IN2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) PALMAS_ADC_CHAN_IIO(IN3, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) PALMAS_ADC_CHAN_IIO(IN4, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) PALMAS_ADC_CHAN_IIO(IN5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) PALMAS_ADC_CHAN_IIO(IN6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) PALMAS_ADC_CHAN_IIO(IN7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) PALMAS_ADC_CHAN_IIO(IN8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) PALMAS_ADC_CHAN_IIO(IN9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) PALMAS_ADC_CHAN_IIO(IN10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) PALMAS_ADC_CHAN_IIO(IN11, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) PALMAS_ADC_CHAN_IIO(IN12, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) PALMAS_ADC_CHAN_IIO(IN13, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) PALMAS_ADC_CHAN_IIO(IN14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) PALMAS_ADC_CHAN_IIO(IN15, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static int palmas_gpadc_get_adc_dt_data(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct palmas_gpadc_platform_data **gpadc_pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct palmas_gpadc_platform_data *gp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) u32 pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) gp_data = devm_kzalloc(&pdev->dev, sizeof(*gp_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (!gp_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ret = of_property_read_u32(np, "ti,channel0-current-microamp", &pval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) gp_data->ch0_current = pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ret = of_property_read_u32(np, "ti,channel3-current-microamp", &pval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) gp_data->ch3_current = pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) gp_data->extended_delay = of_property_read_bool(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) "ti,enable-extended-delay");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) *gpadc_pdata = gp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static int palmas_gpadc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct palmas_gpadc *adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct palmas_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct palmas_gpadc_platform_data *gpadc_pdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) pdata = dev_get_platdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (pdata && pdata->gpadc_pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) gpadc_pdata = pdata->gpadc_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (!gpadc_pdata && pdev->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ret = palmas_gpadc_get_adc_dt_data(pdev, &gpadc_pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (ret < 0)
^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) if (!gpadc_pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (!indio_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) dev_err(&pdev->dev, "iio_device_alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) adc->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) adc->palmas = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) adc->adc_info = palmas_gpadc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) init_completion(&adc->conv_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) dev_set_drvdata(&pdev->dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) adc->auto_conversion_period = gpadc_pdata->auto_conversion_period_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) adc->irq = palmas_irq_get_virq(adc->palmas, PALMAS_GPADC_EOC_SW_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (adc->irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) "get virq failed: %d\n", adc->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ret = adc->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ret = request_threaded_irq(adc->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) palmas_gpadc_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) IRQF_ONESHOT, dev_name(adc->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) "request irq %d failed: %d\n", adc->irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (gpadc_pdata->adc_wakeup1_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) memcpy(&adc->wakeup1_data, gpadc_pdata->adc_wakeup1_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) sizeof(adc->wakeup1_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) adc->wakeup1_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) adc->irq_auto_0 = platform_get_irq(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ret = request_threaded_irq(adc->irq_auto_0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) palmas_gpadc_irq_auto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) "palmas-adc-auto-0", adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) dev_err(adc->dev, "request auto0 irq %d failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) adc->irq_auto_0, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) goto out_irq_free;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (gpadc_pdata->adc_wakeup2_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) memcpy(&adc->wakeup2_data, gpadc_pdata->adc_wakeup2_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) sizeof(adc->wakeup2_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) adc->wakeup2_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) adc->irq_auto_1 = platform_get_irq(pdev, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) ret = request_threaded_irq(adc->irq_auto_1, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) palmas_gpadc_irq_auto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) "palmas-adc-auto-1", adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) dev_err(adc->dev, "request auto1 irq %d failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) adc->irq_auto_1, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) goto out_irq_auto0_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^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) /* set the current source 0 (value 0/5/15/20 uA => 0..3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (gpadc_pdata->ch0_current <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) else if (gpadc_pdata->ch0_current <= 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) else if (gpadc_pdata->ch0_current <= 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* set the current source 3 (value 0/10/400/800 uA => 0..3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (gpadc_pdata->ch3_current <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) else if (gpadc_pdata->ch3_current <= 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) else if (gpadc_pdata->ch3_current <= 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) adc->extended_delay = gpadc_pdata->extended_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) indio_dev->name = MOD_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) indio_dev->info = &palmas_gpadc_iio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) indio_dev->channels = palmas_gpadc_iio_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) indio_dev->num_channels = ARRAY_SIZE(palmas_gpadc_iio_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) dev_err(adc->dev, "iio_device_register() failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) goto out_irq_auto1_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) device_set_wakeup_capable(&pdev->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) for (i = 0; i < PALMAS_ADC_CH_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (!(adc->adc_info[i].is_uncalibrated))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) palmas_gpadc_calibrate(adc, i);
^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) if (adc->wakeup1_enable || adc->wakeup2_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) device_wakeup_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) out_irq_auto1_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (gpadc_pdata->adc_wakeup2_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) free_irq(adc->irq_auto_1, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) out_irq_auto0_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (gpadc_pdata->adc_wakeup1_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) free_irq(adc->irq_auto_0, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) out_irq_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) free_irq(adc->irq, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static int palmas_gpadc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct palmas_gpadc *adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (adc->wakeup1_enable || adc->wakeup2_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) device_wakeup_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) free_irq(adc->irq, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (adc->wakeup1_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) free_irq(adc->irq_auto_0, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (adc->wakeup2_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) free_irq(adc->irq_auto_1, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return 0;
^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) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static int palmas_adc_wakeup_configure(struct palmas_gpadc *adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) int adc_period, conv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) int ch0 = 0, ch1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) int thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) adc_period = adc->auto_conversion_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) for (i = 0; i < 16; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (((1000 * (1 << i)) / 32) >= adc_period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (i > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) adc_period = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) PALMAS_GPADC_AUTO_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) PALMAS_GPADC_AUTO_CTRL_COUNTER_CONV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) adc_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) conv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (adc->wakeup1_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int polarity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ch0 = adc->wakeup1_data.adc_channel_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) conv |= PALMAS_GPADC_AUTO_CTRL_AUTO_CONV0_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (adc->wakeup1_data.adc_high_threshold > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) thres = adc->wakeup1_data.adc_high_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) polarity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) thres = adc->wakeup1_data.adc_low_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) polarity = PALMAS_GPADC_THRES_CONV0_MSB_THRES_CONV0_POL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) PALMAS_GPADC_THRES_CONV0_LSB, thres & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) "THRES_CONV0_LSB write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) PALMAS_GPADC_THRES_CONV0_MSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) ((thres >> 8) & 0xF) | polarity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) "THRES_CONV0_MSB write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (adc->wakeup2_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) int polarity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) ch1 = adc->wakeup2_data.adc_channel_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) conv |= PALMAS_GPADC_AUTO_CTRL_AUTO_CONV1_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (adc->wakeup2_data.adc_high_threshold > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) thres = adc->wakeup2_data.adc_high_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) polarity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) thres = adc->wakeup2_data.adc_low_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) polarity = PALMAS_GPADC_THRES_CONV1_MSB_THRES_CONV1_POL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) PALMAS_GPADC_THRES_CONV1_LSB, thres & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) "THRES_CONV1_LSB write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) PALMAS_GPADC_THRES_CONV1_MSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) ((thres >> 8) & 0xF) | polarity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) "THRES_CONV1_MSB write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^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) ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) PALMAS_GPADC_AUTO_SELECT, (ch1 << 4) | ch0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) dev_err(adc->dev, "AUTO_SELECT write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) PALMAS_GPADC_AUTO_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) PALMAS_GPADC_AUTO_CTRL_AUTO_CONV1_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) PALMAS_GPADC_AUTO_CTRL_AUTO_CONV0_EN, conv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static int palmas_adc_wakeup_reset(struct palmas_gpadc *adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) PALMAS_GPADC_AUTO_SELECT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) dev_err(adc->dev, "AUTO_SELECT write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) ret = palmas_disable_auto_conversion(adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) dev_err(adc->dev, "Disable auto conversion failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static int palmas_gpadc_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct palmas_gpadc *adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) int wakeup = adc->wakeup1_enable || adc->wakeup2_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (!device_may_wakeup(dev) || !wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) ret = palmas_adc_wakeup_configure(adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (adc->wakeup1_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) enable_irq_wake(adc->irq_auto_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (adc->wakeup2_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) enable_irq_wake(adc->irq_auto_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static int palmas_gpadc_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct palmas_gpadc *adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) int wakeup = adc->wakeup1_enable || adc->wakeup2_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (!device_may_wakeup(dev) || !wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ret = palmas_adc_wakeup_reset(adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (adc->wakeup1_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) disable_irq_wake(adc->irq_auto_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (adc->wakeup2_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) disable_irq_wake(adc->irq_auto_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static const struct dev_pm_ops palmas_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) SET_SYSTEM_SLEEP_PM_OPS(palmas_gpadc_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) palmas_gpadc_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static const struct of_device_id of_palmas_gpadc_match_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) { .compatible = "ti,palmas-gpadc", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) { /* end */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) MODULE_DEVICE_TABLE(of, of_palmas_gpadc_match_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static struct platform_driver palmas_gpadc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) .probe = palmas_gpadc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .remove = palmas_gpadc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) .name = MOD_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) .pm = &palmas_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) .of_match_table = of_palmas_gpadc_match_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) module_platform_driver(palmas_gpadc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) MODULE_DESCRIPTION("palmas GPADC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) MODULE_AUTHOR("Pradeep Goudagunta<pgoudagunta@nvidia.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) MODULE_ALIAS("platform:palmas-gpadc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) MODULE_LICENSE("GPL v2");