Add Pmi632 support to control flash led, get battery and charger status on the fairphone 3#242
Add Pmi632 support to control flash led, get battery and charger status on the fairphone 3#242mlainez wants to merge 17 commits into
Conversation
|
Really nice to se you working on that! :) One note regarding flash support on PMI632: On downstream the driver sets POWER_SUPPLY_PROP_FLASH_ACTIVE on the power supply, uses power supply for turning on power, then waits until power is on and then does the normal stuff. FairphoneMirrors/android_kernel_fairphone_sdm632@1c1e21c
LineageOS/android_kernel_fairphone_sm7225@103b127
So from my interpretation of those messages, we should really have some interaction between charger and flash driver to not damage the flash LED by supplying it with too high voltage. Also linking #239 which has similar functionality added (charger & fuel gauge). |
|
@mlainez Please send upstream what you can, there are smaller trivial changes here what could be accepted there very quick. |
The adc5_chans_pmic[] array is missing an entry for ADC5_BAT_THERM_100K_PU (channel 0x4a). The zero-initialized entry has info_mask=0 and type=IIO_VOLTAGE, which means iio_read_channel_processed() returns -EINVAL for this channel since BIT(IIO_CHAN_INFO_PROCESSED) is not set. This affects PMICs like the PMI632 that use this channel for battery thermistor readings via a 100K pull-up. Without this fix, battery temperature cannot be read through the IIO subsystem. Add the missing channel definition with SCALE_HW_CALIB_THERM_100K_PULLUP scaling, consistent with the other thermistor channels in the array. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
The PMI632 flash LED controller reports subtype 0x05, which is not recognized by the driver. The hardware uses the same 3-channel register layout as PMI8998 (subtype 0x03) and PM8150 (subtype 0x04), with 2 flash channels and 2 torch channels. Add FLASH_SUBTYPE_3CH_PMI632_VAL (0x05) and include it in the 3-channel detection path so the driver probes successfully on PMI632. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
Add device tree binding documentation for the QGauge (QG) fuel gauge block found in the Qualcomm PMI632 PMIC. This hardware provides battery voltage and current FIFO sampling, open circuit voltage measurement, and coulomb counting for battery state estimation. The binding requires a monitored-battery phandle (simple-battery node) for OCV-to-capacity lookup tables, and optionally accepts an IIO channel for battery thermistor temperature readings. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
Add a driver for the QGauge (QG) fuel gauge block in the Qualcomm
PMI632 PMIC. The QG hardware provides FIFO-based voltage and current
sampling, open circuit voltage (OCV) measurement during sleep states,
and accumulator-based coulomb counting.
This is a minimal mainline implementation that exposes battery state
via the power_supply subsystem:
- Voltage from last ADC register and FIFO averaging
- Current from burst average register with hold/release protocol
- OCV from power-on (S7) and sleep (S3) hardware measurements
- Temperature via IIO ADC channel (battery thermistor)
- SOC computed in-kernel using power_supply_batinfo_ocv2cap()
with OCV-to-capacity tables from the monitored-battery DT node
Three IRQs are handled: fifo-done (voltage update), good-ocv (new OCV
measurement available), and batt-missing (battery presence change).
The downstream Android driver (~14,000 lines) relies on a userspace
daemon via chardev for SOC calculation and uses several Android-only
frameworks (pmic-voter, qpnp-vadc, of_batterydata). This driver
replaces all of that with standard kernel subsystem APIs.
Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
Add the QGauge (QG) fuel gauge device node at register offset 0x4800 in the PMI632 PMIC. The node defines all 7 hardware interrupts (batt-missing, vbat-low, vbat-empty, fifo-done, good-ocv, fsm-state-chg, event) and is disabled by default, to be enabled by board-level DTS files that provide a monitored-battery reference. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
Add a simple-battery node with the Fuji 3000mAh OCV-to-capacity table (55 data points at 25°C) extracted from the downstream Qualcomm battery profile. Add a battery thermistor ADC channel (ADC5_BAT_THERM_100K_PU) to the PMI632 ADC node for temperature readings. Enable the PMI632 QGauge fuel gauge with a reference to the battery node and the thermistor IIO channel, providing battery voltage, current, OCV, temperature, and capacity reporting. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
Add qcom,pmi632-flash-led to the list of compatible strings for the Qualcomm SPMI flash LED controller. The PMI632 flash peripheral uses the same register layout as the 3-channel variant (PMI8998) but has only 2 flash and 2 torch channels. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
Add the flash LED controller node for the PMI632 PMIC at register base 0xd300 under USID 3. The node uses the qcom,pmi632-flash-led compatible with fallback to the generic qcom,spmi-flash-led driver. The node is disabled by default; board DTS files should enable it and add LED child nodes matching the hardware configuration. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
Enable the PMI632 flash LED controller on the Fairphone 3 with two LED channels (sources 1 and 2), each configured for 300mA torch and 1500mA flash with a maximum timeout of 1.28 seconds. Enable CONFIG_LEDS_QCOM_FLASH as a module in the FP3 config fragment. Note: the flash peripheral subtype register value is not yet known. If the mainline driver does not recognize it on first boot, it will log the value, which can then be added to leds-qcom-flash.c. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
Add device tree binding documentation for the Qualcomm PMI632 SMB5 charger peripheral. The PMI632 integrates an SMB5-class switch-mode battery charger that supports USB charging with automatic input current limiting (AICL) and Type-C current detection. The binding requires charger, DCDC, battery interface, USB input, and miscellaneous register blocks, along with interrupt descriptors for USB plug events, battery over-voltage, watchdog bark, and ICL changes. USB input voltage and current are read via SPMI ADC5 IIO channels. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
Add a driver for the SMB5-class charger integrated in the Qualcomm PMI632 PMIC. This is a standalone implementation separate from the SMB2 charger driver (qcom_pmi8998_charger.c) due to significant register layout differences in the SMB5 variant: - Completely reordered charge status enumeration - ICL_STATUS and POWER_PATH_STATUS relocated from MISC to DCDC block - Different current scaling (50mA vs 25mA steps) - Different float voltage encoding (10mV steps from 3600mV) - BAT_OV status bit repositioned The driver supports: - Battery status, voltage, current, and charge type reporting - USB online detection with automatic input current limit (AICL) - Configurable charge current, float voltage, and input current limit - Battery over-voltage protection - Watchdog bark handling - USB input voltage/current monitoring via SPMI ADC5 IIO channels Battery parameters (charge-full-design-microamp-hours, voltage-max, voltage-min) are read from a monitored-battery phandle using the standard simple-battery binding. Type-C handling is left to the separate pmi632_typec driver. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
Add the SMB5 charger device node for the PMI632 PMIC. The charger block resides at register base 0x1000 on SPMI USID 2 and uses four interrupts: USB plug/unplug detection, battery over-voltage, watchdog bark, and USB input current limit change. USB input voltage and current are monitored via the existing SPMI ADC5 channels (ADC5_USB_IN_I and ADC5_USB_IN_V_16). The node is disabled by default and must be enabled per-board with a monitored-battery phandle. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
Enable the PMI632 SMB5 charger on the Fairphone 3 by referencing the board's battery node and adding CONFIG_CHARGER_QCOM_SMB5 to the FP3 config fragment. The charger uses the same simple-battery node already defined for the fuel gauge, providing charge voltage and current limits. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
The PMI632 QG hardware reports current with positive values for discharge and negative for charge. The power_supply sysfs ABI (Documentation/ABI/testing/sysfs-class-power) specifies the opposite: positive for charging, negative for discharging. Negate the raw reading to match the ABI, so that current_now is positive when the battery is charging and status reports Charging. Signed-off-by: Marc Lainez <marc.lainez@gmail.com>
The power_supply_config struct replaced the of_node member with fwnode. Use dev_fwnode() helper to obtain the firmware node instead.
…onfig The power_supply_config struct replaced the of_node member with fwnode. Use dev_fwnode() helper to obtain the firmware node instead.
…lude The of_device_id struct definition lives in linux/mod_devicetable.h which was not explicitly included, causing an incomplete type error.
| * | ||
| * This driver is for the SMB5 switch-mode battery charger found in the | ||
| * Qualcomm PMI632 PMIC. It is modeled on the SMB2 driver | ||
| * (qcom_pmi8998_charger.c by Caleb Connolly) but adapted for the SMB5 |
|
There's existing work for both SMB5 and QGauge that can be found in e.g. https://github.com/sm7150-mainline/linux/commits/v7.0 which at least for SMB5 is clearly the way to go: it's adding support to the (upd: qgauge is better here, but for SMB5 better to pick that up, to have it go inside of the SMB2 one) |
| u16 raw; | ||
| int ret, i; | ||
|
|
||
| mutex_lock(&qg->lock); |
There was a problem hiding this comment.
Use guard(mutex)(&qg->lock); instead of lock-unlock
| return -ENODATA; | ||
| ret = qg_read_temperature(qg, &val->intval); | ||
| return ret; | ||
|
|
There was a problem hiding this comment.
Missing:
POWER_SUPPLY_PROP_TECHNOLOGY(returnPOWER_SUPPLY_TECHNOLOGY_LIONat least)POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, andPOWER_SUPPLY_PROP_CHARGE_FULL_DESIGN(just from thebatt_info)POWER_SUPPLY_PROP_VOLTAGE_AVG(read the avg register0x80instead of the last reg0xc0)POWER_SUPPLY_PROP_CURRENT_AVG(similarly,0x82is avg current according to the other driver)POWER_SUPPLY_PROP_CHARGE_FULL(read from SDAM NVMEM.. which also has something something OCV related)
| if (ret) | ||
| temp_decidegc = 250; /* default 25.0 degC */ | ||
|
|
||
| *capacity = power_supply_batinfo_ocv2cap(qg->batt_info, |
There was a problem hiding this comment.
Very nice!!! Overall the qgauge is better here, just call it qcom_qg instead of qcom_pmi632_qg, and add a qcom,pm6150-qg compatible as well
|
@valpackett thanks for reviewing. Much appreciated. To be honest, I didn't even know there was some existing work in another fork, I'm not familiar at all with the whole qcom forks ecosystem so if there is any documentation on where to look, let me know. I'm just trying to make most things work on the fairphone3 and this part felt like something that could be useful for others. I'll review this whole PR based on your feedback and what's existing in sm7150. |
Yeah, it's not a super coherent ecosystem, but you can find the forks linked on the postmarketOS wiki and packaged in pmaports, and the only way to know all the stuff is to just be very curious/obsessive and check up on the repos and be in the chatrooms for multiple SoCs and monitor patchwork as well etc. :) Thanks for discovering the ocv2cap stuff, that really improves things. |
There was a problem hiding this comment.
Please keep the original formatting, your changes are not visible like this.
There was a problem hiding this comment.
You should send this upstream.
Add support for pmi632