From e07b2757953538741b1de83edf933b5636357f2e Mon Sep 17 00:00:00 2001 From: Kazuhiro Ondo Date: Thu, 22 Jul 2010 11:57:32 -0500 Subject: [PATCH] Motorola USB flash mode driver. Change-Id: Idf72cbceeff56523be443013c5cbda79ea829994 --- drivers/usb/serial/Kconfig | 9 +++ drivers/usb/serial/Makefile | 1 + drivers/usb/serial/moto_flashmdm.c | 123 +++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 drivers/usb/serial/moto_flashmdm.c diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 8547d3e5d497..22e2552a9b60 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -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 diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 5b50ed1d9dfe..fb818a50c189 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -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 index 000000000000..ef60cce19b51 --- /dev/null +++ b/drivers/usb/serial/moto_flashmdm.c @@ -0,0 +1,123 @@ +/* + * Motorola Modem flash mode driver + * + * Copyright (C) 2008 Greg Kroah-Hartman + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#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"); + -- 2.34.1