static int pca963x_register_leds()

in leds-pca963x.c [285:363]


static int pca963x_register_leds(struct i2c_client *client,
				 struct pca963x *chip)
{
	struct pca963x_chipdef *chipdef = chip->chipdef;
	struct pca963x_led *led = chip->leds;
	struct device *dev = &client->dev;
	struct fwnode_handle *child;
	bool hw_blink;
	s32 mode2;
	u32 reg;
	int ret;

	if (device_property_read_u32(dev, "nxp,period-scale",
				     &chipdef->scaling))
		chipdef->scaling = 1000;

	hw_blink = device_property_read_bool(dev, "nxp,hw-blink");

	mode2 = i2c_smbus_read_byte_data(client, PCA963X_MODE2);
	if (mode2 < 0)
		return mode2;

	/* default to open-drain unless totem pole (push-pull) is specified */
	if (device_property_read_bool(dev, "nxp,totem-pole"))
		mode2 |= PCA963X_MODE2_OUTDRV;
	else
		mode2 &= ~PCA963X_MODE2_OUTDRV;

	/* default to non-inverted output, unless inverted is specified */
	if (device_property_read_bool(dev, "nxp,inverted-out"))
		mode2 |= PCA963X_MODE2_INVRT;
	else
		mode2 &= ~PCA963X_MODE2_INVRT;

	ret = i2c_smbus_write_byte_data(client, PCA963X_MODE2, mode2);
	if (ret < 0)
		return ret;

	device_for_each_child_node(dev, child) {
		struct led_init_data init_data = {};
		char default_label[32];

		ret = fwnode_property_read_u32(child, "reg", &reg);
		if (ret || reg >= chipdef->n_leds) {
			dev_err(dev, "Invalid 'reg' property for node %pfw\n",
				child);
			ret = -EINVAL;
			goto err;
		}

		led->led_num = reg;
		led->chip = chip;
		led->led_cdev.brightness_set_blocking = pca963x_led_set;
		if (hw_blink)
			led->led_cdev.blink_set = pca963x_blink_set;

		init_data.fwnode = child;
		/* for backwards compatibility */
		init_data.devicename = "pca963x";
		snprintf(default_label, sizeof(default_label), "%d:%.2x:%u",
			 client->adapter->nr, client->addr, reg);
		init_data.default_label = default_label;

		ret = devm_led_classdev_register_ext(dev, &led->led_cdev,
						     &init_data);
		if (ret) {
			dev_err(dev, "Failed to register LED for node %pfw\n",
				child);
			goto err;
		}

		++led;
	}

	return 0;
err:
	fwnode_handle_put(child);
	return ret;
}