File: /usr/src/linux/drivers/media/video/zoran_procfs.c

1     #include <linux/config.h>
2     #include <linux/ctype.h>
3     
4     struct procfs_params_zr36067 {
5     	char *name;
6     	short reg;
7     	u32 mask;
8     	short bit;
9     };
10     
11     static 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     
39     static 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     
76     static 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     
105     static 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     	string = sp = vmalloc(count + 1);
115     	if (!string) {
116     		printk(KERN_ERR "%s: write_proc: can not allocate memory\n", zr->name);
117     		return -ENOMEM;
118     	}
119     	memcpy(string, buffer, count);
120     	string[count] = 0;
121     	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));
122     	ldelim = " \t\n";
123     	tdelim = "=";
124     	line = strpbrk(sp, ldelim);
125     	while (line) {
126     		*line = 0;
127     		svar = strpbrk(sp, tdelim);
128     		if (svar) {
129     			*svar = 0;
130     			varname = sp;
131     			svar++;
132     			setparam(zr, varname, svar);
133     		}
134     		sp = line + 1;
135     		line = strpbrk(sp, ldelim);
136     	}
137     	vfree(string);
138     #endif
139     	return count;
140     }
141     
142     static int zoran_proc_init(int i)
143     {
144     #ifdef CONFIG_PROC_FS
145     	char name[8];
146     	sprintf(name, "zoran%d", i);
147     	if ((zoran[i].zoran_proc = create_proc_entry(name, 0, 0))) {
148     		zoran[i].zoran_proc->read_proc = zoran_read_proc;
149     		zoran[i].zoran_proc->write_proc = zoran_write_proc;
150     		zoran[i].zoran_proc->data = &zoran[i];
151     		printk(KERN_INFO "%s: procfs entry /proc/%s allocated. data=%x\n", zoran[i].name, name, (int) zoran[i].zoran_proc->data);
152     	} else {
153     		printk(KERN_ERR "%s: Unable to initialise /proc/%s\n", zoran[i].name, name);
154     		return 1;
155     	}
156     #endif
157     	return 0;
158     }
159     
160     static void zoran_proc_cleanup(int i)
161     {
162     #ifdef CONFIG_PROC_FS
163     	char name[8];
164     	sprintf(name, "zoran%d", i);
165     	if (zoran[i].zoran_proc) {
166     		remove_proc_entry(name, 0);
167     	}
168     	zoran[i].zoran_proc = NULL;
169     #endif
170     }
171