Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
authorDmitry Torokhov <dtor_core@ameritech.net>
Fri, 6 Jan 2006 03:25:13 +0000 (22:25 -0500)
committerDmitry Torokhov <dtor_core@ameritech.net>
Fri, 6 Jan 2006 03:25:13 +0000 (22:25 -0500)
1  2 
drivers/usb/input/appletouch.c

@@@ -6,7 -6,6 +6,7 @@@
   * Copyright (C) 2005      Stelian Pop (stelian@popies.net)
   * Copyright (C) 2005      Frank Arnold (frank@scirocco-5v-turbo.de)
   * Copyright (C) 2005      Peter Osterlund (petero2@telia.com)
 + * Copyright (C) 2005      Michael Hanselmann (linux-kernel@hansmi.ch)
   *
   * Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
   *
  /* Apple has powerbooks which have the keyboard with different Product IDs */
  #define APPLE_VENDOR_ID               0x05AC
  
 +/* These names come from Info.plist in AppleUSBTrackpad.kext */
 +#define GEYSER_ANSI_PRODUCT_ID        0x0214
 +#define GEYSER_ISO_PRODUCT_ID 0x0215
 +#define GEYSER_JIS_PRODUCT_ID 0x0216
 +
  #define ATP_DEVICE(prod)                                      \
        .match_flags = USB_DEVICE_ID_MATCH_DEVICE |             \
                       USB_DEVICE_ID_MATCH_INT_CLASS |          \
@@@ -59,17 -53,13 +59,17 @@@ static struct usb_device_id atp_table [
        { ATP_DEVICE(0x020F) },
        { ATP_DEVICE(0x030A) },
        { ATP_DEVICE(0x030B) },
 -      { }                                     /* Terminating entry */
 +
 +      /* PowerBooks Oct 2005 */
 +      { ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) },
 +      { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
 +      { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
 +
 +      /* Terminating entry */
 +      { }
  };
  MODULE_DEVICE_TABLE (usb, atp_table);
  
 -/* size of a USB urb transfer */
 -#define ATP_DATASIZE  81
 -
  /*
   * number of sensors. Note that only 16 instead of 26 X (horizontal)
   * sensors exist on 12" and 15" PowerBooks. All models have 16 Y
@@@ -118,8 -108,6 +118,8 @@@ struct atp 
        signed char             xy_old[ATP_XSENSORS + ATP_YSENSORS];
                                                /* accumulated sensors */
        int                     xy_acc[ATP_XSENSORS + ATP_YSENSORS];
 +      int                     overflowwarn;   /* overflow warning printed? */
 +      int                     datalen;        /* size of an USB urb transfer */
  };
  
  #define dbg_dump(msg, tab) \
                if (debug) printk(format, ##a);                         \
        } while (0)
  
 -MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold");
 +MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann");
  MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
  MODULE_LICENSE("GPL");
  
@@@ -144,16 -132,6 +144,16 @@@ static int debug = 1
  module_param(debug, int, 0644);
  MODULE_PARM_DESC(debug, "Activate debugging output");
  
 +/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */
 +static inline int atp_is_geyser_2(struct atp *dev)
 +{
 +      int16_t productId = le16_to_cpu(dev->udev->descriptor.idProduct);
 +
 +      return (productId == GEYSER_ANSI_PRODUCT_ID) ||
 +              (productId == GEYSER_ISO_PRODUCT_ID) ||
 +              (productId == GEYSER_JIS_PRODUCT_ID);
 +}
 +
  static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
                             int *z, int *fingers)
  {
@@@ -190,20 -168,13 +190,20 @@@ static inline void atp_report_fingers(s
  static void atp_complete(struct urb* urb, struct pt_regs* regs)
  {
        int x, y, x_z, y_z, x_f, y_f;
 -      int retval, i;
 +      int retval, i, j;
        struct atp *dev = urb->context;
  
        switch (urb->status) {
        case 0:
                /* success */
                break;
 +      case -EOVERFLOW:
 +              if(!dev->overflowwarn) {
 +                      printk("appletouch: OVERFLOW with data "
 +                              "length %d, actual length is %d\n",
 +                              dev->datalen, dev->urb->actual_length);
 +                      dev->overflowwarn = 1;
 +              }
        case -ECONNRESET:
        case -ENOENT:
        case -ESHUTDOWN:
        }
  
        /* drop incomplete datasets */
 -      if (dev->urb->actual_length != ATP_DATASIZE) {
 +      if (dev->urb->actual_length != dev->datalen) {
                dprintk("appletouch: incomplete data package.\n");
                goto exit;
        }
  
        /* reorder the sensors values */
 -      for (i = 0; i < 8; i++) {
 -              /* X values */
 -              dev->xy_cur[i     ] = dev->data[5 * i +  2];
 -              dev->xy_cur[i +  8] = dev->data[5 * i +  4];
 -              dev->xy_cur[i + 16] = dev->data[5 * i + 42];
 -              if (i < 2)
 -                      dev->xy_cur[i + 24] = dev->data[5 * i + 44];
 -
 -              /* Y values */
 -              dev->xy_cur[i + 26] = dev->data[5 * i +  1];
 -              dev->xy_cur[i + 34] = dev->data[5 * i +  3];
 +      if (atp_is_geyser_2(dev)) {
 +              memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
 +
 +              /*
 +               * The values are laid out like this:
 +               * Y1, Y2, -, Y3, Y4, -, ..., X1, X2, -, X3, X4, -, ...
 +               * '-' is an unused value.
 +               */
 +
 +              /* read X values */
 +              for (i = 0, j = 19; i < 20; i += 2, j += 3) {
 +                      dev->xy_cur[i] = dev->data[j];
 +                      dev->xy_cur[i + 1] = dev->data[j + 1];
 +              }
 +
 +              /* read Y values */
 +              for (i = 0, j = 1; i < 9; i += 2, j += 3) {
 +                      dev->xy_cur[ATP_XSENSORS + i] = dev->data[j];
 +                      dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 1];
 +              }
 +      } else {
 +              for (i = 0; i < 8; i++) {
 +                      /* X values */
 +                      dev->xy_cur[i     ] = dev->data[5 * i +  2];
 +                      dev->xy_cur[i +  8] = dev->data[5 * i +  4];
 +                      dev->xy_cur[i + 16] = dev->data[5 * i + 42];
 +                      if (i < 2)
 +                              dev->xy_cur[i + 24] = dev->data[5 * i + 44];
 +
 +                      /* Y values */
 +                      dev->xy_cur[i + 26] = dev->data[5 * i +  1];
 +                      dev->xy_cur[i + 34] = dev->data[5 * i +  3];
 +              }
        }
  
        dbg_dump("sample", dev->xy_cur);
                dev->x_old = dev->y_old = -1;
                memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
  
 -              /* 17" Powerbooks have 10 extra X sensors */
 -              for (i = 16; i < ATP_XSENSORS; i++)
 -                      if (dev->xy_cur[i]) {
 -                              printk("appletouch: 17\" model detected.\n");
 +              /* 17" Powerbooks have extra X sensors */
 +              for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) {
 +                      if (!dev->xy_cur[i]) continue;
 +
 +                      printk("appletouch: 17\" model detected.\n");
 +                      if(atp_is_geyser_2(dev))
 +                              input_set_abs_params(dev->input, ABS_X, 0,
 +                                                   (20 - 1) *
 +                                                   ATP_XFACT - 1,
 +                                                   ATP_FUZZ, 0);
 +                      else
                                input_set_abs_params(dev->input, ABS_X, 0,
                                                     (ATP_XSENSORS - 1) *
                                                     ATP_XFACT - 1,
                                                     ATP_FUZZ, 0);
 -                              break;
 -                      }
 +
 +                      break;
 +              }
  
                goto exit;
        }
                memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
        }
  
 -      input_report_key(dev->input, BTN_LEFT, !!dev->data[80]);
 +      input_report_key(dev->input, BTN_LEFT,
 +                       !!dev->data[dev->datalen - 1]);
  
        input_sync(dev->input);
  
@@@ -413,8 -353,6 +413,8 @@@ static int atp_probe(struct usb_interfa
  
        dev->udev = udev;
        dev->input = input_dev;
 +      dev->overflowwarn = 0;
 +      dev->datalen = (atp_is_geyser_2(dev)?64:81);
  
        dev->urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!dev->urb) {
                goto err_free_devs;
        }
  
 -      dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL,
 +      dev->data = usb_buffer_alloc(dev->udev, dev->datalen, GFP_KERNEL,
                                     &dev->urb->transfer_dma);
        if (!dev->data) {
                retval = -ENOMEM;
  
        usb_fill_int_urb(dev->urb, udev,
                         usb_rcvintpipe(udev, int_in_endpointAddr),
 -                       dev->data, ATP_DATASIZE, atp_complete, dev, 1);
 +                       dev->data, dev->datalen, atp_complete, dev, 1);
  
        usb_make_path(udev, dev->phys, sizeof(dev->phys));
        strlcat(dev->phys, "/input0", sizeof(dev->phys));
  
        set_bit(EV_ABS, input_dev->evbit);
  
 -      /*
 -       * 12" and 15" Powerbooks only have 16 x sensors,
 -       * 17" models are detected later.
 -       */
 -      input_set_abs_params(input_dev, ABS_X, 0,
 -                           (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
 -      input_set_abs_params(input_dev, ABS_Y, 0,
 -                           (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
 +      if (atp_is_geyser_2(dev)) {
 +              /*
 +               * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
 +               * later.
 +               */
 +              input_set_abs_params(input_dev, ABS_X, 0,
 +                                   ((15 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
 +              input_set_abs_params(input_dev, ABS_Y, 0,
 +                                   ((9 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
 +      } else {
 +              /*
 +               * 12" and 15" Powerbooks only have 16 x sensors,
 +               * 17" models are detected later.
 +               */
 +              input_set_abs_params(input_dev, ABS_X, 0,
 +                                   (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
 +              input_set_abs_params(input_dev, ABS_Y, 0,
 +                                   (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
 +      }
        input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
  
        set_bit(EV_KEY, input_dev->evbit);
@@@ -500,7 -427,7 +500,7 @@@ static void atp_disconnect(struct usb_i
                usb_kill_urb(dev->urb);
                input_unregister_device(dev->input);
                usb_free_urb(dev->urb);
 -              usb_buffer_free(dev->udev, ATP_DATASIZE,
 +              usb_buffer_free(dev->udev, dev->datalen,
                                dev->data, dev->urb->transfer_dma);
                kfree(dev);
        }
@@@ -525,7 -452,6 +525,6 @@@ static int atp_resume(struct usb_interf
  }
  
  static struct usb_driver atp_driver = {
-       .owner          = THIS_MODULE,
        .name           = "appletouch",
        .probe          = atp_probe,
        .disconnect     = atp_disconnect,