Backlight for v6.19

* Add support for Awinic AW99706 backlight driver.
 
   * Add GPIOLIB dependency to backlight ktd2801 driver.
   * Add devlink to LED Backlight's supplier LEDs to enforce correct removal
     order and prevent NULL pointer dereferences.
   * Fix kernel-doc warnings in lp855x.h
 
   * Do not include <linux/fb.h> in backlight.h.
   * Fix unused function warnings from suspend/resume ops in aw99706.c by
     switching to DEFINE_SIMPLE_DEV_PM_OPS and using pm_ptr().
 
   * Add Awinic AW99706 backlight binding to MAINTAINERS.
   * Add Awinic AW99706 backlight binding documentation.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmkxtz4ACgkQUa+KL4f8
 d2FYoQ//T/M/Vd+6HSuGSnICrPY7CGXwheE1xfg8hhVB9Sa5+LL8Tt4RTJ1BRNzT
 B7VromDCPkPI7dAfYL7G0dFTu1kU3nN2Xl+86CjvsXsc7gy+8ftpePvUYJbUdhTl
 w4K8sslvcCyMhGHm7U9TwFNDE6+ousrDLADJCo0Tf+tJhmy2IFcl5Sjgt5Y0RnMt
 TmSOAXirbCvVJ8eIQSVPm5geCrSCJ7nxh1WRTKI6BMZsazvxAG1KzShKF0xE0xN3
 SUurIJydxyw6qiNIwYlqph0h0151shILtELsN2/guegqN9RZTHTAFKa8kcrXMJS+
 oGooIZh6B+IkLotv0T3v8LugX3kIi/jvevWffIak3AjHy4zSMhpDXZ0QhVDnMfzT
 ueeNBpyqMeGwbkCirn2iZmlwMUIMS7AYhluBkq6HAmdO++GwSkqficypTPbyxCh7
 M/DPZaFF0aJ4JOIyWDY5Pk2Fc+owsKWf2DurXhSZ7mHgzHgrY5NTEzG1q4esrPXj
 r1mNxSP2CegE6S1XIp3fa96SM2VWnZYvW2ZGIfLHkwqnwOT4dqp8BvEVj7+3jt9x
 5awFLVBjxEf4kUOKfF6ztRQfsJaeN+ujobHcP9wsGmEMWvA2ZH9+Z24SlrbsyfRT
 kunwxRK9CDVw+l1e7JLWZG0wGbEck25n3Qt4opY+jnSX2SdvnXI=
 =n4gn
 -----END PGP SIGNATURE-----

Merge tag 'backlight-next-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight

Pull backlight updates from Lee Jones:
 "Additions:
   - Add support for Awinic AW99706 backlight driver

  Fixes:
   - Add GPIOLIB dependency to backlight ktd2801 driver
   - Add devlink to LED Backlight's supplier LEDs to enforce correct
     removal order and prevent NULL pointer dereferences
   - Fix kernel-doc warnings in lp855x.h

  Removals:
   - Do not include <linux/fb.h> in backlight.h
   - Fix unused function warnings from suspend/resume ops in aw99706.c
     by switching to DEFINE_SIMPLE_DEV_PM_OPS and using pm_ptr()

  Bindings:
   - Add Awinic AW99706 backlight binding to MAINTAINERS
   - Add Awinic AW99706 backlight binding documentation"

* tag 'backlight-next-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight:
  backlight: aw99706: Fix unused function warnings from suspend/resume ops
  backlight: lp855x: Fix lp855x.h kernel-doc warnings
  dt-bindings: leds: backlight: Add Awinic AW99706 backlight
  backlight: aw99706: Add support for Awinic AW99706 backlight
  backlight: led-bl: Add devlink to supplier LEDs
  backlight: ktd2801: Depend on GPIOLIB
  backlight: Do not include <linux/fb.h> in header file
This commit is contained in:
Linus Torvalds 2025-12-04 15:29:27 -08:00
commit d1b46f53a5
8 changed files with 603 additions and 3 deletions

View File

@ -0,0 +1,101 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/leds/backlight/awinic,aw99706.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Awinic AW99706 6-channel WLED Backlight Driver
maintainers:
- Junjie Cao <caojunjie650@gmail.com>
allOf:
- $ref: common.yaml#
properties:
compatible:
const: awinic,aw99706
reg:
maxItems: 1
enable-gpios:
description: GPIO to use to enable/disable the backlight (HWEN pin).
maxItems: 1
awinic,dim-mode:
$ref: /schemas/types.yaml#/definitions/uint32
description: >
Select dimming mode of the device.
0 = Bypass mode.
1 = DC mode.
2 = MIX mode(PWM at low brightness and DC at high brightness).
3 = MIX-26k mode(MIX mode with different PWM frequency).
enum: [ 0, 1, 2, 3 ]
default: 1
awinic,sw-freq-hz:
description: Boost switching frequency in Hz.
enum: [ 300000, 400000, 500000, 600000, 660000, 750000, 850000, 1000000,
1200000, 1330000, 1500000, 1700000 ]
default: 750000
awinic,sw-ilmt-microamp:
description: Switching current limitation in uA.
enum: [ 1500000, 2000000, 2500000, 3000000 ]
default: 3000000
awinic,iled-max-microamp:
description: Maximum LED current setting in uA.
minimum: 5000
maximum: 50000
multipleOf: 500
default: 20000
awinic,uvlo-thres-microvolt:
description: UVLO(Under Voltage Lock Out) in uV.
enum: [ 2200000, 5000000 ]
default: 2200000
awinic,ramp-ctl:
$ref: /schemas/types.yaml#/definitions/uint32
description: >
Select ramp control and filter of the device.
0 = Fade in/fade out.
1 = Light filter.
2 = Medium filter.
3 = Heavy filter.
enum: [ 0, 1, 2, 3 ]
default: 2
required:
- compatible
- reg
- enable-gpios
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
backlight@76 {
compatible = "awinic,aw99706";
reg = <0x76>;
enable-gpios = <&tlmm 88 GPIO_ACTIVE_HIGH>;
default-brightness = <2047>;
max-brightness = <4095>;
awinic,dim-mode = <1>;
awinic,sw-freq-hz = <750000>;
awinic,sw-ilmt-microamp = <3000000>;
awinic,uvlo-thres-microvolt = <2200000>;
awinic,iled-max-microamp = <20000>;
awinic,ramp-ctl = <2>;
};
};
...

View File

@ -4156,6 +4156,12 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
F: drivers/iio/adc/hx711.c
AWINIC AW99706 WLED BACKLIGHT DRIVER
M: Junjie Cao <caojunjie650@gmail.com>
S: Maintained
F: Documentation/devicetree/bindings/leds/backlight/awinic,aw99706.yaml
F: drivers/video/backlight/aw99706.c
AX.25 NETWORK LAYER
L: linux-hams@vger.kernel.org
S: Orphan

View File

@ -156,6 +156,14 @@ config BACKLIGHT_ATMEL_LCDC
If in doubt, it's safe to enable this option; it doesn't kick
in unless the board's description says it's wired that way.
config BACKLIGHT_AW99706
tristate "Backlight Driver for Awinic AW99706"
depends on I2C
select REGMAP_I2C
help
If you have a LCD backlight connected to the WLED output of AW99706
WLED output, say Y here to enable this driver.
config BACKLIGHT_EP93XX
tristate "Cirrus EP93xx Backlight Driver"
depends on FB_EP93XX
@ -185,6 +193,7 @@ config BACKLIGHT_KTD253
config BACKLIGHT_KTD2801
tristate "Backlight Driver for Kinetic KTD2801"
depends on GPIOLIB || COMPILE_TEST
select LEDS_EXPRESSWIRE
help
Say Y to enable the backlight driver for the Kinetic KTD2801 1-wire

View File

@ -25,6 +25,7 @@ obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
obj-$(CONFIG_BACKLIGHT_APPLE_DWI) += apple_dwi_bl.o
obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o
obj-$(CONFIG_BACKLIGHT_AW99706) += aw99706.o
obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o

View File

@ -0,0 +1,471 @@
// SPDX-License-Identifier: GPL-2.0
/*
* aw99706 - Backlight driver for the AWINIC AW99706
*
* Copyright (C) 2025 Junjie Cao <caojunjie650@gmail.com>
* Copyright (C) 2025 Pengyu Luo <mitltlatltl@gmail.com>
*
* Based on vendor driver:
* Copyright (c) 2023 AWINIC Technology CO., LTD
*/
#include <linux/backlight.h>
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/regmap.h>
#define AW99706_MAX_BRT_LVL 4095
#define AW99706_REG_MAX 0x1F
#define AW99706_ID 0x07
/* registers list */
#define AW99706_CFG0_REG 0x00
#define AW99706_DIM_MODE_MASK GENMASK(1, 0)
#define AW99706_CFG1_REG 0x01
#define AW99706_SW_FREQ_MASK GENMASK(3, 0)
#define AW99706_SW_ILMT_MASK GENMASK(5, 4)
#define AW99706_CFG2_REG 0x02
#define AW99706_ILED_MAX_MASK GENMASK(6, 0)
#define AW99706_UVLOSEL_MASK BIT(7)
#define AW99706_CFG3_REG 0x03
#define AW99706_CFG4_REG 0x04
#define AW99706_BRT_MSB_MASK GENMASK(3, 0)
#define AW99706_CFG5_REG 0x05
#define AW99706_BRT_LSB_MASK GENMASK(7, 0)
#define AW99706_CFG6_REG 0x06
#define AW99706_RAMP_CTL_MASK GENMASK(7, 6)
#define AW99706_CFG7_REG 0x07
#define AW99706_CFG8_REG 0x08
#define AW99706_CFG9_REG 0x09
#define AW99706_CFGA_REG 0x0A
#define AW99706_CFGB_REG 0x0B
#define AW99706_CFGC_REG 0x0C
#define AW99706_CFGD_REG 0x0D
#define AW99706_FLAG_REG 0x10
#define AW99706_BACKLIGHT_EN_MASK BIT(7)
#define AW99706_CHIPID_REG 0x11
#define AW99706_LED_OPEN_FLAG_REG 0x12
#define AW99706_LED_SHORT_FLAG_REG 0x13
#define AW99706_MTPLDOSEL_REG 0x1E
#define AW99706_MTPRUN_REG 0x1F
#define RESV 0
/* Boost switching frequency table, in Hz */
static const u32 aw99706_sw_freq_tbl[] = {
RESV, RESV, RESV, RESV, 300000, 400000, 500000, 600000,
660000, 750000, 850000, 1000000, 1200000, 1330000, 1500000, 1700000
};
/* Switching current limitation table, in uA */
static const u32 aw99706_sw_ilmt_tbl[] = {
1500000, 2000000, 2500000, 3000000
};
/* ULVO threshold table, in uV */
static const u32 aw99706_ulvo_thres_tbl[] = {
2200000, 5000000
};
struct aw99706_dt_prop {
const char * const name;
int (*lookup)(const struct aw99706_dt_prop *prop, u32 dt_val, u8 *val);
const u32 * const lookup_tbl;
u8 tbl_size;
u8 reg;
u8 mask;
u32 def_val;
};
static int aw99706_dt_property_lookup(const struct aw99706_dt_prop *prop,
u32 dt_val, u8 *val)
{
int i;
if (!prop->lookup_tbl) {
*val = dt_val;
return 0;
}
for (i = 0; i < prop->tbl_size; i++)
if (prop->lookup_tbl[i] == dt_val)
break;
*val = i;
return i == prop->tbl_size ? -1 : 0;
}
#define MIN_ILED_MAX 5000
#define MAX_ILED_MAX 50000
#define STEP_ILED_MAX 500
static int
aw99706_dt_property_iled_max_convert(const struct aw99706_dt_prop *prop,
u32 dt_val, u8 *val)
{
if (dt_val > MAX_ILED_MAX || dt_val < MIN_ILED_MAX)
return -1;
*val = (dt_val - MIN_ILED_MAX) / STEP_ILED_MAX;
return (dt_val - MIN_ILED_MAX) % STEP_ILED_MAX;
}
static const struct aw99706_dt_prop aw99706_dt_props[] = {
{
"awinic,dim-mode", aw99706_dt_property_lookup,
NULL, 0,
AW99706_CFG0_REG, AW99706_DIM_MODE_MASK, 1,
},
{
"awinic,sw-freq", aw99706_dt_property_lookup,
aw99706_sw_freq_tbl, ARRAY_SIZE(aw99706_sw_freq_tbl),
AW99706_CFG1_REG, AW99706_SW_FREQ_MASK, 750000,
},
{
"awinic,sw-ilmt", aw99706_dt_property_lookup,
aw99706_sw_ilmt_tbl, ARRAY_SIZE(aw99706_sw_ilmt_tbl),
AW99706_CFG1_REG, AW99706_SW_ILMT_MASK, 3000000,
},
{
"awinic,iled-max", aw99706_dt_property_iled_max_convert,
NULL, 0,
AW99706_CFG2_REG, AW99706_ILED_MAX_MASK, 20000,
},
{
"awinic,uvlo-thres", aw99706_dt_property_lookup,
aw99706_ulvo_thres_tbl, ARRAY_SIZE(aw99706_ulvo_thres_tbl),
AW99706_CFG2_REG, AW99706_UVLOSEL_MASK, 2200000,
},
{
"awinic,ramp-ctl", aw99706_dt_property_lookup,
NULL, 0,
AW99706_CFG6_REG, AW99706_RAMP_CTL_MASK, 2,
}
};
struct reg_init_data {
u8 reg;
u8 mask;
u8 val;
};
struct aw99706_device {
struct i2c_client *client;
struct device *dev;
struct regmap *regmap;
struct backlight_device *bl_dev;
struct gpio_desc *hwen_gpio;
struct reg_init_data init_tbl[ARRAY_SIZE(aw99706_dt_props)];
bool bl_enable;
};
enum reg_access {
REG_NONE_ACCESS = 0,
REG_RD_ACCESS = 1,
REG_WR_ACCESS = 2,
};
static const u8 aw99706_regs[AW99706_REG_MAX + 1] = {
[AW99706_CFG0_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFG1_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFG2_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFG3_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFG4_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFG5_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFG6_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFG7_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFG8_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFG9_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFGA_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFGB_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFGC_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_CFGD_REG] = REG_RD_ACCESS | REG_WR_ACCESS,
[AW99706_FLAG_REG] = REG_RD_ACCESS,
[AW99706_CHIPID_REG] = REG_RD_ACCESS,
[AW99706_LED_OPEN_FLAG_REG] = REG_RD_ACCESS,
[AW99706_LED_SHORT_FLAG_REG] = REG_RD_ACCESS,
/*
* Write bit is dropped here, writing BIT(0) to MTPLDOSEL will unlock
* Multi-time Programmable (MTP).
*/
[AW99706_MTPLDOSEL_REG] = REG_RD_ACCESS,
[AW99706_MTPRUN_REG] = REG_NONE_ACCESS,
};
static bool aw99706_readable_reg(struct device *dev, unsigned int reg)
{
return aw99706_regs[reg] & REG_RD_ACCESS;
}
static bool aw99706_writeable_reg(struct device *dev, unsigned int reg)
{
return aw99706_regs[reg] & REG_WR_ACCESS;
}
static inline int aw99706_i2c_read(struct aw99706_device *aw, u8 reg,
unsigned int *val)
{
return regmap_read(aw->regmap, reg, val);
}
static inline int aw99706_i2c_write(struct aw99706_device *aw, u8 reg, u8 val)
{
return regmap_write(aw->regmap, reg, val);
}
static inline int aw99706_i2c_update_bits(struct aw99706_device *aw, u8 reg,
u8 mask, u8 val)
{
return regmap_update_bits(aw->regmap, reg, mask, val);
}
static void aw99706_dt_parse(struct aw99706_device *aw,
struct backlight_properties *bl_props)
{
const struct aw99706_dt_prop *prop;
u32 dt_val;
int ret, i;
u8 val;
for (i = 0; i < ARRAY_SIZE(aw99706_dt_props); i++) {
prop = &aw99706_dt_props[i];
ret = device_property_read_u32(aw->dev, prop->name, &dt_val);
if (ret < 0)
dt_val = prop->def_val;
if (prop->lookup(prop, dt_val, &val)) {
dev_warn(aw->dev, "invalid value %d for property %s, using default value %d\n",
dt_val, prop->name, prop->def_val);
prop->lookup(prop, prop->def_val, &val);
}
aw->init_tbl[i].reg = prop->reg;
aw->init_tbl[i].mask = prop->mask;
aw->init_tbl[i].val = val << __ffs(prop->mask);
}
bl_props->brightness = AW99706_MAX_BRT_LVL >> 1;
bl_props->max_brightness = AW99706_MAX_BRT_LVL;
device_property_read_u32(aw->dev, "default-brightness",
&bl_props->brightness);
device_property_read_u32(aw->dev, "max-brightness",
&bl_props->max_brightness);
if (bl_props->max_brightness > AW99706_MAX_BRT_LVL)
bl_props->max_brightness = AW99706_MAX_BRT_LVL;
if (bl_props->brightness > bl_props->max_brightness)
bl_props->brightness = bl_props->max_brightness;
}
static int aw99706_hw_init(struct aw99706_device *aw)
{
int ret, i;
gpiod_set_value_cansleep(aw->hwen_gpio, 1);
for (i = 0; i < ARRAY_SIZE(aw->init_tbl); i++) {
ret = aw99706_i2c_update_bits(aw, aw->init_tbl[i].reg,
aw->init_tbl[i].mask,
aw->init_tbl[i].val);
if (ret < 0) {
dev_err(aw->dev, "Failed to write init data %d\n", ret);
return ret;
}
}
return 0;
}
static int aw99706_bl_enable(struct aw99706_device *aw, bool en)
{
int ret;
u8 val;
val = FIELD_PREP(AW99706_BACKLIGHT_EN_MASK, en);
ret = aw99706_i2c_update_bits(aw, AW99706_CFGD_REG,
AW99706_BACKLIGHT_EN_MASK, val);
if (ret)
dev_err(aw->dev, "Failed to enable backlight!\n");
return ret;
}
static int aw99706_update_brightness(struct aw99706_device *aw, u32 brt_lvl)
{
bool bl_enable_now = !!brt_lvl;
int ret;
ret = aw99706_i2c_write(aw, AW99706_CFG4_REG,
(brt_lvl >> 8) & AW99706_BRT_MSB_MASK);
if (ret < 0)
return ret;
ret = aw99706_i2c_write(aw, AW99706_CFG5_REG,
brt_lvl & AW99706_BRT_LSB_MASK);
if (ret < 0)
return ret;
if (aw->bl_enable != bl_enable_now) {
ret = aw99706_bl_enable(aw, bl_enable_now);
if (!ret)
aw->bl_enable = bl_enable_now;
}
return ret;
}
static int aw99706_bl_update_status(struct backlight_device *bl)
{
struct aw99706_device *aw = bl_get_data(bl);
return aw99706_update_brightness(aw, bl->props.brightness);
}
static const struct backlight_ops aw99706_bl_ops = {
.options = BL_CORE_SUSPENDRESUME,
.update_status = aw99706_bl_update_status,
};
static const struct regmap_config aw99706_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = AW99706_REG_MAX,
.writeable_reg = aw99706_writeable_reg,
.readable_reg = aw99706_readable_reg,
};
static int aw99706_chip_id_read(struct aw99706_device *aw)
{
int ret;
unsigned int val;
ret = aw99706_i2c_read(aw, AW99706_CHIPID_REG, &val);
if (ret < 0)
return ret;
return val;
}
static int aw99706_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct aw99706_device *aw;
struct backlight_device *bl_dev;
struct backlight_properties props = {};
int ret = 0;
aw = devm_kzalloc(dev, sizeof(*aw), GFP_KERNEL);
if (!aw)
return -ENOMEM;
aw->client = client;
aw->dev = dev;
i2c_set_clientdata(client, aw);
aw->regmap = devm_regmap_init_i2c(client, &aw99706_regmap_config);
if (IS_ERR(aw->regmap))
return dev_err_probe(dev, PTR_ERR(aw->regmap),
"Failed to init regmap\n");
ret = aw99706_chip_id_read(aw);
if (ret != AW99706_ID)
return dev_err_probe(dev, -ENODEV,
"Unknown chip id 0x%02x\n", ret);
aw99706_dt_parse(aw, &props);
aw->hwen_gpio = devm_gpiod_get(aw->dev, "enable", GPIOD_OUT_LOW);
if (IS_ERR(aw->hwen_gpio))
return dev_err_probe(dev, PTR_ERR(aw->hwen_gpio),
"Failed to get enable gpio\n");
ret = aw99706_hw_init(aw);
if (ret < 0)
return dev_err_probe(dev, ret,
"Failed to initialize the chip\n");
props.type = BACKLIGHT_RAW;
props.scale = BACKLIGHT_SCALE_LINEAR;
bl_dev = devm_backlight_device_register(dev, "aw99706-backlight", dev,
aw, &aw99706_bl_ops, &props);
if (IS_ERR(bl_dev))
return dev_err_probe(dev, PTR_ERR(bl_dev),
"Failed to register backlight!\n");
aw->bl_dev = bl_dev;
return 0;
}
static void aw99706_remove(struct i2c_client *client)
{
struct aw99706_device *aw = i2c_get_clientdata(client);
aw99706_update_brightness(aw, 0);
msleep(50);
gpiod_set_value_cansleep(aw->hwen_gpio, 0);
}
static int aw99706_suspend(struct device *dev)
{
struct aw99706_device *aw = dev_get_drvdata(dev);
return aw99706_update_brightness(aw, 0);
}
static int aw99706_resume(struct device *dev)
{
struct aw99706_device *aw = dev_get_drvdata(dev);
return aw99706_hw_init(aw);
}
static DEFINE_SIMPLE_DEV_PM_OPS(aw99706_pm_ops, aw99706_suspend, aw99706_resume);
static const struct i2c_device_id aw99706_ids[] = {
{ "aw99706" },
{ }
};
MODULE_DEVICE_TABLE(i2c, aw99706_ids);
static const struct of_device_id aw99706_match_table[] = {
{ .compatible = "awinic,aw99706", },
{ }
};
MODULE_DEVICE_TABLE(of, aw99706_match_table);
static struct i2c_driver aw99706_i2c_driver = {
.probe = aw99706_probe,
.remove = aw99706_remove,
.id_table = aw99706_ids,
.driver = {
.name = "aw99706",
.of_match_table = aw99706_match_table,
.pm = pm_ptr(&aw99706_pm_ops),
},
};
module_i2c_driver(aw99706_i2c_driver);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("BackLight driver for aw99706");

View File

@ -210,6 +210,19 @@ static int led_bl_probe(struct platform_device *pdev)
return PTR_ERR(priv->bl_dev);
}
for (i = 0; i < priv->nb_leds; i++) {
struct device_link *link;
link = device_link_add(&pdev->dev, priv->leds[i]->dev->parent,
DL_FLAG_AUTOREMOVE_CONSUMER);
if (!link) {
dev_err(&pdev->dev, "Failed to add devlink (consumer %s, supplier %s)\n",
dev_name(&pdev->dev), dev_name(priv->leds[i]->dev->parent));
backlight_device_unregister(priv->bl_dev);
return -EINVAL;
}
}
for (i = 0; i < priv->nb_leds; i++) {
mutex_lock(&priv->leds[i]->led_access);
led_sysfs_disable(priv->leds[i]);

View File

@ -10,7 +10,6 @@
#define _LINUX_BACKLIGHT_H
#include <linux/device.h>
#include <linux/fb.h>
#include <linux/mutex.h>
#include <linux/types.h>

View File

@ -124,12 +124,12 @@ struct lp855x_rom_data {
};
/**
* struct lp855x_platform_data
* struct lp855x_platform_data - lp855 platform-specific data
* @name : Backlight driver name. If it is not defined, default name is set.
* @device_control : value of DEVICE CONTROL register
* @initial_brightness : initial value of backlight brightness
* @period_ns : platform specific pwm period value. unit is nano.
Only valid when mode is PWM_BASED.
* Only valid when mode is PWM_BASED.
* @size_program : total size of lp855x_rom_data
* @rom_data : list of new eeprom/eprom registers
*/