Message ID | 77BC725C9062764F874D79F51E1F1A8F40C14099@S04-MBX01-01.s04.local (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Dudley, On Wed, Apr 16, 2014 at 08:39:34AM +0000, Dudley Du wrote: > Rely on EV_SW and SW_LID bits to identify a LID device, and hook > up our filter to listen for SW_LID events to enable/disable touchpad when > LID is open/closed. > TEST=test on Chomebooks. This is a policy and it does not belong in the kernel. Please work with Rafael to establish generic interface to put devices into low power mode (like accelerating runtime PM idle timeout) and use it when userspace detects that lid is closed. Thanks. > > Signed-off-by: Du, Dudley <dudl@cypress.com> > --- > diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c > index 6820b3f..da03427 100644 > --- a/drivers/input/mouse/cyapa.c > +++ b/drivers/input/mouse/cyapa.c > @@ -523,6 +523,9 @@ struct cyapa { > int physical_size_x; > int physical_size_y; > > + bool lid_handler_registered; > + struct input_handler lid_handler; > + > /* used in ttsp and truetouch based trackpad devices. */ > u8 x_origin; /* X Axis Origin: 0 = left side; 1 = rigth side. */ > u8 y_origin; /* Y Axis Origin: 0 = top; 1 = bottom. */ > @@ -3107,6 +3110,125 @@ static void cyapa_start_runtime(struct cyapa *cyapa) > static void cyapa_start_runtime(struct cyapa *cyapa) {} > #endif /* CONFIG_PM_RUNTIME */ > > + > +/* > + * We rely on EV_SW and SW_LID bits to identify a LID device, and hook > + * up our filter to listen for SW_LID events to enable/disable touchpad when > + * LID is open/closed. > + */ > +static const struct input_device_id lid_device_ids[] = { > + { > + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | > + INPUT_DEVICE_ID_MATCH_SWBIT, > + .evbit = { BIT_MASK(EV_SW) }, > + .swbit = { BIT_MASK(SW_LID) }, > + }, > + { }, > +}; > + > +static int lid_device_connect(struct input_handler *handler, > + struct input_dev *dev, > + const struct input_device_id *id) > +{ > + struct input_handle *lid_handle; > + int error; > + > + lid_handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); > + if (!lid_handle) > + return -ENOMEM; > + > + lid_handle->dev = dev; > + lid_handle->handler = handler; > + lid_handle->name = "lid_event_handler"; > + lid_handle->private = handler->private; > + > + error = input_register_handle(lid_handle); > + if (error) > + goto err_free; > + > + error = input_open_device(lid_handle); > + if (error) > + goto err_unregister; > + > + return 0; > +err_unregister: > + input_unregister_handle(lid_handle); > +err_free: > + kfree(lid_handle); > + return error; > +} > + > +static void lid_device_disconnect(struct input_handle *handle) > +{ > + input_close_device(handle); > + input_unregister_handle(handle); > + kfree(handle); > +} > + > +static bool lid_event_filter(struct input_handle *handle, > + unsigned int type, unsigned int code, int value) > +{ > + struct cyapa *cyapa = handle->private; > + struct device *dev = &cyapa->client->dev; > + > + if (type == EV_SW && code == SW_LID) { > + if (cyapa->suspended) { > + /* > + * If the lid event filter is called while suspended, > + * there is no guarantee that the underlying i2cs are > + * resumed at this point, so it is not safe to issue > + * the command to change power modes. > + * Instead, rely on cyapa_resume to set us back to > + * PWR_MODE_FULL_ACTIVE. > + */ > + return false; > + } > + if (value == 0) { > + if (cyapa->cyapa_set_power_mode) > + cyapa->cyapa_set_power_mode(cyapa, > + PWR_MODE_FULL_ACTIVE, 0); > + pm_runtime_set_active(dev); > + pm_runtime_enable(dev); > + } else { > + pm_runtime_disable(dev); > + if (cyapa->cyapa_set_power_mode) > + cyapa->cyapa_set_power_mode(cyapa, > + PWR_MODE_OFF, 0); > + } > + } > + > + return false; > +} > + > +static void lid_event_register_handler(struct cyapa *cyapa) > +{ > + int error; > + struct input_handler *lid_handler = &cyapa->lid_handler; > + > + if (cyapa->lid_handler_registered) > + return; > + > + lid_handler->filter = lid_event_filter; > + lid_handler->connect = lid_device_connect; > + lid_handler->disconnect = lid_device_disconnect; > + lid_handler->name = "cyapa_lid_event_handler"; > + lid_handler->id_table = lid_device_ids; > + lid_handler->private = cyapa; > + > + error = input_register_handler(lid_handler); > + if (error) > + return; > + cyapa->lid_handler_registered = true; > +} > + > +static void lid_event_unregister_handler(struct cyapa *cyapa) > +{ > + if (cyapa->lid_handler_registered) { > + input_unregister_handler(&cyapa->lid_handler); > + cyapa->lid_handler_registered = false; > + } > +} > + > static void cyapa_detect_async(void *data, async_cookie_t cookie) > { > struct cyapa *cyapa = (struct cyapa *)data; > @@ -3126,6 +3248,7 @@ static void cyapa_detect_and_start(void *data, async_cookie_t cookie) > cyapa_detect_async(data, cookie); > > cyapa_start_runtime(cyapa); > + lid_event_register_handler(cyapa); > } > > static int cyapa_probe(struct i2c_client *client, > @@ -3221,7 +3344,7 @@ static int cyapa_remove(struct i2c_client *client) > > free_irq(cyapa->irq, cyapa); > input_unregister_device(cyapa->input); > - > + lid_event_unregister_handler(cyapa); > if (cyapa->cyapa_set_power_mode) > cyapa->cyapa_set_power_mode(cyapa, PWR_MODE_OFF, 0); > i2c_set_clientdata(client, NULL); > This message and any attachments may contain Cypress (or its subsidiaries) confidential information. If it has been received in error, please advise the sender and immediately delete this message.
Hi Rafael, Could you help give some advice on how to apply the function to put the trackpad device into low power mode with LID in current kernel? or it's just a policy and should not be submitted to kernel right now? Thanks, Dudley > > -----Original Message----- > From: Dmitry Torokhov [mailto:dmitry.torokhov@gmail.com] > Sent: Tuesday, May 20, 2014 11:43 AM > To: Dudley Du > Cc: Benson Leung; Daniel Kurtz; David Solda; linux-input@vger.kernel.org; linux-kernel@vger.kernel.org > Subject: Re: [PATCH 4/6] input: cyapa: enable/disable trackpad device based on LID state > > Hi Dudley, > > On Wed, Apr 16, 2014 at 08:39:34AM +0000, Dudley Du wrote: > > Rely on EV_SW and SW_LID bits to identify a LID device, and hook up > > our filter to listen for SW_LID events to enable/disable touchpad when > > LID is open/closed. > > TEST=test on Chomebooks. > > This is a policy and it does not belong in the kernel. Please work with Rafael to establish generic interface to put devices into low power mode (like accelerating runtime PM idle timeout) and use it when userspace detects that lid is closed. > > Thanks. > > > > > Signed-off-by: Du, Dudley <dudl@cypress.com> > > --- > > diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c > > index 6820b3f..da03427 100644 > > --- a/drivers/input/mouse/cyapa.c > > +++ b/drivers/input/mouse/cyapa.c > > @@ -523,6 +523,9 @@ struct cyapa { > > int physical_size_x; > > int physical_size_y; > > > > + bool lid_handler_registered; > > + struct input_handler lid_handler; > > + > > /* used in ttsp and truetouch based trackpad devices. */ > > u8 x_origin; /* X Axis Origin: 0 = left side; 1 = rigth side. */ > > u8 y_origin; /* Y Axis Origin: 0 = top; 1 = bottom. */ @@ > > -3107,6 +3110,125 @@ static void cyapa_start_runtime(struct cyapa > > *cyapa) static void cyapa_start_runtime(struct cyapa *cyapa) {} > > #endif /* CONFIG_PM_RUNTIME */ > > > > + > > +/* > > + * We rely on EV_SW and SW_LID bits to identify a LID device, and > > +hook > > + * up our filter to listen for SW_LID events to enable/disable > > +touchpad when > > + * LID is open/closed. > > + */ > > +static const struct input_device_id lid_device_ids[] = { > > + { > > + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | > > + INPUT_DEVICE_ID_MATCH_SWBIT, > > + .evbit = { BIT_MASK(EV_SW) }, > > + .swbit = { BIT_MASK(SW_LID) }, > > + }, > > + { }, > > +}; > > + > > +static int lid_device_connect(struct input_handler *handler, > > + struct input_dev *dev, > > + const struct input_device_id *id) { > > + struct input_handle *lid_handle; > > + int error; > > + > > + lid_handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); > > + if (!lid_handle) > > + return -ENOMEM; > > + > > + lid_handle->dev = dev; > > + lid_handle->handler = handler; > > + lid_handle->name = "lid_event_handler"; > > + lid_handle->private = handler->private; > > + > > + error = input_register_handle(lid_handle); > > + if (error) > > + goto err_free; > > + > > + error = input_open_device(lid_handle); > > + if (error) > > + goto err_unregister; > > + > > + return 0; > > +err_unregister: > > + input_unregister_handle(lid_handle); > > +err_free: > > + kfree(lid_handle); > > + return error; > > +} > > + > > +static void lid_device_disconnect(struct input_handle *handle) { > > + input_close_device(handle); > > + input_unregister_handle(handle); > > + kfree(handle); > > +} > > + > > +static bool lid_event_filter(struct input_handle *handle, > > + unsigned int type, unsigned int code, int > > +value) { > > + struct cyapa *cyapa = handle->private; > > + struct device *dev = &cyapa->client->dev; > > + > > + if (type == EV_SW && code == SW_LID) { > > + if (cyapa->suspended) { > > + /* > > + * If the lid event filter is called while suspended, > > + * there is no guarantee that the underlying i2cs are > > + * resumed at this point, so it is not safe to issue > > + * the command to change power modes. > > + * Instead, rely on cyapa_resume to set us back to > > + * PWR_MODE_FULL_ACTIVE. > > + */ > > + return false; > > + } > > + if (value == 0) { > > + if (cyapa->cyapa_set_power_mode) > > + cyapa->cyapa_set_power_mode(cyapa, > > + PWR_MODE_FULL_ACTIVE, 0); > > + pm_runtime_set_active(dev); > > + pm_runtime_enable(dev); > > + } else { > > + pm_runtime_disable(dev); > > + if (cyapa->cyapa_set_power_mode) > > + cyapa->cyapa_set_power_mode(cyapa, > > + PWR_MODE_OFF, 0); > > + } > > + } > > + > > + return false; > > +} > > + > > +static void lid_event_register_handler(struct cyapa *cyapa) { > > + int error; > > + struct input_handler *lid_handler = &cyapa->lid_handler; > > + > > + if (cyapa->lid_handler_registered) > > + return; > > + > > + lid_handler->filter = lid_event_filter; > > + lid_handler->connect = lid_device_connect; > > + lid_handler->disconnect = lid_device_disconnect; > > + lid_handler->name = "cyapa_lid_event_handler"; > > + lid_handler->id_table = lid_device_ids; > > + lid_handler->private = cyapa; > > + > > + error = input_register_handler(lid_handler); > > + if (error) > > + return; > > + cyapa->lid_handler_registered = true; } > > + > > +static void lid_event_unregister_handler(struct cyapa *cyapa) { > > + if (cyapa->lid_handler_registered) { > > + input_unregister_handler(&cyapa->lid_handler); > > + cyapa->lid_handler_registered = false; > > + } > > +} > > + > > static void cyapa_detect_async(void *data, async_cookie_t cookie) { > > struct cyapa *cyapa = (struct cyapa *)data; @@ -3126,6 +3248,7 > > @@ static void cyapa_detect_and_start(void *data, async_cookie_t cookie) > > cyapa_detect_async(data, cookie); > > > > cyapa_start_runtime(cyapa); > > + lid_event_register_handler(cyapa); > > } > > > > static int cyapa_probe(struct i2c_client *client, @@ -3221,7 +3344,7 > > @@ static int cyapa_remove(struct i2c_client *client) > > > > free_irq(cyapa->irq, cyapa); > > input_unregister_device(cyapa->input); > > - > > + lid_event_unregister_handler(cyapa); > > if (cyapa->cyapa_set_power_mode) > > cyapa->cyapa_set_power_mode(cyapa, PWR_MODE_OFF, 0); > > i2c_set_clientdata(client, NULL); This message and any > > attachments may contain Cypress (or its subsidiaries) confidential information. If it has been received in error, please advise the sender and immediately delete this message. > > -- > Dmitry This message and any attachments may contain Cypress (or its subsidiaries) confidential information. If it has been received in error, please advise the sender and immediately delete this message. -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Monday, May 19, 2014 08:43:02 PM Dmitry Torokhov wrote: > Hi Dudley, > > On Wed, Apr 16, 2014 at 08:39:34AM +0000, Dudley Du wrote: > > Rely on EV_SW and SW_LID bits to identify a LID device, and hook > > up our filter to listen for SW_LID events to enable/disable touchpad when > > LID is open/closed. > > TEST=test on Chomebooks. > > This is a policy and it does not belong in the kernel. Please work with > Rafael to establish generic interface to put devices into low power mode > (like accelerating runtime PM idle timeout) I'm not really sure what you mean here, care to be more specific? > and use it when userspace detects that lid is closed. I guess we get an event then, don't we? Rafael -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, May 20, 2014 at 02:40:12PM +0200, Rafael J. Wysocki wrote: > On Monday, May 19, 2014 08:43:02 PM Dmitry Torokhov wrote: > > Hi Dudley, > > > > On Wed, Apr 16, 2014 at 08:39:34AM +0000, Dudley Du wrote: > > > Rely on EV_SW and SW_LID bits to identify a LID device, and hook > > > up our filter to listen for SW_LID events to enable/disable touchpad when > > > LID is open/closed. > > > TEST=test on Chomebooks. > > > > This is a policy and it does not belong in the kernel. Please work with > > Rafael to establish generic interface to put devices into low power mode > > (like accelerating runtime PM idle timeout) > > I'm not really sure what you mean here, care to be more specific? I think we chatted about this before - we need a uniform interface for userspace to put devices into low power mode on demand. As implementation detail I thought we could require runtime PM for that and simply pretend that the PM timeout expired early when userspace invokes that API. > > > and use it when userspace detects that lid is closed. > > I guess we get an event then, don't we? Right, userspace gets EV_SW/SW_LID input event and needs to react. In this particular case the desire is to power down touchpad (since it is unaccessible). I am not sure why system suspend (which I expect happen in reaction to lid closing) is not enough, but that's question for Dudley. Thanks.
Hi Dmitry and Rafael, I can provide more insight here since I implemented an early version of this in the atmel and cyapa drivers that are used in the chromeos kernel. On Tue, May 20, 2014 at 8:25 AM, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote: > On Tue, May 20, 2014 at 02:40:12PM +0200, Rafael J. Wysocki wrote: >> On Monday, May 19, 2014 08:43:02 PM Dmitry Torokhov wrote: >> > Hi Dudley, >> > >> > On Wed, Apr 16, 2014 at 08:39:34AM +0000, Dudley Du wrote: >> > > Rely on EV_SW and SW_LID bits to identify a LID device, and hook >> > > up our filter to listen for SW_LID events to enable/disable touchpad when >> > > LID is open/closed. >> > > TEST=test on Chomebooks. >> > >> > This is a policy and it does not belong in the kernel. Please work with >> > Rafael to establish generic interface to put devices into low power mode >> > (like accelerating runtime PM idle timeout) >> >> I'm not really sure what you mean here, care to be more specific? > > I think we chatted about this before - we need a uniform interface for > userspace to put devices into low power mode on demand. As > implementation detail I thought we could require runtime PM for that and > simply pretend that the PM timeout expired early when userspace invokes > that API. > >> >> > and use it when userspace detects that lid is closed. >> >> I guess we get an event then, don't we? > > Right, userspace gets EV_SW/SW_LID input event and needs to react. In > this particular case the desire is to power down touchpad (since it is > unaccessible). I am not sure why system suspend (which I expect happen > in reaction to lid closing) is not enough, but that's question for > Dudley. Waiting for system suspend isn't sufficient here because system suspend takes some time to trigger from user space, and in that time, the B panel of the laptop may couple with the active trackpad, or the C panel with the active touchscreen. This may generate stray input events, which may in turn cancel the suspend if the drivers use pm_wakeup_event(), and those input events may trigger something unwanted in the UI (think, accidentally one-click buy something on Amazon, etc). I came up with a requirement: When the lid is closed, as soon as possible, the devices must be off. That's part of the reason why Dudley's patch does it in the kernel rather than doing the round trip to user space. Furthermore, the policy on lid close is not always to enter suspend. We have something called Docked Mode, which allows the system to not suspend while the lid is closed if there's an external monitor attached. In this case, the touch devices must be disabled as well as again they risk generating stray events with the lid closed. I'd prefer if there was some way to establish a relationship between the lid and devices that must be power managed differently depending on the state of the lid, rather than leaving it to user space to manage the power management of these devices in real time and open up the possibility of race conditions there if user space is too slow. Thanks!
On Tuesday, May 20, 2014 08:25:51 AM Dmitry Torokhov wrote: > On Tue, May 20, 2014 at 02:40:12PM +0200, Rafael J. Wysocki wrote: > > On Monday, May 19, 2014 08:43:02 PM Dmitry Torokhov wrote: > > > Hi Dudley, > > > > > > On Wed, Apr 16, 2014 at 08:39:34AM +0000, Dudley Du wrote: > > > > Rely on EV_SW and SW_LID bits to identify a LID device, and hook > > > > up our filter to listen for SW_LID events to enable/disable touchpad when > > > > LID is open/closed. > > > > TEST=test on Chomebooks. > > > > > > This is a policy and it does not belong in the kernel. Please work with > > > Rafael to establish generic interface to put devices into low power mode > > > (like accelerating runtime PM idle timeout) > > > > I'm not really sure what you mean here, care to be more specific? > > I think we chatted about this before - we need a uniform interface for > userspace to put devices into low power mode on demand. I'm still not sure what you mean exactly. If you mean an interface for user space to *force* transitions into low-power states, we can't have it, because user space doesn't know when it is safe to do that. The /sys/devices/.../power/control interface is the best we can give to user space to this end. Adding Alan Stern to the recipient list, because he was inovlved in discussions about that. But if you mean an interface for user space to poke at pm_runtime_idle() to possibly trigger a runtime suspend, that we can add I think. Alan? > As implementation detail I thought we could require runtime PM for that and > simply pretend that the PM timeout expired early when userspace invokes > that API. That'd be overly complicated IMHO. Calling pm_runtime_idle() should suffice. > > > > > and use it when userspace detects that lid is closed. > > > > I guess we get an event then, don't we? > > Right, userspace gets EV_SW/SW_LID input event and needs to react. In > this particular case the desire is to power down touchpad (since it is > unaccessible). I am not sure why system suspend (which I expect happen > in reaction to lid closing) is not enough, but that's question for > Dudley. OK Rafael -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index 6820b3f..da03427 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c @@ -523,6 +523,9 @@ struct cyapa { int physical_size_x; int physical_size_y; + bool lid_handler_registered; + struct input_handler lid_handler; + /* used in ttsp and truetouch based trackpad devices. */ u8 x_origin; /* X Axis Origin: 0 = left side; 1 = rigth side. */ u8 y_origin; /* Y Axis Origin: 0 = top; 1 = bottom. */ @@ -3107,6 +3110,125 @@ static void cyapa_start_runtime(struct cyapa *cyapa) static void cyapa_start_runtime(struct cyapa *cyapa) {} #endif /* CONFIG_PM_RUNTIME */ + +/* + * We rely on EV_SW and SW_LID bits to identify a LID device, and hook + * up our filter to listen for SW_LID events to enable/disable touchpad when + * LID is open/closed. + */ +static const struct input_device_id lid_device_ids[] = { + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | + INPUT_DEVICE_ID_MATCH_SWBIT, + .evbit = { BIT_MASK(EV_SW) }, + .swbit = { BIT_MASK(SW_LID) }, + }, + { }, +}; + +static int lid_device_connect(struct input_handler *handler, + struct input_dev *dev, + const struct input_device_id *id) +{ + struct input_handle *lid_handle; + int error; + + lid_handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); + if (!lid_handle) + return -ENOMEM; + + lid_handle->dev = dev; + lid_handle->handler = handler; + lid_handle->name = "lid_event_handler"; + lid_handle->private = handler->private; + + error = input_register_handle(lid_handle); + if (error) + goto err_free; + + error = input_open_device(lid_handle); + if (error) + goto err_unregister; + + return 0; +err_unregister: + input_unregister_handle(lid_handle); +err_free: + kfree(lid_handle); + return error; +} + +static void lid_device_disconnect(struct input_handle *handle) +{ + input_close_device(handle); + input_unregister_handle(handle); + kfree(handle); +} + +static bool lid_event_filter(struct input_handle *handle, + unsigned int type, unsigned int code, int value) +{ + struct cyapa *cyapa = handle->private; + struct device *dev = &cyapa->client->dev; + + if (type == EV_SW && code == SW_LID) { + if (cyapa->suspended) { + /* + * If the lid event filter is called while suspended, + * there is no guarantee that the underlying i2cs are + * resumed at this point, so it is not safe to issue + * the command to change power modes. + * Instead, rely on cyapa_resume to set us back to + * PWR_MODE_FULL_ACTIVE. + */ + return false; + } + if (value == 0) { + if (cyapa->cyapa_set_power_mode) + cyapa->cyapa_set_power_mode(cyapa, + PWR_MODE_FULL_ACTIVE, 0); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + } else { + pm_runtime_disable(dev); + if (cyapa->cyapa_set_power_mode) + cyapa->cyapa_set_power_mode(cyapa, + PWR_MODE_OFF, 0); + } + } + + return false; +} + +static void lid_event_register_handler(struct cyapa *cyapa) +{ + int error; + struct input_handler *lid_handler = &cyapa->lid_handler; + + if (cyapa->lid_handler_registered) + return; + + lid_handler->filter = lid_event_filter; + lid_handler->connect = lid_device_connect; + lid_handler->disconnect = lid_device_disconnect; + lid_handler->name = "cyapa_lid_event_handler"; + lid_handler->id_table = lid_device_ids; + lid_handler->private = cyapa; + + error = input_register_handler(lid_handler); + if (error) + return; + cyapa->lid_handler_registered = true; +} + +static void lid_event_unregister_handler(struct cyapa *cyapa) +{ + if (cyapa->lid_handler_registered) { + input_unregister_handler(&cyapa->lid_handler); + cyapa->lid_handler_registered = false; + } +} + static void cyapa_detect_async(void *data, async_cookie_t cookie) { struct cyapa *cyapa = (struct cyapa *)data; @@ -3126,6 +3248,7 @@ static void cyapa_detect_and_start(void *data, async_cookie_t cookie) cyapa_detect_async(data, cookie); cyapa_start_runtime(cyapa); + lid_event_register_handler(cyapa); } static int cyapa_probe(struct i2c_client *client, @@ -3221,7 +3344,7 @@ static int cyapa_remove(struct i2c_client *client) free_irq(cyapa->irq, cyapa); input_unregister_device(cyapa->input); - + lid_event_unregister_handler(cyapa); if (cyapa->cyapa_set_power_mode) cyapa->cyapa_set_power_mode(cyapa, PWR_MODE_OFF, 0); i2c_set_clientdata(client, NULL);
Rely on EV_SW and SW_LID bits to identify a LID device, and hook up our filter to listen for SW_LID events to enable/disable touchpad when LID is open/closed. TEST=test on Chomebooks. Signed-off-by: Du, Dudley <dudl@cypress.com> --- This message and any attachments may contain Cypress (or its subsidiaries) confidential information. If it has been received in error, please advise the sender and immediately delete this message.