1 /* 2 * Driver for ISSI IS31FL32xx family of I2C LED controllers 3 * 4 * Copyright 2015 Allworx Corp. 5 * 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * Datasheets: 12 * http://www.issi.com/US/product-analog-fxled-driver.shtml 13 * http://www.si-en.com/product.asp?parentid=890 14 */ 15 16 #include <linux/device.h> 17 #include <linux/i2c.h> 18 #include <linux/kernel.h> 19 #include <linux/leds.h> 20 #include <linux/module.h> 21 #include <linux/of.h> 22 #include <linux/of_device.h> 23 24 /* Used to indicate a device has no such register */ 25 #define IS31FL32XX_REG_NONE 0xFF 26 27 /* Software Shutdown bit in Shutdown Register */ 28 #define IS31FL32XX_SHUTDOWN_SSD_ENABLE 0 29 #define IS31FL32XX_SHUTDOWN_SSD_DISABLE BIT(0) 30 31 /* IS31FL3216 has a number of unique registers */ 32 #define IS31FL3216_CONFIG_REG 0x00 33 #define IS31FL3216_LIGHTING_EFFECT_REG 0x03 34 #define IS31FL3216_CHANNEL_CONFIG_REG 0x04 35 36 /* Software Shutdown bit in 3216 Config Register */ 37 #define IS31FL3216_CONFIG_SSD_ENABLE BIT(7) 38 #define IS31FL3216_CONFIG_SSD_DISABLE 0 39 40 struct is31fl32xx_priv; 41 struct is31fl32xx_led_data { 42 struct led_classdev cdev; 43 u8 channel; /* 1-based, max priv->cdef->channels */ 44 struct is31fl32xx_priv *priv; 45 }; 46 47 struct is31fl32xx_priv { 48 const struct is31fl32xx_chipdef *cdef; 49 struct i2c_client *client; 50 unsigned int num_leds; 51 struct is31fl32xx_led_data leds[0]; 52 }; 53 54 /** 55 * struct is31fl32xx_chipdef - chip-specific attributes 56 * @channels : Number of LED channels 57 * @shutdown_reg : address of Shutdown register (optional) 58 * @pwm_update_reg : address of PWM Update register 59 * @global_control_reg : address of Global Control register (optional) 60 * @reset_reg : address of Reset register (optional) 61 * @pwm_register_base : address of first PWM register 62 * @pwm_registers_reversed: : true if PWM registers count down instead of up 63 * @led_control_register_base : address of first LED control register (optional) 64 * @enable_bits_per_led_control_register: number of LEDs enable bits in each 65 * @reset_func: : pointer to reset function 66 * 67 * For all optional register addresses, the sentinel value %IS31FL32XX_REG_NONE 68 * indicates that this chip has no such register. 69 * 70 * If non-NULL, @reset_func will be called during probing to set all 71 * necessary registers to a known initialization state. This is needed 72 * for chips that do not have a @reset_reg. 73 * 74 * @enable_bits_per_led_control_register must be >=1 if 75 * @led_control_register_base != %IS31FL32XX_REG_NONE. 76 */ 77 struct is31fl32xx_chipdef { 78 u8 channels; 79 u8 shutdown_reg; 80 u8 pwm_update_reg; 81 u8 global_control_reg; 82 u8 reset_reg; 83 u8 pwm_register_base; 84 bool pwm_registers_reversed; 85 u8 led_control_register_base; 86 u8 enable_bits_per_led_control_register; 87 int (*reset_func)(struct is31fl32xx_priv *priv); 88 int (*sw_shutdown_func)(struct is31fl32xx_priv *priv, bool enable); 89 }; 90 91 static const struct is31fl32xx_chipdef is31fl3236_cdef = { 92 .channels = 36, 93 .shutdown_reg = 0x00, 94 .pwm_update_reg = 0x25, 95 .global_control_reg = 0x4a, 96 .reset_reg = 0x4f, 97 .pwm_register_base = 0x01, 98 .led_control_register_base = 0x26, 99 .enable_bits_per_led_control_register = 1, 100 }; 101 102 static const struct is31fl32xx_chipdef is31fl3235_cdef = { 103 .channels = 28, 104 .shutdown_reg = 0x00, 105 .pwm_update_reg = 0x25, 106 .global_control_reg = 0x4a, 107 .reset_reg = 0x4f, 108 .pwm_register_base = 0x05, 109 .led_control_register_base = 0x2a, 110 .enable_bits_per_led_control_register = 1, 111 }; 112 113 static const struct is31fl32xx_chipdef is31fl3218_cdef = { 114 .channels = 18, 115 .shutdown_reg = 0x00, 116 .pwm_update_reg = 0x16, 117 .global_control_reg = IS31FL32XX_REG_NONE, 118 .reset_reg = 0x17, 119 .pwm_register_base = 0x01, 120 .led_control_register_base = 0x13, 121 .enable_bits_per_led_control_register = 6, 122 }; 123 124 static int is31fl3216_reset(struct is31fl32xx_priv *priv); 125 static int is31fl3216_software_shutdown(struct is31fl32xx_priv *priv, 126 bool enable); 127 static const struct is31fl32xx_chipdef is31fl3216_cdef = { 128 .channels = 16, 129 .shutdown_reg = IS31FL32XX_REG_NONE, 130 .pwm_update_reg = 0xB0, 131 .global_control_reg = IS31FL32XX_REG_NONE, 132 .reset_reg = IS31FL32XX_REG_NONE, 133 .pwm_register_base = 0x10, 134 .pwm_registers_reversed = true, 135 .led_control_register_base = 0x01, 136 .enable_bits_per_led_control_register = 8, 137 .reset_func = is31fl3216_reset, 138 .sw_shutdown_func = is31fl3216_software_shutdown, 139 }; 140 141 static int is31fl32xx_write(struct is31fl32xx_priv *priv, u8 reg, u8 val) 142 { 143 int ret; 144 145 dev_dbg(&priv->client->dev, "writing register 0x%02X=0x%02X", reg, val); 146 147 ret = i2c_smbus_write_byte_data(priv->client, reg, val); 148 if (ret) { 149 dev_err(&priv->client->dev, 150 "register write to 0x%02X failed (error %d)", 151 reg, ret); 152 } 153 return ret; 154 } 155 156 /* 157 * Custom reset function for IS31FL3216 because it does not have a RESET 158 * register the way that the other IS31FL32xx chips do. We don't bother 159 * writing the GPIO and animation registers, because the registers we 160 * do write ensure those will have no effect. 161 */ 162 static int is31fl3216_reset(struct is31fl32xx_priv *priv) 163 { 164 unsigned int i; 165 int ret; 166 167 ret = is31fl32xx_write(priv, IS31FL3216_CONFIG_REG, 168 IS31FL3216_CONFIG_SSD_ENABLE); 169 if (ret) 170 return ret; 171 for (i = 0; i < priv->cdef->channels; i++) { 172 ret = is31fl32xx_write(priv, priv->cdef->pwm_register_base+i, 173 0x00); 174 if (ret) 175 return ret; 176 } 177 ret = is31fl32xx_write(priv, priv->cdef->pwm_update_reg, 0); 178 if (ret) 179 return ret; 180 ret = is31fl32xx_write(priv, IS31FL3216_LIGHTING_EFFECT_REG, 0x00); 181 if (ret) 182 return ret; 183 ret = is31fl32xx_write(priv, IS31FL3216_CHANNEL_CONFIG_REG, 0x00); 184 if (ret) 185 return ret; 186 187 return 0; 188 } 189 190 /* 191 * Custom Software-Shutdown function for IS31FL3216 because it does not have 192 * a SHUTDOWN register the way that the other IS31FL32xx chips do. 193 * We don't bother doing a read/modify/write on the CONFIG register because 194 * we only ever use a value of '0' for the other fields in that register. 195 */ 196 static int is31fl3216_software_shutdown(struct is31fl32xx_priv *priv, 197 bool enable) 198 { 199 u8 value = enable ? IS31FL3216_CONFIG_SSD_ENABLE : 200 IS31FL3216_CONFIG_SSD_DISABLE; 201 202 return is31fl32xx_write(priv, IS31FL3216_CONFIG_REG, value); 203 } 204 205 /* 206 * NOTE: A mutex is not needed in this function because: 207 * - All referenced data is read-only after probe() 208 * - The I2C core has a mutex on to protect the bus 209 * - There are no read/modify/write operations 210 * - Intervening operations between the write of the PWM register 211 * and the Update register are harmless. 212 * 213 * Example: 214 * PWM_REG_1 write 16 215 * UPDATE_REG write 0 216 * PWM_REG_2 write 128 217 * UPDATE_REG write 0 218 * vs: 219 * PWM_REG_1 write 16 220 * PWM_REG_2 write 128 221 * UPDATE_REG write 0 222 * UPDATE_REG write 0 223 * are equivalent. Poking the Update register merely applies all PWM 224 * register writes up to that point. 225 */ 226 static int is31fl32xx_brightness_set(struct led_classdev *led_cdev, 227 enum led_brightness brightness) 228 { 229 const struct is31fl32xx_led_data *led_data = 230 container_of(led_cdev, struct is31fl32xx_led_data, cdev); 231 const struct is31fl32xx_chipdef *cdef = led_data->priv->cdef; 232 u8 pwm_register_offset; 233 int ret; 234 235 dev_dbg(led_cdev->dev, "%s: %d\n", __func__, brightness); 236 237 /* NOTE: led_data->channel is 1-based */ 238 if (cdef->pwm_registers_reversed) 239 pwm_register_offset = cdef->channels - led_data->channel; 240 else 241 pwm_register_offset = led_data->channel - 1; 242 243 ret = is31fl32xx_write(led_data->priv, 244 cdef->pwm_register_base + pwm_register_offset, 245 brightness); 246 if (ret) 247 return ret; 248 249 return is31fl32xx_write(led_data->priv, cdef->pwm_update_reg, 0); 250 } 251 252 static int is31fl32xx_reset_regs(struct is31fl32xx_priv *priv) 253 { 254 const struct is31fl32xx_chipdef *cdef = priv->cdef; 255 int ret; 256 257 if (cdef->reset_reg != IS31FL32XX_REG_NONE) { 258 ret = is31fl32xx_write(priv, cdef->reset_reg, 0); 259 if (ret) 260 return ret; 261 } 262 263 if (cdef->reset_func) 264 return cdef->reset_func(priv); 265 266 return 0; 267 } 268 269 static int is31fl32xx_software_shutdown(struct is31fl32xx_priv *priv, 270 bool enable) 271 { 272 const struct is31fl32xx_chipdef *cdef = priv->cdef; 273 int ret; 274 275 if (cdef->shutdown_reg != IS31FL32XX_REG_NONE) { 276 u8 value = enable ? IS31FL32XX_SHUTDOWN_SSD_ENABLE : 277 IS31FL32XX_SHUTDOWN_SSD_DISABLE; 278 ret = is31fl32xx_write(priv, cdef->shutdown_reg, value); 279 if (ret) 280 return ret; 281 } 282 283 if (cdef->sw_shutdown_func) 284 return cdef->sw_shutdown_func(priv, enable); 285 286 return 0; 287 } 288 289 static int is31fl32xx_init_regs(struct is31fl32xx_priv *priv) 290 { 291 const struct is31fl32xx_chipdef *cdef = priv->cdef; 292 int ret; 293 294 ret = is31fl32xx_reset_regs(priv); 295 if (ret) 296 return ret; 297 298 /* 299 * Set enable bit for all channels. 300 * We will control state with PWM registers alone. 301 */ 302 if (cdef->led_control_register_base != IS31FL32XX_REG_NONE) { 303 u8 value = 304 GENMASK(cdef->enable_bits_per_led_control_register-1, 0); 305 u8 num_regs = cdef->channels / 306 cdef->enable_bits_per_led_control_register; 307 int i; 308 309 for (i = 0; i < num_regs; i++) { 310 ret = is31fl32xx_write(priv, 311 cdef->led_control_register_base+i, 312 value); 313 if (ret) 314 return ret; 315 } 316 } 317 318 ret = is31fl32xx_software_shutdown(priv, false); 319 if (ret) 320 return ret; 321 322 if (cdef->global_control_reg != IS31FL32XX_REG_NONE) { 323 ret = is31fl32xx_write(priv, cdef->global_control_reg, 0x00); 324 if (ret) 325 return ret; 326 } 327 328 return 0; 329 } 330 331 static inline size_t sizeof_is31fl32xx_priv(int num_leds) 332 { 333 return sizeof(struct is31fl32xx_priv) + 334 (sizeof(struct is31fl32xx_led_data) * num_leds); 335 } 336 337 static int is31fl32xx_parse_child_dt(const struct device *dev, 338 const struct device_node *child, 339 struct is31fl32xx_led_data *led_data) 340 { 341 struct led_classdev *cdev = &led_data->cdev; 342 int ret = 0; 343 u32 reg; 344 345 if (of_property_read_string(child, "label", &cdev->name)) 346 cdev->name = child->name; 347 348 ret = of_property_read_u32(child, "reg", ®); 349 if (ret || reg < 1 || reg > led_data->priv->cdef->channels) { 350 dev_err(dev, 351 "Child node %s does not have a valid reg property\n", 352 child->full_name); 353 return -EINVAL; 354 } 355 led_data->channel = reg; 356 357 of_property_read_string(child, "linux,default-trigger", 358 &cdev->default_trigger); 359 360 cdev->brightness_set_blocking = is31fl32xx_brightness_set; 361 362 return 0; 363 } 364 365 static struct is31fl32xx_led_data *is31fl32xx_find_led_data( 366 struct is31fl32xx_priv *priv, 367 u8 channel) 368 { 369 size_t i; 370 371 for (i = 0; i < priv->num_leds; i++) { 372 if (priv->leds[i].channel == channel) 373 return &priv->leds[i]; 374 } 375 376 return NULL; 377 } 378 379 static int is31fl32xx_parse_dt(struct device *dev, 380 struct is31fl32xx_priv *priv) 381 { 382 struct device_node *child; 383 int ret = 0; 384 385 for_each_child_of_node(dev->of_node, child) { 386 struct is31fl32xx_led_data *led_data = 387 &priv->leds[priv->num_leds]; 388 const struct is31fl32xx_led_data *other_led_data; 389 390 led_data->priv = priv; 391 392 ret = is31fl32xx_parse_child_dt(dev, child, led_data); 393 if (ret) 394 goto err; 395 396 /* Detect if channel is already in use by another child */ 397 other_led_data = is31fl32xx_find_led_data(priv, 398 led_data->channel); 399 if (other_led_data) { 400 dev_err(dev, 401 "%s and %s both attempting to use channel %d\n", 402 led_data->cdev.name, 403 other_led_data->cdev.name, 404 led_data->channel); 405 goto err; 406 } 407 408 ret = devm_led_classdev_register(dev, &led_data->cdev); 409 if (ret) { 410 dev_err(dev, "failed to register PWM led for %s: %d\n", 411 led_data->cdev.name, ret); 412 goto err; 413 } 414 415 priv->num_leds++; 416 } 417 418 return 0; 419 420 err: 421 of_node_put(child); 422 return ret; 423 } 424 425 static const struct of_device_id of_is31fl31xx_match[] = { 426 { .compatible = "issi,is31fl3236", .data = &is31fl3236_cdef, }, 427 { .compatible = "issi,is31fl3235", .data = &is31fl3235_cdef, }, 428 { .compatible = "issi,is31fl3218", .data = &is31fl3218_cdef, }, 429 { .compatible = "si-en,sn3218", .data = &is31fl3218_cdef, }, 430 { .compatible = "issi,is31fl3216", .data = &is31fl3216_cdef, }, 431 { .compatible = "si-en,sn3216", .data = &is31fl3216_cdef, }, 432 {}, 433 }; 434 435 MODULE_DEVICE_TABLE(of, of_is31fl31xx_match); 436 437 static int is31fl32xx_probe(struct i2c_client *client, 438 const struct i2c_device_id *id) 439 { 440 const struct is31fl32xx_chipdef *cdef; 441 const struct of_device_id *of_dev_id; 442 struct device *dev = &client->dev; 443 struct is31fl32xx_priv *priv; 444 int count; 445 int ret = 0; 446 447 of_dev_id = of_match_device(of_is31fl31xx_match, dev); 448 if (!of_dev_id) 449 return -EINVAL; 450 451 cdef = of_dev_id->data; 452 453 count = of_get_child_count(dev->of_node); 454 if (!count) 455 return -EINVAL; 456 457 priv = devm_kzalloc(dev, sizeof_is31fl32xx_priv(count), 458 GFP_KERNEL); 459 if (!priv) 460 return -ENOMEM; 461 462 priv->client = client; 463 priv->cdef = cdef; 464 i2c_set_clientdata(client, priv); 465 466 ret = is31fl32xx_init_regs(priv); 467 if (ret) 468 return ret; 469 470 ret = is31fl32xx_parse_dt(dev, priv); 471 if (ret) 472 return ret; 473 474 return 0; 475 } 476 477 static int is31fl32xx_remove(struct i2c_client *client) 478 { 479 struct is31fl32xx_priv *priv = i2c_get_clientdata(client); 480 481 return is31fl32xx_reset_regs(priv); 482 } 483 484 /* 485 * i2c-core requires that id_table be non-NULL, even though 486 * it is not used for DeviceTree based instantiation. 487 */ 488 static const struct i2c_device_id is31fl31xx_id[] = { 489 {}, 490 }; 491 492 MODULE_DEVICE_TABLE(i2c, is31fl31xx_id); 493 494 static struct i2c_driver is31fl32xx_driver = { 495 .driver = { 496 .name = "is31fl32xx", 497 .of_match_table = of_is31fl31xx_match, 498 }, 499 .probe = is31fl32xx_probe, 500 .remove = is31fl32xx_remove, 501 .id_table = is31fl31xx_id, 502 }; 503 504 module_i2c_driver(is31fl32xx_driver); 505 506 MODULE_AUTHOR("David Rivshin <drivshin@allworx.com>"); 507 MODULE_DESCRIPTION("ISSI IS31FL32xx LED driver"); 508 MODULE_LICENSE("GPL v2"); 509