Motorola USB flash mode driver.
authorKazuhiro Ondo <kazuhiro.ondo@motorola.com>
Thu, 22 Jul 2010 16:57:32 +0000 (11:57 -0500)
committerColin Cross <ccross@android.com>
Wed, 6 Oct 2010 23:33:23 +0000 (16:33 -0700)
Change-Id: Idf72cbceeff56523be443013c5cbda79ea829994

drivers/usb/serial/Kconfig
drivers/usb/serial/Makefile
drivers/usb/serial/moto_flashmdm.c [new file with mode: 0644]

index 8547d3e5d497276e230e8db1ae15e372ce74192f..22e2552a9b601890b183459b8a20ee157b768102 100644 (file)
@@ -467,6 +467,15 @@ config USB_MDM6600_CDMA_MODEM
           To compile this driver as a module, choose M here: the
           module will be called mdm6600_modem.  If unsure, choose N.
 
+config USB_SERIAL_MOTO_FLASH_MODEM
+       tristate "USB Motorola modem flash driver"
+       ---help---
+        Say Y here if you want to enable the AP/BP USB IPC link
+        driver for MDM6600 modem.
+
+        To compile this driver as a module, choose M here: the
+        module will be called moto_flashmdm.  If unsure, choose N.
+
 config USB_SERIAL_NAVMAN
        tristate "USB Navman GPS device"
        help
index 5b50ed1d9dfe209f8d60061d0ebc7966a6915474..fb818a50c189fa0d019d458915a05f6f7eea96a2 100644 (file)
@@ -40,6 +40,7 @@ obj-$(CONFIG_USB_SERIAL_MOS7720)              += mos7720.o
 obj-$(CONFIG_USB_SERIAL_MOS7840)               += mos7840.o
 obj-$(CONFIG_USB_SERIAL_MOTOROLA)              += moto_modem.o
 obj-$(CONFIG_USB_MDM6600_CDMA_MODEM)            += mdm6600_modem.o
+obj-$(CONFIG_USB_SERIAL_MOTO_FLASH_MODEM)      += moto_flashmdm.o
 obj-$(CONFIG_USB_SERIAL_NAVMAN)                        += navman.o
 obj-$(CONFIG_USB_SERIAL_OMNINET)               += omninet.o
 obj-$(CONFIG_USB_SERIAL_OPTICON)               += opticon.o
diff --git a/drivers/usb/serial/moto_flashmdm.c b/drivers/usb/serial/moto_flashmdm.c
new file mode 100644 (file)
index 0000000..ef60cce
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Motorola Modem flash mode driver
+ *
+ * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2009 Motorola, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+#include <linux/io.h>
+#include <mach/io.h>
+#if defined(CONFIG_ARCH_OMAP34XX)
+#include "../host/ehci-omap.h"
+#endif
+
+static struct usb_device_id id_table[] = {
+       {USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x2db4, 0x0a, 0, 0xfc)},
+       {},
+};
+
+MODULE_DEVICE_TABLE(usb, id_table);
+
+#define MOTO_FLASHMDM_BULKOUT_SIZE     8192
+
+#if defined(CONFIG_ARCH_OMAP34XX)
+/* disable the uhh_sysconfig auto idle bit,
+ * so that, host iclk will not be disabled and BP
+ * can re-enumerated on AP
+ */
+static void omap_flashmdm_disable_uhh_smart_idle(void)
+{
+       u32 sysconfig;
+
+       sysconfig = omap_readl(OMAP_UHH_SYSCONFIG);
+       sysconfig &= ~(1 << OMAP_UHH_SYSCONFIG_AUTOIDLE_SHIFT);
+       omap_writel(sysconfig, OMAP_UHH_SYSCONFIG);
+}
+#endif
+
+static int moto_flashmdm_attach(struct usb_serial *serial)
+{
+       struct usb_serial_port *port = serial->port[0];
+
+       if (port->bulk_out_size >= MOTO_FLASHMDM_BULKOUT_SIZE) {
+               dev_info(&serial->dev->dev,
+                        "bulk_out_size %d\n", port->bulk_out_size);
+               return 0;
+       }
+
+       kfree(port->bulk_out_buffer);
+       port->bulk_out_size = MOTO_FLASHMDM_BULKOUT_SIZE;
+       port->bulk_out_buffer = kmalloc(port->bulk_out_size, GFP_KERNEL);
+       if (!port->bulk_out_buffer) {
+               dev_err(&serial->dev->dev,
+                       "Couldn't allocate bulk_out_buffer\n");
+               return -ENOMEM;
+       }
+       usb_fill_bulk_urb(port->write_urb, serial->dev,
+                         usb_sndbulkpipe(serial->dev,
+                                         port->bulk_out_endpointAddress),
+                         port->bulk_out_buffer, port->bulk_out_size,
+                         usb_serial_generic_write_bulk_callback, port);
+
+#if defined(CONFIG_ARCH_OMAP34XX)
+       /* need to disable the AUTO IDLE for the usb iclk */
+       omap_flashmdm_disable_uhh_smart_idle();
+#endif
+
+       return 0;
+}
+
+static struct usb_driver moto_flashmdm_driver = {
+       .name = "moto-flashmdm",
+       .probe = usb_serial_probe,
+       .disconnect = usb_serial_disconnect,
+       .id_table = id_table,
+       .no_dynamic_id = 1,
+
+};
+
+static struct usb_serial_driver moto_flashmdm_device = {
+       .driver = {
+                  .owner = THIS_MODULE,
+                  .name = "moto-flashmdm",
+                  },
+       .id_table = id_table,
+       .num_ports = 1,
+       .attach = moto_flashmdm_attach,
+};
+
+static int __init moto_flashmdm_init(void)
+{
+       int retval;
+
+       retval = usb_serial_register(&moto_flashmdm_device);
+       if (retval)
+               return retval;
+       retval = usb_register(&moto_flashmdm_driver);
+       if (retval)
+               usb_serial_deregister(&moto_flashmdm_device);
+       return retval;
+}
+
+static void __exit moto_flashmdm_exit(void)
+{
+       usb_deregister(&moto_flashmdm_driver);
+       usb_serial_deregister(&moto_flashmdm_device);
+}
+
+module_init(moto_flashmdm_init);
+module_exit(moto_flashmdm_exit);
+MODULE_LICENSE("GPL");
+