#define TOSH_BT_POWER_ON "BTPO"
#define TOSH_BT_POWER_OFF "BTPF"
#define TOSH_BT_STATUS "BTST"
+#define TOSH_BT_KSST_MASK 0x1
+#define TOSH_BT_USB_MASK 0x40
+#define TOSH_BT_POWER_MASK 0x80
/*
* ACPI driver for Toshiba Bluetooth device
int retval = 0;
acpi_handle dev_handle, method_handle;
int i;
- struct acpi_backend_data *priv_data = io_op->backend->data;
+ struct acpi_backend_data *priv_data;
if (unlikely(acpi_disabled)) {
printk(O_ERR "ACPI is disabled: feature unavailable.\n");
return -ENODEV;
}
- if (!priv_data) {
+ if (!io_op->backend->data) {
dprintk("Try to init ACPI backend\n");
mutex_init(&io_op->backend->mutex);
mutex_lock(&io_op->backend->mutex);
if ((retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_STATUS, 0, &raw_state)))
return retval;
- printk(O_INFO "BTST raw_state: %x\n", raw_state);
+ dprintk("BTST raw_state: %x\n", raw_state);
- /* FIXME: raw_state => state translation */
*state = BT_EX;
+ *state |= ((raw_state & TOSH_BT_USB_MASK) && (raw_state & TOSH_BT_POWER_MASK)) ? BT_STA : 0;
return retval;
}
#include "omnibook.h"
#include "hardware.h"
-static int ec_read16(u8 addr, u16 * data)
+struct omnibook_battery_info {
+ u8 type; /* 1 - Li-Ion, 2 NiMH */
+ u16 sn; /* Serial number */
+ u16 dv; /* Design Voltage */
+ u16 dc; /* Design Capacity */
+};
+
+struct omnibook_battery_state {
+ u16 pv; /* Present Voltage */
+ u16 rc; /* Remaining Capacity */
+ u16 lc; /* Last Full Capacity */
+ u8 gauge; /* Gauge in % */
+ u8 status; /* 0 - unknown, 1 - charged, 2 - discharging, 3 - charging, 4 - critical) */
+};
+
+enum {
+ OMNIBOOK_BATTSTAT_UNKNOWN,
+ OMNIBOOK_BATTSTAT_CHARGED,
+ OMNIBOOK_BATTSTAT_DISCHARGING,
+ OMNIBOOK_BATTSTAT_CHARGING,
+ OMNIBOOK_BATTSTAT_CRITICAL
+};
+
+#define BAT_OFFSET 0x10
+
+static int __backend_u16_read(struct omnibook_operation *io_op, u16 *data)
{
int retval;
- u8 high;
- u8 low;
- u16 result;
- retval = legacy_ec_read(addr, &low);
+ u8 byte;
+
+ retval = __backend_byte_read(io_op, &byte);
if (retval)
return retval;
- retval = legacy_ec_read(addr + 0x01, &high);
- result = ((high << 8) + low);
- *data = result;
+ *data = byte;
+ io_op->read_addr += 1;
+ retval = __backend_byte_read(io_op, &byte);
+ *data += (byte << 8);
return retval;
}
-static int omnibook_battery_present(int num)
+static int omnibook_battery_present(struct omnibook_operation *io_op, int num)
{
int retval;
- int i;
u8 bat;
- u8 mask = 0;
+ int i;
/*
* XE3GF
* TSM30X
*/
if (omnibook_ectype & (XE3GF | TSP10 | TSM30X)) {
-
- if (num >= 2)
- return -EINVAL;
- if ((retval = legacy_ec_read(XE3GF_BAL, &bat)))
- return retval;
- mask = XE3GF_BAL0_MASK;
+ io_op->read_addr = XE3GF_BAL;
+ io_op->read_mask = XE3GF_BAL0_MASK;
for (i = 0; i < num; i++)
- mask = mask << 1;
- /*
- * XE3GC
- * AMILOD
- */
+ io_op->read_mask = io_op->read_mask << 1;
+ retval = __backend_byte_read(io_op, &bat);
+ /*
+ * XE3GC
+ * AMILOD
+ */
} else if (omnibook_ectype & (XE3GC | AMILOD)) {
- if (num >= 2)
- return -EINVAL;
- if ((retval = legacy_ec_read(XE3GC_BAT, &bat)))
- return retval;
- mask = XE3GC_BAT0_MASK;
+ io_op->read_addr = XE3GC_BAT;
+ io_op->read_mask = XE3GC_BAT0_MASK;
for (i = 0; i < num; i++)
- mask = mask << 1;
- }
- return (bat & mask) ? 1 : 0;
+ io_op->read_mask = io_op->read_mask << 1;
+ retval = __backend_byte_read(io_op, &bat);
+ } else
+ retval = -ENODEV;
+
+ /* restore default read_mask */
+ io_op->read_mask = 0;
+
+ return !!bat;
}
/*
* 1 - Battery is not present
* 2 - Not supported
*/
-static int omnibook_get_battery_info(int num, struct omnibook_battery_info *battinfo)
+static int omnibook_get_battery_info(struct omnibook_operation *io_op,
+ int num,
+ struct omnibook_battery_info *battinfo)
{
int retval;
- u32 offset;
-
/*
* XE3GF
* TSP10
* TSM30X
*/
if (omnibook_ectype & (XE3GF | TSP10 | TSM30X)) {
- offset = 0x10;
- retval = omnibook_battery_present(num);
+ retval = omnibook_battery_present(io_op, num);
if (retval < 0)
return retval;
if (retval) {
- if ((retval =
- legacy_ec_read(XE3GF_BTY0 + (offset * num), &(*battinfo).type)))
+ io_op->read_addr = XE3GF_BTY0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &(*battinfo).type)))
return retval;
- if ((retval = ec_read16(XE3GF_BSN0 + (offset * num), &(*battinfo).sn)))
+ io_op->read_addr = XE3GF_BSN0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).sn)))
return retval;
- if ((retval = ec_read16(XE3GF_BDV0 + (offset * num), &(*battinfo).dv)))
+ io_op->read_addr = XE3GF_BDV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dv)))
return retval;
- if ((retval = ec_read16(XE3GF_BDC0 + (offset * num), &(*battinfo).dc)))
+ io_op->read_addr = XE3GF_BDC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dc)))
return retval;
(*battinfo).type = ((*battinfo).type & XE3GF_BTY_MASK) ? 1 : 0;
} else
return 1;
- /*
- * XE3GC
- */
+ /*
+ * XE3GC
+ */
} else if (omnibook_ectype & (XE3GC)) {
- offset = 0x10;
- retval = omnibook_battery_present(num);
+ retval = omnibook_battery_present(io_op, num);
if (retval < 0)
return retval;
if (retval) {
- if ((retval = ec_read16(XE3GC_BDV0 + (offset * num), &(*battinfo).dv)))
+ io_op->read_addr = XE3GC_BDV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dv)))
return retval;
- if ((retval = ec_read16(XE3GC_BDC0 + (offset * num), &(*battinfo).dc)))
+ io_op->read_addr = XE3GC_BDC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dc)))
return retval;
- if ((retval =
- legacy_ec_read(XE3GC_BTY0 + (offset * num), &(*battinfo).type)))
+ io_op->read_addr = XE3GC_BTY0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &(*battinfo).type)))
return retval;
(*battinfo).type = ((*battinfo).type & XE3GC_BTY_MASK) ? 1 : 0;
* AMILOD
*/
} else if (omnibook_ectype & (AMILOD)) {
- offset = 0x10;
- retval = omnibook_battery_present(num);
+ retval = omnibook_battery_present(io_op, num);
if (retval < 0)
return retval;
if (retval) {
- if ((retval = ec_read16(AMILOD_BDV0 + (offset * num), &(*battinfo).dv)))
+ io_op->read_addr = AMILOD_BDV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dv)))
return retval;
- if ((retval = ec_read16(AMILOD_BDC0 + (offset * num), &(*battinfo).dc)))
+ io_op->read_addr = AMILOD_BDC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dc)))
return retval;
- if ((retval =
- legacy_ec_read(AMILOD_BTY0 + (offset * num), &(*battinfo).type)))
+ io_op->read_addr = AMILOD_BTY0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &(*battinfo).type)))
return retval;
(*battinfo).type = ((*battinfo).type & AMILOD_BTY_MASK) ? 1 : 0;
} else if (omnibook_ectype & (OB500 | OB510)) {
switch (num) {
case 0:
- break;
case 1:
- break;
case 2:
break;
default:
} else if (omnibook_ectype & (OB6000 | OB6100 | XE4500)) {
switch (num) {
case 0:
- break;
case 1:
break;
default:
return -EINVAL;
}
- } else {
+ } else
return 2;
- }
+
return 0;
}
* 1 - Battery is not present
* 2 - Not supported
*/
-static int omnibook_get_battery_status(int num, struct omnibook_battery_state *battstat)
+static int omnibook_get_battery_status(struct omnibook_operation *io_op,
+ int num,
+ struct omnibook_battery_state *battstat)
{
int retval;
u8 status;
u16 dc;
int gauge;
- u8 offset;
/*
* XE3GF
* TSM30X
*/
if (omnibook_ectype & (XE3GF | TSP10 | TSM30X)) {
- offset = 0x10;
- retval = omnibook_battery_present(num);
+ retval = omnibook_battery_present(io_op, num);
if (retval < 0)
return retval;
if (retval) {
- if ((retval = legacy_ec_read(XE3GF_BST0 + (offset * num), &status)))
+ io_op->read_addr = XE3GF_BST0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &status)))
return retval;
- if ((retval = ec_read16(XE3GF_BRC0 + (offset * num), &(*battstat).rc)))
+ io_op->read_addr = XE3GF_BRC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
return retval;
- if ((retval = ec_read16(XE3GF_BPV0 + (offset * num), &(*battstat).pv)))
+ io_op->read_addr = XE3GF_BPV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
return retval;
- if ((retval = ec_read16(XE3GF_BFC0 + (offset * num), &(*battstat).lc)))
+ io_op->read_addr = XE3GF_BFC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).lc)))
return retval;
- if ((retval =
- legacy_ec_read(XE3GF_GAU0 + (offset * num), &(*battstat).gauge)))
+ io_op->read_addr = XE3GF_GAU0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &(*battstat).gauge)))
return retval;
if (status & XE3GF_BST_MASK_CRT)
}
} else
return 1;
- /*
- * XE3GC
- */
+ /*
+ * XE3GC
+ */
} else if (omnibook_ectype & (XE3GC)) {
- offset = 0x10;
- retval = omnibook_battery_present(num);
+ retval = omnibook_battery_present(io_op, num);
if (retval < 0)
return retval;
if (retval) {
- if ((retval = legacy_ec_read(XE3GC_BST0 + (offset * num), &status)))
+ io_op->read_addr = XE3GC_BST0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &status)))
return retval;
- if ((retval = ec_read16(XE3GC_BRC0 + (offset * num), &(*battstat).rc)))
+ io_op->read_addr = XE3GC_BRC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
return retval;
- if ((retval = ec_read16(XE3GC_BPV0 + (offset * num), &(*battstat).pv)))
+ io_op->read_addr = XE3GC_BPV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
return retval;
- if ((retval = ec_read16(XE3GC_BDC0 + (offset * num), &dc)))
+ io_op->read_addr = XE3GC_BDC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &dc)))
return retval;
if (status & XE3GC_BST_MASK_CRT)
(*battstat).lc = 0; /* Unknown */
} else
return 1;
- /*
- * AMILOD
- */
+ /*
+ * AMILOD
+ */
} else if (omnibook_ectype & (AMILOD)) {
- offset = 0x10;
- retval = omnibook_battery_present(num);
+ retval = omnibook_battery_present(io_op, num);
if (retval < 0)
return retval;
if (retval) {
- if ((retval = legacy_ec_read(AMILOD_BST0 + (offset * num), &status)))
+ io_op->read_addr = AMILOD_BST0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &status)))
return retval;
- if ((retval = ec_read16(AMILOD_BRC0 + (offset * num), &(*battstat).rc)))
+ io_op->read_addr = AMILOD_BRC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
return retval;
- if ((retval = ec_read16(AMILOD_BPV0 + (offset * num), &(*battstat).pv)))
+ io_op->read_addr = AMILOD_BPV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
return retval;
- if ((retval = ec_read16(AMILOD_BDC0 + (offset * num), &dc)))
+ io_op->read_addr = AMILOD_BDC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &dc)))
return retval;
if (status & AMILOD_BST_MASK_CRT)
} else if (omnibook_ectype & (OB500 | OB510)) {
switch (num) {
case 0:
- if ((retval = legacy_ec_read(OB500_BT1S, &status)))
+ io_op->read_addr = OB500_BT1S;
+ if ((retval = __backend_byte_read(io_op, &status)))
return retval;
- if ((retval = ec_read16(OB500_BT1C, &(*battstat).rc)))
+ io_op->read_addr = OB500_BT1C;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
return retval;
- if ((retval = ec_read16(OB500_BT1V, &(*battstat).pv)))
+ io_op->read_addr = OB500_BT1V;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
return retval;
break;
case 1:
- if ((retval = legacy_ec_read(OB500_BT2S, &status)))
+ io_op->read_addr = OB500_BT2S;
+ if ((retval = __backend_byte_read(io_op, &status)))
return retval;
- if ((retval = ec_read16(OB500_BT2C, &(*battstat).rc)))
+ io_op->read_addr = OB500_BT2C;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
return retval;
- if ((retval = ec_read16(OB500_BT2V, &(*battstat).pv)))
+ io_op->read_addr = OB500_BT2V;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
return retval;
break;
case 2:
- if ((retval = legacy_ec_read(OB500_BT3S, &status)))
+ io_op->read_addr = OB500_BT3S;
+ if ((retval = __backend_byte_read(io_op, &status)))
return retval;
- if ((retval = ec_read16(OB500_BT3C, &(*battstat).rc)))
+ io_op->read_addr = OB500_BT3C;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
return retval;
- if ((retval = ec_read16(OB500_BT3V, &(*battstat).pv)))
+ io_op->read_addr = OB500_BT3V;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
return retval;
break;
default:
} else if (omnibook_ectype & (OB6000 | OB6100 | XE4500)) {
switch (num) {
case 0:
- if ((retval = legacy_ec_read(OB500_BT1S, &status)))
+ io_op->read_addr = OB500_BT1S;
+ if ((retval = __backend_byte_read(io_op, &status)))
return retval;
- if ((retval = ec_read16(OB500_BT1C, &(*battstat).rc)))
+ io_op->read_addr = OB500_BT1C;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
return retval;
- if ((retval = ec_read16(OB500_BT1V, &(*battstat).pv)))
+ io_op->read_addr = OB500_BT1V;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
return retval;
break;
case 1:
- if ((retval = legacy_ec_read(OB500_BT3S, &status)))
+ io_op->read_addr = OB500_BT3S;
+ if ((retval = __backend_byte_read(io_op, &status)))
return retval;
- if ((retval = ec_read16(OB500_BT3C, &(*battstat).rc)))
+ io_op->read_addr = OB500_BT3C;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
return retval;
- if ((retval = ec_read16(OB500_BT3V, &(*battstat).pv)))
+ io_op->read_addr = OB500_BT3V;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
return retval;
break;
default:
else if (omnibook_ectype & (TSM30X))
max = 1;
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
for (i = 0; i < max; i++) {
- retval = omnibook_get_battery_info(i, &battinfo);
+ retval = omnibook_get_battery_info(io_op, i, &battinfo);
if (retval == 0) {
num++;
- omnibook_get_battery_status(i, &battstat);
+ omnibook_get_battery_status(io_op, i, &battstat);
typestr = (battinfo.type) ? "Li-Ion" : "NiMH";
switch (battstat.status) {
case OMNIBOOK_BATTSTAT_CHARGED:
if (num == 0)
len += sprintf(buffer + len, "No battery present\n");
+ mutex_unlock(&io_op->backend->mutex);
+
return len;
}
+static struct omnibook_tbl battery_table[] __initdata = {
+ {XE3GF | XE3GC | AMILOD | TSP10 | TSM30X, {EC,}},
+ {0,}
+};
+
static struct omnibook_feature __declared_feature battery_driver = {
.name = "battery",
#ifdef CONFIG_OMNIBOOK_LEGACY
#endif
.read = omnibook_battery_read,
.ectypes = XE3GF | XE3GC | AMILOD | TSP10 | TSM30X, /* FIXME: OB500|OB6000|OB6100|XE4500 */
+ .tbl = battery_table,
};
module_param_named(battery, battery_driver.enabled, int, S_IRUGO);
int omnibook_lcd_blank(int blank)
{
struct omnibook_feature *blank_feature = omnibook_find_feature("blank");
- int retval = 0;
if(!blank_feature)
return -ENODEV;
- if (blank_feature->io_op->backend == PIO)
- omnibook_apply_write_mask(blank_feature->io_op, blank);
- else if (blank_feature->io_op->backend == KBC || blank_feature->io_op->backend == CDI)
- omnibook_toggle(blank_feature->io_op, blank);
- else {
- retval = -ENODEV;
- }
-
- return retval;
+ return omnibook_apply_write_mask(blank_feature->io_op, blank);
}
static int console_blank_register_hook(void)
for (i = 0; i < 255; i += 16) {
len += sprintf(buffer + len, "EC 0x%02x:", i);
for (j = 0; j < 16; j++) {
- if (legacy_ec_read(i + j, &v))
+ io_op->read_addr = i +j;
+ if (backend_byte_read(io_op, &v))
break;
if (v != ecdump_regs[i + j])
len += sprintf(buffer + len, " *%02x", v);
} else
return -EINVAL;
if (i >= 0 && i < 256 && v >= 0 && v < 256) {
- if (legacy_ec_write(i, v))
- return -EIO;
+ io_op->write_addr = i;
+ return backend_byte_write(io_op, v);
} else
return -EINVAL;
return 0;
}
+static struct omnibook_tbl dump_table[] __initdata = {
+ {ALL_ECTYPES, {EC,}},
+ {0,}
+};
+
static struct omnibook_feature __declared_feature dump_driver = {
.name = "dump",
.enabled = 0,
.read = ecdump_read,
.write = ecdump_write,
+ .tbl = dump_table,
};
module_param_named(dump, dump_driver.enabled, int, S_IRUGO);
return retval;
}
-/*
- * legacy access function for unconverted old code who expect old omnibook_ec_read
- */
-
-int legacy_ec_read(u8 addr, u8 * data)
-{
- int retval;
- struct omnibook_operation io_op = SIMPLE_BYTE(EC, addr, 0);
- retval = omnibook_ec_read(&io_op, data);
- return retval;
-}
-
-/*
- * legacy access function for unconverted old code who expect old omnibook_ec_write
- */
-
-int legacy_ec_write(u8 addr, u8 data)
-{
- int retval;
- struct omnibook_operation io_op = SIMPLE_BYTE(EC, addr, 0);
- retval = omnibook_ec_write(&io_op, data);
- return retval;
-}
-
static int omnibook_ec_display(const struct omnibook_operation *io_op, unsigned int *state)
{
int retval;
* Do not change these values unless you exactly know what you do.
*/
-#define OMNIBOOK_FAN_LEVELS 7
+#define OMNIBOOK_FAN_LEVELS 8
#define OMNIBOOK_FAN_MIN 25 /* Minimal value of fan off temperature */
#define OMNIBOOK_FOT_MAX 75 /* Maximal value of fan off temperature */
#define OMNIBOOK_FAN_MAX 95 /* Maximal value of fan on temperature */
#define OMNIBOOK_FAN6_DEFAULT 95 /* Default value of fan level 6 temperature */
#define OMNIBOOK_FAN7_DEFAULT 95 /* Default value of fan level 7 temperature */
-static u8 omnibook_fan_policy[OMNIBOOK_FAN_LEVELS];
+static const u8 fan_defaults[] = {
+ OMNIBOOK_FOT_DEFAULT,
+ OMNIBOOK_FAN1_DEFAULT,
+ OMNIBOOK_FAN2_DEFAULT,
+ OMNIBOOK_FAN3_DEFAULT,
+ OMNIBOOK_FAN4_DEFAULT,
+ OMNIBOOK_FAN5_DEFAULT,
+ OMNIBOOK_FAN6_DEFAULT,
+ OMNIBOOK_FAN7_DEFAULT,
+};
-static int omnibook_get_fan_policy(void)
+static int omnibook_get_fan_policy(struct omnibook_operation *io_op, u8 *fan_policy)
{
- int retval = 0;
+ int retval ;
int i;
- u8 tmp;
- /*
- * XE3GF
- */
- if (omnibook_ectype & (XE3GF)) {
- for (i = 0; i <= OMNIBOOK_FAN_LEVELS; i++) {
- if ((retval = legacy_ec_read(XE3GF_FOT + i, &tmp)))
- return retval;
- omnibook_fan_policy[i] = tmp;
- }
- } else {
- printk(O_INFO "Fan policy is unsupported on this machine.\n");
- retval = -ENODEV;
+ for (i = 0; i < OMNIBOOK_FAN_LEVELS; i++) {
+ io_op->read_addr = XE3GF_FOT + i;
+ if ((retval = __backend_byte_read(io_op, &fan_policy[i])))
+ return retval;
}
- return retval;
+ return 0;
}
-static int omnibook_set_fan_policy(void)
+static int omnibook_set_fan_policy(struct omnibook_operation *io_op, const u8 *fan_policy)
{
int retval;
int i;
- /*
- * XE3GF
- */
- if (omnibook_ectype & (XE3GF)) {
- if (omnibook_fan_policy[0] > OMNIBOOK_FOT_MAX)
+ if (fan_policy[0] > OMNIBOOK_FOT_MAX)
+ return -EINVAL;
+
+ for (i = 0; i < OMNIBOOK_FAN_LEVELS; i++) {
+ if ((fan_policy[i] > fan_policy[i + 1])
+ || (fan_policy[i] < OMNIBOOK_FAN_MIN)
+ || (fan_policy[i] > OMNIBOOK_FAN_MAX))
return -EINVAL;
- for (i = 0; i < OMNIBOOK_FAN_LEVELS; i++) {
- if ((omnibook_fan_policy[i] > omnibook_fan_policy[i + 1])
- || (omnibook_fan_policy[i] < OMNIBOOK_FAN_MIN)
- || (omnibook_fan_policy[i] > OMNIBOOK_FAN_MAX))
- return -EINVAL;
- if (omnibook_fan_policy[i + 1] > OMNIBOOK_FAN_MAX)
- return -EINVAL;
- }
- for (i = 0; i <= OMNIBOOK_FAN_LEVELS; i++) {
- if ((retval = legacy_ec_write(XE3GF_FOT + i, omnibook_fan_policy[i])))
- return retval;
- }
- } else {
- printk(O_INFO "Fan policy is unsupported on this machine.\n");
- retval = -ENODEV;
}
-
- return retval;
-}
-
-static int omnibook_set_fan_policy_defaults(void)
-{
- int retval;
- int i;
- u8 fan_defaults[] = {
- OMNIBOOK_FOT_DEFAULT,
- OMNIBOOK_FAN1_DEFAULT,
- OMNIBOOK_FAN2_DEFAULT,
- OMNIBOOK_FAN3_DEFAULT,
- OMNIBOOK_FAN4_DEFAULT,
- OMNIBOOK_FAN5_DEFAULT,
- OMNIBOOK_FAN6_DEFAULT,
- OMNIBOOK_FAN7_DEFAULT,
- };
-
- /*
- * XE3GF
- */
- if (omnibook_ectype & (XE3GF)) {
- for (i = 0; i <= OMNIBOOK_FAN_LEVELS; i++) {
- if ((retval = legacy_ec_write(XE3GF_FOT + i, fan_defaults[i])))
- return retval;
- }
- } else {
- printk(O_INFO "Fan policy is unsupported on this machine.\n");
- retval = -ENODEV;
+ for (i = 0; i < OMNIBOOK_FAN_LEVELS; i++) {
+ io_op->write_addr = XE3GF_FOT + i;
+ if ((retval = __backend_byte_write(io_op, fan_policy[i])))
+ return retval;
}
- return retval;
+ return 0;
}
static int omnibook_fan_policy_read(char *buffer, struct omnibook_operation *io_op)
int retval;
int len = 0;
u8 i;
+ u8 fan_policy[OMNIBOOK_FAN_LEVELS];
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
- if ((retval = omnibook_get_fan_policy()))
+ retval = omnibook_get_fan_policy(io_op, &fan_policy[0]);
+
+ mutex_unlock(&io_op->backend->mutex);
+
+ if(retval)
return retval;
- len += sprintf(buffer + len, "Fan off temperature: %2d C\n", omnibook_fan_policy[0]);
- len += sprintf(buffer + len, "Fan on temperature: %2d C\n", omnibook_fan_policy[1]);
- for (i = 2; i <= OMNIBOOK_FAN_LEVELS; i++) {
+ len += sprintf(buffer + len, "Fan off temperature: %2d C\n", fan_policy[0]);
+ len += sprintf(buffer + len, "Fan on temperature: %2d C\n", fan_policy[1]);
+ for (i = 2; i < OMNIBOOK_FAN_LEVELS; i++) {
len +=
sprintf(buffer + len, "Fan level %1d temperature: %2d C\n", i,
- omnibook_fan_policy[i]);
+ fan_policy[i]);
}
len += sprintf(buffer + len, "Minimal temperature to set: %2d C\n", OMNIBOOK_FAN_MIN);
len += sprintf(buffer + len, "Maximal temperature to set: %2d C\n", OMNIBOOK_FAN_MAX);
char *endp;
int retval;
int temp;
+ u8 fan_policy[OMNIBOOK_FAN_LEVELS];
- if ((retval = omnibook_get_fan_policy()))
- return retval;
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ if ((retval = omnibook_get_fan_policy(io_op, &fan_policy[0])))
+ goto out;
/*
* Could also be done much simpler using sscanf(,"%u %u ...
b = buffer;
do {
dprintk("n=[%i] b=[%s]\n", n, b);
- if (n > OMNIBOOK_FAN_LEVELS)
- return -EINVAL;
+ if (n > OMNIBOOK_FAN_LEVELS) {
+ retval = -EINVAL;
+ goto out;
+ }
if (!isspace(*b)) {
temp = simple_strtoul(b, &endp, 10);
if (endp != b) { /* there was a match */
- omnibook_fan_policy[n++] = temp;
+ fan_policy[n++] = temp;
b = endp;
- } else
- return -EINVAL;
+ } else {
+ retval = -EINVAL;
+ goto out;
+ }
} else
b++;
} while ((*b != '\0') && (*b != '\n'));
/* A zero value set the defaults */
- if ((omnibook_fan_policy[0] == 0) && (n == 1)) {
- if ((retval = omnibook_set_fan_policy_defaults()))
- return retval;
- } else if ((retval = omnibook_set_fan_policy()))
- return retval;
- return 0;
+ if ((fan_policy[0] == 0) && (n == 1))
+ retval = omnibook_set_fan_policy(io_op, &fan_defaults[0]);
+ else
+ retval = omnibook_set_fan_policy(io_op, &fan_policy[0]);
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
}
+static struct omnibook_tbl fan_policy_table[] __initdata = {
+ {XE3GF, {EC,}},
+ {0,}
+};
+
static struct omnibook_feature __declared_feature fan_policy_driver = {
.name = "fan_policy",
.enabled = 1,
.read = omnibook_fan_policy_read,
.write = omnibook_fan_policy_write,
.ectypes = XE3GF,
+ .tbl = fan_policy_table,
};
module_param_named(fan_policy, fan_policy_driver.enabled, int, S_IRUGO);
#define SMI &nbsmi_backend
#define CDI &compal_backend
-int legacy_ec_read(u8 addr, u8 *data);
-int legacy_ec_write(u8 addr, u8 data);
int __omnibook_apply_write_mask(const struct omnibook_operation *io_op, int toggle);
int __omnibook_toggle(const struct omnibook_operation *io_op, int toggle);
static int omnibook_userset = 0;
-struct input_dev *omnibook_input_dev;
-
/*
* The platform_driver interface was added in linux 2.6.15
*/
spin_lock_irq(&omnibook_kbc_lock);
retval = omnibook_kbc_wait(OMNIBOOK_KBC_STAT_IBF);
if (retval)
- goto end;;
+ goto end;
outb(data, OMNIBOOK_KBC_DATA);
retval = omnibook_kbc_wait(OMNIBOOK_KBC_STAT_IBF);
end:
/*
* Backend interface declarations
*/
-
-struct mutex kbc_mutex;
-
struct omnibook_backend kbc_backend = {
.name = "i8042",
.hotkeys_write_cap = HKEY_ONETOUCH,
#include "compat.h"
#include <linux/input.h>
+/*
+ * Generic funtion for applying a mask on a value
+ * Hack: degenerate to omnibook_toggle if there is no read method
+ * of if the read address is 0, this is used in blank.c
+ */
int __omnibook_apply_write_mask(const struct omnibook_operation *io_op, int toggle)
{
int retval = 0;
int mask;
u8 data;
+ if(!(io_op->backend->byte_read && io_op->read_addr))
+ return __omnibook_toggle(io_op,toggle);
+
if ((retval = __backend_byte_read(io_op, &data)))
return retval;
+config OMNIBOOK_LEGACY
+ bool "HP omnibook legacy features"
+ depends on OMNIBOOK
-+ default y if !ACPI
++ default y if !ACPI
+ ---help---
+ This option enable support for some legacy features of the omnibook
+ driver, including:
#include <asm/io.h>
#include <asm/mc146818rtc.h>
#include <linux/workqueue.h>
+#include <linux/delay.h>
/* copied from drivers/input/serio/i8042-io.h */
#define I8042_KBD_PHYS_DESC "isa0060/serio0"
#define BUFFER_SIZE 0x20
#define INTEL_OFFSET 0x60
#define INTEL_SMI_PORT 0xb2 /* APM_CNT port in INTEL ICH specs */
+
/*
* Toshiba Specs state 0xef here but:
* -this would overflow (ef + 19 > ff)
* -code from Toshiba use e0, which make much more sense
*/
+
#define ATI_OFFSET 0xe0
#define ATI_SMI_PORT 0xb0
#define BTEX_MASK 0x1
#define BTAT_MASK 0x2
-/*
- * Crital sections around #SMI triggering are run atomically using a spinlock
- */
-static DEFINE_SPINLOCK(smi_spinlock);
-
/*
* Private data of this backend
*/
-static struct pci_dev *lpc_bridge; /* Southbridge chip ISA bridge/LPC interface PCI device */
-static u8 start_offset;
-static struct input_dev *nbsmi_input_dev;
+struct nbsmi_backend_data {
+ struct pci_dev *lpc_bridge; /* Southbridge chip ISA bridge/LPC interface PCI device */
+ u8 start_offset; /* Start offset in CMOS memory */
+ struct input_dev *nbsmi_input_dev;
+ struct work_struct fnkey_work;
+};
/*
* Possible list of supported southbridges
* process.
* We also disable preemtion and IRQs upon SMI call.
*/
-
-static inline u32 ati_do_smi_call( u16 function)
+static inline u32 ati_do_smi_call(u16 function)
{
unsigned long flags;
u32 retval = 0;
- spin_lock_irqsave(&smi_spinlock,flags);
+
+ local_irq_save(flags);
+ preempt_disable();
/*
* eflags, eax, ebx, ecx, edx, esi and edi are clobbered upon writing to SMI_PORT
* retval = -EIO; [too bad]
* out:
*/
-
__asm__ __volatile__("outw %%ax, %2; \
orw %%ax, %%ax; \
jz 1f; \
: "a"(function), "N"(ATI_SMI_PORT), "N"(ATI_SMI_PORT+1), "i"(-EIO)
: "memory", "ebx", "ecx", "edx", "esi", "edi", "cc");
- spin_unlock_irqrestore(&smi_spinlock,flags);
+ local_irq_restore(flags);
+ preempt_enable_no_resched();
return retval;
}
-static inline u32 intel_do_smi_call(u16 function)
+static inline u32 intel_do_smi_call(u16 function, struct pci_dev *lpc_bridge)
{
u32 state, sci_en;
unsigned long flags;
u32 retval = 0;
- spin_lock_irqsave(&smi_spinlock,flags);
+
+ local_irq_save(flags);
+ preempt_disable();
/*
* We get the PMBASE offset ( bits 15:7 at 0x40 offset of PCI config space )
sci_en = sci_en & 0xff80; /* Keep bits 15:7 */
sci_en += INTEL_GPE0_EN; /* GPEO_EN offset */
state = inl(sci_en);
- outl(0,sci_en);
+ outl(0, sci_en);
/*
* eflags, eax, ebx, ecx, edx, esi and edi are clobbered upon writing to SMI_PORT
: "a"(function), "N"(INTEL_SMI_PORT), "i"(-EIO)
: "memory", "ebx", "ecx", "edx", "esi", "edi", "cc");
- outl( state, sci_en );
- spin_unlock_irqrestore(&smi_spinlock,flags);
+ outl(state, sci_en);
+ local_irq_restore(flags);
+ preempt_enable_no_resched();
return retval;
}
-static int nbsmi_smi_command(u16 function, const u8 * inputbuffer, u8 * outputbuffer)
+static int nbsmi_smi_command(u16 function,
+ const u8 * inputbuffer,
+ u8 * outputbuffer,
+ struct nbsmi_backend_data *priv_data)
{
int count;
u32 retval = 0;
for (count = 0; count < BUFFER_SIZE; count++) {
- outb(count + start_offset, RTC_PORT(2));
+ outb(count + priv_data->start_offset, RTC_PORT(2));
outb(*(inputbuffer + count), RTC_PORT(3));
}
function = (function & 0xff) << 8;
function |= 0xe4;
- switch (lpc_bridge->vendor) {
+ switch (priv_data->lpc_bridge->vendor) {
case PCI_VENDOR_ID_INTEL:
- retval = intel_do_smi_call(function);
+ retval = intel_do_smi_call(function, priv_data->lpc_bridge);
break;
case PCI_VENDOR_ID_ATI:
retval = ati_do_smi_call(function);
printk(O_ERR "smi_command failed with error %u.\n", retval);
for (count = 0; count < BUFFER_SIZE; count++) {
- outb(count + start_offset, RTC_PORT(2));
+ outb(count + priv_data->start_offset, RTC_PORT(2));
*(outputbuffer + count) = inb(RTC_PORT(3));
}
int retval;
u8 *inputbuffer;
u8 *outputbuffer;
+ struct nbsmi_backend_data *priv_data = io_op->backend->data;
- if (!lpc_bridge)
+ if (!priv_data)
return -ENODEV;
inputbuffer = kcalloc(BUFFER_SIZE, sizeof(u8), GFP_KERNEL);
goto error2;
}
- retval = nbsmi_smi_command((u16) io_op->read_addr, inputbuffer, outputbuffer);
+ retval = nbsmi_smi_command((u16) io_op->read_addr, inputbuffer, outputbuffer, priv_data);
if (retval)
goto out;
int retval;
u8 *inputbuffer;
u8 *outputbuffer;
+ struct nbsmi_backend_data *priv_data = io_op->backend->data;
- if (!lpc_bridge)
+ if (!priv_data)
return -ENODEV;
inputbuffer = kcalloc(BUFFER_SIZE, sizeof(u8), GFP_KERNEL);
inputbuffer[0] = data;
- retval = nbsmi_smi_command((u16) io_op->write_addr, inputbuffer, outputbuffer);
+ retval = nbsmi_smi_command((u16) io_op->write_addr, inputbuffer, outputbuffer, priv_data);
kfree(outputbuffer);
error2:
/*
* Read/Write to INDEX/DATA interface at port 0x300 (SMSC Mailbox registers)
*/
-void nbsmi_ec_read_command(u8 index, u8 * data)
+static inline void nbsmi_ec_read_command(u8 index, u8 * data)
{
- spin_lock_irq(&smi_spinlock);
outb(index, EC_INDEX_PORT);
*data = inb(EC_DATA_PORT);
- spin_unlock_irq(&smi_spinlock);
}
#if 0
-static void nbsmi_ec_write_command(u8 index, u8 data)
+static inline void nbsmi_ec_write_command(u8 index, u8 data)
{
- spin_lock_irq(&smi_spinlock);
outb(index, EC_INDEX_PORT);
outb(data, EC_DATA_PORT);
- spin_unlock_irq(&smi_spinlock);
}
#endif
handle->dev = dev;
handle->handler = handler;
handle->name = "omnibook_scancode_hook";
+ handle->private = handler->private;
input_open_device(handle);
* the nbsmi backend might sleep.
*/
-static void omnibook_handle_fnkey(void* data);
-DECLARE_WORK(omnibook_fnkey_work, *omnibook_handle_fnkey, NULL);
-
static void hook_event(struct input_handle *handle, unsigned int event_type,
unsigned int event_code, int value)
{
- if (event_type == EV_MSC && event_code == MSC_SCAN && value == SMI_FN_SCAN )
- schedule_work(&omnibook_fnkey_work);
+ if (event_type == EV_MSC && event_code == MSC_SCAN && value == SMI_FN_SCAN)
+ schedule_work(&((struct nbsmi_backend_data *)handle->private)->fnkey_work);
}
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
/*
* Detected scancode to keycode table
*/
-static struct {
+static const struct {
unsigned int scancode;
unsigned int keycode;
} nbsmi_scan_table[] = {
{ 0,0},
};
+static void omnibook_handle_fnkey(void* data);
+
/*
* Register the input handler and the input device in the input subsystem
*/
-static int register_input_subsystem(void)
+static int register_input_subsystem(struct nbsmi_backend_data *priv_data)
{
int i, retval = 0;
-
+ struct input_dev *nbsmi_input_dev;
+
nbsmi_input_dev = input_allocate_device();
if (!nbsmi_input_dev) {
retval = -ENOMEM;
set_bit(nbsmi_scan_table[i].keycode, nbsmi_input_dev->keybit);
retval = input_register_device(nbsmi_input_dev);
+ if(retval) {
+ input_free_device(nbsmi_input_dev);
+ goto out;
+ }
+ priv_data->nbsmi_input_dev = nbsmi_input_dev;
+
+ INIT_WORK(&priv_data->fnkey_work, *omnibook_handle_fnkey, priv_data);
+
+ hook_handler.private = priv_data;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
retval = input_register_handler(&hook_handler);
return retval;
}
-
/*
* Try to init the backend
* This function can be called blindly as it use a kref
int i;
u8 ec_data;
u32 smi_port = 0;
+ struct nbsmi_backend_data *priv_data;
/* ectypes other than TSM40 have no business with this backend */
if (!(omnibook_ectype & TSM40))
return -ENODEV;
}
- if (!lpc_bridge) {
+ if (!io_op->backend->data) {
/* Fist use of the backend */
dprintk("Try to init NbSmi\n");
mutex_init(&io_op->backend->mutex);
mutex_lock(&io_op->backend->mutex);
kref_init(&io_op->backend->kref);
+ priv_data = kzalloc(sizeof(struct nbsmi_backend_data), GFP_KERNEL);
+ if (!priv_data) {
+ retval = -ENOMEM;
+ goto error0;
+ }
+
/* PCI probing: find the LPC Super I/O bridge PCI device */
- for (i = 0; !lpc_bridge && lpc_bridge_table[i].vendor; ++i)
- lpc_bridge =
+ for (i = 0; !priv_data->lpc_bridge && lpc_bridge_table[i].vendor; ++i)
+ priv_data->lpc_bridge =
pci_get_device(lpc_bridge_table[i].vendor, lpc_bridge_table[i].device,
NULL);
- if (!lpc_bridge) {
+ if (!priv_data->lpc_bridge) {
printk(O_ERR "Fail to find a supported LPC I/O bridge, please report\n");
retval = -ENODEV;
goto error1;
}
- if ((retval = pci_enable_device(lpc_bridge))) {
+ if ((retval = pci_enable_device(priv_data->lpc_bridge))) {
printk(O_ERR "Unable to enable PCI device.\n");
goto error2;
}
- switch (lpc_bridge->vendor) {
+ switch (priv_data->lpc_bridge->vendor) {
case PCI_VENDOR_ID_INTEL:
- start_offset = INTEL_OFFSET;
+ priv_data->start_offset = INTEL_OFFSET;
smi_port = INTEL_SMI_PORT;
break;
case PCI_VENDOR_ID_ATI:
- start_offset = ATI_OFFSET;
+ priv_data->start_offset = ATI_OFFSET;
smi_port = ATI_SMI_PORT;
break;
default:
goto error4;
}
- register_input_subsystem();
+ retval = register_input_subsystem(priv_data);
+ if(retval)
+ goto error4;
+
+ io_op->backend->data = priv_data;
+
dprintk("NbSmi init ok\n");
mutex_unlock(&io_op->backend->mutex);
return 0;
error3:
release_region(smi_port, 2);
error2:
- pci_dev_put(lpc_bridge);
- lpc_bridge = NULL;
+ pci_dev_put(priv_data->lpc_bridge);
error1:
+ kfree(priv_data);
+ io_op->backend->data = NULL;
+ error0:
io_op->backend->already_failed = 1;
mutex_unlock(&io_op->backend->mutex);
mutex_destroy(&io_op->backend->mutex);
{
u32 smi_port = 0;
struct omnibook_backend *backend;
+ struct nbsmi_backend_data *priv_data;
dprintk("NbSmi not used anymore: disposing\n");
+ backend = container_of(ref, struct omnibook_backend, kref);
+ priv_data = backend->data;
+
flush_scheduled_work();
input_unregister_handler(&hook_handler);
- input_unregister_device(nbsmi_input_dev);
-
- backend = container_of(ref, struct omnibook_backend, kref);
+ input_unregister_device(priv_data->nbsmi_input_dev);
mutex_lock(&backend->mutex);
- switch (lpc_bridge->vendor) {
+ switch (priv_data->lpc_bridge->vendor) {
case PCI_VENDOR_ID_INTEL:
smi_port = INTEL_SMI_PORT;
break;
BUG();
}
- pci_dev_put(lpc_bridge);
+ pci_dev_put(priv_data->lpc_bridge);
release_region(smi_port, 2);
release_region(EC_INDEX_PORT, 2);
- lpc_bridge = NULL;
+ kfree(priv_data);
+ backend->data = NULL;
mutex_unlock(&backend->mutex);
mutex_destroy(&backend->mutex);
}
brgt = omnibook_max_brightness;
else
brgt += delta;
-
+
retval = __backend_byte_write(io_op, brgt);
out:
{
int i;
u8 gen_scan;
+ struct input_dev *input_dev;
if(backend_byte_read(&last_scan_op, &gen_scan))
return;
adjust_brighness(+1);
break;
}
- for(i=0 ; i < ARRAY_SIZE(nbsmi_scan_table); i++) {
+
+ for(i = 0 ; i < ARRAY_SIZE(nbsmi_scan_table); i++) {
if( gen_scan == nbsmi_scan_table[i].scancode) {
dprintk("generating keycode %i.\n", nbsmi_scan_table[i].keycode);
- omnibook_report_key(nbsmi_input_dev, nbsmi_scan_table[i].keycode);
+ input_dev = ((struct nbsmi_backend_data *) data)->nbsmi_input_dev;
+ omnibook_report_key(input_dev, nbsmi_scan_table[i].keycode);
break;
}
}
static int omnibook_nbsmi_get_wireless(const struct omnibook_operation *io_op, unsigned int *state)
{
int retval = 0;
- struct omnibook_operation aerial_op;
+ struct omnibook_operation aerial_op = SIMPLE_BYTE(SMI, SMI_GET_KILL_SWITCH, 0);
u8 data;
- aerial_op.read_addr = SMI_GET_KILL_SWITCH;
- aerial_op.read_mask = 0;
-
if ((retval = nbsmi_smi_read_command(&aerial_op, &data)))
goto out;
*state = data ? KILLSWITCH : 0;
aerial_op.read_addr = SMI_GET_AERIAL;
- aerial_op.read_mask = 0;
if ((retval = nbsmi_smi_read_command(&aerial_op, &data)))
goto out;
{
int retval = 0;
u8 data;
- struct omnibook_operation aerial_op;
-
- aerial_op.write_addr = SMI_SET_AERIAL;
+ struct omnibook_operation aerial_op = SIMPLE_BYTE(SMI, SMI_SET_AERIAL, 0);
data = !!(state & BT_STA);
data |= !!(state & WIFI_STA) << 0x1;
return retval;
}
-/*
- * Hotkeys reading return completly unreliable results on a least Tecra S1
- * It is therefore disabled
- */
-#if 0
static int omnibook_nbmsi_hotkeys_get(const struct omnibook_operation *io_op, unsigned int *state)
{
int retval;
u8 data = 0;
- struct omnibook_operation hotkeys_op;
-
- hotkeys_op.read_addr = SMI_GET_FN_INTERFACE;
- hotkeys_op.read_mask = 0;
+ struct omnibook_operation hotkeys_op = SIMPLE_BYTE(SMI, SMI_GET_FN_INTERFACE, 0);
retval = nbsmi_smi_read_command(&hotkeys_op, &data);
if (retval < 0)
return 0;
}
-#endif
+
static int omnibook_nbmsi_hotkeys_set(const struct omnibook_operation *io_op, unsigned int state)
{
- int retval;
- u8 data = 0;
- struct omnibook_operation hotkeys_op;
+ int i, retval;
+ u8 data, rdata;
+ struct omnibook_operation hotkeys_op = SIMPLE_BYTE(SMI, SMI_SET_FN_F5_INTERFACE, 0);
- hotkeys_op.write_addr = SMI_SET_FN_INTERFACE;
- data |= (state & HKEY_FN) ? SMI_FN_KEYS_MASK : 0;
- data |= (state & HKEY_STICK) ? SMI_STICK_KEYS_MASK : 0;
- data |= (state & HKEY_TWICE_LOCK) ? SMI_FN_TWICE_LOCK_MASK : 0;
- data |= (state & HKEY_DOCK) ? SMI_FN_DOCK_MASK : 0;
+ data = !!(state & HKEY_FNF5);
- dprintk("set_hotkeys (Fn interface) raw_state: %x\n", data);
+ dprintk("set_hotkeys (Fn F5) raw_state: %x\n", data);
retval = nbsmi_smi_write_command(&hotkeys_op, data);
if (retval < 0)
return retval;
- hotkeys_op.write_addr = SMI_SET_FN_F5_INTERFACE;
- data = !!(state & HKEY_FNF5);
+ hotkeys_op.write_addr = SMI_SET_FN_INTERFACE;
+ hotkeys_op.read_addr = SMI_GET_FN_INTERFACE;
- dprintk("set_hotkeys (Fn F5) raw_state: %x\n", data);
+ data = (state & HKEY_FN) ? SMI_FN_KEYS_MASK : 0;
+ data |= (state & HKEY_STICK) ? SMI_STICK_KEYS_MASK : 0;
+ data |= (state & HKEY_TWICE_LOCK) ? SMI_FN_TWICE_LOCK_MASK : 0;
+ data |= (state & HKEY_DOCK) ? SMI_FN_DOCK_MASK : 0;
+
+ dprintk("set_hotkeys (Fn interface) raw_state: %x\n", data);
+
+ /*
+ * Hardware seems to be quite stubborn and multiple retries may be
+ * required. The criteria here is simple: retry until probed state match
+ * the requested one (with timeout).
+ */
+ for (i = 0; i < 250; i++) {
+ retval = nbsmi_smi_write_command(&hotkeys_op, data);
+ if (retval)
+ return retval;
+ mdelay(1);
+ retval = nbsmi_smi_read_command(&hotkeys_op, &rdata);
+ if(retval)
+ return retval;
+ if(rdata == data) {
+ dprintk("check loop ok after %i iters\n.",i);
+ return 0;
+ }
+ }
+ dprintk("error or check loop timeout !!\n");
- retval = nbsmi_smi_write_command(&hotkeys_op, data);
-
return retval;
}
break;
}
}
- if(matched==255) {
- printk("Display mode %x is unsupported.\n", state);
+
+ if(matched == 255) {
+ printk(O_ERR "Display mode %x is unsupported.\n", state);
return -EINVAL;
}
struct omnibook_backend nbsmi_backend = {
.name = "nbsmi",
-/* .hotkey_read_cap = HKEY_FN | HKEY_STICK | HKEY_TWICE_LOCK | HKEY_DOCK, */
+ .hotkeys_read_cap = HKEY_FN | HKEY_STICK | HKEY_TWICE_LOCK | HKEY_DOCK,
.hotkeys_write_cap = HKEY_FN | HKEY_STICK | HKEY_TWICE_LOCK | HKEY_DOCK | HKEY_FNF5,
.init = omnibook_nbsmi_init,
.exit = omnibook_nbsmi_exit,
.byte_write = nbsmi_smi_write_command,
.aerial_get = omnibook_nbsmi_get_wireless,
.aerial_set = omnibook_nbsmi_set_wireless,
-/* .hotkeys_get = omnibook_nbmsi_hotkeys_get, */
+ .hotkeys_get = omnibook_nbmsi_hotkeys_get,
.hotkeys_set = omnibook_nbmsi_hotkeys_set,
.display_get = omnibook_nbmsi_display_get,
.display_set = omnibook_nbmsi_display_set,
TSA105 = (1<<13) /* 14 Toshiba Satellite A105 */
} omnibook_ectype;
+#define ALL_ECTYPES XE3GF|XE3GC|OB500|OB510|OB6000|OB6100|XE4500|OB4150|XE2|AMILOD|TSP10|TSM30X|TSM40|TSA105
+
/*
* This represent a feature provided by this module
*/
struct list_head list;
};
-struct omnibook_battery_info {
- u8 type; /* 1 - Li-Ion, 2 NiMH */
- u16 sn; /* Serial number */
- u16 dv; /* Design Voltage */
- u16 dc; /* Design Capacity */
-};
-struct omnibook_battery_state {
- u16 pv; /* Present Voltage */
- u16 rc; /* Remaining Capacity */
- u16 lc; /* Last Full Capacity */
- u8 gauge; /* Gauge in % */
- u8 status; /* 0 - unknown, 1 - charged, 2 - discharging, 3 - charging, 4 - critical) */
-};
-
-enum {
- OMNIBOOK_BATTSTAT_UNKNOWN,
- OMNIBOOK_BATTSTAT_CHARGED,
- OMNIBOOK_BATTSTAT_DISCHARGING,
- OMNIBOOK_BATTSTAT_CHARGING,
- OMNIBOOK_BATTSTAT_CRITICAL
-};
-
-
/*
* State of a Wifi/Bluetooth adapter
*/
/*
* Configuration for standalone compilation:
* -Register as backlight depends on kernel config (requires 2.6.17+ interface)
- * -Legacy features disbled by default
+ * -Legacy features disabled for ACPI enabled system
*/
#ifdef OMNIBOOK_STANDALONE
#else
#undef CONFIG_OMNIBOOK_BACKLIGHT
#endif /* BACKLIGHT_CLASS_DEVICE */
-#undef CONFIG_OMNIBOOK_LEGACY
+#ifdef CONFIG_ACPI_EC
+#undef CONFIG_OMNIBOOK_LEGACY
+#else
+#define CONFIG_OMNIBOOK_LEGACY
+#endif /* CONFIG_ACPI_EC */
#endif /* OMNIBOOK_STANDALONE */
/* End of file */
* only at module init/exit time so there is no need for a lock.
*/
-struct pio_private_data_t {
+struct pio_priv_data_t {
unsigned long addr;
struct kref refcount;
struct list_head list;
};
-static struct pio_private_data_t pio_private_data = {
+static struct pio_priv_data_t pio_priv_data = {
.addr = 0,
- .list = LIST_HEAD_INIT(pio_private_data.list),
+ .list = LIST_HEAD_INIT(pio_priv_data.list),
};
/*
* Match an entry in the linked list helper function: see if we have and entry
* whose addr field match maddr
*/
-static struct pio_private_data_t *omnibook_match_port(struct pio_private_data_t *data,
+static struct pio_priv_data_t *omnibook_match_port(struct pio_priv_data_t *data,
unsigned long maddr)
{
- struct pio_private_data_t *cursor;
+ struct pio_priv_data_t *cursor;
list_for_each_entry(cursor, &data->list, list) {
if (cursor->addr == maddr) {
/*
* See if we have to request raddr
*/
-static int omnibook_claim_port(struct pio_private_data_t *data, unsigned long raddr)
+static int omnibook_claim_port(struct pio_priv_data_t *data, unsigned long raddr)
{
- struct pio_private_data_t *match, *new;
+ struct pio_priv_data_t *match, *new;
match = omnibook_match_port(data, raddr);
if (match) {
return -ENODEV;
}
- new = kmalloc(sizeof(struct pio_private_data_t), GFP_KERNEL);
+ new = kmalloc(sizeof(struct pio_priv_data_t), GFP_KERNEL);
if (!new) {
release_region(raddr, 1);
return -ENOMEM;
*/
static void omnibook_free_port(struct kref *ref)
{
- struct pio_private_data_t *data;
+ struct pio_priv_data_t *data;
- data = container_of(ref, struct pio_private_data_t, refcount);
+ data = container_of(ref, struct pio_priv_data_t, refcount);
release_region(data->addr, 1);
list_del(&data->list);
kfree(data);
*/
static void omnibook_pio_exit(const struct omnibook_operation *io_op)
{
- struct pio_private_data_t *match;
+ struct pio_priv_data_t *match;
match = omnibook_match_port(io_op->backend->data, io_op->read_addr);
if (match)
*/
struct omnibook_backend pio_backend = {
.name = "pio",
- .data = &pio_private_data,
+ .data = &pio_priv_data,
.init = omnibook_pio_init,
.exit = omnibook_pio_exit,
.byte_read = omnibook_io_read,
*/
static struct workqueue_struct *omnibook_wq;
static int key_polling_enabled;
-DEFINE_MUTEX(poll_mutex);
+static DEFINE_MUTEX(poll_mutex);
static void omnibook_key_poller(void *data);
static struct omnibook_feature key_polling_driver;
-DECLARE_WORK(omnibook_poll_work, *omnibook_key_poller, &key_polling_driver.io_op);
+static DECLARE_WORK(omnibook_poll_work, *omnibook_key_poller, &key_polling_driver.io_op);
static struct input_dev *poll_input_dev;