static int rt8515_probe()

in flash/leds-rt8515.c [276:368]


static int rt8515_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct fwnode_handle *child;
	struct rt8515 *rt;
	struct led_classdev *led;
	struct led_classdev_flash *fled;
	struct led_init_data init_data = {};
	struct v4l2_flash_config v4l2_sd_cfg = {};
	int ret;

	rt = devm_kzalloc(dev, sizeof(*rt), GFP_KERNEL);
	if (!rt)
		return -ENOMEM;

	rt->dev = dev;
	fled = &rt->fled;
	led = &fled->led_cdev;

	/* ENF - Enable Flash line */
	rt->enable_flash = devm_gpiod_get(dev, "enf", GPIOD_OUT_LOW);
	if (IS_ERR(rt->enable_flash))
		return dev_err_probe(dev, PTR_ERR(rt->enable_flash),
				     "cannot get ENF (enable flash) GPIO\n");

	/* ENT - Enable Torch line */
	rt->enable_torch = devm_gpiod_get(dev, "ent", GPIOD_OUT_LOW);
	if (IS_ERR(rt->enable_torch))
		return dev_err_probe(dev, PTR_ERR(rt->enable_torch),
				     "cannot get ENT (enable torch) GPIO\n");

	child = fwnode_get_next_available_child_node(dev->fwnode, NULL);
	if (!child) {
		dev_err(dev,
			"No fwnode child node found for connected LED.\n");
		return -EINVAL;
	}
	init_data.fwnode = child;

	rt8515_determine_max_intensity(rt, child, "richtek,rfs-ohms",
				       "flash-max-microamp",
				       RT8515_FLASH_MAX,
				       &rt->flash_max_intensity);
	rt8515_determine_max_intensity(rt, child, "richtek,rts-ohms",
				       "led-max-microamp",
				       RT8515_TORCH_MAX,
				       &rt->torch_max_intensity);

	ret = fwnode_property_read_u32(child, "flash-max-timeout-us",
				       &rt->max_timeout);
	if (ret) {
		rt->max_timeout = RT8515_MAX_TIMEOUT_US;
		dev_warn(dev,
			 "flash-max-timeout-us property missing\n");
	}
	timer_setup(&rt->powerdown_timer, rt8515_powerdown_timer, 0);
	rt8515_init_flash_timeout(rt);

	fled->ops = &rt8515_flash_ops;

	led->max_brightness = rt->torch_max_intensity;
	led->brightness_set_blocking = rt8515_led_brightness_set;
	led->flags |= LED_CORE_SUSPENDRESUME | LED_DEV_CAP_FLASH;

	mutex_init(&rt->lock);

	platform_set_drvdata(pdev, rt);

	ret = devm_led_classdev_flash_register_ext(dev, fled, &init_data);
	if (ret) {
		fwnode_handle_put(child);
		mutex_destroy(&rt->lock);
		dev_err(dev, "can't register LED %s\n", led->name);
		return ret;
	}

	rt8515_init_v4l2_flash_config(rt, &v4l2_sd_cfg);

	/* Create a V4L2 Flash device if V4L2 flash is enabled */
	rt->v4l2_flash = v4l2_flash_init(dev, child, fled, NULL, &v4l2_sd_cfg);
	if (IS_ERR(rt->v4l2_flash)) {
		ret = PTR_ERR(rt->v4l2_flash);
		dev_err(dev, "failed to register V4L2 flash device (%d)\n",
			ret);
		/*
		 * Continue without the V4L2 flash
		 * (we still have the classdev)
		 */
	}

	fwnode_handle_put(child);
	return 0;
}