Lines 67-72
gboolean _have_sysfs_lid_button = FALSE;
Link Here
|
67 |
gboolean _have_sysfs_lid_button = FALSE; |
67 |
gboolean _have_sysfs_lid_button = FALSE; |
68 |
gboolean _have_sysfs_power_button = FALSE; |
68 |
gboolean _have_sysfs_power_button = FALSE; |
69 |
gboolean _have_sysfs_sleep_button = FALSE; |
69 |
gboolean _have_sysfs_sleep_button = FALSE; |
|
|
70 |
gboolean _have_sysfs_power_supply = FALSE; |
71 |
|
72 |
#define POWER_SUPPLY_BATTERY_POLL_INTERVAL 30000 |
70 |
|
73 |
|
71 |
/* we must use this kernel-compatible implementation */ |
74 |
/* we must use this kernel-compatible implementation */ |
72 |
#define BITS_PER_LONG (sizeof(long) * 8) |
75 |
#define BITS_PER_LONG (sizeof(long) * 8) |
Lines 3001-3015
refresh_battery_fast (HalDevice *d)
Link Here
|
3001 |
{ |
3004 |
{ |
3002 |
gint percentage = 0; |
3005 |
gint percentage = 0; |
3003 |
gint voltage_now = 0; |
3006 |
gint voltage_now = 0; |
3004 |
gint voltage_design = 0; |
|
|
3005 |
gint current = 0; |
3007 |
gint current = 0; |
3006 |
gint time = 0; |
3008 |
gint time = 0; |
3007 |
gint value_now = 0; |
3009 |
gint value_now = 0; |
3008 |
gint value_last_full = 0; |
3010 |
gint value_last_full = 0; |
3009 |
gint value_full_design = 0; |
|
|
3010 |
gboolean present = FALSE; |
3011 |
gboolean present = FALSE; |
3011 |
gboolean could_be_mah = TRUE; |
3012 |
gboolean unknown_unit = TRUE; |
3012 |
gboolean could_be_mwh = TRUE; |
|
|
3013 |
gboolean is_mah = FALSE; |
3013 |
gboolean is_mah = FALSE; |
3014 |
gboolean is_mwh = FALSE; |
3014 |
gboolean is_mwh = FALSE; |
3015 |
gboolean is_charging = FALSE; |
3015 |
gboolean is_charging = FALSE; |
Lines 3047-3061
refresh_battery_fast (HalDevice *d)
Link Here
|
3047 |
} else if (hal_util_get_int_from_file (path, "voltage_now", &voltage_now, 10)) { |
3047 |
} else if (hal_util_get_int_from_file (path, "voltage_now", &voltage_now, 10)) { |
3048 |
hal_device_property_set_int (d, "battery.voltage.current", voltage_now / 1000); |
3048 |
hal_device_property_set_int (d, "battery.voltage.current", voltage_now / 1000); |
3049 |
} |
3049 |
} |
3050 |
if (hal_util_get_int_from_file (path, "voltage_max_design", &voltage_design, 10)) { |
|
|
3051 |
hal_device_property_set_int (d, "battery.voltage.design", voltage_design / 1000); |
3052 |
} |
3053 |
|
3050 |
|
3054 |
/* CURRENT: we prefer the average if it exists, although present is still pretty good */ |
3051 |
/* CURRENT: we prefer the average if it exists, although present is still pretty good */ |
3055 |
if (hal_util_get_int_from_file (path, "current_avg", ¤t, 10)) { |
3052 |
if (hal_util_get_int_from_file (path, "current_avg", ¤t, 10)) { |
3056 |
hal_device_property_set_int (d, "battery.current", current / 1000); |
3053 |
hal_device_property_set_int (d, "battery.reporting.rate", current / 1000); |
3057 |
} else if (hal_util_get_int_from_file (path, "current_now", ¤t, 10)) { |
3054 |
} else if (hal_util_get_int_from_file (path, "current_now", ¤t, 10)) { |
3058 |
hal_device_property_set_int (d, "battery.current", current / 1000); |
3055 |
hal_device_property_set_int (d, "battery.reporting.rate", current / 1000); |
3059 |
} |
3056 |
} |
3060 |
|
3057 |
|
3061 |
/* STATUS: Convert to charging/discharging state */ |
3058 |
/* STATUS: Convert to charging/discharging state */ |
Lines 3066-3071
refresh_battery_fast (HalDevice *d)
Link Here
|
3066 |
} else if (strcasecmp (status, "discharging") == 0) { |
3063 |
} else if (strcasecmp (status, "discharging") == 0) { |
3067 |
is_discharging = TRUE; |
3064 |
is_discharging = TRUE; |
3068 |
} |
3065 |
} |
|
|
3066 |
hal_device_property_set_bool (d, "battery.is_rechargeable", TRUE); |
3069 |
hal_device_property_set_bool (d, "battery.rechargeable.is_charging", is_charging); |
3067 |
hal_device_property_set_bool (d, "battery.rechargeable.is_charging", is_charging); |
3070 |
hal_device_property_set_bool (d, "battery.rechargeable.is_discharging", is_discharging); |
3068 |
hal_device_property_set_bool (d, "battery.rechargeable.is_discharging", is_discharging); |
3071 |
} |
3069 |
} |
Lines 3088-3101
refresh_battery_fast (HalDevice *d)
Link Here
|
3088 |
reporting_unit = hal_device_property_get_string (d, "battery.reporting.unit"); |
3086 |
reporting_unit = hal_device_property_get_string (d, "battery.reporting.unit"); |
3089 |
if (reporting_unit != NULL) { |
3087 |
if (reporting_unit != NULL) { |
3090 |
if (strcasecmp (reporting_unit, "mah") == 0) { |
3088 |
if (strcasecmp (reporting_unit, "mah") == 0) { |
3091 |
could_be_mwh = FALSE; |
3089 |
is_mah = TRUE; |
|
|
3090 |
unknown_unit = FALSE; |
3092 |
} else if (strcasecmp (reporting_unit, "mwh") == 0) { |
3091 |
} else if (strcasecmp (reporting_unit, "mwh") == 0) { |
3093 |
could_be_mah = FALSE; |
3092 |
is_mwh = TRUE; |
|
|
3093 |
unknown_unit = FALSE; |
3094 |
} |
3094 |
} |
3095 |
} |
3095 |
} |
3096 |
|
3096 |
|
3097 |
/* ENERGY (reported in uWh, so need to convert to mWh) */ |
3097 |
/* ENERGY (reported in uWh, so need to convert to mWh) */ |
3098 |
if (could_be_mwh) { |
3098 |
if (unknown_unit || is_mwh) { |
3099 |
if (hal_util_get_int_from_file (path, "energy_avg", &value_now, 10)) { |
3099 |
if (hal_util_get_int_from_file (path, "energy_avg", &value_now, 10)) { |
3100 |
hal_device_property_set_int (d, "battery.reporting.current", value_now / 1000); |
3100 |
hal_device_property_set_int (d, "battery.reporting.current", value_now / 1000); |
3101 |
is_mwh = TRUE; |
3101 |
is_mwh = TRUE; |
Lines 3107-3120
refresh_battery_fast (HalDevice *d)
Link Here
|
3107 |
hal_device_property_set_int (d, "battery.reporting.last_full", value_last_full / 1000); |
3107 |
hal_device_property_set_int (d, "battery.reporting.last_full", value_last_full / 1000); |
3108 |
is_mwh = TRUE; |
3108 |
is_mwh = TRUE; |
3109 |
} |
3109 |
} |
3110 |
if (hal_util_get_int_from_file (path, "energy_full_design", &value_full_design, 10)) { |
|
|
3111 |
hal_device_property_set_int (d, "battery.reporting.design", value_full_design / 1000); |
3112 |
is_mwh = TRUE; |
3113 |
} |
3114 |
} |
3110 |
} |
3115 |
|
3111 |
|
3116 |
/* CHARGE (reported in uAh, so need to convert to mAh) */ |
3112 |
/* CHARGE (reported in uAh, so need to convert to mAh) */ |
3117 |
if (could_be_mah) { |
3113 |
if ((unknown_unit && !is_mwh) || is_mah) { |
3118 |
if (hal_util_get_int_from_file (path, "charge_avg", &value_now, 10)) { |
3114 |
if (hal_util_get_int_from_file (path, "charge_avg", &value_now, 10)) { |
3119 |
hal_device_property_set_int (d, "battery.reporting.current", value_now / 1000); |
3115 |
hal_device_property_set_int (d, "battery.reporting.current", value_now / 1000); |
3120 |
is_mah = TRUE; |
3116 |
is_mah = TRUE; |
Lines 3126-3142
refresh_battery_fast (HalDevice *d)
Link Here
|
3126 |
hal_device_property_set_int (d, "battery.reporting.last_full", value_last_full / 1000); |
3122 |
hal_device_property_set_int (d, "battery.reporting.last_full", value_last_full / 1000); |
3127 |
is_mah = TRUE; |
3123 |
is_mah = TRUE; |
3128 |
} |
3124 |
} |
3129 |
if (hal_util_get_int_from_file (path, "charge_full_design", &value_full_design, 10)) { |
|
|
3130 |
hal_device_property_set_int (d, "battery.reporting.design", value_full_design / 1000); |
3131 |
is_mah = TRUE; |
3132 |
} |
3133 |
} |
3125 |
} |
3134 |
|
3126 |
|
3135 |
/* record these for future savings */ |
3127 |
/* record these for future savings */ |
3136 |
if (is_mwh == TRUE) { |
3128 |
if (unknown_unit) { |
3137 |
hal_device_property_set_string (d, "battery.reporting.unit", "mWh"); |
3129 |
if (is_mwh == TRUE) { |
3138 |
} else if (is_mah == TRUE) { |
3130 |
hal_device_property_set_string (d, "battery.reporting.unit", "mWh"); |
3139 |
hal_device_property_set_string (d, "battery.reporting.unit", "mAh"); |
3131 |
} else if (is_mah == TRUE) { |
|
|
3132 |
hal_device_property_set_string (d, "battery.reporting.unit", "mAh"); |
3133 |
} |
3140 |
} |
3134 |
} |
3141 |
|
3135 |
|
3142 |
/* we've now got the 'reporting' keys, now we need to populate the |
3136 |
/* we've now got the 'reporting' keys, now we need to populate the |
Lines 3166-3175
static void
Link Here
|
3166 |
static void |
3160 |
static void |
3167 |
refresh_battery_slow (HalDevice *d) |
3161 |
refresh_battery_slow (HalDevice *d) |
3168 |
{ |
3162 |
{ |
3169 |
const char *technology; |
3163 |
gint voltage_design = 0; |
|
|
3164 |
gint value_full_design = 0; |
3170 |
char *technology_raw; |
3165 |
char *technology_raw; |
3171 |
char *model_name; |
3166 |
char *model_name; |
3172 |
char *manufacturer; |
3167 |
char *manufacturer; |
|
|
3168 |
char *serial; |
3173 |
const gchar *path; |
3169 |
const gchar *path; |
3174 |
|
3170 |
|
3175 |
path = hal_device_property_get_string (d, "linux.sysfs_path"); |
3171 |
path = hal_device_property_get_string (d, "linux.sysfs_path"); |
Lines 3181-3193
refresh_battery_slow (HalDevice *d)
Link Here
|
3181 |
if (technology_raw != NULL) { |
3177 |
if (technology_raw != NULL) { |
3182 |
hal_device_property_set_string (d, "battery.reporting.technology", technology_raw); |
3178 |
hal_device_property_set_string (d, "battery.reporting.technology", technology_raw); |
3183 |
} |
3179 |
} |
3184 |
/* we set this, even if it's unknown */ |
3180 |
hal_device_property_set_string (d, "battery.technology", util_get_battery_technology (technology_raw)); |
3185 |
technology = util_get_battery_technology (technology_raw); |
|
|
3186 |
hal_device_property_set_string (d, "battery.technology", technology); |
3187 |
|
3181 |
|
3188 |
/* get product name */ |
3182 |
/* get product name */ |
3189 |
model_name = hal_util_get_string_from_file (path, "technology"); |
3183 |
model_name = hal_util_get_string_from_file (path, "model_name"); |
3190 |
if (model_name != NULL) { |
3184 |
if (model_name != NULL) { |
|
|
3185 |
hal_device_property_set_string (d, "battery.model", model_name); |
3191 |
hal_device_property_set_string (d, "info.product", model_name); |
3186 |
hal_device_property_set_string (d, "info.product", model_name); |
3192 |
} else { |
3187 |
} else { |
3193 |
hal_device_property_set_string (d, "info.product", "Generic Battery Device"); |
3188 |
hal_device_property_set_string (d, "info.product", "Generic Battery Device"); |
Lines 3197-3202
refresh_battery_slow (HalDevice *d)
Link Here
|
3197 |
manufacturer = hal_util_get_string_from_file (path, "manufacturer"); |
3192 |
manufacturer = hal_util_get_string_from_file (path, "manufacturer"); |
3198 |
if (manufacturer != NULL) { |
3193 |
if (manufacturer != NULL) { |
3199 |
hal_device_property_set_string (d, "battery.vendor", manufacturer); |
3194 |
hal_device_property_set_string (d, "battery.vendor", manufacturer); |
|
|
3195 |
} |
3196 |
|
3197 |
/* get stuff that never changes */ |
3198 |
if (hal_util_get_int_from_file (path, "voltage_max_design", &voltage_design, 10)) { |
3199 |
hal_device_property_set_int (d, "battery.voltage.design", voltage_design / 1000); |
3200 |
hal_device_property_set_string (d, "battery.voltage.unit", "mV"); |
3201 |
} else if (hal_util_get_int_from_file (path, "voltage_min_design", &voltage_design, 10)) { |
3202 |
hal_device_property_set_int (d, "battery.voltage.design", voltage_design / 1000); |
3203 |
hal_device_property_set_string (d, "battery.voltage.unit", "mV"); |
3204 |
} |
3205 |
|
3206 |
/* try to get the design info and set the units */ |
3207 |
if (hal_util_get_int_from_file (path, "energy_full_design", &value_full_design, 10)) { |
3208 |
hal_device_property_set_int (d, "battery.reporting.design", value_full_design / 1000); |
3209 |
hal_device_property_set_string (d, "battery.reporting.unit", "mWh"); |
3210 |
} else if (hal_util_get_int_from_file (path, "charge_full_design", &value_full_design, 10)) { |
3211 |
hal_device_property_set_int (d, "battery.reporting.design", value_full_design / 1000); |
3212 |
hal_device_property_set_string (d, "battery.reporting.unit", "mAh"); |
3213 |
} |
3214 |
|
3215 |
/* get serial */ |
3216 |
serial = hal_util_get_string_from_file (path, "serial_number"); |
3217 |
if (serial != NULL) { |
3218 |
hal_device_property_set_string (d, "battery.serial", serial); |
3200 |
} |
3219 |
} |
3201 |
|
3220 |
|
3202 |
/* now do stuff that happens quickly */ |
3221 |
/* now do stuff that happens quickly */ |
Lines 3217-3228
power_supply_refresh (HalDevice *d)
Link Here
|
3217 |
device_property_atomic_update_end (); |
3236 |
device_property_atomic_update_end (); |
3218 |
} else if (strcmp (type, "battery") == 0) { |
3237 |
} else if (strcmp (type, "battery") == 0) { |
3219 |
device_property_atomic_update_begin (); |
3238 |
device_property_atomic_update_begin (); |
3220 |
refresh_battery_slow (d); |
3239 |
refresh_battery_fast (d); |
3221 |
device_property_atomic_update_end (); |
3240 |
device_property_atomic_update_end (); |
3222 |
} else { |
3241 |
} else { |
3223 |
HAL_WARNING (("Could not recognise power_supply type!")); |
3242 |
HAL_WARNING (("Could not recognise power_supply type!")); |
3224 |
return FALSE; |
3243 |
return FALSE; |
3225 |
} |
3244 |
} |
|
|
3245 |
return TRUE; |
3246 |
} |
3247 |
|
3248 |
|
3249 |
static gboolean |
3250 |
power_supply_battery_poll (gpointer data) { |
3251 |
|
3252 |
GSList *i; |
3253 |
GSList *battery_devices; |
3254 |
HalDevice *d; |
3255 |
|
3256 |
/* for now do it only for primary batteries and extend if neede for the other types */ |
3257 |
battery_devices = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), |
3258 |
"battery.type", |
3259 |
"primary"); |
3260 |
|
3261 |
if (battery_devices) { |
3262 |
for (i = battery_devices; i != NULL; i = g_slist_next (i)) { |
3263 |
const char *subsys; |
3264 |
|
3265 |
d = HAL_DEVICE (i->data); |
3266 |
subsys = hal_device_property_get_string (d, "linux.subsystem"); |
3267 |
if (subsys && (strcmp(subsys, "power_supply") == 0)) { |
3268 |
hal_util_grep_discard_existing_data(); |
3269 |
device_property_atomic_update_begin (); |
3270 |
refresh_battery_fast(d); |
3271 |
device_property_atomic_update_end (); |
3272 |
} |
3273 |
} |
3274 |
} |
3275 |
g_slist_free (battery_devices); |
3226 |
return TRUE; |
3276 |
return TRUE; |
3227 |
} |
3277 |
} |
3228 |
|
3278 |
|
Lines 3268-3273
power_supply_add (const gchar *sysfs_pat
Link Here
|
3268 |
hal_device_property_set_string (d, "battery.type", battery_type); |
3318 |
hal_device_property_set_string (d, "battery.type", battery_type); |
3269 |
refresh_battery_slow (d); |
3319 |
refresh_battery_slow (d); |
3270 |
hal_device_add_capability (d, "battery"); |
3320 |
hal_device_add_capability (d, "battery"); |
|
|
3321 |
|
3322 |
/* setup timer for things that we need to poll */ |
3323 |
g_timeout_add ( POWER_SUPPLY_BATTERY_POLL_INTERVAL, |
3324 |
power_supply_battery_poll, |
3325 |
NULL); |
3271 |
} |
3326 |
} |
3272 |
|
3327 |
|
3273 |
if (is_ac_adapter == TRUE) { |
3328 |
if (is_ac_adapter == TRUE) { |
Lines 3276-3281
power_supply_add (const gchar *sysfs_pat
Link Here
|
3276 |
refresh_ac_adapter (d); |
3331 |
refresh_ac_adapter (d); |
3277 |
hal_device_add_capability (d, "ac_adapter"); |
3332 |
hal_device_add_capability (d, "ac_adapter"); |
3278 |
} |
3333 |
} |
|
|
3334 |
|
3335 |
_have_sysfs_power_supply = TRUE; |
3279 |
finish: |
3336 |
finish: |
3280 |
return d; |
3337 |
return d; |
3281 |
} |
3338 |
} |
Lines 3290-3298
power_supply_compute_udi (HalDevice *d)
Link Here
|
3290 |
dir = hal_device_property_get_string (d, "linux.sysfs_path"); |
3347 |
dir = hal_device_property_get_string (d, "linux.sysfs_path"); |
3291 |
|
3348 |
|
3292 |
name = hal_util_get_last_element(dir); |
3349 |
name = hal_util_get_last_element(dir); |
3293 |
hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi), |
3350 |
if (name) |
3294 |
"%s_power_supply", |
3351 |
hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi), |
3295 |
hal_device_property_get_string (d, "info.parent")); |
3352 |
"%s_power_supply_%s_%s", |
|
|
3353 |
hal_device_property_get_string (d, "info.parent"), |
3354 |
hal_device_property_get_string (d, "info.category"), |
3355 |
name); |
3356 |
else |
3357 |
hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi), |
3358 |
"%s_power_supply_%s", |
3359 |
hal_device_property_get_string (d, "info.parent"), |
3360 |
hal_device_property_get_string (d, "info.category")); |
3361 |
|
3296 |
hal_device_set_udi (d, udi); |
3362 |
hal_device_set_udi (d, udi); |
3297 |
hal_device_property_set_string (d, "info.udi", udi); |
3363 |
hal_device_property_set_string (d, "info.udi", udi); |
3298 |
return TRUE; |
3364 |
return TRUE; |