diff options
Diffstat (limited to 'drivers/media/video/sn9c102')
-rw-r--r-- | drivers/media/video/sn9c102/Kconfig | 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 | 274 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_devtable.h | 14 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_hv7131d.c | 25 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_hv7131r.c | 366 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_mi0343.c | 130 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_mi0360.c | 338 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_ov7630.c | 121 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_ov7660.c | 234 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_pas106b.c | 23 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_pas202bcb.c | 77 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_sensor.h | 12 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_tas5110c1b.c | 18 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_tas5110d.c | 118 | ||||
-rw-r--r-- | drivers/media/video/sn9c102/sn9c102_tas5130d1b.c | 19 |
17 files changed, 1281 insertions, 524 deletions
diff --git a/drivers/media/video/sn9c102/Kconfig b/drivers/media/video/sn9c102/Kconfig index 1a7ccb666ab0..19204f5686e1 100644 --- a/drivers/media/video/sn9c102/Kconfig +++ b/drivers/media/video/sn9c102/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config USB_SN9C102 | 1 | config USB_SN9C102 |
2 | tristate "USB SN9C1xx PC Camera Controller support" | 2 | tristate "USB SN9C1xx PC Camera Controller support" |
3 | depends on USB && VIDEO_V4L1 | 3 | depends on USB && VIDEO_V4L2 |
4 | ---help--- | 4 | ---help--- |
5 | Say Y here if you want support for cameras based on SONiX SN9C101, | 5 | Say Y here if you want support for cameras based on SONiX SN9C101, |
6 | SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers. | 6 | SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers. |
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..89f83354de3b 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 | ||
@@ -208,27 +209,40 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam) | |||
208 | } | 209 | } |
209 | 210 | ||
210 | /*****************************************************************************/ | 211 | /*****************************************************************************/ |
211 | 212 | /* | |
212 | int sn9c102_write_regs(struct sn9c102_device* cam, u8* buff, u16 index) | 213 | * Write a sequence of count value/register pairs. Returns -1 after the |
214 | * first failed write, or 0 for no errors. | ||
215 | */ | ||
216 | int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2], | ||
217 | int count) | ||
213 | { | 218 | { |
214 | struct usb_device* udev = cam->usbdev; | 219 | struct usb_device* udev = cam->usbdev; |
220 | u8* value = cam->control_buffer; /* Needed for DMA'able memory */ | ||
215 | int i, res; | 221 | int i, res; |
216 | 222 | ||
217 | if (index + sizeof(buff) >= ARRAY_SIZE(cam->reg)) | 223 | for (i = 0; i < count; i++) { |
218 | return -1; | 224 | u8 index = valreg[i][1]; |
225 | |||
226 | /* | ||
227 | * index is a u8, so it must be <256 and can't be out of range. | ||
228 | * If we put in a check anyway, gcc annoys us with a warning | ||
229 | * that our check is useless. People get all uppity when they | ||
230 | * see warnings in the kernel compile. | ||
231 | */ | ||
232 | |||
233 | *value = valreg[i][0]; | ||
234 | res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
235 | 0x08, 0x41, index, 0, | ||
236 | value, 1, SN9C102_CTRL_TIMEOUT); | ||
237 | if (res < 0) { | ||
238 | DBG(3, "Failed to write a register (value 0x%02X, " | ||
239 | "index 0x%02X, error %d)", *value, index, res); | ||
240 | return -1; | ||
241 | } | ||
219 | 242 | ||
220 | res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, | 243 | cam->reg[index] = *value; |
221 | index, 0, buff, sizeof(buff), | ||
222 | SN9C102_CTRL_TIMEOUT*sizeof(buff)); | ||
223 | if (res < 0) { | ||
224 | DBG(3, "Failed to write registers (index 0x%02X, error %d)", | ||
225 | index, res); | ||
226 | return -1; | ||
227 | } | 244 | } |
228 | 245 | ||
229 | for (i = 0; i < sizeof(buff); i++) | ||
230 | cam->reg[index+i] = buff[i]; | ||
231 | |||
232 | return 0; | 246 | return 0; |
233 | } | 247 | } |
234 | 248 | ||
@@ -485,18 +499,43 @@ static size_t sn9c102_sof_length(struct sn9c102_device* cam) | |||
485 | static void* | 499 | static void* |
486 | sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) | 500 | sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) |
487 | { | 501 | { |
488 | char sof_header[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; | 502 | static const char marker[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; |
489 | size_t soflen = 0, i; | 503 | const char *m = mem; |
504 | size_t soflen = 0, i, j; | ||
490 | 505 | ||
491 | soflen = sn9c102_sof_length(cam); | 506 | soflen = sn9c102_sof_length(cam); |
492 | 507 | ||
493 | for (i = 0; (len >= soflen) && (i <= len - soflen); i++) | 508 | for (i = 0; i < len; i++) { |
494 | if (!memcmp(mem + i, sof_header, sizeof(sof_header))) { | 509 | size_t b; |
495 | memcpy(cam->sof_header, mem + i, | 510 | |
496 | sizeof(sn9c102_sof_header_t)); | 511 | /* Read the variable part of the header */ |
497 | /* Skip the header */ | 512 | if (unlikely(cam->sof.bytesread >= sizeof(marker))) { |
498 | return mem + i + soflen; | 513 | cam->sof.header[cam->sof.bytesread] = *(m+i); |
514 | if (++cam->sof.bytesread == soflen) { | ||
515 | cam->sof.bytesread = 0; | ||
516 | return mem + i; | ||
517 | } | ||
518 | continue; | ||
519 | } | ||
520 | |||
521 | /* Search for the SOF marker (fixed part) in the header */ | ||
522 | for (j = 0, b=cam->sof.bytesread; j+b < sizeof(marker); j++) { | ||
523 | if (unlikely(i+j) == len) | ||
524 | return NULL; | ||
525 | if (*(m+i+j) == marker[cam->sof.bytesread]) { | ||
526 | cam->sof.header[cam->sof.bytesread] = *(m+i+j); | ||
527 | if (++cam->sof.bytesread == sizeof(marker)) { | ||
528 | PDBGG("Bytes to analyze: %zd. SOF " | ||
529 | "starts at byte #%zd", len, i); | ||
530 | i += j+1; | ||
531 | break; | ||
532 | } | ||
533 | } else { | ||
534 | cam->sof.bytesread = 0; | ||
535 | break; | ||
499 | } | 536 | } |
537 | } | ||
538 | } | ||
500 | 539 | ||
501 | return NULL; | 540 | return NULL; |
502 | } | 541 | } |
@@ -505,7 +544,7 @@ sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) | |||
505 | static void* | 544 | static void* |
506 | sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len) | 545 | sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len) |
507 | { | 546 | { |
508 | char eof_header[4][4] = { | 547 | static const u8 eof_header[4][4] = { |
509 | {0x00, 0x00, 0x00, 0x00}, | 548 | {0x00, 0x00, 0x00, 0x00}, |
510 | {0x40, 0x00, 0x00, 0x00}, | 549 | {0x40, 0x00, 0x00, 0x00}, |
511 | {0x80, 0x00, 0x00, 0x00}, | 550 | {0x80, 0x00, 0x00, 0x00}, |
@@ -513,10 +552,16 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len) | |||
513 | }; | 552 | }; |
514 | size_t i, j; | 553 | size_t i, j; |
515 | 554 | ||
555 | /* The EOF header does not exist in compressed data */ | ||
516 | if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X || | 556 | if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X || |
517 | cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG) | 557 | cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG) |
518 | return NULL; /* EOF header does not exist in compressed data */ | 558 | return NULL; |
519 | 559 | ||
560 | /* | ||
561 | The EOF header might cross the packet boundary, but this is not a | ||
562 | problem, since the end of a frame is determined by checking its size | ||
563 | in the first place. | ||
564 | */ | ||
520 | for (i = 0; (len >= 4) && (i <= len - 4); i++) | 565 | for (i = 0; (len >= 4) && (i <= len - 4); i++) |
521 | for (j = 0; j < ARRAY_SIZE(eof_header); j++) | 566 | for (j = 0; j < ARRAY_SIZE(eof_header); j++) |
522 | if (!memcmp(mem + i, eof_header[j], 4)) | 567 | if (!memcmp(mem + i, eof_header[j], 4)) |
@@ -529,7 +574,7 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len) | |||
529 | static void | 574 | static void |
530 | sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f) | 575 | sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f) |
531 | { | 576 | { |
532 | static u8 jpeg_header[589] = { | 577 | static const u8 jpeg_header[589] = { |
533 | 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05, | 578 | 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05, |
534 | 0x06, 0x05, 0x04, 0x06, 0x06, 0x05, 0x06, 0x07, 0x07, 0x06, | 579 | 0x06, 0x05, 0x04, 0x06, 0x06, 0x05, 0x06, 0x07, 0x07, 0x06, |
535 | 0x08, 0x0a, 0x10, 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e, | 580 | 0x08, 0x0a, 0x10, 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e, |
@@ -639,6 +684,7 @@ static void sn9c102_urb_complete(struct urb *urb) | |||
639 | cam->stream = STREAM_OFF; | 684 | cam->stream = STREAM_OFF; |
640 | if ((*f)) | 685 | if ((*f)) |
641 | (*f)->state = F_QUEUED; | 686 | (*f)->state = F_QUEUED; |
687 | cam->sof.bytesread = 0; | ||
642 | DBG(3, "Stream interrupted by application"); | 688 | DBG(3, "Stream interrupted by application"); |
643 | wake_up(&cam->wait_stream); | 689 | wake_up(&cam->wait_stream); |
644 | } | 690 | } |
@@ -676,6 +722,7 @@ static void sn9c102_urb_complete(struct urb *urb) | |||
676 | if (status) { | 722 | if (status) { |
677 | DBG(3, "Error in isochronous frame"); | 723 | DBG(3, "Error in isochronous frame"); |
678 | (*f)->state = F_ERROR; | 724 | (*f)->state = F_ERROR; |
725 | cam->sof.bytesread = 0; | ||
679 | continue; | 726 | continue; |
680 | } | 727 | } |
681 | 728 | ||
@@ -692,13 +739,13 @@ end_of_frame: | |||
692 | if (eof) | 739 | if (eof) |
693 | img = (eof > pos) ? eof - pos - 1 : 0; | 740 | img = (eof > pos) ? eof - pos - 1 : 0; |
694 | 741 | ||
695 | if ((*f)->buf.bytesused+img > imagesize) { | 742 | if ((*f)->buf.bytesused + img > imagesize) { |
696 | u32 b; | 743 | u32 b; |
697 | b = (*f)->buf.bytesused + img - | 744 | b = (*f)->buf.bytesused + img - |
698 | imagesize; | 745 | imagesize; |
699 | img = imagesize - (*f)->buf.bytesused; | 746 | img = imagesize - (*f)->buf.bytesused; |
700 | DBG(3, "Expected EOF not found: " | 747 | PDBGG("Expected EOF not found: video " |
701 | "video frame cut"); | 748 | "frame cut"); |
702 | if (eof) | 749 | if (eof) |
703 | DBG(3, "Exceeded limit: +%u " | 750 | DBG(3, "Exceeded limit: +%u " |
704 | "bytes", (unsigned)(b)); | 751 | "bytes", (unsigned)(b)); |
@@ -719,11 +766,6 @@ end_of_frame: | |||
719 | V4L2_PIX_FMT_JPEG) && eof)) { | 766 | V4L2_PIX_FMT_JPEG) && eof)) { |
720 | u32 b; | 767 | u32 b; |
721 | 768 | ||
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; | 769 | b = (*f)->buf.bytesused; |
728 | (*f)->state = F_DONE; | 770 | (*f)->state = F_DONE; |
729 | (*f)->buf.sequence= ++cam->frame_count; | 771 | (*f)->buf.sequence= ++cam->frame_count; |
@@ -741,7 +783,7 @@ end_of_frame: | |||
741 | spin_unlock(&cam->queue_lock); | 783 | spin_unlock(&cam->queue_lock); |
742 | 784 | ||
743 | memcpy(cam->sysfs.frame_header, | 785 | memcpy(cam->sysfs.frame_header, |
744 | cam->sof_header, soflen); | 786 | cam->sof.header, soflen); |
745 | 787 | ||
746 | DBG(3, "Video frame captured: %lu " | 788 | DBG(3, "Video frame captured: %lu " |
747 | "bytes", (unsigned long)(b)); | 789 | "bytes", (unsigned long)(b)); |
@@ -791,7 +833,13 @@ start_of_frame: | |||
791 | V4L2_PIX_FMT_SN9C10X || | 833 | V4L2_PIX_FMT_SN9C10X || |
792 | cam->sensor.pix_format.pixelformat == | 834 | cam->sensor.pix_format.pixelformat == |
793 | V4L2_PIX_FMT_JPEG) { | 835 | V4L2_PIX_FMT_JPEG) { |
794 | eof = sof - soflen; | 836 | if (sof - pos >= soflen) { |
837 | eof = sof - soflen; | ||
838 | } else { /* remove header */ | ||
839 | eof = pos; | ||
840 | (*f)->buf.bytesused -= | ||
841 | (soflen - (sof - pos)); | ||
842 | } | ||
795 | goto end_of_frame; | 843 | goto end_of_frame; |
796 | } else { | 844 | } else { |
797 | DBG(3, "SOF before expected EOF after " | 845 | DBG(3, "SOF before expected EOF after " |
@@ -878,6 +926,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) | |||
878 | } | 926 | } |
879 | 927 | ||
880 | cam->frame_current = NULL; | 928 | cam->frame_current = NULL; |
929 | cam->sof.bytesread = 0; | ||
881 | 930 | ||
882 | for (i = 0; i < SN9C102_URBS; i++) { | 931 | for (i = 0; i < SN9C102_URBS; i++) { |
883 | err = usb_submit_urb(cam->urb[i], GFP_KERNEL); | 932 | err = usb_submit_urb(cam->urb[i], GFP_KERNEL); |
@@ -959,9 +1008,9 @@ static u16 sn9c102_strtou16(const char* buff, size_t len, ssize_t* count) | |||
959 | 1008 | ||
960 | if (len < 6) { | 1009 | if (len < 6) { |
961 | strncpy(str, buff, len); | 1010 | strncpy(str, buff, len); |
962 | str[len+1] = '\0'; | 1011 | str[len] = '\0'; |
963 | } else { | 1012 | } else { |
964 | strncpy(str, buff, 4); | 1013 | strncpy(str, buff, 6); |
965 | str[6] = '\0'; | 1014 | str[6] = '\0'; |
966 | } | 1015 | } |
967 | 1016 | ||
@@ -1062,7 +1111,7 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf) | |||
1062 | 1111 | ||
1063 | count = sprintf(buf, "%d\n", val); | 1112 | count = sprintf(buf, "%d\n", val); |
1064 | 1113 | ||
1065 | DBG(3, "Read bytes: %zd", count); | 1114 | DBG(3, "Read bytes: %zd, value: %d", count, val); |
1066 | 1115 | ||
1067 | mutex_unlock(&sn9c102_sysfs_lock); | 1116 | mutex_unlock(&sn9c102_sysfs_lock); |
1068 | 1117 | ||
@@ -1197,7 +1246,7 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf) | |||
1197 | 1246 | ||
1198 | count = sprintf(buf, "%d\n", val); | 1247 | count = sprintf(buf, "%d\n", val); |
1199 | 1248 | ||
1200 | DBG(3, "Read bytes: %zd", count); | 1249 | DBG(3, "Read bytes: %zd, value: %d", count, val); |
1201 | 1250 | ||
1202 | mutex_unlock(&sn9c102_sysfs_lock); | 1251 | mutex_unlock(&sn9c102_sysfs_lock); |
1203 | 1252 | ||
@@ -1371,35 +1420,35 @@ static CLASS_DEVICE_ATTR(frame_header, S_IRUGO, | |||
1371 | 1420 | ||
1372 | static int sn9c102_create_sysfs(struct sn9c102_device* cam) | 1421 | static int sn9c102_create_sysfs(struct sn9c102_device* cam) |
1373 | { | 1422 | { |
1374 | struct video_device *v4ldev = cam->v4ldev; | 1423 | struct class_device *classdev = &(cam->v4ldev->class_dev); |
1375 | int err = 0; | 1424 | int err = 0; |
1376 | 1425 | ||
1377 | if ((err = video_device_create_file(v4ldev, &class_device_attr_reg))) | 1426 | if ((err = class_device_create_file(classdev, &class_device_attr_reg))) |
1378 | goto err_out; | 1427 | goto err_out; |
1379 | if ((err = video_device_create_file(v4ldev, &class_device_attr_val))) | 1428 | if ((err = class_device_create_file(classdev, &class_device_attr_val))) |
1380 | goto err_reg; | 1429 | goto err_reg; |
1381 | if ((err = video_device_create_file(v4ldev, | 1430 | if ((err = class_device_create_file(classdev, |
1382 | &class_device_attr_frame_header))) | 1431 | &class_device_attr_frame_header))) |
1383 | goto err_val; | 1432 | goto err_val; |
1384 | 1433 | ||
1385 | if (cam->sensor.sysfs_ops) { | 1434 | if (cam->sensor.sysfs_ops) { |
1386 | if ((err = video_device_create_file(v4ldev, | 1435 | if ((err = class_device_create_file(classdev, |
1387 | &class_device_attr_i2c_reg))) | 1436 | &class_device_attr_i2c_reg))) |
1388 | goto err_frame_header; | 1437 | goto err_frame_header; |
1389 | if ((err = video_device_create_file(v4ldev, | 1438 | if ((err = class_device_create_file(classdev, |
1390 | &class_device_attr_i2c_val))) | 1439 | &class_device_attr_i2c_val))) |
1391 | goto err_i2c_reg; | 1440 | goto err_i2c_reg; |
1392 | } | 1441 | } |
1393 | 1442 | ||
1394 | if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) { | 1443 | if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) { |
1395 | if ((err = video_device_create_file(v4ldev, | 1444 | if ((err = class_device_create_file(classdev, |
1396 | &class_device_attr_green))) | 1445 | &class_device_attr_green))) |
1397 | goto err_i2c_val; | 1446 | goto err_i2c_val; |
1398 | } else { | 1447 | } else { |
1399 | if ((err = video_device_create_file(v4ldev, | 1448 | if ((err = class_device_create_file(classdev, |
1400 | &class_device_attr_blue))) | 1449 | &class_device_attr_blue))) |
1401 | goto err_i2c_val; | 1450 | goto err_i2c_val; |
1402 | if ((err = video_device_create_file(v4ldev, | 1451 | if ((err = class_device_create_file(classdev, |
1403 | &class_device_attr_red))) | 1452 | &class_device_attr_red))) |
1404 | goto err_blue; | 1453 | goto err_blue; |
1405 | } | 1454 | } |
@@ -1407,19 +1456,19 @@ static int sn9c102_create_sysfs(struct sn9c102_device* cam) | |||
1407 | return 0; | 1456 | return 0; |
1408 | 1457 | ||
1409 | err_blue: | 1458 | err_blue: |
1410 | video_device_remove_file(v4ldev, &class_device_attr_blue); | 1459 | class_device_remove_file(classdev, &class_device_attr_blue); |
1411 | err_i2c_val: | 1460 | err_i2c_val: |
1412 | if (cam->sensor.sysfs_ops) | 1461 | if (cam->sensor.sysfs_ops) |
1413 | video_device_remove_file(v4ldev, &class_device_attr_i2c_val); | 1462 | class_device_remove_file(classdev, &class_device_attr_i2c_val); |
1414 | err_i2c_reg: | 1463 | err_i2c_reg: |
1415 | if (cam->sensor.sysfs_ops) | 1464 | if (cam->sensor.sysfs_ops) |
1416 | video_device_remove_file(v4ldev, &class_device_attr_i2c_reg); | 1465 | class_device_remove_file(classdev, &class_device_attr_i2c_reg); |
1417 | err_frame_header: | 1466 | err_frame_header: |
1418 | video_device_remove_file(v4ldev, &class_device_attr_frame_header); | 1467 | class_device_remove_file(classdev, &class_device_attr_frame_header); |
1419 | err_val: | 1468 | err_val: |
1420 | video_device_remove_file(v4ldev, &class_device_attr_val); | 1469 | class_device_remove_file(classdev, &class_device_attr_val); |
1421 | err_reg: | 1470 | err_reg: |
1422 | video_device_remove_file(v4ldev, &class_device_attr_reg); | 1471 | class_device_remove_file(classdev, &class_device_attr_reg); |
1423 | err_out: | 1472 | err_out: |
1424 | return err; | 1473 | return err; |
1425 | } | 1474 | } |
@@ -1477,10 +1526,10 @@ sn9c102_set_compression(struct sn9c102_device* cam, | |||
1477 | case BRIDGE_SN9C101: | 1526 | case BRIDGE_SN9C101: |
1478 | case BRIDGE_SN9C102: | 1527 | case BRIDGE_SN9C102: |
1479 | case BRIDGE_SN9C103: | 1528 | case BRIDGE_SN9C103: |
1480 | if (compression->quality == 0) | 1529 | if (compression->quality == 0) |
1481 | err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01, | 1530 | err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01, |
1482 | 0x17); | 1531 | 0x17); |
1483 | else if (compression->quality == 1) | 1532 | else if (compression->quality == 1) |
1484 | err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe, | 1533 | err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe, |
1485 | 0x17); | 1534 | 0x17); |
1486 | break; | 1535 | break; |
@@ -1489,10 +1538,10 @@ sn9c102_set_compression(struct sn9c102_device* cam, | |||
1489 | if (compression->quality == 0) { | 1538 | if (compression->quality == 0) { |
1490 | for (i = 0; i <= 63; i++) { | 1539 | for (i = 0; i <= 63; i++) { |
1491 | err += sn9c102_write_reg(cam, | 1540 | err += sn9c102_write_reg(cam, |
1492 | SN9C102_Y_QTABLE0[i], | 1541 | SN9C102_Y_QTABLE1[i], |
1493 | 0x100 + i); | 1542 | 0x100 + i); |
1494 | err += sn9c102_write_reg(cam, | 1543 | err += sn9c102_write_reg(cam, |
1495 | SN9C102_UV_QTABLE0[i], | 1544 | SN9C102_UV_QTABLE1[i], |
1496 | 0x140 + i); | 1545 | 0x140 + i); |
1497 | } | 1546 | } |
1498 | err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf, | 1547 | err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf, |
@@ -1597,9 +1646,13 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1597 | if (cam->bridge == BRIDGE_SN9C101 || | 1646 | if (cam->bridge == BRIDGE_SN9C101 || |
1598 | cam->bridge == BRIDGE_SN9C102 || | 1647 | cam->bridge == BRIDGE_SN9C102 || |
1599 | cam->bridge == BRIDGE_SN9C103) { | 1648 | cam->bridge == BRIDGE_SN9C103) { |
1649 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG) | ||
1650 | s->pix_format.pixelformat= V4L2_PIX_FMT_SBGGR8; | ||
1600 | cam->compression.quality = cam->reg[0x17] & 0x01 ? | 1651 | cam->compression.quality = cam->reg[0x17] & 0x01 ? |
1601 | 0 : 1; | 1652 | 0 : 1; |
1602 | } else { | 1653 | } else { |
1654 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) | ||
1655 | s->pix_format.pixelformat = V4L2_PIX_FMT_JPEG; | ||
1603 | cam->compression.quality = cam->reg[0x18] & 0x40 ? | 1656 | cam->compression.quality = cam->reg[0x18] & 0x40 ? |
1604 | 0 : 1; | 1657 | 0 : 1; |
1605 | err += sn9c102_set_compression(cam, &cam->compression); | 1658 | err += sn9c102_set_compression(cam, &cam->compression); |
@@ -1805,7 +1858,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 " | 1858 | DBG(3, "Close and open the device again to choose " |
1806 | "the read method"); | 1859 | "the read method"); |
1807 | mutex_unlock(&cam->fileop_mutex); | 1860 | mutex_unlock(&cam->fileop_mutex); |
1808 | return -EINVAL; | 1861 | return -EBUSY; |
1809 | } | 1862 | } |
1810 | 1863 | ||
1811 | if (cam->io == IO_NONE) { | 1864 | if (cam->io == IO_NONE) { |
@@ -1845,16 +1898,16 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) | |||
1845 | return err; | 1898 | return err; |
1846 | } | 1899 | } |
1847 | } else { | 1900 | } else { |
1848 | timeout = wait_event_interruptible_timeout | 1901 | timeout = wait_event_interruptible_timeout |
1849 | ( cam->wait_frame, | 1902 | ( cam->wait_frame, |
1850 | (!list_empty(&cam->outqueue)) || | 1903 | (!list_empty(&cam->outqueue)) || |
1851 | (cam->state & DEV_DISCONNECTED) || | 1904 | (cam->state & DEV_DISCONNECTED) || |
1852 | (cam->state & DEV_MISCONFIGURED), | 1905 | (cam->state & DEV_MISCONFIGURED), |
1853 | cam->module_param.frame_timeout * | 1906 | cam->module_param.frame_timeout * |
1854 | 1000 * msecs_to_jiffies(1) ); | 1907 | 1000 * msecs_to_jiffies(1) ); |
1855 | if (timeout < 0) { | 1908 | if (timeout < 0) { |
1856 | mutex_unlock(&cam->fileop_mutex); | 1909 | mutex_unlock(&cam->fileop_mutex); |
1857 | return timeout; | 1910 | return timeout; |
1858 | } else if (timeout == 0 && | 1911 | } else if (timeout == 0 && |
1859 | !(cam->state & DEV_DISCONNECTED)) { | 1912 | !(cam->state & DEV_DISCONNECTED)) { |
1860 | DBG(1, "Video frame timeout elapsed"); | 1913 | DBG(1, "Video frame timeout elapsed"); |
@@ -2001,7 +2054,12 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) | |||
2001 | return -EIO; | 2054 | return -EIO; |
2002 | } | 2055 | } |
2003 | 2056 | ||
2004 | if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || | 2057 | if (!(vma->vm_flags & (VM_WRITE | VM_READ))) { |
2058 | mutex_unlock(&cam->fileop_mutex); | ||
2059 | return -EACCES; | ||
2060 | } | ||
2061 | |||
2062 | if (cam->io != IO_MMAP || | ||
2005 | size != PAGE_ALIGN(cam->frame[0].buf.length)) { | 2063 | size != PAGE_ALIGN(cam->frame[0].buf.length)) { |
2006 | mutex_unlock(&cam->fileop_mutex); | 2064 | mutex_unlock(&cam->fileop_mutex); |
2007 | return -EINVAL; | 2065 | return -EINVAL; |
@@ -2267,7 +2325,7 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg) | |||
2267 | if (cam->frame[i].vma_use_count) { | 2325 | if (cam->frame[i].vma_use_count) { |
2268 | DBG(3, "VIDIOC_S_CROP failed. " | 2326 | DBG(3, "VIDIOC_S_CROP failed. " |
2269 | "Unmap the buffers first."); | 2327 | "Unmap the buffers first."); |
2270 | return -EINVAL; | 2328 | return -EBUSY; |
2271 | } | 2329 | } |
2272 | 2330 | ||
2273 | /* Preserve R,G or B origin */ | 2331 | /* Preserve R,G or B origin */ |
@@ -2410,8 +2468,8 @@ sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg) | |||
2410 | case BRIDGE_SN9C101: | 2468 | case BRIDGE_SN9C101: |
2411 | case BRIDGE_SN9C102: | 2469 | case BRIDGE_SN9C102: |
2412 | case BRIDGE_SN9C103: | 2470 | case BRIDGE_SN9C103: |
2413 | strcpy(fmtd.description, "compressed"); | 2471 | strcpy(fmtd.description, "compressed"); |
2414 | fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X; | 2472 | fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X; |
2415 | break; | 2473 | break; |
2416 | case BRIDGE_SN9C105: | 2474 | case BRIDGE_SN9C105: |
2417 | case BRIDGE_SN9C120: | 2475 | case BRIDGE_SN9C120: |
@@ -2445,8 +2503,10 @@ sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg) | |||
2445 | if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 2503 | if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
2446 | return -EINVAL; | 2504 | return -EINVAL; |
2447 | 2505 | ||
2448 | pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X || | 2506 | pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_JPEG) ? |
2449 | pfmt->pixelformat==V4L2_PIX_FMT_JPEG) | 2507 | V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB; |
2508 | pfmt->bytesperline = (pfmt->pixelformat == V4L2_PIX_FMT_SN9C10X || | ||
2509 | pfmt->pixelformat == V4L2_PIX_FMT_JPEG) | ||
2450 | ? 0 : (pfmt->width * pfmt->priv) / 8; | 2510 | ? 0 : (pfmt->width * pfmt->priv) / 8; |
2451 | pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); | 2511 | pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); |
2452 | pfmt->field = V4L2_FIELD_NONE; | 2512 | pfmt->field = V4L2_FIELD_NONE; |
@@ -2521,9 +2581,9 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, | |||
2521 | case BRIDGE_SN9C101: | 2581 | case BRIDGE_SN9C101: |
2522 | case BRIDGE_SN9C102: | 2582 | case BRIDGE_SN9C102: |
2523 | case BRIDGE_SN9C103: | 2583 | case BRIDGE_SN9C103: |
2524 | if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X && | 2584 | if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X && |
2525 | pix->pixelformat != V4L2_PIX_FMT_SBGGR8) | 2585 | pix->pixelformat != V4L2_PIX_FMT_SBGGR8) |
2526 | pix->pixelformat = pfmt->pixelformat; | 2586 | pix->pixelformat = pfmt->pixelformat; |
2527 | break; | 2587 | break; |
2528 | case BRIDGE_SN9C105: | 2588 | case BRIDGE_SN9C105: |
2529 | case BRIDGE_SN9C120: | 2589 | case BRIDGE_SN9C120: |
@@ -2533,7 +2593,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, | |||
2533 | break; | 2593 | break; |
2534 | } | 2594 | } |
2535 | pix->priv = pfmt->priv; /* bpp */ | 2595 | pix->priv = pfmt->priv; /* bpp */ |
2536 | pix->colorspace = pfmt->colorspace; | 2596 | pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_JPEG) ? |
2597 | V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB; | ||
2537 | pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X || | 2598 | pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X || |
2538 | pix->pixelformat == V4L2_PIX_FMT_JPEG) | 2599 | pix->pixelformat == V4L2_PIX_FMT_JPEG) |
2539 | ? 0 : (pix->width * pix->priv) / 8; | 2600 | ? 0 : (pix->width * pix->priv) / 8; |
@@ -2551,7 +2612,7 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, | |||
2551 | if (cam->frame[i].vma_use_count) { | 2612 | if (cam->frame[i].vma_use_count) { |
2552 | DBG(3, "VIDIOC_S_FMT failed. Unmap the " | 2613 | DBG(3, "VIDIOC_S_FMT failed. Unmap the " |
2553 | "buffers first."); | 2614 | "buffers first."); |
2554 | return -EINVAL; | 2615 | return -EBUSY; |
2555 | } | 2616 | } |
2556 | 2617 | ||
2557 | if (cam->stream == STREAM_ON) | 2618 | if (cam->stream == STREAM_ON) |
@@ -2666,14 +2727,14 @@ sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg) | |||
2666 | if (cam->io == IO_READ) { | 2727 | if (cam->io == IO_READ) { |
2667 | DBG(3, "Close and open the device again to choose the mmap " | 2728 | DBG(3, "Close and open the device again to choose the mmap " |
2668 | "I/O method"); | 2729 | "I/O method"); |
2669 | return -EINVAL; | 2730 | return -EBUSY; |
2670 | } | 2731 | } |
2671 | 2732 | ||
2672 | for (i = 0; i < cam->nbuffers; i++) | 2733 | for (i = 0; i < cam->nbuffers; i++) |
2673 | if (cam->frame[i].vma_use_count) { | 2734 | if (cam->frame[i].vma_use_count) { |
2674 | DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are " | 2735 | DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are " |
2675 | "still mapped."); | 2736 | "still mapped."); |
2676 | return -EINVAL; | 2737 | return -EBUSY; |
2677 | } | 2738 | } |
2678 | 2739 | ||
2679 | if (cam->stream == STREAM_ON) | 2740 | if (cam->stream == STREAM_ON) |
@@ -2785,15 +2846,15 @@ sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp, | |||
2785 | if (err) | 2846 | if (err) |
2786 | return err; | 2847 | return err; |
2787 | } else { | 2848 | } else { |
2788 | timeout = wait_event_interruptible_timeout | 2849 | timeout = wait_event_interruptible_timeout |
2789 | ( cam->wait_frame, | 2850 | ( cam->wait_frame, |
2790 | (!list_empty(&cam->outqueue)) || | 2851 | (!list_empty(&cam->outqueue)) || |
2791 | (cam->state & DEV_DISCONNECTED) || | 2852 | (cam->state & DEV_DISCONNECTED) || |
2792 | (cam->state & DEV_MISCONFIGURED), | 2853 | (cam->state & DEV_MISCONFIGURED), |
2793 | cam->module_param.frame_timeout * | 2854 | cam->module_param.frame_timeout * |
2794 | 1000 * msecs_to_jiffies(1) ); | 2855 | 1000 * msecs_to_jiffies(1) ); |
2795 | if (timeout < 0) | 2856 | if (timeout < 0) |
2796 | return timeout; | 2857 | return timeout; |
2797 | else if (timeout == 0 && | 2858 | else if (timeout == 0 && |
2798 | !(cam->state & DEV_DISCONNECTED)) { | 2859 | !(cam->state & DEV_DISCONNECTED)) { |
2799 | DBG(1, "Video frame timeout elapsed"); | 2860 | DBG(1, "Video frame timeout elapsed"); |
@@ -2837,9 +2898,6 @@ sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg) | |||
2837 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) | 2898 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) |
2838 | return -EINVAL; | 2899 | return -EINVAL; |
2839 | 2900 | ||
2840 | if (list_empty(&cam->inqueue)) | ||
2841 | return -EINVAL; | ||
2842 | |||
2843 | cam->stream = STREAM_ON; | 2901 | cam->stream = STREAM_ON; |
2844 | 2902 | ||
2845 | DBG(3, "Stream on"); | 2903 | DBG(3, "Stream on"); |
@@ -3166,8 +3224,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3166 | 3224 | ||
3167 | r = sn9c102_read_reg(cam, 0x00); | 3225 | r = sn9c102_read_reg(cam, 0x00); |
3168 | if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) { | 3226 | if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) { |
3169 | DBG(1, "Sorry, this is not a SN9C1xx based camera " | 3227 | DBG(1, "Sorry, this is not a SN9C1xx-based camera " |
3170 | "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | 3228 | "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); |
3171 | err = -ENODEV; | 3229 | err = -ENODEV; |
3172 | goto fail; | 3230 | goto fail; |
3173 | } | 3231 | } |
@@ -3177,19 +3235,19 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3177 | case BRIDGE_SN9C101: | 3235 | case BRIDGE_SN9C101: |
3178 | case BRIDGE_SN9C102: | 3236 | case BRIDGE_SN9C102: |
3179 | DBG(2, "SN9C10[12] PC Camera Controller detected " | 3237 | DBG(2, "SN9C10[12] PC Camera Controller detected " |
3180 | "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | 3238 | "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); |
3181 | break; | 3239 | break; |
3182 | case BRIDGE_SN9C103: | 3240 | case BRIDGE_SN9C103: |
3183 | DBG(2, "SN9C103 PC Camera Controller detected " | 3241 | DBG(2, "SN9C103 PC Camera Controller detected " |
3184 | "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | 3242 | "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); |
3185 | break; | 3243 | break; |
3186 | case BRIDGE_SN9C105: | 3244 | case BRIDGE_SN9C105: |
3187 | DBG(2, "SN9C105 PC Camera Controller detected " | 3245 | DBG(2, "SN9C105 PC Camera Controller detected " |
3188 | "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | 3246 | "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); |
3189 | break; | 3247 | break; |
3190 | case BRIDGE_SN9C120: | 3248 | case BRIDGE_SN9C120: |
3191 | DBG(2, "SN9C120 PC Camera Controller detected " | 3249 | DBG(2, "SN9C120 PC Camera Controller detected " |
3192 | "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | 3250 | "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); |
3193 | break; | 3251 | break; |
3194 | } | 3252 | } |
3195 | 3253 | ||
@@ -3260,6 +3318,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3260 | "device controlling. Error #%d", err); | 3318 | "device controlling. Error #%d", err); |
3261 | #else | 3319 | #else |
3262 | DBG(2, "Optional device control through 'sysfs' interface disabled"); | 3320 | DBG(2, "Optional device control through 'sysfs' interface disabled"); |
3321 | DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' " | ||
3322 | "configuration option to enable it."); | ||
3263 | #endif | 3323 | #endif |
3264 | 3324 | ||
3265 | usb_set_intfdata(intf, cam); | 3325 | 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..28a861aed044 100644 --- a/drivers/media/video/sn9c102/sn9c102_hv7131d.c +++ b/drivers/media/video/sn9c102/sn9c102_hv7131d.c | |||
@@ -22,19 +22,13 @@ | |||
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; |
31 | 28 | ||
32 | err += sn9c102_write_reg(cam, 0x00, 0x10); | 29 | err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11}, |
33 | err += sn9c102_write_reg(cam, 0x00, 0x11); | 30 | {0x00, 0x14}, {0x60, 0x17}, |
34 | err += sn9c102_write_reg(cam, 0x00, 0x14); | 31 | {0x0e, 0x18}, {0xf2, 0x19}); |
35 | err += sn9c102_write_reg(cam, 0x60, 0x17); | ||
36 | err += sn9c102_write_reg(cam, 0x0e, 0x18); | ||
37 | err += sn9c102_write_reg(cam, 0xf2, 0x19); | ||
38 | 32 | ||
39 | err += sn9c102_i2c_write(cam, 0x01, 0x04); | 33 | err += sn9c102_i2c_write(cam, 0x01, 0x04); |
40 | err += sn9c102_i2c_write(cam, 0x02, 0x00); | 34 | err += sn9c102_i2c_write(cam, 0x02, 0x00); |
@@ -153,7 +147,7 @@ static int hv7131d_set_pix_format(struct sn9c102_device* cam, | |||
153 | static struct sn9c102_sensor hv7131d = { | 147 | static struct sn9c102_sensor hv7131d = { |
154 | .name = "HV7131D", | 148 | .name = "HV7131D", |
155 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | 149 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", |
156 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, | 150 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, |
157 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, | 151 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, |
158 | .frequency = SN9C102_I2C_100KHZ, | 152 | .frequency = SN9C102_I2C_100KHZ, |
159 | .interface = SN9C102_I2C_2WIRES, | 153 | .interface = SN9C102_I2C_2WIRES, |
@@ -250,11 +244,10 @@ static struct sn9c102_sensor hv7131d = { | |||
250 | 244 | ||
251 | int sn9c102_probe_hv7131d(struct sn9c102_device* cam) | 245 | int sn9c102_probe_hv7131d(struct sn9c102_device* cam) |
252 | { | 246 | { |
253 | int r0 = 0, r1 = 0, err = 0; | 247 | int r0 = 0, r1 = 0, err; |
254 | 248 | ||
255 | err += sn9c102_write_reg(cam, 0x01, 0x01); | 249 | err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01}, |
256 | err += sn9c102_write_reg(cam, 0x00, 0x01); | 250 | {0x28, 0x17}); |
257 | err += sn9c102_write_reg(cam, 0x28, 0x17); | ||
258 | if (err) | 251 | if (err) |
259 | return -EIO; | 252 | return -EIO; |
260 | 253 | ||
@@ -263,7 +256,7 @@ int sn9c102_probe_hv7131d(struct sn9c102_device* cam) | |||
263 | if (r0 < 0 || r1 < 0) | 256 | if (r0 < 0 || r1 < 0) |
264 | return -EIO; | 257 | return -EIO; |
265 | 258 | ||
266 | if (r0 != 0x00 && r1 != 0x04) | 259 | if (r0 != 0x00 || r1 != 0x04) |
267 | return -ENODEV; | 260 | return -ENODEV; |
268 | 261 | ||
269 | sn9c102_attach_sensor(cam, &hv7131d); | 262 | 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..5a495baa5f95 --- /dev/null +++ b/drivers/media/video/sn9c102/sn9c102_hv7131r.c | |||
@@ -0,0 +1,366 @@ | |||
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_const_regs(cam, {0x00, 0x03}, {0x1a, 0x04}, | ||
32 | {0x20, 0x05}, {0x20, 0x06}, | ||
33 | {0x03, 0x10}, {0x00, 0x14}, | ||
34 | {0x60, 0x17}, {0x0a, 0x18}, | ||
35 | {0xf0, 0x19}, {0x1d, 0x1a}, | ||
36 | {0x10, 0x1b}, {0x02, 0x1c}, | ||
37 | {0x03, 0x1d}, {0x0f, 0x1e}, | ||
38 | {0x0c, 0x1f}, {0x00, 0x20}, | ||
39 | {0x10, 0x21}, {0x20, 0x22}, | ||
40 | {0x30, 0x23}, {0x40, 0x24}, | ||
41 | {0x50, 0x25}, {0x60, 0x26}, | ||
42 | {0x70, 0x27}, {0x80, 0x28}, | ||
43 | {0x90, 0x29}, {0xa0, 0x2a}, | ||
44 | {0xb0, 0x2b}, {0xc0, 0x2c}, | ||
45 | {0xd0, 0x2d}, {0xe0, 0x2e}, | ||
46 | {0xf0, 0x2f}, {0xff, 0x30}); | ||
47 | |||
48 | break; | ||
49 | case BRIDGE_SN9C105: | ||
50 | case BRIDGE_SN9C120: | ||
51 | err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02}, | ||
52 | {0x00, 0x03}, {0x1a, 0x04}, | ||
53 | {0x44, 0x05}, {0x3e, 0x06}, | ||
54 | {0x1a, 0x07}, {0x03, 0x10}, | ||
55 | {0x08, 0x14}, {0xa3, 0x17}, | ||
56 | {0x4b, 0x18}, {0x00, 0x19}, | ||
57 | {0x1d, 0x1a}, {0x10, 0x1b}, | ||
58 | {0x02, 0x1c}, {0x03, 0x1d}, | ||
59 | {0x0f, 0x1e}, {0x0c, 0x1f}, | ||
60 | {0x00, 0x20}, {0x29, 0x21}, | ||
61 | {0x40, 0x22}, {0x54, 0x23}, | ||
62 | {0x66, 0x24}, {0x76, 0x25}, | ||
63 | {0x85, 0x26}, {0x94, 0x27}, | ||
64 | {0xa1, 0x28}, {0xae, 0x29}, | ||
65 | {0xbb, 0x2a}, {0xc7, 0x2b}, | ||
66 | {0xd3, 0x2c}, {0xde, 0x2d}, | ||
67 | {0xea, 0x2e}, {0xf4, 0x2f}, | ||
68 | {0xff, 0x30}, {0x00, 0x3F}, | ||
69 | {0xC7, 0x40}, {0x01, 0x41}, | ||
70 | {0x44, 0x42}, {0x00, 0x43}, | ||
71 | {0x44, 0x44}, {0x00, 0x45}, | ||
72 | {0x44, 0x46}, {0x00, 0x47}, | ||
73 | {0xC7, 0x48}, {0x01, 0x49}, | ||
74 | {0xC7, 0x4A}, {0x01, 0x4B}, | ||
75 | {0xC7, 0x4C}, {0x01, 0x4D}, | ||
76 | {0x44, 0x4E}, {0x00, 0x4F}, | ||
77 | {0x44, 0x50}, {0x00, 0x51}, | ||
78 | {0x44, 0x52}, {0x00, 0x53}, | ||
79 | {0xC7, 0x54}, {0x01, 0x55}, | ||
80 | {0xC7, 0x56}, {0x01, 0x57}, | ||
81 | {0xC7, 0x58}, {0x01, 0x59}, | ||
82 | {0x44, 0x5A}, {0x00, 0x5B}, | ||
83 | {0x44, 0x5C}, {0x00, 0x5D}, | ||
84 | {0x44, 0x5E}, {0x00, 0x5F}, | ||
85 | {0xC7, 0x60}, {0x01, 0x61}, | ||
86 | {0xC7, 0x62}, {0x01, 0x63}, | ||
87 | {0xC7, 0x64}, {0x01, 0x65}, | ||
88 | {0x44, 0x66}, {0x00, 0x67}, | ||
89 | {0x44, 0x68}, {0x00, 0x69}, | ||
90 | {0x44, 0x6A}, {0x00, 0x6B}, | ||
91 | {0xC7, 0x6C}, {0x01, 0x6D}, | ||
92 | {0xC7, 0x6E}, {0x01, 0x6F}, | ||
93 | {0xC7, 0x70}, {0x01, 0x71}, | ||
94 | {0x44, 0x72}, {0x00, 0x73}, | ||
95 | {0x44, 0x74}, {0x00, 0x75}, | ||
96 | {0x44, 0x76}, {0x00, 0x77}, | ||
97 | {0xC7, 0x78}, {0x01, 0x79}, | ||
98 | {0xC7, 0x7A}, {0x01, 0x7B}, | ||
99 | {0xC7, 0x7C}, {0x01, 0x7D}, | ||
100 | {0x44, 0x7E}, {0x00, 0x7F}, | ||
101 | {0x14, 0x84}, {0x00, 0x85}, | ||
102 | {0x27, 0x86}, {0x00, 0x87}, | ||
103 | {0x07, 0x88}, {0x00, 0x89}, | ||
104 | {0xEC, 0x8A}, {0x0f, 0x8B}, | ||
105 | {0xD8, 0x8C}, {0x0f, 0x8D}, | ||
106 | {0x3D, 0x8E}, {0x00, 0x8F}, | ||
107 | {0x3D, 0x90}, {0x00, 0x91}, | ||
108 | {0xCD, 0x92}, {0x0f, 0x93}, | ||
109 | {0xf7, 0x94}, {0x0f, 0x95}, | ||
110 | {0x0C, 0x96}, {0x00, 0x97}, | ||
111 | {0x00, 0x98}, {0x66, 0x99}, | ||
112 | {0x05, 0x9A}, {0x00, 0x9B}, | ||
113 | {0x04, 0x9C}, {0x00, 0x9D}, | ||
114 | {0x08, 0x9E}, {0x00, 0x9F}, | ||
115 | {0x2D, 0xC0}, {0x2D, 0xC1}, | ||
116 | {0x3A, 0xC2}, {0x05, 0xC3}, | ||
117 | {0x04, 0xC4}, {0x3F, 0xC5}, | ||
118 | {0x00, 0xC6}, {0x00, 0xC7}, | ||
119 | {0x50, 0xC8}, {0x3C, 0xC9}, | ||
120 | {0x28, 0xCA}, {0xD8, 0xCB}, | ||
121 | {0x14, 0xCC}, {0xEC, 0xCD}, | ||
122 | {0x32, 0xCE}, {0xDD, 0xCF}, | ||
123 | {0x32, 0xD0}, {0xDD, 0xD1}, | ||
124 | {0x6A, 0xD2}, {0x50, 0xD3}, | ||
125 | {0x00, 0xD4}, {0x00, 0xD5}, | ||
126 | {0x00, 0xD6}); | ||
127 | break; | ||
128 | default: | ||
129 | break; | ||
130 | } | ||
131 | |||
132 | err += sn9c102_i2c_write(cam, 0x20, 0x00); | ||
133 | err += sn9c102_i2c_write(cam, 0x21, 0xd6); | ||
134 | err += sn9c102_i2c_write(cam, 0x25, 0x06); | ||
135 | |||
136 | return err; | ||
137 | } | ||
138 | |||
139 | |||
140 | static int hv7131r_get_ctrl(struct sn9c102_device* cam, | ||
141 | struct v4l2_control* ctrl) | ||
142 | { | ||
143 | switch (ctrl->id) { | ||
144 | case V4L2_CID_GAIN: | ||
145 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x30)) < 0) | ||
146 | return -EIO; | ||
147 | return 0; | ||
148 | case V4L2_CID_RED_BALANCE: | ||
149 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x31)) < 0) | ||
150 | return -EIO; | ||
151 | ctrl->value = ctrl->value & 0x3f; | ||
152 | return 0; | ||
153 | case V4L2_CID_BLUE_BALANCE: | ||
154 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x33)) < 0) | ||
155 | return -EIO; | ||
156 | ctrl->value = ctrl->value & 0x3f; | ||
157 | return 0; | ||
158 | case SN9C102_V4L2_CID_GREEN_BALANCE: | ||
159 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x32)) < 0) | ||
160 | return -EIO; | ||
161 | ctrl->value = ctrl->value & 0x3f; | ||
162 | return 0; | ||
163 | case V4L2_CID_BLACK_LEVEL: | ||
164 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x01)) < 0) | ||
165 | return -EIO; | ||
166 | ctrl->value = (ctrl->value & 0x08) ? 1 : 0; | ||
167 | return 0; | ||
168 | default: | ||
169 | return -EINVAL; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | |||
174 | static int hv7131r_set_ctrl(struct sn9c102_device* cam, | ||
175 | const struct v4l2_control* ctrl) | ||
176 | { | ||
177 | int err = 0; | ||
178 | |||
179 | switch (ctrl->id) { | ||
180 | case V4L2_CID_GAIN: | ||
181 | err += sn9c102_i2c_write(cam, 0x30, ctrl->value); | ||
182 | break; | ||
183 | case V4L2_CID_RED_BALANCE: | ||
184 | err += sn9c102_i2c_write(cam, 0x31, ctrl->value); | ||
185 | break; | ||
186 | case V4L2_CID_BLUE_BALANCE: | ||
187 | err += sn9c102_i2c_write(cam, 0x33, ctrl->value); | ||
188 | break; | ||
189 | case SN9C102_V4L2_CID_GREEN_BALANCE: | ||
190 | err += sn9c102_i2c_write(cam, 0x32, ctrl->value); | ||
191 | break; | ||
192 | case V4L2_CID_BLACK_LEVEL: | ||
193 | { | ||
194 | int r = sn9c102_i2c_read(cam, 0x01); | ||
195 | if (r < 0) | ||
196 | return -EIO; | ||
197 | err += sn9c102_i2c_write(cam, 0x01, | ||
198 | (ctrl->value<<3) | (r&0xf7)); | ||
199 | } | ||
200 | break; | ||
201 | default: | ||
202 | return -EINVAL; | ||
203 | } | ||
204 | |||
205 | return err ? -EIO : 0; | ||
206 | } | ||
207 | |||
208 | |||
209 | static int hv7131r_set_crop(struct sn9c102_device* cam, | ||
210 | const struct v4l2_rect* rect) | ||
211 | { | ||
212 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
213 | int err = 0; | ||
214 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1, | ||
215 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; | ||
216 | |||
217 | err += sn9c102_write_reg(cam, h_start, 0x12); | ||
218 | err += sn9c102_write_reg(cam, v_start, 0x13); | ||
219 | |||
220 | return err; | ||
221 | } | ||
222 | |||
223 | |||
224 | static int hv7131r_set_pix_format(struct sn9c102_device* cam, | ||
225 | const struct v4l2_pix_format* pix) | ||
226 | { | ||
227 | int err = 0; | ||
228 | |||
229 | switch (sn9c102_get_bridge(cam)) { | ||
230 | case BRIDGE_SN9C103: | ||
231 | if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) { | ||
232 | err += sn9c102_write_reg(cam, 0xa0, 0x19); | ||
233 | err += sn9c102_i2c_write(cam, 0x01, 0x04); | ||
234 | } else { | ||
235 | err += sn9c102_write_reg(cam, 0x30, 0x19); | ||
236 | err += sn9c102_i2c_write(cam, 0x01, 0x04); | ||
237 | } | ||
238 | break; | ||
239 | case BRIDGE_SN9C105: | ||
240 | case BRIDGE_SN9C120: | ||
241 | if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) { | ||
242 | err += sn9c102_write_reg(cam, 0xa5, 0x17); | ||
243 | err += sn9c102_i2c_write(cam, 0x01, 0x24); | ||
244 | } else { | ||
245 | err += sn9c102_write_reg(cam, 0xa3, 0x17); | ||
246 | err += sn9c102_i2c_write(cam, 0x01, 0x04); | ||
247 | } | ||
248 | break; | ||
249 | default: | ||
250 | break; | ||
251 | } | ||
252 | |||
253 | return err; | ||
254 | } | ||
255 | |||
256 | |||
257 | static struct sn9c102_sensor hv7131r = { | ||
258 | .name = "HV7131R", | ||
259 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | ||
260 | .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120, | ||
261 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, | ||
262 | .frequency = SN9C102_I2C_100KHZ, | ||
263 | .interface = SN9C102_I2C_2WIRES, | ||
264 | .i2c_slave_id = 0x11, | ||
265 | .init = &hv7131r_init, | ||
266 | .qctrl = { | ||
267 | { | ||
268 | .id = V4L2_CID_GAIN, | ||
269 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
270 | .name = "global gain", | ||
271 | .minimum = 0x00, | ||
272 | .maximum = 0xff, | ||
273 | .step = 0x01, | ||
274 | .default_value = 0x40, | ||
275 | .flags = 0, | ||
276 | }, | ||
277 | { | ||
278 | .id = V4L2_CID_RED_BALANCE, | ||
279 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
280 | .name = "red balance", | ||
281 | .minimum = 0x00, | ||
282 | .maximum = 0x3f, | ||
283 | .step = 0x01, | ||
284 | .default_value = 0x08, | ||
285 | .flags = 0, | ||
286 | }, | ||
287 | { | ||
288 | .id = V4L2_CID_BLUE_BALANCE, | ||
289 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
290 | .name = "blue balance", | ||
291 | .minimum = 0x00, | ||
292 | .maximum = 0x3f, | ||
293 | .step = 0x01, | ||
294 | .default_value = 0x1a, | ||
295 | .flags = 0, | ||
296 | }, | ||
297 | { | ||
298 | .id = SN9C102_V4L2_CID_GREEN_BALANCE, | ||
299 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
300 | .name = "green balance", | ||
301 | .minimum = 0x00, | ||
302 | .maximum = 0x3f, | ||
303 | .step = 0x01, | ||
304 | .default_value = 0x2f, | ||
305 | .flags = 0, | ||
306 | }, | ||
307 | { | ||
308 | .id = V4L2_CID_BLACK_LEVEL, | ||
309 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
310 | .name = "auto black level compensation", | ||
311 | .minimum = 0x00, | ||
312 | .maximum = 0x01, | ||
313 | .step = 0x01, | ||
314 | .default_value = 0x00, | ||
315 | .flags = 0, | ||
316 | }, | ||
317 | }, | ||
318 | .get_ctrl = &hv7131r_get_ctrl, | ||
319 | .set_ctrl = &hv7131r_set_ctrl, | ||
320 | .cropcap = { | ||
321 | .bounds = { | ||
322 | .left = 0, | ||
323 | .top = 0, | ||
324 | .width = 640, | ||
325 | .height = 480, | ||
326 | }, | ||
327 | .defrect = { | ||
328 | .left = 0, | ||
329 | .top = 0, | ||
330 | .width = 640, | ||
331 | .height = 480, | ||
332 | }, | ||
333 | }, | ||
334 | .set_crop = &hv7131r_set_crop, | ||
335 | .pix_format = { | ||
336 | .width = 640, | ||
337 | .height = 480, | ||
338 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | ||
339 | .priv = 8, | ||
340 | }, | ||
341 | .set_pix_format = &hv7131r_set_pix_format | ||
342 | }; | ||
343 | |||
344 | |||
345 | int sn9c102_probe_hv7131r(struct sn9c102_device* cam) | ||
346 | { | ||
347 | int devid, err; | ||
348 | |||
349 | err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x02}, | ||
350 | {0x34, 0x01}, {0x20, 0x17}, | ||
351 | {0x34, 0x01}, {0x46, 0x01}); | ||
352 | |||
353 | if (err) | ||
354 | return -EIO; | ||
355 | |||
356 | devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00); | ||
357 | if (devid < 0) | ||
358 | return -EIO; | ||
359 | |||
360 | if (devid != 0x02) | ||
361 | return -ENODEV; | ||
362 | |||
363 | sn9c102_attach_sensor(cam, &hv7131r); | ||
364 | |||
365 | return 0; | ||
366 | } | ||
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0343.c b/drivers/media/video/sn9c102/sn9c102_mi0343.c index a33d1bc10f90..9200845d011b 100644 --- a/drivers/media/video/sn9c102/sn9c102_mi0343.c +++ b/drivers/media/video/sn9c102/sn9c102_mi0343.c | |||
@@ -22,36 +22,30 @@ | |||
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_const_regs(cam, {0x00, 0x10}, {0x00, 0x11}, |
34 | err += sn9c102_write_reg(cam, 0x00, 0x11); | 31 | {0x0a, 0x14}, {0x40, 0x01}, |
35 | err += sn9c102_write_reg(cam, 0x0a, 0x14); | 32 | {0x20, 0x17}, {0x07, 0x18}, |
36 | err += sn9c102_write_reg(cam, 0x40, 0x01); | 33 | {0xa0, 0x19}); |
37 | err += sn9c102_write_reg(cam, 0x20, 0x17); | 34 | |
38 | err += sn9c102_write_reg(cam, 0x07, 0x18); | 35 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d, |
39 | err += sn9c102_write_reg(cam, 0xa0, 0x19); | 36 | 0x00, 0x01, 0, 0); |
40 | 37 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d, | |
41 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 38 | 0x00, 0x00, 0, 0); |
42 | 0x0d, 0x00, 0x01, 0, 0); | 39 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03, |
43 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 40 | 0x01, 0xe1, 0, 0); |
44 | 0x0d, 0x00, 0x00, 0, 0); | 41 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04, |
45 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 42 | 0x02, 0x81, 0, 0); |
46 | 0x03, 0x01, 0xe1, 0, 0); | 43 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05, |
47 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 44 | 0x00, 0x17, 0, 0); |
48 | 0x04, 0x02, 0x81, 0, 0); | 45 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06, |
49 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 46 | 0x00, 0x11, 0, 0); |
50 | 0x05, 0x00, 0x17, 0, 0); | 47 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62, |
51 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | 48 | 0x04, 0x9a, 0, 0); |
52 | 0x06, 0x00, 0x11, 0, 0); | ||
53 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, | ||
54 | 0x62, 0x04, 0x9a, 0, 0); | ||
55 | 49 | ||
56 | return err; | 50 | return err; |
57 | } | 51 | } |
@@ -60,43 +54,46 @@ static int mi0343_init(struct sn9c102_device* cam) | |||
60 | static int mi0343_get_ctrl(struct sn9c102_device* cam, | 54 | static int mi0343_get_ctrl(struct sn9c102_device* cam, |
61 | struct v4l2_control* ctrl) | 55 | struct v4l2_control* ctrl) |
62 | { | 56 | { |
57 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
58 | u8 data[5+1]; | ||
59 | |||
63 | switch (ctrl->id) { | 60 | switch (ctrl->id) { |
64 | case V4L2_CID_EXPOSURE: | 61 | case V4L2_CID_EXPOSURE: |
65 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 62 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, |
66 | 0x09, 2+1, mi0343_i2c_data) < 0) | 63 | 2+1, data) < 0) |
67 | return -EIO; | 64 | return -EIO; |
68 | ctrl->value = mi0343_i2c_data[2]; | 65 | ctrl->value = data[2]; |
69 | return 0; | 66 | return 0; |
70 | case V4L2_CID_GAIN: | 67 | case V4L2_CID_GAIN: |
71 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 68 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, |
72 | 0x35, 2+1, mi0343_i2c_data) < 0) | 69 | 2+1, data) < 0) |
73 | return -EIO; | 70 | return -EIO; |
74 | break; | 71 | break; |
75 | case V4L2_CID_HFLIP: | 72 | case V4L2_CID_HFLIP: |
76 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 73 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, |
77 | 0x20, 2+1, mi0343_i2c_data) < 0) | 74 | 2+1, data) < 0) |
78 | return -EIO; | 75 | return -EIO; |
79 | ctrl->value = mi0343_i2c_data[3] & 0x20 ? 1 : 0; | 76 | ctrl->value = data[3] & 0x20 ? 1 : 0; |
80 | return 0; | 77 | return 0; |
81 | case V4L2_CID_VFLIP: | 78 | case V4L2_CID_VFLIP: |
82 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 79 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, |
83 | 0x20, 2+1, mi0343_i2c_data) < 0) | 80 | 2+1, data) < 0) |
84 | return -EIO; | 81 | return -EIO; |
85 | ctrl->value = mi0343_i2c_data[3] & 0x80 ? 1 : 0; | 82 | ctrl->value = data[3] & 0x80 ? 1 : 0; |
86 | return 0; | 83 | return 0; |
87 | case V4L2_CID_RED_BALANCE: | 84 | case V4L2_CID_RED_BALANCE: |
88 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 85 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, |
89 | 0x2d, 2+1, mi0343_i2c_data) < 0) | 86 | 2+1, data) < 0) |
90 | return -EIO; | 87 | return -EIO; |
91 | break; | 88 | break; |
92 | case V4L2_CID_BLUE_BALANCE: | 89 | case V4L2_CID_BLUE_BALANCE: |
93 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 90 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, |
94 | 0x2c, 2+1, mi0343_i2c_data) < 0) | 91 | 2+1, data) < 0) |
95 | return -EIO; | 92 | return -EIO; |
96 | break; | 93 | break; |
97 | case SN9C102_V4L2_CID_GREEN_BALANCE: | 94 | case SN9C102_V4L2_CID_GREEN_BALANCE: |
98 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, | 95 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, |
99 | 0x2e, 2+1, mi0343_i2c_data) < 0) | 96 | 2+1, data) < 0) |
100 | return -EIO; | 97 | return -EIO; |
101 | break; | 98 | break; |
102 | default: | 99 | default: |
@@ -108,7 +105,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam, | |||
108 | case V4L2_CID_RED_BALANCE: | 105 | case V4L2_CID_RED_BALANCE: |
109 | case V4L2_CID_BLUE_BALANCE: | 106 | case V4L2_CID_BLUE_BALANCE: |
110 | case SN9C102_V4L2_CID_GREEN_BALANCE: | 107 | case SN9C102_V4L2_CID_GREEN_BALANCE: |
111 | ctrl->value = mi0343_i2c_data[3] | (mi0343_i2c_data[2] << 8); | 108 | ctrl->value = data[3] | (data[2] << 8); |
112 | if (ctrl->value >= 0x10 && ctrl->value <= 0x3f) | 109 | if (ctrl->value >= 0x10 && ctrl->value <= 0x3f) |
113 | ctrl->value -= 0x10; | 110 | ctrl->value -= 0x10; |
114 | else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f) | 111 | else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f) |
@@ -124,6 +121,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam, | |||
124 | static int mi0343_set_ctrl(struct sn9c102_device* cam, | 121 | static int mi0343_set_ctrl(struct sn9c102_device* cam, |
125 | const struct v4l2_control* ctrl) | 122 | const struct v4l2_control* ctrl) |
126 | { | 123 | { |
124 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
127 | u16 reg = 0; | 125 | u16 reg = 0; |
128 | int err = 0; | 126 | int err = 0; |
129 | 127 | ||
@@ -143,50 +141,42 @@ static int mi0343_set_ctrl(struct sn9c102_device* cam, | |||
143 | 141 | ||
144 | switch (ctrl->id) { | 142 | switch (ctrl->id) { |
145 | case V4L2_CID_EXPOSURE: | 143 | case V4L2_CID_EXPOSURE: |
146 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 144 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
147 | mi0343.i2c_slave_id, | ||
148 | 0x09, ctrl->value, 0x00, | 145 | 0x09, ctrl->value, 0x00, |
149 | 0, 0); | 146 | 0, 0); |
150 | break; | 147 | break; |
151 | case V4L2_CID_GAIN: | 148 | case V4L2_CID_GAIN: |
152 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 149 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
153 | mi0343.i2c_slave_id, | ||
154 | 0x35, reg >> 8, reg & 0xff, | 150 | 0x35, reg >> 8, reg & 0xff, |
155 | 0, 0); | 151 | 0, 0); |
156 | break; | 152 | break; |
157 | case V4L2_CID_HFLIP: | 153 | case V4L2_CID_HFLIP: |
158 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 154 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
159 | mi0343.i2c_slave_id, | ||
160 | 0x20, ctrl->value ? 0x40:0x00, | 155 | 0x20, ctrl->value ? 0x40:0x00, |
161 | ctrl->value ? 0x20:0x00, | 156 | ctrl->value ? 0x20:0x00, |
162 | 0, 0); | 157 | 0, 0); |
163 | break; | 158 | break; |
164 | case V4L2_CID_VFLIP: | 159 | case V4L2_CID_VFLIP: |
165 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 160 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
166 | mi0343.i2c_slave_id, | ||
167 | 0x20, ctrl->value ? 0x80:0x00, | 161 | 0x20, ctrl->value ? 0x80:0x00, |
168 | ctrl->value ? 0x80:0x00, | 162 | ctrl->value ? 0x80:0x00, |
169 | 0, 0); | 163 | 0, 0); |
170 | break; | 164 | break; |
171 | case V4L2_CID_RED_BALANCE: | 165 | case V4L2_CID_RED_BALANCE: |
172 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 166 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
173 | mi0343.i2c_slave_id, | ||
174 | 0x2d, reg >> 8, reg & 0xff, | 167 | 0x2d, reg >> 8, reg & 0xff, |
175 | 0, 0); | 168 | 0, 0); |
176 | break; | 169 | break; |
177 | case V4L2_CID_BLUE_BALANCE: | 170 | case V4L2_CID_BLUE_BALANCE: |
178 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 171 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
179 | mi0343.i2c_slave_id, | ||
180 | 0x2c, reg >> 8, reg & 0xff, | 172 | 0x2c, reg >> 8, reg & 0xff, |
181 | 0, 0); | 173 | 0, 0); |
182 | break; | 174 | break; |
183 | case SN9C102_V4L2_CID_GREEN_BALANCE: | 175 | case SN9C102_V4L2_CID_GREEN_BALANCE: |
184 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 176 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
185 | mi0343.i2c_slave_id, | ||
186 | 0x2b, reg >> 8, reg & 0xff, | 177 | 0x2b, reg >> 8, reg & 0xff, |
187 | 0, 0); | 178 | 0, 0); |
188 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 179 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
189 | mi0343.i2c_slave_id, | ||
190 | 0x2e, reg >> 8, reg & 0xff, | 180 | 0x2e, reg >> 8, reg & 0xff, |
191 | 0, 0); | 181 | 0, 0); |
192 | break; | 182 | break; |
@@ -216,16 +206,15 @@ static int mi0343_set_crop(struct sn9c102_device* cam, | |||
216 | static int mi0343_set_pix_format(struct sn9c102_device* cam, | 206 | static int mi0343_set_pix_format(struct sn9c102_device* cam, |
217 | const struct v4l2_pix_format* pix) | 207 | const struct v4l2_pix_format* pix) |
218 | { | 208 | { |
209 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
219 | int err = 0; | 210 | int err = 0; |
220 | 211 | ||
221 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) { | 212 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) { |
222 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 213 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
223 | mi0343.i2c_slave_id, | ||
224 | 0x0a, 0x00, 0x03, 0, 0); | 214 | 0x0a, 0x00, 0x03, 0, 0); |
225 | err += sn9c102_write_reg(cam, 0x20, 0x19); | 215 | err += sn9c102_write_reg(cam, 0x20, 0x19); |
226 | } else { | 216 | } else { |
227 | err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, | 217 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, |
228 | mi0343.i2c_slave_id, | ||
229 | 0x0a, 0x00, 0x05, 0, 0); | 218 | 0x0a, 0x00, 0x05, 0, 0); |
230 | err += sn9c102_write_reg(cam, 0xa0, 0x19); | 219 | err += sn9c102_write_reg(cam, 0xa0, 0x19); |
231 | } | 220 | } |
@@ -237,7 +226,7 @@ static int mi0343_set_pix_format(struct sn9c102_device* cam, | |||
237 | static struct sn9c102_sensor mi0343 = { | 226 | static struct sn9c102_sensor mi0343 = { |
238 | .name = "MI-0343", | 227 | .name = "MI-0343", |
239 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | 228 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", |
240 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, | 229 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, |
241 | .frequency = SN9C102_I2C_100KHZ, | 230 | .frequency = SN9C102_I2C_100KHZ, |
242 | .interface = SN9C102_I2C_2WIRES, | 231 | .interface = SN9C102_I2C_2WIRES, |
243 | .i2c_slave_id = 0x5d, | 232 | .i2c_slave_id = 0x5d, |
@@ -343,19 +332,20 @@ static struct sn9c102_sensor mi0343 = { | |||
343 | 332 | ||
344 | int sn9c102_probe_mi0343(struct sn9c102_device* cam) | 333 | int sn9c102_probe_mi0343(struct sn9c102_device* cam) |
345 | { | 334 | { |
335 | u8 data[5+1]; | ||
346 | int err = 0; | 336 | int err = 0; |
347 | 337 | ||
348 | err += sn9c102_write_reg(cam, 0x01, 0x01); | 338 | err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01}, |
349 | err += sn9c102_write_reg(cam, 0x00, 0x01); | 339 | {0x28, 0x17}); |
350 | err += sn9c102_write_reg(cam, 0x28, 0x17); | 340 | |
351 | if (err) | 341 | if (err) |
352 | return -EIO; | 342 | return -EIO; |
353 | 343 | ||
354 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00, | 344 | if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00, |
355 | 2, mi0343_i2c_data) < 0) | 345 | 2, data) < 0) |
356 | return -EIO; | 346 | return -EIO; |
357 | 347 | ||
358 | if (mi0343_i2c_data[4] != 0x32 && mi0343_i2c_data[3] != 0xe3) | 348 | if (data[4] != 0x32 || data[3] != 0xe3) |
359 | return -ENODEV; | 349 | return -ENODEV; |
360 | 350 | ||
361 | sn9c102_attach_sensor(cam, &mi0343); | 351 | 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..64698acb0b15 --- /dev/null +++ b/drivers/media/video/sn9c102/sn9c102_mi0360.c | |||
@@ -0,0 +1,338 @@ | |||
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_const_regs(cam, {0x00, 0x10}, {0x00, 0x11}, | ||
31 | {0x0a, 0x14}, {0x40, 0x01}, | ||
32 | {0x20, 0x17}, {0x07, 0x18}, | ||
33 | {0xa0, 0x19}, {0x02, 0x1c}, | ||
34 | {0x03, 0x1d}, {0x0f, 0x1e}, | ||
35 | {0x0c, 0x1f}, {0x00, 0x20}, | ||
36 | {0x10, 0x21}, {0x20, 0x22}, | ||
37 | {0x30, 0x23}, {0x40, 0x24}, | ||
38 | {0x50, 0x25}, {0x60, 0x26}, | ||
39 | {0x70, 0x27}, {0x80, 0x28}, | ||
40 | {0x90, 0x29}, {0xa0, 0x2a}, | ||
41 | {0xb0, 0x2b}, {0xc0, 0x2c}, | ||
42 | {0xd0, 0x2d}, {0xe0, 0x2e}, | ||
43 | {0xf0, 0x2f}, {0xff, 0x30}); | ||
44 | |||
45 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d, | ||
46 | 0x00, 0x01, 0, 0); | ||
47 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d, | ||
48 | 0x00, 0x00, 0, 0); | ||
49 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03, | ||
50 | 0x01, 0xe1, 0, 0); | ||
51 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04, | ||
52 | 0x02, 0x81, 0, 0); | ||
53 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05, | ||
54 | 0x00, 0x17, 0, 0); | ||
55 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06, | ||
56 | 0x00, 0x11, 0, 0); | ||
57 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62, | ||
58 | 0x04, 0x9a, 0, 0); | ||
59 | |||
60 | return err; | ||
61 | } | ||
62 | |||
63 | |||
64 | static int mi0360_get_ctrl(struct sn9c102_device* cam, | ||
65 | struct v4l2_control* ctrl) | ||
66 | { | ||
67 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
68 | u8 data[5+1]; | ||
69 | |||
70 | switch (ctrl->id) { | ||
71 | case V4L2_CID_EXPOSURE: | ||
72 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, | ||
73 | 2+1, data) < 0) | ||
74 | return -EIO; | ||
75 | ctrl->value = data[2]; | ||
76 | return 0; | ||
77 | case V4L2_CID_GAIN: | ||
78 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, | ||
79 | 2+1, data) < 0) | ||
80 | return -EIO; | ||
81 | ctrl->value = data[3]; | ||
82 | return 0; | ||
83 | case V4L2_CID_RED_BALANCE: | ||
84 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, | ||
85 | 2+1, data) < 0) | ||
86 | return -EIO; | ||
87 | ctrl->value = data[3]; | ||
88 | return 0; | ||
89 | case V4L2_CID_BLUE_BALANCE: | ||
90 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, | ||
91 | 2+1, data) < 0) | ||
92 | return -EIO; | ||
93 | ctrl->value = data[3]; | ||
94 | return 0; | ||
95 | case SN9C102_V4L2_CID_GREEN_BALANCE: | ||
96 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, | ||
97 | 2+1, data) < 0) | ||
98 | return -EIO; | ||
99 | ctrl->value = data[3]; | ||
100 | return 0; | ||
101 | case V4L2_CID_HFLIP: | ||
102 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, | ||
103 | 2+1, data) < 0) | ||
104 | return -EIO; | ||
105 | ctrl->value = data[3] & 0x20 ? 1 : 0; | ||
106 | return 0; | ||
107 | case V4L2_CID_VFLIP: | ||
108 | if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, | ||
109 | 2+1, data) < 0) | ||
110 | return -EIO; | ||
111 | ctrl->value = data[3] & 0x80 ? 1 : 0; | ||
112 | return 0; | ||
113 | default: | ||
114 | return -EINVAL; | ||
115 | } | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | |||
121 | static int mi0360_set_ctrl(struct sn9c102_device* cam, | ||
122 | const struct v4l2_control* ctrl) | ||
123 | { | ||
124 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
125 | int err = 0; | ||
126 | |||
127 | switch (ctrl->id) { | ||
128 | case V4L2_CID_EXPOSURE: | ||
129 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
130 | 0x09, ctrl->value, 0x00, | ||
131 | 0, 0); | ||
132 | break; | ||
133 | case V4L2_CID_GAIN: | ||
134 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
135 | 0x35, 0x03, ctrl->value, | ||
136 | 0, 0); | ||
137 | break; | ||
138 | case V4L2_CID_RED_BALANCE: | ||
139 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
140 | 0x2c, 0x03, ctrl->value, | ||
141 | 0, 0); | ||
142 | break; | ||
143 | case V4L2_CID_BLUE_BALANCE: | ||
144 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
145 | 0x2d, 0x03, ctrl->value, | ||
146 | 0, 0); | ||
147 | break; | ||
148 | case SN9C102_V4L2_CID_GREEN_BALANCE: | ||
149 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
150 | 0x2b, 0x03, ctrl->value, | ||
151 | 0, 0); | ||
152 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
153 | 0x2e, 0x03, ctrl->value, | ||
154 | 0, 0); | ||
155 | break; | ||
156 | case V4L2_CID_HFLIP: | ||
157 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
158 | 0x20, ctrl->value ? 0x40:0x00, | ||
159 | ctrl->value ? 0x20:0x00, | ||
160 | 0, 0); | ||
161 | break; | ||
162 | case V4L2_CID_VFLIP: | ||
163 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
164 | 0x20, ctrl->value ? 0x80:0x00, | ||
165 | ctrl->value ? 0x80:0x00, | ||
166 | 0, 0); | ||
167 | break; | ||
168 | default: | ||
169 | return -EINVAL; | ||
170 | } | ||
171 | |||
172 | return err ? -EIO : 0; | ||
173 | } | ||
174 | |||
175 | |||
176 | static int mi0360_set_crop(struct sn9c102_device* cam, | ||
177 | const struct v4l2_rect* rect) | ||
178 | { | ||
179 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
180 | int err = 0; | ||
181 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0, | ||
182 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; | ||
183 | |||
184 | err += sn9c102_write_reg(cam, h_start, 0x12); | ||
185 | err += sn9c102_write_reg(cam, v_start, 0x13); | ||
186 | |||
187 | return err; | ||
188 | } | ||
189 | |||
190 | |||
191 | static int mi0360_set_pix_format(struct sn9c102_device* cam, | ||
192 | const struct v4l2_pix_format* pix) | ||
193 | { | ||
194 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
195 | int err = 0; | ||
196 | |||
197 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) { | ||
198 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
199 | 0x0a, 0x00, 0x02, 0, 0); | ||
200 | err += sn9c102_write_reg(cam, 0x20, 0x19); | ||
201 | } else { | ||
202 | err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, | ||
203 | 0x0a, 0x00, 0x05, 0, 0); | ||
204 | err += sn9c102_write_reg(cam, 0x60, 0x19); | ||
205 | } | ||
206 | |||
207 | return err; | ||
208 | } | ||
209 | |||
210 | |||
211 | static struct sn9c102_sensor mi0360 = { | ||
212 | .name = "MI-0360", | ||
213 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | ||
214 | .supported_bridge = BRIDGE_SN9C103, | ||
215 | .frequency = SN9C102_I2C_100KHZ, | ||
216 | .interface = SN9C102_I2C_2WIRES, | ||
217 | .i2c_slave_id = 0x5d, | ||
218 | .init = &mi0360_init, | ||
219 | .qctrl = { | ||
220 | { | ||
221 | .id = V4L2_CID_EXPOSURE, | ||
222 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
223 | .name = "exposure", | ||
224 | .minimum = 0x00, | ||
225 | .maximum = 0x0f, | ||
226 | .step = 0x01, | ||
227 | .default_value = 0x05, | ||
228 | .flags = 0, | ||
229 | }, | ||
230 | { | ||
231 | .id = V4L2_CID_GAIN, | ||
232 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
233 | .name = "global gain", | ||
234 | .minimum = 0x00, | ||
235 | .maximum = 0x7f, | ||
236 | .step = 0x01, | ||
237 | .default_value = 0x25, | ||
238 | .flags = 0, | ||
239 | }, | ||
240 | { | ||
241 | .id = V4L2_CID_HFLIP, | ||
242 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
243 | .name = "horizontal mirror", | ||
244 | .minimum = 0, | ||
245 | .maximum = 1, | ||
246 | .step = 1, | ||
247 | .default_value = 0, | ||
248 | .flags = 0, | ||
249 | }, | ||
250 | { | ||
251 | .id = V4L2_CID_VFLIP, | ||
252 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
253 | .name = "vertical mirror", | ||
254 | .minimum = 0, | ||
255 | .maximum = 1, | ||
256 | .step = 1, | ||
257 | .default_value = 0, | ||
258 | .flags = 0, | ||
259 | }, | ||
260 | { | ||
261 | .id = V4L2_CID_BLUE_BALANCE, | ||
262 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
263 | .name = "blue balance", | ||
264 | .minimum = 0x00, | ||
265 | .maximum = 0x7f, | ||
266 | .step = 0x01, | ||
267 | .default_value = 0x0f, | ||
268 | .flags = 0, | ||
269 | }, | ||
270 | { | ||
271 | .id = V4L2_CID_RED_BALANCE, | ||
272 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
273 | .name = "red balance", | ||
274 | .minimum = 0x00, | ||
275 | .maximum = 0x7f, | ||
276 | .step = 0x01, | ||
277 | .default_value = 0x32, | ||
278 | .flags = 0, | ||
279 | }, | ||
280 | { | ||
281 | .id = SN9C102_V4L2_CID_GREEN_BALANCE, | ||
282 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
283 | .name = "green balance", | ||
284 | .minimum = 0x00, | ||
285 | .maximum = 0x7f, | ||
286 | .step = 0x01, | ||
287 | .default_value = 0x25, | ||
288 | .flags = 0, | ||
289 | }, | ||
290 | }, | ||
291 | .get_ctrl = &mi0360_get_ctrl, | ||
292 | .set_ctrl = &mi0360_set_ctrl, | ||
293 | .cropcap = { | ||
294 | .bounds = { | ||
295 | .left = 0, | ||
296 | .top = 0, | ||
297 | .width = 640, | ||
298 | .height = 480, | ||
299 | }, | ||
300 | .defrect = { | ||
301 | .left = 0, | ||
302 | .top = 0, | ||
303 | .width = 640, | ||
304 | .height = 480, | ||
305 | }, | ||
306 | }, | ||
307 | .set_crop = &mi0360_set_crop, | ||
308 | .pix_format = { | ||
309 | .width = 640, | ||
310 | .height = 480, | ||
311 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | ||
312 | .priv = 8, | ||
313 | }, | ||
314 | .set_pix_format = &mi0360_set_pix_format | ||
315 | }; | ||
316 | |||
317 | |||
318 | int sn9c102_probe_mi0360(struct sn9c102_device* cam) | ||
319 | { | ||
320 | u8 data[5+1]; | ||
321 | int err; | ||
322 | |||
323 | err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01}, | ||
324 | {0x28, 0x17}); | ||
325 | if (err) | ||
326 | return -EIO; | ||
327 | |||
328 | if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00, | ||
329 | 2+1, data) < 0) | ||
330 | return -EIO; | ||
331 | |||
332 | if (data[2] != 0x82 || data[3] != 0x43) | ||
333 | return -ENODEV; | ||
334 | |||
335 | sn9c102_attach_sensor(cam, &mi0360); | ||
336 | |||
337 | return 0; | ||
338 | } | ||
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7630.c b/drivers/media/video/sn9c102/sn9c102_ov7630.c index 7df09ff38e63..31b6080b0615 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,20 @@ 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_const_regs(cam, {0x00, 0x14}, |
36 | err += sn9c102_write_reg(cam, 0x60, 0x17); | 33 | {0x60, 0x17}, {0x0f, 0x18}, |
37 | err += sn9c102_write_reg(cam, 0x0f, 0x18); | 34 | {0x50, 0x19}); |
38 | err += sn9c102_write_reg(cam, 0x50, 0x19); | ||
39 | 35 | ||
40 | err += sn9c102_i2c_write(cam, 0x12, 0x8d); | 36 | err += sn9c102_i2c_write(cam, 0x12, 0x8d); |
41 | err += sn9c102_i2c_write(cam, 0x12, 0x0d); | 37 | err += sn9c102_i2c_write(cam, 0x12, 0x0d); |
42 | err += sn9c102_i2c_write(cam, 0x11, 0x00); | 38 | err += sn9c102_i2c_write(cam, 0x11, 0x00); |
43 | err += sn9c102_i2c_write(cam, 0x15, 0x34); | 39 | err += sn9c102_i2c_write(cam, 0x15, 0x35); |
44 | err += sn9c102_i2c_write(cam, 0x16, 0x03); | 40 | err += sn9c102_i2c_write(cam, 0x16, 0x03); |
45 | err += sn9c102_i2c_write(cam, 0x17, 0x1c); | 41 | err += sn9c102_i2c_write(cam, 0x17, 0x1c); |
46 | err += sn9c102_i2c_write(cam, 0x18, 0xbd); | 42 | err += sn9c102_i2c_write(cam, 0x18, 0xbd); |
47 | err += sn9c102_i2c_write(cam, 0x19, 0x06); | 43 | err += sn9c102_i2c_write(cam, 0x19, 0x06); |
48 | err += sn9c102_i2c_write(cam, 0x1a, 0xf6); | 44 | err += sn9c102_i2c_write(cam, 0x1a, 0xf6); |
49 | err += sn9c102_i2c_write(cam, 0x1b, 0x04); | 45 | err += sn9c102_i2c_write(cam, 0x1b, 0x04); |
50 | err += sn9c102_i2c_write(cam, 0x20, 0x44); | 46 | err += sn9c102_i2c_write(cam, 0x20, 0x44); |
51 | err += sn9c102_i2c_write(cam, 0x23, 0xee); | 47 | err += sn9c102_i2c_write(cam, 0x23, 0xee); |
52 | err += sn9c102_i2c_write(cam, 0x26, 0xa0); | 48 | err += sn9c102_i2c_write(cam, 0x26, 0xa0); |
@@ -65,42 +61,26 @@ static int ov7630_init(struct sn9c102_device* cam) | |||
65 | err += sn9c102_i2c_write(cam, 0x71, 0x00); | 61 | err += sn9c102_i2c_write(cam, 0x71, 0x00); |
66 | err += sn9c102_i2c_write(cam, 0x74, 0x21); | 62 | err += sn9c102_i2c_write(cam, 0x74, 0x21); |
67 | err += sn9c102_i2c_write(cam, 0x7d, 0xf7); | 63 | err += sn9c102_i2c_write(cam, 0x7d, 0xf7); |
64 | |||
68 | break; | 65 | break; |
69 | case BRIDGE_SN9C103: | 66 | case BRIDGE_SN9C103: |
70 | err += sn9c102_write_reg(cam, 0x00, 0x02); | 67 | err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03}, |
71 | err += sn9c102_write_reg(cam, 0x00, 0x03); | 68 | {0x1a, 0x04}, {0x20, 0x05}, |
72 | err += sn9c102_write_reg(cam, 0x1a, 0x04); | 69 | {0x20, 0x06}, {0x20, 0x07}, |
73 | err += sn9c102_write_reg(cam, 0x20, 0x05); | 70 | {0x03, 0x10}, {0x0a, 0x14}, |
74 | err += sn9c102_write_reg(cam, 0x20, 0x06); | 71 | {0x60, 0x17}, {0x0f, 0x18}, |
75 | err += sn9c102_write_reg(cam, 0x20, 0x07); | 72 | {0x50, 0x19}, {0x1d, 0x1a}, |
76 | err += sn9c102_write_reg(cam, 0x03, 0x10); | 73 | {0x10, 0x1b}, {0x02, 0x1c}, |
77 | err += sn9c102_write_reg(cam, 0x0a, 0x14); | 74 | {0x03, 0x1d}, {0x0f, 0x1e}, |
78 | err += sn9c102_write_reg(cam, 0x60, 0x17); | 75 | {0x0c, 0x1f}, {0x00, 0x20}, |
79 | err += sn9c102_write_reg(cam, 0x0f, 0x18); | 76 | {0x10, 0x21}, {0x20, 0x22}, |
80 | err += sn9c102_write_reg(cam, 0x50, 0x19); | 77 | {0x30, 0x23}, {0x40, 0x24}, |
81 | err += sn9c102_write_reg(cam, 0x1d, 0x1a); | 78 | {0x50, 0x25}, {0x60, 0x26}, |
82 | err += sn9c102_write_reg(cam, 0x10, 0x1b); | 79 | {0x70, 0x27}, {0x80, 0x28}, |
83 | err += sn9c102_write_reg(cam, 0x02, 0x1c); | 80 | {0x90, 0x29}, {0xa0, 0x2a}, |
84 | err += sn9c102_write_reg(cam, 0x03, 0x1d); | 81 | {0xb0, 0x2b}, {0xc0, 0x2c}, |
85 | err += sn9c102_write_reg(cam, 0x0f, 0x1e); | 82 | {0xd0, 0x2d}, {0xe0, 0x2e}, |
86 | err += sn9c102_write_reg(cam, 0x0c, 0x1f); | 83 | {0xf0, 0x2f}, {0xff, 0x30}); |
87 | err += sn9c102_write_reg(cam, 0x00, 0x20); | ||
88 | err += sn9c102_write_reg(cam, 0x10, 0x21); | ||
89 | err += sn9c102_write_reg(cam, 0x20, 0x22); | ||
90 | err += sn9c102_write_reg(cam, 0x30, 0x23); | ||
91 | err += sn9c102_write_reg(cam, 0x40, 0x24); | ||
92 | err += sn9c102_write_reg(cam, 0x50, 0x25); | ||
93 | err += sn9c102_write_reg(cam, 0x60, 0x26); | ||
94 | err += sn9c102_write_reg(cam, 0x70, 0x27); | ||
95 | err += sn9c102_write_reg(cam, 0x80, 0x28); | ||
96 | err += sn9c102_write_reg(cam, 0x90, 0x29); | ||
97 | err += sn9c102_write_reg(cam, 0xa0, 0x2a); | ||
98 | err += sn9c102_write_reg(cam, 0xb0, 0x2b); | ||
99 | err += sn9c102_write_reg(cam, 0xc0, 0x2c); | ||
100 | err += sn9c102_write_reg(cam, 0xd0, 0x2d); | ||
101 | err += sn9c102_write_reg(cam, 0xe0, 0x2e); | ||
102 | err += sn9c102_write_reg(cam, 0xf0, 0x2f); | ||
103 | err += sn9c102_write_reg(cam, 0xff, 0x30); | ||
104 | 84 | ||
105 | err += sn9c102_i2c_write(cam, 0x12, 0x8d); | 85 | err += sn9c102_i2c_write(cam, 0x12, 0x8d); |
106 | err += sn9c102_i2c_write(cam, 0x12, 0x0d); | 86 | err += sn9c102_i2c_write(cam, 0x12, 0x0d); |
@@ -108,23 +88,23 @@ static int ov7630_init(struct sn9c102_device* cam) | |||
108 | err += sn9c102_i2c_write(cam, 0x11, 0x01); | 88 | err += sn9c102_i2c_write(cam, 0x11, 0x01); |
109 | err += sn9c102_i2c_write(cam, 0x1b, 0x04); | 89 | err += sn9c102_i2c_write(cam, 0x1b, 0x04); |
110 | err += sn9c102_i2c_write(cam, 0x20, 0x44); | 90 | err += sn9c102_i2c_write(cam, 0x20, 0x44); |
111 | err += sn9c102_i2c_write(cam, 0x23, 0xee); | 91 | err += sn9c102_i2c_write(cam, 0x23, 0xee); |
112 | err += sn9c102_i2c_write(cam, 0x26, 0xa0); | 92 | err += sn9c102_i2c_write(cam, 0x26, 0xa0); |
113 | err += sn9c102_i2c_write(cam, 0x27, 0x9a); | 93 | err += sn9c102_i2c_write(cam, 0x27, 0x9a); |
114 | err += sn9c102_i2c_write(cam, 0x28, 0x20); | 94 | err += sn9c102_i2c_write(cam, 0x28, 0x20); |
115 | err += sn9c102_i2c_write(cam, 0x29, 0x30); | 95 | err += sn9c102_i2c_write(cam, 0x29, 0x30); |
116 | err += sn9c102_i2c_write(cam, 0x2f, 0x3d); | 96 | err += sn9c102_i2c_write(cam, 0x2f, 0x3d); |
117 | err += sn9c102_i2c_write(cam, 0x30, 0x24); | 97 | err += sn9c102_i2c_write(cam, 0x30, 0x24); |
118 | err += sn9c102_i2c_write(cam, 0x32, 0x86); | 98 | err += sn9c102_i2c_write(cam, 0x32, 0x86); |
119 | err += sn9c102_i2c_write(cam, 0x60, 0xa9); | 99 | err += sn9c102_i2c_write(cam, 0x60, 0xa9); |
120 | err += sn9c102_i2c_write(cam, 0x61, 0x42); | 100 | err += sn9c102_i2c_write(cam, 0x61, 0x42); |
121 | err += sn9c102_i2c_write(cam, 0x65, 0x00); | 101 | err += sn9c102_i2c_write(cam, 0x65, 0x00); |
122 | err += sn9c102_i2c_write(cam, 0x69, 0x38); | 102 | err += sn9c102_i2c_write(cam, 0x69, 0x38); |
123 | err += sn9c102_i2c_write(cam, 0x6f, 0x88); | 103 | err += sn9c102_i2c_write(cam, 0x6f, 0x88); |
124 | err += sn9c102_i2c_write(cam, 0x70, 0x0b); | 104 | err += sn9c102_i2c_write(cam, 0x70, 0x0b); |
125 | err += sn9c102_i2c_write(cam, 0x71, 0x00); | 105 | err += sn9c102_i2c_write(cam, 0x71, 0x00); |
126 | err += sn9c102_i2c_write(cam, 0x74, 0x21); | 106 | err += sn9c102_i2c_write(cam, 0x74, 0x21); |
127 | err += sn9c102_i2c_write(cam, 0x7d, 0xf7); | 107 | err += sn9c102_i2c_write(cam, 0x7d, 0xf7); |
128 | break; | 108 | break; |
129 | default: | 109 | default: |
130 | break; | 110 | break; |
@@ -428,15 +408,14 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam) | |||
428 | switch (sn9c102_get_bridge(cam)) { | 408 | switch (sn9c102_get_bridge(cam)) { |
429 | case BRIDGE_SN9C101: | 409 | case BRIDGE_SN9C101: |
430 | case BRIDGE_SN9C102: | 410 | case BRIDGE_SN9C102: |
431 | err += sn9c102_write_reg(cam, 0x01, 0x01); | 411 | err = sn9c102_write_const_regs(cam, {0x01, 0x01}, |
432 | err += sn9c102_write_reg(cam, 0x00, 0x01); | 412 | {0x00, 0x01}, {0x28, 0x17}); |
433 | err += sn9c102_write_reg(cam, 0x28, 0x17); | 413 | |
434 | break; | 414 | break; |
435 | case BRIDGE_SN9C103: /* do _not_ change anything! */ | 415 | case BRIDGE_SN9C103: /* do _not_ change anything! */ |
436 | err += sn9c102_write_reg(cam, 0x09, 0x01); | 416 | err = sn9c102_write_const_regs(cam, {0x09, 0x01}, |
437 | err += sn9c102_write_reg(cam, 0x42, 0x01); | 417 | {0x42, 0x01}, {0x28, 0x17}, |
438 | err += sn9c102_write_reg(cam, 0x28, 0x17); | 418 | {0x44, 0x02}); |
439 | err += sn9c102_write_reg(cam, 0x44, 0x02); | ||
440 | pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a); | 419 | pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a); |
441 | if (err || pid < 0) { /* try a different initialization */ | 420 | if (err || pid < 0) { /* try a different initialization */ |
442 | err = sn9c102_write_reg(cam, 0x01, 0x01); | 421 | err = sn9c102_write_reg(cam, 0x01, 0x01); |
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7660.c b/drivers/media/video/sn9c102/sn9c102_ov7660.c index d670c24d4435..c898e948fe8d 100644 --- a/drivers/media/video/sn9c102/sn9c102_ov7660.c +++ b/drivers/media/video/sn9c102/sn9c102_ov7660.c | |||
@@ -22,160 +22,84 @@ | |||
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; |
31 | 28 | ||
32 | err += sn9c102_write_reg(cam, 0x40, 0x02); | 29 | err = sn9c102_write_const_regs(cam, {0x40, 0x02}, {0x00, 0x03}, |
33 | err += sn9c102_write_reg(cam, 0x00, 0x03); | 30 | {0x1a, 0x04}, {0x03, 0x10}, |
34 | err += sn9c102_write_reg(cam, 0x1a, 0x04); | 31 | {0x08, 0x14}, {0x20, 0x17}, |
35 | err += sn9c102_write_reg(cam, 0x03, 0x10); | 32 | {0x8b, 0x18}, {0x00, 0x19}, |
36 | err += sn9c102_write_reg(cam, 0x08, 0x14); | 33 | {0x1d, 0x1a}, {0x10, 0x1b}, |
37 | err += sn9c102_write_reg(cam, 0x20, 0x17); | 34 | {0x02, 0x1c}, {0x03, 0x1d}, |
38 | err += sn9c102_write_reg(cam, 0x8b, 0x18); | 35 | {0x0f, 0x1e}, {0x0c, 0x1f}, |
39 | err += sn9c102_write_reg(cam, 0x00, 0x19); | 36 | {0x00, 0x20}, {0x29, 0x21}, |
40 | err += sn9c102_write_reg(cam, 0x1d, 0x1a); | 37 | {0x40, 0x22}, {0x54, 0x23}, |
41 | err += sn9c102_write_reg(cam, 0x10, 0x1b); | 38 | {0x66, 0x24}, {0x76, 0x25}, |
42 | err += sn9c102_write_reg(cam, 0x02, 0x1c); | 39 | {0x85, 0x26}, {0x94, 0x27}, |
43 | err += sn9c102_write_reg(cam, 0x03, 0x1d); | 40 | {0xa1, 0x28}, {0xae, 0x29}, |
44 | err += sn9c102_write_reg(cam, 0x0f, 0x1e); | 41 | {0xbb, 0x2a}, {0xc7, 0x2b}, |
45 | err += sn9c102_write_reg(cam, 0x0c, 0x1f); | 42 | {0xd3, 0x2c}, {0xde, 0x2d}, |
46 | err += sn9c102_write_reg(cam, 0x00, 0x20); | 43 | {0xea, 0x2e}, {0xf4, 0x2f}, |
47 | err += sn9c102_write_reg(cam, 0x29, 0x21); | 44 | {0xff, 0x30}, {0x00, 0x3F}, |
48 | err += sn9c102_write_reg(cam, 0x40, 0x22); | 45 | {0xC7, 0x40}, {0x01, 0x41}, |
49 | err += sn9c102_write_reg(cam, 0x54, 0x23); | 46 | {0x44, 0x42}, {0x00, 0x43}, |
50 | err += sn9c102_write_reg(cam, 0x66, 0x24); | 47 | {0x44, 0x44}, {0x00, 0x45}, |
51 | err += sn9c102_write_reg(cam, 0x76, 0x25); | 48 | {0x44, 0x46}, {0x00, 0x47}, |
52 | err += sn9c102_write_reg(cam, 0x85, 0x26); | 49 | {0xC7, 0x48}, {0x01, 0x49}, |
53 | err += sn9c102_write_reg(cam, 0x94, 0x27); | 50 | {0xC7, 0x4A}, {0x01, 0x4B}, |
54 | err += sn9c102_write_reg(cam, 0xa1, 0x28); | 51 | {0xC7, 0x4C}, {0x01, 0x4D}, |
55 | err += sn9c102_write_reg(cam, 0xae, 0x29); | 52 | {0x44, 0x4E}, {0x00, 0x4F}, |
56 | err += sn9c102_write_reg(cam, 0xbb, 0x2a); | 53 | {0x44, 0x50}, {0x00, 0x51}, |
57 | err += sn9c102_write_reg(cam, 0xc7, 0x2b); | 54 | {0x44, 0x52}, {0x00, 0x53}, |
58 | err += sn9c102_write_reg(cam, 0xd3, 0x2c); | 55 | {0xC7, 0x54}, {0x01, 0x55}, |
59 | err += sn9c102_write_reg(cam, 0xde, 0x2d); | 56 | {0xC7, 0x56}, {0x01, 0x57}, |
60 | err += sn9c102_write_reg(cam, 0xea, 0x2e); | 57 | {0xC7, 0x58}, {0x01, 0x59}, |
61 | err += sn9c102_write_reg(cam, 0xf4, 0x2f); | 58 | {0x44, 0x5A}, {0x00, 0x5B}, |
62 | err += sn9c102_write_reg(cam, 0xff, 0x30); | 59 | {0x44, 0x5C}, {0x00, 0x5D}, |
63 | err += sn9c102_write_reg(cam, 0x00, 0x3F); | 60 | {0x44, 0x5E}, {0x00, 0x5F}, |
64 | err += sn9c102_write_reg(cam, 0xC7, 0x40); | 61 | {0xC7, 0x60}, {0x01, 0x61}, |
65 | err += sn9c102_write_reg(cam, 0x01, 0x41); | 62 | {0xC7, 0x62}, {0x01, 0x63}, |
66 | err += sn9c102_write_reg(cam, 0x44, 0x42); | 63 | {0xC7, 0x64}, {0x01, 0x65}, |
67 | err += sn9c102_write_reg(cam, 0x00, 0x43); | 64 | {0x44, 0x66}, {0x00, 0x67}, |
68 | err += sn9c102_write_reg(cam, 0x44, 0x44); | 65 | {0x44, 0x68}, {0x00, 0x69}, |
69 | err += sn9c102_write_reg(cam, 0x00, 0x45); | 66 | {0x44, 0x6A}, {0x00, 0x6B}, |
70 | err += sn9c102_write_reg(cam, 0x44, 0x46); | 67 | {0xC7, 0x6C}, {0x01, 0x6D}, |
71 | err += sn9c102_write_reg(cam, 0x00, 0x47); | 68 | {0xC7, 0x6E}, {0x01, 0x6F}, |
72 | err += sn9c102_write_reg(cam, 0xC7, 0x48); | 69 | {0xC7, 0x70}, {0x01, 0x71}, |
73 | err += sn9c102_write_reg(cam, 0x01, 0x49); | 70 | {0x44, 0x72}, {0x00, 0x73}, |
74 | err += sn9c102_write_reg(cam, 0xC7, 0x4A); | 71 | {0x44, 0x74}, {0x00, 0x75}, |
75 | err += sn9c102_write_reg(cam, 0x01, 0x4B); | 72 | {0x44, 0x76}, {0x00, 0x77}, |
76 | err += sn9c102_write_reg(cam, 0xC7, 0x4C); | 73 | {0xC7, 0x78}, {0x01, 0x79}, |
77 | err += sn9c102_write_reg(cam, 0x01, 0x4D); | 74 | {0xC7, 0x7A}, {0x01, 0x7B}, |
78 | err += sn9c102_write_reg(cam, 0x44, 0x4E); | 75 | {0xC7, 0x7C}, {0x01, 0x7D}, |
79 | err += sn9c102_write_reg(cam, 0x00, 0x4F); | 76 | {0x44, 0x7E}, {0x00, 0x7F}, |
80 | err += sn9c102_write_reg(cam, 0x44, 0x50); | 77 | {0x14, 0x84}, {0x00, 0x85}, |
81 | err += sn9c102_write_reg(cam, 0x00, 0x51); | 78 | {0x27, 0x86}, {0x00, 0x87}, |
82 | err += sn9c102_write_reg(cam, 0x44, 0x52); | 79 | {0x07, 0x88}, {0x00, 0x89}, |
83 | err += sn9c102_write_reg(cam, 0x00, 0x53); | 80 | {0xEC, 0x8A}, {0x0f, 0x8B}, |
84 | err += sn9c102_write_reg(cam, 0xC7, 0x54); | 81 | {0xD8, 0x8C}, {0x0f, 0x8D}, |
85 | err += sn9c102_write_reg(cam, 0x01, 0x55); | 82 | {0x3D, 0x8E}, {0x00, 0x8F}, |
86 | err += sn9c102_write_reg(cam, 0xC7, 0x56); | 83 | {0x3D, 0x90}, {0x00, 0x91}, |
87 | err += sn9c102_write_reg(cam, 0x01, 0x57); | 84 | {0xCD, 0x92}, {0x0f, 0x93}, |
88 | err += sn9c102_write_reg(cam, 0xC7, 0x58); | 85 | {0xf7, 0x94}, {0x0f, 0x95}, |
89 | err += sn9c102_write_reg(cam, 0x01, 0x59); | 86 | {0x0C, 0x96}, {0x00, 0x97}, |
90 | err += sn9c102_write_reg(cam, 0x44, 0x5A); | 87 | {0x00, 0x98}, {0x66, 0x99}, |
91 | err += sn9c102_write_reg(cam, 0x00, 0x5B); | 88 | {0x05, 0x9A}, {0x00, 0x9B}, |
92 | err += sn9c102_write_reg(cam, 0x44, 0x5C); | 89 | {0x04, 0x9C}, {0x00, 0x9D}, |
93 | err += sn9c102_write_reg(cam, 0x00, 0x5D); | 90 | {0x08, 0x9E}, {0x00, 0x9F}, |
94 | err += sn9c102_write_reg(cam, 0x44, 0x5E); | 91 | {0x2D, 0xC0}, {0x2D, 0xC1}, |
95 | err += sn9c102_write_reg(cam, 0x00, 0x5F); | 92 | {0x3A, 0xC2}, {0x05, 0xC3}, |
96 | err += sn9c102_write_reg(cam, 0xC7, 0x60); | 93 | {0x04, 0xC4}, {0x3F, 0xC5}, |
97 | err += sn9c102_write_reg(cam, 0x01, 0x61); | 94 | {0x00, 0xC6}, {0x00, 0xC7}, |
98 | err += sn9c102_write_reg(cam, 0xC7, 0x62); | 95 | {0x50, 0xC8}, {0x3C, 0xC9}, |
99 | err += sn9c102_write_reg(cam, 0x01, 0x63); | 96 | {0x28, 0xCA}, {0xD8, 0xCB}, |
100 | err += sn9c102_write_reg(cam, 0xC7, 0x64); | 97 | {0x14, 0xCC}, {0xEC, 0xCD}, |
101 | err += sn9c102_write_reg(cam, 0x01, 0x65); | 98 | {0x32, 0xCE}, {0xDD, 0xCF}, |
102 | err += sn9c102_write_reg(cam, 0x44, 0x66); | 99 | {0x32, 0xD0}, {0xDD, 0xD1}, |
103 | err += sn9c102_write_reg(cam, 0x00, 0x67); | 100 | {0x6A, 0xD2}, {0x50, 0xD3}, |
104 | err += sn9c102_write_reg(cam, 0x44, 0x68); | 101 | {0x00, 0xD4}, {0x00, 0xD5}, |
105 | err += sn9c102_write_reg(cam, 0x00, 0x69); | 102 | {0x00, 0xD6}); |
106 | err += sn9c102_write_reg(cam, 0x44, 0x6A); | ||
107 | err += sn9c102_write_reg(cam, 0x00, 0x6B); | ||
108 | err += sn9c102_write_reg(cam, 0xC7, 0x6C); | ||
109 | err += sn9c102_write_reg(cam, 0x01, 0x6D); | ||
110 | err += sn9c102_write_reg(cam, 0xC7, 0x6E); | ||
111 | err += sn9c102_write_reg(cam, 0x01, 0x6F); | ||
112 | err += sn9c102_write_reg(cam, 0xC7, 0x70); | ||
113 | err += sn9c102_write_reg(cam, 0x01, 0x71); | ||
114 | err += sn9c102_write_reg(cam, 0x44, 0x72); | ||
115 | err += sn9c102_write_reg(cam, 0x00, 0x73); | ||
116 | err += sn9c102_write_reg(cam, 0x44, 0x74); | ||
117 | err += sn9c102_write_reg(cam, 0x00, 0x75); | ||
118 | err += sn9c102_write_reg(cam, 0x44, 0x76); | ||
119 | err += sn9c102_write_reg(cam, 0x00, 0x77); | ||
120 | err += sn9c102_write_reg(cam, 0xC7, 0x78); | ||
121 | err += sn9c102_write_reg(cam, 0x01, 0x79); | ||
122 | err += sn9c102_write_reg(cam, 0xC7, 0x7A); | ||
123 | err += sn9c102_write_reg(cam, 0x01, 0x7B); | ||
124 | err += sn9c102_write_reg(cam, 0xC7, 0x7C); | ||
125 | err += sn9c102_write_reg(cam, 0x01, 0x7D); | ||
126 | err += sn9c102_write_reg(cam, 0x44, 0x7E); | ||
127 | err += sn9c102_write_reg(cam, 0x00, 0x7F); | ||
128 | err += sn9c102_write_reg(cam, 0x14, 0x84); | ||
129 | err += sn9c102_write_reg(cam, 0x00, 0x85); | ||
130 | err += sn9c102_write_reg(cam, 0x27, 0x86); | ||
131 | err += sn9c102_write_reg(cam, 0x00, 0x87); | ||
132 | err += sn9c102_write_reg(cam, 0x07, 0x88); | ||
133 | err += sn9c102_write_reg(cam, 0x00, 0x89); | ||
134 | err += sn9c102_write_reg(cam, 0xEC, 0x8A); | ||
135 | err += sn9c102_write_reg(cam, 0x0f, 0x8B); | ||
136 | err += sn9c102_write_reg(cam, 0xD8, 0x8C); | ||
137 | err += sn9c102_write_reg(cam, 0x0f, 0x8D); | ||
138 | err += sn9c102_write_reg(cam, 0x3D, 0x8E); | ||
139 | err += sn9c102_write_reg(cam, 0x00, 0x8F); | ||
140 | err += sn9c102_write_reg(cam, 0x3D, 0x90); | ||
141 | err += sn9c102_write_reg(cam, 0x00, 0x91); | ||
142 | err += sn9c102_write_reg(cam, 0xCD, 0x92); | ||
143 | err += sn9c102_write_reg(cam, 0x0f, 0x93); | ||
144 | err += sn9c102_write_reg(cam, 0xf7, 0x94); | ||
145 | err += sn9c102_write_reg(cam, 0x0f, 0x95); | ||
146 | err += sn9c102_write_reg(cam, 0x0C, 0x96); | ||
147 | err += sn9c102_write_reg(cam, 0x00, 0x97); | ||
148 | err += sn9c102_write_reg(cam, 0x00, 0x98); | ||
149 | err += sn9c102_write_reg(cam, 0x66, 0x99); | ||
150 | err += sn9c102_write_reg(cam, 0x05, 0x9A); | ||
151 | err += sn9c102_write_reg(cam, 0x00, 0x9B); | ||
152 | err += sn9c102_write_reg(cam, 0x04, 0x9C); | ||
153 | err += sn9c102_write_reg(cam, 0x00, 0x9D); | ||
154 | err += sn9c102_write_reg(cam, 0x08, 0x9E); | ||
155 | err += sn9c102_write_reg(cam, 0x00, 0x9F); | ||
156 | err += sn9c102_write_reg(cam, 0x2D, 0xC0); | ||
157 | err += sn9c102_write_reg(cam, 0x2D, 0xC1); | ||
158 | err += sn9c102_write_reg(cam, 0x3A, 0xC2); | ||
159 | err += sn9c102_write_reg(cam, 0x05, 0xC3); | ||
160 | err += sn9c102_write_reg(cam, 0x04, 0xC4); | ||
161 | err += sn9c102_write_reg(cam, 0x3F, 0xC5); | ||
162 | err += sn9c102_write_reg(cam, 0x00, 0xC6); | ||
163 | err += sn9c102_write_reg(cam, 0x00, 0xC7); | ||
164 | err += sn9c102_write_reg(cam, 0x50, 0xC8); | ||
165 | err += sn9c102_write_reg(cam, 0x3C, 0xC9); | ||
166 | err += sn9c102_write_reg(cam, 0x28, 0xCA); | ||
167 | err += sn9c102_write_reg(cam, 0xD8, 0xCB); | ||
168 | err += sn9c102_write_reg(cam, 0x14, 0xCC); | ||
169 | err += sn9c102_write_reg(cam, 0xEC, 0xCD); | ||
170 | err += sn9c102_write_reg(cam, 0x32, 0xCE); | ||
171 | err += sn9c102_write_reg(cam, 0xDD, 0xCF); | ||
172 | err += sn9c102_write_reg(cam, 0x32, 0xD0); | ||
173 | err += sn9c102_write_reg(cam, 0xDD, 0xD1); | ||
174 | err += sn9c102_write_reg(cam, 0x6A, 0xD2); | ||
175 | err += sn9c102_write_reg(cam, 0x50, 0xD3); | ||
176 | err += sn9c102_write_reg(cam, 0x00, 0xD4); | ||
177 | err += sn9c102_write_reg(cam, 0x00, 0xD5); | ||
178 | err += sn9c102_write_reg(cam, 0x00, 0xD6); | ||
179 | 103 | ||
180 | err += sn9c102_i2c_write(cam, 0x12, 0x80); | 104 | err += sn9c102_i2c_write(cam, 0x12, 0x80); |
181 | err += sn9c102_i2c_write(cam, 0x11, 0x09); | 105 | err += sn9c102_i2c_write(cam, 0x11, 0x09); |
@@ -572,13 +496,11 @@ static struct sn9c102_sensor ov7660 = { | |||
572 | 496 | ||
573 | int sn9c102_probe_ov7660(struct sn9c102_device* cam) | 497 | int sn9c102_probe_ov7660(struct sn9c102_device* cam) |
574 | { | 498 | { |
575 | int pid, ver, err = 0; | 499 | int pid, ver, err; |
576 | 500 | ||
577 | err += sn9c102_write_reg(cam, 0x01, 0xf1); | 501 | err = sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1}, |
578 | err += sn9c102_write_reg(cam, 0x00, 0xf1); | 502 | {0x01, 0x01}, {0x00, 0x01}, |
579 | err += sn9c102_write_reg(cam, 0x01, 0x01); | 503 | {0x28, 0x17}); |
580 | err += sn9c102_write_reg(cam, 0x00, 0x01); | ||
581 | err += sn9c102_write_reg(cam, 0x28, 0x17); | ||
582 | 504 | ||
583 | pid = sn9c102_i2c_try_read(cam, &ov7660, 0x0a); | 505 | pid = sn9c102_i2c_try_read(cam, &ov7660, 0x0a); |
584 | ver = sn9c102_i2c_try_read(cam, &ov7660, 0x0b); | 506 | ver = sn9c102_i2c_try_read(cam, &ov7660, 0x0b); |
diff --git a/drivers/media/video/sn9c102/sn9c102_pas106b.c b/drivers/media/video/sn9c102/sn9c102_pas106b.c index 8d79a5fae5de..67151964801f 100644 --- a/drivers/media/video/sn9c102/sn9c102_pas106b.c +++ b/drivers/media/video/sn9c102/sn9c102_pas106b.c | |||
@@ -23,19 +23,13 @@ | |||
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; |
32 | 29 | ||
33 | err += sn9c102_write_reg(cam, 0x00, 0x10); | 30 | err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11}, |
34 | err += sn9c102_write_reg(cam, 0x00, 0x11); | 31 | {0x00, 0x14}, {0x20, 0x17}, |
35 | err += sn9c102_write_reg(cam, 0x00, 0x14); | 32 | {0x20, 0x19}, {0x09, 0x18}); |
36 | err += sn9c102_write_reg(cam, 0x20, 0x17); | ||
37 | err += sn9c102_write_reg(cam, 0x20, 0x19); | ||
38 | err += sn9c102_write_reg(cam, 0x09, 0x18); | ||
39 | 33 | ||
40 | err += sn9c102_i2c_write(cam, 0x02, 0x0c); | 34 | err += sn9c102_i2c_write(cam, 0x02, 0x0c); |
41 | err += sn9c102_i2c_write(cam, 0x05, 0x5a); | 35 | err += sn9c102_i2c_write(cam, 0x05, 0x5a); |
@@ -172,7 +166,7 @@ static int pas106b_set_pix_format(struct sn9c102_device* cam, | |||
172 | static struct sn9c102_sensor pas106b = { | 166 | static struct sn9c102_sensor pas106b = { |
173 | .name = "PAS106B", | 167 | .name = "PAS106B", |
174 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | 168 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", |
175 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, | 169 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, |
176 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, | 170 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, |
177 | .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ, | 171 | .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ, |
178 | .interface = SN9C102_I2C_2WIRES, | 172 | .interface = SN9C102_I2C_2WIRES, |
@@ -279,16 +273,17 @@ static struct sn9c102_sensor pas106b = { | |||
279 | 273 | ||
280 | int sn9c102_probe_pas106b(struct sn9c102_device* cam) | 274 | int sn9c102_probe_pas106b(struct sn9c102_device* cam) |
281 | { | 275 | { |
282 | int r0 = 0, r1 = 0, err = 0; | 276 | int r0 = 0, r1 = 0, err; |
283 | unsigned int pid = 0; | 277 | unsigned int pid = 0; |
284 | 278 | ||
285 | /* | 279 | /* |
286 | Minimal initialization to enable the I2C communication | 280 | Minimal initialization to enable the I2C communication |
287 | NOTE: do NOT change the values! | 281 | NOTE: do NOT change the values! |
288 | */ | 282 | */ |
289 | err += sn9c102_write_reg(cam, 0x01, 0x01); /* sensor power down */ | 283 | err = sn9c102_write_const_regs(cam, |
290 | err += sn9c102_write_reg(cam, 0x00, 0x01); /* sensor power on */ | 284 | {0x01, 0x01}, /* sensor power down */ |
291 | err += sn9c102_write_reg(cam, 0x28, 0x17); /* sensor clock at 24 MHz */ | 285 | {0x00, 0x01}, /* sensor power on */ |
286 | {0x28, 0x17});/* sensor clock 24 MHz */ | ||
292 | if (err) | 287 | if (err) |
293 | return -EIO; | 288 | return -EIO; |
294 | 289 | ||
diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c index 7894f01b56e8..c1b8d6b63b47 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,47 +35,29 @@ 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_const_regs(cam, {0x00, 0x10}, |
42 | err += sn9c102_write_reg(cam, 0x00, 0x11); | 39 | {0x00, 0x11}, {0x00, 0x14}, |
43 | err += sn9c102_write_reg(cam, 0x00, 0x14); | 40 | {0x20, 0x17}, {0x30, 0x19}, |
44 | err += sn9c102_write_reg(cam, 0x20, 0x17); | 41 | {0x09, 0x18}); |
45 | err += sn9c102_write_reg(cam, 0x30, 0x19); | ||
46 | err += sn9c102_write_reg(cam, 0x09, 0x18); | ||
47 | break; | 42 | break; |
48 | case BRIDGE_SN9C103: | 43 | case BRIDGE_SN9C103: |
49 | err += sn9c102_write_reg(cam, 0x00, 0x02); | 44 | err = sn9c102_write_const_regs(cam, {0x00, 0x02}, |
50 | err += sn9c102_write_reg(cam, 0x00, 0x03); | 45 | {0x00, 0x03}, {0x1a, 0x04}, |
51 | err += sn9c102_write_reg(cam, 0x1a, 0x04); | 46 | {0x20, 0x05}, {0x20, 0x06}, |
52 | err += sn9c102_write_reg(cam, 0x20, 0x05); | 47 | {0x20, 0x07}, {0x00, 0x10}, |
53 | err += sn9c102_write_reg(cam, 0x20, 0x06); | 48 | {0x00, 0x11}, {0x00, 0x14}, |
54 | err += sn9c102_write_reg(cam, 0x20, 0x07); | 49 | {0x20, 0x17}, {0x30, 0x19}, |
55 | err += sn9c102_write_reg(cam, 0x00, 0x10); | 50 | {0x09, 0x18}, {0x02, 0x1c}, |
56 | err += sn9c102_write_reg(cam, 0x00, 0x11); | 51 | {0x03, 0x1d}, {0x0f, 0x1e}, |
57 | err += sn9c102_write_reg(cam, 0x00, 0x14); | 52 | {0x0c, 0x1f}, {0x00, 0x20}, |
58 | err += sn9c102_write_reg(cam, 0x20, 0x17); | 53 | {0x10, 0x21}, {0x20, 0x22}, |
59 | err += sn9c102_write_reg(cam, 0x30, 0x19); | 54 | {0x30, 0x23}, {0x40, 0x24}, |
60 | err += sn9c102_write_reg(cam, 0x09, 0x18); | 55 | {0x50, 0x25}, {0x60, 0x26}, |
61 | err += sn9c102_write_reg(cam, 0x02, 0x1c); | 56 | {0x70, 0x27}, {0x80, 0x28}, |
62 | err += sn9c102_write_reg(cam, 0x03, 0x1d); | 57 | {0x90, 0x29}, {0xa0, 0x2a}, |
63 | err += sn9c102_write_reg(cam, 0x0f, 0x1e); | 58 | {0xb0, 0x2b}, {0xc0, 0x2c}, |
64 | err += sn9c102_write_reg(cam, 0x0c, 0x1f); | 59 | {0xd0, 0x2d}, {0xe0, 0x2e}, |
65 | err += sn9c102_write_reg(cam, 0x00, 0x20); | 60 | {0xf0, 0x2f}, {0xff, 0x30}); |
66 | err += sn9c102_write_reg(cam, 0x10, 0x21); | ||
67 | err += sn9c102_write_reg(cam, 0x20, 0x22); | ||
68 | err += sn9c102_write_reg(cam, 0x30, 0x23); | ||
69 | err += sn9c102_write_reg(cam, 0x40, 0x24); | ||
70 | err += sn9c102_write_reg(cam, 0x50, 0x25); | ||
71 | err += sn9c102_write_reg(cam, 0x60, 0x26); | ||
72 | err += sn9c102_write_reg(cam, 0x70, 0x27); | ||
73 | err += sn9c102_write_reg(cam, 0x80, 0x28); | ||
74 | err += sn9c102_write_reg(cam, 0x90, 0x29); | ||
75 | err += sn9c102_write_reg(cam, 0xa0, 0x2a); | ||
76 | err += sn9c102_write_reg(cam, 0xb0, 0x2b); | ||
77 | err += sn9c102_write_reg(cam, 0xc0, 0x2c); | ||
78 | err += sn9c102_write_reg(cam, 0xd0, 0x2d); | ||
79 | err += sn9c102_write_reg(cam, 0xe0, 0x2e); | ||
80 | err += sn9c102_write_reg(cam, 0xf0, 0x2f); | ||
81 | err += sn9c102_write_reg(cam, 0xff, 0x30); | ||
82 | break; | 61 | break; |
83 | default: | 62 | default: |
84 | break; | 63 | break; |
@@ -328,15 +307,15 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam) | |||
328 | switch (sn9c102_get_bridge(cam)) { | 307 | switch (sn9c102_get_bridge(cam)) { |
329 | case BRIDGE_SN9C101: | 308 | case BRIDGE_SN9C101: |
330 | case BRIDGE_SN9C102: | 309 | case BRIDGE_SN9C102: |
331 | err += sn9c102_write_reg(cam, 0x01, 0x01); /* power down */ | 310 | err = sn9c102_write_const_regs(cam, |
332 | err += sn9c102_write_reg(cam, 0x40, 0x01); /* power on */ | 311 | {0x01, 0x01}, /* power down */ |
333 | err += sn9c102_write_reg(cam, 0x28, 0x17); /* clock 24 MHz */ | 312 | {0x40, 0x01}, /* power on */ |
313 | {0x28, 0x17});/* clock 24 MHz */ | ||
334 | break; | 314 | break; |
335 | case BRIDGE_SN9C103: /* do _not_ change anything! */ | 315 | case BRIDGE_SN9C103: /* do _not_ change anything! */ |
336 | err += sn9c102_write_reg(cam, 0x09, 0x01); | 316 | err = sn9c102_write_const_regs(cam, {0x09, 0x01}, |
337 | err += sn9c102_write_reg(cam, 0x44, 0x01); | 317 | {0x44, 0x01}, {0x44, 0x02}, |
338 | err += sn9c102_write_reg(cam, 0x44, 0x02); | 318 | {0x29, 0x17}); |
339 | err += sn9c102_write_reg(cam, 0x29, 0x17); | ||
340 | break; | 319 | break; |
341 | default: | 320 | default: |
342 | break; | 321 | break; |
diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h index 05f2942639c3..1bbf64c897a2 100644 --- a/drivers/media/video/sn9c102/sn9c102_sensor.h +++ b/drivers/media/video/sn9c102/sn9c102_sensor.h | |||
@@ -114,9 +114,17 @@ extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value); | |||
114 | extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address); | 114 | extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address); |
115 | 115 | ||
116 | /* I/O on registers in the bridge. Could be used by the sensor methods too */ | 116 | /* I/O on registers in the bridge. Could be used by the sensor methods too */ |
117 | extern int sn9c102_write_regs(struct sn9c102_device*, u8* buff, u16 index); | ||
118 | extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index); | ||
119 | extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index); | 117 | extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index); |
118 | extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index); | ||
119 | extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2], | ||
120 | int count); | ||
121 | /* | ||
122 | * Write multiple registers with constant values. For example: | ||
123 | * sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18}); | ||
124 | */ | ||
125 | #define sn9c102_write_const_regs(device, data...) \ | ||
126 | ({ const static u8 _data[][2] = {data}; \ | ||
127 | sn9c102_write_regs(device, _data, ARRAY_SIZE(_data)); }) | ||
120 | 128 | ||
121 | /*****************************************************************************/ | 129 | /*****************************************************************************/ |
122 | 130 | ||
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c index 90023ad63adc..0e7ec8662c70 100644 --- a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c +++ b/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c | |||
@@ -22,21 +22,14 @@ | |||
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; |
31 | 28 | ||
32 | err += sn9c102_write_reg(cam, 0x01, 0x01); | 29 | err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x44, 0x01}, |
33 | err += sn9c102_write_reg(cam, 0x44, 0x01); | 30 | {0x00, 0x10}, {0x00, 0x11}, |
34 | err += sn9c102_write_reg(cam, 0x00, 0x10); | 31 | {0x0a, 0x14}, {0x60, 0x17}, |
35 | err += sn9c102_write_reg(cam, 0x00, 0x11); | 32 | {0x06, 0x18}, {0xfb, 0x19}); |
36 | err += sn9c102_write_reg(cam, 0x0a, 0x14); | ||
37 | err += sn9c102_write_reg(cam, 0x60, 0x17); | ||
38 | err += sn9c102_write_reg(cam, 0x06, 0x18); | ||
39 | err += sn9c102_write_reg(cam, 0xfb, 0x19); | ||
40 | 33 | ||
41 | err += sn9c102_i2c_write(cam, 0xc0, 0x80); | 34 | err += sn9c102_i2c_write(cam, 0xc0, 0x80); |
42 | 35 | ||
@@ -98,7 +91,7 @@ static int tas5110c1b_set_pix_format(struct sn9c102_device* cam, | |||
98 | static struct sn9c102_sensor tas5110c1b = { | 91 | static struct sn9c102_sensor tas5110c1b = { |
99 | .name = "TAS5110C1B", | 92 | .name = "TAS5110C1B", |
100 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | 93 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", |
101 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, | 94 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, |
102 | .sysfs_ops = SN9C102_I2C_WRITE, | 95 | .sysfs_ops = SN9C102_I2C_WRITE, |
103 | .frequency = SN9C102_I2C_100KHZ, | 96 | .frequency = SN9C102_I2C_100KHZ, |
104 | .interface = SN9C102_I2C_3WIRES, | 97 | .interface = SN9C102_I2C_3WIRES, |
@@ -146,7 +139,6 @@ int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam) | |||
146 | const struct usb_device_id tas5110c1b_id_table[] = { | 139 | const struct usb_device_id tas5110c1b_id_table[] = { |
147 | { USB_DEVICE(0x0c45, 0x6001), }, | 140 | { USB_DEVICE(0x0c45, 0x6001), }, |
148 | { USB_DEVICE(0x0c45, 0x6005), }, | 141 | { USB_DEVICE(0x0c45, 0x6005), }, |
149 | { USB_DEVICE(0x0c45, 0x6007), }, | ||
150 | { USB_DEVICE(0x0c45, 0x60ab), }, | 142 | { USB_DEVICE(0x0c45, 0x60ab), }, |
151 | { } | 143 | { } |
152 | }; | 144 | }; |
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110d.c b/drivers/media/video/sn9c102/sn9c102_tas5110d.c new file mode 100644 index 000000000000..83a39e8b5e71 --- /dev/null +++ b/drivers/media/video/sn9c102/sn9c102_tas5110d.c | |||
@@ -0,0 +1,118 @@ | |||
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; | ||
28 | |||
29 | err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x04, 0x01}, | ||
30 | {0x0a, 0x14}, {0x60, 0x17}, | ||
31 | {0x06, 0x18}, {0xfb, 0x19}); | ||
32 | |||
33 | err += sn9c102_i2c_write(cam, 0x9a, 0xca); | ||
34 | |||
35 | return err; | ||
36 | } | ||
37 | |||
38 | |||
39 | static int tas5110d_set_crop(struct sn9c102_device* cam, | ||
40 | const struct v4l2_rect* rect) | ||
41 | { | ||
42 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | ||
43 | int err = 0; | ||
44 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69, | ||
45 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9; | ||
46 | |||
47 | err += sn9c102_write_reg(cam, h_start, 0x12); | ||
48 | err += sn9c102_write_reg(cam, v_start, 0x13); | ||
49 | |||
50 | err += sn9c102_write_reg(cam, 0x14, 0x1a); | ||
51 | err += sn9c102_write_reg(cam, 0x0a, 0x1b); | ||
52 | |||
53 | return err; | ||
54 | } | ||
55 | |||
56 | |||
57 | static int tas5110d_set_pix_format(struct sn9c102_device* cam, | ||
58 | const struct v4l2_pix_format* pix) | ||
59 | { | ||
60 | int err = 0; | ||
61 | |||
62 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) | ||
63 | err += sn9c102_write_reg(cam, 0x3b, 0x19); | ||
64 | else | ||
65 | err += sn9c102_write_reg(cam, 0xfb, 0x19); | ||
66 | |||
67 | return err; | ||
68 | } | ||
69 | |||
70 | |||
71 | static struct sn9c102_sensor tas5110d = { | ||
72 | .name = "TAS5110D", | ||
73 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | ||
74 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, | ||
75 | .sysfs_ops = SN9C102_I2C_WRITE, | ||
76 | .frequency = SN9C102_I2C_100KHZ, | ||
77 | .interface = SN9C102_I2C_2WIRES, | ||
78 | .i2c_slave_id = 0x61, | ||
79 | .init = &tas5110d_init, | ||
80 | .cropcap = { | ||
81 | .bounds = { | ||
82 | .left = 0, | ||
83 | .top = 0, | ||
84 | .width = 352, | ||
85 | .height = 288, | ||
86 | }, | ||
87 | .defrect = { | ||
88 | .left = 0, | ||
89 | .top = 0, | ||
90 | .width = 352, | ||
91 | .height = 288, | ||
92 | }, | ||
93 | }, | ||
94 | .set_crop = &tas5110d_set_crop, | ||
95 | .pix_format = { | ||
96 | .width = 352, | ||
97 | .height = 288, | ||
98 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | ||
99 | .priv = 8, | ||
100 | }, | ||
101 | .set_pix_format = &tas5110d_set_pix_format | ||
102 | }; | ||
103 | |||
104 | |||
105 | int sn9c102_probe_tas5110d(struct sn9c102_device* cam) | ||
106 | { | ||
107 | const struct usb_device_id tas5110d_id_table[] = { | ||
108 | { USB_DEVICE(0x0c45, 0x6007), }, | ||
109 | { } | ||
110 | }; | ||
111 | |||
112 | if (!sn9c102_match_id(cam, tas5110d_id_table)) | ||
113 | return -ENODEV; | ||
114 | |||
115 | sn9c102_attach_sensor(cam, &tas5110d); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c index cb1b318bc1ff..50406503fc40 100644 --- a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c +++ b/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c | |||
@@ -22,21 +22,14 @@ | |||
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; |
31 | 28 | ||
32 | err += sn9c102_write_reg(cam, 0x01, 0x01); | 29 | err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x20, 0x17}, |
33 | err += sn9c102_write_reg(cam, 0x20, 0x17); | 30 | {0x04, 0x01}, {0x01, 0x10}, |
34 | err += sn9c102_write_reg(cam, 0x04, 0x01); | 31 | {0x00, 0x11}, {0x00, 0x14}, |
35 | err += sn9c102_write_reg(cam, 0x01, 0x10); | 32 | {0x60, 0x17}, {0x07, 0x18}); |
36 | err += sn9c102_write_reg(cam, 0x00, 0x11); | ||
37 | err += sn9c102_write_reg(cam, 0x00, 0x14); | ||
38 | err += sn9c102_write_reg(cam, 0x60, 0x17); | ||
39 | err += sn9c102_write_reg(cam, 0x07, 0x18); | ||
40 | 33 | ||
41 | return err; | 34 | return err; |
42 | } | 35 | } |
@@ -99,7 +92,7 @@ static int tas5130d1b_set_pix_format(struct sn9c102_device* cam, | |||
99 | static struct sn9c102_sensor tas5130d1b = { | 92 | static struct sn9c102_sensor tas5130d1b = { |
100 | .name = "TAS5130D1B", | 93 | .name = "TAS5130D1B", |
101 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | 94 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", |
102 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, | 95 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, |
103 | .sysfs_ops = SN9C102_I2C_WRITE, | 96 | .sysfs_ops = SN9C102_I2C_WRITE, |
104 | .frequency = SN9C102_I2C_100KHZ, | 97 | .frequency = SN9C102_I2C_100KHZ, |
105 | .interface = SN9C102_I2C_3WIRES, | 98 | .interface = SN9C102_I2C_3WIRES, |