generic: ar8216: add custom LED support for the AR8327 switch
Signed-off-by: Gabor Juhos <juhosg@openwrt.org> SVN-Revision: 39338
This commit is contained in:
parent
15d41de1eb
commit
0056ac55af
3 changed files with 408 additions and 0 deletions
|
@ -34,6 +34,8 @@
|
||||||
#include <linux/ar8216_platform.h>
|
#include <linux/ar8216_platform.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/leds.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
|
||||||
#include "ar8216.h"
|
#include "ar8216.h"
|
||||||
|
|
||||||
|
@ -82,9 +84,40 @@ struct ar8xxx_chip {
|
||||||
unsigned num_mibs;
|
unsigned num_mibs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ar8327_led_pattern {
|
||||||
|
AR8327_LED_PATTERN_OFF = 0,
|
||||||
|
AR8327_LED_PATTERN_BLINK,
|
||||||
|
AR8327_LED_PATTERN_ON,
|
||||||
|
AR8327_LED_PATTERN_RULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ar8327_led_entry {
|
||||||
|
unsigned reg;
|
||||||
|
unsigned shift;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ar8327_led {
|
||||||
|
struct led_classdev cdev;
|
||||||
|
struct ar8xxx_priv *sw_priv;
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
bool active_low;
|
||||||
|
u8 led_num;
|
||||||
|
enum ar8327_led_mode mode;
|
||||||
|
|
||||||
|
struct mutex mutex;
|
||||||
|
spinlock_t lock;
|
||||||
|
struct work_struct led_work;
|
||||||
|
bool enable_hw_mode;
|
||||||
|
enum ar8327_led_pattern pattern;
|
||||||
|
};
|
||||||
|
|
||||||
struct ar8327_data {
|
struct ar8327_data {
|
||||||
u32 port0_status;
|
u32 port0_status;
|
||||||
u32 port6_status;
|
u32 port6_status;
|
||||||
|
|
||||||
|
struct ar8327_led **leds;
|
||||||
|
unsigned int num_leds;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ar8xxx_priv {
|
struct ar8xxx_priv {
|
||||||
|
@ -1090,6 +1123,317 @@ ar8327_get_port_init_status(struct ar8327_port_cfg *cfg)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define AR8327_LED_ENTRY(_num, _reg, _shift) \
|
||||||
|
[_num] = { .reg = (_reg), .shift = (_shift) }
|
||||||
|
|
||||||
|
static const struct ar8327_led_entry
|
||||||
|
ar8327_led_map[AR8327_NUM_LEDS] = {
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY0_0, 0, 14),
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY0_1, 1, 14),
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY0_2, 2, 14),
|
||||||
|
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY1_0, 3, 8),
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY1_1, 3, 10),
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY1_2, 3, 12),
|
||||||
|
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY2_0, 3, 14),
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY2_1, 3, 16),
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY2_2, 3, 18),
|
||||||
|
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY3_0, 3, 20),
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY3_1, 3, 22),
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY3_2, 3, 24),
|
||||||
|
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY4_0, 0, 30),
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY4_1, 1, 30),
|
||||||
|
AR8327_LED_ENTRY(AR8327_LED_PHY4_2, 2, 30),
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
ar8327_set_led_pattern(struct ar8xxx_priv *priv, unsigned int led_num,
|
||||||
|
enum ar8327_led_pattern pattern)
|
||||||
|
{
|
||||||
|
const struct ar8327_led_entry *entry;
|
||||||
|
|
||||||
|
entry = &ar8327_led_map[led_num];
|
||||||
|
ar8xxx_rmw(priv, AR8327_REG_LED_CTRL(entry->reg),
|
||||||
|
(3 << entry->shift), pattern << entry->shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ar8327_led_work_func(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct ar8327_led *aled;
|
||||||
|
u8 pattern;
|
||||||
|
|
||||||
|
aled = container_of(work, struct ar8327_led, led_work);
|
||||||
|
|
||||||
|
spin_lock(&aled->lock);
|
||||||
|
pattern = aled->pattern;
|
||||||
|
spin_unlock(&aled->lock);
|
||||||
|
|
||||||
|
ar8327_set_led_pattern(aled->sw_priv, aled->led_num,
|
||||||
|
pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ar8327_led_schedule_change(struct ar8327_led *aled, u8 pattern)
|
||||||
|
{
|
||||||
|
if (aled->pattern == pattern)
|
||||||
|
return;
|
||||||
|
|
||||||
|
aled->pattern = pattern;
|
||||||
|
schedule_work(&aled->led_work);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct ar8327_led *
|
||||||
|
led_cdev_to_ar8327_led(struct led_classdev *led_cdev)
|
||||||
|
{
|
||||||
|
return container_of(led_cdev, struct ar8327_led, cdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ar8327_led_blink_set(struct led_classdev *led_cdev,
|
||||||
|
unsigned long *delay_on,
|
||||||
|
unsigned long *delay_off)
|
||||||
|
{
|
||||||
|
struct ar8327_led *aled = led_cdev_to_ar8327_led(led_cdev);
|
||||||
|
|
||||||
|
if (*delay_on == 0 && *delay_off == 0) {
|
||||||
|
*delay_on = 125;
|
||||||
|
*delay_off = 125;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*delay_on != 125 || *delay_off != 125) {
|
||||||
|
/*
|
||||||
|
* The hardware only supports blinking at 4Hz. Fall back
|
||||||
|
* to software implementation in other cases.
|
||||||
|
*/
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock(&aled->lock);
|
||||||
|
|
||||||
|
aled->enable_hw_mode = false;
|
||||||
|
ar8327_led_schedule_change(aled, AR8327_LED_PATTERN_BLINK);
|
||||||
|
|
||||||
|
spin_unlock(&aled->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ar8327_led_set_brightness(struct led_classdev *led_cdev,
|
||||||
|
enum led_brightness brightness)
|
||||||
|
{
|
||||||
|
struct ar8327_led *aled = led_cdev_to_ar8327_led(led_cdev);
|
||||||
|
u8 pattern;
|
||||||
|
bool active;
|
||||||
|
|
||||||
|
active = (brightness != LED_OFF);
|
||||||
|
active ^= aled->active_low;
|
||||||
|
|
||||||
|
pattern = (active) ? AR8327_LED_PATTERN_ON :
|
||||||
|
AR8327_LED_PATTERN_OFF;
|
||||||
|
|
||||||
|
spin_lock(&aled->lock);
|
||||||
|
|
||||||
|
aled->enable_hw_mode = false;
|
||||||
|
ar8327_led_schedule_change(aled, pattern);
|
||||||
|
|
||||||
|
spin_unlock(&aled->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
ar8327_led_enable_hw_mode_show(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||||
|
struct ar8327_led *aled = led_cdev_to_ar8327_led(led_cdev);
|
||||||
|
ssize_t ret = 0;
|
||||||
|
|
||||||
|
spin_lock(&aled->lock);
|
||||||
|
ret += sprintf(buf, "%d\n", aled->enable_hw_mode);
|
||||||
|
spin_unlock(&aled->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
ar8327_led_enable_hw_mode_store(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
const char *buf,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||||
|
struct ar8327_led *aled = led_cdev_to_ar8327_led(led_cdev);
|
||||||
|
u8 pattern;
|
||||||
|
u8 value;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = kstrtou8(buf, 10, &value);
|
||||||
|
if (ret < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
spin_lock(&aled->lock);
|
||||||
|
|
||||||
|
aled->enable_hw_mode = !!value;
|
||||||
|
if (aled->enable_hw_mode)
|
||||||
|
pattern = AR8327_LED_PATTERN_RULE;
|
||||||
|
else
|
||||||
|
pattern = AR8327_LED_PATTERN_OFF;
|
||||||
|
|
||||||
|
ar8327_led_schedule_change(aled, pattern);
|
||||||
|
|
||||||
|
spin_unlock(&aled->lock);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(enable_hw_mode, S_IRUGO | S_IWUSR,
|
||||||
|
ar8327_led_enable_hw_mode_show,
|
||||||
|
ar8327_led_enable_hw_mode_store);
|
||||||
|
|
||||||
|
static int
|
||||||
|
ar8327_led_register(struct ar8xxx_priv *priv, struct ar8327_led *aled)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = led_classdev_register(NULL, &aled->cdev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (aled->mode == AR8327_LED_MODE_HW) {
|
||||||
|
ret = device_create_file(aled->cdev.dev,
|
||||||
|
&dev_attr_enable_hw_mode);
|
||||||
|
if (ret)
|
||||||
|
goto err_unregister;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_unregister:
|
||||||
|
led_classdev_unregister(&aled->cdev);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ar8327_led_unregister(struct ar8327_led *aled)
|
||||||
|
{
|
||||||
|
if (aled->mode == AR8327_LED_MODE_HW)
|
||||||
|
device_remove_file(aled->cdev.dev, &dev_attr_enable_hw_mode);
|
||||||
|
|
||||||
|
led_classdev_unregister(&aled->cdev);
|
||||||
|
cancel_work_sync(&aled->led_work);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ar8327_led_create(struct ar8xxx_priv *priv,
|
||||||
|
const struct ar8327_led_info *led_info)
|
||||||
|
{
|
||||||
|
struct ar8327_data *data = &priv->chip_data.ar8327;
|
||||||
|
struct ar8327_led *aled;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_AR8216_PHY_LEDS))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!led_info->name)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (led_info->led_num >= AR8327_NUM_LEDS)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
aled = kzalloc(sizeof(*aled) + strlen(led_info->name) + 1,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!aled)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
aled->sw_priv = priv;
|
||||||
|
aled->led_num = led_info->led_num;
|
||||||
|
aled->active_low = led_info->active_low;
|
||||||
|
aled->mode = led_info->mode;
|
||||||
|
|
||||||
|
if (aled->mode == AR8327_LED_MODE_HW)
|
||||||
|
aled->enable_hw_mode = true;
|
||||||
|
|
||||||
|
aled->name = (char *)(aled + 1);
|
||||||
|
strcpy(aled->name, led_info->name);
|
||||||
|
|
||||||
|
aled->cdev.name = aled->name;
|
||||||
|
aled->cdev.brightness_set = ar8327_led_set_brightness;
|
||||||
|
aled->cdev.blink_set = ar8327_led_blink_set;
|
||||||
|
aled->cdev.default_trigger = led_info->default_trigger;
|
||||||
|
|
||||||
|
spin_lock_init(&aled->lock);
|
||||||
|
mutex_init(&aled->mutex);
|
||||||
|
INIT_WORK(&aled->led_work, ar8327_led_work_func);
|
||||||
|
|
||||||
|
ret = ar8327_led_register(priv, aled);
|
||||||
|
if (ret)
|
||||||
|
goto err_free;
|
||||||
|
|
||||||
|
data->leds[data->num_leds++] = aled;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_free:
|
||||||
|
kfree(aled);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ar8327_led_destroy(struct ar8327_led *aled)
|
||||||
|
{
|
||||||
|
ar8327_led_unregister(aled);
|
||||||
|
kfree(aled);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ar8327_leds_init(struct ar8xxx_priv *priv)
|
||||||
|
{
|
||||||
|
struct ar8327_data *data;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_AR8216_PHY_LEDS))
|
||||||
|
return;
|
||||||
|
|
||||||
|
data = &priv->chip_data.ar8327;
|
||||||
|
|
||||||
|
for (i = 0; i < data->num_leds; i++) {
|
||||||
|
struct ar8327_led *aled;
|
||||||
|
|
||||||
|
aled = data->leds[i];
|
||||||
|
|
||||||
|
if (aled->enable_hw_mode)
|
||||||
|
aled->pattern = AR8327_LED_PATTERN_RULE;
|
||||||
|
else
|
||||||
|
aled->pattern = AR8327_LED_PATTERN_OFF;
|
||||||
|
|
||||||
|
ar8327_set_led_pattern(priv, aled->led_num, aled->pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ar8327_leds_cleanup(struct ar8xxx_priv *priv)
|
||||||
|
{
|
||||||
|
struct ar8327_data *data = &priv->chip_data.ar8327;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_AR8216_PHY_LEDS))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < data->num_leds; i++) {
|
||||||
|
struct ar8327_led *aled;
|
||||||
|
|
||||||
|
aled = data->leds[i];
|
||||||
|
ar8327_led_destroy(aled);
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(data->leds);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ar8327_hw_config_pdata(struct ar8xxx_priv *priv,
|
ar8327_hw_config_pdata(struct ar8xxx_priv *priv,
|
||||||
struct ar8327_platform_data *pdata)
|
struct ar8327_platform_data *pdata)
|
||||||
|
@ -1159,6 +1503,18 @@ ar8327_hw_config_pdata(struct ar8xxx_priv *priv,
|
||||||
|
|
||||||
priv->write(priv, AR8327_REG_POWER_ON_STRIP, new_pos);
|
priv->write(priv, AR8327_REG_POWER_ON_STRIP, new_pos);
|
||||||
|
|
||||||
|
if (pdata->leds && pdata->num_leds) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
data->leds = kzalloc(pdata->num_leds * sizeof(void *),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!data->leds)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (i = 0; i < pdata->num_leds; i++)
|
||||||
|
ar8327_led_create(priv, &pdata->leds[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1222,6 +1578,8 @@ ar8327_hw_init(struct ar8xxx_priv *priv)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ar8327_leds_init(priv);
|
||||||
|
|
||||||
bus = priv->mii_bus;
|
bus = priv->mii_bus;
|
||||||
for (i = 0; i < AR8327_NUM_PHYS; i++) {
|
for (i = 0; i < AR8327_NUM_PHYS; i++) {
|
||||||
ar8327_phy_fixup(priv, i);
|
ar8327_phy_fixup(priv, i);
|
||||||
|
@ -1239,6 +1597,12 @@ ar8327_hw_init(struct ar8xxx_priv *priv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ar8327_cleanup(struct ar8xxx_priv *priv)
|
||||||
|
{
|
||||||
|
ar8327_leds_cleanup(priv);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ar8327_init_globals(struct ar8xxx_priv *priv)
|
ar8327_init_globals(struct ar8xxx_priv *priv)
|
||||||
{
|
{
|
||||||
|
@ -1395,6 +1759,7 @@ ar8327_setup_port(struct ar8xxx_priv *priv, int port, u32 egress, u32 ingress,
|
||||||
static const struct ar8xxx_chip ar8327_chip = {
|
static const struct ar8xxx_chip ar8327_chip = {
|
||||||
.caps = AR8XXX_CAP_GIGE | AR8XXX_CAP_MIB_COUNTERS,
|
.caps = AR8XXX_CAP_GIGE | AR8XXX_CAP_MIB_COUNTERS,
|
||||||
.hw_init = ar8327_hw_init,
|
.hw_init = ar8327_hw_init,
|
||||||
|
.cleanup = ar8327_cleanup,
|
||||||
.init_globals = ar8327_init_globals,
|
.init_globals = ar8327_init_globals,
|
||||||
.init_port = ar8327_init_port,
|
.init_port = ar8327_init_port,
|
||||||
.setup_port = ar8327_setup_port,
|
.setup_port = ar8327_setup_port,
|
||||||
|
|
|
@ -290,8 +290,10 @@
|
||||||
#define AR8316_POSTRIP_POWER_ON_SEL BIT(31)
|
#define AR8316_POSTRIP_POWER_ON_SEL BIT(31)
|
||||||
|
|
||||||
#define AR8327_NUM_PORTS 7
|
#define AR8327_NUM_PORTS 7
|
||||||
|
#define AR8327_NUM_LEDS 15
|
||||||
#define AR8327_NUM_PHYS 5
|
#define AR8327_NUM_PHYS 5
|
||||||
#define AR8327_PORTS_ALL 0x7f
|
#define AR8327_PORTS_ALL 0x7f
|
||||||
|
#define AR8327_NUM_LED_CTRL_REGS 4
|
||||||
|
|
||||||
#define AR8327_REG_MASK 0x000
|
#define AR8327_REG_MASK 0x000
|
||||||
|
|
||||||
|
@ -343,6 +345,7 @@
|
||||||
#define AR8327_MIB_CPU_KEEP BIT(20)
|
#define AR8327_MIB_CPU_KEEP BIT(20)
|
||||||
|
|
||||||
#define AR8327_REG_SERVICE_TAG 0x048
|
#define AR8327_REG_SERVICE_TAG 0x048
|
||||||
|
#define AR8327_REG_LED_CTRL(_i) (0x050 + (_i) * 4)
|
||||||
#define AR8327_REG_LED_CTRL0 0x050
|
#define AR8327_REG_LED_CTRL0 0x050
|
||||||
#define AR8327_REG_LED_CTRL1 0x054
|
#define AR8327_REG_LED_CTRL1 0x054
|
||||||
#define AR8327_REG_LED_CTRL2 0x058
|
#define AR8327_REG_LED_CTRL2 0x058
|
||||||
|
|
|
@ -76,6 +76,43 @@ struct ar8327_led_cfg {
|
||||||
bool open_drain;
|
bool open_drain;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ar8327_led_num {
|
||||||
|
AR8327_LED_PHY0_0 = 0,
|
||||||
|
AR8327_LED_PHY0_1,
|
||||||
|
AR8327_LED_PHY0_2,
|
||||||
|
AR8327_LED_PHY1_0,
|
||||||
|
AR8327_LED_PHY1_1,
|
||||||
|
AR8327_LED_PHY1_2,
|
||||||
|
AR8327_LED_PHY2_0,
|
||||||
|
AR8327_LED_PHY2_1,
|
||||||
|
AR8327_LED_PHY2_2,
|
||||||
|
AR8327_LED_PHY3_0,
|
||||||
|
AR8327_LED_PHY3_1,
|
||||||
|
AR8327_LED_PHY3_2,
|
||||||
|
AR8327_LED_PHY4_0,
|
||||||
|
AR8327_LED_PHY4_1,
|
||||||
|
AR8327_LED_PHY4_2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ar8327_led_mode {
|
||||||
|
AR8327_LED_MODE_HW = 0,
|
||||||
|
AR8327_LED_MODE_SW,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ar8327_led_info {
|
||||||
|
const char *name;
|
||||||
|
const char *default_trigger;
|
||||||
|
bool active_low;
|
||||||
|
enum ar8327_led_num led_num;
|
||||||
|
enum ar8327_led_mode mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define AR8327_LED_INFO(_led, _mode, _name) { \
|
||||||
|
.name = (_name), \
|
||||||
|
.led_num = AR8327_LED_ ## _led, \
|
||||||
|
.mode = AR8327_LED_MODE_ ## _mode \
|
||||||
|
}
|
||||||
|
|
||||||
struct ar8327_platform_data {
|
struct ar8327_platform_data {
|
||||||
struct ar8327_pad_cfg *pad0_cfg;
|
struct ar8327_pad_cfg *pad0_cfg;
|
||||||
struct ar8327_pad_cfg *pad5_cfg;
|
struct ar8327_pad_cfg *pad5_cfg;
|
||||||
|
@ -86,6 +123,9 @@ struct ar8327_platform_data {
|
||||||
struct ar8327_led_cfg *led_cfg;
|
struct ar8327_led_cfg *led_cfg;
|
||||||
|
|
||||||
int (*get_port_link)(unsigned port);
|
int (*get_port_link)(unsigned port);
|
||||||
|
|
||||||
|
unsigned num_leds;
|
||||||
|
const struct ar8327_led_info *leds;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* AR8216_PLATFORM_H */
|
#endif /* AR8216_PLATFORM_H */
|
Loading…
Reference in a new issue