get best profile

struct device_node *of_batterydata_get_best_profile(
		const struct device_node *batterydata_container_node,
		const char *psy_name,  const char  *batt_type)
{
	struct batt_ids batt_ids;
	struct device_node *node, *best_node = NULL;
	struct power_supply *psy;
	const char *battery_type = NULL;
	union power_supply_propval ret = {0, };
	int delta = 0, best_delta = 0, best_id_kohm = 0, id_range_pct,
		batt_id_kohm = 0, i = 0, rc = 0, limit = 0;
	bool in_range = false;

    // 找到psy_name注册的句柄
	psy = power_supply_get_by_name(psy_name); // "bms"
	if (!psy) {
		pr_err("%s supply not found. defer\n", psy_name);
		return ERR_PTR(-EPROBE_DEFER);
	}

    // 获得获得某一个属性的值
	rc = psy->get_property(psy, POWER_SUPPLY_PROP_RESISTANCE_ID, &ret);
	if (rc) {
		pr_err("failed to retrieve resistance value rc=%d\n", rc);
		return ERR_PTR(-ENOSYS);
	}

	batt_id_kohm = ret.intval / 1000;
	pr_info("battery_id_ohm : %d (kohm) \n",batt_id_kohm);

    // 读取差异百分比
	/* read battery id range percentage for best profile */
	rc = of_property_read_u32(batterydata_container_node,
			"qcom,batt-id-range-pct", &id_range_pct); // 成功返回0   id_range_pct = 15 ??

	if (rc) {
		if (rc == -EINVAL) {
			id_range_pct = 0;
		} else {
			pr_err("failed to read battery id range\n");
			return ERR_PTR(-ENXIO);
		}
	}

	/* 读取电池类型 10k  220k
	 * Find the battery data with a battery id resistor closest to this one
	 */
	for_each_child_of_node(batterydata_container_node, node) {
		if (batt_type != NULL) {
			rc = of_property_read_string(node, "qcom,battery-type",
							&battery_type); // 读取dts中类型
			if (!rc && strcmp(battery_type, batt_type) == 0) {// 在batt_type已知的情况下,匹配则赋值
				best_node = node;
				best_id_kohm = batt_id_kohm;  // 10 or 220
				break;
			}
		} else { //在batt_type未知的情况下,遍历 然后赋值
			rc = of_batterydata_read_batt_id_kohm(node,
							"qcom,batt-id-kohm",
							&batt_ids);
			if (rc)
				continue;
			for (i = 0; i < batt_ids.num; i++) {
				delta = abs(batt_ids.kohm[i] - batt_id_kohm);
				limit = (batt_ids.kohm[i] * id_range_pct) / 100;  // 15%
				in_range = (delta <= limit); // 是否再范围内 如果不在范围内 则下面的判断直接出局
				/*
				 * Check if the delta is the lowest one
				 * and also if the limits are in range
				 * before selecting the best node.
				 */
				in_range = true; /*2017.1.13 terry add:use first node as default*/
				if ((delta < best_delta || !best_node) // best_node为假 或者delta小于最优delta
					&& in_range) { // 很精华 
					best_node = node;
					best_delta = delta;
					best_id_kohm = batt_ids.kohm[i];
				}
			}
		}
	}

	if (best_node == NULL) {
		pr_err("No battery data found\n");
		return best_node;
	}

	// 当找到与这个物理ID最接近的电池参数后,再来检查一遍  为什么还要再检查一遍的 前面难道不能保证?
	#if 0
	/* check that profile id is in range of the measured batt_id */
	if (abs(best_id_kohm - batt_id_kohm) >
			((best_id_kohm * id_range_pct) / 100)) {
		pr_err("out of range: profile id %d batt id %d pct %d",
			best_id_kohm, batt_id_kohm, id_range_pct);
		return NULL;
	}
	#endif

	rc = of_property_read_string(best_node, "qcom,battery-type",
							&battery_type);
	if (!rc)
		pr_info("%s found\n", battery_type);
	else
		pr_info("%s found\n", best_node->name);

	return best_node;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YouthTravel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值