From: Cyril Chemparathy <cyril-l0cyMroinI0@public.gmane.org>
To: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org,
spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org,
lrg-kDsPt+C1G03kYMGBc/C6ZA@public.gmane.org,
broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org,
rpurdie@rpsys
Cc: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org,
Cyril Chemparathy <cyril-l0cyMroinI0@public.gmane.org>,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org,
alan-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org
Subject: [PATCH v7 10/12] backlight: add support for tps6116x controller
Date: Tue, 7 Dec 2010 09:52:00 -0500 [thread overview]
Message-ID: <1291733522-3626-11-git-send-email-cyril@ti.com> (raw)
In-Reply-To: <1291733522-3626-1-git-send-email-cyril-l0cyMroinI0@public.gmane.org>
TPS6116x is an EasyScale backlight controller device. This driver supports
TPS6116x devices connected on a single GPIO.
Signed-off-by: Cyril Chemparathy <cyril-l0cyMroinI0@public.gmane.org>
---
drivers/video/backlight/Kconfig | 7 +
drivers/video/backlight/Makefile | 2 +-
drivers/video/backlight/tps6116x.c | 299 ++++++++++++++++++++++++++++++++++++
3 files changed, 307 insertions(+), 1 deletions(-)
create mode 100644 drivers/video/backlight/tps6116x.c
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index e54a337..06e868e 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -307,6 +307,13 @@ config BACKLIGHT_PCF50633
If you have a backlight driven by a NXP PCF50633 MFD, say Y here to
enable its driver.
+config BACKLIGHT_TPS6116X
+ tristate "TPS6116X LCD Backlight"
+ depends on GENERIC_GPIO
+ help
+ This driver controls the LCD backlight level for EasyScale capable
+ SSP connected backlight controllers.
+
endif # BACKLIGHT_CLASS_DEVICE
endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 44c0f81..5d407c8 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -35,4 +35,4 @@ obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o
obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
-
+obj-$(CONFIG_BACKLIGHT_TPS6116X)+= tps6116x.o
diff --git a/drivers/video/backlight/tps6116x.c b/drivers/video/backlight/tps6116x.c
new file mode 100644
index 0000000..7f846ab
--- /dev/null
+++ b/drivers/video/backlight/tps6116x.c
@@ -0,0 +1,299 @@
+/*
+ * TPS6116X LCD Backlight Controller Driver
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/fb.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#define TPS6116X_MAX_INTENSITY 31
+#define TPS6116X_DEFAULT_INTENSITY 10
+
+/* Easyscale timing w/ margin (usecs) */
+#define T_POWER_SETTLE 2000
+#define T_ES_DELAY 120
+#define T_ES_DETECT 280
+#define T_ES_WINDOW (1000 - T_ES_DELAY - T_ES_DETECT)
+#define T_START 3
+#define T_EOS 3
+#define T_INACTIVE 3
+#define T_ACTIVE (3 * T_INACTIVE)
+
+#define CMD_SET 0x72
+
+struct tps6116x {
+ struct ti_ssp_device *handle;
+ struct device *dev;
+ int gpio;
+ struct mutex lock;
+ int intensity;
+ struct backlight_properties props;
+ struct backlight_device *bl;
+ struct regulator *regulator;
+ bool power;
+ bool suspended;
+};
+
+static int __set_power(struct tps6116x *hw, bool power)
+{
+ unsigned long flags;
+ int error;
+
+ if (power == hw->power)
+ return 0; /* nothing to do */
+
+ /* disabling is simple... choke power */
+ if (!power) {
+ error = regulator_disable(hw->regulator);
+ goto done;
+ }
+
+ /* set ctrl pin init state for easyscale detection */
+ gpio_set_value(hw->gpio, 0);
+
+ error = regulator_enable(hw->regulator);
+ if (error < 0)
+ goto done;
+
+ udelay(T_POWER_SETTLE);
+
+ /*
+ * Now that the controller is powered up, we need to put it into 1-wire
+ * mode. This is a timing sensitive operation, hence the irq disable.
+ * Ideally, this should happen rarely, and mostly at init, so disabling
+ * interrupts for the duration should not be a problem.
+ */
+ local_irq_save(flags);
+
+ gpio_set_value(hw->gpio, 1);
+ udelay(T_ES_DELAY);
+ gpio_set_value(hw->gpio, 0);
+ udelay(T_ES_DETECT);
+ gpio_set_value(hw->gpio, 1);
+
+ local_irq_restore(flags);
+
+done:
+ if (error >= 0)
+ hw->power = power;
+
+ return error;
+}
+
+static void __write_byte(struct tps6116x *hw, u8 data)
+{
+ int bit;
+
+ gpio_set_value(hw->gpio, 1);
+ udelay(T_START);
+
+ for (bit = 0; bit < 8; bit++, data <<= 1) {
+ int val = data & 0x80;
+ int t_lo = val ? T_INACTIVE : T_ACTIVE;
+ int t_hi = val ? T_ACTIVE : T_INACTIVE;
+
+ gpio_set_value(hw->gpio, 0);
+ udelay(t_lo);
+ gpio_set_value(hw->gpio, 1);
+ udelay(t_hi);
+ }
+
+ gpio_set_value(hw->gpio, 0);
+ udelay(T_EOS);
+ gpio_set_value(hw->gpio, 1);
+}
+
+static void __set_intensity(struct tps6116x *hw, int intensity)
+{
+ unsigned long flags;
+
+ intensity = clamp(intensity, 0, TPS6116X_MAX_INTENSITY);
+
+ local_irq_save(flags);
+ __write_byte(hw, CMD_SET);
+ __write_byte(hw, intensity);
+ local_irq_restore(flags);
+}
+
+static int set_intensity(struct tps6116x *hw, int intensity)
+{
+ int error = 0;
+
+ if (intensity == hw->intensity)
+ return 0;
+
+ mutex_lock(&hw->lock);
+
+ error = __set_power(hw, intensity ? true : false);
+ if (error < 0)
+ goto error;
+
+ if (intensity > 0)
+ __set_intensity(hw, intensity);
+
+ hw->intensity = intensity;
+error:
+ mutex_unlock(&hw->lock);
+
+ return error;
+}
+
+static int get_brightness(struct backlight_device *bl)
+{
+ struct tps6116x *hw = bl_get_data(bl);
+
+ return hw->intensity;
+}
+
+static int update_status(struct backlight_device *bl)
+{
+ struct tps6116x *hw = bl_get_data(bl);
+ int intensity = bl->props.brightness;
+
+ if (hw->suspended || hw->props.state & BL_CORE_SUSPENDED)
+ intensity = 0;
+ if (bl->props.power != FB_BLANK_UNBLANK)
+ intensity = 0;
+ if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+ intensity = 0;
+
+ return set_intensity(hw, intensity);
+}
+
+static const struct backlight_ops tps6116x_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .get_brightness = get_brightness,
+ .update_status = update_status,
+};
+
+static int __devinit tps6116x_probe(struct platform_device *pdev)
+{
+ struct tps6116x *hw;
+ struct device *dev = &pdev->dev;
+ struct backlight_properties props;
+ int error;
+
+ hw = kzalloc(sizeof(struct tps6116x), GFP_KERNEL);
+ if (!hw) {
+ dev_err(dev, "cannot allocate driver data\n");
+ return -ENOMEM;
+ }
+ platform_set_drvdata(pdev, hw);
+
+ hw->gpio = (int)dev->platform_data;
+ hw->dev = dev;
+
+ mutex_init(&hw->lock);
+
+ hw->regulator = regulator_get(dev, "vlcd");
+ if (IS_ERR(hw->regulator)) {
+ error = PTR_ERR(hw->regulator);
+ dev_err(dev, "cannot claim regulator\n");
+ goto error_regulator;
+ }
+
+ error = gpio_request_one(hw->gpio, GPIOF_DIR_OUT, dev_name(dev));
+ if (error < 0) {
+ dev_err(dev, "cannot claim gpio\n");
+ goto error_gpio;
+ }
+
+ memset(&props, 0, sizeof(props));
+ props.max_brightness = TPS6116X_MAX_INTENSITY;
+ props.brightness = TPS6116X_DEFAULT_INTENSITY;
+ props.power = FB_BLANK_UNBLANK;
+
+ hw->bl = backlight_device_register("tps6116x", hw->dev, hw,
+ &tps6116x_backlight_ops, &props);
+ if (IS_ERR(hw->bl)) {
+ error = PTR_ERR(hw->bl);
+ dev_err(dev, "backlight registration failed\n");
+ goto error_register;
+ }
+
+ update_status(hw->bl);
+ dev_info(dev, "registered backlight controller\n");
+ return 0;
+
+error_register:
+ gpio_free(hw->gpio);
+error_gpio:
+ regulator_put(hw->regulator);
+error_regulator:
+ kfree(hw);
+ platform_set_drvdata(pdev, NULL);
+ return error;
+}
+
+static int __devexit tps6116x_remove(struct platform_device *pdev)
+{
+ struct tps6116x *hw = platform_get_drvdata(pdev);
+
+ backlight_device_unregister(hw->bl);
+ regulator_disable(hw->regulator);
+ regulator_put(hw->regulator);
+ gpio_free(hw->gpio);
+ kfree(hw);
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static int tps6116x_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct tps6116x *hw = platform_get_drvdata(pdev);
+ hw->suspended = true;
+ update_status(hw->bl);
+ return 0;
+}
+
+static int tps6116x_resume(struct platform_device *pdev)
+{
+ struct tps6116x *hw = platform_get_drvdata(pdev);
+ hw->suspended = false;
+ update_status(hw->bl);
+ return 0;
+}
+
+static struct platform_driver tps6116x_driver = {
+ .probe = tps6116x_probe,
+ .remove = __devexit_p(tps6116x_remove),
+ .suspend = tps6116x_suspend,
+ .resume = tps6116x_resume,
+ .driver = {
+ .name = "tps6116x",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init tps6116x_init(void)
+{
+ return platform_driver_register(&tps6116x_driver);
+}
+module_init(tps6116x_init);
+
+static void __exit tps6116x_exit(void)
+{
+ platform_driver_unregister(&tps6116x_driver);
+}
+module_exit(tps6116x_exit);
+
+MODULE_DESCRIPTION("SSP TPS6116X Driver");
+MODULE_AUTHOR("Cyril Chemparathy");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:tps6116x");
--
1.7.1
------------------------------------------------------------------------------
What happens now with your Lotus Notes apps - do you make another costly
upgrade, or settle for being marooned without product support? Time to move
off Lotus Notes and onto the cloud with Force.com, apps are easier to build,
use, and manage than apps on traditional platforms. Sign up for the Lotus
Notes Migration Kit to learn more. http://p.sf.net/sfu/salesforce-d2d
next prev parent reply other threads:[~2010-12-07 14:52 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-07 14:51 [PATCH v7 00/12] tnetv107x ssp drivers Cyril Chemparathy
[not found] ` <1291733522-3626-1-git-send-email-cyril-l0cyMroinI0@public.gmane.org>
2010-12-07 14:51 ` [PATCH v7 01/12] misc: add driver for sequencer serial port Cyril Chemparathy
[not found] ` <1291733522-3626-2-git-send-email-cyril-l0cyMroinI0@public.gmane.org>
2010-12-11 0:13 ` Kevin Hilman
2010-12-07 14:51 ` [PATCH v7 02/12] davinci: add tnetv107x ssp platform device Cyril Chemparathy
2010-12-07 14:51 ` [PATCH v7 03/12] davinci: add ssp config for tnetv107x evm board Cyril Chemparathy
2010-12-07 14:51 ` [PATCH v7 04/12] spi: add ti-ssp spi master driver Cyril Chemparathy
[not found] ` <1291733522-3626-5-git-send-email-cyril-l0cyMroinI0@public.gmane.org>
2010-12-31 6:26 ` Grant Likely
2010-12-07 14:51 ` [PATCH v7 05/12] davinci: add spi devices on tnetv107x evm Cyril Chemparathy
2010-12-07 14:51 ` [PATCH v7 06/12] regulator: add driver for tps6524x regulator Cyril Chemparathy
[not found] ` <1291733522-3626-7-git-send-email-cyril-l0cyMroinI0@public.gmane.org>
2010-12-07 15:22 ` Mark Brown
[not found] ` <20101207152222.GD9689-HF5t3jzXg/6ND3a5+9QAFujbO/Zr0HzV@public.gmane.org>
2010-12-07 16:46 ` Cyril Chemparathy
2010-12-07 14:51 ` [PATCH v7 07/12] davinci: add tnetv107x evm regulators Cyril Chemparathy
2010-12-07 14:51 ` [PATCH v7 08/12] gpio: add ti-ssp gpio driver Cyril Chemparathy
[not found] ` <1291733522-3626-9-git-send-email-cyril-l0cyMroinI0@public.gmane.org>
2010-12-31 6:16 ` Grant Likely
2010-12-07 14:51 ` [PATCH v7 09/12] davinci: add tnetv107x evm ti-ssp gpio device Cyril Chemparathy
2010-12-07 14:52 ` Cyril Chemparathy [this message]
2010-12-07 14:52 ` [PATCH v7 11/12] davinci: add tnetv107x evm backlight device Cyril Chemparathy
[not found] ` <1291733522-3626-12-git-send-email-cyril-l0cyMroinI0@public.gmane.org>
2010-12-09 8:55 ` Nori, Sekhar
[not found] ` <B85A65D85D7EB246BE421B3FB0FBB5930247CD83E1@dbde02.ent.ti.com>
[not found] ` <B85A65D85D7EB246BE421B3FB0FBB5930247CD83E1-/tLxBxkBPtCIQmiDNMet8wC/G2K4zDHf@public.gmane.org>
2010-12-09 11:00 ` Nori, Sekhar
[not found] ` <B85A65D85D7EB246BE421B3FB0FBB5930247CD84F4@dbde02.ent.ti.com>
[not found] ` <B85A65D85D7EB246BE421B3FB0FBB5930247CD84F4-/tLxBxkBPtCIQmiDNMet8wC/G2K4zDHf@public.gmane.org>
2010-12-09 14:58 ` Cyril Chemparathy
[not found] ` <4D00EEA1.8070201-l0cyMroinI0@public.gmane.org>
2010-12-10 16:01 ` Nori, Sekhar
[not found] ` <B85A65D85D7EB246BE421B3FB0FBB5930247CD8CE8-/tLxBxkBPtCIQmiDNMet8wC/G2K4zDHf@public.gmane.org>
2010-12-10 16:56 ` Kevin Hilman
2010-12-07 14:52 ` [PATCH v7 12/12] davinci: add tnetv107x evm i2c eeprom device Cyril Chemparathy
2010-12-11 0:19 ` [PATCH v7 00/12] tnetv107x ssp drivers Kevin Hilman
[not found] ` <87r5dp6tzv.fsf-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org>
2010-12-11 12:42 ` Mark Brown
[not found] ` <20101211124242.GE9380-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2010-12-30 21:05 ` Grant Likely
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1291733522-3626-11-git-send-email-cyril@ti.com \
--to=cyril-l0cymroini0@public.gmane.org \
--cc=akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org \
--cc=alan-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org \
--cc=broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org \
--cc=davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org \
--cc=dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org \
--cc=lrg-kDsPt+C1G03kYMGBc/C6ZA@public.gmane.org \
--cc=rpurdie@rpsys \
--cc=sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org \
--cc=spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).