diff -Naurp a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c --- a/arch/powerpc/kvm/book3s_emulate.c 2013-07-01 00:13:29.000000000 +0200 +++ b/arch/powerpc/kvm/book3s_emulate.c 2013-09-05 02:02:56.000000000 +0200 @@ -458,6 +458,7 @@ int kvmppc_core_emulate_mtspr(struct kvm case SPRN_PMC4_GEKKO: case SPRN_WPAR_GEKKO: case SPRN_MSSSR0: + case SPRN_DABR: break; unprivileged: default: @@ -555,6 +556,7 @@ int kvmppc_core_emulate_mfspr(struct kvm case SPRN_PMC4_GEKKO: case SPRN_WPAR_GEKKO: case SPRN_MSSSR0: + case SPRN_DABR: *spr_val = 0; break; default: diff -Naurp a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c --- a/drivers/i2c/busses/i2c-powermac.c 2013-07-01 00:13:29.000000000 +0200 +++ b/drivers/i2c/busses/i2c-powermac.c 2013-08-29 06:18:10.000000000 +0200 @@ -220,138 +220,28 @@ static int i2c_powermac_remove(struct pl return 0; } -static u32 i2c_powermac_get_addr(struct i2c_adapter *adap, - struct pmac_i2c_bus *bus, - struct device_node *node) -{ - const __be32 *prop; - int len; - - /* First check for valid "reg" */ - prop = of_get_property(node, "reg", &len); - if (prop && (len >= sizeof(int))) - return (be32_to_cpup(prop) & 0xff) >> 1; - - /* Then check old-style "i2c-address" */ - prop = of_get_property(node, "i2c-address", &len); - if (prop && (len >= sizeof(int))) - return (be32_to_cpup(prop) & 0xff) >> 1; - - /* Now handle some devices with missing "reg" properties */ - if (!strcmp(node->name, "cereal")) - return 0x60; - else if (!strcmp(node->name, "deq")) - return 0x34; - - dev_warn(&adap->dev, "No i2c address for %s\n", node->full_name); - - return 0xffffffff; -} - -static void i2c_powermac_create_one(struct i2c_adapter *adap, - const char *type, - u32 addr) -{ - struct i2c_board_info info = {}; - struct i2c_client *newdev; - - strncpy(info.type, type, sizeof(info.type)); - info.addr = addr; - newdev = i2c_new_device(adap, &info); - if (!newdev) - dev_err(&adap->dev, - "i2c-powermac: Failure to register missing %s\n", - type); -} - -static void i2c_powermac_add_missing(struct i2c_adapter *adap, - struct pmac_i2c_bus *bus, - bool found_onyx) -{ - struct device_node *busnode = pmac_i2c_get_bus_node(bus); - int rc; - - /* Check for the onyx audio codec */ -#define ONYX_REG_CONTROL 67 - if (of_device_is_compatible(busnode, "k2-i2c") && !found_onyx) { - union i2c_smbus_data data; - - rc = i2c_smbus_xfer(adap, 0x46, 0, I2C_SMBUS_READ, - ONYX_REG_CONTROL, I2C_SMBUS_BYTE_DATA, - &data); - if (rc >= 0) - i2c_powermac_create_one(adap, "MAC,pcm3052", 0x46); - - rc = i2c_smbus_xfer(adap, 0x47, 0, I2C_SMBUS_READ, - ONYX_REG_CONTROL, I2C_SMBUS_BYTE_DATA, - &data); - if (rc >= 0) - i2c_powermac_create_one(adap, "MAC,pcm3052", 0x47); - } -} - -static bool i2c_powermac_get_type(struct i2c_adapter *adap, - struct device_node *node, - u32 addr, char *type, int type_size) -{ - char tmp[16]; - - /* Note: we to _NOT_ want the standard - * i2c drivers to match with any of our powermac stuff - * unless they have been specifically modified to handle - * it on a case by case basis. For example, for thermal - * control, things like lm75 etc... shall match with their - * corresponding windfarm drivers, _NOT_ the generic ones, - * so we force a prefix of AAPL, onto the modalias to - * make that happen - */ - - /* First try proper modalias */ - if (of_modalias_node(node, tmp, sizeof(tmp)) >= 0) { - snprintf(type, type_size, "MAC,%s", tmp); - return true; - } - - /* Now look for known workarounds */ - if (!strcmp(node->name, "deq")) { - /* Apple uses address 0x34 for TAS3001 and 0x35 for TAS3004 */ - if (addr == 0x34) { - snprintf(type, type_size, "MAC,tas3001"); - return true; - } else if (addr == 0x35) { - snprintf(type, type_size, "MAC,tas3004"); - return true; - } - } - - dev_err(&adap->dev, "i2c-powermac: modalias failure" - " on %s\n", node->full_name); - return false; -} - static void i2c_powermac_register_devices(struct i2c_adapter *adap, struct pmac_i2c_bus *bus) { struct i2c_client *newdev; struct device_node *node; - bool found_onyx = 0; - - /* - * In some cases we end up with the via-pmu node itself, in this - * case we skip this function completely as the device-tree will - * not contain anything useful. - */ - if (!strcmp(adap->dev.of_node->name, "via-pmu")) - return; for_each_child_of_node(adap->dev.of_node, node) { struct i2c_board_info info = {}; + struct dev_archdata dev_ad = {}; + const __be32 *reg; + char tmp[16]; u32 addr; + int len; /* Get address & channel */ - addr = i2c_powermac_get_addr(adap, bus, node); - if (addr == 0xffffffff) + reg = of_get_property(node, "reg", &len); + if (!reg || (len < sizeof(int))) { + dev_err(&adap->dev, "i2c-powermac: invalid reg on %s\n", + node->full_name); continue; + } + addr = be32_to_cpup(reg); /* Multibus setup, check channel */ if (!pmac_i2c_match_adapter(node, adap)) @@ -360,23 +250,18 @@ static void i2c_powermac_register_device dev_dbg(&adap->dev, "i2c-powermac: register %s\n", node->full_name); - /* - * Keep track of some device existence to handle - * workarounds later. - */ - if (of_device_is_compatible(node, "pcm3052")) - found_onyx = true; - - /* Make up a modalias */ - if (!i2c_powermac_get_type(adap, node, addr, - info.type, sizeof(info.type))) { + if (of_modalias_node(node, tmp, sizeof(tmp)) < 0) { + dev_err(&adap->dev, "i2c-powermac: modalias failure" + " on %s\n", node->full_name); continue; } + snprintf(info.type, sizeof(info.type), "MAC,%s", tmp); /* Fill out the rest of the info structure */ - info.addr = addr; + info.addr = (addr & 0xff) >> 1; info.irq = irq_of_parse_and_map(node, 0); info.of_node = of_node_get(node); + info.archdata = &dev_ad; newdev = i2c_new_device(adap, &info); if (!newdev) { @@ -391,9 +276,6 @@ static void i2c_powermac_register_device continue; } } - - /* Additional workarounds */ - i2c_powermac_add_missing(adap, bus, found_onyx); } static int i2c_powermac_probe(struct platform_device *dev) diff -Naurp a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig --- a/drivers/macintosh/Kconfig 2013-07-01 00:13:29.000000000 +0200 +++ b/drivers/macintosh/Kconfig 2013-08-29 16:24:28.000000000 +0200 @@ -171,6 +171,13 @@ config INPUT_ADBHID If unsure, say Y. +config ADB_TRACKPAD_ABSOLUTE + bool "Enable absolute mode for adb trackpads" + depends on INPUT_ADBHID + help + Enable absolute mode in adb-base trackpads. This feature adds + compatibility with synaptics Xorg / Xfree drivers. + config MAC_EMUMOUSEBTN tristate "Support for mouse button 2+3 emulation" depends on SYSCTL && INPUT diff -Naurp a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c --- a/drivers/macintosh/adbhid.c 2013-07-01 00:13:29.000000000 +0200 +++ b/drivers/macintosh/adbhid.c 2013-08-29 16:26:47.000000000 +0200 @@ -261,6 +261,15 @@ static struct adb_ids buttons_ids; #define ADBMOUSE_MS_A3 8 /* Mouse systems A3 trackball (handler 3) */ #define ADBMOUSE_MACALLY2 9 /* MacAlly 2-button mouse */ +#ifdef CONFIG_ADB_TRACKPAD_ABSOLUTE +#define ABS_XMIN 310 +#define ABS_XMAX 1700 +#define ABS_YMIN 200 +#define ABS_YMAX 1000 +#define ABS_ZMIN 0 +#define ABS_ZMAX 55 +#endif + static void adbhid_keyboard_input(unsigned char *data, int nb, int apoll) { @@ -405,6 +414,9 @@ static void adbhid_mouse_input(unsigned char *data, int nb, int autopoll) { int id = (data[0] >> 4) & 0x0f; +#ifdef CONFIG_ADB_TRACKPAD_ABSOLUTE + int btn = 0; int x_axis = 0; int y_axis = 0; int z_axis = 0; +#endif if (!adbhid[id]) { printk(KERN_ERR "ADB HID on ID %d not yet registered\n", id); @@ -436,6 +448,17 @@ adbhid_mouse_input(unsigned char *data, high bits of y-axis motion. XY is additional high bits of x-axis motion. + For ADB Absolute motion protocol the data array will contain the + following values: + + BITS COMMENTS + data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd. + data[1] = byyy yyyy Left button and y-axis motion. + data[2] = bxxx xxxx Second button and x-axis motion. + data[3] = 1yyy 1xxx Half bits of y-axis and x-axis motion. + data[4] = 1yyy 1xxx Higher bits of y-axis and x-axis motion. + data[5] = 1zzz 1zzz Higher and lower bits of z-pressure. + MacAlly 2-button mouse protocol. For MacAlly 2-button mouse protocol the data array will contain the @@ -458,8 +481,17 @@ adbhid_mouse_input(unsigned char *data, switch (adbhid[id]->mouse_kind) { case ADBMOUSE_TRACKPAD: +#ifdef CONFIG_ADB_TRACKPAD_ABSOLUTE + x_axis = (data[2] & 0x7f) | ((data[3] & 0x07) << 7) | + ((data[4] & 0x07) << 10); + y_axis = (data[1] & 0x7f) | ((data[3] & 0x70) << 3) | + ((data[4] & 0x70) << 6); + z_axis = (data[5] & 0x07) | ((data[5] & 0x70) >> 1); + btn = (!(data[1] >> 7)) & 1; +#else data[1] = (data[1] & 0x7f) | ((data[1] & data[2]) & 0x80); data[2] = data[2] | 0x80; +#endif break; case ADBMOUSE_MICROSPEED: data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7); @@ -485,17 +517,39 @@ adbhid_mouse_input(unsigned char *data, break; } - input_report_key(adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1)); - input_report_key(adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1)); - - if (nb >= 4 && adbhid[id]->mouse_kind != ADBMOUSE_TRACKPAD) - input_report_key(adbhid[id]->input, BTN_RIGHT, !((data[3] >> 7) & 1)); - - input_report_rel(adbhid[id]->input, REL_X, - ((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 )); - input_report_rel(adbhid[id]->input, REL_Y, - ((data[1]&0x7f) < 64 ? (data[1]&0x7f) : (data[1]&0x7f)-128 )); +#ifdef CONFIG_ADB_TRACKPAD_ABSOLUTE + if ( adbhid[id]->mouse_kind == ADBMOUSE_TRACKPAD ) { + + if(z_axis > 30) input_report_key(adbhid[id]->input, BTN_TOUCH, 1); + if(z_axis < 25) input_report_key(adbhid[id]->input, BTN_TOUCH, 0); + + if(z_axis > 0){ + input_report_abs(adbhid[id]->input, ABS_X, x_axis); + input_report_abs(adbhid[id]->input, ABS_Y, y_axis); + input_report_key(adbhid[id]->input, BTN_TOOL_FINGER, 1); + input_report_key(adbhid[id]->input, ABS_TOOL_WIDTH, 5); + } else { + input_report_key(adbhid[id]->input, BTN_TOOL_FINGER, 0); + input_report_key(adbhid[id]->input, ABS_TOOL_WIDTH, 0); + } + input_report_abs(adbhid[id]->input, ABS_PRESSURE, z_axis); + input_report_key(adbhid[id]->input, BTN_LEFT, btn); + } else { +#endif + input_report_key(adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1)); + input_report_key(adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1)); + + if (nb >= 4 && adbhid[id]->mouse_kind != ADBMOUSE_TRACKPAD) + input_report_key(adbhid[id]->input, BTN_RIGHT, !((data[3] >> 7) & 1)); + + input_report_rel(adbhid[id]->input, REL_X, + ((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 )); + input_report_rel(adbhid[id]->input, REL_Y, + ((data[1]&0x7f) < 64 ? (data[1]&0x7f) : (data[1]&0x7f)-128 )); +#ifdef CONFIG_ADB_TRACKPAD_ABSOLUTE + } +#endif input_sync(adbhid[id]->input); } @@ -849,6 +903,15 @@ adbhid_input_register(int id, int defaul input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); +#ifdef CONFIG_ADB_TRACKPAD_ABSOLUTE + set_bit(EV_ABS, input_dev->evbit); + input_set_abs_params(input_dev, ABS_X, ABS_XMIN, ABS_XMAX, 0, 0); + input_set_abs_params(input_dev, ABS_Y, ABS_YMIN, ABS_YMAX, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, ABS_ZMIN, ABS_ZMAX, 0, 0); + set_bit(BTN_TOUCH, input_dev->keybit); + set_bit(BTN_TOOL_FINGER, input_dev->keybit); + set_bit(ABS_TOOL_WIDTH, input_dev->absbit); +#endif break; case ADB_MISC: @@ -1132,7 +1195,11 @@ init_trackpad(int id) r1_buffer[3], r1_buffer[4], r1_buffer[5], +#ifdef CONFIG_ADB_TRACKPAD_ABSOLUTE + 0x00, /* Enable absolute mode */ +#else 0x03, /*r1_buffer[6],*/ +#endif r1_buffer[7]); /* Without this flush, the trackpad may be locked up */