Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 84064
b: refs/heads/master
c: de92043
h: refs/heads/master
v: v3
  • Loading branch information
Mattia Dongili authored and Len Brown committed Jan 24, 2008
1 parent 93ec068 commit 98f39ba
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 83 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 88877c2a2ebd0e554496efb23e7dc8ade661d289
refs/heads/master: de9204300112dea10ca3d3cc76858cee61043e47
186 changes: 104 additions & 82 deletions trunk/drivers/misc/sony-laptop.c
Original file line number Diff line number Diff line change
Expand Up @@ -1194,18 +1194,33 @@ struct sony_pic_irq {
struct list_head list;
};

struct sonypi_eventtypes {
u8 data;
unsigned long mask;
struct sonypi_event *events;
};

struct device_ctrl {
int model;
int (*handle_irq)(void);
u16 evport_offset;
u8 has_camera;
u8 has_bluetooth;
u8 has_wwan;
struct sonypi_eventtypes *event_types;
};

struct sony_pic_dev {
int model;
u16 evport_offset;
u8 camera_power;
u8 bluetooth_power;
u8 wwan_power;
struct device_ctrl *control;
struct acpi_device *acpi_dev;
struct sony_pic_irq *cur_irq;
struct sony_pic_ioport *cur_ioport;
struct list_head interrupts;
struct list_head ioports;
struct mutex lock;
u8 camera_power;
u8 bluetooth_power;
u8 wwan_power;
};

static struct sony_pic_dev spic_dev = {
Expand Down Expand Up @@ -1370,74 +1385,92 @@ static struct sonypi_event sonypi_batteryev[] = {
{ 0, 0 }
};

static struct sonypi_eventtypes {
int model;
u8 data;
unsigned long mask;
struct sonypi_event * events;
} sony_pic_eventtypes[] = {
{ SONYPI_DEVICE_TYPE1, 0, 0xffffffff, sonypi_releaseev },
{ SONYPI_DEVICE_TYPE1, 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
{ SONYPI_DEVICE_TYPE1, 0x30, SONYPI_LID_MASK, sonypi_lidev },
{ SONYPI_DEVICE_TYPE1, 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
{ SONYPI_DEVICE_TYPE1, 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
{ SONYPI_DEVICE_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
{ SONYPI_DEVICE_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
{ SONYPI_DEVICE_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ SONYPI_DEVICE_TYPE1, 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
{ SONYPI_DEVICE_TYPE1, 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev },

{ SONYPI_DEVICE_TYPE2, 0, 0xffffffff, sonypi_releaseev },
{ SONYPI_DEVICE_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev },
{ SONYPI_DEVICE_TYPE2, 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev },
{ SONYPI_DEVICE_TYPE2, 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev },
{ SONYPI_DEVICE_TYPE2, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
{ SONYPI_DEVICE_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
{ SONYPI_DEVICE_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ SONYPI_DEVICE_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev },
{ SONYPI_DEVICE_TYPE2, 0x21, SONYPI_HELP_MASK, sonypi_helpev },
{ SONYPI_DEVICE_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
{ SONYPI_DEVICE_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
{ SONYPI_DEVICE_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
{ SONYPI_DEVICE_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
{ SONYPI_DEVICE_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },

{ SONYPI_DEVICE_TYPE3, 0, 0xffffffff, sonypi_releaseev },
{ SONYPI_DEVICE_TYPE3, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
{ SONYPI_DEVICE_TYPE3, 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
{ SONYPI_DEVICE_TYPE3, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
{ SONYPI_DEVICE_TYPE3, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
{ SONYPI_DEVICE_TYPE3, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ 0 }
static struct sonypi_eventtypes type1_events[] = {
{ 0, 0xffffffff, sonypi_releaseev },
{ 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
{ 0x30, SONYPI_LID_MASK, sonypi_lidev },
{ 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
{ 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
{ 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
{ 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
{ 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
{ 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev },
{ 0 },
};
static struct sonypi_eventtypes type2_events[] = {
{ 0, 0xffffffff, sonypi_releaseev },
{ 0x38, SONYPI_LID_MASK, sonypi_lidev },
{ 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev },
{ 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev },
{ 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
{ 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
{ 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ 0x11, SONYPI_BACK_MASK, sonypi_backev },
{ 0x21, SONYPI_HELP_MASK, sonypi_helpev },
{ 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
{ 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
{ 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ 0 },
};
static struct sonypi_eventtypes type3_events[] = {
{ 0, 0xffffffff, sonypi_releaseev },
{ 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
{ 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
{ 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ 0 },
};

static int sony_pic_detect_device_type(void)
static struct device_ctrl spic_types[] = {
{
.model = SONYPI_DEVICE_TYPE1,
.handle_irq = NULL,
.evport_offset = SONYPI_TYPE1_OFFSET,
.event_types = type1_events,
},
{
.model = SONYPI_DEVICE_TYPE2,
.handle_irq = NULL,
.evport_offset = SONYPI_TYPE2_OFFSET,
.event_types = type2_events,
},
{
.model = SONYPI_DEVICE_TYPE3,
.handle_irq = NULL,
.evport_offset = SONYPI_TYPE3_OFFSET,
.event_types = type3_events,
},
};

static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
{
struct pci_dev *pcidev;
int model = 0;

if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82371AB_3, NULL)))
model = SONYPI_DEVICE_TYPE1;
dev->control = &spic_types[0];

else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
model = SONYPI_DEVICE_TYPE3;
dev->control = &spic_types[2];

else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH7_1, NULL)))
model = SONYPI_DEVICE_TYPE3;
dev->control = &spic_types[2];

else
model = SONYPI_DEVICE_TYPE2;
dev->control = &spic_types[1];

if (pcidev)
pci_dev_put(pcidev);

printk(KERN_INFO DRV_PFX "detected Type%d model\n",
model == SONYPI_DEVICE_TYPE1 ? 1 :
model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
return model;
dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 :
dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
}

#define ITERATIONS_LONG 10000
Expand Down Expand Up @@ -2263,7 +2296,7 @@ static int sony_pic_enable(struct acpi_device *device,
buffer.pointer = resource;

/* setup Type 1 resources */
if (spic_dev.model == SONYPI_DEVICE_TYPE1) {
if (spic_dev.control->model == SONYPI_DEVICE_TYPE1) {

/* setup io resources */
resource->res1.type = ACPI_RESOURCE_TYPE_IO;
Expand Down Expand Up @@ -2345,39 +2378,42 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
if (dev->cur_ioport->io2.minimum)
data_mask = inb_p(dev->cur_ioport->io2.minimum);
else
data_mask = inb_p(dev->cur_ioport->io1.minimum + dev->evport_offset);
data_mask = inb_p(dev->cur_ioport->io1.minimum +
dev->control->evport_offset);

dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
ev, data_mask, dev->cur_ioport->io1.minimum, dev->evport_offset);
ev, data_mask, dev->cur_ioport->io1.minimum,
dev->control->evport_offset);

if (ev == 0x00 || ev == 0xff)
return IRQ_HANDLED;

for (i = 0; sony_pic_eventtypes[i].model; i++) {
for (i = 0; dev->control->event_types[i].mask; i++) {

if (spic_dev.model != sony_pic_eventtypes[i].model)
if ((data_mask & dev->control->event_types[i].data) !=
dev->control->event_types[i].data)
continue;

if ((data_mask & sony_pic_eventtypes[i].data) !=
sony_pic_eventtypes[i].data)
if (!(mask & dev->control->event_types[i].mask))
continue;

if (!(mask & sony_pic_eventtypes[i].mask))
continue;

for (j = 0; sony_pic_eventtypes[i].events[j].event; j++) {
if (ev == sony_pic_eventtypes[i].events[j].data) {
for (j = 0; dev->control->event_types[i].events[j].event; j++) {
if (ev == dev->control->event_types[i].events[j].data) {
device_event =
sony_pic_eventtypes[i].events[j].event;
dev->control->
event_types[i].events[j].event;
goto found;
}
}
}
dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
ev, data_mask, dev->cur_ioport->io1.minimum,
dev->control->evport_offset);
return IRQ_HANDLED;

found:
sony_laptop_report_input_event(device_event);
acpi_bus_generate_proc_event(spic_dev.acpi_dev, 1, device_event);
acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event);
sonypi_compat_report_event(device_event);

return IRQ_HANDLED;
Expand Down Expand Up @@ -2439,23 +2475,9 @@ static int sony_pic_add(struct acpi_device *device)

spic_dev.acpi_dev = device;
strcpy(acpi_device_class(device), "sony/hotkey");
spic_dev.model = sony_pic_detect_device_type();
sony_pic_detect_device_type(&spic_dev);
mutex_init(&spic_dev.lock);

/* model specific characteristics */
switch(spic_dev.model) {
case SONYPI_DEVICE_TYPE1:
spic_dev.evport_offset = SONYPI_TYPE1_OFFSET;
break;
case SONYPI_DEVICE_TYPE3:
spic_dev.evport_offset = SONYPI_TYPE3_OFFSET;
break;
case SONYPI_DEVICE_TYPE2:
default:
spic_dev.evport_offset = SONYPI_TYPE2_OFFSET;
break;
}

/* read _PRS resources */
result = sony_pic_possible_resources(device);
if (result) {
Expand Down

0 comments on commit 98f39ba

Please sign in to comment.