^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) * Simple driver for Texas Instruments LM355x LED Flash driver chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2012 Texas Instruments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/leds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/platform_data/leds-lm355x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) enum lm355x_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) CHIP_LM3554 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) CHIP_LM3556,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) enum lm355x_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) REG_FLAG = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) REG_TORCH_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) REG_TORCH_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) REG_STROBE_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) REG_FLASH_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) REG_INDI_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) REG_INDI_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) REG_OPMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) REG_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* operation mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) enum lm355x_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) MODE_SHDN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) MODE_INDIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) MODE_TORCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) MODE_FLASH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* register map info. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct lm355x_reg_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u8 regno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) u8 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) u8 shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct lm355x_chip_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) enum lm355x_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct led_classdev cdev_flash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct led_classdev cdev_torch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct led_classdev cdev_indicator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct lm355x_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned int last_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct lm355x_reg_data *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* specific indicator function for lm3556 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) enum lm3556_indic_pulse_time {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) PULSE_TIME_0_MS = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) PULSE_TIME_32_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) PULSE_TIME_64_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) PULSE_TIME_92_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) PULSE_TIME_128_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) PULSE_TIME_160_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) PULSE_TIME_196_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) PULSE_TIME_224_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) PULSE_TIME_256_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) PULSE_TIME_288_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) PULSE_TIME_320_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) PULSE_TIME_352_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) PULSE_TIME_384_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) PULSE_TIME_416_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) PULSE_TIME_448_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) PULSE_TIME_480_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) enum lm3556_indic_n_blank {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) INDIC_N_BLANK_0 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) INDIC_N_BLANK_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) INDIC_N_BLANK_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) INDIC_N_BLANK_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) INDIC_N_BLANK_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) INDIC_N_BLANK_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) INDIC_N_BLANK_6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) INDIC_N_BLANK_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) INDIC_N_BLANK_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) INDIC_N_BLANK_9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) INDIC_N_BLANK_10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) INDIC_N_BLANK_11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) INDIC_N_BLANK_12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) INDIC_N_BLANK_13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) INDIC_N_BLANK_14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) INDIC_N_BLANK_15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) enum lm3556_indic_period {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) INDIC_PERIOD_0 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) INDIC_PERIOD_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) INDIC_PERIOD_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) INDIC_PERIOD_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) INDIC_PERIOD_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) INDIC_PERIOD_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) INDIC_PERIOD_6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) INDIC_PERIOD_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define INDIC_PATTERN_SIZE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct indicator {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u8 blinking;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u8 period_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* indicator pattern data only for lm3556 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static struct indicator indicator_pattern[INDIC_PATTERN_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) [0] = {(INDIC_N_BLANK_1 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) [1] = {(INDIC_N_BLANK_15 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) [2] = {(INDIC_N_BLANK_10 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) [3] = {(INDIC_N_BLANK_5 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static struct lm355x_reg_data lm3554_regs[REG_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) [REG_FLAG] = {0xD0, 0xBF, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) [REG_TORCH_CFG] = {0xE0, 0x80, 7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) [REG_TORCH_CTRL] = {0xA0, 0x38, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) [REG_STROBE_CFG] = {0xE0, 0x04, 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) [REG_FLASH_CTRL] = {0xB0, 0x78, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) [REG_INDI_CFG] = {0xE0, 0x08, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) [REG_INDI_CTRL] = {0xA0, 0xC0, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) [REG_OPMODE] = {0xA0, 0x03, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static struct lm355x_reg_data lm3556_regs[REG_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) [REG_FLAG] = {0x0B, 0xFF, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) [REG_TORCH_CFG] = {0x0A, 0x10, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) [REG_TORCH_CTRL] = {0x09, 0x70, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) [REG_STROBE_CFG] = {0x0A, 0x20, 5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) [REG_FLASH_CTRL] = {0x09, 0x0F, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) [REG_INDI_CFG] = {0xFF, 0xFF, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) [REG_INDI_CTRL] = {0x09, 0x70, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) [REG_OPMODE] = {0x0A, 0x03, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static char lm355x_name[][I2C_NAME_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) [CHIP_LM3554] = LM3554_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) [CHIP_LM3556] = LM3556_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* chip initialize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int lm355x_chip_init(struct lm355x_chip_data *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned int reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct lm355x_platform_data *pdata = chip->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* input and output pins configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) switch (chip->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case CHIP_LM3554:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) reg_val = (u32)pdata->pin_tx2 | (u32)pdata->ntc_pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ret = regmap_update_bits(chip->regmap, 0xE0, 0x28, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) reg_val = (u32)pdata->pass_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ret = regmap_update_bits(chip->regmap, 0xA0, 0x04, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case CHIP_LM3556:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) reg_val = (u32)pdata->pin_tx2 | (u32)pdata->ntc_pin |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) (u32)pdata->pass_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ret = regmap_update_bits(chip->regmap, 0x0A, 0xC4, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* chip control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int lm355x_control(struct lm355x_chip_data *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u8 brightness, enum lm355x_mode opmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned int reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct lm355x_platform_data *pdata = chip->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct lm355x_reg_data *preg = chip->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ret = regmap_read(chip->regmap, preg[REG_FLAG].regno, &chip->last_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (chip->last_flag & preg[REG_FLAG].mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) dev_info(chip->dev, "%s Last FLAG is 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) lm355x_name[chip->type],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) chip->last_flag & preg[REG_FLAG].mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* brightness 0 means shutdown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (!brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) opmode = MODE_SHDN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) switch (opmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case MODE_TORCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) regmap_update_bits(chip->regmap, preg[REG_TORCH_CTRL].regno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) preg[REG_TORCH_CTRL].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) (brightness - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) << preg[REG_TORCH_CTRL].shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (pdata->pin_tx1 != LM355x_PIN_TORCH_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) regmap_update_bits(chip->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) preg[REG_TORCH_CFG].regno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) preg[REG_TORCH_CFG].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 0x01 <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) preg[REG_TORCH_CFG].shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) opmode = MODE_SHDN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) dev_info(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) "torch brt is set - ext. torch pin mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) case MODE_FLASH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) regmap_update_bits(chip->regmap, preg[REG_FLASH_CTRL].regno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) preg[REG_FLASH_CTRL].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) (brightness - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) << preg[REG_FLASH_CTRL].shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (pdata->pin_strobe != LM355x_PIN_STROBE_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (chip->type == CHIP_LM3554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) reg_val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) reg_val = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) regmap_update_bits(chip->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) preg[REG_STROBE_CFG].regno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) preg[REG_STROBE_CFG].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) reg_val <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) preg[REG_STROBE_CFG].shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) opmode = MODE_SHDN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) dev_info(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) "flash brt is set - ext. strobe pin mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) case MODE_INDIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) regmap_update_bits(chip->regmap, preg[REG_INDI_CTRL].regno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) preg[REG_INDI_CTRL].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) (brightness - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) << preg[REG_INDI_CTRL].shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (pdata->pin_tx2 != LM355x_PIN_TX_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) regmap_update_bits(chip->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) preg[REG_INDI_CFG].regno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) preg[REG_INDI_CFG].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 0x01 <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) preg[REG_INDI_CFG].shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) opmode = MODE_SHDN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) case MODE_SHDN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /* operation mode control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ret = regmap_update_bits(chip->regmap, preg[REG_OPMODE].regno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) preg[REG_OPMODE].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) opmode << preg[REG_OPMODE].shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* torch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static int lm355x_torch_brightness_set(struct led_classdev *cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) enum led_brightness brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct lm355x_chip_data *chip =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) container_of(cdev, struct lm355x_chip_data, cdev_torch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ret = lm355x_control(chip, brightness, MODE_TORCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* flash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static int lm355x_strobe_brightness_set(struct led_classdev *cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) enum led_brightness brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct lm355x_chip_data *chip =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) container_of(cdev, struct lm355x_chip_data, cdev_flash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ret = lm355x_control(chip, brightness, MODE_FLASH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* indicator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int lm355x_indicator_brightness_set(struct led_classdev *cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) enum led_brightness brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct lm355x_chip_data *chip =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) container_of(cdev, struct lm355x_chip_data, cdev_indicator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ret = lm355x_control(chip, brightness, MODE_INDIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* indicator pattern only for lm3556*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static ssize_t lm3556_indicator_pattern_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) const char *buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct led_classdev *led_cdev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct lm355x_chip_data *chip =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) container_of(led_cdev, struct lm355x_chip_data, cdev_indicator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) unsigned int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ret = kstrtouint(buf, 10, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (state > INDIC_PATTERN_SIZE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) state = INDIC_PATTERN_SIZE - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ret = regmap_write(chip->regmap, 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) indicator_pattern[state].blinking);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret = regmap_write(chip->regmap, 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) indicator_pattern[state].period_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static DEVICE_ATTR(pattern, S_IWUSR, NULL, lm3556_indicator_pattern_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static struct attribute *lm355x_indicator_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) &dev_attr_pattern.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ATTRIBUTE_GROUPS(lm355x_indicator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static const struct regmap_config lm355x_regmap = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .max_register = 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* module initialize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static int lm355x_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct lm355x_platform_data *pdata = dev_get_platdata(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct lm355x_chip_data *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dev_err(&client->dev, "i2c functionality check fail.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (pdata == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) dev_err(&client->dev, "needs Platform Data.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) chip = devm_kzalloc(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) sizeof(struct lm355x_chip_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) chip->dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) chip->type = id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) switch (id->driver_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) case CHIP_LM3554:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) chip->regs = lm3554_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) case CHIP_LM3556:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) chip->regs = lm3556_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) chip->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) chip->regmap = devm_regmap_init_i2c(client, &lm355x_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (IS_ERR(chip->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) err = PTR_ERR(chip->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) "Failed to allocate register map: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) mutex_init(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) i2c_set_clientdata(client, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) err = lm355x_chip_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* flash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) chip->cdev_flash.name = "flash";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) chip->cdev_flash.max_brightness = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) chip->cdev_flash.brightness_set_blocking = lm355x_strobe_brightness_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) chip->cdev_flash.default_trigger = "flash";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) err = led_classdev_register(&client->dev, &chip->cdev_flash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* torch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) chip->cdev_torch.name = "torch";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) chip->cdev_torch.max_brightness = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) chip->cdev_torch.brightness_set_blocking = lm355x_torch_brightness_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) chip->cdev_torch.default_trigger = "torch";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) err = led_classdev_register(&client->dev, &chip->cdev_torch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) goto err_create_torch_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* indicator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) chip->cdev_indicator.name = "indicator";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (id->driver_data == CHIP_LM3554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) chip->cdev_indicator.max_brightness = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) chip->cdev_indicator.max_brightness = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) chip->cdev_indicator.brightness_set_blocking =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) lm355x_indicator_brightness_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /* indicator pattern control only for LM3556 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (id->driver_data == CHIP_LM3556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) chip->cdev_indicator.groups = lm355x_indicator_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) err = led_classdev_register(&client->dev, &chip->cdev_indicator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) goto err_create_indicator_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) dev_info(&client->dev, "%s is initialized\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) lm355x_name[id->driver_data]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) err_create_indicator_file:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) led_classdev_unregister(&chip->cdev_torch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) err_create_torch_file:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) led_classdev_unregister(&chip->cdev_flash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static int lm355x_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct lm355x_chip_data *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct lm355x_reg_data *preg = chip->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) regmap_write(chip->regmap, preg[REG_OPMODE].regno, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) led_classdev_unregister(&chip->cdev_indicator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) led_classdev_unregister(&chip->cdev_torch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) led_classdev_unregister(&chip->cdev_flash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) dev_info(&client->dev, "%s is removed\n", lm355x_name[chip->type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static const struct i2c_device_id lm355x_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {LM3554_NAME, CHIP_LM3554},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {LM3556_NAME, CHIP_LM3556},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) MODULE_DEVICE_TABLE(i2c, lm355x_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static struct i2c_driver lm355x_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .name = LM355x_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) .pm = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .probe = lm355x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .remove = lm355x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) .id_table = lm355x_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) module_i2c_driver(lm355x_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM355x");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) MODULE_LICENSE("GPL v2");