1 /* 2 * Simple driver for Texas Instruments LM3642 LED Flash driver chip 3 * Copyright (C) 2012 Texas Instruments 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 */ 10 #include <linux/module.h> 11 #include <linux/delay.h> 12 #include <linux/i2c.h> 13 #include <linux/leds.h> 14 #include <linux/slab.h> 15 #include <linux/platform_device.h> 16 #include <linux/fs.h> 17 #include <linux/regmap.h> 18 #include <linux/workqueue.h> 19 #include <linux/platform_data/leds-lm3642.h> 20 21 #define REG_FILT_TIME (0x0) 22 #define REG_IVFM_MODE (0x1) 23 #define REG_TORCH_TIME (0x6) 24 #define REG_FLASH (0x8) 25 #define REG_I_CTRL (0x9) 26 #define REG_ENABLE (0xA) 27 #define REG_FLAG (0xB) 28 #define REG_MAX (0xB) 29 30 #define UVLO_EN_SHIFT (7) 31 #define IVM_D_TH_SHIFT (2) 32 #define TORCH_RAMP_UP_TIME_SHIFT (3) 33 #define TORCH_RAMP_DN_TIME_SHIFT (0) 34 #define INDUCTOR_I_LIMIT_SHIFT (6) 35 #define FLASH_RAMP_TIME_SHIFT (3) 36 #define FLASH_TOUT_TIME_SHIFT (0) 37 #define TORCH_I_SHIFT (4) 38 #define FLASH_I_SHIFT (0) 39 #define IVFM_SHIFT (7) 40 #define TX_PIN_EN_SHIFT (6) 41 #define STROBE_PIN_EN_SHIFT (5) 42 #define TORCH_PIN_EN_SHIFT (4) 43 #define MODE_BITS_SHIFT (0) 44 45 #define UVLO_EN_MASK (0x1) 46 #define IVM_D_TH_MASK (0x7) 47 #define TORCH_RAMP_UP_TIME_MASK (0x7) 48 #define TORCH_RAMP_DN_TIME_MASK (0x7) 49 #define INDUCTOR_I_LIMIT_MASK (0x1) 50 #define FLASH_RAMP_TIME_MASK (0x7) 51 #define FLASH_TOUT_TIME_MASK (0x7) 52 #define TORCH_I_MASK (0x7) 53 #define FLASH_I_MASK (0xF) 54 #define IVFM_MASK (0x1) 55 #define TX_PIN_EN_MASK (0x1) 56 #define STROBE_PIN_EN_MASK (0x1) 57 #define TORCH_PIN_EN_MASK (0x1) 58 #define MODE_BITS_MASK (0x73) 59 #define EX_PIN_CONTROL_MASK (0x71) 60 #define EX_PIN_ENABLE_MASK (0x70) 61 62 enum lm3642_mode { 63 MODES_STASNDBY = 0, 64 MODES_INDIC, 65 MODES_TORCH, 66 MODES_FLASH 67 }; 68 69 struct lm3642_chip_data { 70 struct device *dev; 71 72 struct led_classdev cdev_flash; 73 struct led_classdev cdev_torch; 74 struct led_classdev cdev_indicator; 75 76 struct work_struct work_flash; 77 struct work_struct work_torch; 78 struct work_struct work_indicator; 79 80 u8 br_flash; 81 u8 br_torch; 82 u8 br_indicator; 83 84 enum lm3642_torch_pin_enable torch_pin; 85 enum lm3642_strobe_pin_enable strobe_pin; 86 enum lm3642_tx_pin_enable tx_pin; 87 88 struct lm3642_platform_data *pdata; 89 struct regmap *regmap; 90 struct mutex lock; 91 92 unsigned int last_flag; 93 }; 94 95 /* chip initialize */ 96 static int lm3642_chip_init(struct lm3642_chip_data *chip) 97 { 98 int ret; 99 struct lm3642_platform_data *pdata = chip->pdata; 100 101 /* set enable register */ 102 ret = regmap_update_bits(chip->regmap, REG_ENABLE, EX_PIN_ENABLE_MASK, 103 pdata->tx_pin); 104 if (ret < 0) 105 dev_err(chip->dev, "Failed to update REG_ENABLE Register\n"); 106 return ret; 107 } 108 109 /* chip control */ 110 static int lm3642_control(struct lm3642_chip_data *chip, 111 u8 brightness, enum lm3642_mode opmode) 112 { 113 int ret; 114 115 ret = regmap_read(chip->regmap, REG_FLAG, &chip->last_flag); 116 if (ret < 0) { 117 dev_err(chip->dev, "Failed to read REG_FLAG Register\n"); 118 goto out; 119 } 120 121 if (chip->last_flag) 122 dev_info(chip->dev, "Last FLAG is 0x%x\n", chip->last_flag); 123 124 /* brightness 0 means off-state */ 125 if (!brightness) 126 opmode = MODES_STASNDBY; 127 128 switch (opmode) { 129 case MODES_TORCH: 130 ret = regmap_update_bits(chip->regmap, REG_I_CTRL, 131 TORCH_I_MASK << TORCH_I_SHIFT, 132 (brightness - 1) << TORCH_I_SHIFT); 133 134 if (chip->torch_pin) 135 opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT); 136 break; 137 138 case MODES_FLASH: 139 ret = regmap_update_bits(chip->regmap, REG_I_CTRL, 140 FLASH_I_MASK << FLASH_I_SHIFT, 141 (brightness - 1) << FLASH_I_SHIFT); 142 143 if (chip->strobe_pin) 144 opmode |= (STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT); 145 break; 146 147 case MODES_INDIC: 148 ret = regmap_update_bits(chip->regmap, REG_I_CTRL, 149 TORCH_I_MASK << TORCH_I_SHIFT, 150 (brightness - 1) << TORCH_I_SHIFT); 151 break; 152 153 case MODES_STASNDBY: 154 155 break; 156 157 default: 158 return ret; 159 } 160 if (ret < 0) { 161 dev_err(chip->dev, "Failed to write REG_I_CTRL Register\n"); 162 goto out; 163 } 164 165 if (chip->tx_pin) 166 opmode |= (TX_PIN_EN_MASK << TX_PIN_EN_SHIFT); 167 168 ret = regmap_update_bits(chip->regmap, REG_ENABLE, 169 MODE_BITS_MASK << MODE_BITS_SHIFT, 170 opmode << MODE_BITS_SHIFT); 171 out: 172 return ret; 173 } 174 175 /* torch */ 176 177 /* torch pin config for lm3642*/ 178 static ssize_t lm3642_torch_pin_store(struct device *dev, 179 struct device_attribute *attr, 180 const char *buf, size_t size) 181 { 182 ssize_t ret; 183 struct led_classdev *led_cdev = dev_get_drvdata(dev); 184 struct lm3642_chip_data *chip = 185 container_of(led_cdev, struct lm3642_chip_data, cdev_indicator); 186 unsigned int state; 187 188 ret = kstrtouint(buf, 10, &state); 189 if (ret) 190 goto out_strtoint; 191 if (state != 0) 192 state = 0x01 << TORCH_PIN_EN_SHIFT; 193 194 chip->torch_pin = state; 195 ret = regmap_update_bits(chip->regmap, REG_ENABLE, 196 TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT, 197 state); 198 if (ret < 0) 199 goto out; 200 201 return size; 202 out: 203 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__); 204 return ret; 205 out_strtoint: 206 dev_err(chip->dev, "%s: fail to change str to int\n", __func__); 207 return ret; 208 } 209 210 static DEVICE_ATTR(torch_pin, S_IWUSR, NULL, lm3642_torch_pin_store); 211 212 static void lm3642_deferred_torch_brightness_set(struct work_struct *work) 213 { 214 struct lm3642_chip_data *chip = 215 container_of(work, struct lm3642_chip_data, work_torch); 216 217 mutex_lock(&chip->lock); 218 lm3642_control(chip, chip->br_torch, MODES_TORCH); 219 mutex_unlock(&chip->lock); 220 } 221 222 static void lm3642_torch_brightness_set(struct led_classdev *cdev, 223 enum led_brightness brightness) 224 { 225 struct lm3642_chip_data *chip = 226 container_of(cdev, struct lm3642_chip_data, cdev_torch); 227 228 chip->br_torch = brightness; 229 schedule_work(&chip->work_torch); 230 } 231 232 /* flash */ 233 234 /* strobe pin config for lm3642*/ 235 static ssize_t lm3642_strobe_pin_store(struct device *dev, 236 struct device_attribute *attr, 237 const char *buf, size_t size) 238 { 239 ssize_t ret; 240 struct led_classdev *led_cdev = dev_get_drvdata(dev); 241 struct lm3642_chip_data *chip = 242 container_of(led_cdev, struct lm3642_chip_data, cdev_indicator); 243 unsigned int state; 244 245 ret = kstrtouint(buf, 10, &state); 246 if (ret) 247 goto out_strtoint; 248 if (state != 0) 249 state = 0x01 << STROBE_PIN_EN_SHIFT; 250 251 chip->strobe_pin = state; 252 ret = regmap_update_bits(chip->regmap, REG_ENABLE, 253 STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT, 254 state); 255 if (ret < 0) 256 goto out; 257 258 return size; 259 out: 260 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__); 261 return ret; 262 out_strtoint: 263 dev_err(chip->dev, "%s: fail to change str to int\n", __func__); 264 return ret; 265 } 266 267 static DEVICE_ATTR(strobe_pin, S_IWUSR, NULL, lm3642_strobe_pin_store); 268 269 static void lm3642_deferred_strobe_brightness_set(struct work_struct *work) 270 { 271 struct lm3642_chip_data *chip = 272 container_of(work, struct lm3642_chip_data, work_flash); 273 274 mutex_lock(&chip->lock); 275 lm3642_control(chip, chip->br_flash, MODES_FLASH); 276 mutex_unlock(&chip->lock); 277 } 278 279 static void lm3642_strobe_brightness_set(struct led_classdev *cdev, 280 enum led_brightness brightness) 281 { 282 struct lm3642_chip_data *chip = 283 container_of(cdev, struct lm3642_chip_data, cdev_flash); 284 285 chip->br_flash = brightness; 286 schedule_work(&chip->work_flash); 287 } 288 289 /* indicator */ 290 static void lm3642_deferred_indicator_brightness_set(struct work_struct *work) 291 { 292 struct lm3642_chip_data *chip = 293 container_of(work, struct lm3642_chip_data, work_indicator); 294 295 mutex_lock(&chip->lock); 296 lm3642_control(chip, chip->br_indicator, MODES_INDIC); 297 mutex_unlock(&chip->lock); 298 } 299 300 static void lm3642_indicator_brightness_set(struct led_classdev *cdev, 301 enum led_brightness brightness) 302 { 303 struct lm3642_chip_data *chip = 304 container_of(cdev, struct lm3642_chip_data, cdev_indicator); 305 306 chip->br_indicator = brightness; 307 schedule_work(&chip->work_indicator); 308 } 309 310 static const struct regmap_config lm3642_regmap = { 311 .reg_bits = 8, 312 .val_bits = 8, 313 .max_register = REG_MAX, 314 }; 315 316 static int lm3642_probe(struct i2c_client *client, 317 const struct i2c_device_id *id) 318 { 319 struct lm3642_platform_data *pdata = dev_get_platdata(&client->dev); 320 struct lm3642_chip_data *chip; 321 322 int err; 323 324 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 325 dev_err(&client->dev, "i2c functionality check fail.\n"); 326 return -EOPNOTSUPP; 327 } 328 329 if (pdata == NULL) { 330 dev_err(&client->dev, "needs Platform Data.\n"); 331 return -ENODATA; 332 } 333 334 chip = devm_kzalloc(&client->dev, 335 sizeof(struct lm3642_chip_data), GFP_KERNEL); 336 if (!chip) 337 return -ENOMEM; 338 339 chip->dev = &client->dev; 340 chip->pdata = pdata; 341 342 chip->tx_pin = pdata->tx_pin; 343 chip->torch_pin = pdata->torch_pin; 344 chip->strobe_pin = pdata->strobe_pin; 345 346 chip->regmap = devm_regmap_init_i2c(client, &lm3642_regmap); 347 if (IS_ERR(chip->regmap)) { 348 err = PTR_ERR(chip->regmap); 349 dev_err(&client->dev, "Failed to allocate register map: %d\n", 350 err); 351 return err; 352 } 353 354 mutex_init(&chip->lock); 355 i2c_set_clientdata(client, chip); 356 357 err = lm3642_chip_init(chip); 358 if (err < 0) 359 goto err_out; 360 361 /* flash */ 362 INIT_WORK(&chip->work_flash, lm3642_deferred_strobe_brightness_set); 363 chip->cdev_flash.name = "flash"; 364 chip->cdev_flash.max_brightness = 16; 365 chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set; 366 chip->cdev_flash.default_trigger = "flash"; 367 err = led_classdev_register((struct device *) 368 &client->dev, &chip->cdev_flash); 369 if (err < 0) { 370 dev_err(chip->dev, "failed to register flash\n"); 371 goto err_out; 372 } 373 err = device_create_file(chip->cdev_flash.dev, &dev_attr_strobe_pin); 374 if (err < 0) { 375 dev_err(chip->dev, "failed to create strobe-pin file\n"); 376 goto err_create_flash_pin_file; 377 } 378 379 /* torch */ 380 INIT_WORK(&chip->work_torch, lm3642_deferred_torch_brightness_set); 381 chip->cdev_torch.name = "torch"; 382 chip->cdev_torch.max_brightness = 8; 383 chip->cdev_torch.brightness_set = lm3642_torch_brightness_set; 384 chip->cdev_torch.default_trigger = "torch"; 385 err = led_classdev_register((struct device *) 386 &client->dev, &chip->cdev_torch); 387 if (err < 0) { 388 dev_err(chip->dev, "failed to register torch\n"); 389 goto err_create_torch_file; 390 } 391 err = device_create_file(chip->cdev_torch.dev, &dev_attr_torch_pin); 392 if (err < 0) { 393 dev_err(chip->dev, "failed to create torch-pin file\n"); 394 goto err_create_torch_pin_file; 395 } 396 397 /* indicator */ 398 INIT_WORK(&chip->work_indicator, 399 lm3642_deferred_indicator_brightness_set); 400 chip->cdev_indicator.name = "indicator"; 401 chip->cdev_indicator.max_brightness = 8; 402 chip->cdev_indicator.brightness_set = lm3642_indicator_brightness_set; 403 err = led_classdev_register((struct device *) 404 &client->dev, &chip->cdev_indicator); 405 if (err < 0) { 406 dev_err(chip->dev, "failed to register indicator\n"); 407 goto err_create_indicator_file; 408 } 409 410 dev_info(&client->dev, "LM3642 is initialized\n"); 411 return 0; 412 413 err_create_indicator_file: 414 device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin); 415 err_create_torch_pin_file: 416 led_classdev_unregister(&chip->cdev_torch); 417 err_create_torch_file: 418 device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin); 419 err_create_flash_pin_file: 420 led_classdev_unregister(&chip->cdev_flash); 421 err_out: 422 return err; 423 } 424 425 static int lm3642_remove(struct i2c_client *client) 426 { 427 struct lm3642_chip_data *chip = i2c_get_clientdata(client); 428 429 led_classdev_unregister(&chip->cdev_indicator); 430 flush_work(&chip->work_indicator); 431 device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin); 432 led_classdev_unregister(&chip->cdev_torch); 433 flush_work(&chip->work_torch); 434 device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin); 435 led_classdev_unregister(&chip->cdev_flash); 436 flush_work(&chip->work_flash); 437 regmap_write(chip->regmap, REG_ENABLE, 0); 438 return 0; 439 } 440 441 static const struct i2c_device_id lm3642_id[] = { 442 {LM3642_NAME, 0}, 443 {} 444 }; 445 446 MODULE_DEVICE_TABLE(i2c, lm3642_id); 447 448 static struct i2c_driver lm3642_i2c_driver = { 449 .driver = { 450 .name = LM3642_NAME, 451 .owner = THIS_MODULE, 452 .pm = NULL, 453 }, 454 .probe = lm3642_probe, 455 .remove = lm3642_remove, 456 .id_table = lm3642_id, 457 }; 458 459 module_i2c_driver(lm3642_i2c_driver); 460 461 MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3642"); 462 MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>"); 463 MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>"); 464 MODULE_LICENSE("GPL v2"); 465