1#include <linux/config.h>
2#include <linux/ctype.h>
3
4struct procfs_params_zr36067 {
5	char *name;
6	short reg;
7	u32 mask;
8	short bit;
9};
10
11static struct procfs_params_zr36067 zr67[] = {
12	{"HSPol", 0x000, 1, 30},
13	{"HStart", 0x000, 0x3ff, 10},
14	{"HEnd", 0x000, 0x3ff, 0},
15
16	{"VSPol", 0x004, 1, 30},
17	{"VStart", 0x004, 0x3ff, 10},
18	{"VEnd", 0x004, 0x3ff, 0},
19
20	{"ExtFl", 0x008, 1, 26},
21	{"TopField", 0x008, 1, 25},
22	{"VCLKPol", 0x008, 1, 24},
23	{"DupFld", 0x008, 1, 20},
24	{"LittleEndian", 0x008, 1, 0},
25
26	{"HsyncStart", 0x10c, 0xffff, 16},
27	{"LineTot", 0x10c, 0xffff, 0},
28
29	{"NAX", 0x110, 0xffff, 16},
30	{"PAX", 0x110, 0xffff, 0},
31
32	{"NAY", 0x114, 0xffff, 16},
33	{"PAY", 0x114, 0xffff, 0},
34/*    {"",,,}, */
35
36	{NULL, 0, 0, 0},
37};
38
39static void setparam(struct zoran *zr, char *name, char *sval)
40{
41	int i, reg0, reg, val;
42	i = 0;
43	while (zr67[i].name != NULL) {
44		if (!strncmp(name, zr67[i].name, strlen(zr67[i].name))) {
45			reg = reg0 = btread(zr67[i].reg);
46			reg &= ~(zr67[i].mask << zr67[i].bit);
47			if (!isdigit(sval[0]))
48				break;
49			val = simple_strtoul(sval, NULL, 0);
50			if ((val & ~zr67[i].mask))
51				break;
52			reg |= (val & zr67[i].mask) << zr67[i].bit;
53			printk(KERN_INFO "%s: setparam: setting ZR36067 register 0x%03x: 0x%08x=>0x%08x %s=%d\n",
54			       zr->name, zr67[i].reg, reg0, reg, zr67[i].name, val);
55			btwrite(reg, zr67[i].reg);
56			break;
57		}
58		i++;
59	}
60}
61
62/* This macro was stolen from /usr/src/drivers/char/nvram.c and modified */
63#define	PRINT_PROC(args...)					\
64	do {							\
65		if (begin + len > offset + size) {		\
66			*eof = 0;                               \
67                        break;				        \
68		}                                               \
69                len += sprintf( buffer+len, ##args );	        \
70		if (begin + len < offset) {			\
71			begin += len;				\
72			len = 0;				\
73		}						\
74	} while(0)
75
76static int zoran_read_proc(char *buffer, char **start, off_t offset, int size, int *eof, void *data)
77{
78#ifdef CONFIG_PROC_FS
79	int len = 0;
80	off_t begin = 0;
81
82	int i;
83	struct zoran *zr;
84
85	zr = (struct zoran *) data;
86	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));
87	*eof = 1;
88	PRINT_PROC("ZR36067 registers:");
89	for (i = 0; i < 0x130; i += 4) {
90		if (!(i % 16)) {
91			PRINT_PROC("\n%03X", i);
92		}
93		PRINT_PROC(" %08X ", btread(i));
94	}
95	PRINT_PROC("\n");
96	if (offset >= len + begin) {
97		return 0;
98	}
99	*start = buffer + begin - offset;
100	return ((size < begin + len - offset) ? size : begin + len - offset);
101#endif
102	return 0;
103}
104
105static int zoran_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
106{
107#ifdef CONFIG_PROC_FS
108	char *string, *sp;
109	char *line, *ldelim, *varname, *svar, *tdelim;
110	struct zoran *zr;
111
112	zr = (struct zoran *) data;
113
114	if(count > 32768)		/* Stupidity filter */
115		count = 32768;
116
117	string = sp = vmalloc(count + 1);
118	if (!string) {
119		printk(KERN_ERR "%s: write_proc: can not allocate memory\n", zr->name);
120		return -ENOMEM;
121	}
122	memcpy(string, buffer, count);
123	string[count] = 0;
124	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));
125	ldelim = " \t\n";
126	tdelim = "=";
127	line = strpbrk(sp, ldelim);
128	while (line) {
129		*line = 0;
130		svar = strpbrk(sp, tdelim);
131		if (svar) {
132			*svar = 0;
133			varname = sp;
134			svar++;
135			setparam(zr, varname, svar);
136		}
137		sp = line + 1;
138		line = strpbrk(sp, ldelim);
139	}
140	vfree(string);
141#endif
142	return count;
143}
144
145static int zoran_proc_init(int i)
146{
147#ifdef CONFIG_PROC_FS
148	char name[8];
149	sprintf(name, "zoran%d", i);
150	if ((zoran[i].zoran_proc = create_proc_entry(name, 0, 0))) {
151		zoran[i].zoran_proc->read_proc = zoran_read_proc;
152		zoran[i].zoran_proc->write_proc = zoran_write_proc;
153		zoran[i].zoran_proc->data = &zoran[i];
154		printk(KERN_INFO "%s: procfs entry /proc/%s allocated. data=%x\n", zoran[i].name, name, (int) zoran[i].zoran_proc->data);
155	} else {
156		printk(KERN_ERR "%s: Unable to initialise /proc/%s\n", zoran[i].name, name);
157		return 1;
158	}
159#endif
160	return 0;
161}
162
163static void zoran_proc_cleanup(int i)
164{
165#ifdef CONFIG_PROC_FS
166	char name[8];
167	sprintf(name, "zoran%d", i);
168	if (zoran[i].zoran_proc) {
169		remove_proc_entry(name, 0);
170	}
171	zoran[i].zoran_proc = NULL;
172#endif
173}
174