mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'leds-next-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds
Pull LED updates from Lee Jones:
"Core Frameworks:
- Ensure seldom updated triggers have a brightness value before first
update
New Device Support:
- Add support for Simatic IPC Device BX_59A to IPC LEDs Core
- Add support for Qualcomm PMI8950 PWM to LPG Core
New Functionality:
- Add a bunch of new LED function identifiers
- Add support for High Resolution Timers in LED Trigger Patten
Fix-ups:
- Shift out Audio Trigger to the Sound subsystem
- Convert suitable calls to devm_* managed resources
- Device Tree binding adaptions/conversions/creation
- Remove superfluous code/variables/attributes and simplify overall
- Use/convert to new/better APIs/helpers/MACROs instead of
hand-rolling implementations
Bug Fixes:
- Repair enabling Torch Mode from V4L2 on the second LED
- Ensure PWM is disabled when suspending"
* tag 'leds-next-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds: (28 commits)
leds: mt6370: Remove unused field 'reg_cfgs' from 'struct mt6370_priv'
leds: lp50xx: Remove unused field 'num_of_banked_leds' from 'struct lp50xx'
leds: lp50xx: Remove unused field 'bank_modules' from 'struct lp50xx_led'
leds: aat1290: Remove unused field 'torch_brightness' from 'struct aat1290_led'
leds: sun50i-a100: Use match_string() helper to simplify the code
leds: pwm: Disable PWM when going to suspend
leds: trigger: pattern: Add support for hrtimer
leds: mt6360: Fix the second LED can not enable torch mode by V4L2
dt-bindings: leds: leds-qcom-lpg: Add support for PMI8950 PWM
leds: qcom-lpg: Add support for PMI8950 PWM
leds: apu: Remove duplicate DMI lookup data
leds: trigger: netdev: Remove not needed call to led_set_brightness in deactivate
dt-bindings: leds: Add LED_FUNCTION_SPEED_* for link speed on LAN/WAN
dt-bindings: leds: Add LED_FUNCTION_MOBILE for mobile network
leds: simatic-ipc-leds-gpio: Add support for module BX-59A
dt-bindings: leds: qcom-lpg: Document PM6150L compatible
dt-bindings: leds: pca963x: Convert text bindings to YAML
leds: an30259a: Use devm_mutex_init() for mutex initialization
leds: mlxreg: Use devm_mutex_init() for mutex initialization
leds: nic78bx: Use devm API to cleanup module's resources
...
This commit is contained in:
@@ -12,6 +12,16 @@ Description:
|
||||
The exact format is described in:
|
||||
Documentation/devicetree/bindings/leds/leds-trigger-pattern.txt
|
||||
|
||||
What: /sys/class/leds/<led>/hr_pattern
|
||||
Date: April 2024
|
||||
Description:
|
||||
Specify a software pattern for the LED, that supports altering
|
||||
the brightness for the specified duration with one software
|
||||
timer. It can do gradual dimming and step change of brightness.
|
||||
|
||||
Unlike the /sys/class/leds/<led>/pattern, this attribute runs
|
||||
a pattern on high-resolution timer (hrtimer).
|
||||
|
||||
What: /sys/class/leds/<led>/hw_pattern
|
||||
Date: September 2018
|
||||
KernelVersion: 4.20
|
||||
|
||||
@@ -27,9 +27,14 @@ properties:
|
||||
- qcom,pm8994-lpg
|
||||
- qcom,pmc8180c-lpg
|
||||
- qcom,pmi632-lpg
|
||||
- qcom,pmi8950-pwm
|
||||
- qcom,pmi8994-lpg
|
||||
- qcom,pmi8998-lpg
|
||||
- qcom,pmk8550-pwm
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,pm6150l-lpg
|
||||
- const: qcom,pm8150l-lpg
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,pm8550-pwm
|
||||
@@ -142,6 +147,7 @@ allOf:
|
||||
- qcom,pm8941-lpg
|
||||
- qcom,pm8994-lpg
|
||||
- qcom,pmc8180c-lpg
|
||||
- qcom,pmi8950-pwm
|
||||
- qcom,pmi8994-lpg
|
||||
- qcom,pmi8998-lpg
|
||||
- qcom,pmk8550-pwm
|
||||
@@ -290,5 +296,3 @@ examples:
|
||||
label = "blue";
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
140
Documentation/devicetree/bindings/leds/nxp,pca963x.yaml
Normal file
140
Documentation/devicetree/bindings/leds/nxp,pca963x.yaml
Normal file
@@ -0,0 +1,140 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/leds/nxp,pca963x.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP PCA963x LED controllers
|
||||
|
||||
maintainers:
|
||||
- Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
|
||||
description: |
|
||||
The NXP PCA963x are I2C-controlled LED drivers optimized for
|
||||
Red/Green/Blue/Amber (RGBA) color mixing applications. Each LED is
|
||||
individually controllable and has its own PWM controller.
|
||||
|
||||
Datasheets are available at
|
||||
|
||||
- https://www.nxp.com/docs/en/data-sheet/PCA9632.pdf
|
||||
- https://www.nxp.com/docs/en/data-sheet/PCA9633.pdf
|
||||
- https://www.nxp.com/docs/en/data-sheet/PCA9634.pdf
|
||||
- https://www.nxp.com/docs/en/data-sheet/PCA9635.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nxp,pca9632
|
||||
- nxp,pca9633
|
||||
- nxp,pca9634
|
||||
- nxp,pca9635
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
nxp,hw-blink:
|
||||
type: boolean
|
||||
description:
|
||||
Use hardware blinking instead of software blinking
|
||||
|
||||
nxp,inverted-out:
|
||||
type: boolean
|
||||
description:
|
||||
Invert the polarity of the generated PWM.
|
||||
|
||||
nxp,period-scale:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
In some configurations, the chip blinks faster than expected. This
|
||||
parameter provides a scaling ratio (fixed point, decimal divided by 1000)
|
||||
to compensate, e.g. 1300=1.3x and 750=0.75x.
|
||||
|
||||
nxp,totem-pole:
|
||||
type: boolean
|
||||
description:
|
||||
Use totem pole (push-pull) instead of open-drain (pca9632 defaults to
|
||||
open-drain, newer chips to totem pole).
|
||||
|
||||
patternProperties:
|
||||
"^led@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: common.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
reg:
|
||||
minimum: 0
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nxp,pca9632
|
||||
- nxp,pca9633
|
||||
then:
|
||||
patternProperties:
|
||||
"^led@[0-9a-f]+$":
|
||||
properties:
|
||||
reg:
|
||||
maximum: 3
|
||||
else:
|
||||
patternProperties:
|
||||
"^led@[0-9a-f]+$":
|
||||
properties:
|
||||
reg:
|
||||
maximum: 7
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led-controller@62 {
|
||||
compatible = "nxp,pca9632";
|
||||
reg = <0x62>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@0 {
|
||||
reg = <0>;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
};
|
||||
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
};
|
||||
|
||||
led@2 {
|
||||
reg = <2>;
|
||||
color = <LED_COLOR_ID_BLUE>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
};
|
||||
|
||||
led@3 {
|
||||
reg = <3>;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -1,52 +0,0 @@
|
||||
LEDs connected to pca9632, pca9633 or pca9634
|
||||
|
||||
Required properties:
|
||||
- compatible : should be : "nxp,pca9632", "nxp,pca9633", "nxp,pca9634" or "nxp,pca9635"
|
||||
|
||||
Optional properties:
|
||||
- nxp,totem-pole : use totem pole (push-pull) instead of open-drain (pca9632 defaults
|
||||
to open-drain, newer chips to totem pole)
|
||||
- nxp,hw-blink : use hardware blinking instead of software blinking
|
||||
- nxp,period-scale : In some configurations, the chip blinks faster than expected.
|
||||
This parameter provides a scaling ratio (fixed point, decimal divided
|
||||
by 1000) to compensate, e.g. 1300=1.3x and 750=0.75x.
|
||||
- nxp,inverted-out: invert the polarity of the generated PWM
|
||||
|
||||
Each led is represented as a sub-node of the nxp,pca963x device.
|
||||
|
||||
LED sub-node properties:
|
||||
- label : (optional) see Documentation/devicetree/bindings/leds/common.txt
|
||||
- reg : number of LED line (could be from 0 to 3 in pca9632 or pca9633,
|
||||
0 to 7 in pca9634, or 0 to 15 in pca9635)
|
||||
- linux,default-trigger : (optional)
|
||||
see Documentation/devicetree/bindings/leds/common.txt
|
||||
|
||||
Examples:
|
||||
|
||||
pca9632: pca9632 {
|
||||
compatible = "nxp,pca9632";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x62>;
|
||||
|
||||
red@0 {
|
||||
label = "red";
|
||||
reg = <0>;
|
||||
linux,default-trigger = "none";
|
||||
};
|
||||
green@1 {
|
||||
label = "green";
|
||||
reg = <1>;
|
||||
linux,default-trigger = "none";
|
||||
};
|
||||
blue@2 {
|
||||
label = "blue";
|
||||
reg = <2>;
|
||||
linux,default-trigger = "none";
|
||||
};
|
||||
unused@3 {
|
||||
label = "unused";
|
||||
reg = <3>;
|
||||
linux,default-trigger = "none";
|
||||
};
|
||||
};
|
||||
@@ -152,7 +152,6 @@ CONFIG_LEDS_TRIGGER_CAMERA=m
|
||||
CONFIG_LEDS_TRIGGER_PANIC=y
|
||||
CONFIG_LEDS_TRIGGER_NETDEV=y
|
||||
CONFIG_LEDS_TRIGGER_PATTERN=y
|
||||
CONFIG_LEDS_TRIGGER_AUDIO=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_JZ4740=y
|
||||
CONFIG_DMADEVICES=y
|
||||
|
||||
@@ -77,8 +77,6 @@ struct aat1290_led {
|
||||
int *mm_current_scale;
|
||||
/* device mode */
|
||||
bool movie_mode;
|
||||
/* brightness cache */
|
||||
unsigned int torch_brightness;
|
||||
};
|
||||
|
||||
static struct aat1290_led *fled_cdev_to_led(
|
||||
|
||||
@@ -241,10 +241,20 @@ static int mt6360_strobe_set(struct led_classdev_flash *fl_cdev, bool state)
|
||||
u32 enable_mask = MT6360_STROBEN_MASK | MT6360_FLCSEN_MASK(led->led_no);
|
||||
u32 val = state ? MT6360_FLCSEN_MASK(led->led_no) : 0;
|
||||
u32 prev = priv->fled_strobe_used, curr;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
/*
|
||||
* If the state of the upcoming change is the same as the current LED
|
||||
* device state, then skip the subsequent code to avoid conflict
|
||||
* with the flow of turning on LED torch mode in V4L2.
|
||||
*/
|
||||
if (state == !!(BIT(led->led_no) & prev)) {
|
||||
dev_info(lcdev->dev, "No change in strobe state [0x%x]\n", prev);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only one set of flash control logic, use the flag to avoid torch is
|
||||
* currently used
|
||||
|
||||
@@ -194,11 +194,11 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
|
||||
spin_unlock(&trig->leddev_list_lock);
|
||||
led_cdev->trigger = trig;
|
||||
|
||||
ret = 0;
|
||||
if (trig->activate)
|
||||
ret = trig->activate(led_cdev);
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
led_set_brightness(led_cdev, trig->brightness);
|
||||
if (ret)
|
||||
goto err_activate;
|
||||
|
||||
@@ -387,6 +387,8 @@ void led_trigger_event(struct led_trigger *trig,
|
||||
if (!trig)
|
||||
return;
|
||||
|
||||
trig->brightness = brightness;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list)
|
||||
led_set_brightness(led_cdev, brightness);
|
||||
|
||||
@@ -283,7 +283,10 @@ static int an30259a_probe(struct i2c_client *client)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
mutex_init(&chip->mutex);
|
||||
err = devm_mutex_init(&client->dev, &chip->mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
chip->client = client;
|
||||
i2c_set_clientdata(client, chip);
|
||||
|
||||
@@ -317,17 +320,9 @@ static int an30259a_probe(struct i2c_client *client)
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
mutex_destroy(&chip->mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void an30259a_remove(struct i2c_client *client)
|
||||
{
|
||||
struct an30259a *chip = i2c_get_clientdata(client);
|
||||
|
||||
mutex_destroy(&chip->mutex);
|
||||
}
|
||||
|
||||
static const struct of_device_id an30259a_match_table[] = {
|
||||
{ .compatible = "panasonic,an30259a", },
|
||||
{ /* sentinel */ },
|
||||
@@ -347,7 +342,6 @@ static struct i2c_driver an30259a_driver = {
|
||||
.of_match_table = an30259a_match_table,
|
||||
},
|
||||
.probe = an30259a_probe,
|
||||
.remove = an30259a_remove,
|
||||
.id_table = an30259a_id,
|
||||
};
|
||||
|
||||
|
||||
@@ -181,8 +181,7 @@ static int __init apu_led_init(void)
|
||||
struct platform_device *pdev;
|
||||
int err;
|
||||
|
||||
if (!(dmi_match(DMI_SYS_VENDOR, "PC Engines") &&
|
||||
(dmi_match(DMI_PRODUCT_NAME, "APU") || dmi_match(DMI_PRODUCT_NAME, "apu1")))) {
|
||||
if (!dmi_check_system(apu_led_dmi_table)) {
|
||||
pr_err("No PC Engines APUv1 board detected. For APUv2,3 support, enable CONFIG_PCENGINES_APU2\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -530,6 +530,16 @@ static const struct regmap_config aw200xx_regmap_config = {
|
||||
.disable_locking = true,
|
||||
};
|
||||
|
||||
static void aw200xx_chip_reset_action(void *data)
|
||||
{
|
||||
aw200xx_chip_reset(data);
|
||||
}
|
||||
|
||||
static void aw200xx_disable_action(void *data)
|
||||
{
|
||||
aw200xx_disable(data);
|
||||
}
|
||||
|
||||
static int aw200xx_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct aw200xx_chipdef *cdef;
|
||||
@@ -568,11 +578,17 @@ static int aw200xx_probe(struct i2c_client *client)
|
||||
|
||||
aw200xx_enable(chip);
|
||||
|
||||
ret = devm_add_action(&client->dev, aw200xx_disable_action, chip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = aw200xx_chip_check(chip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_init(&chip->mutex);
|
||||
ret = devm_mutex_init(&client->dev, &chip->mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Need a lock now since after call aw200xx_probe_fw, sysfs nodes created */
|
||||
mutex_lock(&chip->mutex);
|
||||
@@ -581,6 +597,10 @@ static int aw200xx_probe(struct i2c_client *client)
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
ret = devm_add_action(&client->dev, aw200xx_chip_reset_action, chip);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
ret = aw200xx_probe_fw(&client->dev, chip);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
@@ -595,15 +615,6 @@ out_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aw200xx_remove(struct i2c_client *client)
|
||||
{
|
||||
struct aw200xx *chip = i2c_get_clientdata(client);
|
||||
|
||||
aw200xx_chip_reset(chip);
|
||||
aw200xx_disable(chip);
|
||||
mutex_destroy(&chip->mutex);
|
||||
}
|
||||
|
||||
static const struct aw200xx_chipdef aw20036_cdef = {
|
||||
.channels = 36,
|
||||
.display_size_rows_max = 3,
|
||||
@@ -652,7 +663,6 @@ static struct i2c_driver aw200xx_driver = {
|
||||
.of_match_table = aw200xx_match_table,
|
||||
},
|
||||
.probe = aw200xx_probe,
|
||||
.remove = aw200xx_remove,
|
||||
.id_table = aw200xx_id,
|
||||
};
|
||||
module_i2c_driver(aw200xx_driver);
|
||||
|
||||
@@ -320,6 +320,11 @@ static int aw2013_probe_dt(struct aw2013 *chip)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aw2013_chip_disable_action(void *data)
|
||||
{
|
||||
aw2013_chip_disable(data);
|
||||
}
|
||||
|
||||
static const struct regmap_config aw2013_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@@ -336,7 +341,10 @@ static int aw2013_probe(struct i2c_client *client)
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&chip->mutex);
|
||||
ret = devm_mutex_init(&client->dev, &chip->mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&chip->mutex);
|
||||
|
||||
chip->client = client;
|
||||
@@ -384,6 +392,10 @@ static int aw2013_probe(struct i2c_client *client)
|
||||
goto error_reg;
|
||||
}
|
||||
|
||||
ret = devm_add_action(&client->dev, aw2013_chip_disable_action, chip);
|
||||
if (ret)
|
||||
goto error_reg;
|
||||
|
||||
ret = aw2013_probe_dt(chip);
|
||||
if (ret < 0)
|
||||
goto error_reg;
|
||||
@@ -406,19 +418,9 @@ error_reg:
|
||||
|
||||
error:
|
||||
mutex_unlock(&chip->mutex);
|
||||
mutex_destroy(&chip->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aw2013_remove(struct i2c_client *client)
|
||||
{
|
||||
struct aw2013 *chip = i2c_get_clientdata(client);
|
||||
|
||||
aw2013_chip_disable(chip);
|
||||
|
||||
mutex_destroy(&chip->mutex);
|
||||
}
|
||||
|
||||
static const struct of_device_id aw2013_match_table[] = {
|
||||
{ .compatible = "awinic,aw2013", },
|
||||
{ /* sentinel */ },
|
||||
@@ -432,7 +434,6 @@ static struct i2c_driver aw2013_driver = {
|
||||
.of_match_table = aw2013_match_table,
|
||||
},
|
||||
.probe = aw2013_probe,
|
||||
.remove = aw2013_remove,
|
||||
};
|
||||
|
||||
module_i2c_driver(aw2013_driver);
|
||||
|
||||
@@ -542,6 +542,13 @@ static int lm3532_parse_als(struct lm3532_data *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void gpio_set_low_action(void *data)
|
||||
{
|
||||
struct lm3532_data *priv = data;
|
||||
|
||||
gpiod_direction_output(priv->enable_gpio, 0);
|
||||
}
|
||||
|
||||
static int lm3532_parse_node(struct lm3532_data *priv)
|
||||
{
|
||||
struct fwnode_handle *child = NULL;
|
||||
@@ -556,6 +563,12 @@ static int lm3532_parse_node(struct lm3532_data *priv)
|
||||
if (IS_ERR(priv->enable_gpio))
|
||||
priv->enable_gpio = NULL;
|
||||
|
||||
if (priv->enable_gpio) {
|
||||
ret = devm_add_action(&priv->client->dev, gpio_set_low_action, priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv->regulator = devm_regulator_get(&priv->client->dev, "vin");
|
||||
if (IS_ERR(priv->regulator))
|
||||
priv->regulator = NULL;
|
||||
@@ -691,7 +704,10 @@ static int lm3532_probe(struct i2c_client *client)
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_init(&drvdata->lock);
|
||||
ret = devm_mutex_init(&client->dev, &drvdata->lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
i2c_set_clientdata(client, drvdata);
|
||||
|
||||
ret = lm3532_parse_node(drvdata);
|
||||
@@ -703,16 +719,6 @@ static int lm3532_probe(struct i2c_client *client)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lm3532_remove(struct i2c_client *client)
|
||||
{
|
||||
struct lm3532_data *drvdata = i2c_get_clientdata(client);
|
||||
|
||||
mutex_destroy(&drvdata->lock);
|
||||
|
||||
if (drvdata->enable_gpio)
|
||||
gpiod_direction_output(drvdata->enable_gpio, 0);
|
||||
}
|
||||
|
||||
static const struct of_device_id of_lm3532_leds_match[] = {
|
||||
{ .compatible = "ti,lm3532", },
|
||||
{},
|
||||
@@ -727,7 +733,6 @@ MODULE_DEVICE_TABLE(i2c, lm3532_id);
|
||||
|
||||
static struct i2c_driver lm3532_i2c_driver = {
|
||||
.probe = lm3532_probe,
|
||||
.remove = lm3532_remove,
|
||||
.id_table = lm3532_id,
|
||||
.driver = {
|
||||
.name = LM3532_NAME,
|
||||
|
||||
@@ -207,6 +207,13 @@ static const struct regmap_config lp3952_regmap = {
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
static void gpio_set_low_action(void *data)
|
||||
{
|
||||
struct lp3952_led_array *priv = data;
|
||||
|
||||
gpiod_set_value(priv->enable_gpio, 0);
|
||||
}
|
||||
|
||||
static int lp3952_probe(struct i2c_client *client)
|
||||
{
|
||||
int status;
|
||||
@@ -226,6 +233,10 @@ static int lp3952_probe(struct i2c_client *client)
|
||||
return status;
|
||||
}
|
||||
|
||||
status = devm_add_action(&client->dev, gpio_set_low_action, priv);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
priv->regmap = devm_regmap_init_i2c(client, &lp3952_regmap);
|
||||
if (IS_ERR(priv->regmap)) {
|
||||
int err = PTR_ERR(priv->regmap);
|
||||
@@ -254,15 +265,6 @@ static int lp3952_probe(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lp3952_remove(struct i2c_client *client)
|
||||
{
|
||||
struct lp3952_led_array *priv;
|
||||
|
||||
priv = i2c_get_clientdata(client);
|
||||
lp3952_on_off(priv, LP3952_LED_ALL, false);
|
||||
gpiod_set_value(priv->enable_gpio, 0);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id lp3952_id[] = {
|
||||
{LP3952_NAME, 0},
|
||||
{}
|
||||
@@ -274,7 +276,6 @@ static struct i2c_driver lp3952_i2c_driver = {
|
||||
.name = LP3952_NAME,
|
||||
},
|
||||
.probe = lp3952_probe,
|
||||
.remove = lp3952_remove,
|
||||
.id_table = lp3952_id,
|
||||
};
|
||||
|
||||
|
||||
@@ -265,7 +265,6 @@ static const struct lp50xx_chip_info lp50xx_chip_info_tbl[] = {
|
||||
struct lp50xx_led {
|
||||
struct led_classdev_mc mc_cdev;
|
||||
struct lp50xx *priv;
|
||||
unsigned long bank_modules;
|
||||
u8 ctrl_bank_enabled;
|
||||
int led_number;
|
||||
};
|
||||
@@ -279,7 +278,6 @@ struct lp50xx_led {
|
||||
* @dev: pointer to the devices device struct
|
||||
* @lock: lock for reading/writing the device
|
||||
* @chip_info: chip specific information (ie num_leds)
|
||||
* @num_of_banked_leds: holds the number of banked LEDs
|
||||
* @leds: array of LED strings
|
||||
*/
|
||||
struct lp50xx {
|
||||
@@ -290,7 +288,6 @@ struct lp50xx {
|
||||
struct device *dev;
|
||||
struct mutex lock;
|
||||
const struct lp50xx_chip_info *chip_info;
|
||||
int num_of_banked_leds;
|
||||
|
||||
/* This needs to be at the end of the struct */
|
||||
struct lp50xx_led leds[];
|
||||
@@ -404,8 +401,6 @@ static int lp50xx_probe_leds(struct fwnode_handle *child, struct lp50xx *priv,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->num_of_banked_leds = num_leds;
|
||||
|
||||
ret = fwnode_property_read_u32_array(child, "reg", led_banks, num_leds);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "reg property is missing\n");
|
||||
|
||||
@@ -256,6 +256,7 @@ static int mlxreg_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mlxreg_core_platform_data *led_pdata;
|
||||
struct mlxreg_led_priv_data *priv;
|
||||
int err;
|
||||
|
||||
led_pdata = dev_get_platdata(&pdev->dev);
|
||||
if (!led_pdata) {
|
||||
@@ -267,26 +268,21 @@ static int mlxreg_led_probe(struct platform_device *pdev)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&priv->access_lock);
|
||||
err = devm_mutex_init(&pdev->dev, &priv->access_lock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
priv->pdev = pdev;
|
||||
priv->pdata = led_pdata;
|
||||
|
||||
return mlxreg_led_config(priv);
|
||||
}
|
||||
|
||||
static void mlxreg_led_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mlxreg_led_priv_data *priv = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
mutex_destroy(&priv->access_lock);
|
||||
}
|
||||
|
||||
static struct platform_driver mlxreg_led_driver = {
|
||||
.driver = {
|
||||
.name = "leds-mlxreg",
|
||||
},
|
||||
.probe = mlxreg_led_probe,
|
||||
.remove_new = mlxreg_led_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(mlxreg_led_driver);
|
||||
|
||||
@@ -118,6 +118,15 @@ static struct nic78bx_led nic78bx_leds[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static void lock_led_reg_action(void *data)
|
||||
{
|
||||
struct nic78bx_led_data *led_data = data;
|
||||
|
||||
/* Lock LED register */
|
||||
outb(NIC78BX_LOCK_VALUE,
|
||||
led_data->io_base + NIC78BX_LOCK_REG_OFFSET);
|
||||
}
|
||||
|
||||
static int nic78bx_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -152,6 +161,10 @@ static int nic78bx_probe(struct platform_device *pdev)
|
||||
led_data->io_base = io_rc->start;
|
||||
spin_lock_init(&led_data->lock);
|
||||
|
||||
ret = devm_add_action(dev, lock_led_reg_action, led_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(nic78bx_leds); i++) {
|
||||
nic78bx_leds[i].data = led_data;
|
||||
|
||||
@@ -167,15 +180,6 @@ static int nic78bx_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nic78bx_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct nic78bx_led_data *led_data = platform_get_drvdata(pdev);
|
||||
|
||||
/* Lock LED register */
|
||||
outb(NIC78BX_LOCK_VALUE,
|
||||
led_data->io_base + NIC78BX_LOCK_REG_OFFSET);
|
||||
}
|
||||
|
||||
static const struct acpi_device_id led_device_ids[] = {
|
||||
{"NIC78B3", 0},
|
||||
{"", 0},
|
||||
@@ -184,7 +188,6 @@ MODULE_DEVICE_TABLE(acpi, led_device_ids);
|
||||
|
||||
static struct platform_driver led_driver = {
|
||||
.probe = nic78bx_probe,
|
||||
.remove_new = nic78bx_remove,
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.acpi_match_table = ACPI_PTR(led_device_ids),
|
||||
|
||||
@@ -53,7 +53,13 @@ static int led_pwm_set(struct led_classdev *led_cdev,
|
||||
duty = led_dat->pwmstate.period - duty;
|
||||
|
||||
led_dat->pwmstate.duty_cycle = duty;
|
||||
led_dat->pwmstate.enabled = true;
|
||||
/*
|
||||
* Disabling a PWM doesn't guarantee that it emits the inactive level.
|
||||
* So keep it on. Only for suspending the PWM should be disabled because
|
||||
* otherwise it refuses to suspend. The possible downside is that the
|
||||
* LED might stay (or even go) on.
|
||||
*/
|
||||
led_dat->pwmstate.enabled = !(led_cdev->flags & LED_SUSPENDED);
|
||||
return pwm_apply_might_sleep(led_dat->pwm, &led_dat->pwmstate);
|
||||
}
|
||||
|
||||
|
||||
@@ -252,18 +252,16 @@ static int sun50i_a100_ledc_parse_format(struct device *dev,
|
||||
struct sun50i_a100_ledc *priv)
|
||||
{
|
||||
const char *format = "grb";
|
||||
u32 i;
|
||||
int i;
|
||||
|
||||
device_property_read_string(dev, "allwinner,pixel-format", &format);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sun50i_a100_ledc_formats); i++) {
|
||||
if (!strcmp(format, sun50i_a100_ledc_formats[i])) {
|
||||
priv->format = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
i = match_string(sun50i_a100_ledc_formats, ARRAY_SIZE(sun50i_a100_ledc_formats), format);
|
||||
if (i < 0)
|
||||
return dev_err_probe(dev, i, "Bad pixel format '%s'\n", format);
|
||||
|
||||
return dev_err_probe(dev, -EINVAL, "Bad pixel format '%s'\n", format);
|
||||
priv->format = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sun50i_a100_ledc_set_format(struct sun50i_a100_ledc *priv)
|
||||
|
||||
@@ -149,7 +149,6 @@ struct mt6370_priv {
|
||||
struct regmap_field *fields[F_MAX_FIELDS];
|
||||
const struct reg_field *reg_fields;
|
||||
const struct linear_range *ranges;
|
||||
struct reg_cfg *reg_cfgs;
|
||||
const struct mt6370_pdata *pdata;
|
||||
unsigned int leds_count;
|
||||
unsigned int leds_active;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user