Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

leds: lm3692x: Support LED sync configuration

The LM36922 has one output but can sync current to 2 LED
strings. The user may only use one sync so the other
syncs need to be disabled.

The LM36923 has 3 LED syncs.

Signed-off-by: Dan Murphy <dmurphy@ti.com>
Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>

authored by

Dan Murphy and committed by
Jacek Anaszewski
07abd432 581e3ca3

+122 -40
+122 -40
drivers/leds/leds-lm3692x.c
··· 15 15 #include <linux/slab.h> 16 16 #include <uapi/linux/uleds.h> 17 17 18 + #define LM36922_MODEL 0 19 + #define LM36923_MODEL 1 20 + 18 21 #define LM3692X_REV 0x0 19 22 #define LM3692X_RESET 0x1 20 23 #define LM3692X_EN 0x10 ··· 36 33 #define LM3692X_DEVICE_EN BIT(0) 37 34 #define LM3692X_LED1_EN BIT(1) 38 35 #define LM3692X_LED2_EN BIT(2) 36 + #define LM36923_LED3_EN BIT(3) 37 + #define LM3692X_ENABLE_MASK (LM3692X_DEVICE_EN | LM3692X_LED1_EN | \ 38 + LM3692X_LED2_EN | LM36923_LED3_EN) 39 39 40 40 /* Brightness Control Bits */ 41 41 #define LM3692X_BL_ADJ_POL BIT(0) ··· 104 98 * @enable_gpio - VDDIO/EN gpio to enable communication interface 105 99 * @regulator - LED supply regulator pointer 106 100 * @label - LED label 101 + * @led_enable - LED sync to be enabled 102 + * @model_id - Current device model ID enumerated 107 103 */ 108 104 struct lm3692x_led { 109 105 struct mutex lock; ··· 115 107 struct gpio_desc *enable_gpio; 116 108 struct regulator *regulator; 117 109 char label[LED_MAX_NAME_SIZE]; 110 + int led_enable; 111 + int model_id; 118 112 }; 119 113 120 114 static const struct reg_default lm3692x_reg_defs[] = { ··· 199 189 200 190 static int lm3692x_init(struct lm3692x_led *led) 201 191 { 192 + int enable_state; 202 193 int ret; 203 194 204 195 if (led->regulator) { ··· 226 215 227 216 /* 228 217 * For glitch free operation, the following data should 229 - * only be written while device enable bit is 0 218 + * only be written while LEDx enable bits are 0 and the device enable 219 + * bit is set to 1. 230 220 * per Section 7.5.14 of the data sheet 231 221 */ 222 + ret = regmap_write(led->regmap, LM3692X_EN, LM3692X_DEVICE_EN); 223 + if (ret) 224 + goto out; 225 + 226 + /* Set the brightness to 0 so when enabled the LEDs do not come 227 + * on with full brightness. 228 + */ 229 + ret = regmap_write(led->regmap, LM3692X_BRT_MSB, 0); 230 + if (ret) 231 + goto out; 232 + 233 + ret = regmap_write(led->regmap, LM3692X_BRT_LSB, 0); 234 + if (ret) 235 + goto out; 236 + 232 237 ret = regmap_write(led->regmap, LM3692X_PWM_CTRL, 233 238 LM3692X_PWM_FILTER_100 | LM3692X_PWM_SAMP_24MHZ); 234 239 if (ret) ··· 274 247 if (ret) 275 248 goto out; 276 249 250 + switch (led->led_enable) { 251 + case 0: 252 + default: 253 + if (led->model_id == LM36923_MODEL) 254 + enable_state = LM3692X_LED1_EN | LM3692X_LED2_EN | 255 + LM36923_LED3_EN; 256 + else 257 + enable_state = LM3692X_LED1_EN | LM3692X_LED2_EN; 258 + 259 + break; 260 + case 1: 261 + enable_state = LM3692X_LED1_EN; 262 + break; 263 + case 2: 264 + enable_state = LM3692X_LED2_EN; 265 + break; 266 + 267 + case 3: 268 + if (led->model_id == LM36923_MODEL) { 269 + enable_state = LM36923_LED3_EN; 270 + break; 271 + } 272 + 273 + ret = -EINVAL; 274 + dev_err(&led->client->dev, 275 + "LED3 sync not available on this device\n"); 276 + goto out; 277 + } 278 + 279 + ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_ENABLE_MASK, 280 + enable_state | LM3692X_DEVICE_EN); 281 + 277 282 return ret; 278 283 out: 279 284 dev_err(&led->client->dev, "Fail writing initialization values\n"); ··· 322 263 323 264 return ret; 324 265 } 325 - 326 - static int lm3692x_probe(struct i2c_client *client, 327 - const struct i2c_device_id *id) 266 + static int lm3692x_probe_dt(struct lm3692x_led *led) 328 267 { 329 268 struct fwnode_handle *child = NULL; 330 - struct lm3692x_led *led; 331 269 const char *name; 332 270 int ret; 333 271 334 - led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL); 335 - if (!led) 336 - return -ENOMEM; 337 - 338 - led->enable_gpio = devm_gpiod_get_optional(&client->dev, 272 + led->enable_gpio = devm_gpiod_get_optional(&led->client->dev, 339 273 "enable", GPIOD_OUT_LOW); 340 274 if (IS_ERR(led->enable_gpio)) { 341 275 ret = PTR_ERR(led->enable_gpio); 342 - dev_err(&client->dev, "Failed to get enable gpio: %d\n", ret); 343 - return ret; 344 - } 345 - 346 - led->regulator = devm_regulator_get(&client->dev, "vled"); 347 - if (IS_ERR(led->regulator)) 348 - led->regulator = NULL; 349 - 350 - led->client = client; 351 - led->led_dev.name = led->label; 352 - led->led_dev.brightness_set_blocking = lm3692x_brightness_set; 353 - 354 - mutex_init(&led->lock); 355 - 356 - i2c_set_clientdata(client, led); 357 - 358 - led->regmap = devm_regmap_init_i2c(client, &lm3692x_regmap_config); 359 - if (IS_ERR(led->regmap)) { 360 - ret = PTR_ERR(led->regmap); 361 - dev_err(&client->dev, "Failed to allocate register map: %d\n", 276 + dev_err(&led->client->dev, "Failed to get enable gpio: %d\n", 362 277 ret); 363 278 return ret; 364 279 } 365 280 366 - ret = lm3692x_init(led); 367 - if (ret) 368 - return ret; 281 + led->regulator = devm_regulator_get(&led->client->dev, "vled"); 282 + if (IS_ERR(led->regulator)) 283 + led->regulator = NULL; 369 284 370 285 child = device_get_next_child_node(&led->client->dev, child); 371 286 if (!child) { 372 287 dev_err(&led->client->dev, "No LED Child node\n"); 373 - return ret; 288 + return -ENODEV; 374 289 } 375 290 376 291 fwnode_property_read_string(child, "linux,default-trigger", ··· 358 325 snprintf(led->label, sizeof(led->label), 359 326 "%s:%s", led->client->name, name); 360 327 361 - led->led_dev.dev->of_node = to_of_node(child); 362 - 363 - ret = devm_led_classdev_register(&client->dev, &led->led_dev); 328 + ret = fwnode_property_read_u32(child, "reg", &led->led_enable); 364 329 if (ret) { 365 - dev_err(&client->dev, "led register err: %d\n", ret); 330 + dev_err(&led->client->dev, "reg DT property missing\n"); 366 331 return ret; 367 332 } 333 + 334 + led->led_dev.name = led->label; 335 + 336 + ret = devm_led_classdev_register(&led->client->dev, &led->led_dev); 337 + if (ret) { 338 + dev_err(&led->client->dev, "led register err: %d\n", ret); 339 + return ret; 340 + } 341 + 342 + led->led_dev.dev->of_node = to_of_node(child); 343 + 344 + return 0; 345 + } 346 + 347 + static int lm3692x_probe(struct i2c_client *client, 348 + const struct i2c_device_id *id) 349 + { 350 + struct lm3692x_led *led; 351 + int ret; 352 + 353 + led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL); 354 + if (!led) 355 + return -ENOMEM; 356 + 357 + mutex_init(&led->lock); 358 + led->client = client; 359 + led->led_dev.brightness_set_blocking = lm3692x_brightness_set; 360 + led->model_id = id->driver_data; 361 + i2c_set_clientdata(client, led); 362 + 363 + led->regmap = devm_regmap_init_i2c(client, &lm3692x_regmap_config); 364 + if (IS_ERR(led->regmap)) { 365 + ret = PTR_ERR(led->regmap); 366 + dev_err(&client->dev, "Failed to allocate register map: %d\n", 367 + ret); 368 + return ret; 369 + } 370 + 371 + ret = lm3692x_probe_dt(led); 372 + if (ret) 373 + return ret; 374 + 375 + ret = lm3692x_init(led); 376 + if (ret) 377 + return ret; 368 378 369 379 return 0; 370 380 } ··· 416 340 { 417 341 struct lm3692x_led *led = i2c_get_clientdata(client); 418 342 int ret; 343 + 344 + ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_DEVICE_EN, 0); 345 + if (ret) { 346 + dev_err(&led->client->dev, "Failed to disable regulator\n"); 347 + return ret; 348 + } 419 349 420 350 if (led->enable_gpio) 421 351 gpiod_direction_output(led->enable_gpio, 0); ··· 439 357 } 440 358 441 359 static const struct i2c_device_id lm3692x_id[] = { 442 - { "lm36922", 0 }, 443 - { "lm36923", 1 }, 360 + { "lm36922", LM36922_MODEL }, 361 + { "lm36923", LM36923_MODEL }, 444 362 { } 445 363 }; 446 364 MODULE_DEVICE_TABLE(i2c, lm3692x_id);