123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749 |
- /*
- * Copyright (C) ST-Ericsson AP Pte Ltd 2010
- *
- * ISP1763 Linux HCD Controller driver : hal
- *
- * This program is free software; you can redistribute it and/or modify it under the terms of
- * the GNU General Public License as published by the Free Software Foundation; version
- * 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * This is the main hardware abstraction layer file. Hardware initialization, interupt
- * processing and read/write routines are handled here.
- *
- * Author : wired support <wired.support@stericsson.com>
- *
- */
- #include <linux/module.h>
- #include <linux/device.h>
- #include <linux/platform_device.h>
- #include <linux/kernel.h>
- #include <linux/delay.h>
- #include <linux/ioport.h>
- #include <linux/sched.h>
- #include <linux/completion.h>
- #include <linux/slab.h>
- #include <linux/smp_lock.h>
- #include <linux/errno.h>
- #include <linux/init.h>
- #include <linux/timer.h>
- #include <linux/list.h>
- #include <linux/interrupt.h>
- #include <linux/usb.h>
- #include <linux/gpio.h>
- #include <mach/board.h>
- #include <linux/poll.h>
- #include <asm/io.h>
- #include <asm/irq.h>
- #include <asm/system.h>
- #include <asm/unaligned.h>
- /*--------------------------------------------------------------*
- * linux system include files
- *--------------------------------------------------------------*/
- #include "hal_msm.h"
- #include "../hal/hal_intf.h"
- #include "../hal/isp1763.h"
- /*--------------------------------------------------------------*
- * Local variable Definitions
- *--------------------------------------------------------------*/
- struct isp1763_dev isp1763_loc_dev[ISP1763_LAST_DEV];
- /*--------------------------------------------------------------*
- * Local # Definitions
- *--------------------------------------------------------------*/
- #define PCI_ACCESS_RETRY_COUNT 20
- #define ISP1763_DRIVER_NAME "isp1763_usb"
- /*--------------------------------------------------------------*
- * Local Function
- *--------------------------------------------------------------*/
- static int __devexit isp1763_remove(struct platform_device *pdev);
- static int __devinit isp1763_probe(struct platform_device *pdev);
- /*--------------------------------------------------------------*
- * Platform Driver Interface Functions
- *--------------------------------------------------------------*/
- static struct platform_driver isp1763_usb_driver = {
- .remove = __exit_p(isp1763_remove),
- .driver = {
- .name = ISP1763_DRIVER_NAME,
- .owner = THIS_MODULE,
- },
- };
- /*--------------------------------------------------------------*
- * ISP1763 Read write routine
- *--------------------------------------------------------------*/
- /*
- * EBI2 on 8660 ignores the first bit and shifts the address by
- * one bit to the right.
- * Hence, shift left all the register addresses before accessing
- * them over EBI2.
- * This logic applies only for the register read/writes, for
- * read/write from ISP memory this conversion is not needed
- * as the ISP obtains the memory address from 'memory' register
- */
- /* Write a 32 bit Register of isp1763 */
- void
- isp1763_reg_write32(struct isp1763_dev *dev, u16 reg, u32 data)
- {
- /* Write the 32bit to the register address given to us */
- reg <<= 1;
- #ifdef DATABUS_WIDTH_16
- writew((u16) data, dev->baseaddress + ((reg)));
- writew((u16) (data >> 16), dev->baseaddress + (((reg + 4))));
- #else
- writeb((u8) data, dev->baseaddress + (reg));
- writeb((u8) (data >> 8), dev->baseaddress + ((reg + 1)));
- writeb((u8) (data >> 16), dev->baseaddress + ((reg + 2)));
- writeb((u8) (data >> 24), dev->baseaddress + ((reg + 3)));
- #endif
- }
- EXPORT_SYMBOL(isp1763_reg_write32);
- /* Read a 32 bit Register of isp1763 */
- u32
- isp1763_reg_read32(struct isp1763_dev *dev, u16 reg, u32 data)
- {
- #ifdef DATABUS_WIDTH_16
- u16 wvalue1, wvalue2;
- #else
- u8 bval1, bval2, bval3, bval4;
- #endif
- data = 0;
- reg <<= 1;
- #ifdef DATABUS_WIDTH_16
- wvalue1 = readw(dev->baseaddress + ((reg)));
- wvalue2 = readw(dev->baseaddress + (((reg + 4))));
- data |= wvalue2;
- data <<= 16;
- data |= wvalue1;
- #else
- bval1 = readb(dev->baseaddress + (reg));
- bval2 = readb(dev->baseaddress + (reg + 1));
- bval3 = readb(dev->baseaddress + (reg + 2));
- bval4 = readb(dev->baseaddress + (reg + 3));
- data = 0;
- data |= bval4;
- data <<= 8;
- data |= bval3;
- data <<= 8;
- data |= bval2;
- data <<= 8;
- data |= bval1;
- #endif
- return data;
- }
- EXPORT_SYMBOL(isp1763_reg_read32);
- /* Read a 16 bit Register of isp1763 */
- u16
- isp1763_reg_read16(struct isp1763_dev * dev, u16 reg, u16 data)
- {
- reg <<= 1;
- #ifdef DATABUS_WIDTH_16
- data = readw(dev->baseaddress + ((reg)));
- #else
- u8 bval1, bval2;
- bval1 = readb(dev->baseaddress + (reg));
- if (reg == HC_DATA_REG){
- bval2 = readb(dev->baseaddress + (reg));
- } else {
- bval2 = readb(dev->baseaddress + ((reg + 1)));
- }
- data = 0;
- data |= bval2;
- data <<= 8;
- data |= bval1;
- #endif
- return data;
- }
- EXPORT_SYMBOL(isp1763_reg_read16);
- /* Write a 16 bit Register of isp1763 */
- void
- isp1763_reg_write16(struct isp1763_dev *dev, u16 reg, u16 data)
- {
- reg <<= 1;
- #ifdef DATABUS_WIDTH_16
- writew(data, dev->baseaddress + ((reg)));
- #else
- writeb((u8) data, dev->baseaddress + (reg));
- if (reg == HC_DATA_REG){
- writeb((u8) (data >> 8), dev->baseaddress + (reg));
- }else{
- writeb((u8) (data >> 8), dev->baseaddress + ((reg + 1)));
- }
- #endif
- }
- EXPORT_SYMBOL(isp1763_reg_write16);
- /* Read a 8 bit Register of isp1763 */
- u8
- isp1763_reg_read8(struct isp1763_dev *dev, u16 reg, u8 data)
- {
- reg <<= 1;
- data = readb((dev->baseaddress + (reg)));
- return data;
- }
- EXPORT_SYMBOL(isp1763_reg_read8);
- /* Write a 8 bit Register of isp1763 */
- void
- isp1763_reg_write8(struct isp1763_dev *dev, u16 reg, u8 data)
- {
- reg <<= 1;
- writeb(data, (dev->baseaddress + (reg)));
- }
- EXPORT_SYMBOL(isp1763_reg_write8);
- /*--------------------------------------------------------------*
- *
- * Module dtatils: isp1763_mem_read
- *
- * Memory read using PIO method.
- *
- * Input: struct isp1763_driver *drv --> Driver structure.
- * u32 start_add --> Starting address of memory
- * u32 end_add ---> End address
- *
- * u32 * buffer --> Buffer pointer.
- * u32 length ---> Length
- * u16 dir ---> Direction ( Inc or Dec)
- *
- * Output int Length ----> Number of bytes read
- *
- * Called by: system function
- *
- *
- *--------------------------------------------------------------*/
- /* Memory read function PIO */
- int
- isp1763_mem_read(struct isp1763_dev *dev, u32 start_add,
- u32 end_add, u32 * buffer, u32 length, u16 dir)
- {
- u8 *one = (u8 *) buffer;
- u16 *two = (u16 *) buffer;
- u32 a = (u32) length;
- u32 w;
- u32 w2;
- if (buffer == 0) {
- printk("Buffer address zero\n");
- return 0;
- }
- isp1763_reg_write16(dev, HC_MEM_READ_REG, start_add);
- /* This delay requirement comes from the ISP1763A programming guide */
- ndelay(100);
- last:
- w = isp1763_reg_read16(dev, HC_DATA_REG, w);
- w2 = isp1763_reg_read16(dev, HC_DATA_REG, w);
- w2 <<= 16;
- w = w | w2;
- if (a == 1) {
- *one = (u8) w;
- return 0;
- }
- if (a == 2) {
- *two = (u16) w;
- return 0;
- }
- if (a == 3) {
- *two = (u16) w;
- two += 1;
- w >>= 16;
- *two = (u8) (w);
- return 0;
- }
- while (a > 0) {
- *buffer = w;
- a -= 4;
- if (a <= 0) {
- break;
- }
- if (a < 4) {
- buffer += 1;
- one = (u8 *) buffer;
- two = (u16 *) buffer;
- goto last;
- }
- buffer += 1;
- w = isp1763_reg_read16(dev, HC_DATA_REG, w);
- w2 = isp1763_reg_read16(dev, HC_DATA_REG, w);
- w2 <<= 16;
- w = w | w2;
- }
- return ((a < 0) || (a == 0)) ? 0 : (-1);
- }
- EXPORT_SYMBOL(isp1763_mem_read);
- /*--------------------------------------------------------------*
- *
- * Module dtatils: isp1763_mem_write
- *
- * Memory write using PIO method.
- *
- * Input: struct isp1763_driver *drv --> Driver structure.
- * u32 start_add --> Starting address of memory
- * u32 end_add ---> End address
- *
- * u32 * buffer --> Buffer pointer.
- * u32 length ---> Length
- * u16 dir ---> Direction ( Inc or Dec)
- *
- * Output int Length ----> Number of bytes read
- *
- * Called by: system function
- *
- *
- *--------------------------------------------------------------*/
- /* Memory read function IO */
- int
- isp1763_mem_write(struct isp1763_dev *dev,
- u32 start_add, u32 end_add, u32 * buffer, u32 length, u16 dir)
- {
- int a = length;
- u8 one = (u8) (*buffer);
- u16 two = (u16) (*buffer);
- isp1763_reg_write16(dev, HC_MEM_READ_REG, start_add);
- /* This delay requirement comes from the ISP1763A programming guide */
- ndelay(100);
- if (a == 1) {
- isp1763_reg_write16(dev, HC_DATA_REG, one);
- return 0;
- }
- if (a == 2) {
- isp1763_reg_write16(dev, HC_DATA_REG, two);
- return 0;
- }
- while (a > 0) {
- isp1763_reg_write16(dev, HC_DATA_REG, (u16) (*buffer));
- if (a >= 3)
- isp1763_reg_write16(dev, HC_DATA_REG,
- (u16) ((*buffer) >> 16));
- start_add += 4;
- a -= 4;
- if (a <= 0)
- break;
- buffer += 1;
- }
- return ((a < 0) || (a == 0)) ? 0 : (-1);
- }
- EXPORT_SYMBOL(isp1763_mem_write);
- /*--------------------------------------------------------------*
- *
- * Module dtatils: isp1763_register_driver
- *
- * This function is used by top driver (OTG, HCD, DCD) to register
- * their communication functions (probe, remove, suspend, resume) using
- * the drv data structure.
- * This function will call the probe function of the driver if the ISP1763
- * corresponding to the driver is enabled
- *
- * Input: struct isp1763_driver *drv --> Driver structure.
- * Output result
- * 0= complete
- * 1= error.
- *
- * Called by: system function module_init
- *
- *
- *--------------------------------------------------------------*/
- int
- isp1763_register_driver(struct isp1763_driver *drv)
- {
- struct isp1763_dev *dev;
- int result = -EINVAL;
- hal_entry("%s: Entered\n", __FUNCTION__);
- info("isp1763_register_driver(drv=%pK)\n", drv);
- if (!drv) {
- return -EINVAL;
- }
- dev = &isp1763_loc_dev[drv->index];
- if (!dev->baseaddress)
- return -EINVAL;
- dev->active = 1; /* set the driver as active*/
- if (drv->probe) {
- result = drv->probe(dev, drv->id);
- } else {
- printk("%s no probe function for indes %d \n", __FUNCTION__,
- (int)drv->index);
- }
- if (result >= 0) {
- pr_debug(KERN_INFO __FILE__ ": Registered Driver %s\n",
- drv->name);
- dev->driver = drv;
- }
- hal_entry("%s: Exit\n", __FUNCTION__);
- return result;
- } /* End of isp1763_register_driver */
- EXPORT_SYMBOL(isp1763_register_driver);
- /*--------------------------------------------------------------*
- *
- * Module dtatils: isp1763_unregister_driver
- *
- * This function is used by top driver (OTG, HCD, DCD) to de-register
- * their communication functions (probe, remove, suspend, resume) using
- * the drv data structure.
- * This function will check whether the driver is registered or not and
- * call the remove function of the driver if registered
- *
- * Input: struct isp1763_driver *drv --> Driver structure.
- * Output result
- * 0= complete
- * 1= error.
- *
- * Called by: system function module_init
- *
- *
- *--------------------------------------------------------------*/
- void
- isp1763_unregister_driver(struct isp1763_driver *drv)
- {
- struct isp1763_dev *dev;
- hal_entry("%s: Entered\n", __FUNCTION__);
- info("isp1763_unregister_driver(drv=%pK)\n", drv);
- dev = &isp1763_loc_dev[drv->index];
- if (dev->driver == drv) {
- /* driver registered is same as the requestig driver */
- drv->remove(dev);
- dev->driver = NULL;
- info(": De-registered Driver %s\n", drv->name);
- return;
- }
- hal_entry("%s: Exit\n", __FUNCTION__);
- } /* End of isp1763_unregister_driver */
- EXPORT_SYMBOL(isp1763_unregister_driver);
- /*--------------------------------------------------------------*
- * ISP1763 Platform driver interface routine.
- *--------------------------------------------------------------*/
- /*--------------------------------------------------------------*
- *
- * Module dtatils: isp1763_module_init
- *
- * This is the module initialization function. It registers to
- * driver for a isp1763 platform device. And also resets the
- * internal data structures.
- *
- * Input: void
- * Output result
- * 0= complete
- * 1= error.
- *
- * Called by: system function module_init
- *
- *
- *
- -------------------------------------------------------------------*/
- static int __init
- isp1763_module_init(void)
- {
- int result = 0;
- hal_entry("%s: Entered\n", __FUNCTION__);
- pr_debug(KERN_NOTICE "+isp1763_module_init\n");
- memset(isp1763_loc_dev, 0, sizeof(isp1763_loc_dev));
- result = platform_driver_probe(&isp1763_usb_driver, isp1763_probe);
- pr_debug(KERN_NOTICE "-isp1763_module_init\n");
- hal_entry("%s: Exit\n", __FUNCTION__);
- return result;
- }
- /*--------------------------------------------------------------*
- *
- * Module dtatils: isp1763_module_cleanup
- *
- * This is the module cleanup function. It de-registers the
- * Platform driver and resets the internal data structures.
- *
- * Input: void
- * Output void
- *
- * Called by: system function module_cleanup
- *
- *
- *
- --------------------------------------------------------------*/
- static void __exit
- isp1763_module_cleanup(void)
- {
- pr_debug("Hal Module Cleanup\n");
- platform_driver_unregister(&isp1763_usb_driver);
- memset(isp1763_loc_dev, 0, sizeof(isp1763_loc_dev));
- }
- void dummy_mem_read(struct isp1763_dev *dev)
- {
- u32 w = 0;
- isp1763_reg_write16(dev, HC_MEM_READ_REG, 0x0400);
- w = isp1763_reg_read16(dev, HC_DATA_REG, w);
- pr_debug("dummy_read DONE: %x\n", w);
- msleep(10);
- }
- /*--------------------------------------------------------------*
- *
- * Module dtatils: isp1763_probe
- *
- * probe function of ISP1763
- * This function is called from module_init if the corresponding platform
- * device is present. This function initializes the information
- * for the Host Controller with the assigned resources and tests the register
- * access to the controller and do a software reset and makes it ready
- * for the driver to play with. It also calls setup_gpio passed from pdata
- * to setup GPIOs (e.g. used for IRQ and RST lines).
- *
- * Input:
- * struct platform_device *dev ----> Platform Device structure
- * Output void
- *
- * Called by: system function module_cleanup
- *
- *
- *
- --------------------------------------------------------------**/
- static int __devinit
- isp1763_probe(struct platform_device *pdev)
- {
- u32 reg_data = 0;
- struct isp1763_dev *loc_dev;
- int status = 1;
- u32 hwmodectrl = 0;
- u16 us_reset_hc = 0;
- u32 chipid = 0;
- struct isp1763_platform_data *pdata = pdev->dev.platform_data;
- hal_entry("%s: Entered\n", __FUNCTION__);
- hal_init(("isp1763_probe(dev=%pK)\n", dev));
- loc_dev = &(isp1763_loc_dev[ISP1763_HC]);
- loc_dev->dev = pdev;
- /* Get the Host Controller IO and INT resources */
- loc_dev->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!loc_dev->mem_res) {
- pr_err("%s: failed to get platform resource mem\n", __func__);
- return -ENODEV;
- }
- loc_dev->baseaddress = ioremap_nocache(loc_dev->mem_res->start,
- resource_size(loc_dev->mem_res));
- if (!loc_dev->baseaddress) {
- pr_err("%s: ioremap failed\n", __func__);
- status = -ENOMEM;
- goto put_mem_res;
- }
- pr_info("%s: ioremap done at: %x\n", __func__,
- (int)loc_dev->baseaddress);
- loc_dev->irq = platform_get_irq(pdev, 0);
- if (!loc_dev->irq) {
- pr_err("%s: platform_get_irq failed\n", __func__);
- status = -ENODEV;
- goto free_regs;
- }
- loc_dev->index = ISP1763_HC; /*zero */
- loc_dev->length = resource_size(loc_dev->mem_res);
- hal_init(("isp1763 HC MEM Base= %pK irq = %d\n",
- loc_dev->baseaddress, loc_dev->irq));
- /* Setup GPIOs and isssue RESET_N to Controller */
- if (pdata->setup_gpio)
- if (pdata->setup_gpio(1))
- pr_err("%s: Failed to setup GPIOs for isp1763\n",
- __func__);
- if (pdata->reset_gpio) {
- gpio_set_value(pdata->reset_gpio, 0);
- msleep(10);
- gpio_set_value(pdata->reset_gpio, 1);
- } else {
- pr_err("%s: Failed to issue RESET_N to isp1763\n", __func__);
- }
- dummy_mem_read(loc_dev);
- chipid = isp1763_reg_read32(loc_dev, DC_CHIPID, chipid);
- pr_info("START: chip id:%x\n", chipid);
- /*reset the host controller */
- pr_debug("RESETTING\n");
- us_reset_hc |= 0x1;
- isp1763_reg_write16(loc_dev, 0xB8, us_reset_hc);
- msleep(20);
- us_reset_hc = 0;
- us_reset_hc |= 0x2;
- isp1763_reg_write16(loc_dev, 0xB8, us_reset_hc);
- chipid = isp1763_reg_read32(loc_dev, DC_CHIPID, chipid);
- pr_info("after HC reset, chipid:%x\n", chipid);
- msleep(20);
- hwmodectrl = isp1763_reg_read16(loc_dev, HC_HWMODECTRL_REG, hwmodectrl);
- pr_debug("Mode Ctrl Value b4 setting buswidth: %x\n", hwmodectrl);
- #ifdef DATABUS_WIDTH_16
- hwmodectrl &= 0xFFEF; /*enable the 16 bit bus */
- #else
- pr_debug("Setting 8-BIT mode\n");
- hwmodectrl |= 0x0010; /*enable the 8 bit bus */
- #endif
- isp1763_reg_write16(loc_dev, HC_HWMODECTRL_REG, hwmodectrl);
- pr_debug("writing 0x%x to hw mode reg\n", hwmodectrl);
- hwmodectrl = isp1763_reg_read16(loc_dev, HC_HWMODECTRL_REG, hwmodectrl);
- msleep(100);
- pr_debug("Mode Ctrl Value after setting buswidth: %x\n", hwmodectrl);
- chipid = isp1763_reg_read32(loc_dev, DC_CHIPID, chipid);
- pr_debug("after setting HW MODE to 8bit, chipid:%x\n", chipid);
- hal_init(("isp1763 DC MEM Base= %lx irq = %d\n",
- loc_dev->io_base, loc_dev->irq));
- reg_data = isp1763_reg_read16(loc_dev, HC_SCRATCH_REG, reg_data);
- pr_debug("Scratch register is 0x%x\n", reg_data);
- reg_data = 0xABCD;
- isp1763_reg_write16(loc_dev, HC_SCRATCH_REG, reg_data);
- reg_data = isp1763_reg_read16(loc_dev, HC_SCRATCH_REG, reg_data);
- pr_debug("After write, Scratch register is 0x%x\n", reg_data);
- if (reg_data != 0xABCD) {
- pr_err("%s: Scratch register write mismatch!!\n", __func__);
- status = -ENODEV;
- goto free_gpios;
- }
- memcpy(loc_dev->name, ISP1763_DRIVER_NAME, sizeof(ISP1763_DRIVER_NAME));
- loc_dev->name[sizeof(ISP1763_DRIVER_NAME)] = 0;
- pr_debug(KERN_NOTICE "-isp1763_pci_probe\n");
- hal_entry("%s: Exit\n", __FUNCTION__);
- return 0;
- free_gpios:
- if (pdata->setup_gpio)
- pdata->setup_gpio(0);
- free_regs:
- iounmap(loc_dev->baseaddress);
- put_mem_res:
- loc_dev->baseaddress = NULL;
- hal_entry("%s: Exit\n", __FUNCTION__);
- return status;
- } /* End of isp1763_probe */
- /*--------------------------------------------------------------*
- *
- * Module details: isp1763_remove
- *
- * cleanup function of ISP1763
- * This functions de-initializes the local variables, frees GPIOs
- * and releases memory resource.
- *
- * Input:
- * struct platform_device *dev ----> Platform Device structure
- *
- * Output void
- *
- * Called by: system function module_cleanup
- *
- *
- *
- --------------------------------------------------------------*/
- static int __devexit
- isp1763_remove(struct platform_device *pdev)
- {
- struct isp1763_dev *loc_dev;
- struct isp1763_platform_data *pdata = pdev->dev.platform_data;
- hal_init(("isp1763_pci_remove(dev=%pK)\n", dev));
- loc_dev = &isp1763_loc_dev[ISP1763_HC];
- iounmap(loc_dev->baseaddress);
- loc_dev->baseaddress = NULL;
- if (pdata->setup_gpio)
- return pdata->setup_gpio(0);
- return 0;
- } /* End of isp1763_remove */
- MODULE_AUTHOR(DRIVER_AUTHOR);
- MODULE_DESCRIPTION(DRIVER_DESC);
- MODULE_LICENSE("GPL");
- module_init(isp1763_module_init);
- module_exit(isp1763_module_cleanup);
|