blob: 9287aa2919edc058507af20ca16843b255afd38f [file] [log] [blame]
#include <linux/config.h>
#include <linux/ctype.h>
struct procfs_params_zr36067 {
char *name;
short reg;
u32 mask;
short bit;
};
static struct procfs_params_zr36067 zr67[] = {
{"HSPol", 0x000, 1, 30},
{"HStart", 0x000, 0x3ff, 10},
{"HEnd", 0x000, 0x3ff, 0},
{"VSPol", 0x004, 1, 30},
{"VStart", 0x004, 0x3ff, 10},
{"VEnd", 0x004, 0x3ff, 0},
{"ExtFl", 0x008, 1, 26},
{"TopField", 0x008, 1, 25},
{"VCLKPol", 0x008, 1, 24},
{"DupFld", 0x008, 1, 20},
{"LittleEndian", 0x008, 1, 0},
{"HsyncStart", 0x10c, 0xffff, 16},
{"LineTot", 0x10c, 0xffff, 0},
{"NAX", 0x110, 0xffff, 16},
{"PAX", 0x110, 0xffff, 0},
{"NAY", 0x114, 0xffff, 16},
{"PAY", 0x114, 0xffff, 0},
/* {"",,,}, */
{NULL, 0, 0, 0},
};
static void setparam(struct zoran *zr, char *name, char *sval)
{
int i, reg0, reg, val;
i = 0;
while (zr67[i].name != NULL) {
if (!strncmp(name, zr67[i].name, strlen(zr67[i].name))) {
reg = reg0 = btread(zr67[i].reg);
reg &= ~(zr67[i].mask << zr67[i].bit);
if (!isdigit(sval[0]))
break;
val = simple_strtoul(sval, NULL, 0);
if ((val & ~zr67[i].mask))
break;
reg |= (val & zr67[i].mask) << zr67[i].bit;
printk(KERN_INFO "%s: setparam: setting ZR36067 register 0x%03x: 0x%08x=>0x%08x %s=%d\n",
zr->name, zr67[i].reg, reg0, reg, zr67[i].name, val);
btwrite(reg, zr67[i].reg);
break;
}
i++;
}
}
/* This macro was stolen from /usr/src/drivers/char/nvram.c and modified */
#define PRINT_PROC(args...) \
do { \
if (begin + len > offset + size) { \
*eof = 0; \
break; \
} \
len += sprintf( buffer+len, ##args ); \
if (begin + len < offset) { \
begin += len; \
len = 0; \
} \
} while(0)
static int zoran_read_proc(char *buffer, char **start, off_t offset, int size, int *eof, void *data)
{
#ifdef CONFIG_PROC_FS
int len = 0;
off_t begin = 0;
int i;
struct zoran *zr;
zr = (struct zoran *) data;
DEBUG2(printk(KERN_INFO "%s: read_proc: buffer=%x, offset=%d, size=%d, data=%x\n", zr->name, (int) buffer, (int) offset, size, (int) data));
*eof = 1;
PRINT_PROC("ZR36067 registers:");
for (i = 0; i < 0x130; i += 4) {
if (!(i % 16)) {
PRINT_PROC("\n%03X", i);
}
PRINT_PROC(" %08X ", btread(i));
}
PRINT_PROC("\n");
if (offset >= len + begin) {
return 0;
}
*start = buffer + begin - offset;
return ((size < begin + len - offset) ? size : begin + len - offset);
#endif
return 0;
}
static int zoran_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
{
#ifdef CONFIG_PROC_FS
char *string, *sp;
char *line, *ldelim, *varname, *svar, *tdelim;
struct zoran *zr;
zr = (struct zoran *) data;
string = sp = vmalloc(count + 1);
if (!string) {
printk(KERN_ERR "%s: write_proc: can not allocate memory\n", zr->name);
return -ENOMEM;
}
memcpy(string, buffer, count);
string[count] = 0;
DEBUG2(printk(KERN_INFO "%s: write_proc: name=%s count=%lu data=%x\n", zr->name, file->f_dentry->d_name.name, count, (int) data));
ldelim = " \t\n";
tdelim = "=";
line = strpbrk(sp, ldelim);
while (line) {
*line = 0;
svar = strpbrk(sp, tdelim);
if (svar) {
*svar = 0;
varname = sp;
svar++;
setparam(zr, varname, svar);
}
sp = line + 1;
line = strpbrk(sp, ldelim);
}
vfree(string);
#endif
return count;
}
static int zoran_proc_init(int i)
{
#ifdef CONFIG_PROC_FS
char name[8];
sprintf(name, "zoran%d", i);
if ((zoran[i].zoran_proc = create_proc_entry(name, 0, 0))) {
zoran[i].zoran_proc->read_proc = zoran_read_proc;
zoran[i].zoran_proc->write_proc = zoran_write_proc;
zoran[i].zoran_proc->data = &zoran[i];
printk(KERN_INFO "%s: procfs entry /proc/%s allocated. data=%x\n", zoran[i].name, name, (int) zoran[i].zoran_proc->data);
} else {
printk(KERN_ERR "%s: Unable to initialise /proc/%s\n", zoran[i].name, name);
return 1;
}
#endif
return 0;
}
static void zoran_proc_cleanup(int i)
{
#ifdef CONFIG_PROC_FS
char name[8];
sprintf(name, "zoran%d", i);
if (zoran[i].zoran_proc) {
remove_proc_entry(name, 0);
}
zoran[i].zoran_proc = NULL;
#endif
}