[PATCH 04/10] backlight: ti-lmu-backlight: Add LM3631 driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




LM3631 has 2 backlight strings and 11 bit dimming is supported.
PWM brightness control is also supported.

Common backlight driver is controlled by TI LMU backlight driver.
Only LM3631 specific code is implemented here.

Cc: Jingoo Han <jg1.han@xxxxxxxxxxx>
Cc: Bryan Wu <cooloney@xxxxxxxxx>
Cc: Lee Jones <lee.jones@xxxxxxxxxx>
Signed-off-by: Milo Kim <milo.kim@xxxxxx>
---
 drivers/video/backlight/Kconfig     |    9 ++
 drivers/video/backlight/Makefile    |    1 +
 drivers/video/backlight/lm3631_bl.c |  186 +++++++++++++++++++++++++++++++++++
 3 files changed, 196 insertions(+)
 create mode 100644 drivers/video/backlight/lm3631_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index d841057..a43a015 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -393,6 +393,15 @@ config BACKLIGHT_LM3532
 	  Up to 3 backlight strings and 8 bit dimming is supported.
 	  PWM brightness control is also supported.
 
+config BACKLIGHT_LM3631
+	tristate "Backlight driver for TI LM3631"
+	depends on BACKLIGHT_CLASS_DEVICE && MFD_TI_LMU
+	select TI_LMU_BACKLIGHT
+	help
+	  Say Y to enable the backlight driver for TI LM3631.
+	  Up to 2 backlight strings and 11 bit dimming is supported.
+	  PWM brightness control is also supported.
+
 config TI_LMU_BACKLIGHT
 	tristate "Backlight driver for TI LMU"
 	depends on BACKLIGHT_LM3532 || BACKLIGHT_LM3631 || BACKLIGHT_LM3633 || BACKLIGHT_LM3695 || BACKLIGHT_LM3697
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 51354d1..2a17f8b 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_BACKLIGHT_LM3533)		+= lm3533_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3630A)		+= lm3630a_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3639)		+= lm3639_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3532)		+= lm3532_bl.o
+obj-$(CONFIG_BACKLIGHT_LM3631)		+= lm3631_bl.o
 obj-$(CONFIG_TI_LMU_BACKLIGHT)		+= ti-lmu-backlight.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO)		+= locomolcd.o
 obj-$(CONFIG_BACKLIGHT_LP855X)		+= lp855x_bl.o
diff --git a/drivers/video/backlight/lm3631_bl.c b/drivers/video/backlight/lm3631_bl.c
new file mode 100644
index 0000000..45693c0
--- /dev/null
+++ b/drivers/video/backlight/lm3631_bl.c
@@ -0,0 +1,186 @@
+/*
+ * TI LM3631 Backlight Driver
+ *
+ * Copyright 2014 Texas Instruments
+ *
+ * Author: Milo Kim <milo.kim@xxxxxx>
+ *
+ * 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.
+ *
+ * LM3631 backlight driver consists of three parts
+ *
+ *   1) LM3631 chip specific part: this file
+ *      Define device specific operations
+ *      Register LMU backlight driver
+ *
+ *   2) LMU backlight common driver: ti-lmu-backlight
+ *      General backlight subsystem control
+ *
+ *   3) LMU effect driver
+ *      Backlight slope time configuration
+ */
+
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/mfd/ti-lmu.h>
+#include <linux/mfd/ti-lmu-effect.h>
+#include <linux/mfd/ti-lmu-register.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+
+#include "ti-lmu-backlight.h"
+
+#define LM3631_FULL_STRINGS		(LMU_HVLED1 | LMU_HVLED2)
+#define LM3631_DEFAULT_MODE		LM3631_MODE_COMB1
+#define LM3631_MAX_BRIGHTNESS		2047
+
+static int lm3631_bl_init(struct ti_lmu_bl_chip *chip)
+{
+	int ret;
+
+	/* Set OVP to 25V by default */
+	ret = ti_lmu_update_bits(chip->lmu, LM3631_REG_BL_BOOST,
+				 LM3631_BOOST_OVP_MASK, LM3631_BOOST_OVP_25V);
+	if (ret)
+		return ret;
+
+	/* Set the brightness mode to 'comb1' by default */
+	return ti_lmu_update_bits(chip->lmu, LM3631_REG_BRT_MODE,
+				  LM3631_MODE_MASK, LM3631_DEFAULT_MODE);
+}
+
+static int lm3631_bl_enable(struct ti_lmu_bl *lmu_bl, int enable)
+{
+	return ti_lmu_update_bits(lmu_bl->chip->lmu, LM3631_REG_DEVCTRL,
+				  LM3631_BL_EN_MASK,
+				  enable << LM3631_BL_EN_SHIFT);
+}
+
+static int lm3631_bl_set_brightness(struct ti_lmu_bl *lmu_bl, int brightness)
+{
+	u8 data;
+	int ret;
+
+	if (lmu_bl->mode == BL_PWM_BASED)
+		return 0;
+
+	data = brightness & LM3631_BRT_LSB_MASK;
+	ret = ti_lmu_update_bits(lmu_bl->chip->lmu, LM3631_REG_BRT_LSB,
+				 LM3631_BRT_LSB_MASK, data);
+	if (ret)
+		return ret;
+
+	data = (brightness >> LM3631_BRT_MSB_SHIFT) & 0xFF;
+	return ti_lmu_write_byte(lmu_bl->chip->lmu, LM3631_REG_BRT_MSB,
+				 data);
+}
+
+static int lm3631_bl_string_configure(struct ti_lmu_bl *lmu_bl)
+{
+	u8 val;
+
+	if (lmu_bl->bl_pdata->bl_string == LM3631_FULL_STRINGS)
+		val = LM3631_BL_TWO_STRINGS;
+	else
+		val = LM3631_BL_ONE_STRING;
+
+	return ti_lmu_update_bits(lmu_bl->chip->lmu, LM3631_REG_BL_CFG,
+				  LM3631_BL_STRING_MASK, val);
+}
+
+static void lm3631_bl_effect_request(struct ti_lmu_bl *lmu_bl)
+{
+	/* Set exponential mapping */
+	ti_lmu_update_bits(lmu_bl->chip->lmu, LM3631_REG_BL_CFG,
+			   LM3631_MAP_MASK, LM3631_EXPONENTIAL_MAP);
+
+	/* Enable slope bit before updating slope time value */
+	ti_lmu_update_bits(lmu_bl->chip->lmu, LM3631_REG_BRT_MODE,
+			   LM3631_EN_SLOPE_MASK, LM3631_EN_SLOPE_MASK);
+
+	ti_lmu_effect_request(LM3631_EFFECT_SLOPE,
+			      ti_lmu_backlight_effect_callback,
+			      BL_EFFECT_RAMPUP, lmu_bl);
+}
+
+static int lm3631_bl_configure(struct ti_lmu_bl *lmu_bl)
+{
+	int ret;
+
+	ret = lm3631_bl_string_configure(lmu_bl);
+	if (ret)
+		return ret;
+
+	if (lmu_bl->mode == BL_PWM_BASED) {
+		snprintf(lmu_bl->pwm_name, sizeof(lmu_bl->pwm_name),
+			 "%s", LMU_BL_DEFAULT_PWM_NAME);
+	}
+
+	/* LMU effect is optional, checking return value is not required */
+	lm3631_bl_effect_request(lmu_bl);
+
+	return 0;
+}
+
+static const struct ti_lmu_bl_ops lm3631_lmu_ops = {
+	.init              = lm3631_bl_init,
+	.configure         = lm3631_bl_configure,
+	.update_brightness = lm3631_bl_set_brightness,
+	.bl_enable         = lm3631_bl_enable,
+	.max_brightness    = LM3631_MAX_BRIGHTNESS,
+};
+
+static int lm3631_bl_probe(struct platform_device *pdev)
+{
+	struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent);
+	struct ti_lmu_bl *lmu_bl;
+	struct ti_lmu_bl_chip *chip;
+
+	chip = ti_lmu_backlight_init_device(&pdev->dev, lmu, &lm3631_lmu_ops);
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+
+	lmu_bl = ti_lmu_backlight_register(chip, lmu->pdata->bl_pdata, 1);
+	if (IS_ERR(lmu_bl))
+		return PTR_ERR(lmu_bl);
+
+	platform_set_drvdata(pdev, lmu_bl);
+
+	return 0;
+}
+
+static int lm3631_bl_remove(struct platform_device *pdev)
+{
+	struct ti_lmu_bl *lmu_bl = platform_get_drvdata(pdev);
+
+	return ti_lmu_backlight_unregister(lmu_bl);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id lm3631_bl_of_match[] = {
+	{ .compatible = "ti,lm3631-backlight", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, lm3631_bl_of_match);
+#endif
+
+static struct platform_driver lm3631_bl_driver = {
+	.probe = lm3631_bl_probe,
+	.remove = lm3631_bl_remove,
+	.driver = {
+		.name = "lm3631-backlight",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(lm3631_bl_of_match),
+	},
+};
+module_platform_driver(lm3631_bl_driver);
+
+MODULE_DESCRIPTION("TI LM3631 Backlight Driver");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lm3631-backlight");
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux