From 518945fbfbe9e2bc39057115aa23e25b084a03e0 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 27 Jan 2013 17:43:41 +0100 Subject: staging: nvec: move toggle global event reporting to its own function Cleanup toggle of global event reporting by moving it to its own function. This simplifies the following cleanup. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 29 ++++++++++++++++++++++------- drivers/staging/nvec/nvec.h | 4 +++- 2 files changed, 25 insertions(+), 8 deletions(-) (limited to 'drivers/staging/nvec') diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 2830946860d1..6fab02faa4a8 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -72,8 +72,10 @@ enum nvec_msg_category { NVEC_MSG_TX, }; -static const unsigned char EC_DISABLE_EVENT_REPORTING[3] = "\x04\x00\x00"; -static const unsigned char EC_ENABLE_EVENT_REPORTING[3] = "\x04\x00\x01"; +enum nvec_sleep_subcmds { + GLOBAL_EVENTS, +}; + static const unsigned char EC_GET_FIRMWARE_VERSION[2] = "\x07\x15"; static struct nvec_chip *nvec_power_handle; @@ -317,6 +319,20 @@ struct nvec_msg *nvec_write_sync(struct nvec_chip *nvec, } EXPORT_SYMBOL(nvec_write_sync); +/** + * nvec_toggle_global_events - enables or disables global event reporting + * @nvec: nvec handle + * @state: true for enable, false for disable + * + * This switches on/off global event reports by the embedded controller. + */ +static void nvec_toggle_global_events(struct nvec_chip *nvec, bool state) +{ + unsigned char global_events[] = { NVEC_SLEEP, GLOBAL_EVENTS, state }; + + nvec_write_async(nvec, global_events, 3); +} + /** * nvec_request_master - Process outgoing messages * @work: A &struct work_struct (the tx_worker member of &struct nvec_chip) @@ -711,7 +727,7 @@ static void nvec_disable_i2c_slave(struct nvec_chip *nvec) static void nvec_power_off(void) { - nvec_write_async(nvec_power_handle, EC_DISABLE_EVENT_REPORTING, 3); + nvec_toggle_global_events(nvec_power_handle, false); nvec_write_async(nvec_power_handle, "\x04\x01", 2); } @@ -815,8 +831,7 @@ static int tegra_nvec_probe(struct platform_device *pdev) /* enable event reporting */ - nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING, - sizeof(EC_ENABLE_EVENT_REPORTING)); + nvec_toggle_global_events(nvec, true); nvec->nvec_status_notifier.notifier_call = nvec_status_notifier; nvec_register_notifier(nvec, &nvec->nvec_status_notifier, 0); @@ -856,7 +871,7 @@ static int tegra_nvec_remove(struct platform_device *pdev) { struct nvec_chip *nvec = platform_get_drvdata(pdev); - nvec_write_async(nvec, EC_DISABLE_EVENT_REPORTING, 3); + nvec_toggle_global_events(nvec, false); mfd_remove_devices(nvec->dev); cancel_work_sync(&nvec->rx_work); cancel_work_sync(&nvec->tx_work); @@ -891,7 +906,7 @@ static int nvec_resume(struct device *dev) dev_dbg(nvec->dev, "resuming\n"); tegra_init_i2c_slave(nvec); - nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING, 3); + nvec_toggle_global_events(nvec, true); return 0; } diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index ba6ed8f4e8a3..bfcd9a9b36e1 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h @@ -71,7 +71,9 @@ enum nvec_event_size { enum nvec_msg_type { NVEC_SYS = 1, NVEC_BAT, - NVEC_KBD = 5, + NVEC_GPIO, + NVEC_SLEEP, + NVEC_KBD, NVEC_PS2, NVEC_CNTL, NVEC_KB_EVT = 0x80, -- cgit v1.2.3-59-g8ed1b From 85a90528b2b4f2d38a56df5b3f137223983aad4b Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 27 Jan 2013 17:43:42 +0100 Subject: staging: nvec: fix mouse suspend/resume calls The EC command for enable/disable is not an EC command. Instead it needs to be send to the mouse. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers/staging/nvec') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 88dd288bf3d7..b1a5a9604ce1 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -25,6 +25,9 @@ #define STOP_STREAMING {'\x06', '\x04'} #define SEND_COMMAND {'\x06', '\x01', '\xf4', '\x01'} +#define ENABLE_MOUSE 0xf4 +#define DISABLE_MOUSE 0xf5 + #ifdef NVEC_PS2_DEBUG #define NVEC_PHD(str, buf, len) \ print_hex_dump(KERN_DEBUG, str, DUMP_PREFIX_NONE, \ @@ -133,27 +136,22 @@ static int nvec_mouse_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int nvec_mouse_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); - /* disable mouse */ - nvec_write_async(nvec, "\x06\xf4", 2); + ps2_sendcommand(ps2_dev.ser_dev, DISABLE_MOUSE); /* send cancel autoreceive */ - nvec_write_async(nvec, "\x06\x04", 2); + ps2_stopstreaming(ps2_dev.ser_dev); return 0; } static int nvec_mouse_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); - + /* start streaming */ ps2_startstreaming(ps2_dev.ser_dev); /* enable mouse */ - nvec_write_async(nvec, "\x06\xf5", 2); + ps2_sendcommand(ps2_dev.ser_dev, ENABLE_MOUSE); return 0; } -- cgit v1.2.3-59-g8ed1b From 93eff83ff1640bef8062568687b5e0e41a0d4c42 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 27 Jan 2013 17:43:43 +0100 Subject: staging: nvec: cleanup the string mess Replace the various command strings by named constants. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 53 +++++++++++++++++++++++++++++++-------- drivers/staging/nvec/nvec.h | 1 + drivers/staging/nvec/nvec_kbd.c | 42 ++++++++++++++++++------------- drivers/staging/nvec/nvec_power.c | 8 +++--- drivers/staging/nvec/nvec_ps2.c | 25 ++++++++++-------- 5 files changed, 89 insertions(+), 40 deletions(-) (limited to 'drivers/staging/nvec') diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 6fab02faa4a8..755585059242 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -74,9 +74,14 @@ enum nvec_msg_category { enum nvec_sleep_subcmds { GLOBAL_EVENTS, + AP_PWR_DOWN, + AP_SUSPEND, }; -static const unsigned char EC_GET_FIRMWARE_VERSION[2] = "\x07\x15"; +#define CNF_EVENT_REPORTING 0x01 +#define GET_FIRMWARE_VERSION 0x15 +#define LID_SWITCH BIT(1) +#define PWR_BUTTON BIT(15) static struct nvec_chip *nvec_power_handle; @@ -333,6 +338,27 @@ static void nvec_toggle_global_events(struct nvec_chip *nvec, bool state) nvec_write_async(nvec, global_events, 3); } +/** + * nvec_event_mask - fill the command string with event bitfield + * ev: points to event command string + * mask: bit to insert into the event mask + * + * Configure event command expects a 32 bit bitfield which describes + * which events to enable. The bitfield has the following structure + * (from highest byte to lowest): + * system state bits 7-0 + * system state bits 15-8 + * oem system state bits 7-0 + * oem system state bits 15-8 + */ +static void nvec_event_mask(char *ev, u32 mask) +{ + ev[3] = mask >> 16 && 0xff; + ev[4] = mask >> 24 && 0xff; + ev[5] = mask >> 0 && 0xff; + ev[6] = mask >> 8 && 0xff; +} + /** * nvec_request_master - Process outgoing messages * @work: A &struct work_struct (the tx_worker member of &struct nvec_chip) @@ -727,8 +753,10 @@ static void nvec_disable_i2c_slave(struct nvec_chip *nvec) static void nvec_power_off(void) { + char ap_pwr_down[] = { NVEC_SLEEP, AP_PWR_DOWN }; + nvec_toggle_global_events(nvec_power_handle, false); - nvec_write_async(nvec_power_handle, "\x04\x01", 2); + nvec_write_async(nvec_power_handle, ap_pwr_down, 2); } static int tegra_nvec_probe(struct platform_device *pdev) @@ -740,6 +768,9 @@ static int tegra_nvec_probe(struct platform_device *pdev) struct nvec_msg *msg; struct resource *res; void __iomem *base; + char get_firmware_version[] = { NVEC_CNTL, GET_FIRMWARE_VERSION }, + unmute_speakers[] = { NVEC_OEM0, 0x10, 0x59, 0x95 }, + enable_event[7] = { NVEC_SYS, CNF_EVENT_REPORTING, true }; nvec = devm_kzalloc(&pdev->dev, sizeof(struct nvec_chip), GFP_KERNEL); if (nvec == NULL) { @@ -840,8 +871,7 @@ static int tegra_nvec_probe(struct platform_device *pdev) pm_power_off = nvec_power_off; /* Get Firmware Version */ - msg = nvec_write_sync(nvec, EC_GET_FIRMWARE_VERSION, - sizeof(EC_GET_FIRMWARE_VERSION)); + msg = nvec_write_sync(nvec, get_firmware_version, 2); if (msg) { dev_warn(nvec->dev, "ec firmware version %02x.%02x.%02x / %02x\n", @@ -856,13 +886,15 @@ static int tegra_nvec_probe(struct platform_device *pdev) dev_err(nvec->dev, "error adding subdevices\n"); /* unmute speakers? */ - nvec_write_async(nvec, "\x0d\x10\x59\x95", 4); + nvec_write_async(nvec, unmute_speakers, 4); /* enable lid switch event */ - nvec_write_async(nvec, "\x01\x01\x01\x00\x00\x02\x00", 7); + nvec_event_mask(enable_event, LID_SWITCH); + nvec_write_async(nvec, enable_event, 7); /* enable power button event */ - nvec_write_async(nvec, "\x01\x01\x01\x00\x00\x80\x00", 7); + nvec_event_mask(enable_event, PWR_BUTTON); + nvec_write_async(nvec, enable_event, 7); return 0; } @@ -885,13 +917,14 @@ static int nvec_suspend(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct nvec_chip *nvec = platform_get_drvdata(pdev); struct nvec_msg *msg; + char ap_suspend[] = { NVEC_SLEEP, AP_SUSPEND }; dev_dbg(nvec->dev, "suspending\n"); /* keep these sync or you'll break suspend */ - msg = nvec_write_sync(nvec, EC_DISABLE_EVENT_REPORTING, 3); - nvec_msg_free(nvec, msg); - msg = nvec_write_sync(nvec, "\x04\x02", 2); + nvec_toggle_global_events(nvec, false); + + msg = nvec_write_sync(nvec, ap_suspend, sizeof(ap_suspend)); nvec_msg_free(nvec, msg); nvec_disable_i2c_slave(nvec); diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index bfcd9a9b36e1..b7a14bc0ab91 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h @@ -76,6 +76,7 @@ enum nvec_msg_type { NVEC_KBD, NVEC_PS2, NVEC_CNTL, + NVEC_OEM0 = 0x0d, NVEC_KB_EVT = 0x80, NVEC_PS2_EVT, }; diff --git a/drivers/staging/nvec/nvec_kbd.c b/drivers/staging/nvec/nvec_kbd.c index 7cb149bf3d3f..7445ce6422bb 100644 --- a/drivers/staging/nvec/nvec_kbd.c +++ b/drivers/staging/nvec/nvec_kbd.c @@ -21,10 +21,14 @@ #include "nvec-keytable.h" #include "nvec.h" -#define ACK_KBD_EVENT {'\x05', '\xed', '\x01'} +enum kbd_subcmds { + CNFG_WAKE = 3, + CNFG_WAKE_KEY_REPORTING, + SET_LEDS = 0xed, + ENABLE_KBD = 0xf4, + DISABLE_KBD, +}; -static const char led_on[3] = "\x05\xed\x07"; -static const char led_off[3] = "\x05\xed\x00"; static unsigned char keycodes[ARRAY_SIZE(code_tab_102us) + ARRAY_SIZE(extcode_tab_us102)]; @@ -39,12 +43,15 @@ static struct nvec_keys keys_dev; static void nvec_kbd_toggle_led(void) { + char buf[] = { NVEC_KBD, SET_LEDS, 0 }; + keys_dev.caps_lock = !keys_dev.caps_lock; if (keys_dev.caps_lock) - nvec_write_async(keys_dev.nvec, led_on, sizeof(led_on)); - else - nvec_write_async(keys_dev.nvec, led_off, sizeof(led_off)); + /* should be BIT(0) only, firmware bug? */ + buf[2] = BIT(0) | BIT(1) | BIT(2); + + nvec_write_async(keys_dev.nvec, buf, sizeof(buf)); } static int nvec_keys_notifier(struct notifier_block *nb, @@ -82,8 +89,8 @@ static int nvec_keys_notifier(struct notifier_block *nb, static int nvec_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - unsigned char buf[] = ACK_KBD_EVENT; struct nvec_chip *nvec = keys_dev.nvec; + char buf[] = { NVEC_KBD, SET_LEDS, 0 }; if (type == EV_REP) return 0; @@ -105,6 +112,11 @@ static int nvec_kbd_probe(struct platform_device *pdev) struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); int i, j, err; struct input_dev *idev; + char clear_leds[] = { NVEC_KBD, SET_LEDS, 0 }, + enable_kbd[] = { NVEC_KBD, ENABLE_KBD }, + cnfg_wake[] = { NVEC_KBD, CNFG_WAKE, true, true }, + cnfg_wake_key_reporting[] = { NVEC_KBD, CNFG_WAKE_KEY_REPORTING, + true }; j = 0; @@ -138,19 +150,15 @@ static int nvec_kbd_probe(struct platform_device *pdev) nvec_register_notifier(nvec, &keys_dev.notifier, 0); /* Enable keyboard */ - nvec_write_async(nvec, "\x05\xf4", 2); + nvec_write_async(nvec, enable_kbd, 2); - /* keyboard reset? */ - nvec_write_async(nvec, "\x05\x03\x01\x01", 4); - nvec_write_async(nvec, "\x05\x04\x01", 3); - nvec_write_async(nvec, "\x06\x01\xff\x03", 4); -/* FIXME - wait until keyboard reset is finished - or until we have a sync write */ - mdelay(1000); + /* configures wake on special keys */ + nvec_write_async(nvec, cnfg_wake, 4); + /* enable wake key reporting */ + nvec_write_async(nvec, cnfg_wake_key_reporting, 3); /* Disable caps lock LED */ - nvec_write_async(nvec, led_off, sizeof(led_off)); + nvec_write_async(nvec, clear_leds, sizeof(clear_leds)); return 0; diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index b7b6d54f58ec..296f7b9a8c8c 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c @@ -22,6 +22,8 @@ #include "nvec.h" +#define GET_SYSTEM_STATUS 0x00 + struct nvec_power { struct notifier_block notifier; struct delayed_work poller; @@ -111,7 +113,7 @@ static const int bat_init[] = { static void get_bat_mfg_data(struct nvec_power *power) { int i; - char buf[] = { '\x02', '\x00' }; + char buf[] = { NVEC_BAT, SLOT_STATUS }; for (i = 0; i < ARRAY_SIZE(bat_init); i++) { buf[1] = bat_init[i]; @@ -348,7 +350,7 @@ static int const bat_iter[] = { static void nvec_power_poll(struct work_struct *work) { - char buf[] = { '\x01', '\x00' }; + char buf[] = { NVEC_SYS, GET_SYSTEM_STATUS }; struct nvec_power *power = container_of(work, struct nvec_power, poller.work); @@ -361,7 +363,7 @@ static void nvec_power_poll(struct work_struct *work) /* select a battery request function via round robin doing it all at once seems to overload the power supply */ - buf[0] = '\x02'; /* battery */ + buf[0] = NVEC_BAT; buf[1] = bat_iter[counter++]; nvec_write_async(power->nvec, buf, 2); diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index b1a5a9604ce1..aff6b9b9f9aa 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -21,12 +21,11 @@ #include "nvec.h" -#define START_STREAMING {'\x06', '\x03', '\x06'} -#define STOP_STREAMING {'\x06', '\x04'} -#define SEND_COMMAND {'\x06', '\x01', '\xf4', '\x01'} +#define PACKET_SIZE 6 -#define ENABLE_MOUSE 0xf4 -#define DISABLE_MOUSE 0xf5 +#define ENABLE_MOUSE 0xf4 +#define DISABLE_MOUSE 0xf5 +#define PSMOUSE_RST 0xff #ifdef NVEC_PS2_DEBUG #define NVEC_PHD(str, buf, len) \ @@ -36,7 +35,12 @@ #define NVEC_PHD(str, buf, len) #endif -static const unsigned char MOUSE_RESET[] = {'\x06', '\x01', '\xff', '\x03'}; +enum ps2_subcmds { + SEND_COMMAND = 1, + RECEIVE_N, + AUTO_RECEIVE_N, + CANCEL_AUTO_RECEIVE, +}; struct nvec_ps2 { struct serio *ser_dev; @@ -48,19 +52,19 @@ static struct nvec_ps2 ps2_dev; static int ps2_startstreaming(struct serio *ser_dev) { - unsigned char buf[] = START_STREAMING; + unsigned char buf[] = { NVEC_PS2, AUTO_RECEIVE_N, PACKET_SIZE }; return nvec_write_async(ps2_dev.nvec, buf, sizeof(buf)); } static void ps2_stopstreaming(struct serio *ser_dev) { - unsigned char buf[] = STOP_STREAMING; + unsigned char buf[] = { NVEC_PS2, CANCEL_AUTO_RECEIVE }; nvec_write_async(ps2_dev.nvec, buf, sizeof(buf)); } static int ps2_sendcommand(struct serio *ser_dev, unsigned char cmd) { - unsigned char buf[] = SEND_COMMAND; + unsigned char buf[] = { NVEC_PS2, SEND_COMMAND, ENABLE_MOUSE, 1 }; buf[2] = cmd & 0xff; @@ -100,6 +104,7 @@ static int nvec_mouse_probe(struct platform_device *pdev) { struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); struct serio *ser_dev; + char mouse_reset[] = { NVEC_PS2, SEND_COMMAND, PSMOUSE_RST, 3 }; ser_dev = devm_kzalloc(&pdev->dev, sizeof(struct serio), GFP_KERNEL); if (ser_dev == NULL) @@ -121,7 +126,7 @@ static int nvec_mouse_probe(struct platform_device *pdev) serio_register_port(ser_dev); /* mouse reset */ - nvec_write_async(nvec, MOUSE_RESET, 4); + nvec_write_async(nvec, mouse_reset, sizeof(mouse_reset)); return 0; } -- cgit v1.2.3-59-g8ed1b