123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- /*
- * sb_batt_dump.c
- * Samsung Mobile Battery Dump Driver
- *
- * Copyright (C) 2021 Samsung Electronics
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
- #include <linux/slab.h>
- #include <linux/battery/sb_sysfs.h>
- #include <linux/battery/sb_notify.h>
- #include "sec_battery.h"
- #include "sec_charging_common.h"
- #include "sb_batt_dump.h"
- #define bd_log(str, ...) pr_info("[BATT-DUMP]:%s: "str, __func__, ##__VA_ARGS__)
- #define BD_MODULE_NAME "batt-dump"
- struct sb_bd {
- struct notifier_block nb;
- };
- static ssize_t show_attrs(struct device *dev,
- struct device_attribute *attr, char *buf);
- static ssize_t store_attrs(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
- #define BD_SYSFS_ATTR(_name) \
- { \
- .attr = {.name = #_name, .mode = 0664}, \
- .show = show_attrs, \
- .store = store_attrs, \
- }
- static struct device_attribute bd_attr[] = {
- BD_SYSFS_ATTR(battery_dump),
- };
- enum sb_bd_attrs {
- BATTERY_DUMP = 0,
- };
- static ssize_t show_attrs(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct power_supply *psy = dev_get_drvdata(dev);
- struct sec_battery_info *battery = power_supply_get_drvdata(psy);
- const ptrdiff_t offset = attr - bd_attr;
- ssize_t count = 0;
- union power_supply_propval value = {0, };
- switch (offset) {
- case BATTERY_DUMP:
- {
- char temp_buf[1024] = {0,};
- int size = 1024;
- union power_supply_propval dc_state = {0, };
- dc_state.strval = "NO_CHARGING";
- #if IS_ENABLED(CONFIG_DIRECT_CHARGING)
- psy_do_property(battery->pdata->charger_name, get,
- POWER_SUPPLY_EXT_PROP_DIRECT_CHARGER_CHG_STATUS, dc_state);
- #endif
- snprintf(temp_buf + strlen(temp_buf), size,
- "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%s,%s,%s,%s,%s,%d,%s,%d,%d,%lu,0x%x,0x%x,0x%x,%d,%d,",
- battery->voltage_now, battery->current_now,
- battery->current_max, battery->charging_current,
- battery->capacity,
- battery->temperature, battery->usb_temp,
- battery->chg_temp, battery->wpc_temp,
- battery->blkt_temp, battery->lrp,
- battery->dchg_temp, battery->sub_bat_temp,
- sb_get_bst_str(battery->status),
- dc_state.strval,
- sb_get_cm_str(battery->charging_mode),
- sb_get_hl_str(battery->health),
- sb_get_ct_str(battery->cable_type),
- battery->muic_cable_type,
- sb_get_tz_str(battery->thermal_zone),
- is_slate_mode(battery),
- battery->store_mode,
- (battery->expired_time / 1000),
- battery->current_event,
- battery->misc_event,
- battery->tx_event,
- #if defined(CONFIG_WIRELESS_RX_PHM_CTRL)
- battery->wc_rx_pdetb_mode,
- #else
- battery->wc_rx_phm_mode,
- #endif
- battery->srccap_transit
- );
- size = sizeof(temp_buf) - strlen(temp_buf);
- {
- unsigned short vid = 0, pid = 0;
- unsigned int xid = 0;
- sec_pd_get_vid_pid(&vid, &pid, &xid);
- snprintf(temp_buf+strlen(temp_buf), size,
- "%04x,%04x,%08x,", vid, pid, xid);
- size = sizeof(temp_buf) - strlen(temp_buf);
- }
- snprintf(temp_buf+strlen(temp_buf), size,
- "%d,%d,%d,%d,",
- battery->voltage_avg_main, battery->voltage_avg_sub,
- battery->current_avg_main, battery->current_avg_sub);
- size = sizeof(temp_buf) - strlen(temp_buf);
- snprintf(temp_buf+strlen(temp_buf), size, "%d,", battery->batt_cycle);
- size = sizeof(temp_buf) - strlen(temp_buf);
- psy_do_property(battery->pdata->fuelgauge_name, get,
- POWER_SUPPLY_EXT_PROP_BATT_DUMP, value);
- snprintf(temp_buf+strlen(temp_buf), size, "%s,", value.strval);
- size = sizeof(temp_buf) - strlen(temp_buf);
- /* Wireless charging related log added at the end of the string */
- value.intval = SB_WRL_NONE;
- #if IS_ENABLED(CONFIG_WIRELESS_CHARGING)
- if (battery->wc_tx_enable) {
- value.intval = SB_WRL_TX_MODE;
- snprintf(temp_buf+strlen(temp_buf), size, "%d,", SB_WRL_TX_MODE);
- } else if (is_wireless_all_type(battery->cable_type)) {
- value.intval = SB_WRL_RX_MODE;
- snprintf(temp_buf+strlen(temp_buf), size, "%d,", SB_WRL_RX_MODE);
- } else
- goto skip_wc;
- size = sizeof(temp_buf) - strlen(temp_buf);
- psy_do_property(battery->pdata->wireless_charger_name, get,
- POWER_SUPPLY_EXT_PROP_BATT_DUMP, value);
- snprintf(temp_buf+strlen(temp_buf), size, "%s", value.strval);
- size = sizeof(temp_buf) - strlen(temp_buf);
- skip_wc:
- #endif
- if (value.intval == SB_WRL_NONE) {
- snprintf(temp_buf+strlen(temp_buf), size, "%d,", 0);
- size = sizeof(temp_buf) - strlen(temp_buf);
- }
- count += scnprintf(buf + count, PAGE_SIZE - count, "%s\n", temp_buf);
- }
- break;
- default:
- break;
- }
- return count;
- }
- static ssize_t store_attrs(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- const ptrdiff_t offset = attr - bd_attr;
- switch (offset) {
- case BATTERY_DUMP:
- break;
- default:
- break;
- }
- return count;
- }
- static int sb_noti_handler(struct notifier_block *nb, unsigned long action, void *data)
- {
- return 0;
- }
- int sb_bd_init(void)
- {
- struct sb_bd *bd;
- int ret = 0;
- bd = kzalloc(sizeof(struct sb_bd), GFP_KERNEL);
- if (!bd)
- return -ENOMEM;
- ret = sb_sysfs_add_attrs(BD_MODULE_NAME, bd, bd_attr, ARRAY_SIZE(bd_attr));
- bd_log("sb_sysfs_add_attrs ret = %s\n", (ret) ? "fail" : "success");
- ret = sb_notify_register(&bd->nb, sb_noti_handler, BD_MODULE_NAME, SB_DEV_MODULE);
- bd_log("sb_notify_register ret = %s\n", (ret) ? "fail" : "success");
- return ret;
- }
- EXPORT_SYMBOL(sb_bd_init);
|