diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-17 16:45:00 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-17 16:45:00 -0800 |
commit | af79ce47efabba36d1db0902d46a80de7f251411 (patch) | |
tree | 571106db25ed2da54891995aed38407f85e6ac4b /drivers/input/rmi4 | |
parent | c07dee7348e2451bcf2f178bf0e7830268e2c31a (diff) | |
parent | f26e8817b235d8764363bffcc9cbfc61867371f2 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input subsystem updates from Dmitry Torokhov:
- updated support for Synaptics RMI4 devices, including support for
SMBus controllers, firmware update support, sensor tuning, and PS/2
guest support
- ALPS driver now supports tracksticks on SS5 controllers
- i8042 now uses chassis info to skip selftest on Asus laptops as list
of individual models became too unwieldy
- miscellaneous fixes to other drivers
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (67 commits)
Input: imx6ul_tsc - generalize the averaging property
Input: drv260x - use generic device properties
Input: drv260x - use temporary for &client->dev
Input: drv260x - fix input device's parent assignment
Input: synaptics-rmi4 - add support for F34 V7 bootloader
Input: drv260x - fix initializing overdrive voltage
Input: ALPS - fix protcol -> protocol
Input: i8042 - comment #else/#endif of CONFIG_PNP
Input: lpc32xx-keys - fix invalid error handling of a requested irq
Input: synaptics-rmi4 - fix debug for sensor clip
Input: synaptics-rmi4 - store the attn data in the driver
Input: synaptics-rmi4 - allow to add attention data
Input: synaptics-rmi4 - f03 - grab data passed by transport device
Input: synaptics-rmi4 - add support for F03
Input: imx6ul_tsc - convert int to u32
Input: imx6ul_tsc - add mask when set REG_ADC_CFG
Input: synaptics-rmi4 - have only one struct platform data
Input: synaptics-rmi4 - remove EXPORT_SYMBOL_GPL for internal functions
Input: synaptics-rmi4 - remove mutex calls while updating the firmware
Input: drv2667 - fix misuse of regmap_update_bits
...
Diffstat (limited to 'drivers/input/rmi4')
-rw-r--r-- | drivers/input/rmi4/Kconfig | 42 | ||||
-rw-r--r-- | drivers/input/rmi4/Makefile | 4 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_2d_sensor.c | 10 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_2d_sensor.h | 2 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_bus.c | 12 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_bus.h | 12 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_driver.c | 420 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_driver.h | 31 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f01.c | 12 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f03.c | 250 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f11.c | 98 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f12.c | 146 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f30.c | 22 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f34.c | 516 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f34.h | 314 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f34v7.c | 1372 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f54.c | 19 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f55.c | 131 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_i2c.c | 74 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_smbus.c | 447 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_spi.c | 72 |
21 files changed, 3686 insertions, 320 deletions
diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig index 4c8a55857e00..30cc627a4f45 100644 --- a/drivers/input/rmi4/Kconfig +++ b/drivers/input/rmi4/Kconfig @@ -27,6 +27,27 @@ config RMI4_SPI If unsure, say N. +config RMI4_SMB + tristate "RMI4 SMB Support" + depends on RMI4_CORE && I2C + help + Say Y here if you want to support RMI4 devices connected to an SMB + bus. + + If unsure, say N. + + To compile this driver as a module, choose M here: the module will be + called rmi_smbus. + +config RMI4_F03 + bool "RMI4 Function 03 (PS2 Guest)" + depends on RMI4_CORE && SERIO + help + Say Y here if you want to add support for RMI4 function 03. + + Function 03 provides PS2 guest support for RMI4 devices. This + includes support for TrackPoints on TouchPads. + config RMI4_2D_SENSOR bool depends on RMI4_CORE @@ -62,13 +83,34 @@ config RMI4_F30 Function 30 provides GPIO and LED support for RMI4 devices. This includes support for buttons on TouchPads and ClickPads. +config RMI4_F34 + bool "RMI4 Function 34 (Device reflash)" + depends on RMI4_CORE + select FW_LOADER + help + Say Y here if you want to add support for RMI4 function 34. + + Function 34 provides support for upgrading the firmware on the RMI4 + device via the firmware loader interface. This is triggered using a + sysfs attribute. + config RMI4_F54 bool "RMI4 Function 54 (Analog diagnostics)" depends on RMI4_CORE depends on VIDEO_V4L2=y || (RMI4_CORE=m && VIDEO_V4L2=m) select VIDEOBUF2_VMALLOC + select RMI4_F55 help Say Y here if you want to add support for RMI4 function 54 Function 54 provides access to various diagnostic features in certain RMI4 touch sensors. + +config RMI4_F55 + bool "RMI4 Function 55 (Sensor tuning)" + depends on RMI4_CORE + help + Say Y here if you want to add support for RMI4 function 55 + + Function 55 provides access to the RMI4 touch sensor tuning + mechanism. diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile index 0bafc8502c4b..9aaac3dd8613 100644 --- a/drivers/input/rmi4/Makefile +++ b/drivers/input/rmi4/Makefile @@ -4,11 +4,15 @@ rmi_core-y := rmi_bus.o rmi_driver.o rmi_f01.o rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o # Function drivers +rmi_core-$(CONFIG_RMI4_F03) += rmi_f03.o rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o +rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o +rmi_core-$(CONFIG_RMI4_F55) += rmi_f55.o # Transports obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o obj-$(CONFIG_RMI4_SPI) += rmi_spi.o +obj-$(CONFIG_RMI4_SMB) += rmi_smbus.o diff --git a/drivers/input/rmi4/rmi_2d_sensor.c b/drivers/input/rmi4/rmi_2d_sensor.c index e97bd7fabccc..07007ff8e29f 100644 --- a/drivers/input/rmi4/rmi_2d_sensor.c +++ b/drivers/input/rmi4/rmi_2d_sensor.c @@ -177,10 +177,12 @@ static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor) sensor->dmax = DMAX * res_x; } - input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xff, 0, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0); - input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0); + input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xff, 0, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0); + input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0); + input_set_abs_params(input, ABS_MT_TOOL_TYPE, + 0, MT_TOOL_MAX, 0, 0); if (sensor->sensor_type == rmi_sensor_touchpad) input_flags = INPUT_MT_POINTER; diff --git a/drivers/input/rmi4/rmi_2d_sensor.h b/drivers/input/rmi4/rmi_2d_sensor.h index 77fcdfef003c..c871bef4dac0 100644 --- a/drivers/input/rmi4/rmi_2d_sensor.h +++ b/drivers/input/rmi4/rmi_2d_sensor.h @@ -67,6 +67,8 @@ struct rmi_2d_sensor { u8 report_rel; u8 x_mm; u8 y_mm; + enum rmi_reg_state dribble; + enum rmi_reg_state palm_detect; }; int rmi_2d_sensor_of_probe(struct device *dev, diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c index ef8c747c35e7..1c40d94ca506 100644 --- a/drivers/input/rmi4/rmi_bus.c +++ b/drivers/input/rmi4/rmi_bus.c @@ -230,6 +230,9 @@ err_put_device: void rmi_unregister_function(struct rmi_function *fn) { + rmi_dbg(RMI_DEBUG_CORE, &fn->dev, "Unregistering F%02X.\n", + fn->fd.function_number); + device_del(&fn->dev); of_node_put(fn->dev.of_node); put_device(&fn->dev); @@ -302,6 +305,9 @@ struct bus_type rmi_bus_type = { static struct rmi_function_handler *fn_handlers[] = { &rmi_f01_handler, +#ifdef CONFIG_RMI4_F03 + &rmi_f03_handler, +#endif #ifdef CONFIG_RMI4_F11 &rmi_f11_handler, #endif @@ -311,9 +317,15 @@ static struct rmi_function_handler *fn_handlers[] = { #ifdef CONFIG_RMI4_F30 &rmi_f30_handler, #endif +#ifdef CONFIG_RMI4_F34 + &rmi_f34_handler, +#endif #ifdef CONFIG_RMI4_F54 &rmi_f54_handler, #endif +#ifdef CONFIG_RMI4_F55 + &rmi_f55_handler, +#endif }; static void __rmi_unregister_function_handlers(int start_idx) diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h index 899579830536..b7625a9ac66a 100644 --- a/drivers/input/rmi4/rmi_bus.h +++ b/drivers/input/rmi4/rmi_bus.h @@ -105,6 +105,18 @@ rmi_get_platform_data(struct rmi_device *d) bool rmi_is_physical_device(struct device *dev); /** + * rmi_reset - reset a RMI4 device + * @d: Pointer to an RMI device + * + * Calls for a reset of each function implemented by a specific device. + * Returns 0 on success or a negative error code. + */ +static inline int rmi_reset(struct rmi_device *d) +{ + return d->driver->reset_handler(d); +} + +/** * rmi_read - read a single byte * @d: Pointer to an RMI device * @addr: The address to read from diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index 4a88312fbd25..11447ab1055c 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -17,6 +17,7 @@ #include <linux/bitmap.h> #include <linux/delay.h> #include <linux/fs.h> +#include <linux/irq.h> #include <linux/pm.h> #include <linux/slab.h> #include <linux/of.h> @@ -33,12 +34,22 @@ #define RMI_DEVICE_RESET_CMD 0x01 #define DEFAULT_RESET_DELAY_MS 100 -static void rmi_free_function_list(struct rmi_device *rmi_dev) +void rmi_free_function_list(struct rmi_device *rmi_dev) { struct rmi_function *fn, *tmp; struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); + rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, "Freeing function list\n"); + + devm_kfree(&rmi_dev->dev, data->irq_memory); + data->irq_memory = NULL; + data->irq_status = NULL; + data->fn_irq_bits = NULL; + data->current_irq_mask = NULL; + data->new_irq_mask = NULL; + data->f01_container = NULL; + data->f34_container = NULL; /* Doing it in the reverse order so F01 will be removed last */ list_for_each_entry_safe_reverse(fn, tmp, @@ -133,7 +144,7 @@ static void process_one_interrupt(struct rmi_driver_data *data, } } -int rmi_process_interrupt_requests(struct rmi_device *rmi_dev) +static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev) { struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); struct device *dev = &rmi_dev->dev; @@ -143,7 +154,7 @@ int rmi_process_interrupt_requests(struct rmi_device *rmi_dev) if (!data) return 0; - if (!rmi_dev->xport->attn_data) { + if (!data->attn_data.data) { error = rmi_read_block(rmi_dev, data->f01_container->fd.data_base_addr + 1, data->irq_status, data->num_of_irq_regs); @@ -178,7 +189,81 @@ int rmi_process_interrupt_requests(struct rmi_device *rmi_dev) return 0; } -EXPORT_SYMBOL_GPL(rmi_process_interrupt_requests); + +void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status, + void *data, size_t size) +{ + struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev); + struct rmi4_attn_data attn_data; + void *fifo_data; + + if (!drvdata->enabled) + return; + + fifo_data = kmemdup(data, size, GFP_ATOMIC); + if (!fifo_data) + return; + + attn_data.irq_status = irq_status; + attn_data.size = size; + attn_data.data = fifo_data; + + kfifo_put(&drvdata->attn_fifo, attn_data); +} +EXPORT_SYMBOL_GPL(rmi_set_attn_data); + +static irqreturn_t rmi_irq_fn(int irq, void *dev_id) +{ + struct rmi_device *rmi_dev = dev_id; + struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev); + struct rmi4_attn_data attn_data = {0}; + int ret, count; + + count = kfifo_get(&drvdata->attn_fifo, &attn_data); + if (count) { + *(drvdata->irq_status) = attn_data.irq_status; + drvdata->attn_data = attn_data; + } + + ret = rmi_process_interrupt_requests(rmi_dev); + if (ret) + rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, + "Failed to process interrupt request: %d\n", ret); + + if (count) + kfree(attn_data.data); + + if (!kfifo_is_empty(&drvdata->attn_fifo)) + return rmi_irq_fn(irq, dev_id); + + return IRQ_HANDLED; +} + +static int rmi_irq_init(struct rmi_device *rmi_dev) +{ + struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); + struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); + int irq_flags = irq_get_trigger_type(pdata->irq); + int ret; + + if (!irq_flags) + irq_flags = IRQF_TRIGGER_LOW; + + ret = devm_request_threaded_irq(&rmi_dev->dev, pdata->irq, NULL, + rmi_irq_fn, irq_flags | IRQF_ONESHOT, + dev_name(rmi_dev->xport->dev), + rmi_dev); + if (ret < 0) { + dev_err(&rmi_dev->dev, "Failed to register interrupt %d\n", + pdata->irq); + + return ret; + } + + data->enabled = true; + + return 0; +} static int suspend_one_function(struct rmi_function *fn) { @@ -248,7 +333,7 @@ static int rmi_resume_functions(struct rmi_device *rmi_dev) return 0; } -static int enable_sensor(struct rmi_device *rmi_dev) +int rmi_enable_sensor(struct rmi_device *rmi_dev) { int retval = 0; @@ -379,8 +464,8 @@ static int rmi_driver_reset_handler(struct rmi_device *rmi_dev) return 0; } -int rmi_read_pdt_entry(struct rmi_device *rmi_dev, struct pdt_entry *entry, - u16 pdt_address) +static int rmi_read_pdt_entry(struct rmi_device *rmi_dev, + struct pdt_entry *entry, u16 pdt_address) { u8 buf[RMI_PDT_ENTRY_SIZE]; int error; @@ -403,7 +488,6 @@ int rmi_read_pdt_entry(struct rmi_device *rmi_dev, struct pdt_entry *entry, return 0; } -EXPORT_SYMBOL_GPL(rmi_read_pdt_entry); static void rmi_driver_copy_pdt_to_fd(const struct pdt_entry *pdt, struct rmi_function_descriptor *fd) @@ -422,6 +506,7 @@ static void rmi_driver_copy_pdt_to_fd(const struct pdt_entry *pdt, static int rmi_scan_pdt_page(struct rmi_device *rmi_dev, int page, + int *empty_pages, void *ctx, int (*callback)(struct rmi_device *rmi_dev, void *ctx, @@ -449,20 +534,30 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_dev, return retval; } - return (data->f01_bootloader_mode || addr == pdt_start) ? + /* + * Count number of empty PDT pages. If a gap of two pages + * or more is found, stop scanning. + */ + if (addr == pdt_start) + ++*empty_pages; + else + *empty_pages = 0; + + return (data->bootloader_mode || *empty_pages >= 2) ? RMI_SCAN_DONE : RMI_SCAN_CONTINUE; } -static int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx, - int (*callback)(struct rmi_device *rmi_dev, - void *ctx, - const struct pdt_entry *entry)) +int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx, + int (*callback)(struct rmi_device *rmi_dev, + void *ctx, const struct pdt_entry *entry)) { int page; + int empty_pages = 0; int retval = RMI_SCAN_DONE; for (page = 0; page <= RMI4_MAX_PAGE; page++) { - retval = rmi_scan_pdt_page(rmi_dev, page, ctx, callback); + retval = rmi_scan_pdt_page(rmi_dev, page, &empty_pages, + ctx, callback); if (retval != RMI_SCAN_CONTINUE) break; } @@ -600,7 +695,6 @@ free_struct_buff: kfree(struct_buf); return ret; } -EXPORT_SYMBOL_GPL(rmi_read_register_desc); const struct rmi_register_desc_item *rmi_get_register_desc_item( struct rmi_register_descriptor *rdesc, u16 reg) @@ -616,7 +710,6 @@ const struct rmi_register_desc_item *rmi_get_register_desc_item( return NULL; } -EXPORT_SYMBOL_GPL(rmi_get_register_desc_item); size_t rmi_register_desc_calc_size(struct rmi_register_descriptor *rdesc) { @@ -630,7 +723,6 @@ size_t rmi_register_desc_calc_size(struct rmi_register_descriptor *rdesc) } return size; } -EXPORT_SYMBOL_GPL(rmi_register_desc_calc_size); /* Compute the register offset relative to the base address */ int rmi_register_desc_calc_reg_offset( @@ -648,7 +740,6 @@ int rmi_register_desc_calc_reg_offset( } return -1; } -EXPORT_SYMBOL_GPL(rmi_register_desc_calc_reg_offset); bool rmi_register_desc_has_subpacket(const struct rmi_register_desc_item *item, u8 subpacket) @@ -657,51 +748,55 @@ bool rmi_register_desc_has_subpacket(const struct rmi_register_desc_item *item, subpacket) == subpacket; } -/* Indicates that flash programming is enabled (bootloader mode). */ -#define RMI_F01_STATUS_BOOTLOADER(status) (!!((status) & 0x40)) - -/* - * Given the PDT entry for F01, read the device status register to determine - * if we're stuck in bootloader mode or not. - * - */ static int rmi_check_bootloader_mode(struct rmi_device *rmi_dev, const struct pdt_entry *pdt) { - int error; - u8 device_status; + struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); + int ret; + u8 status; - error = rmi_read(rmi_dev, pdt->data_base_addr + pdt->page_start, - &device_status); - if (error) { - dev_err(&rmi_dev->dev, - "Failed to read device status: %d.\n", error); - return error; + if (pdt->function_number == 0x34 && pdt->function_version > 1) { + ret = rmi_read(rmi_dev, pdt->data_base_addr, &status); + if (ret) { + dev_err(&rmi_dev->dev, + "Failed to read F34 status: %d.\n", ret); + return ret; + } + + if (status & BIT(7)) + data->bootloader_mode = true; + } else if (pdt->function_number == 0x01) { + ret = rmi_read(rmi_dev, pdt->data_base_addr, &status); + if (ret) { + dev_err(&rmi_dev->dev, + "Failed to read F01 status: %d.\n", ret); + return ret; + } + + if (status & BIT(6)) + data->bootloader_mode = true; } - return RMI_F01_STATUS_BOOTLOADER(device_status); + return 0; } static int rmi_count_irqs(struct rmi_device *rmi_dev, void *ctx, const struct pdt_entry *pdt) { - struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); int *irq_count = ctx; + int ret; *irq_count += pdt->interrupt_source_count; - if (pdt->function_number == 0x01) { - data->f01_bootloader_mode = - rmi_check_bootloader_mode(rmi_dev, pdt); - if (data->f01_bootloader_mode) - dev_warn(&rmi_dev->dev, - "WARNING: RMI4 device is in bootloader mode!\n"); - } + + ret = rmi_check_bootloader_mode(rmi_dev, pdt); + if (ret < 0) + return ret; return RMI_SCAN_CONTINUE; } -static int rmi_initial_reset(struct rmi_device *rmi_dev, - void *ctx, const struct pdt_entry *pdt) +int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx, + const struct pdt_entry *pdt) { int error; @@ -720,6 +815,7 @@ static int rmi_initial_reset(struct rmi_device *rmi_dev, return RMI_SCAN_DONE; } + rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, "Sending reset\n"); error = rmi_write_block(rmi_dev, cmd_addr, &cmd_buf, 1); if (error) { dev_err(&rmi_dev->dev, @@ -776,6 +872,8 @@ static int rmi_create_function(struct rmi_device *rmi_dev, if (pdt->function_number == 0x01) data->f01_container = fn; + else if (pdt->function_number == 0x34) + data->f34_container = fn; list_add_tail(&fn->node, &data->function_list); @@ -786,23 +884,95 @@ err_put_fn: return error; } -int rmi_driver_suspend(struct rmi_device *rmi_dev) +void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake) { - int retval = 0; + struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); + struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); + int irq = pdata->irq; + int irq_flags; + int retval; + + mutex_lock(&data->enabled_mutex); + + if (data->enabled) + goto out; + + enable_irq(irq); + data->enabled = true; + if (clear_wake && device_may_wakeup(rmi_dev->xport->dev)) { + retval = disable_irq_wake(irq); + if (!retval) + dev_warn(&rmi_dev->dev, + "Failed to disable irq for wake: %d\n", + retval); + } + + /* + * Call rmi_process_interrupt_requests() after enabling irq, + * otherwise we may lose interrupt on edge-triggered systems. + */ + irq_flags = irq_get_trigger_type(pdata->irq); + if (irq_flags & IRQ_TYPE_EDGE_BOTH) + rmi_process_interrupt_requests(rmi_dev); + +out: + mutex_unlock(&data->enabled_mutex); +} + +void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake) +{ + struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); + struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); + struct rmi4_attn_data attn_data = {0}; + int irq = pdata->irq; + int retval, count; + + mutex_lock(&data->enabled_mutex); + + if (!data->enabled) + goto out; + + data->enabled = false; + disable_irq(irq); + if (enable_wake && device_may_wakeup(rmi_dev->xport->dev)) { + retval = enable_irq_wake(irq); + if (!retval) + dev_warn(&rmi_dev->dev, + "Failed to enable irq for wake: %d\n", + retval); + } + + /* make sure the fifo is clean */ + while (!kfifo_is_empty(&data->attn_fifo)) { + count = kfifo_get(&data->attn_fifo, &attn_data); + if (count) + kfree(attn_data.data); + } + +out: + mutex_unlock(&data->enabled_mutex); +} + +int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake) +{ + int retval; retval = rmi_suspend_functions(rmi_dev); if (retval) dev_warn(&rmi_dev->dev, "Failed to suspend functions: %d\n", retval); + rmi_disable_irq(rmi_dev, enable_wake); return retval; } EXPORT_SYMBOL_GPL(rmi_driver_suspend); -int rmi_driver_resume(struct rmi_device *rmi_dev) +int rmi_driver_resume(struct rmi_device *rmi_dev, bool clear_wake) { int retval; + rmi_enable_irq(rmi_dev, clear_wake); + retval = rmi_resume_functions(rmi_dev); if (retval) dev_warn(&rmi_dev->dev, "Failed to suspend functions: %d\n", @@ -816,6 +986,9 @@ static int rmi_driver_remove(struct device *dev) { struct rmi_device *rmi_dev = to_rmi_device(dev); + rmi_disable_irq(rmi_dev, false); + + rmi_f34_remove_sysfs(rmi_dev); rmi_free_function_list(rmi_dev); return 0; @@ -842,15 +1015,95 @@ static inline int rmi_driver_of_probe(struct device *dev, } #endif +int rmi_probe_interrupts(struct rmi_driver_data *data) +{ + struct rmi_device *rmi_dev = data->rmi_dev; + struct device *dev = &rmi_dev->dev; + int irq_count; + size_t size; + int retval; + + /* + * We need to count the IRQs and allocate their storage before scanning + * the PDT and creating the function entries, because adding a new + * function can trigger events that result in the IRQ related storage + * being accessed. + */ + rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Counting IRQs.\n", __func__); + irq_count = 0; + data->bootloader_mode = false; + + retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_count_irqs); + if (retval < 0) { + dev_err(dev, "IRQ counting failed with code %d.\n", retval); + return retval; + } + + if (data->bootloader_mode) + dev_warn(&rmi_dev->dev, "Device in bootloader mode.\n"); + + data->irq_count = irq_count; + data->num_of_irq_regs = (data->irq_count + 7) / 8; + + size = BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long); + data->irq_memory = devm_kzalloc(dev, size * 4, GFP_KERNEL); + if (!data->irq_memory) { + dev_err(dev, "Failed to allocate memory for irq masks.\n"); + return retval; + } + + data->irq_status = data->irq_memory + size * 0; + data->fn_irq_bits = data->irq_memory + size * 1; + data->current_irq_mask = data->irq_memory + size * 2; + data->new_irq_mask = data->irq_memory + size * 3; + + return retval; +} + +int rmi_init_functions(struct rmi_driver_data *data) +{ + struct rmi_device *rmi_dev = data->rmi_dev; + struct device *dev = &rmi_dev->dev; + int irq_count; + int retval; + + irq_count = 0; + rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Creating functions.\n", __func__); + retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_create_function); + if (retval < 0) { + dev_err(dev, "Function creation failed with code %d.\n", + retval); + goto err_destroy_functions; + } + + if (!data->f01_container) { + dev_err(dev, "Missing F01 container!\n"); + retval = -EINVAL; + goto err_destroy_functions; + } + + retval = rmi_read_block(rmi_dev, + data->f01_container->fd.control_base_addr + 1, + data->current_irq_mask, data->num_of_irq_regs); + if (retval < 0) { + dev_err(dev, "%s: Failed to read current IRQ mask.\n", + __func__); + goto err_destroy_functions; + } + + return 0; + +err_destroy_functions: + rmi_free_function_list(rmi_dev); + return retval; +} + static int rmi_driver_probe(struct device *dev) { struct rmi_driver *rmi_driver; struct rmi_driver_data *data; struct rmi_device_platform_data *pdata; struct rmi_device *rmi_dev; - size_t size; - void *irq_memory; - int irq_count; int retval; rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Starting probe.\n", @@ -916,35 +1169,12 @@ static int rmi_driver_probe(struct device *dev) PDT_PROPERTIES_LOCATION, retval); } - /* - * We need to count the IRQs and allocate their storage before scanning - * the PDT and creating the function entries, because adding a new - * function can trigger events that result in the IRQ related storage - * being accessed. - */ - rmi_dbg(RMI_DEBUG_CORE, dev, "Counting IRQs.\n"); - irq_count = 0; - retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_count_irqs); - if (retval < 0) { - dev_err(dev, "IRQ counting failed with code %d.\n", retval); - goto err; - } - data->irq_count = irq_count; - data->num_of_irq_regs = (data->irq_count + 7) / 8; - mutex_init(&data->irq_mutex); + mutex_init(&data->enabled_mutex); - size = BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long); - irq_memory = devm_kzalloc(dev, size * 4, GFP_KERNEL); - if (!irq_memory) { - dev_err(dev, "Failed to allocate memory for irq masks.\n"); + retval = rmi_probe_interrupts(data); + if (retval) goto err; - } - - data->irq_status = irq_memory + size * 0; - data->fn_irq_bits = irq_memory + size * 1; - data->current_irq_mask = irq_memory + size * 2; - data->new_irq_mask = irq_memory + size * 3; if (rmi_dev->xport->input) { /* @@ -961,36 +1191,20 @@ static int rmi_driver_probe(struct device *dev) dev_err(dev, "%s: Failed to allocate input device.\n", __func__); retval = -ENOMEM; - goto err_destroy_functions; + goto err; } rmi_driver_set_input_params(rmi_dev, data->input); data->input->phys = devm_kasprintf(dev, GFP_KERNEL, "%s/input0", dev_name(dev)); } - irq_count = 0; - rmi_dbg(RMI_DEBUG_CORE, dev, "Creating functions."); - retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_create_function); - if (retval < 0) { - dev_err(dev, "Function creation failed with code %d.\n", - retval); - goto err_destroy_functions; - } - - if (!data->f01_container) { - dev_err(dev, "Missing F01 container!\n"); - retval = -EINVAL; - goto err_destroy_functions; - } + retval = rmi_init_functions(data); + if (retval) + goto err; - retval = rmi_read_block(rmi_dev, - data->f01_container->fd.control_base_addr + 1, - data->current_irq_mask, data->num_of_irq_regs); - if (retval < 0) { - dev_err(dev, "%s: Failed to read current IRQ mask.\n", - __func__); - goto err_destroy_functions; - } + retval = rmi_f34_create_sysfs(rmi_dev); + if (retval) + goto err; if (data->input) { rmi_driver_set_input_name(rmi_dev, data->input); @@ -1003,9 +1217,13 @@ static int rmi_driver_probe(struct device *dev) } } + retval = rmi_irq_init(rmi_dev); + if (retval < 0) + goto err_destroy_functions; + if (data->f01_container->dev.driver) /* Driver already bound, so enable ATTN now. */ - return enable_sensor(rmi_dev); + return rmi_enable_sensor(rmi_dev); return 0; diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h index 8dfbebe9bf86..24f8f764d171 100644 --- a/drivers/input/rmi4/rmi_driver.h +++ b/drivers/input/rmi4/rmi_driver.h @@ -51,9 +51,6 @@ struct pdt_entry { u8 function_number; }; -int rmi_read_pdt_entry(struct rmi_device *rmi_dev, struct pdt_entry *entry, - u16 pdt_address); - #define RMI_REG_DESC_PRESENSE_BITS (32 * BITS_PER_BYTE) #define RMI_REG_DESC_SUBPACKET_BITS (37 * BITS_PER_BYTE) @@ -95,12 +92,40 @@ bool rmi_register_desc_has_subpacket(const struct rmi_register_desc_item *item, bool rmi_is_physical_driver(struct device_driver *); int rmi_register_physical_driver(void); void rmi_unregister_physical_driver(void); +void rmi_free_function_list(struct rmi_device *rmi_dev); +int rmi_enable_sensor(struct rmi_device *rmi_dev); +int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx, + int (*callback)(struct rmi_device *rmi_dev, void *ctx, + const struct pdt_entry *entry)); +int rmi_probe_interrupts(struct rmi_driver_data *data); +void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake); +void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake); +int rmi_init_functions(struct rmi_driver_data *data); +int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx, + const struct pdt_entry *pdt); char *rmi_f01_get_product_ID(struct rmi_function *fn); +#ifdef CONFIG_RMI4_F34 +int rmi_f34_create_sysfs(struct rmi_device *rmi_dev); +void rmi_f34_remove_sysfs(struct rmi_device *rmi_dev); +#else +static inline int rmi_f34_create_sysfs(struct rmi_device *rmi_dev) +{ + return 0; +} + +static inline void rmi_f34_remove_sysfs(struct rmi_device *rmi_dev) +{ +} +#endif /* CONFIG_RMI_F34 */ + extern struct rmi_function_handler rmi_f01_handler; +extern struct rmi_function_handler rmi_f03_handler; extern struct rmi_function_handler rmi_f11_handler; extern struct rmi_function_handler rmi_f12_handler; extern struct rmi_function_handler rmi_f30_handler; +extern struct rmi_function_handler rmi_f34_handler; extern struct rmi_function_handler rmi_f54_handler; +extern struct rmi_function_handler rmi_f55_handler; #endif diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c index b5d2dfc23bad..18baf4ceb940 100644 --- a/drivers/input/rmi4/rmi_f01.c +++ b/drivers/input/rmi4/rmi_f01.c @@ -62,6 +62,8 @@ struct f01_basic_properties { #define RMI_F01_STATUS_CODE(status) ((status) & 0x0f) /* The device has lost its configuration for some reason. */ #define RMI_F01_STATUS |