Commit 5223161d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds

Pull led updates from Bryan Wu:
 "Sorry for the late pull request, since I'm just back from vacation.

  LED subsystem updates for 3.12:
   - pca9633 driver DT supporting and pca9634 chip supporting
   - restore legacy device attributes for lp5521
   - other fixing and updates"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds: (28 commits)
  leds: wm831x-status: Request a REG resource
  leds: trigger: ledtrig-backlight: Fix invalid memory access in fb_event notification callback
  leds-pca963x: Fix device tree parsing
  leds-pca9633: Rename to leds-pca963x
  leds-pca9633: Add mutex to the ledout register
  leds-pca9633: Unique naming of the LEDs
  leds-pca9633: Add support for PCA9634
  leds: lp5562: use LP55xx common macros for device attributes
  Documentation: leds-lp5521,lp5523: update device attribute information
  leds: lp5523: remove unnecessary writing commands
  leds: lp5523: restore legacy device attributes
  leds: lp5523: LED MUX configuration on initializing
  leds: lp5523: make separate API for loading engine
  leds: lp5521: remove unnecessary writing commands
  leds: lp5521: restore legacy device attributes
  leds: lp55xx: add common macros for device attributes
  leds: lp55xx: add common data structure for program
  Documentation: leds: Fix a typo
  leds: ss4200: Fix incorrect placement of __initdata
  leds: clevo-mail: Fix incorrect placement of __initdata
  ...
parents e5d0c874 61abeba5
Binding for TI/National Semiconductor LP55xx Led Drivers Binding for TI/National Semiconductor LP55xx Led Drivers
Required properties: Required properties:
- compatible: "national,lp5521" or "national,lp5523" or "ti,lp5562" - compatible: "national,lp5521" or "national,lp5523" or "ti,lp5562" or "ti,lp8501"
- reg: I2C slave address - reg: I2C slave address
- clock-mode: Input clock mode, (0: automode, 1: internal, 2: external) - clock-mode: Input clock mode, (0: automode, 1: internal, 2: external)
...@@ -11,6 +11,11 @@ Each child has own specific current settings ...@@ -11,6 +11,11 @@ Each child has own specific current settings
Optional properties: Optional properties:
- label: Used for naming LEDs - label: Used for naming LEDs
- pwr-sel: LP8501 specific property. Power selection for output channels.
0: D1~9 are connected to VDD
1: D1~6 with VDD, D7~9 with VOUT
2: D1~6 with VOUT, D7~9 with VDD
3: D1~9 are connected to VOUT
Alternatively, each child can have specific channel name Alternatively, each child can have specific channel name
- chan-name: Name of each channel name - chan-name: Name of each channel name
...@@ -145,3 +150,68 @@ lp5562@30 { ...@@ -145,3 +150,68 @@ lp5562@30 {
max-cur = /bits/ 8 <0x60>; max-cur = /bits/ 8 <0x60>;
}; };
}; };
example 4) LP8501
9 channels are defined. The 'pwr-sel' is LP8501 specific property.
Others are same as LP5523.
lp8501@32 {
compatible = "ti,lp8501";
reg = <0x32>;
clock-mode = /bits/ 8 <2>;
pwr-sel = /bits/ 8 <3>; /* D1~9 connected to VOUT */
chan0 {
chan-name = "d1";
led-cur = /bits/ 8 <0x14>;
max-cur = /bits/ 8 <0x20>;
};
chan1 {
chan-name = "d2";
led-cur = /bits/ 8 <0x14>;
max-cur = /bits/ 8 <0x20>;
};
chan2 {
chan-name = "d3";
led-cur = /bits/ 8 <0x14>;
max-cur = /bits/ 8 <0x20>;
};
chan3 {
chan-name = "d4";
led-cur = /bits/ 8 <0x14>;
max-cur = /bits/ 8 <0x20>;
};
chan4 {
chan-name = "d5";
led-cur = /bits/ 8 <0x14>;
max-cur = /bits/ 8 <0x20>;
};
chan5 {
chan-name = "d6";
led-cur = /bits/ 8 <0x14>;
max-cur = /bits/ 8 <0x20>;
};
chan6 {
chan-name = "d7";
led-cur = /bits/ 8 <0x14>;
max-cur = /bits/ 8 <0x20>;
};
chan7 {
chan-name = "d8";
led-cur = /bits/ 8 <0x14>;
max-cur = /bits/ 8 <0x20>;
};
chan8 {
chan-name = "d9";
led-cur = /bits/ 8 <0x14>;
max-cur = /bits/ 8 <0x20>;
};
};
LEDs connected to pca9632, pca9633 or pca9634
Required properties:
- compatible : should be : "nxp,pca9632", "nxp,pca9633" or "nxp,pca9634"
Optional properties:
- nxp,totem-pole : use totem pole (push-pull) instead of default open-drain
- nxp,hw-blink : use hardware blinking instead of software blinking
Each led is represented as a sub-node of the nxp,pca963x device.
LED sub-node properties:
- label : (optional) see Documentation/devicetree/bindings/leds/common.txt
- reg : number of LED line (could be from 0 to 3 in pca9632 or pca9633
or 0 to 7 in pca9634)
- linux,default-trigger : (optional)
see Documentation/devicetree/bindings/leds/common.txt
Examples:
pca9632: pca9632 {
compatible = "nxp,pca9632";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x62>;
red@0 {
label = "red";
reg = <0>;
linux,default-trigger = "none";
};
green@1 {
label = "green";
reg = <1>;
linux,default-trigger = "none";
};
blue@2 {
label = "blue";
reg = <2>;
linux,default-trigger = "none";
};
unused@3 {
label = "unused";
reg = <3>;
linux,default-trigger = "none";
};
};
...@@ -18,7 +18,25 @@ All three channels can be also controlled using the engine micro programs. ...@@ -18,7 +18,25 @@ All three channels can be also controlled using the engine micro programs.
More details of the instructions can be found from the public data sheet. More details of the instructions can be found from the public data sheet.
LP5521 has the internal program memory for running various LED patterns. LP5521 has the internal program memory for running various LED patterns.
For the details, please refer to 'firmware' section in leds-lp55xx.txt There are two ways to run LED patterns.
1) Legacy interface - enginex_mode and enginex_load
Control interface for the engines:
x is 1 .. 3
enginex_mode : disabled, load, run
enginex_load : store program (visible only in engine load mode)
Example (start to blink the channel 2 led):
cd /sys/class/leds/lp5521:channel2/device
echo "load" > engine3_mode
echo "037f4d0003ff6000" > engine3_load
echo "run" > engine3_mode
To stop the engine:
echo "disabled" > engine3_mode
2) Firmware interface - LP55xx common interface
For the details, please refer to 'firmware' section in leds-lp55xx.txt
sysfs contains a selftest entry. sysfs contains a selftest entry.
The test communicates with the chip and checks that The test communicates with the chip and checks that
......
...@@ -28,7 +28,26 @@ If both fields are NULL, 'lp5523' is used by default. ...@@ -28,7 +28,26 @@ If both fields are NULL, 'lp5523' is used by default.
/sys/class/leds/lp5523:channelN (N: 0 ~ 8) /sys/class/leds/lp5523:channelN (N: 0 ~ 8)
LP5523 has the internal program memory for running various LED patterns. LP5523 has the internal program memory for running various LED patterns.
For the details, please refer to 'firmware' section in leds-lp55xx.txt There are two ways to run LED patterns.
1) Legacy interface - enginex_mode, enginex_load and enginex_leds
Control interface for the engines:
x is 1 .. 3
enginex_mode : disabled, load, run
enginex_load : microcode load (visible only in load mode)
enginex_leds : led mux control (visible only in load mode)
cd /sys/class/leds/lp5523:channel2/device
echo "load" > engine3_mode
echo "9d80400004ff05ff437f0000" > engine3_load
echo "111111111" > engine3_leds
echo "run" > engine3_mode
To stop the engine:
echo "disabled" > engine3_mode
2) Firmware interface - LP55xx common interface
For the details, please refer to 'firmware' section in leds-lp55xx.txt
Selftest uses always the current from the platform data. Selftest uses always the current from the platform data.
......
LP5521/LP5523/LP55231 Common Driver LP5521/LP5523/LP55231/LP5562/LP8501 Common Driver
=================================== =================================================
Authors: Milo(Woogyom) Kim <milo.kim@ti.com> Authors: Milo(Woogyom) Kim <milo.kim@ti.com>
Description Description
----------- -----------
LP5521, LP5523/55231 and LP5562 have common features as below. LP5521, LP5523/55231, LP5562 and LP8501 have common features as below.
Register access via the I2C Register access via the I2C
Device initialization/deinitialization Device initialization/deinitialization
...@@ -109,6 +109,30 @@ As soon as 'loading' is set to 0, registered callback is called. ...@@ -109,6 +109,30 @@ As soon as 'loading' is set to 0, registered callback is called.
Inside the callback, the selected engine is loaded and memory is updated. Inside the callback, the selected engine is loaded and memory is updated.
To run programmed pattern, 'run_engine' attribute should be enabled. To run programmed pattern, 'run_engine' attribute should be enabled.
The pattern sqeuence of LP8501 is same as LP5523.
However pattern data is specific.
Ex 1) Engine 1 is used
echo 1 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp8501/loading
echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
echo 0 > /sys/class/firmware/lp8501/loading
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
Ex 2) Engine 2 and 3 are used at the same time
echo 2 > /sys/bus/i2c/devices/xxxx/select_engine
sleep 1
echo 1 > /sys/class/firmware/lp8501/loading
echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
echo 0 > /sys/class/firmware/lp8501/loading
sleep 1
echo 3 > /sys/bus/i2c/devices/xxxx/select_engine
sleep 1
echo 1 > /sys/class/firmware/lp8501/loading
echo "9d0340ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
echo 0 > /sys/class/firmware/lp8501/loading
sleep 1
echo 1 > /sys/class/leds/d1/device/run_engine
( 'run_engine' and 'firmware_cb' ) ( 'run_engine' and 'firmware_cb' )
The sequence of running the program data is common. The sequence of running the program data is common.
But each device has own specific register addresses for commands. But each device has own specific register addresses for commands.
......
...@@ -194,11 +194,11 @@ config LEDS_LP3944 ...@@ -194,11 +194,11 @@ config LEDS_LP3944
module will be called leds-lp3944. module will be called leds-lp3944.
config LEDS_LP55XX_COMMON config LEDS_LP55XX_COMMON
tristate "Common Driver for TI/National LP5521, LP5523/55231 and LP5562" tristate "Common Driver for TI/National LP5521/5523/55231/5562/8501"
depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562 depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562 || LEDS_LP8501
select FW_LOADER select FW_LOADER
help help
This option supports common operations for LP5521 and LP5523/55231 This option supports common operations for LP5521/5523/55231/5562/8501
devices. devices.
config LEDS_LP5521 config LEDS_LP5521
...@@ -232,6 +232,18 @@ config LEDS_LP5562 ...@@ -232,6 +232,18 @@ config LEDS_LP5562
Driver provides direct control via LED class and interface for Driver provides direct control via LED class and interface for
programming the engines. programming the engines.
config LEDS_LP8501
tristate "LED Support for TI LP8501 LED driver chip"
depends on LEDS_CLASS && I2C
select LEDS_LP55XX_COMMON
help
If you say yes here you get support for TI LP8501 LED driver.
It is 9 channel chip with programmable engines.
Driver provides direct control via LED class and interface for
programming the engines.
It is similar as LP5523, but output power selection is available.
And register layout and engine program schemes are different.
config LEDS_LP8788 config LEDS_LP8788
tristate "LED support for the TI LP8788 PMIC" tristate "LED support for the TI LP8788 PMIC"
depends on LEDS_CLASS depends on LEDS_CLASS
...@@ -279,13 +291,14 @@ config LEDS_PCA955X ...@@ -279,13 +291,14 @@ config LEDS_PCA955X
LED driver chips accessed via the I2C bus. Supported LED driver chips accessed via the I2C bus. Supported
devices include PCA9550, PCA9551, PCA9552, and PCA9553. devices include PCA9550, PCA9551, PCA9552, and PCA9553.
config LEDS_PCA9633 config LEDS_PCA963X
tristate "LED support for PCA9633 I2C chip" tristate "LED support for PCA963x I2C chip"
depends on LEDS_CLASS depends on LEDS_CLASS
depends on I2C depends on I2C
help help
This option enables support for LEDs connected to the PCA9633 This option enables support for LEDs connected to the PCA963x
LED driver chip accessed via the I2C bus. LED driver chip accessed via the I2C bus. Supported
devices include PCA9633 and PCA9634
config LEDS_WM831X_STATUS config LEDS_WM831X_STATUS
tristate "LED support for status LEDs on WM831x PMICs" tristate "LED support for status LEDs on WM831x PMICs"
...@@ -398,10 +411,7 @@ config LEDS_MC13783 ...@@ -398,10 +411,7 @@ config LEDS_MC13783
config LEDS_NS2 config LEDS_NS2
tristate "LED support for Network Space v2 GPIO LEDs" tristate "LED support for Network Space v2 GPIO LEDs"
depends on LEDS_CLASS depends on LEDS_CLASS
depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || \ depends on ARCH_KIRKWOOD
MACH_NETSPACE_MAX_V2 || MACH_D2NET_V2 || \
MACH_NETSPACE_V2_DT || MACH_INETSPACE_V2_DT || \
MACH_NETSPACE_MAX_V2_DT || MACH_NETSPACE_MINI_V2_DT
default y default y
help help
This option enable support for the dual-GPIO LED found on the This option enable support for the dual-GPIO LED found on the
...@@ -410,8 +420,8 @@ config LEDS_NS2 ...@@ -410,8 +420,8 @@ config LEDS_NS2
config LEDS_NETXBIG config LEDS_NETXBIG
tristate "LED support for Big Network series LEDs" tristate "LED support for Big Network series LEDs"
depends on MACH_NET2BIG_V2 || MACH_NET5BIG_V2
depends on LEDS_CLASS depends on LEDS_CLASS
depends on ARCH_KIRKWOOD
default y default y
help help
This option enable support for LEDs found on the LaCie 2Big This option enable support for LEDs found on the LaCie 2Big
......
...@@ -27,6 +27,7 @@ obj-$(CONFIG_LEDS_LP55XX_COMMON) += leds-lp55xx-common.o ...@@ -27,6 +27,7 @@ obj-$(CONFIG_LEDS_LP55XX_COMMON) += leds-lp55xx-common.o
obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o
obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o
obj-$(CONFIG_LEDS_LP5562) += leds-lp5562.o obj-$(CONFIG_LEDS_LP5562) += leds-lp5562.o
obj-$(CONFIG_LEDS_LP8501) += leds-lp8501.o
obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
...@@ -34,7 +35,7 @@ obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o ...@@ -34,7 +35,7 @@ obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
obj-$(CONFIG_LEDS_OT200) += leds-ot200.o obj-$(CONFIG_LEDS_OT200) += leds-ot200.o
obj-$(CONFIG_LEDS_FSG) += leds-fsg.o obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o
obj-$(CONFIG_LEDS_PCA9633) += leds-pca9633.o obj-$(CONFIG_LEDS_PCA963X) += leds-pca963x.o
obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o
obj-$(CONFIG_LEDS_DA9052) += leds-da9052.o obj-$(CONFIG_LEDS_DA9052) += leds-da9052.o
obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
......
...@@ -157,7 +157,7 @@ static int pm860x_led_dt_init(struct platform_device *pdev, ...@@ -157,7 +157,7 @@ static int pm860x_led_dt_init(struct platform_device *pdev,
static int pm860x_led_probe(struct platform_device *pdev) static int pm860x_led_probe(struct platform_device *pdev)
{ {
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct pm860x_led_pdata *pdata = pdev->dev.platform_data; struct pm860x_led_pdata *pdata = dev_get_platdata(&pdev->dev);
struct pm860x_led *data; struct pm860x_led *data;
struct resource *res; struct resource *res;
int ret = 0; int ret = 0;
......
...@@ -87,7 +87,7 @@ static int adp5520_led_setup(struct adp5520_led *led) ...@@ -87,7 +87,7 @@ static int adp5520_led_setup(struct adp5520_led *led)
static int adp5520_led_prepare(struct platform_device *pdev) static int adp5520_led_prepare(struct platform_device *pdev)
{ {
struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; struct adp5520_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct device *dev = pdev->dev.parent; struct device *dev = pdev->dev.parent;
int ret = 0; int ret = 0;
...@@ -103,7 +103,7 @@ static int adp5520_led_prepare(struct platform_device *pdev) ...@@ -103,7 +103,7 @@ static int adp5520_led_prepare(struct platform_device *pdev)
static int adp5520_led_probe(struct platform_device *pdev) static int adp5520_led_probe(struct platform_device *pdev)
{ {
struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; struct adp5520_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct adp5520_led *led, *led_dat; struct adp5520_led *led, *led_dat;
struct led_info *cur_led; struct led_info *cur_led;
int ret, i; int ret, i;
...@@ -185,7 +185,7 @@ static int adp5520_led_probe(struct platform_device *pdev) ...@@ -185,7 +185,7 @@ static int adp5520_led_probe(struct platform_device *pdev)
static int adp5520_led_remove(struct platform_device *pdev) static int adp5520_led_remove(struct platform_device *pdev)
{ {
struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; struct adp5520_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct adp5520_led *led; struct adp5520_led *led;
int i; int i;
......
...@@ -94,7 +94,7 @@ static int blink_set(struct led_classdev *cdev, ...@@ -94,7 +94,7 @@ static int blink_set(struct led_classdev *cdev,
static int asic3_led_probe(struct platform_device *pdev) static int asic3_led_probe(struct platform_device *pdev)
{ {
struct asic3_led *led = pdev->dev.platform_data; struct asic3_led *led = dev_get_platdata(&pdev->dev);
int ret; int ret;
ret = mfd_cell_enable(pdev); ret = mfd_cell_enable(pdev);
...@@ -127,7 +127,7 @@ static int asic3_led_probe(struct platform_device *pdev) ...@@ -127,7 +127,7 @@ static int asic3_led_probe(struct platform_device *pdev)
static int asic3_led_remove(struct platform_device *pdev) static int asic3_led_remove(struct platform_device *pdev)
{ {
struct asic3_led *led = pdev->dev.platform_data; struct asic3_led *led = dev_get_platdata(&pdev->dev);
led_classdev_unregister(led->cdev); led_classdev_unregister(led->cdev);
......
...@@ -42,7 +42,7 @@ static int pwmled_probe(struct platform_device *pdev) ...@@ -42,7 +42,7 @@ static int pwmled_probe(struct platform_device *pdev)
int i; int i;
int status; int status;
pdata = pdev->dev.platform_data; pdata = dev_get_platdata(&pdev->dev);
if (!pdata || pdata->num_leds < 1) if (!pdata || pdata->num_leds < 1)
return -ENODEV; return -ENODEV;
...@@ -119,7 +119,7 @@ static int pwmled_remove(struct platform_device *pdev) ...@@ -119,7 +119,7 @@ static int pwmled_remove(struct platform_device *pdev)
struct pwmled *leds; struct pwmled *leds;
unsigned i; unsigned i;
pdata = pdev->dev.platform_data; pdata = dev_get_platdata(&pdev->dev);
leds = platform_get_drvdata(pdev); leds = platform_get_drvdata(pdev);
for (i = 0; i < pdata->num_leds; i++) { for (i = 0; i < pdata->num_leds; i++) {
......
...@@ -684,7 +684,7 @@ static int bd2802_probe(struct i2c_client *client, ...@@ -684,7 +684,7 @@ static int bd2802_probe(struct i2c_client *client,
} }
led->client = client; led->client = client;
pdata = led->pdata = client->dev.platform_data; pdata = led->pdata = dev_get_platdata(&client->dev);
i2c_set_clientdata(client, led); i2c_set_clientdata(client, led);
/* Configure RESET GPIO (L: RESET, H: RESET cancel) */ /* Configure RESET GPIO (L: RESET, H: RESET cancel) */
......
...@@ -40,7 +40,7 @@ static int __init clevo_mail_led_dmi_callback(const struct dmi_system_id *id) ...@@ -40,7 +40,7 @@ static int __init clevo_mail_led_dmi_callback(const struct dmi_system_id *id)
* detected as working, but in reality it is not) as low as * detected as working, but in reality it is not) as low as
* possible. * possible.
*/ */
static struct dmi_system_id __initdata clevo_mail_led_dmi_table[] = { static struct dmi_system_id clevo_mail_led_dmi_table[] __initdata = {
{ {
.callback = clevo_mail_led_dmi_callback, .callback = clevo_mail_led_dmi_callback,
.ident = "Clevo D410J", .ident = "Clevo D410J",
......
...@@ -93,7 +93,7 @@ static void da903x_led_set(struct led_classdev *led_cdev, ...@@ -93,7 +93,7 @@ static void da903x_led_set(struct led_classdev *led_cdev,
static int da903x_led_probe(struct platform_device *pdev) static int da903x_led_probe(struct platform_device *pdev)
{ {
struct led_info *pdata = pdev->dev.platform_data; struct led_info *pdata = dev_get_platdata(&pdev->dev);
struct da903x_led *led; struct da903x_led *led;
int id, ret; int id, ret;
......
...@@ -112,7 +112,7 @@ static int da9052_led_probe(struct platform_device *pdev) ...@@ -112,7 +112,7 @@ static int da9052_led_probe(struct platform_device *pdev)
int i; int i;
da9052 = dev_get_drvdata(pdev->dev.parent); da9052 = dev_get_drvdata(pdev->dev.parent);
pdata = da9052->dev->platform_data; pdata = dev_get_platdata(da9052->dev);
if (pdata == NULL) { if (pdata == NULL) {
dev_err(&pdev->dev, "No platform data\n"); dev_err(&pdev->dev, "No platform data\n");
goto err; goto err;
...@@ -185,7 +185,7 @@ static int da9052_led_remove(struct platform_device *pdev) ...@@ -185,7 +185,7 @@ static int da9052_led_remove(struct platform_device *pdev)
int i; int i;
da9052 = dev_get_drvdata(pdev->dev.parent); da9052 = dev_get_drvdata(pdev->dev.parent);
pdata = da9052->dev->platform_data; pdata = dev_get_platdata(da9052->dev);
pled = pdata->pled; pled = pdata->pled;
for (i = 0; i < pled->num_leds; i++) { for (i = 0; i < pled->num_leds; i++) {
......
...@@ -233,7 +233,7 @@ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) ...@@ -233,7 +233,7 @@ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
static int gpio_led_probe(struct platform_device *pdev) static int gpio_led_probe(struct platform_device *pdev)
{ {
struct gpio_led_platform_data *pdata = pdev->dev.platform_data; struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct gpio_leds_priv *priv; struct gpio_leds_priv *priv;
int i, ret = 0; int i, ret = 0;
......
...@@ -403,7 +403,7 @@ static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set); ...@@ -403,7 +403,7 @@ static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set);
static int lm3530_probe(struct i2c_client *client, static int lm3530_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct lm3530_platform_data *pdata = client->dev.platform_data; struct lm3530_platform_data *pdata = dev_get_platdata(&client->dev);
struct lm3530_data *drvdata; struct lm3530_data *drvdata;
int err = 0; int err = 0;
......
...@@ -671,7 +671,7 @@ static int lm3533_led_probe(struct platform_device *pdev) ...@@ -671,7 +671,7 @@ static int lm3533_led_probe(struct platform_device *pdev)
if (!lm3533) if (!lm3533)
return -EINVAL; return -EINVAL;
pdata = pdev->dev.platform_data; pdata = dev_get_platdata(&pdev->dev);
if (!pdata) { if (!pdata) {
dev_err(&pdev->dev, "no platform data\n"); dev_err(&pdev->dev, "no platform data\n");
return -EINVAL; return -EINVAL;
......
...@@ -423,7 +423,7 @@ static const struct regmap_config lm355x_regmap = { ...@@ -423,7 +423,7 @@ static const struct regmap_config lm355x_regmap = {
static int lm355x_probe(struct i2c_client *client, static int lm355x_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct lm355x_platform_data *pdata = client->dev.platform_data; struct lm355x_platform_data *pdata = dev_get_platdata(&client->dev);
struct lm355x_chip_data *chip; struct lm355x_chip_data *chip;
int err; int err;
......
...@@ -316,7 +316,7 @@ static const struct regmap_config lm3642_regmap = { ...@@ -316,7 +316,7 @@ static const struct regmap_config lm3642_regmap = {
static int lm3642_probe(struct i2c_client *client, static int lm3642_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct lm3642_platform_data *pdata = client->dev.platform_data; struct lm3642_platform_data *pdata = dev_get_platdata(&client->dev);
struct lm3642_chip_data *chip; struct lm3642_chip_data *chip;
int err; int err;
......
...@@ -289,7 +289,7 @@ static void lp3944_led_set_brightness(struct led_classdev *led_cdev, ...@@ -289,7 +289,7 @@ static void lp3944_led_set_brightness(struct led_classdev *led_cdev,
dev_dbg(&led->client->dev, "%s: %s, %d\n", dev_dbg(&led->client->dev, "%s: %s, %d\n",
__func__, led_cdev->name, brightness); __func__, led_cdev->name, brightness);
led->status = brightness; led->status = !!brightness;
schedule_work(&led->work); schedule_work(&led->work);
} }
...@@ -377,7 +377,8 @@ static int lp3944_configure(struct i2c_client *client, ...@@ -377,7 +377,8 @@ static int lp3944_configure(struct i2c_client *client,
static int lp3944_probe(struct i2c_client *client, static int lp3944_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data; struct lp3944_platform_data *lp3944_pdata =
dev_get_platdata(&client->dev);
struct lp3944_data *data; struct lp3944_data *data;
int err; int err;
...@@ -413,7 +414,7 @@ static int lp3944_probe(struct i2c_client *client, ...@@ -413,7 +414,7 @@ static int lp3944_probe(struct i2c_client *client,
static int lp3944_remove(struct i2c_client *client) static int lp3944_remove(struct i2c_client *client)
{ {
struct lp3944_platform_data *pdata = client->dev.platform_data; struct lp3944_platform_data *pdata = dev_get_platdata(&client->dev);
struct lp3944_data *data = i2c_get_clientdata(client); struct lp3944_data *data = i2c_get_clientdata(client);
int i; int i;
......
...@@ -220,17 +220,11 @@ static int lp5521_update_program_memory(struct lp55xx_chip *chip, ...@@ -220,17 +220,11 @@ static int lp5521_update_program_memory(struct lp55xx_chip *chip,
}; };
unsigned cmd; unsigned cmd;
char c[3]; char c[3];
int program_size;
int nrchars; int nrchars;
int offset = 0;
int ret; int ret;
int i; int offset = 0;
int i = 0;
/* clear program memory before updating */
for (i = 0; i < LP5521_PROGRAM_LENGTH; i++)
lp55xx_write(chip, addr[idx] + i, 0);
i = 0;
while ((offset < size - 1) && (i < LP5521_PROGRAM_LENGTH)) { while ((offset < size - 1) && (i < LP5521_PROGRAM_LENGTH)) {
/* separate sscanfs because length is working only for %s */ /* separate sscanfs because length is working only for %s */
ret = sscanf(data + offset, "%2s%n ", c, &nrchars); ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
...@@ -250,11 +244,19 @@ static int lp5521_update_program_memory(struct lp55xx_chip *chip, ...@@ -250,11 +244,19 @@ static int lp5521_update_program_memory(struct lp55xx_chip *chip,
if (i % 2) if (i % 2)
goto err; goto err;
program_size = i; mutex_lock(&chip->lock);
for (i = 0; i < program_size; i++)
lp55xx_write(chip, addr[idx] + i, pattern[i]);
return 0; for (i = 0; i < LP5521_PROGRAM_LENGTH; i++) {
ret = lp55xx_write(chip, addr[idx] + i, pattern[i]);
if (ret) {
mutex_unlock(&chip->lock);
return -EINVAL;
}
}
mutex_unlock(&chip->lock);
return size;
err: err:
dev_err(&chip->cl->dev, "wrong pattern format\n"); dev_err(&chip->cl->dev, "wrong pattern format\n");
...@@ -365,6 +367,80 @@ static void lp5521_led_brightness_work(struct work_struct *work) ...@@ -365,6 +367,80 @@ static void lp5521_led_brightness_work(struct work_struct *work)
mutex_unlock(&chip->lock); mutex_unlock(&chip->lock);
} }
static ssize_t show_engine_mode(struct device *dev,
struct device_attribute *attr,
char *buf, int nr)
{
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
struct lp55xx_chip *chip = led->chip;
enum lp55xx_engine_mode mode = chip->engines[nr - 1].mode;
switch (mode) {
case LP55XX_ENGINE_RUN:
return sprintf(buf, "run\n");
case LP55XX_ENGINE_LOAD:
return sprintf(buf, "load\n");
case LP55XX_ENGINE_DISABLED:
default:
return sprintf(buf, "disabled\n");
}
}
show_mode(1)
show_mode(2)
show_mode(3)
static ssize_t store_engine_mode(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len, int nr)
{
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
struct lp55xx_chip *chip = led->chip;
struct lp55xx_engine *engine = &chip->engines[nr - 1];
mutex_lock(&chip->lock);
chip->engine_idx = nr;
if (!strncmp(buf, "run", 3)) {
lp5521_run_engine(chip, true);
engine->mode = LP55XX_ENGINE_RUN;
} else if (!strncmp(buf, "load", 4)) {
lp5521_stop_engine(chip);
lp5521_load_engine(chip);
engine->mode = LP55XX_ENGINE_LOAD;
} else if (!strncmp(buf, "disabled", 8)) {
lp5521_stop_engine(chip);
engine->mode = LP55XX_ENGINE_DISABLED;
}
mutex_unlock(&chip->lock);
return len;
}
store_mode(1)
store_mode(2)
store_mode(3)
static ssize_t store_engine_load(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len, int nr)
{
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
struct lp55xx_chip *chip = led->chip;
mutex_lock(&chip->lock);
chip->engine_idx = nr;
lp5521_load_engine(chip);
mutex_unlock(&chip->lock);
return lp5521_update_program_memory(chip, buf, len);
}
store_load(1)
store_load(2)
store_load(3)
static ssize_t lp5521_selftest(struct device *dev, static ssize_t lp5521_selftest(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
...@@ -381,9 +457,21 @@ static ssize_t lp5521_selftest(struct device *dev, ...@@ -381,9 +457,21 @@ static ssize_t lp5521_selftest(struct device *dev,
} }
/* device attributes */ /* device attributes */
static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL); static LP55XX_DEV_ATTR_RW(engine1_mode, show_engine1_mode, store_engine1_mode);
static LP55XX_DEV_ATTR_RW(engine2_mode, show_engine2_mode, store_engine2_mode);
static LP55XX_DEV_ATTR_RW(engine3_mode, show_engine3_mode, store_engine3_mode);
static LP55XX_DEV_ATTR_WO(engine1_load, store_engine1_load);
static LP55XX_DEV_ATTR_WO(engine2_load, store_engine2_load);
static LP55XX_DEV_ATTR_WO(engine3_load, store_engine3_load);
static LP55XX_DEV_ATTR_RO(selftest, lp5521_selftest);
static struct attribute *lp5521_attributes[] = { static struct attribute *lp5521_attributes[] = {
&dev_attr_engine1_mode.attr,
&dev_attr_engine2_mode.attr,
&dev_attr_engine3_mode.attr,
&dev_attr_engine1_load.attr,
&dev_attr_engine2_load.attr,
&dev_attr_engine3_load.attr,
&dev_attr_selftest.attr, &dev_attr_selftest.attr,
NULL NULL
}; };
...@@ -420,7 +508,7 @@ static int lp5521_probe(struct i2c_client *client, ...@@ -420,7 +508,7 @@ static int lp5521_probe(struct i2c_client *client,
struct lp55xx_platform_data *pdata; struct lp55xx_platform_data *pdata;
struct device_node *np = client->dev.of_node; struct device_node *np = client->dev.of_node;
if (!client->dev.platform_data) { if (!dev_get_platdata(&client->dev)) {
if (np) { if (np) {
ret = lp55xx_of_populate_pdata(&client->dev, np); ret = lp55xx_of_populate_pdata(&client->dev, np);
if (ret < 0) if (ret < 0)
...@@ -430,7 +518,7 @@ static int lp5521_probe(struct i2c_client *client, ...@@ -430,7 +518,7 @@ static int lp5521_probe(struct i2c_client *client,
return -EINVAL; return -EINVAL;
} }
} }
pdata = client->dev.platform_data; pdata = dev_get_platdata(&client->dev);
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip) if (!chip)
......
This diff is collapsed.
...@@ -477,8 +477,8 @@ static ssize_t lp5562_store_engine_mux(struct device *dev, ...@@ -477,8 +477,8 @@ static ssize_t lp5562_store_engine_mux(struct device *dev,
return len; return len;
} }
static DEVICE_ATTR(led_pattern, S_IWUSR, NULL, lp5562_store_pattern); static LP55XX_DEV_ATTR_WO(led_pattern, lp5562_store_pattern);
static DEVICE_ATTR(engine_mux, S_IWUSR, NULL, lp5562_store_engine_mux); static LP55XX_DEV_ATTR_WO(engine_mux, lp5562_store_engine_mux);
static struct attribute *lp5562_attributes[] = { static struct attribute *lp5562_attributes[] = {
&dev_attr_led_pattern.attr, &dev_attr_led_pattern.attr,
...@@ -518,7 +518,7 @@ static int lp5562_probe(struct i2c_client *client, ...@@ -518,7 +518,7 @@ static int lp5562_probe(struct i2c_client *client,
struct lp55xx_platform_data *pdata; struct lp55xx_platform_data *pdata;
struct device_node *np = client->dev.of_node; struct device_node *np = client->dev.of_node;
if (!client->dev.platform_data) { if (!dev_get_platdata(&client->dev)) {
if (np) { if (np) {
ret = lp55xx_of_populate_pdata(&client->dev, np); ret = lp55xx_of_populate_pdata(&client->dev, np);
if (ret < 0) if (ret < 0)
...@@ -528,7 +528,7 @@ static int lp5562_probe(struct i2c_client *client, ...@@ -528,7 +528,7 @@ static int lp5562_probe(struct i2c_client *client,
return -EINVAL; return -EINVAL;
} }
} }
pdata = client->dev.platform_data; pdata = dev_get_platdata(&client->dev);
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip) if (!chip)
......
...@@ -593,6 +593,9 @@ int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np) ...@@ -593,6 +593,9 @@ int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np)
of_property_read_string(np, "label", &pdata->label); of_property_read_string(np, "label", &pdata->label);
of_property_read_u8(np, "clock-mode", &pdata->clock_mode); of_property_read_u8(np, "clock-mode", &pdata->clock_mode);
/* LP8501 specific */
of_property_read_u8(np, "pwr-sel", (u8 *)&pdata->pwr_sel);
dev->platform_data = pdata; dev->platform_data = pdata;
return 0; return 0;
......
...@@ -20,8 +20,62 @@ enum lp55xx_engine_index { ...@@ -20,8 +20,62 @@ enum lp55xx_engine_index {
LP55XX_ENGINE_1, LP55XX_ENGINE_1,
LP55XX_ENGINE_2, LP55XX_ENGINE_2,
LP55XX_ENGINE_3, LP55XX_ENGINE_3,
LP55XX_ENGINE_MAX = LP55XX_ENGINE_3,
}; };
enum lp55xx_engine_mode {
LP55XX_ENGINE_DISABLED,
LP55XX_ENGINE_LOAD,
LP55XX_ENGINE_RUN,
};
#define LP55XX_DEV_ATTR_RW(name, show, store) \
DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show, store)
#define LP55XX_DEV_ATTR_RO(name, show) \
DEVICE_ATTR(name, S_IRUGO, show, NULL)
#define LP55XX_DEV_ATTR_WO(name, store) \
DEVICE_ATTR(name, S_IWUSR, NULL, store)
#define show_mode(nr) \
static ssize_t show_engine##nr##_mode(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
return show_engine_mode(dev, attr, buf, nr); \
}
#define store_mode(nr) \
static ssize_t store_engine##nr##_mode(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t len) \
{ \
return store_engine_mode(dev, attr, buf, len, nr); \
}
#define show_leds(nr) \
static ssize_t show_engine##nr##_leds(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
return show_engine_leds(dev, attr, buf, nr); \
}
#define store_leds(nr) \
static ssize_t store_engine##nr##_leds(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t len) \
{ \
return store_engine_leds(dev, attr, buf, len, nr); \
}
#define store_load(nr) \
static ssize_t store_engine##nr##_load(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t len) \
{ \
return store_engine_load(dev, attr, buf, len, nr); \
}
struct lp55xx_led; struct lp55xx_led;
struct lp55xx_chip; struct lp55xx_chip;
...@@ -71,6 +125,16 @@ struct lp55xx_device_config { ...@@ -71,6 +125,16 @@ struct lp55xx_device_config {
const struct attribute_group *dev_attr_group; const struct attribute_group *dev_attr_group;
}; };
/*
* struct lp55xx_engine
* @mode : Engine mode
* @led_mux : Mux bits for LED selection. Only used in LP5523
*/
struct lp55xx_engine {
enum lp55xx_engine_mode mode;
u16 led_mux;
};
/* /*
* struct lp55xx_chip * struct lp55xx_chip
* @cl : I2C communication for access registers * @cl : I2C communication for access registers
...@@ -79,6 +143,7 @@ struct lp55xx_device_config { ...@@ -79,6 +143,7 @@ struct lp55xx_device_config {
* @num_leds : Number of registered LEDs * @num_leds : Number of registered LEDs
* @cfg : Device specific configuration data * @cfg : Device specific configuration data
* @engine_idx : Selected engine number * @engine_idx : Selected engine number
* @engines : Engine structure for the device attribute R/W interface
* @fw : Firmware data for running a LED pattern * @fw : Firmware data for running a LED pattern
*/ */
struct lp55xx_chip { struct lp55xx_chip {
...@@ -89,6 +154,7 @@ struct lp55xx_chip { ...@@ -89,6 +154,7 @@ struct lp55xx_chip {
int num_leds; int num_leds;
struct lp55xx_device_config *cfg; struct lp55xx_device_config *cfg;
enum lp55xx_engine_index engine_idx; enum lp55xx_engine_index engine_idx;
struct lp55xx_engine engines[LP55XX_ENGINE_MAX];
const struct firmware *fw; const struct firmware *fw;
}; };
......
/*
* TI LP8501 9 channel LED Driver
*
* Copyright (C) 2013 Texas Instruments
*
* Author: Milo(Woogyom) Kim <milo.kim@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*/
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_data/leds-lp55xx.h>
#include <linux/slab.h>
#include "leds-lp55xx-common.h"
#define LP8501_PROGRAM_LENGTH 32
#define LP8501_MAX_LEDS 9
/* Registers */
#define LP8501_REG_ENABLE 0x00
#define LP8501_ENABLE BIT(6)
#define LP8501_EXEC_M 0x3F
#define LP8501_EXEC_ENG1_M 0x30
#define LP8501_EXEC_ENG2_M 0x0C
#define LP8501_EXEC_ENG3_M 0x03
#define LP8501_RUN_ENG1 0x20
#define LP8501_RUN_ENG2 0x08
#define LP8501_RUN_ENG3 0x02
#define LP8501_REG_OP_MODE 0x01
#define LP8501_MODE_ENG1_M 0x30
#define LP8501_MODE_ENG2_M 0x0C
#define LP8501_MODE_ENG3_M 0x03
#define LP8501_LOAD_ENG1 0x10
#define LP8501_LOAD_ENG2 0x04
#define LP8501_LOAD_ENG3 0x01
#define LP8501_REG_PWR_CONFIG 0x05
#define LP8501_PWR_CONFIG_M 0x03
#define LP8501_REG_LED_PWM_BASE 0x16
#define LP8501_REG_LED_CURRENT_BASE 0x26
#define LP8501_REG_CONFIG 0x36
#define LP8501_PWM_PSAVE BIT(7)
#define LP8501_AUTO_INC BIT(6)
#define LP8501_PWR_SAVE BIT(5)
#define LP8501_CP_AUTO 0x18
#define LP8501_INT_CLK BIT(0)
#define LP8501_DEFAULT_CFG \
(LP8501_PWM_PSAVE | LP8501_AUTO_INC | LP8501_PWR_SAVE | LP8501_CP_AUTO)
#define LP8501_REG_RESET 0x3D
#define LP8501_RESET 0xFF
#define LP8501_REG_PROG_PAGE_SEL 0x4F
#define LP8501_PAGE_ENG1 0
#define LP8501_PAGE_ENG2 1
#define LP8501_PAGE_ENG3 2
#define LP8501_REG_PROG_MEM 0x50
#define LP8501_ENG1_IS_LOADING(mode) \
((mode & LP8501_MODE_ENG1_M) == LP8501_LOAD_ENG1)
#define LP8501_ENG2_IS_LOADING(mode) \
((mode & LP8501_MODE_ENG2_M) == LP8501_LOAD_ENG2)
#define LP8501_ENG3_IS_LOADING(mode) \
((mode & LP8501_MODE_ENG3_M) == LP8501_LOAD_ENG3)
static inline void lp8501_wait_opmode_done(void)
{
usleep_range(1000, 2000);
}
static void lp8501_set_led_current(struct lp55xx_led *led, u8 led_current)
{
led->led_current = led_current;
lp55xx_write(led->chip, LP8501_REG_LED_CURRENT_BASE + led->chan_nr,
led_current);
}
static int lp8501_post_init_device(struct lp55xx_chip *chip)
{
int ret;
u8 val = LP8501_DEFAULT_CFG;
ret = lp55xx_write(chip, LP8501_REG_ENABLE, LP8501_ENABLE);
if (ret)
return ret;
/* Chip startup time is 500 us, 1 - 2 ms gives some margin */
usleep_range(1000, 2000);
if (chip->pdata->clock_mode != LP55XX_CLOCK_EXT)
val |= LP8501_INT_CLK;
ret = lp55xx_write(chip, LP8501_REG_CONFIG, val);
if (ret)
return ret;
/* Power selection for each output */
return lp55xx_update_bits(chip, LP8501_REG_PWR_CONFIG,
LP8501_PWR_CONFIG_M, chip->pdata->pwr_sel);
}
static void lp8501_load_engine(struct lp55xx_chip *chip)
{
enum lp55xx_engine_index idx = chip->engine_idx;
u8 mask[] = {
[LP55XX_ENGINE_1] = LP8501_MODE_ENG1_M,
[LP55XX_ENGINE_2] = LP8501_MODE_ENG2_M,
[LP55XX_ENGINE_3] = LP8501_MODE_ENG3_M,
};
u8 val[] = {
[LP55XX_ENGINE_1] = LP8501_LOAD_ENG1,
[LP55XX_ENGINE_2] = LP8501_LOAD_ENG2,
[LP55XX_ENGINE_3] = LP8501_LOAD_ENG3,
};
u8 page_sel[] = {
[LP55XX_ENGINE_1] = LP8501_PAGE_ENG1,
[LP55XX_ENGINE_2] = LP8501_PAGE_ENG2,
[LP55XX_ENGINE_3] = LP8501_PAGE_ENG3,
};
lp55xx_update_bits(chip, LP8501_REG_OP_MODE, mask[idx], val[idx]);
lp8501_wait_opmode_done();
lp55xx_write(chip, LP8501_REG_PROG_PAGE_SEL, page_sel[idx]);
}
static void lp8501_stop_engine(struct lp55xx_chip *chip)
{
lp55xx_write(chip, LP8501_REG_OP_MODE, 0);
lp8501_wait_opmode_done();
}
static void lp8501_turn_off_channels(struct lp55xx_chip *chip)
{
int i;
for (i = 0; i < LP8501_MAX_LEDS; i++)
lp55xx_write(chip, LP8501_REG_LED_PWM_BASE + i, 0);
}
static void lp8501_run_engine(struct lp55xx_chip *chip, bool start)
{
int ret;
u8 mode;
u8 exec;
/* stop engine */
if (!start) {
lp8501_stop_engine(chip);
lp8501_turn_off_channels(chip);
return;
}
/*
* To run the engine,
* operation mode and enable register should updated at the same time
*/
ret = lp55xx_read(chip, LP8501_REG_OP_MODE, &mode);
if (ret)
return;
ret = lp55xx_read(chip, LP8501_REG_ENABLE, &exec);
if (ret)
return;
/* change operation mode to RUN only when each engine is loading */
if (LP8501_ENG1_IS_LOADING(mode)) {
mode = (mode & ~LP8501_MODE_ENG1_M) | LP8501_RUN_ENG1;
exec = (exec & ~LP8501_EXEC_ENG1_M) | LP8501_RUN_ENG1;
}
if (LP8501_ENG2_IS_LOADING(mode)) {
mode = (mode & ~LP8501_MODE_ENG2_M) | LP8501_RUN_ENG2;
exec = (exec & ~LP8501_EXEC_ENG2_M) | LP8501_RUN_ENG2;
}
if (LP8501_ENG3_IS_LOADING(mode)) {
mode = (mode & ~LP8501_MODE_ENG3_M) | LP8501_RUN_ENG3;
exec = (exec & ~LP8501_EXEC_ENG3_M) | LP8501_RUN_ENG3;
}
lp55xx_write(chip, LP8501_REG_OP_MODE, mode);
lp8501_wait_opmode_done();
lp55xx_update_bits(chip, LP8501_REG_ENABLE, LP8501_EXEC_M, exec);
}
static int lp8501_update_program_memory(struct lp55xx_chip *chip,
const u8 *data, size_t size)
{
u8 pattern[LP8501_PROGRAM_LENGTH] = {0};
unsigned cmd;
char c[3];
int update_size;
int nrchars;
int offset = 0;
int ret;
int i;
/* clear program memory before updating */
for (i = 0; i < LP8501_PROGRAM_LENGTH; i++)
lp55xx_write(chip, LP8501_REG_PROG_MEM + i, 0);
i = 0;
while ((offset < size - 1) && (i < LP8501_PROGRAM_LENGTH)) {
/* separate sscanfs because length is working only for %s */
ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
if (ret != 1)
goto err;
ret = sscanf(c, "%2x", &cmd);
if (ret != 1)
goto err;
pattern[i] = (u8)cmd;
offset += nrchars;
i++;
}
/* Each instruction is 16bit long. Check that length is even */
if (i % 2)
goto err;
update_size = i;
for (i = 0; i < update_size; i++)
lp55xx_write(chip, LP8501_REG_PROG_MEM + i, pattern[i]);
return 0;
err:
dev_err(&chip->cl->dev, "wrong pattern format\n");
return -EINVAL;
}
static void lp8501_firmware_loaded(struct lp55xx_chip *chip)
{
const struct firmware *fw = chip->fw;
if (fw->size > LP8501_PROGRAM_LENGTH) {
dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",
fw->size);
return;
}
/*
* Program momery sequence
* 1) set engine mode to "LOAD"
* 2) write firmware data into program memory
*/
lp8501_load_engine(chip);
lp8501_update_program_memory(chip, fw->data, fw->size);
}
static void lp8501_led_brightness_work(struct work_struct *work)
{
struct lp55xx_led *led = container_of(work, struct lp55xx_led,
brightness_work);
struct lp55xx_chip *chip = led->chip;
mutex_lock(&chip->lock);
lp55xx_write(chip, LP8501_REG_LED_PWM_BASE + led->chan_nr,
led->brightness);
mutex_unlock(&chip->lock);
}
/* Chip specific configurations */
static struct lp55xx_device_config lp8501_cfg = {
.reset = {
.addr = LP8501_REG_RESET,
.val = LP8501_RESET,
},
.enable = {
.addr = LP8501_REG_ENABLE,
.val = LP8501_ENABLE,
},
.max_channel = LP8501_MAX_LEDS,
.post_init_device = lp8501_post_init_device,
.brightness_work_fn = lp8501_led_brightness_work,
.set_led_current = lp8501_set_led_current,
.firmware_cb = lp8501_firmware_loaded,
.run_engine = lp8501_run_engine,
};
static int lp8501_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
struct lp55xx_chip *chip;
struct lp55xx_led *led;
struct lp55xx_platform_data *pdata;
struct device_node *np = client->dev.of_node;
if (!dev_get_platdata(&client->dev)) {
if (np) {
ret = lp55xx_of_populate_pdata(&client->dev, np);
if (ret < 0)
return ret;
} else {
dev_err(&client->dev, "no platform data\n");
return -EINVAL;
}
}
pdata = dev_get_platdata(&client->dev);
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
led = devm_kzalloc(&client->dev,
sizeof(*led) * pdata->num_channels, GFP_KERNEL);
if (!led)
return -ENOMEM;
chip->cl = client;
chip->pdata = pdata;
chip->cfg = &lp8501_cfg;
mutex_init(&chip->lock);
i2c_set_clientdata(client, led);
ret = lp55xx_init_device(chip);
if (ret)
goto err_init;
dev_info(&client->dev, "%s Programmable led chip found\n", id->name);
ret = lp55xx_register_leds(led, chip);
if (ret)
goto err_register_leds;
ret = lp55xx_register_sysfs(chip);
if (ret) {
dev_err(&client->dev, "registering sysfs failed\n");
goto err_register_sysfs;
}
return 0;
err_register_sysfs:
lp55xx_unregister_leds(led, chip);
err_register_leds:
lp55xx_deinit_device(chip);
err_init:
return ret;
}
static int lp8501_remove(struct i2c_client *client)
{
struct lp55xx_led *led = i2c_get_clientdata(client);
struct lp55xx_chip *chip = led->chip;
lp8501_stop_engine(chip);
lp55xx_unregister_sysfs(chip);
lp55xx_unregister_leds(led, chip);
lp55xx_deinit_device(chip);
return 0;
}
static const struct i2c_device_id lp8501_id[] = {
{ "lp8501", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp8501_id);
#ifdef CONFIG_OF
static const struct of_device_id of_lp8501_leds_match[] = {
{ .compatible = "ti,lp8501", },
{},
};
MODULE_DEVICE_TABLE(of, of_lp8501_leds_match);
#endif
static struct i2c_driver lp8501_driver = {
.driver = {
.name = "lp8501",
.of_match_table = of_match_ptr(of_lp8501_leds_match),
},
.probe = lp8501_probe,
.remove = lp8501_remove,
.id_table = lp8501_id,
};
module_i2c_driver(lp8501_driver);
MODULE_DESCRIPTION("Texas Instruments LP8501 LED drvier");
MODULE_AUTHOR("Milo Kim");
MODULE_LICENSE("GPL");
...@@ -135,7 +135,7 @@ static void delete_lt3593_led(struct lt3593_led_data *led) ...@@ -135,7 +135,7 @@ static void delete_lt3593_led(struct lt3593_led_data *led)
static int lt3593_led_probe(struct platform_device *pdev) static int lt3593_led_probe(struct platform_device *pdev)
{ {
struct gpio_led_platform_data *pdata = pdev->dev.platform_data; struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct lt3593_led_data *leds_data; struct lt3593_led_data *leds_data;
int i, ret = 0; int i, ret = 0;
...@@ -169,7 +169,7 @@ static int lt3593_led_probe(struct platform_device *pdev) ...@@ -169,7 +169,7 @@ static int lt3593_led_probe(struct platform_device *pdev)
static int lt3593_led_remove(struct platform_device *pdev) static int lt3593_led_remove(struct platform_device *pdev)
{ {
int i; int i;
struct gpio_led_platform_data *pdata = pdev->dev.platform_data; struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct lt3593_led_data *leds_data; struct lt3593_led_data *leds_data;
leds_data = platform_get_drvdata(pdev); leds_data = platform_get_drvdata(pdev);
......
...@@ -306,7 +306,7 @@ create_netxbig_led(struct platform_device *pdev, ...@@ -306,7 +306,7 @@ create_netxbig_led(struct platform_device *pdev,
struct netxbig_led_data *led_dat, struct netxbig_led_data *led_dat,
const struct netxbig_led *template) const struct netxbig_led *template)
{ {
struct netxbig_led_platform_data *pdata = pdev->dev.platform_data; struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
int ret; int ret;
spin_lock_init(&led_dat->lock); spin_lock_init(&led_dat->lock);
...@@ -354,7 +354,7 @@ create_netxbig_led(struct platform_device *pdev, ...@@ -354,7 +354,7 @@ create_netxbig_led(struct platform_device *pdev,
static int netxbig_led_probe(struct platform_device *pdev) static int netxbig_led_probe(struct platform_device *pdev)
{ {
struct netxbig_led_platform_data *pdata = pdev->dev.platform_data; struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct netxbig_led_data *leds_data; struct netxbig_led_data *leds_data;
int i; int i;
int ret; int ret;
...@@ -391,7 +391,7 @@ static int netxbig_led_probe(struct platform_device *pdev) ...@@ -391,7 +391,7 @@ static int netxbig_led_probe(struct platform_device *pdev)
static int netxbig_led_remove(struct platform_device *pdev) static int netxbig_led_remove(struct platform_device *pdev)
{ {
struct netxbig_led_platform_data *pdata = pdev->dev.platform_data; struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct netxbig_led_data *leds_data; struct netxbig_led_data *leds_data;
int i; int i;
......
...@@ -321,7 +321,7 @@ static inline int sizeof_ns2_led_priv(int num_leds) ...@@ -321,7 +321,7 @@ static inline int sizeof_ns2_led_priv(int num_leds)
static int ns2_led_probe(struct platform_device *pdev) static int ns2_led_probe(struct platform_device *pdev)
{ {
struct ns2_led_platform_data *pdata = pdev->dev.platform_data; struct ns2_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct ns2_led_priv *priv; struct ns2_led_priv *priv;
int i; int i;
int ret; int ret;
......
...@@ -446,7 +446,8 @@ static int pca9532_probe(struct i2c_client *client, ...@@ -446,7 +446,8 @@ static int pca9532_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct pca9532_data *data = i2c_get_clientdata(client); struct pca9532_data *data = i2c_get_clientdata(client);
struct pca9532_platform_data *pca9532_pdata = client->dev.platform_data; struct pca9532_platform_data *pca9532_pdata =
dev_get_platdata(&client->dev);
if (!pca9532_pdata) if (!pca9532_pdata)
return -EIO; return -EIO;
......
...@@ -267,7 +267,7 @@ static int pca955x_probe(struct i2c_client *client, ...@@ -267,7 +267,7 @@ static int pca955x_probe(struct i2c_client *client,
chip = &pca955x_chipdefs[id->driver_data]; chip = &pca955x_chipdefs[id->driver_data];
adapter = to_i2c_adapter(client->dev.parent); adapter = to_i2c_adapter(client->dev.parent);
pdata = client->dev.platform_data; pdata = dev_get_platdata(&client->dev);
/* Make sure the slave address / chip type combo given is possible */ /* Make sure the slave address / chip type combo given is possible */
if ((client->addr & ~((1 << chip->slv_addr_shift) - 1)) != if ((client->addr & ~((1 << chip->slv_addr_shift) - 1)) !=
......
/*
* Copyright 2011 bct electronic GmbH
*
* Author: Peter Meerwald <p.meerwald@bct-electronic.com>
*
* Based on leds-pca955x.c
*
* This file is subject to the terms and conditions of version 2 of
* the GNU General Public License. See the file COPYING in the main
* directory of this archive for more details.
*
* LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62)
*
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/leds.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/workqueue.h>
#include <linux/slab.h>
#include <linux/platform_data/leds-pca9633.h>
/* LED select registers determine the source that drives LED outputs */
#define PCA9633_LED_OFF 0x0 /* LED driver off */
#define PCA9633_LED_ON 0x1 /* LED driver on */
#define PCA9633_LED_PWM 0x2 /* Controlled through PWM */
#define PCA9633_LED_GRP_PWM 0x3 /* Controlled through PWM/GRPPWM */
#define PCA9633_MODE1 0x00
#define PCA9633_MODE2 0x01
#define PCA9633_PWM_BASE 0x02
#define PCA9633_LEDOUT 0x08
static const struct i2c_device_id pca9633_id[] = {
{ "pca9633", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pca9633_id);
struct pca9633_led {
struct i2c_client *client;
struct work_struct work;
enum led_brightness brightness;
struct led_classdev led_cdev;
int led_num; /* 0 .. 3 potentially */
char name[32];
};
static void pca9633_led_work(struct work_struct *work)
{
struct pca9633_led *pca9633 = container_of(work,
struct pca9633_led, work);
u8 ledout = i2c_smbus_read_byte_data(pca9633->client, PCA9633_LEDOUT);
int shift = 2 * pca9633->led_num;
u8 mask = 0x3 << shift;
switch (pca9633->brightness) {
case LED_FULL:
i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
(ledout & ~mask) | (PCA9633_LED_ON << shift));
break;
case LED_OFF:
i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
ledout & ~mask);
break;
default:
i2c_smbus_write_byte_data(pca9633->client,
PCA9633_PWM_BASE + pca9633->led_num,
pca9633->brightness);
i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
(ledout & ~mask) | (PCA9633_LED_PWM << shift));
break;
}
}
static void pca9633_led_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
struct pca9633_led *pca9633;
pca9633 = container_of(led_cdev, struct pca9633_led, led_cdev);
pca9633->brightness = value;
/*
* Must use workqueue for the actual I/O since I2C operations
* can sleep.
*/
schedule_work(&pca9633->work);
}
static int pca9633_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pca9633_led *pca9633;
struct pca9633_platform_data *pdata;
int i, err;
pdata = client->dev.platform_data;
if (pdata) {
if (pdata->leds.num_leds <= 0 || pdata->leds.num_leds > 4) {
dev_err(&client->dev, "board info must claim at most 4 LEDs");
return -EINVAL;
}
}
pca9633 = devm_kzalloc(&client->dev, 4 * sizeof(*pca9633), GFP_KERNEL);
if (!pca9633)
return -ENOMEM;
i2c_set_clientdata(client, pca9633);
for (i = 0; i < 4; i++) {
pca9633[i].client = client;
pca9633[i].led_num = i;
/* Platform data can specify LED names and default triggers */
if (pdata && i < pdata->leds.num_leds) {
if (pdata->leds.leds[i].name)
snprintf(pca9633[i].name,
sizeof(pca9633[i].name), "pca9633:%s",
pdata->leds.leds[i].name);
if (pdata->leds.leds[i].default_trigger)
pca9633[i].led_cdev.default_trigger =
pdata->leds.leds[i].default_trigger;
} else {
snprintf(pca9633[i].name, sizeof(pca9633[i].name),
"pca9633:%d", i);
}
pca9633[i].led_cdev.name = pca9633[i].name;
pca9633[i].led_cdev.brightness_set = pca9633_led_set;
INIT_WORK(&pca9633[i].work, pca9633_led_work);
err = led_classdev_register(&client->dev, &pca9633[i].led_cdev);
if (err < 0)
goto exit;
}
/* Disable LED all-call address and set normal mode */
i2c_smbus_write_byte_data(client, PCA9633_MODE1, 0x00);
/* Configure output: open-drain or totem pole (push-pull) */
if (pdata && pdata->outdrv == PCA9633_OPEN_DRAIN)
i2c_smbus_write_byte_data(client, PCA9633_MODE2, 0x01);
/* Turn off LEDs */
i2c_smbus_write_byte_data(client, PCA9633_LEDOUT, 0x00);
return 0;
exit:
while (i--) {
led_classdev_unregister(&pca9633[i].led_cdev);
cancel_work_sync(&pca9633[i].work);
}
return err;
}
static int pca9633_remove(struct i2c_client *client)
{
struct pca9633_led *pca9633 = i2c_get_clientdata(client);
int i;
for (i = 0; i < 4; i++) {
led_classdev_unregister(&pca9633[i].led_cdev);
cancel_work_sync(&pca9633[i].work);
}
return 0;
}
static struct i2c_driver pca9633_driver = {
.driver = {
.name = "leds-pca9633",
.owner = THIS_MODULE,
},
.probe = pca9633_probe,
.remove = pca9633_remove,
.id_table = pca9633_id,
};
module_i2c_driver(pca9633_driver);
MODULE_AUTHOR("Peter Meerwald <p.meerwald@bct-electronic.com>");
MODULE_DESCRIPTION("PCA9633 LED driver");
MODULE_LICENSE("GPL v2");
This diff is collapsed.
...@@ -147,7 +147,7 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev) ...@@ -147,7 +147,7 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
static int led_pwm_probe(struct platform_device *pdev) static int led_pwm_probe(struct platform_device *pdev)
{ {
struct led_pwm_platform_data *pdata = pdev->dev.platform_data; struct led_pwm_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct led_pwm_priv *priv; struct led_pwm_priv *priv;
int i, ret = 0; int i, ret = 0;
......
...@@ -142,7 +142,8 @@ static void regulator_led_brightness_set(struct led_classdev *led_cdev, ...@@ -142,7 +142,8 @@ static void regulator_led_brightness_set(struct led_classdev *led_cdev,
static int regulator_led_probe(struct platform_device *pdev) static int regulator_led_probe(struct platform_device *pdev)
{ {
struct led_regulator_platform_data *pdata = pdev->dev.platform_data; struct led_regulator_platform_data *pdata =
dev_get_platdata(&pdev->dev);
struct regulator_led *led; struct regulator_led *led;
struct regulator *vcc; struct regulator *vcc;
int ret = 0; int ret = 0;
......
...@@ -71,7 +71,7 @@ static int s3c24xx_led_remove(struct platform_device *dev) ...@@ -71,7 +71,7 @@ static int s3c24xx_led_remove(struct platform_device *dev)
static int s3c24xx_led_probe(struct platform_device *dev) static int s3c24xx_led_probe(struct platform_device *dev)
{ {
struct s3c24xx_led_platdata *pdata = dev->dev.platform_data; struct s3c24xx_led_platdata *pdata = dev_get_platdata(&dev->dev);
struct s3c24xx_gpio_led *led; struct s3c24xx_gpio_led *led;
int ret; int ret;
......
...@@ -91,7 +91,7 @@ MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection"); ...@@ -91,7 +91,7 @@ MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection");
* detected as working, but in reality it is not) as low as * detected as working, but in reality it is not) as low as
* possible. * possible.
*/ */
static struct dmi_system_id __initdata nas_led_whitelist[] = { static struct dmi_system_id nas_led_whitelist[] __initdata = {
{ {
.callback = ss4200_led_dmi_callback, .callback = ss4200_led_dmi_callback,
.ident = "Intel SS4200-E", .ident = "Intel SS4200-E",
...@@ -197,7 +197,7 @@ static void nasgpio_led_set_attr(struct led_classdev *led_cdev, ...@@ -197,7 +197,7 @@ static void nasgpio_led_set_attr(struct led_classdev *led_cdev,
spin_unlock(&nasgpio_gpio_lock); spin_unlock(&nasgpio_gpio_lock);
} }
u32 nasgpio_led_get_attr(struct led_classdev *led_cdev, u32 port) static u32 nasgpio_led_get_attr(struct led_classdev *led_cdev, u32 port)
{ {
struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev); struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev);
u32 gpio_in; u32 gpio_in;
......
...@@ -737,7 +737,7 @@ static int tca6507_probe(struct i2c_client *client, ...@@ -737,7 +737,7 @@ static int tca6507_probe(struct i2c_client *client,
int i = 0; int i = 0;
adapter = to_i2c_adapter(client->dev.parent); adapter = to_i2c_adapter(client->dev.parent);
pdata = client->dev.platform_data; pdata = dev_get_platdata(&client->dev);
if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
return -EIO; return -EIO;
......
...@@ -230,9 +230,9 @@ static int wm831x_status_probe(struct platform_device *pdev) ...@@ -230,9 +230,9 @@ static int wm831x_status_probe(struct platform_device *pdev)
int id = pdev->id % ARRAY_SIZE(chip_pdata->status); int id = pdev->id % ARRAY_SIZE(chip_pdata->status);
int ret; int ret;
res = platform_get_resource(pdev, IORESOURCE_IO, 0); res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (res == NULL) { if (res == NULL) {
dev_err(&pdev->dev, "No I/O resource\n"); dev_err(&pdev->dev, "No register resource\n");
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;
} }
...@@ -246,8 +246,8 @@ static int wm831x_status_probe(struct platform_device *pdev) ...@@ -246,8 +246,8 @@ static int wm831x_status_probe(struct platform_device *pdev)
drvdata->wm831x = wm831x; drvdata->wm831x = wm831x;
drvdata->reg = res->start; drvdata->reg = res->start;
if (wm831x->dev->platform_data) if (dev_get_platdata(wm831x->dev))
chip_pdata = wm831x->dev->platform_data; chip_pdata = dev_get_platdata(wm831x->dev);
else else
chip_pdata = NULL; chip_pdata = NULL;
......
...@@ -203,7 +203,7 @@ static int wm8350_led_probe(struct platform_device *pdev) ...@@ -203,7 +203,7 @@ static int wm8350_led_probe(struct platform_device *pdev)
{ {
struct regulator *isink, *dcdc; struct regulator *isink, *dcdc;
struct wm8350_led *led; struct wm8350_led *led;
struct wm8350_led_platform_data *pdata = pdev->dev.platform_data; struct wm8350_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
int i; int i;
if (pdata == NULL) { if (pdata == NULL) {
......
...@@ -36,26 +36,28 @@ static int fb_notifier_callback(struct notifier_block *p, ...@@ -36,26 +36,28 @@ static int fb_notifier_callback(struct notifier_block *p,
struct bl_trig_notifier, notifier); struct bl_trig_notifier, notifier);
struct led_classdev *led = n->led; struct led_classdev *led = n->led;
struct fb_event *fb_event = data; struct fb_event *fb_event = data;
int *blank = fb_event->data; int *blank;
int new_status = *blank ? BLANK : UNBLANK; int new_status;
switch (event) { /* If we aren't interested in this event, skip it immediately ... */
case FB_EVENT_BLANK: if (event != FB_EVENT_BLANK)
if (new_status == n->old_status) return 0;
break;
if ((n->old_status == UNBLANK) ^ n->invert) { blank = fb_event->data;
n->brightness = led->brightness; new_status = *blank ? BLANK : UNBLANK;
__led_set_brightness(led, LED_OFF);
} else {
__led_set_brightness(led, n->brightness);
}
n->old_status = new_status; if (new_status == n->old_status)
return 0;
break; if ((n->old_status == UNBLANK) ^ n->invert) {
n->brightness = led->brightness;
__led_set_brightness(led, LED_OFF);
} else {
__led_set_brightness(led, n->brightness);
} }
n->old_status = new_status;
return 0; return 0;
} }
......
...@@ -36,6 +36,13 @@ struct lp55xx_predef_pattern { ...@@ -36,6 +36,13 @@ struct lp55xx_predef_pattern {
u8 size_b; u8 size_b;
}; };
enum lp8501_pwr_sel {
LP8501_ALL_VDD, /* D1~9 are connected to VDD */
LP8501_6VDD_3VOUT, /* D1~6 with VDD, D7~9 with VOUT */
LP8501_3VDD_6VOUT, /* D1~6 with VOUT, D7~9 with VDD */
LP8501_ALL_VOUT, /* D1~9 are connected to VOUT */
};
/* /*
* struct lp55xx_platform_data * struct lp55xx_platform_data
* @led_config : Configurable led class device * @led_config : Configurable led class device
...@@ -67,6 +74,9 @@ struct lp55xx_platform_data { ...@@ -67,6 +74,9 @@ struct lp55xx_platform_data {
/* Predefined pattern data */ /* Predefined pattern data */
struct lp55xx_predef_pattern *patterns; struct lp55xx_predef_pattern *patterns;
unsigned int num_patterns; unsigned int num_patterns;
/* LP8501 specific */
enum lp8501_pwr_sel pwr_sel;
}; };
#endif /* _LEDS_LP55XX_H */ #endif /* _LEDS_LP55XX_H */
/* /*
* PCA9633 LED chip driver. * PCA963X LED chip driver.
* *
* Copyright 2012 bct electronic GmbH * Copyright 2012 bct electronic GmbH
* Copyright 2013 Qtechnology A/S
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -18,18 +19,24 @@ ...@@ -18,18 +19,24 @@
* 02110-1301 USA * 02110-1301 USA
*/ */
#ifndef __LINUX_PCA9633_H #ifndef __LINUX_PCA963X_H
#define __LINUX_PCA9633_H #define __LINUX_PCA963X_H
#include <linux/leds.h> #include <linux/leds.h>
enum pca9633_outdrv { enum pca963x_outdrv {
PCA9633_OPEN_DRAIN, PCA963X_OPEN_DRAIN,
PCA9633_TOTEM_POLE, /* aka push-pull */ PCA963X_TOTEM_POLE, /* aka push-pull */
}; };
struct pca9633_platform_data { enum pca963x_blink_type {
PCA963X_SW_BLINK,
PCA963X_HW_BLINK,
};
struct pca963x_platform_data {
struct led_platform_data leds; struct led_platform_data leds;
enum pca9633_outdrv outdrv; enum pca963x_outdrv outdrv;
enum pca963x_blink_type blink_type;
}; };
#endif /* __LINUX_PCA9633_H*/ #endif /* __LINUX_PCA963X_H*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment