omap_vout: fix compiler warning
[pandora-kernel.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/types.h>
29 #include <linux/slab.h>
30 #include <linux/ioctl.h>
31 #include <asm/uaccess.h>
32 #include <linux/i2c.h>
33 #include <linux/videodev2.h>
34 #include <media/v4l2-device.h>
35 #include <media/v4l2-chip-ident.h>
36
37 MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
38 MODULE_AUTHOR("Dave Perks");
39 MODULE_LICENSE("GPL");
40
41 #define   I2C_ADV7175        0xd4
42 #define   I2C_ADV7176        0x54
43
44
45 static int debug;
46 module_param(debug, int, 0);
47 MODULE_PARM_DESC(debug, "Debug level (0-1)");
48
49 /* ----------------------------------------------------------------------- */
50
51 struct adv7175 {
52         struct v4l2_subdev sd;
53         v4l2_std_id norm;
54         int input;
55 };
56
57 static inline struct adv7175 *to_adv7175(struct v4l2_subdev *sd)
58 {
59         return container_of(sd, struct adv7175, sd);
60 }
61
62 static char *inputs[] = { "pass_through", "play_back", "color_bar" };
63
64 static enum v4l2_mbus_pixelcode adv7175_codes[] = {
65         V4L2_MBUS_FMT_UYVY8_2X8,
66         V4L2_MBUS_FMT_UYVY8_1X16,
67 };
68
69 /* ----------------------------------------------------------------------- */
70
71 static inline int adv7175_write(struct v4l2_subdev *sd, u8 reg, u8 value)
72 {
73         struct i2c_client *client = v4l2_get_subdevdata(sd);
74
75         return i2c_smbus_write_byte_data(client, reg, value);
76 }
77
78 static inline int adv7175_read(struct v4l2_subdev *sd, u8 reg)
79 {
80         struct i2c_client *client = v4l2_get_subdevdata(sd);
81
82         return i2c_smbus_read_byte_data(client, reg);
83 }
84
85 static int adv7175_write_block(struct v4l2_subdev *sd,
86                      const u8 *data, unsigned int len)
87 {
88         struct i2c_client *client = v4l2_get_subdevdata(sd);
89         int ret = -1;
90         u8 reg;
91
92         /* the adv7175 has an autoincrement function, use it if
93          * the adapter understands raw I2C */
94         if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
95                 /* do raw I2C, not smbus compatible */
96                 u8 block_data[32];
97                 int block_len;
98
99                 while (len >= 2) {
100                         block_len = 0;
101                         block_data[block_len++] = reg = data[0];
102                         do {
103                                 block_data[block_len++] = data[1];
104                                 reg++;
105                                 len -= 2;
106                                 data += 2;
107                         } while (len >= 2 && data[0] == reg && block_len < 32);
108                         ret = i2c_master_send(client, block_data, block_len);
109                         if (ret < 0)
110                                 break;
111                 }
112         } else {
113                 /* do some slow I2C emulation kind of thing */
114                 while (len >= 2) {
115                         reg = *data++;
116                         ret = adv7175_write(sd, reg, *data++);
117                         if (ret < 0)
118                                 break;
119                         len -= 2;
120                 }
121         }
122
123         return ret;
124 }
125
126 static void set_subcarrier_freq(struct v4l2_subdev *sd, int pass_through)
127 {
128         /* for some reason pass_through NTSC needs
129          * a different sub-carrier freq to remain stable. */
130         if (pass_through)
131                 adv7175_write(sd, 0x02, 0x00);
132         else
133                 adv7175_write(sd, 0x02, 0x55);
134
135         adv7175_write(sd, 0x03, 0x55);
136         adv7175_write(sd, 0x04, 0x55);
137         adv7175_write(sd, 0x05, 0x25);
138 }
139
140 /* ----------------------------------------------------------------------- */
141 /* Output filter:  S-Video  Composite */
142
143 #define MR050       0x11        /* 0x09 */
144 #define MR060       0x14        /* 0x0c */
145
146 /* ----------------------------------------------------------------------- */
147
148 #define TR0MODE     0x46
149 #define TR0RST      0x80
150
151 #define TR1CAPT     0x80
152 #define TR1PLAY     0x00
153
154 static const unsigned char init_common[] = {
155
156         0x00, MR050,            /* MR0, PAL enabled */
157         0x01, 0x00,             /* MR1 */
158         0x02, 0x0c,             /* subc. freq. */
159         0x03, 0x8c,             /* subc. freq. */
160         0x04, 0x79,             /* subc. freq. */
161         0x05, 0x26,             /* subc. freq. */
162         0x06, 0x40,             /* subc. phase */
163
164         0x07, TR0MODE,          /* TR0, 16bit */
165         0x08, 0x21,             /*  */
166         0x09, 0x00,             /*  */
167         0x0a, 0x00,             /*  */
168         0x0b, 0x00,             /*  */
169         0x0c, TR1CAPT,          /* TR1 */
170         0x0d, 0x4f,             /* MR2 */
171         0x0e, 0x00,             /*  */
172         0x0f, 0x00,             /*  */
173         0x10, 0x00,             /*  */
174         0x11, 0x00,             /*  */
175 };
176
177 static const unsigned char init_pal[] = {
178         0x00, MR050,            /* MR0, PAL enabled */
179         0x01, 0x00,             /* MR1 */
180         0x02, 0x0c,             /* subc. freq. */
181         0x03, 0x8c,             /* subc. freq. */
182         0x04, 0x79,             /* subc. freq. */
183         0x05, 0x26,             /* subc. freq. */
184         0x06, 0x40,             /* subc. phase */
185 };
186
187 static const unsigned char init_ntsc[] = {
188         0x00, MR060,            /* MR0, NTSC enabled */
189         0x01, 0x00,             /* MR1 */
190         0x02, 0x55,             /* subc. freq. */
191         0x03, 0x55,             /* subc. freq. */
192         0x04, 0x55,             /* subc. freq. */
193         0x05, 0x25,             /* subc. freq. */
194         0x06, 0x1a,             /* subc. phase */
195 };
196
197 static int adv7175_init(struct v4l2_subdev *sd, u32 val)
198 {
199         /* This is just for testing!!! */
200         adv7175_write_block(sd, init_common, sizeof(init_common));
201         adv7175_write(sd, 0x07, TR0MODE | TR0RST);
202         adv7175_write(sd, 0x07, TR0MODE);
203         return 0;
204 }
205
206 static int adv7175_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
207 {
208         struct adv7175 *encoder = to_adv7175(sd);
209
210         if (std & V4L2_STD_NTSC) {
211                 adv7175_write_block(sd, init_ntsc, sizeof(init_ntsc));
212                 if (encoder->input == 0)
213                         adv7175_write(sd, 0x0d, 0x4f);  /* Enable genlock */
214                 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
215                 adv7175_write(sd, 0x07, TR0MODE);
216         } else if (std & V4L2_STD_PAL) {
217                 adv7175_write_block(sd, init_pal, sizeof(init_pal));
218                 if (encoder->input == 0)
219                         adv7175_write(sd, 0x0d, 0x4f);  /* Enable genlock */
220                 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
221                 adv7175_write(sd, 0x07, TR0MODE);
222         } else if (std & V4L2_STD_SECAM) {
223                 /* This is an attempt to convert
224                  * SECAM->PAL (typically it does not work
225                  * due to genlock: when decoder is in SECAM
226                  * and encoder in in PAL the subcarrier can
227                  * not be syncronized with horizontal
228                  * quency) */
229                 adv7175_write_block(sd, init_pal, sizeof(init_pal));
230                 if (encoder->input == 0)
231                         adv7175_write(sd, 0x0d, 0x49);  /* Disable genlock */
232                 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
233                 adv7175_write(sd, 0x07, TR0MODE);
234         } else {
235                 v4l2_dbg(1, debug, sd, "illegal norm: %llx\n",
236                                 (unsigned long long)std);
237                 return -EINVAL;
238         }
239         v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std);
240         encoder->norm = std;
241         return 0;
242 }
243
244 static int adv7175_s_routing(struct v4l2_subdev *sd,
245                              u32 input, u32 output, u32 config)
246 {
247         struct adv7175 *encoder = to_adv7175(sd);
248
249         /* RJ: input = 0: input is from decoder
250            input = 1: input is from ZR36060
251            input = 2: color bar */
252
253         switch (input) {
254         case 0:
255                 adv7175_write(sd, 0x01, 0x00);
256
257                 if (encoder->norm & V4L2_STD_NTSC)
258                         set_subcarrier_freq(sd, 1);
259
260                 adv7175_write(sd, 0x0c, TR1CAPT);       /* TR1 */
261                 if (encoder->norm & V4L2_STD_SECAM)
262                         adv7175_write(sd, 0x0d, 0x49);  /* Disable genlock */
263                 else
264                         adv7175_write(sd, 0x0d, 0x4f);  /* Enable genlock */
265                 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
266                 adv7175_write(sd, 0x07, TR0MODE);
267                 /*udelay(10);*/
268                 break;
269
270         case 1:
271                 adv7175_write(sd, 0x01, 0x00);
272
273                 if (encoder->norm & V4L2_STD_NTSC)
274                         set_subcarrier_freq(sd, 0);
275
276                 adv7175_write(sd, 0x0c, TR1PLAY);       /* TR1 */
277                 adv7175_write(sd, 0x0d, 0x49);
278                 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
279                 adv7175_write(sd, 0x07, TR0MODE);
280                 /* udelay(10); */
281                 break;
282
283         case 2:
284                 adv7175_write(sd, 0x01, 0x80);
285
286                 if (encoder->norm & V4L2_STD_NTSC)
287                         set_subcarrier_freq(sd, 0);
288
289                 adv7175_write(sd, 0x0d, 0x49);
290                 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
291                 adv7175_write(sd, 0x07, TR0MODE);
292                 /* udelay(10); */
293                 break;
294
295         default:
296                 v4l2_dbg(1, debug, sd, "illegal input: %d\n", input);
297                 return -EINVAL;
298         }
299         v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[input]);
300         encoder->input = input;
301         return 0;
302 }
303
304 static int adv7175_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
305                                 enum v4l2_mbus_pixelcode *code)
306 {
307         if (index >= ARRAY_SIZE(adv7175_codes))
308                 return -EINVAL;
309
310         *code = adv7175_codes[index];
311         return 0;
312 }
313
314 static int adv7175_g_fmt(struct v4l2_subdev *sd,
315                                 struct v4l2_mbus_framefmt *mf)
316 {
317         u8 val = adv7175_read(sd, 0x7);
318
319         if ((val & 0x40) == (1 << 6))
320                 mf->code = V4L2_MBUS_FMT_UYVY8_1X16;
321         else
322                 mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
323
324         mf->colorspace  = V4L2_COLORSPACE_SMPTE170M;
325         mf->width       = 0;
326         mf->height      = 0;
327         mf->field       = V4L2_FIELD_ANY;
328
329         return 0;
330 }
331
332 static int adv7175_s_fmt(struct v4l2_subdev *sd,
333                                 struct v4l2_mbus_framefmt *mf)
334 {
335         u8 val = adv7175_read(sd, 0x7);
336         int ret;
337
338         switch (mf->code) {
339         case V4L2_MBUS_FMT_UYVY8_2X8:
340                 val &= ~0x40;
341                 break;
342
343         case V4L2_MBUS_FMT_UYVY8_1X16:
344                 val |= 0x40;
345                 break;
346
347         default:
348                 v4l2_dbg(1, debug, sd,
349                         "illegal v4l2_mbus_framefmt code: %d\n", mf->code);
350                 return -EINVAL;
351         }
352
353         ret = adv7175_write(sd, 0x7, val);
354
355         return ret;
356 }
357
358 static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
359 {
360         struct i2c_client *client = v4l2_get_subdevdata(sd);
361
362         return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0);
363 }
364
365 static int adv7175_s_power(struct v4l2_subdev *sd, int on)
366 {
367         if (on)
368                 adv7175_write(sd, 0x01, 0x00);
369         else
370                 adv7175_write(sd, 0x01, 0x78);
371
372         return 0;
373 }
374
375 /* ----------------------------------------------------------------------- */
376
377 static const struct v4l2_subdev_core_ops adv7175_core_ops = {
378         .g_chip_ident = adv7175_g_chip_ident,
379         .init = adv7175_init,
380         .s_power = adv7175_s_power,
381 };
382
383 static const struct v4l2_subdev_video_ops adv7175_video_ops = {
384         .s_std_output = adv7175_s_std_output,
385         .s_routing = adv7175_s_routing,
386         .s_mbus_fmt = adv7175_s_fmt,
387         .g_mbus_fmt = adv7175_g_fmt,
388         .enum_mbus_fmt  = adv7175_enum_fmt,
389 };
390
391 static const struct v4l2_subdev_ops adv7175_ops = {
392         .core = &adv7175_core_ops,
393         .video = &adv7175_video_ops,
394 };
395
396 /* ----------------------------------------------------------------------- */
397
398 static int adv7175_probe(struct i2c_client *client,
399                         const struct i2c_device_id *id)
400 {
401         int i;
402         struct adv7175 *encoder;
403         struct v4l2_subdev *sd;
404
405         /* Check if the adapter supports the needed features */
406         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
407                 return -ENODEV;
408
409         v4l_info(client, "chip found @ 0x%x (%s)\n",
410                         client->addr << 1, client->adapter->name);
411
412         encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
413         if (encoder == NULL)
414                 return -ENOMEM;
415         sd = &encoder->sd;
416         v4l2_i2c_subdev_init(sd, client, &adv7175_ops);
417         encoder->norm = V4L2_STD_NTSC;
418         encoder->input = 0;
419
420         i = adv7175_write_block(sd, init_common, sizeof(init_common));
421         if (i >= 0) {
422                 i = adv7175_write(sd, 0x07, TR0MODE | TR0RST);
423                 i = adv7175_write(sd, 0x07, TR0MODE);
424                 i = adv7175_read(sd, 0x12);
425                 v4l2_dbg(1, debug, sd, "revision %d\n", i & 1);
426         }
427         if (i < 0)
428                 v4l2_dbg(1, debug, sd, "init error 0x%x\n", i);
429         return 0;
430 }
431
432 static int adv7175_remove(struct i2c_client *client)
433 {
434         struct v4l2_subdev *sd = i2c_get_clientdata(client);
435
436         v4l2_device_unregister_subdev(sd);
437         kfree(to_adv7175(sd));
438         return 0;
439 }
440
441 /* ----------------------------------------------------------------------- */
442
443 static const struct i2c_device_id adv7175_id[] = {
444         { "adv7175", 0 },
445         { "adv7176", 0 },
446         { }
447 };
448 MODULE_DEVICE_TABLE(i2c, adv7175_id);
449
450 static struct i2c_driver adv7175_driver = {
451         .driver = {
452                 .owner  = THIS_MODULE,
453                 .name   = "adv7175",
454         },
455         .probe          = adv7175_probe,
456         .remove         = adv7175_remove,
457         .id_table       = adv7175_id,
458 };
459
460 static __init int init_adv7175(void)
461 {
462         return i2c_add_driver(&adv7175_driver);
463 }
464
465 static __exit void exit_adv7175(void)
466 {
467         i2c_del_driver(&adv7175_driver);
468 }
469
470 module_init(init_adv7175);
471 module_exit(exit_adv7175);