diff options
-rw-r--r-- | Documentation/video4linux/sn9c102.txt | 64 | ||||
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/Makefile | 17 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102.h | 17 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_core.c | 199 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_devtable.h | 14 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_hv7131d.c | 7 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_hv7131r.c | 458 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_mi0343.c | 111 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_mi0360.c | 353 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_ov7630.c | 63 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_ov7660.c | 3 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_pas106b.c | 5 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_pas202bcb.c | 15 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_tas5110c1b.c | 6 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_tas5110d.c | 121 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_tas5130d1b.c | 5 |
17 files changed, 1223 insertions, 237 deletions
diff --git a/Documentation/video4linux/sn9c102.txt b/Documentation/video4linux/sn9c102.txt index 2913da3d0878..5fe0ad7dfc20 100644 --- a/Documentation/video4linux/sn9c102.txt +++ b/Documentation/video4linux/sn9c102.txt | |||
@@ -25,7 +25,7 @@ Index | |||
25 | 25 | ||
26 | 1. Copyright | 26 | 1. Copyright |
27 | ============ | 27 | ============ |
28 | Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> | 28 | Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> |
29 | 29 | ||
30 | 30 | ||
31 | 2. Disclaimer | 31 | 2. Disclaimer |
@@ -216,10 +216,10 @@ Description: Debugging information level, from 0 to 3: | |||
216 | 1 = critical errors | 216 | 1 = critical errors |
217 | 2 = significant informations | 217 | 2 = significant informations |
218 | 3 = more verbose messages | 218 | 3 = more verbose messages |
219 | Level 3 is useful for testing only, when only one device | 219 | Level 3 is useful for testing only. It also shows some more |
220 | is used. It also shows some more informations about the | 220 | informations about the hardware being detected. |
221 | hardware being detected. This parameter can be changed at | 221 | This parameter can be changed at runtime thanks to the /sys |
222 | runtime thanks to the /sys filesystem interface. | 222 | filesystem interface. |
223 | Default: 2 | 223 | Default: 2 |
224 | ------------------------------------------------------------------------------- | 224 | ------------------------------------------------------------------------------- |
225 | 225 | ||
@@ -235,7 +235,7 @@ created in the /sys/class/video4linux/videoX directory. You can set the green | |||
235 | channel's gain by writing the desired value to it. The value may range from 0 | 235 | channel's gain by writing the desired value to it. The value may range from 0 |
236 | to 15 for the SN9C101 or SN9C102 bridges, from 0 to 127 for the SN9C103, | 236 | to 15 for the SN9C101 or SN9C102 bridges, from 0 to 127 for the SN9C103, |
237 | SN9C105 and SN9C120 bridges. | 237 | SN9C105 and SN9C120 bridges. |
238 | Similarly, only for the SN9C103, SN9C105 and SN9120 controllers, blue and red | 238 | Similarly, only for the SN9C103, SN9C105 and SN9C120 controllers, blue and red |
239 | gain control files are available in the same directory, for which accepted | 239 | gain control files are available in the same directory, for which accepted |
240 | values may range from 0 to 127. | 240 | values may range from 0 to 127. |
241 | 241 | ||
@@ -402,38 +402,49 @@ Vendor ID Product ID | |||
402 | 0x0c45 0x60bc | 402 | 0x0c45 0x60bc |
403 | 0x0c45 0x60be | 403 | 0x0c45 0x60be |
404 | 0x0c45 0x60c0 | 404 | 0x0c45 0x60c0 |
405 | 0x0c45 0x60c2 | ||
405 | 0x0c45 0x60c8 | 406 | 0x0c45 0x60c8 |
406 | 0x0c45 0x60cc | 407 | 0x0c45 0x60cc |
407 | 0x0c45 0x60ea | 408 | 0x0c45 0x60ea |
408 | 0x0c45 0x60ec | 409 | 0x0c45 0x60ec |
410 | 0x0c45 0x60ef | ||
409 | 0x0c45 0x60fa | 411 | 0x0c45 0x60fa |
410 | 0x0c45 0x60fb | 412 | 0x0c45 0x60fb |
411 | 0x0c45 0x60fc | 413 | 0x0c45 0x60fc |
412 | 0x0c45 0x60fe | 414 | 0x0c45 0x60fe |
415 | 0x0c45 0x6102 | ||
416 | 0x0c45 0x6108 | ||
417 | 0x0c45 0x610f | ||
413 | 0x0c45 0x6130 | 418 | 0x0c45 0x6130 |
419 | 0x0c45 0x6138 | ||
414 | 0x0c45 0x613a | 420 | 0x0c45 0x613a |
415 | 0x0c45 0x613b | 421 | 0x0c45 0x613b |
416 | 0x0c45 0x613c | 422 | 0x0c45 0x613c |
417 | 0x0c45 0x613e | 423 | 0x0c45 0x613e |
418 | 424 | ||
419 | The list above does not imply that all those devices work with this driver: up | 425 | The list above does not imply that all those devices work with this driver: up |
420 | until now only the ones that assemble the following image sensors are | 426 | until now only the ones that assemble the following pairs of SN9C1xx bridges |
421 | supported; kernel messages will always tell you whether this is the case (see | 427 | and image sensors are supported; kernel messages will always tell you whether |
422 | "Module loading" paragraph): | 428 | this is the case (see "Module loading" paragraph): |
423 | 429 | ||
424 | Model Manufacturer | 430 | Image sensor / SN9C1xx bridge | SN9C10[12] SN9C103 SN9C105 SN9C120 |
425 | ----- ------------ | 431 | ------------------------------------------------------------------------------- |
426 | HV7131D Hynix Semiconductor, Inc. | 432 | HV7131D Hynix Semiconductor | Yes No No No |
427 | MI-0343 Micron Technology, Inc. | 433 | HV7131R Hynix Semiconductor | No Yes Yes Yes |
428 | OV7630 OmniVision Technologies, Inc. | 434 | MI-0343 Micron Technology | Yes No No No |
429 | OV7660 OmniVision Technologies, Inc. | 435 | MI-0360 Micron Technology | No Yes No No |
430 | PAS106B PixArt Imaging, Inc. | 436 | OV7630 OmniVision Technologies | Yes Yes No No |
431 | PAS202BCA PixArt Imaging, Inc. | 437 | OV7660 OmniVision Technologies | No No Yes Yes |
432 | PAS202BCB PixArt Imaging, Inc. | 438 | PAS106B PixArt Imaging | Yes No No No |
433 | TAS5110C1B Taiwan Advanced Sensor Corporation | 439 | PAS202B PixArt Imaging | Yes Yes No No |
434 | TAS5130D1B Taiwan Advanced Sensor Corporation | 440 | TAS5110C1B Taiwan Advanced Sensor | Yes No No No |
435 | 441 | TAS5110D Taiwan Advanced Sensor | Yes No No No | |
436 | Some of the available control settings of each image sensor are supported | 442 | TAS5130D1B Taiwan Advanced Sensor | Yes No No No |
443 | |||
444 | "Yes" means that the pair is supported by the driver, while "No" means that the | ||
445 | pair does not exist or is not supported by the driver. | ||
446 | |||
447 | Only some of the available control settings of each image sensor are supported | ||
437 | through the V4L2 interface. | 448 | through the V4L2 interface. |
438 | 449 | ||
439 | Donations of new models for further testing and support would be much | 450 | Donations of new models for further testing and support would be much |
@@ -482,8 +493,8 @@ The SN9C1xx PC Camera Controllers can send images in two possible video | |||
482 | formats over the USB: either native "Sequential RGB Bayer" or compressed. | 493 | formats over the USB: either native "Sequential RGB Bayer" or compressed. |
483 | The compression is used to achieve high frame rates. With regard to the | 494 | The compression is used to achieve high frame rates. With regard to the |
484 | SN9C101, SN9C102 and SN9C103, the compression is based on the Huffman encoding | 495 | SN9C101, SN9C102 and SN9C103, the compression is based on the Huffman encoding |
485 | algorithm described below, while the SN9C105 and SN9C120 the compression is | 496 | algorithm described below, while with regard to the SN9C105 and SN9C120 the |
486 | based on the JPEG standard. | 497 | compression is based on the JPEG standard. |
487 | The current video format may be selected or queried from the user application | 498 | The current video format may be selected or queried from the user application |
488 | by calling the VIDIOC_S_FMT or VIDIOC_G_FMT ioctl's, as described in the V4L2 | 499 | by calling the VIDIOC_S_FMT or VIDIOC_G_FMT ioctl's, as described in the V4L2 |
489 | API specifications. | 500 | API specifications. |
@@ -573,4 +584,5 @@ order): | |||
573 | - Mizuno Takafumi for the donation of a webcam; | 584 | - Mizuno Takafumi for the donation of a webcam; |
574 | - an "anonymous" donator (who didn't want his name to be revealed) for the | 585 | - an "anonymous" donator (who didn't want his name to be revealed) for the |
575 | donation of a webcam. | 586 | donation of a webcam. |
576 | - an anonymous donator for the donation of four webcams. | 587 | - an anonymous donator for the donation of four webcams and two boards with ten |
588 | image sensors. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 8a2f2fd5403e..415011c9d84e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3606,7 +3606,7 @@ L: linux-usb-devel@lists.sourceforge.net | |||
3606 | W: http://www.connecttech.com | 3606 | W: http://www.connecttech.com |
3607 | S: Supported | 3607 | S: Supported |
3608 | 3608 | ||
3609 | USB SN9C10x DRIVER | 3609 | USB SN9C1xx DRIVER |
3610 | P: Luca Risolia | 3610 | P: Luca Risolia |
3611 | M: luca.risolia@studio.unibo.it | 3611 | M: luca.risolia@studio.unibo.it |
3612 | L: linux-usb-devel@lists.sourceforge.net | 3612 | L: linux-usb-devel@lists.sourceforge.net |
diff --git a/drivers/media/video/sn9c102/Makefile b/drivers/media/video/sn9c102/Makefile index 30e3dfe537fe..a56d16f69c71 100644 --- a/drivers/media/video/sn9c102/Makefile +++ b/drivers/media/video/sn9c102/Makefile | |||
@@ -1,7 +1,14 @@ | |||
1 | sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o \ | 1 | sn9c102-objs := sn9c102_core.o \ |
2 | sn9c102_ov7630.o sn9c102_ov7660.o sn9c102_pas106b.o \ | 2 | sn9c102_hv7131d.o \ |
3 | sn9c102_pas202bcb.o sn9c102_tas5110c1b.o \ | 3 | sn9c102_hv7131r.o \ |
4 | sn9c102_tas5130d1b.o | 4 | sn9c102_mi0343.o \ |
5 | sn9c102_mi0360.o \ | ||
6 | sn9c102_ov7630.o \ | ||
7 | sn9c102_ov7660.o \ | ||
8 | sn9c102_pas106b.o \ | ||
9 | sn9c102_pas202bcb.o \ | ||
10 | sn9c102_tas5110c1b.o \ | ||
11 | sn9c102_tas5110d.o \ | ||
12 | sn9c102_tas5130d1b.o | ||
5 | 13 | ||
6 | obj-$(CONFIG_USB_SN9C102) += sn9c102.o | 14 | obj-$(CONFIG_USB_SN9C102) += sn9c102.o |
7 | |||
diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/media/video/sn9c102/sn9c102.h index 5428f34e7c5b..680e74634527 100644 --- a/drivers/media/video/sn9c102/sn9c102.h +++ b/drivers/media/video/sn9c102/sn9c102.h | |||
@@ -78,8 +78,13 @@ enum sn9c102_stream_state { | |||
78 | 78 | ||
79 | typedef char sn9c102_sof_header_t[62]; | 79 | typedef char sn9c102_sof_header_t[62]; |
80 | 80 | ||
81 | struct sn9c102_sof_t { | ||
82 | sn9c102_sof_header_t header; | ||
83 | u16 bytesread; | ||
84 | }; | ||
85 | |||
81 | struct sn9c102_sysfs_attr { | 86 | struct sn9c102_sysfs_attr { |
82 | u8 reg, i2c_reg; | 87 | u16 reg, i2c_reg; |
83 | sn9c102_sof_header_t frame_header; | 88 | sn9c102_sof_header_t frame_header; |
84 | }; | 89 | }; |
85 | 90 | ||
@@ -112,7 +117,7 @@ struct sn9c102_device { | |||
112 | struct v4l2_jpegcompression compression; | 117 | struct v4l2_jpegcompression compression; |
113 | 118 | ||
114 | struct sn9c102_sysfs_attr sysfs; | 119 | struct sn9c102_sysfs_attr sysfs; |
115 | sn9c102_sof_header_t sof_header; | 120 | struct sn9c102_sof_t sof; |
116 | u16 reg[384]; | 121 | u16 reg[384]; |
117 | 122 | ||
118 | struct sn9c102_module_param module_param; | 123 | struct sn9c102_module_param module_param; |
@@ -182,8 +187,8 @@ do { \ | |||
182 | if ((level) == 1 || (level) == 2) \ | 187 | if ((level) == 1 || (level) == 2) \ |
183 | pr_info("sn9c102: " fmt "\n", ## args); \ | 188 | pr_info("sn9c102: " fmt "\n", ## args); \ |
184 | else if ((level) == 3) \ | 189 | else if ((level) == 3) \ |
185 | pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \ | 190 | pr_debug("sn9c102: [%s:%d] " fmt "\n", \ |
186 | __LINE__ , ## args); \ | 191 | __FUNCTION__, __LINE__ , ## args); \ |
187 | } \ | 192 | } \ |
188 | } while (0) | 193 | } while (0) |
189 | #else | 194 | #else |
@@ -194,8 +199,8 @@ do { \ | |||
194 | 199 | ||
195 | #undef PDBG | 200 | #undef PDBG |
196 | #define PDBG(fmt, args...) \ | 201 | #define PDBG(fmt, args...) \ |
197 | dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ | 202 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \ |
198 | __FUNCTION__, __LINE__ , ## args) | 203 | __LINE__ , ## args) |
199 | 204 | ||
200 | #undef PDBGG | 205 | #undef PDBGG |
201 | #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ | 206 | #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ |
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index d0e2b40a7725..f09caf2b6e75 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
@@ -44,11 +44,12 @@ | |||
44 | /*****************************************************************************/ | 44 | /*****************************************************************************/ |
45 | 45 | ||
46 | #define SN9C102_MODULE_NAME "V4L2 driver for SN9C1xx PC Camera Controllers" | 46 | #define SN9C102_MODULE_NAME "V4L2 driver for SN9C1xx PC Camera Controllers" |
47 | #define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia" | 47 | #define SN9C102_MODULE_ALIAS "sn9c1xx" |
48 | #define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia" | ||
48 | #define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" | 49 | #define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" |
49 | #define SN9C102_MODULE_LICENSE "GPL" | 50 | #define SN9C102_MODULE_LICENSE "GPL" |
50 | #define SN9C102_MODULE_VERSION "1:1.34" | 51 | #define SN9C102_MODULE_VERSION "1:1.39" |
51 | #define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 34) | 52 | #define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 39) |
52 | 53 | ||
53 | /*****************************************************************************/ | 54 | /*****************************************************************************/ |
54 | 55 | ||
@@ -56,6 +57,7 @@ MODULE_DEVICE_TABLE(usb, sn9c102_id_table); | |||
56 | 57 | ||
57 | MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL); | 58 | MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL); |
58 | MODULE_DESCRIPTION(SN9C102_MODULE_NAME); | 59 | MODULE_DESCRIPTION(SN9C102_MODULE_NAME); |
60 | MODULE_ALIAS(SN9C102_MODULE_ALIAS); | ||
59 | MODULE_VERSION(SN9C102_MODULE_VERSION); | 61 | MODULE_VERSION(SN9C102_MODULE_VERSION); |
60 | MODULE_LICENSE(SN9C102_MODULE_LICENSE); | 62 | MODULE_LICENSE(SN9C102_MODULE_LICENSE); |
61 | 63 | ||
@@ -106,8 +108,7 @@ MODULE_PARM_DESC(debug, | |||
106 | "\n1 = critical errors" | 108 | "\n1 = critical errors" |
107 | "\n2 = significant informations" | 109 | "\n2 = significant informations" |
108 | "\n3 = more verbose messages" | 110 | "\n3 = more verbose messages" |
109 | "\nLevel 3 is useful for testing only, when only " | 111 | "\nLevel 3 is useful for testing only." |
110 | "one device is used." | ||
111 | "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"." | 112 | "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"." |
112 | "\n"); | 113 | "\n"); |
113 | #endif | 114 | #endif |
@@ -121,8 +122,8 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, | |||
121 | struct v4l2_pix_format* p = &(cam->sensor.pix_format); | 122 | struct v4l2_pix_format* p = &(cam->sensor.pix_format); |
122 | struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); | 123 | struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); |
123 | size_t imagesize = cam->module_param.force_munmap || io == IO_READ ? | 124 | size_t imagesize = cam->module_param.force_munmap || io == IO_READ ? |
124 | (p->width * p->height * p->priv) / 8 : | 125 | (p->width * p->height * p->priv) / 8 : |
125 | (r->width * r->height * p->priv) / 8; | 126 | (r->width * r->height * p->priv) / 8; |
126 | void* buff = NULL; | 127 | void* buff = NULL; |
127 | u32 i; | 128 | u32 i; |
128 | 129 | ||
@@ -485,18 +486,43 @@ static size_t sn9c102_sof_length(struct sn9c102_device* cam) | |||
485 | static void* | 486 | static void* |
486 | sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) | 487 | sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) |
487 | { | 488 | { |
488 | char sof_header[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; | 489 | const char marker[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; |
489 | size_t soflen = 0, i; | 490 | const char *m = mem; |
491 | size_t soflen = 0, i, j; | ||
490 | 492 | ||
491 | soflen = sn9c102_sof_length(cam); | 493 | soflen = sn9c102_sof_length(cam); |
492 | 494 | ||
493 | for (i = 0; (len >= soflen) && (i <= len - soflen); i++) | 495 | for (i = 0; i < len; i++) { |
494 | if (!memcmp(mem + i, sof_header, sizeof(sof_header))) { | 496 | size_t b; |
495 | memcpy(cam->sof_header, mem + i, | 497 | |
496 | sizeof(sn9c102_sof_header_t)); | 498 | /* Read the variable part of the header */ |
497 | /* Skip the header */ | 499 | if (unlikely(cam->sof.bytesread >= sizeof(marker))) { |
498 | return mem + i + soflen; | 500 | cam->sof.header[cam->sof.bytesread] = *(m+i); |
501 | if (++cam->sof.bytesread == soflen) { | ||
502 | cam->sof.bytesread = 0; | ||
503 | return mem + i; | ||
504 | } | ||
505 | continue; | ||
506 | } | ||
507 | |||
508 | /* Search for the SOF marker (fixed part) in the header */ | ||
509 | for (j = 0, b=cam->sof.bytesread; j+b < sizeof(marker); j++) { | ||
510 | if (unlikely(i+j) == len) | ||
511 | return NULL; | ||
512 | if (*(m+i+j) == marker[cam->sof.bytesread]) { | ||
513 | cam->sof.header[cam->sof.bytesread] = *(m+i+j); | ||
514 | if (++cam->sof.bytesread == sizeof(marker)) { | ||
515 | PDBGG("Bytes to analyze: %zd. SOF " | ||
516 | "starts at byte #%zd", len, i); | ||
517 | i += j+1; | ||
518 | break; | ||
519 | } | ||
520 | } else { | ||
521 | cam->sof.bytesread = 0; | ||
522 | break; | ||
499 | } | 523 | } |
524 | } | ||
525 | } | ||
500 | 526 | ||
501 | return NULL; | 527 | return NULL; |
502 | } | 528 | } |
@@ -513,10 +539,16 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len) | |||
513 | }; | 539 | }; |
514 | size_t i, j; | 540 | size_t i, j; |
515 | 541 | ||
542 | /* The EOF header does not exist in compressed data */ | ||
516 | if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X || | 543 | if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X || |
517 | cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG) | 544 | cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG) |
518 | return NULL; /* EOF header does not exist in compressed data */ | 545 | return NULL; |
519 | 546 | ||
547 | /* | ||
548 | The EOF header might cross the packet boundary, but this is not a | ||
549 | problem, since the end of a frame is determined by checking its size | ||
550 | in the first place. | ||
551 | */ | ||
520 | for (i = 0; (len >= 4) && (i <= len - 4); i++) | 552 | for (i = 0; (len >= 4) && (i <= len - 4); i++) |
521 | for (j = 0; j < ARRAY_SIZE(eof_header); j++) | 553 | for (j = 0; j < ARRAY_SIZE(eof_header); j++) |
522 | if (!memcmp(mem + i, eof_header[j], 4)) | 554 | if (!memcmp(mem + i, eof_header[j], 4)) |
@@ -639,6 +671,7 @@ static void sn9c102_urb_complete(struct urb *urb) | |||
639 | cam->stream = STREAM_OFF; | 671 | cam->stream = STREAM_OFF; |
640 | if ((*f)) | 672 | if ((*f)) |
641 | (*f)->state = F_QUEUED; | 673 | (*f)->state = F_QUEUED; |
674 | cam->sof.bytesread = 0; | ||
642 | DBG(3, "Stream interrupted by application"); | 675 | DBG(3, "Stream interrupted by application"); |
643 | wake_up(&cam->wait_stream); | 676 | wake_up(&cam->wait_stream); |
644 | } | 677 | } |
@@ -676,6 +709,7 @@ static void sn9c102_urb_complete(struct urb *urb) | |||
676 | if (status) { | 709 | if (status) { |
677 | DBG(3, "Error in isochronous frame"); | 710 | DBG(3, "Error in isochronous frame"); |
678 | (*f)->state = F_ERROR; | 711 | (*f)->state = F_ERROR; |
712 | cam->sof.bytesread = 0; | ||
679 | continue; | 713 | continue; |
680 | } | 714 | } |
681 | 715 | ||
@@ -692,13 +726,13 @@ end_of_frame: | |||
692 | if (eof) | 726 | if (eof) |
693 | img = (eof > pos) ? eof - pos - 1 : 0; | 727 | img = (eof > pos) ? eof - pos - 1 : 0; |
694 | 728 | ||
695 | if ((*f)->buf.bytesused+img > imagesize) { | 729 | if ((*f)->buf.bytesused + img > imagesize) { |
696 | u32 b; | 730 | u32 b; |
697 | b = (*f)->buf.bytesused + img - | 731 | b = (*f)->buf.bytesused + img - |
698 | imagesize; | 732 | imagesize; |
699 | img = imagesize - (*f)->buf.bytesused; | 733 | img = imagesize - (*f)->buf.bytesused; |
700 | DBG(3, "Expected EOF not found: " | 734 | PDBGG("Expected EOF not found: video " |
701 | "video frame cut"); | 735 | "frame cut"); |
702 | if (eof) | 736 | if (eof) |
703 | DBG(3, "Exceeded limit: +%u " | 737 | DBG(3, "Exceeded limit: +%u " |
704 | "bytes", (unsigned)(b)); | 738 | "bytes", (unsigned)(b)); |
@@ -719,11 +753,6 @@ end_of_frame: | |||
719 | V4L2_PIX_FMT_JPEG) && eof)) { | 753 | V4L2_PIX_FMT_JPEG) && eof)) { |
720 | u32 b; | 754 | u32 b; |
721 | 755 | ||
722 | if (cam->sensor.pix_format.pixelformat | ||
723 | == V4L2_PIX_FMT_JPEG) | ||
724 | sn9c102_write_eoimarker(cam, | ||
725 | (*f)); | ||
726 | |||
727 | b = (*f)->buf.bytesused; | 756 | b = (*f)->buf.bytesused; |
728 | (*f)->state = F_DONE; | 757 | (*f)->state = F_DONE; |
729 | (*f)->buf.sequence= ++cam->frame_count; | 758 | (*f)->buf.sequence= ++cam->frame_count; |
@@ -741,7 +770,7 @@ end_of_frame: | |||
741 | spin_unlock(&cam->queue_lock); | 770 | spin_unlock(&cam->queue_lock); |
742 | 771 | ||
743 | memcpy(cam->sysfs.frame_header, | 772 | memcpy(cam->sysfs.frame_header, |
744 | cam->sof_header, soflen); | 773 | cam->sof.header, soflen); |
745 | 774 | ||
746 | DBG(3, "Video frame captured: %lu " | 775 | DBG(3, "Video frame captured: %lu " |
747 | "bytes", (unsigned long)(b)); | 776 | "bytes", (unsigned long)(b)); |
@@ -791,7 +820,13 @@ start_of_frame: | |||
791 | V4L2_PIX_FMT_SN9C10X || | 820 | V4L2_PIX_FMT_SN9C10X || |
792 | cam->sensor.pix_format.pixelformat == | 821 | cam->sensor.pix_format.pixelformat == |
793 | V4L2_PIX_FMT_JPEG) { | 822 | V4L2_PIX_FMT_JPEG) { |
794 | eof = sof - soflen; | 823 | if (sof - pos >= soflen) { |
824 | eof = sof - soflen; | ||
825 | } else { /* remove header */ | ||
826 | eof = pos; | ||
827 | (*f)->buf.bytesused -= | ||
828 | (soflen - (sof - pos)); | ||
829 | } | ||
795 | goto end_of_frame; | 830 | goto end_of_frame; |
796 | } else { | 831 | } else { |
797 | DBG(3, "SOF before expected EOF after " | 832 | DBG(3, "SOF before expected EOF after " |
@@ -878,6 +913,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) | |||
878 | } | 913 | } |
879 | 914 | ||
880 | cam->frame_current = NULL; | 915 | cam->frame_current = NULL; |
916 | cam->sof.bytesread = 0; | ||
881 | 917 | ||
882 | for (i = 0; i < SN9C102_URBS; i++) { | 918 | for (i = 0; i < SN9C102_URBS; i++) { |
883 | err = usb_submit_urb(cam->urb[i], GFP_KERNEL); | 919 | err = usb_submit_urb(cam->urb[i], GFP_KERNEL); |
@@ -959,9 +995,9 @@ static u16 sn9c102_strtou16(const char* buff, size_t len, ssize_t* count) | |||
959 | 995 | ||
960 | if (len < 6) { | 996 | if (len < 6) { |
961 | strncpy(str, buff, len); | 997 | strncpy(str, buff, len); |
962 | str[len+1] = '\0'; | 998 | str[len] = '\0'; |
963 | } else { | 999 | } else { |
964 | strncpy(str, buff, 4); | 1000 | strncpy(str, buff, 6); |
965 | str[6] = '\0'; | 1001 | str[6] = '\0'; |
966 | } | 1002 | } |
967 | 1003 | ||
@@ -1062,7 +1098,7 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf) | |||
1062 | 1098 | ||
1063 | count = sprintf(buf, "%d\n", val); | 1099 | count = sprintf(buf, "%d\n", val); |
1064 | 1100 | ||
1065 | DBG(3, "Read bytes: %zd", count); | 1101 | DBG(3, "Read bytes: %zd, value: %d", count, val); |
1066 | 1102 | ||
1067 | mutex_unlock(&sn9c102_sysfs_lock); | 1103 | mutex_unlock(&sn9c102_sysfs_lock); |
1068 | 1104 | ||
@@ -1197,7 +1233,7 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf) | |||
1197 | 1233 | ||
1198 | count = sprintf(buf, "%d\n", val); | 1234 | count = sprintf(buf, "%d\n", val); |
1199 | 1235 | ||
1200 | DBG(3, "Read bytes: %zd", count); | 1236 | DBG(3, "Read bytes: %zd, value: %d", count, val); |
1201 | 1237 | ||
1202 | mutex_unlock(&sn9c102_sysfs_lock); | 1238 | mutex_unlock(&sn9c102_sysfs_lock); |
1203 | 1239 | ||
@@ -1477,10 +1513,10 @@ sn9c102_set_compression(struct sn9c102_device* cam, | |||
1477 | case BRIDGE_SN9C101: | 1513 | case BRIDGE_SN9C101: |
1478 | case BRIDGE_SN9C102: | 1514 | case BRIDGE_SN9C102: |
1479 | case BRIDGE_SN9C103: | 1515 | case BRIDGE_SN9C103: |
1480 | if (compression->quality == 0) | 1516 | if (compression->quality == 0) |
1481 | err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01, | 1517 | err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01, |
1482 | 0x17); | 1518 | 0x17); |
1483 | else if (compression->quality == 1) | 1519 | else if (compression->quality == 1) |
1484 | err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe, | 1520 | err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe, |
1485 | 0x17); | 1521 | 0x17); |
1486 | break; | 1522 | break; |
@@ -1489,10 +1525,10 @@ sn9c102_set_compression(struct sn9c102_device* cam, | |||
1489 | if (compression->quality == 0) { | 1525 | if (compression->quality == 0) { |
1490 | for (i = 0; i <= 63; i++) { | 1526 | for (i = 0; i <= 63; i++) { |
1491 | err += sn9c102_write_reg(cam, | 1527 | err += sn9c102_write_reg(cam, |
1492 | SN9C102_Y_QTABLE0[i], | 1528 | SN9C102_Y_QTABLE1[i], |
1493 | 0x100 + i); | 1529 | 0x100 + i); |
1494 | err += sn9c102_write_reg(cam, | 1530 | err += sn9c102_write_reg(cam, |
1495 | SN9C102_UV_QTABLE0[i], | 1531 | SN9C102_UV_QTABLE1[i], |
1496 | 0x140 + i); | 1532 | 0x140 + i); |
1497 | } | 1533 | } |
1498 | err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf, | 1534 | err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf, |
@@ -1597,9 +1633,13 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1597 | if (cam->bridge == BRIDGE_SN9C101 || | 1633 | if (cam->bridge == BRIDGE_SN9C101 || |
1598 | cam->bridge == BRIDGE_SN9C102 || | 1634 | cam->bridge == BRIDGE_SN9C102 || |
1599 | cam->bridge == BRIDGE_SN9C103) { | 1635 | cam->bridge == BRIDGE_SN9C103) { |
1636 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG) | ||
1637 | s->pix_format.pixelformat= V4L2_PIX_FMT_SBGGR8; | ||
1600 | cam->compression.quality = cam->reg[0x17] & 0x01 ? | 1638 | cam->compression.quality = cam->reg[0x17] & 0x01 ? |
1601 | 0 : 1; | 1639 | 0 : 1; |
1602 | } else { | 1640 | } else { |
1641 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) | ||
1642 | s->pix_format.pixelformat = V4L2_PIX_FMT_JPEG; | ||
1603 | cam->compression.quality = cam->reg[0x18] & 0x40 ? | 1643 | cam->compression.quality = cam->reg[0x18] & 0x40 ? |
1604 | 0 : 1; | 1644 | 0 : 1; |
1605 | err += sn9c102_set_compression(cam, &cam->compression); | 1645 | err += sn9c102_set_compression(cam, &cam->compression); |
@@ -1805,7 +1845,7 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) | |||
1805 | DBG(3, "Close and open the device again to choose " | 1845 | DBG(3, "Close and open the device again to choose " |
1806 | "the read method"); | 1846 | "the read method"); |
1807 | mutex_unlock(&cam->fileop_mutex); | 1847 | mutex_unlock(&cam->fileop_mutex); |
1808 | return -EINVAL; | 1848 | return -EBUSY; |
1809 | } | 1849 | } |
1810 | 1850 | ||
1811 | if (cam->io == IO_NONE) { | 1851 | if (cam->io == IO_NONE) { |
@@ -1845,16 +1885,16 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) | |||
1845 | return err; | 1885 | return err; |
1846 | } | 1886 | } |
1847 | } else { | 1887 | } else { |
1848 | timeout = wait_event_interruptible_timeout | 1888 | timeout = wait_event_interruptible_timeout |
1849 | ( cam->wait_frame, | 1889 | ( cam->wait_frame, |
1850 | (!list_empty(&cam->outqueue)) || | 1890 | (!list_empty(&cam->outqueue)) || |
1851 | (cam->state & DEV_DISCONNECTED) || | 1891 | (cam->state & DEV_DISCONNECTED) || |
1852 | (cam->state & DEV_MISCONFIGURED), | 1892 | (cam->state & DEV_MISCONFIGURED), |
1853 | cam->module_param.frame_timeout * | 1893 | cam->module_param.frame_timeout * |
1854 | 1000 * msecs_to_jiffies(1) ); | 1894 | 1000 * msecs_to_jiffies(1) ); |
1855 | if (timeout < 0) { | 1895 | if (timeout < 0) { |
1856 | mutex_unlock(&cam->fileop_mutex); | 1896 | mutex_unlock(&cam->fileop_mutex); |
1857 | return timeout; | 1897 | return timeout; |
1858 | } else if (timeout == 0 && | 1898 | } else if (timeout == 0 && |
1859 | !(cam->state & DEV_DISCONNECTED)) { | 1899 | !(cam->state & DEV_DISCONNECTED)) { |
1860 | DBG(1, "Video frame timeout elapsed"); | 1900 | DBG(1, "Video frame timeout elapsed"); |
@@ -2001,7 +2041,12 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) | |||
2001 | return -EIO; | 2041 | return -EIO; |
2002 | } | 2042 | } |
2003 | 2043 | ||
2004 | if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || | 2044 | if (!(vma->vm_flags & (VM_WRITE | VM_READ))) { |
2045 | mutex_unlock(&cam->fileop_mutex); | ||
2046 | return -EACCES; | ||
2047 | } | ||
2048 | |||
2049 | if (cam->io != IO_MMAP || | ||
2005 | size != PAGE_ALIGN(cam->frame[0].buf.length)) { | 2050 | size != PAGE_ALIGN(cam->frame[0].buf.length)) { |
2006 | mutex_unlock(&cam->fileop_mutex); | 2051 | mutex_unlock(&cam->fileop_mutex); |
2007 | return -EINVAL; | 2052 | return -EINVAL; |
@@ -2267,7 +2312,7 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg) | |||
2267 | if (cam->frame[i].vma_use_count) { | 2312 | if (cam->frame[i].vma_use_count) { |
2268 | DBG(3, "VIDIOC_S_CROP failed. " | 2313 | DBG(3, "VIDIOC_S_CROP failed. " |
2269 | "Unmap the buffers first."); | 2314 | "Unmap the buffers first."); |
2270 | return -EINVAL; | 2315 | return -EBUSY; |
2271 | } | 2316 | } |
2272 | 2317 | ||
2273 | /* Preserve R,G or B origin */ | 2318 | /* Preserve R,G or B origin */ |
@@ -2410,8 +2455,8 @@ sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg) | |||
2410 | case BRIDGE_SN9C101: | 2455 | case BRIDGE_SN9C101: |
2411 | case BRIDGE_SN9C102: | 2456 | case BRIDGE_SN9C102: |
2412 | case BRIDGE_SN9C103: | 2457 | case BRIDGE_SN9C103: |
2413 | strcpy(fmtd.description, "compressed"); | 2458 | strcpy(fmtd.description, "compressed"); |
2414 | fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X; | 2459 | fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X; |
2415 | break; | 2460 | break; |
2416 | case BRIDGE_SN9C105: | 2461 | case BRIDGE_SN9C105: |
2417 | case BRIDGE_SN9C120: | 2462 | case BRIDGE_SN9C120: |
@@ -2445,8 +2490,10 @@ sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg) | |||
2445 | if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 2490 | if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
2446 | return -EINVAL; | 2491 | return -EINVAL; |
2447 | 2492 | ||
2448 | pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X || | 2493 | pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_JPEG) ? |
2449 | pfmt->pixelformat==V4L2_PIX_FMT_JPEG) | 2494 | V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB; |
2495 | pfmt->bytesperline = (pfmt->pixelformat == V4L2_PIX_FMT_SN9C10X || | ||
2496 | pfmt->pixelformat == V4L2_PIX_FMT_JPEG) | ||
2450 | ? 0 : (pfmt->width * pfmt->priv) / 8; | 2497 | ? 0 : (pfmt->width * pfmt->priv) / 8; |
2451 | pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); | 2498 | pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); |
2452 | pfmt->field = V4L2_FIELD_NONE; | 2499 | pfmt->field = V4L2_FIELD_NONE; |
@@ -2521,9 +2568,9 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, | |||
2521 | case BRIDGE_SN9C101: | 2568 | case BRIDGE_SN9C101: |
2522 | case BRIDGE_SN9C102: | 2569 | case BRIDGE_SN9C102: |
2523 | case BRIDGE_SN9C103: | 2570 | case BRIDGE_SN9C103: |
2524 | if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X && | 2571 | if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X && |
2525 | pix->pixelformat != V4L2_PIX_FMT_SBGGR8) | 2572 | pix->pixelformat != V4L2_PIX_FMT_SBGGR8) |
2526 | pix->pixelformat = pfmt->pixelformat; | 2573 | pix->pixelformat = pfmt->pixelformat; |
2527 | break; | 2574 | break; |
2528 | case BRIDGE_SN9C105: | 2575 | case BRIDGE_SN9C105: |
2529 | case BRIDGE_SN9C120: | 2576 | case BRIDGE_SN9C120: |
@@ -2533,7 +2580,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, | |||
2533 | break; | 2580 | break; |
2534 | } | 2581 | } |
2535 | pix->priv = pfmt->priv; /* bpp */ | 2582 | pix->priv = pfmt->priv; /* bpp */ |
2536 | pix->colorspace = pfmt->colorspace; | 2583 | pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_JPEG) ? |
2584 | V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB; | ||
2537 | pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X || | 2585 | pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X || |
2538 | pix->pixelformat == V4L2_PIX_FMT_JPEG) | 2586 | pix->pixelformat == V4L2_PIX_FMT_JPEG) |
2539 | ? 0 : (pix->width * pix->priv) / 8; | 2587 | ? 0 : (pix->width * pix->priv) / 8; |
@@ -2551,7 +2599,7 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, | |||
2551 | if (cam->frame[i].vma_use_count) { | 2599 | if (cam->frame[i].vma_use_count) { |
2552 | DBG(3, "VIDIOC_S_FMT failed. Unmap the " | 2600 | DBG(3, "VIDIOC_S_FMT failed. Unmap the " |
2553 | "buffers first."); | 2601 | "buffers first."); |
2554 | return -EINVAL; | 2602 | return -EBUSY; |
2555 | } | 2603 | } |
2556 | 2604 | ||
2557 | if (cam->stream == STREAM_ON) | 2605 | if (cam->stream == STREAM_ON) |
@@ -2666,14 +2714,14 @@ sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg) | |||
2666 | if (cam->io == IO_READ) { | 2714 | if (cam->io == IO_READ) { |
2667 | DBG(3, "Close and open the device again to choose the mmap " | 2715 | DBG(3, "Close and open the device again to choose the mmap " |
2668 | "I/O method"); | 2716 | "I/O method"); |
2669 | return -EINVAL; | 2717 | return -EBUSY; |
2670 | } | 2718 | } |
2671 | 2719 | ||
2672 | for (i = 0; i < cam->nbuffers; i++) | 2720 | for (i = 0; i < cam->nbuffers; i++) |
2673 | if (cam->frame[i].vma_use_count) { | 2721 | if (cam->frame[i].vma_use_count) { |
2674 | DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are " | 2722 | DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are " |
2675 | "still mapped."); | 2723 | "still mapped."); |
2676 | return -EINVAL; | 2724 | return -EBUSY; |
2677 | } | 2725 | } |
2678 | 2726 | ||
2679 | if (cam->stream == STREAM_ON) | 2727 | if (cam->stream == STREAM_ON) |
@@ -2785,15 +2833,15 @@ sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp, | |||
2785 | if (err) | 2833 | if (err) |
2786 | return err; | 2834 | return err; |
2787 | } else { | 2835 | } else { |
2788 | timeout = wait_event_interruptible_timeout | 2836 | timeout = wait_event_interruptible_timeout |
2789 | ( cam->wait_frame, | 2837 | ( cam->wait_frame, |
2790 | (!list_empty(&cam->outqueue)) || | 2838 | (!list_empty(&cam->outqueue)) || |
2791 | (cam->state & DEV_DISCONNECTED) || | 2839 | (cam->state & DEV_DISCONNECTED) || |
2792 | (cam->state & DEV_MISCONFIGURED), | 2840 | (cam->state & DEV_MISCONFIGURED), |
2793 | cam->module_param.frame_timeout * | 2841 | cam->module_param.frame_timeout * |
2794 | 1000 * msecs_to_jiffies(1) ); | 2842 | 1000 * msecs_to_jiffies(1) ); |
2795 | if (timeout < 0) | 2843 | if (timeout < 0) |
2796 | return timeout; | 2844 | return timeout; |
2797 | else if (timeout == 0 && | 2845 | else if (timeout == 0 && |
2798 | !(cam->state & DEV_DISCONNECTED)) { | 2846 | !(cam->state & DEV_DISCONNECTED)) { |
2799 | DBG(1, "Video frame timeout elapsed"); | 2847 | DBG(1, "Video frame timeout elapsed"); |
@@ -2837,9 +2885,6 @@ sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg) | |||
2837 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) | 2885 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) |
2838 | return -EINVAL; | 2886 | return -EINVAL; |
2839 | 2887 | ||
2840 | if (list_empty(&cam->inqueue)) | ||
2841 | return -EINVAL; | ||
2842 | |||
2843 | cam->stream = STREAM_ON; | 2888 | cam->stream = STREAM_ON; |
2844 | 2889 | ||
2845 | DBG(3, "Stream on"); | 2890 | DBG(3, "Stream on"); |
@@ -3166,8 +3211,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3166 | 3211 | ||
3167 | r = sn9c102_read_reg(cam, 0x00); | 3212 | r = sn9c102_read_reg(cam, 0x00); |
3168 | if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) { | 3213 | if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) { |
3169 | DBG(1, "Sorry, this is not a SN9C1xx based camera " | 3214 | DBG(1, "Sorry, this is not a SN9C1xx-based camera " |
3170 | "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | 3215 | "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); |
3171 | err = -ENODEV; | 3216 | err = -ENODEV; |
3172 | goto fail; | 3217 | goto fail; |
3173 | } | 3218 | } |
@@ -3177,19 +3222,19 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3177 | case BRIDGE_SN9C101: | 3222 | case BRIDGE_SN9C101: |
3178 | case BRIDGE_SN9C102: | 3223 | case BRIDGE_SN9C102: |
3179 | DBG(2, "SN9C10[12] PC Camera Controller detected " | 3224 | DBG(2, "SN9C10[12] PC Camera Controller detected " |
3180 | "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | 3225 | "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); |
3181 | break; | 3226 | break; |
3182 | case BRIDGE_SN9C103: | 3227 | case BRIDGE_SN9C103: |
3183 | DBG(2, "SN9C103 PC Camera Controller detected " | 3228 | DBG(2, "SN9C103 PC Camera Controller detected " |
3184 | "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | 3229 | "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); |
3185 | break; | 3230 | break; |
3186 | case BRIDGE_SN9C105: | 3231 | case BRIDGE_SN9C105: |
3187 | DBG(2, "SN9C105 PC Camera Controller detected " | 3232 | DBG(2, "SN9C105 PC Camera Controller detected " |
3188 | "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | 3233 | "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); |
3189 | break; | 3234 | break; |
3190 | case BRIDGE_SN9C120: | 3235 | case BRIDGE_SN9C120: |
3191 | DBG(2, "SN9C120 PC Camera Controller detected " | 3236 | DBG(2, "SN9C120 PC Camera Controller detected " |
3192 | "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | 3237 | "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); |
3193 | break; | 3238 | break; |
3194 | } | 3239 | } |
3195 | 3240 | ||
@@ -3260,6 +3305,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3260 | "device controlling. Error #%d", err); | 3305 | "device controlling. Error #%d", err); |
3261 | #else | 3306 | #else |
3262 | DBG(2, "Optional device control through 'sysfs' interface disabled"); | 3307 | DBG(2, "Optional device control through 'sysfs' interface disabled"); |
3308 | DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' " | ||
3309 | "configuration option to enable it."); | ||
3263 | #endif | 3310 | #endif |
3264 | 3311 | ||
3265 | usb_set_intfdata(intf, cam); | 3312 | usb_set_intfdata(intf, cam); |
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h index 3a682eca6c65..f49bd8c5b86e 100644 --- a/drivers/media/video/sn9c102/sn9c102_devtable.h +++ b/drivers/media/video/sn9c102/sn9c102_devtable.h | |||
@@ -89,16 +89,22 @@ static const struct usb_device_id sn9c102_id_table[] = { | |||
89 | { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), }, | 89 | { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), }, |
90 | { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), }, | 90 | { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), }, |
91 | { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), }, | 91 | { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), }, |
92 | { SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), }, | ||
92 | { SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), }, | 93 | { SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), }, |
93 | { SN9C102_USB_DEVICE(0x0c45, 0x60cc, BRIDGE_SN9C105), }, | 94 | { SN9C102_USB_DEVICE(0x0c45, 0x60cc, BRIDGE_SN9C105), }, |
94 | { SN9C102_USB_DEVICE(0x0c45, 0x60ea, BRIDGE_SN9C105), }, | 95 | { SN9C102_USB_DEVICE(0x0c45, 0x60ea, BRIDGE_SN9C105), }, |
95 | { SN9C102_USB_DEVICE(0x0c45, 0x60ec, BRIDGE_SN9C105), }, | 96 | { SN9C102_USB_DEVICE(0x0c45, 0x60ec, BRIDGE_SN9C105), }, |
97 | { SN9C102_USB_DEVICE(0x0c45, 0x60ef, BRIDGE_SN9C105), }, | ||
96 | { SN9C102_USB_DEVICE(0x0c45, 0x60fa, BRIDGE_SN9C105), }, | 98 | { SN9C102_USB_DEVICE(0x0c45, 0x60fa, BRIDGE_SN9C105), }, |
97 | { SN9C102_USB_DEVICE(0x0c45, 0x60fb, BRIDGE_SN9C105), }, | 99 | { SN9C102_USB_DEVICE(0x0c45, 0x60fb, BRIDGE_SN9C105), }, |
98 | { SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), }, | 100 | { SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), }, |
99 | { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), }, | 101 | { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), }, |
100 | /* SN9C120 */ | 102 | /* SN9C120 */ |
103 | { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), }, | ||
104 | { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), }, | ||
105 | { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, | ||
101 | { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), }, | 106 | { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), }, |
107 | { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, | ||
102 | { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), }, | 108 | { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), }, |
103 | { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), }, | 109 | { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), }, |
104 | { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), }, | 110 | { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), }, |
@@ -114,12 +120,15 @@ static const struct usb_device_id sn9c102_id_table[] = { | |||
114 | Functions must return 0 on success, the appropriate error otherwise. | 120 | Functions must return 0 on success, the appropriate error otherwise. |
115 | */ | 121 | */ |
116 | extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam); | 122 | extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam); |
123 | extern int sn9c102_probe_hv7131r(struct sn9c102_device* cam); | ||
117 | extern int sn9c102_probe_mi0343(struct sn9c102_device* cam); | 124 | extern int sn9c102_probe_mi0343(struct sn9c102_device* cam); |
125 | extern int sn9c102_probe_mi0360(struct sn9c102_device* cam); | ||
118 | extern int sn9c102_probe_ov7630(struct sn9c102_device* cam); | 126 | extern int sn9c102_probe_ov7630(struct sn9c102_device* cam); |
119 | extern int sn9c102_probe_ov7660(struct sn9c102_device* cam); | 127 | extern int sn9c102_probe_ov7660(struct sn9c102_device* cam); |
120 | extern int sn9c102_probe_pas106b(struct sn9c102_device* cam); | 128 | extern int sn9c102_probe_pas106b(struct sn9c102_device* cam); |
121 | extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam); | 129 | extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam); |
122 | extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam); | 130 | extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam); |
131 | extern int sn9c102_probe_tas5110d(struct sn9c102_device* cam); | ||
123 | extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam); | 132 | extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam); |
124 | 133 | ||
125 | /* | 134 | /* |
@@ -128,13 +137,16 @@ extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam); | |||
128 | the order of the list below, from top to bottom. | 137 | the order of the list below, from top to bottom. |
129 | */ | 138 | */ |
130 | static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { | 139 | static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { |
140 | &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ | ||
141 | &sn9c102_probe_hv7131r, /* strong detection based on SENSOR ids */ | ||
131 | &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */ | 142 | &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */ |
143 | &sn9c102_probe_mi0360, /* strong detection based on SENSOR ids */ | ||
132 | &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ | 144 | &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ |
133 | &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ | 145 | &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ |
134 | &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ | ||
135 | &sn9c102_probe_ov7630, /* strong detection based on SENSOR ids */ | 146 | &sn9c102_probe_ov7630, /* strong detection based on SENSOR ids */ |
136 | &sn9c102_probe_ov7660, /* strong detection based on SENSOR ids */ | 147 | &sn9c102_probe_ov7660, /* strong detection based on SENSOR ids */ |
137 | &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ | 148 | &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ |
149 | &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */ | ||
138 | &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ | 150 | &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ |
139 | NULL, | 151 | NULL, |
140 | }; | 152 | }; |
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/drivers/media/video/sn9c102/sn9c102_hv7131d.c index 7ae368f60d89..9b2e2d68c739 100644 --- a/drivers/media/video/sn9c102/sn9c102_hv7131d.c +++ b/drivers/media/video/sn9c102/sn9c102_hv7131d.c | |||
@@ -22,9 +22,6 @@ | |||
22 | #include "sn9c102_sensor.h" | 22 | #include "sn9c102_sensor.h" |
23 | 23 | ||
24 | 24 | ||
25 | static struct sn9c102_sensor hv7131d; | ||
26 | |||
27 | |||
28 | static int hv7131d_init(struct sn9c102_device* cam) | 25 | static int hv7131d_init(struct sn9c102_device* cam) |
29 | { | 26 | { |
30 | int err = 0; | 27 | int err = 0; |
@@ -153,7 +150,7 @@ static int hv7131d_set_pix_format(struct sn9c102_device* cam, | |||
153 | static struct sn9c102_sensor hv7131d = { | 150 | static struct sn9c102_sensor hv7131d = { |
154 | .name = "HV7131D", | 151 | .name = "HV7131D", |
155 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | 152 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", |
156 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, | 153 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, |
157 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, | 154 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, |
158 | .frequency = SN9C102_I2C_100KHZ, | 155 | .frequency = SN9C102_I2C_100KHZ, |
159 | .interface = SN9C102_I2C_2WIRES, | 156 | .interface = SN9C102_I2C_2WIRES, |
@@ -263,7 +260,7 @@ int sn9c102_probe_hv7131d(struct sn9c102_device* cam) | |||
263 | if (r0 < 0 || r1 < 0) | 260 | if (r0 < 0 || r1 < 0) |
264 | return -EIO; | 261 | return -EIO; |
265 | 262 | ||
266 | if (r0 != 0x00 && r1 != 0x04) | 263 | if (r0 != 0x00 || r1 != 0x04) |
267 | return -ENODEV; | 264 | return -ENODEV; |
268 | 265 | ||
269 | sn9c102_attach_sensor(cam, &hv7131d); | 266 | sn9c102_attach_sensor(cam, &hv7131d); |
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131r.c b/drivers/media/video/sn9c102/sn9c102_hv7131r.c new file mode 100644 index 000000000000..c4a3e3991e88 --- /dev/null +++ b/drivers/media/video/sn9c102/sn9c102_hv7131r.c | |||
@@ -0,0 +1,458 @@ | |||
1 | /*************************************************************************** | ||
2 | * Plug-in for HV7131R image sensor connected to the SN9C1xx PC Camera * | ||
3 | * Controllers * | ||
4 | * * | ||
5 | * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> * | ||
6 | * * | ||
7 | * This program is free software; you can redistribute it and/or modify * | ||
8 | * it under the terms of the GNU General Public License as published by * | ||
9 | * the Free Software Foundation; either version 2 of the License, or * | ||
10 | * (at your option) any later version. * | ||
11 | * * | ||
12 | * This program is distributed in the hope that it will be useful, * | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
15 | * GNU General Public License for more details. * | ||
16 | * * | ||
17 | * You should have received a copy of the GNU General Public License * | ||
18 | * along with this program; if not, write to the Free Software * | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * | ||
20 | ***************************************************************************/ | ||
21 | |||
22 | #include "sn9c102_sensor.h" | ||
23 | |||
24 | |||
25 | static int hv7131r_init(struct sn9c102_device* cam) | ||
26 | { | ||
27 | int err = 0; | ||
28 | |||
29 | switch (sn9c102_get_bridge(cam)) { | ||
30 | case BRIDGE_SN9C103: | ||
31 | err += sn9c102_write_reg(cam, 0x00, 0x03); | ||
32 | err += sn9c102_write_reg(cam, 0x1a, 0x04); | ||
33 | err += sn9c102_write_reg(cam, 0x20, 0x05); | ||
34 | err += sn9c102_write_reg(cam, 0x20, 0x06); | ||
35 | err += sn9c102_write_reg(cam, 0x03, 0x10); | ||
36 | err += sn9c102_write_reg(cam, 0x00, 0x14); | ||
37 | err += sn9c102_write_reg(cam, 0x60, 0x17); | ||
38 | err += sn9c102_write_reg(cam, 0x0a, 0x18); | ||
39 | err += sn9c102_write_reg(cam, 0xf0, 0x19); | ||
40 | err += sn9c102_write_reg(cam, 0x1d, 0x1a); | ||
41 | err += sn9c102_write_reg(cam, 0x10, 0x1b); | ||
42 | err += sn9c102_write_reg(cam, 0x02, 0x1c); | ||
43 | err += sn9c102_write_reg(cam, 0x03, 0x1d); | ||
44 | err += sn9c102_write_reg(cam, 0x0f, 0x1e); | ||
45 | err += sn9c102_write_reg(cam, 0x0c, 0x1f); | ||
46 | err += sn9c102_write_reg(cam, 0x00, 0x20); | ||
47 | err += sn9c102_write_reg(cam, 0x10, 0x21); | ||
48 | err += sn9c102_write_reg(cam, 0x20, 0x22); | ||
49 | err += sn9c102_write_reg(cam, 0x30, 0x23); | ||
50 | err += sn9c102_write_reg(cam, 0x40, 0x24); | ||
51 | err += sn9c102_write_reg(cam, 0x50, 0x25); | ||
52 | err += sn9c102_write_reg(cam, 0x60, 0x26); | ||
53 | err += sn9c102_write_reg(cam, 0x70, 0x27); | ||
54 | err += sn9c102_write_reg(cam, 0x80, 0x28); | ||
55 | err += sn9c102_write_reg(cam, 0x90, 0x29); | ||
56 | err += sn9c102_write_reg(cam, 0xa0, 0x2a); | ||
57 | err += sn9c102_write_reg(cam, 0xb0, 0x2b); | ||
58 | err += sn9c102_write_reg(cam, 0xc0, 0x2c); | ||
59 | err += sn9c102_write_reg(cam, 0xd0, 0x2d); | ||
60 | err += sn9c102_write_reg(cam, 0xe0, 0x2e); | ||
61 | err += sn9c102_write_reg(cam, 0xf0, 0x2f); | ||
62 | err += sn9c102_write_reg(cam, 0xff, 0x30); | ||
63 | break; | ||
64 | case BRIDGE_SN9C105: | ||
65 | case BRIDGE_SN9C120: | ||
66 | err += sn9c102_write_reg(cam, 0x44, 0x01); | ||
67 | err += sn9c102_write_reg(cam, 0x40, 0x02); | ||
68 | err += sn9c102_write_reg(cam, 0x00, 0x03); | ||
69 | err += sn9c102_write_reg(cam, 0x1a, 0x04); | ||
70 | err += sn9c102_write_reg(cam, 0x44, 0x05); | ||
71 | err += sn9c102_write_reg(cam, 0x3e, 0x06); | ||
72 | err += sn9c102_write_reg(cam, 0x1a, 0x07); | ||
73 | err += sn9c102_write_reg(cam, 0x03, 0x10); | ||
74 | err += sn9c102_write_reg(cam, 0x08, 0x14); | ||
75 | err += sn9c102_write_reg(cam, 0xa3, 0x17); | ||
76 | err += sn9c102_write_reg(cam, 0x4b, 0x18); | ||
77 | err += sn9c102_write_reg(cam, 0x00, 0x19); | ||
78 | err += sn9c102_write_reg(cam, 0x1d, 0x1a); | ||
79 | err += sn9c102_write_reg(cam, 0x10, 0x1b); | ||
80 | err += sn9c102_write_reg(cam, 0x02, 0x1c); | ||
81 | err += sn9c102_write_reg(cam, 0x03, 0x1d); | ||
82 | err += sn9c102_write_reg(cam, 0x0f, 0x1e); | ||
83 | err += sn9c102_write_reg(cam, 0x0c, 0x1f); | ||
84 | err += sn9c102_write_reg(cam, 0x00, 0x20); | ||
85 | err += sn9c102_write_reg(cam, 0x29, 0x21); | ||
86 | err += sn9c102_write_reg(cam, 0x40, 0x22); | ||
87 | err += sn9c102_write_reg(cam, 0x54, 0x23); | ||
88 | err += sn9c102_write_reg(cam, 0x66, 0x24); | ||
89 | err += sn9c102_write_reg(cam, 0x76, 0x25); | ||
90 | err += sn9c102_write_reg(cam, 0x85, 0x26); | ||
91 | err += sn9c102_write_reg(cam, 0x94, 0x27); | ||
92 | err += sn9c102_write_reg(cam, 0xa1, 0x28); | ||
93 | err += sn9c102_write_reg(cam, 0xae, 0x29); | ||
94 | err += sn9c102_write_reg(cam, 0xbb, 0x2a); | ||
95 | err += sn9c102_write_reg(cam, 0xc7, 0x2b); | ||
96 | err += sn9c102_write_reg(cam, 0xd3, 0x2c); | ||
97 | err += sn9c102_write_reg(cam, 0xde, 0x2d); | ||
98 | err += sn9c102_write_reg(cam, 0xea, 0x2e); | ||
99 | err += sn9c102_write_reg(cam, 0xf4, 0x2f); | ||
100 | err += sn9c102_write_reg(cam, 0xff, 0x30); | ||
101 | err += sn9c102_write_reg(cam, 0x00, 0x3F); | ||
102 | err += sn9c102_write_reg(cam, 0xC7, 0x40); | ||
103 | err += sn9c102_write_reg(cam, 0x01, 0x41); | ||
104 | err += sn9c102_write_reg(cam, 0x44, 0x42); | ||
105 | err += sn9c102_write_reg(cam, 0x00, 0x43); | ||
106 | err += sn9c102_write_reg(cam, 0x44, 0x44); | ||
107 | err += sn9c102_write_reg(cam, 0x00, 0x45); | ||
108 | err += sn9c102_write_reg(cam, 0x44, 0x46); | ||
109 | err += sn9c102_write_reg(cam, 0x00, 0x47); | ||
110 | err += sn9c102_write_reg(cam, 0xC7, 0x48); | ||
111 | err += sn9c102_write_reg(cam, 0x01, 0x49); | ||
112 | err += sn9c102_write_reg(cam, 0xC7, 0x4A); | ||
113 | err += sn9c102_write_reg(cam, 0x01, 0x4B); | ||
114 | err += sn9c102_write_reg(cam, 0xC7, 0x4C); | ||
115 | err += sn9c102_write_reg(cam, 0x01, 0x4D); | ||
116 | err += sn9c102_write_reg(cam, 0x44, 0x4E); | ||
117 | err += sn9c102_write_reg(cam, 0x00, 0x4F); | ||
118 | err += sn9c102_write_reg(cam, 0x44, 0x50); | ||
119 | err += sn9c102_write_reg(cam, 0x00, 0x51); | ||
120 | err += sn9c102_write_reg(cam, 0x44, 0x52); | ||
121 | err += sn9c102_write_reg(cam, 0x00, 0x53); | ||
122 | err += sn9c102_write_reg(cam, 0xC7, 0x54); | ||
123 | err += sn9c102_write_reg(cam, 0x01, 0x55); | ||
124 | err += sn9c102_write_reg(cam, 0xC7, 0x56); | ||
125 | err += sn9c102_write_reg(cam, 0x01, 0x57); | ||
126 | err += sn9c102_write_reg(cam, 0xC7, 0x58); | ||
127 | err += sn9c102_write_reg(cam, 0x01, 0x59); | ||
128 | err += sn9c102_write_reg(cam, 0x44, 0x5A); | ||
129 | err += sn9c102_write_reg(cam, 0x00, 0x5B); | ||
130 | err += sn9c102_write_reg(cam, 0x44, 0x5C); | ||
131 | err += sn9c102_write_reg(cam, 0x00, 0x5D); | ||
132 | err += sn9c102_write_reg(cam, 0x44, 0x5E); | ||
133 | err += sn9c102_write_reg(cam, 0x00, 0x5F); | ||
134 | err += sn9c102_write_reg(cam, 0xC7, 0x60); | ||
135 | err += sn9c102_write_reg(cam, 0x01, 0x61); | ||
136 | err += sn9c102_write_reg(cam, 0xC7, 0x62); | ||
137 | err += sn9c102_write_reg(cam, 0x01, 0x63); | ||
138 | err += sn9c102_write_reg(cam, 0xC7, 0x64); | ||
139 | err += sn9c102_write_reg(cam, 0x01, 0x65); | ||
140 | err += sn9c102_write_reg(cam, 0x44, 0x66); | ||
141 | err += sn9c102_write_reg(cam, 0x00, 0x67); | ||
142 | err += sn9c102_write_reg(cam, 0x44, 0x68); | ||
143 | err += sn9c102_write_reg(cam, 0x00, 0x69); | ||
144 | err += sn9c102_write_reg(cam, 0x44, 0x6A); | ||
145 | err += sn9c102_write_reg(cam, 0x00, 0x6B); | ||
146 | err += sn9c102_write_reg(cam, 0xC7, 0x6C); | ||
147 | err += sn9c102_write_reg(cam, 0x01, 0x6D); | ||
148 | err += sn9c102_write_reg(cam, 0xC7, 0x6E); | ||
149 | err += sn9c102_write_reg(cam, 0x01, 0x6F); | ||
150 | err += sn9c102_write_reg(cam, 0xC7, 0x70); | ||
151 | err += sn9c102_write_reg(cam, 0x01, 0x71); | ||
152 | err += sn9c102_write_reg(cam, 0x44, 0x72); | ||
153 | err += sn9c102_write_reg(cam, 0x00, 0x73); | ||
154 | err += sn9c102_write_reg(cam, 0x44, 0x74); | ||
155 | err += sn9c102_write_reg(cam, 0x00, 0x75); | ||
156 | err += sn9c102_write_reg(cam, 0x44, 0x76); | ||
157 | err += sn9c102_write_reg(cam, 0x00, 0x77); | ||
158 | err += sn9c102_write_reg(cam, 0xC7, 0x78); | ||
159 | err += sn9c102_write_reg(cam, 0x01, 0x79); | ||
160 | err += sn9c102_write_reg(cam, 0xC7, 0x7A); | ||
161 | err += sn9c102_write_reg(cam, 0x01, 0x7B); | ||
162 | err += sn9c102_write_reg(cam, 0xC7, 0x7C); | ||
163 | err += sn9c102_write_reg(cam, 0x01, 0x7D); | ||
164 | err += sn9c102_write_reg(cam, 0x44, 0x7E); | ||
165 | err += sn9c102_write_reg(cam, 0x00, 0x7F); | ||
166 | err += sn9c102_write_reg(cam, 0x14, 0x84); | ||
167 | err += sn9c102_write_reg(cam, 0x00, 0x85); | ||
168 | err += sn9c102_write_reg(cam, 0x27, 0x86); | ||
169 | err += sn9c102_write_reg(cam, 0x00, 0x87); | ||
170 | err += sn9c102_write_reg(cam, 0x07, 0x88); | ||
171 | err += sn9c102_write_reg(cam, 0x00, 0x89); | ||
172 | err += sn9c102_write_reg(cam, 0xEC, 0x8A); | ||
173 | err += sn9c102_write_reg(cam, 0x0f, 0x8B); | ||
174 | err += sn9c102_write_reg(cam, 0xD8, 0x8C); | ||
175 | err += sn9c102_write_reg(cam, 0x0f, 0x8D); | ||
176 | err += sn9c102_write_reg(cam, 0x3D, 0x8E); | ||
177 | err += sn9c102_write_reg(cam, 0x00, 0x8F); | ||
178 | err += sn9c102_write_reg(cam, 0x3D, 0x90); | ||
179 | err += sn9c102_write_reg(cam, 0x00, 0x91); | ||
180 | err += sn9c102_write_reg(cam, 0xCD, 0x92); | ||
181 | err += sn9c102_write_reg(cam, 0x0f, 0x93); | ||
182 | err += sn9c102_write_reg(cam, 0xf7, 0x94); | ||
183 | err += sn9c102_write_reg(cam, 0x0f, 0x95); | ||
184 | err += sn9c102_write_reg(cam, 0x0C, 0x96); | ||
185 | err += sn9c102_write_reg(cam, 0x00, 0x97); | ||
186 | err += sn9c102_write_reg(cam, 0x00, 0x98); | ||
187 | err += sn9c102_write_reg(cam, 0x66, 0x99); | ||
188 | err += sn9c102_write_reg(cam, 0x05, 0x9A); | ||
189 | err += sn9c102_write_reg(cam, 0x00, 0x9B); | ||
190 | err += sn9c102_write_reg(cam, 0x04, 0x9C); | ||
191 | err += sn9c102_write_reg(cam, 0x00, 0x9D); | ||
192 | err += sn9c102_write_reg(cam, 0x08, 0x9E); | ||
193 | err += sn9c102_write_reg(cam, 0x00, 0x9F); | ||
194 | err += sn9c102_write_reg(cam, 0x2D, 0xC0); | ||
195 | err += sn9c102_write_reg(cam, 0x2D, 0xC1); | ||
196 | err += sn9c102_write_reg(cam, 0x3A, 0xC2); | ||
197 | err += sn9c102_write_reg(cam, 0x05, 0xC3); | ||
198 | err += sn9c102_write_reg(cam, 0x04, 0xC4); | ||
199 | err += sn9c102_write_reg(cam, 0x3F, 0xC5); | ||
200 | err += sn9c102_write_reg(cam, 0x00, 0xC6); | ||
201 | err += sn9c102_write_reg(cam, 0x00, 0xC7); | ||
202 | err += sn9c102_write_reg(cam, 0x50, 0xC8); | ||
203 | err += sn9c102_write_reg(cam, 0x3C, 0xC9); | ||
204 | err += sn9c102_write_reg(cam, 0x28, 0xCA); | ||
205 | err += sn9c102_write_reg(cam, 0xD8, 0xCB); | ||
206 | err += sn9c102_write_reg(cam, 0x14, 0xCC); | ||
207 | err += sn9c102_write_reg(cam, 0xEC, 0xCD); | ||
208 | err += sn9c102_write_reg(cam, 0x32, 0xCE); | ||
209 | err += sn9c102_write_reg(cam, 0xDD, 0xCF); | ||
210 | err += sn9c102_write_reg(cam, 0x32, 0xD0); | ||
211 | err += sn9c102_write_reg(cam, 0xDD, 0xD1); | ||
212 | err += sn9c102_write_reg(cam, 0x6A, 0xD2); | ||
213 | err += sn9c102_write_reg(cam, 0x50, 0xD3); | ||
214 | err += sn9c102_write_reg(cam, 0x00, 0xD4); | ||
215 | err += sn9c102_write_reg(cam, 0x00, 0xD5); | ||
216 | err += sn9c102_write_reg(cam, 0x00, 0xD6); | ||
217 | break; | ||
218 | default: | ||
219 | break; | ||
220 | } | ||
221 | |||
222 | err += sn9c102_i2c_write(cam, 0x20, 0x00); | ||
223 | err += sn9c102_i2c_write(cam, 0x21, 0xd6); | ||
224 | err += sn9c102_i2c_write(cam, 0x25, 0x06); | ||
225 | |||
226 | return err; | ||
227 | } | ||
228 | |||
229 | |||
230 | static int hv7131r_get_ctrl(struct sn9c102_device* cam, | ||
231 | struct v4l2_control* ctrl) | ||
232 | { | ||
233 | switch (ctrl->id) { | ||
234 | case V4L2_CID_GAIN: | ||
235 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x30)) < 0) | ||
236 | return -EIO; | ||
237 | return 0; | ||
238 | case V4L2_CID_RED_BALANCE: | ||
239 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x31)) < 0) | ||
240 | return -EIO; | ||
241 | ctrl->value = ctrl->value & 0x3f; | ||
242 | return 0; | ||
243 | case V4L2_CID_BLUE_BALANCE: | ||
244 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x33)) < 0) | ||
245 | return -EIO; | ||
246 | ctrl->value = ctrl->value & 0x3f; | ||
247 | return 0; | ||
248 | case SN9C102_V4L2_CID_GREEN_BALANCE: | ||
249 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x32)) < 0) | ||
250 | return -EIO; | ||
251 | ctrl->value = ctrl->value & 0x3f; | ||
252 | return 0; | ||
253 | case V4L2_CID_BLACK_LEVEL: | ||
254 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x01)) < 0) | ||
255 | return -EIO; | ||
256 | ctrl->value = (ctrl->value & 0x08) ? 1 : 0; | ||
257 | return 0; | ||
258 | default: | ||
259 | return -EINVAL; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | |||
264 | static int hv7131r_set_ctrl(struct sn9c102_device* cam, | ||
265 | const struct v4l2_control* ctrl) | ||
266 | { | ||
267 | int err = 0; | ||
268 | |||
269 | switch (ctrl->id) { | ||
270 | case V4L2_CID_GAIN: | ||
271 | err += sn9c102_i2c_write(cam, 0x30, ctrl->value); | ||
272 | break; | ||
273 | case V4L2_CID_RED_BALANCE: | ||
274 | err += sn9c102_i2c_write(cam, 0x31, ctrl->value); | ||
275 | break; | ||
276 | case V4L2_CID_BLUE_BALANCE: | ||
277 | err += sn9c102_i2c_write(cam, 0x33, ctrl->value); | ||
278 | break; | ||
279 | case SN9C102_V4L2_CID_GREEN_BALANCE: | ||
280 | err += sn9c102_i2c_write(cam, 0x32, ctrl->value); | ||
281 | break; | ||
282 | case V4L2_CID_BLACK_LEVEL: | ||
283 | { | ||
284 | int r = sn9c102_i2c_read(cam, 0x01); | ||
285 | if (r < 0) | ||
286 | return -EIO; | ||
287 | err += sn9c102_i2c_write(cam, 0x01, | ||
288 | (ctrl->value<<3) | (r&0xf7)); | ||
289 | } | ||
290 | break; | ||
291 | default: | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | |||
295 | return err ? -EIO : 0; | ||
296 | } | ||
297 | |||
298 | |||
299 | static int hv7131r_set_crop(struct sn9c102_device* cam, | ||
300 | const struct v4l2_rect* rect) | ||
301 | { | ||
302 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
303 | int err = 0; | ||
304 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1, | ||
305 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; | ||
306 | |||
307 | err += sn9c102_write_reg(cam, h_start, 0x12); | ||
308 | err += sn9c102_write_reg(cam, v_start, 0x13); | ||
309 | |||
310 | return err; | ||
311 | } | ||
312 | |||
313 | |||
314 | static int hv7131r_set_pix_format(struct sn9c102_device* cam, | ||
315 | const struct v4l2_pix_format* pix) | ||
316 | { | ||
317 | int err = 0; | ||
318 | |||
319 | switch (sn9c102_get_bridge(cam)) { | ||
320 | case BRIDGE_SN9C103: | ||
321 | if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) { | ||
322 | err += sn9c102_write_reg(cam, 0xa0, 0x19); | ||
323 | err += sn9c102_i2c_write(cam, 0x01, 0x04); | ||
324 | } else { | ||
325 | err += sn9c102_write_reg(cam, 0x30, 0x19); | ||
326 | err += sn9c102_i2c_write(cam, 0x01, 0x04); | ||
327 | } | ||
328 | break; | ||
329 | case BRIDGE_SN9C105: | ||
330 | case BRIDGE_SN9C120: | ||
331 | if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) { | ||
332 | err += sn9c102_write_reg(cam, 0xa5, 0x17); | ||
333 | err += sn9c102_i2c_write(cam, 0x01, 0x24); | ||
334 | } else { | ||
335 | err += sn9c102_write_reg(cam, 0xa3, 0x17); | ||
336 | err += sn9c102_i2c_write(cam, 0x01, 0x04); | ||
337 | } | ||
338 | break; | ||
339 | default: | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | return err; | ||
344 | } | ||
345 | |||
346 | |||
347 | static struct sn9c102_sensor hv7131r = { | ||
348 | .name = "HV7131R", | ||
349 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | ||
350 | .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120, | ||
351 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, | ||
352 | .frequency = SN9C102_I2C_100KHZ, | ||
353 | .interface = SN9C102_I2C_2WIRES, | ||
354 | .i2c_slave_id = 0x11, | ||
355 | .init = &hv7131r_init, | ||
356 | .qctrl = { | ||
357 | { | ||
358 | .id = V4L2_CID_GAIN, | ||
359 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
360 | .name = "global gain", | ||
361 | .minimum = 0x00, | ||
362 | .maximum = 0xff, | ||
363 | .step = 0x01, | ||
364 | .default_value = 0x40, | ||
365 | .flags = 0, | ||
366 | }, | ||
367 | { | ||
368 | .id = V4L2_CID_RED_BALANCE, | ||
369 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
370 | .name = "red balance", | ||
371 | .minimum = 0x00, | ||
372 | .maximum = 0x3f, | ||
373 | .step = 0x01, | ||
374 | .default_value = 0x08, | ||
375 | .flags = 0, | ||
376 | }, | ||
377 | { | ||
378 | .id = V4L2_CID_BLUE_BALANCE, | ||
379 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
380 | .name = "blue balance", | ||
381 | .minimum = 0x00, | ||
382 | .maximum = 0x3f, | ||
383 | .step = 0x01, | ||
384 | .default_value = 0x1a, | ||
385 | .flags = 0, | ||
386 | }, | ||
387 | { | ||
388 | .id = SN9C102_V4L2_CID_GREEN_BALANCE, | ||
389 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
390 | .name = "green balance", | ||
391 | .minimum = 0x00, | ||
392 | .maximum = 0x3f, | ||
393 | .step = 0x01, | ||
394 | .default_value = 0x2f, | ||
395 | .flags = 0, | ||
396 | }, | ||
397 | { | ||
398 | .id = V4L2_CID_BLACK_LEVEL, | ||
399 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
400 | .name = "auto black level compensation", | ||
401 | .minimum = 0x00, | ||
402 | .maximum = 0x01, | ||
403 | .step = 0x01, | ||
404 | .default_value = 0x00, | ||
405 | .flags = 0, | ||
406 | }, | ||
407 | }, | ||
408 | .get_ctrl = &hv7131r_get_ctrl, | ||
409 | .set_ctrl = &hv7131r_set_ctrl, | ||
410 | .cropcap = { | ||
411 | .bounds = { | ||
412 | .left = 0, | ||
413 | .top = 0, | ||
414 | .width = 640, | ||
415 | .height = 480, | ||
416 | }, | ||
417 | .defrect = { | ||
418 | .left = 0, | ||
419 | .top = 0, | ||
420 | .width = 640, | ||
421 | .height = 480, | ||
422 | }, | ||
423 | }, | ||
424 | .set_crop = &hv7131r_set_crop, | ||
425 | .pix_format = { | ||
426 | .width = 640, | ||
427 | .height = 480, | ||
428 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | ||
429 | .priv = 8, | ||
430 | }, | ||
431 | .set_pix_format = &hv7131r_set_pix_format | ||
432 | }; | ||
433 | |||
434 | |||
435 | int sn9c102_probe_hv7131r(struct sn9c102_device* cam) | ||
436 | { | ||
437 | int devid, err = 0; | ||
438 | |||
439 | err += sn9c102_write_reg(cam, 0x09, 0x01); | ||
440 | err += sn9c102_write_reg(cam, 0x44, 0x02); | ||
441 | err += sn9c102_write_reg(cam, 0x34, 0x01); | ||
442 | err += sn9c102_write_reg(cam, 0x20, 0x17); | ||
443 | err += sn9c102_write_reg(cam, 0x34, 0x01); | ||
444 | err += sn9c102_write_reg(cam, 0x46, 0x01); | ||
445 | if (err) | ||
446 | return -EIO; | ||
447 | |||
448 | devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00); | ||
449 | if (devid < 0) | ||
450 | return -EIO; | ||
451 | |||
452 | if (devid != 0x02) | ||
453 | return -ENODEV; | ||
454 | |||
455 | sn9c102_attach_sensor(cam, &hv7131r); | ||
456 | |||
457 | return 0; | ||
458 | } | ||
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0343.c b/drivers/media/video/sn9c102/sn9c102_mi0343.c index a33d1bc10f90..441156d61106 100644 --- a/drivers/media/video/sn9c102/sn9c102_mi0343.c +++ b/drivers/media/video/sn9c102/sn9c102_mi0343.c | |||
@@ -22,12 +22,9 @@ | |||
22 | #include "sn9c102_sensor.h" | 22 | #include "sn9c102_sensor.h" |
23 | 23 | ||
24 | 24 | ||
25 | static struct sn9c102_sensor mi0343; | ||
26 | static u8 mi0343_i2c_data[5+1]; | ||
27 | |||
28 | |||
29 | static int mi0343_init(struct sn9c102_device* cam) | 25 | static int mi0343_init(struct sn9c102_device* cam) |
30 | { | 26 | { |
27 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
31 | int err = 0; | 28 | int err = 0; |
32 | 29 | ||
33 | err += sn9c102_write_reg(cam, 0x00, 0x10); | 30 | err += sn9c102_write_reg(cam, 0x00, 0x10); |
@@ -38,20 +35,20 @@ static int mi0343_init(struct sn9c102_device* cam) | |||
38 | err += sn9c102_write_reg(cam, 0x07, 0x18); | 35 | err += sn9c102_write_reg(cam, 0x07, 0x18); |
39 | err += sn9c102_write_reg(cam, 0xa0, 0x19); | 36 | err += sn9c102_write_reg(cam, 0xa0, 0x19); |
40 | 37 | ||
41 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 38 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d, |
42 | 0x0d, 0x00, 0x01, 0, 0); | 39 | 0x00, 0x01, 0, 0); |
43 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 40 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d, |
44 | 0x0d, 0x00, 0x00, 0, 0); | 41 | 0x00, 0x00, 0, 0); |
45 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 42 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03, |
46 | 0x03, 0x01, 0xe1, 0, 0); | 43 | 0x01, 0xe1, 0, 0); |
47 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 44 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04, |
48 | 0x04, 0x02, 0x81, 0, 0); | 45 | 0x02, 0x81, 0, 0); |
49 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 46 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05, |
50 | 0x05, 0x00, 0x17, 0, 0); | 47 | 0x00, 0x17, 0, 0); |
51 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 48 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06, |
52 | 0x06, 0x00, 0x11, 0, 0); | 49 | 0x00, 0x11, 0, 0); |
53 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 50 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62, |
54 | 0x62, 0x04, 0x9a, 0, 0); | 51 | 0x04, 0x9a, 0, 0); |
55 | 52 | ||
56 | return err; | 53 | return err; |
57 | } | 54 | } |
@@ -60,43 +57,46 @@ static int mi0343_init(struct sn9c102_device* cam) | |||
60 | static int mi0343_get_ctrl(struct sn9c102_device* cam, | 57 | static int mi0343_get_ctrl(struct sn9c102_device* cam, |
61 | struct v4l2_control* ctrl) | 58 | struct v4l2_control* ctrl) |
62 | { | 59 | { |
60 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
61 | u8 data[5+1]; | ||
62 | |||
63 | switch (ctrl->id) { | 63 | switch (ctrl->id) { |
64 | case V4L2_CID_EXPOSURE: | 64 | case V4L2_CID_EXPOSURE: |
65 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 65 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, |
66 | 0x09, 2+1, mi0343_i2c_data) < 0) | 66 | 2+1, data) < 0) |
67 | return -EIO; | 67 | return -EIO; |
68 | ctrl->value = mi0343_i2c_data[2]; | 68 | ctrl->value = data[2]; |
69 | return 0; | 69 | return 0; |
70 | case V4L2_CID_GAIN: | 70 | case V4L2_CID_GAIN: |
71 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 71 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, |
72 | 0x35, 2+1, mi0343_i2c_data) < 0) | 72 | 2+1, data) < 0) |
73 | return -EIO; | 73 | return -EIO; |
74 | break; | 74 | break; |
75 | case V4L2_CID_HFLIP: | 75 | case V4L2_CID_HFLIP: |
76 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 76 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, |
77 | 0x20, 2+1, mi0343_i2c_data) < 0) | 77 | 2+1, data) < 0) |
78 | return -EIO; | 78 | return -EIO; |
79 | ctrl->value = mi0343_i2c_data[3] & 0x20 ? 1 : 0; | 79 | ctrl->value = data[3] & 0x20 ? 1 : 0; |
80 | return 0; | 80 | return 0; |
81 | case V4L2_CID_VFLIP: | 81 | case V4L2_CID_VFLIP: |
82 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 82 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, |
83 | 0x20, 2+1, mi0343_i2c_data) < 0) | 83 | 2+1, data) < 0) |
84 | return -EIO; | 84 | return -EIO; |
85 | ctrl->value = mi0343_i2c_data[3] & 0x80 ? 1 : 0; | 85 | ctrl->value = data[3] & 0x80 ? 1 : 0; |
86 | return 0; | 86 | return 0; |
87 | case V4L2_CID_RED_BALANCE: | 87 | case V4L2_CID_RED_BALANCE: |
88 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 88 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, |
89 | 0x2d, 2+1, mi0343_i2c_data) < 0) | 89 | 2+1, data) < 0) |
90 | return -EIO; | 90 | return -EIO; |
91 | break; | 91 | break; |
92 | case V4L2_CID_BLUE_BALANCE: | 92 | case V4L2_CID_BLUE_BALANCE: |
93 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 93 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, |
94 | 0x2c, 2+1, mi0343_i2c_data) < 0) | 94 | 2+1, data) < 0) |
95 | return -EIO; | 95 | return -EIO; |
96 | break; | 96 | break; |
97 | case SN9C102_V4L2_CID_GREEN_BALANCE: | 97 | case SN9C102_V4L2_CID_GREEN_BALANCE: |
98 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 98 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, |
99 | 0x2e, 2+1, mi0343_i2c_data) < 0) | 99 | 2+1, data) < 0) |
100 | return -EIO; | 100 | return -EIO; |
101 | break; | 101 | break; |
102 | default: | 102 | default: |
@@ -108,7 +108,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam, | |||
108 | case V4L2_CID_RED_BALANCE: | 108 | case V4L2_CID_RED_BALANCE: |
109 | case V4L2_CID_BLUE_BALANCE: | 109 | case V4L2_CID_BLUE_BALANCE: |
110 | case SN9C102_V4L2_CID_GREEN_BALANCE: | 110 | case SN9C102_V4L2_CID_GREEN_BALANCE: |
111 | ctrl->value = mi0343_i2c_data[3] | (mi0343_i2c_data[2] << 8); | 111 | ctrl->value = data[3] | (data[2] << 8); |
112 | if (ctrl->value >= 0x10 && ctrl->value <= 0x3f) | 112 | if (ctrl->value >= 0x10 && ctrl->value <= 0x3f) |
113 | ctrl->value -= 0x10; | 113 | ctrl->value -= 0x10; |
114 | else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f) | 114 | else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f) |
@@ -124,6 +124,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam, | |||
124 | static int mi0343_set_ctrl(struct sn9c102_device* cam, | 124 | static int mi0343_set_ctrl(struct sn9c102_device* cam, |
125 | const struct v4l2_control* ctrl) | 125 | const struct v4l2_control* ctrl) |
126 | { | 126 | { |
127 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
127 | u16 reg = 0; | 128 | u16 reg = 0; |
128 | int err = 0; | 129 | int err = 0; |
129 | 130 | ||
@@ -143,50 +144,42 @@ static int mi0343_set_ctrl(struct sn9c102_device* cam, | |||
143 | 144 | ||
144 | switch (ctrl->id) { | 145 | switch (ctrl->id) { |
145 | case V4L2_CID_EXPOSURE: | 146 | case V4L2_CID_EXPOSURE: |
146 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 147 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
147 | mi0343.i2c_slave_id, | ||
148 | 0x09, ctrl->value, 0x00, | 148 | 0x09, ctrl->value, 0x00, |
149 | 0, 0); | 149 | 0, 0); |
150 | break; | 150 | break; |
151 | case V4L2_CID_GAIN: | 151 | case V4L2_CID_GAIN: |
152 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 152 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
153 | mi0343.i2c_slave_id, | ||
154 | 0x35, reg >> 8, reg & 0xff, | 153 | 0x35, reg >> 8, reg & 0xff, |
155 | 0, 0); | 154 | 0, 0); |
156 | break; | 155 | break; |
157 | case V4L2_CID_HFLIP: | 156 | case V4L2_CID_HFLIP: |
158 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 157 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
159 | mi0343.i2c_slave_id, | ||
160 | 0x20, ctrl->value ? 0x40:0x00, | 158 | 0x20, ctrl->value ? 0x40:0x00, |
161 | ctrl->value ? 0x20:0x00, | 159 | ctrl->value ? 0x20:0x00, |
162 | 0, 0); | 160 | 0, 0); |
163 | break; | 161 | break; |
164 | case V4L2_CID_VFLIP: | 162 | case V4L2_CID_VFLIP: |
165 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 163 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
166 | mi0343.i2c_slave_id, | ||
167 | 0x20, ctrl->value ? 0x80:0x00, | 164 | 0x20, ctrl->value ? 0x80:0x00, |
168 | ctrl->value ? 0x80:0x00, | 165 | ctrl->value ? 0x80:0x00, |
169 | 0, 0); | 166 | 0, 0); |
170 | break; | 167 | break; |
171 | case V4L2_CID_RED_BALANCE: | 168 | case V4L2_CID_RED_BALANCE: |
172 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 169 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
173 | mi0343.i2c_slave_id, | ||
174 | 0x2d, reg >> 8, reg & 0xff, | 170 | 0x2d, reg >> 8, reg & 0xff, |
175 | 0, 0); | 171 | 0, 0); |
176 | break; | 172 | break; |
177 | case V4L2_CID_BLUE_BALANCE: | 173 | case V4L2_CID_BLUE_BALANCE: |
178 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 174 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
179 | mi0343.i2c_slave_id, | ||
180 | 0x2c, reg >> 8, reg & 0xff, | 175 | 0x2c, reg >> 8, reg & 0xff, |
181 | 0, 0); | 176 | 0, 0); |
182 | break; | 177 | break; |
183 | case SN9C102_V4L2_CID_GREEN_BALANCE: | 178 | case SN9C102_V4L2_CID_GREEN_BALANCE: |
184 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 179 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
185 | mi0343.i2c_slave_id, | ||
186 | 0x2b, reg >> 8, reg & 0xff, | 180 | 0x2b, reg >> 8, reg & 0xff, |
187 | 0, 0); | 181 | 0, 0); |
188 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 182 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
189 | mi0343.i2c_slave_id, | ||
190 | 0x2e, reg >> 8, reg & 0xff, | 183 | 0x2e, reg >> 8, reg & 0xff, |
191 | 0, 0); | 184 | 0, 0); |
192 | break; | 185 | break; |
@@ -216,16 +209,15 @@ static int mi0343_set_crop(struct sn9c102_device* cam, | |||
216 | static int mi0343_set_pix_format(struct sn9c102_device* cam, | 209 | static int mi0343_set_pix_format(struct sn9c102_device* cam, |
217 | const struct v4l2_pix_format* pix) | 210 | const struct v4l2_pix_format* pix) |
218 | { | 211 | { |
212 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
219 | int err = 0; | 213 | int err = 0; |
220 | 214 | ||
221 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) { | 215 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) { |
222 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 216 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
223 | mi0343.i2c_slave_id, | ||
224 | 0x0a, 0x00, 0x03, 0, 0); | 217 | 0x0a, 0x00, 0x03, 0, 0); |
225 | err += sn9c102_write_reg(cam, 0x20, 0x19); | 218 | err += sn9c102_write_reg(cam, 0x20, 0x19); |
226 | } else { | 219 | } else { |
227 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 220 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
228 | mi0343.i2c_slave_id, | ||
229 | 0x0a, 0x00, 0x05, 0, 0); | 221 | 0x0a, 0x00, 0x05, 0, 0); |
230 | err += sn9c102_write_reg(cam, 0xa0, 0x19); | 222 | err += sn9c102_write_reg(cam, 0xa0, 0x19); |
231 | } | 223 | } |
@@ -237,7 +229,7 @@ static int mi0343_set_pix_format(struct sn9c102_device* cam, | |||
237 | static struct sn9c102_sensor mi0343 = { | 229 | static struct sn9c102_sensor mi0343 = { |
238 | .name = "MI-0343", | 230 | .name = "MI-0343", |
239 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | 231 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", |
240 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, | 232 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, |
241 | .frequency = SN9C102_I2C_100KHZ, | 233 | .frequency = SN9C102_I2C_100KHZ, |
242 | .interface = SN9C102_I2C_2WIRES, | 234 | .interface = SN9C102_I2C_2WIRES, |
243 | .i2c_slave_id = 0x5d, | 235 | .i2c_slave_id = 0x5d, |
@@ -343,6 +335,7 @@ static struct sn9c102_sensor mi0343 = { | |||
343 | 335 | ||
344 | int sn9c102_probe_mi0343(struct sn9c102_device* cam) | 336 | int sn9c102_probe_mi0343(struct sn9c102_device* cam) |
345 | { | 337 | { |
338 | u8 data[5+1]; | ||
346 | int err = 0; | 339 | int err = 0; |
347 | 340 | ||
348 | err += sn9c102_write_reg(cam, 0x01, 0x01); | 341 | err += sn9c102_write_reg(cam, 0x01, 0x01); |
@@ -352,10 +345,10 @@ int sn9c102_probe_mi0343(struct sn9c102_device* cam) | |||
352 | return -EIO; | 345 | return -EIO; |
353 | 346 | ||
354 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00, | 347 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00, |
355 | 2, mi0343_i2c_data) < 0) | 348 | 2, data) < 0) |
356 | return -EIO; | 349 | return -EIO; |
357 | 350 | ||
358 | if (mi0343_i2c_data[4] != 0x32 && mi0343_i2c_data[3] != 0xe3) | 351 | if (data[4] != 0x32 || data[3] != 0xe3) |
359 | return -ENODEV; | 352 | return -ENODEV; |
360 | 353 | ||
361 | sn9c102_attach_sensor(cam, &mi0343); | 354 | sn9c102_attach_sensor(cam, &mi0343); |
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0360.c b/drivers/media/video/sn9c102/sn9c102_mi0360.c new file mode 100644 index 000000000000..7154dd0534ff --- /dev/null +++ b/drivers/media/video/sn9c102/sn9c102_mi0360.c | |||
@@ -0,0 +1,353 @@ | |||
1 | /*************************************************************************** | ||
2 | * Plug-in for MI-0360 image sensor connected to the SN9C1xx PC Camera * | ||
3 | * Controllers * | ||
4 | * * | ||
5 | * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> * | ||
6 | * * | ||
7 | * This program is free software; you can redistribute it and/or modify * | ||
8 | * it under the terms of the GNU General Public License as published by * | ||
9 | * the Free Software Foundation; either version 2 of the License, or * | ||
10 | * (at your option) any later version. * | ||
11 | * * | ||
12 | * This program is distributed in the hope that it will be useful, * | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
15 | * GNU General Public License for more details. * | ||
16 | * * | ||
17 | * You should have received a copy of the GNU General Public License * | ||
18 | * along with this program; if not, write to the Free Software * | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * | ||
20 | ***************************************************************************/ | ||
21 | |||
22 | #include "sn9c102_sensor.h" | ||
23 | |||
24 | |||
25 | static int mi0360_init(struct sn9c102_device* cam) | ||
26 | { | ||
27 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
28 | int err = 0; | ||
29 | |||
30 | err += sn9c102_write_reg(cam, 0x00, 0x10); | ||
31 | err += sn9c102_write_reg(cam, 0x00, 0x11); | ||
32 | err += sn9c102_write_reg(cam, 0x0a, 0x14); | ||
33 | err += sn9c102_write_reg(cam, 0x40, 0x01); | ||
34 | err += sn9c102_write_reg(cam, 0x20, 0x17); | ||
35 | err += sn9c102_write_reg(cam, 0x07, 0x18); | ||
36 | err += sn9c102_write_reg(cam, 0xa0, 0x19); | ||
37 | err += sn9c102_write_reg(cam, 0x02, 0x1c); | ||
38 | err += sn9c102_write_reg(cam, 0x03, 0x1d); | ||
39 | err += sn9c102_write_reg(cam, 0x0f, 0x1e); | ||
40 | err += sn9c102_write_reg(cam, 0x0c, 0x1f); | ||
41 | err += sn9c102_write_reg(cam, 0x00, 0x20); | ||
42 | err += sn9c102_write_reg(cam, 0x10, 0x21); | ||
43 | err += sn9c102_write_reg(cam, 0x20, 0x22); | ||
44 | err += sn9c102_write_reg(cam, 0x30, 0x23); | ||
45 | err += sn9c102_write_reg(cam, 0x40, 0x24); | ||
46 | err += sn9c102_write_reg(cam, 0x50, 0x25); | ||
47 | err += sn9c102_write_reg(cam, 0x60, 0x26); | ||
48 | err += sn9c102_write_reg(cam, 0x70, 0x27); | ||
49 | err += sn9c102_write_reg(cam, 0x80, 0x28); | ||
50 | err += sn9c102_write_reg(cam, 0x90, 0x29); | ||
51 | err += sn9c102_write_reg(cam, 0xa0, 0x2a); | ||
52 | err += sn9c102_write_reg(cam, 0xb0, 0x2b); | ||
53 | err += sn9c102_write_reg(cam, 0xc0, 0x2c); | ||
54 | err += sn9c102_write_reg(cam, 0xd0, 0x2d); | ||
55 | err += sn9c102_write_reg(cam, 0xe0, 0x2e); | ||
56 | err += sn9c102_write_reg(cam, 0xf0, 0x2f); | ||
57 | err += sn9c102_write_reg(cam, 0xff, 0x30); | ||
58 | |||
59 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d, | ||
60 | 0x00, 0x01, 0, 0); | ||
61 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d, | ||
62 | 0x00, 0x00, 0, 0); | ||
63 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03, | ||
64 | 0x01, 0xe1, 0, 0); | ||
65 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04, | ||
66 | 0x02, 0x81, 0, 0); | ||
67 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05, | ||
68 | 0x00, 0x17, 0, 0); | ||
69 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06, | ||
70 | 0x00, 0x11, 0, 0); | ||
71 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62, | ||
72 | 0x04, 0x9a, 0, 0); | ||
73 | |||
74 | return err; | ||
75 | } | ||
76 | |||
77 | |||
78 | static int mi0360_get_ctrl(struct sn9c102_device* cam, | ||
79 | struct v4l2_control* ctrl) | ||
80 | { | ||
81 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
82 | u8 data[5+1]; | ||
83 | |||
84 | switch (ctrl->id) { | ||
85 | case V4L2_CID_EXPOSURE: | ||
86 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, | ||
87 | 2+1, data) < 0) | ||
88 | return -EIO; | ||
89 | ctrl->value = data[2]; | ||
90 | return 0; | ||
91 | case V4L2_CID_GAIN: | ||
92 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, | ||
93 | 2+1, data) < 0) | ||
94 | return -EIO; | ||
95 | ctrl->value = data[3]; | ||
96 | return 0; | ||
97 | case V4L2_CID_RED_BALANCE: | ||
98 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, | ||
99 | 2+1, data) < 0) | ||
100 | return -EIO; | ||
101 | ctrl->value = data[3]; | ||
102 | return 0; | ||
103 | case V4L2_CID_BLUE_BALANCE: | ||
104 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, | ||
105 | 2+1, data) < 0) | ||
106 | return -EIO; | ||
107 | ctrl->value = data[3]; | ||
108 | return 0; | ||
109 | case SN9C102_V4L2_CID_GREEN_BALANCE: | ||
110 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, | ||
111 | 2+1, data) < 0) | ||
112 | return -EIO; | ||
113 | ctrl->value = data[3]; | ||
114 | return 0; | ||
115 | case V4L2_CID_HFLIP: | ||
116 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, | ||
117 | 2+1, data) < 0) | ||
118 | return -EIO; | ||
119 | ctrl->value = data[3] & 0x20 ? 1 : 0; | ||
120 | return 0; | ||
121 | case V4L2_CID_VFLIP: | ||
122 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, | ||
123 | 2+1, data) < 0) | ||
124 | return -EIO; | ||
125 | ctrl->value = data[3] & 0x80 ? 1 : 0; | ||
126 | return 0; | ||
127 | default: | ||
128 | return -EINVAL; | ||
129 | } | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | |||
135 | static int mi0360_set_ctrl(struct sn9c102_device* cam, | ||
136 | const struct v4l2_control* ctrl) | ||
137 | { | ||
138 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
139 | int err = 0; | ||
140 | |||
141 | switch (ctrl->id) { | ||
142 | case V4L2_CID_EXPOSURE: | ||
143 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
144 | 0x09, ctrl->value, 0x00, | ||
145 | 0, 0); | ||
146 | break; | ||
147 | case V4L2_CID_GAIN: | ||
148 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
149 | 0x35, 0x03, ctrl->value, | ||
150 | 0, 0); | ||
151 | break; | ||
152 | case V4L2_CID_RED_BALANCE: | ||
153 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
154 | 0x2c, 0x03, ctrl->value, | ||
155 | 0, 0); | ||
156 | break; | ||
157 | case V4L2_CID_BLUE_BALANCE: | ||
158 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
159 | 0x2d, 0x03, ctrl->value, | ||
160 | 0, 0); | ||
161 | break; | ||
162 | case SN9C102_V4L2_CID_GREEN_BALANCE: | ||
163 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
164 | 0x2b, 0x03, ctrl->value, | ||
165 | 0, 0); | ||
166 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
167 | 0x2e, 0x03, ctrl->value, | ||
168 | 0, 0); | ||
169 | break; | ||
170 | case V4L2_CID_HFLIP: | ||
171 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
172 | 0x20, ctrl->value ? 0x40:0x00, | ||
173 | ctrl->value ? 0x20:0x00, | ||
174 | 0, 0); | ||
175 | break; | ||
176 | case V4L2_CID_VFLIP: | ||
177 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
178 | 0x20, ctrl->value ? 0x80:0x00, | ||
179 | ctrl->value ? 0x80:0x00, | ||
180 | 0, 0); | ||
181 | break; | ||
182 | default: | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
186 | return err ? -EIO : 0; | ||
187 | } | ||
188 | |||
189 | |||
190 | static int mi0360_set_crop(struct sn9c102_device* cam, | ||
191 | const struct v4l2_rect* rect) | ||
192 | { | ||
193 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
194 | int err = 0; | ||
195 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0, | ||
196 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; | ||
197 | |||
198 | err += sn9c102_write_reg(cam, h_start, 0x12); | ||
199 | err += sn9c102_write_reg(cam, v_start, 0x13); | ||
200 | |||
201 | return err; | ||
202 | } | ||
203 | |||
204 | |||
205 | static int mi0360_set_pix_format(struct sn9c102_device* cam, | ||
206 | const struct v4l2_pix_format* pix) | ||
207 | { | ||
208 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
209 | int err = 0; | ||
210 | |||
211 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) { | ||
212 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
213 | 0x0a, 0x00, 0x02, 0, 0); | ||
214 | err += sn9c102_write_reg(cam, 0x20, 0x19); | ||
215 | } else { | ||
216 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
217 | 0x0a, 0x00, 0x05, 0, 0); | ||
218 | err += sn9c102_write_reg(cam, 0x60, 0x19); | ||
219 | } | ||
220 | |||
221 | return err; | ||
222 | } | ||
223 | |||
224 | |||
225 | static struct sn9c102_sensor mi0360 = { | ||
226 | .name = "MI-0360", | ||
227 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | ||
228 | .supported_bridge = BRIDGE_SN9C103, | ||
229 | .frequency = SN9C102_I2C_100KHZ, | ||
230 | .interface = SN9C102_I2C_2WIRES, | ||
231 | .i2c_slave_id = 0x5d, | ||
232 | .init = &mi0360_init, | ||
233 | .qctrl = { | ||
234 | { | ||
235 | .id = V4L2_CID_EXPOSURE, | ||
236 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
237 | .name = "exposure", | ||
238 | .minimum = 0x00, | ||
239 | .maximum = 0x0f, | ||
240 | .step = 0x01, | ||
241 | .default_value = 0x05, | ||
242 | .flags = 0, | ||
243 | }, | ||
244 | { | ||
245 | .id = V4L2_CID_GAIN, | ||
246 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
247 | .name = "global gain", | ||
248 | .minimum = 0x00, | ||
249 | .maximum = 0x7f, | ||
250 | .step = 0x01, | ||
251 | .default_value = 0x25, | ||
252 | .flags = 0, | ||
253 | }, | ||
254 | { | ||
255 | .id = V4L2_CID_HFLIP, | ||
256 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
257 | .name = "horizontal mirror", | ||
258 | .minimum = 0, | ||
259 | .maximum = 1, | ||
260 | .step = 1, | ||
261 | .default_value = 0, | ||
262 | .flags = 0, | ||
263 | }, | ||
264 | { | ||
265 | .id = V4L2_CID_VFLIP, | ||
266 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
267 | .name = "vertical mirror", | ||
268 | .minimum = 0, | ||
269 | .maximum = 1, | ||
270 | .step = 1, | ||
271 | .default_value = 0, | ||
272 | .flags = 0, | ||
273 | }, | ||
274 | { | ||
275 | .id = V4L2_CID_BLUE_BALANCE, | ||
276 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
277 | .name = "blue balance", | ||
278 | .minimum = 0x00, | ||
279 | .maximum = 0x7f, | ||
280 | .step = 0x01, | ||
281 | .default_value = 0x0f, | ||
282 | .flags = 0, | ||
283 | }, | ||
284 | { | ||
285 | .id = V4L2_CID_RED_BALANCE, | ||
286 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
287 | .name = "red balance", | ||
288 | .minimum = 0x00, | ||
289 | .maximum = 0x7f, | ||
290 | .step = 0x01, | ||
291 | .default_value = 0x32, | ||
292 | .flags = 0, | ||
293 | }, | ||
294 | { | ||
295 | .id = SN9C102_V4L2_CID_GREEN_BALANCE, | ||
296 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
297 | .name = "green balance", | ||
298 | .minimum = 0x00, | ||
299 | .maximum = 0x7f, | ||
300 | .step = 0x01, | ||
301 | .default_value = 0x25, | ||
302 | .flags = 0, | ||
303 | }, | ||
304 | }, | ||
305 | .get_ctrl = &mi0360_get_ctrl, | ||
306 | .set_ctrl = &mi0360_set_ctrl, | ||
307 | .cropcap = { | ||
308 | .bounds = { | ||
309 | .left = 0, | ||
310 | .top = 0, | ||
311 | .width = 640, | ||
312 | .height = 480, | ||
313 | }, | ||
314 | .defrect = { | ||
315 | .left = 0, | ||
316 | .top = 0, | ||
317 | .width = 640, | ||
318 | .height = 480, | ||
319 | }, | ||
320 | }, | ||
321 | .set_crop = &mi0360_set_crop, | ||
322 | .pix_format = { | ||
323 | .width = 640, | ||
324 | .height = 480, | ||
325 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | ||
326 | .priv = 8, | ||
327 | }, | ||
328 | .set_pix_format = &mi0360_set_pix_format | ||
329 | }; | ||
330 | |||
331 | |||
332 | int sn9c102_probe_mi0360(struct sn9c102_device* cam) | ||
333 | { | ||
334 | u8 data[5+1]; | ||
335 | int err = 0; | ||
336 | |||
337 | err += sn9c102_write_reg(cam, 0x01, 0x01); | ||
338 | err += sn9c102_write_reg(cam, 0x00, 0x01); | ||
339 | err += sn9c102_write_reg(cam, 0x28, 0x17); | ||
340 | if (err) | ||
341 | return -EIO; | ||
342 | |||
343 | if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00, | ||
344 | 2+1, data) < 0) | ||
345 | return -EIO; | ||
346 | |||
347 | if (data[2] != 0x82 || data[3] != 0x43) | ||
348 | return -ENODEV; | ||
349 | |||
350 | sn9c102_attach_sensor(cam, &mi0360); | ||
351 | |||
352 | return 0; | ||
353 | } | ||
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7630.c b/drivers/media/video/sn9c102/sn9c102_ov7630.c index 7df09ff38e63..ad9fb2ca2735 100644 --- a/drivers/media/video/sn9c102/sn9c102_ov7630.c +++ b/drivers/media/video/sn9c102/sn9c102_ov7630.c | |||
@@ -22,9 +22,6 @@ | |||
22 | #include "sn9c102_sensor.h" | 22 | #include "sn9c102_sensor.h" |
23 | 23 | ||
24 | 24 | ||
25 | static struct sn9c102_sensor ov7630; | ||
26 | |||
27 | |||
28 | static int ov7630_init(struct sn9c102_device* cam) | 25 | static int ov7630_init(struct sn9c102_device* cam) |
29 | { | 26 | { |
30 | int err = 0; | 27 | int err = 0; |
@@ -32,21 +29,21 @@ static int ov7630_init(struct sn9c102_device* cam) | |||
32 | switch (sn9c102_get_bridge(cam)) { | 29 | switch (sn9c102_get_bridge(cam)) { |
33 | case BRIDGE_SN9C101: | 30 | case BRIDGE_SN9C101: |
34 | case BRIDGE_SN9C102: | 31 | case BRIDGE_SN9C102: |
35 | err += sn9c102_write_reg(cam, 0x00, 0x14); | 32 | err += sn9c102_write_reg(cam, 0x00, 0x14); |
36 | err += sn9c102_write_reg(cam, 0x60, 0x17); | 33 | err += sn9c102_write_reg(cam, 0x60, 0x17); |
37 | err += sn9c102_write_reg(cam, 0x0f, 0x18); | 34 | err += sn9c102_write_reg(cam, 0x0f, 0x18); |
38 | err += sn9c102_write_reg(cam, 0x50, 0x19); | 35 | err += sn9c102_write_reg(cam, 0x50, 0x19); |
39 | 36 | ||
40 | err += sn9c102_i2c_write(cam, 0x12, 0x8d); | 37 | err += sn9c102_i2c_write(cam, 0x12, 0x8d); |
41 | err += sn9c102_i2c_write(cam, 0x12, 0x0d); | 38 | err += sn9c102_i2c_write(cam, 0x12, 0x0d); |
42 | err += sn9c102_i2c_write(cam, 0x11, 0x00); | 39 | err += sn9c102_i2c_write(cam, 0x11, 0x00); |
43 | err += sn9c102_i2c_write(cam, 0x15, 0x34); | 40 | err += sn9c102_i2c_write(cam, 0x15, 0x35); |
44 | err += sn9c102_i2c_write(cam, 0x16, 0x03); | 41 | err += sn9c102_i2c_write(cam, 0x16, 0x03); |
45 | err += sn9c102_i2c_write(cam, 0x17, 0x1c); | 42 | err += sn9c102_i2c_write(cam, 0x17, 0x1c); |
46 | err += sn9c102_i2c_write(cam, 0x18, 0xbd); | 43 | err += sn9c102_i2c_write(cam, 0x18, 0xbd); |
47 | err += sn9c102_i2c_write(cam, 0x19, 0x06); | 44 | err += sn9c102_i2c_write(cam, 0x19, 0x06); |
48 | err += sn9c102_i2c_write(cam, 0x1a, 0xf6); | 45 | err += sn9c102_i2c_write(cam, 0x1a, 0xf6); |
49 | err += sn9c102_i2c_write(cam, 0x1b, 0x04); | 46 | err += sn9c102_i2c_write(cam, 0x1b, 0x04); |
50 | err += sn9c102_i2c_write(cam, 0x20, 0x44); | 47 | err += sn9c102_i2c_write(cam, 0x20, 0x44); |
51 | err += sn9c102_i2c_write(cam, 0x23, 0xee); | 48 | err += sn9c102_i2c_write(cam, 0x23, 0xee); |
52 | err += sn9c102_i2c_write(cam, 0x26, 0xa0); | 49 | err += sn9c102_i2c_write(cam, 0x26, 0xa0); |
@@ -108,23 +105,23 @@ static int ov7630_init(struct sn9c102_device* cam) | |||
108 | err += sn9c102_i2c_write(cam, 0x11, 0x01); | 105 | err += sn9c102_i2c_write(cam, 0x11, 0x01); |
109 | err += sn9c102_i2c_write(cam, 0x1b, 0x04); | 106 | err += sn9c102_i2c_write(cam, 0x1b, 0x04); |
110 | err += sn9c102_i2c_write(cam, 0x20, 0x44); | 107 | err += sn9c102_i2c_write(cam, 0x20, 0x44); |
111 | err += sn9c102_i2c_write(cam, 0x23, 0xee); | 108 | err += sn9c102_i2c_write(cam, 0x23, 0xee); |
112 | err += sn9c102_i2c_write(cam, 0x26, 0xa0); | 109 | err += sn9c102_i2c_write(cam, 0x26, 0xa0); |
113 | err += sn9c102_i2c_write(cam, 0x27, 0x9a); | 110 | err += sn9c102_i2c_write(cam, 0x27, 0x9a); |
114 | err += sn9c102_i2c_write(cam, 0x28, 0x20); | 111 | err += sn9c102_i2c_write(cam, 0x28, 0x20); |
115 | err += sn9c102_i2c_write(cam, 0x29, 0x30); | 112 | err += sn9c102_i2c_write(cam, 0x29, 0x30); |
116 | err += sn9c102_i2c_write(cam, 0x2f, 0x3d); | 113 | err += sn9c102_i2c_write(cam, 0x2f, 0x3d); |
117 | err += sn9c102_i2c_write(cam, 0x30, 0x24); | 114 | err += sn9c102_i2c_write(cam, 0x30, 0x24); |
118 | err += sn9c102_i2c_write(cam, 0x32, 0x86); | 115 | err += sn9c102_i2c_write(cam, 0x32, 0x86); |
119 | err += sn9c102_i2c_write(cam, 0x60, 0xa9); | 116 | err += sn9c102_i2c_write(cam, 0x60, 0xa9); |
120 | err += sn9c102_i2c_write(cam, 0x61, 0x42); | 117 | err += sn9c102_i2c_write(cam, 0x61, 0x42); |
121 | err += sn9c102_i2c_write(cam, 0x65, 0x00); | 118 | err += sn9c102_i2c_write(cam, 0x65, 0x00); |
122 | err += sn9c102_i2c_write(cam, 0x69, 0x38); | 119 | err += sn9c102_i2c_write(cam, 0x69, 0x38); |
123 | err += sn9c102_i2c_write(cam, 0x6f, 0x88); | 120 | err += sn9c102_i2c_write(cam, 0x6f, 0x88); |
124 | err += sn9c102_i2c_write(cam, 0x70, 0x0b); | 121 | err += sn9c102_i2c_write(cam, 0x70, 0x0b); |
125 | err += sn9c102_i2c_write(cam, 0x71, 0x00); | 122 | err += sn9c102_i2c_write(cam, 0x71, 0x00); |
126 | err += sn9c102_i2c_write(cam, 0x74, 0x21); | 123 | err += sn9c102_i2c_write(cam, 0x74, 0x21); |
127 | err += sn9c102_i2c_write(cam, 0x7d, 0xf7); | 124 | err += sn9c102_i2c_write(cam, 0x7d, 0xf7); |
128 | break; | 125 | break; |
129 | default: | 126 | default: |
130 | break; | 127 | break; |
@@ -428,9 +425,9 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam) | |||
428 | switch (sn9c102_get_bridge(cam)) { | 425 | switch (sn9c102_get_bridge(cam)) { |
429 | case BRIDGE_SN9C101: | 426 | case BRIDGE_SN9C101: |
430 | case BRIDGE_SN9C102: | 427 | case BRIDGE_SN9C102: |
431 | err += sn9c102_write_reg(cam, 0x01, 0x01); | 428 | err += sn9c102_write_reg(cam, 0x01, 0x01); |
432 | err += sn9c102_write_reg(cam, 0x00, 0x01); | 429 | err += sn9c102_write_reg(cam, 0x00, 0x01); |
433 | err += sn9c102_write_reg(cam, 0x28, 0x17); | 430 | err += sn9c102_write_reg(cam, 0x28, 0x17); |
434 | break; | 431 | break; |
435 | case BRIDGE_SN9C103: /* do _not_ change anything! */ | 432 | case BRIDGE_SN9C103: /* do _not_ change anything! */ |
436 | err += sn9c102_write_reg(cam, 0x09, 0x01); | 433 | err += sn9c102_write_reg(cam, 0x09, 0x01); |
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7660.c b/drivers/media/video/sn9c102/sn9c102_ov7660.c index d670c24d4435..eef90ff3d474 100644 --- a/drivers/media/video/sn9c102/sn9c102_ov7660.c +++ b/drivers/media/video/sn9c102/sn9c102_ov7660.c | |||
@@ -22,9 +22,6 @@ | |||
22 | #include "sn9c102_sensor.h" | 22 | #include "sn9c102_sensor.h" |
23 | 23 | ||
24 | 24 | ||
25 | static struct sn9c102_sensor ov7660; | ||
26 | |||
27 | |||
28 | static int ov7660_init(struct sn9c102_device* cam) | 25 | static int ov7660_init(struct sn9c102_device* cam) |
29 | { | 26 | { |
30 | int err = 0; | 27 | int err = 0; |
diff --git a/drivers/media/video/sn9c102/sn9c102_pas106b.c b/drivers/media/video/sn9c102/sn9c102_pas106b.c index 8d79a5fae5de..a67057210cab 100644 --- a/drivers/media/video/sn9c102/sn9c102_pas106b.c +++ b/drivers/media/video/sn9c102/sn9c102_pas106b.c | |||
@@ -23,9 +23,6 @@ | |||
23 | #include "sn9c102_sensor.h" | 23 | #include "sn9c102_sensor.h" |
24 | 24 | ||
25 | 25 | ||
26 | static struct sn9c102_sensor pas106b; | ||
27 | |||
28 | |||
29 | static int pas106b_init(struct sn9c102_device* cam) | 26 | static int pas106b_init(struct sn9c102_device* cam) |
30 | { | 27 | { |
31 | int err = 0; | 28 | int err = 0; |
@@ -172,7 +169,7 @@ static int pas106b_set_pix_format(struct sn9c102_device* cam, | |||
172 | static struct sn9c102_sensor pas106b = { | 169 | static struct sn9c102_sensor pas106b = { |
173 | .name = "PAS106B", | 170 | .name = "PAS106B", |
174 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | 171 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", |
175 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, | 172 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, |
176 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, | 173 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, |
177 | .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ, | 174 | .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ, |
178 | .interface = SN9C102_I2C_2WIRES, | 175 | .interface = SN9C102_I2C_2WIRES, |
diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c index 7894f01b56e8..4447d7cb1e92 100644 --- a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c +++ b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c | |||
@@ -28,9 +28,6 @@ | |||
28 | #include "sn9c102_sensor.h" | 28 | #include "sn9c102_sensor.h" |
29 | 29 | ||
30 | 30 | ||
31 | static struct sn9c102_sensor pas202bcb; | ||
32 | |||
33 | |||
34 | static int pas202bcb_init(struct sn9c102_device* cam) | 31 | static int pas202bcb_init(struct sn9c102_device* cam) |
35 | { | 32 | { |
36 | int err = 0; | 33 | int err = 0; |
@@ -38,12 +35,12 @@ static int pas202bcb_init(struct sn9c102_device* cam) | |||
38 | switch (sn9c102_get_bridge(cam)) { | 35 | switch (sn9c102_get_bridge(cam)) { |
39 | case BRIDGE_SN9C101: | 36 | case BRIDGE_SN9C101: |
40 | case BRIDGE_SN9C102: | 37 | case BRIDGE_SN9C102: |
41 | err += sn9c102_write_reg(cam, 0x00, 0x10); | 38 | err += sn9c102_write_reg(cam, 0x00, 0x10); |
42 | err += sn9c102_write_reg(cam, 0x00, 0x11); | 39 | err += sn9c102_write_reg(cam, 0x00, 0x11); |
43 | err += sn9c102_write_reg(cam, 0x00, 0x14); | 40 | err += sn9c102_write_reg(cam, 0x00, 0x14); |
44 | err += sn9c102_write_reg(cam, 0x20, 0x17); | 41 | err += sn9c102_write_reg(cam, 0x20, 0x17); |
45 | err += sn9c102_write_reg(cam, 0x30, 0x19); | 42 | err += sn9c102_write_reg(cam, 0x30, 0x19); |
46 | err += sn9c102_write_reg(cam, 0x09, 0x18); | 43 | err += sn9c102_write_reg(cam, 0x09, 0x18); |
47 | break; | 44 | break; |
48 | case BRIDGE_SN9C103: | 45 | case BRIDGE_SN9C103: |
49 | err += sn9c102_write_reg(cam, 0x00, 0x02); | 46 | err += sn9c102_write_reg(cam, 0x00, 0x02); |
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c index 90023ad63adc..a265767e5f31 100644 --- a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c +++ b/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c | |||
@@ -22,9 +22,6 @@ | |||
22 | #include "sn9c102_sensor.h" | 22 | #include "sn9c102_sensor.h" |
23 | 23 | ||
24 | 24 | ||
25 | static struct sn9c102_sensor tas5110c1b; | ||
26 | |||
27 | |||
28 | static int tas5110c1b_init(struct sn9c102_device* cam) | 25 | static int tas5110c1b_init(struct sn9c102_device* cam) |
29 | { | 26 | { |
30 | int err = 0; | 27 | int err = 0; |
@@ -98,7 +95,7 @@ static int tas5110c1b_set_pix_format(struct sn9c102_device* cam, | |||
98 | static struct sn9c102_sensor tas5110c1b = { | 95 | static struct sn9c102_sensor tas5110c1b = { |
99 | .name = "TAS5110C1B", | 96 | .name = "TAS5110C1B", |
100 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | 97 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", |
101 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, | 98 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, |
102 | .sysfs_ops = SN9C102_I2C_WRITE, | 99 | .sysfs_ops = SN9C102_I2C_WRITE, |
103 | .frequency = SN9C102_I2C_100KHZ, | 100 | .frequency = SN9C102_I2C_100KHZ, |
104 | .interface = SN9C102_I2C_3WIRES, | 101 | .interface = SN9C102_I2C_3WIRES, |
@@ -146,7 +143,6 @@ int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam) | |||
146 | const struct usb_device_id tas5110c1b_id_table[] = { | 143 | const struct usb_device_id tas5110c1b_id_table[] = { |
147 | { USB_DEVICE(0x0c45, 0x6001), }, | 144 | { USB_DEVICE(0x0c45, 0x6001), }, |
148 | { USB_DEVICE(0x0c45, 0x6005), }, | 145 | { USB_DEVICE(0x0c45, 0x6005), }, |
149 | { USB_DEVICE(0x0c45, 0x6007), }, | ||
150 | { USB_DEVICE(0x0c45, 0x60ab), }, | 146 | { USB_DEVICE(0x0c45, 0x60ab), }, |
151 | { } | 147 | { } |
152 | }; | 148 | }; |
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110d.c b/drivers/media/video/sn9c102/sn9c102_tas5110d.c new file mode 100644 index 000000000000..4681cfa1bf57 --- /dev/null +++ b/drivers/media/video/sn9c102/sn9c102_tas5110d.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /*************************************************************************** | ||
2 | * Plug-in for TAS5110D image sensor connected to the SN9C1xx PC Camera * | ||
3 | * Controllers * | ||
4 | * * | ||
5 | * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> * | ||
6 | * * | ||
7 | * This program is free software; you can redistribute it and/or modify * | ||
8 | * it under the terms of the GNU General Public License as published by * | ||
9 | * the Free Software Foundation; either version 2 of the License, or * | ||
10 | * (at your option) any later version. * | ||
11 | * * | ||
12 | * This program is distributed in the hope that it will be useful, * | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
15 | * GNU General Public License for more details. * | ||
16 | * * | ||
17 | * You should have received a copy of the GNU General Public License * | ||
18 | * along with this program; if not, write to the Free Software * | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * | ||
20 | ***************************************************************************/ | ||
21 | |||
22 | #include "sn9c102_sensor.h" | ||
23 | |||
24 | |||
25 | static int tas5110d_init(struct sn9c102_device* cam) | ||
26 | { | ||
27 | int err = 0; | ||
28 | |||
29 | err += sn9c102_write_reg(cam, 0x01, 0x01); | ||
30 | err += sn9c102_write_reg(cam, 0x04, 0x01); | ||
31 | err += sn9c102_write_reg(cam, 0x0a, 0x14); | ||
32 | err += sn9c102_write_reg(cam, 0x60, 0x17); | ||
33 | err += sn9c102_write_reg(cam, 0x06, 0x18); | ||
34 | err += sn9c102_write_reg(cam, 0xfb, 0x19); | ||
35 | |||
36 | err += sn9c102_i2c_write(cam, 0x9a, 0xca); | ||
37 | |||
38 | return err; | ||
39 | } | ||
40 | |||
41 | |||
42 | static int tas5110d_set_crop(struct sn9c102_device* cam, | ||
43 | const struct v4l2_rect* rect) | ||
44 | { | ||
45 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
46 | int err = 0; | ||
47 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69, | ||
48 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9; | ||
49 | |||
50 | err += sn9c102_write_reg(cam, h_start, 0x12); | ||
51 | err += sn9c102_write_reg(cam, v_start, 0x13); | ||
52 | |||
53 | err += sn9c102_write_reg(cam, 0x14, 0x1a); | ||
54 | err += sn9c102_write_reg(cam, 0x0a, 0x1b); | ||
55 | |||
56 | return err; | ||
57 | } | ||
58 | |||
59 | |||
60 | static int tas5110d_set_pix_format(struct sn9c102_device* cam, | ||
61 | const struct v4l2_pix_format* pix) | ||
62 | { | ||
63 | int err = 0; | ||
64 | |||
65 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) | ||
66 | err += sn9c102_write_reg(cam, 0x3b, 0x19); | ||
67 | else | ||
68 | err += sn9c102_write_reg(cam, 0xfb, 0x19); | ||
69 | |||
70 | return err; | ||
71 | } | ||
72 | |||
73 | |||
74 | static struct sn9c102_sensor tas5110d = { | ||
75 | .name = "TAS5110D", | ||
76 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | ||
77 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, | ||
78 | .sysfs_ops = SN9C102_I2C_WRITE, | ||
79 | .frequency = SN9C102_I2C_100KHZ, | ||
80 | .interface = SN9C102_I2C_2WIRES, | ||
81 | .i2c_slave_id = 0x61, | ||
82 | .init = &tas5110d_init, | ||
83 | .cropcap = { | ||
84 | .bounds = { | ||
85 | .left = 0, | ||
86 | .top = 0, | ||
87 | .width = 352, | ||
88 | .height = 288, | ||
89 | }, | ||
90 | .defrect = { | ||
91 | .left = 0, | ||
92 | .top = 0, | ||
93 | .width = 352, | ||
94 | .height = 288, | ||
95 | }, | ||
96 | }, | ||
97 | .set_crop = &tas5110d_set_crop, | ||
98 | .pix_format = { | ||
99 | .width = 352, | ||
100 | .height = 288, | ||
101 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | ||
102 | .priv = 8, | ||
103 | }, | ||
104 | .set_pix_format = &tas5110d_set_pix_format | ||
105 | }; | ||
106 | |||
107 | |||
108 | int sn9c102_probe_tas5110d(struct sn9c102_device* cam) | ||
109 | { | ||
110 | const struct usb_device_id tas5110d_id_table[] = { | ||
111 | { USB_DEVICE(0x0c45, 0x6007), }, | ||
112 | { } | ||
113 | }; | ||
114 | |||
115 | if (!sn9c102_match_id(cam, tas5110d_id_table)) | ||
116 | return -ENODEV; | ||
117 | |||
118 | sn9c102_attach_sensor(cam, &tas5110d); | ||
119 | |||
120 | return 0; | ||
121 | } | ||
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c index cb1b318bc1ff..a7f711396152 100644 --- a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c +++ b/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c | |||
@@ -22,9 +22,6 @@ | |||
22 | #include "sn9c102_sensor.h" | 22 | #include "sn9c102_sensor.h" |
23 | 23 | ||
24 | 24 | ||
25 | static struct sn9c102_sensor tas5130d1b; | ||
26 | |||
27 | |||
28 | static int tas5130d1b_init(struct sn9c102_device* cam) | 25 | static int tas5130d1b_init(struct sn9c102_device* cam) |
29 | { | 26 | { |
30 | int err = 0; | 27 | int err = 0; |
@@ -99,7 +96,7 @@ static int tas5130d1b_set_pix_format(struct sn9c102_device* cam, | |||
99 | static struct sn9c102_sensor tas5130d1b = { | 96 | static struct sn9c102_sensor tas5130d1b = { |
100 | .name = "TAS5130D1B", | 97 | .name = "TAS5130D1B", |
101 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | 98 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", |
102 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, | 99 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, |
103 | .sysfs_ops = SN9C102_I2C_WRITE, | 100 | .sysfs_ops = SN9C102_I2C_WRITE, |
104 | .frequency = SN9C102_I2C_100KHZ, | 101 | .frequency = SN9C102_I2C_100KHZ, |
105 | .interface = SN9C102_I2C_3WIRES, | 102 | .interface = SN9C102_I2C_3WIRES, |