diff options
| -rw-r--r-- | Documentation/acpi/dsd/leds.txt | 99 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/leds/leds-lm3532.txt | 101 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/mfd/ti-lmu.txt | 20 | ||||
| -rw-r--r-- | arch/arm/boot/dts/omap4-droid4-xt894.dts | 27 | ||||
| -rw-r--r-- | drivers/leds/Kconfig | 33 | ||||
| -rw-r--r-- | drivers/leds/Makefile | 1 | ||||
| -rw-r--r-- | drivers/leds/led-class.c | 1 | ||||
| -rw-r--r-- | drivers/leds/led-core.c | 5 | ||||
| -rw-r--r-- | drivers/leds/leds-as3645a.c | 93 | ||||
| -rw-r--r-- | drivers/leds/leds-blinkm.c | 1 | ||||
| -rw-r--r-- | drivers/leds/leds-lm3532.c | 683 | ||||
| -rw-r--r-- | drivers/leds/leds-lt3593.c | 64 | ||||
| -rw-r--r-- | drivers/leds/leds-pca955x.c | 57 | ||||
| -rw-r--r-- | drivers/leds/leds-pca963x.c | 66 | ||||
| -rw-r--r-- | drivers/mfd/ti-lmu.c | 11 | ||||
| -rw-r--r-- | include/linux/mfd/ti-lmu-register.h | 44 | ||||
| -rw-r--r-- | include/linux/mfd/ti-lmu.h | 1 | ||||
| -rw-r--r-- | sound/usb/line6/toneport.c | 8 |
18 files changed, 1023 insertions, 292 deletions
diff --git a/Documentation/acpi/dsd/leds.txt b/Documentation/acpi/dsd/leds.txt new file mode 100644 index 000000000000..81a63af42ed2 --- /dev/null +++ b/Documentation/acpi/dsd/leds.txt | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | Describing and referring to LEDs in ACPI | ||
| 2 | |||
| 3 | Individual LEDs are described by hierarchical data extension [6] nodes under the | ||
| 4 | device node, the LED driver chip. The "reg" property in the LED specific nodes | ||
| 5 | tells the numerical ID of each individual LED output to which the LEDs are | ||
| 6 | connected. [3] The hierarchical data nodes are named "led@X", where X is the | ||
| 7 | number of the LED output. | ||
| 8 | |||
| 9 | Referring to LEDs in Device tree is documented in [4], in "flash-leds" property | ||
| 10 | documentation. In short, LEDs are directly referred to by using phandles. | ||
| 11 | |||
| 12 | While Device tree allows referring to any node in the tree[1], in ACPI | ||
| 13 | references are limited to device nodes only [2]. For this reason using the same | ||
| 14 | mechanism on ACPI is not possible. A mechanism to refer to non-device ACPI nodes | ||
| 15 | is documented in [7]. | ||
| 16 | |||
| 17 | ACPI allows (as does DT) using integer arguments after the reference. A | ||
| 18 | combination of the LED driver device reference and an integer argument, | ||
| 19 | referring to the "reg" property of the relevant LED, is used to identify | ||
| 20 | individual LEDs. The value of the "reg" property is a contract between the | ||
| 21 | firmware and software, it uniquely identifies the LED driver outputs. | ||
| 22 | |||
| 23 | Under the LED driver device, The first hierarchical data extension package list | ||
| 24 | entry shall contain the string "led@" followed by the number of the LED, | ||
| 25 | followed by the referred object name. That object shall be named "LED" followed | ||
| 26 | by the number of the LED. | ||
| 27 | |||
| 28 | An ASL example of a camera sensor device and a LED driver device for two LEDs. | ||
| 29 | Objects not relevant for LEDs or the references to them have been omitted. | ||
| 30 | |||
| 31 | Device (LED) | ||
| 32 | { | ||
| 33 | Name (_DSD, Package () { | ||
| 34 | ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), | ||
| 35 | Package () { | ||
| 36 | Package () { "led@0", LED0 }, | ||
| 37 | Package () { "led@1", LED1 }, | ||
| 38 | } | ||
| 39 | }) | ||
| 40 | Name (LED0, Package () { | ||
| 41 | ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), | ||
| 42 | Package () { | ||
| 43 | Package () { "reg", 0 }, | ||
| 44 | Package () { "flash-max-microamp", 1000000 }, | ||
| 45 | Package () { "flash-timeout-us", 200000 }, | ||
| 46 | Package () { "led-max-microamp", 100000 }, | ||
| 47 | Package () { "label", "white:flash" }, | ||
| 48 | } | ||
| 49 | }) | ||
| 50 | Name (LED1, Package () { | ||
| 51 | ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), | ||
| 52 | Package () { | ||
| 53 | Package () { "reg", 1 }, | ||
| 54 | Package () { "led-max-microamp", 10000 }, | ||
| 55 | Package () { "label", "red:indicator" }, | ||
| 56 | } | ||
| 57 | }) | ||
| 58 | } | ||
| 59 | |||
| 60 | Device (SEN) | ||
| 61 | { | ||
| 62 | Name (_DSD, Package () { | ||
| 63 | ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), | ||
| 64 | Package () { | ||
| 65 | Package () { | ||
| 66 | "flash-leds", | ||
| 67 | Package () { ^LED, "led@0", ^LED, "led@1" }, | ||
| 68 | } | ||
| 69 | } | ||
| 70 | }) | ||
| 71 | } | ||
| 72 | |||
| 73 | where | ||
| 74 | |||
| 75 | LED LED driver device | ||
| 76 | LED0 First LED | ||
| 77 | LED1 Second LED | ||
| 78 | SEN Camera sensor device (or another device the LED is | ||
| 79 | related to) | ||
| 80 | |||
| 81 | [1] Device tree. <URL:http://www.devicetree.org>, referenced 2019-02-21. | ||
| 82 | |||
| 83 | [2] Advanced Configuration and Power Interface Specification. | ||
| 84 | <URL:https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf>, | ||
| 85 | referenced 2019-02-21. | ||
| 86 | |||
| 87 | [3] Documentation/devicetree/bindings/leds/common.txt | ||
| 88 | |||
| 89 | [4] Documentation/devicetree/bindings/media/video-interfaces.txt | ||
| 90 | |||
| 91 | [5] Device Properties UUID For _DSD. | ||
| 92 | <URL:http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf>, | ||
| 93 | referenced 2019-02-21. | ||
| 94 | |||
| 95 | [6] Hierarchical Data Extension UUID For _DSD. | ||
| 96 | <URL:http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf>, | ||
| 97 | referenced 2019-02-21. | ||
| 98 | |||
| 99 | [7] Documentation/acpi/dsd/data-node-reference.txt | ||
diff --git a/Documentation/devicetree/bindings/leds/leds-lm3532.txt b/Documentation/devicetree/bindings/leds/leds-lm3532.txt new file mode 100644 index 000000000000..c087f85ddddc --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-lm3532.txt | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | * Texas Instruments - lm3532 White LED driver with ambient light sensing | ||
| 2 | capability. | ||
| 3 | |||
| 4 | The LM3532 provides the 3 high-voltage, low-side current sinks. The device is | ||
| 5 | programmable over an I2C-compatible interface and has independent | ||
| 6 | current control for all three channels. The adaptive current regulation | ||
| 7 | method allows for different LED currents in each current sink thus allowing | ||
| 8 | for a wide variety of backlight and keypad applications. | ||
| 9 | |||
| 10 | The main features of the LM3532 include dual ambient light sensor inputs | ||
| 11 | each with 32 internal voltage setting resistors, 8-bit logarithmic and linear | ||
| 12 | brightness control, dual external PWM brightness control inputs, and up to | ||
| 13 | 1000:1 dimming ratio with programmable fade in and fade out settings. | ||
| 14 | |||
| 15 | Required properties: | ||
| 16 | - compatible : "ti,lm3532" | ||
| 17 | - reg : I2C slave address | ||
| 18 | - #address-cells : 1 | ||
| 19 | - #size-cells : 0 | ||
| 20 | |||
| 21 | Optional properties: | ||
| 22 | - enable-gpios : gpio pin to enable (active high)/disable the device. | ||
| 23 | - ramp-up-us - The Run time ramp rates/step are from one current | ||
| 24 | set-point to another after the device has reached its | ||
| 25 | initial target set point from turn-on | ||
| 26 | - ramp-down-us - The Run time ramp rates/step are from one current | ||
| 27 | set-point to another after the device has reached its | ||
| 28 | initial target set point from turn-on | ||
| 29 | Range for ramp settings: 8us - 65536us | ||
| 30 | |||
| 31 | Optional properties if ALS mode is used: | ||
| 32 | - ti,als-vmin - Minimum ALS voltage defined in Volts | ||
| 33 | - ti,als-vmax - Maximum ALS voltage defined in Volts | ||
| 34 | Per the data sheet the max ALS voltage is 2V and the min is 0V | ||
| 35 | |||
| 36 | - ti,als1-imp-sel - ALS1 impedance resistor selection in Ohms | ||
| 37 | - ti,als2-imp-sel - ALS2 impedance resistor selection in Ohms | ||
| 38 | Range for impedance select: 37000 Ohms - 1190 Ohms | ||
| 39 | Values above 37kohms will be set to the "High Impedance" setting | ||
| 40 | |||
| 41 | - ti,als-avrg-time-us - Determines the length of time the device needs to | ||
| 42 | average the two ALS inputs. This is only used if | ||
| 43 | the input mode is LM3532_ALS_INPUT_AVRG. | ||
| 44 | Range: 17920us - 2293760us | ||
| 45 | - ti,als-input-mode - Determines how the device uses the attached ALS | ||
| 46 | devices. | ||
| 47 | 0x00 - ALS1 and ALS2 input average | ||
| 48 | 0x01 - ALS1 Input | ||
| 49 | 0x02 - ALS2 Input | ||
| 50 | 0x03 - Max of ALS1 and ALS2 | ||
| 51 | |||
| 52 | Required child properties: | ||
| 53 | - reg : Indicates control bank the LED string is controlled by | ||
| 54 | - led-sources : see Documentation/devicetree/bindings/leds/common.txt | ||
| 55 | - ti,led-mode : Defines if the LED strings are manually controlled or | ||
| 56 | if the LED strings are controlled by the ALS. | ||
| 57 | 0x00 - LED strings are I2C controlled via full scale | ||
| 58 | brightness control register | ||
| 59 | 0x01 - LED strings are ALS controlled | ||
| 60 | |||
| 61 | Optional LED child properties: | ||
| 62 | - label : see Documentation/devicetree/bindings/leds/common.txt | ||
| 63 | - linux,default-trigger : | ||
| 64 | see Documentation/devicetree/bindings/leds/common.txt | ||
| 65 | |||
| 66 | Example: | ||
| 67 | led-controller@38 { | ||
| 68 | compatible = "ti,lm3532"; | ||
| 69 | #address-cells = <1>; | ||
| 70 | #size-cells = <0>; | ||
| 71 | reg = <0x38>; | ||
| 72 | |||
| 73 | enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>; | ||
| 74 | ramp-up-us = <1024>; | ||
| 75 | ramp-down-us = <65536>; | ||
| 76 | |||
| 77 | ti,als-vmin = <0>; | ||
| 78 | ti,als-vmax = <2000>; | ||
| 79 | ti,als1-imp-sel = <4110>; | ||
| 80 | ti,als2-imp-sel = <2180>; | ||
| 81 | ti,als-avrg-time-us = <17920>; | ||
| 82 | ti,als-input-mode = <0x00>; | ||
| 83 | |||
| 84 | led@0 { | ||
| 85 | reg = <0>; | ||
| 86 | led-sources = <2>; | ||
| 87 | ti,led-mode = <1>; | ||
| 88 | label = ":backlight"; | ||
| 89 | linux,default-trigger = "backlight"; | ||
| 90 | }; | ||
| 91 | |||
| 92 | led@1 { | ||
| 93 | reg = <1>; | ||
| 94 | led-sources = <1>; | ||
| 95 | ti,led-mode = <0>; | ||
| 96 | label = ":kbd_backlight"; | ||
| 97 | }; | ||
| 98 | }; | ||
| 99 | |||
| 100 | For more product information please see the links below: | ||
| 101 | http://www.ti.com/product/LM3532 | ||
diff --git a/Documentation/devicetree/bindings/mfd/ti-lmu.txt b/Documentation/devicetree/bindings/mfd/ti-lmu.txt index c885cf89b8ce..980394d701a7 100644 --- a/Documentation/devicetree/bindings/mfd/ti-lmu.txt +++ b/Documentation/devicetree/bindings/mfd/ti-lmu.txt | |||
| @@ -4,7 +4,6 @@ TI LMU driver supports lighting devices below. | |||
| 4 | 4 | ||
| 5 | Name Child nodes | 5 | Name Child nodes |
| 6 | ------ --------------------------------- | 6 | ------ --------------------------------- |
| 7 | LM3532 Backlight | ||
| 8 | LM3631 Backlight and regulator | 7 | LM3631 Backlight and regulator |
| 9 | LM3632 Backlight and regulator | 8 | LM3632 Backlight and regulator |
| 10 | LM3633 Backlight, LED and fault monitor | 9 | LM3633 Backlight, LED and fault monitor |
| @@ -13,7 +12,6 @@ TI LMU driver supports lighting devices below. | |||
| 13 | 12 | ||
| 14 | Required properties: | 13 | Required properties: |
| 15 | - compatible: Should be one of: | 14 | - compatible: Should be one of: |
| 16 | "ti,lm3532" | ||
| 17 | "ti,lm3631" | 15 | "ti,lm3631" |
| 18 | "ti,lm3632" | 16 | "ti,lm3632" |
| 19 | "ti,lm3633" | 17 | "ti,lm3633" |
| @@ -23,7 +21,6 @@ Required properties: | |||
| 23 | 0x11 for LM3632 | 21 | 0x11 for LM3632 |
| 24 | 0x29 for LM3631 | 22 | 0x29 for LM3631 |
| 25 | 0x36 for LM3633, LM3697 | 23 | 0x36 for LM3633, LM3697 |
| 26 | 0x38 for LM3532 | ||
| 27 | 0x63 for LM3695 | 24 | 0x63 for LM3695 |
| 28 | 25 | ||
| 29 | Optional property: | 26 | Optional property: |
| @@ -47,23 +44,6 @@ Optional nodes: | |||
| 47 | [2] ../leds/leds-lm3633.txt | 44 | [2] ../leds/leds-lm3633.txt |
| 48 | [3] ../regulator/lm363x-regulator.txt | 45 | [3] ../regulator/lm363x-regulator.txt |
| 49 | 46 | ||
| 50 | lm3532@38 { | ||
| 51 | compatible = "ti,lm3532"; | ||
| 52 | reg = <0x38>; | ||
| 53 | |||
| 54 | enable-gpios = <&pioC 2 GPIO_ACTIVE_HIGH>; | ||
| 55 | |||
| 56 | backlight { | ||
| 57 | compatible = "ti,lm3532-backlight"; | ||
| 58 | |||
| 59 | lcd { | ||
| 60 | led-sources = <0 1 2>; | ||
| 61 | ramp-up-msec = <30>; | ||
| 62 | ramp-down-msec = <0>; | ||
| 63 | }; | ||
| 64 | }; | ||
| 65 | }; | ||
| 66 | |||
| 67 | lm3631@29 { | 47 | lm3631@29 { |
| 68 | compatible = "ti,lm3631"; | 48 | compatible = "ti,lm3631"; |
| 69 | reg = <0x29>; | 49 | reg = <0x29>; |
diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts index e21ec929f096..714863f8f261 100644 --- a/arch/arm/boot/dts/omap4-droid4-xt894.dts +++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts | |||
| @@ -214,7 +214,6 @@ | |||
| 214 | 214 | ||
| 215 | width-mm = <50>; | 215 | width-mm = <50>; |
| 216 | height-mm = <89>; | 216 | height-mm = <89>; |
| 217 | backlight = <&lcd_backlight>; | ||
| 218 | 217 | ||
| 219 | panel-timing { | 218 | panel-timing { |
| 220 | clock-frequency = <0>; /* Calculated by dsi */ | 219 | clock-frequency = <0>; /* Calculated by dsi */ |
| @@ -383,20 +382,30 @@ | |||
| 383 | }; | 382 | }; |
| 384 | 383 | ||
| 385 | &i2c1 { | 384 | &i2c1 { |
| 386 | lm3532@38 { | 385 | led-controller@38 { |
| 387 | compatible = "ti,lm3532"; | 386 | compatible = "ti,lm3532"; |
| 387 | #address-cells = <1>; | ||
| 388 | #size-cells = <0>; | ||
| 388 | reg = <0x38>; | 389 | reg = <0x38>; |
| 389 | 390 | ||
| 390 | enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>; | 391 | enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>; |
| 391 | 392 | ||
| 392 | lcd_backlight: backlight { | 393 | ramp-up-us = <1024>; |
| 393 | compatible = "ti,lm3532-backlight"; | 394 | ramp-down-us = <8193>; |
| 394 | 395 | ||
| 395 | lcd { | 396 | led@0 { |
| 396 | led-sources = <0 1 2>; | 397 | reg = <0>; |
| 397 | ramp-up-msec = <1>; | 398 | led-sources = <2>; |
| 398 | ramp-down-msec = <0>; | 399 | ti,led-mode = <0>; |
| 399 | }; | 400 | label = ":backlight"; |
| 401 | linux,default-trigger = "backlight"; | ||
| 402 | }; | ||
| 403 | |||
| 404 | led@1 { | ||
| 405 | reg = <1>; | ||
| 406 | led-sources = <1>; | ||
| 407 | ti,led-mode = <0>; | ||
| 408 | label = ":kbd_backlight"; | ||
| 400 | }; | 409 | }; |
| 401 | }; | 410 | }; |
| 402 | }; | 411 | }; |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index a72f97fca57b..f3000ccb8d35 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
| @@ -23,8 +23,8 @@ config LEDS_CLASS_FLASH | |||
| 23 | tristate "LED Flash Class Support" | 23 | tristate "LED Flash Class Support" |
| 24 | depends on LEDS_CLASS | 24 | depends on LEDS_CLASS |
| 25 | help | 25 | help |
| 26 | This option enables the flash led sysfs class in /sys/class/leds. | 26 | This option enables the flash LED sysfs class in /sys/class/leds. |
| 27 | It wrapps LED Class and adds flash LEDs specific sysfs attributes | 27 | It wraps LED Class and adds flash LEDs specific sysfs attributes |
| 28 | and kernel internal API to it. You'll need this to provide support | 28 | and kernel internal API to it. You'll need this to provide support |
| 29 | for the flash related features of a LED device. It can be built | 29 | for the flash related features of a LED device. It can be built |
| 30 | as a module. | 30 | as a module. |
| @@ -56,7 +56,7 @@ config LEDS_AAT1290 | |||
| 56 | depends on OF | 56 | depends on OF |
| 57 | depends on PINCTRL | 57 | depends on PINCTRL |
| 58 | help | 58 | help |
| 59 | This option enables support for the LEDs on the AAT1290. | 59 | This option enables support for the LEDs on the AAT1290. |
| 60 | 60 | ||
| 61 | config LEDS_AN30259A | 61 | config LEDS_AN30259A |
| 62 | tristate "LED support for Panasonic AN30259A" | 62 | tristate "LED support for Panasonic AN30259A" |
| @@ -138,6 +138,16 @@ config LEDS_LM3530 | |||
| 138 | controlled manually or using PWM input or using ambient | 138 | controlled manually or using PWM input or using ambient |
| 139 | light automatically. | 139 | light automatically. |
| 140 | 140 | ||
| 141 | config LEDS_LM3532 | ||
| 142 | tristate "LCD Backlight driver for LM3532" | ||
| 143 | depends on LEDS_CLASS | ||
| 144 | depends on I2C | ||
| 145 | help | ||
| 146 | This option enables support for the LCD backlight using | ||
| 147 | LM3532 ambient light sensor chip. This ALS chip can be | ||
| 148 | controlled manually or using PWM input or using ambient | ||
| 149 | light automatically. | ||
| 150 | |||
| 141 | config LEDS_LM3533 | 151 | config LEDS_LM3533 |
| 142 | tristate "LED support for LM3533" | 152 | tristate "LED support for LM3533" |
| 143 | depends on LEDS_CLASS | 153 | depends on LEDS_CLASS |
| @@ -413,13 +423,13 @@ config LEDS_CLEVO_MAIL | |||
| 413 | 423 | ||
| 414 | This module can drive the mail LED for the following notebooks: | 424 | This module can drive the mail LED for the following notebooks: |
| 415 | 425 | ||
| 416 | Clevo D400P | 426 | Clevo D400P |
| 417 | Clevo D410J | 427 | Clevo D410J |
| 418 | Clevo D410V | 428 | Clevo D410V |
| 419 | Clevo D400V/D470V (not tested, but might work) | 429 | Clevo D400V/D470V (not tested, but might work) |
| 420 | Clevo M540N | 430 | Clevo M540N |
| 421 | Clevo M5x0N (not tested, but might work) | 431 | Clevo M5x0N (not tested, but might work) |
| 422 | Positivo Mobile (Clevo M5x0V) | 432 | Positivo Mobile (Clevo M5x0V) |
| 423 | 433 | ||
| 424 | If your model is not listed here you can try the "nodetect" | 434 | If your model is not listed here you can try the "nodetect" |
| 425 | module parameter. | 435 | module parameter. |
| @@ -462,7 +472,7 @@ config LEDS_WM831X_STATUS | |||
| 462 | depends on MFD_WM831X | 472 | depends on MFD_WM831X |
| 463 | help | 473 | help |
| 464 | This option enables support for the status LEDs of the WM831x | 474 | This option enables support for the status LEDs of the WM831x |
| 465 | series of PMICs. | 475 | series of PMICs. |
| 466 | 476 | ||
| 467 | config LEDS_WM8350 | 477 | config LEDS_WM8350 |
| 468 | tristate "LED Support for WM8350 AudioPlus PMIC" | 478 | tristate "LED Support for WM8350 AudioPlus PMIC" |
| @@ -533,6 +543,7 @@ config LEDS_LT3593 | |||
| 533 | tristate "LED driver for LT3593 controllers" | 543 | tristate "LED driver for LT3593 controllers" |
| 534 | depends on LEDS_CLASS | 544 | depends on LEDS_CLASS |
| 535 | depends on GPIOLIB || COMPILE_TEST | 545 | depends on GPIOLIB || COMPILE_TEST |
| 546 | depends on OF | ||
| 536 | help | 547 | help |
| 537 | This option enables support for LEDs driven by a Linear Technology | 548 | This option enables support for LEDs driven by a Linear Technology |
| 538 | LT3593 controller. This controller uses a special one-wire pulse | 549 | LT3593 controller. This controller uses a special one-wire pulse |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 4c1b0054f379..7a8b1f55d459 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
| @@ -18,6 +18,7 @@ obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o | |||
| 18 | obj-$(CONFIG_LEDS_CPCAP) += leds-cpcap.o | 18 | obj-$(CONFIG_LEDS_CPCAP) += leds-cpcap.o |
| 19 | obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o | 19 | obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o |
| 20 | obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o | 20 | obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o |
| 21 | obj-$(CONFIG_LEDS_LM3532) += leds-lm3532.o | ||
| 21 | obj-$(CONFIG_LEDS_LM3533) += leds-lm3533.o | 22 | obj-$(CONFIG_LEDS_LM3533) += leds-lm3533.o |
| 22 | obj-$(CONFIG_LEDS_LM3642) += leds-lm3642.o | 23 | obj-$(CONFIG_LEDS_LM3642) += leds-lm3642.o |
| 23 | obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o | 24 | obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o |
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 3c7e3487b373..85848c5da705 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
| @@ -57,6 +57,7 @@ static ssize_t brightness_store(struct device *dev, | |||
| 57 | if (state == LED_OFF) | 57 | if (state == LED_OFF) |
| 58 | led_trigger_remove(led_cdev); | 58 | led_trigger_remove(led_cdev); |
| 59 | led_set_brightness(led_cdev, state); | 59 | led_set_brightness(led_cdev, state); |
| 60 | flush_work(&led_cdev->set_brightness_work); | ||
| 60 | 61 | ||
| 61 | ret = size; | 62 | ret = size; |
| 62 | unlock: | 63 | unlock: |
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index e3da7c03da1b..e9ae7f87ab90 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c | |||
| @@ -164,6 +164,11 @@ static void led_blink_setup(struct led_classdev *led_cdev, | |||
| 164 | unsigned long *delay_on, | 164 | unsigned long *delay_on, |
| 165 | unsigned long *delay_off) | 165 | unsigned long *delay_off) |
| 166 | { | 166 | { |
| 167 | /* | ||
| 168 | * If "set brightness to 0" is pending in workqueue, we don't | ||
| 169 | * want that to be reordered after blink_set() | ||
| 170 | */ | ||
| 171 | flush_work(&led_cdev->set_brightness_work); | ||
| 167 | if (!test_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags) && | 172 | if (!test_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags) && |
| 168 | led_cdev->blink_set && | 173 | led_cdev->blink_set && |
| 169 | !led_cdev->blink_set(led_cdev, delay_on, delay_off)) | 174 | !led_cdev->blink_set(led_cdev, delay_on, delay_off)) |
diff --git a/drivers/leds/leds-as3645a.c b/drivers/leds/leds-as3645a.c index 98a69b1a43f9..b0df514992e1 100644 --- a/drivers/leds/leds-as3645a.c +++ b/drivers/leds/leds-as3645a.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | #include <linux/leds.h> | 25 | #include <linux/leds.h> |
| 26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
| 28 | #include <linux/of.h> | 28 | #include <linux/property.h> |
| 29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 30 | 30 | ||
| 31 | #include <media/v4l2-flash-led-class.h> | 31 | #include <media/v4l2-flash-led-class.h> |
| @@ -148,8 +148,8 @@ struct as3645a { | |||
| 148 | struct v4l2_flash *vf; | 148 | struct v4l2_flash *vf; |
| 149 | struct v4l2_flash *vfind; | 149 | struct v4l2_flash *vfind; |
| 150 | 150 | ||
| 151 | struct device_node *flash_node; | 151 | struct fwnode_handle *flash_node; |
| 152 | struct device_node *indicator_node; | 152 | struct fwnode_handle *indicator_node; |
| 153 | 153 | ||
| 154 | struct as3645a_config cfg; | 154 | struct as3645a_config cfg; |
| 155 | 155 | ||
| @@ -493,30 +493,31 @@ static int as3645a_detect(struct as3645a *flash) | |||
| 493 | 493 | ||
| 494 | static int as3645a_parse_node(struct as3645a *flash, | 494 | static int as3645a_parse_node(struct as3645a *flash, |
| 495 | struct as3645a_names *names, | 495 | struct as3645a_names *names, |
| 496 | struct device_node *node) | 496 | struct fwnode_handle *fwnode) |
| 497 | { | 497 | { |
| 498 | struct as3645a_config *cfg = &flash->cfg; | 498 | struct as3645a_config *cfg = &flash->cfg; |
| 499 | struct device_node *child; | 499 | struct fwnode_handle *child; |
| 500 | const char *name; | 500 | const char *name; |
| 501 | int rval; | 501 | int rval; |
| 502 | 502 | ||
| 503 | for_each_child_of_node(node, child) { | 503 | fwnode_for_each_child_node(fwnode, child) { |
| 504 | u32 id = 0; | 504 | u32 id = 0; |
| 505 | 505 | ||
| 506 | of_property_read_u32(child, "reg", &id); | 506 | fwnode_property_read_u32(child, "reg", &id); |
| 507 | 507 | ||
| 508 | switch (id) { | 508 | switch (id) { |
| 509 | case AS_LED_FLASH: | 509 | case AS_LED_FLASH: |
| 510 | flash->flash_node = of_node_get(child); | 510 | flash->flash_node = child; |
| 511 | break; | 511 | break; |
| 512 | case AS_LED_INDICATOR: | 512 | case AS_LED_INDICATOR: |
| 513 | flash->indicator_node = of_node_get(child); | 513 | flash->indicator_node = child; |
| 514 | break; | 514 | break; |
| 515 | default: | 515 | default: |
| 516 | dev_warn(&flash->client->dev, | 516 | dev_warn(&flash->client->dev, |
| 517 | "unknown LED %u encountered, ignoring\n", id); | 517 | "unknown LED %u encountered, ignoring\n", id); |
| 518 | break; | 518 | break; |
| 519 | } | 519 | } |
| 520 | fwnode_handle_get(child); | ||
| 520 | } | 521 | } |
| 521 | 522 | ||
| 522 | if (!flash->flash_node) { | 523 | if (!flash->flash_node) { |
| @@ -524,42 +525,46 @@ static int as3645a_parse_node(struct as3645a *flash, | |||
| 524 | return -ENODEV; | 525 | return -ENODEV; |
| 525 | } | 526 | } |
| 526 | 527 | ||
| 527 | rval = of_property_read_string(flash->flash_node, "label", &name); | 528 | rval = fwnode_property_read_string(flash->flash_node, "label", &name); |
| 528 | if (!rval) | 529 | if (!rval) { |
| 529 | strlcpy(names->flash, name, sizeof(names->flash)); | 530 | strlcpy(names->flash, name, sizeof(names->flash)); |
| 530 | else | 531 | } else if (is_of_node(fwnode)) { |
| 531 | snprintf(names->flash, sizeof(names->flash), | 532 | snprintf(names->flash, sizeof(names->flash), |
| 532 | "%pOFn:flash", node); | 533 | "%pOFn:flash", to_of_node(fwnode)); |
| 534 | } else { | ||
| 535 | dev_err(&flash->client->dev, "flash node has no label!\n"); | ||
| 536 | return -EINVAL; | ||
| 537 | } | ||
| 533 | 538 | ||
| 534 | rval = of_property_read_u32(flash->flash_node, "flash-timeout-us", | 539 | rval = fwnode_property_read_u32(flash->flash_node, "flash-timeout-us", |
| 535 | &cfg->flash_timeout_us); | 540 | &cfg->flash_timeout_us); |
| 536 | if (rval < 0) { | 541 | if (rval < 0) { |
| 537 | dev_err(&flash->client->dev, | 542 | dev_err(&flash->client->dev, |
| 538 | "can't read flash-timeout-us property for flash\n"); | 543 | "can't read flash-timeout-us property for flash\n"); |
| 539 | goto out_err; | 544 | goto out_err; |
| 540 | } | 545 | } |
| 541 | 546 | ||
| 542 | rval = of_property_read_u32(flash->flash_node, "flash-max-microamp", | 547 | rval = fwnode_property_read_u32(flash->flash_node, "flash-max-microamp", |
| 543 | &cfg->flash_max_ua); | 548 | &cfg->flash_max_ua); |
| 544 | if (rval < 0) { | 549 | if (rval < 0) { |
| 545 | dev_err(&flash->client->dev, | 550 | dev_err(&flash->client->dev, |
| 546 | "can't read flash-max-microamp property for flash\n"); | 551 | "can't read flash-max-microamp property for flash\n"); |
| 547 | goto out_err; | 552 | goto out_err; |
| 548 | } | 553 | } |
| 549 | 554 | ||
| 550 | rval = of_property_read_u32(flash->flash_node, "led-max-microamp", | 555 | rval = fwnode_property_read_u32(flash->flash_node, "led-max-microamp", |
| 551 | &cfg->assist_max_ua); | 556 | &cfg->assist_max_ua); |
| 552 | if (rval < 0) { | 557 | if (rval < 0) { |
| 553 | dev_err(&flash->client->dev, | 558 | dev_err(&flash->client->dev, |
| 554 | "can't read led-max-microamp property for flash\n"); | 559 | "can't read led-max-microamp property for flash\n"); |
| 555 | goto out_err; | 560 | goto out_err; |
| 556 | } | 561 | } |
| 557 | 562 | ||
| 558 | of_property_read_u32(flash->flash_node, "voltage-reference", | 563 | fwnode_property_read_u32(flash->flash_node, "voltage-reference", |
| 559 | &cfg->voltage_reference); | 564 | &cfg->voltage_reference); |
| 560 | 565 | ||
| 561 | of_property_read_u32(flash->flash_node, "ams,input-max-microamp", | 566 | fwnode_property_read_u32(flash->flash_node, "ams,input-max-microamp", |
| 562 | &cfg->peak); | 567 | &cfg->peak); |
| 563 | cfg->peak = AS_PEAK_mA_TO_REG(cfg->peak); | 568 | cfg->peak = AS_PEAK_mA_TO_REG(cfg->peak); |
| 564 | 569 | ||
| 565 | if (!flash->indicator_node) { | 570 | if (!flash->indicator_node) { |
| @@ -568,15 +573,21 @@ static int as3645a_parse_node(struct as3645a *flash, | |||
| 568 | goto out_err; | 573 | goto out_err; |
| 569 | } | 574 | } |
| 570 | 575 | ||
| 571 | rval = of_property_read_string(flash->indicator_node, "label", &name); | 576 | rval = fwnode_property_read_string(flash->indicator_node, "label", |
| 572 | if (!rval) | 577 | &name); |
| 578 | if (!rval) { | ||
| 573 | strlcpy(names->indicator, name, sizeof(names->indicator)); | 579 | strlcpy(names->indicator, name, sizeof(names->indicator)); |
| 574 | else | 580 | } else if (is_of_node(fwnode)) { |
| 575 | snprintf(names->indicator, sizeof(names->indicator), | 581 | snprintf(names->indicator, sizeof(names->indicator), |
| 576 | "%pOFn:indicator", node); | 582 | "%pOFn:indicator", to_of_node(fwnode)); |
| 583 | } else { | ||
| 584 | dev_err(&flash->client->dev, "indicator node has no label!\n"); | ||
| 585 | return -EINVAL; | ||
| 586 | } | ||
| 577 | 587 | ||
| 578 | rval = of_property_read_u32(flash->indicator_node, "led-max-microamp", | 588 | rval = fwnode_property_read_u32(flash->indicator_node, |
| 579 | &cfg->indicator_max_ua); | 589 | "led-max-microamp", |
| 590 | &cfg->indicator_max_ua); | ||
| 580 | if (rval < 0) { | 591 | if (rval < 0) { |
| 581 | dev_err(&flash->client->dev, | 592 | dev_err(&flash->client->dev, |
| 582 | "can't read led-max-microamp property for indicator\n"); | 593 | "can't read led-max-microamp property for indicator\n"); |
| @@ -586,8 +597,8 @@ static int as3645a_parse_node(struct as3645a *flash, | |||
| 586 | return 0; | 597 | return 0; |
| 587 | 598 | ||
| 588 | out_err: | 599 | out_err: |
| 589 | of_node_put(flash->flash_node); | 600 | fwnode_handle_put(flash->flash_node); |
| 590 | of_node_put(flash->indicator_node); | 601 | fwnode_handle_put(flash->indicator_node); |
| 591 | 602 | ||
| 592 | return rval; | 603 | return rval; |
| 593 | } | 604 | } |
| @@ -668,14 +679,14 @@ static int as3645a_v4l2_setup(struct as3645a *flash) | |||
| 668 | strlcpy(cfgind.dev_name, flash->iled_cdev.name, sizeof(cfg.dev_name)); | 679 | strlcpy(cfgind.dev_name, flash->iled_cdev.name, sizeof(cfg.dev_name)); |
| 669 | 680 | ||
| 670 | flash->vf = v4l2_flash_init( | 681 | flash->vf = v4l2_flash_init( |
| 671 | &flash->client->dev, of_fwnode_handle(flash->flash_node), | 682 | &flash->client->dev, flash->flash_node, &flash->fled, NULL, |
| 672 | &flash->fled, NULL, &cfg); | 683 | &cfg); |
| 673 | if (IS_ERR(flash->vf)) | 684 | if (IS_ERR(flash->vf)) |
| 674 | return PTR_ERR(flash->vf); | 685 | return PTR_ERR(flash->vf); |
| 675 | 686 | ||
| 676 | flash->vfind = v4l2_flash_indicator_init( | 687 | flash->vfind = v4l2_flash_indicator_init( |
| 677 | &flash->client->dev, of_fwnode_handle(flash->indicator_node), | 688 | &flash->client->dev, flash->indicator_node, &flash->iled_cdev, |
| 678 | &flash->iled_cdev, &cfgind); | 689 | &cfgind); |
| 679 | if (IS_ERR(flash->vfind)) { | 690 | if (IS_ERR(flash->vfind)) { |
| 680 | v4l2_flash_release(flash->vf); | 691 | v4l2_flash_release(flash->vf); |
| 681 | return PTR_ERR(flash->vfind); | 692 | return PTR_ERR(flash->vfind); |
| @@ -690,7 +701,7 @@ static int as3645a_probe(struct i2c_client *client) | |||
| 690 | struct as3645a *flash; | 701 | struct as3645a *flash; |
| 691 | int rval; | 702 | int rval; |
| 692 | 703 | ||
| 693 | if (client->dev.of_node == NULL) | 704 | if (!dev_fwnode(&client->dev)) |
| 694 | return -ENODEV; | 705 | return -ENODEV; |
| 695 | 706 | ||
| 696 | flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); | 707 | flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); |
| @@ -699,7 +710,7 @@ static int as3645a_probe(struct i2c_client *client) | |||
| 699 | 710 | ||
| 700 | flash->client = client; | 711 | flash->client = client; |
| 701 | 712 | ||
| 702 | rval = as3645a_parse_node(flash, &names, client->dev.of_node); | 713 | rval = as3645a_parse_node(flash, &names, dev_fwnode(&client->dev)); |
| 703 | if (rval < 0) | 714 | if (rval < 0) |
| 704 | return rval; | 715 | return rval; |
| 705 | 716 | ||
| @@ -731,8 +742,8 @@ out_mutex_destroy: | |||
| 731 | mutex_destroy(&flash->mutex); | 742 | mutex_destroy(&flash->mutex); |
| 732 | 743 | ||
| 733 | out_put_nodes: | 744 | out_put_nodes: |
| 734 | of_node_put(flash->flash_node); | 745 | fwnode_handle_put(flash->flash_node); |
| 735 | of_node_put(flash->indicator_node); | 746 | fwnode_handle_put(flash->indicator_node); |
| 736 | 747 | ||
| 737 | return rval; | 748 | return rval; |
| 738 | } | 749 | } |
| @@ -751,8 +762,8 @@ static int as3645a_remove(struct i2c_client *client) | |||
| 751 | 762 | ||
| 752 | mutex_destroy(&flash->mutex); | 763 | mutex_destroy(&flash->mutex); |
| 753 | 764 | ||
| 754 | of_node_put(flash->flash_node); | 765 | fwnode_handle_put(flash->flash_node); |
| 755 | of_node_put(flash->indicator_node); | 766 | fwnode_handle_put(flash->indicator_node); |
| 756 | 767 | ||
| 757 | return 0; | 768 | return 0; |
| 758 | } | 769 | } |
diff --git a/drivers/leds/leds-blinkm.c b/drivers/leds/leds-blinkm.c index 851c1920b63c..11b771fb933b 100644 --- a/drivers/leds/leds-blinkm.c +++ b/drivers/leds/leds-blinkm.c | |||
| @@ -594,7 +594,6 @@ static int blinkm_probe(struct i2c_client *client, | |||
| 594 | goto exit; | 594 | goto exit; |
| 595 | } | 595 | } |
| 596 | 596 | ||
| 597 | data->i2c_addr = 0x09; | ||
| 598 | data->i2c_addr = 0x08; | 597 | data->i2c_addr = 0x08; |
| 599 | /* i2c addr - use fake addr of 0x08 initially (real is 0x09) */ | 598 | /* i2c addr - use fake addr of 0x08 initially (real is 0x09) */ |
| 600 | data->fw_ver = 0xfe; | 599 | data->fw_ver = 0xfe; |
diff --git a/drivers/leds/leds-lm3532.c b/drivers/leds/leds-lm3532.c new file mode 100644 index 000000000000..180895b83b88 --- /dev/null +++ b/drivers/leds/leds-lm3532.c | |||
| @@ -0,0 +1,683 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | // TI LM3532 LED driver | ||
| 3 | // Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ | ||
| 4 | |||
| 5 | #include <linux/i2c.h> | ||
| 6 | #include <linux/leds.h> | ||
| 7 | #include <linux/slab.h> | ||
| 8 | #include <linux/regmap.h> | ||
| 9 | #include <linux/types.h> | ||
| 10 | #include <linux/regulator/consumer.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <uapi/linux/uleds.h> | ||
| 13 | #include <linux/gpio/consumer.h> | ||
| 14 | |||
| 15 | #define LM3532_NAME "lm3532-led" | ||
| 16 | #define LM3532_BL_MODE_MANUAL 0x00 | ||
| 17 | #define LM3532_BL_MODE_ALS 0x01 | ||
| 18 | |||
| 19 | #define LM3532_REG_OUTPUT_CFG 0x10 | ||
| 20 | #define LM3532_REG_STARTSHUT_RAMP 0x11 | ||
| 21 | #define LM3532_REG_RT_RAMP 0x12 | ||
| 22 | #define LM3532_REG_PWM_A_CFG 0x13 | ||
| 23 | #define LM3532_REG_PWM_B_CFG 0x14 | ||
| 24 | #define LM3532_REG_PWM_C_CFG 0x15 | ||
| 25 | #define LM3532_REG_ZONE_CFG_A 0x16 | ||
| 26 | #define LM3532_REG_CTRL_A_BRT 0x17 | ||
| 27 | #define LM3532_REG_ZONE_CFG_B 0x18 | ||
| 28 | #define LM3532_REG_CTRL_B_BRT 0x19 | ||
| 29 | #define LM3532_REG_ZONE_CFG_C 0x1a | ||
| 30 | #define LM3532_REG_CTRL_C_BRT 0x1b | ||
| 31 | #define LM3532_REG_ENABLE 0x1d | ||
| 32 | #define LM3532_ALS_CONFIG 0x23 | ||
| 33 | #define LM3532_REG_ZN_0_HI 0x60 | ||
| 34 | #define LM3532_REG_ZN_0_LO 0x61 | ||
| 35 | #define LM3532_REG_ZN_1_HI 0x62 | ||
| 36 | #define LM3532_REG_ZN_1_LO 0x63 | ||
| 37 | #define LM3532_REG_ZN_2_HI 0x64 | ||
| 38 | #define LM3532_REG_ZN_2_LO 0x65 | ||
| 39 | #define LM3532_REG_ZN_3_HI 0x66 | ||
| 40 | #define LM3532_REG_ZN_3_LO 0x67 | ||
| 41 | #define LM3532_REG_MAX 0x7e | ||
| 42 | |||
| 43 | /* Contorl Enable */ | ||
| 44 | #define LM3532_CTRL_A_ENABLE BIT(0) | ||
| 45 | #define LM3532_CTRL_B_ENABLE BIT(1) | ||
| 46 | #define LM3532_CTRL_C_ENABLE BIT(2) | ||
| 47 | |||
| 48 | /* PWM Zone Control */ | ||
| 49 | #define LM3532_PWM_ZONE_MASK 0x7c | ||
| 50 | #define LM3532_PWM_ZONE_0_EN BIT(2) | ||
| 51 | #define LM3532_PWM_ZONE_1_EN BIT(3) | ||
| 52 | #define LM3532_PWM_ZONE_2_EN BIT(4) | ||
| 53 | #define LM3532_PWM_ZONE_3_EN BIT(5) | ||
| 54 | #define LM3532_PWM_ZONE_4_EN BIT(6) | ||
| 55 | |||
| 56 | /* Brightness Configuration */ | ||
| 57 | #define LM3532_I2C_CTRL BIT(0) | ||
| 58 | #define LM3532_ALS_CTRL 0 | ||
| 59 | #define LM3532_LINEAR_MAP BIT(1) | ||
| 60 | #define LM3532_ZONE_MASK (BIT(2) | BIT(3) | BIT(4)) | ||
| 61 | #define LM3532_ZONE_0 0 | ||
| 62 | #define LM3532_ZONE_1 BIT(2) | ||
| 63 | #define LM3532_ZONE_2 BIT(3) | ||
| 64 | #define LM3532_ZONE_3 (BIT(2) | BIT(3)) | ||
| 65 | #define LM3532_ZONE_4 BIT(4) | ||
| 66 | |||
| 67 | #define LM3532_ENABLE_ALS BIT(3) | ||
| 68 | #define LM3532_ALS_SEL_SHIFT 6 | ||
| 69 | |||
| 70 | /* Zone Boundary Register */ | ||
| 71 | #define LM3532_ALS_WINDOW_mV 2000 | ||
| 72 | #define LM3532_ALS_ZB_MAX 4 | ||
| 73 | #define LM3532_ALS_OFFSET_mV 2 | ||
| 74 | |||
| 75 | #define LM3532_CONTROL_A 0 | ||
| 76 | #define LM3532_CONTROL_B 1 | ||
| 77 | #define LM3532_CONTROL_C 2 | ||
| 78 | #define LM3532_MAX_CONTROL_BANKS 3 | ||
| 79 | #define LM3532_MAX_LED_STRINGS 3 | ||
| 80 | |||
| 81 | #define LM3532_OUTPUT_CFG_MASK 0x3 | ||
| 82 | #define LM3532_BRT_VAL_ADJUST 8 | ||
| 83 | #define LM3532_RAMP_DOWN_SHIFT 3 | ||
| 84 | |||
| 85 | #define LM3532_NUM_RAMP_VALS 8 | ||
| 86 | #define LM3532_NUM_AVG_VALS 8 | ||
| 87 | #define LM3532_NUM_IMP_VALS 32 | ||
| 88 | |||
| 89 | /* | ||
| 90 | * struct lm3532_als_data | ||
| 91 | * @config - value of ALS configuration register | ||
| 92 | * @als1_imp_sel - value of ALS1 resistor select register | ||
| 93 | * @als2_imp_sel - value of ALS2 resistor select register | ||
| 94 | * @als_avrg_time - ALS averaging time | ||
| 95 | * @als_input_mode - ALS input mode for brightness control | ||
| 96 | * @als_vmin - Minimum ALS voltage | ||
| 97 | * @als_vmax - Maximum ALS voltage | ||
| 98 | * @zone_lo - values of ALS lo ZB(Zone Boundary) registers | ||
| 99 | * @zone_hi - values of ALS hi ZB(Zone Boundary) registers | ||
| 100 | */ | ||
| 101 | struct lm3532_als_data { | ||
| 102 | u8 config; | ||
| 103 | u8 als1_imp_sel; | ||
| 104 | u8 als2_imp_sel; | ||
| 105 | u8 als_avrg_time; | ||
| 106 | u8 als_input_mode; | ||
| 107 | u32 als_vmin; | ||
| 108 | u32 als_vmax; | ||
| 109 | u8 zones_lo[LM3532_ALS_ZB_MAX]; | ||
| 110 | u8 zones_hi[LM3532_ALS_ZB_MAX]; | ||
| 111 | }; | ||
| 112 | |||
| 113 | /** | ||
| 114 | * struct lm3532_led | ||
| 115 | * @led_dev: led class device | ||
| 116 | * @priv - Pointer the device data structure | ||
| 117 | * @control_bank - Control bank the LED is associated to | ||
| 118 | * @mode - Mode of the LED string | ||
| 119 | * @num_leds - Number of LED strings are supported in this array | ||
| 120 | * @led_strings - The LED strings supported in this array | ||
| 121 | * @label - LED label | ||
| 122 | */ | ||
| 123 | struct lm3532_led { | ||
| 124 | struct led_classdev led_dev; | ||
| 125 | struct lm3532_data *priv; | ||
| 126 | |||
| 127 | int control_bank; | ||
| 128 | int mode; | ||
| 129 | int num_leds; | ||
| 130 | u32 led_strings[LM3532_MAX_CONTROL_BANKS]; | ||
| 131 | char label[LED_MAX_NAME_SIZE]; | ||
| 132 | }; | ||
| 133 | |||
| 134 | /** | ||
| 135 | * struct lm3532_data | ||
| 136 | * @enable_gpio - Hardware enable gpio | ||
| 137 | * @regulator: regulator | ||
| 138 | * @client: i2c client | ||
| 139 | * @regmap - Devices register map | ||
| 140 | * @dev - Pointer to the devices device struct | ||
| 141 | * @lock - Lock for reading/writing the device | ||
| 142 | * @als_data - Pointer to the als data struct | ||
| 143 | * @runtime_ramp_up - Runtime ramp up setting | ||
| 144 | * @runtime_ramp_down - Runtime ramp down setting | ||
| 145 | * @leds - Array of LED strings | ||
| 146 | */ | ||
| 147 | struct lm3532_data { | ||
| 148 | struct gpio_desc *enable_gpio; | ||
| 149 | struct regulator *regulator; | ||
| 150 | struct i2c_client *client; | ||
| 151 | struct regmap *regmap; | ||
| 152 | struct device *dev; | ||
| 153 | struct mutex lock; | ||
| 154 | |||
| 155 | struct lm3532_als_data *als_data; | ||
| 156 | |||
| 157 | u32 runtime_ramp_up; | ||
| 158 | u32 runtime_ramp_down; | ||
| 159 | |||
| 160 | struct lm3532_led leds[]; | ||
| 161 | }; | ||
| 162 | |||
| 163 | static const struct reg_default lm3532_reg_defs[] = { | ||
| 164 | {LM3532_REG_OUTPUT_CFG, 0xe4}, | ||
| 165 | {LM3532_REG_STARTSHUT_RAMP, 0xc0}, | ||
| 166 | {LM3532_REG_RT_RAMP, 0xc0}, | ||
| 167 | {LM3532_REG_PWM_A_CFG, 0x82}, | ||
| 168 | {LM3532_REG_PWM_B_CFG, 0x82}, | ||
| 169 | {LM3532_REG_PWM_C_CFG, 0x82}, | ||
| 170 | {LM3532_REG_ZONE_CFG_A, 0xf1}, | ||
| 171 | {LM3532_REG_CTRL_A_BRT, 0xf3}, | ||
| 172 | {LM3532_REG_ZONE_CFG_B, 0xf1}, | ||
| 173 | {LM3532_REG_CTRL_B_BRT, 0xf3}, | ||
| 174 | {LM3532_REG_ZONE_CFG_C, 0xf1}, | ||
| 175 | {LM3532_REG_CTRL_C_BRT, 0xf3}, | ||
| 176 | {LM3532_REG_ENABLE, 0xf8}, | ||
| 177 | {LM3532_ALS_CONFIG, 0x44}, | ||
| 178 | {LM3532_REG_ZN_0_HI, 0x35}, | ||
| 179 | {LM3532_REG_ZN_0_LO, 0x33}, | ||
| 180 | {LM3532_REG_ZN_1_HI, 0x6a}, | ||
| 181 | {LM3532_REG_ZN_1_LO, 0x66}, | ||
| 182 | {LM3532_REG_ZN_2_HI, 0xa1}, | ||
| 183 | {LM3532_REG_ZN_2_LO, 0x99}, | ||
| 184 | {LM3532_REG_ZN_3_HI, 0xdc}, | ||
| 185 | {LM3532_REG_ZN_3_LO, 0xcc}, | ||
| 186 | }; | ||
| 187 | |||
| 188 | static const struct regmap_config lm3532_regmap_config = { | ||
| 189 | .reg_bits = 8, | ||
| 190 | .val_bits = 8, | ||
| 191 | |||
| 192 | .max_register = LM3532_REG_MAX, | ||
| 193 | .reg_defaults = lm3532_reg_defs, | ||
| 194 | .num_reg_defaults = ARRAY_SIZE(lm3532_reg_defs), | ||
| 195 | .cache_type = REGCACHE_FLAT, | ||
| 196 | }; | ||
| 197 | |||
| 198 | const static int als_imp_table[LM3532_NUM_IMP_VALS] = {37000, 18500, 12330, | ||
| 199 | 92500, 7400, 6170, 5290, | ||
| 200 | 4630, 4110, 3700, 3360, | ||
| 201 | 3080, 2850, 2640, 2440, | ||
| 202 | 2310, 2180, 2060, 1950, | ||
| 203 | 1850, 1760, 1680, 1610, | ||
| 204 | 1540, 1480, 1420, 1370, | ||
| 205 | 1320, 1280, 1230, 1190}; | ||
| 206 | static int lm3532_get_als_imp_index(int als_imped) | ||
| 207 | { | ||
| 208 | int i; | ||
| 209 | |||
| 210 | if (als_imped > als_imp_table[1]) | ||
| 211 | return 0; | ||
| 212 | |||
| 213 | if (als_imped < als_imp_table[LM3532_NUM_IMP_VALS - 1]) | ||
| 214 | return LM3532_NUM_IMP_VALS - 1; | ||
| 215 | |||
| 216 | for (i = 1; i < LM3532_NUM_IMP_VALS; i++) { | ||
| 217 | if (als_imped == als_imp_table[i]) | ||
| 218 | return i; | ||
| 219 | |||
| 220 | /* Find an approximate index by looking up the table */ | ||
| 221 | if (als_imped < als_imp_table[i - 1] && | ||
| 222 | als_imped > als_imp_table[i]) { | ||
| 223 | if (als_imped - als_imp_table[i - 1] < | ||
| 224 | als_imp_table[i] - als_imped) | ||
| 225 | return i + 1; | ||
| 226 | else | ||
| 227 | return i; | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | return -EINVAL; | ||
| 232 | } | ||
| 233 | |||
| 234 | static int lm3532_get_index(const int table[], int size, int value) | ||
| 235 | { | ||
| 236 | int i; | ||
| 237 | |||
| 238 | for (i = 1; i < size; i++) { | ||
| 239 | if (value == table[i]) | ||
| 240 | return i; | ||
| 241 | |||
| 242 | /* Find an approximate index by looking up the table */ | ||
| 243 | if (value > table[i - 1] && | ||
| 244 | value < table[i]) { | ||
| 245 | if (value - table[i - 1] < table[i] - value) | ||
| 246 | return i - 1; | ||
| 247 | else | ||
| 248 | return i; | ||
| 249 | } | ||
| 250 | } | ||
| 251 | |||
| 252 | return -EINVAL; | ||
| 253 | } | ||
| 254 | |||
| 255 | const static int als_avrg_table[LM3532_NUM_AVG_VALS] = {17920, 35840, 71680, | ||
| 256 | 1433360, 286720, 573440, | ||
| 257 | 1146880, 2293760}; | ||
| 258 | static int lm3532_get_als_avg_index(int avg_time) | ||
| 259 | { | ||
| 260 | if (avg_time <= als_avrg_table[0]) | ||
| 261 | return 0; | ||
| 262 | |||
| 263 | if (avg_time > als_avrg_table[LM3532_NUM_AVG_VALS - 1]) | ||
| 264 | return LM3532_NUM_AVG_VALS - 1; | ||
| 265 | |||
| 266 | return lm3532_get_index(&als_avrg_table[0], LM3532_NUM_AVG_VALS, | ||
| 267 | avg_time); | ||
| 268 | } | ||
| 269 | |||
| 270 | const static int ramp_table[LM3532_NUM_RAMP_VALS] = { 8, 1024, 2048, 4096, 8192, | ||
| 271 | 16384, 32768, 65536}; | ||
| 272 | static int lm3532_get_ramp_index(int ramp_time) | ||
| 273 | { | ||
| 274 | if (ramp_time <= ramp_table[0]) | ||
| 275 | return 0; | ||
| 276 | |||
| 277 | if (ramp_time > ramp_table[LM3532_NUM_RAMP_VALS - 1]) | ||
| 278 | return LM3532_NUM_RAMP_VALS - 1; | ||
| 279 | |||
| 280 | return lm3532_get_index(&ramp_table[0], LM3532_NUM_RAMP_VALS, | ||
| 281 | ramp_time); | ||
| 282 | } | ||
| 283 | |||
| 284 | static int lm3532_led_enable(struct lm3532_led *led_data) | ||
| 285 | { | ||
| 286 | int ctrl_en_val = BIT(led_data->control_bank); | ||
| 287 | int ret; | ||
| 288 | |||
| 289 | ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE, | ||
| 290 | ctrl_en_val, ctrl_en_val); | ||
| 291 | if (ret) { | ||
| 292 | dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret); | ||
| 293 | return ret; | ||
| 294 | } | ||
| 295 | |||
| 296 | return regulator_enable(led_data->priv->regulator); | ||
| 297 | } | ||
| 298 | |||
| 299 | static int lm3532_led_disable(struct lm3532_led *led_data) | ||
| 300 | { | ||
| 301 | int ctrl_en_val = BIT(led_data->control_bank); | ||
| 302 | int ret; | ||
| 303 | |||
| 304 | ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE, | ||
| 305 | ctrl_en_val, ~ctrl_en_val); | ||
| 306 | if (ret) { | ||
| 307 | dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret); | ||
| 308 | return ret; | ||
| 309 | } | ||
| 310 | |||
| 311 | return regulator_disable(led_data->priv->regulator); | ||
| 312 | } | ||
| 313 | |||
| 314 | static int lm3532_brightness_set(struct led_classdev *led_cdev, | ||
| 315 | enum led_brightness brt_val) | ||
| 316 | { | ||
| 317 | struct lm3532_led *led = | ||
| 318 | container_of(led_cdev, struct lm3532_led, led_dev); | ||
| 319 | u8 brightness_reg; | ||
| 320 | int ret; | ||
| 321 | |||
| 322 | mutex_lock(&led->priv->lock); | ||
| 323 | |||
| 324 | if (led->mode == LM3532_BL_MODE_ALS) { | ||
| 325 | if (brt_val > LED_OFF) | ||
| 326 | ret = lm3532_led_enable(led); | ||
| 327 | else | ||
| 328 | ret = lm3532_led_disable(led); | ||
| 329 | |||
| 330 | goto unlock; | ||
| 331 | } | ||
| 332 | |||
| 333 | if (brt_val == LED_OFF) { | ||
| 334 | ret = lm3532_led_disable(led); | ||
| 335 | goto unlock; | ||
| 336 | } | ||
| 337 | |||
| 338 | ret = lm3532_led_enable(led); | ||
| 339 | if (ret) | ||
| 340 | goto unlock; | ||
| 341 | |||
| 342 | brightness_reg = LM3532_REG_CTRL_A_BRT + led->control_bank * 2; | ||
| 343 | brt_val = brt_val / LM3532_BRT_VAL_ADJUST; | ||
| 344 | |||
| 345 | ret = regmap_write(led->priv->regmap, brightness_reg, brt_val); | ||
| 346 | |||
| 347 | unlock: | ||
| 348 | mutex_unlock(&led->priv->lock); | ||
| 349 | return ret; | ||
| 350 | } | ||
| 351 | |||
| 352 | static int lm3532_init_registers(struct lm3532_led *led) | ||
| 353 | { | ||
| 354 | struct lm3532_data *drvdata = led->priv; | ||
| 355 | unsigned int runtime_ramp_val; | ||
| 356 | unsigned int output_cfg_val = 0; | ||
| 357 | unsigned int output_cfg_shift = 0; | ||
| 358 | unsigned int output_cfg_mask = 0; | ||
| 359 | int ret, i; | ||
| 360 | |||
| 361 | for (i = 0; i < led->num_leds; i++) { | ||
| 362 | output_cfg_shift = led->led_strings[i] * 2; | ||
| 363 | output_cfg_val |= (led->control_bank << output_cfg_shift); | ||
| 364 | output_cfg_mask |= LM3532_OUTPUT_CFG_MASK << output_cfg_shift; | ||
| 365 | } | ||
| 366 | |||
| 367 | ret = regmap_update_bits(drvdata->regmap, LM3532_REG_OUTPUT_CFG, | ||
| 368 | output_cfg_mask, output_cfg_val); | ||
| 369 | if (ret) | ||
| 370 | return ret; | ||
| 371 | |||
| 372 | runtime_ramp_val = drvdata->runtime_ramp_up | | ||
| 373 | (drvdata->runtime_ramp_down << LM3532_RAMP_DOWN_SHIFT); | ||
| 374 | |||
| 375 | return regmap_write(drvdata->regmap, LM3532_REG_RT_RAMP, | ||
| 376 | runtime_ramp_val); | ||
| 377 | } | ||
| 378 | |||
| 379 | static int lm3532_als_configure(struct lm3532_data *priv, | ||
| 380 | struct lm3532_led *led) | ||
| 381 | { | ||
| 382 | struct lm3532_als_data *als = priv->als_data; | ||
| 383 | u32 als_vmin, als_vmax, als_vstep; | ||
| 384 | int zone_reg = LM3532_REG_ZN_0_HI; | ||
| 385 | int brightnes_config_reg; | ||
| 386 | int ret; | ||
| 387 | int i; | ||
| 388 | |||
| 389 | als_vmin = als->als_vmin; | ||
| 390 | als_vmax = als->als_vmax; | ||
| 391 | |||
| 392 | als_vstep = (als_vmax - als_vmin) / ((LM3532_ALS_ZB_MAX + 1) * 2); | ||
| 393 | |||
| 394 | for (i = 0; i < LM3532_ALS_ZB_MAX; i++) { | ||
| 395 | als->zones_lo[i] = ((als_vmin + als_vstep + (i * als_vstep)) * | ||
| 396 | LED_FULL) / 1000; | ||
| 397 | als->zones_hi[i] = ((als_vmin + LM3532_ALS_OFFSET_mV + | ||
| 398 | als_vstep + (i * als_vstep)) * LED_FULL) / 1000; | ||
| 399 | |||
| 400 | zone_reg = LM3532_REG_ZN_0_HI + i * 2; | ||
| 401 | ret = regmap_write(priv->regmap, zone_reg, als->zones_lo[i]); | ||
| 402 | if (ret) | ||
| 403 | return ret; | ||
| 404 | |||
| 405 | zone_reg += 1; | ||
| 406 | ret = regmap_write(priv->regmap, zone_reg, als->zones_hi[i]); | ||
| 407 | if (ret) | ||
| 408 | return ret; | ||
| 409 | } | ||
| 410 | |||
| 411 | als->config = (als->als_avrg_time | (LM3532_ENABLE_ALS) | | ||
| 412 | (als->als_input_mode << LM3532_ALS_SEL_SHIFT)); | ||
| 413 | |||
| 414 | ret = regmap_write(priv->regmap, LM3532_ALS_CONFIG, als->config); | ||
| 415 | if (ret) | ||
| 416 | return ret; | ||
| 417 | |||
| 418 | brightnes_config_reg = LM3532_REG_ZONE_CFG_A + led->control_bank * 2; | ||
| 419 | |||
| 420 | return regmap_update_bits(priv->regmap, brightnes_config_reg, | ||
| 421 | LM3532_I2C_CTRL, LM3532_ALS_CTRL); | ||
| 422 | } | ||
| 423 | |||
| 424 | static int lm3532_parse_als(struct lm3532_data *priv) | ||
| 425 | { | ||
| 426 | struct lm3532_als_data *als; | ||
| 427 | int als_avg_time; | ||
| 428 | int als_impedance; | ||
| 429 | int ret; | ||
| 430 | |||
| 431 | als = devm_kzalloc(priv->dev, sizeof(*als), GFP_KERNEL); | ||
| 432 | if (als == NULL) | ||
| 433 | return -ENOMEM; | ||
| 434 | |||
| 435 | ret = device_property_read_u32(&priv->client->dev, "ti,als-vmin", | ||
| 436 | &als->als_vmin); | ||
| 437 | if (ret) | ||
| 438 | als->als_vmin = 0; | ||
| 439 | |||
| 440 | ret = device_property_read_u32(&priv->client->dev, "ti,als-vmax", | ||
| 441 | &als->als_vmax); | ||
| 442 | if (ret) | ||
| 443 | als->als_vmax = LM3532_ALS_WINDOW_mV; | ||
| 444 | |||
| 445 | if (als->als_vmax > LM3532_ALS_WINDOW_mV) { | ||
| 446 | ret = -EINVAL; | ||
| 447 | return ret; | ||
| 448 | } | ||
| 449 | |||
| 450 | ret = device_property_read_u32(&priv->client->dev, "ti,als1-imp-sel", | ||
| 451 | &als_impedance); | ||
| 452 | if (ret) | ||
| 453 | als->als1_imp_sel = 0; | ||
| 454 | else | ||
| 455 | als->als1_imp_sel = lm3532_get_als_imp_index(als_impedance); | ||
| 456 | |||
| 457 | ret = device_property_read_u32(&priv->client->dev, "ti,als2-imp-sel", | ||
| 458 | &als_impedance); | ||
| 459 | if (ret) | ||
| 460 | als->als2_imp_sel = 0; | ||
| 461 | else | ||
| 462 | als->als2_imp_sel = lm3532_get_als_imp_index(als_impedance); | ||
| 463 | |||
| 464 | ret = device_property_read_u32(&priv->client->dev, "ti,als-avrg-time-us", | ||
| 465 | &als_avg_time); | ||
| 466 | if (ret) | ||
| 467 | als->als_avrg_time = 0; | ||
| 468 | else | ||
| 469 | als->als_avrg_time = lm3532_get_als_avg_index(als_avg_time); | ||
| 470 | |||
| 471 | ret = device_property_read_u8(&priv->client->dev, "ti,als-input-mode", | ||
| 472 | &als->als_input_mode); | ||
| 473 | if (ret) | ||
| 474 | als->als_input_mode = 0; | ||
| 475 | |||
| 476 | if (als->als_input_mode > LM3532_BL_MODE_ALS) { | ||
| 477 | ret = -EINVAL; | ||
| 478 | return ret; | ||
| 479 | } | ||
| 480 | |||
| 481 | priv->als_data = als; | ||
| 482 | |||
| 483 | return ret; | ||
| 484 | } | ||
| 485 | |||
| 486 | static int lm3532_parse_node(struct lm3532_data *priv) | ||
| 487 | { | ||
| 488 | struct fwnode_handle *child = NULL; | ||
| 489 | struct lm3532_led *led; | ||
| 490 | const char *name; | ||
| 491 | int control_bank; | ||
| 492 | u32 ramp_time; | ||
| 493 | size_t i = 0; | ||
| 494 | int ret; | ||
| 495 | |||
| 496 | priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev, | ||
| 497 | "enable", GPIOD_OUT_LOW); | ||
| 498 | if (IS_ERR(priv->enable_gpio)) | ||
| 499 | priv->enable_gpio = NULL; | ||
| 500 | |||
| 501 | priv->regulator = devm_regulator_get(&priv->client->dev, "vin"); | ||
| 502 | if (IS_ERR(priv->regulator)) | ||
| 503 | priv->regulator = NULL; | ||
| 504 | |||
| 505 | ret = device_property_read_u32(&priv->client->dev, "ramp-up-us", | ||
| 506 | &ramp_time); | ||
| 507 | if (ret) | ||
| 508 | dev_info(&priv->client->dev, "ramp-up-ms property missing\n"); | ||
| 509 | else | ||
| 510 | priv->runtime_ramp_up = lm3532_get_ramp_index(ramp_time); | ||
| 511 | |||
| 512 | ret = device_property_read_u32(&priv->client->dev, "ramp-down-us", | ||
| 513 | &ramp_time); | ||
| 514 | if (ret) | ||
| 515 | dev_info(&priv->client->dev, "ramp-down-ms property missing\n"); | ||
| 516 | else | ||
| 517 | priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time); | ||
| 518 | |||
| 519 | device_for_each_child_node(priv->dev, child) { | ||
| 520 | led = &priv->leds[i]; | ||
| 521 | |||
| 522 | ret = fwnode_property_read_u32(child, "reg", &control_bank); | ||
| 523 | if (ret) { | ||
| 524 | dev_err(&priv->client->dev, "reg property missing\n"); | ||
| 525 | fwnode_handle_put(child); | ||
| 526 | goto child_out; | ||
| 527 | } | ||
| 528 | |||
| 529 | if (control_bank > LM3532_CONTROL_C) { | ||
| 530 | dev_err(&priv->client->dev, "Control bank invalid\n"); | ||
| 531 | continue; | ||
| 532 | } | ||
| 533 | |||
| 534 | led->control_bank = control_bank; | ||
| 535 | |||
| 536 | ret = fwnode_property_read_u32(child, "ti,led-mode", | ||
| 537 | &led->mode); | ||
| 538 | if (ret) { | ||
| 539 | dev_err(&priv->client->dev, "ti,led-mode property missing\n"); | ||
| 540 | fwnode_handle_put(child); | ||
| 541 | goto child_out; | ||
| 542 | } | ||
| 543 | |||
| 544 | if (led->mode == LM3532_BL_MODE_ALS) { | ||
| 545 | ret = lm3532_parse_als(priv); | ||
| 546 | if (ret) | ||
| 547 | dev_err(&priv->client->dev, "Failed to parse als\n"); | ||
| 548 | else | ||
| 549 | lm3532_als_configure(priv, led); | ||
| 550 | } | ||
| 551 | |||
| 552 | led->num_leds = fwnode_property_read_u32_array(child, | ||
| 553 | "led-sources", | ||
| 554 | NULL, 0); | ||
| 555 | |||
| 556 | if (led->num_leds > LM3532_MAX_LED_STRINGS) { | ||
| 557 | dev_err(&priv->client->dev, "To many LED string defined\n"); | ||
| 558 | continue; | ||
| 559 | } | ||
| 560 | |||
| 561 | ret = fwnode_property_read_u32_array(child, "led-sources", | ||
| 562 | led->led_strings, | ||
| 563 | led->num_leds); | ||
| 564 | if (ret) { | ||
| 565 | dev_err(&priv->client->dev, "led-sources property missing\n"); | ||
| 566 | fwnode_handle_put(child); | ||
| 567 | goto child_out; | ||
| 568 | } | ||
| 569 | |||
| 570 | fwnode_property_read_string(child, "linux,default-trigger", | ||
| 571 | &led->led_dev.default_trigger); | ||
| 572 | |||
| 573 | ret = fwnode_property_read_string(child, "label", &name); | ||
| 574 | if (ret) | ||
| 575 | snprintf(led->label, sizeof(led->label), | ||
| 576 | "%s::", priv->client->name); | ||
| 577 | else | ||
| 578 | snprintf(led->label, sizeof(led->label), | ||
| 579 | "%s:%s", priv->client->name, name); | ||
| 580 | |||
| 581 | led->priv = priv; | ||
| 582 | led->led_dev.name = led->label; | ||
| 583 | led->led_dev.brightness_set_blocking = lm3532_brightness_set; | ||
| 584 | |||
| 585 | ret = devm_led_classdev_register(priv->dev, &led->led_dev); | ||
| 586 | if (ret) { | ||
| 587 | dev_err(&priv->client->dev, "led register err: %d\n", | ||
| 588 | ret); | ||
| 589 | fwnode_handle_put(child); | ||
| 590 | goto child_out; | ||
| 591 | } | ||
| 592 | |||
| 593 | lm3532_init_registers(led); | ||
| 594 | |||
| 595 | i++; | ||
| 596 | } | ||
| 597 | |||
| 598 | child_out: | ||
| 599 | return ret; | ||
| 600 | } | ||
| 601 | |||
| 602 | static int lm3532_probe(struct i2c_client *client, | ||
| 603 | const struct i2c_device_id *id) | ||
| 604 | { | ||
| 605 | struct lm3532_data *drvdata; | ||
| 606 | int ret = 0; | ||
| 607 | int count; | ||
| 608 | |||
| 609 | count = device_get_child_node_count(&client->dev); | ||
| 610 | if (!count) { | ||
| 611 | dev_err(&client->dev, "LEDs are not defined in device tree!"); | ||
| 612 | return -ENODEV; | ||
| 613 | } | ||
| 614 | |||
| 615 | drvdata = devm_kzalloc(&client->dev, struct_size(drvdata, leds, count), | ||
| 616 | GFP_KERNEL); | ||
| 617 | if (drvdata == NULL) | ||
| 618 | return -ENOMEM; | ||
| 619 | |||
| 620 | drvdata->client = client; | ||
| 621 | drvdata->dev = &client->dev; | ||
| 622 | |||
| 623 | drvdata->regmap = devm_regmap_init_i2c(client, &lm3532_regmap_config); | ||
| 624 | if (IS_ERR(drvdata->regmap)) { | ||
| 625 | ret = PTR_ERR(drvdata->regmap); | ||
| 626 | dev_err(&client->dev, "Failed to allocate register map: %d\n", | ||
| 627 | ret); | ||
| 628 | return ret; | ||
| 629 | } | ||
| 630 | |||
| 631 | mutex_init(&drvdata->lock); | ||
| 632 | i2c_set_clientdata(client, drvdata); | ||
| 633 | |||
| 634 | ret = lm3532_parse_node(drvdata); | ||
| 635 | if (ret) { | ||
| 636 | dev_err(&client->dev, "Failed to parse node\n"); | ||
| 637 | return ret; | ||
| 638 | } | ||
| 639 | |||
| 640 | if (drvdata->enable_gpio) | ||
| 641 | gpiod_direction_output(drvdata->enable_gpio, 1); | ||
| 642 | |||
| 643 | return ret; | ||
| 644 | } | ||
| 645 | |||
| 646 | static int lm3532_remove(struct i2c_client *client) | ||
| 647 | { | ||
| 648 | struct lm3532_data *drvdata = i2c_get_clientdata(client); | ||
| 649 | |||
| 650 | mutex_destroy(&drvdata->lock); | ||
| 651 | |||
| 652 | if (drvdata->enable_gpio) | ||
| 653 | gpiod_direction_output(drvdata->enable_gpio, 0); | ||
| 654 | |||
| 655 | return 0; | ||
| 656 | } | ||
| 657 | |||
| 658 | static const struct of_device_id of_lm3532_leds_match[] = { | ||
| 659 | { .compatible = "ti,lm3532", }, | ||
| 660 | {}, | ||
| 661 | }; | ||
| 662 | MODULE_DEVICE_TABLE(of, of_lm3532_leds_match); | ||
| 663 | |||
| 664 | static const struct i2c_device_id lm3532_id[] = { | ||
| 665 | {LM3532_NAME, 0}, | ||
| 666 | {} | ||
| 667 | }; | ||
| 668 | MODULE_DEVICE_TABLE(i2c, lm3532_id); | ||
| 669 | |||
| 670 | static struct i2c_driver lm3532_i2c_driver = { | ||
| 671 | .probe = lm3532_probe, | ||
| 672 | .remove = lm3532_remove, | ||
| 673 | .id_table = lm3532_id, | ||
| 674 | .driver = { | ||
| 675 | .name = LM3532_NAME, | ||
| 676 | .of_match_table = of_lm3532_leds_match, | ||
| 677 | }, | ||
| 678 | }; | ||
| 679 | module_i2c_driver(lm3532_i2c_driver); | ||
| 680 | |||
| 681 | MODULE_DESCRIPTION("Back Light driver for LM3532"); | ||
| 682 | MODULE_LICENSE("GPL v2"); | ||
| 683 | MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); | ||
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c index de3623e0d094..83e8e58d81cb 100644 --- a/drivers/leds/leds-lt3593.c +++ b/drivers/leds/leds-lt3593.c | |||
| @@ -60,67 +60,14 @@ static int lt3593_led_set(struct led_classdev *led_cdev, | |||
| 60 | return 0; | 60 | return 0; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | static struct lt3593_led_data *lt3593_led_probe_pdata(struct device *dev) | ||
| 64 | { | ||
| 65 | struct gpio_led_platform_data *pdata = dev_get_platdata(dev); | ||
| 66 | const struct gpio_led *template = &pdata->leds[0]; | ||
| 67 | struct lt3593_led_data *led_data; | ||
| 68 | int ret, state; | ||
| 69 | |||
| 70 | if (pdata->num_leds != 1) | ||
| 71 | return ERR_PTR(-EINVAL); | ||
| 72 | |||
| 73 | led_data = devm_kzalloc(dev, sizeof(*led_data), GFP_KERNEL); | ||
| 74 | if (!led_data) | ||
| 75 | return ERR_PTR(-ENOMEM); | ||
| 76 | |||
| 77 | led_data->cdev.name = template->name; | ||
| 78 | led_data->cdev.default_trigger = template->default_trigger; | ||
| 79 | led_data->cdev.brightness_set_blocking = lt3593_led_set; | ||
| 80 | |||
| 81 | state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); | ||
| 82 | led_data->cdev.brightness = state ? LED_FULL : LED_OFF; | ||
| 83 | |||
| 84 | if (!template->retain_state_suspended) | ||
| 85 | led_data->cdev.flags |= LED_CORE_SUSPENDRESUME; | ||
| 86 | |||
| 87 | ret = devm_gpio_request_one(dev, template->gpio, state ? | ||
| 88 | GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, | ||
| 89 | template->name); | ||
| 90 | if (ret < 0) | ||
| 91 | return ERR_PTR(ret); | ||
| 92 | |||
| 93 | led_data->gpiod = gpio_to_desc(template->gpio); | ||
| 94 | if (!led_data->gpiod) | ||
| 95 | return ERR_PTR(-EPROBE_DEFER); | ||
| 96 | |||
| 97 | ret = devm_led_classdev_register(dev, &led_data->cdev); | ||
| 98 | if (ret < 0) | ||
| 99 | return ERR_PTR(ret); | ||
| 100 | |||
| 101 | dev_info(dev, "registered LT3593 LED '%s' at GPIO %d\n", | ||
| 102 | template->name, template->gpio); | ||
| 103 | |||
| 104 | return led_data; | ||
| 105 | } | ||
| 106 | |||
| 107 | static int lt3593_led_probe(struct platform_device *pdev) | 63 | static int lt3593_led_probe(struct platform_device *pdev) |
| 108 | { | 64 | { |
| 109 | struct device *dev = &pdev->dev; | 65 | struct device *dev = &pdev->dev; |
| 110 | struct lt3593_led_data *led_data; | 66 | struct lt3593_led_data *led_data; |
| 111 | struct fwnode_handle *child; | 67 | struct fwnode_handle *child; |
| 112 | int ret, state = LEDS_GPIO_DEFSTATE_OFF; | 68 | int ret, state = LEDS_GPIO_DEFSTATE_OFF; |
| 113 | enum gpiod_flags flags = GPIOD_OUT_LOW; | ||
| 114 | const char *tmp; | 69 | const char *tmp; |
| 115 | 70 | ||
| 116 | if (dev_get_platdata(dev)) { | ||
| 117 | led_data = lt3593_led_probe_pdata(dev); | ||
| 118 | if (IS_ERR(led_data)) | ||
| 119 | return PTR_ERR(led_data); | ||
| 120 | |||
| 121 | goto out; | ||
| 122 | } | ||
| 123 | |||
| 124 | if (!dev->of_node) | 71 | if (!dev->of_node) |
| 125 | return -ENODEV; | 72 | return -ENODEV; |
| 126 | 73 | ||
| @@ -151,13 +98,8 @@ static int lt3593_led_probe(struct platform_device *pdev) | |||
| 151 | &led_data->cdev.default_trigger); | 98 | &led_data->cdev.default_trigger); |
| 152 | 99 | ||
| 153 | if (!fwnode_property_read_string(child, "default-state", &tmp)) { | 100 | if (!fwnode_property_read_string(child, "default-state", &tmp)) { |
| 154 | if (!strcmp(tmp, "keep")) { | 101 | if (!strcmp(tmp, "on")) |
| 155 | state = LEDS_GPIO_DEFSTATE_KEEP; | ||
| 156 | flags = GPIOD_ASIS; | ||
| 157 | } else if (!strcmp(tmp, "on")) { | ||
| 158 | state = LEDS_GPIO_DEFSTATE_ON; | 102 | state = LEDS_GPIO_DEFSTATE_ON; |
| 159 | flags = GPIOD_OUT_HIGH; | ||
| 160 | } | ||
| 161 | } | 103 | } |
| 162 | 104 | ||
| 163 | led_data->cdev.name = led_data->name; | 105 | led_data->cdev.name = led_data->name; |
| @@ -171,20 +113,16 @@ static int lt3593_led_probe(struct platform_device *pdev) | |||
| 171 | } | 113 | } |
| 172 | 114 | ||
| 173 | led_data->cdev.dev->of_node = dev->of_node; | 115 | led_data->cdev.dev->of_node = dev->of_node; |
| 174 | |||
| 175 | out: | ||
| 176 | platform_set_drvdata(pdev, led_data); | 116 | platform_set_drvdata(pdev, led_data); |
| 177 | 117 | ||
| 178 | return 0; | 118 | return 0; |
| 179 | } | 119 | } |
| 180 | 120 | ||
| 181 | #ifdef CONFIG_OF | ||
| 182 | static const struct of_device_id of_lt3593_leds_match[] = { | 121 | static const struct of_device_id of_lt3593_leds_match[] = { |
| 183 | { .compatible = "lltc,lt3593", }, | 122 | { .compatible = "lltc,lt3593", }, |
| 184 | {}, | 123 | {}, |
| 185 | }; | 124 | }; |
| 186 | MODULE_DEVICE_TABLE(of, of_lt3593_leds_match); | 125 | MODULE_DEVICE_TABLE(of, of_lt3593_leds_match); |
| 187 | #endif | ||
| 188 | 126 | ||
| 189 | static struct platform_driver lt3593_led_driver = { | 127 | static struct platform_driver lt3593_led_driver = { |
| 190 | .probe = lt3593_led_probe, | 128 | .probe = lt3593_led_probe, |
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c index f51b356d4426..a9f5dad55956 100644 --- a/drivers/leds/leds-pca955x.c +++ b/drivers/leds/leds-pca955x.c | |||
| @@ -40,7 +40,6 @@ | |||
| 40 | * bits the chip supports. | 40 | * bits the chip supports. |
| 41 | */ | 41 | */ |
| 42 | 42 | ||
| 43 | #include <linux/acpi.h> | ||
| 44 | #include <linux/ctype.h> | 43 | #include <linux/ctype.h> |
| 45 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
| 46 | #include <linux/err.h> | 45 | #include <linux/err.h> |
| @@ -48,8 +47,8 @@ | |||
| 48 | #include <linux/i2c.h> | 47 | #include <linux/i2c.h> |
| 49 | #include <linux/leds.h> | 48 | #include <linux/leds.h> |
| 50 | #include <linux/module.h> | 49 | #include <linux/module.h> |
| 51 | #include <linux/of_device.h> | ||
| 52 | #include <linux/of.h> | 50 | #include <linux/of.h> |
| 51 | #include <linux/property.h> | ||
| 53 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
| 54 | #include <linux/string.h> | 53 | #include <linux/string.h> |
| 55 | 54 | ||
| @@ -110,15 +109,6 @@ static const struct i2c_device_id pca955x_id[] = { | |||
| 110 | }; | 109 | }; |
| 111 | MODULE_DEVICE_TABLE(i2c, pca955x_id); | 110 | MODULE_DEVICE_TABLE(i2c, pca955x_id); |
| 112 | 111 | ||
| 113 | static const struct acpi_device_id pca955x_acpi_ids[] = { | ||
| 114 | { "PCA9550", pca9550 }, | ||
| 115 | { "PCA9551", pca9551 }, | ||
| 116 | { "PCA9552", pca9552 }, | ||
| 117 | { "PCA9553", pca9553 }, | ||
| 118 | { } | ||
| 119 | }; | ||
| 120 | MODULE_DEVICE_TABLE(acpi, pca955x_acpi_ids); | ||
| 121 | |||
| 122 | struct pca955x { | 112 | struct pca955x { |
| 123 | struct mutex lock; | 113 | struct mutex lock; |
| 124 | struct pca955x_led *leds; | 114 | struct pca955x_led *leds; |
| @@ -373,16 +363,14 @@ static int pca955x_gpio_direction_output(struct gpio_chip *gc, | |||
| 373 | } | 363 | } |
| 374 | #endif /* CONFIG_LEDS_PCA955X_GPIO */ | 364 | #endif /* CONFIG_LEDS_PCA955X_GPIO */ |
| 375 | 365 | ||
| 376 | #if IS_ENABLED(CONFIG_OF) | ||
| 377 | static struct pca955x_platform_data * | 366 | static struct pca955x_platform_data * |
| 378 | pca955x_pdata_of_init(struct i2c_client *client, struct pca955x_chipdef *chip) | 367 | pca955x_get_pdata(struct i2c_client *client, struct pca955x_chipdef *chip) |
| 379 | { | 368 | { |
| 380 | struct device_node *np = client->dev.of_node; | ||
| 381 | struct device_node *child; | ||
| 382 | struct pca955x_platform_data *pdata; | 369 | struct pca955x_platform_data *pdata; |
| 370 | struct fwnode_handle *child; | ||
| 383 | int count; | 371 | int count; |
| 384 | 372 | ||
| 385 | count = of_get_child_count(np); | 373 | count = device_get_child_node_count(&client->dev); |
| 386 | if (!count || count > chip->bits) | 374 | if (!count || count > chip->bits) |
| 387 | return ERR_PTR(-ENODEV); | 375 | return ERR_PTR(-ENODEV); |
| 388 | 376 | ||
| @@ -396,24 +384,25 @@ pca955x_pdata_of_init(struct i2c_client *client, struct pca955x_chipdef *chip) | |||
| 396 | if (!pdata->leds) | 384 | if (!pdata->leds) |
| 397 | return ERR_PTR(-ENOMEM); | 385 | return ERR_PTR(-ENOMEM); |
| 398 | 386 | ||
| 399 | for_each_child_of_node(np, child) { | 387 | device_for_each_child_node(&client->dev, child) { |
| 400 | const char *name; | 388 | const char *name; |
| 401 | u32 reg; | 389 | u32 reg; |
| 402 | int res; | 390 | int res; |
| 403 | 391 | ||
| 404 | res = of_property_read_u32(child, "reg", ®); | 392 | res = fwnode_property_read_u32(child, "reg", ®); |
| 405 | if ((res != 0) || (reg >= chip->bits)) | 393 | if ((res != 0) || (reg >= chip->bits)) |
| 406 | continue; | 394 | continue; |
| 407 | 395 | ||
| 408 | if (of_property_read_string(child, "label", &name)) | 396 | res = fwnode_property_read_string(child, "label", &name); |
| 409 | name = child->name; | 397 | if ((res != 0) && is_of_node(child)) |
| 398 | name = to_of_node(child)->name; | ||
| 410 | 399 | ||
| 411 | snprintf(pdata->leds[reg].name, sizeof(pdata->leds[reg].name), | 400 | snprintf(pdata->leds[reg].name, sizeof(pdata->leds[reg].name), |
| 412 | "%s", name); | 401 | "%s", name); |
| 413 | 402 | ||
| 414 | pdata->leds[reg].type = PCA955X_TYPE_LED; | 403 | pdata->leds[reg].type = PCA955X_TYPE_LED; |
| 415 | of_property_read_u32(child, "type", &pdata->leds[reg].type); | 404 | fwnode_property_read_u32(child, "type", &pdata->leds[reg].type); |
| 416 | of_property_read_string(child, "linux,default-trigger", | 405 | fwnode_property_read_string(child, "linux,default-trigger", |
| 417 | &pdata->leds[reg].default_trigger); | 406 | &pdata->leds[reg].default_trigger); |
| 418 | } | 407 | } |
| 419 | 408 | ||
| @@ -429,15 +418,7 @@ static const struct of_device_id of_pca955x_match[] = { | |||
| 429 | { .compatible = "nxp,pca9553", .data = (void *)pca9553 }, | 418 | { .compatible = "nxp,pca9553", .data = (void *)pca9553 }, |
| 430 | {}, | 419 | {}, |
| 431 | }; | 420 | }; |
| 432 | |||
| 433 | MODULE_DEVICE_TABLE(of, of_pca955x_match); | 421 | MODULE_DEVICE_TABLE(of, of_pca955x_match); |
| 434 | #else | ||
| 435 | static struct pca955x_platform_data * | ||
| 436 | pca955x_pdata_of_init(struct i2c_client *client, struct pca955x_chipdef *chip) | ||
| 437 | { | ||
| 438 | return ERR_PTR(-ENODEV); | ||
| 439 | } | ||
| 440 | #endif | ||
| 441 | 422 | ||
| 442 | static int pca955x_probe(struct i2c_client *client, | 423 | static int pca955x_probe(struct i2c_client *client, |
| 443 | const struct i2c_device_id *id) | 424 | const struct i2c_device_id *id) |
| @@ -450,20 +431,11 @@ static int pca955x_probe(struct i2c_client *client, | |||
| 450 | struct pca955x_platform_data *pdata; | 431 | struct pca955x_platform_data *pdata; |
| 451 | int ngpios = 0; | 432 | int ngpios = 0; |
| 452 | 433 | ||
| 453 | if (id) { | 434 | chip = &pca955x_chipdefs[id->driver_data]; |
| 454 | chip = &pca955x_chipdefs[id->driver_data]; | ||
| 455 | } else { | ||
| 456 | const struct acpi_device_id *acpi_id; | ||
| 457 | |||
| 458 | acpi_id = acpi_match_device(pca955x_acpi_ids, &client->dev); | ||
| 459 | if (!acpi_id) | ||
| 460 | return -ENODEV; | ||
| 461 | chip = &pca955x_chipdefs[acpi_id->driver_data]; | ||
| 462 | } | ||
| 463 | adapter = to_i2c_adapter(client->dev.parent); | 435 | adapter = to_i2c_adapter(client->dev.parent); |
| 464 | pdata = dev_get_platdata(&client->dev); | 436 | pdata = dev_get_platdata(&client->dev); |
| 465 | if (!pdata) { | 437 | if (!pdata) { |
| 466 | pdata = pca955x_pdata_of_init(client, chip); | 438 | pdata = pca955x_get_pdata(client, chip); |
| 467 | if (IS_ERR(pdata)) | 439 | if (IS_ERR(pdata)) |
| 468 | return PTR_ERR(pdata); | 440 | return PTR_ERR(pdata); |
| 469 | } | 441 | } |
| @@ -602,8 +574,7 @@ static int pca955x_probe(struct i2c_client *client, | |||
| 602 | static struct i2c_driver pca955x_driver = { | 574 | static struct i2c_driver pca955x_driver = { |
| 603 | .driver = { | 575 | .driver = { |
| 604 | .name = "leds-pca955x", | 576 | .name = "leds-pca955x", |
| 605 | .acpi_match_table = ACPI_PTR(pca955x_acpi_ids), | 577 | .of_match_table = of_pca955x_match, |
| 606 | .of_match_table = of_match_ptr(of_pca955x_match), | ||
| 607 | }, | 578 | }, |
| 608 | .probe = pca955x_probe, | 579 | .probe = pca955x_probe, |
| 609 | .id_table = pca955x_id, | 580 | .id_table = pca955x_id, |
diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c index 5c0908113e38..9b4ef070d956 100644 --- a/drivers/leds/leds-pca963x.c +++ b/drivers/leds/leds-pca963x.c | |||
| @@ -25,7 +25,6 @@ | |||
| 25 | * or by adding the 'nxp,hw-blink' property to the DTS. | 25 | * or by adding the 'nxp,hw-blink' property to the DTS. |
| 26 | */ | 26 | */ |
| 27 | 27 | ||
| 28 | #include <linux/acpi.h> | ||
| 29 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| 30 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
| 31 | #include <linux/string.h> | 30 | #include <linux/string.h> |
| @@ -33,6 +32,7 @@ | |||
| 33 | #include <linux/leds.h> | 32 | #include <linux/leds.h> |
| 34 | #include <linux/err.h> | 33 | #include <linux/err.h> |
| 35 | #include <linux/i2c.h> | 34 | #include <linux/i2c.h> |
| 35 | #include <linux/property.h> | ||
| 36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
| 37 | #include <linux/of.h> | 37 | #include <linux/of.h> |
| 38 | #include <linux/platform_data/leds-pca963x.h> | 38 | #include <linux/platform_data/leds-pca963x.h> |
| @@ -97,15 +97,6 @@ static const struct i2c_device_id pca963x_id[] = { | |||
| 97 | }; | 97 | }; |
| 98 | MODULE_DEVICE_TABLE(i2c, pca963x_id); | 98 | MODULE_DEVICE_TABLE(i2c, pca963x_id); |
| 99 | 99 | ||
| 100 | static const struct acpi_device_id pca963x_acpi_ids[] = { | ||
| 101 | { "PCA9632", pca9633 }, | ||
| 102 | { "PCA9633", pca9633 }, | ||
| 103 | { "PCA9634", pca9634 }, | ||
| 104 | { "PCA9635", pca9635 }, | ||
| 105 | { } | ||
| 106 | }; | ||
| 107 | MODULE_DEVICE_TABLE(acpi, pca963x_acpi_ids); | ||
| 108 | |||
| 109 | struct pca963x_led; | 100 | struct pca963x_led; |
| 110 | 101 | ||
| 111 | struct pca963x { | 102 | struct pca963x { |
| @@ -287,16 +278,15 @@ static int pca963x_blink_set(struct led_classdev *led_cdev, | |||
| 287 | return 0; | 278 | return 0; |
| 288 | } | 279 | } |
| 289 | 280 | ||
| 290 | #if IS_ENABLED(CONFIG_OF) | ||
| 291 | static struct pca963x_platform_data * | 281 | static struct pca963x_platform_data * |
| 292 | pca963x_dt_init(struct i2c_client *client, struct pca963x_chipdef *chip) | 282 | pca963x_get_pdata(struct i2c_client *client, struct pca963x_chipdef *chip) |
| 293 | { | 283 | { |
| 294 | struct device_node *np = client->dev.of_node, *child; | ||
| 295 | struct pca963x_platform_data *pdata; | 284 | struct pca963x_platform_data *pdata; |
| 296 | struct led_info *pca963x_leds; | 285 | struct led_info *pca963x_leds; |
| 286 | struct fwnode_handle *child; | ||
| 297 | int count; | 287 | int count; |
| 298 | 288 | ||
| 299 | count = of_get_child_count(np); | 289 | count = device_get_child_node_count(&client->dev); |
| 300 | if (!count || count > chip->n_leds) | 290 | if (!count || count > chip->n_leds) |
| 301 | return ERR_PTR(-ENODEV); | 291 | return ERR_PTR(-ENODEV); |
| 302 | 292 | ||
| @@ -305,18 +295,22 @@ pca963x_dt_init(struct i2c_client *client, struct pca963x_chipdef *chip) | |||
| 305 | if (!pca963x_leds) | 295 | if (!pca963x_leds) |
| 306 | return ERR_PTR(-ENOMEM); | 296 | return ERR_PTR(-ENOMEM); |
| 307 | 297 | ||
| 308 | for_each_child_of_node(np, child) { | 298 | device_for_each_child_node(&client->dev, child) { |
| 309 | struct led_info led = {}; | 299 | struct led_info led = {}; |
| 310 | u32 reg; | 300 | u32 reg; |
| 311 | int res; | 301 | int res; |
| 312 | 302 | ||
| 313 | res = of_property_read_u32(child, "reg", ®); | 303 | res = fwnode_property_read_u32(child, "reg", ®); |
| 314 | if ((res != 0) || (reg >= chip->n_leds)) | 304 | if ((res != 0) || (reg >= chip->n_leds)) |
| 315 | continue; | 305 | continue; |
| 316 | led.name = | 306 | |
| 317 | of_get_property(child, "label", NULL) ? : child->name; | 307 | res = fwnode_property_read_string(child, "label", &led.name); |
| 318 | led.default_trigger = | 308 | if ((res != 0) && is_of_node(child)) |
| 319 | of_get_property(child, "linux,default-trigger", NULL); | 309 | led.name = to_of_node(child)->name; |
| 310 | |||
| 311 | fwnode_property_read_string(child, "linux,default-trigger", | ||
| 312 | &led.default_trigger); | ||
| 313 | |||
| 320 | pca963x_leds[reg] = led; | 314 | pca963x_leds[reg] = led; |
| 321 | } | 315 | } |
| 322 | pdata = devm_kzalloc(&client->dev, | 316 | pdata = devm_kzalloc(&client->dev, |
| @@ -328,22 +322,23 @@ pca963x_dt_init(struct i2c_client *client, struct pca963x_chipdef *chip) | |||
| 328 | pdata->leds.num_leds = chip->n_leds; | 322 | pdata->leds.num_leds = chip->n_leds; |
| 329 | 323 | ||
| 330 | /* default to open-drain unless totem pole (push-pull) is specified */ | 324 | /* default to open-drain unless totem pole (push-pull) is specified */ |
| 331 | if (of_property_read_bool(np, "nxp,totem-pole")) | 325 | if (device_property_read_bool(&client->dev, "nxp,totem-pole")) |
| 332 | pdata->outdrv = PCA963X_TOTEM_POLE; | 326 | pdata->outdrv = PCA963X_TOTEM_POLE; |
| 333 | else | 327 | else |
| 334 | pdata->outdrv = PCA963X_OPEN_DRAIN; | 328 | pdata->outdrv = PCA963X_OPEN_DRAIN; |
| 335 | 329 | ||
| 336 | /* default to software blinking unless hardware blinking is specified */ | 330 | /* default to software blinking unless hardware blinking is specified */ |
| 337 | if (of_property_read_bool(np, "nxp,hw-blink")) | 331 | if (device_property_read_bool(&client->dev, "nxp,hw-blink")) |
| 338 | pdata->blink_type = PCA963X_HW_BLINK; | 332 | pdata->blink_type = PCA963X_HW_BLINK; |
| 339 | else | 333 | else |
| 340 | pdata->blink_type = PCA963X_SW_BLINK; | 334 | pdata->blink_type = PCA963X_SW_BLINK; |
| 341 | 335 | ||
| 342 | if (of_property_read_u32(np, "nxp,period-scale", &chip->scaling)) | 336 | if (device_property_read_u32(&client->dev, "nxp,period-scale", |
| 337 | &chip->scaling)) | ||
| 343 | chip->scaling = 1000; | 338 | chip->scaling = 1000; |
| 344 | 339 | ||
| 345 | /* default to non-inverted output, unless inverted is specified */ | 340 | /* default to non-inverted output, unless inverted is specified */ |
| 346 | if (of_property_read_bool(np, "nxp,inverted-out")) | 341 | if (device_property_read_bool(&client->dev, "nxp,inverted-out")) |
| 347 | pdata->dir = PCA963X_INVERTED; | 342 | pdata->dir = PCA963X_INVERTED; |
| 348 | else | 343 | else |
| 349 | pdata->dir = PCA963X_NORMAL; | 344 | pdata->dir = PCA963X_NORMAL; |
| @@ -359,13 +354,6 @@ static const struct of_device_id of_pca963x_match[] = { | |||
| 359 | {}, | 354 | {}, |
| 360 | }; | 355 | }; |
| 361 | MODULE_DEVICE_TABLE(of, of_pca963x_match); | 356 | MODULE_DEVICE_TABLE(of, of_pca963x_match); |
| 362 | #else | ||
| 363 | static struct pca963x_platform_data * | ||
| 364 | pca963x_dt_init(struct i2c_client *client, struct pca963x_chipdef *chip) | ||
| 365 | { | ||
| 366 | return ERR_PTR(-ENODEV); | ||
| 367 | } | ||
| 368 | #endif | ||
| 369 | 357 | ||
| 370 | static int pca963x_probe(struct i2c_client *client, | 358 | static int pca963x_probe(struct i2c_client *client, |
| 371 | const struct i2c_device_id *id) | 359 | const struct i2c_device_id *id) |
| @@ -376,20 +364,11 @@ static int pca963x_probe(struct i2c_client *client, | |||
| 376 | struct pca963x_chipdef *chip; | 364 | struct pca963x_chipdef *chip; |
| 377 | int i, err; | 365 | int i, err; |
| 378 | 366 | ||
| 379 | if (id) { | 367 | chip = &pca963x_chipdefs[id->driver_data]; |
| 380 | chip = &pca963x_chipdefs[id->driver_data]; | ||
| 381 | } else { | ||
| 382 | const struct acpi_device_id *acpi_id; | ||
| 383 | |||
| 384 | acpi_id = acpi_match_device(pca963x_acpi_ids, &client->dev); | ||
| 385 | if (!acpi_id) | ||
| 386 | return -ENODEV; | ||
| 387 | chip = &pca963x_chipdefs[acpi_id->driver_data]; | ||
| 388 | } | ||
| 389 | pdata = dev_get_platdata(&client->dev); | 368 | pdata = dev_get_platdata(&client->dev); |
| 390 | 369 | ||
| 391 | if (!pdata) { | 370 | if (!pdata) { |
| 392 | pdata = pca963x_dt_init(client, chip); | 371 | pdata = pca963x_get_pdata(client, chip); |
| 393 | if (IS_ERR(pdata)) { | 372 | if (IS_ERR(pdata)) { |
| 394 | dev_warn(&client->dev, "could not parse configuration\n"); | 373 | dev_warn(&client->dev, "could not parse configuration\n"); |
| 395 | pdata = NULL; | 374 | pdata = NULL; |
| @@ -495,8 +474,7 @@ static int pca963x_remove(struct i2c_client *client) | |||
| 495 | static struct i2c_driver pca963x_driver = { | 474 | static struct i2c_driver pca963x_driver = { |
| 496 | .driver = { | 475 | .driver = { |
| 497 | .name = "leds-pca963x", | 476 | .name = "leds-pca963x", |
| 498 | .of_match_table = of_match_ptr(of_pca963x_match), | 477 | .of_match_table = of_pca963x_match, |
| 499 | .acpi_match_table = ACPI_PTR(pca963x_acpi_ids), | ||
| 500 | }, | 478 | }, |
| 501 | .probe = pca963x_probe, | 479 | .probe = pca963x_probe, |
| 502 | .remove = pca963x_remove, | 480 | .remove = pca963x_remove, |
diff --git a/drivers/mfd/ti-lmu.c b/drivers/mfd/ti-lmu.c index 37d0bdb291c3..b06cb908d1aa 100644 --- a/drivers/mfd/ti-lmu.c +++ b/drivers/mfd/ti-lmu.c | |||
| @@ -54,14 +54,6 @@ static void ti_lmu_disable_hw(void *data) | |||
| 54 | gpiod_set_value(lmu->en_gpio, 0); | 54 | gpiod_set_value(lmu->en_gpio, 0); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | static const struct mfd_cell lm3532_devices[] = { | ||
| 58 | { | ||
| 59 | .name = "ti-lmu-backlight", | ||
| 60 | .id = LM3532, | ||
| 61 | .of_compatible = "ti,lm3532-backlight", | ||
| 62 | }, | ||
| 63 | }; | ||
| 64 | |||
| 65 | #define LM363X_REGULATOR(_id) \ | 57 | #define LM363X_REGULATOR(_id) \ |
| 66 | { \ | 58 | { \ |
| 67 | .name = "lm363x-regulator", \ | 59 | .name = "lm363x-regulator", \ |
| @@ -141,7 +133,6 @@ static const struct ti_lmu_data chip##_data = \ | |||
| 141 | .max_register = max_reg, \ | 133 | .max_register = max_reg, \ |
| 142 | } \ | 134 | } \ |
| 143 | 135 | ||
| 144 | TI_LMU_DATA(lm3532, LM3532_MAX_REG); | ||
| 145 | TI_LMU_DATA(lm3631, LM3631_MAX_REG); | 136 | TI_LMU_DATA(lm3631, LM3631_MAX_REG); |
| 146 | TI_LMU_DATA(lm3632, LM3632_MAX_REG); | 137 | TI_LMU_DATA(lm3632, LM3632_MAX_REG); |
| 147 | TI_LMU_DATA(lm3633, LM3633_MAX_REG); | 138 | TI_LMU_DATA(lm3633, LM3633_MAX_REG); |
| @@ -211,7 +202,6 @@ static int ti_lmu_probe(struct i2c_client *cl, const struct i2c_device_id *id) | |||
| 211 | } | 202 | } |
| 212 | 203 | ||
| 213 | static const struct of_device_id ti_lmu_of_match[] = { | 204 | static const struct of_device_id ti_lmu_of_match[] = { |
| 214 | { .compatible = "ti,lm3532", .data = &lm3532_data }, | ||
| 215 | { .compatible = "ti,lm3631", .data = &lm3631_data }, | 205 | { .compatible = "ti,lm3631", .data = &lm3631_data }, |
| 216 | { .compatible = "ti,lm3632", .data = &lm3632_data }, | 206 | { .compatible = "ti,lm3632", .data = &lm3632_data }, |
| 217 | { .compatible = "ti,lm3633", .data = &lm3633_data }, | 207 | { .compatible = "ti,lm3633", .data = &lm3633_data }, |
| @@ -222,7 +212,6 @@ static const struct of_device_id ti_lmu_of_match[] = { | |||
| 222 | MODULE_DEVICE_TABLE(of, ti_lmu_of_match); | 212 | MODULE_DEVICE_TABLE(of, ti_lmu_of_match); |
| 223 | 213 | ||
| 224 | static const struct i2c_device_id ti_lmu_ids[] = { | 214 | static const struct i2c_device_id ti_lmu_ids[] = { |
| 225 | { "lm3532", LM3532 }, | ||
| 226 | { "lm3631", LM3631 }, | 215 | { "lm3631", LM3631 }, |
| 227 | { "lm3632", LM3632 }, | 216 | { "lm3632", LM3632 }, |
| 228 | { "lm3633", LM3633 }, | 217 | { "lm3633", LM3633 }, |
diff --git a/include/linux/mfd/ti-lmu-register.h b/include/linux/mfd/ti-lmu-register.h index 2125c7c02818..f09510561a55 100644 --- a/include/linux/mfd/ti-lmu-register.h +++ b/include/linux/mfd/ti-lmu-register.h | |||
| @@ -15,50 +15,6 @@ | |||
| 15 | 15 | ||
| 16 | #include <linux/bitops.h> | 16 | #include <linux/bitops.h> |
| 17 | 17 | ||
| 18 | /* LM3532 */ | ||
| 19 | #define LM3532_REG_OUTPUT_CFG 0x10 | ||
| 20 | #define LM3532_ILED1_CFG_MASK 0x03 | ||
| 21 | #define LM3532_ILED2_CFG_MASK 0x0C | ||
| 22 | #define LM3532_ILED3_CFG_MASK 0x30 | ||
| 23 | #define LM3532_ILED1_CFG_SHIFT 0 | ||
| 24 | #define LM3532_ILED2_CFG_SHIFT 2 | ||
| 25 | #define LM3532_ILED3_CFG_SHIFT 4 | ||
| 26 | |||
| 27 | #define LM3532_REG_RAMPUP 0x12 | ||
| 28 | #define LM3532_REG_RAMPDN LM3532_REG_RAMPUP | ||
| 29 | #define LM3532_RAMPUP_MASK 0x07 | ||
| 30 | #define LM3532_RAMPUP_SHIFT 0 | ||
| 31 | #define LM3532_RAMPDN_MASK 0x38 | ||
| 32 | #define LM3532_RAMPDN_SHIFT 3 | ||
| 33 | |||
| 34 | #define LM3532_REG_ENABLE 0x1D | ||
| 35 | |||
| 36 | #define LM3532_REG_PWM_A_CFG 0x13 | ||
| 37 | #define LM3532_PWM_A_MASK 0x05 /* zone 0 */ | ||
| 38 | #define LM3532_PWM_ZONE_0 BIT(2) | ||
| 39 | |||
| 40 | #define LM3532_REG_PWM_B_CFG 0x14 | ||
| 41 | #define LM3532_PWM_B_MASK 0x09 /* zone 1 */ | ||
| 42 | #define LM3532_PWM_ZONE_1 BIT(3) | ||
| 43 | |||
| 44 | #define LM3532_REG_PWM_C_CFG 0x15 | ||
| 45 | #define LM3532_PWM_C_MASK 0x11 /* zone 2 */ | ||
| 46 | #define LM3532_PWM_ZONE_2 BIT(4) | ||
| 47 | |||
| 48 | #define LM3532_REG_ZONE_CFG_A 0x16 | ||
| 49 | #define LM3532_REG_ZONE_CFG_B 0x18 | ||
| 50 | #define LM3532_REG_ZONE_CFG_C 0x1A | ||
| 51 | #define LM3532_ZONE_MASK (BIT(2) | BIT(3) | BIT(4)) | ||
| 52 | #define LM3532_ZONE_0 0 | ||
| 53 | #define LM3532_ZONE_1 BIT(2) | ||
| 54 | #define LM3532_ZONE_2 BIT(3) | ||
| 55 | |||
| 56 | #define LM3532_REG_BRT_A 0x70 /* zone 0 */ | ||
| 57 | #define LM3532_REG_BRT_B 0x76 /* zone 1 */ | ||
| 58 | #define LM3532_REG_BRT_C 0x7C /* zone 2 */ | ||
| 59 | |||
| 60 | #define LM3532_MAX_REG 0x7E | ||
| 61 | |||
| 62 | /* LM3631 */ | 18 | /* LM3631 */ |
| 63 | #define LM3631_REG_DEVCTRL 0x00 | 19 | #define LM3631_REG_DEVCTRL 0x00 |
| 64 | #define LM3631_LCD_EN_MASK BIT(1) | 20 | #define LM3631_LCD_EN_MASK BIT(1) |
diff --git a/include/linux/mfd/ti-lmu.h b/include/linux/mfd/ti-lmu.h index 1ef51ed36be5..7762c1bce55d 100644 --- a/include/linux/mfd/ti-lmu.h +++ b/include/linux/mfd/ti-lmu.h | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | #define LMU_EVENT_MONITOR_DONE 0x01 | 22 | #define LMU_EVENT_MONITOR_DONE 0x01 |
| 23 | 23 | ||
| 24 | enum ti_lmu_id { | 24 | enum ti_lmu_id { |
| 25 | LM3532, | ||
| 26 | LM3631, | 25 | LM3631, |
| 27 | LM3632, | 26 | LM3632, |
| 28 | LM3633, | 27 | LM3633, |
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 19bee725de00..ecbe5f3beda5 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c | |||
| @@ -291,8 +291,8 @@ static bool toneport_has_led(struct usb_line6_toneport *toneport) | |||
| 291 | } | 291 | } |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | static const char * const led_colors[2] = { "red", "green" }; | 294 | static const char * const toneport_led_colors[2] = { "red", "green" }; |
| 295 | static const int led_init_vals[2] = { 0x00, 0x26 }; | 295 | static const int toneport_led_init_vals[2] = { 0x00, 0x26 }; |
| 296 | 296 | ||
| 297 | static void toneport_update_led(struct usb_line6_toneport *toneport) | 297 | static void toneport_update_led(struct usb_line6_toneport *toneport) |
| 298 | { | 298 | { |
| @@ -320,9 +320,9 @@ static int toneport_init_leds(struct usb_line6_toneport *toneport) | |||
| 320 | 320 | ||
| 321 | led->toneport = toneport; | 321 | led->toneport = toneport; |
| 322 | snprintf(led->name, sizeof(led->name), "%s::%s", | 322 | snprintf(led->name, sizeof(led->name), "%s::%s", |
| 323 | dev_name(dev), led_colors[i]); | 323 | dev_name(dev), toneport_led_colors[i]); |
| 324 | leddev->name = led->name; | 324 | leddev->name = led->name; |
| 325 | leddev->brightness = led_init_vals[i]; | 325 | leddev->brightness = toneport_led_init_vals[i]; |
| 326 | leddev->max_brightness = 0x26; | 326 | leddev->max_brightness = 0x26; |
| 327 | leddev->brightness_set = toneport_led_brightness_set; | 327 | leddev->brightness_set = toneport_led_brightness_set; |
| 328 | err = led_classdev_register(dev, leddev); | 328 | err = led_classdev_register(dev, leddev); |
