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