History

Merge tag 'leds_for_4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds

Pull LED updates from Jacek Anaszewski: "New drivers: - add LED support for MT6323 PMIC - add LED support for Motorola CPCAP PMIC New features and improvements: - add LED trigger for all CPUs aggregated which is useful on tiny boards with more CPU cores than LED pins - add OF variants of LED registering functions as a preparation for adding generic support for Device Tree parsing - dell-led improvements and cleanups, followed by moving it to the x86 platform driver subsystem which is a more appropriate place for it - extend pca9532 Device Tree support by adding the LEDs 'default-state' property - extend pca963x Device Tree support by adding nxp,inverted-out property for inverting the polarity of the output - remove ACPI support for lp3952 since it relied on a non-official ACPI IDs" * tag 'leds_for_4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds: leds: pca9532: Extend pca9532 device tree support leds: cpcap: new driver mfd: cpcap: Add missing include dependencies leds: lp3952: Use 'if (ret)' pattern leds: lp3952: Remove ACPI support for lp3952 leds: mt6323: Fix an off by one bug in probe dt-bindings: leds: Add document bindings for leds-mt6323 leds: Add LED support for MT6323 PMIC leds: gpio: use OF variant of LED registering function leds: core: add OF variants of LED registering functions platform/x86: dell-wmi-led: fix coding style issues dell-led: move driver to drivers/platform/x86/dell-wmi-led.c dell-led: remove code related to mic mute LED platform/x86: dell-laptop: import dell_micmute_led_set() from drivers/leds/dell-led.c ALSA: hda - rename dell_led_set_func to dell_micmute_led_set_func ALSA: hda - use dell_micmute_led_set() instead of dell_app_wmi_led_set() dell-led: remove GUID check from dell_micmute_led_set() leds/trigger/cpu: Add LED trigger for all CPUs aggregated

Linus Torvalds committed 9 years ago

Commit 85724ed2 parents 477d7ca 28c5fe921 files · +1043 −178Browse files

Unified · Split

21 files
  1. Documentation/devicetree/bindings/leds/leds-cpcap.txt +29 −0
  2. Documentation/devicetree/bindings/leds/leds-mt6323.txt +60 −0
  3. Documentation/devicetree/bindings/leds/leds-pca9532.txt +10 −0
  4. drivers/leds/Kconfig +17 −10
  5. drivers/leds/Makefile +2 −1
  6. drivers/leds/led-class.c +16 −10
  7. drivers/leds/leds-cpcap.c +239 −0
  8. drivers/leds/leds-gpio.c +6 −6
  9. drivers/leds/leds-lp3952.c +4 −14
  10. drivers/leds/leds-mt6323.c +502 −0
  11. drivers/leds/leds-pca9532.c +26 −1
  12. drivers/leds/trigger/ledtrig-cpu.c +31 −2
  13. drivers/platform/x86/Kconfig +8 −0
  14. drivers/platform/x86/Makefile +1 −0
  15. drivers/platform/x86/dell-laptop.c +28 −0
  16. drivers/platform/x86/dell-wmi-led.c +33 −108
  17. include/linux/dell-led.h +1 −5
  18. include/linux/leds-pca9532.h +2 −2
  19. include/linux/leds.h +10 −4
  20. include/linux/mfd/motorola-cpcap.h +3 −0
  21. sound/pci/hda/dell_wmi_helper.c +15 −15
Documentation/devicetree/bindings/leds/leds-cpcap.txt+29−0
@@ -0,0 +1,29 @@
1Motorola CPCAP PMIC LEDs
2------------------------
3
4This module is part of the CPCAP. For more details about the whole
5chip see Documentation/devicetree/bindings/mfd/motorola-cpcap.txt.
6
7Requires node properties:
8- compatible: should be one of
9 * "motorola,cpcap-led-mdl" (Main Display Lighting)
10 * "motorola,cpcap-led-kl" (Keyboard Lighting)
11 * "motorola,cpcap-led-adl" (Aux Display Lighting)
12 * "motorola,cpcap-led-red" (Red Triode)
13 * "motorola,cpcap-led-green" (Green Triode)
14 * "motorola,cpcap-led-blue" (Blue Triode)
15 * "motorola,cpcap-led-cf" (Camera Flash)
16 * "motorola,cpcap-led-bt" (Bluetooth)
17 * "motorola,cpcap-led-cp" (Camera Privacy LED)
18- label: see Documentation/devicetree/bindings/leds/common.txt
19- vdd-supply: A phandle to the regulator powering the LED
20
21Example:
22
23&cpcap {
24 cpcap_led_red: red-led {
25 compatible = "motorola,cpcap-led-red";
26 label = "cpcap:red";
27 vdd-supply = <&sw5>;
28 };
29};
Documentation/devicetree/bindings/leds/leds-mt6323.txt+60−0
@@ -0,0 +1,60 @@
1Device Tree Bindings for LED support on MT6323 PMIC
2
3MT6323 LED controller is subfunction provided by MT6323 PMIC, so the LED
4controllers are defined as the subnode of the function node provided by MT6323
5PMIC controller that is being defined as one kind of Muti-Function Device (MFD)
6using shared bus called PMIC wrapper for each subfunction to access remote
7MT6323 PMIC hardware.
8
9For MT6323 MFD bindings see:
10Documentation/devicetree/bindings/mfd/mt6397.txt
11For MediaTek PMIC wrapper bindings see:
12Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
13
14Required properties:
15- compatible : Must be "mediatek,mt6323-led"
16- address-cells : Must be 1
17- size-cells : Must be 0
18
19Each led is represented as a child node of the mediatek,mt6323-led that
20describes the initial behavior for each LED physically and currently only four
21LED child nodes can be supported.
22
23Required properties for the LED child node:
24- reg : LED channel number (0..3)
25
26Optional properties for the LED child node:
27- label : See Documentation/devicetree/bindings/leds/common.txt
28- linux,default-trigger : See Documentation/devicetree/bindings/leds/common.txt
29- default-state: See Documentation/devicetree/bindings/leds/common.txt
30
31Example:
32
33 mt6323: pmic {
34 compatible = "mediatek,mt6323";
35
36 ...
37
38 mt6323led: leds {
39 compatible = "mediatek,mt6323-led";
40 #address-cells = <1>;
41 #size-cells = <0>;
42
43 led@0 {
44 reg = <0>;
45 label = "LED0";
46 linux,default-trigger = "timer";
47 default-state = "on";
48 };
49 led@1 {
50 reg = <1>;
51 label = "LED1";
52 default-state = "off";
53 };
54 led@2 {
55 reg = <2>;
56 label = "LED2";
57 default-state = "on";
58 };
59 };
60 };
Documentation/devicetree/bindings/leds/leds-pca9532.txt+10−0
@@ -17,6 +17,8 @@ Optional sub-node properties: · 16 unmodified lines
17 - label: see Documentation/devicetree/bindings/leds/common.txt17 - label: see Documentation/devicetree/bindings/leds/common.txt
18 - type: Output configuration, see dt-bindings/leds/leds-pca9532.h (default NONE)18 - type: Output configuration, see dt-bindings/leds/leds-pca9532.h (default NONE)
19 - linux,default-trigger: see Documentation/devicetree/bindings/leds/common.txt19 - linux,default-trigger: see Documentation/devicetree/bindings/leds/common.txt
20 - default-state: see Documentation/devicetree/bindings/leds/common.txt
21 This property is only valid for sub-nodes of type <PCA9532_TYPE_LED>.
20 22
21Example:23Example:
22 #include <dt-bindings/leds/leds-pca9532.h>24 #include <dt-bindings/leds/leds-pca9532.h>
@@ -33,6 +35,14 @@ Example: · 10 unmodified lines
33 label = "pca:green:power";35 label = "pca:green:power";
34 type = <PCA9532_TYPE_LED>;36 type = <PCA9532_TYPE_LED>;
35 };37 };
38 kernel-booting {
39 type = <PCA9532_TYPE_LED>;
40 default-state = "on";
41 };
42 sys-stat {
43 type = <PCA9532_TYPE_LED>;
44 default-state = "keep"; // don't touch, was set by U-Boot
45 };
36 };46 };
37 47
38For more product information please see the link below:48For more product information please see the link below:
drivers/leds/Kconfig+17−10
@@ -76,6 +76,15 @@ config LEDS_BCM6358 · 75 unmodified lines
76 This option enables support for LEDs connected to the BCM635876 This option enables support for LEDs connected to the BCM6358
77 LED HW controller accessed via MMIO registers.77 LED HW controller accessed via MMIO registers.
78 78
79config LEDS_CPCAP
80 tristate "LED Support for Motorola CPCAP"
81 depends on LEDS_CLASS
82 depends on MFD_CPCAP
83 depends on OF
84 help
85 This option enables support for LEDs offered by Motorola's
86 CPCAP PMIC.
87
79config LEDS_LM353088config LEDS_LM3530
80 tristate "LCD Backlight driver for LM3530"89 tristate "LCD Backlight driver for LM3530"
81 depends on LEDS_CLASS90 depends on LEDS_CLASS
@@ -126,6 +135,14 @@ config LEDS_MIKROTIK_RB532 · 44 unmodified lines
126 This option enables support for the so called "User LED" of135 This option enables support for the so called "User LED" of
127 Mikrotik's Routerboard 532.136 Mikrotik's Routerboard 532.
128 137
138config LEDS_MT6323
139 tristate "LED Support for Mediatek MT6323 PMIC"
140 depends on LEDS_CLASS
141 depends on MFD_MT6397
142 help
143 This option enables support for on-chip LED drivers found on
144 Mediatek MT6323 PMIC.
145
129config LEDS_S3C24XX146config LEDS_S3C24XX
130 tristate "LED Support for Samsung S3C24XX GPIO LEDs"147 tristate "LED Support for Samsung S3C24XX GPIO LEDs"
131 depends on LEDS_CLASS148 depends on LEDS_CLASS
@@ -241,7 +258,6 @@ config LEDS_LP3952 · 109 unmodified lines
241 tristate "LED Support for TI LP3952 2 channel LED driver"258 tristate "LED Support for TI LP3952 2 channel LED driver"
242 depends on LEDS_CLASS259 depends on LEDS_CLASS
243 depends on I2C260 depends on I2C
244 depends on ACPI
245 depends on GPIOLIB261 depends on GPIOLIB
246 select REGMAP_I2C262 select REGMAP_I2C
247 help263 help
@@ -463,15 +479,6 @@ config LEDS_ADP5520 · 215 unmodified lines
463 To compile this driver as a module, choose M here: the module will479 To compile this driver as a module, choose M here: the module will
464 be called leds-adp5520.480 be called leds-adp5520.
465 481
466config LEDS_DELL_NETBOOKS
467 tristate "External LED on Dell Business Netbooks"
468 depends on LEDS_CLASS
469 depends on X86 && ACPI_WMI
470 depends on DELL_SMBIOS
471 help
472 This adds support for the Latitude 2100 and similar
473 notebooks that have an external LED.
474
475config LEDS_MC13783482config LEDS_MC13783
476 tristate "LED Support for MC13XXX PMIC"483 tristate "LED Support for MC13XXX PMIC"
477 depends on LEDS_CLASS484 depends on LEDS_CLASS
drivers/leds/Makefile+2−1
@@ -11,6 +11,7 @@ obj-$(CONFIG_LEDS_AAT1290) += leds-aat1290.o · 10 unmodified lines
11obj-$(CONFIG_LEDS_BCM6328) += leds-bcm6328.o11obj-$(CONFIG_LEDS_BCM6328) += leds-bcm6328.o
12obj-$(CONFIG_LEDS_BCM6358) += leds-bcm6358.o12obj-$(CONFIG_LEDS_BCM6358) += leds-bcm6358.o
13obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o13obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
14obj-$(CONFIG_LEDS_CPCAP) += leds-cpcap.o
14obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o15obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
15obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o16obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o
16obj-$(CONFIG_LEDS_LM3533) += leds-lm3533.o17obj-$(CONFIG_LEDS_LM3533) += leds-lm3533.o
@@ -52,7 +53,6 @@ obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o · 35 unmodified lines
52obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o53obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o
53obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o54obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o
54obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o55obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o
55obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o
56obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o56obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o
57obj-$(CONFIG_LEDS_NS2) += leds-ns2.o57obj-$(CONFIG_LEDS_NS2) += leds-ns2.o
58obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o58obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
@@ -72,6 +72,7 @@ obj-$(CONFIG_LEDS_IS31FL32XX) += leds-is31fl32xx.o · 13 unmodified lines
72obj-$(CONFIG_LEDS_PM8058) += leds-pm8058.o72obj-$(CONFIG_LEDS_PM8058) += leds-pm8058.o
73obj-$(CONFIG_LEDS_MLXCPLD) += leds-mlxcpld.o73obj-$(CONFIG_LEDS_MLXCPLD) += leds-mlxcpld.o
74obj-$(CONFIG_LEDS_NIC78BX) += leds-nic78bx.o74obj-$(CONFIG_LEDS_NIC78BX) += leds-nic78bx.o
75obj-$(CONFIG_LEDS_MT6323) += leds-mt6323.o
75 76
76# LED SPI Drivers77# LED SPI Drivers
77obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o78obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
drivers/leds/led-class.c+16−10
@@ -244,11 +244,14 @@ static int led_classdev_next_name(const char *init_name, char *name, · 243 unmodified lines
244}244}
245 245
246/**246/**
247 * led_classdev_register - register a new object of led_classdev class.247 * of_led_classdev_register - register a new object of led_classdev class.
248 * @parent: The device to register.248 *
249 * @parent: parent of LED device
249 * @led_cdev: the led_classdev structure for this device.250 * @led_cdev: the led_classdev structure for this device.
251 * @np: DT node describing this LED
250 */252 */
251int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)253int of_led_classdev_register(struct device *parent, struct device_node *np,
254 struct led_classdev *led_cdev)
252{255{
253 char name[LED_MAX_NAME_SIZE];256 char name[LED_MAX_NAME_SIZE];
254 int ret;257 int ret;
@@ -261,6 +264,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) · 6 unmodified lines
261 led_cdev, led_cdev->groups, "%s", name);264 led_cdev, led_cdev->groups, "%s", name);
262 if (IS_ERR(led_cdev->dev))265 if (IS_ERR(led_cdev->dev))
263 return PTR_ERR(led_cdev->dev);266 return PTR_ERR(led_cdev->dev);
267 led_cdev->dev->of_node = np;
264 268
265 if (ret)269 if (ret)
266 dev_warn(parent, "Led %s renamed to %s due to name collision",270 dev_warn(parent, "Led %s renamed to %s due to name collision",
@@ -303,7 +307,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) · 36 unmodified lines
303 307
304 return 0;308 return 0;
305}309}
306EXPORT_SYMBOL_GPL(led_classdev_register);310EXPORT_SYMBOL_GPL(of_led_classdev_register);
307 311
308/**312/**
309 * led_classdev_unregister - unregisters a object of led_properties class.313 * led_classdev_unregister - unregisters a object of led_properties class.
@@ -348,12 +352,14 @@ static void devm_led_classdev_release(struct device *dev, void *res) · 38 unmodified lines
348}352}
349 353
350/**354/**
351 * devm_led_classdev_register - resource managed led_classdev_register()355 * devm_of_led_classdev_register - resource managed led_classdev_register()
352 * @parent: The device to register.356 *
357 * @parent: parent of LED device
353 * @led_cdev: the led_classdev structure for this device.358 * @led_cdev: the led_classdev structure for this device.
354 */359 */
355int devm_led_classdev_register(struct device *parent,360int devm_of_led_classdev_register(struct device *parent,
356 struct led_classdev *led_cdev)361 struct device_node *np,
362 struct led_classdev *led_cdev)
357{363{
358 struct led_classdev **dr;364 struct led_classdev **dr;
359 int rc;365 int rc;
@@ -362,7 +368,7 @@ int devm_led_classdev_register(struct device *parent, · 2 unmodified lines
362 if (!dr)368 if (!dr)
363 return -ENOMEM;369 return -ENOMEM;
364 370
365 rc = led_classdev_register(parent, led_cdev);371 rc = of_led_classdev_register(parent, np, led_cdev);
366 if (rc) {372 if (rc) {
367 devres_free(dr);373 devres_free(dr);
368 return rc;374 return rc;
@@ -373,7 +379,7 @@ int devm_led_classdev_register(struct device *parent, · 4 unmodified lines
373 379
374 return 0;380 return 0;
375}381}
376EXPORT_SYMBOL_GPL(devm_led_classdev_register);382EXPORT_SYMBOL_GPL(devm_of_led_classdev_register);
377 383
378static int devm_led_classdev_match(struct device *dev, void *res, void *data)384static int devm_led_classdev_match(struct device *dev, void *res, void *data)
379{385{
drivers/leds/leds-cpcap.c+239−0
@@ -0,0 +1,239 @@
1/*
2 * Copyright (c) 2017 Sebastian Reichel <sre@kernel.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 or
6 * later as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/leds.h>
15#include <linux/mfd/motorola-cpcap.h>
16#include <linux/module.h>
17#include <linux/mutex.h>
18#include <linux/of_device.h>
19#include <linux/platform_device.h>
20#include <linux/regmap.h>
21#include <linux/regulator/consumer.h>
22
23#define CPCAP_LED_NO_CURRENT 0x0001
24
25struct cpcap_led_info {
26 u16 reg;
27 u16 mask;
28 u16 limit;
29 u16 init_mask;
30 u16 init_val;
31};
32
33static const struct cpcap_led_info cpcap_led_red = {
34 .reg = CPCAP_REG_REDC,
35 .mask = 0x03FF,
36 .limit = 31,
37};
38
39static const struct cpcap_led_info cpcap_led_green = {
40 .reg = CPCAP_REG_GREENC,
41 .mask = 0x03FF,
42 .limit = 31,
43};
44
45static const struct cpcap_led_info cpcap_led_blue = {
46 .reg = CPCAP_REG_BLUEC,
47 .mask = 0x03FF,
48 .limit = 31,
49};
50
51/* aux display light */
52static const struct cpcap_led_info cpcap_led_adl = {
53 .reg = CPCAP_REG_ADLC,
54 .mask = 0x000F,
55 .limit = 1,
56 .init_mask = 0x7FFF,
57 .init_val = 0x5FF0,
58};
59
60/* camera privacy led */
61static const struct cpcap_led_info cpcap_led_cp = {
62 .reg = CPCAP_REG_CLEDC,
63 .mask = 0x0007,
64 .limit = 1,
65 .init_mask = 0x03FF,
66 .init_val = 0x0008,
67};
68
69struct cpcap_led {
70 struct led_classdev led;
71 const struct cpcap_led_info *info;
72 struct device *dev;
73 struct regmap *regmap;
74 struct mutex update_lock;
75 struct regulator *vdd;
76 bool powered;
77
78 u32 current_limit;
79};
80
81static u16 cpcap_led_val(u8 current_limit, u8 duty_cycle)
82{
83 current_limit &= 0x1f; /* 5 bit */
84 duty_cycle &= 0x0f; /* 4 bit */
85
86 return current_limit << 4 | duty_cycle;
87}
88
89static int cpcap_led_set_power(struct cpcap_led *led, bool status)
90{
91 int err;
92
93 if (status == led->powered)
94 return 0;
95
96 if (status)
97 err = regulator_enable(led->vdd);
98 else
99 err = regulator_disable(led->vdd);
100
101 if (err) {
102 dev_err(led->dev, "regulator failure: %d", err);
103 return err;
104 }
105
106 led->powered = status;
107
108 return 0;
109}
110
111static int cpcap_led_set(struct led_classdev *ledc, enum led_brightness value)
112{
113 struct cpcap_led *led = container_of(ledc, struct cpcap_led, led);
114 int brightness;
115 int err;
116
117 mutex_lock(&led->update_lock);
118
119 if (value > LED_OFF) {
120 err = cpcap_led_set_power(led, true);
121 if (err)
122 goto exit;
123 }
124
125 if (value == LED_OFF) {
126 /* Avoid HW issue by turning off current before duty cycle */
127 err = regmap_update_bits(led->regmap,
128 led->info->reg, led->info->mask, CPCAP_LED_NO_CURRENT);
129 if (err) {
130 dev_err(led->dev, "regmap failed: %d", err);
131 goto exit;
132 }
133
134 brightness = cpcap_led_val(value, LED_OFF);
135 } else {
136 brightness = cpcap_led_val(value, LED_ON);
137 }
138
139 err = regmap_update_bits(led->regmap, led->info->reg, led->info->mask,
140 brightness);
141 if (err) {
142 dev_err(led->dev, "regmap failed: %d", err);
143 goto exit;
144 }
145
146 if (value == LED_OFF) {
147 err = cpcap_led_set_power(led, false);
148 if (err)
149 goto exit;
150 }
151
152exit:
153 mutex_unlock(&led->update_lock);
154 return err;
155}
156
157static const struct of_device_id cpcap_led_of_match[] = {
158 { .compatible = "motorola,cpcap-led-red", .data = &cpcap_led_red },
159 { .compatible = "motorola,cpcap-led-green", .data = &cpcap_led_green },
160 { .compatible = "motorola,cpcap-led-blue", .data = &cpcap_led_blue },
161 { .compatible = "motorola,cpcap-led-adl", .data = &cpcap_led_adl },
162 { .compatible = "motorola,cpcap-led-cp", .data = &cpcap_led_cp },
163 {},
164};
165MODULE_DEVICE_TABLE(of, cpcap_led_of_match);
166
167static int cpcap_led_probe(struct platform_device *pdev)
168{
169 const struct of_device_id *match;
170 struct cpcap_led *led;
171 int err;
172
173 match = of_match_device(of_match_ptr(cpcap_led_of_match), &pdev->dev);
174 if (!match || !match->data)
175 return -EINVAL;
176
177 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
178 if (!led)
179 return -ENOMEM;
180 platform_set_drvdata(pdev, led);
181 led->info = match->data;
182 led->dev = &pdev->dev;
183
184 if (led->info->reg == 0x0000) {
185 dev_err(led->dev, "Unsupported LED");
186 return -ENODEV;
187 }
188
189 led->regmap = dev_get_regmap(pdev->dev.parent, NULL);
190 if (!led->regmap)
191 return -ENODEV;
192
193 led->vdd = devm_regulator_get(&pdev->dev, "vdd");
194 if (IS_ERR(led->vdd)) {
195 err = PTR_ERR(led->vdd);
196 dev_err(led->dev, "Couldn't get regulator: %d", err);
197 return err;
198 }
199
200 err = device_property_read_string(&pdev->dev, "label", &led->led.name);
201 if (err) {
202 dev_err(led->dev, "Couldn't read LED label: %d", err);
203 return err;
204 }
205
206 if (led->info->init_mask) {
207 err = regmap_update_bits(led->regmap, led->info->reg,
208 led->info->init_mask, led->info->init_val);
209 if (err) {
210 dev_err(led->dev, "regmap failed: %d", err);
211 return err;
212 }
213 }
214
215 mutex_init(&led->update_lock);
216
217 led->led.max_brightness = led->info->limit;
218 led->led.brightness_set_blocking = cpcap_led_set;
219 err = devm_led_classdev_register(&pdev->dev, &led->led);
220 if (err) {
221 dev_err(led->dev, "Couldn't register LED: %d", err);
222 return err;
223 }
224
225 return 0;
226}
227
228static struct platform_driver cpcap_led_driver = {
229 .probe = cpcap_led_probe,
230 .driver = {
231 .name = "cpcap-led",
232 .of_match_table = cpcap_led_of_match,
233 },
234};
235module_platform_driver(cpcap_led_driver);
236
237MODULE_DESCRIPTION("CPCAP LED driver");
238MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>");
239MODULE_LICENSE("GPL");
drivers/leds/leds-gpio.c+6−6
@@ -77,7 +77,7 @@ static int gpio_blink_set(struct led_classdev *led_cdev, · 76 unmodified lines
77 77
78static int create_gpio_led(const struct gpio_led *template,78static int create_gpio_led(const struct gpio_led *template,
79 struct gpio_led_data *led_dat, struct device *parent,79 struct gpio_led_data *led_dat, struct device *parent,
80 gpio_blink_set_t blink_set)80 struct device_node *np, gpio_blink_set_t blink_set)
81{81{
82 int ret, state;82 int ret, state;
83 83
@@ -139,7 +139,7 @@ static int create_gpio_led(const struct gpio_led *template, · 55 unmodified lines
139 if (ret < 0)139 if (ret < 0)
140 return ret;140 return ret;
141 141
142 return devm_led_classdev_register(parent, &led_dat->cdev);142 return devm_of_led_classdev_register(parent, np, &led_dat->cdev);
143}143}
144 144
145struct gpio_leds_priv {145struct gpio_leds_priv {
@@ -208,7 +208,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) · 62 unmodified lines
208 if (fwnode_property_present(child, "panic-indicator"))208 if (fwnode_property_present(child, "panic-indicator"))
209 led.panic_indicator = 1;209 led.panic_indicator = 1;
210 210
211 ret = create_gpio_led(&led, led_dat, dev, NULL);211 ret = create_gpio_led(&led, led_dat, dev, np, NULL);
212 if (ret < 0) {212 if (ret < 0) {
213 fwnode_handle_put(child);213 fwnode_handle_put(child);
214 return ERR_PTR(ret);214 return ERR_PTR(ret);
@@ -242,9 +242,9 @@ static int gpio_led_probe(struct platform_device *pdev) · 27 unmodified lines
242 242
243 priv->num_leds = pdata->num_leds;243 priv->num_leds = pdata->num_leds;
244 for (i = 0; i < priv->num_leds; i++) {244 for (i = 0; i < priv->num_leds; i++) {
245 ret = create_gpio_led(&pdata->leds[i],245 ret = create_gpio_led(&pdata->leds[i], &priv->leds[i],
246 &priv->leds[i],246 &pdev->dev, NULL,
247 &pdev->dev, pdata->gpio_blink_set);247 pdata->gpio_blink_set);
248 if (ret < 0)248 if (ret < 0)
249 return ret;249 return ret;
250 }250 }
drivers/leds/leds-lp3952.c+4−14
@@ -10,7 +10,6 @@ · 9 unmodified lines
10 *10 *
11 */11 */
12 12
13#include <linux/acpi.h>
14#include <linux/delay.h>13#include <linux/delay.h>
15#include <linux/gpio.h>14#include <linux/gpio.h>
16#include <linux/i2c.h>15#include <linux/i2c.h>
@@ -103,10 +102,11 @@ static int lp3952_get_label(struct device *dev, const char *label, char *dest) · 86 unmodified lines
103 const char *str;102 const char *str;
104 103
105 ret = device_property_read_string(dev, label, &str);104 ret = device_property_read_string(dev, label, &str);
106 if (!ret)105 if (ret)
107 strncpy(dest, str, LP3952_LABEL_MAX_LEN);106 return ret;
108 107
109 return ret;108 strncpy(dest, str, LP3952_LABEL_MAX_LEN);
109 return 0;
110}110}
111 111
112static int lp3952_register_led_classdev(struct lp3952_led_array *priv)112static int lp3952_register_led_classdev(struct lp3952_led_array *priv)
@@ -276,19 +276,9 @@ static const struct i2c_device_id lp3952_id[] = { · 163 unmodified lines
276};276};
277MODULE_DEVICE_TABLE(i2c, lp3952_id);277MODULE_DEVICE_TABLE(i2c, lp3952_id);
278 278
279#ifdef CONFIG_ACPI
280static const struct acpi_device_id lp3952_acpi_match[] = {
281 {"TXNW3952", 0},
282 {}
283};
284
285MODULE_DEVICE_TABLE(acpi, lp3952_acpi_match);
286#endif
287
288static struct i2c_driver lp3952_i2c_driver = {279static struct i2c_driver lp3952_i2c_driver = {
289 .driver = {280 .driver = {
290 .name = LP3952_NAME,281 .name = LP3952_NAME,
291 .acpi_match_table = ACPI_PTR(lp3952_acpi_match),
292 },282 },
293 .probe = lp3952_probe,283 .probe = lp3952_probe,
294 .remove = lp3952_remove,284 .remove = lp3952_remove,
drivers/leds/leds-mt6323.c+502−0
@@ -0,0 +1,502 @@
1/*
2 * LED driver for Mediatek MT6323 PMIC
3 *
4 * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#include <linux/kernel.h>
17#include <linux/leds.h>
18#include <linux/mfd/mt6323/registers.h>
19#include <linux/mfd/mt6397/core.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/platform_device.h>
23#include <linux/regmap.h>
24
25/*
26 * Register field for MT6323_TOP_CKPDN0 to enable
27 * 32K clock common for LED device.
28 */
29#define MT6323_RG_DRV_32K_CK_PDN BIT(11)
30#define MT6323_RG_DRV_32K_CK_PDN_MASK BIT(11)
31
32/*
33 * Register field for MT6323_TOP_CKPDN2 to enable
34 * individual clock for LED device.
35 */
36#define MT6323_RG_ISINK_CK_PDN(i) BIT(i)
37#define MT6323_RG_ISINK_CK_PDN_MASK(i) BIT(i)
38
39/*
40 * Register field for MT6323_TOP_CKCON1 to select
41 * clock source.
42 */
43#define MT6323_RG_ISINK_CK_SEL_MASK(i) (BIT(10) << (i))
44
45/*
46 * Register for MT6323_ISINK_CON0 to setup the
47 * duty cycle of the blink.
48 */
49#define MT6323_ISINK_CON0(i) (MT6323_ISINK0_CON0 + 0x8 * (i))
50#define MT6323_ISINK_DIM_DUTY_MASK (0x1f << 8)
51#define MT6323_ISINK_DIM_DUTY(i) (((i) << 8) & \
52 MT6323_ISINK_DIM_DUTY_MASK)
53
54/* Register to setup the period of the blink. */
55#define MT6323_ISINK_CON1(i) (MT6323_ISINK0_CON1 + 0x8 * (i))
56#define MT6323_ISINK_DIM_FSEL_MASK (0xffff)
57#define MT6323_ISINK_DIM_FSEL(i) ((i) & MT6323_ISINK_DIM_FSEL_MASK)
58
59/* Register to control the brightness. */
60#define MT6323_ISINK_CON2(i) (MT6323_ISINK0_CON2 + 0x8 * (i))
61#define MT6323_ISINK_CH_STEP_SHIFT 12
62#define MT6323_ISINK_CH_STEP_MASK (0x7 << 12)
63#define MT6323_ISINK_CH_STEP(i) (((i) << 12) & \
64 MT6323_ISINK_CH_STEP_MASK)
65#define MT6323_ISINK_SFSTR0_TC_MASK (0x3 << 1)
66#define MT6323_ISINK_SFSTR0_TC(i) (((i) << 1) & \
67 MT6323_ISINK_SFSTR0_TC_MASK)
68#define MT6323_ISINK_SFSTR0_EN_MASK BIT(0)
69#define MT6323_ISINK_SFSTR0_EN BIT(0)
70
71/* Register to LED channel enablement. */
72#define MT6323_ISINK_CH_EN_MASK(i) BIT(i)
73#define MT6323_ISINK_CH_EN(i) BIT(i)
74
75#define MT6323_MAX_PERIOD 10000
76#define MT6323_MAX_LEDS 4
77#define MT6323_MAX_BRIGHTNESS 6
78#define MT6323_UNIT_DUTY 3125
79#define MT6323_CAL_HW_DUTY(o, p) DIV_ROUND_CLOSEST((o) * 100000ul,\
80 (p) * MT6323_UNIT_DUTY)
81
82struct mt6323_leds;
83
84/**
85 * struct mt6323_led - state container for the LED device
86 * @id: the identifier in MT6323 LED device
87 * @parent: the pointer to MT6323 LED controller
88 * @cdev: LED class device for this LED device
89 * @current_brightness: current state of the LED device
90 */
91struct mt6323_led {
92 int id;
93 struct mt6323_leds *parent;
94 struct led_classdev cdev;
95 enum led_brightness current_brightness;
96};
97
98/**
99 * struct mt6323_leds - state container for holding LED controller
100 * of the driver
101 * @dev: the device pointer
102 * @hw: the underlying hardware providing shared
103 * bus for the register operations
104 * @lock: the lock among process context
105 * @led: the array that contains the state of individual
106 * LED device
107 */
108struct mt6323_leds {
109 struct device *dev;
110 struct mt6397_chip *hw;
111 /* protect among process context */
112 struct mutex lock;
113 struct mt6323_led *led[MT6323_MAX_LEDS];
114};
115
116static int mt6323_led_hw_brightness(struct led_classdev *cdev,
117 enum led_brightness brightness)
118{
119 struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
120 struct mt6323_leds *leds = led->parent;
121 struct regmap *regmap = leds->hw->regmap;
122 u32 con2_mask = 0, con2_val = 0;
123 int ret;
124
125 /*
126 * Setup current output for the corresponding
127 * brightness level.
128 */
129 con2_mask |= MT6323_ISINK_CH_STEP_MASK |
130 MT6323_ISINK_SFSTR0_TC_MASK |
131 MT6323_ISINK_SFSTR0_EN_MASK;
132 con2_val |= MT6323_ISINK_CH_STEP(brightness - 1) |
133 MT6323_ISINK_SFSTR0_TC(2) |
134 MT6323_ISINK_SFSTR0_EN;
135
136 ret = regmap_update_bits(regmap, MT6323_ISINK_CON2(led->id),
137 con2_mask, con2_val);
138 return ret;
139}
140
141static int mt6323_led_hw_off(struct led_classdev *cdev)
142{
143 struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
144 struct mt6323_leds *leds = led->parent;
145 struct regmap *regmap = leds->hw->regmap;
146 unsigned int status;
147 int ret;
148
149 status = MT6323_ISINK_CH_EN(led->id);
150 ret = regmap_update_bits(regmap, MT6323_ISINK_EN_CTRL,
151 MT6323_ISINK_CH_EN_MASK(led->id), ~status);
152 if (ret < 0)
153 return ret;
154
155 usleep_range(100, 300);
156 ret = regmap_update_bits(regmap, MT6323_TOP_CKPDN2,
157 MT6323_RG_ISINK_CK_PDN_MASK(led->id),
158 MT6323_RG_ISINK_CK_PDN(led->id));
159 if (ret < 0)
160 return ret;
161
162 return 0;
163}
164
165static enum led_brightness
166mt6323_get_led_hw_brightness(struct led_classdev *cdev)
167{
168 struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
169 struct mt6323_leds *leds = led->parent;
170 struct regmap *regmap = leds->hw->regmap;
171 unsigned int status;
172 int ret;
173
174 ret = regmap_read(regmap, MT6323_TOP_CKPDN2, &status);
175 if (ret < 0)
176 return ret;
177
178 if (status & MT6323_RG_ISINK_CK_PDN_MASK(led->id))
179 return 0;
180
181 ret = regmap_read(regmap, MT6323_ISINK_EN_CTRL, &status);
182 if (ret < 0)
183 return ret;
184
185 if (!(status & MT6323_ISINK_CH_EN(led->id)))
186 return 0;
187
188 ret = regmap_read(regmap, MT6323_ISINK_CON2(led->id), &status);
189 if (ret < 0)
190 return ret;
191
192 return ((status & MT6323_ISINK_CH_STEP_MASK)
193 >> MT6323_ISINK_CH_STEP_SHIFT) + 1;
194}
195
196static int mt6323_led_hw_on(struct led_classdev *cdev,
197 enum led_brightness brightness)
198{
199 struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
200 struct mt6323_leds *leds = led->parent;
201 struct regmap *regmap = leds->hw->regmap;
202 unsigned int status;
203 int ret;
204
205 /*
206 * Setup required clock source, enable the corresponding
207 * clock and channel and let work with continuous blink as
208 * the default.
209 */
210 ret = regmap_update_bits(regmap, MT6323_TOP_CKCON1,
211 MT6323_RG_ISINK_CK_SEL_MASK(led->id), 0);
212 if (ret < 0)
213 return ret;
214
215 status = MT6323_RG_ISINK_CK_PDN(led->id);
216 ret = regmap_update_bits(regmap, MT6323_TOP_CKPDN2,
217 MT6323_RG_ISINK_CK_PDN_MASK(led->id),
218 ~status);
219 if (ret < 0)
220 return ret;
221
222 usleep_range(100, 300);
223
224 ret = regmap_update_bits(regmap, MT6323_ISINK_EN_CTRL,
225 MT6323_ISINK_CH_EN_MASK(led->id),
226 MT6323_ISINK_CH_EN(led->id));
227 if (ret < 0)
228 return ret;
229
230 ret = mt6323_led_hw_brightness(cdev, brightness);
231 if (ret < 0)
232 return ret;
233
234 ret = regmap_update_bits(regmap, MT6323_ISINK_CON0(led->id),
235 MT6323_ISINK_DIM_DUTY_MASK,
236 MT6323_ISINK_DIM_DUTY(31));
237 if (ret < 0)
238 return ret;
239
240 ret = regmap_update_bits(regmap, MT6323_ISINK_CON1(led->id),
241 MT6323_ISINK_DIM_FSEL_MASK,
242 MT6323_ISINK_DIM_FSEL(1000));
243 if (ret < 0)
244 return ret;
245
246 return 0;
247}
248
249static int mt6323_led_set_blink(struct led_classdev *cdev,
250 unsigned long *delay_on,
251 unsigned long *delay_off)
252{
253 struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
254 struct mt6323_leds *leds = led->parent;
255 struct regmap *regmap = leds->hw->regmap;
256 unsigned long period;
257 u8 duty_hw;
258 int ret;
259
260 /*
261 * Units are in ms, if over the hardware able
262 * to support, fallback into software blink
263 */
264 period = *delay_on + *delay_off;
265
266 if (period > MT6323_MAX_PERIOD)
267 return -EINVAL;
268
269 /*
270 * LED subsystem requires a default user
271 * friendly blink pattern for the LED so using
272 * 1Hz duty cycle 50% here if without specific
273 * value delay_on and delay off being assigned.
274 */
275 if (!*delay_on && !*delay_off) {
276 *delay_on = 500;
277 *delay_off = 500;
278 }
279
280 /*
281 * Calculate duty_hw based on the percentage of period during
282 * which the led is ON.
283 */
284 duty_hw = MT6323_CAL_HW_DUTY(*delay_on, period);
285
286 /* hardware doesn't support zero duty cycle. */
287 if (!duty_hw)
288 return -EINVAL;
289
290 mutex_lock(&leds->lock);
291 /*
292 * Set max_brightness as the software blink behavior
293 * when no blink brightness.
294 */
295 if (!led->current_brightness) {
296 ret = mt6323_led_hw_on(cdev, cdev->max_brightness);
297 if (ret < 0)
298 goto out;
299 led->current_brightness = cdev->max_brightness;
300 }
301
302 ret = regmap_update_bits(regmap, MT6323_ISINK_CON0(led->id),
303 MT6323_ISINK_DIM_DUTY_MASK,
304 MT6323_ISINK_DIM_DUTY(duty_hw - 1));
305 if (ret < 0)
306 goto out;
307
308 ret = regmap_update_bits(regmap, MT6323_ISINK_CON1(led->id),
309 MT6323_ISINK_DIM_FSEL_MASK,
310 MT6323_ISINK_DIM_FSEL(period - 1));
311out:
312 mutex_unlock(&leds->lock);
313
314 return ret;
315}
316
317static int mt6323_led_set_brightness(struct led_classdev *cdev,
318 enum led_brightness brightness)
319{
320 struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
321 struct mt6323_leds *leds = led->parent;
322 int ret;
323
324 mutex_lock(&leds->lock);
325
326 if (!led->current_brightness && brightness) {
327 ret = mt6323_led_hw_on(cdev, brightness);
328 if (ret < 0)
329 goto out;
330 } else if (brightness) {
331 ret = mt6323_led_hw_brightness(cdev, brightness);
332 if (ret < 0)
333 goto out;
334 } else {
335 ret = mt6323_led_hw_off(cdev);
336 if (ret < 0)
337 goto out;
338 }
339
340 led->current_brightness = brightness;
341out:
342 mutex_unlock(&leds->lock);
343
344 return ret;
345}
346
347static int mt6323_led_set_dt_default(struct led_classdev *cdev,
348 struct device_node *np)
349{
350 struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
351 const char *state;
352 int ret = 0;
353
354 led->cdev.name = of_get_property(np, "label", NULL) ? : np->name;
355 led->cdev.default_trigger = of_get_property(np,
356 "linux,default-trigger",
357 NULL);
358
359 state = of_get_property(np, "default-state", NULL);
360 if (state) {
361 if (!strcmp(state, "keep")) {
362 ret = mt6323_get_led_hw_brightness(cdev);
363 if (ret < 0)
364 return ret;
365 led->current_brightness = ret;
366 ret = 0;
367 } else if (!strcmp(state, "on")) {
368 ret =
369 mt6323_led_set_brightness(cdev, cdev->max_brightness);
370 } else {
371 ret = mt6323_led_set_brightness(cdev, LED_OFF);
372 }
373 }
374
375 return ret;
376}
377
378static int mt6323_led_probe(struct platform_device *pdev)
379{
380 struct device *dev = &pdev->dev;
381 struct device_node *np = pdev->dev.of_node;
382 struct device_node *child;
383 struct mt6397_chip *hw = dev_get_drvdata(pdev->dev.parent);
384 struct mt6323_leds *leds;
385 struct mt6323_led *led;
386 int ret;
387 unsigned int status;
388 u32 reg;
389
390 leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL);
391 if (!leds)
392 return -ENOMEM;
393
394 platform_set_drvdata(pdev, leds);
395 leds->dev = dev;
396
397 /*
398 * leds->hw points to the underlying bus for the register
399 * controlled.
400 */
401 leds->hw = hw;
402 mutex_init(&leds->lock);
403
404 status = MT6323_RG_DRV_32K_CK_PDN;
405 ret = regmap_update_bits(leds->hw->regmap, MT6323_TOP_CKPDN0,
406 MT6323_RG_DRV_32K_CK_PDN_MASK, ~status);
407 if (ret < 0) {
408 dev_err(leds->dev,
409 "Failed to update MT6323_TOP_CKPDN0 Register\n");
410 return ret;
411 }
412
413 for_each_available_child_of_node(np, child) {
414 ret = of_property_read_u32(child, "reg", &reg);
415 if (ret) {
416 dev_err(dev, "Failed to read led 'reg' property\n");
417 goto put_child_node;
418 }
419
420 if (reg >= MT6323_MAX_LEDS || leds->led[reg]) {
421 dev_err(dev, "Invalid led reg %u\n", reg);
422 ret = -EINVAL;
423 goto put_child_node;
424 }
425
426 led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
427 if (!led) {
428 ret = -ENOMEM;
429 goto put_child_node;
430 }
431
432 leds->led[reg] = led;
433 leds->led[reg]->id = reg;
434 leds->led[reg]->cdev.max_brightness = MT6323_MAX_BRIGHTNESS;
435 leds->led[reg]->cdev.brightness_set_blocking =
436 mt6323_led_set_brightness;
437 leds->led[reg]->cdev.blink_set = mt6323_led_set_blink;
438 leds->led[reg]->cdev.brightness_get =
439 mt6323_get_led_hw_brightness;
440 leds->led[reg]->parent = leds;
441
442 ret = mt6323_led_set_dt_default(&leds->led[reg]->cdev, child);
443 if (ret < 0) {
444 dev_err(leds->dev,
445 "Failed to LED set default from devicetree\n");
446 goto put_child_node;
447 }
448
449 ret = devm_led_classdev_register(dev, &leds->led[reg]->cdev);
450 if (ret) {
451 dev_err(&pdev->dev, "Failed to register LED: %d\n",
452 ret);
453 goto put_child_node;
454 }
455 leds->led[reg]->cdev.dev->of_node = child;
456 }
457
458 return 0;
459
460put_child_node:
461 of_node_put(child);
462 return ret;
463}
464
465static int mt6323_led_remove(struct platform_device *pdev)
466{
467 struct mt6323_leds *leds = platform_get_drvdata(pdev);
468 int i;
469
470 /* Turn the LEDs off on driver removal. */
471 for (i = 0 ; leds->led[i] ; i++)
472 mt6323_led_hw_off(&leds->led[i]->cdev);
473
474 regmap_update_bits(leds->hw->regmap, MT6323_TOP_CKPDN0,
475 MT6323_RG_DRV_32K_CK_PDN_MASK,
476 MT6323_RG_DRV_32K_CK_PDN);
477
478 mutex_destroy(&leds->lock);
479
480 return 0;
481}
482
483static const struct of_device_id mt6323_led_dt_match[] = {
484 { .compatible = "mediatek,mt6323-led" },
485 {},
486};
487MODULE_DEVICE_TABLE(of, mt6323_led_dt_match);
488
489static struct platform_driver mt6323_led_driver = {
490 .probe = mt6323_led_probe,
491 .remove = mt6323_led_remove,
492 .driver = {
493 .name = "mt6323-led",
494 .of_match_table = mt6323_led_dt_match,
495 },
496};
497
498module_platform_driver(mt6323_led_driver);
499
500MODULE_DESCRIPTION("LED driver for Mediatek MT6323 PMIC");
501MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
502MODULE_LICENSE("GPL");
drivers/leds/leds-pca9532.c+26−1
@@ -254,6 +254,21 @@ static void pca9532_input_work(struct work_struct *work) · 253 unmodified lines
254 mutex_unlock(&data->update_lock);254 mutex_unlock(&data->update_lock);
255}255}
256 256
257static enum pca9532_state pca9532_getled(struct pca9532_led *led)
258{
259 struct i2c_client *client = led->client;
260 struct pca9532_data *data = i2c_get_clientdata(client);
261 u8 maxleds = data->chip_info->num_leds;
262 char reg;
263 enum pca9532_state ret;
264
265 mutex_lock(&data->update_lock);
266 reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id));
267 ret = reg >> LED_NUM(led->id)/2;
268 mutex_unlock(&data->update_lock);
269 return ret;
270}
271
257#ifdef CONFIG_LEDS_PCA9532_GPIO272#ifdef CONFIG_LEDS_PCA9532_GPIO
258static int pca9532_gpio_request_pin(struct gpio_chip *gc, unsigned offset)273static int pca9532_gpio_request_pin(struct gpio_chip *gc, unsigned offset)
259{274{
@@ -366,7 +381,10 @@ static int pca9532_configure(struct i2c_client *client, · 106 unmodified lines
366 gpios++;381 gpios++;
367 break;382 break;
368 case PCA9532_TYPE_LED:383 case PCA9532_TYPE_LED:
369 led->state = pled->state;384 if (pled->state == PCA9532_KEEP)
385 led->state = pca9532_getled(led);
386 else
387 led->state = pled->state;
370 led->name = pled->name;388 led->name = pled->name;
371 led->ldev.name = led->name;389 led->ldev.name = led->name;
372 led->ldev.default_trigger = pled->default_trigger;390 led->ldev.default_trigger = pled->default_trigger;
@@ -456,6 +474,7 @@ pca9532_of_populate_pdata(struct device *dev, struct device_node *np) · 83 unmodified lines
456 const struct of_device_id *match;474 const struct of_device_id *match;
457 int devid, maxleds;475 int devid, maxleds;
458 int i = 0;476 int i = 0;
477 const char *state;
459 478
460 match = of_match_device(of_pca9532_leds_match, dev);479 match = of_match_device(of_pca9532_leds_match, dev);
461 if (!match)480 if (!match)
@@ -475,6 +494,12 @@ pca9532_of_populate_pdata(struct device *dev, struct device_node *np) · 13 unmodified lines
475 of_property_read_u32(child, "type", &pdata->leds[i].type);494 of_property_read_u32(child, "type", &pdata->leds[i].type);
476 of_property_read_string(child, "linux,default-trigger",495 of_property_read_string(child, "linux,default-trigger",
477 &pdata->leds[i].default_trigger);496 &pdata->leds[i].default_trigger);
497 if (!of_property_read_string(child, "default-state", &state)) {
498 if (!strcmp(state, "on"))
499 pdata->leds[i].state = PCA9532_ON;
500 else if (!strcmp(state, "keep"))
501 pdata->leds[i].state = PCA9532_KEEP;
502 }
478 if (++i >= maxleds) {503 if (++i >= maxleds) {
479 of_node_put(child);504 of_node_put(child);
480 break;505 break;
drivers/leds/trigger/ledtrig-cpu.c+31−2
@@ -31,12 +31,16 @@ · 30 unmodified lines
31#define MAX_NAME_LEN 831#define MAX_NAME_LEN 8
32 32
33struct led_trigger_cpu {33struct led_trigger_cpu {
34 bool is_active;
34 char name[MAX_NAME_LEN];35 char name[MAX_NAME_LEN];
35 struct led_trigger *_trig;36 struct led_trigger *_trig;
36};37};
37 38
38static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig);39static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig);
39 40
41static struct led_trigger *trig_cpu_all;
42static atomic_t num_active_cpus = ATOMIC_INIT(0);
43
40/**44/**
41 * ledtrig_cpu - emit a CPU event as a trigger45 * ledtrig_cpu - emit a CPU event as a trigger
42 * @evt: CPU event to be emitted46 * @evt: CPU event to be emitted
@@ -47,26 +51,46 @@ static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); · 4 unmodified lines
47void ledtrig_cpu(enum cpu_led_event ledevt)51void ledtrig_cpu(enum cpu_led_event ledevt)
48{52{
49 struct led_trigger_cpu *trig = this_cpu_ptr(&cpu_trig);53 struct led_trigger_cpu *trig = this_cpu_ptr(&cpu_trig);
54 bool is_active = trig->is_active;
50 55
51 /* Locate the correct CPU LED */56 /* Locate the correct CPU LED */
52 switch (ledevt) {57 switch (ledevt) {
53 case CPU_LED_IDLE_END:58 case CPU_LED_IDLE_END:
54 case CPU_LED_START:59 case CPU_LED_START:
55 /* Will turn the LED on, max brightness */60 /* Will turn the LED on, max brightness */
56 led_trigger_event(trig->_trig, LED_FULL);61 is_active = true;
57 break;62 break;
58 63
59 case CPU_LED_IDLE_START:64 case CPU_LED_IDLE_START:
60 case CPU_LED_STOP:65 case CPU_LED_STOP:
61 case CPU_LED_HALTED:66 case CPU_LED_HALTED:
62 /* Will turn the LED off */67 /* Will turn the LED off */
63 led_trigger_event(trig->_trig, LED_OFF);68 is_active = false;
64 break;69 break;
65 70
66 default:71 default:
67 /* Will leave the LED as it is */72 /* Will leave the LED as it is */
68 break;73 break;
69 }74 }
75
76 if (is_active != trig->is_active) {
77 unsigned int active_cpus;
78 unsigned int total_cpus;
79
80 /* Update trigger state */
81 trig->is_active = is_active;
82 atomic_add(is_active ? 1 : -1, &num_active_cpus);
83 active_cpus = atomic_read(&num_active_cpus);
84 total_cpus = num_present_cpus();
85
86 led_trigger_event(trig->_trig,
87 is_active ? LED_FULL : LED_OFF);
88
89
90 led_trigger_event(trig_cpu_all,
91 DIV_ROUND_UP(LED_FULL * active_cpus, total_cpus));
92
93 }
70}94}
71EXPORT_SYMBOL(ledtrig_cpu);95EXPORT_SYMBOL(ledtrig_cpu);
72 96
@@ -112,6 +136,11 @@ static int __init ledtrig_cpu_init(void) · 39 unmodified lines
112 /* Supports up to 9999 cpu cores */136 /* Supports up to 9999 cpu cores */
113 BUILD_BUG_ON(CONFIG_NR_CPUS > 9999);137 BUILD_BUG_ON(CONFIG_NR_CPUS > 9999);
114 138
139 /*
140 * Registering a trigger for all CPUs.
141 */
142 led_trigger_register_simple("cpu", &trig_cpu_all);
143
115 /*144 /*
116 * Registering CPU led trigger for each CPU core here145 * Registering CPU led trigger for each CPU core here
117 * ignores CPU hotplug, but after this CPU hotplug works146 * ignores CPU hotplug, but after this CPU hotplug works
drivers/platform/x86/Kconfig+8−0
@@ -141,6 +141,14 @@ config DELL_WMI_AIO · 140 unmodified lines
141 To compile this driver as a module, choose M here: the module will141 To compile this driver as a module, choose M here: the module will
142 be called dell-wmi-aio.142 be called dell-wmi-aio.
143 143
144config DELL_WMI_LED
145 tristate "External LED on Dell Business Netbooks"
146 depends on LEDS_CLASS
147 depends on ACPI_WMI
148 help
149 This adds support for the Latitude 2100 and similar
150 notebooks that have an external LED.
151
144config DELL_SMO8800152config DELL_SMO8800
145 tristate "Dell Latitude freefall driver (ACPI SMO88XX)"153 tristate "Dell Latitude freefall driver (ACPI SMO88XX)"
146 depends on ACPI154 depends on ACPI
drivers/platform/x86/Makefile+1−0
@@ -15,6 +15,7 @@ obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o · 14 unmodified lines
15obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o15obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
16obj-$(CONFIG_DELL_WMI) += dell-wmi.o16obj-$(CONFIG_DELL_WMI) += dell-wmi.o
17obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o17obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
18obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o
18obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o19obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o
19obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o20obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o
20obj-$(CONFIG_ACER_WMI) += acer-wmi.o21obj-$(CONFIG_ACER_WMI) += acer-wmi.o
drivers/platform/x86/dell-laptop.c+28−0
@@ -29,6 +29,7 @@ · 28 unmodified lines
29#include <linux/mm.h>29#include <linux/mm.h>
30#include <linux/i8042.h>30#include <linux/i8042.h>
31#include <linux/debugfs.h>31#include <linux/debugfs.h>
32#include <linux/dell-led.h>
32#include <linux/seq_file.h>33#include <linux/seq_file.h>
33#include <acpi/video.h>34#include <acpi/video.h>
34#include "dell-rbtn.h"35#include "dell-rbtn.h"
@@ -42,6 +43,8 @@ · 7 unmodified lines
42#define KBD_LED_AUTO_50_TOKEN 0x02EB43#define KBD_LED_AUTO_50_TOKEN 0x02EB
43#define KBD_LED_AUTO_75_TOKEN 0x02EC44#define KBD_LED_AUTO_75_TOKEN 0x02EC
44#define KBD_LED_AUTO_100_TOKEN 0x02F645#define KBD_LED_AUTO_100_TOKEN 0x02F6
46#define GLOBAL_MIC_MUTE_ENABLE 0x0364
47#define GLOBAL_MIC_MUTE_DISABLE 0x0365
45 48
46struct quirk_entry {49struct quirk_entry {
47 u8 touchpad_led;50 u8 touchpad_led;
@@ -1978,6 +1981,31 @@ static void kbd_led_exit(void) · 1930 unmodified lines
1978 led_classdev_unregister(&kbd_led);1981 led_classdev_unregister(&kbd_led);
1979}1982}
1980 1983
1984int dell_micmute_led_set(int state)
1985{
1986 struct calling_interface_buffer *buffer;
1987 struct calling_interface_token *token;
1988
1989 if (state == 0)
1990 token = dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE);
1991 else if (state == 1)
1992 token = dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE);
1993 else
1994 return -EINVAL;
1995
1996 if (!token)
1997 return -ENODEV;
1998
1999 buffer = dell_smbios_get_buffer();
2000 buffer->input[0] = token->location;
2001 buffer->input[1] = token->value;
2002 dell_smbios_send_request(1, 0);
2003 dell_smbios_release_buffer();
2004
2005 return state;
2006}
2007EXPORT_SYMBOL_GPL(dell_micmute_led_set);
2008
1981static int __init dell_init(void)2009static int __init dell_init(void)
1982{2010{
1983 struct calling_interface_buffer *buffer;2011 struct calling_interface_buffer *buffer;
drivers/platform/x86/dell-wmi-led.crenamed from drivers/leds/dell-led.c+33−108
@@ -1,6 +1,4 @@
1/*1/*
2 * dell_led.c - Dell LED Driver
3 *
4 * Copyright (C) 2010 Dell Inc.2 * Copyright (C) 2010 Dell Inc.
5 * Louis Davis <louis_davis@dell.com>3 * Louis Davis <louis_davis@dell.com>
6 * Jim Dailey <jim_dailey@dell.com>4 * Jim Dailey <jim_dailey@dell.com>
@@ -15,16 +13,12 @@ · 8 unmodified lines
15#include <linux/leds.h>13#include <linux/leds.h>
16#include <linux/slab.h>14#include <linux/slab.h>
17#include <linux/module.h>15#include <linux/module.h>
18#include <linux/dmi.h>
19#include <linux/dell-led.h>
20#include "../platform/x86/dell-smbios.h"
21 16
22MODULE_AUTHOR("Louis Davis/Jim Dailey");17MODULE_AUTHOR("Louis Davis/Jim Dailey");
23MODULE_DESCRIPTION("Dell LED Control Driver");18MODULE_DESCRIPTION("Dell LED Control Driver");
24MODULE_LICENSE("GPL");19MODULE_LICENSE("GPL");
25 20
26#define DELL_LED_BIOS_GUID "F6E4FE6E-909D-47cb-8BAB-C9F6F2F8D396"21#define DELL_LED_BIOS_GUID "F6E4FE6E-909D-47cb-8BAB-C9F6F2F8D396"
27#define DELL_APP_GUID "A80593CE-A997-11DA-B012-B622A1EF5492"
28MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID);22MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID);
29 23
30/* Error Result Codes: */24/* Error Result Codes: */
@@ -43,53 +37,6 @@ MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID); · 12 unmodified lines
43#define CMD_LED_OFF 1737#define CMD_LED_OFF 17
44#define CMD_LED_BLINK 1838#define CMD_LED_BLINK 18
45 39
46#define GLOBAL_MIC_MUTE_ENABLE 0x364
47#define GLOBAL_MIC_MUTE_DISABLE 0x365
48
49static int dell_micmute_led_set(int state)
50{
51 struct calling_interface_buffer *buffer;
52 struct calling_interface_token *token;
53
54 if (!wmi_has_guid(DELL_APP_GUID))
55 return -ENODEV;
56
57 if (state == 0)
58 token = dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE);
59 else if (state == 1)
60 token = dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE);
61 else
62 return -EINVAL;
63
64 if (!token)
65 return -ENODEV;
66
67 buffer = dell_smbios_get_buffer();
68 buffer->input[0] = token->location;
69 buffer->input[1] = token->value;
70 dell_smbios_send_request(1, 0);
71 dell_smbios_release_buffer();
72
73 return state;
74}
75
76int dell_app_wmi_led_set(int whichled, int on)
77{
78 int state = 0;
79
80 switch (whichled) {
81 case DELL_LED_MICMUTE:
82 state = dell_micmute_led_set(on);
83 break;
84 default:
85 pr_warn("led type %x is not supported\n", whichled);
86 break;
87 }
88
89 return state;
90}
91EXPORT_SYMBOL_GPL(dell_app_wmi_led_set);
92
93struct bios_args {40struct bios_args {
94 unsigned char length;41 unsigned char length;
95 unsigned char result_code;42 unsigned char result_code;
@@ -99,37 +46,29 @@ struct bios_args { · 3 unmodified lines
99 unsigned char off_time;46 unsigned char off_time;
100};47};
101 48
102static int dell_led_perform_fn(u8 length,49static int dell_led_perform_fn(u8 length, u8 result_code, u8 device_id,
103 u8 result_code,50 u8 command, u8 on_time, u8 off_time)
104 u8 device_id,
105 u8 command,
106 u8 on_time,
107 u8 off_time)
108{51{
109 struct bios_args *bios_return;
110 u8 return_code;
111 union acpi_object *obj;
112 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };52 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
53 struct bios_args *bios_return;
113 struct acpi_buffer input;54 struct acpi_buffer input;
55 union acpi_object *obj;
114 acpi_status status;56 acpi_status status;
57 u8 return_code;
115 58
116 struct bios_args args;59 struct bios_args args = {
117 args.length = length;60 .length = length,
118 args.result_code = result_code;61 .result_code = result_code,
119 args.device_id = device_id;62 .device_id = device_id,
120 args.command = command;63 .command = command,
121 args.on_time = on_time;64 .on_time = on_time,
122 args.off_time = off_time;65 .off_time = off_time
66 };
123 67
124 input.length = sizeof(struct bios_args);68 input.length = sizeof(struct bios_args);
125 input.pointer = &args;69 input.pointer = &args;
126 70
127 status = wmi_evaluate_method(DELL_LED_BIOS_GUID,71 status = wmi_evaluate_method(DELL_LED_BIOS_GUID, 1, 1, &input, &output);
128 1,
129 1,
130 &input,
131 &output);
132
133 if (ACPI_FAILURE(status))72 if (ACPI_FAILURE(status))
134 return status;73 return status;
135 74
@@ -137,7 +76,7 @@ static int dell_led_perform_fn(u8 length, · 1 unmodified line
137 76
138 if (!obj)77 if (!obj)
139 return -EINVAL;78 return -EINVAL;
140 else if (obj->type != ACPI_TYPE_BUFFER) {79 if (obj->type != ACPI_TYPE_BUFFER) {
141 kfree(obj);80 kfree(obj);
142 return -EINVAL;81 return -EINVAL;
143 }82 }
@@ -170,8 +109,7 @@ static int led_off(void) · 26 unmodified lines
170 0); /* not used */109 0); /* not used */
171}110}
172 111
173static int led_blink(unsigned char on_eighths,112static int led_blink(unsigned char on_eighths, unsigned char off_eighths)
174 unsigned char off_eighths)
175{113{
176 return dell_led_perform_fn(5, /* Length of command */114 return dell_led_perform_fn(5, /* Length of command */
177 INTERFACE_ERROR, /* Init to INTERFACE_ERROR */115 INTERFACE_ERROR, /* Init to INTERFACE_ERROR */
@@ -182,7 +120,7 @@ static int led_blink(unsigned char on_eighths, · 4 unmodified lines
182}120}
183 121
184static void dell_led_set(struct led_classdev *led_cdev,122static void dell_led_set(struct led_classdev *led_cdev,
185 enum led_brightness value)123 enum led_brightness value)
186{124{
187 if (value == LED_OFF)125 if (value == LED_OFF)
188 led_off();126 led_off();
@@ -191,27 +129,22 @@ static void dell_led_set(struct led_classdev *led_cdev, · 2 unmodified lines
191}129}
192 130
193static int dell_led_blink(struct led_classdev *led_cdev,131static int dell_led_blink(struct led_classdev *led_cdev,
194 unsigned long *delay_on,132 unsigned long *delay_on, unsigned long *delay_off)
195 unsigned long *delay_off)
196{133{
197 unsigned long on_eighths;134 unsigned long on_eighths;
198 unsigned long off_eighths;135 unsigned long off_eighths;
199 136
200 /* The Dell LED delay is based on 125ms intervals.137 /*
201 Need to round up to next interval. */138 * The Dell LED delay is based on 125ms intervals.
139 * Need to round up to next interval.
140 */
202 141
203 on_eighths = (*delay_on + 124) / 125;142 on_eighths = DIV_ROUND_UP(*delay_on, 125);
204 if (0 == on_eighths)143 on_eighths = clamp_t(unsigned long, on_eighths, 1, 255);
205 on_eighths = 1;
206 if (on_eighths > 255)
207 on_eighths = 255;
208 *delay_on = on_eighths * 125;144 *delay_on = on_eighths * 125;
209 145
210 off_eighths = (*delay_off + 124) / 125;146 off_eighths = DIV_ROUND_UP(*delay_off, 125);
211 if (0 == off_eighths)147 off_eighths = clamp_t(unsigned long, off_eighths, 1, 255);
212 off_eighths = 1;
213 if (off_eighths > 255)
214 off_eighths = 255;
215 *delay_off = off_eighths * 125;148 *delay_off = off_eighths * 125;
216 149
217 led_blink(on_eighths, off_eighths);150 led_blink(on_eighths, off_eighths);
@@ -232,29 +165,21 @@ static int __init dell_led_init(void) · 14 unmodified lines
232{165{
233 int error = 0;166 int error = 0;
234 167
235 if (!wmi_has_guid(DELL_LED_BIOS_GUID) && !wmi_has_guid(DELL_APP_GUID))168 if (!wmi_has_guid(DELL_LED_BIOS_GUID))
236 return -ENODEV;169 return -ENODEV;
237 170
238 if (wmi_has_guid(DELL_LED_BIOS_GUID)) {171 error = led_off();
239 error = led_off();172 if (error != 0)
240 if (error != 0)173 return -ENODEV;
241 return -ENODEV;
242
243 error = led_classdev_register(NULL, &dell_led);
244 }
245 174
246 return error;175 return led_classdev_register(NULL, &dell_led);
247}176}
248 177
249static void __exit dell_led_exit(void)178static void __exit dell_led_exit(void)
250{179{
251 int error = 0;180 led_classdev_unregister(&dell_led);
252 181
253 if (wmi_has_guid(DELL_LED_BIOS_GUID)) {182 led_off();
254 error = led_off();
255 if (error == 0)
256 led_classdev_unregister(&dell_led);
257 }
258}183}
259 184
260module_init(dell_led_init);185module_init(dell_led_init);
include/linux/dell-led.h+1−5
@@ -1,10 +1,6 @@
1#ifndef __DELL_LED_H__1#ifndef __DELL_LED_H__
2#define __DELL_LED_H__2#define __DELL_LED_H__
3 3
4enum {4int dell_micmute_led_set(int on);
5 DELL_LED_MICMUTE,
6};
7
8int dell_app_wmi_led_set(int whichled, int on);
9 5
10#endif6#endif
include/linux/leds-pca9532.h+2−2
@@ -22,7 +22,8 @@ enum pca9532_state { · 21 unmodified lines
22 PCA9532_OFF = 0x0,22 PCA9532_OFF = 0x0,
23 PCA9532_ON = 0x1,23 PCA9532_ON = 0x1,
24 PCA9532_PWM0 = 0x2,24 PCA9532_PWM0 = 0x2,
25 PCA9532_PWM1 = 0x325 PCA9532_PWM1 = 0x3,
26 PCA9532_KEEP = 0xff,
26};27};
27 28
28struct pca9532_led {29struct pca9532_led {
@@ -44,4 +45,3 @@ struct pca9532_platform_data { · 15 unmodified lines
44};45};
45 46
46#endif /* __LINUX_PCA9532_H */47#endif /* __LINUX_PCA9532_H */
47
include/linux/leds.h+10−4
@@ -122,10 +122,16 @@ struct led_classdev { · 121 unmodified lines
122 struct mutex led_access;122 struct mutex led_access;
123};123};
124 124
125extern int led_classdev_register(struct device *parent,125extern int of_led_classdev_register(struct device *parent,
126 struct led_classdev *led_cdev);126 struct device_node *np,
127extern int devm_led_classdev_register(struct device *parent,127 struct led_classdev *led_cdev);
128 struct led_classdev *led_cdev);128#define led_classdev_register(parent, led_cdev) \
129 of_led_classdev_register(parent, NULL, led_cdev)
130extern int devm_of_led_classdev_register(struct device *parent,
131 struct device_node *np,
132 struct led_classdev *led_cdev);
133#define devm_led_classdev_register(parent, led_cdev) \
134 devm_of_led_classdev_register(parent, NULL, led_cdev)
129extern void led_classdev_unregister(struct led_classdev *led_cdev);135extern void led_classdev_unregister(struct led_classdev *led_cdev);
130extern void devm_led_classdev_unregister(struct device *parent,136extern void devm_led_classdev_unregister(struct device *parent,
131 struct led_classdev *led_cdev);137 struct led_classdev *led_cdev);
include/linux/mfd/motorola-cpcap.h+3−0
@@ -14,6 +14,9 @@ · 13 unmodified lines
14 * published by the Free Software Foundation.14 * published by the Free Software Foundation.
15 */15 */
16 16
17#include <linux/device.h>
18#include <linux/regmap.h>
19
17#define CPCAP_VENDOR_ST 020#define CPCAP_VENDOR_ST 0
18#define CPCAP_VENDOR_TI 121#define CPCAP_VENDOR_TI 1
19 22
sound/pci/hda/dell_wmi_helper.c+15−15
@@ -2,11 +2,11 @@ · 1 unmodified line
2 * to be included from codec driver2 * to be included from codec driver
3 */3 */
4 4
5#if IS_ENABLED(CONFIG_LEDS_DELL_NETBOOKS)5#if IS_ENABLED(CONFIG_DELL_LAPTOP)
6#include <linux/dell-led.h>6#include <linux/dell-led.h>
7 7
8static int dell_led_value;8static int dell_led_value;
9static int (*dell_led_set_func)(int, int);9static int (*dell_micmute_led_set_func)(int);
10static void (*dell_old_cap_hook)(struct hda_codec *,10static void (*dell_old_cap_hook)(struct hda_codec *,
11 struct snd_kcontrol *,11 struct snd_kcontrol *,
12 struct snd_ctl_elem_value *);12 struct snd_ctl_elem_value *);
@@ -18,7 +18,7 @@ static void update_dell_wmi_micmute_led(struct hda_codec *codec, · 5 unmodified lines
18 if (dell_old_cap_hook)18 if (dell_old_cap_hook)
19 dell_old_cap_hook(codec, kcontrol, ucontrol);19 dell_old_cap_hook(codec, kcontrol, ucontrol);
20 20
21 if (!ucontrol || !dell_led_set_func)21 if (!ucontrol || !dell_micmute_led_set_func)
22 return;22 return;
23 if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) {23 if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) {
24 /* TODO: How do I verify if it's a mono or stereo here? */24 /* TODO: How do I verify if it's a mono or stereo here? */
@@ -26,8 +26,8 @@ static void update_dell_wmi_micmute_led(struct hda_codec *codec, · 1 unmodified line
26 if (val == dell_led_value)26 if (val == dell_led_value)
27 return;27 return;
28 dell_led_value = val;28 dell_led_value = val;
29 if (dell_led_set_func)29 if (dell_micmute_led_set_func)
30 dell_led_set_func(DELL_LED_MICMUTE, dell_led_value);30 dell_micmute_led_set_func(dell_led_value);
31 }31 }
32}32}
33 33
@@ -39,15 +39,15 @@ static void alc_fixup_dell_wmi(struct hda_codec *codec, · 5 unmodified lines
39 bool removefunc = false;39 bool removefunc = false;
40 40
41 if (action == HDA_FIXUP_ACT_PROBE) {41 if (action == HDA_FIXUP_ACT_PROBE) {
42 if (!dell_led_set_func)42 if (!dell_micmute_led_set_func)
43 dell_led_set_func = symbol_request(dell_app_wmi_led_set);43 dell_micmute_led_set_func = symbol_request(dell_micmute_led_set);
44 if (!dell_led_set_func) {44 if (!dell_micmute_led_set_func) {
45 codec_warn(codec, "Failed to find dell wmi symbol dell_app_wmi_led_set\n");45 codec_warn(codec, "Failed to find dell wmi symbol dell_micmute_led_set\n");
46 return;46 return;
47 }47 }
48 48
49 removefunc = true;49 removefunc = true;
50 if (dell_led_set_func(DELL_LED_MICMUTE, false) >= 0) {50 if (dell_micmute_led_set_func(false) >= 0) {
51 dell_led_value = 0;51 dell_led_value = 0;
52 if (spec->gen.num_adc_nids > 1 && !spec->gen.dyn_adc_switch)52 if (spec->gen.num_adc_nids > 1 && !spec->gen.dyn_adc_switch)
53 codec_dbg(codec, "Skipping micmute LED control due to several ADCs");53 codec_dbg(codec, "Skipping micmute LED control due to several ADCs");
@@ -60,17 +60,17 @@ static void alc_fixup_dell_wmi(struct hda_codec *codec, · 6 unmodified lines
60 60
61 }61 }
62 62
63 if (dell_led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) {63 if (dell_micmute_led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) {
64 symbol_put(dell_app_wmi_led_set);64 symbol_put(dell_micmute_led_set);
65 dell_led_set_func = NULL;65 dell_micmute_led_set_func = NULL;
66 dell_old_cap_hook = NULL;66 dell_old_cap_hook = NULL;
67 }67 }
68}68}
69 69
70#else /* CONFIG_LEDS_DELL_NETBOOKS */70#else /* CONFIG_DELL_LAPTOP */
71static void alc_fixup_dell_wmi(struct hda_codec *codec,71static void alc_fixup_dell_wmi(struct hda_codec *codec,
72 const struct hda_fixup *fix, int action)72 const struct hda_fixup *fix, int action)
73{73{
74}74}
75 75
76#endif /* CONFIG_LEDS_DELL_NETBOOKS */76#endif /* CONFIG_DELL_LAPTOP */