0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/power_supply.h>
0012 #include <linux/slab.h>
0013 #include <linux/greybus.h>
0014
0015 #define PROP_MAX 32
0016
0017 struct gb_power_supply_prop {
0018 enum power_supply_property prop;
0019 u8 gb_prop;
0020 int val;
0021 int previous_val;
0022 bool is_writeable;
0023 };
0024
0025 struct gb_power_supply {
0026 u8 id;
0027 bool registered;
0028 struct power_supply *psy;
0029 struct power_supply_desc desc;
0030 char name[64];
0031 struct gb_power_supplies *supplies;
0032 struct delayed_work work;
0033 char *manufacturer;
0034 char *model_name;
0035 char *serial_number;
0036 u8 type;
0037 u8 properties_count;
0038 u8 properties_count_str;
0039 unsigned long last_update;
0040 u8 cache_invalid;
0041 unsigned int update_interval;
0042 bool changed;
0043 struct gb_power_supply_prop *props;
0044 enum power_supply_property *props_raw;
0045 bool pm_acquired;
0046 struct mutex supply_lock;
0047 };
0048
0049 struct gb_power_supplies {
0050 struct gb_connection *connection;
0051 u8 supplies_count;
0052 struct gb_power_supply *supply;
0053 struct mutex supplies_lock;
0054 };
0055
0056 #define to_gb_power_supply(x) power_supply_get_drvdata(x)
0057
0058
0059
0060
0061
0062 #ifndef POWER_SUPPLY_PROP_VOLTAGE_BOOT
0063 #define POWER_SUPPLY_PROP_VOLTAGE_BOOT -1
0064 #endif
0065 #ifndef POWER_SUPPLY_PROP_CURRENT_BOOT
0066 #define POWER_SUPPLY_PROP_CURRENT_BOOT -1
0067 #endif
0068 #ifndef POWER_SUPPLY_PROP_CALIBRATE
0069 #define POWER_SUPPLY_PROP_CALIBRATE -1
0070 #endif
0071
0072
0073 static unsigned int cache_time = 1000;
0074
0075
0076
0077
0078 static unsigned int update_interval_init = 1 * HZ;
0079 static unsigned int update_interval_max = 30 * HZ;
0080
0081 struct gb_power_supply_changes {
0082 enum power_supply_property prop;
0083 u32 tolerance_change;
0084 void (*prop_changed)(struct gb_power_supply *gbpsy,
0085 struct gb_power_supply_prop *prop);
0086 };
0087
0088 static void gb_power_supply_state_change(struct gb_power_supply *gbpsy,
0089 struct gb_power_supply_prop *prop);
0090
0091 static const struct gb_power_supply_changes psy_props_changes[] = {
0092 { .prop = GB_POWER_SUPPLY_PROP_STATUS,
0093 .tolerance_change = 0,
0094 .prop_changed = gb_power_supply_state_change,
0095 },
0096 { .prop = GB_POWER_SUPPLY_PROP_TEMP,
0097 .tolerance_change = 500,
0098 .prop_changed = NULL,
0099 },
0100 { .prop = GB_POWER_SUPPLY_PROP_ONLINE,
0101 .tolerance_change = 0,
0102 .prop_changed = NULL,
0103 },
0104 };
0105
0106 static int get_psp_from_gb_prop(int gb_prop, enum power_supply_property *psp)
0107 {
0108 int prop;
0109
0110 switch (gb_prop) {
0111 case GB_POWER_SUPPLY_PROP_STATUS:
0112 prop = POWER_SUPPLY_PROP_STATUS;
0113 break;
0114 case GB_POWER_SUPPLY_PROP_CHARGE_TYPE:
0115 prop = POWER_SUPPLY_PROP_CHARGE_TYPE;
0116 break;
0117 case GB_POWER_SUPPLY_PROP_HEALTH:
0118 prop = POWER_SUPPLY_PROP_HEALTH;
0119 break;
0120 case GB_POWER_SUPPLY_PROP_PRESENT:
0121 prop = POWER_SUPPLY_PROP_PRESENT;
0122 break;
0123 case GB_POWER_SUPPLY_PROP_ONLINE:
0124 prop = POWER_SUPPLY_PROP_ONLINE;
0125 break;
0126 case GB_POWER_SUPPLY_PROP_AUTHENTIC:
0127 prop = POWER_SUPPLY_PROP_AUTHENTIC;
0128 break;
0129 case GB_POWER_SUPPLY_PROP_TECHNOLOGY:
0130 prop = POWER_SUPPLY_PROP_TECHNOLOGY;
0131 break;
0132 case GB_POWER_SUPPLY_PROP_CYCLE_COUNT:
0133 prop = POWER_SUPPLY_PROP_CYCLE_COUNT;
0134 break;
0135 case GB_POWER_SUPPLY_PROP_VOLTAGE_MAX:
0136 prop = POWER_SUPPLY_PROP_VOLTAGE_MAX;
0137 break;
0138 case GB_POWER_SUPPLY_PROP_VOLTAGE_MIN:
0139 prop = POWER_SUPPLY_PROP_VOLTAGE_MIN;
0140 break;
0141 case GB_POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
0142 prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN;
0143 break;
0144 case GB_POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
0145 prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN;
0146 break;
0147 case GB_POWER_SUPPLY_PROP_VOLTAGE_NOW:
0148 prop = POWER_SUPPLY_PROP_VOLTAGE_NOW;
0149 break;
0150 case GB_POWER_SUPPLY_PROP_VOLTAGE_AVG:
0151 prop = POWER_SUPPLY_PROP_VOLTAGE_AVG;
0152 break;
0153 case GB_POWER_SUPPLY_PROP_VOLTAGE_OCV:
0154 prop = POWER_SUPPLY_PROP_VOLTAGE_OCV;
0155 break;
0156 case GB_POWER_SUPPLY_PROP_VOLTAGE_BOOT:
0157 prop = POWER_SUPPLY_PROP_VOLTAGE_BOOT;
0158 break;
0159 case GB_POWER_SUPPLY_PROP_CURRENT_MAX:
0160 prop = POWER_SUPPLY_PROP_CURRENT_MAX;
0161 break;
0162 case GB_POWER_SUPPLY_PROP_CURRENT_NOW:
0163 prop = POWER_SUPPLY_PROP_CURRENT_NOW;
0164 break;
0165 case GB_POWER_SUPPLY_PROP_CURRENT_AVG:
0166 prop = POWER_SUPPLY_PROP_CURRENT_AVG;
0167 break;
0168 case GB_POWER_SUPPLY_PROP_CURRENT_BOOT:
0169 prop = POWER_SUPPLY_PROP_CURRENT_BOOT;
0170 break;
0171 case GB_POWER_SUPPLY_PROP_POWER_NOW:
0172 prop = POWER_SUPPLY_PROP_POWER_NOW;
0173 break;
0174 case GB_POWER_SUPPLY_PROP_POWER_AVG:
0175 prop = POWER_SUPPLY_PROP_POWER_AVG;
0176 break;
0177 case GB_POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
0178 prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
0179 break;
0180 case GB_POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN:
0181 prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN;
0182 break;
0183 case GB_POWER_SUPPLY_PROP_CHARGE_FULL:
0184 prop = POWER_SUPPLY_PROP_CHARGE_FULL;
0185 break;
0186 case GB_POWER_SUPPLY_PROP_CHARGE_EMPTY:
0187 prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
0188 break;
0189 case GB_POWER_SUPPLY_PROP_CHARGE_NOW:
0190 prop = POWER_SUPPLY_PROP_CHARGE_NOW;
0191 break;
0192 case GB_POWER_SUPPLY_PROP_CHARGE_AVG:
0193 prop = POWER_SUPPLY_PROP_CHARGE_AVG;
0194 break;
0195 case GB_POWER_SUPPLY_PROP_CHARGE_COUNTER:
0196 prop = POWER_SUPPLY_PROP_CHARGE_COUNTER;
0197 break;
0198 case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
0199 prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT;
0200 break;
0201 case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
0202 prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
0203 break;
0204 case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
0205 prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE;
0206 break;
0207 case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
0208 prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX;
0209 break;
0210 case GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
0211 prop = POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT;
0212 break;
0213 case GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX:
0214 prop = POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX;
0215 break;
0216 case GB_POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
0217 prop = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
0218 break;
0219 case GB_POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
0220 prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
0221 break;
0222 case GB_POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN:
0223 prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN;
0224 break;
0225 case GB_POWER_SUPPLY_PROP_ENERGY_FULL:
0226 prop = POWER_SUPPLY_PROP_ENERGY_FULL;
0227 break;
0228 case GB_POWER_SUPPLY_PROP_ENERGY_EMPTY:
0229 prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
0230 break;
0231 case GB_POWER_SUPPLY_PROP_ENERGY_NOW:
0232 prop = POWER_SUPPLY_PROP_ENERGY_NOW;
0233 break;
0234 case GB_POWER_SUPPLY_PROP_ENERGY_AVG:
0235 prop = POWER_SUPPLY_PROP_ENERGY_AVG;
0236 break;
0237 case GB_POWER_SUPPLY_PROP_CAPACITY:
0238 prop = POWER_SUPPLY_PROP_CAPACITY;
0239 break;
0240 case GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
0241 prop = POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN;
0242 break;
0243 case GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX:
0244 prop = POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX;
0245 break;
0246 case GB_POWER_SUPPLY_PROP_CAPACITY_LEVEL:
0247 prop = POWER_SUPPLY_PROP_CAPACITY_LEVEL;
0248 break;
0249 case GB_POWER_SUPPLY_PROP_TEMP:
0250 prop = POWER_SUPPLY_PROP_TEMP;
0251 break;
0252 case GB_POWER_SUPPLY_PROP_TEMP_MAX:
0253 prop = POWER_SUPPLY_PROP_TEMP_MAX;
0254 break;
0255 case GB_POWER_SUPPLY_PROP_TEMP_MIN:
0256 prop = POWER_SUPPLY_PROP_TEMP_MIN;
0257 break;
0258 case GB_POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
0259 prop = POWER_SUPPLY_PROP_TEMP_ALERT_MIN;
0260 break;
0261 case GB_POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
0262 prop = POWER_SUPPLY_PROP_TEMP_ALERT_MAX;
0263 break;
0264 case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT:
0265 prop = POWER_SUPPLY_PROP_TEMP_AMBIENT;
0266 break;
0267 case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
0268 prop = POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN;
0269 break;
0270 case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
0271 prop = POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX;
0272 break;
0273 case GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
0274 prop = POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW;
0275 break;
0276 case GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
0277 prop = POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG;
0278 break;
0279 case GB_POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
0280 prop = POWER_SUPPLY_PROP_TIME_TO_FULL_NOW;
0281 break;
0282 case GB_POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
0283 prop = POWER_SUPPLY_PROP_TIME_TO_FULL_AVG;
0284 break;
0285 case GB_POWER_SUPPLY_PROP_TYPE:
0286 prop = POWER_SUPPLY_PROP_TYPE;
0287 break;
0288 case GB_POWER_SUPPLY_PROP_SCOPE:
0289 prop = POWER_SUPPLY_PROP_SCOPE;
0290 break;
0291 case GB_POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
0292 prop = POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT;
0293 break;
0294 case GB_POWER_SUPPLY_PROP_CALIBRATE:
0295 prop = POWER_SUPPLY_PROP_CALIBRATE;
0296 break;
0297 default:
0298 prop = -1;
0299 break;
0300 }
0301
0302 if (prop < 0)
0303 return prop;
0304
0305 *psp = (enum power_supply_property)prop;
0306
0307 return 0;
0308 }
0309
0310 static struct gb_connection *get_conn_from_psy(struct gb_power_supply *gbpsy)
0311 {
0312 return gbpsy->supplies->connection;
0313 }
0314
0315 static struct gb_power_supply_prop *get_psy_prop(struct gb_power_supply *gbpsy,
0316 enum power_supply_property psp)
0317 {
0318 int i;
0319
0320 for (i = 0; i < gbpsy->properties_count; i++)
0321 if (gbpsy->props[i].prop == psp)
0322 return &gbpsy->props[i];
0323 return NULL;
0324 }
0325
0326 static int is_psy_prop_writeable(struct gb_power_supply *gbpsy,
0327 enum power_supply_property psp)
0328 {
0329 struct gb_power_supply_prop *prop;
0330
0331 prop = get_psy_prop(gbpsy, psp);
0332 if (!prop)
0333 return -ENOENT;
0334 return prop->is_writeable ? 1 : 0;
0335 }
0336
0337 static int is_prop_valint(enum power_supply_property psp)
0338 {
0339 return ((psp < POWER_SUPPLY_PROP_MODEL_NAME) ? 1 : 0);
0340 }
0341
0342 static void next_interval(struct gb_power_supply *gbpsy)
0343 {
0344 if (gbpsy->update_interval == update_interval_max)
0345 return;
0346
0347
0348 gbpsy->update_interval *= 2;
0349 if (gbpsy->update_interval > update_interval_max)
0350 gbpsy->update_interval = update_interval_max;
0351 }
0352
0353 static void __gb_power_supply_changed(struct gb_power_supply *gbpsy)
0354 {
0355 power_supply_changed(gbpsy->psy);
0356 }
0357
0358 static void gb_power_supply_state_change(struct gb_power_supply *gbpsy,
0359 struct gb_power_supply_prop *prop)
0360 {
0361 struct gb_connection *connection = get_conn_from_psy(gbpsy);
0362 int ret;
0363
0364
0365
0366
0367
0368 mutex_lock(&gbpsy->supply_lock);
0369
0370 if ((prop->val == GB_POWER_SUPPLY_STATUS_CHARGING) &&
0371 !gbpsy->pm_acquired) {
0372 ret = gb_pm_runtime_get_sync(connection->bundle);
0373 if (ret)
0374 dev_err(&connection->bundle->dev,
0375 "Fail to set wake lock for charging state\n");
0376 else
0377 gbpsy->pm_acquired = true;
0378 } else {
0379 if (gbpsy->pm_acquired) {
0380 ret = gb_pm_runtime_put_autosuspend(connection->bundle);
0381 if (ret)
0382 dev_err(&connection->bundle->dev,
0383 "Fail to set wake unlock for none charging\n");
0384 else
0385 gbpsy->pm_acquired = false;
0386 }
0387 }
0388
0389 mutex_unlock(&gbpsy->supply_lock);
0390 }
0391
0392 static void check_changed(struct gb_power_supply *gbpsy,
0393 struct gb_power_supply_prop *prop)
0394 {
0395 const struct gb_power_supply_changes *psyc;
0396 int val = prop->val;
0397 int prev_val = prop->previous_val;
0398 bool changed = false;
0399 int i;
0400
0401 for (i = 0; i < ARRAY_SIZE(psy_props_changes); i++) {
0402 psyc = &psy_props_changes[i];
0403 if (prop->prop == psyc->prop) {
0404 if (!psyc->tolerance_change)
0405 changed = true;
0406 else if (val < prev_val &&
0407 prev_val - val > psyc->tolerance_change)
0408 changed = true;
0409 else if (val > prev_val &&
0410 val - prev_val > psyc->tolerance_change)
0411 changed = true;
0412
0413 if (changed && psyc->prop_changed)
0414 psyc->prop_changed(gbpsy, prop);
0415
0416 if (changed)
0417 gbpsy->changed = true;
0418 break;
0419 }
0420 }
0421 }
0422
0423 static int total_props(struct gb_power_supply *gbpsy)
0424 {
0425
0426 return (gbpsy->properties_count + gbpsy->properties_count_str);
0427 }
0428
0429 static void prop_append(struct gb_power_supply *gbpsy,
0430 enum power_supply_property prop)
0431 {
0432 enum power_supply_property *new_props_raw;
0433
0434 gbpsy->properties_count_str++;
0435 new_props_raw = krealloc(gbpsy->props_raw, total_props(gbpsy) *
0436 sizeof(enum power_supply_property),
0437 GFP_KERNEL);
0438 if (!new_props_raw)
0439 return;
0440 gbpsy->props_raw = new_props_raw;
0441 gbpsy->props_raw[total_props(gbpsy) - 1] = prop;
0442 }
0443
0444 static int __gb_power_supply_set_name(char *init_name, char *name, size_t len)
0445 {
0446 unsigned int i = 0;
0447 int ret = 0;
0448 struct power_supply *psy;
0449
0450 if (!strlen(init_name))
0451 init_name = "gb_power_supply";
0452 strscpy(name, init_name, len);
0453
0454 while ((ret < len) && (psy = power_supply_get_by_name(name))) {
0455 power_supply_put(psy);
0456
0457 ret = snprintf(name, len, "%s_%u", init_name, ++i);
0458 }
0459 if (ret >= len)
0460 return -ENOMEM;
0461 return i;
0462 }
0463
0464 static void _gb_power_supply_append_props(struct gb_power_supply *gbpsy)
0465 {
0466 if (strlen(gbpsy->manufacturer))
0467 prop_append(gbpsy, POWER_SUPPLY_PROP_MANUFACTURER);
0468 if (strlen(gbpsy->model_name))
0469 prop_append(gbpsy, POWER_SUPPLY_PROP_MODEL_NAME);
0470 if (strlen(gbpsy->serial_number))
0471 prop_append(gbpsy, POWER_SUPPLY_PROP_SERIAL_NUMBER);
0472 }
0473
0474 static int gb_power_supply_description_get(struct gb_power_supply *gbpsy)
0475 {
0476 struct gb_connection *connection = get_conn_from_psy(gbpsy);
0477 struct gb_power_supply_get_description_request req;
0478 struct gb_power_supply_get_description_response resp;
0479 int ret;
0480
0481 req.psy_id = gbpsy->id;
0482
0483 ret = gb_operation_sync(connection,
0484 GB_POWER_SUPPLY_TYPE_GET_DESCRIPTION,
0485 &req, sizeof(req), &resp, sizeof(resp));
0486 if (ret < 0)
0487 return ret;
0488
0489 gbpsy->manufacturer = kstrndup(resp.manufacturer, PROP_MAX, GFP_KERNEL);
0490 if (!gbpsy->manufacturer)
0491 return -ENOMEM;
0492 gbpsy->model_name = kstrndup(resp.model, PROP_MAX, GFP_KERNEL);
0493 if (!gbpsy->model_name)
0494 return -ENOMEM;
0495 gbpsy->serial_number = kstrndup(resp.serial_number, PROP_MAX,
0496 GFP_KERNEL);
0497 if (!gbpsy->serial_number)
0498 return -ENOMEM;
0499
0500 gbpsy->type = le16_to_cpu(resp.type);
0501 gbpsy->properties_count = resp.properties_count;
0502
0503 return 0;
0504 }
0505
0506 static int gb_power_supply_prop_descriptors_get(struct gb_power_supply *gbpsy)
0507 {
0508 struct gb_connection *connection = get_conn_from_psy(gbpsy);
0509 struct gb_power_supply_get_property_descriptors_request *req;
0510 struct gb_power_supply_get_property_descriptors_response *resp;
0511 struct gb_operation *op;
0512 u8 props_count = gbpsy->properties_count;
0513 enum power_supply_property psp;
0514 int ret;
0515 int i, r = 0;
0516
0517 if (props_count == 0)
0518 return 0;
0519
0520 op = gb_operation_create(connection,
0521 GB_POWER_SUPPLY_TYPE_GET_PROP_DESCRIPTORS,
0522 sizeof(*req),
0523 struct_size(resp, props, props_count),
0524 GFP_KERNEL);
0525 if (!op)
0526 return -ENOMEM;
0527
0528 req = op->request->payload;
0529 req->psy_id = gbpsy->id;
0530
0531 ret = gb_operation_request_send_sync(op);
0532 if (ret < 0)
0533 goto out_put_operation;
0534
0535 resp = op->response->payload;
0536
0537
0538 for (i = 0; i < props_count; i++) {
0539 ret = get_psp_from_gb_prop(resp->props[i].property, &psp);
0540 if (ret < 0) {
0541 dev_warn(&connection->bundle->dev,
0542 "greybus property %u it is not supported by this kernel, dropped\n",
0543 resp->props[i].property);
0544 gbpsy->properties_count--;
0545 }
0546 }
0547
0548 gbpsy->props = kcalloc(gbpsy->properties_count, sizeof(*gbpsy->props),
0549 GFP_KERNEL);
0550 if (!gbpsy->props) {
0551 ret = -ENOMEM;
0552 goto out_put_operation;
0553 }
0554
0555 gbpsy->props_raw = kcalloc(gbpsy->properties_count,
0556 sizeof(*gbpsy->props_raw), GFP_KERNEL);
0557 if (!gbpsy->props_raw) {
0558 ret = -ENOMEM;
0559 goto out_put_operation;
0560 }
0561
0562
0563 for (i = 0; i < props_count; i++) {
0564 ret = get_psp_from_gb_prop(resp->props[i].property, &psp);
0565 if (ret < 0) {
0566 r++;
0567 continue;
0568 }
0569 gbpsy->props[i - r].prop = psp;
0570 gbpsy->props[i - r].gb_prop = resp->props[i].property;
0571 gbpsy->props_raw[i - r] = psp;
0572 if (resp->props[i].is_writeable)
0573 gbpsy->props[i - r].is_writeable = true;
0574 }
0575
0576
0577
0578
0579
0580 _gb_power_supply_append_props(gbpsy);
0581
0582 ret = 0;
0583 out_put_operation:
0584 gb_operation_put(op);
0585
0586 return ret;
0587 }
0588
0589 static int __gb_power_supply_property_update(struct gb_power_supply *gbpsy,
0590 enum power_supply_property psp)
0591 {
0592 struct gb_connection *connection = get_conn_from_psy(gbpsy);
0593 struct gb_power_supply_prop *prop;
0594 struct gb_power_supply_get_property_request req;
0595 struct gb_power_supply_get_property_response resp;
0596 int val;
0597 int ret;
0598
0599 prop = get_psy_prop(gbpsy, psp);
0600 if (!prop)
0601 return -EINVAL;
0602 req.psy_id = gbpsy->id;
0603 req.property = prop->gb_prop;
0604
0605 ret = gb_operation_sync(connection, GB_POWER_SUPPLY_TYPE_GET_PROPERTY,
0606 &req, sizeof(req), &resp, sizeof(resp));
0607 if (ret < 0)
0608 return ret;
0609
0610 val = le32_to_cpu(resp.prop_val);
0611 if (val == prop->val)
0612 return 0;
0613
0614 prop->previous_val = prop->val;
0615 prop->val = val;
0616
0617 check_changed(gbpsy, prop);
0618
0619 return 0;
0620 }
0621
0622 static int __gb_power_supply_property_get(struct gb_power_supply *gbpsy,
0623 enum power_supply_property psp,
0624 union power_supply_propval *val)
0625 {
0626 struct gb_power_supply_prop *prop;
0627
0628 prop = get_psy_prop(gbpsy, psp);
0629 if (!prop)
0630 return -EINVAL;
0631
0632 val->intval = prop->val;
0633 return 0;
0634 }
0635
0636 static int __gb_power_supply_property_strval_get(struct gb_power_supply *gbpsy,
0637 enum power_supply_property psp,
0638 union power_supply_propval *val)
0639 {
0640 switch (psp) {
0641 case POWER_SUPPLY_PROP_MODEL_NAME:
0642 val->strval = gbpsy->model_name;
0643 break;
0644 case POWER_SUPPLY_PROP_MANUFACTURER:
0645 val->strval = gbpsy->manufacturer;
0646 break;
0647 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
0648 val->strval = gbpsy->serial_number;
0649 break;
0650 default:
0651 break;
0652 }
0653
0654 return 0;
0655 }
0656
0657 static int _gb_power_supply_property_get(struct gb_power_supply *gbpsy,
0658 enum power_supply_property psp,
0659 union power_supply_propval *val)
0660 {
0661 struct gb_connection *connection = get_conn_from_psy(gbpsy);
0662 int ret;
0663
0664
0665
0666
0667
0668 if (is_prop_valint(psp))
0669 ret = __gb_power_supply_property_get(gbpsy, psp, val);
0670 else
0671 ret = __gb_power_supply_property_strval_get(gbpsy, psp, val);
0672
0673 if (ret < 0)
0674 dev_err(&connection->bundle->dev, "get property %u\n", psp);
0675
0676 return 0;
0677 }
0678
0679 static int is_cache_valid(struct gb_power_supply *gbpsy)
0680 {
0681
0682 if (gbpsy->cache_invalid) {
0683 gbpsy->cache_invalid = 0;
0684 return 0;
0685 }
0686
0687 if (gbpsy->last_update &&
0688 time_is_after_jiffies(gbpsy->last_update +
0689 msecs_to_jiffies(cache_time)))
0690 return 1;
0691
0692 return 0;
0693 }
0694
0695 static int gb_power_supply_status_get(struct gb_power_supply *gbpsy)
0696 {
0697 struct gb_connection *connection = get_conn_from_psy(gbpsy);
0698 int ret = 0;
0699 int i;
0700
0701 if (is_cache_valid(gbpsy))
0702 return 0;
0703
0704 ret = gb_pm_runtime_get_sync(connection->bundle);
0705 if (ret)
0706 return ret;
0707
0708 for (i = 0; i < gbpsy->properties_count; i++) {
0709 ret = __gb_power_supply_property_update(gbpsy,
0710 gbpsy->props[i].prop);
0711 if (ret < 0)
0712 break;
0713 }
0714
0715 if (ret == 0)
0716 gbpsy->last_update = jiffies;
0717
0718 gb_pm_runtime_put_autosuspend(connection->bundle);
0719 return ret;
0720 }
0721
0722 static void gb_power_supply_status_update(struct gb_power_supply *gbpsy)
0723 {
0724
0725 gb_power_supply_status_get(gbpsy);
0726
0727 if (!gbpsy->changed)
0728 return;
0729
0730 gbpsy->update_interval = update_interval_init;
0731 __gb_power_supply_changed(gbpsy);
0732 gbpsy->changed = false;
0733 }
0734
0735 static void gb_power_supply_work(struct work_struct *work)
0736 {
0737 struct gb_power_supply *gbpsy = container_of(work,
0738 struct gb_power_supply,
0739 work.work);
0740
0741
0742
0743
0744
0745 if (!gbpsy->update_interval)
0746 return;
0747
0748 gb_power_supply_status_update(gbpsy);
0749 next_interval(gbpsy);
0750 schedule_delayed_work(&gbpsy->work, gbpsy->update_interval);
0751 }
0752
0753 static int get_property(struct power_supply *b,
0754 enum power_supply_property psp,
0755 union power_supply_propval *val)
0756 {
0757 struct gb_power_supply *gbpsy = to_gb_power_supply(b);
0758
0759 gb_power_supply_status_get(gbpsy);
0760
0761 return _gb_power_supply_property_get(gbpsy, psp, val);
0762 }
0763
0764 static int gb_power_supply_property_set(struct gb_power_supply *gbpsy,
0765 enum power_supply_property psp,
0766 int val)
0767 {
0768 struct gb_connection *connection = get_conn_from_psy(gbpsy);
0769 struct gb_power_supply_prop *prop;
0770 struct gb_power_supply_set_property_request req;
0771 int ret;
0772
0773 ret = gb_pm_runtime_get_sync(connection->bundle);
0774 if (ret)
0775 return ret;
0776
0777 prop = get_psy_prop(gbpsy, psp);
0778 if (!prop) {
0779 ret = -EINVAL;
0780 goto out;
0781 }
0782
0783 req.psy_id = gbpsy->id;
0784 req.property = prop->gb_prop;
0785 req.prop_val = cpu_to_le32((s32)val);
0786
0787 ret = gb_operation_sync(connection, GB_POWER_SUPPLY_TYPE_SET_PROPERTY,
0788 &req, sizeof(req), NULL, 0);
0789 if (ret < 0)
0790 goto out;
0791
0792
0793 prop->val = val;
0794
0795 out:
0796 gb_pm_runtime_put_autosuspend(connection->bundle);
0797 return ret;
0798 }
0799
0800 static int set_property(struct power_supply *b,
0801 enum power_supply_property psp,
0802 const union power_supply_propval *val)
0803 {
0804 struct gb_power_supply *gbpsy = to_gb_power_supply(b);
0805
0806 return gb_power_supply_property_set(gbpsy, psp, val->intval);
0807 }
0808
0809 static int property_is_writeable(struct power_supply *b,
0810 enum power_supply_property psp)
0811 {
0812 struct gb_power_supply *gbpsy = to_gb_power_supply(b);
0813
0814 return is_psy_prop_writeable(gbpsy, psp);
0815 }
0816
0817 static int gb_power_supply_register(struct gb_power_supply *gbpsy)
0818 {
0819 struct gb_connection *connection = get_conn_from_psy(gbpsy);
0820 struct power_supply_config cfg = {};
0821
0822 cfg.drv_data = gbpsy;
0823
0824 gbpsy->desc.name = gbpsy->name;
0825 gbpsy->desc.type = gbpsy->type;
0826 gbpsy->desc.properties = gbpsy->props_raw;
0827 gbpsy->desc.num_properties = total_props(gbpsy);
0828 gbpsy->desc.get_property = get_property;
0829 gbpsy->desc.set_property = set_property;
0830 gbpsy->desc.property_is_writeable = property_is_writeable;
0831
0832 gbpsy->psy = power_supply_register(&connection->bundle->dev,
0833 &gbpsy->desc, &cfg);
0834 return PTR_ERR_OR_ZERO(gbpsy->psy);
0835 }
0836
0837 static void _gb_power_supply_free(struct gb_power_supply *gbpsy)
0838 {
0839 kfree(gbpsy->serial_number);
0840 kfree(gbpsy->model_name);
0841 kfree(gbpsy->manufacturer);
0842 kfree(gbpsy->props_raw);
0843 kfree(gbpsy->props);
0844 }
0845
0846 static void _gb_power_supply_release(struct gb_power_supply *gbpsy)
0847 {
0848 gbpsy->update_interval = 0;
0849
0850 cancel_delayed_work_sync(&gbpsy->work);
0851
0852 if (gbpsy->registered)
0853 power_supply_unregister(gbpsy->psy);
0854
0855 _gb_power_supply_free(gbpsy);
0856 }
0857
0858 static void _gb_power_supplies_release(struct gb_power_supplies *supplies)
0859 {
0860 int i;
0861
0862 if (!supplies->supply)
0863 return;
0864
0865 mutex_lock(&supplies->supplies_lock);
0866 for (i = 0; i < supplies->supplies_count; i++)
0867 _gb_power_supply_release(&supplies->supply[i]);
0868 kfree(supplies->supply);
0869 mutex_unlock(&supplies->supplies_lock);
0870 kfree(supplies);
0871 }
0872
0873 static int gb_power_supplies_get_count(struct gb_power_supplies *supplies)
0874 {
0875 struct gb_power_supply_get_supplies_response resp;
0876 int ret;
0877
0878 ret = gb_operation_sync(supplies->connection,
0879 GB_POWER_SUPPLY_TYPE_GET_SUPPLIES,
0880 NULL, 0, &resp, sizeof(resp));
0881 if (ret < 0)
0882 return ret;
0883
0884 if (!resp.supplies_count)
0885 return -EINVAL;
0886
0887 supplies->supplies_count = resp.supplies_count;
0888
0889 return ret;
0890 }
0891
0892 static int gb_power_supply_config(struct gb_power_supplies *supplies, int id)
0893 {
0894 struct gb_power_supply *gbpsy = &supplies->supply[id];
0895 int ret;
0896
0897 gbpsy->supplies = supplies;
0898 gbpsy->id = id;
0899
0900 ret = gb_power_supply_description_get(gbpsy);
0901 if (ret < 0)
0902 return ret;
0903
0904 return gb_power_supply_prop_descriptors_get(gbpsy);
0905 }
0906
0907 static int gb_power_supply_enable(struct gb_power_supply *gbpsy)
0908 {
0909 int ret;
0910
0911
0912 ret = __gb_power_supply_set_name(gbpsy->model_name, gbpsy->name,
0913 sizeof(gbpsy->name));
0914 if (ret < 0)
0915 return ret;
0916
0917 mutex_init(&gbpsy->supply_lock);
0918
0919 ret = gb_power_supply_register(gbpsy);
0920 if (ret < 0)
0921 return ret;
0922
0923 gbpsy->update_interval = update_interval_init;
0924 INIT_DELAYED_WORK(&gbpsy->work, gb_power_supply_work);
0925 schedule_delayed_work(&gbpsy->work, 0);
0926
0927
0928 gbpsy->registered = true;
0929
0930 return 0;
0931 }
0932
0933 static int gb_power_supplies_setup(struct gb_power_supplies *supplies)
0934 {
0935 struct gb_connection *connection = supplies->connection;
0936 int ret;
0937 int i;
0938
0939 mutex_lock(&supplies->supplies_lock);
0940
0941 ret = gb_power_supplies_get_count(supplies);
0942 if (ret < 0)
0943 goto out;
0944
0945 supplies->supply = kcalloc(supplies->supplies_count,
0946 sizeof(struct gb_power_supply),
0947 GFP_KERNEL);
0948
0949 if (!supplies->supply) {
0950 ret = -ENOMEM;
0951 goto out;
0952 }
0953
0954 for (i = 0; i < supplies->supplies_count; i++) {
0955 ret = gb_power_supply_config(supplies, i);
0956 if (ret < 0) {
0957 dev_err(&connection->bundle->dev,
0958 "Fail to configure supplies devices\n");
0959 goto out;
0960 }
0961 }
0962 out:
0963 mutex_unlock(&supplies->supplies_lock);
0964 return ret;
0965 }
0966
0967 static int gb_power_supplies_register(struct gb_power_supplies *supplies)
0968 {
0969 struct gb_connection *connection = supplies->connection;
0970 int ret = 0;
0971 int i;
0972
0973 mutex_lock(&supplies->supplies_lock);
0974
0975 for (i = 0; i < supplies->supplies_count; i++) {
0976 ret = gb_power_supply_enable(&supplies->supply[i]);
0977 if (ret < 0) {
0978 dev_err(&connection->bundle->dev,
0979 "Fail to enable supplies devices\n");
0980 break;
0981 }
0982 }
0983
0984 mutex_unlock(&supplies->supplies_lock);
0985 return ret;
0986 }
0987
0988 static int gb_supplies_request_handler(struct gb_operation *op)
0989 {
0990 struct gb_connection *connection = op->connection;
0991 struct gb_power_supplies *supplies = gb_connection_get_data(connection);
0992 struct gb_power_supply *gbpsy;
0993 struct gb_message *request;
0994 struct gb_power_supply_event_request *payload;
0995 u8 psy_id;
0996 u8 event;
0997 int ret = 0;
0998
0999 if (op->type != GB_POWER_SUPPLY_TYPE_EVENT) {
1000 dev_err(&connection->bundle->dev,
1001 "Unsupported unsolicited event: %u\n", op->type);
1002 return -EINVAL;
1003 }
1004
1005 request = op->request;
1006
1007 if (request->payload_size < sizeof(*payload)) {
1008 dev_err(&connection->bundle->dev,
1009 "Wrong event size received (%zu < %zu)\n",
1010 request->payload_size, sizeof(*payload));
1011 return -EINVAL;
1012 }
1013
1014 payload = request->payload;
1015 psy_id = payload->psy_id;
1016 mutex_lock(&supplies->supplies_lock);
1017 if (psy_id >= supplies->supplies_count ||
1018 !supplies->supply[psy_id].registered) {
1019 dev_err(&connection->bundle->dev,
1020 "Event received for unconfigured power_supply id: %d\n",
1021 psy_id);
1022 ret = -EINVAL;
1023 goto out_unlock;
1024 }
1025
1026 event = payload->event;
1027
1028
1029
1030
1031 gbpsy = &supplies->supply[psy_id];
1032 if (!gbpsy->update_interval) {
1033 ret = -ESHUTDOWN;
1034 goto out_unlock;
1035 }
1036
1037 if (event & GB_POWER_SUPPLY_UPDATE) {
1038
1039
1040
1041
1042
1043 gbpsy->cache_invalid = 1;
1044 gb_power_supply_status_update(gbpsy);
1045 }
1046
1047 out_unlock:
1048 mutex_unlock(&supplies->supplies_lock);
1049 return ret;
1050 }
1051
1052 static int gb_power_supply_probe(struct gb_bundle *bundle,
1053 const struct greybus_bundle_id *id)
1054 {
1055 struct greybus_descriptor_cport *cport_desc;
1056 struct gb_connection *connection;
1057 struct gb_power_supplies *supplies;
1058 int ret;
1059
1060 if (bundle->num_cports != 1)
1061 return -ENODEV;
1062
1063 cport_desc = &bundle->cport_desc[0];
1064 if (cport_desc->protocol_id != GREYBUS_PROTOCOL_POWER_SUPPLY)
1065 return -ENODEV;
1066
1067 supplies = kzalloc(sizeof(*supplies), GFP_KERNEL);
1068 if (!supplies)
1069 return -ENOMEM;
1070
1071 connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
1072 gb_supplies_request_handler);
1073 if (IS_ERR(connection)) {
1074 ret = PTR_ERR(connection);
1075 goto out;
1076 }
1077
1078 supplies->connection = connection;
1079 gb_connection_set_data(connection, supplies);
1080
1081 mutex_init(&supplies->supplies_lock);
1082
1083 greybus_set_drvdata(bundle, supplies);
1084
1085
1086 ret = gb_connection_enable_tx(connection);
1087 if (ret)
1088 goto error_connection_destroy;
1089
1090 ret = gb_power_supplies_setup(supplies);
1091 if (ret < 0)
1092 goto error_connection_disable;
1093
1094
1095 ret = gb_connection_enable(connection);
1096 if (ret)
1097 goto error_connection_disable;
1098
1099 ret = gb_power_supplies_register(supplies);
1100 if (ret < 0)
1101 goto error_connection_disable;
1102
1103 gb_pm_runtime_put_autosuspend(bundle);
1104 return 0;
1105
1106 error_connection_disable:
1107 gb_connection_disable(connection);
1108 error_connection_destroy:
1109 gb_connection_destroy(connection);
1110 out:
1111 _gb_power_supplies_release(supplies);
1112 return ret;
1113 }
1114
1115 static void gb_power_supply_disconnect(struct gb_bundle *bundle)
1116 {
1117 struct gb_power_supplies *supplies = greybus_get_drvdata(bundle);
1118
1119 gb_connection_disable(supplies->connection);
1120 gb_connection_destroy(supplies->connection);
1121
1122 _gb_power_supplies_release(supplies);
1123 }
1124
1125 static const struct greybus_bundle_id gb_power_supply_id_table[] = {
1126 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_POWER_SUPPLY) },
1127 { }
1128 };
1129 MODULE_DEVICE_TABLE(greybus, gb_power_supply_id_table);
1130
1131 static struct greybus_driver gb_power_supply_driver = {
1132 .name = "power_supply",
1133 .probe = gb_power_supply_probe,
1134 .disconnect = gb_power_supply_disconnect,
1135 .id_table = gb_power_supply_id_table,
1136 };
1137 module_greybus_driver(gb_power_supply_driver);
1138
1139 MODULE_LICENSE("GPL v2");