]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/adv7175.c
1a2b111897d508de2daa036bb97d68d9a4c061d0
[linux-2.6-omap-h63xx.git] / drivers / media / video / adv7175.c
1 /* 
2  *  adv7175 - adv7175a video encoder driver version 0.0.3
3  *
4  * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
5  * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
6  * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
7  *    - some corrections for Pinnacle Systems Inc. DC10plus card.
8  *
9  * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
10  *    - moved over to linux>=2.4.x i2c protocol (9/9/2002)
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  */
26
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/delay.h>
30 #include <linux/errno.h>
31 #include <linux/fs.h>
32 #include <linux/kernel.h>
33 #include <linux/major.h>
34 #include <linux/slab.h>
35 #include <linux/mm.h>
36 #include <linux/pci.h>
37 #include <linux/signal.h>
38 #include <asm/io.h>
39 #include <asm/pgtable.h>
40 #include <asm/page.h>
41 #include <linux/sched.h>
42 #include <linux/types.h>
43
44 #include <linux/videodev.h>
45 #include <asm/uaccess.h>
46
47 MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
48 MODULE_AUTHOR("Dave Perks");
49 MODULE_LICENSE("GPL");
50
51 #include <linux/i2c.h>
52 #include <linux/i2c-dev.h>
53
54 #define I2C_NAME(s) (s)->name
55
56 #include <linux/video_encoder.h>
57
58 static int debug = 0;
59 module_param(debug, int, 0);
60 MODULE_PARM_DESC(debug, "Debug level (0-1)");
61
62 #define dprintk(num, format, args...) \
63         do { \
64                 if (debug >= num) \
65                         printk(format, ##args); \
66         } while (0)
67
68 /* ----------------------------------------------------------------------- */
69
70 struct adv7175 {
71         int norm;
72         int input;
73         int enable;
74         int bright;
75         int contrast;
76         int hue;
77         int sat;
78 };
79
80 #define   I2C_ADV7175        0xd4
81 #define   I2C_ADV7176        0x54
82
83 static char adv7175_name[] = "adv7175";
84 static char adv7176_name[] = "adv7176";
85
86 static char *inputs[] = { "pass_through", "play_back", "color_bar" };
87 static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
88
89 /* ----------------------------------------------------------------------- */
90
91 static inline int
92 adv7175_write (struct i2c_client *client,
93                u8                 reg,
94                u8                 value)
95 {
96         return i2c_smbus_write_byte_data(client, reg, value);
97 }
98
99 static inline int
100 adv7175_read (struct i2c_client *client,
101               u8                 reg)
102 {
103         return i2c_smbus_read_byte_data(client, reg);
104 }
105
106 static int
107 adv7175_write_block (struct i2c_client *client,
108                      const u8          *data,
109                      unsigned int       len)
110 {
111         int ret = -1;
112         u8 reg;
113
114         /* the adv7175 has an autoincrement function, use it if
115          * the adapter understands raw I2C */
116         if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
117                 /* do raw I2C, not smbus compatible */
118                 u8 block_data[32];
119                 int block_len;
120
121                 while (len >= 2) {
122                         block_len = 0;
123                         block_data[block_len++] = reg = data[0];
124                         do {
125                                 block_data[block_len++] = data[1];
126                                 reg++;
127                                 len -= 2;
128                                 data += 2;
129                         } while (len >= 2 && data[0] == reg &&
130                                  block_len < 32);
131                         if ((ret = i2c_master_send(client, block_data,
132                                                    block_len)) < 0)
133                                 break;
134                 }
135         } else {
136                 /* do some slow I2C emulation kind of thing */
137                 while (len >= 2) {
138                         reg = *data++;
139                         if ((ret = adv7175_write(client, reg,
140                                                  *data++)) < 0)
141                                 break;
142                         len -= 2;
143                 }
144         }
145
146         return ret;
147 }
148
149 static void
150 set_subcarrier_freq (struct i2c_client *client,
151                      int                pass_through)
152 {
153         /* for some reason pass_through NTSC needs
154          * a different sub-carrier freq to remain stable. */
155         if(pass_through)
156                 adv7175_write(client, 0x02, 0x00);
157         else
158                 adv7175_write(client, 0x02, 0x55);
159
160         adv7175_write(client, 0x03, 0x55);
161         adv7175_write(client, 0x04, 0x55);
162         adv7175_write(client, 0x05, 0x25);
163 }
164
165 /* ----------------------------------------------------------------------- */
166 // Output filter:  S-Video  Composite
167
168 #define MR050       0x11        //0x09
169 #define MR060       0x14        //0x0c
170
171 //---------------------------------------------------------------------------
172
173 #define TR0MODE     0x46
174 #define TR0RST      0x80
175
176 #define TR1CAPT     0x80
177 #define TR1PLAY     0x00
178
179 static const unsigned char init_common[] = {
180
181         0x00, MR050,            /* MR0, PAL enabled */
182         0x01, 0x00,             /* MR1 */
183         0x02, 0x0c,             /* subc. freq. */
184         0x03, 0x8c,             /* subc. freq. */
185         0x04, 0x79,             /* subc. freq. */
186         0x05, 0x26,             /* subc. freq. */
187         0x06, 0x40,             /* subc. phase */
188
189         0x07, TR0MODE,          /* TR0, 16bit */
190         0x08, 0x21,             /*  */
191         0x09, 0x00,             /*  */
192         0x0a, 0x00,             /*  */
193         0x0b, 0x00,             /*  */
194         0x0c, TR1CAPT,          /* TR1 */
195         0x0d, 0x4f,             /* MR2 */
196         0x0e, 0x00,             /*  */
197         0x0f, 0x00,             /*  */
198         0x10, 0x00,             /*  */
199         0x11, 0x00,             /*  */
200 };
201
202 static const unsigned char init_pal[] = {
203         0x00, MR050,            /* MR0, PAL enabled */
204         0x01, 0x00,             /* MR1 */
205         0x02, 0x0c,             /* subc. freq. */
206         0x03, 0x8c,             /* subc. freq. */
207         0x04, 0x79,             /* subc. freq. */
208         0x05, 0x26,             /* subc. freq. */
209         0x06, 0x40,             /* subc. phase */
210 };
211
212 static const unsigned char init_ntsc[] = {
213         0x00, MR060,            /* MR0, NTSC enabled */
214         0x01, 0x00,             /* MR1 */
215         0x02, 0x55,             /* subc. freq. */
216         0x03, 0x55,             /* subc. freq. */
217         0x04, 0x55,             /* subc. freq. */
218         0x05, 0x25,             /* subc. freq. */
219         0x06, 0x1a,             /* subc. phase */
220 };
221
222 static int
223 adv7175_command (struct i2c_client *client,
224                  unsigned int       cmd,
225                  void              *arg)
226 {
227         struct adv7175 *encoder = i2c_get_clientdata(client);
228
229         switch (cmd) {
230
231         case 0:
232                 /* This is just for testing!!! */
233                 adv7175_write_block(client, init_common,
234                                     sizeof(init_common));
235                 adv7175_write(client, 0x07, TR0MODE | TR0RST);
236                 adv7175_write(client, 0x07, TR0MODE);
237                 break;
238
239         case ENCODER_GET_CAPABILITIES:
240         {
241                 struct video_encoder_capability *cap = arg;
242
243                 cap->flags = VIDEO_ENCODER_PAL |
244                              VIDEO_ENCODER_NTSC |
245                              VIDEO_ENCODER_SECAM; /* well, hacky */
246                 cap->inputs = 2;
247                 cap->outputs = 1;
248         }
249                 break;
250
251         case ENCODER_SET_NORM:
252         {
253                 int iarg = *(int *) arg;
254
255                 switch (iarg) {
256
257                 case VIDEO_MODE_NTSC:
258                         adv7175_write_block(client, init_ntsc,
259                                             sizeof(init_ntsc));
260                         if (encoder->input == 0)
261                                 adv7175_write(client, 0x0d, 0x4f);      // Enable genlock
262                         adv7175_write(client, 0x07, TR0MODE | TR0RST);
263                         adv7175_write(client, 0x07, TR0MODE);
264                         break;
265
266                 case VIDEO_MODE_PAL:
267                         adv7175_write_block(client, init_pal,
268                                             sizeof(init_pal));
269                         if (encoder->input == 0)
270                                 adv7175_write(client, 0x0d, 0x4f);      // Enable genlock
271                         adv7175_write(client, 0x07, TR0MODE | TR0RST);
272                         adv7175_write(client, 0x07, TR0MODE);
273                         break;
274
275                 case VIDEO_MODE_SECAM:  // WARNING! ADV7176 does not support SECAM.
276                         /* This is an attempt to convert
277                          * SECAM->PAL (typically it does not work
278                          * due to genlock: when decoder is in SECAM
279                          * and encoder in in PAL the subcarrier can
280                          * not be syncronized with horizontal
281                          * quency) */
282                         adv7175_write_block(client, init_pal,
283                                             sizeof(init_pal));
284                         if (encoder->input == 0)
285                                 adv7175_write(client, 0x0d, 0x49);      // Disable genlock
286                         adv7175_write(client, 0x07, TR0MODE | TR0RST);
287                         adv7175_write(client, 0x07, TR0MODE);
288                         break;
289                 default:
290                         dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
291                                 I2C_NAME(client), iarg);
292                         return -EINVAL;
293
294                 }
295                 dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
296                         norms[iarg]);
297                 encoder->norm = iarg;
298         }
299                 break;
300
301         case ENCODER_SET_INPUT:
302         {
303                 int iarg = *(int *) arg;
304
305                 /* RJ: *iarg = 0: input is from SAA7110
306                  *iarg = 1: input is from ZR36060
307                  *iarg = 2: color bar */
308
309                 switch (iarg) {
310
311                 case 0:
312                         adv7175_write(client, 0x01, 0x00);
313
314                         if (encoder->norm == VIDEO_MODE_NTSC)
315                                 set_subcarrier_freq(client, 1);
316
317                         adv7175_write(client, 0x0c, TR1CAPT);   /* TR1 */
318                         if (encoder->norm == VIDEO_MODE_SECAM)
319                                 adv7175_write(client, 0x0d, 0x49);      // Disable genlock
320                         else
321                                 adv7175_write(client, 0x0d, 0x4f);      // Enable genlock
322                         adv7175_write(client, 0x07, TR0MODE | TR0RST);
323                         adv7175_write(client, 0x07, TR0MODE);
324                         //udelay(10);
325                         break;
326
327                 case 1:
328                         adv7175_write(client, 0x01, 0x00);
329
330                         if (encoder->norm == VIDEO_MODE_NTSC)
331                                 set_subcarrier_freq(client, 0);
332
333                         adv7175_write(client, 0x0c, TR1PLAY);   /* TR1 */
334                         adv7175_write(client, 0x0d, 0x49);
335                         adv7175_write(client, 0x07, TR0MODE | TR0RST);
336                         adv7175_write(client, 0x07, TR0MODE);
337                         //udelay(10);
338                         break;
339
340                 case 2:
341                         adv7175_write(client, 0x01, 0x80);
342
343                         if (encoder->norm == VIDEO_MODE_NTSC)
344                                 set_subcarrier_freq(client, 0);
345
346                         adv7175_write(client, 0x0d, 0x49);
347                         adv7175_write(client, 0x07, TR0MODE | TR0RST);
348                         adv7175_write(client, 0x07, TR0MODE);
349                         //udelay(10);
350                         break;
351
352                 default:
353                         dprintk(1, KERN_ERR "%s: illegal input: %d\n",
354                                 I2C_NAME(client), iarg);
355                         return -EINVAL;
356
357                 }
358                 dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
359                         inputs[iarg]);
360                 encoder->input = iarg;
361         }
362                 break;
363
364         case ENCODER_SET_OUTPUT:
365         {
366                 int *iarg = arg;
367
368                 /* not much choice of outputs */
369                 if (*iarg != 0) {
370                         return -EINVAL;
371                 }
372         }
373                 break;
374
375         case ENCODER_ENABLE_OUTPUT:
376         {
377                 int *iarg = arg;
378
379                 encoder->enable = !!*iarg;
380         }
381                 break;
382
383         default:
384                 return -EINVAL;
385         }
386
387         return 0;
388 }
389
390 /* ----------------------------------------------------------------------- */
391
392 /*
393  * Generic i2c probe
394  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
395  */
396 static unsigned short normal_i2c[] =
397     { I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
398         I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1,
399         I2C_CLIENT_END
400 };
401
402 static unsigned short ignore = I2C_CLIENT_END;
403                                                                                 
404 static struct i2c_client_address_data addr_data = {
405         .normal_i2c             = normal_i2c,
406         .probe                  = &ignore,
407         .ignore                 = &ignore,
408 };
409
410 static struct i2c_driver i2c_driver_adv7175;
411
412 static int
413 adv7175_detect_client (struct i2c_adapter *adapter,
414                        int                 address,
415                        int                 kind)
416 {
417         int i;
418         struct i2c_client *client;
419         struct adv7175 *encoder;
420         char *dname;
421
422         dprintk(1,
423                 KERN_INFO
424                 "adv7175.c: detecting adv7175 client on address 0x%x\n",
425                 address << 1);
426
427         /* Check if the adapter supports the needed features */
428         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
429                 return 0;
430
431         client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
432         if (client == 0)
433                 return -ENOMEM;
434         client->addr = address;
435         client->adapter = adapter;
436         client->driver = &i2c_driver_adv7175;
437         if ((client->addr == I2C_ADV7175 >> 1) ||
438             (client->addr == (I2C_ADV7175 >> 1) + 1)) {
439                 dname = adv7175_name;
440         } else if ((client->addr == I2C_ADV7176 >> 1) ||
441                    (client->addr == (I2C_ADV7176 >> 1) + 1)) {
442                 dname = adv7176_name;
443         } else {
444                 /* We should never get here!!! */
445                 kfree(client);
446                 return 0;
447         }
448         strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
449
450         encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
451         if (encoder == NULL) {
452                 kfree(client);
453                 return -ENOMEM;
454         }
455         encoder->norm = VIDEO_MODE_PAL;
456         encoder->input = 0;
457         encoder->enable = 1;
458         i2c_set_clientdata(client, encoder);
459
460         i = i2c_attach_client(client);
461         if (i) {
462                 kfree(client);
463                 kfree(encoder);
464                 return i;
465         }
466
467         i = adv7175_write_block(client, init_common, sizeof(init_common));
468         if (i >= 0) {
469                 i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
470                 i = adv7175_write(client, 0x07, TR0MODE);
471                 i = adv7175_read(client, 0x12);
472                 dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%x\n",
473                         I2C_NAME(client), i & 1, client->addr << 1);
474         }
475         if (i < 0) {
476                 dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
477                         I2C_NAME(client), i);
478         }
479
480         return 0;
481 }
482
483 static int
484 adv7175_attach_adapter (struct i2c_adapter *adapter)
485 {
486         dprintk(1,
487                 KERN_INFO
488                 "adv7175.c: starting probe for adapter %s (0x%x)\n",
489                 I2C_NAME(adapter), adapter->id);
490         return i2c_probe(adapter, &addr_data, &adv7175_detect_client);
491 }
492
493 static int
494 adv7175_detach_client (struct i2c_client *client)
495 {
496         struct adv7175 *encoder = i2c_get_clientdata(client);
497         int err;
498
499         err = i2c_detach_client(client);
500         if (err) {
501                 return err;
502         }
503
504         kfree(encoder);
505         kfree(client);
506
507         return 0;
508 }
509
510 /* ----------------------------------------------------------------------- */
511
512 static struct i2c_driver i2c_driver_adv7175 = {
513         .driver = {
514                 .name = "adv7175",      /* name */
515         },
516
517         .id = I2C_DRIVERID_ADV7175,
518
519         .attach_adapter = adv7175_attach_adapter,
520         .detach_client = adv7175_detach_client,
521         .command = adv7175_command,
522 };
523
524 static int __init
525 adv7175_init (void)
526 {
527         return i2c_add_driver(&i2c_driver_adv7175);
528 }
529
530 static void __exit
531 adv7175_exit (void)
532 {
533         i2c_del_driver(&i2c_driver_adv7175);
534 }
535
536 module_init(adv7175_init);
537 module_exit(adv7175_exit);