diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2008-09-07 07:01:20 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-17 16:20:01 -0400 |
commit | 0afb351e62f855b1c3584fb54bc6b91b54b32a9a (patch) | |
tree | b0d901af48d82d33dc79f5beaeb5faad8d231765 /drivers/media/video/saa7185.c | |
parent | b3286f6f52beff997e535bb4b5a9f41d912b11d0 (diff) |
V4L/DVB (9207): saa7185: convert i2c driver for new i2c API
- Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API
- Cleanups
- Use v4l_dbg/v4l_info to have uniform kernel messages
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/saa7185.c')
-rw-r--r-- | drivers/media/video/saa7185.c | 210 |
1 files changed, 50 insertions, 160 deletions
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 02fda4eecea3..6debb65152ee 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c | |||
@@ -25,43 +25,25 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/module.h> | 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> | 28 | #include <linux/types.h> |
38 | #include <linux/i2c.h> | 29 | #include <linux/ioctl.h> |
39 | #include <asm/io.h> | ||
40 | #include <asm/pgtable.h> | ||
41 | #include <asm/page.h> | ||
42 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
43 | 31 | #include <linux/i2c.h> | |
32 | #include <linux/i2c-id.h> | ||
44 | #include <linux/videodev.h> | 33 | #include <linux/videodev.h> |
45 | #include <linux/video_encoder.h> | 34 | #include <linux/video_encoder.h> |
35 | #include <media/v4l2-common.h> | ||
36 | #include <media/v4l2-i2c-drv-legacy.h> | ||
46 | 37 | ||
47 | MODULE_DESCRIPTION("Philips SAA7185 video encoder driver"); | 38 | MODULE_DESCRIPTION("Philips SAA7185 video encoder driver"); |
48 | MODULE_AUTHOR("Dave Perks"); | 39 | MODULE_AUTHOR("Dave Perks"); |
49 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
50 | 41 | ||
51 | 42 | ||
52 | #define I2C_NAME(s) (s)->name | ||
53 | |||
54 | |||
55 | static int debug; | 43 | static int debug; |
56 | module_param(debug, int, 0); | 44 | module_param(debug, int, 0); |
57 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 45 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
58 | 46 | ||
59 | #define dprintk(num, format, args...) \ | ||
60 | do { \ | ||
61 | if (debug >= num) \ | ||
62 | printk(format, ##args); \ | ||
63 | } while (0) | ||
64 | |||
65 | /* ----------------------------------------------------------------------- */ | 47 | /* ----------------------------------------------------------------------- */ |
66 | 48 | ||
67 | struct saa7185 { | 49 | struct saa7185 { |
@@ -75,32 +57,24 @@ struct saa7185 { | |||
75 | int sat; | 57 | int sat; |
76 | }; | 58 | }; |
77 | 59 | ||
78 | #define I2C_SAA7185 0x88 | ||
79 | |||
80 | /* ----------------------------------------------------------------------- */ | 60 | /* ----------------------------------------------------------------------- */ |
81 | 61 | ||
82 | static inline int | 62 | static inline int saa7185_read(struct i2c_client *client) |
83 | saa7185_read (struct i2c_client *client) | ||
84 | { | 63 | { |
85 | return i2c_smbus_read_byte(client); | 64 | return i2c_smbus_read_byte(client); |
86 | } | 65 | } |
87 | 66 | ||
88 | static int | 67 | static int saa7185_write(struct i2c_client *client, u8 reg, u8 value) |
89 | saa7185_write (struct i2c_client *client, | ||
90 | u8 reg, | ||
91 | u8 value) | ||
92 | { | 68 | { |
93 | struct saa7185 *encoder = i2c_get_clientdata(client); | 69 | struct saa7185 *encoder = i2c_get_clientdata(client); |
94 | 70 | ||
95 | dprintk(1, KERN_DEBUG "SAA7185: %02x set to %02x\n", reg, value); | 71 | v4l_dbg(1, debug, client, "%02x set to %02x\n", reg, value); |
96 | encoder->reg[reg] = value; | 72 | encoder->reg[reg] = value; |
97 | return i2c_smbus_write_byte_data(client, reg, value); | 73 | return i2c_smbus_write_byte_data(client, reg, value); |
98 | } | 74 | } |
99 | 75 | ||
100 | static int | 76 | static int saa7185_write_block(struct i2c_client *client, |
101 | saa7185_write_block (struct i2c_client *client, | 77 | const u8 *data, unsigned int len) |
102 | const u8 *data, | ||
103 | unsigned int len) | ||
104 | { | 78 | { |
105 | int ret = -1; | 79 | int ret = -1; |
106 | u8 reg; | 80 | u8 reg; |
@@ -121,18 +95,17 @@ saa7185_write_block (struct i2c_client *client, | |||
121 | encoder->reg[reg++] = data[1]; | 95 | encoder->reg[reg++] = data[1]; |
122 | len -= 2; | 96 | len -= 2; |
123 | data += 2; | 97 | data += 2; |
124 | } while (len >= 2 && data[0] == reg && | 98 | } while (len >= 2 && data[0] == reg && block_len < 32); |
125 | block_len < 32); | 99 | ret = i2c_master_send(client, block_data, block_len); |
126 | if ((ret = i2c_master_send(client, block_data, | 100 | if (ret < 0) |
127 | block_len)) < 0) | ||
128 | break; | 101 | break; |
129 | } | 102 | } |
130 | } else { | 103 | } else { |
131 | /* do some slow I2C emulation kind of thing */ | 104 | /* do some slow I2C emulation kind of thing */ |
132 | while (len >= 2) { | 105 | while (len >= 2) { |
133 | reg = *data++; | 106 | reg = *data++; |
134 | if ((ret = saa7185_write(client, reg, | 107 | ret = saa7185_write(client, reg, *data++); |
135 | *data++)) < 0) | 108 | if (ret < 0) |
136 | break; | 109 | break; |
137 | len -= 2; | 110 | len -= 2; |
138 | } | 111 | } |
@@ -240,15 +213,11 @@ static const unsigned char init_ntsc[] = { | |||
240 | 0x66, 0x21, /* FSC3 */ | 213 | 0x66, 0x21, /* FSC3 */ |
241 | }; | 214 | }; |
242 | 215 | ||
243 | static int | 216 | static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) |
244 | saa7185_command (struct i2c_client *client, | ||
245 | unsigned int cmd, | ||
246 | void *arg) | ||
247 | { | 217 | { |
248 | struct saa7185 *encoder = i2c_get_clientdata(client); | 218 | struct saa7185 *encoder = i2c_get_clientdata(client); |
249 | 219 | ||
250 | switch (cmd) { | 220 | switch (cmd) { |
251 | |||
252 | case 0: | 221 | case 0: |
253 | saa7185_write_block(client, init_common, | 222 | saa7185_write_block(client, init_common, |
254 | sizeof(init_common)); | 223 | sizeof(init_common)); |
@@ -264,7 +233,6 @@ saa7185_command (struct i2c_client *client, | |||
264 | sizeof(init_pal)); | 233 | sizeof(init_pal)); |
265 | break; | 234 | break; |
266 | } | 235 | } |
267 | |||
268 | break; | 236 | break; |
269 | 237 | ||
270 | case ENCODER_GET_CAPABILITIES: | 238 | case ENCODER_GET_CAPABILITIES: |
@@ -276,8 +244,8 @@ saa7185_command (struct i2c_client *client, | |||
276 | VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR; | 244 | VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR; |
277 | cap->inputs = 1; | 245 | cap->inputs = 1; |
278 | cap->outputs = 1; | 246 | cap->outputs = 1; |
279 | } | ||
280 | break; | 247 | break; |
248 | } | ||
281 | 249 | ||
282 | case ENCODER_SET_NORM: | 250 | case ENCODER_SET_NORM: |
283 | { | 251 | { |
@@ -286,7 +254,6 @@ saa7185_command (struct i2c_client *client, | |||
286 | //saa7185_write_block(client, init_common, sizeof(init_common)); | 254 | //saa7185_write_block(client, init_common, sizeof(init_common)); |
287 | 255 | ||
288 | switch (*iarg) { | 256 | switch (*iarg) { |
289 | |||
290 | case VIDEO_MODE_NTSC: | 257 | case VIDEO_MODE_NTSC: |
291 | saa7185_write_block(client, init_ntsc, | 258 | saa7185_write_block(client, init_ntsc, |
292 | sizeof(init_ntsc)); | 259 | sizeof(init_ntsc)); |
@@ -300,11 +267,10 @@ saa7185_command (struct i2c_client *client, | |||
300 | case VIDEO_MODE_SECAM: | 267 | case VIDEO_MODE_SECAM: |
301 | default: | 268 | default: |
302 | return -EINVAL; | 269 | return -EINVAL; |
303 | |||
304 | } | 270 | } |
305 | encoder->norm = *iarg; | 271 | encoder->norm = *iarg; |
306 | } | ||
307 | break; | 272 | break; |
273 | } | ||
308 | 274 | ||
309 | case ENCODER_SET_INPUT: | 275 | case ENCODER_SET_INPUT: |
310 | { | 276 | { |
@@ -314,7 +280,6 @@ saa7185_command (struct i2c_client *client, | |||
314 | *iarg = 1: input is from ZR36060 */ | 280 | *iarg = 1: input is from ZR36060 */ |
315 | 281 | ||
316 | switch (*iarg) { | 282 | switch (*iarg) { |
317 | |||
318 | case 0: | 283 | case 0: |
319 | /* Switch RTCE to 1 */ | 284 | /* Switch RTCE to 1 */ |
320 | saa7185_write(client, 0x61, | 285 | saa7185_write(client, 0x61, |
@@ -332,21 +297,19 @@ saa7185_command (struct i2c_client *client, | |||
332 | 297 | ||
333 | default: | 298 | default: |
334 | return -EINVAL; | 299 | return -EINVAL; |
335 | |||
336 | } | 300 | } |
337 | } | ||
338 | break; | 301 | break; |
302 | } | ||
339 | 303 | ||
340 | case ENCODER_SET_OUTPUT: | 304 | case ENCODER_SET_OUTPUT: |
341 | { | 305 | { |
342 | int *iarg = arg; | 306 | int *iarg = arg; |
343 | 307 | ||
344 | /* not much choice of outputs */ | 308 | /* not much choice of outputs */ |
345 | if (*iarg != 0) { | 309 | if (*iarg != 0) |
346 | return -EINVAL; | 310 | return -EINVAL; |
347 | } | ||
348 | } | ||
349 | break; | 311 | break; |
312 | } | ||
350 | 313 | ||
351 | case ENCODER_ENABLE_OUTPUT: | 314 | case ENCODER_ENABLE_OUTPUT: |
352 | { | 315 | { |
@@ -356,8 +319,8 @@ saa7185_command (struct i2c_client *client, | |||
356 | saa7185_write(client, 0x61, | 319 | saa7185_write(client, 0x61, |
357 | (encoder->reg[0x61] & 0xbf) | | 320 | (encoder->reg[0x61] & 0xbf) | |
358 | (encoder->enable ? 0x00 : 0x40)); | 321 | (encoder->enable ? 0x00 : 0x40)); |
359 | } | ||
360 | break; | 322 | break; |
323 | } | ||
361 | 324 | ||
362 | default: | 325 | default: |
363 | return -EINVAL; | 326 | return -EINVAL; |
@@ -368,138 +331,65 @@ saa7185_command (struct i2c_client *client, | |||
368 | 331 | ||
369 | /* ----------------------------------------------------------------------- */ | 332 | /* ----------------------------------------------------------------------- */ |
370 | 333 | ||
371 | /* | 334 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; |
372 | * Generic i2c probe | ||
373 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
374 | */ | ||
375 | static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END }; | ||
376 | 335 | ||
377 | static unsigned short ignore = I2C_CLIENT_END; | 336 | I2C_CLIENT_INSMOD; |
378 | 337 | ||
379 | static struct i2c_client_address_data addr_data = { | 338 | static int saa7185_probe(struct i2c_client *client, |
380 | .normal_i2c = normal_i2c, | 339 | const struct i2c_device_id *id) |
381 | .probe = &ignore, | ||
382 | .ignore = &ignore, | ||
383 | }; | ||
384 | |||
385 | static struct i2c_driver i2c_driver_saa7185; | ||
386 | |||
387 | static int | ||
388 | saa7185_detect_client (struct i2c_adapter *adapter, | ||
389 | int address, | ||
390 | int kind) | ||
391 | { | 340 | { |
392 | int i; | 341 | int i; |
393 | struct i2c_client *client; | ||
394 | struct saa7185 *encoder; | 342 | struct saa7185 *encoder; |
395 | 343 | ||
396 | dprintk(1, | ||
397 | KERN_INFO | ||
398 | "saa7185.c: detecting saa7185 client on address 0x%x\n", | ||
399 | address << 1); | ||
400 | |||
401 | /* Check if the adapter supports the needed features */ | 344 | /* Check if the adapter supports the needed features */ |
402 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 345 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
403 | return 0; | 346 | return -ENODEV; |
404 | 347 | ||
405 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 348 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
406 | if (!client) | 349 | client->addr << 1, client->adapter->name); |
407 | return -ENOMEM; | ||
408 | client->addr = address; | ||
409 | client->adapter = adapter; | ||
410 | client->driver = &i2c_driver_saa7185; | ||
411 | strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client))); | ||
412 | 350 | ||
413 | encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL); | 351 | encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL); |
414 | if (encoder == NULL) { | 352 | if (encoder == NULL) |
415 | kfree(client); | ||
416 | return -ENOMEM; | 353 | return -ENOMEM; |
417 | } | ||
418 | encoder->norm = VIDEO_MODE_NTSC; | 354 | encoder->norm = VIDEO_MODE_NTSC; |
419 | encoder->enable = 1; | 355 | encoder->enable = 1; |
420 | i2c_set_clientdata(client, encoder); | 356 | i2c_set_clientdata(client, encoder); |
421 | 357 | ||
422 | i = i2c_attach_client(client); | ||
423 | if (i) { | ||
424 | kfree(client); | ||
425 | kfree(encoder); | ||
426 | return i; | ||
427 | } | ||
428 | |||
429 | i = saa7185_write_block(client, init_common, sizeof(init_common)); | 358 | i = saa7185_write_block(client, init_common, sizeof(init_common)); |
430 | if (i >= 0) { | 359 | if (i >= 0) |
431 | i = saa7185_write_block(client, init_ntsc, | 360 | i = saa7185_write_block(client, init_ntsc, sizeof(init_ntsc)); |
432 | sizeof(init_ntsc)); | 361 | if (i < 0) |
433 | } | 362 | v4l_dbg(1, debug, client, "init error %d\n", i); |
434 | if (i < 0) { | 363 | else |
435 | dprintk(1, KERN_ERR "%s_attach: init error %d\n", | 364 | v4l_dbg(1, debug, client, "revision 0x%x\n", |
436 | I2C_NAME(client), i); | 365 | saa7185_read(client) >> 5); |
437 | } else { | ||
438 | dprintk(1, | ||
439 | KERN_INFO | ||
440 | "%s_attach: chip version %d at address 0x%x\n", | ||
441 | I2C_NAME(client), saa7185_read(client) >> 5, | ||
442 | client->addr << 1); | ||
443 | } | ||
444 | |||
445 | return 0; | 366 | return 0; |
446 | } | 367 | } |
447 | 368 | ||
448 | static int | 369 | static int saa7185_remove(struct i2c_client *client) |
449 | saa7185_attach_adapter (struct i2c_adapter *adapter) | ||
450 | { | ||
451 | dprintk(1, | ||
452 | KERN_INFO | ||
453 | "saa7185.c: starting probe for adapter %s (0x%x)\n", | ||
454 | I2C_NAME(adapter), adapter->id); | ||
455 | return i2c_probe(adapter, &addr_data, &saa7185_detect_client); | ||
456 | } | ||
457 | |||
458 | static int | ||
459 | saa7185_detach_client (struct i2c_client *client) | ||
460 | { | 370 | { |
461 | struct saa7185 *encoder = i2c_get_clientdata(client); | 371 | struct saa7185 *encoder = i2c_get_clientdata(client); |
462 | int err; | ||
463 | |||
464 | err = i2c_detach_client(client); | ||
465 | if (err) { | ||
466 | return err; | ||
467 | } | ||
468 | 372 | ||
469 | saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */ | 373 | saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */ |
470 | //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */ | 374 | //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */ |
471 | 375 | ||
472 | kfree(encoder); | 376 | kfree(encoder); |
473 | kfree(client); | ||
474 | |||
475 | return 0; | 377 | return 0; |
476 | } | 378 | } |
477 | 379 | ||
478 | /* ----------------------------------------------------------------------- */ | 380 | /* ----------------------------------------------------------------------- */ |
479 | 381 | ||
480 | static struct i2c_driver i2c_driver_saa7185 = { | 382 | static const struct i2c_device_id saa7185_id[] = { |
481 | .driver = { | 383 | { "saa7185", 0 }, |
482 | .name = "saa7185", /* name */ | 384 | { } |
483 | }, | 385 | }; |
484 | 386 | MODULE_DEVICE_TABLE(i2c, saa7185_id); | |
485 | .id = I2C_DRIVERID_SAA7185B, | ||
486 | 387 | ||
487 | .attach_adapter = saa7185_attach_adapter, | 388 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
488 | .detach_client = saa7185_detach_client, | 389 | .name = "saa7185", |
390 | .driverid = I2C_DRIVERID_SAA7185B, | ||
489 | .command = saa7185_command, | 391 | .command = saa7185_command, |
392 | .probe = saa7185_probe, | ||
393 | .remove = saa7185_remove, | ||
394 | .id_table = saa7185_id, | ||
490 | }; | 395 | }; |
491 | |||
492 | static int __init | ||
493 | saa7185_init (void) | ||
494 | { | ||
495 | return i2c_add_driver(&i2c_driver_saa7185); | ||
496 | } | ||
497 | |||
498 | static void __exit | ||
499 | saa7185_exit (void) | ||
500 | { | ||
501 | i2c_del_driver(&i2c_driver_saa7185); | ||
502 | } | ||
503 | |||
504 | module_init(saa7185_init); | ||
505 | module_exit(saa7185_exit); | ||