1 // SPDX-License-Identifier: GPL-2.0+ 2 // 3 // Driver for Panasonic AN30259A 3-channel LED driver 4 // 5 // Copyright (c) 2018 Simon Shields <simon@lineageos.org> 6 // 7 // Datasheet: 8 // https://www.alliedelec.com/m/d/a9d2b3ee87c2d1a535a41dd747b1c247.pdf 9 10 #include <linux/i2c.h> 11 #include <linux/leds.h> 12 #include <linux/module.h> 13 #include <linux/mutex.h> 14 #include <linux/of.h> 15 #include <linux/regmap.h> 16 #include <uapi/linux/uleds.h> 17 18 #define AN30259A_MAX_LEDS 3 19 20 #define AN30259A_REG_SRESET 0x00 21 #define AN30259A_LED_SRESET BIT(0) 22 23 /* LED power registers */ 24 #define AN30259A_REG_LED_ON 0x01 25 #define AN30259A_LED_EN(x) BIT((x) - 1) 26 #define AN30259A_LED_SLOPE(x) BIT(((x) - 1) + 4) 27 28 #define AN30259A_REG_LEDCC(x) (0x03 + ((x) - 1)) 29 30 /* slope control registers */ 31 #define AN30259A_REG_SLOPE(x) (0x06 + ((x) - 1)) 32 #define AN30259A_LED_SLOPETIME1(x) (x) 33 #define AN30259A_LED_SLOPETIME2(x) ((x) << 4) 34 35 #define AN30259A_REG_LEDCNT1(x) (0x09 + (4 * ((x) - 1))) 36 #define AN30259A_LED_DUTYMAX(x) ((x) << 4) 37 #define AN30259A_LED_DUTYMID(x) (x) 38 39 #define AN30259A_REG_LEDCNT2(x) (0x0A + (4 * ((x) - 1))) 40 #define AN30259A_LED_DELAY(x) ((x) << 4) 41 #define AN30259A_LED_DUTYMIN(x) (x) 42 43 /* detention time control (length of each slope step) */ 44 #define AN30259A_REG_LEDCNT3(x) (0x0B + (4 * ((x) - 1))) 45 #define AN30259A_LED_DT1(x) (x) 46 #define AN30259A_LED_DT2(x) ((x) << 4) 47 48 #define AN30259A_REG_LEDCNT4(x) (0x0C + (4 * ((x) - 1))) 49 #define AN30259A_LED_DT3(x) (x) 50 #define AN30259A_LED_DT4(x) ((x) << 4) 51 52 #define AN30259A_REG_MAX 0x14 53 54 #define AN30259A_BLINK_MAX_TIME 7500 /* ms */ 55 #define AN30259A_SLOPE_RESOLUTION 500 /* ms */ 56 57 #define STATE_OFF 0 58 #define STATE_KEEP 1 59 #define STATE_ON 2 60 61 struct an30259a; 62 63 struct an30259a_led { 64 struct an30259a *chip; 65 struct led_classdev cdev; 66 u32 num; 67 u32 default_state; 68 bool sloping; 69 char label[LED_MAX_NAME_SIZE]; 70 }; 71 72 struct an30259a { 73 struct mutex mutex; /* held when writing to registers */ 74 struct i2c_client *client; 75 struct an30259a_led leds[AN30259A_MAX_LEDS]; 76 struct regmap *regmap; 77 int num_leds; 78 }; 79 80 static int an30259a_brightness_set(struct led_classdev *cdev, 81 enum led_brightness brightness) 82 { 83 struct an30259a_led *led; 84 int ret; 85 unsigned int led_on; 86 87 led = container_of(cdev, struct an30259a_led, cdev); 88 mutex_lock(&led->chip->mutex); 89 90 ret = regmap_read(led->chip->regmap, AN30259A_REG_LED_ON, &led_on); 91 if (ret) 92 goto error; 93 94 switch (brightness) { 95 case LED_OFF: 96 led_on &= ~AN30259A_LED_EN(led->num); 97 led_on &= ~AN30259A_LED_SLOPE(led->num); 98 led->sloping = false; 99 break; 100 default: 101 led_on |= AN30259A_LED_EN(led->num); 102 if (led->sloping) 103 led_on |= AN30259A_LED_SLOPE(led->num); 104 ret = regmap_write(led->chip->regmap, 105 AN30259A_REG_LEDCNT1(led->num), 106 AN30259A_LED_DUTYMAX(0xf) | 107 AN30259A_LED_DUTYMID(0xf)); 108 if (ret) 109 goto error; 110 break; 111 } 112 113 ret = regmap_write(led->chip->regmap, AN30259A_REG_LED_ON, led_on); 114 if (ret) 115 goto error; 116 117 ret = regmap_write(led->chip->regmap, AN30259A_REG_LEDCC(led->num), 118 brightness); 119 120 error: 121 mutex_unlock(&led->chip->mutex); 122 123 return ret; 124 } 125 126 static int an30259a_blink_set(struct led_classdev *cdev, 127 unsigned long *delay_off, unsigned long *delay_on) 128 { 129 struct an30259a_led *led; 130 int ret, num; 131 unsigned int led_on; 132 unsigned long off = *delay_off, on = *delay_on; 133 134 led = container_of(cdev, struct an30259a_led, cdev); 135 136 mutex_lock(&led->chip->mutex); 137 num = led->num; 138 139 /* slope time can only be a multiple of 500ms. */ 140 if (off % AN30259A_SLOPE_RESOLUTION || on % AN30259A_SLOPE_RESOLUTION) { 141 ret = -EINVAL; 142 goto error; 143 } 144 145 /* up to a maximum of 7500ms. */ 146 if (off > AN30259A_BLINK_MAX_TIME || on > AN30259A_BLINK_MAX_TIME) { 147 ret = -EINVAL; 148 goto error; 149 } 150 151 /* if no blink specified, default to 1 Hz. */ 152 if (!off && !on) { 153 *delay_off = off = 500; 154 *delay_on = on = 500; 155 } 156 157 /* convert into values the HW will understand. */ 158 off /= AN30259A_SLOPE_RESOLUTION; 159 on /= AN30259A_SLOPE_RESOLUTION; 160 161 /* duty min should be zero (=off), delay should be zero. */ 162 ret = regmap_write(led->chip->regmap, AN30259A_REG_LEDCNT2(num), 163 AN30259A_LED_DELAY(0) | AN30259A_LED_DUTYMIN(0)); 164 if (ret) 165 goto error; 166 167 /* reset detention time (no "breathing" effect). */ 168 ret = regmap_write(led->chip->regmap, AN30259A_REG_LEDCNT3(num), 169 AN30259A_LED_DT1(0) | AN30259A_LED_DT2(0)); 170 if (ret) 171 goto error; 172 ret = regmap_write(led->chip->regmap, AN30259A_REG_LEDCNT4(num), 173 AN30259A_LED_DT3(0) | AN30259A_LED_DT4(0)); 174 if (ret) 175 goto error; 176 177 /* slope time controls on/off cycle length. */ 178 ret = regmap_write(led->chip->regmap, AN30259A_REG_SLOPE(num), 179 AN30259A_LED_SLOPETIME1(off) | 180 AN30259A_LED_SLOPETIME2(on)); 181 if (ret) 182 goto error; 183 184 /* Finally, enable slope mode. */ 185 ret = regmap_read(led->chip->regmap, AN30259A_REG_LED_ON, &led_on); 186 if (ret) 187 goto error; 188 189 led_on |= AN30259A_LED_SLOPE(num) | AN30259A_LED_EN(led->num); 190 191 ret = regmap_write(led->chip->regmap, AN30259A_REG_LED_ON, led_on); 192 193 if (!ret) 194 led->sloping = true; 195 error: 196 mutex_unlock(&led->chip->mutex); 197 198 return ret; 199 } 200 201 static int an30259a_dt_init(struct i2c_client *client, 202 struct an30259a *chip) 203 { 204 struct device_node *np = client->dev.of_node, *child; 205 int count, ret; 206 int i = 0; 207 const char *str; 208 struct an30259a_led *led; 209 210 count = of_get_child_count(np); 211 if (!count || count > AN30259A_MAX_LEDS) 212 return -EINVAL; 213 214 for_each_available_child_of_node(np, child) { 215 u32 source; 216 217 ret = of_property_read_u32(child, "reg", &source); 218 if (ret != 0 || !source || source > AN30259A_MAX_LEDS) { 219 dev_err(&client->dev, "Couldn't read LED address: %d\n", 220 ret); 221 count--; 222 continue; 223 } 224 225 led = &chip->leds[i]; 226 227 led->num = source; 228 led->chip = chip; 229 230 if (of_property_read_string(child, "label", &str)) 231 snprintf(led->label, sizeof(led->label), "an30259a::"); 232 else 233 snprintf(led->label, sizeof(led->label), "an30259a:%s", 234 str); 235 236 led->cdev.name = led->label; 237 238 if (!of_property_read_string(child, "default-state", &str)) { 239 if (!strcmp(str, "on")) 240 led->default_state = STATE_ON; 241 else if (!strcmp(str, "keep")) 242 led->default_state = STATE_KEEP; 243 else 244 led->default_state = STATE_OFF; 245 } 246 247 of_property_read_string(child, "linux,default-trigger", 248 &led->cdev.default_trigger); 249 250 i++; 251 } 252 253 if (!count) 254 return -EINVAL; 255 256 chip->num_leds = i; 257 258 return 0; 259 } 260 261 static const struct regmap_config an30259a_regmap_config = { 262 .reg_bits = 8, 263 .val_bits = 8, 264 .max_register = AN30259A_REG_MAX, 265 }; 266 267 static void an30259a_init_default_state(struct an30259a_led *led) 268 { 269 struct an30259a *chip = led->chip; 270 int led_on, err; 271 272 switch (led->default_state) { 273 case STATE_ON: 274 led->cdev.brightness = LED_FULL; 275 break; 276 case STATE_KEEP: 277 err = regmap_read(chip->regmap, AN30259A_REG_LED_ON, &led_on); 278 if (err) 279 break; 280 281 if (!(led_on & AN30259A_LED_EN(led->num))) { 282 led->cdev.brightness = LED_OFF; 283 break; 284 } 285 regmap_read(chip->regmap, AN30259A_REG_LEDCC(led->num), 286 &led->cdev.brightness); 287 break; 288 default: 289 led->cdev.brightness = LED_OFF; 290 } 291 292 an30259a_brightness_set(&led->cdev, led->cdev.brightness); 293 } 294 295 static int an30259a_probe(struct i2c_client *client) 296 { 297 struct an30259a *chip; 298 int i, err; 299 300 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 301 if (!chip) 302 return -ENOMEM; 303 304 err = an30259a_dt_init(client, chip); 305 if (err < 0) 306 return err; 307 308 mutex_init(&chip->mutex); 309 chip->client = client; 310 i2c_set_clientdata(client, chip); 311 312 chip->regmap = devm_regmap_init_i2c(client, &an30259a_regmap_config); 313 314 for (i = 0; i < chip->num_leds; i++) { 315 an30259a_init_default_state(&chip->leds[i]); 316 chip->leds[i].cdev.brightness_set_blocking = 317 an30259a_brightness_set; 318 chip->leds[i].cdev.blink_set = an30259a_blink_set; 319 320 err = devm_led_classdev_register(&client->dev, 321 &chip->leds[i].cdev); 322 if (err < 0) 323 goto exit; 324 } 325 return 0; 326 327 exit: 328 mutex_destroy(&chip->mutex); 329 return err; 330 } 331 332 static int an30259a_remove(struct i2c_client *client) 333 { 334 struct an30259a *chip = i2c_get_clientdata(client); 335 336 mutex_destroy(&chip->mutex); 337 338 return 0; 339 } 340 341 static const struct of_device_id an30259a_match_table[] = { 342 { .compatible = "panasonic,an30259a", }, 343 { /* sentinel */ }, 344 }; 345 346 MODULE_DEVICE_TABLE(of, an30259a_match_table); 347 348 static const struct i2c_device_id an30259a_id[] = { 349 { "an30259a", 0 }, 350 { /* sentinel */ }, 351 }; 352 MODULE_DEVICE_TABLE(i2c, an30259a_id); 353 354 static struct i2c_driver an30259a_driver = { 355 .driver = { 356 .name = "leds-an32059a", 357 .of_match_table = of_match_ptr(an30259a_match_table), 358 }, 359 .probe_new = an30259a_probe, 360 .remove = an30259a_remove, 361 .id_table = an30259a_id, 362 }; 363 364 module_i2c_driver(an30259a_driver); 365 366 MODULE_AUTHOR("Simon Shields <simon@lineageos.org>"); 367 MODULE_DESCRIPTION("AN32059A LED driver"); 368 MODULE_LICENSE("GPL v2"); 369