Commit 268943fb 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 subsystem update from Bryan Wu:
 "Basically this cycle is mostly cleanup for LED subsystem"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds:
  leds: s3c24xx: Remove hardware.h inclusion
  leds: replace list_for_each with list_for_each_entry
  leds: kirkwood: Cleanup in header files
  leds: pwm: Remove a warning on non-DT platforms
  leds: leds-pwm: fix duty time overflow.
  leds: leds-mc13783: Remove unneeded mc13xxx_{un}lock
  leds: leds-mc13783: Remove duplicate field in platform data
  drivers: leds: leds-tca6507: check CONFIG_GPIOLIB whether defined for 'gpio_base'
  leds: lp5523: Support LED MUX configuration on running a pattern
  leds: lp5521/5523: Fix multiple engine usage bug
  LEDS: tca6507 - fix up some comments.
  LEDS: tca6507: add device-tree support for GPIO configuration.
  LEDS: tca6507 - fix bugs in parsing of device-tree configuration.
parents 2ad48ee8 3cb6f44a
......@@ -2,6 +2,13 @@ LEDs connected to tca6507
Required properties:
- compatible : should be : "ti,tca6507".
- #address-cells: must be 1
- #size-cells: must be 0
- reg: typically 0x45.
Optional properties:
- gpio-controller: allows lines to be used as output-only GPIOs.
- #gpio-cells: if present, must be 0.
Each led is represented as a sub-node of the ti,tca6507 device.
......@@ -10,6 +17,7 @@ LED sub-node properties:
- reg : number of LED line (could be from 0 to 6)
- linux,default-trigger : (optional)
see Documentation/devicetree/bindings/leds/common.txt
- compatible: either "led" (the default) or "gpio".
Examples:
......@@ -19,6 +27,9 @@ tca6507@45 {
#size-cells = <0>;
reg = <0x45>;
gpio-controller;
#gpio-cells = <2>;
led0: red-aux@0 {
label = "red:aux";
reg = <0x0>;
......@@ -29,5 +40,10 @@ tca6507@45 {
reg = <0x5>;
linux,default-trigger = "default-on";
};
wifi-reset@6 {
reg = <0x6>;
compatible = "gpio";
};
};
......@@ -73,6 +73,10 @@ select_engine : Select which engine is used for running program
run_engine : Start program which is loaded via the firmware interface
firmware : Load program data
In case of LP5523, one more command is required, 'enginex_leds'.
It is used for selecting LED output(s) at each engine number.
In more details, please refer to 'leds-lp5523.txt'.
For example, run blinking pattern in engine #1 of LP5521
echo 1 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp5521/loading
......@@ -81,10 +85,12 @@ echo 0 > /sys/class/firmware/lp5521/loading
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
For example, run blinking pattern in engine #3 of LP55231
Two LEDs are configured as pattern output channels.
echo 3 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp55231/loading
echo "9d0740ff7e0040007e00a0010000" > /sys/class/firmware/lp55231/data
echo 0 > /sys/class/firmware/lp55231/loading
echo "000001100" > /sys/bus/i2c/devices/xxxx/engine3_leds
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
To start blinking patterns in engine #2 and #3 simultaneously,
......@@ -99,17 +105,19 @@ done
echo 1 > /sys/class/leds/red/device/run_engine
Here is another example for LP5523.
Full LED strings are selected by 'engine2_leds'.
echo 2 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp5523/loading
echo "9d80400004ff05ff437f0000" > /sys/class/firmware/lp5523/data
echo 0 > /sys/class/firmware/lp5523/loading
echo "111111111" > /sys/bus/i2c/devices/xxxx/engine2_leds
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
As soon as 'loading' is set to 0, registered callback is called.
Inside the callback, the selected engine is loaded and memory is updated.
To run programmed pattern, 'run_engine' attribute should be enabled.
The pattern sqeuence of LP8501 is same as LP5523.
The pattern sqeuence of LP8501 is similar to LP5523.
However pattern data is specific.
Ex 1) Engine 1 is used
echo 1 > /sys/bus/i2c/devices/xxxx/select_engine
......
......@@ -236,32 +236,26 @@ static struct mc13xxx_led_platform_data moboard_led[] = {
{
.id = MC13783_LED_R1,
.name = "coreboard-led-4:red",
.max_current = 2,
},
{
.id = MC13783_LED_G1,
.name = "coreboard-led-4:green",
.max_current = 2,
},
{
.id = MC13783_LED_B1,
.name = "coreboard-led-4:blue",
.max_current = 2,
},
{
.id = MC13783_LED_R2,
.name = "coreboard-led-5:red",
.max_current = 3,
},
{
.id = MC13783_LED_G2,
.name = "coreboard-led-5:green",
.max_current = 3,
},
{
.id = MC13783_LED_B2,
.name = "coreboard-led-5:blue",
.max_current = 3,
},
};
......@@ -271,8 +265,14 @@ static struct mc13xxx_leds_platform_data moboard_leds = {
.led_control[0] = MC13783_LED_C0_ENABLE | MC13783_LED_C0_ABMODE(0),
.led_control[1] = MC13783_LED_C1_SLEWLIM,
.led_control[2] = MC13783_LED_C2_SLEWLIM,
.led_control[3] = MC13783_LED_C3_PERIOD(0),
.led_control[4] = MC13783_LED_C3_PERIOD(0),
.led_control[3] = MC13783_LED_C3_PERIOD(0) |
MC13783_LED_C3_CURRENT_R1(2) |
MC13783_LED_C3_CURRENT_G1(2) |
MC13783_LED_C3_CURRENT_B1(2),
.led_control[4] = MC13783_LED_C4_PERIOD(0) |
MC13783_LED_C4_CURRENT_R2(3) |
MC13783_LED_C4_CURRENT_G2(3) |
MC13783_LED_C4_CURRENT_B2(3),
};
static struct mc13xxx_buttons_platform_data moboard_buttons = {
......
......@@ -242,18 +242,14 @@ EXPORT_SYMBOL_GPL(led_trigger_unregister);
void led_trigger_event(struct led_trigger *trig,
enum led_brightness brightness)
{
struct list_head *entry;
struct led_classdev *led_cdev;
if (!trig)
return;
read_lock(&trig->leddev_list_lock);
list_for_each(entry, &trig->led_cdevs) {
struct led_classdev *led_cdev;
led_cdev = list_entry(entry, struct led_classdev, trig_list);
list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list)
led_set_brightness(led_cdev, brightness);
}
read_unlock(&trig->leddev_list_lock);
}
EXPORT_SYMBOL_GPL(led_trigger_event);
......@@ -264,16 +260,13 @@ static void led_trigger_blink_setup(struct led_trigger *trig,
int oneshot,
int invert)
{
struct list_head *entry;
struct led_classdev *led_cdev;
if (!trig)
return;
read_lock(&trig->leddev_list_lock);
list_for_each(entry, &trig->led_cdevs) {
struct led_classdev *led_cdev;
led_cdev = list_entry(entry, struct led_classdev, trig_list);
list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) {
if (oneshot)
led_blink_set_oneshot(led_cdev, delay_on, delay_off,
invert);
......
......@@ -152,12 +152,26 @@ static void lp5521_load_engine(struct lp55xx_chip *chip)
lp5521_wait_opmode_done();
}
static void lp5521_stop_engine(struct lp55xx_chip *chip)
static void lp5521_stop_all_engines(struct lp55xx_chip *chip)
{
lp55xx_write(chip, LP5521_REG_OP_MODE, 0);
lp5521_wait_opmode_done();
}
static void lp5521_stop_engine(struct lp55xx_chip *chip)
{
enum lp55xx_engine_index idx = chip->engine_idx;
u8 mask[] = {
[LP55XX_ENGINE_1] = LP5521_MODE_R_M,
[LP55XX_ENGINE_2] = LP5521_MODE_G_M,
[LP55XX_ENGINE_3] = LP5521_MODE_B_M,
};
lp55xx_update_bits(chip, LP5521_REG_OP_MODE, mask[idx], 0);
lp5521_wait_opmode_done();
}
static void lp5521_run_engine(struct lp55xx_chip *chip, bool start)
{
int ret;
......@@ -564,7 +578,7 @@ static int lp5521_remove(struct i2c_client *client)
struct lp55xx_led *led = i2c_get_clientdata(client);
struct lp55xx_chip *chip = led->chip;
lp5521_stop_engine(chip);
lp5521_stop_all_engines(chip);
lp55xx_unregister_sysfs(chip);
lp55xx_unregister_leds(led, chip);
lp55xx_deinit_device(chip);
......
......@@ -195,12 +195,26 @@ static void lp5523_load_engine_and_select_page(struct lp55xx_chip *chip)
lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, page_sel[idx]);
}
static void lp5523_stop_engine(struct lp55xx_chip *chip)
static void lp5523_stop_all_engines(struct lp55xx_chip *chip)
{
lp55xx_write(chip, LP5523_REG_OP_MODE, 0);
lp5523_wait_opmode_done();
}
static void lp5523_stop_engine(struct lp55xx_chip *chip)
{
enum lp55xx_engine_index idx = chip->engine_idx;
u8 mask[] = {
[LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M,
[LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M,
[LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M,
};
lp55xx_update_bits(chip, LP5523_REG_OP_MODE, mask[idx], 0);
lp5523_wait_opmode_done();
}
static void lp5523_turn_off_channels(struct lp55xx_chip *chip)
{
int i;
......@@ -311,7 +325,7 @@ static int lp5523_init_program_engine(struct lp55xx_chip *chip)
}
out:
lp5523_stop_engine(chip);
lp5523_stop_all_engines(chip);
return ret;
}
......@@ -782,7 +796,7 @@ static int lp5523_remove(struct i2c_client *client)
struct lp55xx_led *led = i2c_get_clientdata(client);
struct lp55xx_chip *chip = led->chip;
lp5523_stop_engine(chip);
lp5523_stop_all_engines(chip);
lp55xx_unregister_sysfs(chip);
lp55xx_unregister_leds(led, chip);
lp55xx_deinit_device(chip);
......
......@@ -210,6 +210,7 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
{
struct lp55xx_chip *chip = context;
struct device *dev = &chip->cl->dev;
enum lp55xx_engine_index idx = chip->engine_idx;
if (!fw) {
dev_err(dev, "firmware request failed\n");
......@@ -219,6 +220,7 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
/* handling firmware data is chip dependent */
mutex_lock(&chip->lock);
chip->engines[idx - 1].mode = LP55XX_ENGINE_LOAD;
chip->fw = fw;
if (chip->cfg->firmware_cb)
chip->cfg->firmware_cb(chip);
......
......@@ -117,9 +117,7 @@ static void mc13xxx_led_work(struct work_struct *work)
BUG();
}
mc13xxx_lock(led->master);
mc13xxx_reg_rmw(led->master, reg, mask << shift, value << shift);
mc13xxx_unlock(led->master);
}
static void mc13xxx_led_set(struct led_classdev *led_cdev,
......@@ -132,75 +130,6 @@ static void mc13xxx_led_set(struct led_classdev *led_cdev,
schedule_work(&led->work);
}
static int __init mc13xxx_led_setup(struct mc13xxx_led *led, int max_current)
{
int shift, mask, reg, ret, bank;
switch (led->id) {
case MC13783_LED_MD:
reg = MC13XXX_REG_LED_CONTROL(2);
shift = 0;
mask = 0x07;
break;
case MC13783_LED_AD:
reg = MC13XXX_REG_LED_CONTROL(2);
shift = 3;
mask = 0x07;
break;
case MC13783_LED_KP:
reg = MC13XXX_REG_LED_CONTROL(2);
shift = 6;
mask = 0x07;
break;
case MC13783_LED_R1:
case MC13783_LED_G1:
case MC13783_LED_B1:
case MC13783_LED_R2:
case MC13783_LED_G2:
case MC13783_LED_B2:
case MC13783_LED_R3:
case MC13783_LED_G3:
case MC13783_LED_B3:
bank = (led->id - MC13783_LED_R1) / 3;
reg = MC13XXX_REG_LED_CONTROL(3) + bank;
shift = ((led->id - MC13783_LED_R1) - bank * 3) * 2;
mask = 0x03;
break;
case MC13892_LED_MD:
reg = MC13XXX_REG_LED_CONTROL(0);
shift = 9;
mask = 0x07;
break;
case MC13892_LED_AD:
reg = MC13XXX_REG_LED_CONTROL(0);
shift = 21;
mask = 0x07;
break;
case MC13892_LED_KP:
reg = MC13XXX_REG_LED_CONTROL(1);
shift = 9;
mask = 0x07;
break;
case MC13892_LED_R:
case MC13892_LED_G:
case MC13892_LED_B:
bank = (led->id - MC13892_LED_R) / 2;
reg = MC13XXX_REG_LED_CONTROL(2) + bank;
shift = ((led->id - MC13892_LED_R) - bank * 2) * 12 + 9;
mask = 0x07;
break;
default:
BUG();
}
mc13xxx_lock(led->master);
ret = mc13xxx_reg_rmw(led->master, reg, mask << shift,
max_current << shift);
mc13xxx_unlock(led->master);
return ret;
}
static int __init mc13xxx_led_probe(struct platform_device *pdev)
{
struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
......@@ -233,31 +162,22 @@ static int __init mc13xxx_led_probe(struct platform_device *pdev)
leds->num_leds = num_leds;
platform_set_drvdata(pdev, leds);
mc13xxx_lock(mcdev);
for (i = 0; i < devtype->num_regs; i++) {
reg = pdata->led_control[i];
WARN_ON(reg >= (1 << 24));
ret = mc13xxx_reg_write(mcdev, MC13XXX_REG_LED_CONTROL(i), reg);
if (ret)
break;
}
mc13xxx_unlock(mcdev);
if (ret) {
dev_err(&pdev->dev, "Unable to init LED driver\n");
return ret;
return ret;
}
for (i = 0; i < num_leds; i++) {
const char *name, *trig;
char max_current;
ret = -EINVAL;
id = pdata->led[i].id;
name = pdata->led[i].name;
trig = pdata->led[i].default_trigger;
max_current = pdata->led[i].max_current;
if ((id > devtype->led_max) || (id < devtype->led_min)) {
dev_err(&pdev->dev, "Invalid ID %i\n", id);
......@@ -280,11 +200,6 @@ static int __init mc13xxx_led_probe(struct platform_device *pdev)
INIT_WORK(&leds->led[i].work, mc13xxx_led_work);
ret = mc13xxx_led_setup(&leds->led[i], max_current);
if (ret) {
dev_err(&pdev->dev, "Unable to setup LED %i\n", id);
break;
}
ret = led_classdev_register(pdev->dev.parent,
&leds->led[i].cdev);
if (ret) {
......@@ -313,10 +228,8 @@ static int mc13xxx_led_remove(struct platform_device *pdev)
cancel_work_sync(&leds->led[i].work);
}
mc13xxx_lock(mcdev);
for (i = 0; i < leds->devtype->num_regs; i++)
mc13xxx_reg_write(mcdev, MC13XXX_REG_LED_CONTROL(i), 0);
mc13xxx_unlock(mcdev);
return 0;
}
......
......@@ -66,9 +66,11 @@ static void led_pwm_set(struct led_classdev *led_cdev,
struct led_pwm_data *led_dat =
container_of(led_cdev, struct led_pwm_data, cdev);
unsigned int max = led_dat->cdev.max_brightness;
unsigned int period = led_dat->period;
unsigned long long duty = led_dat->period;
led_dat->duty = brightness * period / max;
duty *= brightness;
do_div(duty, max);
led_dat->duty = duty;
if (led_dat->can_sleep)
schedule_work(&led_dat->work);
......@@ -85,11 +87,10 @@ static inline size_t sizeof_pwm_leds_priv(int num_leds)
static int led_pwm_create_of(struct platform_device *pdev,
struct led_pwm_priv *priv)
{
struct device_node *node = pdev->dev.of_node;
struct device_node *child;
int ret;
for_each_child_of_node(node, child) {
for_each_child_of_node(pdev->dev.of_node, child) {
struct led_pwm_data *led_dat = &priv->leds[priv->num_leds];
led_dat->cdev.name = of_get_property(child, "label",
......
......@@ -18,11 +18,10 @@
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_data/leds-s3c24xx.h>
#include <mach/hardware.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/platform_data/leds-s3c24xx.h>
/* our context */
......
This diff is collapsed.
......@@ -110,9 +110,6 @@ struct mc13xxx_led_platform_data {
int id;
const char *name;
const char *default_trigger;
/* Three or two bits current selection depending on the led */
char max_current;
};
#define MAX_LED_CONTROL_REGS 6
......@@ -121,7 +118,7 @@ struct mc13xxx_leds_platform_data {
struct mc13xxx_led_platform_data *led;
int num_leds;
/* LED Control 0 */
/* MC13783 LED Control 0 */
#define MC13783_LED_C0_ENABLE (1 << 0)
#define MC13783_LED_C0_TRIODE_MD (1 << 7)
#define MC13783_LED_C0_TRIODE_AD (1 << 8)
......@@ -129,21 +126,43 @@ struct mc13xxx_leds_platform_data {
#define MC13783_LED_C0_BOOST (1 << 10)
#define MC13783_LED_C0_ABMODE(x) (((x) & 0x7) << 11)
#define MC13783_LED_C0_ABREF(x) (((x) & 0x3) << 14)
/* LED Control 1 */
/* MC13783 LED Control 1 */
#define MC13783_LED_C1_TC1HALF (1 << 18)
#define MC13783_LED_C1_SLEWLIM (1 << 23)
/* LED Control 2 */
/* MC13783 LED Control 2 */
#define MC13783_LED_C2_CURRENT_MD(x) (((x) & 0x7) << 0)
#define MC13783_LED_C2_CURRENT_AD(x) (((x) & 0x7) << 3)
#define MC13783_LED_C2_CURRENT_KP(x) (((x) & 0x7) << 6)
#define MC13783_LED_C2_PERIOD(x) (((x) & 0x3) << 21)
#define MC13783_LED_C2_SLEWLIM (1 << 23)
/* LED Control 3 */
/* MC13783 LED Control 3 */
#define MC13783_LED_C3_CURRENT_R1(x) (((x) & 0x3) << 0)
#define MC13783_LED_C3_CURRENT_G1(x) (((x) & 0x3) << 2)
#define MC13783_LED_C3_CURRENT_B1(x) (((x) & 0x3) << 4)
#define MC13783_LED_C3_PERIOD(x) (((x) & 0x3) << 21)
#define MC13783_LED_C3_TRIODE_TC1 (1 << 23)
/* LED Control 4 */
/* MC13783 LED Control 4 */
#define MC13783_LED_C4_CURRENT_R2(x) (((x) & 0x3) << 0)
#define MC13783_LED_C4_CURRENT_G2(x) (((x) & 0x3) << 2)
#define MC13783_LED_C4_CURRENT_B2(x) (((x) & 0x3) << 4)
#define MC13783_LED_C4_PERIOD(x) (((x) & 0x3) << 21)
#define MC13783_LED_C4_TRIODE_TC2 (1 << 23)
/* LED Control 5 */
/* MC13783 LED Control 5 */
#define MC13783_LED_C5_CURRENT_R3(x) (((x) & 0x3) << 0)
#define MC13783_LED_C5_CURRENT_G3(x) (((x) & 0x3) << 2)
#define MC13783_LED_C5_CURRENT_B3(x) (((x) & 0x3) << 4)
#define MC13783_LED_C5_PERIOD(x) (((x) & 0x3) << 21)
#define MC13783_LED_C5_TRIODE_TC3 (1 << 23)
/* MC13892 LED Control 0 */
#define MC13892_LED_C0_CURRENT_MD(x) (((x) & 0x7) << 9)
#define MC13892_LED_C0_CURRENT_AD(x) (((x) & 0x7) << 21)
/* MC13892 LED Control 1 */
#define MC13892_LED_C1_CURRENT_KP(x) (((x) & 0x7) << 9)
/* MC13892 LED Control 2 */
#define MC13892_LED_C2_CURRENT_R(x) (((x) & 0x7) << 9)
#define MC13892_LED_C2_CURRENT_G(x) (((x) & 0x7) << 21)
/* MC13892 LED Control 3 */
#define MC13892_LED_C3_CURRENT_B(x) (((x) & 0x7) << 9)
u32 led_control[MAX_LED_CONTROL_REGS];
};
......
/*
* arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
*
* Platform data structure for netxbig LED driver
*
* This file is licensed under the terms of the GNU General Public
......@@ -8,8 +6,8 @@
* warranty of any kind, whether express or implied.
*/
#ifndef __MACH_LEDS_NETXBIG_H
#define __MACH_LEDS_NETXBIG_H
#ifndef __LEDS_KIRKWOOD_NETXBIG_H
#define __LEDS_KIRKWOOD_NETXBIG_H
struct netxbig_gpio_ext {
unsigned *addr;
......@@ -52,4 +50,4 @@ struct netxbig_led_platform_data {
int num_leds;
};
#endif /* __MACH_LEDS_NETXBIG_H */
#endif /* __LEDS_KIRKWOOD_NETXBIG_H */
/*
* arch/arm/mach-kirkwood/include/mach/leds-ns2.h
*
* Platform data structure for Network Space v2 LED driver
*
* This file is licensed under the terms of the GNU General Public
......@@ -8,8 +6,8 @@
* warranty of any kind, whether express or implied.
*/
#ifndef __MACH_LEDS_NS2_H
#define __MACH_LEDS_NS2_H
#ifndef __LEDS_KIRKWOOD_NS2_H
#define __LEDS_KIRKWOOD_NS2_H
struct ns2_led {
const char *name;
......@@ -23,4 +21,4 @@ struct ns2_led_platform_data {
struct ns2_led *leds;
};
#endif /* __MACH_LEDS_NS2_H */
#endif /* __LEDS_KIRKWOOD_NS2_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