1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * LP55XX Common Driver Header 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2012 Texas Instruments 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Author: Milo(Woogyom) Kim <milo.kim@ti.com> 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * Derived from leds-lp5521.c, leds-lp5523.c 10*4882a593Smuzhiyun */ 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #ifndef _LEDS_LP55XX_COMMON_H 13*4882a593Smuzhiyun #define _LEDS_LP55XX_COMMON_H 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #include <linux/led-class-multicolor.h> 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun enum lp55xx_engine_index { 18*4882a593Smuzhiyun LP55XX_ENGINE_INVALID, 19*4882a593Smuzhiyun LP55XX_ENGINE_1, 20*4882a593Smuzhiyun LP55XX_ENGINE_2, 21*4882a593Smuzhiyun LP55XX_ENGINE_3, 22*4882a593Smuzhiyun LP55XX_ENGINE_MAX = LP55XX_ENGINE_3, 23*4882a593Smuzhiyun }; 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun enum lp55xx_engine_mode { 26*4882a593Smuzhiyun LP55XX_ENGINE_DISABLED, 27*4882a593Smuzhiyun LP55XX_ENGINE_LOAD, 28*4882a593Smuzhiyun LP55XX_ENGINE_RUN, 29*4882a593Smuzhiyun }; 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun #define LP55XX_DEV_ATTR_RW(name, show, store) \ 32*4882a593Smuzhiyun DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show, store) 33*4882a593Smuzhiyun #define LP55XX_DEV_ATTR_RO(name, show) \ 34*4882a593Smuzhiyun DEVICE_ATTR(name, S_IRUGO, show, NULL) 35*4882a593Smuzhiyun #define LP55XX_DEV_ATTR_WO(name, store) \ 36*4882a593Smuzhiyun DEVICE_ATTR(name, S_IWUSR, NULL, store) 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun #define show_mode(nr) \ 39*4882a593Smuzhiyun static ssize_t show_engine##nr##_mode(struct device *dev, \ 40*4882a593Smuzhiyun struct device_attribute *attr, \ 41*4882a593Smuzhiyun char *buf) \ 42*4882a593Smuzhiyun { \ 43*4882a593Smuzhiyun return show_engine_mode(dev, attr, buf, nr); \ 44*4882a593Smuzhiyun } 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun #define store_mode(nr) \ 47*4882a593Smuzhiyun static ssize_t store_engine##nr##_mode(struct device *dev, \ 48*4882a593Smuzhiyun struct device_attribute *attr, \ 49*4882a593Smuzhiyun const char *buf, size_t len) \ 50*4882a593Smuzhiyun { \ 51*4882a593Smuzhiyun return store_engine_mode(dev, attr, buf, len, nr); \ 52*4882a593Smuzhiyun } 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun #define show_leds(nr) \ 55*4882a593Smuzhiyun static ssize_t show_engine##nr##_leds(struct device *dev, \ 56*4882a593Smuzhiyun struct device_attribute *attr, \ 57*4882a593Smuzhiyun char *buf) \ 58*4882a593Smuzhiyun { \ 59*4882a593Smuzhiyun return show_engine_leds(dev, attr, buf, nr); \ 60*4882a593Smuzhiyun } 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun #define store_leds(nr) \ 63*4882a593Smuzhiyun static ssize_t store_engine##nr##_leds(struct device *dev, \ 64*4882a593Smuzhiyun struct device_attribute *attr, \ 65*4882a593Smuzhiyun const char *buf, size_t len) \ 66*4882a593Smuzhiyun { \ 67*4882a593Smuzhiyun return store_engine_leds(dev, attr, buf, len, nr); \ 68*4882a593Smuzhiyun } 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun #define store_load(nr) \ 71*4882a593Smuzhiyun static ssize_t store_engine##nr##_load(struct device *dev, \ 72*4882a593Smuzhiyun struct device_attribute *attr, \ 73*4882a593Smuzhiyun const char *buf, size_t len) \ 74*4882a593Smuzhiyun { \ 75*4882a593Smuzhiyun return store_engine_load(dev, attr, buf, len, nr); \ 76*4882a593Smuzhiyun } 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun struct lp55xx_led; 79*4882a593Smuzhiyun struct lp55xx_chip; 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun /* 82*4882a593Smuzhiyun * struct lp55xx_reg 83*4882a593Smuzhiyun * @addr : Register address 84*4882a593Smuzhiyun * @val : Register value 85*4882a593Smuzhiyun */ 86*4882a593Smuzhiyun struct lp55xx_reg { 87*4882a593Smuzhiyun u8 addr; 88*4882a593Smuzhiyun u8 val; 89*4882a593Smuzhiyun }; 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun /* 92*4882a593Smuzhiyun * struct lp55xx_device_config 93*4882a593Smuzhiyun * @reset : Chip specific reset command 94*4882a593Smuzhiyun * @enable : Chip specific enable command 95*4882a593Smuzhiyun * @max_channel : Maximum number of channels 96*4882a593Smuzhiyun * @post_init_device : Chip specific initialization code 97*4882a593Smuzhiyun * @brightness_fn : Brightness function 98*4882a593Smuzhiyun * @multicolor_brightness_fn : Multicolor brightness function 99*4882a593Smuzhiyun * @set_led_current : LED current set function 100*4882a593Smuzhiyun * @firmware_cb : Call function when the firmware is loaded 101*4882a593Smuzhiyun * @run_engine : Run internal engine for pattern 102*4882a593Smuzhiyun * @dev_attr_group : Device specific attributes 103*4882a593Smuzhiyun */ 104*4882a593Smuzhiyun struct lp55xx_device_config { 105*4882a593Smuzhiyun const struct lp55xx_reg reset; 106*4882a593Smuzhiyun const struct lp55xx_reg enable; 107*4882a593Smuzhiyun const int max_channel; 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun /* define if the device has specific initialization process */ 110*4882a593Smuzhiyun int (*post_init_device) (struct lp55xx_chip *chip); 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun /* set LED brightness */ 113*4882a593Smuzhiyun int (*brightness_fn)(struct lp55xx_led *led); 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun /* set multicolor LED brightness */ 116*4882a593Smuzhiyun int (*multicolor_brightness_fn)(struct lp55xx_led *led); 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun /* current setting function */ 119*4882a593Smuzhiyun void (*set_led_current) (struct lp55xx_led *led, u8 led_current); 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun /* access program memory when the firmware is loaded */ 122*4882a593Smuzhiyun void (*firmware_cb)(struct lp55xx_chip *chip); 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun /* used for running firmware LED patterns */ 125*4882a593Smuzhiyun void (*run_engine) (struct lp55xx_chip *chip, bool start); 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun /* additional device specific attributes */ 128*4882a593Smuzhiyun const struct attribute_group *dev_attr_group; 129*4882a593Smuzhiyun }; 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun /* 132*4882a593Smuzhiyun * struct lp55xx_engine 133*4882a593Smuzhiyun * @mode : Engine mode 134*4882a593Smuzhiyun * @led_mux : Mux bits for LED selection. Only used in LP5523 135*4882a593Smuzhiyun */ 136*4882a593Smuzhiyun struct lp55xx_engine { 137*4882a593Smuzhiyun enum lp55xx_engine_mode mode; 138*4882a593Smuzhiyun u16 led_mux; 139*4882a593Smuzhiyun }; 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun /* 142*4882a593Smuzhiyun * struct lp55xx_chip 143*4882a593Smuzhiyun * @cl : I2C communication for access registers 144*4882a593Smuzhiyun * @pdata : Platform specific data 145*4882a593Smuzhiyun * @lock : Lock for user-space interface 146*4882a593Smuzhiyun * @num_leds : Number of registered LEDs 147*4882a593Smuzhiyun * @cfg : Device specific configuration data 148*4882a593Smuzhiyun * @engine_idx : Selected engine number 149*4882a593Smuzhiyun * @engines : Engine structure for the device attribute R/W interface 150*4882a593Smuzhiyun * @fw : Firmware data for running a LED pattern 151*4882a593Smuzhiyun */ 152*4882a593Smuzhiyun struct lp55xx_chip { 153*4882a593Smuzhiyun struct i2c_client *cl; 154*4882a593Smuzhiyun struct clk *clk; 155*4882a593Smuzhiyun struct lp55xx_platform_data *pdata; 156*4882a593Smuzhiyun struct mutex lock; /* lock for user-space interface */ 157*4882a593Smuzhiyun int num_leds; 158*4882a593Smuzhiyun struct lp55xx_device_config *cfg; 159*4882a593Smuzhiyun enum lp55xx_engine_index engine_idx; 160*4882a593Smuzhiyun struct lp55xx_engine engines[LP55XX_ENGINE_MAX]; 161*4882a593Smuzhiyun const struct firmware *fw; 162*4882a593Smuzhiyun }; 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun /* 165*4882a593Smuzhiyun * struct lp55xx_led 166*4882a593Smuzhiyun * @chan_nr : Channel number 167*4882a593Smuzhiyun * @cdev : LED class device 168*4882a593Smuzhiyun * @mc_cdev : Multi color class device 169*4882a593Smuzhiyun * @color_components: Multi color LED map information 170*4882a593Smuzhiyun * @led_current : Current setting at each led channel 171*4882a593Smuzhiyun * @max_current : Maximun current at each led channel 172*4882a593Smuzhiyun * @brightness : Brightness value 173*4882a593Smuzhiyun * @chip : The lp55xx chip data 174*4882a593Smuzhiyun */ 175*4882a593Smuzhiyun struct lp55xx_led { 176*4882a593Smuzhiyun int chan_nr; 177*4882a593Smuzhiyun struct led_classdev cdev; 178*4882a593Smuzhiyun struct led_classdev_mc mc_cdev; 179*4882a593Smuzhiyun u8 led_current; 180*4882a593Smuzhiyun u8 max_current; 181*4882a593Smuzhiyun u8 brightness; 182*4882a593Smuzhiyun struct lp55xx_chip *chip; 183*4882a593Smuzhiyun }; 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun /* register access */ 186*4882a593Smuzhiyun extern int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val); 187*4882a593Smuzhiyun extern int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val); 188*4882a593Smuzhiyun extern int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, 189*4882a593Smuzhiyun u8 mask, u8 val); 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun /* external clock detection */ 192*4882a593Smuzhiyun extern bool lp55xx_is_extclk_used(struct lp55xx_chip *chip); 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun /* common device init/deinit functions */ 195*4882a593Smuzhiyun extern int lp55xx_init_device(struct lp55xx_chip *chip); 196*4882a593Smuzhiyun extern void lp55xx_deinit_device(struct lp55xx_chip *chip); 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun /* common LED class device functions */ 199*4882a593Smuzhiyun extern int lp55xx_register_leds(struct lp55xx_led *led, 200*4882a593Smuzhiyun struct lp55xx_chip *chip); 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun /* common device attributes functions */ 203*4882a593Smuzhiyun extern int lp55xx_register_sysfs(struct lp55xx_chip *chip); 204*4882a593Smuzhiyun extern void lp55xx_unregister_sysfs(struct lp55xx_chip *chip); 205*4882a593Smuzhiyun 206*4882a593Smuzhiyun /* common device tree population function */ 207*4882a593Smuzhiyun extern struct lp55xx_platform_data 208*4882a593Smuzhiyun *lp55xx_of_populate_pdata(struct device *dev, struct device_node *np, 209*4882a593Smuzhiyun struct lp55xx_chip *chip); 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun #endif /* _LEDS_LP55XX_COMMON_H */ 212