Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input updates from Dmitry Torokhov:

 - a new GPIO bit-banging driver implementing PS/2 protocol

 - a new power key driver for Rockchip RK805 PMIC

 - bunch of patches constifying various device ID structures

 - Elan I2C touchpad driver now supports devices with 2 buttons

 - other assorted fixes

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (76 commits)
  Input: byd - make array seq static, reduces object code size
  Input: xilinx_ps2 - fix multiline comment style
  Input: pxa27x_keypad - handle return value of clk_prepare_enable
  Input: tegra-kbc - handle return value of clk_prepare_enable
  Input: PS/2 gpio bit banging driver for serio bus
  Input: xen-kbdfront - enable auto repeat for xen keyboard frontend driver
  Input: ambakmi - constify amba_id
  Input: atmel_mxt_ts - add support for reset line
  Input: atmel_mxt_ts - use more managed resources
  Input: wacom_w8001 - constify serio_device_id
  Input: tsc40 - constify serio_device_id
  Input: touchwin - constify serio_device_id
  Input: touchright - constify serio_device_id
  Input: touchit213 - constify serio_device_id
  Input: penmount - constify serio_device_id
  Input: mtouch - constify serio_device_id
  Input: inexio - constify serio_device_id
  Input: hampshire - constify serio_device_id
  Input: gunze - constify serio_device_id
  Input: fujitsu_ts - constify serio_device_id
  ...
This commit is contained in:
Linus Torvalds 2017-09-07 13:39:21 -07:00
commit 9d71941d39
80 changed files with 947 additions and 190 deletions

View File

@ -22,6 +22,8 @@ Optional properties for main touchpad device:
experiment to determine which bit corresponds to which input. Use
KEY_RESERVED for unused padding values.
- reset-gpios: GPIO specifier for the touchscreen's reset pin (active low)
Example:
touch@4b {

View File

@ -0,0 +1,23 @@
Device-Tree binding for ps/2 gpio device
Required properties:
- compatible = "ps2-gpio"
- data-gpios: the data pin
- clk-gpios: the clock pin
- interrupts: Should trigger on the falling edge of the clock line.
Optional properties:
- write-enable: Indicates whether write function is provided
to serio device. Possibly providing the write fn will not work, because
of the tough timing requirements.
Example nodes:
ps2@0 {
compatible = "ps2-gpio";
interrupt-parent = <&gpio>;
interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
data-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
clk-gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
write-enable;
};

View File

@ -84,6 +84,11 @@ hardware descriptions such as device tree or ACPI:
NAND flash MTD subsystem and provides chip access and partition parsing like
any other NAND driving hardware.
- ps2-gpio: drivers/input/serio/ps2-gpio.c is used to drive a PS/2 (IBM) serio
bus, data and clock line, by bit banging two GPIO lines. It will appear as
any other serio bus to the system and makes it possible to connect drivers
for e.g. keyboards and other PS/2 protocol based devices.
Apart from this there are special GPIO drivers in subsystems like MMC/SD to
read card detect and write protect GPIO lines, and in the TTY serial subsystem
to emulate MCTRL (modem control) signals CTS/RTS by using two GPIO lines. The

View File

@ -377,7 +377,7 @@ static struct gpiod_lookup_table raumfeld_rotary_gpios_table = {
},
};
static struct property_entry raumfeld_rotary_properties[] = {
static const struct property_entry raumfeld_rotary_properties[] __initconst = {
PROPERTY_ENTRY_INTEGER("rotary-encoder,steps-per-period", u32, 24),
PROPERTY_ENTRY_INTEGER("linux,axis", u32, REL_X),
PROPERTY_ENTRY_INTEGER("rotary-encoder,relative_axis", u32, 1),

View File

@ -1398,7 +1398,7 @@ static struct attribute *input_dev_attrs[] = {
NULL
};
static struct attribute_group input_dev_attr_group = {
static const struct attribute_group input_dev_attr_group = {
.attrs = input_dev_attrs,
};
@ -1425,7 +1425,7 @@ static struct attribute *input_dev_id_attrs[] = {
NULL
};
static struct attribute_group input_dev_id_attr_group = {
static const struct attribute_group input_dev_id_attr_group = {
.name = "id",
.attrs = input_dev_id_attrs,
};
@ -1495,7 +1495,7 @@ static struct attribute *input_dev_caps_attrs[] = {
NULL
};
static struct attribute_group input_dev_caps_attr_group = {
static const struct attribute_group input_dev_caps_attr_group = {
.name = "capabilities",
.attrs = input_dev_caps_attrs,
};

View File

@ -164,7 +164,7 @@ static void iforce_serio_disconnect(struct serio *serio)
kfree(iforce);
}
static struct serio_device_id iforce_serio_ids[] = {
static const struct serio_device_id iforce_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_IFORCE,

View File

@ -209,7 +209,7 @@ static void iforce_usb_disconnect(struct usb_interface *intf)
kfree(iforce);
}
static struct usb_device_id iforce_usb_ids [] = {
static const struct usb_device_id iforce_usb_ids[] = {
{ USB_DEVICE(0x044f, 0xa01c) }, /* Thrustmaster Motor Sport GT */
{ USB_DEVICE(0x046d, 0xc281) }, /* Logitech WingMan Force */
{ USB_DEVICE(0x046d, 0xc291) }, /* Logitech WingMan Formula Force */

View File

@ -198,7 +198,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id magellan_serio_ids[] = {
static const struct serio_device_id magellan_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_MAGELLAN,

View File

@ -272,7 +272,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id spaceball_serio_ids[] = {
static const struct serio_device_id spaceball_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_SPACEBALL,

View File

@ -213,7 +213,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id spaceorb_serio_ids[] = {
static const struct serio_device_id spaceorb_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_SPACEORB,

View File

@ -184,7 +184,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id stinger_serio_ids[] = {
static const struct serio_device_id stinger_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_STINGER,

View File

@ -233,7 +233,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id twidjoy_serio_ids[] = {
static const struct serio_device_id twidjoy_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_TWIDJOY,

View File

@ -193,7 +193,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id warrior_serio_ids[] = {
static const struct serio_device_id warrior_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_WARRIOR,

View File

@ -408,7 +408,7 @@ static const signed short xpad_abs_triggers[] = {
#define XPAD_XBOXONE_VENDOR(vend) \
{ XPAD_XBOXONE_VENDOR_PROTOCOL(vend, 208) }
static struct usb_device_id xpad_table[] = {
static const struct usb_device_id xpad_table[] = {
{ USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */
XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */

View File

@ -192,7 +192,7 @@ static int zhenhua_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id zhenhua_serio_ids[] = {
static const struct serio_device_id zhenhua_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_ZHENHUA,

View File

@ -1270,7 +1270,7 @@ static int atkbd_reconnect(struct serio *serio)
return retval;
}
static struct serio_device_id atkbd_serio_ids[] = {
static const struct serio_device_id atkbd_serio_ids[] = {
{
.type = SERIO_8042,
.proto = SERIO_ANY,

View File

@ -353,7 +353,7 @@ static struct attribute *gpio_keys_attrs[] = {
NULL,
};
static struct attribute_group gpio_keys_attr_group = {
static const struct attribute_group gpio_keys_attr_group = {
.attrs = gpio_keys_attrs,
};

View File

@ -559,7 +559,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
return error;
}
static struct serio_device_id hil_dev_ids[] = {
static const struct serio_device_id hil_dev_ids[] = {
{
.type = SERIO_HIL_MLC,
.proto = SERIO_HIL,

View File

@ -707,7 +707,7 @@ static void lkkbd_disconnect(struct serio *serio)
kfree(lk);
}
static struct serio_device_id lkkbd_serio_ids[] = {
static const struct serio_device_id lkkbd_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_LKKBD,

View File

@ -142,7 +142,7 @@ static void nkbd_disconnect(struct serio *serio)
kfree(nkbd);
}
static struct serio_device_id nkbd_serio_ids[] = {
static const struct serio_device_id nkbd_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_NEWTON,

View File

@ -644,9 +644,12 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad)
static int pxa27x_keypad_open(struct input_dev *dev)
{
struct pxa27x_keypad *keypad = input_get_drvdata(dev);
int ret;
/* Enable unit clock */
clk_prepare_enable(keypad->clk);
ret = clk_prepare_enable(keypad->clk);
if (ret)
return ret;
pxa27x_keypad_config(keypad);
return 0;
@ -683,6 +686,7 @@ static int pxa27x_keypad_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
struct input_dev *input_dev = keypad->input_dev;
int ret = 0;
/*
* If the keypad is used as wake up source, the clock is not turned
@ -695,14 +699,15 @@ static int pxa27x_keypad_resume(struct device *dev)
if (input_dev->users) {
/* Enable unit clock */
clk_prepare_enable(keypad->clk);
pxa27x_keypad_config(keypad);
ret = clk_prepare_enable(keypad->clk);
if (!ret)
pxa27x_keypad_config(keypad);
}
mutex_unlock(&input_dev->mutex);
}
return 0;
return ret;
}
#endif

View File

@ -146,7 +146,7 @@ static void skbd_disconnect(struct serio *serio)
kfree(skbd);
}
static struct serio_device_id skbd_serio_ids[] = {
static const struct serio_device_id skbd_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_STOWAWAY,

View File

@ -339,7 +339,7 @@ static void sunkbd_disconnect(struct serio *serio)
kfree(sunkbd);
}
static struct serio_device_id sunkbd_serio_ids[] = {
static const struct serio_device_id sunkbd_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_SUNKBD,

View File

@ -370,8 +370,11 @@ static int tegra_kbc_start(struct tegra_kbc *kbc)
{
unsigned int debounce_cnt;
u32 val = 0;
int ret;
clk_prepare_enable(kbc->clk);
ret = clk_prepare_enable(kbc->clk);
if (ret)
return ret;
/* Reset the KBC controller to clear all previous status.*/
reset_control_assert(kbc->rst);

View File

@ -145,7 +145,7 @@ static void xtkbd_disconnect(struct serio *serio)
kfree(xtkbd);
}
static struct serio_device_id xtkbd_serio_ids[] = {
static const struct serio_device_id xtkbd_serio_ids[] = {
{
.type = SERIO_XT,
.proto = SERIO_ANY,

View File

@ -581,6 +581,17 @@ config INPUT_PWM_BEEPER
To compile this driver as a module, choose M here: the module will be
called pwm-beeper.
config INPUT_RK805_PWRKEY
tristate "Rockchip RK805 PMIC power key support"
depends on MFD_RK808
help
Select this option to enable power key driver for RK805.
If unsure, say N.
To compile this driver as a module, choose M here: the module will be
called rk805_pwrkey.
config INPUT_GPIO_ROTARY_ENCODER
tristate "Rotary encoders connected to GPIO pins"
depends on GPIOLIB || COMPILE_TEST

View File

@ -64,6 +64,7 @@ obj-$(CONFIG_INPUT_REGULATOR_HAPTIC) += regulator-haptic.o
obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o
obj-$(CONFIG_INPUT_AXP20X_PEK) += axp20x-pek.o
obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
obj-$(CONFIG_INPUT_RK805_PWRKEY) += rk805-pwrkey.o
obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o
obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o

View File

@ -110,7 +110,7 @@ static const struct kernel_param_ops param_ops_mode_mask = {
module_param(mode_mask, mode_mask, 0644);
MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
static struct usb_device_id ati_remote2_id_table[] = {
static const struct usb_device_id ati_remote2_id_table[] = {
{ USB_DEVICE(0x0471, 0x0602) }, /* ATI Remote Wonder II */
{ }
};

View File

@ -29,9 +29,17 @@
#define AXP20X_PEK_STARTUP_MASK (0xc0)
#define AXP20X_PEK_SHUTDOWN_MASK (0x03)
struct axp20x_info {
const struct axp20x_time *startup_time;
unsigned int startup_mask;
const struct axp20x_time *shutdown_time;
unsigned int shutdown_mask;
};
struct axp20x_pek {
struct axp20x_dev *axp20x;
struct input_dev *input;
struct axp20x_info *info;
int irq_dbr;
int irq_dbf;
};
@ -48,6 +56,13 @@ static const struct axp20x_time startup_time[] = {
{ .time = 2000, .idx = 3 },
};
static const struct axp20x_time axp221_startup_time[] = {
{ .time = 128, .idx = 0 },
{ .time = 1000, .idx = 1 },
{ .time = 2000, .idx = 2 },
{ .time = 3000, .idx = 3 },
};
static const struct axp20x_time shutdown_time[] = {
{ .time = 4000, .idx = 0 },
{ .time = 6000, .idx = 1 },
@ -55,31 +70,25 @@ static const struct axp20x_time shutdown_time[] = {
{ .time = 10000, .idx = 3 },
};
struct axp20x_pek_ext_attr {
const struct axp20x_time *p_time;
unsigned int mask;
static const struct axp20x_info axp20x_info = {
.startup_time = startup_time,
.startup_mask = AXP20X_PEK_STARTUP_MASK,
.shutdown_time = shutdown_time,
.shutdown_mask = AXP20X_PEK_SHUTDOWN_MASK,
};
static struct axp20x_pek_ext_attr axp20x_pek_startup_ext_attr = {
.p_time = startup_time,
.mask = AXP20X_PEK_STARTUP_MASK,
static const struct axp20x_info axp221_info = {
.startup_time = axp221_startup_time,
.startup_mask = AXP20X_PEK_STARTUP_MASK,
.shutdown_time = shutdown_time,
.shutdown_mask = AXP20X_PEK_SHUTDOWN_MASK,
};
static struct axp20x_pek_ext_attr axp20x_pek_shutdown_ext_attr = {
.p_time = shutdown_time,
.mask = AXP20X_PEK_SHUTDOWN_MASK,
};
static struct axp20x_pek_ext_attr *get_axp_ext_attr(struct device_attribute *attr)
{
return container_of(attr, struct dev_ext_attribute, attr)->var;
}
static ssize_t axp20x_show_ext_attr(struct device *dev,
struct device_attribute *attr, char *buf)
static ssize_t axp20x_show_attr(struct device *dev,
const struct axp20x_time *time,
unsigned int mask, char *buf)
{
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
unsigned int val;
int ret, i;
@ -87,22 +96,42 @@ static ssize_t axp20x_show_ext_attr(struct device *dev,
if (ret != 0)
return ret;
val &= axp20x_ea->mask;
val >>= ffs(axp20x_ea->mask) - 1;
val &= mask;
val >>= ffs(mask) - 1;
for (i = 0; i < 4; i++)
if (val == axp20x_ea->p_time[i].idx)
val = axp20x_ea->p_time[i].time;
if (val == time[i].idx)
val = time[i].time;
return sprintf(buf, "%u\n", val);
}
static ssize_t axp20x_store_ext_attr(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
static ssize_t axp20x_show_attr_startup(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
return axp20x_show_attr(dev, axp20x_pek->info->startup_time,
axp20x_pek->info->startup_mask, buf);
}
static ssize_t axp20x_show_attr_shutdown(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
return axp20x_show_attr(dev, axp20x_pek->info->shutdown_time,
axp20x_pek->info->shutdown_mask, buf);
}
static ssize_t axp20x_store_attr(struct device *dev,
const struct axp20x_time *time,
unsigned int mask, const char *buf,
size_t count)
{
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
char val_str[20];
size_t len;
int ret, i;
@ -123,39 +152,52 @@ static ssize_t axp20x_store_ext_attr(struct device *dev,
for (i = 3; i >= 0; i--) {
unsigned int err;
err = abs(axp20x_ea->p_time[i].time - val);
err = abs(time[i].time - val);
if (err < best_err) {
best_err = err;
idx = axp20x_ea->p_time[i].idx;
idx = time[i].idx;
}
if (!err)
break;
}
idx <<= ffs(axp20x_ea->mask) - 1;
ret = regmap_update_bits(axp20x_pek->axp20x->regmap,
AXP20X_PEK_KEY,
axp20x_ea->mask, idx);
idx <<= ffs(mask) - 1;
ret = regmap_update_bits(axp20x_pek->axp20x->regmap, AXP20X_PEK_KEY,
mask, idx);
if (ret != 0)
return -EINVAL;
return count;
}
static struct dev_ext_attribute axp20x_dev_attr_startup = {
.attr = __ATTR(startup, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
.var = &axp20x_pek_startup_ext_attr,
};
static ssize_t axp20x_store_attr_startup(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
static struct dev_ext_attribute axp20x_dev_attr_shutdown = {
.attr = __ATTR(shutdown, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
.var = &axp20x_pek_shutdown_ext_attr,
};
return axp20x_store_attr(dev, axp20x_pek->info->startup_time,
axp20x_pek->info->startup_mask, buf, count);
}
static ssize_t axp20x_store_attr_shutdown(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
return axp20x_store_attr(dev, axp20x_pek->info->shutdown_time,
axp20x_pek->info->shutdown_mask, buf, count);
}
DEVICE_ATTR(startup, 0644, axp20x_show_attr_startup, axp20x_store_attr_startup);
DEVICE_ATTR(shutdown, 0644, axp20x_show_attr_shutdown,
axp20x_store_attr_shutdown);
static struct attribute *axp20x_attributes[] = {
&axp20x_dev_attr_startup.attr.attr,
&axp20x_dev_attr_shutdown.attr.attr,
&dev_attr_startup.attr,
&dev_attr_shutdown.attr,
NULL,
};
@ -291,8 +333,14 @@ static bool axp20x_pek_should_register_input(struct axp20x_pek *axp20x_pek,
static int axp20x_pek_probe(struct platform_device *pdev)
{
struct axp20x_pek *axp20x_pek;
const struct platform_device_id *match = platform_get_device_id(pdev);
int error;
if (!match) {
dev_err(&pdev->dev, "Failed to get platform_device_id\n");
return -EINVAL;
}
axp20x_pek = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_pek),
GFP_KERNEL);
if (!axp20x_pek)
@ -306,6 +354,8 @@ static int axp20x_pek_probe(struct platform_device *pdev)
return error;
}
axp20x_pek->info = (struct axp20x_info *)match->driver_data;
error = devm_device_add_group(&pdev->dev, &axp20x_attribute_group);
if (error) {
dev_err(&pdev->dev, "Failed to create sysfs attributes: %d\n",
@ -342,8 +392,21 @@ static const struct dev_pm_ops axp20x_pek_pm_ops = {
#endif
};
static const struct platform_device_id axp_pek_id_match[] = {
{
.name = "axp20x-pek",
.driver_data = (kernel_ulong_t)&axp20x_info,
},
{
.name = "axp221-pek",
.driver_data = (kernel_ulong_t)&axp221_info,
},
{ /* sentinel */ }
};
static struct platform_driver axp20x_pek_driver = {
.probe = axp20x_pek_probe,
.id_table = axp_pek_id_match,
.driver = {
.name = "axp20x-pek",
.pm = &axp20x_pek_pm_ops,

View File

@ -1261,7 +1261,7 @@ static umode_t ims_pcu_is_attr_visible(struct kobject *kobj,
return mode;
}
static struct attribute_group ims_pcu_attr_group = {
static const struct attribute_group ims_pcu_attr_group = {
.is_visible = ims_pcu_is_attr_visible,
.attrs = ims_pcu_attrs,
};
@ -1480,7 +1480,7 @@ static struct attribute *ims_pcu_ofn_attrs[] = {
NULL
};
static struct attribute_group ims_pcu_ofn_attr_group = {
static const struct attribute_group ims_pcu_ofn_attr_group = {
.name = "ofn",
.attrs = ims_pcu_ofn_attrs,
};

View File

@ -85,7 +85,7 @@ static const unsigned short keyspan_key_table[] = {
};
/* table of devices that work with this driver */
static struct usb_device_id keyspan_table[] = {
static const struct usb_device_id keyspan_table[] = {
{ USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) },
{ } /* Terminating entry */
};

View File

@ -18,25 +18,30 @@
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/timex.h>
#include <asm/io.h>
#include <linux/io.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("PC Speaker beeper driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pcspkr");
static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
static int pcspkr_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value)
{
unsigned int count = 0;
unsigned long flags;
if (type != EV_SND)
return -1;
return -EINVAL;
switch (code) {
case SND_BELL: if (value) value = 1000;
case SND_TONE: break;
default: return -1;
case SND_BELL:
if (value)
value = 1000;
case SND_TONE:
break;
default:
return -EINVAL;
}
if (value > 20 && value < 32767)

View File

@ -432,7 +432,7 @@ static void powermate_disconnect(struct usb_interface *intf)
}
}
static struct usb_device_id powermate_devices [] = {
static const struct usb_device_id powermate_devices[] = {
{ USB_DEVICE(POWERMATE_VENDOR, POWERMATE_PRODUCT_NEW) },
{ USB_DEVICE(POWERMATE_VENDOR, POWERMATE_PRODUCT_OLD) },
{ USB_DEVICE(CONTOUR_VENDOR, CONTOUR_JOG) },

View File

@ -0,0 +1,111 @@
/*
* Rockchip RK805 PMIC Power Key driver
*
* Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
*
* Author: Joseph Chen <chenjh@rock-chips.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
static irqreturn_t pwrkey_fall_irq(int irq, void *_pwr)
{
struct input_dev *pwr = _pwr;
input_report_key(pwr, KEY_POWER, 1);
input_sync(pwr);
return IRQ_HANDLED;
}
static irqreturn_t pwrkey_rise_irq(int irq, void *_pwr)
{
struct input_dev *pwr = _pwr;
input_report_key(pwr, KEY_POWER, 0);
input_sync(pwr);
return IRQ_HANDLED;
}
static int rk805_pwrkey_probe(struct platform_device *pdev)
{
struct input_dev *pwr;
int fall_irq, rise_irq;
int err;
pwr = devm_input_allocate_device(&pdev->dev);
if (!pwr) {
dev_err(&pdev->dev, "Can't allocate power button\n");
return -ENOMEM;
}
pwr->name = "rk805 pwrkey";
pwr->phys = "rk805_pwrkey/input0";
pwr->id.bustype = BUS_HOST;
input_set_capability(pwr, EV_KEY, KEY_POWER);
fall_irq = platform_get_irq(pdev, 0);
if (fall_irq < 0) {
dev_err(&pdev->dev, "Can't get fall irq: %d\n", fall_irq);
return fall_irq;
}
rise_irq = platform_get_irq(pdev, 1);
if (rise_irq < 0) {
dev_err(&pdev->dev, "Can't get rise irq: %d\n", rise_irq);
return rise_irq;
}
err = devm_request_any_context_irq(&pwr->dev, fall_irq,
pwrkey_fall_irq,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"rk805_pwrkey_fall", pwr);
if (err < 0) {
dev_err(&pdev->dev, "Can't register fall irq: %d\n", err);
return err;
}
err = devm_request_any_context_irq(&pwr->dev, rise_irq,
pwrkey_rise_irq,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"rk805_pwrkey_rise", pwr);
if (err < 0) {
dev_err(&pdev->dev, "Can't register rise irq: %d\n", err);
return err;
}
err = input_register_device(pwr);
if (err) {
dev_err(&pdev->dev, "Can't register power button: %d\n", err);
return err;
}
platform_set_drvdata(pdev, pwr);
device_init_wakeup(&pdev->dev, true);
return 0;
}
static struct platform_driver rk805_pwrkey_driver = {
.probe = rk805_pwrkey_probe,
.driver = {
.name = "rk805-pwrkey",
},
};
module_platform_driver(rk805_pwrkey_driver);
MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>");
MODULE_DESCRIPTION("RK805 PMIC Power Key driver");
MODULE_LICENSE("GPL");

View File

@ -84,17 +84,20 @@ static void xenkbd_handle_key_event(struct xenkbd_info *info,
struct xenkbd_key *key)
{
struct input_dev *dev;
int value = key->pressed;
if (test_bit(key->keycode, info->ptr->keybit)) {
dev = info->ptr;
} else if (test_bit(key->keycode, info->kbd->keybit)) {
dev = info->kbd;
if (key->pressed && test_bit(key->keycode, info->kbd->key))
value = 2; /* Mark as autorepeat */
} else {
pr_warn("unhandled keycode 0x%x\n", key->keycode);
return;
}
input_report_key(dev, key->keycode, key->pressed);
input_event(dev, EV_KEY, key->keycode, value);
input_sync(dev);
}

View File

@ -798,7 +798,7 @@ static struct attribute *yld_attributes[] = {
NULL
};
static struct attribute_group yld_attr_group = {
static const struct attribute_group yld_attr_group = {
.attrs = yld_attributes
};

View File

@ -125,7 +125,7 @@ static const struct atp_info geyser4_info = {
* According to Info.plist Geyser IV is the same as Geyser III.)
*/
static struct usb_device_id atp_table[] = {
static const struct usb_device_id atp_table[] = {
/* PowerBooks Feb 2005, iBooks G4 */
ATP_DEVICE(0x020e, fountain_info), /* FOUNTAIN ANSI */
ATP_DEVICE(0x020f, fountain_info), /* FOUNTAIN ISO */

View File

@ -344,7 +344,7 @@ static int byd_reset_touchpad(struct psmouse *psmouse)
u8 param[4];
size_t i;
const struct {
static const struct {
u16 command;
u8 arg;
} seq[] = {

View File

@ -58,7 +58,7 @@ struct elan_transport_ops {
int (*get_version)(struct i2c_client *client, bool iap, u8 *version);
int (*get_sm_version)(struct i2c_client *client,
u16 *ic_type, u8 *version);
u16 *ic_type, u8 *version, u8 *clickpad);
int (*get_checksum)(struct i2c_client *client, bool iap, u16 *csum);
int (*get_product_id)(struct i2c_client *client, u16 *id);

View File

@ -95,6 +95,7 @@ struct elan_tp_data {
u8 min_baseline;
u8 max_baseline;
bool baseline_ready;
u8 clickpad;
};
static int elan_get_fwinfo(u16 ic_type, u16 *validpage_count,
@ -213,7 +214,7 @@ static int elan_query_product(struct elan_tp_data *data)
return error;
error = data->ops->get_sm_version(data->client, &data->ic_type,
&data->sm_version);
&data->sm_version, &data->clickpad);
if (error)
return error;
@ -923,6 +924,7 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
}
input_report_key(input, BTN_LEFT, tp_info & 0x01);
input_report_key(input, BTN_RIGHT, tp_info & 0x02);
input_report_abs(input, ABS_DISTANCE, hover_event != 0);
input_mt_report_pointer_emulation(input, true);
input_sync(input);
@ -991,7 +993,10 @@ static int elan_setup_input_device(struct elan_tp_data *data)
__set_bit(EV_ABS, input->evbit);
__set_bit(INPUT_PROP_POINTER, input->propbit);
__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
if (data->clickpad)
__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
else
__set_bit(BTN_RIGHT, input->keybit);
__set_bit(BTN_LEFT, input->keybit);
/* Set up ST parameters */

View File

@ -288,7 +288,8 @@ static int elan_i2c_get_version(struct i2c_client *client,
}
static int elan_i2c_get_sm_version(struct i2c_client *client,
u16 *ic_type, u8 *version)
u16 *ic_type, u8 *version,
u8 *clickpad)
{
int error;
u8 pattern_ver;
@ -317,6 +318,7 @@ static int elan_i2c_get_sm_version(struct i2c_client *client,
return error;
}
*version = val[1];
*clickpad = val[0] & 0x10;
} else {
error = elan_i2c_read_cmd(client, ETP_I2C_OSM_VERSION_CMD, val);
if (error) {
@ -326,6 +328,15 @@ static int elan_i2c_get_sm_version(struct i2c_client *client,
}
*version = val[0];
*ic_type = val[1];
error = elan_i2c_read_cmd(client, ETP_I2C_NSM_VERSION_CMD,
val);
if (error) {
dev_err(&client->dev, "failed to get SM version: %d\n",
error);
return error;
}
*clickpad = val[0] & 0x10;
}
return 0;

View File

@ -166,7 +166,8 @@ static int elan_smbus_get_version(struct i2c_client *client,
}
static int elan_smbus_get_sm_version(struct i2c_client *client,
u16 *ic_type, u8 *version)
u16 *ic_type, u8 *version,
u8 *clickpad)
{
int error;
u8 val[3];
@ -180,6 +181,7 @@ static int elan_smbus_get_sm_version(struct i2c_client *client,
*version = val[0];
*ic_type = val[1];
*clickpad = val[0] & 0x10;
return 0;
}

View File

@ -1377,7 +1377,7 @@ static struct attribute *elantech_attrs[] = {
NULL
};
static struct attribute_group elantech_attr_group = {
static const struct attribute_group elantech_attr_group = {
.attrs = elantech_attrs,
};

View File

@ -101,7 +101,7 @@ static struct attribute *psmouse_attributes[] = {
NULL
};
static struct attribute_group psmouse_attribute_group = {
static const struct attribute_group psmouse_attribute_group = {
.attrs = psmouse_attributes,
};

View File

@ -525,7 +525,7 @@ static int synusb_reset_resume(struct usb_interface *intf)
return synusb_resume(intf);
}
static struct usb_device_id synusb_idtable[] = {
static const struct usb_device_id synusb_idtable[] = {
{ USB_DEVICE_SYNAPTICS(TP, SYNUSB_TOUCHPAD) },
{ USB_DEVICE_SYNAPTICS(INT_TP, SYNUSB_TOUCHPAD) },
{ USB_DEVICE_SYNAPTICS(CPAD,

View File

@ -15,6 +15,7 @@
#define MOUSEDEV_MINORS 31
#define MOUSEDEV_MIX 63
#include <linux/bitops.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
@ -103,7 +104,7 @@ struct mousedev_client {
spinlock_t packet_lock;
int pos_x, pos_y;
signed char ps2[6];
u8 ps2[6];
unsigned char ready, buffer, bufsiz;
unsigned char imexseq, impsseq;
enum mousedev_emul mode;
@ -291,11 +292,10 @@ static void mousedev_notify_readers(struct mousedev *mousedev,
}
client->pos_x += packet->dx;
client->pos_x = client->pos_x < 0 ?
0 : (client->pos_x >= xres ? xres : client->pos_x);
client->pos_x = clamp_val(client->pos_x, 0, xres);
client->pos_y += packet->dy;
client->pos_y = client->pos_y < 0 ?
0 : (client->pos_y >= yres ? yres : client->pos_y);
client->pos_y = clamp_val(client->pos_y, 0, yres);
p->dx += packet->dx;
p->dy += packet->dy;
@ -571,44 +571,50 @@ static int mousedev_open(struct inode *inode, struct file *file)
return error;
}
static inline int mousedev_limit_delta(int delta, int limit)
{
return delta > limit ? limit : (delta < -limit ? -limit : delta);
}
static void mousedev_packet(struct mousedev_client *client,
signed char *ps2_data)
static void mousedev_packet(struct mousedev_client *client, u8 *ps2_data)
{
struct mousedev_motion *p = &client->packets[client->tail];
s8 dx, dy, dz;
ps2_data[0] = 0x08 |
((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07);
ps2_data[1] = mousedev_limit_delta(p->dx, 127);
ps2_data[2] = mousedev_limit_delta(p->dy, 127);
p->dx -= ps2_data[1];
p->dy -= ps2_data[2];
dx = clamp_val(p->dx, -127, 127);
p->dx -= dx;
dy = clamp_val(p->dy, -127, 127);
p->dy -= dy;
ps2_data[0] = BIT(3);
ps2_data[0] |= ((dx & BIT(7)) >> 3) | ((dy & BIT(7)) >> 2);
ps2_data[0] |= p->buttons & 0x07;
ps2_data[1] = dx;
ps2_data[2] = dy;
switch (client->mode) {
case MOUSEDEV_EMUL_EXPS:
ps2_data[3] = mousedev_limit_delta(p->dz, 7);
p->dz -= ps2_data[3];
ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1);
dz = clamp_val(p->dz, -7, 7);
p->dz -= dz;
ps2_data[3] = (dz & 0x0f) | ((p->buttons & 0x18) << 1);
client->bufsiz = 4;
break;
case MOUSEDEV_EMUL_IMPS:
ps2_data[0] |=
((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
ps2_data[3] = mousedev_limit_delta(p->dz, 127);
p->dz -= ps2_data[3];
dz = clamp_val(p->dz, -127, 127);
p->dz -= dz;
ps2_data[0] |= ((p->buttons & 0x10) >> 3) |
((p->buttons & 0x08) >> 1);
ps2_data[3] = dz;
client->bufsiz = 4;
break;
case MOUSEDEV_EMUL_PS2:
default:
ps2_data[0] |=
((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
p->dz = 0;
ps2_data[0] |= ((p->buttons & 0x10) >> 3) |
((p->buttons & 0x08) >> 1);
client->bufsiz = 3;
break;
}
@ -714,7 +720,7 @@ static ssize_t mousedev_read(struct file *file, char __user *buffer,
{
struct mousedev_client *client = file->private_data;
struct mousedev *mousedev = client->mousedev;
signed char data[sizeof(client->ps2)];
u8 data[sizeof(client->ps2)];
int retval = 0;
if (!client->ready && !client->buffer && mousedev->exist &&

View File

@ -334,7 +334,7 @@ static struct attribute *rmi_f01_attrs[] = {
NULL
};
static struct attribute_group rmi_f01_attr_group = {
static const struct attribute_group rmi_f01_attr_group = {
.attrs = rmi_f01_attrs,
};

View File

@ -516,7 +516,7 @@ static struct attribute *rmi_firmware_attrs[] = {
NULL
};
static struct attribute_group rmi_firmware_attr_group = {
static const struct attribute_group rmi_firmware_attr_group = {
.attrs = rmi_firmware_attrs,
};

View File

@ -292,6 +292,17 @@ config SERIO_SUN4I_PS2
To compile this driver as a module, choose M here: the
module will be called sun4i-ps2.
config SERIO_GPIO_PS2
tristate "GPIO PS/2 bit banging driver"
depends on GPIOLIB
help
Say Y here if you want PS/2 bit banging support via GPIO.
To compile this driver as a module, choose M here: the
module will be called ps2-gpio.
If you are unsure, say N.
config USERIO
tristate "User space serio port driver support"
help

View File

@ -30,4 +30,5 @@ obj-$(CONFIG_SERIO_APBPS2) += apbps2.o
obj-$(CONFIG_SERIO_OLPC_APSP) += olpc_apsp.o
obj-$(CONFIG_HYPERV_KEYBOARD) += hyperv-keyboard.o
obj-$(CONFIG_SERIO_SUN4I_PS2) += sun4i-ps2.o
obj-$(CONFIG_SERIO_GPIO_PS2) += ps2-gpio.o
obj-$(CONFIG_USERIO) += userio.o

View File

@ -187,7 +187,7 @@ static int __maybe_unused amba_kmi_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(amba_kmi_dev_pm_ops, NULL, amba_kmi_resume);
static struct amba_id amba_kmi_idtable[] = {
static const struct amba_id amba_kmi_idtable[] = {
{
.id = 0x00041050,
.mask = 0x000fffff,

View File

@ -927,7 +927,7 @@ static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *
return 0;
}
static struct pnp_device_id pnp_kbd_devids[] = {
static const struct pnp_device_id pnp_kbd_devids[] = {
{ .id = "PNP0300", .driver_data = 0 },
{ .id = "PNP0301", .driver_data = 0 },
{ .id = "PNP0302", .driver_data = 0 },
@ -957,7 +957,7 @@ static struct pnp_driver i8042_pnp_kbd_driver = {
},
};
static struct pnp_device_id pnp_aux_devids[] = {
static const struct pnp_device_id pnp_aux_devids[] = {
{ .id = "AUI0200", .driver_data = 0 },
{ .id = "FJC6000", .driver_data = 0 },
{ .id = "FJC6001", .driver_data = 0 },

View File

@ -0,0 +1,453 @@
/*
* GPIO based serio bus driver for bit banging the PS/2 protocol
*
* Author: Danilo Krummrich <danilokrummrich@dk-develop.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/serio.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/completion.h>
#include <linux/mutex.h>
#include <linux/preempt.h>
#include <linux/property.h>
#include <linux/of.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
#define DRIVER_NAME "ps2-gpio"
#define PS2_MODE_RX 0
#define PS2_MODE_TX 1
#define PS2_START_BIT 0
#define PS2_DATA_BIT0 1
#define PS2_DATA_BIT1 2
#define PS2_DATA_BIT2 3
#define PS2_DATA_BIT3 4
#define PS2_DATA_BIT4 5
#define PS2_DATA_BIT5 6
#define PS2_DATA_BIT6 7
#define PS2_DATA_BIT7 8
#define PS2_PARITY_BIT 9
#define PS2_STOP_BIT 10
#define PS2_TX_TIMEOUT 11
#define PS2_ACK_BIT 12
#define PS2_DEV_RET_ACK 0xfa
#define PS2_DEV_RET_NACK 0xfe
#define PS2_CMD_RESEND 0xfe
struct ps2_gpio_data {
struct device *dev;
struct serio *serio;
unsigned char mode;
struct gpio_desc *gpio_clk;
struct gpio_desc *gpio_data;
bool write_enable;
int irq;
unsigned char rx_cnt;
unsigned char rx_byte;
unsigned char tx_cnt;
unsigned char tx_byte;
struct completion tx_done;
struct mutex tx_mutex;
struct delayed_work tx_work;
};
static int ps2_gpio_open(struct serio *serio)
{
struct ps2_gpio_data *drvdata = serio->port_data;
enable_irq(drvdata->irq);
return 0;
}
static void ps2_gpio_close(struct serio *serio)
{
struct ps2_gpio_data *drvdata = serio->port_data;
disable_irq(drvdata->irq);
}
static int __ps2_gpio_write(struct serio *serio, unsigned char val)
{
struct ps2_gpio_data *drvdata = serio->port_data;
disable_irq_nosync(drvdata->irq);
gpiod_direction_output(drvdata->gpio_clk, 0);
drvdata->mode = PS2_MODE_TX;
drvdata->tx_byte = val;
schedule_delayed_work(&drvdata->tx_work, usecs_to_jiffies(200));
return 0;
}
static int ps2_gpio_write(struct serio *serio, unsigned char val)
{
struct ps2_gpio_data *drvdata = serio->port_data;
int ret = 0;
if (in_task()) {
mutex_lock(&drvdata->tx_mutex);
__ps2_gpio_write(serio, val);
if (!wait_for_completion_timeout(&drvdata->tx_done,
msecs_to_jiffies(10000)))
ret = SERIO_TIMEOUT;
mutex_unlock(&drvdata->tx_mutex);
} else {
__ps2_gpio_write(serio, val);
}
return ret;
}
static void ps2_gpio_tx_work_fn(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct ps2_gpio_data *drvdata = container_of(dwork,
struct ps2_gpio_data,
tx_work);
enable_irq(drvdata->irq);
gpiod_direction_output(drvdata->gpio_data, 0);
gpiod_direction_input(drvdata->gpio_clk);
}
static irqreturn_t ps2_gpio_irq_rx(struct ps2_gpio_data *drvdata)
{
unsigned char byte, cnt;
int data;
int rxflags = 0;
static unsigned long old_jiffies;
byte = drvdata->rx_byte;
cnt = drvdata->rx_cnt;
if (old_jiffies == 0)
old_jiffies = jiffies;
if ((jiffies - old_jiffies) > usecs_to_jiffies(100)) {
dev_err(drvdata->dev,
"RX: timeout, probably we missed an interrupt\n");
goto err;
}
old_jiffies = jiffies;
data = gpiod_get_value(drvdata->gpio_data);
if (unlikely(data < 0)) {
dev_err(drvdata->dev, "RX: failed to get data gpio val: %d\n",
data);
goto err;
}
switch (cnt) {
case PS2_START_BIT:
/* start bit should be low */
if (unlikely(data)) {
dev_err(drvdata->dev, "RX: start bit should be low\n");
goto err;
}
break;
case PS2_DATA_BIT0:
case PS2_DATA_BIT1:
case PS2_DATA_BIT2:
case PS2_DATA_BIT3:
case PS2_DATA_BIT4:
case PS2_DATA_BIT5:
case PS2_DATA_BIT6:
case PS2_DATA_BIT7:
/* processing data bits */
if (data)
byte |= (data << (cnt - 1));
break;
case PS2_PARITY_BIT:
/* check odd parity */
if (!((hweight8(byte) & 1) ^ data)) {
rxflags |= SERIO_PARITY;
dev_warn(drvdata->dev, "RX: parity error\n");
if (!drvdata->write_enable)
goto err;
}
/* Do not send spurious ACK's and NACK's when write fn is
* not provided.
*/
if (!drvdata->write_enable) {
if (byte == PS2_DEV_RET_NACK)
goto err;
else if (byte == PS2_DEV_RET_ACK)
break;
}
/* Let's send the data without waiting for the stop bit to be
* sent. It may happen that we miss the stop bit. When this
* happens we have no way to recover from this, certainly
* missing the parity bit would be recognized when processing
* the stop bit. When missing both, data is lost.
*/
serio_interrupt(drvdata->serio, byte, rxflags);
dev_dbg(drvdata->dev, "RX: sending byte 0x%x\n", byte);
break;
case PS2_STOP_BIT:
/* stop bit should be high */
if (unlikely(!data)) {
dev_err(drvdata->dev, "RX: stop bit should be high\n");
goto err;
}
cnt = byte = 0;
old_jiffies = 0;
goto end; /* success */
default:
dev_err(drvdata->dev, "RX: got out of sync with the device\n");
goto err;
}
cnt++;
goto end; /* success */
err:
cnt = byte = 0;
old_jiffies = 0;
__ps2_gpio_write(drvdata->serio, PS2_CMD_RESEND);
end:
drvdata->rx_cnt = cnt;
drvdata->rx_byte = byte;
return IRQ_HANDLED;
}
static irqreturn_t ps2_gpio_irq_tx(struct ps2_gpio_data *drvdata)
{
unsigned char byte, cnt;
int data;
static unsigned long old_jiffies;
cnt = drvdata->tx_cnt;
byte = drvdata->tx_byte;
if (old_jiffies == 0)
old_jiffies = jiffies;
if ((jiffies - old_jiffies) > usecs_to_jiffies(100)) {
dev_err(drvdata->dev,
"TX: timeout, probably we missed an interrupt\n");
goto err;
}
old_jiffies = jiffies;
switch (cnt) {
case PS2_START_BIT:
/* should never happen */
dev_err(drvdata->dev,
"TX: start bit should have been sent already\n");
goto err;
case PS2_DATA_BIT0:
case PS2_DATA_BIT1:
case PS2_DATA_BIT2:
case PS2_DATA_BIT3:
case PS2_DATA_BIT4:
case PS2_DATA_BIT5:
case PS2_DATA_BIT6:
case PS2_DATA_BIT7:
data = byte & BIT(cnt - 1);
gpiod_set_value(drvdata->gpio_data, data);
break;
case PS2_PARITY_BIT:
/* do odd parity */
data = !(hweight8(byte) & 1);
gpiod_set_value(drvdata->gpio_data, data);
break;
case PS2_STOP_BIT:
/* release data line to generate stop bit */
gpiod_direction_input(drvdata->gpio_data);
break;
case PS2_TX_TIMEOUT:
/* Devices generate one extra clock pulse before sending the
* acknowledgment.
*/
break;
case PS2_ACK_BIT:
gpiod_direction_input(drvdata->gpio_data);
data = gpiod_get_value(drvdata->gpio_data);
if (data) {
dev_warn(drvdata->dev, "TX: received NACK, retry\n");
goto err;
}
drvdata->mode = PS2_MODE_RX;
complete(&drvdata->tx_done);
cnt = 1;
old_jiffies = 0;
goto end; /* success */
default:
/* Probably we missed the stop bit. Therefore we release data
* line and try again.
*/
gpiod_direction_input(drvdata->gpio_data);
dev_err(drvdata->dev, "TX: got out of sync with the device\n");
goto err;
}
cnt++;
goto end; /* success */
err:
cnt = 1;
old_jiffies = 0;
gpiod_direction_input(drvdata->gpio_data);
__ps2_gpio_write(drvdata->serio, drvdata->tx_byte);
end:
drvdata->tx_cnt = cnt;
return IRQ_HANDLED;
}
static irqreturn_t ps2_gpio_irq(int irq, void *dev_id)
{
struct ps2_gpio_data *drvdata = dev_id;
return drvdata->mode ? ps2_gpio_irq_tx(drvdata) :
ps2_gpio_irq_rx(drvdata);
}
static int ps2_gpio_get_props(struct device *dev,
struct ps2_gpio_data *drvdata)
{
drvdata->gpio_data = devm_gpiod_get(dev, "data", GPIOD_IN);
if (IS_ERR(drvdata->gpio_data)) {
dev_err(dev, "failed to request data gpio: %ld",
PTR_ERR(drvdata->gpio_data));
return PTR_ERR(drvdata->gpio_data);
}
drvdata->gpio_clk = devm_gpiod_get(dev, "clk", GPIOD_IN);
if (IS_ERR(drvdata->gpio_clk)) {
dev_err(dev, "failed to request clock gpio: %ld",
PTR_ERR(drvdata->gpio_clk));
return PTR_ERR(drvdata->gpio_clk);
}
drvdata->write_enable = device_property_read_bool(dev,
"write-enable");
return 0;
}
static int ps2_gpio_probe(struct platform_device *pdev)
{
struct ps2_gpio_data *drvdata;
struct serio *serio;
struct device *dev = &pdev->dev;
int error;
drvdata = devm_kzalloc(dev, sizeof(struct ps2_gpio_data), GFP_KERNEL);
serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
if (!drvdata || !serio) {
error = -ENOMEM;
goto err_free_serio;
}
error = ps2_gpio_get_props(dev, drvdata);
if (error)
goto err_free_serio;
if (gpiod_cansleep(drvdata->gpio_data) ||
gpiod_cansleep(drvdata->gpio_clk)) {
dev_err(dev, "GPIO data or clk are connected via slow bus\n");
error = -EINVAL;
}
drvdata->irq = platform_get_irq(pdev, 0);
if (drvdata->irq < 0) {
dev_err(dev, "failed to get irq from platform resource: %d\n",
drvdata->irq);
error = drvdata->irq;
goto err_free_serio;
}
error = devm_request_irq(dev, drvdata->irq, ps2_gpio_irq,
IRQF_NO_THREAD, DRIVER_NAME, drvdata);
if (error) {
dev_err(dev, "failed to request irq %d: %d\n",
drvdata->irq, error);
goto err_free_serio;
}
/* Keep irq disabled until serio->open is called. */
disable_irq(drvdata->irq);
serio->id.type = SERIO_8042;
serio->open = ps2_gpio_open;
serio->close = ps2_gpio_close;
/* Write can be enabled in platform/dt data, but possibly it will not
* work because of the tough timings.
*/
serio->write = drvdata->write_enable ? ps2_gpio_write : NULL;
serio->port_data = drvdata;
serio->dev.parent = dev;
strlcpy(serio->name, dev_name(dev), sizeof(serio->name));
strlcpy(serio->phys, dev_name(dev), sizeof(serio->phys));
drvdata->serio = serio;
drvdata->dev = dev;
drvdata->mode = PS2_MODE_RX;
/* Tx count always starts at 1, as the start bit is sent implicitly by
* host-to-device communication initialization.
*/
drvdata->tx_cnt = 1;
INIT_DELAYED_WORK(&drvdata->tx_work, ps2_gpio_tx_work_fn);
init_completion(&drvdata->tx_done);
mutex_init(&drvdata->tx_mutex);
serio_register_port(serio);
platform_set_drvdata(pdev, drvdata);
return 0; /* success */
err_free_serio:
kfree(serio);
return error;
}
static int ps2_gpio_remove(struct platform_device *pdev)
{
struct ps2_gpio_data *drvdata = platform_get_drvdata(pdev);
serio_unregister_port(drvdata->serio);
return 0;
}
#if defined(CONFIG_OF)
static const struct of_device_id ps2_gpio_match[] = {
{ .compatible = "ps2-gpio", },
{ },
};
MODULE_DEVICE_TABLE(of, ps2_gpio_match);
#endif
static struct platform_driver ps2_gpio_driver = {
.probe = ps2_gpio_probe,
.remove = ps2_gpio_remove,
.driver = {
.name = DRIVER_NAME,
.of_match_table = of_match_ptr(ps2_gpio_match),
},
};
module_platform_driver(ps2_gpio_driver);
MODULE_AUTHOR("Danilo Krummrich <danilokrummrich@dk-develop.de>");
MODULE_DESCRIPTION("GPIO PS2 driver");
MODULE_LICENSE("GPL v2");

View File

@ -469,7 +469,7 @@ static struct attribute *serio_device_id_attrs[] = {
NULL
};
static struct attribute_group serio_id_attr_group = {
static const struct attribute_group serio_id_attr_group = {
.name = "id",
.attrs = serio_device_id_attrs,
};
@ -489,7 +489,7 @@ static struct attribute *serio_device_attrs[] = {
NULL
};
static struct attribute_group serio_device_attr_group = {
static const struct attribute_group serio_device_attr_group = {
.attrs = serio_device_attrs,
};

View File

@ -410,7 +410,7 @@ static void serio_raw_disconnect(struct serio *serio)
serio_set_drvdata(serio, NULL);
}
static struct serio_device_id serio_raw_serio_ids[] = {
static const struct serio_device_id serio_raw_serio_ids[] = {
{
.type = SERIO_8042,
.proto = SERIO_ANY,

View File

@ -45,8 +45,10 @@
#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. */
/*
* 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 */
@ -292,8 +294,10 @@ static int xps2_of_probe(struct platform_device *ofdev)
/* 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 */
/*
* 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",

View File

@ -260,7 +260,7 @@ static void usb_acecad_disconnect(struct usb_interface *intf)
kfree(acecad);
}
static struct usb_device_id usb_acecad_id_table [] = {
static const struct usb_device_id usb_acecad_id_table[] = {
{ USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_FLAIR), .driver_info = 0 },
{ USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_302), .driver_info = 1 },
{ }

View File

@ -1676,7 +1676,7 @@ static struct attribute *aiptek_attributes[] = {
NULL
};
static struct attribute_group aiptek_attribute_group = {
static const struct attribute_group aiptek_attribute_group = {
.attrs = aiptek_attributes,
};

View File

@ -88,7 +88,7 @@ static void kbtab_irq(struct urb *urb)
__func__, retval);
}
static struct usb_device_id kbtab_ids[] = {
static const struct usb_device_id kbtab_ids[] = {
{ USB_DEVICE(USB_VENDOR_ID_KBGEAR, 0x1001), .driver_info = 0 },
{ }
};

View File

@ -594,7 +594,7 @@ static int wacom_connect(struct serio *serio, struct serio_driver *drv)
return err;
}
static struct serio_device_id wacom_serio_ids[] = {
static const struct serio_device_id wacom_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_WACOM_IV,

View File

@ -499,7 +499,7 @@ static struct attribute *ads7846_attributes[] = {
NULL,
};
static struct attribute_group ads7846_attr_group = {
static const struct attribute_group ads7846_attr_group = {
.attrs = ads7846_attributes,
.is_visible = ads7846_is_visible,
};
@ -599,7 +599,7 @@ static struct attribute *ads784x_attributes[] = {
NULL,
};
static struct attribute_group ads784x_attr_group = {
static const struct attribute_group ads784x_attr_group = {
.attrs = ads784x_attributes,
};

View File

@ -28,6 +28,7 @@
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/gpio/consumer.h>
#include <asm/unaligned.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
@ -300,6 +301,7 @@ struct mxt_data {
u8 multitouch;
struct t7_config t7_cfg;
struct mxt_dbg dbg;
struct gpio_desc *reset_gpio;
/* Cached parameters from object table */
u16 T5_address;
@ -3117,11 +3119,9 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (IS_ERR(pdata))
return PTR_ERR(pdata);
data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
if (!data) {
dev_err(&client->dev, "Failed to allocate memory\n");
data = devm_kzalloc(&client->dev, sizeof(struct mxt_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
}
snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
client->adapter->nr, client->addr);
@ -3135,19 +3135,40 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
init_completion(&data->reset_completion);
init_completion(&data->crc_completion);
error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
pdata->irqflags | IRQF_ONESHOT,
client->name, data);
data->reset_gpio = devm_gpiod_get_optional(&client->dev,
"reset", GPIOD_OUT_LOW);
if (IS_ERR(data->reset_gpio)) {
error = PTR_ERR(data->reset_gpio);
dev_err(&client->dev, "Failed to get reset gpio: %d\n", error);
return error;
}
error = devm_request_threaded_irq(&client->dev, client->irq,
NULL, mxt_interrupt,
pdata->irqflags | IRQF_ONESHOT,
client->name, data);
if (error) {
dev_err(&client->dev, "Failed to register interrupt\n");
goto err_free_mem;
return error;
}
if (data->reset_gpio) {
data->in_bootloader = true;
msleep(MXT_RESET_TIME);
reinit_completion(&data->bl_completion);
gpiod_set_value(data->reset_gpio, 1);
error = mxt_wait_for_completion(data, &data->bl_completion,
MXT_RESET_TIMEOUT);
if (error)
return error;
data->in_bootloader = false;
}
disable_irq(client->irq);
error = mxt_initialize(data);
if (error)
goto err_free_irq;
return error;
error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
if (error) {
@ -3161,10 +3182,6 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
err_free_object:
mxt_free_input_device(data);
mxt_free_object_table(data);
err_free_irq:
free_irq(client->irq, data);
err_free_mem:
kfree(data);
return error;
}
@ -3172,11 +3189,10 @@ static int mxt_remove(struct i2c_client *client)
{
struct mxt_data *data = i2c_get_clientdata(client);
disable_irq(data->irq);
sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
free_irq(data->irq, data);
mxt_free_input_device(data);
mxt_free_object_table(data);
kfree(data);
return 0;
}

View File

@ -164,7 +164,7 @@ static int dynapro_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id dynapro_serio_ids[] = {
static const struct serio_device_id dynapro_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_DYNAPRO,

View File

@ -1066,7 +1066,7 @@ static struct attribute *elants_attributes[] = {
NULL
};
static struct attribute_group elants_attribute_group = {
static const struct attribute_group elants_attribute_group = {
.attrs = elants_attributes,
};

View File

@ -381,7 +381,7 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id elo_serio_ids[] = {
static const struct serio_device_id elo_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_ELO,

View File

@ -151,7 +151,7 @@ static int fujitsu_connect(struct serio *serio, struct serio_driver *drv)
/*
* The serio driver structure.
*/
static struct serio_device_id fujitsu_serio_ids[] = {
static const struct serio_device_id fujitsu_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_FUJITSU,

View File

@ -162,7 +162,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id gunze_serio_ids[] = {
static const struct serio_device_id gunze_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_GUNZE,

View File

@ -163,7 +163,7 @@ static int hampshire_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id hampshire_serio_ids[] = {
static const struct serio_device_id hampshire_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_HAMPSHIRE,

View File

@ -165,7 +165,7 @@ static int inexio_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id inexio_serio_ids[] = {
static const struct serio_device_id inexio_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_INEXIO,

View File

@ -178,7 +178,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id mtouch_serio_ids[] = {
static const struct serio_device_id mtouch_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_MICROTOUCH,

View File

@ -30,7 +30,7 @@
#include <linux/of_irq.h>
#include <linux/platform_device.h>
const char *mxs_lradc_ts_irq_names[] = {
static const char * const mxs_lradc_ts_irq_names[] = {
"mxs-lradc-touchscreen",
"mxs-lradc-channel6",
"mxs-lradc-channel7",
@ -630,9 +630,11 @@ static int mxs_lradc_ts_probe(struct platform_device *pdev)
spin_lock_init(&ts->lock);
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iores)
return -EINVAL;
ts->base = devm_ioremap(dev, iores->start, resource_size(iores));
if (IS_ERR(ts->base))
return PTR_ERR(ts->base);
if (!ts->base)
return -ENOMEM;
ret = of_property_read_u32(node, "fsl,lradc-touchscreen-wires",
&ts_wires);

View File

@ -293,7 +293,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id pm_serio_ids[] = {
static const struct serio_device_id pm_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_PENMOUNT,

View File

@ -939,7 +939,7 @@ static struct attribute *raydium_i2c_attributes[] = {
NULL
};
static struct attribute_group raydium_i2c_attribute_group = {
static const struct attribute_group raydium_i2c_attribute_group = {
.attrs = raydium_i2c_attributes,
};

View File

@ -206,7 +206,7 @@ static int sun4i_get_tz_temp(void *data, int *temp)
return sun4i_get_temp(data, temp);
}
static struct thermal_zone_of_device_ops sun4i_ts_tz_ops = {
static const struct thermal_zone_of_device_ops sun4i_ts_tz_ops = {
.get_temp = sun4i_get_tz_temp,
};

View File

@ -59,7 +59,7 @@ struct sur40_blob {
__le16 blob_id;
u8 action; /* 0x02 = enter/exit, 0x03 = update (?) */
u8 unknown; /* always 0x01 or 0x02 (no idea what this is?) */
u8 type; /* bitmask (0x01 blob, 0x02 touch, 0x04 tag) */
__le16 bb_pos_x; /* upper left corner of bounding box */
__le16 bb_pos_y;
@ -133,12 +133,19 @@ struct sur40_image_header {
/* control commands */
#define SUR40_GET_VERSION 0xb0 /* 12 bytes string */
#define SUR40_UNKNOWN1 0xb3 /* 5 bytes */
#define SUR40_UNKNOWN2 0xc1 /* 24 bytes */
#define SUR40_ACCEL_CAPS 0xb3 /* 5 bytes */
#define SUR40_SENSOR_CAPS 0xc1 /* 24 bytes */
#define SUR40_POKE 0xc5 /* poke register byte */
#define SUR40_PEEK 0xc4 /* 48 bytes registers */
#define SUR40_GET_STATE 0xc5 /* 4 bytes state (?) */
#define SUR40_GET_SENSORS 0xb1 /* 8 bytes sensors */
#define SUR40_BLOB 0x01
#define SUR40_TOUCH 0x02
#define SUR40_TAG 0x04
static const struct v4l2_pix_format sur40_pix_format[] = {
{
.pixelformat = V4L2_TCH_FMT_TU08,
@ -238,11 +245,11 @@ static int sur40_init(struct sur40_state *dev)
if (result < 0)
goto error;
result = sur40_command(dev, SUR40_UNKNOWN2, 0x00, buffer, 24);
result = sur40_command(dev, SUR40_SENSOR_CAPS, 0x00, buffer, 24);
if (result < 0)
goto error;
result = sur40_command(dev, SUR40_UNKNOWN1, 0x00, buffer, 5);
result = sur40_command(dev, SUR40_ACCEL_CAPS, 0x00, buffer, 5);
if (result < 0)
goto error;
@ -289,20 +296,24 @@ static void sur40_close(struct input_polled_dev *polldev)
static void sur40_report_blob(struct sur40_blob *blob, struct input_dev *input)
{
int wide, major, minor;
int bb_size_x, bb_size_y, pos_x, pos_y, ctr_x, ctr_y, slotnum;
int bb_size_x = le16_to_cpu(blob->bb_size_x);
int bb_size_y = le16_to_cpu(blob->bb_size_y);
if (blob->type != SUR40_TOUCH)
return;
int pos_x = le16_to_cpu(blob->pos_x);
int pos_y = le16_to_cpu(blob->pos_y);
int ctr_x = le16_to_cpu(blob->ctr_x);
int ctr_y = le16_to_cpu(blob->ctr_y);
int slotnum = input_mt_get_slot_by_key(input, blob->blob_id);
slotnum = input_mt_get_slot_by_key(input, blob->blob_id);
if (slotnum < 0 || slotnum >= MAX_CONTACTS)
return;
bb_size_x = le16_to_cpu(blob->bb_size_x);
bb_size_y = le16_to_cpu(blob->bb_size_y);
pos_x = le16_to_cpu(blob->pos_x);
pos_y = le16_to_cpu(blob->pos_y);
ctr_x = le16_to_cpu(blob->ctr_x);
ctr_y = le16_to_cpu(blob->ctr_y);
input_mt_slot(input, slotnum);
input_mt_report_slot_state(input, MT_TOOL_FINGER, 1);
wide = (bb_size_x > bb_size_y);
@ -367,10 +378,13 @@ static void sur40_poll(struct input_polled_dev *polldev)
/*
* Sanity check. when video data is also being retrieved, the
* packet ID will usually increase in the middle of a series
* instead of at the end.
*/
* instead of at the end. However, the data is still consistent,
* so the packet ID is probably just valid for the first packet
* in a series.
if (packet_id != le32_to_cpu(header->packet_id))
dev_dbg(sur40->dev, "packet ID mismatch\n");
*/
packet_blobs = result / sizeof(struct sur40_blob);
dev_dbg(sur40->dev, "received %d blobs\n", packet_blobs);

View File

@ -192,7 +192,7 @@ static int touchit213_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id touchit213_serio_ids[] = {
static const struct serio_device_id touchit213_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_TOUCHIT213,

View File

@ -152,7 +152,7 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id tr_serio_ids[] = {
static const struct serio_device_id tr_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_TOUCHRIGHT,

View File

@ -159,7 +159,7 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv)
* The serio driver structure.
*/
static struct serio_device_id tw_serio_ids[] = {
static const struct serio_device_id tw_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_TOUCHWIN,

View File

@ -141,7 +141,7 @@ static void tsc_disconnect(struct serio *serio)
serio_set_drvdata(serio, NULL);
}
static struct serio_device_id tsc_serio_ids[] = {
static const struct serio_device_id tsc_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_TSC40,

View File

@ -681,7 +681,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
return err;
}
static struct serio_device_id w8001_serio_ids[] = {
static const struct serio_device_id w8001_serio_ids[] = {
{
.type = SERIO_RS232,
.proto = SERIO_W8001,