pmic-voter: improve pmic-voter api implementation
Currently the pmic-voter api assumes that the clients are represented as unique integers. Using strings instead of integers adds flexibility. - It enables the votable to be shared across multiple drivers without having a common client enum - Debug prints become more useful While at it - remove the use of num_clients in the apis. All of them default to NUM_CLIENTS. - Create a list of all the votables, this allows for searching for a specific votable. - Error if a votable is already created with the same name earlier. - Add debug prints about current clients and effective results - Remove passing in last_client and last_client_id in the callback. These parameters go unused in all the usecases. - Since clients are assigned sequentially and that they cannot unregister from a votable (clients can only disable their votes, but they cannot remove themselves), a null string in the client string array means there are no more clients. Use this to speed up result calculation by stopping at the id with a null string. - Refactor the vote() implementation. Currently the SET_ANY case flows differently than MIN or MAX, make them uniform. - Create an api to call the callback without casting new votes. CRs-Fixed: 1018090 Change-Id: I8e2bc3366ec12e8485e4be86ee56ba5e4d113c3c Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
parent
31bcecd1a2
commit
74d9ef758e
5 changed files with 407 additions and 274 deletions
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015 The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -10,6 +10,7 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/bitops.h>
|
||||
|
@ -20,15 +21,21 @@
|
|||
|
||||
#define NUM_MAX_CLIENTS 8
|
||||
|
||||
static DEFINE_SPINLOCK(votable_list_slock);
|
||||
static LIST_HEAD(votable_list);
|
||||
|
||||
static struct dentry *debug_root;
|
||||
|
||||
struct client_vote {
|
||||
int state;
|
||||
bool enabled;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct votable {
|
||||
const char *name;
|
||||
struct list_head list;
|
||||
struct client_vote votes[NUM_MAX_CLIENTS];
|
||||
struct device *dev;
|
||||
const char *name;
|
||||
int num_clients;
|
||||
int type;
|
||||
int effective_client_id;
|
||||
|
@ -37,53 +44,84 @@ struct votable {
|
|||
struct mutex vote_lock;
|
||||
int (*callback)(struct device *dev,
|
||||
int effective_result,
|
||||
int effective_client,
|
||||
int last_result,
|
||||
int last_client);
|
||||
const char *effective_client);
|
||||
char *client_strs[NUM_MAX_CLIENTS];
|
||||
struct dentry *ent;
|
||||
};
|
||||
|
||||
static int vote_set_any(struct votable *votable)
|
||||
static void vote_set_any(struct votable *votable, int client_id,
|
||||
int *eff_res, int *eff_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < votable->num_clients; i++)
|
||||
if (votable->votes[i].state == 1)
|
||||
return 1;
|
||||
return 0;
|
||||
for (i = 0; i < votable->num_clients && votable->client_strs[i]; i++)
|
||||
*eff_res |= votable->votes[i].enabled;
|
||||
|
||||
*eff_id = client_id;
|
||||
}
|
||||
|
||||
static int vote_min(struct votable *votable)
|
||||
static void vote_min(struct votable *votable, int client_id,
|
||||
int *eff_res, int *eff_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
*eff_res = INT_MAX;
|
||||
*eff_id = -EINVAL;
|
||||
for (i = 0; i < votable->num_clients && votable->client_strs[i]; i++) {
|
||||
if (votable->votes[i].enabled
|
||||
&& *eff_res > votable->votes[i].value) {
|
||||
*eff_res = votable->votes[i].value;
|
||||
*eff_id = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vote_max(struct votable *votable, int client_id,
|
||||
int *eff_res, int *eff_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
*eff_res = INT_MIN;
|
||||
*eff_id = -EINVAL;
|
||||
for (i = 0; i < votable->num_clients && votable->client_strs[i]; i++) {
|
||||
if (votable->votes[i].enabled &&
|
||||
*eff_res < votable->votes[i].value) {
|
||||
*eff_res = votable->votes[i].value;
|
||||
*eff_id = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int get_client_id(struct votable *votable, const char *client_str)
|
||||
{
|
||||
int min_vote = INT_MAX;
|
||||
int client_index = -EINVAL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < votable->num_clients; i++) {
|
||||
if (votable->votes[i].state == 1 &&
|
||||
min_vote > votable->votes[i].value) {
|
||||
min_vote = votable->votes[i].value;
|
||||
client_index = i;
|
||||
}
|
||||
if (votable->client_strs[i]
|
||||
&& (strcmp(votable->client_strs[i], client_str) == 0))
|
||||
return i;
|
||||
}
|
||||
|
||||
return client_index;
|
||||
/* new client */
|
||||
for (i = 0; i < votable->num_clients; i++) {
|
||||
if (!votable->client_strs[i]) {
|
||||
votable->client_strs[i]
|
||||
= devm_kstrdup(votable->dev,
|
||||
client_str, GFP_KERNEL);
|
||||
if (!votable->client_strs[i])
|
||||
return -ENOMEM;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int vote_max(struct votable *votable)
|
||||
static char *get_client_str(struct votable *votable, int client_id)
|
||||
{
|
||||
int max_vote = INT_MIN;
|
||||
int client_index = -EINVAL;
|
||||
int i;
|
||||
if (client_id == -EINVAL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < votable->num_clients; i++) {
|
||||
if (votable->votes[i].state == 1 &&
|
||||
max_vote < votable->votes[i].value) {
|
||||
max_vote = votable->votes[i].value;
|
||||
client_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
return client_index;
|
||||
return votable->client_strs[client_id];
|
||||
}
|
||||
|
||||
void lock_votable(struct votable *votable)
|
||||
|
@ -96,30 +134,26 @@ void unlock_votable(struct votable *votable)
|
|||
mutex_unlock(&votable->vote_lock);
|
||||
}
|
||||
|
||||
int get_client_vote(struct votable *votable, int client_id)
|
||||
int get_client_vote_locked(struct votable *votable, const char *client_str)
|
||||
{
|
||||
int value;
|
||||
int client_id = get_client_id(votable, client_str);
|
||||
|
||||
lock_votable(votable);
|
||||
value = get_client_vote_locked(votable, client_id);
|
||||
unlock_votable(votable);
|
||||
return value;
|
||||
}
|
||||
if (client_id < 0)
|
||||
return votable->default_result;
|
||||
|
||||
int get_client_vote_locked(struct votable *votable, int client_id)
|
||||
{
|
||||
if (votable->votes[client_id].state < 0)
|
||||
if ((votable->type != VOTE_SET_ANY)
|
||||
&& !votable->votes[client_id].enabled)
|
||||
return votable->default_result;
|
||||
|
||||
return votable->votes[client_id].value;
|
||||
}
|
||||
|
||||
int get_effective_result(struct votable *votable)
|
||||
int get_client_vote(struct votable *votable, const char *client_str)
|
||||
{
|
||||
int value;
|
||||
|
||||
lock_votable(votable);
|
||||
value = get_effective_result_locked(votable);
|
||||
value = get_client_vote_locked(votable, client_str);
|
||||
unlock_votable(votable);
|
||||
return value;
|
||||
}
|
||||
|
@ -132,60 +166,73 @@ int get_effective_result_locked(struct votable *votable)
|
|||
return votable->effective_result;
|
||||
}
|
||||
|
||||
int get_effective_client_id(struct votable *votable)
|
||||
int get_effective_result(struct votable *votable)
|
||||
{
|
||||
int id;
|
||||
int value;
|
||||
|
||||
lock_votable(votable);
|
||||
id = get_effective_client_id_locked(votable);
|
||||
value = get_effective_result_locked(votable);
|
||||
unlock_votable(votable);
|
||||
return id;
|
||||
return value;
|
||||
}
|
||||
|
||||
int get_effective_client_id_locked(struct votable *votable)
|
||||
const char *get_effective_client_locked(struct votable *votable)
|
||||
{
|
||||
return votable->effective_client_id;
|
||||
return get_client_str(votable, votable->effective_client_id);
|
||||
}
|
||||
|
||||
int vote(struct votable *votable, int client_id, bool state, int val)
|
||||
const char *get_effective_client(struct votable *votable)
|
||||
{
|
||||
int effective_id = - EINVAL;
|
||||
const char *client_str;
|
||||
|
||||
lock_votable(votable);
|
||||
client_str = get_effective_client_locked(votable);
|
||||
unlock_votable(votable);
|
||||
return client_str;
|
||||
}
|
||||
|
||||
int vote(struct votable *votable, const char *client_str, bool enabled, int val)
|
||||
{
|
||||
int effective_id = -EINVAL;
|
||||
int effective_result;
|
||||
int client_id;
|
||||
int rc = 0;
|
||||
|
||||
lock_votable(votable);
|
||||
|
||||
if (votable->votes[client_id].state == state &&
|
||||
votable->votes[client_id].value == val) {
|
||||
pr_debug("%s: votes unchanged; skipping\n", votable->name);
|
||||
client_id = get_client_id(votable, client_str);
|
||||
if (client_id < 0) {
|
||||
rc = client_id;
|
||||
goto out;
|
||||
}
|
||||
|
||||
votable->votes[client_id].state = state;
|
||||
if (votable->votes[client_id].enabled == enabled &&
|
||||
votable->votes[client_id].value == val) {
|
||||
pr_debug("%s: %s,%d same vote %s of %d\n",
|
||||
votable->name,
|
||||
client_str, client_id,
|
||||
enabled ? "on" : "off",
|
||||
val);
|
||||
goto out;
|
||||
}
|
||||
|
||||
votable->votes[client_id].enabled = enabled;
|
||||
votable->votes[client_id].value = val;
|
||||
|
||||
pr_debug("%s: %d voting for %d - %s\n",
|
||||
votable->name,
|
||||
client_id, val, state ? "on" : "off");
|
||||
pr_debug("%s: %s,%d voting %s of %d\n",
|
||||
votable->name,
|
||||
client_str, client_id, enabled ? "on" : "off", val);
|
||||
switch (votable->type) {
|
||||
case VOTE_MIN:
|
||||
effective_id = vote_min(votable);
|
||||
vote_min(votable, client_id, &effective_result, &effective_id);
|
||||
break;
|
||||
case VOTE_MAX:
|
||||
effective_id = vote_max(votable);
|
||||
vote_max(votable, client_id, &effective_result, &effective_id);
|
||||
break;
|
||||
case VOTE_SET_ANY:
|
||||
votable->votes[client_id].value = state;
|
||||
effective_result = vote_set_any(votable);
|
||||
if (effective_result != votable->effective_result) {
|
||||
votable->effective_client_id = client_id;
|
||||
votable->effective_result = effective_result;
|
||||
if (votable->callback)
|
||||
rc = votable->callback(votable->dev,
|
||||
effective_result, client_id,
|
||||
state, client_id);
|
||||
}
|
||||
goto out;
|
||||
vote_set_any(votable, client_id,
|
||||
&effective_result, &effective_id);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -197,16 +244,16 @@ int vote(struct votable *votable, int client_id, bool state, int val)
|
|||
goto out;
|
||||
}
|
||||
|
||||
effective_result = votable->votes[effective_id].value;
|
||||
|
||||
if (effective_result != votable->effective_result) {
|
||||
votable->effective_client_id = effective_id;
|
||||
votable->effective_result = effective_result;
|
||||
pr_debug("%s: effective vote is now %d voted by %d\n",
|
||||
votable->name, effective_result, effective_id);
|
||||
pr_debug("%s: effective vote is now %d voted by %s,%d\n",
|
||||
votable->name, effective_result,
|
||||
get_client_str(votable, effective_id),
|
||||
effective_id);
|
||||
if (votable->callback)
|
||||
rc = votable->callback(votable->dev, effective_result,
|
||||
effective_id, val, client_id);
|
||||
get_client_str(votable, effective_id));
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -214,37 +261,134 @@ out:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int rerun_election(struct votable *votable)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
lock_votable(votable);
|
||||
if (votable->callback)
|
||||
rc = votable->callback(votable->dev,
|
||||
votable->effective_result,
|
||||
get_client_str(votable, votable->effective_client_id));
|
||||
unlock_votable(votable);
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct votable *find_votable(const char *name)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct votable *v;
|
||||
bool found = false;
|
||||
|
||||
spin_lock_irqsave(&votable_list_slock, flags);
|
||||
if (list_empty(&votable_list))
|
||||
goto out;
|
||||
|
||||
list_for_each_entry(v, &votable_list, list) {
|
||||
if (strcmp(v->name, name) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
spin_unlock_irqrestore(&votable_list_slock, flags);
|
||||
|
||||
if (found)
|
||||
return v;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int show_votable_clients(struct seq_file *m, void *data)
|
||||
{
|
||||
struct votable *votable = m->private;
|
||||
int i;
|
||||
char *type_str = "Unkonwn";
|
||||
|
||||
lock_votable(votable);
|
||||
|
||||
seq_puts(m, "Clients:\n");
|
||||
for (i = 0; i < votable->num_clients; i++) {
|
||||
if (votable->client_strs[i]) {
|
||||
seq_printf(m, "%-15s:\t\ten=%d\t\tv=%d\n",
|
||||
votable->client_strs[i],
|
||||
votable->votes[i].enabled,
|
||||
votable->votes[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
switch (votable->type) {
|
||||
case VOTE_MIN:
|
||||
type_str = "Min";
|
||||
break;
|
||||
case VOTE_MAX:
|
||||
type_str = "Max";
|
||||
break;
|
||||
case VOTE_SET_ANY:
|
||||
type_str = "Set_any";
|
||||
break;
|
||||
}
|
||||
|
||||
seq_printf(m, "Type: %s\n", type_str);
|
||||
seq_puts(m, "Effective:\n");
|
||||
seq_printf(m, "%-15s:\t\tv=%d\n",
|
||||
get_effective_client_locked(votable),
|
||||
get_effective_result_locked(votable));
|
||||
unlock_votable(votable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int votable_debugfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct votable *votable = inode->i_private;
|
||||
|
||||
return single_open(file, show_votable_clients, votable);
|
||||
}
|
||||
|
||||
static const struct file_operations votable_debugfs_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = votable_debugfs_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
struct votable *create_votable(struct device *dev, const char *name,
|
||||
int votable_type,
|
||||
int num_clients,
|
||||
int default_result,
|
||||
int (*callback)(struct device *dev,
|
||||
int effective_result,
|
||||
int effective_client,
|
||||
int last_result,
|
||||
int last_client)
|
||||
int effective_result,
|
||||
const char *effective_client)
|
||||
)
|
||||
{
|
||||
int i;
|
||||
struct votable *votable;
|
||||
unsigned long flags;
|
||||
|
||||
votable = find_votable(name);
|
||||
if (votable)
|
||||
return ERR_PTR(-EEXIST);
|
||||
|
||||
if (debug_root == NULL) {
|
||||
debug_root = debugfs_create_dir("pmic-votable", NULL);
|
||||
if (!debug_root) {
|
||||
dev_err(dev, "Couldn't create debug dir\n");
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
}
|
||||
|
||||
if (votable_type >= NUM_VOTABLE_TYPES) {
|
||||
dev_err(dev, "Invalid votable_type specified for voter\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (num_clients > NUM_MAX_CLIENTS) {
|
||||
dev_err(dev, "Invalid num_clients specified for voter\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
votable = devm_kzalloc(dev, sizeof(struct votable), GFP_KERNEL);
|
||||
if (!votable)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
votable->dev = dev;
|
||||
votable->name = name;
|
||||
votable->num_clients = num_clients;
|
||||
votable->num_clients = NUM_MAX_CLIENTS;
|
||||
votable->callback = callback;
|
||||
votable->type = votable_type;
|
||||
votable->default_result = default_result;
|
||||
|
@ -257,8 +401,30 @@ struct votable *create_votable(struct device *dev, const char *name,
|
|||
votable->effective_result = -EINVAL;
|
||||
votable->effective_client_id = -EINVAL;
|
||||
|
||||
for (i = 0; i < votable->num_clients; i++)
|
||||
votable->votes[i].state = -EINVAL;
|
||||
spin_lock_irqsave(&votable_list_slock, flags);
|
||||
list_add(&votable->list, &votable_list);
|
||||
spin_unlock_irqrestore(&votable_list_slock, flags);
|
||||
|
||||
votable->ent = debugfs_create_file(name, S_IFREG | S_IRUGO,
|
||||
debug_root, votable,
|
||||
&votable_debugfs_ops);
|
||||
if (!votable->ent) {
|
||||
dev_err(dev, "Couldn't create %s debug file\n", name);
|
||||
devm_kfree(dev, votable);
|
||||
return ERR_PTR(-EEXIST);
|
||||
}
|
||||
|
||||
return votable;
|
||||
}
|
||||
|
||||
void destroy_votable(struct device *dev, struct votable *votable)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* only disengage from list, mem will be freed with dev release */
|
||||
spin_lock_irqsave(&votable_list_slock, flags);
|
||||
list_del(&votable->list);
|
||||
spin_unlock_irqrestore(&votable_list_slock, flags);
|
||||
|
||||
debugfs_remove(votable->ent);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015 The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -24,23 +24,23 @@ enum votable_type {
|
|||
NUM_VOTABLE_TYPES,
|
||||
};
|
||||
|
||||
int get_client_vote(struct votable *votable, int client_id);
|
||||
int get_client_vote_locked(struct votable *votable, int client_id);
|
||||
int get_client_vote(struct votable *votable, const char *client_str);
|
||||
int get_client_vote_locked(struct votable *votable, const char *client_str);
|
||||
int get_effective_result(struct votable *votable);
|
||||
int get_effective_result_locked(struct votable *votable);
|
||||
int get_effective_client_id(struct votable *votable);
|
||||
int get_effective_client_id_locked(struct votable *votable);
|
||||
int vote(struct votable *votable, int client_id, bool state, int val);
|
||||
const char *get_effective_client(struct votable *votable);
|
||||
const char *get_effective_client_locked(struct votable *votable);
|
||||
int vote(struct votable *votable, const char *client_str, bool state, int val);
|
||||
int rerun_election(struct votable *votable);
|
||||
struct votable *find_votable(const char *name);
|
||||
struct votable *create_votable(struct device *dev, const char *name,
|
||||
int votable_type, int num_clients,
|
||||
int default_result,
|
||||
int votable_type, int default_result,
|
||||
int (*callback)(struct device *dev,
|
||||
int effective_result,
|
||||
int effective_client,
|
||||
int last_result,
|
||||
int last_client)
|
||||
const char *effective_client)
|
||||
);
|
||||
void destroy_votable(struct device *dev, struct votable *votable);
|
||||
void lock_votable(struct votable *votable);
|
||||
void unlock_votable(struct votable *votable);
|
||||
void unlock_votable(struct votable *votable);
|
||||
|
||||
#endif /* __PMIC_VOTER_H */
|
||||
|
|
|
@ -338,96 +338,79 @@ enum wake_reason {
|
|||
PM_DETECT_HVDCP = BIT(4),
|
||||
};
|
||||
|
||||
enum fcc_voters {
|
||||
ESR_PULSE_FCC_VOTER,
|
||||
BATT_TYPE_FCC_VOTER,
|
||||
RESTRICTED_CHG_FCC_VOTER,
|
||||
NUM_FCC_VOTER,
|
||||
};
|
||||
/* fcc_voters */
|
||||
#define ESR_PULSE_FCC_VOTER "ESR_PULSE_FCC_VOTER"
|
||||
#define BATT_TYPE_FCC_VOTER "BATT_TYPE_FCC_VOTER"
|
||||
#define RESTRICTED_CHG_FCC_VOTER "RESTRICTED_CHG_FCC_VOTER"
|
||||
|
||||
enum icl_voters {
|
||||
PSY_ICL_VOTER,
|
||||
THERMAL_ICL_VOTER,
|
||||
HVDCP_ICL_VOTER,
|
||||
USER_ICL_VOTER,
|
||||
WEAK_CHARGER_ICL_VOTER,
|
||||
SW_AICL_ICL_VOTER,
|
||||
CHG_SUSPEND_WORKAROUND_ICL_VOTER,
|
||||
NUM_ICL_VOTER,
|
||||
};
|
||||
/* ICL VOTERS */
|
||||
#define PSY_ICL_VOTER "PSY_ICL_VOTER"
|
||||
#define THERMAL_ICL_VOTER "THERMAL_ICL_VOTER"
|
||||
#define HVDCP_ICL_VOTER "HVDCP_ICL_VOTER"
|
||||
#define USER_ICL_VOTER "USER_ICL_VOTER"
|
||||
#define WEAK_CHARGER_ICL_VOTER "WEAK_CHARGER_ICL_VOTER"
|
||||
#define SW_AICL_ICL_VOTER "SW_AICL_ICL_VOTER"
|
||||
#define CHG_SUSPEND_WORKAROUND_ICL_VOTER "CHG_SUSPEND_WORKAROUND_ICL_VOTER"
|
||||
|
||||
enum enable_voters {
|
||||
/* userspace has suspended charging altogether */
|
||||
USER_EN_VOTER,
|
||||
/*
|
||||
* this specific path has been suspended through the power supply
|
||||
* framework
|
||||
*/
|
||||
POWER_SUPPLY_EN_VOTER,
|
||||
/*
|
||||
* the usb driver has suspended this path by setting a current limit
|
||||
* of < 2MA
|
||||
*/
|
||||
USB_EN_VOTER,
|
||||
/*
|
||||
* when a wireless charger comes online,
|
||||
* the dc path is suspended for a second
|
||||
*/
|
||||
WIRELESS_EN_VOTER,
|
||||
/*
|
||||
* the thermal daemon can suspend a charge path when the system
|
||||
* temperature levels rise
|
||||
*/
|
||||
THERMAL_EN_VOTER,
|
||||
/*
|
||||
* an external OTG supply is being used, suspend charge path so the
|
||||
* charger does not accidentally try to charge from the external supply.
|
||||
*/
|
||||
OTG_EN_VOTER,
|
||||
/*
|
||||
* the charger is very weak, do not draw any current from it
|
||||
*/
|
||||
WEAK_CHARGER_EN_VOTER,
|
||||
/*
|
||||
* fake battery voter, if battery id-resistance around 7.5 Kohm
|
||||
*/
|
||||
FAKE_BATTERY_EN_VOTER,
|
||||
NUM_EN_VOTERS,
|
||||
};
|
||||
/* USB SUSPEND VOTERS */
|
||||
/* userspace has suspended charging altogether */
|
||||
#define USER_EN_VOTER "USER_EN_VOTER"
|
||||
/*
|
||||
* this specific path has been suspended through the power supply
|
||||
* framework
|
||||
*/
|
||||
#define POWER_SUPPLY_EN_VOTER "POWER_SUPPLY_EN_VOTER"
|
||||
/*
|
||||
* the usb driver has suspended this path by setting a current limit
|
||||
* of < 2MA
|
||||
*/
|
||||
#define USB_EN_VOTER "USB_EN_VOTER"
|
||||
/*
|
||||
* the thermal daemon can suspend a charge path when the system
|
||||
* temperature levels rise
|
||||
*/
|
||||
#define THERMAL_EN_VOTER "THERMAL_EN_VOTER"
|
||||
/*
|
||||
* an external OTG supply is being used, suspend charge path so the
|
||||
* charger does not accidentally try to charge from the external supply.
|
||||
*/
|
||||
#define OTG_EN_VOTER "OTG_EN_VOTER"
|
||||
/*
|
||||
* the charger is very weak, do not draw any current from it
|
||||
*/
|
||||
#define WEAK_CHARGER_EN_VOTER "WEAK_CHARGER_EN_VOTER"
|
||||
/*
|
||||
* fake battery voter, if battery id-resistance around 7.5 Kohm
|
||||
*/
|
||||
#define FAKE_BATTERY_EN_VOTER "FAKE_BATTERY_EN_VOTER"
|
||||
|
||||
enum battchg_enable_voters {
|
||||
/* battchg_enable_voters */
|
||||
/* userspace has disabled battery charging */
|
||||
BATTCHG_USER_EN_VOTER,
|
||||
#define BATTCHG_USER_EN_VOTER "BATTCHG_USER_EN_VOTER"
|
||||
/* battery charging disabled while loading battery profiles */
|
||||
BATTCHG_UNKNOWN_BATTERY_EN_VOTER,
|
||||
NUM_BATTCHG_EN_VOTERS,
|
||||
};
|
||||
#define BATTCHG_UNKNOWN_BATTERY_EN_VOTER "BATTCHG_UNKNOWN_BATTERY_EN_VOTER"
|
||||
|
||||
enum hw_aicl_rerun_enable_indirect_voters {
|
||||
/* enabled via device tree */
|
||||
DEFAULT_CONFIG_HW_AICL_VOTER,
|
||||
/* Varb workaround voter */
|
||||
VARB_WORKAROUND_VOTER,
|
||||
/* SHUTDOWN workaround voter */
|
||||
SHUTDOWN_WORKAROUND_VOTER,
|
||||
NUM_HW_AICL_RERUN_ENABLE_INDIRECT_VOTERS,
|
||||
};
|
||||
/* hw_aicl_rerun_enable_indirect_voters */
|
||||
/* enabled via device tree */
|
||||
#define DEFAULT_CONFIG_HW_AICL_VOTER "DEFAULT_CONFIG_HW_AICL_VOTER"
|
||||
/* Varb workaround voter */
|
||||
#define VARB_WORKAROUND_VOTER "VARB_WORKAROUND_VOTER"
|
||||
/* SHUTDOWN workaround voter */
|
||||
#define SHUTDOWN_WORKAROUND_VOTER "SHUTDOWN_WORKAROUND_VOTER"
|
||||
|
||||
enum hw_aicl_rerun_disable_voters {
|
||||
/* the results from enabling clients */
|
||||
HW_AICL_RERUN_ENABLE_INDIRECT_VOTER,
|
||||
/* Weak charger voter */
|
||||
WEAK_CHARGER_HW_AICL_VOTER,
|
||||
NUM_HW_AICL_DISABLE_VOTERS,
|
||||
};
|
||||
/* hw_aicl_rerun_disable_voters */
|
||||
/* the results from enabling clients */
|
||||
#define HW_AICL_RERUN_ENABLE_INDIRECT_VOTER \
|
||||
"HW_AICL_RERUN_ENABLE_INDIRECT_VOTER"
|
||||
/* Weak charger voter */
|
||||
#define WEAK_CHARGER_HW_AICL_VOTER "WEAK_CHARGER_HW_AICL_VOTER"
|
||||
|
||||
enum aicl_short_deglitch_voters {
|
||||
/* Varb workaround voter */
|
||||
VARB_WORKAROUND_SHORT_DEGLITCH_VOTER,
|
||||
/* QC 2.0 */
|
||||
HVDCP_SHORT_DEGLITCH_VOTER,
|
||||
NUM_HW_SHORT_DEGLITCH_VOTERS,
|
||||
};
|
||||
/* aicl_short_deglitch_voters */
|
||||
/* Varb workaround voter */
|
||||
#define VARB_WORKAROUND_SHORT_DEGLITCH_VOTER \
|
||||
"VARB_WRKARND_SHORT_DEGLITCH_VOTER"
|
||||
/* QC 2.0 */
|
||||
#define HVDCP_SHORT_DEGLITCH_VOTER "HVDCP_SHORT_DEGLITCH_VOTER"
|
||||
|
||||
static const unsigned int smbchg_extcon_cable[] = {
|
||||
EXTCON_USB,
|
||||
|
@ -2136,7 +2119,8 @@ static bool smbchg_is_parallel_usb_ok(struct smbchg_chip *chip,
|
|||
ktime_t kt_since_last_disable;
|
||||
u8 reg;
|
||||
int fcc_ma = get_effective_result_locked(chip->fcc_votable);
|
||||
int fcc_voter_id = get_effective_client_id_locked(chip->fcc_votable);
|
||||
const char *fcc_voter
|
||||
= get_effective_client_locked(chip->fcc_votable);
|
||||
int usb_icl_ma = get_effective_result_locked(chip->usb_icl_votable);
|
||||
|
||||
if (!parallel_psy || !smbchg_parallel_en
|
||||
|
@ -2216,11 +2200,13 @@ static bool smbchg_is_parallel_usb_ok(struct smbchg_chip *chip,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!fcc_voter)
|
||||
return false;
|
||||
/*
|
||||
* Suspend the parallel charger if the charging current is < 1800 mA
|
||||
* and is not because of an ESR pulse.
|
||||
*/
|
||||
if (fcc_voter_id != ESR_PULSE_FCC_VOTER
|
||||
if ((strcmp(fcc_voter, ESR_PULSE_FCC_VOTER) == 0)
|
||||
&& fcc_ma < PARALLEL_CHG_THRESHOLD_CURRENT) {
|
||||
pr_smb(PR_STATUS, "FCC %d lower than %d\n",
|
||||
fcc_ma,
|
||||
|
@ -2325,8 +2311,7 @@ static void smbchg_parallel_usb_check_ok(struct smbchg_chip *chip)
|
|||
}
|
||||
|
||||
static int charging_suspend_vote_cb(struct device *dev, int suspend,
|
||||
int client, int last_suspend,
|
||||
int last_client)
|
||||
const char *client)
|
||||
{
|
||||
int rc;
|
||||
struct smbchg_chip *chip = dev_get_drvdata(dev);
|
||||
|
@ -2342,8 +2327,7 @@ static int charging_suspend_vote_cb(struct device *dev, int suspend,
|
|||
}
|
||||
|
||||
static int usb_suspend_vote_cb(struct device *dev, int suspend,
|
||||
int client, int last_suspend,
|
||||
int last_client)
|
||||
const char *client)
|
||||
{
|
||||
int rc;
|
||||
struct smbchg_chip *chip = dev_get_drvdata(dev);
|
||||
|
@ -2352,17 +2336,17 @@ static int usb_suspend_vote_cb(struct device *dev, int suspend,
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (client == THERMAL_EN_VOTER || client == POWER_SUPPLY_EN_VOTER ||
|
||||
client == USER_EN_VOTER ||
|
||||
client == FAKE_BATTERY_EN_VOTER)
|
||||
if ((strcmp(client, THERMAL_EN_VOTER) == 0)
|
||||
|| (strcmp(client, POWER_SUPPLY_EN_VOTER) == 0)
|
||||
|| (strcmp(client, USER_EN_VOTER) == 0)
|
||||
|| (strcmp(client, FAKE_BATTERY_EN_VOTER) == 0))
|
||||
smbchg_parallel_usb_check_ok(chip);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dc_suspend_vote_cb(struct device *dev, int suspend,
|
||||
int client, int last_suspend,
|
||||
int last_client)
|
||||
const char *client)
|
||||
{
|
||||
int rc;
|
||||
struct smbchg_chip *chip = dev_get_drvdata(dev);
|
||||
|
@ -2379,9 +2363,7 @@ static int dc_suspend_vote_cb(struct device *dev, int suspend,
|
|||
|
||||
static int set_fastchg_current_vote_cb(struct device *dev,
|
||||
int fcc_ma,
|
||||
int client,
|
||||
int last_fcc_ma,
|
||||
int last_client)
|
||||
const char *client)
|
||||
{
|
||||
struct smbchg_chip *chip = dev_get_drvdata(dev);
|
||||
int rc;
|
||||
|
@ -2667,9 +2649,7 @@ DEFINE_SIMPLE_ATTRIBUTE(force_dcin_icl_ops, NULL,
|
|||
*/
|
||||
static int set_dc_current_limit_vote_cb(struct device *dev,
|
||||
int icl_ma,
|
||||
int client,
|
||||
int last_icl_ma,
|
||||
int last_client)
|
||||
const char *client)
|
||||
{
|
||||
struct smbchg_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
|
@ -2682,17 +2662,19 @@ static int set_dc_current_limit_vote_cb(struct device *dev,
|
|||
*/
|
||||
static int set_usb_current_limit_vote_cb(struct device *dev,
|
||||
int icl_ma,
|
||||
int client,
|
||||
int last_icl_ma,
|
||||
int last_client)
|
||||
const char *client)
|
||||
{
|
||||
struct smbchg_chip *chip = dev_get_drvdata(dev);
|
||||
int rc, aicl_ma, effective_id;
|
||||
int rc, aicl_ma;
|
||||
const char *effective_id;
|
||||
|
||||
effective_id = get_effective_client_id_locked(chip->usb_icl_votable);
|
||||
effective_id = get_effective_client_locked(chip->usb_icl_votable);
|
||||
|
||||
if (!effective_id)
|
||||
return 0;
|
||||
|
||||
/* disable parallel charging if HVDCP is voting for 300mA */
|
||||
if (effective_id == HVDCP_ICL_VOTER)
|
||||
if (strcmp(effective_id, HVDCP_ICL_VOTER) == 0)
|
||||
smbchg_parallel_usb_disable(chip);
|
||||
|
||||
if (chip->parallel.current_max_ma == 0) {
|
||||
|
@ -2704,7 +2686,7 @@ static int set_usb_current_limit_vote_cb(struct device *dev,
|
|||
}
|
||||
|
||||
/* skip the aicl rerun if hvdcp icl voter is active */
|
||||
if (effective_id == HVDCP_ICL_VOTER)
|
||||
if (strcmp(effective_id, HVDCP_ICL_VOTER) == 0)
|
||||
return 0;
|
||||
|
||||
aicl_ma = smbchg_get_aicl_level_ma(chip);
|
||||
|
@ -3268,8 +3250,7 @@ static void smbchg_soc_changed(struct smbchg_chip *chip)
|
|||
|
||||
static int smbchg_hw_aicl_rerun_enable_indirect_cb(struct device *dev,
|
||||
int enable,
|
||||
int client, int last_enable,
|
||||
int last_client)
|
||||
const char *client)
|
||||
{
|
||||
int rc = 0;
|
||||
struct smbchg_chip *chip = dev_get_drvdata(dev);
|
||||
|
@ -3289,8 +3270,7 @@ static int smbchg_hw_aicl_rerun_enable_indirect_cb(struct device *dev,
|
|||
}
|
||||
|
||||
static int smbchg_hw_aicl_rerun_disable_cb(struct device *dev, int disable,
|
||||
int client, int last_disable,
|
||||
int last_client)
|
||||
const char *client)
|
||||
{
|
||||
int rc = 0;
|
||||
struct smbchg_chip *chip = dev_get_drvdata(dev);
|
||||
|
@ -3305,8 +3285,7 @@ static int smbchg_hw_aicl_rerun_disable_cb(struct device *dev, int disable,
|
|||
}
|
||||
|
||||
static int smbchg_aicl_deglitch_config_cb(struct device *dev, int shorter,
|
||||
int client, int last_result,
|
||||
int last_client)
|
||||
const char *client)
|
||||
{
|
||||
int rc = 0;
|
||||
struct smbchg_chip *chip = dev_get_drvdata(dev);
|
||||
|
@ -7943,64 +7922,64 @@ static int smbchg_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
chip->fcc_votable = create_votable(&pdev->dev,
|
||||
"SMBCHG: fcc",
|
||||
VOTE_MIN, NUM_FCC_VOTER, 2000,
|
||||
"BATT_FCC",
|
||||
VOTE_MIN, 2000,
|
||||
set_fastchg_current_vote_cb);
|
||||
if (IS_ERR(chip->fcc_votable))
|
||||
return PTR_ERR(chip->fcc_votable);
|
||||
|
||||
chip->usb_icl_votable = create_votable(&pdev->dev,
|
||||
"SMBCHG: usb_icl",
|
||||
VOTE_MIN, NUM_ICL_VOTER, 3000,
|
||||
"USB_ICL",
|
||||
VOTE_MIN, 3000,
|
||||
set_usb_current_limit_vote_cb);
|
||||
if (IS_ERR(chip->usb_icl_votable))
|
||||
return PTR_ERR(chip->usb_icl_votable);
|
||||
|
||||
chip->dc_icl_votable = create_votable(&pdev->dev,
|
||||
"SMBCHG: dcl_icl",
|
||||
VOTE_MIN, NUM_ICL_VOTER, 3000,
|
||||
"DCIN_ICL",
|
||||
VOTE_MIN, 3000,
|
||||
set_dc_current_limit_vote_cb);
|
||||
if (IS_ERR(chip->dc_icl_votable))
|
||||
return PTR_ERR(chip->dc_icl_votable);
|
||||
|
||||
chip->usb_suspend_votable = create_votable(&pdev->dev,
|
||||
"SMBCHG: usb_suspend",
|
||||
VOTE_SET_ANY, NUM_EN_VOTERS, 0,
|
||||
"USB_SUSPEND",
|
||||
VOTE_SET_ANY, 0,
|
||||
usb_suspend_vote_cb);
|
||||
if (IS_ERR(chip->usb_suspend_votable))
|
||||
return PTR_ERR(chip->usb_suspend_votable);
|
||||
|
||||
chip->dc_suspend_votable = create_votable(&pdev->dev,
|
||||
"SMBCHG: dc_suspend",
|
||||
VOTE_SET_ANY, NUM_EN_VOTERS, 0,
|
||||
"DC_SUSPEND",
|
||||
VOTE_SET_ANY, 0,
|
||||
dc_suspend_vote_cb);
|
||||
if (IS_ERR(chip->dc_suspend_votable))
|
||||
return PTR_ERR(chip->dc_suspend_votable);
|
||||
|
||||
chip->battchg_suspend_votable = create_votable(&pdev->dev,
|
||||
"SMBCHG: battchg_suspend",
|
||||
VOTE_SET_ANY, NUM_BATTCHG_EN_VOTERS, 0,
|
||||
"BATTCHG_SUSPEND",
|
||||
VOTE_SET_ANY, 0,
|
||||
charging_suspend_vote_cb);
|
||||
if (IS_ERR(chip->battchg_suspend_votable))
|
||||
return PTR_ERR(chip->battchg_suspend_votable);
|
||||
|
||||
chip->hw_aicl_rerun_disable_votable = create_votable(&pdev->dev,
|
||||
"SMBCHG: hwaicl_disable",
|
||||
VOTE_SET_ANY, NUM_HW_AICL_DISABLE_VOTERS, 0,
|
||||
"HWAICL_DISABLE",
|
||||
VOTE_SET_ANY, 0,
|
||||
smbchg_hw_aicl_rerun_disable_cb);
|
||||
if (IS_ERR(chip->hw_aicl_rerun_disable_votable))
|
||||
return PTR_ERR(chip->hw_aicl_rerun_disable_votable);
|
||||
|
||||
chip->hw_aicl_rerun_enable_indirect_votable = create_votable(&pdev->dev,
|
||||
"SMBCHG: hwaicl_enable_indirect",
|
||||
VOTE_SET_ANY, NUM_HW_AICL_RERUN_ENABLE_INDIRECT_VOTERS,
|
||||
0, smbchg_hw_aicl_rerun_enable_indirect_cb);
|
||||
"HWAICL_ENABLE_INDIRECT",
|
||||
VOTE_SET_ANY, 0,
|
||||
smbchg_hw_aicl_rerun_enable_indirect_cb);
|
||||
if (IS_ERR(chip->hw_aicl_rerun_enable_indirect_votable))
|
||||
return PTR_ERR(chip->hw_aicl_rerun_enable_indirect_votable);
|
||||
|
||||
chip->aicl_deglitch_short_votable = create_votable(&pdev->dev,
|
||||
"SMBCHG: hwaicl_short_deglitch",
|
||||
VOTE_SET_ANY, NUM_HW_SHORT_DEGLITCH_VOTERS, 0,
|
||||
"HWAICL_SHORT_DEGLITCH",
|
||||
VOTE_SET_ANY, 0,
|
||||
smbchg_aicl_deglitch_config_cb);
|
||||
if (IS_ERR(chip->aicl_deglitch_short_votable))
|
||||
return PTR_ERR(chip->aicl_deglitch_short_votable);
|
||||
|
@ -8217,7 +8196,7 @@ static int smbchg_remove(struct platform_device *pdev)
|
|||
static void smbchg_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct smbchg_chip *chip = dev_get_drvdata(&pdev->dev);
|
||||
int i, rc;
|
||||
int rc;
|
||||
|
||||
if (!(chip->wa_flags & SMBCHG_RESTART_WA))
|
||||
return;
|
||||
|
@ -8256,8 +8235,10 @@ static void smbchg_shutdown(struct platform_device *pdev)
|
|||
disable_irq(chip->wdog_timeout_irq);
|
||||
|
||||
/* remove all votes for short deglitch */
|
||||
for (i = 0; i < NUM_HW_SHORT_DEGLITCH_VOTERS; i++)
|
||||
vote(chip->aicl_deglitch_short_votable, i, false, 0);
|
||||
vote(chip->aicl_deglitch_short_votable,
|
||||
VARB_WORKAROUND_SHORT_DEGLITCH_VOTER, false, 0);
|
||||
vote(chip->aicl_deglitch_short_votable,
|
||||
HVDCP_SHORT_DEGLITCH_VOTER, false, 0);
|
||||
|
||||
/* vote to ensure AICL rerun is enabled */
|
||||
rc = vote(chip->hw_aicl_rerun_enable_indirect_votable,
|
||||
|
|
|
@ -299,24 +299,24 @@ static int smblib_detach_usb(struct smb_charger *chg)
|
|||
* VOTABLE CALLBACKS *
|
||||
*********************/
|
||||
|
||||
int smblib_usb_suspend_vote_callback(struct device *dev,
|
||||
int suspend, int client, int last_suspend, int last_client)
|
||||
static int smblib_usb_suspend_vote_callback(struct device *dev,
|
||||
int suspend, const char *client)
|
||||
{
|
||||
struct smb_charger *chg = dev_get_drvdata(dev);
|
||||
|
||||
return smblib_set_usb_suspend(chg, suspend);
|
||||
}
|
||||
|
||||
int smblib_dc_suspend_vote_callback(struct device *dev,
|
||||
int suspend, int client, int last_suspend, int last_client)
|
||||
static int smblib_dc_suspend_vote_callback(struct device *dev,
|
||||
int suspend, const char *client)
|
||||
{
|
||||
struct smb_charger *chg = dev_get_drvdata(dev);
|
||||
|
||||
return smblib_set_dc_suspend(chg, suspend);
|
||||
}
|
||||
|
||||
int smblib_fcc_vote_callback(struct device *dev,
|
||||
int fcc_ua, int client, int last_fcc_ua, int last_client)
|
||||
static int smblib_fcc_vote_callback(struct device *dev,
|
||||
int fcc_ua, const char *client)
|
||||
{
|
||||
struct smb_charger *chg = dev_get_drvdata(dev);
|
||||
int rc = 0;
|
||||
|
@ -325,8 +325,8 @@ int smblib_fcc_vote_callback(struct device *dev,
|
|||
return rc;
|
||||
}
|
||||
|
||||
int smblib_fv_vote_callback(struct device *dev,
|
||||
int fv_uv, int client, int last_fv_uv, int last_client)
|
||||
static int smblib_fv_vote_callback(struct device *dev,
|
||||
int fv_uv, const char *client)
|
||||
{
|
||||
struct smb_charger *chg = dev_get_drvdata(dev);
|
||||
int rc = 0;
|
||||
|
@ -337,8 +337,8 @@ int smblib_fv_vote_callback(struct device *dev,
|
|||
|
||||
#define USBIN_25MA 25000
|
||||
#define USBIN_100MA 100000
|
||||
int smblib_usb_icl_vote_callback(struct device *dev,
|
||||
int icl_ua, int client, int last_icl_ua, int last_client)
|
||||
static int smblib_usb_icl_vote_callback(struct device *dev,
|
||||
int icl_ua, const char *client)
|
||||
{
|
||||
struct smb_charger *chg = dev_get_drvdata(dev);
|
||||
int rc = 0;
|
||||
|
@ -372,8 +372,8 @@ suspend:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int smblib_dc_icl_vote_callback(struct device *dev,
|
||||
int icl_ua, int client, int last_icl_ua, int last_client)
|
||||
static int smblib_dc_icl_vote_callback(struct device *dev,
|
||||
int icl_ua, const char *client)
|
||||
{
|
||||
struct smb_charger *chg = dev_get_drvdata(dev);
|
||||
int rc = 0;
|
||||
|
@ -1295,7 +1295,7 @@ int smblib_init(struct smb_charger *chg)
|
|||
|
||||
chg->usb_suspend_votable = create_votable(chg->dev,
|
||||
"INPUT_SUSPEND", VOTE_SET_ANY,
|
||||
NUM_VOTERS, 0,
|
||||
0,
|
||||
smblib_usb_suspend_vote_callback);
|
||||
if (IS_ERR(chg->usb_suspend_votable)) {
|
||||
rc = PTR_ERR(chg->usb_suspend_votable);
|
||||
|
@ -1304,7 +1304,7 @@ int smblib_init(struct smb_charger *chg)
|
|||
|
||||
chg->dc_suspend_votable = create_votable(chg->dev,
|
||||
"DC_SUSPEND", VOTE_SET_ANY,
|
||||
NUM_VOTERS, 0,
|
||||
0,
|
||||
smblib_dc_suspend_vote_callback);
|
||||
if (IS_ERR(chg->dc_suspend_votable)) {
|
||||
rc = PTR_ERR(chg->dc_suspend_votable);
|
||||
|
@ -1313,7 +1313,7 @@ int smblib_init(struct smb_charger *chg)
|
|||
|
||||
chg->fcc_votable = create_votable(chg->dev,
|
||||
"FCC", VOTE_MAX,
|
||||
NUM_VOTERS, SMB_DEFAULT_FCC_UA,
|
||||
SMB_DEFAULT_FCC_UA,
|
||||
smblib_fcc_vote_callback);
|
||||
if (IS_ERR(chg->fcc_votable)) {
|
||||
rc = PTR_ERR(chg->fcc_votable);
|
||||
|
@ -1322,7 +1322,7 @@ int smblib_init(struct smb_charger *chg)
|
|||
|
||||
chg->fv_votable = create_votable(chg->dev,
|
||||
"FV", VOTE_MAX,
|
||||
NUM_VOTERS, SMB_DEFAULT_FV_UV,
|
||||
SMB_DEFAULT_FV_UV,
|
||||
smblib_fv_vote_callback);
|
||||
if (IS_ERR(chg->fv_votable)) {
|
||||
rc = PTR_ERR(chg->fv_votable);
|
||||
|
@ -1331,7 +1331,7 @@ int smblib_init(struct smb_charger *chg)
|
|||
|
||||
chg->usb_icl_votable = create_votable(chg->dev,
|
||||
"USB_ICL", VOTE_MIN,
|
||||
NUM_VOTERS, SMB_DEFAULT_ICL_UA,
|
||||
SMB_DEFAULT_ICL_UA,
|
||||
smblib_usb_icl_vote_callback);
|
||||
if (IS_ERR(chg->usb_icl_votable)) {
|
||||
rc = PTR_ERR(chg->usb_icl_votable);
|
||||
|
@ -1340,7 +1340,7 @@ int smblib_init(struct smb_charger *chg)
|
|||
|
||||
chg->dc_icl_votable = create_votable(chg->dev,
|
||||
"DC_ICL", VOTE_MIN,
|
||||
NUM_VOTERS, SMB_DEFAULT_ICL_UA,
|
||||
SMB_DEFAULT_ICL_UA,
|
||||
smblib_dc_icl_vote_callback);
|
||||
if (IS_ERR(chg->dc_icl_votable)) {
|
||||
rc = PTR_ERR(chg->dc_icl_votable);
|
||||
|
@ -1349,7 +1349,7 @@ int smblib_init(struct smb_charger *chg)
|
|||
|
||||
chg->pd_allowed_votable = create_votable(chg->dev,
|
||||
"PD_ALLOWED", VOTE_SET_ANY,
|
||||
NUM_VOTERS, 0, NULL);
|
||||
0, NULL);
|
||||
if (IS_ERR(chg->pd_allowed_votable)) {
|
||||
rc = PTR_ERR(chg->pd_allowed_votable);
|
||||
return rc;
|
||||
|
|
|
@ -23,12 +23,9 @@ enum print_reason {
|
|||
PR_MISC = BIT(2),
|
||||
};
|
||||
|
||||
enum smb_voters {
|
||||
DEFAULT_VOTER = 0,
|
||||
USER_VOTER,
|
||||
PD_VOTER,
|
||||
NUM_VOTERS,
|
||||
};
|
||||
#define DEFAULT_VOTER "DEFAULT_VOTER"
|
||||
#define USER_VOTER "USER_VOTER"
|
||||
#define PD_VOTER "PD_VOTER"
|
||||
|
||||
struct smb_regulator {
|
||||
struct regulator_dev *rdev;
|
||||
|
@ -101,17 +98,6 @@ int smblib_write(struct smb_charger *chg, u16 addr, u8 val);
|
|||
|
||||
int smblib_enable_charging(struct smb_charger *chg, bool enable);
|
||||
|
||||
int smblib_usb_suspend_vote_callback(struct device *dev,
|
||||
int disable, int client, int last_disable, int last_client);
|
||||
int smblib_dc_suspend_vote_callback(struct device *dev,
|
||||
int disable, int client, int last_disable, int last_client);
|
||||
int smblib_fcc_vote_callback(struct device *dev,
|
||||
int fcc_ua, int client, int last_fcc_ua, int last_client);
|
||||
int smblib_usb_icl_vote_callback(struct device *dev,
|
||||
int icl_ua, int client, int last_icl_ua, int last_client);
|
||||
int smblib_dc_icl_vote_callback(struct device *dev,
|
||||
int icl_ua, int client, int last_icl_ua, int last_client);
|
||||
|
||||
int smblib_vbus_regulator_enable(struct regulator_dev *rdev);
|
||||
int smblib_vbus_regulator_disable(struct regulator_dev *rdev);
|
||||
int smblib_vbus_regulator_is_enabled(struct regulator_dev *rdev);
|
||||
|
|
Loading…
Add table
Reference in a new issue