From 0d427cfc41fac70577e0802ac8fda10307ad846a Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Tue, 14 Dec 2021 11:39:54 -0800 Subject: [PATCH 01/17] iio: adc: qcom-spmi-adc5-gen3: Add support for qcom,debug-base Currently, the debug base address is defined under the reg property. This would be confusing if multiple addresses are specified under reg property to support more ADC channels. Separate debug base into its own property. Change-Id: Id96621bafd85bde0e601a89849aef7f094f53bf9 Signed-off-by: Anjelique Melendez --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index 6418373578c1..1786a5cd898a 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -1628,7 +1628,6 @@ static int adc5_gen3_probe(struct platform_device *pdev) struct adc5_chip *adc; struct regmap *regmap; const char *irq_name; - const __be32 *prop_addr; int ret, irq_eoc, i; u32 reg; @@ -1639,6 +1638,10 @@ static int adc5_gen3_probe(struct platform_device *pdev) ret = of_property_read_u32(node, "reg", ®); if (ret < 0) return ret; + adc->base = reg; + + if (!of_property_read_u32(node, "qcom,debug-base", ®)) + adc->debug_base = reg; indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); if (!indio_dev) @@ -1648,19 +1651,6 @@ static int adc5_gen3_probe(struct platform_device *pdev) adc->regmap = regmap; adc->dev = dev; - prop_addr = of_get_address(dev->of_node, 0, NULL, NULL); - if (!prop_addr) { - pr_err("invalid IO resource\n"); - return -EINVAL; - } - adc->base = be32_to_cpu(*prop_addr); - - prop_addr = of_get_address(dev->of_node, 1, NULL, NULL); - if (!prop_addr) - pr_debug("invalid debug resource\n"); - else - adc->debug_base = be32_to_cpu(*prop_addr); - platform_set_drvdata(pdev, adc); indio_dev->info = &adc5_gen3_info; From ef18fb11e35aee50bb4e0ab245e1aa93393680ff Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Tue, 14 Dec 2021 12:13:34 -0800 Subject: [PATCH 02/17] iio: adc: qcom-spmi-adc5-gen3: Update max channels Currently, ADC5 GEN3 driver allows up to 8 channels. In Kalama up to 16 channels can be configured over 2 SDAMs. Dynamically set max_channels based on number of registers(SDAMs) specified. Change-Id: I789b142306dfb0099d955f9e166c17b331a47517 Signed-off-by: Anjelique Melendez --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 34 ++++++++++++++++----------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index 1786a5cd898a..64db5839b6f4 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -114,8 +114,6 @@ static LIST_HEAD(adc_tm_device_list); #define ADC_TM5_GEN3_LOWER_MASK(n) ((n) & GENMASK(7, 0)) #define ADC_TM5_GEN3_UPPER_MASK(n) (((n) & GENMASK(15, 8)) >> 8) -#define ADC_TM5_GEN3_CHANS_MAX 7 - enum adc5_cal_method { ADC5_NO_CAL = 0, ADC5_RATIOMETRIC_CAL, @@ -217,6 +215,7 @@ struct adc5_channel_prop { * @base: base address for the ADC peripheral. * @debug_base: base address for the reserved ADC peripheral, * to dump for debug purposes alone. + * @max_channels: max amount of channels for the ADC peripheral. * @nchannels: number of ADC channels. * @chan_props: array of ADC channel properties. * @iio_chans: array of IIO channels specification. @@ -233,6 +232,7 @@ struct adc5_chip { struct device *dev; u16 base; u16 debug_base; + unsigned int max_channels; unsigned int nchannels; struct adc5_channel_prop *chan_props; struct iio_chan_spec *iio_chans; @@ -1510,9 +1510,9 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc, if (prop->adc_tm && prop->adc_tm != ADC_TM_IIO) { adc->n_tm_channels++; - if (adc->n_tm_channels > ADC_TM5_GEN3_CHANS_MAX) { - pr_err("Number of TM nodes greater than channels supported:%d\n", - adc->n_tm_channels); + if (adc->n_tm_channels > adc->max_channels - 1) { + pr_err("Number of TM nodes %u greater than channels supported:%u\n", + adc->n_tm_channels, adc->max_channels - 1); return -EINVAL; } prop->tm_chan_index = adc->n_tm_channels; @@ -1635,14 +1635,6 @@ static int adc5_gen3_probe(struct platform_device *pdev) if (!regmap) return -ENODEV; - ret = of_property_read_u32(node, "reg", ®); - if (ret < 0) - return ret; - adc->base = reg; - - if (!of_property_read_u32(node, "qcom,debug-base", ®)) - adc->debug_base = reg; - indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); if (!indio_dev) return -ENOMEM; @@ -1651,6 +1643,20 @@ static int adc5_gen3_probe(struct platform_device *pdev) adc->regmap = regmap; adc->dev = dev; + ret = of_property_count_u32_elems(node, "reg"); + if (ret < 0) + return ret; + + adc->max_channels = 8 * ret; + + ret = of_property_read_u32(node, "reg", ®); + if (ret < 0) + return ret; + adc->base = reg; + + if (!of_property_read_u32(node, "qcom,debug-base", ®)) + adc->debug_base = reg; + platform_set_drvdata(pdev, adc); indio_dev->info = &adc5_gen3_info; @@ -1715,7 +1721,7 @@ static int adc5_gen3_exit(struct platform_device *pdev) } /* Disable all available channels */ - for (i = 0; i < 8; i++) { + for (i = 0; i < adc->max_channels; i++) { data = MEAS_INT_DISABLE; adc5_write(adc, ADC5_GEN3_TIMER_SEL, &data, 1); From 94067cd605aa939295dba4b19e034cf62476359e Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Tue, 14 Dec 2021 17:11:03 -0800 Subject: [PATCH 03/17] iio: adc: qcom-spmi-adc5-gen3: Add support for multiple SDAMs Currently, ADC5 GEN3 driver allows up to 8 channels. In Kalama up to 16 channels can be configured over 2 SDAMS. Update member variables, interrupt handling and read and write functions so that driver can handle 2 or more SDAMS. Change-Id: I2d65d9a420092db98cdbf27bba5188700c46fd0a Signed-off-by: Anjelique Melendez --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 234 ++++++++++++++++---------- 1 file changed, 145 insertions(+), 89 deletions(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index 64db5839b6f4..8a4082cdf8b7 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -141,6 +142,12 @@ static struct adc_tm_reverse_scale_fn adc_tm_rscale_fn[] = { [SCALE_R_ABSOLUTE] = {adc_tm_absolute_rthr_gen3}, }; +struct adc5_base_data { + u16 base_addr; + const char *irq_name; + int irq; +}; + /** * struct adc5_channel_prop - ADC channel property. * @channel: channel number, refer to the channel list. @@ -152,6 +159,7 @@ static struct adc_tm_reverse_scale_fn adc_tm_rscale_fn[] = { * start of conversion. * @avg_samples: ability to provide single result from the ADC * that is an average of multiple measurements. + * @sdam_index: Index for which SDAM this channel is on. * @scale_fn_type: Represents the scaling function to convert voltage * physical units desired by the client for the channel. * @datasheet_name: Channel name used in device tree. @@ -184,6 +192,7 @@ struct adc5_channel_prop { unsigned int prescale; unsigned int hw_settle_time; unsigned int avg_samples; + unsigned int sdam_index; enum vadc_scale_fn_type scale_fn_type; const char *datasheet_name; @@ -212,10 +221,10 @@ struct adc5_channel_prop { * struct adc5_chip - ADC private structure. * @regmap: SPMI ADC5 peripheral register map field. * @dev: SPMI ADC5 device. - * @base: base address for the ADC peripheral. + * @base: pointer to array of ADC peripheral base and interrupt. * @debug_base: base address for the reserved ADC peripheral, * to dump for debug purposes alone. - * @max_channels: max amount of channels for the ADC peripheral. + * @num_sdams: number of SDAMs being used. * @nchannels: number of ADC channels. * @chan_props: array of ADC channel properties. * @iio_chans: array of IIO channels specification. @@ -230,9 +239,9 @@ struct adc5_channel_prop { struct adc5_chip { struct regmap *regmap; struct device *dev; - u16 base; + struct adc5_base_data *base; u16 debug_base; - unsigned int max_channels; + unsigned int num_sdams; unsigned int nchannels; struct adc5_channel_prop *chan_props; struct iio_chan_spec *iio_chans; @@ -258,22 +267,22 @@ static const struct u32_fract adc5_prescale_ratios[] = { { .numerator = 1000, .denominator = 305185 }, /* ICHG_FB */ }; -static int adc5_read(struct adc5_chip *adc, u16 offset, u8 *data, int len) +static int adc5_read(struct adc5_chip *adc, unsigned int sdam_index, u16 offset, u8 *data, int len) { int ret; - ret = regmap_bulk_read(adc->regmap, adc->base + offset, data, len); + ret = regmap_bulk_read(adc->regmap, adc->base[sdam_index].base_addr + offset, data, len); if (ret < 0) pr_err("adc read to register 0x%x of length:%d failed, ret=%d\n", offset, len, ret); return ret; } -static int adc5_write(struct adc5_chip *adc, u16 offset, u8 *data, int len) +static int adc5_write(struct adc5_chip *adc, unsigned int sdam_index, u16 offset, u8 *data, int len) { int ret; - ret = regmap_bulk_write(adc->regmap, adc->base + offset, data, len); + ret = regmap_bulk_write(adc->regmap, adc->base[sdam_index].base_addr + offset, data, len); if (ret < 0) pr_err("adc write to register 0x%x of length:%d failed, ret=%d\n", offset, len, ret); @@ -331,12 +340,13 @@ static int adc5_decimation_from_dt(u32 value, return -ENOENT; } -static int adc5_gen3_read_voltage_data(struct adc5_chip *adc, u16 *data) +static int adc5_gen3_read_voltage_data(struct adc5_chip *adc, u16 *data, + struct adc5_channel_prop *prop) { int ret; u8 rslt[2]; - ret = adc5_read(adc, ADC5_GEN3_CH0_DATA0, rslt, 2); + ret = adc5_read(adc, prop->sdam_index, ADC5_GEN3_CH0_DATA0, rslt, 2); if (ret < 0) return ret; @@ -370,7 +380,7 @@ static int adc5_gen3_configure(struct adc5_chip *adc, int ret; u8 conv_req = 0, buf[7]; - ret = adc5_read(adc, ADC5_GEN3_SID, buf, sizeof(buf)); + ret = adc5_read(adc, prop->sdam_index, ADC5_GEN3_SID, buf, sizeof(buf)); if (ret < 0) return ret; @@ -402,12 +412,12 @@ static int adc5_gen3_configure(struct adc5_chip *adc, reinit_completion(&adc->complete); - ret = adc5_write(adc, ADC5_GEN3_SID, buf, sizeof(buf)); + ret = adc5_write(adc, prop->sdam_index, ADC5_GEN3_SID, buf, sizeof(buf)); if (ret < 0) return ret; conv_req = ADC5_GEN3_CONV_REQ_REQ; - ret = adc5_write(adc, ADC5_GEN3_CONV_REQ, &conv_req, 1); + ret = adc5_write(adc, prop->sdam_index, ADC5_GEN3_CONV_REQ, &conv_req, 1); return ret; } @@ -416,13 +426,13 @@ static int adc5_gen3_configure(struct adc5_chip *adc, #define ADC5_GEN3_HS_DELAY_MAX_US 110 #define ADC5_GEN3_HS_RETRY_COUNT 20 -static int adc5_gen3_poll_wait_hs(struct adc5_chip *adc) +static int adc5_gen3_poll_wait_hs(struct adc5_chip *adc, struct adc5_channel_prop *prop) { int ret, count; u8 status = 0; for (count = 0; count < ADC5_GEN3_HS_RETRY_COUNT; count++) { - ret = adc5_read(adc, ADC5_GEN3_HS, &status, 1); + ret = adc5_read(adc, prop->sdam_index, ADC5_GEN3_HS, &status, 1); if (ret < 0) return ret; @@ -453,7 +463,7 @@ static int adc5_gen3_do_conversion(struct adc5_chip *adc, u8 val; mutex_lock(&adc->lock); - ret = adc5_gen3_poll_wait_hs(adc); + ret = adc5_gen3_poll_wait_hs(adc, prop); if (ret < 0) goto unlock; @@ -477,23 +487,23 @@ static int adc5_gen3_do_conversion(struct adc5_chip *adc, pr_debug("ADC channel %s EOC took %u ms\n", prop->datasheet_name, ADC5_GEN3_CONV_TIMEOUT_MS - time_pending_ms); - ret = adc5_gen3_read_voltage_data(adc, data_volt); + ret = adc5_gen3_read_voltage_data(adc, data_volt, prop); if (ret < 0) goto unlock; val = BIT(0); - ret = adc5_write(adc, ADC5_GEN3_EOC_CLR, &val, 1); + ret = adc5_write(adc, prop->sdam_index, ADC5_GEN3_EOC_CLR, &val, 1); if (ret < 0) goto unlock; /* To indicate conversion request is only to clear a status */ val = 0; - ret = adc5_write(adc, ADC5_GEN3_PERPH_CH, &val, 1); + ret = adc5_write(adc, prop->sdam_index, ADC5_GEN3_PERPH_CH, &val, 1); if (ret < 0) goto unlock; val = ADC5_GEN3_CONV_REQ_REQ; - ret = adc5_write(adc, ADC5_GEN3_CONV_REQ, &val, 1); + ret = adc5_write(adc, prop->sdam_index, ADC5_GEN3_CONV_REQ, &val, 1); unlock: mutex_unlock(&adc->lock); @@ -503,42 +513,60 @@ static int adc5_gen3_do_conversion(struct adc5_chip *adc, #define ADC_OFFSET_DUMP 8 #define ADC_SDAM_REG_DUMP 32 -static void adc5_gen3_dump_regs_debug(struct adc5_chip *adc) +static void adc5_gen3_dump_register(struct adc5_chip *adc, unsigned int offset) { - int rc = 0, i = 0, j = 0, offset; + int i, rc; u8 buf[8]; - for (j = 0; j < 2; j++) { - if (!j) { - offset = adc->base; - pr_debug("ADC SDAM DUMP\n"); - } else { - if (adc->debug_base) - offset = adc->debug_base; - else - break; - pr_debug("SDAM 20 DUMP\n"); - } - - for (i = 0; i < ADC_SDAM_REG_DUMP; i++) { - rc = regmap_bulk_read(adc->regmap, offset, buf, sizeof(buf)); - if (rc < 0) { - pr_err("debug register dump failed\n"); - return; - } - offset += ADC_OFFSET_DUMP; - pr_debug("Buf[%d]: %*ph\n", i, sizeof(buf), buf); + for (i = 0; i < ADC_SDAM_REG_DUMP; i++) { + rc = regmap_bulk_read(adc->regmap, offset, buf, sizeof(buf)); + if (rc < 0) { + pr_err("debug register dump failed with rc=%d\n", rc); + return; } + offset += ADC_OFFSET_DUMP; + pr_debug("Buf[%d]: %*ph\n", i, sizeof(buf), buf); } } +static void adc5_gen3_dump_regs_debug(struct adc5_chip *adc) +{ + int i = 0; + + for (i = 0; i < adc->num_sdams; i++) { + pr_debug("ADC SDAM%d DUMP\n", i); + adc5_gen3_dump_register(adc, adc->base[i].base_addr); + } + if (adc->debug_base) { + pr_debug("ADC Debug base DUMP\n"); + adc5_gen3_dump_register(adc, adc->debug_base); + } +} + +static int get_sdam_from_irq(struct adc5_chip *adc, int irq) +{ + int i; + + for (i = 0; i < adc->num_sdams; i++) { + if (adc->base[i].irq == irq) + return i; + } + return -ENOENT; +} + static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) { struct adc5_chip *adc = dev_id; u8 status, tm_status[2], eoc_status, val; - int ret; + int ret, sdam_num; - ret = adc5_read(adc, ADC5_GEN3_EOC_STS, &eoc_status, 1); + sdam_num = get_sdam_from_irq(adc, irq); + if (sdam_num < 0) { + pr_err("adc irq %d not associated with an sdam\n", irq); + goto handler_end; + } + + ret = adc5_read(adc, sdam_num, ADC5_GEN3_EOC_STS, &eoc_status, 1); if (ret < 0) { pr_err("adc read eoc status failed with %d\n", ret); goto handler_end; @@ -548,7 +576,7 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) if (eoc_status & ADC5_GEN3_EOC_CHAN_0) complete(&adc->complete); - ret = adc5_read(adc, ADC5_GEN3_TM_HIGH_STS, tm_status, 2); + ret = adc5_read(adc, sdam_num, ADC5_GEN3_TM_HIGH_STS, tm_status, 2); if (ret < 0) { pr_err("adc read TM status failed with %d\n", ret); goto handler_end; @@ -557,7 +585,7 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) if (tm_status[0] || tm_status[1]) schedule_work(&adc->tm_handler_work); - ret = adc5_read(adc, ADC5_GEN3_STATUS1, &status, 1); + ret = adc5_read(adc, sdam_num, ADC5_GEN3_STATUS1, &status, 1); if (ret < 0) { pr_err("adc read status1 failed with %d\n", ret); goto handler_end; @@ -571,18 +599,18 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) adc5_gen3_dump_regs_debug(adc); val = ADC5_GEN3_CONV_ERR_CLR_REQ; - ret = adc5_write(adc, ADC5_GEN3_CONV_ERR_CLR, &val, 1); + ret = adc5_write(adc, sdam_num, ADC5_GEN3_CONV_ERR_CLR, &val, 1); if (ret < 0) goto handler_end; /* To indicate conversion request is only to clear a status */ val = 0; - ret = adc5_write(adc, ADC5_GEN3_PERPH_CH, &val, 1); + ret = adc5_write(adc, sdam_num, ADC5_GEN3_PERPH_CH, &val, 1); if (ret < 0) goto handler_end; val = ADC5_GEN3_CONV_REQ_REQ; - ret = adc5_write(adc, ADC5_GEN3_CONV_REQ, &val, 1); + ret = adc5_write(adc, sdam_num, ADC5_GEN3_CONV_REQ, &val, 1); if (ret < 0) goto handler_end; } @@ -591,23 +619,21 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static void tm_handler_work(struct work_struct *work) +static void __tm_handler_work(struct adc5_chip *adc, unsigned int sdam_index) { - struct adc5_chip *adc = container_of(work, struct adc5_chip, - tm_handler_work); struct adc5_channel_prop *chan_prop; u8 tm_status[2], buf[16], val; int ret, i; mutex_lock(&adc->lock); - ret = adc5_read(adc, ADC5_GEN3_TM_HIGH_STS, tm_status, 2); + ret = adc5_read(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS, tm_status, 2); if (ret < 0) { pr_err("adc read TM status failed with %d\n", ret); goto work_unlock; } - ret = adc5_write(adc, ADC5_GEN3_TM_HIGH_STS_CLR, tm_status, 2); + ret = adc5_write(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS_CLR, tm_status, 2); if (ret < 0) { pr_err("adc write TM status failed with %d\n", ret); goto work_unlock; @@ -615,20 +641,20 @@ static void tm_handler_work(struct work_struct *work) /* To indicate conversion request is only to clear a status */ val = 0; - ret = adc5_write(adc, ADC5_GEN3_PERPH_CH, &val, 1); + ret = adc5_write(adc, sdam_index, ADC5_GEN3_PERPH_CH, &val, 1); if (ret < 0) { pr_err("adc write status clear conv_req failed with %d\n", ret); goto work_unlock; } val = ADC5_GEN3_CONV_REQ_REQ; - ret = adc5_write(adc, ADC5_GEN3_CONV_REQ, &val, 1); + ret = adc5_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &val, 1); if (ret < 0) { pr_err("adc write conv_req failed with %d\n", ret); goto work_unlock; } - ret = adc5_read(adc, ADC5_GEN3_CH0_DATA0, buf, sizeof(buf)); + ret = adc5_read(adc, sdam_index, ADC5_GEN3_CH0_DATA0, buf, sizeof(buf)); if (ret < 0) { pr_err("adc read data failed with %d\n", ret); goto work_unlock; @@ -636,7 +662,7 @@ static void tm_handler_work(struct work_struct *work) mutex_unlock(&adc->lock); - for (i = 0; i < adc->nchannels; i++) { + for (i = sdam_index * 8; i < (sdam_index + 1) * 8; i++) { bool upper_set = false, lower_set = false; u8 data_low = 0, data_high = 0; u16 code = 0; @@ -704,6 +730,16 @@ static void tm_handler_work(struct work_struct *work) mutex_unlock(&adc->lock); } +static void tm_handler_work(struct work_struct *work) +{ + int i; + struct adc5_chip *adc = container_of(work, struct adc5_chip, + tm_handler_work); + + for (i = 0; i < adc->num_sdams; i++) + __tm_handler_work(adc, i); +} + static int adc5_gen3_of_xlate(struct iio_dev *indio_dev, const struct of_phandle_args *iiospec) { @@ -802,11 +838,11 @@ static int adc_tm5_gen3_configure(struct adc5_channel_prop *prop) u32 mask = 0; struct adc5_chip *adc = prop->chip; - ret = adc5_gen3_poll_wait_hs(adc); + ret = adc5_gen3_poll_wait_hs(adc, prop); if (ret < 0) return ret; - ret = adc5_read(adc, ADC5_GEN3_SID, buf, sizeof(buf)); + ret = adc5_read(adc, prop->sdam_index, ADC5_GEN3_SID, buf, sizeof(buf)); if (ret < 0) return ret; @@ -846,12 +882,12 @@ static int adc_tm5_gen3_configure(struct adc5_channel_prop *prop) buf[10] = ADC_TM5_GEN3_LOWER_MASK(mask); buf[11] = ADC_TM5_GEN3_UPPER_MASK(mask); - ret = adc5_write(adc, ADC5_GEN3_SID, buf, sizeof(buf)); + ret = adc5_write(adc, prop->sdam_index, ADC5_GEN3_SID, buf, sizeof(buf)); if (ret < 0) return ret; conv_req = ADC5_GEN3_CONV_REQ_REQ; - return adc5_write(adc, ADC5_GEN3_CONV_REQ, &conv_req, 1); + return adc5_write(adc, prop->sdam_index, ADC5_GEN3_CONV_REQ, &conv_req, 1); } static int adc_tm5_gen3_set_trip_temp(void *data, @@ -1396,7 +1432,7 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc, const char *name = node->name, *channel_name; u32 chan, value, varr[2]; u32 sid = 0; - int ret; + int ret, val; struct device *dev = adc->dev; ret = of_property_read_u32(node, "reg", &chan); @@ -1510,12 +1546,16 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc, if (prop->adc_tm && prop->adc_tm != ADC_TM_IIO) { adc->n_tm_channels++; - if (adc->n_tm_channels > adc->max_channels - 1) { + if (adc->n_tm_channels > ((adc->num_sdams * 8) - 1)) { pr_err("Number of TM nodes %u greater than channels supported:%u\n", - adc->n_tm_channels, adc->max_channels - 1); + adc->n_tm_channels, (adc->num_sdams * 8) - 1); return -EINVAL; } - prop->tm_chan_index = adc->n_tm_channels; + + val = adc->n_tm_channels / 8; + prop->sdam_index = val; + prop->tm_chan_index = adc->n_tm_channels - (8*val); + prop->timer = MEAS_INT_1S; if (prop->adc_tm == ADC_TM_NON_THERMAL) { @@ -1605,7 +1645,6 @@ static int adc5_get_dt_data(struct adc5_chip *adc, struct device_node *node) data->adc_chans[prop.channel].scale_fn_type; *chan_props = prop; adc_chan = &data->adc_chans[prop.channel]; - iio_chan->channel = prop.channel; iio_chan->datasheet_name = prop.datasheet_name; iio_chan->extend_name = prop.datasheet_name; @@ -1627,9 +1666,9 @@ static int adc5_gen3_probe(struct platform_device *pdev) struct iio_dev *indio_dev; struct adc5_chip *adc; struct regmap *regmap; - const char *irq_name; - int ret, irq_eoc, i; + int ret, i; u32 reg; + char buf[20]; regmap = dev_get_regmap(dev->parent, NULL); if (!regmap) @@ -1647,12 +1686,31 @@ static int adc5_gen3_probe(struct platform_device *pdev) if (ret < 0) return ret; - adc->max_channels = 8 * ret; + adc->num_sdams = ret; - ret = of_property_read_u32(node, "reg", ®); - if (ret < 0) - return ret; - adc->base = reg; + adc->base = devm_kcalloc(adc->dev, adc->num_sdams, sizeof(*adc->base), GFP_KERNEL); + if (!adc->base) + return -ENOMEM; + + for (i = 0; i < adc->num_sdams; i++) { + ret = of_property_read_u32_index(node, "reg", i, ®); + if (ret < 0) + return ret; + + adc->base[i].base_addr = reg; + + scnprintf(buf, sizeof(buf), "adc-sdam%d", i); + ret = of_irq_get_byname(node, buf); + if (ret < 0) { + pr_err("Failed to get irq for ADC5 GEN3 SDAM%d, ret=%d\n", i, ret); + return ret; + } + adc->base[i].irq = ret; + + adc->base[i].irq_name = devm_kstrdup(adc->dev, buf, GFP_KERNEL); + if (!adc->base[i].irq_name) + return -ENOMEM; + } if (!of_property_read_u32(node, "qcom,debug-base", ®)) adc->debug_base = reg; @@ -1672,15 +1730,12 @@ static int adc5_gen3_probe(struct platform_device *pdev) adc_tm_register_tzd(adc); - irq_eoc = platform_get_irq(pdev, 0); - irq_name = "pm-adc5"; - if (adc->data->name) - irq_name = adc->data->name; - - ret = devm_request_irq(dev, irq_eoc, adc5_gen3_isr, 0, - irq_name, adc); - if (ret < 0) - goto fail; + for (i = 0; i < adc->num_sdams; i++) { + ret = devm_request_irq(dev, adc->base[i].irq, adc5_gen3_isr, + 0, adc->base[i].irq_name, adc); + if (ret < 0) + goto fail; + } if (adc->n_tm_channels) INIT_WORK(&adc->tm_handler_work, tm_handler_work); @@ -1711,7 +1766,7 @@ static int adc5_gen3_exit(struct platform_device *pdev) { struct adc5_chip *adc = platform_get_drvdata(pdev); u8 data = 0; - int i; + int i, sdam_index; mutex_lock(&adc->lock); for (i = 0; i < adc->nchannels; i++) { @@ -1721,16 +1776,17 @@ static int adc5_gen3_exit(struct platform_device *pdev) } /* Disable all available channels */ - for (i = 0; i < adc->max_channels; i++) { + for (i = 0; i < adc->num_sdams * 8; i++) { + sdam_index = i / 8; data = MEAS_INT_DISABLE; - adc5_write(adc, ADC5_GEN3_TIMER_SEL, &data, 1); + adc5_write(adc, sdam_index, ADC5_GEN3_TIMER_SEL, &data, 1); /* To indicate there is an actual conversion request */ - data = ADC5_GEN3_CHAN_CONV_REQ | i; - adc5_write(adc, ADC5_GEN3_PERPH_CH, &data, 1); + data = ADC5_GEN3_CHAN_CONV_REQ | (i - (sdam_index*8)); + adc5_write(adc, sdam_index, ADC5_GEN3_PERPH_CH, &data, 1); data = ADC5_GEN3_CONV_REQ_REQ; - adc5_write(adc, ADC5_GEN3_CONV_REQ, &data, 1); + adc5_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &data, 1); } mutex_unlock(&adc->lock); From f394355bf82577c9f54e96009334bbc724580b32 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Fri, 7 Jan 2022 14:05:12 -0800 Subject: [PATCH 04/17] dt-bindings: iio: Add ADC5 GEN3 Channel info for Kalama PMICs Add the ADC5 GEN3 channels used by PMK8550, PM8550 and PM8550B. Change-Id: I0a52446634dfa2108e1b3f2c0e990610138340b9 Signed-off-by: Anjelique Melendez --- .../iio/qcom,spmi-adc5-gen3-pm8550.h | 48 ++++++++++ .../iio/qcom,spmi-adc5-gen3-pm8550b.h | 96 +++++++++++++++++++ .../iio/qcom,spmi-adc5-gen3-pm8550vx.h | 55 +++++++++++ .../iio/qcom,spmi-adc5-gen3-pmk8550.h | 54 +++++++++++ 4 files changed, 253 insertions(+) create mode 100644 include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550.h create mode 100644 include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h create mode 100644 include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550vx.h create mode 100644 include/dt-bindings/iio/qcom,spmi-adc5-gen3-pmk8550.h diff --git a/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550.h b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550.h new file mode 100644 index 000000000000..fa31ca5f1973 --- /dev/null +++ b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_PM8550_H +#define _DT_BINDINGS_QCOM_SPMI_VADC_PM8550_H + +#ifndef PM8550_SID +#define PM8550_SID 1 +#endif + +/* ADC channels for PM8550_ADC for PMIC5 Gen3 */ +#define PM8550_ADC5_GEN3_OFFSET_REF (PM8550_SID << 8 | 0x00) +#define PM8550_ADC5_GEN3_1P25VREF (PM8550_SID << 8 | 0x01) +#define PM8550_ADC5_GEN3_VREF_VADC (PM8550_SID << 8 | 0x02) +#define PM8550_ADC5_GEN3_DIE_TEMP (PM8550_SID << 8 | 0x03) + +#define PM8550_ADC5_GEN3_AMUX_THM1 (PM8550_SID << 8 | 0x04) +#define PM8550_ADC5_GEN3_AMUX_THM2 (PM8550_SID << 8 | 0x05) +#define PM8550_ADC5_GEN3_AMUX_THM3 (PM8550_SID << 8 | 0x06) +#define PM8550_ADC5_GEN3_AMUX_THM4 (PM8550_SID << 8 | 0x07) +#define PM8550_ADC5_GEN3_AMUX_THM5 (PM8550_SID << 8 | 0x08) +#define PM8550_ADC5_GEN3_AMUX_THM6_GPIO2 (PM8550_SID << 8 | 0x09) +#define PM8550_ADC5_GEN3_AMUX1_GPIO3 (PM8550_SID << 8 | 0x0a) +#define PM8550_ADC5_GEN3_AMUX2_GPIO4 (PM8550_SID << 8 | 0x0b) +#define PM8550_ADC5_GEN3_AMUX3_GPIO7 (PM8550_SID << 8 | 0x0c) +#define PM8550_ADC5_GEN3_AMUX4_GPIO12 (PM8550_SID << 8 | 0x0d) + +/* 100k pull-up */ +#define PM8550_ADC5_GEN3_AMUX_THM1_100K_PU (PM8550_SID << 8 | 0x44) +#define PM8550_ADC5_GEN3_AMUX_THM2_100K_PU (PM8550_SID << 8 | 0x45) +#define PM8550_ADC5_GEN3_AMUX_THM3_100K_PU (PM8550_SID << 8 | 0x46) +#define PM8550_ADC5_GEN3_AMUX_THM4_100K_PU (PM8550_SID << 8 | 0x47) +#define PM8550_ADC5_GEN3_AMUX_THM5_100K_PU (PM8550_SID << 8 | 0x48) +#define PM8550_ADC5_GEN3_AMUX_THM6_GPIO2_100K_PU (PM8550_SID << 8 | 0x49) +#define PM8550_ADC5_GEN3_AMUX1_GPIO3_100K_PU (PM8550_SID << 8 | 0x4a) +#define PM8550_ADC5_GEN3_AMUX2_GPIO4_100K_PU (PM8550_SID << 8 | 0x4b) +#define PM8550_ADC5_GEN3_AMUX3_GPIO7_100K_PU (PM8550_SID << 8 | 0x4c) +#define PM8550_ADC5_GEN3_AMUX4_GPIO12_100K_PU (PM8550_SID << 8 | 0x4d) + +/* 1/3 Divider */ +#define PM8550_ADC5_GEN3_AMUX3_GPIO7_DIV3 (PM8550_SID << 8 | 0x8c) +#define PM8550_ADC5_GEN3_AMUX4_GPIO12_DIV3 (PM8550_SID << 8 | 0x8d) + +#define PM8550_ADC5_GEN3_VPH_PWR (PM8550_SID << 8 | 0x8e) + +#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_PM8550_H */ diff --git a/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h new file mode 100644 index 000000000000..e5b149da6c7d --- /dev/null +++ b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_PM8550B_H +#define _DT_BINDINGS_QCOM_SPMI_VADC_PM8550B_H + +#ifndef PM8550B_SID +#define PM8550B_SID 7 +#endif + +/* ADC channels for PM8550B_ADC for PMIC5 Gen3 */ +#define PM8550B_ADC5_GEN3_OFFSET_REF (PM8550B_SID << 8 | 0x00) +#define PM8550B_ADC5_GEN3_1P25VREF (PM8550B_SID << 8 | 0x01) +#define PM8550B_ADC5_GEN3_VREF_VADC (PM8550B_SID << 8 | 0x02) +#define PM8550B_ADC5_GEN3_DIE_TEMP (PM8550B_SID << 8 | 0x03) + +#define PM8550B_ADC5_GEN3_AMUX_THM1_BATT_THERM (PM8550B_SID << 8 | 0x04) +#define PM8550B_ADC5_GEN3_AMUX_THM2_BATT_ID (PM8550B_SID << 8 | 0x05) +#define PM8550B_ADC5_GEN3_AMUX_THM3_SMB_TEMP_V (PM8550B_SID << 8 | 0x06) +#define PM8550B_ADC5_GEN3_AMUX_THM4_USB_THERM (PM8550B_SID << 8 | 0x07) +#define PM8550B_ADC5_GEN3_AMUX_THM5_OPTION (PM8550B_SID << 8 | 0x08) +#define PM8550B_ADC5_GEN3_AMUX_THM6_GPIO10 (PM8550B_SID << 8 | 0x09) +#define PM8550B_ADC5_GEN3_AMUX1_GPIO1 (PM8550B_SID << 8 | 0x0a) +#define PM8550B_ADC5_GEN3_AMUX2_GPIO5 (PM8550B_SID << 8 | 0x0b) +#define PM8550B_ADC5_GEN3_AMUX3_GPIO6 (PM8550B_SID << 8 | 0x0c) +#define PM8550B_ADC5_GEN3_AMUX4_GPIO12 (PM8550B_SID << 8 | 0x0d) + +#define PM8550B_ADC5_GEN3_CHG_TEMP (PM8550B_SID << 8 | 0x10) +#define PM8550B_ADC5_GEN3_USB_SNS_V_16 (PM8550B_SID << 8 | 0x11) +#define PM8550B_ADC5_GEN3_VIN_DIV16_MUX (PM8550B_SID << 8 | 0x12) +#define PM8550B_ADC5_GEN3_USBC_MUX (PM8550B_SID << 8 | 0x13) +#define PM8550B_ADC5_GEN3_VREF_BAT_THERM (PM8550B_SID << 8 | 0x15) +#define PM8550B_ADC5_GEN3_IIN_FB (PM8550B_SID << 8 | 0x17) +#define PM8550B_ADC5_GEN3_TEMP_ALARM_LITE (PM8550B_SID << 8 | 0x18) +#define PM8550B_ADC5_GEN3_SMB_IIN (PM8550B_SID << 8 | 0x19) +#define PM8550B_ADC5_GEN3_VREF_BAT2_THERM (PM8550B_SID << 8 | 0x1a) +#define PM8550B_ADC5_GEN3_SMB_ICHG (PM8550B_SID << 8 | 0x1b) +#define PM8550B_ADC5_GEN3_SMB_TEMP_I (PM8550B_SID << 8 | 0x1e) +#define PM8550B_ADC5_GEN3_CHG_TEMP_I (PM8550B_SID << 8 | 0x1f) + +/* 30k pull-up */ +#define PM8550B_ADC5_GEN3_AMUX_THM1_BATT_THERM_30K_PU (PM8550B_SID << 8 | 0x24) +#define PM8550B_ADC5_GEN3_AMUX_THM2_BATT_ID_30K_PU (PM8550B_SID << 8 | 0x25) +#define PM8550B_ADC5_GEN3_AMUX_THM3_SMB_TEMP_V_30K_PU (PM8550B_SID << 8 | 0x26) +#define PM8550B_ADC5_GEN3_AMUX_THM4_USB_THERM_30K_PU (PM8550B_SID << 8 | 0x27) +#define PM8550B_ADC5_GEN3_AMUX_THM5_OPTION_30K_PU (PM8550B_SID << 8 | 0x28) +#define PM8550B_ADC5_GEN3_AMUX_THM6_GPIO10_30K_PU (PM8550B_SID << 8 | 0x29) +#define PM8550B_ADC5_GEN3_AMUX1_GPIO1_30K_PU (PM8550B_SID << 8 | 0x2a) +#define PM8550B_ADC5_GEN3_AMUX2_GPIO5_30K_PU (PM8550B_SID << 8 | 0x2b) +#define PM8550B_ADC5_GEN3_AMUX3_GPIO6_30K_PU (PM8550B_SID << 8 | 0x2c) +#define PM8550B_ADC5_GEN3_AMUX4_GPIO12_30K_PU (PM8550B_SID << 8 | 0x2d) + +#define PM8550B_ADC5_GEN3_USBC_MUX_30K_PU (PM8550B_SID << 8 | 0x33) + +/* 100k pull-up */ +#define PM8550B_ADC5_GEN3_AMUX_THM1_BATT_THERM_100K_PU (PM8550B_SID << 8 | 0x44) +#define PM8550B_ADC5_GEN3_AMUX_THM2_BATT_ID_100K_PU (PM8550B_SID << 8 | 0x45) +#define PM8550B_ADC5_GEN3_AMUX_THM3_SMB_TEMP_V_100K_PU (PM8550B_SID << 8 | 0x46) +#define PM8550B_ADC5_GEN3_AMUX_THM4_USB_THERM_100K_PU (PM8550B_SID << 8 | 0x47) +#define PM8550B_ADC5_GEN3_AMUX_THM5_OPTION_100K_PU (PM8550B_SID << 8 | 0x48) +#define PM8550B_ADC5_GEN3_AMUX_THM6_GPIO10_100K_PU (PM8550B_SID << 8 | 0x49) +#define PM8550B_ADC5_GEN3_AMUX1_GPIO1_100K_PU (PM8550B_SID << 8 | 0x4a) +#define PM8550B_ADC5_GEN3_AMUX2_GPIO5_100K_PU (PM8550B_SID << 8 | 0x4b) +#define PM8550B_ADC5_GEN3_AMUX3_GPIO5_100K_PU (PM8550B_SID << 8 | 0x4c) +#define PM8550B_ADC5_GEN3_AMUX4_GPIO12_100K_PU (PM8550B_SID << 8 | 0x4d) + +#define PM8550B_ADC5_GEN3_USBC_MUX_100K_PU (PM8550B_SID << 8 | 0x53) + +/* 400k pull-up */ +#define PM8550B_ADC5_GEN3_AMUX_THM1_BATT_THERM_400K_PU (PM8550B_SID << 8 | 0x64) +#define PM8550B_ADC5_GEN3_AMUX_THM2_BATT_ID_400K_PU (PM8550B_SID << 8 | 0x65) +#define PM8550B_ADC5_GEN3_AMUX_THM3_SMB_TEMP_V_400K_PU (PM8550B_SID << 8 | 0x66) +#define PM8550B_ADC5_GEN3_AMUX_THM4_USB_THERM_400K_PU (PM8550B_SID << 8 | 0x67) +#define PM8550B_ADC5_GEN3_AMUX_THM5_OPTION_400K_PU (PM8550B_SID << 8 | 0x68) +#define PM8550B_ADC5_GEN3_AMUX_THM6_GPIO10_400K_PU (PM8550B_SID << 8 | 0x69) +#define PM8550B_ADC5_GEN3_AMUX1_GPIO1_400K_PU (PM8550B_SID << 8 | 0x6a) +#define PM8550B_ADC5_GEN3_AMUX2_GPIO5_400K_PU (PM8550B_SID << 8 | 0x6b) +#define PM8550B_ADC5_GEN3_AMUX3_GPIO6_400K_PU (PM8550B_SID << 8 | 0x6c) +#define PM8550B_ADC5_GEN3_AMUX4_GPIO12_400K_PU (PM8550B_SID << 8 | 0x6d) + +#define PM8550B_ADC5_GEN3_USBC_MUX_400K_PU (PM8550B_SID << 8 | 0x73) + +/* 1/3 Divider */ +#define PM8550B_ADC5_GEN3_AMUX1_GPIO1_DIV3 (PM8550B_SID << 8 | 0x8a) +#define PM8550B_ADC5_GEN3_AMUX2_GPIO5_DIV3 (PM8550B_SID << 8 | 0x8b) +#define PM8550B_ADC5_GEN3_AMUX3_GPIO6_DIV3 (PM8550B_SID << 8 | 0x8c) + +#define PM8550B_ADC5_GEN3_VPH_PWR (PM8550B_SID << 8 | 0x8e) +#define PM8550B_ADC5_GEN3_VBAT_SNS_QBG (PM8550B_SID << 8 | 0x8f) +#define PM8550B_ADC5_GEN3_VBAT_SNS_CHGR (PM8550B_SID << 8 | 0x94) +#define PM8550B_ADC5_GEN3_VREF_2S_MID_QBG (PM8550B_SID << 8 | 0x96) +#define PM8550B_ADC5_GEN3_VBAT_2S_MID_CHGR (PM8550B_SID << 8 | 0x9d) + +#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_PM8550B_H */ diff --git a/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550vx.h b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550vx.h new file mode 100644 index 000000000000..8ba64fae8f21 --- /dev/null +++ b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550vx.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_PM8550VX_H +#define _DT_BINDINGS_QCOM_SPMI_VADC_PM8550VX_H + +#ifndef PM8550VS_C_SID +#define PM8550VS_C_SID 2 +#endif + +#ifndef PM8550VS_D_SID +#define PM8550VS_D_SID 3 +#endif + +#ifndef PM8550VS_E_SID +#define PM8550VS_E_SID 4 +#endif + +#ifndef PM8550VS_G_SID +#define PM8550VS_G_SID 6 +#endif + +#ifndef PM8550VE_SID +#define PM8550VE_SID 5 +#endif + +/* ADC channels for PM8550VX_ADC for PMIC5 Gen3 */ +#define PM8550VS_C_ADC5_GEN3_OFFSET_REF (PM8550VS_C_SID << 8 | 0x00) +#define PM8550VS_C_ADC5_GEN3_1P25VREF (PM8550VS_C_SID << 8 | 0x01) +#define PM8550VS_C_ADC5_GEN3_VREF_VADC (PM8550VS_C_SID << 8 | 0X02) +#define PM8550VS_C_ADC5_GEN3_DIE_TEMP (PM8550VS_C_SID << 8 | 0x03) + +#define PM8550VS_D_ADC5_GEN3_OFFSET_REF (PM8550VS_D_SID << 8 | 0x00) +#define PM8550VS_D_ADC5_GEN3_1P25VREF (PM8550VS_D_SID << 8 | 0x01) +#define PM8550VS_D_ADC5_GEN3_VREF_VADC (PM8550VS_D_SID << 8 | 0X02) +#define PM8550VS_D_ADC5_GEN3_DIE_TEMP (PM8550VS_D_SID << 8 | 0x03) + +#define PM8550VS_E_ADC5_GEN3_OFFSET_REF (PM8550VS_E_SID << 8 | 0x00) +#define PM8550VS_E_ADC5_GEN3_1P25VREF (PM8550VS_E_SID << 8 | 0x01) +#define PM8550VS_E_ADC5_GEN3_VREF_VADC (PM8550VS_E_SID << 8 | 0X02) +#define PM8550VS_E_ADC5_GEN3_DIE_TEMP (PM8550VS_E_SID << 8 | 0x03) + +#define PM8550VS_G_ADC5_GEN3_OFFSET_REF (PM8550VS_G_SID << 8 | 0x00) +#define PM8550VS_G_ADC5_GEN3_1P25VREF (PM8550VS_G_SID << 8 | 0x01) +#define PM8550VS_G_ADC5_GEN3_VREF_VADC (PM8550VS_G_SID << 8 | 0X02) +#define PM8550VS_G_ADC5_GEN3_DIE_TEMP (PM8550VS_G_SID << 8 | 0x03) + +#define PM8550VE_ADC5_GEN3_OFFSET_REF (PM8550VE_SID << 8 | 0x00) +#define PM8550VE_ADC5_GEN3_1P25VREF (PM8550VE_SID << 8 | 0x01) +#define PM8550VE_ADC5_GEN3_VREF_VADC (PM8550VE_SID << 8 | 0X02) +#define PM8550VE_ADC5_GEN3_DIE_TEMP (PM8550VE_SID << 8 | 0x03) + +#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_PM8550VX_H */ diff --git a/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pmk8550.h b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pmk8550.h new file mode 100644 index 000000000000..db88b7e63e0a --- /dev/null +++ b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pmk8550.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_PMK8550_H +#define _DT_BINDINGS_QCOM_SPMI_VADC_PMK8550_H + +#ifndef PMK8550_SID +#define PMK8550_SID 0 +#endif + +/* ADC channels for PMK8550_ADC for PMIC5 Gen3 */ +#define PMK8550_ADC5_GEN3_OFFSET_REF (PMK8550_SID << 8 | 0x00) +#define PMK8550_ADC5_GEN3_1P25VREF (PMK8550_SID << 8 | 0x01) +#define PMK8550_ADC5_GEN3_VREF_VADC (PMK8550_SID << 8 | 0x02) +#define PMK8550_ADC5_GEN3_DIE_TEMP (PMK8550_SID << 8 | 0x03) + +#define PMK8550_ADC5_GEN3_AMUX_THM1_XO_THERM (PMK8550_SID << 8 | 0x04) +#define PMK8550_ADC5_GEN3_AMUX_THM2_GPIO1 (PMK8550_SID << 8 | 0x05) +#define PMK8550_ADC5_GEN3_AMUX_THM3_GPIO2 (PMK8550_SID << 8 | 0x06) +#define PMK8550_ADC5_GEN3_AMUX_THM4_GPIO3 (PMK8550_SID << 8 | 0x07) +#define PMK8550_ADC5_GEN3_AMUX_THM5_GPIO4 (PMK8550_SID << 8 | 0x08) +#define PMK8550_ADC5_GEN3_AMUX_THM6_GPIO5 (PMK8550_SID << 8 | 0x09) +#define PMK8550_ADC5_GEN3_AMUX1_GPIO6 (PMK8550_SID << 8 | 0x0a) + +/* 30k pull-up */ +#define PMK8550_ADC5_GEN3_AMUX_THM1_XO_THERM_30K_PU (PMK8550_SID << 8 | 0x24) +#define PMK8550_ADC5_GEN3_AMUX_THM2_GPIO1_30K_PU (PMK8550_SID << 8 | 0x25) +#define PMK8550_ADC5_GEN3_AMUX_THM3_GPIO2_30K_PU (PMK8550_SID << 8 | 0x26) +#define PMK8550_ADC5_GEN3_AMUX_THM4_GPIO3_30K_PU (PMK8550_SID << 8 | 0x27) +#define PMK8550_ADC5_GEN3_AMUX_THM5_GPIO4_30K_PU (PMK8550_SID << 8 | 0x28) +#define PMK8550_ADC5_GEN3_AMUX_THM6_GPIO5_30K_PU (PMK8550_SID << 8 | 0x29) +#define PMK8550_ADC5_GEN3_AMUX1_GPIO6_30K_PU (PMK8550_SID << 8 | 0x2a) + +/* 100k pull-up */ +#define PMK8550_ADC5_GEN3_AMUX_THM1_XO_THERM_100K_PU (PMK8550_SID << 8 | 0x44) +#define PMK8550_ADC5_GEN3_AMUX_THM2_GPIO1_100K_PU (PMK8550_SID << 8 | 0x45) +#define PMK8550_ADC5_GEN3_AMUX_THM3_GPIO2_100K_PU (PMK8550_SID << 8 | 0x46) +#define PMK8550_ADC5_GEN3_AMUX_THM4_GPIO3_100K_PU (PMK8550_SID << 8 | 0x47) +#define PMK8550_ADC5_GEN3_AMUX_THM5_GPIO4_100K_PU (PMK8550_SID << 8 | 0x48) +#define PMK8550_ADC5_GEN3_AMUX_THM6_GPIO5_100K_PU (PMK8550_SID << 8 | 0x49) +#define PMK8550_ADC5_GEN3_AMUX1_GPIO6_100K_PU (PMK8550_SID << 8 | 0x4a) + +/* 400k pull-up */ +#define PMK8550_ADC5_GEN3_AMUX_THM1_XO_THERM_400K_PU (PMK8550_SID << 8 | 0x64) +#define PMK8550_ADC5_GEN3_AMUX_THM2_GPIO1_400K_PU (PMK8550_SID << 8 | 0x65) +#define PMK8550_ADC5_GEN3_AMUX_THM3_GPIO2_400K_PU (PMK8550_SID << 8 | 0x66) +#define PMK8550_ADC5_GEN3_AMUX_THM4_GPIO3_400K_PU (PMK8550_SID << 8 | 0x67) +#define PMK8550_ADC5_GEN3_AMUX_THM5_GPIO4_400K_PU (PMK8550_SID << 8 | 0x68) +#define PMK8550_ADC5_GEN3_AMUX_THM6_GPIO5_400K_PU (PMK8550_SID << 8 | 0x69) +#define PMK8550_ADC5_GEN3_AMUX1_GPIO6_400K_PU (PMK8550_SID << 8 | 0x6a) + +#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_PMK8550_H */ From 1d56dd15cbb5ba12f8bb2e2d11cd639e3692ded0 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Thu, 20 Jan 2022 16:36:39 -0800 Subject: [PATCH 05/17] iio: adc: qcom-spmi-adc5-gen3: Fix interrupt handler returns Currently, the adc5 gen3 interrupt handler always returns IRQ_HANDLED. Fix the handler so that on errors IRQ_NONE is returned. Change-Id: I2ccebb985c81ad9de57b829b469ec8e58437f9e9 Signed-off-by: Anjelique Melendez --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index 8a4082cdf8b7..c6c3f6a1ba7d 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -615,8 +615,10 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) goto handler_end; } -handler_end: return IRQ_HANDLED; + +handler_end: + return IRQ_NONE; } static void __tm_handler_work(struct adc5_chip *adc, unsigned int sdam_index) From 0801e19f0845ddc7d15f10ae6ee8d4e0268f0670 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Thu, 3 Feb 2022 17:37:22 -0800 Subject: [PATCH 06/17] dt-bindings: iio: Correct PM8550B ADC channel names Typo found in two of PM8550B ADC channel names. Fix them. Change-Id: I3e69402f3837cb6e29d84ea1ddb789801c72ec2f Signed-off-by: Anjelique Melendez --- include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h index e5b149da6c7d..e4c7d4bb7a64 100644 --- a/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h +++ b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h @@ -63,7 +63,7 @@ #define PM8550B_ADC5_GEN3_AMUX_THM6_GPIO10_100K_PU (PM8550B_SID << 8 | 0x49) #define PM8550B_ADC5_GEN3_AMUX1_GPIO1_100K_PU (PM8550B_SID << 8 | 0x4a) #define PM8550B_ADC5_GEN3_AMUX2_GPIO5_100K_PU (PM8550B_SID << 8 | 0x4b) -#define PM8550B_ADC5_GEN3_AMUX3_GPIO5_100K_PU (PM8550B_SID << 8 | 0x4c) +#define PM8550B_ADC5_GEN3_AMUX3_GPIO6_100K_PU (PM8550B_SID << 8 | 0x4c) #define PM8550B_ADC5_GEN3_AMUX4_GPIO12_100K_PU (PM8550B_SID << 8 | 0x4d) #define PM8550B_ADC5_GEN3_USBC_MUX_100K_PU (PM8550B_SID << 8 | 0x53) @@ -90,7 +90,7 @@ #define PM8550B_ADC5_GEN3_VPH_PWR (PM8550B_SID << 8 | 0x8e) #define PM8550B_ADC5_GEN3_VBAT_SNS_QBG (PM8550B_SID << 8 | 0x8f) #define PM8550B_ADC5_GEN3_VBAT_SNS_CHGR (PM8550B_SID << 8 | 0x94) -#define PM8550B_ADC5_GEN3_VREF_2S_MID_QBG (PM8550B_SID << 8 | 0x96) +#define PM8550B_ADC5_GEN3_VBAT_2S_MID_QBG (PM8550B_SID << 8 | 0x96) #define PM8550B_ADC5_GEN3_VBAT_2S_MID_CHGR (PM8550B_SID << 8 | 0x9d) #endif /* _DT_BINDINGS_QCOM_SPMI_VADC_PM8550B_H */ From 48efaf8e968c09c5a3f10bd0166e90928081eeaf Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Wed, 9 Feb 2022 12:12:08 -0800 Subject: [PATCH 07/17] iio: adc: qcom-spmi-adc5-gen3: Fix some indentation Fix the indentation to keep it uniform and readable. Change-Id: I73da8941c72857a9f63dca3e8085873413b3a1f2 Signed-off-by: Subbaraman Narayanamurthy --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 120 +++++++++++++------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index c6c3f6a1ba7d..955f7ef04d83 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -175,33 +175,33 @@ struct adc5_base_data { * @high_thr_voltage: upper threshold voltage for TM. * @low_thr_voltage: lower threshold voltage for TM. * @last_temp: last temperature that caused threshold violation, - * or a thermal TM channel. + * or a thermal TM channel. * @last_temp_set: indicates if last_temp is stored. * @req_wq: workqueue holding queued notification tasks for a non-thermal - * TM channel. + * TM channel. * @work: scheduled work for handling non-thermal TM client notification. * @thr_list: list of client thresholds configured for non-thermal TM channel. * @adc_rscale_fn: reverse scaling function to convert voltage to raw code - * for non-thermal TM channels. + * for non-thermal TM channels. */ struct adc5_channel_prop { - unsigned int channel; - enum adc5_cal_method cal_method; - unsigned int decimation; - unsigned int sid; - unsigned int prescale; - unsigned int hw_settle_time; - unsigned int avg_samples; - unsigned int sdam_index; + unsigned int channel; + enum adc5_cal_method cal_method; + unsigned int decimation; + unsigned int sid; + unsigned int prescale; + unsigned int hw_settle_time; + unsigned int avg_samples; + unsigned int sdam_index; - enum vadc_scale_fn_type scale_fn_type; - const char *datasheet_name; + enum vadc_scale_fn_type scale_fn_type; + const char *datasheet_name; struct adc5_chip *chip; /* TM properties */ - int adc_tm; - unsigned int tm_chan_index; - unsigned int timer; + int adc_tm; + unsigned int tm_chan_index; + unsigned int timer; struct thermal_zone_device *tzd; int high_thr_en; int low_thr_en; @@ -209,8 +209,8 @@ struct adc5_channel_prop { bool low_thr_triggered; int64_t high_thr_voltage; int64_t low_thr_voltage; - int last_temp; - bool last_temp_set; + int last_temp; + bool last_temp_set; struct workqueue_struct *req_wq; struct work_struct work; struct list_head thr_list; @@ -223,7 +223,7 @@ struct adc5_channel_prop { * @dev: SPMI ADC5 device. * @base: pointer to array of ADC peripheral base and interrupt. * @debug_base: base address for the reserved ADC peripheral, - * to dump for debug purposes alone. + * to dump for debug purposes alone. * @num_sdams: number of SDAMs being used. * @nchannels: number of ADC channels. * @chan_props: array of ADC channel properties. @@ -231,28 +231,28 @@ struct adc5_channel_prop { * @complete: ADC result notification after interrupt is received. * @lock: ADC lock for access to the peripheral. * @data: software configuration data. + * @n_tm_channels: number of ADC channels used for TM measurements. * @list: list item, used to add this device to gloal list of ADC_TM devices. * @device_list: pointer to list of ADC_TM devices. - * @n_tm_channels: number of ADC channels used for TM measurements. * @tm_handler_work: scheduled work for handling TM threshold violation. */ struct adc5_chip { - struct regmap *regmap; - struct device *dev; - struct adc5_base_data *base; - u16 debug_base; - unsigned int num_sdams; - unsigned int nchannels; + struct regmap *regmap; + struct device *dev; + struct adc5_base_data *base; + u16 debug_base; + unsigned int num_sdams; + unsigned int nchannels; struct adc5_channel_prop *chan_props; - struct iio_chan_spec *iio_chans; - struct completion complete; - struct mutex lock; - const struct adc5_data *data; + struct iio_chan_spec *iio_chans; + struct completion complete; + struct mutex lock; + const struct adc5_data *data; /* TM properties */ - unsigned int n_tm_channels; + unsigned int n_tm_channels; struct list_head list; struct list_head *device_list; - struct work_struct tm_handler_work; + struct work_struct tm_handler_work; }; static const struct u32_fract adc5_prescale_ratios[] = { @@ -424,7 +424,7 @@ static int adc5_gen3_configure(struct adc5_chip *adc, #define ADC5_GEN3_HS_DELAY_MIN_US 100 #define ADC5_GEN3_HS_DELAY_MAX_US 110 -#define ADC5_GEN3_HS_RETRY_COUNT 20 +#define ADC5_GEN3_HS_RETRY_COUNT 20 static int adc5_gen3_poll_wait_hs(struct adc5_chip *adc, struct adc5_channel_prop *prop) { @@ -511,8 +511,8 @@ static int adc5_gen3_do_conversion(struct adc5_chip *adc, return ret; } -#define ADC_OFFSET_DUMP 8 -#define ADC_SDAM_REG_DUMP 32 +#define ADC_OFFSET_DUMP 8 +#define ADC_SDAM_REG_DUMP 32 static void adc5_gen3_dump_register(struct adc5_chip *adc, unsigned int offset) { int i, rc; @@ -1379,51 +1379,51 @@ struct adc5_channels { static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = { [ADC5_GEN3_OFFSET_REF] = ADC5_CHAN_VOLT("ref_gnd", 0, - SCALE_HW_CALIB_DEFAULT) + SCALE_HW_CALIB_DEFAULT) [ADC5_GEN3_1P25VREF] = ADC5_CHAN_VOLT("vref_1p25", 0, - SCALE_HW_CALIB_DEFAULT) + SCALE_HW_CALIB_DEFAULT) [ADC5_GEN3_VPH_PWR] = ADC5_CHAN_VOLT("vph_pwr", 1, - SCALE_HW_CALIB_DEFAULT) - [ADC5_GEN3_VBAT_SNS_QBG] = ADC5_CHAN_VOLT("vbat_sns", 1, - SCALE_HW_CALIB_DEFAULT) - [ADC5_GEN3_AMUX3_THM] = ADC5_CHAN_TEMP("smb_temp", 0, - SCALE_HW_CALIB_PM7_SMB_TEMP) + SCALE_HW_CALIB_DEFAULT) + [ADC5_GEN3_VBAT_SNS_QBG] = ADC5_CHAN_VOLT("vbat_sns", 1, + SCALE_HW_CALIB_DEFAULT) + [ADC5_GEN3_AMUX3_THM] = ADC5_CHAN_TEMP("smb_temp", 0, + SCALE_HW_CALIB_PM7_SMB_TEMP) [ADC5_GEN3_CHG_TEMP] = ADC5_CHAN_TEMP("chg_temp", 0, - SCALE_HW_CALIB_PM7_CHG_TEMP) + SCALE_HW_CALIB_PM7_CHG_TEMP) [ADC5_GEN3_USB_SNS_V_16] = ADC5_CHAN_TEMP("usb_sns_v_div_16", 3, - SCALE_HW_CALIB_DEFAULT) + SCALE_HW_CALIB_DEFAULT) [ADC5_GEN3_VIN_DIV16_MUX] = ADC5_CHAN_TEMP("vin_div_16", 3, - SCALE_HW_CALIB_DEFAULT) + SCALE_HW_CALIB_DEFAULT) [ADC5_GEN3_IIN_FB] = ADC5_CHAN_CUR("iin_fb", 4, - SCALE_HW_CALIB_CUR) + SCALE_HW_CALIB_CUR) [ADC5_GEN3_ICHG_SMB] = ADC5_CHAN_CUR("ichg_smb", 5, - SCALE_HW_CALIB_CUR) + SCALE_HW_CALIB_CUR) [ADC5_GEN3_IIN_SMB] = ADC5_CHAN_CUR("iin_smb", 6, - SCALE_HW_CALIB_CUR) + SCALE_HW_CALIB_CUR) [ADC5_GEN3_ICHG_FB] = ADC5_CHAN_CUR("ichg_fb", 7, - SCALE_HW_CALIB_CUR_RAW) + SCALE_HW_CALIB_CUR_RAW) [ADC5_GEN3_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0, - SCALE_HW_CALIB_PMIC_THERM_PM7) + SCALE_HW_CALIB_PMIC_THERM_PM7) [ADC5_GEN3_AMUX1_THM_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_pu2", 0, - SCALE_HW_CALIB_THERM_100K_PU_PM7) + SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC5_GEN3_AMUX2_THM_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_pu2", 0, - SCALE_HW_CALIB_THERM_100K_PU_PM7) + SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC5_GEN3_AMUX3_THM_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_pu2", 0, - SCALE_HW_CALIB_THERM_100K_PU_PM7) + SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC5_GEN3_AMUX4_THM_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_pu2", 0, - SCALE_HW_CALIB_THERM_100K_PU_PM7) + SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC5_GEN3_AMUX5_THM_100K_PU] = ADC5_CHAN_TEMP("amux_thm5_pu2", 0, - SCALE_HW_CALIB_THERM_100K_PU_PM7) + SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC5_GEN3_AMUX6_THM_100K_PU] = ADC5_CHAN_TEMP("amux_thm6_pu2", 0, - SCALE_HW_CALIB_THERM_100K_PU_PM7) + SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC5_GEN3_AMUX1_GPIO_100K_PU] = ADC5_CHAN_TEMP("amux1_gpio_pu2", 0, - SCALE_HW_CALIB_THERM_100K_PU_PM7) + SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC5_GEN3_AMUX2_GPIO_100K_PU] = ADC5_CHAN_TEMP("amux2_gpio_pu2", 0, - SCALE_HW_CALIB_THERM_100K_PU_PM7) + SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC5_GEN3_AMUX3_GPIO_100K_PU] = ADC5_CHAN_TEMP("amux3_gpio_pu2", 0, - SCALE_HW_CALIB_THERM_100K_PU_PM7) + SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC5_GEN3_AMUX4_GPIO_100K_PU] = ADC5_CHAN_TEMP("amux4_gpio_pu2", 0, - SCALE_HW_CALIB_THERM_100K_PU_PM7) + SCALE_HW_CALIB_THERM_100K_PU_PM7) }; static int adc5_get_dt_channel_data(struct adc5_chip *adc, From 7ad32f5546ebc4fbc58925b063ec604c2580de2b Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Mon, 7 Feb 2022 16:23:30 -0800 Subject: [PATCH 08/17] iio: adc: qcom-spmi-adc5-gen3: Remove adc5_prescaling_from_dt() adc5_prescaling_from_dt() is not needed as that is replaced with qcom_adc5_prescaling_from_dt() in qcom-vadc-common.c. Since adc5_prescale_ratios[] is also used from qcom-vadc-common.c and not needed in qcom-spmi-adc5-gen3.c, remove it. With the above change, adc5_chans_pmic[] needs to be updated with the right indices. Update it. Change-Id: Ibeb8ef6d9436ae448aadc9a99e5d0ef69767ac47 Signed-off-by: Subbaraman Narayanamurthy [quic_collinsd@quicinc.com: fixed minor merge conflict] Signed-off-by: David Collins --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 42 +++++---------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index 955f7ef04d83..d28ca099f9aa 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -255,18 +255,6 @@ struct adc5_chip { struct work_struct tm_handler_work; }; -static const struct u32_fract adc5_prescale_ratios[] = { - { .numerator = 1, .denominator = 1 }, - { .numerator = 1, .denominator = 3 }, - { .numerator = 1, .denominator = 6 }, - { .numerator = 1, .denominator = 16 }, - /* Prescale ratios for current channels below */ - { .numerator = 32, .denominator = 100 }, /* IIN_FB */ - { .numerator = 14, .denominator = 100 }, /* ICHG_SMB */ - { .numerator = 28, .denominator = 100 }, /* IIN_SMB */ - { .numerator = 1000, .denominator = 305185 }, /* ICHG_FB */ -}; - static int adc5_read(struct adc5_chip *adc, unsigned int sdam_index, u16 offset, u8 *data, int len) { int ret; @@ -290,22 +278,6 @@ static int adc5_write(struct adc5_chip *adc, unsigned int sdam_index, u16 offset return ret; } -static int adc5_prescaling_from_dt(u32 numerator, u32 denominator) -{ - unsigned int pre; - - for (pre = 0; pre < ARRAY_SIZE(adc5_prescale_ratios); pre++) { - if (adc5_prescale_ratios[pre].numerator == numerator && - adc5_prescale_ratios[pre].denominator == denominator) - break; - } - - if (pre == ARRAY_SIZE(adc5_prescale_ratios)) - return -ENOENT; - - return pre; -} - static int adc5_hw_settle_time_from_dt(u32 value, const unsigned int *hw_settle) { @@ -1390,17 +1362,17 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = { SCALE_HW_CALIB_PM7_SMB_TEMP) [ADC5_GEN3_CHG_TEMP] = ADC5_CHAN_TEMP("chg_temp", 0, SCALE_HW_CALIB_PM7_CHG_TEMP) - [ADC5_GEN3_USB_SNS_V_16] = ADC5_CHAN_TEMP("usb_sns_v_div_16", 3, + [ADC5_GEN3_USB_SNS_V_16] = ADC5_CHAN_TEMP("usb_sns_v_div_16", 8, SCALE_HW_CALIB_DEFAULT) - [ADC5_GEN3_VIN_DIV16_MUX] = ADC5_CHAN_TEMP("vin_div_16", 3, + [ADC5_GEN3_VIN_DIV16_MUX] = ADC5_CHAN_TEMP("vin_div_16", 8, SCALE_HW_CALIB_DEFAULT) - [ADC5_GEN3_IIN_FB] = ADC5_CHAN_CUR("iin_fb", 4, + [ADC5_GEN3_IIN_FB] = ADC5_CHAN_CUR("iin_fb", 10, SCALE_HW_CALIB_CUR) - [ADC5_GEN3_ICHG_SMB] = ADC5_CHAN_CUR("ichg_smb", 5, + [ADC5_GEN3_ICHG_SMB] = ADC5_CHAN_CUR("ichg_smb", 11, SCALE_HW_CALIB_CUR) - [ADC5_GEN3_IIN_SMB] = ADC5_CHAN_CUR("iin_smb", 6, + [ADC5_GEN3_IIN_SMB] = ADC5_CHAN_CUR("iin_smb", 10, SCALE_HW_CALIB_CUR) - [ADC5_GEN3_ICHG_FB] = ADC5_CHAN_CUR("ichg_fb", 7, + [ADC5_GEN3_ICHG_FB] = ADC5_CHAN_CUR("ichg_fb", 14, SCALE_HW_CALIB_CUR_RAW) [ADC5_GEN3_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0, SCALE_HW_CALIB_PMIC_THERM_PM7) @@ -1483,7 +1455,7 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc, ret = of_property_read_u32_array(node, "qcom,pre-scaling", varr, 2); if (!ret) { - ret = adc5_prescaling_from_dt(varr[0], varr[1]); + ret = qcom_adc5_prescaling_from_dt(varr[0], varr[1]); if (ret < 0) { dev_err(dev, "%02x invalid pre-scaling <%d %d>\n", chan, varr[0], varr[1]); From 2d1c9eacee1a4fcc442329e212d4ed46814d6aaa Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Thu, 10 Feb 2022 13:34:43 -0800 Subject: [PATCH 09/17] iio: adc: qcom-spmi-adc5-gen3: Fix SID config when reading ADC channel Currently, when reading an ADC channel the SID is always configured to 0. This is causing incorrect readings for ADC and ADC TM channels. Fix this. Change-Id: If6332c6ec83f04ce4294df27e5bdb784cc5d23be Signed-off-by: Anjelique Melendez --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index d28ca099f9aa..9916c01c48ad 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -55,7 +55,7 @@ static LIST_HEAD(adc_tm_device_list); #define ADC5_GEN3_CONV_ERR_CLR_REQ BIT(0) #define ADC5_GEN3_SID 0x4f -#define ADC5_GEN3_SID_MASK 0xf +#define ADC5_GEN3_SID_MASK GENMASK(3, 0) #define ADC5_GEN3_PERPH_CH 0x50 #define ADC5_GEN3_CHAN_CONV_REQ BIT(7) @@ -357,8 +357,7 @@ static int adc5_gen3_configure(struct adc5_chip *adc, return ret; /* Write SID */ - buf[0] &= (u8) ~ADC5_GEN3_SID_MASK; - buf[0] &= prop->sid; + buf[0] = prop->sid & ADC5_GEN3_SID_MASK; /* * Use channel 0 by default for immediate conversion and @@ -821,8 +820,7 @@ static int adc_tm5_gen3_configure(struct adc5_channel_prop *prop) return ret; /* Write SID */ - buf[0] &= (u8) ~ADC5_GEN3_SID_MASK; - buf[0] &= prop->sid; + buf[0] = prop->sid & ADC5_GEN3_SID_MASK; /* * Select TM channel and indicate there is an actual From bb50d6564d76fd60eb81420f4a62ad948c0d4011 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Tue, 15 Feb 2022 10:39:40 -0800 Subject: [PATCH 10/17] iio: adc: qcom-spmi-adc5-gen3: Fix order of adc5_gen3_probe() Currently adc5_gen3_probe() registers thermal zone devices and then registers interrupt handlers. While registering the thermal zones the ADC5 GEN3 TM get/set callbacks are called by thermal framework that relies on interrupt completion. Since interrupts have not been registered the callbacks will time out. Fix this and add error handling for thermal zone registration. Change-Id: I3ad94211f7831c94b0847fda549295ecfebcb90b Signed-off-by: Anjelique Melendez --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index 9916c01c48ad..e1eb6a96b667 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -1300,13 +1300,13 @@ static int adc_tm_register_tzd(struct adc5_chip *adc) default: pr_err("Invalid ADC_TM type:%d for dt_ch:%d\n", adc->chan_props[i].adc_tm, adc->chan_props[i].channel); - continue; + return -EINVAL; } if (IS_ERR(tzd)) { pr_err("Error registering TZ zone:%ld for dt_ch:%d\n", PTR_ERR(tzd), adc->chan_props[i].channel); - continue; + return PTR_ERR(tzd); } adc->chan_props[i].tzd = tzd; } @@ -1700,8 +1700,6 @@ static int adc5_gen3_probe(struct platform_device *pdev) goto fail; } - adc_tm_register_tzd(adc); - for (i = 0; i < adc->num_sdams; i++) { ret = devm_request_irq(dev, adc->base[i].irq, adc5_gen3_isr, 0, adc->base[i].irq_name, adc); @@ -1709,6 +1707,10 @@ static int adc5_gen3_probe(struct platform_device *pdev) goto fail; } + ret = adc_tm_register_tzd(adc); + if (ret < 0) + goto fail; + if (adc->n_tm_channels) INIT_WORK(&adc->tm_handler_work, tm_handler_work); From b7b22a2a3078ee8d2dcb1acf66915019e2680965 Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Wed, 2 Mar 2022 20:44:52 -0800 Subject: [PATCH 11/17] dt-bindings: iio: qcom,spmi-vadc: add ADC5_GEN3_TEMP_ALARM_LITE channel Add ADC5_GEN3_TEMP_ALARM_LITE channel id that can be read from PM8550B PMIC. Also, update ADC5_GEN3_ICHG_SMB channel that was using the same channel id before. Change-Id: Ic8d69fc651abe73ab11a8086876d2d2dea686542 Signed-off-by: Subbaraman Narayanamurthy --- include/dt-bindings/iio/qcom,spmi-vadc.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/dt-bindings/iio/qcom,spmi-vadc.h b/include/dt-bindings/iio/qcom,spmi-vadc.h index f04ab1a7e131..335426998c08 100644 --- a/include/dt-bindings/iio/qcom,spmi-vadc.h +++ b/include/dt-bindings/iio/qcom,spmi-vadc.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2012-2014,2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _DT_BINDINGS_QCOM_SPMI_VADC_H @@ -323,8 +324,9 @@ #define ADC5_GEN3_VIN_DIV16_MUX 0x12 #define ADC5_GEN3_VREF_BAT_THERM 0x15 #define ADC5_GEN3_IIN_FB 0x17 -#define ADC5_GEN3_ICHG_SMB 0x18 +#define ADC5_GEN3_TEMP_ALARM_LITE 0x18 #define ADC5_GEN3_IIN_SMB 0x19 +#define ADC5_GEN3_ICHG_SMB 0x1b #define ADC5_GEN3_ICHG_FB 0xa1 /* 30k pull-up1 */ From d43304f631291255be42434a936c781ab9b0d740 Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Wed, 2 Mar 2022 20:48:02 -0800 Subject: [PATCH 12/17] iio: adc: qcom-spmi-adc5-gen3: Add TEMP_ALARM_LITE to adc5_chans_pmic[] Add TEMP_ALARM_LITE channel mapping so that the proper scaling function can be used with ADC code obtained after the conversion. Change-Id: I4ad0564ba4e4bd3d8409e3923d4b0ad5f0395503 Signed-off-by: Subbaraman Narayanamurthy --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index e1eb6a96b667..dc61e6342047 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -1374,6 +1374,8 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = { SCALE_HW_CALIB_CUR_RAW) [ADC5_GEN3_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0, SCALE_HW_CALIB_PMIC_THERM_PM7) + [ADC5_GEN3_TEMP_ALARM_LITE] = ADC5_CHAN_TEMP("die_temp_lite", 0, + SCALE_HW_CALIB_PMIC_THERM_PM7) [ADC5_GEN3_AMUX1_THM_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC5_GEN3_AMUX2_THM_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_pu2", 0, From 23dbb3507882d984bc3f15a71155a64b104fb908 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Wed, 9 Mar 2022 13:00:47 -0800 Subject: [PATCH 13/17] iio: adc: qcom-spmi-adc5-gen3: Fix __tm_handler_work() loop conditions Currently __tm_handler_work() assumes that each element in chan_props[] represents 1 SDAM register. However, chan_props[] has an element for every ADC and ADC TM channel. Since every ADC channel shares the same SDAM register the loop within __tm_handler_work() has incorrect conditions. Fix this. While at it, remove __tm_handler_work() which was invoked for every SDAM as tm_handler_work() goes through all channels. Change-Id: I5f3444ab831ff2067a1a53f49dea0c5dbbdc8758 Signed-off-by: Anjelique Melendez --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 115 ++++++++++++-------------- 1 file changed, 53 insertions(+), 62 deletions(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index dc61e6342047..0d39f047e417 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -592,50 +592,15 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) return IRQ_NONE; } -static void __tm_handler_work(struct adc5_chip *adc, unsigned int sdam_index) +static void tm_handler_work(struct work_struct *work) { struct adc5_channel_prop *chan_prop; u8 tm_status[2], buf[16], val; - int ret, i; + int ret, i, sdam_index = -1; + struct adc5_chip *adc = container_of(work, struct adc5_chip, + tm_handler_work); - mutex_lock(&adc->lock); - - ret = adc5_read(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS, tm_status, 2); - if (ret < 0) { - pr_err("adc read TM status failed with %d\n", ret); - goto work_unlock; - } - - ret = adc5_write(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS_CLR, tm_status, 2); - if (ret < 0) { - pr_err("adc write TM status failed with %d\n", ret); - goto work_unlock; - } - - /* To indicate conversion request is only to clear a status */ - val = 0; - ret = adc5_write(adc, sdam_index, ADC5_GEN3_PERPH_CH, &val, 1); - if (ret < 0) { - pr_err("adc write status clear conv_req failed with %d\n", ret); - goto work_unlock; - } - - val = ADC5_GEN3_CONV_REQ_REQ; - ret = adc5_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &val, 1); - if (ret < 0) { - pr_err("adc write conv_req failed with %d\n", ret); - goto work_unlock; - } - - ret = adc5_read(adc, sdam_index, ADC5_GEN3_CH0_DATA0, buf, sizeof(buf)); - if (ret < 0) { - pr_err("adc read data failed with %d\n", ret); - goto work_unlock; - } - - mutex_unlock(&adc->lock); - - for (i = sdam_index * 8; i < (sdam_index + 1) * 8; i++) { + for (i = 0; i < adc->nchannels; i++) { bool upper_set = false, lower_set = false; u8 data_low = 0, data_high = 0; u16 code = 0; @@ -643,10 +608,47 @@ static void __tm_handler_work(struct adc5_chip *adc, unsigned int sdam_index) chan_prop = &adc->chan_props[i]; offset = chan_prop->tm_chan_index; - if (!chan_prop->adc_tm) + + if (chan_prop->adc_tm != ADC_TM && chan_prop->adc_tm != ADC_TM_NON_THERMAL) continue; mutex_lock(&adc->lock); + if (chan_prop->sdam_index != sdam_index) { + sdam_index = chan_prop->sdam_index; + ret = adc5_read(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS, tm_status, 2); + if (ret < 0) { + pr_err("adc read TM status failed with %d\n", ret); + goto work_unlock; + } + + ret = adc5_write(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS_CLR, tm_status, 2); + if (ret < 0) { + pr_err("adc write TM status failed with %d\n", ret); + goto work_unlock; + } + + /* To indicate conversion request is only to clear a status */ + val = 0; + ret = adc5_write(adc, sdam_index, ADC5_GEN3_PERPH_CH, &val, 1); + if (ret < 0) { + pr_err("adc write status clear conv_req failed with %d\n", ret); + goto work_unlock; + } + + val = ADC5_GEN3_CONV_REQ_REQ; + ret = adc5_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &val, 1); + if (ret < 0) { + pr_err("adc write conv_req failed with %d\n", ret); + goto work_unlock; + } + + ret = adc5_read(adc, sdam_index, ADC5_GEN3_CH0_DATA0, buf, sizeof(buf)); + if (ret < 0) { + pr_err("adc read data failed with %d\n", ret); + goto work_unlock; + } + } + if ((tm_status[0] & BIT(offset)) && (chan_prop->high_thr_en)) upper_set = true; @@ -703,16 +705,6 @@ static void __tm_handler_work(struct adc5_chip *adc, unsigned int sdam_index) mutex_unlock(&adc->lock); } -static void tm_handler_work(struct work_struct *work) -{ - int i; - struct adc5_chip *adc = container_of(work, struct adc5_chip, - tm_handler_work); - - for (i = 0; i < adc->num_sdams; i++) - __tm_handler_work(adc, i); -} - static int adc5_gen3_of_xlate(struct iio_dev *indio_dev, const struct of_phandle_args *iiospec) { @@ -1575,7 +1567,7 @@ static int adc5_get_dt_data(struct adc5_chip *adc, struct device_node *node) { const struct adc5_channels *adc_chan; struct iio_chan_spec *iio_chan; - struct adc5_channel_prop prop, *chan_props; + struct adc5_channel_prop *chan_props; struct device_node *child; unsigned int index = 0; const struct of_device_id *id; @@ -1607,21 +1599,20 @@ static int adc5_get_dt_data(struct adc5_chip *adc, struct device_node *node) adc->data = data; for_each_available_child_of_node(node, child) { - ret = adc5_get_dt_channel_data(adc, &prop, child, data); + ret = adc5_get_dt_channel_data(adc, chan_props, child, data); if (ret < 0) { of_node_put(child); return ret; } - prop.chip = adc; - if (prop.scale_fn_type == -EINVAL) - prop.scale_fn_type = - data->adc_chans[prop.channel].scale_fn_type; - *chan_props = prop; - adc_chan = &data->adc_chans[prop.channel]; - iio_chan->channel = prop.channel; - iio_chan->datasheet_name = prop.datasheet_name; - iio_chan->extend_name = prop.datasheet_name; + chan_props->chip = adc; + if (chan_props->scale_fn_type == -EINVAL) + chan_props->scale_fn_type = + data->adc_chans[chan_props->channel].scale_fn_type; + adc_chan = &data->adc_chans[chan_props->channel]; + iio_chan->channel = chan_props->channel; + iio_chan->datasheet_name = chan_props->datasheet_name; + iio_chan->extend_name = chan_props->datasheet_name; iio_chan->info_mask_separate = adc_chan->info_mask; iio_chan->type = adc_chan->type; iio_chan->address = index; From da7e8fbcc1ea0f42dcc3779eb9abce314a61ed15 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Wed, 6 Apr 2022 11:56:32 -0700 Subject: [PATCH 14/17] dt-bindings: iio: add ICHG_FB channel on PM8550B Add ICHG_FB channel on PM8550B. Change-Id: If8d229673442745d4fffd7b31120ef1ed9f9b1b3 Signed-off-by: Anjelique Melendez --- include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h index e4c7d4bb7a64..8c2604b7238a 100644 --- a/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h +++ b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-pm8550b.h @@ -39,6 +39,7 @@ #define PM8550B_ADC5_GEN3_SMB_ICHG (PM8550B_SID << 8 | 0x1b) #define PM8550B_ADC5_GEN3_SMB_TEMP_I (PM8550B_SID << 8 | 0x1e) #define PM8550B_ADC5_GEN3_CHG_TEMP_I (PM8550B_SID << 8 | 0x1f) +#define PM8550B_ADC5_GEN3_ICHG_FB (PM8550B_SID << 8 | 0xa1) /* 30k pull-up */ #define PM8550B_ADC5_GEN3_AMUX_THM1_BATT_THERM_30K_PU (PM8550B_SID << 8 | 0x24) From c9265a04861c6aae3cae7bfef62cc42cc8943b3c Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Wed, 6 Apr 2022 11:51:52 -0700 Subject: [PATCH 15/17] iio: qcom-spmi-adc5-gen3: Update scaling index of ICHG_FB channel Update scaling index of ICHG_FB channel used in ADC5 GEN3. Change-Id: Iaa17e7c7a44288091818d28d6e0286d46f0eea6d Signed-off-by: Anjelique Melendez [quic_collinsd@quicinc.com: changed prescale "num" and "den" to "numerator" and "denominator" respectively] Signed-off-by: David Collins --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 2 +- drivers/iio/adc/qcom-vadc-common.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index 0d39f047e417..89935948b909 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -1362,7 +1362,7 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = { SCALE_HW_CALIB_CUR) [ADC5_GEN3_IIN_SMB] = ADC5_CHAN_CUR("iin_smb", 10, SCALE_HW_CALIB_CUR) - [ADC5_GEN3_ICHG_FB] = ADC5_CHAN_CUR("ichg_fb", 14, + [ADC5_GEN3_ICHG_FB] = ADC5_CHAN_CUR("ichg_fb", 16, SCALE_HW_CALIB_CUR_RAW) [ADC5_GEN3_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0, SCALE_HW_CALIB_PMIC_THERM_PM7) diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c index 75af6bb3d49b..e46a4528b844 100644 --- a/drivers/iio/adc/qcom-vadc-common.c +++ b/drivers/iio/adc/qcom-vadc-common.c @@ -614,6 +614,8 @@ static const struct u32_fract adc5_prescale_ratios[] = { { .numerator = 640, .denominator = 4100 }, /* ICHG_SMB_new */ { .numerator = 1000, .denominator = 305185 }, /* ICHG_FB */ { .numerator = 1000, .denominator = 610370 }, /* ICHG_FB_2X */ + { .numerator = 1000, .denominator = 366220 }, /* ICHG_FB ADC5_GEN3 */ + { .numerator = 1000, .denominator = 732440 }, /* ICHG_FB_2X ADC5_GEN3 */ }; static int qcom_vadc_scale_hw_calib_volt( From 88d5476b3002d24b8268ad7d252ec24a64be4365 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Wed, 6 Apr 2022 12:02:11 -0700 Subject: [PATCH 16/17] dt-bindings: iio: Add the ADC5 GEN3 Channel info for SMB139x Add the ADC5 GEN3 channels used by SMB139x. Change-Id: Ibdf37c90397ae10a87f7607ebb1ddc2445d698c7 Signed-off-by: Anjelique Melendez --- .../iio/qcom,spmi-adc5-gen3-smb139x.h | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 include/dt-bindings/iio/qcom,spmi-adc5-gen3-smb139x.h diff --git a/include/dt-bindings/iio/qcom,spmi-adc5-gen3-smb139x.h b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-smb139x.h new file mode 100644 index 000000000000..1a63286c1167 --- /dev/null +++ b/include/dt-bindings/iio/qcom,spmi-adc5-gen3-smb139x.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_GEN3_SMB139X_H +#define _DT_BINDINGS_QCOM_SPMI_VADC_GEN3_SMB139X_H + +#ifndef SMB1394_1_SID +#define SMB1394_1_SID 0x09 +#endif + +#ifndef SMB1394_2_SID +#define SMB1394_2_SID 0x0b +#endif + +#define SMB1394_1_ADC5_GEN3_SMB_TEMP (SMB1394_1_SID << 8 | 0x06) +#define SMB1394_1_ADC5_GEN3_IIN_SMB (SMB1394_1_SID << 8 | 0x19) +#define SMB1394_1_ADC5_GEN3_ICHG_SMB (SMB1394_1_SID << 8 | 0x1b) + +#define SMB1394_2_ADC5_GEN3_SMB_TEMP (SMB1394_2_SID << 8 | 0x06) +#define SMB1394_2_ADC5_GEN3_IIN_SMB (SMB1394_2_SID << 8 | 0x19) +#define SMB1394_2_ADC5_GEN3_ICHG_SMB (SMB1394_2_SID << 8 | 0x1b) + +#endif From 89afc38fb271a8319b9cd7a312c0a25b25eaf5ff Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Tue, 19 Apr 2022 15:52:47 -0700 Subject: [PATCH 17/17] iio: adc: qcom-spmi-adc5-gen3: Update ratios for SMB_* channels for ADC7 As per the hardware recommendation, add a ratio of 41/40 (i.e. numerator 40 and denominator 41 based on how it's used in our calculations) for the ADC channels that use SMB_TEMP pin because of the voltage divider circuit with a 1 K and 40 K in parallel. Change-Id: Id2d23c040fc3b38a826212b10152b6644918c96d Signed-off-by: Subbaraman Narayanamurthy --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index 89935948b909..145100c01ee8 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -1348,7 +1348,7 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = { SCALE_HW_CALIB_DEFAULT) [ADC5_GEN3_VBAT_SNS_QBG] = ADC5_CHAN_VOLT("vbat_sns", 1, SCALE_HW_CALIB_DEFAULT) - [ADC5_GEN3_AMUX3_THM] = ADC5_CHAN_TEMP("smb_temp", 0, + [ADC5_GEN3_AMUX3_THM] = ADC5_CHAN_TEMP("smb_temp", 9, SCALE_HW_CALIB_PM7_SMB_TEMP) [ADC5_GEN3_CHG_TEMP] = ADC5_CHAN_TEMP("chg_temp", 0, SCALE_HW_CALIB_PM7_CHG_TEMP) @@ -1358,9 +1358,9 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = { SCALE_HW_CALIB_DEFAULT) [ADC5_GEN3_IIN_FB] = ADC5_CHAN_CUR("iin_fb", 10, SCALE_HW_CALIB_CUR) - [ADC5_GEN3_ICHG_SMB] = ADC5_CHAN_CUR("ichg_smb", 11, + [ADC5_GEN3_ICHG_SMB] = ADC5_CHAN_CUR("ichg_smb", 13, SCALE_HW_CALIB_CUR) - [ADC5_GEN3_IIN_SMB] = ADC5_CHAN_CUR("iin_smb", 10, + [ADC5_GEN3_IIN_SMB] = ADC5_CHAN_CUR("iin_smb", 12, SCALE_HW_CALIB_CUR) [ADC5_GEN3_ICHG_FB] = ADC5_CHAN_CUR("ichg_fb", 16, SCALE_HW_CALIB_CUR_RAW)