aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/pms.c1297
1 files changed, 636 insertions, 661 deletions
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index a1ad38fc49c1..2919aa42c94e 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -31,171 +31,175 @@
31#include <linux/videodev.h> 31#include <linux/videodev.h>
32#include <media/v4l2-common.h> 32#include <media/v4l2-common.h>
33#include <media/v4l2-ioctl.h> 33#include <media/v4l2-ioctl.h>
34#include <media/v4l2-device.h>
34#include <linux/mutex.h> 35#include <linux/mutex.h>
35 36
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
37 38
39MODULE_LICENSE("GPL");
40
38 41
39#define MOTOROLA 1 42#define MOTOROLA 1
40#define PHILIPS2 2 43#define PHILIPS2 2
41#define PHILIPS1 3 44#define PHILIPS1 3
42#define MVVMEMORYWIDTH 0x40 /* 512 bytes */ 45#define MVVMEMORYWIDTH 0x40 /* 512 bytes */
43 46
44struct pms_device 47struct i2c_info {
45{
46 struct video_device v;
47 struct video_picture picture;
48 int height;
49 int width;
50 unsigned long in_use;
51 struct mutex lock;
52};
53
54struct i2c_info
55{
56 u8 slave; 48 u8 slave;
57 u8 sub; 49 u8 sub;
58 u8 data; 50 u8 data;
59 u8 hits; 51 u8 hits;
60}; 52};
61 53
62static int i2c_count; 54struct pms {
63static struct i2c_info i2cinfo[64]; 55 struct v4l2_device v4l2_dev;
56 struct video_device vdev;
57 struct video_picture picture;
58 int height;
59 int width;
60 unsigned long in_use;
61 struct mutex lock;
62 int i2c_count;
63 struct i2c_info i2cinfo[64];
64
65 int decoder;
66 int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
67 int io;
68 int data;
69 void __iomem *mem;
70};
64 71
65static int decoder = PHILIPS2; 72static struct pms pms_card;
66static int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
67 73
68/* 74/*
69 * I/O ports and Shared Memory 75 * I/O ports and Shared Memory
70 */ 76 */
71 77
72static int io_port = 0x250; 78static int io_port = 0x250;
73static int data_port = 0x251; 79module_param(io_port, int, 0);
74static int mem_base = 0xC8000; 80
75static void __iomem *mem; 81static int mem_base = 0xc8000;
76static int video_nr = -1; 82module_param(mem_base, int, 0);
77 83
84static int video_nr = -1;
85module_param(video_nr, int, 0);
78 86
79 87
80static inline void mvv_write(u8 index, u8 value) 88static inline void mvv_write(struct pms *dev, u8 index, u8 value)
81{ 89{
82 outw(index|(value<<8), io_port); 90 outw(index | (value << 8), dev->io);
83} 91}
84 92
85static inline u8 mvv_read(u8 index) 93static inline u8 mvv_read(struct pms *dev, u8 index)
86{ 94{
87 outb(index, io_port); 95 outb(index, dev->io);
88 return inb(data_port); 96 return inb(dev->data);
89} 97}
90 98
91static int pms_i2c_stat(u8 slave) 99static int pms_i2c_stat(struct pms *dev, u8 slave)
92{ 100{
93 int counter; 101 int counter = 0;
94 int i; 102 int i;
95 103
96 outb(0x28, io_port); 104 outb(0x28, dev->io);
97 105
98 counter=0; 106 while ((inb(dev->data) & 0x01) == 0)
99 while((inb(data_port)&0x01)==0) 107 if (counter++ == 256)
100 if(counter++==256)
101 break; 108 break;
102 109
103 while((inb(data_port)&0x01)!=0) 110 while ((inb(dev->data) & 0x01) != 0)
104 if(counter++==256) 111 if (counter++ == 256)
105 break; 112 break;
106 113
107 outb(slave, io_port); 114 outb(slave, dev->io);
108 115
109 counter=0; 116 counter = 0;
110 while((inb(data_port)&0x01)==0) 117 while ((inb(dev->data) & 0x01) == 0)
111 if(counter++==256) 118 if (counter++ == 256)
112 break; 119 break;
113 120
114 while((inb(data_port)&0x01)!=0) 121 while ((inb(dev->data) & 0x01) != 0)
115 if(counter++==256) 122 if (counter++ == 256)
116 break; 123 break;
117 124
118 for(i=0;i<12;i++) 125 for (i = 0; i < 12; i++) {
119 { 126 char st = inb(dev->data);
120 char st=inb(data_port); 127
121 if((st&2)!=0) 128 if ((st & 2) != 0)
122 return -1; 129 return -1;
123 if((st&1)==0) 130 if ((st & 1) == 0)
124 break; 131 break;
125 } 132 }
126 outb(0x29, io_port); 133 outb(0x29, dev->io);
127 return inb(data_port); 134 return inb(dev->data);
128} 135}
129 136
130static int pms_i2c_write(u16 slave, u16 sub, u16 data) 137static int pms_i2c_write(struct pms *dev, u16 slave, u16 sub, u16 data)
131{ 138{
132 int skip=0; 139 int skip = 0;
133 int count; 140 int count;
134 int i; 141 int i;
135 142
136 for(i=0;i<i2c_count;i++) 143 for (i = 0; i < dev->i2c_count; i++) {
137 { 144 if ((dev->i2cinfo[i].slave == slave) &&
138 if((i2cinfo[i].slave==slave) && 145 (dev->i2cinfo[i].sub == sub)) {
139 (i2cinfo[i].sub == sub)) 146 if (dev->i2cinfo[i].data == data)
140 { 147 skip = 1;
141 if(i2cinfo[i].data==data) 148 dev->i2cinfo[i].data = data;
142 skip=1; 149 i = dev->i2c_count + 1;
143 i2cinfo[i].data=data;
144 i=i2c_count+1;
145 } 150 }
146 } 151 }
147 152
148 if(i==i2c_count && i2c_count<64) 153 if (i == dev->i2c_count && dev->i2c_count < 64) {
149 { 154 dev->i2cinfo[dev->i2c_count].slave = slave;
150 i2cinfo[i2c_count].slave=slave; 155 dev->i2cinfo[dev->i2c_count].sub = sub;
151 i2cinfo[i2c_count].sub=sub; 156 dev->i2cinfo[dev->i2c_count].data = data;
152 i2cinfo[i2c_count].data=data; 157 dev->i2c_count++;
153 i2c_count++;
154 } 158 }
155 159
156 if(skip) 160 if (skip)
157 return 0; 161 return 0;
158 162
159 mvv_write(0x29, sub); 163 mvv_write(dev, 0x29, sub);
160 mvv_write(0x2A, data); 164 mvv_write(dev, 0x2A, data);
161 mvv_write(0x28, slave); 165 mvv_write(dev, 0x28, slave);
162 166
163 outb(0x28, io_port); 167 outb(0x28, dev->io);
164 168
165 count=0; 169 count = 0;
166 while((inb(data_port)&1)==0) 170 while ((inb(dev->data) & 1) == 0)
167 if(count>255) 171 if (count > 255)
168 break; 172 break;
169 while((inb(data_port)&1)!=0) 173 while ((inb(dev->data) & 1) != 0)
170 if(count>255) 174 if (count > 255)
171 break; 175 break;
172 176
173 count=inb(data_port); 177 count = inb(dev->data);
174 178
175 if(count&2) 179 if (count & 2)
176 return -1; 180 return -1;
177 return count; 181 return count;
178} 182}
179 183
180static int pms_i2c_read(int slave, int sub) 184static int pms_i2c_read(struct pms *dev, int slave, int sub)
181{ 185{
182 int i=0; 186 int i;
183 for(i=0;i<i2c_count;i++) 187
184 { 188 for (i = 0; i < dev->i2c_count; i++) {
185 if(i2cinfo[i].slave==slave && i2cinfo[i].sub==sub) 189 if (dev->i2cinfo[i].slave == slave && dev->i2cinfo[i].sub == sub)
186 return i2cinfo[i].data; 190 return dev->i2cinfo[i].data;
187 } 191 }
188 return 0; 192 return 0;
189} 193}
190 194
191 195
192static void pms_i2c_andor(int slave, int sub, int and, int or) 196static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or)
193{ 197{
194 u8 tmp; 198 u8 tmp;
195 199
196 tmp=pms_i2c_read(slave, sub); 200 tmp = pms_i2c_read(dev, slave, sub);
197 tmp = (tmp&and)|or; 201 tmp = (tmp & and) | or;
198 pms_i2c_write(slave, sub, tmp); 202 pms_i2c_write(dev, slave, sub, tmp);
199} 203}
200 204
201/* 205/*
@@ -203,100 +207,96 @@ static void pms_i2c_andor(int slave, int sub, int and, int or)
203 */ 207 */
204 208
205 209
206static void pms_videosource(short source) 210static void pms_videosource(struct pms *dev, short source)
207{ 211{
208 mvv_write(0x2E, source?0x31:0x30); 212 mvv_write(dev, 0x2E, source ? 0x31 : 0x30);
209} 213}
210 214
211static void pms_hue(short hue) 215static void pms_hue(struct pms *dev, short hue)
212{ 216{
213 switch(decoder) 217 switch (dev->decoder) {
214 { 218 case MOTOROLA:
215 case MOTOROLA: 219 pms_i2c_write(dev, 0x8a, 0x00, hue);
216 pms_i2c_write(0x8A, 0x00, hue); 220 break;
217 break; 221 case PHILIPS2:
218 case PHILIPS2: 222 pms_i2c_write(dev, 0x8a, 0x07, hue);
219 pms_i2c_write(0x8A, 0x07, hue); 223 break;
220 break; 224 case PHILIPS1:
221 case PHILIPS1: 225 pms_i2c_write(dev, 0x42, 0x07, hue);
222 pms_i2c_write(0x42, 0x07, hue); 226 break;
223 break;
224 } 227 }
225} 228}
226 229
227static void pms_colour(short colour) 230static void pms_colour(struct pms *dev, short colour)
228{ 231{
229 switch(decoder) 232 switch (dev->decoder) {
230 { 233 case MOTOROLA:
231 case MOTOROLA: 234 pms_i2c_write(dev, 0x8a, 0x00, colour);
232 pms_i2c_write(0x8A, 0x00, colour); 235 break;
233 break; 236 case PHILIPS1:
234 case PHILIPS1: 237 pms_i2c_write(dev, 0x42, 0x12, colour);
235 pms_i2c_write(0x42, 0x12, colour); 238 break;
236 break;
237 } 239 }
238} 240}
239 241
240 242
241static void pms_contrast(short contrast) 243static void pms_contrast(struct pms *dev, short contrast)
242{ 244{
243 switch(decoder) 245 switch (dev->decoder) {
244 { 246 case MOTOROLA:
245 case MOTOROLA: 247 pms_i2c_write(dev, 0x8a, 0x00, contrast);
246 pms_i2c_write(0x8A, 0x00, contrast); 248 break;
247 break; 249 case PHILIPS1:
248 case PHILIPS1: 250 pms_i2c_write(dev, 0x42, 0x13, contrast);
249 pms_i2c_write(0x42, 0x13, contrast); 251 break;
250 break;
251 } 252 }
252} 253}
253 254
254static void pms_brightness(short brightness) 255static void pms_brightness(struct pms *dev, short brightness)
255{ 256{
256 switch(decoder) 257 switch (dev->decoder) {
257 { 258 case MOTOROLA:
258 case MOTOROLA: 259 pms_i2c_write(dev, 0x8a, 0x00, brightness);
259 pms_i2c_write(0x8A, 0x00, brightness); 260 pms_i2c_write(dev, 0x8a, 0x00, brightness);
260 pms_i2c_write(0x8A, 0x00, brightness); 261 pms_i2c_write(dev, 0x8a, 0x00, brightness);
261 pms_i2c_write(0x8A, 0x00, brightness); 262 break;
262 break; 263 case PHILIPS1:
263 case PHILIPS1: 264 pms_i2c_write(dev, 0x42, 0x19, brightness);
264 pms_i2c_write(0x42, 0x19, brightness); 265 break;
265 break;
266 } 266 }
267} 267}
268 268
269 269
270static void pms_format(short format) 270static void pms_format(struct pms *dev, short format)
271{ 271{
272 int target; 272 int target;
273 standard = format;
274 273
275 if(decoder==PHILIPS1) 274 dev->standard = format;
276 target=0x42; 275
277 else if(decoder==PHILIPS2) 276 if (dev->decoder == PHILIPS1)
278 target=0x8A; 277 target = 0x42;
278 else if (dev->decoder == PHILIPS2)
279 target = 0x8a;
279 else 280 else
280 return; 281 return;
281 282
282 switch(format) 283 switch (format) {
283 { 284 case 0: /* Auto */
284 case 0: /* Auto */ 285 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
285 pms_i2c_andor(target, 0x0D, 0xFE,0x00); 286 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x80);
286 pms_i2c_andor(target, 0x0F, 0x3F,0x80); 287 break;
287 break; 288 case 1: /* NTSC */
288 case 1: /* NTSC */ 289 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
289 pms_i2c_andor(target, 0x0D, 0xFE, 0x00); 290 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x40);
290 pms_i2c_andor(target, 0x0F, 0x3F, 0x40); 291 break;
291 break; 292 case 2: /* PAL */
292 case 2: /* PAL */ 293 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
293 pms_i2c_andor(target, 0x0D, 0xFE, 0x00); 294 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
294 pms_i2c_andor(target, 0x0F, 0x3F, 0x00); 295 break;
295 break; 296 case 3: /* SECAM */
296 case 3: /* SECAM */ 297 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x01);
297 pms_i2c_andor(target, 0x0D, 0xFE, 0x01); 298 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
298 pms_i2c_andor(target, 0x0F, 0x3F, 0x00); 299 break;
299 break;
300 } 300 }
301} 301}
302 302
@@ -308,18 +308,17 @@ static void pms_format(short format)
308 * people need it. We also don't yet use the PMS interrupt. 308 * people need it. We also don't yet use the PMS interrupt.
309 */ 309 */
310 310
311static void pms_hstart(short start) 311static void pms_hstart(struct pms *dev, short start)
312{ 312{
313 switch(decoder) 313 switch (dev->decoder) {
314 { 314 case PHILIPS1:
315 case PHILIPS1: 315 pms_i2c_write(dev, 0x8a, 0x05, start);
316 pms_i2c_write(0x8A, 0x05, start); 316 pms_i2c_write(dev, 0x8a, 0x18, start);
317 pms_i2c_write(0x8A, 0x18, start); 317 break;
318 break; 318 case PHILIPS2:
319 case PHILIPS2: 319 pms_i2c_write(dev, 0x42, 0x05, start);
320 pms_i2c_write(0x42, 0x05, start); 320 pms_i2c_write(dev, 0x42, 0x18, start);
321 pms_i2c_write(0x42, 0x18, start); 321 break;
322 break;
323 } 322 }
324} 323}
325 324
@@ -327,293 +326,271 @@ static void pms_hstart(short start)
327 * Bandpass filters 326 * Bandpass filters
328 */ 327 */
329 328
330static void pms_bandpass(short pass) 329static void pms_bandpass(struct pms *dev, short pass)
331{ 330{
332 if(decoder==PHILIPS2) 331 if (dev->decoder == PHILIPS2)
333 pms_i2c_andor(0x8A, 0x06, 0xCF, (pass&0x03)<<4); 332 pms_i2c_andor(dev, 0x8a, 0x06, 0xcf, (pass & 0x03) << 4);
334 else if(decoder==PHILIPS1) 333 else if (dev->decoder == PHILIPS1)
335 pms_i2c_andor(0x42, 0x06, 0xCF, (pass&0x03)<<4); 334 pms_i2c_andor(dev, 0x42, 0x06, 0xcf, (pass & 0x03) << 4);
336} 335}
337 336
338static void pms_antisnow(short snow) 337static void pms_antisnow(struct pms *dev, short snow)
339{ 338{
340 if(decoder==PHILIPS2) 339 if (dev->decoder == PHILIPS2)
341 pms_i2c_andor(0x8A, 0x06, 0xF3, (snow&0x03)<<2); 340 pms_i2c_andor(dev, 0x8a, 0x06, 0xf3, (snow & 0x03) << 2);
342 else if(decoder==PHILIPS1) 341 else if (dev->decoder == PHILIPS1)
343 pms_i2c_andor(0x42, 0x06, 0xF3, (snow&0x03)<<2); 342 pms_i2c_andor(dev, 0x42, 0x06, 0xf3, (snow & 0x03) << 2);
344} 343}
345 344
346static void pms_sharpness(short sharp) 345static void pms_sharpness(struct pms *dev, short sharp)
347{ 346{
348 if(decoder==PHILIPS2) 347 if (dev->decoder == PHILIPS2)
349 pms_i2c_andor(0x8A, 0x06, 0xFC, sharp&0x03); 348 pms_i2c_andor(dev, 0x8a, 0x06, 0xfc, sharp & 0x03);
350 else if(decoder==PHILIPS1) 349 else if (dev->decoder == PHILIPS1)
351 pms_i2c_andor(0x42, 0x06, 0xFC, sharp&0x03); 350 pms_i2c_andor(dev, 0x42, 0x06, 0xfc, sharp & 0x03);
352} 351}
353 352
354static void pms_chromaagc(short agc) 353static void pms_chromaagc(struct pms *dev, short agc)
355{ 354{
356 if(decoder==PHILIPS2) 355 if (dev->decoder == PHILIPS2)
357 pms_i2c_andor(0x8A, 0x0C, 0x9F, (agc&0x03)<<5); 356 pms_i2c_andor(dev, 0x8a, 0x0c, 0x9f, (agc & 0x03) << 5);
358 else if(decoder==PHILIPS1) 357 else if (dev->decoder == PHILIPS1)
359 pms_i2c_andor(0x42, 0x0C, 0x9F, (agc&0x03)<<5); 358 pms_i2c_andor(dev, 0x42, 0x0c, 0x9f, (agc & 0x03) << 5);
360} 359}
361 360
362static void pms_vertnoise(short noise) 361static void pms_vertnoise(struct pms *dev, short noise)
363{ 362{
364 if(decoder==PHILIPS2) 363 if (dev->decoder == PHILIPS2)
365 pms_i2c_andor(0x8A, 0x10, 0xFC, noise&3); 364 pms_i2c_andor(dev, 0x8a, 0x10, 0xfc, noise & 3);
366 else if(decoder==PHILIPS1) 365 else if (dev->decoder == PHILIPS1)
367 pms_i2c_andor(0x42, 0x10, 0xFC, noise&3); 366 pms_i2c_andor(dev, 0x42, 0x10, 0xfc, noise & 3);
368} 367}
369 368
370static void pms_forcecolour(short colour) 369static void pms_forcecolour(struct pms *dev, short colour)
371{ 370{
372 if(decoder==PHILIPS2) 371 if (dev->decoder == PHILIPS2)
373 pms_i2c_andor(0x8A, 0x0C, 0x7F, (colour&1)<<7); 372 pms_i2c_andor(dev, 0x8a, 0x0c, 0x7f, (colour & 1) << 7);
374 else if(decoder==PHILIPS1) 373 else if (dev->decoder == PHILIPS1)
375 pms_i2c_andor(0x42, 0x0C, 0x7, (colour&1)<<7); 374 pms_i2c_andor(dev, 0x42, 0x0c, 0x7, (colour & 1) << 7);
376} 375}
377 376
378static void pms_antigamma(short gamma) 377static void pms_antigamma(struct pms *dev, short gamma)
379{ 378{
380 if(decoder==PHILIPS2) 379 if (dev->decoder == PHILIPS2)
381 pms_i2c_andor(0xB8, 0x00, 0x7F, (gamma&1)<<7); 380 pms_i2c_andor(dev, 0xb8, 0x00, 0x7f, (gamma & 1) << 7);
382 else if(decoder==PHILIPS1) 381 else if (dev->decoder == PHILIPS1)
383 pms_i2c_andor(0x42, 0x20, 0x7, (gamma&1)<<7); 382 pms_i2c_andor(dev, 0x42, 0x20, 0x7, (gamma & 1) << 7);
384} 383}
385 384
386static void pms_prefilter(short filter) 385static void pms_prefilter(struct pms *dev, short filter)
387{ 386{
388 if(decoder==PHILIPS2) 387 if (dev->decoder == PHILIPS2)
389 pms_i2c_andor(0x8A, 0x06, 0xBF, (filter&1)<<6); 388 pms_i2c_andor(dev, 0x8a, 0x06, 0xbf, (filter & 1) << 6);
390 else if(decoder==PHILIPS1) 389 else if (dev->decoder == PHILIPS1)
391 pms_i2c_andor(0x42, 0x06, 0xBF, (filter&1)<<6); 390 pms_i2c_andor(dev, 0x42, 0x06, 0xbf, (filter & 1) << 6);
392} 391}
393 392
394static void pms_hfilter(short filter) 393static void pms_hfilter(struct pms *dev, short filter)
395{ 394{
396 if(decoder==PHILIPS2) 395 if (dev->decoder == PHILIPS2)
397 pms_i2c_andor(0xB8, 0x04, 0x1F, (filter&7)<<5); 396 pms_i2c_andor(dev, 0xb8, 0x04, 0x1f, (filter & 7) << 5);
398 else if(decoder==PHILIPS1) 397 else if (dev->decoder == PHILIPS1)
399 pms_i2c_andor(0x42, 0x24, 0x1F, (filter&7)<<5); 398 pms_i2c_andor(dev, 0x42, 0x24, 0x1f, (filter & 7) << 5);
400} 399}
401 400
402static void pms_vfilter(short filter) 401static void pms_vfilter(struct pms *dev, short filter)
403{ 402{
404 if(decoder==PHILIPS2) 403 if (dev->decoder == PHILIPS2)
405 pms_i2c_andor(0xB8, 0x08, 0x9F, (filter&3)<<5); 404 pms_i2c_andor(dev, 0xb8, 0x08, 0x9f, (filter & 3) << 5);
406 else if(decoder==PHILIPS1) 405 else if (dev->decoder == PHILIPS1)
407 pms_i2c_andor(0x42, 0x28, 0x9F, (filter&3)<<5); 406 pms_i2c_andor(dev, 0x42, 0x28, 0x9f, (filter & 3) << 5);
408} 407}
409 408
410static void pms_killcolour(short colour) 409static void pms_killcolour(struct pms *dev, short colour)
411{ 410{
412 if(decoder==PHILIPS2) 411 if (dev->decoder == PHILIPS2) {
413 { 412 pms_i2c_andor(dev, 0x8a, 0x08, 0x07, (colour & 0x1f) << 3);
414 pms_i2c_andor(0x8A, 0x08, 0x07, (colour&0x1F)<<3); 413 pms_i2c_andor(dev, 0x8a, 0x09, 0x07, (colour & 0x1f) << 3);
415 pms_i2c_andor(0x8A, 0x09, 0x07, (colour&0x1F)<<3); 414 } else if (dev->decoder == PHILIPS1) {
416 } 415 pms_i2c_andor(dev, 0x42, 0x08, 0x07, (colour & 0x1f) << 3);
417 else if(decoder==PHILIPS1) 416 pms_i2c_andor(dev, 0x42, 0x09, 0x07, (colour & 0x1f) << 3);
418 {
419 pms_i2c_andor(0x42, 0x08, 0x07, (colour&0x1F)<<3);
420 pms_i2c_andor(0x42, 0x09, 0x07, (colour&0x1F)<<3);
421 } 417 }
422} 418}
423 419
424static void pms_chromagain(short chroma) 420static void pms_chromagain(struct pms *dev, short chroma)
425{ 421{
426 if(decoder==PHILIPS2) 422 if (dev->decoder == PHILIPS2)
427 { 423 pms_i2c_write(dev, 0x8a, 0x11, chroma);
428 pms_i2c_write(0x8A, 0x11, chroma); 424 else if (dev->decoder == PHILIPS1)
429 } 425 pms_i2c_write(dev, 0x42, 0x11, chroma);
430 else if(decoder==PHILIPS1)
431 {
432 pms_i2c_write(0x42, 0x11, chroma);
433 }
434} 426}
435 427
436 428
437static void pms_spacialcompl(short data) 429static void pms_spacialcompl(struct pms *dev, short data)
438{ 430{
439 mvv_write(0x3B, data); 431 mvv_write(dev, 0x3b, data);
440} 432}
441 433
442static void pms_spacialcomph(short data) 434static void pms_spacialcomph(struct pms *dev, short data)
443{ 435{
444 mvv_write(0x3A, data); 436 mvv_write(dev, 0x3a, data);
445} 437}
446 438
447static void pms_vstart(short start) 439static void pms_vstart(struct pms *dev, short start)
448{ 440{
449 mvv_write(0x16, start); 441 mvv_write(dev, 0x16, start);
450 mvv_write(0x17, (start>>8)&0x01); 442 mvv_write(dev, 0x17, (start >> 8) & 0x01);
451} 443}
452 444
453#endif 445#endif
454 446
455static void pms_secamcross(short cross) 447static void pms_secamcross(struct pms *dev, short cross)
456{ 448{
457 if(decoder==PHILIPS2) 449 if (dev->decoder == PHILIPS2)
458 pms_i2c_andor(0x8A, 0x0F, 0xDF, (cross&1)<<5); 450 pms_i2c_andor(dev, 0x8a, 0x0f, 0xdf, (cross & 1) << 5);
459 else if(decoder==PHILIPS1) 451 else if (dev->decoder == PHILIPS1)
460 pms_i2c_andor(0x42, 0x0F, 0xDF, (cross&1)<<5); 452 pms_i2c_andor(dev, 0x42, 0x0f, 0xdf, (cross & 1) << 5);
461} 453}
462 454
463 455
464static void pms_swsense(short sense) 456static void pms_swsense(struct pms *dev, short sense)
465{ 457{
466 if(decoder==PHILIPS2) 458 if (dev->decoder == PHILIPS2) {
467 { 459 pms_i2c_write(dev, 0x8a, 0x0a, sense);
468 pms_i2c_write(0x8A, 0x0A, sense); 460 pms_i2c_write(dev, 0x8a, 0x0b, sense);
469 pms_i2c_write(0x8A, 0x0B, sense); 461 } else if (dev->decoder == PHILIPS1) {
470 } 462 pms_i2c_write(dev, 0x42, 0x0a, sense);
471 else if(decoder==PHILIPS1) 463 pms_i2c_write(dev, 0x42, 0x0b, sense);
472 {
473 pms_i2c_write(0x42, 0x0A, sense);
474 pms_i2c_write(0x42, 0x0B, sense);
475 } 464 }
476} 465}
477 466
478 467
479static void pms_framerate(short frr) 468static void pms_framerate(struct pms *dev, short frr)
480{ 469{
481 int fps=(standard==1)?30:25; 470 int fps = (dev->standard == 1) ? 30 : 25;
482 if(frr==0) 471
472 if (frr == 0)
483 return; 473 return;
484 fps=fps/frr; 474 fps = fps/frr;
485 mvv_write(0x14,0x80|fps); 475 mvv_write(dev, 0x14, 0x80 | fps);
486 mvv_write(0x15,1); 476 mvv_write(dev, 0x15, 1);
487} 477}
488 478
489static void pms_vert(u8 deciden, u8 decinum) 479static void pms_vert(struct pms *dev, u8 deciden, u8 decinum)
490{ 480{
491 mvv_write(0x1C, deciden); /* Denominator */ 481 mvv_write(dev, 0x1c, deciden); /* Denominator */
492 mvv_write(0x1D, decinum); /* Numerator */ 482 mvv_write(dev, 0x1d, decinum); /* Numerator */
493} 483}
494 484
495/* 485/*
496 * Turn 16bit ratios into best small ratio the chipset can grok 486 * Turn 16bit ratios into best small ratio the chipset can grok
497 */ 487 */
498 488
499static void pms_vertdeci(unsigned short decinum, unsigned short deciden) 489static void pms_vertdeci(struct pms *dev, unsigned short decinum, unsigned short deciden)
500{ 490{
501 /* Knock it down by /5 once */ 491 /* Knock it down by / 5 once */
502 if(decinum%5==0) 492 if (decinum % 5 == 0) {
503 { 493 deciden /= 5;
504 deciden/=5; 494 decinum /= 5;
505 decinum/=5;
506 } 495 }
507 /* 496 /*
508 * 3's 497 * 3's
509 */ 498 */
510 while(decinum%3==0 && deciden%3==0) 499 while (decinum % 3 == 0 && deciden % 3 == 0) {
511 { 500 deciden /= 3;
512 deciden/=3; 501 decinum /= 3;
513 decinum/=3;
514 } 502 }
515 /* 503 /*
516 * 2's 504 * 2's
517 */ 505 */
518 while(decinum%2==0 && deciden%2==0) 506 while (decinum % 2 == 0 && deciden % 2 == 0) {
519 { 507 decinum /= 2;
520 decinum/=2; 508 deciden /= 2;
521 deciden/=2;
522 } 509 }
523 /* 510 /*
524 * Fudgyify 511 * Fudgyify
525 */ 512 */
526 while(deciden>32) 513 while (deciden > 32) {
527 { 514 deciden /= 2;
528 deciden/=2; 515 decinum = (decinum + 1) / 2;
529 decinum=(decinum+1)/2;
530 } 516 }
531 if(deciden==32) 517 if (deciden == 32)
532 deciden--; 518 deciden--;
533 pms_vert(deciden,decinum); 519 pms_vert(dev, deciden, decinum);
534} 520}
535 521
536static void pms_horzdeci(short decinum, short deciden) 522static void pms_horzdeci(struct pms *dev, short decinum, short deciden)
537{ 523{
538 if(decinum<=512) 524 if (decinum <= 512) {
539 { 525 if (decinum % 5 == 0) {
540 if(decinum%5==0) 526 decinum /= 5;
541 { 527 deciden /= 5;
542 decinum/=5;
543 deciden/=5;
544 } 528 }
545 } 529 } else {
546 else 530 decinum = 512;
547 { 531 deciden = 640; /* 768 would be ideal */
548 decinum=512;
549 deciden=640; /* 768 would be ideal */
550 } 532 }
551 533
552 while(((decinum|deciden)&1)==0) 534 while (((decinum | deciden) & 1) == 0) {
553 { 535 decinum >>= 1;
554 decinum>>=1; 536 deciden >>= 1;
555 deciden>>=1;
556 } 537 }
557 while(deciden>32) 538 while (deciden > 32) {
558 { 539 deciden >>= 1;
559 deciden>>=1; 540 decinum = (decinum + 1) >> 1;
560 decinum=(decinum+1)>>1;
561 } 541 }
562 if(deciden==32) 542 if (deciden == 32)
563 deciden--; 543 deciden--;
564 544
565 mvv_write(0x24, 0x80|deciden); 545 mvv_write(dev, 0x24, 0x80 | deciden);
566 mvv_write(0x25, decinum); 546 mvv_write(dev, 0x25, decinum);
567} 547}
568 548
569static void pms_resolution(short width, short height) 549static void pms_resolution(struct pms *dev, short width, short height)
570{ 550{
571 int fg_height; 551 int fg_height;
572 552
573 fg_height=height; 553 fg_height = height;
574 if(fg_height>280) 554 if (fg_height > 280)
575 fg_height=280; 555 fg_height = 280;
576 556
577 mvv_write(0x18, fg_height); 557 mvv_write(dev, 0x18, fg_height);
578 mvv_write(0x19, fg_height>>8); 558 mvv_write(dev, 0x19, fg_height >> 8);
579 559
580 if(standard==1) 560 if (dev->standard == 1) {
581 { 561 mvv_write(dev, 0x1a, 0xfc);
582 mvv_write(0x1A, 0xFC); 562 mvv_write(dev, 0x1b, 0x00);
583 mvv_write(0x1B, 0x00); 563 if (height > fg_height)
584 if(height>fg_height) 564 pms_vertdeci(dev, 240, 240);
585 pms_vertdeci(240,240);
586 else 565 else
587 pms_vertdeci(fg_height,240); 566 pms_vertdeci(dev, fg_height, 240);
588 } 567 } else {
589 else 568 mvv_write(dev, 0x1a, 0x1a);
590 { 569 mvv_write(dev, 0x1b, 0x01);
591 mvv_write(0x1A, 0x1A); 570 if (fg_height > 256)
592 mvv_write(0x1B, 0x01); 571 pms_vertdeci(dev, 270, 270);
593 if(fg_height>256)
594 pms_vertdeci(270,270);
595 else 572 else
596 pms_vertdeci(fg_height, 270); 573 pms_vertdeci(dev, fg_height, 270);
597 } 574 }
598 mvv_write(0x12,0); 575 mvv_write(dev, 0x12, 0);
599 mvv_write(0x13, MVVMEMORYWIDTH); 576 mvv_write(dev, 0x13, MVVMEMORYWIDTH);
600 mvv_write(0x42, 0x00); 577 mvv_write(dev, 0x42, 0x00);
601 mvv_write(0x43, 0x00); 578 mvv_write(dev, 0x43, 0x00);
602 mvv_write(0x44, MVVMEMORYWIDTH); 579 mvv_write(dev, 0x44, MVVMEMORYWIDTH);
603 580
604 mvv_write(0x22, width+8); 581 mvv_write(dev, 0x22, width + 8);
605 mvv_write(0x23, (width+8)>> 8); 582 mvv_write(dev, 0x23, (width + 8) >> 8);
606 583
607 if(standard==1) 584 if (dev->standard == 1)
608 pms_horzdeci(width,640); 585 pms_horzdeci(dev, width, 640);
609 else 586 else
610 pms_horzdeci(width+8, 768); 587 pms_horzdeci(dev, width + 8, 768);
611 588
612 mvv_write(0x30, mvv_read(0x30)&0xFE); 589 mvv_write(dev, 0x30, mvv_read(dev, 0x30) & 0xfe);
613 mvv_write(0x08, mvv_read(0x08)|0x01); 590 mvv_write(dev, 0x08, mvv_read(dev, 0x08) | 0x01);
614 mvv_write(0x01, mvv_read(0x01)&0xFD); 591 mvv_write(dev, 0x01, mvv_read(dev, 0x01) & 0xfd);
615 mvv_write(0x32, 0x00); 592 mvv_write(dev, 0x32, 0x00);
616 mvv_write(0x33, MVVMEMORYWIDTH); 593 mvv_write(dev, 0x33, MVVMEMORYWIDTH);
617} 594}
618 595
619 596
@@ -621,52 +598,49 @@ static void pms_resolution(short width, short height)
621 * Set Input 598 * Set Input
622 */ 599 */
623 600
624static void pms_vcrinput(short input) 601static void pms_vcrinput(struct pms *dev, short input)
625{ 602{
626 if(decoder==PHILIPS2) 603 if (dev->decoder == PHILIPS2)
627 pms_i2c_andor(0x8A,0x0D,0x7F,(input&1)<<7); 604 pms_i2c_andor(dev, 0x8a, 0x0d, 0x7f, (input & 1) << 7);
628 else if(decoder==PHILIPS1) 605 else if (dev->decoder == PHILIPS1)
629 pms_i2c_andor(0x42,0x0D,0x7F,(input&1)<<7); 606 pms_i2c_andor(dev, 0x42, 0x0d, 0x7f, (input & 1) << 7);
630} 607}
631 608
632 609
633static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int count) 610static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
634{ 611{
635 int y; 612 int y;
636 int dw = 2*dev->width; 613 int dw = 2 * dev->width;
637 614 char tmp[dw + 32]; /* using a temp buffer is faster than direct */
638 char tmp[dw+32]; /* using a temp buffer is faster than direct */
639 int cnt = 0; 615 int cnt = 0;
640 int len=0; 616 int len = 0;
641 unsigned char r8 = 0x5; /* value for reg8 */ 617 unsigned char r8 = 0x5; /* value for reg8 */
642 618
643 if (rgb555) 619 if (rgb555)
644 r8 |= 0x20; /* else use untranslated rgb = 565 */ 620 r8 |= 0x20; /* else use untranslated rgb = 565 */
645 mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */ 621 mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
646 622
647/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */ 623/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
648 624
649 for (y = 0; y < dev->height; y++ ) 625 for (y = 0; y < dev->height; y++) {
650 { 626 writeb(0, dev->mem); /* synchronisiert neue Zeile */
651 writeb(0, mem); /* synchronisiert neue Zeile */
652 627
653 /* 628 /*
654 * This is in truth a fifo, be very careful as if you 629 * This is in truth a fifo, be very careful as if you
655 * forgot this odd things will occur 8) 630 * forgot this odd things will occur 8)
656 */ 631 */
657 632
658 memcpy_fromio(tmp, mem, dw+32); /* discard 16 word */ 633 memcpy_fromio(tmp, dev->mem, dw + 32); /* discard 16 word */
659 cnt -= dev->height; 634 cnt -= dev->height;
660 while (cnt <= 0) 635 while (cnt <= 0) {
661 {
662 /* 636 /*
663 * Don't copy too far 637 * Don't copy too far
664 */ 638 */
665 int dt=dw; 639 int dt = dw;
666 if(dt+len>count) 640 if (dt + len > count)
667 dt=count-len; 641 dt = count - len;
668 cnt += dev->height; 642 cnt += dev->height;
669 if (copy_to_user(buf, tmp+32, dt)) 643 if (copy_to_user(buf, tmp + 32, dt))
670 return len ? len : -EFAULT; 644 return len ? len : -EFAULT;
671 buf += dt; 645 buf += dt;
672 len += dt; 646 len += dt;
@@ -682,182 +656,182 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int
682 656
683static long pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) 657static long pms_do_ioctl(struct file *file, unsigned int cmd, void *arg)
684{ 658{
685 struct video_device *dev = video_devdata(file); 659 struct pms *dev = video_drvdata(file);
686 struct pms_device *pd=(struct pms_device *)dev; 660
687 661 switch (cmd) {
688 switch(cmd) 662 case VIDIOCGCAP: {
689 { 663 struct video_capability *b = arg;
690 case VIDIOCGCAP: 664
691 { 665 strcpy(b->name, "Mediavision PMS");
692 struct video_capability *b = arg; 666 b->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
693 strcpy(b->name, "Mediavision PMS"); 667 b->channels = 4;
694 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES; 668 b->audios = 0;
695 b->channels = 4; 669 b->maxwidth = 640;
696 b->audios = 0; 670 b->maxheight = 480;
697 b->maxwidth = 640; 671 b->minwidth = 16;
698 b->maxheight = 480; 672 b->minheight = 16;
699 b->minwidth = 16; 673 return 0;
700 b->minheight = 16; 674 }
701 return 0; 675 case VIDIOCGCHAN: {
702 } 676 struct video_channel *v = arg;
703 case VIDIOCGCHAN: 677
704 { 678 if (v->channel < 0 || v->channel > 3)
705 struct video_channel *v = arg; 679 return -EINVAL;
706 if(v->channel<0 || v->channel>3) 680 v->flags = 0;
707 return -EINVAL; 681 v->tuners = 1;
708 v->flags=0; 682 /* Good question.. its composite or SVHS so.. */
709 v->tuners=1; 683 v->type = VIDEO_TYPE_CAMERA;
710 /* Good question.. its composite or SVHS so.. */ 684 switch (v->channel) {
711 v->type = VIDEO_TYPE_CAMERA; 685 case 0:
712 switch(v->channel) 686 strcpy(v->name, "Composite");
713 { 687 break;
714 case 0: 688 case 1:
715 strcpy(v->name, "Composite");break; 689 strcpy(v->name, "SVideo");
716 case 1: 690 break;
717 strcpy(v->name, "SVideo");break; 691 case 2:
718 case 2: 692 strcpy(v->name, "Composite(VCR)");
719 strcpy(v->name, "Composite(VCR)");break; 693 break;
720 case 3: 694 case 3:
721 strcpy(v->name, "SVideo(VCR)");break; 695 strcpy(v->name, "SVideo(VCR)");
722 } 696 break;
723 return 0;
724 }
725 case VIDIOCSCHAN:
726 {
727 struct video_channel *v = arg;
728 if(v->channel<0 || v->channel>3)
729 return -EINVAL;
730 mutex_lock(&pd->lock);
731 pms_videosource(v->channel&1);
732 pms_vcrinput(v->channel>>1);
733 mutex_unlock(&pd->lock);
734 return 0;
735 }
736 case VIDIOCGTUNER:
737 {
738 struct video_tuner *v = arg;
739 if(v->tuner)
740 return -EINVAL;
741 strcpy(v->name, "Format");
742 v->rangelow=0;
743 v->rangehigh=0;
744 v->flags= VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
745 switch(standard)
746 {
747 case 0:
748 v->mode = VIDEO_MODE_AUTO;
749 break;
750 case 1:
751 v->mode = VIDEO_MODE_NTSC;
752 break;
753 case 2:
754 v->mode = VIDEO_MODE_PAL;
755 break;
756 case 3:
757 v->mode = VIDEO_MODE_SECAM;
758 break;
759 }
760 return 0;
761 }
762 case VIDIOCSTUNER:
763 {
764 struct video_tuner *v = arg;
765 if(v->tuner)
766 return -EINVAL;
767 mutex_lock(&pd->lock);
768 switch(v->mode)
769 {
770 case VIDEO_MODE_AUTO:
771 pms_framerate(25);
772 pms_secamcross(0);
773 pms_format(0);
774 break;
775 case VIDEO_MODE_NTSC:
776 pms_framerate(30);
777 pms_secamcross(0);
778 pms_format(1);
779 break;
780 case VIDEO_MODE_PAL:
781 pms_framerate(25);
782 pms_secamcross(0);
783 pms_format(2);
784 break;
785 case VIDEO_MODE_SECAM:
786 pms_framerate(25);
787 pms_secamcross(1);
788 pms_format(2);
789 break;
790 default:
791 mutex_unlock(&pd->lock);
792 return -EINVAL;
793 }
794 mutex_unlock(&pd->lock);
795 return 0;
796 }
797 case VIDIOCGPICT:
798 {
799 struct video_picture *p = arg;
800 *p = pd->picture;
801 return 0;
802 } 697 }
803 case VIDIOCSPICT: 698 return 0;
804 { 699 }
805 struct video_picture *p = arg; 700 case VIDIOCSCHAN: {
806 if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16) 701 struct video_channel *v = arg;
807 ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15)))
808 return -EINVAL;
809 pd->picture= *p;
810 702
811 /* 703 if (v->channel < 0 || v->channel > 3)
812 * Now load the card. 704 return -EINVAL;
813 */ 705 mutex_lock(&dev->lock);
706 pms_videosource(dev, v->channel & 1);
707 pms_vcrinput(dev, v->channel >> 1);
708 mutex_unlock(&dev->lock);
709 return 0;
710 }
711 case VIDIOCGTUNER: {
712 struct video_tuner *v = arg;
814 713
815 mutex_lock(&pd->lock); 714 if (v->tuner)
816 pms_brightness(p->brightness>>8); 715 return -EINVAL;
817 pms_hue(p->hue>>8); 716 strcpy(v->name, "Format");
818 pms_colour(p->colour>>8); 717 v->rangelow = 0;
819 pms_contrast(p->contrast>>8); 718 v->rangehigh = 0;
820 mutex_unlock(&pd->lock); 719 v->flags = VIDEO_TUNER_PAL | VIDEO_TUNER_NTSC | VIDEO_TUNER_SECAM;
821 return 0; 720 switch (dev->standard) {
822 } 721 case 0:
823 case VIDIOCSWIN: 722 v->mode = VIDEO_MODE_AUTO;
824 { 723 break;
825 struct video_window *vw = arg; 724 case 1:
826 if(vw->flags) 725 v->mode = VIDEO_MODE_NTSC;
827 return -EINVAL; 726 break;
828 if(vw->clipcount) 727 case 2:
829 return -EINVAL; 728 v->mode = VIDEO_MODE_PAL;
830 if(vw->height<16||vw->height>480) 729 break;
831 return -EINVAL; 730 case 3:
832 if(vw->width<16||vw->width>640) 731 v->mode = VIDEO_MODE_SECAM;
833 return -EINVAL; 732 break;
834 pd->width=vw->width;
835 pd->height=vw->height;
836 mutex_lock(&pd->lock);
837 pms_resolution(pd->width, pd->height);
838 mutex_unlock(&pd->lock); /* Ok we figured out what to use from our wide choice */
839 return 0;
840 }
841 case VIDIOCGWIN:
842 {
843 struct video_window *vw = arg;
844 memset(vw,0,sizeof(*vw));
845 vw->width=pd->width;
846 vw->height=pd->height;
847 return 0;
848 } 733 }
849 case VIDIOCKEY: 734 return 0;
850 return 0; 735 }
851 case VIDIOCCAPTURE: 736 case VIDIOCSTUNER: {
852 case VIDIOCGFBUF: 737 struct video_tuner *v = arg;
853 case VIDIOCSFBUF: 738
854 case VIDIOCGFREQ: 739 if (v->tuner)
855 case VIDIOCSFREQ:
856 case VIDIOCGAUDIO:
857 case VIDIOCSAUDIO:
858 return -EINVAL; 740 return -EINVAL;
741 mutex_lock(&dev->lock);
742 switch (v->mode) {
743 case VIDEO_MODE_AUTO:
744 pms_framerate(dev, 25);
745 pms_secamcross(dev, 0);
746 pms_format(dev, 0);
747 break;
748 case VIDEO_MODE_NTSC:
749 pms_framerate(dev, 30);
750 pms_secamcross(dev, 0);
751 pms_format(dev, 1);
752 break;
753 case VIDEO_MODE_PAL:
754 pms_framerate(dev, 25);
755 pms_secamcross(dev, 0);
756 pms_format(dev, 2);
757 break;
758 case VIDEO_MODE_SECAM:
759 pms_framerate(dev, 25);
760 pms_secamcross(dev, 1);
761 pms_format(dev, 2);
762 break;
859 default: 763 default:
860 return -ENOIOCTLCMD; 764 mutex_unlock(&dev->lock);
765 return -EINVAL;
766 }
767 mutex_unlock(&dev->lock);
768 return 0;
769 }
770 case VIDIOCGPICT: {
771 struct video_picture *p = arg;
772
773 *p = dev->picture;
774 return 0;
775 }
776 case VIDIOCSPICT: {
777 struct video_picture *p = arg;
778
779 if (!((p->palette == VIDEO_PALETTE_RGB565 && p->depth == 16) ||
780 (p->palette == VIDEO_PALETTE_RGB555 && p->depth == 15)))
781 return -EINVAL;
782 dev->picture = *p;
783
784 /*
785 * Now load the card.
786 */
787
788 mutex_lock(&dev->lock);
789 pms_brightness(dev, p->brightness >> 8);
790 pms_hue(dev, p->hue >> 8);
791 pms_colour(dev, p->colour >> 8);
792 pms_contrast(dev, p->contrast >> 8);
793 mutex_unlock(&dev->lock);
794 return 0;
795 }
796 case VIDIOCSWIN: {
797 struct video_window *vw = arg;
798
799 if (vw->flags)
800 return -EINVAL;
801 if (vw->clipcount)
802 return -EINVAL;
803 if (vw->height < 16 || vw->height > 480)
804 return -EINVAL;
805 if (vw->width < 16 || vw->width > 640)
806 return -EINVAL;
807 dev->width = vw->width;
808 dev->height = vw->height;
809 mutex_lock(&dev->lock);
810 pms_resolution(dev, dev->width, dev->height);
811 /* Ok we figured out what to use from our wide choice */
812 mutex_unlock(&dev->lock);
813 return 0;
814 }
815 case VIDIOCGWIN: {
816 struct video_window *vw = arg;
817
818 memset(vw, 0, sizeof(*vw));
819 vw->width = dev->width;
820 vw->height = dev->height;
821 return 0;
822 }
823 case VIDIOCKEY:
824 return 0;
825 case VIDIOCCAPTURE:
826 case VIDIOCGFBUF:
827 case VIDIOCSFBUF:
828 case VIDIOCGFREQ:
829 case VIDIOCSFREQ:
830 case VIDIOCGAUDIO:
831 case VIDIOCSAUDIO:
832 return -EINVAL;
833 default:
834 return -ENOIOCTLCMD;
861 } 835 }
862 return 0; 836 return 0;
863} 837}
@@ -871,30 +845,27 @@ static long pms_ioctl(struct file *file,
871static ssize_t pms_read(struct file *file, char __user *buf, 845static ssize_t pms_read(struct file *file, char __user *buf,
872 size_t count, loff_t *ppos) 846 size_t count, loff_t *ppos)
873{ 847{
874 struct video_device *v = video_devdata(file); 848 struct pms *dev = video_drvdata(file);
875 struct pms_device *pd=(struct pms_device *)v;
876 int len; 849 int len;
877 850
878 mutex_lock(&pd->lock); 851 mutex_lock(&dev->lock);
879 len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count); 852 len = pms_capture(dev, buf, (dev->picture.depth == 16) ? 0 : 1, count);
880 mutex_unlock(&pd->lock); 853 mutex_unlock(&dev->lock);
881 return len; 854 return len;
882} 855}
883 856
884static int pms_exclusive_open(struct file *file) 857static int pms_exclusive_open(struct file *file)
885{ 858{
886 struct video_device *v = video_devdata(file); 859 struct pms *dev = video_drvdata(file);
887 struct pms_device *pd = (struct pms_device *)v;
888 860
889 return test_and_set_bit(0, &pd->in_use) ? -EBUSY : 0; 861 return test_and_set_bit(0, &dev->in_use) ? -EBUSY : 0;
890} 862}
891 863
892static int pms_exclusive_release(struct file *file) 864static int pms_exclusive_release(struct file *file)
893{ 865{
894 struct video_device *v = video_devdata(file); 866 struct pms *dev = video_drvdata(file);
895 struct pms_device *pd = (struct pms_device *)v;
896 867
897 clear_bit(0, &pd->in_use); 868 clear_bit(0, &dev->in_use);
898 return 0; 869 return 0;
899} 870}
900 871
@@ -906,74 +877,62 @@ static const struct v4l2_file_operations pms_fops = {
906 .read = pms_read, 877 .read = pms_read,
907}; 878};
908 879
909static struct video_device pms_template=
910{
911 .name = "Mediavision PMS",
912 .fops = &pms_fops,
913 .release = video_device_release_empty,
914};
915
916static struct pms_device pms_device;
917
918 880
919/* 881/*
920 * Probe for and initialise the Mediavision PMS 882 * Probe for and initialise the Mediavision PMS
921 */ 883 */
922 884
923static int init_mediavision(void) 885static int init_mediavision(struct pms *dev)
924{ 886{
925 int id; 887 int id;
926 int idec, decst; 888 int idec, decst;
927 int i; 889 int i;
928 890 static const unsigned char i2c_defs[] = {
929 unsigned char i2c_defs[]={ 891 0x4c, 0x30, 0x00, 0xe8,
930 0x4C,0x30,0x00,0xE8, 892 0xb6, 0xe2, 0x00, 0x00,
931 0xB6,0xE2,0x00,0x00, 893 0xff, 0xff, 0x00, 0x00,
932 0xFF,0xFF,0x00,0x00, 894 0x00, 0x00, 0x78, 0x98,
933 0x00,0x00,0x78,0x98, 895 0x00, 0x00, 0x00, 0x00,
934 0x00,0x00,0x00,0x00, 896 0x34, 0x0a, 0xf4, 0xce,
935 0x34,0x0A,0xF4,0xCE, 897 0xe4
936 0xE4
937 }; 898 };
938 899
939 mem = ioremap(mem_base, 0x800); 900 dev->mem = ioremap(mem_base, 0x800);
940 if (!mem) 901 if (!dev->mem)
941 return -ENOMEM; 902 return -ENOMEM;
942 903
943 if (!request_region(0x9A01, 1, "Mediavision PMS config")) 904 if (!request_region(0x9a01, 1, "Mediavision PMS config")) {
944 { 905 printk(KERN_WARNING "mediavision: unable to detect: 0x9a01 in use.\n");
945 printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n"); 906 iounmap(dev->mem);
946 iounmap(mem);
947 return -EBUSY; 907 return -EBUSY;
948 } 908 }
949 if (!request_region(io_port, 3, "Mediavision PMS")) 909 if (!request_region(dev->io, 3, "Mediavision PMS")) {
950 { 910 printk(KERN_WARNING "mediavision: I/O port %d in use.\n", dev->io);
951 printk(KERN_WARNING "mediavision: I/O port %d in use.\n", io_port); 911 release_region(0x9a01, 1);
952 release_region(0x9A01, 1); 912 iounmap(dev->mem);
953 iounmap(mem);
954 return -EBUSY; 913 return -EBUSY;
955 } 914 }
956 outb(0xB8, 0x9A01); /* Unlock */ 915 outb(0xb8, 0x9a01); /* Unlock */
957 outb(io_port>>4, 0x9A01); /* Set IO port */ 916 outb(dev->io >> 4, 0x9a01); /* Set IO port */
958 917
959 918
960 id=mvv_read(3); 919 id = mvv_read(dev, 3);
961 decst=pms_i2c_stat(0x43); 920 decst = pms_i2c_stat(dev, 0x43);
962 921
963 if(decst!=-1) 922 if (decst != -1)
964 idec=2; 923 idec = 2;
965 else if(pms_i2c_stat(0xb9)!=-1) 924 else if (pms_i2c_stat(dev, 0xb9) != -1)
966 idec=3; 925 idec = 3;
967 else if(pms_i2c_stat(0x8b)!=-1) 926 else if (pms_i2c_stat(dev, 0x8b) != -1)
968 idec=1; 927 idec = 1;
969 else 928 else
970 idec=0; 929 idec = 0;
971 930
972 printk(KERN_INFO "PMS type is %d\n", idec); 931 printk(KERN_INFO "PMS type is %d\n", idec);
973 if(idec == 0) { 932 if (idec == 0) {
974 release_region(io_port, 3); 933 release_region(dev->io, 3);
975 release_region(0x9A01, 1); 934 release_region(0x9a01, 1);
976 iounmap(mem); 935 iounmap(dev->mem);
977 return -ENODEV; 936 return -ENODEV;
978 } 937 }
979 938
@@ -981,51 +940,50 @@ static int init_mediavision(void)
981 * Ok we have a PMS of some sort 940 * Ok we have a PMS of some sort
982 */ 941 */
983 942
984 mvv_write(0x04, mem_base>>12); /* Set the memory area */ 943 mvv_write(dev, 0x04, mem_base >> 12); /* Set the memory area */
985 944
986 /* Ok now load the defaults */ 945 /* Ok now load the defaults */
987 946
988 for(i=0;i<0x19;i++) 947 for (i = 0; i < 0x19; i++) {
989 { 948 if (i2c_defs[i] == 0xff)
990 if(i2c_defs[i]==0xFF) 949 pms_i2c_andor(dev, 0x8a, i, 0x07, 0x00);
991 pms_i2c_andor(0x8A, i, 0x07,0x00);
992 else 950 else
993 pms_i2c_write(0x8A, i, i2c_defs[i]); 951 pms_i2c_write(dev, 0x8a, i, i2c_defs[i]);
994 } 952 }
995 953
996 pms_i2c_write(0xB8,0x00,0x12); 954 pms_i2c_write(dev, 0xb8, 0x00, 0x12);
997 pms_i2c_write(0xB8,0x04,0x00); 955 pms_i2c_write(dev, 0xb8, 0x04, 0x00);
998 pms_i2c_write(0xB8,0x07,0x00); 956 pms_i2c_write(dev, 0xb8, 0x07, 0x00);
999 pms_i2c_write(0xB8,0x08,0x00); 957 pms_i2c_write(dev, 0xb8, 0x08, 0x00);
1000 pms_i2c_write(0xB8,0x09,0xFF); 958 pms_i2c_write(dev, 0xb8, 0x09, 0xff);
1001 pms_i2c_write(0xB8,0x0A,0x00); 959 pms_i2c_write(dev, 0xb8, 0x0a, 0x00);
1002 pms_i2c_write(0xB8,0x0B,0x10); 960 pms_i2c_write(dev, 0xb8, 0x0b, 0x10);
1003 pms_i2c_write(0xB8,0x10,0x03); 961 pms_i2c_write(dev, 0xb8, 0x10, 0x03);
1004 962
1005 mvv_write(0x01, 0x00); 963 mvv_write(dev, 0x01, 0x00);
1006 mvv_write(0x05, 0xA0); 964 mvv_write(dev, 0x05, 0xa0);
1007 mvv_write(0x08, 0x25); 965 mvv_write(dev, 0x08, 0x25);
1008 mvv_write(0x09, 0x00); 966 mvv_write(dev, 0x09, 0x00);
1009 mvv_write(0x0A, 0x20|MVVMEMORYWIDTH); 967 mvv_write(dev, 0x0a, 0x20 | MVVMEMORYWIDTH);
1010 968
1011 mvv_write(0x10, 0x02); 969 mvv_write(dev, 0x10, 0x02);
1012 mvv_write(0x1E, 0x0C); 970 mvv_write(dev, 0x1e, 0x0c);
1013 mvv_write(0x1F, 0x03); 971 mvv_write(dev, 0x1f, 0x03);
1014 mvv_write(0x26, 0x06); 972 mvv_write(dev, 0x26, 0x06);
1015 973
1016 mvv_write(0x2B, 0x00); 974 mvv_write(dev, 0x2b, 0x00);
1017 mvv_write(0x2C, 0x20); 975 mvv_write(dev, 0x2c, 0x20);
1018 mvv_write(0x2D, 0x00); 976 mvv_write(dev, 0x2d, 0x00);
1019 mvv_write(0x2F, 0x70); 977 mvv_write(dev, 0x2f, 0x70);
1020 mvv_write(0x32, 0x00); 978 mvv_write(dev, 0x32, 0x00);
1021 mvv_write(0x33, MVVMEMORYWIDTH); 979 mvv_write(dev, 0x33, MVVMEMORYWIDTH);
1022 mvv_write(0x34, 0x00); 980 mvv_write(dev, 0x34, 0x00);
1023 mvv_write(0x35, 0x00); 981 mvv_write(dev, 0x35, 0x00);
1024 mvv_write(0x3A, 0x80); 982 mvv_write(dev, 0x3a, 0x80);
1025 mvv_write(0x3B, 0x10); 983 mvv_write(dev, 0x3b, 0x10);
1026 mvv_write(0x20, 0x00); 984 mvv_write(dev, 0x20, 0x00);
1027 mvv_write(0x21, 0x00); 985 mvv_write(dev, 0x21, 0x00);
1028 mvv_write(0x30, 0x22); 986 mvv_write(dev, 0x30, 0x22);
1029 return 0; 987 return 0;
1030} 988}
1031 989
@@ -1038,53 +996,70 @@ static int enable;
1038module_param(enable, int, 0); 996module_param(enable, int, 0);
1039#endif 997#endif
1040 998
1041static int __init init_pms_cards(void) 999static int __init pms_init(void)
1042{ 1000{
1043 printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n"); 1001 struct pms *dev = &pms_card;
1002 struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
1003 int res;
1004
1005 strlcpy(v4l2_dev->name, "pms", sizeof(v4l2_dev->name));
1006
1007 v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.03\n");
1044 1008
1045#ifndef MODULE 1009#ifndef MODULE
1046 if (!enable) { 1010 if (!enable) {
1047 printk(KERN_INFO "PMS: not enabled, use pms.enable=1 to " 1011 v4l2_err(v4l2_dev,
1048 "probe\n"); 1012 "PMS: not enabled, use pms.enable=1 to probe\n");
1049 return -ENODEV; 1013 return -ENODEV;
1050 } 1014 }
1051#endif 1015#endif
1052 1016
1053 data_port = io_port +1; 1017 dev->decoder = PHILIPS2;
1018 dev->io = io_port;
1019 dev->data = io_port + 1;
1054 1020
1055 if(init_mediavision()) 1021 if (init_mediavision(dev)) {
1056 { 1022 v4l2_err(v4l2_dev, "Board not found.\n");
1057 printk(KERN_INFO "Board not found.\n");
1058 return -ENODEV; 1023 return -ENODEV;
1059 } 1024 }
1060 memcpy(&pms_device, &pms_template, sizeof(pms_template));
1061 mutex_init(&pms_device.lock);
1062 pms_device.height=240;
1063 pms_device.width=320;
1064 pms_swsense(75);
1065 pms_resolution(320,240);
1066 return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER, video_nr);
1067}
1068
1069module_param(io_port, int, 0);
1070module_param(mem_base, int, 0);
1071module_param(video_nr, int, 0);
1072MODULE_LICENSE("GPL");
1073 1025
1026 res = v4l2_device_register(NULL, v4l2_dev);
1027 if (res < 0) {
1028 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
1029 return res;
1030 }
1074 1031
1075static void __exit shutdown_mediavision(void) 1032 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
1076{ 1033 dev->vdev.v4l2_dev = v4l2_dev;
1077 release_region(io_port,3); 1034 dev->vdev.fops = &pms_fops;
1078 release_region(0x9A01, 1); 1035 dev->vdev.release = video_device_release_empty;
1036 video_set_drvdata(&dev->vdev, dev);
1037 mutex_init(&dev->lock);
1038 dev->height = 240;
1039 dev->width = 320;
1040 pms_swsense(dev, 75);
1041 pms_resolution(dev, 320, 240);
1042 pms_videosource(dev, 0);
1043 pms_vcrinput(dev, 0);
1044 if (video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1045 v4l2_device_unregister(&dev->v4l2_dev);
1046 release_region(dev->io, 3);
1047 release_region(0x9a01, 1);
1048 iounmap(dev->mem);
1049 return -EINVAL;
1050 }
1051 return 0;
1079} 1052}
1080 1053
1081static void __exit cleanup_pms_module(void) 1054static void __exit pms_exit(void)
1082{ 1055{
1083 shutdown_mediavision(); 1056 struct pms *dev = &pms_card;
1084 video_unregister_device((struct video_device *)&pms_device);
1085 iounmap(mem);
1086}
1087 1057
1088module_init(init_pms_cards); 1058 video_unregister_device(&dev->vdev);
1089module_exit(cleanup_pms_module); 1059 release_region(dev->io, 3);
1060 release_region(0x9a01, 1);
1061 iounmap(dev->mem);
1062}
1090 1063
1064module_init(pms_init);
1065module_exit(pms_exit);