^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * TI LP8860 4-Channel LED Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2014 Texas Instruments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Dan Murphy <dmurphy@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/leds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define LP8860_DISP_CL1_BRT_MSB 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define LP8860_DISP_CL1_BRT_LSB 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define LP8860_DISP_CL1_CURR_MSB 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define LP8860_DISP_CL1_CURR_LSB 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define LP8860_CL2_BRT_MSB 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define LP8860_CL2_BRT_LSB 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define LP8860_CL2_CURRENT 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define LP8860_CL3_BRT_MSB 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define LP8860_CL3_BRT_LSB 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define LP8860_CL3_CURRENT 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define LP8860_CL4_BRT_MSB 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define LP8860_CL4_BRT_LSB 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define LP8860_CL4_CURRENT 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define LP8860_CONFIG 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define LP8860_STATUS 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define LP8860_FAULT 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define LP8860_LED_FAULT 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define LP8860_FAULT_CLEAR 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define LP8860_ID 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define LP8860_TEMP_MSB 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define LP8860_TEMP_LSB 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define LP8860_DISP_LED_CURR_MSB 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define LP8860_DISP_LED_CURR_LSB 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define LP8860_DISP_LED_PWM_MSB 0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define LP8860_DISP_LED_PWM_LSB 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define LP8860_EEPROM_CNTRL 0x19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define LP8860_EEPROM_UNLOCK 0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define LP8860_EEPROM_REG_0 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define LP8860_EEPROM_REG_1 0x61
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define LP8860_EEPROM_REG_2 0x62
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define LP8860_EEPROM_REG_3 0x63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define LP8860_EEPROM_REG_4 0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define LP8860_EEPROM_REG_5 0x65
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define LP8860_EEPROM_REG_6 0x66
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define LP8860_EEPROM_REG_7 0x67
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define LP8860_EEPROM_REG_8 0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define LP8860_EEPROM_REG_9 0x69
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define LP8860_EEPROM_REG_10 0x6a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define LP8860_EEPROM_REG_11 0x6b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define LP8860_EEPROM_REG_12 0x6c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define LP8860_EEPROM_REG_13 0x6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define LP8860_EEPROM_REG_14 0x6e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define LP8860_EEPROM_REG_15 0x6f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define LP8860_EEPROM_REG_16 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define LP8860_EEPROM_REG_17 0x71
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define LP8860_EEPROM_REG_18 0x72
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define LP8860_EEPROM_REG_19 0x73
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define LP8860_EEPROM_REG_20 0x74
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define LP8860_EEPROM_REG_21 0x75
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define LP8860_EEPROM_REG_22 0x76
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define LP8860_EEPROM_REG_23 0x77
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define LP8860_EEPROM_REG_24 0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define LP8860_LOCK_EEPROM 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define LP8860_UNLOCK_EEPROM 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define LP8860_PROGRAM_EEPROM 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define LP8860_EEPROM_CODE_1 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define LP8860_EEPROM_CODE_2 0xba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define LP8860_EEPROM_CODE_3 0xef
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define LP8860_CLEAR_FAULTS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define LP8860_NAME "lp8860"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * struct lp8860_led -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @lock - Lock for reading/writing the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @client - Pointer to the I2C client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @led_dev - led class device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @regmap - Devices register map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * @eeprom_regmap - EEPROM register map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * @enable_gpio - VDDIO/EN gpio to enable communication interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * @regulator - LED supply regulator pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct lp8860_led {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct led_classdev led_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct regmap *eeprom_regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct gpio_desc *enable_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct regulator *regulator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct lp8860_eeprom_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) uint8_t reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) uint8_t value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static struct lp8860_eeprom_reg lp8860_eeprom_disp_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) { LP8860_EEPROM_REG_0, 0xed },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) { LP8860_EEPROM_REG_1, 0xdf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) { LP8860_EEPROM_REG_2, 0xdc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) { LP8860_EEPROM_REG_3, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) { LP8860_EEPROM_REG_4, 0xdf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) { LP8860_EEPROM_REG_5, 0xe5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) { LP8860_EEPROM_REG_6, 0xf2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) { LP8860_EEPROM_REG_7, 0x77 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) { LP8860_EEPROM_REG_8, 0x77 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) { LP8860_EEPROM_REG_9, 0x71 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) { LP8860_EEPROM_REG_10, 0x3f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) { LP8860_EEPROM_REG_11, 0xb7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) { LP8860_EEPROM_REG_12, 0x17 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) { LP8860_EEPROM_REG_13, 0xef },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) { LP8860_EEPROM_REG_14, 0xb0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) { LP8860_EEPROM_REG_15, 0x87 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) { LP8860_EEPROM_REG_16, 0xce },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) { LP8860_EEPROM_REG_17, 0x72 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) { LP8860_EEPROM_REG_18, 0xe5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) { LP8860_EEPROM_REG_19, 0xdf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) { LP8860_EEPROM_REG_20, 0x35 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) { LP8860_EEPROM_REG_21, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) { LP8860_EEPROM_REG_22, 0xdc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) { LP8860_EEPROM_REG_23, 0x88 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) { LP8860_EEPROM_REG_24, 0x3E },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int lp8860_unlock_eeprom(struct lp8860_led *led, int lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) mutex_lock(&led->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (lock == LP8860_UNLOCK_EEPROM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ret = regmap_write(led->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) LP8860_EEPROM_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) LP8860_EEPROM_CODE_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) dev_err(&led->client->dev, "EEPROM Unlock failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ret = regmap_write(led->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) LP8860_EEPROM_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) LP8860_EEPROM_CODE_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dev_err(&led->client->dev, "EEPROM Unlock failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ret = regmap_write(led->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) LP8860_EEPROM_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) LP8860_EEPROM_CODE_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) dev_err(&led->client->dev, "EEPROM Unlock failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ret = regmap_write(led->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) LP8860_EEPROM_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) LP8860_LOCK_EEPROM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mutex_unlock(&led->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int lp8860_fault_check(struct lp8860_led *led)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int ret, fault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) unsigned int read_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ret = regmap_read(led->regmap, LP8860_LED_FAULT, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) fault = read_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ret = regmap_read(led->regmap, LP8860_FAULT, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) fault |= read_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* Attempt to clear any faults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (fault)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ret = regmap_write(led->regmap, LP8860_FAULT_CLEAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) LP8860_CLEAR_FAULTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int lp8860_brightness_set(struct led_classdev *led_cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) enum led_brightness brt_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct lp8860_led *led =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) container_of(led_cdev, struct lp8860_led, led_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int disp_brightness = brt_val * 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) mutex_lock(&led->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ret = lp8860_fault_check(led);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) dev_err(&led->client->dev, "Cannot read/clear faults\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ret = regmap_write(led->regmap, LP8860_DISP_CL1_BRT_MSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) (disp_brightness & 0xff00) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) dev_err(&led->client->dev, "Cannot write CL1 MSB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) ret = regmap_write(led->regmap, LP8860_DISP_CL1_BRT_LSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) disp_brightness & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dev_err(&led->client->dev, "Cannot write CL1 LSB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) mutex_unlock(&led->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int lp8860_init(struct lp8860_led *led)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) unsigned int read_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int ret, i, reg_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (led->regulator) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ret = regulator_enable(led->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) dev_err(&led->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) "Failed to enable regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (led->enable_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) gpiod_direction_output(led->enable_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ret = lp8860_fault_check(led);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ret = regmap_read(led->regmap, LP8860_STATUS, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ret = lp8860_unlock_eeprom(led, LP8860_UNLOCK_EEPROM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dev_err(&led->client->dev, "Failed unlocking EEPROM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs) / sizeof(lp8860_eeprom_disp_regs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) for (i = 0; i < reg_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ret = regmap_write(led->eeprom_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) lp8860_eeprom_disp_regs[i].reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) lp8860_eeprom_disp_regs[i].value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dev_err(&led->client->dev, "Failed writing EEPROM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ret = lp8860_unlock_eeprom(led, LP8860_LOCK_EEPROM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ret = regmap_write(led->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) LP8860_EEPROM_CNTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) LP8860_PROGRAM_EEPROM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dev_err(&led->client->dev, "Failed programming EEPROM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (led->enable_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) gpiod_direction_output(led->enable_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (led->regulator) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ret = regulator_disable(led->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) dev_err(&led->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) "Failed to disable regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static const struct reg_default lp8860_reg_defs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) { LP8860_DISP_CL1_BRT_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) { LP8860_DISP_CL1_BRT_LSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) { LP8860_DISP_CL1_CURR_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) { LP8860_DISP_CL1_CURR_LSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) { LP8860_CL2_BRT_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) { LP8860_CL2_BRT_LSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) { LP8860_CL2_CURRENT, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) { LP8860_CL3_BRT_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) { LP8860_CL3_BRT_LSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) { LP8860_CL3_CURRENT, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) { LP8860_CL4_BRT_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) { LP8860_CL4_BRT_LSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) { LP8860_CL4_CURRENT, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) { LP8860_CONFIG, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) { LP8860_FAULT_CLEAR, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) { LP8860_EEPROM_CNTRL, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) { LP8860_EEPROM_UNLOCK, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static const struct regmap_config lp8860_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) .max_register = LP8860_EEPROM_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .reg_defaults = lp8860_reg_defs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .num_reg_defaults = ARRAY_SIZE(lp8860_reg_defs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .cache_type = REGCACHE_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static const struct reg_default lp8860_eeprom_defs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) { LP8860_EEPROM_REG_0, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) { LP8860_EEPROM_REG_1, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) { LP8860_EEPROM_REG_2, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) { LP8860_EEPROM_REG_3, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) { LP8860_EEPROM_REG_4, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) { LP8860_EEPROM_REG_5, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) { LP8860_EEPROM_REG_6, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) { LP8860_EEPROM_REG_7, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) { LP8860_EEPROM_REG_8, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) { LP8860_EEPROM_REG_9, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) { LP8860_EEPROM_REG_10, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) { LP8860_EEPROM_REG_11, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) { LP8860_EEPROM_REG_12, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) { LP8860_EEPROM_REG_13, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) { LP8860_EEPROM_REG_14, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) { LP8860_EEPROM_REG_15, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) { LP8860_EEPROM_REG_16, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) { LP8860_EEPROM_REG_17, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) { LP8860_EEPROM_REG_18, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) { LP8860_EEPROM_REG_19, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) { LP8860_EEPROM_REG_20, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) { LP8860_EEPROM_REG_21, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) { LP8860_EEPROM_REG_22, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) { LP8860_EEPROM_REG_23, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) { LP8860_EEPROM_REG_24, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static const struct regmap_config lp8860_eeprom_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .max_register = LP8860_EEPROM_REG_24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .reg_defaults = lp8860_eeprom_defs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .num_reg_defaults = ARRAY_SIZE(lp8860_eeprom_defs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) .cache_type = REGCACHE_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int lp8860_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct lp8860_led *led;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct device_node *np = dev_of_node(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct device_node *child_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct led_init_data init_data = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!led)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) child_node = of_get_next_available_child(np, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (!child_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) led->enable_gpio = devm_gpiod_get_optional(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) "enable", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (IS_ERR(led->enable_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ret = PTR_ERR(led->enable_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) dev_err(&client->dev, "Failed to get enable gpio: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) led->regulator = devm_regulator_get(&client->dev, "vled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (IS_ERR(led->regulator))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) led->regulator = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) led->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) led->led_dev.brightness_set_blocking = lp8860_brightness_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) mutex_init(&led->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) i2c_set_clientdata(client, led);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) led->regmap = devm_regmap_init_i2c(client, &lp8860_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (IS_ERR(led->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ret = PTR_ERR(led->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) dev_err(&client->dev, "Failed to allocate register map: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) led->eeprom_regmap = devm_regmap_init_i2c(client, &lp8860_eeprom_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (IS_ERR(led->eeprom_regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ret = PTR_ERR(led->eeprom_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) dev_err(&client->dev, "Failed to allocate register map: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret = lp8860_init(led);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) init_data.fwnode = of_fwnode_handle(child_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) init_data.devicename = LP8860_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) init_data.default_label = ":display_cluster";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ret = devm_led_classdev_register_ext(&client->dev, &led->led_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) &init_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dev_err(&client->dev, "led register err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int lp8860_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct lp8860_led *led = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (led->enable_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) gpiod_direction_output(led->enable_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (led->regulator) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ret = regulator_disable(led->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) dev_err(&led->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) "Failed to disable regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) mutex_destroy(&led->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static const struct i2c_device_id lp8860_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) { "lp8860", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) MODULE_DEVICE_TABLE(i2c, lp8860_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static const struct of_device_id of_lp8860_leds_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) { .compatible = "ti,lp8860", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) MODULE_DEVICE_TABLE(of, of_lp8860_leds_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static struct i2c_driver lp8860_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .name = "lp8860",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .of_match_table = of_lp8860_leds_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .probe = lp8860_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .remove = lp8860_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .id_table = lp8860_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) module_i2c_driver(lp8860_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) MODULE_DESCRIPTION("Texas Instruments LP8860 LED driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) MODULE_LICENSE("GPL v2");