mirror of
https://github.com/torvalds/linux.git
synced 2024-12-23 11:21:33 +00:00
Merge branches 'ib-leds-mfd-6.11', 'ib-leds-platform-power-6.11' and 'ib-mfd-leds-platform-6.11' into ibs-for-leds-merged
This commit is contained in:
commit
59561ccd90
@ -134,6 +134,7 @@ int led_classdev_multicolor_register_ext(struct device *parent,
|
||||
return -EINVAL;
|
||||
|
||||
led_cdev = &mcled_cdev->led_cdev;
|
||||
led_cdev->flags |= LED_MULTI_COLOR;
|
||||
mcled_cdev->led_cdev.groups = led_multicolor_groups;
|
||||
|
||||
return led_classdev_register_ext(parent, led_cdev, init_data);
|
||||
|
@ -503,6 +503,11 @@ int led_classdev_register_ext(struct device *parent,
|
||||
ret = led_classdev_next_name(proposed_name, final_name, sizeof(final_name));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (ret && led_cdev->flags & LED_REJECT_NAME_CONFLICT)
|
||||
return -EEXIST;
|
||||
else if (ret)
|
||||
dev_warn(parent, "Led %s renamed to %s due to name collision\n",
|
||||
proposed_name, final_name);
|
||||
|
||||
if (led_cdev->color >= LED_COLOR_ID_MAX)
|
||||
dev_warn(parent, "LED %s color identifier out of range\n", final_name);
|
||||
@ -518,10 +523,6 @@ int led_classdev_register_ext(struct device *parent,
|
||||
if (init_data && init_data->fwnode)
|
||||
device_set_node(led_cdev->dev, init_data->fwnode);
|
||||
|
||||
if (ret)
|
||||
dev_warn(parent, "Led %s renamed to %s due to name collision",
|
||||
proposed_name, dev_name(led_cdev->dev));
|
||||
|
||||
if (led_cdev->flags & LED_BRIGHT_HW_CHANGED) {
|
||||
ret = led_add_brightness_hw_changed(led_cdev);
|
||||
if (ret) {
|
||||
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/led-class-multicolor.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
@ -361,6 +362,36 @@ int led_set_brightness_sync(struct led_classdev *led_cdev, unsigned int value)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_set_brightness_sync);
|
||||
|
||||
/*
|
||||
* This is a led-core function because just like led_set_brightness()
|
||||
* it is used in the kernel by e.g. triggers.
|
||||
*/
|
||||
void led_mc_set_brightness(struct led_classdev *led_cdev,
|
||||
unsigned int *intensity_value, unsigned int num_colors,
|
||||
unsigned int brightness)
|
||||
{
|
||||
struct led_classdev_mc *mcled_cdev;
|
||||
unsigned int i;
|
||||
|
||||
if (!(led_cdev->flags & LED_MULTI_COLOR)) {
|
||||
dev_err_once(led_cdev->dev, "error not a multi-color LED\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mcled_cdev = lcdev_to_mccdev(led_cdev);
|
||||
if (num_colors != mcled_cdev->num_colors) {
|
||||
dev_err_once(led_cdev->dev, "error num_colors mismatch %u != %u\n",
|
||||
num_colors, mcled_cdev->num_colors);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < mcled_cdev->num_colors; i++)
|
||||
mcled_cdev->subled_info[i].intensity = intensity_value[i];
|
||||
|
||||
led_set_brightness(led_cdev, brightness);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_mc_set_brightness);
|
||||
|
||||
int led_update_brightness(struct led_classdev *led_cdev)
|
||||
{
|
||||
int ret;
|
||||
|
@ -396,6 +396,26 @@ void led_trigger_event(struct led_trigger *trig,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_event);
|
||||
|
||||
void led_mc_trigger_event(struct led_trigger *trig,
|
||||
unsigned int *intensity_value, unsigned int num_colors,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct led_classdev *led_cdev;
|
||||
|
||||
if (!trig)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) {
|
||||
if (!(led_cdev->flags & LED_MULTI_COLOR))
|
||||
continue;
|
||||
|
||||
led_mc_set_brightness(led_cdev, intensity_value, num_colors, brightness);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_mc_trigger_event);
|
||||
|
||||
static void led_trigger_blink_setup(struct led_trigger *trig,
|
||||
unsigned long delay_on,
|
||||
unsigned long delay_off,
|
||||
|
@ -17,7 +17,6 @@ config LEDS_GROUP_MULTICOLOR
|
||||
config LEDS_KTD202X
|
||||
tristate "LED support for KTD202x Chips"
|
||||
depends on I2C
|
||||
depends on OF
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This option enables support for the Kinetic KTD2026/KTD2027
|
||||
|
@ -99,7 +99,7 @@ struct ktd202x {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
bool enabled;
|
||||
int num_leds;
|
||||
unsigned long num_leds;
|
||||
struct ktd202x_led leds[] __counted_by(num_leds);
|
||||
};
|
||||
|
||||
@ -381,16 +381,19 @@ static int ktd202x_blink_mc_set(struct led_classdev *cdev,
|
||||
mc->num_colors);
|
||||
}
|
||||
|
||||
static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct device_node *np,
|
||||
static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct fwnode_handle *fwnode,
|
||||
struct ktd202x_led *led, struct led_init_data *init_data)
|
||||
{
|
||||
struct fwnode_handle *child;
|
||||
struct led_classdev *cdev;
|
||||
struct device_node *child;
|
||||
struct mc_subled *info;
|
||||
int num_channels;
|
||||
int i = 0;
|
||||
|
||||
num_channels = of_get_available_child_count(np);
|
||||
num_channels = 0;
|
||||
fwnode_for_each_available_child_node(fwnode, child)
|
||||
num_channels++;
|
||||
|
||||
if (!num_channels || num_channels > chip->num_leds)
|
||||
return -EINVAL;
|
||||
|
||||
@ -398,22 +401,22 @@ static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct device_node *np,
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_available_child_of_node(np, child) {
|
||||
fwnode_for_each_available_child_node(fwnode, child) {
|
||||
u32 mono_color;
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_u32(child, "reg", ®);
|
||||
ret = fwnode_property_read_u32(child, "reg", ®);
|
||||
if (ret != 0 || reg >= chip->num_leds) {
|
||||
dev_err(chip->dev, "invalid 'reg' of %pOFn\n", child);
|
||||
of_node_put(child);
|
||||
return -EINVAL;
|
||||
dev_err(chip->dev, "invalid 'reg' of %pfw\n", child);
|
||||
fwnode_handle_put(child);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(child, "color", &mono_color);
|
||||
ret = fwnode_property_read_u32(child, "color", &mono_color);
|
||||
if (ret < 0 && ret != -EINVAL) {
|
||||
dev_err(chip->dev, "failed to parse 'color' of %pOF\n", child);
|
||||
of_node_put(child);
|
||||
dev_err(chip->dev, "failed to parse 'color' of %pfw\n", child);
|
||||
fwnode_handle_put(child);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -433,16 +436,16 @@ static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct device_node *np,
|
||||
return devm_led_classdev_multicolor_register_ext(chip->dev, &led->mcdev, init_data);
|
||||
}
|
||||
|
||||
static int ktd202x_setup_led_single(struct ktd202x *chip, struct device_node *np,
|
||||
static int ktd202x_setup_led_single(struct ktd202x *chip, struct fwnode_handle *fwnode,
|
||||
struct ktd202x_led *led, struct led_init_data *init_data)
|
||||
{
|
||||
struct led_classdev *cdev;
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_u32(np, "reg", ®);
|
||||
ret = fwnode_property_read_u32(fwnode, "reg", ®);
|
||||
if (ret != 0 || reg >= chip->num_leds) {
|
||||
dev_err(chip->dev, "invalid 'reg' of %pOFn\n", np);
|
||||
dev_err(chip->dev, "invalid 'reg' of %pfw\n", fwnode);
|
||||
return -EINVAL;
|
||||
}
|
||||
led->index = reg;
|
||||
@ -454,7 +457,7 @@ static int ktd202x_setup_led_single(struct ktd202x *chip, struct device_node *np
|
||||
return devm_led_classdev_register_ext(chip->dev, &led->cdev, init_data);
|
||||
}
|
||||
|
||||
static int ktd202x_add_led(struct ktd202x *chip, struct device_node *np, unsigned int index)
|
||||
static int ktd202x_add_led(struct ktd202x *chip, struct fwnode_handle *fwnode, unsigned int index)
|
||||
{
|
||||
struct ktd202x_led *led = &chip->leds[index];
|
||||
struct led_init_data init_data = {};
|
||||
@ -463,21 +466,21 @@ static int ktd202x_add_led(struct ktd202x *chip, struct device_node *np, unsigne
|
||||
int ret;
|
||||
|
||||
/* Color property is optional in single color case */
|
||||
ret = of_property_read_u32(np, "color", &color);
|
||||
ret = fwnode_property_read_u32(fwnode, "color", &color);
|
||||
if (ret < 0 && ret != -EINVAL) {
|
||||
dev_err(chip->dev, "failed to parse 'color' of %pOF\n", np);
|
||||
dev_err(chip->dev, "failed to parse 'color' of %pfw\n", fwnode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
led->chip = chip;
|
||||
init_data.fwnode = of_fwnode_handle(np);
|
||||
init_data.fwnode = fwnode;
|
||||
|
||||
if (color == LED_COLOR_ID_RGB) {
|
||||
cdev = &led->mcdev.led_cdev;
|
||||
ret = ktd202x_setup_led_rgb(chip, np, led, &init_data);
|
||||
ret = ktd202x_setup_led_rgb(chip, fwnode, led, &init_data);
|
||||
} else {
|
||||
cdev = &led->cdev;
|
||||
ret = ktd202x_setup_led_single(chip, np, led, &init_data);
|
||||
ret = ktd202x_setup_led_single(chip, fwnode, led, &init_data);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
@ -490,15 +493,14 @@ static int ktd202x_add_led(struct ktd202x *chip, struct device_node *np, unsigne
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ktd202x_probe_dt(struct ktd202x *chip)
|
||||
static int ktd202x_probe_fw(struct ktd202x *chip)
|
||||
{
|
||||
struct device_node *np = dev_of_node(chip->dev), *child;
|
||||
struct fwnode_handle *child;
|
||||
struct device *dev = chip->dev;
|
||||
int count;
|
||||
int i = 0;
|
||||
|
||||
chip->num_leds = (int)(unsigned long)of_device_get_match_data(chip->dev);
|
||||
|
||||
count = of_get_available_child_count(np);
|
||||
count = device_get_child_node_count(dev);
|
||||
if (!count || count > chip->num_leds)
|
||||
return -EINVAL;
|
||||
|
||||
@ -507,11 +509,11 @@ static int ktd202x_probe_dt(struct ktd202x *chip)
|
||||
/* Allow the device to execute the complete reset */
|
||||
usleep_range(200, 300);
|
||||
|
||||
for_each_available_child_of_node(np, child) {
|
||||
device_for_each_child_node(dev, child) {
|
||||
int ret = ktd202x_add_led(chip, child, i);
|
||||
|
||||
if (ret) {
|
||||
of_node_put(child);
|
||||
fwnode_handle_put(child);
|
||||
return ret;
|
||||
}
|
||||
i++;
|
||||
@ -554,6 +556,12 @@ static int ktd202x_probe(struct i2c_client *client)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_mutex_init(dev, &chip->mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
chip->num_leds = (unsigned long)i2c_get_match_data(client);
|
||||
|
||||
chip->regulators[0].supply = "vin";
|
||||
chip->regulators[1].supply = "vio";
|
||||
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators);
|
||||
@ -568,7 +576,7 @@ static int ktd202x_probe(struct i2c_client *client)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ktd202x_probe_dt(chip);
|
||||
ret = ktd202x_probe_fw(chip);
|
||||
if (ret < 0) {
|
||||
regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
|
||||
return ret;
|
||||
@ -580,8 +588,6 @@ static int ktd202x_probe(struct i2c_client *client)
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_init(&chip->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -590,8 +596,6 @@ static void ktd202x_remove(struct i2c_client *client)
|
||||
struct ktd202x *chip = i2c_get_clientdata(client);
|
||||
|
||||
ktd202x_chip_disable(chip);
|
||||
|
||||
mutex_destroy(&chip->mutex);
|
||||
}
|
||||
|
||||
static void ktd202x_shutdown(struct i2c_client *client)
|
||||
@ -602,10 +606,17 @@ static void ktd202x_shutdown(struct i2c_client *client)
|
||||
regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_RSTR_RESET);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id ktd202x_id[] = {
|
||||
{"ktd2026", KTD2026_NUM_LEDS},
|
||||
{"ktd2027", KTD2027_NUM_LEDS},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ktd202x_id);
|
||||
|
||||
static const struct of_device_id ktd202x_match_table[] = {
|
||||
{ .compatible = "kinetic,ktd2026", .data = (void *)KTD2026_NUM_LEDS },
|
||||
{ .compatible = "kinetic,ktd2027", .data = (void *)KTD2027_NUM_LEDS },
|
||||
{},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ktd202x_match_table);
|
||||
|
||||
@ -617,6 +628,7 @@ static struct i2c_driver ktd202x_driver = {
|
||||
.probe = ktd202x_probe,
|
||||
.remove = ktd202x_remove,
|
||||
.shutdown = ktd202x_shutdown,
|
||||
.id_table = ktd202x_id,
|
||||
};
|
||||
module_i2c_driver(ktd202x_driver);
|
||||
|
||||
|
@ -103,6 +103,10 @@ static const struct mfd_cell cros_ec_led_cells[] = {
|
||||
{ .name = "cros-ec-led", },
|
||||
};
|
||||
|
||||
static const struct mfd_cell cros_ec_keyboard_leds_cells[] = {
|
||||
{ .name = "cros-keyboard-leds", },
|
||||
};
|
||||
|
||||
static const struct cros_feature_to_cells cros_subdevices[] = {
|
||||
{
|
||||
.id = EC_FEATURE_CEC,
|
||||
@ -134,6 +138,11 @@ static const struct cros_feature_to_cells cros_subdevices[] = {
|
||||
.mfd_cells = cros_ec_led_cells,
|
||||
.num_cells = ARRAY_SIZE(cros_ec_led_cells),
|
||||
},
|
||||
{
|
||||
.id = EC_FEATURE_PWM_KEYB,
|
||||
.mfd_cells = cros_ec_keyboard_leds_cells,
|
||||
.num_cells = ARRAY_SIZE(cros_ec_keyboard_leds_cells),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell cros_ec_platform_cells[] = {
|
||||
|
@ -150,7 +150,7 @@ config CROS_EC_PROTO
|
||||
|
||||
config CROS_KBD_LED_BACKLIGHT
|
||||
tristate "Backlight LED support for Chrome OS keyboards"
|
||||
depends on LEDS_CLASS && (ACPI || CROS_EC)
|
||||
depends on LEDS_CLASS && (ACPI || CROS_EC || MFD_CROS_EC_DEV)
|
||||
help
|
||||
This option enables support for the keyboard backlight LEDs on
|
||||
select Chrome OS systems.
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
@ -194,13 +195,46 @@ static const __maybe_unused struct keyboard_led_drvdata keyboard_led_drvdata_ec_
|
||||
|
||||
#endif /* IS_ENABLED(CONFIG_CROS_EC) */
|
||||
|
||||
#if IS_ENABLED(CONFIG_MFD_CROS_EC_DEV)
|
||||
static int keyboard_led_init_ec_pwm_mfd(struct platform_device *pdev)
|
||||
{
|
||||
struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct cros_ec_device *cros_ec = ec_dev->ec_dev;
|
||||
struct keyboard_led *keyboard_led = platform_get_drvdata(pdev);
|
||||
|
||||
keyboard_led->ec = cros_ec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct keyboard_led_drvdata keyboard_led_drvdata_ec_pwm_mfd = {
|
||||
.init = keyboard_led_init_ec_pwm_mfd,
|
||||
.brightness_set_blocking = keyboard_led_set_brightness_ec_pwm,
|
||||
.brightness_get = keyboard_led_get_brightness_ec_pwm,
|
||||
.max_brightness = KEYBOARD_BACKLIGHT_MAX,
|
||||
};
|
||||
|
||||
#else /* IS_ENABLED(CONFIG_MFD_CROS_EC_DEV) */
|
||||
|
||||
static const struct keyboard_led_drvdata keyboard_led_drvdata_ec_pwm_mfd = {};
|
||||
|
||||
#endif /* IS_ENABLED(CONFIG_MFD_CROS_EC_DEV) */
|
||||
|
||||
static int keyboard_led_is_mfd_device(struct platform_device *pdev)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_MFD_CROS_EC_DEV) && mfd_get_cell(pdev);
|
||||
}
|
||||
|
||||
static int keyboard_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct keyboard_led_drvdata *drvdata;
|
||||
struct keyboard_led *keyboard_led;
|
||||
int error;
|
||||
|
||||
drvdata = device_get_match_data(&pdev->dev);
|
||||
if (keyboard_led_is_mfd_device(pdev))
|
||||
drvdata = &keyboard_led_drvdata_ec_pwm_mfd;
|
||||
else
|
||||
drvdata = device_get_match_data(&pdev->dev);
|
||||
if (!drvdata)
|
||||
return -EINVAL;
|
||||
|
||||
@ -216,13 +250,15 @@ static int keyboard_led_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
keyboard_led->cdev.name = "chromeos::kbd_backlight";
|
||||
keyboard_led->cdev.flags |= LED_CORE_SUSPENDRESUME;
|
||||
keyboard_led->cdev.flags |= LED_CORE_SUSPENDRESUME | LED_REJECT_NAME_CONFLICT;
|
||||
keyboard_led->cdev.max_brightness = drvdata->max_brightness;
|
||||
keyboard_led->cdev.brightness_set = drvdata->brightness_set;
|
||||
keyboard_led->cdev.brightness_set_blocking = drvdata->brightness_set_blocking;
|
||||
keyboard_led->cdev.brightness_get = drvdata->brightness_get;
|
||||
|
||||
error = devm_led_classdev_register(&pdev->dev, &keyboard_led->cdev);
|
||||
if (error == -EEXIST) /* Already bound via other mechanism */
|
||||
return -ENODEV;
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
static void power_supply_update_bat_leds(struct power_supply *psy)
|
||||
{
|
||||
union power_supply_propval status;
|
||||
unsigned int intensity_green[3] = { 0, 255, 0 };
|
||||
unsigned int intensity_orange[3] = { 255, 128, 0 };
|
||||
|
||||
if (power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS, &status))
|
||||
return;
|
||||
@ -36,12 +38,20 @@ static void power_supply_update_bat_leds(struct power_supply *psy)
|
||||
/* Going from blink to LED on requires a LED_OFF event to stop blink */
|
||||
led_trigger_event(psy->charging_blink_full_solid_trig, LED_OFF);
|
||||
led_trigger_event(psy->charging_blink_full_solid_trig, LED_FULL);
|
||||
led_mc_trigger_event(psy->charging_orange_full_green_trig,
|
||||
intensity_green,
|
||||
ARRAY_SIZE(intensity_green),
|
||||
LED_FULL);
|
||||
break;
|
||||
case POWER_SUPPLY_STATUS_CHARGING:
|
||||
led_trigger_event(psy->charging_full_trig, LED_FULL);
|
||||
led_trigger_event(psy->charging_trig, LED_FULL);
|
||||
led_trigger_event(psy->full_trig, LED_OFF);
|
||||
led_trigger_blink(psy->charging_blink_full_solid_trig, 0, 0);
|
||||
led_mc_trigger_event(psy->charging_orange_full_green_trig,
|
||||
intensity_orange,
|
||||
ARRAY_SIZE(intensity_orange),
|
||||
LED_FULL);
|
||||
break;
|
||||
default:
|
||||
led_trigger_event(psy->charging_full_trig, LED_OFF);
|
||||
@ -49,6 +59,8 @@ static void power_supply_update_bat_leds(struct power_supply *psy)
|
||||
led_trigger_event(psy->full_trig, LED_OFF);
|
||||
led_trigger_event(psy->charging_blink_full_solid_trig,
|
||||
LED_OFF);
|
||||
led_trigger_event(psy->charging_orange_full_green_trig,
|
||||
LED_OFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -74,6 +86,11 @@ static int power_supply_create_bat_triggers(struct power_supply *psy)
|
||||
if (!psy->charging_blink_full_solid_trig_name)
|
||||
goto charging_blink_full_solid_failed;
|
||||
|
||||
psy->charging_orange_full_green_trig_name = kasprintf(GFP_KERNEL,
|
||||
"%s-charging-orange-full-green", psy->desc->name);
|
||||
if (!psy->charging_orange_full_green_trig_name)
|
||||
goto charging_red_full_green_failed;
|
||||
|
||||
led_trigger_register_simple(psy->charging_full_trig_name,
|
||||
&psy->charging_full_trig);
|
||||
led_trigger_register_simple(psy->charging_trig_name,
|
||||
@ -82,9 +99,13 @@ static int power_supply_create_bat_triggers(struct power_supply *psy)
|
||||
&psy->full_trig);
|
||||
led_trigger_register_simple(psy->charging_blink_full_solid_trig_name,
|
||||
&psy->charging_blink_full_solid_trig);
|
||||
led_trigger_register_simple(psy->charging_orange_full_green_trig_name,
|
||||
&psy->charging_orange_full_green_trig);
|
||||
|
||||
return 0;
|
||||
|
||||
charging_red_full_green_failed:
|
||||
kfree(psy->charging_blink_full_solid_trig_name);
|
||||
charging_blink_full_solid_failed:
|
||||
kfree(psy->full_trig_name);
|
||||
full_failed:
|
||||
@ -101,10 +122,12 @@ static void power_supply_remove_bat_triggers(struct power_supply *psy)
|
||||
led_trigger_unregister_simple(psy->charging_trig);
|
||||
led_trigger_unregister_simple(psy->full_trig);
|
||||
led_trigger_unregister_simple(psy->charging_blink_full_solid_trig);
|
||||
led_trigger_unregister_simple(psy->charging_orange_full_green_trig);
|
||||
kfree(psy->charging_blink_full_solid_trig_name);
|
||||
kfree(psy->full_trig_name);
|
||||
kfree(psy->charging_trig_name);
|
||||
kfree(psy->charging_full_trig_name);
|
||||
kfree(psy->charging_orange_full_green_trig_name);
|
||||
}
|
||||
|
||||
/* Generated power specific LEDs triggers. */
|
||||
|
@ -107,6 +107,8 @@ struct led_classdev {
|
||||
#define LED_BRIGHT_HW_CHANGED BIT(21)
|
||||
#define LED_RETAIN_AT_SHUTDOWN BIT(22)
|
||||
#define LED_INIT_DEFAULT_TRIGGER BIT(23)
|
||||
#define LED_REJECT_NAME_CONFLICT BIT(24)
|
||||
#define LED_MULTI_COLOR BIT(25)
|
||||
|
||||
/* set_brightness_work / blink_timer flags, atomic, private. */
|
||||
unsigned long work_flags;
|
||||
@ -373,6 +375,25 @@ void led_set_brightness(struct led_classdev *led_cdev, unsigned int brightness);
|
||||
*/
|
||||
int led_set_brightness_sync(struct led_classdev *led_cdev, unsigned int value);
|
||||
|
||||
/**
|
||||
* led_mc_set_brightness - set mc LED color intensity values and brightness
|
||||
* @led_cdev: the LED to set
|
||||
* @intensity_value: array of per color intensity values to set
|
||||
* @num_colors: amount of entries in intensity_value array
|
||||
* @brightness: the brightness to set the LED to
|
||||
*
|
||||
* Set a multi-color LED's per color intensity values and brightness.
|
||||
* If necessary, this cancels the software blink timer. This function is
|
||||
* guaranteed not to sleep.
|
||||
*
|
||||
* Calling this function on a non multi-color led_classdev or with the wrong
|
||||
* num_colors value is an error. In this case an error will be logged once
|
||||
* and the call will do nothing.
|
||||
*/
|
||||
void led_mc_set_brightness(struct led_classdev *led_cdev,
|
||||
unsigned int *intensity_value, unsigned int num_colors,
|
||||
unsigned int brightness);
|
||||
|
||||
/**
|
||||
* led_update_brightness - update LED brightness
|
||||
* @led_cdev: the LED to query
|
||||
@ -500,6 +521,9 @@ void led_trigger_register_simple(const char *name,
|
||||
struct led_trigger **trigger);
|
||||
void led_trigger_unregister_simple(struct led_trigger *trigger);
|
||||
void led_trigger_event(struct led_trigger *trigger, enum led_brightness event);
|
||||
void led_mc_trigger_event(struct led_trigger *trig,
|
||||
unsigned int *intensity_value, unsigned int num_colors,
|
||||
enum led_brightness brightness);
|
||||
void led_trigger_blink(struct led_trigger *trigger, unsigned long delay_on,
|
||||
unsigned long delay_off);
|
||||
void led_trigger_blink_oneshot(struct led_trigger *trigger,
|
||||
@ -542,6 +566,9 @@ static inline void led_trigger_register_simple(const char *name,
|
||||
static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {}
|
||||
static inline void led_trigger_event(struct led_trigger *trigger,
|
||||
enum led_brightness event) {}
|
||||
static inline void led_mc_trigger_event(struct led_trigger *trig,
|
||||
unsigned int *intensity_value, unsigned int num_colors,
|
||||
enum led_brightness brightness) {}
|
||||
static inline void led_trigger_blink(struct led_trigger *trigger,
|
||||
unsigned long delay_on,
|
||||
unsigned long delay_off) {}
|
||||
|
@ -319,6 +319,8 @@ struct power_supply {
|
||||
char *online_trig_name;
|
||||
struct led_trigger *charging_blink_full_solid_trig;
|
||||
char *charging_blink_full_solid_trig_name;
|
||||
struct led_trigger *charging_orange_full_green_trig;
|
||||
char *charging_orange_full_green_trig_name;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user