diff options
| author | Wengang Wu <wgw@motorola.com> | 2014-07-23 19:01:06 -0500 |
|---|---|---|
| committer | Wengang Wu <wgw@motorola.com> | 2014-07-23 19:01:06 -0500 |
| commit | 3ec0e610cc23c072b90c1bde3ff7bc767f6bac8d (patch) | |
| tree | 5e1da063acd7183666d466bec665467a142b61c6 | |
| parent | 2394a8ad9dd527633e7220de4cbf307cc5fcc3f2 (diff) | |
| download | olio-linux-3.10-3ec0e610cc23c072b90c1bde3ff7bc767f6bac8d.tar.xz olio-linux-3.10-3ec0e610cc23c072b90c1bde3ff7bc767f6bac8d.zip | |
IKXCLOCK-3122 Smart Ambient: support ambient off gesture
Change-Id: I22622983c50f1d564f40314f92e49646279826f5
| -rw-r--r-- | arch/arm/boot/dts/omap3-minnow.dtsi | 3 | ||||
| -rw-r--r-- | drivers/misc/c55_ctrl.c | 12 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_gesture.c | 27 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_pedometer.c | 9 | ||||
| -rw-r--r-- | drivers/video/omap2/displays/panel-minnow.c | 161 | ||||
| -rw-r--r-- | include/linux/wakeup_source_notify.h | 14 |
6 files changed, 142 insertions, 84 deletions
diff --git a/arch/arm/boot/dts/omap3-minnow.dtsi b/arch/arm/boot/dts/omap3-minnow.dtsi index 753ae8c7391..b2d6a60f538 100644 --- a/arch/arm/boot/dts/omap3-minnow.dtsi +++ b/arch/arm/boot/dts/omap3-minnow.dtsi @@ -82,7 +82,8 @@ //gpio_te = <&gpio1 0 0>; /* EXT_TE gpio-0 */ //pins = <0 1 2 3>; /* DSI Pin config */ esd_interval = <8000>; /* ESD_INTERVAL */ - ambient_timeout = <5>; /* timeout in second */ + support_smart_ambient; + ambient_timeout = <0>; /* time out in second */ //pixel_clock = <4608>; /* kHZ = 320*240*60/1000*/ /* 0: RGB888 * 1: RGB666 diff --git a/drivers/misc/c55_ctrl.c b/drivers/misc/c55_ctrl.c index 49f84e6bcb6..54ffc6e5b2b 100644 --- a/drivers/misc/c55_ctrl.c +++ b/drivers/misc/c55_ctrl.c @@ -170,8 +170,8 @@ static ssize_t c55_ctrl_enable(struct device *dev, gpio_set_value(cdata->ap_c55_int_gpio, 1); if (m4sensorhub_reg_write_1byte - (m4sensorhub, M4SH_REG_USERSETTINGS_SCREENSTATUS, - INTERACTIVE_ON, SCREEN_STATUS_INTERACTIVE_MASK) != 1) { + (m4sensorhub, M4SH_REG_USERSETTINGS_AUDIOSTATUS, + AUDIO_STATUS_ON, 0xFF) != 1) { dev_err(dev, "Unable to set screen status to 0x01\n"); mutex_unlock(&cdata->ctrl_mutex); return -EINVAL; @@ -190,8 +190,8 @@ static ssize_t c55_ctrl_enable(struct device *dev, } if (m4sensorhub_reg_write_1byte - (m4sensorhub, M4SH_REG_USERSETTINGS_SCREENSTATUS, - INTERACTIVE_OFF, SCREEN_STATUS_INTERACTIVE_MASK) != 1) { + (m4sensorhub, M4SH_REG_USERSETTINGS_AUDIOSTATUS, + AUDIO_STATUS_OFF, 0xFF) != 1) { dev_err(dev, "Unable to set screen status to 0x00\n"); mutex_unlock(&cdata->ctrl_mutex); return -EINVAL; @@ -376,8 +376,8 @@ static int c55_ctrl_suspend(struct platform_device *dev, pm_message_t state) } if (m4sensorhub_reg_write_1byte - (m4sensorhub, M4SH_REG_USERSETTINGS_SCREENSTATUS, - INTERACTIVE_OFF, SCREEN_STATUS_INTERACTIVE_MASK) != 1) { + (m4sensorhub, M4SH_REG_USERSETTINGS_AUDIOSTATUS, + AUDIO_STATUS_OFF, 0xFF) != 1) { dev_err(&dev->dev, "Unable to set screen status to 0x00\n"); } diff --git a/drivers/misc/m4sensorhub_gesture.c b/drivers/misc/m4sensorhub_gesture.c index 6ef8daacebc..d5e364ea6c5 100644 --- a/drivers/misc/m4sensorhub_gesture.c +++ b/drivers/misc/m4sensorhub_gesture.c @@ -76,18 +76,6 @@ static void m4ges_isr(enum m4sensorhub_irqs int_event, void *handle) goto m4ges_isr_fail; } -#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY - if (dd->iiodat.gesture_type == GESTURE_WRIST_ROTATE) { - notify_display_wakeup(GESTURE); - } else if (dd->iiodat.gesture_type == GESTURE_VIEW) { - notify_display_wakeup(GESTURE_VIEW); - /* the GESTURE_VIEW is only effect for kernel now - * do not send gesture to android - */ - goto m4ges_isr_fail; - } -#endif /* CONFIG_WAKEUP_SOURCE_NOTIFY */ - size = m4sensorhub_reg_getsize(dd->m4, M4SH_REG_GESTURE_CONFIDENCE1); err = m4sensorhub_reg_read(dd->m4, M4SH_REG_GESTURE_CONFIDENCE1, (char *)&(dd->iiodat.gesture_confidence)); @@ -115,6 +103,21 @@ static void m4ges_isr(enum m4sensorhub_irqs int_event, void *handle) goto m4ges_isr_fail; } +#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY + if (dd->iiodat.gesture_type == GESTURE_WRIST_ROTATE) { + notify_display_wakeup(GESTURE); + } else if (dd->iiodat.gesture_type == GESTURE_VIEW) { + if (dd->iiodat.gesture_value == GESTURE_VIEW_ON) + notify_display_wakeup(GESTURE_VIEWON); + else + notify_display_wakeup(GESTURE_VIEWOFF); + /* the GESTURE_VIEW is only effect for kernel now + * do not send gesture to android + */ + goto m4ges_isr_fail; + } +#endif /* CONFIG_WAKEUP_SOURCE_NOTIFY */ + dd->iiodat.timestamp = iio_get_time_ns(); iio_push_to_buffers(iio, (unsigned char *)&(dd->iiodat)); dd->gesture_count++; diff --git a/drivers/misc/m4sensorhub_pedometer.c b/drivers/misc/m4sensorhub_pedometer.c index 699ba9fb571..ff3a0c1e913 100644 --- a/drivers/misc/m4sensorhub_pedometer.c +++ b/drivers/misc/m4sensorhub_pedometer.c @@ -339,7 +339,7 @@ static ssize_t m4ped_userdata_show(struct device *dev, mutex_lock(&(dd->mutex)); - err = m4sensorhub_reg_read_n(dd->m4, M4SH_REG_USERSETTINGS_VERSION, + err = m4sensorhub_reg_read_n(dd->m4, M4SH_REG_USERSETTINGS_SCREENSTATUS, (char *)&(data[0]), ARRAY_SIZE(data)); if (err < 0) { m4ped_err("%s: Failed to read user data.\n", __func__); @@ -351,13 +351,6 @@ static ssize_t m4ped_userdata_show(struct device *dev, goto m4ped_userdata_show_fail; } - if (data[0] > 0) { - m4ped_err("%s: User settings version is too new (0x%02X)\n", - __func__, data[0]); - err = -EINVAL; - goto m4ped_userdata_show_fail; - } - size = snprintf(buf, PAGE_SIZE, "%s%s\n%s%hhu\n%s%hhu\n%s%hhu\n", "Gender (M/F): ", data[2] ? "M" : "F", diff --git a/drivers/video/omap2/displays/panel-minnow.c b/drivers/video/omap2/displays/panel-minnow.c index a103d3c7981..52d761bcdb4 100644 --- a/drivers/video/omap2/displays/panel-minnow.c +++ b/drivers/video/omap2/displays/panel-minnow.c @@ -257,11 +257,11 @@ static struct minnow_panel_attr panel_attr_table[MINNOW_PANEL_MAX] = { #endif enum display_state { - DISPLAY_DISABLE, - DISPLAY_ENABLE, + DISPLAY_DISABLE = SCREEN_STATUS_NORMAL_OFF, + DISPLAY_ENABLE = SCREEN_STATUS_NORMAL_ON, #ifdef CONFIG_HAS_AMBIENTMODE - DISPLAY_AMBIENT_OFF, - DISPLAY_AMBIENT_ON, + DISPLAY_AMBIENT_OFF = SCREEN_STATUS_AMBIENT_OFF, + DISPLAY_AMBIENT_ON = SCREEN_STATUS_AMBIENT_ON, #endif }; @@ -303,6 +303,7 @@ struct minnow_panel_data { /* runtime variables */ enum display_state state; + enum display_state m4_state; bool enabled; bool interactive; bool output_enabled; @@ -365,9 +366,11 @@ struct minnow_panel_data { struct work_struct dock_work; struct work_struct ambient_wake_work; struct alarm ambient_timeout_alarm; + bool smart_ambient; int ambient_timeout; /* time out in seconds */ struct work_struct ambient_timeout_work; - int is_docked; + bool is_docked; + bool is_gesture_view_on; #endif }; @@ -414,12 +417,35 @@ static void minnow_panel_sync_resume_mlocked(struct minnow_panel_data *mpd) #endif } +#ifdef CONFIG_HAS_AMBIENTMODE +/* the smart ambient feature enabled when + * 1) support_smart_ambient + * 2) and it's not on dock + */ +#define is_smart_ambient_feature_enabled(mpd) \ + (mpd->smart_ambient && !mpd->is_docked) + +/* the smart ambient timeout enabled when + * 1) support_smart_ambient + * 2) and defined ambient timeout + * 3) and it's not on dock + */ +#define is_smart_ambient_timeout_enabled(mpd) \ + (mpd->smart_ambient && mpd->ambient_timeout && !mpd->is_docked) +#endif + #ifdef CONFIG_WAKEUP_SOURCE_NOTIFY static int omapdss_displayenable_notify(struct notifier_block *self, unsigned long action, void *dev) { DECLARE_MPD_FROM_CONTAINER(self, displayenable_nb); + + /* don't case non-display wakeup event */ + if (GET_WAKEUP_EVENT_TYPE(action) != WAKEUP_DISPLAY) + return NOTIFY_OK; + dev_info(&mpd->dssdev->dev, "%s, action is %lu", __func__, action); + switch (action) { case DISPLAY_WAKE_EVENT_POWERKEY: case DISPLAY_WAKE_EVENT_TOUCH: @@ -427,12 +453,16 @@ static int omapdss_displayenable_notify(struct notifier_block *self, /* Queue work to early enable the display */ queue_work(mpd->workqueue, &mpd->early_init_work); break; + case DISPLAY_WAKE_EVENT_GESTURE_VIEWON: + case DISPLAY_WAKE_EVENT_GESTURE_VIEWOFF: #ifdef CONFIG_HAS_AMBIENTMODE - case DISPLAY_WAKE_EVENT_GESTURE_VIEW: - /* Queue work to enable the ambient display mode */ - queue_work(mpd->workqueue, &mpd->ambient_wake_work); - break; + mpd->is_gesture_view_on = + action == DISPLAY_WAKE_EVENT_GESTURE_VIEWON; + /* Queue work to enable the smart ambient display mode */ + if (is_smart_ambient_feature_enabled(mpd)) + queue_work(mpd->workqueue, &mpd->ambient_wake_work); #endif + break; case DISPLAY_WAKE_EVENT_DOCKON: case DISPLAY_WAKE_EVENT_DOCKOFF: #ifdef CONFIG_HAS_AMBIENTMODE @@ -446,6 +476,7 @@ static int omapdss_displayenable_notify(struct notifier_block *self, "%s: ignore unknown action(%lu)!\n", __func__, action); break; } + return NOTIFY_OK; } @@ -502,7 +533,7 @@ static void minnow_panel_dock_func(struct work_struct *work) /* to handler DOCK event is for blocking the smart ambient * timeout when it's on dock, so the only thing is needed * just update state to DISPLAY_AMBIENT_ON as: - * 1) when ambient timout (DISPLAY_AMBIENT_OFF), put device + * 1) when ambient timeout (DISPLAY_AMBIENT_OFF), put device * dock, need wake up it to ambient mode and never timeout * 2) when it's on ambient mode, leave device from dock, set * DISPLAY_AMBIENT_ON that will restart ambient timeout @@ -525,7 +556,10 @@ static void minnow_panel_ambient_wake_func(struct work_struct *work) { DECLARE_MPD_FROM_CONTAINER(work, ambient_wake_work); mutex_lock(&mpd->lock); - minnow_panel_change_state_mlocked(mpd, DISPLAY_AMBIENT_ON); + minnow_panel_change_state_mlocked(mpd, + mpd->is_gesture_view_on + ? DISPLAY_AMBIENT_ON + : DISPLAY_AMBIENT_OFF); mutex_unlock(&mpd->lock); } @@ -548,12 +582,6 @@ static void minnow_panel_ambient_timeout_func(struct work_struct *work) mutex_unlock(&mpd->lock); } -/* the smart ambient timeout enabled when - * 1) defined ambient timeout - * 2) and it's not on dock - */ -#define is_smart_ambient_timeout_enabled(mpd) \ - (mpd->ambient_timeout && !mpd->is_docked) static void minnow_panel_start_ambient_alarm(struct minnow_panel_data *mpd) { alarm_cancel(&mpd->ambient_timeout_alarm); @@ -1735,7 +1763,7 @@ static ssize_t minnow_panel_show_init_data(struct device *dev, i += snprintf(buf+i, PAGE_SIZE-i, "%02d %02d:", data[0], data[1]); for (j = 0; j < *data && i < PAGE_SIZE; j++) { - i + snprintf(buf+i, PAGE_SIZE-i, " %02X", data[2+j]); + i += snprintf(buf+i, PAGE_SIZE-i, " %02X", data[2+j]); } snprintf(buf+i, PAGE_SIZE-i, "\n"); i++; @@ -1781,8 +1809,12 @@ static ssize_t minnow_panel_store_interactivemode(struct device *dev, } #endif if (mpd->interactive != enable) { - r = enable ? DISPLAY_ENABLE : DISPLAY_AMBIENT_OFF; - r = minnow_panel_change_state_mlocked(mpd, r); + int state = mpd->state; + if (enable) + state = DISPLAY_ENABLE; + else if (state != DISPLAY_DISABLE) + state = DISPLAY_AMBIENT_ON; + r = minnow_panel_change_state_mlocked(mpd, state); if (!r) mpd->interactive = enable; } @@ -2197,7 +2229,10 @@ static int minnow_panel_dt_init(struct minnow_panel_data *mpd) mpd->esd_interval = value; DTINFO("esd_interval = %d\n", mpd->esd_interval); } -#ifdef CONFIG_HAS_AMBIENTMODE +#ifdef CONFIG_HAS_AMBIENTMODE + mpd->smart_ambient = + of_property_read_bool(dt_node, "support_smart_ambient"); + DTINFO("support_smart_ambient = %d\n", mpd->smart_ambient); mpd->ambient_timeout = 0; if (!of_property_read_u32(dt_node, "ambient_timeout", &value)) { mpd->ambient_timeout = value; @@ -2333,6 +2368,7 @@ static int minnow_panel_probe(struct omap_dss_device *dssdev) dev_set_drvdata(&dssdev->dev, mpd); mpd->dssdev = dssdev; mpd->first_enable = true; + mpd->m4_state = DISPLAY_ENABLE; r = minnow_panel_dt_init(mpd); if (r) @@ -2611,7 +2647,7 @@ static void __exit minnow_panel_remove(struct omap_dss_device *dssdev) wakeup_source_unregister_notify(&mpd->displayenable_nb); cancel_work_sync(&mpd->early_init_work); #endif /* CONFIG_WAKEUP_SOURCE_NOTIFY */ -#ifdef CONFIG_HAS_AMBIENTMODE +#ifdef CONFIG_HAS_AMBIENTMODE alarm_cancel(&mpd->ambient_timeout_alarm); #endif minnow_panel_cancel_ulps_work(mpd); @@ -2946,31 +2982,37 @@ static void minnow_panel_disable_mlocked(struct minnow_panel_data *mpd) static void minnow_panel_sync_display_status_mlocked( struct minnow_panel_data *mpd) { - static int last_display_on = -1; - int display_on = (mpd->state == DISPLAY_DISABLE) - ? DISPLAY_OFF : DISPLAY_ON; struct m4sensorhub_data *m4sensorhub; - - if (display_on == last_display_on) + enum display_state m4_state = mpd->state; + /* special case for dock mode, set to DISPLAY_ENABLE + * to block all wakeup gestures + */ + if (mpd->is_docked) + m4_state = DISPLAY_ENABLE; + if (mpd->m4_state == m4_state) return; + + /* be safety to sync resume states first */ + minnow_panel_sync_resume_mlocked(mpd); + m4sensorhub = m4sensorhub_client_get_drvdata(); if (m4sensorhub->mode != NORMALMODE) { dev_err(&mpd->dssdev->dev, - "M4 is not ready, unable to set screen status\n"); + "M4 is not ready, unable to set screen status(%d)\n", + m4_state); return; } if (m4sensorhub_reg_write_1byte(m4sensorhub, M4SH_REG_USERSETTINGS_SCREENSTATUS, - display_on, - SCREEN_STATUS_DISPLAY_MASK) != 1) { + m4_state, 0xFF) != 1) { dev_err(&mpd->dssdev->dev, "Unable to set screen status(%d) to M4\n", - display_on); + m4_state); return; } dev_dbg(&mpd->dssdev->dev, - "Set screen status(%d) to M4 success!\n", display_on); - last_display_on = display_on; + "Set screen status(%d) to M4 success!\n", m4_state); + mpd->m4_state = m4_state; } static int minnow_panel_change_state_mlocked(struct minnow_panel_data *mpd, @@ -2989,12 +3031,15 @@ static int minnow_panel_change_state_mlocked(struct minnow_panel_data *mpd, minnow_panel_start_ambient_alarm(mpd); } #endif - return r; + goto _ret_; } #ifdef CONFIG_HAS_AMBIENTMODE alarm_cancel(&mpd->ambient_timeout_alarm); #endif + /* be safety to sync resume states first */ + minnow_panel_sync_resume_mlocked(mpd); + switch (state) { case DISPLAY_DISABLE: if (mpd->enabled) @@ -3006,46 +3051,54 @@ static int minnow_panel_change_state_mlocked(struct minnow_panel_data *mpd, break; #ifdef CONFIG_HAS_AMBIENTMODE case DISPLAY_AMBIENT_OFF: - /* it can't go to smart ambient mode when display disabled */ - if (mpd->state == DISPLAY_DISABLE) { - r = -EINVAL; - break; - } - if (is_smart_ambient_timeout_enabled(mpd)) { - minnow_panel_disable_mlocked(mpd); + /* it can't go to ambient mode when display already disabled. + * this is normal case that turn off display first, then set + * interactive off later, do nothing just return success + */ + if (mpd->state == DISPLAY_DISABLE) + goto _ret_; + if (is_smart_ambient_feature_enabled(mpd)) { /* Turn off the back light */ - /* LED function below dependent on panel_disable_mlocked - * above to guarantee i2c bus is ready */ led_set_brightness(led_get_default_dev(), 0); + minnow_panel_disable_mlocked(mpd); } break; case DISPLAY_AMBIENT_ON: - /* it can only turn on ambient mode it's off before */ - if (mpd->state == DISPLAY_AMBIENT_OFF) { - /* check if smart ambient mode feature enabled */ - if (!mpd->ambient_timeout) - break; + /* it can't go to ambient mode when display already disabled. + * this is normal case that turn off display first, then set + * interactive off later, do nothing just return success + */ + if (mpd->state == DISPLAY_DISABLE) + goto _ret_; + /* check if smart ambient mode feature enabled */ + if (!is_smart_ambient_feature_enabled(mpd)) + break; + if (mpd->state == DISPLAY_ENABLE) { + /* first time to turn on ambient mode, + * start time out only + */ + minnow_panel_start_ambient_alarm(mpd); + } else { + /* turn on display when it's off before */ r = minnow_panel_enable_mlocked(mpd); if (!r) { /* Dim the back light */ led_set_brightness(led_get_default_dev(), 5); minnow_panel_start_ambient_alarm(mpd); } - } else { - r = -EINVAL; } break; #endif /* CONFIG_HAS_AMBIENTMODE */ default: r = -EINVAL; } - if (!r) { + if (!r) mpd->state = state; - minnow_panel_sync_display_status_mlocked(mpd); - } else { + else dev_err(&mpd->dssdev->dev, "failed(%d) set state(%d)," " current state(%d)\n", r, state, mpd->state); - } +_ret_: + minnow_panel_sync_display_status_mlocked(mpd); return r; } diff --git a/include/linux/wakeup_source_notify.h b/include/linux/wakeup_source_notify.h index 070a8bcab46..98db849d13d 100644 --- a/include/linux/wakeup_source_notify.h +++ b/include/linux/wakeup_source_notify.h @@ -19,14 +19,22 @@ #ifdef __KERNEL__ +enum wakeup_request_type { + WAKEUP_DISPLAY, +}; +#define WAKEUP_EVENT_START(type) ((type) << 8) +#define GET_WAKEUP_EVENT_TYPE(event) ((event) >> 8) + enum display_wakeup_request { - DISPLAY_WAKE_EVENT_POWERKEY, + DISPLAY_WAKE_EVENT_BEGIN = WAKEUP_EVENT_START(WAKEUP_DISPLAY), + DISPLAY_WAKE_EVENT_POWERKEY = DISPLAY_WAKE_EVENT_BEGIN, DISPLAY_WAKE_EVENT_TOUCH, DISPLAY_WAKE_EVENT_GESTURE, - DISPLAY_WAKE_EVENT_GESTURE_VIEW, + DISPLAY_WAKE_EVENT_GESTURE_VIEWON, + DISPLAY_WAKE_EVENT_GESTURE_VIEWOFF, DISPLAY_WAKE_EVENT_DOCKON, DISPLAY_WAKE_EVENT_DOCKOFF, - DISPLAY_WAKE_EVENT_MAX + DISPLAY_WAKE_EVENT_END }; #define notify_display_wakeup(reason) \ |