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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'leds-next-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds

Pull LED updates from Lee Jones:
"Core Frameworks:
- New trigger for Input Events
- New led_mc_set_brightness() call to adapt colour/brightness for
mutli-colour LEDs
- New lled_mc_trigger_event() call to call the above based on given
trigger conditions
- New led_get_color_name() call, a wrapper around the existing
led_colors[] array
- A new flag to avoid automatic renaming of LED devices

New Drivers:
- Silergy SY7802 Flash LED Controller
- Texas Instruments LP5569 LED Controller
- ChromeOS EC LED Controller

New Device Support:
- KTD202{6,7} support for Kinetic KTD2026/7 LEDs

Fix-ups:
- Replace ACPI/DT firmware helpers with agnostic variants
- Make use of resource managed devm_* API calls
- Device Tree binding adaptions/conversions/creation
- Constify/staticise applicable data structures
- Trivial; spelling, whitespace, coding-style adaptions
- Drop i2c_device_id::driver_data where the value is unused
- Utilise centrally provided helpers and macros to aid simplicity and
avoid duplication
- Use generic platform device properties instead of OF/ACPI specific
ones
- Consolidate/de-duplicate various functionality
- Remove superfluous/duplicated/unused sections
- Make use of the new *_scoped() guard APIs
- Improve/simplify error handling

Bug Fixes:
- Flush pending brightness changes before activating the trigger
- Repair incorrect device naming preventing matches
- Prevent memory leaks by correctly free resources during error
handling routines
- Repair locking issue causing circular dependency splats and
lock-ups
- Unregister sysfs entries before deactivating triggers to prevent
use-after issues
- Supply a bunch of MODULE_DESCRIPTIONs to silence modpost warnings
- Use correct return codes expected by the callers
- Omit set_brightness() error message for a LEDs that support only HW
triggers"

* tag 'leds-next-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds: (65 commits)
leds: leds-lp5569: Enable chip after chip configuration
leds: leds-lp5569: Better handle enabling clock internal setting
leds: leds-lp5569: Fix typo in driver name
leds: flash: leds-qcom-flash: Test the correct variable in init
leds: leds-lp55xx: Convert mutex lock/unlock to guard API
leds: leds-lp5523: Convert to sysfs_emit API
leds: leds-lp5569: Convert to sysfs_emit API
Revert "leds: led-core: Fix refcount leak in of_led_get()"
leds: leds-lp5569: Add support for Texas Instruments LP5569
leds: leds-lp55xx: Drop deprecated defines
leds: leds-lp55xx: Support ENGINE program up to 128 bytes
leds: leds-lp55xx: Generalize sysfs master_fader
leds: leds-lp55xx: Generalize sysfs engine_leds
leds: leds-lp55xx: Generalize sysfs engine_load and engine_mode
leds: leds-lp55xx: Generalize stop_engine function
leds: leds-lp55xx: Generalize turn_off_channels function
leds: leds-lp55xx: Generalize set_led_current function
leds: leds-lp55xx: Generalize multicolor_brightness function
leds: leds-lp55xx: Generalize led_brightness function
leds: leds-lp55xx: Generalize firmware_loaded function
...

+2728 -1864
+11
Documentation/devicetree/bindings/leds/leds-lp55xx.yaml
··· 28 28 - national,lp5523 29 29 - ti,lp55231 30 30 - ti,lp5562 31 + - ti,lp5569 31 32 - ti,lp8501 32 33 33 34 reg: ··· 151 150 chan-name: 152 151 $ref: /schemas/types.yaml#/definitions/string 153 152 description: name of channel 153 + 154 + if: 155 + not: 156 + properties: 157 + compatible: 158 + contains: 159 + const: ti,lp8501 160 + then: 161 + properties: 162 + pwr-sel: false 154 163 155 164 required: 156 165 - compatible
+100
Documentation/devicetree/bindings/leds/silergy,sy7802.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/leds/silergy,sy7802.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Silergy SY7802 1800mA Boost Charge Pump LED Driver 8 + 9 + maintainers: 10 + - André Apitzsch <git@apitzsch.eu> 11 + 12 + description: | 13 + The SY7802 is a current-regulated charge pump which can regulate two current 14 + levels for Flash and Torch modes. 15 + 16 + The SY7802 is a high-current synchronous boost converter with 2-channel 17 + high side current sources. Each channel is able to deliver 900mA current. 18 + 19 + properties: 20 + compatible: 21 + enum: 22 + - silergy,sy7802 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + enable-gpios: 28 + maxItems: 1 29 + description: A connection to the 'EN' pin. 30 + 31 + flash-gpios: 32 + maxItems: 1 33 + description: A connection to the 'FLEN' pin. 34 + 35 + vin-supply: 36 + description: Regulator providing power to the 'VIN' pin. 37 + 38 + "#address-cells": 39 + const: 1 40 + 41 + "#size-cells": 42 + const: 0 43 + 44 + patternProperties: 45 + "^led@[0-1]$": 46 + type: object 47 + $ref: common.yaml# 48 + unevaluatedProperties: false 49 + 50 + properties: 51 + reg: 52 + description: Index of the LED. 53 + minimum: 0 54 + maximum: 1 55 + 56 + led-sources: 57 + minItems: 1 58 + maxItems: 2 59 + items: 60 + minimum: 0 61 + maximum: 1 62 + 63 + required: 64 + - reg 65 + - led-sources 66 + 67 + required: 68 + - compatible 69 + - reg 70 + - "#address-cells" 71 + - "#size-cells" 72 + - enable-gpios 73 + 74 + additionalProperties: false 75 + 76 + examples: 77 + - | 78 + #include <dt-bindings/gpio/gpio.h> 79 + #include <dt-bindings/leds/common.h> 80 + 81 + i2c { 82 + #address-cells = <1>; 83 + #size-cells = <0>; 84 + 85 + flash-led-controller@53 { 86 + compatible = "silergy,sy7802"; 87 + reg = <0x53>; 88 + #address-cells = <1>; 89 + #size-cells = <0>; 90 + 91 + enable-gpios = <&tlmm 16 GPIO_ACTIVE_HIGH>; 92 + 93 + led@0 { 94 + reg = <0>; 95 + function = LED_FUNCTION_FLASH; 96 + color = <LED_COLOR_ID_WHITE>; 97 + led-sources = <0>, <1>; 98 + }; 99 + }; 100 + };
+1 -1
Documentation/leds/leds-blinkm.rst
··· 7 7 They are RGB-LED modules driven by a (AT)tiny microcontroller and 8 8 communicate through I2C. The default address of these modules is 9 9 0x09 but this can be changed through a command. By this you could 10 - dasy-chain up to 127 BlinkMs on an I2C bus. 10 + daisy-chain up to 127 BlinkMs on an I2C bus. 11 11 12 12 The device accepts RGB and HSB color values through separate commands. 13 13 Also you can store blinking sequences as "scripts" in
+1 -1
MAINTAINERS
··· 12598 12598 M: Lee Jones <lee@kernel.org> 12599 12599 L: linux-leds@vger.kernel.org 12600 12600 S: Maintained 12601 - T: git git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git 12601 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds.git 12602 12602 F: Documentation/devicetree/bindings/leds/ 12603 12603 F: Documentation/leds/ 12604 12604 F: drivers/leds/
+13 -4
drivers/leds/Kconfig
··· 429 429 module will be called leds-lp50xx. 430 430 431 431 config LEDS_LP55XX_COMMON 432 - tristate "Common Driver for TI/National LP5521/5523/55231/5562/8501" 432 + tristate "Common Driver for TI/National LP5521/5523/55231/5562/5569/8501" 433 433 depends on LEDS_CLASS 434 434 depends on LEDS_CLASS_MULTICOLOR 435 435 depends on OF ··· 437 437 select FW_LOADER 438 438 select FW_LOADER_USER_HELPER 439 439 help 440 - This option supports common operations for LP5521/5523/55231/5562/8501 441 - devices. 440 + This option supports common operations for LP5521/5523/55231/5562/5569/ 441 + 8501 devices. 442 442 443 443 config LEDS_LP5521 444 444 tristate "LED Support for N.S. LP5521 LED driver chip" ··· 468 468 help 469 469 If you say yes here you get support for TI LP5562 LED driver. 470 470 It is 4 channels chip with programmable engines. 471 + Driver provides direct control via LED class and interface for 472 + programming the engines. 473 + 474 + config LEDS_LP5569 475 + tristate "LED Support for TI LP5569 LED driver chip" 476 + depends on LEDS_CLASS && I2C 477 + depends on LEDS_LP55XX_COMMON 478 + help 479 + If you say yes here you get support for TI LP5569 LED driver. 480 + It is 9 channels chip with programmable engines. 471 481 Driver provides direct control via LED class and interface for 472 482 programming the engines. 473 483 ··· 894 884 tristate "LED support for SPI LED controller with a single byte" 895 885 depends on LEDS_CLASS 896 886 depends on SPI 897 - depends on OF 898 887 help 899 888 This option enables support for LED controller which use a single byte 900 889 for controlling the brightness. Currently the following controller is
+1
drivers/leds/Makefile
··· 52 52 obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o 53 53 obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o 54 54 obj-$(CONFIG_LEDS_LP5562) += leds-lp5562.o 55 + obj-$(CONFIG_LEDS_LP5569) += leds-lp5569.o 55 56 obj-$(CONFIG_LEDS_LP55XX_COMMON) += leds-lp55xx-common.o 56 57 obj-$(CONFIG_LEDS_LP8501) += leds-lp8501.o 57 58 obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
+1
drivers/leds/blink/leds-bcm63138.c
··· 303 303 module_platform_driver(bcm63138_leds_driver); 304 304 305 305 MODULE_AUTHOR("Rafał Miłecki"); 306 + MODULE_DESCRIPTION("Broadcom BCM63138 SoC LED driver"); 306 307 MODULE_LICENSE("GPL"); 307 308 MODULE_DEVICE_TABLE(of, bcm63138_leds_of_match_table);
+11
drivers/leds/flash/Kconfig
··· 121 121 This option enables support for the SGM3140 500mA Buck/Boost Charge 122 122 Pump LED Driver. 123 123 124 + config LEDS_SY7802 125 + tristate "LED support for the Silergy SY7802" 126 + depends on I2C && OF 127 + depends on GPIOLIB 128 + select REGMAP_I2C 129 + help 130 + This option enables support for the SY7802 flash LED controller. 131 + SY7802 includes torch and flash functions with programmable current. 132 + 133 + This driver can be built as a module, it will be called "leds-sy7802". 134 + 124 135 endif # LEDS_CLASS_FLASH
+1
drivers/leds/flash/Makefile
··· 11 11 obj-$(CONFIG_LEDS_RT4505) += leds-rt4505.o 12 12 obj-$(CONFIG_LEDS_RT8515) += leds-rt8515.o 13 13 obj-$(CONFIG_LEDS_SGM3140) += leds-sgm3140.o 14 + obj-$(CONFIG_LEDS_SY7802) += leds-sy7802.o
+2 -2
drivers/leds/flash/leds-as3645a.c
··· 743 743 } 744 744 745 745 static const struct i2c_device_id as3645a_id_table[] = { 746 - { AS_NAME, 0 }, 747 - { }, 746 + { AS_NAME }, 747 + { } 748 748 }; 749 749 MODULE_DEVICE_TABLE(i2c, as3645a_id_table); 750 750
+4 -1
drivers/leds/flash/leds-mt6360.c
··· 643 643 644 644 ret = fwnode_property_read_u32(child, "reg", &reg); 645 645 if (ret || reg > MT6360_LED_ISNK3 || 646 - priv->leds_active & BIT(reg)) 646 + priv->leds_active & BIT(reg)) { 647 + fwnode_handle_put(child); 647 648 return -EINVAL; 649 + } 648 650 649 651 ret = fwnode_property_read_u32(child, "color", &color); 650 652 if (ret) { 651 653 dev_err(priv->dev, 652 654 "led %d, no color specified\n", 653 655 led->led_no); 656 + fwnode_handle_put(child); 654 657 return ret; 655 658 } 656 659
+7 -3
drivers/leds/flash/leds-qcom-flash.c
··· 505 505 struct qcom_flash_data *flash_data = led->flash_data; 506 506 struct v4l2_flash_config v4l2_cfg = { 0 }; 507 507 struct led_flash_setting *intensity = &v4l2_cfg.intensity; 508 + struct v4l2_flash *v4l2_flash; 508 509 509 510 if (!(led->flash.led_cdev.flags & LED_DEV_CAP_FLASH)) 510 511 return 0; ··· 524 523 LED_FAULT_OVER_TEMPERATURE | 525 524 LED_FAULT_TIMEOUT; 526 525 527 - flash_data->v4l2_flash[flash_data->leds_count] = 528 - v4l2_flash_init(dev, fwnode, &led->flash, &qcom_v4l2_flash_ops, &v4l2_cfg); 529 - return PTR_ERR_OR_ZERO(flash_data->v4l2_flash); 526 + v4l2_flash = v4l2_flash_init(dev, fwnode, &led->flash, &qcom_v4l2_flash_ops, &v4l2_cfg); 527 + if (IS_ERR(v4l2_flash)) 528 + return PTR_ERR(v4l2_flash); 529 + 530 + flash_data->v4l2_flash[flash_data->leds_count] = v4l2_flash; 531 + return 0; 530 532 } 531 533 # else 532 534 static int
+1
drivers/leds/flash/leds-rt4505.c
··· 426 426 module_i2c_driver(rt4505_driver); 427 427 428 428 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); 429 + MODULE_DESCRIPTION("Richtek RT4505 LED driver"); 429 430 MODULE_LICENSE("GPL v2");
+539
drivers/leds/flash/leds-sy7802.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Silergy SY7802 flash LED driver with an I2C interface 4 + * 5 + * Copyright 2024 André Apitzsch <git@apitzsch.eu> 6 + */ 7 + 8 + #include <linux/gpio/consumer.h> 9 + #include <linux/i2c.h> 10 + #include <linux/kernel.h> 11 + #include <linux/led-class-flash.h> 12 + #include <linux/module.h> 13 + #include <linux/mutex.h> 14 + #include <linux/regmap.h> 15 + #include <linux/regulator/consumer.h> 16 + 17 + #define SY7802_MAX_LEDS 2 18 + #define SY7802_LED_JOINT 2 19 + 20 + #define SY7802_REG_ENABLE 0x10 21 + #define SY7802_REG_TORCH_BRIGHTNESS 0xa0 22 + #define SY7802_REG_FLASH_BRIGHTNESS 0xb0 23 + #define SY7802_REG_FLASH_DURATION 0xc0 24 + #define SY7802_REG_FLAGS 0xd0 25 + #define SY7802_REG_CONFIG_1 0xe0 26 + #define SY7802_REG_CONFIG_2 0xf0 27 + #define SY7802_REG_VIN_MONITOR 0x80 28 + #define SY7802_REG_LAST_FLASH 0x81 29 + #define SY7802_REG_VLED_MONITOR 0x30 30 + #define SY7802_REG_ADC_DELAY 0x31 31 + #define SY7802_REG_DEV_ID 0xff 32 + 33 + #define SY7802_MODE_OFF 0 34 + #define SY7802_MODE_TORCH 2 35 + #define SY7802_MODE_FLASH 3 36 + #define SY7802_MODE_MASK GENMASK(1, 0) 37 + 38 + #define SY7802_LEDS_SHIFT 3 39 + #define SY7802_LEDS_MASK(_id) (BIT(_id) << SY7802_LEDS_SHIFT) 40 + #define SY7802_LEDS_MASK_ALL (SY7802_LEDS_MASK(0) | SY7802_LEDS_MASK(1)) 41 + 42 + #define SY7802_TORCH_CURRENT_SHIFT 3 43 + #define SY7802_TORCH_CURRENT_MASK(_id) \ 44 + (GENMASK(2, 0) << (SY7802_TORCH_CURRENT_SHIFT * (_id))) 45 + #define SY7802_TORCH_CURRENT_MASK_ALL \ 46 + (SY7802_TORCH_CURRENT_MASK(0) | SY7802_TORCH_CURRENT_MASK(1)) 47 + 48 + #define SY7802_FLASH_CURRENT_SHIFT 4 49 + #define SY7802_FLASH_CURRENT_MASK(_id) \ 50 + (GENMASK(3, 0) << (SY7802_FLASH_CURRENT_SHIFT * (_id))) 51 + #define SY7802_FLASH_CURRENT_MASK_ALL \ 52 + (SY7802_FLASH_CURRENT_MASK(0) | SY7802_FLASH_CURRENT_MASK(1)) 53 + 54 + #define SY7802_TIMEOUT_DEFAULT_US 512000U 55 + #define SY7802_TIMEOUT_MIN_US 32000U 56 + #define SY7802_TIMEOUT_MAX_US 1024000U 57 + #define SY7802_TIMEOUT_STEPSIZE_US 32000U 58 + 59 + #define SY7802_TORCH_BRIGHTNESS_MAX 8 60 + 61 + #define SY7802_FLASH_BRIGHTNESS_DEFAULT 14 62 + #define SY7802_FLASH_BRIGHTNESS_MIN 0 63 + #define SY7802_FLASH_BRIGHTNESS_MAX 15 64 + #define SY7802_FLASH_BRIGHTNESS_STEP 1 65 + 66 + #define SY7802_FLAG_TIMEOUT BIT(0) 67 + #define SY7802_FLAG_THERMAL_SHUTDOWN BIT(1) 68 + #define SY7802_FLAG_LED_FAULT BIT(2) 69 + #define SY7802_FLAG_TX1_INTERRUPT BIT(3) 70 + #define SY7802_FLAG_TX2_INTERRUPT BIT(4) 71 + #define SY7802_FLAG_LED_THERMAL_FAULT BIT(5) 72 + #define SY7802_FLAG_FLASH_INPUT_VOLTAGE_LOW BIT(6) 73 + #define SY7802_FLAG_INPUT_VOLTAGE_LOW BIT(7) 74 + 75 + #define SY7802_CHIP_ID 0x51 76 + 77 + static const struct reg_default sy7802_regmap_defs[] = { 78 + { SY7802_REG_ENABLE, SY7802_LEDS_MASK_ALL }, 79 + { SY7802_REG_TORCH_BRIGHTNESS, 0x92 }, 80 + { SY7802_REG_FLASH_BRIGHTNESS, SY7802_FLASH_BRIGHTNESS_DEFAULT | 81 + SY7802_FLASH_BRIGHTNESS_DEFAULT << SY7802_FLASH_CURRENT_SHIFT }, 82 + { SY7802_REG_FLASH_DURATION, 0x6f }, 83 + { SY7802_REG_FLAGS, 0x0 }, 84 + { SY7802_REG_CONFIG_1, 0x68 }, 85 + { SY7802_REG_CONFIG_2, 0xf0 }, 86 + }; 87 + 88 + struct sy7802_led { 89 + struct led_classdev_flash flash; 90 + struct sy7802 *chip; 91 + u8 led_id; 92 + }; 93 + 94 + struct sy7802 { 95 + struct device *dev; 96 + struct regmap *regmap; 97 + struct mutex mutex; 98 + 99 + struct gpio_desc *enable_gpio; 100 + struct regulator *vin_regulator; 101 + 102 + unsigned int fled_strobe_used; 103 + unsigned int fled_torch_used; 104 + unsigned int leds_active; 105 + int num_leds; 106 + struct sy7802_led leds[] __counted_by(num_leds); 107 + }; 108 + 109 + static int sy7802_torch_brightness_set(struct led_classdev *lcdev, enum led_brightness brightness) 110 + { 111 + struct sy7802_led *led = container_of(lcdev, struct sy7802_led, flash.led_cdev); 112 + struct sy7802 *chip = led->chip; 113 + u32 fled_torch_used_tmp; 114 + u32 led_enable_mask; 115 + u32 enable_mask; 116 + u32 torch_mask; 117 + u32 val; 118 + int ret; 119 + 120 + mutex_lock(&chip->mutex); 121 + 122 + if (chip->fled_strobe_used) { 123 + dev_warn(chip->dev, "Cannot set torch brightness whilst strobe is enabled\n"); 124 + ret = -EBUSY; 125 + goto unlock; 126 + } 127 + 128 + if (brightness) 129 + fled_torch_used_tmp = chip->fled_torch_used | BIT(led->led_id); 130 + else 131 + fled_torch_used_tmp = chip->fled_torch_used & ~BIT(led->led_id); 132 + 133 + led_enable_mask = led->led_id == SY7802_LED_JOINT ? 134 + SY7802_LEDS_MASK_ALL : 135 + SY7802_LEDS_MASK(led->led_id); 136 + 137 + val = brightness ? led_enable_mask : SY7802_MODE_OFF; 138 + if (fled_torch_used_tmp) 139 + val |= SY7802_MODE_TORCH; 140 + 141 + /* Disable torch to apply brightness */ 142 + ret = regmap_update_bits(chip->regmap, SY7802_REG_ENABLE, SY7802_MODE_MASK, 143 + SY7802_MODE_OFF); 144 + if (ret) 145 + goto unlock; 146 + 147 + torch_mask = led->led_id == SY7802_LED_JOINT ? 148 + SY7802_TORCH_CURRENT_MASK_ALL : 149 + SY7802_TORCH_CURRENT_MASK(led->led_id); 150 + 151 + /* Register expects brightness between 0 and MAX_BRIGHTNESS - 1 */ 152 + if (brightness) 153 + brightness -= 1; 154 + 155 + brightness |= (brightness << SY7802_TORCH_CURRENT_SHIFT); 156 + 157 + ret = regmap_update_bits(chip->regmap, SY7802_REG_TORCH_BRIGHTNESS, torch_mask, brightness); 158 + if (ret) 159 + goto unlock; 160 + 161 + enable_mask = SY7802_MODE_MASK | led_enable_mask; 162 + ret = regmap_update_bits(chip->regmap, SY7802_REG_ENABLE, enable_mask, val); 163 + if (ret) 164 + goto unlock; 165 + 166 + chip->fled_torch_used = fled_torch_used_tmp; 167 + 168 + unlock: 169 + mutex_unlock(&chip->mutex); 170 + return ret; 171 + } 172 + 173 + static int sy7802_flash_brightness_set(struct led_classdev_flash *fl_cdev, u32 brightness) 174 + { 175 + struct sy7802_led *led = container_of(fl_cdev, struct sy7802_led, flash); 176 + struct led_flash_setting *s = &fl_cdev->brightness; 177 + u32 val = (brightness - s->min) / s->step; 178 + struct sy7802 *chip = led->chip; 179 + u32 flash_mask; 180 + int ret; 181 + 182 + val |= (val << SY7802_FLASH_CURRENT_SHIFT); 183 + flash_mask = led->led_id == SY7802_LED_JOINT ? 184 + SY7802_FLASH_CURRENT_MASK_ALL : 185 + SY7802_FLASH_CURRENT_MASK(led->led_id); 186 + 187 + mutex_lock(&chip->mutex); 188 + ret = regmap_update_bits(chip->regmap, SY7802_REG_FLASH_BRIGHTNESS, flash_mask, val); 189 + mutex_unlock(&chip->mutex); 190 + 191 + return ret; 192 + } 193 + 194 + static int sy7802_strobe_set(struct led_classdev_flash *fl_cdev, bool state) 195 + { 196 + struct sy7802_led *led = container_of(fl_cdev, struct sy7802_led, flash); 197 + struct sy7802 *chip = led->chip; 198 + u32 fled_strobe_used_tmp; 199 + u32 led_enable_mask; 200 + u32 enable_mask; 201 + u32 val; 202 + int ret; 203 + 204 + mutex_lock(&chip->mutex); 205 + 206 + if (chip->fled_torch_used) { 207 + dev_warn(chip->dev, "Cannot set strobe brightness whilst torch is enabled\n"); 208 + ret = -EBUSY; 209 + goto unlock; 210 + } 211 + 212 + if (state) 213 + fled_strobe_used_tmp = chip->fled_strobe_used | BIT(led->led_id); 214 + else 215 + fled_strobe_used_tmp = chip->fled_strobe_used & ~BIT(led->led_id); 216 + 217 + led_enable_mask = led->led_id == SY7802_LED_JOINT ? 218 + SY7802_LEDS_MASK_ALL : 219 + SY7802_LEDS_MASK(led->led_id); 220 + 221 + val = state ? led_enable_mask : SY7802_MODE_OFF; 222 + if (fled_strobe_used_tmp) 223 + val |= SY7802_MODE_FLASH; 224 + 225 + enable_mask = SY7802_MODE_MASK | led_enable_mask; 226 + ret = regmap_update_bits(chip->regmap, SY7802_REG_ENABLE, enable_mask, val); 227 + 228 + if (ret) 229 + goto unlock; 230 + 231 + chip->fled_strobe_used = fled_strobe_used_tmp; 232 + 233 + unlock: 234 + mutex_unlock(&chip->mutex); 235 + return ret; 236 + } 237 + 238 + static int sy7802_strobe_get(struct led_classdev_flash *fl_cdev, bool *state) 239 + { 240 + struct sy7802_led *led = container_of(fl_cdev, struct sy7802_led, flash); 241 + struct sy7802 *chip = led->chip; 242 + 243 + mutex_lock(&chip->mutex); 244 + *state = !!(chip->fled_strobe_used & BIT(led->led_id)); 245 + mutex_unlock(&chip->mutex); 246 + 247 + return 0; 248 + } 249 + 250 + static int sy7802_timeout_set(struct led_classdev_flash *fl_cdev, u32 timeout) 251 + { 252 + struct sy7802_led *led = container_of(fl_cdev, struct sy7802_led, flash); 253 + struct led_flash_setting *s = &fl_cdev->timeout; 254 + u32 val = (timeout - s->min) / s->step; 255 + struct sy7802 *chip = led->chip; 256 + 257 + return regmap_write(chip->regmap, SY7802_REG_FLASH_DURATION, val); 258 + } 259 + 260 + static int sy7802_fault_get(struct led_classdev_flash *fl_cdev, u32 *fault) 261 + { 262 + struct sy7802_led *led = container_of(fl_cdev, struct sy7802_led, flash); 263 + struct sy7802 *chip = led->chip; 264 + u32 val, led_faults = 0; 265 + int ret; 266 + 267 + /* NOTE: reading register clears fault status */ 268 + ret = regmap_read(chip->regmap, SY7802_REG_FLAGS, &val); 269 + if (ret) 270 + return ret; 271 + 272 + if (val & (SY7802_FLAG_FLASH_INPUT_VOLTAGE_LOW | SY7802_FLAG_INPUT_VOLTAGE_LOW)) 273 + led_faults |= LED_FAULT_INPUT_VOLTAGE; 274 + 275 + if (val & SY7802_FLAG_THERMAL_SHUTDOWN) 276 + led_faults |= LED_FAULT_OVER_TEMPERATURE; 277 + 278 + if (val & SY7802_FLAG_TIMEOUT) 279 + led_faults |= LED_FAULT_TIMEOUT; 280 + 281 + *fault = led_faults; 282 + return 0; 283 + } 284 + 285 + static const struct led_flash_ops sy7802_flash_ops = { 286 + .flash_brightness_set = sy7802_flash_brightness_set, 287 + .strobe_set = sy7802_strobe_set, 288 + .strobe_get = sy7802_strobe_get, 289 + .timeout_set = sy7802_timeout_set, 290 + .fault_get = sy7802_fault_get, 291 + }; 292 + 293 + static void sy7802_init_flash_brightness(struct led_classdev_flash *fl_cdev) 294 + { 295 + struct led_flash_setting *s; 296 + 297 + /* Init flash brightness setting */ 298 + s = &fl_cdev->brightness; 299 + s->min = SY7802_FLASH_BRIGHTNESS_MIN; 300 + s->max = SY7802_FLASH_BRIGHTNESS_MAX; 301 + s->step = SY7802_FLASH_BRIGHTNESS_STEP; 302 + s->val = SY7802_FLASH_BRIGHTNESS_DEFAULT; 303 + } 304 + 305 + static void sy7802_init_flash_timeout(struct led_classdev_flash *fl_cdev) 306 + { 307 + struct led_flash_setting *s; 308 + 309 + /* Init flash timeout setting */ 310 + s = &fl_cdev->timeout; 311 + s->min = SY7802_TIMEOUT_MIN_US; 312 + s->max = SY7802_TIMEOUT_MAX_US; 313 + s->step = SY7802_TIMEOUT_STEPSIZE_US; 314 + s->val = SY7802_TIMEOUT_DEFAULT_US; 315 + } 316 + 317 + static int sy7802_led_register(struct device *dev, struct sy7802_led *led, 318 + struct device_node *np) 319 + { 320 + struct led_init_data init_data = {}; 321 + int ret; 322 + 323 + init_data.fwnode = of_fwnode_handle(np); 324 + 325 + ret = devm_led_classdev_flash_register_ext(dev, &led->flash, &init_data); 326 + if (ret) { 327 + dev_err(dev, "Couldn't register flash %d\n", led->led_id); 328 + return ret; 329 + } 330 + 331 + return 0; 332 + } 333 + 334 + static int sy7802_init_flash_properties(struct device *dev, struct sy7802_led *led, 335 + struct device_node *np) 336 + { 337 + struct led_classdev_flash *flash = &led->flash; 338 + struct led_classdev *lcdev = &flash->led_cdev; 339 + u32 sources[SY7802_MAX_LEDS]; 340 + int i, num, ret; 341 + 342 + num = of_property_count_u32_elems(np, "led-sources"); 343 + if (num < 1) { 344 + dev_err(dev, "Not specified or wrong number of led-sources\n"); 345 + return -EINVAL; 346 + } 347 + 348 + ret = of_property_read_u32_array(np, "led-sources", sources, num); 349 + if (ret) 350 + return ret; 351 + 352 + for (i = 0; i < num; i++) { 353 + if (sources[i] >= SY7802_MAX_LEDS) 354 + return -EINVAL; 355 + if (led->chip->leds_active & BIT(sources[i])) 356 + return -EINVAL; 357 + led->chip->leds_active |= BIT(sources[i]); 358 + } 359 + 360 + /* If both channels are specified in 'led-sources', joint flash output mode is used */ 361 + led->led_id = num == 2 ? SY7802_LED_JOINT : sources[0]; 362 + 363 + lcdev->max_brightness = SY7802_TORCH_BRIGHTNESS_MAX; 364 + lcdev->brightness_set_blocking = sy7802_torch_brightness_set; 365 + lcdev->flags |= LED_DEV_CAP_FLASH; 366 + 367 + flash->ops = &sy7802_flash_ops; 368 + 369 + sy7802_init_flash_brightness(flash); 370 + sy7802_init_flash_timeout(flash); 371 + 372 + return 0; 373 + } 374 + 375 + static int sy7802_chip_check(struct sy7802 *chip) 376 + { 377 + struct device *dev = chip->dev; 378 + u32 chipid; 379 + int ret; 380 + 381 + ret = regmap_read(chip->regmap, SY7802_REG_DEV_ID, &chipid); 382 + if (ret) 383 + return dev_err_probe(dev, ret, "Failed to read chip ID\n"); 384 + 385 + if (chipid != SY7802_CHIP_ID) 386 + return dev_err_probe(dev, -ENODEV, "Unsupported chip detected: %x\n", chipid); 387 + 388 + return 0; 389 + } 390 + 391 + static void sy7802_enable(struct sy7802 *chip) 392 + { 393 + gpiod_set_value_cansleep(chip->enable_gpio, 1); 394 + usleep_range(200, 300); 395 + } 396 + 397 + static void sy7802_disable(struct sy7802 *chip) 398 + { 399 + gpiod_set_value_cansleep(chip->enable_gpio, 0); 400 + } 401 + 402 + static int sy7802_probe_dt(struct sy7802 *chip) 403 + { 404 + struct device_node *np = dev_of_node(chip->dev); 405 + int child_num; 406 + int ret; 407 + 408 + regmap_write(chip->regmap, SY7802_REG_ENABLE, SY7802_MODE_OFF); 409 + regmap_write(chip->regmap, SY7802_REG_TORCH_BRIGHTNESS, LED_OFF); 410 + 411 + child_num = 0; 412 + for_each_available_child_of_node_scoped(np, child) { 413 + struct sy7802_led *led = chip->leds + child_num; 414 + 415 + led->chip = chip; 416 + led->led_id = child_num; 417 + 418 + ret = sy7802_init_flash_properties(chip->dev, led, child); 419 + if (ret) 420 + return ret; 421 + 422 + ret = sy7802_led_register(chip->dev, led, child); 423 + if (ret) 424 + return ret; 425 + 426 + child_num++; 427 + } 428 + return 0; 429 + } 430 + 431 + static void sy7802_chip_disable_action(void *data) 432 + { 433 + struct sy7802 *chip = data; 434 + 435 + sy7802_disable(chip); 436 + } 437 + 438 + static void sy7802_regulator_disable_action(void *data) 439 + { 440 + struct sy7802 *chip = data; 441 + 442 + regulator_disable(chip->vin_regulator); 443 + } 444 + 445 + static const struct regmap_config sy7802_regmap_config = { 446 + .reg_bits = 8, 447 + .val_bits = 8, 448 + .max_register = 0xff, 449 + .cache_type = REGCACHE_MAPLE, 450 + .reg_defaults = sy7802_regmap_defs, 451 + .num_reg_defaults = ARRAY_SIZE(sy7802_regmap_defs), 452 + }; 453 + 454 + static int sy7802_probe(struct i2c_client *client) 455 + { 456 + struct device *dev = &client->dev; 457 + struct sy7802 *chip; 458 + size_t count; 459 + int ret; 460 + 461 + count = device_get_child_node_count(dev); 462 + if (!count || count > SY7802_MAX_LEDS) 463 + return dev_err_probe(dev, -EINVAL, "Invalid amount of LED nodes %zu\n", count); 464 + 465 + chip = devm_kzalloc(dev, struct_size(chip, leds, count), GFP_KERNEL); 466 + if (!chip) 467 + return -ENOMEM; 468 + 469 + chip->num_leds = count; 470 + 471 + chip->dev = dev; 472 + i2c_set_clientdata(client, chip); 473 + 474 + chip->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); 475 + ret = PTR_ERR_OR_ZERO(chip->enable_gpio); 476 + if (ret) 477 + return dev_err_probe(dev, ret, "Failed to request enable gpio\n"); 478 + 479 + chip->vin_regulator = devm_regulator_get(dev, "vin"); 480 + ret = PTR_ERR_OR_ZERO(chip->vin_regulator); 481 + if (ret) 482 + return dev_err_probe(dev, ret, "Failed to request regulator\n"); 483 + 484 + ret = regulator_enable(chip->vin_regulator); 485 + if (ret) 486 + return dev_err_probe(dev, ret, "Failed to enable regulator\n"); 487 + 488 + ret = devm_add_action_or_reset(dev, sy7802_regulator_disable_action, chip); 489 + if (ret) 490 + return ret; 491 + 492 + ret = devm_mutex_init(dev, &chip->mutex); 493 + if (ret) 494 + return ret; 495 + 496 + mutex_lock(&chip->mutex); 497 + 498 + chip->regmap = devm_regmap_init_i2c(client, &sy7802_regmap_config); 499 + if (IS_ERR(chip->regmap)) { 500 + ret = PTR_ERR(chip->regmap); 501 + dev_err_probe(dev, ret, "Failed to allocate register map\n"); 502 + goto error; 503 + } 504 + 505 + ret = sy7802_probe_dt(chip); 506 + if (ret < 0) 507 + goto error; 508 + 509 + sy7802_enable(chip); 510 + 511 + ret = devm_add_action_or_reset(dev, sy7802_chip_disable_action, chip); 512 + if (ret) 513 + goto error; 514 + 515 + ret = sy7802_chip_check(chip); 516 + 517 + error: 518 + mutex_unlock(&chip->mutex); 519 + return ret; 520 + } 521 + 522 + static const struct of_device_id __maybe_unused sy7802_leds_match[] = { 523 + { .compatible = "silergy,sy7802", }, 524 + {} 525 + }; 526 + MODULE_DEVICE_TABLE(of, sy7802_leds_match); 527 + 528 + static struct i2c_driver sy7802_driver = { 529 + .driver = { 530 + .name = "sy7802", 531 + .of_match_table = of_match_ptr(sy7802_leds_match), 532 + }, 533 + .probe = sy7802_probe, 534 + }; 535 + module_i2c_driver(sy7802_driver); 536 + 537 + MODULE_AUTHOR("André Apitzsch <git@apitzsch.eu>"); 538 + MODULE_DESCRIPTION("Silergy SY7802 flash LED driver"); 539 + MODULE_LICENSE("GPL");
+1
drivers/leds/led-class-multicolor.c
··· 134 134 return -EINVAL; 135 135 136 136 led_cdev = &mcled_cdev->led_cdev; 137 + led_cdev->flags |= LED_MULTI_COLOR; 137 138 mcled_cdev->led_cdev.groups = led_multicolor_groups; 138 139 139 140 return led_classdev_register_ext(parent, led_cdev, init_data);
-1
drivers/leds/led-class.c
··· 258 258 259 259 led_dev = class_find_device_by_of_node(&leds_class, led_node); 260 260 of_node_put(led_node); 261 - put_device(led_dev); 262 261 263 262 return led_module_get(led_dev); 264 263 }
+44 -6
drivers/leds/led-core.c
··· 8 8 */ 9 9 10 10 #include <linux/kernel.h> 11 + #include <linux/led-class-multicolor.h> 11 12 #include <linux/leds.h> 12 13 #include <linux/list.h> 13 14 #include <linux/module.h> ··· 122 121 static void set_brightness_delayed_set_brightness(struct led_classdev *led_cdev, 123 122 unsigned int value) 124 123 { 125 - int ret = 0; 124 + int ret; 126 125 127 126 ret = __led_set_brightness(led_cdev, value); 128 - if (ret == -ENOTSUPP) 127 + if (ret == -ENOTSUPP) { 129 128 ret = __led_set_brightness_blocking(led_cdev, value); 130 - if (ret < 0 && 131 - /* LED HW might have been unplugged, therefore don't warn */ 132 - !(ret == -ENODEV && (led_cdev->flags & LED_UNREGISTERING) && 133 - (led_cdev->flags & LED_HW_PLUGGABLE))) 129 + if (ret == -ENOTSUPP) 130 + /* No back-end support to set a fixed brightness value */ 131 + return; 132 + } 133 + 134 + /* LED HW might have been unplugged, therefore don't warn */ 135 + if (ret == -ENODEV && led_cdev->flags & LED_UNREGISTERING && 136 + led_cdev->flags & LED_HW_PLUGGABLE) 137 + return; 138 + 139 + if (ret < 0) 134 140 dev_err(led_cdev->dev, 135 141 "Setting an LED's brightness failed (%d)\n", ret); 136 142 } ··· 368 360 return __led_set_brightness_blocking(led_cdev, led_cdev->brightness); 369 361 } 370 362 EXPORT_SYMBOL_GPL(led_set_brightness_sync); 363 + 364 + /* 365 + * This is a led-core function because just like led_set_brightness() 366 + * it is used in the kernel by e.g. triggers. 367 + */ 368 + void led_mc_set_brightness(struct led_classdev *led_cdev, 369 + unsigned int *intensity_value, unsigned int num_colors, 370 + unsigned int brightness) 371 + { 372 + struct led_classdev_mc *mcled_cdev; 373 + unsigned int i; 374 + 375 + if (!(led_cdev->flags & LED_MULTI_COLOR)) { 376 + dev_err_once(led_cdev->dev, "error not a multi-color LED\n"); 377 + return; 378 + } 379 + 380 + mcled_cdev = lcdev_to_mccdev(led_cdev); 381 + if (num_colors != mcled_cdev->num_colors) { 382 + dev_err_once(led_cdev->dev, "error num_colors mismatch %u != %u\n", 383 + num_colors, mcled_cdev->num_colors); 384 + return; 385 + } 386 + 387 + for (i = 0; i < mcled_cdev->num_colors; i++) 388 + mcled_cdev->subled_info[i].intensity = intensity_value[i]; 389 + 390 + led_set_brightness(led_cdev, brightness); 391 + } 392 + EXPORT_SYMBOL_GPL(led_mc_set_brightness); 371 393 372 394 int led_update_brightness(struct led_classdev *led_cdev) 373 395 {
+34 -1
drivers/leds/led-triggers.c
··· 179 179 180 180 cancel_work_sync(&led_cdev->set_brightness_work); 181 181 led_stop_software_blink(led_cdev); 182 + device_remove_groups(led_cdev->dev, led_cdev->trigger->groups); 182 183 if (led_cdev->trigger->deactivate) 183 184 led_cdev->trigger->deactivate(led_cdev); 184 - device_remove_groups(led_cdev->dev, led_cdev->trigger->groups); 185 185 led_cdev->trigger = NULL; 186 186 led_cdev->trigger_data = NULL; 187 187 led_cdev->activated = false; ··· 193 193 list_add_tail_rcu(&led_cdev->trig_list, &trig->led_cdevs); 194 194 spin_unlock(&trig->leddev_list_lock); 195 195 led_cdev->trigger = trig; 196 + 197 + /* 198 + * Some activate() calls use led_trigger_event() to initialize 199 + * the brightness of the LED for which the trigger is being set. 200 + * Ensure the led_cdev is visible on trig->led_cdevs for this. 201 + */ 202 + synchronize_rcu(); 203 + 204 + /* 205 + * If "set brightness to 0" is pending in workqueue, 206 + * we don't want that to be reordered after ->activate() 207 + */ 208 + flush_work(&led_cdev->set_brightness_work); 196 209 197 210 ret = 0; 198 211 if (trig->activate) ··· 408 395 rcu_read_unlock(); 409 396 } 410 397 EXPORT_SYMBOL_GPL(led_trigger_event); 398 + 399 + void led_mc_trigger_event(struct led_trigger *trig, 400 + unsigned int *intensity_value, unsigned int num_colors, 401 + enum led_brightness brightness) 402 + { 403 + struct led_classdev *led_cdev; 404 + 405 + if (!trig) 406 + return; 407 + 408 + rcu_read_lock(); 409 + list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) { 410 + if (!(led_cdev->flags & LED_MULTI_COLOR)) 411 + continue; 412 + 413 + led_mc_set_brightness(led_cdev, intensity_value, num_colors, brightness); 414 + } 415 + rcu_read_unlock(); 416 + } 417 + EXPORT_SYMBOL_GPL(led_mc_trigger_event); 411 418 412 419 static void led_trigger_blink_setup(struct led_trigger *trig, 413 420 unsigned long delay_on,
+2 -2
drivers/leds/leds-an30259a.c
··· 331 331 MODULE_DEVICE_TABLE(of, an30259a_match_table); 332 332 333 333 static const struct i2c_device_id an30259a_id[] = { 334 - { "an30259a", 0 }, 335 - { /* sentinel */ }, 334 + { "an30259a" }, 335 + { /* sentinel */ } 336 336 }; 337 337 MODULE_DEVICE_TABLE(i2c, an30259a_id); 338 338
+1 -1
drivers/leds/leds-bd2802.c
··· 776 776 static SIMPLE_DEV_PM_OPS(bd2802_pm, bd2802_suspend, bd2802_resume); 777 777 778 778 static const struct i2c_device_id bd2802_id[] = { 779 - { "BD2802", 0 }, 779 + { "BD2802" }, 780 780 { } 781 781 }; 782 782 MODULE_DEVICE_TABLE(i2c, bd2802_id);
+1 -1
drivers/leds/leds-blinkm.c
··· 718 718 } 719 719 720 720 static const struct i2c_device_id blinkm_id[] = { 721 - {"blinkm", 0}, 721 + { "blinkm" }, 722 722 {} 723 723 }; 724 724
+2 -2
drivers/leds/leds-is31fl319x.c
··· 140 140 { IS31FL3190_PWM(2), 0x00 }, 141 141 }; 142 142 143 - static struct regmap_config is31fl3190_regmap_config = { 143 + static const struct regmap_config is31fl3190_regmap_config = { 144 144 .reg_bits = 8, 145 145 .val_bits = 8, 146 146 .max_register = IS31FL3190_RESET, ··· 178 178 { IS31FL3196_PWM(8), 0x00 }, 179 179 }; 180 180 181 - static struct regmap_config is31fl3196_regmap_config = { 181 + static const struct regmap_config is31fl3196_regmap_config = { 182 182 .reg_bits = 8, 183 183 .val_bits = 8, 184 184 .max_register = IS31FL3196_REG_CNT,
+1 -1
drivers/leds/leds-lm3530.c
··· 478 478 } 479 479 480 480 static const struct i2c_device_id lm3530_id[] = { 481 - {LM3530_NAME, 0}, 481 + { LM3530_NAME }, 482 482 {} 483 483 }; 484 484 MODULE_DEVICE_TABLE(i2c, lm3530_id);
+1 -1
drivers/leds/leds-lm3532.c
··· 726 726 MODULE_DEVICE_TABLE(of, of_lm3532_leds_match); 727 727 728 728 static const struct i2c_device_id lm3532_id[] = { 729 - {LM3532_NAME, 0}, 729 + { LM3532_NAME }, 730 730 {} 731 731 }; 732 732 MODULE_DEVICE_TABLE(i2c, lm3532_id);
+1 -1
drivers/leds/leds-lm3642.c
··· 390 390 } 391 391 392 392 static const struct i2c_device_id lm3642_id[] = { 393 - {LM3642_NAME, 0}, 393 + { LM3642_NAME }, 394 394 {} 395 395 }; 396 396
+1 -1
drivers/leds/leds-lm3697.c
··· 360 360 } 361 361 362 362 static const struct i2c_device_id lm3697_id[] = { 363 - { "lm3697", 0 }, 363 + { "lm3697" }, 364 364 { } 365 365 }; 366 366 MODULE_DEVICE_TABLE(i2c, lm3697_id);
+1 -1
drivers/leds/leds-lp3944.c
··· 417 417 418 418 /* lp3944 i2c driver struct */ 419 419 static const struct i2c_device_id lp3944_id[] = { 420 - {"lp3944", 0}, 420 + { "lp3944" }, 421 421 {} 422 422 }; 423 423
+1 -1
drivers/leds/leds-lp3952.c
··· 266 266 } 267 267 268 268 static const struct i2c_device_id lp3952_id[] = { 269 - {LP3952_NAME, 0}, 269 + { LP3952_NAME }, 270 270 {} 271 271 }; 272 272 MODULE_DEVICE_TABLE(i2c, lp3952_id);
+36 -374
drivers/leds/leds-lp5521.c
··· 9 9 * Milo(Woogyom) Kim <milo.kim@ti.com> 10 10 */ 11 11 12 + #include <linux/cleanup.h> 12 13 #include <linux/delay.h> 13 14 #include <linux/firmware.h> 14 15 #include <linux/i2c.h> ··· 22 21 23 22 #include "leds-lp55xx-common.h" 24 23 25 - #define LP5521_PROGRAM_LENGTH 32 26 24 #define LP5521_MAX_LEDS 3 27 25 #define LP5521_CMD_DIRECT 0x3F 28 26 ··· 73 73 /* Reset register value */ 74 74 #define LP5521_RESET 0xFF 75 75 76 - /* Program Memory Operations */ 77 - #define LP5521_MODE_R_M 0x30 /* Operation Mode Register */ 78 - #define LP5521_MODE_G_M 0x0C 79 - #define LP5521_MODE_B_M 0x03 80 - #define LP5521_LOAD_R 0x10 81 - #define LP5521_LOAD_G 0x04 82 - #define LP5521_LOAD_B 0x01 83 - 84 - #define LP5521_R_IS_LOADING(mode) \ 85 - ((mode & LP5521_MODE_R_M) == LP5521_LOAD_R) 86 - #define LP5521_G_IS_LOADING(mode) \ 87 - ((mode & LP5521_MODE_G_M) == LP5521_LOAD_G) 88 - #define LP5521_B_IS_LOADING(mode) \ 89 - ((mode & LP5521_MODE_B_M) == LP5521_LOAD_B) 90 - 91 - #define LP5521_EXEC_R_M 0x30 /* Enable Register */ 92 - #define LP5521_EXEC_G_M 0x0C 93 - #define LP5521_EXEC_B_M 0x03 94 - #define LP5521_EXEC_M 0x3F 95 - #define LP5521_RUN_R 0x20 96 - #define LP5521_RUN_G 0x08 97 - #define LP5521_RUN_B 0x02 98 - 99 76 static inline void lp5521_wait_opmode_done(void) 100 77 { 101 78 /* operation mode change needs to be longer than 153 us */ ··· 85 108 usleep_range(500, 600); 86 109 } 87 110 88 - static void lp5521_set_led_current(struct lp55xx_led *led, u8 led_current) 89 - { 90 - led->led_current = led_current; 91 - lp55xx_write(led->chip, LP5521_REG_LED_CURRENT_BASE + led->chan_nr, 92 - led_current); 93 - } 94 - 95 - static void lp5521_load_engine(struct lp55xx_chip *chip) 96 - { 97 - enum lp55xx_engine_index idx = chip->engine_idx; 98 - static const u8 mask[] = { 99 - [LP55XX_ENGINE_1] = LP5521_MODE_R_M, 100 - [LP55XX_ENGINE_2] = LP5521_MODE_G_M, 101 - [LP55XX_ENGINE_3] = LP5521_MODE_B_M, 102 - }; 103 - 104 - static const u8 val[] = { 105 - [LP55XX_ENGINE_1] = LP5521_LOAD_R, 106 - [LP55XX_ENGINE_2] = LP5521_LOAD_G, 107 - [LP55XX_ENGINE_3] = LP5521_LOAD_B, 108 - }; 109 - 110 - lp55xx_update_bits(chip, LP5521_REG_OP_MODE, mask[idx], val[idx]); 111 - 112 - lp5521_wait_opmode_done(); 113 - } 114 - 115 - static void lp5521_stop_all_engines(struct lp55xx_chip *chip) 116 - { 117 - lp55xx_write(chip, LP5521_REG_OP_MODE, 0); 118 - lp5521_wait_opmode_done(); 119 - } 120 - 121 - static void lp5521_stop_engine(struct lp55xx_chip *chip) 122 - { 123 - enum lp55xx_engine_index idx = chip->engine_idx; 124 - static const u8 mask[] = { 125 - [LP55XX_ENGINE_1] = LP5521_MODE_R_M, 126 - [LP55XX_ENGINE_2] = LP5521_MODE_G_M, 127 - [LP55XX_ENGINE_3] = LP5521_MODE_B_M, 128 - }; 129 - 130 - lp55xx_update_bits(chip, LP5521_REG_OP_MODE, mask[idx], 0); 131 - 132 - lp5521_wait_opmode_done(); 133 - } 134 - 135 111 static void lp5521_run_engine(struct lp55xx_chip *chip, bool start) 136 112 { 137 113 int ret; 138 - u8 mode; 139 - u8 exec; 140 114 141 115 /* stop engine */ 142 116 if (!start) { 143 - lp5521_stop_engine(chip); 117 + lp55xx_stop_engine(chip); 144 118 lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); 145 119 lp5521_wait_opmode_done(); 146 120 return; 147 121 } 148 122 149 - /* 150 - * To run the engine, 151 - * operation mode and enable register should updated at the same time 152 - */ 153 - 154 - ret = lp55xx_read(chip, LP5521_REG_OP_MODE, &mode); 155 - if (ret) 156 - return; 157 - 158 - ret = lp55xx_read(chip, LP5521_REG_ENABLE, &exec); 159 - if (ret) 160 - return; 161 - 162 - /* change operation mode to RUN only when each engine is loading */ 163 - if (LP5521_R_IS_LOADING(mode)) { 164 - mode = (mode & ~LP5521_MODE_R_M) | LP5521_RUN_R; 165 - exec = (exec & ~LP5521_EXEC_R_M) | LP5521_RUN_R; 166 - } 167 - 168 - if (LP5521_G_IS_LOADING(mode)) { 169 - mode = (mode & ~LP5521_MODE_G_M) | LP5521_RUN_G; 170 - exec = (exec & ~LP5521_EXEC_G_M) | LP5521_RUN_G; 171 - } 172 - 173 - if (LP5521_B_IS_LOADING(mode)) { 174 - mode = (mode & ~LP5521_MODE_B_M) | LP5521_RUN_B; 175 - exec = (exec & ~LP5521_EXEC_B_M) | LP5521_RUN_B; 176 - } 177 - 178 - lp55xx_write(chip, LP5521_REG_OP_MODE, mode); 179 - lp5521_wait_opmode_done(); 180 - 181 - lp55xx_update_bits(chip, LP5521_REG_ENABLE, LP5521_EXEC_M, exec); 182 - lp5521_wait_enable_done(); 183 - } 184 - 185 - static int lp5521_update_program_memory(struct lp55xx_chip *chip, 186 - const u8 *data, size_t size) 187 - { 188 - enum lp55xx_engine_index idx = chip->engine_idx; 189 - u8 pattern[LP5521_PROGRAM_LENGTH] = {0}; 190 - static const u8 addr[] = { 191 - [LP55XX_ENGINE_1] = LP5521_REG_R_PROG_MEM, 192 - [LP55XX_ENGINE_2] = LP5521_REG_G_PROG_MEM, 193 - [LP55XX_ENGINE_3] = LP5521_REG_B_PROG_MEM, 194 - }; 195 - unsigned cmd; 196 - char c[3]; 197 - int nrchars; 198 - int ret; 199 - int offset = 0; 200 - int i = 0; 201 - 202 - while ((offset < size - 1) && (i < LP5521_PROGRAM_LENGTH)) { 203 - /* separate sscanfs because length is working only for %s */ 204 - ret = sscanf(data + offset, "%2s%n ", c, &nrchars); 205 - if (ret != 1) 206 - goto err; 207 - 208 - ret = sscanf(c, "%2x", &cmd); 209 - if (ret != 1) 210 - goto err; 211 - 212 - pattern[i] = (u8)cmd; 213 - offset += nrchars; 214 - i++; 215 - } 216 - 217 - /* Each instruction is 16bit long. Check that length is even */ 218 - if (i % 2) 219 - goto err; 220 - 221 - for (i = 0; i < LP5521_PROGRAM_LENGTH; i++) { 222 - ret = lp55xx_write(chip, addr[idx] + i, pattern[i]); 223 - if (ret) 224 - return -EINVAL; 225 - } 226 - 227 - return size; 228 - 229 - err: 230 - dev_err(&chip->cl->dev, "wrong pattern format\n"); 231 - return -EINVAL; 232 - } 233 - 234 - static void lp5521_firmware_loaded(struct lp55xx_chip *chip) 235 - { 236 - const struct firmware *fw = chip->fw; 237 - 238 - if (fw->size > LP5521_PROGRAM_LENGTH) { 239 - dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n", 240 - fw->size); 241 - return; 242 - } 243 - 244 - /* 245 - * Program memory sequence 246 - * 1) set engine mode to "LOAD" 247 - * 2) write firmware data into program memory 248 - */ 249 - 250 - lp5521_load_engine(chip); 251 - lp5521_update_program_memory(chip, fw->data, fw->size); 123 + ret = lp55xx_run_engine_common(chip); 124 + if (!ret) 125 + lp5521_wait_enable_done(); 252 126 } 253 127 254 128 static int lp5521_post_init_device(struct lp55xx_chip *chip) ··· 178 350 return 0; 179 351 } 180 352 181 - static int lp5521_multicolor_brightness(struct lp55xx_led *led) 182 - { 183 - struct lp55xx_chip *chip = led->chip; 184 - int ret; 185 - int i; 186 - 187 - mutex_lock(&chip->lock); 188 - for (i = 0; i < led->mc_cdev.num_colors; i++) { 189 - ret = lp55xx_write(chip, 190 - LP5521_REG_LED_PWM_BASE + 191 - led->mc_cdev.subled_info[i].channel, 192 - led->mc_cdev.subled_info[i].brightness); 193 - if (ret) 194 - break; 195 - } 196 - mutex_unlock(&chip->lock); 197 - return ret; 198 - } 199 - 200 - static int lp5521_led_brightness(struct lp55xx_led *led) 201 - { 202 - struct lp55xx_chip *chip = led->chip; 203 - int ret; 204 - 205 - mutex_lock(&chip->lock); 206 - ret = lp55xx_write(chip, LP5521_REG_LED_PWM_BASE + led->chan_nr, 207 - led->brightness); 208 - mutex_unlock(&chip->lock); 209 - 210 - return ret; 211 - } 212 - 213 - static ssize_t show_engine_mode(struct device *dev, 214 - struct device_attribute *attr, 215 - char *buf, int nr) 216 - { 217 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 218 - struct lp55xx_chip *chip = led->chip; 219 - enum lp55xx_engine_mode mode = chip->engines[nr - 1].mode; 220 - 221 - switch (mode) { 222 - case LP55XX_ENGINE_RUN: 223 - return sprintf(buf, "run\n"); 224 - case LP55XX_ENGINE_LOAD: 225 - return sprintf(buf, "load\n"); 226 - case LP55XX_ENGINE_DISABLED: 227 - default: 228 - return sprintf(buf, "disabled\n"); 229 - } 230 - } 231 - show_mode(1) 232 - show_mode(2) 233 - show_mode(3) 234 - 235 - static ssize_t store_engine_mode(struct device *dev, 236 - struct device_attribute *attr, 237 - const char *buf, size_t len, int nr) 238 - { 239 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 240 - struct lp55xx_chip *chip = led->chip; 241 - struct lp55xx_engine *engine = &chip->engines[nr - 1]; 242 - 243 - mutex_lock(&chip->lock); 244 - 245 - chip->engine_idx = nr; 246 - 247 - if (!strncmp(buf, "run", 3)) { 248 - lp5521_run_engine(chip, true); 249 - engine->mode = LP55XX_ENGINE_RUN; 250 - } else if (!strncmp(buf, "load", 4)) { 251 - lp5521_stop_engine(chip); 252 - lp5521_load_engine(chip); 253 - engine->mode = LP55XX_ENGINE_LOAD; 254 - } else if (!strncmp(buf, "disabled", 8)) { 255 - lp5521_stop_engine(chip); 256 - engine->mode = LP55XX_ENGINE_DISABLED; 257 - } 258 - 259 - mutex_unlock(&chip->lock); 260 - 261 - return len; 262 - } 263 - store_mode(1) 264 - store_mode(2) 265 - store_mode(3) 266 - 267 - static ssize_t store_engine_load(struct device *dev, 268 - struct device_attribute *attr, 269 - const char *buf, size_t len, int nr) 270 - { 271 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 272 - struct lp55xx_chip *chip = led->chip; 273 - int ret; 274 - 275 - mutex_lock(&chip->lock); 276 - 277 - chip->engine_idx = nr; 278 - lp5521_load_engine(chip); 279 - ret = lp5521_update_program_memory(chip, buf, len); 280 - 281 - mutex_unlock(&chip->lock); 282 - 283 - return ret; 284 - } 285 - store_load(1) 286 - store_load(2) 287 - store_load(3) 288 - 289 353 static ssize_t lp5521_selftest(struct device *dev, 290 354 struct device_attribute *attr, 291 355 char *buf) ··· 186 466 struct lp55xx_chip *chip = led->chip; 187 467 int ret; 188 468 189 - mutex_lock(&chip->lock); 469 + guard(mutex)(&chip->lock); 470 + 190 471 ret = lp5521_run_selftest(chip, buf); 191 - mutex_unlock(&chip->lock); 192 472 193 473 return sysfs_emit(buf, "%s\n", ret ? "FAIL" : "OK"); 194 474 } 195 475 196 476 /* device attributes */ 197 - static LP55XX_DEV_ATTR_RW(engine1_mode, show_engine1_mode, store_engine1_mode); 198 - static LP55XX_DEV_ATTR_RW(engine2_mode, show_engine2_mode, store_engine2_mode); 199 - static LP55XX_DEV_ATTR_RW(engine3_mode, show_engine3_mode, store_engine3_mode); 200 - static LP55XX_DEV_ATTR_WO(engine1_load, store_engine1_load); 201 - static LP55XX_DEV_ATTR_WO(engine2_load, store_engine2_load); 202 - static LP55XX_DEV_ATTR_WO(engine3_load, store_engine3_load); 477 + LP55XX_DEV_ATTR_ENGINE_MODE(1); 478 + LP55XX_DEV_ATTR_ENGINE_MODE(2); 479 + LP55XX_DEV_ATTR_ENGINE_MODE(3); 480 + LP55XX_DEV_ATTR_ENGINE_LOAD(1); 481 + LP55XX_DEV_ATTR_ENGINE_LOAD(2); 482 + LP55XX_DEV_ATTR_ENGINE_LOAD(3); 203 483 static LP55XX_DEV_ATTR_RO(selftest, lp5521_selftest); 204 484 205 485 static struct attribute *lp5521_attributes[] = { ··· 219 499 220 500 /* Chip specific configurations */ 221 501 static struct lp55xx_device_config lp5521_cfg = { 502 + .reg_op_mode = { 503 + .addr = LP5521_REG_OP_MODE, 504 + }, 505 + .reg_exec = { 506 + .addr = LP5521_REG_ENABLE, 507 + }, 222 508 .reset = { 223 509 .addr = LP5521_REG_RESET, 224 510 .val = LP5521_RESET, ··· 233 507 .addr = LP5521_REG_ENABLE, 234 508 .val = LP5521_ENABLE_DEFAULT, 235 509 }, 510 + .prog_mem_base = { 511 + .addr = LP5521_REG_R_PROG_MEM, 512 + }, 513 + .reg_led_pwm_base = { 514 + .addr = LP5521_REG_LED_PWM_BASE, 515 + }, 516 + .reg_led_current_base = { 517 + .addr = LP5521_REG_LED_CURRENT_BASE, 518 + }, 236 519 .max_channel = LP5521_MAX_LEDS, 237 520 .post_init_device = lp5521_post_init_device, 238 - .brightness_fn = lp5521_led_brightness, 239 - .multicolor_brightness_fn = lp5521_multicolor_brightness, 240 - .set_led_current = lp5521_set_led_current, 241 - .firmware_cb = lp5521_firmware_loaded, 521 + .brightness_fn = lp55xx_led_brightness, 522 + .multicolor_brightness_fn = lp55xx_multicolor_brightness, 523 + .set_led_current = lp55xx_set_led_current, 524 + .firmware_cb = lp55xx_firmware_loaded_cb, 242 525 .run_engine = lp5521_run_engine, 243 526 .dev_attr_group = &lp5521_group, 244 527 }; 245 528 246 - static int lp5521_probe(struct i2c_client *client) 247 - { 248 - const struct i2c_device_id *id = i2c_client_get_device_id(client); 249 - int ret; 250 - struct lp55xx_chip *chip; 251 - struct lp55xx_led *led; 252 - struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev); 253 - struct device_node *np = dev_of_node(&client->dev); 254 - 255 - chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 256 - if (!chip) 257 - return -ENOMEM; 258 - 259 - chip->cfg = &lp5521_cfg; 260 - 261 - if (!pdata) { 262 - if (np) { 263 - pdata = lp55xx_of_populate_pdata(&client->dev, np, 264 - chip); 265 - if (IS_ERR(pdata)) 266 - return PTR_ERR(pdata); 267 - } else { 268 - dev_err(&client->dev, "no platform data\n"); 269 - return -EINVAL; 270 - } 271 - } 272 - 273 - led = devm_kcalloc(&client->dev, 274 - pdata->num_channels, sizeof(*led), GFP_KERNEL); 275 - if (!led) 276 - return -ENOMEM; 277 - 278 - chip->cl = client; 279 - chip->pdata = pdata; 280 - 281 - mutex_init(&chip->lock); 282 - 283 - i2c_set_clientdata(client, led); 284 - 285 - ret = lp55xx_init_device(chip); 286 - if (ret) 287 - goto err_init; 288 - 289 - dev_info(&client->dev, "%s programmable led chip found\n", id->name); 290 - 291 - ret = lp55xx_register_leds(led, chip); 292 - if (ret) 293 - goto err_out; 294 - 295 - ret = lp55xx_register_sysfs(chip); 296 - if (ret) { 297 - dev_err(&client->dev, "registering sysfs failed\n"); 298 - goto err_out; 299 - } 300 - 301 - return 0; 302 - 303 - err_out: 304 - lp55xx_deinit_device(chip); 305 - err_init: 306 - return ret; 307 - } 308 - 309 - static void lp5521_remove(struct i2c_client *client) 310 - { 311 - struct lp55xx_led *led = i2c_get_clientdata(client); 312 - struct lp55xx_chip *chip = led->chip; 313 - 314 - lp5521_stop_all_engines(chip); 315 - lp55xx_unregister_sysfs(chip); 316 - lp55xx_deinit_device(chip); 317 - } 318 - 319 529 static const struct i2c_device_id lp5521_id[] = { 320 - { "lp5521", 0 }, /* Three channel chip */ 530 + { "lp5521", .driver_data = (kernel_ulong_t)&lp5521_cfg, }, /* Three channel chip */ 321 531 { } 322 532 }; 323 533 MODULE_DEVICE_TABLE(i2c, lp5521_id); 324 534 325 535 static const struct of_device_id of_lp5521_leds_match[] = { 326 - { .compatible = "national,lp5521", }, 536 + { .compatible = "national,lp5521", .data = &lp5521_cfg, }, 327 537 {}, 328 538 }; 329 539 ··· 270 608 .name = "lp5521", 271 609 .of_match_table = of_lp5521_leds_match, 272 610 }, 273 - .probe = lp5521_probe, 274 - .remove = lp5521_remove, 611 + .probe = lp55xx_probe, 612 + .remove = lp55xx_remove, 275 613 .id_table = lp5521_id, 276 614 }; 277 615
+72 -691
drivers/leds/leds-lp5523.c
··· 9 9 * Milo(Woogyom) Kim <milo.kim@ti.com> 10 10 */ 11 11 12 + #include <linux/cleanup.h> 12 13 #include <linux/delay.h> 13 14 #include <linux/firmware.h> 14 15 #include <linux/i2c.h> ··· 22 21 23 22 #include "leds-lp55xx-common.h" 24 23 25 - #define LP5523_PROGRAM_LENGTH 32 /* bytes */ 26 24 /* Memory is used like this: 27 25 * 0x00 engine 1 program 28 26 * 0x10 engine 2 program ··· 30 30 * 0x40 engine 2 muxing info 31 31 * 0x50 engine 3 muxing info 32 32 */ 33 + #define LP5523_PAGES_PER_ENGINE 1 33 34 #define LP5523_MAX_LEDS 9 34 35 35 36 /* Registers */ ··· 42 41 #define LP5523_REG_LED_PWM_BASE 0x16 43 42 #define LP5523_REG_LED_CURRENT_BASE 0x26 44 43 #define LP5523_REG_CONFIG 0x36 44 + 45 45 #define LP5523_REG_STATUS 0x3A 46 + #define LP5523_ENGINE_BUSY BIT(4) 47 + 46 48 #define LP5523_REG_RESET 0x3D 47 49 #define LP5523_REG_LED_TEST_CTRL 0x41 48 50 #define LP5523_REG_LED_TEST_ADC 0x42 ··· 74 70 #define LP5523_EXT_CLK_USED 0x08 75 71 #define LP5523_ENG_STATUS_MASK 0x07 76 72 77 - #define LP5523_FADER_MAPPING_MASK 0xC0 78 - #define LP5523_FADER_MAPPING_SHIFT 6 79 - 80 - /* Memory Page Selection */ 81 - #define LP5523_PAGE_ENG1 0 82 - #define LP5523_PAGE_ENG2 1 83 - #define LP5523_PAGE_ENG3 2 84 - #define LP5523_PAGE_MUX1 3 85 - #define LP5523_PAGE_MUX2 4 86 - #define LP5523_PAGE_MUX3 5 87 - 88 - /* Program Memory Operations */ 89 - #define LP5523_MODE_ENG1_M 0x30 /* Operation Mode Register */ 90 - #define LP5523_MODE_ENG2_M 0x0C 91 - #define LP5523_MODE_ENG3_M 0x03 92 - #define LP5523_LOAD_ENG1 0x10 93 - #define LP5523_LOAD_ENG2 0x04 94 - #define LP5523_LOAD_ENG3 0x01 95 - 96 - #define LP5523_ENG1_IS_LOADING(mode) \ 97 - ((mode & LP5523_MODE_ENG1_M) == LP5523_LOAD_ENG1) 98 - #define LP5523_ENG2_IS_LOADING(mode) \ 99 - ((mode & LP5523_MODE_ENG2_M) == LP5523_LOAD_ENG2) 100 - #define LP5523_ENG3_IS_LOADING(mode) \ 101 - ((mode & LP5523_MODE_ENG3_M) == LP5523_LOAD_ENG3) 102 - 103 - #define LP5523_EXEC_ENG1_M 0x30 /* Enable Register */ 104 - #define LP5523_EXEC_ENG2_M 0x0C 105 - #define LP5523_EXEC_ENG3_M 0x03 106 - #define LP5523_EXEC_M 0x3F 107 - #define LP5523_RUN_ENG1 0x20 108 - #define LP5523_RUN_ENG2 0x08 109 - #define LP5523_RUN_ENG3 0x02 110 - 111 - #define LED_ACTIVE(mux, led) (!!(mux & (0x0001 << led))) 112 - 113 - enum lp5523_chip_id { 114 - LP5523, 115 - LP55231, 116 - }; 117 - 118 73 static int lp5523_init_program_engine(struct lp55xx_chip *chip); 119 - 120 - static inline void lp5523_wait_opmode_done(void) 121 - { 122 - usleep_range(1000, 2000); 123 - } 124 - 125 - static void lp5523_set_led_current(struct lp55xx_led *led, u8 led_current) 126 - { 127 - led->led_current = led_current; 128 - lp55xx_write(led->chip, LP5523_REG_LED_CURRENT_BASE + led->chan_nr, 129 - led_current); 130 - } 131 74 132 75 static int lp5523_post_init_device(struct lp55xx_chip *chip) 133 76 { ··· 107 156 return lp5523_init_program_engine(chip); 108 157 } 109 158 110 - static void lp5523_load_engine(struct lp55xx_chip *chip) 111 - { 112 - enum lp55xx_engine_index idx = chip->engine_idx; 113 - static const u8 mask[] = { 114 - [LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M, 115 - [LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M, 116 - [LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M, 117 - }; 118 - 119 - static const u8 val[] = { 120 - [LP55XX_ENGINE_1] = LP5523_LOAD_ENG1, 121 - [LP55XX_ENGINE_2] = LP5523_LOAD_ENG2, 122 - [LP55XX_ENGINE_3] = LP5523_LOAD_ENG3, 123 - }; 124 - 125 - lp55xx_update_bits(chip, LP5523_REG_OP_MODE, mask[idx], val[idx]); 126 - 127 - lp5523_wait_opmode_done(); 128 - } 129 - 130 - static void lp5523_load_engine_and_select_page(struct lp55xx_chip *chip) 131 - { 132 - enum lp55xx_engine_index idx = chip->engine_idx; 133 - static const u8 page_sel[] = { 134 - [LP55XX_ENGINE_1] = LP5523_PAGE_ENG1, 135 - [LP55XX_ENGINE_2] = LP5523_PAGE_ENG2, 136 - [LP55XX_ENGINE_3] = LP5523_PAGE_ENG3, 137 - }; 138 - 139 - lp5523_load_engine(chip); 140 - 141 - lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, page_sel[idx]); 142 - } 143 - 144 - static void lp5523_stop_all_engines(struct lp55xx_chip *chip) 145 - { 146 - lp55xx_write(chip, LP5523_REG_OP_MODE, 0); 147 - lp5523_wait_opmode_done(); 148 - } 149 - 150 - static void lp5523_stop_engine(struct lp55xx_chip *chip) 151 - { 152 - enum lp55xx_engine_index idx = chip->engine_idx; 153 - static const u8 mask[] = { 154 - [LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M, 155 - [LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M, 156 - [LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M, 157 - }; 158 - 159 - lp55xx_update_bits(chip, LP5523_REG_OP_MODE, mask[idx], 0); 160 - 161 - lp5523_wait_opmode_done(); 162 - } 163 - 164 - static void lp5523_turn_off_channels(struct lp55xx_chip *chip) 165 - { 166 - int i; 167 - 168 - for (i = 0; i < LP5523_MAX_LEDS; i++) 169 - lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0); 170 - } 171 - 172 159 static void lp5523_run_engine(struct lp55xx_chip *chip, bool start) 173 160 { 174 - int ret; 175 - u8 mode; 176 - u8 exec; 177 - 178 161 /* stop engine */ 179 162 if (!start) { 180 - lp5523_stop_engine(chip); 181 - lp5523_turn_off_channels(chip); 163 + lp55xx_stop_engine(chip); 164 + lp55xx_turn_off_channels(chip); 182 165 return; 183 166 } 184 167 185 - /* 186 - * To run the engine, 187 - * operation mode and enable register should updated at the same time 188 - */ 189 - 190 - ret = lp55xx_read(chip, LP5523_REG_OP_MODE, &mode); 191 - if (ret) 192 - return; 193 - 194 - ret = lp55xx_read(chip, LP5523_REG_ENABLE, &exec); 195 - if (ret) 196 - return; 197 - 198 - /* change operation mode to RUN only when each engine is loading */ 199 - if (LP5523_ENG1_IS_LOADING(mode)) { 200 - mode = (mode & ~LP5523_MODE_ENG1_M) | LP5523_RUN_ENG1; 201 - exec = (exec & ~LP5523_EXEC_ENG1_M) | LP5523_RUN_ENG1; 202 - } 203 - 204 - if (LP5523_ENG2_IS_LOADING(mode)) { 205 - mode = (mode & ~LP5523_MODE_ENG2_M) | LP5523_RUN_ENG2; 206 - exec = (exec & ~LP5523_EXEC_ENG2_M) | LP5523_RUN_ENG2; 207 - } 208 - 209 - if (LP5523_ENG3_IS_LOADING(mode)) { 210 - mode = (mode & ~LP5523_MODE_ENG3_M) | LP5523_RUN_ENG3; 211 - exec = (exec & ~LP5523_EXEC_ENG3_M) | LP5523_RUN_ENG3; 212 - } 213 - 214 - lp55xx_write(chip, LP5523_REG_OP_MODE, mode); 215 - lp5523_wait_opmode_done(); 216 - 217 - lp55xx_update_bits(chip, LP5523_REG_ENABLE, LP5523_EXEC_M, exec); 168 + lp55xx_run_engine_common(chip); 218 169 } 219 170 220 171 static int lp5523_init_program_engine(struct lp55xx_chip *chip) ··· 126 273 int ret; 127 274 u8 status; 128 275 /* one pattern per engine setting LED MUX start and stop addresses */ 129 - static const u8 pattern[][LP5523_PROGRAM_LENGTH] = { 276 + static const u8 pattern[][LP55xx_BYTES_PER_PAGE] = { 130 277 { 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0}, 131 278 { 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0}, 132 279 { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0}, ··· 148 295 /* write LED MUX address space for each engine */ 149 296 for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) { 150 297 chip->engine_idx = i; 151 - lp5523_load_engine_and_select_page(chip); 298 + lp55xx_load_engine(chip); 152 299 153 - for (j = 0; j < LP5523_PROGRAM_LENGTH; j++) { 300 + for (j = 0; j < LP55xx_BYTES_PER_PAGE; j++) { 154 301 ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + j, 155 302 pattern[i - 1][j]); 156 303 if (ret) ··· 175 322 } 176 323 177 324 out: 178 - lp5523_stop_all_engines(chip); 325 + lp55xx_stop_all_engine(chip); 179 326 return ret; 180 327 } 181 - 182 - static int lp5523_update_program_memory(struct lp55xx_chip *chip, 183 - const u8 *data, size_t size) 184 - { 185 - u8 pattern[LP5523_PROGRAM_LENGTH] = {0}; 186 - unsigned int cmd; 187 - char c[3]; 188 - int nrchars; 189 - int ret; 190 - int offset = 0; 191 - int i = 0; 192 - 193 - while ((offset < size - 1) && (i < LP5523_PROGRAM_LENGTH)) { 194 - /* separate sscanfs because length is working only for %s */ 195 - ret = sscanf(data + offset, "%2s%n ", c, &nrchars); 196 - if (ret != 1) 197 - goto err; 198 - 199 - ret = sscanf(c, "%2x", &cmd); 200 - if (ret != 1) 201 - goto err; 202 - 203 - pattern[i] = (u8)cmd; 204 - offset += nrchars; 205 - i++; 206 - } 207 - 208 - /* Each instruction is 16bit long. Check that length is even */ 209 - if (i % 2) 210 - goto err; 211 - 212 - for (i = 0; i < LP5523_PROGRAM_LENGTH; i++) { 213 - ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + i, pattern[i]); 214 - if (ret) 215 - return -EINVAL; 216 - } 217 - 218 - return size; 219 - 220 - err: 221 - dev_err(&chip->cl->dev, "wrong pattern format\n"); 222 - return -EINVAL; 223 - } 224 - 225 - static void lp5523_firmware_loaded(struct lp55xx_chip *chip) 226 - { 227 - const struct firmware *fw = chip->fw; 228 - 229 - if (fw->size > LP5523_PROGRAM_LENGTH) { 230 - dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n", 231 - fw->size); 232 - return; 233 - } 234 - 235 - /* 236 - * Program memory sequence 237 - * 1) set engine mode to "LOAD" 238 - * 2) write firmware data into program memory 239 - */ 240 - 241 - lp5523_load_engine_and_select_page(chip); 242 - lp5523_update_program_memory(chip, fw->data, fw->size); 243 - } 244 - 245 - static ssize_t show_engine_mode(struct device *dev, 246 - struct device_attribute *attr, 247 - char *buf, int nr) 248 - { 249 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 250 - struct lp55xx_chip *chip = led->chip; 251 - enum lp55xx_engine_mode mode = chip->engines[nr - 1].mode; 252 - 253 - switch (mode) { 254 - case LP55XX_ENGINE_RUN: 255 - return sprintf(buf, "run\n"); 256 - case LP55XX_ENGINE_LOAD: 257 - return sprintf(buf, "load\n"); 258 - case LP55XX_ENGINE_DISABLED: 259 - default: 260 - return sprintf(buf, "disabled\n"); 261 - } 262 - } 263 - show_mode(1) 264 - show_mode(2) 265 - show_mode(3) 266 - 267 - static ssize_t store_engine_mode(struct device *dev, 268 - struct device_attribute *attr, 269 - const char *buf, size_t len, int nr) 270 - { 271 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 272 - struct lp55xx_chip *chip = led->chip; 273 - struct lp55xx_engine *engine = &chip->engines[nr - 1]; 274 - 275 - mutex_lock(&chip->lock); 276 - 277 - chip->engine_idx = nr; 278 - 279 - if (!strncmp(buf, "run", 3)) { 280 - lp5523_run_engine(chip, true); 281 - engine->mode = LP55XX_ENGINE_RUN; 282 - } else if (!strncmp(buf, "load", 4)) { 283 - lp5523_stop_engine(chip); 284 - lp5523_load_engine(chip); 285 - engine->mode = LP55XX_ENGINE_LOAD; 286 - } else if (!strncmp(buf, "disabled", 8)) { 287 - lp5523_stop_engine(chip); 288 - engine->mode = LP55XX_ENGINE_DISABLED; 289 - } 290 - 291 - mutex_unlock(&chip->lock); 292 - 293 - return len; 294 - } 295 - store_mode(1) 296 - store_mode(2) 297 - store_mode(3) 298 - 299 - static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len) 300 - { 301 - u16 tmp_mux = 0; 302 - int i; 303 - 304 - len = min_t(int, len, LP5523_MAX_LEDS); 305 - 306 - for (i = 0; i < len; i++) { 307 - switch (buf[i]) { 308 - case '1': 309 - tmp_mux |= (1 << i); 310 - break; 311 - case '0': 312 - break; 313 - case '\n': 314 - i = len; 315 - break; 316 - default: 317 - return -1; 318 - } 319 - } 320 - *mux = tmp_mux; 321 - 322 - return 0; 323 - } 324 - 325 - static void lp5523_mux_to_array(u16 led_mux, char *array) 326 - { 327 - int i, pos = 0; 328 - 329 - for (i = 0; i < LP5523_MAX_LEDS; i++) 330 - pos += sprintf(array + pos, "%x", LED_ACTIVE(led_mux, i)); 331 - 332 - array[pos] = '\0'; 333 - } 334 - 335 - static ssize_t show_engine_leds(struct device *dev, 336 - struct device_attribute *attr, 337 - char *buf, int nr) 338 - { 339 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 340 - struct lp55xx_chip *chip = led->chip; 341 - char mux[LP5523_MAX_LEDS + 1]; 342 - 343 - lp5523_mux_to_array(chip->engines[nr - 1].led_mux, mux); 344 - 345 - return sprintf(buf, "%s\n", mux); 346 - } 347 - show_leds(1) 348 - show_leds(2) 349 - show_leds(3) 350 - 351 - static int lp5523_load_mux(struct lp55xx_chip *chip, u16 mux, int nr) 352 - { 353 - struct lp55xx_engine *engine = &chip->engines[nr - 1]; 354 - int ret; 355 - static const u8 mux_page[] = { 356 - [LP55XX_ENGINE_1] = LP5523_PAGE_MUX1, 357 - [LP55XX_ENGINE_2] = LP5523_PAGE_MUX2, 358 - [LP55XX_ENGINE_3] = LP5523_PAGE_MUX3, 359 - }; 360 - 361 - lp5523_load_engine(chip); 362 - 363 - ret = lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, mux_page[nr]); 364 - if (ret) 365 - return ret; 366 - 367 - ret = lp55xx_write(chip, LP5523_REG_PROG_MEM, (u8)(mux >> 8)); 368 - if (ret) 369 - return ret; 370 - 371 - ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + 1, (u8)(mux)); 372 - if (ret) 373 - return ret; 374 - 375 - engine->led_mux = mux; 376 - return 0; 377 - } 378 - 379 - static ssize_t store_engine_leds(struct device *dev, 380 - struct device_attribute *attr, 381 - const char *buf, size_t len, int nr) 382 - { 383 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 384 - struct lp55xx_chip *chip = led->chip; 385 - struct lp55xx_engine *engine = &chip->engines[nr - 1]; 386 - u16 mux = 0; 387 - ssize_t ret; 388 - 389 - if (lp5523_mux_parse(buf, &mux, len)) 390 - return -EINVAL; 391 - 392 - mutex_lock(&chip->lock); 393 - 394 - chip->engine_idx = nr; 395 - ret = -EINVAL; 396 - 397 - if (engine->mode != LP55XX_ENGINE_LOAD) 398 - goto leave; 399 - 400 - if (lp5523_load_mux(chip, mux, nr)) 401 - goto leave; 402 - 403 - ret = len; 404 - leave: 405 - mutex_unlock(&chip->lock); 406 - return ret; 407 - } 408 - store_leds(1) 409 - store_leds(2) 410 - store_leds(3) 411 - 412 - static ssize_t store_engine_load(struct device *dev, 413 - struct device_attribute *attr, 414 - const char *buf, size_t len, int nr) 415 - { 416 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 417 - struct lp55xx_chip *chip = led->chip; 418 - int ret; 419 - 420 - mutex_lock(&chip->lock); 421 - 422 - chip->engine_idx = nr; 423 - lp5523_load_engine_and_select_page(chip); 424 - ret = lp5523_update_program_memory(chip, buf, len); 425 - 426 - mutex_unlock(&chip->lock); 427 - 428 - return ret; 429 - } 430 - store_load(1) 431 - store_load(2) 432 - store_load(3) 433 328 434 329 static ssize_t lp5523_selftest(struct device *dev, 435 330 struct device_attribute *attr, ··· 189 588 int ret, pos = 0; 190 589 u8 status, adc, vdd, i; 191 590 192 - mutex_lock(&chip->lock); 591 + guard(mutex)(&chip->lock); 193 592 194 593 ret = lp55xx_read(chip, LP5523_REG_STATUS, &status); 195 594 if (ret < 0) 196 - goto fail; 595 + return sysfs_emit(buf, "FAIL\n"); 197 596 198 597 /* Check that ext clock is really in use if requested */ 199 598 if (pdata->clock_mode == LP55XX_CLOCK_EXT) { 200 599 if ((status & LP5523_EXT_CLK_USED) == 0) 201 - goto fail; 600 + return sysfs_emit(buf, "FAIL\n"); 202 601 } 203 602 204 603 /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */ ··· 206 605 usleep_range(3000, 6000); /* ADC conversion time is typically 2.7 ms */ 207 606 ret = lp55xx_read(chip, LP5523_REG_STATUS, &status); 208 607 if (ret < 0) 209 - goto fail; 608 + return sysfs_emit(buf, "FAIL\n"); 210 609 211 610 if (!(status & LP5523_LEDTEST_DONE)) 212 611 usleep_range(3000, 6000); /* Was not ready. Wait little bit */ 213 612 214 613 ret = lp55xx_read(chip, LP5523_REG_LED_TEST_ADC, &vdd); 215 614 if (ret < 0) 216 - goto fail; 615 + return sysfs_emit(buf, "FAIL\n"); 217 616 218 617 vdd--; /* There may be some fluctuation in measurement */ 219 618 ··· 236 635 usleep_range(3000, 6000); 237 636 ret = lp55xx_read(chip, LP5523_REG_STATUS, &status); 238 637 if (ret < 0) 239 - goto fail; 638 + return sysfs_emit(buf, "FAIL\n"); 240 639 241 640 if (!(status & LP5523_LEDTEST_DONE)) 242 641 usleep_range(3000, 6000); /* Was not ready. Wait. */ 243 642 244 643 ret = lp55xx_read(chip, LP5523_REG_LED_TEST_ADC, &adc); 245 644 if (ret < 0) 246 - goto fail; 645 + return sysfs_emit(buf, "FAIL\n"); 247 646 248 647 if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM) 249 - pos += sprintf(buf + pos, "LED %d FAIL\n", 250 - led->chan_nr); 648 + pos += sysfs_emit_at(buf, pos, "LED %d FAIL\n", 649 + led->chan_nr); 251 650 252 651 lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr, 253 652 0x00); ··· 257 656 led->led_current); 258 657 led++; 259 658 } 260 - if (pos == 0) 261 - pos = sprintf(buf, "OK\n"); 262 - goto release_lock; 263 - fail: 264 - pos = sprintf(buf, "FAIL\n"); 265 659 266 - release_lock: 267 - mutex_unlock(&chip->lock); 268 - 269 - return pos; 660 + return pos == 0 ? sysfs_emit(buf, "OK\n") : pos; 270 661 } 271 662 272 - #define show_fader(nr) \ 273 - static ssize_t show_master_fader##nr(struct device *dev, \ 274 - struct device_attribute *attr, \ 275 - char *buf) \ 276 - { \ 277 - return show_master_fader(dev, attr, buf, nr); \ 278 - } 279 - 280 - #define store_fader(nr) \ 281 - static ssize_t store_master_fader##nr(struct device *dev, \ 282 - struct device_attribute *attr, \ 283 - const char *buf, size_t len) \ 284 - { \ 285 - return store_master_fader(dev, attr, buf, len, nr); \ 286 - } 287 - 288 - static ssize_t show_master_fader(struct device *dev, 289 - struct device_attribute *attr, 290 - char *buf, int nr) 291 - { 292 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 293 - struct lp55xx_chip *chip = led->chip; 294 - int ret; 295 - u8 val; 296 - 297 - mutex_lock(&chip->lock); 298 - ret = lp55xx_read(chip, LP5523_REG_MASTER_FADER_BASE + nr - 1, &val); 299 - mutex_unlock(&chip->lock); 300 - 301 - if (ret == 0) 302 - ret = sprintf(buf, "%u\n", val); 303 - 304 - return ret; 305 - } 306 - show_fader(1) 307 - show_fader(2) 308 - show_fader(3) 309 - 310 - static ssize_t store_master_fader(struct device *dev, 311 - struct device_attribute *attr, 312 - const char *buf, size_t len, int nr) 313 - { 314 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 315 - struct lp55xx_chip *chip = led->chip; 316 - int ret; 317 - unsigned long val; 318 - 319 - if (kstrtoul(buf, 0, &val)) 320 - return -EINVAL; 321 - 322 - if (val > 0xff) 323 - return -EINVAL; 324 - 325 - mutex_lock(&chip->lock); 326 - ret = lp55xx_write(chip, LP5523_REG_MASTER_FADER_BASE + nr - 1, 327 - (u8)val); 328 - mutex_unlock(&chip->lock); 329 - 330 - if (ret == 0) 331 - ret = len; 332 - 333 - return ret; 334 - } 335 - store_fader(1) 336 - store_fader(2) 337 - store_fader(3) 338 - 339 - static ssize_t show_master_fader_leds(struct device *dev, 340 - struct device_attribute *attr, 341 - char *buf) 342 - { 343 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 344 - struct lp55xx_chip *chip = led->chip; 345 - int i, ret, pos = 0; 346 - u8 val; 347 - 348 - mutex_lock(&chip->lock); 349 - 350 - for (i = 0; i < LP5523_MAX_LEDS; i++) { 351 - ret = lp55xx_read(chip, LP5523_REG_LED_CTRL_BASE + i, &val); 352 - if (ret) 353 - goto leave; 354 - 355 - val = (val & LP5523_FADER_MAPPING_MASK) 356 - >> LP5523_FADER_MAPPING_SHIFT; 357 - if (val > 3) { 358 - ret = -EINVAL; 359 - goto leave; 360 - } 361 - buf[pos++] = val + '0'; 362 - } 363 - buf[pos++] = '\n'; 364 - ret = pos; 365 - leave: 366 - mutex_unlock(&chip->lock); 367 - return ret; 368 - } 369 - 370 - static ssize_t store_master_fader_leds(struct device *dev, 371 - struct device_attribute *attr, 372 - const char *buf, size_t len) 373 - { 374 - struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 375 - struct lp55xx_chip *chip = led->chip; 376 - int i, n, ret; 377 - u8 val; 378 - 379 - n = min_t(int, len, LP5523_MAX_LEDS); 380 - 381 - mutex_lock(&chip->lock); 382 - 383 - for (i = 0; i < n; i++) { 384 - if (buf[i] >= '0' && buf[i] <= '3') { 385 - val = (buf[i] - '0') << LP5523_FADER_MAPPING_SHIFT; 386 - ret = lp55xx_update_bits(chip, 387 - LP5523_REG_LED_CTRL_BASE + i, 388 - LP5523_FADER_MAPPING_MASK, 389 - val); 390 - if (ret) 391 - goto leave; 392 - } else { 393 - ret = -EINVAL; 394 - goto leave; 395 - } 396 - } 397 - ret = len; 398 - leave: 399 - mutex_unlock(&chip->lock); 400 - return ret; 401 - } 402 - 403 - static int lp5523_multicolor_brightness(struct lp55xx_led *led) 404 - { 405 - struct lp55xx_chip *chip = led->chip; 406 - int ret; 407 - int i; 408 - 409 - mutex_lock(&chip->lock); 410 - for (i = 0; i < led->mc_cdev.num_colors; i++) { 411 - ret = lp55xx_write(chip, 412 - LP5523_REG_LED_PWM_BASE + 413 - led->mc_cdev.subled_info[i].channel, 414 - led->mc_cdev.subled_info[i].brightness); 415 - if (ret) 416 - break; 417 - } 418 - mutex_unlock(&chip->lock); 419 - return ret; 420 - } 421 - 422 - static int lp5523_led_brightness(struct lp55xx_led *led) 423 - { 424 - struct lp55xx_chip *chip = led->chip; 425 - int ret; 426 - 427 - mutex_lock(&chip->lock); 428 - ret = lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr, 429 - led->brightness); 430 - mutex_unlock(&chip->lock); 431 - return ret; 432 - } 433 - 434 - static LP55XX_DEV_ATTR_RW(engine1_mode, show_engine1_mode, store_engine1_mode); 435 - static LP55XX_DEV_ATTR_RW(engine2_mode, show_engine2_mode, store_engine2_mode); 436 - static LP55XX_DEV_ATTR_RW(engine3_mode, show_engine3_mode, store_engine3_mode); 437 - static LP55XX_DEV_ATTR_RW(engine1_leds, show_engine1_leds, store_engine1_leds); 438 - static LP55XX_DEV_ATTR_RW(engine2_leds, show_engine2_leds, store_engine2_leds); 439 - static LP55XX_DEV_ATTR_RW(engine3_leds, show_engine3_leds, store_engine3_leds); 440 - static LP55XX_DEV_ATTR_WO(engine1_load, store_engine1_load); 441 - static LP55XX_DEV_ATTR_WO(engine2_load, store_engine2_load); 442 - static LP55XX_DEV_ATTR_WO(engine3_load, store_engine3_load); 663 + LP55XX_DEV_ATTR_ENGINE_MODE(1); 664 + LP55XX_DEV_ATTR_ENGINE_MODE(2); 665 + LP55XX_DEV_ATTR_ENGINE_MODE(3); 666 + LP55XX_DEV_ATTR_ENGINE_LEDS(1); 667 + LP55XX_DEV_ATTR_ENGINE_LEDS(2); 668 + LP55XX_DEV_ATTR_ENGINE_LEDS(3); 669 + LP55XX_DEV_ATTR_ENGINE_LOAD(1); 670 + LP55XX_DEV_ATTR_ENGINE_LOAD(2); 671 + LP55XX_DEV_ATTR_ENGINE_LOAD(3); 443 672 static LP55XX_DEV_ATTR_RO(selftest, lp5523_selftest); 444 - static LP55XX_DEV_ATTR_RW(master_fader1, show_master_fader1, 445 - store_master_fader1); 446 - static LP55XX_DEV_ATTR_RW(master_fader2, show_master_fader2, 447 - store_master_fader2); 448 - static LP55XX_DEV_ATTR_RW(master_fader3, show_master_fader3, 449 - store_master_fader3); 450 - static LP55XX_DEV_ATTR_RW(master_fader_leds, show_master_fader_leds, 451 - store_master_fader_leds); 673 + LP55XX_DEV_ATTR_MASTER_FADER(1); 674 + LP55XX_DEV_ATTR_MASTER_FADER(2); 675 + LP55XX_DEV_ATTR_MASTER_FADER(3); 676 + static LP55XX_DEV_ATTR_RW(master_fader_leds, lp55xx_show_master_fader_leds, 677 + lp55xx_store_master_fader_leds); 452 678 453 679 static struct attribute *lp5523_attributes[] = { 454 680 &dev_attr_engine1_mode.attr, ··· 301 873 302 874 /* Chip specific configurations */ 303 875 static struct lp55xx_device_config lp5523_cfg = { 876 + .reg_op_mode = { 877 + .addr = LP5523_REG_OP_MODE, 878 + }, 879 + .reg_exec = { 880 + .addr = LP5523_REG_ENABLE, 881 + }, 882 + .engine_busy = { 883 + .addr = LP5523_REG_STATUS, 884 + .mask = LP5523_ENGINE_BUSY, 885 + }, 304 886 .reset = { 305 887 .addr = LP5523_REG_RESET, 306 888 .val = LP5523_RESET, ··· 319 881 .addr = LP5523_REG_ENABLE, 320 882 .val = LP5523_ENABLE, 321 883 }, 884 + .prog_mem_base = { 885 + .addr = LP5523_REG_PROG_MEM, 886 + }, 887 + .reg_led_pwm_base = { 888 + .addr = LP5523_REG_LED_PWM_BASE, 889 + }, 890 + .reg_led_current_base = { 891 + .addr = LP5523_REG_LED_CURRENT_BASE, 892 + }, 893 + .reg_master_fader_base = { 894 + .addr = LP5523_REG_MASTER_FADER_BASE, 895 + }, 896 + .reg_led_ctrl_base = { 897 + .addr = LP5523_REG_LED_CTRL_BASE, 898 + }, 899 + .pages_per_engine = LP5523_PAGES_PER_ENGINE, 322 900 .max_channel = LP5523_MAX_LEDS, 323 901 .post_init_device = lp5523_post_init_device, 324 - .brightness_fn = lp5523_led_brightness, 325 - .multicolor_brightness_fn = lp5523_multicolor_brightness, 326 - .set_led_current = lp5523_set_led_current, 327 - .firmware_cb = lp5523_firmware_loaded, 902 + .brightness_fn = lp55xx_led_brightness, 903 + .multicolor_brightness_fn = lp55xx_multicolor_brightness, 904 + .set_led_current = lp55xx_set_led_current, 905 + .firmware_cb = lp55xx_firmware_loaded_cb, 328 906 .run_engine = lp5523_run_engine, 329 907 .dev_attr_group = &lp5523_group, 330 908 }; 331 909 332 - static int lp5523_probe(struct i2c_client *client) 333 - { 334 - const struct i2c_device_id *id = i2c_client_get_device_id(client); 335 - int ret; 336 - struct lp55xx_chip *chip; 337 - struct lp55xx_led *led; 338 - struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev); 339 - struct device_node *np = dev_of_node(&client->dev); 340 - 341 - chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 342 - if (!chip) 343 - return -ENOMEM; 344 - 345 - chip->cfg = &lp5523_cfg; 346 - 347 - if (!pdata) { 348 - if (np) { 349 - pdata = lp55xx_of_populate_pdata(&client->dev, np, 350 - chip); 351 - if (IS_ERR(pdata)) 352 - return PTR_ERR(pdata); 353 - } else { 354 - dev_err(&client->dev, "no platform data\n"); 355 - return -EINVAL; 356 - } 357 - } 358 - 359 - led = devm_kcalloc(&client->dev, 360 - pdata->num_channels, sizeof(*led), GFP_KERNEL); 361 - if (!led) 362 - return -ENOMEM; 363 - 364 - chip->cl = client; 365 - chip->pdata = pdata; 366 - 367 - mutex_init(&chip->lock); 368 - 369 - i2c_set_clientdata(client, led); 370 - 371 - ret = lp55xx_init_device(chip); 372 - if (ret) 373 - goto err_init; 374 - 375 - dev_info(&client->dev, "%s Programmable led chip found\n", id->name); 376 - 377 - ret = lp55xx_register_leds(led, chip); 378 - if (ret) 379 - goto err_out; 380 - 381 - ret = lp55xx_register_sysfs(chip); 382 - if (ret) { 383 - dev_err(&client->dev, "registering sysfs failed\n"); 384 - goto err_out; 385 - } 386 - 387 - return 0; 388 - 389 - err_out: 390 - lp55xx_deinit_device(chip); 391 - err_init: 392 - return ret; 393 - } 394 - 395 - static void lp5523_remove(struct i2c_client *client) 396 - { 397 - struct lp55xx_led *led = i2c_get_clientdata(client); 398 - struct lp55xx_chip *chip = led->chip; 399 - 400 - lp5523_stop_all_engines(chip); 401 - lp55xx_unregister_sysfs(chip); 402 - lp55xx_deinit_device(chip); 403 - } 404 - 405 910 static const struct i2c_device_id lp5523_id[] = { 406 - { "lp5523", LP5523 }, 407 - { "lp55231", LP55231 }, 911 + { "lp5523", .driver_data = (kernel_ulong_t)&lp5523_cfg, }, 912 + { "lp55231", .driver_data = (kernel_ulong_t)&lp5523_cfg, }, 408 913 { } 409 914 }; 410 915 411 916 MODULE_DEVICE_TABLE(i2c, lp5523_id); 412 917 413 918 static const struct of_device_id of_lp5523_leds_match[] = { 414 - { .compatible = "national,lp5523", }, 415 - { .compatible = "ti,lp55231", }, 919 + { .compatible = "national,lp5523", .data = &lp5523_cfg, }, 920 + { .compatible = "ti,lp55231", .data = &lp5523_cfg, }, 416 921 {}, 417 922 }; 418 923 ··· 366 985 .name = "lp5523x", 367 986 .of_match_table = of_lp5523_leds_match, 368 987 }, 369 - .probe = lp5523_probe, 370 - .remove = lp5523_remove, 988 + .probe = lp55xx_probe, 989 + .remove = lp55xx_remove, 371 990 .id_table = lp5523_id, 372 991 }; 373 992
+30 -244
drivers/leds/leds-lp5562.c
··· 7 7 * Author: Milo(Woogyom) Kim <milo.kim@ti.com> 8 8 */ 9 9 10 + #include <linux/cleanup.h> 10 11 #include <linux/delay.h> 11 12 #include <linux/firmware.h> 12 13 #include <linux/i2c.h> ··· 20 19 21 20 #include "leds-lp55xx-common.h" 22 21 23 - #define LP5562_PROGRAM_LENGTH 32 24 22 #define LP5562_MAX_LEDS 4 25 23 26 24 /* ENABLE Register 00h */ ··· 38 38 39 39 /* OPMODE Register 01h */ 40 40 #define LP5562_REG_OP_MODE 0x01 41 - #define LP5562_MODE_ENG1_M 0x30 42 - #define LP5562_MODE_ENG2_M 0x0C 43 - #define LP5562_MODE_ENG3_M 0x03 44 - #define LP5562_LOAD_ENG1 0x10 45 - #define LP5562_LOAD_ENG2 0x04 46 - #define LP5562_LOAD_ENG3 0x01 47 - #define LP5562_RUN_ENG1 0x20 48 - #define LP5562_RUN_ENG2 0x08 49 - #define LP5562_RUN_ENG3 0x02 50 - #define LP5562_ENG1_IS_LOADING(mode) \ 51 - ((mode & LP5562_MODE_ENG1_M) == LP5562_LOAD_ENG1) 52 - #define LP5562_ENG2_IS_LOADING(mode) \ 53 - ((mode & LP5562_MODE_ENG2_M) == LP5562_LOAD_ENG2) 54 - #define LP5562_ENG3_IS_LOADING(mode) \ 55 - ((mode & LP5562_MODE_ENG3_M) == LP5562_LOAD_ENG3) 56 41 57 42 /* BRIGHTNESS Registers */ 58 43 #define LP5562_REG_R_PWM 0x04 ··· 109 124 lp55xx_write(led->chip, addr[led->chan_nr], led_current); 110 125 } 111 126 112 - static void lp5562_load_engine(struct lp55xx_chip *chip) 113 - { 114 - enum lp55xx_engine_index idx = chip->engine_idx; 115 - static const u8 mask[] = { 116 - [LP55XX_ENGINE_1] = LP5562_MODE_ENG1_M, 117 - [LP55XX_ENGINE_2] = LP5562_MODE_ENG2_M, 118 - [LP55XX_ENGINE_3] = LP5562_MODE_ENG3_M, 119 - }; 120 - 121 - static const u8 val[] = { 122 - [LP55XX_ENGINE_1] = LP5562_LOAD_ENG1, 123 - [LP55XX_ENGINE_2] = LP5562_LOAD_ENG2, 124 - [LP55XX_ENGINE_3] = LP5562_LOAD_ENG3, 125 - }; 126 - 127 - lp55xx_update_bits(chip, LP5562_REG_OP_MODE, mask[idx], val[idx]); 128 - 129 - lp5562_wait_opmode_done(); 130 - } 131 - 132 - static void lp5562_stop_engine(struct lp55xx_chip *chip) 133 - { 134 - lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DISABLE); 135 - lp5562_wait_opmode_done(); 136 - } 137 - 138 127 static void lp5562_run_engine(struct lp55xx_chip *chip, bool start) 139 128 { 140 129 int ret; 141 - u8 mode; 142 - u8 exec; 143 130 144 131 /* stop engine */ 145 132 if (!start) { 146 133 lp55xx_write(chip, LP5562_REG_ENABLE, LP5562_ENABLE_DEFAULT); 147 134 lp5562_wait_enable_done(); 148 - lp5562_stop_engine(chip); 135 + lp55xx_stop_all_engine(chip); 149 136 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_PWM); 150 137 lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DIRECT); 151 138 lp5562_wait_opmode_done(); 152 139 return; 153 140 } 154 141 155 - /* 156 - * To run the engine, 157 - * operation mode and enable register should updated at the same time 158 - */ 159 - 160 - ret = lp55xx_read(chip, LP5562_REG_OP_MODE, &mode); 161 - if (ret) 162 - return; 163 - 164 - ret = lp55xx_read(chip, LP5562_REG_ENABLE, &exec); 165 - if (ret) 166 - return; 167 - 168 - /* change operation mode to RUN only when each engine is loading */ 169 - if (LP5562_ENG1_IS_LOADING(mode)) { 170 - mode = (mode & ~LP5562_MODE_ENG1_M) | LP5562_RUN_ENG1; 171 - exec = (exec & ~LP5562_EXEC_ENG1_M) | LP5562_RUN_ENG1; 172 - } 173 - 174 - if (LP5562_ENG2_IS_LOADING(mode)) { 175 - mode = (mode & ~LP5562_MODE_ENG2_M) | LP5562_RUN_ENG2; 176 - exec = (exec & ~LP5562_EXEC_ENG2_M) | LP5562_RUN_ENG2; 177 - } 178 - 179 - if (LP5562_ENG3_IS_LOADING(mode)) { 180 - mode = (mode & ~LP5562_MODE_ENG3_M) | LP5562_RUN_ENG3; 181 - exec = (exec & ~LP5562_EXEC_ENG3_M) | LP5562_RUN_ENG3; 182 - } 183 - 184 - lp55xx_write(chip, LP5562_REG_OP_MODE, mode); 185 - lp5562_wait_opmode_done(); 186 - 187 - lp55xx_update_bits(chip, LP5562_REG_ENABLE, LP5562_EXEC_M, exec); 188 - lp5562_wait_enable_done(); 189 - } 190 - 191 - static int lp5562_update_firmware(struct lp55xx_chip *chip, 192 - const u8 *data, size_t size) 193 - { 194 - enum lp55xx_engine_index idx = chip->engine_idx; 195 - u8 pattern[LP5562_PROGRAM_LENGTH] = {0}; 196 - static const u8 addr[] = { 197 - [LP55XX_ENGINE_1] = LP5562_REG_PROG_MEM_ENG1, 198 - [LP55XX_ENGINE_2] = LP5562_REG_PROG_MEM_ENG2, 199 - [LP55XX_ENGINE_3] = LP5562_REG_PROG_MEM_ENG3, 200 - }; 201 - unsigned cmd; 202 - char c[3]; 203 - int program_size; 204 - int nrchars; 205 - int offset = 0; 206 - int ret; 207 - int i; 208 - 209 - /* clear program memory before updating */ 210 - for (i = 0; i < LP5562_PROGRAM_LENGTH; i++) 211 - lp55xx_write(chip, addr[idx] + i, 0); 212 - 213 - i = 0; 214 - while ((offset < size - 1) && (i < LP5562_PROGRAM_LENGTH)) { 215 - /* separate sscanfs because length is working only for %s */ 216 - ret = sscanf(data + offset, "%2s%n ", c, &nrchars); 217 - if (ret != 1) 218 - goto err; 219 - 220 - ret = sscanf(c, "%2x", &cmd); 221 - if (ret != 1) 222 - goto err; 223 - 224 - pattern[i] = (u8)cmd; 225 - offset += nrchars; 226 - i++; 227 - } 228 - 229 - /* Each instruction is 16bit long. Check that length is even */ 230 - if (i % 2) 231 - goto err; 232 - 233 - program_size = i; 234 - for (i = 0; i < program_size; i++) 235 - lp55xx_write(chip, addr[idx] + i, pattern[i]); 236 - 237 - return 0; 238 - 239 - err: 240 - dev_err(&chip->cl->dev, "wrong pattern format\n"); 241 - return -EINVAL; 242 - } 243 - 244 - static void lp5562_firmware_loaded(struct lp55xx_chip *chip) 245 - { 246 - const struct firmware *fw = chip->fw; 247 - 248 - /* 249 - * the firmware is encoded in ascii hex character, with 2 chars 250 - * per byte 251 - */ 252 - if (fw->size > (LP5562_PROGRAM_LENGTH * 2)) { 253 - dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n", 254 - fw->size); 255 - return; 256 - } 257 - 258 - /* 259 - * Program memory sequence 260 - * 1) set engine mode to "LOAD" 261 - * 2) write firmware data into program memory 262 - */ 263 - 264 - lp5562_load_engine(chip); 265 - lp5562_update_firmware(chip, fw->data, fw->size); 142 + ret = lp55xx_run_engine_common(chip); 143 + if (!ret) 144 + lp5562_wait_enable_done(); 266 145 } 267 146 268 147 static int lp5562_post_init_device(struct lp55xx_chip *chip) ··· 172 323 }; 173 324 int ret; 174 325 175 - mutex_lock(&chip->lock); 326 + guard(mutex)(&chip->lock); 327 + 176 328 ret = lp55xx_write(chip, addr[led->chan_nr], led->brightness); 177 - mutex_unlock(&chip->lock); 178 329 179 330 return ret; 180 331 } ··· 197 348 /* check the size of program count */ 198 349 static inline bool _is_pc_overflow(struct lp55xx_predef_pattern *ptn) 199 350 { 200 - return ptn->size_r >= LP5562_PROGRAM_LENGTH || 201 - ptn->size_g >= LP5562_PROGRAM_LENGTH || 202 - ptn->size_b >= LP5562_PROGRAM_LENGTH; 351 + return ptn->size_r >= LP55xx_BYTES_PER_PAGE || 352 + ptn->size_g >= LP55xx_BYTES_PER_PAGE || 353 + ptn->size_b >= LP55xx_BYTES_PER_PAGE; 203 354 } 204 355 205 356 static int lp5562_run_predef_led_pattern(struct lp55xx_chip *chip, int mode) ··· 218 369 return -EINVAL; 219 370 } 220 371 221 - lp5562_stop_engine(chip); 372 + lp55xx_stop_all_engine(chip); 222 373 223 374 /* Set LED map as RGB */ 224 375 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_RGB); ··· 226 377 /* Load engines */ 227 378 for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) { 228 379 chip->engine_idx = i; 229 - lp5562_load_engine(chip); 380 + lp55xx_load_engine(chip); 230 381 } 231 382 232 383 /* Clear program registers */ ··· 269 420 if (mode > num_patterns || !ptn) 270 421 return -EINVAL; 271 422 272 - mutex_lock(&chip->lock); 423 + guard(mutex)(&chip->lock); 424 + 273 425 ret = lp5562_run_predef_led_pattern(chip, mode); 274 - mutex_unlock(&chip->lock); 275 426 276 427 if (ret) 277 428 return ret; ··· 321 472 return -EINVAL; 322 473 } 323 474 324 - mutex_lock(&chip->lock); 475 + guard(mutex)(&chip->lock); 476 + 325 477 lp55xx_update_bits(chip, LP5562_REG_ENG_SEL, mask, val); 326 - mutex_unlock(&chip->lock); 327 478 328 479 return len; 329 480 } ··· 344 495 /* Chip specific configurations */ 345 496 static struct lp55xx_device_config lp5562_cfg = { 346 497 .max_channel = LP5562_MAX_LEDS, 498 + .reg_op_mode = { 499 + .addr = LP5562_REG_OP_MODE, 500 + }, 501 + .reg_exec = { 502 + .addr = LP5562_REG_ENABLE, 503 + }, 347 504 .reset = { 348 505 .addr = LP5562_REG_RESET, 349 506 .val = LP5562_RESET, ··· 358 503 .addr = LP5562_REG_ENABLE, 359 504 .val = LP5562_ENABLE_DEFAULT, 360 505 }, 506 + .prog_mem_base = { 507 + .addr = LP5562_REG_PROG_MEM_ENG1, 508 + }, 361 509 .post_init_device = lp5562_post_init_device, 362 510 .set_led_current = lp5562_set_led_current, 363 511 .brightness_fn = lp5562_led_brightness, 364 512 .run_engine = lp5562_run_engine, 365 - .firmware_cb = lp5562_firmware_loaded, 513 + .firmware_cb = lp55xx_firmware_loaded_cb, 366 514 .dev_attr_group = &lp5562_group, 367 515 }; 368 516 369 - static int lp5562_probe(struct i2c_client *client) 370 - { 371 - int ret; 372 - struct lp55xx_chip *chip; 373 - struct lp55xx_led *led; 374 - struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev); 375 - struct device_node *np = dev_of_node(&client->dev); 376 - 377 - chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 378 - if (!chip) 379 - return -ENOMEM; 380 - 381 - chip->cfg = &lp5562_cfg; 382 - 383 - if (!pdata) { 384 - if (np) { 385 - pdata = lp55xx_of_populate_pdata(&client->dev, np, 386 - chip); 387 - if (IS_ERR(pdata)) 388 - return PTR_ERR(pdata); 389 - } else { 390 - dev_err(&client->dev, "no platform data\n"); 391 - return -EINVAL; 392 - } 393 - } 394 - 395 - 396 - led = devm_kcalloc(&client->dev, 397 - pdata->num_channels, sizeof(*led), GFP_KERNEL); 398 - if (!led) 399 - return -ENOMEM; 400 - 401 - chip->cl = client; 402 - chip->pdata = pdata; 403 - 404 - mutex_init(&chip->lock); 405 - 406 - i2c_set_clientdata(client, led); 407 - 408 - ret = lp55xx_init_device(chip); 409 - if (ret) 410 - goto err_init; 411 - 412 - ret = lp55xx_register_leds(led, chip); 413 - if (ret) 414 - goto err_out; 415 - 416 - ret = lp55xx_register_sysfs(chip); 417 - if (ret) { 418 - dev_err(&client->dev, "registering sysfs failed\n"); 419 - goto err_out; 420 - } 421 - 422 - return 0; 423 - 424 - err_out: 425 - lp55xx_deinit_device(chip); 426 - err_init: 427 - return ret; 428 - } 429 - 430 - static void lp5562_remove(struct i2c_client *client) 431 - { 432 - struct lp55xx_led *led = i2c_get_clientdata(client); 433 - struct lp55xx_chip *chip = led->chip; 434 - 435 - lp5562_stop_engine(chip); 436 - 437 - lp55xx_unregister_sysfs(chip); 438 - lp55xx_deinit_device(chip); 439 - } 440 - 441 517 static const struct i2c_device_id lp5562_id[] = { 442 - { "lp5562", 0 }, 518 + { "lp5562", .driver_data = (kernel_ulong_t)&lp5562_cfg, }, 443 519 { } 444 520 }; 445 521 MODULE_DEVICE_TABLE(i2c, lp5562_id); 446 522 447 523 static const struct of_device_id of_lp5562_leds_match[] = { 448 - { .compatible = "ti,lp5562", }, 524 + { .compatible = "ti,lp5562", .data = &lp5562_cfg, }, 449 525 {}, 450 526 }; 451 527 ··· 387 601 .name = "lp5562", 388 602 .of_match_table = of_lp5562_leds_match, 389 603 }, 390 - .probe = lp5562_probe, 391 - .remove = lp5562_remove, 604 + .probe = lp55xx_probe, 605 + .remove = lp55xx_remove, 392 606 .id_table = lp5562_id, 393 607 }; 394 608
+544
drivers/leds/leds-lp5569.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2024 Christian Marangi <ansuelsmth@gmail.com> 4 + */ 5 + 6 + #include <linux/bitfield.h> 7 + #include <linux/cleanup.h> 8 + #include <linux/delay.h> 9 + #include <linux/firmware.h> 10 + #include <linux/i2c.h> 11 + #include <linux/iopoll.h> 12 + #include <linux/leds.h> 13 + #include <linux/module.h> 14 + #include <linux/mutex.h> 15 + #include <linux/of.h> 16 + #include <linux/platform_data/leds-lp55xx.h> 17 + #include <linux/slab.h> 18 + #include <dt-bindings/leds/leds-lp55xx.h> 19 + 20 + #include "leds-lp55xx-common.h" 21 + 22 + #define LP5569_MAX_LEDS 9 23 + 24 + /* Memory is used like this: 25 + * 0x00 engine 1 program (4 pages) 26 + * 0x40 engine 2 program (4 pages) 27 + * 0x80 engine 3 program (4 pages) 28 + * 0xc0 engine 1 muxing info (1 page) 29 + * 0xd0 engine 2 muxing info (1 page) 30 + * 0xe0 engine 3 muxing info (1 page) 31 + */ 32 + #define LP5569_PAGES_PER_ENGINE 4 33 + 34 + #define LP5569_REG_ENABLE 0x00 35 + #define LP5569_ENABLE BIT(6) 36 + 37 + #define LP5569_REG_EXEC_CTRL 0x01 38 + #define LP5569_MODE_ENG_SHIFT 2 39 + 40 + #define LP5569_REG_OP_MODE 0x02 41 + #define LP5569_EXEC_ENG_SHIFT 2 42 + 43 + #define LP5569_REG_ENABLE_LEDS_MSB 0x04 44 + #define LP5569_REG_ENABLE_LEDS_LSB 0x05 45 + #define LP5569_REG_LED_CTRL_BASE 0x07 46 + #define LP5569_FADER_MAPPING_MASK GENMASK(7, 5) 47 + #define LP5569_REG_LED_PWM_BASE 0x16 48 + #define LP5569_REG_LED_CURRENT_BASE 0x22 49 + #define LP5569_REG_MISC 0x2F 50 + #define LP5569_AUTO_INC BIT(6) 51 + #define LP5569_PWR_SAVE BIT(5) 52 + #define LP5569_CP_MODE_MASK GENMASK(4, 3) 53 + #define LP5569_PWM_PWR_SAVE BIT(2) 54 + #define LP5569_INTERNAL_CLK BIT(0) 55 + #define LP5569_REG_MISC2 0x33 56 + #define LP5569_LED_SHORT_TEST BIT(4) 57 + #define LP5569_LED_OPEN_TEST BIT(3) 58 + #define LP5569_REG_STATUS 0x3C 59 + #define LP5569_MASK_BUSY BIT(7) 60 + #define LP5569_STARTUP_BUSY BIT(6) 61 + #define LP5569_ENGINE_BUSY BIT(5) 62 + #define LP5569_ENGINE1_INT BIT(2) 63 + #define LP5569_ENGINE2_INT BIT(1) 64 + #define LP5569_ENGINE3_INT BIT(0) 65 + #define LP5569_ENG_STATUS_MASK (LP5569_ENGINE1_INT | LP5569_ENGINE2_INT | \ 66 + LP5569_ENGINE3_INT) 67 + #define LP5569_REG_IO_CONTROL 0x3D 68 + #define LP5569_CLK_OUTPUT BIT(3) 69 + #define LP5569_REG_RESET 0x3F 70 + #define LP5569_RESET 0xFF 71 + #define LP5569_REG_MASTER_FADER_BASE 0x46 72 + #define LP5569_REG_CH1_PROG_START 0x4B 73 + #define LP5569_REG_CH2_PROG_START 0x4C 74 + #define LP5569_REG_CH3_PROG_START 0x4D 75 + #define LP5569_REG_PROG_PAGE_SEL 0x4F 76 + #define LP5569_REG_PROG_MEM 0x50 77 + #define LP5569_REG_LED_FAULT1 0x81 78 + #define LP5569_LED_FAULT8 BIT(0) 79 + #define LP5569_REG_LED_FAULT2 0x82 80 + #define LP5569_LED_FAULT7 BIT(7) 81 + #define LP5569_LED_FAULT6 BIT(6) 82 + #define LP5569_LED_FAULT5 BIT(5) 83 + #define LP5569_LED_FAULT4 BIT(4) 84 + #define LP5569_LED_FAULT3 BIT(3) 85 + #define LP5569_LED_FAULT2 BIT(2) 86 + #define LP5569_LED_FAULT1 BIT(1) 87 + #define LP5569_LED_FAULT0 BIT(0) 88 + 89 + #define LP5569_ENG1_PROG_ADDR 0x0 90 + #define LP5569_ENG2_PROG_ADDR 0x40 91 + #define LP5569_ENG3_PROG_ADDR 0x80 92 + #define LP5569_ENG1_MUX_ADDR 0xc0 93 + #define LP5569_ENG2_MUX_ADDR 0xd0 94 + #define LP5569_ENG3_MUX_ADDR 0xe0 95 + 96 + #define LP5569_STARTUP_SLEEP 500 97 + 98 + #define LEDn_STATUS_FAULT(n, status) ((status) >> (n) & BIT(0)) 99 + 100 + #define LP5569_DEFAULT_CONFIG \ 101 + (LP5569_AUTO_INC | LP5569_PWR_SAVE | LP5569_PWM_PWR_SAVE) 102 + 103 + static void lp5569_run_engine(struct lp55xx_chip *chip, bool start) 104 + { 105 + if (!start) { 106 + lp55xx_stop_engine(chip); 107 + lp55xx_turn_off_channels(chip); 108 + return; 109 + } 110 + 111 + lp55xx_run_engine_common(chip); 112 + } 113 + 114 + static int lp5569_init_program_engine(struct lp55xx_chip *chip) 115 + { 116 + int i; 117 + int j; 118 + int ret; 119 + u8 status; 120 + /* Precompiled pattern per ENGINE setting LED MUX start and stop addresses */ 121 + static const u8 pattern[][LP55xx_BYTES_PER_PAGE] = { 122 + { 0x9c, LP5569_ENG1_MUX_ADDR, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0}, 123 + { 0x9c, LP5569_ENG2_MUX_ADDR, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0}, 124 + { 0x9c, LP5569_ENG3_MUX_ADDR, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0}, 125 + }; 126 + 127 + /* Setup each ENGINE program start address */ 128 + ret = lp55xx_write(chip, LP5569_REG_CH1_PROG_START, LP5569_ENG1_PROG_ADDR); 129 + if (ret) 130 + return ret; 131 + 132 + ret = lp55xx_write(chip, LP5569_REG_CH2_PROG_START, LP5569_ENG2_PROG_ADDR); 133 + if (ret) 134 + return ret; 135 + 136 + ret = lp55xx_write(chip, LP5569_REG_CH3_PROG_START, LP5569_ENG3_PROG_ADDR); 137 + if (ret) 138 + return ret; 139 + 140 + /* Write precompiled pattern for LED MUX address space for each ENGINE */ 141 + for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) { 142 + chip->engine_idx = i; 143 + lp55xx_load_engine(chip); 144 + 145 + for (j = 0; j < LP55xx_BYTES_PER_PAGE; j++) { 146 + ret = lp55xx_write(chip, LP5569_REG_PROG_MEM + j, 147 + pattern[i - 1][j]); 148 + if (ret) 149 + goto out; 150 + } 151 + } 152 + 153 + lp5569_run_engine(chip, true); 154 + 155 + /* Let the programs run for couple of ms and check the engine status */ 156 + usleep_range(3000, 6000); 157 + lp55xx_read(chip, LP5569_REG_STATUS, &status); 158 + status = FIELD_GET(LP5569_ENG_STATUS_MASK, status); 159 + 160 + if (status != LP5569_ENG_STATUS_MASK) { 161 + dev_err(&chip->cl->dev, 162 + "could not configure LED engine, status = 0x%.2x\n", 163 + status); 164 + ret = -EINVAL; 165 + } 166 + 167 + out: 168 + lp55xx_stop_all_engine(chip); 169 + return ret; 170 + } 171 + 172 + static int lp5569_post_init_device(struct lp55xx_chip *chip) 173 + { 174 + int ret; 175 + u8 val; 176 + 177 + val = LP5569_DEFAULT_CONFIG; 178 + val |= FIELD_PREP(LP5569_CP_MODE_MASK, chip->pdata->charge_pump_mode); 179 + ret = lp55xx_write(chip, LP5569_REG_MISC, val); 180 + if (ret) 181 + return ret; 182 + 183 + if (chip->pdata->clock_mode == LP55XX_CLOCK_INT) { 184 + /* Internal clock MUST be configured before CLK output */ 185 + ret = lp55xx_update_bits(chip, LP5569_REG_MISC, 186 + LP5569_INTERNAL_CLK, 187 + LP5569_INTERNAL_CLK); 188 + if (ret) 189 + return ret; 190 + 191 + ret = lp55xx_update_bits(chip, LP5569_REG_IO_CONTROL, 192 + LP5569_CLK_OUTPUT, 193 + LP5569_CLK_OUTPUT); 194 + if (ret) 195 + return ret; 196 + } 197 + 198 + ret = lp55xx_write(chip, LP5569_REG_ENABLE, LP5569_ENABLE); 199 + if (ret) 200 + return ret; 201 + 202 + read_poll_timeout(lp55xx_read, ret, !(val & LP5569_STARTUP_BUSY), 203 + LP5569_STARTUP_SLEEP, LP5569_STARTUP_SLEEP * 10, false, 204 + chip, LP5569_REG_STATUS, &val); 205 + 206 + return lp5569_init_program_engine(chip); 207 + } 208 + 209 + static ssize_t lp5569_led_open_test(struct lp55xx_led *led, char *buf) 210 + { 211 + struct lp55xx_chip *chip = led->chip; 212 + struct lp55xx_platform_data *pdata = chip->pdata; 213 + bool leds_fault[LP5569_MAX_LEDS]; 214 + struct lp55xx_led *led_tmp = led; 215 + int i, ret, pos = 0; 216 + u8 status; 217 + 218 + /* Set in STANDBY state */ 219 + ret = lp55xx_write(chip, LP5569_REG_ENABLE, 0); 220 + if (ret) 221 + goto exit; 222 + 223 + /* Wait 1ms for device to enter STANDBY state */ 224 + usleep_range(1000, 2000); 225 + 226 + /* Set Charge Pump to 1.5x */ 227 + ret = lp55xx_update_bits(chip, LP5569_REG_MISC, 228 + FIELD_PREP(LP5569_CP_MODE_MASK, LP55XX_CP_BOOST), 229 + LP5569_CP_MODE_MASK); 230 + if (ret) 231 + goto exit; 232 + 233 + /* Enable LED Open Test */ 234 + ret = lp55xx_update_bits(chip, LP5569_REG_MISC2, LP5569_LED_OPEN_TEST, 235 + LP5569_LED_OPEN_TEST); 236 + if (ret) 237 + goto exit; 238 + 239 + /* Put Device in NORMAL state */ 240 + ret = lp55xx_write(chip, LP5569_REG_ENABLE, LP5569_ENABLE); 241 + if (ret) 242 + goto exit; 243 + 244 + /* Wait 500 us for device to enter NORMAL state */ 245 + usleep_range(500, 750); 246 + 247 + /* Enable LED and set to 100% brightness */ 248 + for (i = 0; i < pdata->num_channels; i++) { 249 + ret = lp55xx_write(chip, LP5569_REG_LED_PWM_BASE + led_tmp->chan_nr, 250 + LED_FULL); 251 + if (ret) 252 + goto exit; 253 + 254 + led_tmp++; 255 + } 256 + 257 + /* Wait 500 us for device to fill status regs */ 258 + usleep_range(500, 750); 259 + 260 + /* Parse status led fault 1 regs */ 261 + ret = lp55xx_read(chip, LP5569_REG_LED_FAULT1, &status); 262 + if (ret < 0) 263 + goto exit; 264 + 265 + for (i = 0; i < 8; i++) 266 + leds_fault[i] = !!((status >> i) & 0x1); 267 + 268 + /* Parse status led fault 2 regs */ 269 + ret = lp55xx_read(chip, LP5569_REG_LED_FAULT2, &status); 270 + if (ret < 0) 271 + goto exit; 272 + 273 + for (i = 0; i < 1; i++) 274 + leds_fault[i + 8] = !!((status >> i) & 0x1); 275 + 276 + /* Report LED fault */ 277 + led_tmp = led; 278 + for (i = 0; i < pdata->num_channels; i++) { 279 + if (leds_fault[led_tmp->chan_nr]) 280 + pos += sysfs_emit_at(buf, pos, "LED %d OPEN FAIL\n", 281 + led_tmp->chan_nr); 282 + 283 + led_tmp++; 284 + } 285 + 286 + ret = pos; 287 + 288 + exit: 289 + /* Disable LED Open Test */ 290 + lp55xx_update_bits(chip, LP5569_REG_MISC2, LP5569_LED_OPEN_TEST, 0); 291 + 292 + led_tmp = led; 293 + for (i = 0; i < pdata->num_channels; i++) { 294 + lp55xx_write(chip, LP5569_REG_LED_PWM_BASE + led_tmp->chan_nr, 0); 295 + 296 + led_tmp++; 297 + } 298 + 299 + return ret; 300 + } 301 + 302 + static ssize_t lp5569_led_short_test(struct lp55xx_led *led, char *buf) 303 + { 304 + struct lp55xx_chip *chip = led->chip; 305 + struct lp55xx_platform_data *pdata = chip->pdata; 306 + bool leds_fault[LP5569_MAX_LEDS]; 307 + struct lp55xx_led *led_tmp = led; 308 + int i, ret, pos = 0; 309 + u8 status; 310 + 311 + /* Set in STANDBY state */ 312 + ret = lp55xx_write(chip, LP5569_REG_ENABLE, 0); 313 + if (ret) 314 + goto exit; 315 + 316 + /* Wait 1ms for device to enter STANDBY state */ 317 + usleep_range(1000, 2000); 318 + 319 + /* Set Charge Pump to 1x */ 320 + ret = lp55xx_update_bits(chip, LP5569_REG_MISC, 321 + FIELD_PREP(LP5569_CP_MODE_MASK, LP55XX_CP_BYPASS), 322 + LP5569_CP_MODE_MASK); 323 + if (ret) 324 + goto exit; 325 + 326 + /* Enable LED and set to 100% brightness and current to 100% (25.5mA) */ 327 + for (i = 0; i < pdata->num_channels; i++) { 328 + ret = lp55xx_write(chip, LP5569_REG_LED_PWM_BASE + led_tmp->chan_nr, 329 + LED_FULL); 330 + if (ret) 331 + goto exit; 332 + 333 + ret = lp55xx_write(chip, LP5569_REG_LED_CURRENT_BASE + led_tmp->chan_nr, 334 + LED_FULL); 335 + if (ret) 336 + goto exit; 337 + 338 + led_tmp++; 339 + } 340 + 341 + /* Put Device in NORMAL state */ 342 + ret = lp55xx_write(chip, LP5569_REG_ENABLE, LP5569_ENABLE); 343 + if (ret) 344 + goto exit; 345 + 346 + /* Wait 500 us for device to enter NORMAL state */ 347 + usleep_range(500, 750); 348 + 349 + /* Enable LED Shorted Test */ 350 + ret = lp55xx_update_bits(chip, LP5569_REG_MISC2, LP5569_LED_OPEN_TEST, 351 + LP5569_LED_SHORT_TEST); 352 + if (ret) 353 + goto exit; 354 + 355 + /* Wait 500 us for device to fill status regs */ 356 + usleep_range(500, 750); 357 + 358 + /* Parse status led fault 1 regs */ 359 + ret = lp55xx_read(chip, LP5569_REG_LED_FAULT1, &status); 360 + if (ret < 0) 361 + goto exit; 362 + 363 + for (i = 0; i < 8; i++) 364 + leds_fault[i] = !!LEDn_STATUS_FAULT(i, status); 365 + 366 + /* Parse status led fault 2 regs */ 367 + ret = lp55xx_read(chip, LP5569_REG_LED_FAULT2, &status); 368 + if (ret < 0) 369 + goto exit; 370 + 371 + for (i = 0; i < 1; i++) 372 + leds_fault[i + 8] = !!LEDn_STATUS_FAULT(i, status); 373 + 374 + /* Report LED fault */ 375 + led_tmp = led; 376 + for (i = 0; i < pdata->num_channels; i++) { 377 + if (leds_fault[led_tmp->chan_nr]) 378 + pos += sysfs_emit_at(buf, pos, "LED %d SHORTED FAIL\n", 379 + led_tmp->chan_nr); 380 + 381 + led_tmp++; 382 + } 383 + 384 + ret = pos; 385 + 386 + exit: 387 + /* Disable LED Shorted Test */ 388 + lp55xx_update_bits(chip, LP5569_REG_MISC2, LP5569_LED_SHORT_TEST, 0); 389 + 390 + led_tmp = led; 391 + for (i = 0; i < pdata->num_channels; i++) { 392 + lp55xx_write(chip, LP5569_REG_LED_PWM_BASE + led_tmp->chan_nr, 0); 393 + 394 + led_tmp++; 395 + } 396 + 397 + return ret; 398 + } 399 + 400 + static ssize_t lp5569_selftest(struct device *dev, 401 + struct device_attribute *attr, 402 + char *buf) 403 + { 404 + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 405 + struct lp55xx_chip *chip = led->chip; 406 + int i, pos = 0; 407 + 408 + guard(mutex)(&chip->lock); 409 + 410 + /* Test LED Open */ 411 + pos = lp5569_led_open_test(led, buf); 412 + if (pos < 0) 413 + return sprintf(buf, "FAIL\n"); 414 + 415 + /* Test LED Shorted */ 416 + pos += lp5569_led_short_test(led, buf); 417 + if (pos < 0) 418 + return sprintf(buf, "FAIL\n"); 419 + 420 + for (i = 0; i < chip->pdata->num_channels; i++) { 421 + /* Restore current */ 422 + lp55xx_write(chip, LP5569_REG_LED_CURRENT_BASE + led->chan_nr, 423 + led->led_current); 424 + 425 + /* Restore brightness */ 426 + lp55xx_write(chip, LP5569_REG_LED_PWM_BASE + led->chan_nr, 427 + led->brightness); 428 + led++; 429 + } 430 + 431 + return pos == 0 ? sysfs_emit(buf, "OK\n") : pos; 432 + } 433 + 434 + LP55XX_DEV_ATTR_ENGINE_MODE(1); 435 + LP55XX_DEV_ATTR_ENGINE_MODE(2); 436 + LP55XX_DEV_ATTR_ENGINE_MODE(3); 437 + LP55XX_DEV_ATTR_ENGINE_LEDS(1); 438 + LP55XX_DEV_ATTR_ENGINE_LEDS(2); 439 + LP55XX_DEV_ATTR_ENGINE_LEDS(3); 440 + LP55XX_DEV_ATTR_ENGINE_LOAD(1); 441 + LP55XX_DEV_ATTR_ENGINE_LOAD(2); 442 + LP55XX_DEV_ATTR_ENGINE_LOAD(3); 443 + static LP55XX_DEV_ATTR_RO(selftest, lp5569_selftest); 444 + LP55XX_DEV_ATTR_MASTER_FADER(1); 445 + LP55XX_DEV_ATTR_MASTER_FADER(2); 446 + LP55XX_DEV_ATTR_MASTER_FADER(3); 447 + static LP55XX_DEV_ATTR_RW(master_fader_leds, lp55xx_show_master_fader_leds, 448 + lp55xx_store_master_fader_leds); 449 + 450 + static struct attribute *lp5569_attributes[] = { 451 + &dev_attr_engine1_mode.attr, 452 + &dev_attr_engine2_mode.attr, 453 + &dev_attr_engine3_mode.attr, 454 + &dev_attr_engine1_load.attr, 455 + &dev_attr_engine2_load.attr, 456 + &dev_attr_engine3_load.attr, 457 + &dev_attr_engine1_leds.attr, 458 + &dev_attr_engine2_leds.attr, 459 + &dev_attr_engine3_leds.attr, 460 + &dev_attr_selftest.attr, 461 + &dev_attr_master_fader1.attr, 462 + &dev_attr_master_fader2.attr, 463 + &dev_attr_master_fader3.attr, 464 + &dev_attr_master_fader_leds.attr, 465 + NULL, 466 + }; 467 + 468 + static const struct attribute_group lp5569_group = { 469 + .attrs = lp5569_attributes, 470 + }; 471 + 472 + /* Chip specific configurations */ 473 + static struct lp55xx_device_config lp5569_cfg = { 474 + .reg_op_mode = { 475 + .addr = LP5569_REG_OP_MODE, 476 + .shift = LP5569_MODE_ENG_SHIFT, 477 + }, 478 + .reg_exec = { 479 + .addr = LP5569_REG_EXEC_CTRL, 480 + .shift = LP5569_EXEC_ENG_SHIFT, 481 + }, 482 + .reset = { 483 + .addr = LP5569_REG_RESET, 484 + .val = LP5569_RESET, 485 + }, 486 + .enable = { 487 + .addr = LP5569_REG_ENABLE, 488 + .val = LP5569_ENABLE, 489 + }, 490 + .prog_mem_base = { 491 + .addr = LP5569_REG_PROG_MEM, 492 + }, 493 + .reg_led_pwm_base = { 494 + .addr = LP5569_REG_LED_PWM_BASE, 495 + }, 496 + .reg_led_current_base = { 497 + .addr = LP5569_REG_LED_CURRENT_BASE, 498 + }, 499 + .reg_master_fader_base = { 500 + .addr = LP5569_REG_MASTER_FADER_BASE, 501 + }, 502 + .reg_led_ctrl_base = { 503 + .addr = LP5569_REG_LED_CTRL_BASE, 504 + }, 505 + .pages_per_engine = LP5569_PAGES_PER_ENGINE, 506 + .max_channel = LP5569_MAX_LEDS, 507 + .post_init_device = lp5569_post_init_device, 508 + .brightness_fn = lp55xx_led_brightness, 509 + .multicolor_brightness_fn = lp55xx_multicolor_brightness, 510 + .set_led_current = lp55xx_set_led_current, 511 + .firmware_cb = lp55xx_firmware_loaded_cb, 512 + .run_engine = lp5569_run_engine, 513 + .dev_attr_group = &lp5569_group, 514 + }; 515 + 516 + static const struct i2c_device_id lp5569_id[] = { 517 + { "lp5569", .driver_data = (kernel_ulong_t)&lp5569_cfg, }, 518 + { } 519 + }; 520 + 521 + MODULE_DEVICE_TABLE(i2c, lp5569_id); 522 + 523 + static const struct of_device_id of_lp5569_leds_match[] = { 524 + { .compatible = "ti,lp5569", .data = &lp5569_cfg, }, 525 + {}, 526 + }; 527 + 528 + MODULE_DEVICE_TABLE(of, of_lp5569_leds_match); 529 + 530 + static struct i2c_driver lp5569_driver = { 531 + .driver = { 532 + .name = "lp5569", 533 + .of_match_table = of_lp5569_leds_match, 534 + }, 535 + .probe = lp55xx_probe, 536 + .remove = lp55xx_remove, 537 + .id_table = lp5569_id, 538 + }; 539 + 540 + module_i2c_driver(lp5569_driver); 541 + 542 + MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>"); 543 + MODULE_DESCRIPTION("LP5569 LED engine"); 544 + MODULE_LICENSE("GPL");
+704 -56
drivers/leds/leds-lp55xx-common.c
··· 9 9 * Derived from leds-lp5521.c, leds-lp5523.c 10 10 */ 11 11 12 + #include <linux/bitfield.h> 13 + #include <linux/cleanup.h> 12 14 #include <linux/clk.h> 13 15 #include <linux/delay.h> 14 16 #include <linux/firmware.h> 15 17 #include <linux/i2c.h> 18 + #include <linux/iopoll.h> 16 19 #include <linux/leds.h> 17 20 #include <linux/module.h> 18 21 #include <linux/platform_data/leds-lp55xx.h> ··· 24 21 #include <dt-bindings/leds/leds-lp55xx.h> 25 22 26 23 #include "leds-lp55xx-common.h" 24 + 25 + /* OP MODE require at least 153 us to clear regs */ 26 + #define LP55XX_CMD_SLEEP 200 27 + 28 + #define LP55xx_PROGRAM_PAGES 16 29 + #define LP55xx_MAX_PROGRAM_LENGTH (LP55xx_BYTES_PER_PAGE * 4) /* 128 bytes (4 pages) */ 30 + 31 + /* 32 + * Program Memory Operations 33 + * Same Mask for each engine for both mode and exec 34 + * ENG1 GENMASK(3, 2) 35 + * ENG2 GENMASK(5, 4) 36 + * ENG3 GENMASK(7, 6) 37 + */ 38 + #define LP55xx_MODE_DISABLE_ALL_ENG 0x0 39 + #define LP55xx_MODE_ENG_MASK GENMASK(1, 0) 40 + #define LP55xx_MODE_DISABLE_ENG FIELD_PREP_CONST(LP55xx_MODE_ENG_MASK, 0x0) 41 + #define LP55xx_MODE_LOAD_ENG FIELD_PREP_CONST(LP55xx_MODE_ENG_MASK, 0x1) 42 + #define LP55xx_MODE_RUN_ENG FIELD_PREP_CONST(LP55xx_MODE_ENG_MASK, 0x2) 43 + #define LP55xx_MODE_HALT_ENG FIELD_PREP_CONST(LP55xx_MODE_ENG_MASK, 0x3) 44 + 45 + #define LP55xx_MODE_ENGn_SHIFT(n, shift) ((shift) + (2 * (3 - (n)))) 46 + #define LP55xx_MODE_ENGn_MASK(n, shift) (LP55xx_MODE_ENG_MASK << LP55xx_MODE_ENGn_SHIFT(n, shift)) 47 + #define LP55xx_MODE_ENGn_GET(n, mode, shift) \ 48 + (((mode) >> LP55xx_MODE_ENGn_SHIFT(n, shift)) & LP55xx_MODE_ENG_MASK) 49 + 50 + #define LP55xx_EXEC_ENG_MASK GENMASK(1, 0) 51 + #define LP55xx_EXEC_HOLD_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x0) 52 + #define LP55xx_EXEC_STEP_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x1) 53 + #define LP55xx_EXEC_RUN_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x2) 54 + #define LP55xx_EXEC_ONCE_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x3) 55 + 56 + #define LP55xx_EXEC_ENGn_SHIFT(n, shift) ((shift) + (2 * (3 - (n)))) 57 + #define LP55xx_EXEC_ENGn_MASK(n, shift) (LP55xx_EXEC_ENG_MASK << LP55xx_EXEC_ENGn_SHIFT(n, shift)) 58 + 59 + /* Memory Page Selection */ 60 + #define LP55xx_REG_PROG_PAGE_SEL 0x4f 61 + /* If supported, each ENGINE have an equal amount of pages offset from page 0 */ 62 + #define LP55xx_PAGE_OFFSET(n, pages) (((n) - 1) * (pages)) 63 + 64 + #define LED_ACTIVE(mux, led) (!!((mux) & (0x0001 << (led)))) 65 + 66 + /* MASTER FADER common property */ 67 + #define LP55xx_FADER_MAPPING_MASK GENMASK(7, 6) 27 68 28 69 /* External clock rate */ 29 70 #define LP55XX_CLK_32K 32768 ··· 87 40 return container_of(mc_cdev, struct lp55xx_led, mc_cdev); 88 41 } 89 42 43 + static void lp55xx_wait_opmode_done(struct lp55xx_chip *chip) 44 + { 45 + const struct lp55xx_device_config *cfg = chip->cfg; 46 + int __always_unused ret; 47 + u8 val; 48 + 49 + /* 50 + * Recent chip supports BUSY bit for engine. 51 + * Check support by checking if val is not 0. 52 + * For legacy device, sleep at least 153 us. 53 + */ 54 + if (cfg->engine_busy.val) { 55 + read_poll_timeout(lp55xx_read, ret, !(val & cfg->engine_busy.mask), 56 + LP55XX_CMD_SLEEP, LP55XX_CMD_SLEEP * 10, false, 57 + chip, cfg->engine_busy.addr, &val); 58 + } else { 59 + usleep_range(LP55XX_CMD_SLEEP, LP55XX_CMD_SLEEP * 2); 60 + } 61 + } 62 + 63 + void lp55xx_stop_all_engine(struct lp55xx_chip *chip) 64 + { 65 + const struct lp55xx_device_config *cfg = chip->cfg; 66 + 67 + lp55xx_write(chip, cfg->reg_op_mode.addr, LP55xx_MODE_DISABLE_ALL_ENG); 68 + lp55xx_wait_opmode_done(chip); 69 + } 70 + EXPORT_SYMBOL_GPL(lp55xx_stop_all_engine); 71 + 72 + void lp55xx_load_engine(struct lp55xx_chip *chip) 73 + { 74 + enum lp55xx_engine_index idx = chip->engine_idx; 75 + const struct lp55xx_device_config *cfg = chip->cfg; 76 + u8 mask, val; 77 + 78 + mask = LP55xx_MODE_ENGn_MASK(idx, cfg->reg_op_mode.shift); 79 + val = LP55xx_MODE_LOAD_ENG << LP55xx_MODE_ENGn_SHIFT(idx, cfg->reg_op_mode.shift); 80 + 81 + lp55xx_update_bits(chip, cfg->reg_op_mode.addr, mask, val); 82 + lp55xx_wait_opmode_done(chip); 83 + 84 + /* Setup PAGE if supported (pages_per_engine not 0)*/ 85 + if (cfg->pages_per_engine) 86 + lp55xx_write(chip, LP55xx_REG_PROG_PAGE_SEL, 87 + LP55xx_PAGE_OFFSET(idx, cfg->pages_per_engine)); 88 + } 89 + EXPORT_SYMBOL_GPL(lp55xx_load_engine); 90 + 91 + int lp55xx_run_engine_common(struct lp55xx_chip *chip) 92 + { 93 + const struct lp55xx_device_config *cfg = chip->cfg; 94 + u8 mode, exec; 95 + int i, ret; 96 + 97 + /* To run the engine, both OP MODE and EXEC needs to be put in RUN mode */ 98 + ret = lp55xx_read(chip, cfg->reg_op_mode.addr, &mode); 99 + if (ret) 100 + return ret; 101 + 102 + ret = lp55xx_read(chip, cfg->reg_exec.addr, &exec); 103 + if (ret) 104 + return ret; 105 + 106 + /* Switch to RUN only for engine that were put in LOAD previously */ 107 + for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) { 108 + if (LP55xx_MODE_ENGn_GET(i, mode, cfg->reg_op_mode.shift) != LP55xx_MODE_LOAD_ENG) 109 + continue; 110 + 111 + mode &= ~LP55xx_MODE_ENGn_MASK(i, cfg->reg_op_mode.shift); 112 + mode |= LP55xx_MODE_RUN_ENG << LP55xx_MODE_ENGn_SHIFT(i, cfg->reg_op_mode.shift); 113 + exec &= ~LP55xx_EXEC_ENGn_MASK(i, cfg->reg_exec.shift); 114 + exec |= LP55xx_EXEC_RUN_ENG << LP55xx_EXEC_ENGn_SHIFT(i, cfg->reg_exec.shift); 115 + } 116 + 117 + lp55xx_write(chip, cfg->reg_op_mode.addr, mode); 118 + lp55xx_wait_opmode_done(chip); 119 + lp55xx_write(chip, cfg->reg_exec.addr, exec); 120 + 121 + return 0; 122 + } 123 + EXPORT_SYMBOL_GPL(lp55xx_run_engine_common); 124 + 125 + int lp55xx_update_program_memory(struct lp55xx_chip *chip, 126 + const u8 *data, size_t size) 127 + { 128 + enum lp55xx_engine_index idx = chip->engine_idx; 129 + const struct lp55xx_device_config *cfg = chip->cfg; 130 + u8 pattern[LP55xx_MAX_PROGRAM_LENGTH] = { }; 131 + u8 start_addr = cfg->prog_mem_base.addr; 132 + int page, i = 0, offset = 0; 133 + int program_length, ret; 134 + 135 + program_length = LP55xx_BYTES_PER_PAGE; 136 + if (cfg->pages_per_engine) 137 + program_length *= cfg->pages_per_engine; 138 + 139 + while ((offset < size - 1) && (i < program_length)) { 140 + unsigned int cmd; 141 + int nrchars; 142 + char c[3]; 143 + 144 + /* separate sscanfs because length is working only for %s */ 145 + ret = sscanf(data + offset, "%2s%n ", c, &nrchars); 146 + if (ret != 1) 147 + goto err; 148 + 149 + ret = sscanf(c, "%2x", &cmd); 150 + if (ret != 1) 151 + goto err; 152 + 153 + pattern[i] = (u8)cmd; 154 + offset += nrchars; 155 + i++; 156 + } 157 + 158 + /* Each instruction is 16bit long. Check that length is even */ 159 + if (i % 2) 160 + goto err; 161 + 162 + /* 163 + * For legacy LED chip with no page support, engine base address are 164 + * one after another at offset of 32. 165 + * For LED chip that support page, PAGE is already set in load_engine. 166 + */ 167 + if (!cfg->pages_per_engine) 168 + start_addr += LP55xx_BYTES_PER_PAGE * idx; 169 + 170 + for (page = 0; page < program_length / LP55xx_BYTES_PER_PAGE; page++) { 171 + /* Write to the next page each 32 bytes (if supported) */ 172 + if (cfg->pages_per_engine) 173 + lp55xx_write(chip, LP55xx_REG_PROG_PAGE_SEL, 174 + LP55xx_PAGE_OFFSET(idx, cfg->pages_per_engine) + page); 175 + 176 + for (i = 0; i < LP55xx_BYTES_PER_PAGE; i++) { 177 + ret = lp55xx_write(chip, start_addr + i, 178 + pattern[i + (page * LP55xx_BYTES_PER_PAGE)]); 179 + if (ret) 180 + return -EINVAL; 181 + } 182 + } 183 + 184 + return size; 185 + 186 + err: 187 + dev_err(&chip->cl->dev, "wrong pattern format\n"); 188 + return -EINVAL; 189 + } 190 + EXPORT_SYMBOL_GPL(lp55xx_update_program_memory); 191 + 192 + void lp55xx_firmware_loaded_cb(struct lp55xx_chip *chip) 193 + { 194 + const struct lp55xx_device_config *cfg = chip->cfg; 195 + const struct firmware *fw = chip->fw; 196 + int program_length; 197 + 198 + program_length = LP55xx_BYTES_PER_PAGE; 199 + if (cfg->pages_per_engine) 200 + program_length *= cfg->pages_per_engine; 201 + 202 + /* 203 + * the firmware is encoded in ascii hex character, with 2 chars 204 + * per byte 205 + */ 206 + if (fw->size > program_length * 2) { 207 + dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n", 208 + fw->size); 209 + return; 210 + } 211 + 212 + /* 213 + * Program memory sequence 214 + * 1) set engine mode to "LOAD" 215 + * 2) write firmware data into program memory 216 + */ 217 + 218 + lp55xx_load_engine(chip); 219 + lp55xx_update_program_memory(chip, fw->data, fw->size); 220 + } 221 + EXPORT_SYMBOL_GPL(lp55xx_firmware_loaded_cb); 222 + 223 + int lp55xx_led_brightness(struct lp55xx_led *led) 224 + { 225 + struct lp55xx_chip *chip = led->chip; 226 + const struct lp55xx_device_config *cfg = chip->cfg; 227 + int ret; 228 + 229 + guard(mutex)(&chip->lock); 230 + 231 + ret = lp55xx_write(chip, cfg->reg_led_pwm_base.addr + led->chan_nr, 232 + led->brightness); 233 + return ret; 234 + } 235 + EXPORT_SYMBOL_GPL(lp55xx_led_brightness); 236 + 237 + int lp55xx_multicolor_brightness(struct lp55xx_led *led) 238 + { 239 + struct lp55xx_chip *chip = led->chip; 240 + const struct lp55xx_device_config *cfg = chip->cfg; 241 + int ret; 242 + int i; 243 + 244 + guard(mutex)(&chip->lock); 245 + 246 + for (i = 0; i < led->mc_cdev.num_colors; i++) { 247 + ret = lp55xx_write(chip, 248 + cfg->reg_led_pwm_base.addr + 249 + led->mc_cdev.subled_info[i].channel, 250 + led->mc_cdev.subled_info[i].brightness); 251 + if (ret) 252 + break; 253 + } 254 + 255 + return ret; 256 + } 257 + EXPORT_SYMBOL_GPL(lp55xx_multicolor_brightness); 258 + 259 + void lp55xx_set_led_current(struct lp55xx_led *led, u8 led_current) 260 + { 261 + struct lp55xx_chip *chip = led->chip; 262 + const struct lp55xx_device_config *cfg = chip->cfg; 263 + 264 + led->led_current = led_current; 265 + lp55xx_write(led->chip, cfg->reg_led_current_base.addr + led->chan_nr, 266 + led_current); 267 + } 268 + EXPORT_SYMBOL_GPL(lp55xx_set_led_current); 269 + 270 + void lp55xx_turn_off_channels(struct lp55xx_chip *chip) 271 + { 272 + const struct lp55xx_device_config *cfg = chip->cfg; 273 + int i; 274 + 275 + for (i = 0; i < cfg->max_channel; i++) 276 + lp55xx_write(chip, cfg->reg_led_pwm_base.addr + i, 0); 277 + } 278 + EXPORT_SYMBOL_GPL(lp55xx_turn_off_channels); 279 + 280 + void lp55xx_stop_engine(struct lp55xx_chip *chip) 281 + { 282 + enum lp55xx_engine_index idx = chip->engine_idx; 283 + const struct lp55xx_device_config *cfg = chip->cfg; 284 + u8 mask; 285 + 286 + mask = LP55xx_MODE_ENGn_MASK(idx, cfg->reg_op_mode.shift); 287 + lp55xx_update_bits(chip, cfg->reg_op_mode.addr, mask, 0); 288 + 289 + lp55xx_wait_opmode_done(chip); 290 + } 291 + EXPORT_SYMBOL_GPL(lp55xx_stop_engine); 292 + 90 293 static void lp55xx_reset_device(struct lp55xx_chip *chip) 91 294 { 92 - struct lp55xx_device_config *cfg = chip->cfg; 295 + const struct lp55xx_device_config *cfg = chip->cfg; 93 296 u8 addr = cfg->reset.addr; 94 297 u8 val = cfg->reset.val; 95 298 ··· 349 52 350 53 static int lp55xx_detect_device(struct lp55xx_chip *chip) 351 54 { 352 - struct lp55xx_device_config *cfg = chip->cfg; 55 + const struct lp55xx_device_config *cfg = chip->cfg; 353 56 u8 addr = cfg->enable.addr; 354 57 u8 val = cfg->enable.val; 355 58 int ret; ··· 372 75 373 76 static int lp55xx_post_init_device(struct lp55xx_chip *chip) 374 77 { 375 - struct lp55xx_device_config *cfg = chip->cfg; 78 + const struct lp55xx_device_config *cfg = chip->cfg; 376 79 377 80 if (!cfg->post_init_device) 378 81 return 0; ··· 406 109 if (!chip->cfg->set_led_current) 407 110 return len; 408 111 409 - mutex_lock(&chip->lock); 112 + guard(mutex)(&chip->lock); 113 + 410 114 chip->cfg->set_led_current(led, (u8)curr); 411 - mutex_unlock(&chip->lock); 412 115 413 116 return len; 414 117 } ··· 437 140 { 438 141 struct led_classdev_mc *mc_dev = lcdev_to_mccdev(cdev); 439 142 struct lp55xx_led *led = mcled_cdev_to_led(mc_dev); 440 - struct lp55xx_device_config *cfg = led->chip->cfg; 143 + const struct lp55xx_device_config *cfg = led->chip->cfg; 441 144 442 145 led_mc_calc_color_components(&led->mc_cdev, brightness); 443 146 return cfg->multicolor_brightness_fn(led); ··· 448 151 enum led_brightness brightness) 449 152 { 450 153 struct lp55xx_led *led = cdev_to_lp55xx_led(cdev); 451 - struct lp55xx_device_config *cfg = led->chip->cfg; 154 + const struct lp55xx_device_config *cfg = led->chip->cfg; 452 155 453 156 led->brightness = (u8)brightness; 454 157 return cfg->brightness_fn(led); ··· 458 161 struct lp55xx_chip *chip, int chan) 459 162 { 460 163 struct lp55xx_platform_data *pdata = chip->pdata; 461 - struct lp55xx_device_config *cfg = chip->cfg; 164 + const struct lp55xx_device_config *cfg = chip->cfg; 462 165 struct device *dev = &chip->cl->dev; 463 166 int max_channel = cfg->max_channel; 464 167 struct mc_subled *mc_led_info; ··· 543 246 } 544 247 545 248 /* handling firmware data is chip dependent */ 546 - mutex_lock(&chip->lock); 547 - 548 - chip->engines[idx - 1].mode = LP55XX_ENGINE_LOAD; 549 - chip->fw = fw; 550 - if (chip->cfg->firmware_cb) 551 - chip->cfg->firmware_cb(chip); 552 - 553 - mutex_unlock(&chip->lock); 249 + scoped_guard(mutex, &chip->lock) { 250 + chip->engines[idx - 1].mode = LP55XX_ENGINE_LOAD; 251 + chip->fw = fw; 252 + if (chip->cfg->firmware_cb) 253 + chip->cfg->firmware_cb(chip); 254 + } 554 255 555 256 /* firmware should be released for other channel use */ 556 257 release_firmware(chip->fw); ··· 565 270 } 566 271 567 272 static ssize_t select_engine_show(struct device *dev, 568 - struct device_attribute *attr, 569 - char *buf) 273 + struct device_attribute *attr, 274 + char *buf) 570 275 { 571 276 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 572 277 struct lp55xx_chip *chip = led->chip; ··· 575 280 } 576 281 577 282 static ssize_t select_engine_store(struct device *dev, 578 - struct device_attribute *attr, 579 - const char *buf, size_t len) 283 + struct device_attribute *attr, 284 + const char *buf, size_t len) 580 285 { 581 286 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 582 287 struct lp55xx_chip *chip = led->chip; ··· 592 297 case LP55XX_ENGINE_1: 593 298 case LP55XX_ENGINE_2: 594 299 case LP55XX_ENGINE_3: 595 - mutex_lock(&chip->lock); 596 - chip->engine_idx = val; 597 - ret = lp55xx_request_firmware(chip); 598 - mutex_unlock(&chip->lock); 300 + scoped_guard(mutex, &chip->lock) { 301 + chip->engine_idx = val; 302 + ret = lp55xx_request_firmware(chip); 303 + } 599 304 break; 600 305 default: 601 306 dev_err(dev, "%lu: invalid engine index. (1, 2, 3)\n", val); ··· 617 322 } 618 323 619 324 static ssize_t run_engine_store(struct device *dev, 620 - struct device_attribute *attr, 621 - const char *buf, size_t len) 325 + struct device_attribute *attr, 326 + const char *buf, size_t len) 622 327 { 623 328 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 624 329 struct lp55xx_chip *chip = led->chip; ··· 634 339 return len; 635 340 } 636 341 637 - mutex_lock(&chip->lock); 342 + guard(mutex)(&chip->lock); 343 + 638 344 lp55xx_run_engine(chip, true); 639 - mutex_unlock(&chip->lock); 640 345 641 346 return len; 642 347 } 643 348 644 349 static DEVICE_ATTR_RW(select_engine); 645 350 static DEVICE_ATTR_WO(run_engine); 351 + 352 + ssize_t lp55xx_show_engine_mode(struct device *dev, 353 + struct device_attribute *attr, 354 + char *buf, int nr) 355 + { 356 + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 357 + struct lp55xx_chip *chip = led->chip; 358 + enum lp55xx_engine_mode mode = chip->engines[nr - 1].mode; 359 + 360 + switch (mode) { 361 + case LP55XX_ENGINE_RUN: 362 + return sysfs_emit(buf, "run\n"); 363 + case LP55XX_ENGINE_LOAD: 364 + return sysfs_emit(buf, "load\n"); 365 + case LP55XX_ENGINE_DISABLED: 366 + default: 367 + return sysfs_emit(buf, "disabled\n"); 368 + } 369 + } 370 + EXPORT_SYMBOL_GPL(lp55xx_show_engine_mode); 371 + 372 + ssize_t lp55xx_store_engine_mode(struct device *dev, 373 + struct device_attribute *attr, 374 + const char *buf, size_t len, int nr) 375 + { 376 + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 377 + struct lp55xx_chip *chip = led->chip; 378 + const struct lp55xx_device_config *cfg = chip->cfg; 379 + struct lp55xx_engine *engine = &chip->engines[nr - 1]; 380 + 381 + guard(mutex)(&chip->lock); 382 + 383 + chip->engine_idx = nr; 384 + 385 + if (!strncmp(buf, "run", 3)) { 386 + cfg->run_engine(chip, true); 387 + engine->mode = LP55XX_ENGINE_RUN; 388 + } else if (!strncmp(buf, "load", 4)) { 389 + lp55xx_stop_engine(chip); 390 + lp55xx_load_engine(chip); 391 + engine->mode = LP55XX_ENGINE_LOAD; 392 + } else if (!strncmp(buf, "disabled", 8)) { 393 + lp55xx_stop_engine(chip); 394 + engine->mode = LP55XX_ENGINE_DISABLED; 395 + } 396 + 397 + return len; 398 + } 399 + EXPORT_SYMBOL_GPL(lp55xx_store_engine_mode); 400 + 401 + ssize_t lp55xx_store_engine_load(struct device *dev, 402 + struct device_attribute *attr, 403 + const char *buf, size_t len, int nr) 404 + { 405 + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 406 + struct lp55xx_chip *chip = led->chip; 407 + int ret; 408 + 409 + guard(mutex)(&chip->lock); 410 + 411 + chip->engine_idx = nr; 412 + lp55xx_load_engine(chip); 413 + ret = lp55xx_update_program_memory(chip, buf, len); 414 + 415 + return ret; 416 + } 417 + EXPORT_SYMBOL_GPL(lp55xx_store_engine_load); 418 + 419 + static int lp55xx_mux_parse(struct lp55xx_chip *chip, const char *buf, 420 + u16 *mux, size_t len) 421 + { 422 + const struct lp55xx_device_config *cfg = chip->cfg; 423 + u16 tmp_mux = 0; 424 + int i; 425 + 426 + len = min_t(int, len, cfg->max_channel); 427 + 428 + for (i = 0; i < len; i++) { 429 + switch (buf[i]) { 430 + case '1': 431 + tmp_mux |= (1 << i); 432 + break; 433 + case '0': 434 + break; 435 + case '\n': 436 + i = len; 437 + break; 438 + default: 439 + return -1; 440 + } 441 + } 442 + *mux = tmp_mux; 443 + 444 + return 0; 445 + } 446 + 447 + ssize_t lp55xx_show_engine_leds(struct device *dev, 448 + struct device_attribute *attr, 449 + char *buf, int nr) 450 + { 451 + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 452 + struct lp55xx_chip *chip = led->chip; 453 + const struct lp55xx_device_config *cfg = chip->cfg; 454 + unsigned int led_active; 455 + int i, pos = 0; 456 + 457 + for (i = 0; i < cfg->max_channel; i++) { 458 + led_active = LED_ACTIVE(chip->engines[nr - 1].led_mux, i); 459 + pos += sysfs_emit_at(buf, pos, "%x", led_active); 460 + } 461 + 462 + pos += sysfs_emit_at(buf, pos, "\n"); 463 + 464 + return pos; 465 + } 466 + EXPORT_SYMBOL_GPL(lp55xx_show_engine_leds); 467 + 468 + static int lp55xx_load_mux(struct lp55xx_chip *chip, u16 mux, int nr) 469 + { 470 + struct lp55xx_engine *engine = &chip->engines[nr - 1]; 471 + const struct lp55xx_device_config *cfg = chip->cfg; 472 + u8 mux_page; 473 + int ret; 474 + 475 + lp55xx_load_engine(chip); 476 + 477 + /* Derive the MUX page offset by starting at the end of the ENGINE pages */ 478 + mux_page = cfg->pages_per_engine * LP55XX_ENGINE_MAX + (nr - 1); 479 + ret = lp55xx_write(chip, LP55xx_REG_PROG_PAGE_SEL, mux_page); 480 + if (ret) 481 + return ret; 482 + 483 + ret = lp55xx_write(chip, cfg->prog_mem_base.addr, (u8)(mux >> 8)); 484 + if (ret) 485 + return ret; 486 + 487 + ret = lp55xx_write(chip, cfg->prog_mem_base.addr + 1, (u8)(mux)); 488 + if (ret) 489 + return ret; 490 + 491 + engine->led_mux = mux; 492 + return 0; 493 + } 494 + 495 + ssize_t lp55xx_store_engine_leds(struct device *dev, 496 + struct device_attribute *attr, 497 + const char *buf, size_t len, int nr) 498 + { 499 + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 500 + struct lp55xx_chip *chip = led->chip; 501 + struct lp55xx_engine *engine = &chip->engines[nr - 1]; 502 + u16 mux = 0; 503 + 504 + if (lp55xx_mux_parse(chip, buf, &mux, len)) 505 + return -EINVAL; 506 + 507 + guard(mutex)(&chip->lock); 508 + 509 + chip->engine_idx = nr; 510 + 511 + if (engine->mode != LP55XX_ENGINE_LOAD) 512 + return -EINVAL; 513 + 514 + if (lp55xx_load_mux(chip, mux, nr)) 515 + return -EINVAL; 516 + 517 + return len; 518 + } 519 + EXPORT_SYMBOL_GPL(lp55xx_store_engine_leds); 520 + 521 + ssize_t lp55xx_show_master_fader(struct device *dev, 522 + struct device_attribute *attr, 523 + char *buf, int nr) 524 + { 525 + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 526 + struct lp55xx_chip *chip = led->chip; 527 + const struct lp55xx_device_config *cfg = chip->cfg; 528 + int ret; 529 + u8 val; 530 + 531 + guard(mutex)(&chip->lock); 532 + 533 + ret = lp55xx_read(chip, cfg->reg_master_fader_base.addr + nr - 1, &val); 534 + 535 + return ret ? ret : sysfs_emit(buf, "%u\n", val); 536 + } 537 + EXPORT_SYMBOL_GPL(lp55xx_show_master_fader); 538 + 539 + ssize_t lp55xx_store_master_fader(struct device *dev, 540 + struct device_attribute *attr, 541 + const char *buf, size_t len, int nr) 542 + { 543 + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 544 + struct lp55xx_chip *chip = led->chip; 545 + const struct lp55xx_device_config *cfg = chip->cfg; 546 + int ret; 547 + unsigned long val; 548 + 549 + if (kstrtoul(buf, 0, &val)) 550 + return -EINVAL; 551 + 552 + if (val > 0xff) 553 + return -EINVAL; 554 + 555 + guard(mutex)(&chip->lock); 556 + 557 + ret = lp55xx_write(chip, cfg->reg_master_fader_base.addr + nr - 1, 558 + (u8)val); 559 + 560 + return ret ? ret : len; 561 + } 562 + EXPORT_SYMBOL_GPL(lp55xx_store_master_fader); 563 + 564 + ssize_t lp55xx_show_master_fader_leds(struct device *dev, 565 + struct device_attribute *attr, 566 + char *buf) 567 + { 568 + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 569 + struct lp55xx_chip *chip = led->chip; 570 + const struct lp55xx_device_config *cfg = chip->cfg; 571 + int i, ret, pos = 0; 572 + u8 val; 573 + 574 + guard(mutex)(&chip->lock); 575 + 576 + for (i = 0; i < cfg->max_channel; i++) { 577 + ret = lp55xx_read(chip, cfg->reg_led_ctrl_base.addr + i, &val); 578 + if (ret) 579 + return ret; 580 + 581 + val = FIELD_GET(LP55xx_FADER_MAPPING_MASK, val); 582 + if (val > FIELD_MAX(LP55xx_FADER_MAPPING_MASK)) { 583 + return -EINVAL; 584 + } 585 + buf[pos++] = val + '0'; 586 + } 587 + buf[pos++] = '\n'; 588 + 589 + return pos; 590 + } 591 + EXPORT_SYMBOL_GPL(lp55xx_show_master_fader_leds); 592 + 593 + ssize_t lp55xx_store_master_fader_leds(struct device *dev, 594 + struct device_attribute *attr, 595 + const char *buf, size_t len) 596 + { 597 + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 598 + struct lp55xx_chip *chip = led->chip; 599 + const struct lp55xx_device_config *cfg = chip->cfg; 600 + int i, n, ret; 601 + u8 val; 602 + 603 + n = min_t(int, len, cfg->max_channel); 604 + 605 + guard(mutex)(&chip->lock); 606 + 607 + for (i = 0; i < n; i++) { 608 + if (buf[i] >= '0' && buf[i] <= '3') { 609 + val = (buf[i] - '0') << __bf_shf(LP55xx_FADER_MAPPING_MASK); 610 + ret = lp55xx_update_bits(chip, 611 + cfg->reg_led_ctrl_base.addr + i, 612 + LP55xx_FADER_MAPPING_MASK, 613 + val); 614 + if (ret) 615 + return ret; 616 + } else { 617 + return -EINVAL; 618 + } 619 + } 620 + 621 + return len; 622 + } 623 + EXPORT_SYMBOL_GPL(lp55xx_store_master_fader_leds); 646 624 647 625 static struct attribute *lp55xx_engine_attributes[] = { 648 626 &dev_attr_select_engine.attr, ··· 991 423 } 992 424 EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used); 993 425 994 - int lp55xx_init_device(struct lp55xx_chip *chip) 426 + static void lp55xx_deinit_device(struct lp55xx_chip *chip) 427 + { 428 + struct lp55xx_platform_data *pdata = chip->pdata; 429 + 430 + if (chip->clk) 431 + clk_disable_unprepare(chip->clk); 432 + 433 + if (pdata->enable_gpiod) 434 + gpiod_set_value(pdata->enable_gpiod, 0); 435 + } 436 + 437 + static int lp55xx_init_device(struct lp55xx_chip *chip) 995 438 { 996 439 struct lp55xx_platform_data *pdata; 997 - struct lp55xx_device_config *cfg; 440 + const struct lp55xx_device_config *cfg; 998 441 struct device *dev = &chip->cl->dev; 999 442 int ret = 0; 1000 443 ··· 1055 476 err: 1056 477 return ret; 1057 478 } 1058 - EXPORT_SYMBOL_GPL(lp55xx_init_device); 1059 479 1060 - void lp55xx_deinit_device(struct lp55xx_chip *chip) 480 + static int lp55xx_register_leds(struct lp55xx_led *led, struct lp55xx_chip *chip) 1061 481 { 1062 482 struct lp55xx_platform_data *pdata = chip->pdata; 1063 - 1064 - if (chip->clk) 1065 - clk_disable_unprepare(chip->clk); 1066 - 1067 - if (pdata->enable_gpiod) 1068 - gpiod_set_value(pdata->enable_gpiod, 0); 1069 - } 1070 - EXPORT_SYMBOL_GPL(lp55xx_deinit_device); 1071 - 1072 - int lp55xx_register_leds(struct lp55xx_led *led, struct lp55xx_chip *chip) 1073 - { 1074 - struct lp55xx_platform_data *pdata = chip->pdata; 1075 - struct lp55xx_device_config *cfg = chip->cfg; 483 + const struct lp55xx_device_config *cfg = chip->cfg; 1076 484 int num_channels = pdata->num_channels; 1077 485 struct lp55xx_led *each; 1078 486 u8 led_current; ··· 1096 530 err_init_led: 1097 531 return ret; 1098 532 } 1099 - EXPORT_SYMBOL_GPL(lp55xx_register_leds); 1100 533 1101 - int lp55xx_register_sysfs(struct lp55xx_chip *chip) 534 + static int lp55xx_register_sysfs(struct lp55xx_chip *chip) 1102 535 { 1103 536 struct device *dev = &chip->cl->dev; 1104 - struct lp55xx_device_config *cfg = chip->cfg; 537 + const struct lp55xx_device_config *cfg = chip->cfg; 1105 538 int ret; 1106 539 1107 540 if (!cfg->run_engine || !cfg->firmware_cb) ··· 1114 549 return cfg->dev_attr_group ? 1115 550 sysfs_create_group(&dev->kobj, cfg->dev_attr_group) : 0; 1116 551 } 1117 - EXPORT_SYMBOL_GPL(lp55xx_register_sysfs); 1118 552 1119 - void lp55xx_unregister_sysfs(struct lp55xx_chip *chip) 553 + static void lp55xx_unregister_sysfs(struct lp55xx_chip *chip) 1120 554 { 1121 555 struct device *dev = &chip->cl->dev; 1122 - struct lp55xx_device_config *cfg = chip->cfg; 556 + const struct lp55xx_device_config *cfg = chip->cfg; 1123 557 1124 558 if (cfg->dev_attr_group) 1125 559 sysfs_remove_group(&dev->kobj, cfg->dev_attr_group); 1126 560 1127 561 sysfs_remove_group(&dev->kobj, &lp55xx_engine_attr_group); 1128 562 } 1129 - EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs); 1130 563 1131 564 static int lp55xx_parse_common_child(struct device_node *np, 1132 565 struct lp55xx_led_config *cfg, ··· 1217 654 return ret; 1218 655 } 1219 656 1220 - struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev, 1221 - struct device_node *np, 1222 - struct lp55xx_chip *chip) 657 + static struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev, 658 + struct device_node *np, 659 + struct lp55xx_chip *chip) 1223 660 { 1224 661 struct device_node *child; 1225 662 struct lp55xx_platform_data *pdata; ··· 1276 713 1277 714 return pdata; 1278 715 } 1279 - EXPORT_SYMBOL_GPL(lp55xx_of_populate_pdata); 716 + 717 + int lp55xx_probe(struct i2c_client *client) 718 + { 719 + const struct i2c_device_id *id = i2c_client_get_device_id(client); 720 + int program_length, ret; 721 + struct lp55xx_chip *chip; 722 + struct lp55xx_led *led; 723 + struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev); 724 + struct device_node *np = dev_of_node(&client->dev); 725 + 726 + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 727 + if (!chip) 728 + return -ENOMEM; 729 + 730 + chip->cfg = i2c_get_match_data(client); 731 + 732 + if (!pdata) { 733 + if (np) { 734 + pdata = lp55xx_of_populate_pdata(&client->dev, np, 735 + chip); 736 + if (IS_ERR(pdata)) 737 + return PTR_ERR(pdata); 738 + } else { 739 + dev_err(&client->dev, "no platform data\n"); 740 + return -EINVAL; 741 + } 742 + } 743 + 744 + /* Validate max program page */ 745 + program_length = LP55xx_BYTES_PER_PAGE; 746 + if (chip->cfg->pages_per_engine) 747 + program_length *= chip->cfg->pages_per_engine; 748 + 749 + /* support a max of 128bytes */ 750 + if (program_length > LP55xx_MAX_PROGRAM_LENGTH) { 751 + dev_err(&client->dev, "invalid pages_per_engine configured\n"); 752 + return -EINVAL; 753 + } 754 + 755 + led = devm_kcalloc(&client->dev, 756 + pdata->num_channels, sizeof(*led), GFP_KERNEL); 757 + if (!led) 758 + return -ENOMEM; 759 + 760 + chip->cl = client; 761 + chip->pdata = pdata; 762 + 763 + mutex_init(&chip->lock); 764 + 765 + i2c_set_clientdata(client, led); 766 + 767 + ret = lp55xx_init_device(chip); 768 + if (ret) 769 + goto err_init; 770 + 771 + dev_info(&client->dev, "%s Programmable led chip found\n", id->name); 772 + 773 + ret = lp55xx_register_leds(led, chip); 774 + if (ret) 775 + goto err_out; 776 + 777 + ret = lp55xx_register_sysfs(chip); 778 + if (ret) { 779 + dev_err(&client->dev, "registering sysfs failed\n"); 780 + goto err_out; 781 + } 782 + 783 + return 0; 784 + 785 + err_out: 786 + lp55xx_deinit_device(chip); 787 + err_init: 788 + return ret; 789 + } 790 + EXPORT_SYMBOL_GPL(lp55xx_probe); 791 + 792 + void lp55xx_remove(struct i2c_client *client) 793 + { 794 + struct lp55xx_led *led = i2c_get_clientdata(client); 795 + struct lp55xx_chip *chip = led->chip; 796 + 797 + lp55xx_stop_all_engine(chip); 798 + lp55xx_unregister_sysfs(chip); 799 + lp55xx_deinit_device(chip); 800 + } 801 + EXPORT_SYMBOL_GPL(lp55xx_remove); 1280 802 1281 803 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>"); 1282 804 MODULE_DESCRIPTION("LP55xx Common Driver");
+117 -46
drivers/leds/leds-lp55xx-common.h
··· 14 14 15 15 #include <linux/led-class-multicolor.h> 16 16 17 + #define LP55xx_BYTES_PER_PAGE 32 /* bytes */ 18 + 17 19 enum lp55xx_engine_index { 18 20 LP55XX_ENGINE_INVALID, 19 21 LP55XX_ENGINE_1, ··· 37 35 #define LP55XX_DEV_ATTR_WO(name, store) \ 38 36 DEVICE_ATTR(name, S_IWUSR, NULL, store) 39 37 40 - #define show_mode(nr) \ 38 + #define LP55XX_DEV_ATTR_ENGINE_MODE(nr) \ 41 39 static ssize_t show_engine##nr##_mode(struct device *dev, \ 42 - struct device_attribute *attr, \ 43 - char *buf) \ 40 + struct device_attribute *attr, \ 41 + char *buf) \ 44 42 { \ 45 - return show_engine_mode(dev, attr, buf, nr); \ 46 - } 47 - 48 - #define store_mode(nr) \ 43 + return lp55xx_show_engine_mode(dev, attr, buf, nr); \ 44 + } \ 49 45 static ssize_t store_engine##nr##_mode(struct device *dev, \ 50 - struct device_attribute *attr, \ 51 - const char *buf, size_t len) \ 46 + struct device_attribute *attr, \ 47 + const char *buf, size_t len) \ 52 48 { \ 53 - return store_engine_mode(dev, attr, buf, len, nr); \ 54 - } 49 + return lp55xx_store_engine_mode(dev, attr, buf, len, nr); \ 50 + } \ 51 + static LP55XX_DEV_ATTR_RW(engine##nr##_mode, show_engine##nr##_mode, \ 52 + store_engine##nr##_mode) 55 53 56 - #define show_leds(nr) \ 54 + #define LP55XX_DEV_ATTR_ENGINE_LEDS(nr) \ 57 55 static ssize_t show_engine##nr##_leds(struct device *dev, \ 58 - struct device_attribute *attr, \ 59 - char *buf) \ 56 + struct device_attribute *attr, \ 57 + char *buf) \ 60 58 { \ 61 - return show_engine_leds(dev, attr, buf, nr); \ 62 - } 59 + return lp55xx_show_engine_leds(dev, attr, buf, nr); \ 60 + } \ 61 + static ssize_t store_engine##nr##_leds(struct device *dev, \ 62 + struct device_attribute *attr, \ 63 + const char *buf, size_t len) \ 64 + { \ 65 + return lp55xx_store_engine_leds(dev, attr, buf, len, nr); \ 66 + } \ 67 + static LP55XX_DEV_ATTR_RW(engine##nr##_leds, show_engine##nr##_leds, \ 68 + store_engine##nr##_leds) 63 69 64 - #define store_leds(nr) \ 65 - static ssize_t store_engine##nr##_leds(struct device *dev, \ 66 - struct device_attribute *attr, \ 67 - const char *buf, size_t len) \ 68 - { \ 69 - return store_engine_leds(dev, attr, buf, len, nr); \ 70 - } 71 - 72 - #define store_load(nr) \ 70 + #define LP55XX_DEV_ATTR_ENGINE_LOAD(nr) \ 73 71 static ssize_t store_engine##nr##_load(struct device *dev, \ 74 - struct device_attribute *attr, \ 75 - const char *buf, size_t len) \ 72 + struct device_attribute *attr, \ 73 + const char *buf, size_t len) \ 76 74 { \ 77 - return store_engine_load(dev, attr, buf, len, nr); \ 78 - } 75 + return lp55xx_store_engine_load(dev, attr, buf, len, nr); \ 76 + } \ 77 + static LP55XX_DEV_ATTR_WO(engine##nr##_load, store_engine##nr##_load) 78 + 79 + #define LP55XX_DEV_ATTR_MASTER_FADER(nr) \ 80 + static ssize_t show_master_fader##nr(struct device *dev, \ 81 + struct device_attribute *attr, \ 82 + char *buf) \ 83 + { \ 84 + return lp55xx_show_master_fader(dev, attr, buf, nr); \ 85 + } \ 86 + static ssize_t store_master_fader##nr(struct device *dev, \ 87 + struct device_attribute *attr, \ 88 + const char *buf, size_t len) \ 89 + { \ 90 + return lp55xx_store_master_fader(dev, attr, buf, len, nr); \ 91 + } \ 92 + static LP55XX_DEV_ATTR_RW(master_fader##nr, show_master_fader##nr, \ 93 + store_master_fader##nr) 79 94 80 95 struct lp55xx_led; 81 96 struct lp55xx_chip; ··· 100 81 /* 101 82 * struct lp55xx_reg 102 83 * @addr : Register address 103 - * @val : Register value 84 + * @val : Register value (can also used as mask or shift) 104 85 */ 105 86 struct lp55xx_reg { 106 87 u8 addr; 107 - u8 val; 88 + union { 89 + u8 val; 90 + u8 mask; 91 + u8 shift; 92 + }; 108 93 }; 109 94 110 95 /* 111 96 * struct lp55xx_device_config 97 + * @reg_op_mode : Chip specific OP MODE reg addr 98 + * @engine_busy : Chip specific engine busy 99 + * (if not supported 153 us sleep) 112 100 * @reset : Chip specific reset command 113 101 * @enable : Chip specific enable command 102 + * @prog_mem_base : Chip specific base reg address for chip SMEM programming 103 + * @reg_led_pwm_base : Chip specific base reg address for LED PWM conf 104 + * @reg_led_current_base : Chip specific base reg address for LED current conf 105 + * @reg_master_fader_base : Chip specific base reg address for master fader base 106 + * @reg_led_ctrl_base : Chip specific base reg address for LED ctrl base 107 + * @pages_per_engine : Assigned pages for each engine 108 + * (if not set chip doesn't support pages) 114 109 * @max_channel : Maximum number of channels 115 110 * @post_init_device : Chip specific initialization code 116 111 * @brightness_fn : Brightness function ··· 135 102 * @dev_attr_group : Device specific attributes 136 103 */ 137 104 struct lp55xx_device_config { 105 + const struct lp55xx_reg reg_op_mode; /* addr, shift */ 106 + const struct lp55xx_reg reg_exec; /* addr, shift */ 107 + const struct lp55xx_reg engine_busy; /* addr, mask */ 138 108 const struct lp55xx_reg reset; 139 109 const struct lp55xx_reg enable; 110 + const struct lp55xx_reg prog_mem_base; 111 + const struct lp55xx_reg reg_led_pwm_base; 112 + const struct lp55xx_reg reg_led_current_base; 113 + const struct lp55xx_reg reg_master_fader_base; 114 + const struct lp55xx_reg reg_led_ctrl_base; 115 + const int pages_per_engine; 140 116 const int max_channel; 141 117 142 118 /* define if the device has specific initialization process */ ··· 197 155 struct lp55xx_platform_data *pdata; 198 156 struct mutex lock; /* lock for user-space interface */ 199 157 int num_leds; 200 - struct lp55xx_device_config *cfg; 158 + const struct lp55xx_device_config *cfg; 201 159 enum lp55xx_engine_index engine_idx; 202 160 struct lp55xx_engine engines[LP55XX_ENGINE_MAX]; 203 161 const struct firmware *fw; ··· 233 191 /* external clock detection */ 234 192 extern bool lp55xx_is_extclk_used(struct lp55xx_chip *chip); 235 193 236 - /* common device init/deinit functions */ 237 - extern int lp55xx_init_device(struct lp55xx_chip *chip); 238 - extern void lp55xx_deinit_device(struct lp55xx_chip *chip); 194 + /* common chip functions */ 195 + extern void lp55xx_stop_all_engine(struct lp55xx_chip *chip); 196 + extern void lp55xx_load_engine(struct lp55xx_chip *chip); 197 + extern int lp55xx_run_engine_common(struct lp55xx_chip *chip); 198 + extern int lp55xx_update_program_memory(struct lp55xx_chip *chip, 199 + const u8 *data, size_t size); 200 + extern void lp55xx_firmware_loaded_cb(struct lp55xx_chip *chip); 201 + extern int lp55xx_led_brightness(struct lp55xx_led *led); 202 + extern int lp55xx_multicolor_brightness(struct lp55xx_led *led); 203 + extern void lp55xx_set_led_current(struct lp55xx_led *led, u8 led_current); 204 + extern void lp55xx_turn_off_channels(struct lp55xx_chip *chip); 205 + extern void lp55xx_stop_engine(struct lp55xx_chip *chip); 239 206 240 - /* common LED class device functions */ 241 - extern int lp55xx_register_leds(struct lp55xx_led *led, 242 - struct lp55xx_chip *chip); 207 + /* common probe/remove function */ 208 + extern int lp55xx_probe(struct i2c_client *client); 209 + extern void lp55xx_remove(struct i2c_client *client); 243 210 244 - /* common device attributes functions */ 245 - extern int lp55xx_register_sysfs(struct lp55xx_chip *chip); 246 - extern void lp55xx_unregister_sysfs(struct lp55xx_chip *chip); 247 - 248 - /* common device tree population function */ 249 - extern struct lp55xx_platform_data 250 - *lp55xx_of_populate_pdata(struct device *dev, struct device_node *np, 251 - struct lp55xx_chip *chip); 211 + /* common sysfs function */ 212 + extern ssize_t lp55xx_show_engine_mode(struct device *dev, 213 + struct device_attribute *attr, 214 + char *buf, int nr); 215 + extern ssize_t lp55xx_store_engine_mode(struct device *dev, 216 + struct device_attribute *attr, 217 + const char *buf, size_t len, int nr); 218 + extern ssize_t lp55xx_store_engine_load(struct device *dev, 219 + struct device_attribute *attr, 220 + const char *buf, size_t len, int nr); 221 + extern ssize_t lp55xx_show_engine_leds(struct device *dev, 222 + struct device_attribute *attr, 223 + char *buf, int nr); 224 + extern ssize_t lp55xx_store_engine_leds(struct device *dev, 225 + struct device_attribute *attr, 226 + const char *buf, size_t len, int nr); 227 + extern ssize_t lp55xx_show_master_fader(struct device *dev, 228 + struct device_attribute *attr, 229 + char *buf, int nr); 230 + extern ssize_t lp55xx_store_master_fader(struct device *dev, 231 + struct device_attribute *attr, 232 + const char *buf, size_t len, int nr); 233 + extern ssize_t lp55xx_show_master_fader_leds(struct device *dev, 234 + struct device_attribute *attr, 235 + char *buf); 236 + extern ssize_t lp55xx_store_master_fader_leds(struct device *dev, 237 + struct device_attribute *attr, 238 + const char *buf, size_t len); 252 239 253 240 #endif /* _LEDS_LP55XX_COMMON_H */
+34 -279
drivers/leds/leds-lp8501.c
··· 20 20 21 21 #include "leds-lp55xx-common.h" 22 22 23 - #define LP8501_PROGRAM_LENGTH 32 23 + #define LP8501_PAGES_PER_ENGINE 1 24 24 #define LP8501_MAX_LEDS 9 25 25 26 26 /* Registers */ 27 27 #define LP8501_REG_ENABLE 0x00 28 28 #define LP8501_ENABLE BIT(6) 29 - #define LP8501_EXEC_M 0x3F 30 - #define LP8501_EXEC_ENG1_M 0x30 31 - #define LP8501_EXEC_ENG2_M 0x0C 32 - #define LP8501_EXEC_ENG3_M 0x03 33 - #define LP8501_RUN_ENG1 0x20 34 - #define LP8501_RUN_ENG2 0x08 35 - #define LP8501_RUN_ENG3 0x02 36 29 37 30 #define LP8501_REG_OP_MODE 0x01 38 - #define LP8501_MODE_ENG1_M 0x30 39 - #define LP8501_MODE_ENG2_M 0x0C 40 - #define LP8501_MODE_ENG3_M 0x03 41 - #define LP8501_LOAD_ENG1 0x10 42 - #define LP8501_LOAD_ENG2 0x04 43 - #define LP8501_LOAD_ENG3 0x01 44 31 45 32 #define LP8501_REG_PWR_CONFIG 0x05 46 33 #define LP8501_PWR_CONFIG_M 0x03 ··· 45 58 #define LP8501_INT_CLK BIT(0) 46 59 #define LP8501_DEFAULT_CFG (LP8501_PWM_PSAVE | LP8501_AUTO_INC | LP8501_PWR_SAVE) 47 60 61 + #define LP8501_REG_STATUS 0x3A 62 + #define LP8501_ENGINE_BUSY BIT(4) 63 + 48 64 #define LP8501_REG_RESET 0x3D 49 65 #define LP8501_RESET 0xFF 50 66 51 - #define LP8501_REG_PROG_PAGE_SEL 0x4F 52 - #define LP8501_PAGE_ENG1 0 53 - #define LP8501_PAGE_ENG2 1 54 - #define LP8501_PAGE_ENG3 2 55 - 56 67 #define LP8501_REG_PROG_MEM 0x50 57 - 58 - #define LP8501_ENG1_IS_LOADING(mode) \ 59 - ((mode & LP8501_MODE_ENG1_M) == LP8501_LOAD_ENG1) 60 - #define LP8501_ENG2_IS_LOADING(mode) \ 61 - ((mode & LP8501_MODE_ENG2_M) == LP8501_LOAD_ENG2) 62 - #define LP8501_ENG3_IS_LOADING(mode) \ 63 - ((mode & LP8501_MODE_ENG3_M) == LP8501_LOAD_ENG3) 64 - 65 - static inline void lp8501_wait_opmode_done(void) 66 - { 67 - usleep_range(1000, 2000); 68 - } 69 - 70 - static void lp8501_set_led_current(struct lp55xx_led *led, u8 led_current) 71 - { 72 - led->led_current = led_current; 73 - lp55xx_write(led->chip, LP8501_REG_LED_CURRENT_BASE + led->chan_nr, 74 - led_current); 75 - } 76 68 77 69 static int lp8501_post_init_device(struct lp55xx_chip *chip) 78 70 { ··· 79 113 LP8501_PWR_CONFIG_M, chip->pdata->pwr_sel); 80 114 } 81 115 82 - static void lp8501_load_engine(struct lp55xx_chip *chip) 83 - { 84 - enum lp55xx_engine_index idx = chip->engine_idx; 85 - static const u8 mask[] = { 86 - [LP55XX_ENGINE_1] = LP8501_MODE_ENG1_M, 87 - [LP55XX_ENGINE_2] = LP8501_MODE_ENG2_M, 88 - [LP55XX_ENGINE_3] = LP8501_MODE_ENG3_M, 89 - }; 90 - 91 - static const u8 val[] = { 92 - [LP55XX_ENGINE_1] = LP8501_LOAD_ENG1, 93 - [LP55XX_ENGINE_2] = LP8501_LOAD_ENG2, 94 - [LP55XX_ENGINE_3] = LP8501_LOAD_ENG3, 95 - }; 96 - 97 - static const u8 page_sel[] = { 98 - [LP55XX_ENGINE_1] = LP8501_PAGE_ENG1, 99 - [LP55XX_ENGINE_2] = LP8501_PAGE_ENG2, 100 - [LP55XX_ENGINE_3] = LP8501_PAGE_ENG3, 101 - }; 102 - 103 - lp55xx_update_bits(chip, LP8501_REG_OP_MODE, mask[idx], val[idx]); 104 - 105 - lp8501_wait_opmode_done(); 106 - 107 - lp55xx_write(chip, LP8501_REG_PROG_PAGE_SEL, page_sel[idx]); 108 - } 109 - 110 - static void lp8501_stop_engine(struct lp55xx_chip *chip) 111 - { 112 - lp55xx_write(chip, LP8501_REG_OP_MODE, 0); 113 - lp8501_wait_opmode_done(); 114 - } 115 - 116 - static void lp8501_turn_off_channels(struct lp55xx_chip *chip) 117 - { 118 - int i; 119 - 120 - for (i = 0; i < LP8501_MAX_LEDS; i++) 121 - lp55xx_write(chip, LP8501_REG_LED_PWM_BASE + i, 0); 122 - } 123 - 124 116 static void lp8501_run_engine(struct lp55xx_chip *chip, bool start) 125 117 { 126 - int ret; 127 - u8 mode; 128 - u8 exec; 129 - 130 118 /* stop engine */ 131 119 if (!start) { 132 - lp8501_stop_engine(chip); 133 - lp8501_turn_off_channels(chip); 120 + lp55xx_stop_all_engine(chip); 121 + lp55xx_turn_off_channels(chip); 134 122 return; 135 123 } 136 124 137 - /* 138 - * To run the engine, 139 - * operation mode and enable register should updated at the same time 140 - */ 141 - 142 - ret = lp55xx_read(chip, LP8501_REG_OP_MODE, &mode); 143 - if (ret) 144 - return; 145 - 146 - ret = lp55xx_read(chip, LP8501_REG_ENABLE, &exec); 147 - if (ret) 148 - return; 149 - 150 - /* change operation mode to RUN only when each engine is loading */ 151 - if (LP8501_ENG1_IS_LOADING(mode)) { 152 - mode = (mode & ~LP8501_MODE_ENG1_M) | LP8501_RUN_ENG1; 153 - exec = (exec & ~LP8501_EXEC_ENG1_M) | LP8501_RUN_ENG1; 154 - } 155 - 156 - if (LP8501_ENG2_IS_LOADING(mode)) { 157 - mode = (mode & ~LP8501_MODE_ENG2_M) | LP8501_RUN_ENG2; 158 - exec = (exec & ~LP8501_EXEC_ENG2_M) | LP8501_RUN_ENG2; 159 - } 160 - 161 - if (LP8501_ENG3_IS_LOADING(mode)) { 162 - mode = (mode & ~LP8501_MODE_ENG3_M) | LP8501_RUN_ENG3; 163 - exec = (exec & ~LP8501_EXEC_ENG3_M) | LP8501_RUN_ENG3; 164 - } 165 - 166 - lp55xx_write(chip, LP8501_REG_OP_MODE, mode); 167 - lp8501_wait_opmode_done(); 168 - 169 - lp55xx_update_bits(chip, LP8501_REG_ENABLE, LP8501_EXEC_M, exec); 170 - } 171 - 172 - static int lp8501_update_program_memory(struct lp55xx_chip *chip, 173 - const u8 *data, size_t size) 174 - { 175 - u8 pattern[LP8501_PROGRAM_LENGTH] = {0}; 176 - unsigned cmd; 177 - char c[3]; 178 - int update_size; 179 - int nrchars; 180 - int offset = 0; 181 - int ret; 182 - int i; 183 - 184 - /* clear program memory before updating */ 185 - for (i = 0; i < LP8501_PROGRAM_LENGTH; i++) 186 - lp55xx_write(chip, LP8501_REG_PROG_MEM + i, 0); 187 - 188 - i = 0; 189 - while ((offset < size - 1) && (i < LP8501_PROGRAM_LENGTH)) { 190 - /* separate sscanfs because length is working only for %s */ 191 - ret = sscanf(data + offset, "%2s%n ", c, &nrchars); 192 - if (ret != 1) 193 - goto err; 194 - 195 - ret = sscanf(c, "%2x", &cmd); 196 - if (ret != 1) 197 - goto err; 198 - 199 - pattern[i] = (u8)cmd; 200 - offset += nrchars; 201 - i++; 202 - } 203 - 204 - /* Each instruction is 16bit long. Check that length is even */ 205 - if (i % 2) 206 - goto err; 207 - 208 - update_size = i; 209 - for (i = 0; i < update_size; i++) 210 - lp55xx_write(chip, LP8501_REG_PROG_MEM + i, pattern[i]); 211 - 212 - return 0; 213 - 214 - err: 215 - dev_err(&chip->cl->dev, "wrong pattern format\n"); 216 - return -EINVAL; 217 - } 218 - 219 - static void lp8501_firmware_loaded(struct lp55xx_chip *chip) 220 - { 221 - const struct firmware *fw = chip->fw; 222 - 223 - if (fw->size > LP8501_PROGRAM_LENGTH) { 224 - dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n", 225 - fw->size); 226 - return; 227 - } 228 - 229 - /* 230 - * Program memory sequence 231 - * 1) set engine mode to "LOAD" 232 - * 2) write firmware data into program memory 233 - */ 234 - 235 - lp8501_load_engine(chip); 236 - lp8501_update_program_memory(chip, fw->data, fw->size); 237 - } 238 - 239 - static int lp8501_led_brightness(struct lp55xx_led *led) 240 - { 241 - struct lp55xx_chip *chip = led->chip; 242 - int ret; 243 - 244 - mutex_lock(&chip->lock); 245 - ret = lp55xx_write(chip, LP8501_REG_LED_PWM_BASE + led->chan_nr, 246 - led->brightness); 247 - mutex_unlock(&chip->lock); 248 - 249 - return ret; 125 + lp55xx_run_engine_common(chip); 250 126 } 251 127 252 128 /* Chip specific configurations */ 253 129 static struct lp55xx_device_config lp8501_cfg = { 130 + .reg_op_mode = { 131 + .addr = LP8501_REG_OP_MODE, 132 + }, 133 + .reg_exec = { 134 + .addr = LP8501_REG_ENABLE, 135 + }, 136 + .engine_busy = { 137 + .addr = LP8501_REG_STATUS, 138 + .mask = LP8501_ENGINE_BUSY, 139 + }, 254 140 .reset = { 255 141 .addr = LP8501_REG_RESET, 256 142 .val = LP8501_RESET, ··· 111 293 .addr = LP8501_REG_ENABLE, 112 294 .val = LP8501_ENABLE, 113 295 }, 296 + .prog_mem_base = { 297 + .addr = LP8501_REG_PROG_MEM, 298 + }, 299 + .reg_led_pwm_base = { 300 + .addr = LP8501_REG_LED_PWM_BASE, 301 + }, 302 + .reg_led_current_base = { 303 + .addr = LP8501_REG_LED_CURRENT_BASE, 304 + }, 305 + .pages_per_engine = LP8501_PAGES_PER_ENGINE, 114 306 .max_channel = LP8501_MAX_LEDS, 115 307 .post_init_device = lp8501_post_init_device, 116 - .brightness_fn = lp8501_led_brightness, 117 - .set_led_current = lp8501_set_led_current, 118 - .firmware_cb = lp8501_firmware_loaded, 308 + .brightness_fn = lp55xx_led_brightness, 309 + .set_led_current = lp55xx_set_led_current, 310 + .firmware_cb = lp55xx_firmware_loaded_cb, 119 311 .run_engine = lp8501_run_engine, 120 312 }; 121 313 122 - static int lp8501_probe(struct i2c_client *client) 123 - { 124 - const struct i2c_device_id *id = i2c_client_get_device_id(client); 125 - int ret; 126 - struct lp55xx_chip *chip; 127 - struct lp55xx_led *led; 128 - struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev); 129 - struct device_node *np = dev_of_node(&client->dev); 130 - 131 - chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 132 - if (!chip) 133 - return -ENOMEM; 134 - 135 - chip->cfg = &lp8501_cfg; 136 - 137 - if (!pdata) { 138 - if (np) { 139 - pdata = lp55xx_of_populate_pdata(&client->dev, np, 140 - chip); 141 - if (IS_ERR(pdata)) 142 - return PTR_ERR(pdata); 143 - } else { 144 - dev_err(&client->dev, "no platform data\n"); 145 - return -EINVAL; 146 - } 147 - } 148 - 149 - led = devm_kcalloc(&client->dev, 150 - pdata->num_channels, sizeof(*led), GFP_KERNEL); 151 - if (!led) 152 - return -ENOMEM; 153 - 154 - chip->cl = client; 155 - chip->pdata = pdata; 156 - 157 - mutex_init(&chip->lock); 158 - 159 - i2c_set_clientdata(client, led); 160 - 161 - ret = lp55xx_init_device(chip); 162 - if (ret) 163 - goto err_init; 164 - 165 - dev_info(&client->dev, "%s Programmable led chip found\n", id->name); 166 - 167 - ret = lp55xx_register_leds(led, chip); 168 - if (ret) 169 - goto err_out; 170 - 171 - ret = lp55xx_register_sysfs(chip); 172 - if (ret) { 173 - dev_err(&client->dev, "registering sysfs failed\n"); 174 - goto err_out; 175 - } 176 - 177 - return 0; 178 - 179 - err_out: 180 - lp55xx_deinit_device(chip); 181 - err_init: 182 - return ret; 183 - } 184 - 185 - static void lp8501_remove(struct i2c_client *client) 186 - { 187 - struct lp55xx_led *led = i2c_get_clientdata(client); 188 - struct lp55xx_chip *chip = led->chip; 189 - 190 - lp8501_stop_engine(chip); 191 - lp55xx_unregister_sysfs(chip); 192 - lp55xx_deinit_device(chip); 193 - } 194 - 195 314 static const struct i2c_device_id lp8501_id[] = { 196 - { "lp8501", 0 }, 315 + { "lp8501", .driver_data = (kernel_ulong_t)&lp8501_cfg, }, 197 316 { } 198 317 }; 199 318 MODULE_DEVICE_TABLE(i2c, lp8501_id); 200 319 201 320 static const struct of_device_id of_lp8501_leds_match[] = { 202 - { .compatible = "ti,lp8501", }, 321 + { .compatible = "ti,lp8501", .data = &lp8501_cfg, }, 203 322 {}, 204 323 }; 205 324 ··· 147 392 .name = "lp8501", 148 393 .of_match_table = of_lp8501_leds_match, 149 394 }, 150 - .probe = lp8501_probe, 151 - .remove = lp8501_remove, 395 + .probe = lp55xx_probe, 396 + .remove = lp55xx_remove, 152 397 .id_table = lp8501_id, 153 398 }; 154 399
+1 -1
drivers/leds/leds-lp8860.c
··· 459 459 } 460 460 461 461 static const struct i2c_device_id lp8860_id[] = { 462 - { "lp8860", 0 }, 462 + { "lp8860" }, 463 463 { } 464 464 }; 465 465 MODULE_DEVICE_TABLE(i2c, lp8860_id);
+63 -18
drivers/leds/leds-pca9532.c
··· 29 29 #define LED_SHIFT(led) (LED_NUM(led) * 2) 30 30 #define LED_MASK(led) (0x3 << LED_SHIFT(led)) 31 31 32 + #define PCA9532_PWM_PERIOD_DIV 152 33 + #define PCA9532_PWM_DUTY_DIV 256 34 + 32 35 #define ldev_to_led(c) container_of(c, struct pca9532_led, ldev) 33 36 34 37 struct pca9532_chip_info { ··· 48 45 struct gpio_chip gpio; 49 46 #endif 50 47 const struct pca9532_chip_info *chip_info; 48 + 49 + #define PCA9532_PWM_ID_0 0 50 + #define PCA9532_PWM_ID_1 1 51 51 u8 pwm[2]; 52 52 u8 psc[2]; 53 + bool hw_blink; 53 54 }; 54 55 55 56 static int pca9532_probe(struct i2c_client *client); ··· 188 181 led->state = PCA9532_ON; 189 182 else { 190 183 led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */ 191 - err = pca9532_calcpwm(led->client, 0, 0, value); 184 + err = pca9532_calcpwm(led->client, PCA9532_PWM_ID_0, 0, value); 192 185 if (err) 193 186 return err; 194 187 } 195 188 if (led->state == PCA9532_PWM0) 196 - pca9532_setpwm(led->client, 0); 189 + pca9532_setpwm(led->client, PCA9532_PWM_ID_0); 197 190 pca9532_setled(led); 198 191 return err; 192 + } 193 + 194 + static int pca9532_update_hw_blink(struct pca9532_led *led, 195 + unsigned long delay_on, unsigned long delay_off) 196 + { 197 + struct pca9532_data *data = i2c_get_clientdata(led->client); 198 + unsigned int psc; 199 + int i; 200 + 201 + /* Look for others LEDs that already use PWM1 */ 202 + for (i = 0; i < data->chip_info->num_leds; i++) { 203 + struct pca9532_led *other = &data->leds[i]; 204 + 205 + if (other == led) 206 + continue; 207 + 208 + if (other->state == PCA9532_PWM1) { 209 + if (other->ldev.blink_delay_on != delay_on || 210 + other->ldev.blink_delay_off != delay_off) { 211 + dev_err(&led->client->dev, 212 + "HW can handle only one blink configuration at a time\n"); 213 + return -EINVAL; 214 + } 215 + } 216 + } 217 + 218 + psc = ((delay_on + delay_off) * PCA9532_PWM_PERIOD_DIV - 1) / 1000; 219 + if (psc > U8_MAX) { 220 + dev_err(&led->client->dev, "Blink period too long to be handled by hardware\n"); 221 + return -EINVAL; 222 + } 223 + 224 + led->state = PCA9532_PWM1; 225 + data->psc[PCA9532_PWM_ID_1] = psc; 226 + data->pwm[PCA9532_PWM_ID_1] = (delay_on * PCA9532_PWM_DUTY_DIV) / (delay_on + delay_off); 227 + 228 + return pca9532_setpwm(data->client, PCA9532_PWM_ID_1); 199 229 } 200 230 201 231 static int pca9532_set_blink(struct led_classdev *led_cdev, ··· 240 196 { 241 197 struct pca9532_led *led = ldev_to_led(led_cdev); 242 198 struct i2c_client *client = led->client; 243 - int psc; 244 - int err = 0; 199 + struct pca9532_data *data = i2c_get_clientdata(client); 200 + int err; 201 + 202 + if (!data->hw_blink) 203 + return -EINVAL; 245 204 246 205 if (*delay_on == 0 && *delay_off == 0) { 247 206 /* led subsystem ask us for a blink rate */ 248 - *delay_on = 1000; 249 - *delay_off = 1000; 207 + *delay_on = 500; 208 + *delay_off = 500; 250 209 } 251 - if (*delay_on != *delay_off || *delay_on > 1690 || *delay_on < 6) 252 - return -EINVAL; 253 210 254 - /* Thecus specific: only use PSC/PWM 0 */ 255 - psc = (*delay_on * 152-1)/1000; 256 - err = pca9532_calcpwm(client, 0, psc, led_cdev->brightness); 211 + err = pca9532_update_hw_blink(led, *delay_on, *delay_off); 257 212 if (err) 258 213 return err; 259 - if (led->state == PCA9532_PWM0) 260 - pca9532_setpwm(led->client, 0); 214 + 261 215 pca9532_setled(led); 262 216 263 217 return 0; ··· 271 229 272 230 /* XXX: allow different kind of beeps with psc/pwm modifications */ 273 231 if (value > 1 && value < 32767) 274 - data->pwm[1] = 127; 232 + data->pwm[PCA9532_PWM_ID_1] = 127; 275 233 else 276 - data->pwm[1] = 0; 234 + data->pwm[PCA9532_PWM_ID_1] = 0; 277 235 278 236 schedule_work(&data->work); 279 237 ··· 288 246 289 247 mutex_lock(&data->update_lock); 290 248 i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(maxleds, 1), 291 - data->pwm[1]); 249 + data->pwm[PCA9532_PWM_ID_1]); 292 250 mutex_unlock(&data->update_lock); 293 251 } 294 252 ··· 401 359 data->psc[i]); 402 360 } 403 361 362 + data->hw_blink = true; 404 363 for (i = 0; i < data->chip_info->num_leds; i++) { 405 364 struct pca9532_led *led = &data->leds[i]; 406 365 struct pca9532_led *pled = &pdata->leds[i]; ··· 436 393 pca9532_setled(led); 437 394 break; 438 395 case PCA9532_TYPE_N2100_BEEP: 396 + /* PWM1 is reserved for beeper so blink will not use hardware */ 397 + data->hw_blink = false; 439 398 BUG_ON(data->idev); 440 399 led->state = PCA9532_PWM1; 441 400 pca9532_setled(led); ··· 520 475 521 476 pdata->gpio_base = -1; 522 477 523 - of_property_read_u8_array(np, "nxp,pwm", &pdata->pwm[0], 478 + of_property_read_u8_array(np, "nxp,pwm", &pdata->pwm[PCA9532_PWM_ID_0], 524 479 ARRAY_SIZE(pdata->pwm)); 525 - of_property_read_u8_array(np, "nxp,psc", &pdata->psc[0], 480 + of_property_read_u8_array(np, "nxp,psc", &pdata->psc[PCA9532_PWM_ID_0], 526 481 ARRAY_SIZE(pdata->psc)); 527 482 528 483 for_each_available_child_of_node(np, child) {
+9 -19
drivers/leds/leds-powernv.c
··· 246 246 const char *cur = NULL; 247 247 int rc = -1; 248 248 struct property *p; 249 - struct device_node *np; 250 249 struct powernv_led_data *powernv_led; 251 250 struct device *dev = &pdev->dev; 252 251 253 - for_each_available_child_of_node(led_node, np) { 252 + for_each_available_child_of_node_scoped(led_node, np) { 254 253 p = of_find_property(np, "led-types", NULL); 255 254 256 255 while ((cur = of_prop_next_string(p, cur)) != NULL) { 257 256 powernv_led = devm_kzalloc(dev, sizeof(*powernv_led), 258 257 GFP_KERNEL); 259 - if (!powernv_led) { 260 - of_node_put(np); 258 + if (!powernv_led) 261 259 return -ENOMEM; 262 - } 263 260 264 261 powernv_led->common = powernv_led_common; 265 262 powernv_led->loc_code = (char *)np->name; 266 263 267 264 rc = powernv_led_create(dev, powernv_led, cur); 268 - if (rc) { 269 - of_node_put(np); 265 + if (rc) 270 266 return rc; 271 - } 267 + 272 268 } /* while end */ 273 269 } 274 270 ··· 274 278 /* Platform driver probe */ 275 279 static int powernv_led_probe(struct platform_device *pdev) 276 280 { 277 - struct device_node *led_node; 278 281 struct powernv_led_common *powernv_led_common; 279 282 struct device *dev = &pdev->dev; 280 - int rc; 283 + struct device_node *led_node 284 + __free(device_node) = of_find_node_by_path("/ibm,opal/leds"); 281 285 282 - led_node = of_find_node_by_path("/ibm,opal/leds"); 283 286 if (!led_node) { 284 287 dev_err(dev, "%s: LED parent device node not found\n", 285 288 __func__); ··· 287 292 288 293 powernv_led_common = devm_kzalloc(dev, sizeof(*powernv_led_common), 289 294 GFP_KERNEL); 290 - if (!powernv_led_common) { 291 - rc = -ENOMEM; 292 - goto out; 293 - } 295 + if (!powernv_led_common) 296 + return -ENOMEM; 294 297 295 298 mutex_init(&powernv_led_common->lock); 296 299 powernv_led_common->max_led_type = cpu_to_be64(OPAL_SLOT_LED_TYPE_MAX); 297 300 298 301 platform_set_drvdata(pdev, powernv_led_common); 299 302 300 - rc = powernv_led_classdev(pdev, led_node, powernv_led_common); 301 - out: 302 - of_node_put(led_node); 303 - return rc; 303 + return powernv_led_classdev(pdev, led_node, powernv_led_common); 304 304 } 305 305 306 306 /* Platform driver remove */
+22 -41
drivers/leds/leds-spi-byte.c
··· 29 29 */ 30 30 31 31 #include <linux/leds.h> 32 + #include <linux/mod_devicetable.h> 32 33 #include <linux/module.h> 33 - #include <linux/of.h> 34 - #include <linux/spi/spi.h> 35 34 #include <linux/mutex.h> 35 + #include <linux/property.h> 36 + #include <linux/spi/spi.h> 36 37 #include <uapi/linux/uleds.h> 37 38 38 39 struct spi_byte_chipdef { ··· 56 55 .max_value = 0x3F, 57 56 }; 58 57 59 - static const struct of_device_id spi_byte_dt_ids[] = { 60 - { .compatible = "ubnt,acb-spi-led", .data = &ubnt_acb_spi_led_cdef }, 61 - {}, 62 - }; 63 - 64 - MODULE_DEVICE_TABLE(of, spi_byte_dt_ids); 65 - 66 58 static int spi_byte_brightness_set_blocking(struct led_classdev *dev, 67 59 enum led_brightness brightness) 68 60 { ··· 74 80 75 81 static int spi_byte_probe(struct spi_device *spi) 76 82 { 77 - struct device_node *child; 83 + struct fwnode_handle *child __free(fwnode_handle) = NULL; 78 84 struct device *dev = &spi->dev; 79 85 struct spi_byte_led *led; 80 86 struct led_init_data init_data = {}; 81 - const char *state; 87 + enum led_default_state state; 82 88 int ret; 83 89 84 - if (of_get_available_child_count(dev_of_node(dev)) != 1) { 90 + if (device_get_child_node_count(dev) != 1) { 85 91 dev_err(dev, "Device must have exactly one LED sub-node."); 86 92 return -EINVAL; 87 93 } 88 - child = of_get_next_available_child(dev_of_node(dev), NULL); 89 94 90 95 led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); 91 96 if (!led) 92 97 return -ENOMEM; 93 98 99 + ret = devm_mutex_init(dev, &led->mutex); 100 + if (ret) 101 + return ret; 102 + 94 103 led->spi = spi; 95 - mutex_init(&led->mutex); 96 104 led->cdef = device_get_match_data(dev); 97 105 led->ldev.brightness = LED_OFF; 98 106 led->ldev.max_brightness = led->cdef->max_value - led->cdef->off_value; 99 107 led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking; 100 108 101 - state = of_get_property(child, "default-state", NULL); 102 - if (state) { 103 - if (!strcmp(state, "on")) { 104 - led->ldev.brightness = led->ldev.max_brightness; 105 - } else if (strcmp(state, "off")) { 106 - /* all other cases except "off" */ 107 - dev_err(dev, "default-state can only be 'on' or 'off'"); 108 - return -EINVAL; 109 - } 110 - } 109 + child = device_get_next_child_node(dev, NULL); 110 + 111 + state = led_init_default_state_get(child); 112 + if (state == LEDS_DEFSTATE_ON) 113 + led->ldev.brightness = led->ldev.max_brightness; 111 114 spi_byte_brightness_set_blocking(&led->ldev, 112 115 led->ldev.brightness); 113 116 114 - init_data.fwnode = of_fwnode_handle(child); 117 + init_data.fwnode = child; 115 118 init_data.devicename = "leds-spi-byte"; 116 119 init_data.default_label = ":"; 117 120 118 - ret = devm_led_classdev_register_ext(&spi->dev, &led->ldev, &init_data); 119 - if (ret) { 120 - mutex_destroy(&led->mutex); 121 - return ret; 122 - } 123 - spi_set_drvdata(spi, led); 124 - 125 - return 0; 121 + return devm_led_classdev_register_ext(dev, &led->ldev, &init_data); 126 122 } 127 123 128 - static void spi_byte_remove(struct spi_device *spi) 129 - { 130 - struct spi_byte_led *led = spi_get_drvdata(spi); 131 - 132 - mutex_destroy(&led->mutex); 133 - } 124 + static const struct of_device_id spi_byte_dt_ids[] = { 125 + { .compatible = "ubnt,acb-spi-led", .data = &ubnt_acb_spi_led_cdef }, 126 + {} 127 + }; 128 + MODULE_DEVICE_TABLE(of, spi_byte_dt_ids); 134 129 135 130 static struct spi_driver spi_byte_driver = { 136 131 .probe = spi_byte_probe, 137 - .remove = spi_byte_remove, 138 132 .driver = { 139 133 .name = KBUILD_MODNAME, 140 134 .of_match_table = spi_byte_dt_ids, 141 135 }, 142 136 }; 143 - 144 137 module_spi_driver(spi_byte_driver); 145 138 146 139 MODULE_AUTHOR("Christian Mauderer <oss@c-mauderer.de>");
+5 -2
drivers/leds/leds-ss4200.c
··· 356 356 357 357 nas_gpio_pci_dev = dev; 358 358 status = pci_read_config_dword(dev, PMBASE, &g_pm_io_base); 359 - if (status) 359 + if (status) { 360 + status = pcibios_err_to_errno(status); 360 361 goto out; 362 + } 361 363 g_pm_io_base &= 0x00000ff80; 362 364 363 365 status = pci_read_config_dword(dev, GPIO_CTRL, &gc); ··· 371 369 } 372 370 373 371 status = pci_read_config_dword(dev, GPIO_BASE, &nas_gpio_io_base); 374 - if (0 > status) { 372 + if (status) { 375 373 dev_info(&dev->dev, "Unable to read GPIOBASE.\n"); 374 + status = pcibios_err_to_errno(status); 376 375 goto out; 377 376 } 378 377 dev_dbg(&dev->dev, ": GPIOBASE = 0x%08x\n", nas_gpio_io_base);
+7 -11
drivers/leds/leds-tlc591xx.c
··· 146 146 static int 147 147 tlc591xx_probe(struct i2c_client *client) 148 148 { 149 - struct device_node *np, *child; 149 + struct device_node *np; 150 150 struct device *dev = &client->dev; 151 151 const struct tlc591xx *tlc591xx; 152 152 struct tlc591xx_priv *priv; ··· 182 182 if (err < 0) 183 183 return err; 184 184 185 - for_each_available_child_of_node(np, child) { 185 + for_each_available_child_of_node_scoped(np, child) { 186 186 struct tlc591xx_led *led; 187 187 struct led_init_data init_data = {}; 188 188 189 189 init_data.fwnode = of_fwnode_handle(child); 190 190 191 191 err = of_property_read_u32(child, "reg", &reg); 192 - if (err) { 193 - of_node_put(child); 192 + if (err) 194 193 return err; 195 - } 194 + 196 195 if (reg < 0 || reg >= tlc591xx->max_leds || 197 - priv->leds[reg].active) { 198 - of_node_put(child); 196 + priv->leds[reg].active) 199 197 return -EINVAL; 200 - } 198 + 201 199 led = &priv->leds[reg]; 202 200 203 201 led->active = true; ··· 205 207 led->ldev.max_brightness = TLC591XX_MAX_BRIGHTNESS; 206 208 err = devm_led_classdev_register_ext(dev, &led->ldev, 207 209 &init_data); 208 - if (err < 0) { 209 - of_node_put(child); 210 + if (err < 0) 210 211 return dev_err_probe(dev, err, 211 212 "couldn't register LED %s\n", 212 213 led->ldev.name); 213 - } 214 214 } 215 215 return 0; 216 216 }
+1 -1
drivers/leds/leds-turris-omnia.c
··· 534 534 }; 535 535 536 536 static const struct i2c_device_id omnia_id[] = { 537 - { "omnia", 0 }, 537 + { "omnia" }, 538 538 { } 539 539 }; 540 540 MODULE_DEVICE_TABLE(i2c, omnia_id);
-1
drivers/leds/rgb/Kconfig
··· 17 17 config LEDS_KTD202X 18 18 tristate "LED support for KTD202x Chips" 19 19 depends on I2C 20 - depends on OF 21 20 select REGMAP_I2C 22 21 help 23 22 This option enables support for the Kinetic KTD2026/KTD2027
+46 -34
drivers/leds/rgb/leds-ktd202x.c
··· 99 99 struct device *dev; 100 100 struct regmap *regmap; 101 101 bool enabled; 102 - int num_leds; 102 + unsigned long num_leds; 103 103 struct ktd202x_led leds[] __counted_by(num_leds); 104 104 }; 105 105 ··· 381 381 mc->num_colors); 382 382 } 383 383 384 - static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct device_node *np, 384 + static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct fwnode_handle *fwnode, 385 385 struct ktd202x_led *led, struct led_init_data *init_data) 386 386 { 387 + struct fwnode_handle *child; 387 388 struct led_classdev *cdev; 388 - struct device_node *child; 389 389 struct mc_subled *info; 390 390 int num_channels; 391 391 int i = 0; 392 392 393 - num_channels = of_get_available_child_count(np); 393 + num_channels = 0; 394 + fwnode_for_each_available_child_node(fwnode, child) 395 + num_channels++; 396 + 394 397 if (!num_channels || num_channels > chip->num_leds) 395 398 return -EINVAL; 396 399 ··· 401 398 if (!info) 402 399 return -ENOMEM; 403 400 404 - for_each_available_child_of_node(np, child) { 401 + fwnode_for_each_available_child_node(fwnode, child) { 405 402 u32 mono_color; 406 403 u32 reg; 407 404 int ret; 408 405 409 - ret = of_property_read_u32(child, "reg", &reg); 406 + ret = fwnode_property_read_u32(child, "reg", &reg); 410 407 if (ret != 0 || reg >= chip->num_leds) { 411 - dev_err(chip->dev, "invalid 'reg' of %pOFn\n", child); 412 - of_node_put(child); 413 - return -EINVAL; 408 + dev_err(chip->dev, "invalid 'reg' of %pfw\n", child); 409 + fwnode_handle_put(child); 410 + return ret; 414 411 } 415 412 416 - ret = of_property_read_u32(child, "color", &mono_color); 413 + ret = fwnode_property_read_u32(child, "color", &mono_color); 417 414 if (ret < 0 && ret != -EINVAL) { 418 - dev_err(chip->dev, "failed to parse 'color' of %pOF\n", child); 419 - of_node_put(child); 415 + dev_err(chip->dev, "failed to parse 'color' of %pfw\n", child); 416 + fwnode_handle_put(child); 420 417 return ret; 421 418 } 422 419 ··· 436 433 return devm_led_classdev_multicolor_register_ext(chip->dev, &led->mcdev, init_data); 437 434 } 438 435 439 - static int ktd202x_setup_led_single(struct ktd202x *chip, struct device_node *np, 436 + static int ktd202x_setup_led_single(struct ktd202x *chip, struct fwnode_handle *fwnode, 440 437 struct ktd202x_led *led, struct led_init_data *init_data) 441 438 { 442 439 struct led_classdev *cdev; 443 440 u32 reg; 444 441 int ret; 445 442 446 - ret = of_property_read_u32(np, "reg", &reg); 443 + ret = fwnode_property_read_u32(fwnode, "reg", &reg); 447 444 if (ret != 0 || reg >= chip->num_leds) { 448 - dev_err(chip->dev, "invalid 'reg' of %pOFn\n", np); 445 + dev_err(chip->dev, "invalid 'reg' of %pfw\n", fwnode); 449 446 return -EINVAL; 450 447 } 451 448 led->index = reg; ··· 457 454 return devm_led_classdev_register_ext(chip->dev, &led->cdev, init_data); 458 455 } 459 456 460 - static int ktd202x_add_led(struct ktd202x *chip, struct device_node *np, unsigned int index) 457 + static int ktd202x_add_led(struct ktd202x *chip, struct fwnode_handle *fwnode, unsigned int index) 461 458 { 462 459 struct ktd202x_led *led = &chip->leds[index]; 463 460 struct led_init_data init_data = {}; ··· 466 463 int ret; 467 464 468 465 /* Color property is optional in single color case */ 469 - ret = of_property_read_u32(np, "color", &color); 466 + ret = fwnode_property_read_u32(fwnode, "color", &color); 470 467 if (ret < 0 && ret != -EINVAL) { 471 - dev_err(chip->dev, "failed to parse 'color' of %pOF\n", np); 468 + dev_err(chip->dev, "failed to parse 'color' of %pfw\n", fwnode); 472 469 return ret; 473 470 } 474 471 475 472 led->chip = chip; 476 - init_data.fwnode = of_fwnode_handle(np); 473 + init_data.fwnode = fwnode; 477 474 478 475 if (color == LED_COLOR_ID_RGB) { 479 476 cdev = &led->mcdev.led_cdev; 480 - ret = ktd202x_setup_led_rgb(chip, np, led, &init_data); 477 + ret = ktd202x_setup_led_rgb(chip, fwnode, led, &init_data); 481 478 } else { 482 479 cdev = &led->cdev; 483 - ret = ktd202x_setup_led_single(chip, np, led, &init_data); 480 + ret = ktd202x_setup_led_single(chip, fwnode, led, &init_data); 484 481 } 485 482 486 483 if (ret) { ··· 493 490 return 0; 494 491 } 495 492 496 - static int ktd202x_probe_dt(struct ktd202x *chip) 493 + static int ktd202x_probe_fw(struct ktd202x *chip) 497 494 { 498 - struct device_node *np = dev_of_node(chip->dev), *child; 495 + struct fwnode_handle *child; 496 + struct device *dev = chip->dev; 499 497 int count; 500 498 int i = 0; 501 499 502 - chip->num_leds = (int)(unsigned long)of_device_get_match_data(chip->dev); 503 - 504 - count = of_get_available_child_count(np); 500 + count = device_get_child_node_count(dev); 505 501 if (!count || count > chip->num_leds) 506 502 return -EINVAL; 507 503 ··· 509 507 /* Allow the device to execute the complete reset */ 510 508 usleep_range(200, 300); 511 509 512 - for_each_available_child_of_node(np, child) { 510 + device_for_each_child_node(dev, child) { 513 511 int ret = ktd202x_add_led(chip, child, i); 514 512 515 513 if (ret) { 516 - of_node_put(child); 514 + fwnode_handle_put(child); 517 515 return ret; 518 516 } 519 517 i++; ··· 556 554 return ret; 557 555 } 558 556 557 + ret = devm_mutex_init(dev, &chip->mutex); 558 + if (ret) 559 + return ret; 560 + 561 + chip->num_leds = (unsigned long)i2c_get_match_data(client); 562 + 559 563 chip->regulators[0].supply = "vin"; 560 564 chip->regulators[1].supply = "vio"; 561 565 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators); ··· 576 568 return ret; 577 569 } 578 570 579 - ret = ktd202x_probe_dt(chip); 571 + ret = ktd202x_probe_fw(chip); 580 572 if (ret < 0) { 581 573 regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators); 582 574 return ret; ··· 588 580 return ret; 589 581 } 590 582 591 - mutex_init(&chip->mutex); 592 - 593 583 return 0; 594 584 } 595 585 ··· 596 590 struct ktd202x *chip = i2c_get_clientdata(client); 597 591 598 592 ktd202x_chip_disable(chip); 599 - 600 - mutex_destroy(&chip->mutex); 601 593 } 602 594 603 595 static void ktd202x_shutdown(struct i2c_client *client) ··· 606 602 regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_RSTR_RESET); 607 603 } 608 604 605 + static const struct i2c_device_id ktd202x_id[] = { 606 + {"ktd2026", KTD2026_NUM_LEDS}, 607 + {"ktd2027", KTD2027_NUM_LEDS}, 608 + {} 609 + }; 610 + MODULE_DEVICE_TABLE(i2c, ktd202x_id); 611 + 609 612 static const struct of_device_id ktd202x_match_table[] = { 610 613 { .compatible = "kinetic,ktd2026", .data = (void *)KTD2026_NUM_LEDS }, 611 614 { .compatible = "kinetic,ktd2027", .data = (void *)KTD2027_NUM_LEDS }, 612 - {}, 615 + {} 613 616 }; 614 617 MODULE_DEVICE_TABLE(of, ktd202x_match_table); 615 618 ··· 628 617 .probe = ktd202x_probe, 629 618 .remove = ktd202x_remove, 630 619 .shutdown = ktd202x_shutdown, 620 + .id_table = ktd202x_id, 631 621 }; 632 622 module_i2c_driver(ktd202x_driver); 633 623
+8 -8
drivers/leds/rgb/leds-ncp5623.c
··· 183 183 184 184 fwnode_for_each_available_child_node(mc_node, led_node) { 185 185 ret = fwnode_property_read_u32(led_node, "color", &color_index); 186 - if (ret) { 187 - fwnode_handle_put(led_node); 188 - goto release_mc_node; 189 - } 186 + if (ret) 187 + goto release_led_node; 190 188 191 189 ret = fwnode_property_read_u32(led_node, "reg", &reg); 192 - if (ret) { 193 - fwnode_handle_put(led_node); 194 - goto release_mc_node; 195 - } 190 + if (ret) 191 + goto release_led_node; 196 192 197 193 subled_info[ncp->mc_dev.num_colors].channel = reg; 198 194 subled_info[ncp->mc_dev.num_colors++].color_index = color_index; ··· 219 223 fwnode_handle_put(mc_node); 220 224 221 225 return ret; 226 + 227 + release_led_node: 228 + fwnode_handle_put(led_node); 229 + goto release_mc_node; 222 230 } 223 231 224 232 static void ncp5623_remove(struct i2c_client *client)
+7 -1
drivers/leds/rgb/leds-qcom-lpg.c
··· 2 2 /* 3 3 * Copyright (c) 2017-2022 Linaro Ltd 4 4 * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. 5 - * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. 6 6 */ 7 7 #include <linux/bits.h> 8 8 #include <linux/bitfield.h> ··· 254 254 u8 val = 0; 255 255 int rc; 256 256 257 + if (!lpg->lpg_chan_sdam) 258 + return 0; 259 + 257 260 lpg->pbs_en_bitmap &= (~lut_mask); 258 261 if (!lpg->pbs_en_bitmap) { 259 262 rc = nvmem_device_write(lpg->lpg_chan_sdam, SDAM_REG_PBS_SEQ_EN, 1, &val); ··· 278 275 { 279 276 u8 val = PBS_SW_TRIG_BIT; 280 277 int rc; 278 + 279 + if (!lpg->lpg_chan_sdam) 280 + return 0; 281 281 282 282 if (!lpg->pbs_en_bitmap) { 283 283 rc = nvmem_device_write(lpg->lpg_chan_sdam, SDAM_REG_PBS_SEQ_EN, 1, &val);
+1
drivers/leds/simple/simatic-ipc-leds-gpio-apollolake.c
··· 60 60 }; 61 61 module_platform_driver(simatic_ipc_led_gpio_apollolake_driver); 62 62 63 + MODULE_DESCRIPTION("LED driver for Siemens Simatic IPCs based on Intel Apollo Lake GPIO"); 63 64 MODULE_LICENSE("GPL v2"); 64 65 MODULE_ALIAS("platform:" KBUILD_MODNAME); 65 66 MODULE_SOFTDEP("pre: simatic-ipc-leds-gpio-core platform:apollolake-pinctrl");
+1
drivers/leds/simple/simatic-ipc-leds-gpio-core.c
··· 102 102 } 103 103 EXPORT_SYMBOL_GPL(simatic_ipc_leds_gpio_probe); 104 104 105 + MODULE_DESCRIPTION("Siemens SIMATIC IPC core driver for GPIO based LEDs"); 105 106 MODULE_LICENSE("GPL v2"); 106 107 MODULE_SOFTDEP("pre: platform:leds-gpio"); 107 108 MODULE_AUTHOR("Henning Schild <henning.schild@siemens.com>");
+1
drivers/leds/simple/simatic-ipc-leds-gpio-elkhartlake.c
··· 50 50 }; 51 51 module_platform_driver(simatic_ipc_led_gpio_elkhartlake_driver); 52 52 53 + MODULE_DESCRIPTION("LED driver for Siemens Simatic IPCs based on Intel Elkhart Lake GPIO"); 53 54 MODULE_LICENSE("GPL v2"); 54 55 MODULE_ALIAS("platform:" KBUILD_MODNAME); 55 56 MODULE_SOFTDEP("pre: simatic-ipc-leds-gpio-core platform:elkhartlake-pinctrl");
+1
drivers/leds/simple/simatic-ipc-leds-gpio-f7188x.c
··· 100 100 }; 101 101 module_platform_driver(simatic_ipc_led_gpio_driver); 102 102 103 + MODULE_DESCRIPTION("LED driver for Siemens Simatic IPCs based on Nuvoton GPIO"); 103 104 MODULE_LICENSE("GPL v2"); 104 105 MODULE_ALIAS("platform:" KBUILD_MODNAME); 105 106 MODULE_SOFTDEP("pre: simatic-ipc-leds-gpio-core gpio_f7188x");
+1
drivers/leds/simple/simatic-ipc-leds.c
··· 128 128 }; 129 129 module_platform_driver(simatic_ipc_led_driver); 130 130 131 + MODULE_DESCRIPTION("LED driver for Siemens Simatic IPCs"); 131 132 MODULE_LICENSE("GPL v2"); 132 133 MODULE_ALIAS("platform:" KBUILD_MODNAME); 133 134 MODULE_AUTHOR("Henning Schild <henning.schild@siemens.com>");
+16
drivers/leds/trigger/Kconfig
··· 145 145 146 146 When build as a module this driver will be called ledtrig-tty. 147 147 148 + config LEDS_TRIGGER_INPUT_EVENTS 149 + tristate "LED Input events trigger" 150 + depends on INPUT 151 + help 152 + Turn LEDs on when there is input (/dev/input/event*) activity and turn 153 + them back off again after there has been no activity for 5 seconds. 154 + 155 + This is primarily intended to control LEDs which are a backlight for 156 + capacitive touch-buttons, such as e.g. the menu / home / back buttons 157 + found on the bottom bezel of many older smartphones and tablets. 158 + 159 + This can also be used to turn on the keyboard backlight LED on 160 + input events and turn the keyboard backlight off again when idle. 161 + 162 + When build as a module this driver will be called ledtrig-input-events. 163 + 148 164 endif # LEDS_TRIGGERS
+1
drivers/leds/trigger/Makefile
··· 15 15 obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o 16 16 obj-$(CONFIG_LEDS_TRIGGER_PATTERN) += ledtrig-pattern.o 17 17 obj-$(CONFIG_LEDS_TRIGGER_TTY) += ledtrig-tty.o 18 + obj-$(CONFIG_LEDS_TRIGGER_INPUT_EVENTS) += ledtrig-input-events.o
+165
drivers/leds/trigger/ledtrig-input-events.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Input Events LED trigger 4 + * 5 + * Copyright (C) 2024 Hans de Goede <hansg@kernel.org> 6 + */ 7 + 8 + #include <linux/input.h> 9 + #include <linux/jiffies.h> 10 + #include <linux/leds.h> 11 + #include <linux/module.h> 12 + #include <linux/moduleparam.h> 13 + #include <linux/slab.h> 14 + #include <linux/spinlock.h> 15 + #include <linux/workqueue.h> 16 + #include "../leds.h" 17 + 18 + static unsigned long led_off_delay_ms = 5000; 19 + module_param(led_off_delay_ms, ulong, 0644); 20 + MODULE_PARM_DESC(led_off_delay_ms, 21 + "Specify delay in ms for turning LEDs off after last input event"); 22 + 23 + static struct input_events_data { 24 + struct delayed_work work; 25 + spinlock_t lock; 26 + /* To avoid repeatedly setting the brightness while there are events */ 27 + bool led_on; 28 + unsigned long led_off_time; 29 + } input_events_data; 30 + 31 + static struct led_trigger *input_events_led_trigger; 32 + 33 + static void led_input_events_work(struct work_struct *work) 34 + { 35 + struct input_events_data *data = 36 + container_of(work, struct input_events_data, work.work); 37 + 38 + spin_lock_irq(&data->lock); 39 + 40 + /* 41 + * This time_after_eq() check avoids a race where this work starts 42 + * running before a new event pushed led_off_time back. 43 + */ 44 + if (time_after_eq(jiffies, data->led_off_time)) { 45 + led_trigger_event(input_events_led_trigger, LED_OFF); 46 + data->led_on = false; 47 + } 48 + 49 + spin_unlock_irq(&data->lock); 50 + } 51 + 52 + static void input_events_event(struct input_handle *handle, unsigned int type, 53 + unsigned int code, int val) 54 + { 55 + struct input_events_data *data = &input_events_data; 56 + unsigned long led_off_delay = msecs_to_jiffies(led_off_delay_ms); 57 + unsigned long flags; 58 + 59 + spin_lock_irqsave(&data->lock, flags); 60 + 61 + if (!data->led_on) { 62 + led_trigger_event(input_events_led_trigger, LED_FULL); 63 + data->led_on = true; 64 + } 65 + data->led_off_time = jiffies + led_off_delay; 66 + 67 + spin_unlock_irqrestore(&data->lock, flags); 68 + 69 + mod_delayed_work(system_wq, &data->work, led_off_delay); 70 + } 71 + 72 + static int input_events_connect(struct input_handler *handler, struct input_dev *dev, 73 + const struct input_device_id *id) 74 + { 75 + struct input_handle *handle; 76 + int ret; 77 + 78 + handle = kzalloc(sizeof(*handle), GFP_KERNEL); 79 + if (!handle) 80 + return -ENOMEM; 81 + 82 + handle->dev = dev; 83 + handle->handler = handler; 84 + handle->name = KBUILD_MODNAME; 85 + 86 + ret = input_register_handle(handle); 87 + if (ret) 88 + goto err_free_handle; 89 + 90 + ret = input_open_device(handle); 91 + if (ret) 92 + goto err_unregister_handle; 93 + 94 + return 0; 95 + 96 + err_unregister_handle: 97 + input_unregister_handle(handle); 98 + err_free_handle: 99 + kfree(handle); 100 + return ret; 101 + } 102 + 103 + static void input_events_disconnect(struct input_handle *handle) 104 + { 105 + input_close_device(handle); 106 + input_unregister_handle(handle); 107 + kfree(handle); 108 + } 109 + 110 + static const struct input_device_id input_events_ids[] = { 111 + { 112 + .flags = INPUT_DEVICE_ID_MATCH_EVBIT, 113 + .evbit = { BIT_MASK(EV_KEY) }, 114 + }, 115 + { 116 + .flags = INPUT_DEVICE_ID_MATCH_EVBIT, 117 + .evbit = { BIT_MASK(EV_REL) }, 118 + }, 119 + { 120 + .flags = INPUT_DEVICE_ID_MATCH_EVBIT, 121 + .evbit = { BIT_MASK(EV_ABS) }, 122 + }, 123 + { } 124 + }; 125 + 126 + static struct input_handler input_events_handler = { 127 + .name = KBUILD_MODNAME, 128 + .event = input_events_event, 129 + .connect = input_events_connect, 130 + .disconnect = input_events_disconnect, 131 + .id_table = input_events_ids, 132 + }; 133 + 134 + static int __init input_events_init(void) 135 + { 136 + int ret; 137 + 138 + INIT_DELAYED_WORK(&input_events_data.work, led_input_events_work); 139 + spin_lock_init(&input_events_data.lock); 140 + 141 + led_trigger_register_simple("input-events", &input_events_led_trigger); 142 + 143 + ret = input_register_handler(&input_events_handler); 144 + if (ret) { 145 + led_trigger_unregister_simple(input_events_led_trigger); 146 + return ret; 147 + } 148 + 149 + return 0; 150 + } 151 + 152 + static void __exit input_events_exit(void) 153 + { 154 + input_unregister_handler(&input_events_handler); 155 + cancel_delayed_work_sync(&input_events_data.work); 156 + led_trigger_unregister_simple(input_events_led_trigger); 157 + } 158 + 159 + module_init(input_events_init); 160 + module_exit(input_events_exit); 161 + 162 + MODULE_AUTHOR("Hans de Goede <hansg@kernel.org>"); 163 + MODULE_DESCRIPTION("Input Events LED trigger"); 164 + MODULE_LICENSE("GPL"); 165 + MODULE_ALIAS("ledtrig:input-events");
-5
drivers/leds/trigger/ledtrig-timer.c
··· 110 110 led_cdev->flags &= ~LED_INIT_DEFAULT_TRIGGER; 111 111 } 112 112 113 - /* 114 - * If "set brightness to 0" is pending in workqueue, we don't 115 - * want that to be reordered after blink_set() 116 - */ 117 - flush_work(&led_cdev->set_brightness_work); 118 113 led_blink_set(led_cdev, &led_cdev->blink_delay_on, 119 114 &led_cdev->blink_delay_off); 120 115
+23
drivers/power/supply/power_supply_leds.c
··· 22 22 static void power_supply_update_bat_leds(struct power_supply *psy) 23 23 { 24 24 union power_supply_propval status; 25 + unsigned int intensity_green[3] = { 0, 255, 0 }; 26 + unsigned int intensity_orange[3] = { 255, 128, 0 }; 25 27 26 28 if (power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS, &status)) 27 29 return; ··· 38 36 /* Going from blink to LED on requires a LED_OFF event to stop blink */ 39 37 led_trigger_event(psy->charging_blink_full_solid_trig, LED_OFF); 40 38 led_trigger_event(psy->charging_blink_full_solid_trig, LED_FULL); 39 + led_mc_trigger_event(psy->charging_orange_full_green_trig, 40 + intensity_green, 41 + ARRAY_SIZE(intensity_green), 42 + LED_FULL); 41 43 break; 42 44 case POWER_SUPPLY_STATUS_CHARGING: 43 45 led_trigger_event(psy->charging_full_trig, LED_FULL); 44 46 led_trigger_event(psy->charging_trig, LED_FULL); 45 47 led_trigger_event(psy->full_trig, LED_OFF); 46 48 led_trigger_blink(psy->charging_blink_full_solid_trig, 0, 0); 49 + led_mc_trigger_event(psy->charging_orange_full_green_trig, 50 + intensity_orange, 51 + ARRAY_SIZE(intensity_orange), 52 + LED_FULL); 47 53 break; 48 54 default: 49 55 led_trigger_event(psy->charging_full_trig, LED_OFF); 50 56 led_trigger_event(psy->charging_trig, LED_OFF); 51 57 led_trigger_event(psy->full_trig, LED_OFF); 52 58 led_trigger_event(psy->charging_blink_full_solid_trig, 59 + LED_OFF); 60 + led_trigger_event(psy->charging_orange_full_green_trig, 53 61 LED_OFF); 54 62 break; 55 63 } ··· 86 74 if (!psy->charging_blink_full_solid_trig_name) 87 75 goto charging_blink_full_solid_failed; 88 76 77 + psy->charging_orange_full_green_trig_name = kasprintf(GFP_KERNEL, 78 + "%s-charging-orange-full-green", psy->desc->name); 79 + if (!psy->charging_orange_full_green_trig_name) 80 + goto charging_red_full_green_failed; 81 + 89 82 led_trigger_register_simple(psy->charging_full_trig_name, 90 83 &psy->charging_full_trig); 91 84 led_trigger_register_simple(psy->charging_trig_name, ··· 99 82 &psy->full_trig); 100 83 led_trigger_register_simple(psy->charging_blink_full_solid_trig_name, 101 84 &psy->charging_blink_full_solid_trig); 85 + led_trigger_register_simple(psy->charging_orange_full_green_trig_name, 86 + &psy->charging_orange_full_green_trig); 102 87 103 88 return 0; 104 89 90 + charging_red_full_green_failed: 91 + kfree(psy->charging_blink_full_solid_trig_name); 105 92 charging_blink_full_solid_failed: 106 93 kfree(psy->full_trig_name); 107 94 full_failed: ··· 122 101 led_trigger_unregister_simple(psy->charging_trig); 123 102 led_trigger_unregister_simple(psy->full_trig); 124 103 led_trigger_unregister_simple(psy->charging_blink_full_solid_trig); 104 + led_trigger_unregister_simple(psy->charging_orange_full_green_trig); 125 105 kfree(psy->charging_blink_full_solid_trig_name); 126 106 kfree(psy->full_trig_name); 127 107 kfree(psy->charging_trig_name); 128 108 kfree(psy->charging_full_trig_name); 109 + kfree(psy->charging_orange_full_green_trig_name); 129 110 } 130 111 131 112 /* Generated power specific LEDs triggers. */
+26
include/linux/leds.h
··· 108 108 #define LED_RETAIN_AT_SHUTDOWN BIT(22) 109 109 #define LED_INIT_DEFAULT_TRIGGER BIT(23) 110 110 #define LED_REJECT_NAME_CONFLICT BIT(24) 111 + #define LED_MULTI_COLOR BIT(25) 111 112 112 113 /* set_brightness_work / blink_timer flags, atomic, private. */ 113 114 unsigned long work_flags; ··· 376 375 int led_set_brightness_sync(struct led_classdev *led_cdev, unsigned int value); 377 376 378 377 /** 378 + * led_mc_set_brightness - set mc LED color intensity values and brightness 379 + * @led_cdev: the LED to set 380 + * @intensity_value: array of per color intensity values to set 381 + * @num_colors: amount of entries in intensity_value array 382 + * @brightness: the brightness to set the LED to 383 + * 384 + * Set a multi-color LED's per color intensity values and brightness. 385 + * If necessary, this cancels the software blink timer. This function is 386 + * guaranteed not to sleep. 387 + * 388 + * Calling this function on a non multi-color led_classdev or with the wrong 389 + * num_colors value is an error. In this case an error will be logged once 390 + * and the call will do nothing. 391 + */ 392 + void led_mc_set_brightness(struct led_classdev *led_cdev, 393 + unsigned int *intensity_value, unsigned int num_colors, 394 + unsigned int brightness); 395 + 396 + /** 379 397 * led_update_brightness - update LED brightness 380 398 * @led_cdev: the LED to query 381 399 * ··· 521 501 struct led_trigger **trigger); 522 502 void led_trigger_unregister_simple(struct led_trigger *trigger); 523 503 void led_trigger_event(struct led_trigger *trigger, enum led_brightness event); 504 + void led_mc_trigger_event(struct led_trigger *trig, 505 + unsigned int *intensity_value, unsigned int num_colors, 506 + enum led_brightness brightness); 524 507 void led_trigger_blink(struct led_trigger *trigger, unsigned long delay_on, 525 508 unsigned long delay_off); 526 509 void led_trigger_blink_oneshot(struct led_trigger *trigger, ··· 566 543 static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {} 567 544 static inline void led_trigger_event(struct led_trigger *trigger, 568 545 enum led_brightness event) {} 546 + static inline void led_mc_trigger_event(struct led_trigger *trig, 547 + unsigned int *intensity_value, unsigned int num_colors, 548 + enum led_brightness brightness) {} 569 549 static inline void led_trigger_blink(struct led_trigger *trigger, 570 550 unsigned long delay_on, 571 551 unsigned long delay_off) {}
+2
include/linux/power_supply.h
··· 319 319 char *online_trig_name; 320 320 struct led_trigger *charging_blink_full_solid_trig; 321 321 char *charging_blink_full_solid_trig_name; 322 + struct led_trigger *charging_orange_full_green_trig; 323 + char *charging_orange_full_green_trig_name; 322 324 #endif 323 325 }; 324 326