]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/staging/nvec/nvec.c
staging: nvec: rework the nvec slave init
[mirror_ubuntu-artful-kernel.git] / drivers / staging / nvec / nvec.c
index 72258e8c64ca34e52192ce5900dc1423a4a7c938..6c6e39447a5ff5b0934aa80823400166574d0e8c 100644 (file)
@@ -1,13 +1,25 @@
-// #define DEBUG
-
-/* ToDo list (incomplete, unorderd)
-       - convert mouse, keyboard, and power to platform devices
-*/
+/*
+ * NVEC: NVIDIA compliant embedded controller interface
+ *
+ * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
+ *
+ * Authors:  Pierre-Hugues Husson <phhusson@free.fr>
+ *           Ilya Petrov <ilya.muromec@gmail.com>
+ *           Marc Dietrich <marvin24@gmx.de>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+/* #define DEBUG */
 
-#include <asm/io.h>
 #include <asm/irq.h>
+
 #include <linux/completion.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/input.h>
 #include <linux/workqueue.h>
 #include <linux/clk.h>
-#include <mach/iomap.h>
-#include <mach/clk.h>
+
 #include <linux/semaphore.h>
 #include <linux/list.h>
 #include <linux/notifier.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+
+#include <mach/iomap.h>
+#include <mach/clk.h>
+
 #include "nvec.h"
 
-static unsigned char EC_DISABLE_EVENT_REPORTING[] =    {'\x04','\x00','\x00'};
-static unsigned char EC_ENABLE_EVENT_REPORTING[] =     {'\x04','\x00','\x01'};
-static unsigned char EC_GET_FIRMWARE_VERSION[] =       {'\x07','\x15'};
+static const unsigned char EC_DISABLE_EVENT_REPORTING[3] = "\x04\x00\x00";
+static const unsigned char EC_ENABLE_EVENT_REPORTING[3]  = "\x04\x00\x01";
+static const unsigned char EC_GET_FIRMWARE_VERSION[2]    = "\x07\x15";
 
 static struct nvec_chip *nvec_power_handle;
 
+static struct mfd_cell nvec_devices[] = {
+       {
+               .name = "nvec-kbd",
+               .id = 1,
+       },
+       {
+               .name = "nvec-mouse",
+               .id = 1,
+       },
+       {
+               .name = "nvec-power",
+               .id = 1,
+       },
+       {
+               .name = "nvec-power",
+               .id = 2,
+       },
+};
+
 int nvec_register_notifier(struct nvec_chip *nvec, struct notifier_block *nb,
-                               unsigned int events)
+                          unsigned int events)
 {
        return atomic_notifier_chain_register(&nvec->notifier_list, nb);
 }
 EXPORT_SYMBOL_GPL(nvec_register_notifier);
 
-static int nvec_status_notifier(struct notifier_block *nb, unsigned long event_type,
-                               void *data)
+static int nvec_status_notifier(struct notifier_block *nb,
+                               unsigned long event_type, void *data)
 {
        unsigned char *msg = (unsigned char *)data;
-       int i;
 
-       if(event_type != NVEC_CNTL)
+       if (event_type != NVEC_CNTL)
                return NOTIFY_DONE;
 
-       printk("unhandled msg type %ld, payload: ", event_type);
-       for (i = 0; i < msg[1]; i++)
-               printk("%0x ", msg[i+2]);
-       printk("\n");
+       printk(KERN_WARNING "unhandled msg type %ld\n", event_type);
+       print_hex_dump(KERN_WARNING, "payload: ", DUMP_PREFIX_NONE, 16, 1,
+               msg, msg[1] + 2, true);
 
        return NOTIFY_OK;
 }
 
-void nvec_write_async(struct nvec_chip *nvec, unsigned char *data, short size)
+void nvec_write_async(struct nvec_chip *nvec, const unsigned char *data,
+                       short size)
 {
        struct nvec_msg *msg = kzalloc(sizeof(struct nvec_msg), GFP_NOWAIT);
 
@@ -75,42 +109,39 @@ static void nvec_request_master(struct work_struct *work)
 {
        struct nvec_chip *nvec = container_of(work, struct nvec_chip, tx_work);
 
-       if(!list_empty(&nvec->tx_data)) {
+       if (!list_empty(&nvec->tx_data))
                gpio_set_value(nvec->gpio, 0);
-       }
 }
 
 static int parse_msg(struct nvec_chip *nvec, struct nvec_msg *msg)
 {
-       int i;
-
-       if((msg->data[0] & 1<<7) == 0 && msg->data[3]) {
-               dev_err(nvec->dev, "ec responded %02x %02x %02x %02x\n", msg->data[0],
-                       msg->data[1], msg->data[2], msg->data[3]);
+       if ((msg->data[0] & 1 << 7) == 0 && msg->data[3]) {
+               dev_err(nvec->dev, "ec responded %02x %02x %02x %02x\n",
+                       msg->data[0], msg->data[1], msg->data[2], msg->data[3]);
                return -EINVAL;
        }
 
-       if ((msg->data[0] >> 7 ) == 1 && (msg->data[0] & 0x0f) == 5)
-       {
-               dev_warn(nvec->dev, "ec system event ");
-               for (i=0; i < msg->data[1]; i++)
-                       dev_warn(nvec->dev, "%02x ", msg->data[2+i]);
-               dev_warn(nvec->dev, "\n");
-       }
+       if ((msg->data[0] >> 7) == 1 && (msg->data[0] & 0x0f) == 5)
+               print_hex_dump(KERN_WARNING, "ec system event ",
+                               DUMP_PREFIX_NONE, 16, 1, msg->data,
+                               msg->data[1] + 2, true);
 
-       atomic_notifier_call_chain(&nvec->notifier_list, msg->data[0] & 0x8f, msg->data);
+       atomic_notifier_call_chain(&nvec->notifier_list, msg->data[0] & 0x8f,
+                                  msg->data);
 
        return 0;
 }
 
-static struct nvec_msg *nvec_write_sync(struct nvec_chip *nvec, unsigned char *data, short size)
+static struct nvec_msg *nvec_write_sync(struct nvec_chip *nvec,
+                                       const unsigned char *data, short size)
 {
        down(&nvec->sync_write_mutex);
 
        nvec->sync_write_pending = (data[1] << 8) + data[0];
        nvec_write_async(nvec, data, size);
 
-       dev_dbg(nvec->dev, "nvec_sync_write: 0x%04x\n", nvec->sync_write_pending);
+       dev_dbg(nvec->dev, "nvec_sync_write: 0x%04x\n",
+               nvec->sync_write_pending);
        wait_for_completion(&nvec->sync_write);
        dev_dbg(nvec->dev, "nvec_sync_write: pong!\n");
 
@@ -125,21 +156,21 @@ static void nvec_dispatch(struct work_struct *work)
        struct nvec_chip *nvec = container_of(work, struct nvec_chip, rx_work);
        struct nvec_msg *msg;
 
-       while(!list_empty(&nvec->rx_data))
-       {
+       while (!list_empty(&nvec->rx_data)) {
                msg = list_first_entry(&nvec->rx_data, struct nvec_msg, node);
                list_del_init(&msg->node);
 
-               if(nvec->sync_write_pending == (msg->data[2] << 8) + msg->data[0])
-               {
+               if (nvec->sync_write_pending ==
+                   (msg->data[2] << 8) + msg->data[0]) {
                        dev_dbg(nvec->dev, "sync write completed!\n");
                        nvec->sync_write_pending = 0;
                        nvec->last_sync_msg = msg;
                        complete(&nvec->sync_write);
                } else {
                        parse_msg(nvec, msg);
-                       if((!msg) || (!msg->data))
-                               dev_warn(nvec->dev, "attempt access zero pointer");
+                       if ((!msg) || (!msg->data))
+                               dev_warn(nvec->dev,
+                                       "attempt access zero pointer\n");
                        else {
                                kfree(msg->data);
                                kfree(msg);
@@ -148,31 +179,24 @@ static void nvec_dispatch(struct work_struct *work)
        }
 }
 
-static irqreturn_t i2c_interrupt(int irq, void *dev)
+static irqreturn_t nvec_interrupt(int irq, void *dev)
 {
        unsigned long status;
        unsigned long received;
        unsigned char to_send;
        struct nvec_msg *msg;
        struct nvec_chip *nvec = (struct nvec_chip *)dev;
-       unsigned char *i2c_regs = nvec->i2c_regs;
+       void __iomem *base = nvec->base;
 
-       status = readl(i2c_regs + I2C_SL_STATUS);
+       status = readl(base + I2C_SL_STATUS);
 
-       if(!(status & I2C_SL_IRQ))
-       {
+       if (!(status & I2C_SL_IRQ)) {
                dev_warn(nvec->dev, "nvec Spurious IRQ\n");
-               //Yup, handled. ahum.
                goto handled;
        }
-       if(status & END_TRANS && !(status & RCVD))
-       {
-               //Reenable IRQ only when even has been sent
-               //printk("Write sequence ended !\n");
-                //parse_msg(nvec);
+       if (status & END_TRANS && !(status & RCVD)) {
                nvec->state = NVEC_WAIT;
-               if(nvec->rx->size > 1)
-               {
+               if (nvec->rx->size > 1) {
                        list_add_tail(&nvec->rx->node, &nvec->rx_data);
                        schedule_work(&nvec->rx_work);
                } else {
@@ -180,41 +204,31 @@ static irqreturn_t i2c_interrupt(int irq, void *dev)
                        kfree(nvec->rx);
                }
                return IRQ_HANDLED;
-       } else if(status & RNW)
-       {
-               // Work around for AP20 New Slave Hw Bug. Give 1us extra.
-               // nvec/smbus/nvec_i2c_transport.c in NV`s crap for reference
-               if(status & RCVD)
+       } else if (status & RNW) {
+               if (status & RCVD)
                        udelay(3);
 
-               if(status & RCVD)
-               {
+               if (status & RCVD)
                        nvec->state = NVEC_WRITE;
-                       //Master wants something from us. New communication
-//                     dev_dbg(nvec->dev, "New read comm!\n");
-               } else {
-                       //Master wants something from us from a communication we've already started
-//                     dev_dbg(nvec->dev, "Read comm cont !\n");
-               }
-               //if(msg_pos<msg_size) {
-               if(list_empty(&nvec->tx_data))
-               {
+
+               if (list_empty(&nvec->tx_data)) {
                        dev_err(nvec->dev, "nvec empty tx - sending no-op\n");
                        to_send = 0x8a;
                        nvec_write_async(nvec, "\x07\x02", 2);
-//                     to_send = 0x01;
                } else {
-                       msg = list_first_entry(&nvec->tx_data, struct nvec_msg, node);
-                       if(msg->pos < msg->size) {
+                       msg =
+                           list_first_entry(&nvec->tx_data, struct nvec_msg,
+                                            node);
+                       if (msg->pos < msg->size) {
                                to_send = msg->data[msg->pos];
                                msg->pos++;
                        } else {
-                               dev_err(nvec->dev, "nvec crap! %d\n", msg->size);
+                               dev_err(nvec->dev, "nvec crap! %d\n",
+                                       msg->size);
                                to_send = 0x01;
                        }
 
-                       if(msg->pos >= msg->size)
-                       {
+                       if (msg->pos >= msg->size) {
                                list_del_init(&msg->node);
                                kfree(msg->data);
                                kfree(msg);
@@ -222,7 +236,7 @@ static irqreturn_t i2c_interrupt(int irq, void *dev)
                                nvec->state = NVEC_WAIT;
                        }
                }
-               writel(to_send, i2c_regs + I2C_SL_RCVD);
+               writel(to_send, base + I2C_SL_RCVD);
 
                gpio_set_value(nvec->gpio, 1);
 
@@ -230,15 +244,14 @@ static irqreturn_t i2c_interrupt(int irq, void *dev)
 
                goto handled;
        } else {
-               received = readl(i2c_regs + I2C_SL_RCVD);
-               //Workaround?
-               if(status & RCVD) {
-                       writel(0, i2c_regs + I2C_SL_RCVD);
+               received = readl(base + I2C_SL_RCVD);
+
+               if (status & RCVD) {
+                       writel(0, base + I2C_SL_RCVD);
                        goto handled;
                }
 
-               if (nvec->state == NVEC_WAIT)
-               {
+               if (nvec->state == NVEC_WAIT) {
                        nvec->state = NVEC_READ;
                        msg = kzalloc(sizeof(struct nvec_msg), GFP_NOWAIT);
                        msg->data = kzalloc(32, GFP_NOWAIT);
@@ -252,43 +265,45 @@ static irqreturn_t i2c_interrupt(int irq, void *dev)
                msg->data[msg->pos] = received;
                msg->pos++;
                msg->size = msg->pos;
-               dev_dbg(nvec->dev, "Got %02lx from Master (pos: %d)!\n", received, msg->pos);
+               dev_dbg(nvec->dev, "Got %02lx from Master (pos: %d)!\n",
+                       received, msg->pos);
        }
 handled:
        return IRQ_HANDLED;
 }
 
-static int __devinit nvec_add_subdev(struct nvec_chip *nvec, struct nvec_subdev *subdev)
+static void tegra_init_i2c_slave(struct nvec_chip *nvec)
 {
-       struct platform_device *pdev;
+       u32 val;
 
-       pdev = platform_device_alloc(subdev->name, subdev->id);
-       pdev->dev.parent = nvec->dev;
-       pdev->dev.platform_data = subdev->platform_data;
+       clk_enable(nvec->i2c_clk);
 
-       return platform_device_add(pdev);
-}
+       tegra_periph_reset_assert(nvec->i2c_clk);
+       udelay(2);
+       tegra_periph_reset_deassert(nvec->i2c_clk);
 
-static void tegra_init_i2c_slave(struct nvec_platform_data *pdata, unsigned char *i2c_regs,
-                                       struct clk *i2c_clk)
-{
-       u32 val;
+       val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN |
+           (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
+       writel(val, nvec->base + I2C_CNFG);
 
-       clk_enable(i2c_clk);
-       tegra_periph_reset_assert(i2c_clk);
-       udelay(2);
-       tegra_periph_reset_deassert(i2c_clk);
+       clk_set_rate(nvec->i2c_clk, 8 * 80000);
 
-       writel(pdata->i2c_addr>>1, i2c_regs + I2C_SL_ADDR1);
-       writel(0, i2c_regs + I2C_SL_ADDR2);
+       writel(I2C_SL_NEWL, nvec->base + I2C_SL_CNFG);
+       writel(0x1E, nvec->base + I2C_SL_DELAY_COUNT);
 
-       writel(0x1E, i2c_regs + I2C_SL_DELAY_COUNT);
-       val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN |
-               (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
-       writel(val, i2c_regs + I2C_CNFG);
-       writel(I2C_SL_NEWL, i2c_regs + I2C_SL_CNFG);
+       writel(nvec->i2c_addr>>1, nvec->base + I2C_SL_ADDR1);
+       writel(0, nvec->base + I2C_SL_ADDR2);
+
+       enable_irq(nvec->irq);
 
-       clk_disable(i2c_clk);
+       clk_disable(nvec->i2c_clk);
+}
+
+static void nvec_disable_i2c_slave(struct nvec_chip *nvec)
+{
+       disable_irq(nvec->irq);
+       writel(I2C_SL_NEWL | I2C_SL_NACK, nvec->base + I2C_SL_CNFG);
+       clk_disable(nvec->i2c_clk);
 }
 
 static void nvec_power_off(void)
@@ -299,64 +314,65 @@ static void nvec_power_off(void)
 
 static int __devinit tegra_nvec_probe(struct platform_device *pdev)
 {
-       int err, i, ret;
+       int err, ret;
        struct clk *i2c_clk;
        struct nvec_platform_data *pdata = pdev->dev.platform_data;
        struct nvec_chip *nvec;
        struct nvec_msg *msg;
-       unsigned char *i2c_regs;
+       struct resource *res;
+       struct resource *iomem;
+       void __iomem *base;
 
        nvec = kzalloc(sizeof(struct nvec_chip), GFP_KERNEL);
-       if(nvec == NULL) {
+       if (nvec == NULL) {
                dev_err(&pdev->dev, "failed to reserve memory\n");
                return -ENOMEM;
        }
        platform_set_drvdata(pdev, nvec);
        nvec->dev = &pdev->dev;
        nvec->gpio = pdata->gpio;
-       nvec->irq = pdata->irq;
+       nvec->i2c_addr = pdata->i2c_addr;
 
-/*
-       i2c_clk=clk_get_sys(NULL, "i2c");
-       if(IS_ERR_OR_NULL(i2c_clk))
-               printk(KERN_ERR"No such clock tegra-i2c.2\n");
-       else
-               clk_enable(i2c_clk);
-*/
-       i2c_regs = ioremap(pdata->base, pdata->size);
-       if(!i2c_regs) {
-               dev_err(nvec->dev, "failed to ioremap registers\n");
-               goto failed;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "no mem resource?\n");
+               return -ENODEV;
        }
 
-       nvec->i2c_regs = i2c_regs;
+       iomem = request_mem_region(res->start, resource_size(res), pdev->name);
+       if (!iomem) {
+               dev_err(&pdev->dev, "I2C region already claimed\n");
+               return -EBUSY;
+       }
 
-       i2c_clk = clk_get_sys(pdata->clock, NULL);
-       if(IS_ERR_OR_NULL(i2c_clk)) {
-               dev_err(nvec->dev, "failed to get clock tegra-i2c.2\n");
-               goto failed;
+       base = ioremap(iomem->start, resource_size(iomem));
+       if (!base) {
+               dev_err(&pdev->dev, "Can't ioremap I2C region\n");
+               return -ENOMEM;
        }
 
-       tegra_init_i2c_slave(pdata, i2c_regs, i2c_clk);
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "no irq resource?\n");
+               ret = -ENODEV;
+               goto err_iounmap;
+       }
 
-       err = request_irq(nvec->irq, i2c_interrupt, IRQF_DISABLED, "nvec", nvec);
-       if(err) {
-               dev_err(nvec->dev, "couldn't request irq");
-               goto failed;
+       i2c_clk = clk_get_sys("tegra-i2c.2", NULL);
+       if (IS_ERR(i2c_clk)) {
+               dev_err(nvec->dev, "failed to get controller clock\n");
+               goto err_iounmap;
        }
 
-       clk_enable(i2c_clk);
-       clk_set_rate(i2c_clk, 8*80000);
+       nvec->base = base;
+       nvec->irq = res->start;
+       nvec->i2c_clk = i2c_clk;
 
        /* Set the gpio to low when we've got something to say */
        err = gpio_request(nvec->gpio, "nvec gpio");
-       if(err < 0)
+       if (err < 0)
                dev_err(nvec->dev, "couldn't request gpio\n");
 
-       tegra_gpio_enable(nvec->gpio);
-       gpio_direction_output(nvec->gpio, 1);
-       gpio_set_value(nvec->gpio, 1);
-
        ATOMIC_INIT_NOTIFIER_HEAD(&nvec->notifier_list);
 
        init_completion(&nvec->sync_write);
@@ -366,19 +382,23 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev)
        INIT_WORK(&nvec->rx_work, nvec_dispatch);
        INIT_WORK(&nvec->tx_work, nvec_request_master);
 
-       /* enable event reporting */
-       nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING,
-                               sizeof(EC_ENABLE_EVENT_REPORTING));
+       err = request_irq(nvec->irq, nvec_interrupt, 0, "nvec", nvec);
+       if (err) {
+               dev_err(nvec->dev, "couldn't request irq\n");
+               goto failed;
+       }
+       disable_irq(nvec->irq);
 
-       nvec_kbd_init(nvec);
-#ifdef CONFIG_SERIO_NVEC_PS2
-       nvec_ps2(nvec);
-#endif
+       tegra_init_i2c_slave(nvec);
 
-        /* setup subdevs */
-       for (i = 0; i < pdata->num_subdevs; i++) {
-               ret = nvec_add_subdev(nvec, &pdata->subdevs[i]);
-       }
+       clk_enable(i2c_clk);
+
+       gpio_direction_output(nvec->gpio, 1);
+       gpio_set_value(nvec->gpio, 1);
+
+       /* enable event reporting */
+       nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING,
+                        sizeof(EC_ENABLE_EVENT_REPORTING));
 
        nvec->nvec_status_notifier.notifier_call = nvec_status_notifier;
        nvec_register_notifier(nvec, &nvec->nvec_status_notifier, 0);
@@ -388,14 +408,19 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev)
 
        /* Get Firmware Version */
        msg = nvec_write_sync(nvec, EC_GET_FIRMWARE_VERSION,
-               sizeof(EC_GET_FIRMWARE_VERSION));
+                             sizeof(EC_GET_FIRMWARE_VERSION));
 
        dev_warn(nvec->dev, "ec firmware version %02x.%02x.%02x / %02x\n",
-                       msg->data[4], msg->data[5], msg->data[6], msg->data[7]);
+                msg->data[4], msg->data[5], msg->data[6], msg->data[7]);
 
        kfree(msg->data);
        kfree(msg);
 
+       ret = mfd_add_devices(nvec->dev, -1, nvec_devices,
+                             ARRAY_SIZE(nvec_devices), base, 0);
+       if (ret)
+               dev_err(nvec->dev, "error adding subdevices\n");
+
        /* unmute speakers? */
        nvec_write_async(nvec, "\x0d\x10\x59\x94", 4);
 
@@ -407,6 +432,8 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev)
 
        return 0;
 
+err_iounmap:
+       iounmap(base);
 failed:
        kfree(nvec);
        return -ENOMEM;
@@ -414,7 +441,15 @@ failed:
 
 static int __devexit tegra_nvec_remove(struct platform_device *pdev)
 {
-       // TODO: unregister
+       struct nvec_chip *nvec = platform_get_drvdata(pdev);
+
+       nvec_write_async(nvec, EC_DISABLE_EVENT_REPORTING, 3);
+       mfd_remove_devices(nvec->dev);
+       free_irq(nvec->irq, &nvec_interrupt);
+       iounmap(nvec->base);
+       gpio_free(nvec->gpio);
+       kfree(nvec);
+
        return 0;
 }
 
@@ -427,15 +462,17 @@ static int tegra_nvec_suspend(struct platform_device *pdev, pm_message_t state)
        dev_dbg(nvec->dev, "suspending\n");
        nvec_write_async(nvec, EC_DISABLE_EVENT_REPORTING, 3);
        nvec_write_async(nvec, "\x04\x02", 2);
+       nvec_disable_i2c_slave(nvec);
 
        return 0;
 }
 
-static int tegra_nvec_resume(struct platform_device *pdev) {
-
+static int tegra_nvec_resume(struct platform_device *pdev)
+{
        struct nvec_chip *nvec = platform_get_drvdata(pdev);
 
        dev_dbg(nvec->dev, "resuming\n");
+       tegra_init_i2c_slave(nvec);
        nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING, 3);
 
        return 0;
@@ -446,13 +483,12 @@ static int tegra_nvec_resume(struct platform_device *pdev) {
 #define tegra_nvec_resume NULL
 #endif
 
-static struct platform_driver nvec_device_driver =
-{
-       .probe = tegra_nvec_probe,
-       .remove = __devexit_p(tegra_nvec_remove),
+static struct platform_driver nvec_device_driver = {
+       .probe   = tegra_nvec_probe,
+       .remove  = __devexit_p(tegra_nvec_remove),
        .suspend = tegra_nvec_suspend,
-       .resume = tegra_nvec_resume,
-       .driver = {
+       .resume  = tegra_nvec_resume,
+       .driver  = {
                .name = "nvec",
                .owner = THIS_MODULE,
        }
@@ -464,4 +500,8 @@ static int __init tegra_nvec_init(void)
 }
 
 module_init(tegra_nvec_init);
+
 MODULE_ALIAS("platform:nvec");
+MODULE_DESCRIPTION("NVIDIA compliant embedded controller interface");
+MODULE_AUTHOR("Marc Dietrich <marvin24@gmx.de>");
+MODULE_LICENSE("GPL");