static int bd9995x_fw_probe()

in supply/bd99954-charger.c [882:1028]


static int bd9995x_fw_probe(struct bd9995x_device *bd)
{
	int ret;
	struct power_supply_battery_info *info;
	u32 property;
	int i;
	int regval;
	bool found;
	struct bd9995x_init_data *init = &bd->init_data;
	struct battery_init battery_inits[] = {
		{
			.name = "trickle-charging current",
			.range = &charging_current_ranges[0],
			.ranges = 2,
			.data = &init->itrich_set,
		}, {
			.name = "pre-charging current",
			.range = &charging_current_ranges[0],
			.ranges = 2,
			.data = &init->iprech_set,
		}, {
			.name = "pre-to-trickle charge voltage threshold",
			.range = &trickle_to_pre_threshold_ranges[0],
			.ranges = 2,
			.data = &init->vprechg_th_set,
		}, {
			.name = "charging termination current",
			.range = &charging_current_ranges[0],
			.ranges = 2,
			.data = &init->iterm_set,
		}, {
			.name = "charging re-start voltage",
			.range = &charge_voltage_regulation_ranges[0],
			.ranges = 2,
			.data = &init->vrechg_set,
		}, {
			.name = "battery overvoltage limit",
			.range = &charge_voltage_regulation_ranges[0],
			.ranges = 2,
			.data = &init->vbatovp_set,
		}, {
			.name = "fast-charging max current",
			.range = &fast_charge_current_ranges[0],
			.ranges = 1,
			.data = &init->ichg_set,
		}, {
			.name = "fast-charging voltage",
			.range = &charge_voltage_regulation_ranges[0],
			.ranges = 2,
			.data = &init->vfastchg_reg_set1,
		},
	};
	struct dt_init props[] = {
		{
			.prop = "rohm,vsys-regulation-microvolt",
			.range = &vsys_voltage_regulation_ranges[0],
			.ranges = 2,
			.data = &init->vsysreg_set,
		}, {
			.prop = "rohm,vbus-input-current-limit-microamp",
			.range = &input_current_limit_ranges[0],
			.ranges = 1,
			.data = &init->ibus_lim_set,
		}, {
			.prop = "rohm,vcc-input-current-limit-microamp",
			.range = &input_current_limit_ranges[0],
			.ranges = 1,
			.data = &init->icc_lim_set,
		},
	};

	/*
	 * The power_supply_get_battery_info() does not support getting values
	 * from ACPI. Let's fix it if ACPI is required here.
	 */
	ret = power_supply_get_battery_info(bd->charger, &info);
	if (ret < 0)
		return ret;

	/* Put pointers to the generic battery info */
	battery_inits[0].info_data = &info->tricklecharge_current_ua;
	battery_inits[1].info_data = &info->precharge_current_ua;
	battery_inits[2].info_data = &info->precharge_voltage_max_uv;
	battery_inits[3].info_data = &info->charge_term_current_ua;
	battery_inits[4].info_data = &info->charge_restart_voltage_uv;
	battery_inits[5].info_data = &info->overvoltage_limit_uv;
	battery_inits[6].info_data = &info->constant_charge_current_max_ua;
	battery_inits[7].info_data = &info->constant_charge_voltage_max_uv;

	for (i = 0; i < ARRAY_SIZE(battery_inits); i++) {
		int val = *battery_inits[i].info_data;
		const struct linear_range *range = battery_inits[i].range;
		int ranges = battery_inits[i].ranges;

		if (val == -EINVAL)
			continue;

		ret = linear_range_get_selector_low_array(range, ranges, val,
							  &regval, &found);
		if (ret) {
			dev_err(bd->dev, "Unsupported value for %s\n",
				battery_inits[i].name);

			power_supply_put_battery_info(bd->charger, info);
			return -EINVAL;
		}
		if (!found) {
			dev_warn(bd->dev,
				 "Unsupported value for %s - using smaller\n",
				 battery_inits[i].name);
		}
		*(battery_inits[i].data) = regval;
	}

	power_supply_put_battery_info(bd->charger, info);

	for (i = 0; i < ARRAY_SIZE(props); i++) {
		ret = device_property_read_u32(bd->dev, props[i].prop,
					       &property);
		if (ret < 0) {
			dev_err(bd->dev, "failed to read %s", props[i].prop);

			return ret;
		}

		ret = linear_range_get_selector_low_array(props[i].range,
							  props[i].ranges,
							  property, &regval,
							  &found);
		if (ret) {
			dev_err(bd->dev, "Unsupported value for '%s'\n",
				props[i].prop);

			return -EINVAL;
		}

		if (!found) {
			dev_warn(bd->dev,
				 "Unsupported value for '%s' - using smaller\n",
				 props[i].prop);
		}

		*(props[i].data) = regval;
	}

	return 0;
}