Lee Jones offered his help with maintaining LEDs, thanks a
lot. Plus, there are some bugfixes as a bonus. -----BEGIN PGP SIGNATURE----- iF0EABECAB0WIQRPfPO7r0eAhk010v0w5/Bqldv68gUCY5xICAAKCRAw5/Bqldv6 8nkhAJ9lqVnS7+m2eq5w1gQlgd2ToktRaQCfcj7WPznJCe3dPVpwSsWxa//B1Rw= =B8QS -----END PGP SIGNATURE----- Merge tag 'leds-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds Pull LED updates from Pavel Machek: "Lee Jones offered his help with maintaining LEDs, thanks a lot. Plus, there are some bugfixes as a bonus" * tag 'leds-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds: leds: MAINTAINERS: include dt-bindings headers leds: qcom,pm8058-led: Convert to DT schema leds: use sysfs_emit() to instead of scnprintf() leds: is31fl319x: Fix setting current limit for is31fl319{0,1,3} MAINTAINERS: Add additional co-maintainer to LEDs leds: lp5523: fix out-of-bounds bug in lp5523_selftest() dt-bindings: leds: Add 'cpuX' to 'linux,default-trigger' led: qcom-lpg: Fix sleeping in atomic leds: max8997: Don't error if there is no pdata leds: lp55xx: remove variable j leds-pca955x: Remove the unused function pca95xx_num_led_regs()
This commit is contained in:
commit
75caf59408
|
@ -100,6 +100,7 @@ properties:
|
|||
- pattern
|
||||
# LED is triggered by SD/MMC activity
|
||||
- pattern: "^mmc[0-9]+$"
|
||||
- pattern: "^cpu[0-9]*$"
|
||||
|
||||
led-pattern:
|
||||
description: |
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
Qualcomm PM8058 LED driver
|
||||
|
||||
The Qualcomm PM8058 is a multi-functional device which contains
|
||||
an LED driver block for up to six LEDs: three normal LEDs, two
|
||||
"flash" LEDs and one "keypad backlight" LED. The names are
|
||||
quoted because sometimes these LED drivers are used for wildly
|
||||
different things than flash or keypad backlight: their names
|
||||
are more of a suggestion than a hard-wired usecase.
|
||||
|
||||
Hardware-wise the different LEDs support slightly different
|
||||
output currents. The "flash" LEDs do not need to charge nor
|
||||
do they support external triggers. They are just powerful LED
|
||||
drivers.
|
||||
|
||||
The LEDs appear as children to the PM8058 device, with the
|
||||
proper compatible string. For the PM8058 bindings see:
|
||||
mfd/qcom-pm8xxx.txt.
|
||||
|
||||
Each LED is represented as a sub-node of the syscon device. Each
|
||||
node's name represents the name of the corresponding LED.
|
||||
|
||||
LED sub-node properties:
|
||||
|
||||
Required properties:
|
||||
- compatible: one of
|
||||
"qcom,pm8058-led" (for the normal LEDs at 0x131, 0x132 and 0x133)
|
||||
"qcom,pm8058-keypad-led" (for the "keypad" LED at 0x48)
|
||||
"qcom,pm8058-flash-led" (for the "flash" LEDs at 0x49 and 0xFB)
|
||||
|
||||
Optional properties:
|
||||
- label: see Documentation/devicetree/bindings/leds/common.txt
|
||||
- default-state: see Documentation/devicetree/bindings/leds/common.txt
|
||||
- linux,default-trigger: see Documentation/devicetree/bindings/leds/common.txt
|
||||
|
||||
Example:
|
||||
|
||||
qcom,ssbi@500000 {
|
||||
pmicintc: pmic@0 {
|
||||
compatible = "qcom,pm8058";
|
||||
led@48 {
|
||||
compatible = "qcom,pm8058-keypad-led";
|
||||
reg = <0x48>;
|
||||
label = "pm8050:white:keypad";
|
||||
default-state = "off";
|
||||
};
|
||||
led@131 {
|
||||
compatible = "qcom,pm8058-led";
|
||||
reg = <0x131>;
|
||||
label = "pm8058:red";
|
||||
default-state = "off";
|
||||
};
|
||||
led@132 {
|
||||
compatible = "qcom,pm8058-led";
|
||||
reg = <0x132>;
|
||||
label = "pm8058:yellow";
|
||||
default-state = "off";
|
||||
linux,default-trigger = "mmc0";
|
||||
};
|
||||
led@133 {
|
||||
compatible = "qcom,pm8058-led";
|
||||
reg = <0x133>;
|
||||
label = "pm8058:green";
|
||||
default-state = "on";
|
||||
linux,default-trigger = "heartbeat";
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,57 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/leds/qcom,pm8058-led.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm PM8058 PMIC LED
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
|
||||
description: |
|
||||
The Qualcomm PM8058 contains an LED block for up to six LEDs:: three normal
|
||||
LEDs, two "flash" LEDs and one "keypad backlight" LED. The names are quoted
|
||||
because sometimes these LED drivers are used for wildly different things than
|
||||
flash or keypad backlight:: their names are more of a suggestion than a
|
||||
hard-wired usecase.
|
||||
|
||||
Hardware-wise the different LEDs support slightly different output currents.
|
||||
The "flash" LEDs do not need to charge nor do they support external triggers.
|
||||
They are just powerful LED drivers.
|
||||
|
||||
allOf:
|
||||
- $ref: common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,pm8058-led
|
||||
- qcom,pm8058-keypad-led
|
||||
- qcom,pm8058-flash-led
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
pmic {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@131 {
|
||||
compatible = "qcom,pm8058-led";
|
||||
reg = <0x131>;
|
||||
label = "pm8058:red";
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
|
@ -39,6 +39,10 @@ properties:
|
|||
interrupt-controller: true
|
||||
|
||||
patternProperties:
|
||||
"led@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/leds/qcom,pm8058-led.yaml#
|
||||
|
||||
"rtc@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: "../rtc/qcom-pm8xxx-rtc.yaml"
|
||||
|
|
|
@ -11732,11 +11732,13 @@ F: scripts/leaking_addresses.pl
|
|||
|
||||
LED SUBSYSTEM
|
||||
M: Pavel Machek <pavel@ucw.cz>
|
||||
M: Lee Jones <lee@kernel.org>
|
||||
L: linux-leds@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git
|
||||
F: Documentation/devicetree/bindings/leds/
|
||||
F: drivers/leds/
|
||||
F: include/dt-bindings/leds/
|
||||
F: include/linux/leds.h
|
||||
|
||||
LEGACY EEPROM DRIVER
|
||||
|
|
|
@ -139,11 +139,11 @@ static ssize_t show_color_common(struct device *dev, char *buf, int color)
|
|||
return ret;
|
||||
switch (color) {
|
||||
case RED:
|
||||
return scnprintf(buf, PAGE_SIZE, "%02X\n", data->red);
|
||||
return sysfs_emit(buf, "%02X\n", data->red);
|
||||
case GREEN:
|
||||
return scnprintf(buf, PAGE_SIZE, "%02X\n", data->green);
|
||||
return sysfs_emit(buf, "%02X\n", data->green);
|
||||
case BLUE:
|
||||
return scnprintf(buf, PAGE_SIZE, "%02X\n", data->blue);
|
||||
return sysfs_emit(buf, "%02X\n", data->blue);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ static DEVICE_ATTR_RW(blue);
|
|||
static ssize_t test_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE,
|
||||
return sysfs_emit(buf,
|
||||
"#Write into test to start test sequence!#\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#define IS31FL3190_CURRENT_uA_MIN 5000
|
||||
#define IS31FL3190_CURRENT_uA_DEFAULT 42000
|
||||
#define IS31FL3190_CURRENT_uA_MAX 42000
|
||||
#define IS31FL3190_CURRENT_SHIFT 2
|
||||
#define IS31FL3190_CURRENT_MASK GENMASK(4, 2)
|
||||
#define IS31FL3190_CURRENT_5_mA 0x02
|
||||
#define IS31FL3190_CURRENT_10_mA 0x01
|
||||
|
@ -553,7 +554,7 @@ static int is31fl319x_probe(struct i2c_client *client)
|
|||
is31fl3196_db_to_gain(is31->audio_gain_db));
|
||||
else
|
||||
regmap_update_bits(is31->regmap, IS31FL3190_CURRENT, IS31FL3190_CURRENT_MASK,
|
||||
is31fl3190_microamp_to_cs(dev, aggregated_led_microamp));
|
||||
is31fl3190_microamp_to_cs(dev, aggregated_led_microamp) << IS31FL3190_CURRENT_SHIFT);
|
||||
|
||||
for (i = 0; i < is31->cdef->num_leds; i++) {
|
||||
struct is31fl319x_led *led = &is31->leds[i];
|
||||
|
|
|
@ -314,7 +314,7 @@ static ssize_t show_id(struct device *dev,
|
|||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
struct lm3533_led *led = to_lm3533_led(led_cdev);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", led->id);
|
||||
return sysfs_emit(buf, "%d\n", led->id);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -344,7 +344,7 @@ static ssize_t show_risefalltime(struct device *dev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%x\n", val);
|
||||
return sysfs_emit(buf, "%x\n", val);
|
||||
}
|
||||
|
||||
static ssize_t show_risetime(struct device *dev,
|
||||
|
@ -415,7 +415,7 @@ static ssize_t show_als_channel(struct device *dev,
|
|||
|
||||
channel = (val & LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK) + 1;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%u\n", channel);
|
||||
return sysfs_emit(buf, "%u\n", channel);
|
||||
}
|
||||
|
||||
static ssize_t store_als_channel(struct device *dev,
|
||||
|
@ -465,7 +465,7 @@ static ssize_t show_als_en(struct device *dev,
|
|||
|
||||
enable = val & LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", enable);
|
||||
return sysfs_emit(buf, "%d\n", enable);
|
||||
}
|
||||
|
||||
static ssize_t store_als_en(struct device *dev,
|
||||
|
@ -518,7 +518,7 @@ static ssize_t show_linear(struct device *dev,
|
|||
else
|
||||
linear = 0;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%x\n", linear);
|
||||
return sysfs_emit(buf, "%x\n", linear);
|
||||
}
|
||||
|
||||
static ssize_t store_linear(struct device *dev,
|
||||
|
@ -564,7 +564,7 @@ static ssize_t show_pwm(struct device *dev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%u\n", val);
|
||||
return sysfs_emit(buf, "%u\n", val);
|
||||
}
|
||||
|
||||
static ssize_t store_pwm(struct device *dev,
|
||||
|
|
|
@ -469,7 +469,7 @@ static ssize_t lp5521_selftest(struct device *dev,
|
|||
ret = lp5521_run_selftest(chip, buf);
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%s\n", ret ? "FAIL" : "OK");
|
||||
return sysfs_emit(buf, "%s\n", ret ? "FAIL" : "OK");
|
||||
}
|
||||
|
||||
/* device attributes */
|
||||
|
|
|
@ -581,8 +581,8 @@ static ssize_t lp5523_selftest(struct device *dev,
|
|||
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
|
||||
struct lp55xx_chip *chip = led->chip;
|
||||
struct lp55xx_platform_data *pdata = chip->pdata;
|
||||
int i, ret, pos = 0;
|
||||
u8 status, adc, vdd;
|
||||
int ret, pos = 0;
|
||||
u8 status, adc, vdd, i;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
|
@ -612,20 +612,21 @@ static ssize_t lp5523_selftest(struct device *dev,
|
|||
|
||||
vdd--; /* There may be some fluctuation in measurement */
|
||||
|
||||
for (i = 0; i < LP5523_MAX_LEDS; i++) {
|
||||
/* Skip non-existing channels */
|
||||
for (i = 0; i < pdata->num_channels; i++) {
|
||||
/* Skip disabled channels */
|
||||
if (pdata->led_config[i].led_current == 0)
|
||||
continue;
|
||||
|
||||
/* Set default current */
|
||||
lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i,
|
||||
lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + led->chan_nr,
|
||||
pdata->led_config[i].led_current);
|
||||
|
||||
lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0xff);
|
||||
lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr,
|
||||
0xff);
|
||||
/* let current stabilize 2 - 4ms before measurements start */
|
||||
usleep_range(2000, 4000);
|
||||
lp55xx_write(chip, LP5523_REG_LED_TEST_CTRL,
|
||||
LP5523_EN_LEDTEST | i);
|
||||
LP5523_EN_LEDTEST | led->chan_nr);
|
||||
/* ADC conversion time is 2.7 ms typically */
|
||||
usleep_range(3000, 6000);
|
||||
ret = lp55xx_read(chip, LP5523_REG_STATUS, &status);
|
||||
|
@ -633,20 +634,22 @@ static ssize_t lp5523_selftest(struct device *dev,
|
|||
goto fail;
|
||||
|
||||
if (!(status & LP5523_LEDTEST_DONE))
|
||||
usleep_range(3000, 6000);/* Was not ready. Wait. */
|
||||
usleep_range(3000, 6000); /* Was not ready. Wait. */
|
||||
|
||||
ret = lp55xx_read(chip, LP5523_REG_LED_TEST_ADC, &adc);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM)
|
||||
pos += sprintf(buf + pos, "LED %d FAIL\n", i);
|
||||
pos += sprintf(buf + pos, "LED %d FAIL\n",
|
||||
led->chan_nr);
|
||||
|
||||
lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0x00);
|
||||
lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr,
|
||||
0x00);
|
||||
|
||||
/* Restore current */
|
||||
lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i,
|
||||
led->led_current);
|
||||
lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + led->chan_nr,
|
||||
led->led_current);
|
||||
led++;
|
||||
}
|
||||
if (pos == 0)
|
||||
|
|
|
@ -88,7 +88,7 @@ static ssize_t led_current_show(struct device *dev,
|
|||
{
|
||||
struct lp55xx_led *led = dev_to_lp55xx_led(dev);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", led->led_current);
|
||||
return sysfs_emit(buf, "%d\n", led->led_current);
|
||||
}
|
||||
|
||||
static ssize_t led_current_store(struct device *dev,
|
||||
|
@ -121,7 +121,7 @@ static ssize_t max_current_show(struct device *dev,
|
|||
{
|
||||
struct lp55xx_led *led = dev_to_lp55xx_led(dev);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", led->max_current);
|
||||
return sysfs_emit(buf, "%d\n", led->max_current);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(led_current);
|
||||
|
@ -166,7 +166,7 @@ static int lp55xx_init_led(struct lp55xx_led *led,
|
|||
struct mc_subled *mc_led_info;
|
||||
struct led_classdev *led_cdev;
|
||||
char name[32];
|
||||
int i, j = 0;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (chan >= max_channel) {
|
||||
|
@ -201,7 +201,6 @@ static int lp55xx_init_led(struct lp55xx_led *led,
|
|||
pdata->led_config[chan].color_id[i];
|
||||
mc_led_info[i].channel =
|
||||
pdata->led_config[chan].output_num[i];
|
||||
j++;
|
||||
}
|
||||
|
||||
led->mc_cdev.subled_info = mc_led_info;
|
||||
|
|
|
@ -238,11 +238,6 @@ static int max8997_led_probe(struct platform_device *pdev)
|
|||
char name[20];
|
||||
int ret = 0;
|
||||
|
||||
if (pdata == NULL) {
|
||||
dev_err(&pdev->dev, "no platform data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
|
||||
if (led == NULL)
|
||||
return -ENOMEM;
|
||||
|
@ -258,7 +253,7 @@ static int max8997_led_probe(struct platform_device *pdev)
|
|||
led->iodev = iodev;
|
||||
|
||||
/* initialize mode and brightness according to platform_data */
|
||||
if (pdata->led_pdata) {
|
||||
if (pdata && pdata->led_pdata) {
|
||||
u8 mode = 0, brightness = 0;
|
||||
|
||||
mode = pdata->led_pdata->mode[led->id];
|
||||
|
|
|
@ -145,12 +145,6 @@ static inline int pca95xx_num_input_regs(int bits)
|
|||
return (bits + 7) / 8;
|
||||
}
|
||||
|
||||
/* 4 bits per LED selector register */
|
||||
static inline int pca95xx_num_led_regs(int bits)
|
||||
{
|
||||
return (bits + 3) / 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return an LED selector register value based on an existing one, with
|
||||
* the appropriate 2-bit state value set for the given LED number (0-3).
|
||||
|
|
|
@ -602,8 +602,8 @@ static void lpg_brightness_set(struct lpg_led *led, struct led_classdev *cdev,
|
|||
lpg_lut_sync(lpg, lut_mask);
|
||||
}
|
||||
|
||||
static void lpg_brightness_single_set(struct led_classdev *cdev,
|
||||
enum led_brightness value)
|
||||
static int lpg_brightness_single_set(struct led_classdev *cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
struct lpg_led *led = container_of(cdev, struct lpg_led, cdev);
|
||||
struct mc_subled info;
|
||||
|
@ -614,10 +614,12 @@ static void lpg_brightness_single_set(struct led_classdev *cdev,
|
|||
lpg_brightness_set(led, cdev, &info);
|
||||
|
||||
mutex_unlock(&led->lpg->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lpg_brightness_mc_set(struct led_classdev *cdev,
|
||||
enum led_brightness value)
|
||||
static int lpg_brightness_mc_set(struct led_classdev *cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
|
||||
struct lpg_led *led = container_of(mc, struct lpg_led, mcdev);
|
||||
|
@ -628,6 +630,8 @@ static void lpg_brightness_mc_set(struct led_classdev *cdev,
|
|||
lpg_brightness_set(led, cdev, mc->subled_info);
|
||||
|
||||
mutex_unlock(&led->lpg->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lpg_blink_set(struct lpg_led *led,
|
||||
|
@ -1118,7 +1122,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
|
|||
led->mcdev.num_colors = num_channels;
|
||||
|
||||
cdev = &led->mcdev.led_cdev;
|
||||
cdev->brightness_set = lpg_brightness_mc_set;
|
||||
cdev->brightness_set_blocking = lpg_brightness_mc_set;
|
||||
cdev->blink_set = lpg_blink_mc_set;
|
||||
|
||||
/* Register pattern accessors only if we have a LUT block */
|
||||
|
@ -1132,7 +1136,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
|
|||
return ret;
|
||||
|
||||
cdev = &led->cdev;
|
||||
cdev->brightness_set = lpg_brightness_single_set;
|
||||
cdev->brightness_set_blocking = lpg_brightness_single_set;
|
||||
cdev->blink_set = lpg_blink_single_set;
|
||||
|
||||
/* Register pattern accessors only if we have a LUT block */
|
||||
|
@ -1151,7 +1155,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
|
|||
else
|
||||
cdev->brightness = LED_OFF;
|
||||
|
||||
cdev->brightness_set(cdev, cdev->brightness);
|
||||
cdev->brightness_set_blocking(cdev, cdev->brightness);
|
||||
|
||||
init_data.fwnode = of_fwnode_handle(np);
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ static ssize_t repeat_show(struct device *dev, struct device_attribute *attr,
|
|||
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", repeat);
|
||||
return sysfs_emit(buf, "%d\n", repeat);
|
||||
}
|
||||
|
||||
static ssize_t repeat_store(struct device *dev, struct device_attribute *attr,
|
||||
|
|
Loading…
Reference in New Issue