[media] saa7164: add firmware debug message collection and procfs changes
authorSteven Toth <stoth@kernellabs.com>
Sat, 31 Jul 2010 19:08:52 +0000 (16:08 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 21 Oct 2010 09:55:08 +0000 (07:55 -0200)
Check for PROCFS and dynamically adjust code.
Cache some PCIe values in the device context.
Provide a mechanism to collect the debug messages
coming from the firmware.

Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/saa7164/saa7164-api.c
drivers/media/video/saa7164/saa7164-core.c
drivers/media/video/saa7164/saa7164-reg.h
drivers/media/video/saa7164/saa7164-types.h
drivers/media/video/saa7164/saa7164.h

index 814751d..01cf4ab 100644 (file)
 
 #include "saa7164.h"
 
+int saa7164_api_collect_debug(struct saa7164_dev *dev, struct seq_file *m)
+{
+       tmComResDebugGetData_t d;
+       u8 more = 255;
+       int ret;
+
+       dprintk(DBGLVL_API, "%s()\n", __func__);
+
+       while (more--) {
+
+               memset(&d, 0, sizeof(d));
+
+               ret = saa7164_cmd_send(dev, 0, GET_CUR,
+                       GET_DEBUG_DATA_CONTROL, sizeof(d), &d);
+               if (ret != SAA_OK) {
+                       printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+               }
+
+               if (d.dwResult != SAA_OK)
+                       break;
+
+               seq_printf(m, "%s", d.ucDebugData);
+
+       }
+
+       return 0;
+}
+
+int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
+{
+       tmComResDebugSetLevel_t lvl;
+       int ret;
+
+       dprintk(DBGLVL_API, "%s(level=%d)\n", __func__, level);
+
+       /* Retrieve current state */
+       ret = saa7164_cmd_send(dev, 0, GET_CUR,
+               SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
+       if (ret != SAA_OK) {
+               printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+       }
+       dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel);
+
+       lvl.dwDebugLevel = level;
+
+       /* set new state */
+       ret = saa7164_cmd_send(dev, 0, SET_CUR,
+               SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
+       if (ret != SAA_OK) {
+               printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+       }
+
+       return ret;
+}
+
 int saa7164_api_set_vbi_format(struct saa7164_port *port)
 {
        struct saa7164_dev *dev = port->dev;
        tmComResProbeCommit_t fmt, rsp;
        int ret;
 
-       dprintk(DBGLVL_API, "%s(nr=%d)\n", __func__, port->nr);
+       dprintk(DBGLVL_API, "%s(nr=%d, unitid=0x%x)\n", __func__,
+               port->nr, port->hwcfg.unitid);
 
        fmt.bmHint = 0;
        fmt.bFormatIndex = 1;
@@ -50,6 +106,8 @@ int saa7164_api_set_vbi_format(struct saa7164_port *port)
        } else {
                /* Compare requested vs received, should be same */
                if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) {
+                       dprintk(DBGLVL_API, "SET/PROBE Verified\n");
+
                        /* Ask the device to select the negotiated format */
                        ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
                                SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt);
@@ -63,9 +121,11 @@ int saa7164_api_set_vbi_format(struct saa7164_port *port)
                                printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n",
                                        __func__, ret);
 
-                       if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0)
+                       if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0) {
                                printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n",
                                        __func__, ret);
+                       } else
+                               dprintk(DBGLVL_API, "SET/COMMIT Verified\n");
 
                        dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
                        dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", rsp.bFormatIndex);
@@ -723,6 +783,25 @@ int saa7164_api_configure_port_vbi(struct saa7164_dev *dev,
        dprintk(DBGLVL_API, "    EndLine       = %d\n", fmt->EndLine);
        dprintk(DBGLVL_API, "    FieldRate     = %d\n", fmt->FieldRate);
        dprintk(DBGLVL_API, "    bNumLines     = %d\n", fmt->bNumLines);
+
+       /* Cache the hardware configuration in the port */
+
+       port->bufcounter = port->hwcfg.BARLocation;
+       port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
+       port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
+       port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
+       port->bufptr32l = port->hwcfg.BARLocation +
+               (4 * sizeof(u32)) +
+               (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
+       port->bufptr32h = port->hwcfg.BARLocation +
+               (4 * sizeof(u32)) +
+               (sizeof(u32) * port->hwcfg.buffercount);
+       port->bufptr64 = port->hwcfg.BARLocation +
+               (4 * sizeof(u32)) +
+               (sizeof(u32) * port->hwcfg.buffercount);
+       dprintk(DBGLVL_API, "   = port->hwcfg.BARLocation = 0x%x\n",
+               port->hwcfg.BARLocation);
+
        dprintk(DBGLVL_API, "   = VS_FORMAT_VBI (becomes dev->en[%d])\n",
                port->nr);
 
index 7901bb1..1071cc7 100644 (file)
@@ -30,6 +30,9 @@
 #include <linux/delay.h>
 #include <asm/div64.h>
 
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#endif
 #include "saa7164.h"
 
 MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
@@ -49,6 +52,10 @@ unsigned int saa_debug;
 module_param_named(debug, saa_debug, int, 0644);
 MODULE_PARM_DESC(debug, "enable debug messages");
 
+unsigned int fw_debug = 2;
+module_param(fw_debug, int, 0644);
+MODULE_PARM_DESC(fw_debug, "Firware debug level def:2");
+
 unsigned int encoder_buffers = SAA7164_MAX_ENCODER_BUFFERS;
 module_param(encoder_buffers, int, 0644);
 MODULE_PARM_DESC(encoder_buffers, "Total buffers in read queue 16-512 def:64");
@@ -1067,6 +1074,63 @@ static void saa7164_dev_unregister(struct saa7164_dev *dev)
        return;
 }
 
+#ifdef CONFIG_PROC_FS
+static int saa7164_proc_show(struct seq_file *m, void *v)
+{
+       struct saa7164_dev *dev;
+       tmComResBusInfo_t *b;
+       struct list_head *list;
+       int i, c;
+
+       if (saa7164_devcount == 0)
+               return 0;
+
+       list_for_each(list, &saa7164_devlist) {
+               dev = list_entry(list, struct saa7164_dev, devlist);
+               seq_printf(m, "%s = %p\n", dev->name, dev);
+
+               if (dev->board != SAA7164_BOARD_UNKNOWN) {
+                       seq_printf(m, "Firmware messages ----->\n");
+                       saa7164_api_collect_debug(dev, m);
+                       seq_printf(m, "<---- Firmware messages\n");
+               }
+
+               /* Lock the bus from any other access */
+               b = &dev->bus;
+               mutex_lock(&b->lock);
+
+
+               mutex_unlock(&b->lock);
+
+       }
+
+       return 0;
+}
+
+static int saa7164_proc_open(struct inode *inode, struct file *filp)
+{
+       return single_open(filp, saa7164_proc_show, NULL);
+}
+
+static struct file_operations saa7164_proc_fops = {
+       .open           = saa7164_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int saa7164_proc_create(void)
+{
+       struct proc_dir_entry *pe;
+
+       pe = proc_create("saa7164", S_IRUGO, NULL, &saa7164_proc_fops);
+       if (!pe)
+               return -ENOMEM;
+
+       return 0;
+}
+#endif
+
 static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
                                     const struct pci_device_id *pci_id)
 {
@@ -1226,7 +1290,7 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
                                        "vbi device\n", __func__);
                        }
                }
-
+               saa7164_api_set_debug(dev, fw_debug);
 
        } /* != BOARD_UNKNOWN */
        else
@@ -1255,6 +1319,9 @@ static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
 {
        struct saa7164_dev *dev = pci_get_drvdata(pci_dev);
 
+       if (dev->board != SAA7164_BOARD_UNKNOWN)
+               saa7164_api_set_debug(dev, 0x00);
+
        saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
                &dev->ports[ SAA7164_PORT_ENC1 ].irq_interval);
        saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
@@ -1334,11 +1401,18 @@ static struct pci_driver saa7164_pci_driver = {
 static int __init saa7164_init(void)
 {
        printk(KERN_INFO "saa7164 driver loaded\n");
+
+#ifdef CONFIG_PROC_FS
+       saa7164_proc_create();
+#endif
        return pci_register_driver(&saa7164_pci_driver);
 }
 
 static void __exit saa7164_fini(void)
 {
+#ifdef CONFIG_PROC_FS
+       remove_proc_entry("saa7164", NULL);
+#endif
        pci_unregister_driver(&saa7164_pci_driver);
 }
 
index b950f41..153da76 100644 (file)
 #define EU_AUDIO_FORMAT_CONTROL                0x0C
 #define EU_AUDIO_BIT_RATE_CONTROL      0x0D
 
+/* Firmware Debugging */
+#define SET_DEBUG_LEVEL_CONTROL        0x0B
+#define GET_DEBUG_DATA_CONTROL 0x0C
index cb051d5..3406a95 100644 (file)
@@ -434,3 +434,15 @@ typedef struct
        u8      bFormatIndex;
        u8      bFrameIndex;
 } __attribute__((packed)) tmComResProbeCommit_t;
+
+typedef struct
+{
+       u32     dwDebugLevel;
+} __attribute__((packed)) tmComResDebugSetLevel_t;
+
+typedef struct
+{
+       u32     dwResult;
+       u8      ucDebugData[256];
+} __attribute__((packed)) tmComResDebugGetData_t;
+
index 82ff561..e2de805 100644 (file)
@@ -541,6 +541,8 @@ int saa7164_api_set_audio_std(struct saa7164_port *port);
 int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect);
 int saa7164_api_get_videomux(struct saa7164_port *port);
 int saa7164_api_set_vbi_format(struct saa7164_port *port);
+int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level);
+int saa7164_api_collect_debug(struct saa7164_dev *dev, struct seq_file *m);
 
 /* ----------------------------------------------------------- */
 /* saa7164-cards.c                                             */