^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 LP855x Backlight Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2011 Texas Instruments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^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/backlight.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/platform_data/lp855x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/pwm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* LP8550/1/2/3/6 Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define LP855X_BRIGHTNESS_CTRL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define LP855X_DEVICE_CTRL 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define LP855X_EEPROM_START 0xA0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define LP855X_EEPROM_END 0xA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define LP8556_EPROM_START 0xA0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define LP8556_EPROM_END 0xAF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* LP8555/7 Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define LP8557_BL_CMD 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define LP8557_BL_MASK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define LP8557_BL_ON 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define LP8557_BL_OFF 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define LP8557_BRIGHTNESS_CTRL 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define LP8557_CONFIG 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define LP8555_EPROM_START 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define LP8555_EPROM_END 0x7A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define LP8557_EPROM_START 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define LP8557_EPROM_END 0x1E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define DEFAULT_BL_NAME "lcd-backlight"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MAX_BRIGHTNESS 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) enum lp855x_brightness_ctrl_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) PWM_BASED = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) REGISTER_BASED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct lp855x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * struct lp855x_device_config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * @pre_init_device: init device function call before updating the brightness
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * @reg_brightness: register address for brigthenss control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * @reg_devicectrl: register address for device control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * @post_init_device: late init device function call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct lp855x_device_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int (*pre_init_device)(struct lp855x *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u8 reg_brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u8 reg_devicectrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int (*post_init_device)(struct lp855x *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct lp855x {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) const char *chipname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) enum lp855x_chip_id chip_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) enum lp855x_brightness_ctrl_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct lp855x_device_config *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct backlight_device *bl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct lp855x_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct pwm_device *pwm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct regulator *supply; /* regulator for VDD input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct regulator *enable; /* regulator for EN/VDDIO input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return i2c_smbus_write_byte_data(lp->client, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static int lp855x_update_bit(struct lp855x *lp, u8 reg, u8 mask, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ret = i2c_smbus_read_byte_data(lp->client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) tmp = (u8)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) tmp &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) tmp |= data & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return lp855x_write_byte(lp, reg, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u8 start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) switch (lp->chip_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) case LP8550:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) case LP8551:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) case LP8552:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) case LP8553:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) start = LP855X_EEPROM_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) end = LP855X_EEPROM_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) case LP8556:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) start = LP8556_EPROM_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) end = LP8556_EPROM_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case LP8555:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) start = LP8555_EPROM_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) end = LP8555_EPROM_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) case LP8557:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) start = LP8557_EPROM_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) end = LP8557_EPROM_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return addr >= start && addr <= end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int lp8557_bl_off(struct lp855x *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* BL_ON = 0 before updating EPROM settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) LP8557_BL_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int lp8557_bl_on(struct lp855x *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* BL_ON = 1 after updating EPROM settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) LP8557_BL_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static struct lp855x_device_config lp855x_dev_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .reg_brightness = LP855X_BRIGHTNESS_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .reg_devicectrl = LP855X_DEVICE_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static struct lp855x_device_config lp8557_dev_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .reg_brightness = LP8557_BRIGHTNESS_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .reg_devicectrl = LP8557_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .pre_init_device = lp8557_bl_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .post_init_device = lp8557_bl_on,
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * Device specific configuration flow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * a) pre_init_device(optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * b) update the brightness register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * c) update device control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * d) update ROM area(optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * e) post_init_device(optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int lp855x_configure(struct lp855x *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u8 val, addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct lp855x_platform_data *pd = lp->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) switch (lp->chip_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) case LP8550:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) case LP8551:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case LP8552:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case LP8553:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case LP8556:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) lp->cfg = &lp855x_dev_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case LP8555:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case LP8557:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) lp->cfg = &lp8557_dev_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (lp->cfg->pre_init_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ret = lp->cfg->pre_init_device(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) dev_err(lp->dev, "pre init device err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) val = pd->initial_brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ret = lp855x_write_byte(lp, lp->cfg->reg_brightness, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) val = pd->device_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ret = lp855x_write_byte(lp, lp->cfg->reg_devicectrl, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (pd->size_program > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) for (i = 0; i < pd->size_program; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) addr = pd->rom_data[i].addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) val = pd->rom_data[i].val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (!lp855x_is_valid_rom_area(lp, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ret = lp855x_write_byte(lp, addr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (lp->cfg->post_init_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ret = lp->cfg->post_init_device(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) dev_err(lp->dev, "post init device err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^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) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) unsigned int period = lp->pdata->period_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) unsigned int duty = br * period / max_br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct pwm_device *pwm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* request pwm device with the consumer name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (!lp->pwm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) pwm = devm_pwm_get(lp->dev, lp->chipname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (IS_ERR(pwm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) lp->pwm = pwm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * FIXME: pwm_apply_args() should be removed when switching to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * the atomic PWM API.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) pwm_apply_args(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) pwm_config(lp->pwm, duty, period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (duty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) pwm_enable(lp->pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) pwm_disable(lp->pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static int lp855x_bl_update_status(struct backlight_device *bl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct lp855x *lp = bl_get_data(bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int brightness = bl->props.brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) brightness = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (lp->mode == PWM_BASED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) lp855x_pwm_ctrl(lp, brightness, bl->props.max_brightness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) else if (lp->mode == REGISTER_BASED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) lp855x_write_byte(lp, lp->cfg->reg_brightness, (u8)brightness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static const struct backlight_ops lp855x_bl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .options = BL_CORE_SUSPENDRESUME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .update_status = lp855x_bl_update_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static int lp855x_backlight_register(struct lp855x *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct backlight_device *bl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct backlight_properties props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct lp855x_platform_data *pdata = lp->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) const char *name = pdata->name ? : DEFAULT_BL_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) memset(&props, 0, sizeof(props));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) props.type = BACKLIGHT_PLATFORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) props.max_brightness = MAX_BRIGHTNESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (pdata->initial_brightness > props.max_brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) pdata->initial_brightness = props.max_brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) props.brightness = pdata->initial_brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) bl = devm_backlight_device_register(lp->dev, name, lp->dev, lp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) &lp855x_bl_ops, &props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (IS_ERR(bl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return PTR_ERR(bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) lp->bl = bl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static ssize_t lp855x_get_chip_id(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct lp855x *lp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return scnprintf(buf, PAGE_SIZE, "%s\n", lp->chipname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static ssize_t lp855x_get_bl_ctl_mode(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct lp855x *lp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) char *strmode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (lp->mode == PWM_BASED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) strmode = "pwm based";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) else if (lp->mode == REGISTER_BASED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) strmode = "register based";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return scnprintf(buf, PAGE_SIZE, "%s\n", strmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static DEVICE_ATTR(chip_id, S_IRUGO, lp855x_get_chip_id, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp855x_get_bl_ctl_mode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static struct attribute *lp855x_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) &dev_attr_chip_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) &dev_attr_bl_ctl_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) NULL,
^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 attribute_group lp855x_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .attrs = lp855x_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int lp855x_parse_dt(struct lp855x *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct device *dev = lp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct device_node *node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct lp855x_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int rom_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) dev_err(dev, "no platform data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) of_property_read_string(node, "bl-name", &pdata->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) of_property_read_u8(node, "dev-ctrl", &pdata->device_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) of_property_read_u8(node, "init-brt", &pdata->initial_brightness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) of_property_read_u32(node, "pwm-period", &pdata->period_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* Fill ROM platform data if defined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) rom_length = of_get_child_count(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (rom_length > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct lp855x_rom_data *rom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) rom = devm_kcalloc(dev, rom_length, sizeof(*rom), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (!rom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) for_each_child_of_node(node, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) of_property_read_u8(child, "rom-addr", &rom[i].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) of_property_read_u8(child, "rom-val", &rom[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) pdata->size_program = rom_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) pdata->rom_data = &rom[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) lp->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static int lp855x_parse_dt(struct lp855x *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct lp855x *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) lp = devm_kzalloc(&cl->dev, sizeof(struct lp855x), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (!lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) lp->client = cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) lp->dev = &cl->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) lp->chipname = id->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) lp->chip_id = id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) lp->pdata = dev_get_platdata(&cl->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (!lp->pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ret = lp855x_parse_dt(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (ret < 0)
^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) if (lp->pdata->period_ns > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) lp->mode = PWM_BASED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) lp->mode = REGISTER_BASED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) lp->supply = devm_regulator_get(lp->dev, "power");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (IS_ERR(lp->supply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (PTR_ERR(lp->supply) == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) lp->supply = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) lp->enable = devm_regulator_get_optional(lp->dev, "enable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (IS_ERR(lp->enable)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ret = PTR_ERR(lp->enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (ret == -ENODEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) lp->enable = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (ret != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dev_err(lp->dev, "error getting enable regulator: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (lp->supply) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ret = regulator_enable(lp->supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dev_err(&cl->dev, "failed to enable supply: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (lp->enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ret = regulator_enable(lp->enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) dev_err(lp->dev, "failed to enable vddio: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) goto disable_supply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^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) * LP8555 datasheet says t_RESPONSE (time between VDDIO and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * I2C) is 1ms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) i2c_set_clientdata(cl, lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ret = lp855x_configure(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) dev_err(lp->dev, "device config err: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) goto disable_vddio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ret = lp855x_backlight_register(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) dev_err(lp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) "failed to register backlight. err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) goto disable_vddio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ret = sysfs_create_group(&lp->dev->kobj, &lp855x_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) goto disable_vddio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) backlight_update_status(lp->bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) disable_vddio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (lp->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) regulator_disable(lp->enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) disable_supply:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (lp->supply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) regulator_disable(lp->supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static int lp855x_remove(struct i2c_client *cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct lp855x *lp = i2c_get_clientdata(cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) lp->bl->props.brightness = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) backlight_update_status(lp->bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (lp->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) regulator_disable(lp->enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (lp->supply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) regulator_disable(lp->supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static const struct of_device_id lp855x_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) { .compatible = "ti,lp8550", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) { .compatible = "ti,lp8551", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) { .compatible = "ti,lp8552", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) { .compatible = "ti,lp8553", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) { .compatible = "ti,lp8555", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) { .compatible = "ti,lp8556", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) { .compatible = "ti,lp8557", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) MODULE_DEVICE_TABLE(of, lp855x_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static const struct i2c_device_id lp855x_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {"lp8550", LP8550},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {"lp8551", LP8551},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {"lp8552", LP8552},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {"lp8553", LP8553},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {"lp8555", LP8555},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {"lp8556", LP8556},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {"lp8557", LP8557},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) MODULE_DEVICE_TABLE(i2c, lp855x_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static struct i2c_driver lp855x_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .name = "lp855x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .of_match_table = of_match_ptr(lp855x_dt_ids),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .probe = lp855x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .remove = lp855x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .id_table = lp855x_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) module_i2c_driver(lp855x_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) MODULE_DESCRIPTION("Texas Instruments LP855x Backlight driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) MODULE_LICENSE("GPL");