Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3a016ea4 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "backlight: qcom-spmi-wled: Add support for PM7325B WLED"

parents 0a38c437 041c8f64
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -246,3 +246,6 @@ CONFIG_SM_VIDEOCC_YUPIK=m
CONFIG_SM_CAMCC_YUPIK=m
CONFIG_QCOM_YUPIK_LLCC=m
CONFIG_SM_DISPCC_YUPIK=m
CONFIG_REGULATOR_QPNP_LCDB=m
CONFIG_LEDS_QPNP_VIBRATOR_LDO=m
CONFIG_BACKLIGHT_QCOM_SPMI_WLED=m
+70 −21
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 * Copyright (c) 2015, Sony Mobile Communications, AB.
 */
/*
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)	"WLED: %s: " fmt, __func__
@@ -18,6 +18,8 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/power_supply.h>
#include <linux/soc/qcom/battery_charger.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>
#include <linux/leds-qpnp-flash.h>
@@ -182,6 +184,7 @@ enum wled_version {
	WLED_PMI8998 = 4,
	WLED_PM660L,
	WLED_PM8150L,
	WLED_PM7325B,
};

enum wled_flash_mode {
@@ -194,6 +197,7 @@ static const int version_table[] = {
	[0] = WLED_PMI8998,
	[1] = WLED_PM660L,
	[2] = WLED_PM8150L,
	[3] = WLED_PM7325B,
};

struct wled_config {
@@ -220,6 +224,7 @@ struct wled {
	struct platform_device *pdev;
	struct regmap *regmap;
	struct iio_channel **iio_channels;
	struct power_supply *batt_psy;
	struct mutex lock;
	struct wled_config cfg;
	ktime_t last_sc_event_time;
@@ -241,6 +246,7 @@ struct wled {
	bool auto_calib_done;
	bool force_mod_disable;
	bool cabc_disabled;
	bool use_psy;
	int (*cabc_config)(struct wled *wled, bool enable);

	struct led_classdev flash_cdev;
@@ -299,7 +305,7 @@ static inline bool is_wled4(struct wled *wled)

static inline bool is_wled5(struct wled *wled)
{
	if (*wled->version == WLED_PM8150L)
	if (*wled->version == WLED_PM8150L || *wled->version == WLED_PM7325B)
		return true;

	return false;
@@ -314,7 +320,7 @@ static int wled_module_enable(struct wled *wled, int val)
		return 0;

	/* Force HFRC off */
	if (*wled->version == WLED_PM8150L) {
	if (is_wled5(wled)) {
		reg = val ? 0 : 3;
		rc = regmap_write(wled->regmap, wled->ctrl_addr +
				  WLED5_CTRL_PBUS_WRITE_SYNC_CTL, reg);
@@ -329,7 +335,7 @@ static int wled_module_enable(struct wled *wled, int val)
		return rc;

	/* Force HFRC off */
	if (*wled->version == WLED_PM8150L && val) {
	if (is_wled5(wled) && val) {
		rc = regmap_write(wled->regmap, wled->sink_addr +
				  WLED5_SINK_FLASH_SHDN_CLR_REG, 0);
		if (rc < 0)
@@ -1561,6 +1567,7 @@ static int wled_get_max_avail_current(struct led_classdev *led_cdev,
	struct wled *wled;
	int rc, ocv_mv, r_bat_mohms, i_bat_ma, i_sink_ma = 0, max_fsc_ma;
	int64_t p_out_string, p_out, p_in, v_safe_mv, i_flash_ma, v_ph_mv;
	union power_supply_propval prop = {};

	if (!strcmp(led_cdev->name, "wled_switch"))
		wled = container_of(led_cdev, struct wled, switch_cdev);
@@ -1576,6 +1583,38 @@ static int wled_get_max_avail_current(struct led_classdev *led_cdev,
		return 0;
	}

	if (wled->use_psy) {
		if (!wled->batt_psy)
			wled->batt_psy = power_supply_get_by_name("battery");

		if (!wled->batt_psy) {
			pr_err("Failed to get battery power supply\n");
			return -ENODEV;
		}

		rc = power_supply_get_property(wled->batt_psy, POWER_SUPPLY_PROP_VOLTAGE_OCV,
				&prop);
		if (rc < 0) {
			pr_err("Failed to get battery OCV, rc=%d\n", rc);
			return rc;
		}
		ocv_mv = prop.intval/1000;

		rc = power_supply_get_property(wled->batt_psy, POWER_SUPPLY_PROP_CURRENT_NOW,
				&prop);
		if (rc < 0) {
			pr_err("Failed to get battery current, rc=%d\n", rc);
			return rc;
		}
		i_bat_ma = -prop.intval/1000;

		rc = qti_battery_charger_get_prop("battery", BATTERY_RESISTANCE, &r_bat_mohms);
		if (rc < 0) {
			pr_err("Failed to get battery resistance, rc=%d\n", rc);
			return rc;
		}
		r_bat_mohms /= 1000;
	} else {
		rc = wled_iio_get_prop(wled, OCV, &ocv_mv);
		if (rc < 0) {
			pr_err("Error in getting OCV rc=%d\n", rc);
@@ -1596,6 +1635,7 @@ static int wled_get_max_avail_current(struct led_classdev *led_cdev,
			return rc;
		}
		r_bat_mohms /= 1000;
	}

	pr_debug("ocv: %d i_bat: %d r_bat: %d\n", ocv_mv, i_bat_ma,
		r_bat_mohms);
@@ -2340,6 +2380,14 @@ static int wled_probe(struct platform_device *pdev)
		return -ENODEV;
	}

	switch (*wled->version) {
	case WLED_PM7325B:
		wled->use_psy = true;
		break;
	default:
		break;
	}

	rc = wled_configure(wled, &pdev->dev);
	if (rc < 0) {
		dev_err(&pdev->dev, "wled configure failed rc:%d\n", rc);
@@ -2413,6 +2461,7 @@ static const struct of_device_id wled_match_table[] = {
	{ .compatible = "qcom,pm8150l-spmi-wled", .data = &version_table[2] },
	{ .compatible = "qcom,pm6150l-spmi-wled", .data = &version_table[2] },
	{ .compatible = "qcom,pm660l-spmi-wled",  .data = &version_table[1] },
	{ .compatible = "qcom,pm7325b-spmi-wled", .data = &version_table[3] },
	{ },
};

+13 −2
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
 */

#ifndef __LEDS_QTI_FLASH_H
@@ -35,7 +35,18 @@ static inline int qti_flash_led_prepare(struct led_trigger *trig,
}

static inline int qti_flash_led_set_param(struct led_trigger *trig,
			struct flash_led_param param);
			struct flash_led_param param)
{
	return -EINVAL;
}
#endif

#if IS_ENABLED(CONFIG_BACKLIGHT_QCOM_SPMI_WLED)
int wled_flash_led_prepare(struct led_trigger *trig, int options,
					int *max_current);
#else
static inline int wled_flash_led_prepare(struct led_trigger *trig, int options,
					int *max_current)
{
	return -EINVAL;
}