Commit 133309a8 authored by Linus Torvalds's avatar Linus Torvalds

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

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (52 commits)
  Input: bcm5974 - silence uninitialized variables warnings
  Input: wistron_btns - add keymap for AOpen 1557
  Input: psmouse - use boolean type
  Input: i8042 - use platform_driver_probe
  Input: i8042 - use boolean type where it makes sense
  Input: i8042 - try disabling and re-enabling AUX port at close
  Input: pxa27x_keypad - allow modifying keymap from userspace
  Input: sunkbd - fix formatting
  Input: i8042 - bypass AUX IRQ delivery test on laptops
  Input: wacom_w8001 - simplify querying logic
  Input: atkbd - allow setting force-release bitmap via sysfs
  Input: w90p910_keypad - move a dereference below a NULL test
  Input: add twl4030_keypad driver
  Input: matrix-keypad - add function to build device keymap
  Input: tosakbd - fix cleaning up KEY_STROBEs after error
  Input: joydev - validate axis/button maps before clobbering current ones
  Input: xpad - add USB ID for the drumkit controller from Rock Band
  Input: w90p910_keypad - rename driver name to match platform
  Input: add new driver for Sentelic Finger Sensing Pad
  Input: psmouse - allow defining read-only attributes
  ...
parents 5489375d fc8e1ead
This diff is collapsed.
......@@ -2,9 +2,12 @@
#define __ASM_ARCH_PXA27x_KEYPAD_H
#include <linux/input.h>
#include <linux/input/matrix_keypad.h>
#define MAX_MATRIX_KEY_ROWS (8)
#define MAX_MATRIX_KEY_COLS (8)
#define MATRIX_ROW_SHIFT (3)
#define MAX_DIRECT_KEY_NUM (8)
/* pxa3xx keypad platform specific parameters
*
......@@ -33,7 +36,7 @@ struct pxa27x_keypad_platform_data {
/* direct keys */
int direct_key_num;
unsigned int direct_key_map[8];
unsigned int direct_key_map[MAX_DIRECT_KEY_NUM];
/* rotary encoders 0 */
int enable_rotary0;
......@@ -51,8 +54,6 @@ struct pxa27x_keypad_platform_data {
unsigned int debounce_interval;
};
#define KEY(row, col, val) (((row) << 28) | ((col) << 24) | (val))
extern void pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info);
#endif /* __ASM_ARCH_PXA27x_KEYPAD_H */
#ifndef __ASM_ARCH_W90P910_KEYPAD_H
#define __ASM_ARCH_W90P910_KEYPAD_H
#include <linux/input/matrix_keypad.h>
extern void mfp_set_groupi(struct device *dev);
struct w90p910_keypad_platform_data {
const struct matrix_keymap_data *keymap_data;
unsigned int prescale;
unsigned int debounce;
};
#endif /* __ASM_ARCH_W90P910_KEYPAD_H */
/*
* board initialization should put one of these structures into platform_data
* and place the bfin-rotary onto platform_bus named "bfin-rotary".
*/
#ifndef _BFIN_ROTARY_H
#define _BFIN_ROTARY_H
/* mode bitmasks */
#define ROT_QUAD_ENC CNTMODE_QUADENC /* quadrature/grey code encoder mode */
#define ROT_BIN_ENC CNTMODE_BINENC /* binary encoder mode */
#define ROT_UD_CNT CNTMODE_UDCNT /* rotary counter mode */
#define ROT_DIR_CNT CNTMODE_DIRCNT /* direction counter mode */
#define ROT_DEBE DEBE /* Debounce Enable */
#define ROT_CDGINV CDGINV /* CDG Pin Polarity Invert */
#define ROT_CUDINV CUDINV /* CUD Pin Polarity Invert */
#define ROT_CZMINV CZMINV /* CZM Pin Polarity Invert */
struct bfin_rotary_platform_data {
/* set rotary UP KEY_### or BTN_### in case you prefer
* bfin-rotary to send EV_KEY otherwise set 0
*/
unsigned int rotary_up_key;
/* set rotary DOWN KEY_### or BTN_### in case you prefer
* bfin-rotary to send EV_KEY otherwise set 0
*/
unsigned int rotary_down_key;
/* set rotary BUTTON KEY_### or BTN_### */
unsigned int rotary_button_key;
/* set rotary Relative Axis REL_### in case you prefer
* bfin-rotary to send EV_REL otherwise set 0
*/
unsigned int rotary_rel_code;
unsigned short debounce; /* 0..17 */
unsigned short mode;
};
#endif
......@@ -922,7 +922,7 @@ static int platform_pm_restore_noirq(struct device *dev)
#endif /* !CONFIG_HIBERNATION */
static struct dev_pm_ops platform_dev_pm_ops = {
static const struct dev_pm_ops platform_dev_pm_ops = {
.prepare = platform_pm_prepare,
.complete = platform_pm_complete,
.suspend = platform_pm_suspend,
......
......@@ -157,8 +157,9 @@ void device_pm_move_last(struct device *dev)
* @ops: PM operations to choose from.
* @state: PM transition of the system being carried out.
*/
static int pm_op(struct device *dev, struct dev_pm_ops *ops,
pm_message_t state)
static int pm_op(struct device *dev,
const struct dev_pm_ops *ops,
pm_message_t state)
{
int error = 0;
......@@ -220,7 +221,8 @@ static int pm_op(struct device *dev, struct dev_pm_ops *ops,
* The operation is executed with interrupts disabled by the only remaining
* functional CPU in the system.
*/
static int pm_noirq_op(struct device *dev, struct dev_pm_ops *ops,
static int pm_noirq_op(struct device *dev,
const struct dev_pm_ops *ops,
pm_message_t state)
{
int error = 0;
......
......@@ -452,6 +452,76 @@ static unsigned int joydev_poll(struct file *file, poll_table *wait)
(joydev->exist ? 0 : (POLLHUP | POLLERR));
}
static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev,
void __user *argp, size_t len)
{
__u8 *abspam;
int i;
int retval = 0;
len = min(len, sizeof(joydev->abspam));
/* Validate the map. */
abspam = kmalloc(len, GFP_KERNEL);
if (!abspam)
return -ENOMEM;
if (copy_from_user(abspam, argp, len)) {
retval = -EFAULT;
goto out;
}
for (i = 0; i < joydev->nabs; i++) {
if (abspam[i] > ABS_MAX) {
retval = -EINVAL;
goto out;
}
}
memcpy(joydev->abspam, abspam, len);
out:
kfree(abspam);
return retval;
}
static int joydev_handle_JSIOCSBTNMAP(struct joydev *joydev,
void __user *argp, size_t len)
{
__u16 *keypam;
int i;
int retval = 0;
len = min(len, sizeof(joydev->keypam));
/* Validate the map. */
keypam = kmalloc(len, GFP_KERNEL);
if (!keypam)
return -ENOMEM;
if (copy_from_user(keypam, argp, len)) {
retval = -EFAULT;
goto out;
}
for (i = 0; i < joydev->nkey; i++) {
if (keypam[i] > KEY_MAX || keypam[i] < BTN_MISC) {
retval = -EINVAL;
goto out;
}
}
memcpy(joydev->keypam, keypam, len);
for (i = 0; i < joydev->nkey; i++)
joydev->keymap[keypam[i] - BTN_MISC] = i;
out:
kfree(keypam);
return retval;
}
static int joydev_ioctl_common(struct joydev *joydev,
unsigned int cmd, void __user *argp)
{
......@@ -512,46 +582,18 @@ static int joydev_ioctl_common(struct joydev *joydev,
switch (cmd & ~IOCSIZE_MASK) {
case (JSIOCSAXMAP & ~IOCSIZE_MASK):
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
/*
* FIXME: we should not copy into our axis map before
* validating the data.
*/
if (copy_from_user(joydev->abspam, argp, len))
return -EFAULT;
for (i = 0; i < joydev->nabs; i++) {
if (joydev->abspam[i] > ABS_MAX)
return -EINVAL;
joydev->absmap[joydev->abspam[i]] = i;
}
return 0;
return joydev_handle_JSIOCSAXMAP(joydev, argp, _IOC_SIZE(cmd));
case (JSIOCGAXMAP & ~IOCSIZE_MASK):
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : 0;
return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : len;
case (JSIOCSBTNMAP & ~IOCSIZE_MASK):
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
/*
* FIXME: we should not copy into our keymap before
* validating the data.
*/
if (copy_from_user(joydev->keypam, argp, len))
return -EFAULT;
for (i = 0; i < joydev->nkey; i++) {
if (joydev->keypam[i] > KEY_MAX ||
joydev->keypam[i] < BTN_MISC)
return -EINVAL;
joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
}
return 0;
return joydev_handle_JSIOCSBTNMAP(joydev, argp, _IOC_SIZE(cmd));
case (JSIOCGBTNMAP & ~IOCSIZE_MASK):
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : 0;
return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : len;
case JSIOCGNAME(0):
name = dev->name;
......
......@@ -144,6 +144,7 @@ static const struct xpad_device {
{ 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
{ 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
{ 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN }
};
......@@ -208,6 +209,7 @@ static struct usb_device_id xpad_table [] = {
XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x1bad), /* Rock Band Drums */
{ }
};
......
......@@ -187,7 +187,7 @@ config KEYBOARD_HIL_OLD
submenu.
config KEYBOARD_HIL
tristate "HP HIL keyboard support"
tristate "HP HIL keyboard/pointer support"
depends on GSC || HP300
default y
select HP_SDC
......@@ -196,7 +196,8 @@ config KEYBOARD_HIL
help
The "Human Interface Loop" is a older, 8-channel USB-like
controller used in several Hewlett Packard models.
This driver implements support for HIL-keyboards attached
This driver implements support for HIL-keyboards and pointing
devices (mice, tablets, touchscreens) attached
to your machine, so normally you should say Y here.
config KEYBOARD_HP6XX
......@@ -329,6 +330,17 @@ config KEYBOARD_OMAP
To compile this driver as a module, choose M here: the
module will be called omap-keypad.
config KEYBOARD_TWL4030
tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
depends on TWL4030_CORE
help
Say Y here if your board use the keypad controller on
TWL4030 family chips. It's safe to say enable this
even on boards that don't use the keypad controller.
To compile this driver as a module, choose M here: the
module will be called twl4030_keypad.
config KEYBOARD_TOSA
tristate "Tosa keyboard"
depends on MACH_TOSA
......@@ -361,4 +373,14 @@ config KEYBOARD_XTKBD
To compile this driver as a module, choose M here: the
module will be called xtkbd.
config KEYBOARD_W90P910
tristate "W90P910 Matrix Keypad support"
depends on ARCH_W90X900
help
Say Y here to enable the matrix keypad on evaluation board
based on W90P910.
To compile this driver as a module, choose M here: the
module will be called w90p910_keypad.
endif
......@@ -30,4 +30,6 @@ obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o
obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o
obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o
......@@ -68,7 +68,9 @@ MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and
* are loadable via a userland utility.
*/
static const unsigned short atkbd_set2_keycode[512] = {
#define ATKBD_KEYMAP_SIZE 512
static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = {
#ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES
......@@ -99,7 +101,7 @@ static const unsigned short atkbd_set2_keycode[512] = {
#endif
};
static const unsigned short atkbd_set3_keycode[512] = {
static const unsigned short atkbd_set3_keycode[ATKBD_KEYMAP_SIZE] = {
0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60,
131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62,
......@@ -200,8 +202,8 @@ struct atkbd {
char phys[32];
unsigned short id;
unsigned short keycode[512];
DECLARE_BITMAP(force_release_mask, 512);
unsigned short keycode[ATKBD_KEYMAP_SIZE];
DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE);
unsigned char set;
unsigned char translated;
unsigned char extra;
......@@ -253,6 +255,7 @@ static struct device_attribute atkbd_attr_##_name = \
__ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name);
ATKBD_DEFINE_ATTR(extra);
ATKBD_DEFINE_ATTR(force_release);
ATKBD_DEFINE_ATTR(scroll);
ATKBD_DEFINE_ATTR(set);
ATKBD_DEFINE_ATTR(softrepeat);
......@@ -272,6 +275,7 @@ ATKBD_DEFINE_RO_ATTR(err_count);
static struct attribute *atkbd_attributes[] = {
&atkbd_attr_extra.attr,
&atkbd_attr_force_release.attr,
&atkbd_attr_scroll.attr,
&atkbd_attr_set.attr,
&atkbd_attr_softrepeat.attr,
......@@ -934,7 +938,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
int i, j;
memset(atkbd->keycode, 0, sizeof(atkbd->keycode));
bitmap_zero(atkbd->force_release_mask, 512);
bitmap_zero(atkbd->force_release_mask, ATKBD_KEYMAP_SIZE);
if (atkbd->translated) {
for (i = 0; i < 128; i++) {
......@@ -1041,7 +1045,7 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
input_dev->keycodesize = sizeof(unsigned short);
input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
for (i = 0; i < 512; i++)
for (i = 0; i < ATKBD_KEYMAP_SIZE; i++)
if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
__set_bit(atkbd->keycode[i], input_dev->keybit);
}
......@@ -1309,6 +1313,33 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
return count;
}
static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf)
{
size_t len = bitmap_scnlistprintf(buf, PAGE_SIZE - 2,
atkbd->force_release_mask, ATKBD_KEYMAP_SIZE);
buf[len++] = '\n';
buf[len] = '\0';
return len;
}
static ssize_t atkbd_set_force_release(struct atkbd *atkbd,
const char *buf, size_t count)
{
/* 64 bytes on stack should be acceptable */
DECLARE_BITMAP(new_mask, ATKBD_KEYMAP_SIZE);
int err;
err = bitmap_parselist(buf, new_mask, ATKBD_KEYMAP_SIZE);
if (err)
return err;
memcpy(atkbd->force_release_mask, new_mask, sizeof(atkbd->force_release_mask));
return count;
}
static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf)
{
return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0);
......
......@@ -184,14 +184,13 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
int i, error;
if (!pdata->rows || !pdata->cols || !pdata->keymap) {
printk(KERN_ERR DRV_NAME
": No rows, cols or keymap from pdata\n");
dev_err(&pdev->dev, "no rows, cols or keymap from pdata\n");
return -EINVAL;
}
if (!pdata->keymapsize ||
pdata->keymapsize > (pdata->rows * pdata->cols)) {
printk(KERN_ERR DRV_NAME ": Invalid keymapsize\n");
dev_err(&pdev->dev, "invalid keymapsize\n");
return -EINVAL;
}
......@@ -211,8 +210,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT ||
!pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) {
printk(KERN_WARNING DRV_NAME
": Invalid Debounce/Columndrive Time in platform data\n");
dev_warn(&pdev->dev,
"invalid platform debounce/columndrive time\n");
bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */
} else {
bfin_write_KPAD_MSEL(
......@@ -231,16 +230,14 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
if (peripheral_request_list((u16 *)&per_rows[MAX_RC - pdata->rows],
DRV_NAME)) {
printk(KERN_ERR DRV_NAME
": Requesting Peripherals failed\n");
dev_err(&pdev->dev, "requesting peripherals failed\n");
error = -EFAULT;
goto out0;
}
if (peripheral_request_list((u16 *)&per_cols[MAX_RC - pdata->cols],
DRV_NAME)) {
printk(KERN_ERR DRV_NAME
": Requesting Peripherals failed\n");
dev_err(&pdev->dev, "requesting peripherals failed\n");
error = -EFAULT;
goto out1;
}
......@@ -254,9 +251,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
error = request_irq(bf54x_kpad->irq, bfin_kpad_isr,
0, DRV_NAME, pdev);
if (error) {
printk(KERN_ERR DRV_NAME
": unable to claim irq %d; error %d\n",
bf54x_kpad->irq, error);
dev_err(&pdev->dev, "unable to claim irq %d\n",
bf54x_kpad->irq);
goto out2;
}
......@@ -297,8 +293,7 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
error = input_register_device(input);
if (error) {
printk(KERN_ERR DRV_NAME
": Unable to register input device (%d)\n", error);
dev_err(&pdev->dev, "unable to register input device\n");
goto out4;
}
......@@ -316,9 +311,6 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
printk(KERN_ERR DRV_NAME
": Blackfin BF54x Keypad registered IRQ %d\n", bf54x_kpad->irq);
return 0;
out4:
......
......@@ -216,8 +216,9 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
#ifdef CONFIG_PM
static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state)
static int gpio_keys_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
int i;
......@@ -234,8 +235,9 @@ static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
static int gpio_keys_resume(struct platform_device *pdev)
static int gpio_keys_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
int i;
......@@ -251,19 +253,22 @@ static int gpio_keys_resume(struct platform_device *pdev)
return 0;
}
#else
#define gpio_keys_suspend NULL
#define gpio_keys_resume NULL
static const struct dev_pm_ops gpio_keys_pm_ops = {
.suspend = gpio_keys_suspend,
.resume = gpio_keys_resume,
};
#endif
static struct platform_driver gpio_keys_device_driver = {
.probe = gpio_keys_probe,
.remove = __devexit_p(gpio_keys_remove),
.suspend = gpio_keys_suspend,
.resume = gpio_keys_resume,
.driver = {
.name = "gpio-keys",
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &gpio_keys_pm_ops,
#endif
}
};
......
This diff is collapsed.
......@@ -525,12 +525,12 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
if (leds_on != 0) {
lk->serio->write (lk->serio, LK_CMD_LED_ON);
lk->serio->write (lk->serio, leds_on);
serio_write (lk->serio, LK_CMD_LED_ON);
serio_write (lk->serio, leds_on);
}
if (leds_off != 0) {
lk->serio->write (lk->serio, LK_CMD_LED_OFF);
lk->serio->write (lk->serio, leds_off);
serio_write (lk->serio, LK_CMD_LED_OFF);
serio_write (lk->serio, leds_off);
}
return 0;
......@@ -539,20 +539,20 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
case SND_CLICK:
if (value == 0) {
DBG ("%s: Deactivating key clicks\n", __func__);
lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
} else {
DBG ("%s: Activating key clicks\n", __func__);
lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
serio_write (lk->serio, volume_to_hw (lk->keyclick_volume));
serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
}
return 0;
case SND_BELL:
if (value != 0)
lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
serio_write (lk->serio, LK_CMD_SOUND_BELL);
return 0;
}
......@@ -579,10 +579,10 @@ lkkbd_reinit (struct work_struct *work)
unsigned char leds_off = 0;
/* Ask for ID */
lk->serio->write (lk->serio, LK_CMD_REQUEST_ID);
serio_write (lk->serio, LK_CMD_REQUEST_ID);
/* Reset parameters */
lk->serio->write (lk->serio, LK_CMD_SET_DEFAULTS);
serio_write (lk->serio, LK_CMD_SET_DEFAULTS);
/* Set LEDs */
CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
......@@ -590,12 +590,12 @@ lkkbd_reinit (struct work_struct *work)
CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
if (leds_on != 0) {
lk->serio->write (lk->serio, LK_CMD_LED_ON);
lk->serio->write (lk->serio, leds_on);
serio_write (lk->serio, LK_CMD_LED_ON);
serio_write (lk->serio, leds_on);
}
if (leds_off != 0) {
lk->serio->write (lk->serio, LK_CMD_LED_OFF);
lk->serio->write (lk->serio, leds_off);
serio_write (lk->serio, LK_CMD_LED_OFF);
serio_write (lk->serio, leds_off);
}
/*
......@@ -603,31 +603,31 @@ lkkbd_reinit (struct work_struct *work)
* only work with a LK401 keyboard and grants access to
* LAlt, RAlt, RCompose and RShift.
*/
lk->serio->write (lk->serio, LK_CMD_ENABLE_LK401);
serio_write (lk->serio, LK_CMD_ENABLE_LK401);
/* Set all keys to UPDOWN mode */
for (division = 1; division <= 14; division++)
lk->serio->write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN,
serio_write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN,
division));
/* Enable bell and set volume */
lk->serio->write (lk->serio, LK_CMD_ENABLE_BELL);
lk->serio->write (lk->serio, volume_to_hw (lk->bell_volume));
serio_write (lk->serio, LK_CMD_ENABLE_BELL);
serio_write (lk->serio, volume_to_hw (lk->bell_volume));
/* Enable/disable keyclick (and possibly set volume) */
if (test_bit (SND_CLICK, lk->dev->snd)) {
lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
serio_write (lk->serio, volume_to_hw (lk->keyclick_volume));
serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
} else {
lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
}
/* Sound the bell if needed */
if (test_bit (SND_BELL, lk->dev->snd))
lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
serio_write (lk->serio, LK_CMD_SOUND_BELL);
}
/*
......@@ -684,8 +684,10 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv)
input_dev->keycode = lk->keycode;
input_dev->keycodesize = sizeof (lk_keycode_t);
input_dev->keycodemax = LK_NUM_KEYCODES;
for (i = 0; i < LK_NUM_KEYCODES; i++)
set_bit (lk->keycode[i], input_dev->keybit);
__set_bit (lk->keycode[i], input_dev->keybit);
__clear_bit(KEY_RESERVED, input_dev->keybit);
serio_set_drvdata (serio, lk);
......@@ -697,7 +699,7 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv)
if (err)
goto fail3;
lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);
serio_write (lk->serio, LK_CMD_POWERCYCLE_RESET);
return 0;
......
......@@ -319,7 +319,6 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
struct input_dev *input_dev;
unsigned short *keycodes;
unsigned int row_shift;
int i;
int err;
pdata = pdev->dev.platform_data;
......@@ -363,18 +362,10 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
input_dev->keycode = keycodes;
input_dev->keycodesize = sizeof(*keycodes);
input_dev->keycodemax = pdata->num_row_gpios << keypad->row_shift;
for (i = 0; i < keymap_data->keymap_size; i++) {
unsigned int key = keymap_data->keymap[i];
unsigned int row = KEY_ROW(key);
unsigned int col = KEY_COL(key);
unsigned short code = KEY_VAL(key);
input_dev->keycodemax = pdata->num_row_gpios << row_shift;
keycodes[MATRIX_SCAN_CODE(row, col, row_shift)] = code;
__set_bit(code, input_dev->keybit);
}
__clear_bit(KEY_RESERVED, input_dev->keybit);
matrix_keypad_build_keymap(keymap_data, row_shift,
input_dev->keycode, input_dev->keybit);
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
input_set_drvdata(input_dev, keypad);
......
This diff is collapsed.
......@@ -128,7 +128,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
struct resource *res;
struct input_dev *input;
char clk_name[8];
int i, k;
int i;
int irq, error;
if (!pdev->dev.platform_data) {
......@@ -195,17 +195,19 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
input->id.product = 0x0001;
input->id.version = 0x0100;
input->keycode = pdata->keycodes;
input->keycodesize = sizeof(pdata->keycodes[0]);
input->keycodemax = ARRAY_SIZE(pdata->keycodes);
error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev);
if (error) {
dev_err(&pdev->dev, "failed to request IRQ\n");
goto err4;
}
for (i = 0; i < SH_KEYSC_MAXKEYS; i++) {
k = pdata->keycodes[i];
if (k)
input_set_capability(input, EV_KEY, k);
}
for (i = 0; i < SH_KEYSC_MAXKEYS; i++)
__set_bit(pdata->keycodes[i], input->keybit);
__clear_bit(KEY_RESERVED, input->keybit);
error = input_register_device(input);
if (error) {
......@@ -221,7 +223,9 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
device_init_wakeup(&pdev->dev, 1);
return 0;
err5:
free_irq(irq, pdev);
err4:
......@@ -252,6 +256,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
kfree(priv);
return 0;
}
......@@ -267,11 +272,12 @@ static int sh_keysc_suspend(struct device *dev)
if (device_may_wakeup(dev)) {
value |= 0x80;
enable_irq_wake(irq);
}
else
} else {
value &= ~0x80;
}
iowrite16(value, priv->iomem_base + KYCR1_OFFS);
return 0;
}
......
......@@ -73,7 +73,7 @@ static unsigned char sunkbd_keycode[128] = {
*/
struct sunkbd {
unsigned char keycode[128];
unsigned char keycode[ARRAY_SIZE(sunkbd_keycode)];
struct input_dev *dev;
struct serio *serio;
struct work_struct tq;
......@@ -81,7 +81,7 @@ struct sunkbd {
char name[64];
char phys[32];
char type;
unsigned char enabled;
bool enabled;
volatile s8 reset;
volatile s8 layout;
};
......@@ -94,10 +94,14 @@ struct sunkbd {
static irqreturn_t sunkbd_interrupt(struct serio *serio,
unsigned char data, unsigned int flags)
{
struct sunkbd* sunkbd = serio_get_drvdata(serio);
struct sunkbd *sunkbd = serio_get_drvdata(serio);
if (sunkbd->reset <= -1) { /* If cp[i] is 0xff, sunkbd->reset will stay -1. */
sunkbd->reset = data; /* The keyboard sends 0xff 0xff 0xID on powerup */
if (sunkbd->reset <= -1) {
/*
* If cp[i] is 0xff, sunkbd->reset will stay -1.
* The keyboard sends 0xff 0xff 0xID on powerup.
*/
sunkbd->reset = data;
wake_up_interruptible(&sunkbd->wait);
goto out;
}
......@@ -110,29 +114,33 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio,
switch (data) {
case SUNKBD_RET_RESET:
schedule_work(&sunkbd->tq);
sunkbd->reset = -1;
break;
case SUNKBD_RET_RESET:
schedule_work(&sunkbd->tq);
sunkbd->reset = -1;
break;
case SUNKBD_RET_LAYOUT:
sunkbd->layout = -1;
break;
case SUNKBD_RET_LAYOUT:
sunkbd->layout = -1;
break;
case SUNKBD_RET_ALLUP: /* All keys released */
break;
case SUNKBD_RET_ALLUP: /* All keys released */
default:
if (!sunkbd->enabled)
break;
default:
if (!sunkbd->enabled)
break;
if (sunkbd->keycode[data & SUNKBD_KEY]) {
input_report_key(sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
input_sync(sunkbd->dev);
} else {
printk(KERN_WARNING "sunkbd.c: Unknown key (scancode %#x) %s.\n",
data & SUNKBD_KEY, data & SUNKBD_RELEASE ? "released" : "pressed");
}
if (sunkbd->keycode[data & SUNKBD_KEY]) {
input_report_key(sunkbd->dev,
sunkbd->keycode[data & SUNKBD_KEY],
!(data & SUNKBD_RELEASE));
input_sync(sunkbd->dev);
} else {
printk(KERN_WARNING
"sunkbd.c: Unknown key (scancode %#x) %s.\n",
data & SUNKBD_KEY,
data & SUNKBD_RELEASE ? "released" : "pressed");
}
}
out:
return IRQ_HANDLED;
......@@ -142,34 +150,37 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio,
* sunkbd_event() handles events from the input module.
*/
static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
static int sunkbd_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
struct sunkbd *sunkbd = input_get_drvdata(dev);
switch (type) {
case EV_LED:
case EV_LED:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
sunkbd->serio->write(sunkbd->serio,
(!!test_bit(LED_CAPSL, dev->led) << 3) | (!!test_bit(LED_SCROLLL, dev->led) << 2) |
(!!test_bit(LED_COMPOSE, dev->led) << 1) | !!test_bit(LED_NUML, dev->led));
return 0;
serio_write(sunkbd->serio, SUNKBD_CMD_SETLED);
serio_write(sunkbd->serio,
(!!test_bit(LED_CAPSL, dev->led) << 3) |
(!!test_bit(LED_SCROLLL, dev->led) << 2) |
(!!test_bit(LED_COMPOSE, dev->led) << 1) |
!!test_bit(LED_NUML, dev->led));
return 0;
case EV_SND:
case EV_SND:
switch (code) {
switch (code) {
case SND_CLICK:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value);
return 0;
case SND_CLICK:
serio_write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value);
return 0;
case SND_BELL:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value);
return 0;
}
case SND_BELL:
serio_write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value);
return 0;
}
break;
break;
}
return -1;
......@@ -183,7 +194,7 @@ static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int c
static int sunkbd_initialize(struct sunkbd *sunkbd)
{
sunkbd->reset = -2;
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_RESET);
serio_write(sunkbd->serio, SUNKBD_CMD_RESET);
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
if (sunkbd->reset < 0)
return -1;
......@@ -192,10 +203,13 @@ static int sunkbd_initialize(struct sunkbd *sunkbd)
if (sunkbd->type == 4) { /* Type 4 keyboard */
sunkbd->layout = -2;
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_LAYOUT);
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->layout >= 0, HZ/4);
if (sunkbd->layout < 0) return -1;
if (sunkbd->layout & SUNKBD_LAYOUT_5_MASK) sunkbd->type = 5;
serio_write(sunkbd->serio, SUNKBD_CMD_LAYOUT);
wait_event_interruptible_timeout(sunkbd->wait,
sunkbd->layout >= 0, HZ / 4);
if (sunkbd->layout < 0)
return -1;
if (sunkbd->layout & SUNKBD_LAYOUT_5_MASK)
sunkbd->type = 5;
}
return 0;
......@@ -212,15 +226,19 @@ static void sunkbd_reinit(struct work_struct *work)
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
sunkbd->serio->write(sunkbd->serio,
(!!test_bit(LED_CAPSL, sunkbd->dev->led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev->led) << 2) |
(!!test_bit(LED_COMPOSE, sunkbd->dev->led) << 1) | !!test_bit(LED_NUML, sunkbd->dev->led));
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev->snd));
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd));
serio_write(sunkbd->serio, SUNKBD_CMD_SETLED);
serio_write(sunkbd->serio,
(!!test_bit(LED_CAPSL, sunkbd->dev->led) << 3) |
(!!test_bit(LED_SCROLLL, sunkbd->dev->led) << 2) |
(!!test_bit(LED_COMPOSE, sunkbd->dev->led) << 1) |
!!test_bit(LED_NUML, sunkbd->dev->led));
serio_write(sunkbd->serio,
SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev->snd));
serio_write(sunkbd->serio,
SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd));
}
static void sunkbd_enable(struct sunkbd *sunkbd, int enable)
static void sunkbd_enable(struct sunkbd *sunkbd, bool enable)
{
serio_pause_rx(sunkbd->serio);
sunkbd->enabled = enable;
......@@ -228,7 +246,8 @@ static void sunkbd_enable(struct sunkbd *sunkbd, int enable)
}
/*
* sunkbd_connect() probes for a Sun keyboard and fills the necessary structures.
* sunkbd_connect() probes for a Sun keyboard and fills the necessary
* structures.
*/
static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
......@@ -260,7 +279,8 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
goto fail3;
}
snprintf(sunkbd->name, sizeof(sunkbd->name), "Sun Type %d keyboard", sunkbd->type);
snprintf(sunkbd->name, sizeof(sunkbd->name),
"Sun Type %d keyboard", sunkbd->type);
memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
input_dev->name = sunkbd->name;
......@@ -284,11 +304,11 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
input_dev->keycode = sunkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(sunkbd_keycode);
for (i = 0; i < 128; i++)
set_bit(sunkbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
for (i = 0; i < ARRAY_SIZE(sunkbd_keycode); i++)
__set_bit(sunkbd->keycode[i], input_dev->keybit);
__clear_bit(KEY_RESERVED, input_dev->keybit);
sunkbd_enable(sunkbd, 1);
sunkbd_enable(sunkbd, true);
err = input_register_device(sunkbd->dev);
if (err)
......@@ -296,7 +316,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
return 0;
fail4: sunkbd_enable(sunkbd, 0);
fail4: sunkbd_enable(sunkbd, false);
fail3: serio_close(serio);
fail2: serio_set_drvdata(serio, NULL);
fail1: input_free_device(input_dev);
......@@ -312,7 +332,7 @@ static void sunkbd_disconnect(struct serio *serio)
{
struct sunkbd *sunkbd = serio_get_drvdata(serio);
sunkbd_enable(sunkbd, 0);
sunkbd_enable(sunkbd, false);
input_unregister_device(sunkbd->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
......
......@@ -31,7 +31,7 @@
#define KB_DISCHARGE_DELAY 10
#define KB_ACTIVATE_DELAY 10
static unsigned int tosakbd_keycode[NR_SCANCODES] = {
static unsigned short tosakbd_keycode[NR_SCANCODES] = {
0,
0, KEY_W, 0, 0, 0, KEY_K, KEY_BACKSPACE, KEY_P,
0, 0, 0, 0, 0, 0, 0, 0,
......@@ -50,9 +50,9 @@ KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_
};
struct tosakbd {
unsigned int keycode[ARRAY_SIZE(tosakbd_keycode)];
unsigned short keycode[ARRAY_SIZE(tosakbd_keycode)];
struct input_dev *input;
int suspended;
bool suspended;
spinlock_t lock; /* protect kbd scanning */
struct timer_list timer;
};
......@@ -215,7 +215,7 @@ static int tosakbd_suspend(struct platform_device *dev, pm_message_t state)
unsigned long flags;
spin_lock_irqsave(&tosakbd->lock, flags);
tosakbd->suspended = 1;
tosakbd->suspended = true;
spin_unlock_irqrestore(&tosakbd->lock, flags);
del_timer_sync(&tosakbd->timer);
......@@ -227,7 +227,7 @@ static int tosakbd_resume(struct platform_device *dev)
{
struct tosakbd *tosakbd = platform_get_drvdata(dev);
tosakbd->suspended = 0;
tosakbd->suspended = false;
tosakbd_scankeyboard(dev);
return 0;
......@@ -277,14 +277,14 @@ static int __devinit tosakbd_probe(struct platform_device *pdev) {
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
input_dev->keycode = tosakbd->keycode;
input_dev->keycodesize = sizeof(unsigned int);
input_dev->keycodesize = sizeof(tosakbd->keycode[0]);
input_dev->keycodemax = ARRAY_SIZE(tosakbd_keycode);
memcpy(tosakbd->keycode, tosakbd_keycode, sizeof(tosakbd_keycode));
for (i = 0; i < ARRAY_SIZE(tosakbd_keycode); i++)
__set_bit(tosakbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
__clear_bit(KEY_RESERVED, input_dev->keybit);
/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) {
......@@ -344,7 +344,7 @@ static int __devinit tosakbd_probe(struct platform_device *pdev) {
" direction for GPIO %d, error %d\n",
gpio, error);
gpio_free(gpio);
goto fail;
goto fail2;
}
}
......@@ -353,7 +353,7 @@ static int __devinit tosakbd_probe(struct platform_device *pdev) {
if (error) {
printk(KERN_ERR "tosakbd: Unable to register input device, "
"error: %d\n", error);
goto fail;
goto fail2;
}
printk(KERN_INFO "input: Tosa Keyboard Registered\n");
......
This diff is collapsed.
/*
* Copyright (c) 2008-2009 Nuvoton technology corporation.
*
* Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <mach/w90p910_keypad.h>
/* Keypad Interface Control Registers */
#define KPI_CONF 0x00
#define KPI_3KCONF 0x04
#define KPI_LPCONF 0x08
#define KPI_STATUS 0x0C
#define IS1KEY (0x01 << 16)
#define INTTR (0x01 << 21)
#define KEY0R (0x0f << 3)
#define KEY0C 0x07
#define DEBOUNCE_BIT 0x08
#define KSIZE0 (0x01 << 16)
#define KSIZE1 (0x01 << 17)
#define KPSEL (0x01 << 19)
#define ENKP (0x01 << 18)
#define KGET_RAW(n) (((n) & KEY0R) >> 3)
#define KGET_COLUMN(n) ((n) & KEY0C)
#define W90P910_MAX_KEY_NUM (8 * 8)
#define W90P910_ROW_SHIFT 3
struct w90p910_keypad {
const struct w90p910_keypad_platform_data *pdata;
struct clk *clk;
struct input_dev *input_dev;
void __iomem *mmio_base;
int irq;
unsigned short keymap[W90P910_MAX_KEY_NUM];
};
static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad,
unsigned int status)
{
struct input_dev *input_dev = keypad->input_dev;
unsigned int row = KGET_RAW(status);
unsigned int col = KGET_COLUMN(status);
unsigned int code = MATRIX_SCAN_CODE(row, col, W90P910_ROW_SHIFT);
unsigned int key = keypad->keymap[code];
input_event(input_dev, EV_MSC, MSC_SCAN, code);
input_report_key(input_dev, key, 1);
input_sync(input_dev);
input_event(input_dev, EV_MSC, MSC_SCAN, code);
input_report_key(input_dev, key, 0);
input_sync(input_dev);
}
static irqreturn_t w90p910_keypad_irq_handler(int irq, void *dev_id)
{
struct w90p910_keypad *keypad = dev_id;
unsigned int kstatus, val;
kstatus = __raw_readl(keypad->mmio_base + KPI_STATUS);
val = INTTR | IS1KEY;
if (kstatus & val)
w90p910_keypad_scan_matrix(keypad, kstatus);
return IRQ_HANDLED;
}
static int w90p910_keypad_open(struct input_dev *dev)
{
struct w90p910_keypad *keypad = input_get_drvdata(dev);
const struct w90p910_keypad_platform_data *pdata = keypad->pdata;
unsigned int val, config;
/* Enable unit clock */
clk_enable(keypad->clk);
val = __raw_readl(keypad->mmio_base + KPI_CONF);
val |= (KPSEL | ENKP);
val &= ~(KSIZE0 | KSIZE1);
config = pdata->prescale | (pdata->debounce << DEBOUNCE_BIT);
val |= config;
__raw_writel(val, keypad->mmio_base + KPI_CONF);
return 0;
}
static void w90p910_keypad_close(struct input_dev *dev)
{
struct w90p910_keypad *keypad = input_get_drvdata(dev);
/* Disable clock unit */
clk_disable(keypad->clk);
}
static int __devinit w90p910_keypad_probe(struct platform_device *pdev)
{
const struct w90p910_keypad_platform_data *pdata =
pdev->dev.platform_data;
const struct matrix_keymap_data *keymap_data;
struct w90p910_keypad *keypad;
struct input_dev *input_dev;
struct resource *res;
int irq;
int error;
if (!pdata) {
dev_err(&pdev->dev, "no platform data defined\n");
return -EINVAL;
}
keymap_data = pdata->keymap_data;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "failed to get keypad irq\n");
return -ENXIO;
}
keypad = kzalloc(sizeof(struct w90p910_keypad), GFP_KERNEL);
input_dev = input_allocate_device();
if (!keypad || !input_dev) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
error = -ENOMEM;
goto failed_free;
}
keypad->pdata = pdata;
keypad->input_dev = input_dev;
keypad->irq = irq;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "failed to get I/O memory\n");
error = -ENXIO;
goto failed_free;
}
res = request_mem_region(res->start, resource_size(res), pdev->name);
if (res == NULL) {
dev_err(&pdev->dev, "failed to request I/O memory\n");
error = -EBUSY;
goto failed_free;
}
keypad->mmio_base = ioremap(res->start, resource_size(res));
if (keypad->mmio_base == NULL) {
dev_err(&pdev->dev, "failed to remap I/O memory\n");
error = -ENXIO;
goto failed_free_res;
}
keypad->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(keypad->clk)) {
dev_err(&pdev->dev, "failed to get keypad clock\n");
error = PTR_ERR(keypad->clk);
goto failed_free_io;
}
/* set multi-function pin for w90p910 kpi. */
mfp_set_groupi(&pdev->dev);
input_dev->name = pdev->name;
input_dev->id.bustype = BUS_HOST;
input_dev->open = w90p910_keypad_open;
input_dev->close = w90p910_keypad_close;
input_dev->dev.parent = &pdev->dev;
input_dev->keycode = keypad->keymap;
input_dev->keycodesize = sizeof(keypad->keymap[0]);
input_dev->keycodemax = ARRAY_SIZE(keypad->keymap);
input_set_drvdata(input_dev, keypad);
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
matrix_keypad_build_keymap(keymap_data, W90P910_ROW_SHIFT,
input_dev->keycode, input_dev->keybit);
error = request_irq(keypad->irq, w90p910_keypad_irq_handler,
IRQF_DISABLED, pdev->name, keypad);
if (error) {
dev_err(&pdev->dev, "failed to request IRQ\n");
goto failed_put_clk;
}
/* Register the input device */
error = input_register_device(input_dev);
if (error) {
dev_err(&pdev->dev, "failed to register input device\n");
goto failed_free_irq;
}
platform_set_drvdata(pdev, keypad);
return 0;
failed_free_irq:
free_irq(irq, pdev);
failed_put_clk:
clk_put(keypad->clk);
failed_free_io:
iounmap(keypad->mmio_base);
failed_free_res:
release_mem_region(res->start, resource_size(res));
failed_free:
input_free_device(input_dev);
kfree(keypad);
return error;
}
static int __devexit w90p910_keypad_remove(struct platform_device *pdev)
{
struct w90p910_keypad *keypad = platform_get_drvdata(pdev);
struct resource *res;
free_irq(keypad->irq, pdev);
clk_put(keypad->clk);
input_unregister_device(keypad->input_dev);
iounmap(keypad->mmio_base);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, resource_size(res));
platform_set_drvdata(pdev, NULL);
kfree(keypad);
return 0;
}
static struct platform_driver w90p910_keypad_driver = {
.probe = w90p910_keypad_probe,
.remove = __devexit_p(w90p910_keypad_remove),
.driver = {
.name = "nuc900-keypad",
.owner = THIS_MODULE,
},
};
static int __init w90p910_keypad_init(void)
{
return platform_driver_register(&w90p910_keypad_driver);
}
static void __exit w90p910_keypad_exit(void)
{
platform_driver_unregister(&w90p910_keypad_driver);
}
module_init(w90p910_keypad_init);
module_exit(w90p910_keypad_exit);
MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
MODULE_DESCRIPTION("w90p910 keypad driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:nuc900-keypad");
......@@ -269,4 +269,14 @@ config INPUT_DM355EVM
To compile this driver as a module, choose M here: the
module will be called dm355evm_keys.
config INPUT_BFIN_ROTARY
tristate "Blackfin Rotary support"
depends on BF54x || BF52x
help
Say Y here if you want to use the Blackfin Rotary.
To compile this driver as a module, choose M here: the
module will be called bfin-rotary.
endif
......@@ -8,6 +8,7 @@ obj-$(CONFIG_INPUT_APANEL) += apanel.o
obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o
obj-$(CONFIG_INPUT_CM109) += cm109.o
obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o
......
/*
* Rotary counter driver for Analog Devices Blackfin Processors
*
* Copyright 2008-2009 Analog Devices Inc.
* Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <asm/portmux.h>
#include <asm/bfin_rotary.h>
static const u16 per_cnt[] = {
P_CNT_CUD,
P_CNT_CDG,
P_CNT_CZM,
0
};
struct bfin_rot {
struct input_dev *input;
int irq;
unsigned int up_key;
unsigned int down_key;
unsigned int button_key;
unsigned int rel_code;
unsigned short cnt_config;
unsigned short cnt_imask;
unsigned short cnt_debounce;
};
static void report_key_event(struct input_dev *input, int keycode)
{
/* simulate a press-n-release */
input_report_key(input, keycode, 1);
input_sync(input);
input_report_key(input, keycode, 0);
input_sync(input);
}
static void report_rotary_event(struct bfin_rot *rotary, int delta)
{
struct input_dev *input = rotary->input;
if (rotary->up_key) {
report_key_event(input,
delta > 0 ? rotary->up_key : rotary->down_key);
} else {
input_report_rel(input, rotary->rel_code, delta);
input_sync(input);
}
}
static irqreturn_t bfin_rotary_isr(int irq, void *dev_id)
{
struct platform_device *pdev = dev_id;
struct bfin_rot *rotary = platform_get_drvdata(pdev);
int delta;
switch (bfin_read_CNT_STATUS()) {
case ICII:
break;
case UCII:
case DCII:
delta = bfin_read_CNT_COUNTER();
if (delta)
report_rotary_event(rotary, delta);
break;
case CZMII:
report_key_event(rotary->input, rotary->button_key);
break;
default:
break;
}
bfin_write_CNT_COMMAND(W1LCNT_ZERO); /* Clear COUNTER */
bfin_write_CNT_STATUS(-1); /* Clear STATUS */
return IRQ_HANDLED;
}
static int __devinit bfin_rotary_probe(struct platform_device *pdev)
{
struct bfin_rotary_platform_data *pdata = pdev->dev.platform_data;
struct bfin_rot *rotary;
struct input_dev *input;
int error;
/* Basic validation */
if ((pdata->rotary_up_key && !pdata->rotary_down_key) ||
(!pdata->rotary_up_key && pdata->rotary_down_key)) {
return -EINVAL;
}
error = peripheral_request_list(per_cnt, dev_name(&pdev->dev));
if (error) {
dev_err(&pdev->dev, "requesting peripherals failed\n");
return error;
}
rotary = kzalloc(sizeof(struct bfin_rot), GFP_KERNEL);
input = input_allocate_device();
if (!rotary || !input) {
error = -ENOMEM;
goto out1;
}
rotary->input = input;
rotary->up_key = pdata->rotary_up_key;
rotary->down_key = pdata->rotary_down_key;
rotary->button_key = pdata->rotary_button_key;
rotary->rel_code = pdata->rotary_rel_code;
error = rotary->irq = platform_get_irq(pdev, 0);
if (error < 0)
goto out1;
input->name = pdev->name;
input->phys = "bfin-rotary/input0";
input->dev.parent = &pdev->dev;
input_set_drvdata(input, rotary);
input->id.bustype = BUS_HOST;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0100;
if (rotary->up_key) {
__set_bit(EV_KEY, input->evbit);
__set_bit(rotary->up_key, input->keybit);
__set_bit(rotary->down_key, input->keybit);
} else {
__set_bit(EV_REL, input->evbit);
__set_bit(rotary->rel_code, input->relbit);
}
if (rotary->button_key) {
__set_bit(EV_KEY, input->evbit);
__set_bit(rotary->button_key, input->keybit);
}
error = request_irq(rotary->irq, bfin_rotary_isr,
0, dev_name(&pdev->dev), pdev);
if (error) {
dev_err(&pdev->dev,
"unable to claim irq %d; error %d\n",
rotary->irq, error);
goto out1;
}
error = input_register_device(input);
if (error) {
dev_err(&pdev->dev,
"unable to register input device (%d)\n", error);
goto out2;
}
if (pdata->rotary_button_key)
bfin_write_CNT_IMASK(CZMIE);
if (pdata->mode & ROT_DEBE)
bfin_write_CNT_DEBOUNCE(pdata->debounce & DPRESCALE);
if (pdata->mode)
bfin_write_CNT_CONFIG(bfin_read_CNT_CONFIG() |
(pdata->mode & ~CNTE));
bfin_write_CNT_IMASK(bfin_read_CNT_IMASK() | UCIE | DCIE);
bfin_write_CNT_CONFIG(bfin_read_CNT_CONFIG() | CNTE);
platform_set_drvdata(pdev, rotary);
device_init_wakeup(&pdev->dev, 1);
return 0;
out2:
free_irq(rotary->irq, pdev);
out1:
input_free_device(input);
kfree(rotary);
peripheral_free_list(per_cnt);
return error;
}
static int __devexit bfin_rotary_remove(struct platform_device *pdev)
{
struct bfin_rot *rotary = platform_get_drvdata(pdev);
bfin_write_CNT_CONFIG(0);
bfin_write_CNT_IMASK(0);
free_irq(rotary->irq, pdev);
input_unregister_device(rotary->input);
peripheral_free_list(per_cnt);
kfree(rotary);
platform_set_drvdata(pdev, NULL);
return 0;
}
#ifdef CONFIG_PM
static int bfin_rotary_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct bfin_rot *rotary = platform_get_drvdata(pdev);
rotary->cnt_config = bfin_read_CNT_CONFIG();
rotary->cnt_imask = bfin_read_CNT_IMASK();
rotary->cnt_debounce = bfin_read_CNT_DEBOUNCE();
if (device_may_wakeup(&pdev->dev))
enable_irq_wake(rotary->irq);
return 0;
}
static int bfin_rotary_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct bfin_rot *rotary = platform_get_drvdata(pdev);
bfin_write_CNT_DEBOUNCE(rotary->cnt_debounce);
bfin_write_CNT_IMASK(rotary->cnt_imask);
bfin_write_CNT_CONFIG(rotary->cnt_config & ~CNTE);
if (device_may_wakeup(&pdev->dev))
disable_irq_wake(rotary->irq);
if (rotary->cnt_config & CNTE)
bfin_write_CNT_CONFIG(rotary->cnt_config);
return 0;
}
static struct dev_pm_ops bfin_rotary_pm_ops = {
.suspend = bfin_rotary_suspend,
.resume = bfin_rotary_resume,
};
#endif
static struct platform_driver bfin_rotary_device_driver = {
.probe = bfin_rotary_probe,
.remove = __devexit_p(bfin_rotary_remove),
.driver = {
.name = "bfin-rotary",
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &bfin_rotary_pm_ops,
#endif
},
};
static int __init bfin_rotary_init(void)
{
return platform_driver_register(&bfin_rotary_device_driver);
}
module_init(bfin_rotary_init);
static void __exit bfin_rotary_exit(void)
{
platform_driver_unregister(&bfin_rotary_device_driver);
}
module_exit(bfin_rotary_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
MODULE_DESCRIPTION("Rotary Counter driver for Blackfin Processors");
MODULE_ALIAS("platform:bfin-rotary");
......@@ -116,7 +116,7 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev)
}
bdev->poll_dev = poll_dev;
bdev->reg = ioremap(res->start, res->end - res->start + 1);
bdev->reg = ioremap(res->start, resource_size(res));
dev_set_drvdata(&pdev->dev, bdev);
error = input_register_polled_device(poll_dev);
......
......@@ -23,30 +23,16 @@
* pressed, or its autorepeat kicks in, an event is sent. This driver
* read those events from the small (32 event) queue and reports them.
*
* Because we communicate with the MSP430 using I2C, and all I2C calls
* in Linux sleep, we need to cons up a kind of threaded IRQ handler
* using a work_struct. The IRQ is active low, but we use it through
* the GPIO controller so we can trigger on falling edges.
*
* Note that physically there can only be one of these devices.
*
* This driver was tested with firmware revision A4.
*/
struct dm355evm_keys {
struct work_struct work;
struct input_dev *input;
struct device *dev;
int irq;
};
static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
{
struct dm355evm_keys *keys = _keys;
schedule_work(&keys->work);
return IRQ_HANDLED;
}
/* These initial keycodes can be remapped by dm355evm_setkeycode(). */
static struct {
u16 event;
......@@ -110,13 +96,12 @@ static struct {
{ 0x3169, KEY_PAUSE, },
};
static void dm355evm_keys_work(struct work_struct *work)
/* runs in an IRQ thread -- can (and will!) sleep */
static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
{
struct dm355evm_keys *keys;
struct dm355evm_keys *keys = _keys;
int status;
keys = container_of(work, struct dm355evm_keys, work);
/* For simplicity we ignore INPUT_COUNT and just read
* events until we get the "queue empty" indicator.
* Reading INPUT_LOW decrements the count.
......@@ -183,6 +168,19 @@ static void dm355evm_keys_work(struct work_struct *work)
input_report_key(keys->input, keycode, 0);
input_sync(keys->input);
}
return IRQ_HANDLED;
}
/*
* Because we communicate with the MSP430 using I2C, and all I2C calls
* in Linux sleep, we use a threaded IRQ handler. The IRQ itself is
* active low, but we go through the GPIO controller so we can trigger
* on falling edges and not worry about enabling/disabling the IRQ in
* the keypress handling path.
*/
static irqreturn_t dm355evm_keys_hardirq(int irq, void *_keys)
{
return IRQ_WAKE_THREAD;
}
static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode)
......@@ -233,7 +231,6 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
keys->dev = &pdev->dev;
keys->input = input;
INIT_WORK(&keys->work, dm355evm_keys_work);
/* set up "threaded IRQ handler" */
status = platform_get_irq(pdev, 0);
......@@ -260,9 +257,10 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
/* REVISIT: flush the event queue? */
status = request_irq(keys->irq, dm355evm_keys_irq,
IRQF_TRIGGER_FALLING,
dev_name(&pdev->dev), keys);
status = request_threaded_irq(keys->irq,
dm355evm_keys_hardirq, dm355evm_keys_irq,
IRQF_TRIGGER_FALLING,
dev_name(&pdev->dev), keys);
if (status < 0)
goto fail1;
......
......@@ -243,9 +243,9 @@ enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
#define FE_UNTESTED 0x80
static struct key_entry *keymap; /* = NULL; Current key map */
static int have_wifi;
static int have_bluetooth;
static int have_leds;
static bool have_wifi;
static bool have_bluetooth;
static int leds_present; /* bitmask of leds present */
static int __init dmi_matched(const struct dmi_system_id *dmi)
{
......@@ -254,11 +254,11 @@ static int __init dmi_matched(const struct dmi_system_id *dmi)
keymap = dmi->driver_data;
for (key = keymap; key->type != KE_END; key++) {
if (key->type == KE_WIFI)
have_wifi = 1;
have_wifi = true;
else if (key->type == KE_BLUETOOTH)
have_bluetooth = 1;
have_bluetooth = true;
}
have_leds = key->code & (FE_MAIL_LED | FE_WIFI_LED);
leds_present = key->code & (FE_MAIL_LED | FE_WIFI_LED);
return 1;
}
......@@ -611,10 +611,24 @@ static struct key_entry keymap_wistron_generic[] __initdata = {
{ KE_END, 0 }
};
static struct key_entry keymap_aopen_1557[] __initdata = {
{ KE_KEY, 0x01, {KEY_HELP} },
{ KE_KEY, 0x11, {KEY_PROG1} },
{ KE_KEY, 0x12, {KEY_PROG2} },
{ KE_WIFI, 0x30 },
{ KE_KEY, 0x22, {KEY_REWIND} },
{ KE_KEY, 0x23, {KEY_FORWARD} },
{ KE_KEY, 0x24, {KEY_PLAYPAUSE} },
{ KE_KEY, 0x25, {KEY_STOPCD} },
{ KE_KEY, 0x31, {KEY_MAIL} },
{ KE_KEY, 0x36, {KEY_WWW} },
{ KE_END, 0 }
};
static struct key_entry keymap_prestigio[] __initdata = {
{ KE_KEY, 0x11, {KEY_PROG1} },
{ KE_KEY, 0x12, {KEY_PROG2} },
{ KE_WIFI, 0x30 },
{ KE_WIFI, 0x30 },
{ KE_KEY, 0x22, {KEY_REWIND} },
{ KE_KEY, 0x23, {KEY_FORWARD} },
{ KE_KEY, 0x24, {KEY_PLAYPAUSE} },
......@@ -985,6 +999,8 @@ static int __init select_keymap(void)
if (keymap_name != NULL) {
if (strcmp (keymap_name, "1557/MS2141") == 0)
keymap = keymap_wistron_ms2141;
else if (strcmp (keymap_name, "aopen1557") == 0)
keymap = keymap_aopen_1557;
else if (strcmp (keymap_name, "prestigio") == 0)
keymap = keymap_prestigio;
else if (strcmp (keymap_name, "generic") == 0)
......@@ -1009,8 +1025,8 @@ static int __init select_keymap(void)
static struct input_polled_dev *wistron_idev;
static unsigned long jiffies_last_press;
static int wifi_enabled;
static int bluetooth_enabled;
static bool wifi_enabled;
static bool bluetooth_enabled;
static void report_key(struct input_dev *dev, unsigned int keycode)
{
......@@ -1053,24 +1069,24 @@ static struct led_classdev wistron_wifi_led = {
static void __devinit wistron_led_init(struct device *parent)
{
if (have_leds & FE_WIFI_LED) {
if (leds_present & FE_WIFI_LED) {
u16 wifi = bios_get_default_setting(WIFI);
if (wifi & 1) {
wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF;
if (led_classdev_register(parent, &wistron_wifi_led))
have_leds &= ~FE_WIFI_LED;
leds_present &= ~FE_WIFI_LED;
else
bios_set_state(WIFI, wistron_wifi_led.brightness);
} else
have_leds &= ~FE_WIFI_LED;
leds_present &= ~FE_WIFI_LED;
}
if (have_leds & FE_MAIL_LED) {
if (leds_present & FE_MAIL_LED) {
/* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */
wistron_mail_led.brightness = LED_OFF;
if (led_classdev_register(parent, &wistron_mail_led))
have_leds &= ~FE_MAIL_LED;
leds_present &= ~FE_MAIL_LED;
else
bios_set_state(MAIL_LED, wistron_mail_led.brightness);
}
......@@ -1078,28 +1094,28 @@ static void __devinit wistron_led_init(struct device *parent)
static void __devexit wistron_led_remove(void)
{
if (have_leds & FE_MAIL_LED)
if (leds_present & FE_MAIL_LED)
led_classdev_unregister(&wistron_mail_led);
if (have_leds & FE_WIFI_LED)
if (leds_present & FE_WIFI_LED)
led_classdev_unregister(&wistron_wifi_led);
}
static inline void wistron_led_suspend(void)
{
if (have_leds & FE_MAIL_LED)
if (leds_present & FE_MAIL_LED)
led_classdev_suspend(&wistron_mail_led);
if (have_leds & FE_WIFI_LED)
if (leds_present & FE_WIFI_LED)
led_classdev_suspend(&wistron_wifi_led);
}
static inline void wistron_led_resume(void)
{
if (have_leds & FE_MAIL_LED)
if (leds_present & FE_MAIL_LED)
led_classdev_resume(&wistron_mail_led);
if (have_leds & FE_WIFI_LED)
if (leds_present & FE_WIFI_LED)
led_classdev_resume(&wistron_wifi_led);
}
......@@ -1312,7 +1328,7 @@ static int __devinit wistron_probe(struct platform_device *dev)
if (have_wifi) {
u16 wifi = bios_get_default_setting(WIFI);
if (wifi & 1)
wifi_enabled = (wifi & 2) ? 1 : 0;
wifi_enabled = wifi & 2;
else
have_wifi = 0;
......@@ -1323,15 +1339,16 @@ static int __devinit wistron_probe(struct platform_device *dev)
if (have_bluetooth) {
u16 bt = bios_get_default_setting(BLUETOOTH);
if (bt & 1)
bluetooth_enabled = (bt & 2) ? 1 : 0;
bluetooth_enabled = bt & 2;
else
have_bluetooth = 0;
have_bluetooth = false;
if (have_bluetooth)
bios_set_state(BLUETOOTH, bluetooth_enabled);
}
wistron_led_init(&dev->dev);
err = setup_input_dev();
if (err) {
bios_detach();
......@@ -1352,7 +1369,7 @@ static int __devexit wistron_remove(struct platform_device *dev)
}
#ifdef CONFIG_PM
static int wistron_suspend(struct platform_device *dev, pm_message_t state)
static int wistron_suspend(struct device *dev)
{
if (have_wifi)
bios_set_state(WIFI, 0);
......@@ -1361,10 +1378,11 @@ static int wistron_suspend(struct platform_device *dev, pm_message_t state)
bios_set_state(BLUETOOTH, 0);
wistron_led_suspend();
return 0;
}
static int wistron_resume(struct platform_device *dev)
static int wistron_resume(struct device *dev)
{
if (have_wifi)
bios_set_state(WIFI, wifi_enabled);
......@@ -1373,24 +1391,30 @@ static int wistron_resume(struct platform_device *dev)
bios_set_state(BLUETOOTH, bluetooth_enabled);
wistron_led_resume();
poll_bios(true);
return 0;
}
#else
#define wistron_suspend NULL
#define wistron_resume NULL
static const struct dev_pm_ops wistron_pm_ops = {
.suspend = wistron_suspend,
.resume = wistron_resume,
.poweroff = wistron_suspend,
.restore = wistron_resume,
};
#endif
static struct platform_driver wistron_driver = {
.driver = {
.name = "wistron-bios",
.owner = THIS_MODULE,
#if CONFIG_PM
.pm = &wistron_pm_ops,
#endif
},
.probe = wistron_probe,
.remove = __devexit_p(wistron_remove),
.suspend = wistron_suspend,
.resume = wistron_resume,
};
static int __init wb_module_init(void)
......
......@@ -107,6 +107,14 @@ config MOUSE_PS2_ELANTECH
entries. For further information,
see <file:Documentation/input/elantech.txt>.
config MOUSE_PS2_SENTELIC
bool "Sentelic Finger Sensing Pad PS/2 protocol extension"
depends on MOUSE_PS2
help
Say Y here if you have a laptop (such as MSI WIND Netbook)
with Sentelic Finger Sensing Pad touchpad.
If unsure, say N.
config MOUSE_PS2_TOUCHKIT
bool "eGalax TouchKit PS/2 protocol extension"
......@@ -262,14 +270,6 @@ config MOUSE_VSXXXAA
described in the source file). This driver also works with the
digitizer (VSXXX-AB) DEC produced.
config MOUSE_HIL
tristate "HIL pointers (mice etc)."
depends on GSC || HP300
select HP_SDC
select HIL_MLC
help
Say Y here to support HIL pointers.
config MOUSE_GPIO
tristate "GPIO mouse"
depends on GENERIC_GPIO
......
......@@ -9,7 +9,6 @@ obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o
obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o
obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o
obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
obj-$(CONFIG_MOUSE_INPORT) += inport.o
obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o
obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o
......@@ -28,5 +27,6 @@ psmouse-$(CONFIG_MOUSE_PS2_ELANTECH) += elantech.o
psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o
psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o
psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o
psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o
psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o
......@@ -279,7 +279,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
* subsequent commands. It looks like glidepad is behind stickpointer,
* I'd thought it would be other way around...
*/
static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
static int alps_passthrough_mode(struct psmouse *psmouse, bool enable)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
......@@ -367,16 +367,16 @@ static int alps_poll(struct psmouse *psmouse)
{
struct alps_data *priv = psmouse->private;
unsigned char buf[6];
int poll_failed;
bool poll_failed;
if (priv->i->flags & ALPS_PASS)
alps_passthrough_mode(psmouse, 1);
alps_passthrough_mode(psmouse, true);
poll_failed = ps2_command(&psmouse->ps2dev, buf,
PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
if (priv->i->flags & ALPS_PASS)
alps_passthrough_mode(psmouse, 0);
alps_passthrough_mode(psmouse, false);
if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
return -1;
......@@ -401,10 +401,12 @@ static int alps_hw_init(struct psmouse *psmouse, int *version)
if (!priv->i)
return -1;
if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
if ((priv->i->flags & ALPS_PASS) &&
alps_passthrough_mode(psmouse, true)) {
return -1;
}
if (alps_tap_mode(psmouse, 1)) {
if (alps_tap_mode(psmouse, true)) {
printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
return -1;
}
......@@ -414,8 +416,10 @@ static int alps_hw_init(struct psmouse *psmouse, int *version)
return -1;
}
if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
if ((priv->i->flags & ALPS_PASS) &&
alps_passthrough_mode(psmouse, false)) {
return -1;
}
/* ALPS needs stream mode, otherwise it won't report any data */
if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
......@@ -519,7 +523,7 @@ int alps_init(struct psmouse *psmouse)
return -1;
}
int alps_detect(struct psmouse *psmouse, int set_properties)
int alps_detect(struct psmouse *psmouse, bool set_properties)
{
int version;
const struct alps_model_info *model;
......
......@@ -26,10 +26,10 @@ struct alps_data {
};
#ifdef CONFIG_MOUSE_PS2_ALPS
int alps_detect(struct psmouse *psmouse, int set_properties);
int alps_detect(struct psmouse *psmouse, bool set_properties);
int alps_init(struct psmouse *psmouse);
#else
inline int alps_detect(struct psmouse *psmouse, int set_properties)
inline int alps_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENOSYS;
}
......
......@@ -317,7 +317,7 @@ static int report_tp_state(struct bcm5974 *dev, int size)
const struct tp_finger *f;
struct input_dev *input = dev->input;
int raw_p, raw_w, raw_x, raw_y, raw_n;
int ptest = 0, origin = 0, ibt = 0, nmin = 0, nmax = 0;
int ptest, origin, ibt = 0, nmin = 0, nmax = 0;
int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0)
......@@ -345,21 +345,22 @@ static int report_tp_state(struct bcm5974 *dev, int size)
/* set the integrated button if applicable */
if (c->tp_type == TYPE2)
ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
}
/* while tracking finger still valid, count all fingers */
if (ptest > PRESSURE_LOW && origin) {
abs_p = ptest;
abs_w = int2bound(&c->w, raw_w);
abs_x = int2bound(&c->x, raw_x - c->x.devmin);
abs_y = int2bound(&c->y, c->y.devmax - raw_y);
while (raw_n--) {
ptest = int2bound(&c->p, raw2int(f->force_major));
if (ptest > PRESSURE_LOW)
nmax++;
if (ptest > PRESSURE_HIGH)
nmin++;
f++;
/* while tracking finger still valid, count all fingers */
if (ptest > PRESSURE_LOW && origin) {
abs_p = ptest;
abs_w = int2bound(&c->w, raw_w);
abs_x = int2bound(&c->x, raw_x - c->x.devmin);
abs_y = int2bound(&c->y, c->y.devmax - raw_y);
while (raw_n--) {
ptest = int2bound(&c->p,
raw2int(f->force_major));
if (ptest > PRESSURE_LOW)
nmax++;
if (ptest > PRESSURE_HIGH)
nmin++;
f++;
}
}
}
......
......@@ -553,7 +553,7 @@ static struct attribute_group elantech_attr_group = {
/*
* Use magic knock to detect Elantech touchpad
*/
int elantech_detect(struct psmouse *psmouse, int set_properties)
int elantech_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[3];
......
......@@ -109,10 +109,10 @@ struct elantech_data {
};
#ifdef CONFIG_MOUSE_PS2_ELANTECH
int elantech_detect(struct psmouse *psmouse, int set_properties);
int elantech_detect(struct psmouse *psmouse, bool set_properties);
int elantech_init(struct psmouse *psmouse);
#else
static inline int elantech_detect(struct psmouse *psmouse, int set_properties)
static inline int elantech_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENOSYS;
}
......
......@@ -367,7 +367,36 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
}
__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
hgpk_show_powered, hgpk_set_powered, 0);
hgpk_show_powered, hgpk_set_powered, false);
static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,
void *data, char *buf)
{
return -EINVAL;
}
static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data,
const char *buf, size_t count)
{
struct hgpk_data *priv = psmouse->private;
unsigned long value;
int err;
err = strict_strtoul(buf, 10, &value);
if (err || value != 1)
return -EINVAL;
/*
* We queue work instead of doing recalibration right here
* to avoid adding locking to to hgpk_force_recalibrate()
* since workqueue provides serialization.
*/
psmouse_queue_work(psmouse, &priv->recalib_wq, 0);
return count;
}
__PSMOUSE_DEFINE_ATTR(recalibrate, S_IWUSR | S_IRUGO, NULL,
hgpk_trigger_recal_show, hgpk_trigger_recal, false);
static void hgpk_disconnect(struct psmouse *psmouse)
{
......@@ -375,6 +404,11 @@ static void hgpk_disconnect(struct psmouse *psmouse)
device_remove_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_powered.dattr);
if (psmouse->model >= HGPK_MODEL_C)
device_remove_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_recalibrate.dattr);
psmouse_reset(psmouse);
kfree(priv);
}
......@@ -423,10 +457,25 @@ static int hgpk_register(struct psmouse *psmouse)
err = device_create_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_powered.dattr);
if (err)
hgpk_err(psmouse, "Failed to create sysfs attribute\n");
if (err) {
hgpk_err(psmouse, "Failed creating 'powered' sysfs node\n");
return err;
}
return err;
/* C-series touchpads added the recalibrate command */
if (psmouse->model >= HGPK_MODEL_C) {
err = device_create_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_recalibrate.dattr);
if (err) {
hgpk_err(psmouse,
"Failed creating 'recalibrate' sysfs node\n");
device_remove_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_powered.dattr);
return err;
}
}
return 0;
}
int hgpk_init(struct psmouse *psmouse)
......@@ -440,7 +489,7 @@ int hgpk_init(struct psmouse *psmouse)
psmouse->private = priv;
priv->psmouse = psmouse;
priv->powered = 1;
priv->powered = true;
INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
err = psmouse_reset(psmouse);
......@@ -483,7 +532,7 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
return param[2];
}
int hgpk_detect(struct psmouse *psmouse, int set_properties)
int hgpk_detect(struct psmouse *psmouse, bool set_properties)
{
int version;
......
......@@ -15,7 +15,7 @@ enum hgpk_model_t {
struct hgpk_data {
struct psmouse *psmouse;
int powered;
bool powered;
int count, x_tally, y_tally; /* hardware workaround stuff */
unsigned long recalib_window;
struct delayed_work recalib_wq;
......@@ -33,10 +33,10 @@ struct hgpk_data {
dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#ifdef CONFIG_MOUSE_PS2_OLPC
int hgpk_detect(struct psmouse *psmouse, int set_properties);
int hgpk_detect(struct psmouse *psmouse, bool set_properties);
int hgpk_init(struct psmouse *psmouse);
#else
static inline int hgpk_detect(struct psmouse *psmouse, int set_properties)
static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENODEV;
}
......
This diff is collapsed.
......@@ -33,11 +33,11 @@ static int lifebook_set_serio_phys(const struct dmi_system_id *d)
return 0;
}
static unsigned char lifebook_use_6byte_proto;
static bool lifebook_use_6byte_proto;
static int lifebook_set_6byte_proto(const struct dmi_system_id *d)
{
lifebook_use_6byte_proto = 1;
lifebook_use_6byte_proto = true;
return 0;
}
......@@ -125,7 +125,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
struct input_dev *dev1 = psmouse->dev;
struct input_dev *dev2 = priv ? priv->dev2 : NULL;
unsigned char *packet = psmouse->packet;
int relative_packet = packet[0] & 0x08;
bool relative_packet = packet[0] & 0x08;
if (relative_packet || !lifebook_use_6byte_proto) {
if (psmouse->pktcnt != 3)
......@@ -242,7 +242,7 @@ static void lifebook_disconnect(struct psmouse *psmouse)
psmouse->private = NULL;
}
int lifebook_detect(struct psmouse *psmouse, int set_properties)
int lifebook_detect(struct psmouse *psmouse, bool set_properties)
{
if (!dmi_check_system(lifebook_dmi_table))
return -1;
......
......@@ -12,10 +12,10 @@
#define _LIFEBOOK_H
#ifdef CONFIG_MOUSE_PS2_LIFEBOOK
int lifebook_detect(struct psmouse *psmouse, int set_properties);
int lifebook_detect(struct psmouse *psmouse, bool set_properties);
int lifebook_init(struct psmouse *psmouse);
#else
inline int lifebook_detect(struct psmouse *psmouse, int set_properties)
inline int lifebook_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENOSYS;
}
......
......@@ -130,14 +130,11 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha
* 0 - disabled
*/
static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscroll)
static void ps2pp_set_smartscroll(struct psmouse *psmouse, bool smartscroll)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[4];
if (smartscroll > 1)
smartscroll = 1;
ps2pp_cmd(psmouse, param, 0x32);
param[0] = 0;
......@@ -149,12 +146,14 @@ static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscr
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
}
static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data, char *buf)
static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse,
void *data, char *buf)
{
return sprintf(buf, "%d\n", psmouse->smartscroll ? 1 : 0);
return sprintf(buf, "%d\n", psmouse->smartscroll);
}
static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count)
static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data,
const char *buf, size_t count)
{
unsigned long value;
......@@ -261,29 +260,29 @@ static const struct ps2pp_info *get_model_info(unsigned char model)
static void ps2pp_set_model_properties(struct psmouse *psmouse,
const struct ps2pp_info *model_info,
int using_ps2pp)
bool using_ps2pp)
{
struct input_dev *input_dev = psmouse->dev;
if (model_info->features & PS2PP_SIDE_BTN)
set_bit(BTN_SIDE, input_dev->keybit);
__set_bit(BTN_SIDE, input_dev->keybit);
if (model_info->features & PS2PP_EXTRA_BTN)
set_bit(BTN_EXTRA, input_dev->keybit);
__set_bit(BTN_EXTRA, input_dev->keybit);
if (model_info->features & PS2PP_TASK_BTN)
set_bit(BTN_TASK, input_dev->keybit);
__set_bit(BTN_TASK, input_dev->keybit);
if (model_info->features & PS2PP_NAV_BTN) {
set_bit(BTN_FORWARD, input_dev->keybit);
set_bit(BTN_BACK, input_dev->keybit);
__set_bit(BTN_FORWARD, input_dev->keybit);
__set_bit(BTN_BACK, input_dev->keybit);
}
if (model_info->features & PS2PP_WHEEL)
set_bit(REL_WHEEL, input_dev->relbit);
__set_bit(REL_WHEEL, input_dev->relbit);
if (model_info->features & PS2PP_HWHEEL)
set_bit(REL_HWHEEL, input_dev->relbit);
__set_bit(REL_HWHEEL, input_dev->relbit);
switch (model_info->kind) {
case PS2PP_KIND_WHEEL:
......@@ -321,13 +320,13 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
* that support it.
*/
int ps2pp_init(struct psmouse *psmouse, int set_properties)
int ps2pp_init(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[4];
unsigned char model, buttons;
const struct ps2pp_info *model_info;
int use_ps2pp = 0;
bool use_ps2pp = false;
int error;
param[0] = 0;
......@@ -364,7 +363,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
param[0] = 0;
if (!ps2_command(ps2dev, param, 0x13d1) &&
param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
use_ps2pp = 1;
use_ps2pp = true;
}
} else {
......@@ -376,8 +375,8 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
if ((param[0] & 0x78) == 0x48 &&
(param[1] & 0xf3) == 0xc2 &&
(param[2] & 0x03) == ((param[1] >> 2) & 3)) {
ps2pp_set_smartscroll(psmouse, psmouse->smartscroll);
use_ps2pp = 1;
ps2pp_set_smartscroll(psmouse, false);
use_ps2pp = true;
}
}
}
......@@ -406,7 +405,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
}
if (buttons < 3)
clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
__clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
if (model_info)
ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
......
......@@ -12,9 +12,9 @@
#define _LOGIPS2PP_H
#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
int ps2pp_init(struct psmouse *psmouse, int set_properties);
int ps2pp_init(struct psmouse *psmouse, bool set_properties);
#else
inline int ps2pp_init(struct psmouse *psmouse, int set_properties)
inline int ps2pp_init(struct psmouse *psmouse, bool set_properties)
{
return -ENOSYS;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -105,7 +105,7 @@ struct synaptics_data {
int scroll;
};
int synaptics_detect(struct psmouse *psmouse, int set_properties);
int synaptics_detect(struct psmouse *psmouse, bool set_properties);
int synaptics_init(struct psmouse *psmouse);
void synaptics_reset(struct psmouse *psmouse);
......
......@@ -67,7 +67,7 @@ static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse)
return PSMOUSE_FULL_PACKET;
}
int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
int touchkit_ps2_detect(struct psmouse *psmouse, bool set_properties)
{
struct input_dev *dev = psmouse->dev;
unsigned char param[3];
......@@ -86,7 +86,7 @@ int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
if (set_properties) {
dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
set_bit(BTN_TOUCH, dev->keybit);
__set_bit(BTN_TOUCH, dev->keybit);
input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0);
input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0);
......
This diff is collapsed.
......@@ -282,7 +282,7 @@ static int trackpoint_reconnect(struct psmouse *psmouse)
return 0;
}
int trackpoint_detect(struct psmouse *psmouse, int set_properties)
int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
{
struct trackpoint_data *priv;
struct ps2dev *ps2dev = &psmouse->ps2dev;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment