282 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * LP55XX Common Driver Header4 *5 * Copyright (C) 2012 Texas Instruments6 *7 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>8 *9 * Derived from leds-lp5521.c, leds-lp5523.c10 */11 12#ifndef _LEDS_LP55XX_COMMON_H13#define _LEDS_LP55XX_COMMON_H14 15#include <linux/led-class-multicolor.h>16 17#define LP55xx_BYTES_PER_PAGE 32 /* bytes */18 19enum lp55xx_engine_index {20 LP55XX_ENGINE_INVALID,21 LP55XX_ENGINE_1,22 LP55XX_ENGINE_2,23 LP55XX_ENGINE_3,24 LP55XX_ENGINE_MAX = LP55XX_ENGINE_3,25};26 27enum lp55xx_engine_mode {28 LP55XX_ENGINE_DISABLED,29 LP55XX_ENGINE_LOAD,30 LP55XX_ENGINE_RUN,31};32 33#define LP55XX_DEV_ATTR_RW(name, show, store) \34 DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show, store)35#define LP55XX_DEV_ATTR_RO(name, show) \36 DEVICE_ATTR(name, S_IRUGO, show, NULL)37#define LP55XX_DEV_ATTR_WO(name, store) \38 DEVICE_ATTR(name, S_IWUSR, NULL, store)39 40#define LP55XX_DEV_ATTR_ENGINE_MODE(nr) \41static ssize_t show_engine##nr##_mode(struct device *dev, \42 struct device_attribute *attr, \43 char *buf) \44{ \45 return lp55xx_show_engine_mode(dev, attr, buf, nr); \46} \47static ssize_t store_engine##nr##_mode(struct device *dev, \48 struct device_attribute *attr, \49 const char *buf, size_t len) \50{ \51 return lp55xx_store_engine_mode(dev, attr, buf, len, nr); \52} \53static LP55XX_DEV_ATTR_RW(engine##nr##_mode, show_engine##nr##_mode, \54 store_engine##nr##_mode)55 56#define LP55XX_DEV_ATTR_ENGINE_LEDS(nr) \57static ssize_t show_engine##nr##_leds(struct device *dev, \58 struct device_attribute *attr, \59 char *buf) \60{ \61 return lp55xx_show_engine_leds(dev, attr, buf, nr); \62} \63static ssize_t store_engine##nr##_leds(struct device *dev, \64 struct device_attribute *attr, \65 const char *buf, size_t len) \66{ \67 return lp55xx_store_engine_leds(dev, attr, buf, len, nr); \68} \69static LP55XX_DEV_ATTR_RW(engine##nr##_leds, show_engine##nr##_leds, \70 store_engine##nr##_leds)71 72#define LP55XX_DEV_ATTR_ENGINE_LOAD(nr) \73static ssize_t store_engine##nr##_load(struct device *dev, \74 struct device_attribute *attr, \75 const char *buf, size_t len) \76{ \77 return lp55xx_store_engine_load(dev, attr, buf, len, nr); \78} \79static LP55XX_DEV_ATTR_WO(engine##nr##_load, store_engine##nr##_load)80 81#define LP55XX_DEV_ATTR_MASTER_FADER(nr) \82static ssize_t show_master_fader##nr(struct device *dev, \83 struct device_attribute *attr, \84 char *buf) \85{ \86 return lp55xx_show_master_fader(dev, attr, buf, nr); \87} \88static ssize_t store_master_fader##nr(struct device *dev, \89 struct device_attribute *attr, \90 const char *buf, size_t len) \91{ \92 return lp55xx_store_master_fader(dev, attr, buf, len, nr); \93} \94static LP55XX_DEV_ATTR_RW(master_fader##nr, show_master_fader##nr, \95 store_master_fader##nr)96 97struct lp55xx_led;98struct lp55xx_chip;99 100/*101 * struct lp55xx_reg102 * @addr : Register address103 * @val : Register value (can also used as mask or shift)104 */105struct lp55xx_reg {106 u8 addr;107 union {108 u8 val;109 u8 mask;110 u8 shift;111 };112};113 114/*115 * struct lp55xx_device_config116 * @reg_op_mode : Chip specific OP MODE reg addr117 * @engine_busy : Chip specific engine busy118 * (if not supported 153 us sleep)119 * @reset : Chip specific reset command120 * @enable : Chip specific enable command121 * @prog_mem_base : Chip specific base reg address for chip SMEM programming122 * @reg_led_pwm_base : Chip specific base reg address for LED PWM conf123 * @reg_led_current_base : Chip specific base reg address for LED current conf124 * @reg_master_fader_base : Chip specific base reg address for master fader base125 * @reg_led_ctrl_base : Chip specific base reg address for LED ctrl base126 * @pages_per_engine : Assigned pages for each engine127 * (if not set chip doesn't support pages)128 * @max_channel : Maximum number of channels129 * @post_init_device : Chip specific initialization code130 * @brightness_fn : Brightness function131 * @multicolor_brightness_fn : Multicolor brightness function132 * @set_led_current : LED current set function133 * @firmware_cb : Call function when the firmware is loaded134 * @run_engine : Run internal engine for pattern135 * @dev_attr_group : Device specific attributes136 */137struct lp55xx_device_config {138 const struct lp55xx_reg reg_op_mode; /* addr, shift */139 const struct lp55xx_reg reg_exec; /* addr, shift */140 const struct lp55xx_reg engine_busy; /* addr, mask */141 const struct lp55xx_reg reset;142 const struct lp55xx_reg enable;143 const struct lp55xx_reg prog_mem_base;144 const struct lp55xx_reg reg_led_pwm_base;145 const struct lp55xx_reg reg_led_current_base;146 const struct lp55xx_reg reg_master_fader_base;147 const struct lp55xx_reg reg_led_ctrl_base;148 const int pages_per_engine;149 const int max_channel;150 151 /* define if the device has specific initialization process */152 int (*post_init_device) (struct lp55xx_chip *chip);153 154 /* set LED brightness */155 int (*brightness_fn)(struct lp55xx_led *led);156 157 /* set multicolor LED brightness */158 int (*multicolor_brightness_fn)(struct lp55xx_led *led);159 160 /* current setting function */161 void (*set_led_current) (struct lp55xx_led *led, u8 led_current);162 163 /* access program memory when the firmware is loaded */164 void (*firmware_cb)(struct lp55xx_chip *chip);165 166 /* used for running firmware LED patterns */167 void (*run_engine) (struct lp55xx_chip *chip, bool start);168 169 /* additional device specific attributes */170 const struct attribute_group *dev_attr_group;171};172 173/*174 * struct lp55xx_engine175 * @mode : Engine mode176 * @led_mux : Mux bits for LED selection. Only used in LP5523177 */178struct lp55xx_engine {179 enum lp55xx_engine_mode mode;180 u16 led_mux;181};182 183/*184 * struct lp55xx_chip185 * @cl : I2C communication for access registers186 * @pdata : Platform specific data187 * @lock : Lock for user-space interface188 * @num_leds : Number of registered LEDs189 * @cfg : Device specific configuration data190 * @engine_idx : Selected engine number191 * @engines : Engine structure for the device attribute R/W interface192 * @fw : Firmware data for running a LED pattern193 */194struct lp55xx_chip {195 struct i2c_client *cl;196 struct lp55xx_platform_data *pdata;197 struct mutex lock; /* lock for user-space interface */198 int num_leds;199 const struct lp55xx_device_config *cfg;200 enum lp55xx_engine_index engine_idx;201 struct lp55xx_engine engines[LP55XX_ENGINE_MAX];202 const struct firmware *fw;203};204 205/*206 * struct lp55xx_led207 * @chan_nr : Channel number208 * @cdev : LED class device209 * @mc_cdev : Multi color class device210 * @color_components: Multi color LED map information211 * @led_current : Current setting at each led channel212 * @max_current : Maximun current at each led channel213 * @brightness : Brightness value214 * @chip : The lp55xx chip data215 */216struct lp55xx_led {217 int chan_nr;218 struct led_classdev cdev;219 struct led_classdev_mc mc_cdev;220 u8 led_current;221 u8 max_current;222 u8 brightness;223 struct lp55xx_chip *chip;224};225 226/* register access */227extern int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val);228extern int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val);229extern int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg,230 u8 mask, u8 val);231 232/* external clock detection */233extern bool lp55xx_is_extclk_used(struct lp55xx_chip *chip);234 235/* common chip functions */236extern void lp55xx_stop_all_engine(struct lp55xx_chip *chip);237extern void lp55xx_load_engine(struct lp55xx_chip *chip);238extern int lp55xx_run_engine_common(struct lp55xx_chip *chip);239extern int lp55xx_update_program_memory(struct lp55xx_chip *chip,240 const u8 *data, size_t size);241extern void lp55xx_firmware_loaded_cb(struct lp55xx_chip *chip);242extern int lp55xx_led_brightness(struct lp55xx_led *led);243extern int lp55xx_multicolor_brightness(struct lp55xx_led *led);244extern void lp55xx_set_led_current(struct lp55xx_led *led, u8 led_current);245extern void lp55xx_turn_off_channels(struct lp55xx_chip *chip);246extern void lp55xx_stop_engine(struct lp55xx_chip *chip);247 248/* common probe/remove function */249extern int lp55xx_probe(struct i2c_client *client);250extern void lp55xx_remove(struct i2c_client *client);251 252/* common sysfs function */253extern ssize_t lp55xx_show_engine_mode(struct device *dev,254 struct device_attribute *attr,255 char *buf, int nr);256extern ssize_t lp55xx_store_engine_mode(struct device *dev,257 struct device_attribute *attr,258 const char *buf, size_t len, int nr);259extern ssize_t lp55xx_store_engine_load(struct device *dev,260 struct device_attribute *attr,261 const char *buf, size_t len, int nr);262extern ssize_t lp55xx_show_engine_leds(struct device *dev,263 struct device_attribute *attr,264 char *buf, int nr);265extern ssize_t lp55xx_store_engine_leds(struct device *dev,266 struct device_attribute *attr,267 const char *buf, size_t len, int nr);268extern ssize_t lp55xx_show_master_fader(struct device *dev,269 struct device_attribute *attr,270 char *buf, int nr);271extern ssize_t lp55xx_store_master_fader(struct device *dev,272 struct device_attribute *attr,273 const char *buf, size_t len, int nr);274extern ssize_t lp55xx_show_master_fader_leds(struct device *dev,275 struct device_attribute *attr,276 char *buf);277extern ssize_t lp55xx_store_master_fader_leds(struct device *dev,278 struct device_attribute *attr,279 const char *buf, size_t len);280 281#endif /* _LEDS_LP55XX_COMMON_H */282