blob: c79f945fc2d481856b8bca1089b5463f536d32ca [file] [log] [blame] [edit]
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 2019 Google, LLC
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef MAX77779_FG_MODEL_H_
#define MAX77779_FG_MODEL_H_
#include "max1720x_battery.h"
#include "max77779.h"
/* change to 1 or 0 to load FG model with default parameters on startup */
#define MAX77779_LOAD_MODEL_DISABLED -1
#define MAX77779_LOAD_MODEL_IDLE 0
#define MAX77779_LOAD_MODEL_REQUEST 5
#define MAX77779_FG_MODEL_START 0x80
#define MAX77779_FG_MODEL_SIZE 48
/* model version */
#define MAX77779_INVALID_VERSION -1
/** ------------------------------------------------------------------------ */
/*
* Custom parameters are updated while the device is running.
* NOTE: a subset (model_state_save) is saved to permanent storage every "n"
* cycles and restored when the model is reloaded (usually on POR).
* TODO: handle switching between RC1 and RC2 model types.
*/
struct max77779_custom_parameters {
u16 iavg_empty; /* WV */
u16 relaxcfg;
u16 learncfg;
u16 config;
u16 config2;
u16 fullsocthr;
u16 fullcaprep; /* WV */
u16 designcap;
u16 dpacc; /* WV */
u16 dqacc; /* WV */
u16 fullcapnom; /* WV */
u16 v_empty;
u16 qresidual00; /* WV */
u16 qresidual10; /* WV */
u16 qresidual20; /* WV */
u16 qresidual30; /* WV */
u16 rcomp0; /* WV */
u16 tempco; /* WV */
u16 ichgterm;
u16 tgain;
u16 toff;
u16 tcurve; /* write to 0x00B9 */
u16 misccfg; /* 0x9d0 for internal current sense, 0x8d0 external */
u16 atrate;
u16 convgcfg;
u16 filtercfg; /* write to 0x0029 */
} __attribute__((packed));
/* this is what is saved and restored to/from GMSR */
struct model_state_save {
u16 rcomp0;
u16 tempco;
u16 fullcaprep;
u16 cycles;
u16 fullcapnom;
u8 padding[6]; /* keep the same size as 59 for consistency GBMS_GMSR_LEN */
u8 crc;
} __attribute__((packed));
struct max77779_model_data {
struct device *dev;
struct max17x0x_regmap *regmap;
struct regmap *debug_regmap;
/* initial parameters are in device tree they are also learned */
struct max77779_custom_parameters parameters;
u16 cycles;
u16 cv_mixcap;
int custom_model_size;
u16 *custom_model;
u32 model_version;
bool force_reset_model_data;
/* to/from GMSR */
struct model_state_save model_save;
};
/** ------------------------------------------------------------------------ */
int max77779_model_read_version(const struct max77779_model_data *model_data);
int max77779_model_get_cap_lsb(const struct max77779_model_data *model_data);
int max77779_reset_state_data(struct max77779_model_data *model_data);
int max77779_needs_reset_model_data(const struct max77779_model_data *model_data);
/*
* max77779 might use the low 8 bits of devname to keep the model version number
* - 0 not M5, !=0 M5
*/
static inline int max77779_check_devname(u16 devname)
{
const u16 radix = devname >> 8;
return radix == 0x62 || radix == 0x63;
}
static inline int max77779_fg_model_version(const struct max77779_model_data *model_data)
{
return model_data ? model_data->model_version : MAX77779_INVALID_VERSION;
}
/*
* 0 reload, != 0 no reload
* always reload when the model version is not specified
*/
static inline int max77779_fg_model_check_version(const struct max77779_model_data *model_data)
{
if (!model_data)
return 1;
if (model_data->model_version == MAX77779_INVALID_VERSION)
return 0;
return max77779_model_read_version(model_data) == model_data->model_version;
}
#define MAX77779_FG_REGMAP_WRITE(regmap, what, value) \
max77779_fg_register_write(regmap, what, value, false)
#define MAX77779_FG_REGMAP_WRITE_VERIFY(regmap, what, value) \
max77779_fg_register_write(regmap, what, value, true)
/** ------------------------------------------------------------------------ */
int max77779_max17x0x_regmap_init(struct max17x0x_regmap *regmap, struct i2c_client *clnt,
const struct regmap_config *regmap_config, bool tag);
int max77779_fg_usr_lock(const struct max17x0x_regmap *map, bool enabled);
int max77779_fg_register_write(const struct max17x0x_regmap *regmap, unsigned int reg,
u16 value, bool verify);
void *max77779_init_data(struct device *dev, struct device_node *batt_node,
struct max17x0x_regmap *regmap);
void max77779_free_data(void *data);
int max77779_load_state_data(struct max77779_model_data *model_data);
int max77779_save_state_data(struct max77779_model_data *model_data);
/* read state from the gauge */
int max77779_model_read_state(struct max77779_model_data *model_data);
int max77779_model_check_state(struct max77779_model_data *model_data);
/* load model to gauge */
int max77779_load_gauge_model(struct max77779_model_data *model_data);
ssize_t max77779_model_state_cstr(char *buf, int max, struct max77779_model_data *model_data);
int max77779_fg_model_cstr(char *buf, int max, const struct max77779_model_data *model_data);
/* read saved value */
ssize_t max77779_gmsr_state_cstr(char *buf, int max);
/** ------------------------------------------------------------------------ */
void *max77779_get_model_data(struct i2c_client *client);
#endif