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