Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6

This commit is contained in:
Linus Torvalds 2005-10-28 13:09:47 -07:00
commit 84860bf064
244 changed files with 5575 additions and 5209 deletions

View File

@ -65,7 +65,7 @@ o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
o nfs-utils 1.0.5 # showmount --version
o procps 3.2.0 # ps --version
o oprofile 0.9 # oprofiled --version
o udev 058 # udevinfo -V
o udev 071 # udevinfo -V
Kernel compilation
==================

View File

@ -345,8 +345,7 @@ if (!retval) {
<programlisting>
static inline void skel_delete (struct usb_skel *dev)
{
if (dev->bulk_in_buffer != NULL)
kfree (dev->bulk_in_buffer);
kfree (dev->bulk_in_buffer);
if (dev->bulk_out_buffer != NULL)
usb_buffer_free (dev->udev, dev->bulk_out_size,
dev->bulk_out_buffer,

View File

@ -14,8 +14,8 @@ struct device_driver {
int (*probe) (struct device * dev);
int (*remove) (struct device * dev);
int (*suspend) (struct device * dev, pm_message_t state, u32 level);
int (*resume) (struct device * dev, u32 level);
int (*suspend) (struct device * dev, pm_message_t state);
int (*resume) (struct device * dev);
};
@ -194,69 +194,13 @@ device; i.e. anything in the device's driver_data field.
If the device is still present, it should quiesce the device and place
it into a supported low-power state.
int (*suspend) (struct device * dev, pm_message_t state, u32 level);
int (*suspend) (struct device * dev, pm_message_t state);
suspend is called to put the device in a low power state. There are
several stages to successfully suspending a device, which is denoted in
the @level parameter. Breaking the suspend transition into several
stages affords the platform flexibility in performing device power
management based on the requirements of the system and the
user-defined policy.
suspend is called to put the device in a low power state.
SUSPEND_NOTIFY notifies the device that a suspend transition is about
to happen. This happens on system power state transitions to verify
that all devices can successfully suspend.
int (*resume) (struct device * dev);
A driver may choose to fail on this call, which should cause the
entire suspend transition to fail. A driver should fail only if it
knows that the device will not be able to be resumed properly when the
system wakes up again. It could also fail if it somehow determines it
is in the middle of an operation too important to stop.
SUSPEND_DISABLE tells the device to stop I/O transactions. When it
stops transactions, or what it should do with unfinished transactions
is a policy of the driver. After this call, the driver should not
accept any other I/O requests.
SUSPEND_SAVE_STATE tells the device to save the context of the
hardware. This includes any bus-specific hardware state and
device-specific hardware state. A pointer to this saved state can be
stored in the device's saved_state field.
SUSPEND_POWER_DOWN tells the driver to place the device in the low
power state requested.
Whether suspend is called with a given level is a policy of the
platform. Some levels may be omitted; drivers must not assume the
reception of any level. However, all levels must be called in the
order above; i.e. notification will always come before disabling;
disabling the device will come before suspending the device.
All calls are made with interrupts enabled, except for the
SUSPEND_POWER_DOWN level.
int (*resume) (struct device * dev, u32 level);
Resume is used to bring a device back from a low power state. Like the
suspend transition, it happens in several stages.
RESUME_POWER_ON tells the driver to set the power state to the state
before the suspend call (The device could have already been in a low
power state before the suspend call to put in a lower power state).
RESUME_RESTORE_STATE tells the driver to restore the state saved by
the SUSPEND_SAVE_STATE suspend call.
RESUME_ENABLE tells the driver to start accepting I/O transactions
again. Depending on driver policy, the device may already have pending
I/O requests.
RESUME_POWER_ON is called with interrupts disabled. The other resume
levels are called with interrupts enabled.
As with the various suspend stages, the driver must not assume that
any other resume calls have been or will be made. Each call should be
self-contained and not dependent on any external state.
Resume is used to bring a device back from a low power state.
Attributes

View File

@ -350,7 +350,7 @@ When a driver is registered, the bus's list of devices is iterated
over. bus->match() is called for each device that is not already
claimed by a driver.
When a device is successfully bound to a device, device->driver is
When a device is successfully bound to a driver, device->driver is
set, the device is added to a per-driver list of devices, and a
symlink is created in the driver's sysfs directory that points to the
device's physical directory:

View File

@ -550,15 +550,12 @@ struct locomo_save_data {
u16 LCM_SPIMD;
};
static int locomo_suspend(struct device *dev, pm_message_t state, u32 level)
static int locomo_suspend(struct device *dev, pm_message_t state)
{
struct locomo *lchip = dev_get_drvdata(dev);
struct locomo_save_data *save;
unsigned long flags;
if (level != SUSPEND_DISABLE)
return 0;
save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL);
if (!save)
return -ENOMEM;
@ -597,16 +594,13 @@ static int locomo_suspend(struct device *dev, pm_message_t state, u32 level)
return 0;
}
static int locomo_resume(struct device *dev, u32 level)
static int locomo_resume(struct device *dev)
{
struct locomo *lchip = dev_get_drvdata(dev);
struct locomo_save_data *save;
unsigned long r;
unsigned long flags;
if (level != RESUME_ENABLE)
return 0;
save = (struct locomo_save_data *) dev->power.saved_state;
if (!save)
return 0;

View File

@ -801,7 +801,7 @@ struct sa1111_save_data {
#ifdef CONFIG_PM
static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
static int sa1111_suspend(struct device *dev, pm_message_t state)
{
struct sa1111 *sachip = dev_get_drvdata(dev);
struct sa1111_save_data *save;
@ -809,9 +809,6 @@ static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
unsigned int val;
void __iomem *base;
if (level != SUSPEND_DISABLE)
return 0;
save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL);
if (!save)
return -ENOMEM;
@ -856,23 +853,19 @@ static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
/*
* sa1111_resume - Restore the SA1111 device state.
* @dev: device to restore
* @level: resume level
*
* Restore the general state of the SA1111; clock control and
* interrupt controller. Other parts of the SA1111 must be
* restored by their respective drivers, and must be called
* via LDM after this function.
*/
static int sa1111_resume(struct device *dev, u32 level)
static int sa1111_resume(struct device *dev)
{
struct sa1111 *sachip = dev_get_drvdata(dev);
struct sa1111_save_data *save;
unsigned long flags, id;
void __iomem *base;
if (level != RESUME_ENABLE)
return 0;
save = (struct sa1111_save_data *)dev->power.saved_state;
if (!save)
return 0;

View File

@ -102,26 +102,24 @@ static void check_scoop_reg(struct scoop_dev *sdev)
}
#ifdef CONFIG_PM
static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level)
static int scoop_suspend(struct device *dev, pm_message_t state)
{
if (level == SUSPEND_POWER_DOWN) {
struct scoop_dev *sdev = dev_get_drvdata(dev);
struct scoop_dev *sdev = dev_get_drvdata(dev);
check_scoop_reg(sdev);
sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;
check_scoop_reg(sdev);
sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;
}
return 0;
}
static int scoop_resume(struct device *dev, uint32_t level)
static int scoop_resume(struct device *dev)
{
if (level == RESUME_POWER_ON) {
struct scoop_dev *sdev = dev_get_drvdata(dev);
struct scoop_dev *sdev = dev_get_drvdata(dev);
check_scoop_reg(sdev);
SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
check_scoop_reg(sdev);
SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
}
return 0;
}
#else

View File

@ -222,24 +222,22 @@ static int corgi_ssp_remove(struct device *dev)
return 0;
}
static int corgi_ssp_suspend(struct device *dev, pm_message_t state, u32 level)
static int corgi_ssp_suspend(struct device *dev, pm_message_t state)
{
if (level == SUSPEND_POWER_DOWN) {
ssp_flush(&corgi_ssp_dev);
ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
}
ssp_flush(&corgi_ssp_dev);
ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
return 0;
}
static int corgi_ssp_resume(struct device *dev, u32 level)
static int corgi_ssp_resume(struct device *dev)
{
if (level == RESUME_POWER_ON) {
GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */
GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
ssp_enable(&corgi_ssp_dev);
}
GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */
GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
ssp_enable(&corgi_ssp_dev);
return 0;
}

View File

@ -178,33 +178,27 @@ static int neponset_probe(struct device *dev)
/*
* LDM power management.
*/
static int neponset_suspend(struct device *dev, pm_message_t state, u32 level)
static int neponset_suspend(struct device *dev, pm_message_t state)
{
/*
* Save state.
*/
if (level == SUSPEND_SAVE_STATE ||
level == SUSPEND_DISABLE ||
level == SUSPEND_POWER_DOWN) {
if (!dev->power.saved_state)
dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
if (!dev->power.saved_state)
return -ENOMEM;
if (!dev->power.saved_state)
dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
if (!dev->power.saved_state)
return -ENOMEM;
*(unsigned int *)dev->power.saved_state = NCR_0;
}
*(unsigned int *)dev->power.saved_state = NCR_0;
return 0;
}
static int neponset_resume(struct device *dev, u32 level)
static int neponset_resume(struct device *dev)
{
if (level == RESUME_RESTORE_STATE || level == RESUME_ENABLE) {
if (dev->power.saved_state) {
NCR_0 = *(unsigned int *)dev->power.saved_state;
kfree(dev->power.saved_state);
dev->power.saved_state = NULL;
}
if (dev->power.saved_state) {
NCR_0 = *(unsigned int *)dev->power.saved_state;
kfree(dev->power.saved_state);
dev->power.saved_state = NULL;
}
return 0;

View File

@ -163,7 +163,7 @@ static int cpuid_class_device_create(int i)
int err = 0;
struct class_device *class_err;
class_err = class_device_create(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
class_err = class_device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
if (IS_ERR(class_err))
err = PTR_ERR(class_err);
return err;

View File

@ -246,7 +246,7 @@ static int msr_class_device_create(int i)
int err = 0;
struct class_device *class_err;
class_err = class_device_create(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
class_err = class_device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
if (IS_ERR(class_err))
err = PTR_ERR(class_err);
return err;

View File

@ -19,6 +19,8 @@
#include <linux/list.h>
#include <linux/module.h>
#include "base.h"
/* This is a private structure used to tie the classdev and the
* container .. it should never be visible outside this file */
struct internal_container {

View File

@ -1,3 +1,15 @@
/* initialisation functions */
extern int devices_init(void);
extern int buses_init(void);
extern int classes_init(void);
extern int firmware_init(void);
extern int platform_bus_init(void);
extern int system_bus_init(void);
extern int cpu_dev_init(void);
extern int attribute_container_init(void);
extern int bus_add_device(struct device * dev);
extern void bus_remove_device(struct device * dev);

View File

@ -99,7 +99,8 @@ struct class * class_get(struct class * cls)
void class_put(struct class * cls)
{
subsys_put(&cls->subsys);
if (cls)
subsys_put(&cls->subsys);
}
@ -165,14 +166,25 @@ void class_unregister(struct class * cls)
static void class_create_release(struct class *cls)
{
pr_debug("%s called for %s\n", __FUNCTION__, cls->name);
kfree(cls);
}
static void class_device_create_release(struct class_device *class_dev)
{
pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
kfree(class_dev);
}
/* needed to allow these devices to have parent class devices */
static int class_device_create_hotplug(struct class_device *class_dev,
char **envp, int num_envp,
char *buffer, int buffer_size)
{
pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
return 0;
}
/**
* class_create - create a struct class structure
* @owner: pointer to the module that is to "own" this struct class
@ -301,10 +313,12 @@ static void class_dev_release(struct kobject * kobj)
kfree(cd->devt_attr);
cd->devt_attr = NULL;
if (cls->release)
if (cd->release)
cd->release(cd);
else if (cls->release)
cls->release(cd);
else {
printk(KERN_ERR "Device class '%s' does not have a release() function, "
printk(KERN_ERR "Class Device '%s' does not have a release() function, "
"it is broken and must be fixed.\n",
cd->class_id);
WARN_ON(1);
@ -382,14 +396,18 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
buffer = &buffer[length];
buffer_size -= length;
if (class_dev->class->hotplug) {
/* have the bus specific function add its stuff */
retval = class_dev->class->hotplug (class_dev, envp, num_envp,
buffer, buffer_size);
if (retval) {
pr_debug ("%s - hotplug() returned %d\n",
__FUNCTION__, retval);
}
if (class_dev->hotplug) {
/* have the class device specific function add its stuff */
retval = class_dev->hotplug(class_dev, envp, num_envp,
buffer, buffer_size);
if (retval)
pr_debug("class_dev->hotplug() returned %d\n", retval);
} else if (class_dev->class->hotplug) {
/* have the class specific function add its stuff */
retval = class_dev->class->hotplug(class_dev, envp, num_envp,
buffer, buffer_size);
if (retval)
pr_debug("class->hotplug() returned %d\n", retval);
}
return retval;
@ -442,6 +460,13 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
return print_dev_t(buf, class_dev->devt);
}
static ssize_t store_uevent(struct class_device *class_dev,
const char *buf, size_t count)
{
kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
return count;
}
void class_device_initialize(struct class_device *class_dev)
{
kobj_set_kset_s(class_dev, class_obj_subsys);
@ -469,34 +494,45 @@ static char *make_class_name(struct class_device *class_dev)
int class_device_add(struct class_device *class_dev)
{
struct class * parent = NULL;
struct class_interface * class_intf;
struct class *parent_class = NULL;
struct class_device *parent_class_dev = NULL;
struct class_interface *class_intf;
char *class_name = NULL;
int error;
int error = -EINVAL;
class_dev = class_device_get(class_dev);
if (!class_dev)
return -EINVAL;
if (!strlen(class_dev->class_id)) {
error = -EINVAL;
if (!strlen(class_dev->class_id))
goto register_done;
}
parent = class_get(class_dev->class);
parent_class = class_get(class_dev->class);
if (!parent_class)
goto register_done;
parent_class_dev = class_device_get(class_dev->parent);
pr_debug("CLASS: registering class device: ID = '%s'\n",
class_dev->class_id);
/* first, register with generic layer. */
kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
if (parent)
class_dev->kobj.parent = &parent->subsys.kset.kobj;
if (parent_class_dev)
class_dev->kobj.parent = &parent_class_dev->kobj;
else
class_dev->kobj.parent = &parent_class->subsys.kset.kobj;
if ((error = kobject_add(&class_dev->kobj)))
error = kobject_add(&class_dev->kobj);
if (error)
goto register_done;
/* add the needed attributes to this device */
class_dev->uevent_attr.attr.name = "uevent";
class_dev->uevent_attr.attr.mode = S_IWUSR;
class_dev->uevent_attr.attr.owner = parent_class->owner;
class_dev->uevent_attr.store = store_uevent;
class_device_create_file(class_dev, &class_dev->uevent_attr);
if (MAJOR(class_dev->devt)) {
struct class_device_attribute *attr;
attr = kzalloc(sizeof(*attr), GFP_KERNEL);
@ -505,12 +541,10 @@ int class_device_add(struct class_device *class_dev)
kobject_del(&class_dev->kobj);
goto register_done;
}
attr->attr.name = "dev";
attr->attr.mode = S_IRUGO;
attr->attr.owner = parent->owner;
attr->attr.owner = parent_class->owner;
attr->show = show_dev;
attr->store = NULL;
class_device_create_file(class_dev, attr);
class_dev->devt_attr = attr;
}
@ -524,20 +558,23 @@ int class_device_add(struct class_device *class_dev)
class_name);
}
/* notify any interfaces this device is now here */
if (parent) {
down(&parent->sem);
list_add_tail(&class_dev->node, &parent->children);
list_for_each_entry(class_intf, &parent->interfaces, node)
if (class_intf->add)
class_intf->add(class_dev);
up(&parent->sem);
}
kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
/* notify any interfaces this device is now here */
if (parent_class) {
down(&parent_class->sem);
list_add_tail(&class_dev->node, &parent_class->children);
list_for_each_entry(class_intf, &parent_class->interfaces, node)
if (class_intf->add)
class_intf->add(class_dev, class_intf);
up(&parent_class->sem);
}
register_done:
if (error && parent)
class_put(parent);
if (error) {
class_put(parent_class);
class_device_put(parent_class_dev);
}
class_device_put(class_dev);
kfree(class_name);
return error;
@ -552,21 +589,28 @@ int class_device_register(struct class_device *class_dev)
/**
* class_device_create - creates a class device and registers it with sysfs
* @cs: pointer to the struct class that this device should be registered to.
* @parent: pointer to the parent struct class_device of this new device, if any.
* @dev: the dev_t for the char device to be added.
* @device: a pointer to a struct device that is assiociated with this class device.
* @fmt: string for the class device's name
*
* This function can be used by char device classes. A struct
* class_device will be created in sysfs, registered to the specified
* class. A "dev" file will be created, showing the dev_t for the
* device. The pointer to the struct class_device will be returned from
* the call. Any further sysfs files that might be required can be
* created using this pointer.
* class.
* A "dev" file will be created, showing the dev_t for the device, if
* the dev_t is not 0,0.
* If a pointer to a parent struct class_device is passed in, the newly
* created struct class_device will be a child of that device in sysfs.
* The pointer to the struct class_device will be returned from the
* call. Any further sysfs files that might be required can be created
* using this pointer.
*
* Note: the struct class passed to this function must have previously
* been created with a call to class_create().
*/
struct class_device *class_device_create(struct class *cls, dev_t devt,
struct class_device *class_device_create(struct class *cls,
struct class_device *parent,
dev_t devt,
struct device *device, char *fmt, ...)
{
va_list args;
@ -585,6 +629,9 @@ struct class_device *class_device_create(struct class *cls, dev_t devt,
class_dev->devt = devt;
class_dev->dev = device;
class_dev->class = cls;
class_dev->parent = parent;
class_dev->release = class_device_create_release;
class_dev->hotplug = class_device_create_hotplug;
va_start(args, fmt);
vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
@ -602,17 +649,18 @@ error:
void class_device_del(struct class_device *class_dev)
{
struct class * parent = class_dev->class;
struct class_interface * class_intf;
struct class *parent_class = class_dev->class;
struct class_device *parent_device = class_dev->parent;
struct class_interface *class_intf;
char *class_name = NULL;
if (parent) {
down(&parent->sem);
if (parent_class) {
down(&parent_class->sem);
list_del_init(&class_dev->node);
list_for_each_entry(class_intf, &parent->interfaces, node)
list_for_each_entry(class_intf, &parent_class->interfaces, node)
if (class_intf->remove)
class_intf->remove(class_dev);
up(&parent->sem);
class_intf->remove(class_dev, class_intf);
up(&parent_class->sem);
}
if (class_dev->dev) {
@ -620,6 +668,7 @@ void class_device_del(struct class_device *class_dev)
sysfs_remove_link(&class_dev->kobj, "device");
sysfs_remove_link(&class_dev->dev->kobj, class_name);
}
class_device_remove_file(class_dev, &class_dev->uevent_attr);
if (class_dev->devt_attr)
class_device_remove_file(class_dev, class_dev->devt_attr);
class_device_remove_attrs(class_dev);
@ -627,8 +676,8 @@ void class_device_del(struct class_device *class_dev)
kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
kobject_del(&class_dev->kobj);
if (parent)
class_put(parent);
class_device_put(parent_device);
class_put(parent_class);
kfree(class_name);
}
@ -708,7 +757,8 @@ struct class_device * class_device_get(struct class_device *class_dev)
void class_device_put(struct class_device *class_dev)
{
kobject_put(&class_dev->kobj);
if (class_dev)
kobject_put(&class_dev->kobj);
}
@ -728,7 +778,7 @@ int class_interface_register(struct class_interface *class_intf)
list_add_tail(&class_intf->node, &parent->interfaces);
if (class_intf->add) {
list_for_each_entry(class_dev, &parent->children, node)
class_intf->add(class_dev);
class_intf->add(class_dev, class_intf);
}
up(&parent->sem);
@ -747,7 +797,7 @@ void class_interface_unregister(struct class_interface *class_intf)
list_del_init(&class_intf->node);
if (class_intf->remove) {
list_for_each_entry(class_dev, &parent->children, node)
class_intf->remove(class_dev);
class_intf->remove(class_dev, class_intf);
}
up(&parent->sem);

View File

@ -154,6 +154,13 @@ static struct kset_hotplug_ops device_hotplug_ops = {
.hotplug = dev_hotplug,
};
static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
kobject_hotplug(&dev->kobj, KOBJ_ADD);
return count;
}
/**
* device_subsys - structure to be registered with kobject core.
*/
@ -225,6 +232,7 @@ void device_initialize(struct device *dev)
klist_children_put);
INIT_LIST_HEAD(&dev->dma_pools);
init_MUTEX(&dev->sem);
device_init_wakeup(dev, 0);
}
/**
@ -258,6 +266,14 @@ int device_add(struct device *dev)
if ((error = kobject_add(&dev->kobj)))
goto Error;
dev->uevent_attr.attr.name = "uevent";
dev->uevent_attr.attr.mode = S_IWUSR;
if (dev->driver)
dev->uevent_attr.attr.owner = dev->driver->owner;
dev->uevent_attr.store = store_uevent;
device_create_file(dev, &dev->uevent_attr);
kobject_hotplug(&dev->kobj, KOBJ_ADD);
if ((error = device_pm_add(dev)))
goto PMError;
@ -349,6 +365,7 @@ void device_del(struct device * dev)
if (parent)
klist_del(&dev->knode_parent);
device_remove_file(dev, &dev->uevent_attr);
/* Notify the platform of the removal, in case they
* need to do anything...
@ -390,11 +407,11 @@ static struct device * next_device(struct klist_iter * i)
/**
* device_for_each_child - device child iterator.
* @dev: parent struct device.
* @parent: parent struct device.
* @data: data for the callback.
* @fn: function to be called for each device.
*
* Iterate over @dev's child devices, and call @fn for each,
* Iterate over @parent's child devices, and call @fn for each,
* passing it @data.
*
* We check the return of @fn each time. If it returns anything

View File

@ -9,6 +9,7 @@
#include <linux/topology.h>
#include <linux/device.h>
#include "base.h"
struct sysdev_class cpu_sysdev_class = {
set_kset_name("cpu"),

View File

@ -28,6 +28,7 @@ static struct device * next_device(struct klist_iter * i)
/**
* driver_for_each_device - Iterator for devices bound to a driver.
* @drv: Driver we're iterating.
* @start: Device to begin with
* @data: Data to pass to the callback.
* @fn: Function to call for each device.
*
@ -57,7 +58,7 @@ EXPORT_SYMBOL_GPL(driver_for_each_device);
/**
* driver_find_device - device iterator for locating a particular device.
* @driver: The device's driver
* @drv: The device's driver
* @start: Device to begin with
* @data: Data to pass to match function
* @match: Callback function to check device

View File

@ -11,6 +11,9 @@
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include "base.h"
static decl_subsys(firmware, NULL, NULL);

View File

@ -10,14 +10,8 @@
#include <linux/device.h>
#include <linux/init.h>
extern int devices_init(void);
extern int buses_init(void);
extern int classes_init(void);
extern int firmware_init(void);
extern int platform_bus_init(void);
extern int system_bus_init(void);
extern int cpu_dev_init(void);
extern int attribute_container_init(void);
#include "base.h"
/**
* driver_init - initialize driver model.
*

View File

@ -17,6 +17,8 @@
#include <linux/bootmem.h>
#include <linux/err.h>
#include "base.h"
struct device platform_bus = {
.bus_id = "platform",
};
@ -279,13 +281,9 @@ static int platform_suspend(struct device * dev, pm_message_t state)
{
int ret = 0;
if (dev->driver && dev->driver->suspend) {
ret = dev->driver->suspend(dev, state, SUSPEND_DISABLE);
if (ret == 0)
ret = dev->driver->suspend(dev, state, SUSPEND_SAVE_STATE);
if (ret == 0)
ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
}
if (dev->driver && dev->driver->suspend)
ret = dev->driver->suspend(dev, state);
return ret;
}
@ -293,13 +291,9 @@ static int platform_resume(struct device * dev)
{
int ret = 0;
if (dev->driver && dev->driver->resume) {
ret = dev->driver->resume(dev, RESUME_POWER_ON);
if (ret == 0)
ret = dev->driver->resume(dev, RESUME_RESTORE_STATE);
if (ret == 0)
ret = dev->driver->resume(dev, RESUME_ENABLE);
}
if (dev->driver && dev->driver->resume)
ret = dev->driver->resume(dev);
return ret;
}

View File

@ -48,8 +48,81 @@ static ssize_t state_store(struct device * dev, struct device_attribute *attr, c
static DEVICE_ATTR(state, 0644, state_show, state_store);
/*
* wakeup - Report/change current wakeup option for device
*
* Some devices support "wakeup" events, which are hardware signals
* used to activate devices from suspended or low power states. Such
* devices have one of three values for the sysfs power/wakeup file:
*
* + "enabled\n" to issue the events;
* + "disabled\n" not to do so; or
* + "\n" for temporary or permanent inability to issue wakeup.
*
* (For example, unconfigured USB devices can't issue wakeups.)
*
* Familiar examples of devices that can issue wakeup events include
* keyboards and mice (both PS2 and USB styles), power buttons, modems,
* "Wake-On-LAN" Ethernet links, GPIO lines, and more. Some events
* will wake the entire system from a suspend state; others may just
* wake up the device (if the system as a whole is already active).
* Some wakeup events use normal IRQ lines; other use special out
* of band signaling.
*
* It is the responsibility of device drivers to enable (or disable)
* wakeup signaling as part of changing device power states, respecting
* the policy choices provided through the driver model.
*
* Devices may not be able to generate wakeup events from all power
* states. Also, the events may be ignored in some configurations;
* for example, they might need help from other devices that aren't
* active, or which may have wakeup disabled. Some drivers rely on
* wakeup events internally (unless they are disabled), keeping
* their hardware in low power modes whenever they're unused. This
* saves runtime power, without requiring system-wide sleep states.
*/
static const char enabled[] = "enabled";
static const char disabled[] = "disabled";
static ssize_t
wake_show(struct device * dev, struct device_attribute *attr, char * buf)
{
return sprintf(buf, "%s\n", device_can_wakeup(dev)
? (device_may_wakeup(dev) ? enabled : disabled)
: "");
}
static ssize_t
wake_store(struct device * dev, struct device_attribute *attr,
const char * buf, size_t n)
{
char *cp;
int len = n;
if (!device_can_wakeup(dev))
return -EINVAL;
cp = memchr(buf, '\n', n);
if (cp)
len = cp - buf;
if (len == sizeof enabled - 1
&& strncmp(buf, enabled, sizeof enabled - 1) == 0)
device_set_wakeup_enable(dev, 1);
else if (len == sizeof disabled - 1
&& strncmp(buf, disabled, sizeof disabled - 1) == 0)
device_set_wakeup_enable(dev, 0);
else
return -EINVAL;
return n;
}
static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
static struct attribute * power_attrs[] = {
&dev_attr_state.attr,
&dev_attr_wakeup.attr,
NULL,
};
static struct attribute_group pm_attr_group = {

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
#define VERSION "12"
#define VERSION "14"
#define AOE_MAJOR 152
#define DEVICE_NAME "aoe"

View File

@ -224,7 +224,7 @@ aoechr_init(void)
return PTR_ERR(aoe_class);
}
for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
class_device_create(aoe_class,
class_device_create(aoe_class, NULL,
MKDEV(AOE_MAJOR, chardevs[i].minor),
NULL, chardevs[i].name);

View File

@ -8,6 +8,7 @@
#include <linux/blkdev.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <asm/unaligned.h>
#include "aoe.h"
#define TIMERTICK (HZ / 10)
@ -311,16 +312,16 @@ ataid_complete(struct aoedev *d, unsigned char *id)
u16 n;
/* word 83: command set supported */
n = le16_to_cpup((__le16 *) &id[83<<1]);
n = le16_to_cpu(get_unaligned((__le16 *) &id[83<<1]));
/* word 86: command set/feature enabled */
n |= le16_to_cpup((__le16 *) &id[86<<1]);
n |= le16_to_cpu(get_unaligned((__le16 *) &id[86<<1]));
if (n & (1<<10)) { /* bit 10: LBA 48 */
d->flags |= DEVFL_EXT;
/* word 100: number lba48 sectors */
ssize = le64_to_cpup((__le64 *) &id[100<<1]);
ssize = le64_to_cpu(get_unaligned((__le64 *) &id[100<<1]));
/* set as in ide-disk.c:init_idedisk_capacity */
d->geo.cylinders = ssize;
@ -331,12 +332,12 @@ ataid_complete(struct aoedev *d, unsigned char *id)
d->flags &= ~DEVFL_EXT;
/* number lba28 sectors */
ssize = le32_to_cpup((__le32 *) &id[60<<1]);
ssize = le32_to_cpu(get_unaligned((__le32 *) &id[60<<1]));
/* NOTE: obsolete in ATA 6 */
d->geo.cylinders = le16_to_cpup((__le16 *) &id[54<<1]);
d->geo.heads = le16_to_cpup((__le16 *) &id[55<<1]);
d->geo.sectors = le16_to_cpup((__le16 *) &id[56<<1]);
d->geo.cylinders = le16_to_cpu(get_unaligned((__le16 *) &id[54<<1]));
d->geo.heads = le16_to_cpu(get_unaligned((__le16 *) &id[55<<1]));
d->geo.sectors = le16_to_cpu(get_unaligned((__le16 *) &id[56<<1]));
}
d->ssize = ssize;
d->geo.start = 0;

View File

@ -337,10 +337,30 @@ static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
return ret;
}
static ssize_t disk_attr_store(struct kobject * kobj, struct attribute * attr,
const char *page, size_t count)
{
struct gendisk *disk = to_disk(kobj);
struct disk_attribute *disk_attr =
container_of(attr,struct disk_attribute,attr);
ssize_t ret = 0;
if (disk_attr->store)
ret = disk_attr->store(disk, page, count);
return ret;
}
static struct sysfs_ops disk_sysfs_ops = {
.show = &disk_attr_show,
.store = &disk_attr_store,
};
static ssize_t disk_uevent_store(struct gendisk * disk,
const char *buf, size_t count)
{
kobject_hotplug(&disk->kobj, KOBJ_ADD);
return count;
}
static ssize_t disk_dev_read(struct gendisk * disk, char *page)
{
dev_t base = MKDEV(disk->major, disk->first_minor);
@ -382,6 +402,10 @@ static ssize_t disk_stats_read(struct gendisk * disk, char *page)
jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
}
static struct disk_attribute disk_attr_uevent = {
.attr = {.name = "uevent", .mode = S_IWUSR },
.store = disk_uevent_store
};
static struct disk_attribute disk_attr_dev = {
.attr = {.name = "dev", .mode = S_IRUGO },
.show = disk_dev_read
@ -404,6 +428,7 @@ static struct disk_attribute disk_attr_stat = {
};
static struct attribute * default_attrs[] = {
&disk_attr_uevent.attr,
&disk_attr_dev.attr,
&disk_attr_range.attr,
&disk_attr_removable.attr,

View File

@ -674,7 +674,7 @@ static int __init pg_init(void)
for (unit = 0; unit < PG_UNITS; unit++) {
struct pg *dev = &devices[unit];
if (dev->present) {
class_device_create(pg_class, MKDEV(major, unit),
class_device_create(pg_class, NULL, MKDEV(major, unit),
NULL, "pg%u", unit);
err = devfs_mk_cdev(MKDEV(major, unit),
S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",

View File

@ -971,7 +971,7 @@ static int __init pt_init(void)
devfs_mk_dir("pt");
for (unit = 0; unit < PT_UNITS; unit++)
if (pt[unit].present) {
class_device_create(pt_class, MKDEV(major, unit),
class_device_create(pt_class, NULL, MKDEV(major, unit),
NULL, "pt%d", unit);
err = devfs_mk_cdev(MKDEV(major, unit),
S_IFCHR | S_IRUSR | S_IWUSR,
@ -980,7 +980,7 @@ static int __init pt_init(void)
class_device_destroy(pt_class, MKDEV(major, unit));
goto out_class;
}
class_device_create(pt_class, MKDEV(major, unit + 128),
class_device_create(pt_class, NULL, MKDEV(major, unit + 128),
NULL, "pt%dn", unit);
err = devfs_mk_cdev(MKDEV(major, unit + 128),
S_IFCHR | S_IRUSR | S_IWUSR,

View File

@ -515,7 +515,7 @@ static int __init dsp56k_init_driver(void)
err = PTR_ERR(dsp56k_class);
goto out_chrdev;
}
class_device_create(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0),
S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k");

View File

@ -331,27 +331,27 @@ KERN_INFO
zft_class = class_create(THIS_MODULE, "zft");
for (i = 0; i < 4; i++) {
class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i),
S_IFCHR | S_IRUSR | S_IWUSR,
"qft%i", i);
class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4),
S_IFCHR | S_IRUSR | S_IWUSR,
"nqft%i", i);
class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16),
S_IFCHR | S_IRUSR | S_IWUSR,
"zqft%i", i);
class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20),
S_IFCHR | S_IRUSR | S_IWUSR,
"nzqft%i", i);
class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32),
S_IFCHR | S_IRUSR | S_IWUSR,
"rawqft%i", i);
class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36),
S_IFCHR | S_IRUSR | S_IWUSR,
"nrawqft%i", i);

View File

@ -721,8 +721,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
}
if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
4 * i), NULL, "ipl%d", i);
class_device_create(ip2_class, NULL,
MKDEV(IP2_IPL_MAJOR, 4 * i),
NULL, "ipl%d", i);
err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
"ip2/ipl%d", i);
@ -732,8 +733,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
goto out_class;
}
class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
4 * i + 1), NULL, "stat%d", i);
class_device_create(ip2_class, NULL,
MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
NULL, "stat%d", i);
err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
"ip2/stat%d", i);

View File

@ -798,7 +798,7 @@ static void ipmi_new_smi(int if_num)
devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
"ipmidev/%d", if_num);
class_device_create(ipmi_class, dev, NULL, "ipmi%d", if_num);
class_device_create(ipmi_class, NULL, dev, NULL, "ipmi%d", if_num);
}
static void ipmi_smi_gone(int if_num)

View File

@ -5246,7 +5246,8 @@ int __init stli_init(void)
devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
S_IFCHR | S_IRUSR | S_IWUSR,
"staliomem/%d", i);
class_device_create(istallion_class, MKDEV(STL_SIOMEMMAJOR, i),
class_device_create(istallion_class, NULL,
MKDEV(STL_SIOMEMMAJOR, i),
NULL, "staliomem%d", i);
}

View File

@ -805,7 +805,7 @@ static int lp_register(int nr, struct parport *port)
if (reset)
lp_reset(nr);
class_device_create(lp_class, MKDEV(LP_MAJOR, nr), NULL,
class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL,
"lp%d", nr);
devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO,
"printers/%d", nr);

View File

@ -920,7 +920,8 @@ static int __init chr_dev_init(void)
mem_class = class_create(THIS_MODULE, "mem");
for (i = 0; i < ARRAY_SIZE(devlist); i++) {
class_device_create(mem_class, MKDEV(MEM_MAJOR, devlist[i].minor),
class_device_create(mem_class, NULL,
MKDEV(MEM_MAJOR, devlist[i].minor),
NULL, devlist[i].name);
devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor),
S_IFCHR | devlist[i].mode, devlist[i].name);

View File

@ -234,7 +234,7 @@ int misc_register(struct miscdevice * misc)
}
dev = MKDEV(MISC_MAJOR, misc->minor);
misc->class = class_device_create(misc_class, dev, misc->dev,
misc->class = class_device_create(misc_class, NULL, dev, misc->dev,
"%s", misc->name);
if (IS_ERR(misc->class)) {
err = PTR_ERR(misc->class);

View File

@ -752,7 +752,7 @@ static struct file_operations pp_fops = {
static void pp_attach(struct parport *port)
{
class_device_create(ppdev_class, MKDEV(PP_MAJOR, port->number),
class_device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number),
NULL, "parport%d", port->number);
}

View File

@ -128,7 +128,7 @@ raw_ioctl(struct inode *inode, struct file *filp,
static void bind_device(struct raw_config_request *rq)
{
class_device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor));
class_device_create(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor),
class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor),
NULL, "raw%d", rq->raw_minor);
}
@ -307,7 +307,7 @@ static int __init raw_init(void)
unregister_chrdev_region(dev, MAX_RAW_MINORS);
goto error;
}
class_device_create(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
S_IFCHR | S_IRUGO | S_IWUGO,

View File

@ -519,30 +519,28 @@ static struct timespec s3c2410_rtc_delta;
static int ticnt_save;
static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state, u32 level)
static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state)
{
struct rtc_time tm;
struct timespec time;
time.tv_nsec = 0;
if (level == SUSPEND_POWER_DOWN) {
/* save TICNT for anyone using periodic interrupts */
/* save TICNT for anyone using periodic interrupts */
ticnt_save = readb(S3C2410_TICNT);
ticnt_save = readb(S3C2410_TICNT);
/* calculate time delta for suspend */
/* calculate time delta for suspend */
s3c2410_rtc_gettime(&tm);
rtc_tm_to_time(&tm, &time.tv_sec);
save_time_delta(&s3c2410_rtc_delta, &time);
s3c2410_rtc_enable(dev, 0);
}
s3c2410_rtc_gettime(&tm);
rtc_tm_to_time(&tm, &time.tv_sec);
save_time_delta(&s3c2410_rtc_delta, &time);
s3c2410_rtc_enable(dev, 0);
return 0;
}
static int s3c2410_rtc_resume(struct device *dev, u32 level)
static int s3c2410_rtc_resume(struct device *dev)
{
struct rtc_time tm;
struct timespec time;

View File

@ -437,7 +437,7 @@ scdrv_init(void)
continue;
}
class_device_create(snsc_class, dev, NULL,
class_device_create(snsc_class, NULL, dev, NULL,
"%s", devname);
ia64_sn_irtr_intr_enable(scd->scd_nasid,

View File

@ -424,10 +424,6 @@ static struct sonypi_eventtypes {
#define SONYPI_BUF_SIZE 128
/* The name of the devices for the input device drivers */
#define SONYPI_JOG_INPUTNAME "Sony Vaio Jogdial"
#define SONYPI_KEY_INPUTNAME "Sony Vaio Keys"
/* Correspondance table between sonypi events and input layer events */
static struct {
int sonypiev;
@ -490,8 +486,8 @@ static struct sonypi_device {
struct fasync_struct *fifo_async;
int open_count;
int model;
struct input_dev input_jog_dev;
struct input_dev input_key_dev;
struct input_dev *input_jog_dev;
struct input_dev *input_key_dev;
struct work_struct input_work;
struct kfifo *input_fifo;
spinlock_t input_fifo_lock;
@ -779,8 +775,8 @@ static void input_keyrelease(void *data)
static void sonypi_report_input_event(u8 event)
{
struct input_dev *jog_dev = &sonypi_device.input_jog_dev;
struct input_dev *key_dev = &sonypi_device.input_key_dev;
struct input_dev *jog_dev = sonypi_device.input_jog_dev;
struct input_dev *key_dev = sonypi_device.input_key_dev;
struct sonypi_keypress kp = { NULL };
int i;
@ -1171,19 +1167,17 @@ static int sonypi_disable(void)
#ifdef CONFIG_PM
static int old_camera_power;
static int sonypi_suspend(struct device *dev, pm_message_t state, u32 level)
static int sonypi_suspend(struct device *dev, pm_message_t state)
{
if (level == SUSPEND_DISABLE) {
old_camera_power = sonypi_device.camera_power;
sonypi_disable();
}
old_camera_power = sonypi_device.camera_power;
sonypi_disable();
return 0;
}
static int sonypi_resume(struct device *dev, u32 level)
static int sonypi_resume(struct device *dev)
{
if (level == RESUME_ENABLE)
sonypi_enable(old_camera_power);
sonypi_enable(old_camera_power);
return 0;
}
#endif
@ -1203,6 +1197,47 @@ static struct device_driver sonypi_driver = {
.shutdown = sonypi_shutdown,
};
static int __devinit sonypi_create_input_devices(void)
{
struct input_dev *jog_dev;
struct input_dev *key_dev;
int i;
sonypi_device.input_jog_dev = jog_dev = input_allocate_device();
if (!jog_dev)
return -ENOMEM;
jog_dev->name = "Sony Vaio Jogdial";
jog_dev->id.bustype = BUS_ISA;
jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE);
jog_dev->relbit[0] = BIT(REL_WHEEL);
sonypi_device.input_key_dev = key_dev = input_allocate_device();
if (!key_dev) {
input_free_device(jog_dev);
sonypi_device.input_jog_dev = NULL;
return -ENOMEM;
}
key_dev->name = "Sony Vaio Keys";
key_dev->id.bustype = BUS_ISA;
key_dev->id.vendor = PCI_VENDOR_ID_SONY;
/* Initialize the Input Drivers: special keys */
key_dev->evbit[0] = BIT(EV_KEY);
for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
if (sonypi_inputkeys[i].inputev)
set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
input_register_device(jog_dev);
input_register_device(key_dev);
return 0;
}
static int __devinit sonypi_probe(void)
{
int i, ret;
@ -1298,34 +1333,10 @@ static int __devinit sonypi_probe(void)
}
if (useinput) {
/* Initialize the Input Drivers: jogdial */
int i;
sonypi_device.input_jog_dev.evbit[0] =
BIT(EV_KEY) | BIT(EV_REL);
sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] =
BIT(BTN_MIDDLE);
sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL);
sonypi_device.input_jog_dev.name = SONYPI_JOG_INPUTNAME;
sonypi_device.input_jog_dev.id.bustype = BUS_ISA;
sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY;
input_register_device(&sonypi_device.input_jog_dev);
printk(KERN_INFO "%s input method installed.\n",
sonypi_device.input_jog_dev.name);
/* Initialize the Input Drivers: special keys */
sonypi_device.input_key_dev.evbit[0] = BIT(EV_KEY);
for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
if (sonypi_inputkeys[i].inputev)
set_bit(sonypi_inputkeys[i].inputev,
sonypi_device.input_key_dev.keybit);
sonypi_device.input_key_dev.name = SONYPI_KEY_INPUTNAME;
sonypi_device.input_key_dev.id.bustype = BUS_ISA;
sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY;
input_register_device(&sonypi_device.input_key_dev);
printk(KERN_INFO "%s input method installed.\n",
sonypi_device.input_key_dev.name);
ret = sonypi_create_input_devices();
if (ret)
goto out_inputdevices;
spin_lock_init(&sonypi_device.input_fifo_lock);
sonypi_device.input_fifo =
@ -1375,8 +1386,9 @@ static int __devinit sonypi_probe(void)
out_platformdev:
kfifo_free(sonypi_device.input_fifo);
out_infifo:
input_unregister_device(&sonypi_device.input_key_dev);
input_unregister_device(&sonypi_device.input_jog_dev);
input_unregister_device(sonypi_device.input_key_dev);
input_unregister_device(sonypi_device.input_jog_dev);
out_inputdevices:
free_irq(sonypi_device.irq, sonypi_irq);
out_reqirq:
release_region(sonypi_device.ioport1, sonypi_device.region_size);
@ -1402,8 +1414,8 @@ static void __devexit sonypi_remove(void)
platform_device_unregister(sonypi_device.pdev);
if (useinput) {
input_unregister_device(&sonypi_device.input_key_dev);
input_unregister_device(&sonypi_device.input_jog_dev);
input_unregister_device(sonypi_device.input_key_dev);
input_unregister_device(sonypi_device.input_jog_dev);
kfifo_free(sonypi_device.input_fifo);
}

View File

@ -3095,7 +3095,9 @@ static int __init stl_init(void)
devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
S_IFCHR|S_IRUSR|S_IWUSR,
"staliomem/%d", i);
class_device_create(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i);
class_device_create(stallion_class, NULL,
MKDEV(STL_SIOMEMMAJOR, i), NULL,
"staliomem%d", i);
}
stl_serial->owner = THIS_MODULE;

View File

@ -436,7 +436,7 @@ tipar_register(int nr, struct parport *port)
goto out;
}
class_device_create(tipar_class, MKDEV(TIPAR_MAJOR,
class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR,
TIPAR_MINOR + nr), NULL, "par%d", nr);
/* Use devfs, tree: /dev/ticables/par/[0..2] */
err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),

View File

@ -2728,7 +2728,7 @@ void tty_register_device(struct tty_driver *driver, unsigned index,
pty_line_name(driver, index, name);
else
tty_line_name(driver, index, name);
class_device_create(tty_class, dev, device, name);
class_device_create(tty_class, NULL, dev, device, "%s", name);
}
/**
@ -2983,14 +2983,14 @@ static int __init tty_init(void)
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
panic("Couldn't register /dev/tty driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
cdev_init(&console_cdev, &console_fops);
if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
panic("Couldn't register /dev/console driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
#ifdef CONFIG_UNIX98_PTYS
cdev_init(&ptmx_cdev, &ptmx_fops);
@ -2998,7 +2998,7 @@ static int __init tty_init(void)
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
panic("Couldn't register /dev/ptmx driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
#endif
#ifdef CONFIG_VT
@ -3007,7 +3007,7 @@ static int __init tty_init(void)
register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
panic("Couldn't register /dev/tty0 driver\n");
devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
class_device_create(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
vty_init();
#endif

View File

@ -484,8 +484,10 @@ void vcs_make_devfs(struct tty_struct *tty)
devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129),
S_IFCHR|S_IRUSR|S_IWUSR,
"vcc/a%u", tty->index + 1);
class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1);
class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1);
class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
NULL, "vcs%u", tty->index + 1);
class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
NULL, "vcsa%u", tty->index + 1);
}
void vcs_remove_devfs(struct tty_struct *tty)
{
@ -503,7 +505,7 @@ int __init vcs_init(void)
devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0");
devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0");
class_device_create(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
class_device_create(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
return 0;
}

View File

@ -956,9 +956,9 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
state[i].cur_part = 0;
for (j = 0; j < MAX_PARTITIONS; ++j)
state[i].part_stat_rwi[j] = VIOT_IDLE;
class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL,
class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL,
"iseries!vt%d", i);
class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80),
class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
NULL, "iseries!nvt%d", i);
devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR,
"iseries/vt%d", i);

View File

@ -464,32 +464,28 @@ static void s3c2410wdt_shutdown(struct device *dev)
static unsigned long wtcon_save;
static unsigned long wtdat_save;
static int s3c2410wdt_suspend(struct device *dev, pm_message_t state, u32 level)
static int s3c2410wdt_suspend(struct device *dev, pm_message_t state)
{
if (level == SUSPEND_POWER_DOWN) {
/* Save watchdog state, and turn it off. */
wtcon_save = readl(wdt_base + S3C2410_WTCON);
wtdat_save = readl(wdt_base + S3C2410_WTDAT);
/* Save watchdog state, and turn it off. */
wtcon_save = readl(wdt_base + S3C2410_WTCON);
wtdat_save = readl(wdt_base + S3C2410_WTDAT);
/* Note that WTCNT doesn't need to be saved. */
s3c2410wdt_stop();
}
/* Note that WTCNT doesn't need to be saved. */
s3c2410wdt_stop();
return 0;
}
static int s3c2410wdt_resume(struct device *dev, u32 level)
static int s3c2410wdt_resume(struct device *dev)
{
if (level == RESUME_POWER_ON) {
/* Restore watchdog state. */
/* Restore watchdog state. */
writel(wtdat_save, wdt_base + S3C2410_WTDAT);
writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */
writel(wtcon_save, wdt_base + S3C2410_WTCON);
writel(wtdat_save, wdt_base + S3C2410_WTDAT);
writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */
writel(wtcon_save, wdt_base + S3C2410_WTCON);
printk(KERN_INFO PFX "watchdog %sabled\n",
(wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
}
printk(KERN_INFO PFX "watchdog %sabled\n",
(wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
return 0;
}

View File

@ -296,11 +296,9 @@ static int hdaps_probe(struct device *dev)
return 0;
}
static int hdaps_resume(struct device *dev, u32 level)
static int hdaps_resume(struct device *dev)
{
if (level == RESUME_ENABLE)
return hdaps_device_init();
return 0;
return hdaps_device_init();
}
static struct device_driver hdaps_driver = {

View File

@ -45,7 +45,7 @@ struct class_device *hwmon_device_register(struct device *dev)
return ERR_PTR(-ENOMEM);
id = id & MAX_ID_MASK;
cdev = class_device_create(hwmon_class, MKDEV(0,0), dev,
cdev = class_device_create(hwmon_class, NULL, MKDEV(0,0), dev,
HWMON_ID_FORMAT, id);
if (IS_ERR(cdev))

View File

@ -879,14 +879,12 @@ static int s3c24xx_i2c_remove(struct device *dev)
}
#ifdef CONFIG_PM
static int s3c24xx_i2c_resume(struct device *dev, u32 level)
static int s3c24xx_i2c_resume(struct device *dev)
{
struct s3c24xx_i2c *i2c = dev_get_drvdata(dev);
if (i2c != NULL && level == RESUME_ENABLE) {
dev_dbg(dev, "resume: level %d\n", level);
if (i2c != NULL)
s3c24xx_i2c_init(i2c);
}
return 0;
}

View File

@ -48,7 +48,7 @@ static int i2c_bus_suspend(struct device * dev, pm_message_t state)
int rc = 0;
if (dev->driver && dev->driver->suspend)
rc = dev->driver->suspend(dev,state,0);
rc = dev->driver->suspend(dev, state);
return rc;
}
@ -57,7 +57,7 @@ static int i2c_bus_resume(struct device * dev)
int rc = 0;
if (dev->driver && dev->driver->resume)
rc = dev->driver->resume(dev,0);
rc = dev->driver->resume(dev);
return rc;
}

View File

@ -1013,6 +1013,8 @@ typedef struct ide_tape_obj {
static DECLARE_MUTEX(idetape_ref_sem);
static struct class *idetape_sysfs_class;
#define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref)
#define ide_tape_g(disk) \
@ -4704,6 +4706,10 @@ static void ide_tape_release(struct kref *kref)
drive->dsc_overlap = 0;
drive->driver_data = NULL;
class_device_destroy(idetape_sysfs_class,
MKDEV(IDETAPE_MAJOR, tape->minor));
class_device_destroy(idetape_sysfs_class,
MKDEV(IDETAPE_MAJOR, tape->minor + 128));
devfs_remove("%s/mt", drive->devfs_name);
devfs_remove("%s/mtn", drive->devfs_name);
devfs_unregister_tape(g->number);
@ -4878,6 +4884,11 @@ static int ide_tape_probe(struct device *dev)
idetape_setup(drive, tape, minor);
class_device_create(idetape_sysfs_class, NULL,
MKDEV(IDETAPE_MAJOR, minor), dev, "%s", tape->name);
class_device_create(idetape_sysfs_class, NULL,
MKDEV(IDETAPE_MAJOR, minor + 128), dev, "n%s", tape->name);
devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor),
S_IFCHR | S_IRUGO | S_IWUGO,
"%s/mt", drive->devfs_name);
@ -4903,6 +4914,7 @@ MODULE_LICENSE("GPL");
static void __exit idetape_exit (void)
{
driver_unregister(&idetape_driver.gen_driver);
class_destroy(idetape_sysfs_class);
unregister_chrdev(IDETAPE_MAJOR, "ht");
}
@ -4911,11 +4923,33 @@ static void __exit idetape_exit (void)
*/
static int idetape_init (void)
{
int error = 1;
idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");
if (IS_ERR(idetape_sysfs_class)) {
idetape_sysfs_class = NULL;
printk(KERN_ERR "Unable to create sysfs class for ide tapes\n");
error = -EBUSY;
goto out;
}
if (register_chrdev(IDETAPE_MAJOR, "ht", &idetape_fops)) {
printk(KERN_ERR "ide-tape: Failed to register character device interface\n");
return -EBUSY;
error = -EBUSY;
goto out_free_class;
}
return driver_register(&idetape_driver.gen_driver);
error = driver_register(&idetape_driver.gen_driver);
if (error)
goto out_free_driver;
return 0;
out_free_driver:
driver_unregister(&idetape_driver.gen_driver);
out_free_class:
class_destroy(idetape_sysfs_class);
out:
return error;
}
module_init(idetape_init);

View File

@ -2361,7 +2361,7 @@ static void dv1394_add_host (struct hpsb_host *host)
ohci = (struct ti_ohci *)host->hostdata;
class_device_create(hpsb_protocol_class, MKDEV(
class_device_create(hpsb_protocol_class, NULL, MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
NULL, "dv1394-%d", id);
devfs_mk_dir("ieee1394/dv/host%d", id);

View File

@ -1292,7 +1292,7 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
if (ud->device.driver &&
(!ud->device.driver->suspend ||
ud->device.driver->suspend(&ud->device, PMSG_SUSPEND, 0)))
ud->device.driver->suspend(&ud->device, PMSG_SUSPEND)))
device_release_driver(&ud->device);
}
up_write(&ne->device.bus->subsys.rwsem);
@ -1315,7 +1315,7 @@ static void nodemgr_resume_ne(struct node_entry *ne)
continue;
if (ud->device.driver && ud->device.driver->resume)
ud->device.driver->resume(&ud->device, 0);
ud->device.driver->resume(&ud->device);
}
up_read(&ne->device.bus->subsys.rwsem);

View File

@ -2912,7 +2912,7 @@ static int __init init_raw1394(void)
hpsb_register_highlevel(&raw1394_highlevel);
if (IS_ERR(class_device_create(hpsb_protocol_class, MKDEV(
if (IS_ERR(class_device_create(hpsb_protocol_class, NULL, MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
NULL, RAW1394_DEVICE_NAME))) {
ret = -EFAULT;

View File

@ -1370,7 +1370,7 @@ static void video1394_add_host (struct hpsb_host *host)
hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
class_device_create(hpsb_protocol_class, MKDEV(
class_device_create(hpsb_protocol_class, NULL, MKDEV(
IEEE1394_MAJOR, minor),
NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor),

View File

@ -1300,7 +1300,7 @@ static int __init ib_ucm_init(void)
goto err_class;
}
class_device_create(ib_ucm_class, IB_UCM_DEV, NULL, "ucm");
class_device_create(ib_ucm_class, NULL, IB_UCM_DEV, NULL, "ucm");
idr_init(&ctx_id_table);
init_MUTEX(&ctx_id_mutex);

View File

@ -20,7 +20,6 @@
#include <linux/major.h>
#include <linux/smp_lock.h>
#include <linux/device.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/compat.h>
struct evdev {
@ -662,6 +661,7 @@ static struct file_operations evdev_fops = {
static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
{
struct evdev *evdev;
struct class_device *cdev;
int minor;
for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++);
@ -687,11 +687,13 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct
evdev_table[minor] = evdev;
devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor);
class_device_create(input_class,
cdev = class_device_create(&input_class, &dev->cdev,
MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
dev->dev, "event%d", minor);
dev->cdev.dev, evdev->name);
/* temporary symlink to keep userspace happy */
sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
evdev->name);
return &evdev->handle;
}
@ -701,9 +703,9 @@ static void evdev_disconnect(struct input_handle *handle)
struct evdev *evdev = handle->private;
struct evdev_list *list;
class_device_destroy(input_class,
sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name);
class_device_destroy(&input_class,
MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
devfs_remove("input/event%d", evdev->minor);
evdev->exist = 0;
if (evdev->open) {

View File

@ -22,12 +22,12 @@
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/device.h>
#include <linux/devfs_fs_kernel.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input core");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(input_allocate_device);
EXPORT_SYMBOL(input_register_device);
EXPORT_SYMBOL(input_unregister_device);
EXPORT_SYMBOL(input_register_handler);
@ -39,7 +39,7 @@ EXPORT_SYMBOL(input_close_device);
EXPORT_SYMBOL(input_accept_process);
EXPORT_SYMBOL(input_flush_device);
EXPORT_SYMBOL(input_event);
EXPORT_SYMBOL(input_class);
EXPORT_SYMBOL_GPL(input_class);
#define INPUT_DEVICES 256
@ -316,124 +316,21 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st
return NULL;
}
/*
* Input hotplugging interface - loading event handlers based on
* device bitfields.
*/
#ifdef CONFIG_HOTPLUG
/*
* Input hotplugging invokes what /proc/sys/kernel/hotplug says
* (normally /sbin/hotplug) when input devices get added or removed.
*
* This invokes a user mode policy agent, typically helping to load driver
* or other modules, configure the device, and more. Drivers can provide
* a MODULE_DEVICE_TABLE to help with module loading subtasks.
*
*/
#define SPRINTF_BIT_A(bit, name, max) \
do { \
envp[i++] = scratch; \
scratch += sprintf(scratch, name); \
for (j = NBITS(max) - 1; j >= 0; j--) \
if (dev->bit[j]) break; \
for (; j >= 0; j--) \
scratch += sprintf(scratch, "%lx ", dev->bit[j]); \
scratch++; \
} while (0)
#define SPRINTF_BIT_A2(bit, name, max, ev) \
do { \
if (test_bit(ev, dev->evbit)) \
SPRINTF_BIT_A(bit, name, max); \
} while (0)
static void input_call_hotplug(char *verb, struct input_dev *dev)
static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, int max)
{
char *argv[3], **envp, *buf, *scratch;
int i = 0, j, value;
int i;
int len = 0;
if (!hotplug_path[0]) {
printk(KERN_ERR "input.c: calling hotplug without a hotplug agent defined\n");
return;
}
if (in_interrupt()) {
printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
return;
}
if (!current->fs->root) {
printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
return;
}
if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
return;
}
if (!(buf = kmalloc(1024, GFP_KERNEL))) {
kfree (envp);
printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
return;
}
for (i = NBITS(max) - 1; i > 0; i--)
if (bitmap[i])
break;
argv[0] = hotplug_path;
argv[1] = "input";
argv[2] = NULL;
envp[i++] = "HOME=/";
envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
scratch = buf;
envp[i++] = scratch;
scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
envp[i++] = scratch;
scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
if (dev->name) {
envp[i++] = scratch;
scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
}
if (dev->phys) {
envp[i++] = scratch;
scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
}
SPRINTF_BIT_A(evbit, "EV=", EV_MAX);
SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY);
SPRINTF_BIT_A2(relbit, "REL=", REL_MAX, EV_REL);
SPRINTF_BIT_A2(absbit, "ABS=", ABS_MAX, EV_ABS);
SPRINTF_BIT_A2(mscbit, "MSC=", MSC_MAX, EV_MSC);
SPRINTF_BIT_A2(ledbit, "LED=", LED_MAX, EV_LED);
SPRINTF_BIT_A2(sndbit, "SND=", SND_MAX, EV_SND);
SPRINTF_BIT_A2(ffbit, "FF=", FF_MAX, EV_FF);
SPRINTF_BIT_A2(swbit, "SW=", SW_MAX, EV_SW);
envp[i++] = NULL;
#ifdef INPUT_DEBUG
printk(KERN_DEBUG "input.c: calling %s %s [%s %s %s %s %s]\n",
argv[0], argv[1], envp[0], envp[1], envp[2], envp[3], envp[4]);
#endif
value = call_usermodehelper(argv [0], argv, envp, 0);
kfree(buf);
kfree(envp);
#ifdef INPUT_DEBUG
if (value != 0)
printk(KERN_DEBUG "input.c: hotplug returned %d\n", value);
#endif
for (; i >= 0; i--)
len += snprintf(buf + len, max(buf_size - len, 0),
"%lx%s", bitmap[i], i > 0 ? " " : "");
return len;
}
#endif
#ifdef CONFIG_PROC_FS
static struct proc_dir_entry *proc_bus_input_dir;
@ -455,37 +352,39 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait)
return 0;
}
#define SPRINTF_BIT_B(bit, name, max) \
do { \
len += sprintf(buf + len, "B: %s", name); \
for (i = NBITS(max) - 1; i >= 0; i--) \
if (dev->bit[i]) break; \
for (; i >= 0; i--) \
len += sprintf(buf + len, "%lx ", dev->bit[i]); \
len += sprintf(buf + len, "\n"); \
#define SPRINTF_BIT(ev, bm) \
do { \
len += sprintf(buf + len, "B: %s=", #ev); \
len += input_print_bitmap(buf + len, INT_MAX, \
dev->bm##bit, ev##_MAX); \
len += sprintf(buf + len, "\n"); \
} while (0)
#define SPRINTF_BIT_B2(bit, name, max, ev) \
do { \
if (test_bit(ev, dev->evbit)) \
SPRINTF_BIT_B(bit, name, max); \
#define TEST_AND_SPRINTF_BIT(ev, bm) \
do { \
if (test_bit(EV_##ev, dev->evbit)) \
SPRINTF_BIT(ev, bm); \
} while (0)
static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
{
struct input_dev *dev;
struct input_handle *handle;
const char *path;
off_t at = 0;
int i, len, cnt = 0;
int len, cnt = 0;
list_for_each_entry(dev, &input_dev_list, node) {
path = dev->dynalloc ? kobject_get_path(&dev->cdev.kobj, GFP_KERNEL) : NULL;
len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version);
len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : "");
len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : "");
len += sprintf(buf + len, "S: Sysfs=%s\n", path ? path : "");
len += sprintf(buf + len, "H: Handlers=");
list_for_each_entry(handle, &dev->h_list, d_node)
@ -493,15 +392,15 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int
len += sprintf(buf + len, "\n");
SPRINTF_BIT_B(evbit, "EV=", EV_MAX);
SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY);
SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL);
SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS);
SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC);
SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED);
SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND);
SPRINTF_BIT_B2(ffbit, "FF=", FF_MAX, EV_FF);
SPRINTF_BIT_B2(swbit, "SW=", SW_MAX, EV_SW);
SPRINTF_BIT(EV, ev);
TEST_AND_SPRINTF_BIT(KEY, key);
TEST_AND_SPRINTF_BIT(REL, rel);
TEST_AND_SPRINTF_BIT(ABS, abs);
TEST_AND_SPRINTF_BIT(MSC, msc);
TEST_AND_SPRINTF_BIT(LED, led);
TEST_AND_SPRINTF_BIT(SND, snd);
TEST_AND_SPRINTF_BIT(FF, ff);
TEST_AND_SPRINTF_BIT(SW, sw);
len += sprintf(buf + len, "\n");
@ -516,6 +415,8 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int
if (cnt >= count)
break;
}
kfree(path);
}
if (&dev->node == &input_dev_list)
@ -606,6 +507,240 @@ static inline int input_proc_init(void) { return 0; }
static inline void input_proc_exit(void) { }
#endif
#define INPUT_DEV_STRING_ATTR_SHOW(name) \
static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \
{ \
struct input_dev *input_dev = to_input_dev(dev); \
int retval; \
\
retval = down_interruptible(&input_dev->sem); \
if (retval) \
return retval; \
\
retval = sprintf(buf, "%s\n", input_dev->name ? input_dev->name : ""); \
\
up(&input_dev->sem); \
\
return retval; \
} \
static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL);
INPUT_DEV_STRING_ATTR_SHOW(name);
INPUT_DEV_STRING_ATTR_SHOW(phys);
INPUT_DEV_STRING_ATTR_SHOW(uniq);
static struct attribute *input_dev_attrs[] = {
&class_device_attr_name.attr,
&class_device_attr_phys.attr,
&class_device_attr_uniq.attr,
NULL
};
static struct attribute_group input_dev_group = {
.attrs = input_dev_attrs,
};
#define INPUT_DEV_ID_ATTR(name) \
static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \
{ \
struct input_dev *input_dev = to_input_dev(dev); \
return sprintf(buf, "%04x\n", input_dev->id.name); \
} \
static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL);
INPUT_DEV_ID_ATTR(bustype);
INPUT_DEV_ID_ATTR(vendor);
INPUT_DEV_ID_ATTR(product);
INPUT_DEV_ID_ATTR(version);
static struct attribute *input_dev_id_attrs[] = {
&class_device_attr_bustype.attr,
&class_device_attr_vendor.attr,
&class_device_attr_product.attr,
&class_device_attr_version.attr,
NULL
};
static struct attribute_group input_dev_id_attr_group = {
.name = "id",
.attrs = input_dev_id_attrs,
};
#define INPUT_DEV_CAP_ATTR(ev, bm) \
static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \
{ \
struct input_dev *input_dev = to_input_dev(dev); \
return input_print_bitmap(buf, PAGE_SIZE, input_dev->bm##bit, ev##_MAX);\
} \
static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL);
INPUT_DEV_CAP_ATTR(EV, ev);
INPUT_DEV_CAP_ATTR(KEY, key);
INPUT_DEV_CAP_ATTR(REL, rel);
INPUT_DEV_CAP_ATTR(ABS, abs);
INPUT_DEV_CAP_ATTR(MSC, msc);
INPUT_DEV_CAP_ATTR(LED, led);
INPUT_DEV_CAP_ATTR(SND, snd);
INPUT_DEV_CAP_ATTR(FF, ff);
INPUT_DEV_CAP_ATTR(SW, sw);
static struct attribute *input_dev_caps_attrs[] = {
&class_device_attr_ev.attr,
&class_device_attr_key.attr,
&class_device_attr_rel.attr,
&class_device_attr_abs.attr,
&class_device_attr_msc.attr,
&class_device_attr_led.attr,
&class_device_attr_snd.attr,
&class_device_attr_ff.attr,
&class_device_attr_sw.attr,
NULL
};
static struct attribute_group input_dev_caps_attr_group = {
.name = "capabilities",
.attrs = input_dev_caps_attrs,
};
static void input_dev_release(struct class_device *class_dev)
{
struct input_dev *dev = to_input_dev(class_dev);
kfree(dev);
module_put(THIS_MODULE);
}
/*
* Input hotplugging interface - loading event handlers based on
* device bitfields.
*/
static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
char *buffer, int buffer_size, int *cur_len,
const char *name, unsigned long *bitmap, int max)
{
if (*cur_index >= num_envp - 1)
return -ENOMEM;
envp[*cur_index] = buffer + *cur_len;
*cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name);
if (*cur_len > buffer_size)
return -ENOMEM;
*cur_len += input_print_bitmap(buffer + *cur_len,
max(buffer_size - *cur_len, 0),
bitmap, max) + 1;
if (*cur_len > buffer_size)
return -ENOMEM;
(*cur_index)++;
return 0;
}
#define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \
do { \
int err = add_hotplug_env_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
fmt, val); \
if (err) \
return err; \
} while (0)
#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \
do { \
int err = input_add_hotplug_bm_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
name, bm, max); \
if (err) \
return err; \
} while (0)
static int input_dev_hotplug(struct class_device *cdev, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct input_dev *dev = to_input_dev(cdev);
int i = 0;
int len = 0;
INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x",
dev->id.bustype, dev->id.vendor,
dev->id.product, dev->id.version);
if (dev->name)
INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name);
if (dev->phys)
INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys);
if (dev->phys)
INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq);
INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX);
if (test_bit(EV_KEY, dev->evbit))
INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX);
if (test_bit(EV_REL, dev->evbit))
INPUT_ADD_HOTPLUG_BM_VAR("REL=", dev->relbit, REL_MAX);
if (test_bit(EV_ABS, dev->evbit))
INPUT_ADD_HOTPLUG_BM_VAR("ABS=", dev->absbit, ABS_MAX);
if (test_bit(EV_MSC, dev->evbit))
INPUT_ADD_HOTPLUG_BM_VAR("MSC=", dev->mscbit, MSC_MAX);
if (test_bit(EV_LED, dev->evbit))
INPUT_ADD_HOTPLUG_BM_VAR("LED=", dev->ledbit, LED_MAX);
if (test_bit(EV_SND, dev->evbit))
INPUT_ADD_HOTPLUG_BM_VAR("SND=", dev->sndbit, SND_MAX);
if (test_bit(EV_FF, dev->evbit))
INPUT_ADD_HOTPLUG_BM_VAR("FF=", dev->ffbit, FF_MAX);
if (test_bit(EV_SW, dev->evbit))
INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX);
envp[i] = NULL;
return 0;
}
struct class input_class = {
.name = "input",
.release = input_dev_release,
.hotplug = input_dev_hotplug,
};
struct input_dev *input_allocate_device(void)
{
struct input_dev *dev;
dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
if (dev) {
dev->dynalloc = 1;
dev->cdev.class = &input_class;
class_device_initialize(&dev->cdev);
INIT_LIST_HEAD(&dev->h_list);
INIT_LIST_HEAD(&dev->node);
}
return dev;
}
static void input_register_classdevice(struct input_dev *dev)
{
static atomic_t input_no = ATOMIC_INIT(0);
const char *path;
__module_get(THIS_MODULE);
dev->dev = dev->cdev.dev;
snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
"input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
printk(KERN_INFO "input: %s/%s as %s\n",
dev->name ? dev->name : "Unspecified device",
path ? path : "", dev->cdev.class_id);
kfree(path);
class_device_add(&dev->cdev);
sysfs_create_group(&dev->cdev.kobj, &input_dev_group);
sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
}
void input_register_device(struct input_dev *dev)
{
struct input_handle *handle;
@ -632,15 +767,15 @@ void input_register_device(struct input_dev *dev)
INIT_LIST_HEAD(&dev->h_list);
list_add_tail(&dev->node, &input_dev_list);
if (dev->dynalloc)
input_register_classdevice(dev);
list_for_each_entry(handler, &input_handler_list, node)
if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
if ((id = input_match_device(handler->id_table, dev)))
if ((handle = handler->connect(handler, dev, id)))
input_link_handle(handle);
#ifdef CONFIG_HOTPLUG
input_call_hotplug("add", dev);
#endif
input_wakeup_procfs_readers();
}
@ -660,12 +795,14 @@ void input_unregister_device(struct input_dev *dev)
handle->handler->disconnect(handle);
}
#ifdef CONFIG_HOTPLUG
input_call_hotplug("remove", dev);
#endif
list_del_init(&dev->node);
if (dev->dynalloc) {
sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
class_device_unregister(&dev->cdev);
}
input_wakeup_procfs_readers();
}
@ -748,16 +885,14 @@ static struct file_operations input_fops = {
.open = input_open_file,
};
struct class *input_class;
static int __init input_init(void)
{
int err;
input_class = class_create(THIS_MODULE, "input");
if (IS_ERR(input_class)) {
printk(KERN_ERR "input: unable to register input class\n");
return PTR_ERR(input_class);
err = class_register(&input_class);
if (err) {
printk(KERN_ERR "input: unable to register input_dev class\n");
return err;
}
err = input_proc_init();
@ -770,24 +905,18 @@ static int __init input_init(void)
goto fail2;
}
err = devfs_mk_dir("input");
if (err)
goto fail3;
return 0;
fail3: unregister_chrdev(INPUT_MAJOR, "input");
fail2: input_proc_exit();
fail1: class_destroy(input_class);
fail1: class_unregister(&input_class);
return err;
}
static void __exit input_exit(void)
{
input_proc_exit();
devfs_remove("input");
unregister_chrdev(INPUT_MAJOR, "input");
class_destroy(input_class);
class_unregister(&input_class);
}
subsys_initcall(input_init);

View File

@ -26,7 +26,6 @@
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/device.h>
#include <linux/devfs_fs_kernel.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Joystick device interfaces");
@ -449,6 +448,7 @@ static struct file_operations joydev_fops = {
static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
{
struct joydev *joydev;
struct class_device *cdev;
int i, j, t, minor;
for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
@ -514,11 +514,13 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
joydev_table[minor] = joydev;
devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor);
class_device_create(input_class,
cdev = class_device_create(&input_class, &dev->cdev,
MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
dev->dev, "js%d", minor);
dev->cdev.dev, joydev->name);
/* temporary symlink to keep userspace happy */
sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
joydev->name);
return &joydev->handle;
}
@ -528,8 +530,8 @@ static void joydev_disconnect(struct input_handle *handle)
struct joydev *joydev = handle->private;
struct joydev_list *list;
class_device_destroy(input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
devfs_remove("input/js%d", joydev->minor);
sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
joydev->exist = 0;
if (joydev->open) {

View File

@ -54,7 +54,7 @@ MODULE_LICENSE("GPL");
#define ADI_MIN_LENGTH 8
#define ADI_MIN_LEN_LENGTH 10
#define ADI_MIN_ID_LENGTH 66
#define ADI_MAX_NAME_LENGTH 48
#define ADI_MAX_NAME_LENGTH 64
#define ADI_MAX_CNAME_LENGTH 16
#define ADI_MAX_PHYS_LENGTH 64
@ -106,7 +106,7 @@ static struct {
*/
struct adi {
struct input_dev dev;
struct input_dev *dev;
int length;
int ret;
int idx;
@ -215,7 +215,7 @@ static inline int adi_get_bits(struct adi *adi, int count)
static int adi_decode(struct adi *adi)
{
struct input_dev *dev = &adi->dev;
struct input_dev *dev = adi->dev;
char *abs = adi->abs;
short *key = adi->key;
int i, t;
@ -318,7 +318,8 @@ static void adi_init_digital(struct gameport *gameport)
for (i = 0; seq[i]; i++) {
gameport_trigger(gameport);
if (seq[i] > 0) msleep(seq[i]);
if (seq[i] > 0)
msleep(seq[i]);
if (seq[i] < 0) {
mdelay(-seq[i]);
udelay(-seq[i]*14); /* It looks like mdelay() is off by approx 1.4% */
@ -397,42 +398,46 @@ static void adi_id_decode(struct adi *adi, struct adi_port *port)
}
}
static void adi_init_input(struct adi *adi, struct adi_port *port, int half)
static int adi_init_input(struct adi *adi, struct adi_port *port, int half)
{
int i, t;
struct input_dev *input_dev;
char buf[ADI_MAX_NAME_LENGTH];
int i, t;
if (!adi->length) return;
init_input_dev(&adi->dev);
adi->dev = input_dev = input_allocate_device();
if (!input_dev)
return -ENOMEM;
t = adi->id < ADI_ID_MAX ? adi->id : ADI_ID_MAX;
snprintf(buf, ADI_MAX_PHYS_LENGTH, adi_names[t], adi->id);
snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s", buf);
snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s [%s]", buf, adi->cname);
snprintf(adi->phys, ADI_MAX_PHYS_LENGTH, "%s/input%d", port->gameport->phys, half);
adi->abs = adi_abs[t];
adi->key = adi_key[t];
adi->dev.open = adi_open;
adi->dev.close = adi_close;
input_dev->name = adi->name;
input_dev->phys = adi->phys;
input_dev->id.bustype = BUS_GAMEPORT;
input_dev->id.vendor = GAMEPORT_ID_VENDOR_LOGITECH;
input_dev->id.product = adi->id;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &port->gameport->dev;
input_dev->private = port;
adi->dev.name = adi->name;
adi->dev.phys = adi->phys;
adi->dev.id.bustype = BUS_GAMEPORT;
adi->dev.id.vendor = GAMEPORT_ID_VENDOR_LOGITECH;
adi->dev.id.product = adi->id;
adi->dev.id.version = 0x0100;
input_dev->open = adi_open;
input_dev->close = adi_close;
adi->dev.private = port;
adi->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++)
set_bit(adi->abs[i], adi->dev.absbit);
set_bit(adi->abs[i], input_dev->absbit);
for (i = 0; i < adi->buttons; i++)
set_bit(adi->key[i], adi->dev.keybit);
set_bit(adi->key[i], input_dev->keybit);
return 0;
}
static void adi_init_center(struct adi *adi)
@ -445,17 +450,17 @@ static void adi_init_center(struct adi *adi)
for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) {
t = adi->abs[i];
x = adi->dev.abs[t];
x = adi->dev->abs[t];
if (t == ABS_THROTTLE || t == ABS_RUDDER || adi->id == ADI_ID_WGPE)
x = i < adi->axes10 ? 512 : 128;
if (i < adi->axes10)
input_set_abs_params(&adi->dev, t, 64, x * 2 - 64, 2, 16);
input_set_abs_params(adi->dev, t, 64, x * 2 - 64, 2, 16);
else if (i < adi->axes10 + adi->axes8)
input_set_abs_params(&adi->dev, t, 48, x * 2 - 48, 1, 16);
input_set_abs_params(adi->dev, t, 48, x * 2 - 48, 1, 16);
else
input_set_abs_params(&adi->dev, t, -1, 1, 0, 0);
input_set_abs_params(adi->dev, t, -1, 1, 0, 0);
}
}
@ -469,7 +474,8 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
int i;
int err;
if (!(port = kzalloc(sizeof(struct adi_port), GFP_KERNEL)))
port = kzalloc(sizeof(struct adi_port), GFP_KERNEL);
if (!port)
return -ENOMEM;
port->gameport = gameport;
@ -477,10 +483,8 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
gameport_set_drvdata(gameport, port);
err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
if (err) {
kfree(port);
return err;
}
if (err)
goto fail1;
adi_init_digital(gameport);
adi_read_packet(port);
@ -490,13 +494,18 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
for (i = 0; i < 2; i++) {
adi_id_decode(port->adi + i, port);
adi_init_input(port->adi + i, port, i);
if (!port->adi[i].length)
continue;
err = adi_init_input(port->adi + i, port, i);
if (err)
goto fail2;
}
if (!port->adi[0].length && !port->adi[1].length) {
gameport_close(gameport);
kfree(port);
return -ENODEV;
err = -ENODEV;
goto fail2;
}
gameport_set_poll_handler(gameport, adi_poll);
@ -511,12 +520,18 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
for (i = 0; i < 2; i++)
if (port->adi[i].length > 0) {
adi_init_center(port->adi + i);
input_register_device(&port->adi[i].dev);
printk(KERN_INFO "input: %s [%s] on %s\n",
port->adi[i].name, port->adi[i].cname, gameport->phys);
input_register_device(port->adi[i].dev);
}
return 0;
fail2: for (i = 0; i < 2; i++)
if (port->adi[i].dev)
input_free_device(port->adi[i].dev);
gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
kfree(port);
return err;
}
static void adi_disconnect(struct gameport *gameport)
@ -526,7 +541,7 @@ static void adi_disconnect(struct gameport *gameport)
for (i = 0; i < 2; i++)
if (port->adi[i].length > 0)
input_unregister_device(&port->adi[i].dev);
input_unregister_device(port->adi[i].dev);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(port);

View File

@ -53,11 +53,9 @@ __obsolete_setup("amijoy=");
static int amijoy_used;
static DECLARE_MUTEX(amijoy_sem);
static struct input_dev amijoy_dev[2];
static struct input_dev *amijoy_dev[2];
static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
static char *amijoy_name = "Amiga joystick";
static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
int i, data = 0, button = 0;
@ -70,15 +68,15 @@ static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
}
input_regs(amijoy_dev + i, fp);
input_regs(amijoy_dev[i], fp);
input_report_key(amijoy_dev + i, BTN_TRIGGER, button);
input_report_key(amijoy_dev[i], BTN_TRIGGER, button);
input_report_abs(amijoy_dev + i, ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
input_report_abs(amijoy_dev[i], ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
data = ~(data ^ (data << 1));
input_report_abs(amijoy_dev + i, ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1));
input_report_abs(amijoy_dev[i], ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1));
input_sync(amijoy_dev + i);
input_sync(amijoy_dev[i]);
}
return IRQ_HANDLED;
}
@ -114,39 +112,52 @@ static void amijoy_close(struct input_dev *dev)
static int __init amijoy_init(void)
{
int i, j;
int err;
for (i = 0; i < 2; i++)
if (amijoy[i]) {
if (!request_mem_region(CUSTOM_PHYSADDR+10+i*2, 2,
"amijoy [Denise]")) {
if (i == 1 && amijoy[0]) {
input_unregister_device(amijoy_dev);
release_mem_region(CUSTOM_PHYSADDR+10, 2);
}
return -EBUSY;
}
for (i = 0; i < 2; i++) {
if (!amijoy[i])
continue;
amijoy_dev[i].open = amijoy_open;
amijoy_dev[i].close = amijoy_close;
amijoy_dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
amijoy_dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
amijoy_dev[i].keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
for (j = 0; j < 2; j++) {
amijoy_dev[i].absmin[ABS_X + j] = -1;
amijoy_dev[i].absmax[ABS_X + j] = 1;
}
amijoy_dev[i].name = amijoy_name;
amijoy_dev[i].phys = amijoy_phys[i];
amijoy_dev[i].id.bustype = BUS_AMIGA;
amijoy_dev[i].id.vendor = 0x0001;
amijoy_dev[i].id.product = 0x0003;
amijoy_dev[i].id.version = 0x0100;
input_register_device(amijoy_dev + i);
printk(KERN_INFO "input: %s at joy%ddat\n", amijoy_name, i);
amijoy_dev[i] = input_allocate_device();
if (!amijoy_dev[i]) {
err = -ENOMEM;
goto fail;
}
if (!request_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2, "amijoy [Denise]")) {
input_free_device(amijoy_dev[i]);
err = -EBUSY;
goto fail;
}
amijoy_dev[i]->name = "Amiga joystick";
amijoy_dev[i]->phys = amijoy_phys[i];
amijoy_dev[i]->id.bustype = BUS_AMIGA;
amijoy_dev[i]->id.vendor = 0x0001;
amijoy_dev[i]->id.product = 0x0003;
amijoy_dev[i]->id.version = 0x0100;
amijoy_dev[i]->open = amijoy_open;
amijoy_dev[i]->close = amijoy_close;
amijoy_dev[i]->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
amijoy_dev[i]->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
amijoy_dev[i]->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
for (j = 0; j < 2; j++) {
amijoy_dev[i]->absmin[ABS_X + j] = -1;
amijoy_dev[i]->absmax[ABS_X + j] = 1;
}
input_register_device(amijoy_dev[i]);
}
return 0;
fail: while (--i >= 0)
if (amijoy[i]) {
input_unregister_device(amijoy_dev[i]);
release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2);
}
return err;
}
static void __exit amijoy_exit(void)
@ -155,8 +166,8 @@ static void __exit amijoy_exit(void)
for (i = 0; i < 2; i++)
if (amijoy[i]) {
input_unregister_device(amijoy_dev + i);
release_mem_region(CUSTOM_PHYSADDR+10+i*2, 2);
input_unregister_device(amijoy_dev[i]);
release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2);
}
}

View File

@ -111,7 +111,7 @@ static short analog_joy_btn[] = { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN
static unsigned char analog_chf[] = { 0xf, 0x0, 0x1, 0x9, 0x2, 0x4, 0xc, 0x8, 0x3, 0x5, 0xb, 0x7, 0xd, 0xe, 0xa, 0x6 };
struct analog {
struct input_dev dev;
struct input_dev *dev;
int mask;
short *buttons;
char name[ANALOG_MAX_NAME_LENGTH];
@ -182,7 +182,7 @@ static unsigned long analog_faketime = 0;
static void analog_decode(struct analog *analog, int *axes, int *initial, int buttons)
{
struct input_dev *dev = &analog->dev;
struct input_dev *dev = analog->dev;
int i, j;
if (analog->mask & ANALOG_HAT_FCS)
@ -428,27 +428,30 @@ static void analog_name(struct analog *analog)
* analog_init_device()
*/
static void analog_init_device(struct analog_port *port, struct analog *analog, int index)
static int analog_init_device(struct analog_port *port, struct analog *analog, int index)
{
struct input_dev *input_dev;
int i, j, t, v, w, x, y, z;
analog_name(analog);
sprintf(analog->phys, "%s/input%d", port->gameport->phys, index);
analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn;
init_input_dev(&analog->dev);
analog->dev = input_dev = input_allocate_device();
if (!input_dev)
return -ENOMEM;
analog->dev.name = analog->name;
analog->dev.phys = analog->phys;
analog->dev.id.bustype = BUS_GAMEPORT;
analog->dev.id.vendor = GAMEPORT_ID_VENDOR_ANALOG;
analog->dev.id.product = analog->mask >> 4;
analog->dev.id.version = 0x0100;
input_dev->name = analog->name;
input_dev->phys = analog->phys;
input_dev->id.bustype = BUS_GAMEPORT;
input_dev->id.vendor = GAMEPORT_ID_VENDOR_ANALOG;
input_dev->id.product = analog->mask >> 4;
input_dev->id.version = 0x0100;
analog->dev.open = analog_open;
analog->dev.close = analog_close;
analog->dev.private = port;
analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->open = analog_open;
input_dev->close = analog_close;
input_dev->private = port;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = j = 0; i < 4; i++)
if (analog->mask & (1 << i)) {
@ -461,8 +464,6 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
v = (x >> 3);
w = (x >> 3);
set_bit(t, analog->dev.absbit);
if ((i == 2 || i == 3) && (j == 2 || j == 3) && (z > (y >> 3)))
x = y;
@ -472,11 +473,7 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
w = (x >> 4);
}
analog->dev.absmax[t] = (x << 1) - v;
analog->dev.absmin[t] = v;
analog->dev.absfuzz[t] = port->fuzz;
analog->dev.absflat[t] = w;
input_set_abs_params(input_dev, t, v, (x << 1) - v, port->fuzz, w);
j++;
}
@ -484,41 +481,30 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
if (analog->mask & analog_exts[i])
for (x = 0; x < 2; x++) {
t = analog_hats[j++];
set_bit(t, analog->dev.absbit);
analog->dev.absmax[t] = 1;
analog->dev.absmin[t] = -1;
input_set_abs_params(input_dev, t, -1, 1, 0, 0);
}
for (i = j = 0; i < 4; i++)
if (analog->mask & (0x10 << i))
set_bit(analog->buttons[j++], analog->dev.keybit);
set_bit(analog->buttons[j++], input_dev->keybit);
if (analog->mask & ANALOG_BTNS_CHF)
for (i = 0; i < 2; i++)
set_bit(analog->buttons[j++], analog->dev.keybit);
set_bit(analog->buttons[j++], input_dev->keybit);
if (analog->mask & ANALOG_HBTN_CHF)
for (i = 0; i < 4; i++)
set_bit(analog->buttons[j++], analog->dev.keybit);
set_bit(analog->buttons[j++], input_dev->keybit);
for (i = 0; i < 4; i++)
if (analog->mask & (ANALOG_BTN_TL << i))
set_bit(analog_pads[i], analog->dev.keybit);
set_bit(analog_pads[i], input_dev->keybit);
analog_decode(analog, port->axes, port->initial, port->buttons);
input_register_device(&analog->dev);
input_register_device(analog->dev);
printk(KERN_INFO "input: %s at %s", analog->name, port->gameport->phys);
if (port->cooked)
printk(" [ADC port]\n");
else
printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME,
port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed,
port->speed > 10000 ? "M" : "k",
port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000)
: (port->loop * 1000000) / port->speed);
return 0;
}
/*
@ -659,37 +645,41 @@ static int analog_connect(struct gameport *gameport, struct gameport_driver *drv
return - ENOMEM;
err = analog_init_port(gameport, drv, port);
if (err) {
kfree(port);
return err;
}
if (err)
goto fail1;
err = analog_init_masks(port);
if (err) {
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(port);
return err;
}
if (err)
goto fail2;
gameport_set_poll_handler(gameport, analog_poll);
gameport_set_poll_interval(gameport, 10);
for (i = 0; i < 2; i++)
if (port->analog[i].mask)
analog_init_device(port, port->analog + i, i);
if (port->analog[i].mask) {
err = analog_init_device(port, port->analog + i, i);
if (err)
goto fail3;
}
return 0;
fail3: while (--i >= 0)
input_unregister_device(port->analog[i].dev);
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
kfree(port);
return err;
}
static void analog_disconnect(struct gameport *gameport)
{
int i;
struct analog_port *port = gameport_get_drvdata(gameport);
int i;
for (i = 0; i < 2; i++)
if (port->analog[i].mask)
input_unregister_device(&port->analog[i].dev);
input_unregister_device(port->analog[i].dev);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
printk(KERN_INFO "analog.c: %d out of %d reads (%d%%) on %s failed\n",

View File

@ -44,13 +44,11 @@ MODULE_LICENSE("GPL");
#define COBRA_MAX_STROBE 45 /* 45 us max wait for first strobe */
#define COBRA_LENGTH 36
static char* cobra_name = "Creative Labs Blaster GamePad Cobra";
static int cobra_btn[] = { BTN_START, BTN_SELECT, BTN_TL, BTN_TR, BTN_X, BTN_Y, BTN_Z, BTN_A, BTN_B, BTN_C, BTN_TL2, BTN_TR2, 0 };
struct cobra {
struct gameport *gameport;
struct input_dev dev[2];
struct input_dev *dev[2];
int reads;
int bads;
unsigned char exists;
@ -128,7 +126,7 @@ static void cobra_poll(struct gameport *gameport)
for (i = 0; i < 2; i++)
if (cobra->exists & r & (1 << i)) {
dev = cobra->dev + i;
dev = cobra->dev[i];
input_report_abs(dev, ABS_X, ((data[i] >> 4) & 1) - ((data[i] >> 3) & 1));
input_report_abs(dev, ABS_Y, ((data[i] >> 2) & 1) - ((data[i] >> 1) & 1));
@ -159,11 +157,13 @@ static void cobra_close(struct input_dev *dev)
static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct cobra *cobra;
struct input_dev *input_dev;
unsigned int data[2];
int i, j;
int err;
if (!(cobra = kzalloc(sizeof(struct cobra), GFP_KERNEL)))
cobra = kzalloc(sizeof(struct cobra), GFP_KERNEL);
if (!cobra)
return -ENOMEM;
cobra->gameport = gameport;
@ -191,38 +191,46 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
gameport_set_poll_handler(gameport, cobra_poll);
gameport_set_poll_interval(gameport, 20);
for (i = 0; i < 2; i++)
if ((cobra->exists >> i) & 1) {
for (i = 0; i < 2; i++) {
if (~(cobra->exists >> i) & 1)
continue;
sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i);
cobra->dev[i].private = cobra;
cobra->dev[i].open = cobra_open;
cobra->dev[i].close = cobra_close;
cobra->dev[i].name = cobra_name;
cobra->dev[i].phys = cobra->phys[i];
cobra->dev[i].id.bustype = BUS_GAMEPORT;
cobra->dev[i].id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
cobra->dev[i].id.product = 0x0008;
cobra->dev[i].id.version = 0x0100;
cobra->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_set_abs_params(&cobra->dev[i], ABS_X, -1, 1, 0, 0);
input_set_abs_params(&cobra->dev[i], ABS_Y, -1, 1, 0, 0);
for (j = 0; cobra_btn[j]; j++)
set_bit(cobra_btn[j], cobra->dev[i].keybit);
input_register_device(&cobra->dev[i]);
printk(KERN_INFO "input: %s on %s\n", cobra_name, gameport->phys);
cobra->dev[i] = input_dev = input_allocate_device();
if (!input_dev) {
err = -ENOMEM;
goto fail3;
}
sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i);
input_dev->name = "Creative Labs Blaster GamePad Cobra";
input_dev->phys = cobra->phys[i];
input_dev->id.bustype = BUS_GAMEPORT;
input_dev->id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
input_dev->id.product = 0x0008;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &gameport->dev;
input_dev->private = cobra;
input_dev->open = cobra_open;
input_dev->close = cobra_close;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
for (j = 0; cobra_btn[j]; j++)
set_bit(cobra_btn[j], input_dev->keybit);
input_register_device(cobra->dev[i]);
}
return 0;
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
fail3: for (i = 0; i < 2; i++)
if (cobra->dev[i])
input_unregister_device(cobra->dev[i]);
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
kfree(cobra);
return err;
}
@ -234,7 +242,7 @@ static void cobra_disconnect(struct gameport *gameport)
for (i = 0; i < 2; i++)
if ((cobra->exists >> i) & 1)
input_unregister_device(cobra->dev + i);
input_unregister_device(cobra->dev[i]);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(cobra);

View File

@ -43,25 +43,28 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver");
MODULE_LICENSE("GPL");
static int db9[] __initdata = { -1, 0 };
static int db9_nargs __initdata = 0;
module_param_array_named(dev, db9, int, &db9_nargs, 0);
struct db9_config {
int args[2];
int nargs;
};
#define DB9_MAX_PORTS 3
static struct db9_config db9[DB9_MAX_PORTS] __initdata;
module_param_array_named(dev, db9[0].args, int, &db9[0].nargs, 0);
MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
static int db9_2[] __initdata = { -1, 0 };
static int db9_nargs_2 __initdata = 0;
module_param_array_named(dev2, db9_2, int, &db9_nargs_2, 0);
module_param_array_named(dev2, db9[1].args, int, &db9[0].nargs, 0);
MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
static int db9_3[] __initdata = { -1, 0 };
static int db9_nargs_3 __initdata = 0;
module_param_array_named(dev3, db9_3, int, &db9_nargs_3, 0);
module_param_array_named(dev3, db9[2].args, int, &db9[2].nargs, 0);
MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");
__obsolete_setup("db9=");
__obsolete_setup("db9_2=");
__obsolete_setup("db9_3=");
#define DB9_ARG_PARPORT 0
#define DB9_ARG_MODE 1
#define DB9_MULTI_STICK 0x01
#define DB9_MULTI2_STICK 0x02
#define DB9_GENESIS_PAD 0x03
@ -87,40 +90,53 @@ __obsolete_setup("db9_3=");
#define DB9_NORMAL 0x0a
#define DB9_NOSELECT 0x08
#define DB9_MAX_DEVICES 2
#define DB9_GENESIS6_DELAY 14
#define DB9_REFRESH_TIME HZ/100
#define DB9_MAX_DEVICES 2
struct db9_mode_data {
const char *name;
const short *buttons;
int n_buttons;
int n_pads;
int n_axis;
int bidirectional;
int reverse;
};
struct db9 {
struct input_dev dev[DB9_MAX_DEVICES];
struct input_dev *dev[DB9_MAX_DEVICES];
struct timer_list timer;
struct pardevice *pd;
int mode;
int used;
struct semaphore sem;
char phys[2][32];
char phys[DB9_MAX_DEVICES][32];
};
static struct db9 *db9_base[3];
static short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 9, 1, 1, 7, 9, 9 };
static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn,
db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn,
db9_cd32_btn, db9_cd32_btn };
static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick",
"Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad", "Saturn dpp", "Saturn dpp dual" };
static const int db9_max_pads[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 6, 1, 2, 1, 6, 12 };
static const int db9_num_axis[DB9_MAX_PAD] = { 0, 2, 2, 2, 0, 2, 2, 7, 2, 2, 2 ,7, 7 };
static const short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
static const short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
static const short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
static const short db9_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_RZ, ABS_Z, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
static const int db9_bidirectional[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0 };
static const int db9_reverse[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0 };
static const struct db9_mode_data db9_modes[] = {
{ NULL, NULL, 0, 0, 0, 0, 0 },
{ "Multisystem joystick", db9_multi_btn, 1, 1, 2, 1, 1 },
{ "Multisystem joystick (2 fire)", db9_multi_btn, 2, 1, 2, 1, 1 },
{ "Genesis pad", db9_genesis_btn, 4, 1, 2, 1, 1 },
{ NULL, NULL, 0, 0, 0, 0, 0 },
{ "Genesis 5 pad", db9_genesis_btn, 6, 1, 2, 1, 1 },
{ "Genesis 6 pad", db9_genesis_btn, 8, 1, 2, 1, 1 },
{ "Saturn pad", db9_cd32_btn, 9, 6, 7, 0, 1 },
{ "Multisystem (0.8.0.2) joystick", db9_multi_btn, 1, 1, 2, 1, 1 },
{ "Multisystem (0.8.0.2-dual) joystick", db9_multi_btn, 1, 2, 2, 1, 1 },
{ "Amiga CD-32 pad", db9_cd32_btn, 7, 1, 2, 1, 1 },
{ "Saturn dpp", db9_cd32_btn, 9, 6, 7, 0, 0 },
{ "Saturn dpp dual", db9_cd32_btn, 9, 12, 7, 0, 0 },
};
/*
* Saturn controllers
@ -342,7 +358,7 @@ static int db9_saturn(int mode, struct parport *port, struct input_dev *dev)
default:
return -1;
}
max_pads = min(db9_max_pads[mode], DB9_MAX_DEVICES);
max_pads = min(db9_modes[mode].n_pads, DB9_MAX_DEVICES);
for (tmp = 0, i = 0; i < n; i++) {
id = db9_saturn_read_packet(port, data, type + i, 1);
tmp = db9_saturn_report(id, data, dev, tmp, max_pads);
@ -354,17 +370,18 @@ static void db9_timer(unsigned long private)
{
struct db9 *db9 = (void *) private;
struct parport *port = db9->pd->port;
struct input_dev *dev = db9->dev;
struct input_dev *dev = db9->dev[0];
struct input_dev *dev2 = db9->dev[1];
int data, i;
switch(db9->mode) {
switch (db9->mode) {
case DB9_MULTI_0802_2:
data = parport_read_data(port) >> 3;
input_report_abs(dev + 1, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
input_report_abs(dev + 1, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
input_report_key(dev + 1, BTN_TRIGGER, ~data & DB9_FIRE1);
input_report_abs(dev2, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
input_report_abs(dev2, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
input_report_key(dev2, BTN_TRIGGER, ~data & DB9_FIRE1);
case DB9_MULTI_0802:
@ -405,7 +422,7 @@ static void db9_timer(unsigned long private)
input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
parport_write_control(port, DB9_NORMAL);
data=parport_read_data(port);
data = parport_read_data(port);
input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
@ -414,7 +431,7 @@ static void db9_timer(unsigned long private)
case DB9_GENESIS5_PAD:
parport_write_control(port, DB9_NOSELECT);
data=parport_read_data(port);
data = parport_read_data(port);
input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
@ -422,7 +439,7 @@ static void db9_timer(unsigned long private)
input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
parport_write_control(port, DB9_NORMAL);
data=parport_read_data(port);
data = parport_read_data(port);
input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
input_report_key(dev, BTN_X, ~data & DB9_FIRE2);
@ -434,7 +451,7 @@ static void db9_timer(unsigned long private)
parport_write_control(port, DB9_NOSELECT); /* 1 */
udelay(DB9_GENESIS6_DELAY);
data=parport_read_data(port);
data = parport_read_data(port);
input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
@ -443,7 +460,7 @@ static void db9_timer(unsigned long private)
parport_write_control(port, DB9_NORMAL);
udelay(DB9_GENESIS6_DELAY);
data=parport_read_data(port);
data = parport_read_data(port);
input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
@ -477,7 +494,7 @@ static void db9_timer(unsigned long private)
case DB9_CD32_PAD:
data=parport_read_data(port);
data = parport_read_data(port);
input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
@ -489,7 +506,7 @@ static void db9_timer(unsigned long private)
parport_write_control(port, 0x02);
parport_write_control(port, 0x0a);
input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2);
}
}
parport_write_control(port, 0x00);
break;
@ -513,7 +530,7 @@ static int db9_open(struct input_dev *dev)
if (!db9->used++) {
parport_claim(db9->pd);
parport_write_data(port, 0xff);
if (db9_reverse[db9->mode]) {
if (db9_modes[db9->mode].reverse) {
parport_data_reverse(port);
parport_write_control(port, DB9_NORMAL);
}
@ -539,117 +556,160 @@ static void db9_close(struct input_dev *dev)
up(&db9->sem);
}
static struct db9 __init *db9_probe(int *config, int nargs)
static struct db9 __init *db9_probe(int parport, int mode)
{
struct db9 *db9;
const struct db9_mode_data *db9_mode;
struct parport *pp;
struct pardevice *pd;
struct input_dev *input_dev;
int i, j;
int err;
if (config[0] < 0)
return NULL;
if (nargs < 2) {
printk(KERN_ERR "db9.c: Device type must be specified.\n");
return NULL;
if (mode < 1 || mode >= DB9_MAX_PAD || !db9_modes[mode].n_buttons) {
printk(KERN_ERR "db9.c: Bad device type %d\n", mode);
err = -EINVAL;
goto err_out;
}
if (config[1] < 1 || config[1] >= DB9_MAX_PAD || !db9_buttons[config[1]]) {
printk(KERN_ERR "db9.c: bad config\n");
return NULL;
}
db9_mode = &db9_modes[mode];
pp = parport_find_number(config[0]);
pp = parport_find_number(parport);
if (!pp) {
printk(KERN_ERR "db9.c: no such parport\n");
return NULL;
err = -ENODEV;
goto err_out;
}
if (db9_bidirectional[config[1]]) {
if (!(pp->modes & PARPORT_MODE_TRISTATE)) {
printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
parport_put_port(pp);
return NULL;
}
if (db9_mode[mode].bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) {
printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
err = -EINVAL;
goto err_put_pp;
}
if (!(db9 = kzalloc(sizeof(struct db9), GFP_KERNEL))) {
parport_put_port(pp);
return NULL;
pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
if (!pd) {
printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
err = -EBUSY;
goto err_put_pp;
}
db9 = kzalloc(sizeof(struct db9), GFP_KERNEL);
if (!db9) {
printk(KERN_ERR "db9.c: Not enough memory\n");
err = -ENOMEM;
goto err_unreg_pardev;
}
init_MUTEX(&db9->sem);
db9->mode = config[1];
db9->pd = pd;
db9->mode = mode;
init_timer(&db9->timer);
db9->timer.data = (long) db9;
db9->timer.function = db9_timer;
db9->pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
parport_put_port(pp);
for (i = 0; i < (min(db9_mode->n_pads, DB9_MAX_DEVICES)); i++) {
if (!db9->pd) {
printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
kfree(db9);
return NULL;
}
for (i = 0; i < (min(db9_max_pads[db9->mode], DB9_MAX_DEVICES)); i++) {
db9->dev[i] = input_dev = input_allocate_device();
if (!input_dev) {
printk(KERN_ERR "db9.c: Not enough memory for input device\n");
err = -ENOMEM;
goto err_free_devs;
}
sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i);
db9->dev[i].private = db9;
db9->dev[i].open = db9_open;
db9->dev[i].close = db9_close;
input_dev->name = db9_mode->name;
input_dev->phys = db9->phys[i];
input_dev->id.bustype = BUS_PARPORT;
input_dev->id.vendor = 0x0002;
input_dev->id.product = mode;
input_dev->id.version = 0x0100;
input_dev->private = db9;
db9->dev[i].name = db9_name[db9->mode];
db9->dev[i].phys = db9->phys[i];
db9->dev[i].id.bustype = BUS_PARPORT;
db9->dev[i].id.vendor = 0x0002;
db9->dev[i].id.product = config[1];
db9->dev[i].id.version = 0x0100;
input_dev->open = db9_open;
input_dev->close = db9_close;
db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (j = 0; j < db9_buttons[db9->mode]; j++)
set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit);
for (j = 0; j < db9_num_axis[db9->mode]; j++) {
set_bit(db9_abs[j], db9->dev[i].absbit);
if (j < 2) {
db9->dev[i].absmin[db9_abs[j]] = -1;
db9->dev[i].absmax[db9_abs[j]] = 1;
} else {
db9->dev[i].absmin[db9_abs[j]] = 1;
db9->dev[i].absmax[db9_abs[j]] = 255;
db9->dev[i].absflat[db9_abs[j]] = 0;
}
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (j = 0; j < db9_mode->n_buttons; j++)
set_bit(db9_mode->buttons[j], input_dev->keybit);
for (j = 0; j < db9_mode->n_axis; j++) {
if (j < 2)
input_set_abs_params(input_dev, db9_abs[j], -1, 1, 0, 0);
else
input_set_abs_params(input_dev, db9_abs[j], 1, 255, 0, 0);
}
input_register_device(db9->dev + i);
printk(KERN_INFO "input: %s on %s\n", db9->dev[i].name, db9->pd->port->name);
input_register_device(input_dev);
}
parport_put_port(pp);
return db9;
err_free_devs:
while (--i >= 0)
input_unregister_device(db9->dev[i]);
kfree(db9);
err_unreg_pardev:
parport_unregister_device(pd);
err_put_pp:
parport_put_port(pp);
err_out:
return ERR_PTR(err);
}
static void __exit db9_remove(struct db9 *db9)
{
int i;
for (i = 0; i < min(db9_modes[db9->mode].n_pads, DB9_MAX_DEVICES); i++)
input_unregister_device(db9->dev[i]);
parport_unregister_device(db9->pd);
kfree(db9);
}
static int __init db9_init(void)
{
db9_base[0] = db9_probe(db9, db9_nargs);
db9_base[1] = db9_probe(db9_2, db9_nargs_2);
db9_base[2] = db9_probe(db9_3, db9_nargs_3);
int i;
int have_dev = 0;
int err = 0;
if (db9_base[0] || db9_base[1] || db9_base[2])
return 0;
for (i = 0; i < DB9_MAX_PORTS; i++) {
if (db9[i].nargs == 0 || db9[i].args[DB9_ARG_PARPORT] < 0)
continue;
return -ENODEV;
if (db9[i].nargs < 2) {
printk(KERN_ERR "db9.c: Device type must be specified.\n");
err = -EINVAL;
break;
}
db9_base[i] = db9_probe(db9[i].args[DB9_ARG_PARPORT],
db9[i].args[DB9_ARG_MODE]);
if (IS_ERR(db9_base[i])) {
err = PTR_ERR(db9_base[i]);
break;
}
have_dev = 1;
}
if (err) {
while (--i >= 0)
db9_remove(db9_base[i]);
return err;
}
return have_dev ? 0 : -ENODEV;
}
static void __exit db9_exit(void)
{
int i, j;
int i;
for (i = 0; i < 3; i++)
if (db9_base[i]) {
for (j = 0; j < min(db9_max_pads[db9_base[i]->mode], DB9_MAX_DEVICES); j++)
input_unregister_device(db9_base[i]->dev + j);
parport_unregister_device(db9_base[i]->pd);
}
for (i = 0; i < DB9_MAX_PORTS; i++)
if (db9_base[i])
db9_remove(db9_base[i]);
}
module_init(db9_init);

View File

@ -41,20 +41,22 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver");
MODULE_LICENSE("GPL");
static int gc[] __initdata = { -1, 0, 0, 0, 0, 0 };
static int gc_nargs __initdata = 0;
module_param_array_named(map, gc, int, &gc_nargs, 0);
MODULE_PARM_DESC(map, "Describers first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
#define GC_MAX_PORTS 3
#define GC_MAX_DEVICES 5
static int gc_2[] __initdata = { -1, 0, 0, 0, 0, 0 };
static int gc_nargs_2 __initdata = 0;
module_param_array_named(map2, gc_2, int, &gc_nargs_2, 0);
MODULE_PARM_DESC(map2, "Describers second set of devices");
struct gc_config {
int args[GC_MAX_DEVICES + 1];
int nargs;
};
static int gc_3[] __initdata = { -1, 0, 0, 0, 0, 0 };
static int gc_nargs_3 __initdata = 0;
module_param_array_named(map3, gc_3, int, &gc_nargs_3, 0);
MODULE_PARM_DESC(map3, "Describers third set of devices");
static struct gc_config gc[GC_MAX_PORTS] __initdata;
module_param_array_named(map, gc[0].args, int, &gc[0].nargs, 0);
MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
module_param_array_named(map2, gc[1].args, int, &gc[1].nargs, 0);
MODULE_PARM_DESC(map2, "Describes second set of devices");
module_param_array_named(map3, gc[2].args, int, &gc[2].nargs, 0);
MODULE_PARM_DESC(map3, "Describes third set of devices");
__obsolete_setup("gc=");
__obsolete_setup("gc_2=");
@ -77,12 +79,12 @@ __obsolete_setup("gc_3=");
struct gc {
struct pardevice *pd;
struct input_dev dev[5];
struct input_dev *dev[GC_MAX_DEVICES];
struct timer_list timer;
unsigned char pads[GC_MAX + 1];
int used;
struct semaphore sem;
char phys[5][32];
char phys[GC_MAX_DEVICES][32];
};
static struct gc *gc_base[3];
@ -330,7 +332,6 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES
static void gc_timer(unsigned long private)
{
struct gc *gc = (void *) private;
struct input_dev *dev = gc->dev;
unsigned char data[GC_MAX_LENGTH];
unsigned char data_psx[5][GC_PSX_BYTES];
int i, j, s;
@ -357,16 +358,16 @@ static void gc_timer(unsigned long private)
if (data[31 - j] & s) axes[1] |= 1 << j;
}
input_report_abs(dev + i, ABS_X, axes[0]);
input_report_abs(dev + i, ABS_Y, -axes[1]);
input_report_abs(gc->dev[i], ABS_X, axes[0]);
input_report_abs(gc->dev[i], ABS_Y, -axes[1]);
input_report_abs(dev + i, ABS_HAT0X, !(s & data[6]) - !(s & data[7]));
input_report_abs(dev + i, ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));
input_report_abs(gc->dev[i], ABS_HAT0X, !(s & data[6]) - !(s & data[7]));
input_report_abs(gc->dev[i], ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));
for (j = 0; j < 10; j++)
input_report_key(dev + i, gc_n64_btn[j], s & data[gc_n64_bytes[j]]);
input_report_key(gc->dev[i], gc_n64_btn[j], s & data[gc_n64_bytes[j]]);
input_sync(dev + i);
input_sync(gc->dev[i]);
}
}
}
@ -384,19 +385,19 @@ static void gc_timer(unsigned long private)
s = gc_status_bit[i];
if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) {
input_report_abs(dev + i, ABS_X, !(s & data[6]) - !(s & data[7]));
input_report_abs(dev + i, ABS_Y, !(s & data[4]) - !(s & data[5]));
input_report_abs(gc->dev[i], ABS_X, !(s & data[6]) - !(s & data[7]));
input_report_abs(gc->dev[i], ABS_Y, !(s & data[4]) - !(s & data[5]));
}
if (s & gc->pads[GC_NES])
for (j = 0; j < 4; j++)
input_report_key(dev + i, gc_snes_btn[j], s & data[gc_nes_bytes[j]]);
input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_nes_bytes[j]]);
if (s & gc->pads[GC_SNES])
for (j = 0; j < 8; j++)
input_report_key(dev + i, gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
input_sync(dev + i);
input_sync(gc->dev[i]);
}
}
@ -413,15 +414,15 @@ static void gc_timer(unsigned long private)
s = gc_status_bit[i];
if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) {
input_report_abs(dev + i, ABS_X, !(s & data[2]) - !(s & data[3]));
input_report_abs(dev + i, ABS_Y, !(s & data[0]) - !(s & data[1]));
input_report_key(dev + i, BTN_TRIGGER, s & data[4]);
input_report_abs(gc->dev[i], ABS_X, !(s & data[2]) - !(s & data[3]));
input_report_abs(gc->dev[i], ABS_Y, !(s & data[0]) - !(s & data[1]));
input_report_key(gc->dev[i], BTN_TRIGGER, s & data[4]);
}
if (s & gc->pads[GC_MULTI2])
input_report_key(dev + i, BTN_THUMB, s & data[5]);
input_report_key(gc->dev[i], BTN_THUMB, s & data[5]);
input_sync(dev + i);
input_sync(gc->dev[i]);
}
}
@ -438,44 +439,44 @@ static void gc_timer(unsigned long private)
case GC_PSX_RUMBLE:
input_report_key(dev + i, BTN_THUMBL, ~data_psx[i][0] & 0x04);
input_report_key(dev + i, BTN_THUMBR, ~data_psx[i][0] & 0x02);
input_report_key(gc->dev[i], BTN_THUMBL, ~data_psx[i][0] & 0x04);
input_report_key(gc->dev[i], BTN_THUMBR, ~data_psx[i][0] & 0x02);
case GC_PSX_NEGCON:
case GC_PSX_ANALOG:
if(gc->pads[GC_DDR] & gc_status_bit[i]) {
if (gc->pads[GC_DDR] & gc_status_bit[i]) {
for(j = 0; j < 4; j++)
input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
} else {
for (j = 0; j < 4; j++)
input_report_abs(dev + i, gc_psx_abs[j+2], data_psx[i][j + 2]);
input_report_abs(gc->dev[i], gc_psx_abs[j+2], data_psx[i][j + 2]);
input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
}
for (j = 0; j < 8; j++)
input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
input_report_key(dev + i, BTN_START, ~data_psx[i][0] & 0x08);
input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);
input_report_key(gc->dev[i], BTN_START, ~data_psx[i][0] & 0x08);
input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01);
input_sync(dev + i);
input_sync(gc->dev[i]);
break;
case GC_PSX_NORMAL:
if(gc->pads[GC_DDR] & gc_status_bit[i]) {
if (gc->pads[GC_DDR] & gc_status_bit[i]) {
for(j = 0; j < 4; j++)
input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
} else {
input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
/* for some reason if the extra axes are left unset they drift */
/* for (j = 0; j < 4; j++)
input_report_abs(dev + i, gc_psx_abs[j+2], 128);
input_report_abs(gc->dev[i], gc_psx_abs[j+2], 128);
* This needs to be debugged properly,
* maybe fuzz processing needs to be done in input_sync()
* --vojtech
@ -483,12 +484,12 @@ static void gc_timer(unsigned long private)
}
for (j = 0; j < 8; j++)
input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
input_report_key(dev + i, BTN_START, ~data_psx[i][0] & 0x08);
input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);
input_report_key(gc->dev[i], BTN_START, ~data_psx[i][0] & 0x08);
input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01);
input_sync(dev + i);
input_sync(gc->dev[i]);
break;
@ -533,177 +534,212 @@ static void gc_close(struct input_dev *dev)
up(&gc->sem);
}
static struct gc __init *gc_probe(int *config, int nargs)
static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
{
struct input_dev *input_dev;
int i;
if (!pad_type)
return 0;
if (pad_type < 1 || pad_type > GC_MAX) {
printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", pad_type);
return -EINVAL;
}
gc->dev[idx] = input_dev = input_allocate_device();
if (!input_dev) {
printk(KERN_ERR "gamecon.c: Not enough memory for input device\n");
return -ENOMEM;
}
input_dev->name = gc_names[pad_type];
input_dev->phys = gc->phys[idx];
input_dev->id.bustype = BUS_PARPORT;
input_dev->id.vendor = 0x0001;
input_dev->id.product = pad_type;
input_dev->id.version = 0x0100;
input_dev->private = gc;
input_dev->open = gc_open;
input_dev->close = gc_close;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < 2; i++)
input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
gc->pads[0] |= gc_status_bit[idx];
gc->pads[pad_type] |= gc_status_bit[idx];
switch (pad_type) {
case GC_N64:
for (i = 0; i < 10; i++)
set_bit(gc_n64_btn[i], input_dev->keybit);
for (i = 0; i < 2; i++) {
input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2);
input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
}
break;
case GC_SNES:
for (i = 4; i < 8; i++)
set_bit(gc_snes_btn[i], input_dev->keybit);
case GC_NES:
for (i = 0; i < 4; i++)
set_bit(gc_snes_btn[i], input_dev->keybit);
break;
case GC_MULTI2:
set_bit(BTN_THUMB, input_dev->keybit);
case GC_MULTI:
set_bit(BTN_TRIGGER, input_dev->keybit);
break;
case GC_PSX:
for (i = 0; i < 6; i++)
input_set_abs_params(input_dev, gc_psx_abs[i], 4, 252, 0, 2);
for (i = 0; i < 12; i++)
set_bit(gc_psx_btn[i], input_dev->keybit);
break;
case GC_DDR:
for (i = 0; i < 4; i++)
set_bit(gc_psx_ddr_btn[i], input_dev->keybit);
for (i = 0; i < 12; i++)
set_bit(gc_psx_btn[i], input_dev->keybit);
break;
}
return 0;
}
static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
{
struct gc *gc;
struct parport *pp;
int i, j;
if (config[0] < 0)
return NULL;
if (nargs < 2) {
printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
return NULL;
}
pp = parport_find_number(config[0]);
struct pardevice *pd;
int i;
int err;
pp = parport_find_number(parport);
if (!pp) {
printk(KERN_ERR "gamecon.c: no such parport\n");
return NULL;
err = -EINVAL;
goto err_out;
}
if (!(gc = kzalloc(sizeof(struct gc), GFP_KERNEL))) {
parport_put_port(pp);
return NULL;
pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
if (!pd) {
printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n");
err = -EBUSY;
goto err_put_pp;
}
gc = kzalloc(sizeof(struct gc), GFP_KERNEL);
if (!gc) {
printk(KERN_ERR "gamecon.c: Not enough memory\n");
err = -ENOMEM;
goto err_unreg_pardev;
}
init_MUTEX(&gc->sem);
gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
parport_put_port(pp);
if (!gc->pd) {
printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n");
kfree(gc);
return NULL;
}
parport_claim(gc->pd);
gc->pd = pd;
init_timer(&gc->timer);
gc->timer.data = (long) gc;
gc->timer.function = gc_timer;
for (i = 0; i < nargs - 1; i++) {
if (!config[i + 1])
for (i = 0; i < n_pads; i++) {
if (!pads[i])
continue;
if (config[i + 1] < 1 || config[i + 1] > GC_MAX) {
printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", config[i + 1]);
continue;
}
gc->dev[i].private = gc;
gc->dev[i].open = gc_open;
gc->dev[i].close = gc_close;
gc->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (j = 0; j < 2; j++) {
set_bit(ABS_X + j, gc->dev[i].absbit);
gc->dev[i].absmin[ABS_X + j] = -1;
gc->dev[i].absmax[ABS_X + j] = 1;
}
gc->pads[0] |= gc_status_bit[i];
gc->pads[config[i + 1]] |= gc_status_bit[i];
switch(config[i + 1]) {
case GC_N64:
for (j = 0; j < 10; j++)
set_bit(gc_n64_btn[j], gc->dev[i].keybit);
for (j = 0; j < 2; j++) {
set_bit(ABS_X + j, gc->dev[i].absbit);
gc->dev[i].absmin[ABS_X + j] = -127;
gc->dev[i].absmax[ABS_X + j] = 126;
gc->dev[i].absflat[ABS_X + j] = 2;
set_bit(ABS_HAT0X + j, gc->dev[i].absbit);
gc->dev[i].absmin[ABS_HAT0X + j] = -1;
gc->dev[i].absmax[ABS_HAT0X + j] = 1;
}
break;
case GC_SNES:
for (j = 4; j < 8; j++)
set_bit(gc_snes_btn[j], gc->dev[i].keybit);
case GC_NES:
for (j = 0; j < 4; j++)
set_bit(gc_snes_btn[j], gc->dev[i].keybit);
break;
case GC_MULTI2:
set_bit(BTN_THUMB, gc->dev[i].keybit);
case GC_MULTI:
set_bit(BTN_TRIGGER, gc->dev[i].keybit);
break;
case GC_PSX:
case GC_DDR:
if(config[i + 1] == GC_DDR) {
for (j = 0; j < 4; j++)
set_bit(gc_psx_ddr_btn[j], gc->dev[i].keybit);
} else {
for (j = 0; j < 6; j++) {
set_bit(gc_psx_abs[j], gc->dev[i].absbit);
gc->dev[i].absmin[gc_psx_abs[j]] = 4;
gc->dev[i].absmax[gc_psx_abs[j]] = 252;
gc->dev[i].absflat[gc_psx_abs[j]] = 2;
}
}
for (j = 0; j < 12; j++)
set_bit(gc_psx_btn[j], gc->dev[i].keybit);
break;
}
sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i);
err = gc_setup_pad(gc, i, pads[i]);
if (err)
goto err_free_devs;
gc->dev[i].name = gc_names[config[i + 1]];
gc->dev[i].phys = gc->phys[i];
gc->dev[i].id.bustype = BUS_PARPORT;
gc->dev[i].id.vendor = 0x0001;
gc->dev[i].id.product = config[i + 1];
gc->dev[i].id.version = 0x0100;
input_register_device(gc->dev[i]);
}
parport_release(gc->pd);
if (!gc->pads[0]) {
parport_unregister_device(gc->pd);
kfree(gc);
return NULL;
printk(KERN_ERR "gamecon.c: No valid devices specified\n");
err = -EINVAL;
goto err_free_gc;
}
for (i = 0; i < 5; i++)
if (gc->pads[0] & gc_status_bit[i]) {
input_register_device(gc->dev + i);
printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name);
}
parport_put_port(pp);
return gc;
err_free_devs:
while (--i >= 0)
input_unregister_device(gc->dev[i]);
err_free_gc:
kfree(gc);
err_unreg_pardev:
parport_unregister_device(pd);
err_put_pp:
parport_put_port(pp);
err_out:
return ERR_PTR(err);
}
static void __exit gc_remove(struct gc *gc)
{
int i;
for (i = 0; i < GC_MAX_DEVICES; i++)
if (gc->dev[i])
input_unregister_device(gc->dev[i]);
parport_unregister_device(gc->pd);
kfree(gc);
}
static int __init gc_init(void)
{
gc_base[0] = gc_probe(gc, gc_nargs);
gc_base[1] = gc_probe(gc_2, gc_nargs_2);
gc_base[2] = gc_probe(gc_3, gc_nargs_3);
int i;
int have_dev = 0;
int err = 0;
if (gc_base[0] || gc_base[1] || gc_base[2])
return 0;
for (i = 0; i < GC_MAX_PORTS; i++) {
if (gc[i].nargs == 0 || gc[i].args[0] < 0)
continue;
return -ENODEV;
if (gc[i].nargs < 2) {
printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
err = -EINVAL;
break;
}
gc_base[i] = gc_probe(gc[i].args[0], gc[i].args + 1, gc[i].nargs - 1);
if (IS_ERR(gc_base[i])) {
err = PTR_ERR(gc_base[i]);
break;
}
have_dev = 1;
}
if (err) {
while (--i >= 0)
gc_remove(gc_base[i]);
return err;
}
return have_dev ? 0 : -ENODEV;
}
static void __exit gc_exit(void)
{
int i, j;
int i;
for (i = 0; i < 3; i++)
if (gc_base[i]) {
for (j = 0; j < 5; j++)
if (gc_base[i]->pads[0] & gc_status_bit[j])
input_unregister_device(gc_base[i]->dev + j);
parport_unregister_device(gc_base[i]->pd);
}
for (i = 0; i < GC_MAX_PORTS; i++)
if (gc_base[i])
gc_remove(gc_base[i]);
}
module_init(gc_init);

View File

@ -81,7 +81,7 @@ static short gf2k_seq_digital[] = { 590, 320, 860, 0 };
struct gf2k {
struct gameport *gameport;
struct input_dev dev;
struct input_dev *dev;
int reads;
int bads;
unsigned char id;
@ -175,7 +175,7 @@ static int gf2k_get_bits(unsigned char *buf, int pos, int num, int shift)
static void gf2k_read(struct gf2k *gf2k, unsigned char *data)
{
struct input_dev *dev = &gf2k->dev;
struct input_dev *dev = gf2k->dev;
int i, t;
for (i = 0; i < 4 && i < gf2k_axes[gf2k->id]; i++)
@ -239,13 +239,19 @@ static void gf2k_close(struct input_dev *dev)
static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct gf2k *gf2k;
struct input_dev *input_dev;
unsigned char data[GF2K_LENGTH];
int i, err;
if (!(gf2k = kzalloc(sizeof(struct gf2k), GFP_KERNEL)))
return -ENOMEM;
gf2k = kzalloc(sizeof(struct gf2k), GFP_KERNEL);
input_dev = input_allocate_device();
if (!gf2k || !input_dev) {
err = -ENOMEM;
goto fail1;
}
gf2k->gameport = gameport;
gf2k->dev = input_dev;
gameport_set_drvdata(gameport, gf2k);
@ -295,53 +301,52 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
gf2k->length = gf2k_lens[gf2k->id];
init_input_dev(&gf2k->dev);
input_dev->name = gf2k_names[gf2k->id];
input_dev->phys = gf2k->phys;
input_dev->id.bustype = BUS_GAMEPORT;
input_dev->id.vendor = GAMEPORT_ID_VENDOR_GENIUS;
input_dev->id.product = gf2k->id;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &gameport->dev;
input_dev->private = gf2k;
gf2k->dev.private = gf2k;
gf2k->dev.open = gf2k_open;
gf2k->dev.close = gf2k_close;
gf2k->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
gf2k->dev.name = gf2k_names[gf2k->id];
gf2k->dev.phys = gf2k->phys;
gf2k->dev.id.bustype = BUS_GAMEPORT;
gf2k->dev.id.vendor = GAMEPORT_ID_VENDOR_GENIUS;
gf2k->dev.id.product = gf2k->id;
gf2k->dev.id.version = 0x0100;
input_dev->open = gf2k_open;
input_dev->close = gf2k_close;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < gf2k_axes[gf2k->id]; i++)
set_bit(gf2k_abs[i], gf2k->dev.absbit);
set_bit(gf2k_abs[i], input_dev->absbit);
for (i = 0; i < gf2k_hats[gf2k->id]; i++) {
set_bit(ABS_HAT0X + i, gf2k->dev.absbit);
gf2k->dev.absmin[ABS_HAT0X + i] = -1;
gf2k->dev.absmax[ABS_HAT0X + i] = 1;
set_bit(ABS_HAT0X + i, input_dev->absbit);
input_dev->absmin[ABS_HAT0X + i] = -1;
input_dev->absmax[ABS_HAT0X + i] = 1;
}
for (i = 0; i < gf2k_joys[gf2k->id]; i++)
set_bit(gf2k_btn_joy[i], gf2k->dev.keybit);
set_bit(gf2k_btn_joy[i], input_dev->keybit);
for (i = 0; i < gf2k_pads[gf2k->id]; i++)
set_bit(gf2k_btn_pad[i], gf2k->dev.keybit);
set_bit(gf2k_btn_pad[i], input_dev->keybit);
gf2k_read_packet(gameport, gf2k->length, data);
gf2k_read(gf2k, data);
for (i = 0; i < gf2k_axes[gf2k->id]; i++) {
gf2k->dev.absmax[gf2k_abs[i]] = (i < 2) ? gf2k->dev.abs[gf2k_abs[i]] * 2 - 32 :
gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
gf2k->dev.absmin[gf2k_abs[i]] = 32;
gf2k->dev.absfuzz[gf2k_abs[i]] = 8;
gf2k->dev.absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
input_dev->absmax[gf2k_abs[i]] = (i < 2) ? input_dev->abs[gf2k_abs[i]] * 2 - 32 :
input_dev->abs[gf2k_abs[0]] + input_dev->abs[gf2k_abs[1]] - 32;
input_dev->absmin[gf2k_abs[i]] = 32;
input_dev->absfuzz[gf2k_abs[i]] = 8;
input_dev->absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
}
input_register_device(&gf2k->dev);
printk(KERN_INFO "input: %s on %s\n", gf2k_names[gf2k->id], gameport->phys);
input_register_device(gf2k->dev);
return 0;
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
input_free_device(input_dev);
kfree(gf2k);
return err;
}
@ -350,7 +355,7 @@ static void gf2k_disconnect(struct gameport *gameport)
{
struct gf2k *gf2k = gameport_get_drvdata(gameport);
input_unregister_device(&gf2k->dev);
input_unregister_device(gf2k->dev);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(gf2k);

View File

@ -55,7 +55,7 @@ MODULE_LICENSE("GPL");
struct grip {
struct gameport *gameport;
struct input_dev dev[2];
struct input_dev *dev[2];
unsigned char mode[2];
int reads;
int bads;
@ -190,7 +190,7 @@ static void grip_poll(struct gameport *gameport)
for (i = 0; i < 2; i++) {
dev = grip->dev + i;
dev = grip->dev[i];
grip->reads++;
switch (grip->mode[i]) {
@ -297,6 +297,7 @@ static void grip_close(struct input_dev *dev)
static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct grip *grip;
struct input_dev *input_dev;
unsigned int data[GRIP_LENGTH_XT];
int i, j, t;
int err;
@ -339,48 +340,56 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
gameport_set_poll_handler(gameport, grip_poll);
gameport_set_poll_interval(gameport, 20);
for (i = 0; i < 2; i++)
if (grip->mode[i]) {
for (i = 0; i < 2; i++) {
if (!grip->mode[i])
continue;
sprintf(grip->phys[i], "%s/input%d", gameport->phys, i);
grip->dev[i].private = grip;
grip->dev[i].open = grip_open;
grip->dev[i].close = grip_close;
grip->dev[i].name = grip_name[grip->mode[i]];
grip->dev[i].phys = grip->phys[i];
grip->dev[i].id.bustype = BUS_GAMEPORT;
grip->dev[i].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
grip->dev[i].id.product = grip->mode[i];
grip->dev[i].id.version = 0x0100;
grip->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
if (j < grip_cen[grip->mode[i]])
input_set_abs_params(&grip->dev[i], t, 14, 52, 1, 2);
else if (j < grip_anx[grip->mode[i]])
input_set_abs_params(&grip->dev[i], t, 3, 57, 1, 0);
else
input_set_abs_params(&grip->dev[i], t, -1, 1, 0, 0);
}
for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++)
if (t > 0)
set_bit(t, grip->dev[i].keybit);
printk(KERN_INFO "input: %s on %s\n",
grip_name[grip->mode[i]], gameport->phys);
input_register_device(grip->dev + i);
grip->dev[i] = input_dev = input_allocate_device();
if (!input_dev) {
err = -ENOMEM;
goto fail3;
}
sprintf(grip->phys[i], "%s/input%d", gameport->phys, i);
input_dev->name = grip_name[grip->mode[i]];
input_dev->phys = grip->phys[i];
input_dev->id.bustype = BUS_GAMEPORT;
input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
input_dev->id.product = grip->mode[i];
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &gameport->dev;
input_dev->private = grip;
input_dev->open = grip_open;
input_dev->close = grip_close;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
if (j < grip_cen[grip->mode[i]])
input_set_abs_params(input_dev, t, 14, 52, 1, 2);
else if (j < grip_anx[grip->mode[i]])
input_set_abs_params(input_dev, t, 3, 57, 1, 0);
else
input_set_abs_params(input_dev, t, -1, 1, 0, 0);
}
for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++)
if (t > 0)
set_bit(t, input_dev->keybit);
input_register_device(grip->dev[i]);
}
return 0;
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
fail3: for (i = 0; i < 2; i++)
if (grip->dev[i])
input_unregister_device(grip->dev[i]);
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
kfree(grip);
return err;
}
@ -391,8 +400,8 @@ static void grip_disconnect(struct gameport *gameport)
int i;
for (i = 0; i < 2; i++)
if (grip->mode[i])
input_unregister_device(grip->dev + i);
if (grip->dev[i])
input_unregister_device(grip->dev[i]);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(grip);

View File

@ -32,23 +32,37 @@ MODULE_LICENSE("GPL");
#define dbg(format, arg...) do {} while (0)
#endif
#define GRIP_MAX_PORTS 4
/*
* Grip multiport state
*/
struct grip_port {
struct input_dev *dev;
int mode;
int registered;
/* individual gamepad states */
int buttons;
int xaxes;
int yaxes;
int dirty; /* has the state been updated? */
};
struct grip_mp {
struct gameport *gameport;
struct input_dev dev[4];
int mode[4];
int registered[4];
struct grip_port *port[GRIP_MAX_PORTS];
// struct input_dev *dev[4];
// int mode[4];
// int registered[4];
int reads;
int bads;
/* individual gamepad states */
int buttons[4];
int xaxes[4];
int yaxes[4];
int dirty[4]; /* has the state been updated? */
// int buttons[4];
// int xaxes[4];
// int yaxes[4];
// int dirty[4]; /* has the state been updated? */
};
/*
@ -85,16 +99,16 @@ struct grip_mp {
#define GRIP_MODE_GP 2
#define GRIP_MODE_C64 3
static int grip_btn_gp[] = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
static int grip_btn_c64[] = { BTN_JOYSTICK, -1 };
static const int grip_btn_gp[] = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
static const int grip_btn_c64[] = { BTN_JOYSTICK, -1 };
static int grip_abs_gp[] = { ABS_X, ABS_Y, -1 };
static int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };
static const int grip_abs_gp[] = { ABS_X, ABS_Y, -1 };
static const int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };
static int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
static int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };
static const int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
static const int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };
static char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };
static const char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };
static const int init_seq[] = {
1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
@ -104,9 +118,9 @@ static const int init_seq[] = {
/* Maps multiport directional values to X,Y axis values (each axis encoded in 3 bits) */
static int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };
static const int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };
static void register_slot(int i, struct grip_mp *grip);
static int register_slot(int i, struct grip_mp *grip);
/*
* Returns whether an odd or even number of bits are on in pkt.
@ -353,9 +367,10 @@ static int dig_mode_start(struct gameport *gameport, u32 *packet)
static int get_and_decode_packet(struct grip_mp *grip, int flags)
{
struct grip_port *port;
u32 packet;
int joytype = 0;
int slot = 0;
int slot;
/* Get a packet and check for validity */
@ -377,6 +392,8 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags)
if ((slot < 0) || (slot > 3))
return flags;
port = grip->port[slot];
/*
* Handle "reset" packets, which occur at startup, and when gamepads
* are removed or plugged in. May contain configuration of a new gamepad.
@ -385,14 +402,14 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags)
joytype = (packet >> 16) & 0x1f;
if (!joytype) {
if (grip->registered[slot]) {
if (port->registered) {
printk(KERN_INFO "grip_mp: removing %s, slot %d\n",
grip_name[grip->mode[slot]], slot);
input_unregister_device(grip->dev + slot);
grip->registered[slot] = 0;
grip_name[port->mode], slot);
input_unregister_device(port->dev);
port->registered = 0;
}
dbg("Reset: grip multiport slot %d\n", slot);
grip->mode[slot] = GRIP_MODE_RESET;
port->mode = GRIP_MODE_RESET;
flags |= IO_SLOT_CHANGE;
return flags;
}
@ -402,17 +419,17 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags)
if (joytype == 0x1f) {
int dir = (packet >> 8) & 0xf; /* eight way directional value */
grip->buttons[slot] = (~packet) & 0xff;
grip->yaxes[slot] = ((axis_map[dir] >> 2) & 3) - 1;
grip->xaxes[slot] = (axis_map[dir] & 3) - 1;
grip->dirty[slot] = 1;
port->buttons = (~packet) & 0xff;
port->yaxes = ((axis_map[dir] >> 2) & 3) - 1;
port->xaxes = (axis_map[dir] & 3) - 1;
port->dirty = 1;
if (grip->mode[slot] == GRIP_MODE_RESET)
if (port->mode == GRIP_MODE_RESET)
flags |= IO_SLOT_CHANGE;
grip->mode[slot] = GRIP_MODE_GP;
port->mode = GRIP_MODE_GP;
if (!grip->registered[slot]) {
if (!port->registered) {
dbg("New Grip pad in multiport slot %d.\n", slot);
register_slot(slot, grip);
}
@ -445,9 +462,9 @@ static int slots_valid(struct grip_mp *grip)
return 0;
for (slot = 0; slot < 4; slot++) {
if (grip->mode[slot] == GRIP_MODE_RESET)
if (grip->port[slot]->mode == GRIP_MODE_RESET)
invalid = 1;
if (grip->mode[slot] != GRIP_MODE_NONE)
if (grip->port[slot]->mode != GRIP_MODE_NONE)
active = 1;
}
@ -484,7 +501,7 @@ static int multiport_init(struct grip_mp *grip)
/* Get packets, store multiport state, and check state's validity */
for (tries = 0; tries < 4096; tries++) {
if ( slots_valid(grip) ) {
if (slots_valid(grip)) {
initialized = 1;
break;
}
@ -499,24 +516,24 @@ static int multiport_init(struct grip_mp *grip)
static void report_slot(struct grip_mp *grip, int slot)
{
struct input_dev *dev = &(grip->dev[slot]);
int i, buttons = grip->buttons[slot];
struct grip_port *port = grip->port[slot];
int i;
/* Store button states with linux input driver */
for (i = 0; i < 8; i++)
input_report_key(dev, grip_btn_gp[i], (buttons >> i) & 1);
input_report_key(port->dev, grip_btn_gp[i], (port->buttons >> i) & 1);
/* Store axis states with linux driver */
input_report_abs(dev, ABS_X, grip->xaxes[slot]);
input_report_abs(dev, ABS_Y, grip->yaxes[slot]);
input_report_abs(port->dev, ABS_X, port->xaxes);
input_report_abs(port->dev, ABS_Y, port->yaxes);
/* Tell the receiver of the events to process them */
input_sync(dev);
input_sync(port->dev);
grip->dirty[slot] = 0;
port->dirty = 0;
}
/*
@ -540,7 +557,7 @@ static void grip_poll(struct gameport *gameport)
}
for (i = 0; i < 4; i++)
if (grip->dirty[i])
if (grip->port[i]->dirty)
report_slot(grip, i);
}
@ -571,35 +588,43 @@ static void grip_close(struct input_dev *dev)
* Tell the linux input layer about a newly plugged-in gamepad.
*/
static void register_slot(int slot, struct grip_mp *grip)
static int register_slot(int slot, struct grip_mp *grip)
{
struct grip_port *port = grip->port[slot];
struct input_dev *input_dev;
int j, t;
grip->dev[slot].private = grip;
grip->dev[slot].open = grip_open;
grip->dev[slot].close = grip_close;
grip->dev[slot].name = grip_name[grip->mode[slot]];
grip->dev[slot].id.bustype = BUS_GAMEPORT;
grip->dev[slot].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
grip->dev[slot].id.product = 0x0100 + grip->mode[slot];
grip->dev[slot].id.version = 0x0100;
grip->dev[slot].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
port->dev = input_dev = input_allocate_device();
if (!input_dev)
return -ENOMEM;
for (j = 0; (t = grip_abs[grip->mode[slot]][j]) >= 0; j++)
input_set_abs_params(&grip->dev[slot], t, -1, 1, 0, 0);
input_dev->name = grip_name[port->mode];
input_dev->id.bustype = BUS_GAMEPORT;
input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
input_dev->id.product = 0x0100 + port->mode;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &grip->gameport->dev;
input_dev->private = grip;
for (j = 0; (t = grip_btn[grip->mode[slot]][j]) >= 0; j++)
input_dev->open = grip_open;
input_dev->close = grip_close;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++)
input_set_abs_params(input_dev, t, -1, 1, 0, 0);
for (j = 0; (t = grip_btn[port->mode][j]) >= 0; j++)
if (t > 0)
set_bit(t, grip->dev[slot].keybit);
set_bit(t, input_dev->keybit);
input_register_device(grip->dev + slot);
grip->registered[slot] = 1;
input_register_device(port->dev);
port->registered = 1;
if (grip->dirty[slot]) /* report initial state, if any */
if (port->dirty) /* report initial state, if any */
report_slot(grip, slot);
printk(KERN_INFO "grip_mp: added %s, slot %d\n",
grip_name[grip->mode[slot]], slot);
return 0;
}
static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
@ -626,7 +651,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
goto fail2;
}
if (!grip->mode[0] && !grip->mode[1] && !grip->mode[2] && !grip->mode[3]) {
if (!grip->port[0]->mode && !grip->port[1]->mode && !grip->port[2]->mode && !grip->port[3]->mode) {
/* nothing plugged in */
err = -ENODEV;
goto fail2;
@ -646,8 +671,8 @@ static void grip_disconnect(struct gameport *gameport)
int i;
for (i = 0; i < 4; i++)
if (grip->registered[i])
input_unregister_device(grip->dev + i);
if (grip->port[i]->registered)
input_unregister_device(grip->port[i]->dev);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(grip);

View File

@ -67,7 +67,7 @@ struct guillemot_type {
struct guillemot {
struct gameport *gameport;
struct input_dev dev;
struct input_dev *dev;
int bads;
int reads;
struct guillemot_type *type;
@ -123,7 +123,7 @@ static int guillemot_read_packet(struct gameport *gameport, u8 *data)
static void guillemot_poll(struct gameport *gameport)
{
struct guillemot *guillemot = gameport_get_drvdata(gameport);
struct input_dev *dev = &guillemot->dev;
struct input_dev *dev = guillemot->dev;
u8 data[GUILLEMOT_MAX_LENGTH];
int i;
@ -179,14 +179,20 @@ static void guillemot_close(struct input_dev *dev)
static int guillemot_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct guillemot *guillemot;
struct input_dev *input_dev;
u8 data[GUILLEMOT_MAX_LENGTH];
int i, t;
int err;
if (!(guillemot = kzalloc(sizeof(struct guillemot), GFP_KERNEL)))
return -ENOMEM;
guillemot = kzalloc(sizeof(struct guillemot), GFP_KERNEL);
input_dev = input_allocate_device();
if (!guillemot || !input_dev) {
err = -ENOMEM;
goto fail1;
}
guillemot->gameport = gameport;
guillemot->dev = input_dev;
gameport_set_drvdata(gameport, guillemot);
@ -216,41 +222,40 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver *
gameport_set_poll_interval(gameport, 20);
sprintf(guillemot->phys, "%s/input0", gameport->phys);
guillemot->type = guillemot_type + i;
guillemot->dev.private = guillemot;
guillemot->dev.open = guillemot_open;
guillemot->dev.close = guillemot_close;
input_dev->name = guillemot_type[i].name;
input_dev->phys = guillemot->phys;
input_dev->id.bustype = BUS_GAMEPORT;
input_dev->id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT;
input_dev->id.product = guillemot_type[i].id;
input_dev->id.version = (int)data[14] << 8 | data[15];
input_dev->cdev.dev = &gameport->dev;
input_dev->private = guillemot;
guillemot->dev.name = guillemot_type[i].name;
guillemot->dev.phys = guillemot->phys;
guillemot->dev.id.bustype = BUS_GAMEPORT;
guillemot->dev.id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT;
guillemot->dev.id.product = guillemot_type[i].id;
guillemot->dev.id.version = (int)data[14] << 8 | data[15];
input_dev->open = guillemot_open;
input_dev->close = guillemot_close;
guillemot->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++)
input_set_abs_params(&guillemot->dev, t, 0, 255, 0, 0);
input_set_abs_params(input_dev, t, 0, 255, 0, 0);
if (guillemot->type->hat) {
input_set_abs_params(&guillemot->dev, ABS_HAT0X, -1, 1, 0, 0);
input_set_abs_params(&guillemot->dev, ABS_HAT0Y, -1, 1, 0, 0);
input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
input_set_abs_params(input_dev, ABS_HAT0Y, -1, 1, 0, 0);
}
for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++)
set_bit(t, guillemot->dev.keybit);
set_bit(t, input_dev->keybit);
input_register_device(&guillemot->dev);
printk(KERN_INFO "input: %s ver %d.%02d on %s\n",
guillemot->type->name, data[14], data[15], gameport->phys);
input_register_device(guillemot->dev);
return 0;
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
input_free_device(input_dev);
kfree(guillemot);
return err;
}
@ -260,7 +265,7 @@ static void guillemot_disconnect(struct gameport *gameport)
struct guillemot *guillemot = gameport_get_drvdata(gameport);
printk(KERN_INFO "guillemot.c: Failed %d reads out of %d on %s\n", guillemot->reads, guillemot->bads, guillemot->phys);
input_unregister_device(&guillemot->dev);
input_unregister_device(guillemot->dev);
gameport_close(gameport);
kfree(guillemot);
}

View File

@ -144,7 +144,7 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
int is_update;
/* Check this effect type is supported by this device */
if (!test_bit(effect->type, iforce->dev.ffbit))
if (!test_bit(effect->type, iforce->dev->ffbit))
return -EINVAL;
/*
@ -152,30 +152,31 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
*/
if (effect->id == -1) {
for (id=0; id < FF_EFFECTS_MAX; ++id)
if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags)) break;
for (id = 0; id < FF_EFFECTS_MAX; ++id)
if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags))
break;
if ( id == FF_EFFECTS_MAX || id >= iforce->dev.ff_effects_max)
if (id == FF_EFFECTS_MAX || id >= iforce->dev->ff_effects_max)
return -ENOMEM;
effect->id = id;
iforce->core_effects[id].owner = current->pid;
iforce->core_effects[id].flags[0] = (1<<FF_CORE_IS_USED); /* Only IS_USED bit must be set */
iforce->core_effects[id].flags[0] = (1 << FF_CORE_IS_USED); /* Only IS_USED bit must be set */
is_update = FALSE;
}
else {
/* We want to update an effect */
if (!CHECK_OWNERSHIP(effect->id, iforce)) return -EACCES;
if (!CHECK_OWNERSHIP(effect->id, iforce))
return -EACCES;
/* Parameter type cannot be updated */
if (effect->type != iforce->core_effects[effect->id].effect.type)
return -EINVAL;
/* Check the effect is not already being updated */
if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags)) {
if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags))
return -EAGAIN;
}
is_update = TRUE;
}
@ -339,15 +340,19 @@ void iforce_delete_device(struct iforce *iforce)
int iforce_init_device(struct iforce *iforce)
{
struct input_dev *input_dev;
unsigned char c[] = "CEOV";
int i;
input_dev = input_allocate_device();
if (input_dev)
return -ENOMEM;
init_waitqueue_head(&iforce->wait);
spin_lock_init(&iforce->xmit_lock);
init_MUTEX(&iforce->mem_mutex);
iforce->xmit.buf = iforce->xmit_data;
iforce->dev.ff_effects_max = 10;
iforce->dev = input_dev;
/*
* Input device fields.
@ -356,26 +361,27 @@ int iforce_init_device(struct iforce *iforce)
switch (iforce->bus) {
#ifdef CONFIG_JOYSTICK_IFORCE_USB
case IFORCE_USB:
iforce->dev.id.bustype = BUS_USB;
iforce->dev.dev = &iforce->usbdev->dev;
input_dev->id.bustype = BUS_USB;
input_dev->cdev.dev = &iforce->usbdev->dev;
break;
#endif
#ifdef CONFIG_JOYSTICK_IFORCE_232
case IFORCE_232:
iforce->dev.id.bustype = BUS_RS232;
iforce->dev.dev = &iforce->serio->dev;
input_dev->id.bustype = BUS_RS232;
input_dev->cdev.dev = &iforce->serio->dev;
break;
#endif
}
iforce->dev.private = iforce;
iforce->dev.name = "Unknown I-Force device";
iforce->dev.open = iforce_open;
iforce->dev.close = iforce_release;
iforce->dev.flush = iforce_flush;
iforce->dev.event = iforce_input_event;
iforce->dev.upload_effect = iforce_upload_effect;
iforce->dev.erase_effect = iforce_erase_effect;
input_dev->private = iforce;
input_dev->name = "Unknown I-Force device";
input_dev->open = iforce_open;
input_dev->close = iforce_release;
input_dev->flush = iforce_flush;
input_dev->event = iforce_input_event;
input_dev->upload_effect = iforce_upload_effect;
input_dev->erase_effect = iforce_erase_effect;
input_dev->ff_effects_max = 10;
/*
* On-device memory allocation.
@ -399,7 +405,8 @@ int iforce_init_device(struct iforce *iforce)
if (i == 20) { /* 5 seconds */
printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n");
return -1;
input_free_device(input_dev);
return -ENODEV;
}
/*
@ -407,12 +414,12 @@ int iforce_init_device(struct iforce *iforce)
*/
if (!iforce_get_id_packet(iforce, "M"))
iforce->dev.id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
else
printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet M\n");
if (!iforce_get_id_packet(iforce, "P"))
iforce->dev.id.product = (iforce->edata[2] << 8) | iforce->edata[1];
input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1];
else
printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet P\n");
@ -422,15 +429,15 @@ int iforce_init_device(struct iforce *iforce)
printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n");
if (!iforce_get_id_packet(iforce, "N"))
iforce->dev.ff_effects_max = iforce->edata[1];
iforce->dev->ff_effects_max = iforce->edata[1];
else
printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n");
/* Check if the device can store more effects than the driver can really handle */
if (iforce->dev.ff_effects_max > FF_EFFECTS_MAX) {
if (iforce->dev->ff_effects_max > FF_EFFECTS_MAX) {
printk(KERN_WARNING "input??: Device can handle %d effects, but N_EFFECTS_MAX is set to %d in iforce.h\n",
iforce->dev.ff_effects_max, FF_EFFECTS_MAX);
iforce->dev.ff_effects_max = FF_EFFECTS_MAX;
iforce->dev->ff_effects_max, FF_EFFECTS_MAX);
iforce->dev->ff_effects_max = FF_EFFECTS_MAX;
}
/*
@ -453,29 +460,28 @@ int iforce_init_device(struct iforce *iforce)
*/
for (i = 0; iforce_device[i].idvendor; i++)
if (iforce_device[i].idvendor == iforce->dev.id.vendor &&
iforce_device[i].idproduct == iforce->dev.id.product)
if (iforce_device[i].idvendor == input_dev->id.vendor &&
iforce_device[i].idproduct == input_dev->id.product)
break;
iforce->type = iforce_device + i;
iforce->dev.name = iforce->type->name;
input_dev->name = iforce->type->name;
/*
* Set input device bitfields and ranges.
*/
iforce->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
for (i = 0; iforce->type->btn[i] >= 0; i++) {
signed short t = iforce->type->btn[i];
set_bit(t, iforce->dev.keybit);
set_bit(t, input_dev->keybit);
}
set_bit(BTN_DEAD, iforce->dev.keybit);
set_bit(BTN_DEAD, input_dev->keybit);
for (i = 0; iforce->type->abs[i] >= 0; i++) {
signed short t = iforce->type->abs[i];
set_bit(t, iforce->dev.absbit);
switch (t) {
@ -483,52 +489,42 @@ int iforce_init_device(struct iforce *iforce)
case ABS_Y:
case ABS_WHEEL:
iforce->dev.absmax[t] = 1920;
iforce->dev.absmin[t] = -1920;
iforce->dev.absflat[t] = 128;
iforce->dev.absfuzz[t] = 16;
set_bit(t, iforce->dev.ffbit);
input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
set_bit(t, input_dev->ffbit);
break;
case ABS_THROTTLE:
case ABS_GAS:
case ABS_BRAKE:
iforce->dev.absmax[t] = 255;
iforce->dev.absmin[t] = 0;
input_set_abs_params(input_dev, t, 0, 255, 0, 0);
break;
case ABS_RUDDER:
iforce->dev.absmax[t] = 127;
iforce->dev.absmin[t] = -128;
input_set_abs_params(input_dev, t, -128, 127, 0, 0);
break;
case ABS_HAT0X:
case ABS_HAT0Y:
case ABS_HAT1X:
case ABS_HAT1Y:
iforce->dev.absmax[t] = 1;
iforce->dev.absmin[t] = -1;
input_set_abs_params(input_dev, t, -1, 1, 0, 0);
break;
}
}
for (i = 0; iforce->type->ff[i] >= 0; i++)
set_bit(iforce->type->ff[i], iforce->dev.ffbit);
set_bit(iforce->type->ff[i], input_dev->ffbit);
/*
* Register input device.
*/
input_register_device(&iforce->dev);
input_register_device(iforce->dev);
printk(KERN_DEBUG "iforce->dev.open = %p\n", iforce->dev.open);
printk(KERN_INFO "input: %s [%d effects, %ld bytes memory]\n",
iforce->dev.name, iforce->dev.ff_effects_max,
iforce->device_memory.end);
printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open);
return 0;
}

View File

@ -139,7 +139,8 @@ printk(KERN_DEBUG "iforce-packets.c: control_playback %d %d\n", id, value);
static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
{
int i;
for (i=0; i<iforce->dev.ff_effects_max; ++i) {
for (i = 0; i < iforce->dev->ff_effects_max; ++i) {
if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
(iforce->core_effects[i].mod1_chunk.start == addr ||
iforce->core_effects[i].mod2_chunk.start == addr)) {
@ -153,7 +154,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs)
{
struct input_dev *dev = &iforce->dev;
struct input_dev *dev = iforce->dev;
int i;
static int being_used = 0;

View File

@ -131,11 +131,10 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
struct iforce *iforce;
int err;
if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL)))
iforce = kzalloc(sizeof(struct iforce), GFP_KERNEL);
if (!iforce)
return -ENOMEM;
memset(iforce, 0, sizeof(struct iforce));
iforce->bus = IFORCE_232;
iforce->serio = serio;
@ -148,7 +147,8 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
return err;
}
if (iforce_init_device(iforce)) {
err = iforce_init_device(iforce);
if (err) {
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(iforce);
@ -162,7 +162,7 @@ static void iforce_serio_disconnect(struct serio *serio)
{
struct iforce *iforce = serio_get_drvdata(serio);
input_unregister_device(&iforce->dev);
input_unregister_device(iforce->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(iforce);

View File

@ -135,28 +135,24 @@ static int iforce_usb_probe(struct usb_interface *intf,
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *epirq, *epout;
struct iforce *iforce;
int err = -ENOMEM;
interface = intf->cur_altsetting;
epirq = &interface->endpoint[0].desc;
epout = &interface->endpoint[1].desc;
if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
if (!(iforce = kzalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
goto fail;
memset(iforce, 0, sizeof(struct iforce));
if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL))) {
if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
}
if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL))) {
if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
}
if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL))) {
if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
}
iforce->bus = IFORCE_USB;
iforce->usbdev = dev;
@ -174,7 +170,9 @@ static int iforce_usb_probe(struct usb_interface *intf,
usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
(void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce);
if (iforce_init_device(iforce)) goto fail;
err = iforce_init_device(iforce);
if (err)
goto fail;
usb_set_intfdata(intf, iforce);
return 0;
@ -187,7 +185,7 @@ fail:
kfree(iforce);
}
return -ENODEV;
return err;
}
/* Called by iforce_delete() */
@ -211,7 +209,7 @@ static void iforce_usb_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
if (iforce) {
iforce->usbdev = NULL;
input_unregister_device(&iforce->dev);
input_unregister_device(iforce->dev);
if (!open) {
iforce_delete_device(iforce);

View File

@ -117,7 +117,7 @@ struct iforce_device {
};
struct iforce {
struct input_dev dev; /* Input device interface */
struct input_dev *dev; /* Input device interface */
struct iforce_device *type;
int bus;

View File

@ -54,7 +54,7 @@ MODULE_LICENSE("GPL");
struct interact {
struct gameport *gameport;
struct input_dev dev;
struct input_dev *dev;
int bads;
int reads;
unsigned char type;
@ -130,7 +130,7 @@ static int interact_read_packet(struct gameport *gameport, int length, u32 *data
static void interact_poll(struct gameport *gameport)
{
struct interact *interact = gameport_get_drvdata(gameport);
struct input_dev *dev = &interact->dev;
struct input_dev *dev = interact->dev;
u32 data[3];
int i;
@ -208,14 +208,20 @@ static void interact_close(struct input_dev *dev)
static int interact_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct interact *interact;
struct input_dev *input_dev;
__u32 data[3];
int i, t;
int err;
if (!(interact = kzalloc(sizeof(struct interact), GFP_KERNEL)))
return -ENOMEM;
interact = kzalloc(sizeof(struct interact), GFP_KERNEL);
input_dev = input_allocate_device();
if (!interact || !input_dev) {
err = -ENOMEM;
goto fail1;
}
interact->gameport = gameport;
interact->dev = input_dev;
gameport_set_drvdata(gameport, interact);
@ -249,41 +255,40 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d
interact->type = i;
interact->length = interact_type[i].length;
interact->dev.private = interact;
interact->dev.open = interact_open;
interact->dev.close = interact_close;
input_dev->name = interact_type[i].name;
input_dev->phys = interact->phys;
input_dev->id.bustype = BUS_GAMEPORT;
input_dev->id.vendor = GAMEPORT_ID_VENDOR_INTERACT;
input_dev->id.product = interact_type[i].id;
input_dev->id.version = 0x0100;
input_dev->private = interact;
interact->dev.name = interact_type[i].name;
interact->dev.phys = interact->phys;
interact->dev.id.bustype = BUS_GAMEPORT;
interact->dev.id.vendor = GAMEPORT_ID_VENDOR_INTERACT;
interact->dev.id.product = interact_type[i].id;
interact->dev.id.version = 0x0100;
input_dev->open = interact_open;
input_dev->close = interact_close;
interact->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) {
set_bit(t, interact->dev.absbit);
set_bit(t, input_dev->absbit);
if (i < interact_type[interact->type].b8) {
interact->dev.absmin[t] = 0;
interact->dev.absmax[t] = 255;
input_dev->absmin[t] = 0;
input_dev->absmax[t] = 255;
} else {
interact->dev.absmin[t] = -1;
interact->dev.absmax[t] = 1;
input_dev->absmin[t] = -1;
input_dev->absmax[t] = 1;
}
}
for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++)
set_bit(t, interact->dev.keybit);
set_bit(t, input_dev->keybit);
input_register_device(&interact->dev);
printk(KERN_INFO "input: %s on %s\n",
interact_type[interact->type].name, gameport->phys);
input_register_device(interact->dev);
return 0;
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
input_free_device(input_dev);
kfree(interact);
return err;
}
@ -292,7 +297,7 @@ static void interact_disconnect(struct gameport *gameport)
{
struct interact *interact = gameport_get_drvdata(gameport);
input_unregister_device(&interact->dev);
input_unregister_device(interact->dev);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(interact);

View File

@ -49,14 +49,13 @@ MODULE_LICENSE("GPL");
static int magellan_buttons[] = { BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8 };
static int magellan_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ };
static char *magellan_name = "LogiCad3D Magellan / SpaceMouse";
/*
* Per-Magellan data.
*/
struct magellan {
struct input_dev dev;
struct input_dev *dev;
int idx;
unsigned char data[MAGELLAN_MAX_LENGTH];
char phys[32];
@ -85,7 +84,7 @@ static int magellan_crunch_nibbles(unsigned char *data, int count)
static void magellan_process_packet(struct magellan* magellan, struct pt_regs *regs)
{
struct input_dev *dev = &magellan->dev;
struct input_dev *dev = magellan->dev;
unsigned char *data = magellan->data;
int i, t;
@ -138,9 +137,9 @@ static void magellan_disconnect(struct serio *serio)
{
struct magellan* magellan = serio_get_drvdata(serio);
input_unregister_device(&magellan->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
input_unregister_device(magellan->dev);
kfree(magellan);
}
@ -153,52 +152,48 @@ static void magellan_disconnect(struct serio *serio)
static int magellan_connect(struct serio *serio, struct serio_driver *drv)
{
struct magellan *magellan;
int i, t;
int err;
struct input_dev *input_dev;
int err = -ENOMEM;
int i;
if (!(magellan = kmalloc(sizeof(struct magellan), GFP_KERNEL)))
return -ENOMEM;
memset(magellan, 0, sizeof(struct magellan));
magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < 9; i++)
set_bit(magellan_buttons[i], magellan->dev.keybit);
for (i = 0; i < 6; i++) {
t = magellan_axes[i];
set_bit(t, magellan->dev.absbit);
magellan->dev.absmin[t] = -360;
magellan->dev.absmax[t] = 360;
}
magellan = kzalloc(sizeof(struct magellan), GFP_KERNEL);
input_dev = input_allocate_device();
if (!magellan || !input_dev)
goto fail;
magellan->dev = input_dev;
sprintf(magellan->phys, "%s/input0", serio->phys);
init_input_dev(&magellan->dev);
magellan->dev.private = magellan;
magellan->dev.name = magellan_name;
magellan->dev.phys = magellan->phys;
magellan->dev.id.bustype = BUS_RS232;
magellan->dev.id.vendor = SERIO_MAGELLAN;
magellan->dev.id.product = 0x0001;
magellan->dev.id.version = 0x0100;
magellan->dev.dev = &serio->dev;
input_dev->name = "LogiCad3D Magellan / SpaceMouse";
input_dev->phys = magellan->phys;
input_dev->id.bustype = BUS_RS232;
input_dev->id.vendor = SERIO_MAGELLAN;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &serio->dev;
input_dev->private = magellan;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < 9; i++)
set_bit(magellan_buttons[i], input_dev->keybit);
for (i = 0; i < 6; i++)
input_set_abs_params(input_dev, magellan_axes[i], -360, 360, 0, 0);
serio_set_drvdata(serio, magellan);
err = serio_open(serio, drv);
if (err) {
serio_set_drvdata(serio, NULL);
kfree(magellan);
return err;
}
input_register_device(&magellan->dev);
printk(KERN_INFO "input: %s on %s\n", magellan_name, serio->phys);
if (err)
goto fail;
input_register_device(magellan->dev);
return 0;
fail: serio_set_drvdata(serio, NULL);
input_free_device(input_dev);
kfree(magellan);
return err;
}
/*

View File

@ -113,7 +113,7 @@ static struct {
struct sw {
struct gameport *gameport;
struct input_dev dev[4];
struct input_dev *dev[4];
char name[64];
char phys[4][32];
int length;
@ -301,7 +301,7 @@ static int sw_check(__u64 t)
static int sw_parse(unsigned char *buf, struct sw *sw)
{
int hat, i, j;
struct input_dev *dev = sw->dev;
struct input_dev *dev;
switch (sw->type) {
@ -310,6 +310,8 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
if (sw_check(GB(0,64)) || (hat = (GB(6,1) << 3) | GB(60,3)) > 8)
return -1;
dev = sw->dev[0];
input_report_abs(dev, ABS_X, (GB( 3,3) << 7) | GB(16,7));
input_report_abs(dev, ABS_Y, (GB( 0,3) << 7) | GB(24,7));
input_report_abs(dev, ABS_RZ, (GB(35,2) << 7) | GB(40,7));
@ -335,13 +337,13 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
if (sw_parity(GB(i*15,15)))
return -1;
input_report_abs(dev + i, ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
input_report_abs(dev + i, ABS_Y, GB(i*15+0,1) - GB(i*15+1,1));
input_report_abs(sw->dev[i], ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
input_report_abs(sw->dev[i], ABS_Y, GB(i*15+0,1) - GB(i*15+1,1));
for (j = 0; j < 10; j++)
input_report_key(dev + i, sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1));
input_report_key(sw->dev[i], sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1));
input_sync(dev + i);
input_sync(sw->dev[i]);
}
return 0;
@ -352,6 +354,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8)
return -1;
dev = sw->dev[0];
input_report_abs(dev, ABS_X, GB( 9,10));
input_report_abs(dev, ABS_Y, GB(19,10));
input_report_abs(dev, ABS_RZ, GB(36, 6));
@ -372,6 +375,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8)
return -1;
dev = sw->dev[0];
input_report_abs(dev, ABS_X, GB( 0,10));
input_report_abs(dev, ABS_Y, GB(16,10));
input_report_abs(dev, ABS_THROTTLE, GB(32, 6));
@ -396,6 +400,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
if (!sw_parity(GB(0,33)))
return -1;
dev = sw->dev[0];
input_report_abs(dev, ABS_RX, GB( 0,10));
input_report_abs(dev, ABS_RUDDER, GB(10, 6));
input_report_abs(dev, ABS_THROTTLE, GB(16, 6));
@ -581,6 +586,7 @@ static int sw_guess_mode(unsigned char *buf, int len)
static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct sw *sw;
struct input_dev *input_dev;
int i, j, k, l;
int err;
unsigned char *buf = NULL; /* [SW_LENGTH] */
@ -729,42 +735,50 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]);
sprintf(sw->phys[i], "%s/input%d", gameport->phys, i);
sw->dev[i].private = sw;
input_dev = input_allocate_device();
if (!input_dev) {
err = -ENOMEM;
goto fail3;
}
sw->dev[i].open = sw_open;
sw->dev[i].close = sw_close;
input_dev->name = sw->name;
input_dev->phys = sw->phys[i];
input_dev->id.bustype = BUS_GAMEPORT;
input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT;
input_dev->id.product = sw->type;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &gameport->dev;
input_dev->private = sw;
sw->dev[i].name = sw->name;
sw->dev[i].phys = sw->phys[i];
sw->dev[i].id.bustype = BUS_GAMEPORT;
sw->dev[i].id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT;
sw->dev[i].id.product = sw->type;
sw->dev[i].id.version = 0x0100;
input_dev->open = sw_open;
input_dev->close = sw_close;
sw->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (j = 0; (bits = sw_bit[sw->type][j]); j++) {
code = sw_abs[sw->type][j];
set_bit(code, sw->dev[i].absbit);
sw->dev[i].absmax[code] = (1 << bits) - 1;
sw->dev[i].absmin[code] = (bits == 1) ? -1 : 0;
sw->dev[i].absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0;
set_bit(code, input_dev->absbit);
input_dev->absmax[code] = (1 << bits) - 1;
input_dev->absmin[code] = (bits == 1) ? -1 : 0;
input_dev->absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0;
if (code != ABS_THROTTLE)
sw->dev[i].absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0;
input_dev->absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0;
}
for (j = 0; (code = sw_btn[sw->type][j]); j++)
set_bit(code, sw->dev[i].keybit);
set_bit(code, input_dev->keybit);
input_register_device(sw->dev + i);
printk(KERN_INFO "input: %s%s on %s [%d-bit id %d data %d]\n",
sw->name, comment, gameport->phys, m, l, k);
dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k);
input_register_device(sw->dev[i]);
}
return 0;
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
fail3: while (--i >= 0)
input_unregister_device(sw->dev[i]);
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
kfree(sw);
kfree(buf);
kfree(idbuf);
@ -777,7 +791,7 @@ static void sw_disconnect(struct gameport *gameport)
int i;
for (i = 0; i < sw->number; i++)
input_unregister_device(sw->dev + i);
input_unregister_device(sw->dev[i]);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(sw);

View File

@ -70,8 +70,7 @@ static char *spaceball_names[] = {
*/
struct spaceball {
struct input_dev dev;
struct serio *serio;
struct input_dev *dev;
int idx;
int escape;
unsigned char data[SPACEBALL_MAX_LENGTH];
@ -85,7 +84,7 @@ struct spaceball {
static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs *regs)
{
struct input_dev *dev = &spaceball->dev;
struct input_dev *dev = spaceball->dev;
unsigned char *data = spaceball->data;
int i;
@ -193,9 +192,9 @@ static void spaceball_disconnect(struct serio *serio)
{
struct spaceball* spaceball = serio_get_drvdata(serio);
input_unregister_device(&spaceball->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
input_unregister_device(spaceball->dev);
kfree(spaceball);
}
@ -208,69 +207,62 @@ static void spaceball_disconnect(struct serio *serio)
static int spaceball_connect(struct serio *serio, struct serio_driver *drv)
{
struct spaceball *spaceball;
int i, t, id;
int err;
struct input_dev *input_dev;
int err = -ENOMEM;
int i, id;
if ((id = serio->id.id) > SPACEBALL_MAX_ID)
return -ENODEV;
if (!(spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL)))
return - ENOMEM;
spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL);
input_dev = input_allocate_device();
if (!spaceball || !input_dev)
goto fail;
memset(spaceball, 0, sizeof(struct spaceball));
spaceball->dev = input_dev;
sprintf(spaceball->phys, "%s/input0", serio->phys);
spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->name = spaceball_names[id];
input_dev->phys = spaceball->phys;
input_dev->id.bustype = BUS_RS232;
input_dev->id.vendor = SERIO_SPACEBALL;
input_dev->id.product = id;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &serio->dev;
input_dev->private = spaceball;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
switch (id) {
case SPACEBALL_4000FLX:
case SPACEBALL_4000FLX_L:
spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_9);
spaceball->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_9);
input_dev->keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
default:
spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
| BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8);
case SPACEBALL_3003C:
spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
}
for (i = 0; i < 6; i++) {
t = spaceball_axes[i];
set_bit(t, spaceball->dev.absbit);
spaceball->dev.absmin[t] = i < 3 ? -8000 : -1600;
spaceball->dev.absmax[t] = i < 3 ? 8000 : 1600;
spaceball->dev.absflat[t] = i < 3 ? 40 : 8;
spaceball->dev.absfuzz[t] = i < 3 ? 8 : 2;
for (i = 0; i < 3; i++) {
input_set_abs_params(input_dev, ABS_X + i, -8000, 8000, 8, 40);
input_set_abs_params(input_dev, ABS_RX + i, -1600, 1600, 2, 8);
}
spaceball->serio = serio;
spaceball->dev.private = spaceball;
sprintf(spaceball->phys, "%s/input0", serio->phys);
init_input_dev(&spaceball->dev);
spaceball->dev.name = spaceball_names[id];
spaceball->dev.phys = spaceball->phys;
spaceball->dev.id.bustype = BUS_RS232;
spaceball->dev.id.vendor = SERIO_SPACEBALL;
spaceball->dev.id.product = id;
spaceball->dev.id.version = 0x0100;
spaceball->dev.dev = &serio->dev;
serio_set_drvdata(serio, spaceball);
err = serio_open(serio, drv);
if (err) {
serio_set_drvdata(serio, NULL);
kfree(spaceball);
return err;
}
input_register_device(&spaceball->dev);
printk(KERN_INFO "input: %s on serio%s\n",
spaceball_names[id], serio->phys);
if (err)
goto fail;
input_register_device(spaceball->dev);
return 0;
fail: serio_set_drvdata(serio, NULL);
input_free_device(input_dev);
kfree(spaceball);
return err;
}
/*

View File

@ -52,15 +52,13 @@ MODULE_LICENSE("GPL");
static int spaceorb_buttons[] = { BTN_TL, BTN_TR, BTN_Y, BTN_X, BTN_B, BTN_A };
static int spaceorb_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ };
static char *spaceorb_name = "SpaceTec SpaceOrb 360 / Avenger";
/*
* Per-Orb data.
*/
struct spaceorb {
struct input_dev dev;
struct serio *serio;
struct input_dev *dev;
int idx;
unsigned char data[SPACEORB_MAX_LENGTH];
char phys[32];
@ -78,7 +76,7 @@ static unsigned char *spaceorb_errors[] = { "EEPROM storing 0 failed", "Receive
static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *regs)
{
struct input_dev *dev = &spaceorb->dev;
struct input_dev *dev = spaceorb->dev;
unsigned char *data = spaceorb->data;
unsigned char c = 0;
int axes[6];
@ -95,8 +93,8 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r
case 'R': /* Reset packet */
spaceorb->data[spaceorb->idx - 1] = 0;
for (i = 1; i < spaceorb->idx && spaceorb->data[i] == ' '; i++);
printk(KERN_INFO "input: %s [%s] on %s\n",
spaceorb_name, spaceorb->data + i, spaceorb->serio->phys);
printk(KERN_INFO "input: %s [%s] is %s\n",
dev->name, spaceorb->data + i, spaceorb->phys);
break;
case 'D': /* Ball + button data */
@ -123,7 +121,7 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r
case 'E': /* Error packet */
if (spaceorb->idx != 4) return;
printk(KERN_ERR "joy-spaceorb: Device error. [ ");
printk(KERN_ERR "spaceorb: Device error. [ ");
for (i = 0; i < 7; i++) if (data[1] & (1 << i)) printk("%s ", spaceorb_errors[i]);
printk("]\n");
break;
@ -154,9 +152,9 @@ static void spaceorb_disconnect(struct serio *serio)
{
struct spaceorb* spaceorb = serio_get_drvdata(serio);
input_unregister_device(&spaceorb->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
input_unregister_device(spaceorb->dev);
kfree(spaceorb);
}
@ -169,52 +167,48 @@ static void spaceorb_disconnect(struct serio *serio)
static int spaceorb_connect(struct serio *serio, struct serio_driver *drv)
{
struct spaceorb *spaceorb;
int i, t;
int err;
struct input_dev *input_dev;
int err = -ENOMEM;
int i;
if (!(spaceorb = kmalloc(sizeof(struct spaceorb), GFP_KERNEL)))
return -ENOMEM;
memset(spaceorb, 0, sizeof(struct spaceorb));
spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < 6; i++)
set_bit(spaceorb_buttons[i], spaceorb->dev.keybit);
for (i = 0; i < 6; i++) {
t = spaceorb_axes[i];
set_bit(t, spaceorb->dev.absbit);
spaceorb->dev.absmin[t] = -508;
spaceorb->dev.absmax[t] = 508;
}
spaceorb->serio = serio;
spaceorb->dev.private = spaceorb;
spaceorb = kzalloc(sizeof(struct spaceorb), GFP_KERNEL);
input_dev = input_allocate_device();
if (!spaceorb || !input_dev)
goto fail;
spaceorb->dev = input_dev;
sprintf(spaceorb->phys, "%s/input0", serio->phys);
init_input_dev(&spaceorb->dev);
spaceorb->dev.name = spaceorb_name;
spaceorb->dev.phys = spaceorb->phys;
spaceorb->dev.id.bustype = BUS_RS232;
spaceorb->dev.id.vendor = SERIO_SPACEORB;
spaceorb->dev.id.product = 0x0001;
spaceorb->dev.id.version = 0x0100;
spaceorb->dev.dev = &serio->dev;
input_dev->name = "SpaceTec SpaceOrb 360 / Avenger";
input_dev->phys = spaceorb->phys;
input_dev->id.bustype = BUS_RS232;
input_dev->id.vendor = SERIO_SPACEORB;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &serio->dev;
input_dev->private = spaceorb;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < 6; i++)
set_bit(spaceorb_buttons[i], input_dev->keybit);
for (i = 0; i < 6; i++)
input_set_abs_params(input_dev, spaceorb_axes[i], -508, 508, 0, 0);
serio_set_drvdata(serio, spaceorb);
err = serio_open(serio, drv);
if (err) {
serio_set_drvdata(serio, NULL);
kfree(spaceorb);
return err;
}
input_register_device(&spaceorb->dev);
if (err)
goto fail;
input_register_device(spaceorb->dev);
return 0;
fail: serio_set_drvdata(serio, NULL);
input_free_device(input_dev);
kfree(spaceorb);
return err;
}
/*

View File

@ -48,14 +48,12 @@ MODULE_LICENSE("GPL");
#define STINGER_MAX_LENGTH 8
static char *stinger_name = "Gravis Stinger";
/*
* Per-Stinger data.
*/
struct stinger {
struct input_dev dev;
struct input_dev *dev;
int idx;
unsigned char data[STINGER_MAX_LENGTH];
char phys[32];
@ -68,7 +66,7 @@ struct stinger {
static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs)
{
struct input_dev *dev = &stinger->dev;
struct input_dev *dev = stinger->dev;
unsigned char *data = stinger->data;
if (!stinger->idx) return;
@ -126,9 +124,9 @@ static void stinger_disconnect(struct serio *serio)
{
struct stinger *stinger = serio_get_drvdata(serio);
input_unregister_device(&stinger->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
input_unregister_device(stinger->dev);
kfree(stinger);
}
@ -141,53 +139,46 @@ static void stinger_disconnect(struct serio *serio)
static int stinger_connect(struct serio *serio, struct serio_driver *drv)
{
struct stinger *stinger;
int i;
int err;
struct input_dev *input_dev;
int err = -ENOMEM;
if (!(stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL)))
return -ENOMEM;
memset(stinger, 0, sizeof(struct stinger));
stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
stinger->dev.keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | \
BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | \
BIT(BTN_START) | BIT(BTN_SELECT);
stinger->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL);
input_dev = input_allocate_device();
if (!stinger || !input_dev)
goto fail;
stinger->dev = input_dev;
sprintf(stinger->phys, "%s/serio0", serio->phys);
init_input_dev(&stinger->dev);
stinger->dev.name = stinger_name;
stinger->dev.phys = stinger->phys;
stinger->dev.id.bustype = BUS_RS232;
stinger->dev.id.vendor = SERIO_STINGER;
stinger->dev.id.product = 0x0001;
stinger->dev.id.version = 0x0100;
stinger->dev.dev = &serio->dev;
input_dev->name = "Gravis Stinger";
input_dev->phys = stinger->phys;
input_dev->id.bustype = BUS_RS232;
input_dev->id.vendor = SERIO_STINGER;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &serio->dev;
input_dev->private = stinger;
for (i = 0; i < 2; i++) {
stinger->dev.absmax[ABS_X+i] = 64;
stinger->dev.absmin[ABS_X+i] = -64;
stinger->dev.absflat[ABS_X+i] = 4;
}
stinger->dev.private = stinger;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) |
BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) |
BIT(BTN_START) | BIT(BTN_SELECT);
input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 4);
input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 4);
serio_set_drvdata(serio, stinger);
err = serio_open(serio, drv);
if (err) {
serio_set_drvdata(serio, NULL);
kfree(stinger);
return err;
}
input_register_device(&stinger->dev);
printk(KERN_INFO "input: %s on %s\n", stinger_name, serio->phys);
if (err)
goto fail;
input_register_device(stinger->dev);
return 0;
fail: serio_set_drvdata(serio, NULL);
input_free_device(input_dev);
kfree(stinger);
return err;
}
/*

View File

@ -63,37 +63,70 @@ MODULE_LICENSE("GPL");
#define TMDC_ABS_HAT 4
#define TMDC_BTN 16
static unsigned char tmdc_byte_a[16] = { 0, 1, 3, 4, 6, 7 };
static unsigned char tmdc_byte_d[16] = { 2, 5, 8, 9 };
static const unsigned char tmdc_byte_a[16] = { 0, 1, 3, 4, 6, 7 };
static const unsigned char tmdc_byte_d[16] = { 2, 5, 8, 9 };
static signed char tmdc_abs[TMDC_ABS] =
static const signed char tmdc_abs[TMDC_ABS] =
{ ABS_X, ABS_Y, ABS_RUDDER, ABS_THROTTLE, ABS_RX, ABS_RY, ABS_RZ };
static signed char tmdc_abs_hat[TMDC_ABS_HAT] =
static const signed char tmdc_abs_hat[TMDC_ABS_HAT] =
{ ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
static signed char tmdc_abs_at[TMDC_ABS] =
static const signed char tmdc_abs_at[TMDC_ABS] =
{ ABS_X, ABS_Y, ABS_RUDDER, -1, ABS_THROTTLE };
static signed char tmdc_abs_fm[TMDC_ABS] =
static const signed char tmdc_abs_fm[TMDC_ABS] =
{ ABS_RX, ABS_RY, ABS_X, ABS_Y };
static short tmdc_btn_pad[TMDC_BTN] =
static const short tmdc_btn_pad[TMDC_BTN] =
{ BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_START, BTN_SELECT, BTN_TL, BTN_TR };
static short tmdc_btn_joy[TMDC_BTN] =
static const short tmdc_btn_joy[TMDC_BTN] =
{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_THUMB2, BTN_PINKIE,
BTN_BASE3, BTN_BASE4, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z };
static short tmdc_btn_fm[TMDC_BTN] =
static const short tmdc_btn_fm[TMDC_BTN] =
{ BTN_TRIGGER, BTN_C, BTN_B, BTN_A, BTN_THUMB, BTN_X, BTN_Y, BTN_Z, BTN_TOP, BTN_TOP2 };
static short tmdc_btn_at[TMDC_BTN] =
static const short tmdc_btn_at[TMDC_BTN] =
{ BTN_TRIGGER, BTN_THUMB2, BTN_PINKIE, BTN_THUMB, BTN_BASE6, BTN_BASE5, BTN_BASE4,
BTN_BASE3, BTN_BASE2, BTN_BASE };
static struct {
static const struct {
int x;
int y;
} tmdc_hat_to_axis[] = {{ 0, 0}, { 1, 0}, { 0,-1}, {-1, 0}, { 0, 1}};
static const struct tmdc_model {
unsigned char id;
const char *name;
char abs;
char hats;
char btnc[4];
char btno[4];
const signed char *axes;
const short *buttons;
} tmdc_models[] = {
{ 1, "ThrustMaster Millenium 3D Inceptor", 6, 2, { 4, 2 }, { 4, 6 }, tmdc_abs, tmdc_btn_joy },
{ 3, "ThrustMaster Rage 3D Gamepad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
{ 4, "ThrustMaster Attack Throttle", 5, 2, { 4, 6 }, { 4, 2 }, tmdc_abs_at, tmdc_btn_at },
{ 8, "ThrustMaster FragMaster", 4, 0, { 8, 2 }, { 0, 0 }, tmdc_abs_fm, tmdc_btn_fm },
{ 163, "Thrustmaster Fusion GamePad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
{ 0, "Unknown %d-axis, %d-button TM device %d", 0, 0, { 0, 0 }, { 0, 0 }, tmdc_abs, tmdc_btn_joy }
};
struct tmdc_port {
struct input_dev *dev;
char name[64];
char phys[32];
int mode;
const signed char *abs;
const short *btn;
unsigned char absc;
unsigned char btnc[4];
unsigned char btno[4];
};
struct tmdc {
struct gameport *gameport;
struct input_dev dev[2];
struct tmdc_port *port[2];
#if 0
struct input_dev *dev[2];
char name[2][64];
char phys[2][32];
int mode[2];
@ -102,6 +135,7 @@ struct tmdc {
unsigned char absc[2];
unsigned char btnc[2][4];
unsigned char btno[2][4];
#endif
int reads;
int bads;
unsigned char exists;
@ -156,6 +190,50 @@ static int tmdc_read_packet(struct gameport *gameport, unsigned char data[2][TMD
return (i[0] == TMDC_MAX_LENGTH) | ((i[1] == TMDC_MAX_LENGTH) << 1);
}
static int tmdc_parse_packet(struct tmdc_port *port, unsigned char *data)
{
int i, k, l;
if (data[TMDC_BYTE_ID] != port->mode)
return -1;
for (i = 0; i < port->absc; i++) {
if (port->abs[i] < 0)
return 0;
input_report_abs(port->dev, port->abs[i], data[tmdc_byte_a[i]]);
}
switch (port->mode) {
case TMDC_MODE_M3DI:
i = tmdc_byte_d[0];
input_report_abs(port->dev, ABS_HAT0X, ((data[i] >> 3) & 1) - ((data[i] >> 1) & 1));
input_report_abs(port->dev, ABS_HAT0Y, ((data[i] >> 2) & 1) - ( data[i] & 1));
break;
case TMDC_MODE_AT:
i = tmdc_byte_a[3];
input_report_abs(port->dev, ABS_HAT0X, tmdc_hat_to_axis[(data[i] - 141) / 25].x);
input_report_abs(port->dev, ABS_HAT0Y, tmdc_hat_to_axis[(data[i] - 141) / 25].y);
break;
}
for (k = l = 0; k < 4; k++) {
for (i = 0; i < port->btnc[k]; i++)
input_report_key(port->dev, port->btn[i + l],
((data[tmdc_byte_d[k]] >> (i + port->btno[k])) & 1));
l += port->btnc[k];
}
input_sync(port->dev);
return 0;
}
/*
* tmdc_poll() reads and analyzes ThrustMaster joystick data.
*/
@ -164,57 +242,21 @@ static void tmdc_poll(struct gameport *gameport)
{
unsigned char data[2][TMDC_MAX_LENGTH];
struct tmdc *tmdc = gameport_get_drvdata(gameport);
struct input_dev *dev;
unsigned char r, bad = 0;
int i, j, k, l;
int i;
tmdc->reads++;
if ((r = tmdc_read_packet(tmdc->gameport, data)) != tmdc->exists)
bad = 1;
else
else {
for (i = 0; i < 2; i++) {
if (r & (1 << i) & tmdc->exists) {
for (j = 0; j < 2; j++)
if (r & (1 << j) & tmdc->exists) {
if (data[j][TMDC_BYTE_ID] != tmdc->mode[j]) {
bad = 1;
continue;
if (tmdc_parse_packet(tmdc->port[i], data[i]))
bad = 1;
}
dev = tmdc->dev + j;
for (i = 0; i < tmdc->absc[j]; i++) {
if (tmdc->abs[j][i] < 0) continue;
input_report_abs(dev, tmdc->abs[j][i], data[j][tmdc_byte_a[i]]);
}
switch (tmdc->mode[j]) {
case TMDC_MODE_M3DI:
i = tmdc_byte_d[0];
input_report_abs(dev, ABS_HAT0X, ((data[j][i] >> 3) & 1) - ((data[j][i] >> 1) & 1));
input_report_abs(dev, ABS_HAT0Y, ((data[j][i] >> 2) & 1) - ( data[j][i] & 1));
break;
case TMDC_MODE_AT:
i = tmdc_byte_a[3];
input_report_abs(dev, ABS_HAT0X, tmdc_hat_to_axis[(data[j][i] - 141) / 25].x);
input_report_abs(dev, ABS_HAT0Y, tmdc_hat_to_axis[(data[j][i] - 141) / 25].y);
break;
}
for (k = l = 0; k < 4; k++) {
for (i = 0; i < tmdc->btnc[j][k]; i++)
input_report_key(dev, tmdc->btn[j][i + l],
((data[j][tmdc_byte_d[k]] >> (i + tmdc->btno[j][k])) & 1));
l += tmdc->btnc[j][k];
}
input_sync(dev);
}
}
tmdc->bads += bad;
@ -235,31 +277,89 @@ static void tmdc_close(struct input_dev *dev)
gameport_stop_polling(tmdc->gameport);
}
static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data)
{
const struct tmdc_model *model;
struct tmdc_port *port;
struct input_dev *input_dev;
int i, j, b = 0;
tmdc->port[idx] = port = kzalloc(sizeof (struct tmdc_port), GFP_KERNEL);
input_dev = input_allocate_device();
if (!port || !input_dev) {
kfree(port);
input_free_device(input_dev);
return -ENOMEM;
}
port->mode = data[TMDC_BYTE_ID];
for (model = tmdc_models; model->id && model->id != port->mode; model++)
/* empty */;
port->abs = model->axes;
port->btn = model->buttons;
if (!model->id) {
port->absc = data[TMDC_BYTE_DEF] >> 4;
for (i = 0; i < 4; i++)
port->btnc[i] = i < (data[TMDC_BYTE_DEF] & 0xf) ? 8 : 0;
} else {
port->absc = model->abs;
for (i = 0; i < 4; i++)
port->btnc[i] = model->btnc[i];
}
for (i = 0; i < 4; i++)
port->btno[i] = model->btno[i];
snprintf(port->name, sizeof(port->name), model->name,
port->absc, (data[TMDC_BYTE_DEF] & 0xf) << 3, port->mode);
snprintf(port->phys, sizeof(port->phys), "%s/input%d", tmdc->gameport->phys, i);
port->dev = input_dev;
input_dev->name = port->name;
input_dev->phys = port->phys;
input_dev->id.bustype = BUS_GAMEPORT;
input_dev->id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER;
input_dev->id.product = model->id;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &tmdc->gameport->dev;
input_dev->private = tmdc;
input_dev->open = tmdc_open;
input_dev->close = tmdc_close;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < port->absc && i < TMDC_ABS; i++)
if (port->abs[i] >= 0)
input_set_abs_params(input_dev, port->abs[i], 8, 248, 2, 4);
for (i = 0; i < model->hats && i < TMDC_ABS_HAT; i++)
input_set_abs_params(input_dev, tmdc_abs_hat[i], -1, 1, 0, 0);
for (i = 0; i < 4; i++) {
for (j = 0; j < port->btnc[i] && j < TMDC_BTN; j++)
set_bit(port->btn[j + b], input_dev->keybit);
b += port->btnc[i];
}
input_register_device(port->dev);
return 0;
}
/*
* tmdc_probe() probes for ThrustMaster type joysticks.
*/
static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv)
{
static struct models {
unsigned char id;
char *name;
char abs;
char hats;
char btnc[4];
char btno[4];
signed char *axes;
short *buttons;
} models[] = { { 1, "ThrustMaster Millenium 3D Inceptor", 6, 2, { 4, 2 }, { 4, 6 }, tmdc_abs, tmdc_btn_joy },
{ 3, "ThrustMaster Rage 3D Gamepad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
{ 4, "ThrustMaster Attack Throttle", 5, 2, { 4, 6 }, { 4, 2 }, tmdc_abs_at, tmdc_btn_at },
{ 8, "ThrustMaster FragMaster", 4, 0, { 8, 2 }, { 0, 0 }, tmdc_abs_fm, tmdc_btn_fm },
{ 163, "Thrustmaster Fusion GamePad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
{ 0, "Unknown %d-axis, %d-button TM device %d", 0, 0, { 0, 0 }, { 0, 0 }, tmdc_abs, tmdc_btn_joy }};
unsigned char data[2][TMDC_MAX_LENGTH];
struct tmdc *tmdc;
int i, j, k, l, m;
int i;
int err;
if (!(tmdc = kzalloc(sizeof(struct tmdc), GFP_KERNEL)))
@ -281,68 +381,25 @@ static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv)
gameport_set_poll_handler(gameport, tmdc_poll);
gameport_set_poll_interval(gameport, 20);
for (j = 0; j < 2; j++)
if (tmdc->exists & (1 << j)) {
for (i = 0; i < 2; i++) {
if (tmdc->exists & (1 << i)) {
tmdc->mode[j] = data[j][TMDC_BYTE_ID];
for (m = 0; models[m].id && models[m].id != tmdc->mode[j]; m++);
tmdc->abs[j] = models[m].axes;
tmdc->btn[j] = models[m].buttons;
if (!models[m].id) {
models[m].abs = data[j][TMDC_BYTE_DEF] >> 4;
for (k = 0; k < 4; k++)
models[m].btnc[k] = k < (data[j][TMDC_BYTE_DEF] & 0xf) ? 8 : 0;
}
tmdc->absc[j] = models[m].abs;
for (k = 0; k < 4; k++) {
tmdc->btnc[j][k] = models[m].btnc[k];
tmdc->btno[j][k] = models[m].btno[k];
}
sprintf(tmdc->name[j], models[m].name, models[m].abs,
(data[j][TMDC_BYTE_DEF] & 0xf) << 3, tmdc->mode[j]);
sprintf(tmdc->phys[j], "%s/input%d", gameport->phys, j);
tmdc->dev[j].private = tmdc;
tmdc->dev[j].open = tmdc_open;
tmdc->dev[j].close = tmdc_close;
tmdc->dev[j].name = tmdc->name[j];
tmdc->dev[j].phys = tmdc->phys[j];
tmdc->dev[j].id.bustype = BUS_GAMEPORT;
tmdc->dev[j].id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER;
tmdc->dev[j].id.product = models[m].id;
tmdc->dev[j].id.version = 0x0100;
tmdc->dev[j].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < models[m].abs && i < TMDC_ABS; i++)
if (tmdc->abs[j][i] >= 0)
input_set_abs_params(&tmdc->dev[j], tmdc->abs[j][i], 8, 248, 2, 4);
for (i = 0; i < models[m].hats && i < TMDC_ABS_HAT; i++)
input_set_abs_params(&tmdc->dev[j], tmdc_abs_hat[i], -1, 1, 0, 0);
for (k = l = 0; k < 4; k++) {
for (i = 0; i < models[m].btnc[k] && i < TMDC_BTN; i++)
set_bit(tmdc->btn[j][i + l], tmdc->dev[j].keybit);
l += models[m].btnc[k];
}
input_register_device(tmdc->dev + j);
printk(KERN_INFO "input: %s on %s\n", tmdc->name[j], gameport->phys);
err = tmdc_setup_port(tmdc, i, data[i]);
if (err)
goto fail3;
}
}
return 0;
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
fail3: while (--i >= 0) {
if (tmdc->port[i]) {
input_unregister_device(tmdc->port[i]->dev);
kfree(tmdc->port[i]);
}
}
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
kfree(tmdc);
return err;
}
@ -352,9 +409,12 @@ static void tmdc_disconnect(struct gameport *gameport)
struct tmdc *tmdc = gameport_get_drvdata(gameport);
int i;
for (i = 0; i < 2; i++)
if (tmdc->exists & (1 << i))
input_unregister_device(tmdc->dev + i);
for (i = 0; i < 2; i++) {
if (tmdc->port[i]) {
input_unregister_device(tmdc->port[i]->dev);
kfree(tmdc->port[i]);
}
}
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(tmdc);

View File

@ -42,19 +42,21 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("TurboGraFX parallel port interface driver");
MODULE_LICENSE("GPL");
static int tgfx[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
static int tgfx_nargs __initdata = 0;
module_param_array_named(map, tgfx, int, &tgfx_nargs, 0);
#define TGFX_MAX_PORTS 3
#define TGFX_MAX_DEVICES 7
struct tgfx_config {
int args[TGFX_MAX_DEVICES + 1];
int nargs;
};
static struct tgfx_config tgfx[TGFX_MAX_PORTS] __initdata;
module_param_array_named(map, tgfx[0].args, int, &tgfx[0].nargs, 0);
MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
static int tgfx_2[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
static int tgfx_nargs_2 __initdata = 0;
module_param_array_named(map2, tgfx_2, int, &tgfx_nargs_2, 0);
module_param_array_named(map2, tgfx[1].args, int, &tgfx[1].nargs, 0);
MODULE_PARM_DESC(map2, "Describes second set of devices");
static int tgfx_3[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
static int tgfx_nargs_3 __initdata = 0;
module_param_array_named(map3, tgfx_3, int, &tgfx_nargs_3, 0);
module_param_array_named(map3, tgfx[2].args, int, &tgfx[2].nargs, 0);
MODULE_PARM_DESC(map3, "Describes third set of devices");
__obsolete_setup("tgfx=");
@ -75,17 +77,17 @@ __obsolete_setup("tgfx_3=");
#define TGFX_TOP2 0x08
static int tgfx_buttons[] = { BTN_TRIGGER, BTN_THUMB, BTN_THUMB2, BTN_TOP, BTN_TOP2 };
static char *tgfx_name = "TurboGraFX Multisystem joystick";
static struct tgfx {
struct pardevice *pd;
struct timer_list timer;
struct input_dev dev[7];
char phys[7][32];
struct input_dev *dev[TGFX_MAX_DEVICES];
char name[TGFX_MAX_DEVICES][64];
char phys[TGFX_MAX_DEVICES][32];
int sticks;
int used;
struct semaphore sem;
} *tgfx_base[3];
} *tgfx_base[TGFX_MAX_PORTS];
/*
* tgfx_timer() reads and analyzes TurboGraFX joystick data.
@ -100,7 +102,7 @@ static void tgfx_timer(unsigned long private)
for (i = 0; i < 7; i++)
if (tgfx->sticks & (1 << i)) {
dev = tgfx->dev + i;
dev = tgfx->dev[i];
parport_write_data(tgfx->pd->port, ~(1 << i));
data1 = parport_read_status(tgfx->pd->port) ^ 0x7f;
@ -153,118 +155,165 @@ static void tgfx_close(struct input_dev *dev)
up(&tgfx->sem);
}
/*
* tgfx_probe() probes for tg gamepads.
*/
static struct tgfx __init *tgfx_probe(int *config, int nargs)
static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
{
struct tgfx *tgfx;
struct input_dev *input_dev;
struct parport *pp;
struct pardevice *pd;
int i, j;
int err;
if (config[0] < 0)
return NULL;
if (nargs < 2) {
printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
return NULL;
}
pp = parport_find_number(config[0]);
pp = parport_find_number(parport);
if (!pp) {
printk(KERN_ERR "turbografx.c: no such parport\n");
return NULL;
err = -EINVAL;
goto err_out;
}
if (!(tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL))) {
parport_put_port(pp);
return NULL;
pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
if (!pd) {
printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n");
err = -EBUSY;
goto err_put_pp;
}
tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL);
if (!tgfx) {
printk(KERN_ERR "turbografx.c: Not enough memory\n");
err = -ENOMEM;
goto err_unreg_pardev;
}
init_MUTEX(&tgfx->sem);
tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
parport_put_port(pp);
if (!tgfx->pd) {
printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n");
kfree(tgfx);
return NULL;
}
tgfx->pd = pd;
init_timer(&tgfx->timer);
tgfx->timer.data = (long) tgfx;
tgfx->timer.function = tgfx_timer;
tgfx->sticks = 0;
for (i = 0; i < n_devs; i++) {
if (n_buttons[i] < 1)
continue;
for (i = 0; i < nargs - 1; i++)
if (config[i+1] > 0 && config[i+1] < 6) {
tgfx->sticks |= (1 << i);
tgfx->dev[i].private = tgfx;
tgfx->dev[i].open = tgfx_open;
tgfx->dev[i].close = tgfx_close;
sprintf(tgfx->phys[i], "%s/input0", tgfx->pd->port->name);
tgfx->dev[i].name = tgfx_name;
tgfx->dev[i].phys = tgfx->phys[i];
tgfx->dev[i].id.bustype = BUS_PARPORT;
tgfx->dev[i].id.vendor = 0x0003;
tgfx->dev[i].id.product = config[i+1];
tgfx->dev[i].id.version = 0x0100;
tgfx->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
tgfx->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
for (j = 0; j < config[i+1]; j++)
set_bit(tgfx_buttons[j], tgfx->dev[i].keybit);
tgfx->dev[i].absmin[ABS_X] = -1; tgfx->dev[i].absmax[ABS_X] = 1;
tgfx->dev[i].absmin[ABS_Y] = -1; tgfx->dev[i].absmax[ABS_Y] = 1;
input_register_device(tgfx->dev + i);
printk(KERN_INFO "input: %d-button Multisystem joystick on %s\n",
config[i+1], tgfx->pd->port->name);
if (n_buttons[i] > 6) {
printk(KERN_ERR "turbografx.c: Invalid number of buttons %d\n", n_buttons[i]);
err = -EINVAL;
goto err_free_devs;
}
tgfx->dev[i] = input_dev = input_allocate_device();
if (!input_dev) {
printk(KERN_ERR "turbografx.c: Not enough memory for input device\n");
err = -ENOMEM;
goto err_free_devs;
}
tgfx->sticks |= (1 << i);
snprintf(tgfx->name[i], sizeof(tgfx->name[i]),
"TurboGraFX %d-button Multisystem joystick", n_buttons[i]);
snprintf(tgfx->phys[i], sizeof(tgfx->phys[i]),
"%s/input%d", tgfx->pd->port->name, i);
input_dev->name = tgfx->name[i];
input_dev->phys = tgfx->phys[i];
input_dev->id.bustype = BUS_PARPORT;
input_dev->id.vendor = 0x0003;
input_dev->id.product = n_buttons[i];
input_dev->id.version = 0x0100;
input_dev->private = tgfx;
input_dev->open = tgfx_open;
input_dev->close = tgfx_close;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
for (j = 0; j < n_buttons[i]; j++)
set_bit(tgfx_buttons[j], input_dev->keybit);
input_register_device(tgfx->dev[i]);
}
if (!tgfx->sticks) {
parport_unregister_device(tgfx->pd);
kfree(tgfx);
return NULL;
printk(KERN_ERR "turbografx.c: No valid devices specified\n");
err = -EINVAL;
goto err_free_tgfx;
}
return tgfx;
err_free_devs:
while (--i >= 0)
input_unregister_device(tgfx->dev[i]);
err_free_tgfx:
kfree(tgfx);
err_unreg_pardev:
parport_unregister_device(pd);
err_put_pp:
parport_put_port(pp);
err_out:
return ERR_PTR(err);
}
static void __exit tgfx_remove(struct tgfx *tgfx)
{
int i;
for (i = 0; i < TGFX_MAX_DEVICES; i++)
if (tgfx->dev[i])
input_unregister_device(tgfx->dev[i]);
parport_unregister_device(tgfx->pd);
kfree(tgfx);
}
static int __init tgfx_init(void)
{
tgfx_base[0] = tgfx_probe(tgfx, tgfx_nargs);
tgfx_base[1] = tgfx_probe(tgfx_2, tgfx_nargs_2);
tgfx_base[2] = tgfx_probe(tgfx_3, tgfx_nargs_3);
int i;
int have_dev = 0;
int err = 0;
if (tgfx_base[0] || tgfx_base[1] || tgfx_base[2])
return 0;
for (i = 0; i < TGFX_MAX_PORTS; i++) {
if (tgfx[i].nargs == 0 || tgfx[i].args[0] < 0)
continue;
return -ENODEV;
if (tgfx[i].nargs < 2) {
printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
err = -EINVAL;
break;
}
tgfx_base[i] = tgfx_probe(tgfx[i].args[0], tgfx[i].args + 1, tgfx[i].nargs - 1);
if (IS_ERR(tgfx_base[i])) {
err = PTR_ERR(tgfx_base[i]);
break;
}
have_dev = 1;
}
if (err) {
while (--i >= 0)
tgfx_remove(tgfx_base[i]);
return err;
}
return have_dev ? 0 : -ENODEV;
}
static void __exit tgfx_exit(void)
{
int i, j;
int i;
for (i = 0; i < 3; i++)
if (tgfx_base[i]) {
for (j = 0; j < 7; j++)
if (tgfx_base[i]->sticks & (1 << j))
input_unregister_device(tgfx_base[i]->dev + j);
parport_unregister_device(tgfx_base[i]->pd);
}
for (i = 0; i < TGFX_MAX_PORTS; i++)
if (tgfx_base[i])
tgfx_remove(tgfx_base[i]);
}
module_init(tgfx_init);

View File

@ -69,8 +69,6 @@ MODULE_LICENSE("GPL");
#define TWIDJOY_MAX_LENGTH 5
static char *twidjoy_name = "Handykey Twiddler";
static struct twidjoy_button_spec {
int bitshift;
int bitmask;
@ -95,7 +93,7 @@ twidjoy_buttons[] = {
*/
struct twidjoy {
struct input_dev dev;
struct input_dev *dev;
int idx;
unsigned char data[TWIDJOY_MAX_LENGTH];
char phys[32];
@ -108,37 +106,33 @@ struct twidjoy {
static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs)
{
if (twidjoy->idx == TWIDJOY_MAX_LENGTH) {
struct input_dev *dev = &twidjoy->dev;
unsigned char *data = twidjoy->data;
struct twidjoy_button_spec *bp;
int button_bits, abs_x, abs_y;
struct input_dev *dev = twidjoy->dev;
unsigned char *data = twidjoy->data;
struct twidjoy_button_spec *bp;
int button_bits, abs_x, abs_y;
button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
input_regs(dev, regs);
input_regs(dev, regs);
for (bp = twidjoy_buttons; bp->bitmask; bp++) {
int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
int i;
for (bp = twidjoy_buttons; bp->bitmask; bp++) {
int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
int i;
for (i = 0; i < bp->bitmask; i++)
input_report_key(dev, bp->buttons[i], i+1 == value);
}
abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2);
if (data[4] & 0x08) abs_x -= 256;
abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0);
if (data[3] & 0x02) abs_y -= 256;
input_report_abs(dev, ABS_X, -abs_x);
input_report_abs(dev, ABS_Y, +abs_y);
input_sync(dev);
for (i = 0; i < bp->bitmask; i++)
input_report_key(dev, bp->buttons[i], i+1 == value);
}
return;
abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2);
if (data[4] & 0x08) abs_x -= 256;
abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0);
if (data[3] & 0x02) abs_y -= 256;
input_report_abs(dev, ABS_X, -abs_x);
input_report_abs(dev, ABS_Y, +abs_y);
input_sync(dev);
}
/*
@ -179,9 +173,9 @@ static void twidjoy_disconnect(struct serio *serio)
{
struct twidjoy *twidjoy = serio_get_drvdata(serio);
input_unregister_device(&twidjoy->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
input_unregister_device(twidjoy->dev);
kfree(twidjoy);
}
@ -195,59 +189,49 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv)
{
struct twidjoy_button_spec *bp;
struct twidjoy *twidjoy;
struct input_dev *input_dev;
int err = -ENOMEM;
int i;
int err;
if (!(twidjoy = kmalloc(sizeof(struct twidjoy), GFP_KERNEL)))
return -ENOMEM;
memset(twidjoy, 0, sizeof(struct twidjoy));
twidjoy = kzalloc(sizeof(struct twidjoy), GFP_KERNEL);
input_dev = input_allocate_device();
if (!twidjoy || !input_dev)
goto fail;
twidjoy->dev = input_dev;
sprintf(twidjoy->phys, "%s/input0", serio->phys);
init_input_dev(&twidjoy->dev);
twidjoy->dev.name = twidjoy_name;
twidjoy->dev.phys = twidjoy->phys;
twidjoy->dev.id.bustype = BUS_RS232;
twidjoy->dev.id.vendor = SERIO_TWIDJOY;
twidjoy->dev.id.product = 0x0001;
twidjoy->dev.id.version = 0x0100;
twidjoy->dev.dev = &serio->dev;
input_dev->name = "Handykey Twiddler";
input_dev->phys = twidjoy->phys;
input_dev->id.bustype = BUS_RS232;
input_dev->id.vendor = SERIO_TWIDJOY;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &serio->dev;
input_dev->private = twidjoy;
twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4);
input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4);
for (bp = twidjoy_buttons; bp->bitmask; bp++) {
for (bp = twidjoy_buttons; bp->bitmask; bp++)
for (i = 0; i < bp->bitmask; i++)
set_bit(bp->buttons[i], twidjoy->dev.keybit);
}
twidjoy->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
for (i = 0; i < 2; i++) {
twidjoy->dev.absmax[ABS_X+i] = 50;
twidjoy->dev.absmin[ABS_X+i] = -50;
/* TODO: arndt 20010708: Are these values appropriate? */
twidjoy->dev.absfuzz[ABS_X+i] = 4;
twidjoy->dev.absflat[ABS_X+i] = 4;
}
twidjoy->dev.private = twidjoy;
set_bit(bp->buttons[i], input_dev->keybit);
serio_set_drvdata(serio, twidjoy);
err = serio_open(serio, drv);
if (err) {
serio_set_drvdata(serio, NULL);
kfree(twidjoy);
return err;
}
input_register_device(&twidjoy->dev);
printk(KERN_INFO "input: %s on %s\n", twidjoy_name, serio->phys);
if (err)
goto fail;
input_register_device(twidjoy->dev);
return 0;
fail: serio_set_drvdata(serio, NULL);
input_free_device(input_dev);
kfree(twidjoy);
return err;
}
/*

View File

@ -47,14 +47,13 @@ MODULE_LICENSE("GPL");
#define WARRIOR_MAX_LENGTH 16
static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 };
static char *warrior_name = "Logitech WingMan Warrior";
/*
* Per-Warrior data.
*/
struct warrior {
struct input_dev dev;
struct input_dev *dev;
int idx, len;
unsigned char data[WARRIOR_MAX_LENGTH];
char phys[32];
@ -67,7 +66,7 @@ struct warrior {
static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs)
{
struct input_dev *dev = &warrior->dev;
struct input_dev *dev = warrior->dev;
unsigned char *data = warrior->data;
if (!warrior->idx) return;
@ -131,9 +130,9 @@ static void warrior_disconnect(struct serio *serio)
{
struct warrior *warrior = serio_get_drvdata(serio);
input_unregister_device(&warrior->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
input_unregister_device(warrior->dev);
kfree(warrior);
}
@ -146,60 +145,48 @@ static void warrior_disconnect(struct serio *serio)
static int warrior_connect(struct serio *serio, struct serio_driver *drv)
{
struct warrior *warrior;
int i;
int err;
struct input_dev *input_dev;
int err = -ENOMEM;
if (!(warrior = kmalloc(sizeof(struct warrior), GFP_KERNEL)))
return -ENOMEM;
memset(warrior, 0, sizeof(struct warrior));
warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
warrior->dev.keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
warrior->dev.relbit[0] = BIT(REL_DIAL);
warrior->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y);
warrior = kzalloc(sizeof(struct warrior), GFP_KERNEL);
input_dev = input_allocate_device();
if (!warrior || !input_dev)
goto fail;
warrior->dev = input_dev;
sprintf(warrior->phys, "%s/input0", serio->phys);
init_input_dev(&warrior->dev);
warrior->dev.name = warrior_name;
warrior->dev.phys = warrior->phys;
warrior->dev.id.bustype = BUS_RS232;
warrior->dev.id.vendor = SERIO_WARRIOR;
warrior->dev.id.product = 0x0001;
warrior->dev.id.version = 0x0100;
warrior->dev.dev = &serio->dev;
input_dev->name = "Logitech WingMan Warrior";
input_dev->phys = warrior->phys;
input_dev->id.bustype = BUS_RS232;
input_dev->id.vendor = SERIO_WARRIOR;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &serio->dev;
input_dev->private = warrior;
for (i = 0; i < 2; i++) {
warrior->dev.absmax[ABS_X+i] = -64;
warrior->dev.absmin[ABS_X+i] = 64;
warrior->dev.absflat[ABS_X+i] = 8;
}
warrior->dev.absmax[ABS_THROTTLE] = -112;
warrior->dev.absmin[ABS_THROTTLE] = 112;
for (i = 0; i < 2; i++) {
warrior->dev.absmax[ABS_HAT0X+i] = -1;
warrior->dev.absmin[ABS_HAT0X+i] = 1;
}
warrior->dev.private = warrior;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
input_dev->relbit[0] = BIT(REL_DIAL);
input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 8);
input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8);
input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0);
input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
serio_set_drvdata(serio, warrior);
err = serio_open(serio, drv);
if (err) {
serio_set_drvdata(serio, NULL);
kfree(warrior);
return err;
}
input_register_device(&warrior->dev);
printk(KERN_INFO "input: Logitech WingMan Warrior on %s\n", serio->phys);
if (err)
goto fail;
input_register_device(warrior->dev);
return 0;
fail: serio_set_drvdata(serio, NULL);
input_free_device(input_dev);
kfree(warrior);
return err;
}
/*

View File

@ -155,10 +155,7 @@ static const char *amikbd_messages[8] = {
[7] = KERN_WARNING "amikbd: keyboard interrupt\n"
};
static struct input_dev amikbd_dev;
static char *amikbd_name = "Amiga keyboard";
static char *amikbd_phys = "amikbd/input0";
static struct input_dev *amikbd_dev;
static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
@ -176,16 +173,16 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
scancode = amikbd_keycode[scancode];
input_regs(&amikbd_dev, fp);
input_regs(amikbd_dev, fp);
if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */
input_report_key(&amikbd_dev, scancode, 1);
input_report_key(&amikbd_dev, scancode, 0);
input_sync(&amikbd_dev);
input_report_key(amikbd_dev, scancode, 1);
input_report_key(amikbd_dev, scancode, 0);
} else {
input_report_key(&amikbd_dev, scancode, down);
input_sync(&amikbd_dev);
input_report_key(amikbd_dev, scancode, down);
}
input_sync(amikbd_dev);
} else /* scancodes >= 0x78 are error codes */
printk(amikbd_messages[scancode - 0x78]);
@ -202,39 +199,41 @@ static int __init amikbd_init(void)
if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
return -EBUSY;
init_input_dev(&amikbd_dev);
amikbd_dev = input_dev_allocate();
if (!amikbd_dev) {
printk(KERN_ERR "amikbd: not enough memory for input device\n");
release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
return -ENOMEM;
}
amikbd_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
amikbd_dev.keycode = amikbd_keycode;
amikbd_dev.keycodesize = sizeof(unsigned char);
amikbd_dev.keycodemax = ARRAY_SIZE(amikbd_keycode);
amikbd_dev->name = "Amiga Keyboard";
amikbd_dev->phys = "amikbd/input0";
amikbd_dev->id.bustype = BUS_AMIGA;
amikbd_dev->id.vendor = 0x0001;
amikbd_dev->id.product = 0x0001;
amikbd_dev->id.version = 0x0100;
amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
amikbd_dev->keycode = amikbd_keycode;
amikbd_dev->keycodesize = sizeof(unsigned char);
amikbd_dev->keycodemax = ARRAY_SIZE(amikbd_keycode);
for (i = 0; i < 0x78; i++)
if (amikbd_keycode[i])
set_bit(amikbd_keycode[i], amikbd_dev.keybit);
set_bit(amikbd_keycode[i], amikbd_dev->keybit);
ciaa.cra &= ~0x41; /* serial data in, turn off TA */
request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt);
amikbd_dev.name = amikbd_name;
amikbd_dev.phys = amikbd_phys;
amikbd_dev.id.bustype = BUS_AMIGA;
amikbd_dev.id.vendor = 0x0001;
amikbd_dev.id.product = 0x0001;
amikbd_dev.id.version = 0x0100;
input_register_device(&amikbd_dev);
printk(KERN_INFO "input: %s\n", amikbd_name);
input_register_device(amikbd_dev);
return 0;
}
static void __exit amikbd_exit(void)
{
input_unregister_device(&amikbd_dev);
free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt);
release_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100);
input_unregister_device(amikbd_dev);
release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
}
module_init(amikbd_init);

View File

@ -185,12 +185,12 @@ static struct {
struct atkbd {
struct ps2dev ps2dev;
struct ps2dev ps2dev;
struct input_dev *dev;
/* Written only during init */
char name[64];
char phys[32];
struct input_dev dev;
unsigned short id;
unsigned char keycode[512];
@ -290,7 +290,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
if (!atkbd->enabled)
goto out;
input_event(&atkbd->dev, EV_MSC, MSC_RAW, code);
input_event(atkbd->dev, EV_MSC, MSC_RAW, code);
if (atkbd->translated) {
@ -326,10 +326,10 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
atkbd->release = 1;
goto out;
case ATKBD_RET_HANGUEL:
atkbd_report_key(&atkbd->dev, regs, KEY_HANGUEL, 3);
atkbd_report_key(atkbd->dev, regs, KEY_HANGUEL, 3);
goto out;
case ATKBD_RET_HANJA:
atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3);
atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3);
goto out;
case ATKBD_RET_ERR:
printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
@ -345,7 +345,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
}
if (atkbd->keycode[code] != ATKBD_KEY_NULL)
input_event(&atkbd->dev, EV_MSC, MSC_SCAN, code);
input_event(atkbd->dev, EV_MSC, MSC_SCAN, code);
switch (atkbd->keycode[code]) {
case ATKBD_KEY_NULL:
@ -365,7 +365,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
"to make it known.\n",
code & 0x80 ? "e0" : "", code & 0x7f);
}
input_sync(&atkbd->dev);
input_sync(atkbd->dev);
break;
case ATKBD_SCR_1:
scroll = 1 - atkbd->release * 2;
@ -390,7 +390,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
break;
default:
value = atkbd->release ? 0 :
(1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key)));
(1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev->key)));
switch (value) { /* Workaround Toshiba laptop multiple keypress */
case 0:
@ -398,7 +398,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
break;
case 1:
atkbd->last = code;
atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev.rep[REP_DELAY]) / 2;
atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev->rep[REP_DELAY]) / 2;
break;
case 2:
if (!time_after(jiffies, atkbd->time) && atkbd->last == code)
@ -406,16 +406,16 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
break;
}
atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value);
atkbd_report_key(atkbd->dev, regs, atkbd->keycode[code], value);
}
if (atkbd->scroll) {
input_regs(&atkbd->dev, regs);
input_regs(atkbd->dev, regs);
if (click != -1)
input_report_key(&atkbd->dev, BTN_MIDDLE, click);
input_report_rel(&atkbd->dev, REL_WHEEL, scroll);
input_report_rel(&atkbd->dev, REL_HWHEEL, hscroll);
input_sync(&atkbd->dev);
input_report_key(atkbd->dev, BTN_MIDDLE, click);
input_report_rel(atkbd->dev, REL_WHEEL, scroll);
input_report_rel(atkbd->dev, REL_HWHEEL, hscroll);
input_sync(atkbd->dev);
}
atkbd->release = 0;
@ -463,7 +463,6 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co
return 0;
case EV_REP:
if (atkbd->softrepeat) return 0;
@ -693,7 +692,7 @@ static void atkbd_disconnect(struct serio *serio)
device_remove_file(&serio->dev, &atkbd_attr_softrepeat);
device_remove_file(&serio->dev, &atkbd_attr_softraw);
input_unregister_device(&atkbd->dev);
input_unregister_device(atkbd->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(atkbd);
@ -701,7 +700,7 @@ static void atkbd_disconnect(struct serio *serio)
/*
* atkbd_set_device_attrs() initializes keyboard's keycode table
* atkbd_set_keycode_table() initializes keyboard's keycode table
* according to the selected scancode set
*/
@ -737,53 +736,58 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
static void atkbd_set_device_attrs(struct atkbd *atkbd)
{
struct input_dev *input_dev = atkbd->dev;
int i;
memset(&atkbd->dev, 0, sizeof(struct input_dev));
if (atkbd->extra)
sprintf(atkbd->name, "AT Set 2 Extra keyboard");
else
sprintf(atkbd->name, "AT %s Set %d keyboard",
atkbd->translated ? "Translated" : "Raw", atkbd->set);
init_input_dev(&atkbd->dev);
sprintf(atkbd->phys, "%s/input0", atkbd->ps2dev.serio->phys);
atkbd->dev.name = atkbd->name;
atkbd->dev.phys = atkbd->phys;
atkbd->dev.id.bustype = BUS_I8042;
atkbd->dev.id.vendor = 0x0001;
atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set;
atkbd->dev.id.version = atkbd->id;
atkbd->dev.event = atkbd_event;
atkbd->dev.private = atkbd;
atkbd->dev.dev = &atkbd->ps2dev.serio->dev;
input_dev->name = atkbd->name;
input_dev->phys = atkbd->phys;
input_dev->id.bustype = BUS_I8042;
input_dev->id.vendor = 0x0001;
input_dev->id.product = atkbd->translated ? 1 : atkbd->set;
input_dev->id.version = atkbd->id;
input_dev->event = atkbd_event;
input_dev->private = atkbd;
input_dev->cdev.dev = &atkbd->ps2dev.serio->dev;
atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
if (atkbd->write) {
atkbd->dev.evbit[0] |= BIT(EV_LED);
atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
input_dev->evbit[0] |= BIT(EV_LED);
input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
}
if (atkbd->extra)
atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
input_dev->ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
if (!atkbd->softrepeat) {
atkbd->dev.rep[REP_DELAY] = 250;
atkbd->dev.rep[REP_PERIOD] = 33;
input_dev->rep[REP_DELAY] = 250;
input_dev->rep[REP_PERIOD] = 33;
}
atkbd->dev.mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
input_dev->mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
if (atkbd->scroll) {
atkbd->dev.evbit[0] |= BIT(EV_REL);
atkbd->dev.relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
set_bit(BTN_MIDDLE, atkbd->dev.keybit);
input_dev->evbit[0] |= BIT(EV_REL);
input_dev->relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
set_bit(BTN_MIDDLE, input_dev->keybit);
}
atkbd->dev.keycode = atkbd->keycode;
atkbd->dev.keycodesize = sizeof(unsigned char);
atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
input_dev->keycode = atkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
for (i = 0; i < 512; i++)
if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
set_bit(atkbd->keycode[i], atkbd->dev.keybit);
set_bit(atkbd->keycode[i], input_dev->keybit);
}
/*
@ -796,13 +800,15 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct atkbd *atkbd;
int err;
struct input_dev *dev;
int err = -ENOMEM;
if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL)))
return - ENOMEM;
memset(atkbd, 0, sizeof(struct atkbd));
atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL);
dev = input_allocate_device();
if (!atkbd || !dev)
goto fail;
atkbd->dev = dev;
ps2_init(&atkbd->ps2dev, serio);
switch (serio->id.type) {
@ -828,19 +834,15 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
serio_set_drvdata(serio, atkbd);
err = serio_open(serio, drv);
if (err) {
serio_set_drvdata(serio, NULL);
kfree(atkbd);
return err;
}
if (err)
goto fail;
if (atkbd->write) {
if (atkbd_probe(atkbd)) {
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(atkbd);
return -ENODEV;
err = -ENODEV;
goto fail;
}
atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
@ -851,19 +853,9 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
atkbd->id = 0xab00;
}
if (atkbd->extra)
sprintf(atkbd->name, "AT Set 2 Extra keyboard");
else
sprintf(atkbd->name, "AT %s Set %d keyboard",
atkbd->translated ? "Translated" : "Raw", atkbd->set);
sprintf(atkbd->phys, "%s/input0", serio->phys);
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
input_register_device(&atkbd->dev);
device_create_file(&serio->dev, &atkbd_attr_extra);
device_create_file(&serio->dev, &atkbd_attr_scroll);
device_create_file(&serio->dev, &atkbd_attr_set);
@ -872,9 +864,14 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
atkbd_enable(atkbd);
printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys);
input_register_device(atkbd->dev);
return 0;
fail: serio_set_drvdata(serio, NULL);
input_free_device(dev);
kfree(atkbd);
return err;
}
/*
@ -896,9 +893,9 @@ static int atkbd_reconnect(struct serio *serio)
atkbd_disable(atkbd);
if (atkbd->write) {
param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0)
| (test_bit(LED_NUML, atkbd->dev.led) ? 2 : 0)
| (test_bit(LED_CAPSL, atkbd->dev.led) ? 4 : 0);
param[0] = (test_bit(LED_SCROLLL, atkbd->dev->led) ? 1 : 0)
| (test_bit(LED_NUML, atkbd->dev->led) ? 2 : 0)
| (test_bit(LED_CAPSL, atkbd->dev->led) ? 4 : 0);
if (atkbd_probe(atkbd))
return -1;
@ -1008,6 +1005,7 @@ static ssize_t atkbd_show_extra(struct atkbd *atkbd, char *buf)
static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count)
{
struct input_dev *new_dev;
unsigned long value;
char *rest;
@ -1019,12 +1017,19 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
return -EINVAL;
if (atkbd->extra != value) {
/* unregister device as it's properties will change */
input_unregister_device(&atkbd->dev);
/*
* Since device's properties will change we need to
* unregister old device. But allocate new one first
* to make sure we have it.
*/
if (!(new_dev = input_allocate_device()))
return -ENOMEM;
input_unregister_device(atkbd->dev);
atkbd->dev = new_dev;
atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
atkbd_activate(atkbd);
atkbd_set_device_attrs(atkbd);
input_register_device(&atkbd->dev);
input_register_device(atkbd->dev);
}
return count;
}
@ -1036,6 +1041,7 @@ static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf)
static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count)
{
struct input_dev *new_dev;
unsigned long value;
char *rest;
@ -1044,12 +1050,14 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou
return -EINVAL;
if (atkbd->scroll != value) {
/* unregister device as it's properties will change */
input_unregister_device(&atkbd->dev);
if (!(new_dev = input_allocate_device()))
return -ENOMEM;
input_unregister_device(atkbd->dev);
atkbd->dev = new_dev;
atkbd->scroll = value;
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
input_register_device(&atkbd->dev);
input_register_device(atkbd->dev);
}
return count;
}
@ -1061,6 +1069,7 @@ static ssize_t atkbd_show_set(struct atkbd *atkbd, char *buf)
static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
{
struct input_dev *new_dev;
unsigned long value;
char *rest;
@ -1072,13 +1081,15 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
return -EINVAL;
if (atkbd->set != value) {
/* unregister device as it's properties will change */
input_unregister_device(&atkbd->dev);
if (!(new_dev = input_allocate_device()))
return -ENOMEM;
input_unregister_device(atkbd->dev);
atkbd->dev = new_dev;
atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra);
atkbd_activate(atkbd);
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
input_register_device(&atkbd->dev);
input_register_device(atkbd->dev);
}
return count;
}
@ -1090,6 +1101,7 @@ static ssize_t atkbd_show_softrepeat(struct atkbd *atkbd, char *buf)
static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count)
{
struct input_dev *new_dev;
unsigned long value;
char *rest;
@ -1101,15 +1113,16 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t
return -EINVAL;
if (atkbd->softrepeat != value) {
/* unregister device as it's properties will change */
input_unregister_device(&atkbd->dev);
if (!(new_dev = input_allocate_device()))
return -ENOMEM;
input_unregister_device(atkbd->dev);
atkbd->dev = new_dev;
atkbd->softrepeat = value;
if (atkbd->softrepeat)
atkbd->softraw = 1;
atkbd_set_device_attrs(atkbd);
input_register_device(&atkbd->dev);
input_register_device(atkbd->dev);
}
return count;
}
@ -1121,6 +1134,7 @@ static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf)
static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count)
{
struct input_dev *new_dev;
unsigned long value;
char *rest;
@ -1129,11 +1143,13 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
return -EINVAL;
if (atkbd->softraw != value) {
/* unregister device as it's properties will change */
input_unregister_device(&atkbd->dev);
if (!(new_dev = input_allocate_device()))
return -ENOMEM;
input_unregister_device(atkbd->dev);
atkbd->dev = new_dev;
atkbd->softraw = value;
atkbd_set_device_attrs(atkbd);
input_register_device(&atkbd->dev);
input_register_device(atkbd->dev);
}
return count;
}

View File

@ -70,8 +70,7 @@ static unsigned char corgikbd_keycode[NR_SCANCODES] = {
struct corgikbd {
unsigned char keycode[ARRAY_SIZE(corgikbd_keycode)];
struct input_dev input;
char phys[32];
struct input_dev *input;
spinlock_t lock;
struct timer_list timer;
@ -147,7 +146,7 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
spin_lock_irqsave(&corgikbd_data->lock, flags);
if (regs)
input_regs(&corgikbd_data->input, regs);
input_regs(corgikbd_data->input, regs);
num_pressed = 0;
for (col = 0; col < KB_COLS; col++) {
@ -169,14 +168,14 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
scancode = SCANCODE(row, col);
pressed = rowd & KB_ROWMASK(row);
input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], pressed);
input_report_key(corgikbd_data->input, corgikbd_data->keycode[scancode], pressed);
if (pressed)
num_pressed++;
if (pressed && (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF)
&& time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) {
input_event(&corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
input_event(corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
corgikbd_data->suspend_jiffies=jiffies;
}
}
@ -185,7 +184,7 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
corgikbd_activate_all();
input_sync(&corgikbd_data->input);
input_sync(corgikbd_data->input);
/* if any keys are pressed, enable the timer */
if (num_pressed)
@ -249,9 +248,9 @@ static void corgikbd_hinge_timer(unsigned long data)
if (hinge_count >= HINGE_STABLE_COUNT) {
spin_lock_irqsave(&corgikbd_data->lock, flags);
input_report_switch(&corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
input_report_switch(&corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
input_sync(&corgikbd_data->input);
input_report_switch(corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
input_report_switch(corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
input_sync(corgikbd_data->input);
spin_unlock_irqrestore(&corgikbd_data->lock, flags);
}
@ -260,24 +259,22 @@ static void corgikbd_hinge_timer(unsigned long data)
}
#ifdef CONFIG_PM
static int corgikbd_suspend(struct device *dev, pm_message_t state, uint32_t level)
static int corgikbd_suspend(struct device *dev, pm_message_t state)
{
if (level == SUSPEND_POWER_DOWN) {
struct corgikbd *corgikbd = dev_get_drvdata(dev);
corgikbd->suspended = 1;
}
struct corgikbd *corgikbd = dev_get_drvdata(dev);
corgikbd->suspended = 1;
return 0;
}
static int corgikbd_resume(struct device *dev, uint32_t level)
static int corgikbd_resume(struct device *dev)
{
if (level == RESUME_POWER_ON) {
struct corgikbd *corgikbd = dev_get_drvdata(dev);
struct corgikbd *corgikbd = dev_get_drvdata(dev);
/* Upon resume, ignore the suspend key for a short while */
corgikbd->suspend_jiffies=jiffies;
corgikbd->suspended = 0;
/* Upon resume, ignore the suspend key for a short while */
corgikbd->suspend_jiffies=jiffies;
corgikbd->suspended = 0;
}
return 0;
}
#else
@ -287,16 +284,21 @@ static int corgikbd_resume(struct device *dev, uint32_t level)
static int __init corgikbd_probe(struct device *dev)
{
int i;
struct corgikbd *corgikbd;
struct input_dev *input_dev;
int i;
corgikbd = kzalloc(sizeof(struct corgikbd), GFP_KERNEL);
if (!corgikbd)
input_dev = input_allocate_device();
if (!corgikbd || !input_dev) {
kfree(corgikbd);
input_free_device(input_dev);
return -ENOMEM;
}
dev_set_drvdata(dev,corgikbd);
strcpy(corgikbd->phys, "corgikbd/input0");
dev_set_drvdata(dev, corgikbd);
corgikbd->input = input_dev;
spin_lock_init(&corgikbd->lock);
/* Init Keyboard rescan timer */
@ -311,28 +313,30 @@ static int __init corgikbd_probe(struct device *dev)
corgikbd->suspend_jiffies=jiffies;
init_input_dev(&corgikbd->input);
corgikbd->input.private = corgikbd;
corgikbd->input.name = "Corgi Keyboard";
corgikbd->input.dev = dev;
corgikbd->input.phys = corgikbd->phys;
corgikbd->input.id.bustype = BUS_HOST;
corgikbd->input.id.vendor = 0x0001;
corgikbd->input.id.product = 0x0001;
corgikbd->input.id.version = 0x0100;
corgikbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
corgikbd->input.keycode = corgikbd->keycode;
corgikbd->input.keycodesize = sizeof(unsigned char);
corgikbd->input.keycodemax = ARRAY_SIZE(corgikbd_keycode);
memcpy(corgikbd->keycode, corgikbd_keycode, sizeof(corgikbd->keycode));
for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
set_bit(corgikbd->keycode[i], corgikbd->input.keybit);
clear_bit(0, corgikbd->input.keybit);
set_bit(SW_0, corgikbd->input.swbit);
set_bit(SW_1, corgikbd->input.swbit);
input_register_device(&corgikbd->input);
input_dev->name = "Corgi Keyboard";
input_dev->phys = "corgikbd/input0";
input_dev->id.bustype = BUS_HOST;
input_dev->id.vendor = 0x0001;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = dev;
input_dev->private = corgikbd;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
input_dev->keycode = corgikbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode);
for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
set_bit(corgikbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
set_bit(SW_0, input_dev->swbit);
set_bit(SW_1, input_dev->swbit);
input_register_device(corgikbd->input);
mod_timer(&corgikbd->htimer, jiffies + HINGE_SCAN_INTERVAL);
/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
@ -349,8 +353,6 @@ static int __init corgikbd_probe(struct device *dev)
for (i = 0; i < CORGI_KEY_STROBE_NUM; i++)
pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);
printk(KERN_INFO "input: Corgi Keyboard Registered\n");
return 0;
}
@ -365,7 +367,7 @@ static int corgikbd_remove(struct device *dev)
del_timer_sync(&corgikbd->htimer);
del_timer_sync(&corgikbd->timer);
input_unregister_device(&corgikbd->input);
input_unregister_device(corgikbd->input);
kfree(corgikbd);

View File

@ -102,7 +102,7 @@ static int ctrlclick_volume = 100; /* % */
module_param (ctrlclick_volume, int, 0);
MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");
static int lk201_compose_is_alt = 0;
static int lk201_compose_is_alt;
module_param (lk201_compose_is_alt, int, 0);
MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key "
"will act as an Alt key");
@ -274,7 +274,7 @@ static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = {
};
#define CHECK_LED(LED, BITS) do { \
if (test_bit (LED, lk->dev.led)) \
if (test_bit (LED, lk->dev->led)) \
leds_on |= BITS; \
else \
leds_off |= BITS; \
@ -287,7 +287,7 @@ struct lkkbd {
lk_keycode_t keycode[LK_NUM_KEYCODES];
int ignore_bytes;
unsigned char id[LK_NUM_IGNORE_BYTES];
struct input_dev dev;
struct input_dev *dev;
struct serio *serio;
struct work_struct tq;
char name[64];
@ -423,8 +423,7 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
DBG (KERN_INFO "Got byte 0x%02x\n", data);
if (lk->ignore_bytes > 0) {
DBG (KERN_INFO "Ignoring a byte on %s\n",
lk->name);
DBG (KERN_INFO "Ignoring a byte on %s\n", lk->name);
lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
if (lk->ignore_bytes == 0)
@ -435,14 +434,14 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
switch (data) {
case LK_ALL_KEYS_UP:
input_regs (&lk->dev, regs);
input_regs (lk->dev, regs);
for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++)
if (lk->keycode[i] != KEY_RESERVED)
input_report_key (&lk->dev, lk->keycode[i], 0);
input_sync (&lk->dev);
input_report_key (lk->dev, lk->keycode[i], 0);
input_sync (lk->dev);
break;
case LK_METRONOME:
DBG (KERN_INFO "Got LK_METRONOME and don't "
DBG (KERN_INFO "Got %#d and don't "
"know how to handle...\n");
break;
case LK_OUTPUT_ERROR:
@ -482,12 +481,12 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
default:
if (lk->keycode[data] != KEY_RESERVED) {
input_regs (&lk->dev, regs);
if (!test_bit (lk->keycode[data], lk->dev.key))
input_report_key (&lk->dev, lk->keycode[data], 1);
input_regs (lk->dev, regs);
if (!test_bit (lk->keycode[data], lk->dev->key))
input_report_key (lk->dev, lk->keycode[data], 1);
else
input_report_key (&lk->dev, lk->keycode[data], 0);
input_sync (&lk->dev);
input_report_key (lk->dev, lk->keycode[data], 0);
input_sync (lk->dev);
} else
printk (KERN_WARNING "%s: Unknown key with "
"scancode 0x%02x on %s.\n",
@ -605,7 +604,7 @@ lkkbd_reinit (void *data)
lk->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)) {
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);
@ -616,7 +615,7 @@ lkkbd_reinit (void *data)
}
/* Sound the bell if needed */
if (test_bit (SND_BELL, lk->dev.snd))
if (test_bit (SND_BELL, lk->dev->snd))
lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
}
@ -627,71 +626,70 @@ static int
lkkbd_connect (struct serio *serio, struct serio_driver *drv)
{
struct lkkbd *lk;
struct input_dev *input_dev;
int i;
int err;
if (!(lk = kmalloc (sizeof (struct lkkbd), GFP_KERNEL)))
return -ENOMEM;
memset (lk, 0, sizeof (struct lkkbd));
init_input_dev (&lk->dev);
set_bit (EV_KEY, lk->dev.evbit);
set_bit (EV_LED, lk->dev.evbit);
set_bit (EV_SND, lk->dev.evbit);
set_bit (EV_REP, lk->dev.evbit);
set_bit (LED_CAPSL, lk->dev.ledbit);
set_bit (LED_SLEEP, lk->dev.ledbit);
set_bit (LED_COMPOSE, lk->dev.ledbit);
set_bit (LED_SCROLLL, lk->dev.ledbit);
set_bit (SND_BELL, lk->dev.sndbit);
set_bit (SND_CLICK, lk->dev.sndbit);
lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL);
input_dev = input_allocate_device ();
if (!lk || !input_dev) {
err = -ENOMEM;
goto fail;
}
lk->serio = serio;
lk->dev = input_dev;
INIT_WORK (&lk->tq, lkkbd_reinit, lk);
lk->bell_volume = bell_volume;
lk->keyclick_volume = keyclick_volume;
lk->ctrlclick_volume = ctrlclick_volume;
memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
lk->dev.keycode = lk->keycode;
lk->dev.keycodesize = sizeof (lk_keycode_t);
lk->dev.keycodemax = LK_NUM_KEYCODES;
strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name));
snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);
lk->dev.event = lkkbd_event;
lk->dev.private = lk;
input_dev->name = lk->name;
input_dev->phys = lk->phys;
input_dev->id.bustype = BUS_RS232;
input_dev->id.vendor = SERIO_LKKBD;
input_dev->id.product = 0;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &serio->dev;
input_dev->event = lkkbd_event;
input_dev->private = lk;
set_bit (EV_KEY, input_dev->evbit);
set_bit (EV_LED, input_dev->evbit);
set_bit (EV_SND, input_dev->evbit);
set_bit (EV_REP, input_dev->evbit);
set_bit (LED_CAPSL, input_dev->ledbit);
set_bit (LED_SLEEP, input_dev->ledbit);
set_bit (LED_COMPOSE, input_dev->ledbit);
set_bit (LED_SCROLLL, input_dev->ledbit);
set_bit (SND_BELL, input_dev->sndbit);
set_bit (SND_CLICK, input_dev->sndbit);
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);
serio_set_drvdata (serio, lk);
err = serio_open (serio, drv);
if (err) {
serio_set_drvdata (serio, NULL);
kfree (lk);
return err;
}
if (err)
goto fail;
sprintf (lk->name, "DEC LK keyboard");
sprintf (lk->phys, "%s/input0", serio->phys);
memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
for (i = 0; i < LK_NUM_KEYCODES; i++)
set_bit (lk->keycode[i], lk->dev.keybit);
lk->dev.name = lk->name;
lk->dev.phys = lk->phys;
lk->dev.id.bustype = BUS_RS232;
lk->dev.id.vendor = SERIO_LKKBD;
lk->dev.id.product = 0;
lk->dev.id.version = 0x0100;
lk->dev.dev = &serio->dev;
input_register_device (&lk->dev);
printk (KERN_INFO "input: %s on %s, initiating reset\n", lk->name, serio->phys);
input_register_device (lk->dev);
lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);
return 0;
fail: serio_set_drvdata (serio, NULL);
input_free_device (input_dev);
kfree (lk);
return err;
}
/*
@ -702,9 +700,11 @@ lkkbd_disconnect (struct serio *serio)
{
struct lkkbd *lk = serio_get_drvdata (serio);
input_unregister_device (&lk->dev);
input_get_device (lk->dev);
input_unregister_device (lk->dev);
serio_close (serio);
serio_set_drvdata (serio, NULL);
input_put_device (lk->dev);
kfree (lk);
}

View File

@ -37,7 +37,7 @@ static unsigned char dc_kbd_keycode[256] = {
struct dc_kbd {
struct input_dev dev;
struct input_dev *dev;
unsigned char new[8];
unsigned char old[8];
};
@ -46,30 +46,24 @@ struct dc_kbd {
static void dc_scan_kbd(struct dc_kbd *kbd)
{
int i;
struct input_dev *dev = &kbd->dev;
struct input_dev *dev = kbd->dev;
for(i=0; i<8; i++)
input_report_key(dev,
dc_kbd_keycode[i+224],
(kbd->new[0]>>i)&1);
for (i = 0; i < 8; i++)
input_report_key(dev, dc_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
for(i=2; i<8; i++) {
for (i = 2; i < 8; i++) {
if(kbd->old[i]>3&&memscan(kbd->new+2, kbd->old[i], 6)==NULL) {
if(dc_kbd_keycode[kbd->old[i]])
input_report_key(dev,
dc_kbd_keycode[kbd->old[i]],
0);
if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == NULL) {
if (dc_kbd_keycode[kbd->old[i]])
input_report_key(dev, dc_kbd_keycode[kbd->old[i]], 0);
else
printk("Unknown key (scancode %#x) released.",
kbd->old[i]);
}
if(kbd->new[i]>3&&memscan(kbd->old+2, kbd->new[i], 6)!=NULL) {
if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) != NULL) {
if(dc_kbd_keycode[kbd->new[i]])
input_report_key(dev,
dc_kbd_keycode[kbd->new[i]],
1);
input_report_key(dev, dc_kbd_keycode[kbd->new[i]], 1);
else
printk("Unknown key (scancode %#x) pressed.",
kbd->new[i]);
@ -89,43 +83,39 @@ static void dc_kbd_callback(struct mapleq *mq)
unsigned long *buf = mq->recvbuf;
if (buf[1] == mapledev->function) {
memcpy(kbd->new, buf+2, 8);
memcpy(kbd->new, buf + 2, 8);
dc_scan_kbd(kbd);
}
}
static int dc_kbd_connect(struct maple_device *dev)
{
int i;
unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
struct dc_kbd *kbd;
struct input_dev *input_dev;
unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
int i;
if (!(kbd = kmalloc(sizeof(struct dc_kbd), GFP_KERNEL)))
return -1;
memset(kbd, 0, sizeof(struct dc_kbd));
dev->private_data = kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL);
input_dev = input_allocate_device();
if (!kbd || !input_dev) {
kfree(kbd);
input_free_device(input_dev);
return -ENOMEM;
}
dev->private_data = kbd;
kbd->dev = input_dev;
kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
input_dev->name = dev->product_name;
input_dev->id.bustype = BUS_MAPLE;
input_dev->private = kbd;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
for (i = 0; i < 255; i++)
set_bit(dc_kbd_keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
init_input_dev(&kbd->dev);
for (i=0; i<255; i++)
set_bit(dc_kbd_keycode[i], kbd->dev.keybit);
clear_bit(0, kbd->dev.keybit);
kbd->dev.private = kbd;
kbd->dev.name = dev->product_name;
kbd->dev.id.bustype = BUS_MAPLE;
input_register_device(&kbd->dev);
input_register_device(kbd->dev);
maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD);
printk(KERN_INFO "input: keyboard(0x%lx): %s\n", data, kbd->dev.name);
return 0;
}
@ -134,7 +124,7 @@ static void dc_kbd_disconnect(struct maple_device *dev)
{
struct dc_kbd *kbd = dev->private_data;
input_unregister_device(&kbd->dev);
input_unregister_device(kbd->dev);
kfree(kbd);
}

View File

@ -57,11 +57,9 @@ static unsigned char nkbd_keycode[128] = {
KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0
};
static char *nkbd_name = "Newton Keyboard";
struct nkbd {
unsigned char keycode[128];
struct input_dev dev;
struct input_dev *dev;
struct serio *serio;
char phys[32];
};
@ -73,13 +71,13 @@ static irqreturn_t nkbd_interrupt(struct serio *serio,
/* invalid scan codes are probably the init sequence, so we ignore them */
if (nkbd->keycode[data & NKBD_KEY]) {
input_regs(&nkbd->dev, regs);
input_report_key(&nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
input_sync(&nkbd->dev);
input_regs(nkbd->dev, regs);
input_report_key(nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
input_sync(nkbd->dev);
}
else if (data == 0xe7) /* end of init sequence */
printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
printk(KERN_INFO "input: %s on %s\n", nkbd->dev->name, serio->phys);
return IRQ_HANDLED;
}
@ -87,62 +85,59 @@ static irqreturn_t nkbd_interrupt(struct serio *serio,
static int nkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct nkbd *nkbd;
struct input_dev *input_dev;
int err = -ENOMEM;
int i;
int err;
if (!(nkbd = kmalloc(sizeof(struct nkbd), GFP_KERNEL)))
return -ENOMEM;
memset(nkbd, 0, sizeof(struct nkbd));
nkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
nkbd = kzalloc(sizeof(struct nkbd), GFP_KERNEL);
input_dev = input_allocate_device();
if (!nkbd || !input_dev)
goto fail;
nkbd->serio = serio;
nkbd->dev = input_dev;
sprintf(nkbd->phys, "%s/input0", serio->phys);
memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
init_input_dev(&nkbd->dev);
nkbd->dev.keycode = nkbd->keycode;
nkbd->dev.keycodesize = sizeof(unsigned char);
nkbd->dev.keycodemax = ARRAY_SIZE(nkbd_keycode);
nkbd->dev.private = nkbd;
input_dev->name = "Newton Keyboard";
input_dev->phys = nkbd->phys;
input_dev->id.bustype = BUS_RS232;
input_dev->id.vendor = SERIO_NEWTON;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &serio->dev;
input_dev->private = nkbd;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
input_dev->keycode = nkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(nkbd_keycode);
for (i = 0; i < 128; i++)
set_bit(nkbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
serio_set_drvdata(serio, nkbd);
err = serio_open(serio, drv);
if (err) {
serio_set_drvdata(serio, NULL);
kfree(nkbd);
return err;
}
memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
for (i = 0; i < 128; i++)
set_bit(nkbd->keycode[i], nkbd->dev.keybit);
clear_bit(0, nkbd->dev.keybit);
sprintf(nkbd->phys, "%s/input0", serio->phys);
nkbd->dev.name = nkbd_name;
nkbd->dev.phys = nkbd->phys;
nkbd->dev.id.bustype = BUS_RS232;
nkbd->dev.id.vendor = SERIO_NEWTON;
nkbd->dev.id.product = 0x0001;
nkbd->dev.id.version = 0x0100;
nkbd->dev.dev = &serio->dev;
input_register_device(&nkbd->dev);
printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
if (err)
goto fail;
input_register_device(nkbd->dev);
return 0;
fail: serio_set_drvdata(serio, NULL);
input_free_device(input_dev);
kfree(nkbd);
return err;
}
static void nkbd_disconnect(struct serio *serio)
{
struct nkbd *nkbd = serio_get_drvdata(serio);
input_unregister_device(&nkbd->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
input_unregister_device(nkbd->dev);
kfree(nkbd);
}

View File

@ -85,7 +85,7 @@ static int spitz_senses[] = {
struct spitzkbd {
unsigned char keycode[ARRAY_SIZE(spitzkbd_keycode)];
struct input_dev input;
struct input_dev *input;
char phys[32];
spinlock_t lock;
@ -187,8 +187,7 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
spin_lock_irqsave(&spitzkbd_data->lock, flags);
if (regs)
input_regs(&spitzkbd_data->input, regs);
input_regs(spitzkbd_data->input, regs);
num_pressed = 0;
for (col = 0; col < KB_COLS; col++) {
@ -210,7 +209,7 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
scancode = SCANCODE(row, col);
pressed = rowd & KB_ROWMASK(row);
input_report_key(&spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
input_report_key(spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
if (pressed)
num_pressed++;
@ -220,15 +219,15 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
spitzkbd_activate_all();
input_report_key(&spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
input_report_key(&spitzkbd_data->input, KEY_SUSPEND, pwrkey);
input_report_key(spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
input_report_key(spitzkbd_data->input, KEY_SUSPEND, pwrkey);
if (pwrkey && time_after(jiffies, spitzkbd_data->suspend_jiffies + msecs_to_jiffies(1000))) {
input_event(&spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
input_event(spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
spitzkbd_data->suspend_jiffies = jiffies;
}
input_sync(&spitzkbd_data->input);
input_sync(spitzkbd_data->input);
/* if any keys are pressed, enable the timer */
if (num_pressed)
@ -259,6 +258,7 @@ static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id, struct pt_regs *reg
static void spitzkbd_timer_callback(unsigned long data)
{
struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
spitzkbd_scankeyboard(spitzkbd_data, NULL);
}
@ -298,9 +298,9 @@ static void spitzkbd_hinge_timer(unsigned long data)
if (hinge_count >= HINGE_STABLE_COUNT) {
spin_lock_irqsave(&spitzkbd_data->lock, flags);
input_report_switch(&spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
input_report_switch(&spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
input_sync(&spitzkbd_data->input);
input_report_switch(spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
input_report_switch(spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
input_sync(spitzkbd_data->input);
spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
} else {
@ -309,34 +309,32 @@ static void spitzkbd_hinge_timer(unsigned long data)
}
#ifdef CONFIG_PM
static int spitzkbd_suspend(struct device *dev, pm_message_t state, uint32_t level)
static int spitzkbd_suspend(struct device *dev, pm_message_t state)
{
if (level == SUSPEND_POWER_DOWN) {
int i;
struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
spitzkbd->suspended = 1;
int i;
struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
spitzkbd->suspended = 1;
/* Set Strobe lines as inputs - *except* strobe line 0 leave this
enabled so we can detect a power button press for resume */
for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
/* Set Strobe lines as inputs - *except* strobe line 0 leave this
enabled so we can detect a power button press for resume */
for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
}
return 0;
}
static int spitzkbd_resume(struct device *dev, uint32_t level)
static int spitzkbd_resume(struct device *dev)
{
if (level == RESUME_POWER_ON) {
int i;
struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
int i;
struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
/* Upon resume, ignore the suspend key for a short while */
spitzkbd->suspend_jiffies = jiffies;
spitzkbd->suspended = 0;
/* Upon resume, ignore the suspend key for a short while */
spitzkbd->suspend_jiffies = jiffies;
spitzkbd->suspended = 0;
}
return 0;
}
#else
@ -346,14 +344,21 @@ static int spitzkbd_resume(struct device *dev, uint32_t level)
static int __init spitzkbd_probe(struct device *dev)
{
int i;
struct spitzkbd *spitzkbd;
struct input_dev *input_dev;
int i;
spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL);
if (!spitzkbd)
return -ENOMEM;
dev_set_drvdata(dev,spitzkbd);
input_dev = input_allocate_device();
if (!input_dev) {
kfree(spitzkbd);
return -ENOMEM;
}
dev_set_drvdata(dev, spitzkbd);
strcpy(spitzkbd->phys, "spitzkbd/input0");
spin_lock_init(&spitzkbd->lock);
@ -368,30 +373,34 @@ static int __init spitzkbd_probe(struct device *dev)
spitzkbd->htimer.function = spitzkbd_hinge_timer;
spitzkbd->htimer.data = (unsigned long) spitzkbd;
spitzkbd->suspend_jiffies=jiffies;
spitzkbd->suspend_jiffies = jiffies;
init_input_dev(&spitzkbd->input);
spitzkbd->input.private = spitzkbd;
spitzkbd->input.name = "Spitz Keyboard";
spitzkbd->input.dev = dev;
spitzkbd->input.phys = spitzkbd->phys;
spitzkbd->input.id.bustype = BUS_HOST;
spitzkbd->input.id.vendor = 0x0001;
spitzkbd->input.id.product = 0x0001;
spitzkbd->input.id.version = 0x0100;
spitzkbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
spitzkbd->input.keycode = spitzkbd->keycode;
spitzkbd->input.keycodesize = sizeof(unsigned char);
spitzkbd->input.keycodemax = ARRAY_SIZE(spitzkbd_keycode);
spitzkbd->input = input_dev;
input_dev->private = spitzkbd;
input_dev->name = "Spitz Keyboard";
input_dev->phys = spitzkbd->phys;
input_dev->cdev.dev = dev;
input_dev->id.bustype = BUS_HOST;
input_dev->id.vendor = 0x0001;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
input_dev->keycode = spitzkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode);
memcpy(spitzkbd->keycode, spitzkbd_keycode, sizeof(spitzkbd->keycode));
for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++)
set_bit(spitzkbd->keycode[i], spitzkbd->input.keybit);
clear_bit(0, spitzkbd->input.keybit);
set_bit(SW_0, spitzkbd->input.swbit);
set_bit(SW_1, spitzkbd->input.swbit);
set_bit(spitzkbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
set_bit(SW_0, input_dev->swbit);
set_bit(SW_1, input_dev->swbit);
input_register_device(input_dev);
input_register_device(&spitzkbd->input);
mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
@ -444,7 +453,7 @@ static int spitzkbd_remove(struct device *dev)
del_timer_sync(&spitzkbd->htimer);
del_timer_sync(&spitzkbd->timer);
input_unregister_device(&spitzkbd->input);
input_unregister_device(spitzkbd->input);
kfree(spitzkbd);

View File

@ -76,13 +76,14 @@ static unsigned char sunkbd_keycode[128] = {
struct sunkbd {
unsigned char keycode[128];
struct input_dev dev;
struct input_dev *dev;
struct serio *serio;
struct work_struct tq;
wait_queue_head_t wait;
char name[64];
char phys[32];
char type;
unsigned char enabled;
volatile s8 reset;
volatile s8 layout;
};
@ -124,10 +125,13 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio,
break;
default:
if (!sunkbd->enabled)
break;
if (sunkbd->keycode[data & SUNKBD_KEY]) {
input_regs(&sunkbd->dev, regs);
input_report_key(&sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
input_sync(&sunkbd->dev);
input_regs(sunkbd->dev, regs);
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");
@ -184,7 +188,7 @@ static int sunkbd_initialize(struct sunkbd *sunkbd)
sunkbd->reset = -2;
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_RESET);
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
if (sunkbd->reset <0)
if (sunkbd->reset < 0)
return -1;
sunkbd->type = sunkbd->reset;
@ -213,10 +217,17 @@ static void sunkbd_reinit(void *data)
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));
(!!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));
}
static void sunkbd_enable(struct sunkbd *sunkbd, int enable)
{
serio_pause_rx(sunkbd->serio);
sunkbd->enabled = 1;
serio_continue_rx(sunkbd->serio);
}
/*
@ -226,70 +237,64 @@ static void sunkbd_reinit(void *data)
static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct sunkbd *sunkbd;
struct input_dev *input_dev;
int err = -ENOMEM;
int i;
int err;
if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL)))
return -ENOMEM;
memset(sunkbd, 0, sizeof(struct sunkbd));
init_input_dev(&sunkbd->dev);
init_waitqueue_head(&sunkbd->wait);
sunkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
sunkbd->dev.ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
sunkbd->dev.sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL);
input_dev = input_allocate_device();
if (!sunkbd || !input_dev)
goto fail;
sunkbd->serio = serio;
sunkbd->dev = input_dev;
init_waitqueue_head(&sunkbd->wait);
INIT_WORK(&sunkbd->tq, sunkbd_reinit, sunkbd);
sunkbd->dev.keycode = sunkbd->keycode;
sunkbd->dev.keycodesize = sizeof(unsigned char);
sunkbd->dev.keycodemax = ARRAY_SIZE(sunkbd_keycode);
sunkbd->dev.event = sunkbd_event;
sunkbd->dev.private = sunkbd;
snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys);
serio_set_drvdata(serio, sunkbd);
err = serio_open(serio, drv);
if (err) {
serio_set_drvdata(serio, NULL);
kfree(sunkbd);
return err;
}
if (err)
goto fail;
if (sunkbd_initialize(sunkbd) < 0) {
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(sunkbd);
return -ENODEV;
goto fail;
}
sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type);
memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
input_dev->name = sunkbd->name;
input_dev->phys = sunkbd->phys;
input_dev->id.bustype = BUS_RS232;
input_dev->id.vendor = SERIO_SUNKBD;
input_dev->id.product = sunkbd->type;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &serio->dev;
input_dev->private = sunkbd;
input_dev->event = sunkbd_event;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
input_dev->ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
input_dev->sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
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], sunkbd->dev.keybit);
clear_bit(0, sunkbd->dev.keybit);
sprintf(sunkbd->phys, "%s/input0", serio->phys);
sunkbd->dev.name = sunkbd->name;
sunkbd->dev.phys = sunkbd->phys;
sunkbd->dev.id.bustype = BUS_RS232;
sunkbd->dev.id.vendor = SERIO_SUNKBD;
sunkbd->dev.id.product = sunkbd->type;
sunkbd->dev.id.version = 0x0100;
sunkbd->dev.dev = &serio->dev;
input_register_device(&sunkbd->dev);
printk(KERN_INFO "input: %s on %s\n", sunkbd->name, serio->phys);
set_bit(sunkbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
sunkbd_enable(sunkbd, 1);
input_register_device(sunkbd->dev);
return 0;
fail: serio_set_drvdata(serio, NULL);
input_free_device(input_dev);
kfree(sunkbd);
return err;
}
/*
@ -299,7 +304,9 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
static void sunkbd_disconnect(struct serio *serio)
{
struct sunkbd *sunkbd = serio_get_drvdata(serio);
input_unregister_device(&sunkbd->dev);
sunkbd_enable(sunkbd, 0);
input_unregister_device(sunkbd->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(sunkbd);

View File

@ -56,11 +56,9 @@ static unsigned char xtkbd_keycode[256] = {
106
};
static char *xtkbd_name = "XT Keyboard";
struct xtkbd {
unsigned char keycode[256];
struct input_dev dev;
struct input_dev *dev;
struct serio *serio;
char phys[32];
};
@ -77,9 +75,9 @@ static irqreturn_t xtkbd_interrupt(struct serio *serio,
default:
if (xtkbd->keycode[data & XTKBD_KEY]) {
input_regs(&xtkbd->dev, regs);
input_report_key(&xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
input_sync(&xtkbd->dev);
input_regs(xtkbd->dev, regs);
input_report_key(xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
input_sync(xtkbd->dev);
} else {
printk(KERN_WARNING "xtkbd.c: Unknown key (scancode %#x) %s.\n",
data & XTKBD_KEY, data & XTKBD_RELEASE ? "released" : "pressed");
@ -91,62 +89,60 @@ static irqreturn_t xtkbd_interrupt(struct serio *serio,
static int xtkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct xtkbd *xtkbd;
struct input_dev *input_dev;
int err = -ENOMEM;
int i;
int err;
if (!(xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL)))
return -ENOMEM;
memset(xtkbd, 0, sizeof(struct xtkbd));
xtkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL);
input_dev = input_allocate_device();
if (!xtkbd || !input_dev)
goto fail;
xtkbd->serio = serio;
xtkbd->dev = input_dev;
sprintf(xtkbd->phys, "%s/input0", serio->phys);
memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode));
init_input_dev(&xtkbd->dev);
xtkbd->dev.keycode = xtkbd->keycode;
xtkbd->dev.keycodesize = sizeof(unsigned char);
xtkbd->dev.keycodemax = ARRAY_SIZE(xtkbd_keycode);
xtkbd->dev.private = xtkbd;
input_dev->name = "XT Keyboard";
input_dev->phys = xtkbd->phys;
input_dev->id.bustype = BUS_XTKBD;
input_dev->id.vendor = 0x0001;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &serio->dev;
input_dev->private = xtkbd;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
input_dev->keycode = xtkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(xtkbd_keycode);
for (i = 0; i < 255; i++)
set_bit(xtkbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
serio_set_drvdata(serio, xtkbd);
err = serio_open(serio, drv);
if (err) {
serio_set_drvdata(serio, NULL);
kfree(xtkbd);
return err;
}
memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode));
for (i = 0; i < 255; i++)
set_bit(xtkbd->keycode[i], xtkbd->dev.keybit);
clear_bit(0, xtkbd->dev.keybit);
sprintf(xtkbd->phys, "%s/input0", serio->phys);
xtkbd->dev.name = xtkbd_name;
xtkbd->dev.phys = xtkbd->phys;
xtkbd->dev.id.bustype = BUS_XTKBD;
xtkbd->dev.id.vendor = 0x0001;
xtkbd->dev.id.product = 0x0001;
xtkbd->dev.id.version = 0x0100;
xtkbd->dev.dev = &serio->dev;
input_register_device(&xtkbd->dev);
printk(KERN_INFO "input: %s on %s\n", xtkbd_name, serio->phys);
if (err)
goto fail;
input_register_device(xtkbd->dev);
return 0;
fail: serio_set_drvdata(serio, NULL);
input_free_device(input_dev);
kfree(xtkbd);
return err;
}
static void xtkbd_disconnect(struct serio *serio)
{
struct xtkbd *xtkbd = serio_get_drvdata(serio);
input_unregister_device(&xtkbd->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
input_unregister_device(xtkbd->dev);
kfree(xtkbd);
}

View File

@ -24,9 +24,7 @@ MODULE_AUTHOR("Richard Zidlicky <rz@linux-m68k.org>");
MODULE_DESCRIPTION("m68k beeper driver");
MODULE_LICENSE("GPL");
static char m68kspkr_name[] = "m68k beeper";
static char m68kspkr_phys[] = "m68k/generic";
static struct input_dev m68kspkr_dev;
static struct input_dev *m68kspkr_dev;
static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
@ -51,32 +49,34 @@ static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int
static int __init m68kspkr_init(void)
{
if (!mach_beep){
printk("%s: no lowlevel beep support\n", m68kspkr_name);
return -1;
if (!mach_beep) {
printk(KERN_INFO "m68kspkr: no lowlevel beep support\n");
return -ENODEV;
}
m68kspkr_dev.evbit[0] = BIT(EV_SND);
m68kspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
m68kspkr_dev.event = m68kspkr_event;
m68kspkr_dev = input_allocate_device();
if (!m68kspkr_dev)
return -ENOMEM;
m68kspkr_dev.name = m68kspkr_name;
m68kspkr_dev.phys = m68kspkr_phys;
m68kspkr_dev.id.bustype = BUS_HOST;
m68kspkr_dev.id.vendor = 0x001f;
m68kspkr_dev.id.product = 0x0001;
m68kspkr_dev.id.version = 0x0100;
m68kspkr_dev->name = "m68k beeper";
m68kspkr_dev->phys = "m68k/generic";
m68kspkr_dev->id.bustype = BUS_HOST;
m68kspkr_dev->id.vendor = 0x001f;
m68kspkr_dev->id.product = 0x0001;
m68kspkr_dev->id.version = 0x0100;
input_register_device(&m68kspkr_dev);
m68kspkr_dev->evbit[0] = BIT(EV_SND);
m68kspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
m68kspkr_dev->event = m68kspkr_event;
printk(KERN_INFO "input: %s\n", m68kspkr_name);
input_register_device(m68kspkr_dev);
return 0;
}
static void __exit m68kspkr_exit(void)
{
input_unregister_device(&m68kspkr_dev);
input_unregister_device(m68kspkr_dev);
}
module_init(m68kspkr_init);

View File

@ -23,9 +23,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("PC Speaker beeper driver");
MODULE_LICENSE("GPL");
static char pcspkr_name[] = "PC Speaker";
static char pcspkr_phys[] = "isa0061/input0";
static struct input_dev pcspkr_dev;
static struct input_dev *pcspkr_dev;
static DEFINE_SPINLOCK(i8253_beep_lock);
@ -68,27 +66,29 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
static int __init pcspkr_init(void)
{
pcspkr_dev.evbit[0] = BIT(EV_SND);
pcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
pcspkr_dev.event = pcspkr_event;
pcspkr_dev = input_allocate_device();
if (!pcspkr_dev)
return -ENOMEM;
pcspkr_dev.name = pcspkr_name;
pcspkr_dev.phys = pcspkr_phys;
pcspkr_dev.id.bustype = BUS_ISA;
pcspkr_dev.id.vendor = 0x001f;
pcspkr_dev.id.product = 0x0001;
pcspkr_dev.id.version = 0x0100;
pcspkr_dev->name = "PC Speaker";
pcspkr_dev->name = "isa0061/input0";
pcspkr_dev->id.bustype = BUS_ISA;
pcspkr_dev->id.vendor = 0x001f;
pcspkr_dev->id.product = 0x0001;
pcspkr_dev->id.version = 0x0100;
input_register_device(&pcspkr_dev);
pcspkr_dev->evbit[0] = BIT(EV_SND);
pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
pcspkr_dev->event = pcspkr_event;
printk(KERN_INFO "input: %s\n", pcspkr_name);
input_register_device(pcspkr_dev);
return 0;
}
static void __exit pcspkr_exit(void)
{
input_unregister_device(&pcspkr_dev);
input_unregister_device(pcspkr_dev);
/* turn off the speaker */
pcspkr_event(NULL, EV_SND, SND_BELL, 0);
}

View File

@ -17,28 +17,24 @@
#endif
MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
MODULE_DESCRIPTION("PC Speaker beeper driver");
MODULE_DESCRIPTION("Sparc Speaker beeper driver");
MODULE_LICENSE("GPL");
static unsigned long beep_iobase;
static char *sparcspkr_isa_name = "Sparc ISA Speaker";
static char *sparcspkr_ebus_name = "Sparc EBUS Speaker";
static char *sparcspkr_phys = "sparc/input0";
static struct input_dev sparcspkr_dev;
static struct input_dev *sparcspkr_dev;
DEFINE_SPINLOCK(beep_lock);
static void __init init_sparcspkr_struct(void)
{
sparcspkr_dev.evbit[0] = BIT(EV_SND);
sparcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
sparcspkr_dev->evbit[0] = BIT(EV_SND);
sparcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
sparcspkr_dev.phys = sparcspkr_phys;
sparcspkr_dev.id.bustype = BUS_ISA;
sparcspkr_dev.id.vendor = 0x001f;
sparcspkr_dev.id.product = 0x0001;
sparcspkr_dev.id.version = 0x0100;
sparcspkr_dev->phys = "sparc/input0";
sparcspkr_dev->id.bustype = BUS_ISA;
sparcspkr_dev->id.vendor = 0x001f;
sparcspkr_dev->id.product = 0x0001;
sparcspkr_dev->id.version = 0x0100;
}
static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@ -84,14 +80,15 @@ static int __init init_ebus_beep(struct linux_ebus_device *edev)
{
beep_iobase = edev->resource[0].start;
init_sparcspkr_struct();
sparcspkr_dev = input_allocate_device();
if (!sparcspkr_dev)
return -ENOMEM;
sparcspkr_dev.name = sparcspkr_ebus_name;
sparcspkr_dev.event = ebus_spkr_event;
sparcspkr_dev->name = "Sparc EBUS Speaker";
sparcspkr_dev->event = ebus_spkr_event;
input_register_device(&sparcspkr_dev);
input_register_device(sparcspkr_dev);
printk(KERN_INFO "input: %s\n", sparcspkr_ebus_name);
return 0;
}
@ -137,15 +134,17 @@ static int __init init_isa_beep(struct sparc_isa_device *isa_dev)
{
beep_iobase = isa_dev->resource.start;
sparcspkr_dev = input_allocate_device();
if (!sparcspkr_dev)
return -ENOMEM;
init_sparcspkr_struct();
sparcspkr_dev.name = sparcspkr_isa_name;
sparcspkr_dev.event = isa_spkr_event;
sparcspkr_dev.id.bustype = BUS_ISA;
sparcspkr_dev->name = "Sparc ISA Speaker";
sparcspkr_dev->event = isa_spkr_event;
input_register_device(&sparcspkr_dev);
printk(KERN_INFO "input: %s\n", sparcspkr_isa_name);
return 0;
}
#endif
@ -182,7 +181,7 @@ static int __init sparcspkr_init(void)
static void __exit sparcspkr_exit(void)
{
input_unregister_device(&sparcspkr_dev);
input_unregister_device(sparcspkr_dev);
}
module_init(sparcspkr_init);

View File

@ -79,8 +79,8 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
{
struct alps_data *priv = psmouse->private;
unsigned char *packet = psmouse->packet;
struct input_dev *dev = &psmouse->dev;
struct input_dev *dev2 = &priv->dev2;
struct input_dev *dev = psmouse->dev;
struct input_dev *dev2 = priv->dev2;
int x, y, z, ges, fin, left, right, middle;
int back = 0, forward = 0;
@ -379,20 +379,24 @@ static int alps_reconnect(struct psmouse *psmouse)
static void alps_disconnect(struct psmouse *psmouse)
{
struct alps_data *priv = psmouse->private;
psmouse_reset(psmouse);
input_unregister_device(&priv->dev2);
input_unregister_device(priv->dev2);
kfree(priv);
}
int alps_init(struct psmouse *psmouse)
{
struct alps_data *priv;
struct input_dev *dev1 = psmouse->dev, *dev2;
int version;
psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL);
if (!priv)
psmouse->private = priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
dev2 = input_allocate_device();
if (!priv || !dev2)
goto init_fail;
memset(priv, 0, sizeof(struct alps_data));
priv->dev2 = dev2;
if (!(priv->i = alps_get_model(psmouse, &version)))
goto init_fail;
@ -411,41 +415,39 @@ int alps_init(struct psmouse *psmouse)
if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
goto init_fail;
psmouse->dev.evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
psmouse->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
psmouse->dev.keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
psmouse->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
dev1->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
dev1->keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
dev1->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
psmouse->dev.evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
input_set_abs_params(&psmouse->dev, ABS_X, 0, 1023, 0, 0);
input_set_abs_params(&psmouse->dev, ABS_Y, 0, 767, 0, 0);
input_set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 127, 0, 0);
dev1->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
if (priv->i->flags & ALPS_WHEEL) {
psmouse->dev.evbit[LONG(EV_REL)] |= BIT(EV_REL);
psmouse->dev.relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
dev1->evbit[LONG(EV_REL)] |= BIT(EV_REL);
dev1->relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
}
if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
dev1->keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
}
sprintf(priv->phys, "%s/input1", psmouse->ps2dev.serio->phys);
priv->dev2.phys = priv->phys;
priv->dev2.name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
priv->dev2.id.bustype = BUS_I8042;
priv->dev2.id.vendor = 0x0002;
priv->dev2.id.product = PSMOUSE_ALPS;
priv->dev2.id.version = 0x0000;
dev2->phys = priv->phys;
dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
dev2->id.bustype = BUS_I8042;
dev2->id.vendor = 0x0002;
dev2->id.product = PSMOUSE_ALPS;
dev2->id.version = 0x0000;
priv->dev2.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
priv->dev2.relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
priv->dev2.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
input_register_device(&priv->dev2);
printk(KERN_INFO "input: %s on %s\n", priv->dev2.name, psmouse->ps2dev.serio->phys);
input_register_device(priv->dev2);
psmouse->protocol_handler = alps_process_byte;
psmouse->disconnect = alps_disconnect;
@ -455,6 +457,7 @@ int alps_init(struct psmouse *psmouse)
return 0;
init_fail:
input_free_device(dev2);
kfree(priv);
return -1;
}

View File

@ -22,7 +22,7 @@ struct alps_model_info {
};
struct alps_data {
struct input_dev dev2; /* Relative device */
struct input_dev *dev2; /* Relative device */
char name[32]; /* Name */
char phys[32]; /* Phys */
struct alps_model_info *i; /* Info */

View File

@ -34,10 +34,7 @@ MODULE_DESCRIPTION("Amiga mouse driver");
MODULE_LICENSE("GPL");
static int amimouse_lastx, amimouse_lasty;
static struct input_dev amimouse_dev;
static char *amimouse_name = "Amiga mouse";
static char *amimouse_phys = "amimouse/input0";
static struct input_dev *amimouse_dev;
static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
@ -62,16 +59,16 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
potgor = custom.potgor;
input_regs(&amimouse_dev, fp);
input_regs(amimouse_dev, fp);
input_report_rel(&amimouse_dev, REL_X, dx);
input_report_rel(&amimouse_dev, REL_Y, dy);
input_report_rel(amimouse_dev, REL_X, dx);
input_report_rel(amimouse_dev, REL_Y, dy);
input_report_key(&amimouse_dev, BTN_LEFT, ciaa.pra & 0x40);
input_report_key(&amimouse_dev, BTN_MIDDLE, potgor & 0x0100);
input_report_key(&amimouse_dev, BTN_RIGHT, potgor & 0x0400);
input_report_key(amimouse_dev, BTN_LEFT, ciaa.pra & 0x40);
input_report_key(amimouse_dev, BTN_MIDDLE, potgor & 0x0100);
input_report_key(amimouse_dev, BTN_RIGHT, potgor & 0x0400);
input_sync(&amimouse_dev);
input_sync(amimouse_dev);
return IRQ_HANDLED;
}
@ -103,28 +100,30 @@ static int __init amimouse_init(void)
if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE))
return -ENODEV;
amimouse_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
amimouse_dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
amimouse_dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
amimouse_dev.open = amimouse_open;
amimouse_dev.close = amimouse_close;
if (!(amimouse_dev = input_allocate_device()))
return -ENOMEM;
amimouse_dev.name = amimouse_name;
amimouse_dev.phys = amimouse_phys;
amimouse_dev.id.bustype = BUS_AMIGA;
amimouse_dev.id.vendor = 0x0001;
amimouse_dev.id.product = 0x0002;
amimouse_dev.id.version = 0x0100;
amimouse_dev->name = "Amiga mouse";
amimouse_dev->phys = "amimouse/input0";
amimouse_dev->id.bustype = BUS_AMIGA;
amimouse_dev->id.vendor = 0x0001;
amimouse_dev->id.product = 0x0002;
amimouse_dev->id.version = 0x0100;
input_register_device(&amimouse_dev);
amimouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
amimouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
amimouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
amimouse_dev->open = amimouse_open;
amimouse_dev->close = amimouse_close;
input_register_device(amimouse_dev);
printk(KERN_INFO "input: %s at joy0dat\n", amimouse_name);
return 0;
}
static void __exit amimouse_exit(void)
{
input_unregister_device(&amimouse_dev);
input_unregister_device(amimouse_dev);
}
module_init(amimouse_init);

View File

@ -87,7 +87,36 @@ MODULE_PARM_DESC(irq, "IRQ number (5=default)");
__obsolete_setup("inport_irq=");
static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static struct input_dev *inport_dev;
static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned char buttons;
outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
input_regs(inport_dev, regs);
outb(INPORT_REG_X, INPORT_CONTROL_PORT);
input_report_rel(inport_dev, REL_X, inb(INPORT_DATA_PORT));
outb(INPORT_REG_Y, INPORT_CONTROL_PORT);
input_report_rel(inport_dev, REL_Y, inb(INPORT_DATA_PORT));
outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT);
buttons = inb(INPORT_DATA_PORT);
input_report_key(inport_dev, BTN_MIDDLE, buttons & 1);
input_report_key(inport_dev, BTN_LEFT, buttons & 2);
input_report_key(inport_dev, BTN_RIGHT, buttons & 4);
outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
input_sync(inport_dev);
return IRQ_HANDLED;
}
static int inport_open(struct input_dev *dev)
{
@ -106,54 +135,9 @@ static void inport_close(struct input_dev *dev)
free_irq(inport_irq, NULL);
}
static struct input_dev inport_dev = {
.evbit = { BIT(EV_KEY) | BIT(EV_REL) },
.keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) },
.relbit = { BIT(REL_X) | BIT(REL_Y) },
.open = inport_open,
.close = inport_close,
.name = INPORT_NAME,
.phys = "isa023c/input0",
.id = {
.bustype = BUS_ISA,
.vendor = INPORT_VENDOR,
.product = 0x0001,
.version = 0x0100,
},
};
static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned char buttons;
outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
input_regs(&inport_dev, regs);
outb(INPORT_REG_X, INPORT_CONTROL_PORT);
input_report_rel(&inport_dev, REL_X, inb(INPORT_DATA_PORT));
outb(INPORT_REG_Y, INPORT_CONTROL_PORT);
input_report_rel(&inport_dev, REL_Y, inb(INPORT_DATA_PORT));
outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT);
buttons = inb(INPORT_DATA_PORT);
input_report_key(&inport_dev, BTN_MIDDLE, buttons & 1);
input_report_key(&inport_dev, BTN_LEFT, buttons & 2);
input_report_key(&inport_dev, BTN_RIGHT, buttons & 4);
outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
input_sync(&inport_dev);
return IRQ_HANDLED;
}
static int __init inport_init(void)
{
unsigned char a,b,c;
unsigned char a, b, c;
if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) {
printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE);
@ -163,26 +147,44 @@ static int __init inport_init(void)
a = inb(INPORT_SIGNATURE_PORT);
b = inb(INPORT_SIGNATURE_PORT);
c = inb(INPORT_SIGNATURE_PORT);
if (( a == b ) || ( a != c )) {
if (a == b || a != c) {
release_region(INPORT_BASE, INPORT_EXTENT);
printk(KERN_ERR "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE);
return -ENODEV;
}
if (!(inport_dev = input_allocate_device())) {
printk(KERN_ERR "inport.c: Not enough memory for input device\n");
release_region(INPORT_BASE, INPORT_EXTENT);
return -ENOMEM;
}
inport_dev->name = INPORT_NAME;
inport_dev->phys = "isa023c/input0";
inport_dev->id.bustype = BUS_ISA;
inport_dev->id.vendor = INPORT_VENDOR;
inport_dev->id.product = 0x0001;
inport_dev->id.version = 0x0100;
inport_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
inport_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
inport_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
inport_dev->open = inport_open;
inport_dev->close = inport_close;
outb(INPORT_RESET, INPORT_CONTROL_PORT);
outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
input_register_device(&inport_dev);
printk(KERN_INFO "input: " INPORT_NAME " at %#x irq %d\n", INPORT_BASE, inport_irq);
input_register_device(inport_dev);
return 0;
}
static void __exit inport_exit(void)
{
input_unregister_device(&inport_dev);
input_unregister_device(inport_dev);
release_region(INPORT_BASE, INPORT_EXTENT);
}

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