Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1278000 > unrolled thread
| Started by | Milo Kim <milo.kim@ti.com> |
|---|---|
| First post | 2015-11-26 08:00 +0100 |
| Last post | 2015-11-26 08:10 +0100 |
| Articles | 9 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v2 0/9] Support TI LMU devices Milo Kim <milo.kim@ti.com> - 2015-11-26 08:00 +0100
[PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator binding information Milo Kim <milo.kim@ti.com> - 2015-11-26 08:10 +0100
Re: [PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator binding information Mark Brown <broonie@kernel.org> - 2015-11-27 13:40 +0100
Re: [PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator binding information Rob Herring <robh@kernel.org> - 2015-11-27 21:50 +0100
Re: [PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator binding information Mark Brown <broonie@kernel.org> - 2015-11-27 23:10 +0100
Applied "regulator: lm363x: add LM363x regulator binding information" to the regulator tree Mark Brown <broonie@kernel.org> - 2015-11-27 14:00 +0100
Re: [PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator binding information Rob Herring <robh@kernel.org> - 2015-11-27 22:00 +0100
[PATCH v2 2/9] Documentation: dt-bindings: leds: backlight: add TI LMU backlight binding information Milo Kim <milo.kim@ti.com> - 2015-11-26 08:10 +0100
[PATCH v2 7/9] backlight: add TI LMU backlight driver Milo Kim <milo.kim@ti.com> - 2015-11-26 08:10 +0100
| From | Milo Kim <milo.kim@ti.com> |
|---|---|
| Date | 2015-11-26 08:00 +0100 |
| Subject | [PATCH v2 0/9] Support TI LMU devices |
| Message-ID | <qyYH7-1f6-3@gated-at.bofh.it> |
TI Lighting Management Unit drivers support lighting devices below.
Enable pin Backlight HW fault monitoring LEDs Regulators
---------- --------- ------------------- ---- ------------
LM3532 o o x x x
LM3631 o o x x 5 regulators
LM3632 o o x x 3 regulators
LM3633 o o o o x
LM3695 o o x x x
LM3697 o o o x x
This patch-set consists of several parts below.
DT bindings : Binding information for each module
LMU MFD : Device registration and HW enable pin control
LMU fault monitor : HW fault monitoring for open and short circuit
LMU backlight : Consolidated LMU backlight driver
LM3633 LED : LED subsystem and dimming pattern generation
supported
LM363X regulator : LM3631 and LM3632 regulator driver for the
display bias
Updates from v1
---------------
* DT bindings
mfd : Describe complete DT properties.
backlight : Move backlight properties into leds/backlight/.
Use common LED properties like 'led-sources' and 'label'.
hwmon : LMU fault monitoring driver is not HWMON any more.
So related properties are moved into 'ti-lmu' binding.
leds : Use LED common properties like 'led-sources' and 'label'.
* MFD
Remove LMU helpers for I2C register access. Each driver uses regmap
helpers instead.
* LMU fault monitoring driver
In v1, it was HWMON driver but HWMON subsystem maintainer suggested
moving it into MFD because it has no sensor data like temperature or
voltage. Device attributes were replaced with debugfs files because
monitoring should be processed for debug purpose only.
* Backlight
Six separate driver code was consolidated.
Driver control code is implemented in 'ti-lmu-backlight-core.c'.
Device specific data is defined in 'ti-lmu-backlight-data.c'.
194 lines are saved in v2. The text segment is decreased by removing
duplicate instructions.
Lines of code:
v1: 1420 (8 files)
v2: 1226 (3 files)
Size:
v1:
text data bss filename
12202 720 40 drivers/video/backlight/built-in.o
v2:
text data bss filename
6883 712 41 drivers/video/backlight/built-in.o
* LED
Use single device attribute for LED dimming operation.
Max brightness is determined by DT property, 'led-max-microamp'.
Remove brightness workqueue.
* Regulator
Use 'of_match' in regulator_desc instead of calling of_regulator_match.
Remove unnecessary OF device ID because MFD core registers a platform
device based on the compatible string.
Milo Kim (9):
Documentation: dt-bindings: mfd: add TI LMU device binding information
Documentation: dt-bindings: leds: backlight: add TI LMU backlight
binding information
Documentation: dt-bindings: leds: add LM3633 LED binding information
Documentation: dt-bindings: regulator: add LM363x regulator binding
information
mfd: add TI LMU driver
mfd: add TI LMU hardware fault monitoring driver
backlight: add TI LMU backlight driver
leds: add LM3633 driver
regulator: add LM363X driver
.../ABI/testing/debugfs-ti-lmu-fault-monitor | 32 +
Documentation/ABI/testing/sysfs-class-led-lm3633 | 97 +++
.../bindings/leds/backlight/ti-lmu-backlight.txt | 65 ++
.../devicetree/bindings/leds/leds-lm3633.txt | 24 +
Documentation/devicetree/bindings/mfd/ti-lmu.txt | 243 ++++++
.../bindings/regulator/lm363x-regulator.txt | 34 +
drivers/leds/Kconfig | 10 +
drivers/leds/Makefile | 1 +
drivers/leds/leds-lm3633.c | 840 +++++++++++++++++++++
drivers/mfd/Kconfig | 22 +
drivers/mfd/Makefile | 3 +
drivers/mfd/ti-lmu-fault-monitor.c | 405 ++++++++++
drivers/mfd/ti-lmu.c | 259 +++++++
drivers/regulator/Kconfig | 9 +
drivers/regulator/Makefile | 1 +
drivers/regulator/lm363x-regulator.c | 309 ++++++++
drivers/video/backlight/Kconfig | 7 +
drivers/video/backlight/Makefile | 3 +
drivers/video/backlight/ti-lmu-backlight-core.c | 649 ++++++++++++++++
drivers/video/backlight/ti-lmu-backlight-data.c | 287 +++++++
include/linux/mfd/ti-lmu-backlight.h | 290 +++++++
include/linux/mfd/ti-lmu-register.h | 280 +++++++
include/linux/mfd/ti-lmu.h | 87 +++
23 files changed, 3957 insertions(+)
create mode 100644 Documentation/ABI/testing/debugfs-ti-lmu-fault-monitor
create mode 100644 Documentation/ABI/testing/sysfs-class-led-lm3633
create mode 100644 Documentation/devicetree/bindings/leds/backlight/ti-lmu-backlight.txt
create mode 100644 Documentation/devicetree/bindings/leds/leds-lm3633.txt
create mode 100644 Documentation/devicetree/bindings/mfd/ti-lmu.txt
create mode 100644 Documentation/devicetree/bindings/regulator/lm363x-regulator.txt
create mode 100644 drivers/leds/leds-lm3633.c
create mode 100644 drivers/mfd/ti-lmu-fault-monitor.c
create mode 100644 drivers/mfd/ti-lmu.c
create mode 100644 drivers/regulator/lm363x-regulator.c
create mode 100644 drivers/video/backlight/ti-lmu-backlight-core.c
create mode 100644 drivers/video/backlight/ti-lmu-backlight-data.c
create mode 100644 include/linux/mfd/ti-lmu-backlight.h
create mode 100644 include/linux/mfd/ti-lmu-register.h
create mode 100644 include/linux/mfd/ti-lmu.h
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Milo Kim <milo.kim@ti.com> |
|---|---|
| Date | 2015-11-26 08:10 +0100 |
| Subject | [PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator binding information |
| Message-ID | <qyYQN-1zw-1@gated-at.bofh.it> |
| In reply to | #1278000 |
This binding describes LM3631 and LM3632 regulator properties. Cc: Rob Herring <robh+dt@kernel.org> Cc: devicetree@vger.kernel.org Cc: Lee Jones <lee.jones@linaro.org> Cc: Jacek Anaszewski <j.anaszewski@samsung.com> Cc: Mark Brown <broonie@kernel.org> Cc: linux-leds@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Milo Kim <milo.kim@ti.com> --- .../bindings/regulator/lm363x-regulator.txt | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/lm363x-regulator.txt diff --git a/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt b/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt new file mode 100644 index 0000000..8f14df9 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt @@ -0,0 +1,34 @@ +TI LMU LM363x regulator device tree bindings + +LM363x regulator driver supports LM3631 and LM3632. +LM3631 has five regulators and LM3632 supports three regulators. + +Required property: + - compatible: "ti,lm363x-regulator" + +Optional properties: + LM3632 has external enable pins for two LDOs. + - ti,lcm-en1-gpio: A GPIO specifier for Vpos control pin. + - ti,lcm-en2-gpio: A GPIO specifier for Vneg control pin. + +Child nodes: + LM3631 + - vboost + - vcont + - voref + - vpos + - vneg + + LM3632 + - vboost + - vpos + - vneg + + Optional properties of a child node: + Each sub-node should contain the constraints and initialization. + Please refer to [1]. + +Examples: Please refer to ti-lmu dt-bindings [2]. + +[1] ../regulator/regulator.txt +[2] ../mfd/ti-lmu.txt -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Mark Brown <broonie@kernel.org> |
|---|---|
| Date | 2015-11-27 13:40 +0100 |
| Subject | Re: [PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator binding information |
| Message-ID | <qzqtI-2QO-7@gated-at.bofh.it> |
| In reply to | #1278001 |
[Multipart message — attachments visible in raw view] — view raw
On Thu, Nov 26, 2015 at 03:57:00PM +0900, Milo Kim wrote: > This binding describes LM3631 and LM3632 regulator properties. Please use subject lines matching the style for the subsystem.
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2015-11-27 21:50 +0100 |
| Subject | Re: [PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator binding information |
| Message-ID | <qzy7T-7H7-1@gated-at.bofh.it> |
| In reply to | #1278788 |
On Fri, Nov 27, 2015 at 12:37:50PM +0000, Mark Brown wrote: > On Thu, Nov 26, 2015 at 03:57:00PM +0900, Milo Kim wrote: > > This binding describes LM3631 and LM3632 regulator properties. > > Please use subject lines matching the style for the subsystem. Which for bindings, my preference is "dt-bindings: ..." I assume you meant to follow regulator style though. Rob -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Mark Brown <broonie@kernel.org> |
|---|---|
| Date | 2015-11-27 23:10 +0100 |
| Subject | Re: [PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator binding information |
| Message-ID | <qzznj-bk-9@gated-at.bofh.it> |
| In reply to | #1278953 |
[Multipart message — attachments visible in raw view] — view raw
On Fri, Nov 27, 2015 at 02:44:50PM -0600, Rob Herring wrote: > On Fri, Nov 27, 2015 at 12:37:50PM +0000, Mark Brown wrote: > > On Thu, Nov 26, 2015 at 03:57:00PM +0900, Milo Kim wrote: > > > This binding describes LM3631 and LM3632 regulator properties. > > Please use subject lines matching the style for the subsystem. > Which for bindings, my preference is "dt-bindings: ..." I assume you > meant to follow regulator style though. Given that maintainers are generally expected to review and apply bindings themselves it seems sensible (and it's what we mostly seem to do).
[toc] | [prev] | [next] | [standalone]
| From | Mark Brown <broonie@kernel.org> |
|---|---|
| Date | 2015-11-27 14:00 +0100 |
| Subject | Applied "regulator: lm363x: add LM363x regulator binding information" to the regulator tree |
| Message-ID | <qzqN3-2YK-5@gated-at.bofh.it> |
| In reply to | #1278001 |
The patch regulator: lm363x: add LM363x regulator binding information has been applied to the regulator tree at git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark From eaea7d27129b9b493c3029608486c157827a92ce Mon Sep 17 00:00:00 2001 From: Milo Kim <milo.kim@ti.com> Date: Thu, 26 Nov 2015 15:57:00 +0900 Subject: [PATCH] regulator: lm363x: add LM363x regulator binding information This binding describes LM3631 and LM3632 regulator properties. Signed-off-by: Milo Kim <milo.kim@ti.com> Signed-off-by: Mark Brown <broonie@kernel.org> --- .../bindings/regulator/lm363x-regulator.txt | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/lm363x-regulator.txt diff --git a/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt b/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt new file mode 100644 index 000000000000..8f14df9d1205 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt @@ -0,0 +1,34 @@ +TI LMU LM363x regulator device tree bindings + +LM363x regulator driver supports LM3631 and LM3632. +LM3631 has five regulators and LM3632 supports three regulators. + +Required property: + - compatible: "ti,lm363x-regulator" + +Optional properties: + LM3632 has external enable pins for two LDOs. + - ti,lcm-en1-gpio: A GPIO specifier for Vpos control pin. + - ti,lcm-en2-gpio: A GPIO specifier for Vneg control pin. + +Child nodes: + LM3631 + - vboost + - vcont + - voref + - vpos + - vneg + + LM3632 + - vboost + - vpos + - vneg + + Optional properties of a child node: + Each sub-node should contain the constraints and initialization. + Please refer to [1]. + +Examples: Please refer to ti-lmu dt-bindings [2]. + +[1] ../regulator/regulator.txt +[2] ../mfd/ti-lmu.txt -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2015-11-27 22:00 +0100 |
| Subject | Re: [PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator binding information |
| Message-ID | <qzyhz-7Kz-5@gated-at.bofh.it> |
| In reply to | #1278001 |
On Thu, Nov 26, 2015 at 03:57:00PM +0900, Milo Kim wrote: > This binding describes LM3631 and LM3632 regulator properties. > > Cc: Rob Herring <robh+dt@kernel.org> > Cc: devicetree@vger.kernel.org > Cc: Lee Jones <lee.jones@linaro.org> > Cc: Jacek Anaszewski <j.anaszewski@samsung.com> > Cc: Mark Brown <broonie@kernel.org> > Cc: linux-leds@vger.kernel.org > Cc: linux-kernel@vger.kernel.org > Signed-off-by: Milo Kim <milo.kim@ti.com> > --- > .../bindings/regulator/lm363x-regulator.txt | 34 ++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > create mode 100644 Documentation/devicetree/bindings/regulator/lm363x-regulator.txt > > diff --git a/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt b/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt > new file mode 100644 > index 0000000..8f14df9 > --- /dev/null > +++ b/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt > @@ -0,0 +1,34 @@ > +TI LMU LM363x regulator device tree bindings > + > +LM363x regulator driver supports LM3631 and LM3632. > +LM3631 has five regulators and LM3632 supports three regulators. > + > +Required property: > + - compatible: "ti,lm363x-regulator" > + > +Optional properties: > + LM3632 has external enable pins for two LDOs. > + - ti,lcm-en1-gpio: A GPIO specifier for Vpos control pin. > + - ti,lcm-en2-gpio: A GPIO specifier for Vneg control pin. Use "-gpios" please. > + > +Child nodes: > + LM3631 > + - vboost > + - vcont > + - voref > + - vpos > + - vneg > + > + LM3632 > + - vboost > + - vpos > + - vneg > + > + Optional properties of a child node: > + Each sub-node should contain the constraints and initialization. > + Please refer to [1]. What about the regulator names? > + > +Examples: Please refer to ti-lmu dt-bindings [2]. > + > +[1] ../regulator/regulator.txt > +[2] ../mfd/ti-lmu.txt > -- > 1.9.1 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Milo Kim <milo.kim@ti.com> |
|---|---|
| Date | 2015-11-26 08:10 +0100 |
| Subject | [PATCH v2 2/9] Documentation: dt-bindings: leds: backlight: add TI LMU backlight binding information |
| Message-ID | <qyYQO-1zw-15@gated-at.bofh.it> |
| In reply to | #1278000 |
LM3532, LM3631, LM3632, LM3633, LM3695 and LM3697 use common dt-bindings for describing backlight device. Cc: Rob Herring <robh+dt@kernel.org> Cc: devicetree@vger.kernel.org Cc: Lee Jones <lee.jones@linaro.org> Cc: Jacek Anaszewski <j.anaszewski@samsung.com> Cc: Mark Brown <broonie@kernel.org> Cc: linux-leds@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Milo Kim <milo.kim@ti.com> --- .../bindings/leds/backlight/ti-lmu-backlight.txt | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/backlight/ti-lmu-backlight.txt diff --git a/Documentation/devicetree/bindings/leds/backlight/ti-lmu-backlight.txt b/Documentation/devicetree/bindings/leds/backlight/ti-lmu-backlight.txt new file mode 100644 index 0000000..c2c35b2 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/backlight/ti-lmu-backlight.txt @@ -0,0 +1,65 @@ +TI LMU backlight device tree bindings + +Required property: + - compatible: Should be one of: + "ti,lm3532-backlight" + "ti,lm3631-backlight" + "ti,lm3632-backlight" + "ti,lm3633-backlight" + "ti,lm3695-backlight" + "ti,lm3697-backlight" + +Optional properties: + There are two backlight control mode. One is I2C, the other is PWM mode. + Following properties are only specified in PWM mode. + Please note that LMU backlight device can have only one PWM channel. + + - pwms: OF device-tree PWM specification. + - pwm-names: a list of names for the PWM devices specified in the "pwms" + property. + + For the PWM user nodes, please refer to [1]. + +Child nodes: + LMU backlight is represented as sub-nodes of the TI LMU device [2]. + So, LMU backlight should have more than one backlight child node. + Each node exactly matches with backlight control bank configuration. + Maximum numbers of child nodes depend on the device. + 1 = LM3631, LM3632, LM3695 + 2 = LM3633, LM3697 + 3 = LM3532 + + Required property of a child node: + - led-sources: List of enabled channels from 0 to 2. + Please refer to LED binding [3]. + For output channels, please refer to the datasheets [4]. + + Optional properties of a child node: + - label: Backlight channel identification. + Please refer to LED binding [3]. + - default-brightness-level: Backlight initial brightness value. + Type is <u32>. It is set as soon as backlight + device is created. + 0 ~ 2047 = LM3631, LM3632, LM3633, LM3695 and + LM3697 + 0 ~ 255 = LM3532 + - ramp-up-msec, ramp-down-msec: Light dimming effect properties. + Type is <u32>. Unit is millisecond. + 0 ~ 65 msec = LM3532 + 0 ~ 4000 msec = LM3631 + 0 ~ 16000 msec = LM3633 and LM3697 + - pwm-period: PWM period. Only valid in PWM brightness mode. + Type is <u32>. If this property is missing, then control + mode is set to I2C by default. + +Examples: Please refer to ti-lmu dt-bindings. [2]. + +[1] ../pwm/pwm.txt +[2] ../mfd/ti-lmu.txt +[3] ../leds/common.txt +[4] LM3532: http://www.ti.com/product/LM3532/datasheet + LM3631: http://www.ti.com/product/LM3631/datasheet + LM3632: http://www.ti.com/product/LM3632A/datasheet + LM3633: http://www.ti.com/product/LM3633/datasheet + LM3695: Datasheet is not opened yet, but only two strings are used. + LM3697: http://www.ti.com/product/LM3697/datasheet -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Milo Kim <milo.kim@ti.com> |
|---|---|
| Date | 2015-11-26 08:10 +0100 |
| Subject | [PATCH v2 7/9] backlight: add TI LMU backlight driver |
| Message-ID | <qyYQP-1zw-31@gated-at.bofh.it> |
| In reply to | #1278000 |
This is consolidated driver which supports backlight devices below.
LM3532, LM3631, LM3632, LM3633, LM3695 and LM3697.
Structure
---------
It consists of two parts - core and data.
Core part supports features below.
- Backlight subsystem control
- Channel configuration from DT properties
- Light dimming effect control: ramp up and down.
- LMU fault monitor notifier handling
- PWM brightness control
Data part describes device specific data.
- Register value configuration for each LMU device
: initialization, channel configuration, control mode, enable and
brightness.
- PWM action configuration
- Light dimming effect table
- Option for LMU fault monitor support
Macros for register data
------------------------
All LMU devices have 8-bit based registers. LMU_BL_REG() creates 24-bit
register value in data part. It consists of address, mask and value.
On the other hand, register value should be parsed when the driver
reads/writes data from/to I2C registers. Driver uses LMU_BL_GET_ADDR(),
LMU_BL_GET_MASK() and LMU_BL_GET_VAL() for this purpose.
Data structure
--------------
ti_lmu_bl: Backlight output channel data
ti_lmu_bl_chip: Backlight device data. One device can have multiple
backlight channel data.
ti_lmu_bl_reg: Backlight device register data
ti_lmu_bl_cfg: Backlight configuration data for each LMU device
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Jacek Anaszewski <j.anaszewski@samsung.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-leds@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim <milo.kim@ti.com>
---
drivers/video/backlight/Kconfig | 7 +
drivers/video/backlight/Makefile | 3 +
drivers/video/backlight/ti-lmu-backlight-core.c | 649 ++++++++++++++++++++++++
drivers/video/backlight/ti-lmu-backlight-data.c | 287 +++++++++++
include/linux/mfd/ti-lmu-backlight.h | 290 +++++++++++
5 files changed, 1236 insertions(+)
create mode 100644 drivers/video/backlight/ti-lmu-backlight-core.c
create mode 100644 drivers/video/backlight/ti-lmu-backlight-data.c
create mode 100644 include/linux/mfd/ti-lmu-backlight.h
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 5ffa4b4..451d043 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -427,6 +427,13 @@ config BACKLIGHT_SKY81452
To compile this driver as a module, choose M here: the module will
be called sky81452-backlight
+config BACKLIGHT_TI_LMU
+ tristate "Backlight driver for TI LMU"
+ depends on BACKLIGHT_CLASS_DEVICE && MFD_TI_LMU
+ help
+ Say Y to enable the backlight driver for TI LMU devices.
+ This supports LM3532, LM3631, LM3632, LM3633, LM3695 and LM3697.
+
config BACKLIGHT_TPS65217
tristate "TPS65217 Backlight"
depends on BACKLIGHT_CLASS_DEVICE && MFD_TPS65217
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 16ec534..0f74ce7 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -52,6 +52,9 @@ obj-$(CONFIG_BACKLIGHT_PM8941_WLED) += pm8941-wled.o
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
obj-$(CONFIG_BACKLIGHT_SKY81452) += sky81452-backlight.o
+ti-lmu-backlight-objs := ti-lmu-backlight-core.o \
+ ti-lmu-backlight-data.o
+obj-$(CONFIG_BACKLIGHT_TI_LMU) += ti-lmu-backlight.o
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
diff --git a/drivers/video/backlight/ti-lmu-backlight-core.c b/drivers/video/backlight/ti-lmu-backlight-core.c
new file mode 100644
index 0000000..838e2c2
--- /dev/null
+++ b/drivers/video/backlight/ti-lmu-backlight-core.c
@@ -0,0 +1,649 @@
+/*
+ * TI LMU (Lighting Management Unit) Backlight Driver
+ *
+ * Copyright 2015 Texas Instruments
+ *
+ * Author: Milo 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/backlight.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/mfd/ti-lmu.h>
+#include <linux/mfd/ti-lmu-backlight.h>
+#include <linux/mfd/ti-lmu-register.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+
+#define NUM_DUAL_CHANNEL 2
+#define LMU_BACKLIGHT_DUAL_CHANNEL_USED (BIT(0) | BIT(1))
+#define LMU_BACKLIGHT_11BIT_LSB_MASK (BIT(0) | BIT(1) | BIT(2))
+#define LMU_BACKLIGHT_11BIT_MSB_SHIFT 3
+#define DEFAULT_PWM_NAME "lmu-backlight"
+
+static int ti_lmu_backlight_enable(struct ti_lmu_bl *lmu_bl, int enable)
+{
+ struct ti_lmu_bl_chip *chip = lmu_bl->chip;
+ struct regmap *regmap = chip->lmu->regmap;
+ unsigned long enable_time = chip->cfg->reginfo->enable_usec;
+ u8 *reg = chip->cfg->reginfo->enable;
+ u8 mask = BIT(lmu_bl->bank_id);
+
+ if (!reg)
+ return -EINVAL;
+
+ if (enable)
+ return regmap_update_bits(regmap, *reg, mask, mask);
+ else
+ return regmap_update_bits(regmap, *reg, mask, 0);
+
+ if (enable_time > 0)
+ usleep_range(enable_time, enable_time + 100);
+}
+
+static void ti_lmu_backlight_pwm_ctrl(struct ti_lmu_bl *lmu_bl, int brightness,
+ int max_brightness)
+{
+ struct pwm_device *pwm;
+ unsigned int duty, period;
+
+ if (!lmu_bl->pwm) {
+ pwm = devm_pwm_get(lmu_bl->chip->dev, DEFAULT_PWM_NAME);
+ if (IS_ERR(pwm)) {
+ dev_err(lmu_bl->chip->dev,
+ "Can not get PWM device, err: %ld\n",
+ PTR_ERR(pwm));
+ return;
+ }
+
+ lmu_bl->pwm = pwm;
+ }
+
+ period = lmu_bl->pwm_period;
+ duty = brightness * period / max_brightness;
+
+ pwm_config(lmu_bl->pwm, duty, period);
+ if (duty)
+ pwm_enable(lmu_bl->pwm);
+ else
+ pwm_disable(lmu_bl->pwm);
+}
+
+static int ti_lmu_backlight_update_brightness_register(struct ti_lmu_bl *lmu_bl,
+ int brightness)
+{
+ const struct ti_lmu_bl_cfg *cfg = lmu_bl->chip->cfg;
+ const struct ti_lmu_bl_reg *reginfo = cfg->reginfo;
+ struct regmap *regmap = lmu_bl->chip->lmu->regmap;
+ u8 reg, val;
+ int ret;
+
+ if (lmu_bl->mode == BL_PWM_BASED) {
+ switch (cfg->pwm_action) {
+ case UPDATE_PWM_ONLY:
+ /* No register update is required */
+ return 0;
+ case UPDATE_MAX_BRT:
+ /*
+ * PWM can start from any non-zero code and dim down
+ * to zero. So, brightness register should be updated
+ * even in PWM mode.
+ */
+ if (brightness > 0)
+ brightness = MAX_BRIGHTNESS_11BIT;
+ else
+ brightness = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /*
+ * Brightness register update
+ *
+ * 11 bit dimming: update LSB bits and write MSB byte.
+ * MSB brightness should be shifted.
+ * 8 bit dimming: write MSB byte.
+ */
+
+ if (!reginfo->brightness_msb)
+ return -EINVAL;
+
+ if (cfg->max_brightness == MAX_BRIGHTNESS_11BIT) {
+ if (!reginfo->brightness_lsb)
+ return -EINVAL;
+
+ reg = reginfo->brightness_lsb[lmu_bl->bank_id];
+ ret = regmap_update_bits(regmap, reg,
+ LMU_BACKLIGHT_11BIT_LSB_MASK,
+ brightness);
+ if (ret)
+ return ret;
+
+ val = (brightness >> LMU_BACKLIGHT_11BIT_MSB_SHIFT) & 0xFF;
+ } else {
+ val = brightness & 0xFF;
+ }
+
+ reg = reginfo->brightness_msb[lmu_bl->bank_id];
+ return regmap_write(regmap, reg, val);
+}
+
+static int ti_lmu_backlight_update_status(struct backlight_device *bl_dev)
+{
+ struct ti_lmu_bl *lmu_bl = bl_get_data(bl_dev);
+ int brightness = bl_dev->props.brightness;
+ int ret;
+
+ if (bl_dev->props.state & BL_CORE_SUSPENDED)
+ brightness = 0;
+
+ if (brightness > 0)
+ ret = ti_lmu_backlight_enable(lmu_bl, 1);
+ else
+ ret = ti_lmu_backlight_enable(lmu_bl, 0);
+
+ if (ret)
+ return ret;
+
+ if (lmu_bl->mode == BL_PWM_BASED)
+ ti_lmu_backlight_pwm_ctrl(lmu_bl, brightness,
+ bl_dev->props.max_brightness);
+
+ return ti_lmu_backlight_update_brightness_register(lmu_bl, brightness);
+}
+
+static const struct backlight_ops lmu_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = ti_lmu_backlight_update_status,
+};
+
+static int ti_lmu_backlight_of_get_ctrl_bank(struct device_node *np,
+ struct ti_lmu_bl *lmu_bl)
+{
+ const char *name;
+ u32 *sources;
+ int num_channels = lmu_bl->chip->cfg->num_channels;
+ int ret, num_sources;
+
+ sources = devm_kzalloc(lmu_bl->chip->dev, num_channels, GFP_KERNEL);
+ if (!sources)
+ return -ENOMEM;
+
+ if (!of_property_read_string(np, "label", &name))
+ lmu_bl->name = name;
+ else
+ lmu_bl->name = np->name;
+
+ ret = of_property_count_u32_elems(np, "led-sources");
+ if (ret < 0 || ret > num_channels)
+ return -EINVAL;
+
+ num_sources = ret;
+ ret = of_property_read_u32_array(np, "led-sources", sources,
+ num_sources);
+ if (ret)
+ return ret;
+
+ lmu_bl->led_sources = 0;
+ while (num_sources--)
+ set_bit(sources[num_sources], &lmu_bl->led_sources);
+
+ return 0;
+}
+
+static void ti_lmu_backlight_of_get_light_properties(struct device_node *np,
+ struct ti_lmu_bl *lmu_bl)
+{
+ of_property_read_u32(np, "default-brightness-level",
+ &lmu_bl->default_brightness);
+
+ of_property_read_u32(np, "ramp-up-msec", &lmu_bl->ramp_up_msec);
+ of_property_read_u32(np, "ramp-down-msec", &lmu_bl->ramp_down_msec);
+}
+
+static void ti_lmu_backlight_of_get_brightness_mode(struct device_node *np,
+ struct ti_lmu_bl *lmu_bl)
+{
+ of_property_read_u32(np, "pwm-period", &lmu_bl->pwm_period);
+
+ if (lmu_bl->pwm_period > 0)
+ lmu_bl->mode = BL_PWM_BASED;
+ else
+ lmu_bl->mode = BL_REGISTER_BASED;
+}
+
+static int ti_lmu_backlight_of_create(struct ti_lmu_bl_chip *chip,
+ struct device_node *np)
+{
+ struct device_node *child;
+ struct ti_lmu_bl *lmu_bl, *each;
+ int ret, num_backlights;
+ int i = 0;
+
+ num_backlights = of_get_child_count(np);
+ if (num_backlights == 0) {
+ dev_err(chip->dev, "No backlight strings\n");
+ return -ENODEV;
+ }
+
+ /* One chip can have mulitple backlight strings */
+ lmu_bl = devm_kzalloc(chip->dev, sizeof(*lmu_bl) * num_backlights,
+ GFP_KERNEL);
+ if (!lmu_bl)
+ return -ENOMEM;
+
+ /* Child is mapped to LMU backlight control bank */
+ for_each_child_of_node(np, child) {
+ each = lmu_bl + i;
+ each->bank_id = i;
+ each->chip = chip;
+
+ ret = ti_lmu_backlight_of_get_ctrl_bank(child, each);
+ if (ret) {
+ of_node_put(np);
+ return ret;
+ }
+
+ ti_lmu_backlight_of_get_light_properties(child, each);
+ ti_lmu_backlight_of_get_brightness_mode(child, each);
+
+ i++;
+ }
+
+ chip->lmu_bl = lmu_bl;
+ chip->num_backlights = num_backlights;
+
+ return 0;
+}
+
+static int ti_lmu_backlight_create_channel(struct ti_lmu_bl *lmu_bl)
+{
+ struct regmap *regmap = lmu_bl->chip->lmu->regmap;
+ u32 *reg = lmu_bl->chip->cfg->reginfo->channel;
+ int num_channels = lmu_bl->chip->cfg->num_channels;
+ int i, ret;
+ u8 shift;
+
+ /*
+ * How to create backlight output channels:
+ * Check 'led_sources' bit and update registers.
+ *
+ * 1) Dual channel configuration
+ * The 1st register data is used for single channel.
+ * The 2nd register data is used for dual channel.
+ *
+ * 2) Multiple channel configuration
+ * Each register data is mapped to bank ID.
+ * Bit shift operation is defined in channel registers.
+ *
+ * Channel register data consists of address, mask, value.
+ * Driver can get each data by using LMU_BL_GET_ADDR(),
+ * LMU_BL_GET_MASK(), LMU_BL_GET_VAL().
+ */
+
+ if (num_channels == NUM_DUAL_CHANNEL) {
+ if (lmu_bl->led_sources == LMU_BACKLIGHT_DUAL_CHANNEL_USED)
+ ++reg;
+
+ return regmap_update_bits(regmap, LMU_BL_GET_ADDR(*reg),
+ LMU_BL_GET_MASK(*reg),
+ LMU_BL_GET_VAL(*reg));
+ }
+
+ for (i = 0; i < num_channels; i++) {
+ if (!reg)
+ break;
+
+ /*
+ * Note that the result of LMU_BL_GET_VAL() is shift bit.
+ * The bank_id should be shifted for the channel configuration.
+ */
+ if (test_bit(i, &lmu_bl->led_sources)) {
+ shift = LMU_BL_GET_VAL(*reg);
+ ret = regmap_update_bits(regmap, LMU_BL_GET_ADDR(*reg),
+ LMU_BL_GET_MASK(*reg),
+ lmu_bl->bank_id << shift);
+ if (ret)
+ return ret;
+ }
+
+ reg++;
+ }
+
+ return 0;
+}
+
+static int ti_lmu_backlight_update_ctrl_mode(struct ti_lmu_bl *lmu_bl)
+{
+ struct regmap *regmap = lmu_bl->chip->lmu->regmap;
+ u32 *reg = lmu_bl->chip->cfg->reginfo->mode + lmu_bl->bank_id;
+ u8 val;
+
+ if (!reg)
+ return 0;
+
+ /*
+ * Update PWM configuration register.
+ * If the mode is register based, then clear the bit.
+ */
+ if (lmu_bl->mode == BL_PWM_BASED)
+ val = LMU_BL_GET_VAL(*reg);
+ else
+ val = 0;
+
+ return regmap_update_bits(regmap, LMU_BL_GET_ADDR(*reg),
+ LMU_BL_GET_MASK(*reg), val);
+}
+
+static int ti_lmu_backlight_convert_ramp_to_index(struct ti_lmu_bl *lmu_bl,
+ enum ti_lmu_bl_ramp_mode mode)
+{
+ const int *ramp_table = lmu_bl->chip->cfg->ramp_table;
+ const int size = lmu_bl->chip->cfg->size_ramp;
+ unsigned int msec;
+ int i;
+
+ if (!ramp_table)
+ return -EINVAL;
+
+ switch (mode) {
+ case BL_RAMP_UP:
+ msec = lmu_bl->ramp_up_msec;
+ break;
+ case BL_RAMP_DOWN:
+ msec = lmu_bl->ramp_down_msec;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (msec <= ramp_table[0])
+ return 0;
+
+ if (msec > ramp_table[size - 1])
+ return size - 1;
+
+ for (i = 1; i < size; i++) {
+ if (msec == ramp_table[i])
+ return i;
+
+ /* Find an approximate index by looking up the table */
+ if (msec > ramp_table[i - 1] && msec < ramp_table[i]) {
+ if (msec - ramp_table[i - 1] < ramp_table[i] - msec)
+ return i - 1;
+ else
+ return i;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int ti_lmu_backlight_set_ramp(struct ti_lmu_bl *lmu_bl)
+{
+ struct regmap *regmap = lmu_bl->chip->lmu->regmap;
+ const struct ti_lmu_bl_reg *reginfo = lmu_bl->chip->cfg->reginfo;
+ int offset = reginfo->ramp_reg_offset;
+ int i, ret, index;
+ u32 reg;
+
+ for (i = BL_RAMP_UP; i <= BL_RAMP_DOWN; i++) {
+ index = ti_lmu_backlight_convert_ramp_to_index(lmu_bl, i);
+ if (index > 0) {
+ if (!reginfo->ramp)
+ break;
+
+ if (lmu_bl->bank_id == 0)
+ reg = reginfo->ramp[i];
+ else
+ reg = reginfo->ramp[i] + offset;
+
+ /*
+ * Note that the result of LMU_BL_GET_VAL() is
+ * shift bit. So updated bit is shifted index value.
+ */
+ ret = regmap_update_bits(regmap, LMU_BL_GET_ADDR(reg),
+ LMU_BL_GET_MASK(reg),
+ index << LMU_BL_GET_VAL(reg));
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int ti_lmu_backlight_configure(struct ti_lmu_bl *lmu_bl)
+{
+ int ret;
+
+ ret = ti_lmu_backlight_create_channel(lmu_bl);
+ if (ret)
+ return ret;
+
+ ret = ti_lmu_backlight_update_ctrl_mode(lmu_bl);
+ if (ret)
+ return ret;
+
+ return ti_lmu_backlight_set_ramp(lmu_bl);
+}
+
+static int ti_lmu_backlight_init(struct ti_lmu_bl_chip *chip)
+{
+ struct regmap *regmap = chip->lmu->regmap;
+ u32 *reg = chip->cfg->reginfo->init;
+ int num_init = chip->cfg->reginfo->num_init;
+ int i, ret;
+
+ /*
+ * 'init' register data consists of address, mask, value.
+ * Driver can get each data by using LMU_BL_GET_ADDR(),
+ * LMU_BL_GET_MASK(), LMU_BL_GET_VAL().
+ */
+
+ for (i = 0; i < num_init; i++) {
+ if (!reg)
+ break;
+
+ ret = regmap_update_bits(regmap, LMU_BL_GET_ADDR(*reg),
+ LMU_BL_GET_MASK(*reg),
+ LMU_BL_GET_VAL(*reg));
+ if (ret)
+ return ret;
+
+ reg++;
+ }
+
+ return 0;
+}
+
+static int ti_lmu_backlight_reload(struct ti_lmu_bl_chip *chip)
+{
+ struct ti_lmu_bl *each;
+ int i, ret;
+
+ ret = ti_lmu_backlight_init(chip);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < chip->num_backlights; i++) {
+ each = chip->lmu_bl + i;
+ ret = ti_lmu_backlight_configure(each);
+ if (ret)
+ return ret;
+
+ backlight_update_status(each->bl_dev);
+ }
+
+ return 0;
+}
+
+static int ti_lmu_backlight_add_device(struct device *dev,
+ struct ti_lmu_bl *lmu_bl)
+{
+ struct backlight_device *bl_dev;
+ struct backlight_properties props;
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.type = BACKLIGHT_PLATFORM;
+ props.brightness = lmu_bl->default_brightness;
+ props.max_brightness = lmu_bl->chip->cfg->max_brightness;
+
+ bl_dev = devm_backlight_device_register(dev, lmu_bl->name,
+ lmu_bl->chip->dev, lmu_bl,
+ &lmu_backlight_ops, &props);
+ if (IS_ERR(bl_dev))
+ return PTR_ERR(bl_dev);
+
+ lmu_bl->bl_dev = bl_dev;
+
+ return 0;
+}
+
+static struct ti_lmu_bl_chip *
+ti_lmu_backlight_register(struct device *dev, struct ti_lmu *lmu,
+ const struct ti_lmu_bl_cfg *cfg)
+{
+ struct ti_lmu_bl_chip *chip;
+ struct ti_lmu_bl *each;
+ int i, ret;
+
+ if (!cfg) {
+ dev_err(dev, "Operation is not configured\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+ if (!chip)
+ return ERR_PTR(-ENOMEM);
+
+ chip->dev = dev;
+ chip->lmu = lmu;
+ chip->cfg = cfg;
+
+ ret = ti_lmu_backlight_of_create(chip, dev->of_node);
+ if (ret)
+ return ERR_PTR(ret);
+
+ ret = ti_lmu_backlight_init(chip);
+ if (ret) {
+ dev_err(dev, "Backlight init err: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+
+ for (i = 0; i < chip->num_backlights; i++) {
+ each = chip->lmu_bl + i;
+
+ ret = ti_lmu_backlight_configure(each);
+ if (ret) {
+ dev_err(dev, "Backlight config err: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+
+ ret = ti_lmu_backlight_add_device(dev, each);
+ if (ret) {
+ dev_err(dev, "Backlight device err: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+
+ backlight_update_status(each->bl_dev);
+ }
+
+ return chip;
+}
+
+static void ti_lmu_backlight_unregister(struct ti_lmu_bl_chip *chip)
+{
+ struct ti_lmu_bl *each;
+ int i;
+
+ /* Turn off the brightness */
+ for (i = 0; i < chip->num_backlights; i++) {
+ each = chip->lmu_bl + i;
+ each->bl_dev->props.brightness = 0;
+ backlight_update_status(each->bl_dev);
+ }
+}
+
+static int ti_lmu_backlight_monitor_notifier(struct notifier_block *nb,
+ unsigned long action, void *unused)
+{
+ struct ti_lmu_bl_chip *chip = container_of(nb, struct ti_lmu_bl_chip,
+ nb);
+
+ if (action == LMU_EVENT_MONITOR_DONE) {
+ if (ti_lmu_backlight_reload(chip))
+ return NOTIFY_STOP;
+ }
+
+ return NOTIFY_OK;
+}
+
+static int ti_lmu_backlight_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ti_lmu *lmu = dev_get_drvdata(dev->parent);
+ struct ti_lmu_bl_chip *chip;
+ int ret;
+
+ chip = ti_lmu_backlight_register(dev, lmu, &lmu_bl_cfg[pdev->id]);
+ if (IS_ERR(chip))
+ return PTR_ERR(chip);
+
+ /*
+ * Notifier callback is required because backlight device needs
+ * reconfiguration after fault detection procedure is done by
+ * ti-lmu-fault-monitor driver.
+ */
+ if (chip->cfg->fault_monitor_used) {
+ chip->nb.notifier_call = ti_lmu_backlight_monitor_notifier;
+ ret = blocking_notifier_chain_register(&chip->lmu->notifier,
+ &chip->nb);
+ if (ret)
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, chip);
+
+ return 0;
+}
+
+static int ti_lmu_backlight_remove(struct platform_device *pdev)
+{
+ struct ti_lmu_bl_chip *chip = platform_get_drvdata(pdev);
+
+ if (chip->cfg->fault_monitor_used)
+ blocking_notifier_chain_unregister(&chip->lmu->notifier,
+ &chip->nb);
+
+ ti_lmu_backlight_unregister(chip);
+
+ return 0;
+}
+
+static struct platform_driver ti_lmu_backlight_driver = {
+ .probe = ti_lmu_backlight_probe,
+ .remove = ti_lmu_backlight_remove,
+ .driver = {
+ .name = "ti-lmu-backlight",
+ },
+};
+
+module_platform_driver(ti_lmu_backlight_driver)
+
+MODULE_DESCRIPTION("TI LMU Backlight Driver");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:ti-lmu-backlight");
diff --git a/drivers/video/backlight/ti-lmu-backlight-data.c b/drivers/video/backlight/ti-lmu-backlight-data.c
new file mode 100644
index 0000000..0a486b2
--- /dev/null
+++ b/drivers/video/backlight/ti-lmu-backlight-data.c
@@ -0,0 +1,287 @@
+/*
+ * TI LMU (Lighting Management Unit) Backlight Device Data
+ *
+ * Copyright 2015 Texas Instruments
+ *
+ * Author: Milo 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/kernel.h>
+#include <linux/mfd/ti-lmu.h>
+#include <linux/mfd/ti-lmu-backlight.h>
+#include <linux/mfd/ti-lmu-register.h>
+#include <linux/module.h>
+
+/* LM3532 */
+static u32 lm3532_init_regs[] = {
+ LM3532_INIT_ZONE_0,
+ LM3532_INIT_ZONE_1,
+ LM3532_INIT_ZONE_2,
+};
+
+static u32 lm3532_channel_regs[] = {
+ LM3532_CHANNEL_1,
+ LM3532_CHANNEL_2,
+ LM3532_CHANNEL_3,
+};
+
+static u32 lm3532_mode_regs[] = {
+ LM3532_MODE_PWM_A,
+ LM3532_MODE_PWM_B,
+ LM3532_MODE_PWM_C,
+};
+
+static u32 lm3532_ramp_regs[] = {
+ LM3532_RAMPUP,
+ LM3532_RAMPDN,
+};
+
+static u8 lm3532_enable_reg = LM3532_REG_ENABLE;
+
+static u8 lm3532_brightness_regs[] = {
+ LM3532_REG_BRT_A,
+ LM3532_REG_BRT_B,
+ LM3532_REG_BRT_C,
+};
+
+static const struct ti_lmu_bl_reg lm3532_reg_info = {
+ .init = lm3532_init_regs,
+ .num_init = ARRAY_SIZE(lm3532_init_regs),
+ .channel = lm3532_channel_regs,
+ .mode = lm3532_mode_regs,
+ .ramp = lm3532_ramp_regs,
+ .enable = &lm3532_enable_reg,
+ .brightness_msb = lm3532_brightness_regs,
+};
+
+/* LM3631 */
+static u32 lm3631_init_regs[] = {
+ LM3631_INIT_BRT_MODE,
+ LM3631_INIT_DIMMING_MODE,
+};
+
+static u32 lm3631_channel_regs[] = {
+ LM3631_SINGLE_CHANNEL,
+ LM3631_DUAL_CHANNEL,
+};
+
+static u32 lm3631_ramp_reg = LM3631_RAMP;
+static u8 lm3631_enable_reg = LM3631_REG_DEVCTRL;
+static u8 lm3631_brightness_msb_reg = LM3631_REG_BRT_MSB;
+static u8 lm3631_brightness_lsb_reg = LM3631_REG_BRT_LSB;
+
+static const struct ti_lmu_bl_reg lm3631_reg_info = {
+ .init = lm3631_init_regs,
+ .num_init = ARRAY_SIZE(lm3631_init_regs),
+ .channel = lm3631_channel_regs,
+ .ramp = &lm3631_ramp_reg,
+ .enable = &lm3631_enable_reg,
+ .brightness_msb = &lm3631_brightness_msb_reg,
+ .brightness_lsb = &lm3631_brightness_lsb_reg,
+};
+
+/* LM3632 */
+static u32 lm3632_init_regs[] = {
+ LM3632_INIT_OVP_25V,
+ LM3632_INIT_SWFREQ_1MHZ,
+};
+
+static u32 lm3632_channel_regs[] = {
+ LM3632_SINGLE_CHANNEL,
+ LM3632_DUAL_CHANNEL,
+};
+
+static u32 lm3632_mode_reg = LM3632_MODE_PWM;
+static u8 lm3632_enable_reg = LM3632_REG_ENABLE;
+static u8 lm3632_brightness_msb_reg = LM3632_REG_BRT_MSB;
+static u8 lm3632_brightness_lsb_reg = LM3632_REG_BRT_LSB;
+
+static const struct ti_lmu_bl_reg lm3632_reg_info = {
+ .init = lm3632_init_regs,
+ .num_init = ARRAY_SIZE(lm3632_init_regs),
+ .channel = lm3632_channel_regs,
+ .mode = &lm3632_mode_reg,
+ .enable = &lm3632_enable_reg,
+ .brightness_msb = &lm3632_brightness_msb_reg,
+ .brightness_lsb = &lm3632_brightness_lsb_reg,
+};
+
+/* LM3633 */
+static u32 lm3633_init_regs[] = {
+ LM3633_INIT_OVP_40V,
+ LM3633_INIT_RAMP_SELECT,
+};
+
+static u32 lm3633_channel_regs[] = {
+ LM3633_CHANNEL_HVLED1,
+ LM3633_CHANNEL_HVLED2,
+ LM3633_CHANNEL_HVLED3,
+};
+
+static u32 lm3633_mode_regs[] = {
+ LM3633_MODE_PWM_A,
+ LM3633_MODE_PWM_B,
+};
+
+static u32 lm3633_ramp_regs[] = {
+ LM3633_RAMPUP,
+ LM3633_RAMPDN,
+};
+
+static u8 lm3633_enable_reg = LM3633_REG_ENABLE;
+
+static u8 lm3633_brightness_msb_regs[] = {
+ LM3633_REG_BRT_HVLED_A_MSB,
+ LM3633_REG_BRT_HVLED_B_MSB,
+};
+
+static u8 lm3633_brightness_lsb_regs[] = {
+ LM3633_REG_BRT_HVLED_A_LSB,
+ LM3633_REG_BRT_HVLED_B_LSB,
+};
+
+static const struct ti_lmu_bl_reg lm3633_reg_info = {
+ .init = lm3633_init_regs,
+ .num_init = ARRAY_SIZE(lm3633_init_regs),
+ .channel = lm3633_channel_regs,
+ .mode = lm3633_mode_regs,
+ .ramp = lm3633_ramp_regs,
+ .ramp_reg_offset = 1, /* For LM3633_REG_BL1_RAMPUP/DN */
+ .enable = &lm3633_enable_reg,
+ .brightness_msb = lm3633_brightness_msb_regs,
+ .brightness_lsb = lm3633_brightness_lsb_regs,
+};
+
+/* LM3695 */
+static u32 lm3695_init_regs[] = {
+ LM3695_INIT_BRT_MODE,
+};
+
+static u32 lm3695_channel_regs[] = {
+ LM3695_SINGLE_CHANNEL,
+ LM3695_DUAL_CHANNEL,
+};
+
+static u8 lm3695_enable_reg = LM3695_REG_GP;
+static u8 lm3695_brightness_msb_reg = LM3695_REG_BRT_MSB;
+static u8 lm3695_brightness_lsb_reg = LM3695_REG_BRT_LSB;
+
+static const struct ti_lmu_bl_reg lm3695_reg_info = {
+ .init = lm3695_init_regs,
+ .num_init = ARRAY_SIZE(lm3695_init_regs),
+ .channel = lm3695_channel_regs,
+ .enable = &lm3695_enable_reg,
+ .enable_usec = 600,
+ .brightness_msb = &lm3695_brightness_msb_reg,
+ .brightness_lsb = &lm3695_brightness_lsb_reg,
+};
+
+/* LM3697 */
+static u32 lm3697_init_regs[] = {
+ LM3697_INIT_RAMP_SELECT,
+};
+
+static u32 lm3697_channel_regs[] = {
+ LM3697_CHANNEL_1,
+ LM3697_CHANNEL_2,
+ LM3697_CHANNEL_3,
+};
+
+static u32 lm3697_mode_regs[] = {
+ LM3697_MODE_PWM_A,
+ LM3697_MODE_PWM_B,
+};
+
+static u32 lm3697_ramp_regs[] = {
+ LM3697_RAMPUP,
+ LM3697_RAMPDN,
+};
+
+static u8 lm3697_enable_reg = LM3697_REG_ENABLE;
+
+static u8 lm3697_brightness_msb_regs[] = {
+ LM3697_REG_BRT_A_MSB,
+ LM3697_REG_BRT_B_MSB,
+};
+
+static u8 lm3697_brightness_lsb_regs[] = {
+ LM3697_REG_BRT_A_LSB,
+ LM3697_REG_BRT_B_LSB,
+};
+
+static const struct ti_lmu_bl_reg lm3697_reg_info = {
+ .init = lm3697_init_regs,
+ .num_init = ARRAY_SIZE(lm3697_init_regs),
+ .channel = lm3697_channel_regs,
+ .mode = lm3697_mode_regs,
+ .ramp = lm3697_ramp_regs,
+ .ramp_reg_offset = 1, /* For LM3697_REG_BL1_RAMPUP/DN */
+ .enable = &lm3697_enable_reg,
+ .brightness_msb = lm3697_brightness_msb_regs,
+ .brightness_lsb = lm3697_brightness_lsb_regs,
+};
+
+static int lm3532_ramp_table[] = { 0, 1, 2, 4, 8, 16, 32, 65 };
+
+static int lm3631_ramp_table[] = {
+ 0, 1, 2, 5, 10, 20, 50, 100,
+ 250, 500, 750, 1000, 1500, 2000, 3000, 4000,
+};
+
+static int common_ramp_table[] = {
+ 2, 250, 500, 1000, 2000, 4000, 8000, 16000,
+};
+
+struct ti_lmu_bl_cfg lmu_bl_cfg[LMU_MAX_ID] = {
+ {
+ .reginfo = &lm3532_reg_info,
+ .num_channels = LM3532_MAX_CHANNELS,
+ .max_brightness = MAX_BRIGHTNESS_8BIT,
+ .pwm_action = UPDATE_PWM_AND_BRT_REGISTER,
+ .ramp_table = lm3532_ramp_table,
+ .size_ramp = ARRAY_SIZE(lm3532_ramp_table),
+ },
+ {
+ .reginfo = &lm3631_reg_info,
+ .num_channels = LM3631_MAX_CHANNELS,
+ .max_brightness = MAX_BRIGHTNESS_11BIT,
+ .pwm_action = UPDATE_PWM_ONLY,
+ .ramp_table = lm3631_ramp_table,
+ .size_ramp = ARRAY_SIZE(lm3631_ramp_table),
+ },
+ {
+ .reginfo = &lm3632_reg_info,
+ .num_channels = LM3632_MAX_CHANNELS,
+ .max_brightness = MAX_BRIGHTNESS_11BIT,
+ .pwm_action = UPDATE_PWM_ONLY,
+ },
+ {
+ .reginfo = &lm3633_reg_info,
+ .num_channels = LM3633_MAX_CHANNELS,
+ .max_brightness = MAX_BRIGHTNESS_11BIT,
+ .pwm_action = UPDATE_MAX_BRT,
+ .ramp_table = common_ramp_table,
+ .size_ramp = ARRAY_SIZE(common_ramp_table),
+ .fault_monitor_used = true,
+ },
+ {
+ .reginfo = &lm3695_reg_info,
+ .num_channels = LM3695_MAX_CHANNELS,
+ .max_brightness = MAX_BRIGHTNESS_11BIT,
+ .pwm_action = UPDATE_PWM_AND_BRT_REGISTER,
+ },
+ {
+ .reginfo = &lm3697_reg_info,
+ .num_channels = LM3697_MAX_CHANNELS,
+ .max_brightness = MAX_BRIGHTNESS_11BIT,
+ .pwm_action = UPDATE_PWM_AND_BRT_REGISTER,
+ .ramp_table = common_ramp_table,
+ .size_ramp = ARRAY_SIZE(common_ramp_table),
+ .fault_monitor_used = true,
+ },
+};
+EXPORT_SYMBOL_GPL(lmu_bl_cfg);
diff --git a/include/linux/mfd/ti-lmu-backlight.h b/include/linux/mfd/ti-lmu-backlight.h
new file mode 100644
index 0000000..43e5300
--- /dev/null
+++ b/include/linux/mfd/ti-lmu-backlight.h
@@ -0,0 +1,290 @@
+/*
+ * TI LMU (Lighting Management Unit) Backlight Common Driver
+ *
+ * Copyright 2015 Texas Instruments
+ *
+ * Author: Milo 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.
+ */
+
+#ifndef __TI_LMU_BACKLIGHT_H__
+#define __TI_LMU_BACKLIGHT_H__
+
+#include <linux/backlight.h>
+#include <linux/device.h>
+#include <linux/mfd/ti-lmu.h>
+#include <linux/mfd/ti-lmu-register.h>
+#include <linux/notifier.h>
+
+/**
+ * LMU backlight register data
+ * value[23:16] | mask[15:8] | address[7:0]
+ */
+#define LMU_BL_REG(addr, mask, value) \
+ ((value << 16) | (mask << 8) | addr)
+
+#define LMU_BL_GET_ADDR(x) (x & 0xFF)
+#define LMU_BL_GET_MASK(x) ((x >> 8) & 0xFF)
+#define LMU_BL_GET_VAL(x) ((x >> 16) & 0xFF)
+
+#define LM3532_INIT_ZONE_0 \
+ LMU_BL_REG(LM3532_REG_ZONE_CFG_A, LM3532_ZONE_MASK, LM3532_ZONE_0)
+#define LM3532_INIT_ZONE_1 \
+ LMU_BL_REG(LM3532_REG_ZONE_CFG_B, LM3532_ZONE_MASK, LM3532_ZONE_1)
+#define LM3532_INIT_ZONE_2 \
+ LMU_BL_REG(LM3532_REG_ZONE_CFG_C, LM3532_ZONE_MASK, LM3532_ZONE_2)
+#define LM3532_CHANNEL_1 \
+ LMU_BL_REG(LM3532_REG_OUTPUT_CFG, LM3532_ILED1_CFG_MASK, \
+ LM3532_ILED1_CFG_SHIFT)
+#define LM3532_CHANNEL_2 \
+ LMU_BL_REG(LM3532_REG_OUTPUT_CFG, LM3532_ILED2_CFG_MASK, \
+ LM3532_ILED2_CFG_SHIFT)
+#define LM3532_CHANNEL_3 \
+ LMU_BL_REG(LM3532_REG_OUTPUT_CFG, LM3532_ILED3_CFG_MASK, \
+ LM3532_ILED3_CFG_SHIFT)
+#define LM3532_MODE_PWM_A \
+ LMU_BL_REG(LM3532_REG_PWM_A_CFG, LM3532_PWM_A_MASK, LM3532_PWM_ZONE_0)
+#define LM3532_MODE_PWM_B \
+ LMU_BL_REG(LM3532_REG_PWM_B_CFG, LM3532_PWM_B_MASK, LM3532_PWM_ZONE_1)
+#define LM3532_MODE_PWM_C \
+ LMU_BL_REG(LM3532_REG_PWM_C_CFG, LM3532_PWM_C_MASK, LM3532_PWM_ZONE_2)
+#define LM3532_RAMPUP \
+ LMU_BL_REG(LM3532_REG_RAMPUP, LM3532_RAMPUP_MASK, LM3532_RAMPUP_SHIFT)
+#define LM3532_RAMPDN \
+ LMU_BL_REG(LM3532_REG_RAMPDN, LM3532_RAMPDN_MASK, LM3532_RAMPDN_SHIFT)
+
+#define LM3631_INIT_BRT_MODE \
+ LMU_BL_REG(LM3631_REG_BRT_MODE, LM3631_MODE_MASK, LM3631_DEFAULT_MODE)
+#define LM3631_INIT_DIMMING_MODE \
+ LMU_BL_REG(LM3631_REG_BL_CFG, LM3631_MAP_MASK, LM3631_EXPONENTIAL_MAP)
+#define LM3631_SINGLE_CHANNEL \
+ LMU_BL_REG(LM3631_REG_BL_CFG, LM3631_BL_CHANNEL_MASK, \
+ LM3631_BL_SINGLE_CHANNEL)
+#define LM3631_DUAL_CHANNEL \
+ LMU_BL_REG(LM3631_REG_BL_CFG, LM3631_BL_CHANNEL_MASK, \
+ LM3631_BL_DUAL_CHANNEL)
+#define LM3631_RAMP \
+ LMU_BL_REG(LM3631_REG_SLOPE, LM3631_SLOPE_MASK, LM3631_SLOPE_SHIFT)
+
+#define LM3632_INIT_OVP_25V \
+ LMU_BL_REG(LM3632_REG_CONFIG1, LM3632_OVP_MASK, LM3632_OVP_25V)
+#define LM3632_INIT_SWFREQ_1MHZ \
+ LMU_BL_REG(LM3632_REG_CONFIG2, LM3632_SWFREQ_MASK, LM3632_SWFREQ_1MHZ)
+#define LM3632_SINGLE_CHANNEL \
+ LMU_BL_REG(LM3632_REG_ENABLE, LM3632_BL_CHANNEL_MASK, \
+ LM3632_BL_SINGLE_CHANNEL)
+#define LM3632_DUAL_CHANNEL \
+ LMU_BL_REG(LM3632_REG_ENABLE, LM3632_BL_CHANNEL_MASK, \
+ LM3632_BL_DUAL_CHANNEL)
+#define LM3632_MODE_PWM \
+ LMU_BL_REG(LM3632_REG_IO_CTRL, LM3632_PWM_MASK, LM3632_PWM_MODE)
+
+#define LM3633_INIT_OVP_40V \
+ LMU_BL_REG(LM3633_REG_BOOST_CFG, LM3633_OVP_MASK, LM3633_OVP_40V)
+#define LM3633_INIT_RAMP_SELECT \
+ LMU_BL_REG(LM3633_REG_BL_RAMP_CONF, LM3633_BL_RAMP_MASK, \
+ LM3633_BL_RAMP_EACH)
+#define LM3633_CHANNEL_HVLED1 \
+ LMU_BL_REG(LM3633_REG_HVLED_OUTPUT_CFG, LM3633_HVLED1_CFG_MASK, \
+ LM3633_HVLED1_CFG_SHIFT)
+#define LM3633_CHANNEL_HVLED2 \
+ LMU_BL_REG(LM3633_REG_HVLED_OUTPUT_CFG, LM3633_HVLED2_CFG_MASK, \
+ LM3633_HVLED2_CFG_SHIFT)
+#define LM3633_CHANNEL_HVLED3 \
+ LMU_BL_REG(LM3633_REG_HVLED_OUTPUT_CFG, LM3633_HVLED3_CFG_MASK, \
+ LM3633_HVLED3_CFG_SHIFT)
+#define LM3633_MODE_PWM_A \
+ LMU_BL_REG(LM3633_REG_PWM_CFG, LM3633_PWM_A_MASK, LM3633_PWM_A_MASK)
+#define LM3633_MODE_PWM_B \
+ LMU_BL_REG(LM3633_REG_PWM_CFG, LM3633_PWM_B_MASK, LM3633_PWM_B_MASK)
+#define LM3633_RAMPUP \
+ LMU_BL_REG(LM3633_REG_BL0_RAMP, LM3633_BL_RAMPUP_MASK, \
+ LM3633_BL_RAMPUP_SHIFT)
+#define LM3633_RAMPDN \
+ LMU_BL_REG(LM3633_REG_BL0_RAMP, LM3633_BL_RAMPDN_MASK, \
+ LM3633_BL_RAMPDN_SHIFT)
+
+#define LM3695_INIT_BRT_MODE \
+ LMU_BL_REG(LM3695_REG_GP, LM3695_BRT_RW_MASK, LM3695_BRT_RW_MASK)
+#define LM3695_SINGLE_CHANNEL \
+ LMU_BL_REG(LM3695_REG_GP, LM3695_BL_CHANNEL_MASK, \
+ LM3695_BL_SINGLE_CHANNEL)
+#define LM3695_DUAL_CHANNEL \
+ LMU_BL_REG(LM3695_REG_GP, LM3695_BL_CHANNEL_MASK, \
+ LM3695_BL_DUAL_CHANNEL)
+
+#define LM3697_INIT_RAMP_SELECT \
+ LMU_BL_REG(LM3697_REG_RAMP_CONF, LM3697_RAMP_MASK, LM3697_RAMP_EACH)
+#define LM3697_CHANNEL_1 \
+ LMU_BL_REG(LM3697_REG_HVLED_OUTPUT_CFG, LM3697_HVLED1_CFG_MASK, \
+ LM3697_HVLED1_CFG_SHIFT)
+#define LM3697_CHANNEL_2 \
+ LMU_BL_REG(LM3697_REG_HVLED_OUTPUT_CFG, LM3697_HVLED2_CFG_MASK, \
+ LM3697_HVLED2_CFG_SHIFT)
+#define LM3697_CHANNEL_3 \
+ LMU_BL_REG(LM3697_REG_HVLED_OUTPUT_CFG, LM3697_HVLED3_CFG_MASK, \
+ LM3697_HVLED3_CFG_SHIFT)
+#define LM3697_MODE_PWM_A \
+ LMU_BL_REG(LM3697_REG_PWM_CFG, LM3697_PWM_A_MASK, LM3697_PWM_A_MASK)
+#define LM3697_MODE_PWM_B \
+ LMU_BL_REG(LM3697_REG_PWM_CFG, LM3697_PWM_B_MASK, LM3697_PWM_B_MASK)
+#define LM3697_RAMPUP \
+ LMU_BL_REG(LM3697_REG_BL0_RAMP, LM3697_RAMPUP_MASK, LM3697_RAMPUP_SHIFT)
+#define LM3697_RAMPDN \
+ LMU_BL_REG(LM3697_REG_BL0_RAMP, LM3697_RAMPDN_MASK, LM3697_RAMPDN_SHIFT)
+
+#define LM3532_MAX_CHANNELS 3
+#define LM3631_MAX_CHANNELS 2
+#define LM3632_MAX_CHANNELS 2
+#define LM3633_MAX_CHANNELS 3
+#define LM3695_MAX_CHANNELS 2
+#define LM3697_MAX_CHANNELS 3
+
+#define MAX_BRIGHTNESS_8BIT 255
+#define MAX_BRIGHTNESS_11BIT 2047
+
+enum ti_lmu_bl_ctrl_mode {
+ BL_REGISTER_BASED,
+ BL_PWM_BASED,
+};
+
+enum ti_lmu_bl_pwm_action {
+ /* Update PWM duty, no brightness register update is required */
+ UPDATE_PWM_ONLY,
+ /* Update not only duty but also brightness register */
+ UPDATE_PWM_AND_BRT_REGISTER,
+ /* Update max value in brightness registers */
+ UPDATE_MAX_BRT,
+};
+
+enum ti_lmu_bl_ramp_mode {
+ BL_RAMP_UP,
+ BL_RAMP_DOWN,
+};
+
+struct ti_lmu_bl;
+struct ti_lmu_bl_chip;
+
+/**
+ * struct ti_lmu_bl_reg
+ *
+ * @init: Device initialization registers
+ * @num_init: Numbers of initialization registers
+ * @channel: Backlight channel configuration registers
+ * @mode: Brightness control mode registers
+ * @ramp: Ramp registers for lighting effect
+ * @ramp_reg_offset: Ramp register offset.
+ * Only used for multiple ramp registers.
+ * @enable: Enable control register address
+ * @enable_usec: Delay time for updating enable register.
+ * Unit is microsecond.
+ * @brightness_msb: Brightness MSB(Upper 8 bits) registers.
+ * Concatenated with LSB in 11 bit dimming mode.
+ * In 8 bit dimming, only MSB is used.
+ * @brightness_lsb: Brightness LSB(Lower 3 bits) registers.
+ * Only valid in 11 bit dimming mode.
+ */
+struct ti_lmu_bl_reg {
+ u32 *init;
+ int num_init;
+ u32 *channel;
+ u32 *mode;
+ u32 *ramp;
+ int ramp_reg_offset;
+ u8 *enable;
+ unsigned long enable_usec;
+ u8 *brightness_msb;
+ u8 *brightness_lsb;
+};
+
+/**
+ * struct ti_lmu_bl_cfg
+ *
+ * @reginfo: Device register configuration
+ * @num_channels: Number of backlight channels
+ * @max_brightness: Max brightness value of backlight device
+ * @pwm_action: How to control brightness registers in PWM mode
+ * @ramp_table: [Optional] Ramp time table for lighting effect.
+ * It's used for searching approximate register index.
+ * @size_ramp: [Optional] Size of ramp table
+ * @fault_monitor_used: [Optional] Set true if the device needs to handle
+ * LMU fault monitor event.
+ *
+ * This structure is used for device specific data configuration.
+ */
+struct ti_lmu_bl_cfg {
+ const struct ti_lmu_bl_reg *reginfo;
+ int num_channels;
+ int max_brightness;
+ enum ti_lmu_bl_pwm_action pwm_action;
+ int *ramp_table;
+ int size_ramp;
+ bool fault_monitor_used;
+};
+
+/**
+ * struct ti_lmu_bl_chip
+ *
+ * @dev: Parent device pointer
+ * @lmu: LMU structure.
+ * Used for register R/W access and notification.
+ * @cfg: Device configuration data
+ * @lmu_bl: Multiple backlight channels
+ * @num_backlights: Number of backlight channels
+ * @nb: Notifier block for handling LMU fault monitor event
+ *
+ * One backlight chip can have multiple backlight channels, 'ti_lmu_bl'.
+ */
+struct ti_lmu_bl_chip {
+ struct device *dev;
+ struct ti_lmu *lmu;
+ const struct ti_lmu_bl_cfg *cfg;
+ struct ti_lmu_bl *lmu_bl;
+ int num_backlights;
+ struct notifier_block nb;
+};
+
+/**
+ * struct ti_lmu_bl
+ *
+ * @chip: Pointer to parent backlight device
+ * @bl_dev: Backlight subsystem device structure
+ * @bank_id: Backlight bank ID
+ * @name: Backlight channel name
+ * @mode: Backlight control mode
+ * @led_sources: Backlight output channel configuration.
+ * Bit mask is set on parsing DT.
+ * @default_brightness: [Optional] Initial brightness value
+ * @ramp_up_msec: [Optional] Ramp up time
+ * @ramp_down_msec: [Optional] Ramp down time
+ * @pwm_period: [Optional] PWM period
+ * @pwm: [Optional] PWM subsystem structure
+ *
+ * Each backlight device has its own channel configuration.
+ * For chip control, parent chip data structure is used.
+ */
+struct ti_lmu_bl {
+ struct ti_lmu_bl_chip *chip;
+ struct backlight_device *bl_dev;
+
+ int bank_id;
+ const char *name;
+ enum ti_lmu_bl_ctrl_mode mode;
+ unsigned long led_sources;
+
+ unsigned int default_brightness;
+
+ /* Used for lighting effect */
+ unsigned int ramp_up_msec;
+ unsigned int ramp_down_msec;
+
+ /* Only valid in PWM mode */
+ unsigned int pwm_period;
+ struct pwm_device *pwm;
+};
+
+extern struct ti_lmu_bl_cfg lmu_bl_cfg[LMU_MAX_ID];
+#endif
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web