[media] saa7164: add firmware debug message collection and procfs changes
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>
This commit is contained in:
parent
e8ce2f2166
commit
e48836b8bd
|
@ -24,13 +24,69 @@
|
||||||
|
|
||||||
#include "saa7164.h"
|
#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)
|
int saa7164_api_set_vbi_format(struct saa7164_port *port)
|
||||||
{
|
{
|
||||||
struct saa7164_dev *dev = port->dev;
|
struct saa7164_dev *dev = port->dev;
|
||||||
tmComResProbeCommit_t fmt, rsp;
|
tmComResProbeCommit_t fmt, rsp;
|
||||||
int ret;
|
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.bmHint = 0;
|
||||||
fmt.bFormatIndex = 1;
|
fmt.bFormatIndex = 1;
|
||||||
|
@ -50,6 +106,8 @@ int saa7164_api_set_vbi_format(struct saa7164_port *port)
|
||||||
} else {
|
} else {
|
||||||
/* Compare requested vs received, should be same */
|
/* Compare requested vs received, should be same */
|
||||||
if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) {
|
if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) {
|
||||||
|
dprintk(DBGLVL_API, "SET/PROBE Verified\n");
|
||||||
|
|
||||||
/* Ask the device to select the negotiated format */
|
/* Ask the device to select the negotiated format */
|
||||||
ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
|
ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
|
||||||
SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt);
|
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",
|
printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n",
|
||||||
__func__, ret);
|
__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",
|
printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n",
|
||||||
__func__, ret);
|
__func__, ret);
|
||||||
|
} else
|
||||||
|
dprintk(DBGLVL_API, "SET/COMMIT Verified\n");
|
||||||
|
|
||||||
dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
|
dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
|
||||||
dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", rsp.bFormatIndex);
|
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, " EndLine = %d\n", fmt->EndLine);
|
||||||
dprintk(DBGLVL_API, " FieldRate = %d\n", fmt->FieldRate);
|
dprintk(DBGLVL_API, " FieldRate = %d\n", fmt->FieldRate);
|
||||||
dprintk(DBGLVL_API, " bNumLines = %d\n", fmt->bNumLines);
|
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",
|
dprintk(DBGLVL_API, " = VS_FORMAT_VBI (becomes dev->en[%d])\n",
|
||||||
port->nr);
|
port->nr);
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <asm/div64.h>
|
#include <asm/div64.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_PROC_FS
|
||||||
|
#include <linux/proc_fs.h>
|
||||||
|
#endif
|
||||||
#include "saa7164.h"
|
#include "saa7164.h"
|
||||||
|
|
||||||
MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
|
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_param_named(debug, saa_debug, int, 0644);
|
||||||
MODULE_PARM_DESC(debug, "enable debug messages");
|
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;
|
unsigned int encoder_buffers = SAA7164_MAX_ENCODER_BUFFERS;
|
||||||
module_param(encoder_buffers, int, 0644);
|
module_param(encoder_buffers, int, 0644);
|
||||||
MODULE_PARM_DESC(encoder_buffers, "Total buffers in read queue 16-512 def:64");
|
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;
|
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,
|
static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
|
||||||
const struct pci_device_id *pci_id)
|
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__);
|
"vbi device\n", __func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
saa7164_api_set_debug(dev, fw_debug);
|
||||||
|
|
||||||
} /* != BOARD_UNKNOWN */
|
} /* != BOARD_UNKNOWN */
|
||||||
else
|
else
|
||||||
|
@ -1255,6 +1319,9 @@ static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
|
||||||
{
|
{
|
||||||
struct saa7164_dev *dev = pci_get_drvdata(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 ],
|
saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
|
||||||
&dev->ports[ SAA7164_PORT_ENC1 ].irq_interval);
|
&dev->ports[ SAA7164_PORT_ENC1 ].irq_interval);
|
||||||
saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
|
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)
|
static int __init saa7164_init(void)
|
||||||
{
|
{
|
||||||
printk(KERN_INFO "saa7164 driver loaded\n");
|
printk(KERN_INFO "saa7164 driver loaded\n");
|
||||||
|
|
||||||
|
#ifdef CONFIG_PROC_FS
|
||||||
|
saa7164_proc_create();
|
||||||
|
#endif
|
||||||
return pci_register_driver(&saa7164_pci_driver);
|
return pci_register_driver(&saa7164_pci_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit saa7164_fini(void)
|
static void __exit saa7164_fini(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_PROC_FS
|
||||||
|
remove_proc_entry("saa7164", NULL);
|
||||||
|
#endif
|
||||||
pci_unregister_driver(&saa7164_pci_driver);
|
pci_unregister_driver(&saa7164_pci_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -213,3 +213,6 @@
|
||||||
#define EU_AUDIO_FORMAT_CONTROL 0x0C
|
#define EU_AUDIO_FORMAT_CONTROL 0x0C
|
||||||
#define EU_AUDIO_BIT_RATE_CONTROL 0x0D
|
#define EU_AUDIO_BIT_RATE_CONTROL 0x0D
|
||||||
|
|
||||||
|
/* Firmware Debugging */
|
||||||
|
#define SET_DEBUG_LEVEL_CONTROL 0x0B
|
||||||
|
#define GET_DEBUG_DATA_CONTROL 0x0C
|
||||||
|
|
|
@ -434,3 +434,15 @@ typedef struct
|
||||||
u8 bFormatIndex;
|
u8 bFormatIndex;
|
||||||
u8 bFrameIndex;
|
u8 bFrameIndex;
|
||||||
} __attribute__((packed)) tmComResProbeCommit_t;
|
} __attribute__((packed)) tmComResProbeCommit_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 dwDebugLevel;
|
||||||
|
} __attribute__((packed)) tmComResDebugSetLevel_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 dwResult;
|
||||||
|
u8 ucDebugData[256];
|
||||||
|
} __attribute__((packed)) tmComResDebugGetData_t;
|
||||||
|
|
||||||
|
|
|
@ -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_set_audio_detection(struct saa7164_port *port, int autodetect);
|
||||||
int saa7164_api_get_videomux(struct saa7164_port *port);
|
int saa7164_api_get_videomux(struct saa7164_port *port);
|
||||||
int saa7164_api_set_vbi_format(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 */
|
/* saa7164-cards.c */
|
||||||
|
|
Loading…
Reference in New Issue