Skip to content

Commit

Permalink
[media] saa7164: add firmware debug message collection and procfs cha…
Browse files Browse the repository at this point in the history
…nges

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>
  • Loading branch information
Steven Toth authored and Mauro Carvalho Chehab committed Oct 21, 2010
1 parent e8ce2f2 commit e48836b
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 3 deletions.
83 changes: 81 additions & 2 deletions drivers/media/video/saa7164/saa7164-api.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,69 @@

#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;
Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);

Expand Down
76 changes: 75 additions & 1 deletion drivers/media/video/saa7164/saa7164-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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");
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 ],
Expand Down Expand Up @@ -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);
}

Expand Down
3 changes: 3 additions & 0 deletions drivers/media/video/saa7164/saa7164-reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,6 @@
#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
12 changes: 12 additions & 0 deletions drivers/media/video/saa7164/saa7164-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

2 changes: 2 additions & 0 deletions drivers/media/video/saa7164/saa7164.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit e48836b

Please sign in to comment.