* [PATCH 1/2] mfd: cros-ec: Update cros_ec_commands.h for buttons and switches @ 2017-01-20 10:14 Enric Balletbo i Serra 2017-01-20 10:14 ` [PATCH 2/2] input: cros_ec_keyb: Add non-matrix " Enric Balletbo i Serra 2017-01-23 12:13 ` [PATCH 1/2] mfd: cros-ec: Update cros_ec_commands.h for " Lee Jones 0 siblings, 2 replies; 5+ messages in thread From: Enric Balletbo i Serra @ 2017-01-20 10:14 UTC (permalink / raw) To: Lee Jones, Dmitry Torokhov; +Cc: linux-kernel, linux-input, Douglas Anderson From: Douglas Anderson <dianders@chromium.org> Add the defines for the new buttons and switches connected to the CrosEC. Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> --- include/linux/mfd/cros_ec_commands.h | 73 +++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h index 23619b2..a01dde4 100644 --- a/include/linux/mfd/cros_ec_commands.h +++ b/include/linux/mfd/cros_ec_commands.h @@ -1865,18 +1865,69 @@ struct ec_response_tmp006_get_raw { * * Returns raw data for keyboard cols; see ec_response_mkbp_info.cols for * expected response size. + * + * NOTE: This has been superseded by EC_CMD_MKBP_GET_NEXT_EVENT. If you wish + * to obtain the instantaneous state, use EC_CMD_MKBP_INFO with the type + * EC_MKBP_INFO_CURRENT and event EC_MKBP_EVENT_KEY_MATRIX. */ #define EC_CMD_MKBP_STATE 0x60 -/* Provide information about the matrix : number of rows and columns */ +/* + * Provide information about various MKBP things. See enum ec_mkbp_info_type. + */ #define EC_CMD_MKBP_INFO 0x61 struct ec_response_mkbp_info { uint32_t rows; uint32_t cols; - uint8_t switches; + /* Formerly "switches", which was 0. */ + uint8_t reserved; } __packed; +struct ec_params_mkbp_info { + uint8_t info_type; + uint8_t event_type; +} __packed; + +enum ec_mkbp_info_type { + /* + * Info about the keyboard matrix: number of rows and columns. + * + * Returns struct ec_response_mkbp_info. + */ + EC_MKBP_INFO_KBD = 0, + + /* + * For buttons and switches, info about which specifically are + * supported. event_type must be set to one of the values in enum + * ec_mkbp_event. + * + * For EC_MKBP_EVENT_BUTTON and EC_MKBP_EVENT_SWITCH, returns a 4 byte + * bitmask indicating which buttons or switches are present. See the + * bit inidices below. + */ + EC_MKBP_INFO_SUPPORTED = 1, + + /* + * Instantaneous state of buttons and switches. + * + * event_type must be set to one of the values in enum ec_mkbp_event. + * + * For EC_MKBP_EVENT_KEY_MATRIX, returns uint8_t key_matrix[13] + * indicating the current state of the keyboard matrix. + * + * For EC_MKBP_EVENT_HOST_EVENT, return uint32_t host_event, the raw + * event state. + * + * For EC_MKBP_EVENT_BUTTON, returns uint32_t buttons, indicating the + * state of supported buttons. + * + * For EC_MKBP_EVENT_SWITCH, returns uint32_t switches, indicating the + * state of supported switches. + */ + EC_MKBP_INFO_CURRENT = 2, +}; + /* Simulate key press */ #define EC_CMD_MKBP_SIMULATE_KEY 0x62 @@ -2009,6 +2060,12 @@ enum ec_mkbp_event { /* New Sensor FIFO data. The event data is fifo_info structure. */ EC_MKBP_EVENT_SENSOR_FIFO = 2, + /* The state of the non-matrixed buttons have changed. */ + EC_MKBP_EVENT_BUTTON = 3, + + /* The state of the switches have changed. */ + EC_MKBP_EVENT_SWITCH = 4, + /* Number of MKBP events */ EC_MKBP_EVENT_COUNT, }; @@ -2018,6 +2075,9 @@ union ec_response_get_next_data { /* Unaligned */ uint32_t host_event; + + uint32_t buttons; + uint32_t switches; } __packed; struct ec_response_get_next_event { @@ -2026,6 +2086,15 @@ struct ec_response_get_next_event { union ec_response_get_next_data data; } __packed; +/* Bit indices for buttons and switches.*/ +/* Buttons */ +#define EC_MKBP_POWER_BUTTON 0 +#define EC_MKBP_VOL_UP 1 +#define EC_MKBP_VOL_DOWN 2 + +/* Switches */ +#define EC_MKBP_LID_OPEN 0 + /*****************************************************************************/ /* Temperature sensor commands */ -- 2.9.3 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] input: cros_ec_keyb: Add non-matrix buttons and switches 2017-01-20 10:14 [PATCH 1/2] mfd: cros-ec: Update cros_ec_commands.h for buttons and switches Enric Balletbo i Serra @ 2017-01-20 10:14 ` Enric Balletbo i Serra 2017-02-01 17:51 ` Dmitry Torokhov 2017-01-23 12:13 ` [PATCH 1/2] mfd: cros-ec: Update cros_ec_commands.h for " Lee Jones 1 sibling, 1 reply; 5+ messages in thread From: Enric Balletbo i Serra @ 2017-01-20 10:14 UTC (permalink / raw) To: Lee Jones, Dmitry Torokhov; +Cc: linux-kernel, linux-input, Douglas Anderson From: Douglas Anderson <dianders@chromium.org> On some newer boards using mkbp we're hooking up non-matrix buttons and switches to the EC but NOT to the main application processor. Let's add kernel support to handle this. Rather than creating a whole new input driver, we'll continue to use cros_ec_keyb and just report the new keys. Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> --- drivers/input/keyboard/cros_ec_keyb.c | 447 ++++++++++++++++++++++++++++++---- 1 file changed, 402 insertions(+), 45 deletions(-) diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 25943e9..ad74ebc 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -34,6 +34,8 @@ #include <linux/mfd/cros_ec.h> #include <linux/mfd/cros_ec_commands.h> +#include <asm/unaligned.h> + /* * @rows: Number of rows in the keypad * @cols: Number of columns in the keypad @@ -43,8 +45,9 @@ * @valid_keys: bitmap of existing keys for each matrix column * @old_kb_state: bitmap of keys pressed last scan * @dev: Device pointer - * @idev: Input device * @ec: Top level ChromeOS device to use to talk to EC + * @idev: The input device for the matrix keys. + * @bs_idev: The input device for non-matrix buttons and switches (or NULL). * @notifier: interrupt event notifier for transport devices */ struct cros_ec_keyb { @@ -57,12 +60,59 @@ struct cros_ec_keyb { uint8_t *old_kb_state; struct device *dev; - struct input_dev *idev; struct cros_ec_device *ec; + + struct input_dev *idev; + struct input_dev *bs_idev; struct notifier_block notifier; }; +/** + * cros_ec_bs_map - Struct mapping Linux keycodes to EC button/switch bitmap + * #defines + * + * @ev_type: The type of the input event to generate (e.g., EV_KEY). + * @code: A linux keycode + * @bit: A #define like EC_MKBP_POWER_BUTTON or EC_MKBP_LID_OPEN + * @inverted: If the #define and EV_SW have opposite meanings, this is true. + * Only applicable to switches. + */ +struct cros_ec_bs_map { + unsigned int ev_type; + unsigned int code; + u8 bit; + bool inverted; +}; + +/* cros_ec_keyb_bs - Map EC button/switch #defines into kernel ones */ +static const struct cros_ec_bs_map cros_ec_keyb_bs[] = { + /* Buttons */ + { + .ev_type = EV_KEY, + .code = KEY_POWER, + .bit = EC_MKBP_POWER_BUTTON, + }, + { + .ev_type = EV_KEY, + .code = KEY_VOLUMEUP, + .bit = EC_MKBP_VOL_UP, + }, + { + .ev_type = EV_KEY, + .code = KEY_VOLUMEDOWN, + .bit = EC_MKBP_VOL_DOWN, + }, + + /* Switches */ + { + .ev_type = EV_SW, + .code = SW_LID, + .bit = EC_MKBP_LID_OPEN, + .inverted = true, + }, +}; + /* * Returns true when there is at least one combination of pressed keys that * results in ghosting. @@ -149,20 +199,33 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, input_sync(ckdev->idev); } -static int cros_ec_keyb_open(struct input_dev *dev) +/** + * cros_ec_keyb_report_bs - Report non-matrixed buttons or switches + * + * This takes a bitmap of buttons or switches from the EC and reports events, + * syncing at the end. + * + * @ckdev: The keyboard device. + * @ev_type: The input event type (e.g., EV_KEY). + * @mask: A bitmap of buttons from the EC. + */ +static void cros_ec_keyb_report_bs(struct cros_ec_keyb *ckdev, + unsigned int ev_type, u32 mask) + { - struct cros_ec_keyb *ckdev = input_get_drvdata(dev); + struct input_dev *idev = ckdev->bs_idev; + int i; - return blocking_notifier_chain_register(&ckdev->ec->event_notifier, - &ckdev->notifier); -} + for (i = 0; i < ARRAY_SIZE(cros_ec_keyb_bs); i++) { + const struct cros_ec_bs_map *map = &cros_ec_keyb_bs[i]; -static void cros_ec_keyb_close(struct input_dev *dev) -{ - struct cros_ec_keyb *ckdev = input_get_drvdata(dev); + if (map->ev_type != ev_type) + continue; - blocking_notifier_chain_unregister(&ckdev->ec->event_notifier, - &ckdev->notifier); + input_event(idev, ev_type, map->code, + !!(mask & BIT(map->bit)) ^ map->inverted); + } + input_sync(idev); } static int cros_ec_keyb_work(struct notifier_block *nb, @@ -170,22 +233,54 @@ static int cros_ec_keyb_work(struct notifier_block *nb, { struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb, notifier); + u32 val; + unsigned int ev_type; + + switch (ckdev->ec->event_data.event_type) { + case EC_MKBP_EVENT_KEY_MATRIX: + /* + * If EC is not the wake source, discard key state changes + * during suspend. + */ + if (queued_during_suspend) + return NOTIFY_OK; + + if (ckdev->ec->event_size != ckdev->cols) { + dev_err(ckdev->dev, + "Discarded incomplete key matrix event.\n"); + return NOTIFY_OK; + } + cros_ec_keyb_process(ckdev, + ckdev->ec->event_data.data.key_matrix, + ckdev->ec->event_size); + break; + + case EC_MKBP_EVENT_BUTTON: + case EC_MKBP_EVENT_SWITCH: + /* + * If EC is not the wake source, discard key state + * changes during suspend. Switches will be re-checked in + * cros_ec_keyb_resume() to be sure nothing is lost. + */ + if (queued_during_suspend) + return NOTIFY_OK; + + if (ckdev->ec->event_data.event_type == EC_MKBP_EVENT_BUTTON) { + val = get_unaligned_le32( + &ckdev->ec->event_data.data.buttons); + ev_type = EV_KEY; + } else { + val = get_unaligned_le32( + &ckdev->ec->event_data.data.switches); + ev_type = EV_SW; + } + cros_ec_keyb_report_bs(ckdev, ev_type, val); + break; - if (ckdev->ec->event_data.event_type != EC_MKBP_EVENT_KEY_MATRIX) + default: return NOTIFY_DONE; - /* - * If EC is not the wake source, discard key state changes during - * suspend. - */ - if (queued_during_suspend) - return NOTIFY_OK; - if (ckdev->ec->event_size != ckdev->cols) { - dev_err(ckdev->dev, - "Discarded incomplete key matrix event.\n"); - return NOTIFY_OK; } - cros_ec_keyb_process(ckdev, ckdev->ec->event_data.data.key_matrix, - ckdev->ec->event_size); + return NOTIFY_OK; } @@ -213,22 +308,228 @@ static void cros_ec_keyb_compute_valid_keys(struct cros_ec_keyb *ckdev) } } -static int cros_ec_keyb_probe(struct platform_device *pdev) +/** + * cros_ec_keyb_info - Wrap the EC command EC_CMD_MKBP_INFO + * + * This wraps the EC_CMD_MKBP_INFO, abstracting out all of the marshalling and + * unmarshalling and different version nonsense into something simple. + * + * @ec_dev: The EC device + * @info_type: Either EC_MKBP_INFO_SUPPORTED or EC_MKBP_INFO_CURRENT. + * @event_type: Either EC_MKBP_EVENT_BUTTON or EC_MKBP_EVENT_SWITCH. Actually + * in some cases this could be EC_MKBP_EVENT_KEY_MATRIX or + * EC_MKBP_EVENT_HOST_EVENT too but we don't use in this driver. + * @result: Where we'll store the result; a union + * @result_size: The size of the result. Expected to be the size of one of + * the elements in the union. + * + * Returns 0 if no error or -error upon error. + */ +static int cros_ec_keyb_info(struct cros_ec_device *ec_dev, + enum ec_mkbp_info_type info_type, + enum ec_mkbp_event event_type, + union ec_response_get_next_data *result, + size_t result_size) { - struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); - struct device *dev = &pdev->dev; - struct cros_ec_keyb *ckdev; + struct ec_params_mkbp_info *params; + struct cros_ec_command *msg; + int ret; + + msg = kzalloc(sizeof(*msg) + max_t(size_t, result_size, + sizeof(*params)), GFP_KERNEL); + if (!msg) + return -ENOMEM; + + msg->command = EC_CMD_MKBP_INFO; + msg->version = 1; + msg->outsize = sizeof(*params); + msg->insize = result_size; + params = (struct ec_params_mkbp_info *)msg->data; + params->info_type = info_type; + params->event_type = event_type; + + ret = cros_ec_cmd_xfer(ec_dev, msg); + if (ret < 0) { + dev_warn(ec_dev->dev, "Transfer error %d/%d: %d\n", + (int)info_type, (int)event_type, ret); + } else if (msg->result == EC_RES_INVALID_VERSION) { + /* With older ECs we just return 0 for everything */ + memset(result, 0, result_size); + ret = 0; + } else if (msg->result != EC_RES_SUCCESS) { + dev_warn(ec_dev->dev, "Error getting info %d/%d: %d\n", + (int)info_type, (int)event_type, msg->result); + ret = -EPROTO; + } else if (ret != result_size) { + dev_warn(ec_dev->dev, "Wrong size %d/%d: %d != %zu\n", + (int)info_type, (int)event_type, + ret, result_size); + ret = -EPROTO; + } else { + memcpy(result, msg->data, result_size); + ret = 0; + } + + kfree(msg); + + return ret; +} + +/** + * cros_ec_keyb_query_switches - Query the state of switches and report + * + * This will ask the EC about the current state of switches and report to the + * kernel. Note that we don't query for buttons because they are more + * transitory and we'll get an update on the next release / press. + * + * @ckdev: The keyboard device + * + * Returns 0 if no error or -error upon error. + */ +static int cros_ec_keyb_query_switches(struct cros_ec_keyb *ckdev) +{ + struct cros_ec_device *ec_dev = ckdev->ec; + union ec_response_get_next_data event_data = {}; + int ret; + + ret = cros_ec_keyb_info(ec_dev, EC_MKBP_INFO_CURRENT, + EC_MKBP_EVENT_SWITCH, &event_data, + sizeof(event_data.switches)); + if (ret) + return ret; + + cros_ec_keyb_report_bs(ckdev, EV_SW, + get_unaligned_le32(&event_data.switches)); + + return 0; +} + +/** + * cros_ec_keyb_resume - Resume the keyboard + * + * We use the resume notification as a chance to query the EC for switches. + * + * @dev: The keyboard device + * + * Returns 0 if no error or -error upon error. + */ +static __maybe_unused int cros_ec_keyb_resume(struct device *dev) +{ + struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); + + if (ckdev->bs_idev) + return cros_ec_keyb_query_switches(ckdev); + + return 0; +} + +/** + * cros_ec_keyb_register_bs - Register non-matrix buttons/switches + * + * Handles all the bits of the keyboard driver related to non-matrix buttons + * and switches, including asking the EC about which are present and telling + * the kernel to expect them. + * + * If this device has no support for buttons and switches we'll return no error + * but the ckdev->bs_idev will remain NULL when this function exits. + * + * @ckdev: The keyboard device + * + * Returns 0 if no error or -error upon error. + */ +static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev) +{ + struct cros_ec_device *ec_dev = ckdev->ec; + struct device *dev = ckdev->dev; struct input_dev *idev; - struct device_node *np; - int err; + union ec_response_get_next_data event_data = {}; + const char *phys; + u32 buttons; + u32 switches; + int ret; + int i; + + ret = cros_ec_keyb_info(ec_dev, EC_MKBP_INFO_SUPPORTED, + EC_MKBP_EVENT_BUTTON, &event_data, + sizeof(event_data.buttons)); + if (ret) + return ret; + buttons = get_unaligned_le32(&event_data.buttons); + + ret = cros_ec_keyb_info(ec_dev, EC_MKBP_INFO_SUPPORTED, + EC_MKBP_EVENT_SWITCH, &event_data, + sizeof(event_data.switches)); + if (ret) + return ret; + switches = get_unaligned_le32(&event_data.switches); + + if (!buttons && !switches) + return 0; - np = pdev->dev.of_node; - if (!np) - return -ENODEV; + /* + * We call the non-matrix buttons/switches 'input1', if present. + * Allocate phys before input dev, to ensure correct tear-down + * ordering. + */ + phys = devm_kasprintf(dev, GFP_KERNEL, "%s/input1", ec_dev->phys_name); + if (!phys) + return -ENOMEM; - ckdev = devm_kzalloc(dev, sizeof(*ckdev), GFP_KERNEL); - if (!ckdev) + idev = devm_input_allocate_device(dev); + if (!idev) return -ENOMEM; + + idev->name = "cros_ec_buttons"; + idev->phys = phys; + __set_bit(EV_REP, idev->evbit); + + idev->id.bustype = BUS_VIRTUAL; + idev->id.version = 1; + idev->id.product = 0; + idev->dev.parent = dev; + + input_set_drvdata(idev, ckdev); + ckdev->bs_idev = idev; + + for (i = 0; i < ARRAY_SIZE(cros_ec_keyb_bs); i++) { + const struct cros_ec_bs_map *map = &cros_ec_keyb_bs[i]; + + if (buttons & BIT(map->bit)) + input_set_capability(idev, map->ev_type, map->code); + } + + ret = cros_ec_keyb_query_switches(ckdev); + if (ret) { + dev_err(dev, "cannot query switches\n"); + return ret; + } + + ret = input_register_device(ckdev->bs_idev); + if (ret) { + dev_err(dev, "cannot register input device\n"); + return ret; + } + + return 0; +} + +/** + * cros_ec_keyb_register_bs - Register matrix keys + * + * Handles all the bits of the keyboard driver related to matrix keys. + * + * @ckdev: The keyboard device + * + * Returns 0 if no error or -error upon error. + */ +static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev) +{ + struct cros_ec_device *ec_dev = ckdev->ec; + struct device *dev = ckdev->dev; + struct input_dev *idev; + const char *phys; + int err; + err = matrix_keypad_parse_of_params(dev, &ckdev->rows, &ckdev->cols); if (err) return err; @@ -241,27 +542,28 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) if (!ckdev->old_kb_state) return -ENOMEM; + /* + * We call the keyboard matrix 'input0'. Allocate phys before input + * dev, to ensure correct tear-down ordering. + */ + phys = devm_kasprintf(dev, GFP_KERNEL, "%s/input0", ec_dev->phys_name); + if (!phys) + return -ENOMEM; + idev = devm_input_allocate_device(dev); if (!idev) return -ENOMEM; - ckdev->ec = ec; - ckdev->notifier.notifier_call = cros_ec_keyb_work; - ckdev->dev = dev; - dev_set_drvdata(dev, ckdev); - idev->name = CROS_EC_DEV_NAME; - idev->phys = ec->phys_name; + idev->phys = phys; __set_bit(EV_REP, idev->evbit); idev->id.bustype = BUS_VIRTUAL; idev->id.version = 1; idev->id.product = 0; idev->dev.parent = dev; - idev->open = cros_ec_keyb_open; - idev->close = cros_ec_keyb_close; - ckdev->ghost_filter = of_property_read_bool(np, + ckdev->ghost_filter = of_property_read_bool(dev->of_node, "google,needs-ghost-filter"); err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols, @@ -287,6 +589,57 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) return 0; } +static int cros_ec_keyb_probe(struct platform_device *pdev) +{ + struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; + struct cros_ec_keyb *ckdev; + int err; + + if (!dev->of_node) + return -ENODEV; + + ckdev = devm_kzalloc(dev, sizeof(*ckdev), GFP_KERNEL); + if (!ckdev) + return -ENOMEM; + + ckdev->ec = ec; + ckdev->dev = dev; + dev_set_drvdata(dev, ckdev); + + err = cros_ec_keyb_register_matrix(ckdev); + if (err) { + dev_err(dev, "cannot register matrix inputs: %d\n", err); + return err; + } + + err = cros_ec_keyb_register_bs(ckdev); + if (err) { + dev_err(dev, "cannot register non-matrix inputs: %d\n", err); + return err; + } + + ckdev->notifier.notifier_call = cros_ec_keyb_work; + err = blocking_notifier_chain_register(&ckdev->ec->event_notifier, + &ckdev->notifier); + if (err) { + dev_err(dev, "cannot register notifier: %d\n", err); + return err; + } + + return 0; +} + +static int cros_ec_keyb_remove(struct platform_device *pdev) +{ + struct cros_ec_keyb *ckdev = dev_get_drvdata(&pdev->dev); + + blocking_notifier_chain_unregister(&ckdev->ec->event_notifier, + &ckdev->notifier); + + return 0; +} + #ifdef CONFIG_OF static const struct of_device_id cros_ec_keyb_of_match[] = { { .compatible = "google,cros-ec-keyb" }, @@ -295,11 +648,15 @@ static const struct of_device_id cros_ec_keyb_of_match[] = { MODULE_DEVICE_TABLE(of, cros_ec_keyb_of_match); #endif +static const SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume); + static struct platform_driver cros_ec_keyb_driver = { .probe = cros_ec_keyb_probe, + .remove = cros_ec_keyb_remove, .driver = { .name = "cros-ec-keyb", .of_match_table = of_match_ptr(cros_ec_keyb_of_match), + .pm = &cros_ec_keyb_pm_ops, }, }; -- 2.9.3 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] input: cros_ec_keyb: Add non-matrix buttons and switches 2017-01-20 10:14 ` [PATCH 2/2] input: cros_ec_keyb: Add non-matrix " Enric Balletbo i Serra @ 2017-02-01 17:51 ` Dmitry Torokhov 0 siblings, 0 replies; 5+ messages in thread From: Dmitry Torokhov @ 2017-02-01 17:51 UTC (permalink / raw) To: Enric Balletbo i Serra Cc: Lee Jones, linux-kernel, linux-input, Douglas Anderson On Fri, Jan 20, 2017 at 11:14:15AM +0100, Enric Balletbo i Serra wrote: > From: Douglas Anderson <dianders@chromium.org> > > On some newer boards using mkbp we're hooking up non-matrix buttons and > switches to the EC but NOT to the main application processor. > > Let's add kernel support to handle this. Rather than creating a whole > new input driver, we'll continue to use cros_ec_keyb and just report the > new keys. > > Signed-off-by: Douglas Anderson <dianders@chromium.org> > Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> > --- > drivers/input/keyboard/cros_ec_keyb.c | 447 ++++++++++++++++++++++++++++++---- > 1 file changed, 402 insertions(+), 45 deletions(-) > > diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c > index 25943e9..ad74ebc 100644 > --- a/drivers/input/keyboard/cros_ec_keyb.c > +++ b/drivers/input/keyboard/cros_ec_keyb.c > @@ -34,6 +34,8 @@ > #include <linux/mfd/cros_ec.h> > #include <linux/mfd/cros_ec_commands.h> > > +#include <asm/unaligned.h> > + > /* > * @rows: Number of rows in the keypad > * @cols: Number of columns in the keypad > @@ -43,8 +45,9 @@ > * @valid_keys: bitmap of existing keys for each matrix column > * @old_kb_state: bitmap of keys pressed last scan > * @dev: Device pointer > - * @idev: Input device > * @ec: Top level ChromeOS device to use to talk to EC > + * @idev: The input device for the matrix keys. > + * @bs_idev: The input device for non-matrix buttons and switches (or NULL). > * @notifier: interrupt event notifier for transport devices > */ > struct cros_ec_keyb { > @@ -57,12 +60,59 @@ struct cros_ec_keyb { > uint8_t *old_kb_state; > > struct device *dev; > - struct input_dev *idev; > struct cros_ec_device *ec; > + > + struct input_dev *idev; > + struct input_dev *bs_idev; > struct notifier_block notifier; > }; > > > +/** > + * cros_ec_bs_map - Struct mapping Linux keycodes to EC button/switch bitmap > + * #defines > + * > + * @ev_type: The type of the input event to generate (e.g., EV_KEY). > + * @code: A linux keycode > + * @bit: A #define like EC_MKBP_POWER_BUTTON or EC_MKBP_LID_OPEN > + * @inverted: If the #define and EV_SW have opposite meanings, this is true. > + * Only applicable to switches. > + */ > +struct cros_ec_bs_map { > + unsigned int ev_type; > + unsigned int code; > + u8 bit; > + bool inverted; > +}; > + > +/* cros_ec_keyb_bs - Map EC button/switch #defines into kernel ones */ > +static const struct cros_ec_bs_map cros_ec_keyb_bs[] = { > + /* Buttons */ > + { > + .ev_type = EV_KEY, > + .code = KEY_POWER, > + .bit = EC_MKBP_POWER_BUTTON, > + }, > + { > + .ev_type = EV_KEY, > + .code = KEY_VOLUMEUP, > + .bit = EC_MKBP_VOL_UP, > + }, > + { > + .ev_type = EV_KEY, > + .code = KEY_VOLUMEDOWN, > + .bit = EC_MKBP_VOL_DOWN, > + }, > + > + /* Switches */ > + { > + .ev_type = EV_SW, > + .code = SW_LID, > + .bit = EC_MKBP_LID_OPEN, > + .inverted = true, > + }, > +}; > + > /* > * Returns true when there is at least one combination of pressed keys that > * results in ghosting. > @@ -149,20 +199,33 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, > input_sync(ckdev->idev); > } > > -static int cros_ec_keyb_open(struct input_dev *dev) > +/** > + * cros_ec_keyb_report_bs - Report non-matrixed buttons or switches > + * > + * This takes a bitmap of buttons or switches from the EC and reports events, > + * syncing at the end. > + * > + * @ckdev: The keyboard device. > + * @ev_type: The input event type (e.g., EV_KEY). > + * @mask: A bitmap of buttons from the EC. > + */ > +static void cros_ec_keyb_report_bs(struct cros_ec_keyb *ckdev, > + unsigned int ev_type, u32 mask) > + > { > - struct cros_ec_keyb *ckdev = input_get_drvdata(dev); > + struct input_dev *idev = ckdev->bs_idev; > + int i; > > - return blocking_notifier_chain_register(&ckdev->ec->event_notifier, > - &ckdev->notifier); > -} > + for (i = 0; i < ARRAY_SIZE(cros_ec_keyb_bs); i++) { > + const struct cros_ec_bs_map *map = &cros_ec_keyb_bs[i]; > > -static void cros_ec_keyb_close(struct input_dev *dev) > -{ > - struct cros_ec_keyb *ckdev = input_get_drvdata(dev); > + if (map->ev_type != ev_type) > + continue; > > - blocking_notifier_chain_unregister(&ckdev->ec->event_notifier, > - &ckdev->notifier); > + input_event(idev, ev_type, map->code, > + !!(mask & BIT(map->bit)) ^ map->inverted); > + } > + input_sync(idev); > } > > static int cros_ec_keyb_work(struct notifier_block *nb, > @@ -170,22 +233,54 @@ static int cros_ec_keyb_work(struct notifier_block *nb, > { > struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb, > notifier); > + u32 val; > + unsigned int ev_type; > + > + switch (ckdev->ec->event_data.event_type) { > + case EC_MKBP_EVENT_KEY_MATRIX: > + /* > + * If EC is not the wake source, discard key state changes > + * during suspend. > + */ > + if (queued_during_suspend) > + return NOTIFY_OK; > + > + if (ckdev->ec->event_size != ckdev->cols) { > + dev_err(ckdev->dev, > + "Discarded incomplete key matrix event.\n"); > + return NOTIFY_OK; > + } > + cros_ec_keyb_process(ckdev, > + ckdev->ec->event_data.data.key_matrix, > + ckdev->ec->event_size); > + break; > + > + case EC_MKBP_EVENT_BUTTON: > + case EC_MKBP_EVENT_SWITCH: > + /* > + * If EC is not the wake source, discard key state > + * changes during suspend. Switches will be re-checked in > + * cros_ec_keyb_resume() to be sure nothing is lost. > + */ > + if (queued_during_suspend) > + return NOTIFY_OK; > + > + if (ckdev->ec->event_data.event_type == EC_MKBP_EVENT_BUTTON) { > + val = get_unaligned_le32( > + &ckdev->ec->event_data.data.buttons); > + ev_type = EV_KEY; > + } else { > + val = get_unaligned_le32( > + &ckdev->ec->event_data.data.switches); > + ev_type = EV_SW; > + } > + cros_ec_keyb_report_bs(ckdev, ev_type, val); > + break; > > - if (ckdev->ec->event_data.event_type != EC_MKBP_EVENT_KEY_MATRIX) > + default: > return NOTIFY_DONE; > - /* > - * If EC is not the wake source, discard key state changes during > - * suspend. > - */ > - if (queued_during_suspend) > - return NOTIFY_OK; > - if (ckdev->ec->event_size != ckdev->cols) { > - dev_err(ckdev->dev, > - "Discarded incomplete key matrix event.\n"); > - return NOTIFY_OK; > } > - cros_ec_keyb_process(ckdev, ckdev->ec->event_data.data.key_matrix, > - ckdev->ec->event_size); > + > return NOTIFY_OK; > } > > @@ -213,22 +308,228 @@ static void cros_ec_keyb_compute_valid_keys(struct cros_ec_keyb *ckdev) > } > } > > -static int cros_ec_keyb_probe(struct platform_device *pdev) > +/** > + * cros_ec_keyb_info - Wrap the EC command EC_CMD_MKBP_INFO > + * > + * This wraps the EC_CMD_MKBP_INFO, abstracting out all of the marshalling and > + * unmarshalling and different version nonsense into something simple. > + * > + * @ec_dev: The EC device > + * @info_type: Either EC_MKBP_INFO_SUPPORTED or EC_MKBP_INFO_CURRENT. > + * @event_type: Either EC_MKBP_EVENT_BUTTON or EC_MKBP_EVENT_SWITCH. Actually > + * in some cases this could be EC_MKBP_EVENT_KEY_MATRIX or > + * EC_MKBP_EVENT_HOST_EVENT too but we don't use in this driver. > + * @result: Where we'll store the result; a union > + * @result_size: The size of the result. Expected to be the size of one of > + * the elements in the union. > + * > + * Returns 0 if no error or -error upon error. > + */ > +static int cros_ec_keyb_info(struct cros_ec_device *ec_dev, > + enum ec_mkbp_info_type info_type, > + enum ec_mkbp_event event_type, > + union ec_response_get_next_data *result, > + size_t result_size) > { > - struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); > - struct device *dev = &pdev->dev; > - struct cros_ec_keyb *ckdev; > + struct ec_params_mkbp_info *params; > + struct cros_ec_command *msg; > + int ret; > + > + msg = kzalloc(sizeof(*msg) + max_t(size_t, result_size, > + sizeof(*params)), GFP_KERNEL); > + if (!msg) > + return -ENOMEM; > + > + msg->command = EC_CMD_MKBP_INFO; > + msg->version = 1; > + msg->outsize = sizeof(*params); > + msg->insize = result_size; > + params = (struct ec_params_mkbp_info *)msg->data; > + params->info_type = info_type; > + params->event_type = event_type; > + > + ret = cros_ec_cmd_xfer(ec_dev, msg); > + if (ret < 0) { > + dev_warn(ec_dev->dev, "Transfer error %d/%d: %d\n", > + (int)info_type, (int)event_type, ret); > + } else if (msg->result == EC_RES_INVALID_VERSION) { > + /* With older ECs we just return 0 for everything */ > + memset(result, 0, result_size); > + ret = 0; > + } else if (msg->result != EC_RES_SUCCESS) { > + dev_warn(ec_dev->dev, "Error getting info %d/%d: %d\n", > + (int)info_type, (int)event_type, msg->result); > + ret = -EPROTO; > + } else if (ret != result_size) { > + dev_warn(ec_dev->dev, "Wrong size %d/%d: %d != %zu\n", > + (int)info_type, (int)event_type, > + ret, result_size); > + ret = -EPROTO; > + } else { > + memcpy(result, msg->data, result_size); > + ret = 0; > + } > + > + kfree(msg); > + > + return ret; > +} > + > +/** > + * cros_ec_keyb_query_switches - Query the state of switches and report > + * > + * This will ask the EC about the current state of switches and report to the > + * kernel. Note that we don't query for buttons because they are more > + * transitory and we'll get an update on the next release / press. > + * > + * @ckdev: The keyboard device > + * > + * Returns 0 if no error or -error upon error. > + */ > +static int cros_ec_keyb_query_switches(struct cros_ec_keyb *ckdev) > +{ > + struct cros_ec_device *ec_dev = ckdev->ec; > + union ec_response_get_next_data event_data = {}; > + int ret; > + > + ret = cros_ec_keyb_info(ec_dev, EC_MKBP_INFO_CURRENT, > + EC_MKBP_EVENT_SWITCH, &event_data, > + sizeof(event_data.switches)); > + if (ret) > + return ret; > + > + cros_ec_keyb_report_bs(ckdev, EV_SW, > + get_unaligned_le32(&event_data.switches)); > + > + return 0; > +} > + > +/** > + * cros_ec_keyb_resume - Resume the keyboard > + * > + * We use the resume notification as a chance to query the EC for switches. > + * > + * @dev: The keyboard device > + * > + * Returns 0 if no error or -error upon error. > + */ > +static __maybe_unused int cros_ec_keyb_resume(struct device *dev) > +{ > + struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); > + > + if (ckdev->bs_idev) > + return cros_ec_keyb_query_switches(ckdev); > + > + return 0; > +} > + > +/** > + * cros_ec_keyb_register_bs - Register non-matrix buttons/switches > + * > + * Handles all the bits of the keyboard driver related to non-matrix buttons > + * and switches, including asking the EC about which are present and telling > + * the kernel to expect them. > + * > + * If this device has no support for buttons and switches we'll return no error > + * but the ckdev->bs_idev will remain NULL when this function exits. > + * > + * @ckdev: The keyboard device > + * > + * Returns 0 if no error or -error upon error. > + */ > +static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev) > +{ > + struct cros_ec_device *ec_dev = ckdev->ec; > + struct device *dev = ckdev->dev; > struct input_dev *idev; > - struct device_node *np; > - int err; > + union ec_response_get_next_data event_data = {}; > + const char *phys; > + u32 buttons; > + u32 switches; > + int ret; > + int i; > + > + ret = cros_ec_keyb_info(ec_dev, EC_MKBP_INFO_SUPPORTED, > + EC_MKBP_EVENT_BUTTON, &event_data, > + sizeof(event_data.buttons)); > + if (ret) > + return ret; > + buttons = get_unaligned_le32(&event_data.buttons); > + > + ret = cros_ec_keyb_info(ec_dev, EC_MKBP_INFO_SUPPORTED, > + EC_MKBP_EVENT_SWITCH, &event_data, > + sizeof(event_data.switches)); > + if (ret) > + return ret; > + switches = get_unaligned_le32(&event_data.switches); > + > + if (!buttons && !switches) > + return 0; > > - np = pdev->dev.of_node; > - if (!np) > - return -ENODEV; > + /* > + * We call the non-matrix buttons/switches 'input1', if present. > + * Allocate phys before input dev, to ensure correct tear-down > + * ordering. > + */ > + phys = devm_kasprintf(dev, GFP_KERNEL, "%s/input1", ec_dev->phys_name); > + if (!phys) > + return -ENOMEM; > > - ckdev = devm_kzalloc(dev, sizeof(*ckdev), GFP_KERNEL); > - if (!ckdev) > + idev = devm_input_allocate_device(dev); > + if (!idev) > return -ENOMEM; > + > + idev->name = "cros_ec_buttons"; > + idev->phys = phys; > + __set_bit(EV_REP, idev->evbit); > + > + idev->id.bustype = BUS_VIRTUAL; > + idev->id.version = 1; > + idev->id.product = 0; > + idev->dev.parent = dev; > + > + input_set_drvdata(idev, ckdev); > + ckdev->bs_idev = idev; > + > + for (i = 0; i < ARRAY_SIZE(cros_ec_keyb_bs); i++) { > + const struct cros_ec_bs_map *map = &cros_ec_keyb_bs[i]; > + > + if (buttons & BIT(map->bit)) > + input_set_capability(idev, map->ev_type, map->code); > + } > + > + ret = cros_ec_keyb_query_switches(ckdev); > + if (ret) { > + dev_err(dev, "cannot query switches\n"); > + return ret; > + } > + > + ret = input_register_device(ckdev->bs_idev); > + if (ret) { > + dev_err(dev, "cannot register input device\n"); > + return ret; > + } > + > + return 0; > +} > + > +/** > + * cros_ec_keyb_register_bs - Register matrix keys > + * > + * Handles all the bits of the keyboard driver related to matrix keys. > + * > + * @ckdev: The keyboard device > + * > + * Returns 0 if no error or -error upon error. > + */ > +static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev) > +{ > + struct cros_ec_device *ec_dev = ckdev->ec; > + struct device *dev = ckdev->dev; > + struct input_dev *idev; > + const char *phys; > + int err; > + > err = matrix_keypad_parse_of_params(dev, &ckdev->rows, &ckdev->cols); > if (err) > return err; > @@ -241,27 +542,28 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) > if (!ckdev->old_kb_state) > return -ENOMEM; > > + /* > + * We call the keyboard matrix 'input0'. Allocate phys before input > + * dev, to ensure correct tear-down ordering. > + */ > + phys = devm_kasprintf(dev, GFP_KERNEL, "%s/input0", ec_dev->phys_name); > + if (!phys) > + return -ENOMEM; > + > idev = devm_input_allocate_device(dev); > if (!idev) > return -ENOMEM; > > - ckdev->ec = ec; > - ckdev->notifier.notifier_call = cros_ec_keyb_work; > - ckdev->dev = dev; > - dev_set_drvdata(dev, ckdev); > - > idev->name = CROS_EC_DEV_NAME; > - idev->phys = ec->phys_name; > + idev->phys = phys; > __set_bit(EV_REP, idev->evbit); > > idev->id.bustype = BUS_VIRTUAL; > idev->id.version = 1; > idev->id.product = 0; > idev->dev.parent = dev; > - idev->open = cros_ec_keyb_open; > - idev->close = cros_ec_keyb_close; > > - ckdev->ghost_filter = of_property_read_bool(np, > + ckdev->ghost_filter = of_property_read_bool(dev->of_node, > "google,needs-ghost-filter"); > > err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols, > @@ -287,6 +589,57 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) > return 0; > } > > +static int cros_ec_keyb_probe(struct platform_device *pdev) > +{ > + struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); > + struct device *dev = &pdev->dev; > + struct cros_ec_keyb *ckdev; > + int err; > + > + if (!dev->of_node) > + return -ENODEV; > + > + ckdev = devm_kzalloc(dev, sizeof(*ckdev), GFP_KERNEL); > + if (!ckdev) > + return -ENOMEM; > + > + ckdev->ec = ec; > + ckdev->dev = dev; > + dev_set_drvdata(dev, ckdev); > + > + err = cros_ec_keyb_register_matrix(ckdev); > + if (err) { > + dev_err(dev, "cannot register matrix inputs: %d\n", err); > + return err; > + } > + > + err = cros_ec_keyb_register_bs(ckdev); > + if (err) { > + dev_err(dev, "cannot register non-matrix inputs: %d\n", err); > + return err; > + } > + > + ckdev->notifier.notifier_call = cros_ec_keyb_work; > + err = blocking_notifier_chain_register(&ckdev->ec->event_notifier, > + &ckdev->notifier); > + if (err) { > + dev_err(dev, "cannot register notifier: %d\n", err); > + return err; > + } > + > + return 0; > +} > + > +static int cros_ec_keyb_remove(struct platform_device *pdev) > +{ > + struct cros_ec_keyb *ckdev = dev_get_drvdata(&pdev->dev); > + > + blocking_notifier_chain_unregister(&ckdev->ec->event_notifier, > + &ckdev->notifier); > + > + return 0; > +} > + > #ifdef CONFIG_OF > static const struct of_device_id cros_ec_keyb_of_match[] = { > { .compatible = "google,cros-ec-keyb" }, > @@ -295,11 +648,15 @@ static const struct of_device_id cros_ec_keyb_of_match[] = { > MODULE_DEVICE_TABLE(of, cros_ec_keyb_of_match); > #endif > > +static const SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume); > + > static struct platform_driver cros_ec_keyb_driver = { > .probe = cros_ec_keyb_probe, > + .remove = cros_ec_keyb_remove, > .driver = { > .name = "cros-ec-keyb", > .of_match_table = of_match_ptr(cros_ec_keyb_of_match), > + .pm = &cros_ec_keyb_pm_ops, > }, > }; > > -- > 2.9.3 > -- Dmitry ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] mfd: cros-ec: Update cros_ec_commands.h for buttons and switches 2017-01-20 10:14 [PATCH 1/2] mfd: cros-ec: Update cros_ec_commands.h for buttons and switches Enric Balletbo i Serra 2017-01-20 10:14 ` [PATCH 2/2] input: cros_ec_keyb: Add non-matrix " Enric Balletbo i Serra @ 2017-01-23 12:13 ` Lee Jones 2017-02-01 17:52 ` Dmitry Torokhov 1 sibling, 1 reply; 5+ messages in thread From: Lee Jones @ 2017-01-23 12:13 UTC (permalink / raw) To: Enric Balletbo i Serra Cc: Dmitry Torokhov, linux-kernel, linux-input, Douglas Anderson On Fri, 20 Jan 2017, Enric Balletbo i Serra wrote: > From: Douglas Anderson <dianders@chromium.org> > > Add the defines for the new buttons and switches connected to the CrosEC. > > Signed-off-by: Douglas Anderson <dianders@chromium.org> > Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> > --- > include/linux/mfd/cros_ec_commands.h | 73 +++++++++++++++++++++++++++++++++++- > 1 file changed, 71 insertions(+), 2 deletions(-) Applied, thanks. > diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h > index 23619b2..a01dde4 100644 > --- a/include/linux/mfd/cros_ec_commands.h > +++ b/include/linux/mfd/cros_ec_commands.h > @@ -1865,18 +1865,69 @@ struct ec_response_tmp006_get_raw { > * > * Returns raw data for keyboard cols; see ec_response_mkbp_info.cols for > * expected response size. > + * > + * NOTE: This has been superseded by EC_CMD_MKBP_GET_NEXT_EVENT. If you wish > + * to obtain the instantaneous state, use EC_CMD_MKBP_INFO with the type > + * EC_MKBP_INFO_CURRENT and event EC_MKBP_EVENT_KEY_MATRIX. > */ > #define EC_CMD_MKBP_STATE 0x60 > > -/* Provide information about the matrix : number of rows and columns */ > +/* > + * Provide information about various MKBP things. See enum ec_mkbp_info_type. > + */ > #define EC_CMD_MKBP_INFO 0x61 > > struct ec_response_mkbp_info { > uint32_t rows; > uint32_t cols; > - uint8_t switches; > + /* Formerly "switches", which was 0. */ > + uint8_t reserved; > } __packed; > > +struct ec_params_mkbp_info { > + uint8_t info_type; > + uint8_t event_type; > +} __packed; > + > +enum ec_mkbp_info_type { > + /* > + * Info about the keyboard matrix: number of rows and columns. > + * > + * Returns struct ec_response_mkbp_info. > + */ > + EC_MKBP_INFO_KBD = 0, > + > + /* > + * For buttons and switches, info about which specifically are > + * supported. event_type must be set to one of the values in enum > + * ec_mkbp_event. > + * > + * For EC_MKBP_EVENT_BUTTON and EC_MKBP_EVENT_SWITCH, returns a 4 byte > + * bitmask indicating which buttons or switches are present. See the > + * bit inidices below. > + */ > + EC_MKBP_INFO_SUPPORTED = 1, > + > + /* > + * Instantaneous state of buttons and switches. > + * > + * event_type must be set to one of the values in enum ec_mkbp_event. > + * > + * For EC_MKBP_EVENT_KEY_MATRIX, returns uint8_t key_matrix[13] > + * indicating the current state of the keyboard matrix. > + * > + * For EC_MKBP_EVENT_HOST_EVENT, return uint32_t host_event, the raw > + * event state. > + * > + * For EC_MKBP_EVENT_BUTTON, returns uint32_t buttons, indicating the > + * state of supported buttons. > + * > + * For EC_MKBP_EVENT_SWITCH, returns uint32_t switches, indicating the > + * state of supported switches. > + */ > + EC_MKBP_INFO_CURRENT = 2, > +}; > + > /* Simulate key press */ > #define EC_CMD_MKBP_SIMULATE_KEY 0x62 > > @@ -2009,6 +2060,12 @@ enum ec_mkbp_event { > /* New Sensor FIFO data. The event data is fifo_info structure. */ > EC_MKBP_EVENT_SENSOR_FIFO = 2, > > + /* The state of the non-matrixed buttons have changed. */ > + EC_MKBP_EVENT_BUTTON = 3, > + > + /* The state of the switches have changed. */ > + EC_MKBP_EVENT_SWITCH = 4, > + > /* Number of MKBP events */ > EC_MKBP_EVENT_COUNT, > }; > @@ -2018,6 +2075,9 @@ union ec_response_get_next_data { > > /* Unaligned */ > uint32_t host_event; > + > + uint32_t buttons; > + uint32_t switches; > } __packed; > > struct ec_response_get_next_event { > @@ -2026,6 +2086,15 @@ struct ec_response_get_next_event { > union ec_response_get_next_data data; > } __packed; > > +/* Bit indices for buttons and switches.*/ > +/* Buttons */ > +#define EC_MKBP_POWER_BUTTON 0 > +#define EC_MKBP_VOL_UP 1 > +#define EC_MKBP_VOL_DOWN 2 > + > +/* Switches */ > +#define EC_MKBP_LID_OPEN 0 > + > /*****************************************************************************/ > /* Temperature sensor commands */ > -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] mfd: cros-ec: Update cros_ec_commands.h for buttons and switches 2017-01-23 12:13 ` [PATCH 1/2] mfd: cros-ec: Update cros_ec_commands.h for " Lee Jones @ 2017-02-01 17:52 ` Dmitry Torokhov 0 siblings, 0 replies; 5+ messages in thread From: Dmitry Torokhov @ 2017-02-01 17:52 UTC (permalink / raw) To: Lee Jones Cc: Enric Balletbo i Serra, linux-kernel, linux-input, Douglas Anderson On Mon, Jan 23, 2017 at 12:13:19PM +0000, Lee Jones wrote: > On Fri, 20 Jan 2017, Enric Balletbo i Serra wrote: > > > From: Douglas Anderson <dianders@chromium.org> > > > > Add the defines for the new buttons and switches connected to the CrosEC. > > > > Signed-off-by: Douglas Anderson <dianders@chromium.org> > > Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> > > --- > > include/linux/mfd/cros_ec_commands.h | 73 +++++++++++++++++++++++++++++++++++- > > 1 file changed, 71 insertions(+), 2 deletions(-) > > Applied, thanks. Then please take "[PATCH 2/2] input: cros_ec_keyb: Add non-matrix buttons and switches" as well as it depends on this one. Thanks. -- Dmitry ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-02-01 17:52 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-01-20 10:14 [PATCH 1/2] mfd: cros-ec: Update cros_ec_commands.h for buttons and switches Enric Balletbo i Serra 2017-01-20 10:14 ` [PATCH 2/2] input: cros_ec_keyb: Add non-matrix " Enric Balletbo i Serra 2017-02-01 17:51 ` Dmitry Torokhov 2017-01-23 12:13 ` [PATCH 1/2] mfd: cros-ec: Update cros_ec_commands.h for " Lee Jones 2017-02-01 17:52 ` Dmitry Torokhov
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).