Skip to content

Commit

Permalink
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/cooloney/linux-leds

Pull LED updates from Bryan Wu:
 "I just found merge window is open and I'm quite busy and almost forget
  to send out this pull request.  Thanks Russell and Alexandre ping me
  about this.

  So basically we got some clean up and leds-pwm fixing patches from
  Russell"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds:
  leds: Remove duplicated OOM message for individual driver
  drivers/leds: Replace __get_cpu_var use through this_cpu_ptr
  leds: lp55xx: add DT bindings for LP55231
  leds: 88pm860x: Fix missing refcount decrement for parent of_node
  leds: 88pm860x: Use of_get_child_by_name
  leds: leds-pwm: add DT support for LEDs wired to supply
  leds: leds-pwm: implement PWM inversion
  leds: leds-pwm: convert OF parsing code to use led_pwm_add()
  leds: leds-pwm: provide a common function to setup a single led-pwm device
  leds: pca9685: Remove leds-pca9685 driver
  dell-led: add mic mute led interface
  • Loading branch information
Linus Torvalds committed Jun 12, 2014
2 parents af76004 + 0c9a03b commit 7c574cf
Show file tree
Hide file tree
Showing 18 changed files with 267 additions and 367 deletions.
8 changes: 7 additions & 1 deletion Documentation/devicetree/bindings/leds/leds-lp55xx.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
Binding for TI/National Semiconductor LP55xx Led Drivers

Required properties:
- compatible: "national,lp5521" or "national,lp5523" or "ti,lp5562" or "ti,lp8501"
- compatible: one of
national,lp5521
national,lp5523
ti,lp55231
ti,lp5562
ti,lp8501

- reg: I2C slave address
- clock-mode: Input clock mode, (0: automode, 1: internal, 2: external)

Expand Down
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/leds/leds-pwm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ LED sub-node properties:
For the pwms and pwm-names property please refer to:
Documentation/devicetree/bindings/pwm/pwm.txt
- max-brightness : Maximum brightness possible for the LED
- active-low : (optional) For PWMs where the LED is wired to supply
rather than ground.
- label : (optional)
see Documentation/devicetree/bindings/leds/common.txt
- linux,default-trigger : (optional)
Expand Down
10 changes: 0 additions & 10 deletions drivers/leds/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -300,16 +300,6 @@ config LEDS_PCA963X
LED driver chip accessed via the I2C bus. Supported
devices include PCA9633 and PCA9634

config LEDS_PCA9685
tristate "LED support for PCA9685 I2C chip"
depends on LEDS_CLASS
depends on I2C
help
This option enables support for LEDs connected to the PCA9685
LED driver chip accessed via the I2C bus.
The PCA9685 offers 12-bit PWM (4095 levels of brightness) on
16 individual channels.

config LEDS_WM831X_STATUS
tristate "LED support for status LEDs on WM831x PMICs"
depends on LEDS_CLASS
Expand Down
1 change: 0 additions & 1 deletion drivers/leds/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ obj-$(CONFIG_LEDS_OT200) += leds-ot200.o
obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o
obj-$(CONFIG_LEDS_PCA963X) += leds-pca963x.o
obj-$(CONFIG_LEDS_PCA9685) += leds-pca9685.o
obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o
obj-$(CONFIG_LEDS_DA9052) += leds-da9052.o
obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
Expand Down
171 changes: 164 additions & 7 deletions drivers/leds/dell-led.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
#include <linux/leds.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dmi.h>
#include <linux/dell-led.h>

MODULE_AUTHOR("Louis Davis/Jim Dailey");
MODULE_DESCRIPTION("Dell LED Control Driver");
MODULE_LICENSE("GPL");

#define DELL_LED_BIOS_GUID "F6E4FE6E-909D-47cb-8BAB-C9F6F2F8D396"
#define DELL_APP_GUID "A80593CE-A997-11DA-B012-B622A1EF5492"
MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID);

/* Error Result Codes: */
Expand All @@ -39,6 +42,149 @@ MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID);
#define CMD_LED_OFF 17
#define CMD_LED_BLINK 18

struct app_wmi_args {
u16 class;
u16 selector;
u32 arg1;
u32 arg2;
u32 arg3;
u32 arg4;
u32 res1;
u32 res2;
u32 res3;
u32 res4;
char dummy[92];
};

#define GLOBAL_MIC_MUTE_ENABLE 0x364
#define GLOBAL_MIC_MUTE_DISABLE 0x365

struct dell_bios_data_token {
u16 tokenid;
u16 location;
u16 value;
};

struct __attribute__ ((__packed__)) dell_bios_calling_interface {
struct dmi_header header;
u16 cmd_io_addr;
u8 cmd_io_code;
u32 supported_cmds;
struct dell_bios_data_token damap[];
};

static struct dell_bios_data_token dell_mic_tokens[2];

static int dell_wmi_perform_query(struct app_wmi_args *args)
{
struct app_wmi_args *bios_return;
union acpi_object *obj;
struct acpi_buffer input;
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
acpi_status status;
u32 rc = -EINVAL;

input.length = 128;
input.pointer = args;

status = wmi_evaluate_method(DELL_APP_GUID, 0, 1, &input, &output);
if (!ACPI_SUCCESS(status))
goto err_out0;

obj = output.pointer;
if (!obj)
goto err_out0;

if (obj->type != ACPI_TYPE_BUFFER)
goto err_out1;

bios_return = (struct app_wmi_args *)obj->buffer.pointer;
rc = bios_return->res1;
if (rc)
goto err_out1;

memcpy(args, bios_return, sizeof(struct app_wmi_args));
rc = 0;

err_out1:
kfree(obj);
err_out0:
return rc;
}

static void __init find_micmute_tokens(const struct dmi_header *dm, void *dummy)
{
struct dell_bios_calling_interface *calling_interface;
struct dell_bios_data_token *token;
int token_size = sizeof(struct dell_bios_data_token);
int i = 0;

if (dm->type == 0xda && dm->length > 17) {
calling_interface = container_of(dm,
struct dell_bios_calling_interface, header);

token = &calling_interface->damap[i];
while (token->tokenid != 0xffff) {
if (token->tokenid == GLOBAL_MIC_MUTE_DISABLE)
memcpy(&dell_mic_tokens[0], token, token_size);
else if (token->tokenid == GLOBAL_MIC_MUTE_ENABLE)
memcpy(&dell_mic_tokens[1], token, token_size);

i++;
token = &calling_interface->damap[i];
}
}
}

static int dell_micmute_led_set(int state)
{
struct app_wmi_args args;
struct dell_bios_data_token *token;

if (!wmi_has_guid(DELL_APP_GUID))
return -ENODEV;

if (state == 0 || state == 1)
token = &dell_mic_tokens[state];
else
return -EINVAL;

memset(&args, 0, sizeof(struct app_wmi_args));

args.class = 1;
args.arg1 = token->location;
args.arg2 = token->value;

dell_wmi_perform_query(&args);

return state;
}

int dell_app_wmi_led_set(int whichled, int on)
{
int state = 0;

switch (whichled) {
case DELL_LED_MICMUTE:
state = dell_micmute_led_set(on);
break;
default:
pr_warn("led type %x is not supported\n", whichled);
break;
}

return state;
}
EXPORT_SYMBOL_GPL(dell_app_wmi_led_set);

static int __init dell_micmute_led_init(void)
{
memset(dell_mic_tokens, 0, sizeof(struct dell_bios_data_token) * 2);
dmi_walk(find_micmute_tokens, NULL);

return 0;
}

struct bios_args {
unsigned char length;
unsigned char result_code;
Expand Down Expand Up @@ -181,21 +327,32 @@ static int __init dell_led_init(void)
{
int error = 0;

if (!wmi_has_guid(DELL_LED_BIOS_GUID))
if (!wmi_has_guid(DELL_LED_BIOS_GUID) && !wmi_has_guid(DELL_APP_GUID))
return -ENODEV;

error = led_off();
if (error != 0)
return -ENODEV;
if (wmi_has_guid(DELL_APP_GUID))
error = dell_micmute_led_init();

return led_classdev_register(NULL, &dell_led);
if (wmi_has_guid(DELL_LED_BIOS_GUID)) {
error = led_off();
if (error != 0)
return -ENODEV;

error = led_classdev_register(NULL, &dell_led);
}

return error;
}

static void __exit dell_led_exit(void)
{
led_classdev_unregister(&dell_led);
int error = 0;

led_off();
if (wmi_has_guid(DELL_LED_BIOS_GUID)) {
error = led_off();
if (error == 0)
led_classdev_unregister(&dell_led);
}
}

module_init(dell_led_init);
Expand Down
5 changes: 2 additions & 3 deletions drivers/leds/leds-88pm860x.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,9 @@ static int pm860x_led_dt_init(struct platform_device *pdev,
struct device_node *nproot, *np;
int iset = 0;

nproot = of_node_get(pdev->dev.parent->of_node);
if (!nproot)
if (!pdev->dev.parent->of_node)
return -ENODEV;
nproot = of_find_node_by_name(nproot, "leds");
nproot = of_get_child_by_name(pdev->dev.parent->of_node, "leds");
if (!nproot) {
dev_err(&pdev->dev, "failed to find leds node\n");
return -ENODEV;
Expand Down
5 changes: 1 addition & 4 deletions drivers/leds/leds-adp5520.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,10 @@ static int adp5520_led_probe(struct platform_device *pdev)

led = devm_kzalloc(&pdev->dev, sizeof(*led) * pdata->num_leds,
GFP_KERNEL);
if (led == NULL) {
dev_err(&pdev->dev, "failed to alloc memory\n");
if (!led)
return -ENOMEM;
}

ret = adp5520_led_prepare(pdev);

if (ret) {
dev_err(&pdev->dev, "failed to write\n");
return ret;
Expand Down
4 changes: 1 addition & 3 deletions drivers/leds/leds-bd2802.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,10 +678,8 @@ static int bd2802_probe(struct i2c_client *client,
int ret, i;

led = devm_kzalloc(&client->dev, sizeof(struct bd2802_led), GFP_KERNEL);
if (!led) {
dev_err(&client->dev, "failed to allocate driver data\n");
if (!led)
return -ENOMEM;
}

led->client = client;
pdata = led->pdata = dev_get_platdata(&client->dev);
Expand Down
4 changes: 1 addition & 3 deletions drivers/leds/leds-da903x.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,8 @@ static int da903x_led_probe(struct platform_device *pdev)
}

led = devm_kzalloc(&pdev->dev, sizeof(struct da903x_led), GFP_KERNEL);
if (led == NULL) {
dev_err(&pdev->dev, "failed to alloc memory for LED%d\n", id);
if (!led)
return -ENOMEM;
}

led->cdev.name = pdata->name;
led->cdev.default_trigger = pdata->default_trigger;
Expand Down
3 changes: 1 addition & 2 deletions drivers/leds/leds-da9052.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ static int da9052_led_probe(struct platform_device *pdev)
led = devm_kzalloc(&pdev->dev,
sizeof(struct da9052_led) * pled->num_leds,
GFP_KERNEL);
if (led == NULL) {
dev_err(&pdev->dev, "Failed to alloc memory\n");
if (!led) {
error = -ENOMEM;
goto err;
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/leds/leds-lp5523.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* lp5523.c - LP5523 LED Driver
* lp5523.c - LP5523, LP55231 LED Driver
*
* Copyright (C) 2010 Nokia Corporation
* Copyright (C) 2012 Texas Instruments
Expand Down Expand Up @@ -814,6 +814,7 @@ MODULE_DEVICE_TABLE(i2c, lp5523_id);
#ifdef CONFIG_OF
static const struct of_device_id of_lp5523_leds_match[] = {
{ .compatible = "national,lp5523", },
{ .compatible = "ti,lp55231", },
{},
};

Expand Down
Loading

0 comments on commit 7c574cf

Please sign in to comment.