maru_codec : Fixed a bug when audio some codecs are decoded simultaneously.
authorKitae Kim <kt920.kim@samsung.com>
Mon, 17 Dec 2012 17:02:50 +0000 (02:02 +0900)
committerKitae Kim <kt920.kim@samsung.com>
Mon, 17 Dec 2012 17:11:18 +0000 (02:11 +0900)
Source cleanup and codec driver can get and set offset of device memory for audio type.

Signed-off-by: Kitae Kim <kt920.kim@samsung.com>
drivers/maru/maru_codec.c
package/changelog
package/pkginfo.manifest

index 2fa7b1b5e46bbb8ded1d53cfc87c498dd5951215..ec691faa17935ecb3543abfb2345c1fc8f32c036 100644 (file)
@@ -59,29 +59,32 @@ MODULE_LICENSE("GPL2");
 
 #define CODEC_IRQ 0x7f
 
-/* Clean up source. : _param, svcodec_param_offset, paramindex */
 struct codec_param {
        uint32_t api_index;
        uint32_t ctx_index;
+       uint32_t mem_index;
        uint32_t mmap_offset;
        uint32_t ret;
 };
 
 enum codec_io_cmd {
-       CODEC_API_INDEX = 0,
-       CODEC_QUERY_STATE,
-       CODEC_CONTEXT_INDEX,
-       CODEC_MMAP_OFFSET,
-       CODEC_FILE_INDEX,
-       CODEC_CLOSED,
+       CODEC_CMD_API_INDEX = 0,
+       CODEC_CMD_CONTEXT_INDEX,
+       CODEC_CMD_FILE_INDEX,
+       CODEC_CMD_DEVICE_MEM_OFFSET,
+       CODEC_CMD_GET_THREAD_STATE,
+       CODEC_CMD_GET_VERSION,
+       CODEC_CMD_GET_DEVICE_MEM,
+       CODEC_CMD_SET_DEVICE_MEM,
+       CODEC_CMD_GET_MMAP_OFFSET,
+       CODEC_CMD_SET_MMAP_OFFSET,
+       CODEC_CMD_RESET_CODEC_INFO,
 };
 
 enum codec_api_index {
        EMUL_AV_REGISTER_ALL = 1,
-       EMUL_AVCODEC_ALLOC_CONTEXT,
        EMUL_AVCODEC_OPEN,
        EMUL_AVCODEC_CLOSE,
-       EMUL_AV_FREE,
        EMUL_AVCODEC_FLUSH_BUFFERS,
        EMUL_AVCODEC_DECODE_VIDEO,
        EMUL_AVCODEC_ENCODE_VIDEO,
@@ -91,8 +94,7 @@ enum codec_api_index {
        EMUL_AV_PARSER_INIT,
        EMUL_AV_PARSER_PARSE,
        EMUL_AV_PARSER_CLOSE,
-       EMUL_GET_CODEC_VER = 50,
-       EMUL_LOCK_MEM_REGION,
+       EMUL_LOCK_MEM_REGION = 50,
        EMUL_UNLOCK_MEM_REGION,
 };
 
@@ -109,10 +111,10 @@ struct svcodec_device {
        resource_size_t mem_size;
 
        /* irq handler */
-       wait_queue_head_t codec_wq;
+       wait_queue_head_t codec_job_wq;
        spinlock_t lock;
-       int sleep_flag;
 
+       int codec_job_done;
        int availableMem;
 };
 
@@ -123,24 +125,34 @@ static long svcodec_ioctl(struct file *file,
                        unsigned int cmd,
                        unsigned long arg)
 {
+       long value;
+
        mutex_lock(&codec_mutex);
 
        if (cmd == EMUL_LOCK_MEM_REGION) {
-               if (svcodec->availableMem == 0)
+               if (svcodec->availableMem == 0) {
                        svcodec->availableMem = 1;
-               else
+               } else {
                        svcodec->availableMem = -1;
-
+               }
+               value = svcodec->availableMem;
        } else if (cmd == EMUL_UNLOCK_MEM_REGION) {
-               svcodec->availableMem = 0;
+               value = svcodec->availableMem = 0;
+       } else if (cmd == CODEC_CMD_GET_VERSION) {
+               value = readl(svcodec->ioaddr + cmd);
+       } else if (cmd == CODEC_CMD_GET_MMAP_OFFSET) {
+               value = readl(svcodec->ioaddr + cmd);
+               CODEC_LOG(KERN_DEBUG,
+                               "ioctl: get mmap offset: %d.\n", value);
        } else {
-               CODEC_LOG(KERN_ERR, "there is no command.\n");
+               CODEC_LOG(KERN_INFO,
+                               "ioctl: no command available.\n");
+               value = 0;
        }
 
-       if (copy_to_user((void *)arg,
-                       &svcodec->availableMem,
-                       sizeof(int)))
-               CODEC_LOG(KERN_ERR, "failed to copy data to user\n");
+       if (copy_to_user((void *)arg, &value, sizeof(int))) {
+               CODEC_LOG(KERN_ERR, "ioctl: failed to copy data to user\n");
+    }
 
        mutex_unlock(&codec_mutex);
 
@@ -164,29 +176,36 @@ static ssize_t svcodec_write(struct file *file, const char __user *buf,
 
        if (!svcodec) {
                CODEC_LOG(KERN_ERR, "failed to get codec device info\n");
+               mutex_unlock(&codec_mutex);
                return -EINVAL;
        }
 
-       if (copy_from_user(&paramInfo, buf, sizeof(struct codec_param)))
+       if (copy_from_user(&paramInfo, buf, sizeof(struct codec_param))) {
                CODEC_LOG(KERN_ERR,
                        "failed to get codec parameter info from user\n");
+               mutex_unlock(&codec_mutex);
+               return -EIO;
+       }
 
-       if (paramInfo.api_index == EMUL_AVCODEC_ALLOC_CONTEXT)
-               writel((uint32_t)file, svcodec->ioaddr + CODEC_FILE_INDEX);
+       if (paramInfo.api_index == EMUL_AVCODEC_OPEN) {
+               writel((uint32_t)file, svcodec->ioaddr + CODEC_CMD_FILE_INDEX);
+               writel((uint32_t)paramInfo.mem_index,
+                       svcodec->ioaddr + CODEC_CMD_SET_MMAP_OFFSET);
+       }
 
        writel((uint32_t)paramInfo.ctx_index,
-               svcodec->ioaddr + CODEC_CONTEXT_INDEX);
+               svcodec->ioaddr + CODEC_CMD_CONTEXT_INDEX);
        writel((uint32_t)paramInfo.mmap_offset,
-               svcodec->ioaddr + CODEC_MMAP_OFFSET);
+               svcodec->ioaddr + CODEC_CMD_DEVICE_MEM_OFFSET);
        writel((uint32_t)paramInfo.api_index,
-               svcodec->ioaddr + CODEC_API_INDEX);
+               svcodec->ioaddr + CODEC_CMD_API_INDEX);
 
        /* wait decoding or encoding job */
        if (paramInfo.api_index >= EMUL_AVCODEC_DECODE_VIDEO &&
                paramInfo.api_index <= EMUL_AVCODEC_ENCODE_AUDIO) {
-               wait_event_interruptible(svcodec->codec_wq,
-                                       svcodec->sleep_flag != 0);
-               svcodec->sleep_flag = 0;
+               wait_event_interruptible(svcodec->codec_job_wq,
+                                       svcodec->codec_job_done != 0);
+               svcodec->codec_job_done = 0;
        }
 
        mutex_unlock(&codec_mutex);
@@ -214,7 +233,7 @@ static int svcodec_mmap(struct file *file, struct vm_area_struct *vm)
                        size, vm->vm_page_prot);
        if (ret < 0) {
                CODEC_LOG(KERN_ERR, "failed to remap page range\n");
-               return -EAGAIN;
+               return ret;
        }
 
        vm->vm_flags |= VM_IO;
@@ -226,21 +245,18 @@ static int svcodec_mmap(struct file *file, struct vm_area_struct *vm)
 static irqreturn_t svcodec_irq_handler (int irq, void *dev_id)
 {
        struct svcodec_device *dev = (struct svcodec_device *)dev_id;
+       unsigned long flags = 0;
        int val = 0;
-       unsigned long flags;
-
-/*     spin_lock_irqsave(&dev->lock, flags); */
 
-       val = readl(dev->ioaddr + CODEC_QUERY_STATE);
+       val = readl(dev->ioaddr + CODEC_CMD_GET_THREAD_STATE);
        if (!(val & CODEC_IRQ)) {
-/*             spin_unlock_irqrestore(&dev->lock, flags); */
                return IRQ_NONE;
        }
 
        spin_lock_irqsave(&dev->lock, flags);
 
-       dev->sleep_flag = 1;
-       wake_up_interruptible(&dev->codec_wq);
+       dev->codec_job_done = 1;
+       wake_up_interruptible(&dev->codec_job_wq);
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
@@ -252,7 +268,7 @@ static int svcodec_open(struct inode *inode, struct file *file)
        mutex_lock(&codec_mutex);
        CODEC_LOG(KERN_DEBUG, "open! struct file:%p\n", file);
 
-       svcodec->sleep_flag = 0;
+       svcodec->codec_job_done = 0;
 
        /* register interrupt handler */
        if (request_irq(svcodec->dev->irq, svcodec_irq_handler,
@@ -279,8 +295,11 @@ static int svcodec_release(struct inode *inode, struct file *file)
        svcodec->availableMem = 0;
 
        /* notify closing codec device of qemu. */
-       if (file)
-               writel((uint32_t)file, svcodec->ioaddr + CODEC_CLOSED);
+       if (file) {
+               CODEC_LOG(KERN_DEBUG, "reset codec info.\n");
+               writel((uint32_t)file,
+                       svcodec->ioaddr + CODEC_CMD_RESET_CODEC_INFO);
+       }
 
        module_put(THIS_MODULE);
        mutex_unlock(&codec_mutex);
@@ -312,93 +331,77 @@ static int __devinit svcodec_probe(struct pci_dev *pci_dev,
        int ret;
 
        svcodec = kmalloc(sizeof(struct svcodec_device), GFP_KERNEL);
+       if (!svcodec) {
+               CODEC_LOG(KERN_ERR, "Failed to allocate memory for codec.\n");
+               return -EIO;
+       }
        memset(svcodec, 0x00, sizeof(struct svcodec_device));
+       svcodec->dev = pci_dev;
 
-       init_waitqueue_head(&svcodec->codec_wq);
+       init_waitqueue_head(&svcodec->codec_job_wq);
        spin_lock_init(&svcodec->lock);
 
-       svcodec->dev = pci_dev;
-
-       if (pci_enable_device(pci_dev)) {
+       if ((ret = pci_enable_device(pci_dev))) {
                CODEC_LOG(KERN_ERR, "pci_enable_device failed\n");
-               goto err_rel;
+               return ret;
        }
 
        pci_set_master(pci_dev);
 
        svcodec->mem_start = pci_resource_start(pci_dev, 0);
        svcodec->mem_size = pci_resource_len(pci_dev, 0);
-
        if (!svcodec->mem_start) {
                CODEC_LOG(KERN_ERR, "pci_resource_start failed\n");
-               goto err_out;
+               pci_disable_device(pci_dev);
+               return -ENODEV;
        }
 
        if (!request_mem_region(svcodec->mem_start,
                                svcodec->mem_size,
                                DEVICE_NAME)) {
                CODEC_LOG(KERN_ERR, "request_mem_region failed\n");
-               goto err_out;
+               pci_disable_device(pci_dev);
+               return -EINVAL;
        }
 
        svcodec->io_start = pci_resource_start(pci_dev, 1);
        svcodec->io_size = pci_resource_len(pci_dev, 1);
-
        if (!svcodec->io_start) {
                CODEC_LOG(KERN_ERR, "pci_resource_start failed\n");
-               goto err_mem_region;
+               release_mem_region(svcodec->mem_start, svcodec->mem_size);
+               pci_disable_device(pci_dev);
+               return -ENODEV;
        }
 
        if (!request_mem_region(svcodec->io_start,
                                svcodec->io_size,
                                DEVICE_NAME)) {
                CODEC_LOG(KERN_ERR, "request_io_region failed\n");
-               goto err_mem_region;
-       }
-
-#if 0
-       svcodec->memaddr = ioremap(svcodec->mem_start, svcodec->mem_size);
-       if (!svcodec->memaddr) {
-               CODEC_LOG(KERN_ERR, "[%s] : ioremap failed\n", __func__);
-               goto err_io_region;
+               release_mem_region(svcodec->mem_start, svcodec->mem_size);
+               pci_disable_device(pci_dev);
+               return -EINVAL;
        }
-#endif
 
        svcodec->ioaddr = ioremap_nocache(svcodec->io_start, svcodec->io_size);
        if (!svcodec->ioaddr) {
                CODEC_LOG(KERN_ERR, "ioremap failed\n");
-               goto err_io_region;
+               release_mem_region(svcodec->io_start, svcodec->io_size);
+               release_mem_region(svcodec->mem_start, svcodec->mem_size);
+               pci_disable_device(pci_dev);
+               return -EINVAL;
        }
 
-#if 0
-       /* register chrdev */
-       if (register_chrdev(CODEC_MAJOR, DEVICE_NAME, &svcodec_fops)) {
-               CODEC_LOG(KERN_ERR, "register_chrdev failed\n");
-               goto err_io_unmap;
-       }
-#endif
        ret = misc_register(&codec_dev);
        if (ret) {
                CODEC_LOG(KERN_ERR, "cannot register codec as misc\n");
-               goto err_io_unmap;
+               iounmap(svcodec->ioaddr);
+               release_mem_region(svcodec->io_start, svcodec->io_size);
+               release_mem_region(svcodec->mem_start, svcodec->mem_size);
+               pci_disable_device(pci_dev);
+               return ret;
        }
 
        return 0;
-
-err_io_unmap:
-       iounmap(svcodec->ioaddr);
-#if 0
-err_mem_unmap:
-       iounmap(svcodec->memaddr);
-#endif
-err_io_region:
-       release_mem_region(svcodec->io_start, svcodec->io_size);
-err_mem_region:
-       release_mem_region(svcodec->mem_start, svcodec->mem_size);
-err_out:
-       pci_disable_device(pci_dev);
-err_rel:
-       return -EIO;
 }
 
 static void __devinit svcodec_remove(struct pci_dev *pci_dev)
@@ -409,13 +412,6 @@ static void __devinit svcodec_remove(struct pci_dev *pci_dev)
                        svcodec->ioaddr = 0;
                }
 
-#if 0
-               if (svcodec->memaddr) {
-                       iounmap(svcodec->memaddr);
-                       svcodec->memaddr = 0;
-               }
-#endif
-
                if (svcodec->io_start) {
                        release_mem_region(svcodec->io_start,
                                        svcodec->io_size);
index 3f9dabd4e2bd274b16a64b770bb6e033ce688835..c3a9bb89119700ad7bc414b418cc88bfabc75958 100644 (file)
@@ -1,3 +1,7 @@
+* 1.4.10
+- Fixed a bug when audio some codecs are decoded simultaneously.
+- Source cleanup and codec driver can get and set offset of device memory for audio type.
+== Kitae Kim <kt920.kim@samsung.com> 2012-12-18
 * 1.4.5
 - Modified touchscreen range
 == GiWoong Kim <giwoong.kim@samsung.com> 2012-11-27
index af66509b7e2e22f04169432f44d7d949e51818d7..6af4be6b2bb0c3621cb32cf3a4eb4ed8f4c242a7 100644 (file)
@@ -1,4 +1,4 @@
-Version: 1.4.9
+Version: 1.4.10
 Maintainer: Yeong-Kyoon, Lee <yeongkyoon.lee@samsung.com>
 Source: emulator-kernel