Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
01f7e67a
Commit
01f7e67a
authored
Jun 12, 2018
by
Dmitry Torokhov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'next' into for-linus
Prepare second round of input updates for 4.18 merge window.
parents
fc573af6
c258e84b
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
337 additions
and
112 deletions
+337
-112
Documentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt
...mentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt
+23
-0
drivers/input/input-mt.c
drivers/input/input-mt.c
+8
-4
drivers/input/keyboard/goldfish_events.c
drivers/input/keyboard/goldfish_events.c
+5
-4
drivers/input/misc/Kconfig
drivers/input/misc/Kconfig
+10
-0
drivers/input/misc/Makefile
drivers/input/misc/Makefile
+1
-0
drivers/input/misc/sc27xx-vibra.c
drivers/input/misc/sc27xx-vibra.c
+154
-0
drivers/input/rmi4/Kconfig
drivers/input/rmi4/Kconfig
+1
-0
drivers/input/rmi4/rmi_2d_sensor.c
drivers/input/rmi4/rmi_2d_sensor.c
+16
-18
drivers/input/rmi4/rmi_bus.c
drivers/input/rmi4/rmi_bus.c
+49
-1
drivers/input/rmi4/rmi_bus.h
drivers/input/rmi4/rmi_bus.h
+9
-1
drivers/input/rmi4/rmi_driver.c
drivers/input/rmi4/rmi_driver.c
+20
-32
drivers/input/rmi4/rmi_f01.c
drivers/input/rmi4/rmi_f01.c
+5
-5
drivers/input/rmi4/rmi_f03.c
drivers/input/rmi4/rmi_f03.c
+5
-4
drivers/input/rmi4/rmi_f11.c
drivers/input/rmi4/rmi_f11.c
+16
-26
drivers/input/rmi4/rmi_f12.c
drivers/input/rmi4/rmi_f12.c
+4
-4
drivers/input/rmi4/rmi_f30.c
drivers/input/rmi4/rmi_f30.c
+5
-4
drivers/input/rmi4/rmi_f34.c
drivers/input/rmi4/rmi_f34.c
+3
-2
drivers/input/rmi4/rmi_f54.c
drivers/input/rmi4/rmi_f54.c
+0
-6
include/linux/input/mt.h
include/linux/input/mt.h
+1
-1
include/linux/rmi.h
include/linux/rmi.h
+2
-0
No files found.
Documentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt
0 → 100644
View file @
01f7e67a
Spreadtrum SC27xx PMIC Vibrator
Required properties:
- compatible: should be "sprd,sc2731-vibrator".
- reg: address of vibrator control register.
Example :
sc2731_pmic: pmic@0 {
compatible = "sprd,sc2731";
reg = <0>;
spi-max-frequency = <26000000>;
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
#address-cells = <1>;
#size-cells = <0>;
vibrator@eb4 {
compatible = "sprd,sc2731-vibrator";
reg = <0xeb4>;
};
};
drivers/input/input-mt.c
View file @
01f7e67a
...
...
@@ -131,8 +131,10 @@ EXPORT_SYMBOL(input_mt_destroy_slots);
* inactive, or if the tool type is changed, a new tracking id is
* assigned to the slot. The tool type is only reported if the
* corresponding absbit field is set.
*
* Returns true if contact is active.
*/
void
input_mt_report_slot_state
(
struct
input_dev
*
dev
,
bool
input_mt_report_slot_state
(
struct
input_dev
*
dev
,
unsigned
int
tool_type
,
bool
active
)
{
struct
input_mt
*
mt
=
dev
->
mt
;
...
...
@@ -140,22 +142,24 @@ void input_mt_report_slot_state(struct input_dev *dev,
int
id
;
if
(
!
mt
)
return
;
return
false
;
slot
=
&
mt
->
slots
[
mt
->
slot
];
slot
->
frame
=
mt
->
frame
;
if
(
!
active
)
{
input_event
(
dev
,
EV_ABS
,
ABS_MT_TRACKING_ID
,
-
1
);
return
;
return
false
;
}
id
=
input_mt_get_value
(
slot
,
ABS_MT_TRACKING_ID
);
if
(
id
<
0
||
input_mt_get_value
(
slot
,
ABS_MT_TOOL_TYPE
)
!=
tool_type
)
if
(
id
<
0
)
id
=
input_mt_new_trkid
(
mt
);
input_event
(
dev
,
EV_ABS
,
ABS_MT_TRACKING_ID
,
id
);
input_event
(
dev
,
EV_ABS
,
ABS_MT_TOOL_TYPE
,
tool_type
);
return
true
;
}
EXPORT_SYMBOL
(
input_mt_report_slot_state
);
...
...
drivers/input/keyboard/goldfish_events.c
View file @
01f7e67a
...
...
@@ -45,7 +45,7 @@ struct event_dev {
static
irqreturn_t
events_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
event_dev
*
edev
=
dev_id
;
unsigned
type
,
code
,
value
;
unsigned
int
type
,
code
,
value
;
type
=
__raw_readl
(
edev
->
addr
+
REG_READ
);
code
=
__raw_readl
(
edev
->
addr
+
REG_READ
);
...
...
@@ -57,7 +57,7 @@ static irqreturn_t events_interrupt(int irq, void *dev_id)
}
static
void
events_import_bits
(
struct
event_dev
*
edev
,
unsigned
long
bits
[],
unsigned
type
,
size_t
count
)
unsigned
long
bits
[],
unsigned
int
type
,
size_t
count
)
{
void
__iomem
*
addr
=
edev
->
addr
;
int
i
,
j
;
...
...
@@ -99,6 +99,7 @@ static void events_import_abs_params(struct event_dev *edev)
for
(
j
=
0
;
j
<
ARRAY_SIZE
(
val
);
j
++
)
{
int
offset
=
(
i
*
ARRAY_SIZE
(
val
)
+
j
)
*
sizeof
(
u32
);
val
[
j
]
=
__raw_readl
(
edev
->
addr
+
REG_DATA
+
offset
);
}
...
...
@@ -112,7 +113,7 @@ static int events_probe(struct platform_device *pdev)
struct
input_dev
*
input_dev
;
struct
event_dev
*
edev
;
struct
resource
*
res
;
unsigned
keymapnamelen
;
unsigned
int
keymapnamelen
;
void
__iomem
*
addr
;
int
irq
;
int
i
;
...
...
@@ -150,7 +151,7 @@ static int events_probe(struct platform_device *pdev)
for
(
i
=
0
;
i
<
keymapnamelen
;
i
++
)
edev
->
name
[
i
]
=
__raw_readb
(
edev
->
addr
+
REG_DATA
+
i
);
pr_debug
(
"
events_probe() keymap=%s
\n
"
,
edev
->
name
);
pr_debug
(
"
%s: keymap=%s
\n
"
,
__func__
,
edev
->
name
);
input_dev
->
name
=
edev
->
name
;
input_dev
->
id
.
bustype
=
BUS_HOST
;
...
...
drivers/input/misc/Kconfig
View file @
01f7e67a
...
...
@@ -841,4 +841,14 @@ config INPUT_RAVE_SP_PWRBUTTON
To compile this driver as a module, choose M here: the
module will be called rave-sp-pwrbutton.
config INPUT_SC27XX_VIBRA
tristate "Spreadtrum sc27xx vibrator support"
depends on MFD_SC27XX_PMIC || COMPILE_TEST
select INPUT_FF_MEMLESS
help
This option enables support for Spreadtrum sc27xx vibrator driver.
To compile this driver as a module, choose M here. The module will
be called sc27xx_vibra.
endif
drivers/input/misc/Makefile
View file @
01f7e67a
...
...
@@ -66,6 +66,7 @@ obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o
obj-$(CONFIG_INPUT_AXP20X_PEK)
+=
axp20x-pek.o
obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)
+=
rotary_encoder.o
obj-$(CONFIG_INPUT_RK805_PWRKEY)
+=
rk805-pwrkey.o
obj-$(CONFIG_INPUT_SC27XX_VIBRA)
+=
sc27xx-vibra.o
obj-$(CONFIG_INPUT_SGI_BTNS)
+=
sgi_btns.o
obj-$(CONFIG_INPUT_SIRFSOC_ONKEY)
+=
sirfsoc-onkey.o
obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY)
+=
soc_button_array.o
...
...
drivers/input/misc/sc27xx-vibra.c
0 → 100644
View file @
01f7e67a
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Spreadtrum Communications Inc.
*/
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#define CUR_DRV_CAL_SEL GENMASK(13, 12)
#define SLP_LDOVIBR_PD_EN BIT(9)
#define LDO_VIBR_PD BIT(8)
struct
vibra_info
{
struct
input_dev
*
input_dev
;
struct
work_struct
play_work
;
struct
regmap
*
regmap
;
u32
base
;
u32
strength
;
bool
enabled
;
};
static
void
sc27xx_vibra_set
(
struct
vibra_info
*
info
,
bool
on
)
{
if
(
on
)
{
regmap_update_bits
(
info
->
regmap
,
info
->
base
,
LDO_VIBR_PD
,
0
);
regmap_update_bits
(
info
->
regmap
,
info
->
base
,
SLP_LDOVIBR_PD_EN
,
0
);
info
->
enabled
=
true
;
}
else
{
regmap_update_bits
(
info
->
regmap
,
info
->
base
,
LDO_VIBR_PD
,
LDO_VIBR_PD
);
regmap_update_bits
(
info
->
regmap
,
info
->
base
,
SLP_LDOVIBR_PD_EN
,
SLP_LDOVIBR_PD_EN
);
info
->
enabled
=
false
;
}
}
static
int
sc27xx_vibra_hw_init
(
struct
vibra_info
*
info
)
{
return
regmap_update_bits
(
info
->
regmap
,
info
->
base
,
CUR_DRV_CAL_SEL
,
0
);
}
static
void
sc27xx_vibra_play_work
(
struct
work_struct
*
work
)
{
struct
vibra_info
*
info
=
container_of
(
work
,
struct
vibra_info
,
play_work
);
if
(
info
->
strength
&&
!
info
->
enabled
)
sc27xx_vibra_set
(
info
,
true
);
else
if
(
info
->
strength
==
0
&&
info
->
enabled
)
sc27xx_vibra_set
(
info
,
false
);
}
static
int
sc27xx_vibra_play
(
struct
input_dev
*
input
,
void
*
data
,
struct
ff_effect
*
effect
)
{
struct
vibra_info
*
info
=
input_get_drvdata
(
input
);
info
->
strength
=
effect
->
u
.
rumble
.
weak_magnitude
;
schedule_work
(
&
info
->
play_work
);
return
0
;
}
static
void
sc27xx_vibra_close
(
struct
input_dev
*
input
)
{
struct
vibra_info
*
info
=
input_get_drvdata
(
input
);
cancel_work_sync
(
&
info
->
play_work
);
if
(
info
->
enabled
)
sc27xx_vibra_set
(
info
,
false
);
}
static
int
sc27xx_vibra_probe
(
struct
platform_device
*
pdev
)
{
struct
vibra_info
*
info
;
int
error
;
info
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
info
),
GFP_KERNEL
);
if
(
!
info
)
return
-
ENOMEM
;
info
->
regmap
=
dev_get_regmap
(
pdev
->
dev
.
parent
,
NULL
);
if
(
!
info
->
regmap
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get vibrator regmap.
\n
"
);
return
-
ENODEV
;
}
error
=
device_property_read_u32
(
&
pdev
->
dev
,
"reg"
,
&
info
->
base
);
if
(
error
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get vibrator base address.
\n
"
);
return
error
;
}
info
->
input_dev
=
devm_input_allocate_device
(
&
pdev
->
dev
);
if
(
!
info
->
input_dev
)
{
dev_err
(
&
pdev
->
dev
,
"failed to allocate input device.
\n
"
);
return
-
ENOMEM
;
}
info
->
input_dev
->
name
=
"sc27xx:vibrator"
;
info
->
input_dev
->
id
.
version
=
0
;
info
->
input_dev
->
close
=
sc27xx_vibra_close
;
input_set_drvdata
(
info
->
input_dev
,
info
);
input_set_capability
(
info
->
input_dev
,
EV_FF
,
FF_RUMBLE
);
INIT_WORK
(
&
info
->
play_work
,
sc27xx_vibra_play_work
);
info
->
enabled
=
false
;
error
=
sc27xx_vibra_hw_init
(
info
);
if
(
error
)
{
dev_err
(
&
pdev
->
dev
,
"failed to initialize the vibrator.
\n
"
);
return
error
;
}
error
=
input_ff_create_memless
(
info
->
input_dev
,
NULL
,
sc27xx_vibra_play
);
if
(
error
)
{
dev_err
(
&
pdev
->
dev
,
"failed to register vibrator to FF.
\n
"
);
return
error
;
}
error
=
input_register_device
(
info
->
input_dev
);
if
(
error
)
{
dev_err
(
&
pdev
->
dev
,
"failed to register input device.
\n
"
);
return
error
;
}
return
0
;
}
static
const
struct
of_device_id
sc27xx_vibra_of_match
[]
=
{
{
.
compatible
=
"sprd,sc2731-vibrator"
,
},
{}
};
MODULE_DEVICE_TABLE
(
of
,
sc27xx_vibra_of_match
);
static
struct
platform_driver
sc27xx_vibra_driver
=
{
.
driver
=
{
.
name
=
"sc27xx-vibrator"
,
.
of_match_table
=
sc27xx_vibra_of_match
,
},
.
probe
=
sc27xx_vibra_probe
,
};
module_platform_driver
(
sc27xx_vibra_driver
);
MODULE_DESCRIPTION
(
"Spreadtrum SC27xx Vibrator Driver"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_AUTHOR
(
"Xiaotong Lu <xiaotong.lu@spreadtrum.com>"
);
drivers/input/rmi4/Kconfig
View file @
01f7e67a
...
...
@@ -3,6 +3,7 @@
#
config RMI4_CORE
tristate "Synaptics RMI4 bus support"
select IRQ_DOMAIN
help
Say Y here if you want to support the Synaptics RMI4 bus. This is
required for all RMI4 device support.
...
...
drivers/input/rmi4/rmi_2d_sensor.c
View file @
01f7e67a
...
...
@@ -32,15 +32,15 @@ void rmi_2d_sensor_abs_process(struct rmi_2d_sensor *sensor,
if
(
obj
->
type
==
RMI_2D_OBJECT_NONE
)
return
;
if
(
axis_align
->
swap_axes
)
swap
(
obj
->
x
,
obj
->
y
);
if
(
axis_align
->
flip_x
)
obj
->
x
=
sensor
->
max_x
-
obj
->
x
;
if
(
axis_align
->
flip_y
)
obj
->
y
=
sensor
->
max_y
-
obj
->
y
;
if
(
axis_align
->
swap_axes
)
swap
(
obj
->
x
,
obj
->
y
);
/*
* Here checking if X offset or y offset are specified is
* redundant. We just add the offsets or clip the values.
...
...
@@ -120,15 +120,15 @@ void rmi_2d_sensor_rel_report(struct rmi_2d_sensor *sensor, int x, int y)
x
=
min
(
RMI_2D_REL_POS_MAX
,
max
(
RMI_2D_REL_POS_MIN
,
(
int
)
x
));
y
=
min
(
RMI_2D_REL_POS_MAX
,
max
(
RMI_2D_REL_POS_MIN
,
(
int
)
y
));
if
(
axis_align
->
swap_axes
)
swap
(
x
,
y
);
if
(
axis_align
->
flip_x
)
x
=
min
(
RMI_2D_REL_POS_MAX
,
-
x
);
if
(
axis_align
->
flip_y
)
y
=
min
(
RMI_2D_REL_POS_MAX
,
-
y
);
if
(
axis_align
->
swap_axes
)
swap
(
x
,
y
);
if
(
x
||
y
)
{
input_report_rel
(
sensor
->
input
,
REL_X
,
x
);
input_report_rel
(
sensor
->
input
,
REL_Y
,
y
);
...
...
@@ -141,17 +141,10 @@ static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
struct
input_dev
*
input
=
sensor
->
input
;
int
res_x
;
int
res_y
;
int
max_x
,
max_y
;
int
input_flags
=
0
;
if
(
sensor
->
report_abs
)
{
if
(
sensor
->
axis_align
.
swap_axes
)
{
swap
(
sensor
->
max_x
,
sensor
->
max_y
);
swap
(
sensor
->
axis_align
.
clip_x_low
,
sensor
->
axis_align
.
clip_y_low
);
swap
(
sensor
->
axis_align
.
clip_x_high
,
sensor
->
axis_align
.
clip_y_high
);
}
sensor
->
min_x
=
sensor
->
axis_align
.
clip_x_low
;
if
(
sensor
->
axis_align
.
clip_x_high
)
sensor
->
max_x
=
min
(
sensor
->
max_x
,
...
...
@@ -163,14 +156,19 @@ static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
sensor
->
axis_align
.
clip_y_high
);
set_bit
(
EV_ABS
,
input
->
evbit
);
input_set_abs_params
(
input
,
ABS_MT_POSITION_X
,
0
,
sensor
->
max_x
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_MT_POSITION_Y
,
0
,
sensor
->
max_y
,
0
,
0
);
max_x
=
sensor
->
max_x
;
max_y
=
sensor
->
max_y
;
if
(
sensor
->
axis_align
.
swap_axes
)
swap
(
max_x
,
max_y
);
input_set_abs_params
(
input
,
ABS_MT_POSITION_X
,
0
,
max_x
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_MT_POSITION_Y
,
0
,
max_y
,
0
,
0
);
if
(
sensor
->
x_mm
&&
sensor
->
y_mm
)
{
res_x
=
(
sensor
->
max_x
-
sensor
->
min_x
)
/
sensor
->
x_mm
;
res_y
=
(
sensor
->
max_y
-
sensor
->
min_y
)
/
sensor
->
y_mm
;
if
(
sensor
->
axis_align
.
swap_axes
)
swap
(
res_x
,
res_y
);
input_abs_set_res
(
input
,
ABS_X
,
res_x
);
input_abs_set_res
(
input
,
ABS_Y
,
res_y
);
...
...
drivers/input/rmi4/rmi_bus.c
View file @
01f7e67a
...
...
@@ -9,6 +9,8 @@
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/list.h>
#include <linux/pm.h>
#include <linux/rmi.h>
...
...
@@ -167,6 +169,39 @@ static inline void rmi_function_of_probe(struct rmi_function *fn)
{}
#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
)
{
struct
rmi_function
*
fn
=
to_rmi_function
(
dev
);
...
...
@@ -178,7 +213,14 @@ static int rmi_function_probe(struct device *dev)
if
(
handler
->
probe
)
{
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
;
...
...
@@ -230,12 +272,18 @@ int rmi_register_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
"
,
fn
->
fd
.
function_number
);
device_del
(
&
fn
->
dev
);
of_node_put
(
fn
->
dev
.
of_node
);
put_device
(
&
fn
->
dev
);
for
(
i
=
0
;
i
<
fn
->
num_of_irqs
;
i
++
)
irq_dispose_mapping
(
fn
->
irq
[
i
]);
}
/**
...
...
drivers/input/rmi4/rmi_bus.h
View file @
01f7e67a
...
...
@@ -14,6 +14,12 @@
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
* 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_mask: For convenience, can be used to mask IRQ bits off during ATTN
* interrupt handling.
* @irqs: assigned virq numbers (up to num_of_irqs)
*
* @node: entry in device's list of functions
*/
...
...
@@ -36,6 +43,7 @@ struct rmi_function {
struct
list_head
node
;
unsigned
int
num_of_irqs
;
int
irq
[
RMI_FN_MAX_IRQS
];
unsigned
int
irq_pos
;
unsigned
long
irq_mask
[];
};
...
...
@@ -76,7 +84,7 @@ struct rmi_function_handler {
void
(
*
remove
)(
struct
rmi_function
*
fn
);
int
(
*
config
)(
struct
rmi_function
*
fn
);
int
(
*
reset
)(
struct
rmi_function
*
fn
);
i
nt
(
*
attention
)(
struct
rmi_function
*
fn
,
unsigned
long
*
irq_bits
);
i
rqreturn_t
(
*
attention
)(
int
irq
,
void
*
ctx
);
int
(
*
suspend
)(
struct
rmi_function
*
fn
);
int
(
*
resume
)(
struct
rmi_function
*
fn
);
};
...
...
drivers/input/rmi4/rmi_driver.c
View file @
01f7e67a
...
...
@@ -21,6 +21,7 @@
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/irqdomain.h>
#include <uapi/linux/input.h>
#include <linux/rmi.h>
#include "rmi_bus.h"
...
...
@@ -127,28 +128,11 @@ static int rmi_driver_process_config_requests(struct rmi_device *rmi_dev)
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
)
{
struct
rmi_driver_data
*
data
=
dev_get_drvdata
(
&
rmi_dev
->
dev
);
struct
device
*
dev
=
&
rmi_dev
->
dev
;
struct
rmi_function
*
entry
;
int
i
;
int
error
;
if
(
!
data
)
...
...
@@ -173,16 +157,8 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
*/
mutex_unlock
(
&
data
->
irq_mutex
);
/*
* It would be nice to be able to use irq_chip to handle these
* 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
);
for_each_set_bit
(
i
,
data
->
irq_status
,
data
->
irq_count
)
handle_nested_irq
(
irq_find_mapping
(
data
->
irqdomain
,
i
));
if
(
data
->
input
)
input_sync
(
data
->
input
);
...
...
@@ -1000,9 +976,13 @@ EXPORT_SYMBOL_GPL(rmi_driver_resume);
static
int
rmi_driver_remove
(
struct
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
);
irq_domain_remove
(
data
->
irqdomain
);
data
->
irqdomain
=
NULL
;
rmi_f34_remove_sysfs
(
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
device
*
dev
=
&
rmi_dev
->
dev
;
int
irq_count
;
struct
fwnode_handle
*
fwnode
=
rmi_dev
->
xport
->
dev
->
fwnode
;
int
irq_count
=
0
;
size_t
size
;
int
retval
;
...
...
@@ -1045,7 +1026,6 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
* 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
);
...
...
@@ -1057,6 +1037,15 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
if
(
data
->
bootloader_mode
)
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
-
ENOMEM
;
}
data
->
irq_count
=
irq_count
;
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
device
*
dev
=
&
rmi_dev
->
dev
;
int
irq_count
;
int
irq_count
=
0
;
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
)
{
...
...
drivers/input/rmi4/rmi_f01.c
View file @
01f7e67a
...
...
@@ -681,9 +681,9 @@ static int rmi_f01_resume(struct rmi_function *fn)
return
0
;
}
static
int
rmi_f01_attention
(
struct
rmi_function
*
fn
,
unsigned
long
*
irq_bits
)
static
irqreturn_t
rmi_f01_attention
(
int
irq
,
void
*
ctx
)
{
struct
rmi_function
*
fn
=
ctx
;
struct
rmi_device
*
rmi_dev
=
fn
->
rmi_dev
;
int
error
;
u8
device_status
;
...
...
@@ -692,7 +692,7 @@ static int rmi_f01_attention(struct rmi_function *fn,
if
(
error
)
{
dev_err
(
&
fn
->
dev
,
"Failed to read device status: %d.
\n
"
,
error
);
return
error
;
return
IRQ_RETVAL
(
error
)
;
}
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
);
if
(
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
=
{
...
...
drivers/input/rmi4/rmi_f03.c
View file @
01f7e67a
...
...
@@ -244,8 +244,9 @@ static int rmi_f03_config(struct rmi_function *fn)
return
0
;
}
static
i
nt
rmi_f03_attention
(
struct
rmi_function
*
fn
,
unsigned
long
*
irq_bits
)
static
i
rqreturn_t
rmi_f03_attention
(
int
irq
,
void
*
ctx
)
{
struct
rmi_function
*
fn
=
ctx
;
struct
rmi_device
*
rmi_dev
=
fn
->
rmi_dev
;
struct
rmi_driver_data
*
drvdata
=
dev_get_drvdata
(
&
rmi_dev
->
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 */
if
(
drvdata
->
attn_data
.
size
<
ob_len
)
{
dev_warn
(
&
fn
->
dev
,
"F03 interrupted, but data is missing!
\n
"
);
return
0
;
return
IRQ_HANDLED
;
}
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
"
,
__func__
,
error
);
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
);
}
return
0
;
return
IRQ_HANDLED
;
}
static
void
rmi_f03_remove
(
struct
rmi_function
*
fn
)
...
...
drivers/input/rmi4/rmi_f11.c
View file @
01f7e67a
...
...
@@ -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
,
struct
rmi_2d_sensor
*
sensor
,
unsigned
long
*
irq_bits
,
int
num_irq_regs
,
int
size
)
struct
rmi_2d_sensor
*
sensor
,
int
size
)
{
const
u8
*
f_state
=
f11
->
data
.
f_state
;
u8
finger_state
;
...
...
@@ -581,12 +579,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
int
rel_fingers
;
int
abs_size
=
sensor
->
nbr_fingers
*
RMI_F11_ABS_BYTES
;
int
abs_bits
=
bitmap_and
(
f11
->
result_bits
,
irq_bits
,
f11
->
abs_mask
,
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
(
sensor
->
report_abs
)
{
if
(
abs_size
>
size
)
abs_fingers
=
size
/
RMI_F11_ABS_BYTES
;
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
],
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
* tracking to take place.
...
...
@@ -638,7 +619,16 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
}
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
)
...
...
@@ -1275,8 +1265,9 @@ static int rmi_f11_config(struct rmi_function *fn)
return
0
;
}
static
i
nt
rmi_f11_attention
(
struct
rmi_function
*
fn
,
unsigned
long
*
irq_bits
)
static
i
rqreturn_t
rmi_f11_attention
(
int
irq
,
void
*
ctx
)
{
struct
rmi_function
*
fn
=
ctx
;
struct
rmi_device
*
rmi_dev
=
fn
->
rmi_dev
;
struct
rmi_driver_data
*
drvdata
=
dev_get_drvdata
(
&
rmi_dev
->
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
,
f11
->
sensor
.
pkt_size
);
if
(
error
<
0
)
return
error
;
return
IRQ_RETVAL
(
error
)
;
}
rmi_f11_finger_handler
(
f11
,
&
f11
->
sensor
,
irq_bits
,
drvdata
->
num_of_irq_regs
,
valid_bytes
);
rmi_f11_finger_handler
(
f11
,
&
f11
->
sensor
,
valid_bytes
);
return
0
;
return
IRQ_HANDLED
;
}
static
int
rmi_f11_resume
(
struct
rmi_function
*
fn
)
...
...
drivers/input/rmi4/rmi_f12.c
View file @
01f7e67a
...
...
@@ -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
);
}
static
int
rmi_f12_attention
(
struct
rmi_function
*
fn
,
unsigned
long
*
irq_nr_regs
)
static
irqreturn_t
rmi_f12_attention
(
int
irq
,
void
*
ctx
)
{
int
retval
;
struct
rmi_function
*
fn
=
ctx
;
struct
rmi_device
*
rmi_dev
=
fn
->
rmi_dev
;
struct
rmi_driver_data
*
drvdata
=
dev_get_drvdata
(
&
rmi_dev
->
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
)
{
dev_err
(
&
fn
->
dev
,
"Failed to read object data. Code: %d.
\n
"
,
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
);
return
0
;
return
IRQ_HANDLED
;
}
static
int
rmi_f12_write_control_regs
(
struct
rmi_function
*
fn
)
...
...
drivers/input/rmi4/rmi_f30.c
View file @
01f7e67a
...
...
@@ -122,8 +122,9 @@ static void rmi_f30_report_button(struct rmi_function *fn,
}
}
static
i
nt
rmi_f30_attention
(
struct
rmi_function
*
fn
,
unsigned
long
*
irq_bits
)
static
i
rqreturn_t
rmi_f30_attention
(
int
irq
,
void
*
ctx
)
{
struct
rmi_function
*
fn
=
ctx
;
struct
f30_data
*
f30
=
dev_get_drvdata
(
&
fn
->
dev
);
struct
rmi_driver_data
*
drvdata
=
dev_get_drvdata
(
&
fn
->
rmi_dev
->
dev
);
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
)
{
dev_warn
(
&
fn
->
dev
,
"F30 interrupted, but data is missing
\n
"
);
return
0
;
return
IRQ_HANDLED
;
}
memcpy
(
f30
->
data_regs
,
drvdata
->
attn_data
.
data
,
f30
->
register_count
);
...
...
@@ -147,7 +148,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
dev_err
(
&
fn
->
dev
,
"%s: Failed to read F30 data registers: %d
\n
"
,
__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
);
}
return
0
;
return
IRQ_HANDLED
;
}
static
int
rmi_f30_config
(
struct
rmi_function
*
fn
)
...
...
drivers/input/rmi4/rmi_f34.c
View file @
01f7e67a
...
...
@@ -100,8 +100,9 @@ static int rmi_f34_command(struct f34_data *f34, u8 command,
return
0
;
}
static
i
nt
rmi_f34_attention
(
struct
rmi_function
*
fn
,
unsigned
long
*
irq_bits
)
static
i
rqreturn_t
rmi_f34_attention
(
int
irq
,
void
*
ctx
)
{
struct
rmi_function
*
fn
=
ctx
;
struct
f34_data
*
f34
=
dev_get_drvdata
(
&
fn
->
dev
);
int
ret
;
u8
status
;
...
...
@@ -126,7 +127,7 @@ static int rmi_f34_attention(struct rmi_function *fn, unsigned long *irq_bits)
complete
(
&
f34
->
v7
.
cmd_done
);
}
return
0
;
return
IRQ_HANDLED
;
}
static
int
rmi_f34_write_blocks
(
struct
f34_data
*
f34
,
const
void
*
data
,
...
...
drivers/input/rmi4/rmi_f54.c
View file @
01f7e67a
...
...
@@ -610,11 +610,6 @@ static void rmi_f54_work(struct work_struct *work)
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
)
{
struct
rmi_driver
*
drv
=
fn
->
rmi_dev
->
driver
;
...
...
@@ -756,6 +751,5 @@ struct rmi_function_handler rmi_f54_handler = {
.
func
=
0x54
,
.
probe
=
rmi_f54_probe
,
.
config
=
rmi_f54_config
,
.
attention
=
rmi_f54_attention
,
.
remove
=
rmi_f54_remove
,
};
include/linux/input/mt.h
View file @
01f7e67a
...
...
@@ -100,7 +100,7 @@ static inline bool input_is_mt_axis(int axis)
return
axis
==
ABS_MT_SLOT
||
input_is_mt_value
(
axis
);
}
void
input_mt_report_slot_state
(
struct
input_dev
*
dev
,
bool
input_mt_report_slot_state
(
struct
input_dev
*
dev
,
unsigned
int
tool_type
,
bool
active
);
void
input_mt_report_finger_count
(
struct
input_dev
*
dev
,
int
count
);
...
...
include/linux/rmi.h
View file @
01f7e67a
...
...
@@ -354,6 +354,8 @@ struct rmi_driver_data {
struct
mutex
irq_mutex
;
struct
input_dev
*
input
;
struct
irq_domain
*
irqdomain
;
u8
pdt_props
;
u8
num_rx_electrodes
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment