added mtd driver
[linux-2.4.git] / 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         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         if(copy_from_user(string, buffer, count))
123         {
124                 vfree(string);
125                 return -EFAULT;
126         }
127         string[count] = 0;
128         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));
129         ldelim = " \t\n";
130         tdelim = "=";
131         line = strpbrk(sp, ldelim);
132         while (line) {
133                 *line = 0;
134                 svar = strpbrk(sp, tdelim);
135                 if (svar) {
136                         *svar = 0;
137                         varname = sp;
138                         svar++;
139                         setparam(zr, varname, svar);
140                 }
141                 sp = line + 1;
142                 line = strpbrk(sp, ldelim);
143         }
144         vfree(string);
145 #endif
146         return count;
147 }
148
149 static int zoran_proc_init(int i)
150 {
151 #ifdef CONFIG_PROC_FS
152         char name[8];
153         sprintf(name, "zoran%d", i);
154         if ((zoran[i].zoran_proc = create_proc_entry(name, 0, 0))) {
155                 zoran[i].zoran_proc->read_proc = zoran_read_proc;
156                 zoran[i].zoran_proc->write_proc = zoran_write_proc;
157                 zoran[i].zoran_proc->data = &zoran[i];
158                 printk(KERN_INFO "%s: procfs entry /proc/%s allocated. data=%x\n", zoran[i].name, name, (int) zoran[i].zoran_proc->data);
159         } else {
160                 printk(KERN_ERR "%s: Unable to initialise /proc/%s\n", zoran[i].name, name);
161                 return 1;
162         }
163 #endif
164         return 0;
165 }
166
167 static void zoran_proc_cleanup(int i)
168 {
169 #ifdef CONFIG_PROC_FS
170         char name[8];
171         sprintf(name, "zoran%d", i);
172         if (zoran[i].zoran_proc) {
173                 remove_proc_entry(name, 0);
174         }
175         zoran[i].zoran_proc = NULL;
176 #endif
177 }