static int lm3532_parse_node()

in leds-lm3532.c [545:664]


static int lm3532_parse_node(struct lm3532_data *priv)
{
	struct fwnode_handle *child = NULL;
	struct lm3532_led *led;
	int control_bank;
	u32 ramp_time;
	size_t i = 0;
	int ret;

	priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
						   "enable", GPIOD_OUT_LOW);
	if (IS_ERR(priv->enable_gpio))
		priv->enable_gpio = NULL;

	priv->regulator = devm_regulator_get(&priv->client->dev, "vin");
	if (IS_ERR(priv->regulator))
		priv->regulator = NULL;

	ret = device_property_read_u32(&priv->client->dev, "ramp-up-us",
				       &ramp_time);
	if (ret)
		dev_info(&priv->client->dev, "ramp-up-ms property missing\n");
	else
		priv->runtime_ramp_up = lm3532_get_ramp_index(ramp_time);

	ret = device_property_read_u32(&priv->client->dev, "ramp-down-us",
				       &ramp_time);
	if (ret)
		dev_info(&priv->client->dev, "ramp-down-ms property missing\n");
	else
		priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time);

	device_for_each_child_node(priv->dev, child) {
		struct led_init_data idata = {
			.fwnode = child,
			.default_label = ":",
			.devicename = priv->client->name,
		};

		led = &priv->leds[i];

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

		if (control_bank > LM3532_CONTROL_C) {
			dev_err(&priv->client->dev, "Control bank invalid\n");
			continue;
		}

		led->control_bank = control_bank;

		ret = fwnode_property_read_u32(child, "ti,led-mode",
					       &led->mode);
		if (ret) {
			dev_err(&priv->client->dev, "ti,led-mode property missing\n");
			goto child_out;
		}

		if (fwnode_property_present(child, "led-max-microamp") &&
		    fwnode_property_read_u32(child, "led-max-microamp",
					     &led->full_scale_current))
			dev_err(&priv->client->dev,
				"Failed getting led-max-microamp\n");
		else
			led->full_scale_current = min(led->full_scale_current,
						      LM3532_FS_CURR_MAX);

		if (led->mode == LM3532_BL_MODE_ALS) {
			led->mode = LM3532_ALS_CTRL;
			ret = lm3532_parse_als(priv);
			if (ret)
				dev_err(&priv->client->dev, "Failed to parse als\n");
			else
				lm3532_als_configure(priv, led);
		} else {
			led->mode = LM3532_I2C_CTRL;
		}

		led->num_leds = fwnode_property_count_u32(child, "led-sources");
		if (led->num_leds > LM3532_MAX_LED_STRINGS) {
			dev_err(&priv->client->dev, "Too many LED string defined\n");
			continue;
		}

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

		led->priv = priv;
		led->led_dev.brightness_set_blocking = lm3532_brightness_set;

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

		ret = lm3532_init_registers(led);
		if (ret) {
			dev_err(&priv->client->dev, "register init err: %d\n",
				ret);
			goto child_out;
		}

		i++;
	}
	return 0;

child_out:
	fwnode_handle_put(child);
	return ret;
}