forked from Minki/linux
Input: synaptics-rmi4 - convert irq distribution to irq_domain
Convert the RMI driver to use the standard mechanism for distributing IRQs to the various functions. Tested on: * S7300 (F11, F34, F54) * S7817 (F12, F34, F54) Signed-off-by: Nick Dyer <nick@shmanahar.org> Acked-by: Christopher Heiny <cheiny@synaptics.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
parent
8f6a652a8c
commit
24d28e4f12
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
config RMI4_CORE
|
config RMI4_CORE
|
||||||
tristate "Synaptics RMI4 bus support"
|
tristate "Synaptics RMI4 bus support"
|
||||||
|
select IRQ_DOMAIN
|
||||||
help
|
help
|
||||||
Say Y here if you want to support the Synaptics RMI4 bus. This is
|
Say Y here if you want to support the Synaptics RMI4 bus. This is
|
||||||
required for all RMI4 device support.
|
required for all RMI4 device support.
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <linux/irqdomain.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/rmi.h>
|
#include <linux/rmi.h>
|
||||||
@ -167,6 +169,39 @@ static inline void rmi_function_of_probe(struct rmi_function *fn)
|
|||||||
{}
|
{}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static struct irq_chip rmi_irq_chip = {
|
||||||
|
.name = "rmi4",
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rmi_create_function_irq(struct rmi_function *fn,
|
||||||
|
struct rmi_function_handler *handler)
|
||||||
|
{
|
||||||
|
struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
|
||||||
|
int i, error;
|
||||||
|
|
||||||
|
for (i = 0; i < fn->num_of_irqs; i++) {
|
||||||
|
set_bit(fn->irq_pos + i, fn->irq_mask);
|
||||||
|
|
||||||
|
fn->irq[i] = irq_create_mapping(drvdata->irqdomain,
|
||||||
|
fn->irq_pos + i);
|
||||||
|
|
||||||
|
irq_set_chip_data(fn->irq[i], fn);
|
||||||
|
irq_set_chip_and_handler(fn->irq[i], &rmi_irq_chip,
|
||||||
|
handle_simple_irq);
|
||||||
|
irq_set_nested_thread(fn->irq[i], 1);
|
||||||
|
|
||||||
|
error = devm_request_threaded_irq(&fn->dev, fn->irq[i], NULL,
|
||||||
|
handler->attention, IRQF_ONESHOT,
|
||||||
|
dev_name(&fn->dev), fn);
|
||||||
|
if (error) {
|
||||||
|
dev_err(&fn->dev, "Error %d registering IRQ\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int rmi_function_probe(struct device *dev)
|
static int rmi_function_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
struct rmi_function *fn = to_rmi_function(dev);
|
struct rmi_function *fn = to_rmi_function(dev);
|
||||||
@ -178,7 +213,14 @@ static int rmi_function_probe(struct device *dev)
|
|||||||
|
|
||||||
if (handler->probe) {
|
if (handler->probe) {
|
||||||
error = handler->probe(fn);
|
error = handler->probe(fn);
|
||||||
return error;
|
if (error)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fn->num_of_irqs && handler->attention) {
|
||||||
|
error = rmi_create_function_irq(fn, handler);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -230,12 +272,18 @@ err_put_device:
|
|||||||
|
|
||||||
void rmi_unregister_function(struct rmi_function *fn)
|
void rmi_unregister_function(struct rmi_function *fn)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
rmi_dbg(RMI_DEBUG_CORE, &fn->dev, "Unregistering F%02X.\n",
|
rmi_dbg(RMI_DEBUG_CORE, &fn->dev, "Unregistering F%02X.\n",
|
||||||
fn->fd.function_number);
|
fn->fd.function_number);
|
||||||
|
|
||||||
device_del(&fn->dev);
|
device_del(&fn->dev);
|
||||||
of_node_put(fn->dev.of_node);
|
of_node_put(fn->dev.of_node);
|
||||||
put_device(&fn->dev);
|
put_device(&fn->dev);
|
||||||
|
|
||||||
|
for (i = 0; i < fn->num_of_irqs; i++)
|
||||||
|
irq_dispose_mapping(fn->irq[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,6 +14,12 @@
|
|||||||
|
|
||||||
struct rmi_device;
|
struct rmi_device;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt source count in the function descriptor can represent up to
|
||||||
|
* 6 interrupt sources in the normal manner.
|
||||||
|
*/
|
||||||
|
#define RMI_FN_MAX_IRQS 6
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct rmi_function - represents the implementation of an RMI4
|
* struct rmi_function - represents the implementation of an RMI4
|
||||||
* function for a particular device (basically, a driver for that RMI4 function)
|
* function for a particular device (basically, a driver for that RMI4 function)
|
||||||
@ -26,6 +32,7 @@ struct rmi_device;
|
|||||||
* @irq_pos: The position in the irq bitfield this function holds
|
* @irq_pos: The position in the irq bitfield this function holds
|
||||||
* @irq_mask: For convenience, can be used to mask IRQ bits off during ATTN
|
* @irq_mask: For convenience, can be used to mask IRQ bits off during ATTN
|
||||||
* interrupt handling.
|
* interrupt handling.
|
||||||
|
* @irqs: assigned virq numbers (up to num_of_irqs)
|
||||||
*
|
*
|
||||||
* @node: entry in device's list of functions
|
* @node: entry in device's list of functions
|
||||||
*/
|
*/
|
||||||
@ -36,6 +43,7 @@ struct rmi_function {
|
|||||||
struct list_head node;
|
struct list_head node;
|
||||||
|
|
||||||
unsigned int num_of_irqs;
|
unsigned int num_of_irqs;
|
||||||
|
int irq[RMI_FN_MAX_IRQS];
|
||||||
unsigned int irq_pos;
|
unsigned int irq_pos;
|
||||||
unsigned long irq_mask[];
|
unsigned long irq_mask[];
|
||||||
};
|
};
|
||||||
@ -76,7 +84,7 @@ struct rmi_function_handler {
|
|||||||
void (*remove)(struct rmi_function *fn);
|
void (*remove)(struct rmi_function *fn);
|
||||||
int (*config)(struct rmi_function *fn);
|
int (*config)(struct rmi_function *fn);
|
||||||
int (*reset)(struct rmi_function *fn);
|
int (*reset)(struct rmi_function *fn);
|
||||||
int (*attention)(struct rmi_function *fn, unsigned long *irq_bits);
|
irqreturn_t (*attention)(int irq, void *ctx);
|
||||||
int (*suspend)(struct rmi_function *fn);
|
int (*suspend)(struct rmi_function *fn);
|
||||||
int (*resume)(struct rmi_function *fn);
|
int (*resume)(struct rmi_function *fn);
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
#include <linux/irqdomain.h>
|
||||||
#include <uapi/linux/input.h>
|
#include <uapi/linux/input.h>
|
||||||
#include <linux/rmi.h>
|
#include <linux/rmi.h>
|
||||||
#include "rmi_bus.h"
|
#include "rmi_bus.h"
|
||||||
@ -127,28 +128,11 @@ static int rmi_driver_process_config_requests(struct rmi_device *rmi_dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_one_interrupt(struct rmi_driver_data *data,
|
|
||||||
struct rmi_function *fn)
|
|
||||||
{
|
|
||||||
struct rmi_function_handler *fh;
|
|
||||||
|
|
||||||
if (!fn || !fn->dev.driver)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fh = to_rmi_function_handler(fn->dev.driver);
|
|
||||||
if (fh->attention) {
|
|
||||||
bitmap_and(data->fn_irq_bits, data->irq_status, fn->irq_mask,
|
|
||||||
data->irq_count);
|
|
||||||
if (!bitmap_empty(data->fn_irq_bits, data->irq_count))
|
|
||||||
fh->attention(fn, data->fn_irq_bits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static 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 rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
|
||||||
struct device *dev = &rmi_dev->dev;
|
struct device *dev = &rmi_dev->dev;
|
||||||
struct rmi_function *entry;
|
int i;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
@ -173,16 +157,8 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
|
|||||||
*/
|
*/
|
||||||
mutex_unlock(&data->irq_mutex);
|
mutex_unlock(&data->irq_mutex);
|
||||||
|
|
||||||
/*
|
for_each_set_bit(i, data->irq_status, data->irq_count)
|
||||||
* It would be nice to be able to use irq_chip to handle these
|
handle_nested_irq(irq_find_mapping(data->irqdomain, i));
|
||||||
* nested IRQs. Unfortunately, most of the current customers for
|
|
||||||
* this driver are using older kernels (3.0.x) that don't support
|
|
||||||
* the features required for that. Once they've shifted to more
|
|
||||||
* recent kernels (say, 3.3 and higher), this should be switched to
|
|
||||||
* use irq_chip.
|
|
||||||
*/
|
|
||||||
list_for_each_entry(entry, &data->function_list, node)
|
|
||||||
process_one_interrupt(data, entry);
|
|
||||||
|
|
||||||
if (data->input)
|
if (data->input)
|
||||||
input_sync(data->input);
|
input_sync(data->input);
|
||||||
@ -1000,9 +976,13 @@ EXPORT_SYMBOL_GPL(rmi_driver_resume);
|
|||||||
static int rmi_driver_remove(struct device *dev)
|
static int rmi_driver_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
struct rmi_device *rmi_dev = to_rmi_device(dev);
|
struct rmi_device *rmi_dev = to_rmi_device(dev);
|
||||||
|
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
|
||||||
|
|
||||||
rmi_disable_irq(rmi_dev, false);
|
rmi_disable_irq(rmi_dev, false);
|
||||||
|
|
||||||
|
irq_domain_remove(data->irqdomain);
|
||||||
|
data->irqdomain = NULL;
|
||||||
|
|
||||||
rmi_f34_remove_sysfs(rmi_dev);
|
rmi_f34_remove_sysfs(rmi_dev);
|
||||||
rmi_free_function_list(rmi_dev);
|
rmi_free_function_list(rmi_dev);
|
||||||
|
|
||||||
@ -1034,7 +1014,8 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
|
|||||||
{
|
{
|
||||||
struct rmi_device *rmi_dev = data->rmi_dev;
|
struct rmi_device *rmi_dev = data->rmi_dev;
|
||||||
struct device *dev = &rmi_dev->dev;
|
struct device *dev = &rmi_dev->dev;
|
||||||
int irq_count;
|
struct fwnode_handle *fwnode = rmi_dev->xport->dev->fwnode;
|
||||||
|
int irq_count = 0;
|
||||||
size_t size;
|
size_t size;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
@ -1045,7 +1026,6 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
|
|||||||
* being accessed.
|
* being accessed.
|
||||||
*/
|
*/
|
||||||
rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Counting IRQs.\n", __func__);
|
rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Counting IRQs.\n", __func__);
|
||||||
irq_count = 0;
|
|
||||||
data->bootloader_mode = false;
|
data->bootloader_mode = false;
|
||||||
|
|
||||||
retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_count_irqs);
|
retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_count_irqs);
|
||||||
@ -1057,6 +1037,15 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
|
|||||||
if (data->bootloader_mode)
|
if (data->bootloader_mode)
|
||||||
dev_warn(dev, "Device in bootloader mode.\n");
|
dev_warn(dev, "Device in bootloader mode.\n");
|
||||||
|
|
||||||
|
/* Allocate and register a linear revmap irq_domain */
|
||||||
|
data->irqdomain = irq_domain_create_linear(fwnode, irq_count,
|
||||||
|
&irq_domain_simple_ops,
|
||||||
|
data);
|
||||||
|
if (!data->irqdomain) {
|
||||||
|
dev_err(&rmi_dev->dev, "Failed to create IRQ domain\n");
|
||||||
|
return PTR_ERR(data->irqdomain);
|
||||||
|
}
|
||||||
|
|
||||||
data->irq_count = irq_count;
|
data->irq_count = irq_count;
|
||||||
data->num_of_irq_regs = (data->irq_count + 7) / 8;
|
data->num_of_irq_regs = (data->irq_count + 7) / 8;
|
||||||
|
|
||||||
@ -1079,10 +1068,9 @@ int rmi_init_functions(struct rmi_driver_data *data)
|
|||||||
{
|
{
|
||||||
struct rmi_device *rmi_dev = data->rmi_dev;
|
struct rmi_device *rmi_dev = data->rmi_dev;
|
||||||
struct device *dev = &rmi_dev->dev;
|
struct device *dev = &rmi_dev->dev;
|
||||||
int irq_count;
|
int irq_count = 0;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
irq_count = 0;
|
|
||||||
rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Creating functions.\n", __func__);
|
rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Creating functions.\n", __func__);
|
||||||
retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_create_function);
|
retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_create_function);
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
|
@ -681,9 +681,9 @@ static int rmi_f01_resume(struct rmi_function *fn)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_f01_attention(struct rmi_function *fn,
|
static irqreturn_t rmi_f01_attention(int irq, void *ctx)
|
||||||
unsigned long *irq_bits)
|
|
||||||
{
|
{
|
||||||
|
struct rmi_function *fn = ctx;
|
||||||
struct rmi_device *rmi_dev = fn->rmi_dev;
|
struct rmi_device *rmi_dev = fn->rmi_dev;
|
||||||
int error;
|
int error;
|
||||||
u8 device_status;
|
u8 device_status;
|
||||||
@ -692,7 +692,7 @@ static int rmi_f01_attention(struct rmi_function *fn,
|
|||||||
if (error) {
|
if (error) {
|
||||||
dev_err(&fn->dev,
|
dev_err(&fn->dev,
|
||||||
"Failed to read device status: %d.\n", error);
|
"Failed to read device status: %d.\n", error);
|
||||||
return error;
|
return IRQ_RETVAL(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RMI_F01_STATUS_BOOTLOADER(device_status))
|
if (RMI_F01_STATUS_BOOTLOADER(device_status))
|
||||||
@ -704,11 +704,11 @@ static int rmi_f01_attention(struct rmi_function *fn,
|
|||||||
error = rmi_dev->driver->reset_handler(rmi_dev);
|
error = rmi_dev->driver->reset_handler(rmi_dev);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(&fn->dev, "Device reset failed: %d\n", error);
|
dev_err(&fn->dev, "Device reset failed: %d\n", error);
|
||||||
return error;
|
return IRQ_RETVAL(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rmi_function_handler rmi_f01_handler = {
|
struct rmi_function_handler rmi_f01_handler = {
|
||||||
|
@ -244,8 +244,9 @@ static int rmi_f03_config(struct rmi_function *fn)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
static irqreturn_t rmi_f03_attention(int irq, void *ctx)
|
||||||
{
|
{
|
||||||
|
struct rmi_function *fn = ctx;
|
||||||
struct rmi_device *rmi_dev = fn->rmi_dev;
|
struct rmi_device *rmi_dev = fn->rmi_dev;
|
||||||
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
|
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
|
||||||
struct f03_data *f03 = dev_get_drvdata(&fn->dev);
|
struct f03_data *f03 = dev_get_drvdata(&fn->dev);
|
||||||
@ -262,7 +263,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
|||||||
/* First grab the data passed by the transport device */
|
/* First grab the data passed by the transport device */
|
||||||
if (drvdata->attn_data.size < ob_len) {
|
if (drvdata->attn_data.size < ob_len) {
|
||||||
dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n");
|
dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n");
|
||||||
return 0;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(obs, drvdata->attn_data.data, ob_len);
|
memcpy(obs, drvdata->attn_data.data, ob_len);
|
||||||
@ -277,7 +278,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
|||||||
"%s: Failed to read F03 output buffers: %d\n",
|
"%s: Failed to read F03 output buffers: %d\n",
|
||||||
__func__, error);
|
__func__, error);
|
||||||
serio_interrupt(f03->serio, 0, SERIO_TIMEOUT);
|
serio_interrupt(f03->serio, 0, SERIO_TIMEOUT);
|
||||||
return error;
|
return IRQ_RETVAL(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +304,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
|||||||
serio_interrupt(f03->serio, ob_data, serio_flags);
|
serio_interrupt(f03->serio, ob_data, serio_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rmi_f03_remove(struct rmi_function *fn)
|
static void rmi_f03_remove(struct rmi_function *fn)
|
||||||
|
@ -570,9 +570,7 @@ static inline u8 rmi_f11_parse_finger_state(const u8 *f_state, u8 n_finger)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void rmi_f11_finger_handler(struct f11_data *f11,
|
static void rmi_f11_finger_handler(struct f11_data *f11,
|
||||||
struct rmi_2d_sensor *sensor,
|
struct rmi_2d_sensor *sensor, int size)
|
||||||
unsigned long *irq_bits, int num_irq_regs,
|
|
||||||
int size)
|
|
||||||
{
|
{
|
||||||
const u8 *f_state = f11->data.f_state;
|
const u8 *f_state = f11->data.f_state;
|
||||||
u8 finger_state;
|
u8 finger_state;
|
||||||
@ -581,12 +579,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
|
|||||||
int rel_fingers;
|
int rel_fingers;
|
||||||
int abs_size = sensor->nbr_fingers * RMI_F11_ABS_BYTES;
|
int abs_size = sensor->nbr_fingers * RMI_F11_ABS_BYTES;
|
||||||
|
|
||||||
int abs_bits = bitmap_and(f11->result_bits, irq_bits, f11->abs_mask,
|
if (sensor->report_abs) {
|
||||||
num_irq_regs * 8);
|
|
||||||
int rel_bits = bitmap_and(f11->result_bits, irq_bits, f11->rel_mask,
|
|
||||||
num_irq_regs * 8);
|
|
||||||
|
|
||||||
if (abs_bits) {
|
|
||||||
if (abs_size > size)
|
if (abs_size > size)
|
||||||
abs_fingers = size / RMI_F11_ABS_BYTES;
|
abs_fingers = size / RMI_F11_ABS_BYTES;
|
||||||
else
|
else
|
||||||
@ -604,19 +597,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
|
|||||||
rmi_f11_abs_pos_process(f11, sensor, &sensor->objs[i],
|
rmi_f11_abs_pos_process(f11, sensor, &sensor->objs[i],
|
||||||
finger_state, i);
|
finger_state, i);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (rel_bits) {
|
|
||||||
if ((abs_size + sensor->nbr_fingers * RMI_F11_REL_BYTES) > size)
|
|
||||||
rel_fingers = (size - abs_size) / RMI_F11_REL_BYTES;
|
|
||||||
else
|
|
||||||
rel_fingers = sensor->nbr_fingers;
|
|
||||||
|
|
||||||
for (i = 0; i < rel_fingers; i++)
|
|
||||||
rmi_f11_rel_pos_report(f11, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (abs_bits) {
|
|
||||||
/*
|
/*
|
||||||
* the absolute part is made in 2 parts to allow the kernel
|
* the absolute part is made in 2 parts to allow the kernel
|
||||||
* tracking to take place.
|
* tracking to take place.
|
||||||
@ -638,7 +619,16 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
|
|||||||
}
|
}
|
||||||
|
|
||||||
input_mt_sync_frame(sensor->input);
|
input_mt_sync_frame(sensor->input);
|
||||||
|
} else if (sensor->report_rel) {
|
||||||
|
if ((abs_size + sensor->nbr_fingers * RMI_F11_REL_BYTES) > size)
|
||||||
|
rel_fingers = (size - abs_size) / RMI_F11_REL_BYTES;
|
||||||
|
else
|
||||||
|
rel_fingers = sensor->nbr_fingers;
|
||||||
|
|
||||||
|
for (i = 0; i < rel_fingers; i++)
|
||||||
|
rmi_f11_rel_pos_report(f11, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f11_2d_construct_data(struct f11_data *f11)
|
static int f11_2d_construct_data(struct f11_data *f11)
|
||||||
@ -1275,8 +1265,9 @@ static int rmi_f11_config(struct rmi_function *fn)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
static irqreturn_t rmi_f11_attention(int irq, void *ctx)
|
||||||
{
|
{
|
||||||
|
struct rmi_function *fn = ctx;
|
||||||
struct rmi_device *rmi_dev = fn->rmi_dev;
|
struct rmi_device *rmi_dev = fn->rmi_dev;
|
||||||
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
|
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
|
||||||
struct f11_data *f11 = dev_get_drvdata(&fn->dev);
|
struct f11_data *f11 = dev_get_drvdata(&fn->dev);
|
||||||
@ -1302,13 +1293,12 @@ static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
|||||||
data_base_addr, f11->sensor.data_pkt,
|
data_base_addr, f11->sensor.data_pkt,
|
||||||
f11->sensor.pkt_size);
|
f11->sensor.pkt_size);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
return error;
|
return IRQ_RETVAL(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
rmi_f11_finger_handler(f11, &f11->sensor, irq_bits,
|
rmi_f11_finger_handler(f11, &f11->sensor, valid_bytes);
|
||||||
drvdata->num_of_irq_regs, valid_bytes);
|
|
||||||
|
|
||||||
return 0;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_f11_resume(struct rmi_function *fn)
|
static int rmi_f11_resume(struct rmi_function *fn)
|
||||||
|
@ -197,10 +197,10 @@ static void rmi_f12_process_objects(struct f12_data *f12, u8 *data1, int size)
|
|||||||
rmi_2d_sensor_abs_report(sensor, &sensor->objs[i], i);
|
rmi_2d_sensor_abs_report(sensor, &sensor->objs[i], i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_f12_attention(struct rmi_function *fn,
|
static irqreturn_t rmi_f12_attention(int irq, void *ctx)
|
||||||
unsigned long *irq_nr_regs)
|
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
struct rmi_function *fn = ctx;
|
||||||
struct rmi_device *rmi_dev = fn->rmi_dev;
|
struct rmi_device *rmi_dev = fn->rmi_dev;
|
||||||
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
|
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
|
||||||
struct f12_data *f12 = dev_get_drvdata(&fn->dev);
|
struct f12_data *f12 = dev_get_drvdata(&fn->dev);
|
||||||
@ -222,7 +222,7 @@ static int rmi_f12_attention(struct rmi_function *fn,
|
|||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
dev_err(&fn->dev, "Failed to read object data. Code: %d.\n",
|
dev_err(&fn->dev, "Failed to read object data. Code: %d.\n",
|
||||||
retval);
|
retval);
|
||||||
return retval;
|
return IRQ_RETVAL(retval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ static int rmi_f12_attention(struct rmi_function *fn,
|
|||||||
|
|
||||||
input_mt_sync_frame(sensor->input);
|
input_mt_sync_frame(sensor->input);
|
||||||
|
|
||||||
return 0;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_f12_write_control_regs(struct rmi_function *fn)
|
static int rmi_f12_write_control_regs(struct rmi_function *fn)
|
||||||
|
@ -122,8 +122,9 @@ static void rmi_f30_report_button(struct rmi_function *fn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
static irqreturn_t rmi_f30_attention(int irq, void *ctx)
|
||||||
{
|
{
|
||||||
|
struct rmi_function *fn = ctx;
|
||||||
struct f30_data *f30 = dev_get_drvdata(&fn->dev);
|
struct f30_data *f30 = dev_get_drvdata(&fn->dev);
|
||||||
struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
|
struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
|
||||||
int error;
|
int error;
|
||||||
@ -134,7 +135,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
|||||||
if (drvdata->attn_data.size < f30->register_count) {
|
if (drvdata->attn_data.size < f30->register_count) {
|
||||||
dev_warn(&fn->dev,
|
dev_warn(&fn->dev,
|
||||||
"F30 interrupted, but data is missing\n");
|
"F30 interrupted, but data is missing\n");
|
||||||
return 0;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
memcpy(f30->data_regs, drvdata->attn_data.data,
|
memcpy(f30->data_regs, drvdata->attn_data.data,
|
||||||
f30->register_count);
|
f30->register_count);
|
||||||
@ -147,7 +148,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
|||||||
dev_err(&fn->dev,
|
dev_err(&fn->dev,
|
||||||
"%s: Failed to read F30 data registers: %d\n",
|
"%s: Failed to read F30 data registers: %d\n",
|
||||||
__func__, error);
|
__func__, error);
|
||||||
return error;
|
return IRQ_RETVAL(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +160,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
|||||||
rmi_f03_commit_buttons(f30->f03);
|
rmi_f03_commit_buttons(f30->f03);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_f30_config(struct rmi_function *fn)
|
static int rmi_f30_config(struct rmi_function *fn)
|
||||||
|
@ -100,8 +100,9 @@ static int rmi_f34_command(struct f34_data *f34, u8 command,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_f34_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
static irqreturn_t rmi_f34_attention(int irq, void *ctx)
|
||||||
{
|
{
|
||||||
|
struct rmi_function *fn = ctx;
|
||||||
struct f34_data *f34 = dev_get_drvdata(&fn->dev);
|
struct f34_data *f34 = dev_get_drvdata(&fn->dev);
|
||||||
int ret;
|
int ret;
|
||||||
u8 status;
|
u8 status;
|
||||||
@ -126,7 +127,7 @@ static int rmi_f34_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
|||||||
complete(&f34->v7.cmd_done);
|
complete(&f34->v7.cmd_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_f34_write_blocks(struct f34_data *f34, const void *data,
|
static int rmi_f34_write_blocks(struct f34_data *f34, const void *data,
|
||||||
|
@ -610,11 +610,6 @@ error:
|
|||||||
mutex_unlock(&f54->data_mutex);
|
mutex_unlock(&f54->data_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_f54_attention(struct rmi_function *fn, unsigned long *irqbits)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rmi_f54_config(struct rmi_function *fn)
|
static int rmi_f54_config(struct rmi_function *fn)
|
||||||
{
|
{
|
||||||
struct rmi_driver *drv = fn->rmi_dev->driver;
|
struct rmi_driver *drv = fn->rmi_dev->driver;
|
||||||
@ -756,6 +751,5 @@ struct rmi_function_handler rmi_f54_handler = {
|
|||||||
.func = 0x54,
|
.func = 0x54,
|
||||||
.probe = rmi_f54_probe,
|
.probe = rmi_f54_probe,
|
||||||
.config = rmi_f54_config,
|
.config = rmi_f54_config,
|
||||||
.attention = rmi_f54_attention,
|
|
||||||
.remove = rmi_f54_remove,
|
.remove = rmi_f54_remove,
|
||||||
};
|
};
|
||||||
|
@ -354,6 +354,8 @@ struct rmi_driver_data {
|
|||||||
struct mutex irq_mutex;
|
struct mutex irq_mutex;
|
||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
|
|
||||||
|
struct irq_domain *irqdomain;
|
||||||
|
|
||||||
u8 pdt_props;
|
u8 pdt_props;
|
||||||
|
|
||||||
u8 num_rx_electrodes;
|
u8 num_rx_electrodes;
|
||||||
|
Loading…
Reference in New Issue
Block a user