static int lm3697_probe_dt()

in leds-lm3697.c [203:300]


static int lm3697_probe_dt(struct lm3697 *priv)
{
	struct fwnode_handle *child = NULL;
	struct device *dev = priv->dev;
	struct lm3697_led *led;
	int ret = -EINVAL;
	int control_bank;
	size_t i = 0;
	int j;

	priv->enable_gpio = devm_gpiod_get_optional(dev, "enable",
						    GPIOD_OUT_LOW);
	if (IS_ERR(priv->enable_gpio))
		return dev_err_probe(dev, PTR_ERR(priv->enable_gpio),
					  "Failed to get enable GPIO\n");

	priv->regulator = devm_regulator_get(dev, "vled");
	if (IS_ERR(priv->regulator))
		priv->regulator = NULL;

	device_for_each_child_node(dev, child) {
		struct led_init_data init_data = {};

		ret = fwnode_property_read_u32(child, "reg", &control_bank);
		if (ret) {
			dev_err(dev, "reg property missing\n");
			goto child_out;
		}

		if (control_bank > LM3697_CONTROL_B) {
			dev_err(dev, "reg property is invalid\n");
			ret = -EINVAL;
			goto child_out;
		}

		led = &priv->leds[i];

		ret = ti_lmu_common_get_brt_res(dev, child, &led->lmu_data);
		if (ret)
			dev_warn(dev,
				 "brightness resolution property missing\n");

		led->control_bank = control_bank;
		led->lmu_data.regmap = priv->regmap;
		led->lmu_data.runtime_ramp_reg = LM3697_CTRL_A_RAMP +
						 control_bank;
		led->lmu_data.msb_brightness_reg = LM3697_CTRL_A_BRT_MSB +
						   led->control_bank * 2;
		led->lmu_data.lsb_brightness_reg = LM3697_CTRL_A_BRT_LSB +
						   led->control_bank * 2;

		led->num_leds = fwnode_property_count_u32(child, "led-sources");
		if (led->num_leds > LM3697_MAX_LED_STRINGS) {
			dev_err(dev, "Too many LED strings defined\n");
			continue;
		}

		ret = fwnode_property_read_u32_array(child, "led-sources",
						    led->hvled_strings,
						    led->num_leds);
		if (ret) {
			dev_err(dev, "led-sources property missing\n");
			goto child_out;
		}

		for (j = 0; j < led->num_leds; j++)
			priv->bank_cfg |=
				(led->control_bank << led->hvled_strings[j]);

		ret = ti_lmu_common_get_ramp_params(dev, child, &led->lmu_data);
		if (ret)
			dev_warn(dev, "runtime-ramp properties missing\n");

		init_data.fwnode = child;
		init_data.devicename = priv->client->name;
		/* for backwards compatibility if `label` is not present */
		init_data.default_label = ":";

		led->priv = priv;
		led->led_dev.max_brightness = led->lmu_data.max_brightness;
		led->led_dev.brightness_set_blocking = lm3697_brightness_set;

		ret = devm_led_classdev_register_ext(dev, &led->led_dev,
						     &init_data);
		if (ret) {
			dev_err(dev, "led register err: %d\n", ret);
			goto child_out;
		}

		i++;
	}

	return ret;

child_out:
	fwnode_handle_put(child);
	return ret;
}