1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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/signal.h>
37#include <linux/types.h>
38#include <linux/i2c.h>
39#include <asm/io.h>
40#include <asm/pgtable.h>
41#include <asm/page.h>
42#include <asm/uaccess.h>
43
44#include <linux/videodev.h>
45#include <linux/video_encoder.h>
46
47MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
48MODULE_AUTHOR("Dave Perks");
49MODULE_LICENSE("GPL");
50
51
52#define I2C_NAME(s) (s)->name
53
54
55static int debug = 0;
56module_param(debug, int, 0);
57MODULE_PARM_DESC(debug, "Debug level (0-1)");
58
59#define dprintk(num, format, args...) \
60 do { \
61 if (debug >= num) \
62 printk(format, ##args); \
63 } while (0)
64
65
66
67struct adv7175 {
68 int norm;
69 int input;
70 int enable;
71 int bright;
72 int contrast;
73 int hue;
74 int sat;
75};
76
77#define I2C_ADV7175 0xd4
78#define I2C_ADV7176 0x54
79
80static char adv7175_name[] = "adv7175";
81static char adv7176_name[] = "adv7176";
82
83static char *inputs[] = { "pass_through", "play_back", "color_bar" };
84static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
85
86
87
88static inline int
89adv7175_write (struct i2c_client *client,
90 u8 reg,
91 u8 value)
92{
93 return i2c_smbus_write_byte_data(client, reg, value);
94}
95
96static inline int
97adv7175_read (struct i2c_client *client,
98 u8 reg)
99{
100 return i2c_smbus_read_byte_data(client, reg);
101}
102
103static int
104adv7175_write_block (struct i2c_client *client,
105 const u8 *data,
106 unsigned int len)
107{
108 int ret = -1;
109 u8 reg;
110
111
112
113 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
114
115 u8 block_data[32];
116 int block_len;
117
118 while (len >= 2) {
119 block_len = 0;
120 block_data[block_len++] = reg = data[0];
121 do {
122 block_data[block_len++] = data[1];
123 reg++;
124 len -= 2;
125 data += 2;
126 } while (len >= 2 && data[0] == reg &&
127 block_len < 32);
128 if ((ret = i2c_master_send(client, block_data,
129 block_len)) < 0)
130 break;
131 }
132 } else {
133
134 while (len >= 2) {
135 reg = *data++;
136 if ((ret = adv7175_write(client, reg,
137 *data++)) < 0)
138 break;
139 len -= 2;
140 }
141 }
142
143 return ret;
144}
145
146static void
147set_subcarrier_freq (struct i2c_client *client,
148 int pass_through)
149{
150
151
152 if(pass_through)
153 adv7175_write(client, 0x02, 0x00);
154 else
155 adv7175_write(client, 0x02, 0x55);
156
157 adv7175_write(client, 0x03, 0x55);
158 adv7175_write(client, 0x04, 0x55);
159 adv7175_write(client, 0x05, 0x25);
160}
161
162
163
164
165#define MR050 0x11
166#define MR060 0x14
167
168
169
170#define TR0MODE 0x46
171#define TR0RST 0x80
172
173#define TR1CAPT 0x80
174#define TR1PLAY 0x00
175
176static const unsigned char init_common[] = {
177
178 0x00, MR050,
179 0x01, 0x00,
180 0x02, 0x0c,
181 0x03, 0x8c,
182 0x04, 0x79,
183 0x05, 0x26,
184 0x06, 0x40,
185
186 0x07, TR0MODE,
187 0x08, 0x21,
188 0x09, 0x00,
189 0x0a, 0x00,
190 0x0b, 0x00,
191 0x0c, TR1CAPT,
192 0x0d, 0x4f,
193 0x0e, 0x00,
194 0x0f, 0x00,
195 0x10, 0x00,
196 0x11, 0x00,
197};
198
199static const unsigned char init_pal[] = {
200 0x00, MR050,
201 0x01, 0x00,
202 0x02, 0x0c,
203 0x03, 0x8c,
204 0x04, 0x79,
205 0x05, 0x26,
206 0x06, 0x40,
207};
208
209static const unsigned char init_ntsc[] = {
210 0x00, MR060,
211 0x01, 0x00,
212 0x02, 0x55,
213 0x03, 0x55,
214 0x04, 0x55,
215 0x05, 0x25,
216 0x06, 0x1a,
217};
218
219static int
220adv7175_command (struct i2c_client *client,
221 unsigned int cmd,
222 void *arg)
223{
224 struct adv7175 *encoder = i2c_get_clientdata(client);
225
226 switch (cmd) {
227
228 case 0:
229
230 adv7175_write_block(client, init_common,
231 sizeof(init_common));
232 adv7175_write(client, 0x07, TR0MODE | TR0RST);
233 adv7175_write(client, 0x07, TR0MODE);
234 break;
235
236 case ENCODER_GET_CAPABILITIES:
237 {
238 struct video_encoder_capability *cap = arg;
239
240 cap->flags = VIDEO_ENCODER_PAL |
241 VIDEO_ENCODER_NTSC |
242 VIDEO_ENCODER_SECAM;
243 cap->inputs = 2;
244 cap->outputs = 1;
245 }
246 break;
247
248 case ENCODER_SET_NORM:
249 {
250 int iarg = *(int *) arg;
251
252 switch (iarg) {
253
254 case VIDEO_MODE_NTSC:
255 adv7175_write_block(client, init_ntsc,
256 sizeof(init_ntsc));
257 if (encoder->input == 0)
258 adv7175_write(client, 0x0d, 0x4f);
259 adv7175_write(client, 0x07, TR0MODE | TR0RST);
260 adv7175_write(client, 0x07, TR0MODE);
261 break;
262
263 case VIDEO_MODE_PAL:
264 adv7175_write_block(client, init_pal,
265 sizeof(init_pal));
266 if (encoder->input == 0)
267 adv7175_write(client, 0x0d, 0x4f);
268 adv7175_write(client, 0x07, TR0MODE | TR0RST);
269 adv7175_write(client, 0x07, TR0MODE);
270 break;
271
272 case VIDEO_MODE_SECAM:
273
274
275
276
277
278
279 adv7175_write_block(client, init_pal,
280 sizeof(init_pal));
281 if (encoder->input == 0)
282 adv7175_write(client, 0x0d, 0x49);
283 adv7175_write(client, 0x07, TR0MODE | TR0RST);
284 adv7175_write(client, 0x07, TR0MODE);
285 break;
286 default:
287 dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
288 I2C_NAME(client), iarg);
289 return -EINVAL;
290
291 }
292 dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
293 norms[iarg]);
294 encoder->norm = iarg;
295 }
296 break;
297
298 case ENCODER_SET_INPUT:
299 {
300 int iarg = *(int *) arg;
301
302
303
304
305
306 switch (iarg) {
307
308 case 0:
309 adv7175_write(client, 0x01, 0x00);
310
311 if (encoder->norm == VIDEO_MODE_NTSC)
312 set_subcarrier_freq(client, 1);
313
314 adv7175_write(client, 0x0c, TR1CAPT);
315 if (encoder->norm == VIDEO_MODE_SECAM)
316 adv7175_write(client, 0x0d, 0x49);
317 else
318 adv7175_write(client, 0x0d, 0x4f);
319 adv7175_write(client, 0x07, TR0MODE | TR0RST);
320 adv7175_write(client, 0x07, TR0MODE);
321
322 break;
323
324 case 1:
325 adv7175_write(client, 0x01, 0x00);
326
327 if (encoder->norm == VIDEO_MODE_NTSC)
328 set_subcarrier_freq(client, 0);
329
330 adv7175_write(client, 0x0c, TR1PLAY);
331 adv7175_write(client, 0x0d, 0x49);
332 adv7175_write(client, 0x07, TR0MODE | TR0RST);
333 adv7175_write(client, 0x07, TR0MODE);
334
335 break;
336
337 case 2:
338 adv7175_write(client, 0x01, 0x80);
339
340 if (encoder->norm == VIDEO_MODE_NTSC)
341 set_subcarrier_freq(client, 0);
342
343 adv7175_write(client, 0x0d, 0x49);
344 adv7175_write(client, 0x07, TR0MODE | TR0RST);
345 adv7175_write(client, 0x07, TR0MODE);
346
347 break;
348
349 default:
350 dprintk(1, KERN_ERR "%s: illegal input: %d\n",
351 I2C_NAME(client), iarg);
352 return -EINVAL;
353
354 }
355 dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
356 inputs[iarg]);
357 encoder->input = iarg;
358 }
359 break;
360
361 case ENCODER_SET_OUTPUT:
362 {
363 int *iarg = arg;
364
365
366 if (*iarg != 0) {
367 return -EINVAL;
368 }
369 }
370 break;
371
372 case ENCODER_ENABLE_OUTPUT:
373 {
374 int *iarg = arg;
375
376 encoder->enable = !!*iarg;
377 }
378 break;
379
380 default:
381 return -EINVAL;
382 }
383
384 return 0;
385}
386
387
388
389
390
391
392
393static unsigned short normal_i2c[] =
394 { I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
395 I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1,
396 I2C_CLIENT_END
397};
398
399static unsigned short ignore = I2C_CLIENT_END;
400
401static struct i2c_client_address_data addr_data = {
402 .normal_i2c = normal_i2c,
403 .probe = &ignore,
404 .ignore = &ignore,
405};
406
407static struct i2c_driver i2c_driver_adv7175;
408
409static int
410adv7175_detect_client (struct i2c_adapter *adapter,
411 int address,
412 int kind)
413{
414 int i;
415 struct i2c_client *client;
416 struct adv7175 *encoder;
417 char *dname;
418
419 dprintk(1,
420 KERN_INFO
421 "adv7175.c: detecting adv7175 client on address 0x%x\n",
422 address << 1);
423
424
425 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
426 return 0;
427
428 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
429 if (client == 0)
430 return -ENOMEM;
431 client->addr = address;
432 client->adapter = adapter;
433 client->driver = &i2c_driver_adv7175;
434 if ((client->addr == I2C_ADV7175 >> 1) ||
435 (client->addr == (I2C_ADV7175 >> 1) + 1)) {
436 dname = adv7175_name;
437 } else if ((client->addr == I2C_ADV7176 >> 1) ||
438 (client->addr == (I2C_ADV7176 >> 1) + 1)) {
439 dname = adv7176_name;
440 } else {
441
442 kfree(client);
443 return 0;
444 }
445 strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
446
447 encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
448 if (encoder == NULL) {
449 kfree(client);
450 return -ENOMEM;
451 }
452 encoder->norm = VIDEO_MODE_PAL;
453 encoder->input = 0;
454 encoder->enable = 1;
455 i2c_set_clientdata(client, encoder);
456
457 i = i2c_attach_client(client);
458 if (i) {
459 kfree(client);
460 kfree(encoder);
461 return i;
462 }
463
464 i = adv7175_write_block(client, init_common, sizeof(init_common));
465 if (i >= 0) {
466 i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
467 i = adv7175_write(client, 0x07, TR0MODE);
468 i = adv7175_read(client, 0x12);
469 dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%x\n",
470 I2C_NAME(client), i & 1, client->addr << 1);
471 }
472 if (i < 0) {
473 dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
474 I2C_NAME(client), i);
475 }
476
477 return 0;
478}
479
480static int
481adv7175_attach_adapter (struct i2c_adapter *adapter)
482{
483 dprintk(1,
484 KERN_INFO
485 "adv7175.c: starting probe for adapter %s (0x%x)\n",
486 I2C_NAME(adapter), adapter->id);
487 return i2c_probe(adapter, &addr_data, &adv7175_detect_client);
488}
489
490static int
491adv7175_detach_client (struct i2c_client *client)
492{
493 struct adv7175 *encoder = i2c_get_clientdata(client);
494 int err;
495
496 err = i2c_detach_client(client);
497 if (err) {
498 return err;
499 }
500
501 kfree(encoder);
502 kfree(client);
503
504 return 0;
505}
506
507
508
509static struct i2c_driver i2c_driver_adv7175 = {
510 .driver = {
511 .name = "adv7175",
512 },
513
514 .id = I2C_DRIVERID_ADV7175,
515
516 .attach_adapter = adv7175_attach_adapter,
517 .detach_client = adv7175_detach_client,
518 .command = adv7175_command,
519};
520
521static int __init
522adv7175_init (void)
523{
524 return i2c_add_driver(&i2c_driver_adv7175);
525}
526
527static void __exit
528adv7175_exit (void)
529{
530 i2c_del_driver(&i2c_driver_adv7175);
531}
532
533module_init(adv7175_init);
534module_exit(adv7175_exit);
535