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