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

leds: add aw2013 driver

This commit adds support for AWINIC AW2013 3-channel LED driver.
The chip supports 3 PWM channels and is controlled with I2C.

Signed-off-by: Nikita Travkin <nikitos.tr@gmail.com>
Signed-off-by: Pavel Machek <pavel@ucw.cz>

authored by

Nikita Travkin and committed by
Pavel Machek
59ea3c9f 9f6b72e4

+447
+10
drivers/leds/Kconfig
··· 103 103 controller. V4L2 flash API is provided as well if 104 104 CONFIG_V4L2_FLASH_API is enabled. 105 105 106 + config LEDS_AW2013 107 + tristate "LED support for Awinic AW2013" 108 + depends on LEDS_CLASS && I2C && OF 109 + help 110 + This option enables support for the AW2013 3-channel 111 + LED driver. 112 + 113 + To compile this driver as a module, choose M here: the module 114 + will be called leds-aw2013. 115 + 106 116 config LEDS_BCM6328 107 117 tristate "LED Support for Broadcom BCM6328" 108 118 depends on LEDS_CLASS
+1
drivers/leds/Makefile
··· 15 15 obj-$(CONFIG_LEDS_ARIEL) += leds-ariel.o 16 16 obj-$(CONFIG_LEDS_AS3645A) += leds-as3645a.o 17 17 obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o 18 + obj-$(CONFIG_LEDS_AW2013) += leds-aw2013.o 18 19 obj-$(CONFIG_LEDS_BCM6328) += leds-bcm6328.o 19 20 obj-$(CONFIG_LEDS_BCM6358) += leds-bcm6358.o 20 21 obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
+436
drivers/leds/leds-aw2013.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // Driver for Awinic AW2013 3-channel LED driver 3 + 4 + #include <linux/i2c.h> 5 + #include <linux/leds.h> 6 + #include <linux/module.h> 7 + #include <linux/regulator/consumer.h> 8 + #include <linux/mutex.h> 9 + #include <linux/of.h> 10 + #include <linux/regmap.h> 11 + 12 + #define AW2013_MAX_LEDS 3 13 + 14 + /* Reset and ID register */ 15 + #define AW2013_RSTR 0x00 16 + #define AW2013_RSTR_RESET 0x55 17 + #define AW2013_RSTR_CHIP_ID 0x33 18 + 19 + /* Global control register */ 20 + #define AW2013_GCR 0x01 21 + #define AW2013_GCR_ENABLE BIT(0) 22 + 23 + /* LED channel enable register */ 24 + #define AW2013_LCTR 0x30 25 + #define AW2013_LCTR_LE(x) BIT((x)) 26 + 27 + /* LED channel control registers */ 28 + #define AW2013_LCFG(x) (0x31 + (x)) 29 + #define AW2013_LCFG_IMAX_MASK (BIT(0) | BIT(1)) // Should be 0-3 30 + #define AW2013_LCFG_MD BIT(4) 31 + #define AW2013_LCFG_FI BIT(5) 32 + #define AW2013_LCFG_FO BIT(6) 33 + 34 + /* LED channel PWM registers */ 35 + #define AW2013_REG_PWM(x) (0x34 + (x)) 36 + 37 + /* LED channel timing registers */ 38 + #define AW2013_LEDT0(x) (0x37 + (x) * 3) 39 + #define AW2013_LEDT0_T1(x) ((x) << 4) // Should be 0-7 40 + #define AW2013_LEDT0_T2(x) (x) // Should be 0-5 41 + 42 + #define AW2013_LEDT1(x) (0x38 + (x) * 3) 43 + #define AW2013_LEDT1_T3(x) ((x) << 4) // Should be 0-7 44 + #define AW2013_LEDT1_T4(x) (x) // Should be 0-7 45 + 46 + #define AW2013_LEDT2(x) (0x39 + (x) * 3) 47 + #define AW2013_LEDT2_T0(x) ((x) << 4) // Should be 0-8 48 + #define AW2013_LEDT2_REPEAT(x) (x) // Should be 0-15 49 + 50 + #define AW2013_REG_MAX 0x77 51 + 52 + #define AW2013_TIME_STEP 130 /* ms */ 53 + 54 + struct aw2013; 55 + 56 + struct aw2013_led { 57 + struct aw2013 *chip; 58 + struct led_classdev cdev; 59 + u32 num; 60 + unsigned int imax; 61 + }; 62 + 63 + struct aw2013 { 64 + struct mutex mutex; /* held when writing to registers */ 65 + struct regulator *vcc_regulator; 66 + struct i2c_client *client; 67 + struct aw2013_led leds[AW2013_MAX_LEDS]; 68 + struct regmap *regmap; 69 + int num_leds; 70 + bool enabled; 71 + }; 72 + 73 + static int aw2013_chip_init(struct aw2013 *chip) 74 + { 75 + int i, ret; 76 + 77 + ret = regmap_write(chip->regmap, AW2013_GCR, AW2013_GCR_ENABLE); 78 + if (ret) { 79 + dev_err(&chip->client->dev, "Failed to enable the chip: %d\n", 80 + ret); 81 + return ret; 82 + } 83 + 84 + for (i = 0; i < chip->num_leds; i++) { 85 + ret = regmap_update_bits(chip->regmap, 86 + AW2013_LCFG(chip->leds[i].num), 87 + AW2013_LCFG_IMAX_MASK, 88 + chip->leds[i].imax); 89 + if (ret) { 90 + dev_err(&chip->client->dev, 91 + "Failed to set maximum current for led %d: %d\n", 92 + chip->leds[i].num, ret); 93 + return ret; 94 + } 95 + } 96 + 97 + return ret; 98 + } 99 + 100 + static void aw2013_chip_disable(struct aw2013 *chip) 101 + { 102 + int ret; 103 + 104 + if (!chip->enabled) 105 + return; 106 + 107 + regmap_write(chip->regmap, AW2013_GCR, 0); 108 + 109 + ret = regulator_disable(chip->vcc_regulator); 110 + if (ret) { 111 + dev_err(&chip->client->dev, 112 + "Failed to disable regulator: %d\n", ret); 113 + return; 114 + } 115 + 116 + chip->enabled = false; 117 + } 118 + 119 + static int aw2013_chip_enable(struct aw2013 *chip) 120 + { 121 + int ret; 122 + 123 + if (chip->enabled) 124 + return 0; 125 + 126 + ret = regulator_enable(chip->vcc_regulator); 127 + if (ret) { 128 + dev_err(&chip->client->dev, 129 + "Failed to enable regulator: %d\n", ret); 130 + return ret; 131 + } 132 + chip->enabled = true; 133 + 134 + ret = aw2013_chip_init(chip); 135 + if (ret) 136 + aw2013_chip_disable(chip); 137 + 138 + return ret; 139 + } 140 + 141 + static bool aw2013_chip_in_use(struct aw2013 *chip) 142 + { 143 + int i; 144 + 145 + for (i = 0; i < chip->num_leds; i++) 146 + if (chip->leds[i].cdev.brightness) 147 + return true; 148 + 149 + return false; 150 + } 151 + 152 + static int aw2013_brightness_set(struct led_classdev *cdev, 153 + enum led_brightness brightness) 154 + { 155 + struct aw2013_led *led = container_of(cdev, struct aw2013_led, cdev); 156 + int ret, num; 157 + 158 + mutex_lock(&led->chip->mutex); 159 + 160 + if (aw2013_chip_in_use(led->chip)) { 161 + ret = aw2013_chip_enable(led->chip); 162 + if (ret) 163 + goto error; 164 + } 165 + 166 + num = led->num; 167 + 168 + ret = regmap_write(led->chip->regmap, AW2013_REG_PWM(num), brightness); 169 + if (ret) 170 + goto error; 171 + 172 + if (brightness) { 173 + ret = regmap_update_bits(led->chip->regmap, AW2013_LCTR, 174 + AW2013_LCTR_LE(num), 0xFF); 175 + } else { 176 + ret = regmap_update_bits(led->chip->regmap, AW2013_LCTR, 177 + AW2013_LCTR_LE(num), 0); 178 + if (ret) 179 + goto error; 180 + ret = regmap_update_bits(led->chip->regmap, AW2013_LCFG(num), 181 + AW2013_LCFG_MD, 0); 182 + } 183 + if (ret) 184 + goto error; 185 + 186 + if (!aw2013_chip_in_use(led->chip)) 187 + aw2013_chip_disable(led->chip); 188 + 189 + error: 190 + mutex_unlock(&led->chip->mutex); 191 + 192 + return ret; 193 + } 194 + 195 + static int aw2013_blink_set(struct led_classdev *cdev, 196 + unsigned long *delay_on, unsigned long *delay_off) 197 + { 198 + struct aw2013_led *led = container_of(cdev, struct aw2013_led, cdev); 199 + int ret, num = led->num; 200 + unsigned long off = 0, on = 0; 201 + 202 + /* If no blink specified, default to 1 Hz. */ 203 + if (!*delay_off && !*delay_on) { 204 + *delay_off = 500; 205 + *delay_on = 500; 206 + } 207 + 208 + if (!led->cdev.brightness) { 209 + led->cdev.brightness = LED_FULL; 210 + ret = aw2013_brightness_set(&led->cdev, led->cdev.brightness); 211 + if (ret) 212 + return ret; 213 + } 214 + 215 + /* Never on - just set to off */ 216 + if (!*delay_on) { 217 + led->cdev.brightness = LED_OFF; 218 + return aw2013_brightness_set(&led->cdev, LED_OFF); 219 + } 220 + 221 + mutex_lock(&led->chip->mutex); 222 + 223 + /* Never off - brightness is already set, disable blinking */ 224 + if (!*delay_off) { 225 + ret = regmap_update_bits(led->chip->regmap, AW2013_LCFG(num), 226 + AW2013_LCFG_MD, 0); 227 + goto out; 228 + } 229 + 230 + /* Convert into values the HW will understand. */ 231 + off = min(5, ilog2((*delay_off - 1) / AW2013_TIME_STEP) + 1); 232 + on = min(7, ilog2((*delay_on - 1) / AW2013_TIME_STEP) + 1); 233 + 234 + *delay_off = BIT(off) * AW2013_TIME_STEP; 235 + *delay_on = BIT(on) * AW2013_TIME_STEP; 236 + 237 + /* Set timings */ 238 + ret = regmap_write(led->chip->regmap, 239 + AW2013_LEDT0(num), AW2013_LEDT0_T2(on)); 240 + if (ret) 241 + goto out; 242 + ret = regmap_write(led->chip->regmap, 243 + AW2013_LEDT1(num), AW2013_LEDT1_T4(off)); 244 + if (ret) 245 + goto out; 246 + 247 + /* Finally, enable the LED */ 248 + ret = regmap_update_bits(led->chip->regmap, AW2013_LCFG(num), 249 + AW2013_LCFG_MD, 0xFF); 250 + if (ret) 251 + goto out; 252 + 253 + ret = regmap_update_bits(led->chip->regmap, AW2013_LCTR, 254 + AW2013_LCTR_LE(num), 0xFF); 255 + 256 + out: 257 + mutex_unlock(&led->chip->mutex); 258 + 259 + return ret; 260 + } 261 + 262 + static int aw2013_probe_dt(struct aw2013 *chip) 263 + { 264 + struct device_node *np = chip->client->dev.of_node, *child; 265 + int count, ret = 0, i = 0; 266 + struct aw2013_led *led; 267 + 268 + count = of_get_child_count(np); 269 + if (!count || count > AW2013_MAX_LEDS) 270 + return -EINVAL; 271 + 272 + regmap_write(chip->regmap, AW2013_RSTR, AW2013_RSTR_RESET); 273 + 274 + for_each_available_child_of_node(np, child) { 275 + struct led_init_data init_data = {}; 276 + u32 source; 277 + u32 imax; 278 + 279 + ret = of_property_read_u32(child, "reg", &source); 280 + if (ret != 0 || source >= AW2013_MAX_LEDS) { 281 + dev_err(&chip->client->dev, 282 + "Couldn't read LED address: %d\n", ret); 283 + count--; 284 + continue; 285 + } 286 + 287 + led = &chip->leds[i]; 288 + led->num = source; 289 + led->chip = chip; 290 + init_data.fwnode = of_fwnode_handle(child); 291 + 292 + if (!of_property_read_u32(child, "led-max-microamp", &imax)) { 293 + led->imax = min_t(u32, imax / 5000, 3); 294 + } else { 295 + led->imax = 1; // 5mA 296 + dev_info(&chip->client->dev, 297 + "DT property led-max-microamp is missing\n"); 298 + } 299 + 300 + of_property_read_string(child, "linux,default-trigger", 301 + &led->cdev.default_trigger); 302 + 303 + led->cdev.brightness_set_blocking = aw2013_brightness_set; 304 + led->cdev.blink_set = aw2013_blink_set; 305 + 306 + ret = devm_led_classdev_register_ext(&chip->client->dev, 307 + &led->cdev, &init_data); 308 + if (ret < 0) 309 + return ret; 310 + 311 + i++; 312 + } 313 + 314 + if (!count) 315 + return -EINVAL; 316 + 317 + chip->num_leds = i; 318 + 319 + return 0; 320 + } 321 + 322 + static const struct regmap_config aw2013_regmap_config = { 323 + .reg_bits = 8, 324 + .val_bits = 8, 325 + .max_register = AW2013_REG_MAX, 326 + }; 327 + 328 + static int aw2013_probe(struct i2c_client *client) 329 + { 330 + struct aw2013 *chip; 331 + int ret; 332 + unsigned int chipid; 333 + 334 + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 335 + if (!chip) 336 + return -ENOMEM; 337 + 338 + mutex_init(&chip->mutex); 339 + mutex_lock(&chip->mutex); 340 + 341 + chip->client = client; 342 + i2c_set_clientdata(client, chip); 343 + 344 + chip->regmap = devm_regmap_init_i2c(client, &aw2013_regmap_config); 345 + if (IS_ERR(chip->regmap)) { 346 + ret = PTR_ERR(chip->regmap); 347 + dev_err(&client->dev, "Failed to allocate register map: %d\n", 348 + ret); 349 + goto error; 350 + } 351 + 352 + chip->vcc_regulator = devm_regulator_get(&client->dev, "vcc"); 353 + ret = PTR_ERR_OR_ZERO(chip->vcc_regulator); 354 + if (ret) { 355 + if (ret != -EPROBE_DEFER) 356 + dev_err(&client->dev, 357 + "Failed to request regulator: %d\n", ret); 358 + goto error; 359 + } 360 + 361 + ret = regulator_enable(chip->vcc_regulator); 362 + if (ret) { 363 + dev_err(&client->dev, 364 + "Failed to enable regulator: %d\n", ret); 365 + goto error; 366 + } 367 + 368 + ret = regmap_read(chip->regmap, AW2013_RSTR, &chipid); 369 + if (ret) { 370 + dev_err(&client->dev, "Failed to read chip ID: %d\n", 371 + ret); 372 + goto error_reg; 373 + } 374 + 375 + if (chipid != AW2013_RSTR_CHIP_ID) { 376 + dev_err(&client->dev, "Chip reported wrong ID: %x\n", 377 + chipid); 378 + ret = -ENODEV; 379 + goto error_reg; 380 + } 381 + 382 + ret = aw2013_probe_dt(chip); 383 + if (ret < 0) 384 + goto error_reg; 385 + 386 + ret = regulator_disable(chip->vcc_regulator); 387 + if (ret) { 388 + dev_err(&client->dev, 389 + "Failed to disable regulator: %d\n", ret); 390 + goto error; 391 + } 392 + 393 + mutex_unlock(&chip->mutex); 394 + 395 + return 0; 396 + 397 + error_reg: 398 + regulator_disable(chip->vcc_regulator); 399 + 400 + error: 401 + mutex_destroy(&chip->mutex); 402 + return ret; 403 + } 404 + 405 + static int aw2013_remove(struct i2c_client *client) 406 + { 407 + struct aw2013 *chip = i2c_get_clientdata(client); 408 + 409 + aw2013_chip_disable(chip); 410 + 411 + mutex_destroy(&chip->mutex); 412 + 413 + return 0; 414 + } 415 + 416 + static const struct of_device_id aw2013_match_table[] = { 417 + { .compatible = "awinic,aw2013", }, 418 + { /* sentinel */ }, 419 + }; 420 + 421 + MODULE_DEVICE_TABLE(of, aw2013_match_table); 422 + 423 + static struct i2c_driver aw2013_driver = { 424 + .driver = { 425 + .name = "leds-aw2013", 426 + .of_match_table = of_match_ptr(aw2013_match_table), 427 + }, 428 + .probe_new = aw2013_probe, 429 + .remove = aw2013_remove, 430 + }; 431 + 432 + module_i2c_driver(aw2013_driver); 433 + 434 + MODULE_AUTHOR("Nikita Travkin <nikitos.tr@gmail.com>"); 435 + MODULE_DESCRIPTION("AW2013 LED driver"); 436 + MODULE_LICENSE("GPL v2");