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

Merge tag 'ti-lmu-led-drivers' into for-next

Merge immutable branch between LEDs, MFD and REGULATOR due to
TI LMU LED support rework and introduction of two new drivers
with DT bindings.

* tag 'ti-lmu-led-drivers':
leds: lm36274: Introduce the TI LM36274 LED driver
dt-bindings: leds: Add LED bindings for the LM36274
regulator: lm363x: Add support for LM36274
mfd: ti-lmu: Add LM36274 support to the ti-lmu
dt-bindings: mfd: Add lm36274 bindings to ti-lmu
leds: lm3697: Introduce the lm3697 driver
mfd: ti-lmu: Remove support for LM3697
dt-bindings: ti-lmu: Modify dt bindings for the LM3697
leds: TI LMU: Add common code for TI LMU devices
dt-bindings: mfd: LMU: Add ti,brightness-resolution
dt-bindings: mfd: LMU: Add the ramp up/down property

+1132 -82
+85
Documentation/devicetree/bindings/leds/leds-lm36274.txt
··· 1 + * Texas Instruments LM36274 4-Channel LCD Backlight Driver w/Integrated Bias 2 + 3 + The LM36274 is an integrated four-channel WLED driver and LCD bias supply. 4 + The backlight boost provides the power to bias four parallel LED strings with 5 + up to 29V total output voltage. The 11-bit LED current is programmable via 6 + the I2C bus and/or controlled via a logic level PWM input from 60 uA to 30 mA. 7 + 8 + Parent device properties are documented in 9 + Documentation/devicetree/bindings/mfd/ti_lmu.txt 10 + 11 + Regulator properties are documented in 12 + Documentation/devicetree/bindings/regulator/lm363x-regulator.txt 13 + 14 + Required backlight properties: 15 + - compatible: 16 + "ti,lm36274-backlight" 17 + - reg : 0 18 + - #address-cells : 1 19 + - #size-cells : 0 20 + - led-sources : Indicates which LED strings will be enabled. 21 + Values from 0-3, sources is 0 based so strings will be 22 + source value + 1. 23 + 24 + Optional backlight properties: 25 + - label : see Documentation/devicetree/bindings/leds/common.txt 26 + - linux,default-trigger : 27 + see Documentation/devicetree/bindings/leds/common.txt 28 + 29 + Example: 30 + 31 + HVLED string 1 and 3 are controlled by control bank A and HVLED 2 string is 32 + controlled by control bank B. 33 + 34 + lm36274@11 { 35 + compatible = "ti,lm36274"; 36 + #address-cells = <1>; 37 + #size-cells = <0>; 38 + reg = <0x11>; 39 + 40 + enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; 41 + 42 + regulators { 43 + #address-cells = <1>; 44 + #size-cells = <0>; 45 + compatible = "ti,lm363x-regulator"; 46 + 47 + enable-gpios = <&pioC 0 GPIO_ACTIVE_HIGH>, 48 + <&pioC 1 GPIO_ACTIVE_HIGH>; 49 + 50 + vboost { 51 + regulator-name = "lcd_boost"; 52 + regulator-min-microvolt = <4000000>; 53 + regulator-max-microvolt = <7150000>; 54 + regulator-always-on; 55 + }; 56 + 57 + vpos { 58 + regulator-name = "lcd_vpos"; 59 + regulator-min-microvolt = <4000000>; 60 + regulator-max-microvolt = <6500000>; 61 + }; 62 + 63 + vneg { 64 + regulator-name = "lcd_vneg"; 65 + regulator-min-microvolt = <4000000>; 66 + regulator-max-microvolt = <6500000>; 67 + }; 68 + }; 69 + 70 + backlight { 71 + #address-cells = <1>; 72 + #size-cells = <0>; 73 + compatible = "ti,lm36274-backlight"; 74 + 75 + led@0 { 76 + reg = <0>; 77 + led-sources = <0 2>; 78 + label = "white:backlight_cluster"; 79 + linux,default-trigger = "backlight"; 80 + }; 81 + }; 82 + }; 83 + 84 + For more product information please see the link below: 85 + http://www.ti.com/lit/ds/symlink/lm36274.pdf
+73
Documentation/devicetree/bindings/leds/leds-lm3697.txt
··· 1 + * Texas Instruments - LM3697 Highly Efficient White LED Driver 2 + 3 + The LM3697 11-bit LED driver provides high- 4 + performance backlight dimming for 1, 2, or 3 series 5 + LED strings while delivering up to 90% efficiency. 6 + 7 + This device is suitable for display and keypad lighting 8 + 9 + Required properties: 10 + - compatible: 11 + "ti,lm3697" 12 + - reg : I2C slave address 13 + - #address-cells : 1 14 + - #size-cells : 0 15 + 16 + Optional properties: 17 + - enable-gpios : GPIO pin to enable/disable the device 18 + - vled-supply : LED supply 19 + 20 + Required child properties: 21 + - reg : 0 - LED is Controlled by bank A 22 + 1 - LED is Controlled by bank B 23 + - led-sources : Indicates which HVLED string is associated to which 24 + control bank. This is a zero based property so 25 + HVLED1 = 0, HVLED2 = 1, HVLED3 = 2. 26 + Additional information is contained 27 + in Documentation/devicetree/bindings/leds/common.txt 28 + 29 + Optional child properties: 30 + - ti,brightness-resolution - see Documentation/devicetree/bindings/mfd/ti-lmu.txt 31 + - ramp-up-us: see Documentation/devicetree/bindings/mfd/ti-lmu.txt 32 + - ramp-down-us: see Documentation/devicetree/bindings/mfd/ti-lmu.txt 33 + - label : see Documentation/devicetree/bindings/leds/common.txt 34 + - linux,default-trigger : 35 + see Documentation/devicetree/bindings/leds/common.txt 36 + 37 + Example: 38 + 39 + HVLED string 1 and 3 are controlled by control bank A and HVLED 2 string is 40 + controlled by control bank B. 41 + 42 + led-controller@36 { 43 + compatible = "ti,lm3697"; 44 + #address-cells = <1>; 45 + #size-cells = <0>; 46 + reg = <0x36>; 47 + 48 + enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; 49 + vled-supply = <&vbatt>; 50 + 51 + led@0 { 52 + reg = <0>; 53 + led-sources = <0 2>; 54 + ti,brightness-resolution = <2047>; 55 + ramp-up-us = <5000>; 56 + ramp-down-us = <1000>; 57 + label = "white:first_backlight_cluster"; 58 + linux,default-trigger = "backlight"; 59 + }; 60 + 61 + led@1 { 62 + reg = <1>; 63 + led-sources = <1>; 64 + ti,brightness-resolution = <255>; 65 + ramp-up-us = <500>; 66 + ramp-down-us = <1000>; 67 + label = "white:second_backlight_cluster"; 68 + linux,default-trigger = "backlight"; 69 + }; 70 + } 71 + 72 + For more product information please see the link below: 73 + http://www.ti.com/lit/ds/symlink/lm3697.pdf
+67 -21
Documentation/devicetree/bindings/mfd/ti-lmu.txt
··· 8 8 LM3632 Backlight and regulator 9 9 LM3633 Backlight, LED and fault monitor 10 10 LM3695 Backlight 11 - LM3697 Backlight and fault monitor 11 + LM36274 Backlight and regulator 12 12 13 13 Required properties: 14 14 - compatible: Should be one of: ··· 16 16 "ti,lm3632" 17 17 "ti,lm3633" 18 18 "ti,lm3695" 19 - "ti,lm3697" 19 + "ti,lm36274" 20 20 - reg: I2C slave address. 21 21 0x11 for LM3632 22 22 0x29 for LM3631 23 - 0x36 for LM3633, LM3697 23 + 0x36 for LM3633 24 24 0x63 for LM3695 25 + 0x11 for LM36274 25 26 26 - Optional property: 27 + Optional properties: 27 28 - enable-gpios: A GPIO specifier for hardware enable pin. 29 + - ramp-up-us: Current ramping from one brightness level to 30 + the a higher brightness level. 31 + Range from 2048 us - 117.44 s 32 + - ramp-down-us: Current ramping from one brightness level to 33 + the a lower brightness level. 34 + Range from 2048 us - 117.44 s 35 + - ti,brightness-resolution - This determines whether to use 8 bit brightness 36 + mode or 11 bit brightness mode. If this value is 37 + not set the device is defaulted to the preferred 38 + 8bit brightness mode per 7.3.4.1 of the data 39 + sheet. This setting can either be in the parent 40 + node or as part of the LED child nodes. This 41 + is determined by the part itself if the strings 42 + have a common brightness register or individual 43 + brightness registers. 44 + The values are 255 (8bit) or 2047 (11bit). 28 45 29 46 Required node: 30 47 - backlight: All LMU devices have backlight child nodes. ··· 52 35 Required properties: 53 36 - compatible: Should be one of: 54 37 "ti,lm3633-fault-monitor" 55 - "ti,lm3697-fault-monitor" 56 38 - leds: LED properties for LM3633. Please refer to [2]. 39 + LED properties for LM36274. Please refer to [4]. 57 40 - regulators: Regulator properties for LM3631 and LM3632. 58 41 Please refer to [3]. 59 42 60 43 [1] ../leds/backlight/ti-lmu-backlight.txt 61 44 [2] ../leds/leds-lm3633.txt 62 45 [3] ../regulator/lm363x-regulator.txt 46 + [4] ../leds/leds-lm36274.txt 63 47 64 48 lm3631@29 { 65 49 compatible = "ti,lm3631"; ··· 108 90 109 91 lcd_bl { 110 92 led-sources = <0 1>; 111 - ramp-up-msec = <300>; 93 + ramp-up-us = <300000>; 112 94 }; 113 95 }; 114 96 }; ··· 170 152 main { 171 153 label = "main_lcd"; 172 154 led-sources = <1 2>; 173 - ramp-up-msec = <500>; 174 - ramp-down-msec = <500>; 155 + ramp-up-us = <500000>; 156 + ramp-down-us = <500000>; 175 157 }; 176 158 177 159 front { 178 160 label = "front_lcd"; 179 161 led-sources = <0>; 180 - ramp-up-msec = <1000>; 181 - ramp-down-msec = <0>; 162 + ramp-up-us = <1000000>; 163 + ramp-down-us = <0>; 182 164 }; 183 165 }; 184 166 ··· 219 201 }; 220 202 }; 221 203 222 - lm3697@36 { 223 - compatible = "ti,lm3697"; 224 - reg = <0x36>; 204 + lm36274@11 { 205 + compatible = "ti,lm36274"; 206 + #address-cells = <1>; 207 + #size-cells = <0>; 208 + reg = <0x11>; 225 209 226 210 enable-gpios = <&pioC 2 GPIO_ACTIVE_HIGH>; 211 + regulators { 212 + #address-cells = <1>; 213 + #size-cells = <0>; 214 + compatible = "ti,lm363x-regulator"; 227 215 228 - backlight { 229 - compatible = "ti,lm3697-backlight"; 216 + enable-gpios = <&pioC 0 GPIO_ACTIVE_HIGH>, 217 + <&pioC 1 GPIO_ACTIVE_HIGH>; 230 218 231 - lcd { 232 - led-sources = <0 1 2>; 233 - ramp-up-msec = <200>; 234 - ramp-down-msec = <200>; 219 + vboost { 220 + regulator-name = "lcd_boost"; 221 + regulator-min-microvolt = <4000000>; 222 + regulator-max-microvolt = <7150000>; 223 + regulator-always-on; 224 + }; 225 + 226 + vpos { 227 + regulator-name = "lcd_vpos"; 228 + regulator-min-microvolt = <4000000>; 229 + regulator-max-microvolt = <6500000>; 230 + }; 231 + 232 + vneg { 233 + regulator-name = "lcd_vneg"; 234 + regulator-min-microvolt = <4000000>; 235 + regulator-max-microvolt = <6500000>; 235 236 }; 236 237 }; 237 238 238 - fault-monitor { 239 - compatible = "ti,lm3697-fault-monitor"; 239 + backlight { 240 + #address-cells = <1>; 241 + #size-cells = <0>; 242 + compatible = "ti,lm36274-backlight"; 243 + 244 + led@0 { 245 + reg = <0>; 246 + led-sources = <0 2>; 247 + label = "white:backlight_cluster"; 248 + linux,default-trigger = "backlight"; 249 + }; 240 250 }; 241 251 };
+25
drivers/leds/Kconfig
··· 793 793 for controlling the brightness. Currently the following controller is 794 794 supported: Ubiquiti airCube ISP microcontroller based LED controller. 795 795 796 + config LEDS_TI_LMU_COMMON 797 + tristate "LED driver for TI LMU" 798 + depends on LEDS_CLASS 799 + depends on REGMAP 800 + help 801 + Say Y to enable the LED driver for TI LMU devices. 802 + This supports common features between the TI LM3532, LM3631, LM3632, 803 + LM3633, LM3695 and LM3697. 804 + 805 + config LEDS_LM3697 806 + tristate "LED driver for LM3697" 807 + depends on LEDS_TI_LMU_COMMON 808 + depends on I2C && OF 809 + help 810 + Say Y to enable the LM3697 LED driver for TI LMU devices. 811 + This supports the LED device LM3697. 812 + 813 + config LEDS_LM36274 814 + tristate "LED driver for LM36274" 815 + depends on LEDS_TI_LMU_COMMON 816 + depends on MFD_TI_LMU 817 + help 818 + Say Y to enable the LM36274 LED driver for TI LMU devices. 819 + This supports the LED device LM36274. 820 + 796 821 comment "LED Triggers" 797 822 source "drivers/leds/trigger/Kconfig" 798 823
+3
drivers/leds/Makefile
··· 82 82 obj-$(CONFIG_LEDS_LM3692X) += leds-lm3692x.o 83 83 obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o 84 84 obj-$(CONFIG_LEDS_LM3601X) += leds-lm3601x.o 85 + obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o 86 + obj-$(CONFIG_LEDS_LM3697) += leds-lm3697.o 87 + obj-$(CONFIG_LEDS_LM36274) += leds-lm36274.o 85 88 86 89 # LED SPI Drivers 87 90 obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o
+172
drivers/leds/leds-lm36274.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // TI LM36274 LED chip family driver 3 + // Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ 4 + 5 + #include <linux/bitops.h> 6 + #include <linux/device.h> 7 + #include <linux/err.h> 8 + #include <linux/leds.h> 9 + #include <linux/leds-ti-lmu-common.h> 10 + #include <linux/module.h> 11 + #include <linux/of_device.h> 12 + #include <linux/platform_device.h> 13 + 14 + #include <linux/mfd/ti-lmu.h> 15 + #include <linux/mfd/ti-lmu-register.h> 16 + 17 + #include <uapi/linux/uleds.h> 18 + 19 + #define LM36274_MAX_STRINGS 4 20 + #define LM36274_BL_EN BIT(4) 21 + 22 + /** 23 + * struct lm36274 24 + * @pdev: platform device 25 + * @led_dev: led class device 26 + * @lmu_data: Register and setting values for common code 27 + * @regmap: Devices register map 28 + * @dev: Pointer to the devices device struct 29 + * @led_sources - The LED strings supported in this array 30 + * @num_leds - Number of LED strings are supported in this array 31 + */ 32 + struct lm36274 { 33 + struct platform_device *pdev; 34 + struct led_classdev led_dev; 35 + struct ti_lmu_bank lmu_data; 36 + struct regmap *regmap; 37 + struct device *dev; 38 + 39 + u32 led_sources[LM36274_MAX_STRINGS]; 40 + int num_leds; 41 + }; 42 + 43 + static int lm36274_brightness_set(struct led_classdev *led_cdev, 44 + enum led_brightness brt_val) 45 + { 46 + struct lm36274 *led = container_of(led_cdev, struct lm36274, led_dev); 47 + 48 + return ti_lmu_common_set_brightness(&led->lmu_data, brt_val); 49 + } 50 + 51 + static int lm36274_init(struct lm36274 *lm36274_data) 52 + { 53 + int enable_val = 0; 54 + int i; 55 + 56 + for (i = 0; i < lm36274_data->num_leds; i++) 57 + enable_val |= (1 << lm36274_data->led_sources[i]); 58 + 59 + if (!enable_val) { 60 + dev_err(lm36274_data->dev, "No LEDs were enabled\n"); 61 + return -EINVAL; 62 + } 63 + 64 + enable_val |= LM36274_BL_EN; 65 + 66 + return regmap_write(lm36274_data->regmap, LM36274_REG_BL_EN, 67 + enable_val); 68 + } 69 + 70 + static int lm36274_parse_dt(struct lm36274 *lm36274_data) 71 + { 72 + struct fwnode_handle *child = NULL; 73 + char label[LED_MAX_NAME_SIZE]; 74 + struct device *dev = &lm36274_data->pdev->dev; 75 + const char *name; 76 + int child_cnt; 77 + int ret = -EINVAL; 78 + 79 + /* There should only be 1 node */ 80 + child_cnt = device_get_child_node_count(dev); 81 + if (child_cnt != 1) 82 + return -EINVAL; 83 + 84 + device_for_each_child_node(dev, child) { 85 + ret = fwnode_property_read_string(child, "label", &name); 86 + if (ret) 87 + snprintf(label, sizeof(label), 88 + "%s::", lm36274_data->pdev->name); 89 + else 90 + snprintf(label, sizeof(label), 91 + "%s:%s", lm36274_data->pdev->name, name); 92 + 93 + lm36274_data->num_leds = fwnode_property_read_u32_array(child, 94 + "led-sources", 95 + NULL, 0); 96 + if (lm36274_data->num_leds <= 0) 97 + return -ENODEV; 98 + 99 + ret = fwnode_property_read_u32_array(child, "led-sources", 100 + lm36274_data->led_sources, 101 + lm36274_data->num_leds); 102 + if (ret) { 103 + dev_err(dev, "led-sources property missing\n"); 104 + return ret; 105 + } 106 + 107 + fwnode_property_read_string(child, "linux,default-trigger", 108 + &lm36274_data->led_dev.default_trigger); 109 + 110 + } 111 + 112 + lm36274_data->lmu_data.regmap = lm36274_data->regmap; 113 + lm36274_data->lmu_data.max_brightness = MAX_BRIGHTNESS_11BIT; 114 + lm36274_data->lmu_data.msb_brightness_reg = LM36274_REG_BRT_MSB; 115 + lm36274_data->lmu_data.lsb_brightness_reg = LM36274_REG_BRT_LSB; 116 + 117 + lm36274_data->led_dev.name = label; 118 + lm36274_data->led_dev.max_brightness = MAX_BRIGHTNESS_11BIT; 119 + lm36274_data->led_dev.brightness_set_blocking = lm36274_brightness_set; 120 + 121 + return 0; 122 + } 123 + 124 + static int lm36274_probe(struct platform_device *pdev) 125 + { 126 + struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent); 127 + struct lm36274 *lm36274_data; 128 + int ret; 129 + 130 + lm36274_data = devm_kzalloc(&pdev->dev, sizeof(*lm36274_data), 131 + GFP_KERNEL); 132 + if (!lm36274_data) 133 + return -ENOMEM; 134 + 135 + lm36274_data->pdev = pdev; 136 + lm36274_data->dev = lmu->dev; 137 + lm36274_data->regmap = lmu->regmap; 138 + dev_set_drvdata(&pdev->dev, lm36274_data); 139 + 140 + ret = lm36274_parse_dt(lm36274_data); 141 + if (ret) { 142 + dev_err(lm36274_data->dev, "Failed to parse DT node\n"); 143 + return ret; 144 + } 145 + 146 + ret = lm36274_init(lm36274_data); 147 + if (ret) { 148 + dev_err(lm36274_data->dev, "Failed to init the device\n"); 149 + return ret; 150 + } 151 + 152 + return devm_led_classdev_register(lm36274_data->dev, 153 + &lm36274_data->led_dev); 154 + } 155 + 156 + static const struct of_device_id of_lm36274_leds_match[] = { 157 + { .compatible = "ti,lm36274-backlight", }, 158 + {}, 159 + }; 160 + MODULE_DEVICE_TABLE(of, of_lm36274_leds_match); 161 + 162 + static struct platform_driver lm36274_driver = { 163 + .probe = lm36274_probe, 164 + .driver = { 165 + .name = "lm36274-leds", 166 + }, 167 + }; 168 + module_platform_driver(lm36274_driver) 169 + 170 + MODULE_DESCRIPTION("Texas Instruments LM36274 LED driver"); 171 + MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 172 + MODULE_LICENSE("GPL v2");
+395
drivers/leds/leds-lm3697.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // TI LM3697 LED chip family driver 3 + // Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ 4 + 5 + #include <linux/gpio/consumer.h> 6 + #include <linux/i2c.h> 7 + #include <linux/of.h> 8 + #include <linux/of_gpio.h> 9 + #include <linux/regulator/consumer.h> 10 + #include <linux/leds-ti-lmu-common.h> 11 + 12 + #define LM3697_REV 0x0 13 + #define LM3697_RESET 0x1 14 + #define LM3697_OUTPUT_CONFIG 0x10 15 + #define LM3697_CTRL_A_RAMP 0x11 16 + #define LM3697_CTRL_B_RAMP 0x12 17 + #define LM3697_CTRL_A_B_RT_RAMP 0x13 18 + #define LM3697_CTRL_A_B_RAMP_CFG 0x14 19 + #define LM3697_CTRL_A_B_BRT_CFG 0x16 20 + #define LM3697_CTRL_A_FS_CURR_CFG 0x17 21 + #define LM3697_CTRL_B_FS_CURR_CFG 0x18 22 + #define LM3697_PWM_CFG 0x1c 23 + #define LM3697_CTRL_A_BRT_LSB 0x20 24 + #define LM3697_CTRL_A_BRT_MSB 0x21 25 + #define LM3697_CTRL_B_BRT_LSB 0x22 26 + #define LM3697_CTRL_B_BRT_MSB 0x23 27 + #define LM3697_CTRL_ENABLE 0x24 28 + 29 + #define LM3697_SW_RESET BIT(0) 30 + 31 + #define LM3697_CTRL_A_EN BIT(0) 32 + #define LM3697_CTRL_B_EN BIT(1) 33 + #define LM3697_CTRL_A_B_EN (LM3697_CTRL_A_EN | LM3697_CTRL_B_EN) 34 + 35 + #define LM3697_MAX_LED_STRINGS 3 36 + 37 + #define LM3697_CONTROL_A 0 38 + #define LM3697_CONTROL_B 1 39 + #define LM3697_MAX_CONTROL_BANKS 2 40 + 41 + /** 42 + * struct lm3697_led - 43 + * @hvled_strings: Array of LED strings associated with a control bank 44 + * @label: LED label 45 + * @led_dev: LED class device 46 + * @priv: Pointer to the device struct 47 + * @lmu_data: Register and setting values for common code 48 + * @control_bank: Control bank the LED is associated to. 0 is control bank A 49 + * 1 is control bank B 50 + */ 51 + struct lm3697_led { 52 + u32 hvled_strings[LM3697_MAX_LED_STRINGS]; 53 + char label[LED_MAX_NAME_SIZE]; 54 + struct led_classdev led_dev; 55 + struct lm3697 *priv; 56 + struct ti_lmu_bank lmu_data; 57 + int control_bank; 58 + int enabled; 59 + int num_leds; 60 + }; 61 + 62 + /** 63 + * struct lm3697 - 64 + * @enable_gpio: Hardware enable gpio 65 + * @regulator: LED supply regulator pointer 66 + * @client: Pointer to the I2C client 67 + * @regmap: Devices register map 68 + * @dev: Pointer to the devices device struct 69 + * @lock: Lock for reading/writing the device 70 + * @leds: Array of LED strings 71 + */ 72 + struct lm3697 { 73 + struct gpio_desc *enable_gpio; 74 + struct regulator *regulator; 75 + struct i2c_client *client; 76 + struct regmap *regmap; 77 + struct device *dev; 78 + struct mutex lock; 79 + 80 + int bank_cfg; 81 + 82 + struct lm3697_led leds[]; 83 + }; 84 + 85 + static const struct reg_default lm3697_reg_defs[] = { 86 + {LM3697_OUTPUT_CONFIG, 0x6}, 87 + {LM3697_CTRL_A_RAMP, 0x0}, 88 + {LM3697_CTRL_B_RAMP, 0x0}, 89 + {LM3697_CTRL_A_B_RT_RAMP, 0x0}, 90 + {LM3697_CTRL_A_B_RAMP_CFG, 0x0}, 91 + {LM3697_CTRL_A_B_BRT_CFG, 0x0}, 92 + {LM3697_CTRL_A_FS_CURR_CFG, 0x13}, 93 + {LM3697_CTRL_B_FS_CURR_CFG, 0x13}, 94 + {LM3697_PWM_CFG, 0xc}, 95 + {LM3697_CTRL_A_BRT_LSB, 0x0}, 96 + {LM3697_CTRL_A_BRT_MSB, 0x0}, 97 + {LM3697_CTRL_B_BRT_LSB, 0x0}, 98 + {LM3697_CTRL_B_BRT_MSB, 0x0}, 99 + {LM3697_CTRL_ENABLE, 0x0}, 100 + }; 101 + 102 + static const struct regmap_config lm3697_regmap_config = { 103 + .reg_bits = 8, 104 + .val_bits = 8, 105 + 106 + .max_register = LM3697_CTRL_ENABLE, 107 + .reg_defaults = lm3697_reg_defs, 108 + .num_reg_defaults = ARRAY_SIZE(lm3697_reg_defs), 109 + .cache_type = REGCACHE_FLAT, 110 + }; 111 + 112 + static int lm3697_brightness_set(struct led_classdev *led_cdev, 113 + enum led_brightness brt_val) 114 + { 115 + struct lm3697_led *led = container_of(led_cdev, struct lm3697_led, 116 + led_dev); 117 + int ctrl_en_val = (1 << led->control_bank); 118 + int ret; 119 + 120 + mutex_lock(&led->priv->lock); 121 + 122 + if (brt_val == LED_OFF) { 123 + ret = regmap_update_bits(led->priv->regmap, LM3697_CTRL_ENABLE, 124 + ctrl_en_val, ~ctrl_en_val); 125 + if (ret) { 126 + dev_err(&led->priv->client->dev, "Cannot write ctrl register\n"); 127 + goto brightness_out; 128 + } 129 + 130 + led->enabled = LED_OFF; 131 + } else { 132 + ret = ti_lmu_common_set_brightness(&led->lmu_data, brt_val); 133 + if (ret) { 134 + dev_err(&led->priv->client->dev, 135 + "Cannot write brightness\n"); 136 + goto brightness_out; 137 + } 138 + 139 + if (!led->enabled) { 140 + ret = regmap_update_bits(led->priv->regmap, 141 + LM3697_CTRL_ENABLE, 142 + ctrl_en_val, ctrl_en_val); 143 + if (ret) { 144 + dev_err(&led->priv->client->dev, 145 + "Cannot enable the device\n"); 146 + goto brightness_out; 147 + } 148 + 149 + led->enabled = brt_val; 150 + } 151 + } 152 + 153 + brightness_out: 154 + mutex_unlock(&led->priv->lock); 155 + return ret; 156 + } 157 + 158 + static int lm3697_init(struct lm3697 *priv) 159 + { 160 + struct lm3697_led *led; 161 + int i, ret; 162 + 163 + if (priv->enable_gpio) { 164 + gpiod_direction_output(priv->enable_gpio, 1); 165 + } else { 166 + ret = regmap_write(priv->regmap, LM3697_RESET, LM3697_SW_RESET); 167 + if (ret) { 168 + dev_err(&priv->client->dev, "Cannot reset the device\n"); 169 + goto out; 170 + } 171 + } 172 + 173 + ret = regmap_write(priv->regmap, LM3697_CTRL_ENABLE, 0x0); 174 + if (ret) { 175 + dev_err(&priv->client->dev, "Cannot write ctrl enable\n"); 176 + goto out; 177 + } 178 + 179 + ret = regmap_write(priv->regmap, LM3697_OUTPUT_CONFIG, priv->bank_cfg); 180 + if (ret) 181 + dev_err(&priv->client->dev, "Cannot write OUTPUT config\n"); 182 + 183 + for (i = 0; i < LM3697_MAX_CONTROL_BANKS; i++) { 184 + led = &priv->leds[i]; 185 + ret = ti_lmu_common_set_ramp(&led->lmu_data); 186 + if (ret) 187 + dev_err(&priv->client->dev, "Setting the ramp rate failed\n"); 188 + } 189 + out: 190 + return ret; 191 + } 192 + 193 + static int lm3697_probe_dt(struct lm3697 *priv) 194 + { 195 + struct fwnode_handle *child = NULL; 196 + struct lm3697_led *led; 197 + const char *name; 198 + int control_bank; 199 + size_t i = 0; 200 + int ret = -EINVAL; 201 + int j; 202 + 203 + priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev, 204 + "enable", GPIOD_OUT_LOW); 205 + if (IS_ERR(priv->enable_gpio)) { 206 + ret = PTR_ERR(priv->enable_gpio); 207 + dev_err(&priv->client->dev, "Failed to get enable gpio: %d\n", 208 + ret); 209 + return ret; 210 + } 211 + 212 + priv->regulator = devm_regulator_get(&priv->client->dev, "vled"); 213 + if (IS_ERR(priv->regulator)) 214 + priv->regulator = NULL; 215 + 216 + device_for_each_child_node(priv->dev, child) { 217 + ret = fwnode_property_read_u32(child, "reg", &control_bank); 218 + if (ret) { 219 + dev_err(&priv->client->dev, "reg property missing\n"); 220 + fwnode_handle_put(child); 221 + goto child_out; 222 + } 223 + 224 + if (control_bank > LM3697_CONTROL_B) { 225 + dev_err(&priv->client->dev, "reg property is invalid\n"); 226 + ret = -EINVAL; 227 + fwnode_handle_put(child); 228 + goto child_out; 229 + } 230 + 231 + led = &priv->leds[i]; 232 + 233 + ret = ti_lmu_common_get_brt_res(&priv->client->dev, 234 + child, &led->lmu_data); 235 + if (ret) 236 + dev_warn(&priv->client->dev, "brightness resolution property missing\n"); 237 + 238 + led->control_bank = control_bank; 239 + led->lmu_data.regmap = priv->regmap; 240 + led->lmu_data.runtime_ramp_reg = LM3697_CTRL_A_RAMP + 241 + control_bank; 242 + led->lmu_data.msb_brightness_reg = LM3697_CTRL_A_BRT_MSB + 243 + led->control_bank * 2; 244 + led->lmu_data.lsb_brightness_reg = LM3697_CTRL_A_BRT_LSB + 245 + led->control_bank * 2; 246 + 247 + led->num_leds = fwnode_property_read_u32_array(child, 248 + "led-sources", 249 + NULL, 0); 250 + 251 + if (led->num_leds > LM3697_MAX_LED_STRINGS) { 252 + dev_err(&priv->client->dev, "To many LED strings defined\n"); 253 + continue; 254 + } 255 + 256 + ret = fwnode_property_read_u32_array(child, "led-sources", 257 + led->hvled_strings, 258 + led->num_leds); 259 + if (ret) { 260 + dev_err(&priv->client->dev, "led-sources property missing\n"); 261 + fwnode_handle_put(child); 262 + goto child_out; 263 + } 264 + 265 + for (j = 0; j < led->num_leds; j++) 266 + priv->bank_cfg |= 267 + (led->control_bank << led->hvled_strings[j]); 268 + 269 + ret = ti_lmu_common_get_ramp_params(&priv->client->dev, 270 + child, &led->lmu_data); 271 + if (ret) 272 + dev_warn(&priv->client->dev, "runtime-ramp properties missing\n"); 273 + 274 + fwnode_property_read_string(child, "linux,default-trigger", 275 + &led->led_dev.default_trigger); 276 + 277 + ret = fwnode_property_read_string(child, "label", &name); 278 + if (ret) 279 + snprintf(led->label, sizeof(led->label), 280 + "%s::", priv->client->name); 281 + else 282 + snprintf(led->label, sizeof(led->label), 283 + "%s:%s", priv->client->name, name); 284 + 285 + led->priv = priv; 286 + led->led_dev.name = led->label; 287 + led->led_dev.max_brightness = led->lmu_data.max_brightness; 288 + led->led_dev.brightness_set_blocking = lm3697_brightness_set; 289 + 290 + ret = devm_led_classdev_register(priv->dev, &led->led_dev); 291 + if (ret) { 292 + dev_err(&priv->client->dev, "led register err: %d\n", 293 + ret); 294 + fwnode_handle_put(child); 295 + goto child_out; 296 + } 297 + 298 + i++; 299 + } 300 + 301 + child_out: 302 + return ret; 303 + } 304 + 305 + static int lm3697_probe(struct i2c_client *client, 306 + const struct i2c_device_id *id) 307 + { 308 + struct lm3697 *led; 309 + int count; 310 + int ret; 311 + 312 + count = device_get_child_node_count(&client->dev); 313 + if (!count) { 314 + dev_err(&client->dev, "LEDs are not defined in device tree!"); 315 + return -ENODEV; 316 + } 317 + 318 + led = devm_kzalloc(&client->dev, struct_size(led, leds, count), 319 + GFP_KERNEL); 320 + if (!led) 321 + return -ENOMEM; 322 + 323 + mutex_init(&led->lock); 324 + i2c_set_clientdata(client, led); 325 + 326 + led->client = client; 327 + led->dev = &client->dev; 328 + led->regmap = devm_regmap_init_i2c(client, &lm3697_regmap_config); 329 + if (IS_ERR(led->regmap)) { 330 + ret = PTR_ERR(led->regmap); 331 + dev_err(&client->dev, "Failed to allocate register map: %d\n", 332 + ret); 333 + return ret; 334 + } 335 + 336 + ret = lm3697_probe_dt(led); 337 + if (ret) 338 + return ret; 339 + 340 + return lm3697_init(led); 341 + } 342 + 343 + static int lm3697_remove(struct i2c_client *client) 344 + { 345 + struct lm3697 *led = i2c_get_clientdata(client); 346 + int ret; 347 + 348 + ret = regmap_update_bits(led->regmap, LM3697_CTRL_ENABLE, 349 + LM3697_CTRL_A_B_EN, 0); 350 + if (ret) { 351 + dev_err(&led->client->dev, "Failed to disable the device\n"); 352 + return ret; 353 + } 354 + 355 + if (led->enable_gpio) 356 + gpiod_direction_output(led->enable_gpio, 0); 357 + 358 + if (led->regulator) { 359 + ret = regulator_disable(led->regulator); 360 + if (ret) 361 + dev_err(&led->client->dev, 362 + "Failed to disable regulator\n"); 363 + } 364 + 365 + mutex_destroy(&led->lock); 366 + 367 + return 0; 368 + } 369 + 370 + static const struct i2c_device_id lm3697_id[] = { 371 + { "lm3697", 0 }, 372 + { } 373 + }; 374 + MODULE_DEVICE_TABLE(i2c, lm3697_id); 375 + 376 + static const struct of_device_id of_lm3697_leds_match[] = { 377 + { .compatible = "ti,lm3697", }, 378 + {}, 379 + }; 380 + MODULE_DEVICE_TABLE(of, of_lm3697_leds_match); 381 + 382 + static struct i2c_driver lm3697_driver = { 383 + .driver = { 384 + .name = "lm3697", 385 + .of_match_table = of_lm3697_leds_match, 386 + }, 387 + .probe = lm3697_probe, 388 + .remove = lm3697_remove, 389 + .id_table = lm3697_id, 390 + }; 391 + module_i2c_driver(lm3697_driver); 392 + 393 + MODULE_DESCRIPTION("Texas Instruments LM3697 LED driver"); 394 + MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 395 + MODULE_LICENSE("GPL v2");
+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");
+2 -3
drivers/mfd/Kconfig
··· 1335 1335 select REGMAP_I2C 1336 1336 help 1337 1337 Say yes here to enable support for TI LMU chips. 1338 - 1339 - TI LMU MFD supports LM3532, LM3631, LM3632, LM3633, LM3695 and LM3697. 1340 - It consists of backlight, LED and regulator driver. 1338 + TI LMU MFD supports LM3532, LM3631, LM3632, LM3633, LM3695 and 1339 + LM36274. It consists of backlight, LED and regulator driver. 1341 1340 It provides consistent device controls for lighting functions. 1342 1341 1343 1342 config MFD_OMAP_USB_HOST
+10 -13
drivers/mfd/ti-lmu.c
··· 111 111 }, 112 112 }; 113 113 114 - static const struct mfd_cell lm3697_devices[] = { 114 + static const struct mfd_cell lm36274_devices[] = { 115 + LM363X_REGULATOR(LM36274_BOOST), 116 + LM363X_REGULATOR(LM36274_LDO_POS), 117 + LM363X_REGULATOR(LM36274_LDO_NEG), 115 118 { 116 - .name = "ti-lmu-backlight", 117 - .id = LM3697, 118 - .of_compatible = "ti,lm3697-backlight", 119 - }, 120 - /* Monitoring driver for open/short circuit detection */ 121 - { 122 - .name = "ti-lmu-fault-monitor", 123 - .id = LM3697, 124 - .of_compatible = "ti,lm3697-fault-monitor", 119 + .name = "lm36274-leds", 120 + .id = LM36274, 121 + .of_compatible = "ti,lm36274-backlight", 125 122 }, 126 123 }; 127 124 ··· 134 137 TI_LMU_DATA(lm3632, LM3632_MAX_REG); 135 138 TI_LMU_DATA(lm3633, LM3633_MAX_REG); 136 139 TI_LMU_DATA(lm3695, LM3695_MAX_REG); 137 - TI_LMU_DATA(lm3697, LM3697_MAX_REG); 140 + TI_LMU_DATA(lm36274, LM36274_MAX_REG); 138 141 139 142 static int ti_lmu_probe(struct i2c_client *cl, const struct i2c_device_id *id) 140 143 { ··· 203 206 { .compatible = "ti,lm3632", .data = &lm3632_data }, 204 207 { .compatible = "ti,lm3633", .data = &lm3633_data }, 205 208 { .compatible = "ti,lm3695", .data = &lm3695_data }, 206 - { .compatible = "ti,lm3697", .data = &lm3697_data }, 209 + { .compatible = "ti,lm36274", .data = &lm36274_data }, 207 210 { } 208 211 }; 209 212 MODULE_DEVICE_TABLE(of, ti_lmu_of_match); ··· 213 216 { "lm3632", LM3632 }, 214 217 { "lm3633", LM3633 }, 215 218 { "lm3695", LM3695 }, 216 - { "lm3697", LM3697 }, 219 + { "lm36274", LM36274 }, 217 220 { } 218 221 }; 219 222 MODULE_DEVICE_TABLE(i2c, ti_lmu_ids);
+1 -1
drivers/regulator/Kconfig
··· 363 363 tristate "TI LM363X voltage regulators" 364 364 depends on MFD_TI_LMU 365 365 help 366 - This driver supports LM3631 and LM3632 voltage regulators for 366 + This driver supports LM3631, LM3632 and LM36274 voltage regulators for 367 367 the LCD bias. 368 368 One boost output voltage is configurable and always on. 369 369 Other LDOs are used for the display module.
+74 -4
drivers/regulator/lm363x-regulator.c
··· 37 37 #define LM3632_VBOOST_MIN 4500000 38 38 #define LM3632_VLDO_MIN 4000000 39 39 40 + /* LM36274 */ 41 + #define LM36274_BOOST_VSEL_MAX 0x3f 42 + #define LM36274_LDO_VSEL_MAX 0x34 43 + #define LM36274_VOLTAGE_MIN 4000000 44 + 40 45 /* Common */ 41 46 #define LM363X_STEP_50mV 50000 42 47 #define LM363X_STEP_500mV 500000 ··· 222 217 .enable_reg = LM3632_REG_BIAS_CONFIG, 223 218 .enable_mask = LM3632_EN_VNEG_MASK, 224 219 }, 220 + 221 + /* LM36274 */ 222 + { 223 + .name = "vboost", 224 + .of_match = "vboost", 225 + .id = LM36274_BOOST, 226 + .ops = &lm363x_boost_voltage_table_ops, 227 + .n_voltages = LM36274_BOOST_VSEL_MAX, 228 + .min_uV = LM36274_VOLTAGE_MIN, 229 + .uV_step = LM363X_STEP_50mV, 230 + .type = REGULATOR_VOLTAGE, 231 + .owner = THIS_MODULE, 232 + .vsel_reg = LM36274_REG_VOUT_BOOST, 233 + .vsel_mask = LM36274_VOUT_MASK, 234 + }, 235 + { 236 + .name = "ldo_vpos", 237 + .of_match = "vpos", 238 + .id = LM36274_LDO_POS, 239 + .ops = &lm363x_regulator_voltage_table_ops, 240 + .n_voltages = LM36274_LDO_VSEL_MAX, 241 + .min_uV = LM36274_VOLTAGE_MIN, 242 + .uV_step = LM363X_STEP_50mV, 243 + .type = REGULATOR_VOLTAGE, 244 + .owner = THIS_MODULE, 245 + .vsel_reg = LM36274_REG_VOUT_POS, 246 + .vsel_mask = LM36274_VOUT_MASK, 247 + .enable_reg = LM36274_REG_BIAS_CONFIG_1, 248 + .enable_mask = LM36274_EN_VPOS_MASK, 249 + }, 250 + { 251 + .name = "ldo_vneg", 252 + .of_match = "vneg", 253 + .id = LM36274_LDO_NEG, 254 + .ops = &lm363x_regulator_voltage_table_ops, 255 + .n_voltages = LM36274_LDO_VSEL_MAX, 256 + .min_uV = LM36274_VOLTAGE_MIN, 257 + .uV_step = LM363X_STEP_50mV, 258 + .type = REGULATOR_VOLTAGE, 259 + .owner = THIS_MODULE, 260 + .vsel_reg = LM36274_REG_VOUT_NEG, 261 + .vsel_mask = LM36274_VOUT_MASK, 262 + .enable_reg = LM36274_REG_BIAS_CONFIG_1, 263 + .enable_mask = LM36274_EN_VNEG_MASK, 264 + }, 225 265 }; 226 266 227 267 static struct gpio_desc *lm363x_regulator_of_get_enable_gpio(struct device *dev, int id) ··· 279 229 */ 280 230 switch (id) { 281 231 case LM3632_LDO_POS: 232 + case LM36274_LDO_POS: 282 233 return gpiod_get_index_optional(dev, "enable", 0, 283 234 GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE); 284 235 case LM3632_LDO_NEG: 236 + case LM36274_LDO_NEG: 285 237 return gpiod_get_index_optional(dev, "enable", 1, 286 238 GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE); 287 239 default: 288 240 return NULL; 289 241 } 242 + } 243 + 244 + static int lm363x_regulator_set_ext_en(struct regmap *regmap, int id) 245 + { 246 + int ext_en_mask = 0; 247 + 248 + switch (id) { 249 + case LM3632_LDO_POS: 250 + case LM3632_LDO_NEG: 251 + ext_en_mask = LM3632_EXT_EN_MASK; 252 + break; 253 + case LM36274_LDO_POS: 254 + case LM36274_LDO_NEG: 255 + ext_en_mask = LM36274_EXT_EN_MASK; 256 + break; 257 + default: 258 + return -ENODEV; 259 + } 260 + 261 + return regmap_update_bits(regmap, lm363x_regulator_desc[id].enable_reg, 262 + ext_en_mask, ext_en_mask); 290 263 } 291 264 292 265 static int lm363x_regulator_probe(struct platform_device *pdev) ··· 336 263 337 264 if (gpiod) { 338 265 cfg.ena_gpiod = gpiod; 339 - 340 - ret = regmap_update_bits(regmap, LM3632_REG_BIAS_CONFIG, 341 - LM3632_EXT_EN_MASK, 342 - LM3632_EXT_EN_MASK); 266 + ret = lm363x_regulator_set_ext_en(regmap, id); 343 267 if (ret) { 344 268 gpiod_put(gpiod); 345 269 dev_err(dev, "External pin err: %d\n", ret);
+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_ */
+18 -39
include/linux/mfd/ti-lmu-register.h
··· 190 190 191 191 #define LM3695_MAX_REG 0x14 192 192 193 - /* LM3697 */ 194 - #define LM3697_REG_HVLED_OUTPUT_CFG 0x10 195 - #define LM3697_HVLED1_CFG_MASK BIT(0) 196 - #define LM3697_HVLED2_CFG_MASK BIT(1) 197 - #define LM3697_HVLED3_CFG_MASK BIT(2) 198 - #define LM3697_HVLED1_CFG_SHIFT 0 199 - #define LM3697_HVLED2_CFG_SHIFT 1 200 - #define LM3697_HVLED3_CFG_SHIFT 2 193 + /* LM36274 */ 194 + #define LM36274_REG_REV 0x01 195 + #define LM36274_REG_BL_CFG_1 0x02 196 + #define LM36274_REG_BL_CFG_2 0x03 197 + #define LM36274_REG_BRT_LSB 0x04 198 + #define LM36274_REG_BRT_MSB 0x05 199 + #define LM36274_REG_BL_EN 0x08 201 200 202 - #define LM3697_REG_BL0_RAMP 0x11 203 - #define LM3697_REG_BL1_RAMP 0x12 204 - #define LM3697_RAMPUP_MASK 0xF0 205 - #define LM3697_RAMPUP_SHIFT 4 206 - #define LM3697_RAMPDN_MASK 0x0F 207 - #define LM3697_RAMPDN_SHIFT 0 201 + #define LM36274_REG_BIAS_CONFIG_1 0x09 202 + #define LM36274_EXT_EN_MASK BIT(0) 203 + #define LM36274_EN_VNEG_MASK BIT(1) 204 + #define LM36274_EN_VPOS_MASK BIT(2) 208 205 209 - #define LM3697_REG_RAMP_CONF 0x14 210 - #define LM3697_RAMP_MASK 0x0F 211 - #define LM3697_RAMP_EACH 0x05 206 + #define LM36274_REG_BIAS_CONFIG_2 0x0a 207 + #define LM36274_REG_BIAS_CONFIG_3 0x0b 208 + #define LM36274_REG_VOUT_BOOST 0x0c 209 + #define LM36274_REG_VOUT_POS 0x0d 210 + #define LM36274_REG_VOUT_NEG 0x0e 211 + #define LM36274_VOUT_MASK 0x3F 212 212 213 - #define LM3697_REG_PWM_CFG 0x1C 214 - #define LM3697_PWM_A_MASK BIT(0) 215 - #define LM3697_PWM_B_MASK BIT(1) 213 + #define LM36274_MAX_REG 0x13 216 214 217 - #define LM3697_REG_IMAX_A 0x17 218 - #define LM3697_REG_IMAX_B 0x18 219 - 220 - #define LM3697_REG_FEEDBACK_ENABLE 0x19 221 - 222 - #define LM3697_REG_BRT_A_LSB 0x20 223 - #define LM3697_REG_BRT_A_MSB 0x21 224 - #define LM3697_REG_BRT_B_LSB 0x22 225 - #define LM3697_REG_BRT_B_MSB 0x23 226 - 227 - #define LM3697_REG_ENABLE 0x24 228 - 229 - #define LM3697_REG_OPEN_FAULT_STATUS 0xB0 230 - 231 - #define LM3697_REG_SHORT_FAULT_STATUS 0xB2 232 - 233 - #define LM3697_REG_MONITOR_ENABLE 0xB4 234 - 235 - #define LM3697_MAX_REG 0xB4 236 215 #endif
+4 -1
include/linux/mfd/ti-lmu.h
··· 26 26 LM3632, 27 27 LM3633, 28 28 LM3695, 29 - LM3697, 29 + LM36274, 30 30 LMU_MAX_ID, 31 31 }; 32 32 ··· 68 68 LM3632_BOOST, /* Boost output */ 69 69 LM3632_LDO_POS, /* Positive display bias output */ 70 70 LM3632_LDO_NEG, /* Negative display bias output */ 71 + LM36274_BOOST, /* Boost output */ 72 + LM36274_LDO_POS, /* Positive display bias output */ 73 + LM36274_LDO_NEG, /* Negative display bias output */ 71 74 }; 72 75 73 76 /**