diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-17 00:15:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-17 00:15:42 -0400 |
commit | 0dd5198672dd2bbeb933862e1fc82162e0b636be (patch) | |
tree | c9efed20d90603c4d1626c21bd7aab1e7fc74a58 /drivers/media/video | |
parent | c868d550115b9ccc0027c67265b9520790f05601 (diff) | |
parent | 11c635a25b9f3a5d87409ce46cf2e05c500251ec (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (425 commits)
V4L/DVB (11870): gspca - main: VIDIOC_ENUM_FRAMESIZES ioctl added.
V4L/DVB (12004): poll method lose race condition
V4L/DVB (11894): flexcop-pci: dmesg visible names broken
V4L/DVB (11892): Siano: smsendian - declare function as extern
V4L/DVB (11891): Siano: smscore - bind the GPIO SMS protocol
V4L/DVB (11890): Siano: smscore - remove redundant code
V4L/DVB (11889): Siano: smsdvb - add DVB v3 events
V4L/DVB (11888): Siano: smsusb - remove redundant ifdef
V4L/DVB (11887): Siano: smscards - add board (target) events
V4L/DVB (11886): Siano: smscore - fix some new GPIO definitions names
V4L/DVB (11885): Siano: Add new GPIO management interface
V4L/DVB (11884): Siano: smssdio - revert to stand alone module
V4L/DVB (11883): Siano: cards - add two additional (USB) devices
V4L/DVB (11824): Siano: smsusb - change exit func debug msg
V4L/DVB (11823): Siano: smsusb - fix typo in module description
V4L/DVB (11822): Siano: smscore - bug fix at get_device_mode
V4L/DVB (11821): Siano: smscore - fix isdb-t firmware name
V4L/DVB (11820): Siano: smscore - fix byte ordering bug
V4L/DVB (11819): Siano: smscore - fix get_common_buffer bug
V4L/DVB (11818): Siano: smscards - assign gpio to HPG targets
...
Diffstat (limited to 'drivers/media/video')
163 files changed, 9362 insertions, 5195 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 57835f5715fc..94f440535c64 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -440,6 +440,24 @@ config VIDEO_ADV7175 | |||
440 | To compile this driver as a module, choose M here: the | 440 | To compile this driver as a module, choose M here: the |
441 | module will be called adv7175. | 441 | module will be called adv7175. |
442 | 442 | ||
443 | config VIDEO_THS7303 | ||
444 | tristate "THS7303 Video Amplifier" | ||
445 | depends on I2C | ||
446 | help | ||
447 | Support for TI THS7303 video amplifier | ||
448 | |||
449 | To compile this driver as a module, choose M here: the | ||
450 | module will be called ths7303. | ||
451 | |||
452 | config VIDEO_ADV7343 | ||
453 | tristate "ADV7343 video encoder" | ||
454 | depends on I2C | ||
455 | help | ||
456 | Support for Analog Devices I2C bus based ADV7343 encoder. | ||
457 | |||
458 | To compile this driver as a module, choose M here: the | ||
459 | module will be called adv7343. | ||
460 | |||
443 | comment "Video improvement chips" | 461 | comment "Video improvement chips" |
444 | 462 | ||
445 | config VIDEO_UPD64031A | 463 | config VIDEO_UPD64031A |
@@ -694,7 +712,7 @@ config VIDEO_CAFE_CCIC | |||
694 | 712 | ||
695 | config SOC_CAMERA | 713 | config SOC_CAMERA |
696 | tristate "SoC camera support" | 714 | tristate "SoC camera support" |
697 | depends on VIDEO_V4L2 && HAS_DMA | 715 | depends on VIDEO_V4L2 && HAS_DMA && I2C |
698 | select VIDEOBUF_GEN | 716 | select VIDEOBUF_GEN |
699 | help | 717 | help |
700 | SoC Camera is a common API to several cameras, not connecting | 718 | SoC Camera is a common API to several cameras, not connecting |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 3f1a0350a569..7fb3add1b387 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -12,6 +12,8 @@ omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o | |||
12 | 12 | ||
13 | videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o | 13 | videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o |
14 | 14 | ||
15 | # V4L2 core modules | ||
16 | |||
15 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o | 17 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o |
16 | ifeq ($(CONFIG_COMPAT),y) | 18 | ifeq ($(CONFIG_COMPAT),y) |
17 | obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o | 19 | obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o |
@@ -23,21 +25,15 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y) | |||
23 | obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o | 25 | obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o |
24 | endif | 26 | endif |
25 | 27 | ||
26 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o | 28 | # All i2c modules must come first: |
27 | 29 | ||
28 | obj-$(CONFIG_VIDEO_BT848) += bt8xx/ | 30 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o |
29 | obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o | ||
30 | obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o | 31 | obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o |
31 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o | 32 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o |
32 | obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o | 33 | obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o |
33 | |||
34 | obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o | 34 | obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o |
35 | obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o | 35 | obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o |
36 | obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o | 36 | obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o |
37 | obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o | ||
38 | obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o | ||
39 | obj-$(CONFIG_VIDEO_W9966) += w9966.o | ||
40 | |||
41 | obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o | 37 | obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o |
42 | obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o | 38 | obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o |
43 | obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o | 39 | obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o |
@@ -49,16 +45,47 @@ obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o | |||
49 | obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o | 45 | obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o |
50 | obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o | 46 | obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o |
51 | obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o | 47 | obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o |
48 | obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o | ||
52 | obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o | 49 | obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o |
53 | obj-$(CONFIG_VIDEO_BT819) += bt819.o | 50 | obj-$(CONFIG_VIDEO_BT819) += bt819.o |
54 | obj-$(CONFIG_VIDEO_BT856) += bt856.o | 51 | obj-$(CONFIG_VIDEO_BT856) += bt856.o |
55 | obj-$(CONFIG_VIDEO_BT866) += bt866.o | 52 | obj-$(CONFIG_VIDEO_BT866) += bt866.o |
56 | obj-$(CONFIG_VIDEO_KS0127) += ks0127.o | 53 | obj-$(CONFIG_VIDEO_KS0127) += ks0127.o |
54 | obj-$(CONFIG_VIDEO_THS7303) += ths7303.o | ||
55 | obj-$(CONFIG_VIDEO_VINO) += indycam.o | ||
56 | obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o | ||
57 | obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o | ||
58 | obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o | ||
59 | obj-$(CONFIG_VIDEO_CS5345) += cs5345.o | ||
60 | obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o | ||
61 | obj-$(CONFIG_VIDEO_M52790) += m52790.o | ||
62 | obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o | ||
63 | obj-$(CONFIG_VIDEO_WM8775) += wm8775.o | ||
64 | obj-$(CONFIG_VIDEO_WM8739) += wm8739.o | ||
65 | obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o | ||
66 | obj-$(CONFIG_VIDEO_CX25840) += cx25840/ | ||
67 | obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o | ||
68 | obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o | ||
69 | obj-$(CONFIG_VIDEO_OV7670) += ov7670.o | ||
70 | obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o | ||
71 | obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o | ||
57 | 72 | ||
58 | obj-$(CONFIG_VIDEO_ZORAN) += zoran/ | 73 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o |
74 | obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o | ||
75 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o | ||
76 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o | ||
77 | obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o | ||
78 | obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o | ||
59 | 79 | ||
80 | # And now the v4l2 drivers: | ||
81 | |||
82 | obj-$(CONFIG_VIDEO_BT848) += bt8xx/ | ||
83 | obj-$(CONFIG_VIDEO_ZORAN) += zoran/ | ||
84 | obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o | ||
85 | obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o | ||
86 | obj-$(CONFIG_VIDEO_W9966) += w9966.o | ||
60 | obj-$(CONFIG_VIDEO_PMS) += pms.o | 87 | obj-$(CONFIG_VIDEO_PMS) += pms.o |
61 | obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o | 88 | obj-$(CONFIG_VIDEO_VINO) += vino.o |
62 | obj-$(CONFIG_VIDEO_STRADIS) += stradis.o | 89 | obj-$(CONFIG_VIDEO_STRADIS) += stradis.o |
63 | obj-$(CONFIG_VIDEO_CPIA) += cpia.o | 90 | obj-$(CONFIG_VIDEO_CPIA) += cpia.o |
64 | obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o | 91 | obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o |
@@ -69,17 +96,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/ | |||
69 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ | 96 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ |
70 | obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/ | 97 | obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/ |
71 | obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ | 98 | obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ |
72 | obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o | ||
73 | obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o | ||
74 | obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ | 99 | obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ |
75 | obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o | ||
76 | obj-$(CONFIG_VIDEO_CS5345) += cs5345.o | ||
77 | obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o | ||
78 | obj-$(CONFIG_VIDEO_M52790) += m52790.o | ||
79 | obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o | ||
80 | obj-$(CONFIG_VIDEO_WM8775) += wm8775.o | ||
81 | obj-$(CONFIG_VIDEO_WM8739) += wm8739.o | ||
82 | obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o | ||
83 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ | 100 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ |
84 | obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ | 101 | obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ |
85 | obj-$(CONFIG_VIDEO_MXB) += mxb.o | 102 | obj-$(CONFIG_VIDEO_MXB) += mxb.o |
@@ -92,19 +109,12 @@ obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o | |||
92 | obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o | 109 | obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o |
93 | obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o | 110 | obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o |
94 | obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o | 111 | obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o |
95 | obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o | ||
96 | 112 | ||
97 | obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o | 113 | obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o |
98 | 114 | ||
99 | obj-$(CONFIG_VIDEO_CX25840) += cx25840/ | ||
100 | obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o | ||
101 | obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o | ||
102 | obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o | 115 | obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o |
103 | 116 | ||
104 | obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o | 117 | obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o |
105 | obj-$(CONFIG_VIDEO_OV7670) += ov7670.o | ||
106 | |||
107 | obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o | ||
108 | 118 | ||
109 | obj-$(CONFIG_USB_DABUSB) += dabusb.o | 119 | obj-$(CONFIG_USB_DABUSB) += dabusb.o |
110 | obj-$(CONFIG_USB_OV511) += ov511.o | 120 | obj-$(CONFIG_USB_OV511) += ov511.o |
@@ -134,24 +144,21 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/ | |||
134 | obj-$(CONFIG_VIDEO_VIVI) += vivi.o | 144 | obj-$(CONFIG_VIDEO_VIVI) += vivi.o |
135 | obj-$(CONFIG_VIDEO_CX23885) += cx23885/ | 145 | obj-$(CONFIG_VIDEO_CX23885) += cx23885/ |
136 | 146 | ||
147 | obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o | ||
148 | obj-$(CONFIG_SOC_CAMERA) += soc_camera.o | ||
149 | obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o | ||
150 | # soc-camera host drivers have to be linked after camera drivers | ||
137 | obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o | 151 | obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o |
138 | obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o | 152 | obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o |
139 | obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o | 153 | obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o |
140 | obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o | 154 | obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o |
141 | obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o | ||
142 | obj-$(CONFIG_SOC_CAMERA) += soc_camera.o | ||
143 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o | ||
144 | obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o | ||
145 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o | ||
146 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o | ||
147 | obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o | ||
148 | obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o | ||
149 | obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o | ||
150 | 155 | ||
151 | obj-$(CONFIG_VIDEO_AU0828) += au0828/ | 156 | obj-$(CONFIG_VIDEO_AU0828) += au0828/ |
152 | 157 | ||
153 | obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/ | 158 | obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/ |
154 | 159 | ||
160 | obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o | ||
161 | |||
155 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 162 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
156 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 163 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
157 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | 164 | EXTRA_CFLAGS += -Idrivers/media/common/tuners |
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c new file mode 100644 index 000000000000..30f5caf5dda5 --- /dev/null +++ b/drivers/media/video/adv7343.c | |||
@@ -0,0 +1,534 @@ | |||
1 | /* | ||
2 | * adv7343 - ADV7343 Video Encoder Driver | ||
3 | * | ||
4 | * The encoder hardware does not support SECAM. | ||
5 | * | ||
6 | * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation version 2. | ||
11 | * | ||
12 | * This program is distributed .as is. WITHOUT ANY WARRANTY of any | ||
13 | * kind, whether express or implied; without even the implied warranty | ||
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/ctype.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/device.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/videodev2.h> | ||
26 | #include <linux/uaccess.h> | ||
27 | #include <linux/version.h> | ||
28 | |||
29 | #include <media/adv7343.h> | ||
30 | #include <media/v4l2-device.h> | ||
31 | #include <media/v4l2-chip-ident.h> | ||
32 | |||
33 | #include "adv7343_regs.h" | ||
34 | |||
35 | MODULE_DESCRIPTION("ADV7343 video encoder driver"); | ||
36 | MODULE_LICENSE("GPL"); | ||
37 | |||
38 | static int debug; | ||
39 | module_param(debug, int, 0644); | ||
40 | MODULE_PARM_DESC(debug, "Debug level 0-1"); | ||
41 | |||
42 | struct adv7343_state { | ||
43 | struct v4l2_subdev sd; | ||
44 | u8 reg00; | ||
45 | u8 reg01; | ||
46 | u8 reg02; | ||
47 | u8 reg35; | ||
48 | u8 reg80; | ||
49 | u8 reg82; | ||
50 | int bright; | ||
51 | int hue; | ||
52 | int gain; | ||
53 | u32 output; | ||
54 | v4l2_std_id std; | ||
55 | }; | ||
56 | |||
57 | static inline struct adv7343_state *to_state(struct v4l2_subdev *sd) | ||
58 | { | ||
59 | return container_of(sd, struct adv7343_state, sd); | ||
60 | } | ||
61 | |||
62 | static inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value) | ||
63 | { | ||
64 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
65 | |||
66 | return i2c_smbus_write_byte_data(client, reg, value); | ||
67 | } | ||
68 | |||
69 | static const u8 adv7343_init_reg_val[] = { | ||
70 | ADV7343_SOFT_RESET, ADV7343_SOFT_RESET_DEFAULT, | ||
71 | ADV7343_POWER_MODE_REG, ADV7343_POWER_MODE_REG_DEFAULT, | ||
72 | |||
73 | ADV7343_HD_MODE_REG1, ADV7343_HD_MODE_REG1_DEFAULT, | ||
74 | ADV7343_HD_MODE_REG2, ADV7343_HD_MODE_REG2_DEFAULT, | ||
75 | ADV7343_HD_MODE_REG3, ADV7343_HD_MODE_REG3_DEFAULT, | ||
76 | ADV7343_HD_MODE_REG4, ADV7343_HD_MODE_REG4_DEFAULT, | ||
77 | ADV7343_HD_MODE_REG5, ADV7343_HD_MODE_REG5_DEFAULT, | ||
78 | ADV7343_HD_MODE_REG6, ADV7343_HD_MODE_REG6_DEFAULT, | ||
79 | ADV7343_HD_MODE_REG7, ADV7343_HD_MODE_REG7_DEFAULT, | ||
80 | |||
81 | ADV7343_SD_MODE_REG1, ADV7343_SD_MODE_REG1_DEFAULT, | ||
82 | ADV7343_SD_MODE_REG2, ADV7343_SD_MODE_REG2_DEFAULT, | ||
83 | ADV7343_SD_MODE_REG3, ADV7343_SD_MODE_REG3_DEFAULT, | ||
84 | ADV7343_SD_MODE_REG4, ADV7343_SD_MODE_REG4_DEFAULT, | ||
85 | ADV7343_SD_MODE_REG5, ADV7343_SD_MODE_REG5_DEFAULT, | ||
86 | ADV7343_SD_MODE_REG6, ADV7343_SD_MODE_REG6_DEFAULT, | ||
87 | ADV7343_SD_MODE_REG7, ADV7343_SD_MODE_REG7_DEFAULT, | ||
88 | ADV7343_SD_MODE_REG8, ADV7343_SD_MODE_REG8_DEFAULT, | ||
89 | |||
90 | ADV7343_SD_HUE_REG, ADV7343_SD_HUE_REG_DEFAULT, | ||
91 | ADV7343_SD_CGMS_WSS0, ADV7343_SD_CGMS_WSS0_DEFAULT, | ||
92 | ADV7343_SD_BRIGHTNESS_WSS, ADV7343_SD_BRIGHTNESS_WSS_DEFAULT, | ||
93 | }; | ||
94 | |||
95 | /* | ||
96 | * 2^32 | ||
97 | * FSC(reg) = FSC (HZ) * -------- | ||
98 | * 27000000 | ||
99 | */ | ||
100 | static const struct adv7343_std_info stdinfo[] = { | ||
101 | { | ||
102 | /* FSC(Hz) = 3,579,545.45 Hz */ | ||
103 | SD_STD_NTSC, 569408542, V4L2_STD_NTSC, | ||
104 | }, { | ||
105 | /* FSC(Hz) = 3,575,611.00 Hz */ | ||
106 | SD_STD_PAL_M, 568782678, V4L2_STD_PAL_M, | ||
107 | }, { | ||
108 | /* FSC(Hz) = 3,582,056.00 */ | ||
109 | SD_STD_PAL_N, 569807903, V4L2_STD_PAL_Nc, | ||
110 | }, { | ||
111 | /* FSC(Hz) = 4,433,618.75 Hz */ | ||
112 | SD_STD_PAL_N, 705268427, V4L2_STD_PAL_N, | ||
113 | }, { | ||
114 | /* FSC(Hz) = 4,433,618.75 Hz */ | ||
115 | SD_STD_PAL_BDGHI, 705268427, V4L2_STD_PAL, | ||
116 | }, { | ||
117 | /* FSC(Hz) = 4,433,618.75 Hz */ | ||
118 | SD_STD_NTSC, 705268427, V4L2_STD_NTSC_443, | ||
119 | }, { | ||
120 | /* FSC(Hz) = 4,433,618.75 Hz */ | ||
121 | SD_STD_PAL_M, 705268427, V4L2_STD_PAL_60, | ||
122 | }, | ||
123 | }; | ||
124 | |||
125 | static int adv7343_setstd(struct v4l2_subdev *sd, v4l2_std_id std) | ||
126 | { | ||
127 | struct adv7343_state *state = to_state(sd); | ||
128 | struct adv7343_std_info *std_info; | ||
129 | int output_idx, num_std; | ||
130 | char *fsc_ptr; | ||
131 | u8 reg, val; | ||
132 | int err = 0; | ||
133 | int i = 0; | ||
134 | |||
135 | output_idx = state->output; | ||
136 | |||
137 | std_info = (struct adv7343_std_info *)stdinfo; | ||
138 | num_std = ARRAY_SIZE(stdinfo); | ||
139 | |||
140 | for (i = 0; i < num_std; i++) { | ||
141 | if (std_info[i].stdid & std) | ||
142 | break; | ||
143 | } | ||
144 | |||
145 | if (i == num_std) { | ||
146 | v4l2_dbg(1, debug, sd, | ||
147 | "Invalid std or std is not supported: %llx\n", | ||
148 | (unsigned long long)std); | ||
149 | return -EINVAL; | ||
150 | } | ||
151 | |||
152 | /* Set the standard */ | ||
153 | val = state->reg80 & (~(SD_STD_MASK)); | ||
154 | val |= std_info[i].standard_val3; | ||
155 | err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val); | ||
156 | if (err < 0) | ||
157 | goto setstd_exit; | ||
158 | |||
159 | state->reg80 = val; | ||
160 | |||
161 | /* Configure the input mode register */ | ||
162 | val = state->reg01 & (~((u8) INPUT_MODE_MASK)); | ||
163 | val |= SD_INPUT_MODE; | ||
164 | err = adv7343_write(sd, ADV7343_MODE_SELECT_REG, val); | ||
165 | if (err < 0) | ||
166 | goto setstd_exit; | ||
167 | |||
168 | state->reg01 = val; | ||
169 | |||
170 | /* Program the sub carrier frequency registers */ | ||
171 | fsc_ptr = (unsigned char *)&std_info[i].fsc_val; | ||
172 | reg = ADV7343_FSC_REG0; | ||
173 | for (i = 0; i < 4; i++, reg++, fsc_ptr++) { | ||
174 | err = adv7343_write(sd, reg, *fsc_ptr); | ||
175 | if (err < 0) | ||
176 | goto setstd_exit; | ||
177 | } | ||
178 | |||
179 | val = state->reg80; | ||
180 | |||
181 | /* Filter settings */ | ||
182 | if (std & (V4L2_STD_NTSC | V4L2_STD_NTSC_443)) | ||
183 | val &= 0x03; | ||
184 | else if (std & ~V4L2_STD_SECAM) | ||
185 | val |= 0x04; | ||
186 | |||
187 | err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val); | ||
188 | if (err < 0) | ||
189 | goto setstd_exit; | ||
190 | |||
191 | state->reg80 = val; | ||
192 | |||
193 | setstd_exit: | ||
194 | if (err != 0) | ||
195 | v4l2_err(sd, "Error setting std, write failed\n"); | ||
196 | |||
197 | return err; | ||
198 | } | ||
199 | |||
200 | static int adv7343_setoutput(struct v4l2_subdev *sd, u32 output_type) | ||
201 | { | ||
202 | struct adv7343_state *state = to_state(sd); | ||
203 | unsigned char val; | ||
204 | int err = 0; | ||
205 | |||
206 | if (output_type > ADV7343_SVIDEO_ID) { | ||
207 | v4l2_dbg(1, debug, sd, | ||
208 | "Invalid output type or output type not supported:%d\n", | ||
209 | output_type); | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | /* Enable Appropriate DAC */ | ||
214 | val = state->reg00 & 0x03; | ||
215 | |||
216 | if (output_type == ADV7343_COMPOSITE_ID) | ||
217 | val |= ADV7343_COMPOSITE_POWER_VALUE; | ||
218 | else if (output_type == ADV7343_COMPONENT_ID) | ||
219 | val |= ADV7343_COMPONENT_POWER_VALUE; | ||
220 | else | ||
221 | val |= ADV7343_SVIDEO_POWER_VALUE; | ||
222 | |||
223 | err = adv7343_write(sd, ADV7343_POWER_MODE_REG, val); | ||
224 | if (err < 0) | ||
225 | goto setoutput_exit; | ||
226 | |||
227 | state->reg00 = val; | ||
228 | |||
229 | /* Enable YUV output */ | ||
230 | val = state->reg02 | YUV_OUTPUT_SELECT; | ||
231 | err = adv7343_write(sd, ADV7343_MODE_REG0, val); | ||
232 | if (err < 0) | ||
233 | goto setoutput_exit; | ||
234 | |||
235 | state->reg02 = val; | ||
236 | |||
237 | /* configure SD DAC Output 2 and SD DAC Output 1 bit to zero */ | ||
238 | val = state->reg82 & (SD_DAC_1_DI & SD_DAC_2_DI); | ||
239 | err = adv7343_write(sd, ADV7343_SD_MODE_REG2, val); | ||
240 | if (err < 0) | ||
241 | goto setoutput_exit; | ||
242 | |||
243 | state->reg82 = val; | ||
244 | |||
245 | /* configure ED/HD Color DAC Swap and ED/HD RGB Input Enable bit to | ||
246 | * zero */ | ||
247 | val = state->reg35 & (HD_RGB_INPUT_DI & HD_DAC_SWAP_DI); | ||
248 | err = adv7343_write(sd, ADV7343_HD_MODE_REG6, val); | ||
249 | if (err < 0) | ||
250 | goto setoutput_exit; | ||
251 | |||
252 | state->reg35 = val; | ||
253 | |||
254 | setoutput_exit: | ||
255 | if (err != 0) | ||
256 | v4l2_err(sd, "Error setting output, write failed\n"); | ||
257 | |||
258 | return err; | ||
259 | } | ||
260 | |||
261 | static int adv7343_log_status(struct v4l2_subdev *sd) | ||
262 | { | ||
263 | struct adv7343_state *state = to_state(sd); | ||
264 | |||
265 | v4l2_info(sd, "Standard: %llx\n", (unsigned long long)state->std); | ||
266 | v4l2_info(sd, "Output: %s\n", (state->output == 0) ? "Composite" : | ||
267 | ((state->output == 1) ? "Component" : "S-Video")); | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static int adv7343_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | ||
272 | { | ||
273 | switch (qc->id) { | ||
274 | case V4L2_CID_BRIGHTNESS: | ||
275 | return v4l2_ctrl_query_fill(qc, ADV7343_BRIGHTNESS_MIN, | ||
276 | ADV7343_BRIGHTNESS_MAX, 1, | ||
277 | ADV7343_BRIGHTNESS_DEF); | ||
278 | case V4L2_CID_HUE: | ||
279 | return v4l2_ctrl_query_fill(qc, ADV7343_HUE_MIN, | ||
280 | ADV7343_HUE_MAX, 1 , | ||
281 | ADV7343_HUE_DEF); | ||
282 | case V4L2_CID_GAIN: | ||
283 | return v4l2_ctrl_query_fill(qc, ADV7343_GAIN_MIN, | ||
284 | ADV7343_GAIN_MAX, 1, | ||
285 | ADV7343_GAIN_DEF); | ||
286 | default: | ||
287 | break; | ||
288 | } | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static int adv7343_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
294 | { | ||
295 | struct adv7343_state *state = to_state(sd); | ||
296 | int err = 0; | ||
297 | |||
298 | switch (ctrl->id) { | ||
299 | case V4L2_CID_BRIGHTNESS: | ||
300 | if (ctrl->value < ADV7343_BRIGHTNESS_MIN || | ||
301 | ctrl->value > ADV7343_BRIGHTNESS_MAX) { | ||
302 | v4l2_dbg(1, debug, sd, | ||
303 | "invalid brightness settings %d\n", | ||
304 | ctrl->value); | ||
305 | return -ERANGE; | ||
306 | } | ||
307 | |||
308 | state->bright = ctrl->value; | ||
309 | err = adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS, | ||
310 | state->bright); | ||
311 | break; | ||
312 | |||
313 | case V4L2_CID_HUE: | ||
314 | if (ctrl->value < ADV7343_HUE_MIN || | ||
315 | ctrl->value > ADV7343_HUE_MAX) { | ||
316 | v4l2_dbg(1, debug, sd, "invalid hue settings %d\n", | ||
317 | ctrl->value); | ||
318 | return -ERANGE; | ||
319 | } | ||
320 | |||
321 | state->hue = ctrl->value; | ||
322 | err = adv7343_write(sd, ADV7343_SD_HUE_REG, state->hue); | ||
323 | break; | ||
324 | |||
325 | case V4L2_CID_GAIN: | ||
326 | if (ctrl->value < ADV7343_GAIN_MIN || | ||
327 | ctrl->value > ADV7343_GAIN_MAX) { | ||
328 | v4l2_dbg(1, debug, sd, "invalid gain settings %d\n", | ||
329 | ctrl->value); | ||
330 | return -ERANGE; | ||
331 | } | ||
332 | |||
333 | if ((ctrl->value > POSITIVE_GAIN_MAX) && | ||
334 | (ctrl->value < NEGATIVE_GAIN_MIN)) { | ||
335 | v4l2_dbg(1, debug, sd, | ||
336 | "gain settings not within the specified range\n"); | ||
337 | return -ERANGE; | ||
338 | } | ||
339 | |||
340 | state->gain = ctrl->value; | ||
341 | err = adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, state->gain); | ||
342 | break; | ||
343 | |||
344 | default: | ||
345 | return -EINVAL; | ||
346 | } | ||
347 | |||
348 | if (err < 0) | ||
349 | v4l2_err(sd, "Failed to set the encoder controls\n"); | ||
350 | |||
351 | return err; | ||
352 | } | ||
353 | |||
354 | static int adv7343_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
355 | { | ||
356 | struct adv7343_state *state = to_state(sd); | ||
357 | |||
358 | switch (ctrl->id) { | ||
359 | case V4L2_CID_BRIGHTNESS: | ||
360 | ctrl->value = state->bright; | ||
361 | break; | ||
362 | |||
363 | case V4L2_CID_HUE: | ||
364 | ctrl->value = state->hue; | ||
365 | break; | ||
366 | |||
367 | case V4L2_CID_GAIN: | ||
368 | ctrl->value = state->gain; | ||
369 | break; | ||
370 | |||
371 | default: | ||
372 | return -EINVAL; | ||
373 | } | ||
374 | |||
375 | return 0; | ||
376 | } | ||
377 | |||
378 | static int adv7343_g_chip_ident(struct v4l2_subdev *sd, | ||
379 | struct v4l2_dbg_chip_ident *chip) | ||
380 | { | ||
381 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
382 | |||
383 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0); | ||
384 | } | ||
385 | |||
386 | static const struct v4l2_subdev_core_ops adv7343_core_ops = { | ||
387 | .log_status = adv7343_log_status, | ||
388 | .g_chip_ident = adv7343_g_chip_ident, | ||
389 | .g_ctrl = adv7343_g_ctrl, | ||
390 | .s_ctrl = adv7343_s_ctrl, | ||
391 | .queryctrl = adv7343_queryctrl, | ||
392 | }; | ||
393 | |||
394 | static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) | ||
395 | { | ||
396 | struct adv7343_state *state = to_state(sd); | ||
397 | int err = 0; | ||
398 | |||
399 | if (state->std == std) | ||
400 | return 0; | ||
401 | |||
402 | err = adv7343_setstd(sd, std); | ||
403 | if (!err) | ||
404 | state->std = std; | ||
405 | |||
406 | return err; | ||
407 | } | ||
408 | |||
409 | static int adv7343_s_routing(struct v4l2_subdev *sd, | ||
410 | u32 input, u32 output, u32 config) | ||
411 | { | ||
412 | struct adv7343_state *state = to_state(sd); | ||
413 | int err = 0; | ||
414 | |||
415 | if (state->output == output) | ||
416 | return 0; | ||
417 | |||
418 | err = adv7343_setoutput(sd, output); | ||
419 | if (!err) | ||
420 | state->output = output; | ||
421 | |||
422 | return err; | ||
423 | } | ||
424 | |||
425 | static const struct v4l2_subdev_video_ops adv7343_video_ops = { | ||
426 | .s_std_output = adv7343_s_std_output, | ||
427 | .s_routing = adv7343_s_routing, | ||
428 | }; | ||
429 | |||
430 | static const struct v4l2_subdev_ops adv7343_ops = { | ||
431 | .core = &adv7343_core_ops, | ||
432 | .video = &adv7343_video_ops, | ||
433 | }; | ||
434 | |||
435 | static int adv7343_initialize(struct v4l2_subdev *sd) | ||
436 | { | ||
437 | struct adv7343_state *state = to_state(sd); | ||
438 | int err = 0; | ||
439 | int i; | ||
440 | |||
441 | for (i = 0; i < ARRAY_SIZE(adv7343_init_reg_val); i += 2) { | ||
442 | |||
443 | err = adv7343_write(sd, adv7343_init_reg_val[i], | ||
444 | adv7343_init_reg_val[i+1]); | ||
445 | if (err) { | ||
446 | v4l2_err(sd, "Error initializing\n"); | ||
447 | return err; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | /* Configure for default video standard */ | ||
452 | err = adv7343_setoutput(sd, state->output); | ||
453 | if (err < 0) { | ||
454 | v4l2_err(sd, "Error setting output during init\n"); | ||
455 | return -EINVAL; | ||
456 | } | ||
457 | |||
458 | err = adv7343_setstd(sd, state->std); | ||
459 | if (err < 0) { | ||
460 | v4l2_err(sd, "Error setting std during init\n"); | ||
461 | return -EINVAL; | ||
462 | } | ||
463 | |||
464 | return err; | ||
465 | } | ||
466 | |||
467 | static int adv7343_probe(struct i2c_client *client, | ||
468 | const struct i2c_device_id *id) | ||
469 | { | ||
470 | struct adv7343_state *state; | ||
471 | |||
472 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
473 | return -ENODEV; | ||
474 | |||
475 | v4l_info(client, "chip found @ 0x%x (%s)\n", | ||
476 | client->addr << 1, client->adapter->name); | ||
477 | |||
478 | state = kzalloc(sizeof(struct adv7343_state), GFP_KERNEL); | ||
479 | if (state == NULL) | ||
480 | return -ENOMEM; | ||
481 | |||
482 | state->reg00 = 0x80; | ||
483 | state->reg01 = 0x00; | ||
484 | state->reg02 = 0x20; | ||
485 | state->reg35 = 0x00; | ||
486 | state->reg80 = ADV7343_SD_MODE_REG1_DEFAULT; | ||
487 | state->reg82 = ADV7343_SD_MODE_REG2_DEFAULT; | ||
488 | |||
489 | state->output = ADV7343_COMPOSITE_ID; | ||
490 | state->std = V4L2_STD_NTSC; | ||
491 | |||
492 | v4l2_i2c_subdev_init(&state->sd, client, &adv7343_ops); | ||
493 | return adv7343_initialize(&state->sd); | ||
494 | } | ||
495 | |||
496 | static int adv7343_remove(struct i2c_client *client) | ||
497 | { | ||
498 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
499 | |||
500 | v4l2_device_unregister_subdev(sd); | ||
501 | kfree(to_state(sd)); | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | static const struct i2c_device_id adv7343_id[] = { | ||
507 | {"adv7343", 0}, | ||
508 | {}, | ||
509 | }; | ||
510 | |||
511 | MODULE_DEVICE_TABLE(i2c, adv7343_id); | ||
512 | |||
513 | static struct i2c_driver adv7343_driver = { | ||
514 | .driver = { | ||
515 | .owner = THIS_MODULE, | ||
516 | .name = "adv7343", | ||
517 | }, | ||
518 | .probe = adv7343_probe, | ||
519 | .remove = adv7343_remove, | ||
520 | .id_table = adv7343_id, | ||
521 | }; | ||
522 | |||
523 | static __init int init_adv7343(void) | ||
524 | { | ||
525 | return i2c_add_driver(&adv7343_driver); | ||
526 | } | ||
527 | |||
528 | static __exit void exit_adv7343(void) | ||
529 | { | ||
530 | i2c_del_driver(&adv7343_driver); | ||
531 | } | ||
532 | |||
533 | module_init(init_adv7343); | ||
534 | module_exit(exit_adv7343); | ||
diff --git a/drivers/media/video/adv7343_regs.h b/drivers/media/video/adv7343_regs.h new file mode 100644 index 000000000000..3431045b33da --- /dev/null +++ b/drivers/media/video/adv7343_regs.h | |||
@@ -0,0 +1,185 @@ | |||
1 | /* | ||
2 | * ADV7343 encoder related structure and register definitions | ||
3 | * | ||
4 | * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed .as is. WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef ADV7343_REG_H | ||
17 | #define ADV7343_REGS_H | ||
18 | |||
19 | struct adv7343_std_info { | ||
20 | u32 standard_val3; | ||
21 | u32 fsc_val; | ||
22 | v4l2_std_id stdid; | ||
23 | }; | ||
24 | |||
25 | /* Register offset macros */ | ||
26 | #define ADV7343_POWER_MODE_REG (0x00) | ||
27 | #define ADV7343_MODE_SELECT_REG (0x01) | ||
28 | #define ADV7343_MODE_REG0 (0x02) | ||
29 | |||
30 | #define ADV7343_DAC2_OUTPUT_LEVEL (0x0b) | ||
31 | |||
32 | #define ADV7343_SOFT_RESET (0x17) | ||
33 | |||
34 | #define ADV7343_HD_MODE_REG1 (0x30) | ||
35 | #define ADV7343_HD_MODE_REG2 (0x31) | ||
36 | #define ADV7343_HD_MODE_REG3 (0x32) | ||
37 | #define ADV7343_HD_MODE_REG4 (0x33) | ||
38 | #define ADV7343_HD_MODE_REG5 (0x34) | ||
39 | #define ADV7343_HD_MODE_REG6 (0x35) | ||
40 | |||
41 | #define ADV7343_HD_MODE_REG7 (0x39) | ||
42 | |||
43 | #define ADV7343_SD_MODE_REG1 (0x80) | ||
44 | #define ADV7343_SD_MODE_REG2 (0x82) | ||
45 | #define ADV7343_SD_MODE_REG3 (0x83) | ||
46 | #define ADV7343_SD_MODE_REG4 (0x84) | ||
47 | #define ADV7343_SD_MODE_REG5 (0x86) | ||
48 | #define ADV7343_SD_MODE_REG6 (0x87) | ||
49 | #define ADV7343_SD_MODE_REG7 (0x88) | ||
50 | #define ADV7343_SD_MODE_REG8 (0x89) | ||
51 | |||
52 | #define ADV7343_FSC_REG0 (0x8C) | ||
53 | #define ADV7343_FSC_REG1 (0x8D) | ||
54 | #define ADV7343_FSC_REG2 (0x8E) | ||
55 | #define ADV7343_FSC_REG3 (0x8F) | ||
56 | |||
57 | #define ADV7343_SD_CGMS_WSS0 (0x99) | ||
58 | |||
59 | #define ADV7343_SD_HUE_REG (0xA0) | ||
60 | #define ADV7343_SD_BRIGHTNESS_WSS (0xA1) | ||
61 | |||
62 | /* Default values for the registers */ | ||
63 | #define ADV7343_POWER_MODE_REG_DEFAULT (0x10) | ||
64 | #define ADV7343_HD_MODE_REG1_DEFAULT (0x3C) /* Changed Default | ||
65 | 720p EAVSAV code*/ | ||
66 | #define ADV7343_HD_MODE_REG2_DEFAULT (0x01) /* Changed Pixel data | ||
67 | valid */ | ||
68 | #define ADV7343_HD_MODE_REG3_DEFAULT (0x00) /* Color delay 0 clks */ | ||
69 | #define ADV7343_HD_MODE_REG4_DEFAULT (0xE8) /* Changed */ | ||
70 | #define ADV7343_HD_MODE_REG5_DEFAULT (0x08) | ||
71 | #define ADV7343_HD_MODE_REG6_DEFAULT (0x00) | ||
72 | #define ADV7343_HD_MODE_REG7_DEFAULT (0x00) | ||
73 | #define ADV7343_SD_MODE_REG8_DEFAULT (0x00) | ||
74 | #define ADV7343_SOFT_RESET_DEFAULT (0x02) | ||
75 | #define ADV7343_COMPOSITE_POWER_VALUE (0x80) | ||
76 | #define ADV7343_COMPONENT_POWER_VALUE (0x1C) | ||
77 | #define ADV7343_SVIDEO_POWER_VALUE (0x60) | ||
78 | #define ADV7343_SD_HUE_REG_DEFAULT (127) | ||
79 | #define ADV7343_SD_BRIGHTNESS_WSS_DEFAULT (0x03) | ||
80 | |||
81 | #define ADV7343_SD_CGMS_WSS0_DEFAULT (0x10) | ||
82 | |||
83 | #define ADV7343_SD_MODE_REG1_DEFAULT (0x00) | ||
84 | #define ADV7343_SD_MODE_REG2_DEFAULT (0xC9) | ||
85 | #define ADV7343_SD_MODE_REG3_DEFAULT (0x10) | ||
86 | #define ADV7343_SD_MODE_REG4_DEFAULT (0x01) | ||
87 | #define ADV7343_SD_MODE_REG5_DEFAULT (0x02) | ||
88 | #define ADV7343_SD_MODE_REG6_DEFAULT (0x0C) | ||
89 | #define ADV7343_SD_MODE_REG7_DEFAULT (0x04) | ||
90 | #define ADV7343_SD_MODE_REG8_DEFAULT (0x00) | ||
91 | |||
92 | /* Bit masks for Mode Select Register */ | ||
93 | #define INPUT_MODE_MASK (0x70) | ||
94 | #define SD_INPUT_MODE (0x00) | ||
95 | #define HD_720P_INPUT_MODE (0x10) | ||
96 | #define HD_1080I_INPUT_MODE (0x10) | ||
97 | |||
98 | /* Bit masks for Mode Register 0 */ | ||
99 | #define TEST_PATTERN_BLACK_BAR_EN (0x04) | ||
100 | #define YUV_OUTPUT_SELECT (0x20) | ||
101 | #define RGB_OUTPUT_SELECT (0xDF) | ||
102 | |||
103 | /* Bit masks for DAC output levels */ | ||
104 | #define DAC_OUTPUT_LEVEL_MASK (0xFF) | ||
105 | #define POSITIVE_GAIN_MAX (0x40) | ||
106 | #define POSITIVE_GAIN_MIN (0x00) | ||
107 | #define NEGATIVE_GAIN_MAX (0xFF) | ||
108 | #define NEGATIVE_GAIN_MIN (0xC0) | ||
109 | |||
110 | /* Bit masks for soft reset register */ | ||
111 | #define SOFT_RESET (0x02) | ||
112 | |||
113 | /* Bit masks for HD Mode Register 1 */ | ||
114 | #define OUTPUT_STD_MASK (0x03) | ||
115 | #define OUTPUT_STD_SHIFT (0) | ||
116 | #define OUTPUT_STD_EIA0_2 (0x00) | ||
117 | #define OUTPUT_STD_EIA0_1 (0x01) | ||
118 | #define OUTPUT_STD_FULL (0x02) | ||
119 | #define EMBEDDED_SYNC (0x04) | ||
120 | #define EXTERNAL_SYNC (0xFB) | ||
121 | #define STD_MODE_SHIFT (3) | ||
122 | #define STD_MODE_MASK (0x1F) | ||
123 | #define STD_MODE_720P (0x05) | ||
124 | #define STD_MODE_720P_25 (0x08) | ||
125 | #define STD_MODE_720P_30 (0x07) | ||
126 | #define STD_MODE_720P_50 (0x06) | ||
127 | #define STD_MODE_1080I (0x0D) | ||
128 | #define STD_MODE_1080I_25fps (0x0E) | ||
129 | #define STD_MODE_1080P_24 (0x12) | ||
130 | #define STD_MODE_1080P_25 (0x10) | ||
131 | #define STD_MODE_1080P_30 (0x0F) | ||
132 | #define STD_MODE_525P (0x00) | ||
133 | #define STD_MODE_625P (0x03) | ||
134 | |||
135 | /* Bit masks for SD Mode Register 1 */ | ||
136 | #define SD_STD_MASK (0x03) | ||
137 | #define SD_STD_NTSC (0x00) | ||
138 | #define SD_STD_PAL_BDGHI (0x01) | ||
139 | #define SD_STD_PAL_M (0x02) | ||
140 | #define SD_STD_PAL_N (0x03) | ||
141 | #define SD_LUMA_FLTR_MASK (0x7) | ||
142 | #define SD_LUMA_FLTR_SHIFT (0x2) | ||
143 | #define SD_CHROMA_FLTR_MASK (0x7) | ||
144 | #define SD_CHROMA_FLTR_SHIFT (0x5) | ||
145 | |||
146 | /* Bit masks for SD Mode Register 2 */ | ||
147 | #define SD_PBPR_SSAF_EN (0x01) | ||
148 | #define SD_PBPR_SSAF_DI (0xFE) | ||
149 | #define SD_DAC_1_DI (0xFD) | ||
150 | #define SD_DAC_2_DI (0xFB) | ||
151 | #define SD_PEDESTAL_EN (0x08) | ||
152 | #define SD_PEDESTAL_DI (0xF7) | ||
153 | #define SD_SQUARE_PIXEL_EN (0x10) | ||
154 | #define SD_SQUARE_PIXEL_DI (0xEF) | ||
155 | #define SD_PIXEL_DATA_VALID (0x40) | ||
156 | #define SD_ACTIVE_EDGE_EN (0x80) | ||
157 | #define SD_ACTIVE_EDGE_DI (0x7F) | ||
158 | |||
159 | /* Bit masks for HD Mode Register 6 */ | ||
160 | #define HD_RGB_INPUT_EN (0x02) | ||
161 | #define HD_RGB_INPUT_DI (0xFD) | ||
162 | #define HD_PBPR_SYNC_EN (0x04) | ||
163 | #define HD_PBPR_SYNC_DI (0xFB) | ||
164 | #define HD_DAC_SWAP_EN (0x08) | ||
165 | #define HD_DAC_SWAP_DI (0xF7) | ||
166 | #define HD_GAMMA_CURVE_A (0xEF) | ||
167 | #define HD_GAMMA_CURVE_B (0x10) | ||
168 | #define HD_GAMMA_EN (0x20) | ||
169 | #define HD_GAMMA_DI (0xDF) | ||
170 | #define HD_ADPT_FLTR_MODEB (0x40) | ||
171 | #define HD_ADPT_FLTR_MODEA (0xBF) | ||
172 | #define HD_ADPT_FLTR_EN (0x80) | ||
173 | #define HD_ADPT_FLTR_DI (0x7F) | ||
174 | |||
175 | #define ADV7343_BRIGHTNESS_MAX (127) | ||
176 | #define ADV7343_BRIGHTNESS_MIN (0) | ||
177 | #define ADV7343_BRIGHTNESS_DEF (3) | ||
178 | #define ADV7343_HUE_MAX (255) | ||
179 | #define ADV7343_HUE_MIN (0) | ||
180 | #define ADV7343_HUE_DEF (127) | ||
181 | #define ADV7343_GAIN_MAX (255) | ||
182 | #define ADV7343_GAIN_MIN (0) | ||
183 | #define ADV7343_GAIN_DEF (0) | ||
184 | |||
185 | #endif | ||
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 053bbe8c8e3a..830c4a933f63 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c | |||
@@ -136,9 +136,9 @@ int au0828_tuner_callback(void *priv, int component, int command, int arg) | |||
136 | /* Tuner Reset Command from xc5000 */ | 136 | /* Tuner Reset Command from xc5000 */ |
137 | /* Drive the tuner into reset and out */ | 137 | /* Drive the tuner into reset and out */ |
138 | au0828_clear(dev, REG_001, 2); | 138 | au0828_clear(dev, REG_001, 2); |
139 | mdelay(200); | 139 | mdelay(10); |
140 | au0828_set(dev, REG_001, 2); | 140 | au0828_set(dev, REG_001, 2); |
141 | mdelay(50); | 141 | mdelay(10); |
142 | return 0; | 142 | return 0; |
143 | } else { | 143 | } else { |
144 | printk(KERN_ERR | 144 | printk(KERN_ERR |
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c index a1e4c0d769a6..3544a2f12f13 100644 --- a/drivers/media/video/au0828/au0828-core.c +++ b/drivers/media/video/au0828/au0828-core.c | |||
@@ -36,6 +36,11 @@ int au0828_debug; | |||
36 | module_param_named(debug, au0828_debug, int, 0644); | 36 | module_param_named(debug, au0828_debug, int, 0644); |
37 | MODULE_PARM_DESC(debug, "enable debug messages"); | 37 | MODULE_PARM_DESC(debug, "enable debug messages"); |
38 | 38 | ||
39 | static unsigned int disable_usb_speed_check; | ||
40 | module_param(disable_usb_speed_check, int, 0444); | ||
41 | MODULE_PARM_DESC(disable_usb_speed_check, | ||
42 | "override min bandwidth requirement of 480M bps"); | ||
43 | |||
39 | #define _AU0828_BULKPIPE 0x03 | 44 | #define _AU0828_BULKPIPE 0x03 |
40 | #define _BULKPIPESIZE 0xffff | 45 | #define _BULKPIPESIZE 0xffff |
41 | 46 | ||
@@ -181,6 +186,18 @@ static int au0828_usb_probe(struct usb_interface *interface, | |||
181 | le16_to_cpu(usbdev->descriptor.idProduct), | 186 | le16_to_cpu(usbdev->descriptor.idProduct), |
182 | ifnum); | 187 | ifnum); |
183 | 188 | ||
189 | /* | ||
190 | * Make sure we have 480 Mbps of bandwidth, otherwise things like | ||
191 | * video stream wouldn't likely work, since 12 Mbps is generally | ||
192 | * not enough even for most Digital TV streams. | ||
193 | */ | ||
194 | if (usbdev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { | ||
195 | printk(KERN_ERR "au0828: Device initialization failed.\n"); | ||
196 | printk(KERN_ERR "au0828: Device must be connected to a " | ||
197 | "high-speed USB 2.0 port.\n"); | ||
198 | return -ENODEV; | ||
199 | } | ||
200 | |||
184 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 201 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
185 | if (dev == NULL) { | 202 | if (dev == NULL) { |
186 | printk(KERN_ERR "%s() Unable to allocate memory\n", __func__); | 203 | printk(KERN_ERR "%s() Unable to allocate memory\n", __func__); |
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index 27bedc6c7791..51527d7b55a7 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c | |||
@@ -829,6 +829,9 @@ static int au0828_v4l2_close(struct file *filp) | |||
829 | 829 | ||
830 | au0828_uninit_isoc(dev); | 830 | au0828_uninit_isoc(dev); |
831 | 831 | ||
832 | /* Save some power by putting tuner to sleep */ | ||
833 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby); | ||
834 | |||
832 | /* When close the device, set the usb intf0 into alt0 to free | 835 | /* When close the device, set the usb intf0 into alt0 to free |
833 | USB bandwidth */ | 836 | USB bandwidth */ |
834 | ret = usb_set_interface(dev->usbdev, 0, 0); | 837 | ret = usb_set_interface(dev->usbdev, 0, 0); |
@@ -910,11 +913,6 @@ static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
910 | 913 | ||
911 | rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); | 914 | rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); |
912 | 915 | ||
913 | dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n", | ||
914 | (unsigned long)vma->vm_start, | ||
915 | (unsigned long)vma->vm_end-(unsigned long)vma->vm_start, | ||
916 | rc); | ||
917 | |||
918 | return rc; | 916 | return rc; |
919 | } | 917 | } |
920 | 918 | ||
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 23b7499b3185..5eb1464af670 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -3152,6 +3152,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3152 | struct bttv_fh *fh = file->private_data; | 3152 | struct bttv_fh *fh = file->private_data; |
3153 | struct bttv_buffer *buf; | 3153 | struct bttv_buffer *buf; |
3154 | enum v4l2_field field; | 3154 | enum v4l2_field field; |
3155 | unsigned int rc = POLLERR; | ||
3155 | 3156 | ||
3156 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { | 3157 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { |
3157 | if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) | 3158 | if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) |
@@ -3160,9 +3161,10 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3160 | } | 3161 | } |
3161 | 3162 | ||
3162 | if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { | 3163 | if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { |
3164 | mutex_lock(&fh->cap.vb_lock); | ||
3163 | /* streaming capture */ | 3165 | /* streaming capture */ |
3164 | if (list_empty(&fh->cap.stream)) | 3166 | if (list_empty(&fh->cap.stream)) |
3165 | return POLLERR; | 3167 | goto err; |
3166 | buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); | 3168 | buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); |
3167 | } else { | 3169 | } else { |
3168 | /* read() capture */ | 3170 | /* read() capture */ |
@@ -3191,11 +3193,12 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3191 | poll_wait(file, &buf->vb.done, wait); | 3193 | poll_wait(file, &buf->vb.done, wait); |
3192 | if (buf->vb.state == VIDEOBUF_DONE || | 3194 | if (buf->vb.state == VIDEOBUF_DONE || |
3193 | buf->vb.state == VIDEOBUF_ERROR) | 3195 | buf->vb.state == VIDEOBUF_ERROR) |
3194 | return POLLIN|POLLRDNORM; | 3196 | rc = POLLIN|POLLRDNORM; |
3195 | return 0; | 3197 | else |
3198 | rc = 0; | ||
3196 | err: | 3199 | err: |
3197 | mutex_unlock(&fh->cap.vb_lock); | 3200 | mutex_unlock(&fh->cap.vb_lock); |
3198 | return POLLERR; | 3201 | return rc; |
3199 | } | 3202 | } |
3200 | 3203 | ||
3201 | static int bttv_open(struct file *file) | 3204 | static int bttv_open(struct file *file) |
@@ -4166,7 +4169,6 @@ static struct video_device *vdev_init(struct bttv *btv, | |||
4166 | if (NULL == vfd) | 4169 | if (NULL == vfd) |
4167 | return NULL; | 4170 | return NULL; |
4168 | *vfd = *template; | 4171 | *vfd = *template; |
4169 | vfd->minor = -1; | ||
4170 | vfd->v4l2_dev = &btv->c.v4l2_dev; | 4172 | vfd->v4l2_dev = &btv->c.v4l2_dev; |
4171 | vfd->release = video_device_release; | 4173 | vfd->release = video_device_release; |
4172 | vfd->debug = bttv_debug; | 4174 | vfd->debug = bttv_debug; |
@@ -4629,7 +4631,7 @@ static int __init bttv_init_module(void) | |||
4629 | #endif | 4631 | #endif |
4630 | if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) | 4632 | if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) |
4631 | gbuffers = 2; | 4633 | gbuffers = 2; |
4632 | if (gbufsize < 0 || gbufsize > BTTV_MAX_FBUF) | 4634 | if (gbufsize > BTTV_MAX_FBUF) |
4633 | gbufsize = BTTV_MAX_FBUF; | 4635 | gbufsize = BTTV_MAX_FBUF; |
4634 | gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK; | 4636 | gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK; |
4635 | if (bttv_verbose) | 4637 | if (bttv_verbose) |
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index a99d92fac3dc..ebd1ee9dc871 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c | |||
@@ -389,6 +389,27 @@ int __devinit init_bttv_i2c(struct bttv *btv) | |||
389 | } | 389 | } |
390 | if (0 == btv->i2c_rc && i2c_scan) | 390 | if (0 == btv->i2c_rc && i2c_scan) |
391 | do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); | 391 | do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); |
392 | |||
393 | /* Instantiate the IR receiver device, if present */ | ||
394 | if (0 == btv->i2c_rc) { | ||
395 | struct i2c_board_info info; | ||
396 | /* The external IR receiver is at i2c address 0x34 (0x35 for | ||
397 | reads). Future Hauppauge cards will have an internal | ||
398 | receiver at 0x30 (0x31 for reads). In theory, both can be | ||
399 | fitted, and Hauppauge suggest an external overrides an | ||
400 | internal. | ||
401 | |||
402 | That's why we probe 0x1a (~0x34) first. CB | ||
403 | */ | ||
404 | const unsigned short addr_list[] = { | ||
405 | 0x1a, 0x18, 0x4b, 0x64, 0x30, | ||
406 | I2C_CLIENT_END | ||
407 | }; | ||
408 | |||
409 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
410 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
411 | i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list); | ||
412 | } | ||
392 | return btv->i2c_rc; | 413 | return btv->i2c_rc; |
393 | } | 414 | } |
394 | 415 | ||
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index d4099f5312ac..0b4a8f309cfa 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c | |||
@@ -1064,7 +1064,7 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam) | |||
1064 | 1064 | ||
1065 | switch(m->id) { | 1065 | switch(m->id) { |
1066 | case CPIA2_CID_FLICKER_MODE: | 1066 | case CPIA2_CID_FLICKER_MODE: |
1067 | if(m->index < 0 || m->index >= NUM_FLICKER_CONTROLS) | 1067 | if (m->index >= NUM_FLICKER_CONTROLS) |
1068 | return -EINVAL; | 1068 | return -EINVAL; |
1069 | 1069 | ||
1070 | strcpy(m->name, flicker_controls[m->index].name); | 1070 | strcpy(m->name, flicker_controls[m->index].name); |
@@ -1082,14 +1082,14 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam) | |||
1082 | maximum = i; | 1082 | maximum = i; |
1083 | } | 1083 | } |
1084 | } | 1084 | } |
1085 | if(m->index < 0 || m->index > maximum) | 1085 | if (m->index > maximum) |
1086 | return -EINVAL; | 1086 | return -EINVAL; |
1087 | 1087 | ||
1088 | strcpy(m->name, framerate_controls[m->index].name); | 1088 | strcpy(m->name, framerate_controls[m->index].name); |
1089 | break; | 1089 | break; |
1090 | } | 1090 | } |
1091 | case CPIA2_CID_LIGHTS: | 1091 | case CPIA2_CID_LIGHTS: |
1092 | if(m->index < 0 || m->index >= NUM_LIGHTS_CONTROLS) | 1092 | if (m->index >= NUM_LIGHTS_CONTROLS) |
1093 | return -EINVAL; | 1093 | return -EINVAL; |
1094 | 1094 | ||
1095 | strcpy(m->name, lights_controls[m->index].name); | 1095 | strcpy(m->name, lights_controls[m->index].name); |
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c index 7a8ad5963de8..35268923911c 100644 --- a/drivers/media/video/cx18/cx18-audio.c +++ b/drivers/media/video/cx18/cx18-audio.c | |||
@@ -26,14 +26,18 @@ | |||
26 | #include "cx18-cards.h" | 26 | #include "cx18-cards.h" |
27 | #include "cx18-audio.h" | 27 | #include "cx18-audio.h" |
28 | 28 | ||
29 | #define CX18_AUDIO_ENABLE 0xc72014 | 29 | #define CX18_AUDIO_ENABLE 0xc72014 |
30 | #define CX18_AI1_MUX_MASK 0x30 | ||
31 | #define CX18_AI1_MUX_I2S1 0x00 | ||
32 | #define CX18_AI1_MUX_I2S2 0x10 | ||
33 | #define CX18_AI1_MUX_843_I2S 0x20 | ||
30 | 34 | ||
31 | /* Selects the audio input and output according to the current | 35 | /* Selects the audio input and output according to the current |
32 | settings. */ | 36 | settings. */ |
33 | int cx18_audio_set_io(struct cx18 *cx) | 37 | int cx18_audio_set_io(struct cx18 *cx) |
34 | { | 38 | { |
35 | const struct cx18_card_audio_input *in; | 39 | const struct cx18_card_audio_input *in; |
36 | u32 val; | 40 | u32 u, v; |
37 | int err; | 41 | int err; |
38 | 42 | ||
39 | /* Determine which input to use */ | 43 | /* Determine which input to use */ |
@@ -52,9 +56,37 @@ int cx18_audio_set_io(struct cx18 *cx) | |||
52 | return err; | 56 | return err; |
53 | 57 | ||
54 | /* FIXME - this internal mux should be abstracted to a subdev */ | 58 | /* FIXME - this internal mux should be abstracted to a subdev */ |
55 | val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30; | 59 | u = cx18_read_reg(cx, CX18_AUDIO_ENABLE); |
56 | val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : | 60 | v = u & ~CX18_AI1_MUX_MASK; |
57 | (in->audio_input << 4); | 61 | switch (in->audio_input) { |
58 | cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30); | 62 | case CX18_AV_AUDIO_SERIAL1: |
63 | v |= CX18_AI1_MUX_I2S1; | ||
64 | break; | ||
65 | case CX18_AV_AUDIO_SERIAL2: | ||
66 | v |= CX18_AI1_MUX_I2S2; | ||
67 | break; | ||
68 | default: | ||
69 | v |= CX18_AI1_MUX_843_I2S; | ||
70 | break; | ||
71 | } | ||
72 | if (v == u) { | ||
73 | /* force a toggle of some AI1 MUX control bits */ | ||
74 | u &= ~CX18_AI1_MUX_MASK; | ||
75 | switch (in->audio_input) { | ||
76 | case CX18_AV_AUDIO_SERIAL1: | ||
77 | u |= CX18_AI1_MUX_843_I2S; | ||
78 | break; | ||
79 | case CX18_AV_AUDIO_SERIAL2: | ||
80 | u |= CX18_AI1_MUX_843_I2S; | ||
81 | break; | ||
82 | default: | ||
83 | u |= CX18_AI1_MUX_I2S1; | ||
84 | break; | ||
85 | } | ||
86 | cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE, | ||
87 | u, CX18_AI1_MUX_MASK); | ||
88 | } | ||
89 | cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE, | ||
90 | v, CX18_AI1_MUX_MASK); | ||
59 | return 0; | 91 | return 0; |
60 | } | 92 | } |
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index cf2bd888a429..536dedb23ba3 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c | |||
@@ -99,9 +99,39 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, | |||
99 | or_value); | 99 | or_value); |
100 | } | 100 | } |
101 | 101 | ||
102 | static void cx18_av_initialize(struct cx18 *cx) | 102 | static int cx18_av_init(struct v4l2_subdev *sd, u32 val) |
103 | { | 103 | { |
104 | struct cx18_av_state *state = &cx->av_state; | 104 | struct cx18 *cx = v4l2_get_subdevdata(sd); |
105 | |||
106 | /* | ||
107 | * The crystal freq used in calculations in this driver will be | ||
108 | * 28.636360 MHz. | ||
109 | * Aim to run the PLLs' VCOs near 400 MHz to minimze errors. | ||
110 | */ | ||
111 | |||
112 | /* | ||
113 | * VDCLK Integer = 0x0f, Post Divider = 0x04 | ||
114 | * AIMCLK Integer = 0x0e, Post Divider = 0x16 | ||
115 | */ | ||
116 | cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f); | ||
117 | |||
118 | /* VDCLK Fraction = 0x2be2fe */ | ||
119 | /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */ | ||
120 | cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe); | ||
121 | |||
122 | /* AIMCLK Fraction = 0x05227ad */ | ||
123 | /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/ | ||
124 | cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad); | ||
125 | |||
126 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ | ||
127 | cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static void cx18_av_initialize(struct v4l2_subdev *sd) | ||
132 | { | ||
133 | struct cx18_av_state *state = to_cx18_av_state(sd); | ||
134 | struct cx18 *cx = v4l2_get_subdevdata(sd); | ||
105 | u32 v; | 135 | u32 v; |
106 | 136 | ||
107 | cx18_av_loadfw(cx); | 137 | cx18_av_loadfw(cx); |
@@ -150,6 +180,26 @@ static void cx18_av_initialize(struct cx18 *cx) | |||
150 | cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000); | 180 | cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000); |
151 | cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0); | 181 | cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0); |
152 | 182 | ||
183 | /* | ||
184 | * Disable Video Auto-config of the Analog Front End and Video PLL. | ||
185 | * | ||
186 | * Since we only use BT.656 pixel mode, which works for both 525 and 625 | ||
187 | * line systems, it's just easier for us to set registers | ||
188 | * 0x102 (CXADEC_CHIP_CTRL), 0x104-0x106 (CXADEC_AFE_CTRL), | ||
189 | * 0x108-0x109 (CXADEC_PLL_CTRL1), and 0x10c-0x10f (CXADEC_VID_PLL_FRAC) | ||
190 | * ourselves, than to run around cleaning up after the auto-config. | ||
191 | * | ||
192 | * (Note: my CX23418 chip doesn't seem to let the ACFG_DIS bit | ||
193 | * get set to 1, but OTOH, it doesn't seem to do AFE and VID PLL | ||
194 | * autoconfig either.) | ||
195 | * | ||
196 | * As a default, also turn off Dual mode for ADC2 and set ADC2 to CH3. | ||
197 | */ | ||
198 | cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000); | ||
199 | |||
200 | /* Setup the Video and and Aux/Audio PLLs */ | ||
201 | cx18_av_init(sd, 0); | ||
202 | |||
153 | /* set video to auto-detect */ | 203 | /* set video to auto-detect */ |
154 | /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */ | 204 | /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */ |
155 | /* set the comb notch = 1 */ | 205 | /* set the comb notch = 1 */ |
@@ -176,12 +226,23 @@ static void cx18_av_initialize(struct cx18 *cx) | |||
176 | /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */ | 226 | /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */ |
177 | /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */ | 227 | /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */ |
178 | 228 | ||
179 | v = cx18_av_read4(cx, CXADEC_AFE_CTRL); | 229 | /* |
180 | v &= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */ | 230 | * Analog Front End (AFE) |
181 | v &= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */ | 231 | * Default to luma on ch1/ADC1, chroma on ch2/ADC2, SIF on ch3/ADC2 |
182 | v &= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */ | 232 | * bypass_ch[1-3] use filter |
183 | /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */ | 233 | * droop_comp_ch[1-3] disable |
184 | cx18_av_write4(cx, CXADEC_AFE_CTRL, v); | 234 | * clamp_en_ch[1-3] disable |
235 | * aud_in_sel ADC2 | ||
236 | * luma_in_sel ADC1 | ||
237 | * chroma_in_sel ADC2 | ||
238 | * clamp_sel_ch[2-3] midcode | ||
239 | * clamp_sel_ch1 video decoder | ||
240 | * vga_sel_ch3 audio decoder | ||
241 | * vga_sel_ch[1-2] video decoder | ||
242 | * half_bw_ch[1-3] disable | ||
243 | * +12db_ch[1-3] disable | ||
244 | */ | ||
245 | cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00); | ||
185 | 246 | ||
186 | /* if(dwEnable && dw3DCombAvailable) { */ | 247 | /* if(dwEnable && dw3DCombAvailable) { */ |
187 | /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */ | 248 | /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */ |
@@ -195,50 +256,18 @@ static void cx18_av_initialize(struct cx18 *cx) | |||
195 | 256 | ||
196 | static int cx18_av_reset(struct v4l2_subdev *sd, u32 val) | 257 | static int cx18_av_reset(struct v4l2_subdev *sd, u32 val) |
197 | { | 258 | { |
198 | struct cx18 *cx = v4l2_get_subdevdata(sd); | 259 | cx18_av_initialize(sd); |
199 | |||
200 | cx18_av_initialize(cx); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int cx18_av_init(struct v4l2_subdev *sd, u32 val) | ||
205 | { | ||
206 | struct cx18 *cx = v4l2_get_subdevdata(sd); | ||
207 | |||
208 | /* | ||
209 | * The crystal freq used in calculations in this driver will be | ||
210 | * 28.636360 MHz. | ||
211 | * Aim to run the PLLs' VCOs near 400 MHz to minimze errors. | ||
212 | */ | ||
213 | |||
214 | /* | ||
215 | * VDCLK Integer = 0x0f, Post Divider = 0x04 | ||
216 | * AIMCLK Integer = 0x0e, Post Divider = 0x16 | ||
217 | */ | ||
218 | cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f); | ||
219 | |||
220 | /* VDCLK Fraction = 0x2be2fe */ | ||
221 | /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */ | ||
222 | cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe); | ||
223 | |||
224 | /* AIMCLK Fraction = 0x05227ad */ | ||
225 | /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/ | ||
226 | cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad); | ||
227 | |||
228 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ | ||
229 | cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); | ||
230 | return 0; | 260 | return 0; |
231 | } | 261 | } |
232 | 262 | ||
233 | static int cx18_av_load_fw(struct v4l2_subdev *sd) | 263 | static int cx18_av_load_fw(struct v4l2_subdev *sd) |
234 | { | 264 | { |
235 | struct cx18_av_state *state = to_cx18_av_state(sd); | 265 | struct cx18_av_state *state = to_cx18_av_state(sd); |
236 | struct cx18 *cx = v4l2_get_subdevdata(sd); | ||
237 | 266 | ||
238 | if (!state->is_initialized) { | 267 | if (!state->is_initialized) { |
239 | /* initialize on first use */ | 268 | /* initialize on first use */ |
240 | state->is_initialized = 1; | 269 | state->is_initialized = 1; |
241 | cx18_av_initialize(cx); | 270 | cx18_av_initialize(sd); |
242 | } | 271 | } |
243 | return 0; | 272 | return 0; |
244 | } | 273 | } |
@@ -248,8 +277,15 @@ void cx18_av_std_setup(struct cx18 *cx) | |||
248 | struct cx18_av_state *state = &cx->av_state; | 277 | struct cx18_av_state *state = &cx->av_state; |
249 | struct v4l2_subdev *sd = &state->sd; | 278 | struct v4l2_subdev *sd = &state->sd; |
250 | v4l2_std_id std = state->std; | 279 | v4l2_std_id std = state->std; |
280 | |||
281 | /* | ||
282 | * Video ADC crystal clock to pixel clock SRC decimation ratio | ||
283 | * 28.636360 MHz/13.5 Mpps * 256 = 0x21f.07b | ||
284 | */ | ||
285 | const int src_decimation = 0x21f; | ||
286 | |||
251 | int hblank, hactive, burst, vblank, vactive, sc; | 287 | int hblank, hactive, burst, vblank, vactive, sc; |
252 | int vblank656, src_decimation; | 288 | int vblank656; |
253 | int luma_lpf, uv_lpf, comb; | 289 | int luma_lpf, uv_lpf, comb; |
254 | u32 pll_int, pll_frac, pll_post; | 290 | u32 pll_int, pll_frac, pll_post; |
255 | 291 | ||
@@ -259,40 +295,96 @@ void cx18_av_std_setup(struct cx18 *cx) | |||
259 | else | 295 | else |
260 | cx18_av_write(cx, 0x49f, 0x14); | 296 | cx18_av_write(cx, 0x49f, 0x14); |
261 | 297 | ||
298 | /* | ||
299 | * Note: At the end of a field, there are 3 sets of half line duration | ||
300 | * (double horizontal rate) pulses: | ||
301 | * | ||
302 | * 5 (625) or 6 (525) half-lines to blank for the vertical retrace | ||
303 | * 5 (625) or 6 (525) vertical sync pulses of half line duration | ||
304 | * 5 (625) or 6 (525) half-lines of equalization pulses | ||
305 | */ | ||
262 | if (std & V4L2_STD_625_50) { | 306 | if (std & V4L2_STD_625_50) { |
263 | /* FIXME - revisit these for Sliced VBI */ | 307 | /* |
308 | * The following relationships of half line counts should hold: | ||
309 | * 625 = vblank656 + vactive | ||
310 | * 10 = vblank656 - vblank = vsync pulses + equalization pulses | ||
311 | * | ||
312 | * vblank656: half lines after line 625/mid-313 of blanked video | ||
313 | * vblank: half lines, after line 5/317, of blanked video | ||
314 | * vactive: half lines of active video + | ||
315 | * 5 half lines after the end of active video | ||
316 | * | ||
317 | * As far as I can tell: | ||
318 | * vblank656 starts counting from the falling edge of the first | ||
319 | * vsync pulse (start of line 1 or mid-313) | ||
320 | * vblank starts counting from the after the 5 vsync pulses and | ||
321 | * 5 or 4 equalization pulses (start of line 6 or 318) | ||
322 | * | ||
323 | * For 625 line systems the driver will extract VBI information | ||
324 | * from lines 6-23 and lines 318-335 (but the slicer can only | ||
325 | * handle 17 lines, not the 18 in the vblank region). | ||
326 | * In addition, we need vblank656 and vblank to be one whole | ||
327 | * line longer, to cover line 24 and 336, so the SAV/EAV RP | ||
328 | * codes get generated such that the encoder can actually | ||
329 | * extract line 23 & 335 (WSS). We'll lose 1 line in each field | ||
330 | * at the top of the screen. | ||
331 | * | ||
332 | * It appears the 5 half lines that happen after active | ||
333 | * video must be included in vactive (579 instead of 574), | ||
334 | * otherwise the colors get badly displayed in various regions | ||
335 | * of the screen. I guess the chroma comb filter gets confused | ||
336 | * without them (at least when a PVR-350 is the PAL source). | ||
337 | */ | ||
338 | vblank656 = 48; /* lines 1 - 24 & 313 - 336 */ | ||
339 | vblank = 38; /* lines 6 - 24 & 318 - 336 */ | ||
340 | vactive = 579; /* lines 24 - 313 & 337 - 626 */ | ||
341 | |||
342 | /* | ||
343 | * For a 13.5 Mpps clock and 15,625 Hz line rate, a line is | ||
344 | * is 864 pixels = 720 active + 144 blanking. ITU-R BT.601 | ||
345 | * specifies 12 luma clock periods or ~ 0.9 * 13.5 Mpps after | ||
346 | * the end of active video to start a horizontal line, so that | ||
347 | * leaves 132 pixels of hblank to ignore. | ||
348 | */ | ||
264 | hblank = 132; | 349 | hblank = 132; |
265 | hactive = 720; | 350 | hactive = 720; |
266 | burst = 93; | ||
267 | vblank = 36; | ||
268 | vactive = 580; | ||
269 | vblank656 = 40; | ||
270 | src_decimation = 0x21f; | ||
271 | 351 | ||
352 | /* | ||
353 | * Burst gate delay (for 625 line systems) | ||
354 | * Hsync leading edge to color burst rise = 5.6 us | ||
355 | * Color burst width = 2.25 us | ||
356 | * Gate width = 4 pixel clocks | ||
357 | * (5.6 us + 2.25/2 us) * 13.5 Mpps + 4/2 clocks = 92.79 clocks | ||
358 | */ | ||
359 | burst = 93; | ||
272 | luma_lpf = 2; | 360 | luma_lpf = 2; |
273 | if (std & V4L2_STD_PAL) { | 361 | if (std & V4L2_STD_PAL) { |
274 | uv_lpf = 1; | 362 | uv_lpf = 1; |
275 | comb = 0x20; | 363 | comb = 0x20; |
276 | sc = 688739; | 364 | /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */ |
365 | sc = 688700; | ||
277 | } else if (std == V4L2_STD_PAL_Nc) { | 366 | } else if (std == V4L2_STD_PAL_Nc) { |
278 | uv_lpf = 1; | 367 | uv_lpf = 1; |
279 | comb = 0x20; | 368 | comb = 0x20; |
280 | sc = 556453; | 369 | /* sc = 3582056.25 * src_decimation/28636360 * 2^13 */ |
370 | sc = 556422; | ||
281 | } else { /* SECAM */ | 371 | } else { /* SECAM */ |
282 | uv_lpf = 0; | 372 | uv_lpf = 0; |
283 | comb = 0; | 373 | comb = 0; |
284 | sc = 672351; | 374 | /* (fr + fb)/2 = (4406260 + 4250000)/2 = 4328130 */ |
375 | /* sc = 4328130 * src_decimation/28636360 * 2^13 */ | ||
376 | sc = 672314; | ||
285 | } | 377 | } |
286 | } else { | 378 | } else { |
287 | /* | 379 | /* |
288 | * The following relationships of half line counts should hold: | 380 | * The following relationships of half line counts should hold: |
289 | * 525 = vsync + vactive + vblank656 | 381 | * 525 = prevsync + vblank656 + vactive |
290 | * 12 = vblank656 - vblank | 382 | * 12 = vblank656 - vblank = vsync pulses + equalization pulses |
291 | * | 383 | * |
292 | * vsync: always 6 half-lines of vsync pulses | 384 | * prevsync: 6 half-lines before the vsync pulses |
293 | * vactive: half lines of active video | ||
294 | * vblank656: half lines, after line 3/mid-266, of blanked video | 385 | * vblank656: half lines, after line 3/mid-266, of blanked video |
295 | * vblank: half lines, after line 9/272, of blanked video | 386 | * vblank: half lines, after line 9/272, of blanked video |
387 | * vactive: half lines of active video | ||
296 | * | 388 | * |
297 | * As far as I can tell: | 389 | * As far as I can tell: |
298 | * vblank656 starts counting from the falling edge of the first | 390 | * vblank656 starts counting from the falling edge of the first |
@@ -319,20 +411,30 @@ void cx18_av_std_setup(struct cx18 *cx) | |||
319 | luma_lpf = 1; | 411 | luma_lpf = 1; |
320 | uv_lpf = 1; | 412 | uv_lpf = 1; |
321 | 413 | ||
322 | src_decimation = 0x21f; | 414 | /* |
415 | * Burst gate delay (for 525 line systems) | ||
416 | * Hsync leading edge to color burst rise = 5.3 us | ||
417 | * Color burst width = 2.5 us | ||
418 | * Gate width = 4 pixel clocks | ||
419 | * (5.3 us + 2.5/2 us) * 13.5 Mpps + 4/2 clocks = 90.425 clocks | ||
420 | */ | ||
323 | if (std == V4L2_STD_PAL_60) { | 421 | if (std == V4L2_STD_PAL_60) { |
324 | burst = 0x5b; | 422 | burst = 90; |
325 | luma_lpf = 2; | 423 | luma_lpf = 2; |
326 | comb = 0x20; | 424 | comb = 0x20; |
327 | sc = 688739; | 425 | /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */ |
426 | sc = 688700; | ||
328 | } else if (std == V4L2_STD_PAL_M) { | 427 | } else if (std == V4L2_STD_PAL_M) { |
329 | burst = 0x61; | 428 | /* The 97 needs to be verified against PAL-M timings */ |
429 | burst = 97; | ||
330 | comb = 0x20; | 430 | comb = 0x20; |
331 | sc = 555452; | 431 | /* sc = 3575611.49 * src_decimation/28636360 * 2^13 */ |
432 | sc = 555421; | ||
332 | } else { | 433 | } else { |
333 | burst = 0x5b; | 434 | burst = 90; |
334 | comb = 0x66; | 435 | comb = 0x66; |
335 | sc = 556063; | 436 | /* sc = 3579545.45.. * src_decimation/28636360 * 2^13 */ |
437 | sc = 556032; | ||
336 | } | 438 | } |
337 | } | 439 | } |
338 | 440 | ||
@@ -344,23 +446,26 @@ void cx18_av_std_setup(struct cx18 *cx) | |||
344 | pll_int, pll_frac, pll_post); | 446 | pll_int, pll_frac, pll_post); |
345 | 447 | ||
346 | if (pll_post) { | 448 | if (pll_post) { |
347 | int fin, fsc, pll; | 449 | int fsc, pll; |
450 | u64 tmp; | ||
348 | 451 | ||
349 | pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25; | 452 | pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25; |
350 | pll /= pll_post; | 453 | pll /= pll_post; |
351 | CX18_DEBUG_INFO_DEV(sd, "PLL = %d.%06d MHz\n", | 454 | CX18_DEBUG_INFO_DEV(sd, "Video PLL = %d.%06d MHz\n", |
352 | pll / 1000000, pll % 1000000); | 455 | pll / 1000000, pll % 1000000); |
353 | CX18_DEBUG_INFO_DEV(sd, "PLL/8 = %d.%06d MHz\n", | 456 | CX18_DEBUG_INFO_DEV(sd, "Pixel rate = %d.%06d Mpixel/sec\n", |
354 | pll / 8000000, (pll / 8) % 1000000); | 457 | pll / 8000000, (pll / 8) % 1000000); |
355 | 458 | ||
356 | fin = ((u64)src_decimation * pll) >> 12; | 459 | CX18_DEBUG_INFO_DEV(sd, "ADC XTAL/pixel clock decimation ratio " |
357 | CX18_DEBUG_INFO_DEV(sd, "ADC Sampling freq = %d.%06d MHz\n", | 460 | "= %d.%03d\n", src_decimation / 256, |
358 | fin / 1000000, fin % 1000000); | 461 | ((src_decimation % 256) * 1000) / 256); |
359 | 462 | ||
360 | fsc = (((u64)sc) * pll) >> 24L; | 463 | tmp = 28636360 * (u64) sc; |
464 | do_div(tmp, src_decimation); | ||
465 | fsc = tmp >> 13; | ||
361 | CX18_DEBUG_INFO_DEV(sd, | 466 | CX18_DEBUG_INFO_DEV(sd, |
362 | "Chroma sub-carrier freq = %d.%06d MHz\n", | 467 | "Chroma sub-carrier initial freq = %d.%06d " |
363 | fsc / 1000000, fsc % 1000000); | 468 | "MHz\n", fsc / 1000000, fsc % 1000000); |
364 | 469 | ||
365 | CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, " | 470 | CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, " |
366 | "vactive %i, vblank656 %i, src_dec %i, " | 471 | "vactive %i, vblank656 %i, src_dec %i, " |
@@ -470,16 +575,23 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, | |||
470 | { | 575 | { |
471 | struct cx18_av_state *state = &cx->av_state; | 576 | struct cx18_av_state *state = &cx->av_state; |
472 | struct v4l2_subdev *sd = &state->sd; | 577 | struct v4l2_subdev *sd = &state->sd; |
473 | u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 && | 578 | |
474 | vid_input <= CX18_AV_COMPOSITE8); | 579 | enum analog_signal_type { |
475 | u8 reg; | 580 | NONE, CVBS, Y, C, SIF, Pb, Pr |
476 | u8 v; | 581 | } ch[3] = {NONE, NONE, NONE}; |
582 | |||
583 | u8 afe_mux_cfg; | ||
584 | u8 adc2_cfg; | ||
585 | u32 afe_cfg; | ||
586 | int i; | ||
477 | 587 | ||
478 | CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n", | 588 | CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n", |
479 | vid_input, aud_input); | 589 | vid_input, aud_input); |
480 | 590 | ||
481 | if (is_composite) { | 591 | if (vid_input >= CX18_AV_COMPOSITE1 && |
482 | reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1); | 592 | vid_input <= CX18_AV_COMPOSITE8) { |
593 | afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1); | ||
594 | ch[0] = CVBS; | ||
483 | } else { | 595 | } else { |
484 | int luma = vid_input & 0xf0; | 596 | int luma = vid_input & 0xf0; |
485 | int chroma = vid_input & 0xf00; | 597 | int chroma = vid_input & 0xf00; |
@@ -493,26 +605,45 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, | |||
493 | vid_input); | 605 | vid_input); |
494 | return -EINVAL; | 606 | return -EINVAL; |
495 | } | 607 | } |
496 | reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4); | 608 | afe_mux_cfg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4); |
609 | ch[0] = Y; | ||
497 | if (chroma >= CX18_AV_SVIDEO_CHROMA7) { | 610 | if (chroma >= CX18_AV_SVIDEO_CHROMA7) { |
498 | reg &= 0x3f; | 611 | afe_mux_cfg &= 0x3f; |
499 | reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2; | 612 | afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2; |
613 | ch[2] = C; | ||
500 | } else { | 614 | } else { |
501 | reg &= 0xcf; | 615 | afe_mux_cfg &= 0xcf; |
502 | reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4; | 616 | afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4; |
617 | ch[1] = C; | ||
503 | } | 618 | } |
504 | } | 619 | } |
620 | /* TODO: LeadTek WinFast DVR3100 H & WinFast PVR2100 can do Y/Pb/Pr */ | ||
505 | 621 | ||
506 | switch (aud_input) { | 622 | switch (aud_input) { |
507 | case CX18_AV_AUDIO_SERIAL1: | 623 | case CX18_AV_AUDIO_SERIAL1: |
508 | case CX18_AV_AUDIO_SERIAL2: | 624 | case CX18_AV_AUDIO_SERIAL2: |
509 | /* do nothing, use serial audio input */ | 625 | /* do nothing, use serial audio input */ |
510 | break; | 626 | break; |
511 | case CX18_AV_AUDIO4: reg &= ~0x30; break; | 627 | case CX18_AV_AUDIO4: |
512 | case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break; | 628 | afe_mux_cfg &= ~0x30; |
513 | case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break; | 629 | ch[1] = SIF; |
514 | case CX18_AV_AUDIO7: reg &= ~0xc0; break; | 630 | break; |
515 | case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; | 631 | case CX18_AV_AUDIO5: |
632 | afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x10; | ||
633 | ch[1] = SIF; | ||
634 | break; | ||
635 | case CX18_AV_AUDIO6: | ||
636 | afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x20; | ||
637 | ch[1] = SIF; | ||
638 | break; | ||
639 | case CX18_AV_AUDIO7: | ||
640 | afe_mux_cfg &= ~0xc0; | ||
641 | ch[2] = SIF; | ||
642 | break; | ||
643 | case CX18_AV_AUDIO8: | ||
644 | afe_mux_cfg = (afe_mux_cfg & ~0xc0) | 0x40; | ||
645 | ch[2] = SIF; | ||
646 | break; | ||
516 | 647 | ||
517 | default: | 648 | default: |
518 | CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n", | 649 | CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n", |
@@ -520,24 +651,65 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, | |||
520 | return -EINVAL; | 651 | return -EINVAL; |
521 | } | 652 | } |
522 | 653 | ||
523 | cx18_av_write_expect(cx, 0x103, reg, reg, 0xf7); | 654 | /* Set up analog front end multiplexers */ |
655 | cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7); | ||
524 | /* Set INPUT_MODE to Composite (0) or S-Video (1) */ | 656 | /* Set INPUT_MODE to Composite (0) or S-Video (1) */ |
525 | cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); | 657 | cx18_av_and_or(cx, 0x401, ~0x6, ch[0] == CVBS ? 0 : 0x02); |
526 | 658 | ||
527 | /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ | 659 | /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ |
528 | v = cx18_av_read(cx, 0x102); | 660 | adc2_cfg = cx18_av_read(cx, 0x102); |
529 | if (reg & 0x80) | 661 | if (ch[2] == NONE) |
530 | v &= ~0x2; | 662 | adc2_cfg &= ~0x2; /* No sig on CH3, set ADC2 to CH2 for input */ |
531 | else | 663 | else |
532 | v |= 0x2; | 664 | adc2_cfg |= 0x2; /* Signal on CH3, set ADC2 to CH3 for input */ |
665 | |||
533 | /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ | 666 | /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ |
534 | if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) | 667 | if (ch[1] != NONE && ch[2] != NONE) |
535 | v |= 0x4; | 668 | adc2_cfg |= 0x4; /* Set dual mode */ |
536 | else | 669 | else |
537 | v &= ~0x4; | 670 | adc2_cfg &= ~0x4; /* Clear dual mode */ |
538 | cx18_av_write_expect(cx, 0x102, v, v, 0x17); | 671 | cx18_av_write_expect(cx, 0x102, adc2_cfg, adc2_cfg, 0x17); |
672 | |||
673 | /* Configure the analog front end */ | ||
674 | afe_cfg = cx18_av_read4(cx, CXADEC_AFE_CTRL); | ||
675 | afe_cfg &= 0xff000000; | ||
676 | afe_cfg |= 0x00005000; /* CHROMA_IN, AUD_IN: ADC2; LUMA_IN: ADC1 */ | ||
677 | if (ch[1] != NONE && ch[2] != NONE) | ||
678 | afe_cfg |= 0x00000030; /* half_bw_ch[2-3] since in dual mode */ | ||
679 | |||
680 | for (i = 0; i < 3; i++) { | ||
681 | switch (ch[i]) { | ||
682 | default: | ||
683 | case NONE: | ||
684 | /* CLAMP_SEL = Fixed to midcode clamp level */ | ||
685 | afe_cfg |= (0x00000200 << i); | ||
686 | break; | ||
687 | case CVBS: | ||
688 | case Y: | ||
689 | if (i > 0) | ||
690 | afe_cfg |= 0x00002000; /* LUMA_IN_SEL: ADC2 */ | ||
691 | break; | ||
692 | case C: | ||
693 | case Pb: | ||
694 | case Pr: | ||
695 | /* CLAMP_SEL = Fixed to midcode clamp level */ | ||
696 | afe_cfg |= (0x00000200 << i); | ||
697 | if (i == 0 && ch[i] == C) | ||
698 | afe_cfg &= ~0x00001000; /* CHROMA_IN_SEL ADC1 */ | ||
699 | break; | ||
700 | case SIF: | ||
701 | /* | ||
702 | * VGA_GAIN_SEL = Audio Decoder | ||
703 | * CLAMP_SEL = Fixed to midcode clamp level | ||
704 | */ | ||
705 | afe_cfg |= (0x00000240 << i); | ||
706 | if (i == 0) | ||
707 | afe_cfg &= ~0x00004000; /* AUD_IN_SEL ADC1 */ | ||
708 | break; | ||
709 | } | ||
710 | } | ||
539 | 711 | ||
540 | /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/ | 712 | cx18_av_write4(cx, CXADEC_AFE_CTRL, afe_cfg); |
541 | 713 | ||
542 | state->vid_input = vid_input; | 714 | state->vid_input = vid_input; |
543 | state->aud_input = aud_input; | 715 | state->aud_input = aud_input; |
@@ -858,9 +1030,9 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |||
858 | * cx18_av_std_setup(), above standard values: | 1030 | * cx18_av_std_setup(), above standard values: |
859 | * | 1031 | * |
860 | * 480 + 1 for 60 Hz systems | 1032 | * 480 + 1 for 60 Hz systems |
861 | * 576 + 4 for 50 Hz systems | 1033 | * 576 + 3 for 50 Hz systems |
862 | */ | 1034 | */ |
863 | Vlines = pix->height + (is_50Hz ? 4 : 1); | 1035 | Vlines = pix->height + (is_50Hz ? 3 : 1); |
864 | 1036 | ||
865 | /* | 1037 | /* |
866 | * Invalid height and width scaling requests are: | 1038 | * Invalid height and width scaling requests are: |
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c index 49a55cc8d839..b9e8cc5d264a 100644 --- a/drivers/media/video/cx18/cx18-av-firmware.c +++ b/drivers/media/video/cx18/cx18-av-firmware.c | |||
@@ -24,15 +24,63 @@ | |||
24 | #include "cx18-io.h" | 24 | #include "cx18-io.h" |
25 | #include <linux/firmware.h> | 25 | #include <linux/firmware.h> |
26 | 26 | ||
27 | #define CX18_AUDIO_ENABLE 0xc72014 | 27 | #define CX18_AUDIO_ENABLE 0xc72014 |
28 | #define CX18_AI1_MUX_MASK 0x30 | ||
29 | #define CX18_AI1_MUX_I2S1 0x00 | ||
30 | #define CX18_AI1_MUX_I2S2 0x10 | ||
31 | #define CX18_AI1_MUX_843_I2S 0x20 | ||
32 | #define CX18_AI1_MUX_INVALID 0x30 | ||
33 | |||
28 | #define FWFILE "v4l-cx23418-dig.fw" | 34 | #define FWFILE "v4l-cx23418-dig.fw" |
29 | 35 | ||
36 | static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw) | ||
37 | { | ||
38 | struct v4l2_subdev *sd = &cx->av_state.sd; | ||
39 | int ret = 0; | ||
40 | const u8 *data; | ||
41 | u32 size; | ||
42 | int addr; | ||
43 | u32 expected, dl_control; | ||
44 | |||
45 | /* Ensure we put the 8051 in reset and enable firmware upload mode */ | ||
46 | dl_control = cx18_av_read4(cx, CXADEC_DL_CTL); | ||
47 | do { | ||
48 | dl_control &= 0x00ffffff; | ||
49 | dl_control |= 0x0f000000; | ||
50 | cx18_av_write4_noretry(cx, CXADEC_DL_CTL, dl_control); | ||
51 | dl_control = cx18_av_read4(cx, CXADEC_DL_CTL); | ||
52 | } while ((dl_control & 0xff000000) != 0x0f000000); | ||
53 | |||
54 | /* Read and auto increment until at address 0x0000 */ | ||
55 | while (dl_control & 0x3fff) | ||
56 | dl_control = cx18_av_read4(cx, CXADEC_DL_CTL); | ||
57 | |||
58 | data = fw->data; | ||
59 | size = fw->size; | ||
60 | for (addr = 0; addr < size; addr++) { | ||
61 | dl_control &= 0xffff3fff; /* ignore top 2 bits of address */ | ||
62 | expected = 0x0f000000 | ((u32)data[addr] << 16) | addr; | ||
63 | if (expected != dl_control) { | ||
64 | CX18_ERR_DEV(sd, "verification of %s firmware load " | ||
65 | "failed: expected %#010x got %#010x\n", | ||
66 | FWFILE, expected, dl_control); | ||
67 | ret = -EIO; | ||
68 | break; | ||
69 | } | ||
70 | dl_control = cx18_av_read4(cx, CXADEC_DL_CTL); | ||
71 | } | ||
72 | if (ret == 0) | ||
73 | CX18_INFO_DEV(sd, "verified load of %s firmware (%d bytes)\n", | ||
74 | FWFILE, size); | ||
75 | return ret; | ||
76 | } | ||
77 | |||
30 | int cx18_av_loadfw(struct cx18 *cx) | 78 | int cx18_av_loadfw(struct cx18 *cx) |
31 | { | 79 | { |
32 | struct v4l2_subdev *sd = &cx->av_state.sd; | 80 | struct v4l2_subdev *sd = &cx->av_state.sd; |
33 | const struct firmware *fw = NULL; | 81 | const struct firmware *fw = NULL; |
34 | u32 size; | 82 | u32 size; |
35 | u32 v; | 83 | u32 u, v; |
36 | const u8 *ptr; | 84 | const u8 *ptr; |
37 | int i; | 85 | int i; |
38 | int retries1 = 0; | 86 | int retries1 = 0; |
@@ -95,6 +143,12 @@ int cx18_av_loadfw(struct cx18 *cx) | |||
95 | } | 143 | } |
96 | 144 | ||
97 | cx18_av_write4_expect(cx, CXADEC_DL_CTL, | 145 | cx18_av_write4_expect(cx, CXADEC_DL_CTL, |
146 | 0x03000000 | fw->size, 0x03000000, 0x13000000); | ||
147 | |||
148 | CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size); | ||
149 | |||
150 | if (cx18_av_verifyfw(cx, fw) == 0) | ||
151 | cx18_av_write4_expect(cx, CXADEC_DL_CTL, | ||
98 | 0x13000000 | fw->size, 0x13000000, 0x13000000); | 152 | 0x13000000 | fw->size, 0x13000000, 0x13000000); |
99 | 153 | ||
100 | /* Output to the 416 */ | 154 | /* Output to the 416 */ |
@@ -135,6 +189,28 @@ int cx18_av_loadfw(struct cx18 *cx) | |||
135 | cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE, | 189 | cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE, |
136 | 0, 0x400); | 190 | 0, 0x400); |
137 | 191 | ||
192 | /* Toggle the AI1 MUX */ | ||
193 | v = cx18_read_reg(cx, CX18_AUDIO_ENABLE); | ||
194 | u = v & CX18_AI1_MUX_MASK; | ||
195 | v &= ~CX18_AI1_MUX_MASK; | ||
196 | if (u == CX18_AI1_MUX_843_I2S || u == CX18_AI1_MUX_INVALID) { | ||
197 | /* Switch to I2S1 */ | ||
198 | v |= CX18_AI1_MUX_I2S1; | ||
199 | cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE, | ||
200 | v, CX18_AI1_MUX_MASK); | ||
201 | /* Switch back to the A/V decoder core I2S output */ | ||
202 | v = (v & ~CX18_AI1_MUX_MASK) | CX18_AI1_MUX_843_I2S; | ||
203 | } else { | ||
204 | /* Switch to the A/V decoder core I2S output */ | ||
205 | v |= CX18_AI1_MUX_843_I2S; | ||
206 | cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE, | ||
207 | v, CX18_AI1_MUX_MASK); | ||
208 | /* Switch back to I2S1 or I2S2 */ | ||
209 | v = (v & ~CX18_AI1_MUX_MASK) | u; | ||
210 | } | ||
211 | cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE, | ||
212 | v, CX18_AI1_MUX_MASK); | ||
213 | |||
138 | /* Enable WW auto audio standard detection */ | 214 | /* Enable WW auto audio standard detection */ |
139 | v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); | 215 | v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); |
140 | v |= 0xFF; /* Auto by default */ | 216 | v |= 0xFF; /* Auto by default */ |
@@ -143,7 +219,5 @@ int cx18_av_loadfw(struct cx18 *cx) | |||
143 | cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF); | 219 | cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF); |
144 | 220 | ||
145 | release_firmware(fw); | 221 | release_firmware(fw); |
146 | |||
147 | CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size); | ||
148 | return 0; | 222 | return 0; |
149 | } | 223 | } |
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c index 23b31670bf1d..a51732bcca4b 100644 --- a/drivers/media/video/cx18/cx18-av-vbi.c +++ b/drivers/media/video/cx18/cx18-av-vbi.c | |||
@@ -255,8 +255,8 @@ int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt) | |||
255 | } | 255 | } |
256 | 256 | ||
257 | cx18_av_write(cx, 0x43c, 0x16); | 257 | cx18_av_write(cx, 0x43c, 0x16); |
258 | /* FIXME - should match vblank set in cx18_av_std_setup() */ | 258 | /* Should match vblank set in cx18_av_std_setup() */ |
259 | cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26); | 259 | cx18_av_write(cx, 0x474, is_pal ? 38 : 26); |
260 | return 0; | 260 | return 0; |
261 | } | 261 | } |
262 | 262 | ||
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index 9bc221837847..c92a25036f0e 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c | |||
@@ -340,13 +340,12 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = { | |||
340 | 340 | ||
341 | static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = { | 341 | static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = { |
342 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */ | 342 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */ |
343 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */ | ||
344 | { 0, 0, 0 } | 343 | { 0, 0, 0 } |
345 | }; | 344 | }; |
346 | 345 | ||
347 | static const struct cx18_card cx18_card_leadtek_pvr2100 = { | 346 | static const struct cx18_card cx18_card_leadtek_pvr2100 = { |
348 | .type = CX18_CARD_LEADTEK_PVR2100, | 347 | .type = CX18_CARD_LEADTEK_PVR2100, |
349 | .name = "Leadtek WinFast PVR2100/DVR3100 H", | 348 | .name = "Leadtek WinFast PVR2100", |
350 | .comment = "Experimenters and photos needed for device to work well.\n" | 349 | .comment = "Experimenters and photos needed for device to work well.\n" |
351 | "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", | 350 | "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", |
352 | .v4l2_capabilities = CX18_CAP_ENCODER, | 351 | .v4l2_capabilities = CX18_CAP_ENCODER, |
@@ -365,15 +364,12 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = { | |||
365 | { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, | 364 | { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, |
366 | }, | 365 | }, |
367 | .tuners = { | 366 | .tuners = { |
368 | /* XC3028 tuner */ | 367 | /* XC2028 tuner */ |
369 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | 368 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, |
370 | }, | 369 | }, |
371 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, | 370 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, |
372 | .ddr = { | 371 | .ddr = { |
373 | /* | 372 | /* Pointer to proper DDR config values provided by Terry Wu */ |
374 | * Pointer to proper DDR config values provided by | ||
375 | * Terry Wu <terrywu at leadtek.com.tw> | ||
376 | */ | ||
377 | .chip_config = 0x303, | 373 | .chip_config = 0x303, |
378 | .refresh = 0x3bb, | 374 | .refresh = 0x3bb, |
379 | .timing1 = 0x24220e83, | 375 | .timing1 = 0x24220e83, |
@@ -392,6 +388,58 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = { | |||
392 | 388 | ||
393 | /* ------------------------------------------------------------------------- */ | 389 | /* ------------------------------------------------------------------------- */ |
394 | 390 | ||
391 | /* Leadtek WinFast DVR3100 H */ | ||
392 | |||
393 | static const struct cx18_card_pci_info cx18_pci_leadtek_dvr3100h[] = { | ||
394 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */ | ||
395 | { 0, 0, 0 } | ||
396 | }; | ||
397 | |||
398 | static const struct cx18_card cx18_card_leadtek_dvr3100h = { | ||
399 | .type = CX18_CARD_LEADTEK_DVR3100H, | ||
400 | .name = "Leadtek WinFast DVR3100 H", | ||
401 | .comment = "Simultaneous DVB-T and Analog capture supported,\n" | ||
402 | "\texcept when capturing Analog from the antenna input.\n", | ||
403 | .v4l2_capabilities = CX18_CAP_ENCODER, | ||
404 | .hw_audio_ctrl = CX18_HW_418_AV, | ||
405 | .hw_muxer = CX18_HW_GPIO_MUX, | ||
406 | .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX | | ||
407 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL, | ||
408 | .video_inputs = { | ||
409 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, | ||
410 | { CX18_CARD_INPUT_SVIDEO1, 1, | ||
411 | CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, | ||
412 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 }, | ||
413 | }, | ||
414 | .audio_inputs = { | ||
415 | { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, | ||
416 | { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, | ||
417 | }, | ||
418 | .tuners = { | ||
419 | /* XC3028 tuner */ | ||
420 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | ||
421 | }, | ||
422 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, | ||
423 | .ddr = { | ||
424 | /* Pointer to proper DDR config values provided by Terry Wu */ | ||
425 | .chip_config = 0x303, | ||
426 | .refresh = 0x3bb, | ||
427 | .timing1 = 0x24220e83, | ||
428 | .timing2 = 0x1f, | ||
429 | .tune_lane = 0, | ||
430 | .initial_emrs = 0x2, | ||
431 | }, | ||
432 | .gpio_init.initial_value = 0x6, | ||
433 | .gpio_init.direction = 0x7, | ||
434 | .gpio_audio_input = { .mask = 0x7, | ||
435 | .tuner = 0x6, .linein = 0x2, .radio = 0x2 }, | ||
436 | .xceive_pin = 1, | ||
437 | .pci_list = cx18_pci_leadtek_dvr3100h, | ||
438 | .i2c = &cx18_i2c_std, | ||
439 | }; | ||
440 | |||
441 | /* ------------------------------------------------------------------------- */ | ||
442 | |||
395 | static const struct cx18_card *cx18_card_list[] = { | 443 | static const struct cx18_card *cx18_card_list[] = { |
396 | &cx18_card_hvr1600_esmt, | 444 | &cx18_card_hvr1600_esmt, |
397 | &cx18_card_hvr1600_samsung, | 445 | &cx18_card_hvr1600_samsung, |
@@ -400,6 +448,7 @@ static const struct cx18_card *cx18_card_list[] = { | |||
400 | &cx18_card_cnxt_raptor_pal, | 448 | &cx18_card_cnxt_raptor_pal, |
401 | &cx18_card_toshiba_qosmio_dvbt, | 449 | &cx18_card_toshiba_qosmio_dvbt, |
402 | &cx18_card_leadtek_pvr2100, | 450 | &cx18_card_leadtek_pvr2100, |
451 | &cx18_card_leadtek_dvr3100h, | ||
403 | }; | 452 | }; |
404 | 453 | ||
405 | const struct cx18_card *cx18_get_card(u16 index) | 454 | const struct cx18_card *cx18_get_card(u16 index) |
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c index 82fc2f9d4021..8e35c3aed544 100644 --- a/drivers/media/video/cx18/cx18-controls.c +++ b/drivers/media/video/cx18/cx18-controls.c | |||
@@ -176,8 +176,10 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, | |||
176 | return -EBUSY; | 176 | return -EBUSY; |
177 | 177 | ||
178 | if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV || | 178 | if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV || |
179 | type != V4L2_MPEG_STREAM_TYPE_MPEG2_PS) { | 179 | !(type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS || |
180 | /* We don't do VBI insertion aside from IVTV format in a PS */ | 180 | type == V4L2_MPEG_STREAM_TYPE_MPEG2_DVD || |
181 | type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) { | ||
182 | /* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */ | ||
181 | cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE; | 183 | cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE; |
182 | CX18_DEBUG_INFO("disabled insertion of sliced VBI data into " | 184 | CX18_DEBUG_INFO("disabled insertion of sliced VBI data into " |
183 | "the MPEG stream\n"); | 185 | "the MPEG stream\n"); |
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 49b1c3d7b1a8..92026e82e10e 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "cx18-irq.h" | 30 | #include "cx18-irq.h" |
31 | #include "cx18-gpio.h" | 31 | #include "cx18-gpio.h" |
32 | #include "cx18-firmware.h" | 32 | #include "cx18-firmware.h" |
33 | #include "cx18-queue.h" | ||
33 | #include "cx18-streams.h" | 34 | #include "cx18-streams.h" |
34 | #include "cx18-av-core.h" | 35 | #include "cx18-av-core.h" |
35 | #include "cx18-scb.h" | 36 | #include "cx18-scb.h" |
@@ -151,7 +152,8 @@ MODULE_PARM_DESC(cardtype, | |||
151 | "\t\t\t 4 = Yuan MPC718\n" | 152 | "\t\t\t 4 = Yuan MPC718\n" |
152 | "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" | 153 | "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" |
153 | "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" | 154 | "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" |
154 | "\t\t\t 7 = Leadtek WinFast PVR2100/DVR3100 H\n" | 155 | "\t\t\t 7 = Leadtek WinFast PVR2100\n" |
156 | "\t\t\t 8 = Leadtek WinFast DVR3100 H\n" | ||
155 | "\t\t\t 0 = Autodetect (default)\n" | 157 | "\t\t\t 0 = Autodetect (default)\n" |
156 | "\t\t\t-1 = Ignore this card\n\t\t"); | 158 | "\t\t\t-1 = Ignore this card\n\t\t"); |
157 | MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); | 159 | MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); |
@@ -312,7 +314,7 @@ static void cx18_process_eeprom(struct cx18 *cx) | |||
312 | CX18_INFO("Autodetected %s\n", cx->card_name); | 314 | CX18_INFO("Autodetected %s\n", cx->card_name); |
313 | 315 | ||
314 | if (tv.tuner_type == TUNER_ABSENT) | 316 | if (tv.tuner_type == TUNER_ABSENT) |
315 | CX18_ERR("tveeprom cannot autodetect tuner!"); | 317 | CX18_ERR("tveeprom cannot autodetect tuner!\n"); |
316 | 318 | ||
317 | if (cx->options.tuner == -1) | 319 | if (cx->options.tuner == -1) |
318 | cx->options.tuner = tv.tuner_type; | 320 | cx->options.tuner = tv.tuner_type; |
@@ -546,6 +548,40 @@ done: | |||
546 | cx->card_i2c = cx->card->i2c; | 548 | cx->card_i2c = cx->card->i2c; |
547 | } | 549 | } |
548 | 550 | ||
551 | static int __devinit cx18_create_in_workq(struct cx18 *cx) | ||
552 | { | ||
553 | snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in", | ||
554 | cx->v4l2_dev.name); | ||
555 | cx->in_work_queue = create_singlethread_workqueue(cx->in_workq_name); | ||
556 | if (cx->in_work_queue == NULL) { | ||
557 | CX18_ERR("Unable to create incoming mailbox handler thread\n"); | ||
558 | return -ENOMEM; | ||
559 | } | ||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | static int __devinit cx18_create_out_workq(struct cx18 *cx) | ||
564 | { | ||
565 | snprintf(cx->out_workq_name, sizeof(cx->out_workq_name), "%s-out", | ||
566 | cx->v4l2_dev.name); | ||
567 | cx->out_work_queue = create_workqueue(cx->out_workq_name); | ||
568 | if (cx->out_work_queue == NULL) { | ||
569 | CX18_ERR("Unable to create outgoing mailbox handler threads\n"); | ||
570 | return -ENOMEM; | ||
571 | } | ||
572 | return 0; | ||
573 | } | ||
574 | |||
575 | static void __devinit cx18_init_in_work_orders(struct cx18 *cx) | ||
576 | { | ||
577 | int i; | ||
578 | for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) { | ||
579 | cx->in_work_order[i].cx = cx; | ||
580 | cx->in_work_order[i].str = cx->epu_debug_str; | ||
581 | INIT_WORK(&cx->in_work_order[i].work, cx18_in_work_handler); | ||
582 | } | ||
583 | } | ||
584 | |||
549 | /* Precondition: the cx18 structure has been memset to 0. Only | 585 | /* Precondition: the cx18 structure has been memset to 0. Only |
550 | the dev and instance fields have been filled in. | 586 | the dev and instance fields have been filled in. |
551 | No assumptions on the card type may be made here (see cx18_init_struct2 | 587 | No assumptions on the card type may be made here (see cx18_init_struct2 |
@@ -553,7 +589,7 @@ done: | |||
553 | */ | 589 | */ |
554 | static int __devinit cx18_init_struct1(struct cx18 *cx) | 590 | static int __devinit cx18_init_struct1(struct cx18 *cx) |
555 | { | 591 | { |
556 | int i; | 592 | int ret; |
557 | 593 | ||
558 | cx->base_addr = pci_resource_start(cx->pci_dev, 0); | 594 | cx->base_addr = pci_resource_start(cx->pci_dev, 0); |
559 | 595 | ||
@@ -562,18 +598,18 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) | |||
562 | mutex_init(&cx->epu2apu_mb_lock); | 598 | mutex_init(&cx->epu2apu_mb_lock); |
563 | mutex_init(&cx->epu2cpu_mb_lock); | 599 | mutex_init(&cx->epu2cpu_mb_lock); |
564 | 600 | ||
565 | cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name); | 601 | ret = cx18_create_out_workq(cx); |
566 | if (cx->work_queue == NULL) { | 602 | if (ret) |
567 | CX18_ERR("Unable to create work hander thread\n"); | 603 | return ret; |
568 | return -ENOMEM; | ||
569 | } | ||
570 | 604 | ||
571 | for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) { | 605 | ret = cx18_create_in_workq(cx); |
572 | cx->epu_work_order[i].cx = cx; | 606 | if (ret) { |
573 | cx->epu_work_order[i].str = cx->epu_debug_str; | 607 | destroy_workqueue(cx->out_work_queue); |
574 | INIT_WORK(&cx->epu_work_order[i].work, cx18_epu_work_handler); | 608 | return ret; |
575 | } | 609 | } |
576 | 610 | ||
611 | cx18_init_in_work_orders(cx); | ||
612 | |||
577 | /* start counting open_id at 1 */ | 613 | /* start counting open_id at 1 */ |
578 | cx->open_id = 1; | 614 | cx->open_id = 1; |
579 | 615 | ||
@@ -759,17 +795,17 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, | |||
759 | retval = -ENODEV; | 795 | retval = -ENODEV; |
760 | goto err; | 796 | goto err; |
761 | } | 797 | } |
762 | if (cx18_init_struct1(cx)) { | 798 | |
763 | retval = -ENOMEM; | 799 | retval = cx18_init_struct1(cx); |
800 | if (retval) | ||
764 | goto err; | 801 | goto err; |
765 | } | ||
766 | 802 | ||
767 | CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); | 803 | CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); |
768 | 804 | ||
769 | /* PCI Device Setup */ | 805 | /* PCI Device Setup */ |
770 | retval = cx18_setup_pci(cx, pci_dev, pci_id); | 806 | retval = cx18_setup_pci(cx, pci_dev, pci_id); |
771 | if (retval != 0) | 807 | if (retval != 0) |
772 | goto free_workqueue; | 808 | goto free_workqueues; |
773 | 809 | ||
774 | /* map io memory */ | 810 | /* map io memory */ |
775 | CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", | 811 | CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", |
@@ -943,8 +979,9 @@ free_map: | |||
943 | cx18_iounmap(cx); | 979 | cx18_iounmap(cx); |
944 | free_mem: | 980 | free_mem: |
945 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); | 981 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); |
946 | free_workqueue: | 982 | free_workqueues: |
947 | destroy_workqueue(cx->work_queue); | 983 | destroy_workqueue(cx->in_work_queue); |
984 | destroy_workqueue(cx->out_work_queue); | ||
948 | err: | 985 | err: |
949 | if (retval == 0) | 986 | if (retval == 0) |
950 | retval = -ENODEV; | 987 | retval = -ENODEV; |
@@ -1053,11 +1090,19 @@ int cx18_init_on_first_open(struct cx18 *cx) | |||
1053 | return 0; | 1090 | return 0; |
1054 | } | 1091 | } |
1055 | 1092 | ||
1056 | static void cx18_cancel_epu_work_orders(struct cx18 *cx) | 1093 | static void cx18_cancel_in_work_orders(struct cx18 *cx) |
1057 | { | 1094 | { |
1058 | int i; | 1095 | int i; |
1059 | for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) | 1096 | for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) |
1060 | cancel_work_sync(&cx->epu_work_order[i].work); | 1097 | cancel_work_sync(&cx->in_work_order[i].work); |
1098 | } | ||
1099 | |||
1100 | static void cx18_cancel_out_work_orders(struct cx18 *cx) | ||
1101 | { | ||
1102 | int i; | ||
1103 | for (i = 0; i < CX18_MAX_STREAMS; i++) | ||
1104 | if (&cx->streams[i].video_dev != NULL) | ||
1105 | cancel_work_sync(&cx->streams[i].out_work_order); | ||
1061 | } | 1106 | } |
1062 | 1107 | ||
1063 | static void cx18_remove(struct pci_dev *pci_dev) | 1108 | static void cx18_remove(struct pci_dev *pci_dev) |
@@ -1073,15 +1118,20 @@ static void cx18_remove(struct pci_dev *pci_dev) | |||
1073 | if (atomic_read(&cx->tot_capturing) > 0) | 1118 | if (atomic_read(&cx->tot_capturing) > 0) |
1074 | cx18_stop_all_captures(cx); | 1119 | cx18_stop_all_captures(cx); |
1075 | 1120 | ||
1076 | /* Interrupts */ | 1121 | /* Stop interrupts that cause incoming work to be queued */ |
1077 | cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); | 1122 | cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); |
1123 | |||
1124 | /* Incoming work can cause outgoing work, so clean up incoming first */ | ||
1125 | cx18_cancel_in_work_orders(cx); | ||
1126 | cx18_cancel_out_work_orders(cx); | ||
1127 | |||
1128 | /* Stop ack interrupts that may have been needed for work to finish */ | ||
1078 | cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); | 1129 | cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); |
1079 | 1130 | ||
1080 | cx18_halt_firmware(cx); | 1131 | cx18_halt_firmware(cx); |
1081 | 1132 | ||
1082 | cx18_cancel_epu_work_orders(cx); | 1133 | destroy_workqueue(cx->in_work_queue); |
1083 | 1134 | destroy_workqueue(cx->out_work_queue); | |
1084 | destroy_workqueue(cx->work_queue); | ||
1085 | 1135 | ||
1086 | cx18_streams_cleanup(cx, 1); | 1136 | cx18_streams_cleanup(cx, 1); |
1087 | 1137 | ||
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index ece4f281ef42..c6a1e907f63a 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -80,8 +80,9 @@ | |||
80 | #define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ | 80 | #define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ |
81 | #define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ | 81 | #define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ |
82 | #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ | 82 | #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ |
83 | #define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100/DVR3100 H */ | 83 | #define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */ |
84 | #define CX18_CARD_LAST 6 | 84 | #define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */ |
85 | #define CX18_CARD_LAST 7 | ||
85 | 86 | ||
86 | #define CX18_ENC_STREAM_TYPE_MPG 0 | 87 | #define CX18_ENC_STREAM_TYPE_MPG 0 |
87 | #define CX18_ENC_STREAM_TYPE_TS 1 | 88 | #define CX18_ENC_STREAM_TYPE_TS 1 |
@@ -254,6 +255,7 @@ struct cx18_options { | |||
254 | #define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ | 255 | #define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ |
255 | #define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */ | 256 | #define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */ |
256 | #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ | 257 | #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ |
258 | #define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */ | ||
257 | 259 | ||
258 | /* per-cx18, i_flags */ | 260 | /* per-cx18, i_flags */ |
259 | #define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ | 261 | #define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ |
@@ -285,6 +287,7 @@ struct cx18_queue { | |||
285 | struct list_head list; | 287 | struct list_head list; |
286 | atomic_t buffers; | 288 | atomic_t buffers; |
287 | u32 bytesused; | 289 | u32 bytesused; |
290 | spinlock_t lock; | ||
288 | }; | 291 | }; |
289 | 292 | ||
290 | struct cx18_dvb { | 293 | struct cx18_dvb { |
@@ -305,7 +308,7 @@ struct cx18_scb; /* forward reference */ | |||
305 | 308 | ||
306 | 309 | ||
307 | #define CX18_MAX_MDL_ACKS 2 | 310 | #define CX18_MAX_MDL_ACKS 2 |
308 | #define CX18_MAX_EPU_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7) | 311 | #define CX18_MAX_IN_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7) |
309 | /* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */ | 312 | /* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */ |
310 | 313 | ||
311 | #define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1 | 314 | #define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1 |
@@ -313,7 +316,7 @@ struct cx18_scb; /* forward reference */ | |||
313 | #define CX18_F_EWO_MB_STALE \ | 316 | #define CX18_F_EWO_MB_STALE \ |
314 | (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC) | 317 | (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC) |
315 | 318 | ||
316 | struct cx18_epu_work_order { | 319 | struct cx18_in_work_order { |
317 | struct work_struct work; | 320 | struct work_struct work; |
318 | atomic_t pending; | 321 | atomic_t pending; |
319 | struct cx18 *cx; | 322 | struct cx18 *cx; |
@@ -337,7 +340,6 @@ struct cx18_stream { | |||
337 | unsigned mdl_offset; | 340 | unsigned mdl_offset; |
338 | 341 | ||
339 | u32 id; | 342 | u32 id; |
340 | struct mutex qlock; /* locks access to the queues */ | ||
341 | unsigned long s_flags; /* status flags, see above */ | 343 | unsigned long s_flags; /* status flags, see above */ |
342 | int dma; /* can be PCI_DMA_TODEVICE, | 344 | int dma; /* can be PCI_DMA_TODEVICE, |
343 | PCI_DMA_FROMDEVICE or | 345 | PCI_DMA_FROMDEVICE or |
@@ -353,6 +355,8 @@ struct cx18_stream { | |||
353 | struct cx18_queue q_busy; /* busy buffers - in use by firmware */ | 355 | struct cx18_queue q_busy; /* busy buffers - in use by firmware */ |
354 | struct cx18_queue q_full; /* full buffers - data for user apps */ | 356 | struct cx18_queue q_full; /* full buffers - data for user apps */ |
355 | 357 | ||
358 | struct work_struct out_work_order; | ||
359 | |||
356 | /* DVB / Digital Transport */ | 360 | /* DVB / Digital Transport */ |
357 | struct cx18_dvb dvb; | 361 | struct cx18_dvb dvb; |
358 | }; | 362 | }; |
@@ -568,10 +572,14 @@ struct cx18 { | |||
568 | u32 sw2_irq_mask; | 572 | u32 sw2_irq_mask; |
569 | u32 hw2_irq_mask; | 573 | u32 hw2_irq_mask; |
570 | 574 | ||
571 | struct workqueue_struct *work_queue; | 575 | struct workqueue_struct *in_work_queue; |
572 | struct cx18_epu_work_order epu_work_order[CX18_MAX_EPU_WORK_ORDERS]; | 576 | char in_workq_name[11]; /* "cx18-NN-in" */ |
577 | struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS]; | ||
573 | char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */ | 578 | char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */ |
574 | 579 | ||
580 | struct workqueue_struct *out_work_queue; | ||
581 | char out_workq_name[12]; /* "cx18-NN-out" */ | ||
582 | |||
575 | /* i2c */ | 583 | /* i2c */ |
576 | struct i2c_adapter i2c_adap[2]; | 584 | struct i2c_adapter i2c_adap[2]; |
577 | struct i2c_algo_bit_data i2c_algo[2]; | 585 | struct i2c_algo_bit_data i2c_algo[2]; |
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index 3b86f57cd15a..6ea3fe623ef4 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c | |||
@@ -23,14 +23,20 @@ | |||
23 | #include "cx18-version.h" | 23 | #include "cx18-version.h" |
24 | #include "cx18-dvb.h" | 24 | #include "cx18-dvb.h" |
25 | #include "cx18-io.h" | 25 | #include "cx18-io.h" |
26 | #include "cx18-queue.h" | ||
26 | #include "cx18-streams.h" | 27 | #include "cx18-streams.h" |
27 | #include "cx18-cards.h" | 28 | #include "cx18-cards.h" |
29 | #include "cx18-gpio.h" | ||
28 | #include "s5h1409.h" | 30 | #include "s5h1409.h" |
29 | #include "mxl5005s.h" | 31 | #include "mxl5005s.h" |
32 | #include "zl10353.h" | ||
33 | #include "tuner-xc2028.h" | ||
30 | 34 | ||
31 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 35 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
32 | 36 | ||
33 | #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000 | 37 | #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000 |
38 | #define CX18_CLOCK_ENABLE2 0xc71024 | ||
39 | #define CX18_DMUX_CLK_MASK 0x0080 | ||
34 | 40 | ||
35 | static struct mxl5005s_config hauppauge_hvr1600_tuner = { | 41 | static struct mxl5005s_config hauppauge_hvr1600_tuner = { |
36 | .i2c_address = 0xC6 >> 1, | 42 | .i2c_address = 0xC6 >> 1, |
@@ -57,7 +63,15 @@ static struct s5h1409_config hauppauge_hvr1600_config = { | |||
57 | .inversion = S5H1409_INVERSION_OFF, | 63 | .inversion = S5H1409_INVERSION_OFF, |
58 | .status_mode = S5H1409_DEMODLOCKING, | 64 | .status_mode = S5H1409_DEMODLOCKING, |
59 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK | 65 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK |
66 | }; | ||
60 | 67 | ||
68 | /* Information/confirmation of proper config values provided by Terry Wu */ | ||
69 | static struct zl10353_config leadtek_dvr3100h_demod = { | ||
70 | .demod_address = 0x1e >> 1, /* Datasheet suggested straps */ | ||
71 | .if2 = 45600, /* 4.560 MHz IF from the XC3028 */ | ||
72 | .parallel_ts = 1, /* Not a serial TS */ | ||
73 | .no_tuner = 1, /* XC3028 is not behind the gate */ | ||
74 | .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */ | ||
61 | }; | 75 | }; |
62 | 76 | ||
63 | static int dvb_register(struct cx18_stream *stream); | 77 | static int dvb_register(struct cx18_stream *stream); |
@@ -98,6 +112,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) | |||
98 | cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); | 112 | cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); |
99 | break; | 113 | break; |
100 | 114 | ||
115 | case CX18_CARD_LEADTEK_DVR3100H: | ||
101 | default: | 116 | default: |
102 | /* Assumption - Parallel transport - Signalling | 117 | /* Assumption - Parallel transport - Signalling |
103 | * undefined or default. | 118 | * undefined or default. |
@@ -267,8 +282,7 @@ void cx18_dvb_unregister(struct cx18_stream *stream) | |||
267 | } | 282 | } |
268 | 283 | ||
269 | /* All the DVB attach calls go here, this function get's modified | 284 | /* All the DVB attach calls go here, this function get's modified |
270 | * for each new card. No other function in this file needs | 285 | * for each new card. cx18_dvb_start_feed() will also need changes. |
271 | * to change. | ||
272 | */ | 286 | */ |
273 | static int dvb_register(struct cx18_stream *stream) | 287 | static int dvb_register(struct cx18_stream *stream) |
274 | { | 288 | { |
@@ -289,6 +303,29 @@ static int dvb_register(struct cx18_stream *stream) | |||
289 | ret = 0; | 303 | ret = 0; |
290 | } | 304 | } |
291 | break; | 305 | break; |
306 | case CX18_CARD_LEADTEK_DVR3100H: | ||
307 | dvb->fe = dvb_attach(zl10353_attach, | ||
308 | &leadtek_dvr3100h_demod, | ||
309 | &cx->i2c_adap[1]); | ||
310 | if (dvb->fe != NULL) { | ||
311 | struct dvb_frontend *fe; | ||
312 | struct xc2028_config cfg = { | ||
313 | .i2c_adap = &cx->i2c_adap[1], | ||
314 | .i2c_addr = 0xc2 >> 1, | ||
315 | .ctrl = NULL, | ||
316 | }; | ||
317 | static struct xc2028_ctrl ctrl = { | ||
318 | .fname = XC2028_DEFAULT_FIRMWARE, | ||
319 | .max_len = 64, | ||
320 | .demod = XC3028_FE_ZARLINK456, | ||
321 | .type = XC2028_AUTO, | ||
322 | }; | ||
323 | |||
324 | fe = dvb_attach(xc2028_attach, dvb->fe, &cfg); | ||
325 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | ||
326 | fe->ops.tuner_ops.set_config(fe, &ctrl); | ||
327 | } | ||
328 | break; | ||
292 | default: | 329 | default: |
293 | /* No Digital Tv Support */ | 330 | /* No Digital Tv Support */ |
294 | break; | 331 | break; |
@@ -299,6 +336,8 @@ static int dvb_register(struct cx18_stream *stream) | |||
299 | return -1; | 336 | return -1; |
300 | } | 337 | } |
301 | 338 | ||
339 | dvb->fe->callback = cx18_reset_tuner_gpio; | ||
340 | |||
302 | ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe); | 341 | ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe); |
303 | if (ret < 0) { | 342 | if (ret < 0) { |
304 | if (dvb->fe->ops.release) | 343 | if (dvb->fe->ops.release) |
@@ -306,5 +345,16 @@ static int dvb_register(struct cx18_stream *stream) | |||
306 | return ret; | 345 | return ret; |
307 | } | 346 | } |
308 | 347 | ||
348 | /* | ||
349 | * The firmware seems to enable the TS DMUX clock | ||
350 | * under various circumstances. However, since we know we | ||
351 | * might use it, let's just turn it on ourselves here. | ||
352 | */ | ||
353 | cx18_write_reg_expect(cx, | ||
354 | (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK, | ||
355 | CX18_CLOCK_ENABLE2, | ||
356 | CX18_DMUX_CLK_MASK, | ||
357 | (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK); | ||
358 | |||
309 | return ret; | 359 | return ret; |
310 | } | 360 | } |
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index b3889c0b2697..29969c18949c 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c | |||
@@ -265,8 +265,13 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s, | |||
265 | * an MPEG-2 Program Pack start code, and provide only | 265 | * an MPEG-2 Program Pack start code, and provide only |
266 | * up to that point to the user, so it's easy to insert VBI data | 266 | * up to that point to the user, so it's easy to insert VBI data |
267 | * the next time around. | 267 | * the next time around. |
268 | * | ||
269 | * This will not work for an MPEG-2 TS and has only been | ||
270 | * verified by analysis to work for an MPEG-2 PS. Helen Buus | ||
271 | * pointed out this works for the CX23416 MPEG-2 DVD compatible | ||
272 | * stream, and research indicates both the MPEG 2 SVCD and DVD | ||
273 | * stream types use an MPEG-2 PS container. | ||
268 | */ | 274 | */ |
269 | /* FIXME - This only works for an MPEG-2 PS, not a TS */ | ||
270 | /* | 275 | /* |
271 | * An MPEG-2 Program Stream (PS) is a series of | 276 | * An MPEG-2 Program Stream (PS) is a series of |
272 | * MPEG-2 Program Packs terminated by an | 277 | * MPEG-2 Program Packs terminated by an |
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 2226e5791e99..afe46c3d4057 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c | |||
@@ -131,7 +131,7 @@ static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name) | |||
131 | * Functions that run in a work_queue work handling context | 131 | * Functions that run in a work_queue work handling context |
132 | */ | 132 | */ |
133 | 133 | ||
134 | static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order) | 134 | static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) |
135 | { | 135 | { |
136 | u32 handle, mdl_ack_count, id; | 136 | u32 handle, mdl_ack_count, id; |
137 | struct cx18_mailbox *mb; | 137 | struct cx18_mailbox *mb; |
@@ -191,29 +191,30 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
191 | if (buf == NULL) { | 191 | if (buf == NULL) { |
192 | CX18_WARN("Could not find buf %d for stream %s\n", | 192 | CX18_WARN("Could not find buf %d for stream %s\n", |
193 | id, s->name); | 193 | id, s->name); |
194 | /* Put as many buffers as possible back into fw use */ | ||
195 | cx18_stream_load_fw_queue(s); | ||
196 | continue; | 194 | continue; |
197 | } | 195 | } |
198 | 196 | ||
199 | if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { | 197 | CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n", |
200 | CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n", | 198 | s->name, buf->bytesused); |
201 | buf->bytesused); | 199 | |
202 | dvb_dmx_swfilter(&s->dvb.demux, buf->buf, | 200 | if (s->type != CX18_ENC_STREAM_TYPE_TS) |
203 | buf->bytesused); | 201 | cx18_enqueue(s, buf, &s->q_full); |
202 | else { | ||
203 | if (s->dvb.enabled) | ||
204 | dvb_dmx_swfilter(&s->dvb.demux, buf->buf, | ||
205 | buf->bytesused); | ||
206 | cx18_enqueue(s, buf, &s->q_free); | ||
204 | } | 207 | } |
205 | /* Put as many buffers as possible back into fw use */ | ||
206 | cx18_stream_load_fw_queue(s); | ||
207 | /* Put back TS buffer, since it was removed from all queues */ | ||
208 | if (s->type == CX18_ENC_STREAM_TYPE_TS) | ||
209 | cx18_stream_put_buf_fw(s, buf); | ||
210 | } | 208 | } |
209 | /* Put as many buffers as possible back into fw use */ | ||
210 | cx18_stream_load_fw_queue(s); | ||
211 | |||
211 | wake_up(&cx->dma_waitq); | 212 | wake_up(&cx->dma_waitq); |
212 | if (s->id != -1) | 213 | if (s->id != -1) |
213 | wake_up(&s->waitq); | 214 | wake_up(&s->waitq); |
214 | } | 215 | } |
215 | 216 | ||
216 | static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order) | 217 | static void epu_debug(struct cx18 *cx, struct cx18_in_work_order *order) |
217 | { | 218 | { |
218 | char *p; | 219 | char *p; |
219 | char *str = order->str; | 220 | char *str = order->str; |
@@ -224,7 +225,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
224 | CX18_INFO("FW version: %s\n", p - 1); | 225 | CX18_INFO("FW version: %s\n", p - 1); |
225 | } | 226 | } |
226 | 227 | ||
227 | static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order) | 228 | static void epu_cmd(struct cx18 *cx, struct cx18_in_work_order *order) |
228 | { | 229 | { |
229 | switch (order->rpu) { | 230 | switch (order->rpu) { |
230 | case CPU: | 231 | case CPU: |
@@ -253,18 +254,18 @@ static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
253 | } | 254 | } |
254 | 255 | ||
255 | static | 256 | static |
256 | void free_epu_work_order(struct cx18 *cx, struct cx18_epu_work_order *order) | 257 | void free_in_work_order(struct cx18 *cx, struct cx18_in_work_order *order) |
257 | { | 258 | { |
258 | atomic_set(&order->pending, 0); | 259 | atomic_set(&order->pending, 0); |
259 | } | 260 | } |
260 | 261 | ||
261 | void cx18_epu_work_handler(struct work_struct *work) | 262 | void cx18_in_work_handler(struct work_struct *work) |
262 | { | 263 | { |
263 | struct cx18_epu_work_order *order = | 264 | struct cx18_in_work_order *order = |
264 | container_of(work, struct cx18_epu_work_order, work); | 265 | container_of(work, struct cx18_in_work_order, work); |
265 | struct cx18 *cx = order->cx; | 266 | struct cx18 *cx = order->cx; |
266 | epu_cmd(cx, order); | 267 | epu_cmd(cx, order); |
267 | free_epu_work_order(cx, order); | 268 | free_in_work_order(cx, order); |
268 | } | 269 | } |
269 | 270 | ||
270 | 271 | ||
@@ -272,7 +273,7 @@ void cx18_epu_work_handler(struct work_struct *work) | |||
272 | * Functions that run in an interrupt handling context | 273 | * Functions that run in an interrupt handling context |
273 | */ | 274 | */ |
274 | 275 | ||
275 | static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | 276 | static void mb_ack_irq(struct cx18 *cx, struct cx18_in_work_order *order) |
276 | { | 277 | { |
277 | struct cx18_mailbox __iomem *ack_mb; | 278 | struct cx18_mailbox __iomem *ack_mb; |
278 | u32 ack_irq, req; | 279 | u32 ack_irq, req; |
@@ -308,7 +309,7 @@ static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
308 | return; | 309 | return; |
309 | } | 310 | } |
310 | 311 | ||
311 | static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | 312 | static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order) |
312 | { | 313 | { |
313 | u32 handle, mdl_ack_offset, mdl_ack_count; | 314 | u32 handle, mdl_ack_offset, mdl_ack_count; |
314 | struct cx18_mailbox *mb; | 315 | struct cx18_mailbox *mb; |
@@ -334,7 +335,7 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
334 | } | 335 | } |
335 | 336 | ||
336 | static | 337 | static |
337 | int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | 338 | int epu_debug_irq(struct cx18 *cx, struct cx18_in_work_order *order) |
338 | { | 339 | { |
339 | u32 str_offset; | 340 | u32 str_offset; |
340 | char *str = order->str; | 341 | char *str = order->str; |
@@ -355,7 +356,7 @@ int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
355 | } | 356 | } |
356 | 357 | ||
357 | static inline | 358 | static inline |
358 | int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | 359 | int epu_cmd_irq(struct cx18 *cx, struct cx18_in_work_order *order) |
359 | { | 360 | { |
360 | int ret = -1; | 361 | int ret = -1; |
361 | 362 | ||
@@ -387,12 +388,12 @@ int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
387 | } | 388 | } |
388 | 389 | ||
389 | static inline | 390 | static inline |
390 | struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx) | 391 | struct cx18_in_work_order *alloc_in_work_order_irq(struct cx18 *cx) |
391 | { | 392 | { |
392 | int i; | 393 | int i; |
393 | struct cx18_epu_work_order *order = NULL; | 394 | struct cx18_in_work_order *order = NULL; |
394 | 395 | ||
395 | for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) { | 396 | for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) { |
396 | /* | 397 | /* |
397 | * We only need "pending" atomic to inspect its contents, | 398 | * We only need "pending" atomic to inspect its contents, |
398 | * and need not do a check and set because: | 399 | * and need not do a check and set because: |
@@ -401,8 +402,8 @@ struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx) | |||
401 | * 2. "pending" is only set here, and we're serialized because | 402 | * 2. "pending" is only set here, and we're serialized because |
402 | * we're called in an IRQ handler context. | 403 | * we're called in an IRQ handler context. |
403 | */ | 404 | */ |
404 | if (atomic_read(&cx->epu_work_order[i].pending) == 0) { | 405 | if (atomic_read(&cx->in_work_order[i].pending) == 0) { |
405 | order = &cx->epu_work_order[i]; | 406 | order = &cx->in_work_order[i]; |
406 | atomic_set(&order->pending, 1); | 407 | atomic_set(&order->pending, 1); |
407 | break; | 408 | break; |
408 | } | 409 | } |
@@ -414,7 +415,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) | |||
414 | { | 415 | { |
415 | struct cx18_mailbox __iomem *mb; | 416 | struct cx18_mailbox __iomem *mb; |
416 | struct cx18_mailbox *order_mb; | 417 | struct cx18_mailbox *order_mb; |
417 | struct cx18_epu_work_order *order; | 418 | struct cx18_in_work_order *order; |
418 | int submit; | 419 | int submit; |
419 | 420 | ||
420 | switch (rpu) { | 421 | switch (rpu) { |
@@ -428,7 +429,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) | |||
428 | return; | 429 | return; |
429 | } | 430 | } |
430 | 431 | ||
431 | order = alloc_epu_work_order_irq(cx); | 432 | order = alloc_in_work_order_irq(cx); |
432 | if (order == NULL) { | 433 | if (order == NULL) { |
433 | CX18_WARN("Unable to find blank work order form to schedule " | 434 | CX18_WARN("Unable to find blank work order form to schedule " |
434 | "incoming mailbox command processing\n"); | 435 | "incoming mailbox command processing\n"); |
@@ -461,7 +462,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) | |||
461 | */ | 462 | */ |
462 | submit = epu_cmd_irq(cx, order); | 463 | submit = epu_cmd_irq(cx, order); |
463 | if (submit > 0) { | 464 | if (submit > 0) { |
464 | queue_work(cx->work_queue, &order->work); | 465 | queue_work(cx->in_work_queue, &order->work); |
465 | } | 466 | } |
466 | } | 467 | } |
467 | 468 | ||
@@ -478,9 +479,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) | |||
478 | u32 __iomem *xpu_state; | 479 | u32 __iomem *xpu_state; |
479 | wait_queue_head_t *waitq; | 480 | wait_queue_head_t *waitq; |
480 | struct mutex *mb_lock; | 481 | struct mutex *mb_lock; |
481 | long int timeout, ret; | 482 | unsigned long int t0, timeout, ret; |
482 | int i; | 483 | int i; |
483 | char argstr[MAX_MB_ARGUMENTS*11+1]; | 484 | char argstr[MAX_MB_ARGUMENTS*11+1]; |
485 | DEFINE_WAIT(w); | ||
484 | 486 | ||
485 | if (info == NULL) { | 487 | if (info == NULL) { |
486 | CX18_WARN("unknown cmd %x\n", cmd); | 488 | CX18_WARN("unknown cmd %x\n", cmd); |
@@ -562,25 +564,49 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) | |||
562 | 564 | ||
563 | CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n", | 565 | CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n", |
564 | irq, info->name); | 566 | irq, info->name); |
567 | |||
568 | /* So we don't miss the wakeup, prepare to wait before notifying fw */ | ||
569 | prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE); | ||
565 | cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); | 570 | cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); |
566 | 571 | ||
567 | ret = wait_event_timeout( | 572 | t0 = jiffies; |
568 | *waitq, | 573 | ack = cx18_readl(cx, &mb->ack); |
569 | cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request), | 574 | if (ack != req) { |
570 | timeout); | 575 | schedule_timeout(timeout); |
576 | ret = jiffies - t0; | ||
577 | ack = cx18_readl(cx, &mb->ack); | ||
578 | } else { | ||
579 | ret = jiffies - t0; | ||
580 | } | ||
571 | 581 | ||
572 | if (ret == 0) { | 582 | finish_wait(waitq, &w); |
573 | /* Timed out */ | 583 | |
584 | if (req != ack) { | ||
574 | mutex_unlock(mb_lock); | 585 | mutex_unlock(mb_lock); |
575 | CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU " | 586 | if (ret >= timeout) { |
576 | "acknowledgement\n", | 587 | /* Timed out */ |
577 | info->name, jiffies_to_msecs(timeout)); | 588 | CX18_DEBUG_WARN("sending %s timed out waiting %d msecs " |
589 | "for RPU acknowledgement\n", | ||
590 | info->name, jiffies_to_msecs(ret)); | ||
591 | } else { | ||
592 | CX18_DEBUG_WARN("woken up before mailbox ack was ready " | ||
593 | "after submitting %s to RPU. only " | ||
594 | "waited %d msecs on req %u but awakened" | ||
595 | " with unmatched ack %u\n", | ||
596 | info->name, | ||
597 | jiffies_to_msecs(ret), | ||
598 | req, ack); | ||
599 | } | ||
578 | return -EINVAL; | 600 | return -EINVAL; |
579 | } | 601 | } |
580 | 602 | ||
581 | if (ret != timeout) | 603 | if (ret >= timeout) |
604 | CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment " | ||
605 | "sending %s; timed out waiting %d msecs\n", | ||
606 | info->name, jiffies_to_msecs(ret)); | ||
607 | else | ||
582 | CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n", | 608 | CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n", |
583 | jiffies_to_msecs(timeout-ret), info->name); | 609 | jiffies_to_msecs(ret), info->name); |
584 | 610 | ||
585 | /* Collect data returned by the XPU */ | 611 | /* Collect data returned by the XPU */ |
586 | for (i = 0; i < MAX_MB_ARGUMENTS; i++) | 612 | for (i = 0; i < MAX_MB_ARGUMENTS; i++) |
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h index ce2b6686aa00..e23aaac5b280 100644 --- a/drivers/media/video/cx18/cx18-mailbox.h +++ b/drivers/media/video/cx18/cx18-mailbox.h | |||
@@ -95,6 +95,6 @@ int cx18_api_func(void *priv, u32 cmd, int in, int out, | |||
95 | 95 | ||
96 | void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu); | 96 | void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu); |
97 | 97 | ||
98 | void cx18_epu_work_handler(struct work_struct *work); | 98 | void cx18_in_work_handler(struct work_struct *work); |
99 | 99 | ||
100 | #endif | 100 | #endif |
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index 3046b8e74345..fa1ed7897d97 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c | |||
@@ -23,8 +23,8 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "cx18-driver.h" | 25 | #include "cx18-driver.h" |
26 | #include "cx18-streams.h" | ||
27 | #include "cx18-queue.h" | 26 | #include "cx18-queue.h" |
27 | #include "cx18-streams.h" | ||
28 | #include "cx18-scb.h" | 28 | #include "cx18-scb.h" |
29 | 29 | ||
30 | void cx18_buf_swap(struct cx18_buffer *buf) | 30 | void cx18_buf_swap(struct cx18_buffer *buf) |
@@ -53,13 +53,13 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, | |||
53 | buf->skipped = 0; | 53 | buf->skipped = 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | mutex_lock(&s->qlock); | ||
57 | |||
58 | /* q_busy is restricted to a max buffer count imposed by firmware */ | 56 | /* q_busy is restricted to a max buffer count imposed by firmware */ |
59 | if (q == &s->q_busy && | 57 | if (q == &s->q_busy && |
60 | atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) | 58 | atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) |
61 | q = &s->q_free; | 59 | q = &s->q_free; |
62 | 60 | ||
61 | spin_lock(&q->lock); | ||
62 | |||
63 | if (to_front) | 63 | if (to_front) |
64 | list_add(&buf->list, &q->list); /* LIFO */ | 64 | list_add(&buf->list, &q->list); /* LIFO */ |
65 | else | 65 | else |
@@ -67,7 +67,7 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, | |||
67 | q->bytesused += buf->bytesused - buf->readpos; | 67 | q->bytesused += buf->bytesused - buf->readpos; |
68 | atomic_inc(&q->buffers); | 68 | atomic_inc(&q->buffers); |
69 | 69 | ||
70 | mutex_unlock(&s->qlock); | 70 | spin_unlock(&q->lock); |
71 | return q; | 71 | return q; |
72 | } | 72 | } |
73 | 73 | ||
@@ -75,7 +75,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) | |||
75 | { | 75 | { |
76 | struct cx18_buffer *buf = NULL; | 76 | struct cx18_buffer *buf = NULL; |
77 | 77 | ||
78 | mutex_lock(&s->qlock); | 78 | spin_lock(&q->lock); |
79 | if (!list_empty(&q->list)) { | 79 | if (!list_empty(&q->list)) { |
80 | buf = list_first_entry(&q->list, struct cx18_buffer, list); | 80 | buf = list_first_entry(&q->list, struct cx18_buffer, list); |
81 | list_del_init(&buf->list); | 81 | list_del_init(&buf->list); |
@@ -83,7 +83,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) | |||
83 | buf->skipped = 0; | 83 | buf->skipped = 0; |
84 | atomic_dec(&q->buffers); | 84 | atomic_dec(&q->buffers); |
85 | } | 85 | } |
86 | mutex_unlock(&s->qlock); | 86 | spin_unlock(&q->lock); |
87 | return buf; | 87 | return buf; |
88 | } | 88 | } |
89 | 89 | ||
@@ -94,9 +94,23 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, | |||
94 | struct cx18_buffer *buf; | 94 | struct cx18_buffer *buf; |
95 | struct cx18_buffer *tmp; | 95 | struct cx18_buffer *tmp; |
96 | struct cx18_buffer *ret = NULL; | 96 | struct cx18_buffer *ret = NULL; |
97 | 97 | LIST_HEAD(sweep_up); | |
98 | mutex_lock(&s->qlock); | 98 | |
99 | /* | ||
100 | * We don't have to acquire multiple q locks here, because we are | ||
101 | * serialized by the single threaded work handler. | ||
102 | * Buffers from the firmware will thus remain in order as | ||
103 | * they are moved from q_busy to q_full or to the dvb ring buffer. | ||
104 | */ | ||
105 | spin_lock(&s->q_busy.lock); | ||
99 | list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) { | 106 | list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) { |
107 | /* | ||
108 | * We should find what the firmware told us is done, | ||
109 | * right at the front of the queue. If we don't, we likely have | ||
110 | * missed a buffer done message from the firmware. | ||
111 | * Once we skip a buffer repeatedly, relative to the size of | ||
112 | * q_busy, we have high confidence we've missed it. | ||
113 | */ | ||
100 | if (buf->id != id) { | 114 | if (buf->id != id) { |
101 | buf->skipped++; | 115 | buf->skipped++; |
102 | if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) { | 116 | if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) { |
@@ -105,38 +119,41 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, | |||
105 | "times - it must have dropped out of " | 119 | "times - it must have dropped out of " |
106 | "rotation\n", s->name, buf->id, | 120 | "rotation\n", s->name, buf->id, |
107 | buf->skipped); | 121 | buf->skipped); |
108 | /* move it to q_free */ | 122 | /* Sweep it up to put it back into rotation */ |
109 | list_move_tail(&buf->list, &s->q_free.list); | 123 | list_move_tail(&buf->list, &sweep_up); |
110 | buf->bytesused = buf->readpos = buf->b_flags = | ||
111 | buf->skipped = 0; | ||
112 | atomic_dec(&s->q_busy.buffers); | 124 | atomic_dec(&s->q_busy.buffers); |
113 | atomic_inc(&s->q_free.buffers); | ||
114 | } | 125 | } |
115 | continue; | 126 | continue; |
116 | } | 127 | } |
117 | 128 | /* | |
118 | buf->bytesused = bytesused; | 129 | * We pull the desired buffer off of the queue here. Something |
119 | /* Sync the buffer before we release the qlock */ | 130 | * will have to put it back on a queue later. |
120 | cx18_buf_sync_for_cpu(s, buf); | 131 | */ |
121 | if (s->type == CX18_ENC_STREAM_TYPE_TS) { | 132 | list_del_init(&buf->list); |
122 | /* | ||
123 | * TS doesn't use q_full. As we pull the buffer off of | ||
124 | * the queue here, the caller will have to put it back. | ||
125 | */ | ||
126 | list_del_init(&buf->list); | ||
127 | } else { | ||
128 | /* Move buffer from q_busy to q_full */ | ||
129 | list_move_tail(&buf->list, &s->q_full.list); | ||
130 | set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); | ||
131 | s->q_full.bytesused += buf->bytesused; | ||
132 | atomic_inc(&s->q_full.buffers); | ||
133 | } | ||
134 | atomic_dec(&s->q_busy.buffers); | 133 | atomic_dec(&s->q_busy.buffers); |
135 | |||
136 | ret = buf; | 134 | ret = buf; |
137 | break; | 135 | break; |
138 | } | 136 | } |
139 | mutex_unlock(&s->qlock); | 137 | spin_unlock(&s->q_busy.lock); |
138 | |||
139 | /* | ||
140 | * We found the buffer for which we were looking. Get it ready for | ||
141 | * the caller to put on q_full or in the dvb ring buffer. | ||
142 | */ | ||
143 | if (ret != NULL) { | ||
144 | ret->bytesused = bytesused; | ||
145 | ret->skipped = 0; | ||
146 | /* readpos and b_flags were 0'ed when the buf went on q_busy */ | ||
147 | cx18_buf_sync_for_cpu(s, ret); | ||
148 | if (s->type != CX18_ENC_STREAM_TYPE_TS) | ||
149 | set_bit(CX18_F_B_NEED_BUF_SWAP, &ret->b_flags); | ||
150 | } | ||
151 | |||
152 | /* Put any buffers the firmware is ignoring back into normal rotation */ | ||
153 | list_for_each_entry_safe(buf, tmp, &sweep_up, list) { | ||
154 | list_del_init(&buf->list); | ||
155 | cx18_enqueue(s, buf, &s->q_free); | ||
156 | } | ||
140 | return ret; | 157 | return ret; |
141 | } | 158 | } |
142 | 159 | ||
@@ -148,7 +165,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) | |||
148 | if (q == &s->q_free) | 165 | if (q == &s->q_free) |
149 | return; | 166 | return; |
150 | 167 | ||
151 | mutex_lock(&s->qlock); | 168 | spin_lock(&q->lock); |
152 | while (!list_empty(&q->list)) { | 169 | while (!list_empty(&q->list)) { |
153 | buf = list_first_entry(&q->list, struct cx18_buffer, list); | 170 | buf = list_first_entry(&q->list, struct cx18_buffer, list); |
154 | list_move_tail(&buf->list, &s->q_free.list); | 171 | list_move_tail(&buf->list, &s->q_free.list); |
@@ -156,7 +173,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) | |||
156 | atomic_inc(&s->q_free.buffers); | 173 | atomic_inc(&s->q_free.buffers); |
157 | } | 174 | } |
158 | cx18_queue_init(q); | 175 | cx18_queue_init(q); |
159 | mutex_unlock(&s->qlock); | 176 | spin_unlock(&q->lock); |
160 | } | 177 | } |
161 | 178 | ||
162 | void cx18_flush_queues(struct cx18_stream *s) | 179 | void cx18_flush_queues(struct cx18_stream *s) |
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 0932b76b2373..54d248e16d85 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -116,12 +116,16 @@ static void cx18_stream_init(struct cx18 *cx, int type) | |||
116 | s->buffers = cx->stream_buffers[type]; | 116 | s->buffers = cx->stream_buffers[type]; |
117 | s->buf_size = cx->stream_buf_size[type]; | 117 | s->buf_size = cx->stream_buf_size[type]; |
118 | 118 | ||
119 | mutex_init(&s->qlock); | ||
120 | init_waitqueue_head(&s->waitq); | 119 | init_waitqueue_head(&s->waitq); |
121 | s->id = -1; | 120 | s->id = -1; |
121 | spin_lock_init(&s->q_free.lock); | ||
122 | cx18_queue_init(&s->q_free); | 122 | cx18_queue_init(&s->q_free); |
123 | spin_lock_init(&s->q_busy.lock); | ||
123 | cx18_queue_init(&s->q_busy); | 124 | cx18_queue_init(&s->q_busy); |
125 | spin_lock_init(&s->q_full.lock); | ||
124 | cx18_queue_init(&s->q_full); | 126 | cx18_queue_init(&s->q_full); |
127 | |||
128 | INIT_WORK(&s->out_work_order, cx18_out_work_handler); | ||
125 | } | 129 | } |
126 | 130 | ||
127 | static int cx18_prep_dev(struct cx18 *cx, int type) | 131 | static int cx18_prep_dev(struct cx18 *cx, int type) |
@@ -367,9 +371,14 @@ static void cx18_vbi_setup(struct cx18_stream *s) | |||
367 | * Tell the encoder to capture 21-4+1=18 lines per field, | 371 | * Tell the encoder to capture 21-4+1=18 lines per field, |
368 | * since we want lines 10 through 21. | 372 | * since we want lines 10 through 21. |
369 | * | 373 | * |
370 | * FIXME - revisit for 625/50 systems | 374 | * For 625/50 systems, according to the VIP 2 & BT.656 std: |
375 | * The EAV RP code's Field bit toggles on line 1, a few lines | ||
376 | * after the Vertcal Blank bit has already toggled. | ||
377 | * (We've actually set the digitizer so that the Field bit | ||
378 | * toggles on line 2.) Tell the encoder to capture 23-2+1=22 | ||
379 | * lines per field, since we want lines 6 through 23. | ||
371 | */ | 380 | */ |
372 | lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38; | 381 | lines = cx->is_60hz ? (21 - 4 + 1) * 2 : (23 - 2 + 1) * 2; |
373 | } | 382 | } |
374 | 383 | ||
375 | data[0] = s->handle; | 384 | data[0] = s->handle; |
@@ -431,14 +440,16 @@ static void cx18_vbi_setup(struct cx18_stream *s) | |||
431 | cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); | 440 | cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); |
432 | } | 441 | } |
433 | 442 | ||
434 | struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, | 443 | static |
435 | struct cx18_buffer *buf) | 444 | struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s, |
445 | struct cx18_buffer *buf) | ||
436 | { | 446 | { |
437 | struct cx18 *cx = s->cx; | 447 | struct cx18 *cx = s->cx; |
438 | struct cx18_queue *q; | 448 | struct cx18_queue *q; |
439 | 449 | ||
440 | /* Don't give it to the firmware, if we're not running a capture */ | 450 | /* Don't give it to the firmware, if we're not running a capture */ |
441 | if (s->handle == CX18_INVALID_TASK_HANDLE || | 451 | if (s->handle == CX18_INVALID_TASK_HANDLE || |
452 | test_bit(CX18_F_S_STOPPING, &s->s_flags) || | ||
442 | !test_bit(CX18_F_S_STREAMING, &s->s_flags)) | 453 | !test_bit(CX18_F_S_STREAMING, &s->s_flags)) |
443 | return cx18_enqueue(s, buf, &s->q_free); | 454 | return cx18_enqueue(s, buf, &s->q_free); |
444 | 455 | ||
@@ -453,7 +464,8 @@ struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, | |||
453 | return q; | 464 | return q; |
454 | } | 465 | } |
455 | 466 | ||
456 | void cx18_stream_load_fw_queue(struct cx18_stream *s) | 467 | static |
468 | void _cx18_stream_load_fw_queue(struct cx18_stream *s) | ||
457 | { | 469 | { |
458 | struct cx18_queue *q; | 470 | struct cx18_queue *q; |
459 | struct cx18_buffer *buf; | 471 | struct cx18_buffer *buf; |
@@ -467,11 +479,19 @@ void cx18_stream_load_fw_queue(struct cx18_stream *s) | |||
467 | buf = cx18_dequeue(s, &s->q_free); | 479 | buf = cx18_dequeue(s, &s->q_free); |
468 | if (buf == NULL) | 480 | if (buf == NULL) |
469 | break; | 481 | break; |
470 | q = cx18_stream_put_buf_fw(s, buf); | 482 | q = _cx18_stream_put_buf_fw(s, buf); |
471 | } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM | 483 | } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM |
472 | && q == &s->q_busy); | 484 | && q == &s->q_busy); |
473 | } | 485 | } |
474 | 486 | ||
487 | void cx18_out_work_handler(struct work_struct *work) | ||
488 | { | ||
489 | struct cx18_stream *s = | ||
490 | container_of(work, struct cx18_stream, out_work_order); | ||
491 | |||
492 | _cx18_stream_load_fw_queue(s); | ||
493 | } | ||
494 | |||
475 | int cx18_start_v4l2_encode_stream(struct cx18_stream *s) | 495 | int cx18_start_v4l2_encode_stream(struct cx18_stream *s) |
476 | { | 496 | { |
477 | u32 data[MAX_MB_ARGUMENTS]; | 497 | u32 data[MAX_MB_ARGUMENTS]; |
@@ -600,19 +620,20 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) | |||
600 | 620 | ||
601 | /* Init all the cpu_mdls for this stream */ | 621 | /* Init all the cpu_mdls for this stream */ |
602 | cx18_flush_queues(s); | 622 | cx18_flush_queues(s); |
603 | mutex_lock(&s->qlock); | 623 | spin_lock(&s->q_free.lock); |
604 | list_for_each_entry(buf, &s->q_free.list, list) { | 624 | list_for_each_entry(buf, &s->q_free.list, list) { |
605 | cx18_writel(cx, buf->dma_handle, | 625 | cx18_writel(cx, buf->dma_handle, |
606 | &cx->scb->cpu_mdl[buf->id].paddr); | 626 | &cx->scb->cpu_mdl[buf->id].paddr); |
607 | cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length); | 627 | cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length); |
608 | } | 628 | } |
609 | mutex_unlock(&s->qlock); | 629 | spin_unlock(&s->q_free.lock); |
610 | cx18_stream_load_fw_queue(s); | 630 | _cx18_stream_load_fw_queue(s); |
611 | 631 | ||
612 | /* begin_capture */ | 632 | /* begin_capture */ |
613 | if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { | 633 | if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { |
614 | CX18_DEBUG_WARN("Error starting capture!\n"); | 634 | CX18_DEBUG_WARN("Error starting capture!\n"); |
615 | /* Ensure we're really not capturing before releasing MDLs */ | 635 | /* Ensure we're really not capturing before releasing MDLs */ |
636 | set_bit(CX18_F_S_STOPPING, &s->s_flags); | ||
616 | if (s->type == CX18_ENC_STREAM_TYPE_MPG) | 637 | if (s->type == CX18_ENC_STREAM_TYPE_MPG) |
617 | cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1); | 638 | cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1); |
618 | else | 639 | else |
@@ -622,6 +643,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) | |||
622 | cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); | 643 | cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); |
623 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); | 644 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); |
624 | s->handle = CX18_INVALID_TASK_HANDLE; | 645 | s->handle = CX18_INVALID_TASK_HANDLE; |
646 | clear_bit(CX18_F_S_STOPPING, &s->s_flags); | ||
625 | if (atomic_read(&cx->tot_capturing) == 0) { | 647 | if (atomic_read(&cx->tot_capturing) == 0) { |
626 | set_bit(CX18_F_I_EOS, &cx->i_flags); | 648 | set_bit(CX18_F_I_EOS, &cx->i_flags); |
627 | cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK); | 649 | cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK); |
@@ -666,6 +688,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) | |||
666 | if (atomic_read(&cx->tot_capturing) == 0) | 688 | if (atomic_read(&cx->tot_capturing) == 0) |
667 | return 0; | 689 | return 0; |
668 | 690 | ||
691 | set_bit(CX18_F_S_STOPPING, &s->s_flags); | ||
669 | if (s->type == CX18_ENC_STREAM_TYPE_MPG) | 692 | if (s->type == CX18_ENC_STREAM_TYPE_MPG) |
670 | cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end); | 693 | cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end); |
671 | else | 694 | else |
@@ -689,6 +712,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) | |||
689 | 712 | ||
690 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); | 713 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); |
691 | s->handle = CX18_INVALID_TASK_HANDLE; | 714 | s->handle = CX18_INVALID_TASK_HANDLE; |
715 | clear_bit(CX18_F_S_STOPPING, &s->s_flags); | ||
692 | 716 | ||
693 | if (atomic_read(&cx->tot_capturing) > 0) | 717 | if (atomic_read(&cx->tot_capturing) > 0) |
694 | return 0; | 718 | return 0; |
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h index 420e0a172945..1afc3fd9d822 100644 --- a/drivers/media/video/cx18/cx18-streams.h +++ b/drivers/media/video/cx18/cx18-streams.h | |||
@@ -28,10 +28,24 @@ int cx18_streams_setup(struct cx18 *cx); | |||
28 | int cx18_streams_register(struct cx18 *cx); | 28 | int cx18_streams_register(struct cx18 *cx); |
29 | void cx18_streams_cleanup(struct cx18 *cx, int unregister); | 29 | void cx18_streams_cleanup(struct cx18 *cx, int unregister); |
30 | 30 | ||
31 | /* Related to submission of buffers to firmware */ | ||
32 | static inline void cx18_stream_load_fw_queue(struct cx18_stream *s) | ||
33 | { | ||
34 | struct cx18 *cx = s->cx; | ||
35 | queue_work(cx->out_work_queue, &s->out_work_order); | ||
36 | } | ||
37 | |||
38 | static inline void cx18_stream_put_buf_fw(struct cx18_stream *s, | ||
39 | struct cx18_buffer *buf) | ||
40 | { | ||
41 | /* Put buf on q_free; the out work handler will move buf(s) to q_busy */ | ||
42 | cx18_enqueue(s, buf, &s->q_free); | ||
43 | cx18_stream_load_fw_queue(s); | ||
44 | } | ||
45 | |||
46 | void cx18_out_work_handler(struct work_struct *work); | ||
47 | |||
31 | /* Capture related */ | 48 | /* Capture related */ |
32 | void cx18_stream_load_fw_queue(struct cx18_stream *s); | ||
33 | struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, | ||
34 | struct cx18_buffer *buf); | ||
35 | int cx18_start_v4l2_encode_stream(struct cx18_stream *s); | 49 | int cx18_start_v4l2_encode_stream(struct cx18_stream *s); |
36 | int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end); | 50 | int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end); |
37 | 51 | ||
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h index bd9bd44da791..45494b094e7f 100644 --- a/drivers/media/video/cx18/cx18-version.h +++ b/drivers/media/video/cx18/cx18-version.h | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #define CX18_DRIVER_NAME "cx18" | 25 | #define CX18_DRIVER_NAME "cx18" |
26 | #define CX18_DRIVER_VERSION_MAJOR 1 | 26 | #define CX18_DRIVER_VERSION_MAJOR 1 |
27 | #define CX18_DRIVER_VERSION_MINOR 1 | 27 | #define CX18_DRIVER_VERSION_MINOR 2 |
28 | #define CX18_DRIVER_VERSION_PATCHLEVEL 0 | 28 | #define CX18_DRIVER_VERSION_PATCHLEVEL 0 |
29 | 29 | ||
30 | #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) | 30 | #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) |
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c index 1be3881be991..6a9464079b4c 100644 --- a/drivers/media/video/cx231xx/cx231xx-avcore.c +++ b/drivers/media/video/cx231xx/cx231xx-avcore.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/bitmap.h> | 29 | #include <linux/bitmap.h> |
30 | #include <linux/usb.h> | 30 | #include <linux/usb.h> |
31 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
32 | #include <linux/version.h> | ||
33 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
34 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
35 | 34 | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index c8a32b1b5381..63d2239fd324 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c | |||
@@ -281,12 +281,12 @@ static void cx231xx_config_tuner(struct cx231xx *dev) | |||
281 | } | 281 | } |
282 | 282 | ||
283 | /* ----------------------------------------------------------------------- */ | 283 | /* ----------------------------------------------------------------------- */ |
284 | void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir) | 284 | void cx231xx_register_i2c_ir(struct cx231xx *dev) |
285 | { | 285 | { |
286 | if (disable_ir) { | 286 | if (disable_ir) |
287 | ir->get_key = NULL; | ||
288 | return; | 287 | return; |
289 | } | 288 | |
289 | /* REVISIT: instantiate IR device */ | ||
290 | 290 | ||
291 | /* detect & configure */ | 291 | /* detect & configure */ |
292 | switch (dev->model) { | 292 | switch (dev->model) { |
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c index b4a03d813e00..33219dc4d649 100644 --- a/drivers/media/video/cx231xx/cx231xx-i2c.c +++ b/drivers/media/video/cx231xx/cx231xx-i2c.c | |||
@@ -424,34 +424,6 @@ static u32 functionality(struct i2c_adapter *adap) | |||
424 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; | 424 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; |
425 | } | 425 | } |
426 | 426 | ||
427 | /* | ||
428 | * attach_inform() | ||
429 | * gets called when a device attaches to the i2c bus | ||
430 | * does some basic configuration | ||
431 | */ | ||
432 | static int attach_inform(struct i2c_client *client) | ||
433 | { | ||
434 | struct cx231xx_i2c *bus = i2c_get_adapdata(client->adapter); | ||
435 | struct cx231xx *dev = bus->dev; | ||
436 | |||
437 | switch (client->addr << 1) { | ||
438 | case 0x8e: | ||
439 | { | ||
440 | struct IR_i2c *ir = i2c_get_clientdata(client); | ||
441 | dprintk1(1, "attach_inform: IR detected (%s).\n", | ||
442 | ir->phys); | ||
443 | cx231xx_set_ir(dev, ir); | ||
444 | break; | ||
445 | } | ||
446 | break; | ||
447 | |||
448 | default: | ||
449 | break; | ||
450 | } | ||
451 | |||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static struct i2c_algorithm cx231xx_algo = { | 427 | static struct i2c_algorithm cx231xx_algo = { |
456 | .master_xfer = cx231xx_i2c_xfer, | 428 | .master_xfer = cx231xx_i2c_xfer, |
457 | .functionality = functionality, | 429 | .functionality = functionality, |
@@ -462,7 +434,6 @@ static struct i2c_adapter cx231xx_adap_template = { | |||
462 | .name = "cx231xx", | 434 | .name = "cx231xx", |
463 | .id = I2C_HW_B_CX231XX, | 435 | .id = I2C_HW_B_CX231XX, |
464 | .algo = &cx231xx_algo, | 436 | .algo = &cx231xx_algo, |
465 | .client_register = attach_inform, | ||
466 | }; | 437 | }; |
467 | 438 | ||
468 | static struct i2c_client cx231xx_client_template = { | 439 | static struct i2c_client cx231xx_client_template = { |
@@ -537,6 +508,9 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) | |||
537 | if (0 == bus->i2c_rc) { | 508 | if (0 == bus->i2c_rc) { |
538 | if (i2c_scan) | 509 | if (i2c_scan) |
539 | cx231xx_do_i2c_scan(dev, &bus->i2c_client); | 510 | cx231xx_do_i2c_scan(dev, &bus->i2c_client); |
511 | |||
512 | /* Instantiate the IR receiver device, if present */ | ||
513 | cx231xx_register_i2c_ir(dev); | ||
540 | } else | 514 | } else |
541 | cx231xx_warn("%s: i2c bus %d register FAILED\n", | 515 | cx231xx_warn("%s: i2c bus %d register FAILED\n", |
542 | dev->name, bus->nr); | 516 | dev->name, bus->nr); |
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c index 97e304c3c799..48f22fa38e6c 100644 --- a/drivers/media/video/cx231xx/cx231xx-input.c +++ b/drivers/media/video/cx231xx/cx231xx-input.c | |||
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | |||
36 | 36 | ||
37 | #define i2cdprintk(fmt, arg...) \ | 37 | #define i2cdprintk(fmt, arg...) \ |
38 | if (ir_debug) { \ | 38 | if (ir_debug) { \ |
39 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \ | 39 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ |
40 | } | 40 | } |
41 | 41 | ||
42 | #define dprintk(fmt, arg...) \ | 42 | #define dprintk(fmt, arg...) \ |
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c index 94180526909c..e97b8023a655 100644 --- a/drivers/media/video/cx231xx/cx231xx-vbi.c +++ b/drivers/media/video/cx231xx/cx231xx-vbi.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/bitmap.h> | 26 | #include <linux/bitmap.h> |
27 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/version.h> | ||
30 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
31 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
32 | 31 | ||
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h index aa4a23ef491a..e38eb2d425f7 100644 --- a/drivers/media/video/cx231xx/cx231xx.h +++ b/drivers/media/video/cx231xx/cx231xx.h | |||
@@ -738,7 +738,7 @@ extern void cx231xx_card_setup(struct cx231xx *dev); | |||
738 | extern struct cx231xx_board cx231xx_boards[]; | 738 | extern struct cx231xx_board cx231xx_boards[]; |
739 | extern struct usb_device_id cx231xx_id_table[]; | 739 | extern struct usb_device_id cx231xx_id_table[]; |
740 | extern const unsigned int cx231xx_bcount; | 740 | extern const unsigned int cx231xx_bcount; |
741 | void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir); | 741 | void cx231xx_register_i2c_ir(struct cx231xx *dev); |
742 | int cx231xx_tuner_callback(void *ptr, int component, int command, int arg); | 742 | int cx231xx_tuner_callback(void *ptr, int component, int command, int arg); |
743 | 743 | ||
744 | /* Provided by cx231xx-input.c */ | 744 | /* Provided by cx231xx-input.c */ |
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c index 9a6536998d90..08582e58bdbf 100644 --- a/drivers/media/video/cx23885/cimax2.c +++ b/drivers/media/video/cx23885/cimax2.c | |||
@@ -312,7 +312,7 @@ static void netup_read_ci_status(struct work_struct *work) | |||
312 | "TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0], | 312 | "TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0], |
313 | buf[32]); | 313 | buf[32]); |
314 | 314 | ||
315 | if (buf[0] && 1) | 315 | if (buf[0] & 1) |
316 | state->status = DVB_CA_EN50221_POLL_CAM_PRESENT | | 316 | state->status = DVB_CA_EN50221_POLL_CAM_PRESENT | |
317 | DVB_CA_EN50221_POLL_CAM_READY; | 317 | DVB_CA_EN50221_POLL_CAM_READY; |
318 | else | 318 | else |
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 6f5df90af93e..2943bfd32a94 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c | |||
@@ -1742,7 +1742,6 @@ static struct video_device *cx23885_video_dev_alloc( | |||
1742 | if (NULL == vfd) | 1742 | if (NULL == vfd) |
1743 | return NULL; | 1743 | return NULL; |
1744 | *vfd = *template; | 1744 | *vfd = *template; |
1745 | vfd->minor = -1; | ||
1746 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, | 1745 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, |
1747 | type, cx23885_boards[tsport->dev->board].name); | 1746 | type, cx23885_boards[tsport->dev->board].name); |
1748 | vfd->parent = &pci->dev; | 1747 | vfd->parent = &pci->dev; |
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 6d6293f7d428..ce29b5e34a11 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c | |||
@@ -181,6 +181,26 @@ struct cx23885_board cx23885_boards[] = { | |||
181 | .portb = CX23885_MPEG_DVB, | 181 | .portb = CX23885_MPEG_DVB, |
182 | .portc = CX23885_MPEG_DVB, | 182 | .portc = CX23885_MPEG_DVB, |
183 | }, | 183 | }, |
184 | [CX23885_BOARD_HAUPPAUGE_HVR1270] = { | ||
185 | .name = "Hauppauge WinTV-HVR1270", | ||
186 | .portc = CX23885_MPEG_DVB, | ||
187 | }, | ||
188 | [CX23885_BOARD_HAUPPAUGE_HVR1275] = { | ||
189 | .name = "Hauppauge WinTV-HVR1275", | ||
190 | .portc = CX23885_MPEG_DVB, | ||
191 | }, | ||
192 | [CX23885_BOARD_HAUPPAUGE_HVR1255] = { | ||
193 | .name = "Hauppauge WinTV-HVR1255", | ||
194 | .portc = CX23885_MPEG_DVB, | ||
195 | }, | ||
196 | [CX23885_BOARD_HAUPPAUGE_HVR1210] = { | ||
197 | .name = "Hauppauge WinTV-HVR1210", | ||
198 | .portc = CX23885_MPEG_DVB, | ||
199 | }, | ||
200 | [CX23885_BOARD_MYGICA_X8506] = { | ||
201 | .name = "Mygica X8506 DMB-TH", | ||
202 | .portb = CX23885_MPEG_DVB, | ||
203 | }, | ||
184 | }; | 204 | }; |
185 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); | 205 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); |
186 | 206 | ||
@@ -280,6 +300,30 @@ struct cx23885_subid cx23885_subids[] = { | |||
280 | .subvendor = 0x1b55, | 300 | .subvendor = 0x1b55, |
281 | .subdevice = 0x2a2c, | 301 | .subdevice = 0x2a2c, |
282 | .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI, | 302 | .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI, |
303 | }, { | ||
304 | .subvendor = 0x0070, | ||
305 | .subdevice = 0x2211, | ||
306 | .card = CX23885_BOARD_HAUPPAUGE_HVR1270, | ||
307 | }, { | ||
308 | .subvendor = 0x0070, | ||
309 | .subdevice = 0x2215, | ||
310 | .card = CX23885_BOARD_HAUPPAUGE_HVR1275, | ||
311 | }, { | ||
312 | .subvendor = 0x0070, | ||
313 | .subdevice = 0x2251, | ||
314 | .card = CX23885_BOARD_HAUPPAUGE_HVR1255, | ||
315 | }, { | ||
316 | .subvendor = 0x0070, | ||
317 | .subdevice = 0x2291, | ||
318 | .card = CX23885_BOARD_HAUPPAUGE_HVR1210, | ||
319 | }, { | ||
320 | .subvendor = 0x0070, | ||
321 | .subdevice = 0x2295, | ||
322 | .card = CX23885_BOARD_HAUPPAUGE_HVR1210, | ||
323 | }, { | ||
324 | .subvendor = 0x14f1, | ||
325 | .subdevice = 0x8651, | ||
326 | .card = CX23885_BOARD_MYGICA_X8506, | ||
283 | }, | 327 | }, |
284 | }; | 328 | }; |
285 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); | 329 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); |
@@ -321,6 +365,42 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) | |||
321 | 365 | ||
322 | /* Make sure we support the board model */ | 366 | /* Make sure we support the board model */ |
323 | switch (tv.model) { | 367 | switch (tv.model) { |
368 | case 22001: | ||
369 | /* WinTV-HVR1270 (PCIe, Retail, half height) | ||
370 | * ATSC/QAM and basic analog, IR Blast */ | ||
371 | case 22009: | ||
372 | /* WinTV-HVR1210 (PCIe, Retail, half height) | ||
373 | * DVB-T and basic analog, IR Blast */ | ||
374 | case 22011: | ||
375 | /* WinTV-HVR1270 (PCIe, Retail, half height) | ||
376 | * ATSC/QAM and basic analog, IR Recv */ | ||
377 | case 22019: | ||
378 | /* WinTV-HVR1210 (PCIe, Retail, half height) | ||
379 | * DVB-T and basic analog, IR Recv */ | ||
380 | case 22021: | ||
381 | /* WinTV-HVR1275 (PCIe, Retail, half height) | ||
382 | * ATSC/QAM and basic analog, IR Recv */ | ||
383 | case 22029: | ||
384 | /* WinTV-HVR1210 (PCIe, Retail, half height) | ||
385 | * DVB-T and basic analog, IR Recv */ | ||
386 | case 22101: | ||
387 | /* WinTV-HVR1270 (PCIe, Retail, full height) | ||
388 | * ATSC/QAM and basic analog, IR Blast */ | ||
389 | case 22109: | ||
390 | /* WinTV-HVR1210 (PCIe, Retail, full height) | ||
391 | * DVB-T and basic analog, IR Blast */ | ||
392 | case 22111: | ||
393 | /* WinTV-HVR1270 (PCIe, Retail, full height) | ||
394 | * ATSC/QAM and basic analog, IR Recv */ | ||
395 | case 22119: | ||
396 | /* WinTV-HVR1210 (PCIe, Retail, full height) | ||
397 | * DVB-T and basic analog, IR Recv */ | ||
398 | case 22121: | ||
399 | /* WinTV-HVR1275 (PCIe, Retail, full height) | ||
400 | * ATSC/QAM and basic analog, IR Recv */ | ||
401 | case 22129: | ||
402 | /* WinTV-HVR1210 (PCIe, Retail, full height) | ||
403 | * DVB-T and basic analog, IR Recv */ | ||
324 | case 71009: | 404 | case 71009: |
325 | /* WinTV-HVR1200 (PCIe, Retail, full height) | 405 | /* WinTV-HVR1200 (PCIe, Retail, full height) |
326 | * DVB-T and basic analog */ | 406 | * DVB-T and basic analog */ |
@@ -619,6 +699,30 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
619 | /* enable irq */ | 699 | /* enable irq */ |
620 | cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ | 700 | cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ |
621 | break; | 701 | break; |
702 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | ||
703 | case CX23885_BOARD_HAUPPAUGE_HVR1275: | ||
704 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | ||
705 | case CX23885_BOARD_HAUPPAUGE_HVR1210: | ||
706 | /* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */ | ||
707 | /* GPIO-6 I2C Gate which can isolate the demod from the bus */ | ||
708 | /* GPIO-9 Demod reset */ | ||
709 | |||
710 | /* Put the parts into reset and back */ | ||
711 | cx23885_gpio_enable(dev, GPIO_9 | GPIO_6 | GPIO_5, 1); | ||
712 | cx23885_gpio_set(dev, GPIO_9 | GPIO_6 | GPIO_5); | ||
713 | cx23885_gpio_clear(dev, GPIO_9); | ||
714 | mdelay(20); | ||
715 | cx23885_gpio_set(dev, GPIO_9); | ||
716 | break; | ||
717 | case CX23885_BOARD_MYGICA_X8506: | ||
718 | /* GPIO-1 reset XC5000 */ | ||
719 | /* GPIO-2 reset LGS8GL5 */ | ||
720 | cx_set(GP0_IO, 0x00060000); | ||
721 | cx_clear(GP0_IO, 0x00000006); | ||
722 | mdelay(100); | ||
723 | cx_set(GP0_IO, 0x00060006); | ||
724 | mdelay(100); | ||
725 | break; | ||
622 | } | 726 | } |
623 | } | 727 | } |
624 | 728 | ||
@@ -631,6 +735,10 @@ int cx23885_ir_init(struct cx23885_dev *dev) | |||
631 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | 735 | case CX23885_BOARD_HAUPPAUGE_HVR1800: |
632 | case CX23885_BOARD_HAUPPAUGE_HVR1200: | 736 | case CX23885_BOARD_HAUPPAUGE_HVR1200: |
633 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | 737 | case CX23885_BOARD_HAUPPAUGE_HVR1400: |
738 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | ||
739 | case CX23885_BOARD_HAUPPAUGE_HVR1275: | ||
740 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | ||
741 | case CX23885_BOARD_HAUPPAUGE_HVR1210: | ||
634 | /* FIXME: Implement me */ | 742 | /* FIXME: Implement me */ |
635 | break; | 743 | break; |
636 | case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: | 744 | case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: |
@@ -666,6 +774,10 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
666 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: | 774 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: |
667 | case CX23885_BOARD_HAUPPAUGE_HVR1200: | 775 | case CX23885_BOARD_HAUPPAUGE_HVR1200: |
668 | case CX23885_BOARD_HAUPPAUGE_HVR1700: | 776 | case CX23885_BOARD_HAUPPAUGE_HVR1700: |
777 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | ||
778 | case CX23885_BOARD_HAUPPAUGE_HVR1275: | ||
779 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | ||
780 | case CX23885_BOARD_HAUPPAUGE_HVR1210: | ||
669 | if (dev->i2c_bus[0].i2c_rc == 0) | 781 | if (dev->i2c_bus[0].i2c_rc == 0) |
670 | hauppauge_eeprom(dev, eeprom+0xc0); | 782 | hauppauge_eeprom(dev, eeprom+0xc0); |
671 | break; | 783 | break; |
@@ -714,6 +826,11 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
714 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 826 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
715 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 827 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
716 | break; | 828 | break; |
829 | case CX23885_BOARD_MYGICA_X8506: | ||
830 | ts1->gen_ctrl_val = 0x5; /* Parallel */ | ||
831 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | ||
832 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | ||
833 | break; | ||
717 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 834 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
718 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 835 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
719 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 836 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
@@ -723,6 +840,10 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
723 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | 840 | case CX23885_BOARD_HAUPPAUGE_HVR1400: |
724 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: | 841 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: |
725 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: | 842 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: |
843 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | ||
844 | case CX23885_BOARD_HAUPPAUGE_HVR1275: | ||
845 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | ||
846 | case CX23885_BOARD_HAUPPAUGE_HVR1210: | ||
726 | default: | 847 | default: |
727 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ | 848 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ |
728 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 849 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index beda42925ce7..bf7bb1c412fb 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c | |||
@@ -1700,9 +1700,13 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) | |||
1700 | } | 1700 | } |
1701 | 1701 | ||
1702 | if (cx23885_boards[dev->board].cimax > 0 && | 1702 | if (cx23885_boards[dev->board].cimax > 0 && |
1703 | ((pci_status & PCI_MSK_GPIO0) || (pci_status & PCI_MSK_GPIO1))) | 1703 | ((pci_status & PCI_MSK_GPIO0) || |
1704 | /* handled += cx23885_irq_gpio(dev, pci_status); */ | 1704 | (pci_status & PCI_MSK_GPIO1))) { |
1705 | handled += netup_ci_slot_status(dev, pci_status); | 1705 | |
1706 | if (cx23885_boards[dev->board].cimax > 0) | ||
1707 | handled += netup_ci_slot_status(dev, pci_status); | ||
1708 | |||
1709 | } | ||
1706 | 1710 | ||
1707 | if (ts1_status) { | 1711 | if (ts1_status) { |
1708 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) | 1712 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) |
@@ -1729,6 +1733,88 @@ out: | |||
1729 | return IRQ_RETVAL(handled); | 1733 | return IRQ_RETVAL(handled); |
1730 | } | 1734 | } |
1731 | 1735 | ||
1736 | static inline int encoder_on_portb(struct cx23885_dev *dev) | ||
1737 | { | ||
1738 | return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER; | ||
1739 | } | ||
1740 | |||
1741 | static inline int encoder_on_portc(struct cx23885_dev *dev) | ||
1742 | { | ||
1743 | return cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER; | ||
1744 | } | ||
1745 | |||
1746 | /* Mask represents 32 different GPIOs, GPIO's are split into multiple | ||
1747 | * registers depending on the board configuration (and whether the | ||
1748 | * 417 encoder (wi it's own GPIO's) are present. Each GPIO bit will | ||
1749 | * be pushed into the correct hardware register, regardless of the | ||
1750 | * physical location. Certain registers are shared so we sanity check | ||
1751 | * and report errors if we think we're tampering with a GPIo that might | ||
1752 | * be assigned to the encoder (and used for the host bus). | ||
1753 | * | ||
1754 | * GPIO 2 thru 0 - On the cx23885 bridge | ||
1755 | * GPIO 18 thru 3 - On the cx23417 host bus interface | ||
1756 | * GPIO 23 thru 19 - On the cx25840 a/v core | ||
1757 | */ | ||
1758 | void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask) | ||
1759 | { | ||
1760 | if (mask & 0x7) | ||
1761 | cx_set(GP0_IO, mask & 0x7); | ||
1762 | |||
1763 | if (mask & 0x0007fff8) { | ||
1764 | if (encoder_on_portb(dev) || encoder_on_portc(dev)) | ||
1765 | printk(KERN_ERR | ||
1766 | "%s: Setting GPIO on encoder ports\n", | ||
1767 | dev->name); | ||
1768 | cx_set(MC417_RWD, (mask & 0x0007fff8) >> 3); | ||
1769 | } | ||
1770 | |||
1771 | /* TODO: 23-19 */ | ||
1772 | if (mask & 0x00f80000) | ||
1773 | printk(KERN_INFO "%s: Unsupported\n", dev->name); | ||
1774 | } | ||
1775 | |||
1776 | void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask) | ||
1777 | { | ||
1778 | if (mask & 0x00000007) | ||
1779 | cx_clear(GP0_IO, mask & 0x7); | ||
1780 | |||
1781 | if (mask & 0x0007fff8) { | ||
1782 | if (encoder_on_portb(dev) || encoder_on_portc(dev)) | ||
1783 | printk(KERN_ERR | ||
1784 | "%s: Clearing GPIO moving on encoder ports\n", | ||
1785 | dev->name); | ||
1786 | cx_clear(MC417_RWD, (mask & 0x7fff8) >> 3); | ||
1787 | } | ||
1788 | |||
1789 | /* TODO: 23-19 */ | ||
1790 | if (mask & 0x00f80000) | ||
1791 | printk(KERN_INFO "%s: Unsupported\n", dev->name); | ||
1792 | } | ||
1793 | |||
1794 | void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput) | ||
1795 | { | ||
1796 | if ((mask & 0x00000007) && asoutput) | ||
1797 | cx_set(GP0_IO, (mask & 0x7) << 16); | ||
1798 | else if ((mask & 0x00000007) && !asoutput) | ||
1799 | cx_clear(GP0_IO, (mask & 0x7) << 16); | ||
1800 | |||
1801 | if (mask & 0x0007fff8) { | ||
1802 | if (encoder_on_portb(dev) || encoder_on_portc(dev)) | ||
1803 | printk(KERN_ERR | ||
1804 | "%s: Enabling GPIO on encoder ports\n", | ||
1805 | dev->name); | ||
1806 | } | ||
1807 | |||
1808 | /* MC417_OEN is active low for output, write 1 for an input */ | ||
1809 | if ((mask & 0x0007fff8) && asoutput) | ||
1810 | cx_clear(MC417_OEN, (mask & 0x7fff8) >> 3); | ||
1811 | |||
1812 | else if ((mask & 0x0007fff8) && !asoutput) | ||
1813 | cx_set(MC417_OEN, (mask & 0x7fff8) >> 3); | ||
1814 | |||
1815 | /* TODO: 23-19 */ | ||
1816 | } | ||
1817 | |||
1732 | static int __devinit cx23885_initdev(struct pci_dev *pci_dev, | 1818 | static int __devinit cx23885_initdev(struct pci_dev *pci_dev, |
1733 | const struct pci_device_id *pci_id) | 1819 | const struct pci_device_id *pci_id) |
1734 | { | 1820 | { |
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 1dc070da8652..e236df23370e 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c | |||
@@ -49,8 +49,10 @@ | |||
49 | #include "lnbh24.h" | 49 | #include "lnbh24.h" |
50 | #include "cx24116.h" | 50 | #include "cx24116.h" |
51 | #include "cimax2.h" | 51 | #include "cimax2.h" |
52 | #include "lgs8gxx.h" | ||
52 | #include "netup-eeprom.h" | 53 | #include "netup-eeprom.h" |
53 | #include "netup-init.h" | 54 | #include "netup-init.h" |
55 | #include "lgdt3305.h" | ||
54 | 56 | ||
55 | static unsigned int debug; | 57 | static unsigned int debug; |
56 | 58 | ||
@@ -122,7 +124,22 @@ static struct tda10048_config hauppauge_hvr1200_config = { | |||
122 | .demod_address = 0x10 >> 1, | 124 | .demod_address = 0x10 >> 1, |
123 | .output_mode = TDA10048_SERIAL_OUTPUT, | 125 | .output_mode = TDA10048_SERIAL_OUTPUT, |
124 | .fwbulkwritelen = TDA10048_BULKWRITE_200, | 126 | .fwbulkwritelen = TDA10048_BULKWRITE_200, |
125 | .inversion = TDA10048_INVERSION_ON | 127 | .inversion = TDA10048_INVERSION_ON, |
128 | .dtv6_if_freq_khz = TDA10048_IF_3300, | ||
129 | .dtv7_if_freq_khz = TDA10048_IF_3800, | ||
130 | .dtv8_if_freq_khz = TDA10048_IF_4300, | ||
131 | .clk_freq_khz = TDA10048_CLK_16000, | ||
132 | }; | ||
133 | |||
134 | static struct tda10048_config hauppauge_hvr1210_config = { | ||
135 | .demod_address = 0x10 >> 1, | ||
136 | .output_mode = TDA10048_SERIAL_OUTPUT, | ||
137 | .fwbulkwritelen = TDA10048_BULKWRITE_200, | ||
138 | .inversion = TDA10048_INVERSION_ON, | ||
139 | .dtv6_if_freq_khz = TDA10048_IF_3300, | ||
140 | .dtv7_if_freq_khz = TDA10048_IF_3500, | ||
141 | .dtv8_if_freq_khz = TDA10048_IF_4000, | ||
142 | .clk_freq_khz = TDA10048_CLK_16000, | ||
126 | }; | 143 | }; |
127 | 144 | ||
128 | static struct s5h1409_config hauppauge_ezqam_config = { | 145 | static struct s5h1409_config hauppauge_ezqam_config = { |
@@ -194,6 +211,16 @@ static struct s5h1411_config dvico_s5h1411_config = { | |||
194 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 211 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
195 | }; | 212 | }; |
196 | 213 | ||
214 | static struct s5h1411_config hcw_s5h1411_config = { | ||
215 | .output_mode = S5H1411_SERIAL_OUTPUT, | ||
216 | .gpio = S5H1411_GPIO_OFF, | ||
217 | .vsb_if = S5H1411_IF_44000, | ||
218 | .qam_if = S5H1411_IF_4000, | ||
219 | .inversion = S5H1411_INVERSION_ON, | ||
220 | .status_mode = S5H1411_DEMODLOCKING, | ||
221 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | ||
222 | }; | ||
223 | |||
197 | static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { | 224 | static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { |
198 | .i2c_address = 0x61, | 225 | .i2c_address = 0x61, |
199 | .if_khz = 5380, | 226 | .if_khz = 5380, |
@@ -224,6 +251,32 @@ static struct tda18271_config hauppauge_hvr1200_tuner_config = { | |||
224 | .gate = TDA18271_GATE_ANALOG, | 251 | .gate = TDA18271_GATE_ANALOG, |
225 | }; | 252 | }; |
226 | 253 | ||
254 | static struct tda18271_config hauppauge_hvr1210_tuner_config = { | ||
255 | .gate = TDA18271_GATE_DIGITAL, | ||
256 | }; | ||
257 | |||
258 | static struct tda18271_std_map hauppauge_hvr127x_std_map = { | ||
259 | .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, | ||
260 | .if_lvl = 1, .rfagc_top = 0x58 }, | ||
261 | .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5, | ||
262 | .if_lvl = 1, .rfagc_top = 0x58 }, | ||
263 | }; | ||
264 | |||
265 | static struct tda18271_config hauppauge_hvr127x_config = { | ||
266 | .std_map = &hauppauge_hvr127x_std_map, | ||
267 | }; | ||
268 | |||
269 | static struct lgdt3305_config hauppauge_lgdt3305_config = { | ||
270 | .i2c_addr = 0x0e, | ||
271 | .mpeg_mode = LGDT3305_MPEG_SERIAL, | ||
272 | .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE, | ||
273 | .tpvalid_polarity = LGDT3305_TP_VALID_HIGH, | ||
274 | .deny_i2c_rptr = 1, | ||
275 | .spectral_inversion = 1, | ||
276 | .qam_if_khz = 4000, | ||
277 | .vsb_if_khz = 3250, | ||
278 | }; | ||
279 | |||
227 | static struct dibx000_agc_config xc3028_agc_config = { | 280 | static struct dibx000_agc_config xc3028_agc_config = { |
228 | BAND_VHF | BAND_UHF, /* band_caps */ | 281 | BAND_VHF | BAND_UHF, /* band_caps */ |
229 | 282 | ||
@@ -368,10 +421,29 @@ static struct cx24116_config dvbworld_cx24116_config = { | |||
368 | .demod_address = 0x05, | 421 | .demod_address = 0x05, |
369 | }; | 422 | }; |
370 | 423 | ||
424 | static struct lgs8gxx_config mygica_x8506_lgs8gl5_config = { | ||
425 | .prod = LGS8GXX_PROD_LGS8GL5, | ||
426 | .demod_address = 0x19, | ||
427 | .serial_ts = 0, | ||
428 | .ts_clk_pol = 1, | ||
429 | .ts_clk_gated = 1, | ||
430 | .if_clk_freq = 30400, /* 30.4 MHz */ | ||
431 | .if_freq = 5380, /* 5.38 MHz */ | ||
432 | .if_neg_center = 1, | ||
433 | .ext_adc = 0, | ||
434 | .adc_signed = 0, | ||
435 | .if_neg_edge = 0, | ||
436 | }; | ||
437 | |||
438 | static struct xc5000_config mygica_x8506_xc5000_config = { | ||
439 | .i2c_address = 0x61, | ||
440 | .if_khz = 5380, | ||
441 | }; | ||
442 | |||
371 | static int dvb_register(struct cx23885_tsport *port) | 443 | static int dvb_register(struct cx23885_tsport *port) |
372 | { | 444 | { |
373 | struct cx23885_dev *dev = port->dev; | 445 | struct cx23885_dev *dev = port->dev; |
374 | struct cx23885_i2c *i2c_bus = NULL; | 446 | struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; |
375 | struct videobuf_dvb_frontend *fe0; | 447 | struct videobuf_dvb_frontend *fe0; |
376 | int ret; | 448 | int ret; |
377 | 449 | ||
@@ -396,6 +468,29 @@ static int dvb_register(struct cx23885_tsport *port) | |||
396 | &hauppauge_generic_tunerconfig, 0); | 468 | &hauppauge_generic_tunerconfig, 0); |
397 | } | 469 | } |
398 | break; | 470 | break; |
471 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | ||
472 | case CX23885_BOARD_HAUPPAUGE_HVR1275: | ||
473 | i2c_bus = &dev->i2c_bus[0]; | ||
474 | fe0->dvb.frontend = dvb_attach(lgdt3305_attach, | ||
475 | &hauppauge_lgdt3305_config, | ||
476 | &i2c_bus->i2c_adap); | ||
477 | if (fe0->dvb.frontend != NULL) { | ||
478 | dvb_attach(tda18271_attach, fe0->dvb.frontend, | ||
479 | 0x60, &dev->i2c_bus[1].i2c_adap, | ||
480 | &hauppauge_hvr127x_config); | ||
481 | } | ||
482 | break; | ||
483 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | ||
484 | i2c_bus = &dev->i2c_bus[0]; | ||
485 | fe0->dvb.frontend = dvb_attach(s5h1411_attach, | ||
486 | &hcw_s5h1411_config, | ||
487 | &i2c_bus->i2c_adap); | ||
488 | if (fe0->dvb.frontend != NULL) { | ||
489 | dvb_attach(tda18271_attach, fe0->dvb.frontend, | ||
490 | 0x60, &dev->i2c_bus[1].i2c_adap, | ||
491 | &hauppauge_tda18271_config); | ||
492 | } | ||
493 | break; | ||
399 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | 494 | case CX23885_BOARD_HAUPPAUGE_HVR1800: |
400 | i2c_bus = &dev->i2c_bus[0]; | 495 | i2c_bus = &dev->i2c_bus[0]; |
401 | switch (alt_tuner) { | 496 | switch (alt_tuner) { |
@@ -496,6 +591,17 @@ static int dvb_register(struct cx23885_tsport *port) | |||
496 | &hauppauge_hvr1200_tuner_config); | 591 | &hauppauge_hvr1200_tuner_config); |
497 | } | 592 | } |
498 | break; | 593 | break; |
594 | case CX23885_BOARD_HAUPPAUGE_HVR1210: | ||
595 | i2c_bus = &dev->i2c_bus[0]; | ||
596 | fe0->dvb.frontend = dvb_attach(tda10048_attach, | ||
597 | &hauppauge_hvr1210_config, | ||
598 | &i2c_bus->i2c_adap); | ||
599 | if (fe0->dvb.frontend != NULL) { | ||
600 | dvb_attach(tda18271_attach, fe0->dvb.frontend, | ||
601 | 0x60, &dev->i2c_bus[1].i2c_adap, | ||
602 | &hauppauge_hvr1210_tuner_config); | ||
603 | } | ||
604 | break; | ||
499 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | 605 | case CX23885_BOARD_HAUPPAUGE_HVR1400: |
500 | i2c_bus = &dev->i2c_bus[0]; | 606 | i2c_bus = &dev->i2c_bus[0]; |
501 | fe0->dvb.frontend = dvb_attach(dib7000p_attach, | 607 | fe0->dvb.frontend = dvb_attach(dib7000p_attach, |
@@ -659,6 +765,19 @@ static int dvb_register(struct cx23885_tsport *port) | |||
659 | break; | 765 | break; |
660 | } | 766 | } |
661 | break; | 767 | break; |
768 | case CX23885_BOARD_MYGICA_X8506: | ||
769 | i2c_bus = &dev->i2c_bus[0]; | ||
770 | i2c_bus2 = &dev->i2c_bus[1]; | ||
771 | fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, | ||
772 | &mygica_x8506_lgs8gl5_config, | ||
773 | &i2c_bus->i2c_adap); | ||
774 | if (fe0->dvb.frontend != NULL) { | ||
775 | dvb_attach(xc5000_attach, | ||
776 | fe0->dvb.frontend, | ||
777 | &i2c_bus2->i2c_adap, | ||
778 | &mygica_x8506_xc5000_config); | ||
779 | } | ||
780 | break; | ||
662 | default: | 781 | default: |
663 | printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " | 782 | printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " |
664 | " isn't supported yet\n", | 783 | " isn't supported yet\n", |
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index 3421bd12056a..384dec34134f 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c | |||
@@ -357,6 +357,18 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) | |||
357 | printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", | 357 | printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", |
358 | dev->name, bus->nr); | 358 | dev->name, bus->nr); |
359 | 359 | ||
360 | /* Instantiate the IR receiver device, if present */ | ||
361 | if (0 == bus->i2c_rc) { | ||
362 | struct i2c_board_info info; | ||
363 | const unsigned short addr_list[] = { | ||
364 | 0x6b, I2C_CLIENT_END | ||
365 | }; | ||
366 | |||
367 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
368 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
369 | i2c_new_probed_device(&bus->i2c_adap, &info, addr_list); | ||
370 | } | ||
371 | |||
360 | return bus->i2c_rc; | 372 | return bus->i2c_rc; |
361 | } | 373 | } |
362 | 374 | ||
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 68068c6d0987..66bbd2e71105 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -796,6 +796,7 @@ static unsigned int video_poll(struct file *file, | |||
796 | { | 796 | { |
797 | struct cx23885_fh *fh = file->private_data; | 797 | struct cx23885_fh *fh = file->private_data; |
798 | struct cx23885_buffer *buf; | 798 | struct cx23885_buffer *buf; |
799 | unsigned int rc = POLLERR; | ||
799 | 800 | ||
800 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { | 801 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { |
801 | if (!res_get(fh->dev, fh, RESOURCE_VBI)) | 802 | if (!res_get(fh->dev, fh, RESOURCE_VBI)) |
@@ -803,23 +804,28 @@ static unsigned int video_poll(struct file *file, | |||
803 | return videobuf_poll_stream(file, &fh->vbiq, wait); | 804 | return videobuf_poll_stream(file, &fh->vbiq, wait); |
804 | } | 805 | } |
805 | 806 | ||
807 | mutex_lock(&fh->vidq.vb_lock); | ||
806 | if (res_check(fh, RESOURCE_VIDEO)) { | 808 | if (res_check(fh, RESOURCE_VIDEO)) { |
807 | /* streaming capture */ | 809 | /* streaming capture */ |
808 | if (list_empty(&fh->vidq.stream)) | 810 | if (list_empty(&fh->vidq.stream)) |
809 | return POLLERR; | 811 | goto done; |
810 | buf = list_entry(fh->vidq.stream.next, | 812 | buf = list_entry(fh->vidq.stream.next, |
811 | struct cx23885_buffer, vb.stream); | 813 | struct cx23885_buffer, vb.stream); |
812 | } else { | 814 | } else { |
813 | /* read() capture */ | 815 | /* read() capture */ |
814 | buf = (struct cx23885_buffer *)fh->vidq.read_buf; | 816 | buf = (struct cx23885_buffer *)fh->vidq.read_buf; |
815 | if (NULL == buf) | 817 | if (NULL == buf) |
816 | return POLLERR; | 818 | goto done; |
817 | } | 819 | } |
818 | poll_wait(file, &buf->vb.done, wait); | 820 | poll_wait(file, &buf->vb.done, wait); |
819 | if (buf->vb.state == VIDEOBUF_DONE || | 821 | if (buf->vb.state == VIDEOBUF_DONE || |
820 | buf->vb.state == VIDEOBUF_ERROR) | 822 | buf->vb.state == VIDEOBUF_ERROR) |
821 | return POLLIN|POLLRDNORM; | 823 | rc = POLLIN|POLLRDNORM; |
822 | return 0; | 824 | else |
825 | rc = 0; | ||
826 | done: | ||
827 | mutex_unlock(&fh->vidq.vb_lock); | ||
828 | return rc; | ||
823 | } | 829 | } |
824 | 830 | ||
825 | static int video_release(struct file *file) | 831 | static int video_release(struct file *file) |
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 85642831ea8e..1a2ac518a3f1 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h | |||
@@ -71,6 +71,22 @@ | |||
71 | #define CX23885_BOARD_TEVII_S470 15 | 71 | #define CX23885_BOARD_TEVII_S470 15 |
72 | #define CX23885_BOARD_DVBWORLD_2005 16 | 72 | #define CX23885_BOARD_DVBWORLD_2005 16 |
73 | #define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17 | 73 | #define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17 |
74 | #define CX23885_BOARD_HAUPPAUGE_HVR1270 18 | ||
75 | #define CX23885_BOARD_HAUPPAUGE_HVR1275 19 | ||
76 | #define CX23885_BOARD_HAUPPAUGE_HVR1255 20 | ||
77 | #define CX23885_BOARD_HAUPPAUGE_HVR1210 21 | ||
78 | #define CX23885_BOARD_MYGICA_X8506 22 | ||
79 | |||
80 | #define GPIO_0 0x00000001 | ||
81 | #define GPIO_1 0x00000002 | ||
82 | #define GPIO_2 0x00000004 | ||
83 | #define GPIO_3 0x00000008 | ||
84 | #define GPIO_4 0x00000010 | ||
85 | #define GPIO_5 0x00000020 | ||
86 | #define GPIO_6 0x00000040 | ||
87 | #define GPIO_7 0x00000080 | ||
88 | #define GPIO_8 0x00000100 | ||
89 | #define GPIO_9 0x00000200 | ||
74 | 90 | ||
75 | /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ | 91 | /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ |
76 | #define CX23885_NORMS (\ | 92 | #define CX23885_NORMS (\ |
@@ -422,6 +438,11 @@ extern int cx23885_restart_queue(struct cx23885_tsport *port, | |||
422 | extern void cx23885_wakeup(struct cx23885_tsport *port, | 438 | extern void cx23885_wakeup(struct cx23885_tsport *port, |
423 | struct cx23885_dmaqueue *q, u32 count); | 439 | struct cx23885_dmaqueue *q, u32 count); |
424 | 440 | ||
441 | extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask); | ||
442 | extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask); | ||
443 | extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, | ||
444 | int asoutput); | ||
445 | |||
425 | 446 | ||
426 | /* ----------------------------------------------------------- */ | 447 | /* ----------------------------------------------------------- */ |
427 | /* cx23885-cards.c */ | 448 | /* cx23885-cards.c */ |
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index b06b1275a9ec..5b7e26761f0a 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \ | 1 | cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \ |
2 | cx88-input.o | 2 | cx88-dsp.o cx88-input.o |
3 | cx8800-objs := cx88-video.o cx88-vbi.o | 3 | cx8800-objs := cx88-video.o cx88-vbi.o |
4 | cx8802-objs := cx88-mpeg.o | 4 | cx8802-objs := cx88-mpeg.o |
5 | 5 | ||
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 0ccdf36626e3..5a67445dd6ed 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -871,7 +871,7 @@ static struct pci_driver cx88_audio_pci_driver = { | |||
871 | .name = "cx88_audio", | 871 | .name = "cx88_audio", |
872 | .id_table = cx88_audio_pci_tbl, | 872 | .id_table = cx88_audio_pci_tbl, |
873 | .probe = cx88_audio_initdev, | 873 | .probe = cx88_audio_initdev, |
874 | .remove = cx88_audio_finidev, | 874 | .remove = __devexit_p(cx88_audio_finidev), |
875 | }; | 875 | }; |
876 | 876 | ||
877 | /**************************************************************************** | 877 | /**************************************************************************** |
@@ -881,7 +881,7 @@ static struct pci_driver cx88_audio_pci_driver = { | |||
881 | /* | 881 | /* |
882 | * module init | 882 | * module init |
883 | */ | 883 | */ |
884 | static int cx88_audio_init(void) | 884 | static int __init cx88_audio_init(void) |
885 | { | 885 | { |
886 | printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n", | 886 | printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n", |
887 | (CX88_VERSION_CODE >> 16) & 0xff, | 887 | (CX88_VERSION_CODE >> 16) & 0xff, |
@@ -897,9 +897,8 @@ static int cx88_audio_init(void) | |||
897 | /* | 897 | /* |
898 | * module remove | 898 | * module remove |
899 | */ | 899 | */ |
900 | static void cx88_audio_fini(void) | 900 | static void __exit cx88_audio_fini(void) |
901 | { | 901 | { |
902 | |||
903 | pci_unregister_driver(&cx88_audio_pci_driver); | 902 | pci_unregister_driver(&cx88_audio_pci_driver); |
904 | } | 903 | } |
905 | 904 | ||
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 6bbbfc66bb4b..94b7a52629d0 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -1969,6 +1969,54 @@ static const struct cx88_board cx88_boards[] = { | |||
1969 | }, | 1969 | }, |
1970 | .mpeg = CX88_MPEG_DVB, | 1970 | .mpeg = CX88_MPEG_DVB, |
1971 | }, | 1971 | }, |
1972 | [CX88_BOARD_HAUPPAUGE_IRONLY] = { | ||
1973 | .name = "Hauppauge WinTV-IR Only", | ||
1974 | .tuner_type = UNSET, | ||
1975 | .radio_type = UNSET, | ||
1976 | .tuner_addr = ADDR_UNSET, | ||
1977 | .radio_addr = ADDR_UNSET, | ||
1978 | }, | ||
1979 | [CX88_BOARD_WINFAST_DTV1800H] = { | ||
1980 | .name = "Leadtek WinFast DTV1800 Hybrid", | ||
1981 | .tuner_type = TUNER_XC2028, | ||
1982 | .radio_type = TUNER_XC2028, | ||
1983 | .tuner_addr = 0x61, | ||
1984 | .radio_addr = 0x61, | ||
1985 | /* | ||
1986 | * GPIO setting | ||
1987 | * | ||
1988 | * 2: mute (0=off,1=on) | ||
1989 | * 12: tuner reset pin | ||
1990 | * 13: audio source (0=tuner audio,1=line in) | ||
1991 | * 14: FM (0=on,1=off ???) | ||
1992 | */ | ||
1993 | .input = {{ | ||
1994 | .type = CX88_VMUX_TELEVISION, | ||
1995 | .vmux = 0, | ||
1996 | .gpio0 = 0x0400, /* pin 2 = 0 */ | ||
1997 | .gpio1 = 0x6040, /* pin 13 = 0, pin 14 = 1 */ | ||
1998 | .gpio2 = 0x0000, | ||
1999 | }, { | ||
2000 | .type = CX88_VMUX_COMPOSITE1, | ||
2001 | .vmux = 1, | ||
2002 | .gpio0 = 0x0400, /* pin 2 = 0 */ | ||
2003 | .gpio1 = 0x6060, /* pin 13 = 1, pin 14 = 1 */ | ||
2004 | .gpio2 = 0x0000, | ||
2005 | }, { | ||
2006 | .type = CX88_VMUX_SVIDEO, | ||
2007 | .vmux = 2, | ||
2008 | .gpio0 = 0x0400, /* pin 2 = 0 */ | ||
2009 | .gpio1 = 0x6060, /* pin 13 = 1, pin 14 = 1 */ | ||
2010 | .gpio2 = 0x0000, | ||
2011 | } }, | ||
2012 | .radio = { | ||
2013 | .type = CX88_RADIO, | ||
2014 | .gpio0 = 0x0400, /* pin 2 = 0 */ | ||
2015 | .gpio1 = 0x6000, /* pin 13 = 0, pin 14 = 0 */ | ||
2016 | .gpio2 = 0x0000, | ||
2017 | }, | ||
2018 | .mpeg = CX88_MPEG_DVB, | ||
2019 | }, | ||
1972 | }; | 2020 | }; |
1973 | 2021 | ||
1974 | /* ------------------------------------------------------------------ */ | 2022 | /* ------------------------------------------------------------------ */ |
@@ -2382,6 +2430,14 @@ static const struct cx88_subid cx88_subids[] = { | |||
2382 | .subvendor = 0x153b, | 2430 | .subvendor = 0x153b, |
2383 | .subdevice = 0x1177, | 2431 | .subdevice = 0x1177, |
2384 | .card = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII, | 2432 | .card = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII, |
2433 | }, { | ||
2434 | .subvendor = 0x0070, | ||
2435 | .subdevice = 0x9290, | ||
2436 | .card = CX88_BOARD_HAUPPAUGE_IRONLY, | ||
2437 | }, { | ||
2438 | .subvendor = 0x107d, | ||
2439 | .subdevice = 0x6654, | ||
2440 | .card = CX88_BOARD_WINFAST_DTV1800H, | ||
2385 | }, | 2441 | }, |
2386 | }; | 2442 | }; |
2387 | 2443 | ||
@@ -2448,6 +2504,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
2448 | case 90500: /* Nova-T-PCI (oem) */ | 2504 | case 90500: /* Nova-T-PCI (oem) */ |
2449 | case 90501: /* Nova-T-PCI (oem/IR) */ | 2505 | case 90501: /* Nova-T-PCI (oem/IR) */ |
2450 | case 92000: /* Nova-SE2 (OEM, No Video or IR) */ | 2506 | case 92000: /* Nova-SE2 (OEM, No Video or IR) */ |
2507 | case 92900: /* WinTV-IROnly (No analog or digital Video inputs) */ | ||
2451 | case 94009: /* WinTV-HVR1100 (Video and IR Retail) */ | 2508 | case 94009: /* WinTV-HVR1100 (Video and IR Retail) */ |
2452 | case 94501: /* WinTV-HVR1100 (Video and IR OEM) */ | 2509 | case 94501: /* WinTV-HVR1100 (Video and IR OEM) */ |
2453 | case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */ | 2510 | case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */ |
@@ -2579,6 +2636,23 @@ static int cx88_xc3028_geniatech_tuner_callback(struct cx88_core *core, | |||
2579 | return -EINVAL; | 2636 | return -EINVAL; |
2580 | } | 2637 | } |
2581 | 2638 | ||
2639 | static int cx88_xc3028_winfast1800h_callback(struct cx88_core *core, | ||
2640 | int command, int arg) | ||
2641 | { | ||
2642 | switch (command) { | ||
2643 | case XC2028_TUNER_RESET: | ||
2644 | /* GPIO 12 (xc3028 tuner reset) */ | ||
2645 | cx_set(MO_GP1_IO, 0x1010); | ||
2646 | mdelay(50); | ||
2647 | cx_clear(MO_GP1_IO, 0x10); | ||
2648 | mdelay(50); | ||
2649 | cx_set(MO_GP1_IO, 0x10); | ||
2650 | mdelay(50); | ||
2651 | return 0; | ||
2652 | } | ||
2653 | return -EINVAL; | ||
2654 | } | ||
2655 | |||
2582 | /* ------------------------------------------------------------------- */ | 2656 | /* ------------------------------------------------------------------- */ |
2583 | /* some Divco specific stuff */ | 2657 | /* some Divco specific stuff */ |
2584 | static int cx88_pv_8000gt_callback(struct cx88_core *core, | 2658 | static int cx88_pv_8000gt_callback(struct cx88_core *core, |
@@ -2651,6 +2725,8 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core, | |||
2651 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: | 2725 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: |
2652 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: | 2726 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: |
2653 | return cx88_dvico_xc2028_callback(core, command, arg); | 2727 | return cx88_dvico_xc2028_callback(core, command, arg); |
2728 | case CX88_BOARD_WINFAST_DTV1800H: | ||
2729 | return cx88_xc3028_winfast1800h_callback(core, command, arg); | ||
2654 | } | 2730 | } |
2655 | 2731 | ||
2656 | switch (command) { | 2732 | switch (command) { |
@@ -2690,10 +2766,22 @@ static int cx88_xc5000_tuner_callback(struct cx88_core *core, | |||
2690 | switch (core->boardnr) { | 2766 | switch (core->boardnr) { |
2691 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: | 2767 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: |
2692 | if (command == 0) { /* This is the reset command from xc5000 */ | 2768 | if (command == 0) { /* This is the reset command from xc5000 */ |
2693 | /* Reset XC5000 tuner via SYS_RSTO_pin */ | 2769 | |
2694 | cx_write(MO_SRST_IO, 0); | 2770 | /* djh - According to the engineer at PCTV Systems, |
2695 | msleep(10); | 2771 | the xc5000 reset pin is supposed to be on GPIO12. |
2696 | cx_write(MO_SRST_IO, 1); | 2772 | However, despite three nights of effort, pulling |
2773 | that GPIO low didn't reset the xc5000. While | ||
2774 | pulling MO_SRST_IO low does reset the xc5000, this | ||
2775 | also resets in the s5h1409 being reset as well. | ||
2776 | This causes tuning to always fail since the internal | ||
2777 | state of the s5h1409 does not match the driver's | ||
2778 | state. Given that the only two conditions in which | ||
2779 | the driver performs a reset is during firmware load | ||
2780 | and powering down the chip, I am taking out the | ||
2781 | reset. We know that the chip is being reset | ||
2782 | when the cx88 comes online, and not being able to | ||
2783 | do power management for this board is worse than | ||
2784 | not having any tuning at all. */ | ||
2697 | return 0; | 2785 | return 0; |
2698 | } else { | 2786 | } else { |
2699 | err_printk(core, "xc5000: unknown tuner " | 2787 | err_printk(core, "xc5000: unknown tuner " |
@@ -2825,6 +2913,16 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) | |||
2825 | cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ | 2913 | cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ |
2826 | udelay(1000); | 2914 | udelay(1000); |
2827 | break; | 2915 | break; |
2916 | |||
2917 | case CX88_BOARD_WINFAST_DTV1800H: | ||
2918 | /* GPIO 12 (xc3028 tuner reset) */ | ||
2919 | cx_set(MO_GP1_IO, 0x1010); | ||
2920 | mdelay(50); | ||
2921 | cx_clear(MO_GP1_IO, 0x10); | ||
2922 | mdelay(50); | ||
2923 | cx_set(MO_GP1_IO, 0x10); | ||
2924 | mdelay(50); | ||
2925 | break; | ||
2828 | } | 2926 | } |
2829 | } | 2927 | } |
2830 | 2928 | ||
@@ -2845,6 +2943,7 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl) | |||
2845 | core->i2c_algo.udelay = 16; | 2943 | core->i2c_algo.udelay = 16; |
2846 | break; | 2944 | break; |
2847 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: | 2945 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: |
2946 | case CX88_BOARD_WINFAST_DTV1800H: | ||
2848 | ctl->demod = XC3028_FE_ZARLINK456; | 2947 | ctl->demod = XC3028_FE_ZARLINK456; |
2849 | break; | 2948 | break; |
2850 | case CX88_BOARD_KWORLD_ATSC_120: | 2949 | case CX88_BOARD_KWORLD_ATSC_120: |
@@ -2907,6 +3006,7 @@ static void cx88_card_setup(struct cx88_core *core) | |||
2907 | case CX88_BOARD_HAUPPAUGE_HVR1300: | 3006 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
2908 | case CX88_BOARD_HAUPPAUGE_HVR4000: | 3007 | case CX88_BOARD_HAUPPAUGE_HVR4000: |
2909 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: | 3008 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: |
3009 | case CX88_BOARD_HAUPPAUGE_IRONLY: | ||
2910 | if (0 == core->i2c_rc) | 3010 | if (0 == core->i2c_rc) |
2911 | hauppauge_eeprom(core, eeprom); | 3011 | hauppauge_eeprom(core, eeprom); |
2912 | break; | 3012 | break; |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 0e149b22bd19..cf634606ba9a 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -231,7 +231,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf) | |||
231 | * can use the whole SDRAM for the DMA fifos. To simplify things, we | 231 | * can use the whole SDRAM for the DMA fifos. To simplify things, we |
232 | * use a static memory layout. That surely will waste memory in case | 232 | * use a static memory layout. That surely will waste memory in case |
233 | * we don't use all DMA channels at the same time (which will be the | 233 | * we don't use all DMA channels at the same time (which will be the |
234 | * case most of the time). But that still gives us enougth FIFO space | 234 | * case most of the time). But that still gives us enough FIFO space |
235 | * to be able to deal with insane long pci latencies ... | 235 | * to be able to deal with insane long pci latencies ... |
236 | * | 236 | * |
237 | * FIFO space allocations: | 237 | * FIFO space allocations: |
@@ -241,6 +241,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf) | |||
241 | * channel 24 (vbi) - 4.0k | 241 | * channel 24 (vbi) - 4.0k |
242 | * channels 25+26 (audio) - 4.0k | 242 | * channels 25+26 (audio) - 4.0k |
243 | * channel 28 (mpeg) - 4.0k | 243 | * channel 28 (mpeg) - 4.0k |
244 | * channel 27 (audio rds)- 3.0k | ||
244 | * TOTAL = 29.0k | 245 | * TOTAL = 29.0k |
245 | * | 246 | * |
246 | * Every channel has 160 bytes control data (64 bytes instruction | 247 | * Every channel has 160 bytes control data (64 bytes instruction |
@@ -337,6 +338,18 @@ struct sram_channel cx88_sram_channels[] = { | |||
337 | .cnt1_reg = MO_DMA28_CNT1, | 338 | .cnt1_reg = MO_DMA28_CNT1, |
338 | .cnt2_reg = MO_DMA28_CNT2, | 339 | .cnt2_reg = MO_DMA28_CNT2, |
339 | }, | 340 | }, |
341 | [SRAM_CH27] = { | ||
342 | .name = "audio rds", | ||
343 | .cmds_start = 0x1801C0, | ||
344 | .ctrl_start = 0x180860, | ||
345 | .cdt = 0x180860 + 64, | ||
346 | .fifo_start = 0x187400, | ||
347 | .fifo_size = 0x000C00, | ||
348 | .ptr1_reg = MO_DMA27_PTR1, | ||
349 | .ptr2_reg = MO_DMA27_PTR2, | ||
350 | .cnt1_reg = MO_DMA27_CNT1, | ||
351 | .cnt2_reg = MO_DMA27_CNT2, | ||
352 | }, | ||
340 | }; | 353 | }; |
341 | 354 | ||
342 | int cx88_sram_channel_setup(struct cx88_core *core, | 355 | int cx88_sram_channel_setup(struct cx88_core *core, |
@@ -598,6 +611,7 @@ int cx88_reset(struct cx88_core *core) | |||
598 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0); | 611 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0); |
599 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0); | 612 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0); |
600 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0); | 613 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0); |
614 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0); | ||
601 | 615 | ||
602 | /* misc init ... */ | 616 | /* misc init ... */ |
603 | cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable | 617 | cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable |
@@ -796,6 +810,8 @@ int cx88_start_audio_dma(struct cx88_core *core) | |||
796 | /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */ | 810 | /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */ |
797 | int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4; | 811 | int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4; |
798 | 812 | ||
813 | int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size/AUD_RDS_LINES; | ||
814 | |||
799 | /* If downstream RISC is enabled, bail out; ALSA is managing DMA */ | 815 | /* If downstream RISC is enabled, bail out; ALSA is managing DMA */ |
800 | if (cx_read(MO_AUD_DMACNTRL) & 0x10) | 816 | if (cx_read(MO_AUD_DMACNTRL) & 0x10) |
801 | return 0; | 817 | return 0; |
@@ -803,12 +819,14 @@ int cx88_start_audio_dma(struct cx88_core *core) | |||
803 | /* setup fifo + format */ | 819 | /* setup fifo + format */ |
804 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0); | 820 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0); |
805 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0); | 821 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0); |
822 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], | ||
823 | rds_bpl, 0); | ||
806 | 824 | ||
807 | cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */ | 825 | cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */ |
808 | cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */ | 826 | cx_write(MO_AUDR_LNGTH, rds_bpl); /* fifo bpl size */ |
809 | 827 | ||
810 | /* start dma */ | 828 | /* enable Up, Down and Audio RDS fifo */ |
811 | cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ | 829 | cx_write(MO_AUD_DMACNTRL, 0x0007); |
812 | 830 | ||
813 | return 0; | 831 | return 0; |
814 | } | 832 | } |
@@ -1010,7 +1028,6 @@ struct video_device *cx88_vdev_init(struct cx88_core *core, | |||
1010 | if (NULL == vfd) | 1028 | if (NULL == vfd) |
1011 | return NULL; | 1029 | return NULL; |
1012 | *vfd = *template; | 1030 | *vfd = *template; |
1013 | vfd->minor = -1; | ||
1014 | vfd->v4l2_dev = &core->v4l2_dev; | 1031 | vfd->v4l2_dev = &core->v4l2_dev; |
1015 | vfd->parent = &pci->dev; | 1032 | vfd->parent = &pci->dev; |
1016 | vfd->release = video_device_release; | 1033 | vfd->release = video_device_release; |
diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/video/cx88/cx88-dsp.c new file mode 100644 index 000000000000..3e5eaf3fe2a6 --- /dev/null +++ b/drivers/media/video/cx88/cx88-dsp.c | |||
@@ -0,0 +1,312 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Stereo and SAP detection for cx88 | ||
4 | * | ||
5 | * Copyright (c) 2009 Marton Balint <cus@fazekas.hu> | ||
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 <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/jiffies.h> | ||
25 | #include <asm/div64.h> | ||
26 | |||
27 | #include "cx88.h" | ||
28 | #include "cx88-reg.h" | ||
29 | |||
30 | #define INT_PI ((s32)(3.141592653589 * 32768.0)) | ||
31 | |||
32 | #define compat_remainder(a, b) \ | ||
33 | ((float)(((s32)((a)*100))%((s32)((b)*100)))/100.0) | ||
34 | |||
35 | #define baseband_freq(carrier, srate, tone) ((s32)( \ | ||
36 | (compat_remainder(carrier + tone, srate)) / srate * 2 * INT_PI)) | ||
37 | |||
38 | /* We calculate the baseband frequencies of the carrier and the pilot tones | ||
39 | * based on the the sampling rate of the audio rds fifo. */ | ||
40 | |||
41 | #define FREQ_A2_CARRIER baseband_freq(54687.5, 2689.36, 0.0) | ||
42 | #define FREQ_A2_DUAL baseband_freq(54687.5, 2689.36, 274.1) | ||
43 | #define FREQ_A2_STEREO baseband_freq(54687.5, 2689.36, 117.5) | ||
44 | |||
45 | /* The frequencies below are from the reference driver. They probably need | ||
46 | * further adjustments, because they are not tested at all. You may even need | ||
47 | * to play a bit with the registers of the chip to select the proper signal | ||
48 | * for the input of the audio rds fifo, and measure it's sampling rate to | ||
49 | * calculate the proper baseband frequencies... */ | ||
50 | |||
51 | #define FREQ_A2M_CARRIER ((s32)(2.114516 * 32768.0)) | ||
52 | #define FREQ_A2M_DUAL ((s32)(2.754916 * 32768.0)) | ||
53 | #define FREQ_A2M_STEREO ((s32)(2.462326 * 32768.0)) | ||
54 | |||
55 | #define FREQ_EIAJ_CARRIER ((s32)(1.963495 * 32768.0)) /* 5pi/8 */ | ||
56 | #define FREQ_EIAJ_DUAL ((s32)(2.562118 * 32768.0)) | ||
57 | #define FREQ_EIAJ_STEREO ((s32)(2.601053 * 32768.0)) | ||
58 | |||
59 | #define FREQ_BTSC_DUAL ((s32)(1.963495 * 32768.0)) /* 5pi/8 */ | ||
60 | #define FREQ_BTSC_DUAL_REF ((s32)(1.374446 * 32768.0)) /* 7pi/16 */ | ||
61 | |||
62 | #define FREQ_BTSC_SAP ((s32)(2.471532 * 32768.0)) | ||
63 | #define FREQ_BTSC_SAP_REF ((s32)(1.730072 * 32768.0)) | ||
64 | |||
65 | /* The spectrum of the signal should be empty between these frequencies. */ | ||
66 | #define FREQ_NOISE_START ((s32)(0.100000 * 32768.0)) | ||
67 | #define FREQ_NOISE_END ((s32)(1.200000 * 32768.0)) | ||
68 | |||
69 | static unsigned int dsp_debug; | ||
70 | module_param(dsp_debug, int, 0644); | ||
71 | MODULE_PARM_DESC(dsp_debug, "enable audio dsp debug messages"); | ||
72 | |||
73 | #define dprintk(level, fmt, arg...) if (dsp_debug >= level) \ | ||
74 | printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) | ||
75 | |||
76 | static s32 int_cos(u32 x) | ||
77 | { | ||
78 | u32 t2, t4, t6, t8; | ||
79 | s32 ret; | ||
80 | u16 period = x / INT_PI; | ||
81 | if (period % 2) | ||
82 | return -int_cos(x - INT_PI); | ||
83 | x = x % INT_PI; | ||
84 | if (x > INT_PI/2) | ||
85 | return -int_cos(INT_PI/2 - (x % (INT_PI/2))); | ||
86 | /* Now x is between 0 and INT_PI/2. | ||
87 | * To calculate cos(x) we use it's Taylor polinom. */ | ||
88 | t2 = x*x/32768/2; | ||
89 | t4 = t2*x/32768*x/32768/3/4; | ||
90 | t6 = t4*x/32768*x/32768/5/6; | ||
91 | t8 = t6*x/32768*x/32768/7/8; | ||
92 | ret = 32768-t2+t4-t6+t8; | ||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | static u32 int_goertzel(s16 x[], u32 N, u32 freq) | ||
97 | { | ||
98 | /* We use the Goertzel algorithm to determine the power of the | ||
99 | * given frequency in the signal */ | ||
100 | s32 s_prev = 0; | ||
101 | s32 s_prev2 = 0; | ||
102 | s32 coeff = 2*int_cos(freq); | ||
103 | u32 i; | ||
104 | |||
105 | u64 tmp; | ||
106 | u32 divisor; | ||
107 | |||
108 | for (i = 0; i < N; i++) { | ||
109 | s32 s = x[i] + ((s64)coeff*s_prev/32768) - s_prev2; | ||
110 | s_prev2 = s_prev; | ||
111 | s_prev = s; | ||
112 | } | ||
113 | |||
114 | tmp = (s64)s_prev2 * s_prev2 + (s64)s_prev * s_prev - | ||
115 | (s64)coeff * s_prev2 * s_prev / 32768; | ||
116 | |||
117 | /* XXX: N must be low enough so that N*N fits in s32. | ||
118 | * Else we need two divisions. */ | ||
119 | divisor = N * N; | ||
120 | do_div(tmp, divisor); | ||
121 | |||
122 | return (u32) tmp; | ||
123 | } | ||
124 | |||
125 | static u32 freq_magnitude(s16 x[], u32 N, u32 freq) | ||
126 | { | ||
127 | u32 sum = int_goertzel(x, N, freq); | ||
128 | return (u32)int_sqrt(sum); | ||
129 | } | ||
130 | |||
131 | static u32 noise_magnitude(s16 x[], u32 N, u32 freq_start, u32 freq_end) | ||
132 | { | ||
133 | int i; | ||
134 | u32 sum = 0; | ||
135 | u32 freq_step; | ||
136 | int samples = 5; | ||
137 | |||
138 | if (N > 192) { | ||
139 | /* The last 192 samples are enough for noise detection */ | ||
140 | x += (N-192); | ||
141 | N = 192; | ||
142 | } | ||
143 | |||
144 | freq_step = (freq_end - freq_start) / (samples - 1); | ||
145 | |||
146 | for (i = 0; i < samples; i++) { | ||
147 | sum += int_goertzel(x, N, freq_start); | ||
148 | freq_start += freq_step; | ||
149 | } | ||
150 | |||
151 | return (u32)int_sqrt(sum / samples); | ||
152 | } | ||
153 | |||
154 | static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N) | ||
155 | { | ||
156 | s32 carrier, stereo, dual, noise; | ||
157 | s32 carrier_freq, stereo_freq, dual_freq; | ||
158 | s32 ret; | ||
159 | |||
160 | switch (core->tvaudio) { | ||
161 | case WW_BG: | ||
162 | case WW_DK: | ||
163 | carrier_freq = FREQ_A2_CARRIER; | ||
164 | stereo_freq = FREQ_A2_STEREO; | ||
165 | dual_freq = FREQ_A2_DUAL; | ||
166 | break; | ||
167 | case WW_M: | ||
168 | carrier_freq = FREQ_A2M_CARRIER; | ||
169 | stereo_freq = FREQ_A2M_STEREO; | ||
170 | dual_freq = FREQ_A2M_DUAL; | ||
171 | break; | ||
172 | case WW_EIAJ: | ||
173 | carrier_freq = FREQ_EIAJ_CARRIER; | ||
174 | stereo_freq = FREQ_EIAJ_STEREO; | ||
175 | dual_freq = FREQ_EIAJ_DUAL; | ||
176 | break; | ||
177 | default: | ||
178 | printk(KERN_WARNING "%s/0: unsupported audio mode %d for %s\n", | ||
179 | core->name, core->tvaudio, __func__); | ||
180 | return UNSET; | ||
181 | } | ||
182 | |||
183 | carrier = freq_magnitude(x, N, carrier_freq); | ||
184 | stereo = freq_magnitude(x, N, stereo_freq); | ||
185 | dual = freq_magnitude(x, N, dual_freq); | ||
186 | noise = noise_magnitude(x, N, FREQ_NOISE_START, FREQ_NOISE_END); | ||
187 | |||
188 | dprintk(1, "detect a2/a2m/eiaj: carrier=%d, stereo=%d, dual=%d, " | ||
189 | "noise=%d\n", carrier, stereo, dual, noise); | ||
190 | |||
191 | if (stereo > dual) | ||
192 | ret = V4L2_TUNER_SUB_STEREO; | ||
193 | else | ||
194 | ret = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | ||
195 | |||
196 | if (core->tvaudio == WW_EIAJ) { | ||
197 | /* EIAJ checks may need adjustments */ | ||
198 | if ((carrier > max(stereo, dual)*2) && | ||
199 | (carrier < max(stereo, dual)*6) && | ||
200 | (carrier > 20 && carrier < 200) && | ||
201 | (max(stereo, dual) > min(stereo, dual))) { | ||
202 | /* For EIAJ the carrier is always present, | ||
203 | so we probably don't need noise detection */ | ||
204 | return ret; | ||
205 | } | ||
206 | } else { | ||
207 | if ((carrier > max(stereo, dual)*2) && | ||
208 | (carrier < max(stereo, dual)*8) && | ||
209 | (carrier > 20 && carrier < 200) && | ||
210 | (noise < 10) && | ||
211 | (max(stereo, dual) > min(stereo, dual)*2)) { | ||
212 | return ret; | ||
213 | } | ||
214 | } | ||
215 | return V4L2_TUNER_SUB_MONO; | ||
216 | } | ||
217 | |||
218 | static s32 detect_btsc(struct cx88_core *core, s16 x[], u32 N) | ||
219 | { | ||
220 | s32 sap_ref = freq_magnitude(x, N, FREQ_BTSC_SAP_REF); | ||
221 | s32 sap = freq_magnitude(x, N, FREQ_BTSC_SAP); | ||
222 | s32 dual_ref = freq_magnitude(x, N, FREQ_BTSC_DUAL_REF); | ||
223 | s32 dual = freq_magnitude(x, N, FREQ_BTSC_DUAL); | ||
224 | dprintk(1, "detect btsc: dual_ref=%d, dual=%d, sap_ref=%d, sap=%d" | ||
225 | "\n", dual_ref, dual, sap_ref, sap); | ||
226 | /* FIXME: Currently not supported */ | ||
227 | return UNSET; | ||
228 | } | ||
229 | |||
230 | static s16 *read_rds_samples(struct cx88_core *core, u32 *N) | ||
231 | { | ||
232 | struct sram_channel *srch = &cx88_sram_channels[SRAM_CH27]; | ||
233 | s16 *samples; | ||
234 | |||
235 | unsigned int i; | ||
236 | unsigned int bpl = srch->fifo_size/AUD_RDS_LINES; | ||
237 | unsigned int spl = bpl/4; | ||
238 | unsigned int sample_count = spl*(AUD_RDS_LINES-1); | ||
239 | |||
240 | u32 current_address = cx_read(srch->ptr1_reg); | ||
241 | u32 offset = (current_address - srch->fifo_start + bpl); | ||
242 | |||
243 | dprintk(1, "read RDS samples: current_address=%08x (offset=%08x), " | ||
244 | "sample_count=%d, aud_intstat=%08x\n", current_address, | ||
245 | current_address - srch->fifo_start, sample_count, | ||
246 | cx_read(MO_AUD_INTSTAT)); | ||
247 | |||
248 | samples = kmalloc(sizeof(s16)*sample_count, GFP_KERNEL); | ||
249 | if (!samples) | ||
250 | return NULL; | ||
251 | |||
252 | *N = sample_count; | ||
253 | |||
254 | for (i = 0; i < sample_count; i++) { | ||
255 | offset = offset % (AUD_RDS_LINES*bpl); | ||
256 | samples[i] = cx_read(srch->fifo_start + offset); | ||
257 | offset += 4; | ||
258 | } | ||
259 | |||
260 | if (dsp_debug >= 2) { | ||
261 | dprintk(2, "RDS samples dump: "); | ||
262 | for (i = 0; i < sample_count; i++) | ||
263 | printk("%hd ", samples[i]); | ||
264 | printk(".\n"); | ||
265 | } | ||
266 | |||
267 | return samples; | ||
268 | } | ||
269 | |||
270 | s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core) | ||
271 | { | ||
272 | s16 *samples; | ||
273 | u32 N = 0; | ||
274 | s32 ret = UNSET; | ||
275 | |||
276 | /* If audio RDS fifo is disabled, we can't read the samples */ | ||
277 | if (!(cx_read(MO_AUD_DMACNTRL) & 0x04)) | ||
278 | return ret; | ||
279 | if (!(cx_read(AUD_CTL) & EN_FMRADIO_EN_RDS)) | ||
280 | return ret; | ||
281 | |||
282 | /* Wait at least 500 ms after an audio standard change */ | ||
283 | if (time_before(jiffies, core->last_change + msecs_to_jiffies(500))) | ||
284 | return ret; | ||
285 | |||
286 | samples = read_rds_samples(core, &N); | ||
287 | |||
288 | if (!samples) | ||
289 | return ret; | ||
290 | |||
291 | switch (core->tvaudio) { | ||
292 | case WW_BG: | ||
293 | case WW_DK: | ||
294 | ret = detect_a2_a2m_eiaj(core, samples, N); | ||
295 | break; | ||
296 | case WW_BTSC: | ||
297 | ret = detect_btsc(core, samples, N); | ||
298 | break; | ||
299 | } | ||
300 | |||
301 | kfree(samples); | ||
302 | |||
303 | if (UNSET != ret) | ||
304 | dprintk(1, "stereo/sap detection result:%s%s%s\n", | ||
305 | (ret & V4L2_TUNER_SUB_MONO) ? " mono" : "", | ||
306 | (ret & V4L2_TUNER_SUB_STEREO) ? " stereo" : "", | ||
307 | (ret & V4L2_TUNER_SUB_LANG2) ? " dual" : ""); | ||
308 | |||
309 | return ret; | ||
310 | } | ||
311 | EXPORT_SYMBOL(cx88_dsp_detect_stereo_sap); | ||
312 | |||
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 9389cf290c1b..c44e87600219 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -1014,6 +1014,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
1014 | } | 1014 | } |
1015 | break; | 1015 | break; |
1016 | case CX88_BOARD_PINNACLE_HYBRID_PCTV: | 1016 | case CX88_BOARD_PINNACLE_HYBRID_PCTV: |
1017 | case CX88_BOARD_WINFAST_DTV1800H: | ||
1017 | fe0->dvb.frontend = dvb_attach(zl10353_attach, | 1018 | fe0->dvb.frontend = dvb_attach(zl10353_attach, |
1018 | &cx88_pinnacle_hybrid_pctv, | 1019 | &cx88_pinnacle_hybrid_pctv, |
1019 | &core->i2c_adap); | 1020 | &core->i2c_adap); |
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 996b4ed5a4fc..ee1ca39db06a 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -180,6 +180,19 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) | |||
180 | do_i2c_scan(core->name,&core->i2c_client); | 180 | do_i2c_scan(core->name,&core->i2c_client); |
181 | } else | 181 | } else |
182 | printk("%s: i2c register FAILED\n", core->name); | 182 | printk("%s: i2c register FAILED\n", core->name); |
183 | |||
184 | /* Instantiate the IR receiver device, if present */ | ||
185 | if (0 == core->i2c_rc) { | ||
186 | struct i2c_board_info info; | ||
187 | const unsigned short addr_list[] = { | ||
188 | 0x18, 0x6b, 0x71, | ||
189 | I2C_CLIENT_END | ||
190 | }; | ||
191 | |||
192 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
193 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
194 | i2c_new_probed_device(&core->i2c_adap, &info, addr_list); | ||
195 | } | ||
183 | return core->i2c_rc; | 196 | return core->i2c_rc; |
184 | } | 197 | } |
185 | 198 | ||
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index ec05312a9b62..d91f5c51206d 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -91,6 +91,8 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) | |||
91 | gpio=(gpio & 0x7fd) + (auxgpio & 0xef); | 91 | gpio=(gpio & 0x7fd) + (auxgpio & 0xef); |
92 | break; | 92 | break; |
93 | case CX88_BOARD_WINFAST_DTV1000: | 93 | case CX88_BOARD_WINFAST_DTV1000: |
94 | case CX88_BOARD_WINFAST_DTV1800H: | ||
95 | case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: | ||
94 | gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900); | 96 | gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900); |
95 | auxgpio = gpio; | 97 | auxgpio = gpio; |
96 | break; | 98 | break; |
@@ -217,11 +219,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
217 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: | 219 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: |
218 | case CX88_BOARD_PCHDTV_HD3000: | 220 | case CX88_BOARD_PCHDTV_HD3000: |
219 | case CX88_BOARD_PCHDTV_HD5500: | 221 | case CX88_BOARD_PCHDTV_HD5500: |
222 | case CX88_BOARD_HAUPPAUGE_IRONLY: | ||
220 | ir_codes = ir_codes_hauppauge_new; | 223 | ir_codes = ir_codes_hauppauge_new; |
221 | ir_type = IR_TYPE_RC5; | 224 | ir_type = IR_TYPE_RC5; |
222 | ir->sampling = 1; | 225 | ir->sampling = 1; |
223 | break; | 226 | break; |
224 | case CX88_BOARD_WINFAST_DTV2000H: | 227 | case CX88_BOARD_WINFAST_DTV2000H: |
228 | case CX88_BOARD_WINFAST_DTV1800H: | ||
225 | ir_codes = ir_codes_winfast; | 229 | ir_codes = ir_codes_winfast; |
226 | ir->gpio_addr = MO_GP0_IO; | 230 | ir->gpio_addr = MO_GP0_IO; |
227 | ir->mask_keycode = 0x8f8; | 231 | ir->mask_keycode = 0x8f8; |
@@ -230,6 +234,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
230 | break; | 234 | break; |
231 | case CX88_BOARD_WINFAST2000XP_EXPERT: | 235 | case CX88_BOARD_WINFAST2000XP_EXPERT: |
232 | case CX88_BOARD_WINFAST_DTV1000: | 236 | case CX88_BOARD_WINFAST_DTV1000: |
237 | case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: | ||
233 | ir_codes = ir_codes_winfast; | 238 | ir_codes = ir_codes_winfast; |
234 | ir->gpio_addr = MO_GP0_IO; | 239 | ir->gpio_addr = MO_GP0_IO; |
235 | ir->mask_keycode = 0x8f8; | 240 | ir->mask_keycode = 0x8f8; |
@@ -459,6 +464,7 @@ void cx88_ir_irq(struct cx88_core *core) | |||
459 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: | 464 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: |
460 | case CX88_BOARD_PCHDTV_HD3000: | 465 | case CX88_BOARD_PCHDTV_HD3000: |
461 | case CX88_BOARD_PCHDTV_HD5500: | 466 | case CX88_BOARD_PCHDTV_HD5500: |
467 | case CX88_BOARD_HAUPPAUGE_IRONLY: | ||
462 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); | 468 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); |
463 | ir_dprintk("biphase decoded: %x\n", ircode); | 469 | ir_dprintk("biphase decoded: %x\n", ircode); |
464 | /* | 470 | /* |
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 7dd506b987fe..e8316cf7f32f 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c | |||
@@ -163,6 +163,8 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) | |||
163 | /* unmute */ | 163 | /* unmute */ |
164 | volume = cx_sread(SHADOW_AUD_VOL_CTL); | 164 | volume = cx_sread(SHADOW_AUD_VOL_CTL); |
165 | cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume); | 165 | cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume); |
166 | |||
167 | core->last_change = jiffies; | ||
166 | } | 168 | } |
167 | 169 | ||
168 | /* ----------------------------------------------------------- */ | 170 | /* ----------------------------------------------------------- */ |
@@ -745,6 +747,7 @@ void cx88_set_tvaudio(struct cx88_core *core) | |||
745 | break; | 747 | break; |
746 | case WW_BG: | 748 | case WW_BG: |
747 | case WW_DK: | 749 | case WW_DK: |
750 | case WW_M: | ||
748 | case WW_I: | 751 | case WW_I: |
749 | case WW_L: | 752 | case WW_L: |
750 | /* prepare all dsp registers */ | 753 | /* prepare all dsp registers */ |
@@ -756,6 +759,7 @@ void cx88_set_tvaudio(struct cx88_core *core) | |||
756 | if (0 == cx88_detect_nicam(core)) { | 759 | if (0 == cx88_detect_nicam(core)) { |
757 | /* fall back to fm / am mono */ | 760 | /* fall back to fm / am mono */ |
758 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); | 761 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); |
762 | core->audiomode_current = V4L2_TUNER_MODE_MONO; | ||
759 | core->use_nicam = 0; | 763 | core->use_nicam = 0; |
760 | } else { | 764 | } else { |
761 | core->use_nicam = 1; | 765 | core->use_nicam = 1; |
@@ -787,6 +791,7 @@ void cx88_set_tvaudio(struct cx88_core *core) | |||
787 | void cx88_newstation(struct cx88_core *core) | 791 | void cx88_newstation(struct cx88_core *core) |
788 | { | 792 | { |
789 | core->audiomode_manual = UNSET; | 793 | core->audiomode_manual = UNSET; |
794 | core->last_change = jiffies; | ||
790 | } | 795 | } |
791 | 796 | ||
792 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) | 797 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) |
@@ -805,12 +810,50 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) | |||
805 | aud_ctl_names[cx_read(AUD_CTL) & 63]); | 810 | aud_ctl_names[cx_read(AUD_CTL) & 63]); |
806 | core->astat = reg; | 811 | core->astat = reg; |
807 | 812 | ||
808 | /* TODO | 813 | t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | |
809 | Reading from AUD_STATUS is not enough | 814 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; |
810 | for auto-detecting sap/dual-fm/nicam. | 815 | t->rxsubchans = UNSET; |
811 | Add some code here later. | 816 | t->audmode = V4L2_TUNER_MODE_MONO; |
812 | */ | 817 | |
818 | switch (mode) { | ||
819 | case 0: | ||
820 | t->audmode = V4L2_TUNER_MODE_STEREO; | ||
821 | break; | ||
822 | case 1: | ||
823 | t->audmode = V4L2_TUNER_MODE_LANG2; | ||
824 | break; | ||
825 | case 2: | ||
826 | t->audmode = V4L2_TUNER_MODE_MONO; | ||
827 | break; | ||
828 | case 3: | ||
829 | t->audmode = V4L2_TUNER_MODE_SAP; | ||
830 | break; | ||
831 | } | ||
813 | 832 | ||
833 | switch (core->tvaudio) { | ||
834 | case WW_BTSC: | ||
835 | case WW_BG: | ||
836 | case WW_DK: | ||
837 | case WW_M: | ||
838 | case WW_EIAJ: | ||
839 | if (!core->use_nicam) { | ||
840 | t->rxsubchans = cx88_dsp_detect_stereo_sap(core); | ||
841 | break; | ||
842 | } | ||
843 | break; | ||
844 | default: | ||
845 | /* nothing */ | ||
846 | break; | ||
847 | } | ||
848 | |||
849 | /* If software stereo detection is not supported... */ | ||
850 | if (UNSET == t->rxsubchans) { | ||
851 | t->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
852 | /* If the hardware itself detected stereo, also return | ||
853 | stereo as an available subchannel */ | ||
854 | if (V4L2_TUNER_MODE_STEREO == t->audmode) | ||
855 | t->rxsubchans |= V4L2_TUNER_SUB_STEREO; | ||
856 | } | ||
814 | return; | 857 | return; |
815 | } | 858 | } |
816 | 859 | ||
@@ -847,6 +890,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) | |||
847 | break; | 890 | break; |
848 | case WW_BG: | 891 | case WW_BG: |
849 | case WW_DK: | 892 | case WW_DK: |
893 | case WW_M: | ||
850 | case WW_I: | 894 | case WW_I: |
851 | case WW_L: | 895 | case WW_L: |
852 | if (1 == core->use_nicam) { | 896 | if (1 == core->use_nicam) { |
@@ -872,20 +916,18 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) | |||
872 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); | 916 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); |
873 | } else { | 917 | } else { |
874 | /* TODO: Add A2 autodection */ | 918 | /* TODO: Add A2 autodection */ |
919 | mask = 0x3f; | ||
875 | switch (mode) { | 920 | switch (mode) { |
876 | case V4L2_TUNER_MODE_MONO: | 921 | case V4L2_TUNER_MODE_MONO: |
877 | case V4L2_TUNER_MODE_LANG1: | 922 | case V4L2_TUNER_MODE_LANG1: |
878 | set_audio_standard_A2(core, | 923 | ctl = EN_A2_FORCE_MONO1; |
879 | EN_A2_FORCE_MONO1); | ||
880 | break; | 924 | break; |
881 | case V4L2_TUNER_MODE_LANG2: | 925 | case V4L2_TUNER_MODE_LANG2: |
882 | set_audio_standard_A2(core, | 926 | ctl = EN_A2_FORCE_MONO2; |
883 | EN_A2_FORCE_MONO2); | ||
884 | break; | 927 | break; |
885 | case V4L2_TUNER_MODE_STEREO: | 928 | case V4L2_TUNER_MODE_STEREO: |
886 | case V4L2_TUNER_MODE_LANG1_LANG2: | 929 | case V4L2_TUNER_MODE_LANG1_LANG2: |
887 | set_audio_standard_A2(core, | 930 | ctl = EN_A2_FORCE_STEREO; |
888 | EN_A2_FORCE_STEREO); | ||
889 | break; | 931 | break; |
890 | } | 932 | } |
891 | } | 933 | } |
@@ -932,24 +974,39 @@ int cx88_audio_thread(void *data) | |||
932 | break; | 974 | break; |
933 | try_to_freeze(); | 975 | try_to_freeze(); |
934 | 976 | ||
935 | /* just monitor the audio status for now ... */ | 977 | switch (core->tvaudio) { |
936 | memset(&t, 0, sizeof(t)); | 978 | case WW_BG: |
937 | cx88_get_stereo(core, &t); | 979 | case WW_DK: |
938 | 980 | case WW_M: | |
939 | if (UNSET != core->audiomode_manual) | 981 | case WW_I: |
940 | /* manually set, don't do anything. */ | 982 | case WW_L: |
941 | continue; | 983 | if (core->use_nicam) |
942 | 984 | goto hw_autodetect; | |
943 | /* monitor signal */ | 985 | |
944 | if (t.rxsubchans & V4L2_TUNER_SUB_STEREO) | 986 | /* just monitor the audio status for now ... */ |
945 | mode = V4L2_TUNER_MODE_STEREO; | 987 | memset(&t, 0, sizeof(t)); |
946 | else | 988 | cx88_get_stereo(core, &t); |
947 | mode = V4L2_TUNER_MODE_MONO; | 989 | |
948 | if (mode == core->audiomode_current) | 990 | if (UNSET != core->audiomode_manual) |
949 | continue; | 991 | /* manually set, don't do anything. */ |
950 | 992 | continue; | |
951 | /* automatically switch to best available mode */ | 993 | |
952 | cx88_set_stereo(core, mode, 0); | 994 | /* monitor signal and set stereo if available */ |
995 | if (t.rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
996 | mode = V4L2_TUNER_MODE_STEREO; | ||
997 | else | ||
998 | mode = V4L2_TUNER_MODE_MONO; | ||
999 | if (mode == core->audiomode_current) | ||
1000 | continue; | ||
1001 | /* automatically switch to best available mode */ | ||
1002 | cx88_set_stereo(core, mode, 0); | ||
1003 | break; | ||
1004 | default: | ||
1005 | hw_autodetect: | ||
1006 | /* stereo autodetection is supported by hardware so | ||
1007 | we don't need to do it manually. Do nothing. */ | ||
1008 | break; | ||
1009 | } | ||
953 | } | 1010 | } |
954 | 1011 | ||
955 | dprintk("cx88: tvaudio thread exiting\n"); | 1012 | dprintk("cx88: tvaudio thread exiting\n"); |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index b993d42fe73c..0ccac702bea4 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -869,6 +869,7 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
869 | { | 869 | { |
870 | struct cx8800_fh *fh = file->private_data; | 870 | struct cx8800_fh *fh = file->private_data; |
871 | struct cx88_buffer *buf; | 871 | struct cx88_buffer *buf; |
872 | unsigned int rc = POLLERR; | ||
872 | 873 | ||
873 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { | 874 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { |
874 | if (!res_get(fh->dev,fh,RESOURCE_VBI)) | 875 | if (!res_get(fh->dev,fh,RESOURCE_VBI)) |
@@ -876,22 +877,27 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
876 | return videobuf_poll_stream(file, &fh->vbiq, wait); | 877 | return videobuf_poll_stream(file, &fh->vbiq, wait); |
877 | } | 878 | } |
878 | 879 | ||
880 | mutex_lock(&fh->vidq.vb_lock); | ||
879 | if (res_check(fh,RESOURCE_VIDEO)) { | 881 | if (res_check(fh,RESOURCE_VIDEO)) { |
880 | /* streaming capture */ | 882 | /* streaming capture */ |
881 | if (list_empty(&fh->vidq.stream)) | 883 | if (list_empty(&fh->vidq.stream)) |
882 | return POLLERR; | 884 | goto done; |
883 | buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream); | 885 | buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream); |
884 | } else { | 886 | } else { |
885 | /* read() capture */ | 887 | /* read() capture */ |
886 | buf = (struct cx88_buffer*)fh->vidq.read_buf; | 888 | buf = (struct cx88_buffer*)fh->vidq.read_buf; |
887 | if (NULL == buf) | 889 | if (NULL == buf) |
888 | return POLLERR; | 890 | goto done; |
889 | } | 891 | } |
890 | poll_wait(file, &buf->vb.done, wait); | 892 | poll_wait(file, &buf->vb.done, wait); |
891 | if (buf->vb.state == VIDEOBUF_DONE || | 893 | if (buf->vb.state == VIDEOBUF_DONE || |
892 | buf->vb.state == VIDEOBUF_ERROR) | 894 | buf->vb.state == VIDEOBUF_ERROR) |
893 | return POLLIN|POLLRDNORM; | 895 | rc = POLLIN|POLLRDNORM; |
894 | return 0; | 896 | else |
897 | rc = 0; | ||
898 | done: | ||
899 | mutex_unlock(&fh->vidq.vb_lock); | ||
900 | return rc; | ||
895 | } | 901 | } |
896 | 902 | ||
897 | static int video_release(struct file *file) | 903 | static int video_release(struct file *file) |
@@ -926,8 +932,10 @@ static int video_release(struct file *file) | |||
926 | file->private_data = NULL; | 932 | file->private_data = NULL; |
927 | kfree(fh); | 933 | kfree(fh); |
928 | 934 | ||
935 | mutex_lock(&dev->core->lock); | ||
929 | if(atomic_dec_and_test(&dev->core->users)) | 936 | if(atomic_dec_and_test(&dev->core->users)) |
930 | call_all(dev->core, tuner, s_standby); | 937 | call_all(dev->core, tuner, s_standby); |
938 | mutex_unlock(&dev->core->lock); | ||
931 | 939 | ||
932 | return 0; | 940 | return 0; |
933 | } | 941 | } |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 7724d168fc04..9d83762163f5 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -65,6 +65,8 @@ | |||
65 | #define VBI_LINE_COUNT 17 | 65 | #define VBI_LINE_COUNT 17 |
66 | #define VBI_LINE_LENGTH 2048 | 66 | #define VBI_LINE_LENGTH 2048 |
67 | 67 | ||
68 | #define AUD_RDS_LINES 4 | ||
69 | |||
68 | /* need "shadow" registers for some write-only ones ... */ | 70 | /* need "shadow" registers for some write-only ones ... */ |
69 | #define SHADOW_AUD_VOL_CTL 1 | 71 | #define SHADOW_AUD_VOL_CTL 1 |
70 | #define SHADOW_AUD_BAL_CTL 2 | 72 | #define SHADOW_AUD_BAL_CTL 2 |
@@ -132,6 +134,7 @@ struct cx88_ctrl { | |||
132 | #define SRAM_CH25 4 /* audio */ | 134 | #define SRAM_CH25 4 /* audio */ |
133 | #define SRAM_CH26 5 | 135 | #define SRAM_CH26 5 |
134 | #define SRAM_CH28 6 /* mpeg */ | 136 | #define SRAM_CH28 6 /* mpeg */ |
137 | #define SRAM_CH27 7 /* audio rds */ | ||
135 | /* more */ | 138 | /* more */ |
136 | 139 | ||
137 | struct sram_channel { | 140 | struct sram_channel { |
@@ -232,6 +235,8 @@ extern struct sram_channel cx88_sram_channels[]; | |||
232 | #define CX88_BOARD_TBS_8910 77 | 235 | #define CX88_BOARD_TBS_8910 77 |
233 | #define CX88_BOARD_PROF_6200 78 | 236 | #define CX88_BOARD_PROF_6200 78 |
234 | #define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79 | 237 | #define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79 |
238 | #define CX88_BOARD_HAUPPAUGE_IRONLY 80 | ||
239 | #define CX88_BOARD_WINFAST_DTV1800H 81 | ||
235 | 240 | ||
236 | enum cx88_itype { | 241 | enum cx88_itype { |
237 | CX88_VMUX_COMPOSITE1 = 1, | 242 | CX88_VMUX_COMPOSITE1 = 1, |
@@ -350,6 +355,7 @@ struct cx88_core { | |||
350 | u32 input; | 355 | u32 input; |
351 | u32 astat; | 356 | u32 astat; |
352 | u32 use_nicam; | 357 | u32 use_nicam; |
358 | unsigned long last_change; | ||
353 | 359 | ||
354 | /* IR remote control state */ | 360 | /* IR remote control state */ |
355 | struct cx88_IR *ir; | 361 | struct cx88_IR *ir; |
@@ -652,6 +658,7 @@ extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl); | |||
652 | #define WW_I2SPT 8 | 658 | #define WW_I2SPT 8 |
653 | #define WW_FM 9 | 659 | #define WW_FM 9 |
654 | #define WW_I2SADC 10 | 660 | #define WW_I2SADC 10 |
661 | #define WW_M 11 | ||
655 | 662 | ||
656 | void cx88_set_tvaudio(struct cx88_core *core); | 663 | void cx88_set_tvaudio(struct cx88_core *core); |
657 | void cx88_newstation(struct cx88_core *core); | 664 | void cx88_newstation(struct cx88_core *core); |
@@ -665,6 +672,11 @@ struct cx8802_dev *cx8802_get_device(int minor); | |||
665 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); | 672 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); |
666 | 673 | ||
667 | /* ----------------------------------------------------------- */ | 674 | /* ----------------------------------------------------------- */ |
675 | /* cx88-dsp.c */ | ||
676 | |||
677 | s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core); | ||
678 | |||
679 | /* ----------------------------------------------------------- */ | ||
668 | /* cx88-input.c */ | 680 | /* cx88-input.c */ |
669 | 681 | ||
670 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci); | 682 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci); |
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 0131322475bf..7bd8a70f0a0b 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c | |||
@@ -339,6 +339,11 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) | |||
339 | mutex_lock(&dev->lock); | 339 | mutex_lock(&dev->lock); |
340 | dev->adev.users--; | 340 | dev->adev.users--; |
341 | em28xx_audio_analog_set(dev); | 341 | em28xx_audio_analog_set(dev); |
342 | if (substream->runtime->dma_area) { | ||
343 | dprintk("freeing\n"); | ||
344 | vfree(substream->runtime->dma_area); | ||
345 | substream->runtime->dma_area = NULL; | ||
346 | } | ||
342 | mutex_unlock(&dev->lock); | 347 | mutex_unlock(&dev->lock); |
343 | 348 | ||
344 | return 0; | 349 | return 0; |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 7c70738479dd..00cc791a9e44 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -49,6 +49,11 @@ static unsigned int disable_ir; | |||
49 | module_param(disable_ir, int, 0444); | 49 | module_param(disable_ir, int, 0444); |
50 | MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); | 50 | MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); |
51 | 51 | ||
52 | static unsigned int disable_usb_speed_check; | ||
53 | module_param(disable_usb_speed_check, int, 0444); | ||
54 | MODULE_PARM_DESC(disable_usb_speed_check, | ||
55 | "override min bandwidth requirement of 480M bps"); | ||
56 | |||
52 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 57 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
53 | module_param_array(card, int, NULL, 0444); | 58 | module_param_array(card, int, NULL, 0444); |
54 | MODULE_PARM_DESC(card, "card type"); | 59 | MODULE_PARM_DESC(card, "card type"); |
@@ -104,6 +109,24 @@ static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { | |||
104 | /* Board - EM2870 Kworld 355u | 109 | /* Board - EM2870 Kworld 355u |
105 | Analog - No input analog */ | 110 | Analog - No input analog */ |
106 | 111 | ||
112 | /* Board - EM2882 Kworld 315U digital */ | ||
113 | static struct em28xx_reg_seq em2882_kworld_315u_digital[] = { | ||
114 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
115 | {EM28XX_R08_GPIO, 0xfe, 0xff, 10}, | ||
116 | {EM2880_R04_GPO, 0x04, 0xff, 10}, | ||
117 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
118 | {EM28XX_R08_GPIO, 0x7e, 0xff, 10}, | ||
119 | { -1, -1, -1, -1}, | ||
120 | }; | ||
121 | |||
122 | static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { | ||
123 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
124 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
125 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
126 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
127 | { -1, -1, -1, -1}, | ||
128 | }; | ||
129 | |||
107 | static struct em28xx_reg_seq kworld_330u_analog[] = { | 130 | static struct em28xx_reg_seq kworld_330u_analog[] = { |
108 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | 131 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, |
109 | {EM2880_R04_GPO, 0x00, 0xff, 10}, | 132 | {EM2880_R04_GPO, 0x00, 0xff, 10}, |
@@ -140,6 +163,16 @@ static struct em28xx_reg_seq compro_mute_gpio[] = { | |||
140 | { -1, -1, -1, -1}, | 163 | { -1, -1, -1, -1}, |
141 | }; | 164 | }; |
142 | 165 | ||
166 | /* Terratec AV350 */ | ||
167 | static struct em28xx_reg_seq terratec_av350_mute_gpio[] = { | ||
168 | {EM28XX_R08_GPIO, 0xff, 0x7f, 10}, | ||
169 | { -1, -1, -1, -1}, | ||
170 | }; | ||
171 | |||
172 | static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = { | ||
173 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
174 | { -1, -1, -1, -1}, | ||
175 | }; | ||
143 | /* | 176 | /* |
144 | * Board definitions | 177 | * Board definitions |
145 | */ | 178 | */ |
@@ -992,16 +1025,17 @@ struct em28xx_board em28xx_boards[] = { | |||
992 | .amux = EM28XX_AMUX_LINE_IN, | 1025 | .amux = EM28XX_AMUX_LINE_IN, |
993 | } }, | 1026 | } }, |
994 | }, | 1027 | }, |
995 | [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { | 1028 | [EM2860_BOARD_SAA711X_REFERENCE_DESIGN] = { |
996 | .name = "PointNix Intra-Oral Camera", | 1029 | .name = "EM2860/SAA711X Reference Design", |
997 | .has_snapshot_button = 1, | 1030 | .has_snapshot_button = 1, |
998 | .tda9887_conf = TDA9887_PRESENT, | ||
999 | .tuner_type = TUNER_ABSENT, | 1031 | .tuner_type = TUNER_ABSENT, |
1000 | .decoder = EM28XX_SAA711X, | 1032 | .decoder = EM28XX_SAA711X, |
1001 | .input = { { | 1033 | .input = { { |
1002 | .type = EM28XX_VMUX_SVIDEO, | 1034 | .type = EM28XX_VMUX_SVIDEO, |
1003 | .vmux = SAA7115_SVIDEO3, | 1035 | .vmux = SAA7115_SVIDEO3, |
1004 | .amux = EM28XX_AMUX_VIDEO, | 1036 | }, { |
1037 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1038 | .vmux = SAA7115_COMPOSITE0, | ||
1005 | } }, | 1039 | } }, |
1006 | }, | 1040 | }, |
1007 | [EM2880_BOARD_MSI_DIGIVOX_AD] = { | 1041 | [EM2880_BOARD_MSI_DIGIVOX_AD] = { |
@@ -1095,6 +1129,63 @@ struct em28xx_board em28xx_boards[] = { | |||
1095 | .gpio = default_analog, | 1129 | .gpio = default_analog, |
1096 | } }, | 1130 | } }, |
1097 | }, | 1131 | }, |
1132 | [EM2882_BOARD_KWORLD_ATSC_315U] = { | ||
1133 | .name = "KWorld ATSC 315U HDTV TV Box", | ||
1134 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1135 | .tuner_type = TUNER_THOMSON_DTT761X, | ||
1136 | .tuner_gpio = em2882_kworld_315u_tuner_gpio, | ||
1137 | .tda9887_conf = TDA9887_PRESENT, | ||
1138 | .decoder = EM28XX_SAA711X, | ||
1139 | .has_dvb = 1, | ||
1140 | .dvb_gpio = em2882_kworld_315u_digital, | ||
1141 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1142 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, | ||
1143 | /* Analog mode - still not ready */ | ||
1144 | /*.input = { { | ||
1145 | .type = EM28XX_VMUX_TELEVISION, | ||
1146 | .vmux = SAA7115_COMPOSITE2, | ||
1147 | .amux = EM28XX_AMUX_VIDEO, | ||
1148 | .gpio = em2882_kworld_315u_analog, | ||
1149 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1150 | }, { | ||
1151 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1152 | .vmux = SAA7115_COMPOSITE0, | ||
1153 | .amux = EM28XX_AMUX_LINE_IN, | ||
1154 | .gpio = em2882_kworld_315u_analog1, | ||
1155 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1156 | }, { | ||
1157 | .type = EM28XX_VMUX_SVIDEO, | ||
1158 | .vmux = SAA7115_SVIDEO3, | ||
1159 | .amux = EM28XX_AMUX_LINE_IN, | ||
1160 | .gpio = em2882_kworld_315u_analog1, | ||
1161 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1162 | } }, */ | ||
1163 | }, | ||
1164 | [EM2880_BOARD_EMPIRE_DUAL_TV] = { | ||
1165 | .name = "Empire dual TV", | ||
1166 | .tuner_type = TUNER_XC2028, | ||
1167 | .tuner_gpio = default_tuner_gpio, | ||
1168 | .has_dvb = 1, | ||
1169 | .dvb_gpio = default_digital, | ||
1170 | .mts_firmware = 1, | ||
1171 | .decoder = EM28XX_TVP5150, | ||
1172 | .input = { { | ||
1173 | .type = EM28XX_VMUX_TELEVISION, | ||
1174 | .vmux = TVP5150_COMPOSITE0, | ||
1175 | .amux = EM28XX_AMUX_VIDEO, | ||
1176 | .gpio = default_analog, | ||
1177 | }, { | ||
1178 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1179 | .vmux = TVP5150_COMPOSITE1, | ||
1180 | .amux = EM28XX_AMUX_LINE_IN, | ||
1181 | .gpio = default_analog, | ||
1182 | }, { | ||
1183 | .type = EM28XX_VMUX_SVIDEO, | ||
1184 | .vmux = TVP5150_SVIDEO, | ||
1185 | .amux = EM28XX_AMUX_LINE_IN, | ||
1186 | .gpio = default_analog, | ||
1187 | } }, | ||
1188 | }, | ||
1098 | [EM2881_BOARD_DNT_DA2_HYBRID] = { | 1189 | [EM2881_BOARD_DNT_DA2_HYBRID] = { |
1099 | .name = "DNT DA2 Hybrid", | 1190 | .name = "DNT DA2 Hybrid", |
1100 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1191 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
@@ -1322,6 +1413,42 @@ struct em28xx_board em28xx_boards[] = { | |||
1322 | .amux = EM28XX_AMUX_VIDEO, | 1413 | .amux = EM28XX_AMUX_VIDEO, |
1323 | } }, | 1414 | } }, |
1324 | }, | 1415 | }, |
1416 | [EM2860_BOARD_TERRATEC_GRABBY] = { | ||
1417 | .name = "Terratec Grabby", | ||
1418 | .vchannels = 2, | ||
1419 | .tuner_type = TUNER_ABSENT, | ||
1420 | .decoder = EM28XX_SAA711X, | ||
1421 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1422 | .input = { { | ||
1423 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1424 | .vmux = SAA7115_COMPOSITE0, | ||
1425 | .amux = EM28XX_AMUX_VIDEO2, | ||
1426 | }, { | ||
1427 | .type = EM28XX_VMUX_SVIDEO, | ||
1428 | .vmux = SAA7115_SVIDEO3, | ||
1429 | .amux = EM28XX_AMUX_VIDEO2, | ||
1430 | } }, | ||
1431 | }, | ||
1432 | [EM2860_BOARD_TERRATEC_AV350] = { | ||
1433 | .name = "Terratec AV350", | ||
1434 | .vchannels = 2, | ||
1435 | .tuner_type = TUNER_ABSENT, | ||
1436 | .decoder = EM28XX_TVP5150, | ||
1437 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1438 | .mute_gpio = terratec_av350_mute_gpio, | ||
1439 | .input = { { | ||
1440 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1441 | .vmux = TVP5150_COMPOSITE1, | ||
1442 | .amux = EM28XX_AUDIO_SRC_LINE, | ||
1443 | .gpio = terratec_av350_unmute_gpio, | ||
1444 | |||
1445 | }, { | ||
1446 | .type = EM28XX_VMUX_SVIDEO, | ||
1447 | .vmux = TVP5150_SVIDEO, | ||
1448 | .amux = EM28XX_AUDIO_SRC_LINE, | ||
1449 | .gpio = terratec_av350_unmute_gpio, | ||
1450 | } }, | ||
1451 | }, | ||
1325 | }; | 1452 | }; |
1326 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); | 1453 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); |
1327 | 1454 | ||
@@ -1355,6 +1482,8 @@ struct usb_device_id em28xx_id_table[] = { | |||
1355 | .driver_info = EM2880_BOARD_KWORLD_DVB_305U }, | 1482 | .driver_info = EM2880_BOARD_KWORLD_DVB_305U }, |
1356 | { USB_DEVICE(0xeb1a, 0xe310), | 1483 | { USB_DEVICE(0xeb1a, 0xe310), |
1357 | .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD }, | 1484 | .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD }, |
1485 | { USB_DEVICE(0xeb1a, 0xa313), | ||
1486 | .driver_info = EM2882_BOARD_KWORLD_ATSC_315U }, | ||
1358 | { USB_DEVICE(0xeb1a, 0xa316), | 1487 | { USB_DEVICE(0xeb1a, 0xa316), |
1359 | .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U }, | 1488 | .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U }, |
1360 | { USB_DEVICE(0xeb1a, 0xe320), | 1489 | { USB_DEVICE(0xeb1a, 0xe320), |
@@ -1385,6 +1514,10 @@ struct usb_device_id em28xx_id_table[] = { | |||
1385 | .driver_info = EM2870_BOARD_TERRATEC_XS }, | 1514 | .driver_info = EM2870_BOARD_TERRATEC_XS }, |
1386 | { USB_DEVICE(0x0ccd, 0x0047), | 1515 | { USB_DEVICE(0x0ccd, 0x0047), |
1387 | .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, | 1516 | .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, |
1517 | { USB_DEVICE(0x0ccd, 0x0084), | ||
1518 | .driver_info = EM2860_BOARD_TERRATEC_AV350 }, | ||
1519 | { USB_DEVICE(0x0ccd, 0x0096), | ||
1520 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, | ||
1388 | { USB_DEVICE(0x185b, 0x2870), | 1521 | { USB_DEVICE(0x185b, 0x2870), |
1389 | .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, | 1522 | .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, |
1390 | { USB_DEVICE(0x185b, 0x2041), | 1523 | { USB_DEVICE(0x185b, 0x2041), |
@@ -1437,13 +1570,14 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = { | |||
1437 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, | 1570 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, |
1438 | {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, | 1571 | {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, |
1439 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, | 1572 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, |
1573 | {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, | ||
1440 | }; | 1574 | }; |
1441 | 1575 | ||
1442 | /* I2C devicelist hash table for devices with generic USB IDs */ | 1576 | /* I2C devicelist hash table for devices with generic USB IDs */ |
1443 | static struct em28xx_hash_table em28xx_i2c_hash[] = { | 1577 | static struct em28xx_hash_table em28xx_i2c_hash[] = { |
1444 | {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, | 1578 | {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, |
1445 | {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, | 1579 | {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, |
1446 | {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT}, | 1580 | {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT}, |
1447 | {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, | 1581 | {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, |
1448 | }; | 1582 | }; |
1449 | 1583 | ||
@@ -1619,6 +1753,17 @@ void em28xx_pre_card_setup(struct em28xx *dev) | |||
1619 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | 1753 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); |
1620 | break; | 1754 | break; |
1621 | 1755 | ||
1756 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
1757 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); | ||
1758 | msleep(10); | ||
1759 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
1760 | msleep(10); | ||
1761 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); | ||
1762 | msleep(10); | ||
1763 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x08); | ||
1764 | msleep(10); | ||
1765 | break; | ||
1766 | |||
1622 | case EM2860_BOARD_KAIOMY_TVNPC_U2: | 1767 | case EM2860_BOARD_KAIOMY_TVNPC_U2: |
1623 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); | 1768 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); |
1624 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | 1769 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); |
@@ -1664,6 +1809,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | |||
1664 | ctl->mts = em28xx_boards[dev->model].mts_firmware; | 1809 | ctl->mts = em28xx_boards[dev->model].mts_firmware; |
1665 | 1810 | ||
1666 | switch (dev->model) { | 1811 | switch (dev->model) { |
1812 | case EM2880_BOARD_EMPIRE_DUAL_TV: | ||
1667 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | 1813 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: |
1668 | ctl->demod = XC3028_FE_ZARLINK456; | 1814 | ctl->demod = XC3028_FE_ZARLINK456; |
1669 | break; | 1815 | break; |
@@ -1835,12 +1981,20 @@ static int em28xx_hint_board(struct em28xx *dev) | |||
1835 | } | 1981 | } |
1836 | 1982 | ||
1837 | /* ----------------------------------------------------------------------- */ | 1983 | /* ----------------------------------------------------------------------- */ |
1838 | void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) | 1984 | void em28xx_register_i2c_ir(struct em28xx *dev) |
1839 | { | 1985 | { |
1840 | if (disable_ir) { | 1986 | struct i2c_board_info info; |
1841 | ir->get_key = NULL; | 1987 | struct IR_i2c_init_data init_data; |
1842 | return ; | 1988 | const unsigned short addr_list[] = { |
1843 | } | 1989 | 0x30, 0x47, I2C_CLIENT_END |
1990 | }; | ||
1991 | |||
1992 | if (disable_ir) | ||
1993 | return; | ||
1994 | |||
1995 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1996 | memset(&init_data, 0, sizeof(struct IR_i2c_init_data)); | ||
1997 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
1844 | 1998 | ||
1845 | /* detect & configure */ | 1999 | /* detect & configure */ |
1846 | switch (dev->model) { | 2000 | switch (dev->model) { |
@@ -1850,22 +2004,19 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) | |||
1850 | break; | 2004 | break; |
1851 | case (EM2800_BOARD_TERRATEC_CINERGY_200): | 2005 | case (EM2800_BOARD_TERRATEC_CINERGY_200): |
1852 | case (EM2820_BOARD_TERRATEC_CINERGY_250): | 2006 | case (EM2820_BOARD_TERRATEC_CINERGY_250): |
1853 | ir->ir_codes = ir_codes_em_terratec; | 2007 | init_data.ir_codes = ir_codes_em_terratec; |
1854 | ir->get_key = em28xx_get_key_terratec; | 2008 | init_data.get_key = em28xx_get_key_terratec; |
1855 | snprintf(ir->c.name, sizeof(ir->c.name), | 2009 | init_data.name = "i2c IR (EM28XX Terratec)"; |
1856 | "i2c IR (EM28XX Terratec)"); | ||
1857 | break; | 2010 | break; |
1858 | case (EM2820_BOARD_PINNACLE_USB_2): | 2011 | case (EM2820_BOARD_PINNACLE_USB_2): |
1859 | ir->ir_codes = ir_codes_pinnacle_grey; | 2012 | init_data.ir_codes = ir_codes_pinnacle_grey; |
1860 | ir->get_key = em28xx_get_key_pinnacle_usb_grey; | 2013 | init_data.get_key = em28xx_get_key_pinnacle_usb_grey; |
1861 | snprintf(ir->c.name, sizeof(ir->c.name), | 2014 | init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; |
1862 | "i2c IR (EM28XX Pinnacle PCTV)"); | ||
1863 | break; | 2015 | break; |
1864 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): | 2016 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): |
1865 | ir->ir_codes = ir_codes_hauppauge_new; | 2017 | init_data.ir_codes = ir_codes_hauppauge_new; |
1866 | ir->get_key = em28xx_get_key_em_haup; | 2018 | init_data.get_key = em28xx_get_key_em_haup; |
1867 | snprintf(ir->c.name, sizeof(ir->c.name), | 2019 | init_data.name = "i2c IR (EM2840 Hauppauge)"; |
1868 | "i2c IR (EM2840 Hauppauge)"); | ||
1869 | break; | 2020 | break; |
1870 | case (EM2820_BOARD_MSI_VOX_USB_2): | 2021 | case (EM2820_BOARD_MSI_VOX_USB_2): |
1871 | break; | 2022 | break; |
@@ -1876,6 +2027,10 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) | |||
1876 | case (EM2800_BOARD_GRABBEEX_USB2800): | 2027 | case (EM2800_BOARD_GRABBEEX_USB2800): |
1877 | break; | 2028 | break; |
1878 | } | 2029 | } |
2030 | |||
2031 | if (init_data.name) | ||
2032 | info.platform_data = &init_data; | ||
2033 | i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); | ||
1879 | } | 2034 | } |
1880 | 2035 | ||
1881 | void em28xx_card_setup(struct em28xx *dev) | 2036 | void em28xx_card_setup(struct em28xx *dev) |
@@ -1886,6 +2041,9 @@ void em28xx_card_setup(struct em28xx *dev) | |||
1886 | if (em28xx_boards[dev->model].tuner_addr) | 2041 | if (em28xx_boards[dev->model].tuner_addr) |
1887 | dev->tuner_addr = em28xx_boards[dev->model].tuner_addr; | 2042 | dev->tuner_addr = em28xx_boards[dev->model].tuner_addr; |
1888 | 2043 | ||
2044 | if (em28xx_boards[dev->model].tda9887_conf) | ||
2045 | dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; | ||
2046 | |||
1889 | /* request some modules */ | 2047 | /* request some modules */ |
1890 | switch (dev->model) { | 2048 | switch (dev->model) { |
1891 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: | 2049 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: |
@@ -1915,6 +2073,12 @@ void em28xx_card_setup(struct em28xx *dev) | |||
1915 | #endif | 2073 | #endif |
1916 | break; | 2074 | break; |
1917 | } | 2075 | } |
2076 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
2077 | em28xx_write_reg(dev, 0x0d, 0x42); | ||
2078 | msleep(10); | ||
2079 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | ||
2080 | msleep(10); | ||
2081 | break; | ||
1918 | case EM2820_BOARD_KWORLD_PVRTV2800RF: | 2082 | case EM2820_BOARD_KWORLD_PVRTV2800RF: |
1919 | /* GPIO enables sound on KWORLD PVR TV 2800RF */ | 2083 | /* GPIO enables sound on KWORLD PVR TV 2800RF */ |
1920 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9); | 2084 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9); |
@@ -2279,6 +2443,20 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
2279 | ifnum, | 2443 | ifnum, |
2280 | interface->altsetting->desc.bInterfaceNumber); | 2444 | interface->altsetting->desc.bInterfaceNumber); |
2281 | 2445 | ||
2446 | /* | ||
2447 | * Make sure we have 480 Mbps of bandwidth, otherwise things like | ||
2448 | * video stream wouldn't likely work, since 12 Mbps is generally | ||
2449 | * not enough even for most Digital TV streams. | ||
2450 | */ | ||
2451 | if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { | ||
2452 | printk(DRIVER_NAME ": Device initialization failed.\n"); | ||
2453 | printk(DRIVER_NAME ": Device must be connected to a high-speed" | ||
2454 | " USB 2.0 port.\n"); | ||
2455 | em28xx_devused &= ~(1<<nr); | ||
2456 | retval = -ENODEV; | ||
2457 | goto err; | ||
2458 | } | ||
2459 | |||
2282 | if (nr >= EM28XX_MAXBOARDS) { | 2460 | if (nr >= EM28XX_MAXBOARDS) { |
2283 | printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", | 2461 | printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", |
2284 | EM28XX_MAXBOARDS); | 2462 | EM28XX_MAXBOARDS); |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 192b76cdd5d7..c8d7ce8fbd36 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -500,18 +500,21 @@ int em28xx_audio_setup(struct em28xx *dev) | |||
500 | 500 | ||
501 | /* See how this device is configured */ | 501 | /* See how this device is configured */ |
502 | cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); | 502 | cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); |
503 | if (cfg < 0) | 503 | em28xx_info("Config register raw data: 0x%02x\n", cfg); |
504 | if (cfg < 0) { | ||
505 | /* Register read error? */ | ||
504 | cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */ | 506 | cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */ |
505 | else | 507 | } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 0x00) { |
506 | em28xx_info("Config register raw data: 0x%02x\n", cfg); | 508 | /* The device doesn't have vendor audio at all */ |
507 | 509 | dev->has_alsa_audio = 0; | |
508 | if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == | 510 | dev->audio_mode.has_audio = 0; |
509 | EM28XX_CHIPCFG_I2S_3_SAMPRATES) { | 511 | return 0; |
512 | } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == | ||
513 | EM28XX_CHIPCFG_I2S_3_SAMPRATES) { | ||
510 | em28xx_info("I2S Audio (3 sample rates)\n"); | 514 | em28xx_info("I2S Audio (3 sample rates)\n"); |
511 | dev->audio_mode.i2s_3rates = 1; | 515 | dev->audio_mode.i2s_3rates = 1; |
512 | } | 516 | } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == |
513 | if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == | 517 | EM28XX_CHIPCFG_I2S_5_SAMPRATES) { |
514 | EM28XX_CHIPCFG_I2S_5_SAMPRATES) { | ||
515 | em28xx_info("I2S Audio (5 sample rates)\n"); | 518 | em28xx_info("I2S Audio (5 sample rates)\n"); |
516 | dev->audio_mode.i2s_5rates = 1; | 519 | dev->audio_mode.i2s_5rates = 1; |
517 | } | 520 | } |
@@ -938,7 +941,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
938 | dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, | 941 | dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, |
939 | GFP_KERNEL); | 942 | GFP_KERNEL); |
940 | if (!dev->isoc_ctl.transfer_buffer) { | 943 | if (!dev->isoc_ctl.transfer_buffer) { |
941 | em28xx_errdev("cannot allocate memory for usbtransfer\n"); | 944 | em28xx_errdev("cannot allocate memory for usb transfer\n"); |
942 | kfree(dev->isoc_ctl.urb); | 945 | kfree(dev->isoc_ctl.urb); |
943 | return -ENOMEM; | 946 | return -ENOMEM; |
944 | } | 947 | } |
@@ -1012,6 +1015,41 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
1012 | } | 1015 | } |
1013 | EXPORT_SYMBOL_GPL(em28xx_init_isoc); | 1016 | EXPORT_SYMBOL_GPL(em28xx_init_isoc); |
1014 | 1017 | ||
1018 | /* Determine the packet size for the DVB stream for the given device | ||
1019 | (underlying value programmed into the eeprom) */ | ||
1020 | int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev) | ||
1021 | { | ||
1022 | unsigned int chip_cfg2; | ||
1023 | unsigned int packet_size = 564; | ||
1024 | |||
1025 | if (dev->chip_id == CHIP_ID_EM2874) { | ||
1026 | /* FIXME - for now assume 564 like it was before, but the | ||
1027 | em2874 code should be added to return the proper value... */ | ||
1028 | packet_size = 564; | ||
1029 | } else { | ||
1030 | /* TS max packet size stored in bits 1-0 of R01 */ | ||
1031 | chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2); | ||
1032 | switch (chip_cfg2 & EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK) { | ||
1033 | case EM28XX_CHIPCFG2_TS_PACKETSIZE_188: | ||
1034 | packet_size = 188; | ||
1035 | break; | ||
1036 | case EM28XX_CHIPCFG2_TS_PACKETSIZE_376: | ||
1037 | packet_size = 376; | ||
1038 | break; | ||
1039 | case EM28XX_CHIPCFG2_TS_PACKETSIZE_564: | ||
1040 | packet_size = 564; | ||
1041 | break; | ||
1042 | case EM28XX_CHIPCFG2_TS_PACKETSIZE_752: | ||
1043 | packet_size = 752; | ||
1044 | break; | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1048 | em28xx_coredbg("dvb max packet size=%d\n", packet_size); | ||
1049 | return packet_size; | ||
1050 | } | ||
1051 | EXPORT_SYMBOL_GPL(em28xx_isoc_dvb_max_packetsize); | ||
1052 | |||
1015 | /* | 1053 | /* |
1016 | * em28xx_wake_i2c() | 1054 | * em28xx_wake_i2c() |
1017 | * configure i2c attached devices | 1055 | * configure i2c attached devices |
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index fcd25511209b..563dd2b1c8e9 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include "em28xx.h" | 25 | #include "em28xx.h" |
26 | #include <media/v4l2-common.h> | 26 | #include <media/v4l2-common.h> |
27 | #include <media/videobuf-vmalloc.h> | 27 | #include <media/videobuf-vmalloc.h> |
28 | #include <media/tuner.h> | ||
29 | #include "tuner-simple.h" | ||
28 | 30 | ||
29 | #include "lgdt330x.h" | 31 | #include "lgdt330x.h" |
30 | #include "zl10353.h" | 32 | #include "zl10353.h" |
@@ -46,7 +48,6 @@ if (debug >= level) \ | |||
46 | } while (0) | 48 | } while (0) |
47 | 49 | ||
48 | #define EM28XX_DVB_NUM_BUFS 5 | 50 | #define EM28XX_DVB_NUM_BUFS 5 |
49 | #define EM28XX_DVB_MAX_PACKETSIZE 564 | ||
50 | #define EM28XX_DVB_MAX_PACKETS 64 | 51 | #define EM28XX_DVB_MAX_PACKETS 64 |
51 | 52 | ||
52 | struct em28xx_dvb { | 53 | struct em28xx_dvb { |
@@ -142,14 +143,17 @@ static int start_streaming(struct em28xx_dvb *dvb) | |||
142 | { | 143 | { |
143 | int rc; | 144 | int rc; |
144 | struct em28xx *dev = dvb->adapter.priv; | 145 | struct em28xx *dev = dvb->adapter.priv; |
146 | int max_dvb_packet_size; | ||
145 | 147 | ||
146 | usb_set_interface(dev->udev, 0, 1); | 148 | usb_set_interface(dev->udev, 0, 1); |
147 | rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | 149 | rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); |
148 | if (rc < 0) | 150 | if (rc < 0) |
149 | return rc; | 151 | return rc; |
150 | 152 | ||
153 | max_dvb_packet_size = em28xx_isoc_dvb_max_packetsize(dev); | ||
154 | |||
151 | return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, | 155 | return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, |
152 | EM28XX_DVB_NUM_BUFS, EM28XX_DVB_MAX_PACKETSIZE, | 156 | EM28XX_DVB_NUM_BUFS, max_dvb_packet_size, |
153 | dvb_isoc_copy); | 157 | dvb_isoc_copy); |
154 | } | 158 | } |
155 | 159 | ||
@@ -431,6 +435,7 @@ static int dvb_init(struct em28xx *dev) | |||
431 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | 435 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: |
432 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | 436 | case EM2880_BOARD_TERRATEC_HYBRID_XS: |
433 | case EM2880_BOARD_KWORLD_DVB_310U: | 437 | case EM2880_BOARD_KWORLD_DVB_310U: |
438 | case EM2880_BOARD_EMPIRE_DUAL_TV: | ||
434 | dvb->frontend = dvb_attach(zl10353_attach, | 439 | dvb->frontend = dvb_attach(zl10353_attach, |
435 | &em28xx_zl10353_with_xc3028, | 440 | &em28xx_zl10353_with_xc3028, |
436 | &dev->i2c_adap); | 441 | &dev->i2c_adap); |
@@ -448,6 +453,18 @@ static int dvb_init(struct em28xx *dev) | |||
448 | goto out_free; | 453 | goto out_free; |
449 | } | 454 | } |
450 | break; | 455 | break; |
456 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
457 | dvb->frontend = dvb_attach(lgdt330x_attach, | ||
458 | &em2880_lgdt3303_dev, | ||
459 | &dev->i2c_adap); | ||
460 | if (dvb->frontend != NULL) { | ||
461 | if (!dvb_attach(simple_tuner_attach, dvb->frontend, | ||
462 | &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) { | ||
463 | result = -EINVAL; | ||
464 | goto out_free; | ||
465 | } | ||
466 | } | ||
467 | break; | ||
451 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | 468 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: |
452 | #ifdef EM28XX_DRX397XD_SUPPORT | 469 | #ifdef EM28XX_DRX397XD_SUPPORT |
453 | /* We don't have the config structure properly populated, so | 470 | /* We don't have the config structure properly populated, so |
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index f0bf1d960c75..2c86fcf089f5 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -451,27 +451,6 @@ static u32 functionality(struct i2c_adapter *adap) | |||
451 | return I2C_FUNC_SMBUS_EMUL; | 451 | return I2C_FUNC_SMBUS_EMUL; |
452 | } | 452 | } |
453 | 453 | ||
454 | /* | ||
455 | * attach_inform() | ||
456 | * gets called when a device attaches to the i2c bus | ||
457 | * does some basic configuration | ||
458 | */ | ||
459 | static int attach_inform(struct i2c_client *client) | ||
460 | { | ||
461 | struct em28xx *dev = client->adapter->algo_data; | ||
462 | struct IR_i2c *ir = i2c_get_clientdata(client); | ||
463 | |||
464 | switch (client->addr << 1) { | ||
465 | case 0x60: | ||
466 | case 0x8e: | ||
467 | dprintk1(1, "attach_inform: IR detected (%s).\n", ir->phys); | ||
468 | em28xx_set_ir(dev, ir); | ||
469 | break; | ||
470 | } | ||
471 | |||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | static struct i2c_algorithm em28xx_algo = { | 454 | static struct i2c_algorithm em28xx_algo = { |
476 | .master_xfer = em28xx_i2c_xfer, | 455 | .master_xfer = em28xx_i2c_xfer, |
477 | .functionality = functionality, | 456 | .functionality = functionality, |
@@ -482,7 +461,6 @@ static struct i2c_adapter em28xx_adap_template = { | |||
482 | .name = "em28xx", | 461 | .name = "em28xx", |
483 | .id = I2C_HW_B_EM28XX, | 462 | .id = I2C_HW_B_EM28XX, |
484 | .algo = &em28xx_algo, | 463 | .algo = &em28xx_algo, |
485 | .client_register = attach_inform, | ||
486 | }; | 464 | }; |
487 | 465 | ||
488 | static struct i2c_client em28xx_client_template = { | 466 | static struct i2c_client em28xx_client_template = { |
@@ -575,6 +553,9 @@ int em28xx_i2c_register(struct em28xx *dev) | |||
575 | if (i2c_scan) | 553 | if (i2c_scan) |
576 | em28xx_do_i2c_scan(dev); | 554 | em28xx_do_i2c_scan(dev); |
577 | 555 | ||
556 | /* Instantiate the IR receiver device, if present */ | ||
557 | em28xx_register_i2c_ir(dev); | ||
558 | |||
578 | return 0; | 559 | return 0; |
579 | } | 560 | } |
580 | 561 | ||
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index a5abfd7a19f5..7a0fe3816e3d 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | |||
40 | 40 | ||
41 | #define i2cdprintk(fmt, arg...) \ | 41 | #define i2cdprintk(fmt, arg...) \ |
42 | if (ir_debug) { \ | 42 | if (ir_debug) { \ |
43 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \ | 43 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ |
44 | } | 44 | } |
45 | 45 | ||
46 | #define dprintk(fmt, arg...) \ | 46 | #define dprintk(fmt, arg...) \ |
@@ -85,7 +85,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
85 | unsigned char b; | 85 | unsigned char b; |
86 | 86 | ||
87 | /* poll IR chip */ | 87 | /* poll IR chip */ |
88 | if (1 != i2c_master_recv(&ir->c, &b, 1)) { | 88 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
89 | i2cdprintk("read error\n"); | 89 | i2cdprintk("read error\n"); |
90 | return -EIO; | 90 | return -EIO; |
91 | } | 91 | } |
@@ -114,7 +114,7 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
114 | unsigned char code; | 114 | unsigned char code; |
115 | 115 | ||
116 | /* poll IR chip */ | 116 | /* poll IR chip */ |
117 | if (2 != i2c_master_recv(&ir->c, buf, 2)) | 117 | if (2 != i2c_master_recv(ir->c, buf, 2)) |
118 | return -EIO; | 118 | return -EIO; |
119 | 119 | ||
120 | /* Does eliminate repeated parity code */ | 120 | /* Does eliminate repeated parity code */ |
@@ -147,7 +147,7 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, | |||
147 | 147 | ||
148 | /* poll IR chip */ | 148 | /* poll IR chip */ |
149 | 149 | ||
150 | if (3 != i2c_master_recv(&ir->c, buf, 3)) { | 150 | if (3 != i2c_master_recv(ir->c, buf, 3)) { |
151 | i2cdprintk("read error\n"); | 151 | i2cdprintk("read error\n"); |
152 | return -EIO; | 152 | return -EIO; |
153 | } | 153 | } |
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h index 24e39c56811e..a2676d63cfd0 100644 --- a/drivers/media/video/em28xx/em28xx-reg.h +++ b/drivers/media/video/em28xx/em28xx-reg.h | |||
@@ -27,6 +27,22 @@ | |||
27 | #define EM28XX_CHIPCFG_AC97 0x10 | 27 | #define EM28XX_CHIPCFG_AC97 0x10 |
28 | #define EM28XX_CHIPCFG_AUDIOMASK 0x30 | 28 | #define EM28XX_CHIPCFG_AUDIOMASK 0x30 |
29 | 29 | ||
30 | #define EM28XX_R01_CHIPCFG2 0x01 | ||
31 | |||
32 | /* em28xx Chip Configuration 2 0x01 */ | ||
33 | #define EM28XX_CHIPCFG2_TS_PRESENT 0x10 | ||
34 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_MASK 0x0c /* bits 3-2 */ | ||
35 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_1MF 0x00 | ||
36 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_2MF 0x04 | ||
37 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_4MF 0x08 | ||
38 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_8MF 0x0c | ||
39 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK 0x03 /* bits 0-1 */ | ||
40 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_188 0x00 | ||
41 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_376 0x01 | ||
42 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_564 0x02 | ||
43 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_752 0x03 | ||
44 | |||
45 | |||
30 | /* GPIO/GPO registers */ | 46 | /* GPIO/GPO registers */ |
31 | #define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ | 47 | #define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ |
32 | #define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ | 48 | #define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 4c4e58004f54..8bf81be1da61 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -58,7 +58,7 @@ | |||
58 | #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16 | 58 | #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16 |
59 | #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 | 59 | #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 |
60 | #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 | 60 | #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 |
61 | #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 | 61 | #define EM2860_BOARD_SAA711X_REFERENCE_DESIGN 19 |
62 | #define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 | 62 | #define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 |
63 | #define EM2800_BOARD_GRABBEEX_USB2800 21 | 63 | #define EM2800_BOARD_GRABBEEX_USB2800 21 |
64 | #define EM2750_BOARD_UNKNOWN 22 | 64 | #define EM2750_BOARD_UNKNOWN 22 |
@@ -102,6 +102,10 @@ | |||
102 | #define EM2860_BOARD_KAIOMY_TVNPC_U2 63 | 102 | #define EM2860_BOARD_KAIOMY_TVNPC_U2 63 |
103 | #define EM2860_BOARD_EASYCAP 64 | 103 | #define EM2860_BOARD_EASYCAP 64 |
104 | #define EM2820_BOARD_IODATA_GVMVP_SZ 65 | 104 | #define EM2820_BOARD_IODATA_GVMVP_SZ 65 |
105 | #define EM2880_BOARD_EMPIRE_DUAL_TV 66 | ||
106 | #define EM2860_BOARD_TERRATEC_GRABBY 67 | ||
107 | #define EM2860_BOARD_TERRATEC_AV350 68 | ||
108 | #define EM2882_BOARD_KWORLD_ATSC_315U 69 | ||
105 | 109 | ||
106 | /* Limits minimum and default number of buffers */ | 110 | /* Limits minimum and default number of buffers */ |
107 | #define EM28XX_MIN_BUF 4 | 111 | #define EM28XX_MIN_BUF 4 |
@@ -615,6 +619,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
615 | int num_bufs, int max_pkt_size, | 619 | int num_bufs, int max_pkt_size, |
616 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); | 620 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); |
617 | void em28xx_uninit_isoc(struct em28xx *dev); | 621 | void em28xx_uninit_isoc(struct em28xx *dev); |
622 | int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev); | ||
618 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); | 623 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); |
619 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); | 624 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); |
620 | void em28xx_wake_i2c(struct em28xx *dev); | 625 | void em28xx_wake_i2c(struct em28xx *dev); |
@@ -639,7 +644,7 @@ extern void em28xx_card_setup(struct em28xx *dev); | |||
639 | extern struct em28xx_board em28xx_boards[]; | 644 | extern struct em28xx_board em28xx_boards[]; |
640 | extern struct usb_device_id em28xx_id_table[]; | 645 | extern struct usb_device_id em28xx_id_table[]; |
641 | extern const unsigned int em28xx_bcount; | 646 | extern const unsigned int em28xx_bcount; |
642 | void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); | 647 | void em28xx_register_i2c_ir(struct em28xx *dev); |
643 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg); | 648 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg); |
644 | void em28xx_release_resources(struct em28xx *dev); | 649 | void em28xx_release_resources(struct em28xx *dev); |
645 | 650 | ||
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c index 00e6863ed666..480ec5c87d0e 100644 --- a/drivers/media/video/gspca/finepix.c +++ b/drivers/media/video/gspca/finepix.c | |||
@@ -168,6 +168,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
168 | 168 | ||
169 | cam->cam_mode = fpix_mode; | 169 | cam->cam_mode = fpix_mode; |
170 | cam->nmodes = 1; | 170 | cam->nmodes = 1; |
171 | cam->bulk = 1; | ||
171 | cam->bulk_size = FPIX_MAX_TRANSFER; | 172 | cam->bulk_size = FPIX_MAX_TRANSFER; |
172 | 173 | ||
173 | INIT_WORK(&dev->work_struct, dostream); | 174 | INIT_WORK(&dev->work_struct, dostream); |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index a2741d7dccfe..f7e0355ad644 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Main USB camera driver | 2 | * Main USB camera driver |
3 | * | 3 | * |
4 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | 4 | * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr) |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | |||
47 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); | 47 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); |
48 | MODULE_LICENSE("GPL"); | 48 | MODULE_LICENSE("GPL"); |
49 | 49 | ||
50 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0) | 50 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 6, 0) |
51 | 51 | ||
52 | #ifdef GSPCA_DEBUG | 52 | #ifdef GSPCA_DEBUG |
53 | int gspca_debug = D_ERR | D_PROBE; | 53 | int gspca_debug = D_ERR | D_PROBE; |
@@ -441,7 +441,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) | |||
441 | * look for an input transfer endpoint in an alternate setting | 441 | * look for an input transfer endpoint in an alternate setting |
442 | */ | 442 | */ |
443 | static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, | 443 | static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, |
444 | __u8 xfer) | 444 | int xfer) |
445 | { | 445 | { |
446 | struct usb_host_endpoint *ep; | 446 | struct usb_host_endpoint *ep; |
447 | int i, attr; | 447 | int i, attr; |
@@ -449,7 +449,8 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, | |||
449 | for (i = 0; i < alt->desc.bNumEndpoints; i++) { | 449 | for (i = 0; i < alt->desc.bNumEndpoints; i++) { |
450 | ep = &alt->endpoint[i]; | 450 | ep = &alt->endpoint[i]; |
451 | attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | 451 | attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; |
452 | if (attr == xfer) | 452 | if (attr == xfer |
453 | && ep->desc.wMaxPacketSize != 0) | ||
453 | return ep; | 454 | return ep; |
454 | } | 455 | } |
455 | return NULL; | 456 | return NULL; |
@@ -467,37 +468,28 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) | |||
467 | { | 468 | { |
468 | struct usb_interface *intf; | 469 | struct usb_interface *intf; |
469 | struct usb_host_endpoint *ep; | 470 | struct usb_host_endpoint *ep; |
470 | int i, ret; | 471 | int xfer, i, ret; |
471 | 472 | ||
472 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); | 473 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); |
473 | ep = NULL; | 474 | ep = NULL; |
475 | xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK | ||
476 | : USB_ENDPOINT_XFER_ISOC; | ||
474 | i = gspca_dev->alt; /* previous alt setting */ | 477 | i = gspca_dev->alt; /* previous alt setting */ |
475 | |||
476 | /* try isoc */ | ||
477 | while (--i >= 0) { | 478 | while (--i >= 0) { |
478 | ep = alt_xfer(&intf->altsetting[i], | 479 | ep = alt_xfer(&intf->altsetting[i], xfer); |
479 | USB_ENDPOINT_XFER_ISOC); | ||
480 | if (ep) | 480 | if (ep) |
481 | break; | 481 | break; |
482 | } | 482 | } |
483 | |||
484 | /* if no isoc, try bulk (alt 0 only) */ | ||
485 | if (ep == NULL) { | 483 | if (ep == NULL) { |
486 | ep = alt_xfer(&intf->altsetting[0], | 484 | err("no transfer endpoint found"); |
487 | USB_ENDPOINT_XFER_BULK); | 485 | return NULL; |
488 | if (ep == NULL) { | ||
489 | err("no transfer endpoint found"); | ||
490 | return NULL; | ||
491 | } | ||
492 | i = 0; | ||
493 | gspca_dev->bulk = 1; | ||
494 | } | 486 | } |
495 | PDEBUG(D_STREAM, "use alt %d ep 0x%02x", | 487 | PDEBUG(D_STREAM, "use alt %d ep 0x%02x", |
496 | i, ep->desc.bEndpointAddress); | 488 | i, ep->desc.bEndpointAddress); |
497 | if (i > 0) { | 489 | if (gspca_dev->nbalt > 1) { |
498 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); | 490 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); |
499 | if (ret < 0) { | 491 | if (ret < 0) { |
500 | err("set interface err %d", ret); | 492 | err("set alt %d err %d", i, ret); |
501 | return NULL; | 493 | return NULL; |
502 | } | 494 | } |
503 | } | 495 | } |
@@ -517,13 +509,13 @@ static int create_urbs(struct gspca_dev *gspca_dev, | |||
517 | /* calculate the packet size and the number of packets */ | 509 | /* calculate the packet size and the number of packets */ |
518 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); | 510 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); |
519 | 511 | ||
520 | if (!gspca_dev->bulk) { /* isoc */ | 512 | if (!gspca_dev->cam.bulk) { /* isoc */ |
521 | 513 | ||
522 | /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ | 514 | /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ |
523 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); | 515 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); |
524 | npkt = ISO_MAX_SIZE / psize; | 516 | npkt = gspca_dev->cam.npkt; |
525 | if (npkt > ISO_MAX_PKT) | 517 | if (npkt == 0) |
526 | npkt = ISO_MAX_PKT; | 518 | npkt = 32; /* default value */ |
527 | bsize = psize * npkt; | 519 | bsize = psize * npkt; |
528 | PDEBUG(D_STREAM, | 520 | PDEBUG(D_STREAM, |
529 | "isoc %d pkts size %d = bsize:%d", | 521 | "isoc %d pkts size %d = bsize:%d", |
@@ -617,7 +609,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
617 | goto out; | 609 | goto out; |
618 | 610 | ||
619 | /* clear the bulk endpoint */ | 611 | /* clear the bulk endpoint */ |
620 | if (gspca_dev->bulk) | 612 | if (gspca_dev->cam.bulk) |
621 | usb_clear_halt(gspca_dev->dev, | 613 | usb_clear_halt(gspca_dev->dev, |
622 | gspca_dev->urb[0]->pipe); | 614 | gspca_dev->urb[0]->pipe); |
623 | 615 | ||
@@ -630,7 +622,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
630 | gspca_dev->streaming = 1; | 622 | gspca_dev->streaming = 1; |
631 | 623 | ||
632 | /* some bulk transfers are started by the subdriver */ | 624 | /* some bulk transfers are started by the subdriver */ |
633 | if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0) | 625 | if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0) |
634 | break; | 626 | break; |
635 | 627 | ||
636 | /* submit the URBs */ | 628 | /* submit the URBs */ |
@@ -661,6 +653,8 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev) | |||
661 | { | 653 | { |
662 | int ret; | 654 | int ret; |
663 | 655 | ||
656 | if (gspca_dev->alt == 0) | ||
657 | return 0; | ||
664 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); | 658 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); |
665 | if (ret < 0) | 659 | if (ret < 0) |
666 | PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); | 660 | PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); |
@@ -869,6 +863,32 @@ out: | |||
869 | return ret; | 863 | return ret; |
870 | } | 864 | } |
871 | 865 | ||
866 | static int vidioc_enum_framesizes(struct file *file, void *priv, | ||
867 | struct v4l2_frmsizeenum *fsize) | ||
868 | { | ||
869 | struct gspca_dev *gspca_dev = priv; | ||
870 | int i; | ||
871 | __u32 index = 0; | ||
872 | |||
873 | for (i = 0; i < gspca_dev->cam.nmodes; i++) { | ||
874 | if (fsize->pixel_format != | ||
875 | gspca_dev->cam.cam_mode[i].pixelformat) | ||
876 | continue; | ||
877 | |||
878 | if (fsize->index == index) { | ||
879 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
880 | fsize->discrete.width = | ||
881 | gspca_dev->cam.cam_mode[i].width; | ||
882 | fsize->discrete.height = | ||
883 | gspca_dev->cam.cam_mode[i].height; | ||
884 | return 0; | ||
885 | } | ||
886 | index++; | ||
887 | } | ||
888 | |||
889 | return -EINVAL; | ||
890 | } | ||
891 | |||
872 | static void gspca_release(struct video_device *vfd) | 892 | static void gspca_release(struct video_device *vfd) |
873 | { | 893 | { |
874 | struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); | 894 | struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); |
@@ -989,43 +1009,54 @@ out: | |||
989 | return ret; | 1009 | return ret; |
990 | } | 1010 | } |
991 | 1011 | ||
1012 | static const struct ctrl *get_ctrl(struct gspca_dev *gspca_dev, | ||
1013 | int id) | ||
1014 | { | ||
1015 | const struct ctrl *ctrls; | ||
1016 | int i; | ||
1017 | |||
1018 | for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; | ||
1019 | i < gspca_dev->sd_desc->nctrls; | ||
1020 | i++, ctrls++) { | ||
1021 | if (gspca_dev->ctrl_dis & (1 << i)) | ||
1022 | continue; | ||
1023 | if (id == ctrls->qctrl.id) | ||
1024 | return ctrls; | ||
1025 | } | ||
1026 | return NULL; | ||
1027 | } | ||
1028 | |||
992 | static int vidioc_queryctrl(struct file *file, void *priv, | 1029 | static int vidioc_queryctrl(struct file *file, void *priv, |
993 | struct v4l2_queryctrl *q_ctrl) | 1030 | struct v4l2_queryctrl *q_ctrl) |
994 | { | 1031 | { |
995 | struct gspca_dev *gspca_dev = priv; | 1032 | struct gspca_dev *gspca_dev = priv; |
996 | int i, ix; | 1033 | const struct ctrl *ctrls; |
1034 | int i; | ||
997 | u32 id; | 1035 | u32 id; |
998 | 1036 | ||
999 | ix = -1; | 1037 | ctrls = NULL; |
1000 | id = q_ctrl->id; | 1038 | id = q_ctrl->id; |
1001 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { | 1039 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { |
1002 | id &= V4L2_CTRL_ID_MASK; | 1040 | id &= V4L2_CTRL_ID_MASK; |
1003 | id++; | 1041 | id++; |
1004 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | 1042 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { |
1005 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id) | 1043 | if (gspca_dev->ctrl_dis & (1 << i)) |
1006 | continue; | 1044 | continue; |
1007 | if (ix < 0) { | 1045 | if (ctrls->qctrl.id < id) |
1008 | ix = i; | ||
1009 | continue; | 1046 | continue; |
1047 | if (ctrls != NULL) { | ||
1048 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id | ||
1049 | > ctrls->qctrl.id) | ||
1050 | continue; | ||
1010 | } | 1051 | } |
1011 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id | 1052 | ctrls = &gspca_dev->sd_desc->ctrls[i]; |
1012 | > gspca_dev->sd_desc->ctrls[ix].qctrl.id) | ||
1013 | continue; | ||
1014 | ix = i; | ||
1015 | } | ||
1016 | } | ||
1017 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | ||
1018 | if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { | ||
1019 | ix = i; | ||
1020 | break; | ||
1021 | } | 1053 | } |
1054 | } else { | ||
1055 | ctrls = get_ctrl(gspca_dev, id); | ||
1022 | } | 1056 | } |
1023 | if (ix < 0) | 1057 | if (ctrls == NULL) |
1024 | return -EINVAL; | 1058 | return -EINVAL; |
1025 | memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[ix].qctrl, | 1059 | memcpy(q_ctrl, ctrls, sizeof *q_ctrl); |
1026 | sizeof *q_ctrl); | ||
1027 | if (gspca_dev->ctrl_dis & (1 << ix)) | ||
1028 | q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
1029 | return 0; | 1060 | return 0; |
1030 | } | 1061 | } |
1031 | 1062 | ||
@@ -1034,56 +1065,45 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1034 | { | 1065 | { |
1035 | struct gspca_dev *gspca_dev = priv; | 1066 | struct gspca_dev *gspca_dev = priv; |
1036 | const struct ctrl *ctrls; | 1067 | const struct ctrl *ctrls; |
1037 | int i, ret; | 1068 | int ret; |
1038 | 1069 | ||
1039 | for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; | 1070 | ctrls = get_ctrl(gspca_dev, ctrl->id); |
1040 | i < gspca_dev->sd_desc->nctrls; | 1071 | if (ctrls == NULL) |
1041 | i++, ctrls++) { | 1072 | return -EINVAL; |
1042 | if (ctrl->id != ctrls->qctrl.id) | 1073 | |
1043 | continue; | 1074 | if (ctrl->value < ctrls->qctrl.minimum |
1044 | if (gspca_dev->ctrl_dis & (1 << i)) | 1075 | || ctrl->value > ctrls->qctrl.maximum) |
1045 | return -EINVAL; | 1076 | return -ERANGE; |
1046 | if (ctrl->value < ctrls->qctrl.minimum | 1077 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); |
1047 | || ctrl->value > ctrls->qctrl.maximum) | 1078 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1048 | return -ERANGE; | 1079 | return -ERESTARTSYS; |
1049 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); | 1080 | if (gspca_dev->present) |
1050 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1081 | ret = ctrls->set(gspca_dev, ctrl->value); |
1051 | return -ERESTARTSYS; | 1082 | else |
1052 | if (gspca_dev->present) | 1083 | ret = -ENODEV; |
1053 | ret = ctrls->set(gspca_dev, ctrl->value); | 1084 | mutex_unlock(&gspca_dev->usb_lock); |
1054 | else | 1085 | return ret; |
1055 | ret = -ENODEV; | ||
1056 | mutex_unlock(&gspca_dev->usb_lock); | ||
1057 | return ret; | ||
1058 | } | ||
1059 | return -EINVAL; | ||
1060 | } | 1086 | } |
1061 | 1087 | ||
1062 | static int vidioc_g_ctrl(struct file *file, void *priv, | 1088 | static int vidioc_g_ctrl(struct file *file, void *priv, |
1063 | struct v4l2_control *ctrl) | 1089 | struct v4l2_control *ctrl) |
1064 | { | 1090 | { |
1065 | struct gspca_dev *gspca_dev = priv; | 1091 | struct gspca_dev *gspca_dev = priv; |
1066 | |||
1067 | const struct ctrl *ctrls; | 1092 | const struct ctrl *ctrls; |
1068 | int i, ret; | 1093 | int ret; |
1069 | 1094 | ||
1070 | for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; | 1095 | ctrls = get_ctrl(gspca_dev, ctrl->id); |
1071 | i < gspca_dev->sd_desc->nctrls; | 1096 | if (ctrls == NULL) |
1072 | i++, ctrls++) { | 1097 | return -EINVAL; |
1073 | if (ctrl->id != ctrls->qctrl.id) | 1098 | |
1074 | continue; | 1099 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1075 | if (gspca_dev->ctrl_dis & (1 << i)) | 1100 | return -ERESTARTSYS; |
1076 | return -EINVAL; | 1101 | if (gspca_dev->present) |
1077 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1102 | ret = ctrls->get(gspca_dev, &ctrl->value); |
1078 | return -ERESTARTSYS; | 1103 | else |
1079 | if (gspca_dev->present) | 1104 | ret = -ENODEV; |
1080 | ret = ctrls->get(gspca_dev, &ctrl->value); | 1105 | mutex_unlock(&gspca_dev->usb_lock); |
1081 | else | 1106 | return ret; |
1082 | ret = -ENODEV; | ||
1083 | mutex_unlock(&gspca_dev->usb_lock); | ||
1084 | return ret; | ||
1085 | } | ||
1086 | return -EINVAL; | ||
1087 | } | 1107 | } |
1088 | 1108 | ||
1089 | /*fixme: have an audio flag in gspca_dev?*/ | 1109 | /*fixme: have an audio flag in gspca_dev?*/ |
@@ -1864,6 +1884,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { | |||
1864 | .vidioc_g_parm = vidioc_g_parm, | 1884 | .vidioc_g_parm = vidioc_g_parm, |
1865 | .vidioc_s_parm = vidioc_s_parm, | 1885 | .vidioc_s_parm = vidioc_s_parm, |
1866 | .vidioc_s_std = vidioc_s_std, | 1886 | .vidioc_s_std = vidioc_s_std, |
1887 | .vidioc_enum_framesizes = vidioc_enum_framesizes, | ||
1867 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1888 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1868 | .vidiocgmbuf = vidiocgmbuf, | 1889 | .vidiocgmbuf = vidiocgmbuf, |
1869 | #endif | 1890 | #endif |
@@ -1943,7 +1964,7 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
1943 | 1964 | ||
1944 | /* init video stuff */ | 1965 | /* init video stuff */ |
1945 | memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); | 1966 | memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); |
1946 | gspca_dev->vdev.parent = &dev->dev; | 1967 | gspca_dev->vdev.parent = &intf->dev; |
1947 | gspca_dev->module = module; | 1968 | gspca_dev->module = module; |
1948 | gspca_dev->present = 1; | 1969 | gspca_dev->present = 1; |
1949 | ret = video_register_device(&gspca_dev->vdev, | 1970 | ret = video_register_device(&gspca_dev->vdev, |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 58e8ff02136a..bd1faff88644 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -44,8 +44,6 @@ extern int gspca_debug; | |||
44 | #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ | 44 | #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ |
45 | /* image transfers */ | 45 | /* image transfers */ |
46 | #define MAX_NURBS 4 /* max number of URBs */ | 46 | #define MAX_NURBS 4 /* max number of URBs */ |
47 | #define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */ | ||
48 | #define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */ | ||
49 | 47 | ||
50 | /* device information - set at probe time */ | 48 | /* device information - set at probe time */ |
51 | struct cam { | 49 | struct cam { |
@@ -56,6 +54,9 @@ struct cam { | |||
56 | * - cannot be > MAX_NURBS | 54 | * - cannot be > MAX_NURBS |
57 | * - when 0 and bulk_size != 0 means | 55 | * - when 0 and bulk_size != 0 means |
58 | * 1 URB and submit done by subdriver */ | 56 | * 1 URB and submit done by subdriver */ |
57 | u8 bulk; /* image transfer by 0:isoc / 1:bulk */ | ||
58 | u8 npkt; /* number of packets in an ISOC message | ||
59 | * 0 is the default value: 32 packets */ | ||
59 | u32 input_flags; /* value for ENUM_INPUT status flags */ | 60 | u32 input_flags; /* value for ENUM_INPUT status flags */ |
60 | }; | 61 | }; |
61 | 62 | ||
@@ -168,7 +169,6 @@ struct gspca_dev { | |||
168 | __u8 iface; /* USB interface number */ | 169 | __u8 iface; /* USB interface number */ |
169 | __u8 alt; /* USB alternate setting */ | 170 | __u8 alt; /* USB alternate setting */ |
170 | __u8 nbalt; /* number of USB alternate settings */ | 171 | __u8 nbalt; /* number of USB alternate settings */ |
171 | u8 bulk; /* image transfer by 0:isoc / 1:bulk */ | ||
172 | }; | 172 | }; |
173 | 173 | ||
174 | int gspca_dev_probe(struct usb_interface *intf, | 174 | int gspca_dev_probe(struct usb_interface *intf, |
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile index 9fa3644f4869..bf7a19a1e6d1 100644 --- a/drivers/media/video/gspca/m5602/Makefile +++ b/drivers/media/video/gspca/m5602/Makefile | |||
@@ -2,9 +2,10 @@ obj-$(CONFIG_USB_M5602) += gspca_m5602.o | |||
2 | 2 | ||
3 | gspca_m5602-objs := m5602_core.o \ | 3 | gspca_m5602-objs := m5602_core.o \ |
4 | m5602_ov9650.o \ | 4 | m5602_ov9650.o \ |
5 | m5602_ov7660.o \ | ||
5 | m5602_mt9m111.o \ | 6 | m5602_mt9m111.o \ |
6 | m5602_po1030.o \ | 7 | m5602_po1030.o \ |
7 | m5602_s5k83a.o \ | 8 | m5602_s5k83a.o \ |
8 | m5602_s5k4aa.o | 9 | m5602_s5k4aa.o |
9 | 10 | ||
10 | EXTRA_CFLAGS += -Idrivers/media/video/gspca \ No newline at end of file | 11 | EXTRA_CFLAGS += -Idrivers/media/video/gspca |
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h index 8f1cea6fd3bf..1127a405c9b2 100644 --- a/drivers/media/video/gspca/m5602/m5602_bridge.h +++ b/drivers/media/video/gspca/m5602/m5602_bridge.h | |||
@@ -45,6 +45,15 @@ | |||
45 | #define M5602_XB_SEN_CLK_DIV 0x15 | 45 | #define M5602_XB_SEN_CLK_DIV 0x15 |
46 | #define M5602_XB_AUD_CLK_CTRL 0x16 | 46 | #define M5602_XB_AUD_CLK_CTRL 0x16 |
47 | #define M5602_XB_AUD_CLK_DIV 0x17 | 47 | #define M5602_XB_AUD_CLK_DIV 0x17 |
48 | #define M5602_OB_AC_LINK_STATE 0x22 | ||
49 | #define M5602_OB_PCM_SLOT_INDEX 0x24 | ||
50 | #define M5602_OB_GPIO_SLOT_INDEX 0x25 | ||
51 | #define M5602_OB_ACRX_STATUS_ADDRESS_H 0x28 | ||
52 | #define M5602_OB_ACRX_STATUS_DATA_L 0x29 | ||
53 | #define M5602_OB_ACRX_STATUS_DATA_H 0x2a | ||
54 | #define M5602_OB_ACTX_COMMAND_ADDRESS 0x31 | ||
55 | #define M5602_OB_ACRX_COMMAND_DATA_L 0x32 | ||
56 | #define M5602_OB_ACTX_COMMAND_DATA_H 0X33 | ||
48 | #define M5602_XB_DEVCTR1 0x41 | 57 | #define M5602_XB_DEVCTR1 0x41 |
49 | #define M5602_XB_EPSETR0 0x42 | 58 | #define M5602_XB_EPSETR0 0x42 |
50 | #define M5602_XB_EPAFCTR 0x47 | 59 | #define M5602_XB_EPAFCTR 0x47 |
@@ -77,7 +86,18 @@ | |||
77 | #define M5602_XB_GPIO_EN_L 0x75 | 86 | #define M5602_XB_GPIO_EN_L 0x75 |
78 | #define M5602_XB_GPIO_DAT 0x76 | 87 | #define M5602_XB_GPIO_DAT 0x76 |
79 | #define M5602_XB_GPIO_DIR 0x77 | 88 | #define M5602_XB_GPIO_DIR 0x77 |
80 | #define M5602_XB_MISC_CTL 0x70 | 89 | #define M5602_XB_SEN_CLK_CONTROL 0x80 |
90 | #define M5602_XB_SEN_CLK_DIVISION 0x81 | ||
91 | #define M5602_XB_CPR_CLK_CONTROL 0x82 | ||
92 | #define M5602_XB_CPR_CLK_DIVISION 0x83 | ||
93 | #define M5602_XB_MCU_CLK_CONTROL 0x84 | ||
94 | #define M5602_XB_MCU_CLK_DIVISION 0x85 | ||
95 | #define M5602_XB_DCT_CLK_CONTROL 0x86 | ||
96 | #define M5602_XB_DCT_CLK_DIVISION 0x87 | ||
97 | #define M5602_XB_EC_CLK_CONTROL 0x88 | ||
98 | #define M5602_XB_EC_CLK_DIVISION 0x89 | ||
99 | #define M5602_XB_LBUF_CLK_CONTROL 0x8a | ||
100 | #define M5602_XB_LBUF_CLK_DIVISION 0x8b | ||
81 | 101 | ||
82 | #define I2C_BUSY 0x80 | 102 | #define I2C_BUSY 0x80 |
83 | 103 | ||
@@ -128,10 +148,10 @@ struct sd { | |||
128 | }; | 148 | }; |
129 | 149 | ||
130 | int m5602_read_bridge( | 150 | int m5602_read_bridge( |
131 | struct sd *sd, u8 address, u8 *i2c_data); | 151 | struct sd *sd, const u8 address, u8 *i2c_data); |
132 | 152 | ||
133 | int m5602_write_bridge( | 153 | int m5602_write_bridge( |
134 | struct sd *sd, u8 address, u8 i2c_data); | 154 | struct sd *sd, const u8 address, const u8 i2c_data); |
135 | 155 | ||
136 | int m5602_write_sensor(struct sd *sd, const u8 address, | 156 | int m5602_write_sensor(struct sd *sd, const u8 address, |
137 | u8 *i2c_data, const u8 len); | 157 | u8 *i2c_data, const u8 len); |
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index 1aac2985fee6..8a5bba16ff32 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/drivers/media/video/gspca/m5602/m5602_core.c | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include "m5602_ov9650.h" | 19 | #include "m5602_ov9650.h" |
20 | #include "m5602_ov7660.h" | ||
20 | #include "m5602_mt9m111.h" | 21 | #include "m5602_mt9m111.h" |
21 | #include "m5602_po1030.h" | 22 | #include "m5602_po1030.h" |
22 | #include "m5602_s5k83a.h" | 23 | #include "m5602_s5k83a.h" |
@@ -35,7 +36,7 @@ static const __devinitdata struct usb_device_id m5602_table[] = { | |||
35 | MODULE_DEVICE_TABLE(usb, m5602_table); | 36 | MODULE_DEVICE_TABLE(usb, m5602_table); |
36 | 37 | ||
37 | /* Reads a byte from the m5602 */ | 38 | /* Reads a byte from the m5602 */ |
38 | int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) | 39 | int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data) |
39 | { | 40 | { |
40 | int err; | 41 | int err; |
41 | struct usb_device *udev = sd->gspca_dev.dev; | 42 | struct usb_device *udev = sd->gspca_dev.dev; |
@@ -56,7 +57,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) | |||
56 | } | 57 | } |
57 | 58 | ||
58 | /* Writes a byte to to the m5602 */ | 59 | /* Writes a byte to to the m5602 */ |
59 | int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) | 60 | int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data) |
60 | { | 61 | { |
61 | int err; | 62 | int err; |
62 | struct usb_device *udev = sd->gspca_dev.dev; | 63 | struct usb_device *udev = sd->gspca_dev.dev; |
@@ -80,6 +81,17 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) | |||
80 | return (err < 0) ? err : 0; | 81 | return (err < 0) ? err : 0; |
81 | } | 82 | } |
82 | 83 | ||
84 | int m5602_wait_for_i2c(struct sd *sd) | ||
85 | { | ||
86 | int err; | ||
87 | u8 data; | ||
88 | |||
89 | do { | ||
90 | err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, &data); | ||
91 | } while ((data & I2C_BUSY) && !err); | ||
92 | return err; | ||
93 | } | ||
94 | |||
83 | int m5602_read_sensor(struct sd *sd, const u8 address, | 95 | int m5602_read_sensor(struct sd *sd, const u8 address, |
84 | u8 *i2c_data, const u8 len) | 96 | u8 *i2c_data, const u8 len) |
85 | { | 97 | { |
@@ -88,9 +100,7 @@ int m5602_read_sensor(struct sd *sd, const u8 address, | |||
88 | if (!len || len > sd->sensor->i2c_regW) | 100 | if (!len || len > sd->sensor->i2c_regW) |
89 | return -EINVAL; | 101 | return -EINVAL; |
90 | 102 | ||
91 | do { | 103 | err = m5602_wait_for_i2c(sd); |
92 | err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); | ||
93 | } while ((*i2c_data & I2C_BUSY) && !err); | ||
94 | if (err < 0) | 104 | if (err < 0) |
95 | return err; | 105 | return err; |
96 | 106 | ||
@@ -103,21 +113,25 @@ int m5602_read_sensor(struct sd *sd, const u8 address, | |||
103 | if (err < 0) | 113 | if (err < 0) |
104 | return err; | 114 | return err; |
105 | 115 | ||
116 | /* Sensors with registers that are of only | ||
117 | one byte width are differently read */ | ||
118 | |||
119 | /* FIXME: This works with the ov9650, but has issues with the po1030 */ | ||
106 | if (sd->sensor->i2c_regW == 1) { | 120 | if (sd->sensor->i2c_regW == 1) { |
107 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len); | 121 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1); |
108 | if (err < 0) | 122 | if (err < 0) |
109 | return err; | 123 | return err; |
110 | 124 | ||
111 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); | 125 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); |
112 | if (err < 0) | ||
113 | return err; | ||
114 | } else { | 126 | } else { |
115 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); | 127 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); |
116 | if (err < 0) | ||
117 | return err; | ||
118 | } | 128 | } |
119 | 129 | ||
120 | for (i = 0; (i < len) && !err; i++) { | 130 | for (i = 0; (i < len) && !err; i++) { |
131 | err = m5602_wait_for_i2c(sd); | ||
132 | if (err < 0) | ||
133 | return err; | ||
134 | |||
121 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); | 135 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); |
122 | 136 | ||
123 | PDEBUG(D_CONF, "Reading sensor register " | 137 | PDEBUG(D_CONF, "Reading sensor register " |
@@ -206,6 +220,11 @@ static int m5602_probe_sensor(struct sd *sd) | |||
206 | if (!sd->sensor->probe(sd)) | 220 | if (!sd->sensor->probe(sd)) |
207 | return 0; | 221 | return 0; |
208 | 222 | ||
223 | /* Try the ov7660 */ | ||
224 | sd->sensor = &ov7660; | ||
225 | if (!sd->sensor->probe(sd)) | ||
226 | return 0; | ||
227 | |||
209 | /* Try the s5k83a */ | 228 | /* Try the s5k83a */ |
210 | sd->sensor = &s5k83a; | 229 | sd->sensor = &s5k83a; |
211 | if (!sd->sensor->probe(sd)) | 230 | if (!sd->sensor->probe(sd)) |
@@ -409,8 +428,9 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
409 | MODULE_LICENSE("GPL"); | 428 | MODULE_LICENSE("GPL"); |
410 | module_param(force_sensor, int, S_IRUGO | S_IWUSR); | 429 | module_param(force_sensor, int, S_IRUGO | S_IWUSR); |
411 | MODULE_PARM_DESC(force_sensor, | 430 | MODULE_PARM_DESC(force_sensor, |
412 | "force detection of sensor, " | 431 | "forces detection of a sensor, " |
413 | "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, 4 = MT9M111, 5 = PO1030"); | 432 | "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, " |
433 | "4 = MT9M111, 5 = PO1030, 6 = OV7660"); | ||
414 | 434 | ||
415 | module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); | 435 | module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); |
416 | MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); | 436 | MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); |
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 7d3f9e348ef4..8d071dff6944 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c | |||
@@ -18,6 +18,23 @@ | |||
18 | 18 | ||
19 | #include "m5602_mt9m111.h" | 19 | #include "m5602_mt9m111.h" |
20 | 20 | ||
21 | static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
22 | static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
23 | static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, | ||
28 | __s32 val); | ||
29 | static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, | ||
30 | __s32 *val); | ||
31 | static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
34 | static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
35 | static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
36 | static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
37 | |||
21 | static struct v4l2_pix_format mt9m111_modes[] = { | 38 | static struct v4l2_pix_format mt9m111_modes[] = { |
22 | { | 39 | { |
23 | 640, | 40 | 640, |
@@ -32,6 +49,7 @@ static struct v4l2_pix_format mt9m111_modes[] = { | |||
32 | }; | 49 | }; |
33 | 50 | ||
34 | const static struct ctrl mt9m111_ctrls[] = { | 51 | const static struct ctrl mt9m111_ctrls[] = { |
52 | #define VFLIP_IDX 0 | ||
35 | { | 53 | { |
36 | { | 54 | { |
37 | .id = V4L2_CID_VFLIP, | 55 | .id = V4L2_CID_VFLIP, |
@@ -44,7 +62,9 @@ const static struct ctrl mt9m111_ctrls[] = { | |||
44 | }, | 62 | }, |
45 | .set = mt9m111_set_vflip, | 63 | .set = mt9m111_set_vflip, |
46 | .get = mt9m111_get_vflip | 64 | .get = mt9m111_get_vflip |
47 | }, { | 65 | }, |
66 | #define HFLIP_IDX 1 | ||
67 | { | ||
48 | { | 68 | { |
49 | .id = V4L2_CID_HFLIP, | 69 | .id = V4L2_CID_HFLIP, |
50 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 70 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -56,7 +76,9 @@ const static struct ctrl mt9m111_ctrls[] = { | |||
56 | }, | 76 | }, |
57 | .set = mt9m111_set_hflip, | 77 | .set = mt9m111_set_hflip, |
58 | .get = mt9m111_get_hflip | 78 | .get = mt9m111_get_hflip |
59 | }, { | 79 | }, |
80 | #define GAIN_IDX 2 | ||
81 | { | ||
60 | { | 82 | { |
61 | .id = V4L2_CID_GAIN, | 83 | .id = V4L2_CID_GAIN, |
62 | .type = V4L2_CTRL_TYPE_INTEGER, | 84 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -64,21 +86,80 @@ const static struct ctrl mt9m111_ctrls[] = { | |||
64 | .minimum = 0, | 86 | .minimum = 0, |
65 | .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, | 87 | .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, |
66 | .step = 1, | 88 | .step = 1, |
67 | .default_value = DEFAULT_GAIN, | 89 | .default_value = MT9M111_DEFAULT_GAIN, |
68 | .flags = V4L2_CTRL_FLAG_SLIDER | 90 | .flags = V4L2_CTRL_FLAG_SLIDER |
69 | }, | 91 | }, |
70 | .set = mt9m111_set_gain, | 92 | .set = mt9m111_set_gain, |
71 | .get = mt9m111_get_gain | 93 | .get = mt9m111_get_gain |
72 | } | 94 | }, |
95 | #define AUTO_WHITE_BALANCE_IDX 3 | ||
96 | { | ||
97 | { | ||
98 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
99 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
100 | .name = "auto white balance", | ||
101 | .minimum = 0, | ||
102 | .maximum = 1, | ||
103 | .step = 1, | ||
104 | .default_value = 0, | ||
105 | }, | ||
106 | .set = mt9m111_set_auto_white_balance, | ||
107 | .get = mt9m111_get_auto_white_balance | ||
108 | }, | ||
109 | #define GREEN_BALANCE_IDX 4 | ||
110 | { | ||
111 | { | ||
112 | .id = M5602_V4L2_CID_GREEN_BALANCE, | ||
113 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
114 | .name = "green balance", | ||
115 | .minimum = 0x00, | ||
116 | .maximum = 0x7ff, | ||
117 | .step = 0x1, | ||
118 | .default_value = MT9M111_GREEN_GAIN_DEFAULT, | ||
119 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
120 | }, | ||
121 | .set = mt9m111_set_green_balance, | ||
122 | .get = mt9m111_get_green_balance | ||
123 | }, | ||
124 | #define BLUE_BALANCE_IDX 5 | ||
125 | { | ||
126 | { | ||
127 | .id = V4L2_CID_BLUE_BALANCE, | ||
128 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
129 | .name = "blue balance", | ||
130 | .minimum = 0x00, | ||
131 | .maximum = 0x7ff, | ||
132 | .step = 0x1, | ||
133 | .default_value = MT9M111_BLUE_GAIN_DEFAULT, | ||
134 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
135 | }, | ||
136 | .set = mt9m111_set_blue_balance, | ||
137 | .get = mt9m111_get_blue_balance | ||
138 | }, | ||
139 | #define RED_BALANCE_IDX 5 | ||
140 | { | ||
141 | { | ||
142 | .id = V4L2_CID_RED_BALANCE, | ||
143 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
144 | .name = "red balance", | ||
145 | .minimum = 0x00, | ||
146 | .maximum = 0x7ff, | ||
147 | .step = 0x1, | ||
148 | .default_value = MT9M111_RED_GAIN_DEFAULT, | ||
149 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
150 | }, | ||
151 | .set = mt9m111_set_red_balance, | ||
152 | .get = mt9m111_get_red_balance | ||
153 | }, | ||
73 | }; | 154 | }; |
74 | 155 | ||
75 | |||
76 | static void mt9m111_dump_registers(struct sd *sd); | 156 | static void mt9m111_dump_registers(struct sd *sd); |
77 | 157 | ||
78 | int mt9m111_probe(struct sd *sd) | 158 | int mt9m111_probe(struct sd *sd) |
79 | { | 159 | { |
80 | u8 data[2] = {0x00, 0x00}; | 160 | u8 data[2] = {0x00, 0x00}; |
81 | int i; | 161 | int i; |
162 | s32 *sensor_settings; | ||
82 | 163 | ||
83 | if (force_sensor) { | 164 | if (force_sensor) { |
84 | if (force_sensor == MT9M111_SENSOR) { | 165 | if (force_sensor == MT9M111_SENSOR) { |
@@ -117,16 +198,27 @@ int mt9m111_probe(struct sd *sd) | |||
117 | return -ENODEV; | 198 | return -ENODEV; |
118 | 199 | ||
119 | sensor_found: | 200 | sensor_found: |
201 | sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32), | ||
202 | GFP_KERNEL); | ||
203 | if (!sensor_settings) | ||
204 | return -ENOMEM; | ||
205 | |||
120 | sd->gspca_dev.cam.cam_mode = mt9m111_modes; | 206 | sd->gspca_dev.cam.cam_mode = mt9m111_modes; |
121 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); | 207 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); |
122 | sd->desc->ctrls = mt9m111_ctrls; | 208 | sd->desc->ctrls = mt9m111_ctrls; |
123 | sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); | 209 | sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); |
210 | |||
211 | for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++) | ||
212 | sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value; | ||
213 | sd->sensor_priv = sensor_settings; | ||
214 | |||
124 | return 0; | 215 | return 0; |
125 | } | 216 | } |
126 | 217 | ||
127 | int mt9m111_init(struct sd *sd) | 218 | int mt9m111_init(struct sd *sd) |
128 | { | 219 | { |
129 | int i, err = 0; | 220 | int i, err = 0; |
221 | s32 *sensor_settings = sd->sensor_priv; | ||
130 | 222 | ||
131 | /* Init the sensor */ | 223 | /* Init the sensor */ |
132 | for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { | 224 | for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { |
@@ -147,36 +239,154 @@ int mt9m111_init(struct sd *sd) | |||
147 | if (dump_sensor) | 239 | if (dump_sensor) |
148 | mt9m111_dump_registers(sd); | 240 | mt9m111_dump_registers(sd); |
149 | 241 | ||
150 | return (err < 0) ? err : 0; | 242 | err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); |
243 | if (err < 0) | ||
244 | return err; | ||
245 | |||
246 | err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
247 | if (err < 0) | ||
248 | return err; | ||
249 | |||
250 | err = mt9m111_set_green_balance(&sd->gspca_dev, | ||
251 | sensor_settings[GREEN_BALANCE_IDX]); | ||
252 | if (err < 0) | ||
253 | return err; | ||
254 | |||
255 | err = mt9m111_set_blue_balance(&sd->gspca_dev, | ||
256 | sensor_settings[BLUE_BALANCE_IDX]); | ||
257 | if (err < 0) | ||
258 | return err; | ||
259 | |||
260 | err = mt9m111_set_red_balance(&sd->gspca_dev, | ||
261 | sensor_settings[RED_BALANCE_IDX]); | ||
262 | if (err < 0) | ||
263 | return err; | ||
264 | |||
265 | return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
151 | } | 266 | } |
152 | 267 | ||
153 | int mt9m111_power_down(struct sd *sd) | 268 | int mt9m111_start(struct sd *sd) |
154 | { | 269 | { |
155 | return 0; | 270 | int i, err = 0; |
271 | u8 data[2]; | ||
272 | struct cam *cam = &sd->gspca_dev.cam; | ||
273 | s32 *sensor_settings = sd->sensor_priv; | ||
274 | |||
275 | int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1; | ||
276 | int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; | ||
277 | |||
278 | for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) { | ||
279 | if (start_mt9m111[i][0] == BRIDGE) { | ||
280 | err = m5602_write_bridge(sd, | ||
281 | start_mt9m111[i][1], | ||
282 | start_mt9m111[i][2]); | ||
283 | } else { | ||
284 | data[0] = start_mt9m111[i][2]; | ||
285 | data[1] = start_mt9m111[i][3]; | ||
286 | err = m5602_write_sensor(sd, | ||
287 | start_mt9m111[i][1], data, 2); | ||
288 | } | ||
289 | } | ||
290 | if (err < 0) | ||
291 | return err; | ||
292 | |||
293 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); | ||
294 | if (err < 0) | ||
295 | return err; | ||
296 | |||
297 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); | ||
298 | if (err < 0) | ||
299 | return err; | ||
300 | |||
301 | for (i = 0; i < 2 && !err; i++) | ||
302 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); | ||
303 | if (err < 0) | ||
304 | return err; | ||
305 | |||
306 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
307 | if (err < 0) | ||
308 | return err; | ||
309 | |||
310 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); | ||
311 | if (err < 0) | ||
312 | return err; | ||
313 | |||
314 | for (i = 0; i < 2 && !err; i++) | ||
315 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0); | ||
316 | if (err < 0) | ||
317 | return err; | ||
318 | |||
319 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, | ||
320 | (width >> 8) & 0xff); | ||
321 | if (err < 0) | ||
322 | return err; | ||
323 | |||
324 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff); | ||
325 | if (err < 0) | ||
326 | return err; | ||
327 | |||
328 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
329 | if (err < 0) | ||
330 | return err; | ||
331 | |||
332 | switch (width) { | ||
333 | case 640: | ||
334 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); | ||
335 | data[0] = MT9M111_RMB_OVER_SIZED; | ||
336 | data[1] = MT9M111_RMB_ROW_SKIP_2X | | ||
337 | MT9M111_RMB_COLUMN_SKIP_2X | | ||
338 | (sensor_settings[VFLIP_IDX] << 0) | | ||
339 | (sensor_settings[HFLIP_IDX] << 1); | ||
340 | |||
341 | err = m5602_write_sensor(sd, | ||
342 | MT9M111_SC_R_MODE_CONTEXT_B, data, 2); | ||
343 | break; | ||
344 | |||
345 | case 320: | ||
346 | PDEBUG(D_V4L2, "Configuring camera for QVGA mode"); | ||
347 | data[0] = MT9M111_RMB_OVER_SIZED; | ||
348 | data[1] = MT9M111_RMB_ROW_SKIP_4X | | ||
349 | MT9M111_RMB_COLUMN_SKIP_4X | | ||
350 | (sensor_settings[VFLIP_IDX] << 0) | | ||
351 | (sensor_settings[HFLIP_IDX] << 1); | ||
352 | err = m5602_write_sensor(sd, | ||
353 | MT9M111_SC_R_MODE_CONTEXT_B, data, 2); | ||
354 | break; | ||
355 | } | ||
356 | return err; | ||
156 | } | 357 | } |
157 | 358 | ||
158 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 359 | void mt9m111_disconnect(struct sd *sd) |
360 | { | ||
361 | sd->sensor = NULL; | ||
362 | kfree(sd->sensor_priv); | ||
363 | } | ||
364 | |||
365 | static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
159 | { | 366 | { |
160 | int err; | ||
161 | u8 data[2] = {0x00, 0x00}; | ||
162 | struct sd *sd = (struct sd *) gspca_dev; | 367 | struct sd *sd = (struct sd *) gspca_dev; |
368 | s32 *sensor_settings = sd->sensor_priv; | ||
163 | 369 | ||
164 | err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 370 | *val = sensor_settings[VFLIP_IDX]; |
165 | data, 2); | ||
166 | *val = data[0] & MT9M111_RMB_MIRROR_ROWS; | ||
167 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | 371 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
168 | 372 | ||
169 | return err; | 373 | return 0; |
170 | } | 374 | } |
171 | 375 | ||
172 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 376 | static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
173 | { | 377 | { |
174 | int err; | 378 | int err; |
175 | u8 data[2] = {0x00, 0x00}; | 379 | u8 data[2] = {0x00, 0x00}; |
176 | struct sd *sd = (struct sd *) gspca_dev; | 380 | struct sd *sd = (struct sd *) gspca_dev; |
381 | s32 *sensor_settings = sd->sensor_priv; | ||
177 | 382 | ||
178 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 383 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
179 | 384 | ||
385 | sensor_settings[VFLIP_IDX] = val; | ||
386 | |||
387 | /* The mt9m111 is flipped by default */ | ||
388 | val = !val; | ||
389 | |||
180 | /* Set the correct page map */ | 390 | /* Set the correct page map */ |
181 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 391 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
182 | if (err < 0) | 392 | if (err < 0) |
@@ -186,34 +396,37 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
186 | if (err < 0) | 396 | if (err < 0) |
187 | return err; | 397 | return err; |
188 | 398 | ||
189 | data[0] = (data[0] & 0xfe) | val; | 399 | data[1] = (data[1] & 0xfe) | val; |
190 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 400 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, |
191 | data, 2); | 401 | data, 2); |
192 | return err; | 402 | return err; |
193 | } | 403 | } |
194 | 404 | ||
195 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 405 | static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
196 | { | 406 | { |
197 | int err; | ||
198 | u8 data[2] = {0x00, 0x00}; | ||
199 | struct sd *sd = (struct sd *) gspca_dev; | 407 | struct sd *sd = (struct sd *) gspca_dev; |
408 | s32 *sensor_settings = sd->sensor_priv; | ||
200 | 409 | ||
201 | err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 410 | *val = sensor_settings[HFLIP_IDX]; |
202 | data, 2); | ||
203 | *val = data[0] & MT9M111_RMB_MIRROR_COLS; | ||
204 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | 411 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
205 | 412 | ||
206 | return err; | 413 | return 0; |
207 | } | 414 | } |
208 | 415 | ||
209 | int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 416 | static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
210 | { | 417 | { |
211 | int err; | 418 | int err; |
212 | u8 data[2] = {0x00, 0x00}; | 419 | u8 data[2] = {0x00, 0x00}; |
213 | struct sd *sd = (struct sd *) gspca_dev; | 420 | struct sd *sd = (struct sd *) gspca_dev; |
421 | s32 *sensor_settings = sd->sensor_priv; | ||
214 | 422 | ||
215 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | 423 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); |
216 | 424 | ||
425 | sensor_settings[HFLIP_IDX] = val; | ||
426 | |||
427 | /* The mt9m111 is flipped by default */ | ||
428 | val = !val; | ||
429 | |||
217 | /* Set the correct page map */ | 430 | /* Set the correct page map */ |
218 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 431 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
219 | if (err < 0) | 432 | if (err < 0) |
@@ -223,36 +436,62 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
223 | if (err < 0) | 436 | if (err < 0) |
224 | return err; | 437 | return err; |
225 | 438 | ||
226 | data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02); | 439 | data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02); |
227 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 440 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, |
228 | data, 2); | 441 | data, 2); |
229 | return err; | 442 | return err; |
230 | } | 443 | } |
231 | 444 | ||
232 | int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 445 | static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
233 | { | 446 | { |
234 | int err, tmp; | ||
235 | u8 data[2] = {0x00, 0x00}; | ||
236 | struct sd *sd = (struct sd *) gspca_dev; | 447 | struct sd *sd = (struct sd *) gspca_dev; |
448 | s32 *sensor_settings = sd->sensor_priv; | ||
237 | 449 | ||
238 | err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); | 450 | *val = sensor_settings[GAIN_IDX]; |
239 | tmp = ((data[1] << 8) | data[0]); | 451 | PDEBUG(D_V4L2, "Read gain %d", *val); |
240 | 452 | ||
241 | *val = ((tmp & (1 << 10)) * 2) | | 453 | return 0; |
242 | ((tmp & (1 << 9)) * 2) | | 454 | } |
243 | ((tmp & (1 << 8)) * 2) | | ||
244 | (tmp & 0x7f); | ||
245 | 455 | ||
246 | PDEBUG(D_V4L2, "Read gain %d", *val); | 456 | static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, |
457 | __s32 val) | ||
458 | { | ||
459 | struct sd *sd = (struct sd *) gspca_dev; | ||
460 | s32 *sensor_settings = sd->sensor_priv; | ||
461 | int err; | ||
462 | u8 data[2]; | ||
463 | |||
464 | err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); | ||
465 | if (err < 0) | ||
466 | return err; | ||
467 | |||
468 | sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01; | ||
469 | data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1)); | ||
247 | 470 | ||
471 | err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); | ||
472 | |||
473 | PDEBUG(D_V4L2, "Set auto white balance %d", val); | ||
248 | return err; | 474 | return err; |
249 | } | 475 | } |
250 | 476 | ||
251 | int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 477 | static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, |
478 | __s32 *val) { | ||
479 | struct sd *sd = (struct sd *) gspca_dev; | ||
480 | s32 *sensor_settings = sd->sensor_priv; | ||
481 | |||
482 | *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; | ||
483 | PDEBUG(D_V4L2, "Read auto white balance %d", *val); | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
252 | { | 488 | { |
253 | int err, tmp; | 489 | int err, tmp; |
254 | u8 data[2] = {0x00, 0x00}; | 490 | u8 data[2] = {0x00, 0x00}; |
255 | struct sd *sd = (struct sd *) gspca_dev; | 491 | struct sd *sd = (struct sd *) gspca_dev; |
492 | s32 *sensor_settings = sd->sensor_priv; | ||
493 | |||
494 | sensor_settings[GAIN_IDX] = val; | ||
256 | 495 | ||
257 | /* Set the correct page map */ | 496 | /* Set the correct page map */ |
258 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 497 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
@@ -275,8 +514,8 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
275 | else | 514 | else |
276 | tmp = val; | 515 | tmp = val; |
277 | 516 | ||
278 | data[1] = (tmp & 0xff00) >> 8; | 517 | data[1] = (tmp & 0xff); |
279 | data[0] = (tmp & 0xff); | 518 | data[0] = (tmp & 0xff00) >> 8; |
280 | PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, | 519 | PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, |
281 | data[1], data[0]); | 520 | data[1], data[0]); |
282 | 521 | ||
@@ -286,6 +525,89 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
286 | return err; | 525 | return err; |
287 | } | 526 | } |
288 | 527 | ||
528 | static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
529 | { | ||
530 | int err; | ||
531 | u8 data[2]; | ||
532 | struct sd *sd = (struct sd *) gspca_dev; | ||
533 | s32 *sensor_settings = sd->sensor_priv; | ||
534 | |||
535 | sensor_settings[GREEN_BALANCE_IDX] = val; | ||
536 | data[1] = (val & 0xff); | ||
537 | data[0] = (val & 0xff00) >> 8; | ||
538 | |||
539 | PDEBUG(D_V4L2, "Set green balance %d", val); | ||
540 | err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN, | ||
541 | data, 2); | ||
542 | if (err < 0) | ||
543 | return err; | ||
544 | |||
545 | return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN, | ||
546 | data, 2); | ||
547 | } | ||
548 | |||
549 | static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
550 | { | ||
551 | struct sd *sd = (struct sd *) gspca_dev; | ||
552 | s32 *sensor_settings = sd->sensor_priv; | ||
553 | |||
554 | *val = sensor_settings[GREEN_BALANCE_IDX]; | ||
555 | PDEBUG(D_V4L2, "Read green balance %d", *val); | ||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
560 | { | ||
561 | u8 data[2]; | ||
562 | struct sd *sd = (struct sd *) gspca_dev; | ||
563 | s32 *sensor_settings = sd->sensor_priv; | ||
564 | |||
565 | sensor_settings[BLUE_BALANCE_IDX] = val; | ||
566 | data[1] = (val & 0xff); | ||
567 | data[0] = (val & 0xff00) >> 8; | ||
568 | |||
569 | PDEBUG(D_V4L2, "Set blue balance %d", val); | ||
570 | |||
571 | return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN, | ||
572 | data, 2); | ||
573 | } | ||
574 | |||
575 | static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
576 | { | ||
577 | struct sd *sd = (struct sd *) gspca_dev; | ||
578 | s32 *sensor_settings = sd->sensor_priv; | ||
579 | |||
580 | *val = sensor_settings[BLUE_BALANCE_IDX]; | ||
581 | PDEBUG(D_V4L2, "Read blue balance %d", *val); | ||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
586 | { | ||
587 | u8 data[2]; | ||
588 | struct sd *sd = (struct sd *) gspca_dev; | ||
589 | s32 *sensor_settings = sd->sensor_priv; | ||
590 | |||
591 | sensor_settings[RED_BALANCE_IDX] = val; | ||
592 | data[1] = (val & 0xff); | ||
593 | data[0] = (val & 0xff00) >> 8; | ||
594 | |||
595 | PDEBUG(D_V4L2, "Set red balance %d", val); | ||
596 | |||
597 | return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN, | ||
598 | data, 2); | ||
599 | } | ||
600 | |||
601 | static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
602 | { | ||
603 | struct sd *sd = (struct sd *) gspca_dev; | ||
604 | s32 *sensor_settings = sd->sensor_priv; | ||
605 | |||
606 | *val = sensor_settings[RED_BALANCE_IDX]; | ||
607 | PDEBUG(D_V4L2, "Read red balance %d", *val); | ||
608 | return 0; | ||
609 | } | ||
610 | |||
289 | static void mt9m111_dump_registers(struct sd *sd) | 611 | static void mt9m111_dump_registers(struct sd *sd) |
290 | { | 612 | { |
291 | u8 address, value[2] = {0x00, 0x00}; | 613 | u8 address, value[2] = {0x00, 0x00}; |
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h index 00c6db02bdb7..b3de77823091 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h | |||
@@ -37,7 +37,6 @@ | |||
37 | #define MT9M111_SC_VBLANK_CONTEXT_A 0x08 | 37 | #define MT9M111_SC_VBLANK_CONTEXT_A 0x08 |
38 | #define MT9M111_SC_SHUTTER_WIDTH 0x09 | 38 | #define MT9M111_SC_SHUTTER_WIDTH 0x09 |
39 | #define MT9M111_SC_ROW_SPEED 0x0a | 39 | #define MT9M111_SC_ROW_SPEED 0x0a |
40 | |||
41 | #define MT9M111_SC_EXTRA_DELAY 0x0b | 40 | #define MT9M111_SC_EXTRA_DELAY 0x0b |
42 | #define MT9M111_SC_SHUTTER_DELAY 0x0c | 41 | #define MT9M111_SC_SHUTTER_DELAY 0x0c |
43 | #define MT9M111_SC_RESET 0x0d | 42 | #define MT9M111_SC_RESET 0x0d |
@@ -50,9 +49,6 @@ | |||
50 | #define MT9M111_SC_GREEN_2_GAIN 0x2e | 49 | #define MT9M111_SC_GREEN_2_GAIN 0x2e |
51 | #define MT9M111_SC_GLOBAL_GAIN 0x2f | 50 | #define MT9M111_SC_GLOBAL_GAIN 0x2f |
52 | 51 | ||
53 | #define MT9M111_RMB_MIRROR_ROWS (1 << 0) | ||
54 | #define MT9M111_RMB_MIRROR_COLS (1 << 1) | ||
55 | |||
56 | #define MT9M111_CONTEXT_CONTROL 0xc8 | 52 | #define MT9M111_CONTEXT_CONTROL 0xc8 |
57 | #define MT9M111_PAGE_MAP 0xf0 | 53 | #define MT9M111_PAGE_MAP 0xf0 |
58 | #define MT9M111_BYTEWISE_ADDRESS 0xf1 | 54 | #define MT9M111_BYTEWISE_ADDRESS 0xf1 |
@@ -74,8 +70,37 @@ | |||
74 | #define MT9M111_COLORPIPE 0x01 | 70 | #define MT9M111_COLORPIPE 0x01 |
75 | #define MT9M111_CAMERA_CONTROL 0x02 | 71 | #define MT9M111_CAMERA_CONTROL 0x02 |
76 | 72 | ||
73 | #define MT9M111_RESET (1 << 0) | ||
74 | #define MT9M111_RESTART (1 << 1) | ||
75 | #define MT9M111_ANALOG_STANDBY (1 << 2) | ||
76 | #define MT9M111_CHIP_ENABLE (1 << 3) | ||
77 | #define MT9M111_CHIP_DISABLE (0 << 3) | ||
78 | #define MT9M111_OUTPUT_DISABLE (1 << 4) | ||
79 | #define MT9M111_SHOW_BAD_FRAMES (1 << 0) | ||
80 | #define MT9M111_RESTART_BAD_FRAMES (1 << 1) | ||
81 | #define MT9M111_SYNCHRONIZE_CHANGES (1 << 7) | ||
82 | |||
83 | #define MT9M111_RMB_OVER_SIZED (1 << 0) | ||
84 | #define MT9M111_RMB_MIRROR_ROWS (1 << 0) | ||
85 | #define MT9M111_RMB_MIRROR_COLS (1 << 1) | ||
86 | #define MT9M111_RMB_ROW_SKIP_2X (1 << 2) | ||
87 | #define MT9M111_RMB_COLUMN_SKIP_2X (1 << 3) | ||
88 | #define MT9M111_RMB_ROW_SKIP_4X (1 << 4) | ||
89 | #define MT9M111_RMB_COLUMN_SKIP_4X (1 << 5) | ||
90 | |||
91 | #define MT9M111_COLOR_MATRIX_BYPASS (1 << 4) | ||
92 | #define MT9M111_SEL_CONTEXT_B (1 << 3) | ||
93 | |||
94 | #define MT9M111_TRISTATE_PIN_IN_STANDBY (1 << 1) | ||
95 | #define MT9M111_SOC_SOFT_STANDBY (1 << 0) | ||
96 | |||
97 | #define MT9M111_2D_DEFECT_CORRECTION_ENABLE (1 << 0) | ||
98 | |||
77 | #define INITIAL_MAX_GAIN 64 | 99 | #define INITIAL_MAX_GAIN 64 |
78 | #define DEFAULT_GAIN 283 | 100 | #define MT9M111_DEFAULT_GAIN 283 |
101 | #define MT9M111_GREEN_GAIN_DEFAULT 0x20 | ||
102 | #define MT9M111_BLUE_GAIN_DEFAULT 0x20 | ||
103 | #define MT9M111_RED_GAIN_DEFAULT 0x20 | ||
79 | 104 | ||
80 | /*****************************************************************************/ | 105 | /*****************************************************************************/ |
81 | 106 | ||
@@ -85,16 +110,10 @@ extern int dump_sensor; | |||
85 | 110 | ||
86 | int mt9m111_probe(struct sd *sd); | 111 | int mt9m111_probe(struct sd *sd); |
87 | int mt9m111_init(struct sd *sd); | 112 | int mt9m111_init(struct sd *sd); |
88 | int mt9m111_power_down(struct sd *sd); | 113 | int mt9m111_start(struct sd *sd); |
114 | void mt9m111_disconnect(struct sd *sd); | ||
89 | 115 | ||
90 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | 116 | static const struct m5602_sensor mt9m111 = { |
91 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
92 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
93 | int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
94 | int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
95 | int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
96 | |||
97 | const static struct m5602_sensor mt9m111 = { | ||
98 | .name = "MT9M111", | 117 | .name = "MT9M111", |
99 | 118 | ||
100 | .i2c_slave_id = 0xba, | 119 | .i2c_slave_id = 0xba, |
@@ -102,7 +121,8 @@ const static struct m5602_sensor mt9m111 = { | |||
102 | 121 | ||
103 | .probe = mt9m111_probe, | 122 | .probe = mt9m111_probe, |
104 | .init = mt9m111_init, | 123 | .init = mt9m111_init, |
105 | .power_down = mt9m111_power_down | 124 | .disconnect = mt9m111_disconnect, |
125 | .start = mt9m111_start, | ||
106 | }; | 126 | }; |
107 | 127 | ||
108 | static const unsigned char preinit_mt9m111[][4] = | 128 | static const unsigned char preinit_mt9m111[][4] = |
@@ -117,7 +137,14 @@ static const unsigned char preinit_mt9m111[][4] = | |||
117 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | 137 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, |
118 | 138 | ||
119 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | 139 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, |
120 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7}, | 140 | {SENSOR, MT9M111_SC_RESET, |
141 | MT9M111_RESET | | ||
142 | MT9M111_RESTART | | ||
143 | MT9M111_ANALOG_STANDBY | | ||
144 | MT9M111_CHIP_DISABLE, | ||
145 | MT9M111_SHOW_BAD_FRAMES | | ||
146 | MT9M111_RESTART_BAD_FRAMES | | ||
147 | MT9M111_SYNCHRONIZE_CHANGES}, | ||
121 | 148 | ||
122 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | 149 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, |
123 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | 150 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, |
@@ -145,731 +172,42 @@ static const unsigned char init_mt9m111[][4] = | |||
145 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 172 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
146 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 173 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
147 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 174 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
148 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, | ||
149 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, | ||
150 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
151 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | 175 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, |
152 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
153 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
154 | |||
155 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
156 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, | ||
157 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, | ||
158 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xde}, | ||
159 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, | ||
160 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7}, | ||
161 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
162 | 176 | ||
163 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
164 | |||
165 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0xff, 0xff}, | ||
166 | |||
167 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
168 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
169 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
170 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
171 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
172 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
173 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
174 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
175 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
176 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
177 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
178 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
179 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
180 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
181 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
182 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
183 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
184 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
185 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | 177 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, |
186 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | 178 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, |
187 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
188 | |||
189 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
190 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
191 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
192 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
193 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
194 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
195 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
196 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
197 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
198 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
199 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
200 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
201 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
202 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
203 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
204 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
205 | |||
206 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
207 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
208 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
209 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
210 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
211 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
212 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
213 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
214 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
215 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
216 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
217 | {SENSOR, 0x33, 0x03, 0x49}, | ||
218 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
219 | |||
220 | {SENSOR, 0x33, 0x03, 0x49}, | ||
221 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
222 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
223 | {SENSOR, 0x40, 0x20, 0x20}, | ||
224 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
225 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
226 | {SENSOR, 0x71, 0xff, 0x00}, | ||
227 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
228 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
229 | {SENSOR, 0x74, 0x57, 0x32}, | ||
230 | {SENSOR, 0x75, 0x56, 0x34}, | ||
231 | {SENSOR, 0x76, 0x73, 0x35}, | ||
232 | {SENSOR, 0x77, 0x30, 0x12}, | ||
233 | {SENSOR, 0x78, 0x79, 0x02}, | ||
234 | {SENSOR, 0x79, 0x75, 0x06}, | ||
235 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
236 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
237 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
238 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
239 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
240 | {SENSOR, 0x80, 0x59, 0x04}, | ||
241 | {SENSOR, 0x81, 0x59, 0x04}, | ||
242 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
243 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
244 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
245 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
246 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
247 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
248 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
249 | {SENSOR, 0x60, 0x00, 0x80}, | ||
250 | {SENSOR, 0x61, 0x00, 0x00}, | ||
251 | {SENSOR, 0x62, 0x00, 0x00}, | ||
252 | {SENSOR, 0x63, 0x00, 0x00}, | ||
253 | {SENSOR, 0x64, 0x00, 0x00}, | ||
254 | |||
255 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
256 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, | ||
257 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, | ||
258 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, | ||
259 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, | ||
260 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
261 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, | ||
262 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
263 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, | ||
264 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, | ||
265 | {SENSOR, 0x30, 0x04, 0x00}, | ||
266 | |||
267 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
268 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
269 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
270 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
271 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
272 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
273 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
274 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
275 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
276 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
277 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
278 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
279 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
280 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
281 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
282 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
283 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
284 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
285 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
286 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
287 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
288 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
289 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
290 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, | ||
291 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
292 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, | ||
293 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, | ||
294 | |||
295 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
296 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
297 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
298 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
299 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
300 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
301 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
302 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
303 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
304 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
305 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
306 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
307 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
308 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
309 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
310 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
311 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
312 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
313 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
314 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
315 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
316 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
317 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
318 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
319 | |||
320 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
321 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
322 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
323 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
324 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
325 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
326 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
327 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
328 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
329 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
330 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | 179 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, |
331 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
332 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | 180 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, |
333 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
334 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
335 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | 181 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, |
336 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
337 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
338 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
339 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
340 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
341 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
342 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
343 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
344 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
345 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
346 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
347 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
348 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
349 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
350 | |||
351 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
352 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
353 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
354 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
355 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
356 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
357 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
358 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
359 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
360 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
361 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
362 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
363 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
364 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
365 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
366 | |||
367 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
368 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
369 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
370 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
371 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
372 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
373 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
374 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
375 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
376 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
377 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
378 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
379 | {SENSOR, 0x33, 0x03, 0x49}, | ||
380 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
381 | |||
382 | {SENSOR, 0x33, 0x03, 0x49}, | ||
383 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
384 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
385 | {SENSOR, 0x40, 0x20, 0x20}, | ||
386 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
387 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
388 | {SENSOR, 0x71, 0xff, 0x00}, | ||
389 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
390 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
391 | {SENSOR, 0x74, 0x57, 0x32}, | ||
392 | {SENSOR, 0x75, 0x56, 0x34}, | ||
393 | {SENSOR, 0x76, 0x73, 0x35}, | ||
394 | {SENSOR, 0x77, 0x30, 0x12}, | ||
395 | {SENSOR, 0x78, 0x79, 0x02}, | ||
396 | {SENSOR, 0x79, 0x75, 0x06}, | ||
397 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
398 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
399 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
400 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
401 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
402 | {SENSOR, 0x80, 0x59, 0x04}, | ||
403 | {SENSOR, 0x81, 0x59, 0x04}, | ||
404 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
405 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
406 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
407 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
408 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
409 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
410 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
411 | {SENSOR, 0x60, 0x00, 0x80}, | ||
412 | {SENSOR, 0x61, 0x00, 0x00}, | ||
413 | {SENSOR, 0x62, 0x00, 0x00}, | ||
414 | {SENSOR, 0x63, 0x00, 0x00}, | ||
415 | {SENSOR, 0x64, 0x00, 0x00}, | ||
416 | |||
417 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
418 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, | ||
419 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, | ||
420 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, | ||
421 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, | ||
422 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
423 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, | ||
424 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
425 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, | ||
426 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, | ||
427 | {SENSOR, 0x30, 0x04, 0x00}, | ||
428 | |||
429 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
430 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
431 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
432 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
433 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
434 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
435 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
436 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
437 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
438 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
439 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
440 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
441 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
442 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
443 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
444 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
445 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
446 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
447 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
448 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
449 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
450 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
451 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
452 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, | ||
453 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
454 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, | ||
455 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, | ||
456 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
457 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
458 | |||
459 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
460 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
461 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
462 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
463 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
464 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
465 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
466 | |||
467 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
468 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
469 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
470 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
471 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
472 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
473 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | 182 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, |
474 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
475 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
476 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | 183 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, |
477 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
478 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
479 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
480 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
481 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
482 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
483 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
484 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
485 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | 184 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, |
486 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | 185 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, |
487 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
488 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
489 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | 186 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, |
490 | 187 | ||
491 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
492 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
493 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
494 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | 188 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, |
495 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | 189 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, |
496 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | 190 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, |
497 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | 191 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, |
498 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | 192 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, |
193 | MT9M111_CP_OPERATING_MODE_CTL}, | ||
499 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | 194 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, |
500 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | 195 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, |
501 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | 196 | MT9M111_2D_DEFECT_CORRECTION_ENABLE}, |
197 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, | ||
198 | MT9M111_2D_DEFECT_CORRECTION_ENABLE}, | ||
502 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | 199 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, |
503 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | 200 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, |
504 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | 201 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, |
505 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | 202 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, |
506 | |||
507 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
508 | {SENSOR, 0xcd, 0x00, 0x0e}, | 203 | {SENSOR, 0xcd, 0x00, 0x0e}, |
509 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
510 | {SENSOR, 0xd0, 0x00, 0x40}, | 204 | {SENSOR, 0xd0, 0x00, 0x40}, |
511 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
512 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
513 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
514 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
515 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
516 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
517 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
518 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
519 | {SENSOR, 0x33, 0x03, 0x49}, | ||
520 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
521 | |||
522 | {SENSOR, 0x33, 0x03, 0x49}, | ||
523 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
524 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
525 | {SENSOR, 0x40, 0x20, 0x20}, | ||
526 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
527 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
528 | {SENSOR, 0x71, 0xff, 0x00}, | ||
529 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
530 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
531 | {SENSOR, 0x74, 0x57, 0x32}, | ||
532 | {SENSOR, 0x75, 0x56, 0x34}, | ||
533 | {SENSOR, 0x76, 0x73, 0x35}, | ||
534 | {SENSOR, 0x77, 0x30, 0x12}, | ||
535 | {SENSOR, 0x78, 0x79, 0x02}, | ||
536 | {SENSOR, 0x79, 0x75, 0x06}, | ||
537 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
538 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
539 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
540 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
541 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
542 | {SENSOR, 0x80, 0x59, 0x04}, | ||
543 | {SENSOR, 0x81, 0x59, 0x04}, | ||
544 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
545 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
546 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
547 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
548 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
549 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
550 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
551 | {SENSOR, 0x60, 0x00, 0x80}, | ||
552 | {SENSOR, 0x61, 0x00, 0x00}, | ||
553 | {SENSOR, 0x62, 0x00, 0x00}, | ||
554 | {SENSOR, 0x63, 0x00, 0x00}, | ||
555 | {SENSOR, 0x64, 0x00, 0x00}, | ||
556 | 205 | ||
557 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
558 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, | ||
559 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, | ||
560 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, | ||
561 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, | ||
562 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
563 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, | ||
564 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
565 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, | ||
566 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, | ||
567 | {SENSOR, 0x30, 0x04, 0x00}, | ||
568 | |||
569 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
570 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
571 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
572 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
573 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
574 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
575 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
576 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
577 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
578 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
579 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
580 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
581 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
582 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
583 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
584 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
585 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
586 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
587 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
588 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
589 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
590 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, | ||
591 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
592 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, | ||
593 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, | ||
594 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
595 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
596 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
597 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
598 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
599 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
600 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
601 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
602 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
603 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
604 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
605 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
606 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
607 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
608 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
609 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
610 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
611 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
612 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
613 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
614 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
615 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
616 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
617 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
618 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
619 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
620 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
621 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
622 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
623 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
624 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
625 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
626 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
627 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
628 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
629 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
630 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
631 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
632 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
633 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
634 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
635 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
636 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
637 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
638 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
639 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
640 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
641 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
642 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
643 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
644 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
645 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
646 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
647 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
648 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
649 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
650 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
651 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
652 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
653 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
654 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
655 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
656 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
657 | |||
658 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
659 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
660 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
661 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
662 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
663 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
664 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
665 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
666 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
667 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
668 | |||
669 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
670 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
671 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
672 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
673 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
674 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
675 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
676 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
677 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | 206 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, |
678 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | 207 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, |
679 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
680 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
681 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
682 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
683 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
684 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
685 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
686 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | 208 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, |
687 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
688 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
689 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
690 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
691 | {SENSOR, 0x33, 0x03, 0x49}, | ||
692 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
693 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
694 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
695 | |||
696 | {SENSOR, 0x33, 0x03, 0x49}, | ||
697 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
698 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
699 | {SENSOR, 0x40, 0x20, 0x20}, | ||
700 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
701 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
702 | {SENSOR, 0x71, 0xff, 0x00}, | ||
703 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
704 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
705 | {SENSOR, 0x74, 0x57, 0x32}, | ||
706 | {SENSOR, 0x75, 0x56, 0x34}, | ||
707 | {SENSOR, 0x76, 0x73, 0x35}, | ||
708 | {SENSOR, 0x77, 0x30, 0x12}, | ||
709 | {SENSOR, 0x78, 0x79, 0x02}, | ||
710 | {SENSOR, 0x79, 0x75, 0x06}, | ||
711 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
712 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
713 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
714 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
715 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
716 | {SENSOR, 0x80, 0x59, 0x04}, | ||
717 | {SENSOR, 0x81, 0x59, 0x04}, | ||
718 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
719 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
720 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
721 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
722 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
723 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
724 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
725 | {SENSOR, 0x60, 0x00, 0x80}, | ||
726 | {SENSOR, 0x61, 0x00, 0x00}, | ||
727 | {SENSOR, 0x62, 0x00, 0x00}, | ||
728 | {SENSOR, 0x63, 0x00, 0x00}, | ||
729 | {SENSOR, 0x64, 0x00, 0x00}, | ||
730 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
731 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, | ||
732 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, | ||
733 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, | ||
734 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, | ||
735 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
736 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, | ||
737 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
738 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, | ||
739 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, | ||
740 | {SENSOR, 0x30, 0x04, 0x00}, | ||
741 | |||
742 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
743 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
744 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
745 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
746 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
747 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
748 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
749 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
750 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
751 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
752 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
753 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
754 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe3, 0x00}, | ||
755 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
756 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
757 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
758 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
759 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
760 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
761 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
762 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, | ||
763 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
764 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
765 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
766 | |||
767 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
768 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, | ||
769 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xe6}, | ||
770 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
771 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
772 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
773 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
774 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
775 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
776 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
777 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
778 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
779 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
780 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
781 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
782 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
783 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
784 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
785 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
786 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
787 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
788 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
789 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
790 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
791 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
792 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
793 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
794 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
795 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
796 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
797 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
798 | 209 | ||
799 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
800 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
801 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
802 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
803 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
804 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
805 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
806 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
807 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
808 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
809 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
810 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
811 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
812 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
813 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
814 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
815 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
816 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
817 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
818 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
819 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
820 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
821 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
822 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
823 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
824 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
825 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | 210 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, |
826 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
827 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
828 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
829 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
830 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
831 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
832 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
833 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
834 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
835 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
836 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
837 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
838 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
839 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
840 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
841 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
842 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
843 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
844 | |||
845 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
846 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
847 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
848 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
849 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
850 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
851 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
852 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
853 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
854 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
855 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
856 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
857 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
858 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
859 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
860 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
861 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
862 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
863 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
864 | |||
865 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
866 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
867 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
868 | {SENSOR, 0x33, 0x03, 0x49}, | ||
869 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
870 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
871 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
872 | |||
873 | {SENSOR, 0x33, 0x03, 0x49}, | 211 | {SENSOR, 0x33, 0x03, 0x49}, |
874 | {SENSOR, 0x34, 0xc0, 0x19}, | 212 | {SENSOR, 0x34, 0xc0, 0x19}, |
875 | {SENSOR, 0x3f, 0x20, 0x20}, | 213 | {SENSOR, 0x3f, 0x20, 0x20}, |
@@ -898,25 +236,29 @@ static const unsigned char init_mt9m111[][4] = | |||
898 | {SENSOR, 0x85, 0x48, 0x0e}, | 236 | {SENSOR, 0x85, 0x48, 0x0e}, |
899 | {SENSOR, 0x86, 0x5b, 0x02}, | 237 | {SENSOR, 0x86, 0x5b, 0x02}, |
900 | {SENSOR, 0x87, 0x00, 0x5c}, | 238 | {SENSOR, 0x87, 0x00, 0x5c}, |
901 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | 239 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, MT9M111_SEL_CONTEXT_B}, |
902 | {SENSOR, 0x60, 0x00, 0x80}, | 240 | {SENSOR, 0x60, 0x00, 0x80}, |
903 | {SENSOR, 0x61, 0x00, 0x00}, | 241 | {SENSOR, 0x61, 0x00, 0x00}, |
904 | {SENSOR, 0x62, 0x00, 0x00}, | 242 | {SENSOR, 0x62, 0x00, 0x00}, |
905 | {SENSOR, 0x63, 0x00, 0x00}, | 243 | {SENSOR, 0x63, 0x00, 0x00}, |
906 | {SENSOR, 0x64, 0x00, 0x00}, | 244 | {SENSOR, 0x64, 0x00, 0x00}, |
907 | 245 | ||
908 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | 246 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, /* 13 */ |
909 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, | 247 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, /* 18 */ |
910 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, | 248 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, /* 1024 */ |
911 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, | 249 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, /* 1296 */ |
912 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, | 250 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, /* 352 */ |
913 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | 251 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */ |
914 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, | 252 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */ |
915 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | 253 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */ |
916 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, | 254 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */ |
917 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, | ||
918 | {SENSOR, 0x30, 0x04, 0x00}, | 255 | {SENSOR, 0x30, 0x04, 0x00}, |
256 | /* Set number of blank rows chosen to 400 */ | ||
257 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, | ||
258 | }; | ||
919 | 259 | ||
260 | static const unsigned char start_mt9m111[][4] = | ||
261 | { | ||
920 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 262 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
921 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 263 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
922 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 264 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -928,25 +270,6 @@ static const unsigned char init_mt9m111[][4] = | |||
928 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 270 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
929 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 271 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
930 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 272 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
931 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
932 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, | ||
933 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
934 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
935 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
936 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
937 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
938 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
939 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, /* 639*/ | ||
940 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, | ||
941 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
942 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
943 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
944 | |||
945 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
946 | /* Set number of blank rows chosen to 400 */ | ||
947 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, | ||
948 | /* Set the global gain to 283 (of 512) */ | ||
949 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x03, 0x63} | ||
950 | }; | 273 | }; |
951 | 274 | ||
952 | #endif | 275 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c new file mode 100644 index 000000000000..7aafeb7cfa07 --- /dev/null +++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | * Driver for the ov7660 sensor | ||
3 | * | ||
4 | * Copyright (C) 2009 Erik Andrén | ||
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | ||
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | ||
7 | * | ||
8 | * Portions of code to USB interface and ALi driver software, | ||
9 | * Copyright (c) 2006 Willem Duinker | ||
10 | * v4l2 interface modeled after the V4L2 driver | ||
11 | * for SN9C10x PC Camera Controllers | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License as | ||
15 | * published by the Free Software Foundation, version 2. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include "m5602_ov7660.h" | ||
20 | |||
21 | static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
22 | static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | |||
24 | const static struct ctrl ov7660_ctrls[] = { | ||
25 | #define GAIN_IDX 1 | ||
26 | { | ||
27 | { | ||
28 | .id = V4L2_CID_GAIN, | ||
29 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
30 | .name = "gain", | ||
31 | .minimum = 0x00, | ||
32 | .maximum = 0xff, | ||
33 | .step = 0x1, | ||
34 | .default_value = OV7660_DEFAULT_GAIN, | ||
35 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
36 | }, | ||
37 | .set = ov7660_set_gain, | ||
38 | .get = ov7660_get_gain | ||
39 | }, | ||
40 | }; | ||
41 | |||
42 | static struct v4l2_pix_format ov7660_modes[] = { | ||
43 | { | ||
44 | 640, | ||
45 | 480, | ||
46 | V4L2_PIX_FMT_SBGGR8, | ||
47 | V4L2_FIELD_NONE, | ||
48 | .sizeimage = | ||
49 | 640 * 480, | ||
50 | .bytesperline = 640, | ||
51 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
52 | .priv = 0 | ||
53 | } | ||
54 | }; | ||
55 | |||
56 | static void ov7660_dump_registers(struct sd *sd); | ||
57 | |||
58 | int ov7660_probe(struct sd *sd) | ||
59 | { | ||
60 | int err = 0, i; | ||
61 | u8 prod_id = 0, ver_id = 0; | ||
62 | |||
63 | s32 *sensor_settings; | ||
64 | |||
65 | if (force_sensor) { | ||
66 | if (force_sensor == OV7660_SENSOR) { | ||
67 | info("Forcing an %s sensor", ov7660.name); | ||
68 | goto sensor_found; | ||
69 | } | ||
70 | /* If we want to force another sensor, | ||
71 | don't try to probe this one */ | ||
72 | return -ENODEV; | ||
73 | } | ||
74 | |||
75 | /* Do the preinit */ | ||
76 | for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) { | ||
77 | u8 data[2]; | ||
78 | |||
79 | if (preinit_ov7660[i][0] == BRIDGE) { | ||
80 | err = m5602_write_bridge(sd, | ||
81 | preinit_ov7660[i][1], | ||
82 | preinit_ov7660[i][2]); | ||
83 | } else { | ||
84 | data[0] = preinit_ov7660[i][2]; | ||
85 | err = m5602_write_sensor(sd, | ||
86 | preinit_ov7660[i][1], data, 1); | ||
87 | } | ||
88 | } | ||
89 | if (err < 0) | ||
90 | return err; | ||
91 | |||
92 | if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1)) | ||
93 | return -ENODEV; | ||
94 | |||
95 | if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1)) | ||
96 | return -ENODEV; | ||
97 | |||
98 | info("Sensor reported 0x%x%x", prod_id, ver_id); | ||
99 | |||
100 | if ((prod_id == 0x76) && (ver_id == 0x60)) { | ||
101 | info("Detected a ov7660 sensor"); | ||
102 | goto sensor_found; | ||
103 | } | ||
104 | return -ENODEV; | ||
105 | |||
106 | sensor_found: | ||
107 | sensor_settings = kmalloc( | ||
108 | ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL); | ||
109 | if (!sensor_settings) | ||
110 | return -ENOMEM; | ||
111 | |||
112 | sd->gspca_dev.cam.cam_mode = ov7660_modes; | ||
113 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes); | ||
114 | sd->desc->ctrls = ov7660_ctrls; | ||
115 | sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls); | ||
116 | |||
117 | for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++) | ||
118 | sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value; | ||
119 | sd->sensor_priv = sensor_settings; | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | int ov7660_init(struct sd *sd) | ||
125 | { | ||
126 | int i, err = 0; | ||
127 | s32 *sensor_settings = sd->sensor_priv; | ||
128 | |||
129 | /* Init the sensor */ | ||
130 | for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) { | ||
131 | u8 data[2]; | ||
132 | |||
133 | if (init_ov7660[i][0] == BRIDGE) { | ||
134 | err = m5602_write_bridge(sd, | ||
135 | init_ov7660[i][1], | ||
136 | init_ov7660[i][2]); | ||
137 | } else { | ||
138 | data[0] = init_ov7660[i][2]; | ||
139 | err = m5602_write_sensor(sd, | ||
140 | init_ov7660[i][1], data, 1); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | if (dump_sensor) | ||
145 | ov7660_dump_registers(sd); | ||
146 | |||
147 | err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
148 | if (err < 0) | ||
149 | return err; | ||
150 | |||
151 | return err; | ||
152 | } | ||
153 | |||
154 | int ov7660_start(struct sd *sd) | ||
155 | { | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | int ov7660_stop(struct sd *sd) | ||
160 | { | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | void ov7660_disconnect(struct sd *sd) | ||
165 | { | ||
166 | ov7660_stop(sd); | ||
167 | |||
168 | sd->sensor = NULL; | ||
169 | kfree(sd->sensor_priv); | ||
170 | } | ||
171 | |||
172 | static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | ||
173 | { | ||
174 | struct sd *sd = (struct sd *) gspca_dev; | ||
175 | s32 *sensor_settings = sd->sensor_priv; | ||
176 | |||
177 | *val = sensor_settings[GAIN_IDX]; | ||
178 | PDEBUG(D_V4L2, "Read gain %d", *val); | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
183 | { | ||
184 | int err; | ||
185 | u8 i2c_data; | ||
186 | struct sd *sd = (struct sd *) gspca_dev; | ||
187 | s32 *sensor_settings = sd->sensor_priv; | ||
188 | |||
189 | PDEBUG(D_V4L2, "Setting gain to %d", val); | ||
190 | |||
191 | sensor_settings[GAIN_IDX] = val; | ||
192 | |||
193 | err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1); | ||
194 | return err; | ||
195 | } | ||
196 | |||
197 | static void ov7660_dump_registers(struct sd *sd) | ||
198 | { | ||
199 | int address; | ||
200 | info("Dumping the ov7660 register state"); | ||
201 | for (address = 0; address < 0xa9; address++) { | ||
202 | u8 value; | ||
203 | m5602_read_sensor(sd, address, &value, 1); | ||
204 | info("register 0x%x contains 0x%x", | ||
205 | address, value); | ||
206 | } | ||
207 | |||
208 | info("ov7660 register state dump complete"); | ||
209 | |||
210 | info("Probing for which registers that are read/write"); | ||
211 | for (address = 0; address < 0xff; address++) { | ||
212 | u8 old_value, ctrl_value; | ||
213 | u8 test_value[2] = {0xff, 0xff}; | ||
214 | |||
215 | m5602_read_sensor(sd, address, &old_value, 1); | ||
216 | m5602_write_sensor(sd, address, test_value, 1); | ||
217 | m5602_read_sensor(sd, address, &ctrl_value, 1); | ||
218 | |||
219 | if (ctrl_value == test_value[0]) | ||
220 | info("register 0x%x is writeable", address); | ||
221 | else | ||
222 | info("register 0x%x is read only", address); | ||
223 | |||
224 | /* Restore original value */ | ||
225 | m5602_write_sensor(sd, address, &old_value, 1); | ||
226 | } | ||
227 | } | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h new file mode 100644 index 000000000000..3f2c169a93ea --- /dev/null +++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h | |||
@@ -0,0 +1,279 @@ | |||
1 | /* | ||
2 | * Driver for the ov7660 sensor | ||
3 | * | ||
4 | * Copyright (C) 2009 Erik Andrén | ||
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | ||
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | ||
7 | * | ||
8 | * Portions of code to USB interface and ALi driver software, | ||
9 | * Copyright (c) 2006 Willem Duinker | ||
10 | * v4l2 interface modeled after the V4L2 driver | ||
11 | * for SN9C10x PC Camera Controllers | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License as | ||
15 | * published by the Free Software Foundation, version 2. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #ifndef M5602_OV7660_H_ | ||
20 | #define M5602_OV7660_H_ | ||
21 | |||
22 | #include "m5602_sensor.h" | ||
23 | |||
24 | #define OV7660_GAIN 0x00 | ||
25 | #define OV7660_BLUE_GAIN 0x01 | ||
26 | #define OV7660_RED_GAIN 0x02 | ||
27 | #define OV7660_VREF 0x03 | ||
28 | #define OV7660_COM1 0x04 | ||
29 | #define OV7660_BAVE 0x05 | ||
30 | #define OV7660_GEAVE 0x06 | ||
31 | #define OV7660_AECHH 0x07 | ||
32 | #define OV7660_RAVE 0x08 | ||
33 | #define OV7660_COM2 0x09 | ||
34 | #define OV7660_PID 0x0a | ||
35 | #define OV7660_VER 0x0b | ||
36 | #define OV7660_COM3 0x0c | ||
37 | #define OV7660_COM4 0x0d | ||
38 | #define OV7660_COM5 0x0e | ||
39 | #define OV7660_COM6 0x0f | ||
40 | #define OV7660_AECH 0x10 | ||
41 | #define OV7660_CLKRC 0x11 | ||
42 | #define OV7660_COM7 0x12 | ||
43 | #define OV7660_COM8 0x13 | ||
44 | #define OV7660_COM9 0x14 | ||
45 | #define OV7660_COM10 0x15 | ||
46 | #define OV7660_RSVD16 0x16 | ||
47 | #define OV7660_HSTART 0x17 | ||
48 | #define OV7660_HSTOP 0x18 | ||
49 | #define OV7660_VSTART 0x19 | ||
50 | #define OV7660_VSTOP 0x1a | ||
51 | #define OV7660_PSHFT 0x1b | ||
52 | #define OV7660_MIDH 0x1c | ||
53 | #define OV7660_MIDL 0x1d | ||
54 | #define OV7660_MVFP 0x1e | ||
55 | #define OV7660_LAEC 0x1f | ||
56 | #define OV7660_BOS 0x20 | ||
57 | #define OV7660_GBOS 0x21 | ||
58 | #define OV7660_GROS 0x22 | ||
59 | #define OV7660_ROS 0x23 | ||
60 | #define OV7660_AEW 0x24 | ||
61 | #define OV7660_AEB 0x25 | ||
62 | #define OV7660_VPT 0x26 | ||
63 | #define OV7660_BBIAS 0x27 | ||
64 | #define OV7660_GbBIAS 0x28 | ||
65 | #define OV7660_RSVD29 0x29 | ||
66 | #define OV7660_RBIAS 0x2c | ||
67 | #define OV7660_HREF 0x32 | ||
68 | #define OV7660_ADC 0x37 | ||
69 | #define OV7660_OFON 0x39 | ||
70 | #define OV7660_TSLB 0x3a | ||
71 | #define OV7660_COM12 0x3c | ||
72 | #define OV7660_COM13 0x3d | ||
73 | #define OV7660_LCC1 0x62 | ||
74 | #define OV7660_LCC2 0x63 | ||
75 | #define OV7660_LCC3 0x64 | ||
76 | #define OV7660_LCC4 0x65 | ||
77 | #define OV7660_LCC5 0x66 | ||
78 | #define OV7660_HV 0x69 | ||
79 | #define OV7660_RSVDA1 0xa1 | ||
80 | |||
81 | #define OV7660_DEFAULT_GAIN 0x0e | ||
82 | #define OV7660_DEFAULT_RED_GAIN 0x80 | ||
83 | #define OV7660_DEFAULT_BLUE_GAIN 0x80 | ||
84 | #define OV7660_DEFAULT_SATURATION 0x00 | ||
85 | #define OV7660_DEFAULT_EXPOSURE 0x20 | ||
86 | |||
87 | /* Kernel module parameters */ | ||
88 | extern int force_sensor; | ||
89 | extern int dump_sensor; | ||
90 | |||
91 | int ov7660_probe(struct sd *sd); | ||
92 | int ov7660_init(struct sd *sd); | ||
93 | int ov7660_start(struct sd *sd); | ||
94 | int ov7660_stop(struct sd *sd); | ||
95 | void ov7660_disconnect(struct sd *sd); | ||
96 | |||
97 | const static struct m5602_sensor ov7660 = { | ||
98 | .name = "ov7660", | ||
99 | .i2c_slave_id = 0x42, | ||
100 | .i2c_regW = 1, | ||
101 | .probe = ov7660_probe, | ||
102 | .init = ov7660_init, | ||
103 | .start = ov7660_start, | ||
104 | .stop = ov7660_stop, | ||
105 | .disconnect = ov7660_disconnect, | ||
106 | }; | ||
107 | |||
108 | static const unsigned char preinit_ov7660[][4] = | ||
109 | { | ||
110 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | ||
111 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | ||
112 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
113 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
114 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
115 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
116 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | ||
117 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
118 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
119 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
120 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
121 | |||
122 | {SENSOR, OV7660_OFON, 0x0c}, | ||
123 | {SENSOR, OV7660_COM2, 0x11}, | ||
124 | {SENSOR, OV7660_COM7, 0x05}, | ||
125 | |||
126 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
127 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
128 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
129 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
130 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
131 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
132 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
133 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
134 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
135 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
136 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
137 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
138 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | ||
139 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
140 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00} | ||
141 | }; | ||
142 | |||
143 | static const unsigned char init_ov7660[][4] = | ||
144 | { | ||
145 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | ||
146 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | ||
147 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
148 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
149 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
150 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
151 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | ||
152 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
153 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
154 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
155 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
156 | |||
157 | {SENSOR, OV7660_OFON, 0x0c}, | ||
158 | {SENSOR, OV7660_COM2, 0x11}, | ||
159 | {SENSOR, OV7660_COM7, 0x05}, | ||
160 | |||
161 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
162 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
163 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
164 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
165 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
166 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
167 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
168 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
169 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
170 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
171 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
172 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
173 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | ||
174 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
175 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
176 | |||
177 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02}, | ||
178 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
179 | |||
180 | {SENSOR, OV7660_AECH, OV7660_DEFAULT_EXPOSURE}, | ||
181 | {SENSOR, OV7660_COM1, 0x00}, | ||
182 | |||
183 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
184 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
185 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
186 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
187 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
188 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
189 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
190 | |||
191 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
192 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
193 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
194 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
195 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
196 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | ||
197 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
198 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
199 | |||
200 | {SENSOR, OV7660_COM7, 0x80}, | ||
201 | {SENSOR, OV7660_CLKRC, 0x80}, | ||
202 | {SENSOR, OV7660_BLUE_GAIN, 0x80}, | ||
203 | {SENSOR, OV7660_RED_GAIN, 0x80}, | ||
204 | {SENSOR, OV7660_COM9, 0x4c}, | ||
205 | {SENSOR, OV7660_OFON, 0x43}, | ||
206 | {SENSOR, OV7660_COM12, 0x28}, | ||
207 | {SENSOR, OV7660_COM8, 0x00}, | ||
208 | {SENSOR, OV7660_COM10, 0x40}, | ||
209 | {SENSOR, OV7660_HSTART, 0x0c}, | ||
210 | {SENSOR, OV7660_HSTOP, 0x61}, | ||
211 | {SENSOR, OV7660_HREF, 0xa4}, | ||
212 | {SENSOR, OV7660_PSHFT, 0x0b}, | ||
213 | {SENSOR, OV7660_VSTART, 0x01}, | ||
214 | {SENSOR, OV7660_VSTOP, 0x7a}, | ||
215 | {SENSOR, OV7660_VREF, 0x00}, | ||
216 | {SENSOR, OV7660_COM7, 0x05}, | ||
217 | {SENSOR, OV7660_COM6, 0x4b}, | ||
218 | {SENSOR, OV7660_BBIAS, 0x98}, | ||
219 | {SENSOR, OV7660_GbBIAS, 0x98}, | ||
220 | {SENSOR, OV7660_RSVD29, 0x98}, | ||
221 | {SENSOR, OV7660_RBIAS, 0x98}, | ||
222 | {SENSOR, OV7660_COM1, 0x00}, | ||
223 | {SENSOR, OV7660_AECH, 0x00}, | ||
224 | {SENSOR, OV7660_AECHH, 0x00}, | ||
225 | {SENSOR, OV7660_ADC, 0x04}, | ||
226 | {SENSOR, OV7660_COM13, 0x00}, | ||
227 | {SENSOR, OV7660_RSVDA1, 0x23}, | ||
228 | {SENSOR, OV7660_TSLB, 0x0d}, | ||
229 | {SENSOR, OV7660_HV, 0x80}, | ||
230 | {SENSOR, OV7660_LCC1, 0x00}, | ||
231 | {SENSOR, OV7660_LCC2, 0x00}, | ||
232 | {SENSOR, OV7660_LCC3, 0x10}, | ||
233 | {SENSOR, OV7660_LCC4, 0x40}, | ||
234 | {SENSOR, OV7660_LCC5, 0x01}, | ||
235 | |||
236 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
237 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
238 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
239 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
240 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
241 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
242 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
243 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
244 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x08}, | ||
245 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
246 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
247 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
248 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */ | ||
249 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
250 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
251 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
252 | {BRIDGE, M5602_XB_SIG_INI, 0x02}, | ||
253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x27}, /* 39 */ | ||
255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
256 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xa7}, /* 679 */ | ||
257 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
258 | |||
259 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
260 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
261 | |||
262 | {SENSOR, OV7660_AECH, 0x20}, | ||
263 | {SENSOR, OV7660_COM1, 0x00}, | ||
264 | {SENSOR, OV7660_OFON, 0x0c}, | ||
265 | {SENSOR, OV7660_COM2, 0x11}, | ||
266 | {SENSOR, OV7660_COM7, 0x05}, | ||
267 | {SENSOR, OV7660_BLUE_GAIN, 0x80}, | ||
268 | {SENSOR, OV7660_RED_GAIN, 0x80}, | ||
269 | |||
270 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
271 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
272 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
273 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
274 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
275 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
276 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0} | ||
277 | }; | ||
278 | |||
279 | #endif | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index fc4548fd441d..c2739d6605a1 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c | |||
@@ -18,44 +18,87 @@ | |||
18 | 18 | ||
19 | #include "m5602_ov9650.h" | 19 | #include "m5602_ov9650.h" |
20 | 20 | ||
21 | static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
22 | static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
23 | static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
29 | static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
30 | static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
31 | static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, | ||
34 | __s32 *val); | ||
35 | static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, | ||
36 | __s32 val); | ||
37 | static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
38 | static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
39 | static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
40 | static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
41 | |||
21 | /* Vertically and horizontally flips the image if matched, needed for machines | 42 | /* Vertically and horizontally flips the image if matched, needed for machines |
22 | where the sensor is mounted upside down */ | 43 | where the sensor is mounted upside down */ |
23 | static | 44 | static |
24 | const | 45 | const |
25 | struct dmi_system_id ov9650_flip_dmi_table[] = { | 46 | struct dmi_system_id ov9650_flip_dmi_table[] = { |
26 | { | 47 | { |
27 | .ident = "ASUS A6VC", | 48 | .ident = "ASUS A6Ja", |
28 | .matches = { | 49 | .matches = { |
29 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 50 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
30 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") | 51 | DMI_MATCH(DMI_PRODUCT_NAME, "A6J") |
31 | } | 52 | } |
32 | }, | 53 | }, |
33 | { | 54 | { |
34 | .ident = "ASUS A6VM", | 55 | .ident = "ASUS A6JC", |
35 | .matches = { | 56 | .matches = { |
36 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 57 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
37 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") | 58 | DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") |
38 | } | 59 | } |
39 | }, | 60 | }, |
40 | { | 61 | { |
41 | .ident = "ASUS A6JC", | 62 | .ident = "ASUS A6K", |
42 | .matches = { | 63 | .matches = { |
43 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 64 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
44 | DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") | 65 | DMI_MATCH(DMI_PRODUCT_NAME, "A6K") |
45 | } | 66 | } |
46 | }, | 67 | }, |
47 | { | 68 | { |
48 | .ident = "ASUS A6Ja", | 69 | .ident = "ASUS A6Kt", |
49 | .matches = { | 70 | .matches = { |
50 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 71 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
51 | DMI_MATCH(DMI_PRODUCT_NAME, "A6J") | 72 | DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") |
52 | } | 73 | } |
53 | }, | 74 | }, |
54 | { | 75 | { |
55 | .ident = "ASUS A6Kt", | 76 | .ident = "ASUS A6VA", |
56 | .matches = { | 77 | .matches = { |
57 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 78 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
58 | DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") | 79 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VA") |
80 | } | ||
81 | }, | ||
82 | { | ||
83 | |||
84 | .ident = "ASUS A6VC", | ||
85 | .matches = { | ||
86 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
87 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") | ||
88 | } | ||
89 | }, | ||
90 | { | ||
91 | .ident = "ASUS A6VM", | ||
92 | .matches = { | ||
93 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
94 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") | ||
95 | } | ||
96 | }, | ||
97 | { | ||
98 | .ident = "ASUS A7V", | ||
99 | .matches = { | ||
100 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
101 | DMI_MATCH(DMI_PRODUCT_NAME, "A7V") | ||
59 | } | 102 | } |
60 | }, | 103 | }, |
61 | { | 104 | { |
@@ -68,7 +111,7 @@ static | |||
68 | {} | 111 | {} |
69 | }; | 112 | }; |
70 | 113 | ||
71 | const static struct ctrl ov9650_ctrls[] = { | 114 | static const struct ctrl ov9650_ctrls[] = { |
72 | #define EXPOSURE_IDX 0 | 115 | #define EXPOSURE_IDX 0 |
73 | { | 116 | { |
74 | { | 117 | { |
@@ -102,6 +145,7 @@ const static struct ctrl ov9650_ctrls[] = { | |||
102 | #define RED_BALANCE_IDX 2 | 145 | #define RED_BALANCE_IDX 2 |
103 | { | 146 | { |
104 | { | 147 | { |
148 | .id = V4L2_CID_RED_BALANCE, | ||
105 | .type = V4L2_CTRL_TYPE_INTEGER, | 149 | .type = V4L2_CTRL_TYPE_INTEGER, |
106 | .name = "red balance", | 150 | .name = "red balance", |
107 | .minimum = 0x00, | 151 | .minimum = 0x00, |
@@ -116,6 +160,7 @@ const static struct ctrl ov9650_ctrls[] = { | |||
116 | #define BLUE_BALANCE_IDX 3 | 160 | #define BLUE_BALANCE_IDX 3 |
117 | { | 161 | { |
118 | { | 162 | { |
163 | .id = V4L2_CID_BLUE_BALANCE, | ||
119 | .type = V4L2_CTRL_TYPE_INTEGER, | 164 | .type = V4L2_CTRL_TYPE_INTEGER, |
120 | .name = "blue balance", | 165 | .name = "blue balance", |
121 | .minimum = 0x00, | 166 | .minimum = 0x00, |
@@ -182,7 +227,22 @@ const static struct ctrl ov9650_ctrls[] = { | |||
182 | }, | 227 | }, |
183 | .set = ov9650_set_auto_gain, | 228 | .set = ov9650_set_auto_gain, |
184 | .get = ov9650_get_auto_gain | 229 | .get = ov9650_get_auto_gain |
230 | }, | ||
231 | #define AUTO_EXPOSURE_IDX 8 | ||
232 | { | ||
233 | { | ||
234 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
235 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
236 | .name = "auto exposure", | ||
237 | .minimum = 0, | ||
238 | .maximum = 1, | ||
239 | .step = 1, | ||
240 | .default_value = 1 | ||
241 | }, | ||
242 | .set = ov9650_set_auto_exposure, | ||
243 | .get = ov9650_get_auto_exposure | ||
185 | } | 244 | } |
245 | |||
186 | }; | 246 | }; |
187 | 247 | ||
188 | static struct v4l2_pix_format ov9650_modes[] = { | 248 | static struct v4l2_pix_format ov9650_modes[] = { |
@@ -289,12 +349,6 @@ sensor_found: | |||
289 | for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++) | 349 | for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++) |
290 | sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; | 350 | sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; |
291 | sd->sensor_priv = sensor_settings; | 351 | sd->sensor_priv = sensor_settings; |
292 | |||
293 | if (dmi_check_system(ov9650_flip_dmi_table) && !err) { | ||
294 | info("vflip quirk active"); | ||
295 | sensor_settings[VFLIP_IDX] = 1; | ||
296 | } | ||
297 | |||
298 | return 0; | 352 | return 0; |
299 | } | 353 | } |
300 | 354 | ||
@@ -316,7 +370,8 @@ int ov9650_init(struct sd *sd) | |||
316 | err = m5602_write_bridge(sd, init_ov9650[i][1], data); | 370 | err = m5602_write_bridge(sd, init_ov9650[i][1], data); |
317 | } | 371 | } |
318 | 372 | ||
319 | err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]); | 373 | err = ov9650_set_exposure(&sd->gspca_dev, |
374 | sensor_settings[EXPOSURE_IDX]); | ||
320 | if (err < 0) | 375 | if (err < 0) |
321 | return err; | 376 | return err; |
322 | 377 | ||
@@ -324,11 +379,13 @@ int ov9650_init(struct sd *sd) | |||
324 | if (err < 0) | 379 | if (err < 0) |
325 | return err; | 380 | return err; |
326 | 381 | ||
327 | err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]); | 382 | err = ov9650_set_red_balance(&sd->gspca_dev, |
383 | sensor_settings[RED_BALANCE_IDX]); | ||
328 | if (err < 0) | 384 | if (err < 0) |
329 | return err; | 385 | return err; |
330 | 386 | ||
331 | err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]); | 387 | err = ov9650_set_blue_balance(&sd->gspca_dev, |
388 | sensor_settings[BLUE_BALANCE_IDX]); | ||
332 | if (err < 0) | 389 | if (err < 0) |
333 | return err; | 390 | return err; |
334 | 391 | ||
@@ -340,11 +397,18 @@ int ov9650_init(struct sd *sd) | |||
340 | if (err < 0) | 397 | if (err < 0) |
341 | return err; | 398 | return err; |
342 | 399 | ||
343 | err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]); | 400 | err = ov9650_set_auto_exposure(&sd->gspca_dev, |
401 | sensor_settings[AUTO_EXPOSURE_IDX]); | ||
402 | if (err < 0) | ||
403 | return err; | ||
404 | |||
405 | err = ov9650_set_auto_white_balance(&sd->gspca_dev, | ||
406 | sensor_settings[AUTO_WHITE_BALANCE_IDX]); | ||
344 | if (err < 0) | 407 | if (err < 0) |
345 | return err; | 408 | return err; |
346 | 409 | ||
347 | err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]); | 410 | err = ov9650_set_auto_gain(&sd->gspca_dev, |
411 | sensor_settings[AUTO_GAIN_CTRL_IDX]); | ||
348 | return err; | 412 | return err; |
349 | } | 413 | } |
350 | 414 | ||
@@ -360,7 +424,10 @@ int ov9650_start(struct sd *sd) | |||
360 | int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; | 424 | int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; |
361 | int hor_offs = OV9650_LEFT_OFFSET; | 425 | int hor_offs = OV9650_LEFT_OFFSET; |
362 | 426 | ||
363 | if (sensor_settings[VFLIP_IDX]) | 427 | if ((!dmi_check_system(ov9650_flip_dmi_table) && |
428 | sensor_settings[VFLIP_IDX]) || | ||
429 | (dmi_check_system(ov9650_flip_dmi_table) && | ||
430 | !sensor_settings[VFLIP_IDX])) | ||
364 | ver_offs--; | 431 | ver_offs--; |
365 | 432 | ||
366 | if (width <= 320) | 433 | if (width <= 320) |
@@ -406,6 +473,14 @@ int ov9650_start(struct sd *sd) | |||
406 | if (err < 0) | 473 | if (err < 0) |
407 | return err; | 474 | return err; |
408 | 475 | ||
476 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
477 | if (err < 0) | ||
478 | return err; | ||
479 | |||
480 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); | ||
481 | if (err < 0) | ||
482 | return err; | ||
483 | |||
409 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, | 484 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, |
410 | (hor_offs >> 8) & 0xff); | 485 | (hor_offs >> 8) & 0xff); |
411 | if (err < 0) | 486 | if (err < 0) |
@@ -425,6 +500,10 @@ int ov9650_start(struct sd *sd) | |||
425 | if (err < 0) | 500 | if (err < 0) |
426 | return err; | 501 | return err; |
427 | 502 | ||
503 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
504 | if (err < 0) | ||
505 | return err; | ||
506 | |||
428 | switch (width) { | 507 | switch (width) { |
429 | case 640: | 508 | case 640: |
430 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); | 509 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); |
@@ -467,32 +546,15 @@ int ov9650_stop(struct sd *sd) | |||
467 | return m5602_write_sensor(sd, OV9650_COM2, &data, 1); | 546 | return m5602_write_sensor(sd, OV9650_COM2, &data, 1); |
468 | } | 547 | } |
469 | 548 | ||
470 | int ov9650_power_down(struct sd *sd) | ||
471 | { | ||
472 | int i, err = 0; | ||
473 | for (i = 0; i < ARRAY_SIZE(power_down_ov9650) && !err; i++) { | ||
474 | u8 data = power_down_ov9650[i][2]; | ||
475 | if (power_down_ov9650[i][0] == SENSOR) | ||
476 | err = m5602_write_sensor(sd, | ||
477 | power_down_ov9650[i][1], &data, 1); | ||
478 | else | ||
479 | err = m5602_write_bridge(sd, power_down_ov9650[i][1], | ||
480 | data); | ||
481 | } | ||
482 | |||
483 | return err; | ||
484 | } | ||
485 | |||
486 | void ov9650_disconnect(struct sd *sd) | 549 | void ov9650_disconnect(struct sd *sd) |
487 | { | 550 | { |
488 | ov9650_stop(sd); | 551 | ov9650_stop(sd); |
489 | ov9650_power_down(sd); | ||
490 | 552 | ||
491 | sd->sensor = NULL; | 553 | sd->sensor = NULL; |
492 | kfree(sd->sensor_priv); | 554 | kfree(sd->sensor_priv); |
493 | } | 555 | } |
494 | 556 | ||
495 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 557 | static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
496 | { | 558 | { |
497 | struct sd *sd = (struct sd *) gspca_dev; | 559 | struct sd *sd = (struct sd *) gspca_dev; |
498 | s32 *sensor_settings = sd->sensor_priv; | 560 | s32 *sensor_settings = sd->sensor_priv; |
@@ -502,7 +564,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | |||
502 | return 0; | 564 | return 0; |
503 | } | 565 | } |
504 | 566 | ||
505 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 567 | static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
506 | { | 568 | { |
507 | struct sd *sd = (struct sd *) gspca_dev; | 569 | struct sd *sd = (struct sd *) gspca_dev; |
508 | s32 *sensor_settings = sd->sensor_priv; | 570 | s32 *sensor_settings = sd->sensor_priv; |
@@ -532,7 +594,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
532 | return err; | 594 | return err; |
533 | } | 595 | } |
534 | 596 | ||
535 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 597 | static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
536 | { | 598 | { |
537 | struct sd *sd = (struct sd *) gspca_dev; | 599 | struct sd *sd = (struct sd *) gspca_dev; |
538 | s32 *sensor_settings = sd->sensor_priv; | 600 | s32 *sensor_settings = sd->sensor_priv; |
@@ -542,7 +604,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
542 | return 0; | 604 | return 0; |
543 | } | 605 | } |
544 | 606 | ||
545 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 607 | static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
546 | { | 608 | { |
547 | int err; | 609 | int err; |
548 | u8 i2c_data; | 610 | u8 i2c_data; |
@@ -573,7 +635,7 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
573 | return err; | 635 | return err; |
574 | } | 636 | } |
575 | 637 | ||
576 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 638 | static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) |
577 | { | 639 | { |
578 | struct sd *sd = (struct sd *) gspca_dev; | 640 | struct sd *sd = (struct sd *) gspca_dev; |
579 | s32 *sensor_settings = sd->sensor_priv; | 641 | s32 *sensor_settings = sd->sensor_priv; |
@@ -583,7 +645,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
583 | return 0; | 645 | return 0; |
584 | } | 646 | } |
585 | 647 | ||
586 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 648 | static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) |
587 | { | 649 | { |
588 | int err; | 650 | int err; |
589 | u8 i2c_data; | 651 | u8 i2c_data; |
@@ -599,7 +661,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
599 | return err; | 661 | return err; |
600 | } | 662 | } |
601 | 663 | ||
602 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 664 | static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) |
603 | { | 665 | { |
604 | struct sd *sd = (struct sd *) gspca_dev; | 666 | struct sd *sd = (struct sd *) gspca_dev; |
605 | s32 *sensor_settings = sd->sensor_priv; | 667 | s32 *sensor_settings = sd->sensor_priv; |
@@ -610,7 +672,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
610 | return 0; | 672 | return 0; |
611 | } | 673 | } |
612 | 674 | ||
613 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 675 | static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) |
614 | { | 676 | { |
615 | int err; | 677 | int err; |
616 | u8 i2c_data; | 678 | u8 i2c_data; |
@@ -626,7 +688,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
626 | return err; | 688 | return err; |
627 | } | 689 | } |
628 | 690 | ||
629 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 691 | static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
630 | { | 692 | { |
631 | struct sd *sd = (struct sd *) gspca_dev; | 693 | struct sd *sd = (struct sd *) gspca_dev; |
632 | s32 *sensor_settings = sd->sensor_priv; | 694 | s32 *sensor_settings = sd->sensor_priv; |
@@ -636,7 +698,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
636 | return 0; | 698 | return 0; |
637 | } | 699 | } |
638 | 700 | ||
639 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 701 | static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
640 | { | 702 | { |
641 | int err; | 703 | int err; |
642 | u8 i2c_data; | 704 | u8 i2c_data; |
@@ -646,13 +708,20 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
646 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | 708 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); |
647 | 709 | ||
648 | sensor_settings[HFLIP_IDX] = val; | 710 | sensor_settings[HFLIP_IDX] = val; |
649 | i2c_data = ((val & 0x01) << 5) | (sensor_settings[VFLIP_IDX] << 4); | 711 | |
712 | if (!dmi_check_system(ov9650_flip_dmi_table)) | ||
713 | i2c_data = ((val & 0x01) << 5) | | ||
714 | (sensor_settings[VFLIP_IDX] << 4); | ||
715 | else | ||
716 | i2c_data = ((val & 0x01) << 5) | | ||
717 | (!sensor_settings[VFLIP_IDX] << 4); | ||
718 | |||
650 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 719 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
651 | 720 | ||
652 | return err; | 721 | return err; |
653 | } | 722 | } |
654 | 723 | ||
655 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 724 | static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
656 | { | 725 | { |
657 | struct sd *sd = (struct sd *) gspca_dev; | 726 | struct sd *sd = (struct sd *) gspca_dev; |
658 | s32 *sensor_settings = sd->sensor_priv; | 727 | s32 *sensor_settings = sd->sensor_priv; |
@@ -663,7 +732,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
663 | return 0; | 732 | return 0; |
664 | } | 733 | } |
665 | 734 | ||
666 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 735 | static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
667 | { | 736 | { |
668 | int err; | 737 | int err; |
669 | u8 i2c_data; | 738 | u8 i2c_data; |
@@ -673,6 +742,9 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
673 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 742 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
674 | sensor_settings[VFLIP_IDX] = val; | 743 | sensor_settings[VFLIP_IDX] = val; |
675 | 744 | ||
745 | if (dmi_check_system(ov9650_flip_dmi_table)) | ||
746 | val = !val; | ||
747 | |||
676 | i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); | 748 | i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); |
677 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 749 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
678 | if (err < 0) | 750 | if (err < 0) |
@@ -685,48 +757,38 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
685 | return err; | 757 | return err; |
686 | } | 758 | } |
687 | 759 | ||
688 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 760 | static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
689 | { | 761 | { |
690 | struct sd *sd = (struct sd *) gspca_dev; | 762 | struct sd *sd = (struct sd *) gspca_dev; |
691 | s32 *sensor_settings = sd->sensor_priv; | 763 | s32 *sensor_settings = sd->sensor_priv; |
692 | 764 | ||
693 | *val = sensor_settings[GAIN_IDX]; | 765 | *val = sensor_settings[AUTO_EXPOSURE_IDX]; |
694 | PDEBUG(D_V4L2, "Read gain %d", *val); | 766 | PDEBUG(D_V4L2, "Read auto exposure control %d", *val); |
695 | |||
696 | return 0; | 767 | return 0; |
697 | } | 768 | } |
698 | 769 | ||
699 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 770 | static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, |
771 | __s32 val) | ||
700 | { | 772 | { |
701 | int err; | 773 | int err; |
702 | u8 i2c_data; | 774 | u8 i2c_data; |
703 | struct sd *sd = (struct sd *) gspca_dev; | 775 | struct sd *sd = (struct sd *) gspca_dev; |
704 | s32 *sensor_settings = sd->sensor_priv; | 776 | s32 *sensor_settings = sd->sensor_priv; |
705 | 777 | ||
706 | PDEBUG(D_V4L2, "Set gain to %d", val); | 778 | PDEBUG(D_V4L2, "Set auto exposure control to %d", val); |
707 | |||
708 | sensor_settings[GAIN_IDX] = val; | ||
709 | 779 | ||
710 | /* Read the OV9650_VREF register first to avoid | 780 | sensor_settings[AUTO_EXPOSURE_IDX] = val; |
711 | corrupting the VREF high and low bits */ | 781 | err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); |
712 | err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1); | ||
713 | if (err < 0) | ||
714 | return err; | ||
715 | |||
716 | /* Mask away all uninteresting bits */ | ||
717 | i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F); | ||
718 | err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1); | ||
719 | if (err < 0) | 782 | if (err < 0) |
720 | return err; | 783 | return err; |
721 | 784 | ||
722 | /* The 8 LSBs */ | 785 | i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); |
723 | i2c_data = val & 0xff; | ||
724 | err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); | ||
725 | 786 | ||
726 | return err; | 787 | return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); |
727 | } | 788 | } |
728 | 789 | ||
729 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | 790 | static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, |
791 | __s32 *val) | ||
730 | { | 792 | { |
731 | struct sd *sd = (struct sd *) gspca_dev; | 793 | struct sd *sd = (struct sd *) gspca_dev; |
732 | s32 *sensor_settings = sd->sensor_priv; | 794 | s32 *sensor_settings = sd->sensor_priv; |
@@ -735,7 +797,8 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
735 | return 0; | 797 | return 0; |
736 | } | 798 | } |
737 | 799 | ||
738 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | 800 | static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, |
801 | __s32 val) | ||
739 | { | 802 | { |
740 | int err; | 803 | int err; |
741 | u8 i2c_data; | 804 | u8 i2c_data; |
@@ -755,7 +818,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
755 | return err; | 818 | return err; |
756 | } | 819 | } |
757 | 820 | ||
758 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | 821 | static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) |
759 | { | 822 | { |
760 | struct sd *sd = (struct sd *) gspca_dev; | 823 | struct sd *sd = (struct sd *) gspca_dev; |
761 | s32 *sensor_settings = sd->sensor_priv; | 824 | s32 *sensor_settings = sd->sensor_priv; |
@@ -765,7 +828,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
765 | return 0; | 828 | return 0; |
766 | } | 829 | } |
767 | 830 | ||
768 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | 831 | static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) |
769 | { | 832 | { |
770 | int err; | 833 | int err; |
771 | u8 i2c_data; | 834 | u8 i2c_data; |
@@ -780,9 +843,8 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
780 | return err; | 843 | return err; |
781 | 844 | ||
782 | i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); | 845 | i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); |
783 | err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); | ||
784 | 846 | ||
785 | return err; | 847 | return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); |
786 | } | 848 | } |
787 | 849 | ||
788 | static void ov9650_dump_registers(struct sd *sd) | 850 | static void ov9650_dump_registers(struct sd *sd) |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h index fcc54e4c0f4f..c98c40d69e05 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h | |||
@@ -120,6 +120,10 @@ | |||
120 | #define OV9650_SOFT_SLEEP (1 << 4) | 120 | #define OV9650_SOFT_SLEEP (1 << 4) |
121 | #define OV9650_OUTPUT_DRIVE_2X (1 << 0) | 121 | #define OV9650_OUTPUT_DRIVE_2X (1 << 0) |
122 | 122 | ||
123 | #define OV9650_DENOISE_ENABLE (1 << 5) | ||
124 | #define OV9650_WHITE_PIXEL_ENABLE (1 << 1) | ||
125 | #define OV9650_WHITE_PIXEL_OPTION (1 << 0) | ||
126 | |||
123 | #define OV9650_LEFT_OFFSET 0x62 | 127 | #define OV9650_LEFT_OFFSET 0x62 |
124 | 128 | ||
125 | #define GAIN_DEFAULT 0x14 | 129 | #define GAIN_DEFAULT 0x14 |
@@ -137,29 +141,9 @@ int ov9650_probe(struct sd *sd); | |||
137 | int ov9650_init(struct sd *sd); | 141 | int ov9650_init(struct sd *sd); |
138 | int ov9650_start(struct sd *sd); | 142 | int ov9650_start(struct sd *sd); |
139 | int ov9650_stop(struct sd *sd); | 143 | int ov9650_stop(struct sd *sd); |
140 | int ov9650_power_down(struct sd *sd); | ||
141 | void ov9650_disconnect(struct sd *sd); | 144 | void ov9650_disconnect(struct sd *sd); |
142 | 145 | ||
143 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | 146 | static const struct m5602_sensor ov9650 = { |
144 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
145 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
146 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
147 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
148 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
149 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
150 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
151 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
152 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
153 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
154 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
155 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
156 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
157 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
158 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
159 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
160 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
161 | |||
162 | const static struct m5602_sensor ov9650 = { | ||
163 | .name = "OV9650", | 147 | .name = "OV9650", |
164 | .i2c_slave_id = 0x60, | 148 | .i2c_slave_id = 0x60, |
165 | .i2c_regW = 1, | 149 | .i2c_regW = 1, |
@@ -167,7 +151,6 @@ const static struct m5602_sensor ov9650 = { | |||
167 | .init = ov9650_init, | 151 | .init = ov9650_init, |
168 | .start = ov9650_start, | 152 | .start = ov9650_start, |
169 | .stop = ov9650_stop, | 153 | .stop = ov9650_stop, |
170 | .power_down = ov9650_power_down, | ||
171 | .disconnect = ov9650_disconnect, | 154 | .disconnect = ov9650_disconnect, |
172 | }; | 155 | }; |
173 | 156 | ||
@@ -219,7 +202,7 @@ static const unsigned char init_ov9650[][3] = | |||
219 | /* Reset chip */ | 202 | /* Reset chip */ |
220 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, | 203 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, |
221 | /* One extra reset is needed in order to make the sensor behave | 204 | /* One extra reset is needed in order to make the sensor behave |
222 | properly when resuming from ram */ | 205 | properly when resuming from ram, could be a timing issue */ |
223 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, | 206 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, |
224 | 207 | ||
225 | /* Enable double clock */ | 208 | /* Enable double clock */ |
@@ -229,8 +212,7 @@ static const unsigned char init_ov9650[][3] = | |||
229 | 212 | ||
230 | /* Set fast AGC/AEC algorithm with unlimited step size */ | 213 | /* Set fast AGC/AEC algorithm with unlimited step size */ |
231 | {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | | 214 | {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | |
232 | OV9650_AEC_UNLIM_STEP_SIZE | | 215 | OV9650_AEC_UNLIM_STEP_SIZE}, |
233 | OV9650_AWB_EN | OV9650_AGC_EN}, | ||
234 | 216 | ||
235 | {SENSOR, OV9650_CHLF, 0x10}, | 217 | {SENSOR, OV9650_CHLF, 0x10}, |
236 | {SENSOR, OV9650_ARBLM, 0xbf}, | 218 | {SENSOR, OV9650_ARBLM, 0xbf}, |
@@ -301,8 +283,11 @@ static const unsigned char init_ov9650[][3] = | |||
301 | {SENSOR, OV9650_VREF, 0x10}, | 283 | {SENSOR, OV9650_VREF, 0x10}, |
302 | {SENSOR, OV9650_ADC, 0x04}, | 284 | {SENSOR, OV9650_ADC, 0x04}, |
303 | {SENSOR, OV9650_HV, 0x40}, | 285 | {SENSOR, OV9650_HV, 0x40}, |
286 | |||
304 | /* Enable denoise, and white-pixel erase */ | 287 | /* Enable denoise, and white-pixel erase */ |
305 | {SENSOR, OV9650_COM22, 0x23}, | 288 | {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE | |
289 | OV9650_WHITE_PIXEL_ENABLE | | ||
290 | OV9650_WHITE_PIXEL_OPTION}, | ||
306 | 291 | ||
307 | /* Enable VARIOPIXEL */ | 292 | /* Enable VARIOPIXEL */ |
308 | {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL}, | 293 | {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL}, |
@@ -312,26 +297,6 @@ static const unsigned char init_ov9650[][3] = | |||
312 | {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, | 297 | {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, |
313 | }; | 298 | }; |
314 | 299 | ||
315 | static const unsigned char power_down_ov9650[][3] = | ||
316 | { | ||
317 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
318 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
319 | {SENSOR, OV9650_COM7, 0x80}, | ||
320 | {SENSOR, OV9650_OFON, 0xf4}, | ||
321 | {SENSOR, OV9650_MVFP, 0x80}, | ||
322 | {SENSOR, OV9650_DBLV, 0x3f}, | ||
323 | {SENSOR, OV9650_RSVD36, 0x49}, | ||
324 | {SENSOR, OV9650_COM7, 0x05}, | ||
325 | |||
326 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
327 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
328 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
329 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x06}, | ||
330 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | ||
331 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
332 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
333 | }; | ||
334 | |||
335 | static const unsigned char res_init_ov9650[][3] = | 300 | static const unsigned char res_init_ov9650[][3] = |
336 | { | 301 | { |
337 | {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, | 302 | {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, |
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c index eaddf488bad1..8d74d8065b79 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.c +++ b/drivers/media/video/gspca/m5602/m5602_po1030.c | |||
@@ -18,6 +18,29 @@ | |||
18 | 18 | ||
19 | #include "m5602_po1030.h" | 19 | #include "m5602_po1030.h" |
20 | 20 | ||
21 | static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
22 | static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
29 | static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
30 | static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
31 | static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
34 | static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
35 | static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, | ||
36 | __s32 val); | ||
37 | static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, | ||
38 | __s32 *val); | ||
39 | static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, | ||
40 | __s32 val); | ||
41 | static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev, | ||
42 | __s32 *val); | ||
43 | |||
21 | static struct v4l2_pix_format po1030_modes[] = { | 44 | static struct v4l2_pix_format po1030_modes[] = { |
22 | { | 45 | { |
23 | 640, | 46 | 640, |
@@ -27,11 +50,12 @@ static struct v4l2_pix_format po1030_modes[] = { | |||
27 | .sizeimage = 640 * 480, | 50 | .sizeimage = 640 * 480, |
28 | .bytesperline = 640, | 51 | .bytesperline = 640, |
29 | .colorspace = V4L2_COLORSPACE_SRGB, | 52 | .colorspace = V4L2_COLORSPACE_SRGB, |
30 | .priv = 0 | 53 | .priv = 2 |
31 | } | 54 | } |
32 | }; | 55 | }; |
33 | 56 | ||
34 | const static struct ctrl po1030_ctrls[] = { | 57 | static const struct ctrl po1030_ctrls[] = { |
58 | #define GAIN_IDX 0 | ||
35 | { | 59 | { |
36 | { | 60 | { |
37 | .id = V4L2_CID_GAIN, | 61 | .id = V4L2_CID_GAIN, |
@@ -45,7 +69,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
45 | }, | 69 | }, |
46 | .set = po1030_set_gain, | 70 | .set = po1030_set_gain, |
47 | .get = po1030_get_gain | 71 | .get = po1030_get_gain |
48 | }, { | 72 | }, |
73 | #define EXPOSURE_IDX 1 | ||
74 | { | ||
49 | { | 75 | { |
50 | .id = V4L2_CID_EXPOSURE, | 76 | .id = V4L2_CID_EXPOSURE, |
51 | .type = V4L2_CTRL_TYPE_INTEGER, | 77 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -58,7 +84,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
58 | }, | 84 | }, |
59 | .set = po1030_set_exposure, | 85 | .set = po1030_set_exposure, |
60 | .get = po1030_get_exposure | 86 | .get = po1030_get_exposure |
61 | }, { | 87 | }, |
88 | #define RED_BALANCE_IDX 2 | ||
89 | { | ||
62 | { | 90 | { |
63 | .id = V4L2_CID_RED_BALANCE, | 91 | .id = V4L2_CID_RED_BALANCE, |
64 | .type = V4L2_CTRL_TYPE_INTEGER, | 92 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -71,7 +99,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
71 | }, | 99 | }, |
72 | .set = po1030_set_red_balance, | 100 | .set = po1030_set_red_balance, |
73 | .get = po1030_get_red_balance | 101 | .get = po1030_get_red_balance |
74 | }, { | 102 | }, |
103 | #define BLUE_BALANCE_IDX 3 | ||
104 | { | ||
75 | { | 105 | { |
76 | .id = V4L2_CID_BLUE_BALANCE, | 106 | .id = V4L2_CID_BLUE_BALANCE, |
77 | .type = V4L2_CTRL_TYPE_INTEGER, | 107 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -84,7 +114,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
84 | }, | 114 | }, |
85 | .set = po1030_set_blue_balance, | 115 | .set = po1030_set_blue_balance, |
86 | .get = po1030_get_blue_balance | 116 | .get = po1030_get_blue_balance |
87 | }, { | 117 | }, |
118 | #define HFLIP_IDX 4 | ||
119 | { | ||
88 | { | 120 | { |
89 | .id = V4L2_CID_HFLIP, | 121 | .id = V4L2_CID_HFLIP, |
90 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 122 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -96,7 +128,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
96 | }, | 128 | }, |
97 | .set = po1030_set_hflip, | 129 | .set = po1030_set_hflip, |
98 | .get = po1030_get_hflip | 130 | .get = po1030_get_hflip |
99 | }, { | 131 | }, |
132 | #define VFLIP_IDX 5 | ||
133 | { | ||
100 | { | 134 | { |
101 | .id = V4L2_CID_VFLIP, | 135 | .id = V4L2_CID_VFLIP, |
102 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 136 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -108,14 +142,58 @@ const static struct ctrl po1030_ctrls[] = { | |||
108 | }, | 142 | }, |
109 | .set = po1030_set_vflip, | 143 | .set = po1030_set_vflip, |
110 | .get = po1030_get_vflip | 144 | .get = po1030_get_vflip |
111 | } | 145 | }, |
146 | #define AUTO_WHITE_BALANCE_IDX 6 | ||
147 | { | ||
148 | { | ||
149 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
150 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
151 | .name = "auto white balance", | ||
152 | .minimum = 0, | ||
153 | .maximum = 1, | ||
154 | .step = 1, | ||
155 | .default_value = 0, | ||
156 | }, | ||
157 | .set = po1030_set_auto_white_balance, | ||
158 | .get = po1030_get_auto_white_balance | ||
159 | }, | ||
160 | #define AUTO_EXPOSURE_IDX 7 | ||
161 | { | ||
162 | { | ||
163 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
164 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
165 | .name = "auto exposure", | ||
166 | .minimum = 0, | ||
167 | .maximum = 1, | ||
168 | .step = 1, | ||
169 | .default_value = 0, | ||
170 | }, | ||
171 | .set = po1030_set_auto_exposure, | ||
172 | .get = po1030_get_auto_exposure | ||
173 | }, | ||
174 | #define GREEN_BALANCE_IDX 8 | ||
175 | { | ||
176 | { | ||
177 | .id = M5602_V4L2_CID_GREEN_BALANCE, | ||
178 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
179 | .name = "green balance", | ||
180 | .minimum = 0x00, | ||
181 | .maximum = 0xff, | ||
182 | .step = 0x1, | ||
183 | .default_value = PO1030_GREEN_GAIN_DEFAULT, | ||
184 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
185 | }, | ||
186 | .set = po1030_set_green_balance, | ||
187 | .get = po1030_get_green_balance | ||
188 | }, | ||
112 | }; | 189 | }; |
113 | 190 | ||
114 | static void po1030_dump_registers(struct sd *sd); | 191 | static void po1030_dump_registers(struct sd *sd); |
115 | 192 | ||
116 | int po1030_probe(struct sd *sd) | 193 | int po1030_probe(struct sd *sd) |
117 | { | 194 | { |
118 | u8 prod_id = 0, ver_id = 0, i; | 195 | u8 dev_id_h = 0, i; |
196 | s32 *sensor_settings; | ||
119 | 197 | ||
120 | if (force_sensor) { | 198 | if (force_sensor) { |
121 | if (force_sensor == PO1030_SENSOR) { | 199 | if (force_sensor == PO1030_SENSOR) { |
@@ -139,28 +217,36 @@ int po1030_probe(struct sd *sd) | |||
139 | m5602_write_bridge(sd, preinit_po1030[i][1], data); | 217 | m5602_write_bridge(sd, preinit_po1030[i][1], data); |
140 | } | 218 | } |
141 | 219 | ||
142 | if (m5602_read_sensor(sd, 0x3, &prod_id, 1)) | 220 | if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1)) |
143 | return -ENODEV; | 221 | return -ENODEV; |
144 | 222 | ||
145 | if (m5602_read_sensor(sd, 0x4, &ver_id, 1)) | 223 | if (dev_id_h == 0x30) { |
146 | return -ENODEV; | ||
147 | |||
148 | if ((prod_id == 0x02) && (ver_id == 0xef)) { | ||
149 | info("Detected a po1030 sensor"); | 224 | info("Detected a po1030 sensor"); |
150 | goto sensor_found; | 225 | goto sensor_found; |
151 | } | 226 | } |
152 | return -ENODEV; | 227 | return -ENODEV; |
153 | 228 | ||
154 | sensor_found: | 229 | sensor_found: |
230 | sensor_settings = kmalloc( | ||
231 | ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL); | ||
232 | if (!sensor_settings) | ||
233 | return -ENOMEM; | ||
234 | |||
155 | sd->gspca_dev.cam.cam_mode = po1030_modes; | 235 | sd->gspca_dev.cam.cam_mode = po1030_modes; |
156 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); | 236 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); |
157 | sd->desc->ctrls = po1030_ctrls; | 237 | sd->desc->ctrls = po1030_ctrls; |
158 | sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); | 238 | sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); |
239 | |||
240 | for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++) | ||
241 | sensor_settings[i] = po1030_ctrls[i].qctrl.default_value; | ||
242 | sd->sensor_priv = sensor_settings; | ||
243 | |||
159 | return 0; | 244 | return 0; |
160 | } | 245 | } |
161 | 246 | ||
162 | int po1030_init(struct sd *sd) | 247 | int po1030_init(struct sd *sd) |
163 | { | 248 | { |
249 | s32 *sensor_settings = sd->sensor_priv; | ||
164 | int i, err = 0; | 250 | int i, err = 0; |
165 | 251 | ||
166 | /* Init the sensor */ | 252 | /* Init the sensor */ |
@@ -185,47 +271,206 @@ int po1030_init(struct sd *sd) | |||
185 | return -EINVAL; | 271 | return -EINVAL; |
186 | } | 272 | } |
187 | } | 273 | } |
274 | if (err < 0) | ||
275 | return err; | ||
188 | 276 | ||
189 | if (dump_sensor) | 277 | if (dump_sensor) |
190 | po1030_dump_registers(sd); | 278 | po1030_dump_registers(sd); |
191 | 279 | ||
280 | err = po1030_set_exposure(&sd->gspca_dev, | ||
281 | sensor_settings[EXPOSURE_IDX]); | ||
282 | if (err < 0) | ||
283 | return err; | ||
284 | |||
285 | err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
286 | if (err < 0) | ||
287 | return err; | ||
288 | |||
289 | err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
290 | if (err < 0) | ||
291 | return err; | ||
292 | |||
293 | err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); | ||
294 | if (err < 0) | ||
295 | return err; | ||
296 | |||
297 | err = po1030_set_red_balance(&sd->gspca_dev, | ||
298 | sensor_settings[RED_BALANCE_IDX]); | ||
299 | if (err < 0) | ||
300 | return err; | ||
301 | |||
302 | err = po1030_set_blue_balance(&sd->gspca_dev, | ||
303 | sensor_settings[BLUE_BALANCE_IDX]); | ||
304 | if (err < 0) | ||
305 | return err; | ||
306 | |||
307 | err = po1030_set_green_balance(&sd->gspca_dev, | ||
308 | sensor_settings[GREEN_BALANCE_IDX]); | ||
309 | if (err < 0) | ||
310 | return err; | ||
311 | |||
312 | err = po1030_set_auto_white_balance(&sd->gspca_dev, | ||
313 | sensor_settings[AUTO_WHITE_BALANCE_IDX]); | ||
314 | if (err < 0) | ||
315 | return err; | ||
316 | |||
317 | err = po1030_set_auto_exposure(&sd->gspca_dev, | ||
318 | sensor_settings[AUTO_EXPOSURE_IDX]); | ||
192 | return err; | 319 | return err; |
193 | } | 320 | } |
194 | 321 | ||
195 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 322 | int po1030_start(struct sd *sd) |
196 | { | 323 | { |
197 | struct sd *sd = (struct sd *) gspca_dev; | 324 | struct cam *cam = &sd->gspca_dev.cam; |
198 | u8 i2c_data; | 325 | int i, err = 0; |
199 | int err; | 326 | int width = cam->cam_mode[sd->gspca_dev.curr_mode].width; |
327 | int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; | ||
328 | int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; | ||
329 | u8 data; | ||
330 | |||
331 | switch (width) { | ||
332 | case 320: | ||
333 | data = PO1030_SUBSAMPLING; | ||
334 | err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1); | ||
335 | if (err < 0) | ||
336 | return err; | ||
337 | |||
338 | data = ((width + 3) >> 8) & 0xff; | ||
339 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1); | ||
340 | if (err < 0) | ||
341 | return err; | ||
342 | |||
343 | data = (width + 3) & 0xff; | ||
344 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1); | ||
345 | if (err < 0) | ||
346 | return err; | ||
347 | |||
348 | data = ((height + 1) >> 8) & 0xff; | ||
349 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1); | ||
350 | if (err < 0) | ||
351 | return err; | ||
352 | |||
353 | data = (height + 1) & 0xff; | ||
354 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1); | ||
355 | |||
356 | height += 6; | ||
357 | width -= 1; | ||
358 | break; | ||
359 | |||
360 | case 640: | ||
361 | data = 0; | ||
362 | err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1); | ||
363 | if (err < 0) | ||
364 | return err; | ||
365 | |||
366 | data = ((width + 7) >> 8) & 0xff; | ||
367 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1); | ||
368 | if (err < 0) | ||
369 | return err; | ||
370 | |||
371 | data = (width + 7) & 0xff; | ||
372 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1); | ||
373 | if (err < 0) | ||
374 | return err; | ||
375 | |||
376 | data = ((height + 3) >> 8) & 0xff; | ||
377 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1); | ||
378 | if (err < 0) | ||
379 | return err; | ||
380 | |||
381 | data = (height + 3) & 0xff; | ||
382 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1); | ||
383 | |||
384 | height += 12; | ||
385 | width -= 2; | ||
386 | break; | ||
387 | } | ||
388 | err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c); | ||
389 | if (err < 0) | ||
390 | return err; | ||
200 | 391 | ||
201 | err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H, | 392 | err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81); |
202 | &i2c_data, 1); | ||
203 | if (err < 0) | 393 | if (err < 0) |
204 | return err; | 394 | return err; |
205 | *val = (i2c_data << 8); | ||
206 | 395 | ||
207 | err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M, | 396 | err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82); |
208 | &i2c_data, 1); | 397 | if (err < 0) |
209 | *val |= i2c_data; | 398 | return err; |
210 | 399 | ||
211 | PDEBUG(D_V4L2, "Exposure read as %d", *val); | 400 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01); |
401 | if (err < 0) | ||
402 | return err; | ||
403 | |||
404 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, | ||
405 | ((ver_offs >> 8) & 0xff)); | ||
406 | if (err < 0) | ||
407 | return err; | ||
408 | |||
409 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff)); | ||
410 | if (err < 0) | ||
411 | return err; | ||
412 | |||
413 | for (i = 0; i < 2 && !err; i++) | ||
414 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); | ||
415 | if (err < 0) | ||
416 | return err; | ||
417 | |||
418 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); | ||
419 | if (err < 0) | ||
420 | return err; | ||
421 | |||
422 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); | ||
423 | if (err < 0) | ||
424 | return err; | ||
425 | |||
426 | for (i = 0; i < 2 && !err; i++) | ||
427 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); | ||
428 | |||
429 | for (i = 0; i < 2 && !err; i++) | ||
430 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
431 | |||
432 | for (i = 0; i < 2 && !err; i++) | ||
433 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0); | ||
434 | if (err < 0) | ||
435 | return err; | ||
436 | |||
437 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff); | ||
438 | if (err < 0) | ||
439 | return err; | ||
212 | 440 | ||
441 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff)); | ||
442 | if (err < 0) | ||
443 | return err; | ||
444 | |||
445 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
213 | return err; | 446 | return err; |
214 | } | 447 | } |
215 | 448 | ||
216 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 449 | static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
217 | { | 450 | { |
218 | struct sd *sd = (struct sd *) gspca_dev; | 451 | struct sd *sd = (struct sd *) gspca_dev; |
452 | s32 *sensor_settings = sd->sensor_priv; | ||
453 | |||
454 | *val = sensor_settings[EXPOSURE_IDX]; | ||
455 | PDEBUG(D_V4L2, "Exposure read as %d", *val); | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | ||
460 | { | ||
461 | struct sd *sd = (struct sd *) gspca_dev; | ||
462 | s32 *sensor_settings = sd->sensor_priv; | ||
219 | u8 i2c_data; | 463 | u8 i2c_data; |
220 | int err; | 464 | int err; |
221 | 465 | ||
466 | sensor_settings[EXPOSURE_IDX] = val; | ||
222 | PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); | 467 | PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); |
223 | 468 | ||
224 | i2c_data = ((val & 0xff00) >> 8); | 469 | i2c_data = ((val & 0xff00) >> 8); |
225 | PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", | 470 | PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", |
226 | i2c_data); | 471 | i2c_data); |
227 | 472 | ||
228 | err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H, | 473 | err = m5602_write_sensor(sd, PO1030_INTEGLINES_H, |
229 | &i2c_data, 1); | 474 | &i2c_data, 1); |
230 | if (err < 0) | 475 | if (err < 0) |
231 | return err; | 476 | return err; |
@@ -233,167 +478,256 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
233 | i2c_data = (val & 0xff); | 478 | i2c_data = (val & 0xff); |
234 | PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", | 479 | PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", |
235 | i2c_data); | 480 | i2c_data); |
236 | err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M, | 481 | err = m5602_write_sensor(sd, PO1030_INTEGLINES_M, |
237 | &i2c_data, 1); | 482 | &i2c_data, 1); |
238 | 483 | ||
239 | return err; | 484 | return err; |
240 | } | 485 | } |
241 | 486 | ||
242 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 487 | static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
243 | { | 488 | { |
244 | struct sd *sd = (struct sd *) gspca_dev; | 489 | struct sd *sd = (struct sd *) gspca_dev; |
245 | u8 i2c_data; | 490 | s32 *sensor_settings = sd->sensor_priv; |
246 | int err; | ||
247 | 491 | ||
248 | err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN, | 492 | *val = sensor_settings[GAIN_IDX]; |
249 | &i2c_data, 1); | ||
250 | *val = i2c_data; | ||
251 | PDEBUG(D_V4L2, "Read global gain %d", *val); | 493 | PDEBUG(D_V4L2, "Read global gain %d", *val); |
252 | 494 | return 0; | |
253 | return err; | ||
254 | } | 495 | } |
255 | 496 | ||
256 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 497 | static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
257 | { | 498 | { |
258 | struct sd *sd = (struct sd *) gspca_dev; | 499 | struct sd *sd = (struct sd *) gspca_dev; |
500 | s32 *sensor_settings = sd->sensor_priv; | ||
259 | u8 i2c_data; | 501 | u8 i2c_data; |
260 | int err; | 502 | int err; |
261 | 503 | ||
262 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, | 504 | sensor_settings[GAIN_IDX] = val; |
505 | |||
506 | i2c_data = val & 0xff; | ||
507 | PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); | ||
508 | err = m5602_write_sensor(sd, PO1030_GLOBALGAIN, | ||
263 | &i2c_data, 1); | 509 | &i2c_data, 1); |
510 | return err; | ||
511 | } | ||
264 | 512 | ||
265 | *val = (i2c_data >> 7) & 0x01 ; | 513 | static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
514 | { | ||
515 | struct sd *sd = (struct sd *) gspca_dev; | ||
516 | s32 *sensor_settings = sd->sensor_priv; | ||
266 | 517 | ||
518 | *val = sensor_settings[HFLIP_IDX]; | ||
267 | PDEBUG(D_V4L2, "Read hflip %d", *val); | 519 | PDEBUG(D_V4L2, "Read hflip %d", *val); |
268 | 520 | ||
269 | return err; | 521 | return 0; |
270 | } | 522 | } |
271 | 523 | ||
272 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 524 | static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
273 | { | 525 | { |
274 | struct sd *sd = (struct sd *) gspca_dev; | 526 | struct sd *sd = (struct sd *) gspca_dev; |
527 | s32 *sensor_settings = sd->sensor_priv; | ||
275 | u8 i2c_data; | 528 | u8 i2c_data; |
276 | int err; | 529 | int err; |
277 | 530 | ||
531 | sensor_settings[HFLIP_IDX] = val; | ||
532 | |||
278 | PDEBUG(D_V4L2, "Set hflip %d", val); | 533 | PDEBUG(D_V4L2, "Set hflip %d", val); |
279 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); | 534 | err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); |
280 | if (err < 0) | 535 | if (err < 0) |
281 | return err; | 536 | return err; |
282 | 537 | ||
283 | i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7); | 538 | i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7); |
284 | 539 | ||
285 | err = m5602_write_sensor(sd, PO1030_REG_CONTROL2, | 540 | err = m5602_write_sensor(sd, PO1030_CONTROL2, |
286 | &i2c_data, 1); | 541 | &i2c_data, 1); |
287 | 542 | ||
288 | return err; | 543 | return err; |
289 | } | 544 | } |
290 | 545 | ||
291 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 546 | static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
292 | { | 547 | { |
293 | struct sd *sd = (struct sd *) gspca_dev; | 548 | struct sd *sd = (struct sd *) gspca_dev; |
294 | u8 i2c_data; | 549 | s32 *sensor_settings = sd->sensor_priv; |
295 | int err; | ||
296 | |||
297 | err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN, | ||
298 | &i2c_data, 1); | ||
299 | |||
300 | *val = (i2c_data >> 6) & 0x01; | ||
301 | 550 | ||
551 | *val = sensor_settings[VFLIP_IDX]; | ||
302 | PDEBUG(D_V4L2, "Read vflip %d", *val); | 552 | PDEBUG(D_V4L2, "Read vflip %d", *val); |
303 | 553 | ||
304 | return err; | 554 | return 0; |
305 | } | 555 | } |
306 | 556 | ||
307 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 557 | static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
308 | { | 558 | { |
309 | struct sd *sd = (struct sd *) gspca_dev; | 559 | struct sd *sd = (struct sd *) gspca_dev; |
560 | s32 *sensor_settings = sd->sensor_priv; | ||
310 | u8 i2c_data; | 561 | u8 i2c_data; |
311 | int err; | 562 | int err; |
312 | 563 | ||
564 | sensor_settings[VFLIP_IDX] = val; | ||
565 | |||
313 | PDEBUG(D_V4L2, "Set vflip %d", val); | 566 | PDEBUG(D_V4L2, "Set vflip %d", val); |
314 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); | 567 | err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); |
315 | if (err < 0) | 568 | if (err < 0) |
316 | return err; | 569 | return err; |
317 | 570 | ||
318 | i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6); | 571 | i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6); |
319 | 572 | ||
320 | err = m5602_write_sensor(sd, PO1030_REG_CONTROL2, | 573 | err = m5602_write_sensor(sd, PO1030_CONTROL2, |
321 | &i2c_data, 1); | 574 | &i2c_data, 1); |
322 | 575 | ||
323 | return err; | 576 | return err; |
324 | } | 577 | } |
325 | 578 | ||
326 | int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 579 | static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) |
580 | { | ||
581 | struct sd *sd = (struct sd *) gspca_dev; | ||
582 | s32 *sensor_settings = sd->sensor_priv; | ||
583 | |||
584 | *val = sensor_settings[RED_BALANCE_IDX]; | ||
585 | PDEBUG(D_V4L2, "Read red gain %d", *val); | ||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
327 | { | 590 | { |
328 | struct sd *sd = (struct sd *) gspca_dev; | 591 | struct sd *sd = (struct sd *) gspca_dev; |
592 | s32 *sensor_settings = sd->sensor_priv; | ||
329 | u8 i2c_data; | 593 | u8 i2c_data; |
330 | int err; | 594 | int err; |
331 | 595 | ||
596 | sensor_settings[RED_BALANCE_IDX] = val; | ||
597 | |||
332 | i2c_data = val & 0xff; | 598 | i2c_data = val & 0xff; |
333 | PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); | 599 | PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); |
334 | err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN, | 600 | err = m5602_write_sensor(sd, PO1030_RED_GAIN, |
335 | &i2c_data, 1); | 601 | &i2c_data, 1); |
336 | return err; | 602 | return err; |
337 | } | 603 | } |
338 | 604 | ||
339 | int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 605 | static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) |
340 | { | 606 | { |
341 | struct sd *sd = (struct sd *) gspca_dev; | 607 | struct sd *sd = (struct sd *) gspca_dev; |
342 | u8 i2c_data; | 608 | s32 *sensor_settings = sd->sensor_priv; |
343 | int err; | ||
344 | 609 | ||
345 | err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN, | 610 | *val = sensor_settings[BLUE_BALANCE_IDX]; |
346 | &i2c_data, 1); | 611 | PDEBUG(D_V4L2, "Read blue gain %d", *val); |
347 | *val = i2c_data; | 612 | |
348 | PDEBUG(D_V4L2, "Read red gain %d", *val); | 613 | return 0; |
349 | return err; | ||
350 | } | 614 | } |
351 | 615 | ||
352 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 616 | static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) |
353 | { | 617 | { |
354 | struct sd *sd = (struct sd *) gspca_dev; | 618 | struct sd *sd = (struct sd *) gspca_dev; |
619 | s32 *sensor_settings = sd->sensor_priv; | ||
355 | u8 i2c_data; | 620 | u8 i2c_data; |
356 | int err; | 621 | int err; |
357 | 622 | ||
623 | sensor_settings[BLUE_BALANCE_IDX] = val; | ||
624 | |||
358 | i2c_data = val & 0xff; | 625 | i2c_data = val & 0xff; |
359 | PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); | 626 | PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); |
360 | err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN, | 627 | err = m5602_write_sensor(sd, PO1030_BLUE_GAIN, |
361 | &i2c_data, 1); | 628 | &i2c_data, 1); |
629 | |||
362 | return err; | 630 | return err; |
363 | } | 631 | } |
364 | 632 | ||
365 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 633 | static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val) |
366 | { | 634 | { |
367 | struct sd *sd = (struct sd *) gspca_dev; | 635 | struct sd *sd = (struct sd *) gspca_dev; |
636 | s32 *sensor_settings = sd->sensor_priv; | ||
637 | |||
638 | *val = sensor_settings[GREEN_BALANCE_IDX]; | ||
639 | PDEBUG(D_V4L2, "Read green gain %d", *val); | ||
640 | |||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
645 | { | ||
646 | struct sd *sd = (struct sd *) gspca_dev; | ||
647 | s32 *sensor_settings = sd->sensor_priv; | ||
368 | u8 i2c_data; | 648 | u8 i2c_data; |
369 | int err; | 649 | int err; |
370 | 650 | ||
371 | err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN, | 651 | sensor_settings[GREEN_BALANCE_IDX] = val; |
652 | i2c_data = val & 0xff; | ||
653 | PDEBUG(D_V4L2, "Set green gain to %d", i2c_data); | ||
654 | |||
655 | err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN, | ||
656 | &i2c_data, 1); | ||
657 | if (err < 0) | ||
658 | return err; | ||
659 | |||
660 | return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN, | ||
372 | &i2c_data, 1); | 661 | &i2c_data, 1); |
373 | *val = i2c_data; | 662 | } |
374 | PDEBUG(D_V4L2, "Read blue gain %d", *val); | ||
375 | 663 | ||
376 | return err; | 664 | static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, |
665 | __s32 *val) | ||
666 | { | ||
667 | struct sd *sd = (struct sd *) gspca_dev; | ||
668 | s32 *sensor_settings = sd->sensor_priv; | ||
669 | |||
670 | *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; | ||
671 | PDEBUG(D_V4L2, "Auto white balancing is %d", *val); | ||
672 | |||
673 | return 0; | ||
377 | } | 674 | } |
378 | 675 | ||
379 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 676 | static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, |
677 | __s32 val) | ||
380 | { | 678 | { |
381 | struct sd *sd = (struct sd *) gspca_dev; | 679 | struct sd *sd = (struct sd *) gspca_dev; |
680 | s32 *sensor_settings = sd->sensor_priv; | ||
382 | u8 i2c_data; | 681 | u8 i2c_data; |
383 | int err; | 682 | int err; |
384 | i2c_data = val & 0xff; | ||
385 | PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); | ||
386 | err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN, | ||
387 | &i2c_data, 1); | ||
388 | 683 | ||
684 | sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; | ||
685 | |||
686 | err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
687 | if (err < 0) | ||
688 | return err; | ||
689 | |||
690 | PDEBUG(D_V4L2, "Set auto white balance to %d", val); | ||
691 | i2c_data = (i2c_data & 0xfe) | (val & 0x01); | ||
692 | err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
389 | return err; | 693 | return err; |
390 | } | 694 | } |
391 | 695 | ||
392 | int po1030_power_down(struct sd *sd) | 696 | static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev, |
697 | __s32 *val) | ||
393 | { | 698 | { |
699 | struct sd *sd = (struct sd *) gspca_dev; | ||
700 | s32 *sensor_settings = sd->sensor_priv; | ||
701 | |||
702 | *val = sensor_settings[AUTO_EXPOSURE_IDX]; | ||
703 | PDEBUG(D_V4L2, "Auto exposure is %d", *val); | ||
394 | return 0; | 704 | return 0; |
395 | } | 705 | } |
396 | 706 | ||
707 | static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, | ||
708 | __s32 val) | ||
709 | { | ||
710 | struct sd *sd = (struct sd *) gspca_dev; | ||
711 | s32 *sensor_settings = sd->sensor_priv; | ||
712 | u8 i2c_data; | ||
713 | int err; | ||
714 | |||
715 | sensor_settings[AUTO_EXPOSURE_IDX] = val; | ||
716 | err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
717 | if (err < 0) | ||
718 | return err; | ||
719 | |||
720 | PDEBUG(D_V4L2, "Set auto exposure to %d", val); | ||
721 | i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1); | ||
722 | return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
723 | } | ||
724 | |||
725 | void po1030_disconnect(struct sd *sd) | ||
726 | { | ||
727 | sd->sensor = NULL; | ||
728 | kfree(sd->sensor_priv); | ||
729 | } | ||
730 | |||
397 | static void po1030_dump_registers(struct sd *sd) | 731 | static void po1030_dump_registers(struct sd *sd) |
398 | { | 732 | { |
399 | int address; | 733 | int address; |
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h index c10b12335818..1ea380b2bbe7 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.h +++ b/drivers/media/video/gspca/m5602/m5602_po1030.h | |||
@@ -25,98 +25,123 @@ | |||
25 | 25 | ||
26 | /*****************************************************************************/ | 26 | /*****************************************************************************/ |
27 | 27 | ||
28 | #define PO1030_REG_DEVID_H 0x00 | 28 | #define PO1030_DEVID_H 0x00 |
29 | #define PO1030_REG_DEVID_L 0x01 | 29 | #define PO1030_DEVID_L 0x01 |
30 | #define PO1030_REG_FRAMEWIDTH_H 0x04 | 30 | #define PO1030_FRAMEWIDTH_H 0x04 |
31 | #define PO1030_REG_FRAMEWIDTH_L 0x05 | 31 | #define PO1030_FRAMEWIDTH_L 0x05 |
32 | #define PO1030_REG_FRAMEHEIGHT_H 0x06 | 32 | #define PO1030_FRAMEHEIGHT_H 0x06 |
33 | #define PO1030_REG_FRAMEHEIGHT_L 0x07 | 33 | #define PO1030_FRAMEHEIGHT_L 0x07 |
34 | #define PO1030_REG_WINDOWX_H 0x08 | 34 | #define PO1030_WINDOWX_H 0x08 |
35 | #define PO1030_REG_WINDOWX_L 0x09 | 35 | #define PO1030_WINDOWX_L 0x09 |
36 | #define PO1030_REG_WINDOWY_H 0x0a | 36 | #define PO1030_WINDOWY_H 0x0a |
37 | #define PO1030_REG_WINDOWY_L 0x0b | 37 | #define PO1030_WINDOWY_L 0x0b |
38 | #define PO1030_REG_WINDOWWIDTH_H 0x0c | 38 | #define PO1030_WINDOWWIDTH_H 0x0c |
39 | #define PO1030_REG_WINDOWWIDTH_L 0x0d | 39 | #define PO1030_WINDOWWIDTH_L 0x0d |
40 | #define PO1030_REG_WINDOWHEIGHT_H 0x0e | 40 | #define PO1030_WINDOWHEIGHT_H 0x0e |
41 | #define PO1030_REG_WINDOWHEIGHT_L 0x0f | 41 | #define PO1030_WINDOWHEIGHT_L 0x0f |
42 | 42 | ||
43 | #define PO1030_REG_GLOBALIBIAS 0x12 | 43 | #define PO1030_GLOBALIBIAS 0x12 |
44 | #define PO1030_REG_PIXELIBIAS 0x13 | 44 | #define PO1030_PIXELIBIAS 0x13 |
45 | 45 | ||
46 | #define PO1030_REG_GLOBALGAIN 0x15 | 46 | #define PO1030_GLOBALGAIN 0x15 |
47 | #define PO1030_REG_RED_GAIN 0x16 | 47 | #define PO1030_RED_GAIN 0x16 |
48 | #define PO1030_REG_GREEN_1_GAIN 0x17 | 48 | #define PO1030_GREEN_1_GAIN 0x17 |
49 | #define PO1030_REG_BLUE_GAIN 0x18 | 49 | #define PO1030_BLUE_GAIN 0x18 |
50 | #define PO1030_REG_GREEN_2_GAIN 0x19 | 50 | #define PO1030_GREEN_2_GAIN 0x19 |
51 | 51 | ||
52 | #define PO1030_REG_INTEGLINES_H 0x1a | 52 | #define PO1030_INTEGLINES_H 0x1a |
53 | #define PO1030_REG_INTEGLINES_M 0x1b | 53 | #define PO1030_INTEGLINES_M 0x1b |
54 | #define PO1030_REG_INTEGLINES_L 0x1c | 54 | #define PO1030_INTEGLINES_L 0x1c |
55 | 55 | ||
56 | #define PO1030_REG_CONTROL1 0x1d | 56 | #define PO1030_CONTROL1 0x1d |
57 | #define PO1030_REG_CONTROL2 0x1e | 57 | #define PO1030_CONTROL2 0x1e |
58 | #define PO1030_REG_CONTROL3 0x1f | 58 | #define PO1030_CONTROL3 0x1f |
59 | #define PO1030_REG_CONTROL4 0x20 | 59 | #define PO1030_CONTROL4 0x20 |
60 | 60 | ||
61 | #define PO1030_REG_PERIOD50_H 0x23 | 61 | #define PO1030_PERIOD50_H 0x23 |
62 | #define PO1030_REG_PERIOD50_L 0x24 | 62 | #define PO1030_PERIOD50_L 0x24 |
63 | #define PO1030_REG_PERIOD60_H 0x25 | 63 | #define PO1030_PERIOD60_H 0x25 |
64 | #define PO1030_REG_PERIOD60_L 0x26 | 64 | #define PO1030_PERIOD60_L 0x26 |
65 | #define PO1030_REG_REGCLK167 0x27 | 65 | #define PO1030_REGCLK167 0x27 |
66 | #define PO1030_REG_DELTA50 0x28 | 66 | #define PO1030_FLICKER_DELTA50 0x28 |
67 | #define PO1030_REG_DELTA60 0x29 | 67 | #define PO1030_FLICKERDELTA60 0x29 |
68 | 68 | ||
69 | #define PO1030_REG_ADCOFFSET 0x2c | 69 | #define PO1030_ADCOFFSET 0x2c |
70 | 70 | ||
71 | /* Gamma Correction Coeffs */ | 71 | /* Gamma Correction Coeffs */ |
72 | #define PO1030_REG_GC0 0x2d | 72 | #define PO1030_GC0 0x2d |
73 | #define PO1030_REG_GC1 0x2e | 73 | #define PO1030_GC1 0x2e |
74 | #define PO1030_REG_GC2 0x2f | 74 | #define PO1030_GC2 0x2f |
75 | #define PO1030_REG_GC3 0x30 | 75 | #define PO1030_GC3 0x30 |
76 | #define PO1030_REG_GC4 0x31 | 76 | #define PO1030_GC4 0x31 |
77 | #define PO1030_REG_GC5 0x32 | 77 | #define PO1030_GC5 0x32 |
78 | #define PO1030_REG_GC6 0x33 | 78 | #define PO1030_GC6 0x33 |
79 | #define PO1030_REG_GC7 0x34 | 79 | #define PO1030_GC7 0x34 |
80 | 80 | ||
81 | /* Color Transform Matrix */ | 81 | /* Color Transform Matrix */ |
82 | #define PO1030_REG_CT0 0x35 | 82 | #define PO1030_CT0 0x35 |
83 | #define PO1030_REG_CT1 0x36 | 83 | #define PO1030_CT1 0x36 |
84 | #define PO1030_REG_CT2 0x37 | 84 | #define PO1030_CT2 0x37 |
85 | #define PO1030_REG_CT3 0x38 | 85 | #define PO1030_CT3 0x38 |
86 | #define PO1030_REG_CT4 0x39 | 86 | #define PO1030_CT4 0x39 |
87 | #define PO1030_REG_CT5 0x3a | 87 | #define PO1030_CT5 0x3a |
88 | #define PO1030_REG_CT6 0x3b | 88 | #define PO1030_CT6 0x3b |
89 | #define PO1030_REG_CT7 0x3c | 89 | #define PO1030_CT7 0x3c |
90 | #define PO1030_REG_CT8 0x3d | 90 | #define PO1030_CT8 0x3d |
91 | 91 | ||
92 | #define PO1030_REG_AUTOCTRL1 0x3e | 92 | #define PO1030_AUTOCTRL1 0x3e |
93 | #define PO1030_REG_AUTOCTRL2 0x3f | 93 | #define PO1030_AUTOCTRL2 0x3f |
94 | 94 | ||
95 | #define PO1030_REG_YTARGET 0x40 | 95 | #define PO1030_YTARGET 0x40 |
96 | #define PO1030_REG_GLOBALGAINMIN 0x41 | 96 | #define PO1030_GLOBALGAINMIN 0x41 |
97 | #define PO1030_REG_GLOBALGAINMAX 0x42 | 97 | #define PO1030_GLOBALGAINMAX 0x42 |
98 | |||
99 | #define PO1030_AWB_RED_TUNING 0x47 | ||
100 | #define PO1030_AWB_BLUE_TUNING 0x48 | ||
98 | 101 | ||
99 | /* Output format control */ | 102 | /* Output format control */ |
100 | #define PO1030_REG_OUTFORMCTRL1 0x5a | 103 | #define PO1030_OUTFORMCTRL1 0x5a |
101 | #define PO1030_REG_OUTFORMCTRL2 0x5b | 104 | #define PO1030_OUTFORMCTRL2 0x5b |
102 | #define PO1030_REG_OUTFORMCTRL3 0x5c | 105 | #define PO1030_OUTFORMCTRL3 0x5c |
103 | #define PO1030_REG_OUTFORMCTRL4 0x5d | 106 | #define PO1030_OUTFORMCTRL4 0x5d |
104 | #define PO1030_REG_OUTFORMCTRL5 0x5e | 107 | #define PO1030_OUTFORMCTRL5 0x5e |
105 | 108 | ||
106 | /* Imaging coefficients */ | 109 | #define PO1030_EDGE_ENH_OFF 0x5f |
107 | #define PO1030_REG_YBRIGHT 0x73 | 110 | #define PO1030_EGA 0x60 |
108 | #define PO1030_REG_YCONTRAST 0x74 | ||
109 | #define PO1030_REG_YSATURATION 0x75 | ||
110 | 111 | ||
111 | #define PO1030_HFLIP (1 << 7) | 112 | #define PO1030_Cb_U_GAIN 0x63 |
112 | #define PO1030_VFLIP (1 << 6) | 113 | #define PO1030_Cr_V_GAIN 0x64 |
114 | |||
115 | #define PO1030_YCONTRAST 0x74 | ||
116 | #define PO1030_YSATURATION 0x75 | ||
117 | |||
118 | #define PO1030_HFLIP (1 << 7) | ||
119 | #define PO1030_VFLIP (1 << 6) | ||
120 | |||
121 | #define PO1030_HREF_ENABLE (1 << 6) | ||
122 | |||
123 | #define PO1030_RAW_RGB_BAYER 0x4 | ||
124 | |||
125 | #define PO1030_FRAME_EQUAL (1 << 3) | ||
126 | #define PO1030_AUTO_SUBSAMPLING (1 << 4) | ||
127 | |||
128 | #define PO1030_WEIGHT_WIN_2X (1 << 3) | ||
129 | |||
130 | #define PO1030_SHUTTER_MODE (1 << 6) | ||
131 | #define PO1030_AUTO_SUBSAMPLING (1 << 4) | ||
132 | #define PO1030_FRAME_EQUAL (1 << 3) | ||
133 | |||
134 | #define PO1030_SENSOR_RESET (1 << 5) | ||
135 | |||
136 | #define PO1030_SUBSAMPLING (1 << 6) | ||
113 | 137 | ||
114 | /*****************************************************************************/ | 138 | /*****************************************************************************/ |
115 | 139 | ||
116 | #define PO1030_GLOBAL_GAIN_DEFAULT 0x12 | 140 | #define PO1030_GLOBAL_GAIN_DEFAULT 0x12 |
117 | #define PO1030_EXPOSURE_DEFAULT 0x0085 | 141 | #define PO1030_EXPOSURE_DEFAULT 0x0085 |
118 | #define PO1030_BLUE_GAIN_DEFAULT 0x40 | 142 | #define PO1030_BLUE_GAIN_DEFAULT 0x36 |
119 | #define PO1030_RED_GAIN_DEFAULT 0x40 | 143 | #define PO1030_RED_GAIN_DEFAULT 0x36 |
144 | #define PO1030_GREEN_GAIN_DEFAULT 0x40 | ||
120 | 145 | ||
121 | /*****************************************************************************/ | 146 | /*****************************************************************************/ |
122 | 147 | ||
@@ -126,20 +151,8 @@ extern int dump_sensor; | |||
126 | 151 | ||
127 | int po1030_probe(struct sd *sd); | 152 | int po1030_probe(struct sd *sd); |
128 | int po1030_init(struct sd *sd); | 153 | int po1030_init(struct sd *sd); |
129 | int po1030_power_down(struct sd *sd); | 154 | int po1030_start(struct sd *sd); |
130 | 155 | void po1030_disconnect(struct sd *sd); | |
131 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
132 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
133 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
134 | int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
135 | int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
136 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
137 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
138 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
139 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
140 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
141 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
142 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
143 | 156 | ||
144 | static const struct m5602_sensor po1030 = { | 157 | static const struct m5602_sensor po1030 = { |
145 | .name = "PO1030", | 158 | .name = "PO1030", |
@@ -149,7 +162,8 @@ static const struct m5602_sensor po1030 = { | |||
149 | 162 | ||
150 | .probe = po1030_probe, | 163 | .probe = po1030_probe, |
151 | .init = po1030_init, | 164 | .init = po1030_init, |
152 | .power_down = po1030_power_down, | 165 | .start = po1030_start, |
166 | .disconnect = po1030_disconnect, | ||
153 | }; | 167 | }; |
154 | 168 | ||
155 | static const unsigned char preinit_po1030[][3] = | 169 | static const unsigned char preinit_po1030[][3] = |
@@ -159,248 +173,103 @@ static const unsigned char preinit_po1030[][3] = | |||
159 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 173 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
160 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 174 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
161 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | 175 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, |
162 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
163 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | 176 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, |
164 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
165 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | 177 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, |
166 | |||
167 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
168 | |||
169 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
170 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
171 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
172 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
173 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | ||
174 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
175 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
176 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
177 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
178 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | 178 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, |
179 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
180 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
181 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
182 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
183 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
184 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
185 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
186 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
187 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
188 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, | ||
189 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
190 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
191 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
192 | {BRIDGE, M5602_XB_SIG_INI, 0x02}, | ||
193 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
194 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
195 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, | ||
196 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87}, | ||
197 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
198 | |||
199 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
200 | |||
201 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 179 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
202 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | 180 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, |
203 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | 181 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, |
204 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | 182 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, |
205 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | 183 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, |
184 | |||
185 | {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)}, | ||
186 | |||
206 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | 187 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, |
207 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 188 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
208 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 189 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
209 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 190 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
210 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
211 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | 191 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, |
212 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 192 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
213 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00} | 193 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00} |
214 | }; | 194 | }; |
215 | 195 | ||
216 | static const unsigned char init_po1030[][4] = | 196 | static const unsigned char init_po1030[][3] = |
217 | { | 197 | { |
218 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | 198 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, |
219 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | 199 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, |
220 | /*sequence 1*/ | ||
221 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 200 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
222 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 201 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
223 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | 202 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, |
224 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
225 | |||
226 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | 203 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, |
227 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
228 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | 204 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, |
229 | /*end of sequence 1*/ | ||
230 | |||
231 | /*sequence 2 (same as stop sequence)*/ | ||
232 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
233 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
234 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
235 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
236 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
237 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | ||
238 | |||
239 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
240 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
241 | /*end of sequence 2*/ | ||
242 | 205 | ||
243 | /*sequence 5*/ | 206 | {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)}, |
244 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
245 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
246 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
247 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
248 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
249 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
250 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
251 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
252 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
256 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, | ||
257 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
258 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
259 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
260 | {BRIDGE, M5602_XB_SIG_INI, 0x02}, | ||
261 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
262 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
263 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, | ||
264 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87}, | ||
265 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
266 | /*end of sequence 5*/ | ||
267 | |||
268 | /*sequence 2 stop */ | ||
269 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
270 | 207 | ||
271 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 208 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
272 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | 209 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, |
273 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | 210 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, |
211 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
274 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | 212 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, |
275 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | 213 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, |
276 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | 214 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, |
277 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 215 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
278 | /*end of sequence 2 stop */ | ||
279 | |||
280 | /* --------------------------------- | ||
281 | * end of init - begin of start | ||
282 | * --------------------------------- */ | ||
283 | |||
284 | /*sequence 3*/ | ||
285 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
286 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
287 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
288 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
289 | /*end of sequence 3*/ | ||
290 | /*sequence 4*/ | ||
291 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 216 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
292 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | 217 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, |
293 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
294 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
295 | 218 | ||
296 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x04}, | 219 | {SENSOR, PO1030_AUTOCTRL2, 0x04}, |
220 | |||
221 | {SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER}, | ||
222 | {SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X}, | ||
223 | |||
224 | {SENSOR, PO1030_CONTROL2, 0x03}, | ||
225 | {SENSOR, 0x21, 0x90}, | ||
226 | {SENSOR, PO1030_YTARGET, 0x60}, | ||
227 | {SENSOR, 0x59, 0x13}, | ||
228 | {SENSOR, PO1030_OUTFORMCTRL1, PO1030_HREF_ENABLE}, | ||
229 | {SENSOR, PO1030_EDGE_ENH_OFF, 0x00}, | ||
230 | {SENSOR, PO1030_EGA, 0x80}, | ||
231 | {SENSOR, 0x78, 0x14}, | ||
232 | {SENSOR, 0x6f, 0x01}, | ||
233 | {SENSOR, PO1030_GLOBALGAINMAX, 0x14}, | ||
234 | {SENSOR, PO1030_Cb_U_GAIN, 0x38}, | ||
235 | {SENSOR, PO1030_Cr_V_GAIN, 0x38}, | ||
236 | {SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE | | ||
237 | PO1030_AUTO_SUBSAMPLING | | ||
238 | PO1030_FRAME_EQUAL}, | ||
239 | {SENSOR, PO1030_GC0, 0x10}, | ||
240 | {SENSOR, PO1030_GC1, 0x20}, | ||
241 | {SENSOR, PO1030_GC2, 0x40}, | ||
242 | {SENSOR, PO1030_GC3, 0x60}, | ||
243 | {SENSOR, PO1030_GC4, 0x80}, | ||
244 | {SENSOR, PO1030_GC5, 0xa0}, | ||
245 | {SENSOR, PO1030_GC6, 0xc0}, | ||
246 | {SENSOR, PO1030_GC7, 0xff}, | ||
297 | 247 | ||
298 | /* Set the width to 751 */ | 248 | /* Set the width to 751 */ |
299 | {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02}, | 249 | {SENSOR, PO1030_FRAMEWIDTH_H, 0x02}, |
300 | {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef}, | 250 | {SENSOR, PO1030_FRAMEWIDTH_L, 0xef}, |
301 | 251 | ||
302 | /* Set the height to 540 */ | 252 | /* Set the height to 540 */ |
303 | {SENSOR, PO1030_REG_FRAMEHEIGHT_H, 0x02}, | 253 | {SENSOR, PO1030_FRAMEHEIGHT_H, 0x02}, |
304 | {SENSOR, PO1030_REG_FRAMEHEIGHT_L, 0x1c}, | 254 | {SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c}, |
305 | 255 | ||
306 | /* Set the x window to 1 */ | 256 | /* Set the x window to 1 */ |
307 | {SENSOR, PO1030_REG_WINDOWX_H, 0x00}, | 257 | {SENSOR, PO1030_WINDOWX_H, 0x00}, |
308 | {SENSOR, PO1030_REG_WINDOWX_L, 0x01}, | 258 | {SENSOR, PO1030_WINDOWX_L, 0x01}, |
309 | 259 | ||
310 | /* Set the y window to 1 */ | 260 | /* Set the y window to 1 */ |
311 | {SENSOR, PO1030_REG_WINDOWY_H, 0x00}, | 261 | {SENSOR, PO1030_WINDOWY_H, 0x00}, |
312 | {SENSOR, PO1030_REG_WINDOWY_L, 0x01}, | 262 | {SENSOR, PO1030_WINDOWY_L, 0x01}, |
313 | |||
314 | {SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02}, | ||
315 | {SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87}, | ||
316 | {SENSOR, PO1030_REG_WINDOWHEIGHT_H, 0x01}, | ||
317 | {SENSOR, PO1030_REG_WINDOWHEIGHT_L, 0xe3}, | ||
318 | |||
319 | {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04}, | ||
320 | {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04}, | ||
321 | {SENSOR, PO1030_REG_AUTOCTRL1, 0x08}, | ||
322 | {SENSOR, PO1030_REG_CONTROL2, 0x03}, | ||
323 | {SENSOR, 0x21, 0x90}, | ||
324 | {SENSOR, PO1030_REG_YTARGET, 0x60}, | ||
325 | {SENSOR, 0x59, 0x13}, | ||
326 | {SENSOR, PO1030_REG_OUTFORMCTRL1, 0x40}, | ||
327 | {SENSOR, 0x5f, 0x00}, | ||
328 | {SENSOR, 0x60, 0x80}, | ||
329 | {SENSOR, 0x78, 0x14}, | ||
330 | {SENSOR, 0x6f, 0x01}, | ||
331 | {SENSOR, PO1030_REG_CONTROL1, 0x18}, | ||
332 | {SENSOR, PO1030_REG_GLOBALGAINMAX, 0x14}, | ||
333 | {SENSOR, 0x63, 0x38}, | ||
334 | {SENSOR, 0x64, 0x38}, | ||
335 | {SENSOR, PO1030_REG_CONTROL1, 0x58}, | ||
336 | {SENSOR, PO1030_REG_RED_GAIN, 0x30}, | ||
337 | {SENSOR, PO1030_REG_GREEN_1_GAIN, 0x30}, | ||
338 | {SENSOR, PO1030_REG_BLUE_GAIN, 0x30}, | ||
339 | {SENSOR, PO1030_REG_GREEN_2_GAIN, 0x30}, | ||
340 | {SENSOR, PO1030_REG_GC0, 0x10}, | ||
341 | {SENSOR, PO1030_REG_GC1, 0x20}, | ||
342 | {SENSOR, PO1030_REG_GC2, 0x40}, | ||
343 | {SENSOR, PO1030_REG_GC3, 0x60}, | ||
344 | {SENSOR, PO1030_REG_GC4, 0x80}, | ||
345 | {SENSOR, PO1030_REG_GC5, 0xa0}, | ||
346 | {SENSOR, PO1030_REG_GC6, 0xc0}, | ||
347 | {SENSOR, PO1030_REG_GC7, 0xff}, | ||
348 | /*end of sequence 4*/ | ||
349 | /*sequence 5*/ | ||
350 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
351 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
352 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
353 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
354 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
355 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
356 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
357 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
358 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
359 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
360 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
361 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
362 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, | ||
363 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
364 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
365 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
366 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
367 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
368 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
369 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, | ||
370 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7e}, | ||
371 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
372 | /*end of sequence 5*/ | ||
373 | |||
374 | /*sequence 6*/ | ||
375 | /* Changing 40 in f0 the image becomes green in bayer mode and red in | ||
376 | * rgb mode */ | ||
377 | {SENSOR, PO1030_REG_RED_GAIN, PO1030_RED_GAIN_DEFAULT}, | ||
378 | /* in changing 40 in f0 the image becomes green in bayer mode and red in | ||
379 | * rgb mode */ | ||
380 | {SENSOR, PO1030_REG_BLUE_GAIN, PO1030_BLUE_GAIN_DEFAULT}, | ||
381 | 263 | ||
382 | /* with a very low lighted environment increase the exposure but | 264 | /* with a very low lighted environment increase the exposure but |
383 | * decrease the FPS (Frame Per Second) */ | 265 | * decrease the FPS (Frame Per Second) */ |
384 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 266 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
385 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 267 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
386 | 268 | ||
387 | /* Controls high exposure more than SENSOR_LOW_EXPOSURE, use only in | 269 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
388 | * low lighted environment (f0 is more than ff ?)*/ | 270 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, |
389 | {SENSOR, PO1030_REG_INTEGLINES_H, ((PO1030_EXPOSURE_DEFAULT >> 2) | 271 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, |
390 | & 0xff)}, | 272 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, |
391 | |||
392 | /* Controls middle exposure, use only in high lighted environment */ | ||
393 | {SENSOR, PO1030_REG_INTEGLINES_M, PO1030_EXPOSURE_DEFAULT & 0xff}, | ||
394 | |||
395 | /* Controls clarity (not sure) */ | ||
396 | {SENSOR, PO1030_REG_INTEGLINES_L, 0x00}, | ||
397 | /* Controls gain (the image is more lighted) */ | ||
398 | {SENSOR, PO1030_REG_GLOBALGAIN, PO1030_GLOBAL_GAIN_DEFAULT}, | ||
399 | |||
400 | /* Sets the width */ | ||
401 | {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02}, | ||
402 | {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef} | ||
403 | /*end of sequence 6*/ | ||
404 | }; | 273 | }; |
405 | 274 | ||
406 | #endif | 275 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index 4306d596056d..191bcd718979 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c | |||
@@ -18,6 +18,19 @@ | |||
18 | 18 | ||
19 | #include "m5602_s5k4aa.h" | 19 | #include "m5602_s5k4aa.h" |
20 | 20 | ||
21 | static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
22 | static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
29 | static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val); | ||
30 | static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val); | ||
31 | static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | |||
21 | static | 34 | static |
22 | const | 35 | const |
23 | struct dmi_system_id s5k4aa_vflip_dmi_table[] = { | 36 | struct dmi_system_id s5k4aa_vflip_dmi_table[] = { |
@@ -46,6 +59,18 @@ static | |||
46 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), | 59 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), |
47 | DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700") | 60 | DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700") |
48 | } | 61 | } |
62 | }, { | ||
63 | .ident = "MSI L735", | ||
64 | .matches = { | ||
65 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), | ||
66 | DMI_MATCH(DMI_PRODUCT_NAME, "MS-1717X") | ||
67 | } | ||
68 | }, { | ||
69 | .ident = "Lenovo Y300", | ||
70 | .matches = { | ||
71 | DMI_MATCH(DMI_SYS_VENDOR, "L3000 Y300"), | ||
72 | DMI_MATCH(DMI_PRODUCT_NAME, "Y300") | ||
73 | } | ||
49 | }, | 74 | }, |
50 | { } | 75 | { } |
51 | }; | 76 | }; |
@@ -61,10 +86,22 @@ static struct v4l2_pix_format s5k4aa_modes[] = { | |||
61 | .bytesperline = 640, | 86 | .bytesperline = 640, |
62 | .colorspace = V4L2_COLORSPACE_SRGB, | 87 | .colorspace = V4L2_COLORSPACE_SRGB, |
63 | .priv = 0 | 88 | .priv = 0 |
89 | }, | ||
90 | { | ||
91 | 1280, | ||
92 | 1024, | ||
93 | V4L2_PIX_FMT_SBGGR8, | ||
94 | V4L2_FIELD_NONE, | ||
95 | .sizeimage = | ||
96 | 1280 * 1024, | ||
97 | .bytesperline = 1280, | ||
98 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
99 | .priv = 0 | ||
64 | } | 100 | } |
65 | }; | 101 | }; |
66 | 102 | ||
67 | const static struct ctrl s5k4aa_ctrls[] = { | 103 | static const struct ctrl s5k4aa_ctrls[] = { |
104 | #define VFLIP_IDX 0 | ||
68 | { | 105 | { |
69 | { | 106 | { |
70 | .id = V4L2_CID_VFLIP, | 107 | .id = V4L2_CID_VFLIP, |
@@ -77,8 +114,9 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
77 | }, | 114 | }, |
78 | .set = s5k4aa_set_vflip, | 115 | .set = s5k4aa_set_vflip, |
79 | .get = s5k4aa_get_vflip | 116 | .get = s5k4aa_get_vflip |
80 | 117 | }, | |
81 | }, { | 118 | #define HFLIP_IDX 1 |
119 | { | ||
82 | { | 120 | { |
83 | .id = V4L2_CID_HFLIP, | 121 | .id = V4L2_CID_HFLIP, |
84 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 122 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -90,8 +128,9 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
90 | }, | 128 | }, |
91 | .set = s5k4aa_set_hflip, | 129 | .set = s5k4aa_set_hflip, |
92 | .get = s5k4aa_get_hflip | 130 | .get = s5k4aa_get_hflip |
93 | 131 | }, | |
94 | }, { | 132 | #define GAIN_IDX 2 |
133 | { | ||
95 | { | 134 | { |
96 | .id = V4L2_CID_GAIN, | 135 | .id = V4L2_CID_GAIN, |
97 | .type = V4L2_CTRL_TYPE_INTEGER, | 136 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -99,12 +138,14 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
99 | .minimum = 0, | 138 | .minimum = 0, |
100 | .maximum = 127, | 139 | .maximum = 127, |
101 | .step = 1, | 140 | .step = 1, |
102 | .default_value = 0xa0, | 141 | .default_value = S5K4AA_DEFAULT_GAIN, |
103 | .flags = V4L2_CTRL_FLAG_SLIDER | 142 | .flags = V4L2_CTRL_FLAG_SLIDER |
104 | }, | 143 | }, |
105 | .set = s5k4aa_set_gain, | 144 | .set = s5k4aa_set_gain, |
106 | .get = s5k4aa_get_gain | 145 | .get = s5k4aa_get_gain |
107 | }, { | 146 | }, |
147 | #define EXPOSURE_IDX 3 | ||
148 | { | ||
108 | { | 149 | { |
109 | .id = V4L2_CID_EXPOSURE, | 150 | .id = V4L2_CID_EXPOSURE, |
110 | .type = V4L2_CTRL_TYPE_INTEGER, | 151 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -117,7 +158,36 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
117 | }, | 158 | }, |
118 | .set = s5k4aa_set_exposure, | 159 | .set = s5k4aa_set_exposure, |
119 | .get = s5k4aa_get_exposure | 160 | .get = s5k4aa_get_exposure |
120 | } | 161 | }, |
162 | #define NOISE_SUPP_IDX 4 | ||
163 | { | ||
164 | { | ||
165 | .id = V4L2_CID_PRIVATE_BASE, | ||
166 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
167 | .name = "Noise suppression (smoothing)", | ||
168 | .minimum = 0, | ||
169 | .maximum = 1, | ||
170 | .step = 1, | ||
171 | .default_value = 1, | ||
172 | }, | ||
173 | .set = s5k4aa_set_noise, | ||
174 | .get = s5k4aa_get_noise | ||
175 | }, | ||
176 | #define BRIGHTNESS_IDX 5 | ||
177 | { | ||
178 | { | ||
179 | .id = V4L2_CID_BRIGHTNESS, | ||
180 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
181 | .name = "Brightness", | ||
182 | .minimum = 0, | ||
183 | .maximum = 0x1f, | ||
184 | .step = 1, | ||
185 | .default_value = S5K4AA_DEFAULT_BRIGHTNESS, | ||
186 | }, | ||
187 | .set = s5k4aa_set_brightness, | ||
188 | .get = s5k4aa_get_brightness | ||
189 | }, | ||
190 | |||
121 | }; | 191 | }; |
122 | 192 | ||
123 | static void s5k4aa_dump_registers(struct sd *sd); | 193 | static void s5k4aa_dump_registers(struct sd *sd); |
@@ -127,6 +197,7 @@ int s5k4aa_probe(struct sd *sd) | |||
127 | u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | 197 | u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
128 | const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; | 198 | const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; |
129 | int i, err = 0; | 199 | int i, err = 0; |
200 | s32 *sensor_settings; | ||
130 | 201 | ||
131 | if (force_sensor) { | 202 | if (force_sensor) { |
132 | if (force_sensor == S5K4AA_SENSOR) { | 203 | if (force_sensor == S5K4AA_SENSOR) { |
@@ -185,10 +256,20 @@ int s5k4aa_probe(struct sd *sd) | |||
185 | info("Detected a s5k4aa sensor"); | 256 | info("Detected a s5k4aa sensor"); |
186 | 257 | ||
187 | sensor_found: | 258 | sensor_found: |
259 | sensor_settings = kmalloc( | ||
260 | ARRAY_SIZE(s5k4aa_ctrls) * sizeof(s32), GFP_KERNEL); | ||
261 | if (!sensor_settings) | ||
262 | return -ENOMEM; | ||
263 | |||
188 | sd->gspca_dev.cam.cam_mode = s5k4aa_modes; | 264 | sd->gspca_dev.cam.cam_mode = s5k4aa_modes; |
189 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); | 265 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); |
190 | sd->desc->ctrls = s5k4aa_ctrls; | 266 | sd->desc->ctrls = s5k4aa_ctrls; |
191 | sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); | 267 | sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); |
268 | |||
269 | for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++) | ||
270 | sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value; | ||
271 | sd->sensor_priv = sensor_settings; | ||
272 | |||
192 | return 0; | 273 | return 0; |
193 | } | 274 | } |
194 | 275 | ||
@@ -197,9 +278,45 @@ int s5k4aa_start(struct sd *sd) | |||
197 | int i, err = 0; | 278 | int i, err = 0; |
198 | u8 data[2]; | 279 | u8 data[2]; |
199 | struct cam *cam = &sd->gspca_dev.cam; | 280 | struct cam *cam = &sd->gspca_dev.cam; |
281 | s32 *sensor_settings = sd->sensor_priv; | ||
282 | |||
283 | switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) { | ||
284 | case 1280: | ||
285 | PDEBUG(D_V4L2, "Configuring camera for SXGA mode"); | ||
286 | |||
287 | for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) { | ||
288 | switch (SXGA_s5k4aa[i][0]) { | ||
289 | case BRIDGE: | ||
290 | err = m5602_write_bridge(sd, | ||
291 | SXGA_s5k4aa[i][1], | ||
292 | SXGA_s5k4aa[i][2]); | ||
293 | break; | ||
294 | |||
295 | case SENSOR: | ||
296 | data[0] = SXGA_s5k4aa[i][2]; | ||
297 | err = m5602_write_sensor(sd, | ||
298 | SXGA_s5k4aa[i][1], | ||
299 | data, 1); | ||
300 | break; | ||
301 | |||
302 | case SENSOR_LONG: | ||
303 | data[0] = SXGA_s5k4aa[i][2]; | ||
304 | data[1] = SXGA_s5k4aa[i][3]; | ||
305 | err = m5602_write_sensor(sd, | ||
306 | SXGA_s5k4aa[i][1], | ||
307 | data, 2); | ||
308 | break; | ||
309 | |||
310 | default: | ||
311 | err("Invalid stream command, exiting init"); | ||
312 | return -EINVAL; | ||
313 | } | ||
314 | } | ||
315 | err = s5k4aa_set_noise(&sd->gspca_dev, 0); | ||
316 | if (err < 0) | ||
317 | return err; | ||
318 | break; | ||
200 | 319 | ||
201 | switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) | ||
202 | { | ||
203 | case 640: | 320 | case 640: |
204 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); | 321 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); |
205 | 322 | ||
@@ -231,8 +348,37 @@ int s5k4aa_start(struct sd *sd) | |||
231 | return -EINVAL; | 348 | return -EINVAL; |
232 | } | 349 | } |
233 | } | 350 | } |
351 | err = s5k4aa_set_noise(&sd->gspca_dev, 1); | ||
352 | if (err < 0) | ||
353 | return err; | ||
354 | break; | ||
234 | } | 355 | } |
235 | return err; | 356 | if (err < 0) |
357 | return err; | ||
358 | |||
359 | err = s5k4aa_set_exposure(&sd->gspca_dev, | ||
360 | sensor_settings[EXPOSURE_IDX]); | ||
361 | if (err < 0) | ||
362 | return err; | ||
363 | |||
364 | err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
365 | if (err < 0) | ||
366 | return err; | ||
367 | |||
368 | err = s5k4aa_set_brightness(&sd->gspca_dev, | ||
369 | sensor_settings[BRIGHTNESS_IDX]); | ||
370 | if (err < 0) | ||
371 | return err; | ||
372 | |||
373 | err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]); | ||
374 | if (err < 0) | ||
375 | return err; | ||
376 | |||
377 | err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); | ||
378 | if (err < 0) | ||
379 | return err; | ||
380 | |||
381 | return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
236 | } | 382 | } |
237 | 383 | ||
238 | int s5k4aa_init(struct sd *sd) | 384 | int s5k4aa_init(struct sd *sd) |
@@ -270,62 +416,28 @@ int s5k4aa_init(struct sd *sd) | |||
270 | if (dump_sensor) | 416 | if (dump_sensor) |
271 | s5k4aa_dump_registers(sd); | 417 | s5k4aa_dump_registers(sd); |
272 | 418 | ||
273 | if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) { | 419 | return err; |
274 | u8 data = 0x02; | ||
275 | info("vertical flip quirk active"); | ||
276 | m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
277 | m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
278 | data |= S5K4AA_RM_V_FLIP; | ||
279 | data &= ~S5K4AA_RM_H_FLIP; | ||
280 | m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
281 | |||
282 | /* Decrement COLSTART to preserve color order (BGGR) */ | ||
283 | m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
284 | data--; | ||
285 | m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
286 | |||
287 | /* Increment ROWSTART to preserve color order (BGGR) */ | ||
288 | m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
289 | data++; | ||
290 | m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
291 | } | ||
292 | |||
293 | return (err < 0) ? err : 0; | ||
294 | } | ||
295 | |||
296 | int s5k4aa_power_down(struct sd *sd) | ||
297 | { | ||
298 | return 0; | ||
299 | } | 420 | } |
300 | 421 | ||
301 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 422 | static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
302 | { | 423 | { |
303 | struct sd *sd = (struct sd *) gspca_dev; | 424 | struct sd *sd = (struct sd *) gspca_dev; |
304 | u8 data = S5K4AA_PAGE_MAP_2; | 425 | s32 *sensor_settings = sd->sensor_priv; |
305 | int err; | ||
306 | |||
307 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
308 | if (err < 0) | ||
309 | return err; | ||
310 | 426 | ||
311 | err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); | 427 | *val = sensor_settings[EXPOSURE_IDX]; |
312 | if (err < 0) | ||
313 | return err; | ||
314 | |||
315 | *val = data << 8; | ||
316 | err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); | ||
317 | *val |= data; | ||
318 | PDEBUG(D_V4L2, "Read exposure %d", *val); | 428 | PDEBUG(D_V4L2, "Read exposure %d", *val); |
319 | 429 | ||
320 | return err; | 430 | return 0; |
321 | } | 431 | } |
322 | 432 | ||
323 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 433 | static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
324 | { | 434 | { |
325 | struct sd *sd = (struct sd *) gspca_dev; | 435 | struct sd *sd = (struct sd *) gspca_dev; |
436 | s32 *sensor_settings = sd->sensor_priv; | ||
326 | u8 data = S5K4AA_PAGE_MAP_2; | 437 | u8 data = S5K4AA_PAGE_MAP_2; |
327 | int err; | 438 | int err; |
328 | 439 | ||
440 | sensor_settings[EXPOSURE_IDX] = val; | ||
329 | PDEBUG(D_V4L2, "Set exposure to %d", val); | 441 | PDEBUG(D_V4L2, "Set exposure to %d", val); |
330 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 442 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
331 | if (err < 0) | 443 | if (err < 0) |
@@ -340,29 +452,26 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
340 | return err; | 452 | return err; |
341 | } | 453 | } |
342 | 454 | ||
343 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 455 | static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
344 | { | 456 | { |
345 | struct sd *sd = (struct sd *) gspca_dev; | 457 | struct sd *sd = (struct sd *) gspca_dev; |
346 | u8 data = S5K4AA_PAGE_MAP_2; | 458 | s32 *sensor_settings = sd->sensor_priv; |
347 | int err; | ||
348 | |||
349 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
350 | if (err < 0) | ||
351 | return err; | ||
352 | 459 | ||
353 | err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 460 | *val = sensor_settings[VFLIP_IDX]; |
354 | *val = (data & S5K4AA_RM_V_FLIP) >> 7; | ||
355 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | 461 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
356 | 462 | ||
357 | return err; | 463 | return 0; |
358 | } | 464 | } |
359 | 465 | ||
360 | int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 466 | static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
361 | { | 467 | { |
362 | struct sd *sd = (struct sd *) gspca_dev; | 468 | struct sd *sd = (struct sd *) gspca_dev; |
469 | s32 *sensor_settings = sd->sensor_priv; | ||
363 | u8 data = S5K4AA_PAGE_MAP_2; | 470 | u8 data = S5K4AA_PAGE_MAP_2; |
364 | int err; | 471 | int err; |
365 | 472 | ||
473 | sensor_settings[VFLIP_IDX] = val; | ||
474 | |||
366 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 475 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
367 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 476 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
368 | if (err < 0) | 477 | if (err < 0) |
@@ -370,56 +479,48 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
370 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 479 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
371 | if (err < 0) | 480 | if (err < 0) |
372 | return err; | 481 | return err; |
373 | data = ((data & ~S5K4AA_RM_V_FLIP) | 482 | |
374 | | ((val & 0x01) << 7)); | 483 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
375 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
376 | if (err < 0) | 484 | if (err < 0) |
377 | return err; | 485 | return err; |
378 | 486 | ||
379 | if (val) { | 487 | if (dmi_check_system(s5k4aa_vflip_dmi_table)) |
380 | err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | 488 | val = !val; |
381 | if (err < 0) | ||
382 | return err; | ||
383 | |||
384 | data++; | ||
385 | err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
386 | } else { | ||
387 | err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
388 | if (err < 0) | ||
389 | return err; | ||
390 | 489 | ||
391 | data--; | 490 | data = ((data & ~S5K4AA_RM_V_FLIP) | ((val & 0x01) << 7)); |
392 | err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | 491 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
393 | } | 492 | if (err < 0) |
493 | return err; | ||
394 | 494 | ||
495 | err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
496 | if (err < 0) | ||
497 | return err; | ||
498 | data = (data & 0xfe) | !val; | ||
499 | err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
395 | return err; | 500 | return err; |
396 | } | 501 | } |
397 | 502 | ||
398 | int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 503 | static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
399 | { | 504 | { |
400 | struct sd *sd = (struct sd *) gspca_dev; | 505 | struct sd *sd = (struct sd *) gspca_dev; |
401 | u8 data = S5K4AA_PAGE_MAP_2; | 506 | s32 *sensor_settings = sd->sensor_priv; |
402 | int err; | ||
403 | |||
404 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
405 | if (err < 0) | ||
406 | return err; | ||
407 | 507 | ||
408 | err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 508 | *val = sensor_settings[HFLIP_IDX]; |
409 | *val = (data & S5K4AA_RM_H_FLIP) >> 6; | ||
410 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | 509 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
411 | 510 | ||
412 | return err; | 511 | return 0; |
413 | } | 512 | } |
414 | 513 | ||
415 | int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 514 | static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
416 | { | 515 | { |
417 | struct sd *sd = (struct sd *) gspca_dev; | 516 | struct sd *sd = (struct sd *) gspca_dev; |
517 | s32 *sensor_settings = sd->sensor_priv; | ||
418 | u8 data = S5K4AA_PAGE_MAP_2; | 518 | u8 data = S5K4AA_PAGE_MAP_2; |
419 | int err; | 519 | int err; |
420 | 520 | ||
421 | PDEBUG(D_V4L2, "Set horizontal flip to %d", | 521 | sensor_settings[HFLIP_IDX] = val; |
422 | val); | 522 | |
523 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | ||
423 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 524 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
424 | if (err < 0) | 525 | if (err < 0) |
425 | return err; | 526 | return err; |
@@ -427,62 +528,116 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
427 | if (err < 0) | 528 | if (err < 0) |
428 | return err; | 529 | return err; |
429 | 530 | ||
531 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
532 | if (err < 0) | ||
533 | return err; | ||
534 | |||
535 | if (dmi_check_system(s5k4aa_vflip_dmi_table)) | ||
536 | val = !val; | ||
537 | |||
430 | data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); | 538 | data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); |
431 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 539 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
432 | if (err < 0) | 540 | if (err < 0) |
433 | return err; | 541 | return err; |
434 | 542 | ||
435 | if (val) { | 543 | err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); |
436 | err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | 544 | if (err < 0) |
437 | if (err < 0) | 545 | return err; |
438 | return err; | 546 | data = (data & 0xfe) | !val; |
439 | data++; | 547 | err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); |
440 | err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
441 | if (err < 0) | ||
442 | return err; | ||
443 | } else { | ||
444 | err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
445 | if (err < 0) | ||
446 | return err; | ||
447 | data--; | ||
448 | err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
449 | } | ||
450 | |||
451 | return err; | 548 | return err; |
452 | } | 549 | } |
453 | 550 | ||
454 | int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 551 | static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
552 | { | ||
553 | struct sd *sd = (struct sd *) gspca_dev; | ||
554 | s32 *sensor_settings = sd->sensor_priv; | ||
555 | |||
556 | *val = sensor_settings[GAIN_IDX]; | ||
557 | PDEBUG(D_V4L2, "Read gain %d", *val); | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
455 | { | 562 | { |
456 | struct sd *sd = (struct sd *) gspca_dev; | 563 | struct sd *sd = (struct sd *) gspca_dev; |
564 | s32 *sensor_settings = sd->sensor_priv; | ||
457 | u8 data = S5K4AA_PAGE_MAP_2; | 565 | u8 data = S5K4AA_PAGE_MAP_2; |
458 | int err; | 566 | int err; |
459 | 567 | ||
568 | sensor_settings[GAIN_IDX] = val; | ||
569 | |||
570 | PDEBUG(D_V4L2, "Set gain to %d", val); | ||
460 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 571 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
461 | if (err < 0) | 572 | if (err < 0) |
462 | return err; | 573 | return err; |
463 | 574 | ||
464 | err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); | 575 | data = val & 0xff; |
465 | *val = data; | 576 | err = m5602_write_sensor(sd, S5K4AA_GAIN, &data, 1); |
466 | PDEBUG(D_V4L2, "Read gain %d", *val); | ||
467 | 577 | ||
468 | return err; | 578 | return err; |
469 | } | 579 | } |
470 | 580 | ||
471 | int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 581 | static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) |
582 | { | ||
583 | struct sd *sd = (struct sd *) gspca_dev; | ||
584 | s32 *sensor_settings = sd->sensor_priv; | ||
585 | |||
586 | *val = sensor_settings[BRIGHTNESS_IDX]; | ||
587 | PDEBUG(D_V4L2, "Read brightness %d", *val); | ||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | ||
472 | { | 592 | { |
473 | struct sd *sd = (struct sd *) gspca_dev; | 593 | struct sd *sd = (struct sd *) gspca_dev; |
594 | s32 *sensor_settings = sd->sensor_priv; | ||
474 | u8 data = S5K4AA_PAGE_MAP_2; | 595 | u8 data = S5K4AA_PAGE_MAP_2; |
475 | int err; | 596 | int err; |
476 | 597 | ||
477 | PDEBUG(D_V4L2, "Set gain to %d", val); | 598 | sensor_settings[BRIGHTNESS_IDX] = val; |
599 | |||
600 | PDEBUG(D_V4L2, "Set brightness to %d", val); | ||
478 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 601 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
479 | if (err < 0) | 602 | if (err < 0) |
480 | return err; | 603 | return err; |
481 | 604 | ||
482 | data = val & 0xff; | 605 | data = val & 0xff; |
483 | err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1); | 606 | return m5602_write_sensor(sd, S5K4AA_BRIGHTNESS, &data, 1); |
607 | } | ||
484 | 608 | ||
485 | return err; | 609 | static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val) |
610 | { | ||
611 | struct sd *sd = (struct sd *) gspca_dev; | ||
612 | s32 *sensor_settings = sd->sensor_priv; | ||
613 | |||
614 | *val = sensor_settings[NOISE_SUPP_IDX]; | ||
615 | PDEBUG(D_V4L2, "Read noise %d", *val); | ||
616 | return 0; | ||
617 | } | ||
618 | |||
619 | static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val) | ||
620 | { | ||
621 | struct sd *sd = (struct sd *) gspca_dev; | ||
622 | s32 *sensor_settings = sd->sensor_priv; | ||
623 | u8 data = S5K4AA_PAGE_MAP_2; | ||
624 | int err; | ||
625 | |||
626 | sensor_settings[NOISE_SUPP_IDX] = val; | ||
627 | |||
628 | PDEBUG(D_V4L2, "Set noise to %d", val); | ||
629 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
630 | if (err < 0) | ||
631 | return err; | ||
632 | |||
633 | data = val & 0x01; | ||
634 | return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1); | ||
635 | } | ||
636 | |||
637 | void s5k4aa_disconnect(struct sd *sd) | ||
638 | { | ||
639 | sd->sensor = NULL; | ||
640 | kfree(sd->sensor_priv); | ||
486 | } | 641 | } |
487 | 642 | ||
488 | static void s5k4aa_dump_registers(struct sd *sd) | 643 | static void s5k4aa_dump_registers(struct sd *sd) |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h index ca854d4f9475..4440da4e7f0f 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h | |||
@@ -47,8 +47,9 @@ | |||
47 | #define S5K4AA_H_BLANK_LO__ 0x1e | 47 | #define S5K4AA_H_BLANK_LO__ 0x1e |
48 | #define S5K4AA_EXPOSURE_HI 0x17 | 48 | #define S5K4AA_EXPOSURE_HI 0x17 |
49 | #define S5K4AA_EXPOSURE_LO 0x18 | 49 | #define S5K4AA_EXPOSURE_LO 0x18 |
50 | #define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */ | 50 | #define S5K4AA_BRIGHTNESS 0x1f /* (digital?) gain : 5 bits */ |
51 | #define S5K4AA_GAIN_2 0x20 /* (analogue?) gain : 7 bits */ | 51 | #define S5K4AA_GAIN 0x20 /* (analogue?) gain : 7 bits */ |
52 | #define S5K4AA_NOISE_SUPP 0x37 | ||
52 | 53 | ||
53 | #define S5K4AA_RM_ROW_SKIP_4X 0x08 | 54 | #define S5K4AA_RM_ROW_SKIP_4X 0x08 |
54 | #define S5K4AA_RM_ROW_SKIP_2X 0x04 | 55 | #define S5K4AA_RM_ROW_SKIP_2X 0x04 |
@@ -57,6 +58,9 @@ | |||
57 | #define S5K4AA_RM_H_FLIP 0x40 | 58 | #define S5K4AA_RM_H_FLIP 0x40 |
58 | #define S5K4AA_RM_V_FLIP 0x80 | 59 | #define S5K4AA_RM_V_FLIP 0x80 |
59 | 60 | ||
61 | #define S5K4AA_DEFAULT_GAIN 0x5f | ||
62 | #define S5K4AA_DEFAULT_BRIGHTNESS 0x10 | ||
63 | |||
60 | /*****************************************************************************/ | 64 | /*****************************************************************************/ |
61 | 65 | ||
62 | /* Kernel module parameters */ | 66 | /* Kernel module parameters */ |
@@ -66,25 +70,17 @@ extern int dump_sensor; | |||
66 | int s5k4aa_probe(struct sd *sd); | 70 | int s5k4aa_probe(struct sd *sd); |
67 | int s5k4aa_init(struct sd *sd); | 71 | int s5k4aa_init(struct sd *sd); |
68 | int s5k4aa_start(struct sd *sd); | 72 | int s5k4aa_start(struct sd *sd); |
69 | int s5k4aa_power_down(struct sd *sd); | 73 | void s5k4aa_disconnect(struct sd *sd); |
70 | |||
71 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
72 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
73 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
74 | int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
75 | int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
76 | int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
77 | int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
78 | int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
79 | 74 | ||
80 | static const struct m5602_sensor s5k4aa = { | 75 | static const struct m5602_sensor s5k4aa = { |
81 | .name = "S5K4AA", | 76 | .name = "S5K4AA", |
77 | .i2c_slave_id = 0x5a, | ||
78 | .i2c_regW = 2, | ||
79 | |||
82 | .probe = s5k4aa_probe, | 80 | .probe = s5k4aa_probe, |
83 | .init = s5k4aa_init, | 81 | .init = s5k4aa_init, |
84 | .start = s5k4aa_start, | 82 | .start = s5k4aa_start, |
85 | .power_down = s5k4aa_power_down, | 83 | .disconnect = s5k4aa_disconnect, |
86 | .i2c_slave_id = 0x5a, | ||
87 | .i2c_regW = 2, | ||
88 | }; | 84 | }; |
89 | 85 | ||
90 | static const unsigned char preinit_s5k4aa[][4] = | 86 | static const unsigned char preinit_s5k4aa[][4] = |
@@ -179,30 +175,12 @@ static const unsigned char init_s5k4aa[][4] = | |||
179 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 175 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
180 | {SENSOR, 0x0c, 0x05, 0x00}, | 176 | {SENSOR, 0x0c, 0x05, 0x00}, |
181 | {SENSOR, 0x02, 0x0e, 0x00}, | 177 | {SENSOR, 0x02, 0x0e, 0x00}, |
182 | {SENSOR, S5K4AA_GAIN_1, 0x0f, 0x00}, | ||
183 | {SENSOR, S5K4AA_GAIN_2, 0x00, 0x00}, | ||
184 | {SENSOR, S5K4AA_GLOBAL_GAIN__, 0x01, 0x00}, | ||
185 | {SENSOR, 0x11, 0x00, 0x00}, | ||
186 | {SENSOR, 0x12, 0x00, 0x00}, | ||
187 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | ||
188 | {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00}, | 178 | {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00}, |
189 | {SENSOR, 0x37, 0x00, 0x00}, | 179 | {SENSOR, 0x37, 0x00, 0x00}, |
190 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, | 180 | }; |
191 | {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, | ||
192 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, | ||
193 | {SENSOR, S5K4AA_COLSTART_LO, 0x0b, 0x00}, | ||
194 | {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00}, | ||
195 | {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc4, 0x00}, | ||
196 | {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, | ||
197 | {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x08, 0x00}, | ||
198 | {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00}, | ||
199 | {SENSOR, S5K4AA_H_BLANK_LO__, 0x48, 0x00}, | ||
200 | {SENSOR, S5K4AA_EXPOSURE_HI, 0x00, 0x00}, | ||
201 | {SENSOR, S5K4AA_EXPOSURE_LO, 0x43, 0x00}, | ||
202 | {SENSOR, 0x11, 0x04, 0x00}, | ||
203 | {SENSOR, 0x12, 0xc3, 0x00}, | ||
204 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | ||
205 | 181 | ||
182 | static const unsigned char VGA_s5k4aa[][4] = | ||
183 | { | ||
206 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 184 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
207 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 185 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
208 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 186 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -238,7 +216,7 @@ static const unsigned char init_s5k4aa[][4] = | |||
238 | {SENSOR, 0x37, 0x01, 0x00}, | 216 | {SENSOR, 0x37, 0x01, 0x00}, |
239 | /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ | 217 | /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ |
240 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, | 218 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, |
241 | {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, | 219 | {SENSOR, S5K4AA_ROWSTART_LO, 0x29, 0x00}, |
242 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, | 220 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, |
243 | {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, | 221 | {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, |
244 | /* window_height_hi, window_height_lo : 960 = 0x03c0 */ | 222 | /* window_height_hi, window_height_lo : 960 = 0x03c0 */ |
@@ -255,12 +233,9 @@ static const unsigned char init_s5k4aa[][4] = | |||
255 | {SENSOR, 0x12, 0xc3, 0x00}, | 233 | {SENSOR, 0x12, 0xc3, 0x00}, |
256 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 234 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
257 | {SENSOR, 0x02, 0x0e, 0x00}, | 235 | {SENSOR, 0x02, 0x0e, 0x00}, |
258 | {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00}, | ||
259 | {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00}, | ||
260 | {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00} | ||
261 | }; | 236 | }; |
262 | 237 | ||
263 | static const unsigned char VGA_s5k4aa[][4] = | 238 | static const unsigned char SXGA_s5k4aa[][4] = |
264 | { | 239 | { |
265 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 240 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
266 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 241 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
@@ -273,50 +248,42 @@ static const unsigned char VGA_s5k4aa[][4] = | |||
273 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 248 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
274 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 249 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
275 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 250 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
276 | /* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */ | 251 | /* VSYNC_PARA, VSYNC_PARA : img height 1024 = 0x0400 */ |
277 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | 252 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, |
278 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, | 253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
279 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
280 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
281 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 256 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
282 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | 257 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, |
283 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 258 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
284 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 259 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
285 | /* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */ | 260 | /* HSYNC_PARA, HSYNC_PARA : img width 1280 = 0x0500 */ |
286 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | 261 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, |
287 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00}, | 262 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
288 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 263 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
289 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 264 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
290 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */ | 265 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */ |
291 | 266 | ||
292 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 267 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
293 | {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X | 268 | {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP, 0x00}, |
294 | | S5K4AA_RM_COL_SKIP_2X, 0x00}, | ||
295 | /* 0x37 : Fix image stability when light is too bright and improves | ||
296 | * image quality in 640x480, but worsens it in 1280x1024 */ | ||
297 | {SENSOR, 0x37, 0x01, 0x00}, | 269 | {SENSOR, 0x37, 0x01, 0x00}, |
298 | /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ | ||
299 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, | 270 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, |
300 | {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, | 271 | {SENSOR, S5K4AA_ROWSTART_LO, 0x09, 0x00}, |
301 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, | 272 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, |
302 | {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, | 273 | {SENSOR, S5K4AA_COLSTART_LO, 0x0a, 0x00}, |
303 | /* window_height_hi, window_height_lo : 960 = 0x03c0 */ | 274 | {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00}, |
304 | {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00}, | 275 | {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00}, |
305 | {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00}, | ||
306 | /* window_width_hi, window_width_lo : 1280 = 0x0500 */ | ||
307 | {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, | 276 | {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, |
308 | {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00}, | 277 | {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00}, |
309 | {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00}, | 278 | {SENSOR, S5K4AA_H_BLANK_HI__, 0x01, 0x00}, |
310 | {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */ | 279 | {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, |
311 | {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00}, | 280 | {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00}, |
312 | {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00}, | 281 | {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00}, |
313 | {SENSOR, 0x11, 0x04, 0x00}, | 282 | {SENSOR, 0x11, 0x04, 0x00}, |
314 | {SENSOR, 0x12, 0xc3, 0x00}, | 283 | {SENSOR, 0x12, 0xc3, 0x00}, |
315 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 284 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
316 | {SENSOR, 0x02, 0x0e, 0x00}, | 285 | {SENSOR, 0x02, 0x0e, 0x00}, |
317 | {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00}, | ||
318 | {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00}, | ||
319 | {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00} | ||
320 | }; | 286 | }; |
321 | 287 | ||
288 | |||
322 | #endif | 289 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c index 42c86aa4dc8d..7127321ace8c 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c | |||
@@ -16,8 +16,20 @@ | |||
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/kthread.h> | ||
19 | #include "m5602_s5k83a.h" | 20 | #include "m5602_s5k83a.h" |
20 | 21 | ||
22 | static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
29 | static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
30 | static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
31 | static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
32 | |||
21 | static struct v4l2_pix_format s5k83a_modes[] = { | 33 | static struct v4l2_pix_format s5k83a_modes[] = { |
22 | { | 34 | { |
23 | 640, | 35 | 640, |
@@ -32,68 +44,77 @@ static struct v4l2_pix_format s5k83a_modes[] = { | |||
32 | } | 44 | } |
33 | }; | 45 | }; |
34 | 46 | ||
35 | const static struct ctrl s5k83a_ctrls[] = { | 47 | static const struct ctrl s5k83a_ctrls[] = { |
48 | #define GAIN_IDX 0 | ||
36 | { | 49 | { |
37 | { | 50 | { |
38 | .id = V4L2_CID_BRIGHTNESS, | 51 | .id = V4L2_CID_GAIN, |
39 | .type = V4L2_CTRL_TYPE_INTEGER, | 52 | .type = V4L2_CTRL_TYPE_INTEGER, |
40 | .name = "brightness", | 53 | .name = "gain", |
41 | .minimum = 0x00, | 54 | .minimum = 0x00, |
42 | .maximum = 0xff, | 55 | .maximum = 0xff, |
43 | .step = 0x01, | 56 | .step = 0x01, |
44 | .default_value = S5K83A_DEFAULT_BRIGHTNESS, | 57 | .default_value = S5K83A_DEFAULT_GAIN, |
45 | .flags = V4L2_CTRL_FLAG_SLIDER | 58 | .flags = V4L2_CTRL_FLAG_SLIDER |
46 | }, | 59 | }, |
47 | .set = s5k83a_set_brightness, | 60 | .set = s5k83a_set_gain, |
48 | .get = s5k83a_get_brightness | 61 | .get = s5k83a_get_gain |
49 | 62 | ||
50 | }, { | 63 | }, |
64 | #define BRIGHTNESS_IDX 1 | ||
65 | { | ||
51 | { | 66 | { |
52 | .id = V4L2_CID_WHITENESS, | 67 | .id = V4L2_CID_BRIGHTNESS, |
53 | .type = V4L2_CTRL_TYPE_INTEGER, | 68 | .type = V4L2_CTRL_TYPE_INTEGER, |
54 | .name = "whiteness", | 69 | .name = "brightness", |
55 | .minimum = 0x00, | 70 | .minimum = 0x00, |
56 | .maximum = 0xff, | 71 | .maximum = 0xff, |
57 | .step = 0x01, | 72 | .step = 0x01, |
58 | .default_value = S5K83A_DEFAULT_WHITENESS, | 73 | .default_value = S5K83A_DEFAULT_BRIGHTNESS, |
59 | .flags = V4L2_CTRL_FLAG_SLIDER | 74 | .flags = V4L2_CTRL_FLAG_SLIDER |
60 | }, | 75 | }, |
61 | .set = s5k83a_set_whiteness, | 76 | .set = s5k83a_set_brightness, |
62 | .get = s5k83a_get_whiteness, | 77 | .get = s5k83a_get_brightness, |
63 | }, { | 78 | }, |
79 | #define EXPOSURE_IDX 2 | ||
80 | { | ||
64 | { | 81 | { |
65 | .id = V4L2_CID_GAIN, | 82 | .id = V4L2_CID_EXPOSURE, |
66 | .type = V4L2_CTRL_TYPE_INTEGER, | 83 | .type = V4L2_CTRL_TYPE_INTEGER, |
67 | .name = "gain", | 84 | .name = "exposure", |
68 | .minimum = 0x00, | 85 | .minimum = 0x00, |
69 | .maximum = S5K83A_MAXIMUM_GAIN, | 86 | .maximum = S5K83A_MAXIMUM_EXPOSURE, |
70 | .step = 0x01, | 87 | .step = 0x01, |
71 | .default_value = S5K83A_DEFAULT_GAIN, | 88 | .default_value = S5K83A_DEFAULT_EXPOSURE, |
72 | .flags = V4L2_CTRL_FLAG_SLIDER | 89 | .flags = V4L2_CTRL_FLAG_SLIDER |
73 | }, | 90 | }, |
74 | .set = s5k83a_set_gain, | 91 | .set = s5k83a_set_exposure, |
75 | .get = s5k83a_get_gain | 92 | .get = s5k83a_get_exposure |
76 | }, { | 93 | }, |
94 | #define HFLIP_IDX 3 | ||
95 | { | ||
77 | { | 96 | { |
78 | .id = V4L2_CID_HFLIP, | 97 | .id = V4L2_CID_HFLIP, |
79 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 98 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
80 | .name = "horizontal flip", | 99 | .name = "horizontal flip", |
81 | .minimum = 0, | 100 | .minimum = 0, |
82 | .maximum = 1, | 101 | .maximum = 1, |
83 | .step = 1, | 102 | .step = 1, |
84 | .default_value = 0 | 103 | .default_value = 0 |
85 | }, | 104 | }, |
86 | .set = s5k83a_set_hflip, | 105 | .set = s5k83a_set_hflip, |
87 | .get = s5k83a_get_hflip | 106 | .get = s5k83a_get_hflip |
88 | }, { | 107 | }, |
108 | #define VFLIP_IDX 4 | ||
109 | { | ||
89 | { | 110 | { |
90 | .id = V4L2_CID_VFLIP, | 111 | .id = V4L2_CID_VFLIP, |
91 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 112 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
92 | .name = "vertical flip", | 113 | .name = "vertical flip", |
93 | .minimum = 0, | 114 | .minimum = 0, |
94 | .maximum = 1, | 115 | .maximum = 1, |
95 | .step = 1, | 116 | .step = 1, |
96 | .default_value = 0 | 117 | .default_value = 0 |
97 | }, | 118 | }, |
98 | .set = s5k83a_set_vflip, | 119 | .set = s5k83a_set_vflip, |
99 | .get = s5k83a_get_vflip | 120 | .get = s5k83a_get_vflip |
@@ -101,9 +122,14 @@ const static struct ctrl s5k83a_ctrls[] = { | |||
101 | }; | 122 | }; |
102 | 123 | ||
103 | static void s5k83a_dump_registers(struct sd *sd); | 124 | static void s5k83a_dump_registers(struct sd *sd); |
125 | static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data); | ||
126 | static int s5k83a_set_led_indication(struct sd *sd, u8 val); | ||
127 | static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, | ||
128 | __s32 vflip, __s32 hflip); | ||
104 | 129 | ||
105 | int s5k83a_probe(struct sd *sd) | 130 | int s5k83a_probe(struct sd *sd) |
106 | { | 131 | { |
132 | struct s5k83a_priv *sens_priv; | ||
107 | u8 prod_id = 0, ver_id = 0; | 133 | u8 prod_id = 0, ver_id = 0; |
108 | int i, err = 0; | 134 | int i, err = 0; |
109 | 135 | ||
@@ -145,16 +171,36 @@ int s5k83a_probe(struct sd *sd) | |||
145 | info("Detected a s5k83a sensor"); | 171 | info("Detected a s5k83a sensor"); |
146 | 172 | ||
147 | sensor_found: | 173 | sensor_found: |
174 | sens_priv = kmalloc( | ||
175 | sizeof(struct s5k83a_priv), GFP_KERNEL); | ||
176 | if (!sens_priv) | ||
177 | return -ENOMEM; | ||
178 | |||
179 | sens_priv->settings = | ||
180 | kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL); | ||
181 | if (!sens_priv->settings) | ||
182 | return -ENOMEM; | ||
183 | |||
148 | sd->gspca_dev.cam.cam_mode = s5k83a_modes; | 184 | sd->gspca_dev.cam.cam_mode = s5k83a_modes; |
149 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); | 185 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); |
150 | sd->desc->ctrls = s5k83a_ctrls; | 186 | sd->desc->ctrls = s5k83a_ctrls; |
151 | sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls); | 187 | sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls); |
188 | |||
189 | /* null the pointer! thread is't running now */ | ||
190 | sens_priv->rotation_thread = NULL; | ||
191 | |||
192 | for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++) | ||
193 | sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value; | ||
194 | |||
195 | sd->sensor_priv = sens_priv; | ||
152 | return 0; | 196 | return 0; |
153 | } | 197 | } |
154 | 198 | ||
155 | int s5k83a_init(struct sd *sd) | 199 | int s5k83a_init(struct sd *sd) |
156 | { | 200 | { |
157 | int i, err = 0; | 201 | int i, err = 0; |
202 | s32 *sensor_settings = | ||
203 | ((struct s5k83a_priv *) sd->sensor_priv)->settings; | ||
158 | 204 | ||
159 | for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { | 205 | for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { |
160 | u8 data[2] = {0x00, 0x00}; | 206 | u8 data[2] = {0x00, 0x00}; |
@@ -187,87 +233,138 @@ int s5k83a_init(struct sd *sd) | |||
187 | if (dump_sensor) | 233 | if (dump_sensor) |
188 | s5k83a_dump_registers(sd); | 234 | s5k83a_dump_registers(sd); |
189 | 235 | ||
190 | return (err < 0) ? err : 0; | 236 | err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); |
191 | } | 237 | if (err < 0) |
238 | return err; | ||
192 | 239 | ||
193 | int s5k83a_start(struct sd *sd) | 240 | err = s5k83a_set_brightness(&sd->gspca_dev, |
194 | { | 241 | sensor_settings[BRIGHTNESS_IDX]); |
195 | return s5k83a_set_led_indication(sd, 1); | 242 | if (err < 0) |
196 | } | 243 | return err; |
197 | 244 | ||
198 | int s5k83a_stop(struct sd *sd) | 245 | err = s5k83a_set_exposure(&sd->gspca_dev, |
199 | { | 246 | sensor_settings[EXPOSURE_IDX]); |
200 | return s5k83a_set_led_indication(sd, 0); | 247 | if (err < 0) |
248 | return err; | ||
249 | |||
250 | err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
251 | if (err < 0) | ||
252 | return err; | ||
253 | |||
254 | err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); | ||
255 | |||
256 | return err; | ||
201 | } | 257 | } |
202 | 258 | ||
203 | int s5k83a_power_down(struct sd *sd) | 259 | static int rotation_thread_function(void *data) |
204 | { | 260 | { |
261 | struct sd *sd = (struct sd *) data; | ||
262 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
263 | u8 reg, previous_rotation = 0; | ||
264 | __s32 vflip, hflip; | ||
265 | |||
266 | set_current_state(TASK_INTERRUPTIBLE); | ||
267 | while (!schedule_timeout(100)) { | ||
268 | if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock)) | ||
269 | break; | ||
270 | |||
271 | s5k83a_get_rotation(sd, ®); | ||
272 | if (previous_rotation != reg) { | ||
273 | previous_rotation = reg; | ||
274 | info("Camera was flipped"); | ||
275 | |||
276 | s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); | ||
277 | s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); | ||
278 | |||
279 | if (reg) { | ||
280 | vflip = !vflip; | ||
281 | hflip = !hflip; | ||
282 | } | ||
283 | s5k83a_set_flip_real((struct gspca_dev *) sd, | ||
284 | vflip, hflip); | ||
285 | } | ||
286 | |||
287 | mutex_unlock(&sd->gspca_dev.usb_lock); | ||
288 | set_current_state(TASK_INTERRUPTIBLE); | ||
289 | } | ||
290 | |||
291 | /* return to "front" flip */ | ||
292 | if (previous_rotation) { | ||
293 | s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); | ||
294 | s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); | ||
295 | s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip); | ||
296 | } | ||
297 | |||
298 | sens_priv->rotation_thread = NULL; | ||
205 | return 0; | 299 | return 0; |
206 | } | 300 | } |
207 | 301 | ||
208 | static void s5k83a_dump_registers(struct sd *sd) | 302 | int s5k83a_start(struct sd *sd) |
209 | { | 303 | { |
210 | int address; | 304 | int i, err = 0; |
211 | u8 page, old_page; | 305 | struct s5k83a_priv *sens_priv = sd->sensor_priv; |
212 | m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
213 | 306 | ||
214 | for (page = 0; page < 16; page++) { | 307 | /* Create another thread, polling the GPIO ports of the camera to check |
215 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | 308 | if it got rotated. This is how the windows driver does it so we have |
216 | info("Dumping the s5k83a register state for page 0x%x", page); | 309 | to assume that there is no better way of accomplishing this */ |
217 | for (address = 0; address <= 0xff; address++) { | 310 | sens_priv->rotation_thread = kthread_create(rotation_thread_function, |
218 | u8 val = 0; | 311 | sd, "rotation thread"); |
219 | m5602_read_sensor(sd, address, &val, 1); | 312 | wake_up_process(sens_priv->rotation_thread); |
220 | info("register 0x%x contains 0x%x", | 313 | |
221 | address, val); | 314 | /* Preinit the sensor */ |
222 | } | 315 | for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) { |
316 | u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]}; | ||
317 | if (start_s5k83a[i][0] == SENSOR) | ||
318 | err = m5602_write_sensor(sd, start_s5k83a[i][1], | ||
319 | data, 2); | ||
320 | else | ||
321 | err = m5602_write_bridge(sd, start_s5k83a[i][1], | ||
322 | data[0]); | ||
223 | } | 323 | } |
224 | info("s5k83a register state dump complete"); | 324 | if (err < 0) |
325 | return err; | ||
225 | 326 | ||
226 | for (page = 0; page < 16; page++) { | 327 | return s5k83a_set_led_indication(sd, 1); |
227 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | 328 | } |
228 | info("Probing for which registers that are read/write " | ||
229 | "for page 0x%x", page); | ||
230 | for (address = 0; address <= 0xff; address++) { | ||
231 | u8 old_val, ctrl_val, test_val = 0xff; | ||
232 | 329 | ||
233 | m5602_read_sensor(sd, address, &old_val, 1); | 330 | int s5k83a_stop(struct sd *sd) |
234 | m5602_write_sensor(sd, address, &test_val, 1); | 331 | { |
235 | m5602_read_sensor(sd, address, &ctrl_val, 1); | 332 | struct s5k83a_priv *sens_priv = sd->sensor_priv; |
236 | 333 | ||
237 | if (ctrl_val == test_val) | 334 | if (sens_priv->rotation_thread) |
238 | info("register 0x%x is writeable", address); | 335 | kthread_stop(sens_priv->rotation_thread); |
239 | else | ||
240 | info("register 0x%x is read only", address); | ||
241 | 336 | ||
242 | /* Restore original val */ | 337 | return s5k83a_set_led_indication(sd, 0); |
243 | m5602_write_sensor(sd, address, &old_val, 1); | ||
244 | } | ||
245 | } | ||
246 | info("Read/write register probing complete"); | ||
247 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
248 | } | 338 | } |
249 | 339 | ||
250 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 340 | void s5k83a_disconnect(struct sd *sd) |
251 | { | 341 | { |
252 | int err; | 342 | struct s5k83a_priv *sens_priv = sd->sensor_priv; |
253 | u8 data[2]; | ||
254 | struct sd *sd = (struct sd *) gspca_dev; | ||
255 | 343 | ||
256 | err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2); | 344 | s5k83a_stop(sd); |
257 | if (err < 0) | 345 | |
258 | return err; | 346 | sd->sensor = NULL; |
347 | kfree(sens_priv->settings); | ||
348 | kfree(sens_priv); | ||
349 | } | ||
259 | 350 | ||
260 | data[1] = data[1] << 1; | 351 | static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
261 | *val = data[1]; | 352 | { |
353 | struct sd *sd = (struct sd *) gspca_dev; | ||
354 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
262 | 355 | ||
263 | return err; | 356 | *val = sens_priv->settings[GAIN_IDX]; |
357 | return 0; | ||
264 | } | 358 | } |
265 | 359 | ||
266 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 360 | static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
267 | { | 361 | { |
268 | int err; | 362 | int err; |
269 | u8 data[2]; | 363 | u8 data[2]; |
270 | struct sd *sd = (struct sd *) gspca_dev; | 364 | struct sd *sd = (struct sd *) gspca_dev; |
365 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
366 | |||
367 | sens_priv->settings[GAIN_IDX] = val; | ||
271 | 368 | ||
272 | data[0] = 0x00; | 369 | data[0] = 0x00; |
273 | data[1] = 0x20; | 370 | data[1] = 0x20; |
@@ -283,89 +380,69 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | |||
283 | 380 | ||
284 | /* FIXME: This is not sane, we need to figure out the composition | 381 | /* FIXME: This is not sane, we need to figure out the composition |
285 | of these registers */ | 382 | of these registers */ |
286 | data[0] = val >> 3; /* brightness, high 5 bits */ | 383 | data[0] = val >> 3; /* gain, high 5 bits */ |
287 | data[1] = val >> 1; /* brightness, high 7 bits */ | 384 | data[1] = val >> 1; /* gain, high 7 bits */ |
288 | err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2); | 385 | err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2); |
289 | 386 | ||
290 | return err; | 387 | return err; |
291 | } | 388 | } |
292 | 389 | ||
293 | int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val) | 390 | static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) |
294 | { | 391 | { |
295 | int err; | ||
296 | u8 data; | ||
297 | struct sd *sd = (struct sd *) gspca_dev; | 392 | struct sd *sd = (struct sd *) gspca_dev; |
393 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
298 | 394 | ||
299 | err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1); | 395 | *val = sens_priv->settings[BRIGHTNESS_IDX]; |
300 | if (err < 0) | 396 | return 0; |
301 | return err; | ||
302 | |||
303 | *val = data; | ||
304 | |||
305 | return err; | ||
306 | } | 397 | } |
307 | 398 | ||
308 | int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val) | 399 | static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) |
309 | { | 400 | { |
310 | int err; | 401 | int err; |
311 | u8 data[1]; | 402 | u8 data[1]; |
312 | struct sd *sd = (struct sd *) gspca_dev; | 403 | struct sd *sd = (struct sd *) gspca_dev; |
404 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
313 | 405 | ||
406 | sens_priv->settings[BRIGHTNESS_IDX] = val; | ||
314 | data[0] = val; | 407 | data[0] = val; |
315 | err = m5602_write_sensor(sd, S5K83A_WHITENESS, data, 1); | 408 | err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1); |
316 | |||
317 | return err; | 409 | return err; |
318 | } | 410 | } |
319 | 411 | ||
320 | int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 412 | static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
321 | { | 413 | { |
322 | int err; | ||
323 | u8 data[2]; | ||
324 | struct sd *sd = (struct sd *) gspca_dev; | 414 | struct sd *sd = (struct sd *) gspca_dev; |
415 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
325 | 416 | ||
326 | err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2); | 417 | *val = sens_priv->settings[EXPOSURE_IDX]; |
327 | if (err < 0) | 418 | return 0; |
328 | return err; | ||
329 | |||
330 | data[1] = data[1] & 0x3f; | ||
331 | if (data[1] > S5K83A_MAXIMUM_GAIN) | ||
332 | data[1] = S5K83A_MAXIMUM_GAIN; | ||
333 | |||
334 | *val = data[1]; | ||
335 | |||
336 | return err; | ||
337 | } | 419 | } |
338 | 420 | ||
339 | int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 421 | static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
340 | { | 422 | { |
341 | int err; | 423 | int err; |
342 | u8 data[2]; | 424 | u8 data[2]; |
343 | struct sd *sd = (struct sd *) gspca_dev; | 425 | struct sd *sd = (struct sd *) gspca_dev; |
426 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
344 | 427 | ||
428 | sens_priv->settings[EXPOSURE_IDX] = val; | ||
345 | data[0] = 0; | 429 | data[0] = 0; |
346 | data[1] = val; | 430 | data[1] = val; |
347 | err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2); | 431 | err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2); |
348 | return err; | 432 | return err; |
349 | } | 433 | } |
350 | 434 | ||
351 | int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 435 | static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
352 | { | 436 | { |
353 | int err; | ||
354 | u8 data[1]; | ||
355 | struct sd *sd = (struct sd *) gspca_dev; | 437 | struct sd *sd = (struct sd *) gspca_dev; |
438 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
356 | 439 | ||
357 | data[0] = 0x05; | 440 | *val = sens_priv->settings[VFLIP_IDX]; |
358 | err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); | 441 | return 0; |
359 | if (err < 0) | ||
360 | return err; | ||
361 | |||
362 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | ||
363 | *val = (data[0] | 0x40) ? 1 : 0; | ||
364 | |||
365 | return err; | ||
366 | } | 442 | } |
367 | 443 | ||
368 | int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 444 | static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, |
445 | __s32 vflip, __s32 hflip) | ||
369 | { | 446 | { |
370 | int err; | 447 | int err; |
371 | u8 data[1]; | 448 | u8 data[1]; |
@@ -376,69 +453,83 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
376 | if (err < 0) | 453 | if (err < 0) |
377 | return err; | 454 | return err; |
378 | 455 | ||
379 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | 456 | /* six bit is vflip, seven is hflip */ |
380 | if (err < 0) | 457 | data[0] = S5K83A_FLIP_MASK; |
381 | return err; | 458 | data[0] = (vflip) ? data[0] | 0x40 : data[0]; |
459 | data[0] = (hflip) ? data[0] | 0x80 : data[0]; | ||
382 | 460 | ||
383 | /* set or zero six bit, seven is hflip */ | ||
384 | data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK | ||
385 | : (data[0] & 0x80) | S5K83A_FLIP_MASK; | ||
386 | err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); | 461 | err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); |
387 | if (err < 0) | 462 | if (err < 0) |
388 | return err; | 463 | return err; |
389 | 464 | ||
390 | data[0] = (val) ? 0x0b : 0x0a; | 465 | data[0] = (vflip) ? 0x0b : 0x0a; |
391 | err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); | 466 | err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); |
467 | if (err < 0) | ||
468 | return err; | ||
392 | 469 | ||
470 | data[0] = (hflip) ? 0x0a : 0x0b; | ||
471 | err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); | ||
393 | return err; | 472 | return err; |
394 | } | 473 | } |
395 | 474 | ||
396 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 475 | static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
397 | { | 476 | { |
398 | int err; | 477 | int err; |
399 | u8 data[1]; | 478 | u8 reg; |
479 | __s32 hflip; | ||
400 | struct sd *sd = (struct sd *) gspca_dev; | 480 | struct sd *sd = (struct sd *) gspca_dev; |
481 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
401 | 482 | ||
402 | data[0] = 0x05; | 483 | sens_priv->settings[VFLIP_IDX] = val; |
403 | err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); | 484 | |
485 | s5k83a_get_hflip(gspca_dev, &hflip); | ||
486 | |||
487 | err = s5k83a_get_rotation(sd, ®); | ||
404 | if (err < 0) | 488 | if (err < 0) |
405 | return err; | 489 | return err; |
490 | if (reg) { | ||
491 | val = !val; | ||
492 | hflip = !hflip; | ||
493 | } | ||
406 | 494 | ||
407 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | 495 | err = s5k83a_set_flip_real(gspca_dev, val, hflip); |
408 | *val = (data[0] | 0x80) ? 1 : 0; | ||
409 | |||
410 | return err; | 496 | return err; |
411 | } | 497 | } |
412 | 498 | ||
413 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 499 | static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
500 | { | ||
501 | struct sd *sd = (struct sd *) gspca_dev; | ||
502 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
503 | |||
504 | *val = sens_priv->settings[HFLIP_IDX]; | ||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | ||
414 | { | 509 | { |
415 | int err; | 510 | int err; |
416 | u8 data[1]; | 511 | u8 reg; |
512 | __s32 vflip; | ||
417 | struct sd *sd = (struct sd *) gspca_dev; | 513 | struct sd *sd = (struct sd *) gspca_dev; |
514 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
418 | 515 | ||
419 | data[0] = 0x05; | 516 | sens_priv->settings[HFLIP_IDX] = val; |
420 | err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); | ||
421 | if (err < 0) | ||
422 | return err; | ||
423 | 517 | ||
424 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | 518 | s5k83a_get_vflip(gspca_dev, &vflip); |
425 | if (err < 0) | ||
426 | return err; | ||
427 | 519 | ||
428 | /* set or zero seven bit, six is vflip */ | 520 | err = s5k83a_get_rotation(sd, ®); |
429 | data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK | ||
430 | : (data[0] & 0x40) | S5K83A_FLIP_MASK; | ||
431 | err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); | ||
432 | if (err < 0) | 521 | if (err < 0) |
433 | return err; | 522 | return err; |
523 | if (reg) { | ||
524 | val = !val; | ||
525 | vflip = !vflip; | ||
526 | } | ||
434 | 527 | ||
435 | data[0] = (val) ? 0x0a : 0x0b; | 528 | err = s5k83a_set_flip_real(gspca_dev, vflip, val); |
436 | err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); | ||
437 | |||
438 | return err; | 529 | return err; |
439 | } | 530 | } |
440 | 531 | ||
441 | int s5k83a_set_led_indication(struct sd *sd, u8 val) | 532 | static int s5k83a_set_led_indication(struct sd *sd, u8 val) |
442 | { | 533 | { |
443 | int err = 0; | 534 | int err = 0; |
444 | u8 data[1]; | 535 | u8 data[1]; |
@@ -454,5 +545,55 @@ int s5k83a_set_led_indication(struct sd *sd, u8 val) | |||
454 | 545 | ||
455 | err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]); | 546 | err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]); |
456 | 547 | ||
457 | return (err < 0) ? err : 0; | 548 | return err; |
549 | } | ||
550 | |||
551 | /* Get camera rotation on Acer notebooks */ | ||
552 | static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data) | ||
553 | { | ||
554 | int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data); | ||
555 | *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1; | ||
556 | return err; | ||
557 | } | ||
558 | |||
559 | static void s5k83a_dump_registers(struct sd *sd) | ||
560 | { | ||
561 | int address; | ||
562 | u8 page, old_page; | ||
563 | m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
564 | |||
565 | for (page = 0; page < 16; page++) { | ||
566 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | ||
567 | info("Dumping the s5k83a register state for page 0x%x", page); | ||
568 | for (address = 0; address <= 0xff; address++) { | ||
569 | u8 val = 0; | ||
570 | m5602_read_sensor(sd, address, &val, 1); | ||
571 | info("register 0x%x contains 0x%x", | ||
572 | address, val); | ||
573 | } | ||
574 | } | ||
575 | info("s5k83a register state dump complete"); | ||
576 | |||
577 | for (page = 0; page < 16; page++) { | ||
578 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | ||
579 | info("Probing for which registers that are read/write " | ||
580 | "for page 0x%x", page); | ||
581 | for (address = 0; address <= 0xff; address++) { | ||
582 | u8 old_val, ctrl_val, test_val = 0xff; | ||
583 | |||
584 | m5602_read_sensor(sd, address, &old_val, 1); | ||
585 | m5602_write_sensor(sd, address, &test_val, 1); | ||
586 | m5602_read_sensor(sd, address, &ctrl_val, 1); | ||
587 | |||
588 | if (ctrl_val == test_val) | ||
589 | info("register 0x%x is writeable", address); | ||
590 | else | ||
591 | info("register 0x%x is read only", address); | ||
592 | |||
593 | /* Restore original val */ | ||
594 | m5602_write_sensor(sd, address, &old_val, 1); | ||
595 | } | ||
596 | } | ||
597 | info("Read/write register probing complete"); | ||
598 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
458 | } | 599 | } |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h index 819ab25272be..7814b078acde 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h | |||
@@ -21,20 +21,21 @@ | |||
21 | 21 | ||
22 | #include "m5602_sensor.h" | 22 | #include "m5602_sensor.h" |
23 | 23 | ||
24 | #define S5K83A_FLIP 0x01 | 24 | #define S5K83A_FLIP 0x01 |
25 | #define S5K83A_HFLIP_TUNE 0x03 | 25 | #define S5K83A_HFLIP_TUNE 0x03 |
26 | #define S5K83A_VFLIP_TUNE 0x05 | 26 | #define S5K83A_VFLIP_TUNE 0x05 |
27 | #define S5K83A_WHITENESS 0x0a | 27 | #define S5K83A_BRIGHTNESS 0x0a |
28 | #define S5K83A_GAIN 0x18 | 28 | #define S5K83A_EXPOSURE 0x18 |
29 | #define S5K83A_BRIGHTNESS 0x1b | 29 | #define S5K83A_GAIN 0x1b |
30 | #define S5K83A_PAGE_MAP 0xec | 30 | #define S5K83A_PAGE_MAP 0xec |
31 | 31 | ||
32 | #define S5K83A_DEFAULT_BRIGHTNESS 0x71 | 32 | #define S5K83A_DEFAULT_GAIN 0x71 |
33 | #define S5K83A_DEFAULT_WHITENESS 0x7e | 33 | #define S5K83A_DEFAULT_BRIGHTNESS 0x7e |
34 | #define S5K83A_DEFAULT_GAIN 0x00 | 34 | #define S5K83A_DEFAULT_EXPOSURE 0x00 |
35 | #define S5K83A_MAXIMUM_GAIN 0x3c | 35 | #define S5K83A_MAXIMUM_EXPOSURE 0x3c |
36 | #define S5K83A_FLIP_MASK 0x10 | 36 | #define S5K83A_FLIP_MASK 0x10 |
37 | #define S5K83A_GPIO_LED_MASK 0x10 | 37 | #define S5K83A_GPIO_LED_MASK 0x10 |
38 | #define S5K83A_GPIO_ROTATION_MASK 0x40 | ||
38 | 39 | ||
39 | /*****************************************************************************/ | 40 | /*****************************************************************************/ |
40 | 41 | ||
@@ -46,20 +47,7 @@ int s5k83a_probe(struct sd *sd); | |||
46 | int s5k83a_init(struct sd *sd); | 47 | int s5k83a_init(struct sd *sd); |
47 | int s5k83a_start(struct sd *sd); | 48 | int s5k83a_start(struct sd *sd); |
48 | int s5k83a_stop(struct sd *sd); | 49 | int s5k83a_stop(struct sd *sd); |
49 | int s5k83a_power_down(struct sd *sd); | 50 | void s5k83a_disconnect(struct sd *sd); |
50 | |||
51 | int s5k83a_set_led_indication(struct sd *sd, u8 val); | ||
52 | |||
53 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
54 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val); | ||
56 | int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val); | ||
57 | int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
59 | int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
60 | int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
61 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
62 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
63 | 51 | ||
64 | static const struct m5602_sensor s5k83a = { | 52 | static const struct m5602_sensor s5k83a = { |
65 | .name = "S5K83A", | 53 | .name = "S5K83A", |
@@ -67,11 +55,18 @@ static const struct m5602_sensor s5k83a = { | |||
67 | .init = s5k83a_init, | 55 | .init = s5k83a_init, |
68 | .start = s5k83a_start, | 56 | .start = s5k83a_start, |
69 | .stop = s5k83a_stop, | 57 | .stop = s5k83a_stop, |
70 | .power_down = s5k83a_power_down, | 58 | .disconnect = s5k83a_disconnect, |
71 | .i2c_slave_id = 0x5a, | 59 | .i2c_slave_id = 0x5a, |
72 | .i2c_regW = 2, | 60 | .i2c_regW = 2, |
73 | }; | 61 | }; |
74 | 62 | ||
63 | struct s5k83a_priv { | ||
64 | /* We use another thread periodically | ||
65 | probing the orientation of the camera */ | ||
66 | struct task_struct *rotation_thread; | ||
67 | s32 *settings; | ||
68 | }; | ||
69 | |||
75 | static const unsigned char preinit_s5k83a[][4] = | 70 | static const unsigned char preinit_s5k83a[][4] = |
76 | { | 71 | { |
77 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, | 72 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, |
@@ -108,8 +103,6 @@ static const unsigned char preinit_s5k83a[][4] = | |||
108 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | 103 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, |
109 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | 104 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, |
110 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, | 105 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, |
111 | |||
112 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00} | ||
113 | }; | 106 | }; |
114 | 107 | ||
115 | /* This could probably be considerably shortened. | 108 | /* This could probably be considerably shortened. |
@@ -117,86 +110,8 @@ static const unsigned char preinit_s5k83a[][4] = | |||
117 | */ | 110 | */ |
118 | static const unsigned char init_s5k83a[][4] = | 111 | static const unsigned char init_s5k83a[][4] = |
119 | { | 112 | { |
120 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, | 113 | /* The following sequence is useless after a clean boot |
121 | {SENSOR, 0xaf, 0x01, 0x00}, | 114 | but is necessary after resume from suspend */ |
122 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, | ||
123 | {SENSOR, 0x7b, 0xff, 0x00}, | ||
124 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
125 | {SENSOR, 0x01, 0x50, 0x00}, | ||
126 | {SENSOR, 0x12, 0x20, 0x00}, | ||
127 | {SENSOR, 0x17, 0x40, 0x00}, | ||
128 | {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, | ||
129 | {SENSOR, 0x1c, 0x00, 0x00}, | ||
130 | {SENSOR, 0x02, 0x70, 0x00}, | ||
131 | {SENSOR, 0x03, 0x0b, 0x00}, | ||
132 | {SENSOR, 0x04, 0xf0, 0x00}, | ||
133 | {SENSOR, 0x05, 0x0b, 0x00}, | ||
134 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
135 | |||
136 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
137 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
138 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
139 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
140 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
141 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
142 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
143 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
144 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
145 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
146 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
147 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
148 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | ||
149 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
150 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
151 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
152 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
153 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
154 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
155 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
156 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, | ||
157 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
158 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
159 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
160 | |||
161 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
162 | {SENSOR, 0x06, 0x71, 0x00}, | ||
163 | {SENSOR, 0x07, 0xe8, 0x00}, | ||
164 | {SENSOR, 0x08, 0x02, 0x00}, | ||
165 | {SENSOR, 0x09, 0x88, 0x00}, | ||
166 | {SENSOR, 0x14, 0x00, 0x00}, | ||
167 | {SENSOR, 0x15, 0x20, 0x00}, | ||
168 | {SENSOR, 0x19, 0x00, 0x00}, | ||
169 | {SENSOR, 0x1a, 0x98, 0x00}, | ||
170 | {SENSOR, 0x0f, 0x02, 0x00}, | ||
171 | {SENSOR, 0x10, 0xe5, 0x00}, | ||
172 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
173 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | ||
174 | {SENSOR_LONG, 0x0d, 0x00, 0x7d}, | ||
175 | {SENSOR_LONG, 0x1b, 0x0d, 0x05}, | ||
176 | |||
177 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
178 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
179 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
180 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
181 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
182 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
183 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
184 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
185 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
186 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
187 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
188 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
189 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | ||
190 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
191 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
192 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
193 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
194 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
195 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
196 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
197 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, | ||
198 | |||
199 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
200 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | 115 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, |
201 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, | 116 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, |
202 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, | 117 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, |
@@ -216,7 +131,7 @@ static const unsigned char init_s5k83a[][4] = | |||
216 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 131 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
217 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, | 132 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, |
218 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | 133 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, |
219 | {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, | 134 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, |
220 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | 135 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, |
221 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, | 136 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, |
222 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | 137 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, |
@@ -225,109 +140,34 @@ static const unsigned char init_s5k83a[][4] = | |||
225 | 140 | ||
226 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, | 141 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, |
227 | {SENSOR, 0xaf, 0x01, 0x00}, | 142 | {SENSOR, 0xaf, 0x01, 0x00}, |
228 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | 143 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, |
229 | /* ff ( init value )is very dark) || 71 and f0 better */ | ||
230 | {SENSOR, 0x7b, 0xff, 0x00}, | 144 | {SENSOR, 0x7b, 0xff, 0x00}, |
231 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | 145 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, |
232 | {SENSOR, 0x01, 0x50, 0x00}, | 146 | {SENSOR, 0x01, 0x50, 0x00}, |
233 | {SENSOR, 0x12, 0x20, 0x00}, | 147 | {SENSOR, 0x12, 0x20, 0x00}, |
234 | {SENSOR, 0x17, 0x40, 0x00}, | 148 | {SENSOR, 0x17, 0x40, 0x00}, |
235 | {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, | ||
236 | {SENSOR, 0x1c, 0x00, 0x00}, | 149 | {SENSOR, 0x1c, 0x00, 0x00}, |
237 | {SENSOR, 0x02, 0x70, 0x00}, | 150 | {SENSOR, 0x02, 0x70, 0x00}, |
238 | /* some values like 0x10 give a blue-purple image */ | ||
239 | {SENSOR, 0x03, 0x0b, 0x00}, | 151 | {SENSOR, 0x03, 0x0b, 0x00}, |
240 | {SENSOR, 0x04, 0xf0, 0x00}, | 152 | {SENSOR, 0x04, 0xf0, 0x00}, |
241 | {SENSOR, 0x05, 0x0b, 0x00}, | 153 | {SENSOR, 0x05, 0x0b, 0x00}, |
242 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
243 | |||
244 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
245 | /* under 80 don't work, highter depend on value */ | ||
246 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
247 | |||
248 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
249 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
250 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
251 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
252 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
256 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
257 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
258 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | ||
259 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
260 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
261 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
262 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
263 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
264 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
265 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, | ||
266 | |||
267 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
268 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
269 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
270 | |||
271 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
272 | {SENSOR, 0x06, 0x71, 0x00}, | 154 | {SENSOR, 0x06, 0x71, 0x00}, |
273 | {SENSOR, 0x07, 0xe8, 0x00}, | 155 | {SENSOR, 0x07, 0xe8, 0x00}, /* 488 */ |
274 | {SENSOR, 0x08, 0x02, 0x00}, | 156 | {SENSOR, 0x08, 0x02, 0x00}, |
275 | {SENSOR, 0x09, 0x88, 0x00}, | 157 | {SENSOR, 0x09, 0x88, 0x00}, /* 648 */ |
276 | {SENSOR, 0x14, 0x00, 0x00}, | 158 | {SENSOR, 0x14, 0x00, 0x00}, |
277 | {SENSOR, 0x15, 0x20, 0x00}, | 159 | {SENSOR, 0x15, 0x20, 0x00}, /* 32 */ |
278 | {SENSOR, 0x19, 0x00, 0x00}, | 160 | {SENSOR, 0x19, 0x00, 0x00}, |
279 | {SENSOR, 0x1a, 0x98, 0x00}, | 161 | {SENSOR, 0x1a, 0x98, 0x00}, /* 152 */ |
280 | {SENSOR, 0x0f, 0x02, 0x00}, | 162 | {SENSOR, 0x0f, 0x02, 0x00}, |
281 | {SENSOR, 0x10, 0xe5, 0x00}, | 163 | {SENSOR, 0x10, 0xe5, 0x00}, /* 741 */ |
282 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | 164 | /* normal colors |
283 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | 165 | (this is value after boot, but after tries can be different) */ |
284 | {SENSOR_LONG, 0x0d, 0x00, 0x7d}, | 166 | {SENSOR, 0x00, 0x06, 0x00}, |
285 | {SENSOR_LONG, 0x1b, 0x0d, 0x05}, | 167 | }; |
286 | |||
287 | /* The following sequence is useless after a clean boot | ||
288 | but is necessary after resume from suspend */ | ||
289 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | ||
290 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, | ||
291 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, | ||
292 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, | ||
293 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | ||
294 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
295 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
296 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
297 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, | ||
298 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, | ||
299 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
300 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
301 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
302 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
303 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, | ||
304 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, | ||
305 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
306 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, | ||
307 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | ||
308 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, | ||
309 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
310 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, | ||
311 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | ||
312 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
313 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, | ||
314 | |||
315 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, | ||
316 | {SENSOR, 0xaf, 0x01, 0x00}, | ||
317 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, | ||
318 | {SENSOR, 0x7b, 0xff, 0x00}, | ||
319 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
320 | {SENSOR, 0x01, 0x50, 0x00}, | ||
321 | {SENSOR, 0x12, 0x20, 0x00}, | ||
322 | {SENSOR, 0x17, 0x40, 0x00}, | ||
323 | {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, | ||
324 | {SENSOR, 0x1c, 0x00, 0x00}, | ||
325 | {SENSOR, 0x02, 0x70, 0x00}, | ||
326 | {SENSOR, 0x03, 0x0b, 0x00}, | ||
327 | {SENSOR, 0x04, 0xf0, 0x00}, | ||
328 | {SENSOR, 0x05, 0x0b, 0x00}, | ||
329 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
330 | 168 | ||
169 | static const unsigned char start_s5k83a[][4] = | ||
170 | { | ||
331 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 171 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
332 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 172 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
333 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 173 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -340,7 +180,7 @@ static const unsigned char init_s5k83a[][4] = | |||
340 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 180 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
341 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 181 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
342 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | 182 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, |
343 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | 183 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, /* 484 */ |
344 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 184 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
345 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 185 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
346 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 186 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
@@ -348,50 +188,10 @@ static const unsigned char init_s5k83a[][4] = | |||
348 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 188 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
349 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 189 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
350 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | 190 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, |
351 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, | 191 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, /* 639 */ |
352 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 192 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
353 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 193 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
354 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 194 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
355 | |||
356 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
357 | {SENSOR, 0x06, 0x71, 0x00}, | ||
358 | {SENSOR, 0x07, 0xe8, 0x00}, | ||
359 | {SENSOR, 0x08, 0x02, 0x00}, | ||
360 | {SENSOR, 0x09, 0x88, 0x00}, | ||
361 | {SENSOR, 0x14, 0x00, 0x00}, | ||
362 | {SENSOR, 0x15, 0x20, 0x00}, | ||
363 | {SENSOR, 0x19, 0x00, 0x00}, | ||
364 | {SENSOR, 0x1a, 0x98, 0x00}, | ||
365 | {SENSOR, 0x0f, 0x02, 0x00}, | ||
366 | |||
367 | {SENSOR, 0x10, 0xe5, 0x00}, | ||
368 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
369 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | ||
370 | {SENSOR_LONG, 0x0d, 0x00, 0x7d}, | ||
371 | {SENSOR_LONG, 0x1b, 0x0d, 0x05}, | ||
372 | |||
373 | /* normal colors | ||
374 | (this is value after boot, but after tries can be different) */ | ||
375 | {SENSOR, 0x00, 0x06, 0x00}, | ||
376 | |||
377 | /* set default brightness */ | ||
378 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | ||
379 | {SENSOR_LONG, 0x0d, 0x01, 0x00}, | ||
380 | {SENSOR_LONG, 0x1b, S5K83A_DEFAULT_BRIGHTNESS >> 3, | ||
381 | S5K83A_DEFAULT_BRIGHTNESS >> 1}, | ||
382 | |||
383 | /* set default whiteness */ | ||
384 | {SENSOR, S5K83A_WHITENESS, S5K83A_DEFAULT_WHITENESS, 0x00}, | ||
385 | |||
386 | /* set default gain */ | ||
387 | {SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_GAIN}, | ||
388 | |||
389 | /* set default flip */ | ||
390 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
391 | {SENSOR, S5K83A_FLIP, 0x00 | S5K83A_FLIP_MASK, 0x00}, | ||
392 | {SENSOR, S5K83A_HFLIP_TUNE, 0x0b, 0x00}, | ||
393 | {SENSOR, S5K83A_VFLIP_TUNE, 0x0a, 0x00} | ||
394 | |||
395 | }; | 195 | }; |
396 | 196 | ||
397 | #endif | 197 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h index 0d3026936f2e..edff4f1f586f 100644 --- a/drivers/media/video/gspca/m5602/m5602_sensor.h +++ b/drivers/media/video/gspca/m5602/m5602_sensor.h | |||
@@ -21,13 +21,17 @@ | |||
21 | 21 | ||
22 | #include "m5602_bridge.h" | 22 | #include "m5602_bridge.h" |
23 | 23 | ||
24 | #define M5602_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 0) | ||
25 | #define M5602_V4L2_CID_NOISE_SUPPRESION (V4L2_CID_PRIVATE_BASE + 1) | ||
26 | |||
24 | /* Enumerates all supported sensors */ | 27 | /* Enumerates all supported sensors */ |
25 | enum sensors { | 28 | enum sensors { |
26 | OV9650_SENSOR = 1, | 29 | OV9650_SENSOR = 1, |
27 | S5K83A_SENSOR = 2, | 30 | S5K83A_SENSOR = 2, |
28 | S5K4AA_SENSOR = 3, | 31 | S5K4AA_SENSOR = 3, |
29 | MT9M111_SENSOR = 4, | 32 | MT9M111_SENSOR = 4, |
30 | PO1030_SENSOR = 5 | 33 | PO1030_SENSOR = 5, |
34 | OV7660_SENSOR = 6, | ||
31 | }; | 35 | }; |
32 | 36 | ||
33 | /* Enumerates all possible instruction types */ | 37 | /* Enumerates all possible instruction types */ |
@@ -61,9 +65,6 @@ struct m5602_sensor { | |||
61 | 65 | ||
62 | /* Executed when the device is disconnected */ | 66 | /* Executed when the device is disconnected */ |
63 | void (*disconnect)(struct sd *sd); | 67 | void (*disconnect)(struct sd *sd); |
64 | |||
65 | /* Performs a power down sequence */ | ||
66 | int (*power_down)(struct sd *sd); | ||
67 | }; | 68 | }; |
68 | 69 | ||
69 | #endif | 70 | #endif |
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 2a901a4a6f00..30132513400c 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c | |||
@@ -321,6 +321,7 @@ static const struct sd_desc sd_desc = { | |||
321 | /* -- module initialisation -- */ | 321 | /* -- module initialisation -- */ |
322 | static const __devinitdata struct usb_device_id device_table[] = { | 322 | static const __devinitdata struct usb_device_id device_table[] = { |
323 | {USB_DEVICE(0x08ca, 0x0111)}, | 323 | {USB_DEVICE(0x08ca, 0x0111)}, |
324 | {USB_DEVICE(0x093a, 0x010f)}, | ||
324 | {} | 325 | {} |
325 | }; | 326 | }; |
326 | MODULE_DEVICE_TABLE(usb, device_table); | 327 | MODULE_DEVICE_TABLE(usb, device_table); |
@@ -347,8 +348,11 @@ static struct usb_driver sd_driver = { | |||
347 | /* -- module insert / remove -- */ | 348 | /* -- module insert / remove -- */ |
348 | static int __init sd_mod_init(void) | 349 | static int __init sd_mod_init(void) |
349 | { | 350 | { |
350 | if (usb_register(&sd_driver) < 0) | 351 | int ret; |
351 | return -1; | 352 | |
353 | ret = usb_register(&sd_driver); | ||
354 | if (ret < 0) | ||
355 | return ret; | ||
352 | PDEBUG(D_PROBE, "registered"); | 356 | PDEBUG(D_PROBE, "registered"); |
353 | return 0; | 357 | return 0; |
354 | } | 358 | } |
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 1fff37b79891..188866ac6cef 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -50,6 +50,13 @@ static int i2c_detect_tries = 10; | |||
50 | struct sd { | 50 | struct sd { |
51 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 51 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
52 | 52 | ||
53 | char bridge; | ||
54 | #define BRIDGE_OV511 0 | ||
55 | #define BRIDGE_OV511PLUS 1 | ||
56 | #define BRIDGE_OV518 2 | ||
57 | #define BRIDGE_OV518PLUS 3 | ||
58 | #define BRIDGE_OV519 4 | ||
59 | |||
53 | /* Determined by sensor type */ | 60 | /* Determined by sensor type */ |
54 | __u8 sif; | 61 | __u8 sif; |
55 | 62 | ||
@@ -87,6 +94,9 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | |||
87 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | 94 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); |
88 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | 95 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); |
89 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | 96 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); |
97 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
98 | static void setcontrast(struct gspca_dev *gspca_dev); | ||
99 | static void setcolors(struct gspca_dev *gspca_dev); | ||
90 | 100 | ||
91 | static struct ctrl sd_ctrls[] = { | 101 | static struct ctrl sd_ctrls[] = { |
92 | { | 102 | { |
@@ -164,7 +174,7 @@ static struct ctrl sd_ctrls[] = { | |||
164 | }, | 174 | }, |
165 | }; | 175 | }; |
166 | 176 | ||
167 | static const struct v4l2_pix_format vga_mode[] = { | 177 | static const struct v4l2_pix_format ov519_vga_mode[] = { |
168 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 178 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
169 | .bytesperline = 320, | 179 | .bytesperline = 320, |
170 | .sizeimage = 320 * 240 * 3 / 8 + 590, | 180 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
@@ -176,7 +186,7 @@ static const struct v4l2_pix_format vga_mode[] = { | |||
176 | .colorspace = V4L2_COLORSPACE_JPEG, | 186 | .colorspace = V4L2_COLORSPACE_JPEG, |
177 | .priv = 0}, | 187 | .priv = 0}, |
178 | }; | 188 | }; |
179 | static const struct v4l2_pix_format sif_mode[] = { | 189 | static const struct v4l2_pix_format ov519_sif_mode[] = { |
180 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 190 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
181 | .bytesperline = 176, | 191 | .bytesperline = 176, |
182 | .sizeimage = 176 * 144 * 3 / 8 + 590, | 192 | .sizeimage = 176 * 144 * 3 / 8 + 590, |
@@ -189,6 +199,47 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
189 | .priv = 0}, | 199 | .priv = 0}, |
190 | }; | 200 | }; |
191 | 201 | ||
202 | static const struct v4l2_pix_format ov518_vga_mode[] = { | ||
203 | {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
204 | .bytesperline = 320, | ||
205 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
206 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
207 | .priv = 1}, | ||
208 | {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
209 | .bytesperline = 640, | ||
210 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
211 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
212 | .priv = 0}, | ||
213 | }; | ||
214 | static const struct v4l2_pix_format ov518_sif_mode[] = { | ||
215 | {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
216 | .bytesperline = 176, | ||
217 | .sizeimage = 40000, | ||
218 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
219 | .priv = 1}, | ||
220 | {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
221 | .bytesperline = 352, | ||
222 | .sizeimage = 352 * 288 * 3 / 8 + 590, | ||
223 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
224 | .priv = 0}, | ||
225 | }; | ||
226 | |||
227 | |||
228 | /* Registers common to OV511 / OV518 */ | ||
229 | #define R51x_SYS_RESET 0x50 | ||
230 | #define R51x_SYS_INIT 0x53 | ||
231 | #define R51x_SYS_SNAP 0x52 | ||
232 | #define R51x_SYS_CUST_ID 0x5F | ||
233 | #define R51x_COMP_LUT_BEGIN 0x80 | ||
234 | |||
235 | /* OV511 Camera interface register numbers */ | ||
236 | #define R511_SYS_LED_CTL 0x55 /* OV511+ only */ | ||
237 | #define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */ | ||
238 | |||
239 | /* OV518 Camera interface register numbers */ | ||
240 | #define R518_GPIO_OUT 0x56 /* OV518(+) only */ | ||
241 | #define R518_GPIO_CTL 0x57 /* OV518(+) only */ | ||
242 | |||
192 | /* OV519 Camera interface register numbers */ | 243 | /* OV519 Camera interface register numbers */ |
193 | #define OV519_R10_H_SIZE 0x10 | 244 | #define OV519_R10_H_SIZE 0x10 |
194 | #define OV519_R11_V_SIZE 0x11 | 245 | #define OV519_R11_V_SIZE 0x11 |
@@ -224,6 +275,8 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
224 | 275 | ||
225 | /* OV7610 registers */ | 276 | /* OV7610 registers */ |
226 | #define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ | 277 | #define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ |
278 | #define OV7610_REG_BLUE 0x01 /* blue channel balance */ | ||
279 | #define OV7610_REG_RED 0x02 /* red channel balance */ | ||
227 | #define OV7610_REG_SAT 0x03 /* saturation */ | 280 | #define OV7610_REG_SAT 0x03 /* saturation */ |
228 | #define OV8610_REG_HUE 0x04 /* 04 reserved */ | 281 | #define OV8610_REG_HUE 0x04 /* 04 reserved */ |
229 | #define OV7610_REG_CNT 0x05 /* Y contrast */ | 282 | #define OV7610_REG_CNT 0x05 /* Y contrast */ |
@@ -846,11 +899,12 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) | |||
846 | static int reg_w(struct sd *sd, __u16 index, __u8 value) | 899 | static int reg_w(struct sd *sd, __u16 index, __u8 value) |
847 | { | 900 | { |
848 | int ret; | 901 | int ret; |
902 | int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1; | ||
849 | 903 | ||
850 | sd->gspca_dev.usb_buf[0] = value; | 904 | sd->gspca_dev.usb_buf[0] = value; |
851 | ret = usb_control_msg(sd->gspca_dev.dev, | 905 | ret = usb_control_msg(sd->gspca_dev.dev, |
852 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | 906 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), |
853 | 1, /* REQ_IO (ov518/519) */ | 907 | req, |
854 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 908 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
855 | 0, index, | 909 | 0, index, |
856 | sd->gspca_dev.usb_buf, 1, 500); | 910 | sd->gspca_dev.usb_buf, 1, 500); |
@@ -864,10 +918,11 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value) | |||
864 | static int reg_r(struct sd *sd, __u16 index) | 918 | static int reg_r(struct sd *sd, __u16 index) |
865 | { | 919 | { |
866 | int ret; | 920 | int ret; |
921 | int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1; | ||
867 | 922 | ||
868 | ret = usb_control_msg(sd->gspca_dev.dev, | 923 | ret = usb_control_msg(sd->gspca_dev.dev, |
869 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | 924 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), |
870 | 1, /* REQ_IO */ | 925 | req, |
871 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 926 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
872 | 0, index, sd->gspca_dev.usb_buf, 1, 500); | 927 | 0, index, sd->gspca_dev.usb_buf, 1, 500); |
873 | 928 | ||
@@ -924,6 +979,28 @@ static int reg_w_mask(struct sd *sd, | |||
924 | } | 979 | } |
925 | 980 | ||
926 | /* | 981 | /* |
982 | * Writes multiple (n) byte value to a single register. Only valid with certain | ||
983 | * registers (0x30 and 0xc4 - 0xce). | ||
984 | */ | ||
985 | static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) | ||
986 | { | ||
987 | int ret; | ||
988 | |||
989 | *((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value); | ||
990 | |||
991 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
992 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | ||
993 | 1 /* REG_IO */, | ||
994 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
995 | 0, index, | ||
996 | sd->gspca_dev.usb_buf, n, 500); | ||
997 | if (ret < 0) | ||
998 | PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value); | ||
999 | return ret; | ||
1000 | } | ||
1001 | |||
1002 | |||
1003 | /* | ||
927 | * The OV518 I2C I/O procedure is different, hence, this function. | 1004 | * The OV518 I2C I/O procedure is different, hence, this function. |
928 | * This is normally only called from i2c_w(). Note that this function | 1005 | * This is normally only called from i2c_w(). Note that this function |
929 | * always succeeds regardless of whether the sensor is present and working. | 1006 | * always succeeds regardless of whether the sensor is present and working. |
@@ -1014,20 +1091,47 @@ static inline int ov51x_stop(struct sd *sd) | |||
1014 | { | 1091 | { |
1015 | PDEBUG(D_STREAM, "stopping"); | 1092 | PDEBUG(D_STREAM, "stopping"); |
1016 | sd->stopped = 1; | 1093 | sd->stopped = 1; |
1017 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); | 1094 | switch (sd->bridge) { |
1095 | case BRIDGE_OV511: | ||
1096 | case BRIDGE_OV511PLUS: | ||
1097 | return reg_w(sd, R51x_SYS_RESET, 0x3d); | ||
1098 | case BRIDGE_OV518: | ||
1099 | case BRIDGE_OV518PLUS: | ||
1100 | return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); | ||
1101 | case BRIDGE_OV519: | ||
1102 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); | ||
1103 | } | ||
1104 | |||
1105 | return 0; | ||
1018 | } | 1106 | } |
1019 | 1107 | ||
1020 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not | 1108 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not |
1021 | * actually stopped (for performance). */ | 1109 | * actually stopped (for performance). */ |
1022 | static inline int ov51x_restart(struct sd *sd) | 1110 | static inline int ov51x_restart(struct sd *sd) |
1023 | { | 1111 | { |
1112 | int rc; | ||
1113 | |||
1024 | PDEBUG(D_STREAM, "restarting"); | 1114 | PDEBUG(D_STREAM, "restarting"); |
1025 | if (!sd->stopped) | 1115 | if (!sd->stopped) |
1026 | return 0; | 1116 | return 0; |
1027 | sd->stopped = 0; | 1117 | sd->stopped = 0; |
1028 | 1118 | ||
1029 | /* Reinitialize the stream */ | 1119 | /* Reinitialize the stream */ |
1030 | return reg_w(sd, OV519_SYS_RESET1, 0x00); | 1120 | switch (sd->bridge) { |
1121 | case BRIDGE_OV511: | ||
1122 | case BRIDGE_OV511PLUS: | ||
1123 | return reg_w(sd, R51x_SYS_RESET, 0x00); | ||
1124 | case BRIDGE_OV518: | ||
1125 | case BRIDGE_OV518PLUS: | ||
1126 | rc = reg_w(sd, 0x2f, 0x80); | ||
1127 | if (rc < 0) | ||
1128 | return rc; | ||
1129 | return reg_w(sd, R51x_SYS_RESET, 0x00); | ||
1130 | case BRIDGE_OV519: | ||
1131 | return reg_w(sd, OV519_SYS_RESET1, 0x00); | ||
1132 | } | ||
1133 | |||
1134 | return 0; | ||
1031 | } | 1135 | } |
1032 | 1136 | ||
1033 | /* This does an initial reset of an OmniVision sensor and ensures that I2C | 1137 | /* This does an initial reset of an OmniVision sensor and ensures that I2C |
@@ -1287,16 +1391,161 @@ static int ov6xx0_configure(struct sd *sd) | |||
1287 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ | 1391 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ |
1288 | static void ov51x_led_control(struct sd *sd, int on) | 1392 | static void ov51x_led_control(struct sd *sd, int on) |
1289 | { | 1393 | { |
1290 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | 1394 | switch (sd->bridge) { |
1395 | /* OV511 has no LED control */ | ||
1396 | case BRIDGE_OV511PLUS: | ||
1397 | reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); | ||
1398 | break; | ||
1399 | case BRIDGE_OV518: | ||
1400 | case BRIDGE_OV518PLUS: | ||
1401 | reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); | ||
1402 | break; | ||
1403 | case BRIDGE_OV519: | ||
1404 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | ||
1405 | break; | ||
1406 | } | ||
1291 | } | 1407 | } |
1292 | 1408 | ||
1293 | /* this function is called at probe time */ | 1409 | /* OV518 quantization tables are 8x4 (instead of 8x8) */ |
1294 | static int sd_config(struct gspca_dev *gspca_dev, | 1410 | static int ov518_upload_quan_tables(struct sd *sd) |
1295 | const struct usb_device_id *id) | 1411 | { |
1412 | const unsigned char yQuanTable518[] = { | ||
1413 | 5, 4, 5, 6, 6, 7, 7, 7, | ||
1414 | 5, 5, 5, 5, 6, 7, 7, 7, | ||
1415 | 6, 6, 6, 6, 7, 7, 7, 8, | ||
1416 | 7, 7, 6, 7, 7, 7, 8, 8 | ||
1417 | }; | ||
1418 | |||
1419 | const unsigned char uvQuanTable518[] = { | ||
1420 | 6, 6, 6, 7, 7, 7, 7, 7, | ||
1421 | 6, 6, 6, 7, 7, 7, 7, 7, | ||
1422 | 6, 6, 6, 7, 7, 7, 7, 8, | ||
1423 | 7, 7, 7, 7, 7, 7, 8, 8 | ||
1424 | }; | ||
1425 | |||
1426 | const unsigned char *pYTable = yQuanTable518; | ||
1427 | const unsigned char *pUVTable = uvQuanTable518; | ||
1428 | unsigned char val0, val1; | ||
1429 | int i, rc, reg = R51x_COMP_LUT_BEGIN; | ||
1430 | |||
1431 | PDEBUG(D_PROBE, "Uploading quantization tables"); | ||
1432 | |||
1433 | for (i = 0; i < 16; i++) { | ||
1434 | val0 = *pYTable++; | ||
1435 | val1 = *pYTable++; | ||
1436 | val0 &= 0x0f; | ||
1437 | val1 &= 0x0f; | ||
1438 | val0 |= val1 << 4; | ||
1439 | rc = reg_w(sd, reg, val0); | ||
1440 | if (rc < 0) | ||
1441 | return rc; | ||
1442 | |||
1443 | val0 = *pUVTable++; | ||
1444 | val1 = *pUVTable++; | ||
1445 | val0 &= 0x0f; | ||
1446 | val1 &= 0x0f; | ||
1447 | val0 |= val1 << 4; | ||
1448 | rc = reg_w(sd, reg + 16, val0); | ||
1449 | if (rc < 0) | ||
1450 | return rc; | ||
1451 | |||
1452 | reg++; | ||
1453 | } | ||
1454 | |||
1455 | return 0; | ||
1456 | } | ||
1457 | |||
1458 | /* This initializes the OV518/OV518+ and the sensor */ | ||
1459 | static int ov518_configure(struct gspca_dev *gspca_dev) | ||
1296 | { | 1460 | { |
1297 | struct sd *sd = (struct sd *) gspca_dev; | 1461 | struct sd *sd = (struct sd *) gspca_dev; |
1298 | struct cam *cam; | 1462 | int rc; |
1463 | |||
1464 | /* For 518 and 518+ */ | ||
1465 | static struct ov_regvals init_518[] = { | ||
1466 | { R51x_SYS_RESET, 0x40 }, | ||
1467 | { R51x_SYS_INIT, 0xe1 }, | ||
1468 | { R51x_SYS_RESET, 0x3e }, | ||
1469 | { R51x_SYS_INIT, 0xe1 }, | ||
1470 | { R51x_SYS_RESET, 0x00 }, | ||
1471 | { R51x_SYS_INIT, 0xe1 }, | ||
1472 | { 0x46, 0x00 }, | ||
1473 | { 0x5d, 0x03 }, | ||
1474 | }; | ||
1475 | |||
1476 | static struct ov_regvals norm_518[] = { | ||
1477 | { R51x_SYS_SNAP, 0x02 }, /* Reset */ | ||
1478 | { R51x_SYS_SNAP, 0x01 }, /* Enable */ | ||
1479 | { 0x31, 0x0f }, | ||
1480 | { 0x5d, 0x03 }, | ||
1481 | { 0x24, 0x9f }, | ||
1482 | { 0x25, 0x90 }, | ||
1483 | { 0x20, 0x00 }, | ||
1484 | { 0x51, 0x04 }, | ||
1485 | { 0x71, 0x19 }, | ||
1486 | { 0x2f, 0x80 }, | ||
1487 | }; | ||
1488 | |||
1489 | static struct ov_regvals norm_518_p[] = { | ||
1490 | { R51x_SYS_SNAP, 0x02 }, /* Reset */ | ||
1491 | { R51x_SYS_SNAP, 0x01 }, /* Enable */ | ||
1492 | { 0x31, 0x0f }, | ||
1493 | { 0x5d, 0x03 }, | ||
1494 | { 0x24, 0x9f }, | ||
1495 | { 0x25, 0x90 }, | ||
1496 | { 0x20, 0x60 }, | ||
1497 | { 0x51, 0x02 }, | ||
1498 | { 0x71, 0x19 }, | ||
1499 | { 0x40, 0xff }, | ||
1500 | { 0x41, 0x42 }, | ||
1501 | { 0x46, 0x00 }, | ||
1502 | { 0x33, 0x04 }, | ||
1503 | { 0x21, 0x19 }, | ||
1504 | { 0x3f, 0x10 }, | ||
1505 | { 0x2f, 0x80 }, | ||
1506 | }; | ||
1507 | |||
1508 | /* First 5 bits of custom ID reg are a revision ID on OV518 */ | ||
1509 | PDEBUG(D_PROBE, "Device revision %d", | ||
1510 | 0x1F & reg_r(sd, R51x_SYS_CUST_ID)); | ||
1511 | |||
1512 | rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518)); | ||
1513 | if (rc < 0) | ||
1514 | return rc; | ||
1515 | |||
1516 | /* Set LED GPIO pin to output mode */ | ||
1517 | rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02); | ||
1518 | if (rc < 0) | ||
1519 | return rc; | ||
1299 | 1520 | ||
1521 | switch (sd->bridge) { | ||
1522 | case BRIDGE_OV518: | ||
1523 | rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518)); | ||
1524 | if (rc < 0) | ||
1525 | return rc; | ||
1526 | break; | ||
1527 | case BRIDGE_OV518PLUS: | ||
1528 | rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p)); | ||
1529 | if (rc < 0) | ||
1530 | return rc; | ||
1531 | break; | ||
1532 | } | ||
1533 | |||
1534 | rc = ov518_upload_quan_tables(sd); | ||
1535 | if (rc < 0) { | ||
1536 | PDEBUG(D_ERR, "Error uploading quantization tables"); | ||
1537 | return rc; | ||
1538 | } | ||
1539 | |||
1540 | rc = reg_w(sd, 0x2f, 0x80); | ||
1541 | if (rc < 0) | ||
1542 | return rc; | ||
1543 | |||
1544 | return 0; | ||
1545 | } | ||
1546 | |||
1547 | static int ov519_configure(struct sd *sd) | ||
1548 | { | ||
1300 | static const struct ov_regvals init_519[] = { | 1549 | static const struct ov_regvals init_519[] = { |
1301 | { 0x5a, 0x6d }, /* EnableSystem */ | 1550 | { 0x5a, 0x6d }, /* EnableSystem */ |
1302 | { 0x53, 0x9b }, | 1551 | { 0x53, 0x9b }, |
@@ -1313,8 +1562,32 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1313 | /* windows reads 0x55 at this point*/ | 1562 | /* windows reads 0x55 at this point*/ |
1314 | }; | 1563 | }; |
1315 | 1564 | ||
1316 | if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) | 1565 | return write_regvals(sd, init_519, ARRAY_SIZE(init_519)); |
1566 | } | ||
1567 | |||
1568 | /* this function is called at probe time */ | ||
1569 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1570 | const struct usb_device_id *id) | ||
1571 | { | ||
1572 | struct sd *sd = (struct sd *) gspca_dev; | ||
1573 | struct cam *cam; | ||
1574 | int ret = 0; | ||
1575 | |||
1576 | sd->bridge = id->driver_info; | ||
1577 | |||
1578 | switch (sd->bridge) { | ||
1579 | case BRIDGE_OV518: | ||
1580 | case BRIDGE_OV518PLUS: | ||
1581 | ret = ov518_configure(gspca_dev); | ||
1582 | break; | ||
1583 | case BRIDGE_OV519: | ||
1584 | ret = ov519_configure(sd); | ||
1585 | break; | ||
1586 | } | ||
1587 | |||
1588 | if (ret) | ||
1317 | goto error; | 1589 | goto error; |
1590 | |||
1318 | ov51x_led_control(sd, 0); /* turn LED off */ | 1591 | ov51x_led_control(sd, 0); /* turn LED off */ |
1319 | 1592 | ||
1320 | /* Test for 76xx */ | 1593 | /* Test for 76xx */ |
@@ -1360,12 +1633,26 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1360 | } | 1633 | } |
1361 | 1634 | ||
1362 | cam = &gspca_dev->cam; | 1635 | cam = &gspca_dev->cam; |
1363 | if (!sd->sif) { | 1636 | switch (sd->bridge) { |
1364 | cam->cam_mode = vga_mode; | 1637 | case BRIDGE_OV518: |
1365 | cam->nmodes = ARRAY_SIZE(vga_mode); | 1638 | case BRIDGE_OV518PLUS: |
1366 | } else { | 1639 | if (!sd->sif) { |
1367 | cam->cam_mode = sif_mode; | 1640 | cam->cam_mode = ov518_vga_mode; |
1368 | cam->nmodes = ARRAY_SIZE(sif_mode); | 1641 | cam->nmodes = ARRAY_SIZE(ov518_vga_mode); |
1642 | } else { | ||
1643 | cam->cam_mode = ov518_sif_mode; | ||
1644 | cam->nmodes = ARRAY_SIZE(ov518_sif_mode); | ||
1645 | } | ||
1646 | break; | ||
1647 | case BRIDGE_OV519: | ||
1648 | if (!sd->sif) { | ||
1649 | cam->cam_mode = ov519_vga_mode; | ||
1650 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
1651 | } else { | ||
1652 | cam->cam_mode = ov519_sif_mode; | ||
1653 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); | ||
1654 | } | ||
1655 | break; | ||
1369 | } | 1656 | } |
1370 | sd->brightness = BRIGHTNESS_DEF; | 1657 | sd->brightness = BRIGHTNESS_DEF; |
1371 | sd->contrast = CONTRAST_DEF; | 1658 | sd->contrast = CONTRAST_DEF; |
@@ -1422,6 +1709,106 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1422 | return 0; | 1709 | return 0; |
1423 | } | 1710 | } |
1424 | 1711 | ||
1712 | /* Sets up the OV518/OV518+ with the given image parameters | ||
1713 | * | ||
1714 | * OV518 needs a completely different approach, until we can figure out what | ||
1715 | * the individual registers do. Also, only 15 FPS is supported now. | ||
1716 | * | ||
1717 | * Do not put any sensor-specific code in here (including I2C I/O functions) | ||
1718 | */ | ||
1719 | static int ov518_mode_init_regs(struct sd *sd) | ||
1720 | { | ||
1721 | int hsegs, vsegs; | ||
1722 | |||
1723 | /******** Set the mode ********/ | ||
1724 | |||
1725 | reg_w(sd, 0x2b, 0); | ||
1726 | reg_w(sd, 0x2c, 0); | ||
1727 | reg_w(sd, 0x2d, 0); | ||
1728 | reg_w(sd, 0x2e, 0); | ||
1729 | reg_w(sd, 0x3b, 0); | ||
1730 | reg_w(sd, 0x3c, 0); | ||
1731 | reg_w(sd, 0x3d, 0); | ||
1732 | reg_w(sd, 0x3e, 0); | ||
1733 | |||
1734 | if (sd->bridge == BRIDGE_OV518) { | ||
1735 | /* Set 8-bit (YVYU) input format */ | ||
1736 | reg_w_mask(sd, 0x20, 0x08, 0x08); | ||
1737 | |||
1738 | /* Set 12-bit (4:2:0) output format */ | ||
1739 | reg_w_mask(sd, 0x28, 0x80, 0xf0); | ||
1740 | reg_w_mask(sd, 0x38, 0x80, 0xf0); | ||
1741 | } else { | ||
1742 | reg_w(sd, 0x28, 0x80); | ||
1743 | reg_w(sd, 0x38, 0x80); | ||
1744 | } | ||
1745 | |||
1746 | hsegs = sd->gspca_dev.width / 16; | ||
1747 | vsegs = sd->gspca_dev.height / 4; | ||
1748 | |||
1749 | reg_w(sd, 0x29, hsegs); | ||
1750 | reg_w(sd, 0x2a, vsegs); | ||
1751 | |||
1752 | reg_w(sd, 0x39, hsegs); | ||
1753 | reg_w(sd, 0x3a, vsegs); | ||
1754 | |||
1755 | /* Windows driver does this here; who knows why */ | ||
1756 | reg_w(sd, 0x2f, 0x80); | ||
1757 | |||
1758 | /******** Set the framerate (to 30 FPS) ********/ | ||
1759 | if (sd->bridge == BRIDGE_OV518PLUS) | ||
1760 | sd->clockdiv = 1; | ||
1761 | else | ||
1762 | sd->clockdiv = 0; | ||
1763 | |||
1764 | /* Mode independent, but framerate dependent, regs */ | ||
1765 | reg_w(sd, 0x51, 0x04); /* Clock divider; lower==faster */ | ||
1766 | reg_w(sd, 0x22, 0x18); | ||
1767 | reg_w(sd, 0x23, 0xff); | ||
1768 | |||
1769 | if (sd->bridge == BRIDGE_OV518PLUS) | ||
1770 | reg_w(sd, 0x21, 0x19); | ||
1771 | else | ||
1772 | reg_w(sd, 0x71, 0x17); /* Compression-related? */ | ||
1773 | |||
1774 | /* FIXME: Sensor-specific */ | ||
1775 | /* Bit 5 is what matters here. Of course, it is "reserved" */ | ||
1776 | i2c_w(sd, 0x54, 0x23); | ||
1777 | |||
1778 | reg_w(sd, 0x2f, 0x80); | ||
1779 | |||
1780 | if (sd->bridge == BRIDGE_OV518PLUS) { | ||
1781 | reg_w(sd, 0x24, 0x94); | ||
1782 | reg_w(sd, 0x25, 0x90); | ||
1783 | ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */ | ||
1784 | ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */ | ||
1785 | ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */ | ||
1786 | ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */ | ||
1787 | ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */ | ||
1788 | ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */ | ||
1789 | ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */ | ||
1790 | ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */ | ||
1791 | ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */ | ||
1792 | } else { | ||
1793 | reg_w(sd, 0x24, 0x9f); | ||
1794 | reg_w(sd, 0x25, 0x90); | ||
1795 | ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */ | ||
1796 | ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */ | ||
1797 | ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */ | ||
1798 | ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */ | ||
1799 | ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */ | ||
1800 | ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */ | ||
1801 | ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */ | ||
1802 | ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */ | ||
1803 | ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */ | ||
1804 | } | ||
1805 | |||
1806 | reg_w(sd, 0x2f, 0x80); | ||
1807 | |||
1808 | return 0; | ||
1809 | } | ||
1810 | |||
1811 | |||
1425 | /* Sets up the OV519 with the given image parameters | 1812 | /* Sets up the OV519 with the given image parameters |
1426 | * | 1813 | * |
1427 | * OV519 needs a completely different approach, until we can figure out what | 1814 | * OV519 needs a completely different approach, until we can figure out what |
@@ -1740,6 +2127,11 @@ static int set_ov_sensor_window(struct sd *sd) | |||
1740 | hwebase = 0x3a; | 2127 | hwebase = 0x3a; |
1741 | vwsbase = 0x05; | 2128 | vwsbase = 0x05; |
1742 | vwebase = 0x06; | 2129 | vwebase = 0x06; |
2130 | if (qvga) { | ||
2131 | /* HDG: this fixes U and V getting swapped */ | ||
2132 | hwsbase--; | ||
2133 | vwsbase--; | ||
2134 | } | ||
1743 | break; | 2135 | break; |
1744 | case SEN_OV7620: | 2136 | case SEN_OV7620: |
1745 | hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ | 2137 | hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ |
@@ -1855,15 +2247,28 @@ static int set_ov_sensor_window(struct sd *sd) | |||
1855 | static int sd_start(struct gspca_dev *gspca_dev) | 2247 | static int sd_start(struct gspca_dev *gspca_dev) |
1856 | { | 2248 | { |
1857 | struct sd *sd = (struct sd *) gspca_dev; | 2249 | struct sd *sd = (struct sd *) gspca_dev; |
1858 | int ret; | 2250 | int ret = 0; |
1859 | 2251 | ||
1860 | ret = ov519_mode_init_regs(sd); | 2252 | switch (sd->bridge) { |
2253 | case BRIDGE_OV518: | ||
2254 | case BRIDGE_OV518PLUS: | ||
2255 | ret = ov518_mode_init_regs(sd); | ||
2256 | break; | ||
2257 | case BRIDGE_OV519: | ||
2258 | ret = ov519_mode_init_regs(sd); | ||
2259 | break; | ||
2260 | } | ||
1861 | if (ret < 0) | 2261 | if (ret < 0) |
1862 | goto out; | 2262 | goto out; |
2263 | |||
1863 | ret = set_ov_sensor_window(sd); | 2264 | ret = set_ov_sensor_window(sd); |
1864 | if (ret < 0) | 2265 | if (ret < 0) |
1865 | goto out; | 2266 | goto out; |
1866 | 2267 | ||
2268 | setcontrast(gspca_dev); | ||
2269 | setbrightness(gspca_dev); | ||
2270 | setcolors(gspca_dev); | ||
2271 | |||
1867 | ret = ov51x_restart(sd); | 2272 | ret = ov51x_restart(sd); |
1868 | if (ret < 0) | 2273 | if (ret < 0) |
1869 | goto out; | 2274 | goto out; |
@@ -1882,7 +2287,30 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1882 | ov51x_led_control(sd, 0); | 2287 | ov51x_led_control(sd, 0); |
1883 | } | 2288 | } |
1884 | 2289 | ||
1885 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 2290 | static void ov518_pkt_scan(struct gspca_dev *gspca_dev, |
2291 | struct gspca_frame *frame, /* target */ | ||
2292 | __u8 *data, /* isoc packet */ | ||
2293 | int len) /* iso packet length */ | ||
2294 | { | ||
2295 | PDEBUG(D_STREAM, "ov518_pkt_scan: %d bytes", len); | ||
2296 | |||
2297 | if (len & 7) { | ||
2298 | len--; | ||
2299 | PDEBUG(D_STREAM, "packet number: %d\n", (int)data[len]); | ||
2300 | } | ||
2301 | |||
2302 | /* A false positive here is likely, until OVT gives me | ||
2303 | * the definitive SOF/EOF format */ | ||
2304 | if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { | ||
2305 | gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); | ||
2306 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); | ||
2307 | } | ||
2308 | |||
2309 | /* intermediate packet */ | ||
2310 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
2311 | } | ||
2312 | |||
2313 | static void ov519_pkt_scan(struct gspca_dev *gspca_dev, | ||
1886 | struct gspca_frame *frame, /* target */ | 2314 | struct gspca_frame *frame, /* target */ |
1887 | __u8 *data, /* isoc packet */ | 2315 | __u8 *data, /* isoc packet */ |
1888 | int len) /* iso packet length */ | 2316 | int len) /* iso packet length */ |
@@ -1926,6 +2354,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1926 | data, len); | 2354 | data, len); |
1927 | } | 2355 | } |
1928 | 2356 | ||
2357 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
2358 | struct gspca_frame *frame, /* target */ | ||
2359 | __u8 *data, /* isoc packet */ | ||
2360 | int len) /* iso packet length */ | ||
2361 | { | ||
2362 | struct sd *sd = (struct sd *) gspca_dev; | ||
2363 | |||
2364 | switch (sd->bridge) { | ||
2365 | case BRIDGE_OV511: | ||
2366 | case BRIDGE_OV511PLUS: | ||
2367 | break; | ||
2368 | case BRIDGE_OV518: | ||
2369 | case BRIDGE_OV518PLUS: | ||
2370 | ov518_pkt_scan(gspca_dev, frame, data, len); | ||
2371 | break; | ||
2372 | case BRIDGE_OV519: | ||
2373 | ov519_pkt_scan(gspca_dev, frame, data, len); | ||
2374 | break; | ||
2375 | } | ||
2376 | } | ||
2377 | |||
1929 | /* -- management routines -- */ | 2378 | /* -- management routines -- */ |
1930 | 2379 | ||
1931 | static void setbrightness(struct gspca_dev *gspca_dev) | 2380 | static void setbrightness(struct gspca_dev *gspca_dev) |
@@ -1970,6 +2419,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
1970 | break; | 2419 | break; |
1971 | case SEN_OV6630: | 2420 | case SEN_OV6630: |
1972 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); | 2421 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); |
2422 | break; | ||
1973 | case SEN_OV8610: { | 2423 | case SEN_OV8610: { |
1974 | static const __u8 ctab[] = { | 2424 | static const __u8 ctab[] = { |
1975 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f | 2425 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f |
@@ -2136,19 +2586,21 @@ static const struct sd_desc sd_desc = { | |||
2136 | 2586 | ||
2137 | /* -- module initialisation -- */ | 2587 | /* -- module initialisation -- */ |
2138 | static const __devinitdata struct usb_device_id device_table[] = { | 2588 | static const __devinitdata struct usb_device_id device_table[] = { |
2139 | {USB_DEVICE(0x041e, 0x4052)}, | 2589 | {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 }, |
2140 | {USB_DEVICE(0x041e, 0x405f)}, | 2590 | {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, |
2141 | {USB_DEVICE(0x041e, 0x4060)}, | 2591 | {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, |
2142 | {USB_DEVICE(0x041e, 0x4061)}, | 2592 | {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, |
2143 | {USB_DEVICE(0x041e, 0x4064)}, | 2593 | {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 }, |
2144 | {USB_DEVICE(0x041e, 0x4068)}, | 2594 | {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 }, |
2145 | {USB_DEVICE(0x045e, 0x028c)}, | 2595 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, |
2146 | {USB_DEVICE(0x054c, 0x0154)}, | 2596 | {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, |
2147 | {USB_DEVICE(0x054c, 0x0155)}, | 2597 | {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 }, |
2148 | {USB_DEVICE(0x05a9, 0x0519)}, | 2598 | {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, |
2149 | {USB_DEVICE(0x05a9, 0x0530)}, | 2599 | {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, |
2150 | {USB_DEVICE(0x05a9, 0x4519)}, | 2600 | {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 }, |
2151 | {USB_DEVICE(0x05a9, 0x8519)}, | 2601 | {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 }, |
2602 | {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 }, | ||
2603 | {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS }, | ||
2152 | {} | 2604 | {} |
2153 | }; | 2605 | }; |
2154 | 2606 | ||
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 19e0bc60de14..4b528b372911 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c | |||
@@ -60,10 +60,23 @@ struct sd { | |||
60 | static struct ctrl sd_ctrls[] = { | 60 | static struct ctrl sd_ctrls[] = { |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static const struct v4l2_pix_format vga_mode[] = { | 63 | static const struct v4l2_pix_format vga_yuyv_mode[] = { |
64 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 64 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
65 | .bytesperline = 640 * 2, | 65 | .bytesperline = 640 * 2, |
66 | .sizeimage = 640 * 480 * 2, | 66 | .sizeimage = 640 * 480 * 2, |
67 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
68 | .priv = 0}, | ||
69 | }; | ||
70 | |||
71 | static const struct v4l2_pix_format vga_jpeg_mode[] = { | ||
72 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
73 | .bytesperline = 320, | ||
74 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
75 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
76 | .priv = 1}, | ||
77 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
78 | .bytesperline = 640, | ||
79 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
67 | .colorspace = V4L2_COLORSPACE_JPEG, | 80 | .colorspace = V4L2_COLORSPACE_JPEG, |
68 | .priv = 0}, | 81 | .priv = 0}, |
69 | }; | 82 | }; |
@@ -244,7 +257,7 @@ static const u8 bridge_init_ov965x[][2] = { | |||
244 | }; | 257 | }; |
245 | 258 | ||
246 | static const u8 sensor_init_ov965x[][2] = { | 259 | static const u8 sensor_init_ov965x[][2] = { |
247 | {0x12, 0x80}, /* com7 - reset */ | 260 | {0x12, 0x80}, /* com7 - SSCB reset */ |
248 | {0x00, 0x00}, /* gain */ | 261 | {0x00, 0x00}, /* gain */ |
249 | {0x01, 0x80}, /* blue */ | 262 | {0x01, 0x80}, /* blue */ |
250 | {0x02, 0x80}, /* red */ | 263 | {0x02, 0x80}, /* red */ |
@@ -254,10 +267,10 @@ static const u8 sensor_init_ov965x[][2] = { | |||
254 | {0x0e, 0x61}, /* com5 */ | 267 | {0x0e, 0x61}, /* com5 */ |
255 | {0x0f, 0x42}, /* com6 */ | 268 | {0x0f, 0x42}, /* com6 */ |
256 | {0x11, 0x00}, /* clkrc */ | 269 | {0x11, 0x00}, /* clkrc */ |
257 | {0x12, 0x02}, /* com7 */ | 270 | {0x12, 0x02}, /* com7 - 15fps VGA YUYV */ |
258 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | 271 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
259 | {0x14, 0x28}, /* com9 */ | 272 | {0x14, 0x28}, /* com9 */ |
260 | {0x16, 0x24}, /* rsvd16 */ | 273 | {0x16, 0x24}, /* reg16 */ |
261 | {0x17, 0x1d}, /* hstart*/ | 274 | {0x17, 0x1d}, /* hstart*/ |
262 | {0x18, 0xbd}, /* hstop */ | 275 | {0x18, 0xbd}, /* hstop */ |
263 | {0x19, 0x01}, /* vstrt */ | 276 | {0x19, 0x01}, /* vstrt */ |
@@ -269,24 +282,24 @@ static const u8 sensor_init_ov965x[][2] = { | |||
269 | {0x27, 0x08}, /* bbias */ | 282 | {0x27, 0x08}, /* bbias */ |
270 | {0x28, 0x08}, /* gbbias */ | 283 | {0x28, 0x08}, /* gbbias */ |
271 | {0x29, 0x15}, /* gr com */ | 284 | {0x29, 0x15}, /* gr com */ |
272 | {0x2a, 0x00}, | 285 | {0x2a, 0x00}, /* exhch */ |
273 | {0x2b, 0x00}, | 286 | {0x2b, 0x00}, /* exhcl */ |
274 | {0x2c, 0x08}, /* rbias */ | 287 | {0x2c, 0x08}, /* rbias */ |
275 | {0x32, 0xff}, /* href */ | 288 | {0x32, 0xff}, /* href */ |
276 | {0x33, 0x00}, /* chlf */ | 289 | {0x33, 0x00}, /* chlf */ |
277 | {0x34, 0x3f}, /* arblm */ | 290 | {0x34, 0x3f}, /* aref1 */ |
278 | {0x35, 0x00}, /* rsvd35 */ | 291 | {0x35, 0x00}, /* aref2 */ |
279 | {0x36, 0xf8}, /* rsvd36 */ | 292 | {0x36, 0xf8}, /* aref3 */ |
280 | {0x38, 0x72}, /* acom38 */ | 293 | {0x38, 0x72}, /* adc2 */ |
281 | {0x39, 0x57}, /* ofon */ | 294 | {0x39, 0x57}, /* aref4 */ |
282 | {0x3a, 0x80}, /* tslb */ | 295 | {0x3a, 0x80}, /* tslb - yuyv */ |
283 | {0x3b, 0xc4}, | 296 | {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ |
284 | {0x3d, 0x99}, /* com13 */ | 297 | {0x3d, 0x99}, /* com13 */ |
285 | {0x3f, 0xc1}, | 298 | {0x3f, 0xc1}, /* edge */ |
286 | {0x40, 0xc0}, /* com15 */ | 299 | {0x40, 0xc0}, /* com15 */ |
287 | {0x41, 0x40}, /* com16 */ | 300 | {0x41, 0x40}, /* com16 */ |
288 | {0x42, 0xc0}, | 301 | {0x42, 0xc0}, /* com17 */ |
289 | {0x43, 0x0a}, | 302 | {0x43, 0x0a}, /* rsvd */ |
290 | {0x44, 0xf0}, | 303 | {0x44, 0xf0}, |
291 | {0x45, 0x46}, | 304 | {0x45, 0x46}, |
292 | {0x46, 0x62}, | 305 | {0x46, 0x62}, |
@@ -297,22 +310,22 @@ static const u8 sensor_init_ov965x[][2] = { | |||
297 | {0x4c, 0x7f}, | 310 | {0x4c, 0x7f}, |
298 | {0x4d, 0x7f}, | 311 | {0x4d, 0x7f}, |
299 | {0x4e, 0x7f}, | 312 | {0x4e, 0x7f}, |
300 | {0x4f, 0x98}, | 313 | {0x4f, 0x98}, /* matrix */ |
301 | {0x50, 0x98}, | 314 | {0x50, 0x98}, |
302 | {0x51, 0x00}, | 315 | {0x51, 0x00}, |
303 | {0x52, 0x28}, | 316 | {0x52, 0x28}, |
304 | {0x53, 0x70}, | 317 | {0x53, 0x70}, |
305 | {0x54, 0x98}, | 318 | {0x54, 0x98}, |
306 | {0x58, 0x1a}, | 319 | {0x58, 0x1a}, /* matrix coef sign */ |
307 | {0x59, 0x85}, | 320 | {0x59, 0x85}, /* AWB control */ |
308 | {0x5a, 0xa9}, | 321 | {0x5a, 0xa9}, |
309 | {0x5b, 0x64}, | 322 | {0x5b, 0x64}, |
310 | {0x5c, 0x84}, | 323 | {0x5c, 0x84}, |
311 | {0x5d, 0x53}, | 324 | {0x5d, 0x53}, |
312 | {0x5e, 0x0e}, | 325 | {0x5e, 0x0e}, |
313 | {0x5f, 0xf0}, | 326 | {0x5f, 0xf0}, /* AWB blue limit */ |
314 | {0x60, 0xf0}, | 327 | {0x60, 0xf0}, /* AWB red limit */ |
315 | {0x61, 0xf0}, | 328 | {0x61, 0xf0}, /* AWB green limit */ |
316 | {0x62, 0x00}, /* lcc1 */ | 329 | {0x62, 0x00}, /* lcc1 */ |
317 | {0x63, 0x00}, /* lcc2 */ | 330 | {0x63, 0x00}, /* lcc2 */ |
318 | {0x64, 0x02}, /* lcc3 */ | 331 | {0x64, 0x02}, /* lcc3 */ |
@@ -324,15 +337,15 @@ static const u8 sensor_init_ov965x[][2] = { | |||
324 | {0x6d, 0x55}, | 337 | {0x6d, 0x55}, |
325 | {0x6e, 0x00}, | 338 | {0x6e, 0x00}, |
326 | {0x6f, 0x9d}, | 339 | {0x6f, 0x9d}, |
327 | {0x70, 0x21}, | 340 | {0x70, 0x21}, /* dnsth */ |
328 | {0x71, 0x78}, | 341 | {0x71, 0x78}, |
329 | {0x72, 0x00}, | 342 | {0x72, 0x00}, /* poidx */ |
330 | {0x73, 0x01}, | 343 | {0x73, 0x01}, /* pckdv */ |
331 | {0x74, 0x3a}, | 344 | {0x74, 0x3a}, /* xindx */ |
332 | {0x75, 0x35}, | 345 | {0x75, 0x35}, /* yindx */ |
333 | {0x76, 0x01}, | 346 | {0x76, 0x01}, |
334 | {0x77, 0x02}, | 347 | {0x77, 0x02}, |
335 | {0x7a, 0x12}, | 348 | {0x7a, 0x12}, /* gamma curve */ |
336 | {0x7b, 0x08}, | 349 | {0x7b, 0x08}, |
337 | {0x7c, 0x16}, | 350 | {0x7c, 0x16}, |
338 | {0x7d, 0x30}, | 351 | {0x7d, 0x30}, |
@@ -349,33 +362,33 @@ static const u8 sensor_init_ov965x[][2] = { | |||
349 | {0x88, 0xe6}, | 362 | {0x88, 0xe6}, |
350 | {0x89, 0xf2}, | 363 | {0x89, 0xf2}, |
351 | {0x8a, 0x03}, | 364 | {0x8a, 0x03}, |
352 | {0x8c, 0x89}, | 365 | {0x8c, 0x89}, /* com19 */ |
353 | {0x14, 0x28}, /* com9 */ | 366 | {0x14, 0x28}, /* com9 */ |
354 | {0x90, 0x7d}, | 367 | {0x90, 0x7d}, |
355 | {0x91, 0x7b}, | 368 | {0x91, 0x7b}, |
356 | {0x9d, 0x03}, | 369 | {0x9d, 0x03}, /* lcc6 */ |
357 | {0x9e, 0x04}, | 370 | {0x9e, 0x04}, /* lcc7 */ |
358 | {0x9f, 0x7a}, | 371 | {0x9f, 0x7a}, |
359 | {0xa0, 0x79}, | 372 | {0xa0, 0x79}, |
360 | {0xa1, 0x40}, /* aechm */ | 373 | {0xa1, 0x40}, /* aechm */ |
361 | {0xa4, 0x50}, | 374 | {0xa4, 0x50}, /* com21 */ |
362 | {0xa5, 0x68}, /* com26 */ | 375 | {0xa5, 0x68}, /* com26 */ |
363 | {0xa6, 0x4a}, | 376 | {0xa6, 0x4a}, /* AWB green */ |
364 | {0xa8, 0xc1}, /* acoma8 */ | 377 | {0xa8, 0xc1}, /* refa8 */ |
365 | {0xa9, 0xef}, /* acoma9 */ | 378 | {0xa9, 0xef}, /* refa9 */ |
366 | {0xaa, 0x92}, | 379 | {0xaa, 0x92}, |
367 | {0xab, 0x04}, | 380 | {0xab, 0x04}, |
368 | {0xac, 0x80}, | 381 | {0xac, 0x80}, /* black level control */ |
369 | {0xad, 0x80}, | 382 | {0xad, 0x80}, |
370 | {0xae, 0x80}, | 383 | {0xae, 0x80}, |
371 | {0xaf, 0x80}, | 384 | {0xaf, 0x80}, |
372 | {0xb2, 0xf2}, | 385 | {0xb2, 0xf2}, |
373 | {0xb3, 0x20}, | 386 | {0xb3, 0x20}, |
374 | {0xb4, 0x20}, | 387 | {0xb4, 0x20}, /* ctrlb4 */ |
375 | {0xb5, 0x00}, | 388 | {0xb5, 0x00}, |
376 | {0xb6, 0xaf}, | 389 | {0xb6, 0xaf}, |
377 | {0xbb, 0xae}, | 390 | {0xbb, 0xae}, |
378 | {0xbc, 0x7f}, | 391 | {0xbc, 0x7f}, /* ADC channel offsets */ |
379 | {0xdb, 0x7f}, | 392 | {0xdb, 0x7f}, |
380 | {0xbe, 0x7f}, | 393 | {0xbe, 0x7f}, |
381 | {0xbf, 0x7f}, | 394 | {0xbf, 0x7f}, |
@@ -384,7 +397,7 @@ static const u8 sensor_init_ov965x[][2] = { | |||
384 | {0xc2, 0x01}, | 397 | {0xc2, 0x01}, |
385 | {0xc3, 0x4e}, | 398 | {0xc3, 0x4e}, |
386 | {0xc6, 0x85}, | 399 | {0xc6, 0x85}, |
387 | {0xc7, 0x80}, | 400 | {0xc7, 0x80}, /* com24 */ |
388 | {0xc9, 0xe0}, | 401 | {0xc9, 0xe0}, |
389 | {0xca, 0xe8}, | 402 | {0xca, 0xe8}, |
390 | {0xcb, 0xf0}, | 403 | {0xcb, 0xf0}, |
@@ -399,11 +412,11 @@ static const u8 sensor_init_ov965x[][2] = { | |||
399 | {0x58, 0x1a}, | 412 | {0x58, 0x1a}, |
400 | {0xff, 0x41}, /* read 41, write ff 00 */ | 413 | {0xff, 0x41}, /* read 41, write ff 00 */ |
401 | {0x41, 0x40}, /* com16 */ | 414 | {0x41, 0x40}, /* com16 */ |
402 | {0xc5, 0x03}, | 415 | {0xc5, 0x03}, /* 60 Hz banding filter */ |
403 | {0x6a, 0x02}, | 416 | {0x6a, 0x02}, /* 50 Hz banding filter */ |
404 | 417 | ||
405 | {0x12, 0x62}, /* com7 - VGA + CIF */ | 418 | {0x12, 0x62}, /* com7 - 30fps VGA YUV */ |
406 | {0x36, 0xfa}, /* rsvd36 */ | 419 | {0x36, 0xfa}, /* aref3 */ |
407 | {0x69, 0x0a}, /* hv */ | 420 | {0x69, 0x0a}, /* hv */ |
408 | {0x8c, 0x89}, /* com22 */ | 421 | {0x8c, 0x89}, /* com22 */ |
409 | {0x14, 0x28}, /* com9 */ | 422 | {0x14, 0x28}, /* com9 */ |
@@ -442,8 +455,8 @@ static const u8 bridge_init_ov965x_2[][2] = { | |||
442 | {0x52, 0x3c}, | 455 | {0x52, 0x3c}, |
443 | {0x53, 0x00}, | 456 | {0x53, 0x00}, |
444 | {0x54, 0x00}, | 457 | {0x54, 0x00}, |
445 | {0x55, 0x00}, | 458 | {0x55, 0x00}, /* brightness */ |
446 | {0x57, 0x00}, | 459 | {0x57, 0x00}, /* contrast 2 */ |
447 | {0x5c, 0x00}, | 460 | {0x5c, 0x00}, |
448 | {0x5a, 0xa0}, | 461 | {0x5a, 0xa0}, |
449 | {0x5b, 0x78}, | 462 | {0x5b, 0x78}, |
@@ -489,9 +502,66 @@ static const u8 sensor_init_ov965x_2[][2] = { | |||
489 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | 502 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
490 | }; | 503 | }; |
491 | 504 | ||
505 | static const u8 sensor_start_ov965x[][2] = { | ||
506 | {0x12, 0x62}, /* com7 - 30fps VGA YUV */ | ||
507 | {0x36, 0xfa}, /* aref3 */ | ||
508 | {0x69, 0x0a}, /* hv */ | ||
509 | {0x8c, 0x89}, /* com22 */ | ||
510 | {0x14, 0x28}, /* com9 */ | ||
511 | {0x3e, 0x0c}, /* com14 */ | ||
512 | {0x41, 0x40}, /* com16 */ | ||
513 | {0x72, 0x00}, | ||
514 | {0x73, 0x00}, | ||
515 | {0x74, 0x3a}, | ||
516 | {0x75, 0x35}, | ||
517 | {0x76, 0x01}, | ||
518 | {0xc7, 0x80}, /* com24 */ | ||
519 | {0x03, 0x12}, /* vref */ | ||
520 | {0x17, 0x16}, /* hstart */ | ||
521 | {0x18, 0x02}, /* hstop */ | ||
522 | {0x19, 0x01}, /* vstrt */ | ||
523 | {0x1a, 0x3d}, /* vstop */ | ||
524 | {0x32, 0xff}, /* href */ | ||
525 | {0xc0, 0xaa}, | ||
526 | {} | ||
527 | }; | ||
528 | |||
492 | static const u8 bridge_start_ov965x[][2] = { | 529 | static const u8 bridge_start_ov965x[][2] = { |
530 | {0x94, 0xaa}, | ||
531 | {0xf1, 0x60}, | ||
532 | {0xe5, 0x04}, | ||
533 | {0xc0, 0x50}, | ||
534 | {0xc1, 0x3c}, | ||
535 | {0x8c, 0x00}, | ||
536 | {0x8d, 0x1c}, | ||
537 | {0x34, 0x05}, | ||
538 | {} | ||
539 | }; | ||
540 | |||
541 | static const u8 bridge_start_ov965x_vga[][2] = { | ||
542 | {0xc2, 0x0c}, | ||
543 | {0xc3, 0xf9}, | ||
544 | {0xda, 0x01}, | ||
545 | {0x50, 0x00}, | ||
546 | {0x51, 0xa0}, | ||
547 | {0x52, 0x3c}, | ||
548 | {0x53, 0x00}, | ||
549 | {0x54, 0x00}, | ||
550 | {0x55, 0x00}, | ||
551 | {0x57, 0x00}, | ||
552 | {0x5c, 0x00}, | ||
553 | {0x5a, 0xa0}, | ||
554 | {0x5b, 0x78}, | ||
555 | {0x35, 0x02}, | ||
556 | {0xd9, 0x10}, | ||
557 | {0x94, 0x11}, | ||
558 | {} | ||
559 | }; | ||
560 | |||
561 | static const u8 bridge_start_ov965x_cif[][2] = { | ||
493 | {0xc2, 0x4c}, | 562 | {0xc2, 0x4c}, |
494 | {0xc3, 0xf9}, | 563 | {0xc3, 0xf9}, |
564 | {0xda, 0x00}, | ||
495 | {0x50, 0x00}, | 565 | {0x50, 0x00}, |
496 | {0x51, 0xa0}, | 566 | {0x51, 0xa0}, |
497 | {0x52, 0x78}, | 567 | {0x52, 0x78}, |
@@ -500,30 +570,54 @@ static const u8 bridge_start_ov965x[][2] = { | |||
500 | {0x55, 0x00}, | 570 | {0x55, 0x00}, |
501 | {0x57, 0x00}, | 571 | {0x57, 0x00}, |
502 | {0x5c, 0x00}, | 572 | {0x5c, 0x00}, |
503 | {0x5a, 0x28}, | 573 | {0x5a, 0x50}, |
504 | {0x5b, 0x1e}, | 574 | {0x5b, 0x3c}, |
505 | {0x35, 0x00}, | 575 | {0x35, 0x02}, |
506 | {0xd9, 0x21}, | 576 | {0xd9, 0x10}, |
507 | {0x94, 0x11}, | 577 | {0x94, 0x11}, |
578 | {} | ||
508 | }; | 579 | }; |
509 | 580 | ||
510 | static const u8 sensor_start_ov965x[][2] = { | 581 | static const u8 sensor_start_ov965x_vga[][2] = { |
511 | {0x3b, 0xe4}, | 582 | {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ |
583 | {0x1e, 0x04}, /* mvfp */ | ||
584 | {0x13, 0xe0}, /* com8 */ | ||
585 | {0x00, 0x00}, | ||
586 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | ||
587 | {0x11, 0x03}, /* clkrc */ | ||
588 | {0x6b, 0x5a}, /* dblv */ | ||
589 | {0x6a, 0x05}, /* 50 Hz banding filter */ | ||
590 | {0xc5, 0x07}, /* 60 Hz banding filter */ | ||
591 | {0xa2, 0x4b}, /* bd50 */ | ||
592 | {0xa3, 0x3e}, /* bd60 */ | ||
593 | |||
594 | {0x2d, 0x00}, /* advfl */ | ||
595 | {} | ||
596 | }; | ||
597 | |||
598 | static const u8 sensor_start_ov965x_cif[][2] = { | ||
599 | {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ | ||
512 | {0x1e, 0x04}, /* mvfp */ | 600 | {0x1e, 0x04}, /* mvfp */ |
513 | {0x13, 0xe0}, /* com8 */ | 601 | {0x13, 0xe0}, /* com8 */ |
514 | {0x00, 0x00}, | 602 | {0x00, 0x00}, |
515 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | 603 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
516 | {0x11, 0x01}, /* clkrc */ | 604 | {0x11, 0x01}, /* clkrc */ |
517 | {0x6b, 0x5a}, /* dblv */ | 605 | {0x6b, 0x5a}, /* dblv */ |
518 | {0x6a, 0x02}, | 606 | {0x6a, 0x02}, /* 50 Hz banding filter */ |
519 | {0xc5, 0x03}, | 607 | {0xc5, 0x03}, /* 60 Hz banding filter */ |
520 | {0xa2, 0x96}, | 608 | {0xa2, 0x96}, /* bd50 */ |
521 | {0xa3, 0x7d}, | 609 | {0xa3, 0x7d}, /* bd60 */ |
610 | |||
522 | {0xff, 0x13}, /* read 13, write ff 00 */ | 611 | {0xff, 0x13}, /* read 13, write ff 00 */ |
523 | {0x13, 0xe7}, | 612 | {0x13, 0xe7}, |
524 | {0x3a, 0x80}, | 613 | {0x3a, 0x80}, /* tslb - yuyv */ |
614 | {} | ||
615 | }; | ||
616 | |||
617 | static const u8 sensor_start_ov965x_2[][2] = { | ||
525 | {0xff, 0x42}, /* read 42, write ff 00 */ | 618 | {0xff, 0x42}, /* read 42, write ff 00 */ |
526 | {0x42, 0xc1}, | 619 | {0x42, 0xc1}, /* com17 - 50 Hz filter */ |
620 | {} | ||
527 | }; | 621 | }; |
528 | 622 | ||
529 | 623 | ||
@@ -705,11 +799,17 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
705 | 799 | ||
706 | cam = &gspca_dev->cam; | 800 | cam = &gspca_dev->cam; |
707 | 801 | ||
708 | cam->cam_mode = vga_mode; | 802 | if (sd->sensor == SENSOR_OV772X) { |
709 | cam->nmodes = ARRAY_SIZE(vga_mode); | 803 | cam->cam_mode = vga_yuyv_mode; |
804 | cam->nmodes = ARRAY_SIZE(vga_yuyv_mode); | ||
710 | 805 | ||
711 | cam->bulk_size = 16384; | 806 | cam->bulk = 1; |
712 | cam->bulk_nurbs = 2; | 807 | cam->bulk_size = 16384; |
808 | cam->bulk_nurbs = 2; | ||
809 | } else { /* ov965x */ | ||
810 | cam->cam_mode = vga_jpeg_mode; | ||
811 | cam->nmodes = ARRAY_SIZE(vga_jpeg_mode); | ||
812 | } | ||
713 | 813 | ||
714 | return 0; | 814 | return 0; |
715 | } | 815 | } |
@@ -778,6 +878,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
778 | static int sd_start(struct gspca_dev *gspca_dev) | 878 | static int sd_start(struct gspca_dev *gspca_dev) |
779 | { | 879 | { |
780 | struct sd *sd = (struct sd *) gspca_dev; | 880 | struct sd *sd = (struct sd *) gspca_dev; |
881 | int mode; | ||
781 | 882 | ||
782 | switch (sd->sensor) { | 883 | switch (sd->sensor) { |
783 | case SENSOR_OV772X: | 884 | case SENSOR_OV772X: |
@@ -786,13 +887,28 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
786 | break; | 887 | break; |
787 | default: | 888 | default: |
788 | /* case SENSOR_OV965X: */ | 889 | /* case SENSOR_OV965X: */ |
789 | reg_w_array(gspca_dev, bridge_start_ov965x, | 890 | |
790 | ARRAY_SIZE(bridge_start_ov965x)); | ||
791 | sccb_w_array(gspca_dev, sensor_start_ov965x, | 891 | sccb_w_array(gspca_dev, sensor_start_ov965x, |
792 | ARRAY_SIZE(sensor_start_ov965x)); | 892 | ARRAY_SIZE(sensor_start_ov965x)); |
893 | reg_w_array(gspca_dev, bridge_start_ov965x, | ||
894 | ARRAY_SIZE(bridge_start_ov965x)); | ||
895 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; | ||
896 | if (mode != 0) { /* 320x240 */ | ||
897 | reg_w_array(gspca_dev, bridge_start_ov965x_cif, | ||
898 | ARRAY_SIZE(bridge_start_ov965x_cif)); | ||
899 | sccb_w_array(gspca_dev, sensor_start_ov965x_cif, | ||
900 | ARRAY_SIZE(sensor_start_ov965x_cif)); | ||
901 | } else { /* 640x480 */ | ||
902 | reg_w_array(gspca_dev, bridge_start_ov965x_vga, | ||
903 | ARRAY_SIZE(bridge_start_ov965x_vga)); | ||
904 | sccb_w_array(gspca_dev, sensor_start_ov965x_vga, | ||
905 | ARRAY_SIZE(sensor_start_ov965x_vga)); | ||
906 | } | ||
907 | sccb_w_array(gspca_dev, sensor_start_ov965x_2, | ||
908 | ARRAY_SIZE(sensor_start_ov965x_2)); | ||
909 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | ||
793 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | 910 | ov534_reg_write(gspca_dev, 0xe0, 0x00); |
794 | ov534_set_led(gspca_dev, 1); | 911 | ov534_set_led(gspca_dev, 1); |
795 | /*fixme: other sensor start omitted*/ | ||
796 | } | 912 | } |
797 | return 0; | 913 | return 0; |
798 | } | 914 | } |
@@ -832,9 +948,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, | |||
832 | __u32 this_pts; | 948 | __u32 this_pts; |
833 | u16 this_fid; | 949 | u16 this_fid; |
834 | int remaining_len = len; | 950 | int remaining_len = len; |
951 | int payload_len; | ||
835 | 952 | ||
953 | payload_len = gspca_dev->cam.bulk ? 2048 : 2040; | ||
836 | do { | 954 | do { |
837 | len = min(remaining_len, 2040); /*fixme: was 2048*/ | 955 | len = min(remaining_len, payload_len); |
838 | 956 | ||
839 | /* Payloads are prefixed with a UVC-style header. We | 957 | /* Payloads are prefixed with a UVC-style header. We |
840 | consider a frame to start when the FID toggles, or the PTS | 958 | consider a frame to start when the FID toggles, or the PTS |
@@ -864,30 +982,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, | |||
864 | 982 | ||
865 | /* If PTS or FID has changed, start a new frame. */ | 983 | /* If PTS or FID has changed, start a new frame. */ |
866 | if (this_pts != sd->last_pts || this_fid != sd->last_fid) { | 984 | if (this_pts != sd->last_pts || this_fid != sd->last_fid) { |
867 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 985 | if (gspca_dev->last_packet_type == INTER_PACKET) |
868 | NULL, 0); | 986 | frame = gspca_frame_add(gspca_dev, |
987 | LAST_PACKET, frame, | ||
988 | NULL, 0); | ||
869 | sd->last_pts = this_pts; | 989 | sd->last_pts = this_pts; |
870 | sd->last_fid = this_fid; | 990 | sd->last_fid = this_fid; |
871 | } | 991 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, |
872 | |||
873 | /* Add the data from this payload */ | ||
874 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
875 | data + 12, len - 12); | 992 | data + 12, len - 12); |
876 | |||
877 | /* If this packet is marked as EOF, end the frame */ | 993 | /* If this packet is marked as EOF, end the frame */ |
878 | if (data[1] & UVC_STREAM_EOF) { | 994 | } else if (data[1] & UVC_STREAM_EOF) { |
879 | sd->last_pts = 0; | 995 | sd->last_pts = 0; |
880 | |||
881 | if (frame->data_end - frame->data != | ||
882 | gspca_dev->width * gspca_dev->height * 2) { | ||
883 | PDEBUG(D_PACK, "short frame"); | ||
884 | goto discard; | ||
885 | } | ||
886 | |||
887 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 996 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, |
888 | NULL, 0); | 997 | data + 12, len - 12); |
998 | } else { | ||
999 | |||
1000 | /* Add the data from this payload */ | ||
1001 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1002 | data + 12, len - 12); | ||
889 | } | 1003 | } |
890 | 1004 | ||
1005 | |||
891 | /* Done this payload */ | 1006 | /* Done this payload */ |
892 | goto scan_next; | 1007 | goto scan_next; |
893 | 1008 | ||
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 153d0a91d4b5..cf3af8de6e97 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -877,6 +877,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
877 | cam->cam_mode = sif_mode; | 877 | cam->cam_mode = sif_mode; |
878 | cam->nmodes = ARRAY_SIZE(sif_mode); | 878 | cam->nmodes = ARRAY_SIZE(sif_mode); |
879 | } | 879 | } |
880 | cam->npkt = 36; /* 36 packets per ISOC message */ | ||
881 | |||
880 | sd->brightness = BRIGHTNESS_DEF; | 882 | sd->brightness = BRIGHTNESS_DEF; |
881 | sd->gain = GAIN_DEF; | 883 | sd->gain = GAIN_DEF; |
882 | sd->exposure = EXPOSURE_DEF; | 884 | sd->exposure = EXPOSURE_DEF; |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index c72e19d3ac37..dc6a6f11354a 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -62,7 +62,6 @@ struct sd { | |||
62 | #define BRIDGE_SN9C105 1 | 62 | #define BRIDGE_SN9C105 1 |
63 | #define BRIDGE_SN9C110 2 | 63 | #define BRIDGE_SN9C110 2 |
64 | #define BRIDGE_SN9C120 3 | 64 | #define BRIDGE_SN9C120 3 |
65 | #define BRIDGE_SN9C325 4 | ||
66 | u8 sensor; /* Type of image sensor chip */ | 65 | u8 sensor; /* Type of image sensor chip */ |
67 | #define SENSOR_HV7131R 0 | 66 | #define SENSOR_HV7131R 0 |
68 | #define SENSOR_MI0360 1 | 67 | #define SENSOR_MI0360 1 |
@@ -354,9 +353,9 @@ static const u8 sn_ov7648[0x1c] = { | |||
354 | 353 | ||
355 | static const u8 sn_ov7660[0x1c] = { | 354 | static const u8 sn_ov7660[0x1c] = { |
356 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | 355 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
357 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, | 356 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, |
358 | /* reg8 reg9 rega regb regc regd rege regf */ | 357 | /* reg8 reg9 rega regb regc regd rege regf */ |
359 | 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, | 358 | 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
360 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | 359 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
361 | 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, | 360 | 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, |
362 | /* reg18 reg19 reg1a reg1b */ | 361 | /* reg18 reg19 reg1a reg1b */ |
@@ -757,6 +756,7 @@ static const u8 ov7660_sensor_init[][8] = { | |||
757 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ | 756 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ |
758 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ | 757 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ |
759 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ | 758 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ |
759 | {0xb1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
760 | /****** (some exchanges in the win trace) ******/ | 760 | /****** (some exchanges in the win trace) ******/ |
761 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ | 761 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ |
762 | /* bits[3..0]reserved */ | 762 | /* bits[3..0]reserved */ |
@@ -1065,9 +1065,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1065 | struct sd *sd = (struct sd *) gspca_dev; | 1065 | struct sd *sd = (struct sd *) gspca_dev; |
1066 | const u8 *reg9a; | 1066 | const u8 *reg9a; |
1067 | static const u8 reg9a_def[] = | 1067 | static const u8 reg9a_def[] = |
1068 | {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; | 1068 | {0x00, 0x40, 0x20, 0x00, 0x00, 0x00}; |
1069 | static const u8 reg9a_sn9c325[] = | 1069 | static const u8 reg9a_spec[] = |
1070 | {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; | 1070 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; |
1071 | static const u8 regd4[] = {0x60, 0x00, 0x00}; | 1071 | static const u8 regd4[] = {0x60, 0x00, 0x00}; |
1072 | 1072 | ||
1073 | reg_w1(gspca_dev, 0xf1, 0x00); | 1073 | reg_w1(gspca_dev, 0xf1, 0x00); |
@@ -1077,9 +1077,10 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1077 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); | 1077 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); |
1078 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); | 1078 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); |
1079 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ | 1079 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ |
1080 | switch (sd->bridge) { | 1080 | switch (sd->sensor) { |
1081 | case BRIDGE_SN9C325: | 1081 | case SENSOR_OV7660: |
1082 | reg9a = reg9a_sn9c325; | 1082 | case SENSOR_SP80708: |
1083 | reg9a = reg9a_spec; | ||
1083 | break; | 1084 | break; |
1084 | default: | 1085 | default: |
1085 | reg9a = reg9a_def; | 1086 | reg9a = reg9a_def; |
@@ -1104,7 +1105,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1104 | reg_w1(gspca_dev, 0x17, 0x64); | 1105 | reg_w1(gspca_dev, 0x17, 0x64); |
1105 | reg_w1(gspca_dev, 0x01, 0x42); | 1106 | reg_w1(gspca_dev, 0x01, 0x42); |
1106 | break; | 1107 | break; |
1107 | /*jfm: from win trace */ | ||
1108 | case SENSOR_OV7630: | 1108 | case SENSOR_OV7630: |
1109 | reg_w1(gspca_dev, 0x01, 0x61); | 1109 | reg_w1(gspca_dev, 0x01, 0x61); |
1110 | reg_w1(gspca_dev, 0x17, 0xe2); | 1110 | reg_w1(gspca_dev, 0x17, 0xe2); |
@@ -1114,18 +1114,15 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1114 | case SENSOR_OV7648: | 1114 | case SENSOR_OV7648: |
1115 | reg_w1(gspca_dev, 0x01, 0x63); | 1115 | reg_w1(gspca_dev, 0x01, 0x63); |
1116 | reg_w1(gspca_dev, 0x17, 0x20); | 1116 | reg_w1(gspca_dev, 0x17, 0x20); |
1117 | reg_w1(gspca_dev, 0x01, 0x62); | ||
1117 | reg_w1(gspca_dev, 0x01, 0x42); | 1118 | reg_w1(gspca_dev, 0x01, 0x42); |
1118 | break; | 1119 | break; |
1119 | /*jfm: from win trace */ | ||
1120 | case SENSOR_OV7660: | 1120 | case SENSOR_OV7660: |
1121 | if (sd->bridge == BRIDGE_SN9C120) { | 1121 | reg_w1(gspca_dev, 0x01, 0x61); |
1122 | reg_w1(gspca_dev, 0x01, 0x61); | 1122 | reg_w1(gspca_dev, 0x17, 0x20); |
1123 | reg_w1(gspca_dev, 0x17, 0x20); | 1123 | reg_w1(gspca_dev, 0x01, 0x60); |
1124 | reg_w1(gspca_dev, 0x01, 0x60); | 1124 | reg_w1(gspca_dev, 0x01, 0x40); |
1125 | reg_w1(gspca_dev, 0x01, 0x40); | 1125 | break; |
1126 | break; | ||
1127 | } | ||
1128 | /* fall thru */ | ||
1129 | case SENSOR_SP80708: | 1126 | case SENSOR_SP80708: |
1130 | reg_w1(gspca_dev, 0x01, 0x63); | 1127 | reg_w1(gspca_dev, 0x01, 0x63); |
1131 | reg_w1(gspca_dev, 0x17, 0x20); | 1128 | reg_w1(gspca_dev, 0x17, 0x20); |
@@ -1134,6 +1131,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1134 | mdelay(100); | 1131 | mdelay(100); |
1135 | reg_w1(gspca_dev, 0x02, 0x62); | 1132 | reg_w1(gspca_dev, 0x02, 0x62); |
1136 | break; | 1133 | break; |
1134 | /* case SENSOR_HV7131R: */ | ||
1135 | /* case SENSOR_MI0360: */ | ||
1136 | /* case SENSOR_MO4000: */ | ||
1137 | default: | 1137 | default: |
1138 | reg_w1(gspca_dev, 0x01, 0x43); | 1138 | reg_w1(gspca_dev, 0x01, 0x43); |
1139 | reg_w1(gspca_dev, 0x17, 0x61); | 1139 | reg_w1(gspca_dev, 0x17, 0x61); |
@@ -1280,6 +1280,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1280 | cam = &gspca_dev->cam; | 1280 | cam = &gspca_dev->cam; |
1281 | cam->cam_mode = vga_mode; | 1281 | cam->cam_mode = vga_mode; |
1282 | cam->nmodes = ARRAY_SIZE(vga_mode); | 1282 | cam->nmodes = ARRAY_SIZE(vga_mode); |
1283 | cam->npkt = 24; /* 24 packets per ISOC message */ | ||
1283 | 1284 | ||
1284 | sd->bridge = id->driver_info >> 16; | 1285 | sd->bridge = id->driver_info >> 16; |
1285 | sd->sensor = id->driver_info >> 8; | 1286 | sd->sensor = id->driver_info >> 8; |
@@ -1683,13 +1684,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1683 | case SENSOR_OV7648: | 1684 | case SENSOR_OV7648: |
1684 | reg17 = 0x20; | 1685 | reg17 = 0x20; |
1685 | break; | 1686 | break; |
1686 | /*jfm: from win trace */ | ||
1687 | case SENSOR_OV7660: | 1687 | case SENSOR_OV7660: |
1688 | if (sd->bridge == BRIDGE_SN9C120) { | 1688 | reg17 = 0xa0; |
1689 | reg17 = 0xa0; | 1689 | break; |
1690 | break; | ||
1691 | } | ||
1692 | /* fall thru */ | ||
1693 | default: | 1690 | default: |
1694 | reg17 = 0x60; | 1691 | reg17 = 0x60; |
1695 | break; | 1692 | break; |
@@ -1714,16 +1711,17 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1714 | reg_w1(gspca_dev, 0x9a, 0x0a); | 1711 | reg_w1(gspca_dev, 0x9a, 0x0a); |
1715 | reg_w1(gspca_dev, 0x99, 0x60); | 1712 | reg_w1(gspca_dev, 0x99, 0x60); |
1716 | break; | 1713 | break; |
1714 | case SENSOR_OV7660: | ||
1715 | reg_w1(gspca_dev, 0x9a, 0x05); | ||
1716 | if (sd->bridge == BRIDGE_SN9C105) | ||
1717 | reg_w1(gspca_dev, 0x99, 0xff); | ||
1718 | else | ||
1719 | reg_w1(gspca_dev, 0x99, 0x5b); | ||
1720 | break; | ||
1717 | case SENSOR_SP80708: | 1721 | case SENSOR_SP80708: |
1718 | reg_w1(gspca_dev, 0x9a, 0x05); | 1722 | reg_w1(gspca_dev, 0x9a, 0x05); |
1719 | reg_w1(gspca_dev, 0x99, 0x59); | 1723 | reg_w1(gspca_dev, 0x99, 0x59); |
1720 | break; | 1724 | break; |
1721 | case SENSOR_OV7660: | ||
1722 | if (sd->bridge == BRIDGE_SN9C120) { | ||
1723 | reg_w1(gspca_dev, 0x9a, 0x05); | ||
1724 | break; | ||
1725 | } | ||
1726 | /* fall thru */ | ||
1727 | default: | 1725 | default: |
1728 | reg_w1(gspca_dev, 0x9a, 0x08); | 1726 | reg_w1(gspca_dev, 0x9a, 0x08); |
1729 | reg_w1(gspca_dev, 0x99, 0x59); | 1727 | reg_w1(gspca_dev, 0x99, 0x59); |
@@ -2193,6 +2191,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
2193 | {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, | 2191 | {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, |
2194 | {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, | 2192 | {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, |
2195 | {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, | 2193 | {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, |
2194 | {USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)}, | ||
2196 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, | 2195 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, |
2197 | /* bw600.inf: | 2196 | /* bw600.inf: |
2198 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ | 2197 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ |
@@ -2211,7 +2210,12 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
2211 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | 2210 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
2212 | {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, | 2211 | {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, |
2213 | #endif | 2212 | #endif |
2213 | {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/ | ||
2214 | /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ | 2214 | /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ |
2215 | {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/ | ||
2216 | {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/ | ||
2217 | {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/ | ||
2218 | {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/ | ||
2215 | /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ | 2219 | /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ |
2216 | /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ | 2220 | /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ |
2217 | {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ | 2221 | {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ |
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 6f38fa6d86b6..8806b2ff82be 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c | |||
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL"); | |||
32 | struct sd { | 32 | struct sd { |
33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
34 | 34 | ||
35 | __u8 packet[ISO_MAX_SIZE + 128]; | ||
36 | /* !! no more than 128 ff in an ISO packet */ | ||
37 | |||
38 | unsigned char brightness; | 35 | unsigned char brightness; |
39 | unsigned char contrast; | 36 | unsigned char contrast; |
40 | unsigned char colors; | 37 | unsigned char colors; |
@@ -906,7 +903,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
906 | { | 903 | { |
907 | struct sd *sd = (struct sd *) gspca_dev; | 904 | struct sd *sd = (struct sd *) gspca_dev; |
908 | int i; | 905 | int i; |
909 | __u8 *s, *d; | ||
910 | static __u8 ffd9[] = {0xff, 0xd9}; | 906 | static __u8 ffd9[] = {0xff, 0xd9}; |
911 | 907 | ||
912 | /* frames are jpeg 4.1.1 without 0xff escape */ | 908 | /* frames are jpeg 4.1.1 without 0xff escape */ |
@@ -930,22 +926,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
930 | } | 926 | } |
931 | 927 | ||
932 | /* add 0x00 after 0xff */ | 928 | /* add 0x00 after 0xff */ |
933 | for (i = len; --i >= 0; ) | 929 | i = 0; |
934 | if (data[i] == 0xff) | 930 | do { |
935 | break; | 931 | if (data[i] == 0xff) { |
936 | if (i < 0) { /* no 0xff */ | 932 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
937 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | 933 | data, i + 1); |
938 | return; | 934 | len -= i; |
939 | } | 935 | data += i; |
940 | s = data; | 936 | *data = 0x00; |
941 | d = sd->packet; | 937 | i = 0; |
942 | for (i = 0; i < len; i++) { | 938 | } |
943 | *d++ = *s++; | 939 | i++; |
944 | if (s[-1] == 0xff) | 940 | } while (i < len); |
945 | *d++ = 0x00; | 941 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); |
946 | } | ||
947 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
948 | sd->packet, d - sd->packet); | ||
949 | } | 942 | } |
950 | 943 | ||
951 | static void setbrightness(struct gspca_dev *gspca_dev) | 944 | static void setbrightness(struct gspca_dev *gspca_dev) |
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 2acec58b1b97..ea8c9fe2e961 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c | |||
@@ -637,19 +637,19 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
637 | cam->nmodes = ARRAY_SIZE(vga_mode) - 1; | 637 | cam->nmodes = ARRAY_SIZE(vga_mode) - 1; |
638 | sd->brightness = BRIGHTNESS_DEF; | 638 | sd->brightness = BRIGHTNESS_DEF; |
639 | 639 | ||
640 | if (sd->subtype == Nxultra) { | ||
641 | if (write_vector(gspca_dev, spca505b_init_data)) | ||
642 | return -EIO; | ||
643 | } else { | ||
644 | if (write_vector(gspca_dev, spca505_init_data)) | ||
645 | return -EIO; | ||
646 | } | ||
647 | return 0; | 640 | return 0; |
648 | } | 641 | } |
649 | 642 | ||
650 | /* this function is called at probe and resume time */ | 643 | /* this function is called at probe and resume time */ |
651 | static int sd_init(struct gspca_dev *gspca_dev) | 644 | static int sd_init(struct gspca_dev *gspca_dev) |
652 | { | 645 | { |
646 | struct sd *sd = (struct sd *) gspca_dev; | ||
647 | |||
648 | if (write_vector(gspca_dev, | ||
649 | sd->subtype == Nxultra | ||
650 | ? spca505b_init_data | ||
651 | : spca505_init_data)) | ||
652 | return -EIO; | ||
653 | return 0; | 653 | return 0; |
654 | } | 654 | } |
655 | 655 | ||
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index adacf8437661..2ed2669bac3e 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SPCA508 chip based cameras subdriver | 2 | * SPCA508 chip based cameras subdriver |
3 | * | 3 | * |
4 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | 4 | * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -30,9 +30,9 @@ MODULE_LICENSE("GPL"); | |||
30 | struct sd { | 30 | struct sd { |
31 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 31 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
32 | 32 | ||
33 | unsigned char brightness; | 33 | u8 brightness; |
34 | 34 | ||
35 | char subtype; | 35 | u8 subtype; |
36 | #define CreativeVista 0 | 36 | #define CreativeVista 0 |
37 | #define HamaUSBSightcam 1 | 37 | #define HamaUSBSightcam 1 |
38 | #define HamaUSBSightcam2 2 | 38 | #define HamaUSBSightcam2 2 |
@@ -86,58 +86,34 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
86 | }; | 86 | }; |
87 | 87 | ||
88 | /* Frame packet header offsets for the spca508 */ | 88 | /* Frame packet header offsets for the spca508 */ |
89 | #define SPCA508_OFFSET_TYPE 1 | ||
90 | #define SPCA508_OFFSET_COMPRESS 2 | ||
91 | #define SPCA508_OFFSET_FRAMSEQ 8 | ||
92 | #define SPCA508_OFFSET_WIN1LUM 11 | ||
93 | #define SPCA508_OFFSET_DATA 37 | 89 | #define SPCA508_OFFSET_DATA 37 |
94 | 90 | ||
95 | #define SPCA508_SNAPBIT 0x20 | ||
96 | #define SPCA508_SNAPCTRL 0x40 | ||
97 | /*************** I2c ****************/ | ||
98 | #define SPCA508_INDEX_I2C_BASE 0x8800 | ||
99 | |||
100 | /* | 91 | /* |
101 | * Initialization data: this is the first set-up data written to the | 92 | * Initialization data: this is the first set-up data written to the |
102 | * device (before the open data). | 93 | * device (before the open data). |
103 | */ | 94 | */ |
104 | static const u16 spca508_init_data[][2] = | 95 | static const u16 spca508_init_data[][2] = |
105 | { | 96 | { |
106 | /* line URB value, index */ | 97 | {0x0000, 0x870b}, |
107 | /* 44274 1804 */ {0x0000, 0x870b}, | 98 | |
108 | 99 | {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ | |
109 | /* 44299 1805 */ {0x0020, 0x8112}, | 100 | {0x0003, 0x8111}, /* Reset compression & memory */ |
110 | /* Video drop enable, ISO streaming disable */ | 101 | {0x0000, 0x8110}, /* Disable all outputs */ |
111 | /* 44324 1806 */ {0x0003, 0x8111}, | 102 | /* READ {0x0000, 0x8114} -> 0000: 00 */ |
112 | /* Reset compression & memory */ | 103 | {0x0000, 0x8114}, /* SW GPIO data */ |
113 | /* 44349 1807 */ {0x0000, 0x8110}, | 104 | {0x0008, 0x8110}, /* Enable charge pump output */ |
114 | /* Disable all outputs */ | 105 | {0x0002, 0x8116}, /* 200 kHz pump clock */ |
115 | /* 44372 1808 */ /* READ {0x0000, 0x8114} -> 0000: 00 */ | 106 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */ |
116 | /* 44398 1809 */ {0x0000, 0x8114}, | 107 | {0x0003, 0x8111}, /* Reset compression & memory */ |
117 | /* SW GPIO data */ | 108 | {0x0000, 0x8111}, /* Normal mode (not reset) */ |
118 | /* 44423 1810 */ {0x0008, 0x8110}, | 109 | {0x0098, 0x8110}, |
119 | /* Enable charge pump output */ | 110 | /* Enable charge pump output, sync.serial,external 2x clock */ |
120 | /* 44527 1811 */ {0x0002, 0x8116}, | 111 | {0x000d, 0x8114}, /* SW GPIO data */ |
121 | /* 200 kHz pump clock */ | 112 | {0x0002, 0x8116}, /* 200 kHz pump clock */ |
122 | /* 44555 1812 */ | 113 | {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ |
123 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */ | ||
124 | /* 44590 1813 */ {0x0003, 0x8111}, | ||
125 | /* Reset compression & memory */ | ||
126 | /* 44615 1814 */ {0x0000, 0x8111}, | ||
127 | /* Normal mode (not reset) */ | ||
128 | /* 44640 1815 */ {0x0098, 0x8110}, | ||
129 | /* Enable charge pump output, sync.serial,external 2x clock */ | ||
130 | /* 44665 1816 */ {0x000d, 0x8114}, | ||
131 | /* SW GPIO data */ | ||
132 | /* 44690 1817 */ {0x0002, 0x8116}, | ||
133 | /* 200 kHz pump clock */ | ||
134 | /* 44715 1818 */ {0x0020, 0x8112}, | ||
135 | /* Video drop enable, ISO streaming disable */ | ||
136 | /* --------------------------------------- */ | 114 | /* --------------------------------------- */ |
137 | /* 44740 1819 */ {0x000f, 0x8402}, | 115 | {0x000f, 0x8402}, /* memory bank */ |
138 | /* memory bank */ | 116 | {0x0000, 0x8403}, /* ... address */ |
139 | /* 44765 1820 */ {0x0000, 0x8403}, | ||
140 | /* ... address */ | ||
141 | /* --------------------------------------- */ | 117 | /* --------------------------------------- */ |
142 | /* 0x88__ is Synchronous Serial Interface. */ | 118 | /* 0x88__ is Synchronous Serial Interface. */ |
143 | /* TBD: This table could be expressed more compactly */ | 119 | /* TBD: This table could be expressed more compactly */ |
@@ -145,446 +121,384 @@ static const u16 spca508_init_data[][2] = | |||
145 | /* TBD: Should see if the values in spca50x_i2c_data */ | 121 | /* TBD: Should see if the values in spca50x_i2c_data */ |
146 | /* would work with the VQ110 instead of the values */ | 122 | /* would work with the VQ110 instead of the values */ |
147 | /* below. */ | 123 | /* below. */ |
148 | /* 44790 1821 */ {0x00c0, 0x8804}, | 124 | {0x00c0, 0x8804}, /* SSI slave addr */ |
149 | /* SSI slave addr */ | 125 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
150 | /* 44815 1822 */ {0x0008, 0x8802}, | 126 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
151 | /* 375 Khz SSI clock */ | 127 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
152 | /* 44838 1823 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 128 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
153 | /* 44862 1824 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 129 | {0x0012, 0x8801}, /* SSI reg addr */ |
154 | /* 44888 1825 */ {0x0008, 0x8802}, | 130 | {0x0080, 0x8800}, /* SSI data to write */ |
155 | /* 375 Khz SSI clock */ | 131 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
156 | /* 44913 1826 */ {0x0012, 0x8801}, | 132 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
157 | /* SSI reg addr */ | 133 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
158 | /* 44938 1827 */ {0x0080, 0x8800}, | 134 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
159 | /* SSI data to write */ | 135 | {0x0012, 0x8801}, /* SSI reg addr */ |
160 | /* 44961 1828 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 136 | {0x0000, 0x8800}, /* SSI data to write */ |
161 | /* 44985 1829 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 137 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
162 | /* 45009 1830 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 138 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
163 | /* 45035 1831 */ {0x0008, 0x8802}, | 139 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
164 | /* 375 Khz SSI clock */ | 140 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
165 | /* 45060 1832 */ {0x0012, 0x8801}, | 141 | {0x0011, 0x8801}, /* SSI reg addr */ |
166 | /* SSI reg addr */ | 142 | {0x0040, 0x8800}, /* SSI data to write */ |
167 | /* 45085 1833 */ {0x0000, 0x8800}, | 143 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
168 | /* SSI data to write */ | 144 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
169 | /* 45108 1834 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 145 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
170 | /* 45132 1835 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 146 | {0x0008, 0x8802}, |
171 | /* 45156 1836 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 147 | {0x0013, 0x8801}, |
172 | /* 45182 1837 */ {0x0008, 0x8802}, | 148 | {0x0000, 0x8800}, |
173 | /* 375 Khz SSI clock */ | 149 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
174 | /* 45207 1838 */ {0x0011, 0x8801}, | 150 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
175 | /* SSI reg addr */ | 151 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
176 | /* 45232 1839 */ {0x0040, 0x8800}, | 152 | {0x0008, 0x8802}, |
177 | /* SSI data to write */ | 153 | {0x0014, 0x8801}, |
178 | /* 45255 1840 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 154 | {0x0000, 0x8800}, |
179 | /* 45279 1841 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 155 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
180 | /* 45303 1842 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 156 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
181 | /* 45329 1843 */ {0x0008, 0x8802}, | 157 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
182 | /* 45354 1844 */ {0x0013, 0x8801}, | 158 | {0x0008, 0x8802}, |
183 | /* 45379 1845 */ {0x0000, 0x8800}, | 159 | {0x0015, 0x8801}, |
184 | /* 45402 1846 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 160 | {0x0001, 0x8800}, |
185 | /* 45426 1847 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 161 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
186 | /* 45450 1848 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 162 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
187 | /* 45476 1849 */ {0x0008, 0x8802}, | 163 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
188 | /* 45501 1850 */ {0x0014, 0x8801}, | 164 | {0x0008, 0x8802}, |
189 | /* 45526 1851 */ {0x0000, 0x8800}, | 165 | {0x0016, 0x8801}, |
190 | /* 45549 1852 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 166 | {0x0003, 0x8800}, |
191 | /* 45573 1853 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 167 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
192 | /* 45597 1854 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 168 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
193 | /* 45623 1855 */ {0x0008, 0x8802}, | 169 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
194 | /* 45648 1856 */ {0x0015, 0x8801}, | 170 | {0x0008, 0x8802}, |
195 | /* 45673 1857 */ {0x0001, 0x8800}, | 171 | {0x0017, 0x8801}, |
196 | /* 45696 1858 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 172 | {0x0036, 0x8800}, |
197 | /* 45720 1859 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 173 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
198 | /* 45744 1860 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 174 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
199 | /* 45770 1861 */ {0x0008, 0x8802}, | 175 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
200 | /* 45795 1862 */ {0x0016, 0x8801}, | 176 | {0x0008, 0x8802}, |
201 | /* 45820 1863 */ {0x0003, 0x8800}, | 177 | {0x0018, 0x8801}, |
202 | /* 45843 1864 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 178 | {0x00ec, 0x8800}, |
203 | /* 45867 1865 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 179 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
204 | /* 45891 1866 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 180 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
205 | /* 45917 1867 */ {0x0008, 0x8802}, | 181 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
206 | /* 45942 1868 */ {0x0017, 0x8801}, | 182 | {0x0008, 0x8802}, |
207 | /* 45967 1869 */ {0x0036, 0x8800}, | 183 | {0x001a, 0x8801}, |
208 | /* 45990 1870 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 184 | {0x0094, 0x8800}, |
209 | /* 46014 1871 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 185 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
210 | /* 46038 1872 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 186 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
211 | /* 46064 1873 */ {0x0008, 0x8802}, | 187 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
212 | /* 46089 1874 */ {0x0018, 0x8801}, | 188 | {0x0008, 0x8802}, |
213 | /* 46114 1875 */ {0x00ec, 0x8800}, | 189 | {0x001b, 0x8801}, |
214 | /* 46137 1876 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 190 | {0x0000, 0x8800}, |
215 | /* 46161 1877 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 191 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
216 | /* 46185 1878 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 192 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
217 | /* 46211 1879 */ {0x0008, 0x8802}, | 193 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
218 | /* 46236 1880 */ {0x001a, 0x8801}, | 194 | {0x0008, 0x8802}, |
219 | /* 46261 1881 */ {0x0094, 0x8800}, | 195 | {0x0027, 0x8801}, |
220 | /* 46284 1882 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 196 | {0x00a2, 0x8800}, |
221 | /* 46308 1883 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 197 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
222 | /* 46332 1884 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 198 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
223 | /* 46358 1885 */ {0x0008, 0x8802}, | 199 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
224 | /* 46383 1886 */ {0x001b, 0x8801}, | 200 | {0x0008, 0x8802}, |
225 | /* 46408 1887 */ {0x0000, 0x8800}, | 201 | {0x0028, 0x8801}, |
226 | /* 46431 1888 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 202 | {0x0040, 0x8800}, |
227 | /* 46455 1889 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 203 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
228 | /* 46479 1890 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 204 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
229 | /* 46505 1891 */ {0x0008, 0x8802}, | 205 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
230 | /* 46530 1892 */ {0x0027, 0x8801}, | 206 | {0x0008, 0x8802}, |
231 | /* 46555 1893 */ {0x00a2, 0x8800}, | 207 | {0x002a, 0x8801}, |
232 | /* 46578 1894 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 208 | {0x0084, 0x8800}, |
233 | /* 46602 1895 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 209 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
234 | /* 46626 1896 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 210 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
235 | /* 46652 1897 */ {0x0008, 0x8802}, | 211 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
236 | /* 46677 1898 */ {0x0028, 0x8801}, | 212 | {0x0008, 0x8802}, |
237 | /* 46702 1899 */ {0x0040, 0x8800}, | 213 | {0x002b, 0x8801}, |
238 | /* 46725 1900 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 214 | {0x00a8, 0x8800}, |
239 | /* 46749 1901 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 215 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
240 | /* 46773 1902 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 216 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
241 | /* 46799 1903 */ {0x0008, 0x8802}, | 217 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
242 | /* 46824 1904 */ {0x002a, 0x8801}, | 218 | {0x0008, 0x8802}, |
243 | /* 46849 1905 */ {0x0084, 0x8800}, | 219 | {0x002c, 0x8801}, |
244 | /* 46872 1906 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 220 | {0x00fe, 0x8800}, |
245 | /* 46896 1907 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 221 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
246 | /* 46920 1908 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 222 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
247 | /* 46946 1909 */ {0x0008, 0x8802}, | 223 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
248 | /* 46971 1910 */ {0x002b, 0x8801}, | 224 | {0x0008, 0x8802}, |
249 | /* 46996 1911 */ {0x00a8, 0x8800}, | 225 | {0x002d, 0x8801}, |
250 | /* 47019 1912 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 226 | {0x0003, 0x8800}, |
251 | /* 47043 1913 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 227 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
252 | /* 47067 1914 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 228 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
253 | /* 47093 1915 */ {0x0008, 0x8802}, | 229 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
254 | /* 47118 1916 */ {0x002c, 0x8801}, | 230 | {0x0008, 0x8802}, |
255 | /* 47143 1917 */ {0x00fe, 0x8800}, | 231 | {0x0038, 0x8801}, |
256 | /* 47166 1918 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 232 | {0x0083, 0x8800}, |
257 | /* 47190 1919 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 233 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
258 | /* 47214 1920 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 234 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
259 | /* 47240 1921 */ {0x0008, 0x8802}, | 235 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
260 | /* 47265 1922 */ {0x002d, 0x8801}, | 236 | {0x0008, 0x8802}, |
261 | /* 47290 1923 */ {0x0003, 0x8800}, | 237 | {0x0033, 0x8801}, |
262 | /* 47313 1924 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 238 | {0x0081, 0x8800}, |
263 | /* 47337 1925 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 239 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
264 | /* 47361 1926 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 240 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
265 | /* 47387 1927 */ {0x0008, 0x8802}, | 241 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
266 | /* 47412 1928 */ {0x0038, 0x8801}, | 242 | {0x0008, 0x8802}, |
267 | /* 47437 1929 */ {0x0083, 0x8800}, | 243 | {0x0034, 0x8801}, |
268 | /* 47460 1930 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 244 | {0x004a, 0x8800}, |
269 | /* 47484 1931 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 245 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
270 | /* 47508 1932 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 246 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
271 | /* 47534 1933 */ {0x0008, 0x8802}, | 247 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
272 | /* 47559 1934 */ {0x0033, 0x8801}, | 248 | {0x0008, 0x8802}, |
273 | /* 47584 1935 */ {0x0081, 0x8800}, | 249 | {0x0039, 0x8801}, |
274 | /* 47607 1936 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 250 | {0x0000, 0x8800}, |
275 | /* 47631 1937 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 251 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
276 | /* 47655 1938 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 252 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
277 | /* 47681 1939 */ {0x0008, 0x8802}, | 253 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
278 | /* 47706 1940 */ {0x0034, 0x8801}, | 254 | {0x0008, 0x8802}, |
279 | /* 47731 1941 */ {0x004a, 0x8800}, | 255 | {0x0010, 0x8801}, |
280 | /* 47754 1942 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 256 | {0x00a8, 0x8800}, |
281 | /* 47778 1943 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 257 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
282 | /* 47802 1944 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 258 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
283 | /* 47828 1945 */ {0x0008, 0x8802}, | 259 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
284 | /* 47853 1946 */ {0x0039, 0x8801}, | 260 | {0x0008, 0x8802}, |
285 | /* 47878 1947 */ {0x0000, 0x8800}, | 261 | {0x0006, 0x8801}, |
286 | /* 47901 1948 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 262 | {0x0058, 0x8800}, |
287 | /* 47925 1949 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 263 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
288 | /* 47949 1950 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 264 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
289 | /* 47975 1951 */ {0x0008, 0x8802}, | 265 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
290 | /* 48000 1952 */ {0x0010, 0x8801}, | 266 | {0x0008, 0x8802}, |
291 | /* 48025 1953 */ {0x00a8, 0x8800}, | 267 | {0x0000, 0x8801}, |
292 | /* 48048 1954 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 268 | {0x0004, 0x8800}, |
293 | /* 48072 1955 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 269 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
294 | /* 48096 1956 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 270 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
295 | /* 48122 1957 */ {0x0008, 0x8802}, | 271 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
296 | /* 48147 1958 */ {0x0006, 0x8801}, | 272 | {0x0008, 0x8802}, |
297 | /* 48172 1959 */ {0x0058, 0x8800}, | 273 | {0x0040, 0x8801}, |
298 | /* 48195 1960 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 274 | {0x0080, 0x8800}, |
299 | /* 48219 1961 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 275 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
300 | /* 48243 1962 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 276 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
301 | /* 48269 1963 */ {0x0008, 0x8802}, | 277 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
302 | /* 48294 1964 */ {0x0000, 0x8801}, | 278 | {0x0008, 0x8802}, |
303 | /* 48319 1965 */ {0x0004, 0x8800}, | 279 | {0x0041, 0x8801}, |
304 | /* 48342 1966 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 280 | {0x000c, 0x8800}, |
305 | /* 48366 1967 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 281 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
306 | /* 48390 1968 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 282 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
307 | /* 48416 1969 */ {0x0008, 0x8802}, | 283 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
308 | /* 48441 1970 */ {0x0040, 0x8801}, | 284 | {0x0008, 0x8802}, |
309 | /* 48466 1971 */ {0x0080, 0x8800}, | 285 | {0x0042, 0x8801}, |
310 | /* 48489 1972 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 286 | {0x000c, 0x8800}, |
311 | /* 48513 1973 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 287 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
312 | /* 48537 1974 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 288 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
313 | /* 48563 1975 */ {0x0008, 0x8802}, | 289 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
314 | /* 48588 1976 */ {0x0041, 0x8801}, | 290 | {0x0008, 0x8802}, |
315 | /* 48613 1977 */ {0x000c, 0x8800}, | 291 | {0x0043, 0x8801}, |
316 | /* 48636 1978 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 292 | {0x0028, 0x8800}, |
317 | /* 48660 1979 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 293 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
318 | /* 48684 1980 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 294 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
319 | /* 48710 1981 */ {0x0008, 0x8802}, | 295 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
320 | /* 48735 1982 */ {0x0042, 0x8801}, | 296 | {0x0008, 0x8802}, |
321 | /* 48760 1983 */ {0x000c, 0x8800}, | 297 | {0x0044, 0x8801}, |
322 | /* 48783 1984 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 298 | {0x0080, 0x8800}, |
323 | /* 48807 1985 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 299 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
324 | /* 48831 1986 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 300 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
325 | /* 48857 1987 */ {0x0008, 0x8802}, | 301 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
326 | /* 48882 1988 */ {0x0043, 0x8801}, | 302 | {0x0008, 0x8802}, |
327 | /* 48907 1989 */ {0x0028, 0x8800}, | 303 | {0x0045, 0x8801}, |
328 | /* 48930 1990 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 304 | {0x0020, 0x8800}, |
329 | /* 48954 1991 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 305 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
330 | /* 48978 1992 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 306 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
331 | /* 49004 1993 */ {0x0008, 0x8802}, | 307 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
332 | /* 49029 1994 */ {0x0044, 0x8801}, | 308 | {0x0008, 0x8802}, |
333 | /* 49054 1995 */ {0x0080, 0x8800}, | 309 | {0x0046, 0x8801}, |
334 | /* 49077 1996 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 310 | {0x0020, 0x8800}, |
335 | /* 49101 1997 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 311 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
336 | /* 49125 1998 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 312 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
337 | /* 49151 1999 */ {0x0008, 0x8802}, | 313 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
338 | /* 49176 2000 */ {0x0045, 0x8801}, | 314 | {0x0008, 0x8802}, |
339 | /* 49201 2001 */ {0x0020, 0x8800}, | 315 | {0x0047, 0x8801}, |
340 | /* 49224 2002 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 316 | {0x0080, 0x8800}, |
341 | /* 49248 2003 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 317 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
342 | /* 49272 2004 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 318 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
343 | /* 49298 2005 */ {0x0008, 0x8802}, | 319 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
344 | /* 49323 2006 */ {0x0046, 0x8801}, | 320 | {0x0008, 0x8802}, |
345 | /* 49348 2007 */ {0x0020, 0x8800}, | 321 | {0x0048, 0x8801}, |
346 | /* 49371 2008 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 322 | {0x004c, 0x8800}, |
347 | /* 49395 2009 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 323 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
348 | /* 49419 2010 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 324 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
349 | /* 49445 2011 */ {0x0008, 0x8802}, | 325 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
350 | /* 49470 2012 */ {0x0047, 0x8801}, | 326 | {0x0008, 0x8802}, |
351 | /* 49495 2013 */ {0x0080, 0x8800}, | 327 | {0x0049, 0x8801}, |
352 | /* 49518 2014 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 328 | {0x0084, 0x8800}, |
353 | /* 49542 2015 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 329 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
354 | /* 49566 2016 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 330 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
355 | /* 49592 2017 */ {0x0008, 0x8802}, | 331 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
356 | /* 49617 2018 */ {0x0048, 0x8801}, | 332 | {0x0008, 0x8802}, |
357 | /* 49642 2019 */ {0x004c, 0x8800}, | 333 | {0x004a, 0x8801}, |
358 | /* 49665 2020 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 334 | {0x0084, 0x8800}, |
359 | /* 49689 2021 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 335 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
360 | /* 49713 2022 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 336 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
361 | /* 49739 2023 */ {0x0008, 0x8802}, | 337 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
362 | /* 49764 2024 */ {0x0049, 0x8801}, | 338 | {0x0008, 0x8802}, |
363 | /* 49789 2025 */ {0x0084, 0x8800}, | 339 | {0x004b, 0x8801}, |
364 | /* 49812 2026 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 340 | {0x0084, 0x8800}, |
365 | /* 49836 2027 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 341 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
366 | /* 49860 2028 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
367 | /* 49886 2029 */ {0x0008, 0x8802}, | ||
368 | /* 49911 2030 */ {0x004a, 0x8801}, | ||
369 | /* 49936 2031 */ {0x0084, 0x8800}, | ||
370 | /* 49959 2032 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
371 | /* 49983 2033 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
372 | /* 50007 2034 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
373 | /* 50033 2035 */ {0x0008, 0x8802}, | ||
374 | /* 50058 2036 */ {0x004b, 0x8801}, | ||
375 | /* 50083 2037 */ {0x0084, 0x8800}, | ||
376 | /* 50106 2038 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
377 | /* --------------------------------------- */ | 342 | /* --------------------------------------- */ |
378 | /* 50132 2039 */ {0x0012, 0x8700}, | 343 | {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ |
379 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | 344 | {0x0000, 0x8701}, /* CKx1 clock delay adj */ |
380 | /* 50157 2040 */ {0x0000, 0x8701}, | 345 | {0x0000, 0x8701}, /* CKx1 clock delay adj */ |
381 | /* CKx1 clock delay adj */ | 346 | {0x0001, 0x870c}, /* CKOx2 output */ |
382 | /* 50182 2041 */ {0x0000, 0x8701}, | ||
383 | /* CKx1 clock delay adj */ | ||
384 | /* 50207 2042 */ {0x0001, 0x870c}, | ||
385 | /* CKOx2 output */ | ||
386 | /* --------------------------------------- */ | 347 | /* --------------------------------------- */ |
387 | /* 50232 2043 */ {0x0080, 0x8600}, | 348 | {0x0080, 0x8600}, /* Line memory read counter (L) */ |
388 | /* Line memory read counter (L) */ | 349 | {0x0001, 0x8606}, /* reserved */ |
389 | /* 50257 2044 */ {0x0001, 0x8606}, | 350 | {0x0064, 0x8607}, /* Line memory read counter (H) 0x6480=25,728 */ |
390 | /* reserved */ | 351 | {0x002a, 0x8601}, /* CDSP sharp interpolation mode, |
391 | /* 50282 2045 */ {0x0064, 0x8607}, | ||
392 | /* Line memory read counter (H) 0x6480=25,728 */ | ||
393 | /* 50307 2046 */ {0x002a, 0x8601}, | ||
394 | /* CDSP sharp interpolation mode, | ||
395 | * line sel for color sep, edge enhance enab */ | 352 | * line sel for color sep, edge enhance enab */ |
396 | /* 50332 2047 */ {0x0000, 0x8602}, | 353 | {0x0000, 0x8602}, /* optical black level for user settng = 0 */ |
397 | /* optical black level for user settng = 0 */ | 354 | {0x0080, 0x8600}, /* Line memory read counter (L) */ |
398 | /* 50357 2048 */ {0x0080, 0x8600}, | 355 | {0x000a, 0x8603}, /* optical black level calc mode: |
399 | /* Line memory read counter (L) */ | 356 | * auto; optical black offset = 10 */ |
400 | /* 50382 2049 */ {0x000a, 0x8603}, | 357 | {0x00df, 0x865b}, /* Horiz offset for valid pixels (L)=0xdf */ |
401 | /* optical black level calc mode: auto; optical black offset = 10 */ | 358 | {0x0012, 0x865c}, /* Vert offset for valid lines (L)=0x12 */ |
402 | /* 50407 2050 */ {0x00df, 0x865b}, | ||
403 | /* Horiz offset for valid pixels (L)=0xdf */ | ||
404 | /* 50432 2051 */ {0x0012, 0x865c}, | ||
405 | /* Vert offset for valid lines (L)=0x12 */ | ||
406 | 359 | ||
407 | /* The following two lines seem to be the "wrong" resolution. */ | 360 | /* The following two lines seem to be the "wrong" resolution. */ |
408 | /* But perhaps these indicate the actual size of the sensor */ | 361 | /* But perhaps these indicate the actual size of the sensor */ |
409 | /* rather than the size of the current video mode. */ | 362 | /* rather than the size of the current video mode. */ |
410 | /* 50457 2052 */ {0x0058, 0x865d}, | 363 | {0x0058, 0x865d}, /* Horiz valid pixels (*4) (L) = 352 */ |
411 | /* Horiz valid pixels (*4) (L) = 352 */ | 364 | {0x0048, 0x865e}, /* Vert valid lines (*4) (L) = 288 */ |
412 | /* 50482 2053 */ {0x0048, 0x865e}, | 365 | |
413 | /* Vert valid lines (*4) (L) = 288 */ | 366 | {0x0015, 0x8608}, /* A11 Coef ... */ |
414 | 367 | {0x0030, 0x8609}, | |
415 | /* 50507 2054 */ {0x0015, 0x8608}, | 368 | {0x00fb, 0x860a}, |
416 | /* A11 Coef ... */ | 369 | {0x003e, 0x860b}, |
417 | /* 50532 2055 */ {0x0030, 0x8609}, | 370 | {0x00ce, 0x860c}, |
418 | /* 50557 2056 */ {0x00fb, 0x860a}, | 371 | {0x00f4, 0x860d}, |
419 | /* 50582 2057 */ {0x003e, 0x860b}, | 372 | {0x00eb, 0x860e}, |
420 | /* 50607 2058 */ {0x00ce, 0x860c}, | 373 | {0x00dc, 0x860f}, |
421 | /* 50632 2059 */ {0x00f4, 0x860d}, | 374 | {0x0039, 0x8610}, |
422 | /* 50657 2060 */ {0x00eb, 0x860e}, | 375 | {0x0001, 0x8611}, /* R offset for white balance ... */ |
423 | /* 50682 2061 */ {0x00dc, 0x860f}, | 376 | {0x0000, 0x8612}, |
424 | /* 50707 2062 */ {0x0039, 0x8610}, | 377 | {0x0001, 0x8613}, |
425 | /* 50732 2063 */ {0x0001, 0x8611}, | 378 | {0x0000, 0x8614}, |
426 | /* R offset for white balance ... */ | 379 | {0x005b, 0x8651}, /* R gain for white balance ... */ |
427 | /* 50757 2064 */ {0x0000, 0x8612}, | 380 | {0x0040, 0x8652}, |
428 | /* 50782 2065 */ {0x0001, 0x8613}, | 381 | {0x0060, 0x8653}, |
429 | /* 50807 2066 */ {0x0000, 0x8614}, | 382 | {0x0040, 0x8654}, |
430 | /* 50832 2067 */ {0x005b, 0x8651}, | 383 | {0x0000, 0x8655}, |
431 | /* R gain for white balance ... */ | 384 | {0x0001, 0x863f}, /* Fixed gamma correction enable, USB control, |
432 | /* 50857 2068 */ {0x0040, 0x8652}, | 385 | * lum filter disable, lum noise clip disable */ |
433 | /* 50882 2069 */ {0x0060, 0x8653}, | 386 | {0x00a1, 0x8656}, /* Window1 size 256x256, Windows2 size 64x64, |
434 | /* 50907 2070 */ {0x0040, 0x8654}, | 387 | * gamma look-up disable, |
435 | /* 50932 2071 */ {0x0000, 0x8655}, | 388 | * new edge enhancement enable */ |
436 | /* 50957 2072 */ {0x0001, 0x863f}, | 389 | {0x0018, 0x8657}, /* Edge gain high thresh */ |
437 | /* Fixed gamma correction enable, USB control, | 390 | {0x0020, 0x8658}, /* Edge gain low thresh */ |
438 | * lum filter disable, lum noise clip disable */ | 391 | {0x000a, 0x8659}, /* Edge bandwidth high threshold */ |
439 | /* 50982 2073 */ {0x00a1, 0x8656}, | 392 | {0x0005, 0x865a}, /* Edge bandwidth low threshold */ |
440 | /* Window1 size 256x256, Windows2 size 64x64, | ||
441 | * gamma look-up disable, new edge enhancement enable */ | ||
442 | /* 51007 2074 */ {0x0018, 0x8657}, | ||
443 | /* Edge gain high thresh */ | ||
444 | /* 51032 2075 */ {0x0020, 0x8658}, | ||
445 | /* Edge gain low thresh */ | ||
446 | /* 51057 2076 */ {0x000a, 0x8659}, | ||
447 | /* Edge bandwidth high threshold */ | ||
448 | /* 51082 2077 */ {0x0005, 0x865a}, | ||
449 | /* Edge bandwidth low threshold */ | ||
450 | /* -------------------------------- */ | 393 | /* -------------------------------- */ |
451 | /* 51107 2078 */ {0x0030, 0x8112}, | 394 | {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */ |
452 | /* Video drop enable, ISO streaming enable */ | 395 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
453 | /* 51130 2079 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 396 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
454 | /* 51154 2080 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 397 | {0xa908, 0x8802}, |
455 | /* 51180 2081 */ {0xa908, 0x8802}, | 398 | {0x0034, 0x8801}, /* SSI reg addr */ |
456 | /* 51205 2082 */ {0x0034, 0x8801}, | 399 | {0x00ca, 0x8800}, |
457 | /* SSI reg addr */ | ||
458 | /* 51230 2083 */ {0x00ca, 0x8800}, | ||
459 | /* SSI data to write */ | 400 | /* SSI data to write */ |
460 | /* 51253 2084 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 401 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
461 | /* 51277 2085 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 402 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
462 | /* 51301 2086 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 403 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
463 | /* 51327 2087 */ {0x1f08, 0x8802}, | 404 | {0x1f08, 0x8802}, |
464 | /* 51352 2088 */ {0x0006, 0x8801}, | 405 | {0x0006, 0x8801}, |
465 | /* 51377 2089 */ {0x0080, 0x8800}, | 406 | {0x0080, 0x8800}, |
466 | /* 51400 2090 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 407 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
467 | 408 | ||
468 | /* ----- Read back coefs we wrote earlier. */ | 409 | /* ----- Read back coefs we wrote earlier. */ |
469 | /* 51424 2091 */ /* READ { 0, 0x0000, 0x8608 } -> 0000: 15 */ | 410 | /* READ { 0x0000, 0x8608 } -> 0000: 15 */ |
470 | /* 51448 2092 */ /* READ { 0, 0x0000, 0x8609 } -> 0000: 30 */ | 411 | /* READ { 0x0000, 0x8609 } -> 0000: 30 */ |
471 | /* 51472 2093 */ /* READ { 0, 0x0000, 0x860a } -> 0000: fb */ | 412 | /* READ { 0x0000, 0x860a } -> 0000: fb */ |
472 | /* 51496 2094 */ /* READ { 0, 0x0000, 0x860b } -> 0000: 3e */ | 413 | /* READ { 0x0000, 0x860b } -> 0000: 3e */ |
473 | /* 51520 2095 */ /* READ { 0, 0x0000, 0x860c } -> 0000: ce */ | 414 | /* READ { 0x0000, 0x860c } -> 0000: ce */ |
474 | /* 51544 2096 */ /* READ { 0, 0x0000, 0x860d } -> 0000: f4 */ | 415 | /* READ { 0x0000, 0x860d } -> 0000: f4 */ |
475 | /* 51568 2097 */ /* READ { 0, 0x0000, 0x860e } -> 0000: eb */ | 416 | /* READ { 0x0000, 0x860e } -> 0000: eb */ |
476 | /* 51592 2098 */ /* READ { 0, 0x0000, 0x860f } -> 0000: dc */ | 417 | /* READ { 0x0000, 0x860f } -> 0000: dc */ |
477 | /* 51616 2099 */ /* READ { 0, 0x0000, 0x8610 } -> 0000: 39 */ | 418 | /* READ { 0x0000, 0x8610 } -> 0000: 39 */ |
478 | /* 51640 2100 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 419 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
479 | /* 51664 2101 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 420 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
480 | /* 51690 2102 */ {0xb008, 0x8802}, | 421 | {0xb008, 0x8802}, |
481 | /* 51715 2103 */ {0x0006, 0x8801}, | 422 | {0x0006, 0x8801}, |
482 | /* 51740 2104 */ {0x007d, 0x8800}, | 423 | {0x007d, 0x8800}, |
483 | /* 51763 2105 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 424 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
484 | 425 | ||
485 | 426 | ||
486 | /* This chunk is seemingly redundant with */ | 427 | /* This chunk is seemingly redundant with */ |
487 | /* earlier commands (A11 Coef...), but if I disable it, */ | 428 | /* earlier commands (A11 Coef...), but if I disable it, */ |
488 | /* the image appears too dark. Maybe there was some kind of */ | 429 | /* the image appears too dark. Maybe there was some kind of */ |
489 | /* reset since the earlier commands, so this is necessary again. */ | 430 | /* reset since the earlier commands, so this is necessary again. */ |
490 | /* 51789 2106 */ {0x0015, 0x8608}, | 431 | {0x0015, 0x8608}, |
491 | /* 51814 2107 */ {0x0030, 0x8609}, | 432 | {0x0030, 0x8609}, |
492 | /* 51839 2108 */ {0xfffb, 0x860a}, | 433 | {0xfffb, 0x860a}, |
493 | /* 51864 2109 */ {0x003e, 0x860b}, | 434 | {0x003e, 0x860b}, |
494 | /* 51889 2110 */ {0xffce, 0x860c}, | 435 | {0xffce, 0x860c}, |
495 | /* 51914 2111 */ {0xfff4, 0x860d}, | 436 | {0xfff4, 0x860d}, |
496 | /* 51939 2112 */ {0xffeb, 0x860e}, | 437 | {0xffeb, 0x860e}, |
497 | /* 51964 2113 */ {0xffdc, 0x860f}, | 438 | {0xffdc, 0x860f}, |
498 | /* 51989 2114 */ {0x0039, 0x8610}, | 439 | {0x0039, 0x8610}, |
499 | /* 52014 2115 */ {0x0018, 0x8657}, | 440 | {0x0018, 0x8657}, |
500 | 441 | ||
501 | /* 52039 2116 */ {0x0000, 0x8508}, | 442 | {0x0000, 0x8508}, /* Disable compression. */ |
502 | /* Disable compression. */ | ||
503 | /* Previous line was: | 443 | /* Previous line was: |
504 | * 52039 2116 * { 0, 0x0021, 0x8508 }, * Enable compression. */ | 444 | {0x0021, 0x8508}, * Enable compression. */ |
505 | /* 52064 2117 */ {0x0032, 0x850b}, | 445 | {0x0032, 0x850b}, /* compression stuff */ |
506 | /* compression stuff */ | 446 | {0x0003, 0x8509}, /* compression stuff */ |
507 | /* 52089 2118 */ {0x0003, 0x8509}, | 447 | {0x0011, 0x850a}, /* compression stuff */ |
508 | /* compression stuff */ | 448 | {0x0021, 0x850d}, /* compression stuff */ |
509 | /* 52114 2119 */ {0x0011, 0x850a}, | 449 | {0x0010, 0x850c}, /* compression stuff */ |
510 | /* compression stuff */ | 450 | {0x0003, 0x8500}, /* *** Video mode: 160x120 */ |
511 | /* 52139 2120 */ {0x0021, 0x850d}, | 451 | {0x0001, 0x8501}, /* Hardware-dominated snap control */ |
512 | /* compression stuff */ | 452 | {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128, |
513 | /* 52164 2121 */ {0x0010, 0x850c}, | 453 | * gamma look-up disable, |
514 | /* compression stuff */ | 454 | * new edge enhancement enable */ |
515 | /* 52189 2122 */ {0x0003, 0x8500}, | 455 | {0x0018, 0x8617}, /* Window1 start X (*2) */ |
516 | /* *** Video mode: 160x120 */ | 456 | {0x0008, 0x8618}, /* Window1 start Y (*2) */ |
517 | /* 52214 2123 */ {0x0001, 0x8501}, | 457 | {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128, |
518 | /* Hardware-dominated snap control */ | 458 | * gamma look-up disable, |
519 | /* 52239 2124 */ {0x0061, 0x8656}, | 459 | * new edge enhancement enable */ |
520 | /* Window1 size 128x128, Windows2 size 128x128, | 460 | {0x0058, 0x8619}, /* Window2 start X (*2) */ |
521 | * gamma look-up disable, new edge enhancement enable */ | 461 | {0x0008, 0x861a}, /* Window2 start Y (*2) */ |
522 | /* 52264 2125 */ {0x0018, 0x8617}, | 462 | {0x00ff, 0x8615}, /* High lum thresh for white balance */ |
523 | /* Window1 start X (*2) */ | 463 | {0x0000, 0x8616}, /* Low lum thresh for white balance */ |
524 | /* 52289 2126 */ {0x0008, 0x8618}, | 464 | {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ |
525 | /* Window1 start Y (*2) */ | 465 | {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ |
526 | /* 52314 2127 */ {0x0061, 0x8656}, | 466 | /* READ { 0x0000, 0x8656 } -> 0000: 61 */ |
527 | /* Window1 size 128x128, Windows2 size 128x128, | 467 | {0x0028, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ |
528 | * gamma look-up disable, new edge enhancement enable */ | 468 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
529 | /* 52339 2128 */ {0x0058, 0x8619}, | 469 | /* READ { 0x0001, 0x8802 } -> 0000: 28 */ |
530 | /* Window2 start X (*2) */ | 470 | {0x1f28, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ |
531 | /* 52364 2129 */ {0x0008, 0x861a}, | 471 | {0x0010, 0x8801}, /* SSI reg addr */ |
532 | /* Window2 start Y (*2) */ | 472 | {0x003e, 0x8800}, /* SSI data to write */ |
533 | /* 52389 2130 */ {0x00ff, 0x8615}, | 473 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
534 | /* High lum thresh for white balance */ | 474 | {0x0028, 0x8802}, |
535 | /* 52414 2131 */ {0x0000, 0x8616}, | 475 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
536 | /* Low lum thresh for white balance */ | 476 | /* READ { 0x0001, 0x8802 } -> 0000: 28 */ |
537 | /* 52439 2132 */ {0x0012, 0x8700}, | 477 | {0x1f28, 0x8802}, |
538 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | 478 | {0x0000, 0x8801}, |
539 | /* 52464 2133 */ {0x0012, 0x8700}, | 479 | {0x001f, 0x8800}, |
540 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | 480 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
541 | /* 52487 2134 */ /* READ { 0, 0x0000, 0x8656 } -> 0000: 61 */ | 481 | {0x0001, 0x8602}, /* optical black level for user settning = 1 */ |
542 | /* 52513 2135 */ {0x0028, 0x8802}, | ||
543 | /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ | ||
544 | /* 52536 2136 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
545 | /* 52560 2137 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
546 | /* 52586 2138 */ {0x1f28, 0x8802}, | ||
547 | /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ | ||
548 | /* 52611 2139 */ {0x0010, 0x8801}, | ||
549 | /* SSI reg addr */ | ||
550 | /* 52636 2140 */ {0x003e, 0x8800}, | ||
551 | /* SSI data to write */ | ||
552 | /* 52659 2141 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
553 | /* 52685 2142 */ {0x0028, 0x8802}, | ||
554 | /* 52708 2143 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
555 | /* 52732 2144 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
556 | /* 52758 2145 */ {0x1f28, 0x8802}, | ||
557 | /* 52783 2146 */ {0x0000, 0x8801}, | ||
558 | /* 52808 2147 */ {0x001f, 0x8800}, | ||
559 | /* 52831 2148 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
560 | /* 52857 2149 */ {0x0001, 0x8602}, | ||
561 | /* optical black level for user settning = 1 */ | ||
562 | 482 | ||
563 | /* Original: */ | 483 | /* Original: */ |
564 | /* 52882 2150 */ {0x0023, 0x8700}, | 484 | {0x0023, 0x8700}, /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ |
565 | /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ | 485 | {0x000f, 0x8602}, /* optical black level for user settning = 15 */ |
566 | /* 52907 2151 */ {0x000f, 0x8602}, | 486 | |
567 | /* optical black level for user settning = 15 */ | 487 | {0x0028, 0x8802}, |
568 | 488 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ | |
569 | /* 52932 2152 */ {0x0028, 0x8802}, | 489 | /* READ { 0x0001, 0x8802 } -> 0000: 28 */ |
570 | /* 52955 2153 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 490 | {0x1f28, 0x8802}, |
571 | /* 52979 2154 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | 491 | {0x0010, 0x8801}, |
572 | /* 53005 2155 */ {0x1f28, 0x8802}, | 492 | {0x007b, 0x8800}, |
573 | /* 53030 2156 */ {0x0010, 0x8801}, | 493 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
574 | /* 53055 2157 */ {0x007b, 0x8800}, | 494 | {0x002f, 0x8651}, /* R gain for white balance ... */ |
575 | /* 53078 2158 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 495 | {0x0080, 0x8653}, |
576 | /* 53104 2159 */ {0x002f, 0x8651}, | 496 | /* READ { 0x0000, 0x8655 } -> 0000: 00 */ |
577 | /* R gain for white balance ... */ | 497 | {0x0000, 0x8655}, |
578 | /* 53129 2160 */ {0x0080, 0x8653}, | 498 | |
579 | /* 53152 2161 */ /* READ { 0, 0x0000, 0x8655 } -> 0000: 00 */ | 499 | {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */ |
580 | /* 53178 2162 */ {0x0000, 0x8655}, | 500 | {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ |
581 | 501 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */ | |
582 | /* 53203 2163 */ {0x0030, 0x8112}, | ||
583 | /* Video drop enable, ISO streaming enable */ | ||
584 | /* 53228 2164 */ {0x0020, 0x8112}, | ||
585 | /* Video drop enable, ISO streaming disable */ | ||
586 | /* 53252 2165 */ | ||
587 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */ | ||
588 | {} | 502 | {} |
589 | }; | 503 | }; |
590 | 504 | ||
@@ -592,27 +506,27 @@ static const u16 spca508_init_data[][2] = | |||
592 | * Initialization data for Intel EasyPC Camera CS110 | 506 | * Initialization data for Intel EasyPC Camera CS110 |
593 | */ | 507 | */ |
594 | static const u16 spca508cs110_init_data[][2] = { | 508 | static const u16 spca508cs110_init_data[][2] = { |
595 | {0x0000, 0x870b}, /* Reset CTL3 */ | 509 | {0x0000, 0x870b}, /* Reset CTL3 */ |
596 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ | 510 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ |
597 | {0x0000, 0x8111}, /* Normal operation on reset */ | 511 | {0x0000, 0x8111}, /* Normal operation on reset */ |
598 | {0x0090, 0x8110}, | 512 | {0x0090, 0x8110}, |
599 | /* External Clock 2x & Synchronous Serial Interface Output */ | 513 | /* External Clock 2x & Synchronous Serial Interface Output */ |
600 | {0x0020, 0x8112}, /* Video Drop packet enable */ | 514 | {0x0020, 0x8112}, /* Video Drop packet enable */ |
601 | {0x0000, 0x8114}, /* Software GPIO output data */ | 515 | {0x0000, 0x8114}, /* Software GPIO output data */ |
602 | {0x0001, 0x8114}, | 516 | {0x0001, 0x8114}, |
603 | {0x0001, 0x8114}, | 517 | {0x0001, 0x8114}, |
604 | {0x0001, 0x8114}, | 518 | {0x0001, 0x8114}, |
605 | {0x0003, 0x8114}, | 519 | {0x0003, 0x8114}, |
606 | 520 | ||
607 | /* Initial sequence Synchronous Serial Interface */ | 521 | /* Initial sequence Synchronous Serial Interface */ |
608 | {0x000f, 0x8402}, /* Memory bank Address */ | 522 | {0x000f, 0x8402}, /* Memory bank Address */ |
609 | {0x0000, 0x8403}, /* Memory bank Address */ | 523 | {0x0000, 0x8403}, /* Memory bank Address */ |
610 | {0x00ba, 0x8804}, /* SSI Slave address */ | 524 | {0x00ba, 0x8804}, /* SSI Slave address */ |
611 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ | 525 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ |
612 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ | 526 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ |
613 | 527 | ||
614 | {0x0001, 0x8801}, | 528 | {0x0001, 0x8801}, |
615 | {0x000a, 0x8805},/* a - NWG: Dunno what this is about */ | 529 | {0x000a, 0x8805}, /* a - NWG: Dunno what this is about */ |
616 | {0x0000, 0x8800}, | 530 | {0x0000, 0x8800}, |
617 | {0x0010, 0x8802}, | 531 | {0x0010, 0x8802}, |
618 | 532 | ||
@@ -646,459 +560,459 @@ static const u16 spca508cs110_init_data[][2] = { | |||
646 | {0x0000, 0x8800}, | 560 | {0x0000, 0x8800}, |
647 | {0x0010, 0x8802}, | 561 | {0x0010, 0x8802}, |
648 | 562 | ||
649 | {0x0002, 0x8704}, /* External input CKIx1 */ | 563 | {0x0002, 0x8704}, /* External input CKIx1 */ |
650 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ | 564 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ |
651 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ | 565 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ |
652 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ | 566 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ |
653 | {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ | 567 | {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ |
654 | {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ | 568 | {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ |
655 | 569 | ||
656 | {0x0006, 0x8660}, /* Nibble data + input order */ | 570 | {0x0006, 0x8660}, /* Nibble data + input order */ |
657 | 571 | ||
658 | {0x000a, 0x8602}, /* Optical black level set to 0x0a */ | 572 | {0x000a, 0x8602}, /* Optical black level set to 0x0a */ |
659 | /* 1945 */ {0x0000, 0x8603}, /* Optical black level Offset */ | 573 | {0x0000, 0x8603}, /* Optical black level Offset */ |
660 | 574 | ||
661 | /* 1962 * {0, 0x0000, 0x8611}, * 0 R Offset for white Balance */ | 575 | /* {0x0000, 0x8611}, * 0 R Offset for white Balance */ |
662 | /* 1963 * {0, 0x0000, 0x8612}, * 1 Gr Offset for white Balance */ | 576 | /* {0x0000, 0x8612}, * 1 Gr Offset for white Balance */ |
663 | /* 1964 * {0, 0x0000, 0x8613}, * 1f B Offset for white Balance */ | 577 | /* {0x0000, 0x8613}, * 1f B Offset for white Balance */ |
664 | /* 1965 * {0, 0x0000, 0x8614}, * f0 Gb Offset for white Balance */ | 578 | /* {0x0000, 0x8614}, * f0 Gb Offset for white Balance */ |
665 | 579 | ||
666 | {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ | 580 | {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ |
667 | {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ | 581 | {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ |
668 | {0x0035, 0x8653}, /* 26 RED gain for white balance */ | 582 | {0x0035, 0x8653}, /* 26 RED gain for white balance */ |
669 | {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ | 583 | {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ |
670 | {0x0041, 0x863f}, | 584 | {0x0041, 0x863f}, |
671 | /* Fixed Gamma correction enabled (makes colours look better) */ | 585 | /* Fixed Gamma correction enabled (makes colours look better) */ |
672 | 586 | ||
673 | /* 2422 */ {0x0000, 0x8655}, | 587 | {0x0000, 0x8655}, |
674 | /* High bits for white balance*****brightness control*** */ | 588 | /* High bits for white balance*****brightness control*** */ |
675 | {} | 589 | {} |
676 | }; | 590 | }; |
677 | 591 | ||
678 | static const u16 spca508_sightcam_init_data[][2] = { | 592 | static const u16 spca508_sightcam_init_data[][2] = { |
679 | /* This line seems to setup the frame/canvas */ | 593 | /* This line seems to setup the frame/canvas */ |
680 | /*368 */ {0x000f, 0x8402}, | 594 | {0x000f, 0x8402}, |
681 | 595 | ||
682 | /* Theese 6 lines are needed to startup the webcam */ | 596 | /* Theese 6 lines are needed to startup the webcam */ |
683 | /*398 */ {0x0090, 0x8110}, | 597 | {0x0090, 0x8110}, |
684 | /*399 */ {0x0001, 0x8114}, | 598 | {0x0001, 0x8114}, |
685 | /*400 */ {0x0001, 0x8114}, | 599 | {0x0001, 0x8114}, |
686 | /*401 */ {0x0001, 0x8114}, | 600 | {0x0001, 0x8114}, |
687 | /*402 */ {0x0003, 0x8114}, | 601 | {0x0003, 0x8114}, |
688 | /*403 */ {0x0080, 0x8804}, | 602 | {0x0080, 0x8804}, |
689 | 603 | ||
690 | /* This part seems to make the pictures darker? (autobrightness?) */ | 604 | /* This part seems to make the pictures darker? (autobrightness?) */ |
691 | /*436 */ {0x0001, 0x8801}, | 605 | {0x0001, 0x8801}, |
692 | /*437 */ {0x0004, 0x8800}, | 606 | {0x0004, 0x8800}, |
693 | /*439 */ {0x0003, 0x8801}, | 607 | {0x0003, 0x8801}, |
694 | /*440 */ {0x00e0, 0x8800}, | 608 | {0x00e0, 0x8800}, |
695 | /*442 */ {0x0004, 0x8801}, | 609 | {0x0004, 0x8801}, |
696 | /*443 */ {0x00b4, 0x8800}, | 610 | {0x00b4, 0x8800}, |
697 | /*445 */ {0x0005, 0x8801}, | 611 | {0x0005, 0x8801}, |
698 | /*446 */ {0x0000, 0x8800}, | 612 | {0x0000, 0x8800}, |
699 | 613 | ||
700 | /*448 */ {0x0006, 0x8801}, | 614 | {0x0006, 0x8801}, |
701 | /*449 */ {0x00e0, 0x8800}, | 615 | {0x00e0, 0x8800}, |
702 | /*451 */ {0x0007, 0x8801}, | 616 | {0x0007, 0x8801}, |
703 | /*452 */ {0x000c, 0x8800}, | 617 | {0x000c, 0x8800}, |
704 | 618 | ||
705 | /* This section is just needed, it probably | 619 | /* This section is just needed, it probably |
706 | * does something like the previous section, | 620 | * does something like the previous section, |
707 | * but the cam won't start if it's not included. | 621 | * but the cam won't start if it's not included. |
708 | */ | 622 | */ |
709 | /*484 */ {0x0014, 0x8801}, | 623 | {0x0014, 0x8801}, |
710 | /*485 */ {0x0008, 0x8800}, | 624 | {0x0008, 0x8800}, |
711 | /*487 */ {0x0015, 0x8801}, | 625 | {0x0015, 0x8801}, |
712 | /*488 */ {0x0067, 0x8800}, | 626 | {0x0067, 0x8800}, |
713 | /*490 */ {0x0016, 0x8801}, | 627 | {0x0016, 0x8801}, |
714 | /*491 */ {0x0000, 0x8800}, | 628 | {0x0000, 0x8800}, |
715 | /*493 */ {0x0017, 0x8801}, | 629 | {0x0017, 0x8801}, |
716 | /*494 */ {0x0020, 0x8800}, | 630 | {0x0020, 0x8800}, |
717 | /*496 */ {0x0018, 0x8801}, | 631 | {0x0018, 0x8801}, |
718 | /*497 */ {0x0044, 0x8800}, | 632 | {0x0044, 0x8800}, |
719 | 633 | ||
720 | /* Makes the picture darker - and the | 634 | /* Makes the picture darker - and the |
721 | * cam won't start if not included | 635 | * cam won't start if not included |
722 | */ | 636 | */ |
723 | /*505 */ {0x001e, 0x8801}, | 637 | {0x001e, 0x8801}, |
724 | /*506 */ {0x00ea, 0x8800}, | 638 | {0x00ea, 0x8800}, |
725 | /*508 */ {0x001f, 0x8801}, | 639 | {0x001f, 0x8801}, |
726 | /*509 */ {0x0001, 0x8800}, | 640 | {0x0001, 0x8800}, |
727 | /*511 */ {0x0003, 0x8801}, | 641 | {0x0003, 0x8801}, |
728 | /*512 */ {0x00e0, 0x8800}, | 642 | {0x00e0, 0x8800}, |
729 | 643 | ||
730 | /* seems to place the colors ontop of each other #1 */ | 644 | /* seems to place the colors ontop of each other #1 */ |
731 | /*517 */ {0x0006, 0x8704}, | 645 | {0x0006, 0x8704}, |
732 | /*518 */ {0x0001, 0x870c}, | 646 | {0x0001, 0x870c}, |
733 | /*519 */ {0x0016, 0x8600}, | 647 | {0x0016, 0x8600}, |
734 | /*520 */ {0x0002, 0x8606}, | 648 | {0x0002, 0x8606}, |
735 | 649 | ||
736 | /* if not included the pictures becomes _very_ dark */ | 650 | /* if not included the pictures becomes _very_ dark */ |
737 | /*521 */ {0x0064, 0x8607}, | 651 | {0x0064, 0x8607}, |
738 | /*522 */ {0x003a, 0x8601}, | 652 | {0x003a, 0x8601}, |
739 | /*523 */ {0x0000, 0x8602}, | 653 | {0x0000, 0x8602}, |
740 | 654 | ||
741 | /* seems to place the colors ontop of each other #2 */ | 655 | /* seems to place the colors ontop of each other #2 */ |
742 | /*524 */ {0x0016, 0x8600}, | 656 | {0x0016, 0x8600}, |
743 | /*525 */ {0x0018, 0x8617}, | 657 | {0x0018, 0x8617}, |
744 | /*526 */ {0x0008, 0x8618}, | 658 | {0x0008, 0x8618}, |
745 | /*527 */ {0x00a1, 0x8656}, | 659 | {0x00a1, 0x8656}, |
746 | 660 | ||
747 | /* webcam won't start if not included */ | 661 | /* webcam won't start if not included */ |
748 | /*528 */ {0x0007, 0x865b}, | 662 | {0x0007, 0x865b}, |
749 | /*529 */ {0x0001, 0x865c}, | 663 | {0x0001, 0x865c}, |
750 | /*530 */ {0x0058, 0x865d}, | 664 | {0x0058, 0x865d}, |
751 | /*531 */ {0x0048, 0x865e}, | 665 | {0x0048, 0x865e}, |
752 | 666 | ||
753 | /* adjusts the colors */ | 667 | /* adjusts the colors */ |
754 | /*541 */ {0x0049, 0x8651}, | 668 | {0x0049, 0x8651}, |
755 | /*542 */ {0x0040, 0x8652}, | 669 | {0x0040, 0x8652}, |
756 | /*543 */ {0x004c, 0x8653}, | 670 | {0x004c, 0x8653}, |
757 | /*544 */ {0x0040, 0x8654}, | 671 | {0x0040, 0x8654}, |
758 | {} | 672 | {} |
759 | }; | 673 | }; |
760 | 674 | ||
761 | static const u16 spca508_sightcam2_init_data[][2] = { | 675 | static const u16 spca508_sightcam2_init_data[][2] = { |
762 | /* 35 */ {0x0020, 0x8112}, | 676 | {0x0020, 0x8112}, |
763 | 677 | ||
764 | /* 36 */ {0x000f, 0x8402}, | 678 | {0x000f, 0x8402}, |
765 | /* 37 */ {0x0000, 0x8403}, | 679 | {0x0000, 0x8403}, |
766 | 680 | ||
767 | /* 38 */ {0x0008, 0x8201}, | 681 | {0x0008, 0x8201}, |
768 | /* 39 */ {0x0008, 0x8200}, | 682 | {0x0008, 0x8200}, |
769 | /* 40 */ {0x0001, 0x8200}, | 683 | {0x0001, 0x8200}, |
770 | /* 43 */ {0x0009, 0x8201}, | 684 | {0x0009, 0x8201}, |
771 | /* 44 */ {0x0008, 0x8200}, | 685 | {0x0008, 0x8200}, |
772 | /* 45 */ {0x0001, 0x8200}, | 686 | {0x0001, 0x8200}, |
773 | /* 48 */ {0x000a, 0x8201}, | 687 | {0x000a, 0x8201}, |
774 | /* 49 */ {0x0008, 0x8200}, | 688 | {0x0008, 0x8200}, |
775 | /* 50 */ {0x0001, 0x8200}, | 689 | {0x0001, 0x8200}, |
776 | /* 53 */ {0x000b, 0x8201}, | 690 | {0x000b, 0x8201}, |
777 | /* 54 */ {0x0008, 0x8200}, | 691 | {0x0008, 0x8200}, |
778 | /* 55 */ {0x0001, 0x8200}, | 692 | {0x0001, 0x8200}, |
779 | /* 58 */ {0x000c, 0x8201}, | 693 | {0x000c, 0x8201}, |
780 | /* 59 */ {0x0008, 0x8200}, | 694 | {0x0008, 0x8200}, |
781 | /* 60 */ {0x0001, 0x8200}, | 695 | {0x0001, 0x8200}, |
782 | /* 63 */ {0x000d, 0x8201}, | 696 | {0x000d, 0x8201}, |
783 | /* 64 */ {0x0008, 0x8200}, | 697 | {0x0008, 0x8200}, |
784 | /* 65 */ {0x0001, 0x8200}, | 698 | {0x0001, 0x8200}, |
785 | /* 68 */ {0x000e, 0x8201}, | 699 | {0x000e, 0x8201}, |
786 | /* 69 */ {0x0008, 0x8200}, | 700 | {0x0008, 0x8200}, |
787 | /* 70 */ {0x0001, 0x8200}, | 701 | {0x0001, 0x8200}, |
788 | /* 73 */ {0x0007, 0x8201}, | 702 | {0x0007, 0x8201}, |
789 | /* 74 */ {0x0008, 0x8200}, | 703 | {0x0008, 0x8200}, |
790 | /* 75 */ {0x0001, 0x8200}, | 704 | {0x0001, 0x8200}, |
791 | /* 78 */ {0x000f, 0x8201}, | 705 | {0x000f, 0x8201}, |
792 | /* 79 */ {0x0008, 0x8200}, | 706 | {0x0008, 0x8200}, |
793 | /* 80 */ {0x0001, 0x8200}, | 707 | {0x0001, 0x8200}, |
794 | 708 | ||
795 | /* 84 */ {0x0018, 0x8660}, | 709 | {0x0018, 0x8660}, |
796 | /* 85 */ {0x0010, 0x8201}, | 710 | {0x0010, 0x8201}, |
797 | 711 | ||
798 | /* 86 */ {0x0008, 0x8200}, | 712 | {0x0008, 0x8200}, |
799 | /* 87 */ {0x0001, 0x8200}, | 713 | {0x0001, 0x8200}, |
800 | /* 90 */ {0x0011, 0x8201}, | 714 | {0x0011, 0x8201}, |
801 | /* 91 */ {0x0008, 0x8200}, | 715 | {0x0008, 0x8200}, |
802 | /* 92 */ {0x0001, 0x8200}, | 716 | {0x0001, 0x8200}, |
803 | 717 | ||
804 | /* 95 */ {0x0000, 0x86b0}, | 718 | {0x0000, 0x86b0}, |
805 | /* 96 */ {0x0034, 0x86b1}, | 719 | {0x0034, 0x86b1}, |
806 | /* 97 */ {0x0000, 0x86b2}, | 720 | {0x0000, 0x86b2}, |
807 | /* 98 */ {0x0049, 0x86b3}, | 721 | {0x0049, 0x86b3}, |
808 | /* 99 */ {0x0000, 0x86b4}, | 722 | {0x0000, 0x86b4}, |
809 | /* 100 */ {0x0000, 0x86b4}, | 723 | {0x0000, 0x86b4}, |
810 | 724 | ||
811 | /* 101 */ {0x0012, 0x8201}, | 725 | {0x0012, 0x8201}, |
812 | /* 102 */ {0x0008, 0x8200}, | 726 | {0x0008, 0x8200}, |
813 | /* 103 */ {0x0001, 0x8200}, | 727 | {0x0001, 0x8200}, |
814 | /* 106 */ {0x0013, 0x8201}, | 728 | {0x0013, 0x8201}, |
815 | /* 107 */ {0x0008, 0x8200}, | 729 | {0x0008, 0x8200}, |
816 | /* 108 */ {0x0001, 0x8200}, | 730 | {0x0001, 0x8200}, |
817 | 731 | ||
818 | /* 111 */ {0x0001, 0x86b0}, | 732 | {0x0001, 0x86b0}, |
819 | /* 112 */ {0x00aa, 0x86b1}, | 733 | {0x00aa, 0x86b1}, |
820 | /* 113 */ {0x0000, 0x86b2}, | 734 | {0x0000, 0x86b2}, |
821 | /* 114 */ {0x00e4, 0x86b3}, | 735 | {0x00e4, 0x86b3}, |
822 | /* 115 */ {0x0000, 0x86b4}, | 736 | {0x0000, 0x86b4}, |
823 | /* 116 */ {0x0000, 0x86b4}, | 737 | {0x0000, 0x86b4}, |
824 | 738 | ||
825 | /* 118 */ {0x0018, 0x8660}, | 739 | {0x0018, 0x8660}, |
826 | 740 | ||
827 | /* 119 */ {0x0090, 0x8110}, | 741 | {0x0090, 0x8110}, |
828 | /* 120 */ {0x0001, 0x8114}, | 742 | {0x0001, 0x8114}, |
829 | /* 121 */ {0x0001, 0x8114}, | 743 | {0x0001, 0x8114}, |
830 | /* 122 */ {0x0001, 0x8114}, | 744 | {0x0001, 0x8114}, |
831 | /* 123 */ {0x0003, 0x8114}, | 745 | {0x0003, 0x8114}, |
832 | 746 | ||
833 | /* 124 */ {0x0080, 0x8804}, | 747 | {0x0080, 0x8804}, |
834 | /* 157 */ {0x0003, 0x8801}, | 748 | {0x0003, 0x8801}, |
835 | /* 158 */ {0x0012, 0x8800}, | 749 | {0x0012, 0x8800}, |
836 | /* 160 */ {0x0004, 0x8801}, | 750 | {0x0004, 0x8801}, |
837 | /* 161 */ {0x0005, 0x8800}, | 751 | {0x0005, 0x8800}, |
838 | /* 163 */ {0x0005, 0x8801}, | 752 | {0x0005, 0x8801}, |
839 | /* 164 */ {0x0000, 0x8800}, | 753 | {0x0000, 0x8800}, |
840 | /* 166 */ {0x0006, 0x8801}, | 754 | {0x0006, 0x8801}, |
841 | /* 167 */ {0x0000, 0x8800}, | 755 | {0x0000, 0x8800}, |
842 | /* 169 */ {0x0007, 0x8801}, | 756 | {0x0007, 0x8801}, |
843 | /* 170 */ {0x0000, 0x8800}, | 757 | {0x0000, 0x8800}, |
844 | /* 172 */ {0x0008, 0x8801}, | 758 | {0x0008, 0x8801}, |
845 | /* 173 */ {0x0005, 0x8800}, | 759 | {0x0005, 0x8800}, |
846 | /* 175 */ {0x000a, 0x8700}, | 760 | {0x000a, 0x8700}, |
847 | /* 176 */ {0x000e, 0x8801}, | 761 | {0x000e, 0x8801}, |
848 | /* 177 */ {0x0004, 0x8800}, | 762 | {0x0004, 0x8800}, |
849 | /* 179 */ {0x0005, 0x8801}, | 763 | {0x0005, 0x8801}, |
850 | /* 180 */ {0x0047, 0x8800}, | 764 | {0x0047, 0x8800}, |
851 | /* 182 */ {0x0006, 0x8801}, | 765 | {0x0006, 0x8801}, |
852 | /* 183 */ {0x0000, 0x8800}, | 766 | {0x0000, 0x8800}, |
853 | /* 185 */ {0x0007, 0x8801}, | 767 | {0x0007, 0x8801}, |
854 | /* 186 */ {0x00c0, 0x8800}, | 768 | {0x00c0, 0x8800}, |
855 | /* 188 */ {0x0008, 0x8801}, | 769 | {0x0008, 0x8801}, |
856 | /* 189 */ {0x0003, 0x8800}, | 770 | {0x0003, 0x8800}, |
857 | /* 191 */ {0x0013, 0x8801}, | 771 | {0x0013, 0x8801}, |
858 | /* 192 */ {0x0001, 0x8800}, | 772 | {0x0001, 0x8800}, |
859 | /* 194 */ {0x0009, 0x8801}, | 773 | {0x0009, 0x8801}, |
860 | /* 195 */ {0x0000, 0x8800}, | 774 | {0x0000, 0x8800}, |
861 | /* 197 */ {0x000a, 0x8801}, | 775 | {0x000a, 0x8801}, |
862 | /* 198 */ {0x0000, 0x8800}, | 776 | {0x0000, 0x8800}, |
863 | /* 200 */ {0x000b, 0x8801}, | 777 | {0x000b, 0x8801}, |
864 | /* 201 */ {0x0000, 0x8800}, | 778 | {0x0000, 0x8800}, |
865 | /* 203 */ {0x000c, 0x8801}, | 779 | {0x000c, 0x8801}, |
866 | /* 204 */ {0x0000, 0x8800}, | 780 | {0x0000, 0x8800}, |
867 | /* 206 */ {0x000e, 0x8801}, | 781 | {0x000e, 0x8801}, |
868 | /* 207 */ {0x0004, 0x8800}, | 782 | {0x0004, 0x8800}, |
869 | /* 209 */ {0x000f, 0x8801}, | 783 | {0x000f, 0x8801}, |
870 | /* 210 */ {0x0000, 0x8800}, | 784 | {0x0000, 0x8800}, |
871 | /* 212 */ {0x0010, 0x8801}, | 785 | {0x0010, 0x8801}, |
872 | /* 213 */ {0x0006, 0x8800}, | 786 | {0x0006, 0x8800}, |
873 | /* 215 */ {0x0011, 0x8801}, | 787 | {0x0011, 0x8801}, |
874 | /* 216 */ {0x0006, 0x8800}, | 788 | {0x0006, 0x8800}, |
875 | /* 218 */ {0x0012, 0x8801}, | 789 | {0x0012, 0x8801}, |
876 | /* 219 */ {0x0000, 0x8800}, | 790 | {0x0000, 0x8800}, |
877 | /* 221 */ {0x0013, 0x8801}, | 791 | {0x0013, 0x8801}, |
878 | /* 222 */ {0x0001, 0x8800}, | 792 | {0x0001, 0x8800}, |
879 | 793 | ||
880 | /* 224 */ {0x000a, 0x8700}, | 794 | {0x000a, 0x8700}, |
881 | /* 225 */ {0x0000, 0x8702}, | 795 | {0x0000, 0x8702}, |
882 | /* 226 */ {0x0000, 0x8703}, | 796 | {0x0000, 0x8703}, |
883 | /* 227 */ {0x00c2, 0x8704}, | 797 | {0x00c2, 0x8704}, |
884 | /* 228 */ {0x0001, 0x870c}, | 798 | {0x0001, 0x870c}, |
885 | 799 | ||
886 | /* 229 */ {0x0044, 0x8600}, | 800 | {0x0044, 0x8600}, |
887 | /* 230 */ {0x0002, 0x8606}, | 801 | {0x0002, 0x8606}, |
888 | /* 231 */ {0x0064, 0x8607}, | 802 | {0x0064, 0x8607}, |
889 | /* 232 */ {0x003a, 0x8601}, | 803 | {0x003a, 0x8601}, |
890 | /* 233 */ {0x0008, 0x8602}, | 804 | {0x0008, 0x8602}, |
891 | /* 234 */ {0x0044, 0x8600}, | 805 | {0x0044, 0x8600}, |
892 | /* 235 */ {0x0018, 0x8617}, | 806 | {0x0018, 0x8617}, |
893 | /* 236 */ {0x0008, 0x8618}, | 807 | {0x0008, 0x8618}, |
894 | /* 237 */ {0x00a1, 0x8656}, | 808 | {0x00a1, 0x8656}, |
895 | /* 238 */ {0x0004, 0x865b}, | 809 | {0x0004, 0x865b}, |
896 | /* 239 */ {0x0002, 0x865c}, | 810 | {0x0002, 0x865c}, |
897 | /* 240 */ {0x0058, 0x865d}, | 811 | {0x0058, 0x865d}, |
898 | /* 241 */ {0x0048, 0x865e}, | 812 | {0x0048, 0x865e}, |
899 | /* 242 */ {0x0012, 0x8608}, | 813 | {0x0012, 0x8608}, |
900 | /* 243 */ {0x002c, 0x8609}, | 814 | {0x002c, 0x8609}, |
901 | /* 244 */ {0x0002, 0x860a}, | 815 | {0x0002, 0x860a}, |
902 | /* 245 */ {0x002c, 0x860b}, | 816 | {0x002c, 0x860b}, |
903 | /* 246 */ {0x00db, 0x860c}, | 817 | {0x00db, 0x860c}, |
904 | /* 247 */ {0x00f9, 0x860d}, | 818 | {0x00f9, 0x860d}, |
905 | /* 248 */ {0x00f1, 0x860e}, | 819 | {0x00f1, 0x860e}, |
906 | /* 249 */ {0x00e3, 0x860f}, | 820 | {0x00e3, 0x860f}, |
907 | /* 250 */ {0x002c, 0x8610}, | 821 | {0x002c, 0x8610}, |
908 | /* 251 */ {0x006c, 0x8651}, | 822 | {0x006c, 0x8651}, |
909 | /* 252 */ {0x0041, 0x8652}, | 823 | {0x0041, 0x8652}, |
910 | /* 253 */ {0x0059, 0x8653}, | 824 | {0x0059, 0x8653}, |
911 | /* 254 */ {0x0040, 0x8654}, | 825 | {0x0040, 0x8654}, |
912 | /* 255 */ {0x00fa, 0x8611}, | 826 | {0x00fa, 0x8611}, |
913 | /* 256 */ {0x00ff, 0x8612}, | 827 | {0x00ff, 0x8612}, |
914 | /* 257 */ {0x00f8, 0x8613}, | 828 | {0x00f8, 0x8613}, |
915 | /* 258 */ {0x0000, 0x8614}, | 829 | {0x0000, 0x8614}, |
916 | /* 259 */ {0x0001, 0x863f}, | 830 | {0x0001, 0x863f}, |
917 | /* 260 */ {0x0000, 0x8640}, | 831 | {0x0000, 0x8640}, |
918 | /* 261 */ {0x0026, 0x8641}, | 832 | {0x0026, 0x8641}, |
919 | /* 262 */ {0x0045, 0x8642}, | 833 | {0x0045, 0x8642}, |
920 | /* 263 */ {0x0060, 0x8643}, | 834 | {0x0060, 0x8643}, |
921 | /* 264 */ {0x0075, 0x8644}, | 835 | {0x0075, 0x8644}, |
922 | /* 265 */ {0x0088, 0x8645}, | 836 | {0x0088, 0x8645}, |
923 | /* 266 */ {0x009b, 0x8646}, | 837 | {0x009b, 0x8646}, |
924 | /* 267 */ {0x00b0, 0x8647}, | 838 | {0x00b0, 0x8647}, |
925 | /* 268 */ {0x00c5, 0x8648}, | 839 | {0x00c5, 0x8648}, |
926 | /* 269 */ {0x00d2, 0x8649}, | 840 | {0x00d2, 0x8649}, |
927 | /* 270 */ {0x00dc, 0x864a}, | 841 | {0x00dc, 0x864a}, |
928 | /* 271 */ {0x00e5, 0x864b}, | 842 | {0x00e5, 0x864b}, |
929 | /* 272 */ {0x00eb, 0x864c}, | 843 | {0x00eb, 0x864c}, |
930 | /* 273 */ {0x00f0, 0x864d}, | 844 | {0x00f0, 0x864d}, |
931 | /* 274 */ {0x00f6, 0x864e}, | 845 | {0x00f6, 0x864e}, |
932 | /* 275 */ {0x00fa, 0x864f}, | 846 | {0x00fa, 0x864f}, |
933 | /* 276 */ {0x00ff, 0x8650}, | 847 | {0x00ff, 0x8650}, |
934 | /* 277 */ {0x0060, 0x8657}, | 848 | {0x0060, 0x8657}, |
935 | /* 278 */ {0x0010, 0x8658}, | 849 | {0x0010, 0x8658}, |
936 | /* 279 */ {0x0018, 0x8659}, | 850 | {0x0018, 0x8659}, |
937 | /* 280 */ {0x0005, 0x865a}, | 851 | {0x0005, 0x865a}, |
938 | /* 281 */ {0x0018, 0x8660}, | 852 | {0x0018, 0x8660}, |
939 | /* 282 */ {0x0003, 0x8509}, | 853 | {0x0003, 0x8509}, |
940 | /* 283 */ {0x0011, 0x850a}, | 854 | {0x0011, 0x850a}, |
941 | /* 284 */ {0x0032, 0x850b}, | 855 | {0x0032, 0x850b}, |
942 | /* 285 */ {0x0010, 0x850c}, | 856 | {0x0010, 0x850c}, |
943 | /* 286 */ {0x0021, 0x850d}, | 857 | {0x0021, 0x850d}, |
944 | /* 287 */ {0x0001, 0x8500}, | 858 | {0x0001, 0x8500}, |
945 | /* 288 */ {0x0000, 0x8508}, | 859 | {0x0000, 0x8508}, |
946 | /* 289 */ {0x0012, 0x8608}, | 860 | {0x0012, 0x8608}, |
947 | /* 290 */ {0x002c, 0x8609}, | 861 | {0x002c, 0x8609}, |
948 | /* 291 */ {0x0002, 0x860a}, | 862 | {0x0002, 0x860a}, |
949 | /* 292 */ {0x0039, 0x860b}, | 863 | {0x0039, 0x860b}, |
950 | /* 293 */ {0x00d0, 0x860c}, | 864 | {0x00d0, 0x860c}, |
951 | /* 294 */ {0x00f7, 0x860d}, | 865 | {0x00f7, 0x860d}, |
952 | /* 295 */ {0x00ed, 0x860e}, | 866 | {0x00ed, 0x860e}, |
953 | /* 296 */ {0x00db, 0x860f}, | 867 | {0x00db, 0x860f}, |
954 | /* 297 */ {0x0039, 0x8610}, | 868 | {0x0039, 0x8610}, |
955 | /* 298 */ {0x0012, 0x8657}, | 869 | {0x0012, 0x8657}, |
956 | /* 299 */ {0x000c, 0x8619}, | 870 | {0x000c, 0x8619}, |
957 | /* 300 */ {0x0004, 0x861a}, | 871 | {0x0004, 0x861a}, |
958 | /* 301 */ {0x00a1, 0x8656}, | 872 | {0x00a1, 0x8656}, |
959 | /* 302 */ {0x00c8, 0x8615}, | 873 | {0x00c8, 0x8615}, |
960 | /* 303 */ {0x0032, 0x8616}, | 874 | {0x0032, 0x8616}, |
961 | 875 | ||
962 | /* 306 */ {0x0030, 0x8112}, | 876 | {0x0030, 0x8112}, |
963 | /* 313 */ {0x0020, 0x8112}, | 877 | {0x0020, 0x8112}, |
964 | /* 314 */ {0x0020, 0x8112}, | 878 | {0x0020, 0x8112}, |
965 | /* 315 */ {0x000f, 0x8402}, | 879 | {0x000f, 0x8402}, |
966 | /* 316 */ {0x0000, 0x8403}, | 880 | {0x0000, 0x8403}, |
967 | 881 | ||
968 | /* 317 */ {0x0090, 0x8110}, | 882 | {0x0090, 0x8110}, |
969 | /* 318 */ {0x0001, 0x8114}, | 883 | {0x0001, 0x8114}, |
970 | /* 319 */ {0x0001, 0x8114}, | 884 | {0x0001, 0x8114}, |
971 | /* 320 */ {0x0001, 0x8114}, | 885 | {0x0001, 0x8114}, |
972 | /* 321 */ {0x0003, 0x8114}, | 886 | {0x0003, 0x8114}, |
973 | /* 322 */ {0x0080, 0x8804}, | 887 | {0x0080, 0x8804}, |
974 | 888 | ||
975 | /* 355 */ {0x0003, 0x8801}, | 889 | {0x0003, 0x8801}, |
976 | /* 356 */ {0x0012, 0x8800}, | 890 | {0x0012, 0x8800}, |
977 | /* 358 */ {0x0004, 0x8801}, | 891 | {0x0004, 0x8801}, |
978 | /* 359 */ {0x0005, 0x8800}, | 892 | {0x0005, 0x8800}, |
979 | /* 361 */ {0x0005, 0x8801}, | 893 | {0x0005, 0x8801}, |
980 | /* 362 */ {0x0047, 0x8800}, | 894 | {0x0047, 0x8800}, |
981 | /* 364 */ {0x0006, 0x8801}, | 895 | {0x0006, 0x8801}, |
982 | /* 365 */ {0x0000, 0x8800}, | 896 | {0x0000, 0x8800}, |
983 | /* 367 */ {0x0007, 0x8801}, | 897 | {0x0007, 0x8801}, |
984 | /* 368 */ {0x00c0, 0x8800}, | 898 | {0x00c0, 0x8800}, |
985 | /* 370 */ {0x0008, 0x8801}, | 899 | {0x0008, 0x8801}, |
986 | /* 371 */ {0x0003, 0x8800}, | 900 | {0x0003, 0x8800}, |
987 | /* 373 */ {0x000a, 0x8700}, | 901 | {0x000a, 0x8700}, |
988 | /* 374 */ {0x000e, 0x8801}, | 902 | {0x000e, 0x8801}, |
989 | /* 375 */ {0x0004, 0x8800}, | 903 | {0x0004, 0x8800}, |
990 | /* 377 */ {0x0005, 0x8801}, | 904 | {0x0005, 0x8801}, |
991 | /* 378 */ {0x0047, 0x8800}, | 905 | {0x0047, 0x8800}, |
992 | /* 380 */ {0x0006, 0x8801}, | 906 | {0x0006, 0x8801}, |
993 | /* 381 */ {0x0000, 0x8800}, | 907 | {0x0000, 0x8800}, |
994 | /* 383 */ {0x0007, 0x8801}, | 908 | {0x0007, 0x8801}, |
995 | /* 384 */ {0x00c0, 0x8800}, | 909 | {0x00c0, 0x8800}, |
996 | /* 386 */ {0x0008, 0x8801}, | 910 | {0x0008, 0x8801}, |
997 | /* 387 */ {0x0003, 0x8800}, | 911 | {0x0003, 0x8800}, |
998 | /* 389 */ {0x0013, 0x8801}, | 912 | {0x0013, 0x8801}, |
999 | /* 390 */ {0x0001, 0x8800}, | 913 | {0x0001, 0x8800}, |
1000 | /* 392 */ {0x0009, 0x8801}, | 914 | {0x0009, 0x8801}, |
1001 | /* 393 */ {0x0000, 0x8800}, | 915 | {0x0000, 0x8800}, |
1002 | /* 395 */ {0x000a, 0x8801}, | 916 | {0x000a, 0x8801}, |
1003 | /* 396 */ {0x0000, 0x8800}, | 917 | {0x0000, 0x8800}, |
1004 | /* 398 */ {0x000b, 0x8801}, | 918 | {0x000b, 0x8801}, |
1005 | /* 399 */ {0x0000, 0x8800}, | 919 | {0x0000, 0x8800}, |
1006 | /* 401 */ {0x000c, 0x8801}, | 920 | {0x000c, 0x8801}, |
1007 | /* 402 */ {0x0000, 0x8800}, | 921 | {0x0000, 0x8800}, |
1008 | /* 404 */ {0x000e, 0x8801}, | 922 | {0x000e, 0x8801}, |
1009 | /* 405 */ {0x0004, 0x8800}, | 923 | {0x0004, 0x8800}, |
1010 | /* 407 */ {0x000f, 0x8801}, | 924 | {0x000f, 0x8801}, |
1011 | /* 408 */ {0x0000, 0x8800}, | 925 | {0x0000, 0x8800}, |
1012 | /* 410 */ {0x0010, 0x8801}, | 926 | {0x0010, 0x8801}, |
1013 | /* 411 */ {0x0006, 0x8800}, | 927 | {0x0006, 0x8800}, |
1014 | /* 413 */ {0x0011, 0x8801}, | 928 | {0x0011, 0x8801}, |
1015 | /* 414 */ {0x0006, 0x8800}, | 929 | {0x0006, 0x8800}, |
1016 | /* 416 */ {0x0012, 0x8801}, | 930 | {0x0012, 0x8801}, |
1017 | /* 417 */ {0x0000, 0x8800}, | 931 | {0x0000, 0x8800}, |
1018 | /* 419 */ {0x0013, 0x8801}, | 932 | {0x0013, 0x8801}, |
1019 | /* 420 */ {0x0001, 0x8800}, | 933 | {0x0001, 0x8800}, |
1020 | /* 422 */ {0x000a, 0x8700}, | 934 | {0x000a, 0x8700}, |
1021 | /* 423 */ {0x0000, 0x8702}, | 935 | {0x0000, 0x8702}, |
1022 | /* 424 */ {0x0000, 0x8703}, | 936 | {0x0000, 0x8703}, |
1023 | /* 425 */ {0x00c2, 0x8704}, | 937 | {0x00c2, 0x8704}, |
1024 | /* 426 */ {0x0001, 0x870c}, | 938 | {0x0001, 0x870c}, |
1025 | /* 427 */ {0x0044, 0x8600}, | 939 | {0x0044, 0x8600}, |
1026 | /* 428 */ {0x0002, 0x8606}, | 940 | {0x0002, 0x8606}, |
1027 | /* 429 */ {0x0064, 0x8607}, | 941 | {0x0064, 0x8607}, |
1028 | /* 430 */ {0x003a, 0x8601}, | 942 | {0x003a, 0x8601}, |
1029 | /* 431 */ {0x0008, 0x8602}, | 943 | {0x0008, 0x8602}, |
1030 | /* 432 */ {0x0044, 0x8600}, | 944 | {0x0044, 0x8600}, |
1031 | /* 433 */ {0x0018, 0x8617}, | 945 | {0x0018, 0x8617}, |
1032 | /* 434 */ {0x0008, 0x8618}, | 946 | {0x0008, 0x8618}, |
1033 | /* 435 */ {0x00a1, 0x8656}, | 947 | {0x00a1, 0x8656}, |
1034 | /* 436 */ {0x0004, 0x865b}, | 948 | {0x0004, 0x865b}, |
1035 | /* 437 */ {0x0002, 0x865c}, | 949 | {0x0002, 0x865c}, |
1036 | /* 438 */ {0x0058, 0x865d}, | 950 | {0x0058, 0x865d}, |
1037 | /* 439 */ {0x0048, 0x865e}, | 951 | {0x0048, 0x865e}, |
1038 | /* 440 */ {0x0012, 0x8608}, | 952 | {0x0012, 0x8608}, |
1039 | /* 441 */ {0x002c, 0x8609}, | 953 | {0x002c, 0x8609}, |
1040 | /* 442 */ {0x0002, 0x860a}, | 954 | {0x0002, 0x860a}, |
1041 | /* 443 */ {0x002c, 0x860b}, | 955 | {0x002c, 0x860b}, |
1042 | /* 444 */ {0x00db, 0x860c}, | 956 | {0x00db, 0x860c}, |
1043 | /* 445 */ {0x00f9, 0x860d}, | 957 | {0x00f9, 0x860d}, |
1044 | /* 446 */ {0x00f1, 0x860e}, | 958 | {0x00f1, 0x860e}, |
1045 | /* 447 */ {0x00e3, 0x860f}, | 959 | {0x00e3, 0x860f}, |
1046 | /* 448 */ {0x002c, 0x8610}, | 960 | {0x002c, 0x8610}, |
1047 | /* 449 */ {0x006c, 0x8651}, | 961 | {0x006c, 0x8651}, |
1048 | /* 450 */ {0x0041, 0x8652}, | 962 | {0x0041, 0x8652}, |
1049 | /* 451 */ {0x0059, 0x8653}, | 963 | {0x0059, 0x8653}, |
1050 | /* 452 */ {0x0040, 0x8654}, | 964 | {0x0040, 0x8654}, |
1051 | /* 453 */ {0x00fa, 0x8611}, | 965 | {0x00fa, 0x8611}, |
1052 | /* 454 */ {0x00ff, 0x8612}, | 966 | {0x00ff, 0x8612}, |
1053 | /* 455 */ {0x00f8, 0x8613}, | 967 | {0x00f8, 0x8613}, |
1054 | /* 456 */ {0x0000, 0x8614}, | 968 | {0x0000, 0x8614}, |
1055 | /* 457 */ {0x0001, 0x863f}, | 969 | {0x0001, 0x863f}, |
1056 | /* 458 */ {0x0000, 0x8640}, | 970 | {0x0000, 0x8640}, |
1057 | /* 459 */ {0x0026, 0x8641}, | 971 | {0x0026, 0x8641}, |
1058 | /* 460 */ {0x0045, 0x8642}, | 972 | {0x0045, 0x8642}, |
1059 | /* 461 */ {0x0060, 0x8643}, | 973 | {0x0060, 0x8643}, |
1060 | /* 462 */ {0x0075, 0x8644}, | 974 | {0x0075, 0x8644}, |
1061 | /* 463 */ {0x0088, 0x8645}, | 975 | {0x0088, 0x8645}, |
1062 | /* 464 */ {0x009b, 0x8646}, | 976 | {0x009b, 0x8646}, |
1063 | /* 465 */ {0x00b0, 0x8647}, | 977 | {0x00b0, 0x8647}, |
1064 | /* 466 */ {0x00c5, 0x8648}, | 978 | {0x00c5, 0x8648}, |
1065 | /* 467 */ {0x00d2, 0x8649}, | 979 | {0x00d2, 0x8649}, |
1066 | /* 468 */ {0x00dc, 0x864a}, | 980 | {0x00dc, 0x864a}, |
1067 | /* 469 */ {0x00e5, 0x864b}, | 981 | {0x00e5, 0x864b}, |
1068 | /* 470 */ {0x00eb, 0x864c}, | 982 | {0x00eb, 0x864c}, |
1069 | /* 471 */ {0x00f0, 0x864d}, | 983 | {0x00f0, 0x864d}, |
1070 | /* 472 */ {0x00f6, 0x864e}, | 984 | {0x00f6, 0x864e}, |
1071 | /* 473 */ {0x00fa, 0x864f}, | 985 | {0x00fa, 0x864f}, |
1072 | /* 474 */ {0x00ff, 0x8650}, | 986 | {0x00ff, 0x8650}, |
1073 | /* 475 */ {0x0060, 0x8657}, | 987 | {0x0060, 0x8657}, |
1074 | /* 476 */ {0x0010, 0x8658}, | 988 | {0x0010, 0x8658}, |
1075 | /* 477 */ {0x0018, 0x8659}, | 989 | {0x0018, 0x8659}, |
1076 | /* 478 */ {0x0005, 0x865a}, | 990 | {0x0005, 0x865a}, |
1077 | /* 479 */ {0x0018, 0x8660}, | 991 | {0x0018, 0x8660}, |
1078 | /* 480 */ {0x0003, 0x8509}, | 992 | {0x0003, 0x8509}, |
1079 | /* 481 */ {0x0011, 0x850a}, | 993 | {0x0011, 0x850a}, |
1080 | /* 482 */ {0x0032, 0x850b}, | 994 | {0x0032, 0x850b}, |
1081 | /* 483 */ {0x0010, 0x850c}, | 995 | {0x0010, 0x850c}, |
1082 | /* 484 */ {0x0021, 0x850d}, | 996 | {0x0021, 0x850d}, |
1083 | /* 485 */ {0x0001, 0x8500}, | 997 | {0x0001, 0x8500}, |
1084 | /* 486 */ {0x0000, 0x8508}, | 998 | {0x0000, 0x8508}, |
1085 | 999 | ||
1086 | /* 487 */ {0x0012, 0x8608}, | 1000 | {0x0012, 0x8608}, |
1087 | /* 488 */ {0x002c, 0x8609}, | 1001 | {0x002c, 0x8609}, |
1088 | /* 489 */ {0x0002, 0x860a}, | 1002 | {0x0002, 0x860a}, |
1089 | /* 490 */ {0x0039, 0x860b}, | 1003 | {0x0039, 0x860b}, |
1090 | /* 491 */ {0x00d0, 0x860c}, | 1004 | {0x00d0, 0x860c}, |
1091 | /* 492 */ {0x00f7, 0x860d}, | 1005 | {0x00f7, 0x860d}, |
1092 | /* 493 */ {0x00ed, 0x860e}, | 1006 | {0x00ed, 0x860e}, |
1093 | /* 494 */ {0x00db, 0x860f}, | 1007 | {0x00db, 0x860f}, |
1094 | /* 495 */ {0x0039, 0x8610}, | 1008 | {0x0039, 0x8610}, |
1095 | /* 496 */ {0x0012, 0x8657}, | 1009 | {0x0012, 0x8657}, |
1096 | /* 497 */ {0x0064, 0x8619}, | 1010 | {0x0064, 0x8619}, |
1097 | 1011 | ||
1098 | /* This line starts it all, it is not needed here */ | 1012 | /* This line starts it all, it is not needed here */ |
1099 | /* since it has been build into the driver */ | 1013 | /* since it has been build into the driver */ |
1100 | /* jfm: don't start now */ | 1014 | /* jfm: don't start now */ |
1101 | /* 590 * {0x0030, 0x8112}, */ | 1015 | /* {0x0030, 0x8112}, */ |
1102 | {} | 1016 | {} |
1103 | }; | 1017 | }; |
1104 | 1018 | ||
@@ -1109,14 +1023,14 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1109 | {0x0008, 0x8200}, /* Clear register */ | 1023 | {0x0008, 0x8200}, /* Clear register */ |
1110 | {0x0000, 0x870b}, /* Reset CTL3 */ | 1024 | {0x0000, 0x870b}, /* Reset CTL3 */ |
1111 | {0x0020, 0x8112}, /* Video Drop packet enable */ | 1025 | {0x0020, 0x8112}, /* Video Drop packet enable */ |
1112 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ | 1026 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ |
1113 | {0x0000, 0x8110}, /* Disable everything */ | 1027 | {0x0000, 0x8110}, /* Disable everything */ |
1114 | {0x0000, 0x8114}, /* Software GPIO output data */ | 1028 | {0x0000, 0x8114}, /* Software GPIO output data */ |
1115 | {0x0000, 0x8114}, | 1029 | {0x0000, 0x8114}, |
1116 | 1030 | ||
1117 | {0x0003, 0x8111}, | 1031 | {0x0003, 0x8111}, |
1118 | {0x0000, 0x8111}, | 1032 | {0x0000, 0x8111}, |
1119 | {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ | 1033 | {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ |
1120 | {0x0020, 0x8112}, | 1034 | {0x0020, 0x8112}, |
1121 | {0x0000, 0x8114}, | 1035 | {0x0000, 0x8114}, |
1122 | {0x0001, 0x8114}, | 1036 | {0x0001, 0x8114}, |
@@ -1129,191 +1043,143 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1129 | {0x00ba, 0x8804}, /* SSI Slave address */ | 1043 | {0x00ba, 0x8804}, /* SSI Slave address */ |
1130 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ | 1044 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ |
1131 | 1045 | ||
1132 | /* READ { 0, 0x0001, 0x8803 } -> | 1046 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1133 | 0000: 00 */ | 1047 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1134 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1135 | 0000: 10 */ | ||
1136 | {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ | 1048 | {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ |
1137 | {0x0020, 0x8801}, /* Register address for SSI read/write */ | 1049 | {0x0020, 0x8801}, /* Register address for SSI read/write */ |
1138 | {0x0044, 0x8805}, /* DATA2 */ | 1050 | {0x0044, 0x8805}, /* DATA2 */ |
1139 | {0x0004, 0x8800}, /* DATA1 -> write triggered */ | 1051 | {0x0004, 0x8800}, /* DATA1 -> write triggered */ |
1140 | /* READ { 0, 0x0001, 0x8803 } -> | 1052 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1141 | 0000: 00 */ | ||
1142 | 1053 | ||
1143 | /* READ { 0, 0x0001, 0x8803 } -> | 1054 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1144 | 0000: 00 */ | 1055 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1145 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1146 | 0000: 10 */ | ||
1147 | {0x0010, 0x8802}, | 1056 | {0x0010, 0x8802}, |
1148 | {0x0009, 0x8801}, | 1057 | {0x0009, 0x8801}, |
1149 | {0x0042, 0x8805}, | 1058 | {0x0042, 0x8805}, |
1150 | {0x0001, 0x8800}, | 1059 | {0x0001, 0x8800}, |
1151 | /* READ { 0, 0x0001, 0x8803 } -> | 1060 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1152 | 0000: 00 */ | ||
1153 | 1061 | ||
1154 | /* READ { 0, 0x0001, 0x8803 } -> | 1062 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1155 | 0000: 00 */ | 1063 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1156 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1157 | 0000: 10 */ | ||
1158 | {0x0010, 0x8802}, | 1064 | {0x0010, 0x8802}, |
1159 | {0x003c, 0x8801}, | 1065 | {0x003c, 0x8801}, |
1160 | {0x0001, 0x8805}, | 1066 | {0x0001, 0x8805}, |
1161 | {0x0000, 0x8800}, | 1067 | {0x0000, 0x8800}, |
1162 | /* READ { 0, 0x0001, 0x8803 } -> | 1068 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1163 | 0000: 00 */ | ||
1164 | 1069 | ||
1165 | /* READ { 0, 0x0001, 0x8803 } -> | 1070 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1166 | 0000: 00 */ | 1071 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1167 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1168 | 0000: 10 */ | ||
1169 | {0x0010, 0x8802}, | 1072 | {0x0010, 0x8802}, |
1170 | {0x0001, 0x8801}, | 1073 | {0x0001, 0x8801}, |
1171 | {0x000a, 0x8805}, | 1074 | {0x000a, 0x8805}, |
1172 | {0x0000, 0x8800}, | 1075 | {0x0000, 0x8800}, |
1173 | /* READ { 0, 0x0001, 0x8803 } -> | 1076 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1174 | 0000: 00 */ | ||
1175 | 1077 | ||
1176 | /* READ { 0, 0x0001, 0x8803 } -> | 1078 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1177 | 0000: 00 */ | 1079 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1178 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1179 | 0000: 10 */ | ||
1180 | {0x0010, 0x8802}, | 1080 | {0x0010, 0x8802}, |
1181 | {0x0002, 0x8801}, | 1081 | {0x0002, 0x8801}, |
1182 | {0x0000, 0x8805}, | 1082 | {0x0000, 0x8805}, |
1183 | {0x0000, 0x8800}, | 1083 | {0x0000, 0x8800}, |
1184 | /* READ { 0, 0x0001, 0x8803 } -> | 1084 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1185 | 0000: 00 */ | ||
1186 | 1085 | ||
1187 | /* READ { 0, 0x0001, 0x8803 } -> | 1086 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1188 | 0000: 00 */ | 1087 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1189 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1190 | 0000: 10 */ | ||
1191 | {0x0010, 0x8802}, | 1088 | {0x0010, 0x8802}, |
1192 | {0x0003, 0x8801}, | 1089 | {0x0003, 0x8801}, |
1193 | {0x0027, 0x8805}, | 1090 | {0x0027, 0x8805}, |
1194 | {0x0001, 0x8800}, | 1091 | {0x0001, 0x8800}, |
1195 | /* READ { 0, 0x0001, 0x8803 } -> | 1092 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1196 | 0000: 00 */ | ||
1197 | 1093 | ||
1198 | /* READ { 0, 0x0001, 0x8803 } -> | 1094 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1199 | 0000: 00 */ | 1095 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1200 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1201 | 0000: 10 */ | ||
1202 | {0x0010, 0x8802}, | 1096 | {0x0010, 0x8802}, |
1203 | {0x0004, 0x8801}, | 1097 | {0x0004, 0x8801}, |
1204 | {0x0065, 0x8805}, | 1098 | {0x0065, 0x8805}, |
1205 | {0x0001, 0x8800}, | 1099 | {0x0001, 0x8800}, |
1206 | /* READ { 0, 0x0001, 0x8803 } -> | 1100 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1207 | 0000: 00 */ | ||
1208 | 1101 | ||
1209 | /* READ { 0, 0x0001, 0x8803 } -> | 1102 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1210 | 0000: 00 */ | 1103 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1211 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1212 | 0000: 10 */ | ||
1213 | {0x0010, 0x8802}, | 1104 | {0x0010, 0x8802}, |
1214 | {0x0005, 0x8801}, | 1105 | {0x0005, 0x8801}, |
1215 | {0x0003, 0x8805}, | 1106 | {0x0003, 0x8805}, |
1216 | {0x0000, 0x8800}, | 1107 | {0x0000, 0x8800}, |
1217 | /* READ { 0, 0x0001, 0x8803 } -> | 1108 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1218 | 0000: 00 */ | ||
1219 | 1109 | ||
1220 | /* READ { 0, 0x0001, 0x8803 } -> | 1110 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1221 | 0000: 00 */ | 1111 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1222 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1223 | 0000: 10 */ | ||
1224 | {0x0010, 0x8802}, | 1112 | {0x0010, 0x8802}, |
1225 | {0x0006, 0x8801}, | 1113 | {0x0006, 0x8801}, |
1226 | {0x001c, 0x8805}, | 1114 | {0x001c, 0x8805}, |
1227 | {0x0000, 0x8800}, | 1115 | {0x0000, 0x8800}, |
1228 | /* READ { 0, 0x0001, 0x8803 } -> | 1116 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1229 | 0000: 00 */ | ||
1230 | 1117 | ||
1231 | /* READ { 0, 0x0001, 0x8803 } -> | 1118 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1232 | 0000: 00 */ | 1119 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1233 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1234 | 0000: 10 */ | ||
1235 | {0x0010, 0x8802}, | 1120 | {0x0010, 0x8802}, |
1236 | {0x0007, 0x8801}, | 1121 | {0x0007, 0x8801}, |
1237 | {0x002a, 0x8805}, | 1122 | {0x002a, 0x8805}, |
1238 | {0x0000, 0x8800}, | 1123 | {0x0000, 0x8800}, |
1239 | /* READ { 0, 0x0001, 0x8803 } -> | 1124 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1240 | 0000: 00 */ | ||
1241 | 1125 | ||
1242 | /* READ { 0, 0x0001, 0x8803 } -> | 1126 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1243 | 0000: 00 */ | 1127 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1244 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1245 | 0000: 10 */ | ||
1246 | {0x0010, 0x8802}, | 1128 | {0x0010, 0x8802}, |
1247 | {0x000e, 0x8801}, | 1129 | {0x000e, 0x8801}, |
1248 | {0x0000, 0x8805}, | 1130 | {0x0000, 0x8805}, |
1249 | {0x0000, 0x8800}, | 1131 | {0x0000, 0x8800}, |
1250 | /* READ { 0, 0x0001, 0x8803 } -> | 1132 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1251 | 0000: 00 */ | ||
1252 | 1133 | ||
1253 | /* READ { 0, 0x0001, 0x8803 } -> | 1134 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1254 | 0000: 00 */ | 1135 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1255 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1256 | 0000: 10 */ | ||
1257 | {0x0010, 0x8802}, | 1136 | {0x0010, 0x8802}, |
1258 | {0x0028, 0x8801}, | 1137 | {0x0028, 0x8801}, |
1259 | {0x002e, 0x8805}, | 1138 | {0x002e, 0x8805}, |
1260 | {0x0000, 0x8800}, | 1139 | {0x0000, 0x8800}, |
1261 | /* READ { 0, 0x0001, 0x8803 } -> | 1140 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1262 | 0000: 00 */ | ||
1263 | 1141 | ||
1264 | /* READ { 0, 0x0001, 0x8803 } -> | 1142 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1265 | 0000: 00 */ | 1143 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1266 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1267 | 0000: 10 */ | ||
1268 | {0x0010, 0x8802}, | 1144 | {0x0010, 0x8802}, |
1269 | {0x0039, 0x8801}, | 1145 | {0x0039, 0x8801}, |
1270 | {0x0013, 0x8805}, | 1146 | {0x0013, 0x8805}, |
1271 | {0x0000, 0x8800}, | 1147 | {0x0000, 0x8800}, |
1272 | /* READ { 0, 0x0001, 0x8803 } -> | 1148 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1273 | 0000: 00 */ | ||
1274 | 1149 | ||
1275 | /* READ { 0, 0x0001, 0x8803 } -> | 1150 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1276 | 0000: 00 */ | 1151 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1277 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1278 | 0000: 10 */ | ||
1279 | {0x0010, 0x8802}, | 1152 | {0x0010, 0x8802}, |
1280 | {0x003b, 0x8801}, | 1153 | {0x003b, 0x8801}, |
1281 | {0x000c, 0x8805}, | 1154 | {0x000c, 0x8805}, |
1282 | {0x0000, 0x8800}, | 1155 | {0x0000, 0x8800}, |
1283 | /* READ { 0, 0x0001, 0x8803 } -> | 1156 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1284 | 0000: 00 */ | ||
1285 | 1157 | ||
1286 | /* READ { 0, 0x0001, 0x8803 } -> | 1158 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1287 | 0000: 00 */ | 1159 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1288 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1289 | 0000: 10 */ | ||
1290 | {0x0010, 0x8802}, | 1160 | {0x0010, 0x8802}, |
1291 | {0x0035, 0x8801}, | 1161 | {0x0035, 0x8801}, |
1292 | {0x0028, 0x8805}, | 1162 | {0x0028, 0x8805}, |
1293 | {0x0000, 0x8800}, | 1163 | {0x0000, 0x8800}, |
1294 | /* READ { 0, 0x0001, 0x8803 } -> | 1164 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1295 | 0000: 00 */ | ||
1296 | 1165 | ||
1297 | /* READ { 0, 0x0001, 0x8803 } -> | 1166 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1298 | 0000: 00 */ | 1167 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1299 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1300 | 0000: 10 */ | ||
1301 | {0x0010, 0x8802}, | 1168 | {0x0010, 0x8802}, |
1302 | {0x0009, 0x8801}, | 1169 | {0x0009, 0x8801}, |
1303 | {0x0042, 0x8805}, | 1170 | {0x0042, 0x8805}, |
1304 | {0x0001, 0x8800}, | 1171 | {0x0001, 0x8800}, |
1305 | /* READ { 0, 0x0001, 0x8803 } -> | 1172 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1306 | 0000: 00 */ | ||
1307 | 1173 | ||
1308 | {0x0050, 0x8703}, | 1174 | {0x0050, 0x8703}, |
1309 | {0x0002, 0x8704}, /* External input CKIx1 */ | 1175 | {0x0002, 0x8704}, /* External input CKIx1 */ |
1310 | {0x0001, 0x870c}, /* Select CKOx2 output */ | 1176 | {0x0001, 0x870c}, /* Select CKOx2 output */ |
1311 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ | 1177 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ |
1312 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ | 1178 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ |
1313 | {0x0023, 0x8601}, | 1179 | {0x0023, 0x8601}, |
1314 | {0x0010, 0x8602}, | 1180 | {0x0010, 0x8602}, |
1315 | {0x000a, 0x8603}, | 1181 | {0x000a, 0x8603}, |
1316 | {0x009A, 0x8600}, | 1182 | {0x009a, 0x8600}, |
1317 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ | 1183 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ |
1318 | {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */ | 1184 | {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */ |
1319 | {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */ | 1185 | {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */ |
@@ -1329,7 +1195,7 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1329 | {0x0005, 0x860a}, /* ... */ | 1195 | {0x0005, 0x860a}, /* ... */ |
1330 | {0x0025, 0x860b}, | 1196 | {0x0025, 0x860b}, |
1331 | {0x00e1, 0x860c}, | 1197 | {0x00e1, 0x860c}, |
1332 | {0x00fa, 0x860D}, | 1198 | {0x00fa, 0x860d}, |
1333 | {0x00f4, 0x860e}, | 1199 | {0x00f4, 0x860e}, |
1334 | {0x00e8, 0x860f}, | 1200 | {0x00e8, 0x860f}, |
1335 | {0x0025, 0x8610}, /* A33 Coef. */ | 1201 | {0x0025, 0x8610}, /* A33 Coef. */ |
@@ -1344,11 +1210,12 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1344 | {0x0040, 0x8654}, /* Gb gain for white balance (L) */ | 1210 | {0x0040, 0x8654}, /* Gb gain for white balance (L) */ |
1345 | {0x0001, 0x863f}, /* Enable fixed gamma correction */ | 1211 | {0x0001, 0x863f}, /* Enable fixed gamma correction */ |
1346 | 1212 | ||
1347 | {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ | 1213 | {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128, |
1348 | /* UV division: UV no change, Enable New edge enhancement */ | 1214 | * UV division: UV no change, |
1215 | * Enable New edge enhancement */ | ||
1349 | {0x0018, 0x8657}, /* Edge gain high threshold */ | 1216 | {0x0018, 0x8657}, /* Edge gain high threshold */ |
1350 | {0x0020, 0x8658}, /* Edge gain low threshold */ | 1217 | {0x0020, 0x8658}, /* Edge gain low threshold */ |
1351 | {0x000A, 0x8659}, /* Edge bandwidth high threshold */ | 1218 | {0x000a, 0x8659}, /* Edge bandwidth high threshold */ |
1352 | {0x0005, 0x865a}, /* Edge bandwidth low threshold */ | 1219 | {0x0005, 0x865a}, /* Edge bandwidth low threshold */ |
1353 | {0x0064, 0x8607}, /* UV filter enable */ | 1220 | {0x0064, 0x8607}, /* UV filter enable */ |
1354 | 1221 | ||
@@ -1384,29 +1251,20 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1384 | {0x0000, 0x86b4}, | 1251 | {0x0000, 0x86b4}, |
1385 | {0x001e, 0x8660}, | 1252 | {0x001e, 0x8660}, |
1386 | 1253 | ||
1387 | /* READ { 0, 0x0000, 0x8608 } -> | 1254 | /* READ { 0x0000, 0x8608 } -> 0000: 13 */ |
1388 | 0000: 13 */ | 1255 | /* READ { 0x0000, 0x8609 } -> 0000: 28 */ |
1389 | /* READ { 0, 0x0000, 0x8609 } -> | 1256 | /* READ { 0x0000, 0x8610 } -> 0000: 05 */ |
1390 | 0000: 28 */ | 1257 | /* READ { 0x0000, 0x8611 } -> 0000: 25 */ |
1391 | /* READ { 0, 0x0000, 0x8610 } -> | 1258 | /* READ { 0x0000, 0x8612 } -> 0000: e1 */ |
1392 | 0000: 05 */ | 1259 | /* READ { 0x0000, 0x8613 } -> 0000: fa */ |
1393 | /* READ { 0, 0x0000, 0x8611 } -> | 1260 | /* READ { 0x0000, 0x8614 } -> 0000: f4 */ |
1394 | 0000: 25 */ | 1261 | /* READ { 0x0000, 0x8615 } -> 0000: e8 */ |
1395 | /* READ { 0, 0x0000, 0x8612 } -> | 1262 | /* READ { 0x0000, 0x8616 } -> 0000: 25 */ |
1396 | 0000: e1 */ | ||
1397 | /* READ { 0, 0x0000, 0x8613 } -> | ||
1398 | 0000: fa */ | ||
1399 | /* READ { 0, 0x0000, 0x8614 } -> | ||
1400 | 0000: f4 */ | ||
1401 | /* READ { 0, 0x0000, 0x8615 } -> | ||
1402 | 0000: e8 */ | ||
1403 | /* READ { 0, 0x0000, 0x8616 } -> | ||
1404 | 0000: 25 */ | ||
1405 | {} | 1263 | {} |
1406 | }; | 1264 | }; |
1407 | 1265 | ||
1408 | static int reg_write(struct usb_device *dev, | 1266 | static int reg_write(struct usb_device *dev, |
1409 | __u16 index, __u16 value) | 1267 | u16 index, u16 value) |
1410 | { | 1268 | { |
1411 | int ret; | 1269 | int ret; |
1412 | 1270 | ||
@@ -1425,7 +1283,7 @@ static int reg_write(struct usb_device *dev, | |||
1425 | /* read 1 byte */ | 1283 | /* read 1 byte */ |
1426 | /* returns: negative is error, pos or zero is data */ | 1284 | /* returns: negative is error, pos or zero is data */ |
1427 | static int reg_read(struct gspca_dev *gspca_dev, | 1285 | static int reg_read(struct gspca_dev *gspca_dev, |
1428 | __u16 index) /* wIndex */ | 1286 | u16 index) /* wIndex */ |
1429 | { | 1287 | { |
1430 | int ret; | 1288 | int ret; |
1431 | 1289 | ||
@@ -1447,16 +1305,16 @@ static int reg_read(struct gspca_dev *gspca_dev, | |||
1447 | } | 1305 | } |
1448 | 1306 | ||
1449 | static int write_vector(struct gspca_dev *gspca_dev, | 1307 | static int write_vector(struct gspca_dev *gspca_dev, |
1450 | const u16 data[][2]) | 1308 | const u16 (*data)[2]) |
1451 | { | 1309 | { |
1452 | struct usb_device *dev = gspca_dev->dev; | 1310 | struct usb_device *dev = gspca_dev->dev; |
1453 | int ret, i = 0; | 1311 | int ret; |
1454 | 1312 | ||
1455 | while (data[i][1] != 0) { | 1313 | while ((*data)[1] != 0) { |
1456 | ret = reg_write(dev, data[i][1], data[i][0]); | 1314 | ret = reg_write(dev, (*data)[1], (*data)[0]); |
1457 | if (ret < 0) | 1315 | if (ret < 0) |
1458 | return ret; | 1316 | return ret; |
1459 | i++; | 1317 | data++; |
1460 | } | 1318 | } |
1461 | return 0; | 1319 | return 0; |
1462 | } | 1320 | } |
@@ -1468,6 +1326,15 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1468 | struct sd *sd = (struct sd *) gspca_dev; | 1326 | struct sd *sd = (struct sd *) gspca_dev; |
1469 | struct cam *cam; | 1327 | struct cam *cam; |
1470 | int data1, data2; | 1328 | int data1, data2; |
1329 | const u16 (*init_data)[2]; | ||
1330 | static const u16 (*(init_data_tb[]))[2] = { | ||
1331 | spca508_vista_init_data, /* CreativeVista 0 */ | ||
1332 | spca508_sightcam_init_data, /* HamaUSBSightcam 1 */ | ||
1333 | spca508_sightcam2_init_data, /* HamaUSBSightcam2 2 */ | ||
1334 | spca508cs110_init_data, /* IntelEasyPCCamera 3 */ | ||
1335 | spca508cs110_init_data, /* MicroInnovationIC200 4 */ | ||
1336 | spca508_init_data, /* ViewQuestVQ110 5 */ | ||
1337 | }; | ||
1471 | 1338 | ||
1472 | /* Read from global register the USB product and vendor IDs, just to | 1339 | /* Read from global register the USB product and vendor IDs, just to |
1473 | * prove that we can communicate with the device. This works, which | 1340 | * prove that we can communicate with the device. This works, which |
@@ -1491,37 +1358,13 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1491 | sd->subtype = id->driver_info; | 1358 | sd->subtype = id->driver_info; |
1492 | sd->brightness = BRIGHTNESS_DEF; | 1359 | sd->brightness = BRIGHTNESS_DEF; |
1493 | 1360 | ||
1494 | switch (sd->subtype) { | 1361 | init_data = init_data_tb[sd->subtype]; |
1495 | case ViewQuestVQ110: | 1362 | return write_vector(gspca_dev, init_data); |
1496 | if (write_vector(gspca_dev, spca508_init_data)) | ||
1497 | return -1; | ||
1498 | break; | ||
1499 | default: | ||
1500 | /* case MicroInnovationIC200: */ | ||
1501 | /* case IntelEasyPCCamera: */ | ||
1502 | if (write_vector(gspca_dev, spca508cs110_init_data)) | ||
1503 | return -1; | ||
1504 | break; | ||
1505 | case HamaUSBSightcam: | ||
1506 | if (write_vector(gspca_dev, spca508_sightcam_init_data)) | ||
1507 | return -1; | ||
1508 | break; | ||
1509 | case HamaUSBSightcam2: | ||
1510 | if (write_vector(gspca_dev, spca508_sightcam2_init_data)) | ||
1511 | return -1; | ||
1512 | break; | ||
1513 | case CreativeVista: | ||
1514 | if (write_vector(gspca_dev, spca508_vista_init_data)) | ||
1515 | return -1; | ||
1516 | break; | ||
1517 | } | ||
1518 | return 0; /* success */ | ||
1519 | } | 1363 | } |
1520 | 1364 | ||
1521 | /* this function is called at probe and resume time */ | 1365 | /* this function is called at probe and resume time */ |
1522 | static int sd_init(struct gspca_dev *gspca_dev) | 1366 | static int sd_init(struct gspca_dev *gspca_dev) |
1523 | { | 1367 | { |
1524 | /* write_vector(gspca_dev, spca508_open_data); */ | ||
1525 | return 0; | 1368 | return 0; |
1526 | } | 1369 | } |
1527 | 1370 | ||
@@ -1529,7 +1372,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1529 | { | 1372 | { |
1530 | int mode; | 1373 | int mode; |
1531 | 1374 | ||
1532 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | 1375 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
1533 | reg_write(gspca_dev->dev, 0x8500, mode); | 1376 | reg_write(gspca_dev->dev, 0x8500, mode); |
1534 | switch (mode) { | 1377 | switch (mode) { |
1535 | case 0: | 1378 | case 0: |
@@ -1554,7 +1397,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1554 | 1397 | ||
1555 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1398 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
1556 | struct gspca_frame *frame, /* target */ | 1399 | struct gspca_frame *frame, /* target */ |
1557 | __u8 *data, /* isoc packet */ | 1400 | u8 *data, /* isoc packet */ |
1558 | int len) /* iso packet length */ | 1401 | int len) /* iso packet length */ |
1559 | { | 1402 | { |
1560 | switch (data[0]) { | 1403 | switch (data[0]) { |
@@ -1567,7 +1410,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1567 | data, len); | 1410 | data, len); |
1568 | break; | 1411 | break; |
1569 | case 0xff: /* drop */ | 1412 | case 0xff: /* drop */ |
1570 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1571 | break; | 1413 | break; |
1572 | default: | 1414 | default: |
1573 | data += 1; | 1415 | data += 1; |
@@ -1581,7 +1423,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1581 | static void setbrightness(struct gspca_dev *gspca_dev) | 1423 | static void setbrightness(struct gspca_dev *gspca_dev) |
1582 | { | 1424 | { |
1583 | struct sd *sd = (struct sd *) gspca_dev; | 1425 | struct sd *sd = (struct sd *) gspca_dev; |
1584 | __u8 brightness = sd->brightness; | 1426 | u8 brightness = sd->brightness; |
1585 | 1427 | ||
1586 | /* MX seem contrast */ | 1428 | /* MX seem contrast */ |
1587 | reg_write(gspca_dev->dev, 0x8651, brightness); | 1429 | reg_write(gspca_dev->dev, 0x8651, brightness); |
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index c99c5e34e211..27e82b35f3e7 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -34,8 +34,8 @@ struct sd { | |||
34 | 34 | ||
35 | __u16 exposure; /* rev12a only */ | 35 | __u16 exposure; /* rev12a only */ |
36 | #define EXPOSURE_MIN 1 | 36 | #define EXPOSURE_MIN 1 |
37 | #define EXPOSURE_DEF 200 | 37 | #define EXPOSURE_DEF 700 /* == 10 fps */ |
38 | #define EXPOSURE_MAX (4095 - 900) /* see set_exposure */ | 38 | #define EXPOSURE_MAX (2047 + 325) /* see setexposure */ |
39 | 39 | ||
40 | __u8 contrast; /* rev72a only */ | 40 | __u8 contrast; /* rev72a only */ |
41 | #define CONTRAST_MIN 0x00 | 41 | #define CONTRAST_MIN 0x00 |
@@ -48,9 +48,9 @@ struct sd { | |||
48 | #define BRIGHTNESS_MAX 0x3f | 48 | #define BRIGHTNESS_MAX 0x3f |
49 | 49 | ||
50 | __u8 white; | 50 | __u8 white; |
51 | #define WHITE_MIN 1 | 51 | #define HUE_MIN 1 |
52 | #define WHITE_DEF 0x40 | 52 | #define HUE_DEF 0x40 |
53 | #define WHITE_MAX 0x7f | 53 | #define HUE_MAX 0x7f |
54 | 54 | ||
55 | __u8 autogain; | 55 | __u8 autogain; |
56 | #define AUTOGAIN_MIN 0 | 56 | #define AUTOGAIN_MIN 0 |
@@ -58,9 +58,9 @@ struct sd { | |||
58 | #define AUTOGAIN_MAX 1 | 58 | #define AUTOGAIN_MAX 1 |
59 | 59 | ||
60 | __u8 gain; /* rev12a only */ | 60 | __u8 gain; /* rev12a only */ |
61 | #define GAIN_MIN 0x0 | 61 | #define GAIN_MIN 0 |
62 | #define GAIN_DEF 0x24 | 62 | #define GAIN_DEF 63 |
63 | #define GAIN_MAX 0x24 | 63 | #define GAIN_MAX 255 |
64 | 64 | ||
65 | #define EXPO12A_DEF 3 | 65 | #define EXPO12A_DEF 3 |
66 | __u8 expo12a; /* expo/gain? for rev 12a */ | 66 | __u8 expo12a; /* expo/gain? for rev 12a */ |
@@ -461,7 +461,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
461 | } | 461 | } |
462 | sd->brightness = BRIGHTNESS_DEF; | 462 | sd->brightness = BRIGHTNESS_DEF; |
463 | sd->contrast = CONTRAST_DEF; | 463 | sd->contrast = CONTRAST_DEF; |
464 | sd->white = WHITE_DEF; | 464 | sd->white = HUE_DEF; |
465 | sd->exposure = EXPOSURE_DEF; | 465 | sd->exposure = EXPOSURE_DEF; |
466 | sd->autogain = AUTOGAIN_DEF; | 466 | sd->autogain = AUTOGAIN_DEF; |
467 | sd->gain = GAIN_DEF; | 467 | sd->gain = GAIN_DEF; |
@@ -549,8 +549,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
549 | static void setexposure(struct gspca_dev *gspca_dev) | 549 | static void setexposure(struct gspca_dev *gspca_dev) |
550 | { | 550 | { |
551 | struct sd *sd = (struct sd *) gspca_dev; | 551 | struct sd *sd = (struct sd *) gspca_dev; |
552 | int expo; | 552 | int i, expo = 0; |
553 | int clock_divider; | ||
554 | 553 | ||
555 | /* Register 0x8309 controls exposure for the spca561, | 554 | /* Register 0x8309 controls exposure for the spca561, |
556 | the basic exposure setting goes from 1-2047, where 1 is completely | 555 | the basic exposure setting goes from 1-2047, where 1 is completely |
@@ -564,16 +563,22 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
564 | configure a divider for the base framerate which us used at the | 563 | configure a divider for the base framerate which us used at the |
565 | exposure setting of 1-300. These bits configure the base framerate | 564 | exposure setting of 1-300. These bits configure the base framerate |
566 | according to the following formula: fps = 60 / (value + 2) */ | 565 | according to the following formula: fps = 60 / (value + 2) */ |
567 | if (sd->exposure < 2048) { | 566 | |
568 | expo = sd->exposure; | 567 | /* We choose to use the high bits setting the fixed framerate divisor |
569 | clock_divider = 0; | 568 | asap, as setting high basic exposure setting without the fixed |
570 | } else { | 569 | divider in combination with high gains makes the cam stop */ |
571 | /* Add 900 to make the 0 setting of the second part of the | 570 | int table[] = { 0, 450, 550, 625, EXPOSURE_MAX }; |
572 | exposure equal to the 2047 setting of the first part. */ | 571 | |
573 | expo = (sd->exposure - 2048) + 900; | 572 | for (i = 0; i < ARRAY_SIZE(table) - 1; i++) { |
574 | clock_divider = 3; | 573 | if (sd->exposure <= table[i + 1]) { |
574 | expo = sd->exposure - table[i]; | ||
575 | if (i) | ||
576 | expo += 300; | ||
577 | expo |= i << 11; | ||
578 | break; | ||
579 | } | ||
575 | } | 580 | } |
576 | expo |= clock_divider << 11; | 581 | |
577 | gspca_dev->usb_buf[0] = expo; | 582 | gspca_dev->usb_buf[0] = expo; |
578 | gspca_dev->usb_buf[1] = expo >> 8; | 583 | gspca_dev->usb_buf[1] = expo >> 8; |
579 | reg_w_buf(gspca_dev, 0x8309, 2); | 584 | reg_w_buf(gspca_dev, 0x8309, 2); |
@@ -584,7 +589,16 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
584 | { | 589 | { |
585 | struct sd *sd = (struct sd *) gspca_dev; | 590 | struct sd *sd = (struct sd *) gspca_dev; |
586 | 591 | ||
587 | gspca_dev->usb_buf[0] = sd->gain; | 592 | /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the |
593 | sensitivity when set, so 31 + one of them set == 63, and 15 | ||
594 | with both of them set == 63 */ | ||
595 | if (sd->gain < 64) | ||
596 | gspca_dev->usb_buf[0] = sd->gain; | ||
597 | else if (sd->gain < 128) | ||
598 | gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40; | ||
599 | else | ||
600 | gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0; | ||
601 | |||
588 | gspca_dev->usb_buf[1] = 0; | 602 | gspca_dev->usb_buf[1] = 0; |
589 | reg_w_buf(gspca_dev, 0x8335, 2); | 603 | reg_w_buf(gspca_dev, 0x8335, 2); |
590 | } | 604 | } |
@@ -629,8 +643,7 @@ static int sd_start_12a(struct gspca_dev *gspca_dev) | |||
629 | reg_w_buf(gspca_dev, 0x8391, 8); | 643 | reg_w_buf(gspca_dev, 0x8391, 8); |
630 | reg_w_buf(gspca_dev, 0x8390, 8); | 644 | reg_w_buf(gspca_dev, 0x8390, 8); |
631 | setwhite(gspca_dev); | 645 | setwhite(gspca_dev); |
632 | setautogain(gspca_dev); | 646 | setgain(gspca_dev); |
633 | /* setgain(gspca_dev); */ | ||
634 | setexposure(gspca_dev); | 647 | setexposure(gspca_dev); |
635 | return 0; | 648 | return 0; |
636 | } | 649 | } |
@@ -762,18 +775,6 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
762 | i2c_write(gspca_dev, expotimes | pixelclk, 0x09); | 775 | i2c_write(gspca_dev, expotimes | pixelclk, 0x09); |
763 | } | 776 | } |
764 | break; | 777 | break; |
765 | case Rev012A: | ||
766 | reg_r(gspca_dev, 0x8330, 2); | ||
767 | if (gspca_dev->usb_buf[1] > 0x08) { | ||
768 | gspca_dev->usb_buf[0] = ++sd->expo12a; | ||
769 | gspca_dev->usb_buf[1] = 0; | ||
770 | reg_w_buf(gspca_dev, 0x8339, 2); | ||
771 | } else if (gspca_dev->usb_buf[1] < 0x02) { | ||
772 | gspca_dev->usb_buf[0] = --sd->expo12a; | ||
773 | gspca_dev->usb_buf[1] = 0; | ||
774 | reg_w_buf(gspca_dev, 0x8339, 2); | ||
775 | } | ||
776 | break; | ||
777 | } | 778 | } |
778 | } | 779 | } |
779 | 780 | ||
@@ -928,13 +929,13 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | |||
928 | static struct ctrl sd_ctrls_12a[] = { | 929 | static struct ctrl sd_ctrls_12a[] = { |
929 | { | 930 | { |
930 | { | 931 | { |
931 | .id = V4L2_CID_DO_WHITE_BALANCE, | 932 | .id = V4L2_CID_HUE, |
932 | .type = V4L2_CTRL_TYPE_INTEGER, | 933 | .type = V4L2_CTRL_TYPE_INTEGER, |
933 | .name = "White Balance", | 934 | .name = "Hue", |
934 | .minimum = WHITE_MIN, | 935 | .minimum = HUE_MIN, |
935 | .maximum = WHITE_MAX, | 936 | .maximum = HUE_MAX, |
936 | .step = 1, | 937 | .step = 1, |
937 | .default_value = WHITE_DEF, | 938 | .default_value = HUE_DEF, |
938 | }, | 939 | }, |
939 | .set = sd_setwhite, | 940 | .set = sd_setwhite, |
940 | .get = sd_getwhite, | 941 | .get = sd_getwhite, |
@@ -954,19 +955,6 @@ static struct ctrl sd_ctrls_12a[] = { | |||
954 | }, | 955 | }, |
955 | { | 956 | { |
956 | { | 957 | { |
957 | .id = V4L2_CID_AUTOGAIN, | ||
958 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
959 | .name = "Auto Gain", | ||
960 | .minimum = AUTOGAIN_MIN, | ||
961 | .maximum = AUTOGAIN_MAX, | ||
962 | .step = 1, | ||
963 | .default_value = AUTOGAIN_DEF, | ||
964 | }, | ||
965 | .set = sd_setautogain, | ||
966 | .get = sd_getautogain, | ||
967 | }, | ||
968 | { | ||
969 | { | ||
970 | .id = V4L2_CID_GAIN, | 958 | .id = V4L2_CID_GAIN, |
971 | .type = V4L2_CTRL_TYPE_INTEGER, | 959 | .type = V4L2_CTRL_TYPE_INTEGER, |
972 | .name = "Gain", | 960 | .name = "Gain", |
@@ -983,13 +971,13 @@ static struct ctrl sd_ctrls_12a[] = { | |||
983 | static struct ctrl sd_ctrls_72a[] = { | 971 | static struct ctrl sd_ctrls_72a[] = { |
984 | { | 972 | { |
985 | { | 973 | { |
986 | .id = V4L2_CID_DO_WHITE_BALANCE, | 974 | .id = V4L2_CID_HUE, |
987 | .type = V4L2_CTRL_TYPE_INTEGER, | 975 | .type = V4L2_CTRL_TYPE_INTEGER, |
988 | .name = "White Balance", | 976 | .name = "Hue", |
989 | .minimum = WHITE_MIN, | 977 | .minimum = HUE_MIN, |
990 | .maximum = WHITE_MAX, | 978 | .maximum = HUE_MAX, |
991 | .step = 1, | 979 | .step = 1, |
992 | .default_value = WHITE_DEF, | 980 | .default_value = HUE_DEF, |
993 | }, | 981 | }, |
994 | .set = sd_setwhite, | 982 | .set = sd_setwhite, |
995 | .get = sd_getwhite, | 983 | .get = sd_getwhite, |
@@ -1046,7 +1034,6 @@ static const struct sd_desc sd_desc_12a = { | |||
1046 | .stopN = sd_stopN, | 1034 | .stopN = sd_stopN, |
1047 | .stop0 = sd_stop0, | 1035 | .stop0 = sd_stop0, |
1048 | .pkt_scan = sd_pkt_scan, | 1036 | .pkt_scan = sd_pkt_scan, |
1049 | /* .dq_callback = do_autogain, * fixme */ | ||
1050 | }; | 1037 | }; |
1051 | static const struct sd_desc sd_desc_72a = { | 1038 | static const struct sd_desc sd_desc_72a = { |
1052 | .name = MODULE_NAME, | 1039 | .name = MODULE_NAME, |
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c index 2e1cdf068fda..715a68f0156e 100644 --- a/drivers/media/video/gspca/sq905.c +++ b/drivers/media/video/gspca/sq905.c | |||
@@ -309,6 +309,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
309 | struct sd *dev = (struct sd *) gspca_dev; | 309 | struct sd *dev = (struct sd *) gspca_dev; |
310 | 310 | ||
311 | /* We don't use the buffer gspca allocates so make it small. */ | 311 | /* We don't use the buffer gspca allocates so make it small. */ |
312 | cam->bulk = 1; | ||
312 | cam->bulk_size = 64; | 313 | cam->bulk_size = 64; |
313 | 314 | ||
314 | INIT_WORK(&dev->work_struct, sq905_dostream); | 315 | INIT_WORK(&dev->work_struct, sq905_dostream); |
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index 0bcb74a1b143..916892505432 100644 --- a/drivers/media/video/gspca/sq905c.c +++ b/drivers/media/video/gspca/sq905c.c | |||
@@ -206,6 +206,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
206 | cam->nmodes = 1; | 206 | cam->nmodes = 1; |
207 | /* We don't use the buffer gspca allocates so make it small. */ | 207 | /* We don't use the buffer gspca allocates so make it small. */ |
208 | cam->bulk_size = 32; | 208 | cam->bulk_size = 32; |
209 | cam->bulk = 1; | ||
209 | INIT_WORK(&dev->work_struct, sq905c_dostream); | 210 | INIT_WORK(&dev->work_struct, sq905c_dostream); |
210 | return 0; | 211 | return 0; |
211 | } | 212 | } |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c index 9dff2e65b116..e573c3406324 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx.c | |||
@@ -293,8 +293,6 @@ static void stv06xx_stopN(struct gspca_dev *gspca_dev) | |||
293 | goto out; | 293 | goto out; |
294 | 294 | ||
295 | err = sd->sensor->stop(sd); | 295 | err = sd->sensor->stop(sd); |
296 | if (err < 0) | ||
297 | goto out; | ||
298 | 296 | ||
299 | out: | 297 | out: |
300 | if (err < 0) | 298 | if (err < 0) |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c index 69c77c932fc0..11a0c002f5dc 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c | |||
@@ -80,12 +80,26 @@ static const struct ctrl vv6410_ctrl[] = { | |||
80 | .minimum = 0, | 80 | .minimum = 0, |
81 | .maximum = 15, | 81 | .maximum = 15, |
82 | .step = 1, | 82 | .step = 1, |
83 | .default_value = 0 | 83 | .default_value = 10 |
84 | }, | 84 | }, |
85 | .set = vv6410_set_analog_gain, | 85 | .set = vv6410_set_analog_gain, |
86 | .get = vv6410_get_analog_gain | 86 | .get = vv6410_get_analog_gain |
87 | }, | ||
88 | #define EXPOSURE_IDX 3 | ||
89 | { | ||
90 | { | ||
91 | .id = V4L2_CID_EXPOSURE, | ||
92 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
93 | .name = "exposure", | ||
94 | .minimum = 0, | ||
95 | .maximum = 32768, | ||
96 | .step = 1, | ||
97 | .default_value = 20000 | ||
98 | }, | ||
99 | .set = vv6410_set_exposure, | ||
100 | .get = vv6410_get_exposure | ||
87 | } | 101 | } |
88 | }; | 102 | }; |
89 | 103 | ||
90 | static int vv6410_probe(struct sd *sd) | 104 | static int vv6410_probe(struct sd *sd) |
91 | { | 105 | { |
@@ -121,6 +135,7 @@ static int vv6410_probe(struct sd *sd) | |||
121 | static int vv6410_init(struct sd *sd) | 135 | static int vv6410_init(struct sd *sd) |
122 | { | 136 | { |
123 | int err = 0, i; | 137 | int err = 0, i; |
138 | s32 *sensor_settings = sd->sensor_priv; | ||
124 | 139 | ||
125 | for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) { | 140 | for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) { |
126 | /* if NULL then len contains single value */ | 141 | /* if NULL then len contains single value */ |
@@ -142,6 +157,16 @@ static int vv6410_init(struct sd *sd) | |||
142 | 157 | ||
143 | err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, | 158 | err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, |
144 | ARRAY_SIZE(vv6410_sensor_init)); | 159 | ARRAY_SIZE(vv6410_sensor_init)); |
160 | if (err < 0) | ||
161 | return err; | ||
162 | |||
163 | err = vv6410_set_exposure(&sd->gspca_dev, | ||
164 | sensor_settings[EXPOSURE_IDX]); | ||
165 | if (err < 0) | ||
166 | return err; | ||
167 | |||
168 | err = vv6410_set_analog_gain(&sd->gspca_dev, | ||
169 | sensor_settings[GAIN_IDX]); | ||
145 | 170 | ||
146 | return (err < 0) ? err : 0; | 171 | return (err < 0) ? err : 0; |
147 | } | 172 | } |
@@ -318,3 +343,50 @@ static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
318 | 343 | ||
319 | return (err < 0) ? err : 0; | 344 | return (err < 0) ? err : 0; |
320 | } | 345 | } |
346 | |||
347 | static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | ||
348 | { | ||
349 | struct sd *sd = (struct sd *) gspca_dev; | ||
350 | s32 *sensor_settings = sd->sensor_priv; | ||
351 | |||
352 | *val = sensor_settings[EXPOSURE_IDX]; | ||
353 | |||
354 | PDEBUG(D_V4L2, "Read exposure %d", *val); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | ||
360 | { | ||
361 | int err; | ||
362 | struct sd *sd = (struct sd *) gspca_dev; | ||
363 | s32 *sensor_settings = sd->sensor_priv; | ||
364 | unsigned int fine, coarse; | ||
365 | |||
366 | sensor_settings[EXPOSURE_IDX] = val; | ||
367 | |||
368 | val = (val * val >> 14) + val / 4; | ||
369 | |||
370 | fine = val % VV6410_CIF_LINELENGTH; | ||
371 | coarse = min(512, val / VV6410_CIF_LINELENGTH); | ||
372 | |||
373 | PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d", | ||
374 | coarse, fine); | ||
375 | |||
376 | err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8); | ||
377 | if (err < 0) | ||
378 | goto out; | ||
379 | |||
380 | err = stv06xx_write_sensor(sd, VV6410_FINEL, fine & 0xff); | ||
381 | if (err < 0) | ||
382 | goto out; | ||
383 | |||
384 | err = stv06xx_write_sensor(sd, VV6410_COARSEH, coarse >> 8); | ||
385 | if (err < 0) | ||
386 | goto out; | ||
387 | |||
388 | err = stv06xx_write_sensor(sd, VV6410_COARSEL, coarse & 0xff); | ||
389 | |||
390 | out: | ||
391 | return err; | ||
392 | } | ||
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h index 95ac55891bd4..487d40555343 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h | |||
@@ -173,6 +173,8 @@ | |||
173 | #define VV6410_SUBSAMPLE 0x01 | 173 | #define VV6410_SUBSAMPLE 0x01 |
174 | #define VV6410_CROP_TO_QVGA 0x02 | 174 | #define VV6410_CROP_TO_QVGA 0x02 |
175 | 175 | ||
176 | #define VV6410_CIF_LINELENGTH 415 | ||
177 | |||
176 | static int vv6410_probe(struct sd *sd); | 178 | static int vv6410_probe(struct sd *sd); |
177 | static int vv6410_start(struct sd *sd); | 179 | static int vv6410_start(struct sd *sd); |
178 | static int vv6410_init(struct sd *sd); | 180 | static int vv6410_init(struct sd *sd); |
@@ -187,6 +189,8 @@ static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | |||
187 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | 189 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); |
188 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); | 190 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); |
189 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); | 191 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); |
192 | static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
193 | static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
190 | 194 | ||
191 | const struct stv06xx_sensor stv06xx_sensor_vv6410 = { | 195 | const struct stv06xx_sensor stv06xx_sensor_vv6410 = { |
192 | .name = "ST VV6410", | 196 | .name = "ST VV6410", |
@@ -242,12 +246,6 @@ static const u8 vv6410_sensor_init[][2] = { | |||
242 | /* Pre-clock generator divide off */ | 246 | /* Pre-clock generator divide off */ |
243 | {VV6410_DATAFORMAT, BIT(7) | BIT(0)}, | 247 | {VV6410_DATAFORMAT, BIT(7) | BIT(0)}, |
244 | 248 | ||
245 | /* Exposure registers */ | ||
246 | {VV6410_FINEH, VV6410_FINE_EXPOSURE >> 8}, | ||
247 | {VV6410_FINEL, VV6410_FINE_EXPOSURE & 0xff}, | ||
248 | {VV6410_COARSEH, VV6410_COARSE_EXPOSURE >> 8}, | ||
249 | {VV6410_COARSEL, VV6410_COARSE_EXPOSURE & 0xff}, | ||
250 | {VV6410_ANALOGGAIN, 0xf0 | VV6410_DEFAULT_GAIN}, | ||
251 | {VV6410_CLKDIV, VV6410_CLK_DIV_2}, | 249 | {VV6410_CLKDIV, VV6410_CLK_DIV_2}, |
252 | 250 | ||
253 | /* System registers */ | 251 | /* System registers */ |
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index c2b8c10c075a..9623f294bdac 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c | |||
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL"); | |||
32 | struct sd { | 32 | struct sd { |
33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
34 | 34 | ||
35 | __u8 packet[ISO_MAX_SIZE + 128]; | ||
36 | /* !! no more than 128 ff in an ISO packet */ | ||
37 | |||
38 | unsigned char brightness; | 35 | unsigned char brightness; |
39 | unsigned char contrast; | 36 | unsigned char contrast; |
40 | unsigned char colors; | 37 | unsigned char colors; |
@@ -1103,7 +1100,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1103 | { | 1100 | { |
1104 | struct sd *sd = (struct sd *) gspca_dev; | 1101 | struct sd *sd = (struct sd *) gspca_dev; |
1105 | int i, sof = 0; | 1102 | int i, sof = 0; |
1106 | unsigned char *s, *d; | ||
1107 | static unsigned char ffd9[] = {0xff, 0xd9}; | 1103 | static unsigned char ffd9[] = {0xff, 0xd9}; |
1108 | 1104 | ||
1109 | /* frames are jpeg 4.1.1 without 0xff escape */ | 1105 | /* frames are jpeg 4.1.1 without 0xff escape */ |
@@ -1177,22 +1173,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1177 | } | 1173 | } |
1178 | 1174 | ||
1179 | /* add 0x00 after 0xff */ | 1175 | /* add 0x00 after 0xff */ |
1180 | for (i = len; --i >= 0; ) | 1176 | i = 0; |
1181 | if (data[i] == 0xff) | 1177 | do { |
1182 | break; | 1178 | if (data[i] == 0xff) { |
1183 | if (i < 0) { /* no 0xff */ | 1179 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
1184 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | 1180 | data, i + 1); |
1185 | return; | 1181 | len -= i; |
1186 | } | 1182 | data += i; |
1187 | s = data; | 1183 | *data = 0x00; |
1188 | d = sd->packet; | 1184 | i = 0; |
1189 | for (i = 0; i < len; i++) { | 1185 | } |
1190 | *d++ = *s++; | 1186 | i++; |
1191 | if (s[-1] == 0xff) | 1187 | } while (i < len); |
1192 | *d++ = 0x00; | 1188 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); |
1193 | } | ||
1194 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1195 | sd->packet, d - sd->packet); | ||
1196 | } | 1189 | } |
1197 | 1190 | ||
1198 | static void setbrightness(struct gspca_dev *gspca_dev) | 1191 | static void setbrightness(struct gspca_dev *gspca_dev) |
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index f63e37e2e4fd..404214b8cd2b 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c | |||
@@ -697,7 +697,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
697 | return -EINVAL; | 697 | return -EINVAL; |
698 | } | 698 | } |
699 | 699 | ||
700 | if (sd->sensor != SENSOR_OTHER) { | 700 | if (sd->sensor == SENSOR_OM6802) { |
701 | reg_w_buf(gspca_dev, n1, sizeof n1); | 701 | reg_w_buf(gspca_dev, n1, sizeof n1); |
702 | i = 5; | 702 | i = 5; |
703 | while (--i >= 0) { | 703 | while (--i >= 0) { |
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index e4e933c400bc..26dd155efcc3 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -42,7 +42,7 @@ struct sd { | |||
42 | char bridge; | 42 | char bridge; |
43 | #define BRIDGE_VC0321 0 | 43 | #define BRIDGE_VC0321 0 |
44 | #define BRIDGE_VC0323 1 | 44 | #define BRIDGE_VC0323 1 |
45 | char sensor; | 45 | u8 sensor; |
46 | #define SENSOR_HV7131R 0 | 46 | #define SENSOR_HV7131R 0 |
47 | #define SENSOR_MI0360 1 | 47 | #define SENSOR_MI0360 1 |
48 | #define SENSOR_MI1310_SOC 2 | 48 | #define SENSOR_MI1310_SOC 2 |
@@ -159,17 +159,17 @@ static const struct v4l2_pix_format vc0323_mode[] = { | |||
159 | .priv = 2}, | 159 | .priv = 2}, |
160 | }; | 160 | }; |
161 | static const struct v4l2_pix_format bi_mode[] = { | 161 | static const struct v4l2_pix_format bi_mode[] = { |
162 | {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, | 162 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
163 | .bytesperline = 320, | 163 | .bytesperline = 320, |
164 | .sizeimage = 320 * 240 * 2, | 164 | .sizeimage = 320 * 240 * 2, |
165 | .colorspace = V4L2_COLORSPACE_SRGB, | 165 | .colorspace = V4L2_COLORSPACE_SRGB, |
166 | .priv = 2}, | 166 | .priv = 2}, |
167 | {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, | 167 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
168 | .bytesperline = 640, | 168 | .bytesperline = 640, |
169 | .sizeimage = 640 * 480 * 2, | 169 | .sizeimage = 640 * 480 * 2, |
170 | .colorspace = V4L2_COLORSPACE_SRGB, | 170 | .colorspace = V4L2_COLORSPACE_SRGB, |
171 | .priv = 1}, | 171 | .priv = 1}, |
172 | {1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, | 172 | {1280, 1024, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
173 | .bytesperline = 1280, | 173 | .bytesperline = 1280, |
174 | .sizeimage = 1280 * 1024 * 2, | 174 | .sizeimage = 1280 * 1024 * 2, |
175 | .colorspace = V4L2_COLORSPACE_SRGB, | 175 | .colorspace = V4L2_COLORSPACE_SRGB, |
@@ -2453,6 +2453,17 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2453 | struct usb_device *dev = gspca_dev->dev; | 2453 | struct usb_device *dev = gspca_dev->dev; |
2454 | struct cam *cam; | 2454 | struct cam *cam; |
2455 | int sensor; | 2455 | int sensor; |
2456 | static u8 npkt[] = { /* number of packets per ISOC message */ | ||
2457 | 64, /* HV7131R 0 */ | ||
2458 | 32, /* MI0360 1 */ | ||
2459 | 32, /* MI1310_SOC 2 */ | ||
2460 | 64, /* MI1320 3 */ | ||
2461 | 128, /* MI1320_SOC 4 */ | ||
2462 | 32, /* OV7660 5 */ | ||
2463 | 64, /* OV7670 6 */ | ||
2464 | 128, /* PO1200 7 */ | ||
2465 | 128, /* PO3130NC 8 */ | ||
2466 | }; | ||
2456 | 2467 | ||
2457 | cam = &gspca_dev->cam; | 2468 | cam = &gspca_dev->cam; |
2458 | sd->bridge = id->driver_info; | 2469 | sd->bridge = id->driver_info; |
@@ -2508,6 +2519,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2508 | case SENSOR_MI1320_SOC: | 2519 | case SENSOR_MI1320_SOC: |
2509 | cam->cam_mode = bi_mode; | 2520 | cam->cam_mode = bi_mode; |
2510 | cam->nmodes = ARRAY_SIZE(bi_mode); | 2521 | cam->nmodes = ARRAY_SIZE(bi_mode); |
2522 | cam->input_flags = V4L2_IN_ST_VFLIP | | ||
2523 | V4L2_IN_ST_HFLIP; | ||
2511 | break; | 2524 | break; |
2512 | default: | 2525 | default: |
2513 | cam->cam_mode = vc0323_mode; | 2526 | cam->cam_mode = vc0323_mode; |
@@ -2515,6 +2528,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2515 | break; | 2528 | break; |
2516 | } | 2529 | } |
2517 | } | 2530 | } |
2531 | cam->npkt = npkt[sd->sensor]; | ||
2518 | 2532 | ||
2519 | sd->hflip = HFLIP_DEF; | 2533 | sd->hflip = HFLIP_DEF; |
2520 | sd->vflip = VFLIP_DEF; | 2534 | sd->vflip = VFLIP_DEF; |
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 4fe01d8b6c87..08422d315e68 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -6307,7 +6307,7 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev, | |||
6307 | retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ | 6307 | retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ |
6308 | retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ | 6308 | retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ |
6309 | retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ | 6309 | retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ |
6310 | PDEBUG(D_USBO, "i2c r [%02x] -> %04x (%02x)", | 6310 | PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)", |
6311 | reg, retval, retbyte); | 6311 | reg, retval, retbyte); |
6312 | return retval; | 6312 | return retval; |
6313 | } | 6313 | } |
@@ -6868,7 +6868,6 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { | |||
6868 | {0x8001, 0x13}, | 6868 | {0x8001, 0x13}, |
6869 | {0x8000, 0x14}, /* CS2102K */ | 6869 | {0x8000, 0x14}, /* CS2102K */ |
6870 | {0x8400, 0x15}, /* TAS5130K */ | 6870 | {0x8400, 0x15}, /* TAS5130K */ |
6871 | {0x4001, 0x16}, /* ADCM2700 */ | ||
6872 | }; | 6871 | }; |
6873 | 6872 | ||
6874 | static int vga_3wr_probe(struct gspca_dev *gspca_dev) | 6873 | static int vga_3wr_probe(struct gspca_dev *gspca_dev) |
@@ -6904,12 +6903,15 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6904 | retword |= reg_r(gspca_dev, 0x000a); | 6903 | retword |= reg_r(gspca_dev, 0x000a); |
6905 | PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); | 6904 | PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); |
6906 | reg_r(gspca_dev, 0x0010); | 6905 | reg_r(gspca_dev, 0x0010); |
6907 | /* this is tested only once anyway */ | 6906 | /* value 0x4001 is meaningless */ |
6908 | for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { | 6907 | if (retword != 0x4001) { |
6909 | if (chipset_revision_sensor[i].revision == retword) { | 6908 | for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { |
6910 | sd->chip_revision = retword; | 6909 | if (chipset_revision_sensor[i].revision == retword) { |
6911 | send_unknown(dev, SENSOR_PB0330); | 6910 | sd->chip_revision = retword; |
6912 | return chipset_revision_sensor[i].internal_sensor_id; | 6911 | send_unknown(dev, SENSOR_PB0330); |
6912 | return chipset_revision_sensor[i] | ||
6913 | .internal_sensor_id; | ||
6914 | } | ||
6913 | } | 6915 | } |
6914 | } | 6916 | } |
6915 | 6917 | ||
@@ -6980,12 +6982,12 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6980 | reg_w(dev, 0x01, 0x0001); | 6982 | reg_w(dev, 0x01, 0x0001); |
6981 | reg_w(dev, 0x03, 0x0012); | 6983 | reg_w(dev, 0x03, 0x0012); |
6982 | reg_w(dev, 0x01, 0x0012); | 6984 | reg_w(dev, 0x01, 0x0012); |
6983 | reg_w(dev, 0x05, 0x0001); | 6985 | reg_w(dev, 0x05, 0x0012); |
6984 | reg_w(dev, 0xd3, 0x008b); | 6986 | reg_w(dev, 0xd3, 0x008b); |
6985 | retword = i2c_read(gspca_dev, 0x01); | 6987 | retword = i2c_read(gspca_dev, 0x01); |
6986 | if (retword != 0) { | 6988 | if (retword != 0) { |
6987 | PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); | 6989 | PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); |
6988 | return retword; | 6990 | return 0x16; /* adcm2700 (6100/6200) */ |
6989 | } | 6991 | } |
6990 | return -1; | 6992 | return -1; |
6991 | } | 6993 | } |
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index 8e1463ee1b64..71c211402eb5 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c | |||
@@ -224,7 +224,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) | |||
224 | { | 224 | { |
225 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); | 225 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); |
226 | 226 | ||
227 | if (i->index < 0 || i->index >= HEXIUM_INPUTS) | 227 | if (i->index >= HEXIUM_INPUTS) |
228 | return -EINVAL; | 228 | return -EINVAL; |
229 | 229 | ||
230 | memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); | 230 | memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); |
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index 2bc39f628455..39d65ca41c62 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c | |||
@@ -325,7 +325,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) | |||
325 | { | 325 | { |
326 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); | 326 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); |
327 | 327 | ||
328 | if (i->index < 0 || i->index >= HEXIUM_INPUTS) | 328 | if (i->index >= HEXIUM_INPUTS) |
329 | return -EINVAL; | 329 | return -EINVAL; |
330 | 330 | ||
331 | memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); | 331 | memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 092c7da0f37a..86f2fefe1edf 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -74,7 +74,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, | |||
74 | int start, range, toggle, dev, code, ircode; | 74 | int start, range, toggle, dev, code, ircode; |
75 | 75 | ||
76 | /* poll IR chip */ | 76 | /* poll IR chip */ |
77 | if (size != i2c_master_recv(&ir->c,buf,size)) | 77 | if (size != i2c_master_recv(ir->c, buf, size)) |
78 | return -EIO; | 78 | return -EIO; |
79 | 79 | ||
80 | /* split rc5 data block ... */ | 80 | /* split rc5 data block ... */ |
@@ -137,7 +137,7 @@ static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
137 | unsigned char b; | 137 | unsigned char b; |
138 | 138 | ||
139 | /* poll IR chip */ | 139 | /* poll IR chip */ |
140 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 140 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
141 | dprintk(1,"read error\n"); | 141 | dprintk(1,"read error\n"); |
142 | return -EIO; | 142 | return -EIO; |
143 | } | 143 | } |
@@ -151,7 +151,7 @@ static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
151 | unsigned char b; | 151 | unsigned char b; |
152 | 152 | ||
153 | /* poll IR chip */ | 153 | /* poll IR chip */ |
154 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 154 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
155 | dprintk(1,"read error\n"); | 155 | dprintk(1,"read error\n"); |
156 | return -EIO; | 156 | return -EIO; |
157 | } | 157 | } |
@@ -171,7 +171,7 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
171 | unsigned char buf[4]; | 171 | unsigned char buf[4]; |
172 | 172 | ||
173 | /* poll IR chip */ | 173 | /* poll IR chip */ |
174 | if (4 != i2c_master_recv(&ir->c,buf,4)) { | 174 | if (4 != i2c_master_recv(ir->c, buf, 4)) { |
175 | dprintk(1,"read error\n"); | 175 | dprintk(1,"read error\n"); |
176 | return -EIO; | 176 | return -EIO; |
177 | } | 177 | } |
@@ -195,7 +195,7 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
195 | unsigned char b; | 195 | unsigned char b; |
196 | 196 | ||
197 | /* poll IR chip */ | 197 | /* poll IR chip */ |
198 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 198 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
199 | dprintk(1,"read error\n"); | 199 | dprintk(1,"read error\n"); |
200 | return -EIO; | 200 | return -EIO; |
201 | } | 201 | } |
@@ -222,12 +222,12 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, | |||
222 | u32 *ir_key, u32 *ir_raw) | 222 | u32 *ir_key, u32 *ir_raw) |
223 | { | 223 | { |
224 | unsigned char subaddr, key, keygroup; | 224 | unsigned char subaddr, key, keygroup; |
225 | struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0, | 225 | struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, |
226 | .buf = &subaddr, .len = 1}, | 226 | .buf = &subaddr, .len = 1}, |
227 | { .addr = ir->c.addr, .flags = I2C_M_RD, | 227 | { .addr = ir->c->addr, .flags = I2C_M_RD, |
228 | .buf = &key, .len = 1} }; | 228 | .buf = &key, .len = 1} }; |
229 | subaddr = 0x0d; | 229 | subaddr = 0x0d; |
230 | if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { | 230 | if (2 != i2c_transfer(ir->c->adapter, msg, 2)) { |
231 | dprintk(1, "read error\n"); | 231 | dprintk(1, "read error\n"); |
232 | return -EIO; | 232 | return -EIO; |
233 | } | 233 | } |
@@ -237,7 +237,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, | |||
237 | 237 | ||
238 | subaddr = 0x0b; | 238 | subaddr = 0x0b; |
239 | msg[1].buf = &keygroup; | 239 | msg[1].buf = &keygroup; |
240 | if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { | 240 | if (2 != i2c_transfer(ir->c->adapter, msg, 2)) { |
241 | dprintk(1, "read error\n"); | 241 | dprintk(1, "read error\n"); |
242 | return -EIO; | 242 | return -EIO; |
243 | } | 243 | } |
@@ -286,7 +286,7 @@ static void ir_work(struct work_struct *work) | |||
286 | 286 | ||
287 | /* MSI TV@nywhere Plus requires more frequent polling | 287 | /* MSI TV@nywhere Plus requires more frequent polling |
288 | otherwise it will miss some keypresses */ | 288 | otherwise it will miss some keypresses */ |
289 | if (ir->c.adapter->id == I2C_HW_SAA7134 && ir->c.addr == 0x30) | 289 | if (ir->c->adapter->id == I2C_HW_SAA7134 && ir->c->addr == 0x30) |
290 | polling_interval = 50; | 290 | polling_interval = 50; |
291 | 291 | ||
292 | ir_key_poll(ir); | 292 | ir_key_poll(ir); |
@@ -295,34 +295,15 @@ static void ir_work(struct work_struct *work) | |||
295 | 295 | ||
296 | /* ----------------------------------------------------------------------- */ | 296 | /* ----------------------------------------------------------------------- */ |
297 | 297 | ||
298 | static int ir_attach(struct i2c_adapter *adap, int addr, | 298 | static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) |
299 | unsigned short flags, int kind); | ||
300 | static int ir_detach(struct i2c_client *client); | ||
301 | static int ir_probe(struct i2c_adapter *adap); | ||
302 | |||
303 | static struct i2c_driver driver = { | ||
304 | .driver = { | ||
305 | .name = "ir-kbd-i2c", | ||
306 | }, | ||
307 | .id = I2C_DRIVERID_INFRARED, | ||
308 | .attach_adapter = ir_probe, | ||
309 | .detach_client = ir_detach, | ||
310 | }; | ||
311 | |||
312 | static struct i2c_client client_template = | ||
313 | { | ||
314 | .name = "unset", | ||
315 | .driver = &driver | ||
316 | }; | ||
317 | |||
318 | static int ir_attach(struct i2c_adapter *adap, int addr, | ||
319 | unsigned short flags, int kind) | ||
320 | { | 299 | { |
321 | IR_KEYTAB_TYPE *ir_codes = NULL; | 300 | IR_KEYTAB_TYPE *ir_codes = NULL; |
322 | char *name; | 301 | const char *name = NULL; |
323 | int ir_type; | 302 | int ir_type; |
324 | struct IR_i2c *ir; | 303 | struct IR_i2c *ir; |
325 | struct input_dev *input_dev; | 304 | struct input_dev *input_dev; |
305 | struct i2c_adapter *adap = client->adapter; | ||
306 | unsigned short addr = client->addr; | ||
326 | int err; | 307 | int err; |
327 | 308 | ||
328 | ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); | 309 | ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); |
@@ -332,13 +313,9 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
332 | goto err_out_free; | 313 | goto err_out_free; |
333 | } | 314 | } |
334 | 315 | ||
335 | ir->c = client_template; | 316 | ir->c = client; |
336 | ir->input = input_dev; | 317 | ir->input = input_dev; |
337 | 318 | i2c_set_clientdata(client, ir); | |
338 | ir->c.adapter = adap; | ||
339 | ir->c.addr = addr; | ||
340 | |||
341 | i2c_set_clientdata(&ir->c, ir); | ||
342 | 319 | ||
343 | switch(addr) { | 320 | switch(addr) { |
344 | case 0x64: | 321 | case 0x64: |
@@ -403,44 +380,46 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
403 | ir_codes = ir_codes_avermedia_cardbus; | 380 | ir_codes = ir_codes_avermedia_cardbus; |
404 | break; | 381 | break; |
405 | default: | 382 | default: |
406 | /* shouldn't happen */ | 383 | dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr); |
407 | printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr); | ||
408 | err = -ENODEV; | 384 | err = -ENODEV; |
409 | goto err_out_free; | 385 | goto err_out_free; |
410 | } | 386 | } |
411 | 387 | ||
412 | /* Sets name */ | 388 | /* Let the caller override settings */ |
413 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); | 389 | if (client->dev.platform_data) { |
414 | ir->ir_codes = ir_codes; | 390 | const struct IR_i2c_init_data *init_data = |
391 | client->dev.platform_data; | ||
415 | 392 | ||
416 | /* register i2c device | 393 | ir_codes = init_data->ir_codes; |
417 | * At device register, IR codes may be changed to be | 394 | name = init_data->name; |
418 | * board dependent. | 395 | ir->get_key = init_data->get_key; |
419 | */ | 396 | } |
420 | err = i2c_attach_client(&ir->c); | ||
421 | if (err) | ||
422 | goto err_out_free; | ||
423 | 397 | ||
424 | /* If IR not supported or disabled, unregisters driver */ | 398 | /* Make sure we are all setup before going on */ |
425 | if (ir->get_key == NULL) { | 399 | if (!name || !ir->get_key || !ir_codes) { |
400 | dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n", | ||
401 | addr); | ||
426 | err = -ENODEV; | 402 | err = -ENODEV; |
427 | goto err_out_detach; | 403 | goto err_out_free; |
428 | } | 404 | } |
429 | 405 | ||
430 | /* Phys addr can only be set after attaching (for ir->c.dev) */ | 406 | /* Sets name */ |
407 | snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name); | ||
408 | ir->ir_codes = ir_codes; | ||
409 | |||
431 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", | 410 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", |
432 | dev_name(&ir->c.adapter->dev), | 411 | dev_name(&adap->dev), |
433 | dev_name(&ir->c.dev)); | 412 | dev_name(&client->dev)); |
434 | 413 | ||
435 | /* init + register input device */ | 414 | /* init + register input device */ |
436 | ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); | 415 | ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); |
437 | input_dev->id.bustype = BUS_I2C; | 416 | input_dev->id.bustype = BUS_I2C; |
438 | input_dev->name = ir->c.name; | 417 | input_dev->name = ir->name; |
439 | input_dev->phys = ir->phys; | 418 | input_dev->phys = ir->phys; |
440 | 419 | ||
441 | err = input_register_device(ir->input); | 420 | err = input_register_device(ir->input); |
442 | if (err) | 421 | if (err) |
443 | goto err_out_detach; | 422 | goto err_out_free; |
444 | 423 | ||
445 | printk(DEVNAME ": %s detected at %s [%s]\n", | 424 | printk(DEVNAME ": %s detected at %s [%s]\n", |
446 | ir->input->name, ir->input->phys, adap->name); | 425 | ir->input->name, ir->input->phys, adap->name); |
@@ -451,135 +430,42 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
451 | 430 | ||
452 | return 0; | 431 | return 0; |
453 | 432 | ||
454 | err_out_detach: | ||
455 | i2c_detach_client(&ir->c); | ||
456 | err_out_free: | 433 | err_out_free: |
457 | input_free_device(input_dev); | 434 | input_free_device(input_dev); |
458 | kfree(ir); | 435 | kfree(ir); |
459 | return err; | 436 | return err; |
460 | } | 437 | } |
461 | 438 | ||
462 | static int ir_detach(struct i2c_client *client) | 439 | static int ir_remove(struct i2c_client *client) |
463 | { | 440 | { |
464 | struct IR_i2c *ir = i2c_get_clientdata(client); | 441 | struct IR_i2c *ir = i2c_get_clientdata(client); |
465 | 442 | ||
466 | /* kill outstanding polls */ | 443 | /* kill outstanding polls */ |
467 | cancel_delayed_work_sync(&ir->work); | 444 | cancel_delayed_work_sync(&ir->work); |
468 | 445 | ||
469 | /* unregister devices */ | 446 | /* unregister device */ |
470 | input_unregister_device(ir->input); | 447 | input_unregister_device(ir->input); |
471 | i2c_detach_client(&ir->c); | ||
472 | 448 | ||
473 | /* free memory */ | 449 | /* free memory */ |
474 | kfree(ir); | 450 | kfree(ir); |
475 | return 0; | 451 | return 0; |
476 | } | 452 | } |
477 | 453 | ||
478 | static int ir_probe(struct i2c_adapter *adap) | 454 | static const struct i2c_device_id ir_kbd_id[] = { |
479 | { | 455 | /* Generic entry for any IR receiver */ |
480 | 456 | { "ir_video", 0 }, | |
481 | /* The external IR receiver is at i2c address 0x34 (0x35 for | 457 | /* IR device specific entries could be added here */ |
482 | reads). Future Hauppauge cards will have an internal | 458 | { } |
483 | receiver at 0x30 (0x31 for reads). In theory, both can be | 459 | }; |
484 | fitted, and Hauppauge suggest an external overrides an | ||
485 | internal. | ||
486 | |||
487 | That's why we probe 0x1a (~0x34) first. CB | ||
488 | */ | ||
489 | |||
490 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; | ||
491 | static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 }; | ||
492 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; | ||
493 | static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; | ||
494 | static const int probe_cx23885[] = { 0x6b, -1 }; | ||
495 | const int *probe; | ||
496 | struct i2c_msg msg = { | ||
497 | .flags = I2C_M_RD, | ||
498 | .len = 0, | ||
499 | .buf = NULL, | ||
500 | }; | ||
501 | int i, rc; | ||
502 | |||
503 | switch (adap->id) { | ||
504 | case I2C_HW_B_BT848: | ||
505 | probe = probe_bttv; | ||
506 | break; | ||
507 | case I2C_HW_B_CX2341X: | ||
508 | probe = probe_bttv; | ||
509 | break; | ||
510 | case I2C_HW_SAA7134: | ||
511 | probe = probe_saa7134; | ||
512 | break; | ||
513 | case I2C_HW_B_EM28XX: | ||
514 | probe = probe_em28XX; | ||
515 | break; | ||
516 | case I2C_HW_B_CX2388x: | ||
517 | probe = probe_cx88; | ||
518 | break; | ||
519 | case I2C_HW_B_CX23885: | ||
520 | probe = probe_cx23885; | ||
521 | break; | ||
522 | default: | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | for (i = 0; -1 != probe[i]; i++) { | ||
527 | msg.addr = probe[i]; | ||
528 | rc = i2c_transfer(adap, &msg, 1); | ||
529 | dprintk(1,"probe 0x%02x @ %s: %s\n", | ||
530 | probe[i], adap->name, | ||
531 | (1 == rc) ? "yes" : "no"); | ||
532 | if (1 == rc) { | ||
533 | ir_attach(adap, probe[i], 0, 0); | ||
534 | return 0; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | /* Special case for MSI TV@nywhere Plus remote */ | ||
539 | if (adap->id == I2C_HW_SAA7134) { | ||
540 | u8 temp; | ||
541 | |||
542 | /* MSI TV@nywhere Plus controller doesn't seem to | ||
543 | respond to probes unless we read something from | ||
544 | an existing device. Weird... */ | ||
545 | |||
546 | msg.addr = 0x50; | ||
547 | rc = i2c_transfer(adap, &msg, 1); | ||
548 | dprintk(1, "probe 0x%02x @ %s: %s\n", | ||
549 | msg.addr, adap->name, | ||
550 | (1 == rc) ? "yes" : "no"); | ||
551 | |||
552 | /* Now do the probe. The controller does not respond | ||
553 | to 0-byte reads, so we use a 1-byte read instead. */ | ||
554 | msg.addr = 0x30; | ||
555 | msg.len = 1; | ||
556 | msg.buf = &temp; | ||
557 | rc = i2c_transfer(adap, &msg, 1); | ||
558 | dprintk(1, "probe 0x%02x @ %s: %s\n", | ||
559 | msg.addr, adap->name, | ||
560 | (1 == rc) ? "yes" : "no"); | ||
561 | if (1 == rc) | ||
562 | ir_attach(adap, msg.addr, 0, 0); | ||
563 | } | ||
564 | |||
565 | /* Special case for AVerMedia Cardbus remote */ | ||
566 | if (adap->id == I2C_HW_SAA7134) { | ||
567 | unsigned char subaddr, data; | ||
568 | struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0, | ||
569 | .buf = &subaddr, .len = 1}, | ||
570 | { .addr = 0x40, .flags = I2C_M_RD, | ||
571 | .buf = &data, .len = 1} }; | ||
572 | subaddr = 0x0d; | ||
573 | rc = i2c_transfer(adap, msg, 2); | ||
574 | dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n", | ||
575 | msg[0].addr, subaddr, adap->name, | ||
576 | (2 == rc) ? "yes" : "no"); | ||
577 | if (2 == rc) | ||
578 | ir_attach(adap, msg[0].addr, 0, 0); | ||
579 | } | ||
580 | 460 | ||
581 | return 0; | 461 | static struct i2c_driver driver = { |
582 | } | 462 | .driver = { |
463 | .name = "ir-kbd-i2c", | ||
464 | }, | ||
465 | .probe = ir_probe, | ||
466 | .remove = ir_remove, | ||
467 | .id_table = ir_kbd_id, | ||
468 | }; | ||
583 | 469 | ||
584 | /* ----------------------------------------------------------------------- */ | 470 | /* ----------------------------------------------------------------------- */ |
585 | 471 | ||
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index db2ac9a99acd..558f8a837ff4 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -455,7 +455,7 @@ static void ivtv_process_eeprom(struct ivtv *itv) | |||
455 | break; | 455 | break; |
456 | } | 456 | } |
457 | if (tv.tuner_type == TUNER_ABSENT) | 457 | if (tv.tuner_type == TUNER_ABSENT) |
458 | IVTV_ERR("tveeprom cannot autodetect tuner!"); | 458 | IVTV_ERR("tveeprom cannot autodetect tuner!\n"); |
459 | 459 | ||
460 | if (itv->options.tuner == -1) | 460 | if (itv->options.tuner == -1) |
461 | itv->options.tuner = tv.tuner_type; | 461 | itv->options.tuner = tv.tuner_type; |
@@ -946,17 +946,14 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, | |||
946 | if (itv == NULL) | 946 | if (itv == NULL) |
947 | return -ENOMEM; | 947 | return -ENOMEM; |
948 | itv->pdev = pdev; | 948 | itv->pdev = pdev; |
949 | itv->instance = atomic_inc_return(&ivtv_instance) - 1; | 949 | itv->instance = v4l2_device_set_name(&itv->v4l2_dev, "ivtv", |
950 | &ivtv_instance); | ||
950 | 951 | ||
951 | retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev); | 952 | retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev); |
952 | if (retval) { | 953 | if (retval) { |
953 | kfree(itv); | 954 | kfree(itv); |
954 | return retval; | 955 | return retval; |
955 | } | 956 | } |
956 | /* "ivtv + PCI ID" is a bit of a mouthful, so use | ||
957 | "ivtv + instance" instead. */ | ||
958 | snprintf(itv->v4l2_dev.name, sizeof(itv->v4l2_dev.name), | ||
959 | "ivtv%d", itv->instance); | ||
960 | IVTV_INFO("Initializing card %d\n", itv->instance); | 957 | IVTV_INFO("Initializing card %d\n", itv->instance); |
961 | 958 | ||
962 | ivtv_process_options(itv); | 959 | ivtv_process_options(itv); |
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 9e3d32b8004c..e52aa322b134 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c | |||
@@ -579,9 +579,11 @@ static struct i2c_client ivtv_i2c_client_template = { | |||
579 | .name = "ivtv internal", | 579 | .name = "ivtv internal", |
580 | }; | 580 | }; |
581 | 581 | ||
582 | /* init + register i2c algo-bit adapter */ | 582 | /* init + register i2c adapter + instantiate IR receiver */ |
583 | int init_ivtv_i2c(struct ivtv *itv) | 583 | int init_ivtv_i2c(struct ivtv *itv) |
584 | { | 584 | { |
585 | int retval; | ||
586 | |||
585 | IVTV_DEBUG_I2C("i2c init\n"); | 587 | IVTV_DEBUG_I2C("i2c init\n"); |
586 | 588 | ||
587 | /* Sanity checks for the I2C hardware arrays. They must be the | 589 | /* Sanity checks for the I2C hardware arrays. They must be the |
@@ -619,9 +621,37 @@ int init_ivtv_i2c(struct ivtv *itv) | |||
619 | ivtv_setsda(itv, 1); | 621 | ivtv_setsda(itv, 1); |
620 | 622 | ||
621 | if (itv->options.newi2c > 0) | 623 | if (itv->options.newi2c > 0) |
622 | return i2c_add_adapter(&itv->i2c_adap); | 624 | retval = i2c_add_adapter(&itv->i2c_adap); |
623 | else | 625 | else |
624 | return i2c_bit_add_bus(&itv->i2c_adap); | 626 | retval = i2c_bit_add_bus(&itv->i2c_adap); |
627 | |||
628 | /* Instantiate the IR receiver device, if present */ | ||
629 | if (retval == 0) { | ||
630 | struct i2c_board_info info; | ||
631 | /* The external IR receiver is at i2c address 0x34 (0x35 for | ||
632 | reads). Future Hauppauge cards will have an internal | ||
633 | receiver at 0x30 (0x31 for reads). In theory, both can be | ||
634 | fitted, and Hauppauge suggest an external overrides an | ||
635 | internal. | ||
636 | |||
637 | That's why we probe 0x1a (~0x34) first. CB | ||
638 | */ | ||
639 | const unsigned short addr_list[] = { | ||
640 | 0x1a, /* Hauppauge IR external */ | ||
641 | 0x18, /* Hauppauge IR internal */ | ||
642 | 0x71, /* Hauppauge IR (PVR150) */ | ||
643 | 0x64, /* Pixelview IR */ | ||
644 | 0x30, /* KNC ONE IR */ | ||
645 | 0x6b, /* Adaptec IR */ | ||
646 | I2C_CLIENT_END | ||
647 | }; | ||
648 | |||
649 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
650 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
651 | i2c_new_probed_device(&itv->i2c_adap, &info, addr_list); | ||
652 | } | ||
653 | |||
654 | return retval; | ||
625 | } | 655 | } |
626 | 656 | ||
627 | void exit_ivtv_i2c(struct ivtv *itv) | 657 | void exit_ivtv_i2c(struct ivtv *itv) |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index c342a9fe983e..99f3c39a118b 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -709,7 +709,7 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) | |||
709 | else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET && | 709 | else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET && |
710 | regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE) | 710 | regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE) |
711 | reg_start = itv->dec_mem - IVTV_DECODER_OFFSET; | 711 | reg_start = itv->dec_mem - IVTV_DECODER_OFFSET; |
712 | else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE) | 712 | else if (regs->reg < IVTV_ENCODER_SIZE) |
713 | reg_start = itv->enc_mem; | 713 | reg_start = itv->enc_mem; |
714 | else | 714 | else |
715 | return -EINVAL; | 715 | return -EINVAL; |
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 684f62fa7897..459c04cbf69d 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c | |||
@@ -75,53 +75,50 @@ struct mt9m001 { | |||
75 | unsigned char autoexposure; | 75 | unsigned char autoexposure; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static int reg_read(struct soc_camera_device *icd, const u8 reg) | 78 | static int reg_read(struct i2c_client *client, const u8 reg) |
79 | { | 79 | { |
80 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
81 | struct i2c_client *client = mt9m001->client; | ||
82 | s32 data = i2c_smbus_read_word_data(client, reg); | 80 | s32 data = i2c_smbus_read_word_data(client, reg); |
83 | return data < 0 ? data : swab16(data); | 81 | return data < 0 ? data : swab16(data); |
84 | } | 82 | } |
85 | 83 | ||
86 | static int reg_write(struct soc_camera_device *icd, const u8 reg, | 84 | static int reg_write(struct i2c_client *client, const u8 reg, |
87 | const u16 data) | 85 | const u16 data) |
88 | { | 86 | { |
89 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 87 | return i2c_smbus_write_word_data(client, reg, swab16(data)); |
90 | return i2c_smbus_write_word_data(mt9m001->client, reg, swab16(data)); | ||
91 | } | 88 | } |
92 | 89 | ||
93 | static int reg_set(struct soc_camera_device *icd, const u8 reg, | 90 | static int reg_set(struct i2c_client *client, const u8 reg, |
94 | const u16 data) | 91 | const u16 data) |
95 | { | 92 | { |
96 | int ret; | 93 | int ret; |
97 | 94 | ||
98 | ret = reg_read(icd, reg); | 95 | ret = reg_read(client, reg); |
99 | if (ret < 0) | 96 | if (ret < 0) |
100 | return ret; | 97 | return ret; |
101 | return reg_write(icd, reg, ret | data); | 98 | return reg_write(client, reg, ret | data); |
102 | } | 99 | } |
103 | 100 | ||
104 | static int reg_clear(struct soc_camera_device *icd, const u8 reg, | 101 | static int reg_clear(struct i2c_client *client, const u8 reg, |
105 | const u16 data) | 102 | const u16 data) |
106 | { | 103 | { |
107 | int ret; | 104 | int ret; |
108 | 105 | ||
109 | ret = reg_read(icd, reg); | 106 | ret = reg_read(client, reg); |
110 | if (ret < 0) | 107 | if (ret < 0) |
111 | return ret; | 108 | return ret; |
112 | return reg_write(icd, reg, ret & ~data); | 109 | return reg_write(client, reg, ret & ~data); |
113 | } | 110 | } |
114 | 111 | ||
115 | static int mt9m001_init(struct soc_camera_device *icd) | 112 | static int mt9m001_init(struct soc_camera_device *icd) |
116 | { | 113 | { |
117 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 114 | struct i2c_client *client = to_i2c_client(icd->control); |
118 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | 115 | struct soc_camera_link *icl = client->dev.platform_data; |
119 | int ret; | 116 | int ret; |
120 | 117 | ||
121 | dev_dbg(icd->vdev->parent, "%s\n", __func__); | 118 | dev_dbg(icd->vdev->parent, "%s\n", __func__); |
122 | 119 | ||
123 | if (icl->power) { | 120 | if (icl->power) { |
124 | ret = icl->power(&mt9m001->client->dev, 1); | 121 | ret = icl->power(&client->dev, 1); |
125 | if (ret < 0) { | 122 | if (ret < 0) { |
126 | dev_err(icd->vdev->parent, | 123 | dev_err(icd->vdev->parent, |
127 | "Platform failed to power-on the camera.\n"); | 124 | "Platform failed to power-on the camera.\n"); |
@@ -131,49 +128,53 @@ static int mt9m001_init(struct soc_camera_device *icd) | |||
131 | 128 | ||
132 | /* The camera could have been already on, we reset it additionally */ | 129 | /* The camera could have been already on, we reset it additionally */ |
133 | if (icl->reset) | 130 | if (icl->reset) |
134 | ret = icl->reset(&mt9m001->client->dev); | 131 | ret = icl->reset(&client->dev); |
135 | else | 132 | else |
136 | ret = -ENODEV; | 133 | ret = -ENODEV; |
137 | 134 | ||
138 | if (ret < 0) { | 135 | if (ret < 0) { |
139 | /* Either no platform reset, or platform reset failed */ | 136 | /* Either no platform reset, or platform reset failed */ |
140 | ret = reg_write(icd, MT9M001_RESET, 1); | 137 | ret = reg_write(client, MT9M001_RESET, 1); |
141 | if (!ret) | 138 | if (!ret) |
142 | ret = reg_write(icd, MT9M001_RESET, 0); | 139 | ret = reg_write(client, MT9M001_RESET, 0); |
143 | } | 140 | } |
144 | /* Disable chip, synchronous option update */ | 141 | /* Disable chip, synchronous option update */ |
145 | if (!ret) | 142 | if (!ret) |
146 | ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); | 143 | ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0); |
147 | 144 | ||
148 | return ret; | 145 | return ret; |
149 | } | 146 | } |
150 | 147 | ||
151 | static int mt9m001_release(struct soc_camera_device *icd) | 148 | static int mt9m001_release(struct soc_camera_device *icd) |
152 | { | 149 | { |
153 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 150 | struct i2c_client *client = to_i2c_client(icd->control); |
154 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | 151 | struct soc_camera_link *icl = client->dev.platform_data; |
155 | 152 | ||
156 | /* Disable the chip */ | 153 | /* Disable the chip */ |
157 | reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); | 154 | reg_write(client, MT9M001_OUTPUT_CONTROL, 0); |
158 | 155 | ||
159 | if (icl->power) | 156 | if (icl->power) |
160 | icl->power(&mt9m001->client->dev, 0); | 157 | icl->power(&client->dev, 0); |
161 | 158 | ||
162 | return 0; | 159 | return 0; |
163 | } | 160 | } |
164 | 161 | ||
165 | static int mt9m001_start_capture(struct soc_camera_device *icd) | 162 | static int mt9m001_start_capture(struct soc_camera_device *icd) |
166 | { | 163 | { |
164 | struct i2c_client *client = to_i2c_client(icd->control); | ||
165 | |||
167 | /* Switch to master "normal" mode */ | 166 | /* Switch to master "normal" mode */ |
168 | if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 2) < 0) | 167 | if (reg_write(client, MT9M001_OUTPUT_CONTROL, 2) < 0) |
169 | return -EIO; | 168 | return -EIO; |
170 | return 0; | 169 | return 0; |
171 | } | 170 | } |
172 | 171 | ||
173 | static int mt9m001_stop_capture(struct soc_camera_device *icd) | 172 | static int mt9m001_stop_capture(struct soc_camera_device *icd) |
174 | { | 173 | { |
174 | struct i2c_client *client = to_i2c_client(icd->control); | ||
175 | |||
175 | /* Stop sensor readout */ | 176 | /* Stop sensor readout */ |
176 | if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 0) < 0) | 177 | if (reg_write(client, MT9M001_OUTPUT_CONTROL, 0) < 0) |
177 | return -EIO; | 178 | return -EIO; |
178 | return 0; | 179 | return 0; |
179 | } | 180 | } |
@@ -222,28 +223,29 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) | |||
222 | static int mt9m001_set_crop(struct soc_camera_device *icd, | 223 | static int mt9m001_set_crop(struct soc_camera_device *icd, |
223 | struct v4l2_rect *rect) | 224 | struct v4l2_rect *rect) |
224 | { | 225 | { |
226 | struct i2c_client *client = to_i2c_client(icd->control); | ||
225 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 227 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
226 | int ret; | 228 | int ret; |
227 | const u16 hblank = 9, vblank = 25; | 229 | const u16 hblank = 9, vblank = 25; |
228 | 230 | ||
229 | /* Blanking and start values - default... */ | 231 | /* Blanking and start values - default... */ |
230 | ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank); | 232 | ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); |
231 | if (!ret) | 233 | if (!ret) |
232 | ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank); | 234 | ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank); |
233 | 235 | ||
234 | /* The caller provides a supported format, as verified per | 236 | /* The caller provides a supported format, as verified per |
235 | * call to icd->try_fmt() */ | 237 | * call to icd->try_fmt() */ |
236 | if (!ret) | 238 | if (!ret) |
237 | ret = reg_write(icd, MT9M001_COLUMN_START, rect->left); | 239 | ret = reg_write(client, MT9M001_COLUMN_START, rect->left); |
238 | if (!ret) | 240 | if (!ret) |
239 | ret = reg_write(icd, MT9M001_ROW_START, rect->top); | 241 | ret = reg_write(client, MT9M001_ROW_START, rect->top); |
240 | if (!ret) | 242 | if (!ret) |
241 | ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1); | 243 | ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect->width - 1); |
242 | if (!ret) | 244 | if (!ret) |
243 | ret = reg_write(icd, MT9M001_WINDOW_HEIGHT, | 245 | ret = reg_write(client, MT9M001_WINDOW_HEIGHT, |
244 | rect->height + icd->y_skip_top - 1); | 246 | rect->height + icd->y_skip_top - 1); |
245 | if (!ret && mt9m001->autoexposure) { | 247 | if (!ret && mt9m001->autoexposure) { |
246 | ret = reg_write(icd, MT9M001_SHUTTER_WIDTH, | 248 | ret = reg_write(client, MT9M001_SHUTTER_WIDTH, |
247 | rect->height + icd->y_skip_top + vblank); | 249 | rect->height + icd->y_skip_top + vblank); |
248 | if (!ret) { | 250 | if (!ret) { |
249 | const struct v4l2_queryctrl *qctrl = | 251 | const struct v4l2_queryctrl *qctrl = |
@@ -312,16 +314,16 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd, | |||
312 | static int mt9m001_get_register(struct soc_camera_device *icd, | 314 | static int mt9m001_get_register(struct soc_camera_device *icd, |
313 | struct v4l2_dbg_register *reg) | 315 | struct v4l2_dbg_register *reg) |
314 | { | 316 | { |
315 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 317 | struct i2c_client *client = to_i2c_client(icd->control); |
316 | 318 | ||
317 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 319 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
318 | return -EINVAL; | 320 | return -EINVAL; |
319 | 321 | ||
320 | if (reg->match.addr != mt9m001->client->addr) | 322 | if (reg->match.addr != client->addr) |
321 | return -ENODEV; | 323 | return -ENODEV; |
322 | 324 | ||
323 | reg->size = 2; | 325 | reg->size = 2; |
324 | reg->val = reg_read(icd, reg->reg); | 326 | reg->val = reg_read(client, reg->reg); |
325 | 327 | ||
326 | if (reg->val > 0xffff) | 328 | if (reg->val > 0xffff) |
327 | return -EIO; | 329 | return -EIO; |
@@ -332,15 +334,15 @@ static int mt9m001_get_register(struct soc_camera_device *icd, | |||
332 | static int mt9m001_set_register(struct soc_camera_device *icd, | 334 | static int mt9m001_set_register(struct soc_camera_device *icd, |
333 | struct v4l2_dbg_register *reg) | 335 | struct v4l2_dbg_register *reg) |
334 | { | 336 | { |
335 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 337 | struct i2c_client *client = to_i2c_client(icd->control); |
336 | 338 | ||
337 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 339 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
338 | return -EINVAL; | 340 | return -EINVAL; |
339 | 341 | ||
340 | if (reg->match.addr != mt9m001->client->addr) | 342 | if (reg->match.addr != client->addr) |
341 | return -ENODEV; | 343 | return -ENODEV; |
342 | 344 | ||
343 | if (reg_write(icd, reg->reg, reg->val) < 0) | 345 | if (reg_write(client, reg->reg, reg->val) < 0) |
344 | return -EIO; | 346 | return -EIO; |
345 | 347 | ||
346 | return 0; | 348 | return 0; |
@@ -416,12 +418,13 @@ static struct soc_camera_ops mt9m001_ops = { | |||
416 | 418 | ||
417 | static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 419 | static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
418 | { | 420 | { |
421 | struct i2c_client *client = to_i2c_client(icd->control); | ||
419 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 422 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
420 | int data; | 423 | int data; |
421 | 424 | ||
422 | switch (ctrl->id) { | 425 | switch (ctrl->id) { |
423 | case V4L2_CID_VFLIP: | 426 | case V4L2_CID_VFLIP: |
424 | data = reg_read(icd, MT9M001_READ_OPTIONS2); | 427 | data = reg_read(client, MT9M001_READ_OPTIONS2); |
425 | if (data < 0) | 428 | if (data < 0) |
426 | return -EIO; | 429 | return -EIO; |
427 | ctrl->value = !!(data & 0x8000); | 430 | ctrl->value = !!(data & 0x8000); |
@@ -435,6 +438,7 @@ static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_contro | |||
435 | 438 | ||
436 | static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 439 | static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
437 | { | 440 | { |
441 | struct i2c_client *client = to_i2c_client(icd->control); | ||
438 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 442 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
439 | const struct v4l2_queryctrl *qctrl; | 443 | const struct v4l2_queryctrl *qctrl; |
440 | int data; | 444 | int data; |
@@ -447,9 +451,9 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
447 | switch (ctrl->id) { | 451 | switch (ctrl->id) { |
448 | case V4L2_CID_VFLIP: | 452 | case V4L2_CID_VFLIP: |
449 | if (ctrl->value) | 453 | if (ctrl->value) |
450 | data = reg_set(icd, MT9M001_READ_OPTIONS2, 0x8000); | 454 | data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000); |
451 | else | 455 | else |
452 | data = reg_clear(icd, MT9M001_READ_OPTIONS2, 0x8000); | 456 | data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000); |
453 | if (data < 0) | 457 | if (data < 0) |
454 | return -EIO; | 458 | return -EIO; |
455 | break; | 459 | break; |
@@ -463,7 +467,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
463 | data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; | 467 | data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; |
464 | 468 | ||
465 | dev_dbg(&icd->dev, "Setting gain %d\n", data); | 469 | dev_dbg(&icd->dev, "Setting gain %d\n", data); |
466 | data = reg_write(icd, MT9M001_GLOBAL_GAIN, data); | 470 | data = reg_write(client, MT9M001_GLOBAL_GAIN, data); |
467 | if (data < 0) | 471 | if (data < 0) |
468 | return -EIO; | 472 | return -EIO; |
469 | } else { | 473 | } else { |
@@ -481,8 +485,8 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
481 | data = ((gain - 64) * 7 + 28) / 56 + 96; | 485 | data = ((gain - 64) * 7 + 28) / 56 + 96; |
482 | 486 | ||
483 | dev_dbg(&icd->dev, "Setting gain from %d to %d\n", | 487 | dev_dbg(&icd->dev, "Setting gain from %d to %d\n", |
484 | reg_read(icd, MT9M001_GLOBAL_GAIN), data); | 488 | reg_read(client, MT9M001_GLOBAL_GAIN), data); |
485 | data = reg_write(icd, MT9M001_GLOBAL_GAIN, data); | 489 | data = reg_write(client, MT9M001_GLOBAL_GAIN, data); |
486 | if (data < 0) | 490 | if (data < 0) |
487 | return -EIO; | 491 | return -EIO; |
488 | } | 492 | } |
@@ -500,8 +504,8 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
500 | range / 2) / range + 1; | 504 | range / 2) / range + 1; |
501 | 505 | ||
502 | dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n", | 506 | dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n", |
503 | reg_read(icd, MT9M001_SHUTTER_WIDTH), shutter); | 507 | reg_read(client, MT9M001_SHUTTER_WIDTH), shutter); |
504 | if (reg_write(icd, MT9M001_SHUTTER_WIDTH, shutter) < 0) | 508 | if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0) |
505 | return -EIO; | 509 | return -EIO; |
506 | icd->exposure = ctrl->value; | 510 | icd->exposure = ctrl->value; |
507 | mt9m001->autoexposure = 0; | 511 | mt9m001->autoexposure = 0; |
@@ -510,7 +514,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
510 | case V4L2_CID_EXPOSURE_AUTO: | 514 | case V4L2_CID_EXPOSURE_AUTO: |
511 | if (ctrl->value) { | 515 | if (ctrl->value) { |
512 | const u16 vblank = 25; | 516 | const u16 vblank = 25; |
513 | if (reg_write(icd, MT9M001_SHUTTER_WIDTH, icd->height + | 517 | if (reg_write(client, MT9M001_SHUTTER_WIDTH, icd->height + |
514 | icd->y_skip_top + vblank) < 0) | 518 | icd->y_skip_top + vblank) < 0) |
515 | return -EIO; | 519 | return -EIO; |
516 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | 520 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); |
@@ -529,8 +533,9 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
529 | * this wasn't our capture interface, so, we wait for the right one */ | 533 | * this wasn't our capture interface, so, we wait for the right one */ |
530 | static int mt9m001_video_probe(struct soc_camera_device *icd) | 534 | static int mt9m001_video_probe(struct soc_camera_device *icd) |
531 | { | 535 | { |
536 | struct i2c_client *client = to_i2c_client(icd->control); | ||
532 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 537 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
533 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | 538 | struct soc_camera_link *icl = client->dev.platform_data; |
534 | s32 data; | 539 | s32 data; |
535 | int ret; | 540 | int ret; |
536 | unsigned long flags; | 541 | unsigned long flags; |
@@ -542,11 +547,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd) | |||
542 | return -ENODEV; | 547 | return -ENODEV; |
543 | 548 | ||
544 | /* Enable the chip */ | 549 | /* Enable the chip */ |
545 | data = reg_write(icd, MT9M001_CHIP_ENABLE, 1); | 550 | data = reg_write(client, MT9M001_CHIP_ENABLE, 1); |
546 | dev_dbg(&icd->dev, "write: %d\n", data); | 551 | dev_dbg(&icd->dev, "write: %d\n", data); |
547 | 552 | ||
548 | /* Read out the chip version register */ | 553 | /* Read out the chip version register */ |
549 | data = reg_read(icd, MT9M001_CHIP_VERSION); | 554 | data = reg_read(client, MT9M001_CHIP_VERSION); |
550 | 555 | ||
551 | /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ | 556 | /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ |
552 | switch (data) { | 557 | switch (data) { |
@@ -604,10 +609,13 @@ ei2c: | |||
604 | static void mt9m001_video_remove(struct soc_camera_device *icd) | 609 | static void mt9m001_video_remove(struct soc_camera_device *icd) |
605 | { | 610 | { |
606 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 611 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
612 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | ||
607 | 613 | ||
608 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, | 614 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, |
609 | icd->dev.parent, icd->vdev); | 615 | icd->dev.parent, icd->vdev); |
610 | soc_camera_video_stop(icd); | 616 | soc_camera_video_stop(icd); |
617 | if (icl->free_bus) | ||
618 | icl->free_bus(icl); | ||
611 | } | 619 | } |
612 | 620 | ||
613 | static int mt9m001_probe(struct i2c_client *client, | 621 | static int mt9m001_probe(struct i2c_client *client, |
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index cdd1ddb51388..fc5e2de03766 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c | |||
@@ -113,10 +113,10 @@ | |||
113 | * mt9m111: Camera control register addresses (0x200..0x2ff not implemented) | 113 | * mt9m111: Camera control register addresses (0x200..0x2ff not implemented) |
114 | */ | 114 | */ |
115 | 115 | ||
116 | #define reg_read(reg) mt9m111_reg_read(icd, MT9M111_##reg) | 116 | #define reg_read(reg) mt9m111_reg_read(client, MT9M111_##reg) |
117 | #define reg_write(reg, val) mt9m111_reg_write(icd, MT9M111_##reg, (val)) | 117 | #define reg_write(reg, val) mt9m111_reg_write(client, MT9M111_##reg, (val)) |
118 | #define reg_set(reg, val) mt9m111_reg_set(icd, MT9M111_##reg, (val)) | 118 | #define reg_set(reg, val) mt9m111_reg_set(client, MT9M111_##reg, (val)) |
119 | #define reg_clear(reg, val) mt9m111_reg_clear(icd, MT9M111_##reg, (val)) | 119 | #define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val)) |
120 | 120 | ||
121 | #define MT9M111_MIN_DARK_ROWS 8 | 121 | #define MT9M111_MIN_DARK_ROWS 8 |
122 | #define MT9M111_MIN_DARK_COLS 24 | 122 | #define MT9M111_MIN_DARK_COLS 24 |
@@ -184,58 +184,55 @@ static int reg_page_map_set(struct i2c_client *client, const u16 reg) | |||
184 | return ret; | 184 | return ret; |
185 | } | 185 | } |
186 | 186 | ||
187 | static int mt9m111_reg_read(struct soc_camera_device *icd, const u16 reg) | 187 | static int mt9m111_reg_read(struct i2c_client *client, const u16 reg) |
188 | { | 188 | { |
189 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | ||
190 | struct i2c_client *client = mt9m111->client; | ||
191 | int ret; | 189 | int ret; |
192 | 190 | ||
193 | ret = reg_page_map_set(client, reg); | 191 | ret = reg_page_map_set(client, reg); |
194 | if (!ret) | 192 | if (!ret) |
195 | ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); | 193 | ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); |
196 | 194 | ||
197 | dev_dbg(&icd->dev, "read reg.%03x -> %04x\n", reg, ret); | 195 | dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret); |
198 | return ret; | 196 | return ret; |
199 | } | 197 | } |
200 | 198 | ||
201 | static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg, | 199 | static int mt9m111_reg_write(struct i2c_client *client, const u16 reg, |
202 | const u16 data) | 200 | const u16 data) |
203 | { | 201 | { |
204 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | ||
205 | struct i2c_client *client = mt9m111->client; | ||
206 | int ret; | 202 | int ret; |
207 | 203 | ||
208 | ret = reg_page_map_set(client, reg); | 204 | ret = reg_page_map_set(client, reg); |
209 | if (!ret) | 205 | if (!ret) |
210 | ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff), | 206 | ret = i2c_smbus_write_word_data(client, (reg & 0xff), |
211 | swab16(data)); | 207 | swab16(data)); |
212 | dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); | 208 | dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); |
213 | return ret; | 209 | return ret; |
214 | } | 210 | } |
215 | 211 | ||
216 | static int mt9m111_reg_set(struct soc_camera_device *icd, const u16 reg, | 212 | static int mt9m111_reg_set(struct i2c_client *client, const u16 reg, |
217 | const u16 data) | 213 | const u16 data) |
218 | { | 214 | { |
219 | int ret; | 215 | int ret; |
220 | 216 | ||
221 | ret = mt9m111_reg_read(icd, reg); | 217 | ret = mt9m111_reg_read(client, reg); |
222 | if (ret >= 0) | 218 | if (ret >= 0) |
223 | ret = mt9m111_reg_write(icd, reg, ret | data); | 219 | ret = mt9m111_reg_write(client, reg, ret | data); |
224 | return ret; | 220 | return ret; |
225 | } | 221 | } |
226 | 222 | ||
227 | static int mt9m111_reg_clear(struct soc_camera_device *icd, const u16 reg, | 223 | static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg, |
228 | const u16 data) | 224 | const u16 data) |
229 | { | 225 | { |
230 | int ret; | 226 | int ret; |
231 | 227 | ||
232 | ret = mt9m111_reg_read(icd, reg); | 228 | ret = mt9m111_reg_read(client, reg); |
233 | return mt9m111_reg_write(icd, reg, ret & ~data); | 229 | return mt9m111_reg_write(client, reg, ret & ~data); |
234 | } | 230 | } |
235 | 231 | ||
236 | static int mt9m111_set_context(struct soc_camera_device *icd, | 232 | static int mt9m111_set_context(struct soc_camera_device *icd, |
237 | enum mt9m111_context ctxt) | 233 | enum mt9m111_context ctxt) |
238 | { | 234 | { |
235 | struct i2c_client *client = to_i2c_client(icd->control); | ||
239 | int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B | 236 | int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B |
240 | | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B | 237 | | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B |
241 | | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B | 238 | | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B |
@@ -252,6 +249,7 @@ static int mt9m111_set_context(struct soc_camera_device *icd, | |||
252 | static int mt9m111_setup_rect(struct soc_camera_device *icd, | 249 | static int mt9m111_setup_rect(struct soc_camera_device *icd, |
253 | struct v4l2_rect *rect) | 250 | struct v4l2_rect *rect) |
254 | { | 251 | { |
252 | struct i2c_client *client = to_i2c_client(icd->control); | ||
255 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 253 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
256 | int ret, is_raw_format; | 254 | int ret, is_raw_format; |
257 | int width = rect->width; | 255 | int width = rect->width; |
@@ -296,6 +294,7 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd, | |||
296 | 294 | ||
297 | static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) | 295 | static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) |
298 | { | 296 | { |
297 | struct i2c_client *client = to_i2c_client(icd->control); | ||
299 | int ret; | 298 | int ret; |
300 | 299 | ||
301 | ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); | 300 | ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); |
@@ -357,12 +356,13 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) | |||
357 | 356 | ||
358 | static int mt9m111_enable(struct soc_camera_device *icd) | 357 | static int mt9m111_enable(struct soc_camera_device *icd) |
359 | { | 358 | { |
359 | struct i2c_client *client = to_i2c_client(icd->control); | ||
360 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 360 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
361 | struct soc_camera_link *icl = mt9m111->client->dev.platform_data; | 361 | struct soc_camera_link *icl = client->dev.platform_data; |
362 | int ret; | 362 | int ret; |
363 | 363 | ||
364 | if (icl->power) { | 364 | if (icl->power) { |
365 | ret = icl->power(&mt9m111->client->dev, 1); | 365 | ret = icl->power(&client->dev, 1); |
366 | if (ret < 0) { | 366 | if (ret < 0) { |
367 | dev_err(icd->vdev->parent, | 367 | dev_err(icd->vdev->parent, |
368 | "Platform failed to power-on the camera.\n"); | 368 | "Platform failed to power-on the camera.\n"); |
@@ -378,8 +378,9 @@ static int mt9m111_enable(struct soc_camera_device *icd) | |||
378 | 378 | ||
379 | static int mt9m111_disable(struct soc_camera_device *icd) | 379 | static int mt9m111_disable(struct soc_camera_device *icd) |
380 | { | 380 | { |
381 | struct i2c_client *client = to_i2c_client(icd->control); | ||
381 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 382 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
382 | struct soc_camera_link *icl = mt9m111->client->dev.platform_data; | 383 | struct soc_camera_link *icl = client->dev.platform_data; |
383 | int ret; | 384 | int ret; |
384 | 385 | ||
385 | ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); | 386 | ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); |
@@ -387,15 +388,15 @@ static int mt9m111_disable(struct soc_camera_device *icd) | |||
387 | mt9m111->powered = 0; | 388 | mt9m111->powered = 0; |
388 | 389 | ||
389 | if (icl->power) | 390 | if (icl->power) |
390 | icl->power(&mt9m111->client->dev, 0); | 391 | icl->power(&client->dev, 0); |
391 | 392 | ||
392 | return ret; | 393 | return ret; |
393 | } | 394 | } |
394 | 395 | ||
395 | static int mt9m111_reset(struct soc_camera_device *icd) | 396 | static int mt9m111_reset(struct soc_camera_device *icd) |
396 | { | 397 | { |
397 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 398 | struct i2c_client *client = to_i2c_client(icd->control); |
398 | struct soc_camera_link *icl = mt9m111->client->dev.platform_data; | 399 | struct soc_camera_link *icl = client->dev.platform_data; |
399 | int ret; | 400 | int ret; |
400 | 401 | ||
401 | ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); | 402 | ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); |
@@ -406,7 +407,7 @@ static int mt9m111_reset(struct soc_camera_device *icd) | |||
406 | | MT9M111_RESET_RESET_SOC); | 407 | | MT9M111_RESET_RESET_SOC); |
407 | 408 | ||
408 | if (icl->reset) | 409 | if (icl->reset) |
409 | icl->reset(&mt9m111->client->dev); | 410 | icl->reset(&client->dev); |
410 | 411 | ||
411 | return ret; | 412 | return ret; |
412 | } | 413 | } |
@@ -562,15 +563,14 @@ static int mt9m111_get_register(struct soc_camera_device *icd, | |||
562 | struct v4l2_dbg_register *reg) | 563 | struct v4l2_dbg_register *reg) |
563 | { | 564 | { |
564 | int val; | 565 | int val; |
565 | 566 | struct i2c_client *client = to_i2c_client(icd->control); | |
566 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | ||
567 | 567 | ||
568 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) | 568 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) |
569 | return -EINVAL; | 569 | return -EINVAL; |
570 | if (reg->match.addr != mt9m111->client->addr) | 570 | if (reg->match.addr != client->addr) |
571 | return -ENODEV; | 571 | return -ENODEV; |
572 | 572 | ||
573 | val = mt9m111_reg_read(icd, reg->reg); | 573 | val = mt9m111_reg_read(client, reg->reg); |
574 | reg->size = 2; | 574 | reg->size = 2; |
575 | reg->val = (u64)val; | 575 | reg->val = (u64)val; |
576 | 576 | ||
@@ -583,15 +583,15 @@ static int mt9m111_get_register(struct soc_camera_device *icd, | |||
583 | static int mt9m111_set_register(struct soc_camera_device *icd, | 583 | static int mt9m111_set_register(struct soc_camera_device *icd, |
584 | struct v4l2_dbg_register *reg) | 584 | struct v4l2_dbg_register *reg) |
585 | { | 585 | { |
586 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 586 | struct i2c_client *client = to_i2c_client(icd->control); |
587 | 587 | ||
588 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) | 588 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) |
589 | return -EINVAL; | 589 | return -EINVAL; |
590 | 590 | ||
591 | if (reg->match.addr != mt9m111->client->addr) | 591 | if (reg->match.addr != client->addr) |
592 | return -ENODEV; | 592 | return -ENODEV; |
593 | 593 | ||
594 | if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0) | 594 | if (mt9m111_reg_write(client, reg->reg, reg->val) < 0) |
595 | return -EIO; | 595 | return -EIO; |
596 | 596 | ||
597 | return 0; | 597 | return 0; |
@@ -672,6 +672,7 @@ static struct soc_camera_ops mt9m111_ops = { | |||
672 | 672 | ||
673 | static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) | 673 | static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) |
674 | { | 674 | { |
675 | struct i2c_client *client = to_i2c_client(icd->control); | ||
675 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 676 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
676 | int ret; | 677 | int ret; |
677 | 678 | ||
@@ -692,6 +693,7 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) | |||
692 | 693 | ||
693 | static int mt9m111_get_global_gain(struct soc_camera_device *icd) | 694 | static int mt9m111_get_global_gain(struct soc_camera_device *icd) |
694 | { | 695 | { |
696 | struct i2c_client *client = to_i2c_client(icd->control); | ||
695 | int data; | 697 | int data; |
696 | 698 | ||
697 | data = reg_read(GLOBAL_GAIN); | 699 | data = reg_read(GLOBAL_GAIN); |
@@ -703,6 +705,7 @@ static int mt9m111_get_global_gain(struct soc_camera_device *icd) | |||
703 | 705 | ||
704 | static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) | 706 | static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) |
705 | { | 707 | { |
708 | struct i2c_client *client = to_i2c_client(icd->control); | ||
706 | u16 val; | 709 | u16 val; |
707 | 710 | ||
708 | if (gain > 63 * 2 * 2) | 711 | if (gain > 63 * 2 * 2) |
@@ -721,6 +724,7 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) | |||
721 | 724 | ||
722 | static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) | 725 | static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) |
723 | { | 726 | { |
727 | struct i2c_client *client = to_i2c_client(icd->control); | ||
724 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 728 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
725 | int ret; | 729 | int ret; |
726 | 730 | ||
@@ -737,6 +741,7 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) | |||
737 | 741 | ||
738 | static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) | 742 | static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) |
739 | { | 743 | { |
744 | struct i2c_client *client = to_i2c_client(icd->control); | ||
740 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 745 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
741 | int ret; | 746 | int ret; |
742 | 747 | ||
@@ -754,6 +759,7 @@ static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) | |||
754 | static int mt9m111_get_control(struct soc_camera_device *icd, | 759 | static int mt9m111_get_control(struct soc_camera_device *icd, |
755 | struct v4l2_control *ctrl) | 760 | struct v4l2_control *ctrl) |
756 | { | 761 | { |
762 | struct i2c_client *client = to_i2c_client(icd->control); | ||
757 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 763 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
758 | int data; | 764 | int data; |
759 | 765 | ||
@@ -898,6 +904,7 @@ static int mt9m111_release(struct soc_camera_device *icd) | |||
898 | */ | 904 | */ |
899 | static int mt9m111_video_probe(struct soc_camera_device *icd) | 905 | static int mt9m111_video_probe(struct soc_camera_device *icd) |
900 | { | 906 | { |
907 | struct i2c_client *client = to_i2c_client(icd->control); | ||
901 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 908 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
902 | s32 data; | 909 | s32 data; |
903 | int ret; | 910 | int ret; |
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 2b0927bfd217..f72aeb7c4deb 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c | |||
@@ -76,64 +76,61 @@ struct mt9t031 { | |||
76 | u16 yskip; | 76 | u16 yskip; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static int reg_read(struct soc_camera_device *icd, const u8 reg) | 79 | static int reg_read(struct i2c_client *client, const u8 reg) |
80 | { | 80 | { |
81 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | ||
82 | struct i2c_client *client = mt9t031->client; | ||
83 | s32 data = i2c_smbus_read_word_data(client, reg); | 81 | s32 data = i2c_smbus_read_word_data(client, reg); |
84 | return data < 0 ? data : swab16(data); | 82 | return data < 0 ? data : swab16(data); |
85 | } | 83 | } |
86 | 84 | ||
87 | static int reg_write(struct soc_camera_device *icd, const u8 reg, | 85 | static int reg_write(struct i2c_client *client, const u8 reg, |
88 | const u16 data) | 86 | const u16 data) |
89 | { | 87 | { |
90 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 88 | return i2c_smbus_write_word_data(client, reg, swab16(data)); |
91 | return i2c_smbus_write_word_data(mt9t031->client, reg, swab16(data)); | ||
92 | } | 89 | } |
93 | 90 | ||
94 | static int reg_set(struct soc_camera_device *icd, const u8 reg, | 91 | static int reg_set(struct i2c_client *client, const u8 reg, |
95 | const u16 data) | 92 | const u16 data) |
96 | { | 93 | { |
97 | int ret; | 94 | int ret; |
98 | 95 | ||
99 | ret = reg_read(icd, reg); | 96 | ret = reg_read(client, reg); |
100 | if (ret < 0) | 97 | if (ret < 0) |
101 | return ret; | 98 | return ret; |
102 | return reg_write(icd, reg, ret | data); | 99 | return reg_write(client, reg, ret | data); |
103 | } | 100 | } |
104 | 101 | ||
105 | static int reg_clear(struct soc_camera_device *icd, const u8 reg, | 102 | static int reg_clear(struct i2c_client *client, const u8 reg, |
106 | const u16 data) | 103 | const u16 data) |
107 | { | 104 | { |
108 | int ret; | 105 | int ret; |
109 | 106 | ||
110 | ret = reg_read(icd, reg); | 107 | ret = reg_read(client, reg); |
111 | if (ret < 0) | 108 | if (ret < 0) |
112 | return ret; | 109 | return ret; |
113 | return reg_write(icd, reg, ret & ~data); | 110 | return reg_write(client, reg, ret & ~data); |
114 | } | 111 | } |
115 | 112 | ||
116 | static int set_shutter(struct soc_camera_device *icd, const u32 data) | 113 | static int set_shutter(struct i2c_client *client, const u32 data) |
117 | { | 114 | { |
118 | int ret; | 115 | int ret; |
119 | 116 | ||
120 | ret = reg_write(icd, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16); | 117 | ret = reg_write(client, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16); |
121 | 118 | ||
122 | if (ret >= 0) | 119 | if (ret >= 0) |
123 | ret = reg_write(icd, MT9T031_SHUTTER_WIDTH, data & 0xffff); | 120 | ret = reg_write(client, MT9T031_SHUTTER_WIDTH, data & 0xffff); |
124 | 121 | ||
125 | return ret; | 122 | return ret; |
126 | } | 123 | } |
127 | 124 | ||
128 | static int get_shutter(struct soc_camera_device *icd, u32 *data) | 125 | static int get_shutter(struct i2c_client *client, u32 *data) |
129 | { | 126 | { |
130 | int ret; | 127 | int ret; |
131 | 128 | ||
132 | ret = reg_read(icd, MT9T031_SHUTTER_WIDTH_UPPER); | 129 | ret = reg_read(client, MT9T031_SHUTTER_WIDTH_UPPER); |
133 | *data = ret << 16; | 130 | *data = ret << 16; |
134 | 131 | ||
135 | if (ret >= 0) | 132 | if (ret >= 0) |
136 | ret = reg_read(icd, MT9T031_SHUTTER_WIDTH); | 133 | ret = reg_read(client, MT9T031_SHUTTER_WIDTH); |
137 | *data |= ret & 0xffff; | 134 | *data |= ret & 0xffff; |
138 | 135 | ||
139 | return ret < 0 ? ret : 0; | 136 | return ret < 0 ? ret : 0; |
@@ -141,12 +138,12 @@ static int get_shutter(struct soc_camera_device *icd, u32 *data) | |||
141 | 138 | ||
142 | static int mt9t031_init(struct soc_camera_device *icd) | 139 | static int mt9t031_init(struct soc_camera_device *icd) |
143 | { | 140 | { |
144 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 141 | struct i2c_client *client = to_i2c_client(icd->control); |
145 | struct soc_camera_link *icl = mt9t031->client->dev.platform_data; | 142 | struct soc_camera_link *icl = client->dev.platform_data; |
146 | int ret; | 143 | int ret; |
147 | 144 | ||
148 | if (icl->power) { | 145 | if (icl->power) { |
149 | ret = icl->power(&mt9t031->client->dev, 1); | 146 | ret = icl->power(&client->dev, 1); |
150 | if (ret < 0) { | 147 | if (ret < 0) { |
151 | dev_err(icd->vdev->parent, | 148 | dev_err(icd->vdev->parent, |
152 | "Platform failed to power-on the camera.\n"); | 149 | "Platform failed to power-on the camera.\n"); |
@@ -155,44 +152,48 @@ static int mt9t031_init(struct soc_camera_device *icd) | |||
155 | } | 152 | } |
156 | 153 | ||
157 | /* Disable chip output, synchronous option update */ | 154 | /* Disable chip output, synchronous option update */ |
158 | ret = reg_write(icd, MT9T031_RESET, 1); | 155 | ret = reg_write(client, MT9T031_RESET, 1); |
159 | if (ret >= 0) | 156 | if (ret >= 0) |
160 | ret = reg_write(icd, MT9T031_RESET, 0); | 157 | ret = reg_write(client, MT9T031_RESET, 0); |
161 | if (ret >= 0) | 158 | if (ret >= 0) |
162 | ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2); | 159 | ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); |
163 | 160 | ||
164 | if (ret < 0 && icl->power) | 161 | if (ret < 0 && icl->power) |
165 | icl->power(&mt9t031->client->dev, 0); | 162 | icl->power(&client->dev, 0); |
166 | 163 | ||
167 | return ret >= 0 ? 0 : -EIO; | 164 | return ret >= 0 ? 0 : -EIO; |
168 | } | 165 | } |
169 | 166 | ||
170 | static int mt9t031_release(struct soc_camera_device *icd) | 167 | static int mt9t031_release(struct soc_camera_device *icd) |
171 | { | 168 | { |
172 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 169 | struct i2c_client *client = to_i2c_client(icd->control); |
173 | struct soc_camera_link *icl = mt9t031->client->dev.platform_data; | 170 | struct soc_camera_link *icl = client->dev.platform_data; |
174 | 171 | ||
175 | /* Disable the chip */ | 172 | /* Disable the chip */ |
176 | reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2); | 173 | reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); |
177 | 174 | ||
178 | if (icl->power) | 175 | if (icl->power) |
179 | icl->power(&mt9t031->client->dev, 0); | 176 | icl->power(&client->dev, 0); |
180 | 177 | ||
181 | return 0; | 178 | return 0; |
182 | } | 179 | } |
183 | 180 | ||
184 | static int mt9t031_start_capture(struct soc_camera_device *icd) | 181 | static int mt9t031_start_capture(struct soc_camera_device *icd) |
185 | { | 182 | { |
183 | struct i2c_client *client = to_i2c_client(icd->control); | ||
184 | |||
186 | /* Switch to master "normal" mode */ | 185 | /* Switch to master "normal" mode */ |
187 | if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 2) < 0) | 186 | if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0) |
188 | return -EIO; | 187 | return -EIO; |
189 | return 0; | 188 | return 0; |
190 | } | 189 | } |
191 | 190 | ||
192 | static int mt9t031_stop_capture(struct soc_camera_device *icd) | 191 | static int mt9t031_stop_capture(struct soc_camera_device *icd) |
193 | { | 192 | { |
193 | struct i2c_client *client = to_i2c_client(icd->control); | ||
194 | |||
194 | /* Stop sensor readout */ | 195 | /* Stop sensor readout */ |
195 | if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2) < 0) | 196 | if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0) |
196 | return -EIO; | 197 | return -EIO; |
197 | return 0; | 198 | return 0; |
198 | } | 199 | } |
@@ -200,14 +201,16 @@ static int mt9t031_stop_capture(struct soc_camera_device *icd) | |||
200 | static int mt9t031_set_bus_param(struct soc_camera_device *icd, | 201 | static int mt9t031_set_bus_param(struct soc_camera_device *icd, |
201 | unsigned long flags) | 202 | unsigned long flags) |
202 | { | 203 | { |
204 | struct i2c_client *client = to_i2c_client(icd->control); | ||
205 | |||
203 | /* The caller should have queried our parameters, check anyway */ | 206 | /* The caller should have queried our parameters, check anyway */ |
204 | if (flags & ~MT9T031_BUS_PARAM) | 207 | if (flags & ~MT9T031_BUS_PARAM) |
205 | return -EINVAL; | 208 | return -EINVAL; |
206 | 209 | ||
207 | if (flags & SOCAM_PCLK_SAMPLE_FALLING) | 210 | if (flags & SOCAM_PCLK_SAMPLE_FALLING) |
208 | reg_clear(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); | 211 | reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); |
209 | else | 212 | else |
210 | reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); | 213 | reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); |
211 | 214 | ||
212 | return 0; | 215 | return 0; |
213 | } | 216 | } |
@@ -235,6 +238,7 @@ static void recalculate_limits(struct soc_camera_device *icd, | |||
235 | static int mt9t031_set_params(struct soc_camera_device *icd, | 238 | static int mt9t031_set_params(struct soc_camera_device *icd, |
236 | struct v4l2_rect *rect, u16 xskip, u16 yskip) | 239 | struct v4l2_rect *rect, u16 xskip, u16 yskip) |
237 | { | 240 | { |
241 | struct i2c_client *client = to_i2c_client(icd->control); | ||
238 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 242 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); |
239 | int ret; | 243 | int ret; |
240 | u16 xbin, ybin, width, height, left, top; | 244 | u16 xbin, ybin, width, height, left, top; |
@@ -277,22 +281,22 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
277 | } | 281 | } |
278 | 282 | ||
279 | /* Disable register update, reconfigure atomically */ | 283 | /* Disable register update, reconfigure atomically */ |
280 | ret = reg_set(icd, MT9T031_OUTPUT_CONTROL, 1); | 284 | ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1); |
281 | if (ret < 0) | 285 | if (ret < 0) |
282 | return ret; | 286 | return ret; |
283 | 287 | ||
284 | /* Blanking and start values - default... */ | 288 | /* Blanking and start values - default... */ |
285 | ret = reg_write(icd, MT9T031_HORIZONTAL_BLANKING, hblank); | 289 | ret = reg_write(client, MT9T031_HORIZONTAL_BLANKING, hblank); |
286 | if (ret >= 0) | 290 | if (ret >= 0) |
287 | ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank); | 291 | ret = reg_write(client, MT9T031_VERTICAL_BLANKING, vblank); |
288 | 292 | ||
289 | if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) { | 293 | if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) { |
290 | /* Binning, skipping */ | 294 | /* Binning, skipping */ |
291 | if (ret >= 0) | 295 | if (ret >= 0) |
292 | ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE, | 296 | ret = reg_write(client, MT9T031_COLUMN_ADDRESS_MODE, |
293 | ((xbin - 1) << 4) | (xskip - 1)); | 297 | ((xbin - 1) << 4) | (xskip - 1)); |
294 | if (ret >= 0) | 298 | if (ret >= 0) |
295 | ret = reg_write(icd, MT9T031_ROW_ADDRESS_MODE, | 299 | ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE, |
296 | ((ybin - 1) << 4) | (yskip - 1)); | 300 | ((ybin - 1) << 4) | (yskip - 1)); |
297 | } | 301 | } |
298 | dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top); | 302 | dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top); |
@@ -300,16 +304,16 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
300 | /* The caller provides a supported format, as guaranteed by | 304 | /* The caller provides a supported format, as guaranteed by |
301 | * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ | 305 | * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ |
302 | if (ret >= 0) | 306 | if (ret >= 0) |
303 | ret = reg_write(icd, MT9T031_COLUMN_START, left); | 307 | ret = reg_write(client, MT9T031_COLUMN_START, left); |
304 | if (ret >= 0) | 308 | if (ret >= 0) |
305 | ret = reg_write(icd, MT9T031_ROW_START, top); | 309 | ret = reg_write(client, MT9T031_ROW_START, top); |
306 | if (ret >= 0) | 310 | if (ret >= 0) |
307 | ret = reg_write(icd, MT9T031_WINDOW_WIDTH, width - 1); | 311 | ret = reg_write(client, MT9T031_WINDOW_WIDTH, width - 1); |
308 | if (ret >= 0) | 312 | if (ret >= 0) |
309 | ret = reg_write(icd, MT9T031_WINDOW_HEIGHT, | 313 | ret = reg_write(client, MT9T031_WINDOW_HEIGHT, |
310 | height + icd->y_skip_top - 1); | 314 | height + icd->y_skip_top - 1); |
311 | if (ret >= 0 && mt9t031->autoexposure) { | 315 | if (ret >= 0 && mt9t031->autoexposure) { |
312 | ret = set_shutter(icd, height + icd->y_skip_top + vblank); | 316 | ret = set_shutter(client, height + icd->y_skip_top + vblank); |
313 | if (ret >= 0) { | 317 | if (ret >= 0) { |
314 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; | 318 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; |
315 | const struct v4l2_queryctrl *qctrl = | 319 | const struct v4l2_queryctrl *qctrl = |
@@ -324,7 +328,7 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
324 | 328 | ||
325 | /* Re-enable register update, commit all changes */ | 329 | /* Re-enable register update, commit all changes */ |
326 | if (ret >= 0) | 330 | if (ret >= 0) |
327 | ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 1); | 331 | ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1); |
328 | 332 | ||
329 | return ret < 0 ? ret : 0; | 333 | return ret < 0 ? ret : 0; |
330 | } | 334 | } |
@@ -417,15 +421,15 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd, | |||
417 | static int mt9t031_get_register(struct soc_camera_device *icd, | 421 | static int mt9t031_get_register(struct soc_camera_device *icd, |
418 | struct v4l2_dbg_register *reg) | 422 | struct v4l2_dbg_register *reg) |
419 | { | 423 | { |
420 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 424 | struct i2c_client *client = to_i2c_client(icd->control); |
421 | 425 | ||
422 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 426 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
423 | return -EINVAL; | 427 | return -EINVAL; |
424 | 428 | ||
425 | if (reg->match.addr != mt9t031->client->addr) | 429 | if (reg->match.addr != client->addr) |
426 | return -ENODEV; | 430 | return -ENODEV; |
427 | 431 | ||
428 | reg->val = reg_read(icd, reg->reg); | 432 | reg->val = reg_read(client, reg->reg); |
429 | 433 | ||
430 | if (reg->val > 0xffff) | 434 | if (reg->val > 0xffff) |
431 | return -EIO; | 435 | return -EIO; |
@@ -436,15 +440,15 @@ static int mt9t031_get_register(struct soc_camera_device *icd, | |||
436 | static int mt9t031_set_register(struct soc_camera_device *icd, | 440 | static int mt9t031_set_register(struct soc_camera_device *icd, |
437 | struct v4l2_dbg_register *reg) | 441 | struct v4l2_dbg_register *reg) |
438 | { | 442 | { |
439 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 443 | struct i2c_client *client = to_i2c_client(icd->control); |
440 | 444 | ||
441 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 445 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
442 | return -EINVAL; | 446 | return -EINVAL; |
443 | 447 | ||
444 | if (reg->match.addr != mt9t031->client->addr) | 448 | if (reg->match.addr != client->addr) |
445 | return -ENODEV; | 449 | return -ENODEV; |
446 | 450 | ||
447 | if (reg_write(icd, reg->reg, reg->val) < 0) | 451 | if (reg_write(client, reg->reg, reg->val) < 0) |
448 | return -EIO; | 452 | return -EIO; |
449 | 453 | ||
450 | return 0; | 454 | return 0; |
@@ -528,18 +532,19 @@ static struct soc_camera_ops mt9t031_ops = { | |||
528 | 532 | ||
529 | static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 533 | static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
530 | { | 534 | { |
535 | struct i2c_client *client = to_i2c_client(icd->control); | ||
531 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 536 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); |
532 | int data; | 537 | int data; |
533 | 538 | ||
534 | switch (ctrl->id) { | 539 | switch (ctrl->id) { |
535 | case V4L2_CID_VFLIP: | 540 | case V4L2_CID_VFLIP: |
536 | data = reg_read(icd, MT9T031_READ_MODE_2); | 541 | data = reg_read(client, MT9T031_READ_MODE_2); |
537 | if (data < 0) | 542 | if (data < 0) |
538 | return -EIO; | 543 | return -EIO; |
539 | ctrl->value = !!(data & 0x8000); | 544 | ctrl->value = !!(data & 0x8000); |
540 | break; | 545 | break; |
541 | case V4L2_CID_HFLIP: | 546 | case V4L2_CID_HFLIP: |
542 | data = reg_read(icd, MT9T031_READ_MODE_2); | 547 | data = reg_read(client, MT9T031_READ_MODE_2); |
543 | if (data < 0) | 548 | if (data < 0) |
544 | return -EIO; | 549 | return -EIO; |
545 | ctrl->value = !!(data & 0x4000); | 550 | ctrl->value = !!(data & 0x4000); |
@@ -553,6 +558,7 @@ static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_contro | |||
553 | 558 | ||
554 | static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 559 | static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
555 | { | 560 | { |
561 | struct i2c_client *client = to_i2c_client(icd->control); | ||
556 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 562 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); |
557 | const struct v4l2_queryctrl *qctrl; | 563 | const struct v4l2_queryctrl *qctrl; |
558 | int data; | 564 | int data; |
@@ -565,17 +571,17 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
565 | switch (ctrl->id) { | 571 | switch (ctrl->id) { |
566 | case V4L2_CID_VFLIP: | 572 | case V4L2_CID_VFLIP: |
567 | if (ctrl->value) | 573 | if (ctrl->value) |
568 | data = reg_set(icd, MT9T031_READ_MODE_2, 0x8000); | 574 | data = reg_set(client, MT9T031_READ_MODE_2, 0x8000); |
569 | else | 575 | else |
570 | data = reg_clear(icd, MT9T031_READ_MODE_2, 0x8000); | 576 | data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000); |
571 | if (data < 0) | 577 | if (data < 0) |
572 | return -EIO; | 578 | return -EIO; |
573 | break; | 579 | break; |
574 | case V4L2_CID_HFLIP: | 580 | case V4L2_CID_HFLIP: |
575 | if (ctrl->value) | 581 | if (ctrl->value) |
576 | data = reg_set(icd, MT9T031_READ_MODE_2, 0x4000); | 582 | data = reg_set(client, MT9T031_READ_MODE_2, 0x4000); |
577 | else | 583 | else |
578 | data = reg_clear(icd, MT9T031_READ_MODE_2, 0x4000); | 584 | data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000); |
579 | if (data < 0) | 585 | if (data < 0) |
580 | return -EIO; | 586 | return -EIO; |
581 | break; | 587 | break; |
@@ -589,7 +595,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
589 | data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; | 595 | data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; |
590 | 596 | ||
591 | dev_dbg(&icd->dev, "Setting gain %d\n", data); | 597 | dev_dbg(&icd->dev, "Setting gain %d\n", data); |
592 | data = reg_write(icd, MT9T031_GLOBAL_GAIN, data); | 598 | data = reg_write(client, MT9T031_GLOBAL_GAIN, data); |
593 | if (data < 0) | 599 | if (data < 0) |
594 | return -EIO; | 600 | return -EIO; |
595 | } else { | 601 | } else { |
@@ -609,8 +615,8 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
609 | data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60; | 615 | data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60; |
610 | 616 | ||
611 | dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n", | 617 | dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n", |
612 | reg_read(icd, MT9T031_GLOBAL_GAIN), data); | 618 | reg_read(client, MT9T031_GLOBAL_GAIN), data); |
613 | data = reg_write(icd, MT9T031_GLOBAL_GAIN, data); | 619 | data = reg_write(client, MT9T031_GLOBAL_GAIN, data); |
614 | if (data < 0) | 620 | if (data < 0) |
615 | return -EIO; | 621 | return -EIO; |
616 | } | 622 | } |
@@ -628,10 +634,10 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
628 | range / 2) / range + 1; | 634 | range / 2) / range + 1; |
629 | u32 old; | 635 | u32 old; |
630 | 636 | ||
631 | get_shutter(icd, &old); | 637 | get_shutter(client, &old); |
632 | dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n", | 638 | dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n", |
633 | old, shutter); | 639 | old, shutter); |
634 | if (set_shutter(icd, shutter) < 0) | 640 | if (set_shutter(client, shutter) < 0) |
635 | return -EIO; | 641 | return -EIO; |
636 | icd->exposure = ctrl->value; | 642 | icd->exposure = ctrl->value; |
637 | mt9t031->autoexposure = 0; | 643 | mt9t031->autoexposure = 0; |
@@ -641,7 +647,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
641 | if (ctrl->value) { | 647 | if (ctrl->value) { |
642 | const u16 vblank = MT9T031_VERTICAL_BLANK; | 648 | const u16 vblank = MT9T031_VERTICAL_BLANK; |
643 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; | 649 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; |
644 | if (set_shutter(icd, icd->height + | 650 | if (set_shutter(client, icd->height + |
645 | icd->y_skip_top + vblank) < 0) | 651 | icd->y_skip_top + vblank) < 0) |
646 | return -EIO; | 652 | return -EIO; |
647 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | 653 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); |
@@ -661,6 +667,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
661 | * this wasn't our capture interface, so, we wait for the right one */ | 667 | * this wasn't our capture interface, so, we wait for the right one */ |
662 | static int mt9t031_video_probe(struct soc_camera_device *icd) | 668 | static int mt9t031_video_probe(struct soc_camera_device *icd) |
663 | { | 669 | { |
670 | struct i2c_client *client = to_i2c_client(icd->control); | ||
664 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 671 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); |
665 | s32 data; | 672 | s32 data; |
666 | int ret; | 673 | int ret; |
@@ -672,11 +679,11 @@ static int mt9t031_video_probe(struct soc_camera_device *icd) | |||
672 | return -ENODEV; | 679 | return -ENODEV; |
673 | 680 | ||
674 | /* Enable the chip */ | 681 | /* Enable the chip */ |
675 | data = reg_write(icd, MT9T031_CHIP_ENABLE, 1); | 682 | data = reg_write(client, MT9T031_CHIP_ENABLE, 1); |
676 | dev_dbg(&icd->dev, "write: %d\n", data); | 683 | dev_dbg(&icd->dev, "write: %d\n", data); |
677 | 684 | ||
678 | /* Read out the chip version register */ | 685 | /* Read out the chip version register */ |
679 | data = reg_read(icd, MT9T031_CHIP_VERSION); | 686 | data = reg_read(client, MT9T031_CHIP_VERSION); |
680 | 687 | ||
681 | switch (data) { | 688 | switch (data) { |
682 | case 0x1621: | 689 | case 0x1621: |
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 4d3b4813c322..be20d312b1dc 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c | |||
@@ -91,51 +91,49 @@ struct mt9v022 { | |||
91 | u16 chip_control; | 91 | u16 chip_control; |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static int reg_read(struct soc_camera_device *icd, const u8 reg) | 94 | static int reg_read(struct i2c_client *client, const u8 reg) |
95 | { | 95 | { |
96 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
97 | struct i2c_client *client = mt9v022->client; | ||
98 | s32 data = i2c_smbus_read_word_data(client, reg); | 96 | s32 data = i2c_smbus_read_word_data(client, reg); |
99 | return data < 0 ? data : swab16(data); | 97 | return data < 0 ? data : swab16(data); |
100 | } | 98 | } |
101 | 99 | ||
102 | static int reg_write(struct soc_camera_device *icd, const u8 reg, | 100 | static int reg_write(struct i2c_client *client, const u8 reg, |
103 | const u16 data) | 101 | const u16 data) |
104 | { | 102 | { |
105 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 103 | return i2c_smbus_write_word_data(client, reg, swab16(data)); |
106 | return i2c_smbus_write_word_data(mt9v022->client, reg, swab16(data)); | ||
107 | } | 104 | } |
108 | 105 | ||
109 | static int reg_set(struct soc_camera_device *icd, const u8 reg, | 106 | static int reg_set(struct i2c_client *client, const u8 reg, |
110 | const u16 data) | 107 | const u16 data) |
111 | { | 108 | { |
112 | int ret; | 109 | int ret; |
113 | 110 | ||
114 | ret = reg_read(icd, reg); | 111 | ret = reg_read(client, reg); |
115 | if (ret < 0) | 112 | if (ret < 0) |
116 | return ret; | 113 | return ret; |
117 | return reg_write(icd, reg, ret | data); | 114 | return reg_write(client, reg, ret | data); |
118 | } | 115 | } |
119 | 116 | ||
120 | static int reg_clear(struct soc_camera_device *icd, const u8 reg, | 117 | static int reg_clear(struct i2c_client *client, const u8 reg, |
121 | const u16 data) | 118 | const u16 data) |
122 | { | 119 | { |
123 | int ret; | 120 | int ret; |
124 | 121 | ||
125 | ret = reg_read(icd, reg); | 122 | ret = reg_read(client, reg); |
126 | if (ret < 0) | 123 | if (ret < 0) |
127 | return ret; | 124 | return ret; |
128 | return reg_write(icd, reg, ret & ~data); | 125 | return reg_write(client, reg, ret & ~data); |
129 | } | 126 | } |
130 | 127 | ||
131 | static int mt9v022_init(struct soc_camera_device *icd) | 128 | static int mt9v022_init(struct soc_camera_device *icd) |
132 | { | 129 | { |
130 | struct i2c_client *client = to_i2c_client(icd->control); | ||
133 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 131 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
134 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | 132 | struct soc_camera_link *icl = client->dev.platform_data; |
135 | int ret; | 133 | int ret; |
136 | 134 | ||
137 | if (icl->power) { | 135 | if (icl->power) { |
138 | ret = icl->power(&mt9v022->client->dev, 1); | 136 | ret = icl->power(&client->dev, 1); |
139 | if (ret < 0) { | 137 | if (ret < 0) { |
140 | dev_err(icd->vdev->parent, | 138 | dev_err(icd->vdev->parent, |
141 | "Platform failed to power-on the camera.\n"); | 139 | "Platform failed to power-on the camera.\n"); |
@@ -148,27 +146,27 @@ static int mt9v022_init(struct soc_camera_device *icd) | |||
148 | * if available. Soft reset is done in video_probe(). | 146 | * if available. Soft reset is done in video_probe(). |
149 | */ | 147 | */ |
150 | if (icl->reset) | 148 | if (icl->reset) |
151 | icl->reset(&mt9v022->client->dev); | 149 | icl->reset(&client->dev); |
152 | 150 | ||
153 | /* Almost the default mode: master, parallel, simultaneous, and an | 151 | /* Almost the default mode: master, parallel, simultaneous, and an |
154 | * undocumented bit 0x200, which is present in table 7, but not in 8, | 152 | * undocumented bit 0x200, which is present in table 7, but not in 8, |
155 | * plus snapshot mode to disable scan for now */ | 153 | * plus snapshot mode to disable scan for now */ |
156 | mt9v022->chip_control |= 0x10; | 154 | mt9v022->chip_control |= 0x10; |
157 | ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); | 155 | ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control); |
158 | if (!ret) | 156 | if (!ret) |
159 | ret = reg_write(icd, MT9V022_READ_MODE, 0x300); | 157 | ret = reg_write(client, MT9V022_READ_MODE, 0x300); |
160 | 158 | ||
161 | /* All defaults */ | 159 | /* All defaults */ |
162 | if (!ret) | 160 | if (!ret) |
163 | /* AEC, AGC on */ | 161 | /* AEC, AGC on */ |
164 | ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3); | 162 | ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3); |
165 | if (!ret) | 163 | if (!ret) |
166 | ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); | 164 | ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); |
167 | if (!ret) | 165 | if (!ret) |
168 | /* default - auto */ | 166 | /* default - auto */ |
169 | ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); | 167 | ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); |
170 | if (!ret) | 168 | if (!ret) |
171 | ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0); | 169 | ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0); |
172 | 170 | ||
173 | return ret; | 171 | return ret; |
174 | } | 172 | } |
@@ -186,10 +184,11 @@ static int mt9v022_release(struct soc_camera_device *icd) | |||
186 | 184 | ||
187 | static int mt9v022_start_capture(struct soc_camera_device *icd) | 185 | static int mt9v022_start_capture(struct soc_camera_device *icd) |
188 | { | 186 | { |
187 | struct i2c_client *client = to_i2c_client(icd->control); | ||
189 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 188 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
190 | /* Switch to master "normal" mode */ | 189 | /* Switch to master "normal" mode */ |
191 | mt9v022->chip_control &= ~0x10; | 190 | mt9v022->chip_control &= ~0x10; |
192 | if (reg_write(icd, MT9V022_CHIP_CONTROL, | 191 | if (reg_write(client, MT9V022_CHIP_CONTROL, |
193 | mt9v022->chip_control) < 0) | 192 | mt9v022->chip_control) < 0) |
194 | return -EIO; | 193 | return -EIO; |
195 | return 0; | 194 | return 0; |
@@ -197,10 +196,11 @@ static int mt9v022_start_capture(struct soc_camera_device *icd) | |||
197 | 196 | ||
198 | static int mt9v022_stop_capture(struct soc_camera_device *icd) | 197 | static int mt9v022_stop_capture(struct soc_camera_device *icd) |
199 | { | 198 | { |
199 | struct i2c_client *client = to_i2c_client(icd->control); | ||
200 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 200 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
201 | /* Switch to snapshot mode */ | 201 | /* Switch to snapshot mode */ |
202 | mt9v022->chip_control |= 0x10; | 202 | mt9v022->chip_control |= 0x10; |
203 | if (reg_write(icd, MT9V022_CHIP_CONTROL, | 203 | if (reg_write(client, MT9V022_CHIP_CONTROL, |
204 | mt9v022->chip_control) < 0) | 204 | mt9v022->chip_control) < 0) |
205 | return -EIO; | 205 | return -EIO; |
206 | return 0; | 206 | return 0; |
@@ -209,8 +209,9 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd) | |||
209 | static int mt9v022_set_bus_param(struct soc_camera_device *icd, | 209 | static int mt9v022_set_bus_param(struct soc_camera_device *icd, |
210 | unsigned long flags) | 210 | unsigned long flags) |
211 | { | 211 | { |
212 | struct i2c_client *client = to_i2c_client(icd->control); | ||
212 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 213 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
213 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | 214 | struct soc_camera_link *icl = client->dev.platform_data; |
214 | unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; | 215 | unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; |
215 | int ret; | 216 | int ret; |
216 | u16 pixclk = 0; | 217 | u16 pixclk = 0; |
@@ -243,14 +244,14 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd, | |||
243 | if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH)) | 244 | if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH)) |
244 | pixclk |= 0x2; | 245 | pixclk |= 0x2; |
245 | 246 | ||
246 | ret = reg_write(icd, MT9V022_PIXCLK_FV_LV, pixclk); | 247 | ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk); |
247 | if (ret < 0) | 248 | if (ret < 0) |
248 | return ret; | 249 | return ret; |
249 | 250 | ||
250 | if (!(flags & SOCAM_MASTER)) | 251 | if (!(flags & SOCAM_MASTER)) |
251 | mt9v022->chip_control &= ~0x8; | 252 | mt9v022->chip_control &= ~0x8; |
252 | 253 | ||
253 | ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); | 254 | ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control); |
254 | if (ret < 0) | 255 | if (ret < 0) |
255 | return ret; | 256 | return ret; |
256 | 257 | ||
@@ -282,35 +283,36 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) | |||
282 | static int mt9v022_set_crop(struct soc_camera_device *icd, | 283 | static int mt9v022_set_crop(struct soc_camera_device *icd, |
283 | struct v4l2_rect *rect) | 284 | struct v4l2_rect *rect) |
284 | { | 285 | { |
286 | struct i2c_client *client = to_i2c_client(icd->control); | ||
285 | int ret; | 287 | int ret; |
286 | 288 | ||
287 | /* Like in example app. Contradicts the datasheet though */ | 289 | /* Like in example app. Contradicts the datasheet though */ |
288 | ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | 290 | ret = reg_read(client, MT9V022_AEC_AGC_ENABLE); |
289 | if (ret >= 0) { | 291 | if (ret >= 0) { |
290 | if (ret & 1) /* Autoexposure */ | 292 | if (ret & 1) /* Autoexposure */ |
291 | ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, | 293 | ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, |
292 | rect->height + icd->y_skip_top + 43); | 294 | rect->height + icd->y_skip_top + 43); |
293 | else | 295 | else |
294 | ret = reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, | 296 | ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, |
295 | rect->height + icd->y_skip_top + 43); | 297 | rect->height + icd->y_skip_top + 43); |
296 | } | 298 | } |
297 | /* Setup frame format: defaults apart from width and height */ | 299 | /* Setup frame format: defaults apart from width and height */ |
298 | if (!ret) | 300 | if (!ret) |
299 | ret = reg_write(icd, MT9V022_COLUMN_START, rect->left); | 301 | ret = reg_write(client, MT9V022_COLUMN_START, rect->left); |
300 | if (!ret) | 302 | if (!ret) |
301 | ret = reg_write(icd, MT9V022_ROW_START, rect->top); | 303 | ret = reg_write(client, MT9V022_ROW_START, rect->top); |
302 | if (!ret) | 304 | if (!ret) |
303 | /* Default 94, Phytec driver says: | 305 | /* Default 94, Phytec driver says: |
304 | * "width + horizontal blank >= 660" */ | 306 | * "width + horizontal blank >= 660" */ |
305 | ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING, | 307 | ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING, |
306 | rect->width > 660 - 43 ? 43 : | 308 | rect->width > 660 - 43 ? 43 : |
307 | 660 - rect->width); | 309 | 660 - rect->width); |
308 | if (!ret) | 310 | if (!ret) |
309 | ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45); | 311 | ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45); |
310 | if (!ret) | 312 | if (!ret) |
311 | ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width); | 313 | ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width); |
312 | if (!ret) | 314 | if (!ret) |
313 | ret = reg_write(icd, MT9V022_WINDOW_HEIGHT, | 315 | ret = reg_write(client, MT9V022_WINDOW_HEIGHT, |
314 | rect->height + icd->y_skip_top); | 316 | rect->height + icd->y_skip_top); |
315 | 317 | ||
316 | if (ret < 0) | 318 | if (ret < 0) |
@@ -396,16 +398,16 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd, | |||
396 | static int mt9v022_get_register(struct soc_camera_device *icd, | 398 | static int mt9v022_get_register(struct soc_camera_device *icd, |
397 | struct v4l2_dbg_register *reg) | 399 | struct v4l2_dbg_register *reg) |
398 | { | 400 | { |
399 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 401 | struct i2c_client *client = to_i2c_client(icd->control); |
400 | 402 | ||
401 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 403 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
402 | return -EINVAL; | 404 | return -EINVAL; |
403 | 405 | ||
404 | if (reg->match.addr != mt9v022->client->addr) | 406 | if (reg->match.addr != client->addr) |
405 | return -ENODEV; | 407 | return -ENODEV; |
406 | 408 | ||
407 | reg->size = 2; | 409 | reg->size = 2; |
408 | reg->val = reg_read(icd, reg->reg); | 410 | reg->val = reg_read(client, reg->reg); |
409 | 411 | ||
410 | if (reg->val > 0xffff) | 412 | if (reg->val > 0xffff) |
411 | return -EIO; | 413 | return -EIO; |
@@ -416,15 +418,15 @@ static int mt9v022_get_register(struct soc_camera_device *icd, | |||
416 | static int mt9v022_set_register(struct soc_camera_device *icd, | 418 | static int mt9v022_set_register(struct soc_camera_device *icd, |
417 | struct v4l2_dbg_register *reg) | 419 | struct v4l2_dbg_register *reg) |
418 | { | 420 | { |
419 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 421 | struct i2c_client *client = to_i2c_client(icd->control); |
420 | 422 | ||
421 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 423 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
422 | return -EINVAL; | 424 | return -EINVAL; |
423 | 425 | ||
424 | if (reg->match.addr != mt9v022->client->addr) | 426 | if (reg->match.addr != client->addr) |
425 | return -ENODEV; | 427 | return -ENODEV; |
426 | 428 | ||
427 | if (reg_write(icd, reg->reg, reg->val) < 0) | 429 | if (reg_write(client, reg->reg, reg->val) < 0) |
428 | return -EIO; | 430 | return -EIO; |
429 | 431 | ||
430 | return 0; | 432 | return 0; |
@@ -517,29 +519,30 @@ static struct soc_camera_ops mt9v022_ops = { | |||
517 | static int mt9v022_get_control(struct soc_camera_device *icd, | 519 | static int mt9v022_get_control(struct soc_camera_device *icd, |
518 | struct v4l2_control *ctrl) | 520 | struct v4l2_control *ctrl) |
519 | { | 521 | { |
522 | struct i2c_client *client = to_i2c_client(icd->control); | ||
520 | int data; | 523 | int data; |
521 | 524 | ||
522 | switch (ctrl->id) { | 525 | switch (ctrl->id) { |
523 | case V4L2_CID_VFLIP: | 526 | case V4L2_CID_VFLIP: |
524 | data = reg_read(icd, MT9V022_READ_MODE); | 527 | data = reg_read(client, MT9V022_READ_MODE); |
525 | if (data < 0) | 528 | if (data < 0) |
526 | return -EIO; | 529 | return -EIO; |
527 | ctrl->value = !!(data & 0x10); | 530 | ctrl->value = !!(data & 0x10); |
528 | break; | 531 | break; |
529 | case V4L2_CID_HFLIP: | 532 | case V4L2_CID_HFLIP: |
530 | data = reg_read(icd, MT9V022_READ_MODE); | 533 | data = reg_read(client, MT9V022_READ_MODE); |
531 | if (data < 0) | 534 | if (data < 0) |
532 | return -EIO; | 535 | return -EIO; |
533 | ctrl->value = !!(data & 0x20); | 536 | ctrl->value = !!(data & 0x20); |
534 | break; | 537 | break; |
535 | case V4L2_CID_EXPOSURE_AUTO: | 538 | case V4L2_CID_EXPOSURE_AUTO: |
536 | data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | 539 | data = reg_read(client, MT9V022_AEC_AGC_ENABLE); |
537 | if (data < 0) | 540 | if (data < 0) |
538 | return -EIO; | 541 | return -EIO; |
539 | ctrl->value = !!(data & 0x1); | 542 | ctrl->value = !!(data & 0x1); |
540 | break; | 543 | break; |
541 | case V4L2_CID_AUTOGAIN: | 544 | case V4L2_CID_AUTOGAIN: |
542 | data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | 545 | data = reg_read(client, MT9V022_AEC_AGC_ENABLE); |
543 | if (data < 0) | 546 | if (data < 0) |
544 | return -EIO; | 547 | return -EIO; |
545 | ctrl->value = !!(data & 0x2); | 548 | ctrl->value = !!(data & 0x2); |
@@ -552,6 +555,7 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
552 | struct v4l2_control *ctrl) | 555 | struct v4l2_control *ctrl) |
553 | { | 556 | { |
554 | int data; | 557 | int data; |
558 | struct i2c_client *client = to_i2c_client(icd->control); | ||
555 | const struct v4l2_queryctrl *qctrl; | 559 | const struct v4l2_queryctrl *qctrl; |
556 | 560 | ||
557 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); | 561 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); |
@@ -562,17 +566,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
562 | switch (ctrl->id) { | 566 | switch (ctrl->id) { |
563 | case V4L2_CID_VFLIP: | 567 | case V4L2_CID_VFLIP: |
564 | if (ctrl->value) | 568 | if (ctrl->value) |
565 | data = reg_set(icd, MT9V022_READ_MODE, 0x10); | 569 | data = reg_set(client, MT9V022_READ_MODE, 0x10); |
566 | else | 570 | else |
567 | data = reg_clear(icd, MT9V022_READ_MODE, 0x10); | 571 | data = reg_clear(client, MT9V022_READ_MODE, 0x10); |
568 | if (data < 0) | 572 | if (data < 0) |
569 | return -EIO; | 573 | return -EIO; |
570 | break; | 574 | break; |
571 | case V4L2_CID_HFLIP: | 575 | case V4L2_CID_HFLIP: |
572 | if (ctrl->value) | 576 | if (ctrl->value) |
573 | data = reg_set(icd, MT9V022_READ_MODE, 0x20); | 577 | data = reg_set(client, MT9V022_READ_MODE, 0x20); |
574 | else | 578 | else |
575 | data = reg_clear(icd, MT9V022_READ_MODE, 0x20); | 579 | data = reg_clear(client, MT9V022_READ_MODE, 0x20); |
576 | if (data < 0) | 580 | if (data < 0) |
577 | return -EIO; | 581 | return -EIO; |
578 | break; | 582 | break; |
@@ -593,12 +597,12 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
593 | /* The user wants to set gain manually, hope, she | 597 | /* The user wants to set gain manually, hope, she |
594 | * knows, what she's doing... Switch AGC off. */ | 598 | * knows, what she's doing... Switch AGC off. */ |
595 | 599 | ||
596 | if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) | 600 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) |
597 | return -EIO; | 601 | return -EIO; |
598 | 602 | ||
599 | dev_info(&icd->dev, "Setting gain from %d to %lu\n", | 603 | dev_info(&icd->dev, "Setting gain from %d to %lu\n", |
600 | reg_read(icd, MT9V022_ANALOG_GAIN), gain); | 604 | reg_read(client, MT9V022_ANALOG_GAIN), gain); |
601 | if (reg_write(icd, MT9V022_ANALOG_GAIN, gain) < 0) | 605 | if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0) |
602 | return -EIO; | 606 | return -EIO; |
603 | icd->gain = ctrl->value; | 607 | icd->gain = ctrl->value; |
604 | } | 608 | } |
@@ -614,13 +618,13 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
614 | /* The user wants to set shutter width manually, hope, | 618 | /* The user wants to set shutter width manually, hope, |
615 | * she knows, what she's doing... Switch AEC off. */ | 619 | * she knows, what she's doing... Switch AEC off. */ |
616 | 620 | ||
617 | if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) | 621 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) |
618 | return -EIO; | 622 | return -EIO; |
619 | 623 | ||
620 | dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", | 624 | dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", |
621 | reg_read(icd, MT9V022_TOTAL_SHUTTER_WIDTH), | 625 | reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH), |
622 | shutter); | 626 | shutter); |
623 | if (reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, | 627 | if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, |
624 | shutter) < 0) | 628 | shutter) < 0) |
625 | return -EIO; | 629 | return -EIO; |
626 | icd->exposure = ctrl->value; | 630 | icd->exposure = ctrl->value; |
@@ -628,17 +632,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
628 | break; | 632 | break; |
629 | case V4L2_CID_AUTOGAIN: | 633 | case V4L2_CID_AUTOGAIN: |
630 | if (ctrl->value) | 634 | if (ctrl->value) |
631 | data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x2); | 635 | data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2); |
632 | else | 636 | else |
633 | data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2); | 637 | data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2); |
634 | if (data < 0) | 638 | if (data < 0) |
635 | return -EIO; | 639 | return -EIO; |
636 | break; | 640 | break; |
637 | case V4L2_CID_EXPOSURE_AUTO: | 641 | case V4L2_CID_EXPOSURE_AUTO: |
638 | if (ctrl->value) | 642 | if (ctrl->value) |
639 | data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x1); | 643 | data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1); |
640 | else | 644 | else |
641 | data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1); | 645 | data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1); |
642 | if (data < 0) | 646 | if (data < 0) |
643 | return -EIO; | 647 | return -EIO; |
644 | break; | 648 | break; |
@@ -650,8 +654,9 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
650 | * this wasn't our capture interface, so, we wait for the right one */ | 654 | * this wasn't our capture interface, so, we wait for the right one */ |
651 | static int mt9v022_video_probe(struct soc_camera_device *icd) | 655 | static int mt9v022_video_probe(struct soc_camera_device *icd) |
652 | { | 656 | { |
657 | struct i2c_client *client = to_i2c_client(icd->control); | ||
653 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 658 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
654 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | 659 | struct soc_camera_link *icl = client->dev.platform_data; |
655 | s32 data; | 660 | s32 data; |
656 | int ret; | 661 | int ret; |
657 | unsigned long flags; | 662 | unsigned long flags; |
@@ -661,7 +666,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) | |||
661 | return -ENODEV; | 666 | return -ENODEV; |
662 | 667 | ||
663 | /* Read out the chip version register */ | 668 | /* Read out the chip version register */ |
664 | data = reg_read(icd, MT9V022_CHIP_VERSION); | 669 | data = reg_read(client, MT9V022_CHIP_VERSION); |
665 | 670 | ||
666 | /* must be 0x1311 or 0x1313 */ | 671 | /* must be 0x1311 or 0x1313 */ |
667 | if (data != 0x1311 && data != 0x1313) { | 672 | if (data != 0x1311 && data != 0x1313) { |
@@ -672,12 +677,12 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) | |||
672 | } | 677 | } |
673 | 678 | ||
674 | /* Soft reset */ | 679 | /* Soft reset */ |
675 | ret = reg_write(icd, MT9V022_RESET, 1); | 680 | ret = reg_write(client, MT9V022_RESET, 1); |
676 | if (ret < 0) | 681 | if (ret < 0) |
677 | goto ei2c; | 682 | goto ei2c; |
678 | /* 15 clock cycles */ | 683 | /* 15 clock cycles */ |
679 | udelay(200); | 684 | udelay(200); |
680 | if (reg_read(icd, MT9V022_RESET)) { | 685 | if (reg_read(client, MT9V022_RESET)) { |
681 | dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); | 686 | dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); |
682 | goto ei2c; | 687 | goto ei2c; |
683 | } | 688 | } |
@@ -685,11 +690,11 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) | |||
685 | /* Set monochrome or colour sensor type */ | 690 | /* Set monochrome or colour sensor type */ |
686 | if (sensor_type && (!strcmp("colour", sensor_type) || | 691 | if (sensor_type && (!strcmp("colour", sensor_type) || |
687 | !strcmp("color", sensor_type))) { | 692 | !strcmp("color", sensor_type))) { |
688 | ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); | 693 | ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); |
689 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; | 694 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; |
690 | icd->formats = mt9v022_colour_formats; | 695 | icd->formats = mt9v022_colour_formats; |
691 | } else { | 696 | } else { |
692 | ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11); | 697 | ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11); |
693 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; | 698 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; |
694 | icd->formats = mt9v022_monochrome_formats; | 699 | icd->formats = mt9v022_monochrome_formats; |
695 | } | 700 | } |
@@ -735,10 +740,13 @@ ei2c: | |||
735 | static void mt9v022_video_remove(struct soc_camera_device *icd) | 740 | static void mt9v022_video_remove(struct soc_camera_device *icd) |
736 | { | 741 | { |
737 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 742 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
743 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | ||
738 | 744 | ||
739 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, | 745 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, |
740 | icd->dev.parent, icd->vdev); | 746 | icd->dev.parent, icd->vdev); |
741 | soc_camera_video_stop(icd); | 747 | soc_camera_video_stop(icd); |
748 | if (icl->free_bus) | ||
749 | icl->free_bus(icl); | ||
742 | } | 750 | } |
743 | 751 | ||
744 | static int mt9v022_probe(struct i2c_client *client, | 752 | static int mt9v022_probe(struct i2c_client *client, |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 86fab56c5a20..2d075205bdfe 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -102,10 +102,10 @@ struct mx1_buffer { | |||
102 | * Interface. If anyone ever builds hardware to enable more than | 102 | * Interface. If anyone ever builds hardware to enable more than |
103 | * one camera, they will have to modify this driver too */ | 103 | * one camera, they will have to modify this driver too */ |
104 | struct mx1_camera_dev { | 104 | struct mx1_camera_dev { |
105 | struct soc_camera_host soc_host; | ||
105 | struct soc_camera_device *icd; | 106 | struct soc_camera_device *icd; |
106 | struct mx1_camera_pdata *pdata; | 107 | struct mx1_camera_pdata *pdata; |
107 | struct mx1_buffer *active; | 108 | struct mx1_buffer *active; |
108 | struct device *dev; | ||
109 | struct resource *res; | 109 | struct resource *res; |
110 | struct clk *clk; | 110 | struct clk *clk; |
111 | struct list_head capture; | 111 | struct list_head capture; |
@@ -219,7 +219,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev) | |||
219 | int ret; | 219 | int ret; |
220 | 220 | ||
221 | if (unlikely(!pcdev->active)) { | 221 | if (unlikely(!pcdev->active)) { |
222 | dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n"); | 222 | dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n"); |
223 | return -EFAULT; | 223 | return -EFAULT; |
224 | } | 224 | } |
225 | 225 | ||
@@ -229,7 +229,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev) | |||
229 | vbuf->size, pcdev->res->start + | 229 | vbuf->size, pcdev->res->start + |
230 | CSIRXR, DMA_MODE_READ); | 230 | CSIRXR, DMA_MODE_READ); |
231 | if (unlikely(ret)) | 231 | if (unlikely(ret)) |
232 | dev_err(pcdev->dev, "Failed to setup DMA sg list\n"); | 232 | dev_err(pcdev->soc_host.dev, "Failed to setup DMA sg list\n"); |
233 | 233 | ||
234 | return ret; | 234 | return ret; |
235 | } | 235 | } |
@@ -338,14 +338,14 @@ static void mx1_camera_dma_irq(int channel, void *data) | |||
338 | imx_dma_disable(channel); | 338 | imx_dma_disable(channel); |
339 | 339 | ||
340 | if (unlikely(!pcdev->active)) { | 340 | if (unlikely(!pcdev->active)) { |
341 | dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n"); | 341 | dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n"); |
342 | goto out; | 342 | goto out; |
343 | } | 343 | } |
344 | 344 | ||
345 | vb = &pcdev->active->vb; | 345 | vb = &pcdev->active->vb; |
346 | buf = container_of(vb, struct mx1_buffer, vb); | 346 | buf = container_of(vb, struct mx1_buffer, vb); |
347 | WARN_ON(buf->inwork || list_empty(&vb->queue)); | 347 | WARN_ON(buf->inwork || list_empty(&vb->queue)); |
348 | dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 348 | dev_dbg(pcdev->soc_host.dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, |
349 | vb, vb->baddr, vb->bsize); | 349 | vb, vb->baddr, vb->bsize); |
350 | 350 | ||
351 | mx1_camera_wakeup(pcdev, vb, buf); | 351 | mx1_camera_wakeup(pcdev, vb, buf); |
@@ -366,7 +366,7 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q, | |||
366 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 366 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
367 | struct mx1_camera_dev *pcdev = ici->priv; | 367 | struct mx1_camera_dev *pcdev = ici->priv; |
368 | 368 | ||
369 | videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, pcdev->dev, | 369 | videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, ici->dev, |
370 | &pcdev->lock, | 370 | &pcdev->lock, |
371 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 371 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
372 | V4L2_FIELD_NONE, | 372 | V4L2_FIELD_NONE, |
@@ -385,7 +385,7 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev) | |||
385 | * they get a nice Oops */ | 385 | * they get a nice Oops */ |
386 | div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; | 386 | div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; |
387 | 387 | ||
388 | dev_dbg(pcdev->dev, "System clock %lukHz, target freq %dkHz, " | 388 | dev_dbg(pcdev->soc_host.dev, "System clock %lukHz, target freq %dkHz, " |
389 | "divisor %lu\n", lcdclk / 1000, mclk / 1000, div); | 389 | "divisor %lu\n", lcdclk / 1000, mclk / 1000, div); |
390 | 390 | ||
391 | return div; | 391 | return div; |
@@ -395,7 +395,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) | |||
395 | { | 395 | { |
396 | unsigned int csicr1 = CSICR1_EN; | 396 | unsigned int csicr1 = CSICR1_EN; |
397 | 397 | ||
398 | dev_dbg(pcdev->dev, "Activate device\n"); | 398 | dev_dbg(pcdev->soc_host.dev, "Activate device\n"); |
399 | 399 | ||
400 | clk_enable(pcdev->clk); | 400 | clk_enable(pcdev->clk); |
401 | 401 | ||
@@ -411,7 +411,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) | |||
411 | 411 | ||
412 | static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) | 412 | static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) |
413 | { | 413 | { |
414 | dev_dbg(pcdev->dev, "Deactivate device\n"); | 414 | dev_dbg(pcdev->soc_host.dev, "Deactivate device\n"); |
415 | 415 | ||
416 | /* Disable all CSI interface */ | 416 | /* Disable all CSI interface */ |
417 | __raw_writel(0x00, pcdev->base + CSICR1); | 417 | __raw_writel(0x00, pcdev->base + CSICR1); |
@@ -550,7 +550,7 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd, | |||
550 | 550 | ||
551 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | 551 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); |
552 | if (!xlate) { | 552 | if (!xlate) { |
553 | dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat); | 553 | dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); |
554 | return -EINVAL; | 554 | return -EINVAL; |
555 | } | 555 | } |
556 | 556 | ||
@@ -633,12 +633,6 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = { | |||
633 | .querycap = mx1_camera_querycap, | 633 | .querycap = mx1_camera_querycap, |
634 | }; | 634 | }; |
635 | 635 | ||
636 | /* Should be allocated dynamically too, but we have only one. */ | ||
637 | static struct soc_camera_host mx1_soc_camera_host = { | ||
638 | .drv_name = DRIVER_NAME, | ||
639 | .ops = &mx1_soc_camera_host_ops, | ||
640 | }; | ||
641 | |||
642 | static struct fiq_handler fh = { | 636 | static struct fiq_handler fh = { |
643 | .name = "csi_sof" | 637 | .name = "csi_sof" |
644 | }; | 638 | }; |
@@ -673,7 +667,6 @@ static int __init mx1_camera_probe(struct platform_device *pdev) | |||
673 | goto exit_put_clk; | 667 | goto exit_put_clk; |
674 | } | 668 | } |
675 | 669 | ||
676 | dev_set_drvdata(&pdev->dev, pcdev); | ||
677 | pcdev->res = res; | 670 | pcdev->res = res; |
678 | pcdev->clk = clk; | 671 | pcdev->clk = clk; |
679 | 672 | ||
@@ -707,16 +700,15 @@ static int __init mx1_camera_probe(struct platform_device *pdev) | |||
707 | } | 700 | } |
708 | pcdev->irq = irq; | 701 | pcdev->irq = irq; |
709 | pcdev->base = base; | 702 | pcdev->base = base; |
710 | pcdev->dev = &pdev->dev; | ||
711 | 703 | ||
712 | /* request dma */ | 704 | /* request dma */ |
713 | pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH); | 705 | pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH); |
714 | if (pcdev->dma_chan < 0) { | 706 | if (pcdev->dma_chan < 0) { |
715 | dev_err(pcdev->dev, "Can't request DMA for MX1 CSI\n"); | 707 | dev_err(&pdev->dev, "Can't request DMA for MX1 CSI\n"); |
716 | err = -EBUSY; | 708 | err = -EBUSY; |
717 | goto exit_iounmap; | 709 | goto exit_iounmap; |
718 | } | 710 | } |
719 | dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chan); | 711 | dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan); |
720 | 712 | ||
721 | imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL, | 713 | imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL, |
722 | pcdev); | 714 | pcdev); |
@@ -729,7 +721,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev) | |||
729 | /* request irq */ | 721 | /* request irq */ |
730 | err = claim_fiq(&fh); | 722 | err = claim_fiq(&fh); |
731 | if (err) { | 723 | if (err) { |
732 | dev_err(pcdev->dev, "Camera interrupt register failed \n"); | 724 | dev_err(&pdev->dev, "Camera interrupt register failed \n"); |
733 | goto exit_free_dma; | 725 | goto exit_free_dma; |
734 | } | 726 | } |
735 | 727 | ||
@@ -746,10 +738,12 @@ static int __init mx1_camera_probe(struct platform_device *pdev) | |||
746 | mxc_set_irq_fiq(irq, 1); | 738 | mxc_set_irq_fiq(irq, 1); |
747 | enable_fiq(irq); | 739 | enable_fiq(irq); |
748 | 740 | ||
749 | mx1_soc_camera_host.priv = pcdev; | 741 | pcdev->soc_host.drv_name = DRIVER_NAME; |
750 | mx1_soc_camera_host.dev.parent = &pdev->dev; | 742 | pcdev->soc_host.ops = &mx1_soc_camera_host_ops; |
751 | mx1_soc_camera_host.nr = pdev->id; | 743 | pcdev->soc_host.priv = pcdev; |
752 | err = soc_camera_host_register(&mx1_soc_camera_host); | 744 | pcdev->soc_host.dev = &pdev->dev; |
745 | pcdev->soc_host.nr = pdev->id; | ||
746 | err = soc_camera_host_register(&pcdev->soc_host); | ||
753 | if (err) | 747 | if (err) |
754 | goto exit_free_irq; | 748 | goto exit_free_irq; |
755 | 749 | ||
@@ -777,7 +771,9 @@ exit: | |||
777 | 771 | ||
778 | static int __exit mx1_camera_remove(struct platform_device *pdev) | 772 | static int __exit mx1_camera_remove(struct platform_device *pdev) |
779 | { | 773 | { |
780 | struct mx1_camera_dev *pcdev = platform_get_drvdata(pdev); | 774 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); |
775 | struct mx1_camera_dev *pcdev = container_of(soc_host, | ||
776 | struct mx1_camera_dev, soc_host); | ||
781 | struct resource *res; | 777 | struct resource *res; |
782 | 778 | ||
783 | imx_dma_free(pcdev->dma_chan); | 779 | imx_dma_free(pcdev->dma_chan); |
@@ -787,7 +783,7 @@ static int __exit mx1_camera_remove(struct platform_device *pdev) | |||
787 | 783 | ||
788 | clk_put(pcdev->clk); | 784 | clk_put(pcdev->clk); |
789 | 785 | ||
790 | soc_camera_host_unregister(&mx1_soc_camera_host); | 786 | soc_camera_host_unregister(soc_host); |
791 | 787 | ||
792 | iounmap(pcdev->base); | 788 | iounmap(pcdev->base); |
793 | 789 | ||
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index 2d0781118eb0..e605c076ed89 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
@@ -87,7 +87,6 @@ struct mx3_camera_buffer { | |||
87 | * @soc_host: embedded soc_host object | 87 | * @soc_host: embedded soc_host object |
88 | */ | 88 | */ |
89 | struct mx3_camera_dev { | 89 | struct mx3_camera_dev { |
90 | struct device *dev; | ||
91 | /* | 90 | /* |
92 | * i.MX3x is only supposed to handle one camera on its Camera Sensor | 91 | * i.MX3x is only supposed to handle one camera on its Camera Sensor |
93 | * Interface. If anyone ever builds hardware to enable more than one | 92 | * Interface. If anyone ever builds hardware to enable more than one |
@@ -431,7 +430,7 @@ static void mx3_camera_init_videobuf(struct videobuf_queue *q, | |||
431 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 430 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
432 | struct mx3_camera_dev *mx3_cam = ici->priv; | 431 | struct mx3_camera_dev *mx3_cam = ici->priv; |
433 | 432 | ||
434 | videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, mx3_cam->dev, | 433 | videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, ici->dev, |
435 | &mx3_cam->lock, | 434 | &mx3_cam->lock, |
436 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 435 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
437 | V4L2_FIELD_NONE, | 436 | V4L2_FIELD_NONE, |
@@ -599,7 +598,8 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam, | |||
599 | *flags |= SOCAM_DATAWIDTH_4; | 598 | *flags |= SOCAM_DATAWIDTH_4; |
600 | break; | 599 | break; |
601 | default: | 600 | default: |
602 | dev_info(mx3_cam->dev, "Unsupported bus width %d\n", buswidth); | 601 | dev_info(mx3_cam->soc_host.dev, "Unsupported bus width %d\n", |
602 | buswidth); | ||
603 | return -EINVAL; | 603 | return -EINVAL; |
604 | } | 604 | } |
605 | 605 | ||
@@ -614,7 +614,7 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd, | |||
614 | unsigned long bus_flags, camera_flags; | 614 | unsigned long bus_flags, camera_flags; |
615 | int ret = test_platform_param(mx3_cam, depth, &bus_flags); | 615 | int ret = test_platform_param(mx3_cam, depth, &bus_flags); |
616 | 616 | ||
617 | dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", depth, ret); | 617 | dev_dbg(ici->dev, "requested bus width %d bit: %d\n", depth, ret); |
618 | 618 | ||
619 | if (ret < 0) | 619 | if (ret < 0) |
620 | return ret; | 620 | return ret; |
@@ -637,7 +637,7 @@ static bool chan_filter(struct dma_chan *chan, void *arg) | |||
637 | if (!rq) | 637 | if (!rq) |
638 | return false; | 638 | return false; |
639 | 639 | ||
640 | pdata = rq->mx3_cam->dev->platform_data; | 640 | pdata = rq->mx3_cam->soc_host.dev->platform_data; |
641 | 641 | ||
642 | return rq->id == chan->chan_id && | 642 | return rq->id == chan->chan_id && |
643 | pdata->dma_dev == chan->device->dev; | 643 | pdata->dma_dev == chan->device->dev; |
@@ -697,7 +697,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, | |||
697 | xlate->cam_fmt = icd->formats + idx; | 697 | xlate->cam_fmt = icd->formats + idx; |
698 | xlate->buswidth = buswidth; | 698 | xlate->buswidth = buswidth; |
699 | xlate++; | 699 | xlate++; |
700 | dev_dbg(&ici->dev, "Providing format %s using %s\n", | 700 | dev_dbg(ici->dev, "Providing format %s using %s\n", |
701 | mx3_camera_formats[0].name, | 701 | mx3_camera_formats[0].name, |
702 | icd->formats[idx].name); | 702 | icd->formats[idx].name); |
703 | } | 703 | } |
@@ -709,7 +709,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, | |||
709 | xlate->cam_fmt = icd->formats + idx; | 709 | xlate->cam_fmt = icd->formats + idx; |
710 | xlate->buswidth = buswidth; | 710 | xlate->buswidth = buswidth; |
711 | xlate++; | 711 | xlate++; |
712 | dev_dbg(&ici->dev, "Providing format %s using %s\n", | 712 | dev_dbg(ici->dev, "Providing format %s using %s\n", |
713 | mx3_camera_formats[0].name, | 713 | mx3_camera_formats[0].name, |
714 | icd->formats[idx].name); | 714 | icd->formats[idx].name); |
715 | } | 715 | } |
@@ -722,7 +722,7 @@ passthrough: | |||
722 | xlate->cam_fmt = icd->formats + idx; | 722 | xlate->cam_fmt = icd->formats + idx; |
723 | xlate->buswidth = buswidth; | 723 | xlate->buswidth = buswidth; |
724 | xlate++; | 724 | xlate++; |
725 | dev_dbg(&ici->dev, | 725 | dev_dbg(ici->dev, |
726 | "Providing format %s in pass-through mode\n", | 726 | "Providing format %s in pass-through mode\n", |
727 | icd->formats[idx].name); | 727 | icd->formats[idx].name); |
728 | } | 728 | } |
@@ -829,7 +829,7 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd, | |||
829 | 829 | ||
830 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | 830 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); |
831 | if (!xlate) { | 831 | if (!xlate) { |
832 | dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat); | 832 | dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); |
833 | return -EINVAL; | 833 | return -EINVAL; |
834 | } | 834 | } |
835 | 835 | ||
@@ -866,7 +866,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd, | |||
866 | 866 | ||
867 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 867 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
868 | if (pixfmt && !xlate) { | 868 | if (pixfmt && !xlate) { |
869 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 869 | dev_warn(ici->dev, "Format %x not found\n", pixfmt); |
870 | return -EINVAL; | 870 | return -EINVAL; |
871 | } | 871 | } |
872 | 872 | ||
@@ -933,11 +933,11 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
933 | 933 | ||
934 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 934 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
935 | if (!xlate) { | 935 | if (!xlate) { |
936 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 936 | dev_warn(ici->dev, "Format %x not found\n", pixfmt); |
937 | return -EINVAL; | 937 | return -EINVAL; |
938 | } | 938 | } |
939 | 939 | ||
940 | dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", | 940 | dev_dbg(ici->dev, "requested bus width %d bit: %d\n", |
941 | icd->buswidth, ret); | 941 | icd->buswidth, ret); |
942 | 942 | ||
943 | if (ret < 0) | 943 | if (ret < 0) |
@@ -947,7 +947,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
947 | 947 | ||
948 | common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); | 948 | common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); |
949 | if (!common_flags) { | 949 | if (!common_flags) { |
950 | dev_dbg(&ici->dev, "no common flags: camera %lx, host %lx\n", | 950 | dev_dbg(ici->dev, "no common flags: camera %lx, host %lx\n", |
951 | camera_flags, bus_flags); | 951 | camera_flags, bus_flags); |
952 | return -EINVAL; | 952 | return -EINVAL; |
953 | } | 953 | } |
@@ -1054,7 +1054,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
1054 | 1054 | ||
1055 | csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF); | 1055 | csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF); |
1056 | 1056 | ||
1057 | dev_dbg(&ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw); | 1057 | dev_dbg(ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw); |
1058 | 1058 | ||
1059 | return 0; | 1059 | return 0; |
1060 | } | 1060 | } |
@@ -1074,7 +1074,7 @@ static struct soc_camera_host_ops mx3_soc_camera_host_ops = { | |||
1074 | .set_bus_param = mx3_camera_set_bus_param, | 1074 | .set_bus_param = mx3_camera_set_bus_param, |
1075 | }; | 1075 | }; |
1076 | 1076 | ||
1077 | static int mx3_camera_probe(struct platform_device *pdev) | 1077 | static int __devinit mx3_camera_probe(struct platform_device *pdev) |
1078 | { | 1078 | { |
1079 | struct mx3_camera_dev *mx3_cam; | 1079 | struct mx3_camera_dev *mx3_cam; |
1080 | struct resource *res; | 1080 | struct resource *res; |
@@ -1102,8 +1102,6 @@ static int mx3_camera_probe(struct platform_device *pdev) | |||
1102 | goto eclkget; | 1102 | goto eclkget; |
1103 | } | 1103 | } |
1104 | 1104 | ||
1105 | dev_set_drvdata(&pdev->dev, mx3_cam); | ||
1106 | |||
1107 | mx3_cam->pdata = pdev->dev.platform_data; | 1105 | mx3_cam->pdata = pdev->dev.platform_data; |
1108 | mx3_cam->platform_flags = mx3_cam->pdata->flags; | 1106 | mx3_cam->platform_flags = mx3_cam->pdata->flags; |
1109 | if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 | | 1107 | if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 | |
@@ -1135,14 +1133,14 @@ static int mx3_camera_probe(struct platform_device *pdev) | |||
1135 | } | 1133 | } |
1136 | 1134 | ||
1137 | mx3_cam->base = base; | 1135 | mx3_cam->base = base; |
1138 | mx3_cam->dev = &pdev->dev; | ||
1139 | 1136 | ||
1140 | soc_host = &mx3_cam->soc_host; | 1137 | soc_host = &mx3_cam->soc_host; |
1141 | soc_host->drv_name = MX3_CAM_DRV_NAME; | 1138 | soc_host->drv_name = MX3_CAM_DRV_NAME; |
1142 | soc_host->ops = &mx3_soc_camera_host_ops; | 1139 | soc_host->ops = &mx3_soc_camera_host_ops; |
1143 | soc_host->priv = mx3_cam; | 1140 | soc_host->priv = mx3_cam; |
1144 | soc_host->dev.parent = &pdev->dev; | 1141 | soc_host->dev = &pdev->dev; |
1145 | soc_host->nr = pdev->id; | 1142 | soc_host->nr = pdev->id; |
1143 | |||
1146 | err = soc_camera_host_register(soc_host); | 1144 | err = soc_camera_host_register(soc_host); |
1147 | if (err) | 1145 | if (err) |
1148 | goto ecamhostreg; | 1146 | goto ecamhostreg; |
@@ -1165,11 +1163,13 @@ egetres: | |||
1165 | 1163 | ||
1166 | static int __devexit mx3_camera_remove(struct platform_device *pdev) | 1164 | static int __devexit mx3_camera_remove(struct platform_device *pdev) |
1167 | { | 1165 | { |
1168 | struct mx3_camera_dev *mx3_cam = platform_get_drvdata(pdev); | 1166 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); |
1167 | struct mx3_camera_dev *mx3_cam = container_of(soc_host, | ||
1168 | struct mx3_camera_dev, soc_host); | ||
1169 | 1169 | ||
1170 | clk_put(mx3_cam->clk); | 1170 | clk_put(mx3_cam->clk); |
1171 | 1171 | ||
1172 | soc_camera_host_unregister(&mx3_cam->soc_host); | 1172 | soc_camera_host_unregister(soc_host); |
1173 | 1173 | ||
1174 | iounmap(mx3_cam->base); | 1174 | iounmap(mx3_cam->base); |
1175 | 1175 | ||
@@ -1194,11 +1194,11 @@ static struct platform_driver mx3_camera_driver = { | |||
1194 | .name = MX3_CAM_DRV_NAME, | 1194 | .name = MX3_CAM_DRV_NAME, |
1195 | }, | 1195 | }, |
1196 | .probe = mx3_camera_probe, | 1196 | .probe = mx3_camera_probe, |
1197 | .remove = __exit_p(mx3_camera_remove), | 1197 | .remove = __devexit_p(mx3_camera_remove), |
1198 | }; | 1198 | }; |
1199 | 1199 | ||
1200 | 1200 | ||
1201 | static int __devinit mx3_camera_init(void) | 1201 | static int __init mx3_camera_init(void) |
1202 | { | 1202 | { |
1203 | return platform_driver_register(&mx3_camera_driver); | 1203 | return platform_driver_register(&mx3_camera_driver); |
1204 | } | 1204 | } |
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 3be5a71bdac2..35890e8b2431 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
@@ -453,7 +453,7 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc) | |||
453 | static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) | 453 | static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) |
454 | { | 454 | { |
455 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); | 455 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); |
456 | if (i->index < 0 || i->index >= MXB_INPUTS) | 456 | if (i->index >= MXB_INPUTS) |
457 | return -EINVAL; | 457 | return -EINVAL; |
458 | memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); | 458 | memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); |
459 | return 0; | 459 | return 0; |
@@ -616,7 +616,7 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) | |||
616 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | 616 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
617 | struct mxb *mxb = (struct mxb *)dev->ext_priv; | 617 | struct mxb *mxb = (struct mxb *)dev->ext_priv; |
618 | 618 | ||
619 | if (a->index < 0 || a->index > MXB_INPUTS) { | 619 | if (a->index > MXB_INPUTS) { |
620 | DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index)); | 620 | DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index)); |
621 | return -EINVAL; | 621 | return -EINVAL; |
622 | } | 622 | } |
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 9af5532db142..08cfd3e4ae8a 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c | |||
@@ -112,6 +112,8 @@ static int framedrop = -1; | |||
112 | static int fastset; | 112 | static int fastset; |
113 | static int force_palette; | 113 | static int force_palette; |
114 | static int backlight; | 114 | static int backlight; |
115 | /* Bitmask marking allocated devices from 0 to OV511_MAX_UNIT_VIDEO */ | ||
116 | static unsigned long ov511_devused; | ||
115 | static int unit_video[OV511_MAX_UNIT_VIDEO]; | 117 | static int unit_video[OV511_MAX_UNIT_VIDEO]; |
116 | static int remove_zeros; | 118 | static int remove_zeros; |
117 | static int mirror; | 119 | static int mirror; |
@@ -5720,7 +5722,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
5720 | struct usb_device *dev = interface_to_usbdev(intf); | 5722 | struct usb_device *dev = interface_to_usbdev(intf); |
5721 | struct usb_interface_descriptor *idesc; | 5723 | struct usb_interface_descriptor *idesc; |
5722 | struct usb_ov511 *ov; | 5724 | struct usb_ov511 *ov; |
5723 | int i; | 5725 | int i, rc, nr; |
5724 | 5726 | ||
5725 | PDEBUG(1, "probing for device..."); | 5727 | PDEBUG(1, "probing for device..."); |
5726 | 5728 | ||
@@ -5845,33 +5847,41 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
5845 | ov->vdev->parent = &intf->dev; | 5847 | ov->vdev->parent = &intf->dev; |
5846 | video_set_drvdata(ov->vdev, ov); | 5848 | video_set_drvdata(ov->vdev, ov); |
5847 | 5849 | ||
5848 | for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { | 5850 | mutex_lock(&ov->lock); |
5849 | /* Minor 0 cannot be specified; assume user wants autodetect */ | ||
5850 | if (unit_video[i] == 0) | ||
5851 | break; | ||
5852 | 5851 | ||
5853 | if (video_register_device(ov->vdev, VFL_TYPE_GRABBER, | 5852 | /* Check to see next free device and mark as used */ |
5854 | unit_video[i]) >= 0) { | 5853 | nr = find_first_zero_bit(&ov511_devused, OV511_MAX_UNIT_VIDEO); |
5855 | break; | 5854 | |
5856 | } | 5855 | /* Registers device */ |
5857 | } | 5856 | if (unit_video[nr] != 0) |
5857 | rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER, | ||
5858 | unit_video[nr]); | ||
5859 | else | ||
5860 | rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1); | ||
5858 | 5861 | ||
5859 | /* Use the next available one */ | 5862 | if (rc < 0) { |
5860 | if ((ov->vdev->minor == -1) && | ||
5861 | video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) { | ||
5862 | err("video_register_device failed"); | 5863 | err("video_register_device failed"); |
5864 | mutex_unlock(&ov->lock); | ||
5863 | goto error; | 5865 | goto error; |
5864 | } | 5866 | } |
5865 | 5867 | ||
5868 | /* Mark device as used */ | ||
5869 | ov511_devused |= 1 << nr; | ||
5870 | ov->nr = nr; | ||
5871 | |||
5866 | dev_info(&intf->dev, "Device at %s registered to minor %d\n", | 5872 | dev_info(&intf->dev, "Device at %s registered to minor %d\n", |
5867 | ov->usb_path, ov->vdev->minor); | 5873 | ov->usb_path, ov->vdev->minor); |
5868 | 5874 | ||
5869 | usb_set_intfdata(intf, ov); | 5875 | usb_set_intfdata(intf, ov); |
5870 | if (ov_create_sysfs(ov->vdev)) { | 5876 | if (ov_create_sysfs(ov->vdev)) { |
5871 | err("ov_create_sysfs failed"); | 5877 | err("ov_create_sysfs failed"); |
5878 | ov511_devused &= ~(1 << nr); | ||
5879 | mutex_unlock(&ov->lock); | ||
5872 | goto error; | 5880 | goto error; |
5873 | } | 5881 | } |
5874 | 5882 | ||
5883 | mutex_lock(&ov->lock); | ||
5884 | |||
5875 | return 0; | 5885 | return 0; |
5876 | 5886 | ||
5877 | error: | 5887 | error: |
@@ -5906,10 +5916,16 @@ ov51x_disconnect(struct usb_interface *intf) | |||
5906 | 5916 | ||
5907 | PDEBUG(3, ""); | 5917 | PDEBUG(3, ""); |
5908 | 5918 | ||
5919 | mutex_lock(&ov->lock); | ||
5909 | usb_set_intfdata (intf, NULL); | 5920 | usb_set_intfdata (intf, NULL); |
5910 | 5921 | ||
5911 | if (!ov) | 5922 | if (!ov) { |
5923 | mutex_unlock(&ov->lock); | ||
5912 | return; | 5924 | return; |
5925 | } | ||
5926 | |||
5927 | /* Free device number */ | ||
5928 | ov511_devused &= ~(1 << ov->nr); | ||
5913 | 5929 | ||
5914 | if (ov->vdev) | 5930 | if (ov->vdev) |
5915 | video_unregister_device(ov->vdev); | 5931 | video_unregister_device(ov->vdev); |
@@ -5927,6 +5943,7 @@ ov51x_disconnect(struct usb_interface *intf) | |||
5927 | 5943 | ||
5928 | ov->streaming = 0; | 5944 | ov->streaming = 0; |
5929 | ov51x_unlink_isoc(ov); | 5945 | ov51x_unlink_isoc(ov); |
5946 | mutex_unlock(&ov->lock); | ||
5930 | 5947 | ||
5931 | ov->dev = NULL; | 5948 | ov->dev = NULL; |
5932 | 5949 | ||
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h index 70d99e52329d..c450c92468da 100644 --- a/drivers/media/video/ov511.h +++ b/drivers/media/video/ov511.h | |||
@@ -494,6 +494,9 @@ struct usb_ov511 { | |||
494 | int has_decoder; /* Device has a video decoder */ | 494 | int has_decoder; /* Device has a video decoder */ |
495 | int pal; /* Device is designed for PAL resolution */ | 495 | int pal; /* Device is designed for PAL resolution */ |
496 | 496 | ||
497 | /* ov511 device number ID */ | ||
498 | int nr; /* Stores a device number */ | ||
499 | |||
497 | /* I2C interface */ | 500 | /* I2C interface */ |
498 | struct mutex i2c_lock; /* Protect I2C controller regs */ | 501 | struct mutex i2c_lock; /* Protect I2C controller regs */ |
499 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ | 502 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index 1cb6a260e8b0..336a20eded0f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c | |||
@@ -71,6 +71,7 @@ static const struct pvr2_device_desc pvr2_device_29xxx = { | |||
71 | .flag_has_svideo = !0, | 71 | .flag_has_svideo = !0, |
72 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, | 72 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, |
73 | .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, | 73 | .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, |
74 | .ir_scheme = PVR2_IR_SCHEME_29XXX, | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | 77 | ||
@@ -284,6 +285,11 @@ static struct tda10048_config hauppauge_tda10048_config = { | |||
284 | .output_mode = TDA10048_PARALLEL_OUTPUT, | 285 | .output_mode = TDA10048_PARALLEL_OUTPUT, |
285 | .fwbulkwritelen = TDA10048_BULKWRITE_50, | 286 | .fwbulkwritelen = TDA10048_BULKWRITE_50, |
286 | .inversion = TDA10048_INVERSION_ON, | 287 | .inversion = TDA10048_INVERSION_ON, |
288 | .dtv6_if_freq_khz = TDA10048_IF_3300, | ||
289 | .dtv7_if_freq_khz = TDA10048_IF_3800, | ||
290 | .dtv8_if_freq_khz = TDA10048_IF_4300, | ||
291 | .clk_freq_khz = TDA10048_CLK_16000, | ||
292 | .disable_gate_access = 1, | ||
287 | }; | 293 | }; |
288 | 294 | ||
289 | static struct tda829x_config tda829x_no_probe = { | 295 | static struct tda829x_config tda829x_no_probe = { |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h index 3e553389cbc3..ea04ecf8aa39 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h | |||
@@ -69,6 +69,7 @@ struct pvr2_string_table { | |||
69 | #define PVR2_ROUTING_SCHEME_HAUPPAUGE 0 | 69 | #define PVR2_ROUTING_SCHEME_HAUPPAUGE 0 |
70 | #define PVR2_ROUTING_SCHEME_GOTVIEW 1 | 70 | #define PVR2_ROUTING_SCHEME_GOTVIEW 1 |
71 | #define PVR2_ROUTING_SCHEME_ONAIR 2 | 71 | #define PVR2_ROUTING_SCHEME_ONAIR 2 |
72 | #define PVR2_ROUTING_SCHEME_AV400 3 | ||
72 | 73 | ||
73 | #define PVR2_DIGITAL_SCHEME_NONE 0 | 74 | #define PVR2_DIGITAL_SCHEME_NONE 0 |
74 | #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1 | 75 | #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1 |
@@ -78,8 +79,10 @@ struct pvr2_string_table { | |||
78 | #define PVR2_LED_SCHEME_HAUPPAUGE 1 | 79 | #define PVR2_LED_SCHEME_HAUPPAUGE 1 |
79 | 80 | ||
80 | #define PVR2_IR_SCHEME_NONE 0 | 81 | #define PVR2_IR_SCHEME_NONE 0 |
81 | #define PVR2_IR_SCHEME_24XXX 1 | 82 | #define PVR2_IR_SCHEME_24XXX 1 /* FX2-controlled IR */ |
82 | #define PVR2_IR_SCHEME_ZILOG 2 | 83 | #define PVR2_IR_SCHEME_ZILOG 2 /* HVR-1950 style (must be taken out of reset) */ |
84 | #define PVR2_IR_SCHEME_24XXX_MCE 3 /* 24xxx MCE device */ | ||
85 | #define PVR2_IR_SCHEME_29XXX 4 /* Original 29xxx device */ | ||
83 | 86 | ||
84 | /* This describes a particular hardware type (except for the USB device ID | 87 | /* This describes a particular hardware type (except for the USB device ID |
85 | which must live in a separate structure due to environmental | 88 | which must live in a separate structure due to environmental |
@@ -162,19 +165,9 @@ struct pvr2_device_desc { | |||
162 | ensure that it is found. */ | 165 | ensure that it is found. */ |
163 | unsigned int flag_has_wm8775:1; | 166 | unsigned int flag_has_wm8775:1; |
164 | 167 | ||
165 | /* Indicate any specialized IR scheme that might need to be | 168 | /* Indicate IR scheme of hardware. If not set, then it is assumed |
166 | supported by this driver. If not set, then it is assumed that | 169 | that IR can work without any help from the driver. */ |
167 | IR can work without help from the driver (which is frequently | 170 | unsigned int ir_scheme:3; |
168 | the case). This is otherwise set to one of | ||
169 | PVR2_IR_SCHEME_xxxx. For "xxxx", the value "24XXX" indicates a | ||
170 | Hauppauge 24xxx class device which has an FPGA-hosted IR | ||
171 | receiver that can only be reached via FX2 command codes. In | ||
172 | that case the pvrusb2 driver will emulate the behavior of the | ||
173 | older 29xxx device's IR receiver (a "virtual" I2C chip) in terms | ||
174 | of those command codes. For the value "ZILOG", we're dealing | ||
175 | with an IR chip that must be taken out of reset via another FX2 | ||
176 | command code (which is the case for HVR-1950 devices). */ | ||
177 | unsigned int ir_scheme:2; | ||
178 | 171 | ||
179 | /* These bits define which kinds of sources the device can handle. | 172 | /* These bits define which kinds of sources the device can handle. |
180 | Note: Digital tuner presence is inferred by the | 173 | Note: Digital tuner presence is inferred by the |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index 5d75eb5211b1..5b152ff20bd0 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | |||
@@ -200,6 +200,9 @@ struct pvr2_hdw { | |||
200 | int i2c_cx25840_hack_state; | 200 | int i2c_cx25840_hack_state; |
201 | int i2c_linked; | 201 | int i2c_linked; |
202 | 202 | ||
203 | /* IR related */ | ||
204 | unsigned int ir_scheme_active; /* IR scheme as seen from the outside */ | ||
205 | |||
203 | /* Frequency table */ | 206 | /* Frequency table */ |
204 | unsigned int freqTable[FREQTABLE_SIZE]; | 207 | unsigned int freqTable[FREQTABLE_SIZE]; |
205 | unsigned int freqProgSlot; | 208 | unsigned int freqProgSlot; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index add3395d3248..0c745b142fb7 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -142,6 +142,15 @@ static const unsigned char *module_i2c_addresses[] = { | |||
142 | }; | 142 | }; |
143 | 143 | ||
144 | 144 | ||
145 | static const char *ir_scheme_names[] = { | ||
146 | [PVR2_IR_SCHEME_NONE] = "none", | ||
147 | [PVR2_IR_SCHEME_29XXX] = "29xxx", | ||
148 | [PVR2_IR_SCHEME_24XXX] = "24xxx (29xxx emulation)", | ||
149 | [PVR2_IR_SCHEME_24XXX_MCE] = "24xxx (MCE device)", | ||
150 | [PVR2_IR_SCHEME_ZILOG] = "Zilog", | ||
151 | }; | ||
152 | |||
153 | |||
145 | /* Define the list of additional controls we'll dynamically construct based | 154 | /* Define the list of additional controls we'll dynamically construct based |
146 | on query of the cx2341x module. */ | 155 | on query of the cx2341x module. */ |
147 | struct pvr2_mpeg_ids { | 156 | struct pvr2_mpeg_ids { |
@@ -2170,7 +2179,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) | |||
2170 | } | 2179 | } |
2171 | 2180 | ||
2172 | /* Take the IR chip out of reset, if appropriate */ | 2181 | /* Take the IR chip out of reset, if appropriate */ |
2173 | if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_ZILOG) { | 2182 | if (hdw->ir_scheme_active == PVR2_IR_SCHEME_ZILOG) { |
2174 | pvr2_issue_simple_cmd(hdw, | 2183 | pvr2_issue_simple_cmd(hdw, |
2175 | FX2CMD_HCW_ZILOG_RESET | | 2184 | FX2CMD_HCW_ZILOG_RESET | |
2176 | (1 << 8) | | 2185 | (1 << 8) | |
@@ -2451,6 +2460,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
2451 | GFP_KERNEL); | 2460 | GFP_KERNEL); |
2452 | if (!hdw->controls) goto fail; | 2461 | if (!hdw->controls) goto fail; |
2453 | hdw->hdw_desc = hdw_desc; | 2462 | hdw->hdw_desc = hdw_desc; |
2463 | hdw->ir_scheme_active = hdw->hdw_desc->ir_scheme; | ||
2454 | for (idx = 0; idx < hdw->control_cnt; idx++) { | 2464 | for (idx = 0; idx < hdw->control_cnt; idx++) { |
2455 | cptr = hdw->controls + idx; | 2465 | cptr = hdw->controls + idx; |
2456 | cptr->hdw = hdw; | 2466 | cptr->hdw = hdw; |
@@ -4809,6 +4819,12 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, | |||
4809 | stats.buffers_processed, | 4819 | stats.buffers_processed, |
4810 | stats.buffers_failed); | 4820 | stats.buffers_failed); |
4811 | } | 4821 | } |
4822 | case 6: { | ||
4823 | unsigned int id = hdw->ir_scheme_active; | ||
4824 | return scnprintf(buf, acnt, "ir scheme: id=%d %s", id, | ||
4825 | (id >= ARRAY_SIZE(ir_scheme_names) ? | ||
4826 | "?" : ir_scheme_names[id])); | ||
4827 | } | ||
4812 | default: break; | 4828 | default: break; |
4813 | } | 4829 | } |
4814 | return 0; | 4830 | return 0; |
@@ -4825,65 +4841,35 @@ static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw, | |||
4825 | unsigned int tcnt = 0; | 4841 | unsigned int tcnt = 0; |
4826 | unsigned int ccnt; | 4842 | unsigned int ccnt; |
4827 | struct i2c_client *client; | 4843 | struct i2c_client *client; |
4828 | struct list_head *item; | ||
4829 | void *cd; | ||
4830 | const char *p; | 4844 | const char *p; |
4831 | unsigned int id; | 4845 | unsigned int id; |
4832 | 4846 | ||
4833 | ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers:"); | 4847 | ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers and I2C clients:\n"); |
4834 | tcnt += ccnt; | 4848 | tcnt += ccnt; |
4835 | v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { | 4849 | v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { |
4836 | id = sd->grp_id; | 4850 | id = sd->grp_id; |
4837 | p = NULL; | 4851 | p = NULL; |
4838 | if (id < ARRAY_SIZE(module_names)) p = module_names[id]; | 4852 | if (id < ARRAY_SIZE(module_names)) p = module_names[id]; |
4839 | if (p) { | 4853 | if (p) { |
4840 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s", p); | 4854 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s:", p); |
4841 | tcnt += ccnt; | 4855 | tcnt += ccnt; |
4842 | } else { | 4856 | } else { |
4843 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, | 4857 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, |
4844 | " (unknown id=%u)", id); | 4858 | " (unknown id=%u):", id); |
4845 | tcnt += ccnt; | 4859 | tcnt += ccnt; |
4846 | } | 4860 | } |
4847 | } | 4861 | client = v4l2_get_subdevdata(sd); |
4848 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n"); | 4862 | if (client) { |
4849 | tcnt += ccnt; | 4863 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, |
4850 | 4864 | " %s @ %02x\n", client->name, | |
4851 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, "I2C clients:\n"); | 4865 | client->addr); |
4852 | tcnt += ccnt; | 4866 | tcnt += ccnt; |
4853 | 4867 | } else { | |
4854 | mutex_lock(&hdw->i2c_adap.clist_lock); | 4868 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, |
4855 | list_for_each(item, &hdw->i2c_adap.clients) { | 4869 | " no i2c client\n"); |
4856 | client = list_entry(item, struct i2c_client, list); | 4870 | tcnt += ccnt; |
4857 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, | ||
4858 | " %s: i2c=%02x", client->name, client->addr); | ||
4859 | tcnt += ccnt; | ||
4860 | cd = i2c_get_clientdata(client); | ||
4861 | v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { | ||
4862 | if (cd == sd) { | ||
4863 | id = sd->grp_id; | ||
4864 | p = NULL; | ||
4865 | if (id < ARRAY_SIZE(module_names)) { | ||
4866 | p = module_names[id]; | ||
4867 | } | ||
4868 | if (p) { | ||
4869 | ccnt = scnprintf(buf + tcnt, | ||
4870 | acnt - tcnt, | ||
4871 | " subdev=%s", p); | ||
4872 | tcnt += ccnt; | ||
4873 | } else { | ||
4874 | ccnt = scnprintf(buf + tcnt, | ||
4875 | acnt - tcnt, | ||
4876 | " subdev= id %u)", | ||
4877 | id); | ||
4878 | tcnt += ccnt; | ||
4879 | } | ||
4880 | break; | ||
4881 | } | ||
4882 | } | 4871 | } |
4883 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n"); | ||
4884 | tcnt += ccnt; | ||
4885 | } | 4872 | } |
4886 | mutex_unlock(&hdw->i2c_adap.clist_lock); | ||
4887 | return tcnt; | 4873 | return tcnt; |
4888 | } | 4874 | } |
4889 | 4875 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 9af282f9e765..610bd848df24 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | |||
@@ -42,6 +42,18 @@ static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 }; | |||
42 | module_param_array(ir_mode, int, NULL, 0444); | 42 | module_param_array(ir_mode, int, NULL, 0444); |
43 | MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR"); | 43 | MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR"); |
44 | 44 | ||
45 | static int pvr2_disable_ir_video; | ||
46 | module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video, | ||
47 | int, S_IRUGO|S_IWUSR); | ||
48 | MODULE_PARM_DESC(disable_autoload_ir_video, | ||
49 | "1=do not try to autoload ir_video IR receiver"); | ||
50 | |||
51 | /* Mapping of IR schemes to known I2C addresses - if any */ | ||
52 | static const unsigned char ir_video_addresses[] = { | ||
53 | [PVR2_IR_SCHEME_29XXX] = 0x18, | ||
54 | [PVR2_IR_SCHEME_24XXX] = 0x18, | ||
55 | }; | ||
56 | |||
45 | static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ | 57 | static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ |
46 | u8 i2c_addr, /* I2C address we're talking to */ | 58 | u8 i2c_addr, /* I2C address we're talking to */ |
47 | u8 *data, /* Data to write */ | 59 | u8 *data, /* Data to write */ |
@@ -559,6 +571,31 @@ static void do_i2c_scan(struct pvr2_hdw *hdw) | |||
559 | printk(KERN_INFO "%s: i2c scan done.\n", hdw->name); | 571 | printk(KERN_INFO "%s: i2c scan done.\n", hdw->name); |
560 | } | 572 | } |
561 | 573 | ||
574 | static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw) | ||
575 | { | ||
576 | struct i2c_board_info info; | ||
577 | unsigned char addr = 0; | ||
578 | if (pvr2_disable_ir_video) { | ||
579 | pvr2_trace(PVR2_TRACE_INFO, | ||
580 | "Automatic binding of ir_video has been disabled."); | ||
581 | return; | ||
582 | } | ||
583 | if (hdw->ir_scheme_active < ARRAY_SIZE(ir_video_addresses)) { | ||
584 | addr = ir_video_addresses[hdw->ir_scheme_active]; | ||
585 | } | ||
586 | if (!addr) { | ||
587 | /* The device either doesn't support I2C-based IR or we | ||
588 | don't know (yet) how to operate IR on the device. */ | ||
589 | return; | ||
590 | } | ||
591 | pvr2_trace(PVR2_TRACE_INFO, | ||
592 | "Binding ir_video to i2c address 0x%02x.", addr); | ||
593 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
594 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
595 | info.addr = addr; | ||
596 | i2c_new_device(&hdw->i2c_adap, &info); | ||
597 | } | ||
598 | |||
562 | void pvr2_i2c_core_init(struct pvr2_hdw *hdw) | 599 | void pvr2_i2c_core_init(struct pvr2_hdw *hdw) |
563 | { | 600 | { |
564 | unsigned int idx; | 601 | unsigned int idx; |
@@ -574,7 +611,9 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) | |||
574 | printk(KERN_INFO "%s: IR disabled\n",hdw->name); | 611 | printk(KERN_INFO "%s: IR disabled\n",hdw->name); |
575 | hdw->i2c_func[0x18] = i2c_black_hole; | 612 | hdw->i2c_func[0x18] = i2c_black_hole; |
576 | } else if (ir_mode[hdw->unit_number] == 1) { | 613 | } else if (ir_mode[hdw->unit_number] == 1) { |
577 | if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) { | 614 | if (hdw->ir_scheme_active == PVR2_IR_SCHEME_24XXX) { |
615 | /* Set up translation so that our IR looks like a | ||
616 | 29xxx device */ | ||
578 | hdw->i2c_func[0x18] = i2c_24xxx_ir; | 617 | hdw->i2c_func[0x18] = i2c_24xxx_ir; |
579 | } | 618 | } |
580 | } | 619 | } |
@@ -597,15 +636,23 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) | |||
597 | i2c_add_adapter(&hdw->i2c_adap); | 636 | i2c_add_adapter(&hdw->i2c_adap); |
598 | if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { | 637 | if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { |
599 | /* Probe for a different type of IR receiver on this | 638 | /* Probe for a different type of IR receiver on this |
600 | device. If present, disable the emulated IR receiver. */ | 639 | device. This is really the only way to differentiate |
640 | older 24xxx devices from 24xxx variants that include an | ||
641 | IR blaster. If the IR blaster is present, the IR | ||
642 | receiver is part of that chip and thus we must disable | ||
643 | the emulated IR receiver. */ | ||
601 | if (do_i2c_probe(hdw, 0x71)) { | 644 | if (do_i2c_probe(hdw, 0x71)) { |
602 | pvr2_trace(PVR2_TRACE_INFO, | 645 | pvr2_trace(PVR2_TRACE_INFO, |
603 | "Device has newer IR hardware;" | 646 | "Device has newer IR hardware;" |
604 | " disabling unneeded virtual IR device"); | 647 | " disabling unneeded virtual IR device"); |
605 | hdw->i2c_func[0x18] = NULL; | 648 | hdw->i2c_func[0x18] = NULL; |
649 | /* Remember that this is a different device... */ | ||
650 | hdw->ir_scheme_active = PVR2_IR_SCHEME_24XXX_MCE; | ||
606 | } | 651 | } |
607 | } | 652 | } |
608 | if (i2c_scan) do_i2c_scan(hdw); | 653 | if (i2c_scan) do_i2c_scan(hdw); |
654 | |||
655 | pvr2_i2c_register_ir(hdw); | ||
609 | } | 656 | } |
610 | 657 | ||
611 | void pvr2_i2c_core_done(struct pvr2_hdw *hdw) | 658 | void pvr2_i2c_core_done(struct pvr2_hdw *hdw) |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 9e0f2b07b93b..2d8825e5b1be 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
@@ -90,7 +90,7 @@ static struct v4l2_capability pvr_capability ={ | |||
90 | .driver = "pvrusb2", | 90 | .driver = "pvrusb2", |
91 | .card = "Hauppauge WinTV pvr-usb2", | 91 | .card = "Hauppauge WinTV pvr-usb2", |
92 | .bus_info = "usb", | 92 | .bus_info = "usb", |
93 | .version = KERNEL_VERSION(0,8,0), | 93 | .version = KERNEL_VERSION(0, 9, 0), |
94 | .capabilities = (V4L2_CAP_VIDEO_CAPTURE | | 94 | .capabilities = (V4L2_CAP_VIDEO_CAPTURE | |
95 | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | | 95 | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | |
96 | V4L2_CAP_READWRITE), | 96 | V4L2_CAP_READWRITE), |
@@ -267,7 +267,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
267 | memset(&tmp,0,sizeof(tmp)); | 267 | memset(&tmp,0,sizeof(tmp)); |
268 | tmp.index = vi->index; | 268 | tmp.index = vi->index; |
269 | ret = 0; | 269 | ret = 0; |
270 | if ((vi->index < 0) || (vi->index >= fh->input_cnt)) { | 270 | if (vi->index >= fh->input_cnt) { |
271 | ret = -EINVAL; | 271 | ret = -EINVAL; |
272 | break; | 272 | break; |
273 | } | 273 | } |
@@ -331,7 +331,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
331 | case VIDIOC_S_INPUT: | 331 | case VIDIOC_S_INPUT: |
332 | { | 332 | { |
333 | struct v4l2_input *vi = (struct v4l2_input *)arg; | 333 | struct v4l2_input *vi = (struct v4l2_input *)arg; |
334 | if ((vi->index < 0) || (vi->index >= fh->input_cnt)) { | 334 | if (vi->index >= fh->input_cnt) { |
335 | ret = -ERANGE; | 335 | ret = -ERANGE; |
336 | break; | 336 | break; |
337 | } | 337 | } |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 7c542caf248e..db25c3034c11 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -601,7 +601,7 @@ static void pwc_snapshot_button(struct pwc_device *pdev, int down) | |||
601 | 601 | ||
602 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 602 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
603 | if (pdev->button_dev) { | 603 | if (pdev->button_dev) { |
604 | input_report_key(pdev->button_dev, BTN_0, down); | 604 | input_report_key(pdev->button_dev, KEY_CAMERA, down); |
605 | input_sync(pdev->button_dev); | 605 | input_sync(pdev->button_dev); |
606 | } | 606 | } |
607 | #endif | 607 | #endif |
@@ -1783,7 +1783,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1783 | return -ENOMEM; | 1783 | return -ENOMEM; |
1784 | } | 1784 | } |
1785 | memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); | 1785 | memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); |
1786 | pdev->vdev->parent = &(udev->dev); | 1786 | pdev->vdev->parent = &intf->dev; |
1787 | strcpy(pdev->vdev->name, name); | 1787 | strcpy(pdev->vdev->name, name); |
1788 | video_set_drvdata(pdev->vdev, pdev); | 1788 | video_set_drvdata(pdev->vdev, pdev); |
1789 | 1789 | ||
@@ -1847,7 +1847,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1847 | usb_to_input_id(pdev->udev, &pdev->button_dev->id); | 1847 | usb_to_input_id(pdev->udev, &pdev->button_dev->id); |
1848 | pdev->button_dev->dev.parent = &pdev->udev->dev; | 1848 | pdev->button_dev->dev.parent = &pdev->udev->dev; |
1849 | pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY); | 1849 | pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY); |
1850 | pdev->button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); | 1850 | pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA); |
1851 | 1851 | ||
1852 | rc = input_register_device(pdev->button_dev); | 1852 | rc = input_register_device(pdev->button_dev); |
1853 | if (rc) { | 1853 | if (rc) { |
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index bc0a464295c5..2876ce084510 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
@@ -1107,7 +1107,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1107 | return -EINVAL; | 1107 | return -EINVAL; |
1108 | if (buf->memory != V4L2_MEMORY_MMAP) | 1108 | if (buf->memory != V4L2_MEMORY_MMAP) |
1109 | return -EINVAL; | 1109 | return -EINVAL; |
1110 | if (buf->index < 0 || buf->index >= pwc_mbufs) | 1110 | if (buf->index >= pwc_mbufs) |
1111 | return -EINVAL; | 1111 | return -EINVAL; |
1112 | 1112 | ||
1113 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | 1113 | buf->flags |= V4L2_BUF_FLAG_QUEUED; |
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index c639845460ff..f60de40fd21f 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c | |||
@@ -202,7 +202,7 @@ struct pxa_buffer { | |||
202 | }; | 202 | }; |
203 | 203 | ||
204 | struct pxa_camera_dev { | 204 | struct pxa_camera_dev { |
205 | struct device *dev; | 205 | struct soc_camera_host soc_host; |
206 | /* PXA27x is only supposed to handle one camera on its Quick Capture | 206 | /* PXA27x is only supposed to handle one camera on its Quick Capture |
207 | * interface. If anyone ever builds hardware to enable more than | 207 | * interface. If anyone ever builds hardware to enable more than |
208 | * one camera, they will have to modify this driver too */ | 208 | * one camera, they will have to modify this driver too */ |
@@ -261,7 +261,6 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) | |||
261 | { | 261 | { |
262 | struct soc_camera_device *icd = vq->priv_data; | 262 | struct soc_camera_device *icd = vq->priv_data; |
263 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 263 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
264 | struct pxa_camera_dev *pcdev = ici->priv; | ||
265 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | 264 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); |
266 | int i; | 265 | int i; |
267 | 266 | ||
@@ -278,7 +277,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) | |||
278 | 277 | ||
279 | for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) { | 278 | for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) { |
280 | if (buf->dmas[i].sg_cpu) | 279 | if (buf->dmas[i].sg_cpu) |
281 | dma_free_coherent(pcdev->dev, buf->dmas[i].sg_size, | 280 | dma_free_coherent(ici->dev, buf->dmas[i].sg_size, |
282 | buf->dmas[i].sg_cpu, | 281 | buf->dmas[i].sg_cpu, |
283 | buf->dmas[i].sg_dma); | 282 | buf->dmas[i].sg_dma); |
284 | buf->dmas[i].sg_cpu = NULL; | 283 | buf->dmas[i].sg_cpu = NULL; |
@@ -338,14 +337,14 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev, | |||
338 | int dma_len = 0, xfer_len = 0; | 337 | int dma_len = 0, xfer_len = 0; |
339 | 338 | ||
340 | if (pxa_dma->sg_cpu) | 339 | if (pxa_dma->sg_cpu) |
341 | dma_free_coherent(pcdev->dev, pxa_dma->sg_size, | 340 | dma_free_coherent(pcdev->soc_host.dev, pxa_dma->sg_size, |
342 | pxa_dma->sg_cpu, pxa_dma->sg_dma); | 341 | pxa_dma->sg_cpu, pxa_dma->sg_dma); |
343 | 342 | ||
344 | sglen = calculate_dma_sglen(*sg_first, dma->sglen, | 343 | sglen = calculate_dma_sglen(*sg_first, dma->sglen, |
345 | *sg_first_ofs, size); | 344 | *sg_first_ofs, size); |
346 | 345 | ||
347 | pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc); | 346 | pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc); |
348 | pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->dev, pxa_dma->sg_size, | 347 | pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->soc_host.dev, pxa_dma->sg_size, |
349 | &pxa_dma->sg_dma, GFP_KERNEL); | 348 | &pxa_dma->sg_dma, GFP_KERNEL); |
350 | if (!pxa_dma->sg_cpu) | 349 | if (!pxa_dma->sg_cpu) |
351 | return -ENOMEM; | 350 | return -ENOMEM; |
@@ -353,7 +352,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev, | |||
353 | pxa_dma->sglen = sglen; | 352 | pxa_dma->sglen = sglen; |
354 | offset = *sg_first_ofs; | 353 | offset = *sg_first_ofs; |
355 | 354 | ||
356 | dev_dbg(pcdev->dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n", | 355 | dev_dbg(pcdev->soc_host.dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n", |
357 | *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma); | 356 | *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma); |
358 | 357 | ||
359 | 358 | ||
@@ -376,7 +375,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev, | |||
376 | pxa_dma->sg_cpu[i].ddadr = | 375 | pxa_dma->sg_cpu[i].ddadr = |
377 | pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc); | 376 | pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc); |
378 | 377 | ||
379 | dev_vdbg(pcdev->dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n", | 378 | dev_vdbg(pcdev->soc_host.dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n", |
380 | pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc), | 379 | pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc), |
381 | sg_dma_address(sg) + offset, xfer_len); | 380 | sg_dma_address(sg) + offset, xfer_len); |
382 | offset = 0; | 381 | offset = 0; |
@@ -488,7 +487,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, | |||
488 | ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y, | 487 | ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y, |
489 | &sg, &next_ofs); | 488 | &sg, &next_ofs); |
490 | if (ret) { | 489 | if (ret) { |
491 | dev_err(pcdev->dev, | 490 | dev_err(pcdev->soc_host.dev, |
492 | "DMA initialization for Y/RGB failed\n"); | 491 | "DMA initialization for Y/RGB failed\n"); |
493 | goto fail; | 492 | goto fail; |
494 | } | 493 | } |
@@ -498,7 +497,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, | |||
498 | ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1, | 497 | ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1, |
499 | size_u, &sg, &next_ofs); | 498 | size_u, &sg, &next_ofs); |
500 | if (ret) { | 499 | if (ret) { |
501 | dev_err(pcdev->dev, | 500 | dev_err(pcdev->soc_host.dev, |
502 | "DMA initialization for U failed\n"); | 501 | "DMA initialization for U failed\n"); |
503 | goto fail_u; | 502 | goto fail_u; |
504 | } | 503 | } |
@@ -508,7 +507,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, | |||
508 | ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2, | 507 | ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2, |
509 | size_v, &sg, &next_ofs); | 508 | size_v, &sg, &next_ofs); |
510 | if (ret) { | 509 | if (ret) { |
511 | dev_err(pcdev->dev, | 510 | dev_err(pcdev->soc_host.dev, |
512 | "DMA initialization for V failed\n"); | 511 | "DMA initialization for V failed\n"); |
513 | goto fail_v; | 512 | goto fail_v; |
514 | } | 513 | } |
@@ -522,10 +521,10 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, | |||
522 | return 0; | 521 | return 0; |
523 | 522 | ||
524 | fail_v: | 523 | fail_v: |
525 | dma_free_coherent(pcdev->dev, buf->dmas[1].sg_size, | 524 | dma_free_coherent(pcdev->soc_host.dev, buf->dmas[1].sg_size, |
526 | buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma); | 525 | buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma); |
527 | fail_u: | 526 | fail_u: |
528 | dma_free_coherent(pcdev->dev, buf->dmas[0].sg_size, | 527 | dma_free_coherent(pcdev->soc_host.dev, buf->dmas[0].sg_size, |
529 | buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma); | 528 | buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma); |
530 | fail: | 529 | fail: |
531 | free_buffer(vq, buf); | 530 | free_buffer(vq, buf); |
@@ -549,7 +548,7 @@ static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev) | |||
549 | active = pcdev->active; | 548 | active = pcdev->active; |
550 | 549 | ||
551 | for (i = 0; i < pcdev->channels; i++) { | 550 | for (i = 0; i < pcdev->channels; i++) { |
552 | dev_dbg(pcdev->dev, "%s (channel=%d) ddadr=%08x\n", __func__, | 551 | dev_dbg(pcdev->soc_host.dev, "%s (channel=%d) ddadr=%08x\n", __func__, |
553 | i, active->dmas[i].sg_dma); | 552 | i, active->dmas[i].sg_dma); |
554 | DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma; | 553 | DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma; |
555 | DCSR(pcdev->dma_chans[i]) = DCSR_RUN; | 554 | DCSR(pcdev->dma_chans[i]) = DCSR_RUN; |
@@ -561,7 +560,7 @@ static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev) | |||
561 | int i; | 560 | int i; |
562 | 561 | ||
563 | for (i = 0; i < pcdev->channels; i++) { | 562 | for (i = 0; i < pcdev->channels; i++) { |
564 | dev_dbg(pcdev->dev, "%s (channel=%d)\n", __func__, i); | 563 | dev_dbg(pcdev->soc_host.dev, "%s (channel=%d)\n", __func__, i); |
565 | DCSR(pcdev->dma_chans[i]) = 0; | 564 | DCSR(pcdev->dma_chans[i]) = 0; |
566 | } | 565 | } |
567 | } | 566 | } |
@@ -597,7 +596,7 @@ static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev) | |||
597 | { | 596 | { |
598 | unsigned long cicr0, cifr; | 597 | unsigned long cicr0, cifr; |
599 | 598 | ||
600 | dev_dbg(pcdev->dev, "%s\n", __func__); | 599 | dev_dbg(pcdev->soc_host.dev, "%s\n", __func__); |
601 | /* Reset the FIFOs */ | 600 | /* Reset the FIFOs */ |
602 | cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F; | 601 | cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F; |
603 | __raw_writel(cifr, pcdev->base + CIFR); | 602 | __raw_writel(cifr, pcdev->base + CIFR); |
@@ -617,7 +616,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev) | |||
617 | __raw_writel(cicr0, pcdev->base + CICR0); | 616 | __raw_writel(cicr0, pcdev->base + CICR0); |
618 | 617 | ||
619 | pcdev->active = NULL; | 618 | pcdev->active = NULL; |
620 | dev_dbg(pcdev->dev, "%s\n", __func__); | 619 | dev_dbg(pcdev->soc_host.dev, "%s\n", __func__); |
621 | } | 620 | } |
622 | 621 | ||
623 | static void pxa_videobuf_queue(struct videobuf_queue *vq, | 622 | static void pxa_videobuf_queue(struct videobuf_queue *vq, |
@@ -686,7 +685,7 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev, | |||
686 | do_gettimeofday(&vb->ts); | 685 | do_gettimeofday(&vb->ts); |
687 | vb->field_count++; | 686 | vb->field_count++; |
688 | wake_up(&vb->done); | 687 | wake_up(&vb->done); |
689 | dev_dbg(pcdev->dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb); | 688 | dev_dbg(pcdev->soc_host.dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb); |
690 | 689 | ||
691 | if (list_empty(&pcdev->capture)) { | 690 | if (list_empty(&pcdev->capture)) { |
692 | pxa_camera_stop_capture(pcdev); | 691 | pxa_camera_stop_capture(pcdev); |
@@ -722,7 +721,7 @@ static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev) | |||
722 | for (i = 0; i < pcdev->channels; i++) | 721 | for (i = 0; i < pcdev->channels; i++) |
723 | if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP) | 722 | if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP) |
724 | is_dma_stopped = 0; | 723 | is_dma_stopped = 0; |
725 | dev_dbg(pcdev->dev, "%s : top queued buffer=%p, dma_stopped=%d\n", | 724 | dev_dbg(pcdev->soc_host.dev, "%s : top queued buffer=%p, dma_stopped=%d\n", |
726 | __func__, pcdev->active, is_dma_stopped); | 725 | __func__, pcdev->active, is_dma_stopped); |
727 | if (pcdev->active && is_dma_stopped) | 726 | if (pcdev->active && is_dma_stopped) |
728 | pxa_camera_start_capture(pcdev); | 727 | pxa_camera_start_capture(pcdev); |
@@ -747,12 +746,12 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, | |||
747 | overrun |= CISR_IFO_1 | CISR_IFO_2; | 746 | overrun |= CISR_IFO_1 | CISR_IFO_2; |
748 | 747 | ||
749 | if (status & DCSR_BUSERR) { | 748 | if (status & DCSR_BUSERR) { |
750 | dev_err(pcdev->dev, "DMA Bus Error IRQ!\n"); | 749 | dev_err(pcdev->soc_host.dev, "DMA Bus Error IRQ!\n"); |
751 | goto out; | 750 | goto out; |
752 | } | 751 | } |
753 | 752 | ||
754 | if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) { | 753 | if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) { |
755 | dev_err(pcdev->dev, "Unknown DMA IRQ source, " | 754 | dev_err(pcdev->soc_host.dev, "Unknown DMA IRQ source, " |
756 | "status: 0x%08x\n", status); | 755 | "status: 0x%08x\n", status); |
757 | goto out; | 756 | goto out; |
758 | } | 757 | } |
@@ -776,7 +775,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, | |||
776 | buf = container_of(vb, struct pxa_buffer, vb); | 775 | buf = container_of(vb, struct pxa_buffer, vb); |
777 | WARN_ON(buf->inwork || list_empty(&vb->queue)); | 776 | WARN_ON(buf->inwork || list_empty(&vb->queue)); |
778 | 777 | ||
779 | dev_dbg(pcdev->dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n", | 778 | dev_dbg(pcdev->soc_host.dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n", |
780 | __func__, channel, status & DCSR_STARTINTR ? "SOF " : "", | 779 | __func__, channel, status & DCSR_STARTINTR ? "SOF " : "", |
781 | status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel)); | 780 | status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel)); |
782 | 781 | ||
@@ -787,7 +786,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, | |||
787 | */ | 786 | */ |
788 | if (camera_status & overrun && | 787 | if (camera_status & overrun && |
789 | !list_is_last(pcdev->capture.next, &pcdev->capture)) { | 788 | !list_is_last(pcdev->capture.next, &pcdev->capture)) { |
790 | dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", | 789 | dev_dbg(pcdev->soc_host.dev, "FIFO overrun! CISR: %x\n", |
791 | camera_status); | 790 | camera_status); |
792 | pxa_camera_stop_capture(pcdev); | 791 | pxa_camera_stop_capture(pcdev); |
793 | pxa_camera_start_capture(pcdev); | 792 | pxa_camera_start_capture(pcdev); |
@@ -854,7 +853,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev) | |||
854 | /* mclk <= ciclk / 4 (27.4.2) */ | 853 | /* mclk <= ciclk / 4 (27.4.2) */ |
855 | if (mclk > lcdclk / 4) { | 854 | if (mclk > lcdclk / 4) { |
856 | mclk = lcdclk / 4; | 855 | mclk = lcdclk / 4; |
857 | dev_warn(pcdev->dev, "Limiting master clock to %lu\n", mclk); | 856 | dev_warn(pcdev->soc_host.dev, "Limiting master clock to %lu\n", mclk); |
858 | } | 857 | } |
859 | 858 | ||
860 | /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */ | 859 | /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */ |
@@ -864,7 +863,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev) | |||
864 | if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) | 863 | if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) |
865 | pcdev->mclk = lcdclk / (2 * (div + 1)); | 864 | pcdev->mclk = lcdclk / (2 * (div + 1)); |
866 | 865 | ||
867 | dev_dbg(pcdev->dev, "LCD clock %luHz, target freq %luHz, " | 866 | dev_dbg(pcdev->soc_host.dev, "LCD clock %luHz, target freq %luHz, " |
868 | "divisor %u\n", lcdclk, mclk, div); | 867 | "divisor %u\n", lcdclk, mclk, div); |
869 | 868 | ||
870 | return div; | 869 | return div; |
@@ -884,12 +883,12 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev) | |||
884 | struct pxacamera_platform_data *pdata = pcdev->pdata; | 883 | struct pxacamera_platform_data *pdata = pcdev->pdata; |
885 | u32 cicr4 = 0; | 884 | u32 cicr4 = 0; |
886 | 885 | ||
887 | dev_dbg(pcdev->dev, "Registered platform device at %p data %p\n", | 886 | dev_dbg(pcdev->soc_host.dev, "Registered platform device at %p data %p\n", |
888 | pcdev, pdata); | 887 | pcdev, pdata); |
889 | 888 | ||
890 | if (pdata && pdata->init) { | 889 | if (pdata && pdata->init) { |
891 | dev_dbg(pcdev->dev, "%s: Init gpios\n", __func__); | 890 | dev_dbg(pcdev->soc_host.dev, "%s: Init gpios\n", __func__); |
892 | pdata->init(pcdev->dev); | 891 | pdata->init(pcdev->soc_host.dev); |
893 | } | 892 | } |
894 | 893 | ||
895 | /* disable all interrupts */ | 894 | /* disable all interrupts */ |
@@ -931,7 +930,7 @@ static irqreturn_t pxa_camera_irq(int irq, void *data) | |||
931 | struct videobuf_buffer *vb; | 930 | struct videobuf_buffer *vb; |
932 | 931 | ||
933 | status = __raw_readl(pcdev->base + CISR); | 932 | status = __raw_readl(pcdev->base + CISR); |
934 | dev_dbg(pcdev->dev, "Camera interrupt status 0x%lx\n", status); | 933 | dev_dbg(pcdev->soc_host.dev, "Camera interrupt status 0x%lx\n", status); |
935 | 934 | ||
936 | if (!status) | 935 | if (!status) |
937 | return IRQ_NONE; | 936 | return IRQ_NONE; |
@@ -1259,7 +1258,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, | |||
1259 | xlate->cam_fmt = icd->formats + idx; | 1258 | xlate->cam_fmt = icd->formats + idx; |
1260 | xlate->buswidth = buswidth; | 1259 | xlate->buswidth = buswidth; |
1261 | xlate++; | 1260 | xlate++; |
1262 | dev_dbg(&ici->dev, "Providing format %s using %s\n", | 1261 | dev_dbg(ici->dev, "Providing format %s using %s\n", |
1263 | pxa_camera_formats[0].name, | 1262 | pxa_camera_formats[0].name, |
1264 | icd->formats[idx].name); | 1263 | icd->formats[idx].name); |
1265 | } | 1264 | } |
@@ -1274,7 +1273,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, | |||
1274 | xlate->cam_fmt = icd->formats + idx; | 1273 | xlate->cam_fmt = icd->formats + idx; |
1275 | xlate->buswidth = buswidth; | 1274 | xlate->buswidth = buswidth; |
1276 | xlate++; | 1275 | xlate++; |
1277 | dev_dbg(&ici->dev, "Providing format %s packed\n", | 1276 | dev_dbg(ici->dev, "Providing format %s packed\n", |
1278 | icd->formats[idx].name); | 1277 | icd->formats[idx].name); |
1279 | } | 1278 | } |
1280 | break; | 1279 | break; |
@@ -1286,7 +1285,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, | |||
1286 | xlate->cam_fmt = icd->formats + idx; | 1285 | xlate->cam_fmt = icd->formats + idx; |
1287 | xlate->buswidth = icd->formats[idx].depth; | 1286 | xlate->buswidth = icd->formats[idx].depth; |
1288 | xlate++; | 1287 | xlate++; |
1289 | dev_dbg(&ici->dev, | 1288 | dev_dbg(ici->dev, |
1290 | "Providing format %s in pass-through mode\n", | 1289 | "Providing format %s in pass-through mode\n", |
1291 | icd->formats[idx].name); | 1290 | icd->formats[idx].name); |
1292 | } | 1291 | } |
@@ -1315,11 +1314,11 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, | |||
1315 | icd->sense = NULL; | 1314 | icd->sense = NULL; |
1316 | 1315 | ||
1317 | if (ret < 0) { | 1316 | if (ret < 0) { |
1318 | dev_warn(&ici->dev, "Failed to crop to %ux%u@%u:%u\n", | 1317 | dev_warn(ici->dev, "Failed to crop to %ux%u@%u:%u\n", |
1319 | rect->width, rect->height, rect->left, rect->top); | 1318 | rect->width, rect->height, rect->left, rect->top); |
1320 | } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { | 1319 | } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { |
1321 | if (sense.pixel_clock > sense.pixel_clock_max) { | 1320 | if (sense.pixel_clock > sense.pixel_clock_max) { |
1322 | dev_err(&ici->dev, | 1321 | dev_err(ici->dev, |
1323 | "pixel clock %lu set by the camera too high!", | 1322 | "pixel clock %lu set by the camera too high!", |
1324 | sense.pixel_clock); | 1323 | sense.pixel_clock); |
1325 | return -EIO; | 1324 | return -EIO; |
@@ -1347,7 +1346,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, | |||
1347 | 1346 | ||
1348 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | 1347 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); |
1349 | if (!xlate) { | 1348 | if (!xlate) { |
1350 | dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat); | 1349 | dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); |
1351 | return -EINVAL; | 1350 | return -EINVAL; |
1352 | } | 1351 | } |
1353 | 1352 | ||
@@ -1363,11 +1362,11 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, | |||
1363 | icd->sense = NULL; | 1362 | icd->sense = NULL; |
1364 | 1363 | ||
1365 | if (ret < 0) { | 1364 | if (ret < 0) { |
1366 | dev_warn(&ici->dev, "Failed to configure for format %x\n", | 1365 | dev_warn(ici->dev, "Failed to configure for format %x\n", |
1367 | pix->pixelformat); | 1366 | pix->pixelformat); |
1368 | } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { | 1367 | } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { |
1369 | if (sense.pixel_clock > sense.pixel_clock_max) { | 1368 | if (sense.pixel_clock > sense.pixel_clock_max) { |
1370 | dev_err(&ici->dev, | 1369 | dev_err(ici->dev, |
1371 | "pixel clock %lu set by the camera too high!", | 1370 | "pixel clock %lu set by the camera too high!", |
1372 | sense.pixel_clock); | 1371 | sense.pixel_clock); |
1373 | return -EIO; | 1372 | return -EIO; |
@@ -1395,7 +1394,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, | |||
1395 | 1394 | ||
1396 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 1395 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
1397 | if (!xlate) { | 1396 | if (!xlate) { |
1398 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 1397 | dev_warn(ici->dev, "Format %x not found\n", pixfmt); |
1399 | return -EINVAL; | 1398 | return -EINVAL; |
1400 | } | 1399 | } |
1401 | 1400 | ||
@@ -1552,13 +1551,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = { | |||
1552 | .set_bus_param = pxa_camera_set_bus_param, | 1551 | .set_bus_param = pxa_camera_set_bus_param, |
1553 | }; | 1552 | }; |
1554 | 1553 | ||
1555 | /* Should be allocated dynamically too, but we have only one. */ | 1554 | static int __devinit pxa_camera_probe(struct platform_device *pdev) |
1556 | static struct soc_camera_host pxa_soc_camera_host = { | ||
1557 | .drv_name = PXA_CAM_DRV_NAME, | ||
1558 | .ops = &pxa_soc_camera_host_ops, | ||
1559 | }; | ||
1560 | |||
1561 | static int pxa_camera_probe(struct platform_device *pdev) | ||
1562 | { | 1555 | { |
1563 | struct pxa_camera_dev *pcdev; | 1556 | struct pxa_camera_dev *pcdev; |
1564 | struct resource *res; | 1557 | struct resource *res; |
@@ -1586,7 +1579,6 @@ static int pxa_camera_probe(struct platform_device *pdev) | |||
1586 | goto exit_kfree; | 1579 | goto exit_kfree; |
1587 | } | 1580 | } |
1588 | 1581 | ||
1589 | dev_set_drvdata(&pdev->dev, pcdev); | ||
1590 | pcdev->res = res; | 1582 | pcdev->res = res; |
1591 | 1583 | ||
1592 | pcdev->pdata = pdev->dev.platform_data; | 1584 | pcdev->pdata = pdev->dev.platform_data; |
@@ -1607,7 +1599,6 @@ static int pxa_camera_probe(struct platform_device *pdev) | |||
1607 | pcdev->mclk = 20000000; | 1599 | pcdev->mclk = 20000000; |
1608 | } | 1600 | } |
1609 | 1601 | ||
1610 | pcdev->dev = &pdev->dev; | ||
1611 | pcdev->mclk_divisor = mclk_get_divisor(pcdev); | 1602 | pcdev->mclk_divisor = mclk_get_divisor(pcdev); |
1612 | 1603 | ||
1613 | INIT_LIST_HEAD(&pcdev->capture); | 1604 | INIT_LIST_HEAD(&pcdev->capture); |
@@ -1616,13 +1607,13 @@ static int pxa_camera_probe(struct platform_device *pdev) | |||
1616 | /* | 1607 | /* |
1617 | * Request the regions. | 1608 | * Request the regions. |
1618 | */ | 1609 | */ |
1619 | if (!request_mem_region(res->start, res->end - res->start + 1, | 1610 | if (!request_mem_region(res->start, resource_size(res), |
1620 | PXA_CAM_DRV_NAME)) { | 1611 | PXA_CAM_DRV_NAME)) { |
1621 | err = -EBUSY; | 1612 | err = -EBUSY; |
1622 | goto exit_clk; | 1613 | goto exit_clk; |
1623 | } | 1614 | } |
1624 | 1615 | ||
1625 | base = ioremap(res->start, res->end - res->start + 1); | 1616 | base = ioremap(res->start, resource_size(res)); |
1626 | if (!base) { | 1617 | if (!base) { |
1627 | err = -ENOMEM; | 1618 | err = -ENOMEM; |
1628 | goto exit_release; | 1619 | goto exit_release; |
@@ -1634,29 +1625,29 @@ static int pxa_camera_probe(struct platform_device *pdev) | |||
1634 | err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, | 1625 | err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, |
1635 | pxa_camera_dma_irq_y, pcdev); | 1626 | pxa_camera_dma_irq_y, pcdev); |
1636 | if (err < 0) { | 1627 | if (err < 0) { |
1637 | dev_err(pcdev->dev, "Can't request DMA for Y\n"); | 1628 | dev_err(&pdev->dev, "Can't request DMA for Y\n"); |
1638 | goto exit_iounmap; | 1629 | goto exit_iounmap; |
1639 | } | 1630 | } |
1640 | pcdev->dma_chans[0] = err; | 1631 | pcdev->dma_chans[0] = err; |
1641 | dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]); | 1632 | dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]); |
1642 | 1633 | ||
1643 | err = pxa_request_dma("CI_U", DMA_PRIO_HIGH, | 1634 | err = pxa_request_dma("CI_U", DMA_PRIO_HIGH, |
1644 | pxa_camera_dma_irq_u, pcdev); | 1635 | pxa_camera_dma_irq_u, pcdev); |
1645 | if (err < 0) { | 1636 | if (err < 0) { |
1646 | dev_err(pcdev->dev, "Can't request DMA for U\n"); | 1637 | dev_err(&pdev->dev, "Can't request DMA for U\n"); |
1647 | goto exit_free_dma_y; | 1638 | goto exit_free_dma_y; |
1648 | } | 1639 | } |
1649 | pcdev->dma_chans[1] = err; | 1640 | pcdev->dma_chans[1] = err; |
1650 | dev_dbg(pcdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]); | 1641 | dev_dbg(&pdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]); |
1651 | 1642 | ||
1652 | err = pxa_request_dma("CI_V", DMA_PRIO_HIGH, | 1643 | err = pxa_request_dma("CI_V", DMA_PRIO_HIGH, |
1653 | pxa_camera_dma_irq_v, pcdev); | 1644 | pxa_camera_dma_irq_v, pcdev); |
1654 | if (err < 0) { | 1645 | if (err < 0) { |
1655 | dev_err(pcdev->dev, "Can't request DMA for V\n"); | 1646 | dev_err(&pdev->dev, "Can't request DMA for V\n"); |
1656 | goto exit_free_dma_u; | 1647 | goto exit_free_dma_u; |
1657 | } | 1648 | } |
1658 | pcdev->dma_chans[2] = err; | 1649 | pcdev->dma_chans[2] = err; |
1659 | dev_dbg(pcdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]); | 1650 | dev_dbg(&pdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]); |
1660 | 1651 | ||
1661 | DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD; | 1652 | DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD; |
1662 | DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD; | 1653 | DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD; |
@@ -1666,14 +1657,17 @@ static int pxa_camera_probe(struct platform_device *pdev) | |||
1666 | err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME, | 1657 | err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME, |
1667 | pcdev); | 1658 | pcdev); |
1668 | if (err) { | 1659 | if (err) { |
1669 | dev_err(pcdev->dev, "Camera interrupt register failed \n"); | 1660 | dev_err(&pdev->dev, "Camera interrupt register failed \n"); |
1670 | goto exit_free_dma; | 1661 | goto exit_free_dma; |
1671 | } | 1662 | } |
1672 | 1663 | ||
1673 | pxa_soc_camera_host.priv = pcdev; | 1664 | pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME; |
1674 | pxa_soc_camera_host.dev.parent = &pdev->dev; | 1665 | pcdev->soc_host.ops = &pxa_soc_camera_host_ops; |
1675 | pxa_soc_camera_host.nr = pdev->id; | 1666 | pcdev->soc_host.priv = pcdev; |
1676 | err = soc_camera_host_register(&pxa_soc_camera_host); | 1667 | pcdev->soc_host.dev = &pdev->dev; |
1668 | pcdev->soc_host.nr = pdev->id; | ||
1669 | |||
1670 | err = soc_camera_host_register(&pcdev->soc_host); | ||
1677 | if (err) | 1671 | if (err) |
1678 | goto exit_free_irq; | 1672 | goto exit_free_irq; |
1679 | 1673 | ||
@@ -1690,7 +1684,7 @@ exit_free_dma_y: | |||
1690 | exit_iounmap: | 1684 | exit_iounmap: |
1691 | iounmap(base); | 1685 | iounmap(base); |
1692 | exit_release: | 1686 | exit_release: |
1693 | release_mem_region(res->start, res->end - res->start + 1); | 1687 | release_mem_region(res->start, resource_size(res)); |
1694 | exit_clk: | 1688 | exit_clk: |
1695 | clk_put(pcdev->clk); | 1689 | clk_put(pcdev->clk); |
1696 | exit_kfree: | 1690 | exit_kfree: |
@@ -1701,7 +1695,9 @@ exit: | |||
1701 | 1695 | ||
1702 | static int __devexit pxa_camera_remove(struct platform_device *pdev) | 1696 | static int __devexit pxa_camera_remove(struct platform_device *pdev) |
1703 | { | 1697 | { |
1704 | struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev); | 1698 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); |
1699 | struct pxa_camera_dev *pcdev = container_of(soc_host, | ||
1700 | struct pxa_camera_dev, soc_host); | ||
1705 | struct resource *res; | 1701 | struct resource *res; |
1706 | 1702 | ||
1707 | clk_put(pcdev->clk); | 1703 | clk_put(pcdev->clk); |
@@ -1711,12 +1707,12 @@ static int __devexit pxa_camera_remove(struct platform_device *pdev) | |||
1711 | pxa_free_dma(pcdev->dma_chans[2]); | 1707 | pxa_free_dma(pcdev->dma_chans[2]); |
1712 | free_irq(pcdev->irq, pcdev); | 1708 | free_irq(pcdev->irq, pcdev); |
1713 | 1709 | ||
1714 | soc_camera_host_unregister(&pxa_soc_camera_host); | 1710 | soc_camera_host_unregister(soc_host); |
1715 | 1711 | ||
1716 | iounmap(pcdev->base); | 1712 | iounmap(pcdev->base); |
1717 | 1713 | ||
1718 | res = pcdev->res; | 1714 | res = pcdev->res; |
1719 | release_mem_region(res->start, res->end - res->start + 1); | 1715 | release_mem_region(res->start, resource_size(res)); |
1720 | 1716 | ||
1721 | kfree(pcdev); | 1717 | kfree(pcdev); |
1722 | 1718 | ||
@@ -1730,11 +1726,11 @@ static struct platform_driver pxa_camera_driver = { | |||
1730 | .name = PXA_CAM_DRV_NAME, | 1726 | .name = PXA_CAM_DRV_NAME, |
1731 | }, | 1727 | }, |
1732 | .probe = pxa_camera_probe, | 1728 | .probe = pxa_camera_probe, |
1733 | .remove = __exit_p(pxa_camera_remove), | 1729 | .remove = __devexit_p(pxa_camera_remove), |
1734 | }; | 1730 | }; |
1735 | 1731 | ||
1736 | 1732 | ||
1737 | static int __devinit pxa_camera_init(void) | 1733 | static int __init pxa_camera_init(void) |
1738 | { | 1734 | { |
1739 | return platform_driver_register(&pxa_camera_driver); | 1735 | return platform_driver_register(&pxa_camera_driver); |
1740 | } | 1736 | } |
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 30f4698be90a..6be845ccc7d7 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
@@ -77,6 +77,8 @@ | |||
77 | #define MAX_CHANNELS 4 | 77 | #define MAX_CHANNELS 4 |
78 | #define S2255_MARKER_FRAME 0x2255DA4AL | 78 | #define S2255_MARKER_FRAME 0x2255DA4AL |
79 | #define S2255_MARKER_RESPONSE 0x2255ACACL | 79 | #define S2255_MARKER_RESPONSE 0x2255ACACL |
80 | #define S2255_RESPONSE_SETMODE 0x01 | ||
81 | #define S2255_RESPONSE_FW 0x10 | ||
80 | #define S2255_USB_XFER_SIZE (16 * 1024) | 82 | #define S2255_USB_XFER_SIZE (16 * 1024) |
81 | #define MAX_CHANNELS 4 | 83 | #define MAX_CHANNELS 4 |
82 | #define MAX_PIPE_BUFFERS 1 | 84 | #define MAX_PIPE_BUFFERS 1 |
@@ -107,6 +109,8 @@ | |||
107 | #define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */ | 109 | #define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */ |
108 | #define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */ | 110 | #define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */ |
109 | #define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */ | 111 | #define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */ |
112 | /* SCALE_4CIFSI is the 2 fields interpolated into one */ | ||
113 | #define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */ | ||
110 | 114 | ||
111 | #define COLOR_YUVPL 1 /* YUV planar */ | 115 | #define COLOR_YUVPL 1 /* YUV planar */ |
112 | #define COLOR_YUVPK 2 /* YUV packed */ | 116 | #define COLOR_YUVPK 2 /* YUV packed */ |
@@ -178,9 +182,6 @@ struct s2255_bufferi { | |||
178 | 182 | ||
179 | struct s2255_dmaqueue { | 183 | struct s2255_dmaqueue { |
180 | struct list_head active; | 184 | struct list_head active; |
181 | /* thread for acquisition */ | ||
182 | struct task_struct *kthread; | ||
183 | int frame; | ||
184 | struct s2255_dev *dev; | 185 | struct s2255_dev *dev; |
185 | int channel; | 186 | int channel; |
186 | }; | 187 | }; |
@@ -210,16 +211,11 @@ struct s2255_pipeinfo { | |||
210 | u32 max_transfer_size; | 211 | u32 max_transfer_size; |
211 | u32 cur_transfer_size; | 212 | u32 cur_transfer_size; |
212 | u8 *transfer_buffer; | 213 | u8 *transfer_buffer; |
213 | u32 transfer_flags;; | ||
214 | u32 state; | 214 | u32 state; |
215 | u32 prev_state; | ||
216 | u32 urb_size; | ||
217 | void *stream_urb; | 215 | void *stream_urb; |
218 | void *dev; /* back pointer to s2255_dev struct*/ | 216 | void *dev; /* back pointer to s2255_dev struct*/ |
219 | u32 err_count; | 217 | u32 err_count; |
220 | u32 buf_index; | ||
221 | u32 idx; | 218 | u32 idx; |
222 | u32 priority_set; | ||
223 | }; | 219 | }; |
224 | 220 | ||
225 | struct s2255_fmt; /*forward declaration */ | 221 | struct s2255_fmt; /*forward declaration */ |
@@ -239,13 +235,13 @@ struct s2255_dev { | |||
239 | struct list_head s2255_devlist; | 235 | struct list_head s2255_devlist; |
240 | struct timer_list timer; | 236 | struct timer_list timer; |
241 | struct s2255_fw *fw_data; | 237 | struct s2255_fw *fw_data; |
242 | int board_num; | ||
243 | int is_open; | ||
244 | struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; | 238 | struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; |
245 | struct s2255_bufferi buffer[MAX_CHANNELS]; | 239 | struct s2255_bufferi buffer[MAX_CHANNELS]; |
246 | struct s2255_mode mode[MAX_CHANNELS]; | 240 | struct s2255_mode mode[MAX_CHANNELS]; |
247 | /* jpeg compression */ | 241 | /* jpeg compression */ |
248 | struct v4l2_jpegcompression jc[MAX_CHANNELS]; | 242 | struct v4l2_jpegcompression jc[MAX_CHANNELS]; |
243 | /* capture parameters (for high quality mode full size) */ | ||
244 | struct v4l2_captureparm cap_parm[MAX_CHANNELS]; | ||
249 | const struct s2255_fmt *cur_fmt[MAX_CHANNELS]; | 245 | const struct s2255_fmt *cur_fmt[MAX_CHANNELS]; |
250 | int cur_frame[MAX_CHANNELS]; | 246 | int cur_frame[MAX_CHANNELS]; |
251 | int last_frame[MAX_CHANNELS]; | 247 | int last_frame[MAX_CHANNELS]; |
@@ -297,9 +293,10 @@ struct s2255_fh { | |||
297 | int resources[MAX_CHANNELS]; | 293 | int resources[MAX_CHANNELS]; |
298 | }; | 294 | }; |
299 | 295 | ||
300 | #define CUR_USB_FWVER 774 /* current cypress EEPROM firmware version */ | 296 | /* current cypress EEPROM firmware version */ |
297 | #define S2255_CUR_USB_FWVER ((3 << 8) | 6) | ||
301 | #define S2255_MAJOR_VERSION 1 | 298 | #define S2255_MAJOR_VERSION 1 |
302 | #define S2255_MINOR_VERSION 13 | 299 | #define S2255_MINOR_VERSION 14 |
303 | #define S2255_RELEASE 0 | 300 | #define S2255_RELEASE 0 |
304 | #define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ | 301 | #define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ |
305 | S2255_MINOR_VERSION, \ | 302 | S2255_MINOR_VERSION, \ |
@@ -1027,9 +1024,16 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
1027 | fh->type = f->type; | 1024 | fh->type = f->type; |
1028 | norm = norm_minw(fh->dev->vdev[fh->channel]); | 1025 | norm = norm_minw(fh->dev->vdev[fh->channel]); |
1029 | if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) { | 1026 | if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) { |
1030 | if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) | 1027 | if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) { |
1031 | fh->mode.scale = SCALE_4CIFS; | 1028 | if (fh->dev->cap_parm[fh->channel].capturemode & |
1032 | else | 1029 | V4L2_MODE_HIGHQUALITY) { |
1030 | fh->mode.scale = SCALE_4CIFSI; | ||
1031 | dprintk(2, "scale 4CIFSI\n"); | ||
1032 | } else { | ||
1033 | fh->mode.scale = SCALE_4CIFS; | ||
1034 | dprintk(2, "scale 4CIFS\n"); | ||
1035 | } | ||
1036 | } else | ||
1033 | fh->mode.scale = SCALE_2CIFS; | 1037 | fh->mode.scale = SCALE_2CIFS; |
1034 | 1038 | ||
1035 | } else { | 1039 | } else { |
@@ -1130,6 +1134,7 @@ static u32 get_transfer_size(struct s2255_mode *mode) | |||
1130 | if (mode->format == FORMAT_NTSC) { | 1134 | if (mode->format == FORMAT_NTSC) { |
1131 | switch (mode->scale) { | 1135 | switch (mode->scale) { |
1132 | case SCALE_4CIFS: | 1136 | case SCALE_4CIFS: |
1137 | case SCALE_4CIFSI: | ||
1133 | linesPerFrame = NUM_LINES_4CIFS_NTSC * 2; | 1138 | linesPerFrame = NUM_LINES_4CIFS_NTSC * 2; |
1134 | pixelsPerLine = LINE_SZ_4CIFS_NTSC; | 1139 | pixelsPerLine = LINE_SZ_4CIFS_NTSC; |
1135 | break; | 1140 | break; |
@@ -1147,6 +1152,7 @@ static u32 get_transfer_size(struct s2255_mode *mode) | |||
1147 | } else if (mode->format == FORMAT_PAL) { | 1152 | } else if (mode->format == FORMAT_PAL) { |
1148 | switch (mode->scale) { | 1153 | switch (mode->scale) { |
1149 | case SCALE_4CIFS: | 1154 | case SCALE_4CIFS: |
1155 | case SCALE_4CIFSI: | ||
1150 | linesPerFrame = NUM_LINES_4CIFS_PAL * 2; | 1156 | linesPerFrame = NUM_LINES_4CIFS_PAL * 2; |
1151 | pixelsPerLine = LINE_SZ_4CIFS_PAL; | 1157 | pixelsPerLine = LINE_SZ_4CIFS_PAL; |
1152 | break; | 1158 | break; |
@@ -1502,6 +1508,33 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, | |||
1502 | dprintk(2, "setting jpeg quality %d\n", jc->quality); | 1508 | dprintk(2, "setting jpeg quality %d\n", jc->quality); |
1503 | return 0; | 1509 | return 0; |
1504 | } | 1510 | } |
1511 | |||
1512 | static int vidioc_g_parm(struct file *file, void *priv, | ||
1513 | struct v4l2_streamparm *sp) | ||
1514 | { | ||
1515 | struct s2255_fh *fh = priv; | ||
1516 | struct s2255_dev *dev = fh->dev; | ||
1517 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1518 | return -EINVAL; | ||
1519 | sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode; | ||
1520 | dprintk(2, "getting parm %d\n", sp->parm.capture.capturemode); | ||
1521 | return 0; | ||
1522 | } | ||
1523 | |||
1524 | static int vidioc_s_parm(struct file *file, void *priv, | ||
1525 | struct v4l2_streamparm *sp) | ||
1526 | { | ||
1527 | struct s2255_fh *fh = priv; | ||
1528 | struct s2255_dev *dev = fh->dev; | ||
1529 | |||
1530 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1531 | return -EINVAL; | ||
1532 | |||
1533 | dev->cap_parm[fh->channel].capturemode = sp->parm.capture.capturemode; | ||
1534 | dprintk(2, "setting param capture mode %d\n", | ||
1535 | sp->parm.capture.capturemode); | ||
1536 | return 0; | ||
1537 | } | ||
1505 | static int s2255_open(struct file *file) | 1538 | static int s2255_open(struct file *file) |
1506 | { | 1539 | { |
1507 | int minor = video_devdata(file)->minor; | 1540 | int minor = video_devdata(file)->minor; |
@@ -1793,6 +1826,8 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | |||
1793 | #endif | 1826 | #endif |
1794 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, | 1827 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, |
1795 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, | 1828 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, |
1829 | .vidioc_s_parm = vidioc_s_parm, | ||
1830 | .vidioc_g_parm = vidioc_g_parm, | ||
1796 | }; | 1831 | }; |
1797 | 1832 | ||
1798 | static struct video_device template = { | 1833 | static struct video_device template = { |
@@ -1818,7 +1853,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1818 | INIT_LIST_HEAD(&dev->vidq[i].active); | 1853 | INIT_LIST_HEAD(&dev->vidq[i].active); |
1819 | dev->vidq[i].dev = dev; | 1854 | dev->vidq[i].dev = dev; |
1820 | dev->vidq[i].channel = i; | 1855 | dev->vidq[i].channel = i; |
1821 | dev->vidq[i].kthread = NULL; | ||
1822 | /* register 4 video devices */ | 1856 | /* register 4 video devices */ |
1823 | dev->vdev[i] = video_device_alloc(); | 1857 | dev->vdev[i] = video_device_alloc(); |
1824 | memcpy(dev->vdev[i], &template, sizeof(struct video_device)); | 1858 | memcpy(dev->vdev[i], &template, sizeof(struct video_device)); |
@@ -1839,7 +1873,9 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1839 | return ret; | 1873 | return ret; |
1840 | } | 1874 | } |
1841 | } | 1875 | } |
1842 | printk(KERN_INFO "Sensoray 2255 V4L driver\n"); | 1876 | printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n", |
1877 | S2255_MAJOR_VERSION, | ||
1878 | S2255_MINOR_VERSION); | ||
1843 | return ret; | 1879 | return ret; |
1844 | } | 1880 | } |
1845 | 1881 | ||
@@ -1929,14 +1965,14 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) | |||
1929 | if (!(cc >= 0 && cc < MAX_CHANNELS)) | 1965 | if (!(cc >= 0 && cc < MAX_CHANNELS)) |
1930 | break; | 1966 | break; |
1931 | switch (pdword[2]) { | 1967 | switch (pdword[2]) { |
1932 | case 0x01: | 1968 | case S2255_RESPONSE_SETMODE: |
1933 | /* check if channel valid */ | 1969 | /* check if channel valid */ |
1934 | /* set mode ready */ | 1970 | /* set mode ready */ |
1935 | dev->setmode_ready[cc] = 1; | 1971 | dev->setmode_ready[cc] = 1; |
1936 | wake_up(&dev->wait_setmode[cc]); | 1972 | wake_up(&dev->wait_setmode[cc]); |
1937 | dprintk(5, "setmode ready %d\n", cc); | 1973 | dprintk(5, "setmode ready %d\n", cc); |
1938 | break; | 1974 | break; |
1939 | case 0x10: | 1975 | case S2255_RESPONSE_FW: |
1940 | 1976 | ||
1941 | dev->chn_ready |= (1 << cc); | 1977 | dev->chn_ready |= (1 << cc); |
1942 | if ((dev->chn_ready & 0x0f) != 0x0f) | 1978 | if ((dev->chn_ready & 0x0f) != 0x0f) |
@@ -2172,10 +2208,15 @@ static int s2255_board_init(struct s2255_dev *dev) | |||
2172 | /* query the firmware */ | 2208 | /* query the firmware */ |
2173 | fw_ver = s2255_get_fx2fw(dev); | 2209 | fw_ver = s2255_get_fx2fw(dev); |
2174 | 2210 | ||
2175 | printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver); | 2211 | printk(KERN_INFO "2255 usb firmware version %d.%d\n", |
2176 | if (fw_ver < CUR_USB_FWVER) | 2212 | (fw_ver >> 8) & 0xff, |
2213 | fw_ver & 0xff); | ||
2214 | |||
2215 | if (fw_ver < S2255_CUR_USB_FWVER) | ||
2177 | dev_err(&dev->udev->dev, | 2216 | dev_err(&dev->udev->dev, |
2178 | "usb firmware not up to date %d\n", fw_ver); | 2217 | "usb firmware not up to date %d.%d\n", |
2218 | (fw_ver >> 8) & 0xff, | ||
2219 | fw_ver & 0xff); | ||
2179 | 2220 | ||
2180 | for (j = 0; j < MAX_CHANNELS; j++) { | 2221 | for (j = 0; j < MAX_CHANNELS; j++) { |
2181 | dev->b_acquire[j] = 0; | 2222 | dev->b_acquire[j] = 0; |
@@ -2240,8 +2281,10 @@ static void read_pipe_completion(struct urb *purb) | |||
2240 | return; | 2281 | return; |
2241 | } | 2282 | } |
2242 | status = purb->status; | 2283 | status = purb->status; |
2243 | if (status != 0) { | 2284 | /* if shutting down, do not resubmit, exit immediately */ |
2244 | dprintk(2, "read_pipe_completion: err\n"); | 2285 | if (status == -ESHUTDOWN) { |
2286 | dprintk(2, "read_pipe_completion: err shutdown\n"); | ||
2287 | pipe_info->err_count++; | ||
2245 | return; | 2288 | return; |
2246 | } | 2289 | } |
2247 | 2290 | ||
@@ -2250,9 +2293,13 @@ static void read_pipe_completion(struct urb *purb) | |||
2250 | return; | 2293 | return; |
2251 | } | 2294 | } |
2252 | 2295 | ||
2253 | s2255_read_video_callback(dev, pipe_info); | 2296 | if (status == 0) |
2297 | s2255_read_video_callback(dev, pipe_info); | ||
2298 | else { | ||
2299 | pipe_info->err_count++; | ||
2300 | dprintk(1, "s2255drv: failed URB %d\n", status); | ||
2301 | } | ||
2254 | 2302 | ||
2255 | pipe_info->err_count = 0; | ||
2256 | pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); | 2303 | pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); |
2257 | /* reuse urb */ | 2304 | /* reuse urb */ |
2258 | usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, | 2305 | usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, |
@@ -2264,7 +2311,6 @@ static void read_pipe_completion(struct urb *purb) | |||
2264 | if (pipe_info->state != 0) { | 2311 | if (pipe_info->state != 0) { |
2265 | if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) { | 2312 | if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) { |
2266 | dev_err(&dev->udev->dev, "error submitting urb\n"); | 2313 | dev_err(&dev->udev->dev, "error submitting urb\n"); |
2267 | usb_free_urb(pipe_info->stream_urb); | ||
2268 | } | 2314 | } |
2269 | } else { | 2315 | } else { |
2270 | dprintk(2, "read pipe complete state 0\n"); | 2316 | dprintk(2, "read pipe complete state 0\n"); |
@@ -2283,8 +2329,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev) | |||
2283 | 2329 | ||
2284 | for (i = 0; i < MAX_PIPE_BUFFERS; i++) { | 2330 | for (i = 0; i < MAX_PIPE_BUFFERS; i++) { |
2285 | pipe_info->state = 1; | 2331 | pipe_info->state = 1; |
2286 | pipe_info->buf_index = (u32) i; | 2332 | pipe_info->err_count = 0; |
2287 | pipe_info->priority_set = 0; | ||
2288 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); | 2333 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); |
2289 | if (!pipe_info->stream_urb) { | 2334 | if (!pipe_info->stream_urb) { |
2290 | dev_err(&dev->udev->dev, | 2335 | dev_err(&dev->udev->dev, |
@@ -2298,7 +2343,6 @@ static int s2255_start_readpipe(struct s2255_dev *dev) | |||
2298 | pipe_info->cur_transfer_size, | 2343 | pipe_info->cur_transfer_size, |
2299 | read_pipe_completion, pipe_info); | 2344 | read_pipe_completion, pipe_info); |
2300 | 2345 | ||
2301 | pipe_info->urb_size = sizeof(pipe_info->stream_urb); | ||
2302 | dprintk(4, "submitting URB %p\n", pipe_info->stream_urb); | 2346 | dprintk(4, "submitting URB %p\n", pipe_info->stream_urb); |
2303 | retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); | 2347 | retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); |
2304 | if (retval) { | 2348 | if (retval) { |
@@ -2403,8 +2447,6 @@ static void s2255_stop_readpipe(struct s2255_dev *dev) | |||
2403 | if (pipe_info->state == 0) | 2447 | if (pipe_info->state == 0) |
2404 | continue; | 2448 | continue; |
2405 | pipe_info->state = 0; | 2449 | pipe_info->state = 0; |
2406 | pipe_info->prev_state = 1; | ||
2407 | |||
2408 | } | 2450 | } |
2409 | } | 2451 | } |
2410 | 2452 | ||
@@ -2542,7 +2584,9 @@ static int s2255_probe(struct usb_interface *interface, | |||
2542 | s2255_probe_v4l(dev); | 2584 | s2255_probe_v4l(dev); |
2543 | usb_reset_device(dev->udev); | 2585 | usb_reset_device(dev->udev); |
2544 | /* load 2255 board specific */ | 2586 | /* load 2255 board specific */ |
2545 | s2255_board_init(dev); | 2587 | retval = s2255_board_init(dev); |
2588 | if (retval) | ||
2589 | goto error; | ||
2546 | 2590 | ||
2547 | dprintk(4, "before probe done %p\n", dev); | 2591 | dprintk(4, "before probe done %p\n", dev); |
2548 | spin_lock_init(&dev->slock); | 2592 | spin_lock_init(&dev->slock); |
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index 0ba68987bfce..5bcce092e804 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig | |||
@@ -44,6 +44,7 @@ config VIDEO_SAA7134_DVB | |||
44 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | 44 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE |
45 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | 45 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE |
46 | select DVB_LGDT3305 if !DVB_FE_CUSTOMISE | 46 | select DVB_LGDT3305 if !DVB_FE_CUSTOMISE |
47 | select DVB_TDA10048 if !DVB_FE_CUSTOMISE | ||
47 | select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE | 48 | select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE |
48 | select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE | 49 | select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE |
49 | ---help--- | 50 | ---help--- |
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index 3dbaa19a6d00..604158a8c235 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile | |||
@@ -3,8 +3,7 @@ saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \ | |||
3 | saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o \ | 3 | saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o \ |
4 | saa7134-video.o saa7134-input.o | 4 | saa7134-video.o saa7134-input.o |
5 | 5 | ||
6 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \ | 6 | obj-$(CONFIG_VIDEO_SAA7134) += saa6752hs.o saa7134.o saa7134-empress.o |
7 | saa6752hs.o | ||
8 | 7 | ||
9 | obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o | 8 | obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o |
10 | 9 | ||
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index fdb19449d269..06861b782b95 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -1669,6 +1669,39 @@ struct saa7134_board saa7134_boards[] = { | |||
1669 | .amux = LINE1, | 1669 | .amux = LINE1, |
1670 | }, | 1670 | }, |
1671 | }, | 1671 | }, |
1672 | [SAA7134_BOARD_AVERMEDIA_CARDBUS_501] = { | ||
1673 | /* Oldrich Jedlicka <oldium.pro@seznam.cz> */ | ||
1674 | .name = "AVerMedia Cardbus TV/Radio (E501R)", | ||
1675 | .audio_clock = 0x187de7, | ||
1676 | .tuner_type = TUNER_ALPS_TSBE5_PAL, | ||
1677 | .radio_type = TUNER_TEA5767, | ||
1678 | .tuner_addr = 0x61, | ||
1679 | .radio_addr = 0x60, | ||
1680 | .tda9887_conf = TDA9887_PRESENT, | ||
1681 | .gpiomask = 0x08000000, | ||
1682 | .inputs = { { | ||
1683 | .name = name_tv, | ||
1684 | .vmux = 1, | ||
1685 | .amux = TV, | ||
1686 | .tv = 1, | ||
1687 | .gpio = 0x08000000, | ||
1688 | }, { | ||
1689 | .name = name_comp1, | ||
1690 | .vmux = 3, | ||
1691 | .amux = LINE1, | ||
1692 | .gpio = 0x08000000, | ||
1693 | }, { | ||
1694 | .name = name_svideo, | ||
1695 | .vmux = 8, | ||
1696 | .amux = LINE1, | ||
1697 | .gpio = 0x08000000, | ||
1698 | } }, | ||
1699 | .radio = { | ||
1700 | .name = name_radio, | ||
1701 | .amux = LINE2, | ||
1702 | .gpio = 0x00000000, | ||
1703 | }, | ||
1704 | }, | ||
1672 | [SAA7134_BOARD_CINERGY400_CARDBUS] = { | 1705 | [SAA7134_BOARD_CINERGY400_CARDBUS] = { |
1673 | .name = "Terratec Cinergy 400 mobile", | 1706 | .name = "Terratec Cinergy 400 mobile", |
1674 | .audio_clock = 0x187de7, | 1707 | .audio_clock = 0x187de7, |
@@ -3331,13 +3364,15 @@ struct saa7134_board saa7134_boards[] = { | |||
3331 | }, | 3364 | }, |
3332 | }, | 3365 | }, |
3333 | [SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = { | 3366 | [SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = { |
3334 | .name = "Hauppauge WinTV-HVR1110r3", | 3367 | .name = "Hauppauge WinTV-HVR1110r3 DVB-T/Hybrid", |
3335 | .audio_clock = 0x00187de7, | 3368 | .audio_clock = 0x00187de7, |
3336 | .tuner_type = TUNER_PHILIPS_TDA8290, | 3369 | .tuner_type = TUNER_PHILIPS_TDA8290, |
3337 | .radio_type = UNSET, | 3370 | .radio_type = UNSET, |
3338 | .tuner_addr = ADDR_UNSET, | 3371 | .tuner_addr = ADDR_UNSET, |
3339 | .radio_addr = ADDR_UNSET, | 3372 | .radio_addr = ADDR_UNSET, |
3340 | .tuner_config = 3, | 3373 | .tuner_config = 3, |
3374 | .mpeg = SAA7134_MPEG_DVB, | ||
3375 | .ts_type = SAA7134_MPEG_TS_SERIAL, | ||
3341 | .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */ | 3376 | .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */ |
3342 | .inputs = {{ | 3377 | .inputs = {{ |
3343 | .name = name_tv, | 3378 | .name = name_tv, |
@@ -4006,7 +4041,7 @@ struct saa7134_board saa7134_boards[] = { | |||
4006 | [SAA7134_BOARD_BEHOLD_505FM] = { | 4041 | [SAA7134_BOARD_BEHOLD_505FM] = { |
4007 | /* Beholder Intl. Ltd. 2008 */ | 4042 | /* Beholder Intl. Ltd. 2008 */ |
4008 | /*Dmitry Belimov <d.belimov@gmail.com> */ | 4043 | /*Dmitry Belimov <d.belimov@gmail.com> */ |
4009 | .name = "Beholder BeholdTV 505 FM/RDS", | 4044 | .name = "Beholder BeholdTV 505 FM", |
4010 | .audio_clock = 0x00200000, | 4045 | .audio_clock = 0x00200000, |
4011 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 4046 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
4012 | .radio_type = UNSET, | 4047 | .radio_type = UNSET, |
@@ -4019,6 +4054,40 @@ struct saa7134_board saa7134_boards[] = { | |||
4019 | .vmux = 3, | 4054 | .vmux = 3, |
4020 | .amux = LINE2, | 4055 | .amux = LINE2, |
4021 | .tv = 1, | 4056 | .tv = 1, |
4057 | }, { | ||
4058 | .name = name_comp1, | ||
4059 | .vmux = 1, | ||
4060 | .amux = LINE1, | ||
4061 | }, { | ||
4062 | .name = name_svideo, | ||
4063 | .vmux = 8, | ||
4064 | .amux = LINE1, | ||
4065 | } }, | ||
4066 | .mute = { | ||
4067 | .name = name_mute, | ||
4068 | .amux = LINE1, | ||
4069 | }, | ||
4070 | .radio = { | ||
4071 | .name = name_radio, | ||
4072 | .amux = LINE2, | ||
4073 | }, | ||
4074 | }, | ||
4075 | [SAA7134_BOARD_BEHOLD_505RDS] = { | ||
4076 | /* Beholder Intl. Ltd. 2008 */ | ||
4077 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
4078 | .name = "Beholder BeholdTV 505 RDS", | ||
4079 | .audio_clock = 0x00200000, | ||
4080 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4081 | .radio_type = UNSET, | ||
4082 | .tuner_addr = ADDR_UNSET, | ||
4083 | .radio_addr = ADDR_UNSET, | ||
4084 | .tda9887_conf = TDA9887_PRESENT, | ||
4085 | .gpiomask = 0x00008000, | ||
4086 | .inputs = {{ | ||
4087 | .name = name_tv, | ||
4088 | .vmux = 3, | ||
4089 | .amux = LINE2, | ||
4090 | .tv = 1, | ||
4022 | },{ | 4091 | },{ |
4023 | .name = name_comp1, | 4092 | .name = name_comp1, |
4024 | .vmux = 1, | 4093 | .vmux = 1, |
@@ -4040,7 +4109,7 @@ struct saa7134_board saa7134_boards[] = { | |||
4040 | [SAA7134_BOARD_BEHOLD_507_9FM] = { | 4109 | [SAA7134_BOARD_BEHOLD_507_9FM] = { |
4041 | /* Beholder Intl. Ltd. 2008 */ | 4110 | /* Beholder Intl. Ltd. 2008 */ |
4042 | /*Dmitry Belimov <d.belimov@gmail.com> */ | 4111 | /*Dmitry Belimov <d.belimov@gmail.com> */ |
4043 | .name = "Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM", | 4112 | .name = "Beholder BeholdTV 507 FM / BeholdTV 509 FM", |
4044 | .audio_clock = 0x00187de7, | 4113 | .audio_clock = 0x00187de7, |
4045 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 4114 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
4046 | .radio_type = UNSET, | 4115 | .radio_type = UNSET, |
@@ -4067,6 +4136,66 @@ struct saa7134_board saa7134_boards[] = { | |||
4067 | .amux = LINE2, | 4136 | .amux = LINE2, |
4068 | }, | 4137 | }, |
4069 | }, | 4138 | }, |
4139 | [SAA7134_BOARD_BEHOLD_507RDS_MK5] = { | ||
4140 | /* Beholder Intl. Ltd. 2008 */ | ||
4141 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
4142 | .name = "Beholder BeholdTV 507 RDS", | ||
4143 | .audio_clock = 0x00187de7, | ||
4144 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4145 | .radio_type = UNSET, | ||
4146 | .tuner_addr = ADDR_UNSET, | ||
4147 | .radio_addr = ADDR_UNSET, | ||
4148 | .tda9887_conf = TDA9887_PRESENT, | ||
4149 | .gpiomask = 0x00008000, | ||
4150 | .inputs = {{ | ||
4151 | .name = name_tv, | ||
4152 | .vmux = 3, | ||
4153 | .amux = TV, | ||
4154 | .tv = 1, | ||
4155 | }, { | ||
4156 | .name = name_comp1, | ||
4157 | .vmux = 1, | ||
4158 | .amux = LINE1, | ||
4159 | }, { | ||
4160 | .name = name_svideo, | ||
4161 | .vmux = 8, | ||
4162 | .amux = LINE1, | ||
4163 | } }, | ||
4164 | .radio = { | ||
4165 | .name = name_radio, | ||
4166 | .amux = LINE2, | ||
4167 | }, | ||
4168 | }, | ||
4169 | [SAA7134_BOARD_BEHOLD_507RDS_MK3] = { | ||
4170 | /* Beholder Intl. Ltd. 2008 */ | ||
4171 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
4172 | .name = "Beholder BeholdTV 507 RDS", | ||
4173 | .audio_clock = 0x00187de7, | ||
4174 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
4175 | .radio_type = UNSET, | ||
4176 | .tuner_addr = ADDR_UNSET, | ||
4177 | .radio_addr = ADDR_UNSET, | ||
4178 | .tda9887_conf = TDA9887_PRESENT, | ||
4179 | .gpiomask = 0x00008000, | ||
4180 | .inputs = {{ | ||
4181 | .name = name_tv, | ||
4182 | .vmux = 3, | ||
4183 | .amux = TV, | ||
4184 | .tv = 1, | ||
4185 | }, { | ||
4186 | .name = name_comp1, | ||
4187 | .vmux = 1, | ||
4188 | .amux = LINE1, | ||
4189 | }, { | ||
4190 | .name = name_svideo, | ||
4191 | .vmux = 8, | ||
4192 | .amux = LINE1, | ||
4193 | } }, | ||
4194 | .radio = { | ||
4195 | .name = name_radio, | ||
4196 | .amux = LINE2, | ||
4197 | }, | ||
4198 | }, | ||
4070 | [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { | 4199 | [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { |
4071 | /* Beholder Intl. Ltd. 2008 */ | 4200 | /* Beholder Intl. Ltd. 2008 */ |
4072 | /*Dmitry Belimov <d.belimov@gmail.com> */ | 4201 | /*Dmitry Belimov <d.belimov@gmail.com> */ |
@@ -4101,9 +4230,121 @@ struct saa7134_board saa7134_boards[] = { | |||
4101 | .gpio = 0x000A8000, | 4230 | .gpio = 0x000A8000, |
4102 | }, | 4231 | }, |
4103 | }, | 4232 | }, |
4104 | [SAA7134_BOARD_BEHOLD_607_9FM] = { | 4233 | [SAA7134_BOARD_BEHOLD_607FM_MK3] = { |
4234 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4235 | .name = "Beholder BeholdTV 607 FM", | ||
4236 | .audio_clock = 0x00187de7, | ||
4237 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
4238 | .radio_type = UNSET, | ||
4239 | .tuner_addr = ADDR_UNSET, | ||
4240 | .radio_addr = ADDR_UNSET, | ||
4241 | .tda9887_conf = TDA9887_PRESENT, | ||
4242 | .inputs = {{ | ||
4243 | .name = name_tv, | ||
4244 | .vmux = 3, | ||
4245 | .amux = TV, | ||
4246 | .tv = 1, | ||
4247 | }, { | ||
4248 | .name = name_comp1, | ||
4249 | .vmux = 1, | ||
4250 | .amux = LINE1, | ||
4251 | }, { | ||
4252 | .name = name_svideo, | ||
4253 | .vmux = 8, | ||
4254 | .amux = LINE1, | ||
4255 | } }, | ||
4256 | .radio = { | ||
4257 | .name = name_radio, | ||
4258 | .amux = LINE2, | ||
4259 | }, | ||
4260 | }, | ||
4261 | [SAA7134_BOARD_BEHOLD_609FM_MK3] = { | ||
4262 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4263 | .name = "Beholder BeholdTV 609 FM", | ||
4264 | .audio_clock = 0x00187de7, | ||
4265 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
4266 | .radio_type = UNSET, | ||
4267 | .tuner_addr = ADDR_UNSET, | ||
4268 | .radio_addr = ADDR_UNSET, | ||
4269 | .tda9887_conf = TDA9887_PRESENT, | ||
4270 | .inputs = {{ | ||
4271 | .name = name_tv, | ||
4272 | .vmux = 3, | ||
4273 | .amux = TV, | ||
4274 | .tv = 1, | ||
4275 | }, { | ||
4276 | .name = name_comp1, | ||
4277 | .vmux = 1, | ||
4278 | .amux = LINE1, | ||
4279 | }, { | ||
4280 | .name = name_svideo, | ||
4281 | .vmux = 8, | ||
4282 | .amux = LINE1, | ||
4283 | } }, | ||
4284 | .radio = { | ||
4285 | .name = name_radio, | ||
4286 | .amux = LINE2, | ||
4287 | }, | ||
4288 | }, | ||
4289 | [SAA7134_BOARD_BEHOLD_607FM_MK5] = { | ||
4290 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4291 | .name = "Beholder BeholdTV 607 FM", | ||
4292 | .audio_clock = 0x00187de7, | ||
4293 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4294 | .radio_type = UNSET, | ||
4295 | .tuner_addr = ADDR_UNSET, | ||
4296 | .radio_addr = ADDR_UNSET, | ||
4297 | .tda9887_conf = TDA9887_PRESENT, | ||
4298 | .inputs = {{ | ||
4299 | .name = name_tv, | ||
4300 | .vmux = 3, | ||
4301 | .amux = TV, | ||
4302 | .tv = 1, | ||
4303 | }, { | ||
4304 | .name = name_comp1, | ||
4305 | .vmux = 1, | ||
4306 | .amux = LINE1, | ||
4307 | }, { | ||
4308 | .name = name_svideo, | ||
4309 | .vmux = 8, | ||
4310 | .amux = LINE1, | ||
4311 | } }, | ||
4312 | .radio = { | ||
4313 | .name = name_radio, | ||
4314 | .amux = LINE2, | ||
4315 | }, | ||
4316 | }, | ||
4317 | [SAA7134_BOARD_BEHOLD_609FM_MK5] = { | ||
4105 | /* Andrey Melnikoff <temnota@kmv.ru> */ | 4318 | /* Andrey Melnikoff <temnota@kmv.ru> */ |
4106 | .name = "Beholder BeholdTV 607 / BeholdTV 609", | 4319 | .name = "Beholder BeholdTV 609 FM", |
4320 | .audio_clock = 0x00187de7, | ||
4321 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4322 | .radio_type = UNSET, | ||
4323 | .tuner_addr = ADDR_UNSET, | ||
4324 | .radio_addr = ADDR_UNSET, | ||
4325 | .tda9887_conf = TDA9887_PRESENT, | ||
4326 | .inputs = {{ | ||
4327 | .name = name_tv, | ||
4328 | .vmux = 3, | ||
4329 | .amux = TV, | ||
4330 | .tv = 1, | ||
4331 | }, { | ||
4332 | .name = name_comp1, | ||
4333 | .vmux = 1, | ||
4334 | .amux = LINE1, | ||
4335 | }, { | ||
4336 | .name = name_svideo, | ||
4337 | .vmux = 8, | ||
4338 | .amux = LINE1, | ||
4339 | } }, | ||
4340 | .radio = { | ||
4341 | .name = name_radio, | ||
4342 | .amux = LINE2, | ||
4343 | }, | ||
4344 | }, | ||
4345 | [SAA7134_BOARD_BEHOLD_607RDS_MK3] = { | ||
4346 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4347 | .name = "Beholder BeholdTV 607 RDS", | ||
4107 | .audio_clock = 0x00187de7, | 4348 | .audio_clock = 0x00187de7, |
4108 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 4349 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
4109 | .radio_type = UNSET, | 4350 | .radio_type = UNSET, |
@@ -4115,6 +4356,90 @@ struct saa7134_board saa7134_boards[] = { | |||
4115 | .vmux = 3, | 4356 | .vmux = 3, |
4116 | .amux = TV, | 4357 | .amux = TV, |
4117 | .tv = 1, | 4358 | .tv = 1, |
4359 | }, { | ||
4360 | .name = name_comp1, | ||
4361 | .vmux = 1, | ||
4362 | .amux = LINE1, | ||
4363 | }, { | ||
4364 | .name = name_svideo, | ||
4365 | .vmux = 8, | ||
4366 | .amux = LINE1, | ||
4367 | } }, | ||
4368 | .radio = { | ||
4369 | .name = name_radio, | ||
4370 | .amux = LINE2, | ||
4371 | }, | ||
4372 | }, | ||
4373 | [SAA7134_BOARD_BEHOLD_609RDS_MK3] = { | ||
4374 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4375 | .name = "Beholder BeholdTV 609 RDS", | ||
4376 | .audio_clock = 0x00187de7, | ||
4377 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
4378 | .radio_type = UNSET, | ||
4379 | .tuner_addr = ADDR_UNSET, | ||
4380 | .radio_addr = ADDR_UNSET, | ||
4381 | .tda9887_conf = TDA9887_PRESENT, | ||
4382 | .inputs = {{ | ||
4383 | .name = name_tv, | ||
4384 | .vmux = 3, | ||
4385 | .amux = TV, | ||
4386 | .tv = 1, | ||
4387 | }, { | ||
4388 | .name = name_comp1, | ||
4389 | .vmux = 1, | ||
4390 | .amux = LINE1, | ||
4391 | }, { | ||
4392 | .name = name_svideo, | ||
4393 | .vmux = 8, | ||
4394 | .amux = LINE1, | ||
4395 | } }, | ||
4396 | .radio = { | ||
4397 | .name = name_radio, | ||
4398 | .amux = LINE2, | ||
4399 | }, | ||
4400 | }, | ||
4401 | [SAA7134_BOARD_BEHOLD_607RDS_MK5] = { | ||
4402 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4403 | .name = "Beholder BeholdTV 607 RDS", | ||
4404 | .audio_clock = 0x00187de7, | ||
4405 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4406 | .radio_type = UNSET, | ||
4407 | .tuner_addr = ADDR_UNSET, | ||
4408 | .radio_addr = ADDR_UNSET, | ||
4409 | .tda9887_conf = TDA9887_PRESENT, | ||
4410 | .inputs = {{ | ||
4411 | .name = name_tv, | ||
4412 | .vmux = 3, | ||
4413 | .amux = TV, | ||
4414 | .tv = 1, | ||
4415 | }, { | ||
4416 | .name = name_comp1, | ||
4417 | .vmux = 1, | ||
4418 | .amux = LINE1, | ||
4419 | }, { | ||
4420 | .name = name_svideo, | ||
4421 | .vmux = 8, | ||
4422 | .amux = LINE1, | ||
4423 | } }, | ||
4424 | .radio = { | ||
4425 | .name = name_radio, | ||
4426 | .amux = LINE2, | ||
4427 | }, | ||
4428 | }, | ||
4429 | [SAA7134_BOARD_BEHOLD_609RDS_MK5] = { | ||
4430 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4431 | .name = "Beholder BeholdTV 609 RDS", | ||
4432 | .audio_clock = 0x00187de7, | ||
4433 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4434 | .radio_type = UNSET, | ||
4435 | .tuner_addr = ADDR_UNSET, | ||
4436 | .radio_addr = ADDR_UNSET, | ||
4437 | .tda9887_conf = TDA9887_PRESENT, | ||
4438 | .inputs = {{ | ||
4439 | .name = name_tv, | ||
4440 | .vmux = 3, | ||
4441 | .amux = TV, | ||
4442 | .tv = 1, | ||
4118 | },{ | 4443 | },{ |
4119 | .name = name_comp1, | 4444 | .name = name_comp1, |
4120 | .vmux = 1, | 4445 | .vmux = 1, |
@@ -4133,6 +4458,7 @@ struct saa7134_board saa7134_boards[] = { | |||
4133 | /* Igor Kuznetsov <igk@igk.ru> */ | 4458 | /* Igor Kuznetsov <igk@igk.ru> */ |
4134 | /* Andrey Melnikoff <temnota@kmv.ru> */ | 4459 | /* Andrey Melnikoff <temnota@kmv.ru> */ |
4135 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ | 4460 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ |
4461 | /* Alexey Osipov <lion-simba@pridelands.ru> */ | ||
4136 | .name = "Beholder BeholdTV M6", | 4462 | .name = "Beholder BeholdTV M6", |
4137 | .audio_clock = 0x00187de7, | 4463 | .audio_clock = 0x00187de7, |
4138 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 4464 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
@@ -4207,10 +4533,10 @@ struct saa7134_board saa7134_boards[] = { | |||
4207 | /* Igor Kuznetsov <igk@igk.ru> */ | 4533 | /* Igor Kuznetsov <igk@igk.ru> */ |
4208 | /* Andrey Melnikoff <temnota@kmv.ru> */ | 4534 | /* Andrey Melnikoff <temnota@kmv.ru> */ |
4209 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ | 4535 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ |
4536 | /* Alexey Osipov <lion-simba@pridelands.ru> */ | ||
4210 | .name = "Beholder BeholdTV M6 Extra", | 4537 | .name = "Beholder BeholdTV M6 Extra", |
4211 | .audio_clock = 0x00187de7, | 4538 | .audio_clock = 0x00187de7, |
4212 | /* FIXME: Must be PHILIPS_FM1216ME_MK5*/ | 4539 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ |
4213 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
4214 | .radio_type = UNSET, | 4540 | .radio_type = UNSET, |
4215 | .tuner_addr = ADDR_UNSET, | 4541 | .tuner_addr = ADDR_UNSET, |
4216 | .radio_addr = ADDR_UNSET, | 4542 | .radio_addr = ADDR_UNSET, |
@@ -4465,7 +4791,6 @@ struct saa7134_board saa7134_boards[] = { | |||
4465 | .radio_type = UNSET, | 4791 | .radio_type = UNSET, |
4466 | .tuner_addr = ADDR_UNSET, | 4792 | .tuner_addr = ADDR_UNSET, |
4467 | .radio_addr = ADDR_UNSET, | 4793 | .radio_addr = ADDR_UNSET, |
4468 | .mpeg = SAA7134_MPEG_DVB, | ||
4469 | .inputs = {{ | 4794 | .inputs = {{ |
4470 | .name = name_tv, | 4795 | .name = name_tv, |
4471 | .vmux = 3, | 4796 | .vmux = 3, |
@@ -4753,6 +5078,44 @@ struct saa7134_board saa7134_boards[] = { | |||
4753 | .gpio = 0x01, | 5078 | .gpio = 0x01, |
4754 | }, | 5079 | }, |
4755 | }, | 5080 | }, |
5081 | [SAA7134_BOARD_AVERMEDIA_STUDIO_507UA] = { | ||
5082 | /* Andy Shevchenko <andy@smile.org.ua> */ | ||
5083 | .name = "Avermedia AVerTV Studio 507UA", | ||
5084 | .audio_clock = 0x00187de7, | ||
5085 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* Should be MK5 */ | ||
5086 | .radio_type = UNSET, | ||
5087 | .tuner_addr = ADDR_UNSET, | ||
5088 | .radio_addr = ADDR_UNSET, | ||
5089 | .tda9887_conf = TDA9887_PRESENT, | ||
5090 | .gpiomask = 0x03, | ||
5091 | .inputs = { { | ||
5092 | .name = name_tv, | ||
5093 | .vmux = 1, | ||
5094 | .amux = TV, | ||
5095 | .tv = 1, | ||
5096 | .gpio = 0x00, | ||
5097 | }, { | ||
5098 | .name = name_comp1, | ||
5099 | .vmux = 3, | ||
5100 | .amux = LINE1, | ||
5101 | .gpio = 0x00, | ||
5102 | }, { | ||
5103 | .name = name_svideo, | ||
5104 | .vmux = 8, | ||
5105 | .amux = LINE1, | ||
5106 | .gpio = 0x00, | ||
5107 | } }, | ||
5108 | .radio = { | ||
5109 | .name = name_radio, | ||
5110 | .amux = LINE2, | ||
5111 | .gpio = 0x01, | ||
5112 | }, | ||
5113 | .mute = { | ||
5114 | .name = name_mute, | ||
5115 | .amux = LINE1, | ||
5116 | .gpio = 0x00, | ||
5117 | }, | ||
5118 | }, | ||
4756 | }; | 5119 | }; |
4757 | 5120 | ||
4758 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); | 5121 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); |
@@ -5027,6 +5390,13 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5027 | .subdevice = 0xd6ee, | 5390 | .subdevice = 0xd6ee, |
5028 | .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS, | 5391 | .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS, |
5029 | },{ | 5392 | },{ |
5393 | /* AVerMedia CardBus */ | ||
5394 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5395 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | ||
5396 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
5397 | .subdevice = 0xb7e9, | ||
5398 | .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS_501, | ||
5399 | }, { | ||
5030 | /* TransGear 3000TV */ | 5400 | /* TransGear 3000TV */ |
5031 | .vendor = PCI_VENDOR_ID_PHILIPS, | 5401 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5032 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | 5402 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, |
@@ -5441,6 +5811,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5441 | .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507, | 5811 | .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507, |
5442 | },{ | 5812 | },{ |
5443 | .vendor = PCI_VENDOR_ID_PHILIPS, | 5813 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5814 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | ||
5815 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
5816 | .subdevice = 0xa11b, | ||
5817 | .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507UA, | ||
5818 | }, { | ||
5819 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5444 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 5820 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5445 | .subvendor = 0x1043, | 5821 | .subvendor = 0x1043, |
5446 | .subdevice = 0x4876, | 5822 | .subdevice = 0x4876, |
@@ -5647,14 +6023,8 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5647 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6023 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5648 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | 6024 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, |
5649 | .subvendor = 0x0000, | 6025 | .subvendor = 0x0000, |
5650 | .subdevice = 0x5051, | ||
5651 | .driver_data = SAA7134_BOARD_BEHOLD_505FM, | ||
5652 | },{ | ||
5653 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5654 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | ||
5655 | .subvendor = 0x0000, | ||
5656 | .subdevice = 0x505B, | 6026 | .subdevice = 0x505B, |
5657 | .driver_data = SAA7134_BOARD_BEHOLD_505FM, | 6027 | .driver_data = SAA7134_BOARD_BEHOLD_505RDS, |
5658 | },{ | 6028 | },{ |
5659 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6029 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5660 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | 6030 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, |
@@ -5666,13 +6036,13 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5666 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6036 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5667 | .subvendor = 0x0000, | 6037 | .subvendor = 0x0000, |
5668 | .subdevice = 0x5071, | 6038 | .subdevice = 0x5071, |
5669 | .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, | 6039 | .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK3, |
5670 | },{ | 6040 | },{ |
5671 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6041 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5672 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6042 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5673 | .subvendor = 0x0000, | 6043 | .subvendor = 0x0000, |
5674 | .subdevice = 0x507B, | 6044 | .subdevice = 0x507B, |
5675 | .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, | 6045 | .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK5, |
5676 | },{ | 6046 | },{ |
5677 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6047 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5678 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6048 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
@@ -5696,49 +6066,49 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5696 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6066 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
5697 | .subvendor = 0x5ace, | 6067 | .subvendor = 0x5ace, |
5698 | .subdevice = 0x6070, | 6068 | .subdevice = 0x6070, |
5699 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6069 | .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK3, |
5700 | },{ | 6070 | },{ |
5701 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6071 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5702 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6072 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
5703 | .subvendor = 0x5ace, | 6073 | .subvendor = 0x5ace, |
5704 | .subdevice = 0x6071, | 6074 | .subdevice = 0x6071, |
5705 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6075 | .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK5, |
5706 | },{ | 6076 | },{ |
5707 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6077 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5708 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6078 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
5709 | .subvendor = 0x5ace, | 6079 | .subvendor = 0x5ace, |
5710 | .subdevice = 0x6072, | 6080 | .subdevice = 0x6072, |
5711 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6081 | .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK3, |
5712 | },{ | 6082 | },{ |
5713 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6083 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5714 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6084 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
5715 | .subvendor = 0x5ace, | 6085 | .subvendor = 0x5ace, |
5716 | .subdevice = 0x6073, | 6086 | .subdevice = 0x6073, |
5717 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6087 | .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK5, |
5718 | },{ | 6088 | },{ |
5719 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6089 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5720 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6090 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5721 | .subvendor = 0x5ace, | 6091 | .subvendor = 0x5ace, |
5722 | .subdevice = 0x6090, | 6092 | .subdevice = 0x6090, |
5723 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6093 | .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK3, |
5724 | },{ | 6094 | },{ |
5725 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6095 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5726 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6096 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5727 | .subvendor = 0x5ace, | 6097 | .subvendor = 0x5ace, |
5728 | .subdevice = 0x6091, | 6098 | .subdevice = 0x6091, |
5729 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6099 | .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK5, |
5730 | },{ | 6100 | },{ |
5731 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6101 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5732 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6102 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5733 | .subvendor = 0x5ace, | 6103 | .subvendor = 0x5ace, |
5734 | .subdevice = 0x6092, | 6104 | .subdevice = 0x6092, |
5735 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6105 | .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK3, |
5736 | },{ | 6106 | },{ |
5737 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6107 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5738 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6108 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5739 | .subvendor = 0x5ace, | 6109 | .subvendor = 0x5ace, |
5740 | .subdevice = 0x6093, | 6110 | .subdevice = 0x6093, |
5741 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6111 | .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK5, |
5742 | },{ | 6112 | },{ |
5743 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6113 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5744 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6114 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
@@ -5832,6 +6202,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5832 | }, { | 6202 | }, { |
5833 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6203 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5834 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6204 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
6205 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
6206 | .subdevice = 0xf736, | ||
6207 | .driver_data = SAA7134_BOARD_AVERMEDIA_M103, | ||
6208 | }, { | ||
6209 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
6210 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
5835 | .subvendor = 0x1043, | 6211 | .subvendor = 0x1043, |
5836 | .subdevice = 0x4878, /* REV:1.02G */ | 6212 | .subdevice = 0x4878, /* REV:1.02G */ |
5837 | .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1, | 6213 | .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1, |
@@ -6114,7 +6490,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
6114 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | 6490 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: |
6115 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: | 6491 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: |
6116 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: | 6492 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: |
6117 | case SAA7134_BOARD_VIDEOMATE_T750: | ||
6118 | case SAA7134_BOARD_MANLI_MTV001: | 6493 | case SAA7134_BOARD_MANLI_MTV001: |
6119 | case SAA7134_BOARD_MANLI_MTV002: | 6494 | case SAA7134_BOARD_MANLI_MTV002: |
6120 | case SAA7134_BOARD_BEHOLD_409FM: | 6495 | case SAA7134_BOARD_BEHOLD_409FM: |
@@ -6142,7 +6517,10 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
6142 | case SAA7134_BOARD_BEHOLD_407FM: | 6517 | case SAA7134_BOARD_BEHOLD_407FM: |
6143 | case SAA7134_BOARD_BEHOLD_409: | 6518 | case SAA7134_BOARD_BEHOLD_409: |
6144 | case SAA7134_BOARD_BEHOLD_505FM: | 6519 | case SAA7134_BOARD_BEHOLD_505FM: |
6520 | case SAA7134_BOARD_BEHOLD_505RDS: | ||
6145 | case SAA7134_BOARD_BEHOLD_507_9FM: | 6521 | case SAA7134_BOARD_BEHOLD_507_9FM: |
6522 | case SAA7134_BOARD_BEHOLD_507RDS_MK3: | ||
6523 | case SAA7134_BOARD_BEHOLD_507RDS_MK5: | ||
6146 | case SAA7134_BOARD_GENIUS_TVGO_A11MCE: | 6524 | case SAA7134_BOARD_GENIUS_TVGO_A11MCE: |
6147 | case SAA7134_BOARD_REAL_ANGEL_220: | 6525 | case SAA7134_BOARD_REAL_ANGEL_220: |
6148 | case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: | 6526 | case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: |
@@ -6196,6 +6574,16 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
6196 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); | 6574 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); |
6197 | msleep(10); | 6575 | msleep(10); |
6198 | break; | 6576 | break; |
6577 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: | ||
6578 | /* power-down tuner chip */ | ||
6579 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08400000, 0x08400000); | ||
6580 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0); | ||
6581 | msleep(10); | ||
6582 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08400000, 0x08400000); | ||
6583 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0x08400000); | ||
6584 | msleep(10); | ||
6585 | dev->has_remote = SAA7134_REMOTE_I2C; | ||
6586 | break; | ||
6199 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: | 6587 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: |
6200 | saa7134_set_gpio(dev, 23, 0); | 6588 | saa7134_set_gpio(dev, 23, 0); |
6201 | msleep(10); | 6589 | msleep(10); |
@@ -6253,7 +6641,14 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
6253 | case SAA7134_BOARD_UPMOST_PURPLE_TV: | 6641 | case SAA7134_BOARD_UPMOST_PURPLE_TV: |
6254 | case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: | 6642 | case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: |
6255 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: | 6643 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: |
6256 | case SAA7134_BOARD_BEHOLD_607_9FM: | 6644 | case SAA7134_BOARD_BEHOLD_607FM_MK3: |
6645 | case SAA7134_BOARD_BEHOLD_607FM_MK5: | ||
6646 | case SAA7134_BOARD_BEHOLD_609FM_MK3: | ||
6647 | case SAA7134_BOARD_BEHOLD_609FM_MK5: | ||
6648 | case SAA7134_BOARD_BEHOLD_607RDS_MK3: | ||
6649 | case SAA7134_BOARD_BEHOLD_607RDS_MK5: | ||
6650 | case SAA7134_BOARD_BEHOLD_609RDS_MK3: | ||
6651 | case SAA7134_BOARD_BEHOLD_609RDS_MK5: | ||
6257 | case SAA7134_BOARD_BEHOLD_M6: | 6652 | case SAA7134_BOARD_BEHOLD_M6: |
6258 | case SAA7134_BOARD_BEHOLD_M63: | 6653 | case SAA7134_BOARD_BEHOLD_M63: |
6259 | case SAA7134_BOARD_BEHOLD_M6_EXTRA: | 6654 | case SAA7134_BOARD_BEHOLD_M6_EXTRA: |
@@ -6635,6 +7030,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) | |||
6635 | 7030 | ||
6636 | switch (dev->board) { | 7031 | switch (dev->board) { |
6637 | case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: | 7032 | case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: |
7033 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: | ||
6638 | { | 7034 | { |
6639 | struct v4l2_priv_tun_config tea5767_cfg; | 7035 | struct v4l2_priv_tun_config tea5767_cfg; |
6640 | struct tea5767_ctrl ctl; | 7036 | struct tea5767_ctrl ctl; |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 2def6fec814b..94a023a14bbc 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -331,6 +331,10 @@ void saa7134_buffer_next(struct saa7134_dev *dev, | |||
331 | dprintk("buffer_next %p\n",NULL); | 331 | dprintk("buffer_next %p\n",NULL); |
332 | saa7134_set_dmabits(dev); | 332 | saa7134_set_dmabits(dev); |
333 | del_timer(&q->timeout); | 333 | del_timer(&q->timeout); |
334 | |||
335 | if (card_has_mpeg(dev)) | ||
336 | if (dev->ts_started) | ||
337 | saa7134_ts_stop(dev); | ||
334 | } | 338 | } |
335 | } | 339 | } |
336 | 340 | ||
@@ -416,6 +420,19 @@ int saa7134_set_dmabits(struct saa7134_dev *dev) | |||
416 | ctrl |= SAA7134_MAIN_CTRL_TE5; | 420 | ctrl |= SAA7134_MAIN_CTRL_TE5; |
417 | irq |= SAA7134_IRQ1_INTE_RA2_1 | | 421 | irq |= SAA7134_IRQ1_INTE_RA2_1 | |
418 | SAA7134_IRQ1_INTE_RA2_0; | 422 | SAA7134_IRQ1_INTE_RA2_0; |
423 | |||
424 | /* dma: setup channel 5 (= TS) */ | ||
425 | |||
426 | saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); | ||
427 | saa_writeb(SAA7134_TS_DMA1, | ||
428 | ((dev->ts.nr_packets - 1) >> 8) & 0xff); | ||
429 | /* TSNOPIT=0, TSCOLAP=0 */ | ||
430 | saa_writeb(SAA7134_TS_DMA2, | ||
431 | (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00); | ||
432 | saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); | ||
433 | saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | | ||
434 | SAA7134_RS_CONTROL_ME | | ||
435 | (dev->ts.pt_ts.dma >> 12)); | ||
419 | } | 436 | } |
420 | 437 | ||
421 | /* set task conditions + field handling */ | 438 | /* set task conditions + field handling */ |
@@ -775,7 +792,6 @@ static struct video_device *vdev_init(struct saa7134_dev *dev, | |||
775 | if (NULL == vfd) | 792 | if (NULL == vfd) |
776 | return NULL; | 793 | return NULL; |
777 | *vfd = *template; | 794 | *vfd = *template; |
778 | vfd->minor = -1; | ||
779 | vfd->v4l2_dev = &dev->v4l2_dev; | 795 | vfd->v4l2_dev = &dev->v4l2_dev; |
780 | vfd->release = video_device_release; | 796 | vfd->release = video_device_release; |
781 | vfd->debug = video_debug; | 797 | vfd->debug = video_debug; |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 4eff1ca8593c..31930f26ffc7 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include "isl6405.h" | 48 | #include "isl6405.h" |
49 | #include "lnbp21.h" | 49 | #include "lnbp21.h" |
50 | #include "tuner-simple.h" | 50 | #include "tuner-simple.h" |
51 | #include "tda10048.h" | ||
51 | #include "tda18271.h" | 52 | #include "tda18271.h" |
52 | #include "lgdt3305.h" | 53 | #include "lgdt3305.h" |
53 | #include "tda8290.h" | 54 | #include "tda8290.h" |
@@ -978,6 +979,18 @@ static struct lgdt3305_config hcw_lgdt3305_config = { | |||
978 | .vsb_if_khz = 3250, | 979 | .vsb_if_khz = 3250, |
979 | }; | 980 | }; |
980 | 981 | ||
982 | static struct tda10048_config hcw_tda10048_config = { | ||
983 | .demod_address = 0x10 >> 1, | ||
984 | .output_mode = TDA10048_SERIAL_OUTPUT, | ||
985 | .fwbulkwritelen = TDA10048_BULKWRITE_200, | ||
986 | .inversion = TDA10048_INVERSION_ON, | ||
987 | .dtv6_if_freq_khz = TDA10048_IF_3300, | ||
988 | .dtv7_if_freq_khz = TDA10048_IF_3500, | ||
989 | .dtv8_if_freq_khz = TDA10048_IF_4000, | ||
990 | .clk_freq_khz = TDA10048_CLK_16000, | ||
991 | .disable_gate_access = 1, | ||
992 | }; | ||
993 | |||
981 | static struct tda18271_std_map hauppauge_tda18271_std_map = { | 994 | static struct tda18271_std_map hauppauge_tda18271_std_map = { |
982 | .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, | 995 | .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, |
983 | .if_lvl = 1, .rfagc_top = 0x58, }, | 996 | .if_lvl = 1, .rfagc_top = 0x58, }, |
@@ -1106,6 +1119,19 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1106 | &tda827x_cfg_2) < 0) | 1119 | &tda827x_cfg_2) < 0) |
1107 | goto dettach_frontend; | 1120 | goto dettach_frontend; |
1108 | break; | 1121 | break; |
1122 | case SAA7134_BOARD_HAUPPAUGE_HVR1110R3: | ||
1123 | fe0->dvb.frontend = dvb_attach(tda10048_attach, | ||
1124 | &hcw_tda10048_config, | ||
1125 | &dev->i2c_adap); | ||
1126 | if (fe0->dvb.frontend != NULL) { | ||
1127 | dvb_attach(tda829x_attach, fe0->dvb.frontend, | ||
1128 | &dev->i2c_adap, 0x4b, | ||
1129 | &tda829x_no_probe); | ||
1130 | dvb_attach(tda18271_attach, fe0->dvb.frontend, | ||
1131 | 0x60, &dev->i2c_adap, | ||
1132 | &hcw_tda18271_config); | ||
1133 | } | ||
1134 | break; | ||
1109 | case SAA7134_BOARD_PHILIPS_TIGER: | 1135 | case SAA7134_BOARD_PHILIPS_TIGER: |
1110 | if (configure_tda827x_fe(dev, &philips_tiger_config, | 1136 | if (configure_tda827x_fe(dev, &philips_tiger_config, |
1111 | &tda827x_cfg_0) < 0) | 1137 | &tda827x_cfg_0) < 0) |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 9db3472667e5..add1757f8930 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -255,6 +255,16 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv, | |||
255 | return 0; | 255 | return 0; |
256 | } | 256 | } |
257 | 257 | ||
258 | static int empress_try_fmt_vid_cap(struct file *file, void *priv, | ||
259 | struct v4l2_format *f) | ||
260 | { | ||
261 | struct saa7134_dev *dev = file->private_data; | ||
262 | |||
263 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
264 | f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; | ||
265 | |||
266 | return 0; | ||
267 | } | ||
258 | 268 | ||
259 | static int empress_reqbufs(struct file *file, void *priv, | 269 | static int empress_reqbufs(struct file *file, void *priv, |
260 | struct v4l2_requestbuffers *p) | 270 | struct v4l2_requestbuffers *p) |
@@ -450,6 +460,7 @@ static const struct v4l2_file_operations ts_fops = | |||
450 | static const struct v4l2_ioctl_ops ts_ioctl_ops = { | 460 | static const struct v4l2_ioctl_ops ts_ioctl_ops = { |
451 | .vidioc_querycap = empress_querycap, | 461 | .vidioc_querycap = empress_querycap, |
452 | .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, | 462 | .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, |
463 | .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap, | ||
453 | .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, | 464 | .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, |
454 | .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, | 465 | .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, |
455 | .vidioc_reqbufs = empress_reqbufs, | 466 | .vidioc_reqbufs = empress_reqbufs, |
@@ -491,11 +502,8 @@ static void empress_signal_update(struct work_struct *work) | |||
491 | 502 | ||
492 | if (dev->nosignal) { | 503 | if (dev->nosignal) { |
493 | dprintk("no video signal\n"); | 504 | dprintk("no video signal\n"); |
494 | ts_reset_encoder(dev); | ||
495 | } else { | 505 | } else { |
496 | dprintk("video signal acquired\n"); | 506 | dprintk("video signal acquired\n"); |
497 | if (atomic_read(&dev->empress_users)) | ||
498 | ts_init_encoder(dev); | ||
499 | } | 507 | } |
500 | } | 508 | } |
501 | 509 | ||
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index f3e285aa2fb4..8096dace5f6c 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c | |||
@@ -259,7 +259,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
259 | /* workaround for a saa7134 i2c bug | 259 | /* workaround for a saa7134 i2c bug |
260 | * needed to talk to the mt352 demux | 260 | * needed to talk to the mt352 demux |
261 | * thanks to pinnacle for the hint */ | 261 | * thanks to pinnacle for the hint */ |
262 | int quirk = 0xfd; | 262 | int quirk = 0xfe; |
263 | d1printk(" [%02x quirk]",quirk); | 263 | d1printk(" [%02x quirk]",quirk); |
264 | i2c_send_byte(dev,START,quirk); | 264 | i2c_send_byte(dev,START,quirk); |
265 | i2c_recv_byte(dev); | 265 | i2c_recv_byte(dev); |
@@ -321,33 +321,6 @@ static u32 functionality(struct i2c_adapter *adap) | |||
321 | return I2C_FUNC_SMBUS_EMUL; | 321 | return I2C_FUNC_SMBUS_EMUL; |
322 | } | 322 | } |
323 | 323 | ||
324 | static int attach_inform(struct i2c_client *client) | ||
325 | { | ||
326 | struct saa7134_dev *dev = client->adapter->algo_data; | ||
327 | |||
328 | d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", | ||
329 | client->driver->driver.name, client->addr, client->name); | ||
330 | |||
331 | /* Am I an i2c remote control? */ | ||
332 | |||
333 | switch (client->addr) { | ||
334 | case 0x7a: | ||
335 | case 0x47: | ||
336 | case 0x71: | ||
337 | case 0x2d: | ||
338 | case 0x30: | ||
339 | { | ||
340 | struct IR_i2c *ir = i2c_get_clientdata(client); | ||
341 | d1printk("%s i2c IR detected (%s).\n", | ||
342 | client->driver->driver.name, ir->phys); | ||
343 | saa7134_set_i2c_ir(dev,ir); | ||
344 | break; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static struct i2c_algorithm saa7134_algo = { | 324 | static struct i2c_algorithm saa7134_algo = { |
352 | .master_xfer = saa7134_i2c_xfer, | 325 | .master_xfer = saa7134_i2c_xfer, |
353 | .functionality = functionality, | 326 | .functionality = functionality, |
@@ -358,7 +331,6 @@ static struct i2c_adapter saa7134_adap_template = { | |||
358 | .name = "saa7134", | 331 | .name = "saa7134", |
359 | .id = I2C_HW_SAA7134, | 332 | .id = I2C_HW_SAA7134, |
360 | .algo = &saa7134_algo, | 333 | .algo = &saa7134_algo, |
361 | .client_register = attach_inform, | ||
362 | }; | 334 | }; |
363 | 335 | ||
364 | static struct i2c_client saa7134_client_template = { | 336 | static struct i2c_client saa7134_client_template = { |
@@ -433,6 +405,9 @@ int saa7134_i2c_register(struct saa7134_dev *dev) | |||
433 | saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata)); | 405 | saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata)); |
434 | if (i2c_scan) | 406 | if (i2c_scan) |
435 | do_i2c_scan(dev->name,&dev->i2c_client); | 407 | do_i2c_scan(dev->name,&dev->i2c_client); |
408 | |||
409 | /* Instantiate the IR receiver device, if present */ | ||
410 | saa7134_probe_i2c_ir(dev); | ||
436 | return 0; | 411 | return 0; |
437 | } | 412 | } |
438 | 413 | ||
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 8a106d36e723..6e219c2db841 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of " | |||
60 | #define dprintk(fmt, arg...) if (ir_debug) \ | 60 | #define dprintk(fmt, arg...) if (ir_debug) \ |
61 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) | 61 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) |
62 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ | 62 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ |
63 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) | 63 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg) |
64 | 64 | ||
65 | /* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ | 65 | /* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ |
66 | static int saa7134_rc5_irq(struct saa7134_dev *dev); | 66 | static int saa7134_rc5_irq(struct saa7134_dev *dev); |
@@ -134,10 +134,10 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, | |||
134 | int gpio; | 134 | int gpio; |
135 | 135 | ||
136 | /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ | 136 | /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ |
137 | struct saa7134_dev *dev = ir->c.adapter->algo_data; | 137 | struct saa7134_dev *dev = ir->c->adapter->algo_data; |
138 | if (dev == NULL) { | 138 | if (dev == NULL) { |
139 | dprintk("get_key_msi_tvanywhere_plus: " | 139 | dprintk("get_key_msi_tvanywhere_plus: " |
140 | "gir->c.adapter->algo_data is NULL!\n"); | 140 | "gir->c->adapter->algo_data is NULL!\n"); |
141 | return -EIO; | 141 | return -EIO; |
142 | } | 142 | } |
143 | 143 | ||
@@ -156,7 +156,7 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, | |||
156 | 156 | ||
157 | /* GPIO says there is a button press. Get it. */ | 157 | /* GPIO says there is a button press. Get it. */ |
158 | 158 | ||
159 | if (1 != i2c_master_recv(&ir->c, &b, 1)) { | 159 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
160 | i2cdprintk("read error\n"); | 160 | i2cdprintk("read error\n"); |
161 | return -EIO; | 161 | return -EIO; |
162 | } | 162 | } |
@@ -179,7 +179,7 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
179 | unsigned char b; | 179 | unsigned char b; |
180 | 180 | ||
181 | /* poll IR chip */ | 181 | /* poll IR chip */ |
182 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 182 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
183 | i2cdprintk("read error\n"); | 183 | i2cdprintk("read error\n"); |
184 | return -EIO; | 184 | return -EIO; |
185 | } | 185 | } |
@@ -202,7 +202,7 @@ static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
202 | unsigned char buf[5], cod4, code3, code4; | 202 | unsigned char buf[5], cod4, code3, code4; |
203 | 203 | ||
204 | /* poll IR chip */ | 204 | /* poll IR chip */ |
205 | if (5 != i2c_master_recv(&ir->c,buf,5)) | 205 | if (5 != i2c_master_recv(ir->c, buf, 5)) |
206 | return -EIO; | 206 | return -EIO; |
207 | 207 | ||
208 | cod4 = buf[4]; | 208 | cod4 = buf[4]; |
@@ -224,7 +224,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
224 | unsigned char data[12]; | 224 | unsigned char data[12]; |
225 | u32 gpio; | 225 | u32 gpio; |
226 | 226 | ||
227 | struct saa7134_dev *dev = ir->c.adapter->algo_data; | 227 | struct saa7134_dev *dev = ir->c->adapter->algo_data; |
228 | 228 | ||
229 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ | 229 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ |
230 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | 230 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); |
@@ -235,9 +235,9 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
235 | if (0x400000 & ~gpio) | 235 | if (0x400000 & ~gpio) |
236 | return 0; /* No button press */ | 236 | return 0; /* No button press */ |
237 | 237 | ||
238 | ir->c.addr = 0x5a >> 1; | 238 | ir->c->addr = 0x5a >> 1; |
239 | 239 | ||
240 | if (12 != i2c_master_recv(&ir->c, data, 12)) { | 240 | if (12 != i2c_master_recv(ir->c, data, 12)) { |
241 | i2cdprintk("read error\n"); | 241 | i2cdprintk("read error\n"); |
242 | return -EIO; | 242 | return -EIO; |
243 | } | 243 | } |
@@ -267,7 +267,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, | |||
267 | unsigned int start = 0,parity = 0,code = 0; | 267 | unsigned int start = 0,parity = 0,code = 0; |
268 | 268 | ||
269 | /* poll IR chip */ | 269 | /* poll IR chip */ |
270 | if (4 != i2c_master_recv(&ir->c, b, 4)) { | 270 | if (4 != i2c_master_recv(ir->c, b, 4)) { |
271 | i2cdprintk("read error\n"); | 271 | i2cdprintk("read error\n"); |
272 | return -EIO; | 272 | return -EIO; |
273 | } | 273 | } |
@@ -447,6 +447,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
447 | case SAA7134_BOARD_AVERMEDIA_STUDIO_305: | 447 | case SAA7134_BOARD_AVERMEDIA_STUDIO_305: |
448 | case SAA7134_BOARD_AVERMEDIA_STUDIO_307: | 448 | case SAA7134_BOARD_AVERMEDIA_STUDIO_307: |
449 | case SAA7134_BOARD_AVERMEDIA_STUDIO_507: | 449 | case SAA7134_BOARD_AVERMEDIA_STUDIO_507: |
450 | case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA: | ||
450 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: | 451 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: |
451 | case SAA7134_BOARD_AVERMEDIA_M102: | 452 | case SAA7134_BOARD_AVERMEDIA_M102: |
452 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: | 453 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: |
@@ -506,7 +507,10 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
506 | case SAA7134_BOARD_BEHOLD_407FM: | 507 | case SAA7134_BOARD_BEHOLD_407FM: |
507 | case SAA7134_BOARD_BEHOLD_409: | 508 | case SAA7134_BOARD_BEHOLD_409: |
508 | case SAA7134_BOARD_BEHOLD_505FM: | 509 | case SAA7134_BOARD_BEHOLD_505FM: |
510 | case SAA7134_BOARD_BEHOLD_505RDS: | ||
509 | case SAA7134_BOARD_BEHOLD_507_9FM: | 511 | case SAA7134_BOARD_BEHOLD_507_9FM: |
512 | case SAA7134_BOARD_BEHOLD_507RDS_MK3: | ||
513 | case SAA7134_BOARD_BEHOLD_507RDS_MK5: | ||
510 | ir_codes = ir_codes_manli; | 514 | ir_codes = ir_codes_manli; |
511 | mask_keycode = 0x003f00; | 515 | mask_keycode = 0x003f00; |
512 | mask_keyup = 0x004000; | 516 | mask_keyup = 0x004000; |
@@ -678,55 +682,101 @@ void saa7134_input_fini(struct saa7134_dev *dev) | |||
678 | dev->remote = NULL; | 682 | dev->remote = NULL; |
679 | } | 683 | } |
680 | 684 | ||
681 | void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) | 685 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev) |
682 | { | 686 | { |
687 | struct i2c_board_info info; | ||
688 | struct IR_i2c_init_data init_data; | ||
689 | const unsigned short addr_list[] = { | ||
690 | 0x7a, 0x47, 0x71, 0x2d, | ||
691 | I2C_CLIENT_END | ||
692 | }; | ||
693 | |||
694 | struct i2c_msg msg_msi = { | ||
695 | .addr = 0x50, | ||
696 | .flags = I2C_M_RD, | ||
697 | .len = 0, | ||
698 | .buf = NULL, | ||
699 | }; | ||
700 | |||
701 | int rc; | ||
702 | |||
683 | if (disable_ir) { | 703 | if (disable_ir) { |
684 | dprintk("Found supported i2c remote, but IR has been disabled\n"); | 704 | dprintk("IR has been disabled, not probing for i2c remote\n"); |
685 | ir->get_key=NULL; | ||
686 | return; | 705 | return; |
687 | } | 706 | } |
688 | 707 | ||
708 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
709 | memset(&init_data, 0, sizeof(struct IR_i2c_init_data)); | ||
710 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
711 | |||
689 | switch (dev->board) { | 712 | switch (dev->board) { |
690 | case SAA7134_BOARD_PINNACLE_PCTV_110i: | 713 | case SAA7134_BOARD_PINNACLE_PCTV_110i: |
691 | case SAA7134_BOARD_PINNACLE_PCTV_310i: | 714 | case SAA7134_BOARD_PINNACLE_PCTV_310i: |
692 | snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); | 715 | init_data.name = "Pinnacle PCTV"; |
693 | if (pinnacle_remote == 0) { | 716 | if (pinnacle_remote == 0) { |
694 | ir->get_key = get_key_pinnacle_color; | 717 | init_data.get_key = get_key_pinnacle_color; |
695 | ir->ir_codes = ir_codes_pinnacle_color; | 718 | init_data.ir_codes = ir_codes_pinnacle_color; |
696 | } else { | 719 | } else { |
697 | ir->get_key = get_key_pinnacle_grey; | 720 | init_data.get_key = get_key_pinnacle_grey; |
698 | ir->ir_codes = ir_codes_pinnacle_grey; | 721 | init_data.ir_codes = ir_codes_pinnacle_grey; |
699 | } | 722 | } |
700 | break; | 723 | break; |
701 | case SAA7134_BOARD_UPMOST_PURPLE_TV: | 724 | case SAA7134_BOARD_UPMOST_PURPLE_TV: |
702 | snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV"); | 725 | init_data.name = "Purple TV"; |
703 | ir->get_key = get_key_purpletv; | 726 | init_data.get_key = get_key_purpletv; |
704 | ir->ir_codes = ir_codes_purpletv; | 727 | init_data.ir_codes = ir_codes_purpletv; |
705 | break; | 728 | break; |
706 | case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: | 729 | case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: |
707 | snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus"); | 730 | init_data.name = "MSI TV@nywhere Plus"; |
708 | ir->get_key = get_key_msi_tvanywhere_plus; | 731 | init_data.get_key = get_key_msi_tvanywhere_plus; |
709 | ir->ir_codes = ir_codes_msi_tvanywhere_plus; | 732 | init_data.ir_codes = ir_codes_msi_tvanywhere_plus; |
733 | info.addr = 0x30; | ||
734 | /* MSI TV@nywhere Plus controller doesn't seem to | ||
735 | respond to probes unless we read something from | ||
736 | an existing device. Weird... | ||
737 | REVISIT: might no longer be needed */ | ||
738 | rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1); | ||
739 | dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n", | ||
740 | msg_msi.addr, dev->i2c_adap.name, | ||
741 | (1 == rc) ? "yes" : "no"); | ||
710 | break; | 742 | break; |
711 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: | 743 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: |
712 | snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110"); | 744 | init_data.name = "HVR 1110"; |
713 | ir->get_key = get_key_hvr1110; | 745 | init_data.get_key = get_key_hvr1110; |
714 | ir->ir_codes = ir_codes_hauppauge_new; | 746 | init_data.ir_codes = ir_codes_hauppauge_new; |
715 | break; | 747 | break; |
716 | case SAA7134_BOARD_BEHOLD_607_9FM: | 748 | case SAA7134_BOARD_BEHOLD_607FM_MK3: |
749 | case SAA7134_BOARD_BEHOLD_607FM_MK5: | ||
750 | case SAA7134_BOARD_BEHOLD_609FM_MK3: | ||
751 | case SAA7134_BOARD_BEHOLD_609FM_MK5: | ||
752 | case SAA7134_BOARD_BEHOLD_607RDS_MK3: | ||
753 | case SAA7134_BOARD_BEHOLD_607RDS_MK5: | ||
754 | case SAA7134_BOARD_BEHOLD_609RDS_MK3: | ||
755 | case SAA7134_BOARD_BEHOLD_609RDS_MK5: | ||
717 | case SAA7134_BOARD_BEHOLD_M6: | 756 | case SAA7134_BOARD_BEHOLD_M6: |
718 | case SAA7134_BOARD_BEHOLD_M63: | 757 | case SAA7134_BOARD_BEHOLD_M63: |
719 | case SAA7134_BOARD_BEHOLD_M6_EXTRA: | 758 | case SAA7134_BOARD_BEHOLD_M6_EXTRA: |
720 | case SAA7134_BOARD_BEHOLD_H6: | 759 | case SAA7134_BOARD_BEHOLD_H6: |
721 | snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV"); | 760 | init_data.name = "BeholdTV"; |
722 | ir->get_key = get_key_beholdm6xx; | 761 | init_data.get_key = get_key_beholdm6xx; |
723 | ir->ir_codes = ir_codes_behold; | 762 | init_data.ir_codes = ir_codes_behold; |
724 | break; | 763 | break; |
725 | default: | 764 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: |
726 | dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board); | 765 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: |
766 | info.addr = 0x40; | ||
727 | break; | 767 | break; |
728 | } | 768 | } |
729 | 769 | ||
770 | if (init_data.name) | ||
771 | info.platform_data = &init_data; | ||
772 | /* No need to probe if address is known */ | ||
773 | if (info.addr) { | ||
774 | i2c_new_device(&dev->i2c_adap, &info); | ||
775 | return; | ||
776 | } | ||
777 | |||
778 | /* Address not known, fallback to probing */ | ||
779 | i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); | ||
730 | } | 780 | } |
731 | 781 | ||
732 | static int saa7134_rc5_irq(struct saa7134_dev *dev) | 782 | static int saa7134_rc5_irq(struct saa7134_dev *dev) |
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c index cc8b923afbc0..3fa652279ac0 100644 --- a/drivers/media/video/saa7134/saa7134-ts.c +++ b/drivers/media/video/saa7134/saa7134-ts.c | |||
@@ -65,35 +65,10 @@ static int buffer_activate(struct saa7134_dev *dev, | |||
65 | /* start DMA */ | 65 | /* start DMA */ |
66 | saa7134_set_dmabits(dev); | 66 | saa7134_set_dmabits(dev); |
67 | 67 | ||
68 | mod_timer(&dev->ts_q.timeout, jiffies+BUFFER_TIMEOUT); | 68 | mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT); |
69 | |||
70 | if (dev->ts_state == SAA7134_TS_BUFF_DONE) { | ||
71 | /* Clear TS cache */ | ||
72 | dev->buff_cnt = 0; | ||
73 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
74 | saa_writeb(SAA7134_TS_SERIAL1, 0x03); | ||
75 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
76 | saa_writeb(SAA7134_TS_SERIAL1, 0x01); | ||
77 | |||
78 | /* TS clock non-inverted */ | ||
79 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
80 | |||
81 | /* Start TS stream */ | ||
82 | switch (saa7134_boards[dev->board].ts_type) { | ||
83 | case SAA7134_MPEG_TS_PARALLEL: | ||
84 | saa_writeb(SAA7134_TS_SERIAL0, 0x40); | ||
85 | saa_writeb(SAA7134_TS_PARALLEL, 0xec); | ||
86 | break; | ||
87 | case SAA7134_MPEG_TS_SERIAL: | ||
88 | saa_writeb(SAA7134_TS_SERIAL0, 0xd8); | ||
89 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | ||
90 | saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); | ||
91 | saa_writeb(SAA7134_TS_SERIAL1, 0x02); | ||
92 | break; | ||
93 | } | ||
94 | 69 | ||
95 | dev->ts_state = SAA7134_TS_STARTED; | 70 | if (!dev->ts_started) |
96 | } | 71 | saa7134_ts_start(dev); |
97 | 72 | ||
98 | return 0; | 73 | return 0; |
99 | } | 74 | } |
@@ -104,7 +79,6 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
104 | struct saa7134_dev *dev = q->priv_data; | 79 | struct saa7134_dev *dev = q->priv_data; |
105 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 80 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); |
106 | unsigned int lines, llength, size; | 81 | unsigned int lines, llength, size; |
107 | u32 control; | ||
108 | int err; | 82 | int err; |
109 | 83 | ||
110 | dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); | 84 | dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); |
@@ -121,8 +95,11 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
121 | } | 95 | } |
122 | 96 | ||
123 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 97 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
98 | |||
124 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | 99 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); |
125 | 100 | ||
101 | dprintk("buffer_prepare: needs_init\n"); | ||
102 | |||
126 | buf->vb.width = llength; | 103 | buf->vb.width = llength; |
127 | buf->vb.height = lines; | 104 | buf->vb.height = lines; |
128 | buf->vb.size = size; | 105 | buf->vb.size = size; |
@@ -139,23 +116,6 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
139 | goto oops; | 116 | goto oops; |
140 | } | 117 | } |
141 | 118 | ||
142 | dev->buff_cnt++; | ||
143 | |||
144 | if (dev->buff_cnt == dev->ts.nr_bufs) { | ||
145 | dev->ts_state = SAA7134_TS_BUFF_DONE; | ||
146 | /* dma: setup channel 5 (= TS) */ | ||
147 | control = SAA7134_RS_CONTROL_BURST_16 | | ||
148 | SAA7134_RS_CONTROL_ME | | ||
149 | (buf->pt->dma >> 12); | ||
150 | |||
151 | saa_writeb(SAA7134_TS_DMA0, (lines - 1) & 0xff); | ||
152 | saa_writeb(SAA7134_TS_DMA1, ((lines - 1) >> 8) & 0xff); | ||
153 | /* TSNOPIT=0, TSCOLAP=0 */ | ||
154 | saa_writeb(SAA7134_TS_DMA2, (((lines - 1) >> 16) & 0x3f) | 0x00); | ||
155 | saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); | ||
156 | saa_writel(SAA7134_RS_CONTROL(5), control); | ||
157 | } | ||
158 | |||
159 | buf->vb.state = VIDEOBUF_PREPARED; | 119 | buf->vb.state = VIDEOBUF_PREPARED; |
160 | buf->activate = buffer_activate; | 120 | buf->activate = buffer_activate; |
161 | buf->vb.field = field; | 121 | buf->vb.field = field; |
@@ -175,8 +135,7 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) | |||
175 | if (0 == *count) | 135 | if (0 == *count) |
176 | *count = dev->ts.nr_bufs; | 136 | *count = dev->ts.nr_bufs; |
177 | *count = saa7134_buffer_count(*size,*count); | 137 | *count = saa7134_buffer_count(*size,*count); |
178 | dev->buff_cnt = 0; | 138 | |
179 | dev->ts_state = SAA7134_TS_STOPPED; | ||
180 | return 0; | 139 | return 0; |
181 | } | 140 | } |
182 | 141 | ||
@@ -193,11 +152,9 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | |||
193 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 152 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); |
194 | struct saa7134_dev *dev = q->priv_data; | 153 | struct saa7134_dev *dev = q->priv_data; |
195 | 154 | ||
196 | if (dev->ts_state == SAA7134_TS_STARTED) { | 155 | if (dev->ts_started) |
197 | /* Stop TS transport */ | 156 | saa7134_ts_stop(dev); |
198 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | 157 | |
199 | dev->ts_state = SAA7134_TS_STOPPED; | ||
200 | } | ||
201 | saa7134_dma_free(q,buf); | 158 | saa7134_dma_free(q,buf); |
202 | } | 159 | } |
203 | 160 | ||
@@ -214,7 +171,7 @@ EXPORT_SYMBOL_GPL(saa7134_ts_qops); | |||
214 | 171 | ||
215 | static unsigned int tsbufs = 8; | 172 | static unsigned int tsbufs = 8; |
216 | module_param(tsbufs, int, 0444); | 173 | module_param(tsbufs, int, 0444); |
217 | MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); | 174 | MODULE_PARM_DESC(tsbufs, "number of ts buffers for read/write IO, range 2-32"); |
218 | 175 | ||
219 | static unsigned int ts_nr_packets = 64; | 176 | static unsigned int ts_nr_packets = 64; |
220 | module_param(ts_nr_packets, int, 0444); | 177 | module_param(ts_nr_packets, int, 0444); |
@@ -256,6 +213,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev) | |||
256 | dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q); | 213 | dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q); |
257 | dev->ts_q.dev = dev; | 214 | dev->ts_q.dev = dev; |
258 | dev->ts_q.need_two = 1; | 215 | dev->ts_q.need_two = 1; |
216 | dev->ts_started = 0; | ||
259 | saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts); | 217 | saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts); |
260 | 218 | ||
261 | /* init TS hw */ | 219 | /* init TS hw */ |
@@ -264,13 +222,67 @@ int saa7134_ts_init1(struct saa7134_dev *dev) | |||
264 | return 0; | 222 | return 0; |
265 | } | 223 | } |
266 | 224 | ||
225 | /* Function for stop TS */ | ||
226 | int saa7134_ts_stop(struct saa7134_dev *dev) | ||
227 | { | ||
228 | dprintk("TS stop\n"); | ||
229 | |||
230 | BUG_ON(!dev->ts_started); | ||
231 | |||
232 | /* Stop TS stream */ | ||
233 | switch (saa7134_boards[dev->board].ts_type) { | ||
234 | case SAA7134_MPEG_TS_PARALLEL: | ||
235 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | ||
236 | dev->ts_started = 0; | ||
237 | break; | ||
238 | case SAA7134_MPEG_TS_SERIAL: | ||
239 | saa_writeb(SAA7134_TS_SERIAL0, 0x40); | ||
240 | dev->ts_started = 0; | ||
241 | break; | ||
242 | } | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | /* Function for start TS */ | ||
247 | int saa7134_ts_start(struct saa7134_dev *dev) | ||
248 | { | ||
249 | dprintk("TS start\n"); | ||
250 | |||
251 | BUG_ON(dev->ts_started); | ||
252 | |||
253 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
254 | saa_writeb(SAA7134_TS_SERIAL1, 0x03); | ||
255 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
256 | saa_writeb(SAA7134_TS_SERIAL1, 0x01); | ||
257 | |||
258 | /* TS clock non-inverted */ | ||
259 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
260 | |||
261 | /* Start TS stream */ | ||
262 | switch (saa7134_boards[dev->board].ts_type) { | ||
263 | case SAA7134_MPEG_TS_PARALLEL: | ||
264 | saa_writeb(SAA7134_TS_SERIAL0, 0x40); | ||
265 | saa_writeb(SAA7134_TS_PARALLEL, 0xec); | ||
266 | break; | ||
267 | case SAA7134_MPEG_TS_SERIAL: | ||
268 | saa_writeb(SAA7134_TS_SERIAL0, 0xd8); | ||
269 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | ||
270 | saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); | ||
271 | saa_writeb(SAA7134_TS_SERIAL1, 0x02); | ||
272 | break; | ||
273 | } | ||
274 | |||
275 | dev->ts_started = 1; | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
267 | int saa7134_ts_fini(struct saa7134_dev *dev) | 280 | int saa7134_ts_fini(struct saa7134_dev *dev) |
268 | { | 281 | { |
269 | saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts); | 282 | saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts); |
270 | return 0; | 283 | return 0; |
271 | } | 284 | } |
272 | 285 | ||
273 | |||
274 | void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) | 286 | void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) |
275 | { | 287 | { |
276 | enum v4l2_field field; | 288 | enum v4l2_field field; |
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 493cad941460..e305c1674cee 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -1057,6 +1057,7 @@ static int buffer_prepare(struct videobuf_queue *q, | |||
1057 | buf->vb.field = field; | 1057 | buf->vb.field = field; |
1058 | buf->fmt = fh->fmt; | 1058 | buf->fmt = fh->fmt; |
1059 | buf->pt = &fh->pt_cap; | 1059 | buf->pt = &fh->pt_cap; |
1060 | dev->video_q.curr = NULL; | ||
1060 | 1061 | ||
1061 | err = videobuf_iolock(q,&buf->vb,&dev->ovbuf); | 1062 | err = videobuf_iolock(q,&buf->vb,&dev->ovbuf); |
1062 | if (err) | 1063 | if (err) |
@@ -1423,11 +1424,13 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
1423 | { | 1424 | { |
1424 | struct saa7134_fh *fh = file->private_data; | 1425 | struct saa7134_fh *fh = file->private_data; |
1425 | struct videobuf_buffer *buf = NULL; | 1426 | struct videobuf_buffer *buf = NULL; |
1427 | unsigned int rc = 0; | ||
1426 | 1428 | ||
1427 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) | 1429 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) |
1428 | return videobuf_poll_stream(file, &fh->vbi, wait); | 1430 | return videobuf_poll_stream(file, &fh->vbi, wait); |
1429 | 1431 | ||
1430 | if (res_check(fh,RESOURCE_VIDEO)) { | 1432 | if (res_check(fh,RESOURCE_VIDEO)) { |
1433 | mutex_lock(&fh->cap.vb_lock); | ||
1431 | if (!list_empty(&fh->cap.stream)) | 1434 | if (!list_empty(&fh->cap.stream)) |
1432 | buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); | 1435 | buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); |
1433 | } else { | 1436 | } else { |
@@ -1446,13 +1449,14 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
1446 | } | 1449 | } |
1447 | 1450 | ||
1448 | if (!buf) | 1451 | if (!buf) |
1449 | return POLLERR; | 1452 | goto err; |
1450 | 1453 | ||
1451 | poll_wait(file, &buf->done, wait); | 1454 | poll_wait(file, &buf->done, wait); |
1452 | if (buf->state == VIDEOBUF_DONE || | 1455 | if (buf->state == VIDEOBUF_DONE || |
1453 | buf->state == VIDEOBUF_ERROR) | 1456 | buf->state == VIDEOBUF_ERROR) |
1454 | return POLLIN|POLLRDNORM; | 1457 | rc = POLLIN|POLLRDNORM; |
1455 | return 0; | 1458 | mutex_unlock(&fh->cap.vb_lock); |
1459 | return rc; | ||
1456 | 1460 | ||
1457 | err: | 1461 | err: |
1458 | mutex_unlock(&fh->cap.vb_lock); | 1462 | mutex_unlock(&fh->cap.vb_lock); |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 0cbaf90d4874..82268848f26a 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -252,7 +252,7 @@ struct saa7134_format { | |||
252 | #define SAA7134_BOARD_BEHOLD_505FM 126 | 252 | #define SAA7134_BOARD_BEHOLD_505FM 126 |
253 | #define SAA7134_BOARD_BEHOLD_507_9FM 127 | 253 | #define SAA7134_BOARD_BEHOLD_507_9FM 127 |
254 | #define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128 | 254 | #define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128 |
255 | #define SAA7134_BOARD_BEHOLD_607_9FM 129 | 255 | #define SAA7134_BOARD_BEHOLD_607FM_MK3 129 |
256 | #define SAA7134_BOARD_BEHOLD_M6 130 | 256 | #define SAA7134_BOARD_BEHOLD_M6 130 |
257 | #define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131 | 257 | #define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131 |
258 | #define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132 | 258 | #define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132 |
@@ -280,6 +280,18 @@ struct saa7134_format { | |||
280 | #define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154 | 280 | #define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154 |
281 | #define SAA7134_BOARD_HAUPPAUGE_HVR1120 155 | 281 | #define SAA7134_BOARD_HAUPPAUGE_HVR1120 155 |
282 | #define SAA7134_BOARD_HAUPPAUGE_HVR1110R3 156 | 282 | #define SAA7134_BOARD_HAUPPAUGE_HVR1110R3 156 |
283 | #define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157 | ||
284 | #define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158 | ||
285 | #define SAA7134_BOARD_BEHOLD_505RDS 159 | ||
286 | #define SAA7134_BOARD_BEHOLD_507RDS_MK3 160 | ||
287 | #define SAA7134_BOARD_BEHOLD_507RDS_MK5 161 | ||
288 | #define SAA7134_BOARD_BEHOLD_607FM_MK5 162 | ||
289 | #define SAA7134_BOARD_BEHOLD_609FM_MK3 163 | ||
290 | #define SAA7134_BOARD_BEHOLD_609FM_MK5 164 | ||
291 | #define SAA7134_BOARD_BEHOLD_607RDS_MK3 165 | ||
292 | #define SAA7134_BOARD_BEHOLD_607RDS_MK5 166 | ||
293 | #define SAA7134_BOARD_BEHOLD_609RDS_MK3 167 | ||
294 | #define SAA7134_BOARD_BEHOLD_609RDS_MK5 168 | ||
283 | 295 | ||
284 | #define SAA7134_MAXBOARDS 32 | 296 | #define SAA7134_MAXBOARDS 32 |
285 | #define SAA7134_INPUT_MAX 8 | 297 | #define SAA7134_INPUT_MAX 8 |
@@ -364,6 +376,7 @@ struct saa7134_board { | |||
364 | #define INTERLACE_OFF 2 | 376 | #define INTERLACE_OFF 2 |
365 | 377 | ||
366 | #define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ | 378 | #define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ |
379 | #define TS_BUFFER_TIMEOUT msecs_to_jiffies(1000) /* 1 second */ | ||
367 | 380 | ||
368 | struct saa7134_dev; | 381 | struct saa7134_dev; |
369 | struct saa7134_dma; | 382 | struct saa7134_dma; |
@@ -480,12 +493,6 @@ struct saa7134_mpeg_ops { | |||
480 | void (*signal_change)(struct saa7134_dev *dev); | 493 | void (*signal_change)(struct saa7134_dev *dev); |
481 | }; | 494 | }; |
482 | 495 | ||
483 | enum saa7134_ts_status { | ||
484 | SAA7134_TS_STOPPED, | ||
485 | SAA7134_TS_BUFF_DONE, | ||
486 | SAA7134_TS_STARTED, | ||
487 | }; | ||
488 | |||
489 | /* global device status */ | 496 | /* global device status */ |
490 | struct saa7134_dev { | 497 | struct saa7134_dev { |
491 | struct list_head devlist; | 498 | struct list_head devlist; |
@@ -580,8 +587,7 @@ struct saa7134_dev { | |||
580 | /* SAA7134_MPEG_* */ | 587 | /* SAA7134_MPEG_* */ |
581 | struct saa7134_ts ts; | 588 | struct saa7134_ts ts; |
582 | struct saa7134_dmaqueue ts_q; | 589 | struct saa7134_dmaqueue ts_q; |
583 | enum saa7134_ts_status ts_state; | 590 | int ts_started; |
584 | unsigned int buff_cnt; | ||
585 | struct saa7134_mpeg_ops *mops; | 591 | struct saa7134_mpeg_ops *mops; |
586 | 592 | ||
587 | /* SAA7134_MPEG_EMPRESS only */ | 593 | /* SAA7134_MPEG_EMPRESS only */ |
@@ -739,6 +745,9 @@ void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops); | |||
739 | 745 | ||
740 | int saa7134_ts_init_hw(struct saa7134_dev *dev); | 746 | int saa7134_ts_init_hw(struct saa7134_dev *dev); |
741 | 747 | ||
748 | int saa7134_ts_start(struct saa7134_dev *dev); | ||
749 | int saa7134_ts_stop(struct saa7134_dev *dev); | ||
750 | |||
742 | /* ----------------------------------------------------------- */ | 751 | /* ----------------------------------------------------------- */ |
743 | /* saa7134-vbi.c */ | 752 | /* saa7134-vbi.c */ |
744 | 753 | ||
@@ -786,7 +795,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status); | |||
786 | int saa7134_input_init1(struct saa7134_dev *dev); | 795 | int saa7134_input_init1(struct saa7134_dev *dev); |
787 | void saa7134_input_fini(struct saa7134_dev *dev); | 796 | void saa7134_input_fini(struct saa7134_dev *dev); |
788 | void saa7134_input_irq(struct saa7134_dev *dev); | 797 | void saa7134_input_irq(struct saa7134_dev *dev); |
789 | void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir); | 798 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev); |
790 | void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir); | 799 | void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir); |
791 | void saa7134_ir_stop(struct saa7134_dev *dev); | 800 | void saa7134_ir_stop(struct saa7134_dev *dev); |
792 | 801 | ||
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index 5990ab38a124..c8f05297d0f0 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c | |||
@@ -38,7 +38,7 @@ static const char version[] = "0.24"; | |||
38 | static int flickerless; | 38 | static int flickerless; |
39 | static int video_nr = -1; | 39 | static int video_nr = -1; |
40 | 40 | ||
41 | static struct usb_device_id device_table [] = { | 41 | static struct usb_device_id device_table[] = { |
42 | { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */ | 42 | { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */ |
43 | { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */ | 43 | { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */ |
44 | { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */ | 44 | { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */ |
@@ -53,7 +53,8 @@ MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>"); | |||
53 | MODULE_DESCRIPTION("SE401 USB Camera Driver"); | 53 | MODULE_DESCRIPTION("SE401 USB Camera Driver"); |
54 | MODULE_LICENSE("GPL"); | 54 | MODULE_LICENSE("GPL"); |
55 | module_param(flickerless, int, 0); | 55 | module_param(flickerless, int, 0); |
56 | MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)"); | 56 | MODULE_PARM_DESC(flickerless, |
57 | "Net frequency to adjust exposure time to (0/50/60)"); | ||
57 | module_param(video_nr, int, 0); | 58 | module_param(video_nr, int, 0); |
58 | 59 | ||
59 | static struct usb_driver se401_driver; | 60 | static struct usb_driver se401_driver; |
@@ -78,8 +79,8 @@ static void *rvmalloc(unsigned long size) | |||
78 | adr = (unsigned long) mem; | 79 | adr = (unsigned long) mem; |
79 | while (size > 0) { | 80 | while (size > 0) { |
80 | SetPageReserved(vmalloc_to_page((void *)adr)); | 81 | SetPageReserved(vmalloc_to_page((void *)adr)); |
81 | adr += PAGE_SIZE; | 82 | adr += PAGE_SIZE; |
82 | size -= PAGE_SIZE; | 83 | size -= PAGE_SIZE; |
83 | } | 84 | } |
84 | 85 | ||
85 | return mem; | 86 | return mem; |
@@ -95,8 +96,8 @@ static void rvfree(void *mem, unsigned long size) | |||
95 | adr = (unsigned long) mem; | 96 | adr = (unsigned long) mem; |
96 | while ((long) size > 0) { | 97 | while ((long) size > 0) { |
97 | ClearPageReserved(vmalloc_to_page((void *)adr)); | 98 | ClearPageReserved(vmalloc_to_page((void *)adr)); |
98 | adr += PAGE_SIZE; | 99 | adr += PAGE_SIZE; |
99 | size -= PAGE_SIZE; | 100 | size -= PAGE_SIZE; |
100 | } | 101 | } |
101 | vfree(mem); | 102 | vfree(mem); |
102 | } | 103 | } |
@@ -112,7 +113,7 @@ static void rvfree(void *mem, unsigned long size) | |||
112 | static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req, | 113 | static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req, |
113 | unsigned short value, unsigned char *cp, int size) | 114 | unsigned short value, unsigned char *cp, int size) |
114 | { | 115 | { |
115 | return usb_control_msg ( | 116 | return usb_control_msg( |
116 | se401->dev, | 117 | se401->dev, |
117 | set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0), | 118 | set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0), |
118 | req, | 119 | req, |
@@ -132,7 +133,7 @@ static int se401_set_feature(struct usb_se401 *se401, unsigned short selector, | |||
132 | and the param in index, but in the logs of the windows driver they do | 133 | and the param in index, but in the logs of the windows driver they do |
133 | this the other way around... | 134 | this the other way around... |
134 | */ | 135 | */ |
135 | return usb_control_msg ( | 136 | return usb_control_msg( |
136 | se401->dev, | 137 | se401->dev, |
137 | usb_sndctrlpipe(se401->dev, 0), | 138 | usb_sndctrlpipe(se401->dev, 0), |
138 | SE401_REQ_SET_EXT_FEATURE, | 139 | SE401_REQ_SET_EXT_FEATURE, |
@@ -152,7 +153,7 @@ static unsigned short se401_get_feature(struct usb_se401 *se401, | |||
152 | wrong here to.... | 153 | wrong here to.... |
153 | */ | 154 | */ |
154 | unsigned char cp[2]; | 155 | unsigned char cp[2]; |
155 | usb_control_msg ( | 156 | usb_control_msg( |
156 | se401->dev, | 157 | se401->dev, |
157 | usb_rcvctrlpipe(se401->dev, 0), | 158 | usb_rcvctrlpipe(se401->dev, 0), |
158 | SE401_REQ_GET_EXT_FEATURE, | 159 | SE401_REQ_GET_EXT_FEATURE, |
@@ -175,46 +176,51 @@ static unsigned short se401_get_feature(struct usb_se401 *se401, | |||
175 | 176 | ||
176 | static int se401_send_pict(struct usb_se401 *se401) | 177 | static int se401_send_pict(struct usb_se401 *se401) |
177 | { | 178 | { |
178 | se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */ | 179 | /* integration time low */ |
179 | se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */ | 180 | se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l); |
180 | se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */ | 181 | /* integration time mid */ |
181 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */ | 182 | se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m); |
182 | se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */ | 183 | /* integration time mid */ |
183 | se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */ | 184 | se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h); |
184 | se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */ | 185 | /* reset level value */ |
186 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel); | ||
187 | /* red color gain */ | ||
188 | se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain); | ||
189 | /* green color gain */ | ||
190 | se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain); | ||
191 | /* blue color gain */ | ||
192 | se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain); | ||
185 | 193 | ||
186 | return 0; | 194 | return 0; |
187 | } | 195 | } |
188 | 196 | ||
189 | static void se401_set_exposure(struct usb_se401 *se401, int brightness) | 197 | static void se401_set_exposure(struct usb_se401 *se401, int brightness) |
190 | { | 198 | { |
191 | int integration=brightness<<5; | 199 | int integration = brightness << 5; |
192 | 200 | ||
193 | if (flickerless==50) { | 201 | if (flickerless == 50) |
194 | integration=integration-integration%106667; | 202 | integration = integration-integration % 106667; |
195 | } | 203 | if (flickerless == 60) |
196 | if (flickerless==60) { | 204 | integration = integration-integration % 88889; |
197 | integration=integration-integration%88889; | 205 | se401->brightness = integration >> 5; |
198 | } | 206 | se401->expose_h = (integration >> 16) & 0xff; |
199 | se401->brightness=integration>>5; | 207 | se401->expose_m = (integration >> 8) & 0xff; |
200 | se401->expose_h=(integration>>16)&0xff; | 208 | se401->expose_l = integration & 0xff; |
201 | se401->expose_m=(integration>>8)&0xff; | ||
202 | se401->expose_l=integration&0xff; | ||
203 | } | 209 | } |
204 | 210 | ||
205 | static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p) | 211 | static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p) |
206 | { | 212 | { |
207 | p->brightness=se401->brightness; | 213 | p->brightness = se401->brightness; |
208 | if (se401->enhance) { | 214 | if (se401->enhance) |
209 | p->whiteness=32768; | 215 | p->whiteness = 32768; |
210 | } else { | 216 | else |
211 | p->whiteness=0; | 217 | p->whiteness = 0; |
212 | } | 218 | |
213 | p->colour=65535; | 219 | p->colour = 65535; |
214 | p->contrast=65535; | 220 | p->contrast = 65535; |
215 | p->hue=se401->rgain<<10; | 221 | p->hue = se401->rgain << 10; |
216 | p->palette=se401->palette; | 222 | p->palette = se401->palette; |
217 | p->depth=3; /* rgb24 */ | 223 | p->depth = 3; /* rgb24 */ |
218 | return 0; | 224 | return 0; |
219 | } | 225 | } |
220 | 226 | ||
@@ -223,20 +229,19 @@ static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p) | |||
223 | { | 229 | { |
224 | if (p->palette != VIDEO_PALETTE_RGB24) | 230 | if (p->palette != VIDEO_PALETTE_RGB24) |
225 | return 1; | 231 | return 1; |
226 | se401->palette=p->palette; | 232 | se401->palette = p->palette; |
227 | if (p->hue!=se401->hue) { | 233 | if (p->hue != se401->hue) { |
228 | se401->rgain= p->hue>>10; | 234 | se401->rgain = p->hue >> 10; |
229 | se401->bgain= 0x40-(p->hue>>10); | 235 | se401->bgain = 0x40-(p->hue >> 10); |
230 | se401->hue=p->hue; | 236 | se401->hue = p->hue; |
231 | } | 237 | } |
232 | if (p->brightness!=se401->brightness) { | 238 | if (p->brightness != se401->brightness) |
233 | se401_set_exposure(se401, p->brightness); | 239 | se401_set_exposure(se401, p->brightness); |
234 | } | 240 | |
235 | if (p->whiteness>=32768) { | 241 | if (p->whiteness >= 32768) |
236 | se401->enhance=1; | 242 | se401->enhance = 1; |
237 | } else { | 243 | else |
238 | se401->enhance=0; | 244 | se401->enhance = 0; |
239 | } | ||
240 | se401_send_pict(se401); | 245 | se401_send_pict(se401); |
241 | se401_send_pict(se401); | 246 | se401_send_pict(se401); |
242 | return 0; | 247 | return 0; |
@@ -249,7 +254,7 @@ static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p) | |||
249 | static void se401_auto_resetlevel(struct usb_se401 *se401) | 254 | static void se401_auto_resetlevel(struct usb_se401 *se401) |
250 | { | 255 | { |
251 | unsigned int ahrc, alrc; | 256 | unsigned int ahrc, alrc; |
252 | int oldreset=se401->resetlevel; | 257 | int oldreset = se401->resetlevel; |
253 | 258 | ||
254 | /* For some reason this normally read-only register doesn't get reset | 259 | /* For some reason this normally read-only register doesn't get reset |
255 | to zero after reading them just once... | 260 | to zero after reading them just once... |
@@ -258,24 +263,24 @@ static void se401_auto_resetlevel(struct usb_se401 *se401) | |||
258 | se401_get_feature(se401, HV7131_REG_HIREFNOL); | 263 | se401_get_feature(se401, HV7131_REG_HIREFNOL); |
259 | se401_get_feature(se401, HV7131_REG_LOREFNOH); | 264 | se401_get_feature(se401, HV7131_REG_LOREFNOH); |
260 | se401_get_feature(se401, HV7131_REG_LOREFNOL); | 265 | se401_get_feature(se401, HV7131_REG_LOREFNOL); |
261 | ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) + | 266 | ahrc = 256*se401_get_feature(se401, HV7131_REG_HIREFNOH) + |
262 | se401_get_feature(se401, HV7131_REG_HIREFNOL); | 267 | se401_get_feature(se401, HV7131_REG_HIREFNOL); |
263 | alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) + | 268 | alrc = 256*se401_get_feature(se401, HV7131_REG_LOREFNOH) + |
264 | se401_get_feature(se401, HV7131_REG_LOREFNOL); | 269 | se401_get_feature(se401, HV7131_REG_LOREFNOL); |
265 | 270 | ||
266 | /* Not an exact science, but it seems to work pretty well... */ | 271 | /* Not an exact science, but it seems to work pretty well... */ |
267 | if (alrc > 10) { | 272 | if (alrc > 10) { |
268 | while (alrc>=10 && se401->resetlevel < 63) { | 273 | while (alrc >= 10 && se401->resetlevel < 63) { |
269 | se401->resetlevel++; | 274 | se401->resetlevel++; |
270 | alrc /=2; | 275 | alrc /= 2; |
271 | } | 276 | } |
272 | } else if (ahrc > 20) { | 277 | } else if (ahrc > 20) { |
273 | while (ahrc>=20 && se401->resetlevel > 0) { | 278 | while (ahrc >= 20 && se401->resetlevel > 0) { |
274 | se401->resetlevel--; | 279 | se401->resetlevel--; |
275 | ahrc /=2; | 280 | ahrc /= 2; |
276 | } | 281 | } |
277 | } | 282 | } |
278 | if (se401->resetlevel!=oldreset) | 283 | if (se401->resetlevel != oldreset) |
279 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel); | 284 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel); |
280 | 285 | ||
281 | return; | 286 | return; |
@@ -300,21 +305,22 @@ static void se401_button_irq(struct urb *urb) | |||
300 | case -ENOENT: | 305 | case -ENOENT: |
301 | case -ESHUTDOWN: | 306 | case -ESHUTDOWN: |
302 | /* this urb is terminated, clean up */ | 307 | /* this urb is terminated, clean up */ |
303 | dbg("%s - urb shutting down with status: %d", __func__, urb->status); | 308 | dbg("%s - urb shutting down with status: %d", |
309 | __func__, urb->status); | ||
304 | return; | 310 | return; |
305 | default: | 311 | default: |
306 | dbg("%s - nonzero urb status received: %d", __func__, urb->status); | 312 | dbg("%s - nonzero urb status received: %d", |
313 | __func__, urb->status); | ||
307 | goto exit; | 314 | goto exit; |
308 | } | 315 | } |
309 | 316 | ||
310 | if (urb->actual_length >=2) { | 317 | if (urb->actual_length >= 2) |
311 | if (se401->button) | 318 | if (se401->button) |
312 | se401->buttonpressed=1; | 319 | se401->buttonpressed = 1; |
313 | } | ||
314 | exit: | 320 | exit: |
315 | status = usb_submit_urb (urb, GFP_ATOMIC); | 321 | status = usb_submit_urb(urb, GFP_ATOMIC); |
316 | if (status) | 322 | if (status) |
317 | err ("%s - usb_submit_urb failed with result %d", | 323 | err("%s - usb_submit_urb failed with result %d", |
318 | __func__, status); | 324 | __func__, status); |
319 | } | 325 | } |
320 | 326 | ||
@@ -336,55 +342,52 @@ static void se401_video_irq(struct urb *urb) | |||
336 | keeps sending them forever... | 342 | keeps sending them forever... |
337 | */ | 343 | */ |
338 | if (length && !urb->status) { | 344 | if (length && !urb->status) { |
339 | se401->nullpackets=0; | 345 | se401->nullpackets = 0; |
340 | switch(se401->scratch[se401->scratch_next].state) { | 346 | switch (se401->scratch[se401->scratch_next].state) { |
341 | case BUFFER_READY: | 347 | case BUFFER_READY: |
342 | case BUFFER_BUSY: { | 348 | case BUFFER_BUSY: |
343 | se401->dropped++; | 349 | se401->dropped++; |
344 | break; | 350 | break; |
345 | } | 351 | case BUFFER_UNUSED: |
346 | case BUFFER_UNUSED: { | 352 | memcpy(se401->scratch[se401->scratch_next].data, |
347 | memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length); | 353 | (unsigned char *)urb->transfer_buffer, length); |
348 | se401->scratch[se401->scratch_next].state=BUFFER_READY; | 354 | se401->scratch[se401->scratch_next].state |
349 | se401->scratch[se401->scratch_next].offset=se401->bayeroffset; | 355 | = BUFFER_READY; |
350 | se401->scratch[se401->scratch_next].length=length; | 356 | se401->scratch[se401->scratch_next].offset |
351 | if (waitqueue_active(&se401->wq)) { | 357 | = se401->bayeroffset; |
352 | wake_up_interruptible(&se401->wq); | 358 | se401->scratch[se401->scratch_next].length = length; |
353 | } | 359 | if (waitqueue_active(&se401->wq)) |
354 | se401->scratch_overflow=0; | 360 | wake_up_interruptible(&se401->wq); |
355 | se401->scratch_next++; | 361 | se401->scratch_overflow = 0; |
356 | if (se401->scratch_next>=SE401_NUMSCRATCH) | 362 | se401->scratch_next++; |
357 | se401->scratch_next=0; | 363 | if (se401->scratch_next >= SE401_NUMSCRATCH) |
358 | break; | 364 | se401->scratch_next = 0; |
359 | } | 365 | break; |
360 | } | ||
361 | se401->bayeroffset+=length; | ||
362 | if (se401->bayeroffset>=se401->cheight*se401->cwidth) { | ||
363 | se401->bayeroffset=0; | ||
364 | } | 366 | } |
367 | se401->bayeroffset += length; | ||
368 | if (se401->bayeroffset >= se401->cheight * se401->cwidth) | ||
369 | se401->bayeroffset = 0; | ||
365 | } else { | 370 | } else { |
366 | se401->nullpackets++; | 371 | se401->nullpackets++; |
367 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) { | 372 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) |
368 | if (waitqueue_active(&se401->wq)) { | 373 | if (waitqueue_active(&se401->wq)) |
369 | wake_up_interruptible(&se401->wq); | 374 | wake_up_interruptible(&se401->wq); |
370 | } | ||
371 | } | ||
372 | } | 375 | } |
373 | 376 | ||
374 | /* Resubmit urb for new data */ | 377 | /* Resubmit urb for new data */ |
375 | urb->status=0; | 378 | urb->status = 0; |
376 | urb->dev=se401->dev; | 379 | urb->dev = se401->dev; |
377 | if(usb_submit_urb(urb, GFP_KERNEL)) | 380 | if (usb_submit_urb(urb, GFP_KERNEL)) |
378 | dev_info(&urb->dev->dev, "urb burned down\n"); | 381 | dev_info(&urb->dev->dev, "urb burned down\n"); |
379 | return; | 382 | return; |
380 | } | 383 | } |
381 | 384 | ||
382 | static void se401_send_size(struct usb_se401 *se401, int width, int height) | 385 | static void se401_send_size(struct usb_se401 *se401, int width, int height) |
383 | { | 386 | { |
384 | int i=0; | 387 | int i = 0; |
385 | int mode=0x03; /* No compression */ | 388 | int mode = 0x03; /* No compression */ |
386 | int sendheight=height; | 389 | int sendheight = height; |
387 | int sendwidth=width; | 390 | int sendwidth = width; |
388 | 391 | ||
389 | /* JangGu compression can only be used with the camera supported sizes, | 392 | /* JangGu compression can only be used with the camera supported sizes, |
390 | but bayer seems to work with any size that fits on the sensor. | 393 | but bayer seems to work with any size that fits on the sensor. |
@@ -392,18 +395,21 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height) | |||
392 | 4 or 16 times subcapturing, if not we use uncompressed bayer data | 395 | 4 or 16 times subcapturing, if not we use uncompressed bayer data |
393 | but this will result in cutouts of the maximum size.... | 396 | but this will result in cutouts of the maximum size.... |
394 | */ | 397 | */ |
395 | while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height)) | 398 | while (i < se401->sizes && !(se401->width[i] == width && |
399 | se401->height[i] == height)) | ||
396 | i++; | 400 | i++; |
397 | while (i<se401->sizes) { | 401 | while (i < se401->sizes) { |
398 | if (se401->width[i]==width*2 && se401->height[i]==height*2) { | 402 | if (se401->width[i] == width * 2 && |
399 | sendheight=se401->height[i]; | 403 | se401->height[i] == height * 2) { |
400 | sendwidth=se401->width[i]; | 404 | sendheight = se401->height[i]; |
401 | mode=0x40; | 405 | sendwidth = se401->width[i]; |
406 | mode = 0x40; | ||
402 | } | 407 | } |
403 | if (se401->width[i]==width*4 && se401->height[i]==height*4) { | 408 | if (se401->width[i] == width * 4 && |
404 | sendheight=se401->height[i]; | 409 | se401->height[i] == height * 4) { |
405 | sendwidth=se401->width[i]; | 410 | sendheight = se401->height[i]; |
406 | mode=0x42; | 411 | sendwidth = se401->width[i]; |
412 | mode = 0x42; | ||
407 | } | 413 | } |
408 | i++; | 414 | i++; |
409 | } | 415 | } |
@@ -412,13 +418,10 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height) | |||
412 | se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0); | 418 | se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0); |
413 | se401_set_feature(se401, SE401_OPERATINGMODE, mode); | 419 | se401_set_feature(se401, SE401_OPERATINGMODE, mode); |
414 | 420 | ||
415 | if (mode==0x03) { | 421 | if (mode == 0x03) |
416 | se401->format=FMT_BAYER; | 422 | se401->format = FMT_BAYER; |
417 | } else { | 423 | else |
418 | se401->format=FMT_JANGGU; | 424 | se401->format = FMT_JANGGU; |
419 | } | ||
420 | |||
421 | return; | ||
422 | } | 425 | } |
423 | 426 | ||
424 | /* | 427 | /* |
@@ -429,29 +432,31 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height) | |||
429 | static int se401_start_stream(struct usb_se401 *se401) | 432 | static int se401_start_stream(struct usb_se401 *se401) |
430 | { | 433 | { |
431 | struct urb *urb; | 434 | struct urb *urb; |
432 | int err=0, i; | 435 | int err = 0, i; |
433 | se401->streaming=1; | 436 | se401->streaming = 1; |
434 | 437 | ||
435 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); | 438 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); |
436 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); | 439 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); |
437 | 440 | ||
438 | /* Set picture settings */ | 441 | /* Set picture settings */ |
439 | se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */ | 442 | /* windowed + pix intg */ |
443 | se401_set_feature(se401, HV7131_REG_MODE_B, 0x05); | ||
440 | se401_send_pict(se401); | 444 | se401_send_pict(se401); |
441 | 445 | ||
442 | se401_send_size(se401, se401->cwidth, se401->cheight); | 446 | se401_send_size(se401, se401->cwidth, se401->cheight); |
443 | 447 | ||
444 | se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0); | 448 | se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, |
449 | 0, NULL, 0); | ||
445 | 450 | ||
446 | /* Do some memory allocation */ | 451 | /* Do some memory allocation */ |
447 | for (i=0; i<SE401_NUMFRAMES; i++) { | 452 | for (i = 0; i < SE401_NUMFRAMES; i++) { |
448 | se401->frame[i].data=se401->fbuf + i * se401->maxframesize; | 453 | se401->frame[i].data = se401->fbuf + i * se401->maxframesize; |
449 | se401->frame[i].curpix=0; | 454 | se401->frame[i].curpix = 0; |
450 | } | 455 | } |
451 | for (i=0; i<SE401_NUMSBUF; i++) { | 456 | for (i = 0; i < SE401_NUMSBUF; i++) { |
452 | se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL); | 457 | se401->sbuf[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL); |
453 | if (!se401->sbuf[i].data) { | 458 | if (!se401->sbuf[i].data) { |
454 | for(i = i - 1; i >= 0; i--) { | 459 | for (i = i - 1; i >= 0; i--) { |
455 | kfree(se401->sbuf[i].data); | 460 | kfree(se401->sbuf[i].data); |
456 | se401->sbuf[i].data = NULL; | 461 | se401->sbuf[i].data = NULL; |
457 | } | 462 | } |
@@ -459,26 +464,26 @@ static int se401_start_stream(struct usb_se401 *se401) | |||
459 | } | 464 | } |
460 | } | 465 | } |
461 | 466 | ||
462 | se401->bayeroffset=0; | 467 | se401->bayeroffset = 0; |
463 | se401->scratch_next=0; | 468 | se401->scratch_next = 0; |
464 | se401->scratch_use=0; | 469 | se401->scratch_use = 0; |
465 | se401->scratch_overflow=0; | 470 | se401->scratch_overflow = 0; |
466 | for (i=0; i<SE401_NUMSCRATCH; i++) { | 471 | for (i = 0; i < SE401_NUMSCRATCH; i++) { |
467 | se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL); | 472 | se401->scratch[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL); |
468 | if (!se401->scratch[i].data) { | 473 | if (!se401->scratch[i].data) { |
469 | for(i = i - 1; i >= 0; i--) { | 474 | for (i = i - 1; i >= 0; i--) { |
470 | kfree(se401->scratch[i].data); | 475 | kfree(se401->scratch[i].data); |
471 | se401->scratch[i].data = NULL; | 476 | se401->scratch[i].data = NULL; |
472 | } | 477 | } |
473 | goto nomem_sbuf; | 478 | goto nomem_sbuf; |
474 | } | 479 | } |
475 | se401->scratch[i].state=BUFFER_UNUSED; | 480 | se401->scratch[i].state = BUFFER_UNUSED; |
476 | } | 481 | } |
477 | 482 | ||
478 | for (i=0; i<SE401_NUMSBUF; i++) { | 483 | for (i = 0; i < SE401_NUMSBUF; i++) { |
479 | urb=usb_alloc_urb(0, GFP_KERNEL); | 484 | urb = usb_alloc_urb(0, GFP_KERNEL); |
480 | if(!urb) { | 485 | if (!urb) { |
481 | for(i = i - 1; i >= 0; i--) { | 486 | for (i = i - 1; i >= 0; i--) { |
482 | usb_kill_urb(se401->urb[i]); | 487 | usb_kill_urb(se401->urb[i]); |
483 | usb_free_urb(se401->urb[i]); | 488 | usb_free_urb(se401->urb[i]); |
484 | se401->urb[i] = NULL; | 489 | se401->urb[i] = NULL; |
@@ -492,24 +497,24 @@ static int se401_start_stream(struct usb_se401 *se401) | |||
492 | se401_video_irq, | 497 | se401_video_irq, |
493 | se401); | 498 | se401); |
494 | 499 | ||
495 | se401->urb[i]=urb; | 500 | se401->urb[i] = urb; |
496 | 501 | ||
497 | err=usb_submit_urb(se401->urb[i], GFP_KERNEL); | 502 | err = usb_submit_urb(se401->urb[i], GFP_KERNEL); |
498 | if(err) | 503 | if (err) |
499 | err("urb burned down"); | 504 | err("urb burned down"); |
500 | } | 505 | } |
501 | 506 | ||
502 | se401->framecount=0; | 507 | se401->framecount = 0; |
503 | 508 | ||
504 | return 0; | 509 | return 0; |
505 | 510 | ||
506 | nomem_scratch: | 511 | nomem_scratch: |
507 | for (i=0; i<SE401_NUMSCRATCH; i++) { | 512 | for (i = 0; i < SE401_NUMSCRATCH; i++) { |
508 | kfree(se401->scratch[i].data); | 513 | kfree(se401->scratch[i].data); |
509 | se401->scratch[i].data = NULL; | 514 | se401->scratch[i].data = NULL; |
510 | } | 515 | } |
511 | nomem_sbuf: | 516 | nomem_sbuf: |
512 | for (i=0; i<SE401_NUMSBUF; i++) { | 517 | for (i = 0; i < SE401_NUMSBUF; i++) { |
513 | kfree(se401->sbuf[i].data); | 518 | kfree(se401->sbuf[i].data); |
514 | se401->sbuf[i].data = NULL; | 519 | se401->sbuf[i].data = NULL; |
515 | } | 520 | } |
@@ -523,22 +528,23 @@ static int se401_stop_stream(struct usb_se401 *se401) | |||
523 | if (!se401->streaming || !se401->dev) | 528 | if (!se401->streaming || !se401->dev) |
524 | return 1; | 529 | return 1; |
525 | 530 | ||
526 | se401->streaming=0; | 531 | se401->streaming = 0; |
527 | 532 | ||
528 | se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0); | 533 | se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0); |
529 | 534 | ||
530 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0); | 535 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0); |
531 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0); | 536 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0); |
532 | 537 | ||
533 | for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) { | 538 | for (i = 0; i < SE401_NUMSBUF; i++) |
534 | usb_kill_urb(se401->urb[i]); | 539 | if (se401->urb[i]) { |
535 | usb_free_urb(se401->urb[i]); | 540 | usb_kill_urb(se401->urb[i]); |
536 | se401->urb[i]=NULL; | 541 | usb_free_urb(se401->urb[i]); |
537 | kfree(se401->sbuf[i].data); | 542 | se401->urb[i] = NULL; |
538 | } | 543 | kfree(se401->sbuf[i].data); |
539 | for (i=0; i<SE401_NUMSCRATCH; i++) { | 544 | } |
545 | for (i = 0; i < SE401_NUMSCRATCH; i++) { | ||
540 | kfree(se401->scratch[i].data); | 546 | kfree(se401->scratch[i].data); |
541 | se401->scratch[i].data=NULL; | 547 | se401->scratch[i].data = NULL; |
542 | } | 548 | } |
543 | 549 | ||
544 | return 0; | 550 | return 0; |
@@ -546,9 +552,9 @@ static int se401_stop_stream(struct usb_se401 *se401) | |||
546 | 552 | ||
547 | static int se401_set_size(struct usb_se401 *se401, int width, int height) | 553 | static int se401_set_size(struct usb_se401 *se401, int width, int height) |
548 | { | 554 | { |
549 | int wasstreaming=se401->streaming; | 555 | int wasstreaming = se401->streaming; |
550 | /* Check to see if we need to change */ | 556 | /* Check to see if we need to change */ |
551 | if (se401->cwidth==width && se401->cheight==height) | 557 | if (se401->cwidth == width && se401->cheight == height) |
552 | return 0; | 558 | return 0; |
553 | 559 | ||
554 | /* Check for a valid mode */ | 560 | /* Check for a valid mode */ |
@@ -556,16 +562,16 @@ static int se401_set_size(struct usb_se401 *se401, int width, int height) | |||
556 | return 1; | 562 | return 1; |
557 | if ((width & 1) || (height & 1)) | 563 | if ((width & 1) || (height & 1)) |
558 | return 1; | 564 | return 1; |
559 | if (width>se401->width[se401->sizes-1]) | 565 | if (width > se401->width[se401->sizes-1]) |
560 | return 1; | 566 | return 1; |
561 | if (height>se401->height[se401->sizes-1]) | 567 | if (height > se401->height[se401->sizes-1]) |
562 | return 1; | 568 | return 1; |
563 | 569 | ||
564 | /* Stop a current stream and start it again at the new size */ | 570 | /* Stop a current stream and start it again at the new size */ |
565 | if (wasstreaming) | 571 | if (wasstreaming) |
566 | se401_stop_stream(se401); | 572 | se401_stop_stream(se401); |
567 | se401->cwidth=width; | 573 | se401->cwidth = width; |
568 | se401->cheight=height; | 574 | se401->cheight = height; |
569 | if (wasstreaming) | 575 | if (wasstreaming) |
570 | se401_start_stream(se401); | 576 | se401_start_stream(se401); |
571 | return 0; | 577 | return 0; |
@@ -586,68 +592,68 @@ static int se401_set_size(struct usb_se401 *se401, int width, int height) | |||
586 | static inline void enhance_picture(unsigned char *frame, int len) | 592 | static inline void enhance_picture(unsigned char *frame, int len) |
587 | { | 593 | { |
588 | while (len--) { | 594 | while (len--) { |
589 | *frame=(((*frame^255)*(*frame^255))/255)^255; | 595 | *frame = (((*frame^255)*(*frame^255))/255)^255; |
590 | frame++; | 596 | frame++; |
591 | } | 597 | } |
592 | } | 598 | } |
593 | 599 | ||
594 | static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data) | 600 | static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data) |
595 | { | 601 | { |
596 | struct se401_frame *frame=&se401->frame[se401->curframe]; | 602 | struct se401_frame *frame = &se401->frame[se401->curframe]; |
597 | int linelength=se401->cwidth*3; | 603 | int linelength = se401->cwidth * 3; |
598 | 604 | ||
599 | if (frame->curlinepix >= linelength) { | 605 | if (frame->curlinepix >= linelength) { |
600 | frame->curlinepix=0; | 606 | frame->curlinepix = 0; |
601 | frame->curline+=linelength; | 607 | frame->curline += linelength; |
602 | } | 608 | } |
603 | 609 | ||
604 | /* First three are absolute, all others relative. | 610 | /* First three are absolute, all others relative. |
605 | * Format is rgb from right to left (mirrorred image), | 611 | * Format is rgb from right to left (mirrorred image), |
606 | * we flip it to get bgr from left to right. */ | 612 | * we flip it to get bgr from left to right. */ |
607 | if (frame->curlinepix < 3) { | 613 | if (frame->curlinepix < 3) |
608 | *(frame->curline-frame->curlinepix)=1+data*4; | 614 | *(frame->curline-frame->curlinepix) = 1 + data * 4; |
609 | } else { | 615 | else |
610 | *(frame->curline-frame->curlinepix)= | 616 | *(frame->curline-frame->curlinepix) = |
611 | *(frame->curline-frame->curlinepix+3)+data*4; | 617 | *(frame->curline-frame->curlinepix + 3) + data * 4; |
612 | } | ||
613 | frame->curlinepix++; | 618 | frame->curlinepix++; |
614 | } | 619 | } |
615 | 620 | ||
616 | static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength) | 621 | static inline void decode_JangGu_vlc(struct usb_se401 *se401, |
622 | unsigned char *data, int bit_exp, int packetlength) | ||
617 | { | 623 | { |
618 | int pos=0; | 624 | int pos = 0; |
619 | int vlc_cod=0; | 625 | int vlc_cod = 0; |
620 | int vlc_size=0; | 626 | int vlc_size = 0; |
621 | int vlc_data=0; | 627 | int vlc_data = 0; |
622 | int bit_cur; | 628 | int bit_cur; |
623 | int bit; | 629 | int bit; |
624 | data+=4; | 630 | data += 4; |
625 | while (pos < packetlength) { | 631 | while (pos < packetlength) { |
626 | bit_cur=8; | 632 | bit_cur = 8; |
627 | while (bit_cur && bit_exp) { | 633 | while (bit_cur && bit_exp) { |
628 | bit=((*data)>>(bit_cur-1))&1; | 634 | bit = ((*data) >> (bit_cur-1))&1; |
629 | if (!vlc_cod) { | 635 | if (!vlc_cod) { |
630 | if (bit) { | 636 | if (bit) { |
631 | vlc_size++; | 637 | vlc_size++; |
632 | } else { | 638 | } else { |
633 | if (!vlc_size) { | 639 | if (!vlc_size) |
634 | decode_JangGu_integrate(se401, 0); | 640 | decode_JangGu_integrate(se401, 0); |
635 | } else { | 641 | else { |
636 | vlc_cod=2; | 642 | vlc_cod = 2; |
637 | vlc_data=0; | 643 | vlc_data = 0; |
638 | } | 644 | } |
639 | } | 645 | } |
640 | } else { | 646 | } else { |
641 | if (vlc_cod==2) { | 647 | if (vlc_cod == 2) { |
642 | if (!bit) | 648 | if (!bit) |
643 | vlc_data = -(1<<vlc_size) + 1; | 649 | vlc_data = -(1 << vlc_size) + 1; |
644 | vlc_cod--; | 650 | vlc_cod--; |
645 | } | 651 | } |
646 | vlc_size--; | 652 | vlc_size--; |
647 | vlc_data+=bit<<vlc_size; | 653 | vlc_data += bit << vlc_size; |
648 | if (!vlc_size) { | 654 | if (!vlc_size) { |
649 | decode_JangGu_integrate(se401, vlc_data); | 655 | decode_JangGu_integrate(se401, vlc_data); |
650 | vlc_cod=0; | 656 | vlc_cod = 0; |
651 | } | 657 | } |
652 | } | 658 | } |
653 | bit_cur--; | 659 | bit_cur--; |
@@ -658,186 +664,188 @@ static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *da | |||
658 | } | 664 | } |
659 | } | 665 | } |
660 | 666 | ||
661 | static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer) | 667 | static inline void decode_JangGu(struct usb_se401 *se401, |
668 | struct se401_scratch *buffer) | ||
662 | { | 669 | { |
663 | unsigned char *data=buffer->data; | 670 | unsigned char *data = buffer->data; |
664 | int len=buffer->length; | 671 | int len = buffer->length; |
665 | int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size; | 672 | int bit_exp = 0, pix_exp = 0, frameinfo = 0, packetlength = 0, size; |
666 | int datapos=0; | 673 | int datapos = 0; |
667 | 674 | ||
668 | /* New image? */ | 675 | /* New image? */ |
669 | if (!se401->frame[se401->curframe].curpix) { | 676 | if (!se401->frame[se401->curframe].curpix) { |
670 | se401->frame[se401->curframe].curlinepix=0; | 677 | se401->frame[se401->curframe].curlinepix = 0; |
671 | se401->frame[se401->curframe].curline= | 678 | se401->frame[se401->curframe].curline = |
672 | se401->frame[se401->curframe].data+ | 679 | se401->frame[se401->curframe].data+ |
673 | se401->cwidth*3-1; | 680 | se401->cwidth * 3 - 1; |
674 | if (se401->frame[se401->curframe].grabstate==FRAME_READY) | 681 | if (se401->frame[se401->curframe].grabstate == FRAME_READY) |
675 | se401->frame[se401->curframe].grabstate=FRAME_GRABBING; | 682 | se401->frame[se401->curframe].grabstate = FRAME_GRABBING; |
676 | se401->vlcdatapos=0; | 683 | se401->vlcdatapos = 0; |
677 | } | 684 | } |
678 | while (datapos < len) { | 685 | while (datapos < len) { |
679 | size=1024-se401->vlcdatapos; | 686 | size = 1024 - se401->vlcdatapos; |
680 | if (size+datapos > len) | 687 | if (size+datapos > len) |
681 | size=len-datapos; | 688 | size = len-datapos; |
682 | memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size); | 689 | memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size); |
683 | se401->vlcdatapos+=size; | 690 | se401->vlcdatapos += size; |
684 | packetlength=0; | 691 | packetlength = 0; |
685 | if (se401->vlcdatapos >= 4) { | 692 | if (se401->vlcdatapos >= 4) { |
686 | bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8); | 693 | bit_exp = se401->vlcdata[3] + (se401->vlcdata[2] << 8); |
687 | pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8); | 694 | pix_exp = se401->vlcdata[1] + |
688 | frameinfo=se401->vlcdata[0]&0xc0; | 695 | ((se401->vlcdata[0] & 0x3f) << 8); |
689 | packetlength=((bit_exp+47)>>4)<<1; | 696 | frameinfo = se401->vlcdata[0] & 0xc0; |
697 | packetlength = ((bit_exp + 47) >> 4) << 1; | ||
690 | if (packetlength > 1024) { | 698 | if (packetlength > 1024) { |
691 | se401->vlcdatapos=0; | 699 | se401->vlcdatapos = 0; |
692 | datapos=len; | 700 | datapos = len; |
693 | packetlength=0; | 701 | packetlength = 0; |
694 | se401->error++; | 702 | se401->error++; |
695 | se401->frame[se401->curframe].curpix=0; | 703 | se401->frame[se401->curframe].curpix = 0; |
696 | } | 704 | } |
697 | } | 705 | } |
698 | if (packetlength && se401->vlcdatapos >= packetlength) { | 706 | if (packetlength && se401->vlcdatapos >= packetlength) { |
699 | decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength); | 707 | decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, |
700 | se401->frame[se401->curframe].curpix+=pix_exp*3; | 708 | packetlength); |
701 | datapos+=size-(se401->vlcdatapos-packetlength); | 709 | se401->frame[se401->curframe].curpix += pix_exp * 3; |
702 | se401->vlcdatapos=0; | 710 | datapos += size-(se401->vlcdatapos-packetlength); |
703 | if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) { | 711 | se401->vlcdatapos = 0; |
704 | if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) { | 712 | if (se401->frame[se401->curframe].curpix >= se401->cwidth * se401->cheight * 3) { |
705 | if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) { | 713 | if (se401->frame[se401->curframe].curpix == se401->cwidth * se401->cheight * 3) { |
706 | se401->frame[se401->curframe].grabstate=FRAME_DONE; | 714 | if (se401->frame[se401->curframe].grabstate == FRAME_GRABBING) { |
715 | se401->frame[se401->curframe].grabstate = FRAME_DONE; | ||
707 | se401->framecount++; | 716 | se401->framecount++; |
708 | se401->readcount++; | 717 | se401->readcount++; |
709 | } | 718 | } |
710 | if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) { | 719 | if (se401->frame[(se401->curframe + 1) & (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) |
711 | se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1); | 720 | se401->curframe = (se401->curframe + 1) & (SE401_NUMFRAMES - 1); |
712 | } | 721 | } else |
713 | } else { | ||
714 | se401->error++; | 722 | se401->error++; |
715 | } | 723 | se401->frame[se401->curframe].curpix = 0; |
716 | se401->frame[se401->curframe].curpix=0; | 724 | datapos = len; |
717 | datapos=len; | ||
718 | } | 725 | } |
719 | } else { | 726 | } else |
720 | datapos+=size; | 727 | datapos += size; |
721 | } | ||
722 | } | 728 | } |
723 | } | 729 | } |
724 | 730 | ||
725 | static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer) | 731 | static inline void decode_bayer(struct usb_se401 *se401, |
732 | struct se401_scratch *buffer) | ||
726 | { | 733 | { |
727 | unsigned char *data=buffer->data; | 734 | unsigned char *data = buffer->data; |
728 | int len=buffer->length; | 735 | int len = buffer->length; |
729 | int offset=buffer->offset; | 736 | int offset = buffer->offset; |
730 | int datasize=se401->cwidth*se401->cheight; | 737 | int datasize = se401->cwidth * se401->cheight; |
731 | struct se401_frame *frame=&se401->frame[se401->curframe]; | 738 | struct se401_frame *frame = &se401->frame[se401->curframe]; |
739 | unsigned char *framedata = frame->data, *curline, *nextline; | ||
740 | int width = se401->cwidth; | ||
741 | int blineoffset = 0, bline; | ||
742 | int linelength = width * 3, i; | ||
732 | 743 | ||
733 | unsigned char *framedata=frame->data, *curline, *nextline; | ||
734 | int width=se401->cwidth; | ||
735 | int blineoffset=0, bline; | ||
736 | int linelength=width*3, i; | ||
737 | 744 | ||
745 | if (frame->curpix == 0) { | ||
746 | if (frame->grabstate == FRAME_READY) | ||
747 | frame->grabstate = FRAME_GRABBING; | ||
738 | 748 | ||
739 | if (frame->curpix==0) { | 749 | frame->curline = framedata + linelength; |
740 | if (frame->grabstate==FRAME_READY) { | 750 | frame->curlinepix = 0; |
741 | frame->grabstate=FRAME_GRABBING; | ||
742 | } | ||
743 | frame->curline=framedata+linelength; | ||
744 | frame->curlinepix=0; | ||
745 | } | 751 | } |
746 | 752 | ||
747 | if (offset!=frame->curpix) { | 753 | if (offset != frame->curpix) { |
748 | /* Regard frame as lost :( */ | 754 | /* Regard frame as lost :( */ |
749 | frame->curpix=0; | 755 | frame->curpix = 0; |
750 | se401->error++; | 756 | se401->error++; |
751 | return; | 757 | return; |
752 | } | 758 | } |
753 | 759 | ||
754 | /* Check if we have to much data */ | 760 | /* Check if we have to much data */ |
755 | if (frame->curpix+len > datasize) { | 761 | if (frame->curpix + len > datasize) |
756 | len=datasize-frame->curpix; | 762 | len = datasize-frame->curpix; |
757 | } | 763 | |
758 | if (se401->cheight%4) | 764 | if (se401->cheight % 4) |
759 | blineoffset=1; | 765 | blineoffset = 1; |
760 | bline=frame->curpix/se401->cwidth+blineoffset; | 766 | bline = frame->curpix / se401->cwidth+blineoffset; |
761 | 767 | ||
762 | curline=frame->curline; | 768 | curline = frame->curline; |
763 | nextline=curline+linelength; | 769 | nextline = curline + linelength; |
764 | if (nextline >= framedata+datasize*3) | 770 | if (nextline >= framedata+datasize * 3) |
765 | nextline=curline; | 771 | nextline = curline; |
766 | while (len) { | 772 | while (len) { |
767 | if (frame->curlinepix>=width) { | 773 | if (frame->curlinepix >= width) { |
768 | frame->curlinepix-=width; | 774 | frame->curlinepix -= width; |
769 | bline=frame->curpix/width+blineoffset; | 775 | bline = frame->curpix / width + blineoffset; |
770 | curline+=linelength*2; | 776 | curline += linelength*2; |
771 | nextline+=linelength*2; | 777 | nextline += linelength*2; |
772 | if (curline >= framedata+datasize*3) { | 778 | if (curline >= framedata+datasize * 3) { |
773 | frame->curlinepix++; | 779 | frame->curlinepix++; |
774 | curline-=3; | 780 | curline -= 3; |
775 | nextline-=3; | 781 | nextline -= 3; |
776 | len--; | 782 | len--; |
777 | data++; | 783 | data++; |
778 | frame->curpix++; | 784 | frame->curpix++; |
779 | } | 785 | } |
780 | if (nextline >= framedata+datasize*3) | 786 | if (nextline >= framedata+datasize*3) |
781 | nextline=curline; | 787 | nextline = curline; |
782 | } | 788 | } |
783 | if ((bline&1)) { | 789 | if (bline & 1) { |
784 | if ((frame->curlinepix&1)) { | 790 | if (frame->curlinepix & 1) { |
785 | *(curline+2)=*data; | 791 | *(curline + 2) = *data; |
786 | *(curline-1)=*data; | 792 | *(curline - 1) = *data; |
787 | *(nextline+2)=*data; | 793 | *(nextline + 2) = *data; |
788 | *(nextline-1)=*data; | 794 | *(nextline - 1) = *data; |
789 | } else { | 795 | } else { |
790 | *(curline+1)= | 796 | *(curline + 1) = |
791 | (*(curline+1)+*data)/2; | 797 | (*(curline + 1) + *data) / 2; |
792 | *(curline-2)= | 798 | *(curline-2) = |
793 | (*(curline-2)+*data)/2; | 799 | (*(curline - 2) + *data) / 2; |
794 | *(nextline+1)=*data; | 800 | *(nextline + 1) = *data; |
795 | *(nextline-2)=*data; | 801 | *(nextline - 2) = *data; |
796 | } | 802 | } |
797 | } else { | 803 | } else { |
798 | if ((frame->curlinepix&1)) { | 804 | if (frame->curlinepix & 1) { |
799 | *(curline+1)= | 805 | *(curline + 1) = |
800 | (*(curline+1)+*data)/2; | 806 | (*(curline + 1) + *data) / 2; |
801 | *(curline-2)= | 807 | *(curline - 2) = |
802 | (*(curline-2)+*data)/2; | 808 | (*(curline - 2) + *data) / 2; |
803 | *(nextline+1)=*data; | 809 | *(nextline + 1) = *data; |
804 | *(nextline-2)=*data; | 810 | *(nextline - 2) = *data; |
805 | } else { | 811 | } else { |
806 | *curline=*data; | 812 | *curline = *data; |
807 | *(curline-3)=*data; | 813 | *(curline - 3) = *data; |
808 | *nextline=*data; | 814 | *nextline = *data; |
809 | *(nextline-3)=*data; | 815 | *(nextline - 3) = *data; |
810 | } | 816 | } |
811 | } | 817 | } |
812 | frame->curlinepix++; | 818 | frame->curlinepix++; |
813 | curline-=3; | 819 | curline -= 3; |
814 | nextline-=3; | 820 | nextline -= 3; |
815 | len--; | 821 | len--; |
816 | data++; | 822 | data++; |
817 | frame->curpix++; | 823 | frame->curpix++; |
818 | } | 824 | } |
819 | frame->curline=curline; | 825 | frame->curline = curline; |
820 | 826 | ||
821 | if (frame->curpix>=datasize) { | 827 | if (frame->curpix >= datasize) { |
822 | /* Fix the top line */ | 828 | /* Fix the top line */ |
823 | framedata+=linelength; | 829 | framedata += linelength; |
824 | for (i=0; i<linelength; i++) { | 830 | for (i = 0; i < linelength; i++) { |
825 | framedata--; | 831 | framedata--; |
826 | *framedata=*(framedata+linelength); | 832 | *framedata = *(framedata + linelength); |
827 | } | 833 | } |
828 | /* Fix the left side (green is already present) */ | 834 | /* Fix the left side (green is already present) */ |
829 | for (i=0; i<se401->cheight; i++) { | 835 | for (i = 0; i < se401->cheight; i++) { |
830 | *framedata=*(framedata+3); | 836 | *framedata = *(framedata + 3); |
831 | *(framedata+1)=*(framedata+4); | 837 | *(framedata + 1) = *(framedata + 4); |
832 | *(framedata+2)=*(framedata+5); | 838 | *(framedata + 2) = *(framedata + 5); |
833 | framedata+=linelength; | 839 | framedata += linelength; |
834 | } | 840 | } |
835 | frame->curpix=0; | 841 | frame->curpix = 0; |
836 | frame->grabstate=FRAME_DONE; | 842 | frame->grabstate = FRAME_DONE; |
837 | se401->framecount++; | 843 | se401->framecount++; |
838 | se401->readcount++; | 844 | se401->readcount++; |
839 | if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) { | 845 | if (se401->frame[(se401->curframe + 1) & |
840 | se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1); | 846 | (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) { |
847 | se401->curframe = (se401->curframe+1) & | ||
848 | (SE401_NUMFRAMES-1); | ||
841 | } | 849 | } |
842 | } | 850 | } |
843 | } | 851 | } |
@@ -845,72 +853,76 @@ static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch * | |||
845 | static int se401_newframe(struct usb_se401 *se401, int framenr) | 853 | static int se401_newframe(struct usb_se401 *se401, int framenr) |
846 | { | 854 | { |
847 | DECLARE_WAITQUEUE(wait, current); | 855 | DECLARE_WAITQUEUE(wait, current); |
848 | int errors=0; | 856 | int errors = 0; |
849 | 857 | ||
850 | while (se401->streaming && | 858 | while (se401->streaming && |
851 | (se401->frame[framenr].grabstate==FRAME_READY || | 859 | (se401->frame[framenr].grabstate == FRAME_READY || |
852 | se401->frame[framenr].grabstate==FRAME_GRABBING) ) { | 860 | se401->frame[framenr].grabstate == FRAME_GRABBING)) { |
853 | if(!se401->frame[framenr].curpix) { | 861 | if (!se401->frame[framenr].curpix) |
854 | errors++; | 862 | errors++; |
855 | } | 863 | |
856 | wait_interruptible( | 864 | wait_interruptible( |
857 | se401->scratch[se401->scratch_use].state!=BUFFER_READY, | 865 | se401->scratch[se401->scratch_use].state != BUFFER_READY, |
858 | &se401->wq, | 866 | &se401->wq, &wait); |
859 | &wait | ||
860 | ); | ||
861 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) { | 867 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) { |
862 | se401->nullpackets=0; | 868 | se401->nullpackets = 0; |
863 | dev_info(&se401->dev->dev, | 869 | dev_info(&se401->dev->dev, |
864 | "too many null length packets, restarting capture\n"); | 870 | "too many null length packets, restarting capture\n"); |
865 | se401_stop_stream(se401); | 871 | se401_stop_stream(se401); |
866 | se401_start_stream(se401); | 872 | se401_start_stream(se401); |
867 | } else { | 873 | } else { |
868 | if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) { | 874 | if (se401->scratch[se401->scratch_use].state != |
869 | se401->frame[framenr].grabstate=FRAME_ERROR; | 875 | BUFFER_READY) { |
876 | se401->frame[framenr].grabstate = FRAME_ERROR; | ||
870 | return -EIO; | 877 | return -EIO; |
871 | } | 878 | } |
872 | se401->scratch[se401->scratch_use].state=BUFFER_BUSY; | 879 | se401->scratch[se401->scratch_use].state = BUFFER_BUSY; |
873 | if (se401->format==FMT_JANGGU) { | 880 | if (se401->format == FMT_JANGGU) |
874 | decode_JangGu(se401, &se401->scratch[se401->scratch_use]); | 881 | decode_JangGu(se401, |
875 | } else { | 882 | &se401->scratch[se401->scratch_use]); |
876 | decode_bayer(se401, &se401->scratch[se401->scratch_use]); | 883 | else |
877 | } | 884 | decode_bayer(se401, |
878 | se401->scratch[se401->scratch_use].state=BUFFER_UNUSED; | 885 | &se401->scratch[se401->scratch_use]); |
886 | |||
887 | se401->scratch[se401->scratch_use].state = | ||
888 | BUFFER_UNUSED; | ||
879 | se401->scratch_use++; | 889 | se401->scratch_use++; |
880 | if (se401->scratch_use>=SE401_NUMSCRATCH) | 890 | if (se401->scratch_use >= SE401_NUMSCRATCH) |
881 | se401->scratch_use=0; | 891 | se401->scratch_use = 0; |
882 | if (errors > SE401_MAX_ERRORS) { | 892 | if (errors > SE401_MAX_ERRORS) { |
883 | errors=0; | 893 | errors = 0; |
884 | dev_info(&se401->dev->dev, | 894 | dev_info(&se401->dev->dev, |
885 | "too many errors, restarting capture\n"); | 895 | "too many errors, restarting capture\n"); |
886 | se401_stop_stream(se401); | 896 | se401_stop_stream(se401); |
887 | se401_start_stream(se401); | 897 | se401_start_stream(se401); |
888 | } | 898 | } |
889 | } | 899 | } |
890 | } | 900 | } |
891 | 901 | ||
892 | if (se401->frame[framenr].grabstate==FRAME_DONE) | 902 | if (se401->frame[framenr].grabstate == FRAME_DONE) |
893 | if (se401->enhance) | 903 | if (se401->enhance) |
894 | enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3); | 904 | enhance_picture(se401->frame[framenr].data, |
905 | se401->cheight * se401->cwidth * 3); | ||
895 | return 0; | 906 | return 0; |
896 | } | 907 | } |
897 | 908 | ||
898 | static void usb_se401_remove_disconnected (struct usb_se401 *se401) | 909 | static void usb_se401_remove_disconnected(struct usb_se401 *se401) |
899 | { | 910 | { |
900 | int i; | 911 | int i; |
901 | 912 | ||
902 | se401->dev = NULL; | 913 | se401->dev = NULL; |
903 | 914 | ||
904 | for (i=0; i<SE401_NUMSBUF; i++) | 915 | for (i = 0; i < SE401_NUMSBUF; i++) |
905 | if (se401->urb[i]) { | 916 | if (se401->urb[i]) { |
906 | usb_kill_urb(se401->urb[i]); | 917 | usb_kill_urb(se401->urb[i]); |
907 | usb_free_urb(se401->urb[i]); | 918 | usb_free_urb(se401->urb[i]); |
908 | se401->urb[i] = NULL; | 919 | se401->urb[i] = NULL; |
909 | kfree(se401->sbuf[i].data); | 920 | kfree(se401->sbuf[i].data); |
910 | } | 921 | } |
911 | for (i=0; i<SE401_NUMSCRATCH; i++) { | 922 | |
923 | for (i = 0; i < SE401_NUMSCRATCH; i++) | ||
912 | kfree(se401->scratch[i].data); | 924 | kfree(se401->scratch[i].data); |
913 | } | 925 | |
914 | if (se401->inturb) { | 926 | if (se401->inturb) { |
915 | usb_kill_urb(se401->inturb); | 927 | usb_kill_urb(se401->inturb); |
916 | usb_free_urb(se401->inturb); | 928 | usb_free_urb(se401->inturb); |
@@ -965,11 +977,11 @@ static int se401_close(struct file *file) | |||
965 | dev_info(&se401->dev->dev, "device unregistered\n"); | 977 | dev_info(&se401->dev->dev, "device unregistered\n"); |
966 | usb_se401_remove_disconnected(se401); | 978 | usb_se401_remove_disconnected(se401); |
967 | } else { | 979 | } else { |
968 | for (i=0; i<SE401_NUMFRAMES; i++) | 980 | for (i = 0; i < SE401_NUMFRAMES; i++) |
969 | se401->frame[i].grabstate=FRAME_UNUSED; | 981 | se401->frame[i].grabstate = FRAME_UNUSED; |
970 | if (se401->streaming) | 982 | if (se401->streaming) |
971 | se401_stop_stream(se401); | 983 | se401_stop_stream(se401); |
972 | se401->user=0; | 984 | se401->user = 0; |
973 | } | 985 | } |
974 | file->private_data = NULL; | 986 | file->private_data = NULL; |
975 | return 0; | 987 | return 0; |
@@ -1065,7 +1077,7 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1065 | memset(vm, 0, sizeof(*vm)); | 1077 | memset(vm, 0, sizeof(*vm)); |
1066 | vm->size = SE401_NUMFRAMES * se401->maxframesize; | 1078 | vm->size = SE401_NUMFRAMES * se401->maxframesize; |
1067 | vm->frames = SE401_NUMFRAMES; | 1079 | vm->frames = SE401_NUMFRAMES; |
1068 | for (i=0; i<SE401_NUMFRAMES; i++) | 1080 | for (i = 0; i < SE401_NUMFRAMES; i++) |
1069 | vm->offsets[i] = se401->maxframesize * i; | 1081 | vm->offsets[i] = se401->maxframesize * i; |
1070 | return 0; | 1082 | return 0; |
1071 | } | 1083 | } |
@@ -1083,16 +1095,16 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1083 | /* Is this according to the v4l spec??? */ | 1095 | /* Is this according to the v4l spec??? */ |
1084 | if (se401_set_size(se401, vm->width, vm->height)) | 1096 | if (se401_set_size(se401, vm->width, vm->height)) |
1085 | return -EINVAL; | 1097 | return -EINVAL; |
1086 | se401->frame[vm->frame].grabstate=FRAME_READY; | 1098 | se401->frame[vm->frame].grabstate = FRAME_READY; |
1087 | 1099 | ||
1088 | if (!se401->streaming) | 1100 | if (!se401->streaming) |
1089 | se401_start_stream(se401); | 1101 | se401_start_stream(se401); |
1090 | 1102 | ||
1091 | /* Set the picture properties */ | 1103 | /* Set the picture properties */ |
1092 | if (se401->framecount==0) | 1104 | if (se401->framecount == 0) |
1093 | se401_send_pict(se401); | 1105 | se401_send_pict(se401); |
1094 | /* Calibrate the reset level after a few frames. */ | 1106 | /* Calibrate the reset level after a few frames. */ |
1095 | if (se401->framecount%20==1) | 1107 | if (se401->framecount % 20 == 1) |
1096 | se401_auto_resetlevel(se401); | 1108 | se401_auto_resetlevel(se401); |
1097 | 1109 | ||
1098 | return 0; | 1110 | return 0; |
@@ -1100,13 +1112,13 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1100 | case VIDIOCSYNC: | 1112 | case VIDIOCSYNC: |
1101 | { | 1113 | { |
1102 | int *frame = arg; | 1114 | int *frame = arg; |
1103 | int ret=0; | 1115 | int ret = 0; |
1104 | 1116 | ||
1105 | if(*frame <0 || *frame >= SE401_NUMFRAMES) | 1117 | if (*frame < 0 || *frame >= SE401_NUMFRAMES) |
1106 | return -EINVAL; | 1118 | return -EINVAL; |
1107 | 1119 | ||
1108 | ret=se401_newframe(se401, *frame); | 1120 | ret = se401_newframe(se401, *frame); |
1109 | se401->frame[*frame].grabstate=FRAME_UNUSED; | 1121 | se401->frame[*frame].grabstate = FRAME_UNUSED; |
1110 | return ret; | 1122 | return ret; |
1111 | } | 1123 | } |
1112 | case VIDIOCGFBUF: | 1124 | case VIDIOCGFBUF: |
@@ -1147,36 +1159,36 @@ static long se401_ioctl(struct file *file, | |||
1147 | static ssize_t se401_read(struct file *file, char __user *buf, | 1159 | static ssize_t se401_read(struct file *file, char __user *buf, |
1148 | size_t count, loff_t *ppos) | 1160 | size_t count, loff_t *ppos) |
1149 | { | 1161 | { |
1150 | int realcount=count, ret=0; | 1162 | int realcount = count, ret = 0; |
1151 | struct video_device *dev = file->private_data; | 1163 | struct video_device *dev = file->private_data; |
1152 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | 1164 | struct usb_se401 *se401 = (struct usb_se401 *)dev; |
1153 | 1165 | ||
1154 | 1166 | ||
1155 | if (se401->dev == NULL) | 1167 | if (se401->dev == NULL) |
1156 | return -EIO; | 1168 | return -EIO; |
1157 | if (realcount > se401->cwidth*se401->cheight*3) | 1169 | if (realcount > se401->cwidth*se401->cheight*3) |
1158 | realcount=se401->cwidth*se401->cheight*3; | 1170 | realcount = se401->cwidth*se401->cheight*3; |
1159 | 1171 | ||
1160 | /* Shouldn't happen: */ | 1172 | /* Shouldn't happen: */ |
1161 | if (se401->frame[0].grabstate==FRAME_GRABBING) | 1173 | if (se401->frame[0].grabstate == FRAME_GRABBING) |
1162 | return -EBUSY; | 1174 | return -EBUSY; |
1163 | se401->frame[0].grabstate=FRAME_READY; | 1175 | se401->frame[0].grabstate = FRAME_READY; |
1164 | se401->frame[1].grabstate=FRAME_UNUSED; | 1176 | se401->frame[1].grabstate = FRAME_UNUSED; |
1165 | se401->curframe=0; | 1177 | se401->curframe = 0; |
1166 | 1178 | ||
1167 | if (!se401->streaming) | 1179 | if (!se401->streaming) |
1168 | se401_start_stream(se401); | 1180 | se401_start_stream(se401); |
1169 | 1181 | ||
1170 | /* Set the picture properties */ | 1182 | /* Set the picture properties */ |
1171 | if (se401->framecount==0) | 1183 | if (se401->framecount == 0) |
1172 | se401_send_pict(se401); | 1184 | se401_send_pict(se401); |
1173 | /* Calibrate the reset level after a few frames. */ | 1185 | /* Calibrate the reset level after a few frames. */ |
1174 | if (se401->framecount%20==1) | 1186 | if (se401->framecount%20 == 1) |
1175 | se401_auto_resetlevel(se401); | 1187 | se401_auto_resetlevel(se401); |
1176 | 1188 | ||
1177 | ret=se401_newframe(se401, 0); | 1189 | ret = se401_newframe(se401, 0); |
1178 | 1190 | ||
1179 | se401->frame[0].grabstate=FRAME_UNUSED; | 1191 | se401->frame[0].grabstate = FRAME_UNUSED; |
1180 | if (ret) | 1192 | if (ret) |
1181 | return ret; | 1193 | return ret; |
1182 | if (copy_to_user(buf, se401->frame[0].data, realcount)) | 1194 | if (copy_to_user(buf, se401->frame[0].data, realcount)) |
@@ -1195,11 +1207,12 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) | |||
1195 | 1207 | ||
1196 | mutex_lock(&se401->lock); | 1208 | mutex_lock(&se401->lock); |
1197 | 1209 | ||
1198 | if (se401->dev == NULL) { | 1210 | if (se401->dev == NULL) { |
1199 | mutex_unlock(&se401->lock); | 1211 | mutex_unlock(&se401->lock); |
1200 | return -EIO; | 1212 | return -EIO; |
1201 | } | 1213 | } |
1202 | if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) { | 1214 | if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) |
1215 | & ~(PAGE_SIZE - 1))) { | ||
1203 | mutex_unlock(&se401->lock); | 1216 | mutex_unlock(&se401->lock); |
1204 | return -EINVAL; | 1217 | return -EINVAL; |
1205 | } | 1218 | } |
@@ -1210,10 +1223,10 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) | |||
1210 | mutex_unlock(&se401->lock); | 1223 | mutex_unlock(&se401->lock); |
1211 | return -EAGAIN; | 1224 | return -EAGAIN; |
1212 | } | 1225 | } |
1213 | start += PAGE_SIZE; | 1226 | start += PAGE_SIZE; |
1214 | pos += PAGE_SIZE; | 1227 | pos += PAGE_SIZE; |
1215 | if (size > PAGE_SIZE) | 1228 | if (size > PAGE_SIZE) |
1216 | size -= PAGE_SIZE; | 1229 | size -= PAGE_SIZE; |
1217 | else | 1230 | else |
1218 | size = 0; | 1231 | size = 0; |
1219 | } | 1232 | } |
@@ -1223,7 +1236,7 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) | |||
1223 | } | 1236 | } |
1224 | 1237 | ||
1225 | static const struct v4l2_file_operations se401_fops = { | 1238 | static const struct v4l2_file_operations se401_fops = { |
1226 | .owner = THIS_MODULE, | 1239 | .owner = THIS_MODULE, |
1227 | .open = se401_open, | 1240 | .open = se401_open, |
1228 | .release = se401_close, | 1241 | .release = se401_close, |
1229 | .read = se401_read, | 1242 | .read = se401_read, |
@@ -1241,71 +1254,76 @@ static struct video_device se401_template = { | |||
1241 | /***************************/ | 1254 | /***************************/ |
1242 | static int se401_init(struct usb_se401 *se401, int button) | 1255 | static int se401_init(struct usb_se401 *se401, int button) |
1243 | { | 1256 | { |
1244 | int i=0, rc; | 1257 | int i = 0, rc; |
1245 | unsigned char cp[0x40]; | 1258 | unsigned char cp[0x40]; |
1246 | char temp[200]; | 1259 | char temp[200]; |
1260 | int slen; | ||
1247 | 1261 | ||
1248 | /* led on */ | 1262 | /* led on */ |
1249 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); | 1263 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); |
1250 | 1264 | ||
1251 | /* get camera descriptor */ | 1265 | /* get camera descriptor */ |
1252 | rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp)); | 1266 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, |
1253 | if (cp[1]!=0x41) { | 1267 | cp, sizeof(cp)); |
1268 | if (cp[1] != 0x41) { | ||
1254 | err("Wrong descriptor type"); | 1269 | err("Wrong descriptor type"); |
1255 | return 1; | 1270 | return 1; |
1256 | } | 1271 | } |
1257 | sprintf (temp, "ExtraFeatures: %d", cp[3]); | 1272 | slen = snprintf(temp, 200, "ExtraFeatures: %d", cp[3]); |
1258 | 1273 | ||
1259 | se401->sizes=cp[4]+cp[5]*256; | 1274 | se401->sizes = cp[4] + cp[5] * 256; |
1260 | se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); | 1275 | se401->width = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); |
1261 | if (!se401->width) | 1276 | if (!se401->width) |
1262 | return 1; | 1277 | return 1; |
1263 | se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); | 1278 | se401->height = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); |
1264 | if (!se401->height) { | 1279 | if (!se401->height) { |
1265 | kfree(se401->width); | 1280 | kfree(se401->width); |
1266 | return 1; | 1281 | return 1; |
1267 | } | 1282 | } |
1268 | for (i=0; i<se401->sizes; i++) { | 1283 | for (i = 0; i < se401->sizes; i++) { |
1269 | se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256; | 1284 | se401->width[i] = cp[6 + i * 4 + 0] + cp[6 + i*4 + 1] * 256; |
1270 | se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256; | 1285 | se401->height[i] = cp[6 + i * 4 + 2] + cp[6 + i * 4 + 3] * 256; |
1271 | } | 1286 | } |
1272 | sprintf (temp, "%s Sizes:", temp); | 1287 | slen += snprintf(temp + slen, 200 - slen, " Sizes:"); |
1273 | for (i=0; i<se401->sizes; i++) { | 1288 | for (i = 0; i < se401->sizes; i++) { |
1274 | sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]); | 1289 | slen += snprintf(temp + slen, 200 - slen, |
1290 | " %dx%d", se401->width[i], se401->height[i]); | ||
1275 | } | 1291 | } |
1276 | dev_info(&se401->dev->dev, "%s\n", temp); | 1292 | dev_info(&se401->dev->dev, "%s\n", temp); |
1277 | se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3; | 1293 | se401->maxframesize = se401->width[se401->sizes-1] * |
1294 | se401->height[se401->sizes - 1] * 3; | ||
1278 | 1295 | ||
1279 | rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp)); | 1296 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp)); |
1280 | se401->cwidth=cp[0]+cp[1]*256; | 1297 | se401->cwidth = cp[0]+cp[1]*256; |
1281 | rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp)); | 1298 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp)); |
1282 | se401->cheight=cp[0]+cp[1]*256; | 1299 | se401->cheight = cp[0]+cp[1]*256; |
1283 | 1300 | ||
1284 | if (!(cp[2] & SE401_FORMAT_BAYER)) { | 1301 | if (!(cp[2] & SE401_FORMAT_BAYER)) { |
1285 | err("Bayer format not supported!"); | 1302 | err("Bayer format not supported!"); |
1286 | return 1; | 1303 | return 1; |
1287 | } | 1304 | } |
1288 | /* set output mode (BAYER) */ | 1305 | /* set output mode (BAYER) */ |
1289 | se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0); | 1306 | se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, |
1307 | SE401_FORMAT_BAYER, NULL, 0); | ||
1290 | 1308 | ||
1291 | rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp)); | 1309 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp)); |
1292 | se401->brightness=cp[0]+cp[1]*256; | 1310 | se401->brightness = cp[0]+cp[1]*256; |
1293 | /* some default values */ | 1311 | /* some default values */ |
1294 | se401->resetlevel=0x2d; | 1312 | se401->resetlevel = 0x2d; |
1295 | se401->rgain=0x20; | 1313 | se401->rgain = 0x20; |
1296 | se401->ggain=0x20; | 1314 | se401->ggain = 0x20; |
1297 | se401->bgain=0x20; | 1315 | se401->bgain = 0x20; |
1298 | se401_set_exposure(se401, 20000); | 1316 | se401_set_exposure(se401, 20000); |
1299 | se401->palette=VIDEO_PALETTE_RGB24; | 1317 | se401->palette = VIDEO_PALETTE_RGB24; |
1300 | se401->enhance=1; | 1318 | se401->enhance = 1; |
1301 | se401->dropped=0; | 1319 | se401->dropped = 0; |
1302 | se401->error=0; | 1320 | se401->error = 0; |
1303 | se401->framecount=0; | 1321 | se401->framecount = 0; |
1304 | se401->readcount=0; | 1322 | se401->readcount = 0; |
1305 | 1323 | ||
1306 | /* Start interrupt transfers for snapshot button */ | 1324 | /* Start interrupt transfers for snapshot button */ |
1307 | if (button) { | 1325 | if (button) { |
1308 | se401->inturb=usb_alloc_urb(0, GFP_KERNEL); | 1326 | se401->inturb = usb_alloc_urb(0, GFP_KERNEL); |
1309 | if (!se401->inturb) { | 1327 | if (!se401->inturb) { |
1310 | dev_info(&se401->dev->dev, | 1328 | dev_info(&se401->dev->dev, |
1311 | "Allocation of inturb failed\n"); | 1329 | "Allocation of inturb failed\n"); |
@@ -1323,7 +1341,7 @@ static int se401_init(struct usb_se401 *se401, int button) | |||
1323 | return 1; | 1341 | return 1; |
1324 | } | 1342 | } |
1325 | } else | 1343 | } else |
1326 | se401->inturb=NULL; | 1344 | se401->inturb = NULL; |
1327 | 1345 | ||
1328 | /* Flash the led */ | 1346 | /* Flash the led */ |
1329 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); | 1347 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); |
@@ -1340,8 +1358,8 @@ static int se401_probe(struct usb_interface *intf, | |||
1340 | struct usb_device *dev = interface_to_usbdev(intf); | 1358 | struct usb_device *dev = interface_to_usbdev(intf); |
1341 | struct usb_interface_descriptor *interface; | 1359 | struct usb_interface_descriptor *interface; |
1342 | struct usb_se401 *se401; | 1360 | struct usb_se401 *se401; |
1343 | char *camera_name=NULL; | 1361 | char *camera_name = NULL; |
1344 | int button=1; | 1362 | int button = 1; |
1345 | 1363 | ||
1346 | /* We don't handle multi-config cameras */ | 1364 | /* We don't handle multi-config cameras */ |
1347 | if (dev->descriptor.bNumConfigurations != 1) | 1365 | if (dev->descriptor.bNumConfigurations != 1) |
@@ -1350,22 +1368,22 @@ static int se401_probe(struct usb_interface *intf, | |||
1350 | interface = &intf->cur_altsetting->desc; | 1368 | interface = &intf->cur_altsetting->desc; |
1351 | 1369 | ||
1352 | /* Is it an se401? */ | 1370 | /* Is it an se401? */ |
1353 | if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 && | 1371 | if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 && |
1354 | le16_to_cpu(dev->descriptor.idProduct) == 0x0004) { | 1372 | le16_to_cpu(dev->descriptor.idProduct) == 0x0004) { |
1355 | camera_name="Endpoints/Aox SE401"; | 1373 | camera_name = "Endpoints/Aox SE401"; |
1356 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 && | 1374 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 && |
1357 | le16_to_cpu(dev->descriptor.idProduct) == 0x030b) { | 1375 | le16_to_cpu(dev->descriptor.idProduct) == 0x030b) { |
1358 | camera_name="Philips PCVC665K"; | 1376 | camera_name = "Philips PCVC665K"; |
1359 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | 1377 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && |
1360 | le16_to_cpu(dev->descriptor.idProduct) == 0x5001) { | 1378 | le16_to_cpu(dev->descriptor.idProduct) == 0x5001) { |
1361 | camera_name="Kensington VideoCAM 67014"; | 1379 | camera_name = "Kensington VideoCAM 67014"; |
1362 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | 1380 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && |
1363 | le16_to_cpu(dev->descriptor.idProduct) == 0x5002) { | 1381 | le16_to_cpu(dev->descriptor.idProduct) == 0x5002) { |
1364 | camera_name="Kensington VideoCAM 6701(5/7)"; | 1382 | camera_name = "Kensington VideoCAM 6701(5/7)"; |
1365 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | 1383 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && |
1366 | le16_to_cpu(dev->descriptor.idProduct) == 0x5003) { | 1384 | le16_to_cpu(dev->descriptor.idProduct) == 0x5003) { |
1367 | camera_name="Kensington VideoCAM 67016"; | 1385 | camera_name = "Kensington VideoCAM 67016"; |
1368 | button=0; | 1386 | button = 0; |
1369 | } else | 1387 | } else |
1370 | return -ENODEV; | 1388 | return -ENODEV; |
1371 | 1389 | ||
@@ -1378,7 +1396,8 @@ static int se401_probe(struct usb_interface *intf, | |||
1378 | /* We found one */ | 1396 | /* We found one */ |
1379 | dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name); | 1397 | dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name); |
1380 | 1398 | ||
1381 | if ((se401 = kzalloc(sizeof(*se401), GFP_KERNEL)) == NULL) { | 1399 | se401 = kzalloc(sizeof(*se401), GFP_KERNEL); |
1400 | if (se401 == NULL) { | ||
1382 | err("couldn't kmalloc se401 struct"); | 1401 | err("couldn't kmalloc se401 struct"); |
1383 | return -ENOMEM; | 1402 | return -ENOMEM; |
1384 | } | 1403 | } |
@@ -1396,12 +1415,14 @@ static int se401_probe(struct usb_interface *intf, | |||
1396 | } | 1415 | } |
1397 | 1416 | ||
1398 | memcpy(&se401->vdev, &se401_template, sizeof(se401_template)); | 1417 | memcpy(&se401->vdev, &se401_template, sizeof(se401_template)); |
1399 | memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name)); | 1418 | memcpy(se401->vdev.name, se401->camera_name, |
1419 | strlen(se401->camera_name)); | ||
1400 | init_waitqueue_head(&se401->wq); | 1420 | init_waitqueue_head(&se401->wq); |
1401 | mutex_init(&se401->lock); | 1421 | mutex_init(&se401->lock); |
1402 | wmb(); | 1422 | wmb(); |
1403 | 1423 | ||
1404 | if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { | 1424 | if (video_register_device(&se401->vdev, |
1425 | VFL_TYPE_GRABBER, video_nr) < 0) { | ||
1405 | kfree(se401); | 1426 | kfree(se401); |
1406 | err("video_register_device failed"); | 1427 | err("video_register_device failed"); |
1407 | return -EIO; | 1428 | return -EIO; |
@@ -1409,20 +1430,20 @@ static int se401_probe(struct usb_interface *intf, | |||
1409 | dev_info(&intf->dev, "registered new video device: video%d\n", | 1430 | dev_info(&intf->dev, "registered new video device: video%d\n", |
1410 | se401->vdev.num); | 1431 | se401->vdev.num); |
1411 | 1432 | ||
1412 | usb_set_intfdata (intf, se401); | 1433 | usb_set_intfdata(intf, se401); |
1413 | return 0; | 1434 | return 0; |
1414 | } | 1435 | } |
1415 | 1436 | ||
1416 | static void se401_disconnect(struct usb_interface *intf) | 1437 | static void se401_disconnect(struct usb_interface *intf) |
1417 | { | 1438 | { |
1418 | struct usb_se401 *se401 = usb_get_intfdata (intf); | 1439 | struct usb_se401 *se401 = usb_get_intfdata(intf); |
1419 | 1440 | ||
1420 | usb_set_intfdata (intf, NULL); | 1441 | usb_set_intfdata(intf, NULL); |
1421 | if (se401) { | 1442 | if (se401) { |
1422 | video_unregister_device(&se401->vdev); | 1443 | video_unregister_device(&se401->vdev); |
1423 | if (!se401->user){ | 1444 | if (!se401->user) |
1424 | usb_se401_remove_disconnected(se401); | 1445 | usb_se401_remove_disconnected(se401); |
1425 | } else { | 1446 | else { |
1426 | se401->frame[0].grabstate = FRAME_ERROR; | 1447 | se401->frame[0].grabstate = FRAME_ERROR; |
1427 | se401->frame[0].grabstate = FRAME_ERROR; | 1448 | se401->frame[0].grabstate = FRAME_ERROR; |
1428 | 1449 | ||
@@ -1435,10 +1456,10 @@ static void se401_disconnect(struct usb_interface *intf) | |||
1435 | } | 1456 | } |
1436 | 1457 | ||
1437 | static struct usb_driver se401_driver = { | 1458 | static struct usb_driver se401_driver = { |
1438 | .name = "se401", | 1459 | .name = "se401", |
1439 | .id_table = device_table, | 1460 | .id_table = device_table, |
1440 | .probe = se401_probe, | 1461 | .probe = se401_probe, |
1441 | .disconnect = se401_disconnect, | 1462 | .disconnect = se401_disconnect, |
1442 | }; | 1463 | }; |
1443 | 1464 | ||
1444 | 1465 | ||
@@ -1451,9 +1472,10 @@ static struct usb_driver se401_driver = { | |||
1451 | 1472 | ||
1452 | static int __init usb_se401_init(void) | 1473 | static int __init usb_se401_init(void) |
1453 | { | 1474 | { |
1454 | printk(KERN_INFO "SE401 usb camera driver version %s registering\n", version); | 1475 | printk(KERN_INFO "SE401 usb camera driver version %s registering\n", |
1476 | version); | ||
1455 | if (flickerless) | 1477 | if (flickerless) |
1456 | if (flickerless!=50 && flickerless!=60) { | 1478 | if (flickerless != 50 && flickerless != 60) { |
1457 | printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n"); | 1479 | printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n"); |
1458 | return -1; | 1480 | return -1; |
1459 | } | 1481 | } |
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h index 2ce685db5d8b..bf7d2e9765b0 100644 --- a/drivers/media/video/se401.h +++ b/drivers/media/video/se401.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #ifndef __LINUX_se401_H | 2 | #ifndef __LINUX_se401_H |
3 | #define __LINUX_se401_H | 3 | #define __LINUX_se401_H |
4 | 4 | ||
5 | #include <asm/uaccess.h> | 5 | #include <linux/uaccess.h> |
6 | #include <linux/videodev.h> | 6 | #include <linux/videodev.h> |
7 | #include <media/v4l2-common.h> | 7 | #include <media/v4l2-common.h> |
8 | #include <media/v4l2-ioctl.h> | 8 | #include <media/v4l2-ioctl.h> |
@@ -12,9 +12,10 @@ | |||
12 | 12 | ||
13 | #ifdef se401_DEBUG | 13 | #ifdef se401_DEBUG |
14 | # define PDEBUG(level, fmt, args...) \ | 14 | # define PDEBUG(level, fmt, args...) \ |
15 | if (debug >= level) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args) | 15 | if (debug >= level) \ |
16 | info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args) | ||
16 | #else | 17 | #else |
17 | # define PDEBUG(level, fmt, args...) do {} while(0) | 18 | # define PDEBUG(level, fmt, args...) do {} while (0) |
18 | #endif | 19 | #endif |
19 | 20 | ||
20 | /* An almost drop-in replacement for sleep_on_interruptible */ | 21 | /* An almost drop-in replacement for sleep_on_interruptible */ |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index b5e37a530c62..d369e8409ab8 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -81,7 +81,6 @@ struct sh_mobile_ceu_buffer { | |||
81 | }; | 81 | }; |
82 | 82 | ||
83 | struct sh_mobile_ceu_dev { | 83 | struct sh_mobile_ceu_dev { |
84 | struct device *dev; | ||
85 | struct soc_camera_host ici; | 84 | struct soc_camera_host ici; |
86 | struct soc_camera_device *icd; | 85 | struct soc_camera_device *icd; |
87 | 86 | ||
@@ -617,7 +616,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, | |||
617 | xlate->cam_fmt = icd->formats + idx; | 616 | xlate->cam_fmt = icd->formats + idx; |
618 | xlate->buswidth = icd->formats[idx].depth; | 617 | xlate->buswidth = icd->formats[idx].depth; |
619 | xlate++; | 618 | xlate++; |
620 | dev_dbg(&ici->dev, "Providing format %s using %s\n", | 619 | dev_dbg(ici->dev, "Providing format %s using %s\n", |
621 | sh_mobile_ceu_formats[k].name, | 620 | sh_mobile_ceu_formats[k].name, |
622 | icd->formats[idx].name); | 621 | icd->formats[idx].name); |
623 | } | 622 | } |
@@ -630,7 +629,7 @@ add_single_format: | |||
630 | xlate->cam_fmt = icd->formats + idx; | 629 | xlate->cam_fmt = icd->formats + idx; |
631 | xlate->buswidth = icd->formats[idx].depth; | 630 | xlate->buswidth = icd->formats[idx].depth; |
632 | xlate++; | 631 | xlate++; |
633 | dev_dbg(&ici->dev, | 632 | dev_dbg(ici->dev, |
634 | "Providing format %s in pass-through mode\n", | 633 | "Providing format %s in pass-through mode\n", |
635 | icd->formats[idx].name); | 634 | icd->formats[idx].name); |
636 | } | 635 | } |
@@ -657,7 +656,7 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, | |||
657 | 656 | ||
658 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 657 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
659 | if (!xlate) { | 658 | if (!xlate) { |
660 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 659 | dev_warn(ici->dev, "Format %x not found\n", pixfmt); |
661 | return -EINVAL; | 660 | return -EINVAL; |
662 | } | 661 | } |
663 | 662 | ||
@@ -684,7 +683,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, | |||
684 | 683 | ||
685 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 684 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
686 | if (!xlate) { | 685 | if (!xlate) { |
687 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 686 | dev_warn(ici->dev, "Format %x not found\n", pixfmt); |
688 | return -EINVAL; | 687 | return -EINVAL; |
689 | } | 688 | } |
690 | 689 | ||
@@ -782,7 +781,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q, | |||
782 | 781 | ||
783 | videobuf_queue_dma_contig_init(q, | 782 | videobuf_queue_dma_contig_init(q, |
784 | &sh_mobile_ceu_videobuf_ops, | 783 | &sh_mobile_ceu_videobuf_ops, |
785 | &ici->dev, &pcdev->lock, | 784 | ici->dev, &pcdev->lock, |
786 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 785 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
787 | pcdev->is_interlaced ? | 786 | pcdev->is_interlaced ? |
788 | V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE, | 787 | V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE, |
@@ -829,7 +828,6 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
829 | goto exit; | 828 | goto exit; |
830 | } | 829 | } |
831 | 830 | ||
832 | platform_set_drvdata(pdev, pcdev); | ||
833 | INIT_LIST_HEAD(&pcdev->capture); | 831 | INIT_LIST_HEAD(&pcdev->capture); |
834 | spin_lock_init(&pcdev->lock); | 832 | spin_lock_init(&pcdev->lock); |
835 | 833 | ||
@@ -840,7 +838,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
840 | goto exit_kfree; | 838 | goto exit_kfree; |
841 | } | 839 | } |
842 | 840 | ||
843 | base = ioremap_nocache(res->start, res->end - res->start + 1); | 841 | base = ioremap_nocache(res->start, resource_size(res)); |
844 | if (!base) { | 842 | if (!base) { |
845 | err = -ENXIO; | 843 | err = -ENXIO; |
846 | dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n"); | 844 | dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n"); |
@@ -850,13 +848,12 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
850 | pcdev->irq = irq; | 848 | pcdev->irq = irq; |
851 | pcdev->base = base; | 849 | pcdev->base = base; |
852 | pcdev->video_limit = 0; /* only enabled if second resource exists */ | 850 | pcdev->video_limit = 0; /* only enabled if second resource exists */ |
853 | pcdev->dev = &pdev->dev; | ||
854 | 851 | ||
855 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 852 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
856 | if (res) { | 853 | if (res) { |
857 | err = dma_declare_coherent_memory(&pdev->dev, res->start, | 854 | err = dma_declare_coherent_memory(&pdev->dev, res->start, |
858 | res->start, | 855 | res->start, |
859 | (res->end - res->start) + 1, | 856 | resource_size(res), |
860 | DMA_MEMORY_MAP | | 857 | DMA_MEMORY_MAP | |
861 | DMA_MEMORY_EXCLUSIVE); | 858 | DMA_MEMORY_EXCLUSIVE); |
862 | if (!err) { | 859 | if (!err) { |
@@ -865,7 +862,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
865 | goto exit_iounmap; | 862 | goto exit_iounmap; |
866 | } | 863 | } |
867 | 864 | ||
868 | pcdev->video_limit = (res->end - res->start) + 1; | 865 | pcdev->video_limit = resource_size(res); |
869 | } | 866 | } |
870 | 867 | ||
871 | /* request irq */ | 868 | /* request irq */ |
@@ -885,7 +882,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
885 | } | 882 | } |
886 | 883 | ||
887 | pcdev->ici.priv = pcdev; | 884 | pcdev->ici.priv = pcdev; |
888 | pcdev->ici.dev.parent = &pdev->dev; | 885 | pcdev->ici.dev = &pdev->dev; |
889 | pcdev->ici.nr = pdev->id; | 886 | pcdev->ici.nr = pdev->id; |
890 | pcdev->ici.drv_name = dev_name(&pdev->dev); | 887 | pcdev->ici.drv_name = dev_name(&pdev->dev); |
891 | pcdev->ici.ops = &sh_mobile_ceu_host_ops; | 888 | pcdev->ici.ops = &sh_mobile_ceu_host_ops; |
@@ -913,9 +910,11 @@ exit: | |||
913 | 910 | ||
914 | static int sh_mobile_ceu_remove(struct platform_device *pdev) | 911 | static int sh_mobile_ceu_remove(struct platform_device *pdev) |
915 | { | 912 | { |
916 | struct sh_mobile_ceu_dev *pcdev = platform_get_drvdata(pdev); | 913 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); |
914 | struct sh_mobile_ceu_dev *pcdev = container_of(soc_host, | ||
915 | struct sh_mobile_ceu_dev, ici); | ||
917 | 916 | ||
918 | soc_camera_host_unregister(&pcdev->ici); | 917 | soc_camera_host_unregister(soc_host); |
919 | clk_put(pcdev->clk); | 918 | clk_put(pcdev->clk); |
920 | free_irq(pcdev->irq, pcdev); | 919 | free_irq(pcdev->irq, pcdev); |
921 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) | 920 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 0e890cc23377..16f595d4337a 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -16,19 +16,21 @@ | |||
16 | * published by the Free Software Foundation. | 16 | * published by the Free Software Foundation. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/device.h> | 19 | #include <linux/device.h> |
22 | #include <linux/list.h> | ||
23 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/i2c.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/module.h> | ||
24 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/platform_device.h> | ||
25 | #include <linux/vmalloc.h> | 27 | #include <linux/vmalloc.h> |
26 | 28 | ||
29 | #include <media/soc_camera.h> | ||
27 | #include <media/v4l2-common.h> | 30 | #include <media/v4l2-common.h> |
28 | #include <media/v4l2-ioctl.h> | ||
29 | #include <media/v4l2-dev.h> | 31 | #include <media/v4l2-dev.h> |
32 | #include <media/v4l2-ioctl.h> | ||
30 | #include <media/videobuf-core.h> | 33 | #include <media/videobuf-core.h> |
31 | #include <media/soc_camera.h> | ||
32 | 34 | ||
33 | /* Default to VGA resolution */ | 35 | /* Default to VGA resolution */ |
34 | #define DEFAULT_WIDTH 640 | 36 | #define DEFAULT_WIDTH 640 |
@@ -279,7 +281,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf, | |||
279 | return ret; | 281 | return ret; |
280 | } else if (!icd->current_fmt || | 282 | } else if (!icd->current_fmt || |
281 | icd->current_fmt->fourcc != pix->pixelformat) { | 283 | icd->current_fmt->fourcc != pix->pixelformat) { |
282 | dev_err(&ici->dev, | 284 | dev_err(ici->dev, |
283 | "Host driver hasn't set up current format correctly!\n"); | 285 | "Host driver hasn't set up current format correctly!\n"); |
284 | return -EINVAL; | 286 | return -EINVAL; |
285 | } | 287 | } |
@@ -794,7 +796,7 @@ static void scan_add_host(struct soc_camera_host *ici) | |||
794 | 796 | ||
795 | list_for_each_entry(icd, &devices, list) { | 797 | list_for_each_entry(icd, &devices, list) { |
796 | if (icd->iface == ici->nr) { | 798 | if (icd->iface == ici->nr) { |
797 | icd->dev.parent = &ici->dev; | 799 | icd->dev.parent = ici->dev; |
798 | device_register_link(icd); | 800 | device_register_link(icd); |
799 | } | 801 | } |
800 | } | 802 | } |
@@ -818,7 +820,7 @@ static int scan_add_device(struct soc_camera_device *icd) | |||
818 | list_for_each_entry(ici, &hosts, list) { | 820 | list_for_each_entry(ici, &hosts, list) { |
819 | if (icd->iface == ici->nr) { | 821 | if (icd->iface == ici->nr) { |
820 | ret = 1; | 822 | ret = 1; |
821 | icd->dev.parent = &ici->dev; | 823 | icd->dev.parent = ici->dev; |
822 | break; | 824 | break; |
823 | } | 825 | } |
824 | } | 826 | } |
@@ -952,7 +954,6 @@ static void dummy_release(struct device *dev) | |||
952 | 954 | ||
953 | int soc_camera_host_register(struct soc_camera_host *ici) | 955 | int soc_camera_host_register(struct soc_camera_host *ici) |
954 | { | 956 | { |
955 | int ret; | ||
956 | struct soc_camera_host *ix; | 957 | struct soc_camera_host *ix; |
957 | 958 | ||
958 | if (!ici || !ici->ops || | 959 | if (!ici || !ici->ops || |
@@ -965,12 +966,10 @@ int soc_camera_host_register(struct soc_camera_host *ici) | |||
965 | !ici->ops->reqbufs || | 966 | !ici->ops->reqbufs || |
966 | !ici->ops->add || | 967 | !ici->ops->add || |
967 | !ici->ops->remove || | 968 | !ici->ops->remove || |
968 | !ici->ops->poll) | 969 | !ici->ops->poll || |
970 | !ici->dev) | ||
969 | return -EINVAL; | 971 | return -EINVAL; |
970 | 972 | ||
971 | /* Number might be equal to the platform device ID */ | ||
972 | dev_set_name(&ici->dev, "camera_host%d", ici->nr); | ||
973 | |||
974 | mutex_lock(&list_lock); | 973 | mutex_lock(&list_lock); |
975 | list_for_each_entry(ix, &hosts, list) { | 974 | list_for_each_entry(ix, &hosts, list) { |
976 | if (ix->nr == ici->nr) { | 975 | if (ix->nr == ici->nr) { |
@@ -979,26 +978,14 @@ int soc_camera_host_register(struct soc_camera_host *ici) | |||
979 | } | 978 | } |
980 | } | 979 | } |
981 | 980 | ||
981 | dev_set_drvdata(ici->dev, ici); | ||
982 | |||
982 | list_add_tail(&ici->list, &hosts); | 983 | list_add_tail(&ici->list, &hosts); |
983 | mutex_unlock(&list_lock); | 984 | mutex_unlock(&list_lock); |
984 | 985 | ||
985 | ici->dev.release = dummy_release; | ||
986 | |||
987 | ret = device_register(&ici->dev); | ||
988 | |||
989 | if (ret) | ||
990 | goto edevr; | ||
991 | |||
992 | scan_add_host(ici); | 986 | scan_add_host(ici); |
993 | 987 | ||
994 | return 0; | 988 | return 0; |
995 | |||
996 | edevr: | ||
997 | mutex_lock(&list_lock); | ||
998 | list_del(&ici->list); | ||
999 | mutex_unlock(&list_lock); | ||
1000 | |||
1001 | return ret; | ||
1002 | } | 989 | } |
1003 | EXPORT_SYMBOL(soc_camera_host_register); | 990 | EXPORT_SYMBOL(soc_camera_host_register); |
1004 | 991 | ||
@@ -1012,7 +999,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) | |||
1012 | list_del(&ici->list); | 999 | list_del(&ici->list); |
1013 | 1000 | ||
1014 | list_for_each_entry(icd, &devices, list) { | 1001 | list_for_each_entry(icd, &devices, list) { |
1015 | if (icd->dev.parent == &ici->dev) { | 1002 | if (icd->dev.parent == ici->dev) { |
1016 | device_unregister(&icd->dev); | 1003 | device_unregister(&icd->dev); |
1017 | /* Not before device_unregister(), .remove | 1004 | /* Not before device_unregister(), .remove |
1018 | * needs parent to call ici->ops->remove() */ | 1005 | * needs parent to call ici->ops->remove() */ |
@@ -1023,7 +1010,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) | |||
1023 | 1010 | ||
1024 | mutex_unlock(&list_lock); | 1011 | mutex_unlock(&list_lock); |
1025 | 1012 | ||
1026 | device_unregister(&ici->dev); | 1013 | dev_set_drvdata(ici->dev, NULL); |
1027 | } | 1014 | } |
1028 | EXPORT_SYMBOL(soc_camera_host_unregister); | 1015 | EXPORT_SYMBOL(soc_camera_host_unregister); |
1029 | 1016 | ||
@@ -1130,7 +1117,7 @@ int soc_camera_video_start(struct soc_camera_device *icd) | |||
1130 | vdev = video_device_alloc(); | 1117 | vdev = video_device_alloc(); |
1131 | if (!vdev) | 1118 | if (!vdev) |
1132 | goto evidallocd; | 1119 | goto evidallocd; |
1133 | dev_dbg(&ici->dev, "Allocated video_device %p\n", vdev); | 1120 | dev_dbg(ici->dev, "Allocated video_device %p\n", vdev); |
1134 | 1121 | ||
1135 | strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); | 1122 | strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); |
1136 | 1123 | ||
@@ -1174,6 +1161,57 @@ void soc_camera_video_stop(struct soc_camera_device *icd) | |||
1174 | } | 1161 | } |
1175 | EXPORT_SYMBOL(soc_camera_video_stop); | 1162 | EXPORT_SYMBOL(soc_camera_video_stop); |
1176 | 1163 | ||
1164 | static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) | ||
1165 | { | ||
1166 | struct soc_camera_link *icl = pdev->dev.platform_data; | ||
1167 | struct i2c_adapter *adap; | ||
1168 | struct i2c_client *client; | ||
1169 | |||
1170 | if (!icl) | ||
1171 | return -EINVAL; | ||
1172 | |||
1173 | adap = i2c_get_adapter(icl->i2c_adapter_id); | ||
1174 | if (!adap) { | ||
1175 | dev_warn(&pdev->dev, "Cannot get adapter #%d. No driver?\n", | ||
1176 | icl->i2c_adapter_id); | ||
1177 | /* -ENODEV and -ENXIO do not produce an error on probe()... */ | ||
1178 | return -ENOENT; | ||
1179 | } | ||
1180 | |||
1181 | icl->board_info->platform_data = icl; | ||
1182 | client = i2c_new_device(adap, icl->board_info); | ||
1183 | if (!client) { | ||
1184 | i2c_put_adapter(adap); | ||
1185 | return -ENOMEM; | ||
1186 | } | ||
1187 | |||
1188 | platform_set_drvdata(pdev, client); | ||
1189 | |||
1190 | return 0; | ||
1191 | } | ||
1192 | |||
1193 | static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) | ||
1194 | { | ||
1195 | struct i2c_client *client = platform_get_drvdata(pdev); | ||
1196 | |||
1197 | if (!client) | ||
1198 | return -ENODEV; | ||
1199 | |||
1200 | i2c_unregister_device(client); | ||
1201 | i2c_put_adapter(client->adapter); | ||
1202 | |||
1203 | return 0; | ||
1204 | } | ||
1205 | |||
1206 | static struct platform_driver __refdata soc_camera_pdrv = { | ||
1207 | .probe = soc_camera_pdrv_probe, | ||
1208 | .remove = __devexit_p(soc_camera_pdrv_remove), | ||
1209 | .driver = { | ||
1210 | .name = "soc-camera-pdrv", | ||
1211 | .owner = THIS_MODULE, | ||
1212 | }, | ||
1213 | }; | ||
1214 | |||
1177 | static int __init soc_camera_init(void) | 1215 | static int __init soc_camera_init(void) |
1178 | { | 1216 | { |
1179 | int ret = bus_register(&soc_camera_bus_type); | 1217 | int ret = bus_register(&soc_camera_bus_type); |
@@ -1183,8 +1221,14 @@ static int __init soc_camera_init(void) | |||
1183 | if (ret) | 1221 | if (ret) |
1184 | goto edrvr; | 1222 | goto edrvr; |
1185 | 1223 | ||
1224 | ret = platform_driver_register(&soc_camera_pdrv); | ||
1225 | if (ret) | ||
1226 | goto epdr; | ||
1227 | |||
1186 | return 0; | 1228 | return 0; |
1187 | 1229 | ||
1230 | epdr: | ||
1231 | driver_unregister(&ic_drv); | ||
1188 | edrvr: | 1232 | edrvr: |
1189 | bus_unregister(&soc_camera_bus_type); | 1233 | bus_unregister(&soc_camera_bus_type); |
1190 | return ret; | 1234 | return ret; |
@@ -1192,6 +1236,7 @@ edrvr: | |||
1192 | 1236 | ||
1193 | static void __exit soc_camera_exit(void) | 1237 | static void __exit soc_camera_exit(void) |
1194 | { | 1238 | { |
1239 | platform_driver_unregister(&soc_camera_pdrv); | ||
1195 | driver_unregister(&ic_drv); | 1240 | driver_unregister(&ic_drv); |
1196 | bus_unregister(&soc_camera_bus_type); | 1241 | bus_unregister(&soc_camera_bus_type); |
1197 | } | 1242 | } |
@@ -1202,3 +1247,4 @@ module_exit(soc_camera_exit); | |||
1202 | MODULE_DESCRIPTION("Image capture bus driver"); | 1247 | MODULE_DESCRIPTION("Image capture bus driver"); |
1203 | MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); | 1248 | MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); |
1204 | MODULE_LICENSE("GPL"); | 1249 | MODULE_LICENSE("GPL"); |
1250 | MODULE_ALIAS("platform:soc-camera-pdrv"); | ||
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 1a6d39cbd6f3..2e5937047278 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c | |||
@@ -1137,7 +1137,7 @@ static int stk_vidioc_querybuf(struct file *filp, | |||
1137 | struct stk_camera *dev = priv; | 1137 | struct stk_camera *dev = priv; |
1138 | struct stk_sio_buffer *sbuf; | 1138 | struct stk_sio_buffer *sbuf; |
1139 | 1139 | ||
1140 | if (buf->index < 0 || buf->index >= dev->n_sbufs) | 1140 | if (buf->index >= dev->n_sbufs) |
1141 | return -EINVAL; | 1141 | return -EINVAL; |
1142 | sbuf = dev->sio_bufs + buf->index; | 1142 | sbuf = dev->sio_bufs + buf->index; |
1143 | *buf = sbuf->v4lbuf; | 1143 | *buf = sbuf->v4lbuf; |
@@ -1154,7 +1154,7 @@ static int stk_vidioc_qbuf(struct file *filp, | |||
1154 | if (buf->memory != V4L2_MEMORY_MMAP) | 1154 | if (buf->memory != V4L2_MEMORY_MMAP) |
1155 | return -EINVAL; | 1155 | return -EINVAL; |
1156 | 1156 | ||
1157 | if (buf->index < 0 || buf->index >= dev->n_sbufs) | 1157 | if (buf->index >= dev->n_sbufs) |
1158 | return -EINVAL; | 1158 | return -EINVAL; |
1159 | sbuf = dev->sio_bufs + buf->index; | 1159 | sbuf = dev->sio_bufs + buf->index; |
1160 | if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED) | 1160 | if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED) |
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 005f8a468031..80f1cee23fa5 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c | |||
@@ -20,20 +20,6 @@ | |||
20 | * loudness - set between 0 and 15 for varying degrees of loudness effect | 20 | * loudness - set between 0 and 15 for varying degrees of loudness effect |
21 | * | 21 | * |
22 | * maxvol - set maximium volume to +20db (1), default is 0db(0) | 22 | * maxvol - set maximium volume to +20db (1), default is 0db(0) |
23 | * | ||
24 | * | ||
25 | * Revision: 0.7 - maxvol module parm to set maximium volume 0db or +20db | ||
26 | * store if muted so we can return it | ||
27 | * change balance only if flaged to | ||
28 | * Revision: 0.6 - added tone controls | ||
29 | * Revision: 0.5 - Fixed odd balance problem | ||
30 | * Revision: 0.4 - added muting | ||
31 | * Revision: 0.3 - Fixed silly reversed volume controls. :) | ||
32 | * Revision: 0.2 - Cleaned up #defines | ||
33 | * fixed volume control | ||
34 | * Added I2C_DRIVERID_TDA7432 | ||
35 | * added loudness insmod control | ||
36 | * Revision: 0.1 - initial version | ||
37 | */ | 23 | */ |
38 | 24 | ||
39 | #include <linux/module.h> | 25 | #include <linux/module.h> |
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index d4a9ed45764b..1585839bd0bd 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c | |||
@@ -141,7 +141,6 @@ static const struct v4l2_subdev_ops tea6415c_ops = { | |||
141 | .video = &tea6415c_video_ops, | 141 | .video = &tea6415c_video_ops, |
142 | }; | 142 | }; |
143 | 143 | ||
144 | /* this function is called by i2c_probe */ | ||
145 | static int tea6415c_probe(struct i2c_client *client, | 144 | static int tea6415c_probe(struct i2c_client *client, |
146 | const struct i2c_device_id *id) | 145 | const struct i2c_device_id *id) |
147 | { | 146 | { |
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index ced6eadf347a..0446524d3543 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c | |||
@@ -112,7 +112,6 @@ static const struct v4l2_subdev_ops tea6420_ops = { | |||
112 | .audio = &tea6420_audio_ops, | 112 | .audio = &tea6420_audio_ops, |
113 | }; | 113 | }; |
114 | 114 | ||
115 | /* this function is called by i2c_probe */ | ||
116 | static int tea6420_probe(struct i2c_client *client, | 115 | static int tea6420_probe(struct i2c_client *client, |
117 | const struct i2c_device_id *id) | 116 | const struct i2c_device_id *id) |
118 | { | 117 | { |
diff --git a/drivers/media/video/ths7303.c b/drivers/media/video/ths7303.c new file mode 100644 index 000000000000..21781f8a0e8e --- /dev/null +++ b/drivers/media/video/ths7303.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * ths7303- THS7303 Video Amplifier driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed .as is. WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/ctype.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/uaccess.h> | ||
24 | #include <linux/videodev2.h> | ||
25 | |||
26 | #include <media/v4l2-device.h> | ||
27 | #include <media/v4l2-subdev.h> | ||
28 | #include <media/v4l2-chip-ident.h> | ||
29 | |||
30 | MODULE_DESCRIPTION("TI THS7303 video amplifier driver"); | ||
31 | MODULE_AUTHOR("Chaithrika U S"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | static int debug; | ||
35 | module_param(debug, int, 0644); | ||
36 | MODULE_PARM_DESC(debug, "Debug level 0-1"); | ||
37 | |||
38 | /* following function is used to set ths7303 */ | ||
39 | static int ths7303_setvalue(struct v4l2_subdev *sd, v4l2_std_id std) | ||
40 | { | ||
41 | int err = 0; | ||
42 | u8 val; | ||
43 | struct i2c_client *client; | ||
44 | |||
45 | client = v4l2_get_subdevdata(sd); | ||
46 | |||
47 | if (std & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) { | ||
48 | val = 0x02; | ||
49 | v4l2_dbg(1, debug, sd, "setting value for SDTV format\n"); | ||
50 | } else { | ||
51 | val = 0x00; | ||
52 | v4l2_dbg(1, debug, sd, "disabling all channels\n"); | ||
53 | } | ||
54 | |||
55 | err |= i2c_smbus_write_byte_data(client, 0x01, val); | ||
56 | err |= i2c_smbus_write_byte_data(client, 0x02, val); | ||
57 | err |= i2c_smbus_write_byte_data(client, 0x03, val); | ||
58 | |||
59 | if (err) | ||
60 | v4l2_err(sd, "write failed\n"); | ||
61 | |||
62 | return err; | ||
63 | } | ||
64 | |||
65 | static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) | ||
66 | { | ||
67 | return ths7303_setvalue(sd, norm); | ||
68 | } | ||
69 | |||
70 | static int ths7303_g_chip_ident(struct v4l2_subdev *sd, | ||
71 | struct v4l2_dbg_chip_ident *chip) | ||
72 | { | ||
73 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
74 | |||
75 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_THS7303, 0); | ||
76 | } | ||
77 | |||
78 | static const struct v4l2_subdev_video_ops ths7303_video_ops = { | ||
79 | .s_std_output = ths7303_s_std_output, | ||
80 | }; | ||
81 | |||
82 | static const struct v4l2_subdev_core_ops ths7303_core_ops = { | ||
83 | .g_chip_ident = ths7303_g_chip_ident, | ||
84 | }; | ||
85 | |||
86 | static const struct v4l2_subdev_ops ths7303_ops = { | ||
87 | .core = &ths7303_core_ops, | ||
88 | .video = &ths7303_video_ops, | ||
89 | }; | ||
90 | |||
91 | static int ths7303_probe(struct i2c_client *client, | ||
92 | const struct i2c_device_id *id) | ||
93 | { | ||
94 | struct v4l2_subdev *sd; | ||
95 | v4l2_std_id std_id = V4L2_STD_NTSC; | ||
96 | |||
97 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
98 | return -ENODEV; | ||
99 | |||
100 | v4l_info(client, "chip found @ 0x%x (%s)\n", | ||
101 | client->addr << 1, client->adapter->name); | ||
102 | |||
103 | sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); | ||
104 | if (sd == NULL) | ||
105 | return -ENOMEM; | ||
106 | |||
107 | v4l2_i2c_subdev_init(sd, client, &ths7303_ops); | ||
108 | |||
109 | return ths7303_setvalue(sd, std_id); | ||
110 | } | ||
111 | |||
112 | static int ths7303_remove(struct i2c_client *client) | ||
113 | { | ||
114 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
115 | |||
116 | v4l2_device_unregister_subdev(sd); | ||
117 | kfree(sd); | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static const struct i2c_device_id ths7303_id[] = { | ||
123 | {"ths7303", 0}, | ||
124 | {}, | ||
125 | }; | ||
126 | |||
127 | MODULE_DEVICE_TABLE(i2c, ths7303_id); | ||
128 | |||
129 | static struct i2c_driver ths7303_driver = { | ||
130 | .driver = { | ||
131 | .owner = THIS_MODULE, | ||
132 | .name = "ths7303", | ||
133 | }, | ||
134 | .probe = ths7303_probe, | ||
135 | .remove = ths7303_remove, | ||
136 | .id_table = ths7303_id, | ||
137 | }; | ||
138 | |||
139 | static int __init ths7303_init(void) | ||
140 | { | ||
141 | return i2c_add_driver(&ths7303_driver); | ||
142 | } | ||
143 | |||
144 | static void __exit ths7303_exit(void) | ||
145 | { | ||
146 | i2c_del_driver(&ths7303_driver); | ||
147 | } | ||
148 | |||
149 | module_init(ths7303_init); | ||
150 | module_exit(ths7303_exit); | ||
151 | |||
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 78c377a399cb..537594211a90 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -309,32 +309,6 @@ static void set_freq(struct i2c_client *c, unsigned long freq) | |||
309 | } | 309 | } |
310 | } | 310 | } |
311 | 311 | ||
312 | static void tuner_i2c_address_check(struct tuner *t) | ||
313 | { | ||
314 | if ((t->type == UNSET || t->type == TUNER_ABSENT) || | ||
315 | ((t->i2c->addr < 0x64) || (t->i2c->addr > 0x6f))) | ||
316 | return; | ||
317 | |||
318 | /* We already know that the XC5000 can only be located at | ||
319 | * i2c address 0x61, 0x62, 0x63 or 0x64 */ | ||
320 | if ((t->type == TUNER_XC5000) && | ||
321 | ((t->i2c->addr <= 0x64)) && (t->i2c->addr >= 0x61)) | ||
322 | return; | ||
323 | |||
324 | tuner_warn("====================== WARNING! ======================\n"); | ||
325 | tuner_warn("Support for tuners in i2c address range 0x64 thru 0x6f\n"); | ||
326 | tuner_warn("will soon be dropped. This message indicates that your\n"); | ||
327 | tuner_warn("hardware has a %s tuner at i2c address 0x%02x.\n", | ||
328 | t->name, t->i2c->addr); | ||
329 | tuner_warn("To ensure continued support for your device, please\n"); | ||
330 | tuner_warn("send a copy of this message, along with full dmesg\n"); | ||
331 | tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n"); | ||
332 | tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n"); | ||
333 | tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n", | ||
334 | t->i2c->adapter->name, t->i2c->addr, t->type, t->name); | ||
335 | tuner_warn("====================== WARNING! ======================\n"); | ||
336 | } | ||
337 | |||
338 | static struct xc5000_config xc5000_cfg; | 312 | static struct xc5000_config xc5000_cfg; |
339 | 313 | ||
340 | static void set_type(struct i2c_client *c, unsigned int type, | 314 | static void set_type(struct i2c_client *c, unsigned int type, |
@@ -438,18 +412,12 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
438 | break; | 412 | break; |
439 | case TUNER_XC5000: | 413 | case TUNER_XC5000: |
440 | { | 414 | { |
441 | struct dvb_tuner_ops *xc_tuner_ops; | ||
442 | |||
443 | xc5000_cfg.i2c_address = t->i2c->addr; | 415 | xc5000_cfg.i2c_address = t->i2c->addr; |
444 | /* if_khz will be set when the digital dvb_attach() occurs */ | 416 | /* if_khz will be set when the digital dvb_attach() occurs */ |
445 | xc5000_cfg.if_khz = 0; | 417 | xc5000_cfg.if_khz = 0; |
446 | if (!dvb_attach(xc5000_attach, | 418 | if (!dvb_attach(xc5000_attach, |
447 | &t->fe, t->i2c->adapter, &xc5000_cfg)) | 419 | &t->fe, t->i2c->adapter, &xc5000_cfg)) |
448 | goto attach_failed; | 420 | goto attach_failed; |
449 | |||
450 | xc_tuner_ops = &t->fe.ops.tuner_ops; | ||
451 | if (xc_tuner_ops->init) | ||
452 | xc_tuner_ops->init(&t->fe); | ||
453 | break; | 421 | break; |
454 | } | 422 | } |
455 | default: | 423 | default: |
@@ -490,7 +458,6 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
490 | tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", | 458 | tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", |
491 | c->adapter->name, c->driver->driver.name, c->addr << 1, type, | 459 | c->adapter->name, c->driver->driver.name, c->addr << 1, type, |
492 | t->mode_mask); | 460 | t->mode_mask); |
493 | tuner_i2c_address_check(t); | ||
494 | return; | 461 | return; |
495 | 462 | ||
496 | attach_failed: | 463 | attach_failed: |
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index e24a38c7fa46..ac02808106c1 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -184,7 +184,7 @@ hauppauge_tuner[] = | |||
184 | { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"}, | 184 | { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"}, |
185 | { TUNER_ABSENT, "Thompson DTT757"}, | 185 | { TUNER_ABSENT, "Thompson DTT757"}, |
186 | /* 80-89 */ | 186 | /* 80-89 */ |
187 | { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216LME MK3"}, | 187 | { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK3"}, |
188 | { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"}, | 188 | { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"}, |
189 | { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, | 189 | { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, |
190 | { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, | 190 | { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, |
@@ -210,7 +210,7 @@ hauppauge_tuner[] = | |||
210 | { TUNER_TEA5767, "Philips TEA5768HL FM Radio"}, | 210 | { TUNER_TEA5767, "Philips TEA5768HL FM Radio"}, |
211 | { TUNER_ABSENT, "Panasonic ENV57H12D5"}, | 211 | { TUNER_ABSENT, "Panasonic ENV57H12D5"}, |
212 | { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"}, | 212 | { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"}, |
213 | { TUNER_ABSENT, "TCL MNM05-4"}, | 213 | { TUNER_PHILIPS_FM1236_MK3, "TCL MNM05-4"}, |
214 | { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"}, | 214 | { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"}, |
215 | { TUNER_ABSENT, "TCL MQNM05-4"}, | 215 | { TUNER_ABSENT, "TCL MQNM05-4"}, |
216 | { TUNER_ABSENT, "LG TAPC-W701D"}, | 216 | { TUNER_ABSENT, "LG TAPC-W701D"}, |
@@ -229,7 +229,7 @@ hauppauge_tuner[] = | |||
229 | { TUNER_ABSENT, "Samsung THPD5222FG30A"}, | 229 | { TUNER_ABSENT, "Samsung THPD5222FG30A"}, |
230 | /* 120-129 */ | 230 | /* 120-129 */ |
231 | { TUNER_XC2028, "Xceive XC3028"}, | 231 | { TUNER_XC2028, "Xceive XC3028"}, |
232 | { TUNER_ABSENT, "Philips FQ1216LME MK5"}, | 232 | { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK5"}, |
233 | { TUNER_ABSENT, "Philips FQD1216LME"}, | 233 | { TUNER_ABSENT, "Philips FQD1216LME"}, |
234 | { TUNER_ABSENT, "Conexant CX24118A"}, | 234 | { TUNER_ABSENT, "Conexant CX24118A"}, |
235 | { TUNER_ABSENT, "TCL DMF11WIP"}, | 235 | { TUNER_ABSENT, "TCL DMF11WIP"}, |
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index 4262e60b8116..3750f7fadb12 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c | |||
@@ -692,7 +692,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s, | |||
692 | break; /* Input detected */ | 692 | break; /* Input detected */ |
693 | } | 693 | } |
694 | 694 | ||
695 | if ((current_std == STD_INVALID) || (try_count <= 0)) | 695 | if ((current_std == STD_INVALID) || (try_count < 0)) |
696 | return -EINVAL; | 696 | return -EINVAL; |
697 | 697 | ||
698 | decoder->current_std = current_std; | 698 | decoder->current_std = current_std; |
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c index 900ec2129ca1..31d57f2d09e1 100644 --- a/drivers/media/video/usbvideo/konicawc.c +++ b/drivers/media/video/usbvideo/konicawc.c | |||
@@ -240,7 +240,7 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev | |||
240 | input_dev->dev.parent = &dev->dev; | 240 | input_dev->dev.parent = &dev->dev; |
241 | 241 | ||
242 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | 242 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
243 | input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); | 243 | input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA); |
244 | 244 | ||
245 | error = input_register_device(cam->input); | 245 | error = input_register_device(cam->input); |
246 | if (error) { | 246 | if (error) { |
@@ -263,7 +263,7 @@ static void konicawc_unregister_input(struct konicawc *cam) | |||
263 | static void konicawc_report_buttonstat(struct konicawc *cam) | 263 | static void konicawc_report_buttonstat(struct konicawc *cam) |
264 | { | 264 | { |
265 | if (cam->input) { | 265 | if (cam->input) { |
266 | input_report_key(cam->input, BTN_0, cam->buttonsts); | 266 | input_report_key(cam->input, KEY_CAMERA, cam->buttonsts); |
267 | input_sync(cam->input); | 267 | input_sync(cam->input); |
268 | } | 268 | } |
269 | } | 269 | } |
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c index fd112f0b9d35..803d3e4e29a2 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/drivers/media/video/usbvideo/quickcam_messenger.c | |||
@@ -103,7 +103,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev) | |||
103 | input_dev->dev.parent = &dev->dev; | 103 | input_dev->dev.parent = &dev->dev; |
104 | 104 | ||
105 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | 105 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
106 | input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); | 106 | input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA); |
107 | 107 | ||
108 | error = input_register_device(cam->input); | 108 | error = input_register_device(cam->input); |
109 | if (error) { | 109 | if (error) { |
@@ -126,7 +126,7 @@ static void qcm_unregister_input(struct qcm *cam) | |||
126 | static void qcm_report_buttonstat(struct qcm *cam) | 126 | static void qcm_report_buttonstat(struct qcm *cam) |
127 | { | 127 | { |
128 | if (cam->input) { | 128 | if (cam->input) { |
129 | input_report_key(cam->input, BTN_0, cam->button_sts); | 129 | input_report_key(cam->input, KEY_CAMERA, cam->button_sts); |
130 | input_sync(cam->input); | 130 | input_sync(cam->input); |
131 | } | 131 | } |
132 | } | 132 | } |
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index 8bc03b9e1315..6ba16abeebdd 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c | |||
@@ -390,10 +390,9 @@ int usbvision_scratch_alloc(struct usb_usbvision *usbvision) | |||
390 | 390 | ||
391 | void usbvision_scratch_free(struct usb_usbvision *usbvision) | 391 | void usbvision_scratch_free(struct usb_usbvision *usbvision) |
392 | { | 392 | { |
393 | if (usbvision->scratch != NULL) { | 393 | vfree(usbvision->scratch); |
394 | vfree(usbvision->scratch); | 394 | usbvision->scratch = NULL; |
395 | usbvision->scratch = NULL; | 395 | |
396 | } | ||
397 | } | 396 | } |
398 | 397 | ||
399 | /* | 398 | /* |
@@ -506,10 +505,9 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision) | |||
506 | */ | 505 | */ |
507 | void usbvision_decompress_free(struct usb_usbvision *usbvision) | 506 | void usbvision_decompress_free(struct usb_usbvision *usbvision) |
508 | { | 507 | { |
509 | if (usbvision->IntraFrameBuffer != NULL) { | 508 | vfree(usbvision->IntraFrameBuffer); |
510 | vfree(usbvision->IntraFrameBuffer); | 509 | usbvision->IntraFrameBuffer = NULL; |
511 | usbvision->IntraFrameBuffer = NULL; | 510 | |
512 | } | ||
513 | } | 511 | } |
514 | 512 | ||
515 | /************************************************************ | 513 | /************************************************************ |
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index d7056a5b7f9b..90b58914f984 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -541,7 +541,7 @@ static int vidioc_enum_input (struct file *file, void *priv, | |||
541 | struct usb_usbvision *usbvision = video_drvdata(file); | 541 | struct usb_usbvision *usbvision = video_drvdata(file); |
542 | int chan; | 542 | int chan; |
543 | 543 | ||
544 | if ((vi->index >= usbvision->video_inputs) || (vi->index < 0) ) | 544 | if (vi->index >= usbvision->video_inputs) |
545 | return -EINVAL; | 545 | return -EINVAL; |
546 | if (usbvision->have_tuner) { | 546 | if (usbvision->have_tuner) { |
547 | chan = vi->index; | 547 | chan = vi->index; |
@@ -1794,7 +1794,7 @@ static struct usb_driver usbvision_driver = { | |||
1794 | .name = "usbvision", | 1794 | .name = "usbvision", |
1795 | .id_table = usbvision_table, | 1795 | .id_table = usbvision_table, |
1796 | .probe = usbvision_probe, | 1796 | .probe = usbvision_probe, |
1797 | .disconnect = usbvision_disconnect | 1797 | .disconnect = __devexit_p(usbvision_disconnect), |
1798 | }; | 1798 | }; |
1799 | 1799 | ||
1800 | /* | 1800 | /* |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 0d7e38d6ff6a..36a6ba92df27 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
@@ -1372,21 +1372,19 @@ end: | |||
1372 | } | 1372 | } |
1373 | 1373 | ||
1374 | /* | 1374 | /* |
1375 | * Prune an entity of its bogus controls. This currently includes processing | 1375 | * Prune an entity of its bogus controls using a blacklist. Bogus controls |
1376 | * unit auto controls for which no corresponding manual control is available. | 1376 | * are currently the ones that crash the camera or unconditionally return an |
1377 | * Such auto controls make little sense if any, and are known to crash at | 1377 | * error when queried. |
1378 | * least the SiGma Micro webcam. | ||
1379 | */ | 1378 | */ |
1380 | static void | 1379 | static void |
1381 | uvc_ctrl_prune_entity(struct uvc_entity *entity) | 1380 | uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity) |
1382 | { | 1381 | { |
1383 | static const struct { | 1382 | static const struct { |
1384 | u8 idx_manual; | 1383 | struct usb_device_id id; |
1385 | u8 idx_auto; | 1384 | u8 index; |
1386 | } blacklist[] = { | 1385 | } blacklist[] = { |
1387 | { 2, 11 }, /* Hue */ | 1386 | { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */ |
1388 | { 6, 12 }, /* White Balance Temperature */ | 1387 | { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */ |
1389 | { 7, 13 }, /* White Balance Component */ | ||
1390 | }; | 1388 | }; |
1391 | 1389 | ||
1392 | u8 *controls; | 1390 | u8 *controls; |
@@ -1400,19 +1398,17 @@ uvc_ctrl_prune_entity(struct uvc_entity *entity) | |||
1400 | size = entity->processing.bControlSize; | 1398 | size = entity->processing.bControlSize; |
1401 | 1399 | ||
1402 | for (i = 0; i < ARRAY_SIZE(blacklist); ++i) { | 1400 | for (i = 0; i < ARRAY_SIZE(blacklist); ++i) { |
1403 | if (blacklist[i].idx_auto >= 8 * size || | 1401 | if (!usb_match_id(dev->intf, &blacklist[i].id)) |
1404 | blacklist[i].idx_manual >= 8 * size) | ||
1405 | continue; | 1402 | continue; |
1406 | 1403 | ||
1407 | if (!uvc_test_bit(controls, blacklist[i].idx_auto) || | 1404 | if (blacklist[i].index >= 8 * size || |
1408 | uvc_test_bit(controls, blacklist[i].idx_manual)) | 1405 | !uvc_test_bit(controls, blacklist[i].index)) |
1409 | continue; | 1406 | continue; |
1410 | 1407 | ||
1411 | uvc_trace(UVC_TRACE_CONTROL, "Auto control %u/%u has no " | 1408 | uvc_trace(UVC_TRACE_CONTROL, "%u/%u control is black listed, " |
1412 | "matching manual control, removing it.\n", entity->id, | 1409 | "removing it.\n", entity->id, blacklist[i].index); |
1413 | blacklist[i].idx_auto); | ||
1414 | 1410 | ||
1415 | uvc_clear_bit(controls, blacklist[i].idx_auto); | 1411 | uvc_clear_bit(controls, blacklist[i].index); |
1416 | } | 1412 | } |
1417 | } | 1413 | } |
1418 | 1414 | ||
@@ -1442,8 +1438,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev) | |||
1442 | bControlSize = entity->camera.bControlSize; | 1438 | bControlSize = entity->camera.bControlSize; |
1443 | } | 1439 | } |
1444 | 1440 | ||
1445 | if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS) | 1441 | uvc_ctrl_prune_entity(dev, entity); |
1446 | uvc_ctrl_prune_entity(entity); | ||
1447 | 1442 | ||
1448 | for (i = 0; i < bControlSize; ++i) | 1443 | for (i = 0; i < bControlSize; ++i) |
1449 | ncontrols += hweight8(bmControls[i]); | 1444 | ncontrols += hweight8(bmControls[i]); |
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 507dc85646b2..89927b7aec28 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c | |||
@@ -289,10 +289,8 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
289 | struct uvc_format_desc *fmtdesc; | 289 | struct uvc_format_desc *fmtdesc; |
290 | struct uvc_frame *frame; | 290 | struct uvc_frame *frame; |
291 | const unsigned char *start = buffer; | 291 | const unsigned char *start = buffer; |
292 | unsigned char *_buffer; | ||
293 | unsigned int interval; | 292 | unsigned int interval; |
294 | unsigned int i, n; | 293 | unsigned int i, n; |
295 | int _buflen; | ||
296 | __u8 ftype; | 294 | __u8 ftype; |
297 | 295 | ||
298 | format->type = buffer[2]; | 296 | format->type = buffer[2]; |
@@ -303,7 +301,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
303 | case VS_FORMAT_FRAME_BASED: | 301 | case VS_FORMAT_FRAME_BASED: |
304 | n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28; | 302 | n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28; |
305 | if (buflen < n) { | 303 | if (buflen < n) { |
306 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 304 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
307 | "interface %d FORMAT error\n", | 305 | "interface %d FORMAT error\n", |
308 | dev->udev->devnum, | 306 | dev->udev->devnum, |
309 | alts->desc.bInterfaceNumber); | 307 | alts->desc.bInterfaceNumber); |
@@ -338,7 +336,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
338 | 336 | ||
339 | case VS_FORMAT_MJPEG: | 337 | case VS_FORMAT_MJPEG: |
340 | if (buflen < 11) { | 338 | if (buflen < 11) { |
341 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 339 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
342 | "interface %d FORMAT error\n", | 340 | "interface %d FORMAT error\n", |
343 | dev->udev->devnum, | 341 | dev->udev->devnum, |
344 | alts->desc.bInterfaceNumber); | 342 | alts->desc.bInterfaceNumber); |
@@ -354,7 +352,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
354 | 352 | ||
355 | case VS_FORMAT_DV: | 353 | case VS_FORMAT_DV: |
356 | if (buflen < 9) { | 354 | if (buflen < 9) { |
357 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 355 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
358 | "interface %d FORMAT error\n", | 356 | "interface %d FORMAT error\n", |
359 | dev->udev->devnum, | 357 | dev->udev->devnum, |
360 | alts->desc.bInterfaceNumber); | 358 | alts->desc.bInterfaceNumber); |
@@ -372,7 +370,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
372 | strlcpy(format->name, "HD-DV", sizeof format->name); | 370 | strlcpy(format->name, "HD-DV", sizeof format->name); |
373 | break; | 371 | break; |
374 | default: | 372 | default: |
375 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 373 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
376 | "interface %d: unknown DV format %u\n", | 374 | "interface %d: unknown DV format %u\n", |
377 | dev->udev->devnum, | 375 | dev->udev->devnum, |
378 | alts->desc.bInterfaceNumber, buffer[8]); | 376 | alts->desc.bInterfaceNumber, buffer[8]); |
@@ -401,7 +399,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
401 | case VS_FORMAT_STREAM_BASED: | 399 | case VS_FORMAT_STREAM_BASED: |
402 | /* Not supported yet. */ | 400 | /* Not supported yet. */ |
403 | default: | 401 | default: |
404 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 402 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
405 | "interface %d unsupported format %u\n", | 403 | "interface %d unsupported format %u\n", |
406 | dev->udev->devnum, alts->desc.bInterfaceNumber, | 404 | dev->udev->devnum, alts->desc.bInterfaceNumber, |
407 | buffer[2]); | 405 | buffer[2]); |
@@ -413,20 +411,11 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
413 | buflen -= buffer[0]; | 411 | buflen -= buffer[0]; |
414 | buffer += buffer[0]; | 412 | buffer += buffer[0]; |
415 | 413 | ||
416 | /* Count the number of frame descriptors to test the bFrameIndex | ||
417 | * field when parsing the descriptors. We can't rely on the | ||
418 | * bNumFrameDescriptors field as some cameras don't initialize it | ||
419 | * properly. | ||
420 | */ | ||
421 | for (_buflen = buflen, _buffer = buffer; | ||
422 | _buflen > 2 && _buffer[2] == ftype; | ||
423 | _buflen -= _buffer[0], _buffer += _buffer[0]) | ||
424 | format->nframes++; | ||
425 | |||
426 | /* Parse the frame descriptors. Only uncompressed, MJPEG and frame | 414 | /* Parse the frame descriptors. Only uncompressed, MJPEG and frame |
427 | * based formats have frame descriptors. | 415 | * based formats have frame descriptors. |
428 | */ | 416 | */ |
429 | while (buflen > 2 && buffer[2] == ftype) { | 417 | while (buflen > 2 && buffer[2] == ftype) { |
418 | frame = &format->frame[format->nframes]; | ||
430 | if (ftype != VS_FRAME_FRAME_BASED) | 419 | if (ftype != VS_FRAME_FRAME_BASED) |
431 | n = buflen > 25 ? buffer[25] : 0; | 420 | n = buflen > 25 ? buffer[25] : 0; |
432 | else | 421 | else |
@@ -435,22 +424,12 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
435 | n = n ? n : 3; | 424 | n = n ? n : 3; |
436 | 425 | ||
437 | if (buflen < 26 + 4*n) { | 426 | if (buflen < 26 + 4*n) { |
438 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 427 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
439 | "interface %d FRAME error\n", dev->udev->devnum, | 428 | "interface %d FRAME error\n", dev->udev->devnum, |
440 | alts->desc.bInterfaceNumber); | 429 | alts->desc.bInterfaceNumber); |
441 | return -EINVAL; | 430 | return -EINVAL; |
442 | } | 431 | } |
443 | 432 | ||
444 | if (buffer[3] - 1 >= format->nframes) { | ||
445 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | ||
446 | "interface %d frame index %u out of range\n", | ||
447 | dev->udev->devnum, alts->desc.bInterfaceNumber, | ||
448 | buffer[3]); | ||
449 | return -EINVAL; | ||
450 | } | ||
451 | |||
452 | frame = &format->frame[buffer[3] - 1]; | ||
453 | |||
454 | frame->bFrameIndex = buffer[3]; | 433 | frame->bFrameIndex = buffer[3]; |
455 | frame->bmCapabilities = buffer[4]; | 434 | frame->bmCapabilities = buffer[4]; |
456 | frame->wWidth = get_unaligned_le16(&buffer[5]); | 435 | frame->wWidth = get_unaligned_le16(&buffer[5]); |
@@ -507,6 +486,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
507 | 10000000/frame->dwDefaultFrameInterval, | 486 | 10000000/frame->dwDefaultFrameInterval, |
508 | (100000000/frame->dwDefaultFrameInterval)%10); | 487 | (100000000/frame->dwDefaultFrameInterval)%10); |
509 | 488 | ||
489 | format->nframes++; | ||
510 | buflen -= buffer[0]; | 490 | buflen -= buffer[0]; |
511 | buffer += buffer[0]; | 491 | buffer += buffer[0]; |
512 | } | 492 | } |
@@ -518,7 +498,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
518 | 498 | ||
519 | if (buflen > 2 && buffer[2] == VS_COLORFORMAT) { | 499 | if (buflen > 2 && buffer[2] == VS_COLORFORMAT) { |
520 | if (buflen < 6) { | 500 | if (buflen < 6) { |
521 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 501 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
522 | "interface %d COLORFORMAT error\n", | 502 | "interface %d COLORFORMAT error\n", |
523 | dev->udev->devnum, | 503 | dev->udev->devnum, |
524 | alts->desc.bInterfaceNumber); | 504 | alts->desc.bInterfaceNumber); |
@@ -664,7 +644,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, | |||
664 | _buflen = buflen; | 644 | _buflen = buflen; |
665 | 645 | ||
666 | /* Count the format and frame descriptors. */ | 646 | /* Count the format and frame descriptors. */ |
667 | while (_buflen > 2) { | 647 | while (_buflen > 2 && _buffer[1] == CS_INTERFACE) { |
668 | switch (_buffer[2]) { | 648 | switch (_buffer[2]) { |
669 | case VS_FORMAT_UNCOMPRESSED: | 649 | case VS_FORMAT_UNCOMPRESSED: |
670 | case VS_FORMAT_MJPEG: | 650 | case VS_FORMAT_MJPEG: |
@@ -729,7 +709,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, | |||
729 | streaming->nformats = nformats; | 709 | streaming->nformats = nformats; |
730 | 710 | ||
731 | /* Parse the format descriptors. */ | 711 | /* Parse the format descriptors. */ |
732 | while (buflen > 2) { | 712 | while (buflen > 2 && buffer[1] == CS_INTERFACE) { |
733 | switch (buffer[2]) { | 713 | switch (buffer[2]) { |
734 | case VS_FORMAT_UNCOMPRESSED: | 714 | case VS_FORMAT_UNCOMPRESSED: |
735 | case VS_FORMAT_MJPEG: | 715 | case VS_FORMAT_MJPEG: |
@@ -1316,7 +1296,7 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video, | |||
1316 | continue; | 1296 | continue; |
1317 | 1297 | ||
1318 | if (forward->extension.bNrInPins != 1) { | 1298 | if (forward->extension.bNrInPins != 1) { |
1319 | uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has" | 1299 | uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has " |
1320 | "more than 1 input pin.\n", entity->id); | 1300 | "more than 1 input pin.\n", entity->id); |
1321 | return -1; | 1301 | return -1; |
1322 | } | 1302 | } |
@@ -1614,6 +1594,7 @@ static int uvc_probe(struct usb_interface *intf, | |||
1614 | INIT_LIST_HEAD(&dev->entities); | 1594 | INIT_LIST_HEAD(&dev->entities); |
1615 | INIT_LIST_HEAD(&dev->streaming); | 1595 | INIT_LIST_HEAD(&dev->streaming); |
1616 | kref_init(&dev->kref); | 1596 | kref_init(&dev->kref); |
1597 | atomic_set(&dev->users, 0); | ||
1617 | 1598 | ||
1618 | dev->udev = usb_get_dev(udev); | 1599 | dev->udev = usb_get_dev(udev); |
1619 | dev->intf = usb_get_intf(intf); | 1600 | dev->intf = usb_get_intf(intf); |
@@ -1927,7 +1908,7 @@ static struct usb_device_id uvc_ids[] = { | |||
1927 | .bInterfaceSubClass = 1, | 1908 | .bInterfaceSubClass = 1, |
1928 | .bInterfaceProtocol = 0, | 1909 | .bInterfaceProtocol = 0, |
1929 | .driver_info = UVC_QUIRK_STREAM_NO_FID }, | 1910 | .driver_info = UVC_QUIRK_STREAM_NO_FID }, |
1930 | /* Lenovo Thinkpad SL500 */ | 1911 | /* Lenovo Thinkpad SL400/SL500 */ |
1931 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1912 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
1932 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1913 | | USB_DEVICE_ID_MATCH_INT_INFO, |
1933 | .idVendor = 0x17ef, | 1914 | .idVendor = 0x17ef, |
@@ -1936,6 +1917,15 @@ static struct usb_device_id uvc_ids[] = { | |||
1936 | .bInterfaceSubClass = 1, | 1917 | .bInterfaceSubClass = 1, |
1937 | .bInterfaceProtocol = 0, | 1918 | .bInterfaceProtocol = 0, |
1938 | .driver_info = UVC_QUIRK_STREAM_NO_FID }, | 1919 | .driver_info = UVC_QUIRK_STREAM_NO_FID }, |
1920 | /* Aveo Technology USB 2.0 Camera */ | ||
1921 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
1922 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
1923 | .idVendor = 0x1871, | ||
1924 | .idProduct = 0x0306, | ||
1925 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
1926 | .bInterfaceSubClass = 1, | ||
1927 | .bInterfaceProtocol = 0, | ||
1928 | .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, | ||
1939 | /* Ecamm Pico iMage */ | 1929 | /* Ecamm Pico iMage */ |
1940 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1930 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
1941 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1931 | | USB_DEVICE_ID_MATCH_INT_INFO, |
@@ -1945,6 +1935,15 @@ static struct usb_device_id uvc_ids[] = { | |||
1945 | .bInterfaceSubClass = 1, | 1935 | .bInterfaceSubClass = 1, |
1946 | .bInterfaceProtocol = 0, | 1936 | .bInterfaceProtocol = 0, |
1947 | .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, | 1937 | .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, |
1938 | /* FSC WebCam V30S */ | ||
1939 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
1940 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
1941 | .idVendor = 0x18ec, | ||
1942 | .idProduct = 0x3288, | ||
1943 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
1944 | .bInterfaceSubClass = 1, | ||
1945 | .bInterfaceProtocol = 0, | ||
1946 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | ||
1948 | /* Bodelin ProScopeHR */ | 1947 | /* Bodelin ProScopeHR */ |
1949 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1948 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
1950 | | USB_DEVICE_ID_MATCH_DEV_HI | 1949 | | USB_DEVICE_ID_MATCH_DEV_HI |
@@ -1965,8 +1964,7 @@ static struct usb_device_id uvc_ids[] = { | |||
1965 | .bInterfaceSubClass = 1, | 1964 | .bInterfaceSubClass = 1, |
1966 | .bInterfaceProtocol = 0, | 1965 | .bInterfaceProtocol = 0, |
1967 | .driver_info = UVC_QUIRK_PROBE_MINMAX | 1966 | .driver_info = UVC_QUIRK_PROBE_MINMAX |
1968 | | UVC_QUIRK_IGNORE_SELECTOR_UNIT | 1967 | | UVC_QUIRK_IGNORE_SELECTOR_UNIT }, |
1969 | | UVC_QUIRK_PRUNE_CONTROLS }, | ||
1970 | /* Generic USB Video Class */ | 1968 | /* Generic USB Video Class */ |
1971 | { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, | 1969 | { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, |
1972 | {} | 1970 | {} |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 0155752e4a5a..f854698c4061 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -172,6 +172,20 @@ int uvc_free_buffers(struct uvc_video_queue *queue) | |||
172 | return 0; | 172 | return 0; |
173 | } | 173 | } |
174 | 174 | ||
175 | /* | ||
176 | * Check if buffers have been allocated. | ||
177 | */ | ||
178 | int uvc_queue_allocated(struct uvc_video_queue *queue) | ||
179 | { | ||
180 | int allocated; | ||
181 | |||
182 | mutex_lock(&queue->mutex); | ||
183 | allocated = queue->count != 0; | ||
184 | mutex_unlock(&queue->mutex); | ||
185 | |||
186 | return allocated; | ||
187 | } | ||
188 | |||
175 | static void __uvc_query_buffer(struct uvc_buffer *buf, | 189 | static void __uvc_query_buffer(struct uvc_buffer *buf, |
176 | struct v4l2_buffer *v4l2_buf) | 190 | struct v4l2_buffer *v4l2_buf) |
177 | { | 191 | { |
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c index 21d87124986b..f152a9903862 100644 --- a/drivers/media/video/uvc/uvc_status.c +++ b/drivers/media/video/uvc/uvc_status.c | |||
@@ -194,7 +194,7 @@ int uvc_status_init(struct uvc_device *dev) | |||
194 | dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete, | 194 | dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete, |
195 | dev, interval); | 195 | dev, interval); |
196 | 196 | ||
197 | return usb_submit_urb(dev->int_urb, GFP_KERNEL); | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | void uvc_status_cleanup(struct uvc_device *dev) | 200 | void uvc_status_cleanup(struct uvc_device *dev) |
@@ -205,15 +205,30 @@ void uvc_status_cleanup(struct uvc_device *dev) | |||
205 | uvc_input_cleanup(dev); | 205 | uvc_input_cleanup(dev); |
206 | } | 206 | } |
207 | 207 | ||
208 | int uvc_status_suspend(struct uvc_device *dev) | 208 | int uvc_status_start(struct uvc_device *dev) |
209 | { | ||
210 | if (dev->int_urb == NULL) | ||
211 | return 0; | ||
212 | |||
213 | return usb_submit_urb(dev->int_urb, GFP_KERNEL); | ||
214 | } | ||
215 | |||
216 | void uvc_status_stop(struct uvc_device *dev) | ||
209 | { | 217 | { |
210 | usb_kill_urb(dev->int_urb); | 218 | usb_kill_urb(dev->int_urb); |
219 | } | ||
220 | |||
221 | int uvc_status_suspend(struct uvc_device *dev) | ||
222 | { | ||
223 | if (atomic_read(&dev->users)) | ||
224 | usb_kill_urb(dev->int_urb); | ||
225 | |||
211 | return 0; | 226 | return 0; |
212 | } | 227 | } |
213 | 228 | ||
214 | int uvc_status_resume(struct uvc_device *dev) | 229 | int uvc_status_resume(struct uvc_device *dev) |
215 | { | 230 | { |
216 | if (dev->int_urb == NULL) | 231 | if (dev->int_urb == NULL || atomic_read(&dev->users) == 0) |
217 | return 0; | 232 | return 0; |
218 | 233 | ||
219 | return usb_submit_urb(dev->int_urb, GFP_NOIO); | 234 | return usb_submit_urb(dev->int_urb, GFP_NOIO); |
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 2a80caa54fb4..5e77cad29690 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
@@ -46,6 +46,8 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video, | |||
46 | struct uvc_menu_info *menu_info; | 46 | struct uvc_menu_info *menu_info; |
47 | struct uvc_control_mapping *mapping; | 47 | struct uvc_control_mapping *mapping; |
48 | struct uvc_control *ctrl; | 48 | struct uvc_control *ctrl; |
49 | u32 index = query_menu->index; | ||
50 | u32 id = query_menu->id; | ||
49 | 51 | ||
50 | ctrl = uvc_find_control(video, query_menu->id, &mapping); | 52 | ctrl = uvc_find_control(video, query_menu->id, &mapping); |
51 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) | 53 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) |
@@ -54,6 +56,10 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video, | |||
54 | if (query_menu->index >= mapping->menu_count) | 56 | if (query_menu->index >= mapping->menu_count) |
55 | return -EINVAL; | 57 | return -EINVAL; |
56 | 58 | ||
59 | memset(query_menu, 0, sizeof(*query_menu)); | ||
60 | query_menu->id = id; | ||
61 | query_menu->index = index; | ||
62 | |||
57 | menu_info = &mapping->menu_info[query_menu->index]; | 63 | menu_info = &mapping->menu_info[query_menu->index]; |
58 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | 64 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); |
59 | return 0; | 65 | return 0; |
@@ -245,7 +251,7 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video, | |||
245 | if (fmt->type != video->streaming->type) | 251 | if (fmt->type != video->streaming->type) |
246 | return -EINVAL; | 252 | return -EINVAL; |
247 | 253 | ||
248 | if (uvc_queue_streaming(&video->queue)) | 254 | if (uvc_queue_allocated(&video->queue)) |
249 | return -EBUSY; | 255 | return -EBUSY; |
250 | 256 | ||
251 | ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame); | 257 | ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame); |
@@ -433,6 +439,15 @@ static int uvc_v4l2_open(struct file *file) | |||
433 | goto done; | 439 | goto done; |
434 | } | 440 | } |
435 | 441 | ||
442 | if (atomic_inc_return(&video->dev->users) == 1) { | ||
443 | if ((ret = uvc_status_start(video->dev)) < 0) { | ||
444 | usb_autopm_put_interface(video->dev->intf); | ||
445 | atomic_dec(&video->dev->users); | ||
446 | kfree(handle); | ||
447 | goto done; | ||
448 | } | ||
449 | } | ||
450 | |||
436 | handle->device = video; | 451 | handle->device = video; |
437 | handle->state = UVC_HANDLE_PASSIVE; | 452 | handle->state = UVC_HANDLE_PASSIVE; |
438 | file->private_data = handle; | 453 | file->private_data = handle; |
@@ -467,6 +482,9 @@ static int uvc_v4l2_release(struct file *file) | |||
467 | kfree(handle); | 482 | kfree(handle); |
468 | file->private_data = NULL; | 483 | file->private_data = NULL; |
469 | 484 | ||
485 | if (atomic_dec_return(&video->dev->users) == 0) | ||
486 | uvc_status_stop(video->dev); | ||
487 | |||
470 | usb_autopm_put_interface(video->dev->intf); | 488 | usb_autopm_put_interface(video->dev->intf); |
471 | kref_put(&video->dev->kref, uvc_delete); | 489 | kref_put(&video->dev->kref, uvc_delete); |
472 | return 0; | 490 | return 0; |
@@ -512,7 +530,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
512 | memset(&xctrl, 0, sizeof xctrl); | 530 | memset(&xctrl, 0, sizeof xctrl); |
513 | xctrl.id = ctrl->id; | 531 | xctrl.id = ctrl->id; |
514 | 532 | ||
515 | uvc_ctrl_begin(video); | 533 | ret = uvc_ctrl_begin(video); |
534 | if (ret < 0) | ||
535 | return ret; | ||
536 | |||
516 | ret = uvc_ctrl_get(video, &xctrl); | 537 | ret = uvc_ctrl_get(video, &xctrl); |
517 | uvc_ctrl_rollback(video); | 538 | uvc_ctrl_rollback(video); |
518 | if (ret >= 0) | 539 | if (ret >= 0) |
@@ -529,7 +550,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
529 | xctrl.id = ctrl->id; | 550 | xctrl.id = ctrl->id; |
530 | xctrl.value = ctrl->value; | 551 | xctrl.value = ctrl->value; |
531 | 552 | ||
532 | uvc_ctrl_begin(video); | 553 | ret = uvc_ctrl_begin(video); |
554 | if (ret < 0) | ||
555 | return ret; | ||
556 | |||
533 | ret = uvc_ctrl_set(video, &xctrl); | 557 | ret = uvc_ctrl_set(video, &xctrl); |
534 | if (ret < 0) { | 558 | if (ret < 0) { |
535 | uvc_ctrl_rollback(video); | 559 | uvc_ctrl_rollback(video); |
@@ -548,7 +572,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
548 | struct v4l2_ext_control *ctrl = ctrls->controls; | 572 | struct v4l2_ext_control *ctrl = ctrls->controls; |
549 | unsigned int i; | 573 | unsigned int i; |
550 | 574 | ||
551 | uvc_ctrl_begin(video); | 575 | ret = uvc_ctrl_begin(video); |
576 | if (ret < 0) | ||
577 | return ret; | ||
578 | |||
552 | for (i = 0; i < ctrls->count; ++ctrl, ++i) { | 579 | for (i = 0; i < ctrls->count; ++ctrl, ++i) { |
553 | ret = uvc_ctrl_get(video, ctrl); | 580 | ret = uvc_ctrl_get(video, ctrl); |
554 | if (ret < 0) { | 581 | if (ret < 0) { |
@@ -648,7 +675,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
648 | 675 | ||
649 | case VIDIOC_S_INPUT: | 676 | case VIDIOC_S_INPUT: |
650 | { | 677 | { |
651 | u8 input = *(u32 *)arg + 1; | 678 | u32 input = *(u32 *)arg + 1; |
652 | 679 | ||
653 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 680 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
654 | return ret; | 681 | return ret; |
@@ -660,7 +687,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
660 | break; | 687 | break; |
661 | } | 688 | } |
662 | 689 | ||
663 | if (input > video->selector->selector.bNrInPins) | 690 | if (input == 0 || input > video->selector->selector.bNrInPins) |
664 | return -EINVAL; | 691 | return -EINVAL; |
665 | 692 | ||
666 | return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id, | 693 | return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id, |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 6ce974d7362f..01b633c73480 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -65,7 +65,8 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video, | |||
65 | struct uvc_streaming_control *ctrl) | 65 | struct uvc_streaming_control *ctrl) |
66 | { | 66 | { |
67 | struct uvc_format *format; | 67 | struct uvc_format *format; |
68 | struct uvc_frame *frame; | 68 | struct uvc_frame *frame = NULL; |
69 | unsigned int i; | ||
69 | 70 | ||
70 | if (ctrl->bFormatIndex <= 0 || | 71 | if (ctrl->bFormatIndex <= 0 || |
71 | ctrl->bFormatIndex > video->streaming->nformats) | 72 | ctrl->bFormatIndex > video->streaming->nformats) |
@@ -73,11 +74,15 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video, | |||
73 | 74 | ||
74 | format = &video->streaming->format[ctrl->bFormatIndex - 1]; | 75 | format = &video->streaming->format[ctrl->bFormatIndex - 1]; |
75 | 76 | ||
76 | if (ctrl->bFrameIndex <= 0 || | 77 | for (i = 0; i < format->nframes; ++i) { |
77 | ctrl->bFrameIndex > format->nframes) | 78 | if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) { |
78 | return; | 79 | frame = &format->frame[i]; |
80 | break; | ||
81 | } | ||
82 | } | ||
79 | 83 | ||
80 | frame = &format->frame[ctrl->bFrameIndex - 1]; | 84 | if (frame == NULL) |
85 | return; | ||
81 | 86 | ||
82 | if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) || | 87 | if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) || |
83 | (ctrl->dwMaxVideoFrameSize == 0 && | 88 | (ctrl->dwMaxVideoFrameSize == 0 && |
@@ -1089,7 +1094,7 @@ int uvc_video_init(struct uvc_video_device *video) | |||
1089 | /* Zero bFrameIndex might be correct. Stream-based formats (including | 1094 | /* Zero bFrameIndex might be correct. Stream-based formats (including |
1090 | * MPEG-2 TS and DV) do not support frames but have a dummy frame | 1095 | * MPEG-2 TS and DV) do not support frames but have a dummy frame |
1091 | * descriptor with bFrameIndex set to zero. If the default frame | 1096 | * descriptor with bFrameIndex set to zero. If the default frame |
1092 | * descriptor is not found, use the first avalable frame. | 1097 | * descriptor is not found, use the first available frame. |
1093 | */ | 1098 | */ |
1094 | for (i = format->nframes; i > 0; --i) { | 1099 | for (i = format->nframes; i > 0; --i) { |
1095 | frame = &format->frame[i-1]; | 1100 | frame = &format->frame[i-1]; |
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index e5014e668f99..3c78d3c1e4c0 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -313,7 +313,6 @@ struct uvc_xu_control { | |||
313 | #define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 | 313 | #define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 |
314 | #define UVC_QUIRK_STREAM_NO_FID 0x00000010 | 314 | #define UVC_QUIRK_STREAM_NO_FID 0x00000010 |
315 | #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 | 315 | #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 |
316 | #define UVC_QUIRK_PRUNE_CONTROLS 0x00000040 | ||
317 | #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 | 316 | #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 |
318 | 317 | ||
319 | /* Format flags */ | 318 | /* Format flags */ |
@@ -634,6 +633,7 @@ struct uvc_device { | |||
634 | enum uvc_device_state state; | 633 | enum uvc_device_state state; |
635 | struct kref kref; | 634 | struct kref kref; |
636 | struct list_head list; | 635 | struct list_head list; |
636 | atomic_t users; | ||
637 | 637 | ||
638 | /* Video control interface */ | 638 | /* Video control interface */ |
639 | __u16 uvc_version; | 639 | __u16 uvc_version; |
@@ -747,6 +747,7 @@ extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
747 | struct uvc_buffer *buf); | 747 | struct uvc_buffer *buf); |
748 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, | 748 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, |
749 | struct file *file, poll_table *wait); | 749 | struct file *file, poll_table *wait); |
750 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); | ||
750 | static inline int uvc_queue_streaming(struct uvc_video_queue *queue) | 751 | static inline int uvc_queue_streaming(struct uvc_video_queue *queue) |
751 | { | 752 | { |
752 | return queue->flags & UVC_QUEUE_STREAMING; | 753 | return queue->flags & UVC_QUEUE_STREAMING; |
@@ -770,6 +771,8 @@ extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | |||
770 | /* Status */ | 771 | /* Status */ |
771 | extern int uvc_status_init(struct uvc_device *dev); | 772 | extern int uvc_status_init(struct uvc_device *dev); |
772 | extern void uvc_status_cleanup(struct uvc_device *dev); | 773 | extern void uvc_status_cleanup(struct uvc_device *dev); |
774 | extern int uvc_status_start(struct uvc_device *dev); | ||
775 | extern void uvc_status_stop(struct uvc_device *dev); | ||
773 | extern int uvc_status_suspend(struct uvc_device *dev); | 776 | extern int uvc_status_suspend(struct uvc_device *dev); |
774 | extern int uvc_status_resume(struct uvc_device *dev); | 777 | extern int uvc_status_resume(struct uvc_device *dev); |
775 | 778 | ||
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index f576ef66b807..f96475626da7 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -746,6 +746,7 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, | |||
746 | const struct v4l2_subdev_ops *ops) | 746 | const struct v4l2_subdev_ops *ops) |
747 | { | 747 | { |
748 | v4l2_subdev_init(sd, ops); | 748 | v4l2_subdev_init(sd, ops); |
749 | sd->flags |= V4L2_SUBDEV_FL_IS_I2C; | ||
749 | /* the owner is the same as the i2c_client's driver owner */ | 750 | /* the owner is the same as the i2c_client's driver owner */ |
750 | sd->owner = client->driver->driver.owner; | 751 | sd->owner = client->driver->driver.owner; |
751 | /* i2c_client and v4l2_subdev point to one another */ | 752 | /* i2c_client and v4l2_subdev point to one another */ |
@@ -897,8 +898,7 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type) | |||
897 | }; | 898 | }; |
898 | static const unsigned short tv_addrs[] = { | 899 | static const unsigned short tv_addrs[] = { |
899 | 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ | 900 | 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ |
900 | 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, | 901 | 0x60, 0x61, 0x62, 0x63, 0x64, |
901 | 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, | ||
902 | I2C_CLIENT_END | 902 | I2C_CLIENT_END |
903 | }; | 903 | }; |
904 | 904 | ||
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c index 94aa485ade52..0d06e7cbd5b3 100644 --- a/drivers/media/video/v4l2-device.c +++ b/drivers/media/video/v4l2-device.c | |||
@@ -49,6 +49,22 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) | |||
49 | } | 49 | } |
50 | EXPORT_SYMBOL_GPL(v4l2_device_register); | 50 | EXPORT_SYMBOL_GPL(v4l2_device_register); |
51 | 51 | ||
52 | int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename, | ||
53 | atomic_t *instance) | ||
54 | { | ||
55 | int num = atomic_inc_return(instance) - 1; | ||
56 | int len = strlen(basename); | ||
57 | |||
58 | if (basename[len - 1] >= '0' && basename[len - 1] <= '9') | ||
59 | snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), | ||
60 | "%s-%d", basename, num); | ||
61 | else | ||
62 | snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), | ||
63 | "%s%d", basename, num); | ||
64 | return num; | ||
65 | } | ||
66 | EXPORT_SYMBOL_GPL(v4l2_device_set_name); | ||
67 | |||
52 | void v4l2_device_disconnect(struct v4l2_device *v4l2_dev) | 68 | void v4l2_device_disconnect(struct v4l2_device *v4l2_dev) |
53 | { | 69 | { |
54 | if (v4l2_dev->dev) { | 70 | if (v4l2_dev->dev) { |
@@ -67,8 +83,21 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev) | |||
67 | v4l2_device_disconnect(v4l2_dev); | 83 | v4l2_device_disconnect(v4l2_dev); |
68 | 84 | ||
69 | /* Unregister subdevs */ | 85 | /* Unregister subdevs */ |
70 | list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) | 86 | list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) { |
71 | v4l2_device_unregister_subdev(sd); | 87 | v4l2_device_unregister_subdev(sd); |
88 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
89 | if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) { | ||
90 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
91 | |||
92 | /* We need to unregister the i2c client explicitly. | ||
93 | We cannot rely on i2c_del_adapter to always | ||
94 | unregister clients for us, since if the i2c bus | ||
95 | is a platform bus, then it is never deleted. */ | ||
96 | if (client) | ||
97 | i2c_unregister_device(client); | ||
98 | } | ||
99 | #endif | ||
100 | } | ||
72 | } | 101 | } |
73 | EXPORT_SYMBOL_GPL(v4l2_device_unregister); | 102 | EXPORT_SYMBOL_GPL(v4l2_device_unregister); |
74 | 103 | ||
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index b7b05842cf28..f1ccf98c0a6f 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c | |||
@@ -118,6 +118,7 @@ void videobuf_queue_core_init(struct videobuf_queue *q, | |||
118 | void *priv, | 118 | void *priv, |
119 | struct videobuf_qtype_ops *int_ops) | 119 | struct videobuf_qtype_ops *int_ops) |
120 | { | 120 | { |
121 | BUG_ON(!q); | ||
121 | memset(q, 0, sizeof(*q)); | 122 | memset(q, 0, sizeof(*q)); |
122 | q->irqlock = irqlock; | 123 | q->irqlock = irqlock; |
123 | q->dev = dev; | 124 | q->dev = dev; |
@@ -439,6 +440,7 @@ int videobuf_reqbufs(struct videobuf_queue *q, | |||
439 | } | 440 | } |
440 | 441 | ||
441 | req->count = retval; | 442 | req->count = retval; |
443 | retval = 0; | ||
442 | 444 | ||
443 | done: | 445 | done: |
444 | mutex_unlock(&q->vb_lock); | 446 | mutex_unlock(&q->vb_lock); |
@@ -454,7 +456,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) | |||
454 | dprintk(1, "querybuf: Wrong type.\n"); | 456 | dprintk(1, "querybuf: Wrong type.\n"); |
455 | goto done; | 457 | goto done; |
456 | } | 458 | } |
457 | if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) { | 459 | if (unlikely(b->index >= VIDEO_MAX_FRAME)) { |
458 | dprintk(1, "querybuf: index out of range.\n"); | 460 | dprintk(1, "querybuf: index out of range.\n"); |
459 | goto done; | 461 | goto done; |
460 | } | 462 | } |
@@ -495,7 +497,7 @@ int videobuf_qbuf(struct videobuf_queue *q, | |||
495 | dprintk(1, "qbuf: Wrong type.\n"); | 497 | dprintk(1, "qbuf: Wrong type.\n"); |
496 | goto done; | 498 | goto done; |
497 | } | 499 | } |
498 | if (b->index < 0 || b->index >= VIDEO_MAX_FRAME) { | 500 | if (b->index >= VIDEO_MAX_FRAME) { |
499 | dprintk(1, "qbuf: index out of range.\n"); | 501 | dprintk(1, "qbuf: index out of range.\n"); |
500 | goto done; | 502 | goto done; |
501 | } | 503 | } |
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 0c29a019bc89..d09ce83a9429 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c | |||
@@ -259,19 +259,6 @@ static int __videobuf_iolock(struct videobuf_queue *q, | |||
259 | return 0; | 259 | return 0; |
260 | } | 260 | } |
261 | 261 | ||
262 | static int __videobuf_sync(struct videobuf_queue *q, | ||
263 | struct videobuf_buffer *buf) | ||
264 | { | ||
265 | struct videobuf_dma_contig_memory *mem = buf->priv; | ||
266 | |||
267 | BUG_ON(!mem); | ||
268 | MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); | ||
269 | |||
270 | dma_sync_single_for_cpu(q->dev, mem->dma_handle, mem->size, | ||
271 | DMA_FROM_DEVICE); | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | static int __videobuf_mmap_free(struct videobuf_queue *q) | 262 | static int __videobuf_mmap_free(struct videobuf_queue *q) |
276 | { | 263 | { |
277 | unsigned int i; | 264 | unsigned int i; |
@@ -433,7 +420,6 @@ static struct videobuf_qtype_ops qops = { | |||
433 | 420 | ||
434 | .alloc = __videobuf_alloc, | 421 | .alloc = __videobuf_alloc, |
435 | .iolock = __videobuf_iolock, | 422 | .iolock = __videobuf_iolock, |
436 | .sync = __videobuf_sync, | ||
437 | .mmap_free = __videobuf_mmap_free, | 423 | .mmap_free = __videobuf_mmap_free, |
438 | .mmap_mapper = __videobuf_mmap_mapper, | 424 | .mmap_mapper = __videobuf_mmap_mapper, |
439 | .video_copy_to_user = __videobuf_copy_to_user, | 425 | .video_copy_to_user = __videobuf_copy_to_user, |
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index da1790e57a86..a8dd22ace3fb 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c | |||
@@ -58,9 +58,10 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages) | |||
58 | struct page *pg; | 58 | struct page *pg; |
59 | int i; | 59 | int i; |
60 | 60 | ||
61 | sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL); | 61 | sglist = vmalloc(nr_pages * sizeof(*sglist)); |
62 | if (NULL == sglist) | 62 | if (NULL == sglist) |
63 | return NULL; | 63 | return NULL; |
64 | memset(sglist, 0, nr_pages * sizeof(*sglist)); | ||
64 | sg_init_table(sglist, nr_pages); | 65 | sg_init_table(sglist, nr_pages); |
65 | for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) { | 66 | for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) { |
66 | pg = vmalloc_to_page(virt); | 67 | pg = vmalloc_to_page(virt); |
@@ -72,7 +73,7 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages) | |||
72 | return sglist; | 73 | return sglist; |
73 | 74 | ||
74 | err: | 75 | err: |
75 | kfree(sglist); | 76 | vfree(sglist); |
76 | return NULL; | 77 | return NULL; |
77 | } | 78 | } |
78 | 79 | ||
@@ -84,7 +85,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset) | |||
84 | 85 | ||
85 | if (NULL == pages[0]) | 86 | if (NULL == pages[0]) |
86 | return NULL; | 87 | return NULL; |
87 | sglist = kmalloc(nr_pages * sizeof(*sglist), GFP_KERNEL); | 88 | sglist = vmalloc(nr_pages * sizeof(*sglist)); |
88 | if (NULL == sglist) | 89 | if (NULL == sglist) |
89 | return NULL; | 90 | return NULL; |
90 | sg_init_table(sglist, nr_pages); | 91 | sg_init_table(sglist, nr_pages); |
@@ -104,12 +105,12 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset) | |||
104 | 105 | ||
105 | nopage: | 106 | nopage: |
106 | dprintk(2,"sgl: oops - no page\n"); | 107 | dprintk(2,"sgl: oops - no page\n"); |
107 | kfree(sglist); | 108 | vfree(sglist); |
108 | return NULL; | 109 | return NULL; |
109 | 110 | ||
110 | highmem: | 111 | highmem: |
111 | dprintk(2,"sgl: oops - highmem page\n"); | 112 | dprintk(2,"sgl: oops - highmem page\n"); |
112 | kfree(sglist); | 113 | vfree(sglist); |
113 | return NULL; | 114 | return NULL; |
114 | } | 115 | } |
115 | 116 | ||
@@ -230,7 +231,7 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma) | |||
230 | (dma->vmalloc,dma->nr_pages); | 231 | (dma->vmalloc,dma->nr_pages); |
231 | } | 232 | } |
232 | if (dma->bus_addr) { | 233 | if (dma->bus_addr) { |
233 | dma->sglist = kmalloc(sizeof(struct scatterlist), GFP_KERNEL); | 234 | dma->sglist = vmalloc(sizeof(*dma->sglist)); |
234 | if (NULL != dma->sglist) { | 235 | if (NULL != dma->sglist) { |
235 | dma->sglen = 1; | 236 | dma->sglen = 1; |
236 | sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK; | 237 | sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK; |
@@ -248,10 +249,10 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma) | |||
248 | if (0 == dma->sglen) { | 249 | if (0 == dma->sglen) { |
249 | printk(KERN_WARNING | 250 | printk(KERN_WARNING |
250 | "%s: videobuf_map_sg failed\n",__func__); | 251 | "%s: videobuf_map_sg failed\n",__func__); |
251 | kfree(dma->sglist); | 252 | vfree(dma->sglist); |
252 | dma->sglist = NULL; | 253 | dma->sglist = NULL; |
253 | dma->sglen = 0; | 254 | dma->sglen = 0; |
254 | return -EIO; | 255 | return -ENOMEM; |
255 | } | 256 | } |
256 | } | 257 | } |
257 | return 0; | 258 | return 0; |
@@ -274,7 +275,7 @@ int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma) | |||
274 | 275 | ||
275 | dma_unmap_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction); | 276 | dma_unmap_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction); |
276 | 277 | ||
277 | kfree(dma->sglist); | 278 | vfree(dma->sglist); |
278 | dma->sglist = NULL; | 279 | dma->sglist = NULL; |
279 | dma->sglen = 0; | 280 | dma->sglen = 0; |
280 | return 0; | 281 | return 0; |
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 43e0998adb53..97b082fe4473 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
@@ -868,9 +868,9 @@ static void vino_sync_buffer(struct vino_framebuffer *fb) | |||
868 | dprintk("vino_sync_buffer():\n"); | 868 | dprintk("vino_sync_buffer():\n"); |
869 | 869 | ||
870 | for (i = 0; i < fb->desc_table.page_count; i++) | 870 | for (i = 0; i < fb->desc_table.page_count; i++) |
871 | dma_sync_single(NULL, | 871 | dma_sync_single_for_cpu(NULL, |
872 | fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i], | 872 | fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i], |
873 | PAGE_SIZE, DMA_FROM_DEVICE); | 873 | PAGE_SIZE, DMA_FROM_DEVICE); |
874 | } | 874 | } |
875 | 875 | ||
876 | /* Framebuffer fifo functions (need to be locked externally) */ | 876 | /* Framebuffer fifo functions (need to be locked externally) */ |
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index ea6c577b0eb3..03dc2f3cf84a 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c | |||
@@ -1022,7 +1022,7 @@ zr36057_init (struct zoran *zr) | |||
1022 | zr->vbuf_bytesperline = 0; | 1022 | zr->vbuf_bytesperline = 0; |
1023 | 1023 | ||
1024 | /* Avoid nonsense settings from user for default input/norm */ | 1024 | /* Avoid nonsense settings from user for default input/norm */ |
1025 | if (default_norm < 0 && default_norm > 2) | 1025 | if (default_norm < 0 || default_norm > 2) |
1026 | default_norm = 0; | 1026 | default_norm = 0; |
1027 | if (default_norm == 0) { | 1027 | if (default_norm == 0) { |
1028 | zr->norm = V4L2_STD_PAL; | 1028 | zr->norm = V4L2_STD_PAL; |
@@ -1477,7 +1477,7 @@ static struct pci_driver zoran_driver = { | |||
1477 | .name = "zr36067", | 1477 | .name = "zr36067", |
1478 | .id_table = zr36067_pci_tbl, | 1478 | .id_table = zr36067_pci_tbl, |
1479 | .probe = zoran_probe, | 1479 | .probe = zoran_probe, |
1480 | .remove = zoran_remove, | 1480 | .remove = __devexit_p(zoran_remove), |
1481 | }; | 1481 | }; |
1482 | 1482 | ||
1483 | static int __init zoran_init(void) | 1483 | static int __init zoran_init(void) |
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index ac169c9eb18d..fc976f42f432 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c | |||
@@ -882,9 +882,11 @@ static void zr364xx_disconnect(struct usb_interface *intf) | |||
882 | video_unregister_device(cam->vdev); | 882 | video_unregister_device(cam->vdev); |
883 | cam->vdev = NULL; | 883 | cam->vdev = NULL; |
884 | kfree(cam->buffer); | 884 | kfree(cam->buffer); |
885 | if (cam->framebuf) | 885 | cam->buffer = NULL; |
886 | vfree(cam->framebuf); | 886 | vfree(cam->framebuf); |
887 | cam->framebuf = NULL; | ||
887 | kfree(cam); | 888 | kfree(cam); |
889 | cam = NULL; | ||
888 | } | 890 | } |
889 | 891 | ||
890 | 892 | ||