int qpnp_wled_init(struct qpnp_wled_config_data *config)
{
	int rc;
	struct qpnp_wled *wled;

	wled = malloc(sizeof(struct qpnp_wled));
	if (!wled)
		return ERR_NO_MEMORY;

	memset(wled, 0, sizeof(struct qpnp_wled));

	rc = qpnp_wled_setup(wled, config);
	if (rc) {
		dprintf(CRITICAL, "Setting WLED parameters failed\n");
		return rc;
	}

	rc = qpnp_wled_config(wled);
	if (rc) {
		dprintf(CRITICAL, "wled config failed\n");
		return rc;
	}

	gwled = wled;

	return rc;
}
Beispiel #2
0
static int qpnp_wled_probe(struct spmi_device *spmi)
{
	struct qpnp_wled *wled;
	struct resource *wled_resource;
	int rc, i;

	wled = devm_kzalloc(&spmi->dev, sizeof(*wled), GFP_KERNEL);
	if (!wled)
		return -ENOMEM;

	wled->spmi = spmi;

	wled_resource = spmi_get_resource_byname(spmi, NULL, IORESOURCE_MEM,
					QPNP_WLED_SINK_BASE);
	if (!wled_resource) {
		dev_err(&spmi->dev, "Unable to get wled sink base address\n");
		return -EINVAL;
	}

	wled->sink_base = wled_resource->start;

	wled_resource = spmi_get_resource_byname(spmi, NULL, IORESOURCE_MEM,
					QPNP_WLED_CTRL_BASE);
	if (!wled_resource) {
		dev_err(&spmi->dev, "Unable to get wled ctrl base address\n");
		return -EINVAL;
	}

	wled->ctrl_base = wled_resource->start;

	wled_resource = spmi_get_resource_byname(spmi, NULL, IORESOURCE_MEM,
					QPNP_WLED_IBB_BASE);
	if (!wled_resource) {
		dev_err(&spmi->dev, "Unable to get IBB base address\n");
		return -EINVAL;
	}

	wled->ibb_base = wled_resource->start;

	wled_resource = spmi_get_resource_byname(spmi, NULL, IORESOURCE_MEM,
					QPNP_WLED_LAB_BASE);
	if (!wled_resource) {
		dev_err(&spmi->dev, "Unable to get LAB base address\n");
		return -EINVAL;
	}

	wled->lab_base = wled_resource->start;

	dev_set_drvdata(&spmi->dev, wled);

	rc = qpnp_wled_parse_dt(wled);
	if (rc) {
		dev_err(&spmi->dev, "DT parsing failed\n");
		return rc;
	}

	rc = qpnp_wled_config(wled);
	if (rc) {
		dev_err(&spmi->dev, "wled config failed\n");
		return rc;
	}

	mutex_init(&wled->lock);
	INIT_WORK(&wled->work, qpnp_wled_work);
	wled->ramp_ms = QPNP_WLED_RAMP_DLY_MS;
	wled->ramp_step = 1;

	wled->cdev.brightness_set = qpnp_wled_set;
	wled->cdev.brightness_get = qpnp_wled_get;

	if (wled->en_9b_dim_res)
		wled->cdev.max_brightness = WLED_MAX_LEVEL_511;
	else
		wled->cdev.max_brightness = WLED_MAX_LEVEL_4095;

	rc = led_classdev_register(&spmi->dev, &wled->cdev);
	if (rc) {
		dev_err(&spmi->dev, "wled registration failed(%d)\n", rc);
		goto wled_register_fail;
	}

	for (i = 0; i < ARRAY_SIZE(qpnp_wled_attrs); i++) {
		rc = sysfs_create_file(&wled->cdev.dev->kobj,
				&qpnp_wled_attrs[i].attr);
		if (rc < 0) {
			dev_err(&spmi->dev, "sysfs creation failed\n");
			goto sysfs_fail;
		}
	}

	gwled = wled;

	return 0;

sysfs_fail:
	for (i--; i >= 0; i--)
		sysfs_remove_file(&wled->cdev.dev->kobj,
				&qpnp_wled_attrs[i].attr);
	led_classdev_unregister(&wled->cdev);
wled_register_fail:
	cancel_work_sync(&wled->work);
	mutex_destroy(&wled->lock);
	return rc;
}