summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Jain <ajain@motorola.com>2014-10-05 20:21:19 -0500
committerAmit Jain <ajain@motorola.com>2014-10-06 19:10:24 +0000
commit1d37d79a3000fa182aacf007ca05826ffb4a46fc (patch)
tree932d2a4c3b58c3738624073f89d23e4add86de59
parent89ee8f2ea7aa0a1e9af8184da2e3e3282976f196 (diff)
downloadolio-linux-3.10-1d37d79a3000fa182aacf007ca05826ffb4a46fc.tar.xz
olio-linux-3.10-1d37d79a3000fa182aacf007ca05826ffb4a46fc.zip
IKXCLOCK-4101: use ALS to control backlight
when watch is on charger
-rw-r--r--arch/arm/configs/minnow_defconfig1
-rw-r--r--drivers/leds/leds-lm3535.c42
-rw-r--r--drivers/misc/Kconfig7
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/als_notify.c50
-rw-r--r--drivers/misc/m4sensorhub_als.c58
-rw-r--r--include/linux/als_notify.h27
7 files changed, 182 insertions, 4 deletions
diff --git a/arch/arm/configs/minnow_defconfig b/arch/arm/configs/minnow_defconfig
index fa1a3eb44af..fe129184caf 100644
--- a/arch/arm/configs/minnow_defconfig
+++ b/arch/arm/configs/minnow_defconfig
@@ -1154,6 +1154,7 @@ CONFIG_MOT_UTAG=y
CONFIG_BQ5105X_CTRL=y
CONFIG_BQ5105X_DETECT=y
CONFIG_WAKEUP_SOURCE_NOTIFY=y
+CONFIG_ALS_WHILE_CHARGING=y
# CONFIG_C2PORT is not set
#
diff --git a/drivers/leds/leds-lm3535.c b/drivers/leds/leds-lm3535.c
index 3f157942803..e2764927e3c 100644
--- a/drivers/leds/leds-lm3535.c
+++ b/drivers/leds/leds-lm3535.c
@@ -50,13 +50,16 @@
#ifdef CONFIG_LM3535_ESD_RECOVERY
#include <mot/esd_poll.h>
#endif /* CONFIG_LM3535_ESD_RECOVERY */
-#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY
#include <linux/notifier.h>
+#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY
#include <linux/wakeup_source_notify.h>
-#define MIN_DOCK_BVALUE 36
+#define MIN_DOCK_BVALUE 36
#include <linux/m4sensorhub.h>
#include <linux/m4sensorhub/MemMapUserSettings.h>
#endif
+#ifdef CONFIG_ALS_WHILE_CHARGING
+#include <linux/als_notify.h>
+#endif
#define MODULE_NAME "leds_lm3535"
@@ -275,6 +278,9 @@ struct lm3535 {
atomic_t docked;
struct notifier_block dock_nb;
#endif
+#ifdef CONFIG_ALS_WHILE_CHARGING
+ struct notifier_block als_nb;
+#endif
};
static DEFINE_MUTEX(lm3535_mutex);
@@ -660,6 +666,18 @@ static void lm3535_brightness_set_raw_als(struct led_classdev *led_cdev,
mutex_unlock(&lm3535_mutex);
}
#endif
+
+#ifdef CONFIG_ALS_WHILE_CHARGING
+static int lm3535_als_notifier(struct notifier_block *self,
+ unsigned long action, void *dev)
+{
+ pr_info("%s: ALS value is %lu\n", __func__, action);
+ lm3535_brightness_set_raw_als(led_get_default_dev(),
+ (unsigned int)action);
+ return NOTIFY_OK;
+}
+#endif
+
static void lm3535_brightness_set (struct led_classdev *led_cdev,
enum led_brightness value)
{
@@ -671,6 +689,13 @@ static void lm3535_brightness_set (struct led_classdev *led_cdev,
unsigned bvalue;
unsigned do_ramp = 1;
+#ifdef CONFIG_ALS_WHILE_CHARGING
+ if (atomic_read(&lm3535_data.docked)) {
+ pr_info("%s: docked, ignoring call\n", __func__);
+ return;
+ }
+#endif /* CONFIG_WAKEUP_SOURCE_NOTIFY */
+
printk_br ("%s: %s, 0x%x (%d)\n", __FUNCTION__,
led_cdev->name, value, value);
if (!lm3535_data.initialized) {
@@ -707,6 +732,7 @@ static void lm3535_brightness_set (struct led_classdev *led_cdev,
/* Calculate brightness value for each zone relative to its cap */
bvalue = lm3535_convert_value (value, bright_zone);
+
#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY
if (atomic_read(&lm3535_data.docked) && (bvalue < MIN_DOCK_BVALUE))
bvalue = MIN_DOCK_BVALUE; /* hard code for dock mode */
@@ -1040,6 +1066,11 @@ static int lm3535_probe (struct i2c_client *client,
wakeup_source_register_notify(&lm3535_data.dock_nb);
#endif /* CONFIG_WAKEUP_SOURCE_NOTIFY */
+#ifdef CONFIG_ALS_WHILE_CHARGING
+ lm3535_data.als_nb.notifier_call = lm3535_als_notifier;
+ als_register_notify(&lm3535_data.als_nb);
+#endif
+
INIT_DELAYED_WORK(&lm3535_data.als_delayed_work,
lm3535_allow_als_work_func);
@@ -1519,6 +1550,13 @@ static int lm3535_remove (struct i2c_client *client)
input_unregister_device (lm3535_data.idev);
input_free_device (lm3535_data.idev);
#endif
+
+#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY
+ wakeup_source_unregister_notify(&lm3535_data.dock_nb);
+#endif
+#ifdef CONFIG_ALS_WHILE_CHARGING
+ als_unregister_notify(&lm3535_data.als_nb);
+#endif
return 0;
}
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 5b96da5fda8..5aed79aa3c4 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -586,6 +586,13 @@ config WAKEUP_SOURCE_NOTIFY
help
Driver to allow early notification of wakeups
+config ALS_WHILE_CHARGING
+ tristate "use ALS when on charger"
+ depends on WAKEUP_SOURCE_NOTIFY
+ help
+ ALS when unit is on charger
+
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 2f57dbac599..b415f69e536 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -68,3 +68,4 @@ obj-$(CONFIG_MOT_UTAG) += utag/
obj-$(CONFIG_BQ5105X_CTRL) += bq5105x_ctrl.o
obj-$(CONFIG_BQ5105X_DETECT) += bq5105x_detect.o
obj-$(CONFIG_WAKEUP_SOURCE_NOTIFY) += wakeup_source_notify.o
+obj-$(CONFIG_ALS_WHILE_CHARGING) += als_notify.o
diff --git a/drivers/misc/als_notify.c b/drivers/misc/als_notify.c
new file mode 100644
index 00000000000..cbb4f3a55cd
--- /dev/null
+++ b/drivers/misc/als_notify.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 Motorola Mobility LLC.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/notifier.h>
+#include <linux/als_notify.h>
+
+static BLOCKING_NOTIFIER_HEAD(als_notifier_list);
+
+/**
+ * als_register_notify - register a notifier callback for triggering display init
+ * @nb: pointer to the notifier block for the callback events.
+ *
+ */
+void als_register_notify(struct notifier_block *nb)
+{
+ blocking_notifier_chain_register(&als_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(als_register_notify);
+
+/**
+ * als_unregister_notify - unregister a notifier callback
+ * @nb: pointer to the notifier block for the callback events.
+ *
+ * als_register_notify() must have been previously called
+ * for this function to work properly.
+ */
+void als_unregister_notify(struct notifier_block *nb)
+{
+ blocking_notifier_chain_unregister(&als_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(als_unregister_notify);
+
+void als_notify_subscriber(unsigned long event)
+{
+ blocking_notifier_call_chain(&als_notifier_list, event, NULL);
+}
+EXPORT_SYMBOL_GPL(als_notify_subscriber);
diff --git a/drivers/misc/m4sensorhub_als.c b/drivers/misc/m4sensorhub_als.c
index 55fa5f733e1..717c4fe2911 100644
--- a/drivers/misc/m4sensorhub_als.c
+++ b/drivers/misc/m4sensorhub_als.c
@@ -29,6 +29,11 @@
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#ifdef CONFIG_ALS_WHILE_CHARGING
+#include <linux/notifier.h>
+#include <linux/als_notify.h>
+#include <linux/wakeup_source_notify.h>
+#endif
#define m4als_err(format, args...) KDEBUG(M4SH_ERROR, format, ## args)
@@ -48,8 +53,31 @@ struct m4als_driver_data {
int16_t latest_samplerate;
int16_t fastest_rate;
uint16_t status;
+#ifdef CONFIG_ALS_WHILE_CHARGING
+ struct notifier_block charger_nb;
+ bool chargerstatus;
+#endif
};
+#ifdef CONFIG_ALS_WHILE_CHARGING
+static int charger_notify(struct notifier_block *self,
+ unsigned long action, void *dev)
+{
+ struct m4als_driver_data *dd =
+ container_of(self, struct m4als_driver_data, charger_nb);
+ switch (action) {
+ case DISPLAY_WAKE_EVENT_DOCKON:
+ case DISPLAY_WAKE_EVENT_DOCKOFF:
+ dd->chargerstatus = (action == DISPLAY_WAKE_EVENT_DOCKON);
+ pr_info("%s: dd->chargerstatus is %d\n",
+ __func__, dd->chargerstatus);
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+#endif
+
static void m4als_work_func(struct work_struct *work)
{
int err = 0;
@@ -82,8 +110,18 @@ static void m4als_work_func(struct work_struct *work)
dd->luminosity = luminosity;
- input_event(dd->indev, EV_MSC, MSC_RAW, dd->luminosity);
- input_sync(dd->indev);
+#ifdef CONFIG_ALS_WHILE_CHARGING
+ if (dd->chargerstatus == true) {
+ als_notify_subscriber(luminosity);
+ } else {
+ input_event(dd->indev, EV_MSC, MSC_RAW, dd->luminosity);
+ input_sync(dd->indev);
+ }
+#else
+ input_event(dd->indev, EV_MSC, MSC_RAW, dd->luminosity);
+ input_sync(dd->indev);
+#endif
+
if (dd->samplerate > 0)
queue_delayed_work(system_freezable_wq, &(dd->m4als_work),
msecs_to_jiffies(dd->samplerate));
@@ -102,6 +140,13 @@ static int m4als_set_samplerate(struct m4als_driver_data *dd, int16_t rate)
int err = 0;
int size = 0;
+#ifdef CONFIG_ALS_WHILE_CHARGING
+ if (rate == -1 && dd->chargerstatus == true) {
+ m4als_err("%s: ignoring disable\n", __func__);
+ return err;
+ }
+#endif
+
if ((rate >= 0) && (rate <= dd->fastest_rate))
rate = dd->fastest_rate;
@@ -388,6 +433,12 @@ static int m4als_probe(struct platform_device *pdev)
goto m4als_probe_fail;
}
+#ifdef CONFIG_ALS_WHILE_CHARGING
+ dd->chargerstatus = false;
+ dd->charger_nb.notifier_call = charger_notify;
+ wakeup_source_register_notify(&dd->charger_nb);
+#endif
+
return 0;
m4als_probe_fail:
@@ -406,6 +457,9 @@ static int __exit m4als_remove(struct platform_device *pdev)
cancel_delayed_work(&(dd->m4als_work));
m4als_remove_sysfs(dd);
m4sensorhub_unregister_initcall(m4als_driver_init);
+#ifdef CONFIG_ALS_WHILE_CHARGING
+ wakeup_source_unregister_notify(&dd->charger_nb);
+#endif
if (dd->indev != NULL)
input_unregister_device(dd->indev);
mutex_destroy(&(dd->mutex));
diff --git a/include/linux/als_notify.h b/include/linux/als_notify.h
new file mode 100644
index 00000000000..6cde49e2fe4
--- /dev/null
+++ b/include/linux/als_notify.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2014 Motorola Mobility LLC.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ALS_NOTIFY_H
+#define ALS_NOTIFY_H
+
+#ifdef __KERNEL__
+
+extern void als_register_notify(struct notifier_block *nb);
+extern void als_unregister_notify(struct notifier_block *nb);
+extern void als_notify_subscriber(unsigned long event);
+#endif /* __KERNEL__ */
+
+#endif /* ALS_NOTIFY_H */