Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

leds: TI LMU: Add common code for TI LMU devices

Create a TI LMU common framework for TI LMU devices that share
common features.

Currently the runtime ramp and brightness setting have
been identified as common features with common register settings.

This work is derived from Milo Kims TI LMU MFD code.

Signed-off-by: Dan Murphy <dmurphy@ti.com>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>

authored by

Dan Murphy and committed by
Jacek Anaszewski
3fce8e1e d0147554

+213
+9
drivers/leds/Kconfig
··· 783 783 To compile this driver as a module, choose M here: the module 784 784 will be called leds-nic78bx. 785 785 786 + config LEDS_TI_LMU_COMMON 787 + tristate "LED driver for TI LMU" 788 + depends on LEDS_CLASS 789 + depends on REGMAP 790 + help 791 + Say Y to enable the LED driver for TI LMU devices. 792 + This supports common features between the TI LM3532, LM3631, LM3632, 793 + LM3633, LM3695 and LM3697. 794 + 786 795 comment "LED Triggers" 787 796 source "drivers/leds/trigger/Kconfig" 788 797
+1
drivers/leds/Makefile
··· 81 81 obj-$(CONFIG_LEDS_LM3692X) += leds-lm3692x.o 82 82 obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o 83 83 obj-$(CONFIG_LEDS_LM3601X) += leds-lm3601x.o 84 + obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o 84 85 85 86 # LED SPI Drivers 86 87 obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o
+156
drivers/leds/leds-ti-lmu-common.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright 2015 Texas Instruments 3 + // Copyright 2018 Sebastian Reichel 4 + // Copyright 2018 Pavel Machek <pavel@ucw.cz> 5 + // TI LMU LED common framework, based on previous work from 6 + // Milo Kim <milo.kim@ti.com> 7 + 8 + #include <linux/bitops.h> 9 + #include <linux/err.h> 10 + #include <linux/of_device.h> 11 + 12 + #include <linux/leds-ti-lmu-common.h> 13 + 14 + const static int ramp_table[16] = {2048, 262000, 524000, 1049000, 2090000, 15 + 4194000, 8389000, 16780000, 33550000, 41940000, 16 + 50330000, 58720000, 67110000, 83880000, 17 + 100660000, 117440000}; 18 + 19 + static int ti_lmu_common_update_brightness(struct ti_lmu_bank *lmu_bank, 20 + int brightness) 21 + { 22 + struct regmap *regmap = lmu_bank->regmap; 23 + u8 reg, val; 24 + int ret; 25 + 26 + /* 27 + * Brightness register update 28 + * 29 + * 11 bit dimming: update LSB bits and write MSB byte. 30 + * MSB brightness should be shifted. 31 + * 8 bit dimming: write MSB byte. 32 + */ 33 + if (lmu_bank->max_brightness == MAX_BRIGHTNESS_11BIT) { 34 + reg = lmu_bank->lsb_brightness_reg; 35 + ret = regmap_update_bits(regmap, reg, 36 + LMU_11BIT_LSB_MASK, 37 + brightness); 38 + if (ret) 39 + return ret; 40 + 41 + val = brightness >> LMU_11BIT_MSB_SHIFT; 42 + } else { 43 + val = brightness; 44 + } 45 + 46 + reg = lmu_bank->msb_brightness_reg; 47 + 48 + return regmap_write(regmap, reg, val); 49 + } 50 + 51 + int ti_lmu_common_set_brightness(struct ti_lmu_bank *lmu_bank, int brightness) 52 + { 53 + return ti_lmu_common_update_brightness(lmu_bank, brightness); 54 + } 55 + EXPORT_SYMBOL(ti_lmu_common_set_brightness); 56 + 57 + static int ti_lmu_common_convert_ramp_to_index(unsigned int usec) 58 + { 59 + int size = ARRAY_SIZE(ramp_table); 60 + int i; 61 + 62 + if (usec <= ramp_table[0]) 63 + return 0; 64 + 65 + if (usec > ramp_table[size - 1]) 66 + return size - 1; 67 + 68 + for (i = 1; i < size; i++) { 69 + if (usec == ramp_table[i]) 70 + return i; 71 + 72 + /* Find an approximate index by looking up the table */ 73 + if (usec > ramp_table[i - 1] && usec < ramp_table[i]) { 74 + if (usec - ramp_table[i - 1] < ramp_table[i] - usec) 75 + return i - 1; 76 + else 77 + return i; 78 + } 79 + } 80 + 81 + return -EINVAL; 82 + } 83 + 84 + int ti_lmu_common_set_ramp(struct ti_lmu_bank *lmu_bank) 85 + { 86 + struct regmap *regmap = lmu_bank->regmap; 87 + u8 ramp, ramp_up, ramp_down; 88 + 89 + if (lmu_bank->ramp_up_usec == 0 && lmu_bank->ramp_down_usec == 0) { 90 + ramp_up = 0; 91 + ramp_down = 0; 92 + } else { 93 + ramp_up = ti_lmu_common_convert_ramp_to_index(lmu_bank->ramp_up_usec); 94 + ramp_down = ti_lmu_common_convert_ramp_to_index(lmu_bank->ramp_down_usec); 95 + } 96 + 97 + if (ramp_up < 0 || ramp_down < 0) 98 + return -EINVAL; 99 + 100 + ramp = (ramp_up << 4) | ramp_down; 101 + 102 + return regmap_write(regmap, lmu_bank->runtime_ramp_reg, ramp); 103 + 104 + } 105 + EXPORT_SYMBOL(ti_lmu_common_set_ramp); 106 + 107 + int ti_lmu_common_get_ramp_params(struct device *dev, 108 + struct fwnode_handle *child, 109 + struct ti_lmu_bank *lmu_data) 110 + { 111 + int ret; 112 + 113 + ret = fwnode_property_read_u32(child, "ramp-up-us", 114 + &lmu_data->ramp_up_usec); 115 + if (ret) 116 + dev_warn(dev, "ramp-up-us property missing\n"); 117 + 118 + 119 + ret = fwnode_property_read_u32(child, "ramp-down-us", 120 + &lmu_data->ramp_down_usec); 121 + if (ret) 122 + dev_warn(dev, "ramp-down-us property missing\n"); 123 + 124 + return 0; 125 + } 126 + EXPORT_SYMBOL(ti_lmu_common_get_ramp_params); 127 + 128 + int ti_lmu_common_get_brt_res(struct device *dev, struct fwnode_handle *child, 129 + struct ti_lmu_bank *lmu_data) 130 + { 131 + int ret; 132 + 133 + ret = device_property_read_u32(dev, "ti,brightness-resolution", 134 + &lmu_data->max_brightness); 135 + if (ret) 136 + ret = fwnode_property_read_u32(child, 137 + "ti,brightness-resolution", 138 + &lmu_data->max_brightness); 139 + if (lmu_data->max_brightness <= 0) { 140 + lmu_data->max_brightness = MAX_BRIGHTNESS_8BIT; 141 + return ret; 142 + } 143 + 144 + if (lmu_data->max_brightness > MAX_BRIGHTNESS_11BIT) 145 + lmu_data->max_brightness = MAX_BRIGHTNESS_11BIT; 146 + 147 + 148 + return 0; 149 + } 150 + EXPORT_SYMBOL(ti_lmu_common_get_brt_res); 151 + 152 + MODULE_DESCRIPTION("TI LMU common LED framework"); 153 + MODULE_AUTHOR("Sebastian Reichel"); 154 + MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 155 + MODULE_LICENSE("GPL v2"); 156 + MODULE_ALIAS("ti-lmu-led-common");
+47
include/linux/leds-ti-lmu-common.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + // TI LMU Common Core 3 + // Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ 4 + 5 + #ifndef _TI_LMU_COMMON_H_ 6 + #define _TI_LMU_COMMON_H_ 7 + 8 + #include <linux/delay.h> 9 + #include <linux/device.h> 10 + #include <linux/init.h> 11 + #include <linux/leds.h> 12 + #include <linux/module.h> 13 + #include <linux/regmap.h> 14 + #include <linux/slab.h> 15 + #include <uapi/linux/uleds.h> 16 + 17 + #define LMU_11BIT_LSB_MASK (BIT(0) | BIT(1) | BIT(2)) 18 + #define LMU_11BIT_MSB_SHIFT 3 19 + 20 + #define MAX_BRIGHTNESS_8BIT 255 21 + #define MAX_BRIGHTNESS_11BIT 2047 22 + 23 + struct ti_lmu_bank { 24 + struct regmap *regmap; 25 + 26 + int max_brightness; 27 + 28 + u8 lsb_brightness_reg; 29 + u8 msb_brightness_reg; 30 + 31 + u8 runtime_ramp_reg; 32 + u32 ramp_up_usec; 33 + u32 ramp_down_usec; 34 + }; 35 + 36 + int ti_lmu_common_set_brightness(struct ti_lmu_bank *lmu_bank, int brightness); 37 + 38 + int ti_lmu_common_set_ramp(struct ti_lmu_bank *lmu_bank); 39 + 40 + int ti_lmu_common_get_ramp_params(struct device *dev, 41 + struct fwnode_handle *child, 42 + struct ti_lmu_bank *lmu_data); 43 + 44 + int ti_lmu_common_get_brt_res(struct device *dev, struct fwnode_handle *child, 45 + struct ti_lmu_bank *lmu_data); 46 + 47 + #endif /* _TI_LMU_COMMON_H_ */