Merge tag 'input-for-v7.2-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input updates from Dmitry Torokhov:

 - A new driver for Wacom W9000-series penabled touchscreens

 - Updates to STM FTS driver adding support for reset line and preparing
   the driver for STMFTS5 support

 - Updates to RMI4 and IMS PCU drivers hardening the code

 - Support for half-duplex mode restored in ADS7846 driver

 - Updates to driver's device_id tables to use named initializers

 - Removal of no longer used PCAP keys and touchscreen drivers (support
   for the ezx series of phones was removed in 2022)

 - Removal of xilinx_ps2 driver which is no longer used either

 - Updates to userio to allow setting up additional serio port
   characteristics (such as id, extra and proto)

 - Assorted hardening and cleanup fixes for other drivers

* tag 'input-for-v7.2-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (72 commits)
  Input: mms114 - fix touch indexing for MMS134S and MMS136
  Input: elan_i2c - prevent division by zero and arithmetic underflow
  Input: stop force-feedback timer when unregistering input devices
  Input: iforce - bound the device-reported force-feedback effect index
  Input: goodix - clamp the device-reported contact count
  Input: mms114 - reject an oversized device packet size
  Input: touchwin - reset the packet index on every complete packet
  Input: rmi4 - update formatting in F12
  Input: rmi4 - propagate proper error code in F12 sensor tuning
  Input: rmi4 - simplify size calculations in F12
  Input: rmi4 - use sizeof(*ptr) and idiomatic checks in f12 allocators
  Input: rmi4 - use devm_kmalloc for F12 data packet buffer
  Input: rmi4 - use flexible array member for IRQ masks in F12
  Input: rmi4 - use unaligned access helpers in F12
  Input: rmi4 - change reg_size type to u32
  Input: rmi4 - refactor F12 probe function
  Input: rmi4 - use kzalloc_flex() for struct rmi_function
  Input: rmi4 - refactor function allocation and registration
  Input: rmi4 - use local presence map in rmi_read_register_desc()
  Input: rmi4 - fix limit in rmi_register_desc_has_subpacket()
  ...
This commit is contained in:
Linus Torvalds
2026-06-24 11:16:06 -07:00
110 changed files with 1674 additions and 1502 deletions

View File

@@ -40,6 +40,10 @@ properties:
vdd-supply:
description: Power supply
reset-gpios:
description: Reset GPIO (active-low)
maxItems: 1
required:
- compatible
- reg

View File

@@ -0,0 +1,73 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/touchscreen/wacom,w9007a-lt03.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Wacom W9000-series penabled I2C touchscreen
maintainers:
- Hendrik Noack <hendrik-noack@gmx.de>
description: |
The W9000-series are penabled touchscreen controllers by Wacom.
The firmware of controllers in different devices may differ. This can also
affect the controller's behavior.
allOf:
- $ref: touchscreen.yaml#
properties:
compatible:
enum:
- wacom,w9002
- wacom,w9007a-lt03
- wacom,w9007a-v1
reg:
maxItems: 1
interrupts:
maxItems: 1
vdd-supply: true
flash-mode-gpios:
maxItems: 1
reset-gpios:
maxItems: 1
required:
- compatible
- reg
- interrupts
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
digitizer@56 {
compatible = "wacom,w9007a-lt03";
reg = <0x56>;
interrupt-parent = <&gpd1>;
interrupts = <1 IRQ_TYPE_EDGE_RISING>;
vdd-supply = <&stylus_reg>;
flash-mode-gpios = <&gpd1 3 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpx0 1 GPIO_ACTIVE_LOW>;
touchscreen-x-mm = <216>;
touchscreen-y-mm = <135>;
touchscreen-inverted-x;
};
};

View File

@@ -5,7 +5,7 @@ The userio Protocol
===================
:Copyright: |copy| 2015 Stephen Chandler Paul <thatslyude@gmail.com>
:Copyright: |copy| 2015 Lyude Paul <thatslyude@gmail.com>
Sponsored by Red Hat
@@ -66,8 +66,27 @@ USERIO_CMD_SET_PORT_TYPE
~~~~~~~~~~~~~~~~~~~~~~~~
Sets the type of port we're emulating, where ``data`` is the port type being
set. Can be any of the macros from <linux/serio.h>. For example: SERIO_8042
would set the port type to be a normal PS/2 port.
set. Can be any of the serio type macros from <linux/serio.h>. For example:
SERIO_8042 would set the port type to be a normal PS/2 port.
USERIO_CMD_SET_PORT_PROTO
~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the protocol of port we're emulating, where ``data`` is the protocol being
set. Can be any of the serio proto macros from <linux/serio.h>. For example:
SERIO_IFORCE would set the port type to be an I-Force serial joystick.
USERIO_CMD_SET_PORT_ID
~~~~~~~~~~~~~~~~~~~~~~
Sets the ``id`` value on the identification of port we're emulating, where
``data`` is the value being set.
USERIO_CMD_SET_PORT_EXTRA
~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the ``extra`` value on the identification of port we're emulating, where
``data`` is the value being set.
USERIO_CMD_SEND_INTERRUPT
~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -28731,7 +28731,7 @@ F: sound/drivers/pcmtest.c
F: tools/testing/selftests/alsa/test-pcmtest-driver.c
VIRTUAL SERIO DEVICE DRIVER
M: Stephen Chandler Paul <thatslyude@gmail.com>
M: Lyude Paul <thatslyude@gmail.com>
S: Maintained
F: drivers/input/serio/userio.c
F: include/uapi/linux/userio.h

View File

@@ -484,17 +484,31 @@ static void ml_ff_destroy(struct ff_device *ff)
struct ml_device *ml = ff->private;
/*
* Even though we stop all playing effects when tearing down
* an input device (via input_device_flush() that calls into
* input_ff_flush() that stops and erases all effects), we
* do not actually stop the timer, and therefore we should
* do it here.
* The timer is normally shut down in ml_ff_stop() when the device
* is unregistered. However, we still shut it down here as a safety
* net and for cases where the device was never registered (e.g.
* error paths during probe).
*/
timer_delete_sync(&ml->timer);
timer_shutdown_sync(&ml->timer);
kfree(ml->private);
}
static void ml_ff_stop(struct ff_device *ff)
{
struct ml_device *ml = ff->private;
/*
* Even though we stop all playing effects when tearing down an
* input device (by the way of evdev calling input_flush_device()
* that calls into input_ff_flush() that stops and erases all
* effects), we do not actually shutdown the timer, and therefore
* we should do it here to prevent it firing after the input
* device is unregistered and its associated resources are freed.
*/
timer_shutdown_sync(&ml->timer);
}
/**
* input_ff_create_memless() - create memoryless force-feedback device
* @dev: input device supporting force-feedback
@@ -529,6 +543,7 @@ int input_ff_create_memless(struct input_dev *dev, void *data,
ff->playback = ml_ff_playback;
ff->set_gain = ml_ff_set_gain;
ff->destroy = ml_ff_destroy;
ff->stop = ml_ff_stop;
/* we can emulate periodic effects with RUMBLE */
if (test_bit(FF_RUMBLE, ff->ffbit)) {

View File

@@ -148,29 +148,29 @@ static int ns558_isa_probe(int io)
#ifdef CONFIG_PNP
static const struct pnp_device_id pnp_devids[] = {
{ .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */
{ .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */
{ .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */
{ .id = "@P@2001", .driver_data = 0 }, /* ALS 120 */
{ .id = "ASB16fd", .driver_data = 0 }, /* AdLib NSC16 */
{ .id = "AZT3001", .driver_data = 0 }, /* AZT1008 */
{ .id = "CDC0001", .driver_data = 0 }, /* Opl3-SAx */
{ .id = "CSC0001", .driver_data = 0 }, /* CS4232 */
{ .id = "CSC000f", .driver_data = 0 }, /* CS4236 */
{ .id = "CSC0101", .driver_data = 0 }, /* CS4327 */
{ .id = "CTL7001", .driver_data = 0 }, /* SB16 */
{ .id = "CTL7002", .driver_data = 0 }, /* AWE64 */
{ .id = "CTL7005", .driver_data = 0 }, /* Vibra16 */
{ .id = "ENS2020", .driver_data = 0 }, /* SoundscapeVIVO */
{ .id = "ESS0001", .driver_data = 0 }, /* ES1869 */
{ .id = "ESS0005", .driver_data = 0 }, /* ES1878 */
{ .id = "ESS6880", .driver_data = 0 }, /* ES688 */
{ .id = "IBM0012", .driver_data = 0 }, /* CS4232 */
{ .id = "OPT0001", .driver_data = 0 }, /* OPTi Audio16 */
{ .id = "YMH0006", .driver_data = 0 }, /* Opl3-SA */
{ .id = "YMH0022", .driver_data = 0 }, /* Opl3-SAx */
{ .id = "PNPb02f", .driver_data = 0 }, /* Generic */
{ .id = "", },
{ .id = "@P@0001" }, /* ALS 100 */
{ .id = "@P@0020" }, /* ALS 200 */
{ .id = "@P@1001" }, /* ALS 100+ */
{ .id = "@P@2001" }, /* ALS 120 */
{ .id = "ASB16fd" }, /* AdLib NSC16 */
{ .id = "AZT3001" }, /* AZT1008 */
{ .id = "CDC0001" }, /* Opl3-SAx */
{ .id = "CSC0001" }, /* CS4232 */
{ .id = "CSC000f" }, /* CS4236 */
{ .id = "CSC0101" }, /* CS4327 */
{ .id = "CTL7001" }, /* SB16 */
{ .id = "CTL7002" }, /* AWE64 */
{ .id = "CTL7005" }, /* Vibra16 */
{ .id = "ENS2020" }, /* SoundscapeVIVO */
{ .id = "ESS0001" }, /* ES1869 */
{ .id = "ESS0005" }, /* ES1878 */
{ .id = "ESS6880" }, /* ES688 */
{ .id = "IBM0012" }, /* CS4232 */
{ .id = "OPT0001" }, /* OPTi Audio16 */
{ .id = "YMH0006" }, /* Opl3-SA */
{ .id = "YMH0022" }, /* Opl3-SAx */
{ .id = "PNPb02f" }, /* Generic */
{ }
};
MODULE_DEVICE_TABLE(pnp, pnp_devids);

View File

@@ -2212,6 +2212,9 @@ static void __input_unregister_device(struct input_dev *dev)
input_wakeup_procfs_readers();
}
if (dev->ff && dev->ff->stop)
dev->ff->stop(dev->ff);
device_del(&dev->dev);
}

View File

@@ -304,7 +304,7 @@ static int seesaw_probe(struct i2c_client *client)
}
static const struct i2c_device_id seesaw_id_table[] = {
{ SEESAW_DEVICE_NAME },
{ .name = SEESAW_DEVICE_NAME },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, seesaw_id_table);

View File

@@ -337,7 +337,7 @@ static void as5011_remove(struct i2c_client *client)
}
static const struct i2c_device_id as5011_id[] = {
{ MODULE_DEVICE_ALIAS },
{ .name = MODULE_DEVICE_ALIAS },
{ }
};
MODULE_DEVICE_TABLE(i2c, as5011_id);

View File

@@ -186,14 +186,18 @@ void iforce_process_packet(struct iforce *iforce,
/* Check if an effect was just started or stopped */
i = data[1] & 0x7f;
if (data[1] & 0x80) {
if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
/* Report play event */
input_report_ff_status(dev, i, FF_STATUS_PLAYING);
if (i < IFORCE_EFFECTS_MAX) {
if (data[1] & 0x80) {
if (!test_and_set_bit(FF_CORE_IS_PLAYED,
iforce->core_effects[i].flags)) {
/* Report play event */
input_report_ff_status(dev, i, FF_STATUS_PLAYING);
}
} else if (test_and_clear_bit(FF_CORE_IS_PLAYED,
iforce->core_effects[i].flags)) {
/* Report stop event */
input_report_ff_status(dev, i, FF_STATUS_STOPPED);
}
} else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
/* Report stop event */
input_report_ff_status(dev, i, FF_STATUS_STOPPED);
}
for (j = 3; j < len; j += 2)

View File

@@ -126,7 +126,7 @@ MODULE_DEVICE_TABLE(of, of_qwiic_match);
#endif /* CONFIG_OF */
static const struct i2c_device_id qwiic_id_table[] = {
{ KBUILD_MODNAME },
{ .name = KBUILD_MODNAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, qwiic_id_table);

View File

@@ -842,8 +842,8 @@ static int adp5588_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(adp5588_dev_pm_ops, adp5588_suspend, adp5588_resume);
static const struct i2c_device_id adp5588_id[] = {
{ "adp5588-keys" },
{ "adp5587-keys" },
{ .name = "adp5588-keys" },
{ .name = "adp5587-keys" },
{ }
};
MODULE_DEVICE_TABLE(i2c, adp5588_id);

View File

@@ -651,13 +651,13 @@ static const struct of_device_id cap11xx_dt_ids[] = {
MODULE_DEVICE_TABLE(of, cap11xx_dt_ids);
static const struct i2c_device_id cap11xx_i2c_ids[] = {
{ "cap1106", (kernel_ulong_t)&cap1106_model },
{ "cap1126", (kernel_ulong_t)&cap1126_model },
{ "cap1188", (kernel_ulong_t)&cap1188_model },
{ "cap1203", (kernel_ulong_t)&cap1203_model },
{ "cap1206", (kernel_ulong_t)&cap1206_model },
{ "cap1293", (kernel_ulong_t)&cap1293_model },
{ "cap1298", (kernel_ulong_t)&cap1298_model },
{ .name = "cap1106", .driver_data = (kernel_ulong_t)&cap1106_model },
{ .name = "cap1126", .driver_data = (kernel_ulong_t)&cap1126_model },
{ .name = "cap1188", .driver_data = (kernel_ulong_t)&cap1188_model },
{ .name = "cap1203", .driver_data = (kernel_ulong_t)&cap1203_model },
{ .name = "cap1206", .driver_data = (kernel_ulong_t)&cap1206_model },
{ .name = "cap1293", .driver_data = (kernel_ulong_t)&cap1293_model },
{ .name = "cap1298", .driver_data = (kernel_ulong_t)&cap1298_model },
{ }
};
MODULE_DEVICE_TABLE(i2c, cap11xx_i2c_ids);

View File

@@ -209,7 +209,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(cypress_sf_pm_ops,
cypress_sf_suspend, cypress_sf_resume);
static const struct i2c_device_id cypress_sf_id_table[] = {
{ CYPRESS_SF_DEV_NAME },
{ .name = CYPRESS_SF_DEV_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, cypress_sf_id_table);

View File

@@ -128,7 +128,7 @@ static int dir685_tk_probe(struct i2c_client *client)
}
static const struct i2c_device_id dir685_tk_id[] = {
{ "dir685tk" },
{ .name = "dir685tk" },
{ }
};
MODULE_DEVICE_TABLE(i2c, dir685_tk_id);

View File

@@ -20,12 +20,6 @@
#include <linux/platform_device.h>
#include <linux/mfd/ipaq-micro.h>
struct ipaq_micro_keys {
struct ipaq_micro *micro;
struct input_dev *input;
u16 *codes;
};
static const u16 micro_keycodes[] = {
KEY_RECORD, /* 1: Record button */
KEY_CALENDAR, /* 2: Calendar */
@@ -38,11 +32,20 @@ static const u16 micro_keycodes[] = {
KEY_DOWN, /* 9: Down */
};
struct ipaq_micro_keys {
struct ipaq_micro *micro;
struct input_dev *input;
u16 codes[ARRAY_SIZE(micro_keycodes)];
};
static void micro_key_receive(void *data, int len, unsigned char *msg)
{
struct ipaq_micro_keys *keys = data;
int key, down;
if (len < 1)
return;
down = 0x80 & msg[0];
key = 0x7f & msg[0];
@@ -54,7 +57,7 @@ static void micro_key_receive(void *data, int len, unsigned char *msg)
static void micro_key_start(struct ipaq_micro_keys *keys)
{
guard(spinlock)(&keys->micro->lock);
guard(spinlock_irq)(&keys->micro->lock);
keys->micro->key = micro_key_receive;
keys->micro->key_data = keys;
@@ -62,7 +65,7 @@ static void micro_key_start(struct ipaq_micro_keys *keys)
static void micro_key_stop(struct ipaq_micro_keys *keys)
{
guard(spinlock)(&keys->micro->lock);
guard(spinlock_irq)(&keys->micro->lock);
keys->micro->key = NULL;
keys->micro->key_data = NULL;
@@ -102,10 +105,7 @@ static int micro_key_probe(struct platform_device *pdev)
keys->input->keycodesize = sizeof(micro_keycodes[0]);
keys->input->keycodemax = ARRAY_SIZE(micro_keycodes);
keys->codes = devm_kmemdup_array(&pdev->dev, micro_keycodes, keys->input->keycodemax,
keys->input->keycodesize, GFP_KERNEL);
if (!keys->codes)
return -ENOMEM;
memcpy(keys->codes, micro_keycodes, sizeof(keys->codes));
keys->input->keycode = keys->codes;

View File

@@ -259,7 +259,7 @@ static void process_keys(struct lm8323_chip *lm)
ret = lm8323_read(lm, LM8323_CMD_READ_FIFO, key_fifo, LM8323_FIFO_LEN);
if (ret < 0) {
dev_err(&lm->client->dev, "Failed reading fifo \n");
dev_err(&lm->client->dev, "Failed reading fifo\n");
return;
}
key_fifo[ret] = 0;
@@ -788,7 +788,7 @@ static int lm8323_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(lm8323_pm_ops, lm8323_suspend, lm8323_resume);
static const struct i2c_device_id lm8323_id[] = {
{ "lm8323" },
{ .name = "lm8323" },
{ }
};

View File

@@ -194,7 +194,7 @@ static int lm8333_probe(struct i2c_client *client)
}
static const struct i2c_device_id lm8333_id[] = {
{ "lm8333" },
{ .name = "lm8333" },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm8333_id);

View File

@@ -270,7 +270,7 @@ static int max7359_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(max7359_pm, max7359_suspend, max7359_resume);
static const struct i2c_device_id max7359_ids[] = {
{ "max7359" },
{ .name = "max7359" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max7359_ids);

View File

@@ -322,7 +322,7 @@ static int mpr_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(mpr121_touchkey_pm_ops, mpr_suspend, mpr_resume);
static const struct i2c_device_id mpr121_id[] = {
{ "mpr121_touchkey" },
{ .name = "mpr121_touchkey" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mpr121_id);

View File

@@ -233,7 +233,7 @@ static int qt1070_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(qt1070_pm_ops, qt1070_suspend, qt1070_resume);
static const struct i2c_device_id qt1070_id[] = {
{ "qt1070" },
{ .name = "qt1070" },
{ }
};
MODULE_DEVICE_TABLE(i2c, qt1070_id);

View File

@@ -393,7 +393,7 @@ static int qt2160_probe(struct i2c_client *client)
}
static const struct i2c_device_id qt2160_idtable[] = {
{ "qt2160" },
{ .name = "qt2160" },
{ }
};

View File

@@ -354,7 +354,7 @@ static int tca8418_keypad_probe(struct i2c_client *client)
}
static const struct i2c_device_id tca8418_id[] = {
{ "tca8418", 8418, },
{ .name = "tca8418", .driver_data = 8418 },
{ }
};
MODULE_DEVICE_TABLE(i2c, tca8418_id);

View File

@@ -326,7 +326,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(tm2_touchkey_pm_ops,
tm2_touchkey_suspend, tm2_touchkey_resume);
static const struct i2c_device_id tm2_touchkey_id_table[] = {
{ TM2_TOUCHKEY_DEV_NAME },
{ .name = TM2_TOUCHKEY_DEV_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, tm2_touchkey_id_table);

View File

@@ -745,16 +745,6 @@ config INPUT_WM831X_ON
To compile this driver as a module, choose M here: the module
will be called wm831x_on.
config INPUT_PCAP
tristate "Motorola EZX PCAP misc input events"
depends on EZX_PCAP
help
Say Y here if you want to use Power key and Headphone button
on Motorola EZX phones.
To compile this driver as a module, choose M here: the
module will be called pcap_keys.
config INPUT_ADXL34X
tristate "Analog Devices ADXL34x Three-Axis Digital Accelerometer"
default n

View File

@@ -60,7 +60,6 @@ obj-$(CONFIG_INPUT_MAX8997_HAPTIC) += max8997_haptic.o
obj-$(CONFIG_INPUT_MC13783_PWRBUTTON) += mc13783-pwrbutton.o
obj-$(CONFIG_INPUT_MMA8450) += mma8450.o
obj-$(CONFIG_INPUT_PALMAS_PWRBUTTON) += palmas-pwrbutton.o
obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o
obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o
obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_PF1550_ONKEY) += pf1550-onkey.o

View File

@@ -72,11 +72,11 @@ static int ad714x_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id ad714x_id[] = {
{ "ad7142_captouch" },
{ "ad7143_captouch" },
{ "ad7147_captouch" },
{ "ad7147a_captouch" },
{ "ad7148_captouch" },
{ .name = "ad7142_captouch" },
{ .name = "ad7143_captouch" },
{ .name = "ad7147_captouch" },
{ .name = "ad7147a_captouch" },
{ .name = "ad7148_captouch" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad714x_id);

View File

@@ -96,7 +96,7 @@ static int adxl34x_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id adxl34x_id[] = {
{ "adxl34x" },
{ .name = "adxl34x" },
{ }
};

View File

@@ -192,7 +192,7 @@ static void apanel_shutdown(struct i2c_client *client)
}
static const struct i2c_device_id apanel_id[] = {
{ "fujitsu_apanel" },
{ .name = "fujitsu_apanel" },
{ }
};
MODULE_DEVICE_TABLE(i2c, apanel_id);

View File

@@ -15,17 +15,18 @@
#include <linux/types.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#define ACPI_ATLAS_NAME "Atlas ACPI"
#define ACPI_ATLAS_CLASS "Atlas"
static unsigned short atlas_keymap[16];
static struct input_dev *input_dev;
struct atlas_btns {
struct input_dev *input_dev;
unsigned short keymap[16];
};
/* button handling code */
static acpi_status acpi_atlas_button_setup(acpi_handle region_handle,
u32 function, void *handler_context, void **return_context)
u32 function, void *handler_context,
void **return_context)
{
*return_context =
(function != ACPI_REGION_DEACTIVATE) ? handler_context : NULL;
@@ -34,33 +35,37 @@ static acpi_status acpi_atlas_button_setup(acpi_handle region_handle,
}
static acpi_status acpi_atlas_button_handler(u32 function,
acpi_physical_address address,
u32 bit_width, u64 *value,
void *handler_context, void *region_context)
acpi_physical_address address,
u32 bit_width, u64 *value,
void *handler_context,
void *region_context)
{
acpi_status status;
struct atlas_btns *atlas = region_context;
if (function == ACPI_WRITE) {
int code = address & 0x0f;
int key_down = !(address & 0x10);
input_event(input_dev, EV_MSC, MSC_SCAN, code);
input_report_key(input_dev, atlas_keymap[code], key_down);
input_sync(input_dev);
input_event(atlas->input_dev, EV_MSC, MSC_SCAN, code);
input_report_key(atlas->input_dev, atlas->keymap[code],
key_down);
input_sync(atlas->input_dev);
status = AE_OK;
} else {
pr_warn("shrugged on unexpected function: function=%x,address=%lx,value=%x\n",
function, (unsigned long)address, (u32)*value);
status = AE_BAD_PARAMETER;
return AE_OK;
}
return status;
dev_warn(atlas->input_dev->dev.parent,
"unexpected function: function=%x,address=%lx,value=%x\n",
function, (unsigned long)address, (u32)*value);
return AE_BAD_PARAMETER;
}
static int atlas_acpi_button_probe(struct platform_device *pdev)
{
struct acpi_device *device;
struct atlas_btns *atlas;
struct input_dev *input_dev;
acpi_status status;
int i;
int err;
@@ -69,65 +74,62 @@ static int atlas_acpi_button_probe(struct platform_device *pdev)
if (!device)
return -ENODEV;
input_dev = input_allocate_device();
if (!input_dev) {
pr_err("unable to allocate input device\n");
atlas = devm_kzalloc(&pdev->dev, sizeof(*atlas), GFP_KERNEL);
if (!atlas)
return -ENOMEM;
}
input_dev = devm_input_allocate_device(&pdev->dev);
if (!input_dev)
return -ENOMEM;
atlas->input_dev = input_dev;
input_dev->name = "Atlas ACPI button driver";
input_dev->phys = "ASIM0000/atlas/input0";
input_dev->id.bustype = BUS_HOST;
input_dev->keycode = atlas_keymap;
input_dev->keycodesize = sizeof(unsigned short);
input_dev->keycodemax = ARRAY_SIZE(atlas_keymap);
input_dev->keycode = atlas->keymap;
input_dev->keycodesize = sizeof(atlas->keymap[0]);
input_dev->keycodemax = ARRAY_SIZE(atlas->keymap);
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
__set_bit(EV_KEY, input_dev->evbit);
for (i = 0; i < ARRAY_SIZE(atlas_keymap); i++) {
for (i = 0; i < ARRAY_SIZE(atlas->keymap); i++) {
if (i < 9) {
atlas_keymap[i] = KEY_F1 + i;
__set_bit(KEY_F1 + i, input_dev->keybit);
} else
atlas_keymap[i] = KEY_RESERVED;
atlas->keymap[i] = KEY_F1 + i;
input_set_capability(input_dev, EV_KEY, KEY_F1 + i);
} else {
atlas->keymap[i] = KEY_RESERVED;
}
}
err = input_register_device(input_dev);
if (err) {
pr_err("couldn't register input device\n");
input_free_device(input_dev);
return err;
}
if (err)
return dev_err_probe(&pdev->dev, err,
"couldn't register input device\n");
/* hookup button handler */
status = acpi_install_address_space_handler(device->handle,
0x81, &acpi_atlas_button_handler,
&acpi_atlas_button_setup, device);
if (ACPI_FAILURE(status)) {
pr_err("error installing addr spc handler\n");
input_unregister_device(input_dev);
err = -EINVAL;
}
0x81,
&acpi_atlas_button_handler,
&acpi_atlas_button_setup,
atlas);
if (ACPI_FAILURE(status))
return dev_err_probe(&pdev->dev, -EINVAL,
"error installing addr spc handler\n");
return err;
return 0;
}
static void atlas_acpi_button_remove(struct platform_device *pdev)
{
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
acpi_status status;
status = acpi_remove_address_space_handler(device->handle,
0x81, &acpi_atlas_button_handler);
if (ACPI_FAILURE(status))
pr_err("error removing addr spc handler\n");
input_unregister_device(input_dev);
acpi_remove_address_space_handler(device->handle, 0x81,
&acpi_atlas_button_handler);
}
static const struct acpi_device_id atlas_device_ids[] = {
{"ASIM0000", 0},
{"", 0},
{ "ASIM0000" },
{ "" }
};
MODULE_DEVICE_TABLE(acpi, atlas_device_ids);
@@ -144,4 +146,3 @@ module_platform_driver(atlas_acpi_driver);
MODULE_AUTHOR("Jaya Kumar");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Atlas button driver");

View File

@@ -257,7 +257,7 @@ static const struct of_device_id atmel_captouch_of_id[] = {
MODULE_DEVICE_TABLE(of, atmel_captouch_of_id);
static const struct i2c_device_id atmel_captouch_id[] = {
{ "atmel_captouch" },
{ .name = "atmel_captouch" },
{ }
};
MODULE_DEVICE_TABLE(i2c, atmel_captouch_id);

View File

@@ -536,9 +536,9 @@ static int __maybe_unused bma150_resume(struct device *dev)
static UNIVERSAL_DEV_PM_OPS(bma150_pm, bma150_suspend, bma150_resume, NULL);
static const struct i2c_device_id bma150_id[] = {
{ "bma150" },
{ "smb380" },
{ "bma023" },
{ .name = "bma150" },
{ .name = "smb380" },
{ .name = "bma023" },
{ }
};

View File

@@ -90,7 +90,7 @@ static const struct dev_pm_ops cma3000_i2c_pm_ops = {
};
static const struct i2c_device_id cma3000_i2c_id[] = {
{ "cma3000_d01" },
{ .name = "cma3000_d01" },
{ }
};

View File

@@ -1305,7 +1305,7 @@ MODULE_DEVICE_TABLE(of, da7280_of_match);
#endif
static const struct i2c_device_id da7280_i2c_id[] = {
{ "da7280", },
{ .name = "da7280" },
{ }
};
MODULE_DEVICE_TABLE(i2c, da7280_i2c_id);

View File

@@ -630,10 +630,10 @@ static int drv260x_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(drv260x_pm_ops, drv260x_suspend, drv260x_resume);
static const struct i2c_device_id drv260x_id[] = {
{ "drv2604" },
{ "drv2604l" },
{ "drv2605" },
{ "drv2605l" },
{ .name = "drv2604" },
{ .name = "drv2604l" },
{ .name = "drv2605" },
{ .name = "drv2605l" },
{ }
};
MODULE_DEVICE_TABLE(i2c, drv260x_id);

View File

@@ -281,7 +281,7 @@ static int drv2665_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(drv2665_pm_ops, drv2665_suspend, drv2665_resume);
static const struct i2c_device_id drv2665_id[] = {
{ "drv2665" },
{ .name = "drv2665" },
{ }
};
MODULE_DEVICE_TABLE(i2c, drv2665_id);

View File

@@ -458,7 +458,7 @@ static int drv2667_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(drv2667_pm_ops, drv2667_suspend, drv2667_resume);
static const struct i2c_device_id drv2667_id[] = {
{ "drv2667" },
{ .name = "drv2667" },
{ }
};
MODULE_DEVICE_TABLE(i2c, drv2667_id);

View File

@@ -14,6 +14,7 @@
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/types.h>
#include <linux/usb/input.h>
#include <linux/usb/cdc.h>
@@ -406,7 +407,16 @@ static void ims_pcu_destroy_gamepad(struct ims_pcu *pcu)
static void ims_pcu_report_events(struct ims_pcu *pcu)
{
u32 data = get_unaligned_be32(&pcu->read_buf[3]);
u32 data;
/* 6-axis setting (1 byte) + button data + checksum */
if (pcu->read_pos < IMS_PCU_DATA_OFFSET + 1 + sizeof(data) + 1) {
dev_warn(pcu->dev, "Short buttons report: %d bytes\n",
pcu->read_pos);
return;
}
data = get_unaligned_be32(&pcu->read_buf[IMS_PCU_DATA_OFFSET + 1]);
ims_pcu_buttons_report(pcu, data & ~IMS_PCU_GAMEPAD_MASK);
if (pcu->gamepad)
@@ -440,7 +450,7 @@ static void ims_pcu_handle_response(struct ims_pcu *pcu)
static void ims_pcu_reset_packet(struct ims_pcu *pcu)
{
pcu->have_stx = true;
pcu->have_stx = false;
pcu->have_dle = false;
pcu->read_pos = 0;
pcu->check_sum = 0;
@@ -686,11 +696,19 @@ static int __ims_pcu_execute_bl_command(struct ims_pcu *pcu,
return error;
}
if (expected_response && pcu->cmd_buf[2] != expected_response) {
dev_err(pcu->dev,
"Unexpected response from bootloader: 0x%02x, wanted 0x%02x\n",
pcu->cmd_buf[2], expected_response);
return -EINVAL;
if (expected_response) {
if (pcu->cmd_buf_len < 3) {
dev_err(pcu->dev, "Short response from bootloader: %d bytes\n",
pcu->cmd_buf_len);
return -EIO;
}
if (pcu->cmd_buf[2] != expected_response) {
dev_err(pcu->dev,
"Unexpected response from bootloader: 0x%02x, wanted 0x%02x\n",
pcu->cmd_buf[2], expected_response);
return -EINVAL;
}
}
return 0;
@@ -718,6 +736,12 @@ static int ims_pcu_get_info(struct ims_pcu *pcu)
return error;
}
if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + IMS_PCU_SET_INFO_SIZE + 1) {
dev_err(pcu->dev, "Short GET_INFO response: %d bytes\n",
pcu->cmd_buf_len);
return -EIO;
}
memcpy(pcu->part_number,
&pcu->cmd_buf[IMS_PCU_INFO_PART_OFFSET],
sizeof(pcu->part_number));
@@ -815,6 +839,12 @@ static int ims_pcu_verify_block(struct ims_pcu *pcu,
return error;
}
if (pcu->cmd_buf_len < IMS_PCU_BL_DATA_OFFSET + sizeof(*fragment) + len + 1) {
dev_err(pcu->dev, "Short READ_APP response: %d bytes\n",
pcu->cmd_buf_len);
return -EIO;
}
fragment = (void *)&pcu->cmd_buf[IMS_PCU_BL_DATA_OFFSET];
if (get_unaligned_le32(&fragment->addr) != addr ||
fragment->len != len) {
@@ -934,9 +964,10 @@ static int ims_pcu_handle_firmware_update(struct ims_pcu *pcu,
return retval;
}
static void ims_pcu_process_async_firmware(const struct firmware *fw,
static void ims_pcu_process_async_firmware(const struct firmware *_fw,
void *context)
{
const struct firmware *fw __free(firmware) = _fw;
struct ims_pcu *pcu = context;
int error;
@@ -956,8 +987,6 @@ static void ims_pcu_process_async_firmware(const struct firmware *fw,
scoped_guard(mutex, &pcu->cmd_mutex)
ims_pcu_handle_firmware_update(pcu, fw);
release_firmware(fw);
out:
complete(&pcu->async_firmware_done);
}
@@ -1009,6 +1038,10 @@ ims_pcu_backlight_get_brightness(struct led_classdev *cdev)
error);
/* Assume the LED is OFF */
brightness = LED_OFF;
} else if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 2 + 1) {
dev_err(pcu->dev, "Short GET_BRIGHTNESS response: %d bytes\n",
pcu->cmd_buf_len);
brightness = LED_OFF;
} else {
brightness =
get_unaligned_le16(&pcu->cmd_buf[IMS_PCU_DATA_OFFSET]);
@@ -1153,6 +1186,8 @@ static ssize_t ims_pcu_reset_device(struct device *dev,
dev_info(pcu->dev, "Attempting to reset device\n");
guard(mutex)(&pcu->cmd_mutex);
error = ims_pcu_execute_command(pcu, PCU_RESET, &reset_byte, 1);
if (error) {
dev_info(pcu->dev,
@@ -1249,6 +1284,9 @@ static umode_t ims_pcu_is_attr_visible(struct kobject *kobj,
struct ims_pcu *pcu = usb_get_intfdata(intf);
umode_t mode = attr->mode;
if (intf != pcu->ctrl_intf)
return 0;
if (pcu->bootloader_mode) {
if (attr != &dev_attr_update_firmware_status.attr &&
attr != &dev_attr_update_firmware.attr &&
@@ -1282,6 +1320,12 @@ static int ims_pcu_read_ofn_config(struct ims_pcu *pcu, u8 addr, u8 *data)
if (error)
return error;
if (pcu->cmd_buf_len < OFN_REG_RESULT_OFFSET + 2 + 1) {
dev_err(pcu->dev, "Short OFN_GET_CONFIG response: %d bytes\n",
pcu->cmd_buf_len);
return -EIO;
}
result = (s16)get_unaligned_le16(pcu->cmd_buf + OFN_REG_RESULT_OFFSET);
if (result < 0)
return -EIO;
@@ -1302,6 +1346,12 @@ static int ims_pcu_write_ofn_config(struct ims_pcu *pcu, u8 addr, u8 data)
if (error)
return error;
if (pcu->cmd_buf_len < OFN_REG_RESULT_OFFSET + 2 + 1) {
dev_err(pcu->dev, "Short OFN_SET_CONFIG response: %d bytes\n",
pcu->cmd_buf_len);
return -EIO;
}
result = (s16)get_unaligned_le16(pcu->cmd_buf + OFN_REG_RESULT_OFFSET);
if (result < 0)
return -EIO;
@@ -1488,6 +1538,9 @@ static umode_t ims_pcu_ofn_is_attr_visible(struct kobject *kobj,
struct ims_pcu *pcu = usb_get_intfdata(intf);
umode_t mode = attr->mode;
if (intf != pcu->ctrl_intf)
return SYSFS_GROUP_INVISIBLE;
/*
* PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor.
*/
@@ -1528,7 +1581,7 @@ static void ims_pcu_irq(struct urb *urb)
}
dev_dbg(pcu->dev, "%s: received %d: %*ph\n", __func__,
urb->actual_length, urb->actual_length, pcu->urb_in_buf);
urb->actual_length, urb->actual_length, urb->transfer_buffer);
if (urb == pcu->urb_in)
ims_pcu_process_data(pcu, urb);
@@ -1656,8 +1709,9 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf)
while (buflen >= sizeof(*union_desc)) {
union_desc = (struct usb_cdc_union_desc *)buf;
if (union_desc->bLength > buflen) {
dev_err(&intf->dev, "Too large descriptor\n");
if (union_desc->bLength < 2 || union_desc->bLength > buflen) {
dev_err(&intf->dev, "Invalid descriptor length: %d\n",
union_desc->bLength);
return NULL;
}
@@ -1693,7 +1747,7 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc
pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev,
union_desc->bMasterInterface0);
if (!pcu->ctrl_intf)
if (pcu->ctrl_intf != intf)
return -EINVAL;
alt = pcu->ctrl_intf->cur_altsetting;
@@ -1702,6 +1756,12 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc
return -ENODEV;
pcu->ep_ctrl = &alt->endpoint[0].desc;
if (!usb_endpoint_is_int_in(pcu->ep_ctrl)) {
dev_err(pcu->dev,
"Control endpoint is not INTERRUPT IN\n");
return -EINVAL;
}
pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl);
pcu->data_intf = usb_ifnum_to_if(pcu->udev,
@@ -1783,11 +1843,16 @@ static void ims_pcu_stop_io(struct ims_pcu *pcu)
static int ims_pcu_line_setup(struct ims_pcu *pcu)
{
struct usb_host_interface *interface = pcu->ctrl_intf->cur_altsetting;
struct usb_cdc_line_coding *line = (void *)pcu->cmd_buf;
struct usb_cdc_line_coding *line __free(kfree) =
kmalloc(sizeof(*line), GFP_KERNEL);
int error;
memset(line, 0, sizeof(*line));
if (!line)
return -ENOMEM;
line->dwDTERate = cpu_to_le32(57600);
line->bCharFormat = USB_CDC_1_STOP_BITS;
line->bParityType = USB_CDC_NO_PARITY;
line->bDataBits = 8;
error = usb_control_msg(pcu->udev, usb_sndctrlpipe(pcu->udev, 0),
@@ -1831,6 +1896,12 @@ static int ims_pcu_get_device_info(struct ims_pcu *pcu)
return error;
}
if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 6 + 1) {
dev_err(pcu->dev, "Short GET_FW_VERSION response: %d bytes\n",
pcu->cmd_buf_len);
return -EIO;
}
snprintf(pcu->fw_version, sizeof(pcu->fw_version),
"%02d%02d%02d%02d.%c%c",
pcu->cmd_buf[2], pcu->cmd_buf[3], pcu->cmd_buf[4], pcu->cmd_buf[5],
@@ -1843,6 +1914,12 @@ static int ims_pcu_get_device_info(struct ims_pcu *pcu)
return error;
}
if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 6 + 1) {
dev_err(pcu->dev, "Short GET_BL_VERSION response: %d bytes\n",
pcu->cmd_buf_len);
return -EIO;
}
snprintf(pcu->bl_version, sizeof(pcu->bl_version),
"%02d%02d%02d%02d.%c%c",
pcu->cmd_buf[2], pcu->cmd_buf[3], pcu->cmd_buf[4], pcu->cmd_buf[5],
@@ -1855,6 +1932,12 @@ static int ims_pcu_get_device_info(struct ims_pcu *pcu)
return error;
}
if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 1 + 1) {
dev_err(pcu->dev, "Short RESET_REASON response: %d bytes\n",
pcu->cmd_buf_len);
return -EIO;
}
snprintf(pcu->reset_reason, sizeof(pcu->reset_reason),
"%02x", pcu->cmd_buf[IMS_PCU_DATA_OFFSET]);
@@ -1881,6 +1964,12 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id)
return error;
}
if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 1 + 1) {
dev_err(pcu->dev, "Short GET_DEVICE_ID response: %d bytes\n",
pcu->cmd_buf_len);
return -EIO;
}
*device_id = pcu->cmd_buf[IMS_PCU_DATA_OFFSET];
dev_dbg(pcu->dev, "Detected device ID: %d\n", *device_id);
@@ -1972,6 +2061,12 @@ static int ims_pcu_init_bootloader_mode(struct ims_pcu *pcu)
return error;
}
if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 15 + 4 + 1) {
dev_err(pcu->dev, "Short QUERY_DEVICE response: %d bytes\n",
pcu->cmd_buf_len);
return -EIO;
}
pcu->fw_start_addr =
get_unaligned_le32(&pcu->cmd_buf[IMS_PCU_DATA_OFFSET + 11]);
pcu->fw_end_addr =
@@ -2071,7 +2166,6 @@ static int ims_pcu_probe(struct usb_interface *intf,
static void ims_pcu_disconnect(struct usb_interface *intf)
{
struct ims_pcu *pcu = usb_get_intfdata(intf);
struct usb_host_interface *alt = intf->cur_altsetting;
usb_set_intfdata(intf, NULL);
@@ -2079,7 +2173,7 @@ static void ims_pcu_disconnect(struct usb_interface *intf)
* See if we are dealing with control or data interface. The cleanup
* happens when we unbind primary (control) interface.
*/
if (alt->desc.bInterfaceClass != USB_CLASS_COMM)
if (intf != pcu->ctrl_intf)
return;
ims_pcu_stop_io(pcu);
@@ -2090,6 +2184,7 @@ static void ims_pcu_disconnect(struct usb_interface *intf)
ims_pcu_destroy_application_mode(pcu);
ims_pcu_buffers_free(pcu);
usb_driver_release_interface(&ims_pcu_driver, pcu->data_intf);
kfree(pcu);
}

View File

@@ -525,7 +525,7 @@ static int kxtj9_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(kxtj9_pm_ops, kxtj9_suspend, kxtj9_resume);
static const struct i2c_device_id kxtj9_id[] = {
{ NAME },
{ .name = NAME },
{ }
};

View File

@@ -200,7 +200,7 @@ static int mma8450_probe(struct i2c_client *c)
}
static const struct i2c_device_id mma8450_id[] = {
{ MMA8450_DRV_NAME },
{ .name = MMA8450_DRV_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, mma8450_id);

View File

@@ -1,125 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Input driver for PCAP events:
* * Power key
* * Headphone button
*
* Copyright (c) 2008,2009 Ilya Petrov <ilya.muromec@gmail.com>
*/
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/mfd/ezx-pcap.h>
#include <linux/slab.h>
struct pcap_keys {
struct pcap_chip *pcap;
struct input_dev *input;
};
/* PCAP2 interrupts us on keypress */
static irqreturn_t pcap_keys_handler(int irq, void *_pcap_keys)
{
struct pcap_keys *pcap_keys = _pcap_keys;
int pirq = irq_to_pcap(pcap_keys->pcap, irq);
u32 pstat;
ezx_pcap_read(pcap_keys->pcap, PCAP_REG_PSTAT, &pstat);
pstat &= 1 << pirq;
switch (pirq) {
case PCAP_IRQ_ONOFF:
input_report_key(pcap_keys->input, KEY_POWER, !pstat);
break;
case PCAP_IRQ_MIC:
input_report_key(pcap_keys->input, KEY_HP, !pstat);
break;
}
input_sync(pcap_keys->input);
return IRQ_HANDLED;
}
static int pcap_keys_probe(struct platform_device *pdev)
{
int err = -ENOMEM;
struct pcap_keys *pcap_keys;
struct input_dev *input_dev;
pcap_keys = kmalloc_obj(*pcap_keys);
if (!pcap_keys)
return err;
pcap_keys->pcap = dev_get_drvdata(pdev->dev.parent);
input_dev = input_allocate_device();
if (!input_dev)
goto fail;
pcap_keys->input = input_dev;
platform_set_drvdata(pdev, pcap_keys);
input_dev->name = pdev->name;
input_dev->phys = "pcap-keys/input0";
input_dev->id.bustype = BUS_HOST;
input_dev->dev.parent = &pdev->dev;
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(KEY_POWER, input_dev->keybit);
__set_bit(KEY_HP, input_dev->keybit);
err = input_register_device(input_dev);
if (err)
goto fail_allocate;
err = request_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_ONOFF),
pcap_keys_handler, 0, "Power key", pcap_keys);
if (err)
goto fail_register;
err = request_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_MIC),
pcap_keys_handler, 0, "Headphone button", pcap_keys);
if (err)
goto fail_pwrkey;
return 0;
fail_pwrkey:
free_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_ONOFF), pcap_keys);
fail_register:
input_unregister_device(input_dev);
goto fail;
fail_allocate:
input_free_device(input_dev);
fail:
kfree(pcap_keys);
return err;
}
static void pcap_keys_remove(struct platform_device *pdev)
{
struct pcap_keys *pcap_keys = platform_get_drvdata(pdev);
free_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_ONOFF), pcap_keys);
free_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_MIC), pcap_keys);
input_unregister_device(pcap_keys->input);
kfree(pcap_keys);
}
static struct platform_driver pcap_keys_device_driver = {
.probe = pcap_keys_probe,
.remove = pcap_keys_remove,
.driver = {
.name = "pcap-keys",
}
};
module_platform_driver(pcap_keys_device_driver);
MODULE_DESCRIPTION("Motorola PCAP2 input events driver");
MODULE_AUTHOR("Ilya Petrov <ilya.muromec@gmail.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pcap_keys");

View File

@@ -189,7 +189,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(pcf8574_kp_pm_ops,
pcf8574_kp_suspend, pcf8574_kp_resume);
static const struct i2c_device_id pcf8574_kp_id[] = {
{ DRV_NAME },
{ .name = DRV_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, pcf8574_kp_id);

View File

@@ -22,15 +22,6 @@
* - Olivier Vandorpe, for providing the usbb2k-api.
* - Martin Diehl, for spotting my memory allocation bug.
*
* History:
* 20050527 henk First version, functional keyboard. Keyboard events
* will pop-up on the ../input/eventX bus.
* 20050531 henk Added led, LCD, dialtone and sysfs interface.
* 20050610 henk Cleanups, make it ready for public consumption.
* 20050630 henk Cleanups, fixes in response to comments.
* 20050701 henk sysfs write serialisation, fix potential unload races
* 20050801 henk Added ringtone, restructure USB
* 20050816 henk Merge 2.6.13-rc6
*/
#include <linux/kernel.h>

View File

@@ -1456,7 +1456,7 @@ static const struct dev_pm_ops cyapa_pm_ops = {
};
static const struct i2c_device_id cyapa_id_table[] = {
{ "cyapa" },
{ .name = "cyapa" },
{ }
};
MODULE_DEVICE_TABLE(i2c, cyapa_id_table);

View File

@@ -428,8 +428,17 @@ static int elan_query_device_parameters(struct elan_tp_data *data)
if (error)
return error;
}
data->width_x = data->max_x / x_traces;
data->width_y = data->max_y / y_traces;
if (!x_traces || !y_traces) {
dev_warn(&client->dev,
"invalid trace numbers: x=%u, y=%u\n",
x_traces, y_traces);
data->width_x = 1;
data->width_y = 1;
} else {
data->width_x = data->max_x / x_traces;
data->width_y = data->max_y / y_traces;
}
if (device_property_read_u32(&client->dev,
"touchscreen-x-mm", &x_mm) ||
@@ -443,8 +452,16 @@ static int elan_query_device_parameters(struct elan_tp_data *data)
data->x_res = elan_convert_resolution(hw_x_res, data->pattern);
data->y_res = elan_convert_resolution(hw_y_res, data->pattern);
} else {
data->x_res = (data->max_x + 1) / x_mm;
data->y_res = (data->max_y + 1) / y_mm;
if (unlikely(x_mm == 0 || y_mm == 0)) {
dev_warn(&client->dev,
"invalid physical dimensions: x_mm=%u, y_mm=%u\n",
x_mm, y_mm);
data->x_res = 1;
data->y_res = 1;
} else {
data->x_res = (data->max_x + 1) / x_mm;
data->y_res = (data->max_y + 1) / y_mm;
}
}
if (device_property_read_bool(&client->dev, "elan,clickpad"))
@@ -956,6 +973,7 @@ static void elan_report_contact(struct elan_tp_data *data, int contact_num,
if (data->report_features & ETP_FEATURE_REPORT_MK) {
unsigned int mk_x, mk_y, area_x, area_y;
int adj_width_x, adj_width_y;
u8 mk_data = high_precision ?
packet[ETP_MK_DATA_OFFSET + contact_num] :
finger_data[3];
@@ -967,8 +985,14 @@ static void elan_report_contact(struct elan_tp_data *data, int contact_num,
* To avoid treating large finger as palm, let's reduce
* the width x and y per trace.
*/
area_x = mk_x * (data->width_x - ETP_FWIDTH_REDUCE);
area_y = mk_y * (data->width_y - ETP_FWIDTH_REDUCE);
adj_width_x = data->width_x > ETP_FWIDTH_REDUCE ?
data->width_x - ETP_FWIDTH_REDUCE : 0;
adj_width_y = data->width_y > ETP_FWIDTH_REDUCE ?
data->width_y - ETP_FWIDTH_REDUCE : 0;
area_x = mk_x * adj_width_x;
area_y = mk_y * adj_width_y;
input_report_abs(input, ABS_TOOL_WIDTH, mk_x);
input_report_abs(input, ABS_MT_TOUCH_MAJOR,
@@ -1407,7 +1431,7 @@ static int elan_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(elan_pm_ops, elan_suspend, elan_resume);
static const struct i2c_device_id elan_id[] = {
{ DRIVER_NAME },
{ .name = DRIVER_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, elan_id);

View File

@@ -607,7 +607,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(synaptics_i2c_pm, synaptics_i2c_suspend,
synaptics_i2c_resume);
static const struct i2c_device_id synaptics_i2c_id_table[] = {
{ "synaptics_i2c" },
{ .name = "synaptics_i2c" },
{ }
};
MODULE_DEVICE_TABLE(i2c, synaptics_i2c_id_table);

View File

@@ -56,8 +56,8 @@ struct rmi_2d_sensor {
u16 max_y;
u8 nbr_fingers;
u8 *data_pkt;
int pkt_size;
int attn_size;
u32 pkt_size;
u32 attn_size;
bool topbuttonpad;
enum rmi_sensor_type sensor_type;
struct input_dev *input;

View File

@@ -237,36 +237,44 @@ static int rmi_function_remove(struct device *dev)
return 0;
}
struct rmi_function *rmi_alloc_function(struct rmi_device *rmi_dev, u8 id)
{
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
struct rmi_function *fn;
fn = kzalloc_flex(*fn, irq_mask, BITS_TO_LONGS(data->irq_count));
if (!fn)
return NULL;
device_initialize(&fn->dev);
dev_set_name(&fn->dev, "%s.fn%02x", dev_name(&rmi_dev->dev), id);
fn->dev.parent = &rmi_dev->dev;
fn->dev.type = &rmi_function_type;
fn->dev.bus = &rmi_bus_type;
fn->rmi_dev = rmi_dev;
return fn;
}
int rmi_register_function(struct rmi_function *fn)
{
struct rmi_device *rmi_dev = fn->rmi_dev;
int error;
device_initialize(&fn->dev);
dev_set_name(&fn->dev, "%s.fn%02x",
dev_name(&rmi_dev->dev), fn->fd.function_number);
fn->dev.parent = &rmi_dev->dev;
fn->dev.type = &rmi_function_type;
fn->dev.bus = &rmi_bus_type;
error = device_add(&fn->dev);
if (error) {
dev_err(&rmi_dev->dev,
"Failed device_register function device %s\n",
"Failed to register function device %s\n",
dev_name(&fn->dev));
goto err_put_device;
return error;
}
rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, "Registered F%02X.\n",
fn->fd.function_number);
return 0;
err_put_device:
put_device(&fn->dev);
return error;
}
void rmi_unregister_function(struct rmi_function *fn)
@@ -455,11 +463,13 @@ static int __init rmi_bus_init(void)
if (error) {
pr_err("%s: error registering the RMI physical driver: %d\n",
__func__, error);
goto err_unregister_bus;
goto err_unregister_function_handlers;
}
return 0;
err_unregister_function_handlers:
rmi_unregister_function_handlers();
err_unregister_bus:
bus_unregister(&rmi_bus_type);
return error;

View File

@@ -49,6 +49,7 @@ struct rmi_function {
bool rmi_is_function_device(struct device *dev);
struct rmi_function *rmi_alloc_function(struct rmi_device *rmi_dev, u8 id);
int __must_check rmi_register_function(struct rmi_function *);
void rmi_unregister_function(struct rmi_function *);

View File

@@ -22,6 +22,7 @@
#include <uapi/linux/input.h>
#include <linux/rmi.h>
#include <linux/export.h>
#include <linux/unaligned.h>
#include "rmi_bus.h"
#include "rmi_driver.h"
@@ -182,7 +183,11 @@ void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status,
attn_data.size = size;
attn_data.data = fifo_data;
kfifo_put(&drvdata->attn_fifo, attn_data);
if (!kfifo_put(&drvdata->attn_fifo, attn_data)) {
dev_warn_ratelimited(&rmi_dev->dev,
"Failed to enqueue attention data, FIFO full\n");
kfree(fifo_data);
}
}
EXPORT_SYMBOL_GPL(rmi_set_attn_data);
@@ -193,24 +198,24 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
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;
}
do {
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);
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);
drvdata->attn_data.data = NULL;
}
if (!kfifo_is_empty(&drvdata->attn_fifo))
return rmi_irq_fn(irq, dev_id);
if (count) {
kfree(attn_data.data);
drvdata->attn_data.data = NULL;
}
} while (!kfifo_is_empty(&drvdata->attn_fifo));
return IRQ_HANDLED;
}
@@ -383,9 +388,8 @@ static int rmi_driver_set_irq_bits(struct rmi_device *rmi_dev,
__func__);
goto error_unlock;
}
bitmap_copy(data->current_irq_mask, data->new_irq_mask,
data->num_of_irq_regs);
bitmap_copy(data->current_irq_mask, data->new_irq_mask, data->irq_count);
bitmap_or(data->fn_irq_bits, data->fn_irq_bits, mask, data->irq_count);
error_unlock:
@@ -414,8 +418,8 @@ static int rmi_driver_clear_irq_bits(struct rmi_device *rmi_dev,
__func__);
goto error_unlock;
}
bitmap_copy(data->current_irq_mask, data->new_irq_mask,
data->num_of_irq_regs);
bitmap_copy(data->current_irq_mask, data->new_irq_mask, data->irq_count);
error_unlock:
mutex_unlock(&data->irq_mutex);
@@ -558,30 +562,75 @@ int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx,
return retval < 0 ? retval : 0;
}
int rmi_read_register_desc(struct rmi_device *d, u16 addr,
struct rmi_register_descriptor *rdesc)
static int rmi_parse_register_desc_item(struct rmi_register_desc_item *item,
const u8 *buf, size_t size)
{
int ret;
unsigned int offset = 0;
unsigned int map_offset = 0;
int b;
if (offset >= size)
return -EIO;
item->reg_size = buf[offset++];
if (item->reg_size == 0) {
if (size - offset < 2)
return -EIO;
item->reg_size = get_unaligned_le16(&buf[offset]);
offset += 2;
}
if (item->reg_size == 0) {
if (size - offset < 4)
return -EIO;
item->reg_size = get_unaligned_le32(&buf[offset]);
offset += 4;
}
do {
if (offset >= size)
return -EIO;
for (b = 0; b < 7; b++) {
if (buf[offset] & BIT(b)) {
if (map_offset >= RMI_REG_DESC_SUBPACKET_BITS)
return -EIO;
__set_bit(map_offset, item->subpacket_map);
}
++map_offset;
}
} while (buf[offset++] & BIT(7));
item->num_subpackets = bitmap_weight(item->subpacket_map,
RMI_REG_DESC_SUBPACKET_BITS);
return offset;
}
int rmi_read_register_desc(struct rmi_device *d, u16 addr,
struct rmi_register_descriptor *rdesc)
{
DECLARE_BITMAP(presence_map, RMI_REG_DESC_PRESENCE_BITS);
u8 buf[RMI_REG_DESC_PRESENCE_REGS_MAX];
u8 size_presence_reg;
u8 buf[35];
int presense_offset = 1;
u8 *struct_buf;
int reg;
int offset = 0;
int map_offset = 0;
unsigned int presence_offset;
unsigned int map_offset;
unsigned int offset;
unsigned int reg;
int i;
int b;
int ret;
/*
* The first register of the register descriptor is the size of
* the register descriptor's presense register.
* the register descriptor's presence register.
*/
ret = rmi_read(d, addr, &size_presence_reg);
if (ret)
return ret;
++addr;
if (size_presence_reg < 0 || size_presence_reg > 35)
if (size_presence_reg < 1 || size_presence_reg > RMI_REG_DESC_PRESENCE_REGS_MAX)
return -EIO;
memset(buf, 0, sizeof(buf));
@@ -594,25 +643,33 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr,
ret = rmi_read_block(d, addr, buf, size_presence_reg);
if (ret)
return ret;
++addr;
addr += size_presence_reg;
if (buf[0] == 0) {
presense_offset = 3;
rdesc->struct_size = buf[1] | (buf[2] << 8);
if (size_presence_reg < 3)
return -EIO;
presence_offset = 3;
rdesc->struct_size = get_unaligned_le16(&buf[1]);
} else {
presence_offset = 1;
rdesc->struct_size = buf[0];
}
for (i = presense_offset; i < size_presence_reg; i++) {
memset(presence_map, 0, sizeof(presence_map));
map_offset = 0;
for (i = presence_offset; i < size_presence_reg; i++) {
for (b = 0; b < 8; b++) {
if (buf[i] & (0x1 << b))
bitmap_set(rdesc->presense_map, map_offset, 1);
if (buf[i] & BIT(b)) {
if (map_offset >= RMI_REG_DESC_PRESENCE_BITS)
return -EIO;
bitmap_set(presence_map, map_offset, 1);
}
++map_offset;
}
}
rdesc->num_registers = bitmap_weight(rdesc->presense_map,
RMI_REG_DESC_PRESENSE_BITS);
rdesc->num_registers = bitmap_weight(presence_map,
RMI_REG_DESC_PRESENCE_BITS);
rdesc->registers = devm_kcalloc(&d->dev,
rdesc->num_registers,
@@ -626,7 +683,7 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr,
* I'm not using devm_kzalloc here since it will not be retained
* after exiting this function
*/
struct_buf = kzalloc(rdesc->struct_size, GFP_KERNEL);
u8 *struct_buf __free(kfree) = kzalloc(rdesc->struct_size, GFP_KERNEL);
if (!struct_buf)
return -ENOMEM;
@@ -638,56 +695,32 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr,
*/
ret = rmi_read_block(d, addr, struct_buf, rdesc->struct_size);
if (ret)
goto free_struct_buff;
return ret;
reg = find_first_bit(rdesc->presense_map, RMI_REG_DESC_PRESENSE_BITS);
reg = find_first_bit(presence_map, RMI_REG_DESC_PRESENCE_BITS);
offset = 0;
for (i = 0; i < rdesc->num_registers; i++) {
struct rmi_register_desc_item *item = &rdesc->registers[i];
int reg_size = struct_buf[offset];
int item_size;
++offset;
if (reg_size == 0) {
reg_size = struct_buf[offset] |
(struct_buf[offset + 1] << 8);
offset += 2;
}
if (reg_size == 0) {
reg_size = struct_buf[offset] |
(struct_buf[offset + 1] << 8) |
(struct_buf[offset + 2] << 16) |
(struct_buf[offset + 3] << 24);
offset += 4;
}
item_size = rmi_parse_register_desc_item(item,
&struct_buf[offset],
rdesc->struct_size - offset);
if (item_size < 0)
return item_size;
item->reg = reg;
item->reg_size = reg_size;
map_offset = 0;
do {
for (b = 0; b < 7; b++) {
if (struct_buf[offset] & (0x1 << b))
bitmap_set(item->subpacket_map,
map_offset, 1);
++map_offset;
}
} while (struct_buf[offset++] & 0x80);
item->num_subpackets = bitmap_weight(item->subpacket_map,
RMI_REG_DESC_SUBPACKET_BITS);
offset += item_size;
rmi_dbg(RMI_DEBUG_CORE, &d->dev,
"%s: reg: %d reg size: %ld subpackets: %d\n", __func__,
"%s: reg: %d reg size: %u subpackets: %d\n", __func__,
item->reg, item->reg_size, item->num_subpackets);
reg = find_next_bit(rdesc->presense_map,
RMI_REG_DESC_PRESENSE_BITS, reg + 1);
reg = find_next_bit(presence_map,
RMI_REG_DESC_PRESENCE_BITS, reg + 1);
}
free_struct_buff:
kfree(struct_buf);
return ret;
return 0;
}
const struct rmi_register_desc_item *rmi_get_register_desc_item(
@@ -713,7 +746,7 @@ size_t rmi_register_desc_calc_size(struct rmi_register_descriptor *rdesc)
for (i = 0; i < rdesc->num_registers; i++) {
item = &rdesc->registers[i];
size += item->reg_size;
size = size_add(size, item->reg_size);
}
return size;
}
@@ -738,7 +771,7 @@ int rmi_register_desc_calc_reg_offset(
bool rmi_register_desc_has_subpacket(const struct rmi_register_desc_item *item,
u8 subpacket)
{
return find_next_bit(item->subpacket_map, RMI_REG_DESC_PRESENSE_BITS,
return find_next_bit(item->subpacket_map, RMI_REG_DESC_SUBPACKET_BITS,
subpacket) == subpacket;
}
@@ -839,9 +872,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
rmi_dbg(RMI_DEBUG_CORE, dev, "Initializing F%02X.\n",
pdt->function_number);
fn = kzalloc(sizeof(struct rmi_function) +
BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long),
GFP_KERNEL);
fn = rmi_alloc_function(rmi_dev, pdt->function_number);
if (!fn) {
dev_err(dev, "Failed to allocate memory for F%02X\n",
pdt->function_number);
@@ -851,8 +882,6 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
INIT_LIST_HEAD(&fn->node);
rmi_driver_copy_pdt_to_fd(pdt, &fn->fd);
fn->rmi_dev = rmi_dev;
fn->num_of_irqs = pdt->interrupt_source_count;
fn->irq_pos = *current_irq_count;
*current_irq_count += fn->num_of_irqs;
@@ -861,8 +890,10 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
set_bit(fn->irq_pos + i, fn->irq_mask);
error = rmi_register_function(fn);
if (error)
if (error) {
put_device(&fn->dev);
return error;
}
if (pdt->function_number == 0x01)
data->f01_container = fn;
@@ -1133,6 +1164,7 @@ static int rmi_driver_probe(struct device *dev)
return -ENOMEM;
INIT_LIST_HEAD(&data->function_list);
INIT_KFIFO(data->attn_fifo);
data->rmi_dev = rmi_dev;
dev_set_drvdata(&rmi_dev->dev, data);

View File

@@ -46,16 +46,16 @@ struct pdt_entry {
u8 function_number;
};
#define RMI_REG_DESC_PRESENSE_BITS (32 * BITS_PER_BYTE)
#define RMI_REG_DESC_PRESENCE_BITS (32 * BITS_PER_BYTE)
#define RMI_REG_DESC_PRESENCE_REGS_MAX (3 + RMI_REG_DESC_PRESENCE_BITS / 8)
#define RMI_REG_DESC_SUBPACKET_BITS (37 * BITS_PER_BYTE)
/* describes a single packet register */
struct rmi_register_desc_item {
u32 reg_size;
u16 reg;
unsigned long reg_size;
u8 num_subpackets;
unsigned long subpacket_map[BITS_TO_LONGS(
RMI_REG_DESC_SUBPACKET_BITS)];
u16 num_subpackets;
DECLARE_BITMAP(subpacket_map, RMI_REG_DESC_SUBPACKET_BITS);
};
/*
@@ -64,8 +64,7 @@ struct rmi_register_desc_item {
*/
struct rmi_register_descriptor {
unsigned long struct_size;
unsigned long presense_map[BITS_TO_LONGS(RMI_REG_DESC_PRESENSE_BITS)];
u8 num_registers;
u16 num_registers;
struct rmi_register_desc_item *registers;
};

View File

@@ -1304,7 +1304,7 @@ static irqreturn_t rmi_f11_attention(int irq, void *ctx)
struct f11_data *f11 = dev_get_drvdata(&fn->dev);
u16 data_base_addr = fn->fd.data_base_addr;
int error;
int valid_bytes = f11->sensor.pkt_size;
u32 valid_bytes = f11->sensor.pkt_size;
if (drvdata->attn_data.data) {
/*

View File

@@ -5,6 +5,8 @@
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/rmi.h>
#include <linux/sizes.h>
#include <linux/unaligned.h>
#include "rmi_driver.h"
#include "rmi_2d_sensor.h"
@@ -49,7 +51,6 @@ struct f12_data {
const struct rmi_register_desc_item *data6;
u16 data6_offset;
/* F12 Data9 reports relative data */
const struct rmi_register_desc_item *data9;
u16 data9_offset;
@@ -57,10 +58,39 @@ struct f12_data {
const struct rmi_register_desc_item *data15;
u16 data15_offset;
unsigned long *abs_mask;
unsigned long *rel_mask;
unsigned long irq_mask[];
};
static int rmi_f12_read_register_descs(struct rmi_function *fn,
struct f12_data *f12, u16 query_addr)
{
struct {
struct rmi_register_descriptor *desc;
const char *name;
} descriptors[] = {
{ &f12->query_reg_desc, "Query" },
{ &f12->control_reg_desc, "Control" },
{ &f12->data_reg_desc, "Data" },
};
struct rmi_device *rmi_dev = fn->rmi_dev;
int error;
int i;
for (i = 0; i < ARRAY_SIZE(descriptors); i++) {
error = rmi_read_register_desc(rmi_dev, query_addr,
descriptors[i].desc);
if (error) {
dev_err(&fn->dev,
"Failed to read the %s Register Descriptor: %d\n",
descriptors[i].name, error);
return error;
}
query_addr += 3;
}
return 0;
}
static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
{
const struct rmi_register_desc_item *item;
@@ -88,20 +118,20 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
if (item->reg_size > sizeof(buf)) {
dev_err(&fn->dev,
"F12 control8 should be no bigger than %zd bytes, not: %ld\n",
"F12 control8 should be no bigger than %zd bytes, not: %u\n",
sizeof(buf), item->reg_size);
return -ENODEV;
}
ret = rmi_read_block(rmi_dev, fn->fd.control_base_addr + offset, buf,
item->reg_size);
ret = rmi_read_block(rmi_dev, fn->fd.control_base_addr + offset,
buf, item->reg_size);
if (ret)
return ret;
offset = 0;
if (rmi_register_desc_has_subpacket(item, 0)) {
sensor->max_x = (buf[offset + 1] << 8) | buf[offset];
sensor->max_y = (buf[offset + 3] << 8) | buf[offset + 2];
sensor->max_x = get_unaligned_le16(&buf[offset]);
sensor->max_y = get_unaligned_le16(&buf[offset + 2]);
offset += 4;
}
@@ -109,8 +139,8 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
sensor->max_x, sensor->max_y);
if (rmi_register_desc_has_subpacket(item, 1)) {
pitch_x = (buf[offset + 1] << 8) | buf[offset];
pitch_y = (buf[offset + 3] << 8) | buf[offset + 2];
pitch_x = get_unaligned_le16(&buf[offset]);
pitch_y = get_unaligned_le16(&buf[offset + 2]);
offset += 4;
}
@@ -132,12 +162,12 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
if (rmi_get_register_desc_item(&f12->query_reg_desc,
RMI_F12_QUERY_RESOLUTION)) {
offset = rmi_register_desc_calc_reg_offset(&f12->query_reg_desc,
RMI_F12_QUERY_RESOLUTION);
RMI_F12_QUERY_RESOLUTION);
query_dpm_addr = fn->fd.query_base_addr + offset;
ret = rmi_read(fn->rmi_dev, query_dpm_addr, buf);
if (ret < 0) {
if (ret) {
dev_err(&fn->dev, "Failed to read DPM value: %d\n", ret);
return -ENODEV;
return ret;
}
dpm_resolution = buf[0];
@@ -164,14 +194,11 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
return 0;
}
static void rmi_f12_process_objects(struct f12_data *f12, u8 *data1, int size)
static void rmi_f12_process_objects(struct f12_data *f12, u8 *data1, u32 size)
{
int i;
struct rmi_2d_sensor *sensor = &f12->sensor;
int objects = f12->data1->num_subpackets;
if ((f12->data1->num_subpackets * F12_DATA1_BYTES_PER_OBJ) > size)
objects = size / F12_DATA1_BYTES_PER_OBJ;
u32 objects = min(f12->data1->num_subpackets, size / F12_DATA1_BYTES_PER_OBJ);
int i;
for (i = 0; i < objects; i++) {
struct rmi_2d_sensor_abs_object *obj = &sensor->objs[i];
@@ -196,8 +223,8 @@ static void rmi_f12_process_objects(struct f12_data *f12, u8 *data1, int size)
break;
}
obj->x = (data1[2] << 8) | data1[1];
obj->y = (data1[4] << 8) | data1[3];
obj->x = get_unaligned_le16(&data1[1]);
obj->y = get_unaligned_le16(&data1[3]);
obj->z = data1[5];
obj->wx = data1[6];
obj->wy = data1[7];
@@ -220,21 +247,17 @@ static void rmi_f12_process_objects(struct f12_data *f12, u8 *data1, int size)
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);
struct rmi_2d_sensor *sensor = &f12->sensor;
int valid_bytes = sensor->pkt_size;
u32 valid_bytes = sensor->pkt_size;
int retval;
if (drvdata->attn_data.data) {
if (sensor->attn_size > drvdata->attn_data.size)
valid_bytes = drvdata->attn_data.size;
else
valid_bytes = sensor->attn_size;
memcpy(sensor->data_pkt, drvdata->attn_data.data,
valid_bytes);
valid_bytes = min_t(u32, sensor->attn_size, drvdata->attn_data.size);
memcpy(sensor->data_pkt, drvdata->attn_data.data, valid_bytes);
drvdata->attn_data.data += valid_bytes;
drvdata->attn_data.size -= valid_bytes;
} else {
@@ -248,92 +271,100 @@ static irqreturn_t rmi_f12_attention(int irq, void *ctx)
}
if (f12->data1)
rmi_f12_process_objects(f12,
&sensor->data_pkt[f12->data1_offset], valid_bytes);
rmi_f12_process_objects(f12, &sensor->data_pkt[f12->data1_offset],
valid_bytes);
input_mt_sync_frame(sensor->input);
return IRQ_HANDLED;
}
static int rmi_f12_write_control_regs(struct rmi_function *fn)
static int rmi_f12_update_dribble(struct rmi_function *fn, struct f12_data *f12)
{
int ret;
const struct rmi_register_desc_item *item;
struct rmi_device *rmi_dev = fn->rmi_dev;
struct f12_data *f12 = dev_get_drvdata(&fn->dev);
int control_size;
char buf[3];
u16 control_offset = 0;
u8 subpacket_offset = 0;
u16 control_offset;
u32 control_size;
int error;
u8 buf[3];
if (f12->has_dribble
&& (f12->sensor.dribble != RMI_REG_STATE_DEFAULT)) {
item = rmi_get_register_desc_item(&f12->control_reg_desc, 20);
if (item) {
control_offset = rmi_register_desc_calc_reg_offset(
&f12->control_reg_desc, 20);
item = rmi_get_register_desc_item(&f12->control_reg_desc, 20);
if (!item)
return 0;
/*
* The byte containing the EnableDribble bit will be
* in either byte 0 or byte 2 of control 20. Depending
* on the existence of subpacket 0. If control 20 is
* larger then 3 bytes, just read the first 3.
*/
control_size = min(item->reg_size, 3UL);
control_offset = rmi_register_desc_calc_reg_offset(&f12->control_reg_desc, 20);
ret = rmi_read_block(rmi_dev, fn->fd.control_base_addr
+ control_offset, buf, control_size);
if (ret)
return ret;
/*
* The byte containing the EnableDribble bit will be
* in either byte 0 or byte 2 of control 20. Depending
* on the existence of subpacket 0. If control 20 is
* larger then 3 bytes, just read the first 3.
*/
control_size = min(item->reg_size, 3U);
if (rmi_register_desc_has_subpacket(item, 0))
subpacket_offset += 1;
error = rmi_read_block(rmi_dev, fn->fd.control_base_addr + control_offset,
buf, control_size);
if (error)
return error;
switch (f12->sensor.dribble) {
case RMI_REG_STATE_OFF:
buf[subpacket_offset] &= ~BIT(2);
break;
case RMI_REG_STATE_ON:
buf[subpacket_offset] |= BIT(2);
break;
case RMI_REG_STATE_DEFAULT:
default:
break;
}
if (rmi_register_desc_has_subpacket(item, 0))
subpacket_offset += 1;
ret = rmi_write_block(rmi_dev,
fn->fd.control_base_addr + control_offset,
buf, control_size);
if (ret)
return ret;
}
switch (f12->sensor.dribble) {
case RMI_REG_STATE_OFF:
buf[subpacket_offset] &= ~BIT(2);
break;
case RMI_REG_STATE_ON:
buf[subpacket_offset] |= BIT(2);
break;
case RMI_REG_STATE_DEFAULT:
default:
break;
}
return 0;
error = rmi_write_block(rmi_dev, fn->fd.control_base_addr + control_offset,
buf, control_size);
if (error)
return error;
return 0;
}
static int rmi_f12_write_control_regs(struct rmi_function *fn)
{
struct f12_data *f12 = dev_get_drvdata(&fn->dev);
if (f12->has_dribble && f12->sensor.dribble != RMI_REG_STATE_DEFAULT)
return rmi_f12_update_dribble(fn, f12);
return 0;
}
static int rmi_f12_config(struct rmi_function *fn)
{
struct rmi_driver *drv = fn->rmi_dev->driver;
struct f12_data *f12 = dev_get_drvdata(&fn->dev);
struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
int irq_mask_size = BITS_TO_LONGS(drvdata->irq_count);
unsigned long *abs_mask = f12->irq_mask;
unsigned long *rel_mask = f12->irq_mask + irq_mask_size;
struct rmi_2d_sensor *sensor;
int ret;
sensor = &f12->sensor;
if (!sensor->report_abs)
drv->clear_irq_bits(fn->rmi_dev, f12->abs_mask);
drv->clear_irq_bits(fn->rmi_dev, abs_mask);
else
drv->set_irq_bits(fn->rmi_dev, f12->abs_mask);
drv->set_irq_bits(fn->rmi_dev, abs_mask);
drv->clear_irq_bits(fn->rmi_dev, f12->rel_mask);
drv->clear_irq_bits(fn->rmi_dev, rel_mask);
ret = rmi_f12_write_control_regs(fn);
if (ret)
dev_warn(&fn->dev,
"Failed to write F12 control registers: %d\n", ret);
"Failed to write F12 control registers: %d\n", ret);
return 0;
}
@@ -349,12 +380,14 @@ static int rmi_f12_probe(struct rmi_function *fn)
struct rmi_2d_sensor *sensor;
struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
u16 data_offset = 0;
int mask_size;
size_t data_offset = 0;
size_t pkt_size;
int irq_mask_size;
int i;
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s\n", __func__);
mask_size = BITS_TO_LONGS(drvdata->irq_count) * sizeof(unsigned long);
irq_mask_size = BITS_TO_LONGS(drvdata->irq_count);
ret = rmi_read(fn->rmi_dev, query_addr, &buf);
if (ret < 0) {
@@ -370,18 +403,13 @@ static int rmi_f12_probe(struct rmi_function *fn)
return -ENODEV;
}
f12 = devm_kzalloc(&fn->dev, sizeof(struct f12_data) + mask_size * 2,
GFP_KERNEL);
f12 = devm_kzalloc(&fn->dev, struct_size(f12, irq_mask, irq_mask_size * 2),
GFP_KERNEL);
if (!f12)
return -ENOMEM;
f12->abs_mask = (unsigned long *)((char *)f12
+ sizeof(struct f12_data));
f12->rel_mask = (unsigned long *)((char *)f12
+ sizeof(struct f12_data) + mask_size);
set_bit(fn->irq_pos, f12->abs_mask);
set_bit(fn->irq_pos + 1, f12->rel_mask);
set_bit(fn->irq_pos, f12->irq_mask);
set_bit(fn->irq_pos + 1, f12->irq_mask + irq_mask_size);
f12->has_dribble = !!(buf & BIT(3));
@@ -393,55 +421,32 @@ static int rmi_f12_probe(struct rmi_function *fn)
f12->sensor_pdata = pdata->sensor_pdata;
}
ret = rmi_read_register_desc(rmi_dev, query_addr,
&f12->query_reg_desc);
if (ret) {
dev_err(&fn->dev,
"Failed to read the Query Register Descriptor: %d\n",
ret);
ret = rmi_f12_read_register_descs(fn, f12, query_addr);
if (ret)
return ret;
}
query_addr += 3;
ret = rmi_read_register_desc(rmi_dev, query_addr,
&f12->control_reg_desc);
if (ret) {
dev_err(&fn->dev,
"Failed to read the Control Register Descriptor: %d\n",
ret);
return ret;
}
query_addr += 3;
ret = rmi_read_register_desc(rmi_dev, query_addr,
&f12->data_reg_desc);
if (ret) {
dev_err(&fn->dev,
"Failed to read the Data Register Descriptor: %d\n",
ret);
return ret;
}
query_addr += 3;
sensor = &f12->sensor;
sensor->fn = fn;
f12->data_addr = fn->fd.data_base_addr;
sensor->pkt_size = rmi_register_desc_calc_size(&f12->data_reg_desc);
pkt_size = rmi_register_desc_calc_size(&f12->data_reg_desc);
if (pkt_size > SZ_1M) {
dev_err(&fn->dev, "Invalid data packet size: %zu\n", pkt_size);
return -EINVAL;
}
sensor->pkt_size = pkt_size;
sensor->axis_align =
f12->sensor_pdata.axis_align;
sensor->axis_align = f12->sensor_pdata.axis_align;
sensor->x_mm = f12->sensor_pdata.x_mm;
sensor->y_mm = f12->sensor_pdata.y_mm;
sensor->dribble = f12->sensor_pdata.dribble;
if (sensor->sensor_type == rmi_sensor_default)
sensor->sensor_type =
f12->sensor_pdata.sensor_type;
sensor->sensor_type = f12->sensor_pdata.sensor_type;
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: data packet size: %d\n", __func__,
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: data packet size: %u\n", __func__,
sensor->pkt_size);
sensor->data_pkt = devm_kzalloc(&fn->dev, sensor->pkt_size, GFP_KERNEL);
sensor->data_pkt = devm_kmalloc(&fn->dev, sensor->pkt_size, GFP_KERNEL);
if (!sensor->data_pkt)
return -ENOMEM;
@@ -452,108 +457,86 @@ static int rmi_f12_probe(struct rmi_function *fn)
return ret;
/*
* Figure out what data is contained in the data registers. HID devices
* may have registers defined, but their data is not reported in the
* HID attention report. Registers which are not reported in the HID
* attention report check to see if the device is receiving data from
* HID attention reports.
* Identify available data registers and calculate their offsets within
* the attention report. For HID devices, only Data1 and Data5 are
* included in the report; other registers may be described but are
* not transmitted in the attention packet and thus skipped here.
*/
item = rmi_get_register_desc_item(&f12->data_reg_desc, 0);
if (item && !drvdata->attn_data.data)
data_offset += item->reg_size;
for (i = 0; i < 16; i++) {
item = rmi_get_register_desc_item(&f12->data_reg_desc, i);
if (!item)
continue;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 1);
if (item) {
f12->data1 = item;
f12->data1_offset = data_offset;
data_offset += item->reg_size;
sensor->nbr_fingers = item->num_subpackets;
sensor->report_abs = 1;
sensor->attn_size += item->reg_size;
}
/* HID attention reports only contain Data1 and Data5 */
if (drvdata->attn_data.data && i != 1 && i != 5)
continue;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 2);
if (item && !drvdata->attn_data.data)
data_offset += item->reg_size;
if (data_offset > U16_MAX) {
dev_err(&fn->dev, "Invalid offset for data%d: %zu\n",
i, data_offset);
return -EINVAL;
}
item = rmi_get_register_desc_item(&f12->data_reg_desc, 3);
if (item && !drvdata->attn_data.data)
data_offset += item->reg_size;
switch (i) {
case 1:
f12->data1 = item;
f12->data1_offset = data_offset;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 4);
if (item && !drvdata->attn_data.data)
data_offset += item->reg_size;
if (item->num_subpackets > 255) {
dev_err(&fn->dev,
"Too many fingers declared: %d\n",
item->num_subpackets);
return -EINVAL;
}
item = rmi_get_register_desc_item(&f12->data_reg_desc, 5);
if (item) {
f12->data5 = item;
f12->data5_offset = data_offset;
data_offset += item->reg_size;
sensor->attn_size += item->reg_size;
}
sensor->nbr_fingers = item->num_subpackets;
sensor->report_abs = 1;
sensor->attn_size += item->reg_size;
break;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 6);
if (item && !drvdata->attn_data.data) {
f12->data6 = item;
f12->data6_offset = data_offset;
data_offset += item->reg_size;
}
case 5:
f12->data5 = item;
f12->data5_offset = data_offset;
sensor->attn_size += item->reg_size;
break;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 7);
if (item && !drvdata->attn_data.data)
data_offset += item->reg_size;
case 6:
f12->data6 = item;
f12->data6_offset = data_offset;
break;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 8);
if (item && !drvdata->attn_data.data)
data_offset += item->reg_size;
case 9:
f12->data9 = item;
f12->data9_offset = data_offset;
if (!sensor->report_abs)
sensor->report_rel = 1;
break;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 9);
if (item && !drvdata->attn_data.data) {
f12->data9 = item;
f12->data9_offset = data_offset;
data_offset += item->reg_size;
if (!sensor->report_abs)
sensor->report_rel = 1;
}
case 15:
f12->data15 = item;
f12->data15_offset = data_offset;
break;
}
item = rmi_get_register_desc_item(&f12->data_reg_desc, 10);
if (item && !drvdata->attn_data.data)
data_offset += item->reg_size;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 11);
if (item && !drvdata->attn_data.data)
data_offset += item->reg_size;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 12);
if (item && !drvdata->attn_data.data)
data_offset += item->reg_size;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 13);
if (item && !drvdata->attn_data.data)
data_offset += item->reg_size;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 14);
if (item && !drvdata->attn_data.data)
data_offset += item->reg_size;
item = rmi_get_register_desc_item(&f12->data_reg_desc, 15);
if (item && !drvdata->attn_data.data) {
f12->data15 = item;
f12->data15_offset = data_offset;
data_offset += item->reg_size;
}
/* allocate the in-kernel tracking buffers */
sensor->tracking_pos = devm_kcalloc(&fn->dev,
sensor->nbr_fingers, sizeof(struct input_mt_pos),
GFP_KERNEL);
sensor->tracking_slots = devm_kcalloc(&fn->dev,
sensor->nbr_fingers, sizeof(int), GFP_KERNEL);
sensor->objs = devm_kcalloc(&fn->dev,
sensor->nbr_fingers,
sizeof(struct rmi_2d_sensor_abs_object),
GFP_KERNEL);
if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs)
sensor->tracking_pos = devm_kcalloc(&fn->dev, sensor->nbr_fingers,
sizeof(*sensor->tracking_pos),
GFP_KERNEL);
if (!sensor->tracking_pos)
return -ENOMEM;
sensor->tracking_slots = devm_kcalloc(&fn->dev, sensor->nbr_fingers,
sizeof(*sensor->tracking_slots),
GFP_KERNEL);
if (!sensor->tracking_slots)
return -ENOMEM;
sensor->objs = devm_kcalloc(&fn->dev, sensor->nbr_fingers,
sizeof(*sensor->objs), GFP_KERNEL);
if (!sensor->objs)
return -ENOMEM;
ret = rmi_2d_sensor_configure_input(fn, sensor);

View File

@@ -365,7 +365,7 @@ static const struct dev_pm_ops rmi_i2c_pm = {
};
static const struct i2c_device_id rmi_id[] = {
{ "rmi4_i2c" },
{ .name = "rmi4_i2c" },
{ }
};
MODULE_DEVICE_TABLE(i2c, rmi_id);

View File

@@ -413,7 +413,7 @@ static const struct dev_pm_ops rmi_smb_pm = {
};
static const struct i2c_device_id rmi_id[] = {
{ "rmi4_smbus" },
{ .name = "rmi4_smbus" },
{ }
};
MODULE_DEVICE_TABLE(i2c, rmi_id);

View File

@@ -188,16 +188,6 @@ config SERIO_RAW
To compile this driver as a module, choose M here: the
module will be called serio_raw.
config SERIO_XILINX_XPS_PS2
tristate "Xilinx XPS PS/2 Controller Support"
depends on PPC || MICROBLAZE
help
This driver supports XPS PS/2 IP from the Xilinx EDK on
PowerPC platform.
To compile this driver as a module, choose M here: the
module will be called xilinx_ps2.
config SERIO_ALTERA_PS2
tristate "Altera UP PS/2 controller"
depends on HAS_IOMEM

View File

@@ -23,7 +23,6 @@ obj-$(CONFIG_SERIO_SGI_IOC3) += ioc3kbd.o
obj-$(CONFIG_SERIO_LIBPS2) += libps2.o
obj-$(CONFIG_SERIO_RAW) += serio_raw.o
obj-$(CONFIG_SERIO_AMS_DELTA) += ams_delta_serio.o
obj-$(CONFIG_SERIO_XILINX_XPS_PS2) += xilinx_ps2.o
obj-$(CONFIG_SERIO_ALTERA_PS2) += altera_ps2.o
obj-$(CONFIG_SERIO_ARC_PS2) += arc_ps2.o
obj-$(CONFIG_SERIO_APBPS2) += apbps2.o

View File

@@ -140,7 +140,7 @@ static int apbps2_of_probe(struct platform_device *ofdev)
}
/* Find device address */
priv->regs = devm_platform_get_and_ioremap_resource(ofdev, 0, NULL);
priv->regs = devm_platform_ioremap_resource(ofdev, 0);
if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs);
@@ -148,7 +148,10 @@ static int apbps2_of_probe(struct platform_device *ofdev)
iowrite32be(0, &priv->regs->ctrl);
/* IRQ */
irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
irq = platform_get_irq(ofdev, 0);
if (irq < 0)
return irq;
err = devm_request_irq(&ofdev->dev, irq, apbps2_isr,
IRQF_SHARED, "apbps2", priv);
if (err) {

View File

@@ -1539,22 +1539,22 @@ static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *
}
static const struct pnp_device_id pnp_kbd_devids[] = {
{ .id = "PNP0300", .driver_data = 0 },
{ .id = "PNP0301", .driver_data = 0 },
{ .id = "PNP0302", .driver_data = 0 },
{ .id = "PNP0303", .driver_data = 0 },
{ .id = "PNP0304", .driver_data = 0 },
{ .id = "PNP0305", .driver_data = 0 },
{ .id = "PNP0306", .driver_data = 0 },
{ .id = "PNP0309", .driver_data = 0 },
{ .id = "PNP030a", .driver_data = 0 },
{ .id = "PNP030b", .driver_data = 0 },
{ .id = "PNP0320", .driver_data = 0 },
{ .id = "PNP0343", .driver_data = 0 },
{ .id = "PNP0344", .driver_data = 0 },
{ .id = "PNP0345", .driver_data = 0 },
{ .id = "CPQA0D7", .driver_data = 0 },
{ .id = "", },
{ .id = "PNP0300" },
{ .id = "PNP0301" },
{ .id = "PNP0302" },
{ .id = "PNP0303" },
{ .id = "PNP0304" },
{ .id = "PNP0305" },
{ .id = "PNP0306" },
{ .id = "PNP0309" },
{ .id = "PNP030a" },
{ .id = "PNP030b" },
{ .id = "PNP0320" },
{ .id = "PNP0343" },
{ .id = "PNP0344" },
{ .id = "PNP0345" },
{ .id = "CPQA0D7" },
{ }
};
MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids);
@@ -1569,18 +1569,18 @@ static struct pnp_driver i8042_pnp_kbd_driver = {
};
static const struct pnp_device_id pnp_aux_devids[] = {
{ .id = "AUI0200", .driver_data = 0 },
{ .id = "FJC6000", .driver_data = 0 },
{ .id = "FJC6001", .driver_data = 0 },
{ .id = "PNP0f03", .driver_data = 0 },
{ .id = "PNP0f0b", .driver_data = 0 },
{ .id = "PNP0f0e", .driver_data = 0 },
{ .id = "PNP0f12", .driver_data = 0 },
{ .id = "PNP0f13", .driver_data = 0 },
{ .id = "PNP0f19", .driver_data = 0 },
{ .id = "PNP0f1c", .driver_data = 0 },
{ .id = "SYN0801", .driver_data = 0 },
{ .id = "", },
{ .id = "AUI0200" },
{ .id = "FJC6000" },
{ .id = "FJC6001" },
{ .id = "PNP0f03" },
{ .id = "PNP0f0b" },
{ .id = "PNP0f0e" },
{ .id = "PNP0f12" },
{ .id = "PNP0f13" },
{ .id = "PNP0f19" },
{ .id = "PNP0f1c" },
{ .id = "SYN0801" },
{ },
};
MODULE_DEVICE_TABLE(pnp, pnp_aux_devids);

View File

@@ -1,7 +1,7 @@
/*
* userio kernel serio device emulation module
* Copyright (C) 2015 Red Hat
* Copyright (C) 2015 Stephen Chandler Paul <thatslyude@gmail.com>
* Copyright (C) 2015 Lyude Paul <thatslyude@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
@@ -206,6 +206,36 @@ static int userio_execute_cmd(struct userio_device *userio,
userio->serio->id.type = cmd->data;
break;
case USERIO_CMD_SET_PORT_EXTRA:
if (userio->running) {
dev_warn(userio_misc.this_device,
"Can't change port extra on an already running userio instance\n");
return -EBUSY;
}
userio->serio->id.extra = cmd->data;
break;
case USERIO_CMD_SET_PORT_ID:
if (userio->running) {
dev_warn(userio_misc.this_device,
"Can't change port id on an already running userio instance\n");
return -EBUSY;
}
userio->serio->id.id = cmd->data;
break;
case USERIO_CMD_SET_PORT_PROTO:
if (userio->running) {
dev_warn(userio_misc.this_device,
"Can't change port proto on an already running userio instance\n");
return -EBUSY;
}
userio->serio->id.proto = cmd->data;
break;
case USERIO_CMD_SEND_INTERRUPT:
if (!userio->running) {
dev_warn(userio_misc.this_device,
@@ -278,6 +308,6 @@ module_driver(userio_misc, misc_register, misc_deregister);
MODULE_ALIAS_MISCDEV(USERIO_MINOR);
MODULE_ALIAS("devname:" USERIO_NAME);
MODULE_AUTHOR("Stephen Chandler Paul <thatslyude@gmail.com>");
MODULE_AUTHOR("Lyude Paul <thatslyude@gmail.com>");
MODULE_DESCRIPTION("Virtual Serio Device Support");
MODULE_LICENSE("GPL");

View File

@@ -1,363 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Xilinx XPS PS/2 device driver
*
* (c) 2005 MontaVista Software, Inc.
* (c) 2008 Xilinx, Inc.
*/
#include <linux/module.h>
#include <linux/serio.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#define DRIVER_NAME "xilinx_ps2"
/* Register offsets for the xps2 device */
#define XPS2_SRST_OFFSET 0x00000000 /* Software Reset register */
#define XPS2_STATUS_OFFSET 0x00000004 /* Status register */
#define XPS2_RX_DATA_OFFSET 0x00000008 /* Receive Data register */
#define XPS2_TX_DATA_OFFSET 0x0000000C /* Transmit Data register */
#define XPS2_GIER_OFFSET 0x0000002C /* Global Interrupt Enable reg */
#define XPS2_IPISR_OFFSET 0x00000030 /* Interrupt Status register */
#define XPS2_IPIER_OFFSET 0x00000038 /* Interrupt Enable register */
/* Reset Register Bit Definitions */
#define XPS2_SRST_RESET 0x0000000A /* Software Reset */
/* Status Register Bit Positions */
#define XPS2_STATUS_RX_FULL 0x00000001 /* Receive Full */
#define XPS2_STATUS_TX_FULL 0x00000002 /* Transmit Full */
/*
* Bit definitions for ISR/IER registers. Both the registers have the same bit
* definitions and are only defined once.
*/
#define XPS2_IPIXR_WDT_TOUT 0x00000001 /* Watchdog Timeout Interrupt */
#define XPS2_IPIXR_TX_NOACK 0x00000002 /* Transmit No ACK Interrupt */
#define XPS2_IPIXR_TX_ACK 0x00000004 /* Transmit ACK (Data) Interrupt */
#define XPS2_IPIXR_RX_OVF 0x00000008 /* Receive Overflow Interrupt */
#define XPS2_IPIXR_RX_ERR 0x00000010 /* Receive Error Interrupt */
#define XPS2_IPIXR_RX_FULL 0x00000020 /* Receive Data Interrupt */
/* Mask for all the Transmit Interrupts */
#define XPS2_IPIXR_TX_ALL (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_TX_ACK)
/* Mask for all the Receive Interrupts */
#define XPS2_IPIXR_RX_ALL (XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR | \
XPS2_IPIXR_RX_FULL)
/* Mask for all the Interrupts */
#define XPS2_IPIXR_ALL (XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL | \
XPS2_IPIXR_WDT_TOUT)
/* Global Interrupt Enable mask */
#define XPS2_GIER_GIE_MASK 0x80000000
struct xps2data {
int irq;
spinlock_t lock;
void __iomem *base_address; /* virt. address of control registers */
unsigned int flags;
struct serio *serio; /* serio */
struct device *dev;
};
/************************************/
/* XPS PS/2 data transmission calls */
/************************************/
/**
* xps2_recv() - attempts to receive a byte from the PS/2 port.
* @drvdata: pointer to ps2 device private data structure
* @byte: address where the read data will be copied
*
* If there is any data available in the PS/2 receiver, this functions reads
* the data, otherwise it returns error.
*/
static int xps2_recv(struct xps2data *drvdata, u8 *byte)
{
u32 sr;
int status = -1;
/* If there is data available in the PS/2 receiver, read it */
sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET);
if (sr & XPS2_STATUS_RX_FULL) {
*byte = in_be32(drvdata->base_address + XPS2_RX_DATA_OFFSET);
status = 0;
}
return status;
}
/*********************/
/* Interrupt handler */
/*********************/
static irqreturn_t xps2_interrupt(int irq, void *dev_id)
{
struct xps2data *drvdata = dev_id;
u32 intr_sr;
u8 c;
int status;
/* Get the PS/2 interrupts and clear them */
intr_sr = in_be32(drvdata->base_address + XPS2_IPISR_OFFSET);
out_be32(drvdata->base_address + XPS2_IPISR_OFFSET, intr_sr);
/* Check which interrupt is active */
if (intr_sr & XPS2_IPIXR_RX_OVF)
dev_warn(drvdata->dev, "receive overrun error\n");
if (intr_sr & XPS2_IPIXR_RX_ERR)
drvdata->flags |= SERIO_PARITY;
if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT))
drvdata->flags |= SERIO_TIMEOUT;
if (intr_sr & XPS2_IPIXR_RX_FULL) {
status = xps2_recv(drvdata, &c);
/* Error, if a byte is not received */
if (status) {
dev_err(drvdata->dev,
"wrong rcvd byte count (%d)\n", status);
} else {
serio_interrupt(drvdata->serio, c, drvdata->flags);
drvdata->flags = 0;
}
}
return IRQ_HANDLED;
}
/*******************/
/* serio callbacks */
/*******************/
/**
* sxps2_write() - sends a byte out through the PS/2 port.
* @pserio: pointer to the serio structure of the PS/2 port
* @c: data that needs to be written to the PS/2 port
*
* This function checks if the PS/2 transmitter is empty and sends a byte.
* Otherwise it returns error. Transmission fails only when nothing is connected
* to the PS/2 port. Thats why, we do not try to resend the data in case of a
* failure.
*/
static int sxps2_write(struct serio *pserio, unsigned char c)
{
struct xps2data *drvdata = pserio->port_data;
u32 sr;
guard(spinlock_irqsave)(&drvdata->lock);
/* If the PS/2 transmitter is empty send a byte of data */
sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET);
if (sr & XPS2_STATUS_TX_FULL)
return -EAGAIN;
out_be32(drvdata->base_address + XPS2_TX_DATA_OFFSET, c);
return 0;
}
/**
* sxps2_open() - called when a port is opened by the higher layer.
* @pserio: pointer to the serio structure of the PS/2 device
*
* This function requests irq and enables interrupts for the PS/2 device.
*/
static int sxps2_open(struct serio *pserio)
{
struct xps2data *drvdata = pserio->port_data;
int error;
u8 c;
error = request_irq(drvdata->irq, &xps2_interrupt, 0,
DRIVER_NAME, drvdata);
if (error) {
dev_err(drvdata->dev,
"Couldn't allocate interrupt %d\n", drvdata->irq);
return error;
}
/* start reception by enabling the interrupts */
out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK);
out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL);
(void)xps2_recv(drvdata, &c);
return 0; /* success */
}
/**
* sxps2_close() - frees the interrupt.
* @pserio: pointer to the serio structure of the PS/2 device
*
* This function frees the irq and disables interrupts for the PS/2 device.
*/
static void sxps2_close(struct serio *pserio)
{
struct xps2data *drvdata = pserio->port_data;
/* Disable the PS2 interrupts */
out_be32(drvdata->base_address + XPS2_GIER_OFFSET, 0x00);
out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0x00);
free_irq(drvdata->irq, drvdata);
}
/**
* xps2_of_probe - probe method for the PS/2 device.
* @ofdev: pointer to OF device structure
*
* This function probes the PS/2 device in the device tree.
* It initializes the driver data structure and the hardware.
* It returns 0, if the driver is bound to the PS/2 device, or a negative
* value if there is an error.
*/
static int xps2_of_probe(struct platform_device *ofdev)
{
struct resource r_mem; /* IO mem resources */
struct xps2data *drvdata;
struct serio *serio;
struct device *dev = &ofdev->dev;
resource_size_t remap_size, phys_addr;
unsigned int irq;
int error;
dev_info(dev, "Device Tree Probing \'%pOFn\'\n", dev->of_node);
/* Get iospace for the device */
error = of_address_to_resource(dev->of_node, 0, &r_mem);
if (error) {
dev_err(dev, "invalid address\n");
return error;
}
/* Get IRQ for the device */
irq = irq_of_parse_and_map(dev->of_node, 0);
if (!irq) {
dev_err(dev, "no IRQ found\n");
return -ENODEV;
}
drvdata = kzalloc_obj(*drvdata);
serio = kzalloc_obj(*serio);
if (!drvdata || !serio) {
error = -ENOMEM;
goto failed1;
}
spin_lock_init(&drvdata->lock);
drvdata->irq = irq;
drvdata->serio = serio;
drvdata->dev = dev;
phys_addr = r_mem.start;
remap_size = resource_size(&r_mem);
if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
(unsigned long long)phys_addr);
error = -EBUSY;
goto failed1;
}
/* Fill in configuration data and add them to the list */
drvdata->base_address = ioremap(phys_addr, remap_size);
if (drvdata->base_address == NULL) {
dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
(unsigned long long)phys_addr);
error = -EFAULT;
goto failed2;
}
/* Disable all the interrupts, just in case */
out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);
/*
* Reset the PS2 device and abort any current transaction,
* to make sure we have the PS2 in a good state.
*/
out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);
dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n",
(unsigned long long)phys_addr, drvdata->base_address,
drvdata->irq);
serio->id.type = SERIO_8042;
serio->write = sxps2_write;
serio->open = sxps2_open;
serio->close = sxps2_close;
serio->port_data = drvdata;
serio->dev.parent = dev;
snprintf(serio->name, sizeof(serio->name),
"Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr);
snprintf(serio->phys, sizeof(serio->phys),
"xilinxps2/serio at %08llX", (unsigned long long)phys_addr);
serio_register_port(serio);
platform_set_drvdata(ofdev, drvdata);
return 0; /* success */
failed2:
release_mem_region(phys_addr, remap_size);
failed1:
kfree(serio);
kfree(drvdata);
return error;
}
/**
* xps2_of_remove - unbinds the driver from the PS/2 device.
* @of_dev: pointer to OF device structure
*
* This function is called if a device is physically removed from the system or
* if the driver module is being unloaded. It frees any resources allocated to
* the device.
*/
static void xps2_of_remove(struct platform_device *of_dev)
{
struct xps2data *drvdata = platform_get_drvdata(of_dev);
struct resource r_mem; /* IO mem resources */
serio_unregister_port(drvdata->serio);
iounmap(drvdata->base_address);
/* Get iospace of the device */
if (of_address_to_resource(of_dev->dev.of_node, 0, &r_mem))
dev_err(drvdata->dev, "invalid address\n");
else
release_mem_region(r_mem.start, resource_size(&r_mem));
kfree(drvdata);
}
/* Match table for of_platform binding */
static const struct of_device_id xps2_of_match[] = {
{ .compatible = "xlnx,xps-ps2-1.00.a", },
{ /* end of list */ },
};
MODULE_DEVICE_TABLE(of, xps2_of_match);
static struct platform_driver xps2_of_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = xps2_of_match,
},
.probe = xps2_of_probe,
.remove = xps2_of_remove,
};
module_platform_driver(xps2_of_driver);
MODULE_AUTHOR("Xilinx, Inc.");
MODULE_DESCRIPTION("Xilinx XPS PS/2 driver");
MODULE_LICENSE("GPL");

View File

@@ -16,37 +16,6 @@
*
* Many thanks to Oliver Kuechemann for his support.
*
* ChangeLog:
* v0.1 - Initial release
* v0.2 - Hack to get around fake event 28's. (Bryan W. Headley)
* v0.3 - Make URB dynamic (Bryan W. Headley, Jun-8-2002)
* Released to Linux 2.4.19 and 2.5.x
* v0.4 - Rewrote substantial portions of the code to deal with
* corrected control sequences, timing, dynamic configuration,
* support of 6000U - 12000U, procfs, and macro key support
* (Jan-1-2003 - Feb-5-2003, Bryan W. Headley)
* v1.0 - Added support for diagnostic messages, count of messages
* received from URB - Mar-8-2003, Bryan W. Headley
* v1.1 - added support for tablet resolution, changed DV and proximity
* some corrections - Jun-22-2003, martin schneebacher
* - Added support for the sysfs interface, deprecating the
* procfs interface for 2.5.x kernel. Also added support for
* Wheel command. Bryan W. Headley July-15-2003.
* v1.2 - Reworked jitter timer as a kernel thread.
* Bryan W. Headley November-28-2003/Jan-10-2004.
* v1.3 - Repaired issue of kernel thread going nuts on single-processor
* machines, introduced programmableDelay as a command line
* parameter. Feb 7 2004, Bryan W. Headley.
* v1.4 - Re-wire jitter so it does not require a thread. Courtesy of
* Rene van Paassen. Added reporting of physical pointer device
* (e.g., stylus, mouse in reports 2, 3, 4, 5. We don't know
* for reports 1, 6.)
* what physical device reports for reports 1, 6.) Also enabled
* MOUSE and LENS tool button modes. Renamed "rubber" to "eraser".
* Feb 20, 2004, Bryan W. Headley.
* v1.5 - Added previousJitterable, so we don't do jitter delay when the
* user is holding a button down for periods of time.
*
* NOTE:
* This kernel driver is augmented by the "Aiptek" XFree86 input
* driver for your X server, as well as the Gaiptek GUI Front-end

View File

@@ -610,6 +610,18 @@ config TOUCHSCREEN_WACOM_I2C
To compile this driver as a module, choose M here: the module
will be called wacom_i2c.
config TOUCHSCREEN_WACOM_W9000
tristate "Wacom W9000-series penabled touchscreen (I2C)"
depends on I2C
help
Say Y here if you have a Wacom W9000-series penabled I2C touchscreen.
This driver supports models W9002 and W9007A.
If unsure, say N.
To compile this driver as a module, choose M here: the module
will be called wacom_w9000.
config TOUCHSCREEN_LPC32XX
tristate "LPC32XX touchscreen controller"
depends on ARCH_LPC32XX
@@ -1178,16 +1190,6 @@ config TOUCHSCREEN_TSC2007_IIO
or ambient light monitoring), temperature and raw input
values.
config TOUCHSCREEN_PCAP
tristate "Motorola PCAP touchscreen"
depends on EZX_PCAP
help
Say Y here if you have a Motorola EZX telephone and
want to enable support for the built-in touchscreen.
To compile this driver as a module, choose M here: the
module will be called pcap_ts.
config TOUCHSCREEN_RM_TS
tristate "Raydium I2C Touchscreen"
depends on I2C

View File

@@ -74,7 +74,6 @@ obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o
obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o
obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
obj-$(CONFIG_TOUCHSCREEN_PIXCIR) += pixcir_i2c_ts.o
obj-$(CONFIG_TOUCHSCREEN_RM_TS) += raydium_i2c_ts.o
@@ -101,6 +100,7 @@ tsc2007-$(CONFIG_TOUCHSCREEN_TSC2007_IIO) += tsc2007_iio.o
obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o
obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o
obj-$(CONFIG_TOUCHSCREEN_WACOM_I2C) += wacom_i2c.o
obj-$(CONFIG_TOUCHSCREEN_WACOM_W9000) += wacom_w9000.o
obj-$(CONFIG_TOUCHSCREEN_WDT87XX_I2C) += wdt87xx_i2c.o
obj-$(CONFIG_TOUCHSCREEN_WM831X) += wm831x-ts.o
obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o

View File

@@ -42,8 +42,8 @@ static int ad7879_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id ad7879_id[] = {
{ "ad7879" },
{ "ad7889" },
{ .name = "ad7879" },
{ .name = "ad7889" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad7879_id);

View File

@@ -134,6 +134,9 @@ struct ads7846 {
bool disabled; /* P: lock */
bool suspended; /* P: lock */
int (*setup_spi_msg)(struct ads7846 *ts,
const struct ads7846_platform_data *pdata);
void (*read_state)(struct ads7846 *ts);
int (*filter)(void *data, int data_idx, int *val);
void *filter_data;
int (*get_pendown_state)(void);
@@ -325,7 +328,6 @@ struct ser_req {
u8 ref_on;
u8 command;
u8 ref_off;
u16 scratch;
struct spi_message msg;
struct spi_transfer xfer[8];
/*
@@ -333,6 +335,7 @@ struct ser_req {
* transfer buffers to live in their own cache lines.
*/
__be16 sample ____cacheline_aligned;
u16 scratch;
};
struct ads7845_ser_req {
@@ -403,8 +406,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
spi_message_add_tail(&req->xfer[5], &req->msg);
/* clear the command register */
req->scratch = 0;
req->xfer[6].tx_buf = &req->scratch;
req->xfer[6].rx_buf = &req->scratch;
req->xfer[6].len = 1;
spi_message_add_tail(&req->xfer[6], &req->msg);
@@ -789,6 +791,22 @@ static int ads7846_filter(struct ads7846 *ts)
return 0;
}
static int ads7846_filter_one(struct ads7846 *ts, unsigned int cmd_idx)
{
struct ads7846_packet *packet = ts->packet;
struct ads7846_buf_layout *l = &packet->l[cmd_idx];
int action, val;
val = ads7846_get_value(&packet->rx[l->offset + l->count - 1]);
action = ts->filter(ts->filter_data, cmd_idx, &val);
if (action == ADS7846_FILTER_REPEAT)
return -EAGAIN;
else if (action != ADS7846_FILTER_OK)
return -EIO;
ads7846_set_cmd_val(ts, cmd_idx, val);
return 0;
}
static void ads7846_wait_for_hsync(struct ads7846 *ts)
{
if (ts->wait_for_sync) {
@@ -811,6 +829,45 @@ static void ads7846_wait_for_hsync(struct ads7846 *ts)
cpu_relax();
}
static void ads7846_halfd_read_state(struct ads7846 *ts)
{
struct ads7846_packet *packet = ts->packet;
int msg_idx = 0;
packet->ignore = false;
while (msg_idx < ts->msg_count) {
int error;
ads7846_wait_for_hsync(ts);
error = spi_sync(ts->spi, &ts->msg[msg_idx]);
if (error) {
dev_err_ratelimited(&ts->spi->dev, "spi_sync --> %d\n",
error);
packet->ignore = true;
return;
}
/*
* Last message is power down request, no need to convert
* or filter the value.
*/
if (msg_idx == ts->msg_count - 1)
break;
error = ads7846_filter_one(ts, msg_idx);
if (error == -EAGAIN) {
continue;
} else if (error) {
packet->ignore = true;
msg_idx = ts->msg_count - 1;
} else {
msg_idx++;
}
}
}
static void ads7846_read_state(struct ads7846 *ts)
{
struct ads7846_packet *packet = ts->packet;
@@ -939,7 +996,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle)
while (!ts->stopped && get_pendown_state(ts)) {
/* pen is down, continue with the measurement */
ads7846_read_state(ts);
ts->read_state(ts);
if (!ts->stopped)
ads7846_report_state(ts);
@@ -1022,6 +1079,102 @@ static int ads7846_setup_pendown(struct spi_device *spi,
return 0;
}
/*
* Set up the transfers to read touchscreen state; this assumes we
* use formula #2 for pressure, not #3.
*/
static int ads7846_halfd_spi_msg(struct ads7846 *ts,
const struct ads7846_platform_data *pdata)
{
struct spi_message *m = ts->msg;
struct spi_transfer *x = ts->xfer;
struct ads7846_packet *packet = ts->packet;
int vref = pdata->keep_vref_on;
unsigned int offset = 0;
unsigned int cmd_idx, b;
size_t size = 0;
if (pdata->settle_delay_usecs)
packet->count = 2;
else
packet->count = 1;
if (ts->model == 7846)
packet->cmds = 5; /* x, y, z1, z2, pwdown */
else
packet->cmds = 3; /* x, y, pwdown */
for (cmd_idx = 0; cmd_idx < packet->cmds; cmd_idx++) {
struct ads7846_buf_layout *l = &packet->l[cmd_idx];
unsigned int max_count;
if (cmd_idx == packet->cmds - 1) {
cmd_idx = ADS7846_PWDOWN;
max_count = 1;
} else {
max_count = packet->count;
}
l->offset = offset;
offset += max_count;
l->count = max_count;
l->skip = 0;
size += sizeof(*packet->rx) * max_count;
}
/* We use two transfers per command. */
if (ARRAY_SIZE(ts->xfer) < offset * 2)
return -ENOMEM;
packet->rx = devm_kzalloc(&ts->spi->dev, size, GFP_KERNEL);
if (!packet->rx)
return -ENOMEM;
if (ts->model == 7873) {
/*
* The AD7873 is almost identical to the ADS7846
* keep VREF off during differential/ratiometric
* conversion modes.
*/
ts->model = 7846;
vref = 0;
}
ts->msg_count = 0;
for (cmd_idx = 0; cmd_idx < packet->cmds; cmd_idx++) {
struct ads7846_buf_layout *l = &packet->l[cmd_idx];
u8 cmd;
ts->msg_count++;
spi_message_init(m);
m->context = ts;
if (cmd_idx == packet->cmds - 1)
cmd_idx = ADS7846_PWDOWN;
cmd = ads7846_get_cmd(cmd_idx, vref);
for (b = 0; b < l->count; b++) {
packet->rx[l->offset + b].cmd = cmd;
x->tx_buf = &packet->rx[l->offset + b].cmd;
x->len = 1;
spi_message_add_tail(x, m);
x++;
x->rx_buf = &packet->rx[l->offset + b].data;
x->len = 2;
if (b < l->count - 1 && l->count > 1) {
x->delay.value = pdata->settle_delay_usecs;
x->delay.unit = SPI_DELAY_UNIT_USECS;
}
spi_message_add_tail(x, m);
x++;
}
m++;
}
return 0;
}
/*
* Set up the transfers to read touchscreen state; this assumes we
* use formula #2 for pressure, not #3.
@@ -1236,6 +1389,14 @@ static int ads7846_probe(struct spi_device *spi)
if (!ts)
return -ENOMEM;
if (spi->controller->flags & SPI_CONTROLLER_HALF_DUPLEX) {
ts->setup_spi_msg = ads7846_halfd_spi_msg;
ts->read_state = ads7846_halfd_read_state;
} else {
ts->setup_spi_msg = ads7846_setup_spi_msg;
ts->read_state = ads7846_read_state;
}
packet = devm_kzalloc(dev, sizeof(struct ads7846_packet), GFP_KERNEL);
if (!packet)
return -ENOMEM;
@@ -1330,7 +1491,9 @@ static int ads7846_probe(struct spi_device *spi)
ts->core_prop.swap_x_y = true;
}
ads7846_setup_spi_msg(ts, pdata);
err = ts->setup_spi_msg(ts, pdata);
if (err)
return err;
ts->reg = devm_regulator_get(dev, "vcc");
if (IS_ERR(ts->reg)) {

View File

@@ -164,7 +164,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(ar1021_i2c_pm,
ar1021_i2c_suspend, ar1021_i2c_resume);
static const struct i2c_device_id ar1021_i2c_id[] = {
{ "ar1021" },
{ .name = "ar1021" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ar1021_i2c_id);

View File

@@ -1397,7 +1397,8 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data, struct mxt_cfg *cfg)
{
struct device *dev = &data->client->dev;
struct mxt_object *object;
unsigned int type, instance, size, byte_offset;
unsigned int type, instance, size;
int byte_offset;
int offset;
int ret;
int i;
@@ -2840,14 +2841,12 @@ static ssize_t mxt_object_show(struct device *dev,
int count = 0;
int i, j;
int error;
u8 *obuf;
/* Pre-allocate buffer large enough to hold max sized object. */
obuf = kmalloc(256, GFP_KERNEL);
u8 *obuf __free(kfree) = kmalloc(256, GFP_KERNEL);
if (!obuf)
return -ENOMEM;
error = 0;
for (i = 0; i < data->info->object_num; i++) {
object = data->object_table + i;
@@ -2862,15 +2861,13 @@ static ssize_t mxt_object_show(struct device *dev,
error = __mxt_read_reg(data->client, addr, size, obuf);
if (error)
goto done;
return error;
count = mxt_show_instance(buf, count, object, j, obuf);
}
}
done:
kfree(obuf);
return error ?: count;
return count;
}
static int mxt_check_firmware_format(struct device *dev,
@@ -3420,11 +3417,11 @@ MODULE_DEVICE_TABLE(acpi, mxt_acpi_id);
#endif
static const struct i2c_device_id mxt_id[] = {
{ "qt602240_ts" },
{ "atmel_mxt_ts" },
{ "atmel_mxt_tp" },
{ "maxtouch" },
{ "mXT224" },
{ .name = "qt602240_ts" },
{ .name = "atmel_mxt_ts" },
{ .name = "atmel_mxt_tp" },
{ .name = "maxtouch" },
{ .name = "mXT224" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mxt_id);

View File

@@ -618,7 +618,7 @@ static int auo_pixcir_probe(struct i2c_client *client)
}
static const struct i2c_device_id auo_pixcir_idtable[] = {
{ "auo_pixcir_ts" },
{ .name = "auo_pixcir_ts" },
{ }
};
MODULE_DEVICE_TABLE(i2c, auo_pixcir_idtable);

View File

@@ -597,7 +597,7 @@ static int bu21013_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(bu21013_dev_pm_ops, bu21013_suspend, bu21013_resume);
static const struct i2c_device_id bu21013_id[] = {
{ DRIVER_TP },
{ .name = DRIVER_TP },
{ }
};
MODULE_DEVICE_TABLE(i2c, bu21013_id);

View File

@@ -442,7 +442,7 @@ static int bu21029_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(bu21029_pm_ops, bu21029_suspend, bu21029_resume);
static const struct i2c_device_id bu21029_ids[] = {
{ DRIVER_NAME },
{ .name = DRIVER_NAME },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, bu21029_ids);

View File

@@ -322,7 +322,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(cy8ctma140_pm,
cy8ctma140_suspend, cy8ctma140_resume);
static const struct i2c_device_id cy8ctma140_idtable[] = {
{ CY8CTMA140_NAME },
{ .name = CY8CTMA140_NAME },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, cy8ctma140_idtable);

View File

@@ -267,7 +267,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(cy8ctmg110_pm,
cy8ctmg110_suspend, cy8ctmg110_resume);
static const struct i2c_device_id cy8ctmg110_idtable[] = {
{ CY8CTMG110_DRIVER_NAME, 1 },
{ .name = CY8CTMG110_DRIVER_NAME, .driver_data = 1 },
{ }
};

View File

@@ -938,7 +938,7 @@ static const struct of_device_id cyttsp5_of_match[] = {
MODULE_DEVICE_TABLE(of, cyttsp5_of_match);
static const struct i2c_device_id cyttsp5_i2c_id[] = {
{ CYTTSP5_NAME },
{ .name = CYTTSP5_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, cyttsp5_i2c_id);

View File

@@ -103,7 +103,7 @@ static int cyttsp_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id cyttsp_i2c_id[] = {
{ CY_I2C_NAME },
{ .name = CY_I2C_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, cyttsp_i2c_id);

View File

@@ -266,7 +266,7 @@ static int eeti_ts_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume);
static const struct i2c_device_id eeti_ts_id[] = {
{ "eeti_ts" },
{ .name = "eeti_ts" },
{ }
};
MODULE_DEVICE_TABLE(i2c, eeti_ts_id);

View File

@@ -219,7 +219,7 @@ static int egalax_ts_probe(struct i2c_client *client)
}
static const struct i2c_device_id egalax_ts_id[] = {
{ "egalax_ts" },
{ .name = "egalax_ts" },
{ }
};
MODULE_DEVICE_TABLE(i2c, egalax_ts_id);

View File

@@ -1615,9 +1615,9 @@ static DEFINE_SIMPLE_DEV_PM_OPS(elants_i2c_pm_ops,
elants_i2c_suspend, elants_i2c_resume);
static const struct i2c_device_id elants_i2c_id[] = {
{ DEVICE_NAME, EKTH3500 },
{ "ekth3500", EKTH3500 },
{ "ektf3624", EKTF3624 },
{ .name = DEVICE_NAME, .driver_data = EKTH3500 },
{ .name = "ekth3500", .driver_data = EKTH3500 },
{ .name = "ektf3624", .driver_data = EKTF3624 },
{ }
};
MODULE_DEVICE_TABLE(i2c, elants_i2c_id);

View File

@@ -432,10 +432,10 @@ static int exc3000_probe(struct i2c_client *client)
}
static const struct i2c_device_id exc3000_id[] = {
{ "exc3000", EETI_EXC3000 },
{ "exc80h60", EETI_EXC80H60 },
{ "exc80h84", EETI_EXC80H84 },
{ "exc81w32", EETI_EXC81W32 },
{ .name = "exc3000", .driver_data = EETI_EXC3000 },
{ .name = "exc80h60", .driver_data = EETI_EXC80H60 },
{ .name = "exc80h84", .driver_data = EETI_EXC80H84 },
{ .name = "exc81w32", .driver_data = EETI_EXC81W32 },
{ }
};
MODULE_DEVICE_TABLE(i2c, exc3000_id);

View File

@@ -1057,7 +1057,8 @@ static void goodix_read_config(struct goodix_ts_data *ts)
}
ts->int_trigger_type = ts->config[TRIGGER_LOC] & 0x03;
ts->max_touch_num = ts->config[MAX_CONTACTS_LOC] & 0x0f;
ts->max_touch_num = min(ts->config[MAX_CONTACTS_LOC] & 0x0f,
GOODIX_MAX_CONTACTS);
x_max = get_unaligned_le16(&ts->config[RESOLUTION_LOC]);
y_max = get_unaligned_le16(&ts->config[RESOLUTION_LOC + 2]);
@@ -1523,7 +1524,7 @@ static int goodix_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(goodix_pm_ops, goodix_suspend, goodix_resume);
static const struct i2c_device_id goodix_ts_id[] = {
{ "GDIX1001:00" },
{ .name = "GDIX1001:00" },
{ }
};
MODULE_DEVICE_TABLE(i2c, goodix_ts_id);

View File

@@ -1081,7 +1081,7 @@ static int hideep_probe(struct i2c_client *client)
}
static const struct i2c_device_id hideep_i2c_id[] = {
{ HIDEEP_I2C_NAME },
{ .name = HIDEEP_I2C_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, hideep_i2c_id);

View File

@@ -406,8 +406,8 @@ static const struct himax_chip hx83112b_chip = {
};
static const struct i2c_device_id himax_ts_id[] = {
{ "hx83100a", (kernel_ulong_t)&hx83100a_chip },
{ "hx83112b", (kernel_ulong_t)&hx83112b_chip },
{ .name = "hx83100a", .driver_data = (kernel_ulong_t)&hx83100a_chip },
{ .name = "hx83112b", .driver_data = (kernel_ulong_t)&hx83112b_chip },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, himax_ts_id);

View File

@@ -226,7 +226,7 @@ static int cst816x_probe(struct i2c_client *client)
}
static const struct i2c_device_id cst816x_id[] = {
{ .name = "cst816s", 0 },
{ .name = "cst816s" },
{ }
};
MODULE_DEVICE_TABLE(i2c, cst816x_id);

View File

@@ -1049,10 +1049,10 @@ static int ili210x_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id ili210x_i2c_id[] = {
{ "ili210x", (long)&ili210x_chip },
{ "ili2117", (long)&ili211x_chip },
{ "ili2120", (long)&ili212x_chip },
{ "ili251x", (long)&ili251x_chip },
{ .name = "ili210x", .driver_data = (long)&ili210x_chip },
{ .name = "ili2117", .driver_data = (long)&ili211x_chip },
{ .name = "ili2120", .driver_data = (long)&ili212x_chip },
{ .name = "ili251x", .driver_data = (long)&ili251x_chip },
{ }
};
MODULE_DEVICE_TABLE(i2c, ili210x_i2c_id);

View File

@@ -639,7 +639,7 @@ static int ilitek_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(ilitek_pm_ops, ilitek_suspend, ilitek_resume);
static const struct i2c_device_id ilitek_ts_i2c_id[] = {
{ ILITEK_TS_NAME },
{ .name = ILITEK_TS_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, ilitek_ts_i2c_id);

View File

@@ -1049,9 +1049,9 @@ static int iqs5xx_probe(struct i2c_client *client)
}
static const struct i2c_device_id iqs5xx_id[] = {
{ "iqs550", 0 },
{ "iqs572", 1 },
{ "iqs525", 2 },
{ .name = "iqs550" },
{ .name = "iqs572" },
{ .name = "iqs525" },
{ }
};
MODULE_DEVICE_TABLE(i2c, iqs5xx_id);

View File

@@ -213,7 +213,7 @@ static int max11801_ts_probe(struct i2c_client *client)
}
static const struct i2c_device_id max11801_ts_id[] = {
{ "max11801" },
{ .name = "max11801" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max11801_ts_id);

View File

@@ -1536,7 +1536,7 @@ MODULE_DEVICE_TABLE(acpi, mip4_acpi_match);
#endif
static const struct i2c_device_id mip4_i2c_ids[] = {
{ MIP4_DEVICE_NAME },
{ .name = MIP4_DEVICE_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, mip4_i2c_ids);

View File

@@ -211,7 +211,7 @@ static int migor_ts_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(migor_ts_pm, migor_ts_suspend, migor_ts_resume);
static const struct i2c_device_id migor_ts_id[] = {
{ "migor_ts" },
{ .name = "migor_ts" },
{ }
};
MODULE_DEVICE_TABLE(i2c, migor_ts_id);

View File

@@ -217,7 +217,9 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id)
struct mms114_data *data = dev_id;
struct i2c_client *client = data->client;
struct mms114_touch touch[MMS114_MAX_TOUCH];
struct mms114_touch *t;
int packet_size;
int event_size;
int touch_size;
int index;
int error;
@@ -226,11 +228,19 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id)
if (packet_size <= 0)
goto out;
if (packet_size > sizeof(touch)) {
dev_err(&client->dev, "Invalid packet size %d (max %zu)\n",
packet_size, sizeof(touch));
goto out;
}
/* MMS136 has slightly different event size */
if (data->type == TYPE_MMS134S || data->type == TYPE_MMS136)
touch_size = packet_size / MMS136_EVENT_SIZE;
event_size = MMS136_EVENT_SIZE;
else
touch_size = packet_size / MMS114_EVENT_SIZE;
event_size = MMS114_EVENT_SIZE;
touch_size = packet_size / event_size;
error = __mms114_read_reg(data, MMS114_INFORMATION, packet_size,
(u8 *)touch);
@@ -238,18 +248,20 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id)
goto out;
for (index = 0; index < touch_size; index++) {
switch (touch[index].type) {
t = (struct mms114_touch *)((u8 *)touch + index * event_size);
switch (t->type) {
case MMS114_TYPE_TOUCHSCREEN:
mms114_process_mt(data, touch + index);
mms114_process_mt(data, t);
break;
case MMS114_TYPE_TOUCHKEY:
mms114_process_touchkey(data, touch + index);
mms114_process_touchkey(data, t);
break;
default:
dev_err(&client->dev, "Wrong touch type (%d)\n",
touch[index].type);
t->type);
break;
}
}
@@ -667,7 +679,7 @@ static int mms114_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(mms114_pm_ops, mms114_suspend, mms114_resume);
static const struct i2c_device_id mms114_id[] = {
{ "mms114" },
{ .name = "mms114" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mms114_id);

View File

@@ -326,8 +326,8 @@ static const struct of_device_id nvt_ts_of_match[] = {
MODULE_DEVICE_TABLE(of, nvt_ts_of_match);
static const struct i2c_device_id nvt_ts_i2c_id[] = {
{ "nt11205-ts", (unsigned long) &nvt_nt11205_ts_data },
{ "nt36672a-ts", (unsigned long) &nvt_nt36672a_ts_data },
{ .name = "nt11205-ts", .driver_data = (unsigned long)&nvt_nt11205_ts_data },
{ .name = "nt36672a-ts", .driver_data = (unsigned long)&nvt_nt36672a_ts_data },
{ }
};
MODULE_DEVICE_TABLE(i2c, nvt_ts_i2c_id);

View File

@@ -1,252 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Driver for Motorola PCAP2 touchscreen as found in the EZX phone platform.
*
* Copyright (C) 2006 Harald Welte <laforge@openezx.org>
* Copyright (C) 2009 Daniel Ribeiro <drwyrm@gmail.com>
*/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/pm.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/mfd/ezx-pcap.h>
struct pcap_ts {
struct pcap_chip *pcap;
struct input_dev *input;
struct delayed_work work;
u16 x, y;
u16 pressure;
u8 read_state;
};
#define SAMPLE_DELAY 20 /* msecs */
#define X_AXIS_MIN 0
#define X_AXIS_MAX 1023
#define Y_AXIS_MAX X_AXIS_MAX
#define Y_AXIS_MIN X_AXIS_MIN
#define PRESSURE_MAX X_AXIS_MAX
#define PRESSURE_MIN X_AXIS_MIN
static void pcap_ts_read_xy(void *data, u16 res[2])
{
struct pcap_ts *pcap_ts = data;
switch (pcap_ts->read_state) {
case PCAP_ADC_TS_M_PRESSURE:
/* pressure reading is unreliable */
if (res[0] > PRESSURE_MIN && res[0] < PRESSURE_MAX)
pcap_ts->pressure = res[0];
pcap_ts->read_state = PCAP_ADC_TS_M_XY;
schedule_delayed_work(&pcap_ts->work, 0);
break;
case PCAP_ADC_TS_M_XY:
pcap_ts->y = res[0];
pcap_ts->x = res[1];
if (pcap_ts->x <= X_AXIS_MIN || pcap_ts->x >= X_AXIS_MAX ||
pcap_ts->y <= Y_AXIS_MIN || pcap_ts->y >= Y_AXIS_MAX) {
/* pen has been released */
input_report_abs(pcap_ts->input, ABS_PRESSURE, 0);
input_report_key(pcap_ts->input, BTN_TOUCH, 0);
pcap_ts->read_state = PCAP_ADC_TS_M_STANDBY;
schedule_delayed_work(&pcap_ts->work, 0);
} else {
/* pen is touching the screen */
input_report_abs(pcap_ts->input, ABS_X, pcap_ts->x);
input_report_abs(pcap_ts->input, ABS_Y, pcap_ts->y);
input_report_key(pcap_ts->input, BTN_TOUCH, 1);
input_report_abs(pcap_ts->input, ABS_PRESSURE,
pcap_ts->pressure);
/* switch back to pressure read mode */
pcap_ts->read_state = PCAP_ADC_TS_M_PRESSURE;
schedule_delayed_work(&pcap_ts->work,
msecs_to_jiffies(SAMPLE_DELAY));
}
input_sync(pcap_ts->input);
break;
default:
dev_warn(&pcap_ts->input->dev,
"pcap_ts: Warning, unhandled read_state %d\n",
pcap_ts->read_state);
break;
}
}
static void pcap_ts_work(struct work_struct *work)
{
struct delayed_work *dw = to_delayed_work(work);
struct pcap_ts *pcap_ts = container_of(dw, struct pcap_ts, work);
u8 ch[2];
pcap_set_ts_bits(pcap_ts->pcap,
pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT);
if (pcap_ts->read_state == PCAP_ADC_TS_M_STANDBY)
return;
/* start adc conversion */
ch[0] = PCAP_ADC_CH_TS_X1;
ch[1] = PCAP_ADC_CH_TS_Y1;
pcap_adc_async(pcap_ts->pcap, PCAP_ADC_BANK_1, 0, ch,
pcap_ts_read_xy, pcap_ts);
}
static irqreturn_t pcap_ts_event_touch(int pirq, void *data)
{
struct pcap_ts *pcap_ts = data;
if (pcap_ts->read_state == PCAP_ADC_TS_M_STANDBY) {
pcap_ts->read_state = PCAP_ADC_TS_M_PRESSURE;
schedule_delayed_work(&pcap_ts->work, 0);
}
return IRQ_HANDLED;
}
static int pcap_ts_open(struct input_dev *dev)
{
struct pcap_ts *pcap_ts = input_get_drvdata(dev);
pcap_ts->read_state = PCAP_ADC_TS_M_STANDBY;
schedule_delayed_work(&pcap_ts->work, 0);
return 0;
}
static void pcap_ts_close(struct input_dev *dev)
{
struct pcap_ts *pcap_ts = input_get_drvdata(dev);
cancel_delayed_work_sync(&pcap_ts->work);
pcap_ts->read_state = PCAP_ADC_TS_M_NONTS;
pcap_set_ts_bits(pcap_ts->pcap,
pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT);
}
static int pcap_ts_probe(struct platform_device *pdev)
{
struct input_dev *input_dev;
struct pcap_ts *pcap_ts;
int err = -ENOMEM;
pcap_ts = kzalloc_obj(*pcap_ts);
if (!pcap_ts)
return err;
pcap_ts->pcap = dev_get_drvdata(pdev->dev.parent);
platform_set_drvdata(pdev, pcap_ts);
input_dev = input_allocate_device();
if (!input_dev)
goto fail;
INIT_DELAYED_WORK(&pcap_ts->work, pcap_ts_work);
pcap_ts->read_state = PCAP_ADC_TS_M_NONTS;
pcap_set_ts_bits(pcap_ts->pcap,
pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT);
pcap_ts->input = input_dev;
input_set_drvdata(input_dev, pcap_ts);
input_dev->name = "pcap-touchscreen";
input_dev->phys = "pcap_ts/input0";
input_dev->id.bustype = BUS_HOST;
input_dev->id.vendor = 0x0001;
input_dev->id.product = 0x0002;
input_dev->id.version = 0x0100;
input_dev->dev.parent = &pdev->dev;
input_dev->open = pcap_ts_open;
input_dev->close = pcap_ts_close;
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN,
PRESSURE_MAX, 0, 0);
err = input_register_device(pcap_ts->input);
if (err)
goto fail_allocate;
err = request_irq(pcap_to_irq(pcap_ts->pcap, PCAP_IRQ_TS),
pcap_ts_event_touch, 0, "Touch Screen", pcap_ts);
if (err)
goto fail_register;
return 0;
fail_register:
input_unregister_device(input_dev);
goto fail;
fail_allocate:
input_free_device(input_dev);
fail:
kfree(pcap_ts);
return err;
}
static void pcap_ts_remove(struct platform_device *pdev)
{
struct pcap_ts *pcap_ts = platform_get_drvdata(pdev);
free_irq(pcap_to_irq(pcap_ts->pcap, PCAP_IRQ_TS), pcap_ts);
cancel_delayed_work_sync(&pcap_ts->work);
input_unregister_device(pcap_ts->input);
kfree(pcap_ts);
}
#ifdef CONFIG_PM
static int pcap_ts_suspend(struct device *dev)
{
struct pcap_ts *pcap_ts = dev_get_drvdata(dev);
pcap_set_ts_bits(pcap_ts->pcap, PCAP_ADC_TS_REF_LOWPWR);
return 0;
}
static int pcap_ts_resume(struct device *dev)
{
struct pcap_ts *pcap_ts = dev_get_drvdata(dev);
pcap_set_ts_bits(pcap_ts->pcap,
pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT);
return 0;
}
static const struct dev_pm_ops pcap_ts_pm_ops = {
.suspend = pcap_ts_suspend,
.resume = pcap_ts_resume,
};
#define PCAP_TS_PM_OPS (&pcap_ts_pm_ops)
#else
#define PCAP_TS_PM_OPS NULL
#endif
static struct platform_driver pcap_ts_driver = {
.probe = pcap_ts_probe,
.remove = pcap_ts_remove,
.driver = {
.name = "pcap-ts",
.pm = PCAP_TS_PM_OPS,
},
};
module_platform_driver(pcap_ts_driver);
MODULE_DESCRIPTION("Motorola PCAP2 touchscreen driver");
MODULE_AUTHOR("Daniel Ribeiro / Harald Welte");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pcap_ts");

View File

@@ -580,8 +580,8 @@ static const struct pixcir_i2c_chip_data pixcir_tangoc_data = {
};
static const struct i2c_device_id pixcir_i2c_ts_id[] = {
{ "pixcir_ts", (unsigned long) &pixcir_ts_data },
{ "pixcir_tangoc", (unsigned long) &pixcir_tangoc_data },
{ .name = "pixcir_ts", .driver_data = (unsigned long)&pixcir_ts_data },
{ .name = "pixcir_tangoc", .driver_data = (unsigned long)&pixcir_tangoc_data },
{ }
};
MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id);

View File

@@ -1219,8 +1219,8 @@ static DEFINE_SIMPLE_DEV_PM_OPS(raydium_i2c_pm_ops,
raydium_i2c_suspend, raydium_i2c_resume);
static const struct i2c_device_id raydium_i2c_id[] = {
{ "raydium_i2c" },
{ "rm32380" },
{ .name = "raydium_i2c" },
{ .name = "rm32380" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, raydium_i2c_id);

View File

@@ -1144,7 +1144,7 @@ static int rohm_bu21023_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id rohm_bu21023_i2c_id[] = {
{ BU21023_NAME },
{ .name = BU21023_NAME },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, rohm_bu21023_i2c_id);

View File

@@ -520,7 +520,7 @@ MODULE_DEVICE_TABLE(of, s6sy761_of_match);
#endif
static const struct i2c_device_id s6sy761_id[] = {
{ "s6sy761" },
{ .name = "s6sy761" },
{ }
};
MODULE_DEVICE_TABLE(i2c, s6sy761_id);

View File

@@ -776,12 +776,12 @@ static int silead_ts_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(silead_ts_pm, silead_ts_suspend, silead_ts_resume);
static const struct i2c_device_id silead_ts_id[] = {
{ "gsl1680" },
{ "gsl1688" },
{ "gsl3670" },
{ "gsl3675" },
{ "gsl3692" },
{ "mssl1680" },
{ .name = "gsl1680" },
{ .name = "gsl1688" },
{ .name = "gsl3670" },
{ .name = "gsl3675" },
{ .name = "gsl3692" },
{ .name = "mssl1680" },
{ }
};
MODULE_DEVICE_TABLE(i2c, silead_ts_id);

View File

@@ -374,8 +374,8 @@ MODULE_DEVICE_TABLE(of, sis_ts_dt_ids);
#endif
static const struct i2c_device_id sis_ts_id[] = {
{ SIS_I2C_NAME },
{ "9200-ts" },
{ .name = SIS_I2C_NAME },
{ .name = "9200-ts" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, sis_ts_id);

View File

@@ -453,8 +453,8 @@ static DEFINE_SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops,
st1232_ts_suspend, st1232_ts_resume);
static const struct i2c_device_id st1232_ts_id[] = {
{ ST1232_TS_NAME, (unsigned long)&st1232_chip_info },
{ ST1633_TS_NAME, (unsigned long)&st1633_chip_info },
{ .name = ST1232_TS_NAME, .driver_data = (unsigned long)&st1232_chip_info },
{ .name = ST1633_TS_NAME, .driver_data = (unsigned long)&st1633_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, st1232_ts_id);

View File

@@ -5,6 +5,7 @@
// Copyright (c) 2017 Andi Shyti <andi@etezian.org>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
@@ -69,20 +70,21 @@
#define STMFTS_MAX_FINGERS 10
#define STMFTS_DEV_NAME "stmfts"
enum stmfts_regulators {
STMFTS_REGULATOR_VDD,
STMFTS_REGULATOR_AVDD,
static const struct regulator_bulk_data stmfts_supplies[] = {
{ .supply = "vdd" },
{ .supply = "avdd" },
};
struct stmfts_data {
struct i2c_client *client;
struct input_dev *input;
struct gpio_desc *reset_gpio;
struct led_classdev led_cdev;
struct mutex mutex;
struct touchscreen_properties prop;
struct regulator_bulk_data regulators[2];
struct regulator_bulk_data *supplies;
/*
* Presence of ledvdd will be used also to check
@@ -107,7 +109,7 @@ struct stmfts_data {
};
static int stmfts_brightness_set(struct led_classdev *led_cdev,
enum led_brightness value)
enum led_brightness value)
{
struct stmfts_data *sdata = container_of(led_cdev,
struct stmfts_data, led_cdev);
@@ -250,7 +252,6 @@ static void stmfts_parse_events(struct stmfts_data *sdata)
u8 *event = &sdata->data[i * STMFTS_EVENT_SIZE];
switch (event[0]) {
case STMFTS_EV_CONTROLLER_READY:
case STMFTS_EV_SLEEP_OUT_CONTROLLER_READY:
case STMFTS_EV_STATUS:
@@ -263,7 +264,6 @@ static void stmfts_parse_events(struct stmfts_data *sdata)
}
switch (event[0] & STMFTS_MASK_EVENT_ID) {
case STMFTS_EV_MULTI_TOUCH_ENTER:
case STMFTS_EV_MULTI_TOUCH_MOTION:
stmfts_report_contact_event(sdata, event);
@@ -285,9 +285,9 @@ static void stmfts_parse_events(struct stmfts_data *sdata)
case STMFTS_EV_ERROR:
dev_warn(&sdata->client->dev,
"error code: 0x%x%x%x%x%x%x",
event[6], event[5], event[4],
event[3], event[2], event[1]);
"error code: 0x%x%x%x%x%x%x",
event[6], event[5], event[4],
event[3], event[2], event[1]);
break;
default:
@@ -404,7 +404,7 @@ static void stmfts_input_close(struct input_dev *dev)
}
static ssize_t stmfts_sysfs_chip_id(struct device *dev,
struct device_attribute *attr, char *buf)
struct device_attribute *attr, char *buf)
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
@@ -412,7 +412,8 @@ static ssize_t stmfts_sysfs_chip_id(struct device *dev,
}
static ssize_t stmfts_sysfs_chip_version(struct device *dev,
struct device_attribute *attr, char *buf)
struct device_attribute *attr,
char *buf)
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
@@ -420,7 +421,7 @@ static ssize_t stmfts_sysfs_chip_version(struct device *dev,
}
static ssize_t stmfts_sysfs_fw_ver(struct device *dev,
struct device_attribute *attr, char *buf)
struct device_attribute *attr, char *buf)
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
@@ -428,7 +429,7 @@ static ssize_t stmfts_sysfs_fw_ver(struct device *dev,
}
static ssize_t stmfts_sysfs_config_id(struct device *dev,
struct device_attribute *attr, char *buf)
struct device_attribute *attr, char *buf)
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
@@ -436,7 +437,8 @@ static ssize_t stmfts_sysfs_config_id(struct device *dev,
}
static ssize_t stmfts_sysfs_config_version(struct device *dev,
struct device_attribute *attr, char *buf)
struct device_attribute *attr,
char *buf)
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
@@ -444,7 +446,8 @@ static ssize_t stmfts_sysfs_config_version(struct device *dev,
}
static ssize_t stmfts_sysfs_read_status(struct device *dev,
struct device_attribute *attr, char *buf)
struct device_attribute *attr,
char *buf)
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
u8 status[4];
@@ -459,7 +462,8 @@ static ssize_t stmfts_sysfs_read_status(struct device *dev,
}
static ssize_t stmfts_sysfs_hover_enable_read(struct device *dev,
struct device_attribute *attr, char *buf)
struct device_attribute *attr,
char *buf)
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
@@ -467,8 +471,8 @@ static ssize_t stmfts_sysfs_hover_enable_read(struct device *dev,
}
static ssize_t stmfts_sysfs_hover_enable_write(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
struct device_attribute *attr,
const char *buf, size_t len)
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
unsigned long value;
@@ -485,8 +489,8 @@ static ssize_t stmfts_sysfs_hover_enable_write(struct device *dev,
if (hover != sdata->hover_enabled) {
if (sdata->running) {
err = i2c_smbus_write_byte(sdata->client,
value ? STMFTS_SS_HOVER_SENSE_ON :
STMFTS_SS_HOVER_SENSE_OFF);
value ? STMFTS_SS_HOVER_SENSE_ON :
STMFTS_SS_HOVER_SENSE_OFF);
if (err)
return err;
}
@@ -518,22 +522,11 @@ static struct attribute *stmfts_sysfs_attrs[] = {
};
ATTRIBUTE_GROUPS(stmfts_sysfs);
static int stmfts_power_on(struct stmfts_data *sdata)
static int stmfts_read_system_info(struct stmfts_data *sdata)
{
int err;
u8 reg[8];
err = regulator_bulk_enable(ARRAY_SIZE(sdata->regulators),
sdata->regulators);
if (err)
return err;
/*
* The datasheet does not specify the power on time, but considering
* that the reset time is < 10ms, I sleep 20ms to be sure
*/
msleep(20);
err = i2c_smbus_read_i2c_block_data(sdata->client, STMFTS_READ_INFO,
sizeof(reg), reg);
if (err < 0)
@@ -547,9 +540,21 @@ static int stmfts_power_on(struct stmfts_data *sdata)
sdata->config_id = reg[4];
sdata->config_ver = reg[5];
enable_irq(sdata->client->irq);
return 0;
}
static void stmfts_reset(struct stmfts_data *sdata)
{
gpiod_set_value_cansleep(sdata->reset_gpio, 1);
msleep(20);
gpiod_set_value_cansleep(sdata->reset_gpio, 0);
msleep(50);
}
static int stmfts_configure(struct stmfts_data *sdata)
{
int err;
err = stmfts_command(sdata, STMFTS_SYSTEM_RESET);
if (err)
@@ -575,13 +580,52 @@ static int stmfts_power_on(struct stmfts_data *sdata)
if (err)
return err;
return 0;
}
static int stmfts_power_on(struct stmfts_data *sdata)
{
int err;
err = regulator_bulk_enable(ARRAY_SIZE(stmfts_supplies),
sdata->supplies);
if (err)
return err;
/*
* The datasheet does not specify the power on time, but considering
* that the reset time is < 10ms, I sleep 20ms to be sure
*/
msleep(20);
if (sdata->reset_gpio)
stmfts_reset(sdata);
err = stmfts_read_system_info(sdata);
if (err)
goto err_disable_regulators;
enable_irq(sdata->client->irq);
msleep(50);
err = stmfts_configure(sdata);
if (err)
goto err_disable_irq;
/*
* At this point no one is using the touchscreen
* and I don't really care about the return value
*/
(void) i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
(void)i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
return 0;
err_disable_irq:
disable_irq(sdata->client->irq);
err_disable_regulators:
regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies), sdata->supplies);
return err;
}
static void stmfts_power_off(void *data)
@@ -589,8 +633,11 @@ static void stmfts_power_off(void *data)
struct stmfts_data *sdata = data;
disable_irq(sdata->client->irq);
regulator_bulk_disable(ARRAY_SIZE(sdata->regulators),
sdata->regulators);
if (sdata->reset_gpio)
gpiod_set_value_cansleep(sdata->reset_gpio, 1);
regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies), sdata->supplies);
}
static int stmfts_enable_led(struct stmfts_data *sdata)
@@ -619,6 +666,7 @@ static int stmfts_enable_led(struct stmfts_data *sdata)
static int stmfts_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
int err;
struct stmfts_data *sdata;
@@ -627,7 +675,7 @@ static int stmfts_probe(struct i2c_client *client)
I2C_FUNC_SMBUS_I2C_BLOCK))
return -ENODEV;
sdata = devm_kzalloc(&client->dev, sizeof(*sdata), GFP_KERNEL);
sdata = devm_kzalloc(dev, sizeof(*sdata), GFP_KERNEL);
if (!sdata)
return -ENOMEM;
@@ -637,15 +685,19 @@ static int stmfts_probe(struct i2c_client *client)
mutex_init(&sdata->mutex);
init_completion(&sdata->cmd_done);
sdata->regulators[STMFTS_REGULATOR_VDD].supply = "vdd";
sdata->regulators[STMFTS_REGULATOR_AVDD].supply = "avdd";
err = devm_regulator_bulk_get(&client->dev,
ARRAY_SIZE(sdata->regulators),
sdata->regulators);
err = devm_regulator_bulk_get_const(dev,
ARRAY_SIZE(stmfts_supplies),
stmfts_supplies,
&sdata->supplies);
if (err)
return err;
sdata->input = devm_input_allocate_device(&client->dev);
sdata->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(sdata->reset_gpio))
return dev_err_probe(dev, PTR_ERR(sdata->reset_gpio),
"Failed to get GPIO 'reset'\n");
sdata->input = devm_input_allocate_device(dev);
if (!sdata->input)
return -ENOMEM;
@@ -664,8 +716,7 @@ static int stmfts_probe(struct i2c_client *client)
input_set_abs_params(sdata->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
input_set_abs_params(sdata->input, ABS_DISTANCE, 0, 255, 0, 0);
sdata->use_key = device_property_read_bool(&client->dev,
"touch-key-connected");
sdata->use_key = device_property_read_bool(dev, "touch-key-connected");
if (sdata->use_key) {
input_set_capability(sdata->input, EV_KEY, KEY_MENU);
input_set_capability(sdata->input, EV_KEY, KEY_BACK);
@@ -685,20 +736,20 @@ static int stmfts_probe(struct i2c_client *client)
* interrupts. To be on the safe side it's better to not enable
* the interrupts during their request.
*/
err = devm_request_threaded_irq(&client->dev, client->irq,
err = devm_request_threaded_irq(dev, client->irq,
NULL, stmfts_irq_handler,
IRQF_ONESHOT | IRQF_NO_AUTOEN,
"stmfts_irq", sdata);
if (err)
return err;
dev_dbg(&client->dev, "initializing ST-Microelectronics FTS...\n");
dev_dbg(dev, "initializing ST-Microelectronics FTS...\n");
err = stmfts_power_on(sdata);
if (err)
return err;
err = devm_add_action_or_reset(&client->dev, stmfts_power_off, sdata);
err = devm_add_action_or_reset(dev, stmfts_power_off, sdata);
if (err)
return err;
@@ -715,13 +766,13 @@ static int stmfts_probe(struct i2c_client *client)
* without LEDs. The ledvdd regulator pointer will be
* used as a flag.
*/
dev_warn(&client->dev, "unable to use touchkey leds\n");
dev_warn(dev, "unable to use touchkey leds\n");
sdata->ledvdd = NULL;
}
}
pm_runtime_enable(&client->dev);
device_enable_async_suspend(&client->dev);
pm_runtime_enable(dev);
device_enable_async_suspend(dev);
return 0;
}
@@ -746,9 +797,10 @@ static int stmfts_runtime_suspend(struct device *dev)
static int stmfts_runtime_resume(struct device *dev)
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
struct i2c_client *client = sdata->client;
int ret;
ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_OUT);
ret = i2c_smbus_write_byte(client, STMFTS_SLEEP_OUT);
if (ret)
dev_err(dev, "failed to resume device: %d\n", ret);
@@ -785,7 +837,7 @@ MODULE_DEVICE_TABLE(of, stmfts_of_match);
#endif
static const struct i2c_device_id stmfts_id[] = {
{ "stmfts" },
{ .name = "stmfts" },
{ }
};
MODULE_DEVICE_TABLE(i2c, stmfts_id);
@@ -807,4 +859,4 @@ module_i2c_driver(stmfts_driver);
MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>");
MODULE_DESCRIPTION("STMicroelectronics FTS Touch Screen");
MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL");

Some files were not shown because too many files have changed in this diff Show More