sb_batt_dump.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * sb_batt_dump.c
  3. * Samsung Mobile Battery Dump Driver
  4. *
  5. * Copyright (C) 2021 Samsung Electronics
  6. *
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. *
  12. */
  13. #include <linux/slab.h>
  14. #include <linux/battery/sb_sysfs.h>
  15. #include <linux/battery/sb_notify.h>
  16. #include "sec_battery.h"
  17. #include "sec_charging_common.h"
  18. #include "sb_batt_dump.h"
  19. #define bd_log(str, ...) pr_info("[BATT-DUMP]:%s: "str, __func__, ##__VA_ARGS__)
  20. #define BD_MODULE_NAME "batt-dump"
  21. struct sb_bd {
  22. struct notifier_block nb;
  23. };
  24. static ssize_t show_attrs(struct device *dev,
  25. struct device_attribute *attr, char *buf);
  26. static ssize_t store_attrs(struct device *dev,
  27. struct device_attribute *attr, const char *buf, size_t count);
  28. #define BD_SYSFS_ATTR(_name) \
  29. { \
  30. .attr = {.name = #_name, .mode = 0664}, \
  31. .show = show_attrs, \
  32. .store = store_attrs, \
  33. }
  34. static struct device_attribute bd_attr[] = {
  35. BD_SYSFS_ATTR(battery_dump),
  36. };
  37. enum sb_bd_attrs {
  38. BATTERY_DUMP = 0,
  39. };
  40. static ssize_t show_attrs(struct device *dev,
  41. struct device_attribute *attr, char *buf)
  42. {
  43. struct power_supply *psy = dev_get_drvdata(dev);
  44. struct sec_battery_info *battery = power_supply_get_drvdata(psy);
  45. const ptrdiff_t offset = attr - bd_attr;
  46. ssize_t count = 0;
  47. union power_supply_propval value = {0, };
  48. switch (offset) {
  49. case BATTERY_DUMP:
  50. {
  51. char temp_buf[1024] = {0,};
  52. int size = 1024;
  53. union power_supply_propval dc_state = {0, };
  54. dc_state.strval = "NO_CHARGING";
  55. #if IS_ENABLED(CONFIG_DIRECT_CHARGING)
  56. psy_do_property(battery->pdata->charger_name, get,
  57. POWER_SUPPLY_EXT_PROP_DIRECT_CHARGER_CHG_STATUS, dc_state);
  58. #endif
  59. snprintf(temp_buf + strlen(temp_buf), size,
  60. "%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,",
  61. battery->voltage_now, battery->current_now,
  62. battery->current_max, battery->charging_current,
  63. battery->capacity,
  64. battery->temperature, battery->usb_temp,
  65. battery->chg_temp, battery->wpc_temp,
  66. battery->blkt_temp, battery->lrp,
  67. battery->dchg_temp, battery->sub_bat_temp,
  68. sb_get_bst_str(battery->status),
  69. dc_state.strval,
  70. sb_get_cm_str(battery->charging_mode),
  71. sb_get_hl_str(battery->health),
  72. sb_get_ct_str(battery->cable_type),
  73. battery->muic_cable_type,
  74. sb_get_tz_str(battery->thermal_zone),
  75. is_slate_mode(battery),
  76. battery->store_mode,
  77. (battery->expired_time / 1000),
  78. battery->current_event,
  79. battery->misc_event,
  80. battery->tx_event,
  81. #if defined(CONFIG_WIRELESS_RX_PHM_CTRL)
  82. battery->wc_rx_pdetb_mode,
  83. #else
  84. battery->wc_rx_phm_mode,
  85. #endif
  86. battery->srccap_transit
  87. );
  88. size = sizeof(temp_buf) - strlen(temp_buf);
  89. {
  90. unsigned short vid = 0, pid = 0;
  91. unsigned int xid = 0;
  92. sec_pd_get_vid_pid(&vid, &pid, &xid);
  93. snprintf(temp_buf+strlen(temp_buf), size,
  94. "%04x,%04x,%08x,", vid, pid, xid);
  95. size = sizeof(temp_buf) - strlen(temp_buf);
  96. }
  97. snprintf(temp_buf+strlen(temp_buf), size,
  98. "%d,%d,%d,%d,",
  99. battery->voltage_avg_main, battery->voltage_avg_sub,
  100. battery->current_avg_main, battery->current_avg_sub);
  101. size = sizeof(temp_buf) - strlen(temp_buf);
  102. snprintf(temp_buf+strlen(temp_buf), size, "%d,", battery->batt_cycle);
  103. size = sizeof(temp_buf) - strlen(temp_buf);
  104. psy_do_property(battery->pdata->fuelgauge_name, get,
  105. POWER_SUPPLY_EXT_PROP_BATT_DUMP, value);
  106. snprintf(temp_buf+strlen(temp_buf), size, "%s,", value.strval);
  107. size = sizeof(temp_buf) - strlen(temp_buf);
  108. /* Wireless charging related log added at the end of the string */
  109. value.intval = SB_WRL_NONE;
  110. #if IS_ENABLED(CONFIG_WIRELESS_CHARGING)
  111. if (battery->wc_tx_enable) {
  112. value.intval = SB_WRL_TX_MODE;
  113. snprintf(temp_buf+strlen(temp_buf), size, "%d,", SB_WRL_TX_MODE);
  114. } else if (is_wireless_all_type(battery->cable_type)) {
  115. value.intval = SB_WRL_RX_MODE;
  116. snprintf(temp_buf+strlen(temp_buf), size, "%d,", SB_WRL_RX_MODE);
  117. } else
  118. goto skip_wc;
  119. size = sizeof(temp_buf) - strlen(temp_buf);
  120. psy_do_property(battery->pdata->wireless_charger_name, get,
  121. POWER_SUPPLY_EXT_PROP_BATT_DUMP, value);
  122. snprintf(temp_buf+strlen(temp_buf), size, "%s", value.strval);
  123. size = sizeof(temp_buf) - strlen(temp_buf);
  124. skip_wc:
  125. #endif
  126. if (value.intval == SB_WRL_NONE) {
  127. snprintf(temp_buf+strlen(temp_buf), size, "%d,", 0);
  128. size = sizeof(temp_buf) - strlen(temp_buf);
  129. }
  130. count += scnprintf(buf + count, PAGE_SIZE - count, "%s\n", temp_buf);
  131. }
  132. break;
  133. default:
  134. break;
  135. }
  136. return count;
  137. }
  138. static ssize_t store_attrs(struct device *dev,
  139. struct device_attribute *attr, const char *buf, size_t count)
  140. {
  141. const ptrdiff_t offset = attr - bd_attr;
  142. switch (offset) {
  143. case BATTERY_DUMP:
  144. break;
  145. default:
  146. break;
  147. }
  148. return count;
  149. }
  150. static int sb_noti_handler(struct notifier_block *nb, unsigned long action, void *data)
  151. {
  152. return 0;
  153. }
  154. int sb_bd_init(void)
  155. {
  156. struct sb_bd *bd;
  157. int ret = 0;
  158. bd = kzalloc(sizeof(struct sb_bd), GFP_KERNEL);
  159. if (!bd)
  160. return -ENOMEM;
  161. ret = sb_sysfs_add_attrs(BD_MODULE_NAME, bd, bd_attr, ARRAY_SIZE(bd_attr));
  162. bd_log("sb_sysfs_add_attrs ret = %s\n", (ret) ? "fail" : "success");
  163. ret = sb_notify_register(&bd->nb, sb_noti_handler, BD_MODULE_NAME, SB_DEV_MODULE);
  164. bd_log("sb_notify_register ret = %s\n", (ret) ? "fail" : "success");
  165. return ret;
  166. }
  167. EXPORT_SYMBOL(sb_bd_init);