Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'ib-iio-thermal-qcom-pmic5' into togreg Immutable branch to allow this base work to be merged into thermal.

+1338 -74
+151
Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5-gen3.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/iio/adc/qcom,spmi-adc5-gen3.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm's SPMI PMIC ADC5 Gen3 8 + 9 + maintainers: 10 + - Jishnu Prakash <jishnu.prakash@oss.qualcomm.com> 11 + 12 + description: | 13 + SPMI PMIC5 Gen3 voltage ADC (ADC) provides interface to clients to read 14 + voltage. It is a 16-bit sigma-delta ADC. It also performs the same thermal 15 + monitoring function as the existing ADC_TM devices. 16 + 17 + The interface is implemented on SDAM (Shared Direct Access Memory) peripherals 18 + on the master PMIC rather than a dedicated ADC peripheral. The number of PMIC 19 + SDAM peripherals allocated for ADC is not correlated with the PMIC used, it is 20 + programmed in FW (PBS) and is fixed per SOC, based on the SOC requirements. 21 + All boards using a particular (SOC + master PMIC) combination will have the 22 + same number of ADC SDAMs supported on that PMIC. 23 + 24 + properties: 25 + compatible: 26 + const: qcom,spmi-adc5-gen3 27 + 28 + reg: 29 + items: 30 + - description: SDAM0 base address in the SPMI PMIC register map 31 + - description: SDAM1 base address 32 + minItems: 1 33 + 34 + "#address-cells": 35 + const: 1 36 + 37 + "#size-cells": 38 + const: 0 39 + 40 + "#io-channel-cells": 41 + const: 1 42 + 43 + "#thermal-sensor-cells": 44 + const: 1 45 + 46 + interrupts: 47 + items: 48 + - description: SDAM0 end of conversion (EOC) interrupt 49 + - description: SDAM1 EOC interrupt 50 + minItems: 1 51 + 52 + patternProperties: 53 + "^channel@[0-9a-f]+$": 54 + type: object 55 + unevaluatedProperties: false 56 + $ref: /schemas/iio/adc/qcom,spmi-vadc-common.yaml 57 + description: 58 + Represents the external channels which are connected to the ADC. 59 + 60 + properties: 61 + qcom,decimation: 62 + enum: [ 85, 340, 1360 ] 63 + default: 1360 64 + 65 + qcom,hw-settle-time: 66 + enum: [ 15, 100, 200, 300, 400, 500, 600, 700, 67 + 1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000 ] 68 + default: 15 69 + 70 + qcom,avg-samples: 71 + enum: [ 1, 2, 4, 8, 16 ] 72 + default: 1 73 + 74 + qcom,adc-tm: 75 + description: 76 + ADC_TM is a threshold monitoring feature in HW which can be enabled 77 + on any ADC channel, to trigger an IRQ for threshold violation. In 78 + earlier ADC generations, it was implemented in a separate device 79 + (documented in Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm5.yaml.) 80 + In Gen3, this feature can be enabled in the same ADC device for any 81 + channel and threshold monitoring and IRQ triggering are handled in FW 82 + (PBS) instead of another dedicated HW block. 83 + This property indicates ADC_TM monitoring is done on this channel. 84 + type: boolean 85 + 86 + required: 87 + - compatible 88 + - reg 89 + - "#address-cells" 90 + - "#size-cells" 91 + - "#io-channel-cells" 92 + - interrupts 93 + 94 + additionalProperties: false 95 + 96 + examples: 97 + - | 98 + #include <dt-bindings/interrupt-controller/irq.h> 99 + 100 + pmic { 101 + #address-cells = <1>; 102 + #size-cells = <0>; 103 + 104 + adc@9000 { 105 + compatible = "qcom,spmi-adc5-gen3"; 106 + reg = <0x9000>, <0x9100>; 107 + interrupts = <0x0 0x90 0x1 IRQ_TYPE_EDGE_RISING>, 108 + <0x0 0x91 0x1 IRQ_TYPE_EDGE_RISING>; 109 + #address-cells = <1>; 110 + #size-cells = <0>; 111 + #io-channel-cells = <1>; 112 + #thermal-sensor-cells = <1>; 113 + 114 + /* PMK8550 Channel nodes */ 115 + channel@3 { 116 + reg = <0x3>; 117 + label = "pmk8550_die_temp"; 118 + qcom,pre-scaling = <1 1>; 119 + }; 120 + 121 + channel@44 { 122 + reg = <0x44>; 123 + label = "pmk8550_xo_therm"; 124 + qcom,pre-scaling = <1 1>; 125 + qcom,ratiometric; 126 + qcom,hw-settle-time = <200>; 127 + qcom,adc-tm; 128 + }; 129 + 130 + /* PM8550 Channel nodes */ 131 + channel@103 { 132 + reg = <0x103>; 133 + label = "pm8550_die_temp"; 134 + qcom,pre-scaling = <1 1>; 135 + }; 136 + 137 + /* PM8550B Channel nodes */ 138 + channel@78f { 139 + reg = <0x78f>; 140 + label = "pm8550b_vbat_sns_qbg"; 141 + qcom,pre-scaling = <1 3>; 142 + }; 143 + 144 + /* PM8550VS_C Channel nodes */ 145 + channel@203 { 146 + reg = <0x203>; 147 + label = "pm8550vs_c_die_temp"; 148 + qcom,pre-scaling = <1 1>; 149 + }; 150 + }; 151 + };
+84
Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc-common.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/iio/adc/qcom,spmi-vadc-common.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm Technologies, Inc. SPMI PMIC ADC channels 8 + 9 + maintainers: 10 + - Jishnu Prakash <jishnu.prakash@oss.qualcomm.com> 11 + 12 + description: 13 + This defines the common properties used to define Qualcomm VADC channels. 14 + 15 + properties: 16 + reg: 17 + description: 18 + ADC channel number (PMIC-specific for versions after PMIC5 ADC). 19 + maxItems: 1 20 + 21 + label: 22 + description: 23 + ADC input of the platform as seen in the schematics. 24 + For thermistor inputs connected to generic AMUX or GPIO inputs 25 + these can vary across platform for the same pins. Hence select 26 + the platform schematics name for this channel. 27 + 28 + qcom,decimation: 29 + $ref: /schemas/types.yaml#/definitions/uint32 30 + description: 31 + This parameter is used to decrease ADC sampling rate. 32 + Quicker measurements can be made by reducing decimation ratio. 33 + 34 + qcom,pre-scaling: 35 + $ref: /schemas/types.yaml#/definitions/uint32-array 36 + description: 37 + Used for scaling the channel input signal before the signal is 38 + fed to VADC. The configuration for this node is to know the 39 + pre-determined ratio and use it for post scaling. It is a pair of 40 + integers, denoting the numerator and denominator of the fraction by which 41 + input signal is multiplied. For example, <1 3> indicates the signal is scaled 42 + down to 1/3 of its value before ADC measurement. 43 + If property is not found default value depending on chip will be used. 44 + oneOf: 45 + - items: 46 + - const: 1 47 + - enum: [ 1, 3, 4, 6, 20, 8, 10, 16 ] 48 + - items: 49 + - const: 10 50 + - const: 81 51 + 52 + qcom,ratiometric: 53 + type: boolean 54 + description: | 55 + Channel calibration type. 56 + - For compatible property "qcom,spmi-vadc", if this property is 57 + specified VADC will use the VDD reference (1.8V) and GND for 58 + channel calibration. If property is not found, channel will be 59 + calibrated with 0.625V and 1.25V reference channels, also 60 + known as absolute calibration. 61 + - For other compatible properties, if this property is specified 62 + VADC will use the VDD reference (1.875V) and GND for channel 63 + calibration. If property is not found, channel will be calibrated 64 + with 0V and 1.25V reference channels, also known as absolute calibration. 65 + 66 + qcom,hw-settle-time: 67 + $ref: /schemas/types.yaml#/definitions/uint32 68 + description: | 69 + Time between AMUX getting configured and the ADC starting 70 + conversion. The 'hw_settle_time' is an index used from valid values 71 + and programmed in hardware to achieve the hardware settling delay. 72 + 73 + qcom,avg-samples: 74 + $ref: /schemas/types.yaml#/definitions/uint32 75 + description: | 76 + Number of samples to be used for measurement. 77 + Averaging provides the option to obtain a single measurement 78 + from the ADC that is an average of multiple samples. The value 79 + selected is 2^(value). 80 + 81 + required: 82 + - reg 83 + 84 + additionalProperties: true
+4 -74
Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
··· 15 15 voltage. The VADC is a 15-bit sigma-delta ADC. 16 16 SPMI PMIC5/PMIC7 voltage ADC (ADC) provides interface to clients to read 17 17 voltage. The VADC is a 16-bit sigma-delta ADC. 18 + Note that PMIC7 ADC is the generation between PMIC5 and PMIC5 Gen3 ADC, 19 + it can be considered like PMIC5 Gen2. 18 20 19 21 properties: 20 22 compatible: ··· 58 56 patternProperties: 59 57 "^channel@[0-9a-f]+$": 60 58 type: object 61 - additionalProperties: false 59 + unevaluatedProperties: false 62 60 description: | 63 61 Represents the external channels which are connected to the ADC. 64 62 For compatible property "qcom,spmi-vadc" following channels, also known as ··· 66 64 configuration nodes should be defined: 67 65 VADC_REF_625MV and/or VADC_SPARE1(based on PMIC version) VADC_REF_1250MV, 68 66 VADC_GND_REF and VADC_VDD_VADC. 69 - 70 - properties: 71 - reg: 72 - maxItems: 1 73 - description: | 74 - ADC channel number. 75 - See include/dt-bindings/iio/qcom,spmi-vadc.h 76 - For PMIC7 ADC, the channel numbers are specified separately per PMIC 77 - in the PMIC-specific files in include/dt-bindings/iio/. 78 - 79 - label: 80 - description: | 81 - ADC input of the platform as seen in the schematics. 82 - For thermistor inputs connected to generic AMUX or GPIO inputs 83 - these can vary across platform for the same pins. Hence select 84 - the platform schematics name for this channel. 85 - 86 - qcom,decimation: 87 - $ref: /schemas/types.yaml#/definitions/uint32 88 - description: | 89 - This parameter is used to decrease ADC sampling rate. 90 - Quicker measurements can be made by reducing decimation ratio. 91 - 92 - qcom,pre-scaling: 93 - description: | 94 - Used for scaling the channel input signal before the signal is 95 - fed to VADC. The configuration for this node is to know the 96 - pre-determined ratio and use it for post scaling. It is a pair of 97 - integers, denoting the numerator and denominator of the fraction by which 98 - input signal is multiplied. For example, <1 3> indicates the signal is scaled 99 - down to 1/3 of its value before ADC measurement. 100 - If property is not found default value depending on chip will be used. 101 - $ref: /schemas/types.yaml#/definitions/uint32-array 102 - oneOf: 103 - - items: 104 - - const: 1 105 - - enum: [ 1, 3, 4, 6, 20, 8, 10, 16 ] 106 - - items: 107 - - const: 10 108 - - const: 81 109 - 110 - qcom,ratiometric: 111 - description: | 112 - Channel calibration type. 113 - - For compatible property "qcom,spmi-vadc", if this property is 114 - specified VADC will use the VDD reference (1.8V) and GND for 115 - channel calibration. If property is not found, channel will be 116 - calibrated with 0.625V and 1.25V reference channels, also 117 - known as absolute calibration. 118 - - For compatible property "qcom,spmi-adc5", "qcom,spmi-adc7" and 119 - "qcom,spmi-adc-rev2", if this property is specified VADC will use 120 - the VDD reference (1.875V) and GND for channel calibration. If 121 - property is not found, channel will be calibrated with 0V and 1.25V 122 - reference channels, also known as absolute calibration. 123 - type: boolean 124 - 125 - qcom,hw-settle-time: 126 - $ref: /schemas/types.yaml#/definitions/uint32 127 - description: | 128 - Time between AMUX getting configured and the ADC starting 129 - conversion. The 'hw_settle_time' is an index used from valid values 130 - and programmed in hardware to achieve the hardware settling delay. 131 - 132 - qcom,avg-samples: 133 - $ref: /schemas/types.yaml#/definitions/uint32 134 - description: | 135 - Number of samples to be used for measurement. 136 - Averaging provides the option to obtain a single measurement 137 - from the ADC that is an average of multiple samples. The value 138 - selected is 2^(value). 139 - 140 - required: 141 - - reg 67 + $ref: /schemas/iio/adc/qcom,spmi-vadc-common.yaml 142 68 143 69 allOf: 144 70 - if:
+1
Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
··· 135 135 "^adc@[0-9a-f]+$": 136 136 type: object 137 137 oneOf: 138 + - $ref: /schemas/iio/adc/qcom,spmi-adc5-gen3.yaml# 138 139 - $ref: /schemas/iio/adc/qcom,spmi-iadc.yaml# 139 140 - $ref: /schemas/iio/adc/qcom,spmi-rradc.yaml# 140 141 - $ref: /schemas/iio/adc/qcom,spmi-vadc.yaml#
+26
drivers/iio/adc/Kconfig
··· 1366 1366 To compile this driver as a module, choose M here: the module will 1367 1367 be called qcom-spmi-adc5. 1368 1368 1369 + config QCOM_SPMI_ADC5_GEN3 1370 + tristate "Qualcomm Technologies Inc. SPMI PMIC5 GEN3 ADC" 1371 + depends on SPMI && THERMAL 1372 + select REGMAP_SPMI 1373 + select QCOM_VADC_COMMON 1374 + select AUXILIARY_BUS 1375 + help 1376 + IIO Voltage PMIC5 Gen3 ADC driver for Qualcomm Technologies Inc. 1377 + 1378 + The driver supports reading multiple channels. The ADC is a 16-bit 1379 + sigma-delta ADC. The hardware supports calibrated results for 1380 + conversion requests and clients include reading phone power supply 1381 + voltage, on board system thermistors connected to the PMIC ADC, 1382 + PMIC die temperature, charger temperature, battery current, USB 1383 + voltage input and voltage signals connected to supported PMIC GPIO 1384 + pins. The hardware supports internal pull-up for thermistors and can 1385 + choose between a 30k, 100k or 400k ohm pull up using the ADC channels. 1386 + 1387 + In addition, the same driver supports ADC thermal monitoring devices 1388 + too. They appear as thermal zones with multiple trip points. A thermal 1389 + client sets threshold temperature for both warm and cool trips and 1390 + gets updated when a threshold is reached. 1391 + 1392 + To compile this driver as a module, choose M here: the module will 1393 + be called qcom-spmi-adc5-gen3. 1394 + 1369 1395 config RCAR_GYRO_ADC 1370 1396 tristate "Renesas R-Car GyroADC driver" 1371 1397 depends on ARCH_RCAR_GEN2 || COMPILE_TEST
+1
drivers/iio/adc/Makefile
··· 116 116 obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o 117 117 obj-$(CONFIG_QCOM_PM8XXX_XOADC) += qcom-pm8xxx-xoadc.o 118 118 obj-$(CONFIG_QCOM_SPMI_ADC5) += qcom-spmi-adc5.o 119 + obj-$(CONFIG_QCOM_SPMI_ADC5_GEN3) += qcom-spmi-adc5-gen3.o 119 120 obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o 120 121 obj-$(CONFIG_QCOM_SPMI_RRADC) += qcom-spmi-rradc.o 121 122 obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
+860
drivers/iio/adc/qcom-spmi-adc5-gen3.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 + */ 5 + 6 + #include <linux/auxiliary_bus.h> 7 + #include <linux/bitfield.h> 8 + #include <linux/bits.h> 9 + #include <linux/cleanup.h> 10 + #include <linux/completion.h> 11 + #include <linux/container_of.h> 12 + #include <linux/delay.h> 13 + #include <linux/device.h> 14 + #include <linux/device/devres.h> 15 + #include <linux/dev_printk.h> 16 + #include <linux/err.h> 17 + #include <linux/export.h> 18 + #include <linux/iio/adc/qcom-adc5-gen3-common.h> 19 + #include <linux/iio/iio.h> 20 + #include <linux/interrupt.h> 21 + #include <linux/kernel.h> 22 + #include <linux/module.h> 23 + #include <linux/mod_devicetable.h> 24 + #include <linux/mutex.h> 25 + #include <linux/platform_device.h> 26 + #include <linux/property.h> 27 + #include <linux/regmap.h> 28 + #include <linux/types.h> 29 + #include <linux/unaligned.h> 30 + 31 + #define ADC5_GEN3_VADC_SDAM 0x0 32 + 33 + struct adc5_chip; 34 + 35 + /** 36 + * struct adc5_channel_prop - ADC channel structure 37 + * @common_props: structure with ADC channel properties (common to TM usage). 38 + * @adc_tm: indicates TM type if the channel is used for TM measurements. 39 + * @chip: pointer to top-level ADC device structure. 40 + */ 41 + struct adc5_channel_prop { 42 + struct adc5_channel_common_prop common_props; 43 + int adc_tm; 44 + struct adc5_chip *chip; 45 + }; 46 + 47 + /** 48 + * struct adc5_chip - ADC private structure. 49 + * @dev: SPMI ADC5 Gen3 device. 50 + * @dev_data: Top-level ADC device data. 51 + * @nchannels: number of ADC channels. 52 + * @chan_props: array of ADC channel properties. 53 + * @iio_chans: array of IIO channels specification. 54 + * @complete: ADC result notification after interrupt is received. 55 + * @lock: ADC lock for access to the peripheral, to prevent concurrent 56 + * requests from multiple clients. 57 + * @data: software configuration data. 58 + * @n_tm_channels: number of ADC channels used for TM measurements. 59 + * @handler: TM callback to be called for threshold violation interrupt 60 + * on first SDAM. 61 + * @tm_aux: pointer to auxiliary TM device. 62 + */ 63 + struct adc5_chip { 64 + struct device *dev; 65 + struct adc5_device_data dev_data; 66 + unsigned int nchannels; 67 + struct adc5_channel_prop *chan_props; 68 + struct iio_chan_spec *iio_chans; 69 + struct completion complete; 70 + struct mutex lock; 71 + const struct adc5_data *data; 72 + unsigned int n_tm_channels; 73 + void (*handler)(struct auxiliary_device *tm_aux); 74 + struct auxiliary_device *tm_aux; 75 + }; 76 + 77 + int adc5_gen3_read(struct adc5_device_data *adc, unsigned int sdam_index, 78 + u16 offset, u8 *data, int len) 79 + { 80 + return regmap_bulk_read(adc->regmap, 81 + adc->base[sdam_index].base_addr + offset, 82 + data, len); 83 + } 84 + EXPORT_SYMBOL_NS_GPL(adc5_gen3_read, "QCOM_SPMI_ADC5_GEN3"); 85 + 86 + int adc5_gen3_write(struct adc5_device_data *adc, unsigned int sdam_index, 87 + u16 offset, u8 *data, int len) 88 + { 89 + return regmap_bulk_write(adc->regmap, 90 + adc->base[sdam_index].base_addr + offset, 91 + data, len); 92 + } 93 + EXPORT_SYMBOL_NS_GPL(adc5_gen3_write, "QCOM_SPMI_ADC5_GEN3"); 94 + 95 + static int adc5_gen3_read_voltage_data(struct adc5_chip *adc, u16 *data) 96 + { 97 + u8 rslt[2]; 98 + int ret; 99 + 100 + ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, 101 + ADC5_GEN3_CH_DATA0(0), rslt, sizeof(rslt)); 102 + if (ret) 103 + return ret; 104 + 105 + *data = get_unaligned_le16(rslt); 106 + 107 + if (*data == ADC5_USR_DATA_CHECK) { 108 + dev_err(adc->dev, "Invalid data:%#x\n", *data); 109 + return -EINVAL; 110 + } 111 + 112 + dev_dbg(adc->dev, "voltage raw code:%#x\n", *data); 113 + 114 + return 0; 115 + } 116 + 117 + void adc5_gen3_update_dig_param(struct adc5_channel_common_prop *prop, u8 *data) 118 + { 119 + /* Update calibration select and decimation ratio select */ 120 + *data &= ~(ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK | ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK); 121 + *data |= FIELD_PREP(ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK, prop->cal_method); 122 + *data |= FIELD_PREP(ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK, prop->decimation); 123 + } 124 + EXPORT_SYMBOL_NS_GPL(adc5_gen3_update_dig_param, "QCOM_SPMI_ADC5_GEN3"); 125 + 126 + #define ADC5_GEN3_READ_CONFIG_REGS 7 127 + 128 + static int adc5_gen3_configure(struct adc5_chip *adc, 129 + struct adc5_channel_common_prop *prop) 130 + { 131 + u8 buf[ADC5_GEN3_READ_CONFIG_REGS]; 132 + u8 conv_req = 0; 133 + int ret; 134 + 135 + ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, ADC5_GEN3_SID, 136 + buf, sizeof(buf)); 137 + if (ret) 138 + return ret; 139 + 140 + /* Write SID */ 141 + buf[0] = FIELD_PREP(ADC5_GEN3_SID_MASK, prop->sid); 142 + 143 + /* 144 + * Use channel 0 by default for immediate conversion and to indicate 145 + * there is an actual conversion request 146 + */ 147 + buf[1] = ADC5_GEN3_CHAN_CONV_REQ | 0; 148 + 149 + buf[2] = ADC5_GEN3_TIME_IMMEDIATE; 150 + 151 + /* Digital param selection */ 152 + adc5_gen3_update_dig_param(prop, &buf[3]); 153 + 154 + /* Update fast average sample value */ 155 + buf[4] = FIELD_PREP(ADC5_GEN3_FAST_AVG_CTL_SAMPLES_MASK, 156 + prop->avg_samples) | ADC5_GEN3_FAST_AVG_CTL_EN; 157 + 158 + /* Select ADC channel */ 159 + buf[5] = prop->channel; 160 + 161 + /* Select HW settle delay for channel */ 162 + buf[6] = FIELD_PREP(ADC5_GEN3_HW_SETTLE_DELAY_MASK, 163 + prop->hw_settle_time_us); 164 + 165 + reinit_completion(&adc->complete); 166 + 167 + ret = adc5_gen3_write(&adc->dev_data, ADC5_GEN3_VADC_SDAM, ADC5_GEN3_SID, 168 + buf, sizeof(buf)); 169 + if (ret) 170 + return ret; 171 + 172 + conv_req = ADC5_GEN3_CONV_REQ_REQ; 173 + return adc5_gen3_write(&adc->dev_data, ADC5_GEN3_VADC_SDAM, 174 + ADC5_GEN3_CONV_REQ, &conv_req, sizeof(conv_req)); 175 + } 176 + 177 + /* 178 + * Worst case delay from PBS in readying handshake bit can be up to 15ms, when 179 + * PBS is busy running other simultaneous transactions, while in the best case, 180 + * it is already ready at this point. Assigning polling delay and retry count 181 + * accordingly. 182 + */ 183 + 184 + #define ADC5_GEN3_HS_DELAY_US 100 185 + #define ADC5_GEN3_HS_RETRY_COUNT 150 186 + 187 + int adc5_gen3_poll_wait_hs(struct adc5_device_data *adc, 188 + unsigned int sdam_index) 189 + { 190 + u8 conv_req = ADC5_GEN3_CONV_REQ_REQ; 191 + int ret, count; 192 + u8 status = 0; 193 + 194 + for (count = 0; count < ADC5_GEN3_HS_RETRY_COUNT; count++) { 195 + ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_HS, &status, sizeof(status)); 196 + if (ret) 197 + return ret; 198 + 199 + if (status == ADC5_GEN3_HS_READY) { 200 + ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_CONV_REQ, 201 + &conv_req, sizeof(conv_req)); 202 + if (ret) 203 + return ret; 204 + 205 + if (!conv_req) 206 + return 0; 207 + } 208 + 209 + fsleep(ADC5_GEN3_HS_DELAY_US); 210 + } 211 + 212 + pr_err("Setting HS ready bit timed out, sdam_index:%d, status:%#x\n", 213 + sdam_index, status); 214 + return -ETIMEDOUT; 215 + } 216 + EXPORT_SYMBOL_NS_GPL(adc5_gen3_poll_wait_hs, "QCOM_SPMI_ADC5_GEN3"); 217 + 218 + int adc5_gen3_status_clear(struct adc5_device_data *adc, 219 + int sdam_index, u16 offset, u8 *val, int len) 220 + { 221 + u8 value; 222 + int ret; 223 + 224 + ret = adc5_gen3_write(adc, sdam_index, offset, val, len); 225 + if (ret) 226 + return ret; 227 + 228 + /* To indicate conversion request is only to clear a status */ 229 + value = 0; 230 + ret = adc5_gen3_write(adc, sdam_index, ADC5_GEN3_PERPH_CH, &value, 231 + sizeof(value)); 232 + if (ret) 233 + return ret; 234 + 235 + value = ADC5_GEN3_CONV_REQ_REQ; 236 + return adc5_gen3_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &value, 237 + sizeof(value)); 238 + } 239 + EXPORT_SYMBOL_NS_GPL(adc5_gen3_status_clear, "QCOM_SPMI_ADC5_GEN3"); 240 + 241 + /* 242 + * Worst case delay from PBS for conversion time can be up to 500ms, when PBS 243 + * has timed out twice, once for the initial attempt and once for a retry of 244 + * the same transaction. 245 + */ 246 + 247 + #define ADC5_GEN3_CONV_TIMEOUT_MS 501 248 + 249 + static int adc5_gen3_do_conversion(struct adc5_chip *adc, 250 + struct adc5_channel_common_prop *prop, 251 + u16 *data_volt) 252 + { 253 + unsigned long rc; 254 + int ret; 255 + u8 val; 256 + 257 + guard(mutex)(&adc->lock); 258 + ret = adc5_gen3_poll_wait_hs(&adc->dev_data, ADC5_GEN3_VADC_SDAM); 259 + if (ret) 260 + return ret; 261 + 262 + ret = adc5_gen3_configure(adc, prop); 263 + if (ret) { 264 + dev_err(adc->dev, "ADC configure failed with %d\n", ret); 265 + return ret; 266 + } 267 + 268 + /* No support for polling mode at present */ 269 + rc = wait_for_completion_timeout(&adc->complete, 270 + msecs_to_jiffies(ADC5_GEN3_CONV_TIMEOUT_MS)); 271 + if (!rc) { 272 + dev_err(adc->dev, "Reading ADC channel %s timed out\n", 273 + prop->label); 274 + return -ETIMEDOUT; 275 + } 276 + 277 + ret = adc5_gen3_read_voltage_data(adc, data_volt); 278 + if (ret) 279 + return ret; 280 + 281 + val = BIT(0); 282 + return adc5_gen3_status_clear(&adc->dev_data, ADC5_GEN3_VADC_SDAM, 283 + ADC5_GEN3_EOC_CLR, &val, 1); 284 + } 285 + 286 + static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) 287 + { 288 + struct adc5_chip *adc = dev_id; 289 + struct device *dev = adc->dev; 290 + struct auxiliary_device *adev; 291 + u8 status, eoc_status, val; 292 + u8 tm_status[2]; 293 + int ret; 294 + 295 + ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, 296 + ADC5_GEN3_STATUS1, &status, sizeof(status)); 297 + if (ret) { 298 + dev_err(dev, "adc read status1 failed with %d\n", ret); 299 + return IRQ_HANDLED; 300 + } 301 + 302 + ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, 303 + ADC5_GEN3_EOC_STS, &eoc_status, sizeof(eoc_status)); 304 + if (ret) { 305 + dev_err(dev, "adc read eoc status failed with %d\n", ret); 306 + return IRQ_HANDLED; 307 + } 308 + 309 + if (status & ADC5_GEN3_STATUS1_CONV_FAULT) { 310 + dev_err_ratelimited(dev, 311 + "Unexpected conversion fault, status:%#x, eoc_status:%#x\n", 312 + status, eoc_status); 313 + val = ADC5_GEN3_CONV_ERR_CLR_REQ; 314 + adc5_gen3_status_clear(&adc->dev_data, ADC5_GEN3_VADC_SDAM, 315 + ADC5_GEN3_CONV_ERR_CLR, &val, 1); 316 + return IRQ_HANDLED; 317 + } 318 + 319 + /* CHAN0 is the preconfigured channel for immediate conversion */ 320 + if (eoc_status & ADC5_GEN3_EOC_CHAN_0) 321 + complete(&adc->complete); 322 + 323 + ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, 324 + ADC5_GEN3_TM_HIGH_STS, tm_status, sizeof(tm_status)); 325 + if (ret) { 326 + dev_err(dev, "adc read TM status failed with %d\n", ret); 327 + return IRQ_HANDLED; 328 + } 329 + 330 + dev_dbg(dev, "Interrupt status:%#x, EOC status:%#x, high:%#x, low:%#x\n", 331 + status, eoc_status, tm_status[0], tm_status[1]); 332 + 333 + if (tm_status[0] || tm_status[1]) { 334 + adev = adc->tm_aux; 335 + if (!adev || !adev->dev.driver) { 336 + dev_err(dev, "adc_tm auxiliary device not initialized\n"); 337 + return IRQ_HANDLED; 338 + } 339 + 340 + adc->handler(adev); 341 + } 342 + 343 + return IRQ_HANDLED; 344 + } 345 + 346 + static int adc5_gen3_fwnode_xlate(struct iio_dev *indio_dev, 347 + const struct fwnode_reference_args *iiospec) 348 + { 349 + struct adc5_chip *adc = iio_priv(indio_dev); 350 + int i, v_channel; 351 + 352 + for (i = 0; i < adc->nchannels; i++) { 353 + v_channel = ADC5_GEN3_V_CHAN(adc->chan_props[i].common_props); 354 + if (v_channel == iiospec->args[0]) 355 + return i; 356 + } 357 + 358 + return -ENOENT; 359 + } 360 + 361 + static int adc5_gen3_read_raw(struct iio_dev *indio_dev, 362 + struct iio_chan_spec const *chan, int *val, 363 + int *val2, long mask) 364 + { 365 + struct adc5_chip *adc = iio_priv(indio_dev); 366 + struct adc5_channel_common_prop *prop; 367 + u16 adc_code_volt; 368 + int ret; 369 + 370 + prop = &adc->chan_props[chan->address].common_props; 371 + 372 + switch (mask) { 373 + case IIO_CHAN_INFO_PROCESSED: 374 + ret = adc5_gen3_do_conversion(adc, prop, &adc_code_volt); 375 + if (ret) 376 + return ret; 377 + 378 + ret = qcom_adc5_hw_scale(prop->scale_fn_type, prop->prescale, 379 + adc->data, adc_code_volt, val); 380 + if (ret) 381 + return ret; 382 + 383 + return IIO_VAL_INT; 384 + default: 385 + return -EINVAL; 386 + } 387 + } 388 + 389 + static int adc5_gen3_read_label(struct iio_dev *indio_dev, 390 + const struct iio_chan_spec *chan, char *label) 391 + { 392 + struct adc5_chip *adc = iio_priv(indio_dev); 393 + struct adc5_channel_prop *prop; 394 + 395 + prop = &adc->chan_props[chan->address]; 396 + return sprintf(label, "%s\n", prop->common_props.label); 397 + } 398 + 399 + static const struct iio_info adc5_gen3_info = { 400 + .read_raw = adc5_gen3_read_raw, 401 + .read_label = adc5_gen3_read_label, 402 + .fwnode_xlate = adc5_gen3_fwnode_xlate, 403 + }; 404 + 405 + struct adc5_channels { 406 + unsigned int prescale_index; 407 + enum iio_chan_type type; 408 + long info_mask; 409 + enum vadc_scale_fn_type scale_fn_type; 410 + }; 411 + 412 + /* In these definitions, _pre refers to an index into adc5_prescale_ratios. */ 413 + #define ADC5_CHAN(_type, _mask, _pre, _scale) \ 414 + { \ 415 + .prescale_index = _pre, \ 416 + .type = _type, \ 417 + .info_mask = _mask, \ 418 + .scale_fn_type = _scale, \ 419 + }, \ 420 + 421 + #define ADC5_CHAN_TEMP(_pre, _scale) \ 422 + ADC5_CHAN(IIO_TEMP, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale) \ 423 + 424 + #define ADC5_CHAN_VOLT(_pre, _scale) \ 425 + ADC5_CHAN(IIO_VOLTAGE, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale) \ 426 + 427 + #define ADC5_CHAN_CUR(_pre, _scale) \ 428 + ADC5_CHAN(IIO_CURRENT, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale) \ 429 + 430 + static const struct adc5_channels adc5_gen3_chans_pmic[ADC5_MAX_CHANNEL] = { 431 + [ADC5_GEN3_REF_GND] = ADC5_CHAN_VOLT(0, SCALE_HW_CALIB_DEFAULT) 432 + [ADC5_GEN3_1P25VREF] = ADC5_CHAN_VOLT(0, SCALE_HW_CALIB_DEFAULT) 433 + [ADC5_GEN3_VPH_PWR] = ADC5_CHAN_VOLT(1, SCALE_HW_CALIB_DEFAULT) 434 + [ADC5_GEN3_VBAT_SNS_QBG] = ADC5_CHAN_VOLT(1, SCALE_HW_CALIB_DEFAULT) 435 + [ADC5_GEN3_USB_SNS_V_16] = ADC5_CHAN_TEMP(8, SCALE_HW_CALIB_DEFAULT) 436 + [ADC5_GEN3_VIN_DIV16_MUX] = ADC5_CHAN_TEMP(8, SCALE_HW_CALIB_DEFAULT) 437 + [ADC5_GEN3_DIE_TEMP] = ADC5_CHAN_TEMP(0, 438 + SCALE_HW_CALIB_PMIC_THERM_PM7) 439 + [ADC5_GEN3_AMUX1_THM_100K_PU] = ADC5_CHAN_TEMP(0, 440 + SCALE_HW_CALIB_THERM_100K_PU_PM7) 441 + [ADC5_GEN3_AMUX2_THM_100K_PU] = ADC5_CHAN_TEMP(0, 442 + SCALE_HW_CALIB_THERM_100K_PU_PM7) 443 + [ADC5_GEN3_AMUX3_THM_100K_PU] = ADC5_CHAN_TEMP(0, 444 + SCALE_HW_CALIB_THERM_100K_PU_PM7) 445 + [ADC5_GEN3_AMUX4_THM_100K_PU] = ADC5_CHAN_TEMP(0, 446 + SCALE_HW_CALIB_THERM_100K_PU_PM7) 447 + [ADC5_GEN3_AMUX5_THM_100K_PU] = ADC5_CHAN_TEMP(0, 448 + SCALE_HW_CALIB_THERM_100K_PU_PM7) 449 + [ADC5_GEN3_AMUX6_THM_100K_PU] = ADC5_CHAN_TEMP(0, 450 + SCALE_HW_CALIB_THERM_100K_PU_PM7) 451 + [ADC5_GEN3_AMUX1_GPIO_100K_PU] = ADC5_CHAN_TEMP(0, 452 + SCALE_HW_CALIB_THERM_100K_PU_PM7) 453 + [ADC5_GEN3_AMUX2_GPIO_100K_PU] = ADC5_CHAN_TEMP(0, 454 + SCALE_HW_CALIB_THERM_100K_PU_PM7) 455 + [ADC5_GEN3_AMUX3_GPIO_100K_PU] = ADC5_CHAN_TEMP(0, 456 + SCALE_HW_CALIB_THERM_100K_PU_PM7) 457 + [ADC5_GEN3_AMUX4_GPIO_100K_PU] = ADC5_CHAN_TEMP(0, 458 + SCALE_HW_CALIB_THERM_100K_PU_PM7) 459 + }; 460 + 461 + static int adc5_gen3_get_fw_channel_data(struct adc5_chip *adc, 462 + struct adc5_channel_prop *prop, 463 + struct fwnode_handle *fwnode) 464 + { 465 + const char *name = fwnode_get_name(fwnode); 466 + const struct adc5_data *data = adc->data; 467 + struct device *dev = adc->dev; 468 + const char *channel_name; 469 + u32 chan, value, sid; 470 + u32 varr[2]; 471 + int ret; 472 + 473 + ret = fwnode_property_read_u32(fwnode, "reg", &chan); 474 + if (ret < 0) 475 + return dev_err_probe(dev, ret, "invalid channel number %s\n", 476 + name); 477 + 478 + /* 479 + * Value read from "reg" is virtual channel number 480 + * virtual channel number = sid << 8 | channel number 481 + */ 482 + sid = FIELD_GET(ADC5_GEN3_VIRTUAL_SID_MASK, chan); 483 + chan = FIELD_GET(ADC5_GEN3_CHANNEL_MASK, chan); 484 + 485 + if (chan > ADC5_MAX_CHANNEL) 486 + return dev_err_probe(dev, -EINVAL, 487 + "%s invalid channel number %d\n", 488 + name, chan); 489 + 490 + prop->common_props.channel = chan; 491 + prop->common_props.sid = sid; 492 + 493 + if (!adc->data->adc_chans[chan].info_mask) 494 + return dev_err_probe(dev, -EINVAL, "Channel %#x not supported\n", chan); 495 + 496 + channel_name = name; 497 + fwnode_property_read_string(fwnode, "label", &channel_name); 498 + prop->common_props.label = channel_name; 499 + 500 + value = data->decimation[ADC5_DECIMATION_DEFAULT]; 501 + fwnode_property_read_u32(fwnode, "qcom,decimation", &value); 502 + ret = qcom_adc5_decimation_from_dt(value, data->decimation); 503 + if (ret < 0) 504 + return dev_err_probe(dev, ret, "%#x invalid decimation %d\n", 505 + chan, value); 506 + prop->common_props.decimation = ret; 507 + 508 + prop->common_props.prescale = adc->data->adc_chans[chan].prescale_index; 509 + ret = fwnode_property_read_u32_array(fwnode, "qcom,pre-scaling", varr, 2); 510 + if (!ret) { 511 + ret = qcom_adc5_prescaling_from_dt(varr[0], varr[1]); 512 + if (ret < 0) 513 + return dev_err_probe(dev, ret, 514 + "%#x invalid pre-scaling <%d %d>\n", 515 + chan, varr[0], varr[1]); 516 + prop->common_props.prescale = ret; 517 + } 518 + 519 + value = data->hw_settle_1[VADC_DEF_HW_SETTLE_TIME]; 520 + fwnode_property_read_u32(fwnode, "qcom,hw-settle-time", &value); 521 + ret = qcom_adc5_hw_settle_time_from_dt(value, data->hw_settle_1); 522 + if (ret < 0) 523 + return dev_err_probe(dev, ret, 524 + "%#x invalid hw-settle-time %d us\n", 525 + chan, value); 526 + prop->common_props.hw_settle_time_us = ret; 527 + 528 + value = BIT(VADC_DEF_AVG_SAMPLES); 529 + fwnode_property_read_u32(fwnode, "qcom,avg-samples", &value); 530 + ret = qcom_adc5_avg_samples_from_dt(value); 531 + if (ret < 0) 532 + return dev_err_probe(dev, ret, "%#x invalid avg-samples %d\n", 533 + chan, value); 534 + prop->common_props.avg_samples = ret; 535 + 536 + if (fwnode_property_read_bool(fwnode, "qcom,ratiometric")) 537 + prop->common_props.cal_method = ADC5_RATIOMETRIC_CAL; 538 + else 539 + prop->common_props.cal_method = ADC5_ABSOLUTE_CAL; 540 + 541 + prop->adc_tm = fwnode_property_read_bool(fwnode, "qcom,adc-tm"); 542 + if (prop->adc_tm) { 543 + adc->n_tm_channels++; 544 + if (adc->n_tm_channels > (adc->dev_data.num_sdams * 8 - 1)) 545 + return dev_err_probe(dev, -EINVAL, 546 + "Number of TM nodes %u greater than channels supported:%u\n", 547 + adc->n_tm_channels, 548 + adc->dev_data.num_sdams * 8 - 1); 549 + } 550 + 551 + return 0; 552 + } 553 + 554 + static const struct adc5_data adc5_gen3_data_pmic = { 555 + .full_scale_code_volt = 0x70e4, 556 + .adc_chans = adc5_gen3_chans_pmic, 557 + .info = &adc5_gen3_info, 558 + .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX]) 559 + { 85, 340, 1360 }, 560 + .hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX]) 561 + { 15, 100, 200, 300, 562 + 400, 500, 600, 700, 563 + 1000, 2000, 4000, 8000, 564 + 16000, 32000, 64000, 128000 }, 565 + }; 566 + 567 + static const struct of_device_id adc5_match_table[] = { 568 + { 569 + .compatible = "qcom,spmi-adc5-gen3", 570 + .data = &adc5_gen3_data_pmic, 571 + }, 572 + { } 573 + }; 574 + MODULE_DEVICE_TABLE(of, adc5_match_table); 575 + 576 + static int adc5_get_fw_data(struct adc5_chip *adc) 577 + { 578 + const struct adc5_channels *adc_chan; 579 + struct adc5_channel_prop *chan_props; 580 + struct iio_chan_spec *iio_chan; 581 + struct device *dev = adc->dev; 582 + unsigned int index = 0; 583 + int ret; 584 + 585 + adc->nchannels = device_get_child_node_count(dev); 586 + if (!adc->nchannels) 587 + return dev_err_probe(dev, -EINVAL, "No ADC channels found\n"); 588 + 589 + adc->iio_chans = devm_kcalloc(dev, adc->nchannels, 590 + sizeof(*adc->iio_chans), GFP_KERNEL); 591 + if (!adc->iio_chans) 592 + return -ENOMEM; 593 + 594 + adc->chan_props = devm_kcalloc(dev, adc->nchannels, 595 + sizeof(*adc->chan_props), GFP_KERNEL); 596 + if (!adc->chan_props) 597 + return -ENOMEM; 598 + 599 + chan_props = adc->chan_props; 600 + adc->n_tm_channels = 0; 601 + iio_chan = adc->iio_chans; 602 + adc->data = device_get_match_data(dev); 603 + 604 + device_for_each_child_node_scoped(dev, child) { 605 + ret = adc5_gen3_get_fw_channel_data(adc, chan_props, child); 606 + if (ret) 607 + return ret; 608 + 609 + chan_props->chip = adc; 610 + adc_chan = &adc->data->adc_chans[chan_props->common_props.channel]; 611 + chan_props->common_props.scale_fn_type = adc_chan->scale_fn_type; 612 + 613 + iio_chan->channel = ADC5_GEN3_V_CHAN(chan_props->common_props); 614 + iio_chan->info_mask_separate = adc_chan->info_mask; 615 + iio_chan->type = adc_chan->type; 616 + iio_chan->address = index; 617 + iio_chan->indexed = 1; 618 + iio_chan++; 619 + chan_props++; 620 + index++; 621 + } 622 + 623 + return 0; 624 + } 625 + 626 + static void adc5_gen3_uninit_aux(void *data) 627 + { 628 + auxiliary_device_uninit(data); 629 + } 630 + 631 + static void adc5_gen3_delete_aux(void *data) 632 + { 633 + auxiliary_device_delete(data); 634 + } 635 + 636 + static void adc5_gen3_aux_device_release(struct device *dev) {} 637 + 638 + static int adc5_gen3_add_aux_tm_device(struct adc5_chip *adc) 639 + { 640 + struct tm5_aux_dev_wrapper *aux_device; 641 + int i, ret, i_tm = 0; 642 + 643 + aux_device = devm_kzalloc(adc->dev, sizeof(*aux_device), GFP_KERNEL); 644 + if (!aux_device) 645 + return -ENOMEM; 646 + 647 + aux_device->aux_dev.name = "adc5_tm_gen3"; 648 + aux_device->aux_dev.dev.parent = adc->dev; 649 + aux_device->aux_dev.dev.release = adc5_gen3_aux_device_release; 650 + 651 + aux_device->tm_props = devm_kcalloc(adc->dev, adc->n_tm_channels, 652 + sizeof(*aux_device->tm_props), 653 + GFP_KERNEL); 654 + if (!aux_device->tm_props) 655 + return -ENOMEM; 656 + 657 + aux_device->dev_data = &adc->dev_data; 658 + 659 + for (i = 0; i < adc->nchannels; i++) { 660 + if (!adc->chan_props[i].adc_tm) 661 + continue; 662 + aux_device->tm_props[i_tm] = adc->chan_props[i].common_props; 663 + i_tm++; 664 + } 665 + 666 + device_set_of_node_from_dev(&aux_device->aux_dev.dev, adc->dev); 667 + 668 + aux_device->n_tm_channels = adc->n_tm_channels; 669 + 670 + ret = auxiliary_device_init(&aux_device->aux_dev); 671 + if (ret) 672 + return ret; 673 + 674 + ret = devm_add_action_or_reset(adc->dev, adc5_gen3_uninit_aux, 675 + &aux_device->aux_dev); 676 + if (ret) 677 + return ret; 678 + 679 + ret = auxiliary_device_add(&aux_device->aux_dev); 680 + if (ret) 681 + return ret; 682 + ret = devm_add_action_or_reset(adc->dev, adc5_gen3_delete_aux, 683 + &aux_device->aux_dev); 684 + if (ret) 685 + return ret; 686 + 687 + adc->tm_aux = &aux_device->aux_dev; 688 + 689 + return 0; 690 + } 691 + 692 + void adc5_gen3_mutex_lock(struct device *dev) 693 + __acquires(&adc->lock) 694 + { 695 + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); 696 + struct adc5_chip *adc = iio_priv(indio_dev); 697 + 698 + mutex_lock(&adc->lock); 699 + } 700 + EXPORT_SYMBOL_NS_GPL(adc5_gen3_mutex_lock, "QCOM_SPMI_ADC5_GEN3"); 701 + 702 + void adc5_gen3_mutex_unlock(struct device *dev) 703 + __releases(&adc->lock) 704 + { 705 + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); 706 + struct adc5_chip *adc = iio_priv(indio_dev); 707 + 708 + mutex_unlock(&adc->lock); 709 + } 710 + EXPORT_SYMBOL_NS_GPL(adc5_gen3_mutex_unlock, "QCOM_SPMI_ADC5_GEN3"); 711 + 712 + int adc5_gen3_get_scaled_reading(struct device *dev, 713 + struct adc5_channel_common_prop *common_props, 714 + int *val) 715 + { 716 + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); 717 + struct adc5_chip *adc = iio_priv(indio_dev); 718 + u16 adc_code_volt; 719 + int ret; 720 + 721 + ret = adc5_gen3_do_conversion(adc, common_props, &adc_code_volt); 722 + if (ret) 723 + return ret; 724 + 725 + return qcom_adc5_hw_scale(common_props->scale_fn_type, 726 + common_props->prescale, 727 + adc->data, adc_code_volt, val); 728 + } 729 + EXPORT_SYMBOL_NS_GPL(adc5_gen3_get_scaled_reading, "QCOM_SPMI_ADC5_GEN3"); 730 + 731 + int adc5_gen3_therm_code_to_temp(struct device *dev, 732 + struct adc5_channel_common_prop *common_props, 733 + u16 code, int *val) 734 + { 735 + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); 736 + struct adc5_chip *adc = iio_priv(indio_dev); 737 + 738 + return qcom_adc5_hw_scale(common_props->scale_fn_type, 739 + common_props->prescale, 740 + adc->data, code, val); 741 + } 742 + EXPORT_SYMBOL_NS_GPL(adc5_gen3_therm_code_to_temp, "QCOM_SPMI_ADC5_GEN3"); 743 + 744 + void adc5_gen3_register_tm_event_notifier(struct device *dev, 745 + void (*handler)(struct auxiliary_device *)) 746 + { 747 + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); 748 + struct adc5_chip *adc = iio_priv(indio_dev); 749 + 750 + adc->handler = handler; 751 + } 752 + EXPORT_SYMBOL_NS_GPL(adc5_gen3_register_tm_event_notifier, "QCOM_SPMI_ADC5_GEN3"); 753 + 754 + static int adc5_gen3_probe(struct platform_device *pdev) 755 + { 756 + struct device *dev = &pdev->dev; 757 + struct iio_dev *indio_dev; 758 + struct adc5_chip *adc; 759 + struct regmap *regmap; 760 + int ret, i; 761 + u32 *reg; 762 + 763 + regmap = dev_get_regmap(dev->parent, NULL); 764 + if (!regmap) 765 + return -ENODEV; 766 + 767 + indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); 768 + if (!indio_dev) 769 + return -ENOMEM; 770 + 771 + adc = iio_priv(indio_dev); 772 + adc->dev_data.regmap = regmap; 773 + adc->dev = dev; 774 + 775 + ret = device_property_count_u32(dev, "reg"); 776 + if (ret < 0) 777 + return ret; 778 + 779 + adc->dev_data.num_sdams = ret; 780 + 781 + reg = devm_kcalloc(dev, adc->dev_data.num_sdams, sizeof(u32), 782 + GFP_KERNEL); 783 + if (!reg) 784 + return -ENOMEM; 785 + 786 + ret = device_property_read_u32_array(dev, "reg", reg, 787 + adc->dev_data.num_sdams); 788 + if (ret) 789 + return dev_err_probe(dev, ret, 790 + "Failed to read reg property\n"); 791 + 792 + adc->dev_data.base = devm_kcalloc(dev, adc->dev_data.num_sdams, 793 + sizeof(*adc->dev_data.base), 794 + GFP_KERNEL); 795 + if (!adc->dev_data.base) 796 + return -ENOMEM; 797 + 798 + platform_set_drvdata(pdev, indio_dev); 799 + init_completion(&adc->complete); 800 + ret = devm_mutex_init(dev, &adc->lock); 801 + if (ret) 802 + return ret; 803 + 804 + for (i = 0; i < adc->dev_data.num_sdams; i++) { 805 + adc->dev_data.base[i].base_addr = reg[i]; 806 + 807 + ret = platform_get_irq(pdev, i); 808 + if (ret < 0) 809 + return dev_err_probe(dev, ret, 810 + "Getting IRQ %d failed\n", i); 811 + 812 + adc->dev_data.base[i].irq = ret; 813 + 814 + adc->dev_data.base[i].irq_name = devm_kasprintf(dev, GFP_KERNEL, 815 + "sdam%d", i); 816 + if (!adc->dev_data.base[i].irq_name) 817 + return -ENOMEM; 818 + } 819 + 820 + ret = devm_request_irq(dev, adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq, 821 + adc5_gen3_isr, 0, 822 + adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq_name, 823 + adc); 824 + if (ret) 825 + return dev_err_probe(dev, ret, 826 + "Failed to request SDAM%d irq\n", 827 + ADC5_GEN3_VADC_SDAM); 828 + 829 + ret = adc5_get_fw_data(adc); 830 + if (ret) 831 + return ret; 832 + 833 + if (adc->n_tm_channels > 0) { 834 + ret = adc5_gen3_add_aux_tm_device(adc); 835 + if (ret) 836 + dev_err_probe(dev, ret, 837 + "Failed to add auxiliary TM device\n"); 838 + } 839 + 840 + indio_dev->name = "spmi-adc5-gen3"; 841 + indio_dev->modes = INDIO_DIRECT_MODE; 842 + indio_dev->info = &adc5_gen3_info; 843 + indio_dev->channels = adc->iio_chans; 844 + indio_dev->num_channels = adc->nchannels; 845 + 846 + return devm_iio_device_register(dev, indio_dev); 847 + } 848 + 849 + static struct platform_driver adc5_gen3_driver = { 850 + .driver = { 851 + .name = "qcom-spmi-adc5-gen3", 852 + .of_match_table = adc5_match_table, 853 + }, 854 + .probe = adc5_gen3_probe, 855 + }; 856 + module_platform_driver(adc5_gen3_driver); 857 + 858 + MODULE_DESCRIPTION("Qualcomm Technologies Inc. PMIC5 Gen3 ADC driver"); 859 + MODULE_LICENSE("GPL"); 860 + MODULE_IMPORT_NS("QCOM_SPMI_ADC5_GEN3");
+211
include/linux/iio/adc/qcom-adc5-gen3-common.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 + * 5 + * Code used in the main and auxiliary Qualcomm PMIC voltage ADCs 6 + * of type ADC5 Gen3. 7 + */ 8 + 9 + #ifndef QCOM_ADC5_GEN3_COMMON_H 10 + #define QCOM_ADC5_GEN3_COMMON_H 11 + 12 + #include <linux/auxiliary_bus.h> 13 + #include <linux/bitfield.h> 14 + #include <linux/bits.h> 15 + #include <linux/device.h> 16 + #include <linux/iio/adc/qcom-vadc-common.h> 17 + #include <linux/regmap.h> 18 + #include <linux/types.h> 19 + 20 + #define ADC5_GEN3_HS 0x45 21 + #define ADC5_GEN3_HS_BUSY BIT(7) 22 + #define ADC5_GEN3_HS_READY BIT(0) 23 + 24 + #define ADC5_GEN3_STATUS1 0x46 25 + #define ADC5_GEN3_STATUS1_CONV_FAULT BIT(7) 26 + #define ADC5_GEN3_STATUS1_THR_CROSS BIT(6) 27 + #define ADC5_GEN3_STATUS1_EOC BIT(0) 28 + 29 + #define ADC5_GEN3_TM_EN_STS 0x47 30 + #define ADC5_GEN3_TM_HIGH_STS 0x48 31 + #define ADC5_GEN3_TM_LOW_STS 0x49 32 + 33 + #define ADC5_GEN3_EOC_STS 0x4a 34 + #define ADC5_GEN3_EOC_CHAN_0 BIT(0) 35 + 36 + #define ADC5_GEN3_EOC_CLR 0x4b 37 + #define ADC5_GEN3_TM_HIGH_STS_CLR 0x4c 38 + #define ADC5_GEN3_TM_LOW_STS_CLR 0x4d 39 + #define ADC5_GEN3_CONV_ERR_CLR 0x4e 40 + #define ADC5_GEN3_CONV_ERR_CLR_REQ BIT(0) 41 + 42 + #define ADC5_GEN3_SID 0x4f 43 + #define ADC5_GEN3_SID_MASK GENMASK(3, 0) 44 + 45 + #define ADC5_GEN3_PERPH_CH 0x50 46 + #define ADC5_GEN3_CHAN_CONV_REQ BIT(7) 47 + 48 + #define ADC5_GEN3_TIMER_SEL 0x51 49 + #define ADC5_GEN3_TIME_IMMEDIATE 0x1 50 + 51 + #define ADC5_GEN3_DIG_PARAM 0x52 52 + #define ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK GENMASK(5, 4) 53 + #define ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK GENMASK(3, 2) 54 + 55 + #define ADC5_GEN3_FAST_AVG 0x53 56 + #define ADC5_GEN3_FAST_AVG_CTL_EN BIT(7) 57 + #define ADC5_GEN3_FAST_AVG_CTL_SAMPLES_MASK GENMASK(2, 0) 58 + 59 + #define ADC5_GEN3_ADC_CH_SEL_CTL 0x54 60 + #define ADC5_GEN3_DELAY_CTL 0x55 61 + #define ADC5_GEN3_HW_SETTLE_DELAY_MASK GENMASK(3, 0) 62 + 63 + #define ADC5_GEN3_CH_EN 0x56 64 + #define ADC5_GEN3_HIGH_THR_INT_EN BIT(1) 65 + #define ADC5_GEN3_LOW_THR_INT_EN BIT(0) 66 + 67 + #define ADC5_GEN3_LOW_THR0 0x57 68 + #define ADC5_GEN3_LOW_THR1 0x58 69 + #define ADC5_GEN3_HIGH_THR0 0x59 70 + #define ADC5_GEN3_HIGH_THR1 0x5a 71 + 72 + #define ADC5_GEN3_CH_DATA0(channel) (0x5c + (channel) * 2) 73 + #define ADC5_GEN3_CH_DATA1(channel) (0x5d + (channel) * 2) 74 + 75 + #define ADC5_GEN3_CONV_REQ 0xe5 76 + #define ADC5_GEN3_CONV_REQ_REQ BIT(0) 77 + 78 + #define ADC5_GEN3_VIRTUAL_SID_MASK GENMASK(15, 8) 79 + #define ADC5_GEN3_CHANNEL_MASK GENMASK(7, 0) 80 + #define ADC5_GEN3_V_CHAN(x) \ 81 + (FIELD_PREP(ADC5_GEN3_VIRTUAL_SID_MASK, (x).sid) | (x).channel) 82 + 83 + /* ADC channels for PMIC5 Gen3 */ 84 + #define ADC5_GEN3_REF_GND 0x00 85 + #define ADC5_GEN3_1P25VREF 0x01 86 + #define ADC5_GEN3_DIE_TEMP 0x03 87 + #define ADC5_GEN3_USB_SNS_V_16 0x11 88 + #define ADC5_GEN3_VIN_DIV16_MUX 0x12 89 + #define ADC5_GEN3_VPH_PWR 0x8e 90 + #define ADC5_GEN3_VBAT_SNS_QBG 0x8f 91 + /* 100k pull-up channels */ 92 + #define ADC5_GEN3_AMUX1_THM_100K_PU 0x44 93 + #define ADC5_GEN3_AMUX2_THM_100K_PU 0x45 94 + #define ADC5_GEN3_AMUX3_THM_100K_PU 0x46 95 + #define ADC5_GEN3_AMUX4_THM_100K_PU 0x47 96 + #define ADC5_GEN3_AMUX5_THM_100K_PU 0x48 97 + #define ADC5_GEN3_AMUX6_THM_100K_PU 0x49 98 + #define ADC5_GEN3_AMUX1_GPIO_100K_PU 0x4a 99 + #define ADC5_GEN3_AMUX2_GPIO_100K_PU 0x4b 100 + #define ADC5_GEN3_AMUX3_GPIO_100K_PU 0x4c 101 + #define ADC5_GEN3_AMUX4_GPIO_100K_PU 0x4d 102 + 103 + #define ADC5_MAX_CHANNEL 0xc0 104 + 105 + enum adc5_cal_method { 106 + ADC5_NO_CAL = 0, 107 + ADC5_RATIOMETRIC_CAL, 108 + ADC5_ABSOLUTE_CAL, 109 + }; 110 + 111 + enum adc5_time_select { 112 + MEAS_INT_DISABLE = 0, 113 + MEAS_INT_IMMEDIATE, 114 + MEAS_INT_50MS, 115 + MEAS_INT_100MS, 116 + MEAS_INT_1S, 117 + MEAS_INT_NONE, 118 + }; 119 + 120 + /** 121 + * struct adc5_sdam_data - data per SDAM allocated for adc usage 122 + * @base_addr: base address for the ADC SDAM peripheral. 123 + * @irq_name: ADC IRQ name. 124 + * @irq: ADC IRQ number. 125 + */ 126 + struct adc5_sdam_data { 127 + u16 base_addr; 128 + const char *irq_name; 129 + int irq; 130 + }; 131 + 132 + /** 133 + * struct adc5_device_data - Top-level ADC device data 134 + * @regmap: ADC peripheral register map field. 135 + * @base: array of SDAM data. 136 + * @num_sdams: number of ADC SDAM peripherals. 137 + */ 138 + struct adc5_device_data { 139 + struct regmap *regmap; 140 + struct adc5_sdam_data *base; 141 + int num_sdams; 142 + }; 143 + 144 + /** 145 + * struct adc5_channel_common_prop - ADC channel properties (common to ADC and TM). 146 + * @channel: channel number, refer to the channel list. 147 + * @cal_method: calibration method. 148 + * @decimation: sampling rate supported for the channel. 149 + * @sid: ID of PMIC owning the channel. 150 + * @label: Channel name used in device tree. 151 + * @prescale: channel scaling performed on the input signal. 152 + * @hw_settle_time_us: the time between AMUX being configured and the 153 + * start of conversion in uS. 154 + * @avg_samples: ability to provide single result from the ADC 155 + * that is an average of multiple measurements. 156 + * @scale_fn_type: Represents the scaling function to convert voltage 157 + * physical units desired by the client for the channel. 158 + */ 159 + struct adc5_channel_common_prop { 160 + unsigned int channel; 161 + enum adc5_cal_method cal_method; 162 + unsigned int decimation; 163 + unsigned int sid; 164 + const char *label; 165 + unsigned int prescale; 166 + unsigned int hw_settle_time_us; 167 + unsigned int avg_samples; 168 + enum vadc_scale_fn_type scale_fn_type; 169 + }; 170 + 171 + /** 172 + * struct tm5_aux_dev_wrapper - wrapper structure around TM auxiliary device 173 + * @aux_dev: TM auxiliary device structure. 174 + * @dev_data: Top-level ADC device data. 175 + * @tm_props: Array of common ADC channel properties for TM channels. 176 + * @n_tm_channels: number of TM channels. 177 + */ 178 + struct tm5_aux_dev_wrapper { 179 + struct auxiliary_device aux_dev; 180 + struct adc5_device_data *dev_data; 181 + struct adc5_channel_common_prop *tm_props; 182 + unsigned int n_tm_channels; 183 + }; 184 + 185 + int adc5_gen3_read(struct adc5_device_data *adc, unsigned int sdam_index, 186 + u16 offset, u8 *data, int len); 187 + 188 + int adc5_gen3_write(struct adc5_device_data *adc, unsigned int sdam_index, 189 + u16 offset, u8 *data, int len); 190 + 191 + int adc5_gen3_poll_wait_hs(struct adc5_device_data *adc, 192 + unsigned int sdam_index); 193 + 194 + void adc5_gen3_update_dig_param(struct adc5_channel_common_prop *prop, 195 + u8 *data); 196 + 197 + int adc5_gen3_status_clear(struct adc5_device_data *adc, 198 + int sdam_index, u16 offset, u8 *val, int len); 199 + 200 + void adc5_gen3_mutex_lock(struct device *dev); 201 + void adc5_gen3_mutex_unlock(struct device *dev); 202 + int adc5_gen3_get_scaled_reading(struct device *dev, 203 + struct adc5_channel_common_prop *common_props, 204 + int *val); 205 + int adc5_gen3_therm_code_to_temp(struct device *dev, 206 + struct adc5_channel_common_prop *common_props, 207 + u16 code, int *val); 208 + void adc5_gen3_register_tm_event_notifier(struct device *dev, 209 + void (*handler)(struct auxiliary_device *)); 210 + 211 + #endif /* QCOM_ADC5_GEN3_COMMON_H */