0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/i2c.h>
0011 #include <linux/init.h>
0012 #include <linux/leds.h>
0013 #include <linux/regmap.h>
0014 #include <linux/regulator/consumer.h>
0015 #include <linux/module.h>
0016 #include <linux/mutex.h>
0017 #include <linux/of.h>
0018 #include <linux/of_gpio.h>
0019 #include <linux/gpio/consumer.h>
0020 #include <linux/slab.h>
0021
0022 #define LP8860_DISP_CL1_BRT_MSB 0x00
0023 #define LP8860_DISP_CL1_BRT_LSB 0x01
0024 #define LP8860_DISP_CL1_CURR_MSB 0x02
0025 #define LP8860_DISP_CL1_CURR_LSB 0x03
0026 #define LP8860_CL2_BRT_MSB 0x04
0027 #define LP8860_CL2_BRT_LSB 0x05
0028 #define LP8860_CL2_CURRENT 0x06
0029 #define LP8860_CL3_BRT_MSB 0x07
0030 #define LP8860_CL3_BRT_LSB 0x08
0031 #define LP8860_CL3_CURRENT 0x09
0032 #define LP8860_CL4_BRT_MSB 0x0a
0033 #define LP8860_CL4_BRT_LSB 0x0b
0034 #define LP8860_CL4_CURRENT 0x0c
0035 #define LP8860_CONFIG 0x0d
0036 #define LP8860_STATUS 0x0e
0037 #define LP8860_FAULT 0x0f
0038 #define LP8860_LED_FAULT 0x10
0039 #define LP8860_FAULT_CLEAR 0x11
0040 #define LP8860_ID 0x12
0041 #define LP8860_TEMP_MSB 0x13
0042 #define LP8860_TEMP_LSB 0x14
0043 #define LP8860_DISP_LED_CURR_MSB 0x15
0044 #define LP8860_DISP_LED_CURR_LSB 0x16
0045 #define LP8860_DISP_LED_PWM_MSB 0x17
0046 #define LP8860_DISP_LED_PWM_LSB 0x18
0047 #define LP8860_EEPROM_CNTRL 0x19
0048 #define LP8860_EEPROM_UNLOCK 0x1a
0049
0050 #define LP8860_EEPROM_REG_0 0x60
0051 #define LP8860_EEPROM_REG_1 0x61
0052 #define LP8860_EEPROM_REG_2 0x62
0053 #define LP8860_EEPROM_REG_3 0x63
0054 #define LP8860_EEPROM_REG_4 0x64
0055 #define LP8860_EEPROM_REG_5 0x65
0056 #define LP8860_EEPROM_REG_6 0x66
0057 #define LP8860_EEPROM_REG_7 0x67
0058 #define LP8860_EEPROM_REG_8 0x68
0059 #define LP8860_EEPROM_REG_9 0x69
0060 #define LP8860_EEPROM_REG_10 0x6a
0061 #define LP8860_EEPROM_REG_11 0x6b
0062 #define LP8860_EEPROM_REG_12 0x6c
0063 #define LP8860_EEPROM_REG_13 0x6d
0064 #define LP8860_EEPROM_REG_14 0x6e
0065 #define LP8860_EEPROM_REG_15 0x6f
0066 #define LP8860_EEPROM_REG_16 0x70
0067 #define LP8860_EEPROM_REG_17 0x71
0068 #define LP8860_EEPROM_REG_18 0x72
0069 #define LP8860_EEPROM_REG_19 0x73
0070 #define LP8860_EEPROM_REG_20 0x74
0071 #define LP8860_EEPROM_REG_21 0x75
0072 #define LP8860_EEPROM_REG_22 0x76
0073 #define LP8860_EEPROM_REG_23 0x77
0074 #define LP8860_EEPROM_REG_24 0x78
0075
0076 #define LP8860_LOCK_EEPROM 0x00
0077 #define LP8860_UNLOCK_EEPROM 0x01
0078 #define LP8860_PROGRAM_EEPROM 0x02
0079 #define LP8860_EEPROM_CODE_1 0x08
0080 #define LP8860_EEPROM_CODE_2 0xba
0081 #define LP8860_EEPROM_CODE_3 0xef
0082
0083 #define LP8860_CLEAR_FAULTS 0x01
0084
0085 #define LP8860_NAME "lp8860"
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 struct lp8860_led {
0098 struct mutex lock;
0099 struct i2c_client *client;
0100 struct led_classdev led_dev;
0101 struct regmap *regmap;
0102 struct regmap *eeprom_regmap;
0103 struct gpio_desc *enable_gpio;
0104 struct regulator *regulator;
0105 };
0106
0107 struct lp8860_eeprom_reg {
0108 uint8_t reg;
0109 uint8_t value;
0110 };
0111
0112 static struct lp8860_eeprom_reg lp8860_eeprom_disp_regs[] = {
0113 { LP8860_EEPROM_REG_0, 0xed },
0114 { LP8860_EEPROM_REG_1, 0xdf },
0115 { LP8860_EEPROM_REG_2, 0xdc },
0116 { LP8860_EEPROM_REG_3, 0xf0 },
0117 { LP8860_EEPROM_REG_4, 0xdf },
0118 { LP8860_EEPROM_REG_5, 0xe5 },
0119 { LP8860_EEPROM_REG_6, 0xf2 },
0120 { LP8860_EEPROM_REG_7, 0x77 },
0121 { LP8860_EEPROM_REG_8, 0x77 },
0122 { LP8860_EEPROM_REG_9, 0x71 },
0123 { LP8860_EEPROM_REG_10, 0x3f },
0124 { LP8860_EEPROM_REG_11, 0xb7 },
0125 { LP8860_EEPROM_REG_12, 0x17 },
0126 { LP8860_EEPROM_REG_13, 0xef },
0127 { LP8860_EEPROM_REG_14, 0xb0 },
0128 { LP8860_EEPROM_REG_15, 0x87 },
0129 { LP8860_EEPROM_REG_16, 0xce },
0130 { LP8860_EEPROM_REG_17, 0x72 },
0131 { LP8860_EEPROM_REG_18, 0xe5 },
0132 { LP8860_EEPROM_REG_19, 0xdf },
0133 { LP8860_EEPROM_REG_20, 0x35 },
0134 { LP8860_EEPROM_REG_21, 0x06 },
0135 { LP8860_EEPROM_REG_22, 0xdc },
0136 { LP8860_EEPROM_REG_23, 0x88 },
0137 { LP8860_EEPROM_REG_24, 0x3E },
0138 };
0139
0140 static int lp8860_unlock_eeprom(struct lp8860_led *led, int lock)
0141 {
0142 int ret;
0143
0144 mutex_lock(&led->lock);
0145
0146 if (lock == LP8860_UNLOCK_EEPROM) {
0147 ret = regmap_write(led->regmap,
0148 LP8860_EEPROM_UNLOCK,
0149 LP8860_EEPROM_CODE_1);
0150 if (ret) {
0151 dev_err(&led->client->dev, "EEPROM Unlock failed\n");
0152 goto out;
0153 }
0154
0155 ret = regmap_write(led->regmap,
0156 LP8860_EEPROM_UNLOCK,
0157 LP8860_EEPROM_CODE_2);
0158 if (ret) {
0159 dev_err(&led->client->dev, "EEPROM Unlock failed\n");
0160 goto out;
0161 }
0162 ret = regmap_write(led->regmap,
0163 LP8860_EEPROM_UNLOCK,
0164 LP8860_EEPROM_CODE_3);
0165 if (ret) {
0166 dev_err(&led->client->dev, "EEPROM Unlock failed\n");
0167 goto out;
0168 }
0169 } else {
0170 ret = regmap_write(led->regmap,
0171 LP8860_EEPROM_UNLOCK,
0172 LP8860_LOCK_EEPROM);
0173 }
0174
0175 out:
0176 mutex_unlock(&led->lock);
0177 return ret;
0178 }
0179
0180 static int lp8860_fault_check(struct lp8860_led *led)
0181 {
0182 int ret, fault;
0183 unsigned int read_buf;
0184
0185 ret = regmap_read(led->regmap, LP8860_LED_FAULT, &read_buf);
0186 if (ret)
0187 goto out;
0188
0189 fault = read_buf;
0190
0191 ret = regmap_read(led->regmap, LP8860_FAULT, &read_buf);
0192 if (ret)
0193 goto out;
0194
0195 fault |= read_buf;
0196
0197
0198 if (fault)
0199 ret = regmap_write(led->regmap, LP8860_FAULT_CLEAR,
0200 LP8860_CLEAR_FAULTS);
0201 out:
0202 return ret;
0203 }
0204
0205 static int lp8860_brightness_set(struct led_classdev *led_cdev,
0206 enum led_brightness brt_val)
0207 {
0208 struct lp8860_led *led =
0209 container_of(led_cdev, struct lp8860_led, led_dev);
0210 int disp_brightness = brt_val * 255;
0211 int ret;
0212
0213 mutex_lock(&led->lock);
0214
0215 ret = lp8860_fault_check(led);
0216 if (ret) {
0217 dev_err(&led->client->dev, "Cannot read/clear faults\n");
0218 goto out;
0219 }
0220
0221 ret = regmap_write(led->regmap, LP8860_DISP_CL1_BRT_MSB,
0222 (disp_brightness & 0xff00) >> 8);
0223 if (ret) {
0224 dev_err(&led->client->dev, "Cannot write CL1 MSB\n");
0225 goto out;
0226 }
0227
0228 ret = regmap_write(led->regmap, LP8860_DISP_CL1_BRT_LSB,
0229 disp_brightness & 0xff);
0230 if (ret) {
0231 dev_err(&led->client->dev, "Cannot write CL1 LSB\n");
0232 goto out;
0233 }
0234 out:
0235 mutex_unlock(&led->lock);
0236 return ret;
0237 }
0238
0239 static int lp8860_init(struct lp8860_led *led)
0240 {
0241 unsigned int read_buf;
0242 int ret, i, reg_count;
0243
0244 if (led->regulator) {
0245 ret = regulator_enable(led->regulator);
0246 if (ret) {
0247 dev_err(&led->client->dev,
0248 "Failed to enable regulator\n");
0249 return ret;
0250 }
0251 }
0252
0253 if (led->enable_gpio)
0254 gpiod_direction_output(led->enable_gpio, 1);
0255
0256 ret = lp8860_fault_check(led);
0257 if (ret)
0258 goto out;
0259
0260 ret = regmap_read(led->regmap, LP8860_STATUS, &read_buf);
0261 if (ret)
0262 goto out;
0263
0264 ret = lp8860_unlock_eeprom(led, LP8860_UNLOCK_EEPROM);
0265 if (ret) {
0266 dev_err(&led->client->dev, "Failed unlocking EEPROM\n");
0267 goto out;
0268 }
0269
0270 reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs) / sizeof(lp8860_eeprom_disp_regs[0]);
0271 for (i = 0; i < reg_count; i++) {
0272 ret = regmap_write(led->eeprom_regmap,
0273 lp8860_eeprom_disp_regs[i].reg,
0274 lp8860_eeprom_disp_regs[i].value);
0275 if (ret) {
0276 dev_err(&led->client->dev, "Failed writing EEPROM\n");
0277 goto out;
0278 }
0279 }
0280
0281 ret = lp8860_unlock_eeprom(led, LP8860_LOCK_EEPROM);
0282 if (ret)
0283 goto out;
0284
0285 ret = regmap_write(led->regmap,
0286 LP8860_EEPROM_CNTRL,
0287 LP8860_PROGRAM_EEPROM);
0288 if (ret) {
0289 dev_err(&led->client->dev, "Failed programming EEPROM\n");
0290 goto out;
0291 }
0292
0293 return ret;
0294
0295 out:
0296 if (ret)
0297 if (led->enable_gpio)
0298 gpiod_direction_output(led->enable_gpio, 0);
0299
0300 if (led->regulator) {
0301 ret = regulator_disable(led->regulator);
0302 if (ret)
0303 dev_err(&led->client->dev,
0304 "Failed to disable regulator\n");
0305 }
0306
0307 return ret;
0308 }
0309
0310 static const struct reg_default lp8860_reg_defs[] = {
0311 { LP8860_DISP_CL1_BRT_MSB, 0x00},
0312 { LP8860_DISP_CL1_BRT_LSB, 0x00},
0313 { LP8860_DISP_CL1_CURR_MSB, 0x00},
0314 { LP8860_DISP_CL1_CURR_LSB, 0x00},
0315 { LP8860_CL2_BRT_MSB, 0x00},
0316 { LP8860_CL2_BRT_LSB, 0x00},
0317 { LP8860_CL2_CURRENT, 0x00},
0318 { LP8860_CL3_BRT_MSB, 0x00},
0319 { LP8860_CL3_BRT_LSB, 0x00},
0320 { LP8860_CL3_CURRENT, 0x00},
0321 { LP8860_CL4_BRT_MSB, 0x00},
0322 { LP8860_CL4_BRT_LSB, 0x00},
0323 { LP8860_CL4_CURRENT, 0x00},
0324 { LP8860_CONFIG, 0x00},
0325 { LP8860_FAULT_CLEAR, 0x00},
0326 { LP8860_EEPROM_CNTRL, 0x80},
0327 { LP8860_EEPROM_UNLOCK, 0x00},
0328 };
0329
0330 static const struct regmap_config lp8860_regmap_config = {
0331 .reg_bits = 8,
0332 .val_bits = 8,
0333
0334 .max_register = LP8860_EEPROM_UNLOCK,
0335 .reg_defaults = lp8860_reg_defs,
0336 .num_reg_defaults = ARRAY_SIZE(lp8860_reg_defs),
0337 .cache_type = REGCACHE_NONE,
0338 };
0339
0340 static const struct reg_default lp8860_eeprom_defs[] = {
0341 { LP8860_EEPROM_REG_0, 0x00 },
0342 { LP8860_EEPROM_REG_1, 0x00 },
0343 { LP8860_EEPROM_REG_2, 0x00 },
0344 { LP8860_EEPROM_REG_3, 0x00 },
0345 { LP8860_EEPROM_REG_4, 0x00 },
0346 { LP8860_EEPROM_REG_5, 0x00 },
0347 { LP8860_EEPROM_REG_6, 0x00 },
0348 { LP8860_EEPROM_REG_7, 0x00 },
0349 { LP8860_EEPROM_REG_8, 0x00 },
0350 { LP8860_EEPROM_REG_9, 0x00 },
0351 { LP8860_EEPROM_REG_10, 0x00 },
0352 { LP8860_EEPROM_REG_11, 0x00 },
0353 { LP8860_EEPROM_REG_12, 0x00 },
0354 { LP8860_EEPROM_REG_13, 0x00 },
0355 { LP8860_EEPROM_REG_14, 0x00 },
0356 { LP8860_EEPROM_REG_15, 0x00 },
0357 { LP8860_EEPROM_REG_16, 0x00 },
0358 { LP8860_EEPROM_REG_17, 0x00 },
0359 { LP8860_EEPROM_REG_18, 0x00 },
0360 { LP8860_EEPROM_REG_19, 0x00 },
0361 { LP8860_EEPROM_REG_20, 0x00 },
0362 { LP8860_EEPROM_REG_21, 0x00 },
0363 { LP8860_EEPROM_REG_22, 0x00 },
0364 { LP8860_EEPROM_REG_23, 0x00 },
0365 { LP8860_EEPROM_REG_24, 0x00 },
0366 };
0367
0368 static const struct regmap_config lp8860_eeprom_regmap_config = {
0369 .reg_bits = 8,
0370 .val_bits = 8,
0371
0372 .max_register = LP8860_EEPROM_REG_24,
0373 .reg_defaults = lp8860_eeprom_defs,
0374 .num_reg_defaults = ARRAY_SIZE(lp8860_eeprom_defs),
0375 .cache_type = REGCACHE_NONE,
0376 };
0377
0378 static int lp8860_probe(struct i2c_client *client,
0379 const struct i2c_device_id *id)
0380 {
0381 int ret;
0382 struct lp8860_led *led;
0383 struct device_node *np = dev_of_node(&client->dev);
0384 struct device_node *child_node;
0385 struct led_init_data init_data = {};
0386
0387 led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL);
0388 if (!led)
0389 return -ENOMEM;
0390
0391 child_node = of_get_next_available_child(np, NULL);
0392 if (!child_node)
0393 return -EINVAL;
0394
0395 led->enable_gpio = devm_gpiod_get_optional(&client->dev,
0396 "enable", GPIOD_OUT_LOW);
0397 if (IS_ERR(led->enable_gpio)) {
0398 ret = PTR_ERR(led->enable_gpio);
0399 dev_err(&client->dev, "Failed to get enable gpio: %d\n", ret);
0400 return ret;
0401 }
0402
0403 led->regulator = devm_regulator_get(&client->dev, "vled");
0404 if (IS_ERR(led->regulator))
0405 led->regulator = NULL;
0406
0407 led->client = client;
0408 led->led_dev.brightness_set_blocking = lp8860_brightness_set;
0409
0410 mutex_init(&led->lock);
0411
0412 i2c_set_clientdata(client, led);
0413
0414 led->regmap = devm_regmap_init_i2c(client, &lp8860_regmap_config);
0415 if (IS_ERR(led->regmap)) {
0416 ret = PTR_ERR(led->regmap);
0417 dev_err(&client->dev, "Failed to allocate register map: %d\n",
0418 ret);
0419 return ret;
0420 }
0421
0422 led->eeprom_regmap = devm_regmap_init_i2c(client, &lp8860_eeprom_regmap_config);
0423 if (IS_ERR(led->eeprom_regmap)) {
0424 ret = PTR_ERR(led->eeprom_regmap);
0425 dev_err(&client->dev, "Failed to allocate register map: %d\n",
0426 ret);
0427 return ret;
0428 }
0429
0430 ret = lp8860_init(led);
0431 if (ret)
0432 return ret;
0433
0434 init_data.fwnode = of_fwnode_handle(child_node);
0435 init_data.devicename = LP8860_NAME;
0436 init_data.default_label = ":display_cluster";
0437
0438 ret = devm_led_classdev_register_ext(&client->dev, &led->led_dev,
0439 &init_data);
0440 if (ret) {
0441 dev_err(&client->dev, "led register err: %d\n", ret);
0442 return ret;
0443 }
0444
0445 return 0;
0446 }
0447
0448 static int lp8860_remove(struct i2c_client *client)
0449 {
0450 struct lp8860_led *led = i2c_get_clientdata(client);
0451 int ret;
0452
0453 if (led->enable_gpio)
0454 gpiod_direction_output(led->enable_gpio, 0);
0455
0456 if (led->regulator) {
0457 ret = regulator_disable(led->regulator);
0458 if (ret)
0459 dev_err(&led->client->dev,
0460 "Failed to disable regulator\n");
0461 }
0462
0463 mutex_destroy(&led->lock);
0464
0465 return 0;
0466 }
0467
0468 static const struct i2c_device_id lp8860_id[] = {
0469 { "lp8860", 0 },
0470 { }
0471 };
0472 MODULE_DEVICE_TABLE(i2c, lp8860_id);
0473
0474 static const struct of_device_id of_lp8860_leds_match[] = {
0475 { .compatible = "ti,lp8860", },
0476 {},
0477 };
0478 MODULE_DEVICE_TABLE(of, of_lp8860_leds_match);
0479
0480 static struct i2c_driver lp8860_driver = {
0481 .driver = {
0482 .name = "lp8860",
0483 .of_match_table = of_lp8860_leds_match,
0484 },
0485 .probe = lp8860_probe,
0486 .remove = lp8860_remove,
0487 .id_table = lp8860_id,
0488 };
0489 module_i2c_driver(lp8860_driver);
0490
0491 MODULE_DESCRIPTION("Texas Instruments LP8860 LED driver");
0492 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
0493 MODULE_LICENSE("GPL v2");