QC3P:copy of module mmi_parallel_charger_iio for mmi_discrete_turbo_charger

Code copy from mmi_parallel_charger_iio for the
initial code repo of mmi_discrete_turbo_charger
which used for discrete arch qc3p feature.

Change-Id: Ic0d302f084ee6f192c76ce3c6eaaa7276639c8ef
Signed-off-by: xuwei9 <xuwei9@lenovo.com>
Reviewed-on: https://gerrit.mot.com/2137095
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
xuwei9 2021-12-07 16:23:30 +08:00 committed by Wei Xu
parent b9bf3314c5
commit b1fed3aec8
15 changed files with 5892 additions and 0 deletions

View file

@ -0,0 +1,14 @@
DLKM_DIR := motorola/kernel/modules
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mmi_parallel_charger_iio.ko
LOCAL_MODULE_TAGS := optional
ifeq ($(DLKM_INSTALL_TO_VENDOR_OUT),true)
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/modules/
else
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
endif
include $(DLKM_DIR)/AndroidKernelModule.mk

View file

@ -0,0 +1,16 @@
# add -Wall to try to catch everything we can.
EXTRA_CFLAGS += -Wall
EXTRA_CFLAGS += -I$(TOP)/motorola/kernel/modules/include \
-I$(TOP)/motorola/kernel/modules/drivers/power/mmi_parallel_charger_iio
obj-m += mmi_parallel_charger_iio.o
mmi_parallel_charger_iio-objs += mmi_charger_class.o
mmi_parallel_charger_iio-objs += mmi_charger_core.o
mmi_parallel_charger_iio-objs += mmi_charger_pump_policy.o
mmi_parallel_charger_iio-objs += mmi_cp_charger.o
mmi_parallel_charger_iio-objs += qpnp_pmic_charger.o
mmi_parallel_charger_iio-objs += mmi_qc3p.o
mmi_parallel_charger_iio-objs += mmi_qc3p_cp_policy.o
#ifeq ($(CONFIG_MMI_PL_CP_POLICY), y)
#endif

View file

@ -0,0 +1,11 @@
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
all:
$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
modules_install:
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install
clean:
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean

View file

@ -0,0 +1,222 @@
/*
* Copyright (c) 2018 Motorola Mobility, LLC.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include "mmi_charger_class.h"
static struct class *mmi_charger_class;
int mmi_enable_charging(struct mmi_charger_device *chrg, bool en)
{
if(chrg != NULL && chrg->ops != NULL && chrg->ops->enable)
return chrg->ops->enable(chrg,en);
return -ENOTSUPP;
}
int mmi_is_charging_enabled(struct mmi_charger_device *chrg, bool *en)
{
if(chrg != NULL && chrg->ops != NULL && chrg->ops->is_enabled)
return chrg->ops->is_enabled(chrg,en);
return -ENOTSUPP;
}
int mmi_get_charing_current(struct mmi_charger_device *chrg, u32 *uA)
{
if(chrg != NULL && chrg->ops != NULL && chrg->ops->get_charging_current)
return chrg->ops->get_charging_current(chrg,uA);
return -ENOTSUPP;
}
int mmi_set_charing_current(struct mmi_charger_device *chrg, u32 uA)
{
if(chrg != NULL && chrg->ops != NULL && chrg->ops->set_charging_current)
return chrg->ops->set_charging_current(chrg,uA);
return -ENOTSUPP;
}
int mmi_get_vbus(struct mmi_charger_device *chrg, u32 *mv)
{
if(chrg != NULL && chrg->ops != NULL && chrg->ops->get_vbus)
return chrg->ops->get_vbus(chrg,mv);
return -ENOTSUPP;
}
int mmi_get_input_current_settled(struct mmi_charger_device *chrg, u32 *uA)
{
if(chrg != NULL && chrg->ops != NULL && chrg->ops->get_input_current_settled)
return chrg->ops->get_input_current_settled(chrg,uA);
return -ENOTSUPP;
}
int mmi_get_input_current(struct mmi_charger_device *chrg, u32 *uA)
{
if(chrg != NULL && chrg->ops != NULL && chrg->ops->get_input_current)
return chrg->ops->get_input_current(chrg,uA);
return -ENOTSUPP;
}
int mmi_set_input_current(struct mmi_charger_device *chrg, u32 uA)
{
if(chrg != NULL && chrg->ops != NULL && chrg->ops->set_input_current)
return chrg->ops->set_input_current(chrg,uA);
return -ENOTSUPP;
}
int mmi_update_charger_status(struct mmi_charger_device *chrg)
{
if(chrg != NULL && chrg->ops != NULL && chrg->ops->update_charger_status)
return chrg->ops->update_charger_status(chrg);
return -ENOTSUPP;
}
int mmi_update_charger_error(struct mmi_charger_device *chrg)
{
if(chrg != NULL && chrg->ops != NULL && chrg->ops->update_charger_error)
return chrg->ops->update_charger_error(chrg);
return -ENOTSUPP;
}
int mmi_clear_charger_error(struct mmi_charger_device *chrg)
{
if(chrg != NULL && chrg->ops != NULL && chrg->ops->clear_charger_error)
return chrg->ops->clear_charger_error(chrg);
return -ENOTSUPP;
}
static void mmi_charger_device_release(struct device *dev)
{
struct mmi_charger_device *charger_dev = to_mmi_charger_device(dev);
kfree(charger_dev);
return;
}
static int charger_match_device_by_name(struct device *dev,
const void *data)
{
const char *name = data;
return strcmp(dev_name(dev), name) == 0;
}
struct mmi_charger_device *get_charger_by_name(const char *name)
{
struct device *dev;
if(!name)
return (struct mmi_charger_device *)NULL;
dev = class_find_device(mmi_charger_class, NULL, name,
charger_match_device_by_name);
return dev ? to_mmi_charger_device(dev) : NULL;
}
int is_charger_exist(const char *name)
{
if (get_charger_by_name(name) == NULL)
return 0;
return 1;
}
struct mmi_charger_device *mmi_charger_device_register(const char *name,
const char *psy_name,struct device *parent, void *devdata,
const struct mmi_charger_ops *ops)
{
struct mmi_charger_device *charger_dev;
int rc;
pr_info("mmi charger device register: name=%s\n",name);
charger_dev = kzalloc(sizeof(struct mmi_charger_device),GFP_KERNEL);
if (!charger_dev)
return ERR_PTR(-ENOMEM);
mutex_init(&charger_dev->ops_lock);
charger_dev->dev.class = mmi_charger_class;
charger_dev->dev.parent = parent;
charger_dev->dev.release = mmi_charger_device_release;
charger_dev->name = name;
dev_set_name(&charger_dev->dev, "%s", name);
dev_set_drvdata(&charger_dev->dev, devdata);
rc = device_register(&charger_dev->dev);
if (rc) {
kfree(charger_dev);
return ERR_PTR(rc);
}
charger_dev->chrg_psy = power_supply_get_by_name(psy_name);
charger_dev->ops = ops;
if (!charger_dev->chrg_psy)
return ERR_PTR(-ENODEV);
pr_info("mmi charger device register: name=%s, successfully\n",name);
return charger_dev;
}
void mmi_charger_device_unregister(struct mmi_charger_device* charger_dev)
{
if (!charger_dev)
return;
mutex_lock(&charger_dev->ops_lock);
charger_dev->ops = NULL;
mutex_unlock(&charger_dev->ops_lock);
device_unregister(&charger_dev->dev);
}
void mmi_charger_class_exit(void)
{
class_destroy(mmi_charger_class);
}
int mmi_charger_class_init(void)
{
mmi_charger_class = class_create(THIS_MODULE, "mmi_charger");
if (IS_ERR(mmi_charger_class)) {
pr_err("Unable to create mmi charger class; error = %ld\n",
PTR_ERR(mmi_charger_class));
return PTR_ERR(mmi_charger_class);
}
pr_info("success to create mmi charger class \n");
return 0;
}

View file

@ -0,0 +1,134 @@
/*
* Copyright (c) 2018 Motorola Mobility, LLC.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MMI_CHRG_CLASS_H_
#define __MMI_CHRG_CLASS_H_
#include <linux/power_supply.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/usb/usbpd.h>
#include <linux/debugfs.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mutex.h>
#define chrg_dev_info(chip, fmt, ...) \
pr_info("%s: %s: " fmt, chip->name, \
__func__, ##__VA_ARGS__) \
struct mmi_charger_info {
bool vbus_pres;
int vbatt_volt;
int vbus_volt;
int ibatt_curr;
int ibus_curr;
int batt_temp;
};
#define MMI_BAT_OVP_ALARM_BIT 0
#define MMI_BAT_OCP_ALARM_BIT 1
#define MMI_BAT_UCP_ALARM_BIT 2
#define MMI_BUS_OVP_ALARM_BIT 3
#define MMI_BUS_OCP_ALARM_BIT 4
#define MMI_BUS_UCP_ALARM_BIT 5
#define MMI_BAT_OVP_FAULT_BIT 6
#define MMI_BAT_OCP_FAULT_BIT 7
#define MMI_BAT_UCP_FAULT_BIT 8
#define MMI_BUS_OVP_FAULT_BIT 9
#define MMI_BUS_OCP_FAULT_BIT 10
#define MMI_BUS_UCP_FAULT_BIT 11
#define MMI_CONV_OCP_FAULT_BIT 12
#define MMI_THERM_ALARM_BIT 13
#define MMI_THERM_FAULT_BIT 14
#define MMI_CP_SWITCH_BIT 18
struct mmi_charger_error_info {
int chrg_err_type;
int bus_ucp_err_cnt;
int bus_ocp_err_cnt;
};
struct mmi_charger_device {
const char *name; /*charger device name*/
struct power_supply *chrg_psy; /*power supply handle*/
const struct mmi_charger_ops *ops; /*operation function*/
struct mutex ops_lock;
struct device dev;
struct mmi_charger_info charger_data;
struct mmi_charger_error_info charger_error;
int *debug_mask;
int input_curr_setted; /*save input current*/
int charging_curr_limited; /*charger current limitation*/
int charging_curr_min; /*The minimum charging current supported by this device*/
bool charger_enabled; /*is this charger device enabled*/
bool charger_limited; /*is the charging current of this device limited*/
};
struct mmi_charger_ops {
int (*enable)(struct mmi_charger_device *chrg, bool en);
int (*is_enabled)(struct mmi_charger_device *chrg, bool *en);
int (*get_charging_current)(struct mmi_charger_device *chrg, u32 *uA);
int (*set_charging_current)(struct mmi_charger_device *chrg, u32 uA);
int (*get_input_current_settled)(struct mmi_charger_device *chrg, u32 *uA);
int (*get_vbus)(struct mmi_charger_device *chrg, u32 *mv);
int (*get_input_current)(struct mmi_charger_device *chrg, u32 *uA);
int (*set_input_current)(struct mmi_charger_device *chrg, u32 uA);
int (*update_charger_status)(struct mmi_charger_device *chrg);
int (*update_charger_error)(struct mmi_charger_device *chrg);
int (*clear_charger_error)(struct mmi_charger_device *chrg);
};
#define to_mmi_charger_device(obj) container_of(obj, struct mmi_charger_device, dev)
#define mmi_chrg_name(x) (dev_name(&(x)->dev))
extern struct mmi_charger_device *get_charger_by_name(const char *name);
extern int is_charger_exist(const char *name);
extern int mmi_charger_class_init(void);
extern void mmi_charger_class_exit(void);
extern int mmi_enable_charging(struct mmi_charger_device *chrg, bool en);
extern int mmi_is_charging_enabled(struct mmi_charger_device *chrg, bool *en);
extern int mmi_get_charing_current(struct mmi_charger_device *chrg, u32 *uA);
extern int mmi_set_charing_current(struct mmi_charger_device *chrg, u32 uA);
extern int mmi_get_input_current_settled(struct mmi_charger_device *chrg, u32 *uA);
extern int mmi_get_input_current(struct mmi_charger_device *chrg, u32 *uA);
extern int mmi_set_input_current(struct mmi_charger_device *chrg, u32 uA);
extern int mmi_update_charger_status(struct mmi_charger_device *chrg);
extern int mmi_update_charger_error(struct mmi_charger_device *chrg);
extern int mmi_clear_charger_error(struct mmi_charger_device *chrg);
extern int mmi_get_vbus(struct mmi_charger_device *chrg, u32 *mv);
extern struct mmi_charger_ops cp_charger_ops;
extern struct mmi_charger_ops qpnp_pmic_charger_ops;
extern struct mmi_charger_device *mmi_charger_device_register(const char *name,
const char *psy_name,struct device *parent, void *devdata,
const struct mmi_charger_ops *ops);
extern void mmi_charger_device_unregister(struct mmi_charger_device* charger_dev);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,319 @@
/*
* Copyright (c) 2018 Motorola Mobility, LLC.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MMI_CHRG_CORE_H_
#define __MMI_CHRG_CORE_H_
#include <linux/power_supply.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/usb/usbpd.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/debugfs.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/alarmtimer.h>
#include <linux/notifier.h>
#include "mmi_charger_class.h"
#include <linux/pm_wakeup.h>
#include <linux/build_bug.h>
#include <linux/compiler.h>
#define mmi_chrg_err(chip, fmt, ...) \
pr_err("%s: %s: " fmt, chip->name, \
__func__, ##__VA_ARGS__) \
#define mmi_chrg_info(chip, fmt, ...) \
pr_info("%s: %s: " fmt, chip->name, \
__func__, ##__VA_ARGS__) \
#define mmi_chrg_dbg(chip, reason, fmt, ...) \
do { \
if (*chip->debug_mask & (reason)) \
pr_info("%s: %s: " fmt, chip->name, \
__func__, ##__VA_ARGS__); \
else \
pr_debug("%s: %s: " fmt, chip->name, \
__func__, ##__VA_ARGS__); \
} while (0)
enum print_reason {
PR_INTERRUPT = BIT(0),
PR_MISC = BIT(2),
PR_MOTO = BIT(7),
};
enum {
POWER_SUPPLY_CHARGE_RATE_NONE = 0,
POWER_SUPPLY_CHARGE_RATE_NORMAL,
POWER_SUPPLY_CHARGE_RATE_WEAK,
POWER_SUPPLY_CHARGE_RATE_TURBO,
POWER_SUPPLY_CHARGE_RATE_TURBO_30W,
POWER_SUPPLY_CHARGE_RATE_HYPER,
};
static inline void wakeup_source_init_internal(struct wakeup_source *ws,
const char *name)
{
if(ws) {
memset(ws, 0, sizeof(*ws));
ws->name = name;
}
wakeup_source_add(ws);
}
#define MAX_NUM_STEPS 10
enum mmi_chrg_temp_zones {
ZONE_FIRST = 0,
/* states 0-9 are reserved for zones */
ZONE_LAST = MAX_NUM_STEPS + ZONE_FIRST - 1,
ZONE_HOT,
ZONE_COLD,
ZONE_NONE = 0xFF,
};
enum mmi_chrg_steps {
STEP_FIRST = 0,
STEP_LAST = MAX_NUM_STEPS + STEP_FIRST - 1,
STEP_NONE = 0xFF,
};
enum mmi_pd_pps_result {
NO_ERROR,
BLANCE_POWER,
RESET_POWER,
};
struct mmi_chrg_step_power {
u32 chrg_step_volt;
u32 chrg_step_curr;
};
struct mmi_chrg_temp_zone {
int temp_c; /*temperature*/
struct mmi_chrg_step_power *chrg_step_power;
};
struct mmi_chrg_step_info {
enum mmi_chrg_steps pres_chrg_step;
int temp_c;
int chrg_step_cc_curr;
int chrg_step_cv_volt;
int chrg_step_cv_tapper_curr;
bool last_step;
};
struct mmi_chrg_dev_ops {
const char *dev_name;
struct mmi_charger_ops *ops;
};
struct mmi_chrg_dts_info {
const char *chrg_name;
const char *psy_name;
int charging_curr_limited;
int charging_curr_min;
};
enum mmi_chrg_dev {
PMIC_SW = 0,
CP_MASTER,
CP_SLAVE,
CHRG_NUM,
};
struct mmi_cp_policy_dev {
bool pmic_sw;
bool cp_master;
bool cp_slave;
bool cp_clave_later;
struct mmi_charger_device *chrg_dev[CHRG_NUM];
};
#define PPS_RET_HISTORY_SIZE 8
#define PD_SRC_PDO_TYPE_FIXED 0
#define PD_SRC_PDO_TYPE_BATTERY 1
#define PD_SRC_PDO_TYPE_VARIABLE 2
#define PD_SRC_PDO_TYPE_AUGMENTED 3
#define STEP_FIREST_CURR_COMP 300000
#define TYPEC_HIGH_CURRENT_UA 3000000
#define TYPEC_MIDDLE_CURRENT_UA 2000000
#define PD_ALLOW_MIN_CURRENT_UA 1500000
#define SWITCH_CHARGER_PPS_VOLT 5000000
#define PUMP_CHARGER_PPS_MIN_VOLT 8000000
#define COOLING_HYSTERISIS_DEGC 2
struct mmi_charger_manager {
const char *name;
struct device *dev;
struct power_supply *batt_psy;
struct power_supply *qcom_psy;
struct power_supply *usb_psy;
struct power_supply *mmi_chrg_mgr_psy;
struct usbpd *pd_handle;
struct usbpd_pdo_info mmi_pdo_info[PD_MAX_PDO_NUM];
struct notifier_block psy_nb;
struct iio_channel **ext_iio_chans;
struct iio_dev *indio_dev;
struct iio_chan_spec *iio_chan;
struct iio_channel *int_iio_chans;
bool factory_mode;
bool suspended;
bool awake;
bool cp_disable;
int *debug_mask;
int mmi_pd_pdo_idx; /*request the pdo idx of PD*/
int pps_volt_steps; /*PPS voltage, programming step size*/
int pps_curr_steps; /*pps current, programming step size*/
int pd_volt_max; /*the Maximum request PD Voltage*/
int pd_curr_max; /*the Maximum request PD current*/
int batt_ovp_lmt; /*the battery over current limitation*/
int pl_chrg_vbatt_min; /*the minimum battery voltage to enable parallel charging*/
int typec_middle_current;
int pd_allow_min_current;
int step_first_curr_comp;
int pps_volt_comp;
int pd_request_volt;
int pd_request_curr;
/*the request PD power*/
int pd_request_volt_prev;
int pd_request_curr_prev;
/*the previous request PD power*/
int pd_sys_therm_volt;
int pd_sys_therm_curr;
/*the thermal PD power*/
int pd_batt_therm_volt;
int pd_batt_therm_curr;
int pd_target_volt;
int pd_target_curr;
/*the final commited request PD power*/
int pps_result;
int pps_result_history[PPS_RET_HISTORY_SIZE];
int pps_result_history_idx;
/*save the result of the return from PD request*/
bool vbus_present;
bool pd_pps_support;
bool pd_pps_balance;
bool freeze_pd_power;
bool extrn_fg;
const char *extrn_fg_name;
bool extrn_sense;
bool recovery_pmic_chrg;
bool dont_rerun_aicl;
bool sys_therm_cooling;
bool sys_therm_force_pmic_chrg;
bool batt_therm_cooling;
int batt_therm_cooling_cnt;
struct delayed_work mmi_chrg_sm_work; /*mmi charger state machine work*/
struct delayed_work heartbeat_work; /*cycle trig heartbeat work*/
struct completion sm_completion;
struct work_struct psy_changed_work; /*the change notification of power supply*/
bool sm_work_running;
int num_temp_zones;
struct mmi_chrg_temp_zone *temp_zones; /*the temperature zone of charging*/
enum mmi_chrg_temp_zones pres_temp_zone; /*the present zone idx*/
int *thermal_mitigation; /*thermal mitigation array*/
int thermal_levels;
int system_thermal_level; /*thermal level setting*/
int chrg_step_nums;
struct mmi_chrg_step_info chrg_step; /*step charger info*/
int mmi_chrg_dev_num;
struct mmi_charger_device **chrg_list; /*charger device list*/
/*qc3p*/
int qc3p_max_ibus_ma;
int qc3p_power;
bool qc3p_active;
bool qc3p_sm_work_running;
struct delayed_work mmi_qc3p_chrg_sm_work;
int qc3p_request_volt;
int qc3p_request_volt_prev;
int qc3p_target_volt;
int qc3p_batt_therm_volt;
int qc3p_sys_therm_volt;
bool qc3p_recovery_pmic_chrg;
bool qc3p_sys_therm_cooling;
bool qc3p_sys_therm_force_pmic_chrg;
bool qc3p_batt_therm_cooling;
int qc3p_batt_therm_cooling_cnt;
int qc3p_volt_comp;
int qc3p_ibus_max_volt;
int qc3p_volt_steps;
int qc3p_volt_max;
};
#define PPS_INIT_VOLT_COMP 500000
#define QC3P_INIT_VOLT_COMP 500000
extern void mmi_qc3p_chrg_sm_work_func(struct work_struct *work);
extern struct mmi_cp_policy_dev g_chrg_list;
extern const struct mmi_chrg_dev_ops dev_ops[];
extern void clear_chrg_dev_error_cnt(struct mmi_charger_manager *chip, struct mmi_cp_policy_dev *chrg_list);
extern void chrg_policy_error_clear(struct mmi_charger_manager *chip, struct mmi_cp_policy_dev *chrg_list);
extern void mmi_chrg_sm_work_func(struct work_struct *work);
extern void chrg_dev_init(struct mmi_charger_manager *chip, struct mmi_cp_policy_dev *chrg_list);
extern bool mmi_get_pps_result_history(struct mmi_charger_manager *chip);
extern void mmi_set_pps_result_history(struct mmi_charger_manager *chip, int pps_result);
extern void mmi_clear_pps_result_history(struct mmi_charger_manager *chip);
extern int mmi_calculate_delta_volt(int pps_voltage, int pps_current, int delta_curr);
extern bool mmi_find_chrg_step(struct mmi_charger_manager *chip, int temp_zone, int vbatt_volt);
extern bool mmi_find_temp_zone(struct mmi_charger_manager *chip, int temp_c, bool ignore_hysteresis_degc);
extern void mmi_update_all_charger_status(struct mmi_charger_manager *chip);
extern void mmi_update_all_charger_error(struct mmi_charger_manager *chip);
extern void mmi_dump_charger_error(struct mmi_charger_manager *chip,
struct mmi_charger_device *chrg_dev);
extern bool mmi_is_cable_plugout(struct mmi_charger_manager *chip);
extern ssize_t mmi_get_factory_image_mode(void);
extern ssize_t mmi_set_factory_image_mode(int mode);
extern ssize_t mmi_get_factory_charge_upper(void);
extern ssize_t mmi_get_demo_mode(void);
extern ssize_t mmi_set_demo_mode(int mode);
extern ssize_t mmi_get_max_chrg_temp(void);
extern ssize_t mmi_set_max_chrg_temp(int value);
#endif

View file

@ -0,0 +1,82 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
*/
#ifndef __MMI_CHRG_CORE_IIO_H
#define __MMI_CHRG_CORE_IIO_H
#include <linux/iio/iio.h>
#include <dt-bindings/iio/qti_power_supply_iio.h>
struct mmi_charger_iio_channels {
const char *datasheet_name;
int channel_num;
enum iio_chan_type type;
long info_mask;
};
#define MMI_CHARGER_IIO_CHAN(_name, _num, _type, _mask) \
{ \
.datasheet_name = _name, \
.channel_num = _num, \
.type = _type, \
.info_mask = _mask, \
},
#define MMI_CHARGER_CHAN_INDEX(_name, _num) \
MMI_CHARGER_IIO_CHAN(_name, _num, IIO_INDEX, \
BIT(IIO_CHAN_INFO_PROCESSED))
static const struct mmi_charger_iio_channels mmi_charger_iio_psy_channels[] = {
MMI_CHARGER_CHAN_INDEX("cp_charging_enabled", PSY_IIO_CP_ENABLE)
};
enum mmi_charger_ext_iio_channels {
/*smb5*/
SMB5_HW_CURRENT_MAX,
SMB5_CHARGING_ENABLED,
SMB5_TYPEC_MODE,
SMB5_USB_INPUT_CURRENT_SETTLED,
SMB5_USB_PD_ACTIVE,
/*qc3p*/
SMB5_USB_REAL_TYPE,
SMB5_DP_DM,
SMB5_QC3P_POWER,
/*cp*/
CP_ENABLE,
CP_INPUT_CURRENT_NOW,
CP_INPUT_VOLTAGE_NOW,
CP_STATUS1,
CP_CLEAR_ERROR,
/*mmi-smb5charger-iio*/
MMI_CP_ENABLE_STATUS,
};
static const char * const mmi_charger_ext_iio_chan_name[] = {
/*smb5*/
[SMB5_HW_CURRENT_MAX] = "usb_hw_current_max",
[SMB5_CHARGING_ENABLED] = "charging_enabled",
[SMB5_TYPEC_MODE] = "usb_typec_mode",
[SMB5_USB_INPUT_CURRENT_SETTLED] = "usb_input_current_settled",
[SMB5_USB_PD_ACTIVE] = "usb_pd_active",
/*qc3p*/
[SMB5_USB_REAL_TYPE] = "usb_real_type",
[SMB5_DP_DM] = "battery_dp_dm",
[SMB5_QC3P_POWER] = "usb_qc3p_power",
/*cp*/
[CP_ENABLE] = "cp_enable",
[CP_INPUT_CURRENT_NOW] = "cp_input_current_now",
[CP_INPUT_VOLTAGE_NOW] = "cp_input_voltage_now",
[CP_STATUS1] = "cp_status1",
[CP_CLEAR_ERROR] = "cp_clear_error",
/*mmi-smb5charger-iio*/
[MMI_CP_ENABLE_STATUS] = "mmi_cp_enabled_status",
};
int mmi_charger_read_iio_chan(struct mmi_charger_manager *chip,
enum mmi_charger_ext_iio_channels chan, int *val);
int mmi_charger_write_iio_chan(struct mmi_charger_manager *chip,
enum mmi_charger_ext_iio_channels chan, int val);
#endif

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2018 Motorola Mobility, LLC.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MMI_CHRG_POLICY_H_
#define __MMI_CHRG_POLICY_H_
extern void mmi_chrg_policy_clear(struct mmi_charger_manager *chip);
extern void mmi_chrg_enable_all_cp(struct mmi_charger_manager *chip, int val);
extern void mmi_qc3p_chrg_policy_clear(struct mmi_charger_manager *chip);
extern void mmi_qc3p_chrg_enable_all_cp(struct mmi_charger_manager *chip, int val);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,225 @@
/*
* Copyright (c) 2018 Motorola Mobility, LLC.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include "mmi_charger_class.h"
#include <linux/power_supply.h>
#include "mmi_charger_core.h"
#include "mmi_charger_core_iio.h"
static int cp_enable_charging(struct mmi_charger_device *chrg, bool en)
{
int rc;
struct mmi_charger_manager *chip = dev_get_drvdata(&chrg->dev);
if (!chip)
return -ENODEV;
rc = mmi_charger_write_iio_chan(chip, CP_ENABLE, en);
if (!rc) {
chrg->charger_enabled = !!en;
} else
chrg->charger_enabled = false;
return rc;
}
static int cp_is_charging_enabled(struct mmi_charger_device *chrg, bool *en)
{
int rc;
int value;
struct mmi_charger_manager *chip = dev_get_drvdata(&chrg->dev);
if (!chip)
return -ENODEV;
rc = mmi_charger_read_iio_chan(chip, CP_ENABLE, &value);
if (!rc) {
chrg->charger_enabled = !!value;
} else
chrg->charger_enabled = false;
*en = chrg->charger_enabled;
return rc;
}
static int cp_get_charging_current(struct mmi_charger_device *chrg, u32 *uA)
{
int rc;
union power_supply_propval prop = {0,};
if (!chrg->chrg_psy)
return -ENODEV;
rc = power_supply_get_property(chrg->chrg_psy,
POWER_SUPPLY_PROP_CURRENT_NOW, &prop);
if (!rc)
*uA = !!prop.intval;
return rc;
}
static int cp_get_vbus(struct mmi_charger_device *chrg, u32 *mv)
{
int rc, val;
struct mmi_charger_manager *chip = dev_get_drvdata(&chrg->dev);
if (!chip)
return -ENODEV;
rc = mmi_charger_read_iio_chan(chip, CP_INPUT_VOLTAGE_NOW, &val);
if (!rc)
*mv = val;
return rc;
}
static int cp_get_input_current(struct mmi_charger_device *chrg, u32 *uA) //ibus
{
int rc;
int value;
struct mmi_charger_manager *chip = dev_get_drvdata(&chrg->dev);
if (!chip)
return -ENODEV;
rc = mmi_charger_read_iio_chan(chip, CP_INPUT_CURRENT_NOW, &value);
if (!rc)
*uA = value;
return rc;
}
static int cp_update_charger_status(struct mmi_charger_device *chrg)
{
int rc;
struct mmi_charger_manager *chip = dev_get_drvdata(&chrg->dev);
union power_supply_propval prop = {0,};
if (!chrg->chrg_psy)
return -ENODEV;
rc = power_supply_get_property(chrg->chrg_psy,
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &prop);
if (!rc)
chrg->charger_data.ibus_curr= prop.intval;
rc = power_supply_get_property(chrg->chrg_psy,
POWER_SUPPLY_PROP_VOLTAGE_NOW, &prop);
if (!rc)
chrg->charger_data.vbatt_volt = prop.intval;
rc = power_supply_get_property(chrg->chrg_psy,
POWER_SUPPLY_PROP_CURRENT_NOW, &prop);
if (!rc)
chrg->charger_data.ibatt_curr = prop.intval;
rc = power_supply_get_property(chrg->chrg_psy,
POWER_SUPPLY_PROP_TEMP, &prop);
if (!rc)
chrg->charger_data.batt_temp = prop.intval;
rc = mmi_charger_read_iio_chan(chip, CP_INPUT_VOLTAGE_NOW, &prop.intval);
if (!rc)
chrg->charger_data.vbus_volt = prop.intval;
rc = mmi_charger_read_iio_chan(chip, CP_INPUT_CURRENT_NOW, &prop.intval);
if (!rc)
chrg->charger_data.ibus_curr = prop.intval;
rc = power_supply_get_property(chrg->chrg_psy,
POWER_SUPPLY_PROP_PRESENT, &prop);
if (!rc)
chrg->charger_data.vbus_pres = !!prop.intval;
rc = mmi_charger_read_iio_chan(chip, CP_ENABLE, &prop.intval);
if (!rc)
chrg->charger_enabled = !!prop.intval;
chrg_dev_info(chrg, "CP chrg: %s status update: --- info---\n",chrg->name);
chrg_dev_info(chrg, "vbatt %d\n", chrg->charger_data.vbatt_volt);
chrg_dev_info(chrg, "ibatt %d\n", chrg->charger_data.ibatt_curr);
chrg_dev_info(chrg, "batt temp %d\n", chrg->charger_data.batt_temp);
chrg_dev_info(chrg, "vbus %d\n", chrg->charger_data.vbus_volt);
chrg_dev_info(chrg, "ibus %d\n", chrg->charger_data.ibus_curr);
chrg_dev_info(chrg, "vbus pres %d\n", chrg->charger_data.vbus_pres);
chrg_dev_info(chrg, "charger_enabled %d\n", chrg->charger_enabled);
return rc;
}
static int cp_update_charger_error_status(struct mmi_charger_device *chrg)
{
int rc;
int value = 0;
struct mmi_charger_manager *chip = dev_get_drvdata(&chrg->dev);
if (!chip)
return -ENODEV;
rc = mmi_charger_read_iio_chan(chip, CP_STATUS1, &value);
if (!rc) {
chrg->charger_error.chrg_err_type = value;
}
return rc;
}
static int cp_clear_charger_error(struct mmi_charger_device *chrg)
{
int rc;
int value = 0;
struct mmi_charger_manager *chip = dev_get_drvdata(&chrg->dev);
if (!chip)
return -ENODEV;
rc = mmi_charger_write_iio_chan(chip, CP_CLEAR_ERROR, value);
return rc;
}
struct mmi_charger_ops cp_charger_ops = {
.enable = cp_enable_charging,
.is_enabled = cp_is_charging_enabled,
.get_charging_current = cp_get_charging_current,
.get_vbus = cp_get_vbus,
.get_input_current = cp_get_input_current,
.update_charger_status = cp_update_charger_status,
.update_charger_error = cp_update_charger_error_status,
.clear_charger_error = cp_clear_charger_error,
};

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2012 Motorola Mobility, LLC.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mmi_charger_core.h"
#include "mmi_charger_core_iio.h"
#include <linux/qti_power_supply.h>
bool mmi_qc3p_power_active(struct mmi_charger_manager *chg)
{
int ret, iio_val;
ret = mmi_charger_read_iio_chan(chg, SMB5_USB_REAL_TYPE, &iio_val);
if (ret < 0) {
mmi_chrg_err(chg, "Couldn't read charger type rc=%d\n", ret);
return false;
}
if (iio_val != QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5)
return false;
ret = mmi_charger_read_iio_chan(chg, SMB5_QC3P_POWER, &iio_val);
if (ret < 0) {
mmi_chrg_err(chg, "Couldn't read qc3p power rc=%d\n", ret);
return false;
}
chg->qc3p_power = iio_val;
mmi_chrg_info(chg, "qc3p_power =%d\n", chg->qc3p_power);
if (chg->qc3p_power == QTI_POWER_SUPPLY_QC3P_27W ||
chg->qc3p_power == QTI_POWER_SUPPLY_QC3P_45W)
return true;
else
return false;
}
#define QC3P_PULSE_COUNT_MAX ((11000 - 5000) / 20 + 10)
int mmi_qc3p_set_vbus_voltage(struct mmi_charger_manager *chg, int target_mv)
{
int rc = -EINVAL;
union power_supply_propval val = {0, };
int pulse_cnt, curr_vbus_mv, step, i;
rc = mmi_charger_read_iio_chan(chg, SMB5_DP_DM, &val.intval);
if (rc < 0) {
mmi_chrg_err(chg, "Couldn't read dpdm pulse count rc=%d\n", rc);
return -EINVAL;
} else {
mmi_chrg_info(chg, "DP DM pulse count = %d\n", val.intval);
pulse_cnt = val.intval;
}
rc = mmi_get_vbus(chg->chrg_list[CP_MASTER],
&curr_vbus_mv);
if (rc) {
mmi_chrg_err(chg, "Unable to read USB voltage: %d\n", rc);
return -EINVAL;
}
if(target_mv < curr_vbus_mv) {
step = (curr_vbus_mv - target_mv) / 20;
val.intval = QTI_POWER_SUPPLY_DP_DM_DM_PULSE;
if (pulse_cnt <= step)
step = pulse_cnt;
} else {
step = (target_mv - curr_vbus_mv) / 20;
val.intval = QTI_POWER_SUPPLY_DP_DM_DP_PULSE;
if (step + pulse_cnt > QC3P_PULSE_COUNT_MAX)
step = QC3P_PULSE_COUNT_MAX - pulse_cnt;
}
mmi_chrg_info(chg, "curr_vbus= %d, target_vbus = %d, step = %d\n",curr_vbus_mv, target_mv, step);
for (i = 0; i < step; i++) {
rc = mmi_charger_write_iio_chan(chg, SMB5_DP_DM, val.intval);
if (rc < 0) {
mmi_chrg_err(chg, "Couldn't set dpdm pulse rc=%d\n", rc);
break;
}
if (i < step - 1)
udelay(5000);
}
rc = mmi_get_vbus(chg->chrg_list[CP_MASTER],
&curr_vbus_mv);
if (rc) {
mmi_chrg_err(chg, "Unable to read VBUS: %d\n", rc);
return -EINVAL;
}
mmi_chrg_info(chg, "result_vbus= %d\n",curr_vbus_mv);
return curr_vbus_mv;
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2021 Motorola Mobility, LLC.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
extern bool mmi_qc3p_power_active(struct mmi_charger_manager *chg);
extern int mmi_qc3p_set_vbus_voltage(struct mmi_charger_manager *chg, int target_mv);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,222 @@
/*
* Copyright (c) 2018 Motorola Mobility, LLC.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include "mmi_charger_class.h"
#include <linux/power_supply.h>
#include "mmi_charger_core.h"
#include "mmi_charger_core_iio.h"
static int qpnp_pmic_enable_charging(struct mmi_charger_device *chrg, bool en)
{
int rc = 0;
struct mmi_charger_manager *chip = dev_get_drvdata(&chrg->dev);
if (!chip)
return -ENODEV;
rc = mmi_charger_write_iio_chan(chip, SMB5_CHARGING_ENABLED, en);
if (!rc) {
chrg->charger_enabled = en;
} else {
chrg->charger_enabled = false;
}
return rc;
}
static int qpnp_pmic_is_charging_enabled(struct mmi_charger_device *chrg, bool *en)
{
int rc = 0;
int value;
struct mmi_charger_manager *chip = dev_get_drvdata(&chrg->dev);
if (!chip)
return -ENODEV;
rc = mmi_charger_read_iio_chan(chip, SMB5_CHARGING_ENABLED, &value);
if (!rc) {
chrg->charger_enabled = !!value;
} else
chrg->charger_enabled = false;
*en = chrg->charger_enabled;
return rc;
}
static int qpnp_pmic_get_charging_current(struct mmi_charger_device *chrg, u32 *uA)
{
int rc;
union power_supply_propval prop = {0,};
if (!chrg->chrg_psy)
return -ENODEV;
rc = power_supply_get_property(chrg->chrg_psy,
POWER_SUPPLY_PROP_CURRENT_NOW, &prop);
if (!rc)
*uA = prop.intval;
return rc;
}
static int qpnp_pmic_get_ibus(struct mmi_charger_device *chrg, u32 *uA)
{
int rc;
static struct power_supply *usb_psy;
union power_supply_propval prop = {0,};
if (!usb_psy)
usb_psy = power_supply_get_by_name("usb");
if (!usb_psy)
return -ENODEV;
rc = power_supply_get_property(usb_psy,
POWER_SUPPLY_PROP_CURRENT_NOW, &prop);
if (!rc)
*uA = prop.intval;
return rc;
}
static int qpnp_pmic_set_charging_current(struct mmi_charger_device *chrg, u32 uA)
{
int rc;
union power_supply_propval prop = {0,};
if (!chrg->chrg_psy)
return -ENODEV;
prop.intval = uA;
rc = power_supply_set_property(chrg->chrg_psy,
POWER_SUPPLY_PROP_CURRENT_MAX, &prop);
// if (!rc)
// chrg->charger_limited = true;
return rc;
}
static int qpnp_pmic_get_input_current_settled(struct mmi_charger_device *chrg, u32 *uA)
{
int rc = 0;
int value;
struct mmi_charger_manager *chip = dev_get_drvdata(&chrg->dev);
if (!chip)
return -ENODEV;
rc = mmi_charger_read_iio_chan(chip, SMB5_HW_CURRENT_MAX, &value);
if (!rc)
chrg->input_curr_setted = value;
*uA = chrg->input_curr_setted;
return rc;
}
static int qpnp_pmic_update_charger_status(struct mmi_charger_device *chrg)
{
int rc;
bool value = 0;
static struct power_supply *usb_psy = NULL;
union power_supply_propval prop = {0,};
if (!chrg->chrg_psy)
return -ENODEV;
if (!usb_psy)
usb_psy = power_supply_get_by_name("usb");
if (!usb_psy)
return -ENODEV;
rc = power_supply_get_property(usb_psy,
POWER_SUPPLY_PROP_CURRENT_NOW, &prop);
if (!rc)
chrg->charger_data.ibus_curr= prop.intval;
rc = power_supply_get_property(chrg->chrg_psy,
POWER_SUPPLY_PROP_VOLTAGE_NOW, &prop);
if (!rc)
chrg->charger_data.vbatt_volt = prop.intval;
rc = power_supply_get_property(chrg->chrg_psy,
POWER_SUPPLY_PROP_CURRENT_NOW, &prop);
if (!rc)
chrg->charger_data.ibatt_curr = prop.intval;
rc = power_supply_get_property(chrg->chrg_psy,
POWER_SUPPLY_PROP_TEMP, &prop);
if (!rc)
chrg->charger_data.batt_temp = prop.intval / 10;
rc = power_supply_get_property(usb_psy,
POWER_SUPPLY_PROP_VOLTAGE_NOW, &prop);
if (!rc)
chrg->charger_data.vbus_volt = prop.intval;
rc = power_supply_get_property(usb_psy,
POWER_SUPPLY_PROP_CURRENT_NOW, &prop);
if (!rc)
chrg->charger_data.ibus_curr = prop.intval;
rc = power_supply_get_property(usb_psy,
POWER_SUPPLY_PROP_PRESENT, &prop);
if (!rc)
chrg->charger_data.vbus_pres = !!prop.intval;
rc = qpnp_pmic_is_charging_enabled(chrg, &value);
if (!rc)
chrg->charger_enabled= !!value;
chrg_dev_info(chrg, "QPNP SW chrg: status update: --- info---");
chrg_dev_info(chrg, "vbatt %d\n", chrg->charger_data.vbatt_volt);
chrg_dev_info(chrg, "ibatt %d\n", chrg->charger_data.ibatt_curr);
chrg_dev_info(chrg, "batt temp %d\n", chrg->charger_data.batt_temp);
chrg_dev_info(chrg, "vbus %d\n", chrg->charger_data.vbus_volt);
chrg_dev_info(chrg, "ibus %d\n", chrg->charger_data.ibus_curr);
chrg_dev_info(chrg, "vbus pres %d\n", chrg->charger_data.vbus_pres);
chrg_dev_info(chrg, "charger_enabled %d\n", chrg->charger_enabled);
chrg_dev_info(chrg, "charger_limited %d\n", chrg->charger_limited);
return rc;
}
struct mmi_charger_ops qpnp_pmic_charger_ops = {
.enable = qpnp_pmic_enable_charging,
.is_enabled = qpnp_pmic_is_charging_enabled,
.get_charging_current = qpnp_pmic_get_charging_current,
.get_input_current = qpnp_pmic_get_ibus,
.set_charging_current = qpnp_pmic_set_charging_current,
.get_input_current_settled = qpnp_pmic_get_input_current_settled,
.update_charger_status = qpnp_pmic_update_charger_status,
};