| .. | .. |
|---|
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
|---|
| 2 | 2 | // Flash and torch driver for Texas Instruments LM3601X LED |
|---|
| 3 | 3 | // Flash driver chip family |
|---|
| 4 | | -// Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ |
|---|
| 4 | +// Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/ |
|---|
| 5 | 5 | |
|---|
| 6 | 6 | #include <linux/delay.h> |
|---|
| 7 | 7 | #include <linux/i2c.h> |
|---|
| .. | .. |
|---|
| 10 | 10 | #include <linux/module.h> |
|---|
| 11 | 11 | #include <linux/regmap.h> |
|---|
| 12 | 12 | #include <linux/slab.h> |
|---|
| 13 | | -#include <uapi/linux/uleds.h> |
|---|
| 14 | 13 | |
|---|
| 15 | 14 | #define LM3601X_LED_IR 0x0 |
|---|
| 16 | 15 | #define LM3601X_LED_TORCH 0x1 |
|---|
| .. | .. |
|---|
| 89 | 88 | struct i2c_client *client; |
|---|
| 90 | 89 | struct regmap *regmap; |
|---|
| 91 | 90 | struct mutex lock; |
|---|
| 92 | | - |
|---|
| 93 | | - char led_name[LED_MAX_NAME_SIZE]; |
|---|
| 94 | 91 | |
|---|
| 95 | 92 | unsigned int flash_timeout; |
|---|
| 96 | 93 | unsigned int last_flag; |
|---|
| .. | .. |
|---|
| 322 | 319 | .fault_get = lm3601x_flash_fault_get, |
|---|
| 323 | 320 | }; |
|---|
| 324 | 321 | |
|---|
| 325 | | -static int lm3601x_register_leds(struct lm3601x_led *led) |
|---|
| 322 | +static int lm3601x_register_leds(struct lm3601x_led *led, |
|---|
| 323 | + struct fwnode_handle *fwnode) |
|---|
| 326 | 324 | { |
|---|
| 327 | 325 | struct led_classdev *led_cdev; |
|---|
| 328 | 326 | struct led_flash_setting *setting; |
|---|
| 327 | + struct led_init_data init_data = {}; |
|---|
| 329 | 328 | |
|---|
| 330 | 329 | led->fled_cdev.ops = &flash_ops; |
|---|
| 331 | 330 | |
|---|
| .. | .. |
|---|
| 342 | 341 | setting->val = led->flash_current_max; |
|---|
| 343 | 342 | |
|---|
| 344 | 343 | led_cdev = &led->fled_cdev.led_cdev; |
|---|
| 345 | | - led_cdev->name = led->led_name; |
|---|
| 346 | 344 | led_cdev->brightness_set_blocking = lm3601x_brightness_set; |
|---|
| 347 | 345 | led_cdev->max_brightness = DIV_ROUND_UP(led->torch_current_max, |
|---|
| 348 | 346 | LM3601X_TORCH_REG_DIV); |
|---|
| 349 | 347 | led_cdev->flags |= LED_DEV_CAP_FLASH; |
|---|
| 350 | 348 | |
|---|
| 351 | | - return led_classdev_flash_register(&led->client->dev, &led->fled_cdev); |
|---|
| 349 | + init_data.fwnode = fwnode; |
|---|
| 350 | + init_data.devicename = led->client->name; |
|---|
| 351 | + init_data.default_label = (led->led_mode == LM3601X_LED_TORCH) ? |
|---|
| 352 | + "torch" : "infrared"; |
|---|
| 353 | + return devm_led_classdev_flash_register_ext(&led->client->dev, |
|---|
| 354 | + &led->fled_cdev, &init_data); |
|---|
| 352 | 355 | } |
|---|
| 353 | 356 | |
|---|
| 354 | | -static int lm3601x_parse_node(struct lm3601x_led *led) |
|---|
| 357 | +static int lm3601x_parse_node(struct lm3601x_led *led, |
|---|
| 358 | + struct fwnode_handle **fwnode) |
|---|
| 355 | 359 | { |
|---|
| 356 | 360 | struct fwnode_handle *child = NULL; |
|---|
| 357 | 361 | int ret = -ENODEV; |
|---|
| 358 | | - const char *name; |
|---|
| 359 | 362 | |
|---|
| 360 | 363 | child = device_get_next_child_node(&led->client->dev, child); |
|---|
| 361 | 364 | if (!child) { |
|---|
| .. | .. |
|---|
| 375 | 378 | ret = -EINVAL; |
|---|
| 376 | 379 | goto out_err; |
|---|
| 377 | 380 | } |
|---|
| 378 | | - |
|---|
| 379 | | - ret = fwnode_property_read_string(child, "label", &name); |
|---|
| 380 | | - if (ret) { |
|---|
| 381 | | - if (led->led_mode == LM3601X_LED_TORCH) |
|---|
| 382 | | - name = "torch"; |
|---|
| 383 | | - else |
|---|
| 384 | | - name = "infrared"; |
|---|
| 385 | | - } |
|---|
| 386 | | - |
|---|
| 387 | | - snprintf(led->led_name, sizeof(led->led_name), |
|---|
| 388 | | - "%s:%s", led->client->name, name); |
|---|
| 389 | 381 | |
|---|
| 390 | 382 | ret = fwnode_property_read_u32(child, "led-max-microamp", |
|---|
| 391 | 383 | &led->torch_current_max); |
|---|
| .. | .. |
|---|
| 411 | 403 | goto out_err; |
|---|
| 412 | 404 | } |
|---|
| 413 | 405 | |
|---|
| 406 | + *fwnode = child; |
|---|
| 407 | + |
|---|
| 414 | 408 | out_err: |
|---|
| 415 | 409 | fwnode_handle_put(child); |
|---|
| 416 | 410 | return ret; |
|---|
| .. | .. |
|---|
| 419 | 413 | static int lm3601x_probe(struct i2c_client *client) |
|---|
| 420 | 414 | { |
|---|
| 421 | 415 | struct lm3601x_led *led; |
|---|
| 416 | + struct fwnode_handle *fwnode; |
|---|
| 422 | 417 | int ret; |
|---|
| 423 | 418 | |
|---|
| 424 | 419 | led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 428 | 423 | led->client = client; |
|---|
| 429 | 424 | i2c_set_clientdata(client, led); |
|---|
| 430 | 425 | |
|---|
| 431 | | - ret = lm3601x_parse_node(led); |
|---|
| 426 | + ret = lm3601x_parse_node(led, &fwnode); |
|---|
| 432 | 427 | if (ret) |
|---|
| 433 | 428 | return -ENODEV; |
|---|
| 434 | 429 | |
|---|
| .. | .. |
|---|
| 442 | 437 | |
|---|
| 443 | 438 | mutex_init(&led->lock); |
|---|
| 444 | 439 | |
|---|
| 445 | | - return lm3601x_register_leds(led); |
|---|
| 440 | + return lm3601x_register_leds(led, fwnode); |
|---|
| 446 | 441 | } |
|---|
| 447 | 442 | |
|---|
| 448 | 443 | static int lm3601x_remove(struct i2c_client *client) |
|---|
| 449 | 444 | { |
|---|
| 450 | 445 | struct lm3601x_led *led = i2c_get_clientdata(client); |
|---|
| 451 | | - |
|---|
| 452 | | - led_classdev_flash_unregister(&led->fled_cdev); |
|---|
| 453 | | - mutex_destroy(&led->lock); |
|---|
| 454 | 446 | |
|---|
| 455 | 447 | return regmap_update_bits(led->regmap, LM3601X_ENABLE_REG, |
|---|
| 456 | 448 | LM3601X_ENABLE_MASK, |
|---|