[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#404417: marked as done (linux-source-2.6.18: Add support of appleir module for Apple MacBook computers)



Your message dated Tue, 31 Jul 2007 12:04:26 +0200
with message-id <20070731100426.GG18968@stro.at>
and subject line patches for macbook computers
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--- Begin Message ---
Package: linux-source-2.6.18
Severity: wishlist
Tags: patch

Hello,

I have an Apple MacBook Pro and the appleir kernel module is needed for
controling rhythmbox with the IR remote (for example).

A patch for appleir is maintained in the mactel SVN repository at
http://svn.sourceforge.net/viewvc/mactel-linux/trunk/kernel/mactel-patches-2.6.18/ir.patch?view=log

I also include the patch here.

The patch should be included in vanilla Linux at some time but maybe not
before 2.6.20. It would be nice if the Debian kernel for Etch has
support for Apple MacBook Pro and non Pro computers.

Thanks


-- System Information:
Debian Release: 4.0
  APT prefers testing
  APT policy: (500, 'testing'), (90, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-3-686
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
--- linux-2.6.16.1/drivers/usb/input/Makefile	2006-03-28 07:49:02.000000000 +0100
+++ linux-2.6.16.1-imac-sky2-rtc/drivers/usb/input/Makefile	2006-05-22 13:14:40.000000000 +0100
@@ -32,6 +32,7 @@
 obj-$(CONFIG_USB_HID)		+= usbhid.o
 obj-$(CONFIG_USB_KBD)		+= usbkbd.o
 obj-$(CONFIG_USB_KBTAB)		+= kbtab.o
+obj-$(CONFIG_USB_APPLEIR)		+= appleir.o
 obj-$(CONFIG_USB_KEYSPAN_REMOTE)	+= keyspan_remote.o
 obj-$(CONFIG_USB_MOUSE)		+= usbmouse.o
 obj-$(CONFIG_USB_MTOUCH)	+= mtouchusb.o
--- linux-2.6.16.1/drivers/usb/input/Kconfig	2006-03-28 07:49:02.000000000 +0100
+++ linux-2.6.16.1-imac-sky2-rtc/drivers/usb/input/Kconfig	2006-05-22 13:15:16.000000000 +0100
@@ -173,6 +173,10 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called acecad.
 
+config USB_APPLEIR
+	tristate "Apple Mac Mini USB IR receiver (built in)"
+	depends on USB && INPUT
+	
 config USB_KBTAB
 	tristate "KB Gear JamStudio tablet support"
 	depends on USB && INPUT
--- linux-2.6.16.1/drivers/usb/input/appleir.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.16.1-imac-sky2-rtc/drivers/usb/input/appleir.c	2006-05-29 09:47:40.000000000 +0100
@@ -0,0 +1,390 @@
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <asm/unaligned.h>
+#include <asm/byteorder.h>
+
+/*
+ * Version Information
+ *
+ */
+
+#if 0
+#define DUMP_PACKETS
+#else
+#undef DUMP_PACKETS
+#endif
+
+#define DRIVER_VERSION "v1.1"
+#define DRIVER_AUTHOR "James McKenzie"
+#define DRIVER_DESC "USB Apple MacMini IR Receiver driver"
+#define DRIVER_LICENSE "GPL"
+
+MODULE_AUTHOR (DRIVER_AUTHOR);
+MODULE_DESCRIPTION (DRIVER_DESC);
+MODULE_LICENSE (DRIVER_LICENSE);
+
+#ifndef USB_VENDOR_ID_APPLE
+#define USB_VENDOR_ID_APPLE	0x05ac
+#endif
+#ifndef USB_DEVICE_ID_APPLE_IR
+#define USB_DEVICE_ID_APPLE_IR  0x8240
+#endif
+
+#define URB_SIZE 32
+
+#define MAX_KEYS 8
+#define MAX_KEYS_MASK (MAX_KEYS - 1 )
+
+struct appleir
+{
+  struct input_dev *dev;
+  uint8_t *data;
+  dma_addr_t dma_buf;
+  struct usb_device *usbdev;
+  struct urb *urb;
+  int timer_initted;
+  struct timer_list key_up_timer;
+  int current_key;
+  char phys[32];
+};
+
+
+static struct usb_device_id appleir_ids[] = {
+  {USB_DEVICE (USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR),.driver_info = 0},
+  {}
+};
+
+MODULE_DEVICE_TABLE (usb, appleir_ids);
+
+
+/* I have two devices both of which report the following */
+/* 25 87 ee 83 0a  	+  */
+/* 25 87 ee 83 0c  	-  */
+/* 25 87 ee 83 09	<< */
+/* 25 87 ee 83 06	>> */
+/* 25 87 ee 83 05	>" */
+/* 25 87 ee 83 03	menu */
+/* 26 00 00 00 00	for key repeat*/
+
+/* Thomas Glanzmann reports the following responses */
+/* 25 87 ee ca 0b	+  */
+/* 25 87 ee ca 0d	-  */
+/* 25 87 ee ca 08	<< */
+/* 25 87 ee ca 07	>> */
+/* 25 87 ee ca 04	>" */
+/* 25 87 ee ca 02 	menu */
+/* 26 00 00 00 00       for key repeat*/
+/* He also observes the following event sometimes */
+/* sent after a key is release, which I interpret */
+/* as a flat battery message */
+/* 25 87 e0 ca 06	flat battery */
+
+
+static int keymap[MAX_KEYS] = {
+  KEY_RESERVED, KEY_MENU,
+  KEY_PLAYPAUSE, KEY_NEXTSONG,
+  KEY_PREVIOUSSONG, KEY_VOLUMEUP,
+  KEY_VOLUMEDOWN, KEY_RESERVED
+};
+
+static void
+dump_packet (struct appleir *appleir, char *msg, uint8_t * data, int len)
+{
+  int i;
+
+  printk (KERN_ERR "appleir: %s (%d bytes)", msg, len);
+
+  for (i = 0; i < len; ++i)
+    {
+      printk (" %02x", data[i]);
+    }
+
+  printk ("\n");
+}
+
+
+static void
+key_up (struct appleir *appleir, int key)
+{
+  //printk (KERN_ERR "key %d up\n", key);
+  input_report_key (appleir->dev, key, 0);
+  input_sync (appleir->dev);
+}
+
+static void
+key_down (struct appleir *appleir, int key)
+{
+  //printk (KERN_ERR "key %d down\n", key);
+  input_report_key (appleir->dev, key, 1);
+  input_sync (appleir->dev);
+}
+
+static void
+battery_flat (struct appleir *appleir)
+{
+  printk (KERN_ERR "appleir: possible flat battery?\n");
+}
+
+static void
+key_up_tick (unsigned long data)
+{
+  struct appleir *appleir = (struct appleir *) data;
+
+  if (appleir->current_key)
+    {
+      key_up (appleir, appleir->current_key);
+      appleir->current_key = 0;
+    }
+}
+
+static void
+new_data (struct appleir *appleir, uint8_t * data, int len)
+{
+  static const uint8_t keydown[] = { 0x25, 0x87, 0xee };
+  static const uint8_t keyrepeat[] = { 0x26, 0x00, 0x00, 0x00, 0x00 };
+  static const uint8_t flatbattery[] = { 0x25, 0x87, 0xe0 };
+
+#ifdef DUMP_PACKETS
+  dump_packet (appleir, "received", data, len);
+#endif
+
+  if (len != 5)
+    return;
+
+  if (!memcmp (data, keydown, sizeof (keydown)))
+    {
+      /*If we already have a key down, take it up before marking */
+      /*this one down */
+      if (appleir->current_key)
+        key_up (appleir, appleir->current_key);
+      appleir->current_key = keymap[(data[4] >> 1) & MAX_KEYS_MASK];
+
+      key_down (appleir, appleir->current_key);
+      /*remote doesn't do key up, either pull them up, in the test */
+      /*above, or here set a timer which pulls them up after 1/8 s */
+      mod_timer (&appleir->key_up_timer, jiffies + HZ / 8);
+
+      return;
+    }
+
+  if (!memcmp (data, keyrepeat, sizeof (keyrepeat)))
+    {
+      key_down (appleir, appleir->current_key);
+      /*remote doesn't do key up, either pull them up, in the test */
+      /*above, or here set a timer which pulls them up after 1/8 s */
+      mod_timer (&appleir->key_up_timer, jiffies + HZ / 8);
+      return;
+    }
+
+  if (!memcmp (data, flatbattery, sizeof (flatbattery)))
+    {
+      battery_flat (appleir);
+      /*Fall through */
+    }
+
+  dump_packet (appleir, "unknown packet", data, len);
+}
+
+static void
+appleir_urb (struct urb *urb, struct pt_regs *regs)
+{
+  struct appleir *appleir = urb->context;
+  int retval;
+
+  switch (urb->status)
+    {
+    case 0:
+      new_data (appleir, urb->transfer_buffer, urb->actual_length);
+      break;
+    case -ECONNRESET:
+    case -ENOENT:
+    case -ESHUTDOWN:
+      /* this urb is terminated, clean up */
+      dbg ("%s - urb shutting down with status: %d", __FUNCTION__,
+           urb->status);
+      return;
+    default:
+      dbg ("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+    }
+
+  retval = usb_submit_urb (urb, GFP_ATOMIC);
+  if (retval)
+    err ("%s - usb_submit_urb failed with result %d", __FUNCTION__, retval);
+}
+
+
+static int
+appleir_open (struct input_dev *dev)
+{
+  struct appleir *appleir = dev->private;
+
+  //appleir->urb->dev = appleir->usbdev;
+
+  if (usb_submit_urb (appleir->urb, GFP_KERNEL))
+    return -EIO;
+
+  return 0;
+}
+
+static void
+appleir_close (struct input_dev *dev)
+{
+  struct appleir *appleir = dev->private;
+  usb_kill_urb (appleir->urb);
+  del_timer_sync (&appleir->key_up_timer);
+}
+
+
+
+
+static int
+appleir_probe (struct usb_interface *intf, const struct usb_device_id *id)
+{
+  struct usb_device *dev = interface_to_usbdev (intf);
+  struct usb_endpoint_descriptor *endpoint;
+  struct appleir *appleir = NULL;
+  struct input_dev *input_dev;
+  int i;
+
+  appleir = kzalloc (sizeof (struct appleir), GFP_KERNEL);
+  if (!appleir)
+    goto fail;
+
+  memset (appleir, 0, sizeof (struct appleir));
+
+
+  appleir->data =
+    usb_buffer_alloc (dev, URB_SIZE, GFP_KERNEL, &appleir->dma_buf);
+  if (!appleir->data)
+    goto fail;
+
+  appleir->urb = usb_alloc_urb (0, GFP_KERNEL);
+  if (!appleir->urb)
+    goto fail;
+
+  appleir->usbdev = dev;
+
+  input_dev = input_allocate_device ();
+  if (!input_dev)
+    goto fail;
+
+  appleir->dev = input_dev;
+
+
+  usb_make_path (dev, appleir->phys, sizeof (appleir->phys));
+  strlcpy (appleir->phys, "/input0", sizeof (appleir->phys));
+
+  input_dev->name = "Apple Mac mini infrared remote control driver";
+  input_dev->phys = appleir->phys;
+  usb_to_input_id (dev, &input_dev->id);
+  input_dev->cdev.dev = &intf->dev;
+  input_dev->private = appleir;
+
+  input_dev->evbit[0] = BIT (EV_KEY) | BIT (EV_REP);
+  input_dev->ledbit[0] = 0;
+
+  for (i = 0; i < MAX_KEYS; i++)
+    {
+      set_bit (keymap[i], input_dev->keybit);
+    }
+
+  clear_bit (0, input_dev->keybit);
+
+  input_dev->open = appleir_open;
+  input_dev->close = appleir_close;
+
+  endpoint = &intf->cur_altsetting->endpoint[0].desc;
+
+  usb_fill_int_urb (appleir->urb, dev,
+                    usb_rcvintpipe (dev, endpoint->bEndpointAddress),
+                    appleir->data, 8,
+                    appleir_urb, appleir, endpoint->bInterval);
+
+  appleir->urb->transfer_dma = appleir->dma_buf;
+  appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+  usb_set_intfdata (intf, appleir);
+
+  init_timer (&appleir->key_up_timer);
+
+  appleir->key_up_timer.function = key_up_tick;
+  appleir->key_up_timer.data = (unsigned long) appleir;
+
+  appleir->timer_initted++;
+
+  input_register_device (appleir->dev);
+
+  return 0;
+
+fail:
+
+  if (appleir)
+    {
+
+
+      if (appleir->data)
+        usb_buffer_free (dev, URB_SIZE, appleir->data, appleir->dma_buf);
+
+      if (appleir->timer_initted)
+        del_timer_sync (&appleir->key_up_timer);
+
+      if (appleir->dev)
+        input_free_device (appleir->dev);
+
+      kfree (appleir);
+    }
+
+  return -ENOMEM;
+}
+
+static void
+appleir_disconnect (struct usb_interface *intf)
+{
+  struct appleir *appleir = usb_get_intfdata (intf);
+
+  usb_set_intfdata (intf, NULL);
+  if (appleir)
+    {
+      input_unregister_device (appleir->dev);
+      if (appleir->timer_initted)
+        del_timer_sync (&appleir->key_up_timer);
+      usb_kill_urb (appleir->urb);
+      usb_free_urb (appleir->urb);
+      usb_buffer_free (interface_to_usbdev (intf), URB_SIZE, appleir->data,
+                       appleir->dma_buf);
+      kfree (appleir);
+    }
+}
+
+static struct usb_driver appleir_driver = {
+  .name = "appleir",
+  .probe = appleir_probe,
+  .disconnect = appleir_disconnect,
+  .id_table = appleir_ids,
+};
+
+static int __init
+appleir_init (void)
+{
+  int retval;
+  retval = usb_register (&appleir_driver);
+  if (retval)
+    goto out;
+  info (DRIVER_VERSION ":" DRIVER_DESC);
+out:
+  return retval;
+}
+
+static void __exit
+appleir_exit (void)
+{
+  usb_deregister (&appleir_driver);
+}
+
+module_init (appleir_init);
+module_exit (appleir_exit);

--- End Message ---
--- Begin Message ---
please push those patches upstream,
then they'll land directly into debian.
if they are not upstream quality it is hihgly questionable
why debian should apply them.

please read
http://wiki.debian.org/DebianKernelPatchAcceptanceGuidelines

thus closing

-- 
maks

--- End Message ---

Reply to: