1*4882a593Smuzhiyun================================================= 2*4882a593SmuzhiyunLP5521/LP5523/LP55231/LP5562/LP8501 Common Driver 3*4882a593Smuzhiyun================================================= 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunAuthors: Milo(Woogyom) Kim <milo.kim@ti.com> 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunDescription 8*4882a593Smuzhiyun----------- 9*4882a593SmuzhiyunLP5521, LP5523/55231, LP5562 and LP8501 have common features as below. 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun Register access via the I2C 12*4882a593Smuzhiyun Device initialization/deinitialization 13*4882a593Smuzhiyun Create LED class devices for multiple output channels 14*4882a593Smuzhiyun Device attributes for user-space interface 15*4882a593Smuzhiyun Program memory for running LED patterns 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunThe LP55xx common driver provides these features using exported functions. 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun lp55xx_init_device() / lp55xx_deinit_device() 20*4882a593Smuzhiyun lp55xx_register_leds() / lp55xx_unregister_leds() 21*4882a593Smuzhiyun lp55xx_regsister_sysfs() / lp55xx_unregister_sysfs() 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun( Driver Structure Data ) 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunIn lp55xx common driver, two different data structure is used. 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun* lp55xx_led 28*4882a593Smuzhiyun control multi output LED channels such as led current, channel index. 29*4882a593Smuzhiyun* lp55xx_chip 30*4882a593Smuzhiyun general chip control such like the I2C and platform data. 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunFor example, LP5521 has maximum 3 LED channels. 33*4882a593SmuzhiyunLP5523/55231 has 9 output channels:: 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun lp55xx_chip for LP5521 ... lp55xx_led #1 36*4882a593Smuzhiyun lp55xx_led #2 37*4882a593Smuzhiyun lp55xx_led #3 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun lp55xx_chip for LP5523 ... lp55xx_led #1 40*4882a593Smuzhiyun lp55xx_led #2 41*4882a593Smuzhiyun . 42*4882a593Smuzhiyun . 43*4882a593Smuzhiyun lp55xx_led #9 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun( Chip Dependent Code ) 46*4882a593Smuzhiyun 47*4882a593SmuzhiyunTo support device specific configurations, special structure 48*4882a593Smuzhiyun'lpxx_device_config' is used. 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun - Maximum number of channels 51*4882a593Smuzhiyun - Reset command, chip enable command 52*4882a593Smuzhiyun - Chip specific initialization 53*4882a593Smuzhiyun - Brightness control register access 54*4882a593Smuzhiyun - Setting LED output current 55*4882a593Smuzhiyun - Program memory address access for running patterns 56*4882a593Smuzhiyun - Additional device specific attributes 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun( Firmware Interface ) 59*4882a593Smuzhiyun 60*4882a593SmuzhiyunLP55xx family devices have the internal program memory for running 61*4882a593Smuzhiyunvarious LED patterns. 62*4882a593Smuzhiyun 63*4882a593SmuzhiyunThis pattern data is saved as a file in the user-land or 64*4882a593Smuzhiyunhex byte string is written into the memory through the I2C. 65*4882a593Smuzhiyun 66*4882a593SmuzhiyunLP55xx common driver supports the firmware interface. 67*4882a593Smuzhiyun 68*4882a593SmuzhiyunLP55xx chips have three program engines. 69*4882a593Smuzhiyun 70*4882a593SmuzhiyunTo load and run the pattern, the programming sequence is following. 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun (1) Select an engine number (1/2/3) 73*4882a593Smuzhiyun (2) Mode change to load 74*4882a593Smuzhiyun (3) Write pattern data into selected area 75*4882a593Smuzhiyun (4) Mode change to run 76*4882a593Smuzhiyun 77*4882a593SmuzhiyunThe LP55xx common driver provides simple interfaces as below. 78*4882a593Smuzhiyun 79*4882a593Smuzhiyunselect_engine: 80*4882a593Smuzhiyun Select which engine is used for running program 81*4882a593Smuzhiyunrun_engine: 82*4882a593Smuzhiyun Start program which is loaded via the firmware interface 83*4882a593Smuzhiyunfirmware: 84*4882a593Smuzhiyun Load program data 85*4882a593Smuzhiyun 86*4882a593SmuzhiyunIn case of LP5523, one more command is required, 'enginex_leds'. 87*4882a593SmuzhiyunIt is used for selecting LED output(s) at each engine number. 88*4882a593SmuzhiyunIn more details, please refer to 'leds-lp5523.txt'. 89*4882a593Smuzhiyun 90*4882a593SmuzhiyunFor example, run blinking pattern in engine #1 of LP5521:: 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun echo 1 > /sys/bus/i2c/devices/xxxx/select_engine 93*4882a593Smuzhiyun echo 1 > /sys/class/firmware/lp5521/loading 94*4882a593Smuzhiyun echo "4000600040FF6000" > /sys/class/firmware/lp5521/data 95*4882a593Smuzhiyun echo 0 > /sys/class/firmware/lp5521/loading 96*4882a593Smuzhiyun echo 1 > /sys/bus/i2c/devices/xxxx/run_engine 97*4882a593Smuzhiyun 98*4882a593SmuzhiyunFor example, run blinking pattern in engine #3 of LP55231 99*4882a593Smuzhiyun 100*4882a593SmuzhiyunTwo LEDs are configured as pattern output channels:: 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun echo 3 > /sys/bus/i2c/devices/xxxx/select_engine 103*4882a593Smuzhiyun echo 1 > /sys/class/firmware/lp55231/loading 104*4882a593Smuzhiyun echo "9d0740ff7e0040007e00a0010000" > /sys/class/firmware/lp55231/data 105*4882a593Smuzhiyun echo 0 > /sys/class/firmware/lp55231/loading 106*4882a593Smuzhiyun echo "000001100" > /sys/bus/i2c/devices/xxxx/engine3_leds 107*4882a593Smuzhiyun echo 1 > /sys/bus/i2c/devices/xxxx/run_engine 108*4882a593Smuzhiyun 109*4882a593SmuzhiyunTo start blinking patterns in engine #2 and #3 simultaneously:: 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun for idx in 2 3 112*4882a593Smuzhiyun do 113*4882a593Smuzhiyun echo $idx > /sys/class/leds/red/device/select_engine 114*4882a593Smuzhiyun sleep 0.1 115*4882a593Smuzhiyun echo 1 > /sys/class/firmware/lp5521/loading 116*4882a593Smuzhiyun echo "4000600040FF6000" > /sys/class/firmware/lp5521/data 117*4882a593Smuzhiyun echo 0 > /sys/class/firmware/lp5521/loading 118*4882a593Smuzhiyun done 119*4882a593Smuzhiyun echo 1 > /sys/class/leds/red/device/run_engine 120*4882a593Smuzhiyun 121*4882a593SmuzhiyunHere is another example for LP5523. 122*4882a593Smuzhiyun 123*4882a593SmuzhiyunFull LED strings are selected by 'engine2_leds':: 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun echo 2 > /sys/bus/i2c/devices/xxxx/select_engine 126*4882a593Smuzhiyun echo 1 > /sys/class/firmware/lp5523/loading 127*4882a593Smuzhiyun echo "9d80400004ff05ff437f0000" > /sys/class/firmware/lp5523/data 128*4882a593Smuzhiyun echo 0 > /sys/class/firmware/lp5523/loading 129*4882a593Smuzhiyun echo "111111111" > /sys/bus/i2c/devices/xxxx/engine2_leds 130*4882a593Smuzhiyun echo 1 > /sys/bus/i2c/devices/xxxx/run_engine 131*4882a593Smuzhiyun 132*4882a593SmuzhiyunAs soon as 'loading' is set to 0, registered callback is called. 133*4882a593SmuzhiyunInside the callback, the selected engine is loaded and memory is updated. 134*4882a593SmuzhiyunTo run programmed pattern, 'run_engine' attribute should be enabled. 135*4882a593Smuzhiyun 136*4882a593SmuzhiyunThe pattern sequence of LP8501 is similar to LP5523. 137*4882a593Smuzhiyun 138*4882a593SmuzhiyunHowever pattern data is specific. 139*4882a593Smuzhiyun 140*4882a593SmuzhiyunEx 1) Engine 1 is used:: 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun echo 1 > /sys/bus/i2c/devices/xxxx/select_engine 143*4882a593Smuzhiyun echo 1 > /sys/class/firmware/lp8501/loading 144*4882a593Smuzhiyun echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data 145*4882a593Smuzhiyun echo 0 > /sys/class/firmware/lp8501/loading 146*4882a593Smuzhiyun echo 1 > /sys/bus/i2c/devices/xxxx/run_engine 147*4882a593Smuzhiyun 148*4882a593SmuzhiyunEx 2) Engine 2 and 3 are used at the same time:: 149*4882a593Smuzhiyun 150*4882a593Smuzhiyun echo 2 > /sys/bus/i2c/devices/xxxx/select_engine 151*4882a593Smuzhiyun sleep 1 152*4882a593Smuzhiyun echo 1 > /sys/class/firmware/lp8501/loading 153*4882a593Smuzhiyun echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data 154*4882a593Smuzhiyun echo 0 > /sys/class/firmware/lp8501/loading 155*4882a593Smuzhiyun sleep 1 156*4882a593Smuzhiyun echo 3 > /sys/bus/i2c/devices/xxxx/select_engine 157*4882a593Smuzhiyun sleep 1 158*4882a593Smuzhiyun echo 1 > /sys/class/firmware/lp8501/loading 159*4882a593Smuzhiyun echo "9d0340ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data 160*4882a593Smuzhiyun echo 0 > /sys/class/firmware/lp8501/loading 161*4882a593Smuzhiyun sleep 1 162*4882a593Smuzhiyun echo 1 > /sys/class/leds/d1/device/run_engine 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun( 'run_engine' and 'firmware_cb' ) 165*4882a593Smuzhiyun 166*4882a593SmuzhiyunThe sequence of running the program data is common. 167*4882a593Smuzhiyun 168*4882a593SmuzhiyunBut each device has own specific register addresses for commands. 169*4882a593Smuzhiyun 170*4882a593SmuzhiyunTo support this, 'run_engine' and 'firmware_cb' are configurable in each driver. 171*4882a593Smuzhiyun 172*4882a593Smuzhiyunrun_engine: 173*4882a593Smuzhiyun Control the selected engine 174*4882a593Smuzhiyunfirmware_cb: 175*4882a593Smuzhiyun The callback function after loading the firmware is done. 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun Chip specific commands for loading and updating program memory. 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun( Predefined pattern data ) 180*4882a593Smuzhiyun 181*4882a593SmuzhiyunWithout the firmware interface, LP55xx driver provides another method for 182*4882a593Smuzhiyunloading a LED pattern. That is 'predefined' pattern. 183*4882a593Smuzhiyun 184*4882a593SmuzhiyunA predefined pattern is defined in the platform data and load it(or them) 185*4882a593Smuzhiyunvia the sysfs if needed. 186*4882a593Smuzhiyun 187*4882a593SmuzhiyunTo use the predefined pattern concept, 'patterns' and 'num_patterns' should be 188*4882a593Smuzhiyunconfigured. 189*4882a593Smuzhiyun 190*4882a593SmuzhiyunExample of predefined pattern data:: 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun /* mode_1: blinking data */ 193*4882a593Smuzhiyun static const u8 mode_1[] = { 194*4882a593Smuzhiyun 0x40, 0x00, 0x60, 0x00, 0x40, 0xFF, 0x60, 0x00, 195*4882a593Smuzhiyun }; 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun /* mode_2: always on */ 198*4882a593Smuzhiyun static const u8 mode_2[] = { 0x40, 0xFF, }; 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun struct lp55xx_predef_pattern board_led_patterns[] = { 201*4882a593Smuzhiyun { 202*4882a593Smuzhiyun .r = mode_1, 203*4882a593Smuzhiyun .size_r = ARRAY_SIZE(mode_1), 204*4882a593Smuzhiyun }, 205*4882a593Smuzhiyun { 206*4882a593Smuzhiyun .b = mode_2, 207*4882a593Smuzhiyun .size_b = ARRAY_SIZE(mode_2), 208*4882a593Smuzhiyun }, 209*4882a593Smuzhiyun } 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun struct lp55xx_platform_data lp5562_pdata = { 212*4882a593Smuzhiyun ... 213*4882a593Smuzhiyun .patterns = board_led_patterns, 214*4882a593Smuzhiyun .num_patterns = ARRAY_SIZE(board_led_patterns), 215*4882a593Smuzhiyun }; 216*4882a593Smuzhiyun 217*4882a593SmuzhiyunThen, mode_1 and mode_2 can be run via through the sysfs:: 218*4882a593Smuzhiyun 219*4882a593Smuzhiyun echo 1 > /sys/bus/i2c/devices/xxxx/led_pattern # red blinking LED pattern 220*4882a593Smuzhiyun echo 2 > /sys/bus/i2c/devices/xxxx/led_pattern # blue LED always on 221*4882a593Smuzhiyun 222*4882a593SmuzhiyunTo stop running pattern:: 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern 225