diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-24 14:21:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-24 14:21:08 -0400 |
commit | c328d54cd4ad120d76284e46dcca6c6cf996154a (patch) | |
tree | 104c023be66faa5fce6e0a56c0a6d13c62fd21e5 /drivers/media/video | |
parent | 346ad4b7fe392571f19314f153db9151dbc1d82b (diff) | |
parent | b0166ab3a6ae6d7af8d9a21a7836154963c69a11 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (452 commits)
V4L/DVB (7731): tuner-xc2028: fix signal strength calculus
V4L/DVB (7730): tuner-xc2028: Fix SCODE load for MTS firmwares
V4L/DVB (7729): Fix VIDIOCGAP corruption in ivtv
V4L/DVB (7728): tea5761: bugzilla #10462: tea5761 autodetection code were broken
V4L/DVB (7726): cx23885: Enable cx23417 support on the HVR1800
V4L/DVB (7725): cx23885: Add generic cx23417 hardware encoder support
V4L/DVB (7723): pvrusb2: Clean up input selection list generation in V4L interface
V4L/DVB (7722): pvrusb2: Implement FM radio support for Gotview USB2.0 DVD 2
V4L/DVB (7721): pvrusb2: Restructure cx23416 firmware loading to have a common exit point
V4L/DVB (7720): pvrusb2: Fix bad error code on cx23416 firmware load failure
V4L/DVB (7719): pvrusb2: Implement input selection enforcement
V4L/DVB (7718): pvrusb2-dvb: update Kbuild selections
V4L/DVB (7717): pvrusb2-dvb: add DVB-T support for Hauppauge pvrusb2 model 73xxx
V4L/DVB (7716): pvrusb2: clean up global functions
V4L/DVB (7715): pvrusb2: Clean out all use of __FUNCTION__
V4L/DVB (7714): pvrusb2: Fix hang on module removal
V4L/DVB (7713): pvrusb2: Implement cleaner DVB kernel thread shutdown
V4L/DVB (7712): pvrusb2: Close connect/disconnect race
V4L/DVB (7711): pvrusb2: Fix race on module unload
V4L/DVB (7710): pvrusb2: Implement critical digital streaming quirk for onair devices
...
Diffstat (limited to 'drivers/media/video')
215 files changed, 18947 insertions, 5275 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 1832966f53f3..fe9a4cc14141 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -270,6 +270,15 @@ config VIDEO_SAA711X | |||
270 | To compile this driver as a module, choose M here: the | 270 | To compile this driver as a module, choose M here: the |
271 | module will be called saa7115. | 271 | module will be called saa7115. |
272 | 272 | ||
273 | config VIDEO_SAA717X | ||
274 | tristate "Philips SAA7171/3/4 audio/video decoders" | ||
275 | depends on VIDEO_V4L2 && I2C | ||
276 | ---help--- | ||
277 | Support for the Philips SAA7171/3/4 audio/video decoders. | ||
278 | |||
279 | To compile this driver as a module, choose M here: the | ||
280 | module will be called saa717x. | ||
281 | |||
273 | config VIDEO_SAA7191 | 282 | config VIDEO_SAA7191 |
274 | tristate "Philips SAA7191 video decoder" | 283 | tristate "Philips SAA7191 video decoder" |
275 | depends on VIDEO_V4L1 && I2C | 284 | depends on VIDEO_V4L1 && I2C |
@@ -689,6 +698,8 @@ source "drivers/media/video/cx88/Kconfig" | |||
689 | 698 | ||
690 | source "drivers/media/video/cx23885/Kconfig" | 699 | source "drivers/media/video/cx23885/Kconfig" |
691 | 700 | ||
701 | source "drivers/media/video/au0828/Kconfig" | ||
702 | |||
692 | source "drivers/media/video/ivtv/Kconfig" | 703 | source "drivers/media/video/ivtv/Kconfig" |
693 | 704 | ||
694 | config VIDEO_M32R_AR | 705 | config VIDEO_M32R_AR |
@@ -836,4 +847,49 @@ config USB_STKWEBCAM | |||
836 | 847 | ||
837 | endif # V4L_USB_DRIVERS | 848 | endif # V4L_USB_DRIVERS |
838 | 849 | ||
850 | config SOC_CAMERA | ||
851 | tristate "SoC camera support" | ||
852 | depends on VIDEO_V4L2 | ||
853 | select VIDEOBUF_DMA_SG | ||
854 | help | ||
855 | SoC Camera is a common API to several cameras, not connecting | ||
856 | over a bus like PCI or USB. For example some i2c camera connected | ||
857 | directly to the data bus of an SoC. | ||
858 | |||
859 | config SOC_CAMERA_MT9M001 | ||
860 | tristate "mt9m001 support" | ||
861 | depends on SOC_CAMERA | ||
862 | select GPIO_PCA953X if MT9M001_PCA9536_SWITCH | ||
863 | help | ||
864 | This driver supports MT9M001 cameras from Micron, monochrome | ||
865 | and colour models. | ||
866 | |||
867 | config MT9M001_PCA9536_SWITCH | ||
868 | bool "pca9536 datawidth switch for mt9m001" | ||
869 | depends on SOC_CAMERA_MT9M001 && GENERIC_GPIO | ||
870 | help | ||
871 | Select this if your MT9M001 camera uses a PCA9536 I2C GPIO | ||
872 | extender to switch between 8 and 10 bit datawidth modes | ||
873 | |||
874 | config SOC_CAMERA_MT9V022 | ||
875 | tristate "mt9v022 support" | ||
876 | depends on SOC_CAMERA | ||
877 | select GPIO_PCA953X if MT9V022_PCA9536_SWITCH | ||
878 | help | ||
879 | This driver supports MT9V022 cameras from Micron | ||
880 | |||
881 | config MT9V022_PCA9536_SWITCH | ||
882 | bool "pca9536 datawidth switch for mt9v022" | ||
883 | depends on SOC_CAMERA_MT9V022 && GENERIC_GPIO | ||
884 | help | ||
885 | Select this if your MT9V022 camera uses a PCA9536 I2C GPIO | ||
886 | extender to switch between 8 and 10 bit datawidth modes | ||
887 | |||
888 | config VIDEO_PXA27x | ||
889 | tristate "PXA27x Quick Capture Interface driver" | ||
890 | depends on VIDEO_DEV && PXA27x | ||
891 | select SOC_CAMERA | ||
892 | ---help--- | ||
893 | This is a v4l2 driver for the PXA27x Quick Capture Interface | ||
894 | |||
839 | endif # VIDEO_CAPTURE_DRIVERS | 895 | endif # VIDEO_CAPTURE_DRIVERS |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 3f209b32eeac..be14227f3726 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | zr36067-objs := zoran_procfs.o zoran_device.o \ | 5 | zr36067-objs := zoran_procfs.o zoran_device.o \ |
6 | zoran_driver.o zoran_card.o | 6 | zoran_driver.o zoran_card.o |
7 | tuner-objs := tuner-core.o tuner-types.o | 7 | tuner-objs := tuner-core.o |
8 | 8 | ||
9 | msp3400-objs := msp3400-driver.o msp3400-kthreads.o | 9 | msp3400-objs := msp3400-driver.o msp3400-kthreads.o |
10 | 10 | ||
@@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o | |||
38 | obj-$(CONFIG_VIDEO_SAA7111) += saa7111.o | 38 | obj-$(CONFIG_VIDEO_SAA7111) += saa7111.o |
39 | obj-$(CONFIG_VIDEO_SAA7114) += saa7114.o | 39 | obj-$(CONFIG_VIDEO_SAA7114) += saa7114.o |
40 | obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o | 40 | obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o |
41 | obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o | ||
41 | obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o | 42 | obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o |
42 | obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o | 43 | obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o |
43 | obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o | 44 | obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o |
@@ -87,6 +88,8 @@ obj-$(CONFIG_VIDEO_TUNER) += tuner.o | |||
87 | 88 | ||
88 | obj-$(CONFIG_TUNER_XC2028) += tuner-xc2028.o | 89 | obj-$(CONFIG_TUNER_XC2028) += tuner-xc2028.o |
89 | obj-$(CONFIG_TUNER_SIMPLE) += tuner-simple.o | 90 | obj-$(CONFIG_TUNER_SIMPLE) += tuner-simple.o |
91 | # tuner-types will be merged into tuner-simple, in the future | ||
92 | obj-$(CONFIG_TUNER_SIMPLE) += tuner-types.o | ||
90 | obj-$(CONFIG_TUNER_MT20XX) += mt20xx.o | 93 | obj-$(CONFIG_TUNER_MT20XX) += mt20xx.o |
91 | obj-$(CONFIG_TUNER_TDA8290) += tda8290.o | 94 | obj-$(CONFIG_TUNER_TDA8290) += tda8290.o |
92 | obj-$(CONFIG_TUNER_TEA5767) += tea5767.o | 95 | obj-$(CONFIG_TUNER_TEA5767) += tea5767.o |
@@ -135,5 +138,12 @@ obj-$(CONFIG_VIDEO_IVTV) += ivtv/ | |||
135 | obj-$(CONFIG_VIDEO_VIVI) += vivi.o | 138 | obj-$(CONFIG_VIDEO_VIVI) += vivi.o |
136 | obj-$(CONFIG_VIDEO_CX23885) += cx23885/ | 139 | obj-$(CONFIG_VIDEO_CX23885) += cx23885/ |
137 | 140 | ||
141 | obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o | ||
142 | obj-$(CONFIG_SOC_CAMERA) += soc_camera.o | ||
143 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o | ||
144 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o | ||
145 | |||
146 | obj-$(CONFIG_VIDEO_AU0828) += au0828/ | ||
147 | |||
138 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 148 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
139 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 149 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index fea2e723e34b..f794f2dbfb32 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c | |||
@@ -56,7 +56,7 @@ MODULE_LICENSE("GPL"); | |||
56 | #define I2C_NAME(x) (x)->name | 56 | #define I2C_NAME(x) (x)->name |
57 | 57 | ||
58 | 58 | ||
59 | static int debug = 0; | 59 | static int debug; |
60 | module_param(debug, int, 0); | 60 | module_param(debug, int, 0); |
61 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 61 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
62 | 62 | ||
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index 10d4d89623f1..8ee07a68f702 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c | |||
@@ -52,7 +52,7 @@ MODULE_LICENSE("GPL"); | |||
52 | #define I2C_NAME(s) (s)->name | 52 | #define I2C_NAME(s) (s)->name |
53 | 53 | ||
54 | 54 | ||
55 | static int debug = 0; | 55 | static int debug; |
56 | module_param(debug, int, 0); | 56 | module_param(debug, int, 0); |
57 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 57 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
58 | 58 | ||
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index c94a4d0f2804..8c7d1958856b 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
@@ -125,8 +125,8 @@ static unsigned char yuv[MAX_AR_FRAME_BYTES]; | |||
125 | /* default frequency */ | 125 | /* default frequency */ |
126 | #define DEFAULT_FREQ 50 /* 50 or 75 (MHz) is available as BCLK */ | 126 | #define DEFAULT_FREQ 50 /* 50 or 75 (MHz) is available as BCLK */ |
127 | static int freq = DEFAULT_FREQ; /* BCLK: available 50 or 70 (MHz) */ | 127 | static int freq = DEFAULT_FREQ; /* BCLK: available 50 or 70 (MHz) */ |
128 | static int vga = 0; /* default mode(0:QVGA mode, other:VGA mode) */ | 128 | static int vga; /* default mode(0:QVGA mode, other:VGA mode) */ |
129 | static int vga_interlace = 0; /* 0 is normal mode for, else interlace mode */ | 129 | static int vga_interlace; /* 0 is normal mode for, else interlace mode */ |
130 | module_param(freq, int, 0); | 130 | module_param(freq, int, 0); |
131 | module_param(vga, int, 0); | 131 | module_param(vga, int, 0); |
132 | module_param(vga_interlace, int, 0); | 132 | module_param(vga_interlace, int, 0); |
@@ -747,7 +747,9 @@ static const struct file_operations ar_fops = { | |||
747 | .release = video_exclusive_release, | 747 | .release = video_exclusive_release, |
748 | .read = ar_read, | 748 | .read = ar_read, |
749 | .ioctl = ar_ioctl, | 749 | .ioctl = ar_ioctl, |
750 | #ifdef CONFIG_COMPAT | ||
750 | .compat_ioctl = v4l_compat_ioctl32, | 751 | .compat_ioctl = v4l_compat_ioctl32, |
752 | #endif | ||
751 | .llseek = no_llseek, | 753 | .llseek = no_llseek, |
752 | }; | 754 | }; |
753 | 755 | ||
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig new file mode 100644 index 000000000000..c97c4bd24841 --- /dev/null +++ b/drivers/media/video/au0828/Kconfig | |||
@@ -0,0 +1,12 @@ | |||
1 | |||
2 | config VIDEO_AU0828 | ||
3 | tristate "Auvitek AU0828 support" | ||
4 | depends on VIDEO_DEV && I2C && INPUT | ||
5 | select I2C_ALGOBIT | ||
6 | select DVB_AU8522 if !DVB_FE_CUSTOMIZE | ||
7 | select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE | ||
8 | ---help--- | ||
9 | This is a video4linux driver for Auvitek's USB device. | ||
10 | |||
11 | To compile this driver as a module, choose M here: the | ||
12 | module will be called au0828 | ||
diff --git a/drivers/media/video/au0828/Makefile b/drivers/media/video/au0828/Makefile new file mode 100644 index 000000000000..9f4f572c89c5 --- /dev/null +++ b/drivers/media/video/au0828/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o | ||
2 | |||
3 | obj-$(CONFIG_VIDEO_AU0828) += au0828.o | ||
4 | |||
5 | EXTRA_CFLAGS += -Idrivers/media/video | ||
6 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | ||
7 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | ||
8 | |||
9 | EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) | ||
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c new file mode 100644 index 000000000000..8ca91f814277 --- /dev/null +++ b/drivers/media/video/au0828/au0828-cards.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | * Driver for the Auvitek USB bridge | ||
3 | * | ||
4 | * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> | ||
5 | * | ||
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 | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
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 "au0828.h" | ||
23 | #include "au0828-cards.h" | ||
24 | |||
25 | struct au0828_board au0828_boards[] = { | ||
26 | [AU0828_BOARD_UNKNOWN] = { | ||
27 | .name = "Unknown board", | ||
28 | }, | ||
29 | [AU0828_BOARD_HAUPPAUGE_HVR850] = { | ||
30 | .name = "Hauppauge HVR850", | ||
31 | }, | ||
32 | [AU0828_BOARD_HAUPPAUGE_HVR950Q] = { | ||
33 | .name = "Hauppauge HVR950Q", | ||
34 | }, | ||
35 | [AU0828_BOARD_DVICO_FUSIONHDTV7] = { | ||
36 | .name = "DViCO FusionHDTV USB", | ||
37 | }, | ||
38 | }; | ||
39 | const unsigned int au0828_bcount = ARRAY_SIZE(au0828_boards); | ||
40 | |||
41 | /* Tuner callback function for au0828 boards. Currently only needed | ||
42 | * for HVR1500Q, which has an xc5000 tuner. | ||
43 | */ | ||
44 | int au0828_tuner_callback(void *priv, int command, int arg) | ||
45 | { | ||
46 | struct au0828_dev *dev = priv; | ||
47 | |||
48 | dprintk(1, "%s()\n", __func__); | ||
49 | |||
50 | switch (dev->board) { | ||
51 | case AU0828_BOARD_HAUPPAUGE_HVR850: | ||
52 | case AU0828_BOARD_HAUPPAUGE_HVR950Q: | ||
53 | case AU0828_BOARD_DVICO_FUSIONHDTV7: | ||
54 | if (command == 0) { | ||
55 | /* Tuner Reset Command from xc5000 */ | ||
56 | /* Drive the tuner into reset and out */ | ||
57 | au0828_clear(dev, REG_001, 2); | ||
58 | mdelay(200); | ||
59 | au0828_set(dev, REG_001, 2); | ||
60 | mdelay(50); | ||
61 | return 0; | ||
62 | } else { | ||
63 | printk(KERN_ERR | ||
64 | "%s(): Unknown command.\n", __func__); | ||
65 | return -EINVAL; | ||
66 | } | ||
67 | break; | ||
68 | } | ||
69 | |||
70 | return 0; /* Should never be here */ | ||
71 | } | ||
72 | |||
73 | static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data) | ||
74 | { | ||
75 | struct tveeprom tv; | ||
76 | |||
77 | tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data); | ||
78 | |||
79 | /* Make sure we support the board model */ | ||
80 | switch (tv.model) { | ||
81 | case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */ | ||
82 | case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */ | ||
83 | break; | ||
84 | default: | ||
85 | printk(KERN_WARNING "%s: warning: " | ||
86 | "unknown hauppauge model #%d\n", __func__, tv.model); | ||
87 | break; | ||
88 | } | ||
89 | |||
90 | printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", | ||
91 | __func__, tv.model); | ||
92 | } | ||
93 | |||
94 | void au0828_card_setup(struct au0828_dev *dev) | ||
95 | { | ||
96 | static u8 eeprom[256]; | ||
97 | |||
98 | dprintk(1, "%s()\n", __func__); | ||
99 | |||
100 | if (dev->i2c_rc == 0) { | ||
101 | dev->i2c_client.addr = 0xa0 >> 1; | ||
102 | tveeprom_read(&dev->i2c_client, eeprom, sizeof(eeprom)); | ||
103 | } | ||
104 | |||
105 | switch (dev->board) { | ||
106 | case AU0828_BOARD_HAUPPAUGE_HVR850: | ||
107 | case AU0828_BOARD_HAUPPAUGE_HVR950Q: | ||
108 | if (dev->i2c_rc == 0) | ||
109 | hauppauge_eeprom(dev, eeprom+0xa0); | ||
110 | break; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * The bridge has between 8 and 12 gpios. | ||
116 | * Regs 1 and 0 deal with output enables. | ||
117 | * Regs 3 and 2 deal with direction. | ||
118 | */ | ||
119 | void au0828_gpio_setup(struct au0828_dev *dev) | ||
120 | { | ||
121 | dprintk(1, "%s()\n", __func__); | ||
122 | |||
123 | switch (dev->board) { | ||
124 | case AU0828_BOARD_HAUPPAUGE_HVR850: | ||
125 | case AU0828_BOARD_HAUPPAUGE_HVR950Q: | ||
126 | /* GPIO's | ||
127 | * 4 - CS5340 | ||
128 | * 5 - AU8522 Demodulator | ||
129 | * 6 - eeprom W/P | ||
130 | * 9 - XC5000 Tuner | ||
131 | */ | ||
132 | |||
133 | /* Into reset */ | ||
134 | au0828_write(dev, REG_003, 0x02); | ||
135 | au0828_write(dev, REG_002, 0x88 | 0x20); | ||
136 | au0828_write(dev, REG_001, 0x0); | ||
137 | au0828_write(dev, REG_000, 0x0); | ||
138 | msleep(100); | ||
139 | |||
140 | /* Out of reset */ | ||
141 | au0828_write(dev, REG_003, 0x02); | ||
142 | au0828_write(dev, REG_001, 0x02); | ||
143 | au0828_write(dev, REG_002, 0x88 | 0x20); | ||
144 | au0828_write(dev, REG_000, 0x88 | 0x20 | 0x40); | ||
145 | msleep(250); | ||
146 | break; | ||
147 | case AU0828_BOARD_DVICO_FUSIONHDTV7: | ||
148 | /* GPIO's | ||
149 | * 6 - ? | ||
150 | * 8 - AU8522 Demodulator | ||
151 | * 9 - XC5000 Tuner | ||
152 | */ | ||
153 | |||
154 | /* Into reset */ | ||
155 | au0828_write(dev, REG_003, 0x02); | ||
156 | au0828_write(dev, REG_002, 0xa0); | ||
157 | au0828_write(dev, REG_001, 0x0); | ||
158 | au0828_write(dev, REG_000, 0x0); | ||
159 | msleep(100); | ||
160 | |||
161 | /* Out of reset */ | ||
162 | au0828_write(dev, REG_003, 0x02); | ||
163 | au0828_write(dev, REG_002, 0xa0); | ||
164 | au0828_write(dev, REG_001, 0x02); | ||
165 | au0828_write(dev, REG_000, 0xa0); | ||
166 | msleep(250); | ||
167 | break; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | /* table of devices that work with this driver */ | ||
172 | struct usb_device_id au0828_usb_id_table [] = { | ||
173 | { USB_DEVICE(0x2040, 0x7200), | ||
174 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, | ||
175 | { USB_DEVICE(0x2040, 0x7240), | ||
176 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR850 }, | ||
177 | { USB_DEVICE(0x0fe9, 0xd620), | ||
178 | .driver_info = AU0828_BOARD_DVICO_FUSIONHDTV7 }, | ||
179 | { }, | ||
180 | }; | ||
181 | |||
182 | MODULE_DEVICE_TABLE(usb, au0828_usb_id_table); | ||
diff --git a/drivers/media/video/au0828/au0828-cards.h b/drivers/media/video/au0828/au0828-cards.h new file mode 100644 index 000000000000..e26f54a961d0 --- /dev/null +++ b/drivers/media/video/au0828/au0828-cards.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Driver for the Auvitek USB bridge | ||
3 | * | ||
4 | * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> | ||
5 | * | ||
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 | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
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 | #define AU0828_BOARD_UNKNOWN 0 | ||
23 | #define AU0828_BOARD_HAUPPAUGE_HVR950Q 1 | ||
24 | #define AU0828_BOARD_HAUPPAUGE_HVR850 2 | ||
25 | #define AU0828_BOARD_DVICO_FUSIONHDTV7 3 | ||
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c new file mode 100644 index 000000000000..e65d5642cb1d --- /dev/null +++ b/drivers/media/video/au0828/au0828-core.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | * Driver for the Auvitek USB bridge | ||
3 | * | ||
4 | * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> | ||
5 | * | ||
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 | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
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/module.h> | ||
23 | #include <linux/videodev2.h> | ||
24 | #include <media/v4l2-common.h> | ||
25 | #include <linux/mutex.h> | ||
26 | |||
27 | #include "au0828.h" | ||
28 | |||
29 | /* | ||
30 | * 1 = General debug messages | ||
31 | * 2 = USB handling | ||
32 | * 4 = I2C related | ||
33 | * 8 = Bridge related | ||
34 | */ | ||
35 | unsigned int debug; | ||
36 | module_param(debug, int, 0644); | ||
37 | MODULE_PARM_DESC(debug, "enable debug messages"); | ||
38 | |||
39 | unsigned int usb_debug; | ||
40 | module_param(usb_debug, int, 0644); | ||
41 | MODULE_PARM_DESC(usb_debug, "enable usb debug messages"); | ||
42 | |||
43 | unsigned int bridge_debug; | ||
44 | module_param(bridge_debug, int, 0644); | ||
45 | MODULE_PARM_DESC(bridge_debug, "enable bridge debug messages"); | ||
46 | |||
47 | #define _AU0828_BULKPIPE 0x03 | ||
48 | #define _BULKPIPESIZE 0xffff | ||
49 | |||
50 | static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value, | ||
51 | u16 index, unsigned char *cp, u16 size); | ||
52 | static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value, | ||
53 | u16 index, unsigned char *cp, u16 size); | ||
54 | |||
55 | /* USB Direction */ | ||
56 | #define CMD_REQUEST_IN 0x00 | ||
57 | #define CMD_REQUEST_OUT 0x01 | ||
58 | |||
59 | u32 au0828_readreg(struct au0828_dev *dev, u16 reg) | ||
60 | { | ||
61 | recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, dev->ctrlmsg, 1); | ||
62 | dprintk(8, "%s(0x%x) = 0x%x\n", __func__, reg, dev->ctrlmsg[0]); | ||
63 | return dev->ctrlmsg[0]; | ||
64 | } | ||
65 | |||
66 | u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val) | ||
67 | { | ||
68 | dprintk(8, "%s(0x%x, 0x%x)\n", __func__, reg, val); | ||
69 | return send_control_msg(dev, CMD_REQUEST_OUT, val, reg, | ||
70 | dev->ctrlmsg, 0); | ||
71 | } | ||
72 | |||
73 | static void cmd_msg_dump(struct au0828_dev *dev) | ||
74 | { | ||
75 | int i; | ||
76 | |||
77 | for (i = 0; i < sizeof(dev->ctrlmsg); i += 16) | ||
78 | dprintk(2, "%s() %02x %02x %02x %02x %02x %02x %02x %02x " | ||
79 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
80 | __func__, | ||
81 | dev->ctrlmsg[i+0], dev->ctrlmsg[i+1], | ||
82 | dev->ctrlmsg[i+2], dev->ctrlmsg[i+3], | ||
83 | dev->ctrlmsg[i+4], dev->ctrlmsg[i+5], | ||
84 | dev->ctrlmsg[i+6], dev->ctrlmsg[i+7], | ||
85 | dev->ctrlmsg[i+8], dev->ctrlmsg[i+9], | ||
86 | dev->ctrlmsg[i+10], dev->ctrlmsg[i+11], | ||
87 | dev->ctrlmsg[i+12], dev->ctrlmsg[i+13], | ||
88 | dev->ctrlmsg[i+14], dev->ctrlmsg[i+15]); | ||
89 | } | ||
90 | |||
91 | static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value, | ||
92 | u16 index, unsigned char *cp, u16 size) | ||
93 | { | ||
94 | int status = -ENODEV; | ||
95 | mutex_lock(&dev->mutex); | ||
96 | if (dev->usbdev) { | ||
97 | |||
98 | /* cp must be memory that has been allocated by kmalloc */ | ||
99 | status = usb_control_msg(dev->usbdev, | ||
100 | usb_sndctrlpipe(dev->usbdev, 0), | ||
101 | request, | ||
102 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
103 | value, index, | ||
104 | cp, size, 1000); | ||
105 | |||
106 | status = min(status, 0); | ||
107 | |||
108 | if (status < 0) { | ||
109 | printk(KERN_ERR "%s() Failed sending control message, error %d.\n", | ||
110 | __func__, status); | ||
111 | } | ||
112 | |||
113 | } | ||
114 | mutex_unlock(&dev->mutex); | ||
115 | return status; | ||
116 | } | ||
117 | |||
118 | static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value, | ||
119 | u16 index, unsigned char *cp, u16 size) | ||
120 | { | ||
121 | int status = -ENODEV; | ||
122 | mutex_lock(&dev->mutex); | ||
123 | if (dev->usbdev) { | ||
124 | |||
125 | memset(dev->ctrlmsg, 0, sizeof(dev->ctrlmsg)); | ||
126 | |||
127 | /* cp must be memory that has been allocated by kmalloc */ | ||
128 | status = usb_control_msg(dev->usbdev, | ||
129 | usb_rcvctrlpipe(dev->usbdev, 0), | ||
130 | request, | ||
131 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
132 | value, index, | ||
133 | cp, size, 1000); | ||
134 | |||
135 | status = min(status, 0); | ||
136 | |||
137 | if (status < 0) { | ||
138 | printk(KERN_ERR "%s() Failed receiving control message, error %d.\n", | ||
139 | __func__, status); | ||
140 | } else | ||
141 | cmd_msg_dump(dev); | ||
142 | } | ||
143 | mutex_unlock(&dev->mutex); | ||
144 | return status; | ||
145 | } | ||
146 | |||
147 | static void au0828_usb_disconnect(struct usb_interface *interface) | ||
148 | { | ||
149 | struct au0828_dev *dev = usb_get_intfdata(interface); | ||
150 | |||
151 | dprintk(1, "%s()\n", __func__); | ||
152 | |||
153 | /* Digital TV */ | ||
154 | au0828_dvb_unregister(dev); | ||
155 | |||
156 | /* I2C */ | ||
157 | au0828_i2c_unregister(dev); | ||
158 | |||
159 | usb_set_intfdata(interface, NULL); | ||
160 | |||
161 | mutex_lock(&dev->mutex); | ||
162 | dev->usbdev = NULL; | ||
163 | mutex_unlock(&dev->mutex); | ||
164 | |||
165 | kfree(dev); | ||
166 | |||
167 | } | ||
168 | |||
169 | static int au0828_usb_probe(struct usb_interface *interface, | ||
170 | const struct usb_device_id *id) | ||
171 | { | ||
172 | int ifnum; | ||
173 | struct au0828_dev *dev; | ||
174 | struct usb_device *usbdev = interface_to_usbdev(interface); | ||
175 | |||
176 | ifnum = interface->altsetting->desc.bInterfaceNumber; | ||
177 | |||
178 | if (ifnum != 0) | ||
179 | return -ENODEV; | ||
180 | |||
181 | dprintk(1, "%s() vendor id 0x%x device id 0x%x ifnum:%d\n", __func__, | ||
182 | le16_to_cpu(usbdev->descriptor.idVendor), | ||
183 | le16_to_cpu(usbdev->descriptor.idProduct), | ||
184 | ifnum); | ||
185 | |||
186 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
187 | if (dev == NULL) { | ||
188 | printk(KERN_ERR "%s() Unable to allocate memory\n", __func__); | ||
189 | return -ENOMEM; | ||
190 | } | ||
191 | |||
192 | mutex_init(&dev->mutex); | ||
193 | mutex_init(&dev->dvb.lock); | ||
194 | dev->usbdev = usbdev; | ||
195 | dev->board = id->driver_info; | ||
196 | |||
197 | usb_set_intfdata(interface, dev); | ||
198 | |||
199 | /* Power Up the bridge */ | ||
200 | au0828_write(dev, REG_600, 1 << 4); | ||
201 | |||
202 | /* Bring up the GPIO's and supporting devices */ | ||
203 | au0828_gpio_setup(dev); | ||
204 | |||
205 | /* I2C */ | ||
206 | au0828_i2c_register(dev); | ||
207 | |||
208 | /* Setup */ | ||
209 | au0828_card_setup(dev); | ||
210 | |||
211 | /* Digital TV */ | ||
212 | au0828_dvb_register(dev); | ||
213 | |||
214 | printk(KERN_INFO "Registered device AU0828 [%s]\n", | ||
215 | au0828_boards[dev->board].name == NULL ? "Unset" : | ||
216 | au0828_boards[dev->board].name); | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static struct usb_driver au0828_usb_driver = { | ||
222 | .name = DRIVER_NAME, | ||
223 | .probe = au0828_usb_probe, | ||
224 | .disconnect = au0828_usb_disconnect, | ||
225 | .id_table = au0828_usb_id_table, | ||
226 | }; | ||
227 | |||
228 | static int __init au0828_init(void) | ||
229 | { | ||
230 | int ret; | ||
231 | |||
232 | if (debug) | ||
233 | printk(KERN_INFO "%s() Debugging is enabled\n", __func__); | ||
234 | |||
235 | if (usb_debug) { | ||
236 | printk(KERN_INFO "%s() USB Debugging is enabled\n", __func__); | ||
237 | debug |= 2; | ||
238 | } | ||
239 | |||
240 | if (i2c_debug) { | ||
241 | printk(KERN_INFO "%s() I2C Debugging is enabled\n", __func__); | ||
242 | debug |= 4; | ||
243 | } | ||
244 | |||
245 | if (bridge_debug) { | ||
246 | printk(KERN_INFO "%s() Bridge Debugging is enabled\n", | ||
247 | __func__); | ||
248 | debug |= 8; | ||
249 | } | ||
250 | |||
251 | printk(KERN_INFO "au0828 driver loaded\n"); | ||
252 | |||
253 | ret = usb_register(&au0828_usb_driver); | ||
254 | if (ret) | ||
255 | printk(KERN_ERR "usb_register failed, error = %d\n", ret); | ||
256 | |||
257 | return ret; | ||
258 | } | ||
259 | |||
260 | static void __exit au0828_exit(void) | ||
261 | { | ||
262 | usb_deregister(&au0828_usb_driver); | ||
263 | } | ||
264 | |||
265 | module_init(au0828_init); | ||
266 | module_exit(au0828_exit); | ||
267 | |||
268 | MODULE_DESCRIPTION("Driver for Auvitek AU0828 based products"); | ||
269 | MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); | ||
270 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c new file mode 100644 index 000000000000..85d0ae9a322f --- /dev/null +++ b/drivers/media/video/au0828/au0828-dvb.c | |||
@@ -0,0 +1,373 @@ | |||
1 | /* | ||
2 | * Driver for the Auvitek USB bridge | ||
3 | * | ||
4 | * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> | ||
5 | * | ||
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 | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
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/module.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/suspend.h> | ||
26 | #include <media/v4l2-common.h> | ||
27 | |||
28 | #include "au0828.h" | ||
29 | #include "au8522.h" | ||
30 | #include "xc5000.h" | ||
31 | |||
32 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
33 | |||
34 | #define _AU0828_BULKPIPE 0x83 | ||
35 | #define _BULKPIPESIZE 0xe522 | ||
36 | |||
37 | static struct au8522_config hauppauge_hvr950q_config = { | ||
38 | .demod_address = 0x8e >> 1, | ||
39 | .status_mode = AU8522_DEMODLOCKING, | ||
40 | }; | ||
41 | |||
42 | static struct xc5000_config hauppauge_hvr950q_tunerconfig = { | ||
43 | .i2c_address = 0x61, | ||
44 | .if_khz = 6000, | ||
45 | .tuner_callback = au0828_tuner_callback | ||
46 | }; | ||
47 | |||
48 | /*-------------------------------------------------------------------*/ | ||
49 | static void urb_completion(struct urb *purb) | ||
50 | { | ||
51 | u8 *ptr; | ||
52 | struct au0828_dev *dev = purb->context; | ||
53 | int ptype = usb_pipetype(purb->pipe); | ||
54 | |||
55 | dprintk(2, "%s()\n", __func__); | ||
56 | |||
57 | if (!dev) | ||
58 | return; | ||
59 | |||
60 | if (dev->urb_streaming == 0) | ||
61 | return; | ||
62 | |||
63 | if (ptype != PIPE_BULK) { | ||
64 | printk(KERN_ERR "%s() Unsupported URB type %d\n", | ||
65 | __func__, ptype); | ||
66 | return; | ||
67 | } | ||
68 | |||
69 | ptr = (u8 *)purb->transfer_buffer; | ||
70 | |||
71 | /* Feed the transport payload into the kernel demux */ | ||
72 | dvb_dmx_swfilter_packets(&dev->dvb.demux, | ||
73 | purb->transfer_buffer, purb->actual_length / 188); | ||
74 | |||
75 | /* Clean the buffer before we requeue */ | ||
76 | memset(purb->transfer_buffer, 0, URB_BUFSIZE); | ||
77 | |||
78 | /* Requeue URB */ | ||
79 | usb_submit_urb(purb, GFP_ATOMIC); | ||
80 | } | ||
81 | |||
82 | static int stop_urb_transfer(struct au0828_dev *dev) | ||
83 | { | ||
84 | int i; | ||
85 | |||
86 | dprintk(2, "%s()\n", __func__); | ||
87 | |||
88 | for (i = 0; i < URB_COUNT; i++) { | ||
89 | usb_kill_urb(dev->urbs[i]); | ||
90 | kfree(dev->urbs[i]->transfer_buffer); | ||
91 | usb_free_urb(dev->urbs[i]); | ||
92 | } | ||
93 | |||
94 | dev->urb_streaming = 0; | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static int start_urb_transfer(struct au0828_dev *dev) | ||
100 | { | ||
101 | struct urb *purb; | ||
102 | int i, ret = -ENOMEM; | ||
103 | |||
104 | dprintk(2, "%s()\n", __func__); | ||
105 | |||
106 | if (dev->urb_streaming) { | ||
107 | dprintk(2, "%s: iso xfer already running!\n", __func__); | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | for (i = 0; i < URB_COUNT; i++) { | ||
112 | |||
113 | dev->urbs[i] = usb_alloc_urb(0, GFP_KERNEL); | ||
114 | if (!dev->urbs[i]) | ||
115 | goto err; | ||
116 | |||
117 | purb = dev->urbs[i]; | ||
118 | |||
119 | purb->transfer_buffer = kzalloc(URB_BUFSIZE, GFP_KERNEL); | ||
120 | if (!purb->transfer_buffer) { | ||
121 | usb_free_urb(purb); | ||
122 | dev->urbs[i] = 0; | ||
123 | goto err; | ||
124 | } | ||
125 | |||
126 | purb->status = -EINPROGRESS; | ||
127 | usb_fill_bulk_urb(purb, | ||
128 | dev->usbdev, | ||
129 | usb_rcvbulkpipe(dev->usbdev, _AU0828_BULKPIPE), | ||
130 | purb->transfer_buffer, | ||
131 | URB_BUFSIZE, | ||
132 | urb_completion, | ||
133 | dev); | ||
134 | |||
135 | } | ||
136 | |||
137 | for (i = 0; i < URB_COUNT; i++) { | ||
138 | ret = usb_submit_urb(dev->urbs[i], GFP_ATOMIC); | ||
139 | if (ret != 0) { | ||
140 | stop_urb_transfer(dev); | ||
141 | printk(KERN_ERR "%s: failed urb submission, " | ||
142 | "err = %d\n", __func__, ret); | ||
143 | return ret; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | dev->urb_streaming = 1; | ||
148 | ret = 0; | ||
149 | |||
150 | err: | ||
151 | return ret; | ||
152 | } | ||
153 | |||
154 | static int au0828_dvb_start_feed(struct dvb_demux_feed *feed) | ||
155 | { | ||
156 | struct dvb_demux *demux = feed->demux; | ||
157 | struct au0828_dev *dev = (struct au0828_dev *) demux->priv; | ||
158 | struct au0828_dvb *dvb = &dev->dvb; | ||
159 | int ret = 0; | ||
160 | |||
161 | dprintk(1, "%s()\n", __func__); | ||
162 | |||
163 | if (!demux->dmx.frontend) | ||
164 | return -EINVAL; | ||
165 | |||
166 | if (dvb) { | ||
167 | mutex_lock(&dvb->lock); | ||
168 | if (dvb->feeding++ == 0) { | ||
169 | /* Start transport */ | ||
170 | au0828_write(dev, 0x608, 0x90); | ||
171 | au0828_write(dev, 0x609, 0x72); | ||
172 | au0828_write(dev, 0x60a, 0x71); | ||
173 | au0828_write(dev, 0x60b, 0x01); | ||
174 | ret = start_urb_transfer(dev); | ||
175 | } | ||
176 | mutex_unlock(&dvb->lock); | ||
177 | } | ||
178 | |||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed) | ||
183 | { | ||
184 | struct dvb_demux *demux = feed->demux; | ||
185 | struct au0828_dev *dev = (struct au0828_dev *) demux->priv; | ||
186 | struct au0828_dvb *dvb = &dev->dvb; | ||
187 | int ret = 0; | ||
188 | |||
189 | dprintk(1, "%s()\n", __func__); | ||
190 | |||
191 | if (dvb) { | ||
192 | mutex_lock(&dvb->lock); | ||
193 | if (--dvb->feeding == 0) { | ||
194 | /* Stop transport */ | ||
195 | au0828_write(dev, 0x608, 0x00); | ||
196 | au0828_write(dev, 0x609, 0x00); | ||
197 | au0828_write(dev, 0x60a, 0x00); | ||
198 | au0828_write(dev, 0x60b, 0x00); | ||
199 | ret = stop_urb_transfer(dev); | ||
200 | } | ||
201 | mutex_unlock(&dvb->lock); | ||
202 | } | ||
203 | |||
204 | return ret; | ||
205 | } | ||
206 | |||
207 | int dvb_register(struct au0828_dev *dev) | ||
208 | { | ||
209 | struct au0828_dvb *dvb = &dev->dvb; | ||
210 | int result; | ||
211 | |||
212 | dprintk(1, "%s()\n", __func__); | ||
213 | |||
214 | /* register adapter */ | ||
215 | result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE, | ||
216 | &dev->usbdev->dev, adapter_nr); | ||
217 | if (result < 0) { | ||
218 | printk(KERN_ERR "%s: dvb_register_adapter failed " | ||
219 | "(errno = %d)\n", DRIVER_NAME, result); | ||
220 | goto fail_adapter; | ||
221 | } | ||
222 | dvb->adapter.priv = dev; | ||
223 | |||
224 | /* register frontend */ | ||
225 | result = dvb_register_frontend(&dvb->adapter, dvb->frontend); | ||
226 | if (result < 0) { | ||
227 | printk(KERN_ERR "%s: dvb_register_frontend failed " | ||
228 | "(errno = %d)\n", DRIVER_NAME, result); | ||
229 | goto fail_frontend; | ||
230 | } | ||
231 | |||
232 | /* register demux stuff */ | ||
233 | dvb->demux.dmx.capabilities = | ||
234 | DMX_TS_FILTERING | DMX_SECTION_FILTERING | | ||
235 | DMX_MEMORY_BASED_FILTERING; | ||
236 | dvb->demux.priv = dev; | ||
237 | dvb->demux.filternum = 256; | ||
238 | dvb->demux.feednum = 256; | ||
239 | dvb->demux.start_feed = au0828_dvb_start_feed; | ||
240 | dvb->demux.stop_feed = au0828_dvb_stop_feed; | ||
241 | result = dvb_dmx_init(&dvb->demux); | ||
242 | if (result < 0) { | ||
243 | printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n", | ||
244 | DRIVER_NAME, result); | ||
245 | goto fail_dmx; | ||
246 | } | ||
247 | |||
248 | dvb->dmxdev.filternum = 256; | ||
249 | dvb->dmxdev.demux = &dvb->demux.dmx; | ||
250 | dvb->dmxdev.capabilities = 0; | ||
251 | result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); | ||
252 | if (result < 0) { | ||
253 | printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n", | ||
254 | DRIVER_NAME, result); | ||
255 | goto fail_dmxdev; | ||
256 | } | ||
257 | |||
258 | dvb->fe_hw.source = DMX_FRONTEND_0; | ||
259 | result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
260 | if (result < 0) { | ||
261 | printk(KERN_ERR "%s: add_frontend failed " | ||
262 | "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result); | ||
263 | goto fail_fe_hw; | ||
264 | } | ||
265 | |||
266 | dvb->fe_mem.source = DMX_MEMORY_FE; | ||
267 | result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
268 | if (result < 0) { | ||
269 | printk(KERN_ERR "%s: add_frontend failed " | ||
270 | "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result); | ||
271 | goto fail_fe_mem; | ||
272 | } | ||
273 | |||
274 | result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
275 | if (result < 0) { | ||
276 | printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n", | ||
277 | DRIVER_NAME, result); | ||
278 | goto fail_fe_conn; | ||
279 | } | ||
280 | |||
281 | /* register network adapter */ | ||
282 | dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); | ||
283 | return 0; | ||
284 | |||
285 | fail_fe_conn: | ||
286 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
287 | fail_fe_mem: | ||
288 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
289 | fail_fe_hw: | ||
290 | dvb_dmxdev_release(&dvb->dmxdev); | ||
291 | fail_dmxdev: | ||
292 | dvb_dmx_release(&dvb->demux); | ||
293 | fail_dmx: | ||
294 | dvb_unregister_frontend(dvb->frontend); | ||
295 | fail_frontend: | ||
296 | dvb_frontend_detach(dvb->frontend); | ||
297 | dvb_unregister_adapter(&dvb->adapter); | ||
298 | fail_adapter: | ||
299 | return result; | ||
300 | } | ||
301 | |||
302 | void au0828_dvb_unregister(struct au0828_dev *dev) | ||
303 | { | ||
304 | struct au0828_dvb *dvb = &dev->dvb; | ||
305 | |||
306 | dprintk(1, "%s()\n", __func__); | ||
307 | |||
308 | if (dvb->frontend == NULL) | ||
309 | return; | ||
310 | |||
311 | dvb_net_release(&dvb->net); | ||
312 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
313 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
314 | dvb_dmxdev_release(&dvb->dmxdev); | ||
315 | dvb_dmx_release(&dvb->demux); | ||
316 | dvb_unregister_frontend(dvb->frontend); | ||
317 | dvb_frontend_detach(dvb->frontend); | ||
318 | dvb_unregister_adapter(&dvb->adapter); | ||
319 | } | ||
320 | |||
321 | /* All the DVB attach calls go here, this function get's modified | ||
322 | * for each new card. No other function in this file needs | ||
323 | * to change. | ||
324 | */ | ||
325 | int au0828_dvb_register(struct au0828_dev *dev) | ||
326 | { | ||
327 | struct au0828_dvb *dvb = &dev->dvb; | ||
328 | int ret; | ||
329 | |||
330 | dprintk(1, "%s()\n", __func__); | ||
331 | |||
332 | /* init frontend */ | ||
333 | switch (dev->board) { | ||
334 | case AU0828_BOARD_HAUPPAUGE_HVR850: | ||
335 | case AU0828_BOARD_HAUPPAUGE_HVR950Q: | ||
336 | case AU0828_BOARD_DVICO_FUSIONHDTV7: | ||
337 | dvb->frontend = dvb_attach(au8522_attach, | ||
338 | &hauppauge_hvr950q_config, | ||
339 | &dev->i2c_adap); | ||
340 | if (dvb->frontend != NULL) { | ||
341 | hauppauge_hvr950q_tunerconfig.priv = dev; | ||
342 | dvb_attach(xc5000_attach, dvb->frontend, | ||
343 | &dev->i2c_adap, | ||
344 | &hauppauge_hvr950q_tunerconfig); | ||
345 | } | ||
346 | break; | ||
347 | default: | ||
348 | printk(KERN_WARNING "The frontend of your DVB/ATSC card " | ||
349 | "isn't supported yet\n"); | ||
350 | break; | ||
351 | } | ||
352 | if (NULL == dvb->frontend) { | ||
353 | printk(KERN_ERR "%s() Frontend initialization failed\n", | ||
354 | __func__); | ||
355 | return -1; | ||
356 | } | ||
357 | |||
358 | /* Put the analog decoder in standby to keep it quiet */ | ||
359 | au0828_call_i2c_clients(dev, TUNER_SET_STANDBY, NULL); | ||
360 | |||
361 | if (dvb->frontend->ops.analog_ops.standby) | ||
362 | dvb->frontend->ops.analog_ops.standby(dvb->frontend); | ||
363 | |||
364 | /* register everything */ | ||
365 | ret = dvb_register(dev); | ||
366 | if (ret < 0) { | ||
367 | if (dvb->frontend->ops.release) | ||
368 | dvb->frontend->ops.release(dvb->frontend); | ||
369 | return ret; | ||
370 | } | ||
371 | |||
372 | return 0; | ||
373 | } | ||
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c new file mode 100644 index 000000000000..94c8b74a6651 --- /dev/null +++ b/drivers/media/video/au0828/au0828-i2c.c | |||
@@ -0,0 +1,385 @@ | |||
1 | /* | ||
2 | * Driver for the Auvitek AU0828 USB bridge | ||
3 | * | ||
4 | * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> | ||
5 | * | ||
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 | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
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/module.h> | ||
23 | #include <linux/moduleparam.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/io.h> | ||
27 | |||
28 | #include "au0828.h" | ||
29 | |||
30 | #include <media/v4l2-common.h> | ||
31 | |||
32 | unsigned int i2c_debug; | ||
33 | module_param(i2c_debug, int, 0444); | ||
34 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | ||
35 | |||
36 | unsigned int i2c_scan; | ||
37 | module_param(i2c_scan, int, 0444); | ||
38 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); | ||
39 | |||
40 | #define I2C_WAIT_DELAY 512 | ||
41 | #define I2C_WAIT_RETRY 64 | ||
42 | |||
43 | static inline int i2c_slave_did_write_ack(struct i2c_adapter *i2c_adap) | ||
44 | { | ||
45 | struct au0828_dev *dev = i2c_adap->algo_data; | ||
46 | return au0828_read(dev, REG_201) & 0x08 ? 0 : 1; | ||
47 | } | ||
48 | |||
49 | static inline int i2c_slave_did_read_ack(struct i2c_adapter *i2c_adap) | ||
50 | { | ||
51 | struct au0828_dev *dev = i2c_adap->algo_data; | ||
52 | return au0828_read(dev, REG_201) & 0x02 ? 0 : 1; | ||
53 | } | ||
54 | |||
55 | static int i2c_wait_read_ack(struct i2c_adapter *i2c_adap) | ||
56 | { | ||
57 | int count; | ||
58 | |||
59 | for (count = 0; count < I2C_WAIT_RETRY; count++) { | ||
60 | if (!i2c_slave_did_read_ack(i2c_adap)) | ||
61 | break; | ||
62 | udelay(I2C_WAIT_DELAY); | ||
63 | } | ||
64 | |||
65 | if (I2C_WAIT_RETRY == count) | ||
66 | return 0; | ||
67 | |||
68 | return 1; | ||
69 | } | ||
70 | |||
71 | static inline int i2c_is_read_busy(struct i2c_adapter *i2c_adap) | ||
72 | { | ||
73 | struct au0828_dev *dev = i2c_adap->algo_data; | ||
74 | return au0828_read(dev, REG_201) & 0x01 ? 0 : 1; | ||
75 | } | ||
76 | |||
77 | static int i2c_wait_read_done(struct i2c_adapter *i2c_adap) | ||
78 | { | ||
79 | int count; | ||
80 | |||
81 | for (count = 0; count < I2C_WAIT_RETRY; count++) { | ||
82 | if (!i2c_is_read_busy(i2c_adap)) | ||
83 | break; | ||
84 | udelay(I2C_WAIT_DELAY); | ||
85 | } | ||
86 | |||
87 | if (I2C_WAIT_RETRY == count) | ||
88 | return 0; | ||
89 | |||
90 | return 1; | ||
91 | } | ||
92 | |||
93 | static inline int i2c_is_write_done(struct i2c_adapter *i2c_adap) | ||
94 | { | ||
95 | struct au0828_dev *dev = i2c_adap->algo_data; | ||
96 | return au0828_read(dev, REG_201) & 0x04 ? 1 : 0; | ||
97 | } | ||
98 | |||
99 | static int i2c_wait_write_done(struct i2c_adapter *i2c_adap) | ||
100 | { | ||
101 | int count; | ||
102 | |||
103 | for (count = 0; count < I2C_WAIT_RETRY; count++) { | ||
104 | if (i2c_is_write_done(i2c_adap)) | ||
105 | break; | ||
106 | udelay(I2C_WAIT_DELAY); | ||
107 | } | ||
108 | |||
109 | if (I2C_WAIT_RETRY == count) | ||
110 | return 0; | ||
111 | |||
112 | return 1; | ||
113 | } | ||
114 | |||
115 | static inline int i2c_is_busy(struct i2c_adapter *i2c_adap) | ||
116 | { | ||
117 | struct au0828_dev *dev = i2c_adap->algo_data; | ||
118 | return au0828_read(dev, REG_201) & 0x10 ? 1 : 0; | ||
119 | } | ||
120 | |||
121 | static int i2c_wait_done(struct i2c_adapter *i2c_adap) | ||
122 | { | ||
123 | int count; | ||
124 | |||
125 | for (count = 0; count < I2C_WAIT_RETRY; count++) { | ||
126 | if (!i2c_is_busy(i2c_adap)) | ||
127 | break; | ||
128 | udelay(I2C_WAIT_DELAY); | ||
129 | } | ||
130 | |||
131 | if (I2C_WAIT_RETRY == count) | ||
132 | return 0; | ||
133 | |||
134 | return 1; | ||
135 | } | ||
136 | |||
137 | /* FIXME: Implement join handling correctly */ | ||
138 | static int i2c_sendbytes(struct i2c_adapter *i2c_adap, | ||
139 | const struct i2c_msg *msg, int joined_rlen) | ||
140 | { | ||
141 | int i, strobe = 0; | ||
142 | struct au0828_dev *dev = i2c_adap->algo_data; | ||
143 | |||
144 | dprintk(4, "%s()\n", __func__); | ||
145 | |||
146 | au0828_write(dev, REG_2FF, 0x01); | ||
147 | au0828_write(dev, REG_202, 0x07); | ||
148 | |||
149 | /* Hardware needs 8 bit addresses */ | ||
150 | au0828_write(dev, REG_203, msg->addr << 1); | ||
151 | |||
152 | dprintk(4, "SEND: %02x\n", msg->addr); | ||
153 | |||
154 | for (i = 0; i < msg->len;) { | ||
155 | |||
156 | dprintk(4, " %02x\n", msg->buf[i]); | ||
157 | |||
158 | au0828_write(dev, REG_205, msg->buf[i]); | ||
159 | |||
160 | strobe++; | ||
161 | i++; | ||
162 | |||
163 | if ((strobe >= 4) || (i >= msg->len)) { | ||
164 | |||
165 | /* Strobe the byte into the bus */ | ||
166 | if (i < msg->len) | ||
167 | au0828_write(dev, REG_200, 0x41); | ||
168 | else | ||
169 | au0828_write(dev, REG_200, 0x01); | ||
170 | |||
171 | /* Reset strobe trigger */ | ||
172 | strobe = 0; | ||
173 | |||
174 | if (!i2c_wait_write_done(i2c_adap)) | ||
175 | return -EIO; | ||
176 | |||
177 | } | ||
178 | |||
179 | } | ||
180 | if (!i2c_wait_done(i2c_adap)) | ||
181 | return -EIO; | ||
182 | |||
183 | dprintk(4, "\n"); | ||
184 | |||
185 | return msg->len; | ||
186 | } | ||
187 | |||
188 | /* FIXME: Implement join handling correctly */ | ||
189 | static int i2c_readbytes(struct i2c_adapter *i2c_adap, | ||
190 | const struct i2c_msg *msg, int joined) | ||
191 | { | ||
192 | struct au0828_dev *dev = i2c_adap->algo_data; | ||
193 | int i; | ||
194 | |||
195 | dprintk(4, "%s()\n", __func__); | ||
196 | |||
197 | au0828_write(dev, REG_2FF, 0x01); | ||
198 | au0828_write(dev, REG_202, 0x07); | ||
199 | |||
200 | /* Hardware needs 8 bit addresses */ | ||
201 | au0828_write(dev, REG_203, msg->addr << 1); | ||
202 | |||
203 | dprintk(4, " RECV:\n"); | ||
204 | |||
205 | /* Deal with i2c_scan */ | ||
206 | if (msg->len == 0) { | ||
207 | au0828_write(dev, REG_200, 0x20); | ||
208 | if (i2c_wait_read_ack(i2c_adap)) | ||
209 | return -EIO; | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | for (i = 0; i < msg->len;) { | ||
214 | |||
215 | i++; | ||
216 | |||
217 | if (i < msg->len) | ||
218 | au0828_write(dev, REG_200, 0x60); | ||
219 | else | ||
220 | au0828_write(dev, REG_200, 0x20); | ||
221 | |||
222 | if (!i2c_wait_read_done(i2c_adap)) | ||
223 | return -EIO; | ||
224 | |||
225 | msg->buf[i-1] = au0828_read(dev, REG_209) & 0xff; | ||
226 | |||
227 | dprintk(4, " %02x\n", msg->buf[i-1]); | ||
228 | } | ||
229 | if (!i2c_wait_done(i2c_adap)) | ||
230 | return -EIO; | ||
231 | |||
232 | dprintk(4, "\n"); | ||
233 | |||
234 | return msg->len; | ||
235 | } | ||
236 | |||
237 | static int i2c_xfer(struct i2c_adapter *i2c_adap, | ||
238 | struct i2c_msg *msgs, int num) | ||
239 | { | ||
240 | int i, retval = 0; | ||
241 | |||
242 | dprintk(4, "%s(num = %d)\n", __func__, num); | ||
243 | |||
244 | for (i = 0; i < num; i++) { | ||
245 | dprintk(4, "%s(num = %d) addr = 0x%02x len = 0x%x\n", | ||
246 | __func__, num, msgs[i].addr, msgs[i].len); | ||
247 | if (msgs[i].flags & I2C_M_RD) { | ||
248 | /* read */ | ||
249 | retval = i2c_readbytes(i2c_adap, &msgs[i], 0); | ||
250 | } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && | ||
251 | msgs[i].addr == msgs[i + 1].addr) { | ||
252 | /* write then read from same address */ | ||
253 | retval = i2c_sendbytes(i2c_adap, &msgs[i], | ||
254 | msgs[i + 1].len); | ||
255 | if (retval < 0) | ||
256 | goto err; | ||
257 | i++; | ||
258 | retval = i2c_readbytes(i2c_adap, &msgs[i], 1); | ||
259 | } else { | ||
260 | /* write */ | ||
261 | retval = i2c_sendbytes(i2c_adap, &msgs[i], 0); | ||
262 | } | ||
263 | if (retval < 0) | ||
264 | goto err; | ||
265 | } | ||
266 | return num; | ||
267 | |||
268 | err: | ||
269 | return retval; | ||
270 | } | ||
271 | |||
272 | static int attach_inform(struct i2c_client *client) | ||
273 | { | ||
274 | dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", | ||
275 | client->driver->driver.name, client->addr, client->name); | ||
276 | |||
277 | if (!client->driver->command) | ||
278 | return 0; | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static int detach_inform(struct i2c_client *client) | ||
284 | { | ||
285 | dprintk(1, "i2c detach [client=%s]\n", client->name); | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | void au0828_call_i2c_clients(struct au0828_dev *dev, | ||
291 | unsigned int cmd, void *arg) | ||
292 | { | ||
293 | if (dev->i2c_rc != 0) | ||
294 | return; | ||
295 | |||
296 | i2c_clients_command(&dev->i2c_adap, cmd, arg); | ||
297 | } | ||
298 | |||
299 | static u32 au0828_functionality(struct i2c_adapter *adap) | ||
300 | { | ||
301 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; | ||
302 | } | ||
303 | |||
304 | static struct i2c_algorithm au0828_i2c_algo_template = { | ||
305 | .master_xfer = i2c_xfer, | ||
306 | .functionality = au0828_functionality, | ||
307 | }; | ||
308 | |||
309 | /* ----------------------------------------------------------------------- */ | ||
310 | |||
311 | static struct i2c_adapter au0828_i2c_adap_template = { | ||
312 | .name = DRIVER_NAME, | ||
313 | .owner = THIS_MODULE, | ||
314 | .id = I2C_HW_B_AU0828, | ||
315 | .algo = &au0828_i2c_algo_template, | ||
316 | .class = I2C_CLASS_TV_ANALOG, | ||
317 | .client_register = attach_inform, | ||
318 | .client_unregister = detach_inform, | ||
319 | }; | ||
320 | |||
321 | static struct i2c_client au0828_i2c_client_template = { | ||
322 | .name = "au0828 internal", | ||
323 | }; | ||
324 | |||
325 | static char *i2c_devs[128] = { | ||
326 | [0x8e >> 1] = "au8522", | ||
327 | [0xa0 >> 1] = "eeprom", | ||
328 | [0xc2 >> 1] = "tuner/xc5000", | ||
329 | }; | ||
330 | |||
331 | static void do_i2c_scan(char *name, struct i2c_client *c) | ||
332 | { | ||
333 | unsigned char buf; | ||
334 | int i, rc; | ||
335 | |||
336 | for (i = 0; i < 128; i++) { | ||
337 | c->addr = i; | ||
338 | rc = i2c_master_recv(c, &buf, 0); | ||
339 | if (rc < 0) | ||
340 | continue; | ||
341 | printk(KERN_INFO "%s: i2c scan: found device @ 0x%x [%s]\n", | ||
342 | name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); | ||
343 | } | ||
344 | } | ||
345 | |||
346 | /* init + register i2c algo-bit adapter */ | ||
347 | int au0828_i2c_register(struct au0828_dev *dev) | ||
348 | { | ||
349 | dprintk(1, "%s()\n", __func__); | ||
350 | |||
351 | memcpy(&dev->i2c_adap, &au0828_i2c_adap_template, | ||
352 | sizeof(dev->i2c_adap)); | ||
353 | memcpy(&dev->i2c_algo, &au0828_i2c_algo_template, | ||
354 | sizeof(dev->i2c_algo)); | ||
355 | memcpy(&dev->i2c_client, &au0828_i2c_client_template, | ||
356 | sizeof(dev->i2c_client)); | ||
357 | |||
358 | dev->i2c_adap.dev.parent = &dev->usbdev->dev; | ||
359 | |||
360 | strlcpy(dev->i2c_adap.name, DRIVER_NAME, | ||
361 | sizeof(dev->i2c_adap.name)); | ||
362 | |||
363 | dev->i2c_algo.data = dev; | ||
364 | dev->i2c_adap.algo_data = dev; | ||
365 | i2c_set_adapdata(&dev->i2c_adap, dev); | ||
366 | i2c_add_adapter(&dev->i2c_adap); | ||
367 | |||
368 | dev->i2c_client.adapter = &dev->i2c_adap; | ||
369 | |||
370 | if (0 == dev->i2c_rc) { | ||
371 | printk(KERN_INFO "%s: i2c bus registered\n", DRIVER_NAME); | ||
372 | if (i2c_scan) | ||
373 | do_i2c_scan(DRIVER_NAME, &dev->i2c_client); | ||
374 | } else | ||
375 | printk(KERN_INFO "%s: i2c bus register FAILED\n", DRIVER_NAME); | ||
376 | |||
377 | return dev->i2c_rc; | ||
378 | } | ||
379 | |||
380 | int au0828_i2c_unregister(struct au0828_dev *dev) | ||
381 | { | ||
382 | i2c_del_adapter(&dev->i2c_adap); | ||
383 | return 0; | ||
384 | } | ||
385 | |||
diff --git a/drivers/media/video/au0828/au0828-reg.h b/drivers/media/video/au0828/au0828-reg.h new file mode 100644 index 000000000000..39827550891c --- /dev/null +++ b/drivers/media/video/au0828/au0828-reg.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * Driver for the Auvitek USB bridge | ||
3 | * | ||
4 | * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> | ||
5 | * | ||
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 | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
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 | /* We'll start to rename these registers once we have a better | ||
23 | * understanding of their meaning. | ||
24 | */ | ||
25 | #define REG_000 0x000 | ||
26 | #define REG_001 0x001 | ||
27 | #define REG_002 0x002 | ||
28 | #define REG_003 0x003 | ||
29 | |||
30 | #define REG_200 0x200 | ||
31 | #define REG_201 0x201 | ||
32 | #define REG_202 0x202 | ||
33 | #define REG_203 0x203 | ||
34 | #define REG_205 0x205 | ||
35 | #define REG_209 0x209 | ||
36 | #define REG_2FF 0x2ff | ||
37 | |||
38 | #define REG_600 0x600 | ||
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h new file mode 100644 index 000000000000..0200b9fc5dc4 --- /dev/null +++ b/drivers/media/video/au0828/au0828.h | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * Driver for the Auvitek AU0828 USB bridge | ||
3 | * | ||
4 | * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> | ||
5 | * | ||
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 | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
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/usb.h> | ||
23 | #include <linux/i2c.h> | ||
24 | #include <linux/i2c-algo-bit.h> | ||
25 | #include <media/tveeprom.h> | ||
26 | |||
27 | /* DVB */ | ||
28 | #include "demux.h" | ||
29 | #include "dmxdev.h" | ||
30 | #include "dvb_demux.h" | ||
31 | #include "dvb_frontend.h" | ||
32 | #include "dvb_net.h" | ||
33 | #include "dvbdev.h" | ||
34 | |||
35 | #include "au0828-reg.h" | ||
36 | #include "au0828-cards.h" | ||
37 | |||
38 | #define DRIVER_NAME "au0828" | ||
39 | #define URB_COUNT 16 | ||
40 | #define URB_BUFSIZE (0xe522) | ||
41 | |||
42 | struct au0828_board { | ||
43 | char *name; | ||
44 | }; | ||
45 | |||
46 | struct au0828_dvb { | ||
47 | struct mutex lock; | ||
48 | struct dvb_adapter adapter; | ||
49 | struct dvb_frontend *frontend; | ||
50 | struct dvb_demux demux; | ||
51 | struct dmxdev dmxdev; | ||
52 | struct dmx_frontend fe_hw; | ||
53 | struct dmx_frontend fe_mem; | ||
54 | struct dvb_net net; | ||
55 | int feeding; | ||
56 | }; | ||
57 | |||
58 | struct au0828_dev { | ||
59 | struct mutex mutex; | ||
60 | struct usb_device *usbdev; | ||
61 | int board; | ||
62 | u8 ctrlmsg[64]; | ||
63 | |||
64 | /* I2C */ | ||
65 | struct i2c_adapter i2c_adap; | ||
66 | struct i2c_algo_bit_data i2c_algo; | ||
67 | struct i2c_client i2c_client; | ||
68 | u32 i2c_rc; | ||
69 | |||
70 | /* Digital */ | ||
71 | struct au0828_dvb dvb; | ||
72 | |||
73 | /* USB / URB Related */ | ||
74 | int urb_streaming; | ||
75 | struct urb *urbs[URB_COUNT]; | ||
76 | |||
77 | }; | ||
78 | |||
79 | struct au0828_buff { | ||
80 | struct au0828_dev *dev; | ||
81 | struct urb *purb; | ||
82 | struct list_head buff_list; | ||
83 | }; | ||
84 | |||
85 | /* ----------------------------------------------------------- */ | ||
86 | #define au0828_read(dev, reg) au0828_readreg(dev, reg) | ||
87 | #define au0828_write(dev, reg, value) au0828_writereg(dev, reg, value) | ||
88 | #define au0828_andor(dev, reg, mask, value) \ | ||
89 | au0828_writereg(dev, reg, \ | ||
90 | (au0828_readreg(dev, reg) & ~(mask)) | ((value) & (mask))) | ||
91 | |||
92 | #define au0828_set(dev, reg, bit) au0828_andor(dev, (reg), (bit), (bit)) | ||
93 | #define au0828_clear(dev, reg, bit) au0828_andor(dev, (reg), (bit), 0) | ||
94 | |||
95 | /* ----------------------------------------------------------- */ | ||
96 | /* au0828-core.c */ | ||
97 | extern u32 au0828_read(struct au0828_dev *dev, u16 reg); | ||
98 | extern u32 au0828_write(struct au0828_dev *dev, u16 reg, u32 val); | ||
99 | extern unsigned int debug; | ||
100 | extern unsigned int usb_debug; | ||
101 | extern unsigned int bridge_debug; | ||
102 | |||
103 | /* ----------------------------------------------------------- */ | ||
104 | /* au0828-cards.c */ | ||
105 | extern struct au0828_board au0828_boards[]; | ||
106 | extern struct usb_device_id au0828_usb_id_table[]; | ||
107 | extern const unsigned int au0828_bcount; | ||
108 | extern void au0828_gpio_setup(struct au0828_dev *dev); | ||
109 | extern int au0828_tuner_callback(void *priv, int command, int arg); | ||
110 | extern void au0828_card_setup(struct au0828_dev *dev); | ||
111 | |||
112 | /* ----------------------------------------------------------- */ | ||
113 | /* au0828-i2c.c */ | ||
114 | extern int au0828_i2c_register(struct au0828_dev *dev); | ||
115 | extern int au0828_i2c_unregister(struct au0828_dev *dev); | ||
116 | extern void au0828_call_i2c_clients(struct au0828_dev *dev, | ||
117 | unsigned int cmd, void *arg); | ||
118 | extern unsigned int i2c_debug; | ||
119 | |||
120 | /* ----------------------------------------------------------- */ | ||
121 | /* au0828-dvb.c */ | ||
122 | extern int au0828_dvb_register(struct au0828_dev *dev); | ||
123 | extern void au0828_dvb_unregister(struct au0828_dev *dev); | ||
124 | |||
125 | #define dprintk(level, fmt, arg...)\ | ||
126 | do { if (debug & level)\ | ||
127 | printk(KERN_DEBUG DRIVER_NAME "/0: " fmt, ## arg);\ | ||
128 | } while (0) | ||
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index e663cc045c41..8bfd5c75cb3a 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c | |||
@@ -57,7 +57,7 @@ MODULE_LICENSE("GPL"); | |||
57 | #define I2C_NAME(s) (s)->name | 57 | #define I2C_NAME(s) (s)->name |
58 | 58 | ||
59 | 59 | ||
60 | static int debug = 0; | 60 | static int debug; |
61 | module_param(debug, int, 0); | 61 | module_param(debug, int, 0); |
62 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 62 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
63 | 63 | ||
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index 7dee2e3235ad..98ee2d8feb34 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c | |||
@@ -56,7 +56,7 @@ MODULE_LICENSE("GPL"); | |||
56 | #define I2C_NAME(s) (s)->name | 56 | #define I2C_NAME(s) (s)->name |
57 | 57 | ||
58 | 58 | ||
59 | static int debug = 0; | 59 | static int debug; |
60 | module_param(debug, int, 0); | 60 | module_param(debug, int, 0); |
61 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 61 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
62 | 62 | ||
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 7374c02dd183..f20a01cfc73e 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
@@ -71,6 +71,8 @@ static void kodicom4400r_init(struct bttv *btv); | |||
71 | static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input); | 71 | static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input); |
72 | static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input); | 72 | static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input); |
73 | 73 | ||
74 | static void geovision_muxsel(struct bttv *btv, unsigned int input); | ||
75 | |||
74 | static int terratec_active_radio_upgrade(struct bttv *btv); | 76 | static int terratec_active_radio_upgrade(struct bttv *btv); |
75 | static int tea5757_read(struct bttv *btv); | 77 | static int tea5757_read(struct bttv *btv); |
76 | static int tea5757_write(struct bttv *btv, int value); | 78 | static int tea5757_write(struct bttv *btv, int value); |
@@ -301,6 +303,7 @@ static struct CARD { | |||
301 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, | 303 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, |
302 | { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini "}, | 304 | { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini "}, |
303 | { 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" }, | 305 | { 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" }, |
306 | { 0x763c008a, BTTV_BOARD_GEOVISION_GV600, "GeoVision GV-600" }, | ||
304 | 307 | ||
305 | { 0, -1, NULL } | 308 | { 0, -1, NULL } |
306 | }; | 309 | }; |
@@ -576,6 +579,8 @@ struct tvcard bttv_tvcards[] = { | |||
576 | .needs_tvaudio = 1, | 579 | .needs_tvaudio = 1, |
577 | .pll = PLL_28, | 580 | .pll = PLL_28, |
578 | .tuner_type = UNSET, | 581 | .tuner_type = UNSET, |
582 | .tuner_addr = ADDR_UNSET, | ||
583 | .radio_addr = ADDR_UNSET, | ||
579 | }, | 584 | }, |
580 | [BTTV_BOARD_WINVIEW_601] = { | 585 | [BTTV_BOARD_WINVIEW_601] = { |
581 | .name = "Leadtek WinView 601", | 586 | .name = "Leadtek WinView 601", |
@@ -2322,7 +2327,7 @@ struct tvcard bttv_tvcards[] = { | |||
2322 | .tuner = 0, | 2327 | .tuner = 0, |
2323 | .svhs = 2, | 2328 | .svhs = 2, |
2324 | .muxsel = { 2, 3, 1, 0 }, | 2329 | .muxsel = { 2, 3, 1, 0 }, |
2325 | .tuner_type = TUNER_PHILIPS_ATSC, | 2330 | .tuner_type = TUNER_PHILIPS_FCV1236D, |
2326 | .tuner_addr = ADDR_UNSET, | 2331 | .tuner_addr = ADDR_UNSET, |
2327 | .radio_addr = ADDR_UNSET, | 2332 | .radio_addr = ADDR_UNSET, |
2328 | .has_dvb = 1, | 2333 | .has_dvb = 1, |
@@ -2961,7 +2966,7 @@ struct tvcard bttv_tvcards[] = { | |||
2961 | [BTTV_BOARD_DVICO_FUSIONHDTV_2] = { | 2966 | [BTTV_BOARD_DVICO_FUSIONHDTV_2] = { |
2962 | .name = "DViCO FusionHDTV 2", | 2967 | .name = "DViCO FusionHDTV 2", |
2963 | .tuner = 0, | 2968 | .tuner = 0, |
2964 | .tuner_type = TUNER_PHILIPS_ATSC, /* FCV1236D */ | 2969 | .tuner_type = TUNER_PHILIPS_FCV1236D, |
2965 | .tuner_addr = ADDR_UNSET, | 2970 | .tuner_addr = ADDR_UNSET, |
2966 | .radio_addr = ADDR_UNSET, | 2971 | .radio_addr = ADDR_UNSET, |
2967 | .video_inputs = 3, | 2972 | .video_inputs = 3, |
@@ -2992,6 +2997,45 @@ struct tvcard bttv_tvcards[] = { | |||
2992 | .tuner_addr = ADDR_UNSET, | 2997 | .tuner_addr = ADDR_UNSET, |
2993 | .radio_addr = ADDR_UNSET, | 2998 | .radio_addr = ADDR_UNSET, |
2994 | }, | 2999 | }, |
3000 | [BTTV_BOARD_GEOVISION_GV600] = { | ||
3001 | /* emhn@usb.ve */ | ||
3002 | .name = "Geovision GV-600", | ||
3003 | .video_inputs = 16, | ||
3004 | .audio_inputs = 0, | ||
3005 | .tuner = UNSET, | ||
3006 | .svhs = UNSET, | ||
3007 | .gpiomask = 0x0, | ||
3008 | .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, | ||
3009 | 2, 2, 2, 2, 2, 2, 2, 2 }, | ||
3010 | .muxsel_hook = geovision_muxsel, | ||
3011 | .gpiomux = { 0 }, | ||
3012 | .no_msp34xx = 1, | ||
3013 | .pll = PLL_28, | ||
3014 | .tuner_type = UNSET, | ||
3015 | .tuner_addr = ADDR_UNSET, | ||
3016 | .radio_addr = ADDR_UNSET, | ||
3017 | }, | ||
3018 | [BTTV_BOARD_KOZUMI_KTV_01C] = { | ||
3019 | /* Mauro Lacy <mauro@lacy.com.ar> | ||
3020 | * Based on MagicTV and Conceptronic CONTVFMi */ | ||
3021 | |||
3022 | .name = "Kozumi KTV-01C", | ||
3023 | .video_inputs = 3, | ||
3024 | .audio_inputs = 1, | ||
3025 | .tuner = 0, | ||
3026 | .svhs = 2, | ||
3027 | .gpiomask = 0x008007, | ||
3028 | .muxsel = { 2, 3, 1, 1 }, | ||
3029 | .gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */ | ||
3030 | .gpiomute = 3, /* CONTVFMi */ | ||
3031 | .needs_tvaudio = 0, | ||
3032 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */ | ||
3033 | .tuner_addr = ADDR_UNSET, | ||
3034 | .radio_addr = ADDR_UNSET, | ||
3035 | .pll = PLL_28, | ||
3036 | .has_radio = 1, | ||
3037 | .has_remote = 1, | ||
3038 | }, | ||
2995 | }; | 3039 | }; |
2996 | 3040 | ||
2997 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); | 3041 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); |
@@ -3331,6 +3375,13 @@ static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input) | |||
3331 | gpio_bits( 3<<9, inmux<<9 ); | 3375 | gpio_bits( 3<<9, inmux<<9 ); |
3332 | } | 3376 | } |
3333 | 3377 | ||
3378 | static void geovision_muxsel(struct bttv *btv, unsigned int input) | ||
3379 | { | ||
3380 | unsigned int inmux = input % 16; | ||
3381 | gpio_inout(0xf, 0xf); | ||
3382 | gpio_bits(0xf, inmux); | ||
3383 | } | ||
3384 | |||
3334 | /* ----------------------------------------------------------------------- */ | 3385 | /* ----------------------------------------------------------------------- */ |
3335 | 3386 | ||
3336 | static void bttv_reset_audio(struct bttv *btv) | 3387 | static void bttv_reset_audio(struct bttv *btv) |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index fcf8f2d208a8..2ca3e9cfb2bb 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -2372,7 +2372,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, | |||
2372 | if (check_btres(fh, RESOURCE_OVERLAY)) { | 2372 | if (check_btres(fh, RESOURCE_OVERLAY)) { |
2373 | struct bttv_buffer *new; | 2373 | struct bttv_buffer *new; |
2374 | 2374 | ||
2375 | new = videobuf_pci_alloc(sizeof(*new)); | 2375 | new = videobuf_sg_alloc(sizeof(*new)); |
2376 | new->crop = btv->crop[!!fh->do_crop].rect; | 2376 | new->crop = btv->crop[!!fh->do_crop].rect; |
2377 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); | 2377 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); |
2378 | retval = bttv_switch_overlay(btv,fh,new); | 2378 | retval = bttv_switch_overlay(btv,fh,new); |
@@ -2760,7 +2760,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) | |||
2760 | mutex_lock(&fh->cap.vb_lock); | 2760 | mutex_lock(&fh->cap.vb_lock); |
2761 | if (on) { | 2761 | if (on) { |
2762 | fh->ov.tvnorm = btv->tvnorm; | 2762 | fh->ov.tvnorm = btv->tvnorm; |
2763 | new = videobuf_pci_alloc(sizeof(*new)); | 2763 | new = videobuf_sg_alloc(sizeof(*new)); |
2764 | new->crop = btv->crop[!!fh->do_crop].rect; | 2764 | new->crop = btv->crop[!!fh->do_crop].rect; |
2765 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); | 2765 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); |
2766 | } else { | 2766 | } else { |
@@ -2834,7 +2834,7 @@ static int bttv_s_fbuf(struct file *file, void *f, | |||
2834 | if (check_btres(fh, RESOURCE_OVERLAY)) { | 2834 | if (check_btres(fh, RESOURCE_OVERLAY)) { |
2835 | struct bttv_buffer *new; | 2835 | struct bttv_buffer *new; |
2836 | 2836 | ||
2837 | new = videobuf_pci_alloc(sizeof(*new)); | 2837 | new = videobuf_sg_alloc(sizeof(*new)); |
2838 | new->crop = btv->crop[!!fh->do_crop].rect; | 2838 | new->crop = btv->crop[!!fh->do_crop].rect; |
2839 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); | 2839 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); |
2840 | retval = bttv_switch_overlay(btv, fh, new); | 2840 | retval = bttv_switch_overlay(btv, fh, new); |
@@ -3117,12 +3117,18 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
3117 | 3117 | ||
3118 | static int bttv_g_audio(struct file *file, void *priv, struct v4l2_audio *a) | 3118 | static int bttv_g_audio(struct file *file, void *priv, struct v4l2_audio *a) |
3119 | { | 3119 | { |
3120 | if (unlikely(a->index)) | ||
3121 | return -EINVAL; | ||
3122 | |||
3120 | strcpy(a->name, "audio"); | 3123 | strcpy(a->name, "audio"); |
3121 | return 0; | 3124 | return 0; |
3122 | } | 3125 | } |
3123 | 3126 | ||
3124 | static int bttv_s_audio(struct file *file, void *priv, struct v4l2_audio *a) | 3127 | static int bttv_s_audio(struct file *file, void *priv, struct v4l2_audio *a) |
3125 | { | 3128 | { |
3129 | if (unlikely(a->index)) | ||
3130 | return -EINVAL; | ||
3131 | |||
3126 | return 0; | 3132 | return 0; |
3127 | } | 3133 | } |
3128 | 3134 | ||
@@ -3184,7 +3190,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3184 | /* need to capture a new frame */ | 3190 | /* need to capture a new frame */ |
3185 | if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) | 3191 | if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) |
3186 | goto err; | 3192 | goto err; |
3187 | fh->cap.read_buf = videobuf_pci_alloc(fh->cap.msize); | 3193 | fh->cap.read_buf = videobuf_sg_alloc(fh->cap.msize); |
3188 | if (NULL == fh->cap.read_buf) | 3194 | if (NULL == fh->cap.read_buf) |
3189 | goto err; | 3195 | goto err; |
3190 | fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; | 3196 | fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; |
@@ -3251,14 +3257,14 @@ static int bttv_open(struct inode *inode, struct file *file) | |||
3251 | fh->ov.setup_ok = 0; | 3257 | fh->ov.setup_ok = 0; |
3252 | v4l2_prio_open(&btv->prio,&fh->prio); | 3258 | v4l2_prio_open(&btv->prio,&fh->prio); |
3253 | 3259 | ||
3254 | videobuf_queue_pci_init(&fh->cap, &bttv_video_qops, | 3260 | videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, |
3255 | btv->c.pci, &btv->s_lock, | 3261 | &btv->c.pci->dev, &btv->s_lock, |
3256 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 3262 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
3257 | V4L2_FIELD_INTERLACED, | 3263 | V4L2_FIELD_INTERLACED, |
3258 | sizeof(struct bttv_buffer), | 3264 | sizeof(struct bttv_buffer), |
3259 | fh); | 3265 | fh); |
3260 | videobuf_queue_pci_init(&fh->vbi, &bttv_vbi_qops, | 3266 | videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops, |
3261 | btv->c.pci, &btv->s_lock, | 3267 | &btv->c.pci->dev, &btv->s_lock, |
3262 | V4L2_BUF_TYPE_VBI_CAPTURE, | 3268 | V4L2_BUF_TYPE_VBI_CAPTURE, |
3263 | V4L2_FIELD_SEQ_TB, | 3269 | V4L2_FIELD_SEQ_TB, |
3264 | sizeof(struct bttv_buffer), | 3270 | sizeof(struct bttv_buffer), |
@@ -3457,6 +3463,9 @@ static int radio_release(struct inode *inode, struct file *file) | |||
3457 | struct bttv *btv = fh->btv; | 3463 | struct bttv *btv = fh->btv; |
3458 | struct rds_command cmd; | 3464 | struct rds_command cmd; |
3459 | 3465 | ||
3466 | file->private_data = NULL; | ||
3467 | kfree(fh); | ||
3468 | |||
3460 | btv->radio_user--; | 3469 | btv->radio_user--; |
3461 | 3470 | ||
3462 | bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd); | 3471 | bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd); |
@@ -3510,7 +3519,7 @@ static int radio_enum_input(struct file *file, void *priv, | |||
3510 | return -EINVAL; | 3519 | return -EINVAL; |
3511 | 3520 | ||
3512 | strcpy(i->name, "Radio"); | 3521 | strcpy(i->name, "Radio"); |
3513 | i->type = V4L2_INPUT_TYPE_TUNER; | 3522 | i->type = V4L2_INPUT_TYPE_TUNER; |
3514 | 3523 | ||
3515 | return 0; | 3524 | return 0; |
3516 | } | 3525 | } |
@@ -3518,10 +3527,9 @@ static int radio_enum_input(struct file *file, void *priv, | |||
3518 | static int radio_g_audio(struct file *file, void *priv, | 3527 | static int radio_g_audio(struct file *file, void *priv, |
3519 | struct v4l2_audio *a) | 3528 | struct v4l2_audio *a) |
3520 | { | 3529 | { |
3521 | if (a->index != 0) | 3530 | if (unlikely(a->index)) |
3522 | return -EINVAL; | 3531 | return -EINVAL; |
3523 | 3532 | ||
3524 | memset(a, 0, sizeof(*a)); | ||
3525 | strcpy(a->name, "Radio"); | 3533 | strcpy(a->name, "Radio"); |
3526 | 3534 | ||
3527 | return 0; | 3535 | return 0; |
@@ -3543,11 +3551,17 @@ static int radio_s_tuner(struct file *file, void *priv, | |||
3543 | static int radio_s_audio(struct file *file, void *priv, | 3551 | static int radio_s_audio(struct file *file, void *priv, |
3544 | struct v4l2_audio *a) | 3552 | struct v4l2_audio *a) |
3545 | { | 3553 | { |
3554 | if (unlikely(a->index)) | ||
3555 | return -EINVAL; | ||
3556 | |||
3546 | return 0; | 3557 | return 0; |
3547 | } | 3558 | } |
3548 | 3559 | ||
3549 | static int radio_s_input(struct file *filp, void *priv, unsigned int i) | 3560 | static int radio_s_input(struct file *filp, void *priv, unsigned int i) |
3550 | { | 3561 | { |
3562 | if (unlikely(i)) | ||
3563 | return -EINVAL; | ||
3564 | |||
3551 | return 0; | 3565 | return 0; |
3552 | } | 3566 | } |
3553 | 3567 | ||
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index fc9ecb21eec6..a38af98f4cae 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c | |||
@@ -278,6 +278,12 @@ int bttv_input_init(struct bttv *btv) | |||
278 | ir->mask_keyup = 0x004000; | 278 | ir->mask_keyup = 0x004000; |
279 | ir->polling = 50; /* ms */ | 279 | ir->polling = 50; /* ms */ |
280 | break; | 280 | break; |
281 | case BTTV_BOARD_KOZUMI_KTV_01C: | ||
282 | ir_codes = ir_codes_pctv_sedna; | ||
283 | ir->mask_keycode = 0x001f00; | ||
284 | ir->mask_keyup = 0x006000; | ||
285 | ir->polling = 50; /* ms */ | ||
286 | break; | ||
281 | } | 287 | } |
282 | if (NULL == ir_codes) { | 288 | if (NULL == ir_codes) { |
283 | dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n", btv->c.type); | 289 | dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n", btv->c.type); |
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c index 75fa82c7c735..bfdbc469e30f 100644 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ b/drivers/media/video/bt8xx/bttv-vbi.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #define VBI_DEFLINES 16 | 54 | #define VBI_DEFLINES 16 |
55 | 55 | ||
56 | static unsigned int vbibufs = 4; | 56 | static unsigned int vbibufs = 4; |
57 | static unsigned int vbi_debug = 0; | 57 | static unsigned int vbi_debug; |
58 | 58 | ||
59 | module_param(vbibufs, int, 0444); | 59 | module_param(vbibufs, int, 0444); |
60 | module_param(vbi_debug, int, 0644); | 60 | module_param(vbi_debug, int, 0644); |
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index bf4c339a520c..f2393202904b 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <media/ir-common.h> | 19 | #include <media/ir-common.h> |
20 | #include <media/ir-kbd-i2c.h> | 20 | #include <media/ir-kbd-i2c.h> |
21 | #include <media/i2c-addr.h> | 21 | #include <media/i2c-addr.h> |
22 | #include <media/tuner.h> | ||
22 | 23 | ||
23 | /* ---------------------------------------------------------- */ | 24 | /* ---------------------------------------------------------- */ |
24 | /* exported by bttv-cards.c */ | 25 | /* exported by bttv-cards.c */ |
@@ -173,6 +174,8 @@ | |||
173 | #define BTTV_BOARD_VOODOOTV_200 0x93 | 174 | #define BTTV_BOARD_VOODOOTV_200 0x93 |
174 | #define BTTV_BOARD_DVICO_FUSIONHDTV_2 0x94 | 175 | #define BTTV_BOARD_DVICO_FUSIONHDTV_2 0x94 |
175 | #define BTTV_BOARD_TYPHOON_TVTUNERPCI 0x95 | 176 | #define BTTV_BOARD_TYPHOON_TVTUNERPCI 0x95 |
177 | #define BTTV_BOARD_GEOVISION_GV600 0x96 | ||
178 | #define BTTV_BOARD_KOZUMI_KTV_01C 0x97 | ||
176 | 179 | ||
177 | 180 | ||
178 | /* more card-specific defines */ | 181 | /* more card-specific defines */ |
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index 1305d315cfc5..03816b73f847 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h | |||
@@ -42,7 +42,6 @@ | |||
42 | 42 | ||
43 | #include <linux/device.h> | 43 | #include <linux/device.h> |
44 | #include <media/videobuf-dma-sg.h> | 44 | #include <media/videobuf-dma-sg.h> |
45 | #include <media/tuner.h> | ||
46 | #include <media/tveeprom.h> | 45 | #include <media/tveeprom.h> |
47 | #include <media/ir-common.h> | 46 | #include <media/ir-common.h> |
48 | 47 | ||
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 032265383df2..b364adaae78d 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c | |||
@@ -523,7 +523,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) | |||
523 | int ret=1; | 523 | int ret=1; |
524 | unsigned int hi, lo; | 524 | unsigned int hi, lo; |
525 | unsigned int hi2, lo2; | 525 | unsigned int hi2, lo2; |
526 | static int state = 0; | 526 | static int state; |
527 | 527 | ||
528 | if (buffer == NULL) | 528 | if (buffer == NULL) |
529 | { | 529 | { |
@@ -898,7 +898,9 @@ static const struct file_operations qcam_fops = { | |||
898 | .open = video_exclusive_open, | 898 | .open = video_exclusive_open, |
899 | .release = video_exclusive_release, | 899 | .release = video_exclusive_release, |
900 | .ioctl = qcam_ioctl, | 900 | .ioctl = qcam_ioctl, |
901 | #ifdef CONFIG_COMPAT | ||
901 | .compat_ioctl = v4l_compat_ioctl32, | 902 | .compat_ioctl = v4l_compat_ioctl32, |
903 | #endif | ||
902 | .read = qcam_read, | 904 | .read = qcam_read, |
903 | .llseek = no_llseek, | 905 | .llseek = no_llseek, |
904 | }; | 906 | }; |
@@ -912,7 +914,7 @@ static struct video_device qcam_template= | |||
912 | 914 | ||
913 | #define MAX_CAMS 4 | 915 | #define MAX_CAMS 4 |
914 | static struct qcam_device *qcams[MAX_CAMS]; | 916 | static struct qcam_device *qcams[MAX_CAMS]; |
915 | static unsigned int num_cams = 0; | 917 | static unsigned int num_cams; |
916 | 918 | ||
917 | static int init_bwqcam(struct parport *port) | 919 | static int init_bwqcam(struct parport *port) |
918 | { | 920 | { |
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index cf1546b5a7f1..fe1e67bb1ca8 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/videodev.h> | 36 | #include <linux/videodev.h> |
37 | #include <media/v4l2-common.h> | 37 | #include <media/v4l2-common.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/jiffies.h> | ||
39 | 40 | ||
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
41 | 42 | ||
@@ -69,7 +70,7 @@ struct qcam_device { | |||
69 | 70 | ||
70 | static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 }; | 71 | static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 }; |
71 | static int probe = 2; | 72 | static int probe = 2; |
72 | static int force_rgb = 0; | 73 | static int force_rgb; |
73 | static int video_nr = -1; | 74 | static int video_nr = -1; |
74 | 75 | ||
75 | static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i) | 76 | static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i) |
@@ -95,7 +96,8 @@ static unsigned int qcam_await_ready1(struct qcam_device *qcam, | |||
95 | unsigned long oldjiffies = jiffies; | 96 | unsigned long oldjiffies = jiffies; |
96 | unsigned int i; | 97 | unsigned int i; |
97 | 98 | ||
98 | for (oldjiffies = jiffies; (jiffies - oldjiffies) < msecs_to_jiffies(40); ) | 99 | for (oldjiffies = jiffies; |
100 | time_before(jiffies, oldjiffies + msecs_to_jiffies(40)); ) | ||
99 | if (qcam_ready1(qcam) == value) | 101 | if (qcam_ready1(qcam) == value) |
100 | return 0; | 102 | return 0; |
101 | 103 | ||
@@ -120,7 +122,8 @@ static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value) | |||
120 | unsigned long oldjiffies = jiffies; | 122 | unsigned long oldjiffies = jiffies; |
121 | unsigned int i; | 123 | unsigned int i; |
122 | 124 | ||
123 | for (oldjiffies = jiffies; (jiffies - oldjiffies) < msecs_to_jiffies(40); ) | 125 | for (oldjiffies = jiffies; |
126 | time_before(jiffies, oldjiffies + msecs_to_jiffies(40)); ) | ||
124 | if (qcam_ready2(qcam) == value) | 127 | if (qcam_ready2(qcam) == value) |
125 | return 0; | 128 | return 0; |
126 | 129 | ||
@@ -689,7 +692,9 @@ static const struct file_operations qcam_fops = { | |||
689 | .open = video_exclusive_open, | 692 | .open = video_exclusive_open, |
690 | .release = video_exclusive_release, | 693 | .release = video_exclusive_release, |
691 | .ioctl = qcam_ioctl, | 694 | .ioctl = qcam_ioctl, |
695 | #ifdef CONFIG_COMPAT | ||
692 | .compat_ioctl = v4l_compat_ioctl32, | 696 | .compat_ioctl = v4l_compat_ioctl32, |
697 | #endif | ||
693 | .read = qcam_read, | 698 | .read = qcam_read, |
694 | .llseek = no_llseek, | 699 | .llseek = no_llseek, |
695 | }; | 700 | }; |
@@ -741,7 +746,7 @@ static struct qcam_device *qcam_init(struct parport *port) | |||
741 | } | 746 | } |
742 | 747 | ||
743 | static struct qcam_device *qcams[MAX_CAMS]; | 748 | static struct qcam_device *qcams[MAX_CAMS]; |
744 | static unsigned int num_cams = 0; | 749 | static unsigned int num_cams; |
745 | 750 | ||
746 | static int init_cqcam(struct parport *port) | 751 | static int init_cqcam(struct parport *port) |
747 | { | 752 | { |
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 7ae499c9c54c..5195b1f3378a 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
@@ -65,7 +65,7 @@ MODULE_SUPPORTED_DEVICE("Video"); | |||
65 | */ | 65 | */ |
66 | 66 | ||
67 | #define MAX_DMA_BUFS 3 | 67 | #define MAX_DMA_BUFS 3 |
68 | static int alloc_bufs_at_read = 0; | 68 | static int alloc_bufs_at_read; |
69 | module_param(alloc_bufs_at_read, bool, 0444); | 69 | module_param(alloc_bufs_at_read, bool, 0444); |
70 | MODULE_PARM_DESC(alloc_bufs_at_read, | 70 | MODULE_PARM_DESC(alloc_bufs_at_read, |
71 | "Non-zero value causes DMA buffers to be allocated when the " | 71 | "Non-zero value causes DMA buffers to be allocated when the " |
@@ -99,7 +99,7 @@ MODULE_PARM_DESC(max_buffers, | |||
99 | "will be allowed to allocate. These buffers are big and live " | 99 | "will be allowed to allocate. These buffers are big and live " |
100 | "in vmalloc space."); | 100 | "in vmalloc space."); |
101 | 101 | ||
102 | static int flip = 0; | 102 | static int flip; |
103 | module_param(flip, bool, 0444); | 103 | module_param(flip, bool, 0444); |
104 | MODULE_PARM_DESC(flip, | 104 | MODULE_PARM_DESC(flip, |
105 | "If set, the sensor will be instructed to flip the image " | 105 | "If set, the sensor will be instructed to flip the image " |
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 7c630f5ee725..2a81376ef503 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c | |||
@@ -3792,7 +3792,9 @@ static const struct file_operations cpia_fops = { | |||
3792 | .read = cpia_read, | 3792 | .read = cpia_read, |
3793 | .mmap = cpia_mmap, | 3793 | .mmap = cpia_mmap, |
3794 | .ioctl = cpia_ioctl, | 3794 | .ioctl = cpia_ioctl, |
3795 | #ifdef CONFIG_COMPAT | ||
3795 | .compat_ioctl = v4l_compat_ioctl32, | 3796 | .compat_ioctl = v4l_compat_ioctl32, |
3797 | #endif | ||
3796 | .llseek = no_llseek, | 3798 | .llseek = no_llseek, |
3797 | }; | 3799 | }; |
3798 | 3800 | ||
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h index 78392fb6f94e..5096058bf579 100644 --- a/drivers/media/video/cpia.h +++ b/drivers/media/video/cpia.h | |||
@@ -412,11 +412,11 @@ void cpia_unregister_camera(struct cam_data *cam); | |||
412 | /* ErrorCode */ | 412 | /* ErrorCode */ |
413 | #define ERROR_FLICKER_BELOW_MIN_EXP 0x01 /*flicker exposure got below minimum exposure */ | 413 | #define ERROR_FLICKER_BELOW_MIN_EXP 0x01 /*flicker exposure got below minimum exposure */ |
414 | #define ALOG(fmt,args...) printk(fmt, ##args) | 414 | #define ALOG(fmt,args...) printk(fmt, ##args) |
415 | #define LOG(fmt,args...) ALOG(KERN_INFO __FILE__ ":%s(%d):" fmt, __FUNCTION__ , __LINE__ , ##args) | 415 | #define LOG(fmt,args...) ALOG(KERN_INFO __FILE__ ":%s(%d):" fmt, __func__ , __LINE__ , ##args) |
416 | 416 | ||
417 | #ifdef _CPIA_DEBUG_ | 417 | #ifdef _CPIA_DEBUG_ |
418 | #define ADBG(fmt,args...) printk(fmt, jiffies, ##args) | 418 | #define ADBG(fmt,args...) printk(fmt, jiffies, ##args) |
419 | #define DBG(fmt,args...) ADBG(KERN_DEBUG __FILE__" (%ld):%s(%d):" fmt, __FUNCTION__, __LINE__ , ##args) | 419 | #define DBG(fmt,args...) ADBG(KERN_DEBUG __FILE__" (%ld):%s(%d):" fmt, __func__, __LINE__ , ##args) |
420 | #else | 420 | #else |
421 | #define DBG(fmn,args...) do {} while(0) | 421 | #define DBG(fmn,args...) do {} while(0) |
422 | #endif | 422 | #endif |
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c index a76bd786cf13..c8b9fdb700ff 100644 --- a/drivers/media/video/cpia2/cpia2_core.c +++ b/drivers/media/video/cpia2/cpia2_core.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/vmalloc.h> | 35 | #include <linux/vmalloc.h> |
36 | 36 | ||
37 | //#define _CPIA2_DEBUG_ | 37 | /* #define _CPIA2_DEBUG_ */ |
38 | 38 | ||
39 | #include "cpia2patch.h" | 39 | #include "cpia2patch.h" |
40 | 40 | ||
@@ -48,7 +48,7 @@ static const char *block_name[] = { | |||
48 | }; | 48 | }; |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | static unsigned int debugs_on = 0;//DEBUG_REG; | 51 | static unsigned int debugs_on; /* default 0 - DEBUG_REG */ |
52 | 52 | ||
53 | 53 | ||
54 | /****************************************************************************** | 54 | /****************************************************************************** |
@@ -570,7 +570,7 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd) | |||
570 | block_name[block_index]); | 570 | block_name[block_index]); |
571 | break; | 571 | break; |
572 | default: | 572 | default: |
573 | LOG("%s: invalid request mode\n",__FUNCTION__); | 573 | LOG("%s: invalid request mode\n",__func__); |
574 | return -EINVAL; | 574 | return -EINVAL; |
575 | } | 575 | } |
576 | 576 | ||
@@ -952,7 +952,7 @@ static int set_default_user_mode(struct camera_data *cam) | |||
952 | frame_rate = CPIA2_VP_FRAMERATE_30; | 952 | frame_rate = CPIA2_VP_FRAMERATE_30; |
953 | break; | 953 | break; |
954 | default: | 954 | default: |
955 | LOG("%s: Invalid sensor flag value 0x%0X\n",__FUNCTION__, | 955 | LOG("%s: Invalid sensor flag value 0x%0X\n",__func__, |
956 | cam->params.version.sensor_flags); | 956 | cam->params.version.sensor_flags); |
957 | return -EINVAL; | 957 | return -EINVAL; |
958 | } | 958 | } |
@@ -2356,12 +2356,12 @@ long cpia2_read(struct camera_data *cam, | |||
2356 | } | 2356 | } |
2357 | 2357 | ||
2358 | if (!buf) { | 2358 | if (!buf) { |
2359 | ERR("%s: buffer NULL\n",__FUNCTION__); | 2359 | ERR("%s: buffer NULL\n",__func__); |
2360 | return -EINVAL; | 2360 | return -EINVAL; |
2361 | } | 2361 | } |
2362 | 2362 | ||
2363 | if (!cam) { | 2363 | if (!cam) { |
2364 | ERR("%s: Internal error, camera_data NULL!\n",__FUNCTION__); | 2364 | ERR("%s: Internal error, camera_data NULL!\n",__func__); |
2365 | return -EINVAL; | 2365 | return -EINVAL; |
2366 | } | 2366 | } |
2367 | 2367 | ||
@@ -2370,7 +2370,7 @@ long cpia2_read(struct camera_data *cam, | |||
2370 | return -ERESTARTSYS; | 2370 | return -ERESTARTSYS; |
2371 | 2371 | ||
2372 | if (!cam->present) { | 2372 | if (!cam->present) { |
2373 | LOG("%s: camera removed\n",__FUNCTION__); | 2373 | LOG("%s: camera removed\n",__func__); |
2374 | mutex_unlock(&cam->busy_lock); | 2374 | mutex_unlock(&cam->busy_lock); |
2375 | return 0; /* EOF */ | 2375 | return 0; /* EOF */ |
2376 | } | 2376 | } |
@@ -2434,7 +2434,7 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, | |||
2434 | unsigned int status=0; | 2434 | unsigned int status=0; |
2435 | 2435 | ||
2436 | if(!cam) { | 2436 | if(!cam) { |
2437 | ERR("%s: Internal error, camera_data not found!\n",__FUNCTION__); | 2437 | ERR("%s: Internal error, camera_data not found!\n",__func__); |
2438 | return POLLERR; | 2438 | return POLLERR; |
2439 | } | 2439 | } |
2440 | 2440 | ||
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c index d8e929863a88..a4574740350d 100644 --- a/drivers/media/video/cpia2/cpia2_usb.c +++ b/drivers/media/video/cpia2/cpia2_usb.c | |||
@@ -84,7 +84,7 @@ static struct usb_driver cpia2_driver = { | |||
84 | *****************************************************************************/ | 84 | *****************************************************************************/ |
85 | static void process_frame(struct camera_data *cam) | 85 | static void process_frame(struct camera_data *cam) |
86 | { | 86 | { |
87 | static int frame_count = 0; | 87 | static int frame_count; |
88 | 88 | ||
89 | unsigned char *inbuff = cam->workbuff->data; | 89 | unsigned char *inbuff = cam->workbuff->data; |
90 | 90 | ||
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index e378abec806d..7ce2789fa976 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c | |||
@@ -1927,7 +1927,9 @@ static const struct file_operations fops_template = { | |||
1927 | .poll = cpia2_v4l_poll, | 1927 | .poll = cpia2_v4l_poll, |
1928 | .ioctl = cpia2_ioctl, | 1928 | .ioctl = cpia2_ioctl, |
1929 | .llseek = no_llseek, | 1929 | .llseek = no_llseek, |
1930 | #ifdef CONFIG_COMPAT | ||
1930 | .compat_ioctl = v4l_compat_ioctl32, | 1931 | .compat_ioctl = v4l_compat_ioctl32, |
1932 | #endif | ||
1931 | .mmap = cpia2_mmap, | 1933 | .mmap = cpia2_mmap, |
1932 | }; | 1934 | }; |
1933 | 1935 | ||
diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c index 9da4726eb9b9..ef1f89399983 100644 --- a/drivers/media/video/cpia_usb.c +++ b/drivers/media/video/cpia_usb.c | |||
@@ -170,7 +170,7 @@ static void cpia_usb_complete(struct urb *urb) | |||
170 | /* resubmit */ | 170 | /* resubmit */ |
171 | urb->dev = ucpia->dev; | 171 | urb->dev = ucpia->dev; |
172 | if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0) | 172 | if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0) |
173 | printk(KERN_ERR "%s: usb_submit_urb ret %d\n", __FUNCTION__, i); | 173 | printk(KERN_ERR "%s: usb_submit_urb ret %d\n", __func__, i); |
174 | } | 174 | } |
175 | 175 | ||
176 | static int cpia_usb_open(void *privdata) | 176 | static int cpia_usb_open(void *privdata) |
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig index 1fd326fe4113..ca5fbce3a909 100644 --- a/drivers/media/video/cx23885/Kconfig +++ b/drivers/media/video/cx23885/Kconfig | |||
@@ -8,6 +8,7 @@ config VIDEO_CX23885 | |||
8 | select VIDEO_TVEEPROM | 8 | select VIDEO_TVEEPROM |
9 | select VIDEO_IR | 9 | select VIDEO_IR |
10 | select VIDEOBUF_DVB | 10 | select VIDEOBUF_DVB |
11 | select VIDEO_CX25840 | ||
11 | select DVB_TUNER_MT2131 if !DVB_FE_CUSTOMISE | 12 | select DVB_TUNER_MT2131 if !DVB_FE_CUSTOMISE |
12 | select DVB_S5H1409 if !DVB_FE_CUSTOMISE | 13 | select DVB_S5H1409 if !DVB_FE_CUSTOMISE |
13 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | 14 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE |
@@ -16,6 +17,7 @@ config VIDEO_CX23885 | |||
16 | select TUNER_TDA8290 if !DVB_FE_CUSTOMIZE | 17 | select TUNER_TDA8290 if !DVB_FE_CUSTOMIZE |
17 | select DVB_TDA18271 if !DVB_FE_CUSTOMIZE | 18 | select DVB_TDA18271 if !DVB_FE_CUSTOMIZE |
18 | select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE | 19 | select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE |
20 | select DVB_TDA10048 if !DVB_FE_CUSTOMIZE | ||
19 | ---help--- | 21 | ---help--- |
20 | This is a video4linux driver for Conexant 23885 based | 22 | This is a video4linux driver for Conexant 23885 based |
21 | TV cards. | 23 | TV cards. |
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile index 32c90be50602..d7b0721af062 100644 --- a/drivers/media/video/cx23885/Makefile +++ b/drivers/media/video/cx23885/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o cx23885-core.o cx23885-i2c.o cx23885-dvb.o | 1 | cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o |
2 | 2 | ||
3 | obj-$(CONFIG_VIDEO_CX23885) += cx23885.o | 3 | obj-$(CONFIG_VIDEO_CX23885) += cx23885.o |
4 | 4 | ||
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c new file mode 100644 index 000000000000..acdd3b6b3e7c --- /dev/null +++ b/drivers/media/video/cx23885/cx23885-417.c | |||
@@ -0,0 +1,1764 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Support for a cx23417 mpeg encoder via cx23885 host port. | ||
4 | * | ||
5 | * (c) 2004 Jelle Foks <jelle@foks.8m.com> | ||
6 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> | ||
7 | * (c) 2008 Steven Toth <stoth@hauppauge.com> | ||
8 | * - CX23885/7/8 support | ||
9 | * | ||
10 | * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/), | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/moduleparam.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/fs.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <linux/device.h> | ||
33 | #include <linux/firmware.h> | ||
34 | #include <media/v4l2-common.h> | ||
35 | #include <media/cx2341x.h> | ||
36 | |||
37 | #include "cx23885.h" | ||
38 | #include "media/cx2341x.h" | ||
39 | |||
40 | #define CX23885_FIRM_IMAGE_SIZE 376836 | ||
41 | #define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" | ||
42 | |||
43 | static unsigned int mpegbufs = 32; | ||
44 | module_param(mpegbufs, int, 0644); | ||
45 | MODULE_PARM_DESC(mpegbufs, "number of mpeg buffers, range 2-32"); | ||
46 | static unsigned int mpeglines = 32; | ||
47 | module_param(mpeglines, int, 0644); | ||
48 | MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32"); | ||
49 | static unsigned int mpeglinesize = 512; | ||
50 | module_param(mpeglinesize, int, 0644); | ||
51 | MODULE_PARM_DESC(mpeglinesize, | ||
52 | "number of bytes in each line of an MPEG buffer, range 512-1024"); | ||
53 | |||
54 | static unsigned int v4l_debug; | ||
55 | module_param(v4l_debug, int, 0644); | ||
56 | MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages"); | ||
57 | |||
58 | #define dprintk(level, fmt, arg...)\ | ||
59 | do { if (v4l_debug >= level) \ | ||
60 | printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg);\ | ||
61 | } while (0) | ||
62 | |||
63 | static struct cx23885_tvnorm cx23885_tvnorms[] = { | ||
64 | { | ||
65 | .name = "NTSC-M", | ||
66 | .id = V4L2_STD_NTSC_M, | ||
67 | }, { | ||
68 | .name = "NTSC-JP", | ||
69 | .id = V4L2_STD_NTSC_M_JP, | ||
70 | }, { | ||
71 | .name = "PAL-BG", | ||
72 | .id = V4L2_STD_PAL_BG, | ||
73 | }, { | ||
74 | .name = "PAL-DK", | ||
75 | .id = V4L2_STD_PAL_DK, | ||
76 | }, { | ||
77 | .name = "PAL-I", | ||
78 | .id = V4L2_STD_PAL_I, | ||
79 | }, { | ||
80 | .name = "PAL-M", | ||
81 | .id = V4L2_STD_PAL_M, | ||
82 | }, { | ||
83 | .name = "PAL-N", | ||
84 | .id = V4L2_STD_PAL_N, | ||
85 | }, { | ||
86 | .name = "PAL-Nc", | ||
87 | .id = V4L2_STD_PAL_Nc, | ||
88 | }, { | ||
89 | .name = "PAL-60", | ||
90 | .id = V4L2_STD_PAL_60, | ||
91 | }, { | ||
92 | .name = "SECAM-L", | ||
93 | .id = V4L2_STD_SECAM_L, | ||
94 | }, { | ||
95 | .name = "SECAM-DK", | ||
96 | .id = V4L2_STD_SECAM_DK, | ||
97 | } | ||
98 | }; | ||
99 | |||
100 | /* ------------------------------------------------------------------ */ | ||
101 | enum cx23885_capture_type { | ||
102 | CX23885_MPEG_CAPTURE, | ||
103 | CX23885_RAW_CAPTURE, | ||
104 | CX23885_RAW_PASSTHRU_CAPTURE | ||
105 | }; | ||
106 | enum cx23885_capture_bits { | ||
107 | CX23885_RAW_BITS_NONE = 0x00, | ||
108 | CX23885_RAW_BITS_YUV_CAPTURE = 0x01, | ||
109 | CX23885_RAW_BITS_PCM_CAPTURE = 0x02, | ||
110 | CX23885_RAW_BITS_VBI_CAPTURE = 0x04, | ||
111 | CX23885_RAW_BITS_PASSTHRU_CAPTURE = 0x08, | ||
112 | CX23885_RAW_BITS_TO_HOST_CAPTURE = 0x10 | ||
113 | }; | ||
114 | enum cx23885_capture_end { | ||
115 | CX23885_END_AT_GOP, /* stop at the end of gop, generate irq */ | ||
116 | CX23885_END_NOW, /* stop immediately, no irq */ | ||
117 | }; | ||
118 | enum cx23885_framerate { | ||
119 | CX23885_FRAMERATE_NTSC_30, /* NTSC: 30fps */ | ||
120 | CX23885_FRAMERATE_PAL_25 /* PAL: 25fps */ | ||
121 | }; | ||
122 | enum cx23885_stream_port { | ||
123 | CX23885_OUTPUT_PORT_MEMORY, | ||
124 | CX23885_OUTPUT_PORT_STREAMING, | ||
125 | CX23885_OUTPUT_PORT_SERIAL | ||
126 | }; | ||
127 | enum cx23885_data_xfer_status { | ||
128 | CX23885_MORE_BUFFERS_FOLLOW, | ||
129 | CX23885_LAST_BUFFER, | ||
130 | }; | ||
131 | enum cx23885_picture_mask { | ||
132 | CX23885_PICTURE_MASK_NONE, | ||
133 | CX23885_PICTURE_MASK_I_FRAMES, | ||
134 | CX23885_PICTURE_MASK_I_P_FRAMES = 0x3, | ||
135 | CX23885_PICTURE_MASK_ALL_FRAMES = 0x7, | ||
136 | }; | ||
137 | enum cx23885_vbi_mode_bits { | ||
138 | CX23885_VBI_BITS_SLICED, | ||
139 | CX23885_VBI_BITS_RAW, | ||
140 | }; | ||
141 | enum cx23885_vbi_insertion_bits { | ||
142 | CX23885_VBI_BITS_INSERT_IN_XTENSION_USR_DATA, | ||
143 | CX23885_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1, | ||
144 | CX23885_VBI_BITS_SEPARATE_STREAM = 0x2 << 1, | ||
145 | CX23885_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, | ||
146 | CX23885_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, | ||
147 | }; | ||
148 | enum cx23885_dma_unit { | ||
149 | CX23885_DMA_BYTES, | ||
150 | CX23885_DMA_FRAMES, | ||
151 | }; | ||
152 | enum cx23885_dma_transfer_status_bits { | ||
153 | CX23885_DMA_TRANSFER_BITS_DONE = 0x01, | ||
154 | CX23885_DMA_TRANSFER_BITS_ERROR = 0x04, | ||
155 | CX23885_DMA_TRANSFER_BITS_LL_ERROR = 0x10, | ||
156 | }; | ||
157 | enum cx23885_pause { | ||
158 | CX23885_PAUSE_ENCODING, | ||
159 | CX23885_RESUME_ENCODING, | ||
160 | }; | ||
161 | enum cx23885_copyright { | ||
162 | CX23885_COPYRIGHT_OFF, | ||
163 | CX23885_COPYRIGHT_ON, | ||
164 | }; | ||
165 | enum cx23885_notification_type { | ||
166 | CX23885_NOTIFICATION_REFRESH, | ||
167 | }; | ||
168 | enum cx23885_notification_status { | ||
169 | CX23885_NOTIFICATION_OFF, | ||
170 | CX23885_NOTIFICATION_ON, | ||
171 | }; | ||
172 | enum cx23885_notification_mailbox { | ||
173 | CX23885_NOTIFICATION_NO_MAILBOX = -1, | ||
174 | }; | ||
175 | enum cx23885_field1_lines { | ||
176 | CX23885_FIELD1_SAA7114 = 0x00EF, /* 239 */ | ||
177 | CX23885_FIELD1_SAA7115 = 0x00F0, /* 240 */ | ||
178 | CX23885_FIELD1_MICRONAS = 0x0105, /* 261 */ | ||
179 | }; | ||
180 | enum cx23885_field2_lines { | ||
181 | CX23885_FIELD2_SAA7114 = 0x00EF, /* 239 */ | ||
182 | CX23885_FIELD2_SAA7115 = 0x00F0, /* 240 */ | ||
183 | CX23885_FIELD2_MICRONAS = 0x0106, /* 262 */ | ||
184 | }; | ||
185 | enum cx23885_custom_data_type { | ||
186 | CX23885_CUSTOM_EXTENSION_USR_DATA, | ||
187 | CX23885_CUSTOM_PRIVATE_PACKET, | ||
188 | }; | ||
189 | enum cx23885_mute { | ||
190 | CX23885_UNMUTE, | ||
191 | CX23885_MUTE, | ||
192 | }; | ||
193 | enum cx23885_mute_video_mask { | ||
194 | CX23885_MUTE_VIDEO_V_MASK = 0x0000FF00, | ||
195 | CX23885_MUTE_VIDEO_U_MASK = 0x00FF0000, | ||
196 | CX23885_MUTE_VIDEO_Y_MASK = 0xFF000000, | ||
197 | }; | ||
198 | enum cx23885_mute_video_shift { | ||
199 | CX23885_MUTE_VIDEO_V_SHIFT = 8, | ||
200 | CX23885_MUTE_VIDEO_U_SHIFT = 16, | ||
201 | CX23885_MUTE_VIDEO_Y_SHIFT = 24, | ||
202 | }; | ||
203 | |||
204 | /* defines below are from ivtv-driver.h */ | ||
205 | #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF | ||
206 | |||
207 | /* Firmware API commands */ | ||
208 | #define IVTV_API_STD_TIMEOUT 500 | ||
209 | |||
210 | /* Registers */ | ||
211 | /* IVTV_REG_OFFSET */ | ||
212 | #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8) | ||
213 | #define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC) | ||
214 | #define IVTV_REG_SPU (0x9050) | ||
215 | #define IVTV_REG_HW_BLOCKS (0x9054) | ||
216 | #define IVTV_REG_VPU (0x9058) | ||
217 | #define IVTV_REG_APU (0xA064) | ||
218 | |||
219 | /**** Bit definitions for MC417_RWD and MC417_OEN registers *** | ||
220 | bits 31-16 | ||
221 | +-----------+ | ||
222 | | Reserved | | ||
223 | +-----------+ | ||
224 | bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8 | ||
225 | +-------+-------+-------+-------+-------+-------+-------+-------+ | ||
226 | | MIWR# | MIRD# | MICS# |MIRDY# |MIADDR3|MIADDR2|MIADDR1|MIADDR0| | ||
227 | +-------+-------+-------+-------+-------+-------+-------+-------+ | ||
228 | bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 | ||
229 | +-------+-------+-------+-------+-------+-------+-------+-------+ | ||
230 | |MIDATA7|MIDATA6|MIDATA5|MIDATA4|MIDATA3|MIDATA2|MIDATA1|MIDATA0| | ||
231 | +-------+-------+-------+-------+-------+-------+-------+-------+ | ||
232 | ***/ | ||
233 | #define MC417_MIWR 0x8000 | ||
234 | #define MC417_MIRD 0x4000 | ||
235 | #define MC417_MICS 0x2000 | ||
236 | #define MC417_MIRDY 0x1000 | ||
237 | #define MC417_MIADDR 0x0F00 | ||
238 | #define MC417_MIDATA 0x00FF | ||
239 | |||
240 | /* MIADDR* nibble definitions */ | ||
241 | #define MCI_MEMORY_DATA_BYTE0 0x000 | ||
242 | #define MCI_MEMORY_DATA_BYTE1 0x100 | ||
243 | #define MCI_MEMORY_DATA_BYTE2 0x200 | ||
244 | #define MCI_MEMORY_DATA_BYTE3 0x300 | ||
245 | #define MCI_MEMORY_ADDRESS_BYTE2 0x400 | ||
246 | #define MCI_MEMORY_ADDRESS_BYTE1 0x500 | ||
247 | #define MCI_MEMORY_ADDRESS_BYTE0 0x600 | ||
248 | #define MCI_REGISTER_DATA_BYTE0 0x800 | ||
249 | #define MCI_REGISTER_DATA_BYTE1 0x900 | ||
250 | #define MCI_REGISTER_DATA_BYTE2 0xA00 | ||
251 | #define MCI_REGISTER_DATA_BYTE3 0xB00 | ||
252 | #define MCI_REGISTER_ADDRESS_BYTE0 0xC00 | ||
253 | #define MCI_REGISTER_ADDRESS_BYTE1 0xD00 | ||
254 | #define MCI_REGISTER_MODE 0xE00 | ||
255 | |||
256 | /* Read and write modes */ | ||
257 | #define MCI_MODE_REGISTER_READ 0 | ||
258 | #define MCI_MODE_REGISTER_WRITE 1 | ||
259 | #define MCI_MODE_MEMORY_READ 0 | ||
260 | #define MCI_MODE_MEMORY_WRITE 0x40 | ||
261 | |||
262 | /*** Bit definitions for MC417_CTL register **** | ||
263 | bits 31-6 bits 5-4 bit 3 bits 2-1 Bit 0 | ||
264 | +--------+-------------+--------+--------------+------------+ | ||
265 | |Reserved|MC417_SPD_CTL|Reserved|MC417_GPIO_SEL|UART_GPIO_EN| | ||
266 | +--------+-------------+--------+--------------+------------+ | ||
267 | ***/ | ||
268 | #define MC417_SPD_CTL(x) (((x) << 4) & 0x00000030) | ||
269 | #define MC417_GPIO_SEL(x) (((x) << 1) & 0x00000006) | ||
270 | #define MC417_UART_GPIO_EN 0x00000001 | ||
271 | |||
272 | /* Values for speed control */ | ||
273 | #define MC417_SPD_CTL_SLOW 0x1 | ||
274 | #define MC417_SPD_CTL_MEDIUM 0x0 | ||
275 | #define MC417_SPD_CTL_FAST 0x3 /* b'1x, but we use b'11 */ | ||
276 | |||
277 | /* Values for GPIO select */ | ||
278 | #define MC417_GPIO_SEL_GPIO3 0x3 | ||
279 | #define MC417_GPIO_SEL_GPIO2 0x2 | ||
280 | #define MC417_GPIO_SEL_GPIO1 0x1 | ||
281 | #define MC417_GPIO_SEL_GPIO0 0x0 | ||
282 | |||
283 | void cx23885_mc417_init(struct cx23885_dev *dev) | ||
284 | { | ||
285 | u32 regval; | ||
286 | |||
287 | dprintk(2, "%s()\n", __func__); | ||
288 | |||
289 | /* Configure MC417_CTL register to defaults. */ | ||
290 | regval = MC417_SPD_CTL(MC417_SPD_CTL_FAST) | | ||
291 | MC417_GPIO_SEL(MC417_GPIO_SEL_GPIO3) | | ||
292 | MC417_UART_GPIO_EN; | ||
293 | cx_write(MC417_CTL, regval); | ||
294 | |||
295 | /* Configure MC417_OEN to defaults. */ | ||
296 | regval = MC417_MIRDY; | ||
297 | cx_write(MC417_OEN, regval); | ||
298 | |||
299 | /* Configure MC417_RWD to defaults. */ | ||
300 | regval = MC417_MIWR | MC417_MIRD | MC417_MICS; | ||
301 | cx_write(MC417_RWD, regval); | ||
302 | } | ||
303 | |||
304 | static int mc417_wait_ready(struct cx23885_dev *dev) | ||
305 | { | ||
306 | u32 mi_ready; | ||
307 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
308 | |||
309 | for (;;) { | ||
310 | mi_ready = cx_read(MC417_RWD) & MC417_MIRDY; | ||
311 | if (mi_ready != 0) | ||
312 | return 0; | ||
313 | if (time_after(jiffies, timeout)) | ||
314 | return -1; | ||
315 | udelay(1); | ||
316 | } | ||
317 | } | ||
318 | |||
319 | static int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value) | ||
320 | { | ||
321 | u32 regval; | ||
322 | |||
323 | /* Enable MC417 GPIO outputs except for MC417_MIRDY, | ||
324 | * which is an input. | ||
325 | */ | ||
326 | cx_write(MC417_OEN, MC417_MIRDY); | ||
327 | |||
328 | /* Write data byte 0 */ | ||
329 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0 | | ||
330 | (value & 0x000000FF); | ||
331 | cx_write(MC417_RWD, regval); | ||
332 | |||
333 | /* Transition CS/WR to effect write transaction across bus. */ | ||
334 | regval |= MC417_MICS | MC417_MIWR; | ||
335 | cx_write(MC417_RWD, regval); | ||
336 | |||
337 | /* Write data byte 1 */ | ||
338 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1 | | ||
339 | ((value >> 8) & 0x000000FF); | ||
340 | cx_write(MC417_RWD, regval); | ||
341 | regval |= MC417_MICS | MC417_MIWR; | ||
342 | cx_write(MC417_RWD, regval); | ||
343 | |||
344 | /* Write data byte 2 */ | ||
345 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2 | | ||
346 | ((value >> 16) & 0x000000FF); | ||
347 | cx_write(MC417_RWD, regval); | ||
348 | regval |= MC417_MICS | MC417_MIWR; | ||
349 | cx_write(MC417_RWD, regval); | ||
350 | |||
351 | /* Write data byte 3 */ | ||
352 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3 | | ||
353 | ((value >> 24) & 0x000000FF); | ||
354 | cx_write(MC417_RWD, regval); | ||
355 | regval |= MC417_MICS | MC417_MIWR; | ||
356 | cx_write(MC417_RWD, regval); | ||
357 | |||
358 | /* Write address byte 0 */ | ||
359 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE0 | | ||
360 | (address & 0xFF); | ||
361 | cx_write(MC417_RWD, regval); | ||
362 | regval |= MC417_MICS | MC417_MIWR; | ||
363 | cx_write(MC417_RWD, regval); | ||
364 | |||
365 | /* Write address byte 1 */ | ||
366 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE1 | | ||
367 | ((address >> 8) & 0xFF); | ||
368 | cx_write(MC417_RWD, regval); | ||
369 | regval |= MC417_MICS | MC417_MIWR; | ||
370 | cx_write(MC417_RWD, regval); | ||
371 | |||
372 | /* Indicate that this is a write. */ | ||
373 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_MODE | | ||
374 | MCI_MODE_REGISTER_WRITE; | ||
375 | cx_write(MC417_RWD, regval); | ||
376 | regval |= MC417_MICS | MC417_MIWR; | ||
377 | cx_write(MC417_RWD, regval); | ||
378 | |||
379 | /* Wait for the trans to complete (MC417_MIRDY asserted). */ | ||
380 | return mc417_wait_ready(dev); | ||
381 | } | ||
382 | |||
383 | static int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value) | ||
384 | { | ||
385 | int retval; | ||
386 | u32 regval; | ||
387 | u32 tempval; | ||
388 | u32 dataval; | ||
389 | |||
390 | /* Enable MC417 GPIO outputs except for MC417_MIRDY, | ||
391 | * which is an input. | ||
392 | */ | ||
393 | cx_write(MC417_OEN, MC417_MIRDY); | ||
394 | |||
395 | /* Write address byte 0 */ | ||
396 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE0 | | ||
397 | ((address & 0x00FF)); | ||
398 | cx_write(MC417_RWD, regval); | ||
399 | regval |= MC417_MICS | MC417_MIWR; | ||
400 | cx_write(MC417_RWD, regval); | ||
401 | |||
402 | /* Write address byte 1 */ | ||
403 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE1 | | ||
404 | ((address >> 8) & 0xFF); | ||
405 | cx_write(MC417_RWD, regval); | ||
406 | regval |= MC417_MICS | MC417_MIWR; | ||
407 | cx_write(MC417_RWD, regval); | ||
408 | |||
409 | /* Indicate that this is a register read. */ | ||
410 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_MODE | | ||
411 | MCI_MODE_REGISTER_READ; | ||
412 | cx_write(MC417_RWD, regval); | ||
413 | regval |= MC417_MICS | MC417_MIWR; | ||
414 | cx_write(MC417_RWD, regval); | ||
415 | |||
416 | /* Wait for the trans to complete (MC417_MIRDY asserted). */ | ||
417 | retval = mc417_wait_ready(dev); | ||
418 | |||
419 | /* switch the DAT0-7 GPIO[10:3] to input mode */ | ||
420 | cx_write(MC417_OEN, MC417_MIRDY | MC417_MIDATA); | ||
421 | |||
422 | /* Read data byte 0 */ | ||
423 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0; | ||
424 | cx_write(MC417_RWD, regval); | ||
425 | |||
426 | /* Transition RD to effect read transaction across bus. | ||
427 | * Transtion 0x5000 -> 0x9000 correct (RD/RDY -> WR/RDY)? | ||
428 | * Should it be 0x9000 -> 0xF000 (also why is RDY being set, its | ||
429 | * input only...) | ||
430 | */ | ||
431 | regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0; | ||
432 | cx_write(MC417_RWD, regval); | ||
433 | |||
434 | /* Collect byte */ | ||
435 | tempval = cx_read(MC417_RWD); | ||
436 | dataval = tempval & 0x000000FF; | ||
437 | |||
438 | /* Bring CS and RD high. */ | ||
439 | regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; | ||
440 | cx_write(MC417_RWD, regval); | ||
441 | |||
442 | /* Read data byte 1 */ | ||
443 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1; | ||
444 | cx_write(MC417_RWD, regval); | ||
445 | regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1; | ||
446 | cx_write(MC417_RWD, regval); | ||
447 | tempval = cx_read(MC417_RWD); | ||
448 | dataval |= ((tempval & 0x000000FF) << 8); | ||
449 | regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; | ||
450 | cx_write(MC417_RWD, regval); | ||
451 | |||
452 | /* Read data byte 2 */ | ||
453 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2; | ||
454 | cx_write(MC417_RWD, regval); | ||
455 | regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2; | ||
456 | cx_write(MC417_RWD, regval); | ||
457 | tempval = cx_read(MC417_RWD); | ||
458 | dataval |= ((tempval & 0x000000FF) << 16); | ||
459 | regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; | ||
460 | cx_write(MC417_RWD, regval); | ||
461 | |||
462 | /* Read data byte 3 */ | ||
463 | regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3; | ||
464 | cx_write(MC417_RWD, regval); | ||
465 | regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3; | ||
466 | cx_write(MC417_RWD, regval); | ||
467 | tempval = cx_read(MC417_RWD); | ||
468 | dataval |= ((tempval & 0x000000FF) << 24); | ||
469 | regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; | ||
470 | cx_write(MC417_RWD, regval); | ||
471 | |||
472 | *value = dataval; | ||
473 | |||
474 | return retval; | ||
475 | } | ||
476 | |||
477 | int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value) | ||
478 | { | ||
479 | u32 regval; | ||
480 | |||
481 | /* Enable MC417 GPIO outputs except for MC417_MIRDY, | ||
482 | * which is an input. | ||
483 | */ | ||
484 | cx_write(MC417_OEN, MC417_MIRDY); | ||
485 | |||
486 | /* Write data byte 0 */ | ||
487 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0 | | ||
488 | (value & 0x000000FF); | ||
489 | cx_write(MC417_RWD, regval); | ||
490 | |||
491 | /* Transition CS/WR to effect write transaction across bus. */ | ||
492 | regval |= MC417_MICS | MC417_MIWR; | ||
493 | cx_write(MC417_RWD, regval); | ||
494 | |||
495 | /* Write data byte 1 */ | ||
496 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1 | | ||
497 | ((value >> 8) & 0x000000FF); | ||
498 | cx_write(MC417_RWD, regval); | ||
499 | regval |= MC417_MICS | MC417_MIWR; | ||
500 | cx_write(MC417_RWD, regval); | ||
501 | |||
502 | /* Write data byte 2 */ | ||
503 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2 | | ||
504 | ((value >> 16) & 0x000000FF); | ||
505 | cx_write(MC417_RWD, regval); | ||
506 | regval |= MC417_MICS | MC417_MIWR; | ||
507 | cx_write(MC417_RWD, regval); | ||
508 | |||
509 | /* Write data byte 3 */ | ||
510 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3 | | ||
511 | ((value >> 24) & 0x000000FF); | ||
512 | cx_write(MC417_RWD, regval); | ||
513 | regval |= MC417_MICS | MC417_MIWR; | ||
514 | cx_write(MC417_RWD, regval); | ||
515 | |||
516 | /* Write address byte 2 */ | ||
517 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE2 | | ||
518 | MCI_MODE_MEMORY_WRITE | ((address >> 16) & 0x3F); | ||
519 | cx_write(MC417_RWD, regval); | ||
520 | regval |= MC417_MICS | MC417_MIWR; | ||
521 | cx_write(MC417_RWD, regval); | ||
522 | |||
523 | /* Write address byte 1 */ | ||
524 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE1 | | ||
525 | ((address >> 8) & 0xFF); | ||
526 | cx_write(MC417_RWD, regval); | ||
527 | regval |= MC417_MICS | MC417_MIWR; | ||
528 | cx_write(MC417_RWD, regval); | ||
529 | |||
530 | /* Write address byte 0 */ | ||
531 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE0 | | ||
532 | (address & 0xFF); | ||
533 | cx_write(MC417_RWD, regval); | ||
534 | regval |= MC417_MICS | MC417_MIWR; | ||
535 | cx_write(MC417_RWD, regval); | ||
536 | |||
537 | /* Wait for the trans to complete (MC417_MIRDY asserted). */ | ||
538 | return mc417_wait_ready(dev); | ||
539 | } | ||
540 | |||
541 | int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value) | ||
542 | { | ||
543 | int retval; | ||
544 | u32 regval; | ||
545 | u32 tempval; | ||
546 | u32 dataval; | ||
547 | |||
548 | /* Enable MC417 GPIO outputs except for MC417_MIRDY, | ||
549 | * which is an input. | ||
550 | */ | ||
551 | cx_write(MC417_OEN, MC417_MIRDY); | ||
552 | |||
553 | /* Write address byte 2 */ | ||
554 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE2 | | ||
555 | MCI_MODE_MEMORY_READ | ((address >> 16) & 0x3F); | ||
556 | cx_write(MC417_RWD, regval); | ||
557 | regval |= MC417_MICS | MC417_MIWR; | ||
558 | cx_write(MC417_RWD, regval); | ||
559 | |||
560 | /* Write address byte 1 */ | ||
561 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE1 | | ||
562 | ((address >> 8) & 0xFF); | ||
563 | cx_write(MC417_RWD, regval); | ||
564 | regval |= MC417_MICS | MC417_MIWR; | ||
565 | cx_write(MC417_RWD, regval); | ||
566 | |||
567 | /* Write address byte 0 */ | ||
568 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE0 | | ||
569 | (address & 0xFF); | ||
570 | cx_write(MC417_RWD, regval); | ||
571 | regval |= MC417_MICS | MC417_MIWR; | ||
572 | cx_write(MC417_RWD, regval); | ||
573 | |||
574 | /* Wait for the trans to complete (MC417_MIRDY asserted). */ | ||
575 | retval = mc417_wait_ready(dev); | ||
576 | |||
577 | /* switch the DAT0-7 GPIO[10:3] to input mode */ | ||
578 | cx_write(MC417_OEN, MC417_MIRDY | MC417_MIDATA); | ||
579 | |||
580 | /* Read data byte 3 */ | ||
581 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3; | ||
582 | cx_write(MC417_RWD, regval); | ||
583 | |||
584 | /* Transition RD to effect read transaction across bus. */ | ||
585 | regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3; | ||
586 | cx_write(MC417_RWD, regval); | ||
587 | |||
588 | /* Collect byte */ | ||
589 | tempval = cx_read(MC417_RWD); | ||
590 | dataval = ((tempval & 0x000000FF) << 24); | ||
591 | |||
592 | /* Bring CS and RD high. */ | ||
593 | regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; | ||
594 | cx_write(MC417_RWD, regval); | ||
595 | |||
596 | /* Read data byte 2 */ | ||
597 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2; | ||
598 | cx_write(MC417_RWD, regval); | ||
599 | regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2; | ||
600 | cx_write(MC417_RWD, regval); | ||
601 | tempval = cx_read(MC417_RWD); | ||
602 | dataval |= ((tempval & 0x000000FF) << 16); | ||
603 | regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; | ||
604 | cx_write(MC417_RWD, regval); | ||
605 | |||
606 | /* Read data byte 1 */ | ||
607 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1; | ||
608 | cx_write(MC417_RWD, regval); | ||
609 | regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1; | ||
610 | cx_write(MC417_RWD, regval); | ||
611 | tempval = cx_read(MC417_RWD); | ||
612 | dataval |= ((tempval & 0x000000FF) << 8); | ||
613 | regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; | ||
614 | cx_write(MC417_RWD, regval); | ||
615 | |||
616 | /* Read data byte 0 */ | ||
617 | regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0; | ||
618 | cx_write(MC417_RWD, regval); | ||
619 | regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0; | ||
620 | cx_write(MC417_RWD, regval); | ||
621 | tempval = cx_read(MC417_RWD); | ||
622 | dataval |= (tempval & 0x000000FF); | ||
623 | regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; | ||
624 | cx_write(MC417_RWD, regval); | ||
625 | |||
626 | *value = dataval; | ||
627 | |||
628 | return retval; | ||
629 | } | ||
630 | |||
631 | /* ------------------------------------------------------------------ */ | ||
632 | |||
633 | /* MPEG encoder API */ | ||
634 | char *cmd_to_str(int cmd) | ||
635 | { | ||
636 | switch (cmd) { | ||
637 | case CX2341X_ENC_PING_FW: | ||
638 | return "PING_FW"; | ||
639 | case CX2341X_ENC_START_CAPTURE: | ||
640 | return "START_CAPTURE"; | ||
641 | case CX2341X_ENC_STOP_CAPTURE: | ||
642 | return "STOP_CAPTURE"; | ||
643 | case CX2341X_ENC_SET_AUDIO_ID: | ||
644 | return "SET_AUDIO_ID"; | ||
645 | case CX2341X_ENC_SET_VIDEO_ID: | ||
646 | return "SET_VIDEO_ID"; | ||
647 | case CX2341X_ENC_SET_PCR_ID: | ||
648 | return "SET_PCR_PID"; | ||
649 | case CX2341X_ENC_SET_FRAME_RATE: | ||
650 | return "SET_FRAME_RATE"; | ||
651 | case CX2341X_ENC_SET_FRAME_SIZE: | ||
652 | return "SET_FRAME_SIZE"; | ||
653 | case CX2341X_ENC_SET_BIT_RATE: | ||
654 | return "SET_BIT_RATE"; | ||
655 | case CX2341X_ENC_SET_GOP_PROPERTIES: | ||
656 | return "SET_GOP_PROPERTIES"; | ||
657 | case CX2341X_ENC_SET_ASPECT_RATIO: | ||
658 | return "SET_ASPECT_RATIO"; | ||
659 | case CX2341X_ENC_SET_DNR_FILTER_MODE: | ||
660 | return "SET_DNR_FILTER_PROPS"; | ||
661 | case CX2341X_ENC_SET_DNR_FILTER_PROPS: | ||
662 | return "SET_DNR_FILTER_PROPS"; | ||
663 | case CX2341X_ENC_SET_CORING_LEVELS: | ||
664 | return "SET_CORING_LEVELS"; | ||
665 | case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE: | ||
666 | return "SET_SPATIAL_FILTER_TYPE"; | ||
667 | case CX2341X_ENC_SET_VBI_LINE: | ||
668 | return "SET_VBI_LINE"; | ||
669 | case CX2341X_ENC_SET_STREAM_TYPE: | ||
670 | return "SET_STREAM_TYPE"; | ||
671 | case CX2341X_ENC_SET_OUTPUT_PORT: | ||
672 | return "SET_OUTPUT_PORT"; | ||
673 | case CX2341X_ENC_SET_AUDIO_PROPERTIES: | ||
674 | return "SET_AUDIO_PROPERTIES"; | ||
675 | case CX2341X_ENC_HALT_FW: | ||
676 | return "HALT_FW"; | ||
677 | case CX2341X_ENC_GET_VERSION: | ||
678 | return "GET_VERSION"; | ||
679 | case CX2341X_ENC_SET_GOP_CLOSURE: | ||
680 | return "SET_GOP_CLOSURE"; | ||
681 | case CX2341X_ENC_GET_SEQ_END: | ||
682 | return "GET_SEQ_END"; | ||
683 | case CX2341X_ENC_SET_PGM_INDEX_INFO: | ||
684 | return "SET_PGM_INDEX_INFO"; | ||
685 | case CX2341X_ENC_SET_VBI_CONFIG: | ||
686 | return "SET_VBI_CONFIG"; | ||
687 | case CX2341X_ENC_SET_DMA_BLOCK_SIZE: | ||
688 | return "SET_DMA_BLOCK_SIZE"; | ||
689 | case CX2341X_ENC_GET_PREV_DMA_INFO_MB_10: | ||
690 | return "GET_PREV_DMA_INFO_MB_10"; | ||
691 | case CX2341X_ENC_GET_PREV_DMA_INFO_MB_9: | ||
692 | return "GET_PREV_DMA_INFO_MB_9"; | ||
693 | case CX2341X_ENC_SCHED_DMA_TO_HOST: | ||
694 | return "SCHED_DMA_TO_HOST"; | ||
695 | case CX2341X_ENC_INITIALIZE_INPUT: | ||
696 | return "INITIALIZE_INPUT"; | ||
697 | case CX2341X_ENC_SET_FRAME_DROP_RATE: | ||
698 | return "SET_FRAME_DROP_RATE"; | ||
699 | case CX2341X_ENC_PAUSE_ENCODER: | ||
700 | return "PAUSE_ENCODER"; | ||
701 | case CX2341X_ENC_REFRESH_INPUT: | ||
702 | return "REFRESH_INPUT"; | ||
703 | case CX2341X_ENC_SET_COPYRIGHT: | ||
704 | return "SET_COPYRIGHT"; | ||
705 | case CX2341X_ENC_SET_EVENT_NOTIFICATION: | ||
706 | return "SET_EVENT_NOTIFICATION"; | ||
707 | case CX2341X_ENC_SET_NUM_VSYNC_LINES: | ||
708 | return "SET_NUM_VSYNC_LINES"; | ||
709 | case CX2341X_ENC_SET_PLACEHOLDER: | ||
710 | return "SET_PLACEHOLDER"; | ||
711 | case CX2341X_ENC_MUTE_VIDEO: | ||
712 | return "MUTE_VIDEO"; | ||
713 | case CX2341X_ENC_MUTE_AUDIO: | ||
714 | return "MUTE_AUDIO"; | ||
715 | case CX2341X_ENC_MISC: | ||
716 | return "MISC"; | ||
717 | default: | ||
718 | return "UNKNOWN"; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | static int cx23885_mbox_func(void *priv, | ||
723 | u32 command, | ||
724 | int in, | ||
725 | int out, | ||
726 | u32 data[CX2341X_MBOX_MAX_DATA]) | ||
727 | { | ||
728 | struct cx23885_dev *dev = priv; | ||
729 | unsigned long timeout; | ||
730 | u32 value, flag, retval = 0; | ||
731 | int i; | ||
732 | |||
733 | dprintk(3, "%s: command(0x%X) = %s\n", __func__, command, | ||
734 | cmd_to_str(command)); | ||
735 | |||
736 | /* this may not be 100% safe if we can't read any memory location | ||
737 | without side effects */ | ||
738 | mc417_memory_read(dev, dev->cx23417_mailbox - 4, &value); | ||
739 | if (value != 0x12345678) { | ||
740 | printk(KERN_ERR | ||
741 | "Firmware and/or mailbox pointer not initialized " | ||
742 | "or corrupted, signature = 0x%x, cmd = %s\n", value, | ||
743 | cmd_to_str(command)); | ||
744 | return -1; | ||
745 | } | ||
746 | |||
747 | /* This read looks at 32 bits, but flag is only 8 bits. | ||
748 | * Seems we also bail if CMD or TIMEOUT bytes are set??? | ||
749 | */ | ||
750 | mc417_memory_read(dev, dev->cx23417_mailbox, &flag); | ||
751 | if (flag) { | ||
752 | printk(KERN_ERR "ERROR: Mailbox appears to be in use " | ||
753 | "(%x), cmd = %s\n", flag, cmd_to_str(command)); | ||
754 | return -1; | ||
755 | } | ||
756 | |||
757 | flag |= 1; /* tell 'em we're working on it */ | ||
758 | mc417_memory_write(dev, dev->cx23417_mailbox, flag); | ||
759 | |||
760 | /* write command + args + fill remaining with zeros */ | ||
761 | /* command code */ | ||
762 | mc417_memory_write(dev, dev->cx23417_mailbox + 1, command); | ||
763 | mc417_memory_write(dev, dev->cx23417_mailbox + 3, | ||
764 | IVTV_API_STD_TIMEOUT); /* timeout */ | ||
765 | for (i = 0; i < in; i++) { | ||
766 | mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, data[i]); | ||
767 | dprintk(3, "API Input %d = %d\n", i, data[i]); | ||
768 | } | ||
769 | for (; i < CX2341X_MBOX_MAX_DATA; i++) | ||
770 | mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, 0); | ||
771 | |||
772 | flag |= 3; /* tell 'em we're done writing */ | ||
773 | mc417_memory_write(dev, dev->cx23417_mailbox, flag); | ||
774 | |||
775 | /* wait for firmware to handle the API command */ | ||
776 | timeout = jiffies + msecs_to_jiffies(10); | ||
777 | for (;;) { | ||
778 | mc417_memory_read(dev, dev->cx23417_mailbox, &flag); | ||
779 | if (0 != (flag & 4)) | ||
780 | break; | ||
781 | if (time_after(jiffies, timeout)) { | ||
782 | printk(KERN_ERR "ERROR: API Mailbox timeout\n"); | ||
783 | return -1; | ||
784 | } | ||
785 | udelay(10); | ||
786 | } | ||
787 | |||
788 | /* read output values */ | ||
789 | for (i = 0; i < out; i++) { | ||
790 | mc417_memory_read(dev, dev->cx23417_mailbox + 4 + i, data + i); | ||
791 | dprintk(3, "API Output %d = %d\n", i, data[i]); | ||
792 | } | ||
793 | |||
794 | mc417_memory_read(dev, dev->cx23417_mailbox + 2, &retval); | ||
795 | dprintk(3, "API result = %d\n", retval); | ||
796 | |||
797 | flag = 0; | ||
798 | mc417_memory_write(dev, dev->cx23417_mailbox, flag); | ||
799 | |||
800 | return retval; | ||
801 | } | ||
802 | |||
803 | /* We don't need to call the API often, so using just one | ||
804 | * mailbox will probably suffice | ||
805 | */ | ||
806 | static int cx23885_api_cmd(struct cx23885_dev *dev, | ||
807 | u32 command, | ||
808 | u32 inputcnt, | ||
809 | u32 outputcnt, | ||
810 | ...) | ||
811 | { | ||
812 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
813 | va_list vargs; | ||
814 | int i, err; | ||
815 | |||
816 | dprintk(3, "%s() cmds = 0x%08x\n", __func__, command); | ||
817 | |||
818 | va_start(vargs, outputcnt); | ||
819 | for (i = 0; i < inputcnt; i++) | ||
820 | data[i] = va_arg(vargs, int); | ||
821 | |||
822 | err = cx23885_mbox_func(dev, command, inputcnt, outputcnt, data); | ||
823 | for (i = 0; i < outputcnt; i++) { | ||
824 | int *vptr = va_arg(vargs, int *); | ||
825 | *vptr = data[i]; | ||
826 | } | ||
827 | va_end(vargs); | ||
828 | |||
829 | return err; | ||
830 | } | ||
831 | |||
832 | static int cx23885_find_mailbox(struct cx23885_dev *dev) | ||
833 | { | ||
834 | u32 signature[4] = { | ||
835 | 0x12345678, 0x34567812, 0x56781234, 0x78123456 | ||
836 | }; | ||
837 | int signaturecnt = 0; | ||
838 | u32 value; | ||
839 | int i; | ||
840 | |||
841 | dprintk(2, "%s()\n", __func__); | ||
842 | |||
843 | for (i = 0; i < CX23885_FIRM_IMAGE_SIZE; i++) { | ||
844 | mc417_memory_read(dev, i, &value); | ||
845 | if (value == signature[signaturecnt]) | ||
846 | signaturecnt++; | ||
847 | else | ||
848 | signaturecnt = 0; | ||
849 | if (4 == signaturecnt) { | ||
850 | dprintk(1, "Mailbox signature found at 0x%x\n", i+1); | ||
851 | return i+1; | ||
852 | } | ||
853 | } | ||
854 | printk(KERN_ERR "Mailbox signature values not found!\n"); | ||
855 | return -1; | ||
856 | } | ||
857 | |||
858 | static int cx23885_load_firmware(struct cx23885_dev *dev) | ||
859 | { | ||
860 | static const unsigned char magic[8] = { | ||
861 | 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa | ||
862 | }; | ||
863 | const struct firmware *firmware; | ||
864 | int i, retval = 0; | ||
865 | u32 value = 0; | ||
866 | u32 gpio_output = 0; | ||
867 | u32 checksum = 0; | ||
868 | u32 *dataptr; | ||
869 | |||
870 | dprintk(2, "%s()\n", __func__); | ||
871 | |||
872 | /* Save GPIO settings before reset of APU */ | ||
873 | retval |= mc417_memory_read(dev, 0x9020, &gpio_output); | ||
874 | retval |= mc417_memory_read(dev, 0x900C, &value); | ||
875 | |||
876 | retval = mc417_register_write(dev, | ||
877 | IVTV_REG_VPU, 0xFFFFFFED); | ||
878 | retval |= mc417_register_write(dev, | ||
879 | IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); | ||
880 | retval |= mc417_register_write(dev, | ||
881 | IVTV_REG_ENC_SDRAM_REFRESH, 0x80000800); | ||
882 | retval |= mc417_register_write(dev, | ||
883 | IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); | ||
884 | retval |= mc417_register_write(dev, | ||
885 | IVTV_REG_APU, 0); | ||
886 | |||
887 | if (retval != 0) { | ||
888 | printk(KERN_ERR "%s: Error with mc417_register_write\n", | ||
889 | __func__); | ||
890 | return -1; | ||
891 | } | ||
892 | |||
893 | retval = request_firmware(&firmware, CX23885_FIRM_IMAGE_NAME, | ||
894 | &dev->pci->dev); | ||
895 | |||
896 | if (retval != 0) { | ||
897 | printk(KERN_ERR | ||
898 | "ERROR: Hotplug firmware request failed (%s).\n", | ||
899 | CX2341X_FIRM_ENC_FILENAME); | ||
900 | printk(KERN_ERR "Please fix your hotplug setup, the board will " | ||
901 | "not work without firmware loaded!\n"); | ||
902 | return -1; | ||
903 | } | ||
904 | |||
905 | if (firmware->size != CX23885_FIRM_IMAGE_SIZE) { | ||
906 | printk(KERN_ERR "ERROR: Firmware size mismatch " | ||
907 | "(have %zd, expected %d)\n", | ||
908 | firmware->size, CX23885_FIRM_IMAGE_SIZE); | ||
909 | release_firmware(firmware); | ||
910 | return -1; | ||
911 | } | ||
912 | |||
913 | if (0 != memcmp(firmware->data, magic, 8)) { | ||
914 | printk(KERN_ERR | ||
915 | "ERROR: Firmware magic mismatch, wrong file?\n"); | ||
916 | release_firmware(firmware); | ||
917 | return -1; | ||
918 | } | ||
919 | |||
920 | /* transfer to the chip */ | ||
921 | dprintk(2, "Loading firmware ...\n"); | ||
922 | dataptr = (u32 *)firmware->data; | ||
923 | for (i = 0; i < (firmware->size >> 2); i++) { | ||
924 | value = *dataptr; | ||
925 | checksum += ~value; | ||
926 | if (mc417_memory_write(dev, i, value) != 0) { | ||
927 | printk(KERN_ERR "ERROR: Loading firmware failed!\n"); | ||
928 | release_firmware(firmware); | ||
929 | return -1; | ||
930 | } | ||
931 | dataptr++; | ||
932 | } | ||
933 | |||
934 | /* read back to verify with the checksum */ | ||
935 | dprintk(1, "Verifying firmware ...\n"); | ||
936 | for (i--; i >= 0; i--) { | ||
937 | if (mc417_memory_read(dev, i, &value) != 0) { | ||
938 | printk(KERN_ERR "ERROR: Reading firmware failed!\n"); | ||
939 | release_firmware(firmware); | ||
940 | return -1; | ||
941 | } | ||
942 | checksum -= ~value; | ||
943 | } | ||
944 | if (checksum) { | ||
945 | printk(KERN_ERR | ||
946 | "ERROR: Firmware load failed (checksum mismatch).\n"); | ||
947 | release_firmware(firmware); | ||
948 | return -1; | ||
949 | } | ||
950 | release_firmware(firmware); | ||
951 | dprintk(1, "Firmware upload successful.\n"); | ||
952 | |||
953 | retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS, | ||
954 | IVTV_CMD_HW_BLOCKS_RST); | ||
955 | |||
956 | /* Restore GPIO settings, make sure EIO14 is enabled as an output. */ | ||
957 | dprintk(2, "%s: GPIO output EIO 0-15 was = 0x%x\n", | ||
958 | __func__, gpio_output); | ||
959 | /* Power-up seems to have GPIOs AFU. This was causing digital side | ||
960 | * to fail at power-up. Seems GPIOs should be set to 0x10ff0411 at | ||
961 | * power-up. | ||
962 | * gpio_output |= (1<<14); | ||
963 | */ | ||
964 | /* Note: GPIO14 is specific to the HVR1800 here */ | ||
965 | gpio_output = 0x10ff0411 | (1<<14); | ||
966 | retval |= mc417_register_write(dev, 0x9020, gpio_output | (1<<14)); | ||
967 | dprintk(2, "%s: GPIO output EIO 0-15 now = 0x%x\n", | ||
968 | __func__, gpio_output); | ||
969 | |||
970 | dprintk(1, "%s: GPIO value EIO 0-15 was = 0x%x\n", | ||
971 | __func__, value); | ||
972 | value |= (1<<14); | ||
973 | dprintk(1, "%s: GPIO value EIO 0-15 now = 0x%x\n", | ||
974 | __func__, value); | ||
975 | retval |= mc417_register_write(dev, 0x900C, value); | ||
976 | |||
977 | retval |= mc417_register_read(dev, IVTV_REG_VPU, &value); | ||
978 | retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8); | ||
979 | |||
980 | if (retval < 0) | ||
981 | printk(KERN_ERR "%s: Error with mc417_register_write\n", | ||
982 | __func__); | ||
983 | return 0; | ||
984 | } | ||
985 | |||
986 | void cx23885_417_check_encoder(struct cx23885_dev *dev) | ||
987 | { | ||
988 | u32 status, seq; | ||
989 | |||
990 | status = seq = 0; | ||
991 | cx23885_api_cmd(dev, CX2341X_ENC_GET_SEQ_END, 0, 2, &status, &seq); | ||
992 | dprintk(1, "%s() status = %d, seq = %d\n", __func__, status, seq); | ||
993 | } | ||
994 | |||
995 | static void cx23885_codec_settings(struct cx23885_dev *dev) | ||
996 | { | ||
997 | dprintk(1, "%s()\n", __func__); | ||
998 | |||
999 | /* assign frame size */ | ||
1000 | cx23885_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, | ||
1001 | dev->ts1.height, dev->ts1.width); | ||
1002 | |||
1003 | dev->mpeg_params.width = dev->ts1.width; | ||
1004 | dev->mpeg_params.height = dev->ts1.height; | ||
1005 | dev->mpeg_params.is_50hz = | ||
1006 | (dev->encodernorm.id & V4L2_STD_625_50) != 0; | ||
1007 | |||
1008 | cx2341x_update(dev, cx23885_mbox_func, NULL, &dev->mpeg_params); | ||
1009 | |||
1010 | cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1); | ||
1011 | cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1); | ||
1012 | } | ||
1013 | |||
1014 | static int cx23885_initialize_codec(struct cx23885_dev *dev) | ||
1015 | { | ||
1016 | int version; | ||
1017 | int retval; | ||
1018 | u32 i, data[7]; | ||
1019 | |||
1020 | dprintk(1, "%s()\n", __func__); | ||
1021 | |||
1022 | retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ | ||
1023 | if (retval < 0) { | ||
1024 | dprintk(2, "%s() PING OK\n", __func__); | ||
1025 | retval = cx23885_load_firmware(dev); | ||
1026 | if (retval < 0) { | ||
1027 | printk(KERN_ERR "%s() f/w load failed\n", __func__); | ||
1028 | return retval; | ||
1029 | } | ||
1030 | dev->cx23417_mailbox = cx23885_find_mailbox(dev); | ||
1031 | if (dev->cx23417_mailbox < 0) { | ||
1032 | printk(KERN_ERR "%s() mailbox < 0, error\n", | ||
1033 | __func__); | ||
1034 | return -1; | ||
1035 | } | ||
1036 | retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); | ||
1037 | if (retval < 0) { | ||
1038 | printk(KERN_ERR | ||
1039 | "ERROR: cx23417 firmware ping failed!\n"); | ||
1040 | return -1; | ||
1041 | } | ||
1042 | retval = cx23885_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, | ||
1043 | &version); | ||
1044 | if (retval < 0) { | ||
1045 | printk(KERN_ERR "ERROR: cx23417 firmware get encoder :" | ||
1046 | "version failed!\n"); | ||
1047 | return -1; | ||
1048 | } | ||
1049 | dprintk(1, "cx23417 firmware version is 0x%08x\n", version); | ||
1050 | msleep(200); | ||
1051 | } | ||
1052 | |||
1053 | cx23885_codec_settings(dev); | ||
1054 | msleep(60); | ||
1055 | |||
1056 | cx23885_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0, | ||
1057 | CX23885_FIELD1_SAA7115, CX23885_FIELD2_SAA7115); | ||
1058 | cx23885_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0, | ||
1059 | CX23885_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
1060 | 0, 0); | ||
1061 | |||
1062 | /* Setup to capture VBI */ | ||
1063 | data[0] = 0x0001BD00; | ||
1064 | data[1] = 1; /* frames per interrupt */ | ||
1065 | data[2] = 4; /* total bufs */ | ||
1066 | data[3] = 0x91559155; /* start codes */ | ||
1067 | data[4] = 0x206080C0; /* stop codes */ | ||
1068 | data[5] = 6; /* lines */ | ||
1069 | data[6] = 64; /* BPL */ | ||
1070 | |||
1071 | cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1], | ||
1072 | data[2], data[3], data[4], data[5], data[6]); | ||
1073 | |||
1074 | for (i = 2; i <= 24; i++) { | ||
1075 | int valid; | ||
1076 | |||
1077 | valid = ((i >= 19) && (i <= 21)); | ||
1078 | cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, i, | ||
1079 | valid, 0 , 0, 0); | ||
1080 | cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, | ||
1081 | i | 0x80000000, valid, 0, 0, 0); | ||
1082 | } | ||
1083 | |||
1084 | cx23885_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX23885_UNMUTE); | ||
1085 | msleep(60); | ||
1086 | |||
1087 | /* initialize the video input */ | ||
1088 | cx23885_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0); | ||
1089 | msleep(60); | ||
1090 | |||
1091 | /* Enable VIP style pixel invalidation so we work with scaled mode */ | ||
1092 | mc417_memory_write(dev, 2120, 0x00000080); | ||
1093 | |||
1094 | /* start capturing to the host interface */ | ||
1095 | cx23885_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, | ||
1096 | CX23885_MPEG_CAPTURE, CX23885_RAW_BITS_NONE); | ||
1097 | msleep(10); | ||
1098 | |||
1099 | return 0; | ||
1100 | } | ||
1101 | |||
1102 | /* ------------------------------------------------------------------ */ | ||
1103 | |||
1104 | static int bb_buf_setup(struct videobuf_queue *q, | ||
1105 | unsigned int *count, unsigned int *size) | ||
1106 | { | ||
1107 | struct cx23885_fh *fh = q->priv_data; | ||
1108 | |||
1109 | fh->dev->ts1.ts_packet_size = mpeglinesize; | ||
1110 | fh->dev->ts1.ts_packet_count = mpeglines; | ||
1111 | |||
1112 | *size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count; | ||
1113 | *count = mpegbufs; | ||
1114 | |||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | static int bb_buf_prepare(struct videobuf_queue *q, | ||
1119 | struct videobuf_buffer *vb, enum v4l2_field field) | ||
1120 | { | ||
1121 | struct cx23885_fh *fh = q->priv_data; | ||
1122 | return cx23885_buf_prepare(q, &fh->dev->ts1, | ||
1123 | (struct cx23885_buffer *)vb, | ||
1124 | field); | ||
1125 | } | ||
1126 | |||
1127 | static void bb_buf_queue(struct videobuf_queue *q, | ||
1128 | struct videobuf_buffer *vb) | ||
1129 | { | ||
1130 | struct cx23885_fh *fh = q->priv_data; | ||
1131 | cx23885_buf_queue(&fh->dev->ts1, (struct cx23885_buffer *)vb); | ||
1132 | } | ||
1133 | |||
1134 | static void bb_buf_release(struct videobuf_queue *q, | ||
1135 | struct videobuf_buffer *vb) | ||
1136 | { | ||
1137 | cx23885_free_buffer(q, (struct cx23885_buffer *)vb); | ||
1138 | } | ||
1139 | |||
1140 | static struct videobuf_queue_ops cx23885_qops = { | ||
1141 | .buf_setup = bb_buf_setup, | ||
1142 | .buf_prepare = bb_buf_prepare, | ||
1143 | .buf_queue = bb_buf_queue, | ||
1144 | .buf_release = bb_buf_release, | ||
1145 | }; | ||
1146 | |||
1147 | /* ------------------------------------------------------------------ */ | ||
1148 | |||
1149 | static const u32 *ctrl_classes[] = { | ||
1150 | cx2341x_mpeg_ctrls, | ||
1151 | NULL | ||
1152 | }; | ||
1153 | |||
1154 | static int cx23885_queryctrl(struct cx23885_dev *dev, | ||
1155 | struct v4l2_queryctrl *qctrl) | ||
1156 | { | ||
1157 | qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); | ||
1158 | if (qctrl->id == 0) | ||
1159 | return -EINVAL; | ||
1160 | |||
1161 | /* MPEG V4L2 controls */ | ||
1162 | if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl)) | ||
1163 | qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
1164 | |||
1165 | return 0; | ||
1166 | } | ||
1167 | |||
1168 | static int cx23885_querymenu(struct cx23885_dev *dev, | ||
1169 | struct v4l2_querymenu *qmenu) | ||
1170 | { | ||
1171 | struct v4l2_queryctrl qctrl; | ||
1172 | |||
1173 | qctrl.id = qmenu->id; | ||
1174 | cx23885_queryctrl(dev, &qctrl); | ||
1175 | return v4l2_ctrl_query_menu(qmenu, &qctrl, | ||
1176 | cx2341x_ctrl_get_menu(qmenu->id)); | ||
1177 | } | ||
1178 | |||
1179 | int cx23885_do_ioctl(struct inode *inode, struct file *file, int radio, | ||
1180 | struct cx23885_dev *dev, unsigned int cmd, void *arg, | ||
1181 | v4l2_kioctl driver_ioctl) | ||
1182 | { | ||
1183 | int err; | ||
1184 | |||
1185 | switch (cmd) { | ||
1186 | /* ---------- tv norms ---------- */ | ||
1187 | case VIDIOC_ENUMSTD: | ||
1188 | { | ||
1189 | struct v4l2_standard *e = arg; | ||
1190 | unsigned int i; | ||
1191 | |||
1192 | i = e->index; | ||
1193 | if (i >= ARRAY_SIZE(cx23885_tvnorms)) | ||
1194 | return -EINVAL; | ||
1195 | err = v4l2_video_std_construct(e, | ||
1196 | cx23885_tvnorms[e->index].id, | ||
1197 | cx23885_tvnorms[e->index].name); | ||
1198 | e->index = i; | ||
1199 | if (err < 0) | ||
1200 | return err; | ||
1201 | return 0; | ||
1202 | } | ||
1203 | case VIDIOC_G_STD: | ||
1204 | { | ||
1205 | v4l2_std_id *id = arg; | ||
1206 | |||
1207 | *id = dev->encodernorm.id; | ||
1208 | return 0; | ||
1209 | } | ||
1210 | case VIDIOC_S_STD: | ||
1211 | { | ||
1212 | v4l2_std_id *id = arg; | ||
1213 | unsigned int i; | ||
1214 | |||
1215 | for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++) | ||
1216 | if (*id & cx23885_tvnorms[i].id) | ||
1217 | break; | ||
1218 | if (i == ARRAY_SIZE(cx23885_tvnorms)) | ||
1219 | return -EINVAL; | ||
1220 | dev->encodernorm = cx23885_tvnorms[i]; | ||
1221 | |||
1222 | return 0; | ||
1223 | } | ||
1224 | |||
1225 | /* ------ input switching ---------- */ | ||
1226 | case VIDIOC_ENUMINPUT: | ||
1227 | { | ||
1228 | struct cx23885_input *input; | ||
1229 | struct v4l2_input *i = arg; | ||
1230 | unsigned int n; | ||
1231 | |||
1232 | n = i->index; | ||
1233 | if (n >= 4) | ||
1234 | return -EINVAL; | ||
1235 | input = &cx23885_boards[dev->board].input[n]; | ||
1236 | if (input->type == 0) | ||
1237 | return -EINVAL; | ||
1238 | memset(i, 0, sizeof(*i)); | ||
1239 | i->index = n; | ||
1240 | /* FIXME | ||
1241 | * strcpy(i->name, input->name); */ | ||
1242 | strcpy(i->name, "unset"); | ||
1243 | if (input->type == CX23885_VMUX_TELEVISION || | ||
1244 | input->type == CX23885_VMUX_CABLE) | ||
1245 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
1246 | else | ||
1247 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
1248 | |||
1249 | for (n = 0; n < ARRAY_SIZE(cx23885_tvnorms); n++) | ||
1250 | i->std |= cx23885_tvnorms[n].id; | ||
1251 | return 0; | ||
1252 | } | ||
1253 | case VIDIOC_G_INPUT: | ||
1254 | { | ||
1255 | unsigned int *i = arg; | ||
1256 | |||
1257 | *i = dev->input; | ||
1258 | return 0; | ||
1259 | } | ||
1260 | case VIDIOC_S_INPUT: | ||
1261 | { | ||
1262 | unsigned int *i = arg; | ||
1263 | |||
1264 | if (*i >= 4) | ||
1265 | return -EINVAL; | ||
1266 | |||
1267 | return 0; | ||
1268 | } | ||
1269 | |||
1270 | /* --- tuner ioctls ------------------------------------------ */ | ||
1271 | case VIDIOC_G_TUNER: | ||
1272 | { | ||
1273 | struct v4l2_tuner *t = arg; | ||
1274 | |||
1275 | if (UNSET == dev->tuner_type) | ||
1276 | return -EINVAL; | ||
1277 | if (0 != t->index) | ||
1278 | return -EINVAL; | ||
1279 | memset(t, 0, sizeof(*t)); | ||
1280 | strcpy(t->name, "Television"); | ||
1281 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t); | ||
1282 | cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t); | ||
1283 | |||
1284 | dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type); | ||
1285 | |||
1286 | return 0; | ||
1287 | } | ||
1288 | case VIDIOC_S_TUNER: | ||
1289 | { | ||
1290 | struct v4l2_tuner *t = arg; | ||
1291 | |||
1292 | if (UNSET == dev->tuner_type) | ||
1293 | return -EINVAL; | ||
1294 | |||
1295 | /* Update the A/V core */ | ||
1296 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t); | ||
1297 | |||
1298 | return 0; | ||
1299 | } | ||
1300 | case VIDIOC_G_FREQUENCY: | ||
1301 | { | ||
1302 | struct v4l2_frequency *f = arg; | ||
1303 | |||
1304 | memset(f, 0, sizeof(*f)); | ||
1305 | if (UNSET == dev->tuner_type) | ||
1306 | return -EINVAL; | ||
1307 | f->type = V4L2_TUNER_ANALOG_TV; | ||
1308 | f->frequency = dev->freq; | ||
1309 | |||
1310 | /* Assumption that tuner is always on bus 1 */ | ||
1311 | cx23885_call_i2c_clients(&dev->i2c_bus[1], | ||
1312 | VIDIOC_G_FREQUENCY, f); | ||
1313 | |||
1314 | return 0; | ||
1315 | } | ||
1316 | case VIDIOC_S_FREQUENCY: | ||
1317 | { | ||
1318 | struct v4l2_frequency *f = arg; | ||
1319 | |||
1320 | dprintk(1, "VIDIOC_S_FREQUENCY: dev type %d, f\n", | ||
1321 | dev->tuner_type); | ||
1322 | dprintk(1, "VIDIOC_S_FREQUENCY: f tuner %d, f type %d\n", | ||
1323 | f->tuner, f->type); | ||
1324 | if (UNSET == dev->tuner_type) | ||
1325 | return -EINVAL; | ||
1326 | if (f->tuner != 0) | ||
1327 | return -EINVAL; | ||
1328 | if (f->type != V4L2_TUNER_ANALOG_TV) | ||
1329 | return -EINVAL; | ||
1330 | dev->freq = f->frequency; | ||
1331 | |||
1332 | /* Assumption that tuner is always on bus 1 */ | ||
1333 | cx23885_call_i2c_clients(&dev->i2c_bus[1], | ||
1334 | VIDIOC_S_FREQUENCY, f); | ||
1335 | return 0; | ||
1336 | } | ||
1337 | case VIDIOC_S_CTRL: | ||
1338 | { | ||
1339 | /* Update the A/V core */ | ||
1340 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, arg); | ||
1341 | return 0; | ||
1342 | } | ||
1343 | default: | ||
1344 | /* Convert V4L ioctl to V4L2 and call mpeg_do_ioctl | ||
1345 | * (driver_ioctl) */ | ||
1346 | return v4l_compat_translate_ioctl(inode, file, cmd, arg, | ||
1347 | driver_ioctl); | ||
1348 | } | ||
1349 | |||
1350 | return 0; | ||
1351 | } | ||
1352 | |||
1353 | static int mpeg_do_ioctl(struct inode *inode, struct file *file, | ||
1354 | unsigned int cmd, void *arg) | ||
1355 | { | ||
1356 | struct cx23885_fh *fh = file->private_data; | ||
1357 | struct cx23885_dev *dev = fh->dev; | ||
1358 | struct cx23885_tsport *tsport = &dev->ts1; | ||
1359 | |||
1360 | if (v4l_debug > 1) | ||
1361 | v4l_print_ioctl(dev->name, cmd); | ||
1362 | |||
1363 | switch (cmd) { | ||
1364 | |||
1365 | /* --- capabilities ------------------------------------------ */ | ||
1366 | case VIDIOC_QUERYCAP: | ||
1367 | { | ||
1368 | struct v4l2_capability *cap = arg; | ||
1369 | |||
1370 | memset(cap, 0, sizeof(*cap)); | ||
1371 | strcpy(cap->driver, dev->name); | ||
1372 | strlcpy(cap->card, cx23885_boards[tsport->dev->board].name, | ||
1373 | sizeof(cap->card)); | ||
1374 | sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); | ||
1375 | cap->version = CX23885_VERSION_CODE; | ||
1376 | cap->capabilities = | ||
1377 | V4L2_CAP_VIDEO_CAPTURE | | ||
1378 | V4L2_CAP_READWRITE | | ||
1379 | V4L2_CAP_STREAMING | | ||
1380 | 0; | ||
1381 | if (UNSET != dev->tuner_type) | ||
1382 | cap->capabilities |= V4L2_CAP_TUNER; | ||
1383 | |||
1384 | return 0; | ||
1385 | } | ||
1386 | |||
1387 | /* --- capture ioctls ---------------------------------------- */ | ||
1388 | case VIDIOC_ENUM_FMT: | ||
1389 | { | ||
1390 | struct v4l2_fmtdesc *f = arg; | ||
1391 | int index; | ||
1392 | |||
1393 | index = f->index; | ||
1394 | if (index != 0) | ||
1395 | return -EINVAL; | ||
1396 | |||
1397 | memset(f, 0, sizeof(*f)); | ||
1398 | f->index = index; | ||
1399 | strlcpy(f->description, "MPEG", sizeof(f->description)); | ||
1400 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1401 | f->pixelformat = V4L2_PIX_FMT_MPEG; | ||
1402 | return 0; | ||
1403 | } | ||
1404 | case VIDIOC_G_FMT: | ||
1405 | { | ||
1406 | struct v4l2_format *f = arg; | ||
1407 | |||
1408 | memset(f, 0, sizeof(*f)); | ||
1409 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1410 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
1411 | f->fmt.pix.bytesperline = 0; | ||
1412 | f->fmt.pix.sizeimage = | ||
1413 | dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; | ||
1414 | f->fmt.pix.colorspace = 0; | ||
1415 | f->fmt.pix.width = dev->ts1.width; | ||
1416 | f->fmt.pix.height = dev->ts1.height; | ||
1417 | f->fmt.pix.field = fh->mpegq.field; | ||
1418 | dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", | ||
1419 | dev->ts1.width, dev->ts1.height, fh->mpegq.field); | ||
1420 | return 0; | ||
1421 | } | ||
1422 | case VIDIOC_TRY_FMT: | ||
1423 | { | ||
1424 | struct v4l2_format *f = arg; | ||
1425 | |||
1426 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1427 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
1428 | f->fmt.pix.bytesperline = 0; | ||
1429 | f->fmt.pix.sizeimage = | ||
1430 | dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; | ||
1431 | f->fmt.pix.sizeimage = | ||
1432 | f->fmt.pix.colorspace = 0; | ||
1433 | dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", | ||
1434 | dev->ts1.width, dev->ts1.height, fh->mpegq.field); | ||
1435 | return 0; | ||
1436 | } | ||
1437 | case VIDIOC_S_FMT: | ||
1438 | { | ||
1439 | struct v4l2_format *f = arg; | ||
1440 | |||
1441 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1442 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
1443 | f->fmt.pix.bytesperline = 0; | ||
1444 | f->fmt.pix.sizeimage = | ||
1445 | dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; | ||
1446 | f->fmt.pix.colorspace = 0; | ||
1447 | dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", | ||
1448 | f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); | ||
1449 | return 0; | ||
1450 | } | ||
1451 | |||
1452 | /* --- streaming capture ------------------------------------- */ | ||
1453 | case VIDIOC_REQBUFS: | ||
1454 | return videobuf_reqbufs(&fh->mpegq, arg); | ||
1455 | |||
1456 | case VIDIOC_QUERYBUF: | ||
1457 | return videobuf_querybuf(&fh->mpegq, arg); | ||
1458 | |||
1459 | case VIDIOC_QBUF: | ||
1460 | return videobuf_qbuf(&fh->mpegq, arg); | ||
1461 | |||
1462 | case VIDIOC_DQBUF: | ||
1463 | return videobuf_dqbuf(&fh->mpegq, arg, | ||
1464 | file->f_flags & O_NONBLOCK); | ||
1465 | |||
1466 | case VIDIOC_STREAMON: | ||
1467 | return videobuf_streamon(&fh->mpegq); | ||
1468 | |||
1469 | case VIDIOC_STREAMOFF: | ||
1470 | return videobuf_streamoff(&fh->mpegq); | ||
1471 | |||
1472 | case VIDIOC_G_EXT_CTRLS: | ||
1473 | { | ||
1474 | struct v4l2_ext_controls *f = arg; | ||
1475 | |||
1476 | if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
1477 | return -EINVAL; | ||
1478 | return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, cmd); | ||
1479 | } | ||
1480 | case VIDIOC_S_EXT_CTRLS: | ||
1481 | case VIDIOC_TRY_EXT_CTRLS: | ||
1482 | { | ||
1483 | struct v4l2_ext_controls *f = arg; | ||
1484 | struct cx2341x_mpeg_params p; | ||
1485 | int err; | ||
1486 | |||
1487 | if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
1488 | return -EINVAL; | ||
1489 | p = dev->mpeg_params; | ||
1490 | err = cx2341x_ext_ctrls(&p, 0, f, cmd); | ||
1491 | if (err == 0 && cmd == VIDIOC_S_EXT_CTRLS) { | ||
1492 | err = cx2341x_update(dev, cx23885_mbox_func, | ||
1493 | &dev->mpeg_params, &p); | ||
1494 | dev->mpeg_params = p; | ||
1495 | } | ||
1496 | return err; | ||
1497 | } | ||
1498 | case VIDIOC_S_FREQUENCY: | ||
1499 | { | ||
1500 | cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, | ||
1501 | CX23885_END_NOW, CX23885_MPEG_CAPTURE, | ||
1502 | CX23885_RAW_BITS_NONE); | ||
1503 | cx23885_do_ioctl(inode, file, 0, dev, cmd, arg, | ||
1504 | mpeg_do_ioctl); | ||
1505 | cx23885_initialize_codec(dev); | ||
1506 | |||
1507 | return 0; | ||
1508 | } | ||
1509 | case VIDIOC_LOG_STATUS: | ||
1510 | { | ||
1511 | char name[32 + 2]; | ||
1512 | |||
1513 | snprintf(name, sizeof(name), "%s/2", dev->name); | ||
1514 | printk(KERN_INFO | ||
1515 | "%s/2: ============ START LOG STATUS ============\n", | ||
1516 | dev->name); | ||
1517 | cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS, | ||
1518 | NULL); | ||
1519 | cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS, | ||
1520 | NULL); | ||
1521 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS, | ||
1522 | NULL); | ||
1523 | cx2341x_log_status(&dev->mpeg_params, name); | ||
1524 | printk(KERN_INFO | ||
1525 | "%s/2: ============= END LOG STATUS =============\n", | ||
1526 | dev->name); | ||
1527 | return 0; | ||
1528 | } | ||
1529 | case VIDIOC_QUERYMENU: | ||
1530 | return cx23885_querymenu(dev, arg); | ||
1531 | case VIDIOC_QUERYCTRL: | ||
1532 | { | ||
1533 | struct v4l2_queryctrl *c = arg; | ||
1534 | |||
1535 | return cx23885_queryctrl(dev, c); | ||
1536 | } | ||
1537 | |||
1538 | default: | ||
1539 | return cx23885_do_ioctl(inode, file, 0, dev, cmd, arg, | ||
1540 | mpeg_do_ioctl); | ||
1541 | } | ||
1542 | return 0; | ||
1543 | } | ||
1544 | |||
1545 | static int mpeg_ioctl(struct inode *inode, struct file *file, | ||
1546 | unsigned int cmd, unsigned long arg) | ||
1547 | { | ||
1548 | return video_usercopy(inode, file, cmd, arg, mpeg_do_ioctl); | ||
1549 | } | ||
1550 | |||
1551 | static int mpeg_open(struct inode *inode, struct file *file) | ||
1552 | { | ||
1553 | int minor = iminor(inode); | ||
1554 | struct cx23885_dev *h, *dev = NULL; | ||
1555 | struct list_head *list; | ||
1556 | struct cx23885_fh *fh; | ||
1557 | |||
1558 | dprintk(2, "%s()\n", __func__); | ||
1559 | |||
1560 | list_for_each(list, &cx23885_devlist) { | ||
1561 | h = list_entry(list, struct cx23885_dev, devlist); | ||
1562 | if (h->v4l_device->minor == minor) { | ||
1563 | dev = h; | ||
1564 | break; | ||
1565 | } | ||
1566 | } | ||
1567 | |||
1568 | if (dev == NULL) | ||
1569 | return -ENODEV; | ||
1570 | |||
1571 | /* allocate + initialize per filehandle data */ | ||
1572 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
1573 | if (NULL == fh) | ||
1574 | return -ENOMEM; | ||
1575 | |||
1576 | file->private_data = fh; | ||
1577 | fh->dev = dev; | ||
1578 | |||
1579 | videobuf_queue_sg_init(&fh->mpegq, &cx23885_qops, | ||
1580 | &dev->pci->dev, &dev->ts1.slock, | ||
1581 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
1582 | V4L2_FIELD_INTERLACED, | ||
1583 | sizeof(struct cx23885_buffer), | ||
1584 | fh); | ||
1585 | |||
1586 | return 0; | ||
1587 | } | ||
1588 | |||
1589 | static int mpeg_release(struct inode *inode, struct file *file) | ||
1590 | { | ||
1591 | struct cx23885_fh *fh = file->private_data; | ||
1592 | struct cx23885_dev *dev = fh->dev; | ||
1593 | |||
1594 | dprintk(2, "%s()\n", __func__); | ||
1595 | |||
1596 | /* FIXME: Review this crap */ | ||
1597 | /* Shut device down on last close */ | ||
1598 | if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) { | ||
1599 | if (atomic_dec_return(&dev->v4l_reader_count) == 0) { | ||
1600 | /* stop mpeg capture */ | ||
1601 | cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, | ||
1602 | CX23885_END_NOW, CX23885_MPEG_CAPTURE, | ||
1603 | CX23885_RAW_BITS_NONE); | ||
1604 | |||
1605 | msleep(500); | ||
1606 | cx23885_417_check_encoder(dev); | ||
1607 | |||
1608 | cx23885_cancel_buffers(&fh->dev->ts1); | ||
1609 | } | ||
1610 | } | ||
1611 | |||
1612 | if (fh->mpegq.streaming) | ||
1613 | videobuf_streamoff(&fh->mpegq); | ||
1614 | if (fh->mpegq.reading) | ||
1615 | videobuf_read_stop(&fh->mpegq); | ||
1616 | |||
1617 | videobuf_mmap_free(&fh->mpegq); | ||
1618 | file->private_data = NULL; | ||
1619 | kfree(fh); | ||
1620 | |||
1621 | return 0; | ||
1622 | } | ||
1623 | |||
1624 | static ssize_t mpeg_read(struct file *file, char __user *data, | ||
1625 | size_t count, loff_t *ppos) | ||
1626 | { | ||
1627 | struct cx23885_fh *fh = file->private_data; | ||
1628 | struct cx23885_dev *dev = fh->dev; | ||
1629 | |||
1630 | dprintk(2, "%s()\n", __func__); | ||
1631 | |||
1632 | /* Deal w/ A/V decoder * and mpeg encoder sync issues. */ | ||
1633 | /* Start mpeg encoder on first read. */ | ||
1634 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { | ||
1635 | if (atomic_inc_return(&dev->v4l_reader_count) == 1) { | ||
1636 | if (cx23885_initialize_codec(dev) < 0) | ||
1637 | return -EINVAL; | ||
1638 | } | ||
1639 | } | ||
1640 | |||
1641 | return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0, | ||
1642 | file->f_flags & O_NONBLOCK); | ||
1643 | } | ||
1644 | |||
1645 | static unsigned int mpeg_poll(struct file *file, | ||
1646 | struct poll_table_struct *wait) | ||
1647 | { | ||
1648 | struct cx23885_fh *fh = file->private_data; | ||
1649 | struct cx23885_dev *dev = fh->dev; | ||
1650 | |||
1651 | dprintk(2, "%s\n", __func__); | ||
1652 | |||
1653 | return videobuf_poll_stream(file, &fh->mpegq, wait); | ||
1654 | } | ||
1655 | |||
1656 | static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) | ||
1657 | { | ||
1658 | struct cx23885_fh *fh = file->private_data; | ||
1659 | struct cx23885_dev *dev = fh->dev; | ||
1660 | |||
1661 | dprintk(2, "%s()\n", __func__); | ||
1662 | |||
1663 | return videobuf_mmap_mapper(&fh->mpegq, vma); | ||
1664 | } | ||
1665 | |||
1666 | static struct file_operations mpeg_fops = { | ||
1667 | .owner = THIS_MODULE, | ||
1668 | .open = mpeg_open, | ||
1669 | .release = mpeg_release, | ||
1670 | .read = mpeg_read, | ||
1671 | .poll = mpeg_poll, | ||
1672 | .mmap = mpeg_mmap, | ||
1673 | .ioctl = mpeg_ioctl, | ||
1674 | .llseek = no_llseek, | ||
1675 | }; | ||
1676 | |||
1677 | static struct video_device cx23885_mpeg_template = { | ||
1678 | .name = "cx23885", | ||
1679 | .type = VID_TYPE_CAPTURE | | ||
1680 | VID_TYPE_TUNER | | ||
1681 | VID_TYPE_SCALES | | ||
1682 | VID_TYPE_MPEG_ENCODER, | ||
1683 | .fops = &mpeg_fops, | ||
1684 | .minor = -1, | ||
1685 | }; | ||
1686 | |||
1687 | void cx23885_417_unregister(struct cx23885_dev *dev) | ||
1688 | { | ||
1689 | dprintk(1, "%s()\n", __func__); | ||
1690 | |||
1691 | if (dev->v4l_device) { | ||
1692 | if (-1 != dev->v4l_device->minor) | ||
1693 | video_unregister_device(dev->v4l_device); | ||
1694 | else | ||
1695 | video_device_release(dev->v4l_device); | ||
1696 | dev->v4l_device = NULL; | ||
1697 | } | ||
1698 | } | ||
1699 | |||
1700 | static struct video_device *cx23885_video_dev_alloc( | ||
1701 | struct cx23885_tsport *tsport, | ||
1702 | struct pci_dev *pci, | ||
1703 | struct video_device *template, | ||
1704 | char *type) | ||
1705 | { | ||
1706 | struct video_device *vfd; | ||
1707 | struct cx23885_dev *dev = tsport->dev; | ||
1708 | |||
1709 | dprintk(1, "%s()\n", __func__); | ||
1710 | |||
1711 | vfd = video_device_alloc(); | ||
1712 | if (NULL == vfd) | ||
1713 | return NULL; | ||
1714 | *vfd = *template; | ||
1715 | vfd->minor = -1; | ||
1716 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, | ||
1717 | type, cx23885_boards[tsport->dev->board].name); | ||
1718 | vfd->dev = &pci->dev; | ||
1719 | vfd->release = video_device_release; | ||
1720 | return vfd; | ||
1721 | } | ||
1722 | |||
1723 | int cx23885_417_register(struct cx23885_dev *dev) | ||
1724 | { | ||
1725 | /* FIXME: Port1 hardcoded here */ | ||
1726 | int err = -ENODEV; | ||
1727 | struct cx23885_tsport *tsport = &dev->ts1; | ||
1728 | |||
1729 | dprintk(1, "%s()\n", __func__); | ||
1730 | |||
1731 | if (cx23885_boards[dev->board].portb != CX23885_MPEG_ENCODER) | ||
1732 | return err; | ||
1733 | |||
1734 | /* Set default TV standard */ | ||
1735 | dev->encodernorm = cx23885_tvnorms[0]; | ||
1736 | |||
1737 | if (dev->encodernorm.id & V4L2_STD_525_60) | ||
1738 | tsport->height = 480; | ||
1739 | else | ||
1740 | tsport->height = 576; | ||
1741 | |||
1742 | tsport->width = 720; | ||
1743 | cx2341x_fill_defaults(&dev->mpeg_params); | ||
1744 | |||
1745 | dev->mpeg_params.port = CX2341X_PORT_SERIAL; | ||
1746 | |||
1747 | /* Allocate and initialize V4L video device */ | ||
1748 | dev->v4l_device = cx23885_video_dev_alloc(tsport, | ||
1749 | dev->pci, &cx23885_mpeg_template, "mpeg"); | ||
1750 | err = video_register_device(dev->v4l_device, | ||
1751 | VFL_TYPE_GRABBER, -1); | ||
1752 | if (err < 0) { | ||
1753 | printk(KERN_INFO "%s: can't register mpeg device\n", dev->name); | ||
1754 | return err; | ||
1755 | } | ||
1756 | |||
1757 | /* Initialize MC417 registers */ | ||
1758 | cx23885_mc417_init(dev); | ||
1759 | |||
1760 | printk(KERN_INFO "%s: registered device video%d [mpeg]\n", | ||
1761 | dev->name, dev->v4l_device->minor & 0x1f); | ||
1762 | |||
1763 | return 0; | ||
1764 | } | ||
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index dfa269838e01..6ebf58724a01 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c | |||
@@ -73,6 +73,7 @@ struct cx23885_board cx23885_boards[] = { | |||
73 | [CX23885_BOARD_HAUPPAUGE_HVR1800] = { | 73 | [CX23885_BOARD_HAUPPAUGE_HVR1800] = { |
74 | .name = "Hauppauge WinTV-HVR1800", | 74 | .name = "Hauppauge WinTV-HVR1800", |
75 | .porta = CX23885_ANALOG_VIDEO, | 75 | .porta = CX23885_ANALOG_VIDEO, |
76 | .portb = CX23885_MPEG_ENCODER, | ||
76 | .portc = CX23885_MPEG_DVB, | 77 | .portc = CX23885_MPEG_DVB, |
77 | .tuner_type = TUNER_PHILIPS_TDA8290, | 78 | .tuner_type = TUNER_PHILIPS_TDA8290, |
78 | .tuner_addr = 0x42, /* 0x84 >> 1 */ | 79 | .tuner_addr = 0x42, /* 0x84 >> 1 */ |
@@ -130,6 +131,18 @@ struct cx23885_board cx23885_boards[] = { | |||
130 | .name = "Hauppauge WinTV-HVR1500", | 131 | .name = "Hauppauge WinTV-HVR1500", |
131 | .portc = CX23885_MPEG_DVB, | 132 | .portc = CX23885_MPEG_DVB, |
132 | }, | 133 | }, |
134 | [CX23885_BOARD_HAUPPAUGE_HVR1200] = { | ||
135 | .name = "Hauppauge WinTV-HVR1200", | ||
136 | .portc = CX23885_MPEG_DVB, | ||
137 | }, | ||
138 | [CX23885_BOARD_HAUPPAUGE_HVR1700] = { | ||
139 | .name = "Hauppauge WinTV-HVR1700", | ||
140 | .portc = CX23885_MPEG_DVB, | ||
141 | }, | ||
142 | [CX23885_BOARD_HAUPPAUGE_HVR1400] = { | ||
143 | .name = "Hauppauge WinTV-HVR1400", | ||
144 | .portc = CX23885_MPEG_DVB, | ||
145 | }, | ||
133 | }; | 146 | }; |
134 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); | 147 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); |
135 | 148 | ||
@@ -181,6 +194,18 @@ struct cx23885_subid cx23885_subids[] = { | |||
181 | .subvendor = 0x0070, | 194 | .subvendor = 0x0070, |
182 | .subdevice = 0x7717, | 195 | .subdevice = 0x7717, |
183 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500, | 196 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500, |
197 | }, { | ||
198 | .subvendor = 0x0070, | ||
199 | .subdevice = 0x71d1, | ||
200 | .card = CX23885_BOARD_HAUPPAUGE_HVR1200, | ||
201 | }, { | ||
202 | .subvendor = 0x0070, | ||
203 | .subdevice = 0x8101, | ||
204 | .card = CX23885_BOARD_HAUPPAUGE_HVR1700, | ||
205 | }, { | ||
206 | .subvendor = 0x0070, | ||
207 | .subdevice = 0x8010, | ||
208 | .card = CX23885_BOARD_HAUPPAUGE_HVR1400, | ||
184 | }, | 209 | }, |
185 | }; | 210 | }; |
186 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); | 211 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); |
@@ -235,6 +260,12 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) | |||
235 | case 79561: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ | 260 | case 79561: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ |
236 | case 79571: /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, ATSC and Basic analog */ | 261 | case 79571: /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, ATSC and Basic analog */ |
237 | case 79671: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ | 262 | case 79671: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ |
263 | case 80019: | ||
264 | /* WinTV-HVR1400 (Express Card, Retail, IR, | ||
265 | * DVB-T and Basic analog */ | ||
266 | case 81519: | ||
267 | /* WinTV-HVR1700 (PCIe, Retail, No IR, half height, | ||
268 | * DVB-T and MPEG2 HW Encoder */ | ||
238 | break; | 269 | break; |
239 | default: | 270 | default: |
240 | printk("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model); | 271 | printk("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model); |
@@ -264,7 +295,7 @@ int cx23885_tuner_callback(void *priv, int command, int arg) | |||
264 | } | 295 | } |
265 | else { | 296 | else { |
266 | printk(KERN_ERR | 297 | printk(KERN_ERR |
267 | "%s(): Unknow command.\n", __FUNCTION__); | 298 | "%s(): Unknow command.\n", __func__); |
268 | return -EINVAL; | 299 | return -EINVAL; |
269 | } | 300 | } |
270 | break; | 301 | break; |
@@ -306,6 +337,10 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
306 | /* GPIO-15-18 cx23417 READY, CS, RD, WR */ | 337 | /* GPIO-15-18 cx23417 READY, CS, RD, WR */ |
307 | /* GPIO-19 IR_RX */ | 338 | /* GPIO-19 IR_RX */ |
308 | 339 | ||
340 | /* CX23417 GPIO's */ | ||
341 | /* EIO15 Zilog Reset */ | ||
342 | /* EIO14 S5H1409/CX24227 Reset */ | ||
343 | |||
309 | /* Force the TDA8295A into reset and back */ | 344 | /* Force the TDA8295A into reset and back */ |
310 | cx_set(GP0_IO, 0x00040004); | 345 | cx_set(GP0_IO, 0x00040004); |
311 | mdelay(20); | 346 | mdelay(20); |
@@ -314,6 +349,50 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
314 | cx_set(GP0_IO, 0x00040004); | 349 | cx_set(GP0_IO, 0x00040004); |
315 | mdelay(20); | 350 | mdelay(20); |
316 | break; | 351 | break; |
352 | case CX23885_BOARD_HAUPPAUGE_HVR1200: | ||
353 | /* GPIO-0 tda10048 demodulator reset */ | ||
354 | /* GPIO-2 tda18271 tuner reset */ | ||
355 | |||
356 | /* Put the parts into reset and back */ | ||
357 | cx_set(GP0_IO, 0x00050000); | ||
358 | mdelay(20); | ||
359 | cx_clear(GP0_IO, 0x00000005); | ||
360 | mdelay(20); | ||
361 | cx_set(GP0_IO, 0x00050005); | ||
362 | break; | ||
363 | case CX23885_BOARD_HAUPPAUGE_HVR1700: | ||
364 | /* GPIO-0 TDA10048 demodulator reset */ | ||
365 | /* GPIO-2 TDA8295A Reset */ | ||
366 | /* GPIO-3-10 cx23417 data0-7 */ | ||
367 | /* GPIO-11-14 cx23417 addr0-3 */ | ||
368 | /* GPIO-15-18 cx23417 READY, CS, RD, WR */ | ||
369 | |||
370 | /* The following GPIO's are on the interna AVCore (cx25840) */ | ||
371 | /* GPIO-19 IR_RX */ | ||
372 | /* GPIO-20 IR_TX 416/DVBT Select */ | ||
373 | /* GPIO-21 IIS DAT */ | ||
374 | /* GPIO-22 IIS WCLK */ | ||
375 | /* GPIO-23 IIS BCLK */ | ||
376 | |||
377 | /* Put the parts into reset and back */ | ||
378 | cx_set(GP0_IO, 0x00050000); | ||
379 | mdelay(20); | ||
380 | cx_clear(GP0_IO, 0x00000005); | ||
381 | mdelay(20); | ||
382 | cx_set(GP0_IO, 0x00050005); | ||
383 | break; | ||
384 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | ||
385 | /* GPIO-0 Dibcom7000p demodulator reset */ | ||
386 | /* GPIO-2 xc3028L tuner reset */ | ||
387 | /* GPIO-13 LED */ | ||
388 | |||
389 | /* Put the parts into reset and back */ | ||
390 | cx_set(GP0_IO, 0x00050000); | ||
391 | mdelay(20); | ||
392 | cx_clear(GP0_IO, 0x00000005); | ||
393 | mdelay(20); | ||
394 | cx_set(GP0_IO, 0x00050005); | ||
395 | break; | ||
317 | } | 396 | } |
318 | } | 397 | } |
319 | 398 | ||
@@ -324,6 +403,8 @@ int cx23885_ir_init(struct cx23885_dev *dev) | |||
324 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 403 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
325 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 404 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
326 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | 405 | case CX23885_BOARD_HAUPPAUGE_HVR1800: |
406 | case CX23885_BOARD_HAUPPAUGE_HVR1200: | ||
407 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | ||
327 | /* FIXME: Implement me */ | 408 | /* FIXME: Implement me */ |
328 | break; | 409 | break; |
329 | } | 410 | } |
@@ -348,11 +429,14 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
348 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 429 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
349 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 430 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
350 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 431 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
432 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | ||
351 | if (dev->i2c_bus[0].i2c_rc == 0) | 433 | if (dev->i2c_bus[0].i2c_rc == 0) |
352 | hauppauge_eeprom(dev, eeprom+0x80); | 434 | hauppauge_eeprom(dev, eeprom+0x80); |
353 | break; | 435 | break; |
354 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | 436 | case CX23885_BOARD_HAUPPAUGE_HVR1800: |
355 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: | 437 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: |
438 | case CX23885_BOARD_HAUPPAUGE_HVR1200: | ||
439 | case CX23885_BOARD_HAUPPAUGE_HVR1700: | ||
356 | if (dev->i2c_bus[0].i2c_rc == 0) | 440 | if (dev->i2c_bus[0].i2c_rc == 0) |
357 | hauppauge_eeprom(dev, eeprom+0xc0); | 441 | hauppauge_eeprom(dev, eeprom+0xc0); |
358 | break; | 442 | break; |
@@ -364,17 +448,45 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
364 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 448 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
365 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 449 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
366 | break; | 450 | break; |
451 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | ||
452 | /* Defaults for VID B - Analog encoder */ | ||
453 | /* DREQ_POL, SMODE, PUNC_CLK, MCLK_POL Serial bus + punc clk */ | ||
454 | ts1->gen_ctrl_val = 0x10e; | ||
455 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | ||
456 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | ||
457 | |||
458 | /* APB_TSVALERR_POL (active low)*/ | ||
459 | ts1->vld_misc_val = 0x2000; | ||
460 | ts1->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4 | 0xc); | ||
461 | |||
462 | /* Defaults for VID C */ | ||
463 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ | ||
464 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | ||
465 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | ||
466 | break; | ||
367 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 467 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
368 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 468 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
369 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 469 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
370 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | ||
371 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: | 470 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: |
471 | case CX23885_BOARD_HAUPPAUGE_HVR1200: | ||
472 | case CX23885_BOARD_HAUPPAUGE_HVR1700: | ||
473 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | ||
372 | default: | 474 | default: |
373 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ | 475 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ |
374 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 476 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
375 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 477 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
376 | } | 478 | } |
377 | 479 | ||
480 | /* Certain boards support analog, or require the avcore to be | ||
481 | * loaded, ensure this happens. | ||
482 | */ | ||
483 | switch (dev->board) { | ||
484 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | ||
485 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: | ||
486 | case CX23885_BOARD_HAUPPAUGE_HVR1700: | ||
487 | request_module("cx25840"); | ||
488 | break; | ||
489 | } | ||
378 | } | 490 | } |
379 | 491 | ||
380 | /* ------------------------------------------------------------------ */ | 492 | /* ------------------------------------------------------------------ */ |
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index 7f10b273598f..f24abcd06dea 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c | |||
@@ -190,25 +190,25 @@ static struct sram_channel cx23887_sram_channels[] = { | |||
190 | static int cx23885_risc_decode(u32 risc) | 190 | static int cx23885_risc_decode(u32 risc) |
191 | { | 191 | { |
192 | static char *instr[16] = { | 192 | static char *instr[16] = { |
193 | [ RISC_SYNC >> 28 ] = "sync", | 193 | [RISC_SYNC >> 28] = "sync", |
194 | [ RISC_WRITE >> 28 ] = "write", | 194 | [RISC_WRITE >> 28] = "write", |
195 | [ RISC_WRITEC >> 28 ] = "writec", | 195 | [RISC_WRITEC >> 28] = "writec", |
196 | [ RISC_READ >> 28 ] = "read", | 196 | [RISC_READ >> 28] = "read", |
197 | [ RISC_READC >> 28 ] = "readc", | 197 | [RISC_READC >> 28] = "readc", |
198 | [ RISC_JUMP >> 28 ] = "jump", | 198 | [RISC_JUMP >> 28] = "jump", |
199 | [ RISC_SKIP >> 28 ] = "skip", | 199 | [RISC_SKIP >> 28] = "skip", |
200 | [ RISC_WRITERM >> 28 ] = "writerm", | 200 | [RISC_WRITERM >> 28] = "writerm", |
201 | [ RISC_WRITECM >> 28 ] = "writecm", | 201 | [RISC_WRITECM >> 28] = "writecm", |
202 | [ RISC_WRITECR >> 28 ] = "writecr", | 202 | [RISC_WRITECR >> 28] = "writecr", |
203 | }; | 203 | }; |
204 | static int incr[16] = { | 204 | static int incr[16] = { |
205 | [ RISC_WRITE >> 28 ] = 3, | 205 | [RISC_WRITE >> 28] = 3, |
206 | [ RISC_JUMP >> 28 ] = 3, | 206 | [RISC_JUMP >> 28] = 3, |
207 | [ RISC_SKIP >> 28 ] = 1, | 207 | [RISC_SKIP >> 28] = 1, |
208 | [ RISC_SYNC >> 28 ] = 1, | 208 | [RISC_SYNC >> 28] = 1, |
209 | [ RISC_WRITERM >> 28 ] = 3, | 209 | [RISC_WRITERM >> 28] = 3, |
210 | [ RISC_WRITECM >> 28 ] = 3, | 210 | [RISC_WRITECM >> 28] = 3, |
211 | [ RISC_WRITECR >> 28 ] = 4, | 211 | [RISC_WRITECR >> 28] = 4, |
212 | }; | 212 | }; |
213 | static char *bits[] = { | 213 | static char *bits[] = { |
214 | "12", "13", "14", "resync", | 214 | "12", "13", "14", "resync", |
@@ -260,7 +260,7 @@ void cx23885_wakeup(struct cx23885_tsport *port, | |||
260 | } | 260 | } |
261 | if (bc != 1) | 261 | if (bc != 1) |
262 | printk("%s: %d buffers handled (should be 1)\n", | 262 | printk("%s: %d buffers handled (should be 1)\n", |
263 | __FUNCTION__, bc); | 263 | __func__, bc); |
264 | } | 264 | } |
265 | 265 | ||
266 | int cx23885_sram_channel_setup(struct cx23885_dev *dev, | 266 | int cx23885_sram_channel_setup(struct cx23885_dev *dev, |
@@ -272,7 +272,7 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, | |||
272 | 272 | ||
273 | if (ch->cmds_start == 0) | 273 | if (ch->cmds_start == 0) |
274 | { | 274 | { |
275 | dprintk(1, "%s() Erasing channel [%s]\n", __FUNCTION__, | 275 | dprintk(1, "%s() Erasing channel [%s]\n", __func__, |
276 | ch->name); | 276 | ch->name); |
277 | cx_write(ch->ptr1_reg, 0); | 277 | cx_write(ch->ptr1_reg, 0); |
278 | cx_write(ch->ptr2_reg, 0); | 278 | cx_write(ch->ptr2_reg, 0); |
@@ -280,7 +280,7 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, | |||
280 | cx_write(ch->cnt1_reg, 0); | 280 | cx_write(ch->cnt1_reg, 0); |
281 | return 0; | 281 | return 0; |
282 | } else { | 282 | } else { |
283 | dprintk(1, "%s() Configuring channel [%s]\n", __FUNCTION__, | 283 | dprintk(1, "%s() Configuring channel [%s]\n", __func__, |
284 | ch->name); | 284 | ch->name); |
285 | } | 285 | } |
286 | 286 | ||
@@ -297,7 +297,7 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, | |||
297 | 297 | ||
298 | /* write CDT */ | 298 | /* write CDT */ |
299 | for (i = 0; i < lines; i++) { | 299 | for (i = 0; i < lines; i++) { |
300 | dprintk(2, "%s() 0x%08x <- 0x%08x\n", __FUNCTION__, cdt + 16*i, | 300 | dprintk(2, "%s() 0x%08x <- 0x%08x\n", __func__, cdt + 16*i, |
301 | ch->fifo_start + bpl*i); | 301 | ch->fifo_start + bpl*i); |
302 | cx_write(cdt + 16*i, ch->fifo_start + bpl*i); | 302 | cx_write(cdt + 16*i, ch->fifo_start + bpl*i); |
303 | cx_write(cdt + 16*i + 4, 0); | 303 | cx_write(cdt + 16*i + 4, 0); |
@@ -449,7 +449,7 @@ static void cx23885_shutdown(struct cx23885_dev *dev) | |||
449 | 449 | ||
450 | static void cx23885_reset(struct cx23885_dev *dev) | 450 | static void cx23885_reset(struct cx23885_dev *dev) |
451 | { | 451 | { |
452 | dprintk(1, "%s()\n", __FUNCTION__); | 452 | dprintk(1, "%s()\n", __func__); |
453 | 453 | ||
454 | cx23885_shutdown(dev); | 454 | cx23885_shutdown(dev); |
455 | 455 | ||
@@ -482,7 +482,7 @@ static void cx23885_reset(struct cx23885_dev *dev) | |||
482 | 482 | ||
483 | static int cx23885_pci_quirks(struct cx23885_dev *dev) | 483 | static int cx23885_pci_quirks(struct cx23885_dev *dev) |
484 | { | 484 | { |
485 | dprintk(1, "%s()\n", __FUNCTION__); | 485 | dprintk(1, "%s()\n", __func__); |
486 | 486 | ||
487 | /* The cx23885 bridge has a weird bug which causes NMI to be asserted | 487 | /* The cx23885 bridge has a weird bug which causes NMI to be asserted |
488 | * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not | 488 | * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not |
@@ -513,11 +513,13 @@ int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
513 | 513 | ||
514 | static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno) | 514 | static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno) |
515 | { | 515 | { |
516 | dprintk(1, "%s(portno=%d)\n", __FUNCTION__, portno); | 516 | dprintk(1, "%s(portno=%d)\n", __func__, portno); |
517 | 517 | ||
518 | /* Transport bus init dma queue - Common settings */ | 518 | /* Transport bus init dma queue - Common settings */ |
519 | port->dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */ | 519 | port->dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */ |
520 | port->ts_int_msk_val = 0x1111; /* TS port bits for RISC */ | 520 | port->ts_int_msk_val = 0x1111; /* TS port bits for RISC */ |
521 | port->vld_misc_val = 0x0; | ||
522 | port->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4); | ||
521 | 523 | ||
522 | spin_lock_init(&port->slock); | 524 | spin_lock_init(&port->slock); |
523 | port->dev = dev; | 525 | port->dev = dev; |
@@ -544,7 +546,7 @@ static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *p | |||
544 | port->reg_ts_clk_en = VID_B_TS_CLK_EN; | 546 | port->reg_ts_clk_en = VID_B_TS_CLK_EN; |
545 | port->reg_src_sel = VID_B_SRC_SEL; | 547 | port->reg_src_sel = VID_B_SRC_SEL; |
546 | port->reg_ts_int_msk = VID_B_INT_MSK; | 548 | port->reg_ts_int_msk = VID_B_INT_MSK; |
547 | port->reg_ts_int_stat = VID_B_INT_STAT; | 549 | port->reg_ts_int_stat = VID_B_INT_STAT; |
548 | port->sram_chno = SRAM_CH03; /* VID_B */ | 550 | port->sram_chno = SRAM_CH03; /* VID_B */ |
549 | port->pci_irqmask = 0x02; /* VID_B bit1 */ | 551 | port->pci_irqmask = 0x02; /* VID_B bit1 */ |
550 | break; | 552 | break; |
@@ -604,14 +606,14 @@ static void cx23885_dev_checkrevision(struct cx23885_dev *dev) | |||
604 | break; | 606 | break; |
605 | default: | 607 | default: |
606 | printk(KERN_ERR "%s() New hardware revision found 0x%x\n", | 608 | printk(KERN_ERR "%s() New hardware revision found 0x%x\n", |
607 | __FUNCTION__, dev->hwrevision); | 609 | __func__, dev->hwrevision); |
608 | } | 610 | } |
609 | if (dev->hwrevision) | 611 | if (dev->hwrevision) |
610 | printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", | 612 | printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", |
611 | __FUNCTION__, dev->hwrevision); | 613 | __func__, dev->hwrevision); |
612 | else | 614 | else |
613 | printk(KERN_ERR "%s() Hardware revision unknown 0x%x\n", | 615 | printk(KERN_ERR "%s() Hardware revision unknown 0x%x\n", |
614 | __FUNCTION__, dev->hwrevision); | 616 | __func__, dev->hwrevision); |
615 | } | 617 | } |
616 | 618 | ||
617 | static int cx23885_dev_setup(struct cx23885_dev *dev) | 619 | static int cx23885_dev_setup(struct cx23885_dev *dev) |
@@ -644,7 +646,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
644 | BUG(); | 646 | BUG(); |
645 | 647 | ||
646 | dprintk(1, "%s() Memory configured for PCIe bridge type %d\n", | 648 | dprintk(1, "%s() Memory configured for PCIe bridge type %d\n", |
647 | __FUNCTION__, dev->bridge); | 649 | __func__, dev->bridge); |
648 | 650 | ||
649 | /* board config */ | 651 | /* board config */ |
650 | dev->board = UNSET; | 652 | dev->board = UNSET; |
@@ -697,10 +699,12 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
697 | dev->i2c_bus[2].reg_wdata = I2C3_WDATA; | 699 | dev->i2c_bus[2].reg_wdata = I2C3_WDATA; |
698 | dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */ | 700 | dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */ |
699 | 701 | ||
700 | if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) | 702 | if ((cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) || |
703 | (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER)) | ||
701 | cx23885_init_tsport(dev, &dev->ts1, 1); | 704 | cx23885_init_tsport(dev, &dev->ts1, 1); |
702 | 705 | ||
703 | if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) | 706 | if ((cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) || |
707 | (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER)) | ||
704 | cx23885_init_tsport(dev, &dev->ts2, 2); | 708 | cx23885_init_tsport(dev, &dev->ts2, 2); |
705 | 709 | ||
706 | if (get_resources(dev) < 0) { | 710 | if (get_resources(dev) < 0) { |
@@ -734,9 +738,9 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
734 | dev->radio_addr = cx23885_boards[dev->board].radio_addr; | 738 | dev->radio_addr = cx23885_boards[dev->board].radio_addr; |
735 | 739 | ||
736 | dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x\n", | 740 | dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x\n", |
737 | __FUNCTION__, dev->tuner_type, dev->tuner_addr); | 741 | __func__, dev->tuner_type, dev->tuner_addr); |
738 | dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n", | 742 | dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n", |
739 | __FUNCTION__, dev->radio_type, dev->radio_addr); | 743 | __func__, dev->radio_type, dev->radio_addr); |
740 | 744 | ||
741 | /* init hardware */ | 745 | /* init hardware */ |
742 | cx23885_reset(dev); | 746 | cx23885_reset(dev); |
@@ -744,28 +748,43 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
744 | cx23885_i2c_register(&dev->i2c_bus[0]); | 748 | cx23885_i2c_register(&dev->i2c_bus[0]); |
745 | cx23885_i2c_register(&dev->i2c_bus[1]); | 749 | cx23885_i2c_register(&dev->i2c_bus[1]); |
746 | cx23885_i2c_register(&dev->i2c_bus[2]); | 750 | cx23885_i2c_register(&dev->i2c_bus[2]); |
747 | cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); | ||
748 | cx23885_card_setup(dev); | 751 | cx23885_card_setup(dev); |
752 | cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); | ||
749 | cx23885_ir_init(dev); | 753 | cx23885_ir_init(dev); |
750 | 754 | ||
751 | if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { | 755 | if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { |
752 | if (cx23885_video_register(dev) < 0) { | 756 | if (cx23885_video_register(dev) < 0) { |
753 | printk(KERN_ERR "%s() Failed to register analog " | 757 | printk(KERN_ERR "%s() Failed to register analog " |
754 | "video adapters on VID_A\n", __FUNCTION__); | 758 | "video adapters on VID_A\n", __func__); |
755 | } | 759 | } |
756 | } | 760 | } |
757 | 761 | ||
758 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { | 762 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { |
759 | if (cx23885_dvb_register(&dev->ts1) < 0) { | 763 | if (cx23885_dvb_register(&dev->ts1) < 0) { |
760 | printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", | 764 | printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", |
761 | __FUNCTION__); | 765 | __func__); |
766 | } | ||
767 | } else | ||
768 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { | ||
769 | if (cx23885_417_register(dev) < 0) { | ||
770 | printk(KERN_ERR | ||
771 | "%s() Failed to register 417 on VID_B\n", | ||
772 | __func__); | ||
762 | } | 773 | } |
763 | } | 774 | } |
764 | 775 | ||
765 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { | 776 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { |
766 | if (cx23885_dvb_register(&dev->ts2) < 0) { | 777 | if (cx23885_dvb_register(&dev->ts2) < 0) { |
767 | printk(KERN_ERR "%s() Failed to register dvb adapters on VID_C\n", | 778 | printk(KERN_ERR |
768 | __FUNCTION__); | 779 | "%s() Failed to register dvb on VID_C\n", |
780 | __func__); | ||
781 | } | ||
782 | } else | ||
783 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) { | ||
784 | if (cx23885_417_register(dev) < 0) { | ||
785 | printk(KERN_ERR | ||
786 | "%s() Failed to register 417 on VID_C\n", | ||
787 | __func__); | ||
769 | } | 788 | } |
770 | } | 789 | } |
771 | 790 | ||
@@ -785,12 +804,18 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev) | |||
785 | if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) | 804 | if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) |
786 | cx23885_video_unregister(dev); | 805 | cx23885_video_unregister(dev); |
787 | 806 | ||
788 | if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) | 807 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) |
789 | cx23885_dvb_unregister(&dev->ts1); | 808 | cx23885_dvb_unregister(&dev->ts1); |
790 | 809 | ||
791 | if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) | 810 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) |
811 | cx23885_417_unregister(dev); | ||
812 | |||
813 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) | ||
792 | cx23885_dvb_unregister(&dev->ts2); | 814 | cx23885_dvb_unregister(&dev->ts2); |
793 | 815 | ||
816 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) | ||
817 | cx23885_417_unregister(dev); | ||
818 | |||
794 | cx23885_i2c_unregister(&dev->i2c_bus[2]); | 819 | cx23885_i2c_unregister(&dev->i2c_bus[2]); |
795 | cx23885_i2c_unregister(&dev->i2c_bus[1]); | 820 | cx23885_i2c_unregister(&dev->i2c_bus[1]); |
796 | cx23885_i2c_unregister(&dev->i2c_bus[0]); | 821 | cx23885_i2c_unregister(&dev->i2c_bus[0]); |
@@ -952,7 +977,7 @@ void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf) | |||
952 | videobuf_waiton(&buf->vb, 0, 0); | 977 | videobuf_waiton(&buf->vb, 0, 0); |
953 | videobuf_dma_unmap(q, dma); | 978 | videobuf_dma_unmap(q, dma); |
954 | videobuf_dma_free(dma); | 979 | videobuf_dma_free(dma); |
955 | btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc); | 980 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); |
956 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 981 | buf->vb.state = VIDEOBUF_NEEDS_INIT; |
957 | } | 982 | } |
958 | 983 | ||
@@ -960,50 +985,50 @@ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) | |||
960 | { | 985 | { |
961 | struct cx23885_dev *dev = port->dev; | 986 | struct cx23885_dev *dev = port->dev; |
962 | 987 | ||
963 | dprintk(1, "%s() Register Dump\n", __FUNCTION__); | 988 | dprintk(1, "%s() Register Dump\n", __func__); |
964 | dprintk(1, "%s() DEV_CNTRL2 0x%08X\n", __FUNCTION__, | 989 | dprintk(1, "%s() DEV_CNTRL2 0x%08X\n", __func__, |
965 | cx_read(DEV_CNTRL2)); | 990 | cx_read(DEV_CNTRL2)); |
966 | dprintk(1, "%s() PCI_INT_MSK 0x%08X\n", __FUNCTION__, | 991 | dprintk(1, "%s() PCI_INT_MSK 0x%08X\n", __func__, |
967 | cx_read(PCI_INT_MSK)); | 992 | cx_read(PCI_INT_MSK)); |
968 | dprintk(1, "%s() AUD_INT_INT_MSK 0x%08X\n", __FUNCTION__, | 993 | dprintk(1, "%s() AUD_INT_INT_MSK 0x%08X\n", __func__, |
969 | cx_read(AUDIO_INT_INT_MSK)); | 994 | cx_read(AUDIO_INT_INT_MSK)); |
970 | dprintk(1, "%s() AUD_INT_DMA_CTL 0x%08X\n", __FUNCTION__, | 995 | dprintk(1, "%s() AUD_INT_DMA_CTL 0x%08X\n", __func__, |
971 | cx_read(AUD_INT_DMA_CTL)); | 996 | cx_read(AUD_INT_DMA_CTL)); |
972 | dprintk(1, "%s() AUD_EXT_INT_MSK 0x%08X\n", __FUNCTION__, | 997 | dprintk(1, "%s() AUD_EXT_INT_MSK 0x%08X\n", __func__, |
973 | cx_read(AUDIO_EXT_INT_MSK)); | 998 | cx_read(AUDIO_EXT_INT_MSK)); |
974 | dprintk(1, "%s() AUD_EXT_DMA_CTL 0x%08X\n", __FUNCTION__, | 999 | dprintk(1, "%s() AUD_EXT_DMA_CTL 0x%08X\n", __func__, |
975 | cx_read(AUD_EXT_DMA_CTL)); | 1000 | cx_read(AUD_EXT_DMA_CTL)); |
976 | dprintk(1, "%s() PAD_CTRL 0x%08X\n", __FUNCTION__, | 1001 | dprintk(1, "%s() PAD_CTRL 0x%08X\n", __func__, |
977 | cx_read(PAD_CTRL)); | 1002 | cx_read(PAD_CTRL)); |
978 | dprintk(1, "%s() ALT_PIN_OUT_SEL 0x%08X\n", __FUNCTION__, | 1003 | dprintk(1, "%s() ALT_PIN_OUT_SEL 0x%08X\n", __func__, |
979 | cx_read(ALT_PIN_OUT_SEL)); | 1004 | cx_read(ALT_PIN_OUT_SEL)); |
980 | dprintk(1, "%s() GPIO2 0x%08X\n", __FUNCTION__, | 1005 | dprintk(1, "%s() GPIO2 0x%08X\n", __func__, |
981 | cx_read(GPIO2)); | 1006 | cx_read(GPIO2)); |
982 | dprintk(1, "%s() gpcnt(0x%08X) 0x%08X\n", __FUNCTION__, | 1007 | dprintk(1, "%s() gpcnt(0x%08X) 0x%08X\n", __func__, |
983 | port->reg_gpcnt, cx_read(port->reg_gpcnt)); | 1008 | port->reg_gpcnt, cx_read(port->reg_gpcnt)); |
984 | dprintk(1, "%s() gpcnt_ctl(0x%08X) 0x%08x\n", __FUNCTION__, | 1009 | dprintk(1, "%s() gpcnt_ctl(0x%08X) 0x%08x\n", __func__, |
985 | port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl)); | 1010 | port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl)); |
986 | dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __FUNCTION__, | 1011 | dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __func__, |
987 | port->reg_dma_ctl, cx_read(port->reg_dma_ctl)); | 1012 | port->reg_dma_ctl, cx_read(port->reg_dma_ctl)); |
988 | dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __FUNCTION__, | 1013 | dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__, |
989 | port->reg_src_sel, cx_read(port->reg_src_sel)); | 1014 | port->reg_src_sel, cx_read(port->reg_src_sel)); |
990 | dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __FUNCTION__, | 1015 | dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __func__, |
991 | port->reg_lngth, cx_read(port->reg_lngth)); | 1016 | port->reg_lngth, cx_read(port->reg_lngth)); |
992 | dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __FUNCTION__, | 1017 | dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __func__, |
993 | port->reg_hw_sop_ctrl, cx_read(port->reg_hw_sop_ctrl)); | 1018 | port->reg_hw_sop_ctrl, cx_read(port->reg_hw_sop_ctrl)); |
994 | dprintk(1, "%s() gen_ctrl(0x%08X) 0x%08x\n", __FUNCTION__, | 1019 | dprintk(1, "%s() gen_ctrl(0x%08X) 0x%08x\n", __func__, |
995 | port->reg_gen_ctrl, cx_read(port->reg_gen_ctrl)); | 1020 | port->reg_gen_ctrl, cx_read(port->reg_gen_ctrl)); |
996 | dprintk(1, "%s() bd_pkt_status(0x%08X) 0x%08x\n", __FUNCTION__, | 1021 | dprintk(1, "%s() bd_pkt_status(0x%08X) 0x%08x\n", __func__, |
997 | port->reg_bd_pkt_status, cx_read(port->reg_bd_pkt_status)); | 1022 | port->reg_bd_pkt_status, cx_read(port->reg_bd_pkt_status)); |
998 | dprintk(1, "%s() sop_status(0x%08X) 0x%08x\n", __FUNCTION__, | 1023 | dprintk(1, "%s() sop_status(0x%08X) 0x%08x\n", __func__, |
999 | port->reg_sop_status, cx_read(port->reg_sop_status)); | 1024 | port->reg_sop_status, cx_read(port->reg_sop_status)); |
1000 | dprintk(1, "%s() fifo_ovfl_stat(0x%08X) 0x%08x\n", __FUNCTION__, | 1025 | dprintk(1, "%s() fifo_ovfl_stat(0x%08X) 0x%08x\n", __func__, |
1001 | port->reg_fifo_ovfl_stat, cx_read(port->reg_fifo_ovfl_stat)); | 1026 | port->reg_fifo_ovfl_stat, cx_read(port->reg_fifo_ovfl_stat)); |
1002 | dprintk(1, "%s() vld_misc(0x%08X) 0x%08x\n", __FUNCTION__, | 1027 | dprintk(1, "%s() vld_misc(0x%08X) 0x%08x\n", __func__, |
1003 | port->reg_vld_misc, cx_read(port->reg_vld_misc)); | 1028 | port->reg_vld_misc, cx_read(port->reg_vld_misc)); |
1004 | dprintk(1, "%s() ts_clk_en(0x%08X) 0x%08x\n", __FUNCTION__, | 1029 | dprintk(1, "%s() ts_clk_en(0x%08X) 0x%08x\n", __func__, |
1005 | port->reg_ts_clk_en, cx_read(port->reg_ts_clk_en)); | 1030 | port->reg_ts_clk_en, cx_read(port->reg_ts_clk_en)); |
1006 | dprintk(1, "%s() ts_int_msk(0x%08X) 0x%08x\n", __FUNCTION__, | 1031 | dprintk(1, "%s() ts_int_msk(0x%08X) 0x%08x\n", __func__, |
1007 | port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk)); | 1032 | port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk)); |
1008 | } | 1033 | } |
1009 | 1034 | ||
@@ -1012,8 +1037,9 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1012 | struct cx23885_buffer *buf) | 1037 | struct cx23885_buffer *buf) |
1013 | { | 1038 | { |
1014 | struct cx23885_dev *dev = port->dev; | 1039 | struct cx23885_dev *dev = port->dev; |
1040 | u32 reg; | ||
1015 | 1041 | ||
1016 | dprintk(1, "%s() w: %d, h: %d, f: %d\n", __FUNCTION__, | 1042 | dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__, |
1017 | buf->vb.width, buf->vb.height, buf->vb.field); | 1043 | buf->vb.width, buf->vb.height, buf->vb.field); |
1018 | 1044 | ||
1019 | /* setup fifo + format */ | 1045 | /* setup fifo + format */ |
@@ -1031,21 +1057,24 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1031 | if ( (!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && | 1057 | if ( (!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && |
1032 | (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) ) { | 1058 | (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) ) { |
1033 | printk( "%s() Failed. Unsupported value in .portb/c (0x%08x)/(0x%08x)\n", | 1059 | printk( "%s() Failed. Unsupported value in .portb/c (0x%08x)/(0x%08x)\n", |
1034 | __FUNCTION__, | 1060 | __func__, |
1035 | cx23885_boards[dev->board].portb, | 1061 | cx23885_boards[dev->board].portb, |
1036 | cx23885_boards[dev->board].portc ); | 1062 | cx23885_boards[dev->board].portc ); |
1037 | return -EINVAL; | 1063 | return -EINVAL; |
1038 | } | 1064 | } |
1039 | 1065 | ||
1066 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) | ||
1067 | cx23885_av_clk(dev, 0); | ||
1068 | |||
1040 | udelay(100); | 1069 | udelay(100); |
1041 | 1070 | ||
1042 | /* If the port supports SRC SELECT, configure it */ | 1071 | /* If the port supports SRC SELECT, configure it */ |
1043 | if(port->reg_src_sel) | 1072 | if(port->reg_src_sel) |
1044 | cx_write(port->reg_src_sel, port->src_sel_val); | 1073 | cx_write(port->reg_src_sel, port->src_sel_val); |
1045 | 1074 | ||
1046 | cx_write(port->reg_hw_sop_ctrl, 0x47 << 16 | 188 << 4); | 1075 | cx_write(port->reg_hw_sop_ctrl, port->hw_sop_ctrl_val); |
1047 | cx_write(port->reg_ts_clk_en, port->ts_clk_en_val); | 1076 | cx_write(port->reg_ts_clk_en, port->ts_clk_en_val); |
1048 | cx_write(port->reg_vld_misc, 0x00); | 1077 | cx_write(port->reg_vld_misc, port->vld_misc_val); |
1049 | cx_write(port->reg_gen_ctrl, port->gen_ctrl_val); | 1078 | cx_write(port->reg_gen_ctrl, port->gen_ctrl_val); |
1050 | udelay(100); | 1079 | udelay(100); |
1051 | 1080 | ||
@@ -1054,11 +1083,26 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1054 | cx_write(port->reg_gpcnt_ctl, 3); | 1083 | cx_write(port->reg_gpcnt_ctl, 3); |
1055 | q->count = 1; | 1084 | q->count = 1; |
1056 | 1085 | ||
1086 | if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) { | ||
1087 | |||
1088 | reg = cx_read(PAD_CTRL); | ||
1089 | reg = reg & ~0x1; /* Clear TS1_OE */ | ||
1090 | |||
1091 | /* FIXME, bit 2 writing here is questionable */ | ||
1092 | /* set TS1_SOP_OE and TS1_OE_HI */ | ||
1093 | reg = reg | 0xa; | ||
1094 | cx_write(PAD_CTRL, reg); | ||
1095 | |||
1096 | /* FIXME and these two registers should be documented. */ | ||
1097 | cx_write(CLK_DELAY, cx_read(CLK_DELAY) | 0x80000011); | ||
1098 | cx_write(ALT_PIN_OUT_SEL, 0x10100045); | ||
1099 | } | ||
1100 | |||
1057 | switch(dev->bridge) { | 1101 | switch(dev->bridge) { |
1058 | case CX23885_BRIDGE_885: | 1102 | case CX23885_BRIDGE_885: |
1059 | case CX23885_BRIDGE_887: | 1103 | case CX23885_BRIDGE_887: |
1060 | /* enable irqs */ | 1104 | /* enable irqs */ |
1061 | dprintk(1, "%s() enabling TS int's and DMA\n", __FUNCTION__ ); | 1105 | dprintk(1, "%s() enabling TS int's and DMA\n", __func__ ); |
1062 | cx_set(port->reg_ts_int_msk, port->ts_int_msk_val); | 1106 | cx_set(port->reg_ts_int_msk, port->ts_int_msk_val); |
1063 | cx_set(port->reg_dma_ctl, port->dma_ctl_val); | 1107 | cx_set(port->reg_dma_ctl, port->dma_ctl_val); |
1064 | cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask); | 1108 | cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask); |
@@ -1069,6 +1113,9 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1069 | 1113 | ||
1070 | cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */ | 1114 | cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */ |
1071 | 1115 | ||
1116 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) | ||
1117 | cx23885_av_clk(dev, 1); | ||
1118 | |||
1072 | if (debug > 4) | 1119 | if (debug > 4) |
1073 | cx23885_tsport_reg_dump(port); | 1120 | cx23885_tsport_reg_dump(port); |
1074 | 1121 | ||
@@ -1078,12 +1125,32 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1078 | static int cx23885_stop_dma(struct cx23885_tsport *port) | 1125 | static int cx23885_stop_dma(struct cx23885_tsport *port) |
1079 | { | 1126 | { |
1080 | struct cx23885_dev *dev = port->dev; | 1127 | struct cx23885_dev *dev = port->dev; |
1081 | dprintk(1, "%s()\n", __FUNCTION__); | 1128 | u32 reg; |
1129 | |||
1130 | dprintk(1, "%s()\n", __func__); | ||
1082 | 1131 | ||
1083 | /* Stop interrupts and DMA */ | 1132 | /* Stop interrupts and DMA */ |
1084 | cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val); | 1133 | cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val); |
1085 | cx_clear(port->reg_dma_ctl, port->dma_ctl_val); | 1134 | cx_clear(port->reg_dma_ctl, port->dma_ctl_val); |
1086 | 1135 | ||
1136 | if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) { | ||
1137 | |||
1138 | reg = cx_read(PAD_CTRL); | ||
1139 | |||
1140 | /* Set TS1_OE */ | ||
1141 | reg = reg | 0x1; | ||
1142 | |||
1143 | /* clear TS1_SOP_OE and TS1_OE_HI */ | ||
1144 | reg = reg & ~0xa; | ||
1145 | cx_write(PAD_CTRL, reg); | ||
1146 | cx_write(port->reg_src_sel, 0); | ||
1147 | cx_write(port->reg_gen_ctrl, 8); | ||
1148 | |||
1149 | } | ||
1150 | |||
1151 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) | ||
1152 | cx23885_av_clk(dev, 0); | ||
1153 | |||
1087 | return 0; | 1154 | return 0; |
1088 | } | 1155 | } |
1089 | 1156 | ||
@@ -1093,13 +1160,13 @@ int cx23885_restart_queue(struct cx23885_tsport *port, | |||
1093 | struct cx23885_dev *dev = port->dev; | 1160 | struct cx23885_dev *dev = port->dev; |
1094 | struct cx23885_buffer *buf; | 1161 | struct cx23885_buffer *buf; |
1095 | 1162 | ||
1096 | dprintk(5, "%s()\n", __FUNCTION__); | 1163 | dprintk(5, "%s()\n", __func__); |
1097 | if (list_empty(&q->active)) | 1164 | if (list_empty(&q->active)) |
1098 | { | 1165 | { |
1099 | struct cx23885_buffer *prev; | 1166 | struct cx23885_buffer *prev; |
1100 | prev = NULL; | 1167 | prev = NULL; |
1101 | 1168 | ||
1102 | dprintk(5, "%s() queue is empty\n", __FUNCTION__); | 1169 | dprintk(5, "%s() queue is empty\n", __func__); |
1103 | 1170 | ||
1104 | for (;;) { | 1171 | for (;;) { |
1105 | if (list_empty(&q->queued)) | 1172 | if (list_empty(&q->queued)) |
@@ -1154,7 +1221,7 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, | |||
1154 | int size = port->ts_packet_size * port->ts_packet_count; | 1221 | int size = port->ts_packet_size * port->ts_packet_count; |
1155 | int rc; | 1222 | int rc; |
1156 | 1223 | ||
1157 | dprintk(1, "%s: %p\n", __FUNCTION__, buf); | 1224 | dprintk(1, "%s: %p\n", __func__, buf); |
1158 | if (0 != buf->vb.baddr && buf->vb.bsize < size) | 1225 | if (0 != buf->vb.baddr && buf->vb.bsize < size) |
1159 | return -EINVAL; | 1226 | return -EINVAL; |
1160 | 1227 | ||
@@ -1197,7 +1264,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) | |||
1197 | buf->count = cx88q->count++; | 1264 | buf->count = cx88q->count++; |
1198 | mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT); | 1265 | mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT); |
1199 | dprintk(1, "[%p/%d] %s - first active\n", | 1266 | dprintk(1, "[%p/%d] %s - first active\n", |
1200 | buf, buf->vb.i, __FUNCTION__); | 1267 | buf, buf->vb.i, __func__); |
1201 | } else { | 1268 | } else { |
1202 | dprintk( 1, "queue is not empty - append to active\n" ); | 1269 | dprintk( 1, "queue is not empty - append to active\n" ); |
1203 | prev = list_entry(cx88q->active.prev, struct cx23885_buffer, | 1270 | prev = list_entry(cx88q->active.prev, struct cx23885_buffer, |
@@ -1208,7 +1275,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) | |||
1208 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 1275 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
1209 | prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ | 1276 | prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ |
1210 | dprintk( 1, "[%p/%d] %s - append to active\n", | 1277 | dprintk( 1, "[%p/%d] %s - append to active\n", |
1211 | buf, buf->vb.i, __FUNCTION__); | 1278 | buf, buf->vb.i, __func__); |
1212 | } | 1279 | } |
1213 | } | 1280 | } |
1214 | 1281 | ||
@@ -1239,13 +1306,23 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, | |||
1239 | spin_unlock_irqrestore(&port->slock, flags); | 1306 | spin_unlock_irqrestore(&port->slock, flags); |
1240 | } | 1307 | } |
1241 | 1308 | ||
1309 | void cx23885_cancel_buffers(struct cx23885_tsport *port) | ||
1310 | { | ||
1311 | struct cx23885_dev *dev = port->dev; | ||
1312 | struct cx23885_dmaqueue *q = &port->mpegq; | ||
1313 | |||
1314 | dprintk(1, "%s()\n", __FUNCTION__); | ||
1315 | del_timer_sync(&q->timeout); | ||
1316 | cx23885_stop_dma(port); | ||
1317 | do_cancel_buffers(port, "cancel", 0); | ||
1318 | } | ||
1242 | 1319 | ||
1243 | static void cx23885_timeout(unsigned long data) | 1320 | static void cx23885_timeout(unsigned long data) |
1244 | { | 1321 | { |
1245 | struct cx23885_tsport *port = (struct cx23885_tsport *)data; | 1322 | struct cx23885_tsport *port = (struct cx23885_tsport *)data; |
1246 | struct cx23885_dev *dev = port->dev; | 1323 | struct cx23885_dev *dev = port->dev; |
1247 | 1324 | ||
1248 | dprintk(1, "%s()\n",__FUNCTION__); | 1325 | dprintk(1, "%s()\n",__func__); |
1249 | 1326 | ||
1250 | if (debug > 5) | 1327 | if (debug > 5) |
1251 | cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); | 1328 | cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); |
@@ -1254,16 +1331,77 @@ static void cx23885_timeout(unsigned long data) | |||
1254 | do_cancel_buffers(port, "timeout", 1); | 1331 | do_cancel_buffers(port, "timeout", 1); |
1255 | } | 1332 | } |
1256 | 1333 | ||
1334 | int cx23885_irq_417(struct cx23885_dev *dev, u32 status) | ||
1335 | { | ||
1336 | /* FIXME: port1 assumption here. */ | ||
1337 | struct cx23885_tsport *port = &dev->ts1; | ||
1338 | int count = 0; | ||
1339 | int handled = 0; | ||
1340 | |||
1341 | if (status == 0) | ||
1342 | return handled; | ||
1343 | |||
1344 | count = cx_read(port->reg_gpcnt); | ||
1345 | dprintk(7, "status: 0x%08x mask: 0x%08x count: 0x%x\n", | ||
1346 | status, cx_read(port->reg_ts_int_msk), count); | ||
1347 | |||
1348 | if ((status & VID_B_MSK_BAD_PKT) || | ||
1349 | (status & VID_B_MSK_OPC_ERR) || | ||
1350 | (status & VID_B_MSK_VBI_OPC_ERR) || | ||
1351 | (status & VID_B_MSK_SYNC) || | ||
1352 | (status & VID_B_MSK_VBI_SYNC) || | ||
1353 | (status & VID_B_MSK_OF) || | ||
1354 | (status & VID_B_MSK_VBI_OF)) { | ||
1355 | printk(KERN_ERR "%s: V4L mpeg risc op code error, status " | ||
1356 | "= 0x%x\n", dev->name, status); | ||
1357 | if (status & VID_B_MSK_BAD_PKT) | ||
1358 | dprintk(1, " VID_B_MSK_BAD_PKT\n"); | ||
1359 | if (status & VID_B_MSK_OPC_ERR) | ||
1360 | dprintk(1, " VID_B_MSK_OPC_ERR\n"); | ||
1361 | if (status & VID_B_MSK_VBI_OPC_ERR) | ||
1362 | dprintk(1, " VID_B_MSK_VBI_OPC_ERR\n"); | ||
1363 | if (status & VID_B_MSK_SYNC) | ||
1364 | dprintk(1, " VID_B_MSK_SYNC\n"); | ||
1365 | if (status & VID_B_MSK_VBI_SYNC) | ||
1366 | dprintk(1, " VID_B_MSK_VBI_SYNC\n"); | ||
1367 | if (status & VID_B_MSK_OF) | ||
1368 | dprintk(1, " VID_B_MSK_OF\n"); | ||
1369 | if (status & VID_B_MSK_VBI_OF) | ||
1370 | dprintk(1, " VID_B_MSK_VBI_OF\n"); | ||
1371 | |||
1372 | cx_clear(port->reg_dma_ctl, port->dma_ctl_val); | ||
1373 | cx23885_sram_channel_dump(dev, | ||
1374 | &dev->sram_channels[port->sram_chno]); | ||
1375 | cx23885_417_check_encoder(dev); | ||
1376 | } else if (status & VID_B_MSK_RISCI1) { | ||
1377 | dprintk(7, " VID_B_MSK_RISCI1\n"); | ||
1378 | spin_lock(&port->slock); | ||
1379 | cx23885_wakeup(port, &port->mpegq, count); | ||
1380 | spin_unlock(&port->slock); | ||
1381 | } else if (status & VID_B_MSK_RISCI2) { | ||
1382 | dprintk(7, " VID_B_MSK_RISCI2\n"); | ||
1383 | spin_lock(&port->slock); | ||
1384 | cx23885_restart_queue(port, &port->mpegq); | ||
1385 | spin_unlock(&port->slock); | ||
1386 | } | ||
1387 | if (status) { | ||
1388 | cx_write(port->reg_ts_int_stat, status); | ||
1389 | handled = 1; | ||
1390 | } | ||
1391 | |||
1392 | return handled; | ||
1393 | } | ||
1394 | |||
1257 | static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) | 1395 | static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) |
1258 | { | 1396 | { |
1259 | struct cx23885_dev *dev = port->dev; | 1397 | struct cx23885_dev *dev = port->dev; |
1260 | int handled = 0; | 1398 | int handled = 0; |
1261 | u32 count; | 1399 | u32 count; |
1262 | 1400 | ||
1263 | if ( (status & VID_BC_MSK_OPC_ERR) || | 1401 | if ((status & VID_BC_MSK_OPC_ERR) || |
1264 | (status & VID_BC_MSK_BAD_PKT) || | 1402 | (status & VID_BC_MSK_BAD_PKT) || |
1265 | (status & VID_BC_MSK_SYNC) || | 1403 | (status & VID_BC_MSK_SYNC) || |
1266 | (status & VID_BC_MSK_OF)) | 1404 | (status & VID_BC_MSK_OF)) |
1267 | { | 1405 | { |
1268 | if (status & VID_BC_MSK_OPC_ERR) | 1406 | if (status & VID_BC_MSK_OPC_ERR) |
1269 | dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR); | 1407 | dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR); |
@@ -1277,7 +1415,8 @@ static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) | |||
1277 | printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); | 1415 | printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); |
1278 | 1416 | ||
1279 | cx_clear(port->reg_dma_ctl, port->dma_ctl_val); | 1417 | cx_clear(port->reg_dma_ctl, port->dma_ctl_val); |
1280 | cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); | 1418 | cx23885_sram_channel_dump(dev, |
1419 | &dev->sram_channels[port->sram_chno]); | ||
1281 | 1420 | ||
1282 | } else if (status & VID_BC_MSK_RISCI1) { | 1421 | } else if (status & VID_BC_MSK_RISCI1) { |
1283 | 1422 | ||
@@ -1378,11 +1517,17 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) | |||
1378 | if (ts1_status) { | 1517 | if (ts1_status) { |
1379 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) | 1518 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) |
1380 | handled += cx23885_irq_ts(ts1, ts1_status); | 1519 | handled += cx23885_irq_ts(ts1, ts1_status); |
1520 | else | ||
1521 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) | ||
1522 | handled += cx23885_irq_417(dev, ts1_status); | ||
1381 | } | 1523 | } |
1382 | 1524 | ||
1383 | if (ts2_status) { | 1525 | if (ts2_status) { |
1384 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) | 1526 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) |
1385 | handled += cx23885_irq_ts(ts2, ts2_status); | 1527 | handled += cx23885_irq_ts(ts2, ts2_status); |
1528 | else | ||
1529 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) | ||
1530 | handled += cx23885_irq_417(dev, ts2_status); | ||
1386 | } | 1531 | } |
1387 | 1532 | ||
1388 | if (vida_status) | 1533 | if (vida_status) |
@@ -1422,7 +1567,8 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev, | |||
1422 | printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " | 1567 | printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " |
1423 | "latency: %d, mmio: 0x%llx\n", dev->name, | 1568 | "latency: %d, mmio: 0x%llx\n", dev->name, |
1424 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, | 1569 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, |
1425 | dev->pci_lat, (unsigned long long)pci_resource_start(pci_dev,0)); | 1570 | dev->pci_lat, |
1571 | (unsigned long long)pci_resource_start(pci_dev, 0)); | ||
1426 | 1572 | ||
1427 | pci_set_master(pci_dev); | 1573 | pci_set_master(pci_dev); |
1428 | if (!pci_dma_supported(pci_dev, 0xffffffff)) { | 1574 | if (!pci_dma_supported(pci_dev, 0xffffffff)) { |
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index ed465c007cea..870d6e197d65 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c | |||
@@ -36,9 +36,12 @@ | |||
36 | #include "tda18271.h" | 36 | #include "tda18271.h" |
37 | #include "lgdt330x.h" | 37 | #include "lgdt330x.h" |
38 | #include "xc5000.h" | 38 | #include "xc5000.h" |
39 | #include "tda10048.h" | ||
39 | #include "dvb-pll.h" | 40 | #include "dvb-pll.h" |
40 | #include "tuner-xc2028.h" | 41 | #include "tuner-xc2028.h" |
41 | #include "tuner-xc2028-types.h" | 42 | #include "tuner-simple.h" |
43 | #include "dib7000p.h" | ||
44 | #include "dibx000_common.h" | ||
42 | 45 | ||
43 | static unsigned int debug; | 46 | static unsigned int debug; |
44 | 47 | ||
@@ -53,6 +56,8 @@ static unsigned int alt_tuner; | |||
53 | module_param(alt_tuner, int, 0644); | 56 | module_param(alt_tuner, int, 0644); |
54 | MODULE_PARM_DESC(alt_tuner, "Enable alternate tuner configuration"); | 57 | MODULE_PARM_DESC(alt_tuner, "Enable alternate tuner configuration"); |
55 | 58 | ||
59 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
60 | |||
56 | /* ------------------------------------------------------------------ */ | 61 | /* ------------------------------------------------------------------ */ |
57 | 62 | ||
58 | static int dvb_buf_setup(struct videobuf_queue *q, | 63 | static int dvb_buf_setup(struct videobuf_queue *q, |
@@ -104,6 +109,13 @@ static struct s5h1409_config hauppauge_generic_config = { | |||
104 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 109 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
105 | }; | 110 | }; |
106 | 111 | ||
112 | static struct tda10048_config hauppauge_hvr1200_config = { | ||
113 | .demod_address = 0x10 >> 1, | ||
114 | .output_mode = TDA10048_SERIAL_OUTPUT, | ||
115 | .fwbulkwritelen = TDA10048_BULKWRITE_200, | ||
116 | .inversion = TDA10048_INVERSION_ON | ||
117 | }; | ||
118 | |||
107 | static struct s5h1409_config hauppauge_ezqam_config = { | 119 | static struct s5h1409_config hauppauge_ezqam_config = { |
108 | .demod_address = 0x32 >> 1, | 120 | .demod_address = 0x32 >> 1, |
109 | .output_mode = S5H1409_SERIAL_OUTPUT, | 121 | .output_mode = S5H1409_SERIAL_OUTPUT, |
@@ -164,8 +176,10 @@ static struct tda829x_config tda829x_no_probe = { | |||
164 | }; | 176 | }; |
165 | 177 | ||
166 | static struct tda18271_std_map hauppauge_tda18271_std_map = { | 178 | static struct tda18271_std_map hauppauge_tda18271_std_map = { |
167 | .atsc_6 = { .if_freq = 5380, .std_bits = 0x1b }, | 179 | .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, |
168 | .qam_6 = { .if_freq = 4000, .std_bits = 0x18 }, | 180 | .if_lvl = 6, .rfagc_top = 0x37 }, |
181 | .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, | ||
182 | .if_lvl = 6, .rfagc_top = 0x37 }, | ||
169 | }; | 183 | }; |
170 | 184 | ||
171 | static struct tda18271_config hauppauge_tda18271_config = { | 185 | static struct tda18271_config hauppauge_tda18271_config = { |
@@ -173,6 +187,96 @@ static struct tda18271_config hauppauge_tda18271_config = { | |||
173 | .gate = TDA18271_GATE_ANALOG, | 187 | .gate = TDA18271_GATE_ANALOG, |
174 | }; | 188 | }; |
175 | 189 | ||
190 | static struct tda18271_config hauppauge_hvr1200_tuner_config = { | ||
191 | .gate = TDA18271_GATE_ANALOG, | ||
192 | }; | ||
193 | |||
194 | struct dibx000_agc_config xc3028_agc_config = { | ||
195 | BAND_VHF | BAND_UHF, /* band_caps */ | ||
196 | |||
197 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0, | ||
198 | * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, | ||
199 | * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, | ||
200 | * P_agc_nb_est=2, P_agc_write=0 | ||
201 | */ | ||
202 | (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | | ||
203 | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */ | ||
204 | |||
205 | 712, /* inv_gain */ | ||
206 | 21, /* time_stabiliz */ | ||
207 | |||
208 | 0, /* alpha_level */ | ||
209 | 118, /* thlock */ | ||
210 | |||
211 | 0, /* wbd_inv */ | ||
212 | 2867, /* wbd_ref */ | ||
213 | 0, /* wbd_sel */ | ||
214 | 2, /* wbd_alpha */ | ||
215 | |||
216 | 0, /* agc1_max */ | ||
217 | 0, /* agc1_min */ | ||
218 | 39718, /* agc2_max */ | ||
219 | 9930, /* agc2_min */ | ||
220 | 0, /* agc1_pt1 */ | ||
221 | 0, /* agc1_pt2 */ | ||
222 | 0, /* agc1_pt3 */ | ||
223 | 0, /* agc1_slope1 */ | ||
224 | 0, /* agc1_slope2 */ | ||
225 | 0, /* agc2_pt1 */ | ||
226 | 128, /* agc2_pt2 */ | ||
227 | 29, /* agc2_slope1 */ | ||
228 | 29, /* agc2_slope2 */ | ||
229 | |||
230 | 17, /* alpha_mant */ | ||
231 | 27, /* alpha_exp */ | ||
232 | 23, /* beta_mant */ | ||
233 | 51, /* beta_exp */ | ||
234 | |||
235 | 1, /* perform_agc_softsplit */ | ||
236 | }; | ||
237 | |||
238 | /* PLL Configuration for COFDM BW_MHz = 8.000000 | ||
239 | * With external clock = 30.000000 */ | ||
240 | struct dibx000_bandwidth_config xc3028_bw_config = { | ||
241 | 60000, /* internal */ | ||
242 | 30000, /* sampling */ | ||
243 | 1, /* pll_cfg: prediv */ | ||
244 | 8, /* pll_cfg: ratio */ | ||
245 | 3, /* pll_cfg: range */ | ||
246 | 1, /* pll_cfg: reset */ | ||
247 | 0, /* pll_cfg: bypass */ | ||
248 | 0, /* misc: refdiv */ | ||
249 | 0, /* misc: bypclk_div */ | ||
250 | 1, /* misc: IO_CLK_en_core */ | ||
251 | 1, /* misc: ADClkSrc */ | ||
252 | 0, /* misc: modulo */ | ||
253 | (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */ | ||
254 | (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */ | ||
255 | 20452225, /* timf */ | ||
256 | 30000000 /* xtal_hz */ | ||
257 | }; | ||
258 | |||
259 | static struct dib7000p_config hauppauge_hvr1400_dib7000_config = { | ||
260 | .output_mpeg2_in_188_bytes = 1, | ||
261 | .hostbus_diversity = 1, | ||
262 | .tuner_is_baseband = 0, | ||
263 | .update_lna = NULL, | ||
264 | |||
265 | .agc_config_count = 1, | ||
266 | .agc = &xc3028_agc_config, | ||
267 | .bw = &xc3028_bw_config, | ||
268 | |||
269 | .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, | ||
270 | .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, | ||
271 | .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, | ||
272 | |||
273 | .pwm_freq_div = 0, | ||
274 | .agc_control = NULL, | ||
275 | .spur_protect = 0, | ||
276 | |||
277 | .output_mode = OUTMODE_MPEG2_SERIAL, | ||
278 | }; | ||
279 | |||
176 | static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) | 280 | static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) |
177 | { | 281 | { |
178 | struct cx23885_tsport *port = ptr; | 282 | struct cx23885_tsport *port = ptr; |
@@ -182,7 +286,7 @@ static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) | |||
182 | case XC2028_TUNER_RESET: | 286 | case XC2028_TUNER_RESET: |
183 | /* Send the tuner in then out of reset */ | 287 | /* Send the tuner in then out of reset */ |
184 | /* GPIO-2 xc3028 tuner */ | 288 | /* GPIO-2 xc3028 tuner */ |
185 | dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __FUNCTION__, arg); | 289 | dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg); |
186 | 290 | ||
187 | cx_set(GP0_IO, 0x00040000); | 291 | cx_set(GP0_IO, 0x00040000); |
188 | cx_clear(GP0_IO, 0x00000004); | 292 | cx_clear(GP0_IO, 0x00000004); |
@@ -192,10 +296,10 @@ static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) | |||
192 | msleep(5); | 296 | msleep(5); |
193 | break; | 297 | break; |
194 | case XC2028_RESET_CLK: | 298 | case XC2028_RESET_CLK: |
195 | dprintk(1, "%s: XC2028_RESET_CLK %d\n", __FUNCTION__, arg); | 299 | dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg); |
196 | break; | 300 | break; |
197 | default: | 301 | default: |
198 | dprintk(1, "%s: unknown command %d, arg %d\n", __FUNCTION__, | 302 | dprintk(1, "%s: unknown command %d, arg %d\n", __func__, |
199 | command, arg); | 303 | command, arg); |
200 | return -EINVAL; | 304 | return -EINVAL; |
201 | } | 305 | } |
@@ -271,8 +375,9 @@ static int dvb_register(struct cx23885_tsport *port) | |||
271 | &fusionhdtv_5_express, | 375 | &fusionhdtv_5_express, |
272 | &i2c_bus->i2c_adap); | 376 | &i2c_bus->i2c_adap); |
273 | if (port->dvb.frontend != NULL) { | 377 | if (port->dvb.frontend != NULL) { |
274 | dvb_attach(dvb_pll_attach, port->dvb.frontend, 0x61, | 378 | dvb_attach(simple_tuner_attach, port->dvb.frontend, |
275 | &i2c_bus->i2c_adap, DVB_PLL_LG_TDVS_H06XF); | 379 | &i2c_bus->i2c_adap, 0x61, |
380 | TUNER_LG_TDVS_H06XF); | ||
276 | } | 381 | } |
277 | break; | 382 | break; |
278 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 383 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
@@ -297,13 +402,52 @@ static int dvb_register(struct cx23885_tsport *port) | |||
297 | struct xc2028_config cfg = { | 402 | struct xc2028_config cfg = { |
298 | .i2c_adap = &i2c_bus->i2c_adap, | 403 | .i2c_adap = &i2c_bus->i2c_adap, |
299 | .i2c_addr = 0x61, | 404 | .i2c_addr = 0x61, |
300 | .video_dev = port, | ||
301 | .callback = cx23885_hvr1500_xc3028_callback, | 405 | .callback = cx23885_hvr1500_xc3028_callback, |
302 | }; | 406 | }; |
303 | static struct xc2028_ctrl ctl = { | 407 | static struct xc2028_ctrl ctl = { |
304 | .fname = "xc3028-v27.fw", | 408 | .fname = "xc3028-v27.fw", |
305 | .max_len = 64, | 409 | .max_len = 64, |
306 | .scode_table = OREN538, | 410 | .scode_table = XC3028_FE_OREN538, |
411 | }; | ||
412 | |||
413 | fe = dvb_attach(xc2028_attach, | ||
414 | port->dvb.frontend, &cfg); | ||
415 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | ||
416 | fe->ops.tuner_ops.set_config(fe, &ctl); | ||
417 | } | ||
418 | break; | ||
419 | case CX23885_BOARD_HAUPPAUGE_HVR1200: | ||
420 | case CX23885_BOARD_HAUPPAUGE_HVR1700: | ||
421 | i2c_bus = &dev->i2c_bus[0]; | ||
422 | port->dvb.frontend = dvb_attach(tda10048_attach, | ||
423 | &hauppauge_hvr1200_config, | ||
424 | &i2c_bus->i2c_adap); | ||
425 | if (port->dvb.frontend != NULL) { | ||
426 | dvb_attach(tda829x_attach, port->dvb.frontend, | ||
427 | &dev->i2c_bus[1].i2c_adap, 0x42, | ||
428 | &tda829x_no_probe); | ||
429 | dvb_attach(tda18271_attach, port->dvb.frontend, | ||
430 | 0x60, &dev->i2c_bus[1].i2c_adap, | ||
431 | &hauppauge_hvr1200_tuner_config); | ||
432 | } | ||
433 | break; | ||
434 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | ||
435 | i2c_bus = &dev->i2c_bus[0]; | ||
436 | port->dvb.frontend = dvb_attach(dib7000p_attach, | ||
437 | &i2c_bus->i2c_adap, | ||
438 | 0x12, &hauppauge_hvr1400_dib7000_config); | ||
439 | if (port->dvb.frontend != NULL) { | ||
440 | struct dvb_frontend *fe; | ||
441 | struct xc2028_config cfg = { | ||
442 | .i2c_adap = &dev->i2c_bus[1].i2c_adap, | ||
443 | .i2c_addr = 0x64, | ||
444 | .callback = cx23885_hvr1500_xc3028_callback, | ||
445 | }; | ||
446 | static struct xc2028_ctrl ctl = { | ||
447 | .fname = "xc3028L-v36.fw", | ||
448 | .max_len = 64, | ||
449 | .demod = 5000, | ||
450 | .d2633 = 1 | ||
307 | }; | 451 | }; |
308 | 452 | ||
309 | fe = dvb_attach(xc2028_attach, | 453 | fe = dvb_attach(xc2028_attach, |
@@ -330,7 +474,7 @@ static int dvb_register(struct cx23885_tsport *port) | |||
330 | 474 | ||
331 | /* register everything */ | 475 | /* register everything */ |
332 | return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, | 476 | return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, |
333 | &dev->pci->dev); | 477 | &dev->pci->dev, adapter_nr); |
334 | } | 478 | } |
335 | 479 | ||
336 | int cx23885_dvb_register(struct cx23885_tsport *port) | 480 | int cx23885_dvb_register(struct cx23885_tsport *port) |
@@ -338,7 +482,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port) | |||
338 | struct cx23885_dev *dev = port->dev; | 482 | struct cx23885_dev *dev = port->dev; |
339 | int err; | 483 | int err; |
340 | 484 | ||
341 | dprintk(1, "%s\n", __FUNCTION__); | 485 | dprintk(1, "%s\n", __func__); |
342 | dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", | 486 | dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", |
343 | dev->board, | 487 | dev->board, |
344 | dev->name, | 488 | dev->name, |
@@ -349,12 +493,12 @@ int cx23885_dvb_register(struct cx23885_tsport *port) | |||
349 | 493 | ||
350 | /* dvb stuff */ | 494 | /* dvb stuff */ |
351 | printk("%s: cx23885 based dvb card\n", dev->name); | 495 | printk("%s: cx23885 based dvb card\n", dev->name); |
352 | videobuf_queue_pci_init(&port->dvb.dvbq, &dvb_qops, dev->pci, &port->slock, | 496 | videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, |
353 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, | 497 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, |
354 | sizeof(struct cx23885_buffer), port); | 498 | sizeof(struct cx23885_buffer), port); |
355 | err = dvb_register(port); | 499 | err = dvb_register(port); |
356 | if (err != 0) | 500 | if (err != 0) |
357 | printk("%s() dvb_register failed err = %d\n", __FUNCTION__, err); | 501 | printk("%s() dvb_register failed err = %d\n", __func__, err); |
358 | 502 | ||
359 | return err; | 503 | return err; |
360 | } | 504 | } |
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index 92fe0bd37c84..c6bb0a05bc1c 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c | |||
@@ -33,7 +33,7 @@ static unsigned int i2c_debug; | |||
33 | module_param(i2c_debug, int, 0644); | 33 | module_param(i2c_debug, int, 0644); |
34 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | 34 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); |
35 | 35 | ||
36 | static unsigned int i2c_scan = 0; | 36 | static unsigned int i2c_scan; |
37 | module_param(i2c_scan, int, 0444); | 37 | module_param(i2c_scan, int, 0444); |
38 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); | 38 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); |
39 | 39 | ||
@@ -87,10 +87,10 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, | |||
87 | int retval, cnt; | 87 | int retval, cnt; |
88 | 88 | ||
89 | if (joined_rlen) | 89 | if (joined_rlen) |
90 | dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __FUNCTION__, | 90 | dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__, |
91 | msg->len, joined_rlen); | 91 | msg->len, joined_rlen); |
92 | else | 92 | else |
93 | dprintk(1, "%s(msg->len=%d)\n", __FUNCTION__, msg->len); | 93 | dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); |
94 | 94 | ||
95 | /* Deal with i2c probe functions with zero payload */ | 95 | /* Deal with i2c probe functions with zero payload */ |
96 | if (msg->len == 0) { | 96 | if (msg->len == 0) { |
@@ -101,7 +101,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, | |||
101 | if (!i2c_slave_did_ack(i2c_adap)) | 101 | if (!i2c_slave_did_ack(i2c_adap)) |
102 | return -EIO; | 102 | return -EIO; |
103 | 103 | ||
104 | dprintk(1, "%s() returns 0\n", __FUNCTION__); | 104 | dprintk(1, "%s() returns 0\n", __func__); |
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | 107 | ||
@@ -176,7 +176,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, | |||
176 | 176 | ||
177 | 177 | ||
178 | if (i2c_debug && !joined) | 178 | if (i2c_debug && !joined) |
179 | dprintk(1, "%s(msg->len=%d)\n", __FUNCTION__, msg->len); | 179 | dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); |
180 | 180 | ||
181 | /* Deal with i2c probe functions with zero payload */ | 181 | /* Deal with i2c probe functions with zero payload */ |
182 | if (msg->len == 0) { | 182 | if (msg->len == 0) { |
@@ -188,7 +188,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, | |||
188 | return -EIO; | 188 | return -EIO; |
189 | 189 | ||
190 | 190 | ||
191 | dprintk(1, "%s() returns 0\n", __FUNCTION__); | 191 | dprintk(1, "%s() returns 0\n", __func__); |
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | 194 | ||
@@ -238,11 +238,11 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, | |||
238 | struct cx23885_dev *dev = bus->dev; | 238 | struct cx23885_dev *dev = bus->dev; |
239 | int i, retval = 0; | 239 | int i, retval = 0; |
240 | 240 | ||
241 | dprintk(1, "%s(num = %d)\n", __FUNCTION__, num); | 241 | dprintk(1, "%s(num = %d)\n", __func__, num); |
242 | 242 | ||
243 | for (i = 0 ; i < num; i++) { | 243 | for (i = 0 ; i < num; i++) { |
244 | dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n", | 244 | dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n", |
245 | __FUNCTION__, num, msgs[i].addr, msgs[i].len); | 245 | __func__, num, msgs[i].addr, msgs[i].len); |
246 | if (msgs[i].flags & I2C_M_RD) { | 246 | if (msgs[i].flags & I2C_M_RD) { |
247 | /* read */ | 247 | /* read */ |
248 | retval = i2c_readbytes(i2c_adap, &msgs[i], 0); | 248 | retval = i2c_readbytes(i2c_adap, &msgs[i], 0); |
@@ -353,6 +353,8 @@ static struct i2c_client cx23885_i2c_client_template = { | |||
353 | }; | 353 | }; |
354 | 354 | ||
355 | static char *i2c_devs[128] = { | 355 | static char *i2c_devs[128] = { |
356 | [0x10 >> 1] = "tda10048", | ||
357 | [0x12 >> 1] = "dib7000pc", | ||
356 | [ 0x1c >> 1 ] = "lgdt3303", | 358 | [ 0x1c >> 1 ] = "lgdt3303", |
357 | [ 0x86 >> 1 ] = "tda9887", | 359 | [ 0x86 >> 1 ] = "tda9887", |
358 | [ 0x32 >> 1 ] = "cx24227", | 360 | [ 0x32 >> 1 ] = "cx24227", |
@@ -360,7 +362,8 @@ static char *i2c_devs[128] = { | |||
360 | [ 0x84 >> 1 ] = "tda8295", | 362 | [ 0x84 >> 1 ] = "tda8295", |
361 | [ 0xa0 >> 1 ] = "eeprom", | 363 | [ 0xa0 >> 1 ] = "eeprom", |
362 | [ 0xc0 >> 1 ] = "tuner/mt2131/tda8275", | 364 | [ 0xc0 >> 1 ] = "tuner/mt2131/tda8275", |
363 | [ 0xc2 >> 1 ] = "tuner/mt2131/tda8275/xc5000", | 365 | [0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028", |
366 | [0xc8 >> 1] = "tuner/xc3028L", | ||
364 | }; | 367 | }; |
365 | 368 | ||
366 | static void do_i2c_scan(char *name, struct i2c_client *c) | 369 | static void do_i2c_scan(char *name, struct i2c_client *c) |
@@ -383,7 +386,7 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) | |||
383 | { | 386 | { |
384 | struct cx23885_dev *dev = bus->dev; | 387 | struct cx23885_dev *dev = bus->dev; |
385 | 388 | ||
386 | dprintk(1, "%s(bus = %d)\n", __FUNCTION__, bus->nr); | 389 | dprintk(1, "%s(bus = %d)\n", __func__, bus->nr); |
387 | 390 | ||
388 | memcpy(&bus->i2c_adap, &cx23885_i2c_adap_template, | 391 | memcpy(&bus->i2c_adap, &cx23885_i2c_adap_template, |
389 | sizeof(bus->i2c_adap)); | 392 | sizeof(bus->i2c_adap)); |
@@ -420,6 +423,29 @@ int cx23885_i2c_unregister(struct cx23885_i2c *bus) | |||
420 | return 0; | 423 | return 0; |
421 | } | 424 | } |
422 | 425 | ||
426 | void cx23885_av_clk(struct cx23885_dev *dev, int enable) | ||
427 | { | ||
428 | /* write 0 to bus 2 addr 0x144 via i2x_xfer() */ | ||
429 | char buffer[3]; | ||
430 | struct i2c_msg msg; | ||
431 | dprintk(1, "%s(enabled = %d)\n", __func__, enable); | ||
432 | |||
433 | /* Register 0x144 */ | ||
434 | buffer[0] = 0x01; | ||
435 | buffer[1] = 0x44; | ||
436 | if (enable == 1) | ||
437 | buffer[2] = 0x05; | ||
438 | else | ||
439 | buffer[2] = 0x00; | ||
440 | |||
441 | msg.addr = 0x44; | ||
442 | msg.flags = I2C_M_TEN; | ||
443 | msg.len = 3; | ||
444 | msg.buf = buffer; | ||
445 | |||
446 | i2c_xfer(&dev->i2c_bus[2].i2c_adap, &msg, 1); | ||
447 | } | ||
448 | |||
423 | /* ----------------------------------------------------------------------- */ | 449 | /* ----------------------------------------------------------------------- */ |
424 | 450 | ||
425 | /* | 451 | /* |
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index d3c4d2c5cbe0..84652210a28c 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -141,7 +141,7 @@ static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc) | |||
141 | if (formats[i].fourcc == fourcc) | 141 | if (formats[i].fourcc == fourcc) |
142 | return formats+i; | 142 | return formats+i; |
143 | 143 | ||
144 | printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __FUNCTION__, fourcc); | 144 | printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc); |
145 | return NULL; | 145 | return NULL; |
146 | } | 146 | } |
147 | 147 | ||
@@ -292,13 +292,13 @@ void cx23885_video_wakeup(struct cx23885_dev *dev, | |||
292 | } | 292 | } |
293 | if (bc != 1) | 293 | if (bc != 1) |
294 | printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", | 294 | printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", |
295 | __FUNCTION__, bc); | 295 | __func__, bc); |
296 | } | 296 | } |
297 | 297 | ||
298 | int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) | 298 | int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) |
299 | { | 299 | { |
300 | dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", | 300 | dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", |
301 | __FUNCTION__, | 301 | __func__, |
302 | (unsigned int)norm, | 302 | (unsigned int)norm, |
303 | v4l2_norm_to_name(norm)); | 303 | v4l2_norm_to_name(norm)); |
304 | 304 | ||
@@ -319,7 +319,7 @@ struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, | |||
319 | char *type) | 319 | char *type) |
320 | { | 320 | { |
321 | struct video_device *vfd; | 321 | struct video_device *vfd; |
322 | dprintk(1, "%s()\n", __FUNCTION__); | 322 | dprintk(1, "%s()\n", __func__); |
323 | 323 | ||
324 | vfd = video_device_alloc(); | 324 | vfd = video_device_alloc(); |
325 | if (NULL == vfd) | 325 | if (NULL == vfd) |
@@ -358,7 +358,7 @@ EXPORT_SYMBOL(cx23885_ctrl_query); | |||
358 | static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh, | 358 | static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh, |
359 | unsigned int bit) | 359 | unsigned int bit) |
360 | { | 360 | { |
361 | dprintk(1, "%s()\n", __FUNCTION__); | 361 | dprintk(1, "%s()\n", __func__); |
362 | if (fh->resources & bit) | 362 | if (fh->resources & bit) |
363 | /* have it already allocated */ | 363 | /* have it already allocated */ |
364 | return 1; | 364 | return 1; |
@@ -392,7 +392,7 @@ static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh, | |||
392 | unsigned int bits) | 392 | unsigned int bits) |
393 | { | 393 | { |
394 | BUG_ON((fh->resources & bits) != bits); | 394 | BUG_ON((fh->resources & bits) != bits); |
395 | dprintk(1, "%s()\n", __FUNCTION__); | 395 | dprintk(1, "%s()\n", __func__); |
396 | 396 | ||
397 | mutex_lock(&dev->lock); | 397 | mutex_lock(&dev->lock); |
398 | fh->resources &= ~bits; | 398 | fh->resources &= ~bits; |
@@ -407,7 +407,7 @@ int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) | |||
407 | memset(&route, 0, sizeof(route)); | 407 | memset(&route, 0, sizeof(route)); |
408 | 408 | ||
409 | dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n", | 409 | dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n", |
410 | __FUNCTION__, | 410 | __func__, |
411 | input, INPUT(input)->vmux, | 411 | input, INPUT(input)->vmux, |
412 | INPUT(input)->gpio0, INPUT(input)->gpio1, | 412 | INPUT(input)->gpio0, INPUT(input)->gpio1, |
413 | INPUT(input)->gpio2, INPUT(input)->gpio3); | 413 | INPUT(input)->gpio2, INPUT(input)->gpio3); |
@@ -427,7 +427,7 @@ EXPORT_SYMBOL(cx23885_video_mux); | |||
427 | int cx23885_set_scale(struct cx23885_dev *dev, unsigned int width, | 427 | int cx23885_set_scale(struct cx23885_dev *dev, unsigned int width, |
428 | unsigned int height, enum v4l2_field field) | 428 | unsigned int height, enum v4l2_field field) |
429 | { | 429 | { |
430 | dprintk(1, "%s()\n", __FUNCTION__); | 430 | dprintk(1, "%s()\n", __func__); |
431 | return 0; | 431 | return 0; |
432 | } | 432 | } |
433 | 433 | ||
@@ -435,7 +435,7 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev, | |||
435 | struct cx23885_dmaqueue *q, | 435 | struct cx23885_dmaqueue *q, |
436 | struct cx23885_buffer *buf) | 436 | struct cx23885_buffer *buf) |
437 | { | 437 | { |
438 | dprintk(1, "%s()\n", __FUNCTION__); | 438 | dprintk(1, "%s()\n", __func__); |
439 | 439 | ||
440 | /* setup fifo + format */ | 440 | /* setup fifo + format */ |
441 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01], | 441 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01], |
@@ -463,7 +463,7 @@ static int cx23885_restart_video_queue(struct cx23885_dev *dev, | |||
463 | { | 463 | { |
464 | struct cx23885_buffer *buf, *prev; | 464 | struct cx23885_buffer *buf, *prev; |
465 | struct list_head *item; | 465 | struct list_head *item; |
466 | dprintk(1, "%s()\n", __FUNCTION__); | 466 | dprintk(1, "%s()\n", __func__); |
467 | 467 | ||
468 | if (!list_empty(&q->active)) { | 468 | if (!list_empty(&q->active)) { |
469 | buf = list_entry(q->active.next, struct cx23885_buffer, | 469 | buf = list_entry(q->active.next, struct cx23885_buffer, |
@@ -579,13 +579,13 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
579 | if (dev->tvnorm & V4L2_STD_NTSC) { | 579 | if (dev->tvnorm & V4L2_STD_NTSC) { |
580 | /* cx25840 transmits NTSC bottom field first */ | 580 | /* cx25840 transmits NTSC bottom field first */ |
581 | dprintk(1, "%s() Creating NTSC risc\n", | 581 | dprintk(1, "%s() Creating NTSC risc\n", |
582 | __FUNCTION__); | 582 | __func__); |
583 | line0_offset = buf->bpl; | 583 | line0_offset = buf->bpl; |
584 | line1_offset = 0; | 584 | line1_offset = 0; |
585 | } else { | 585 | } else { |
586 | /* All other formats are top field first */ | 586 | /* All other formats are top field first */ |
587 | dprintk(1, "%s() Creating PAL/SECAM risc\n", | 587 | dprintk(1, "%s() Creating PAL/SECAM risc\n", |
588 | __FUNCTION__); | 588 | __func__); |
589 | line0_offset = 0; | 589 | line0_offset = 0; |
590 | line1_offset = buf->bpl; | 590 | line1_offset = buf->bpl; |
591 | } | 591 | } |
@@ -765,8 +765,8 @@ static int video_open(struct inode *inode, struct file *file) | |||
765 | fh->height = 240; | 765 | fh->height = 240; |
766 | fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); | 766 | fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); |
767 | 767 | ||
768 | videobuf_queue_pci_init(&fh->vidq, &cx23885_video_qops, | 768 | videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops, |
769 | dev->pci, &dev->slock, | 769 | &dev->pci->dev, &dev->slock, |
770 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 770 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
771 | V4L2_FIELD_INTERLACED, | 771 | V4L2_FIELD_INTERLACED, |
772 | sizeof(struct cx23885_buffer), | 772 | sizeof(struct cx23885_buffer), |
@@ -885,7 +885,7 @@ static int video_mmap(struct file *file, struct vm_area_struct *vma) | |||
885 | 885 | ||
886 | int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl) | 886 | int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl) |
887 | { | 887 | { |
888 | dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __FUNCTION__); | 888 | dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__); |
889 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); | 889 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); |
890 | return 0; | 890 | return 0; |
891 | } | 891 | } |
@@ -894,7 +894,7 @@ EXPORT_SYMBOL(cx23885_get_control); | |||
894 | int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl) | 894 | int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl) |
895 | { | 895 | { |
896 | dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)" | 896 | dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)" |
897 | " (disabled - no action)\n", __FUNCTION__); | 897 | " (disabled - no action)\n", __func__); |
898 | return 0; | 898 | return 0; |
899 | } | 899 | } |
900 | EXPORT_SYMBOL(cx23885_set_control); | 900 | EXPORT_SYMBOL(cx23885_set_control); |
@@ -990,7 +990,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
990 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 990 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
991 | int err; | 991 | int err; |
992 | 992 | ||
993 | dprintk(2, "%s()\n", __FUNCTION__); | 993 | dprintk(2, "%s()\n", __func__); |
994 | err = vidioc_try_fmt_cap(file, priv, f); | 994 | err = vidioc_try_fmt_cap(file, priv, f); |
995 | 995 | ||
996 | if (0 != err) | 996 | if (0 != err) |
@@ -999,7 +999,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
999 | fh->width = f->fmt.pix.width; | 999 | fh->width = f->fmt.pix.width; |
1000 | fh->height = f->fmt.pix.height; | 1000 | fh->height = f->fmt.pix.height; |
1001 | fh->vidq.field = f->fmt.pix.field; | 1001 | fh->vidq.field = f->fmt.pix.field; |
1002 | dprintk(2, "%s() width=%d height=%d field=%d\n", __FUNCTION__, | 1002 | dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, |
1003 | fh->width, fh->height, fh->vidq.field); | 1003 | fh->width, fh->height, fh->vidq.field); |
1004 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f); | 1004 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f); |
1005 | return 0; | 1005 | return 0; |
@@ -1101,7 +1101,7 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1101 | { | 1101 | { |
1102 | struct cx23885_fh *fh = priv; | 1102 | struct cx23885_fh *fh = priv; |
1103 | struct cx23885_dev *dev = fh->dev; | 1103 | struct cx23885_dev *dev = fh->dev; |
1104 | dprintk(1, "%s()\n", __FUNCTION__); | 1104 | dprintk(1, "%s()\n", __func__); |
1105 | 1105 | ||
1106 | if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) | 1106 | if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) |
1107 | return -EINVAL; | 1107 | return -EINVAL; |
@@ -1118,7 +1118,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | |||
1118 | struct cx23885_fh *fh = priv; | 1118 | struct cx23885_fh *fh = priv; |
1119 | struct cx23885_dev *dev = fh->dev; | 1119 | struct cx23885_dev *dev = fh->dev; |
1120 | int err, res; | 1120 | int err, res; |
1121 | dprintk(1, "%s()\n", __FUNCTION__); | 1121 | dprintk(1, "%s()\n", __func__); |
1122 | 1122 | ||
1123 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1123 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1124 | return -EINVAL; | 1124 | return -EINVAL; |
@@ -1136,7 +1136,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | |||
1136 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms) | 1136 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms) |
1137 | { | 1137 | { |
1138 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1138 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1139 | dprintk(1, "%s()\n", __FUNCTION__); | 1139 | dprintk(1, "%s()\n", __func__); |
1140 | 1140 | ||
1141 | mutex_lock(&dev->lock); | 1141 | mutex_lock(&dev->lock); |
1142 | cx23885_set_tvnorm(dev, *tvnorms); | 1142 | cx23885_set_tvnorm(dev, *tvnorms); |
@@ -1159,7 +1159,7 @@ int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) | |||
1159 | [CX23885_VMUX_DEBUG] = "for debug only", | 1159 | [CX23885_VMUX_DEBUG] = "for debug only", |
1160 | }; | 1160 | }; |
1161 | unsigned int n; | 1161 | unsigned int n; |
1162 | dprintk(1, "%s()\n", __FUNCTION__); | 1162 | dprintk(1, "%s()\n", __func__); |
1163 | 1163 | ||
1164 | n = i->index; | 1164 | n = i->index; |
1165 | if (n >= 4) | 1165 | if (n >= 4) |
@@ -1184,7 +1184,7 @@ static int vidioc_enum_input(struct file *file, void *priv, | |||
1184 | struct v4l2_input *i) | 1184 | struct v4l2_input *i) |
1185 | { | 1185 | { |
1186 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1186 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1187 | dprintk(1, "%s()\n", __FUNCTION__); | 1187 | dprintk(1, "%s()\n", __func__); |
1188 | return cx23885_enum_input(dev, i); | 1188 | return cx23885_enum_input(dev, i); |
1189 | } | 1189 | } |
1190 | 1190 | ||
@@ -1193,7 +1193,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | |||
1193 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1193 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1194 | 1194 | ||
1195 | *i = dev->input; | 1195 | *i = dev->input; |
1196 | dprintk(1, "%s() returns %d\n", __FUNCTION__, *i); | 1196 | dprintk(1, "%s() returns %d\n", __func__, *i); |
1197 | return 0; | 1197 | return 0; |
1198 | } | 1198 | } |
1199 | 1199 | ||
@@ -1201,10 +1201,10 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | |||
1201 | { | 1201 | { |
1202 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1202 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1203 | 1203 | ||
1204 | dprintk(1, "%s(%d)\n", __FUNCTION__, i); | 1204 | dprintk(1, "%s(%d)\n", __func__, i); |
1205 | 1205 | ||
1206 | if (i >= 4) { | 1206 | if (i >= 4) { |
1207 | dprintk(1, "%s() -EINVAL\n", __FUNCTION__); | 1207 | dprintk(1, "%s() -EINVAL\n", __func__); |
1208 | return -EINVAL; | 1208 | return -EINVAL; |
1209 | } | 1209 | } |
1210 | 1210 | ||
@@ -1389,7 +1389,7 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status) | |||
1389 | return handled; | 1389 | return handled; |
1390 | cx_write(VID_A_INT_STAT, status); | 1390 | cx_write(VID_A_INT_STAT, status); |
1391 | 1391 | ||
1392 | dprintk(2, "%s() status = 0x%08x\n", __FUNCTION__, status); | 1392 | dprintk(2, "%s() status = 0x%08x\n", __func__, status); |
1393 | /* risc op code error */ | 1393 | /* risc op code error */ |
1394 | if (status & (1 << 16)) { | 1394 | if (status & (1 << 16)) { |
1395 | printk(KERN_WARNING "%s/0: video risc op code error\n", | 1395 | printk(KERN_WARNING "%s/0: video risc op code error\n", |
@@ -1487,7 +1487,7 @@ static const struct file_operations radio_fops = { | |||
1487 | 1487 | ||
1488 | void cx23885_video_unregister(struct cx23885_dev *dev) | 1488 | void cx23885_video_unregister(struct cx23885_dev *dev) |
1489 | { | 1489 | { |
1490 | dprintk(1, "%s()\n", __FUNCTION__); | 1490 | dprintk(1, "%s()\n", __func__); |
1491 | cx_clear(PCI_INT_MSK, 1); | 1491 | cx_clear(PCI_INT_MSK, 1); |
1492 | 1492 | ||
1493 | if (dev->video_dev) { | 1493 | if (dev->video_dev) { |
@@ -1505,7 +1505,7 @@ int cx23885_video_register(struct cx23885_dev *dev) | |||
1505 | { | 1505 | { |
1506 | int err; | 1506 | int err; |
1507 | 1507 | ||
1508 | dprintk(1, "%s()\n", __FUNCTION__); | 1508 | dprintk(1, "%s()\n", __func__); |
1509 | spin_lock_init(&dev->slock); | 1509 | spin_lock_init(&dev->slock); |
1510 | 1510 | ||
1511 | /* Initialize VBI template */ | 1511 | /* Initialize VBI template */ |
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 7cb2179f2622..32af87f25e7b 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include "btcx-risc.h" | 33 | #include "btcx-risc.h" |
34 | #include "cx23885-reg.h" | 34 | #include "cx23885-reg.h" |
35 | #include "media/cx2341x.h" | ||
35 | 36 | ||
36 | #include <linux/version.h> | 37 | #include <linux/version.h> |
37 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
@@ -59,6 +60,9 @@ | |||
59 | #define CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP 4 | 60 | #define CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP 4 |
60 | #define CX23885_BOARD_HAUPPAUGE_HVR1500Q 5 | 61 | #define CX23885_BOARD_HAUPPAUGE_HVR1500Q 5 |
61 | #define CX23885_BOARD_HAUPPAUGE_HVR1500 6 | 62 | #define CX23885_BOARD_HAUPPAUGE_HVR1500 6 |
63 | #define CX23885_BOARD_HAUPPAUGE_HVR1200 7 | ||
64 | #define CX23885_BOARD_HAUPPAUGE_HVR1700 8 | ||
65 | #define CX23885_BOARD_HAUPPAUGE_HVR1400 9 | ||
62 | 66 | ||
63 | /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ | 67 | /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ |
64 | #define CX23885_NORMS (\ | 68 | #define CX23885_NORMS (\ |
@@ -154,6 +158,7 @@ typedef enum { | |||
154 | CX23885_MPEG_UNDEFINED = 0, | 158 | CX23885_MPEG_UNDEFINED = 0, |
155 | CX23885_MPEG_DVB, | 159 | CX23885_MPEG_DVB, |
156 | CX23885_ANALOG_VIDEO, | 160 | CX23885_ANALOG_VIDEO, |
161 | CX23885_MPEG_ENCODER, | ||
157 | } port_t; | 162 | } port_t; |
158 | 163 | ||
159 | struct cx23885_board { | 164 | struct cx23885_board { |
@@ -252,6 +257,8 @@ struct cx23885_tsport { | |||
252 | u32 gen_ctrl_val; | 257 | u32 gen_ctrl_val; |
253 | u32 ts_clk_en_val; | 258 | u32 ts_clk_en_val; |
254 | u32 src_sel_val; | 259 | u32 src_sel_val; |
260 | u32 vld_misc_val; | ||
261 | u32 hw_sop_ctrl_val; | ||
255 | }; | 262 | }; |
256 | 263 | ||
257 | struct cx23885_dev { | 264 | struct cx23885_dev { |
@@ -312,6 +319,14 @@ struct cx23885_dev { | |||
312 | struct cx23885_dmaqueue vidq; | 319 | struct cx23885_dmaqueue vidq; |
313 | struct cx23885_dmaqueue vbiq; | 320 | struct cx23885_dmaqueue vbiq; |
314 | spinlock_t slock; | 321 | spinlock_t slock; |
322 | |||
323 | /* MPEG Encoder ONLY settings */ | ||
324 | u32 cx23417_mailbox; | ||
325 | struct cx2341x_mpeg_params mpeg_params; | ||
326 | struct video_device *v4l_device; | ||
327 | atomic_t v4l_reader_count; | ||
328 | struct cx23885_tvnorm encodernorm; | ||
329 | |||
315 | }; | 330 | }; |
316 | 331 | ||
317 | extern struct list_head cx23885_devlist; | 332 | extern struct list_head cx23885_devlist; |
@@ -431,6 +446,18 @@ extern int cx23885_i2c_register(struct cx23885_i2c *bus); | |||
431 | extern int cx23885_i2c_unregister(struct cx23885_i2c *bus); | 446 | extern int cx23885_i2c_unregister(struct cx23885_i2c *bus); |
432 | extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd, | 447 | extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd, |
433 | void *arg); | 448 | void *arg); |
449 | extern void cx23885_av_clk(struct cx23885_dev *dev, int enable); | ||
450 | |||
451 | /* ----------------------------------------------------------- */ | ||
452 | /* cx23885-417.c */ | ||
453 | extern int cx23885_417_register(struct cx23885_dev *dev); | ||
454 | extern void cx23885_417_unregister(struct cx23885_dev *dev); | ||
455 | extern int cx23885_irq_417(struct cx23885_dev *dev, u32 status); | ||
456 | extern void cx23885_417_check_encoder(struct cx23885_dev *dev); | ||
457 | extern void cx23885_mc417_init(struct cx23885_dev *dev); | ||
458 | extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value); | ||
459 | extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value); | ||
460 | |||
434 | 461 | ||
435 | /* ----------------------------------------------------------- */ | 462 | /* ----------------------------------------------------------- */ |
436 | /* tv norms */ | 463 | /* tv norms */ |
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 756a1eeb274e..7fde678b2c4a 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -352,7 +352,7 @@ static void cx23885_initialize(struct i2c_client *client) | |||
352 | static void input_change(struct i2c_client *client) | 352 | static void input_change(struct i2c_client *client) |
353 | { | 353 | { |
354 | struct cx25840_state *state = i2c_get_clientdata(client); | 354 | struct cx25840_state *state = i2c_get_clientdata(client); |
355 | v4l2_std_id std = cx25840_get_v4lstd(client); | 355 | v4l2_std_id std = state->std; |
356 | 356 | ||
357 | /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */ | 357 | /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */ |
358 | if (std & V4L2_STD_SECAM) { | 358 | if (std & V4L2_STD_SECAM) { |
@@ -523,32 +523,34 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp | |||
523 | 523 | ||
524 | /* ----------------------------------------------------------------------- */ | 524 | /* ----------------------------------------------------------------------- */ |
525 | 525 | ||
526 | static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) | 526 | static int set_v4lstd(struct i2c_client *client) |
527 | { | 527 | { |
528 | u8 fmt=0; /* zero is autodetect */ | 528 | struct cx25840_state *state = i2c_get_clientdata(client); |
529 | u8 fmt = 0; /* zero is autodetect */ | ||
530 | u8 pal_m = 0; | ||
529 | 531 | ||
530 | /* First tests should be against specific std */ | 532 | /* First tests should be against specific std */ |
531 | if (std == V4L2_STD_NTSC_M_JP) { | 533 | if (state->std == V4L2_STD_NTSC_M_JP) { |
532 | fmt=0x2; | 534 | fmt = 0x2; |
533 | } else if (std == V4L2_STD_NTSC_443) { | 535 | } else if (state->std == V4L2_STD_NTSC_443) { |
534 | fmt=0x3; | 536 | fmt = 0x3; |
535 | } else if (std == V4L2_STD_PAL_M) { | 537 | } else if (state->std == V4L2_STD_PAL_M) { |
536 | fmt=0x5; | 538 | pal_m = 1; |
537 | } else if (std == V4L2_STD_PAL_N) { | 539 | fmt = 0x5; |
538 | fmt=0x6; | 540 | } else if (state->std == V4L2_STD_PAL_N) { |
539 | } else if (std == V4L2_STD_PAL_Nc) { | 541 | fmt = 0x6; |
540 | fmt=0x7; | 542 | } else if (state->std == V4L2_STD_PAL_Nc) { |
541 | } else if (std == V4L2_STD_PAL_60) { | 543 | fmt = 0x7; |
542 | fmt=0x8; | 544 | } else if (state->std == V4L2_STD_PAL_60) { |
545 | fmt = 0x8; | ||
543 | } else { | 546 | } else { |
544 | /* Then, test against generic ones */ | 547 | /* Then, test against generic ones */ |
545 | if (std & V4L2_STD_NTSC) { | 548 | if (state->std & V4L2_STD_NTSC) |
546 | fmt=0x1; | 549 | fmt = 0x1; |
547 | } else if (std & V4L2_STD_PAL) { | 550 | else if (state->std & V4L2_STD_PAL) |
548 | fmt=0x4; | 551 | fmt = 0x4; |
549 | } else if (std & V4L2_STD_SECAM) { | 552 | else if (state->std & V4L2_STD_SECAM) |
550 | fmt=0xc; | 553 | fmt = 0xc; |
551 | } | ||
552 | } | 554 | } |
553 | 555 | ||
554 | v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt); | 556 | v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt); |
@@ -563,42 +565,13 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
563 | cx25840_and_or(client, 0x47b, ~6, 0); | 565 | cx25840_and_or(client, 0x47b, ~6, 0); |
564 | } | 566 | } |
565 | cx25840_and_or(client, 0x400, ~0xf, fmt); | 567 | cx25840_and_or(client, 0x400, ~0xf, fmt); |
568 | cx25840_and_or(client, 0x403, ~0x3, pal_m); | ||
566 | cx25840_vbi_setup(client); | 569 | cx25840_vbi_setup(client); |
570 | if (!state->is_cx25836) | ||
571 | input_change(client); | ||
567 | return 0; | 572 | return 0; |
568 | } | 573 | } |
569 | 574 | ||
570 | v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) | ||
571 | { | ||
572 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
573 | /* check VID_FMT_SEL first */ | ||
574 | u8 fmt = cx25840_read(client, 0x400) & 0xf; | ||
575 | |||
576 | if (!fmt) { | ||
577 | /* check AFD_FMT_STAT if set to autodetect */ | ||
578 | fmt = cx25840_read(client, 0x40d) & 0xf; | ||
579 | } | ||
580 | |||
581 | switch (fmt) { | ||
582 | case 0x1: | ||
583 | { | ||
584 | /* if the audio std is A2-M, then this is the South Korean | ||
585 | NTSC standard */ | ||
586 | if (!state->is_cx25836 && cx25840_read(client, 0x805) == 2) | ||
587 | return V4L2_STD_NTSC_M_KR; | ||
588 | return V4L2_STD_NTSC_M; | ||
589 | } | ||
590 | case 0x2: return V4L2_STD_NTSC_M_JP; | ||
591 | case 0x3: return V4L2_STD_NTSC_443; | ||
592 | case 0x4: return V4L2_STD_PAL; | ||
593 | case 0x5: return V4L2_STD_PAL_M; | ||
594 | case 0x6: return V4L2_STD_PAL_N; | ||
595 | case 0x7: return V4L2_STD_PAL_Nc; | ||
596 | case 0x8: return V4L2_STD_PAL_60; | ||
597 | case 0xc: return V4L2_STD_SECAM; | ||
598 | default: return V4L2_STD_UNKNOWN; | ||
599 | } | ||
600 | } | ||
601 | |||
602 | /* ----------------------------------------------------------------------- */ | 575 | /* ----------------------------------------------------------------------- */ |
603 | 576 | ||
604 | static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | 577 | static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) |
@@ -718,9 +691,10 @@ static int get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | |||
718 | 691 | ||
719 | static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | 692 | static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) |
720 | { | 693 | { |
694 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
721 | struct v4l2_pix_format *pix; | 695 | struct v4l2_pix_format *pix; |
722 | int HSC, VSC, Vsrc, Hsrc, filter, Vlines; | 696 | int HSC, VSC, Vsrc, Hsrc, filter, Vlines; |
723 | int is_50Hz = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); | 697 | int is_50Hz = !(state->std & V4L2_STD_525_60); |
724 | 698 | ||
725 | switch (fmt->type) { | 699 | switch (fmt->type) { |
726 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 700 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
@@ -1096,12 +1070,15 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
1096 | } | 1070 | } |
1097 | 1071 | ||
1098 | case VIDIOC_G_STD: | 1072 | case VIDIOC_G_STD: |
1099 | *(v4l2_std_id *)arg = cx25840_get_v4lstd(client); | 1073 | *(v4l2_std_id *)arg = state->std; |
1100 | break; | 1074 | break; |
1101 | 1075 | ||
1102 | case VIDIOC_S_STD: | 1076 | case VIDIOC_S_STD: |
1077 | if (state->radio == 0 && state->std == *(v4l2_std_id *)arg) | ||
1078 | return 0; | ||
1103 | state->radio = 0; | 1079 | state->radio = 0; |
1104 | return set_v4lstd(client, *(v4l2_std_id *)arg); | 1080 | state->std = *(v4l2_std_id *)arg; |
1081 | return set_v4lstd(client); | ||
1105 | 1082 | ||
1106 | case AUDC_SET_RADIO: | 1083 | case AUDC_SET_RADIO: |
1107 | state->radio = 1; | 1084 | state->radio = 1; |
@@ -1291,6 +1268,12 @@ static int cx25840_probe(struct i2c_client *client) | |||
1291 | state->id = id; | 1268 | state->id = id; |
1292 | state->rev = device_id; | 1269 | state->rev = device_id; |
1293 | 1270 | ||
1271 | if (state->is_cx23885) { | ||
1272 | /* Drive GPIO2 direction and values */ | ||
1273 | cx25840_write(client, 0x160, 0x1d); | ||
1274 | cx25840_write(client, 0x164, 0x00); | ||
1275 | } | ||
1276 | |||
1294 | return 0; | 1277 | return 0; |
1295 | } | 1278 | } |
1296 | 1279 | ||
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h index 95093edc9186..8bf797f48b09 100644 --- a/drivers/media/video/cx25840/cx25840-core.h +++ b/drivers/media/video/cx25840/cx25840-core.h | |||
@@ -38,6 +38,7 @@ struct cx25840_state { | |||
38 | struct i2c_client *c; | 38 | struct i2c_client *c; |
39 | int pvr150_workaround; | 39 | int pvr150_workaround; |
40 | int radio; | 40 | int radio; |
41 | v4l2_std_id std; | ||
41 | enum cx25840_video_input vid_input; | 42 | enum cx25840_video_input vid_input; |
42 | enum cx25840_audio_input aud_input; | 43 | enum cx25840_audio_input aud_input; |
43 | u32 audclk_freq; | 44 | u32 audclk_freq; |
@@ -60,7 +61,6 @@ int cx25840_write4(struct i2c_client *client, u16 addr, u32 value); | |||
60 | u8 cx25840_read(struct i2c_client *client, u16 addr); | 61 | u8 cx25840_read(struct i2c_client *client, u16 addr); |
61 | u32 cx25840_read4(struct i2c_client *client, u16 addr); | 62 | u32 cx25840_read4(struct i2c_client *client, u16 addr); |
62 | int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value); | 63 | int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value); |
63 | v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client); | ||
64 | 64 | ||
65 | /* ----------------------------------------------------------------------- */ | 65 | /* ----------------------------------------------------------------------- */ |
66 | /* cx25850-firmware.c */ | 66 | /* cx25850-firmware.c */ |
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c index 1ddf724a2c74..620d295947ab 100644 --- a/drivers/media/video/cx25840/cx25840-firmware.c +++ b/drivers/media/video/cx25840/cx25840-firmware.c | |||
@@ -79,11 +79,9 @@ static int check_fw_load(struct i2c_client *client, int size) | |||
79 | return 0; | 79 | return 0; |
80 | } | 80 | } |
81 | 81 | ||
82 | static int fw_write(struct i2c_client *client, u8 * data, int size) | 82 | static int fw_write(struct i2c_client *client, u8 *data, int size) |
83 | { | 83 | { |
84 | int sent; | 84 | if (i2c_master_send(client, data, size) < size) { |
85 | |||
86 | if ((sent = i2c_master_send(client, data, size)) < size) { | ||
87 | v4l_err(client, "firmware load i2c failure\n"); | 85 | v4l_err(client, "firmware load i2c failure\n"); |
88 | return -ENOSYS; | 86 | return -ENOSYS; |
89 | } | 87 | } |
@@ -96,7 +94,7 @@ int cx25840_loadfw(struct i2c_client *client) | |||
96 | struct cx25840_state *state = i2c_get_clientdata(client); | 94 | struct cx25840_state *state = i2c_get_clientdata(client); |
97 | const struct firmware *fw = NULL; | 95 | const struct firmware *fw = NULL; |
98 | u8 buffer[4], *ptr; | 96 | u8 buffer[4], *ptr; |
99 | int size, send, retval; | 97 | int size, retval; |
100 | 98 | ||
101 | if (state->is_cx23885) | 99 | if (state->is_cx23885) |
102 | firmware = FWFILE_CX23885; | 100 | firmware = FWFILE_CX23885; |
@@ -124,8 +122,7 @@ int cx25840_loadfw(struct i2c_client *client) | |||
124 | while (size > 0) { | 122 | while (size > 0) { |
125 | ptr[0] = 0x08; | 123 | ptr[0] = 0x08; |
126 | ptr[1] = 0x02; | 124 | ptr[1] = 0x02; |
127 | send = size > (FWSEND - 2) ? FWSEND : size + 2; | 125 | retval = fw_write(client, ptr, min(FWSEND, size + 2)); |
128 | retval = fw_write(client, ptr, send); | ||
129 | 126 | ||
130 | if (retval < 0) { | 127 | if (retval < 0) { |
131 | release_firmware(fw); | 128 | release_firmware(fw); |
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index 6828f59b9d83..c754b9d13369 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c | |||
@@ -85,7 +85,7 @@ static int decode_vps(u8 * dst, u8 * p) | |||
85 | void cx25840_vbi_setup(struct i2c_client *client) | 85 | void cx25840_vbi_setup(struct i2c_client *client) |
86 | { | 86 | { |
87 | struct cx25840_state *state = i2c_get_clientdata(client); | 87 | struct cx25840_state *state = i2c_get_clientdata(client); |
88 | v4l2_std_id std = cx25840_get_v4lstd(client); | 88 | v4l2_std_id std = state->std; |
89 | int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation; | 89 | int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation; |
90 | int luma_lpf,uv_lpf, comb; | 90 | int luma_lpf,uv_lpf, comb; |
91 | u32 pll_int,pll_frac,pll_post; | 91 | u32 pll_int,pll_frac,pll_post; |
@@ -242,7 +242,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
242 | 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ | 242 | 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ |
243 | 0, 0, 0, 0 | 243 | 0, 0, 0, 0 |
244 | }; | 244 | }; |
245 | int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); | 245 | int is_pal = !(state->std & V4L2_STD_525_60); |
246 | int i; | 246 | int i; |
247 | 247 | ||
248 | fmt = arg; | 248 | fmt = arg; |
@@ -279,7 +279,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
279 | 279 | ||
280 | case VIDIOC_S_FMT: | 280 | case VIDIOC_S_FMT: |
281 | { | 281 | { |
282 | int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); | 282 | int is_pal = !(state->std & V4L2_STD_525_60); |
283 | int vbi_offset = is_pal ? 1 : 0; | 283 | int vbi_offset = is_pal ? 1 : 0; |
284 | int i, x; | 284 | int i, x; |
285 | u8 lcr[24]; | 285 | u8 lcr[24]; |
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 49d3813a9b48..bcf6d9ba063d 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
@@ -57,6 +57,7 @@ config VIDEO_CX88_DVB | |||
57 | select DVB_NXT200X if !DVB_FE_CUSTOMISE | 57 | select DVB_NXT200X if !DVB_FE_CUSTOMISE |
58 | select DVB_CX24123 if !DVB_FE_CUSTOMISE | 58 | select DVB_CX24123 if !DVB_FE_CUSTOMISE |
59 | select DVB_ISL6421 if !DVB_FE_CUSTOMISE | 59 | select DVB_ISL6421 if !DVB_FE_CUSTOMISE |
60 | select TUNER_SIMPLE if !DVB_FE_CUSTOMISE | ||
60 | ---help--- | 61 | ---help--- |
61 | This adds support for DVB/ATSC cards based on the | 62 | This adds support for DVB/ATSC cards based on the |
62 | Conexant 2388x chip. | 63 | Conexant 2388x chip. |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 03feb5b49e1b..e976fc6bef7c 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -283,7 +283,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip) | |||
283 | BUG_ON(!chip->dma_size); | 283 | BUG_ON(!chip->dma_size); |
284 | 284 | ||
285 | dprintk(2,"Freeing buffer\n"); | 285 | dprintk(2,"Freeing buffer\n"); |
286 | videobuf_pci_dma_unmap(chip->pci, chip->dma_risc); | 286 | videobuf_sg_dma_unmap(&chip->pci->dev, chip->dma_risc); |
287 | videobuf_dma_free(chip->dma_risc); | 287 | videobuf_dma_free(chip->dma_risc); |
288 | btcx_riscmem_free(chip->pci,&chip->buf->risc); | 288 | btcx_riscmem_free(chip->pci,&chip->buf->risc); |
289 | kfree(chip->buf); | 289 | kfree(chip->buf); |
@@ -385,7 +385,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream, | |||
385 | BUG_ON(!chip->dma_size); | 385 | BUG_ON(!chip->dma_size); |
386 | BUG_ON(chip->num_periods & (chip->num_periods-1)); | 386 | BUG_ON(chip->num_periods & (chip->num_periods-1)); |
387 | 387 | ||
388 | buf = videobuf_pci_alloc(sizeof(*buf)); | 388 | buf = videobuf_sg_alloc(sizeof(*buf)); |
389 | if (NULL == buf) | 389 | if (NULL == buf) |
390 | return -ENOMEM; | 390 | return -ENOMEM; |
391 | 391 | ||
@@ -396,14 +396,14 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream, | |||
396 | buf->vb.height = chip->num_periods; | 396 | buf->vb.height = chip->num_periods; |
397 | buf->vb.size = chip->dma_size; | 397 | buf->vb.size = chip->dma_size; |
398 | 398 | ||
399 | dma=videobuf_to_dma(&buf->vb); | 399 | dma = videobuf_to_dma(&buf->vb); |
400 | videobuf_dma_init(dma); | 400 | videobuf_dma_init(dma); |
401 | ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE, | 401 | ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE, |
402 | (PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT)); | 402 | (PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT)); |
403 | if (ret < 0) | 403 | if (ret < 0) |
404 | goto error; | 404 | goto error; |
405 | 405 | ||
406 | ret = videobuf_pci_dma_map(chip->pci,dma); | 406 | ret = videobuf_sg_dma_map(&chip->pci->dev, dma); |
407 | if (ret < 0) | 407 | if (ret < 0) |
408 | goto error; | 408 | goto error; |
409 | 409 | ||
@@ -494,7 +494,7 @@ static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream) | |||
494 | 494 | ||
495 | count = atomic_read(&chip->count); | 495 | count = atomic_read(&chip->count); |
496 | 496 | ||
497 | // dprintk(2, "%s - count %d (+%u), period %d, frame %lu\n", __FUNCTION__, | 497 | // dprintk(2, "%s - count %d (+%u), period %d, frame %lu\n", __func__, |
498 | // count, new, count & (runtime->periods-1), | 498 | // count, new, count & (runtime->periods-1), |
499 | // runtime->period_size * (count & (runtime->periods-1))); | 499 | // runtime->period_size * (count & (runtime->periods-1))); |
500 | return runtime->period_size * (count & (runtime->periods-1)); | 500 | return runtime->period_size * (count & (runtime->periods-1)); |
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index a99e9d5950aa..61c4f72644b8 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -45,7 +45,7 @@ static unsigned int mpegbufs = 32; | |||
45 | module_param(mpegbufs,int,0644); | 45 | module_param(mpegbufs,int,0644); |
46 | MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); | 46 | MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); |
47 | 47 | ||
48 | static unsigned int debug = 0; | 48 | static unsigned int debug; |
49 | module_param(debug,int,0644); | 49 | module_param(debug,int,0644); |
50 | MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); | 50 | MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); |
51 | 51 | ||
@@ -314,7 +314,7 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat | |||
314 | u32 value, flag, retval; | 314 | u32 value, flag, retval; |
315 | int i; | 315 | int i; |
316 | 316 | ||
317 | dprintk(1,"%s: 0x%X\n", __FUNCTION__, command); | 317 | dprintk(1,"%s: 0x%X\n", __func__, command); |
318 | 318 | ||
319 | /* this may not be 100% safe if we can't read any memory location | 319 | /* this may not be 100% safe if we can't read any memory location |
320 | without side effects */ | 320 | without side effects */ |
@@ -693,7 +693,7 @@ static int blackbird_queryctrl(struct cx8802_dev *dev, struct v4l2_queryctrl *qc | |||
693 | return -EINVAL; | 693 | return -EINVAL; |
694 | 694 | ||
695 | /* Standard V4L2 controls */ | 695 | /* Standard V4L2 controls */ |
696 | if (cx8800_ctrl_query(qctrl) == 0) | 696 | if (cx8800_ctrl_query(dev->core, qctrl) == 0) |
697 | return 0; | 697 | return 0; |
698 | 698 | ||
699 | /* MPEG V4L2 controls */ | 699 | /* MPEG V4L2 controls */ |
@@ -933,7 +933,7 @@ static int vidioc_queryctrl (struct file *file, void *priv, | |||
933 | qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); | 933 | qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); |
934 | if (unlikely(qctrl->id == 0)) | 934 | if (unlikely(qctrl->id == 0)) |
935 | return -EINVAL; | 935 | return -EINVAL; |
936 | return cx8800_ctrl_query(qctrl); | 936 | return cx8800_ctrl_query(dev->core, qctrl); |
937 | } | 937 | } |
938 | 938 | ||
939 | static int vidioc_enum_input (struct file *file, void *priv, | 939 | static int vidioc_enum_input (struct file *file, void *priv, |
@@ -1055,7 +1055,7 @@ static int mpeg_open(struct inode *inode, struct file *file) | |||
1055 | 1055 | ||
1056 | dev = cx8802_get_device(inode); | 1056 | dev = cx8802_get_device(inode); |
1057 | 1057 | ||
1058 | dprintk( 1, "%s\n", __FUNCTION__); | 1058 | dprintk( 1, "%s\n", __func__); |
1059 | 1059 | ||
1060 | if (dev == NULL) | 1060 | if (dev == NULL) |
1061 | return -ENODEV; | 1061 | return -ENODEV; |
@@ -1065,7 +1065,7 @@ static int mpeg_open(struct inode *inode, struct file *file) | |||
1065 | if (drv) { | 1065 | if (drv) { |
1066 | err = drv->request_acquire(drv); | 1066 | err = drv->request_acquire(drv); |
1067 | if(err != 0) { | 1067 | if(err != 0) { |
1068 | dprintk(1,"%s: Unable to acquire hardware, %d\n", __FUNCTION__, err); | 1068 | dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); |
1069 | return err; | 1069 | return err; |
1070 | } | 1070 | } |
1071 | } | 1071 | } |
@@ -1087,8 +1087,8 @@ static int mpeg_open(struct inode *inode, struct file *file) | |||
1087 | file->private_data = fh; | 1087 | file->private_data = fh; |
1088 | fh->dev = dev; | 1088 | fh->dev = dev; |
1089 | 1089 | ||
1090 | videobuf_queue_pci_init(&fh->mpegq, &blackbird_qops, | 1090 | videobuf_queue_sg_init(&fh->mpegq, &blackbird_qops, |
1091 | dev->pci, &dev->slock, | 1091 | &dev->pci->dev, &dev->slock, |
1092 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1092 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1093 | V4L2_FIELD_INTERLACED, | 1093 | V4L2_FIELD_INTERLACED, |
1094 | sizeof(struct cx88_buffer), | 1094 | sizeof(struct cx88_buffer), |
@@ -1284,7 +1284,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) | |||
1284 | struct cx8802_dev *dev = core->dvbdev; | 1284 | struct cx8802_dev *dev = core->dvbdev; |
1285 | int err; | 1285 | int err; |
1286 | 1286 | ||
1287 | dprintk( 1, "%s\n", __FUNCTION__); | 1287 | dprintk( 1, "%s\n", __func__); |
1288 | dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", | 1288 | dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", |
1289 | core->boardnr, | 1289 | core->boardnr, |
1290 | core->name, | 1290 | core->name, |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 8c9a8adf52de..620159d05506 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -44,6 +44,16 @@ static unsigned int latency = UNSET; | |||
44 | module_param(latency,int,0444); | 44 | module_param(latency,int,0444); |
45 | MODULE_PARM_DESC(latency,"pci latency timer"); | 45 | MODULE_PARM_DESC(latency,"pci latency timer"); |
46 | 46 | ||
47 | #define info_printk(core, fmt, arg...) \ | ||
48 | printk(KERN_INFO "%s: " fmt, core->name , ## arg) | ||
49 | |||
50 | #define warn_printk(core, fmt, arg...) \ | ||
51 | printk(KERN_WARNING "%s: " fmt, core->name , ## arg) | ||
52 | |||
53 | #define err_printk(core, fmt, arg...) \ | ||
54 | printk(KERN_ERR "%s: " fmt, core->name , ## arg) | ||
55 | |||
56 | |||
47 | /* ------------------------------------------------------------------ */ | 57 | /* ------------------------------------------------------------------ */ |
48 | /* board config info */ | 58 | /* board config info */ |
49 | 59 | ||
@@ -1354,6 +1364,10 @@ static const struct cx88_board cx88_boards[] = { | |||
1354 | }}, | 1364 | }}, |
1355 | /* fixme: Add radio support */ | 1365 | /* fixme: Add radio support */ |
1356 | .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, | 1366 | .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, |
1367 | .radio = { | ||
1368 | .type = CX88_RADIO, | ||
1369 | .gpio0 = 0xe780, | ||
1370 | }, | ||
1357 | }, | 1371 | }, |
1358 | [CX88_BOARD_ADSTECH_PTV_390] = { | 1372 | [CX88_BOARD_ADSTECH_PTV_390] = { |
1359 | .name = "ADS Tech Instant Video PCI", | 1373 | .name = "ADS Tech Instant Video PCI", |
@@ -1401,6 +1415,245 @@ static const struct cx88_board cx88_boards[] = { | |||
1401 | }}, | 1415 | }}, |
1402 | .mpeg = CX88_MPEG_DVB, | 1416 | .mpeg = CX88_MPEG_DVB, |
1403 | }, | 1417 | }, |
1418 | [CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO] = { | ||
1419 | .name = "DViCO FusionHDTV 5 PCI nano", | ||
1420 | /* xc3008 tuner, digital only for now */ | ||
1421 | .tuner_type = TUNER_ABSENT, | ||
1422 | .radio_type = UNSET, | ||
1423 | .tuner_addr = ADDR_UNSET, | ||
1424 | .radio_addr = ADDR_UNSET, | ||
1425 | .input = {{ | ||
1426 | .type = CX88_VMUX_TELEVISION, | ||
1427 | .vmux = 0, | ||
1428 | .gpio0 = 0x000027df, /* Unconfirmed */ | ||
1429 | }, { | ||
1430 | .type = CX88_VMUX_COMPOSITE1, | ||
1431 | .vmux = 1, | ||
1432 | .gpio0 = 0x000027df, /* Unconfirmed */ | ||
1433 | .audioroute = 1, | ||
1434 | }, { | ||
1435 | .type = CX88_VMUX_SVIDEO, | ||
1436 | .vmux = 2, | ||
1437 | .gpio0 = 0x000027df, /* Unconfirmed */ | ||
1438 | .audioroute = 1, | ||
1439 | } }, | ||
1440 | .mpeg = CX88_MPEG_DVB, | ||
1441 | }, | ||
1442 | [CX88_BOARD_PINNACLE_HYBRID_PCTV] = { | ||
1443 | .name = "Pinnacle Hybrid PCTV", | ||
1444 | .tuner_type = TUNER_XC2028, | ||
1445 | .tuner_addr = 0x61, | ||
1446 | .input = { { | ||
1447 | .type = CX88_VMUX_TELEVISION, | ||
1448 | .vmux = 0, | ||
1449 | }, { | ||
1450 | .type = CX88_VMUX_COMPOSITE1, | ||
1451 | .vmux = 1, | ||
1452 | }, { | ||
1453 | .type = CX88_VMUX_SVIDEO, | ||
1454 | .vmux = 2, | ||
1455 | } }, | ||
1456 | .radio = { | ||
1457 | .type = CX88_RADIO, | ||
1458 | .gpio0 = 0x004ff, | ||
1459 | .gpio1 = 0x010ff, | ||
1460 | .gpio2 = 0x0ff, | ||
1461 | }, | ||
1462 | }, | ||
1463 | [CX88_BOARD_WINFAST_TV2000_XP_GLOBAL] = { | ||
1464 | .name = "Winfast TV2000 XP Global", | ||
1465 | .tuner_type = TUNER_XC2028, | ||
1466 | .tuner_addr = 0x61, | ||
1467 | .input = { { | ||
1468 | .type = CX88_VMUX_TELEVISION, | ||
1469 | .vmux = 0, | ||
1470 | .gpio0 = 0x0400, /* pin 2:mute = 0 (off?) */ | ||
1471 | .gpio1 = 0x0000, | ||
1472 | .gpio2 = 0x0800, /* pin 19:audio = 0 (tv) */ | ||
1473 | |||
1474 | }, { | ||
1475 | .type = CX88_VMUX_COMPOSITE1, | ||
1476 | .vmux = 1, | ||
1477 | .gpio0 = 0x0400, /* probably? or 0x0404 to turn mute on */ | ||
1478 | .gpio1 = 0x0000, | ||
1479 | .gpio2 = 0x0808, /* pin 19:audio = 1 (line) */ | ||
1480 | |||
1481 | }, { | ||
1482 | .type = CX88_VMUX_SVIDEO, | ||
1483 | .vmux = 2, | ||
1484 | } }, | ||
1485 | .radio = { | ||
1486 | .type = CX88_RADIO, | ||
1487 | .gpio0 = 0x004ff, | ||
1488 | .gpio1 = 0x010ff, | ||
1489 | .gpio2 = 0x0ff, | ||
1490 | }, | ||
1491 | }, | ||
1492 | [CX88_BOARD_POWERCOLOR_REAL_ANGEL] = { | ||
1493 | .name = "PowerColor Real Angel 330", | ||
1494 | .tuner_type = TUNER_XC2028, | ||
1495 | .tuner_addr = 0x61, | ||
1496 | .input = { { | ||
1497 | .type = CX88_VMUX_TELEVISION, | ||
1498 | .vmux = 0, | ||
1499 | .gpio0 = 0x00ff, | ||
1500 | .gpio1 = 0xf35d, | ||
1501 | .gpio3 = 0x0000, | ||
1502 | }, { | ||
1503 | .type = CX88_VMUX_COMPOSITE1, | ||
1504 | .vmux = 1, | ||
1505 | .gpio0 = 0x00ff, | ||
1506 | .gpio1 = 0xf37d, | ||
1507 | .gpio3 = 0x0000, | ||
1508 | }, { | ||
1509 | .type = CX88_VMUX_SVIDEO, | ||
1510 | .vmux = 2, | ||
1511 | .gpio0 = 0x000ff, | ||
1512 | .gpio1 = 0x0f37d, | ||
1513 | .gpio3 = 0x00000, | ||
1514 | } }, | ||
1515 | .radio = { | ||
1516 | .type = CX88_RADIO, | ||
1517 | .gpio0 = 0x000ff, | ||
1518 | .gpio1 = 0x0f35d, | ||
1519 | .gpio3 = 0x00000, | ||
1520 | }, | ||
1521 | }, | ||
1522 | [CX88_BOARD_GENIATECH_X8000_MT] = { | ||
1523 | /* Also PowerColor Real Angel 330 and Geniatech X800 OEM */ | ||
1524 | .name = "Geniatech X8000-MT DVBT", | ||
1525 | .tuner_type = TUNER_XC2028, | ||
1526 | .tuner_addr = 0x61, | ||
1527 | .input = { { | ||
1528 | .type = CX88_VMUX_TELEVISION, | ||
1529 | .vmux = 0, | ||
1530 | .gpio0 = 0x00000000, | ||
1531 | .gpio1 = 0x00e3e341, | ||
1532 | .gpio2 = 0x00000000, | ||
1533 | .gpio3 = 0x00000000, | ||
1534 | }, { | ||
1535 | .type = CX88_VMUX_COMPOSITE1, | ||
1536 | .vmux = 1, | ||
1537 | .gpio0 = 0x00000000, | ||
1538 | .gpio1 = 0x00e3e361, | ||
1539 | .gpio2 = 0x00000000, | ||
1540 | .gpio3 = 0x00000000, | ||
1541 | }, { | ||
1542 | .type = CX88_VMUX_SVIDEO, | ||
1543 | .vmux = 2, | ||
1544 | .gpio0 = 0x00000000, | ||
1545 | .gpio1 = 0x00e3e361, | ||
1546 | .gpio2 = 0x00000000, | ||
1547 | .gpio3 = 0x00000000, | ||
1548 | } }, | ||
1549 | .radio = { | ||
1550 | .type = CX88_RADIO, | ||
1551 | .gpio0 = 0x00000000, | ||
1552 | .gpio1 = 0x00e3e341, | ||
1553 | .gpio2 = 0x00000000, | ||
1554 | .gpio3 = 0x00000000, | ||
1555 | }, | ||
1556 | .mpeg = CX88_MPEG_DVB, | ||
1557 | }, | ||
1558 | [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO] = { | ||
1559 | .name = "DViCO FusionHDTV DVB-T PRO", | ||
1560 | .tuner_type = TUNER_ABSENT, /* XXX: Has XC3028 */ | ||
1561 | .radio_type = UNSET, | ||
1562 | .tuner_addr = ADDR_UNSET, | ||
1563 | .radio_addr = ADDR_UNSET, | ||
1564 | .input = { { | ||
1565 | .type = CX88_VMUX_COMPOSITE1, | ||
1566 | .vmux = 1, | ||
1567 | .gpio0 = 0x000067df, | ||
1568 | }, { | ||
1569 | .type = CX88_VMUX_SVIDEO, | ||
1570 | .vmux = 2, | ||
1571 | .gpio0 = 0x000067df, | ||
1572 | } }, | ||
1573 | .mpeg = CX88_MPEG_DVB, | ||
1574 | }, | ||
1575 | [CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD] = { | ||
1576 | .name = "DViCO FusionHDTV 7 Gold", | ||
1577 | .tuner_type = TUNER_XC5000, | ||
1578 | .radio_type = UNSET, | ||
1579 | .tuner_addr = ADDR_UNSET, | ||
1580 | .radio_addr = ADDR_UNSET, | ||
1581 | .input = {{ | ||
1582 | .type = CX88_VMUX_TELEVISION, | ||
1583 | .vmux = 0, | ||
1584 | .gpio0 = 0x10df, | ||
1585 | },{ | ||
1586 | .type = CX88_VMUX_COMPOSITE1, | ||
1587 | .vmux = 1, | ||
1588 | .gpio0 = 0x16d9, | ||
1589 | },{ | ||
1590 | .type = CX88_VMUX_SVIDEO, | ||
1591 | .vmux = 2, | ||
1592 | .gpio0 = 0x16d9, | ||
1593 | }}, | ||
1594 | }, | ||
1595 | [CX88_BOARD_PROLINK_PV_8000GT] = { | ||
1596 | .name = "Prolink Pixelview MPEG 8000GT", | ||
1597 | .tuner_type = TUNER_XC2028, | ||
1598 | .tuner_addr = 0x61, | ||
1599 | .input = { { | ||
1600 | .type = CX88_VMUX_TELEVISION, | ||
1601 | .vmux = 0, | ||
1602 | .gpio0 = 0x0ff, | ||
1603 | .gpio2 = 0x0cfb, | ||
1604 | }, { | ||
1605 | .type = CX88_VMUX_COMPOSITE1, | ||
1606 | .vmux = 1, | ||
1607 | .gpio2 = 0x0cfb, | ||
1608 | }, { | ||
1609 | .type = CX88_VMUX_SVIDEO, | ||
1610 | .vmux = 2, | ||
1611 | .gpio2 = 0x0cfb, | ||
1612 | } }, | ||
1613 | .radio = { | ||
1614 | .type = CX88_RADIO, | ||
1615 | .gpio2 = 0x0cfb, | ||
1616 | }, | ||
1617 | }, | ||
1618 | /* Both radio, analog and ATSC work with this board. | ||
1619 | However, for analog to work, s5h1409 gate should be open, | ||
1620 | otherwise, tuner-xc3028 won't be detected. | ||
1621 | A proper fix require using the newer i2c methods to add | ||
1622 | tuner-xc3028 without doing an i2c probe. | ||
1623 | */ | ||
1624 | [CX88_BOARD_KWORLD_ATSC_120] = { | ||
1625 | .name = "Kworld PlusTV HD PCI 120 (ATSC 120)", | ||
1626 | .tuner_type = TUNER_XC2028, | ||
1627 | .radio_type = UNSET, | ||
1628 | .tuner_addr = ADDR_UNSET, | ||
1629 | .radio_addr = ADDR_UNSET, | ||
1630 | .input = { { | ||
1631 | .type = CX88_VMUX_TELEVISION, | ||
1632 | .vmux = 0, | ||
1633 | .gpio0 = 0x000000ff, | ||
1634 | .gpio1 = 0x0000f35d, | ||
1635 | .gpio2 = 0x00000000, | ||
1636 | }, { | ||
1637 | .type = CX88_VMUX_COMPOSITE1, | ||
1638 | .vmux = 1, | ||
1639 | .gpio0 = 0x000000ff, | ||
1640 | .gpio1 = 0x0000f37e, | ||
1641 | .gpio2 = 0x00000000, | ||
1642 | }, { | ||
1643 | .type = CX88_VMUX_SVIDEO, | ||
1644 | .vmux = 2, | ||
1645 | .gpio0 = 0x000000ff, | ||
1646 | .gpio1 = 0x0000f37e, | ||
1647 | .gpio2 = 0x00000000, | ||
1648 | } }, | ||
1649 | .radio = { | ||
1650 | .type = CX88_RADIO, | ||
1651 | .gpio0 = 0x000000ff, | ||
1652 | .gpio1 = 0x0000f35d, | ||
1653 | .gpio2 = 0x00000000, | ||
1654 | }, | ||
1655 | .mpeg = CX88_MPEG_DVB, | ||
1656 | }, | ||
1404 | }; | 1657 | }; |
1405 | 1658 | ||
1406 | /* ------------------------------------------------------------------ */ | 1659 | /* ------------------------------------------------------------------ */ |
@@ -1605,7 +1858,11 @@ static const struct cx88_subid cx88_subids[] = { | |||
1605 | .subdevice = 0xdb11, | 1858 | .subdevice = 0xdb11, |
1606 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, | 1859 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, |
1607 | /* Re-branded DViCO: UltraView DVB-T Plus */ | 1860 | /* Re-branded DViCO: UltraView DVB-T Plus */ |
1608 | },{ | 1861 | }, { |
1862 | .subvendor = 0x18ac, | ||
1863 | .subdevice = 0xdb30, | ||
1864 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO, | ||
1865 | }, { | ||
1609 | .subvendor = 0x17de, | 1866 | .subvendor = 0x17de, |
1610 | .subdevice = 0x0840, | 1867 | .subdevice = 0x0840, |
1611 | .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT, | 1868 | .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT, |
@@ -1714,6 +1971,38 @@ static const struct cx88_subid cx88_subids[] = { | |||
1714 | .subvendor = 0x11bd, | 1971 | .subvendor = 0x11bd, |
1715 | .subdevice = 0x0051, | 1972 | .subdevice = 0x0051, |
1716 | .card = CX88_BOARD_PINNACLE_PCTV_HD_800i, | 1973 | .card = CX88_BOARD_PINNACLE_PCTV_HD_800i, |
1974 | }, { | ||
1975 | .subvendor = 0x18ac, | ||
1976 | .subdevice = 0xd530, | ||
1977 | .card = CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO, | ||
1978 | }, { | ||
1979 | .subvendor = 0x12ab, | ||
1980 | .subdevice = 0x1788, | ||
1981 | .card = CX88_BOARD_PINNACLE_HYBRID_PCTV, | ||
1982 | }, { | ||
1983 | .subvendor = 0x14f1, | ||
1984 | .subdevice = 0xea3d, | ||
1985 | .card = CX88_BOARD_POWERCOLOR_REAL_ANGEL, | ||
1986 | }, { | ||
1987 | .subvendor = 0x107d, | ||
1988 | .subdevice = 0x6f18, | ||
1989 | .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL, | ||
1990 | }, { | ||
1991 | .subvendor = 0x14f1, | ||
1992 | .subdevice = 0x8852, | ||
1993 | .card = CX88_BOARD_GENIATECH_X8000_MT, | ||
1994 | }, { | ||
1995 | .subvendor = 0x18ac, | ||
1996 | .subdevice = 0xd610, | ||
1997 | .card = CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD, | ||
1998 | }, { | ||
1999 | .subvendor = 0x1554, | ||
2000 | .subdevice = 0x4935, | ||
2001 | .card = CX88_BOARD_PROLINK_PV_8000GT, | ||
2002 | }, { | ||
2003 | .subvendor = 0x17de, | ||
2004 | .subdevice = 0x08c1, | ||
2005 | .card = CX88_BOARD_KWORLD_ATSC_120, | ||
1717 | }, | 2006 | }, |
1718 | }; | 2007 | }; |
1719 | 2008 | ||
@@ -1731,17 +2020,16 @@ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
1731 | if (eeprom_data[4] != 0x7d || | 2020 | if (eeprom_data[4] != 0x7d || |
1732 | eeprom_data[5] != 0x10 || | 2021 | eeprom_data[5] != 0x10 || |
1733 | eeprom_data[7] != 0x66) { | 2022 | eeprom_data[7] != 0x66) { |
1734 | printk(KERN_WARNING "%s: Leadtek eeprom invalid.\n", | 2023 | warn_printk(core, "Leadtek eeprom invalid.\n"); |
1735 | core->name); | ||
1736 | return; | 2024 | return; |
1737 | } | 2025 | } |
1738 | 2026 | ||
1739 | core->board.tuner_type = (eeprom_data[6] == 0x13) ? | 2027 | core->board.tuner_type = (eeprom_data[6] == 0x13) ? |
1740 | TUNER_PHILIPS_FM1236_MK3 : TUNER_PHILIPS_FM1216ME_MK3; | 2028 | TUNER_PHILIPS_FM1236_MK3 : TUNER_PHILIPS_FM1216ME_MK3; |
1741 | 2029 | ||
1742 | printk(KERN_INFO "%s: Leadtek Winfast 2000XP Expert config: " | 2030 | info_printk(core, "Leadtek Winfast 2000XP Expert config: " |
1743 | "tuner=%d, eeprom[0]=0x%02x\n", | 2031 | "tuner=%d, eeprom[0]=0x%02x\n", |
1744 | core->name, core->board.tuner_type, eeprom_data[0]); | 2032 | core->board.tuner_type, eeprom_data[0]); |
1745 | } | 2033 | } |
1746 | 2034 | ||
1747 | static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) | 2035 | static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) |
@@ -1785,13 +2073,12 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
1785 | /* known */ | 2073 | /* known */ |
1786 | break; | 2074 | break; |
1787 | default: | 2075 | default: |
1788 | printk("%s: warning: unknown hauppauge model #%d\n", | 2076 | warn_printk(core, "warning: unknown hauppauge model #%d\n", |
1789 | core->name, tv.model); | 2077 | tv.model); |
1790 | break; | 2078 | break; |
1791 | } | 2079 | } |
1792 | 2080 | ||
1793 | printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", | 2081 | info_printk(core, "hauppauge eeprom: model=%d\n", tv.model); |
1794 | core->name, tv.model); | ||
1795 | } | 2082 | } |
1796 | 2083 | ||
1797 | /* ----------------------------------------------------------------------- */ | 2084 | /* ----------------------------------------------------------------------- */ |
@@ -1837,8 +2124,7 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
1837 | char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner)) | 2124 | char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner)) |
1838 | ? gdi_tuner[eeprom_data[0x0d]].name : NULL; | 2125 | ? gdi_tuner[eeprom_data[0x0d]].name : NULL; |
1839 | 2126 | ||
1840 | printk(KERN_INFO "%s: GDI: tuner=%s\n", core->name, | 2127 | info_printk(core, "GDI: tuner=%s\n", name ? name : "unknown"); |
1841 | name ? name : "unknown"); | ||
1842 | if (NULL == name) | 2128 | if (NULL == name) |
1843 | return; | 2129 | return; |
1844 | core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id; | 2130 | core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id; |
@@ -1846,6 +2132,75 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
1846 | CX88_RADIO : 0; | 2132 | CX88_RADIO : 0; |
1847 | } | 2133 | } |
1848 | 2134 | ||
2135 | /* ------------------------------------------------------------------- */ | ||
2136 | /* some Divco specific stuff */ | ||
2137 | static int cx88_dvico_xc2028_callback(struct cx88_core *core, | ||
2138 | int command, int arg) | ||
2139 | { | ||
2140 | switch (command) { | ||
2141 | case XC2028_TUNER_RESET: | ||
2142 | cx_write(MO_GP0_IO, 0x101000); | ||
2143 | mdelay(5); | ||
2144 | cx_set(MO_GP0_IO, 0x101010); | ||
2145 | break; | ||
2146 | default: | ||
2147 | return -EINVAL; | ||
2148 | } | ||
2149 | |||
2150 | return 0; | ||
2151 | } | ||
2152 | |||
2153 | |||
2154 | /* ----------------------------------------------------------------------- */ | ||
2155 | /* some Geniatech specific stuff */ | ||
2156 | |||
2157 | static int cx88_xc3028_geniatech_tuner_callback(struct cx88_core *core, | ||
2158 | int command, int mode) | ||
2159 | { | ||
2160 | switch (command) { | ||
2161 | case XC2028_TUNER_RESET: | ||
2162 | switch (INPUT(core->input).type) { | ||
2163 | case CX88_RADIO: | ||
2164 | break; | ||
2165 | case CX88_VMUX_DVB: | ||
2166 | cx_write(MO_GP1_IO, 0x030302); | ||
2167 | mdelay(50); | ||
2168 | break; | ||
2169 | default: | ||
2170 | cx_write(MO_GP1_IO, 0x030301); | ||
2171 | mdelay(50); | ||
2172 | } | ||
2173 | cx_write(MO_GP1_IO, 0x101010); | ||
2174 | mdelay(50); | ||
2175 | cx_write(MO_GP1_IO, 0x101000); | ||
2176 | mdelay(50); | ||
2177 | cx_write(MO_GP1_IO, 0x101010); | ||
2178 | mdelay(50); | ||
2179 | return 0; | ||
2180 | } | ||
2181 | return -EINVAL; | ||
2182 | } | ||
2183 | |||
2184 | /* ------------------------------------------------------------------- */ | ||
2185 | /* some Divco specific stuff */ | ||
2186 | static int cx88_pv_8000gt_callback(struct cx88_core *core, | ||
2187 | int command, int arg) | ||
2188 | { | ||
2189 | switch (command) { | ||
2190 | case XC2028_TUNER_RESET: | ||
2191 | cx_write(MO_GP2_IO, 0xcf7); | ||
2192 | mdelay(50); | ||
2193 | cx_write(MO_GP2_IO, 0xef5); | ||
2194 | mdelay(50); | ||
2195 | cx_write(MO_GP2_IO, 0xcf7); | ||
2196 | break; | ||
2197 | default: | ||
2198 | return -EINVAL; | ||
2199 | } | ||
2200 | |||
2201 | return 0; | ||
2202 | } | ||
2203 | |||
1849 | /* ----------------------------------------------------------------------- */ | 2204 | /* ----------------------------------------------------------------------- */ |
1850 | /* some DViCO specific stuff */ | 2205 | /* some DViCO specific stuff */ |
1851 | 2206 | ||
@@ -1874,32 +2229,85 @@ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core) | |||
1874 | msg.len = (i != 12 ? 5 : 2); | 2229 | msg.len = (i != 12 ? 5 : 2); |
1875 | err = i2c_transfer(&core->i2c_adap, &msg, 1); | 2230 | err = i2c_transfer(&core->i2c_adap, &msg, 1); |
1876 | if (err != 1) { | 2231 | if (err != 1) { |
1877 | printk("dvico_fusionhdtv_hybrid_init buf %d failed (err = %d)!\n", i, err); | 2232 | warn_printk(core, "dvico_fusionhdtv_hybrid_init buf %d " |
2233 | "failed (err = %d)!\n", i, err); | ||
1878 | return; | 2234 | return; |
1879 | } | 2235 | } |
1880 | } | 2236 | } |
1881 | } | 2237 | } |
1882 | 2238 | ||
2239 | static int cx88_xc2028_tuner_callback(struct cx88_core *core, | ||
2240 | int command, int arg) | ||
2241 | { | ||
2242 | /* Board-specific callbacks */ | ||
2243 | switch (core->boardnr) { | ||
2244 | case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: | ||
2245 | case CX88_BOARD_POWERCOLOR_REAL_ANGEL: | ||
2246 | case CX88_BOARD_GENIATECH_X8000_MT: | ||
2247 | case CX88_BOARD_KWORLD_ATSC_120: | ||
2248 | return cx88_xc3028_geniatech_tuner_callback(core, | ||
2249 | command, arg); | ||
2250 | case CX88_BOARD_PROLINK_PV_8000GT: | ||
2251 | return cx88_pv_8000gt_callback(core, command, arg); | ||
2252 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: | ||
2253 | return cx88_dvico_xc2028_callback(core, command, arg); | ||
2254 | } | ||
2255 | |||
2256 | switch (command) { | ||
2257 | case XC2028_TUNER_RESET: | ||
2258 | switch (INPUT(core->input).type) { | ||
2259 | case CX88_RADIO: | ||
2260 | info_printk(core, "setting GPIO to radio!\n"); | ||
2261 | cx_write(MO_GP0_IO, 0x4ff); | ||
2262 | mdelay(250); | ||
2263 | cx_write(MO_GP2_IO, 0xff); | ||
2264 | mdelay(250); | ||
2265 | break; | ||
2266 | case CX88_VMUX_DVB: /* Digital TV*/ | ||
2267 | default: /* Analog TV */ | ||
2268 | info_printk(core, "setting GPIO to TV!\n"); | ||
2269 | break; | ||
2270 | } | ||
2271 | cx_write(MO_GP1_IO, 0x101010); | ||
2272 | mdelay(250); | ||
2273 | cx_write(MO_GP1_IO, 0x101000); | ||
2274 | mdelay(250); | ||
2275 | cx_write(MO_GP1_IO, 0x101010); | ||
2276 | mdelay(250); | ||
2277 | return 0; | ||
2278 | } | ||
2279 | return -EINVAL; | ||
2280 | } | ||
2281 | |||
1883 | /* ----------------------------------------------------------------------- */ | 2282 | /* ----------------------------------------------------------------------- */ |
1884 | /* Tuner callback function. Currently only needed for the Pinnacle * | 2283 | /* Tuner callback function. Currently only needed for the Pinnacle * |
1885 | * PCTV HD 800i with an xc5000 sillicon tuner. This is used for both * | 2284 | * PCTV HD 800i with an xc5000 sillicon tuner. This is used for both * |
1886 | * analog tuner attach (tuner-core.c) and dvb tuner attach (cx88-dvb.c) */ | 2285 | * analog tuner attach (tuner-core.c) and dvb tuner attach (cx88-dvb.c) */ |
1887 | 2286 | ||
1888 | int cx88_tuner_callback(void *priv, int command, int arg) | 2287 | static int cx88_xc5000_tuner_callback(struct cx88_core *core, |
2288 | int command, int arg) | ||
1889 | { | 2289 | { |
1890 | struct i2c_algo_bit_data *i2c_algo = priv; | 2290 | switch (core->boardnr) { |
1891 | struct cx88_core *core = i2c_algo->data; | ||
1892 | |||
1893 | switch(core->boardnr) { | ||
1894 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: | 2291 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: |
1895 | if(command == 0) { /* This is the reset command from xc5000 */ | 2292 | if (command == 0) { /* This is the reset command from xc5000 */ |
1896 | /* Reset XC5000 tuner via SYS_RSTO_pin */ | 2293 | /* Reset XC5000 tuner via SYS_RSTO_pin */ |
1897 | cx_write(MO_SRST_IO, 0); | 2294 | cx_write(MO_SRST_IO, 0); |
1898 | msleep(10); | 2295 | msleep(10); |
1899 | cx_write(MO_SRST_IO, 1); | 2296 | cx_write(MO_SRST_IO, 1); |
1900 | return 0; | 2297 | return 0; |
2298 | } else { | ||
2299 | err_printk(core, "xc5000: unknown tuner " | ||
2300 | "callback command.\n"); | ||
2301 | return -EINVAL; | ||
1901 | } | 2302 | } |
1902 | else { | 2303 | break; |
2304 | case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: | ||
2305 | if (command == 0) { /* This is the reset command from xc5000 */ | ||
2306 | cx_clear(MO_GP0_IO, 0x00000010); | ||
2307 | msleep(10); | ||
2308 | cx_set(MO_GP0_IO, 0x00000010); | ||
2309 | return 0; | ||
2310 | } else { | ||
1903 | printk(KERN_ERR | 2311 | printk(KERN_ERR |
1904 | "xc5000: unknown tuner callback command.\n"); | 2312 | "xc5000: unknown tuner callback command.\n"); |
1905 | return -EINVAL; | 2313 | return -EINVAL; |
@@ -1908,6 +2316,36 @@ int cx88_tuner_callback(void *priv, int command, int arg) | |||
1908 | } | 2316 | } |
1909 | return 0; /* Should never be here */ | 2317 | return 0; /* Should never be here */ |
1910 | } | 2318 | } |
2319 | |||
2320 | int cx88_tuner_callback(void *priv, int command, int arg) | ||
2321 | { | ||
2322 | struct i2c_algo_bit_data *i2c_algo = priv; | ||
2323 | struct cx88_core *core; | ||
2324 | |||
2325 | if (!i2c_algo) { | ||
2326 | printk(KERN_ERR "cx88: Error - i2c private data undefined.\n"); | ||
2327 | return -EINVAL; | ||
2328 | } | ||
2329 | |||
2330 | core = i2c_algo->data; | ||
2331 | |||
2332 | if (!core) { | ||
2333 | printk(KERN_ERR "cx88: Error - device struct undefined.\n"); | ||
2334 | return -EINVAL; | ||
2335 | } | ||
2336 | |||
2337 | switch (core->board.tuner_type) { | ||
2338 | case TUNER_XC2028: | ||
2339 | info_printk(core, "Calling XC2028/3028 callback\n"); | ||
2340 | return cx88_xc2028_tuner_callback(core, command, arg); | ||
2341 | case TUNER_XC5000: | ||
2342 | info_printk(core, "Calling XC5000 callback\n"); | ||
2343 | return cx88_xc5000_tuner_callback(core, command, arg); | ||
2344 | } | ||
2345 | err_printk(core, "Error: Calling callback for tuner %d\n", | ||
2346 | core->board.tuner_type); | ||
2347 | return -EINVAL; | ||
2348 | } | ||
1911 | EXPORT_SYMBOL(cx88_tuner_callback); | 2349 | EXPORT_SYMBOL(cx88_tuner_callback); |
1912 | 2350 | ||
1913 | /* ----------------------------------------------------------------------- */ | 2351 | /* ----------------------------------------------------------------------- */ |
@@ -1918,23 +2356,25 @@ static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) | |||
1918 | 2356 | ||
1919 | if (0 == pci->subsystem_vendor && | 2357 | if (0 == pci->subsystem_vendor && |
1920 | 0 == pci->subsystem_device) { | 2358 | 0 == pci->subsystem_device) { |
1921 | printk("%s: Your board has no valid PCI Subsystem ID and thus can't\n" | 2359 | printk(KERN_ERR |
2360 | "%s: Your board has no valid PCI Subsystem ID and thus can't\n" | ||
1922 | "%s: be autodetected. Please pass card=<n> insmod option to\n" | 2361 | "%s: be autodetected. Please pass card=<n> insmod option to\n" |
1923 | "%s: workaround that. Redirect complaints to the vendor of\n" | 2362 | "%s: workaround that. Redirect complaints to the vendor of\n" |
1924 | "%s: the TV card. Best regards,\n" | 2363 | "%s: the TV card. Best regards,\n" |
1925 | "%s: -- tux\n", | 2364 | "%s: -- tux\n", |
1926 | core->name,core->name,core->name,core->name,core->name); | 2365 | core->name,core->name,core->name,core->name,core->name); |
1927 | } else { | 2366 | } else { |
1928 | printk("%s: Your board isn't known (yet) to the driver. You can\n" | 2367 | printk(KERN_ERR |
2368 | "%s: Your board isn't known (yet) to the driver. You can\n" | ||
1929 | "%s: try to pick one of the existing card configs via\n" | 2369 | "%s: try to pick one of the existing card configs via\n" |
1930 | "%s: card=<n> insmod option. Updating to the latest\n" | 2370 | "%s: card=<n> insmod option. Updating to the latest\n" |
1931 | "%s: version might help as well.\n", | 2371 | "%s: version might help as well.\n", |
1932 | core->name,core->name,core->name,core->name); | 2372 | core->name,core->name,core->name,core->name); |
1933 | } | 2373 | } |
1934 | printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n", | 2374 | err_printk(core, "Here is a list of valid choices for the card=<n> " |
1935 | core->name); | 2375 | "insmod option:\n"); |
1936 | for (i = 0; i < ARRAY_SIZE(cx88_boards); i++) | 2376 | for (i = 0; i < ARRAY_SIZE(cx88_boards); i++) |
1937 | printk("%s: card=%d -> %s\n", | 2377 | printk(KERN_ERR "%s: card=%d -> %s\n", |
1938 | core->name, i, cx88_boards[i].name); | 2378 | core->name, i, cx88_boards[i].name); |
1939 | } | 2379 | } |
1940 | 2380 | ||
@@ -1951,9 +2391,57 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) | |||
1951 | cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ | 2391 | cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ |
1952 | udelay(1000); | 2392 | udelay(1000); |
1953 | break; | 2393 | break; |
2394 | |||
2395 | case CX88_BOARD_PROLINK_PV_8000GT: | ||
2396 | cx_write(MO_GP2_IO, 0xcf7); | ||
2397 | mdelay(50); | ||
2398 | cx_write(MO_GP2_IO, 0xef5); | ||
2399 | mdelay(50); | ||
2400 | cx_write(MO_GP2_IO, 0xcf7); | ||
2401 | msleep(10); | ||
2402 | break; | ||
2403 | |||
2404 | case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: | ||
2405 | /* Enable the xc5000 tuner */ | ||
2406 | cx_set(MO_GP0_IO, 0x00001010); | ||
2407 | break; | ||
1954 | } | 2408 | } |
1955 | } | 2409 | } |
1956 | 2410 | ||
2411 | /* | ||
2412 | * Sets board-dependent xc3028 configuration | ||
2413 | */ | ||
2414 | void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl) | ||
2415 | { | ||
2416 | memset(ctl, 0, sizeof(*ctl)); | ||
2417 | |||
2418 | ctl->fname = XC2028_DEFAULT_FIRMWARE; | ||
2419 | ctl->max_len = 64; | ||
2420 | |||
2421 | switch (core->boardnr) { | ||
2422 | case CX88_BOARD_POWERCOLOR_REAL_ANGEL: | ||
2423 | /* Doesn't work with firmware version 2.7 */ | ||
2424 | ctl->fname = "xc3028-v25.fw"; | ||
2425 | break; | ||
2426 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: | ||
2427 | ctl->scode_table = XC3028_FE_ZARLINK456; | ||
2428 | break; | ||
2429 | case CX88_BOARD_KWORLD_ATSC_120: | ||
2430 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: | ||
2431 | ctl->demod = XC3028_FE_OREN538; | ||
2432 | break; | ||
2433 | case CX88_BOARD_PROLINK_PV_8000GT: | ||
2434 | /* | ||
2435 | * This board uses non-MTS firmware | ||
2436 | */ | ||
2437 | break; | ||
2438 | default: | ||
2439 | ctl->demod = XC3028_FE_OREN538; | ||
2440 | ctl->mts = 1; | ||
2441 | } | ||
2442 | } | ||
2443 | EXPORT_SYMBOL_GPL(cx88_setup_xc3028); | ||
2444 | |||
1957 | static void cx88_card_setup(struct cx88_core *core) | 2445 | static void cx88_card_setup(struct cx88_core *core) |
1958 | { | 2446 | { |
1959 | static u8 eeprom[256]; | 2447 | static u8 eeprom[256]; |
@@ -1991,6 +2479,13 @@ static void cx88_card_setup(struct cx88_core *core) | |||
1991 | cx_write(MO_GP0_IO, 0x000007f8); | 2479 | cx_write(MO_GP0_IO, 0x000007f8); |
1992 | cx_write(MO_GP1_IO, 0x00000001); | 2480 | cx_write(MO_GP1_IO, 0x00000001); |
1993 | break; | 2481 | break; |
2482 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: | ||
2483 | /* GPIO0:0 is hooked to demod reset */ | ||
2484 | /* GPIO0:4 is hooked to xc3028 reset */ | ||
2485 | cx_write(MO_GP0_IO, 0x00111100); | ||
2486 | msleep(1); | ||
2487 | cx_write(MO_GP0_IO, 0x00111111); | ||
2488 | break; | ||
1994 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: | 2489 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: |
1995 | /* GPIO0:6 is hooked to FX2 reset pin */ | 2490 | /* GPIO0:6 is hooked to FX2 reset pin */ |
1996 | cx_set(MO_GP0_IO, 0x00004040); | 2491 | cx_set(MO_GP0_IO, 0x00004040); |
@@ -2038,10 +2533,8 @@ static void cx88_card_setup(struct cx88_core *core) | |||
2038 | for (i = 0; i < ARRAY_SIZE(buffer); i++) | 2533 | for (i = 0; i < ARRAY_SIZE(buffer); i++) |
2039 | if (2 != i2c_master_send(&core->i2c_client, | 2534 | if (2 != i2c_master_send(&core->i2c_client, |
2040 | buffer[i],2)) | 2535 | buffer[i],2)) |
2041 | printk(KERN_WARNING | 2536 | warn_printk(core, "Unable to enable " |
2042 | "%s: Unable to enable " | 2537 | "tuner(%i).\n", i); |
2043 | "tuner(%i).\n", | ||
2044 | core->name, i); | ||
2045 | } | 2538 | } |
2046 | break; | 2539 | break; |
2047 | case CX88_BOARD_MSI_TVANYWHERE_MASTER: | 2540 | case CX88_BOARD_MSI_TVANYWHERE_MASTER: |
@@ -2062,6 +2555,22 @@ static void cx88_card_setup(struct cx88_core *core) | |||
2062 | cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg); | 2555 | cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg); |
2063 | } | 2556 | } |
2064 | } | 2557 | } |
2558 | |||
2559 | if (core->board.tuner_type == TUNER_XC2028) { | ||
2560 | struct v4l2_priv_tun_config xc2028_cfg; | ||
2561 | struct xc2028_ctrl ctl; | ||
2562 | |||
2563 | /* Fills device-dependent initialization parameters */ | ||
2564 | cx88_setup_xc3028(core, &ctl); | ||
2565 | |||
2566 | /* Sends parameters to xc2028/3028 tuner */ | ||
2567 | memset(&xc2028_cfg, 0, sizeof(xc2028_cfg)); | ||
2568 | xc2028_cfg.tuner = TUNER_XC2028; | ||
2569 | xc2028_cfg.priv = &ctl; | ||
2570 | info_printk(core, "Asking xc2028/3028 to load firmware %s\n", | ||
2571 | ctl.fname); | ||
2572 | cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg); | ||
2573 | } | ||
2065 | } | 2574 | } |
2066 | 2575 | ||
2067 | /* ------------------------------------------------------------------ */ | 2576 | /* ------------------------------------------------------------------ */ |
@@ -2178,9 +2687,8 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) | |||
2178 | 2687 | ||
2179 | memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board)); | 2688 | memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board)); |
2180 | 2689 | ||
2181 | printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", | 2690 | info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s]\n", |
2182 | core->name,pci->subsystem_vendor, | 2691 | pci->subsystem_vendor, pci->subsystem_device, core->board.name, |
2183 | pci->subsystem_device, core->board.name, | ||
2184 | core->boardnr, card[core->nr] == core->boardnr ? | 2692 | core->boardnr, card[core->nr] == core->boardnr ? |
2185 | "insmod option" : "autodetected"); | 2693 | "insmod option" : "autodetected"); |
2186 | 2694 | ||
@@ -2189,8 +2697,8 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) | |||
2189 | if (radio[core->nr] != UNSET) | 2697 | if (radio[core->nr] != UNSET) |
2190 | core->board.radio_type = radio[core->nr]; | 2698 | core->board.radio_type = radio[core->nr]; |
2191 | 2699 | ||
2192 | printk(KERN_INFO "%s: TV tuner type %d, Radio tuner type %d\n", | 2700 | info_printk(core, "TV tuner type %d, Radio tuner type %d\n", |
2193 | core->name, core->board.tuner_type, core->board.radio_type); | 2701 | core->board.tuner_type, core->board.radio_type); |
2194 | 2702 | ||
2195 | /* init hardware */ | 2703 | /* init hardware */ |
2196 | cx88_reset(core); | 2704 | cx88_reset(core); |
@@ -2207,12 +2715,3 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) | |||
2207 | 2715 | ||
2208 | return core; | 2716 | return core; |
2209 | } | 2717 | } |
2210 | |||
2211 | /* ------------------------------------------------------------------ */ | ||
2212 | |||
2213 | /* | ||
2214 | * Local variables: | ||
2215 | * c-basic-offset: 8 | ||
2216 | * End: | ||
2217 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off | ||
2218 | */ | ||
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 01e2ac98970b..c4d1aff1fdb4 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -47,15 +47,15 @@ MODULE_LICENSE("GPL"); | |||
47 | 47 | ||
48 | /* ------------------------------------------------------------------ */ | 48 | /* ------------------------------------------------------------------ */ |
49 | 49 | ||
50 | static unsigned int core_debug = 0; | 50 | static unsigned int core_debug; |
51 | module_param(core_debug,int,0644); | 51 | module_param(core_debug,int,0644); |
52 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); | 52 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); |
53 | 53 | ||
54 | static unsigned int nicam = 0; | 54 | static unsigned int nicam; |
55 | module_param(nicam,int,0644); | 55 | module_param(nicam,int,0644); |
56 | MODULE_PARM_DESC(nicam,"tv audio is nicam"); | 56 | MODULE_PARM_DESC(nicam,"tv audio is nicam"); |
57 | 57 | ||
58 | static unsigned int nocomb = 0; | 58 | static unsigned int nocomb; |
59 | module_param(nocomb,int,0644); | 59 | module_param(nocomb,int,0644); |
60 | MODULE_PARM_DESC(nocomb,"disable comb filter"); | 60 | MODULE_PARM_DESC(nocomb,"disable comb filter"); |
61 | 61 | ||
@@ -219,7 +219,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf) | |||
219 | videobuf_waiton(&buf->vb,0,0); | 219 | videobuf_waiton(&buf->vb,0,0); |
220 | videobuf_dma_unmap(q, dma); | 220 | videobuf_dma_unmap(q, dma); |
221 | videobuf_dma_free(dma); | 221 | videobuf_dma_free(dma); |
222 | btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc); | 222 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); |
223 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 223 | buf->vb.state = VIDEOBUF_NEEDS_INIT; |
224 | } | 224 | } |
225 | 225 | ||
@@ -548,7 +548,7 @@ void cx88_wakeup(struct cx88_core *core, | |||
548 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | 548 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); |
549 | } | 549 | } |
550 | if (bc != 1) | 550 | if (bc != 1) |
551 | printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc); | 551 | printk("%s: %d buffers handled (should be 1)\n",__func__,bc); |
552 | } | 552 | } |
553 | 553 | ||
554 | void cx88_shutdown(struct cx88_core *core) | 554 | void cx88_shutdown(struct cx88_core *core) |
@@ -577,7 +577,7 @@ void cx88_shutdown(struct cx88_core *core) | |||
577 | 577 | ||
578 | int cx88_reset(struct cx88_core *core) | 578 | int cx88_reset(struct cx88_core *core) |
579 | { | 579 | { |
580 | dprintk(1,"%s\n",__FUNCTION__); | 580 | dprintk(1,"%s\n",__func__); |
581 | cx88_shutdown(core); | 581 | cx88_shutdown(core); |
582 | 582 | ||
583 | /* clear irq status */ | 583 | /* clear irq status */ |
@@ -929,7 +929,10 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) | |||
929 | 929 | ||
930 | dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n", | 930 | dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n", |
931 | cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f); | 931 | cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f); |
932 | cx_andor(MO_INPUT_FORMAT, 0xf, cxiformat); | 932 | /* Chroma AGC must be disabled if SECAM is used, we enable it |
933 | by default on PAL and NTSC */ | ||
934 | cx_andor(MO_INPUT_FORMAT, 0x40f, | ||
935 | norm & V4L2_STD_SECAM ? cxiformat : cxiformat | 0x400); | ||
933 | 936 | ||
934 | // FIXME: as-is from DScaler | 937 | // FIXME: as-is from DScaler |
935 | dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n", | 938 | dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n", |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index f7b41eb1bb5a..f1251b844e08 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -45,16 +45,20 @@ | |||
45 | #include "nxt200x.h" | 45 | #include "nxt200x.h" |
46 | #include "cx24123.h" | 46 | #include "cx24123.h" |
47 | #include "isl6421.h" | 47 | #include "isl6421.h" |
48 | #include "tuner-simple.h" | ||
49 | #include "tda9887.h" | ||
48 | 50 | ||
49 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); | 51 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); |
50 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); | 52 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); |
51 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 53 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
52 | MODULE_LICENSE("GPL"); | 54 | MODULE_LICENSE("GPL"); |
53 | 55 | ||
54 | static unsigned int debug = 0; | 56 | static unsigned int debug; |
55 | module_param(debug, int, 0644); | 57 | module_param(debug, int, 0644); |
56 | MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); | 58 | MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); |
57 | 59 | ||
60 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
61 | |||
58 | #define dprintk(level,fmt, arg...) if (debug >= level) \ | 62 | #define dprintk(level,fmt, arg...) if (debug >= level) \ |
59 | printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg) | 63 | printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg) |
60 | 64 | ||
@@ -235,6 +239,19 @@ static struct zl10353_config dvico_fusionhdtv_hybrid = { | |||
235 | .no_tuner = 1, | 239 | .no_tuner = 1, |
236 | }; | 240 | }; |
237 | 241 | ||
242 | static struct zl10353_config dvico_fusionhdtv_xc3028 = { | ||
243 | .demod_address = 0x0f, | ||
244 | .if2 = 45600, | ||
245 | .no_tuner = 1, | ||
246 | }; | ||
247 | |||
248 | static struct mt352_config dvico_fusionhdtv_mt352_xc3028 = { | ||
249 | .demod_address = 0x0f, | ||
250 | .if2 = 4560, | ||
251 | .no_tuner = 1, | ||
252 | .demod_init = dvico_fusionhdtv_demod_init, | ||
253 | }; | ||
254 | |||
238 | static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { | 255 | static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { |
239 | .demod_address = 0x0f, | 256 | .demod_address = 0x0f, |
240 | }; | 257 | }; |
@@ -266,7 +283,7 @@ static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) | |||
266 | struct cx8802_dev *dev= fe->dvb->priv; | 283 | struct cx8802_dev *dev= fe->dvb->priv; |
267 | struct cx88_core *core = dev->core; | 284 | struct cx88_core *core = dev->core; |
268 | 285 | ||
269 | dprintk(1, "%s: index = %d\n", __FUNCTION__, index); | 286 | dprintk(1, "%s: index = %d\n", __func__, index); |
270 | if (index == 0) | 287 | if (index == 0) |
271 | cx_clear(MO_GP0_IO, 8); | 288 | cx_clear(MO_GP0_IO, 8); |
272 | else | 289 | else |
@@ -357,6 +374,40 @@ static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, | |||
357 | return 0; | 374 | return 0; |
358 | } | 375 | } |
359 | 376 | ||
377 | static int cx88_pci_nano_callback(void *ptr, int command, int arg) | ||
378 | { | ||
379 | struct cx88_core *core = ptr; | ||
380 | |||
381 | switch (command) { | ||
382 | case XC2028_TUNER_RESET: | ||
383 | /* Send the tuner in then out of reset */ | ||
384 | dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg); | ||
385 | |||
386 | switch (core->boardnr) { | ||
387 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: | ||
388 | /* GPIO-4 xc3028 tuner */ | ||
389 | |||
390 | cx_set(MO_GP0_IO, 0x00001000); | ||
391 | cx_clear(MO_GP0_IO, 0x00000010); | ||
392 | msleep(100); | ||
393 | cx_set(MO_GP0_IO, 0x00000010); | ||
394 | msleep(100); | ||
395 | break; | ||
396 | } | ||
397 | |||
398 | break; | ||
399 | case XC2028_RESET_CLK: | ||
400 | dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg); | ||
401 | break; | ||
402 | default: | ||
403 | dprintk(1, "%s: unknown command %d, arg %d\n", __func__, | ||
404 | command, arg); | ||
405 | return -EINVAL; | ||
406 | } | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | |||
360 | static struct cx24123_config geniatech_dvbs_config = { | 411 | static struct cx24123_config geniatech_dvbs_config = { |
361 | .demod_address = 0x55, | 412 | .demod_address = 0x55, |
362 | .set_ts_params = cx24123_set_ts_param, | 413 | .set_ts_params = cx24123_set_ts_param, |
@@ -383,12 +434,76 @@ static struct s5h1409_config pinnacle_pctv_hd_800i_config = { | |||
383 | .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, | 434 | .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, |
384 | }; | 435 | }; |
385 | 436 | ||
437 | static struct s5h1409_config dvico_hdtv5_pci_nano_config = { | ||
438 | .demod_address = 0x32 >> 1, | ||
439 | .output_mode = S5H1409_SERIAL_OUTPUT, | ||
440 | .gpio = S5H1409_GPIO_OFF, | ||
441 | .inversion = S5H1409_INVERSION_OFF, | ||
442 | .status_mode = S5H1409_DEMODLOCKING, | ||
443 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | ||
444 | }; | ||
445 | |||
446 | static struct s5h1409_config kworld_atsc_120_config = { | ||
447 | .demod_address = 0x32 >> 1, | ||
448 | .output_mode = S5H1409_SERIAL_OUTPUT, | ||
449 | .gpio = S5H1409_GPIO_OFF, | ||
450 | .inversion = S5H1409_INVERSION_OFF, | ||
451 | .status_mode = S5H1409_DEMODLOCKING, | ||
452 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | ||
453 | }; | ||
454 | |||
386 | static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { | 455 | static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { |
387 | .i2c_address = 0x64, | 456 | .i2c_address = 0x64, |
388 | .if_khz = 5380, | 457 | .if_khz = 5380, |
389 | .tuner_callback = cx88_tuner_callback, | 458 | .tuner_callback = cx88_tuner_callback, |
390 | }; | 459 | }; |
391 | 460 | ||
461 | static struct zl10353_config cx88_geniatech_x8000_mt = { | ||
462 | .demod_address = (0x1e >> 1), | ||
463 | .no_tuner = 1, | ||
464 | }; | ||
465 | |||
466 | static int attach_xc3028(u8 addr, struct cx8802_dev *dev) | ||
467 | { | ||
468 | struct dvb_frontend *fe; | ||
469 | struct xc2028_ctrl ctl; | ||
470 | struct xc2028_config cfg = { | ||
471 | .i2c_adap = &dev->core->i2c_adap, | ||
472 | .i2c_addr = addr, | ||
473 | .ctrl = &ctl, | ||
474 | .callback = cx88_tuner_callback, | ||
475 | }; | ||
476 | |||
477 | if (!dev->dvb.frontend) { | ||
478 | printk(KERN_ERR "%s/2: dvb frontend not attached. " | ||
479 | "Can't attach xc3028\n", | ||
480 | dev->core->name); | ||
481 | return -EINVAL; | ||
482 | } | ||
483 | |||
484 | /* | ||
485 | * Some xc3028 devices may be hidden by an I2C gate. This is known | ||
486 | * to happen with some s5h1409-based devices. | ||
487 | * Now that I2C gate is open, sets up xc3028 configuration | ||
488 | */ | ||
489 | cx88_setup_xc3028(dev->core, &ctl); | ||
490 | |||
491 | fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); | ||
492 | if (!fe) { | ||
493 | printk(KERN_ERR "%s/2: xc3028 attach failed\n", | ||
494 | dev->core->name); | ||
495 | dvb_frontend_detach(dev->dvb.frontend); | ||
496 | dvb_unregister_frontend(dev->dvb.frontend); | ||
497 | dev->dvb.frontend = NULL; | ||
498 | return -EINVAL; | ||
499 | } | ||
500 | |||
501 | printk(KERN_INFO "%s/2: xc3028 attached\n", | ||
502 | dev->core->name); | ||
503 | |||
504 | return 0; | ||
505 | } | ||
506 | |||
392 | static int dvb_register(struct cx8802_dev *dev) | 507 | static int dvb_register(struct cx8802_dev *dev) |
393 | { | 508 | { |
394 | /* init struct videobuf_dvb */ | 509 | /* init struct videobuf_dvb */ |
@@ -429,8 +544,9 @@ static int dvb_register(struct cx8802_dev *dev) | |||
429 | &hauppauge_hvr_config, | 544 | &hauppauge_hvr_config, |
430 | &dev->core->i2c_adap); | 545 | &dev->core->i2c_adap); |
431 | if (dev->dvb.frontend != NULL) { | 546 | if (dev->dvb.frontend != NULL) { |
432 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 547 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
433 | &dev->core->i2c_adap, DVB_PLL_FMD1216ME); | 548 | &dev->core->i2c_adap, 0x61, |
549 | TUNER_PHILIPS_FMD1216ME_MK3); | ||
434 | } | 550 | } |
435 | break; | 551 | break; |
436 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: | 552 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: |
@@ -497,8 +613,9 @@ static int dvb_register(struct cx8802_dev *dev) | |||
497 | dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, | 613 | dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, |
498 | &dev->vp3054->adap); | 614 | &dev->vp3054->adap); |
499 | if (dev->dvb.frontend != NULL) { | 615 | if (dev->dvb.frontend != NULL) { |
500 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 616 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
501 | &dev->core->i2c_adap, DVB_PLL_FMD1216ME); | 617 | &dev->core->i2c_adap, 0x61, |
618 | TUNER_PHILIPS_FMD1216ME_MK3); | ||
502 | } | 619 | } |
503 | #else | 620 | #else |
504 | printk(KERN_ERR "%s/2: built without vp3054 support\n", dev->core->name); | 621 | printk(KERN_ERR "%s/2: built without vp3054 support\n", dev->core->name); |
@@ -509,18 +626,36 @@ static int dvb_register(struct cx8802_dev *dev) | |||
509 | &dvico_fusionhdtv_hybrid, | 626 | &dvico_fusionhdtv_hybrid, |
510 | &dev->core->i2c_adap); | 627 | &dev->core->i2c_adap); |
511 | if (dev->dvb.frontend != NULL) { | 628 | if (dev->dvb.frontend != NULL) { |
512 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 629 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
513 | &dev->core->i2c_adap, | 630 | &dev->core->i2c_adap, 0x61, |
514 | DVB_PLL_THOMSON_FE6600); | 631 | TUNER_THOMSON_FE6600); |
515 | } | 632 | } |
516 | break; | 633 | break; |
634 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: | ||
635 | dev->dvb.frontend = dvb_attach(zl10353_attach, | ||
636 | &dvico_fusionhdtv_xc3028, | ||
637 | &dev->core->i2c_adap); | ||
638 | if (dev->dvb.frontend == NULL) | ||
639 | dev->dvb.frontend = dvb_attach(mt352_attach, | ||
640 | &dvico_fusionhdtv_mt352_xc3028, | ||
641 | &dev->core->i2c_adap); | ||
642 | /* | ||
643 | * On this board, the demod provides the I2C bus pullup. | ||
644 | * We must not permit gate_ctrl to be performed, or | ||
645 | * the xc3028 cannot communicate on the bus. | ||
646 | */ | ||
647 | if (dev->dvb.frontend) | ||
648 | dev->dvb.frontend->ops.i2c_gate_ctrl = NULL; | ||
649 | if (attach_xc3028(0x61, dev) < 0) | ||
650 | return -EINVAL; | ||
651 | break; | ||
517 | case CX88_BOARD_PCHDTV_HD3000: | 652 | case CX88_BOARD_PCHDTV_HD3000: |
518 | dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, | 653 | dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, |
519 | &dev->core->i2c_adap); | 654 | &dev->core->i2c_adap); |
520 | if (dev->dvb.frontend != NULL) { | 655 | if (dev->dvb.frontend != NULL) { |
521 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 656 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
522 | &dev->core->i2c_adap, | 657 | &dev->core->i2c_adap, 0x61, |
523 | DVB_PLL_THOMSON_DTT761X); | 658 | TUNER_THOMSON_DTT761X); |
524 | } | 659 | } |
525 | break; | 660 | break; |
526 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: | 661 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: |
@@ -540,9 +675,9 @@ static int dvb_register(struct cx8802_dev *dev) | |||
540 | &fusionhdtv_3_gold, | 675 | &fusionhdtv_3_gold, |
541 | &dev->core->i2c_adap); | 676 | &dev->core->i2c_adap); |
542 | if (dev->dvb.frontend != NULL) { | 677 | if (dev->dvb.frontend != NULL) { |
543 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 678 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
544 | &dev->core->i2c_adap, | 679 | &dev->core->i2c_adap, 0x61, |
545 | DVB_PLL_MICROTUNE_4042); | 680 | TUNER_MICROTUNE_4042FI5); |
546 | } | 681 | } |
547 | } | 682 | } |
548 | break; | 683 | break; |
@@ -560,9 +695,9 @@ static int dvb_register(struct cx8802_dev *dev) | |||
560 | &fusionhdtv_3_gold, | 695 | &fusionhdtv_3_gold, |
561 | &dev->core->i2c_adap); | 696 | &dev->core->i2c_adap); |
562 | if (dev->dvb.frontend != NULL) { | 697 | if (dev->dvb.frontend != NULL) { |
563 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 698 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
564 | &dev->core->i2c_adap, | 699 | &dev->core->i2c_adap, 0x61, |
565 | DVB_PLL_THOMSON_DTT761X); | 700 | TUNER_THOMSON_DTT761X); |
566 | } | 701 | } |
567 | } | 702 | } |
568 | break; | 703 | break; |
@@ -580,9 +715,11 @@ static int dvb_register(struct cx8802_dev *dev) | |||
580 | &fusionhdtv_5_gold, | 715 | &fusionhdtv_5_gold, |
581 | &dev->core->i2c_adap); | 716 | &dev->core->i2c_adap); |
582 | if (dev->dvb.frontend != NULL) { | 717 | if (dev->dvb.frontend != NULL) { |
583 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 718 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
584 | &dev->core->i2c_adap, | 719 | &dev->core->i2c_adap, 0x61, |
585 | DVB_PLL_LG_TDVS_H06XF); | 720 | TUNER_LG_TDVS_H06XF); |
721 | dvb_attach(tda9887_attach, dev->dvb.frontend, | ||
722 | &dev->core->i2c_adap, 0x43); | ||
586 | } | 723 | } |
587 | } | 724 | } |
588 | break; | 725 | break; |
@@ -600,9 +737,11 @@ static int dvb_register(struct cx8802_dev *dev) | |||
600 | &pchdtv_hd5500, | 737 | &pchdtv_hd5500, |
601 | &dev->core->i2c_adap); | 738 | &dev->core->i2c_adap); |
602 | if (dev->dvb.frontend != NULL) { | 739 | if (dev->dvb.frontend != NULL) { |
603 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 740 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
604 | &dev->core->i2c_adap, | 741 | &dev->core->i2c_adap, 0x61, |
605 | DVB_PLL_LG_TDVS_H06XF); | 742 | TUNER_LG_TDVS_H06XF); |
743 | dvb_attach(tda9887_attach, dev->dvb.frontend, | ||
744 | &dev->core->i2c_adap, 0x43); | ||
606 | } | 745 | } |
607 | } | 746 | } |
608 | break; | 747 | break; |
@@ -611,8 +750,9 @@ static int dvb_register(struct cx8802_dev *dev) | |||
611 | &ati_hdtvwonder, | 750 | &ati_hdtvwonder, |
612 | &dev->core->i2c_adap); | 751 | &dev->core->i2c_adap); |
613 | if (dev->dvb.frontend != NULL) { | 752 | if (dev->dvb.frontend != NULL) { |
614 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 753 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
615 | NULL, DVB_PLL_TUV1236D); | 754 | &dev->core->i2c_adap, 0x61, |
755 | TUNER_PHILIPS_TUV1236D); | ||
616 | } | 756 | } |
617 | break; | 757 | break; |
618 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | 758 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: |
@@ -658,14 +798,62 @@ static int dvb_register(struct cx8802_dev *dev) | |||
658 | &pinnacle_pctv_hd_800i_tuner_config); | 798 | &pinnacle_pctv_hd_800i_tuner_config); |
659 | } | 799 | } |
660 | break; | 800 | break; |
801 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: | ||
802 | dev->dvb.frontend = dvb_attach(s5h1409_attach, | ||
803 | &dvico_hdtv5_pci_nano_config, | ||
804 | &dev->core->i2c_adap); | ||
805 | if (dev->dvb.frontend != NULL) { | ||
806 | struct dvb_frontend *fe; | ||
807 | struct xc2028_config cfg = { | ||
808 | .i2c_adap = &dev->core->i2c_adap, | ||
809 | .i2c_addr = 0x61, | ||
810 | .callback = cx88_pci_nano_callback, | ||
811 | }; | ||
812 | static struct xc2028_ctrl ctl = { | ||
813 | .fname = "xc3028-v27.fw", | ||
814 | .max_len = 64, | ||
815 | .scode_table = XC3028_FE_OREN538, | ||
816 | }; | ||
817 | |||
818 | fe = dvb_attach(xc2028_attach, | ||
819 | dev->dvb.frontend, &cfg); | ||
820 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | ||
821 | fe->ops.tuner_ops.set_config(fe, &ctl); | ||
822 | } | ||
823 | break; | ||
824 | case CX88_BOARD_PINNACLE_HYBRID_PCTV: | ||
825 | dev->dvb.frontend = dvb_attach(zl10353_attach, | ||
826 | &cx88_geniatech_x8000_mt, | ||
827 | &dev->core->i2c_adap); | ||
828 | if (attach_xc3028(0x61, dev) < 0) | ||
829 | return -EINVAL; | ||
830 | break; | ||
831 | case CX88_BOARD_GENIATECH_X8000_MT: | ||
832 | dev->ts_gen_cntrl = 0x00; | ||
833 | |||
834 | dev->dvb.frontend = dvb_attach(zl10353_attach, | ||
835 | &cx88_geniatech_x8000_mt, | ||
836 | &dev->core->i2c_adap); | ||
837 | if (attach_xc3028(0x61, dev) < 0) | ||
838 | return -EINVAL; | ||
839 | break; | ||
840 | case CX88_BOARD_KWORLD_ATSC_120: | ||
841 | dev->dvb.frontend = dvb_attach(s5h1409_attach, | ||
842 | &kworld_atsc_120_config, | ||
843 | &dev->core->i2c_adap); | ||
844 | if (attach_xc3028(0x61, dev) < 0) | ||
845 | return -EINVAL; | ||
846 | break; | ||
661 | default: | 847 | default: |
662 | printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", | 848 | printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", |
663 | dev->core->name); | 849 | dev->core->name); |
664 | break; | 850 | break; |
665 | } | 851 | } |
666 | if (NULL == dev->dvb.frontend) { | 852 | if (NULL == dev->dvb.frontend) { |
667 | printk(KERN_ERR "%s/2: frontend initialization failed\n", dev->core->name); | 853 | printk(KERN_ERR |
668 | return -1; | 854 | "%s/2: frontend initialization failed\n", |
855 | dev->core->name); | ||
856 | return -EINVAL; | ||
669 | } | 857 | } |
670 | 858 | ||
671 | /* Ensure all frontends negotiate bus access */ | 859 | /* Ensure all frontends negotiate bus access */ |
@@ -675,7 +863,8 @@ static int dvb_register(struct cx8802_dev *dev) | |||
675 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | 863 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); |
676 | 864 | ||
677 | /* register everything */ | 865 | /* register everything */ |
678 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); | 866 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, |
867 | &dev->pci->dev, adapter_nr); | ||
679 | } | 868 | } |
680 | 869 | ||
681 | /* ----------------------------------------------------------- */ | 870 | /* ----------------------------------------------------------- */ |
@@ -685,7 +874,7 @@ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) | |||
685 | { | 874 | { |
686 | struct cx88_core *core = drv->core; | 875 | struct cx88_core *core = drv->core; |
687 | int err = 0; | 876 | int err = 0; |
688 | dprintk( 1, "%s\n", __FUNCTION__); | 877 | dprintk( 1, "%s\n", __func__); |
689 | 878 | ||
690 | switch (core->boardnr) { | 879 | switch (core->boardnr) { |
691 | case CX88_BOARD_HAUPPAUGE_HVR1300: | 880 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
@@ -708,7 +897,7 @@ static int cx8802_dvb_advise_release(struct cx8802_driver *drv) | |||
708 | { | 897 | { |
709 | struct cx88_core *core = drv->core; | 898 | struct cx88_core *core = drv->core; |
710 | int err = 0; | 899 | int err = 0; |
711 | dprintk( 1, "%s\n", __FUNCTION__); | 900 | dprintk( 1, "%s\n", __func__); |
712 | 901 | ||
713 | switch (core->boardnr) { | 902 | switch (core->boardnr) { |
714 | case CX88_BOARD_HAUPPAUGE_HVR1300: | 903 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
@@ -726,7 +915,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) | |||
726 | struct cx8802_dev *dev = drv->core->dvbdev; | 915 | struct cx8802_dev *dev = drv->core->dvbdev; |
727 | int err; | 916 | int err; |
728 | 917 | ||
729 | dprintk( 1, "%s\n", __FUNCTION__); | 918 | dprintk( 1, "%s\n", __func__); |
730 | dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", | 919 | dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", |
731 | core->boardnr, | 920 | core->boardnr, |
732 | core->name, | 921 | core->name, |
@@ -744,8 +933,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) | |||
744 | 933 | ||
745 | /* dvb stuff */ | 934 | /* dvb stuff */ |
746 | printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); | 935 | printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); |
747 | videobuf_queue_pci_init(&dev->dvb.dvbq, &dvb_qops, | 936 | videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops, |
748 | dev->pci, &dev->slock, | 937 | &dev->pci->dev, &dev->slock, |
749 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 938 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
750 | V4L2_FIELD_TOP, | 939 | V4L2_FIELD_TOP, |
751 | sizeof(struct cx88_buffer), | 940 | sizeof(struct cx88_buffer), |
@@ -764,7 +953,8 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv) | |||
764 | struct cx8802_dev *dev = drv->core->dvbdev; | 953 | struct cx8802_dev *dev = drv->core->dvbdev; |
765 | 954 | ||
766 | /* dvb */ | 955 | /* dvb */ |
767 | videobuf_dvb_unregister(&dev->dvb); | 956 | if (dev->dvb.frontend) |
957 | videobuf_dvb_unregister(&dev->dvb); | ||
768 | 958 | ||
769 | vp3054_i2c_remove(dev); | 959 | vp3054_i2c_remove(dev); |
770 | 960 | ||
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 566b26af523e..c6b44732a082 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -35,11 +35,11 @@ | |||
35 | #include "cx88.h" | 35 | #include "cx88.h" |
36 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
37 | 37 | ||
38 | static unsigned int i2c_debug = 0; | 38 | static unsigned int i2c_debug; |
39 | module_param(i2c_debug, int, 0644); | 39 | module_param(i2c_debug, int, 0644); |
40 | MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]"); | 40 | MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]"); |
41 | 41 | ||
42 | static unsigned int i2c_scan = 0; | 42 | static unsigned int i2c_scan; |
43 | module_param(i2c_scan, int, 0444); | 43 | module_param(i2c_scan, int, 0444); |
44 | MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); | 44 | MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); |
45 | 45 | ||
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index bb0911b4d2f6..53526d997a4e 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -57,7 +57,7 @@ struct cx88_IR { | |||
57 | u32 mask_keyup; | 57 | u32 mask_keyup; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | static int ir_debug = 0; | 60 | static int ir_debug; |
61 | module_param(ir_debug, int, 0644); /* debug level [IR] */ | 61 | module_param(ir_debug, int, 0644); /* debug level [IR] */ |
62 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | 62 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); |
63 | 63 | ||
@@ -258,6 +258,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
258 | ir->mask_keyup = 0x80; | 258 | ir->mask_keyup = 0x80; |
259 | ir->polling = 1; /* ms */ | 259 | ir->polling = 1; /* ms */ |
260 | break; | 260 | break; |
261 | case CX88_BOARD_PROLINK_PV_8000GT: | ||
262 | ir_codes = ir_codes_pixelview_new; | ||
263 | ir->gpio_addr = MO_GP1_IO; | ||
264 | ir->mask_keycode = 0x3f; | ||
265 | ir->mask_keyup = 0x80; | ||
266 | ir->polling = 1; /* ms */ | ||
267 | break; | ||
261 | case CX88_BOARD_KWORLD_LTV883: | 268 | case CX88_BOARD_KWORLD_LTV883: |
262 | ir_codes = ir_codes_pixelview; | 269 | ir_codes = ir_codes_pixelview; |
263 | ir->gpio_addr = MO_GP1_IO; | 270 | ir->gpio_addr = MO_GP1_IO; |
@@ -310,6 +317,12 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
310 | ir_type = IR_TYPE_RC5; | 317 | ir_type = IR_TYPE_RC5; |
311 | ir->sampling = 1; | 318 | ir->sampling = 1; |
312 | break; | 319 | break; |
320 | case CX88_BOARD_POWERCOLOR_REAL_ANGEL: | ||
321 | ir_codes = ir_codes_powercolor_real_angel; | ||
322 | ir->gpio_addr = MO_GP2_IO; | ||
323 | ir->mask_keycode = 0x7e; | ||
324 | ir->polling = 100; /* ms */ | ||
325 | break; | ||
313 | } | 326 | } |
314 | 327 | ||
315 | if (NULL == ir_codes) { | 328 | if (NULL == ir_codes) { |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index e357f415db06..a6b061c2644a 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -39,7 +39,7 @@ MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); | |||
39 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 39 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
40 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
41 | 41 | ||
42 | static unsigned int debug = 0; | 42 | static unsigned int debug; |
43 | module_param(debug,int,0644); | 43 | module_param(debug,int,0644); |
44 | MODULE_PARM_DESC(debug,"enable debug messages [mpeg]"); | 44 | MODULE_PARM_DESC(debug,"enable debug messages [mpeg]"); |
45 | 45 | ||
@@ -146,7 +146,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
146 | cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */ | 146 | cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */ |
147 | udelay(100); | 147 | udelay(100); |
148 | } else { | 148 | } else { |
149 | printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __FUNCTION__, | 149 | printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __func__, |
150 | core->board.mpeg ); | 150 | core->board.mpeg ); |
151 | return -EINVAL; | 151 | return -EINVAL; |
152 | } | 152 | } |
@@ -247,7 +247,7 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev, | |||
247 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | 247 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); |
248 | int rc; | 248 | int rc; |
249 | 249 | ||
250 | dprintk(1, "%s: %p\n", __FUNCTION__, buf); | 250 | dprintk(1, "%s: %p\n", __func__, buf); |
251 | if (0 != buf->vb.baddr && buf->vb.bsize < size) | 251 | if (0 != buf->vb.baddr && buf->vb.bsize < size) |
252 | return -EINVAL; | 252 | return -EINVAL; |
253 | 253 | ||
@@ -289,7 +289,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) | |||
289 | buf->count = cx88q->count++; | 289 | buf->count = cx88q->count++; |
290 | mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); | 290 | mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); |
291 | dprintk(1,"[%p/%d] %s - first active\n", | 291 | dprintk(1,"[%p/%d] %s - first active\n", |
292 | buf, buf->vb.i, __FUNCTION__); | 292 | buf, buf->vb.i, __func__); |
293 | 293 | ||
294 | } else { | 294 | } else { |
295 | dprintk( 1, "queue is not empty - append to active\n" ); | 295 | dprintk( 1, "queue is not empty - append to active\n" ); |
@@ -299,7 +299,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) | |||
299 | buf->count = cx88q->count++; | 299 | buf->count = cx88q->count++; |
300 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 300 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
301 | dprintk( 1, "[%p/%d] %s - append to active\n", | 301 | dprintk( 1, "[%p/%d] %s - append to active\n", |
302 | buf, buf->vb.i, __FUNCTION__); | 302 | buf, buf->vb.i, __func__); |
303 | } | 303 | } |
304 | } | 304 | } |
305 | 305 | ||
@@ -342,7 +342,7 @@ static void cx8802_timeout(unsigned long data) | |||
342 | { | 342 | { |
343 | struct cx8802_dev *dev = (struct cx8802_dev*)data; | 343 | struct cx8802_dev *dev = (struct cx8802_dev*)data; |
344 | 344 | ||
345 | dprintk(1, "%s\n",__FUNCTION__); | 345 | dprintk(1, "%s\n",__func__); |
346 | 346 | ||
347 | if (debug) | 347 | if (debug) |
348 | cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); | 348 | cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); |
@@ -613,6 +613,8 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) | |||
613 | core->active_type_id != drv->type_id) | 613 | core->active_type_id != drv->type_id) |
614 | return -EBUSY; | 614 | return -EBUSY; |
615 | 615 | ||
616 | core->input = CX88_VMUX_DVB; | ||
617 | |||
616 | if (drv->advise_acquire) | 618 | if (drv->advise_acquire) |
617 | { | 619 | { |
618 | mutex_lock(&drv->core->lock); | 620 | mutex_lock(&drv->core->lock); |
@@ -623,7 +625,7 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) | |||
623 | } | 625 | } |
624 | mutex_unlock(&drv->core->lock); | 626 | mutex_unlock(&drv->core->lock); |
625 | 627 | ||
626 | mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); | 628 | mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); |
627 | } | 629 | } |
628 | 630 | ||
629 | return 0; | 631 | return 0; |
@@ -639,7 +641,7 @@ static int cx8802_request_release(struct cx8802_driver *drv) | |||
639 | { | 641 | { |
640 | drv->advise_release(drv); | 642 | drv->advise_release(drv); |
641 | core->active_type_id = CX88_BOARD_NONE; | 643 | core->active_type_id = CX88_BOARD_NONE; |
642 | mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); | 644 | mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); |
643 | } | 645 | } |
644 | mutex_unlock(&drv->core->lock); | 646 | mutex_unlock(&drv->core->lock); |
645 | 647 | ||
@@ -813,7 +815,7 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev) | |||
813 | 815 | ||
814 | dev = pci_get_drvdata(pci_dev); | 816 | dev = pci_get_drvdata(pci_dev); |
815 | 817 | ||
816 | dprintk( 1, "%s\n", __FUNCTION__); | 818 | dprintk( 1, "%s\n", __func__); |
817 | 819 | ||
818 | if (!list_empty(&dev->drvlist)) { | 820 | if (!list_empty(&dev->drvlist)) { |
819 | struct cx8802_driver *drv, *tmp; | 821 | struct cx8802_driver *drv, *tmp; |
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 76e5c78d8ae4..3a1977f41e27 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c | |||
@@ -53,15 +53,15 @@ | |||
53 | 53 | ||
54 | #include "cx88.h" | 54 | #include "cx88.h" |
55 | 55 | ||
56 | static unsigned int audio_debug = 0; | 56 | static unsigned int audio_debug; |
57 | module_param(audio_debug, int, 0644); | 57 | module_param(audio_debug, int, 0644); |
58 | MODULE_PARM_DESC(audio_debug, "enable debug messages [audio]"); | 58 | MODULE_PARM_DESC(audio_debug, "enable debug messages [audio]"); |
59 | 59 | ||
60 | static unsigned int always_analog = 0; | 60 | static unsigned int always_analog; |
61 | module_param(always_analog,int,0644); | 61 | module_param(always_analog,int,0644); |
62 | MODULE_PARM_DESC(always_analog,"force analog audio out"); | 62 | MODULE_PARM_DESC(always_analog,"force analog audio out"); |
63 | 63 | ||
64 | static unsigned int radio_deemphasis = 0; | 64 | static unsigned int radio_deemphasis; |
65 | module_param(radio_deemphasis,int,0644); | 65 | module_param(radio_deemphasis,int,0644); |
66 | MODULE_PARM_DESC(radio_deemphasis, "Radio deemphasis time constant, " | 66 | MODULE_PARM_DESC(radio_deemphasis, "Radio deemphasis time constant, " |
67 | "0=None, 1=50us (elsewhere), 2=75us (USA)"); | 67 | "0=None, 1=50us (elsewhere), 2=75us (USA)"); |
@@ -265,12 +265,12 @@ static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, | |||
265 | mode |= EN_FMRADIO_EN_RDS; | 265 | mode |= EN_FMRADIO_EN_RDS; |
266 | 266 | ||
267 | if (sap) { | 267 | if (sap) { |
268 | dprintk("%s SAP (status: unknown)\n", __FUNCTION__); | 268 | dprintk("%s SAP (status: unknown)\n", __func__); |
269 | set_audio_start(core, SEL_SAP); | 269 | set_audio_start(core, SEL_SAP); |
270 | set_audio_registers(core, btsc_sap); | 270 | set_audio_registers(core, btsc_sap); |
271 | set_audio_finish(core, mode); | 271 | set_audio_finish(core, mode); |
272 | } else { | 272 | } else { |
273 | dprintk("%s (status: known-good)\n", __FUNCTION__); | 273 | dprintk("%s (status: known-good)\n", __func__); |
274 | set_audio_start(core, SEL_BTSC); | 274 | set_audio_start(core, SEL_BTSC); |
275 | set_audio_registers(core, btsc); | 275 | set_audio_registers(core, btsc); |
276 | set_audio_finish(core, mode); | 276 | set_audio_finish(core, mode); |
@@ -351,16 +351,16 @@ static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode) | |||
351 | set_audio_start(core,SEL_NICAM); | 351 | set_audio_start(core,SEL_NICAM); |
352 | switch (core->tvaudio) { | 352 | switch (core->tvaudio) { |
353 | case WW_L: | 353 | case WW_L: |
354 | dprintk("%s SECAM-L NICAM (status: devel)\n", __FUNCTION__); | 354 | dprintk("%s SECAM-L NICAM (status: devel)\n", __func__); |
355 | set_audio_registers(core, nicam_l); | 355 | set_audio_registers(core, nicam_l); |
356 | break; | 356 | break; |
357 | case WW_I: | 357 | case WW_I: |
358 | dprintk("%s PAL-I NICAM (status: known-good)\n", __FUNCTION__); | 358 | dprintk("%s PAL-I NICAM (status: known-good)\n", __func__); |
359 | set_audio_registers(core, nicam_bgdki_common); | 359 | set_audio_registers(core, nicam_bgdki_common); |
360 | set_audio_registers(core, nicam_i); | 360 | set_audio_registers(core, nicam_i); |
361 | break; | 361 | break; |
362 | default: | 362 | default: |
363 | dprintk("%s PAL-BGDK NICAM (status: known-good)\n", __FUNCTION__); | 363 | dprintk("%s PAL-BGDK NICAM (status: known-good)\n", __func__); |
364 | set_audio_registers(core, nicam_bgdki_common); | 364 | set_audio_registers(core, nicam_bgdki_common); |
365 | set_audio_registers(core, nicam_default); | 365 | set_audio_registers(core, nicam_default); |
366 | break; | 366 | break; |
@@ -600,28 +600,28 @@ static void set_audio_standard_A2(struct cx88_core *core, u32 mode) | |||
600 | set_audio_start(core, SEL_A2); | 600 | set_audio_start(core, SEL_A2); |
601 | switch (core->tvaudio) { | 601 | switch (core->tvaudio) { |
602 | case WW_BG: | 602 | case WW_BG: |
603 | dprintk("%s PAL-BG A1/2 (status: known-good)\n", __FUNCTION__); | 603 | dprintk("%s PAL-BG A1/2 (status: known-good)\n", __func__); |
604 | set_audio_registers(core, a2_bgdk_common); | 604 | set_audio_registers(core, a2_bgdk_common); |
605 | set_audio_registers(core, a2_bg); | 605 | set_audio_registers(core, a2_bg); |
606 | set_audio_registers(core, a2_deemph50); | 606 | set_audio_registers(core, a2_deemph50); |
607 | break; | 607 | break; |
608 | case WW_DK: | 608 | case WW_DK: |
609 | dprintk("%s PAL-DK A1/2 (status: known-good)\n", __FUNCTION__); | 609 | dprintk("%s PAL-DK A1/2 (status: known-good)\n", __func__); |
610 | set_audio_registers(core, a2_bgdk_common); | 610 | set_audio_registers(core, a2_bgdk_common); |
611 | set_audio_registers(core, a2_dk); | 611 | set_audio_registers(core, a2_dk); |
612 | set_audio_registers(core, a2_deemph50); | 612 | set_audio_registers(core, a2_deemph50); |
613 | break; | 613 | break; |
614 | case WW_I: | 614 | case WW_I: |
615 | dprintk("%s PAL-I A1 (status: known-good)\n", __FUNCTION__); | 615 | dprintk("%s PAL-I A1 (status: known-good)\n", __func__); |
616 | set_audio_registers(core, a1_i); | 616 | set_audio_registers(core, a1_i); |
617 | set_audio_registers(core, a2_deemph50); | 617 | set_audio_registers(core, a2_deemph50); |
618 | break; | 618 | break; |
619 | case WW_L: | 619 | case WW_L: |
620 | dprintk("%s AM-L (status: devel)\n", __FUNCTION__); | 620 | dprintk("%s AM-L (status: devel)\n", __func__); |
621 | set_audio_registers(core, am_l); | 621 | set_audio_registers(core, am_l); |
622 | break; | 622 | break; |
623 | default: | 623 | default: |
624 | dprintk("%s Warning: wrong value\n", __FUNCTION__); | 624 | dprintk("%s Warning: wrong value\n", __func__); |
625 | return; | 625 | return; |
626 | break; | 626 | break; |
627 | }; | 627 | }; |
@@ -637,7 +637,7 @@ static void set_audio_standard_EIAJ(struct cx88_core *core) | |||
637 | 637 | ||
638 | { /* end of list */ }, | 638 | { /* end of list */ }, |
639 | }; | 639 | }; |
640 | dprintk("%s (status: unknown)\n", __FUNCTION__); | 640 | dprintk("%s (status: unknown)\n", __func__); |
641 | 641 | ||
642 | set_audio_start(core, SEL_EIAJ); | 642 | set_audio_start(core, SEL_EIAJ); |
643 | set_audio_registers(core, eiaj); | 643 | set_audio_registers(core, eiaj); |
@@ -691,7 +691,7 @@ static void set_audio_standard_FM(struct cx88_core *core, | |||
691 | { /* end of list */ }, | 691 | { /* end of list */ }, |
692 | }; | 692 | }; |
693 | 693 | ||
694 | dprintk("%s (status: unknown)\n", __FUNCTION__); | 694 | dprintk("%s (status: unknown)\n", __func__); |
695 | set_audio_start(core, SEL_FMRADIO); | 695 | set_audio_start(core, SEL_FMRADIO); |
696 | 696 | ||
697 | switch (deemph) { | 697 | switch (deemph) { |
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c index d96ecfcf393a..0943060682bc 100644 --- a/drivers/media/video/cx88/cx88-vbi.c +++ b/drivers/media/video/cx88/cx88-vbi.c | |||
@@ -11,7 +11,7 @@ static unsigned int vbibufs = 4; | |||
11 | module_param(vbibufs,int,0644); | 11 | module_param(vbibufs,int,0644); |
12 | MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32"); | 12 | MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32"); |
13 | 13 | ||
14 | static unsigned int vbi_debug = 0; | 14 | static unsigned int vbi_debug; |
15 | module_param(vbi_debug,int,0644); | 15 | module_param(vbi_debug,int,0644); |
16 | MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); | 16 | MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); |
17 | 17 | ||
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 227179620d13..eea23f95edb7 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -63,11 +63,11 @@ MODULE_PARM_DESC(video_nr,"video device numbers"); | |||
63 | MODULE_PARM_DESC(vbi_nr,"vbi device numbers"); | 63 | MODULE_PARM_DESC(vbi_nr,"vbi device numbers"); |
64 | MODULE_PARM_DESC(radio_nr,"radio device numbers"); | 64 | MODULE_PARM_DESC(radio_nr,"radio device numbers"); |
65 | 65 | ||
66 | static unsigned int video_debug = 0; | 66 | static unsigned int video_debug; |
67 | module_param(video_debug,int,0644); | 67 | module_param(video_debug,int,0644); |
68 | MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); | 68 | MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); |
69 | 69 | ||
70 | static unsigned int irq_debug = 0; | 70 | static unsigned int irq_debug; |
71 | module_param(irq_debug,int,0644); | 71 | module_param(irq_debug,int,0644); |
72 | MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]"); | 72 | MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]"); |
73 | 73 | ||
@@ -228,6 +228,30 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
228 | .mask = 0x00ff, | 228 | .mask = 0x00ff, |
229 | .shift = 0, | 229 | .shift = 0, |
230 | },{ | 230 | },{ |
231 | .v = { | ||
232 | .id = V4L2_CID_CHROMA_AGC, | ||
233 | .name = "Chroma AGC", | ||
234 | .minimum = 0, | ||
235 | .maximum = 1, | ||
236 | .default_value = 0x1, | ||
237 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
238 | }, | ||
239 | .reg = MO_INPUT_FORMAT, | ||
240 | .mask = 1 << 10, | ||
241 | .shift = 10, | ||
242 | }, { | ||
243 | .v = { | ||
244 | .id = V4L2_CID_COLOR_KILLER, | ||
245 | .name = "Color killer", | ||
246 | .minimum = 0, | ||
247 | .maximum = 1, | ||
248 | .default_value = 0x1, | ||
249 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
250 | }, | ||
251 | .reg = MO_INPUT_FORMAT, | ||
252 | .mask = 1 << 9, | ||
253 | .shift = 9, | ||
254 | }, { | ||
231 | /* --- audio --- */ | 255 | /* --- audio --- */ |
232 | .v = { | 256 | .v = { |
233 | .id = V4L2_CID_AUDIO_MUTE, | 257 | .id = V4L2_CID_AUDIO_MUTE, |
@@ -282,6 +306,8 @@ const u32 cx88_user_ctrls[] = { | |||
282 | V4L2_CID_AUDIO_VOLUME, | 306 | V4L2_CID_AUDIO_VOLUME, |
283 | V4L2_CID_AUDIO_BALANCE, | 307 | V4L2_CID_AUDIO_BALANCE, |
284 | V4L2_CID_AUDIO_MUTE, | 308 | V4L2_CID_AUDIO_MUTE, |
309 | V4L2_CID_CHROMA_AGC, | ||
310 | V4L2_CID_COLOR_KILLER, | ||
285 | 0 | 311 | 0 |
286 | }; | 312 | }; |
287 | EXPORT_SYMBOL(cx88_user_ctrls); | 313 | EXPORT_SYMBOL(cx88_user_ctrls); |
@@ -291,7 +317,7 @@ static const u32 *ctrl_classes[] = { | |||
291 | NULL | 317 | NULL |
292 | }; | 318 | }; |
293 | 319 | ||
294 | int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl) | 320 | int cx8800_ctrl_query(struct cx88_core *core, struct v4l2_queryctrl *qctrl) |
295 | { | 321 | { |
296 | int i; | 322 | int i; |
297 | 323 | ||
@@ -306,6 +332,11 @@ int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl) | |||
306 | return 0; | 332 | return 0; |
307 | } | 333 | } |
308 | *qctrl = cx8800_ctls[i].v; | 334 | *qctrl = cx8800_ctls[i].v; |
335 | /* Report chroma AGC as inactive when SECAM is selected */ | ||
336 | if (cx8800_ctls[i].v.id == V4L2_CID_CHROMA_AGC && | ||
337 | core->tvnorm & V4L2_STD_SECAM) | ||
338 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
339 | |||
309 | return 0; | 340 | return 0; |
310 | } | 341 | } |
311 | EXPORT_SYMBOL(cx8800_ctrl_query); | 342 | EXPORT_SYMBOL(cx8800_ctrl_query); |
@@ -776,14 +807,14 @@ static int video_open(struct inode *inode, struct file *file) | |||
776 | fh->height = 240; | 807 | fh->height = 240; |
777 | fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); | 808 | fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); |
778 | 809 | ||
779 | videobuf_queue_pci_init(&fh->vidq, &cx8800_video_qops, | 810 | videobuf_queue_sg_init(&fh->vidq, &cx8800_video_qops, |
780 | dev->pci, &dev->slock, | 811 | &dev->pci->dev, &dev->slock, |
781 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 812 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
782 | V4L2_FIELD_INTERLACED, | 813 | V4L2_FIELD_INTERLACED, |
783 | sizeof(struct cx88_buffer), | 814 | sizeof(struct cx88_buffer), |
784 | fh); | 815 | fh); |
785 | videobuf_queue_pci_init(&fh->vbiq, &cx8800_vbi_qops, | 816 | videobuf_queue_sg_init(&fh->vbiq, &cx8800_vbi_qops, |
786 | dev->pci, &dev->slock, | 817 | &dev->pci->dev, &dev->slock, |
787 | V4L2_BUF_TYPE_VBI_CAPTURE, | 818 | V4L2_BUF_TYPE_VBI_CAPTURE, |
788 | V4L2_FIELD_SEQ_TB, | 819 | V4L2_FIELD_SEQ_TB, |
789 | sizeof(struct cx88_buffer), | 820 | sizeof(struct cx88_buffer), |
@@ -976,6 +1007,12 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
976 | } | 1007 | } |
977 | mask=0xffff; | 1008 | mask=0xffff; |
978 | break; | 1009 | break; |
1010 | case V4L2_CID_CHROMA_AGC: | ||
1011 | /* Do not allow chroma AGC to be enabled for SECAM */ | ||
1012 | value = ((ctl->value - c->off) << c->shift) & c->mask; | ||
1013 | if (core->tvnorm & V4L2_STD_SECAM && value) | ||
1014 | return -EINVAL; | ||
1015 | break; | ||
979 | default: | 1016 | default: |
980 | value = ((ctl->value - c->off) << c->shift) & c->mask; | 1017 | value = ((ctl->value - c->off) << c->shift) & c->mask; |
981 | break; | 1018 | break; |
@@ -1268,10 +1305,12 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i) | |||
1268 | static int vidioc_queryctrl (struct file *file, void *priv, | 1305 | static int vidioc_queryctrl (struct file *file, void *priv, |
1269 | struct v4l2_queryctrl *qctrl) | 1306 | struct v4l2_queryctrl *qctrl) |
1270 | { | 1307 | { |
1308 | struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; | ||
1309 | |||
1271 | qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); | 1310 | qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); |
1272 | if (unlikely(qctrl->id == 0)) | 1311 | if (unlikely(qctrl->id == 0)) |
1273 | return -EINVAL; | 1312 | return -EINVAL; |
1274 | return cx8800_ctrl_query(qctrl); | 1313 | return cx8800_ctrl_query(core, qctrl); |
1275 | } | 1314 | } |
1276 | 1315 | ||
1277 | static int vidioc_g_ctrl (struct file *file, void *priv, | 1316 | static int vidioc_g_ctrl (struct file *file, void *priv, |
@@ -1832,8 +1871,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1832 | 1871 | ||
1833 | switch (core->boardnr) { | 1872 | switch (core->boardnr) { |
1834 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: | 1873 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: |
1835 | request_module("ir-kbd-i2c"); | 1874 | case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: |
1836 | request_module("rtc-isl1208"); | 1875 | request_module("rtc-isl1208"); |
1876 | /* break intentionally omitted */ | ||
1877 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: | ||
1878 | request_module("ir-kbd-i2c"); | ||
1837 | } | 1879 | } |
1838 | 1880 | ||
1839 | /* register v4l devices */ | 1881 | /* register v4l devices */ |
@@ -1917,6 +1959,9 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev) | |||
1917 | core->kthread = NULL; | 1959 | core->kthread = NULL; |
1918 | } | 1960 | } |
1919 | 1961 | ||
1962 | if (core->ir) | ||
1963 | cx88_ir_stop(core, core->ir); | ||
1964 | |||
1920 | cx88_shutdown(core); /* FIXME */ | 1965 | cx88_shutdown(core); /* FIXME */ |
1921 | pci_disable_device(pci_dev); | 1966 | pci_disable_device(pci_dev); |
1922 | 1967 | ||
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 37e6d2e4002f..14ac173f4071 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #include "btcx-risc.h" | 38 | #include "btcx-risc.h" |
39 | #include "cx88-reg.h" | 39 | #include "cx88-reg.h" |
40 | #include "tuner-xc2028.h" | ||
40 | 41 | ||
41 | #include <linux/version.h> | 42 | #include <linux/version.h> |
42 | #include <linux/mutex.h> | 43 | #include <linux/mutex.h> |
@@ -211,6 +212,15 @@ extern struct sram_channel cx88_sram_channels[]; | |||
211 | #define CX88_BOARD_HAUPPAUGE_HVR1300 56 | 212 | #define CX88_BOARD_HAUPPAUGE_HVR1300 56 |
212 | #define CX88_BOARD_ADSTECH_PTV_390 57 | 213 | #define CX88_BOARD_ADSTECH_PTV_390 57 |
213 | #define CX88_BOARD_PINNACLE_PCTV_HD_800i 58 | 214 | #define CX88_BOARD_PINNACLE_PCTV_HD_800i 58 |
215 | #define CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO 59 | ||
216 | #define CX88_BOARD_PINNACLE_HYBRID_PCTV 60 | ||
217 | #define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL 61 | ||
218 | #define CX88_BOARD_POWERCOLOR_REAL_ANGEL 62 | ||
219 | #define CX88_BOARD_GENIATECH_X8000_MT 63 | ||
220 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO 64 | ||
221 | #define CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD 65 | ||
222 | #define CX88_BOARD_PROLINK_PV_8000GT 66 | ||
223 | #define CX88_BOARD_KWORLD_ATSC_120 67 | ||
214 | 224 | ||
215 | enum cx88_itype { | 225 | enum cx88_itype { |
216 | CX88_VMUX_COMPOSITE1 = 1, | 226 | CX88_VMUX_COMPOSITE1 = 1, |
@@ -595,6 +605,7 @@ extern int cx88_tuner_callback(void *dev, int command, int arg); | |||
595 | extern int cx88_get_resources(const struct cx88_core *core, | 605 | extern int cx88_get_resources(const struct cx88_core *core, |
596 | struct pci_dev *pci); | 606 | struct pci_dev *pci); |
597 | extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); | 607 | extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); |
608 | extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl); | ||
598 | 609 | ||
599 | /* ----------------------------------------------------------- */ | 610 | /* ----------------------------------------------------------- */ |
600 | /* cx88-tvaudio.c */ | 611 | /* cx88-tvaudio.c */ |
@@ -640,7 +651,8 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev); | |||
640 | /* ----------------------------------------------------------- */ | 651 | /* ----------------------------------------------------------- */ |
641 | /* cx88-video.c*/ | 652 | /* cx88-video.c*/ |
642 | extern const u32 cx88_user_ctrls[]; | 653 | extern const u32 cx88_user_ctrls[]; |
643 | extern int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl); | 654 | extern int cx8800_ctrl_query(struct cx88_core *core, |
655 | struct v4l2_queryctrl *qctrl); | ||
644 | int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i); | 656 | int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i); |
645 | int cx88_set_freq (struct cx88_core *core,struct v4l2_frequency *f); | 657 | int cx88_set_freq (struct cx88_core *core,struct v4l2_frequency *f); |
646 | int cx88_get_control(struct cx88_core *core, struct v4l2_control *ctl); | 658 | int cx88_get_control(struct cx88_core *core, struct v4l2_control *ctl); |
diff --git a/drivers/media/video/dabfirmware.h b/drivers/media/video/dabfirmware.h index d14d803566a3..cbd92635993d 100644 --- a/drivers/media/video/dabfirmware.h +++ b/drivers/media/video/dabfirmware.h | |||
@@ -1,5 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * dabdata.h - dab usb firmware and bitstream data | 2 | * dabdata.h - dab usb firmware and bitstream data |
3 | * | ||
4 | * Copyright (C) 1999 BayCom GmbH | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that redistributions of source | ||
8 | * code retain the above copyright notice and this comment without | ||
9 | * modification. | ||
3 | */ | 10 | */ |
4 | 11 | ||
5 | static INTEL_HEX_RECORD firmware[] = { | 12 | static INTEL_HEX_RECORD firmware[] = { |
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c index a5731f90be0f..8d1f8ee2a533 100644 --- a/drivers/media/video/dabusb.c +++ b/drivers/media/video/dabusb.c | |||
@@ -205,7 +205,7 @@ static void dabusb_iso_complete (struct urb *purb) | |||
205 | /*-------------------------------------------------------------------*/ | 205 | /*-------------------------------------------------------------------*/ |
206 | static int dabusb_alloc_buffers (pdabusb_t s) | 206 | static int dabusb_alloc_buffers (pdabusb_t s) |
207 | { | 207 | { |
208 | int buffers = 0; | 208 | int transfer_len = 0; |
209 | pbuff_t b; | 209 | pbuff_t b; |
210 | unsigned int pipe = usb_rcvisocpipe (s->usbdev, _DABUSB_ISOPIPE); | 210 | unsigned int pipe = usb_rcvisocpipe (s->usbdev, _DABUSB_ISOPIPE); |
211 | int pipesize = usb_maxpacket (s->usbdev, pipe, usb_pipeout (pipe)); | 211 | int pipesize = usb_maxpacket (s->usbdev, pipe, usb_pipeout (pipe)); |
@@ -216,7 +216,7 @@ static int dabusb_alloc_buffers (pdabusb_t s) | |||
216 | dbg("dabusb_alloc_buffers pipesize:%d packets:%d transfer_buffer_len:%d", | 216 | dbg("dabusb_alloc_buffers pipesize:%d packets:%d transfer_buffer_len:%d", |
217 | pipesize, packets, transfer_buffer_length); | 217 | pipesize, packets, transfer_buffer_length); |
218 | 218 | ||
219 | while (buffers < (s->total_buffer_size << 10)) { | 219 | while (transfer_len < (s->total_buffer_size << 10)) { |
220 | b = kzalloc(sizeof (buff_t), GFP_KERNEL); | 220 | b = kzalloc(sizeof (buff_t), GFP_KERNEL); |
221 | if (!b) { | 221 | if (!b) { |
222 | err("kzalloc(sizeof(buff_t))==NULL"); | 222 | err("kzalloc(sizeof(buff_t))==NULL"); |
@@ -251,10 +251,10 @@ static int dabusb_alloc_buffers (pdabusb_t s) | |||
251 | b->purb->iso_frame_desc[i].length = pipesize; | 251 | b->purb->iso_frame_desc[i].length = pipesize; |
252 | } | 252 | } |
253 | 253 | ||
254 | buffers += transfer_buffer_length; | 254 | transfer_len += transfer_buffer_length; |
255 | list_add_tail (&b->buff_list, &s->free_buff_list); | 255 | list_add_tail (&b->buff_list, &s->free_buff_list); |
256 | } | 256 | } |
257 | s->got_mem = buffers; | 257 | s->got_mem = transfer_len; |
258 | 258 | ||
259 | return 0; | 259 | return 0; |
260 | 260 | ||
diff --git a/drivers/media/video/dpc7146.c b/drivers/media/video/dpc7146.c index 9ceb6b2f3949..88d6df71d051 100644 --- a/drivers/media/video/dpc7146.c +++ b/drivers/media/video/dpc7146.c | |||
@@ -54,11 +54,11 @@ | |||
54 | 54 | ||
55 | #define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) | 55 | #define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) |
56 | 56 | ||
57 | static int debug = 0; | 57 | static int debug; |
58 | module_param(debug, int, 0); | 58 | module_param(debug, int, 0); |
59 | MODULE_PARM_DESC(debug, "debug verbosity"); | 59 | MODULE_PARM_DESC(debug, "debug verbosity"); |
60 | 60 | ||
61 | static int dpc_num = 0; | 61 | static int dpc_num; |
62 | 62 | ||
63 | #define DPC_INPUTS 2 | 63 | #define DPC_INPUTS 2 |
64 | static struct v4l2_input dpc_inputs[DPC_INPUTS] = { | 64 | static struct v4l2_input dpc_inputs[DPC_INPUTS] = { |
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig index 0f7a0bd86ff4..9caffed2b6b8 100644 --- a/drivers/media/video/em28xx/Kconfig +++ b/drivers/media/video/em28xx/Kconfig | |||
@@ -1,11 +1,13 @@ | |||
1 | config VIDEO_EM28XX | 1 | config VIDEO_EM28XX |
2 | tristate "Empia EM2800/2820/2840 USB video capture support" | 2 | tristate "Empia EM28xx USB video capture support" |
3 | depends on VIDEO_DEV && I2C && INPUT | 3 | depends on VIDEO_DEV && I2C && INPUT |
4 | select VIDEO_TUNER | 4 | select VIDEO_TUNER |
5 | select VIDEO_TVEEPROM | 5 | select VIDEO_TVEEPROM |
6 | select VIDEO_IR | 6 | select VIDEO_IR |
7 | select VIDEOBUF_VMALLOC | ||
7 | select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO | 8 | select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO |
8 | select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO | 9 | select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO |
10 | select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO | ||
9 | ---help--- | 11 | ---help--- |
10 | This is a video4linux driver for Empia 28xx based TV cards. | 12 | This is a video4linux driver for Empia 28xx based TV cards. |
11 | 13 | ||
@@ -27,3 +29,13 @@ config VIDEO_EM28XX_ALSA | |||
27 | To compile this driver as a module, choose M here: the | 29 | To compile this driver as a module, choose M here: the |
28 | module will be called em28xx-alsa | 30 | module will be called em28xx-alsa |
29 | 31 | ||
32 | config VIDEO_EM28XX_DVB | ||
33 | tristate "DVB/ATSC Support for em28xx based TV cards" | ||
34 | depends on VIDEO_EM28XX && DVB_CORE | ||
35 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | ||
36 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | ||
37 | select VIDEOBUF_DVB | ||
38 | select FW_LOADER | ||
39 | ---help--- | ||
40 | This adds support for DVB cards based on the | ||
41 | Empiatech em28xx chips. | ||
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile index 0924550992d0..3d1c3cc337fe 100644 --- a/drivers/media/video/em28xx/Makefile +++ b/drivers/media/video/em28xx/Makefile | |||
@@ -5,6 +5,7 @@ em28xx-alsa-objs := em28xx-audio.o | |||
5 | 5 | ||
6 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o | 6 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o |
7 | obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o | 7 | obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o |
8 | obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o | ||
8 | 9 | ||
9 | EXTRA_CFLAGS += -Idrivers/media/video | 10 | EXTRA_CFLAGS += -Idrivers/media/video |
10 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 11 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 8c67f678266a..92b2a6db4fdc 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c | |||
@@ -51,7 +51,7 @@ MODULE_PARM_DESC(debug, "activates debug info"); | |||
51 | #define dprintk(fmt, arg...) do { \ | 51 | #define dprintk(fmt, arg...) do { \ |
52 | if (debug) \ | 52 | if (debug) \ |
53 | printk(KERN_INFO "em28xx-audio %s: " fmt, \ | 53 | printk(KERN_INFO "em28xx-audio %s: " fmt, \ |
54 | __FUNCTION__, ##arg); \ | 54 | __func__, ##arg); \ |
55 | } while (0) | 55 | } while (0) |
56 | 56 | ||
57 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | 57 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index aae7753fef11..50ccf3771204 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
37 | 37 | ||
38 | #include "em28xx.h" | 38 | #include "em28xx.h" |
39 | #include "tuner-xc2028.h" | ||
40 | 39 | ||
41 | static int tuner = -1; | 40 | static int tuner = -1; |
42 | module_param(tuner, int, 0444); | 41 | module_param(tuner, int, 0444); |
@@ -52,26 +51,6 @@ struct em28xx_hash_table { | |||
52 | unsigned int tuner; | 51 | unsigned int tuner; |
53 | }; | 52 | }; |
54 | 53 | ||
55 | /* Boards supported by driver */ | ||
56 | |||
57 | #define EM2800_BOARD_UNKNOWN 0 | ||
58 | #define EM2820_BOARD_UNKNOWN 1 | ||
59 | #define EM2820_BOARD_TERRATEC_CINERGY_250 2 | ||
60 | #define EM2820_BOARD_PINNACLE_USB_2 3 | ||
61 | #define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4 | ||
62 | #define EM2820_BOARD_MSI_VOX_USB_2 5 | ||
63 | #define EM2800_BOARD_TERRATEC_CINERGY_200 6 | ||
64 | #define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 | ||
65 | #define EM2800_BOARD_KWORLD_USB2800 8 | ||
66 | #define EM2820_BOARD_PINNACLE_DVC_90 9 | ||
67 | #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 10 | ||
68 | #define EM2880_BOARD_TERRATEC_HYBRID_XS 11 | ||
69 | #define EM2820_BOARD_KWORLD_PVRTV2800RF 12 | ||
70 | #define EM2880_BOARD_TERRATEC_PRODIGY_XS 13 | ||
71 | #define EM2820_BOARD_PROLINK_PLAYTV_USB2 14 | ||
72 | #define EM2800_BOARD_VGEAR_POCKETTV 15 | ||
73 | #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16 | ||
74 | |||
75 | struct em28xx_board em28xx_boards[] = { | 54 | struct em28xx_board em28xx_boards[] = { |
76 | [EM2800_BOARD_UNKNOWN] = { | 55 | [EM2800_BOARD_UNKNOWN] = { |
77 | .name = "Unknown EM2800 video grabber", | 56 | .name = "Unknown EM2800 video grabber", |
@@ -200,6 +179,7 @@ struct em28xx_board em28xx_boards[] = { | |||
200 | .tuner_type = TUNER_XC2028, | 179 | .tuner_type = TUNER_XC2028, |
201 | .mts_firmware = 1, | 180 | .mts_firmware = 1, |
202 | .has_12mhz_i2s = 1, | 181 | .has_12mhz_i2s = 1, |
182 | .has_dvb = 1, | ||
203 | .decoder = EM28XX_TVP5150, | 183 | .decoder = EM28XX_TVP5150, |
204 | .input = { { | 184 | .input = { { |
205 | .type = EM28XX_VMUX_TELEVISION, | 185 | .type = EM28XX_VMUX_TELEVISION, |
@@ -214,9 +194,6 @@ struct em28xx_board em28xx_boards[] = { | |||
214 | .vmux = TVP5150_SVIDEO, | 194 | .vmux = TVP5150_SVIDEO, |
215 | .amux = 1, | 195 | .amux = 1, |
216 | } }, | 196 | } }, |
217 | |||
218 | /* gpio's 4, 1, 0 */ | ||
219 | .analog_gpio = 0x003d2d, | ||
220 | }, | 197 | }, |
221 | [EM2880_BOARD_TERRATEC_HYBRID_XS] = { | 198 | [EM2880_BOARD_TERRATEC_HYBRID_XS] = { |
222 | .name = "Terratec Hybrid XS", | 199 | .name = "Terratec Hybrid XS", |
@@ -331,7 +308,7 @@ struct em28xx_board em28xx_boards[] = { | |||
331 | .name = "Kworld USB2800", | 308 | .name = "Kworld USB2800", |
332 | .is_em2800 = 1, | 309 | .is_em2800 = 1, |
333 | .vchannels = 3, | 310 | .vchannels = 3, |
334 | .tuner_type = TUNER_PHILIPS_ATSC, | 311 | .tuner_type = TUNER_PHILIPS_FCV1236D, |
335 | .tda9887_conf = TDA9887_PRESENT, | 312 | .tda9887_conf = TDA9887_PRESENT, |
336 | .decoder = EM28XX_SAA7113, | 313 | .decoder = EM28XX_SAA7113, |
337 | .input = { { | 314 | .input = { { |
@@ -453,7 +430,36 @@ struct usb_device_id em28xx_id_table [] = { | |||
453 | }; | 430 | }; |
454 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); | 431 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); |
455 | 432 | ||
456 | /* EEPROM hash table for devices with generic USB IDs */ | 433 | /* |
434 | * Reset sequences for analog/digital modes | ||
435 | */ | ||
436 | |||
437 | /* Board Hauppauge WinTV HVR 900 analog */ | ||
438 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { | ||
439 | {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10}, | ||
440 | {0x05, 0xff, 0x10, 10}, | ||
441 | { -1, -1, -1, -1}, | ||
442 | }; | ||
443 | |||
444 | /* Board Hauppauge WinTV HVR 900 digital */ | ||
445 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { | ||
446 | {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10}, | ||
447 | {EM2880_R04_GPO, 0x04, 0x0f, 10}, | ||
448 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, | ||
449 | { -1, -1, -1, -1}, | ||
450 | }; | ||
451 | |||
452 | /* Board Hauppauge WinTV HVR 900 tuner_callback */ | ||
453 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = { | ||
454 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
455 | {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10}, | ||
456 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
457 | { -1, -1, -1, -1}, | ||
458 | }; | ||
459 | |||
460 | /* | ||
461 | * EEPROM hash table for devices with generic USB IDs | ||
462 | */ | ||
457 | static struct em28xx_hash_table em28xx_eeprom_hash [] = { | 463 | static struct em28xx_hash_table em28xx_eeprom_hash [] = { |
458 | /* P/N: SA 60002070465 Tuner: TVF7533-MF */ | 464 | /* P/N: SA 60002070465 Tuner: TVF7533-MF */ |
459 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, | 465 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, |
@@ -465,79 +471,113 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = { | |||
465 | {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, | 471 | {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, |
466 | }; | 472 | }; |
467 | 473 | ||
474 | int em28xx_tuner_callback(void *ptr, int command, int arg) | ||
475 | { | ||
476 | int rc = 0; | ||
477 | struct em28xx *dev = ptr; | ||
478 | |||
479 | if (dev->tuner_type != TUNER_XC2028) | ||
480 | return 0; | ||
481 | |||
482 | if (command != XC2028_TUNER_RESET) | ||
483 | return 0; | ||
484 | |||
485 | if (dev->mode == EM28XX_ANALOG_MODE) | ||
486 | rc = em28xx_gpio_set(dev, dev->tun_analog_gpio); | ||
487 | else | ||
488 | rc = em28xx_gpio_set(dev, dev->tun_digital_gpio); | ||
489 | |||
490 | return rc; | ||
491 | } | ||
492 | EXPORT_SYMBOL_GPL(em28xx_tuner_callback); | ||
493 | |||
494 | static void em28xx_set_model(struct em28xx *dev) | ||
495 | { | ||
496 | dev->is_em2800 = em28xx_boards[dev->model].is_em2800; | ||
497 | dev->has_msp34xx = em28xx_boards[dev->model].has_msp34xx; | ||
498 | dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; | ||
499 | dev->decoder = em28xx_boards[dev->model].decoder; | ||
500 | dev->video_inputs = em28xx_boards[dev->model].vchannels; | ||
501 | dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; | ||
502 | dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; | ||
503 | dev->has_dvb = em28xx_boards[dev->model].has_dvb; | ||
504 | } | ||
505 | |||
468 | /* Since em28xx_pre_card_setup() requires a proper dev->model, | 506 | /* Since em28xx_pre_card_setup() requires a proper dev->model, |
469 | * this won't work for boards with generic PCI IDs | 507 | * this won't work for boards with generic PCI IDs |
470 | */ | 508 | */ |
471 | void em28xx_pre_card_setup(struct em28xx *dev) | 509 | void em28xx_pre_card_setup(struct em28xx *dev) |
472 | { | 510 | { |
511 | int rc; | ||
512 | |||
513 | rc = em28xx_read_reg(dev, EM2880_R04_GPO); | ||
514 | if (rc >= 0) | ||
515 | dev->reg_gpo = rc; | ||
516 | |||
517 | dev->wait_after_write = 5; | ||
518 | rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); | ||
519 | if (rc > 0) { | ||
520 | switch (rc) { | ||
521 | case CHIP_ID_EM2883: | ||
522 | em28xx_info("chip ID is em2882/em2883\n"); | ||
523 | dev->wait_after_write = 0; | ||
524 | break; | ||
525 | default: | ||
526 | em28xx_info("em28xx chip ID = %d\n", rc); | ||
527 | } | ||
528 | } | ||
529 | em28xx_set_model(dev); | ||
530 | |||
473 | /* request some modules */ | 531 | /* request some modules */ |
474 | switch (dev->model) { | 532 | switch (dev->model) { |
475 | case EM2880_BOARD_TERRATEC_PRODIGY_XS: | 533 | case EM2880_BOARD_TERRATEC_PRODIGY_XS: |
476 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | 534 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: |
477 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: | ||
478 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | 535 | case EM2880_BOARD_TERRATEC_HYBRID_XS: |
479 | em28xx_write_regs(dev, XCLK_REG, "\x27", 1); | 536 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: |
480 | em28xx_write_regs(dev, I2C_CLK_REG, "\x40", 1); | 537 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); |
481 | em28xx_write_regs(dev, 0x08, "\xff", 1); | 538 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); |
482 | em28xx_write_regs(dev, 0x04, "\x00", 1); | ||
483 | msleep(100); | ||
484 | em28xx_write_regs(dev, 0x04, "\x08", 1); | ||
485 | msleep(100); | ||
486 | em28xx_write_regs(dev, 0x08, "\xff", 1); | ||
487 | msleep(50); | ||
488 | em28xx_write_regs(dev, 0x08, "\x2d", 1); | ||
489 | msleep(50); | 539 | msleep(50); |
490 | em28xx_write_regs(dev, 0x08, "\x3d", 1); | 540 | |
541 | /* Sets GPO/GPIO sequences for this device */ | ||
542 | dev->analog_gpio = hauppauge_wintv_hvr_900_analog; | ||
543 | dev->digital_gpio = hauppauge_wintv_hvr_900_digital; | ||
544 | dev->tun_analog_gpio = hauppauge_wintv_hvr_900_tuner_callback; | ||
545 | dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback; | ||
546 | |||
491 | break; | 547 | break; |
492 | } | 548 | } |
549 | |||
550 | em28xx_gpio_set(dev, dev->tun_analog_gpio); | ||
551 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | ||
552 | |||
553 | /* Unlock device */ | ||
554 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | ||
493 | } | 555 | } |
494 | 556 | ||
495 | static int em28xx_tuner_callback(void *ptr, int command, int arg) | 557 | static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) |
496 | { | 558 | { |
497 | int rc = 0; | 559 | memset(ctl, 0, sizeof(*ctl)); |
498 | struct em28xx *dev = ptr; | ||
499 | 560 | ||
500 | if (dev->tuner_type != TUNER_XC2028) | 561 | ctl->fname = XC2028_DEFAULT_FIRMWARE; |
501 | return 0; | 562 | ctl->max_len = 64; |
502 | 563 | ctl->mts = em28xx_boards[dev->model].mts_firmware; | |
503 | switch (command) { | ||
504 | case XC2028_TUNER_RESET: | ||
505 | { | ||
506 | /* GPIO and initialization codes for analog TV and radio | ||
507 | This code should be complemented for DTV, since reset | ||
508 | codes are different. | ||
509 | */ | ||
510 | |||
511 | dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); | ||
512 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1); | ||
513 | |||
514 | if (dev->analog_gpio) { | ||
515 | char gpio0 = dev->analog_gpio & 0xff; | ||
516 | char gpio1 = (dev->analog_gpio >> 8) & 0xff; | ||
517 | char gpio4 = dev->analog_gpio >> 24; | ||
518 | |||
519 | if (gpio4) { | ||
520 | dev->em28xx_write_regs(dev, 0x04, &gpio4, 1); | ||
521 | msleep(140); | ||
522 | } | ||
523 | |||
524 | msleep(6); | ||
525 | dev->em28xx_write_regs(dev, 0x08, &gpio0, 1); | ||
526 | msleep(10); | ||
527 | dev->em28xx_write_regs(dev, 0x08, &gpio1, 1); | ||
528 | msleep(5); | ||
529 | } | ||
530 | 564 | ||
565 | switch (dev->model) { | ||
566 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
567 | ctl->demod = XC3028_FE_ZARLINK456; | ||
531 | break; | 568 | break; |
569 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: | ||
570 | /* FIXME: Better to specify the needed IF */ | ||
571 | ctl->demod = XC3028_FE_DEFAULT; | ||
572 | break; | ||
573 | default: | ||
574 | ctl->demod = XC3028_FE_OREN538; | ||
532 | } | 575 | } |
533 | } | ||
534 | return rc; | ||
535 | } | 576 | } |
536 | 577 | ||
537 | static void em28xx_config_tuner(struct em28xx *dev) | 578 | static void em28xx_config_tuner(struct em28xx *dev) |
538 | { | 579 | { |
539 | struct v4l2_priv_tun_config xc2028_cfg; | 580 | struct v4l2_priv_tun_config xc2028_cfg; |
540 | struct xc2028_ctrl ctl; | ||
541 | struct tuner_setup tun_setup; | 581 | struct tuner_setup tun_setup; |
542 | struct v4l2_frequency f; | 582 | struct v4l2_frequency f; |
543 | 583 | ||
@@ -552,11 +592,9 @@ static void em28xx_config_tuner(struct em28xx *dev) | |||
552 | em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); | 592 | em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); |
553 | 593 | ||
554 | if (dev->tuner_type == TUNER_XC2028) { | 594 | if (dev->tuner_type == TUNER_XC2028) { |
555 | memset(&ctl, 0, sizeof(ctl)); | 595 | struct xc2028_ctrl ctl; |
556 | 596 | ||
557 | ctl.fname = XC2028_DEFAULT_FIRMWARE; | 597 | em28xx_setup_xc3028(dev, &ctl); |
558 | ctl.max_len = 64; | ||
559 | ctl.mts = em28xx_boards[dev->model].mts_firmware; | ||
560 | 598 | ||
561 | xc2028_cfg.tuner = TUNER_XC2028; | 599 | xc2028_cfg.tuner = TUNER_XC2028; |
562 | xc2028_cfg.priv = &ctl; | 600 | xc2028_cfg.priv = &ctl; |
@@ -654,19 +692,6 @@ static int em28xx_hint_board(struct em28xx *dev) | |||
654 | return -1; | 692 | return -1; |
655 | } | 693 | } |
656 | 694 | ||
657 | |||
658 | static void em28xx_set_model(struct em28xx *dev) | ||
659 | { | ||
660 | dev->is_em2800 = em28xx_boards[dev->model].is_em2800; | ||
661 | dev->has_msp34xx = em28xx_boards[dev->model].has_msp34xx; | ||
662 | dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; | ||
663 | dev->decoder = em28xx_boards[dev->model].decoder; | ||
664 | dev->video_inputs = em28xx_boards[dev->model].vchannels; | ||
665 | dev->analog_gpio = em28xx_boards[dev->model].analog_gpio; | ||
666 | dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; | ||
667 | dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; | ||
668 | } | ||
669 | |||
670 | /* ----------------------------------------------------------------------- */ | 695 | /* ----------------------------------------------------------------------- */ |
671 | void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) | 696 | void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) |
672 | { | 697 | { |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index c1caaa855b99..f8c41d8c74c4 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -31,104 +31,33 @@ | |||
31 | 31 | ||
32 | /* #define ENABLE_DEBUG_ISOC_FRAMES */ | 32 | /* #define ENABLE_DEBUG_ISOC_FRAMES */ |
33 | 33 | ||
34 | static unsigned int core_debug = 0; | 34 | static unsigned int core_debug; |
35 | module_param(core_debug,int,0644); | 35 | module_param(core_debug,int,0644); |
36 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); | 36 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); |
37 | 37 | ||
38 | #define em28xx_coredbg(fmt, arg...) do {\ | 38 | #define em28xx_coredbg(fmt, arg...) do {\ |
39 | if (core_debug) \ | 39 | if (core_debug) \ |
40 | printk(KERN_INFO "%s %s :"fmt, \ | 40 | printk(KERN_INFO "%s %s :"fmt, \ |
41 | dev->name, __FUNCTION__ , ##arg); } while (0) | 41 | dev->name, __func__ , ##arg); } while (0) |
42 | 42 | ||
43 | static unsigned int reg_debug = 0; | 43 | static unsigned int reg_debug; |
44 | module_param(reg_debug,int,0644); | 44 | module_param(reg_debug,int,0644); |
45 | MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); | 45 | MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); |
46 | 46 | ||
47 | #define em28xx_regdbg(fmt, arg...) do {\ | 47 | #define em28xx_regdbg(fmt, arg...) do {\ |
48 | if (reg_debug) \ | 48 | if (reg_debug) \ |
49 | printk(KERN_INFO "%s %s :"fmt, \ | 49 | printk(KERN_INFO "%s %s :"fmt, \ |
50 | dev->name, __FUNCTION__ , ##arg); } while (0) | 50 | dev->name, __func__ , ##arg); } while (0) |
51 | |||
52 | static unsigned int isoc_debug = 0; | ||
53 | module_param(isoc_debug,int,0644); | ||
54 | MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]"); | ||
55 | |||
56 | #define em28xx_isocdbg(fmt, arg...) do {\ | ||
57 | if (isoc_debug) \ | ||
58 | printk(KERN_INFO "%s %s :"fmt, \ | ||
59 | dev->name, __FUNCTION__ , ##arg); } while (0) | ||
60 | 51 | ||
61 | static int alt = EM28XX_PINOUT; | 52 | static int alt = EM28XX_PINOUT; |
62 | module_param(alt, int, 0644); | 53 | module_param(alt, int, 0644); |
63 | MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); | 54 | MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); |
64 | 55 | ||
65 | 56 | /* FIXME */ | |
66 | /* | 57 | #define em28xx_isocdbg(fmt, arg...) do {\ |
67 | * em28xx_request_buffers() | 58 | if (core_debug) \ |
68 | * allocate a number of buffers | 59 | printk(KERN_INFO "%s %s :"fmt, \ |
69 | */ | 60 | dev->name, __func__ , ##arg); } while (0) |
70 | u32 em28xx_request_buffers(struct em28xx *dev, u32 count) | ||
71 | { | ||
72 | const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ | ||
73 | void *buff = NULL; | ||
74 | u32 i; | ||
75 | em28xx_coredbg("requested %i buffers with size %zi\n", | ||
76 | count, imagesize); | ||
77 | if (count > EM28XX_NUM_FRAMES) | ||
78 | count = EM28XX_NUM_FRAMES; | ||
79 | |||
80 | dev->num_frames = count; | ||
81 | while (dev->num_frames > 0) { | ||
82 | if ((buff = vmalloc_32(dev->num_frames * imagesize))) { | ||
83 | memset(buff, 0, dev->num_frames * imagesize); | ||
84 | break; | ||
85 | } | ||
86 | dev->num_frames--; | ||
87 | } | ||
88 | |||
89 | for (i = 0; i < dev->num_frames; i++) { | ||
90 | dev->frame[i].bufmem = buff + i * imagesize; | ||
91 | dev->frame[i].buf.index = i; | ||
92 | dev->frame[i].buf.m.offset = i * imagesize; | ||
93 | dev->frame[i].buf.length = dev->frame_size; | ||
94 | dev->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
95 | dev->frame[i].buf.sequence = 0; | ||
96 | dev->frame[i].buf.field = V4L2_FIELD_NONE; | ||
97 | dev->frame[i].buf.memory = V4L2_MEMORY_MMAP; | ||
98 | dev->frame[i].buf.flags = 0; | ||
99 | } | ||
100 | return dev->num_frames; | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * em28xx_queue_unusedframes() | ||
105 | * add all frames that are not currently in use to the inbuffer queue | ||
106 | */ | ||
107 | void em28xx_queue_unusedframes(struct em28xx *dev) | ||
108 | { | ||
109 | unsigned long lock_flags; | ||
110 | u32 i; | ||
111 | |||
112 | for (i = 0; i < dev->num_frames; i++) | ||
113 | if (dev->frame[i].state == F_UNUSED) { | ||
114 | dev->frame[i].state = F_QUEUED; | ||
115 | spin_lock_irqsave(&dev->queue_lock, lock_flags); | ||
116 | list_add_tail(&dev->frame[i].frame, &dev->inqueue); | ||
117 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * em28xx_release_buffers() | ||
123 | * free frame buffers | ||
124 | */ | ||
125 | void em28xx_release_buffers(struct em28xx *dev) | ||
126 | { | ||
127 | if (dev->num_frames) { | ||
128 | vfree(dev->frame[0].bufmem); | ||
129 | dev->num_frames = 0; | ||
130 | } | ||
131 | } | ||
132 | 61 | ||
133 | /* | 62 | /* |
134 | * em28xx_read_reg_req() | 63 | * em28xx_read_reg_req() |
@@ -148,11 +77,11 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | |||
148 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 77 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
149 | 0x0000, reg, buf, len, HZ); | 78 | 0x0000, reg, buf, len, HZ); |
150 | 79 | ||
151 | if (reg_debug){ | 80 | if (reg_debug) { |
152 | printk(ret < 0 ? " failed!\n" : "%02x values: ", ret); | 81 | printk(ret < 0 ? " failed!\n" : "%02x values: ", ret); |
153 | for (byte = 0; byte < len; byte++) { | 82 | for (byte = 0; byte < len; byte++) |
154 | printk(" %02x", (unsigned char)buf[byte]); | 83 | printk(" %02x", (unsigned char)buf[byte]); |
155 | } | 84 | |
156 | printk("\n"); | 85 | printk("\n"); |
157 | } | 86 | } |
158 | 87 | ||
@@ -205,7 +134,10 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
205 | unsigned char *bufs; | 134 | unsigned char *bufs; |
206 | 135 | ||
207 | if (dev->state & DEV_DISCONNECTED) | 136 | if (dev->state & DEV_DISCONNECTED) |
208 | return(-ENODEV); | 137 | return -ENODEV; |
138 | |||
139 | if (len < 1) | ||
140 | return -EINVAL; | ||
209 | 141 | ||
210 | bufs = kmalloc(len, GFP_KERNEL); | 142 | bufs = kmalloc(len, GFP_KERNEL); |
211 | 143 | ||
@@ -214,8 +146,8 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
214 | if (reg_debug) { | 146 | if (reg_debug) { |
215 | int i; | 147 | int i; |
216 | for (i = 0; i < len; ++i) | 148 | for (i = 0; i < len; ++i) |
217 | printk (" %02x", (unsigned char)buf[i]); | 149 | printk(" %02x", (unsigned char)buf[i]); |
218 | printk ("\n"); | 150 | printk("\n"); |
219 | } | 151 | } |
220 | 152 | ||
221 | if (!bufs) | 153 | if (!bufs) |
@@ -224,14 +156,32 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
224 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, | 156 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, |
225 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 157 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
226 | 0x0000, reg, bufs, len, HZ); | 158 | 0x0000, reg, bufs, len, HZ); |
227 | msleep(5); /* FIXME: magic number */ | 159 | if (dev->wait_after_write) |
160 | msleep(dev->wait_after_write); | ||
161 | |||
228 | kfree(bufs); | 162 | kfree(bufs); |
229 | return ret; | 163 | return ret; |
230 | } | 164 | } |
231 | 165 | ||
232 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) | 166 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) |
233 | { | 167 | { |
234 | return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len); | 168 | int rc; |
169 | |||
170 | rc = em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len); | ||
171 | |||
172 | /* Stores GPO/GPIO values at the cache, if changed | ||
173 | Only write values should be stored, since input on a GPIO | ||
174 | register will return the input bits. | ||
175 | Not sure what happens on reading GPO register. | ||
176 | */ | ||
177 | if (rc >= 0) { | ||
178 | if (reg == EM2880_R04_GPO) | ||
179 | dev->reg_gpo = buf[0]; | ||
180 | else if (reg == EM28XX_R08_GPIO) | ||
181 | dev->reg_gpio = buf[0]; | ||
182 | } | ||
183 | |||
184 | return rc; | ||
235 | } | 185 | } |
236 | 186 | ||
237 | /* | 187 | /* |
@@ -244,9 +194,20 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, | |||
244 | { | 194 | { |
245 | int oldval; | 195 | int oldval; |
246 | u8 newval; | 196 | u8 newval; |
247 | if ((oldval = em28xx_read_reg(dev, reg)) < 0) | 197 | |
198 | /* Uses cache for gpo/gpio registers */ | ||
199 | if (reg == EM2880_R04_GPO) | ||
200 | oldval = dev->reg_gpo; | ||
201 | else if (reg == EM28XX_R08_GPIO) | ||
202 | oldval = dev->reg_gpio; | ||
203 | else | ||
204 | oldval = em28xx_read_reg(dev, reg); | ||
205 | |||
206 | if (oldval < 0) | ||
248 | return oldval; | 207 | return oldval; |
208 | |||
249 | newval = (((u8) oldval) & ~bitmask) | (val & bitmask); | 209 | newval = (((u8) oldval) & ~bitmask) | (val & bitmask); |
210 | |||
250 | return em28xx_write_regs(dev, reg, &newval, 1); | 211 | return em28xx_write_regs(dev, reg, &newval, 1); |
251 | } | 212 | } |
252 | 213 | ||
@@ -258,20 +219,26 @@ static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val) | |||
258 | { | 219 | { |
259 | int ret, i; | 220 | int ret, i; |
260 | u8 addr = reg & 0x7f; | 221 | u8 addr = reg & 0x7f; |
261 | if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0) | 222 | |
223 | ret = em28xx_write_regs(dev, EM28XX_R40_AC97LSB, val, 2); | ||
224 | if (ret < 0) | ||
262 | return ret; | 225 | return ret; |
263 | if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0) | 226 | |
227 | ret = em28xx_write_regs(dev, EM28XX_R42_AC97ADDR, &addr, 1); | ||
228 | if (ret < 0) | ||
264 | return ret; | 229 | return ret; |
265 | 230 | ||
266 | /* Wait up to 50 ms for AC97 command to complete */ | 231 | /* Wait up to 50 ms for AC97 command to complete */ |
267 | for (i = 0; i < 10; i++) { | 232 | for (i = 0; i < 10; i++) { |
268 | if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) | 233 | ret = em28xx_read_reg(dev, EM28XX_R43_AC97BUSY); |
234 | if (ret < 0) | ||
269 | return ret; | 235 | return ret; |
236 | |||
270 | if (!(ret & 0x01)) | 237 | if (!(ret & 0x01)) |
271 | return 0; | 238 | return 0; |
272 | msleep(5); | 239 | msleep(5); |
273 | } | 240 | } |
274 | em28xx_warn ("AC97 command still being executed: not handled properly!\n"); | 241 | em28xx_warn("AC97 command still being executed: not handled properly!\n"); |
275 | return 0; | 242 | return 0; |
276 | } | 243 | } |
277 | 244 | ||
@@ -289,7 +256,7 @@ static int em28xx_set_audio_source(struct em28xx *dev) | |||
289 | else | 256 | else |
290 | input = EM2800_AUDIO_SRC_TUNER; | 257 | input = EM2800_AUDIO_SRC_TUNER; |
291 | 258 | ||
292 | ret = em28xx_write_regs(dev, EM2800_AUDIOSRC_REG, &input, 1); | 259 | ret = em28xx_write_regs(dev, EM2800_R08_AUDIOSRC, &input, 1); |
293 | if (ret < 0) | 260 | if (ret < 0) |
294 | return ret; | 261 | return ret; |
295 | } | 262 | } |
@@ -315,7 +282,7 @@ static int em28xx_set_audio_source(struct em28xx *dev) | |||
315 | } | 282 | } |
316 | } | 283 | } |
317 | 284 | ||
318 | ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0); | 285 | ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0); |
319 | if (ret < 0) | 286 | if (ret < 0) |
320 | return ret; | 287 | return ret; |
321 | msleep(5); | 288 | msleep(5); |
@@ -323,11 +290,11 @@ static int em28xx_set_audio_source(struct em28xx *dev) | |||
323 | /* Sets AC97 mixer registers | 290 | /* Sets AC97 mixer registers |
324 | This is seems to be needed, even for non-ac97 configs | 291 | This is seems to be needed, even for non-ac97 configs |
325 | */ | 292 | */ |
326 | ret = em28xx_write_ac97(dev, VIDEO_AC97, video); | 293 | ret = em28xx_write_ac97(dev, EM28XX_R14_VIDEO_AC97, video); |
327 | if (ret < 0) | 294 | if (ret < 0) |
328 | return ret; | 295 | return ret; |
329 | 296 | ||
330 | ret = em28xx_write_ac97(dev, LINE_IN_AC97, line); | 297 | ret = em28xx_write_ac97(dev, EM28XX_R10_LINE_IN_AC97, line); |
331 | 298 | ||
332 | return ret; | 299 | return ret; |
333 | } | 300 | } |
@@ -343,7 +310,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) | |||
343 | 310 | ||
344 | /* Mute */ | 311 | /* Mute */ |
345 | s[1] |= 0x80; | 312 | s[1] |= 0x80; |
346 | ret = em28xx_write_ac97(dev, MASTER_AC97, s); | 313 | ret = em28xx_write_ac97(dev, EM28XX_R02_MASTER_AC97, s); |
347 | 314 | ||
348 | if (ret < 0) | 315 | if (ret < 0) |
349 | return ret; | 316 | return ret; |
@@ -354,7 +321,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) | |||
354 | if (!dev->mute) | 321 | if (!dev->mute) |
355 | xclk |= 0x80; | 322 | xclk |= 0x80; |
356 | 323 | ||
357 | ret = em28xx_write_reg_bits(dev, XCLK_REG, xclk, 0xa7); | 324 | ret = em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, xclk, 0xa7); |
358 | if (ret < 0) | 325 | if (ret < 0) |
359 | return ret; | 326 | return ret; |
360 | msleep(10); | 327 | msleep(10); |
@@ -365,7 +332,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) | |||
365 | /* Unmute device */ | 332 | /* Unmute device */ |
366 | if (!dev->mute) | 333 | if (!dev->mute) |
367 | s[1] &= ~0x80; | 334 | s[1] &= ~0x80; |
368 | ret = em28xx_write_ac97(dev, MASTER_AC97, s); | 335 | ret = em28xx_write_ac97(dev, EM28XX_R02_MASTER_AC97, s); |
369 | 336 | ||
370 | return ret; | 337 | return ret; |
371 | } | 338 | } |
@@ -373,50 +340,68 @@ EXPORT_SYMBOL_GPL(em28xx_audio_analog_set); | |||
373 | 340 | ||
374 | int em28xx_colorlevels_set_default(struct em28xx *dev) | 341 | int em28xx_colorlevels_set_default(struct em28xx *dev) |
375 | { | 342 | { |
376 | em28xx_write_regs(dev, YGAIN_REG, "\x10", 1); /* contrast */ | 343 | em28xx_write_regs(dev, EM28XX_R20_YGAIN, "\x10", 1); /* contrast */ |
377 | em28xx_write_regs(dev, YOFFSET_REG, "\x00", 1); /* brightness */ | 344 | em28xx_write_regs(dev, EM28XX_R21_YOFFSET, "\x00", 1); /* brightness */ |
378 | em28xx_write_regs(dev, UVGAIN_REG, "\x10", 1); /* saturation */ | 345 | em28xx_write_regs(dev, EM28XX_R22_UVGAIN, "\x10", 1); /* saturation */ |
379 | em28xx_write_regs(dev, UOFFSET_REG, "\x00", 1); | 346 | em28xx_write_regs(dev, EM28XX_R23_UOFFSET, "\x00", 1); |
380 | em28xx_write_regs(dev, VOFFSET_REG, "\x00", 1); | 347 | em28xx_write_regs(dev, EM28XX_R24_VOFFSET, "\x00", 1); |
381 | em28xx_write_regs(dev, SHARPNESS_REG, "\x00", 1); | 348 | em28xx_write_regs(dev, EM28XX_R25_SHARPNESS, "\x00", 1); |
382 | 349 | ||
383 | em28xx_write_regs(dev, GAMMA_REG, "\x20", 1); | 350 | em28xx_write_regs(dev, EM28XX_R14_GAMMA, "\x20", 1); |
384 | em28xx_write_regs(dev, RGAIN_REG, "\x20", 1); | 351 | em28xx_write_regs(dev, EM28XX_R15_RGAIN, "\x20", 1); |
385 | em28xx_write_regs(dev, GGAIN_REG, "\x20", 1); | 352 | em28xx_write_regs(dev, EM28XX_R16_GGAIN, "\x20", 1); |
386 | em28xx_write_regs(dev, BGAIN_REG, "\x20", 1); | 353 | em28xx_write_regs(dev, EM28XX_R17_BGAIN, "\x20", 1); |
387 | em28xx_write_regs(dev, ROFFSET_REG, "\x00", 1); | 354 | em28xx_write_regs(dev, EM28XX_R18_ROFFSET, "\x00", 1); |
388 | em28xx_write_regs(dev, GOFFSET_REG, "\x00", 1); | 355 | em28xx_write_regs(dev, EM28XX_R19_GOFFSET, "\x00", 1); |
389 | return em28xx_write_regs(dev, BOFFSET_REG, "\x00", 1); | 356 | return em28xx_write_regs(dev, EM28XX_R1A_BOFFSET, "\x00", 1); |
390 | } | 357 | } |
391 | 358 | ||
392 | int em28xx_capture_start(struct em28xx *dev, int start) | 359 | int em28xx_capture_start(struct em28xx *dev, int start) |
393 | { | 360 | { |
394 | int ret; | 361 | int rc; |
395 | /* FIXME: which is the best order? */ | 362 | /* FIXME: which is the best order? */ |
396 | /* video registers are sampled by VREF */ | 363 | /* video registers are sampled by VREF */ |
397 | if ((ret = em28xx_write_reg_bits(dev, USBSUSP_REG, start ? 0x10 : 0x00, | 364 | rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP, |
398 | 0x10)) < 0) | 365 | start ? 0x10 : 0x00, 0x10); |
399 | return ret; | 366 | if (rc < 0) |
367 | return rc; | ||
368 | |||
369 | if (!start) { | ||
370 | /* disable video capture */ | ||
371 | rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x27", 1); | ||
372 | return rc; | ||
373 | } | ||
374 | |||
400 | /* enable video capture */ | 375 | /* enable video capture */ |
401 | return em28xx_write_regs(dev, VINENABLE_REG, start ? "\x67" : "\x27", 1); | 376 | rc = em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); |
377 | |||
378 | if (dev->mode == EM28XX_ANALOG_MODE) | ||
379 | rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x67", 1); | ||
380 | else | ||
381 | rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x37", 1); | ||
382 | |||
383 | msleep(6); | ||
384 | |||
385 | return rc; | ||
402 | } | 386 | } |
403 | 387 | ||
404 | int em28xx_outfmt_set_yuv422(struct em28xx *dev) | 388 | int em28xx_outfmt_set_yuv422(struct em28xx *dev) |
405 | { | 389 | { |
406 | em28xx_write_regs(dev, OUTFMT_REG, "\x34", 1); | 390 | em28xx_write_regs(dev, EM28XX_R27_OUTFMT, "\x34", 1); |
407 | em28xx_write_regs(dev, VINMODE_REG, "\x10", 1); | 391 | em28xx_write_regs(dev, EM28XX_R10_VINMODE, "\x10", 1); |
408 | return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1); | 392 | return em28xx_write_regs(dev, EM28XX_R11_VINCTRL, "\x11", 1); |
409 | } | 393 | } |
410 | 394 | ||
411 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, | 395 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, |
412 | u8 ymin, u8 ymax) | 396 | u8 ymin, u8 ymax) |
413 | { | 397 | { |
414 | em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax); | 398 | em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", |
399 | xmin, ymin, xmax, ymax); | ||
415 | 400 | ||
416 | em28xx_write_regs(dev, XMIN_REG, &xmin, 1); | 401 | em28xx_write_regs(dev, EM28XX_R28_XMIN, &xmin, 1); |
417 | em28xx_write_regs(dev, XMAX_REG, &xmax, 1); | 402 | em28xx_write_regs(dev, EM28XX_R29_XMAX, &xmax, 1); |
418 | em28xx_write_regs(dev, YMIN_REG, &ymin, 1); | 403 | em28xx_write_regs(dev, EM28XX_R2A_YMIN, &ymin, 1); |
419 | return em28xx_write_regs(dev, YMAX_REG, &ymax, 1); | 404 | return em28xx_write_regs(dev, EM28XX_R2B_YMAX, &ymax, 1); |
420 | } | 405 | } |
421 | 406 | ||
422 | static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, | 407 | static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, |
@@ -426,34 +411,36 @@ static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, | |||
426 | u8 cheight = height; | 411 | u8 cheight = height; |
427 | u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01); | 412 | u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01); |
428 | 413 | ||
429 | em28xx_coredbg("em28xx Area Set: (%d,%d)\n", (width | (overflow & 2) << 7), | 414 | em28xx_coredbg("em28xx Area Set: (%d,%d)\n", |
415 | (width | (overflow & 2) << 7), | ||
430 | (height | (overflow & 1) << 8)); | 416 | (height | (overflow & 1) << 8)); |
431 | 417 | ||
432 | em28xx_write_regs(dev, HSTART_REG, &hstart, 1); | 418 | em28xx_write_regs(dev, EM28XX_R1C_HSTART, &hstart, 1); |
433 | em28xx_write_regs(dev, VSTART_REG, &vstart, 1); | 419 | em28xx_write_regs(dev, EM28XX_R1D_VSTART, &vstart, 1); |
434 | em28xx_write_regs(dev, CWIDTH_REG, &cwidth, 1); | 420 | em28xx_write_regs(dev, EM28XX_R1E_CWIDTH, &cwidth, 1); |
435 | em28xx_write_regs(dev, CHEIGHT_REG, &cheight, 1); | 421 | em28xx_write_regs(dev, EM28XX_R1F_CHEIGHT, &cheight, 1); |
436 | return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1); | 422 | return em28xx_write_regs(dev, EM28XX_R1B_OFLOW, &overflow, 1); |
437 | } | 423 | } |
438 | 424 | ||
439 | static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | 425 | static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) |
440 | { | 426 | { |
441 | u8 mode; | 427 | u8 mode; |
442 | /* the em2800 scaler only supports scaling down to 50% */ | 428 | /* the em2800 scaler only supports scaling down to 50% */ |
443 | if(dev->is_em2800) | 429 | if (dev->is_em2800) |
444 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); | 430 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); |
445 | else { | 431 | else { |
446 | u8 buf[2]; | 432 | u8 buf[2]; |
447 | buf[0] = h; | 433 | buf[0] = h; |
448 | buf[1] = h >> 8; | 434 | buf[1] = h >> 8; |
449 | em28xx_write_regs(dev, HSCALELOW_REG, (char *)buf, 2); | 435 | em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2); |
450 | buf[0] = v; | 436 | buf[0] = v; |
451 | buf[1] = v >> 8; | 437 | buf[1] = v >> 8; |
452 | em28xx_write_regs(dev, VSCALELOW_REG, (char *)buf, 2); | 438 | em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2); |
453 | /* it seems that both H and V scalers must be active to work correctly */ | 439 | /* it seems that both H and V scalers must be active |
440 | to work correctly */ | ||
454 | mode = (h || v)? 0x30: 0x00; | 441 | mode = (h || v)? 0x30: 0x00; |
455 | } | 442 | } |
456 | return em28xx_write_reg_bits(dev, COMPR_REG, mode, 0x30); | 443 | return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30); |
457 | } | 444 | } |
458 | 445 | ||
459 | /* FIXME: this only function read values from dev */ | 446 | /* FIXME: this only function read values from dev */ |
@@ -469,376 +456,271 @@ int em28xx_resolution_set(struct em28xx *dev) | |||
469 | return em28xx_scaler_set(dev, dev->hscale, dev->vscale); | 456 | return em28xx_scaler_set(dev, dev->hscale, dev->vscale); |
470 | } | 457 | } |
471 | 458 | ||
472 | 459 | int em28xx_set_alternate(struct em28xx *dev) | |
473 | /******************* isoc transfer handling ****************************/ | ||
474 | |||
475 | #ifdef ENABLE_DEBUG_ISOC_FRAMES | ||
476 | static void em28xx_isoc_dump(struct urb *urb) | ||
477 | { | 460 | { |
478 | int len = 0; | 461 | int errCode, prev_alt = dev->alt; |
479 | int ntrans = 0; | ||
480 | int i; | 462 | int i; |
463 | unsigned int min_pkt_size = dev->width * 2 + 4; | ||
481 | 464 | ||
482 | printk(KERN_DEBUG "isocIrq: sf=%d np=%d ec=%x\n", | 465 | /* When image size is bigger than a certain value, |
483 | urb->start_frame, urb->number_of_packets, | 466 | the frame size should be increased, otherwise, only |
484 | urb->error_count); | 467 | green screen will be received. |
485 | for (i = 0; i < urb->number_of_packets; i++) { | 468 | */ |
486 | unsigned char *buf = | 469 | if (dev->width * 2 * dev->height > 720 * 240 * 2) |
487 | urb->transfer_buffer + | 470 | min_pkt_size *= 2; |
488 | urb->iso_frame_desc[i].offset; | 471 | |
489 | int alen = urb->iso_frame_desc[i].actual_length; | 472 | for (i = 0; i < dev->num_alt; i++) { |
490 | if (alen > 0) { | 473 | /* stop when the selected alt setting offers enough bandwidth */ |
491 | if (buf[0] == 0x88) { | 474 | if (dev->alt_max_pkt_size[i] >= min_pkt_size) { |
492 | ntrans++; | 475 | dev->alt = i; |
493 | len += alen; | 476 | break; |
494 | } else if (buf[0] == 0x22) { | 477 | /* otherwise make sure that we end up with the maximum bandwidth |
495 | printk(KERN_DEBUG | 478 | because the min_pkt_size equation might be wrong... |
496 | "= l=%d nt=%d bpp=%d\n", | 479 | */ |
497 | len - 4 * ntrans, ntrans, | 480 | } else if (dev->alt_max_pkt_size[i] > |
498 | ntrans == 0 ? 0 : len / ntrans); | 481 | dev->alt_max_pkt_size[dev->alt]) |
499 | ntrans = 1; | 482 | dev->alt = i; |
500 | len = alen; | 483 | } |
501 | } else | 484 | |
502 | printk(KERN_DEBUG "!\n"); | 485 | if (dev->alt != prev_alt) { |
486 | em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", | ||
487 | min_pkt_size, dev->alt); | ||
488 | dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; | ||
489 | em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", | ||
490 | dev->alt, dev->max_pkt_size); | ||
491 | errCode = usb_set_interface(dev->udev, 0, dev->alt); | ||
492 | if (errCode < 0) { | ||
493 | em28xx_errdev("cannot change alternate number to %d (error=%i)\n", | ||
494 | dev->alt, errCode); | ||
495 | return errCode; | ||
503 | } | 496 | } |
504 | printk(KERN_DEBUG " n=%d s=%d al=%d %x\n", i, | ||
505 | urb->iso_frame_desc[i].status, | ||
506 | urb->iso_frame_desc[i].actual_length, | ||
507 | (unsigned int) | ||
508 | *((unsigned char *)(urb->transfer_buffer + | ||
509 | urb->iso_frame_desc[i]. | ||
510 | offset))); | ||
511 | } | 497 | } |
498 | return 0; | ||
512 | } | 499 | } |
513 | #endif | ||
514 | 500 | ||
515 | static inline int em28xx_isoc_video(struct em28xx *dev,struct em28xx_frame_t **f, | 501 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio) |
516 | unsigned long *lock_flags, unsigned char buf) | ||
517 | { | 502 | { |
518 | if (!(buf & 0x01)) { | 503 | int rc = 0; |
519 | if ((*f)->state == F_GRABBING) { | 504 | |
520 | /*previous frame is incomplete */ | 505 | if (!gpio) |
521 | if ((*f)->fieldbytesused < dev->field_size) { | 506 | return rc; |
522 | (*f)->state = F_ERROR; | 507 | |
523 | em28xx_isocdbg ("dropping incomplete bottom field (%i missing bytes)", | 508 | dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); |
524 | dev->field_size-(*f)->fieldbytesused); | 509 | if (dev->mode == EM28XX_ANALOG_MODE) |
525 | } else { | 510 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1); |
526 | (*f)->state = F_DONE; | 511 | else |
527 | (*f)->buf.bytesused = dev->frame_size; | 512 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1); |
528 | } | 513 | msleep(6); |
529 | } | 514 | |
530 | if ((*f)->state == F_DONE || (*f)->state == F_ERROR) { | 515 | /* Send GPIO reset sequences specified at board entry */ |
531 | /* move current frame to outqueue and get next free buffer from inqueue */ | 516 | while (gpio->sleep >= 0) { |
532 | spin_lock_irqsave(&dev-> queue_lock, *lock_flags); | 517 | if (gpio->reg >= 0) { |
533 | list_move_tail(&(*f)->frame, &dev->outqueue); | 518 | rc = em28xx_write_reg_bits(dev, |
534 | if (!list_empty(&dev->inqueue)) | 519 | gpio->reg, |
535 | (*f) = list_entry(dev-> inqueue.next, | 520 | gpio->val, |
536 | struct em28xx_frame_t,frame); | 521 | gpio->mask); |
537 | else | 522 | if (rc < 0) |
538 | (*f) = NULL; | 523 | return rc; |
539 | spin_unlock_irqrestore(&dev->queue_lock,*lock_flags); | ||
540 | } | ||
541 | if (!(*f)) { | ||
542 | em28xx_isocdbg ("new frame but no buffer is free"); | ||
543 | return -1; | ||
544 | } | ||
545 | do_gettimeofday(&(*f)->buf.timestamp); | ||
546 | (*f)->buf.sequence = ++dev->frame_count; | ||
547 | (*f)->buf.field = V4L2_FIELD_INTERLACED; | ||
548 | (*f)->state = F_GRABBING; | ||
549 | (*f)->buf.bytesused = 0; | ||
550 | (*f)->top_field = 1; | ||
551 | (*f)->fieldbytesused = 0; | ||
552 | } else { | ||
553 | /* acquiring bottom field */ | ||
554 | if ((*f)->state == F_GRABBING) { | ||
555 | if (!(*f)->top_field) { | ||
556 | (*f)->state = F_ERROR; | ||
557 | em28xx_isocdbg ("unexpected begin of bottom field; discarding it"); | ||
558 | } else if ((*f)-> fieldbytesused < dev->field_size - 172) { | ||
559 | (*f)->state = F_ERROR; | ||
560 | em28xx_isocdbg ("dropping incomplete top field (%i missing bytes)", | ||
561 | dev->field_size-(*f)->fieldbytesused); | ||
562 | } else { | ||
563 | (*f)->top_field = 0; | ||
564 | (*f)->fieldbytesused = 0; | ||
565 | } | ||
566 | } | 524 | } |
525 | if (gpio->sleep > 0) | ||
526 | msleep(gpio->sleep); | ||
527 | |||
528 | gpio++; | ||
567 | } | 529 | } |
568 | return (0); | 530 | return rc; |
569 | } | 531 | } |
570 | 532 | ||
571 | static inline void em28xx_isoc_video_copy(struct em28xx *dev, | 533 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode) |
572 | struct em28xx_frame_t **f, unsigned char *buf, int len) | ||
573 | { | 534 | { |
574 | void *fieldstart, *startwrite, *startread; | 535 | if (dev->mode == set_mode) |
575 | int linesdone, currlinedone, offset, lencopy,remain; | 536 | return 0; |
576 | 537 | ||
577 | if(dev->frame_size != (*f)->buf.length){ | 538 | if (set_mode == EM28XX_MODE_UNDEFINED) { |
578 | em28xx_err("frame_size %i and buf.length %i are different!!!\n",dev->frame_size,(*f)->buf.length); | 539 | dev->mode = set_mode; |
579 | return; | 540 | return 0; |
580 | } | 541 | } |
581 | 542 | ||
582 | if ((*f)->fieldbytesused + len > dev->field_size) | 543 | dev->mode = set_mode; |
583 | len =dev->field_size - (*f)->fieldbytesused; | ||
584 | |||
585 | if (buf[0] != 0x88 && buf[0] != 0x22) { | ||
586 | em28xx_isocdbg("frame is not complete\n"); | ||
587 | startread = buf; | ||
588 | len+=4; | ||
589 | } else | ||
590 | startread = buf + 4; | ||
591 | |||
592 | remain = len; | ||
593 | 544 | ||
594 | if ((*f)->top_field) | 545 | if (dev->mode == EM28XX_DIGITAL_MODE) |
595 | fieldstart = (*f)->bufmem; | 546 | return em28xx_gpio_set(dev, dev->digital_gpio); |
596 | else | 547 | else |
597 | fieldstart = (*f)->bufmem + dev->bytesperline; | 548 | return em28xx_gpio_set(dev, dev->analog_gpio); |
598 | |||
599 | linesdone = (*f)->fieldbytesused / dev->bytesperline; | ||
600 | currlinedone = (*f)->fieldbytesused % dev->bytesperline; | ||
601 | offset = linesdone * dev->bytesperline * 2 + currlinedone; | ||
602 | startwrite = fieldstart + offset; | ||
603 | lencopy = dev->bytesperline - currlinedone; | ||
604 | lencopy = lencopy > remain ? remain : lencopy; | ||
605 | |||
606 | memcpy(startwrite, startread, lencopy); | ||
607 | remain -= lencopy; | ||
608 | |||
609 | while (remain > 0) { | ||
610 | startwrite += lencopy + dev->bytesperline; | ||
611 | startread += lencopy; | ||
612 | if (dev->bytesperline > remain) | ||
613 | lencopy = remain; | ||
614 | else | ||
615 | lencopy = dev->bytesperline; | ||
616 | |||
617 | memcpy(startwrite, startread, lencopy); | ||
618 | remain -= lencopy; | ||
619 | } | ||
620 | |||
621 | (*f)->fieldbytesused += len; | ||
622 | } | 549 | } |
550 | EXPORT_SYMBOL_GPL(em28xx_set_mode); | ||
551 | |||
552 | /* ------------------------------------------------------------------ | ||
553 | URB control | ||
554 | ------------------------------------------------------------------*/ | ||
623 | 555 | ||
624 | /* | 556 | /* |
625 | * em28xx_isoIrq() | 557 | * IRQ callback, called by URB callback |
626 | * handles the incoming isoc urbs and fills the frames from our inqueue | ||
627 | */ | 558 | */ |
628 | static void em28xx_isocIrq(struct urb *urb) | 559 | static void em28xx_irq_callback(struct urb *urb) |
629 | { | 560 | { |
630 | struct em28xx *dev = urb->context; | 561 | struct em28xx_dmaqueue *dma_q = urb->context; |
631 | int i, status; | 562 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); |
632 | struct em28xx_frame_t **f; | 563 | int rc, i; |
633 | unsigned long lock_flags; | ||
634 | |||
635 | if (!dev) | ||
636 | return; | ||
637 | #ifdef ENABLE_DEBUG_ISOC_FRAMES | ||
638 | if (isoc_debug>1) | ||
639 | em28xx_isoc_dump(urb); | ||
640 | #endif | ||
641 | |||
642 | if (urb->status == -ENOENT) | ||
643 | return; | ||
644 | |||
645 | f = &dev->frame_current; | ||
646 | |||
647 | if (dev->stream == STREAM_INTERRUPT) { | ||
648 | dev->stream = STREAM_OFF; | ||
649 | if ((*f)) | ||
650 | (*f)->state = F_QUEUED; | ||
651 | em28xx_isocdbg("stream interrupted"); | ||
652 | wake_up_interruptible(&dev->wait_stream); | ||
653 | } | ||
654 | |||
655 | if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) | ||
656 | return; | ||
657 | |||
658 | if (dev->stream == STREAM_ON && !list_empty(&dev->inqueue)) { | ||
659 | if (!(*f)) | ||
660 | (*f) = list_entry(dev->inqueue.next, | ||
661 | struct em28xx_frame_t, frame); | ||
662 | |||
663 | for (i = 0; i < urb->number_of_packets; i++) { | ||
664 | unsigned char *buf = urb->transfer_buffer + | ||
665 | urb->iso_frame_desc[i].offset; | ||
666 | int len = urb->iso_frame_desc[i].actual_length - 4; | ||
667 | |||
668 | if (urb->iso_frame_desc[i].status) { | ||
669 | em28xx_isocdbg("data error: [%d] len=%d, status=%d", i, | ||
670 | urb->iso_frame_desc[i].actual_length, | ||
671 | urb->iso_frame_desc[i].status); | ||
672 | if (urb->iso_frame_desc[i].status != -EPROTO) | ||
673 | continue; | ||
674 | } | ||
675 | if (urb->iso_frame_desc[i].actual_length <= 0) { | ||
676 | em28xx_isocdbg("packet %d is empty",i); | ||
677 | continue; | ||
678 | } | ||
679 | if (urb->iso_frame_desc[i].actual_length > | ||
680 | urb->iso_frame_desc[i].length) { | ||
681 | em28xx_isocdbg("packet bigger than packet size"); | ||
682 | continue; | ||
683 | } | ||
684 | /*new frame */ | ||
685 | if (buf[0] == 0x22 && buf[1] == 0x5a) { | ||
686 | em28xx_isocdbg("Video frame, length=%i!",len); | ||
687 | |||
688 | if (em28xx_isoc_video(dev,f,&lock_flags,buf[2])) | ||
689 | break; | ||
690 | } else if (buf[0]==0x33 && buf[1]==0x95 && buf[2]==0x00) { | ||
691 | em28xx_isocdbg("VBI HEADER!!!"); | ||
692 | } | ||
693 | 564 | ||
694 | /* actual copying */ | 565 | /* Copy data from URB */ |
695 | if ((*f)->state == F_GRABBING) { | 566 | spin_lock(&dev->slock); |
696 | em28xx_isoc_video_copy(dev,f,buf, len); | 567 | rc = dev->isoc_ctl.isoc_copy(dev, urb); |
697 | } | 568 | spin_unlock(&dev->slock); |
698 | } | ||
699 | } | ||
700 | 569 | ||
570 | /* Reset urb buffers */ | ||
701 | for (i = 0; i < urb->number_of_packets; i++) { | 571 | for (i = 0; i < urb->number_of_packets; i++) { |
702 | urb->iso_frame_desc[i].status = 0; | 572 | urb->iso_frame_desc[i].status = 0; |
703 | urb->iso_frame_desc[i].actual_length = 0; | 573 | urb->iso_frame_desc[i].actual_length = 0; |
704 | } | 574 | } |
705 | |||
706 | urb->status = 0; | 575 | urb->status = 0; |
707 | if ((status = usb_submit_urb(urb, GFP_ATOMIC))) { | 576 | |
708 | em28xx_errdev("resubmit of urb failed (error=%i)\n", status); | 577 | urb->status = usb_submit_urb(urb, GFP_ATOMIC); |
709 | dev->state |= DEV_MISCONFIGURED; | 578 | if (urb->status) { |
579 | em28xx_isocdbg("urb resubmit failed (error=%i)\n", | ||
580 | urb->status); | ||
710 | } | 581 | } |
711 | wake_up_interruptible(&dev->wait_frame); | ||
712 | return; | ||
713 | } | 582 | } |
714 | 583 | ||
715 | /* | 584 | /* |
716 | * em28xx_uninit_isoc() | 585 | * Stop and Deallocate URBs |
717 | * deallocates the buffers and urbs allocated during em28xx_init_iosc() | ||
718 | */ | 586 | */ |
719 | void em28xx_uninit_isoc(struct em28xx *dev) | 587 | void em28xx_uninit_isoc(struct em28xx *dev) |
720 | { | 588 | { |
589 | struct urb *urb; | ||
721 | int i; | 590 | int i; |
722 | 591 | ||
723 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { | 592 | em28xx_isocdbg("em28xx: called em28xx_uninit_isoc\n"); |
724 | if (dev->urb[i]) { | 593 | |
725 | usb_kill_urb(dev->urb[i]); | 594 | dev->isoc_ctl.nfields = -1; |
726 | if (dev->transfer_buffer[i]) { | 595 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { |
596 | urb = dev->isoc_ctl.urb[i]; | ||
597 | if (urb) { | ||
598 | usb_kill_urb(urb); | ||
599 | usb_unlink_urb(urb); | ||
600 | if (dev->isoc_ctl.transfer_buffer[i]) { | ||
727 | usb_buffer_free(dev->udev, | 601 | usb_buffer_free(dev->udev, |
728 | dev->urb[i]->transfer_buffer_length, | 602 | urb->transfer_buffer_length, |
729 | dev->transfer_buffer[i], | 603 | dev->isoc_ctl.transfer_buffer[i], |
730 | dev->urb[i]->transfer_dma); | 604 | urb->transfer_dma); |
731 | } | 605 | } |
732 | usb_free_urb(dev->urb[i]); | 606 | usb_free_urb(urb); |
607 | dev->isoc_ctl.urb[i] = NULL; | ||
733 | } | 608 | } |
734 | dev->urb[i] = NULL; | 609 | dev->isoc_ctl.transfer_buffer[i] = NULL; |
735 | dev->transfer_buffer[i] = NULL; | ||
736 | } | 610 | } |
611 | |||
612 | kfree(dev->isoc_ctl.urb); | ||
613 | kfree(dev->isoc_ctl.transfer_buffer); | ||
614 | |||
615 | dev->isoc_ctl.urb = NULL; | ||
616 | dev->isoc_ctl.transfer_buffer = NULL; | ||
617 | dev->isoc_ctl.num_bufs = 0; | ||
618 | |||
737 | em28xx_capture_start(dev, 0); | 619 | em28xx_capture_start(dev, 0); |
738 | } | 620 | } |
621 | EXPORT_SYMBOL_GPL(em28xx_uninit_isoc); | ||
739 | 622 | ||
740 | /* | 623 | /* |
741 | * em28xx_init_isoc() | 624 | * Allocate URBs and start IRQ |
742 | * allocates transfer buffers and submits the urbs for isoc transfer | ||
743 | */ | 625 | */ |
744 | int em28xx_init_isoc(struct em28xx *dev) | 626 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, |
627 | int num_bufs, int max_pkt_size, | ||
628 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)) | ||
745 | { | 629 | { |
746 | /* change interface to 3 which allows the biggest packet sizes */ | 630 | struct em28xx_dmaqueue *dma_q = &dev->vidq; |
747 | int i, errCode; | 631 | int i; |
748 | int sb_size; | 632 | int sb_size, pipe; |
749 | 633 | struct urb *urb; | |
750 | em28xx_set_alternate(dev); | 634 | int j, k; |
751 | sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size; | 635 | int rc; |
752 | 636 | ||
753 | /* reset streaming vars */ | 637 | em28xx_isocdbg("em28xx: called em28xx_prepare_isoc\n"); |
754 | dev->frame_current = NULL; | 638 | |
755 | dev->frame_count = 0; | 639 | /* De-allocates all pending stuff */ |
756 | 640 | em28xx_uninit_isoc(dev); | |
757 | /* allocate urbs */ | 641 | |
758 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { | 642 | dev->isoc_ctl.isoc_copy = isoc_copy; |
759 | struct urb *urb; | 643 | dev->isoc_ctl.num_bufs = num_bufs; |
760 | int j; | 644 | |
761 | /* allocate transfer buffer */ | 645 | dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); |
762 | urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL); | 646 | if (!dev->isoc_ctl.urb) { |
763 | if (!urb){ | 647 | em28xx_errdev("cannot alloc memory for usb buffers\n"); |
764 | em28xx_errdev("cannot alloc urb %i\n", i); | 648 | return -ENOMEM; |
649 | } | ||
650 | |||
651 | dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, | ||
652 | GFP_KERNEL); | ||
653 | if (!dev->isoc_ctl.urb) { | ||
654 | em28xx_errdev("cannot allocate memory for usbtransfer\n"); | ||
655 | kfree(dev->isoc_ctl.urb); | ||
656 | return -ENOMEM; | ||
657 | } | ||
658 | |||
659 | dev->isoc_ctl.max_pkt_size = max_pkt_size; | ||
660 | dev->isoc_ctl.buf = NULL; | ||
661 | |||
662 | sb_size = max_packets * dev->isoc_ctl.max_pkt_size; | ||
663 | |||
664 | /* allocate urbs and transfer buffers */ | ||
665 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | ||
666 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); | ||
667 | if (!urb) { | ||
668 | em28xx_err("cannot alloc isoc_ctl.urb %i\n", i); | ||
765 | em28xx_uninit_isoc(dev); | 669 | em28xx_uninit_isoc(dev); |
766 | return -ENOMEM; | 670 | return -ENOMEM; |
767 | } | 671 | } |
768 | dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, | 672 | dev->isoc_ctl.urb[i] = urb; |
769 | GFP_KERNEL, | 673 | |
770 | &urb->transfer_dma); | 674 | dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->udev, |
771 | if (!dev->transfer_buffer[i]) { | 675 | sb_size, GFP_KERNEL, &urb->transfer_dma); |
772 | em28xx_errdev | 676 | if (!dev->isoc_ctl.transfer_buffer[i]) { |
773 | ("unable to allocate %i bytes for transfer buffer %i\n", | 677 | em28xx_err("unable to allocate %i bytes for transfer" |
774 | sb_size, i); | 678 | " buffer %i%s\n", |
679 | sb_size, i, | ||
680 | in_interrupt()?" while in int":""); | ||
775 | em28xx_uninit_isoc(dev); | 681 | em28xx_uninit_isoc(dev); |
776 | usb_free_urb(urb); | ||
777 | return -ENOMEM; | 682 | return -ENOMEM; |
778 | } | 683 | } |
779 | memset(dev->transfer_buffer[i], 0, sb_size); | 684 | memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size); |
780 | urb->dev = dev->udev; | 685 | |
781 | urb->context = dev; | 686 | /* FIXME: this is a hack - should be |
782 | urb->pipe = usb_rcvisocpipe(dev->udev, 0x82); | 687 | 'desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK' |
783 | urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; | 688 | should also be using 'desc.bInterval' |
784 | urb->interval = 1; | 689 | */ |
785 | urb->transfer_buffer = dev->transfer_buffer[i]; | 690 | pipe = usb_rcvisocpipe(dev->udev, |
786 | urb->complete = em28xx_isocIrq; | 691 | dev->mode == EM28XX_ANALOG_MODE ? 0x82 : 0x84); |
787 | urb->number_of_packets = EM28XX_NUM_PACKETS; | 692 | |
788 | urb->transfer_buffer_length = sb_size; | 693 | usb_fill_int_urb(urb, dev->udev, pipe, |
789 | for (j = 0; j < EM28XX_NUM_PACKETS; j++) { | 694 | dev->isoc_ctl.transfer_buffer[i], sb_size, |
790 | urb->iso_frame_desc[j].offset = j * dev->max_pkt_size; | 695 | em28xx_irq_callback, dma_q, 1); |
791 | urb->iso_frame_desc[j].length = dev->max_pkt_size; | 696 | |
697 | urb->number_of_packets = max_packets; | ||
698 | urb->transfer_flags = URB_ISO_ASAP; | ||
699 | |||
700 | k = 0; | ||
701 | for (j = 0; j < max_packets; j++) { | ||
702 | urb->iso_frame_desc[j].offset = k; | ||
703 | urb->iso_frame_desc[j].length = | ||
704 | dev->isoc_ctl.max_pkt_size; | ||
705 | k += dev->isoc_ctl.max_pkt_size; | ||
792 | } | 706 | } |
793 | dev->urb[i] = urb; | ||
794 | } | 707 | } |
795 | 708 | ||
796 | /* submit urbs */ | 709 | init_waitqueue_head(&dma_q->wq); |
797 | em28xx_coredbg("Submitting %d urbs of %d packets (%d each)\n", | ||
798 | EM28XX_NUM_BUFS, EM28XX_NUM_PACKETS, dev->max_pkt_size); | ||
799 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { | ||
800 | errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL); | ||
801 | if (errCode) { | ||
802 | em28xx_errdev("submit of urb %i failed (error=%i)\n", i, | ||
803 | errCode); | ||
804 | em28xx_uninit_isoc(dev); | ||
805 | return errCode; | ||
806 | } | ||
807 | } | ||
808 | |||
809 | return 0; | ||
810 | } | ||
811 | |||
812 | int em28xx_set_alternate(struct em28xx *dev) | ||
813 | { | ||
814 | int errCode, prev_alt = dev->alt; | ||
815 | int i; | ||
816 | unsigned int min_pkt_size = dev->bytesperline+4; | ||
817 | |||
818 | /* When image size is bigger than a ceirtain value, | ||
819 | the frame size should be increased, otherwise, only | ||
820 | green screen will be received. | ||
821 | */ | ||
822 | if (dev->frame_size > 720*240*2) | ||
823 | min_pkt_size *= 2; | ||
824 | 710 | ||
825 | for (i = 0; i < dev->num_alt; i++) | 711 | em28xx_capture_start(dev, 1); |
826 | if (dev->alt_max_pkt_size[i] >= min_pkt_size) | ||
827 | break; | ||
828 | dev->alt = i; | ||
829 | 712 | ||
830 | if (dev->alt != prev_alt) { | 713 | /* submit urbs and enables IRQ */ |
831 | em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", | 714 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { |
832 | min_pkt_size, dev->alt); | 715 | rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC); |
833 | dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; | 716 | if (rc) { |
834 | em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", | 717 | em28xx_err("submit of urb %i failed (error=%i)\n", i, |
835 | dev->alt, dev->max_pkt_size); | 718 | rc); |
836 | errCode = usb_set_interface(dev->udev, 0, dev->alt); | 719 | em28xx_uninit_isoc(dev); |
837 | if (errCode < 0) { | 720 | return rc; |
838 | em28xx_errdev ("cannot change alternate number to %d (error=%i)\n", | ||
839 | dev->alt, errCode); | ||
840 | return errCode; | ||
841 | } | 721 | } |
842 | } | 722 | } |
723 | |||
843 | return 0; | 724 | return 0; |
844 | } | 725 | } |
726 | EXPORT_SYMBOL_GPL(em28xx_init_isoc); | ||
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c new file mode 100644 index 000000000000..7df81575b7f2 --- /dev/null +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -0,0 +1,474 @@ | |||
1 | /* | ||
2 | DVB device driver for em28xx | ||
3 | |||
4 | (c) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> | ||
5 | |||
6 | (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> | ||
7 | - Fixes for the driver to properly work with HVR-950 | ||
8 | |||
9 | (c) 2008 Aidan Thornton <makosoft@googlemail.com> | ||
10 | |||
11 | Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by: | ||
12 | (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> | ||
13 | (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | ||
14 | |||
15 | This program is free software; you can redistribute it and/or modify | ||
16 | it under the terms of the GNU General Public License as published by | ||
17 | the Free Software Foundation; either version 2 of the License. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/usb.h> | ||
22 | |||
23 | #include "em28xx.h" | ||
24 | #include <media/v4l2-common.h> | ||
25 | #include <media/videobuf-vmalloc.h> | ||
26 | |||
27 | #include "lgdt330x.h" | ||
28 | #include "zl10353.h" | ||
29 | |||
30 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); | ||
31 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | static unsigned int debug; | ||
35 | module_param(debug, int, 0644); | ||
36 | MODULE_PARM_DESC(debug, "enable debug messages [dvb]"); | ||
37 | |||
38 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
39 | |||
40 | #define dprintk(level, fmt, arg...) do { \ | ||
41 | if (debug >= level) \ | ||
42 | printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \ | ||
43 | } while (0) | ||
44 | |||
45 | #define EM28XX_DVB_NUM_BUFS 5 | ||
46 | #define EM28XX_DVB_MAX_PACKETSIZE 564 | ||
47 | #define EM28XX_DVB_MAX_PACKETS 64 | ||
48 | |||
49 | struct em28xx_dvb { | ||
50 | struct dvb_frontend *frontend; | ||
51 | |||
52 | /* feed count management */ | ||
53 | struct mutex lock; | ||
54 | int nfeeds; | ||
55 | |||
56 | /* general boilerplate stuff */ | ||
57 | struct dvb_adapter adapter; | ||
58 | struct dvb_demux demux; | ||
59 | struct dmxdev dmxdev; | ||
60 | struct dmx_frontend fe_hw; | ||
61 | struct dmx_frontend fe_mem; | ||
62 | struct dvb_net net; | ||
63 | }; | ||
64 | |||
65 | |||
66 | static inline void print_err_status(struct em28xx *dev, | ||
67 | int packet, int status) | ||
68 | { | ||
69 | char *errmsg = "Unknown"; | ||
70 | |||
71 | switch (status) { | ||
72 | case -ENOENT: | ||
73 | errmsg = "unlinked synchronuously"; | ||
74 | break; | ||
75 | case -ECONNRESET: | ||
76 | errmsg = "unlinked asynchronuously"; | ||
77 | break; | ||
78 | case -ENOSR: | ||
79 | errmsg = "Buffer error (overrun)"; | ||
80 | break; | ||
81 | case -EPIPE: | ||
82 | errmsg = "Stalled (device not responding)"; | ||
83 | break; | ||
84 | case -EOVERFLOW: | ||
85 | errmsg = "Babble (bad cable?)"; | ||
86 | break; | ||
87 | case -EPROTO: | ||
88 | errmsg = "Bit-stuff error (bad cable?)"; | ||
89 | break; | ||
90 | case -EILSEQ: | ||
91 | errmsg = "CRC/Timeout (could be anything)"; | ||
92 | break; | ||
93 | case -ETIME: | ||
94 | errmsg = "Device does not respond"; | ||
95 | break; | ||
96 | } | ||
97 | if (packet < 0) { | ||
98 | dprintk(1, "URB status %d [%s].\n", status, errmsg); | ||
99 | } else { | ||
100 | dprintk(1, "URB packet %d, status %d [%s].\n", | ||
101 | packet, status, errmsg); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | static inline int dvb_isoc_copy(struct em28xx *dev, struct urb *urb) | ||
106 | { | ||
107 | int i; | ||
108 | |||
109 | if (!dev) | ||
110 | return 0; | ||
111 | |||
112 | if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) | ||
113 | return 0; | ||
114 | |||
115 | if (urb->status < 0) { | ||
116 | print_err_status(dev, -1, urb->status); | ||
117 | if (urb->status == -ENOENT) | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | for (i = 0; i < urb->number_of_packets; i++) { | ||
122 | int status = urb->iso_frame_desc[i].status; | ||
123 | |||
124 | if (status < 0) { | ||
125 | print_err_status(dev, i, status); | ||
126 | if (urb->iso_frame_desc[i].status != -EPROTO) | ||
127 | continue; | ||
128 | } | ||
129 | |||
130 | dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer + | ||
131 | urb->iso_frame_desc[i].offset, | ||
132 | urb->iso_frame_desc[i].actual_length); | ||
133 | } | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int start_streaming(struct em28xx_dvb *dvb) | ||
139 | { | ||
140 | int rc; | ||
141 | struct em28xx *dev = dvb->adapter.priv; | ||
142 | |||
143 | usb_set_interface(dev->udev, 0, 1); | ||
144 | rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | ||
145 | if (rc < 0) | ||
146 | return rc; | ||
147 | |||
148 | return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, | ||
149 | EM28XX_DVB_NUM_BUFS, EM28XX_DVB_MAX_PACKETSIZE, | ||
150 | dvb_isoc_copy); | ||
151 | } | ||
152 | |||
153 | static int stop_streaming(struct em28xx_dvb *dvb) | ||
154 | { | ||
155 | struct em28xx *dev = dvb->adapter.priv; | ||
156 | |||
157 | em28xx_uninit_isoc(dev); | ||
158 | |||
159 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int start_feed(struct dvb_demux_feed *feed) | ||
165 | { | ||
166 | struct dvb_demux *demux = feed->demux; | ||
167 | struct em28xx_dvb *dvb = demux->priv; | ||
168 | int rc, ret; | ||
169 | |||
170 | if (!demux->dmx.frontend) | ||
171 | return -EINVAL; | ||
172 | |||
173 | mutex_lock(&dvb->lock); | ||
174 | dvb->nfeeds++; | ||
175 | rc = dvb->nfeeds; | ||
176 | |||
177 | if (dvb->nfeeds == 1) { | ||
178 | ret = start_streaming(dvb); | ||
179 | if (ret < 0) | ||
180 | rc = ret; | ||
181 | } | ||
182 | |||
183 | mutex_unlock(&dvb->lock); | ||
184 | return rc; | ||
185 | } | ||
186 | |||
187 | static int stop_feed(struct dvb_demux_feed *feed) | ||
188 | { | ||
189 | struct dvb_demux *demux = feed->demux; | ||
190 | struct em28xx_dvb *dvb = demux->priv; | ||
191 | int err = 0; | ||
192 | |||
193 | mutex_lock(&dvb->lock); | ||
194 | dvb->nfeeds--; | ||
195 | |||
196 | if (0 == dvb->nfeeds) | ||
197 | err = stop_streaming(dvb); | ||
198 | |||
199 | mutex_unlock(&dvb->lock); | ||
200 | return err; | ||
201 | } | ||
202 | |||
203 | |||
204 | |||
205 | /* ------------------------------------------------------------------ */ | ||
206 | static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) | ||
207 | { | ||
208 | struct em28xx *dev = fe->dvb->priv; | ||
209 | |||
210 | if (acquire) | ||
211 | return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | ||
212 | else | ||
213 | return em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | ||
214 | } | ||
215 | |||
216 | /* ------------------------------------------------------------------ */ | ||
217 | |||
218 | static struct lgdt330x_config em2880_lgdt3303_dev = { | ||
219 | .demod_address = 0x0e, | ||
220 | .demod_chip = LGDT3303, | ||
221 | }; | ||
222 | |||
223 | static struct zl10353_config em28xx_zl10353_with_xc3028 = { | ||
224 | .demod_address = (0x1e >> 1), | ||
225 | .no_tuner = 1, | ||
226 | .parallel_ts = 1, | ||
227 | .if2 = 45600, | ||
228 | }; | ||
229 | |||
230 | /* ------------------------------------------------------------------ */ | ||
231 | |||
232 | static int attach_xc3028(u8 addr, struct em28xx *dev) | ||
233 | { | ||
234 | struct dvb_frontend *fe; | ||
235 | struct xc2028_config cfg; | ||
236 | |||
237 | memset(&cfg, 0, sizeof(cfg)); | ||
238 | cfg.i2c_adap = &dev->i2c_adap; | ||
239 | cfg.i2c_addr = addr; | ||
240 | cfg.callback = em28xx_tuner_callback; | ||
241 | |||
242 | if (!dev->dvb->frontend) { | ||
243 | printk(KERN_ERR "%s/2: dvb frontend not attached. " | ||
244 | "Can't attach xc3028\n", | ||
245 | dev->name); | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | |||
249 | fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg); | ||
250 | if (!fe) { | ||
251 | printk(KERN_ERR "%s/2: xc3028 attach failed\n", | ||
252 | dev->name); | ||
253 | dvb_frontend_detach(dev->dvb->frontend); | ||
254 | dvb_unregister_frontend(dev->dvb->frontend); | ||
255 | dev->dvb->frontend = NULL; | ||
256 | return -EINVAL; | ||
257 | } | ||
258 | |||
259 | printk(KERN_INFO "%s/2: xc3028 attached\n", dev->name); | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | /* ------------------------------------------------------------------ */ | ||
265 | |||
266 | int register_dvb(struct em28xx_dvb *dvb, | ||
267 | struct module *module, | ||
268 | struct em28xx *dev, | ||
269 | struct device *device) | ||
270 | { | ||
271 | int result; | ||
272 | |||
273 | mutex_init(&dvb->lock); | ||
274 | |||
275 | /* register adapter */ | ||
276 | result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, | ||
277 | adapter_nr); | ||
278 | if (result < 0) { | ||
279 | printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", | ||
280 | dev->name, result); | ||
281 | goto fail_adapter; | ||
282 | } | ||
283 | |||
284 | /* Ensure all frontends negotiate bus access */ | ||
285 | dvb->frontend->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl; | ||
286 | |||
287 | dvb->adapter.priv = dev; | ||
288 | |||
289 | /* register frontend */ | ||
290 | result = dvb_register_frontend(&dvb->adapter, dvb->frontend); | ||
291 | if (result < 0) { | ||
292 | printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", | ||
293 | dev->name, result); | ||
294 | goto fail_frontend; | ||
295 | } | ||
296 | |||
297 | /* register demux stuff */ | ||
298 | dvb->demux.dmx.capabilities = | ||
299 | DMX_TS_FILTERING | DMX_SECTION_FILTERING | | ||
300 | DMX_MEMORY_BASED_FILTERING; | ||
301 | dvb->demux.priv = dvb; | ||
302 | dvb->demux.filternum = 256; | ||
303 | dvb->demux.feednum = 256; | ||
304 | dvb->demux.start_feed = start_feed; | ||
305 | dvb->demux.stop_feed = stop_feed; | ||
306 | |||
307 | result = dvb_dmx_init(&dvb->demux); | ||
308 | if (result < 0) { | ||
309 | printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n", | ||
310 | dev->name, result); | ||
311 | goto fail_dmx; | ||
312 | } | ||
313 | |||
314 | dvb->dmxdev.filternum = 256; | ||
315 | dvb->dmxdev.demux = &dvb->demux.dmx; | ||
316 | dvb->dmxdev.capabilities = 0; | ||
317 | result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); | ||
318 | if (result < 0) { | ||
319 | printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", | ||
320 | dev->name, result); | ||
321 | goto fail_dmxdev; | ||
322 | } | ||
323 | |||
324 | dvb->fe_hw.source = DMX_FRONTEND_0; | ||
325 | result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
326 | if (result < 0) { | ||
327 | printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", | ||
328 | dev->name, result); | ||
329 | goto fail_fe_hw; | ||
330 | } | ||
331 | |||
332 | dvb->fe_mem.source = DMX_MEMORY_FE; | ||
333 | result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
334 | if (result < 0) { | ||
335 | printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", | ||
336 | dev->name, result); | ||
337 | goto fail_fe_mem; | ||
338 | } | ||
339 | |||
340 | result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
341 | if (result < 0) { | ||
342 | printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n", | ||
343 | dev->name, result); | ||
344 | goto fail_fe_conn; | ||
345 | } | ||
346 | |||
347 | /* register network adapter */ | ||
348 | dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); | ||
349 | return 0; | ||
350 | |||
351 | fail_fe_conn: | ||
352 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
353 | fail_fe_mem: | ||
354 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
355 | fail_fe_hw: | ||
356 | dvb_dmxdev_release(&dvb->dmxdev); | ||
357 | fail_dmxdev: | ||
358 | dvb_dmx_release(&dvb->demux); | ||
359 | fail_dmx: | ||
360 | dvb_unregister_frontend(dvb->frontend); | ||
361 | fail_frontend: | ||
362 | dvb_frontend_detach(dvb->frontend); | ||
363 | dvb_unregister_adapter(&dvb->adapter); | ||
364 | fail_adapter: | ||
365 | return result; | ||
366 | } | ||
367 | |||
368 | static void unregister_dvb(struct em28xx_dvb *dvb) | ||
369 | { | ||
370 | dvb_net_release(&dvb->net); | ||
371 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
372 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
373 | dvb_dmxdev_release(&dvb->dmxdev); | ||
374 | dvb_dmx_release(&dvb->demux); | ||
375 | dvb_unregister_frontend(dvb->frontend); | ||
376 | dvb_frontend_detach(dvb->frontend); | ||
377 | dvb_unregister_adapter(&dvb->adapter); | ||
378 | } | ||
379 | |||
380 | |||
381 | static int dvb_init(struct em28xx *dev) | ||
382 | { | ||
383 | int result = 0; | ||
384 | struct em28xx_dvb *dvb; | ||
385 | |||
386 | dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); | ||
387 | |||
388 | if (dvb == NULL) { | ||
389 | printk(KERN_INFO "em28xx_dvb: memory allocation failed\n"); | ||
390 | return -ENOMEM; | ||
391 | } | ||
392 | dev->dvb = dvb; | ||
393 | |||
394 | em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | ||
395 | /* init frontend */ | ||
396 | switch (dev->model) { | ||
397 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: | ||
398 | dvb->frontend = dvb_attach(lgdt330x_attach, | ||
399 | &em2880_lgdt3303_dev, | ||
400 | &dev->i2c_adap); | ||
401 | if (attach_xc3028(0x61, dev) < 0) { | ||
402 | result = -EINVAL; | ||
403 | goto out_free; | ||
404 | } | ||
405 | break; | ||
406 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
407 | dvb->frontend = dvb_attach(zl10353_attach, | ||
408 | &em28xx_zl10353_with_xc3028, | ||
409 | &dev->i2c_adap); | ||
410 | if (attach_xc3028(0x61, dev) < 0) { | ||
411 | result = -EINVAL; | ||
412 | goto out_free; | ||
413 | } | ||
414 | break; | ||
415 | default: | ||
416 | printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" | ||
417 | " isn't supported yet\n", | ||
418 | dev->name); | ||
419 | break; | ||
420 | } | ||
421 | if (NULL == dvb->frontend) { | ||
422 | printk(KERN_ERR | ||
423 | "%s/2: frontend initialization failed\n", | ||
424 | dev->name); | ||
425 | result = -EINVAL; | ||
426 | goto out_free; | ||
427 | } | ||
428 | |||
429 | /* register everything */ | ||
430 | result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); | ||
431 | |||
432 | if (result < 0) | ||
433 | goto out_free; | ||
434 | |||
435 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | ||
436 | printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); | ||
437 | return 0; | ||
438 | |||
439 | out_free: | ||
440 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | ||
441 | kfree(dvb); | ||
442 | dev->dvb = NULL; | ||
443 | return result; | ||
444 | } | ||
445 | |||
446 | static int dvb_fini(struct em28xx *dev) | ||
447 | { | ||
448 | if (dev->dvb) { | ||
449 | unregister_dvb(dev->dvb); | ||
450 | dev->dvb = NULL; | ||
451 | } | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static struct em28xx_ops dvb_ops = { | ||
457 | .id = EM28XX_DVB, | ||
458 | .name = "Em28xx dvb Extension", | ||
459 | .init = dvb_init, | ||
460 | .fini = dvb_fini, | ||
461 | }; | ||
462 | |||
463 | static int __init em28xx_dvb_register(void) | ||
464 | { | ||
465 | return em28xx_register_extension(&dvb_ops); | ||
466 | } | ||
467 | |||
468 | static void __exit em28xx_dvb_unregister(void) | ||
469 | { | ||
470 | em28xx_unregister_extension(&dvb_ops); | ||
471 | } | ||
472 | |||
473 | module_init(em28xx_dvb_register); | ||
474 | module_exit(em28xx_dvb_unregister); | ||
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index cacd04d46e99..6a78fd294cab 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -33,19 +33,29 @@ | |||
33 | 33 | ||
34 | /* ----------------------------------------------------------- */ | 34 | /* ----------------------------------------------------------- */ |
35 | 35 | ||
36 | static unsigned int i2c_scan = 0; | 36 | static unsigned int i2c_scan; |
37 | module_param(i2c_scan, int, 0444); | 37 | module_param(i2c_scan, int, 0444); |
38 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); | 38 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); |
39 | 39 | ||
40 | static unsigned int i2c_debug = 0; | 40 | static unsigned int i2c_debug; |
41 | module_param(i2c_debug, int, 0644); | 41 | module_param(i2c_debug, int, 0644); |
42 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | 42 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); |
43 | 43 | ||
44 | #define dprintk1(lvl,fmt, args...) if (i2c_debug>=lvl) do {\ | 44 | |
45 | printk(fmt, ##args); } while (0) | 45 | #define dprintk1(lvl, fmt, args...) \ |
46 | #define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \ | 46 | do { \ |
47 | printk(KERN_DEBUG "%s at %s: " fmt, \ | 47 | if (i2c_debug >= lvl) { \ |
48 | dev->name, __FUNCTION__ , ##args); } while (0) | 48 | printk(fmt, ##args); \ |
49 | } \ | ||
50 | } while (0) | ||
51 | |||
52 | #define dprintk2(lvl, fmt, args...) \ | ||
53 | do { \ | ||
54 | if (i2c_debug >= lvl) { \ | ||
55 | printk(KERN_DEBUG "%s at %s: " fmt, \ | ||
56 | dev->name, __func__ , ##args); \ | ||
57 | } \ | ||
58 | } while (0) | ||
49 | 59 | ||
50 | /* | 60 | /* |
51 | * em2800_i2c_send_max4() | 61 | * em2800_i2c_send_max4() |
@@ -235,16 +245,16 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
235 | return 0; | 245 | return 0; |
236 | for (i = 0; i < num; i++) { | 246 | for (i = 0; i < num; i++) { |
237 | addr = msgs[i].addr << 1; | 247 | addr = msgs[i].addr << 1; |
238 | dprintk2(2,"%s %s addr=%x len=%d:", | 248 | dprintk2(2, "%s %s addr=%x len=%d:", |
239 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", | 249 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", |
240 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); | 250 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); |
241 | if (!msgs[i].len) { /* no len: check only for device presence */ | 251 | if (!msgs[i].len) { /* no len: check only for device presence */ |
242 | if (dev->is_em2800) | 252 | if (dev->is_em2800) |
243 | rc = em2800_i2c_check_for_device(dev, addr); | 253 | rc = em2800_i2c_check_for_device(dev, addr); |
244 | else | 254 | else |
245 | rc = em28xx_i2c_check_for_device(dev, addr); | 255 | rc = em28xx_i2c_check_for_device(dev, addr); |
246 | if (rc < 0) { | 256 | if (rc < 0) { |
247 | dprintk2(2," no device\n"); | 257 | dprintk2(2, " no device\n"); |
248 | return rc; | 258 | return rc; |
249 | } | 259 | } |
250 | 260 | ||
@@ -258,14 +268,13 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
258 | rc = em28xx_i2c_recv_bytes(dev, addr, | 268 | rc = em28xx_i2c_recv_bytes(dev, addr, |
259 | msgs[i].buf, | 269 | msgs[i].buf, |
260 | msgs[i].len); | 270 | msgs[i].len); |
261 | if (i2c_debug>=2) { | 271 | if (i2c_debug >= 2) { |
262 | for (byte = 0; byte < msgs[i].len; byte++) { | 272 | for (byte = 0; byte < msgs[i].len; byte++) |
263 | printk(" %02x", msgs[i].buf[byte]); | 273 | printk(" %02x", msgs[i].buf[byte]); |
264 | } | ||
265 | } | 274 | } |
266 | } else { | 275 | } else { |
267 | /* write bytes */ | 276 | /* write bytes */ |
268 | if (i2c_debug>=2) { | 277 | if (i2c_debug >= 2) { |
269 | for (byte = 0; byte < msgs[i].len; byte++) | 278 | for (byte = 0; byte < msgs[i].len; byte++) |
270 | printk(" %02x", msgs[i].buf[byte]); | 279 | printk(" %02x", msgs[i].buf[byte]); |
271 | } | 280 | } |
@@ -281,13 +290,13 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
281 | } | 290 | } |
282 | if (rc < 0) | 291 | if (rc < 0) |
283 | goto err; | 292 | goto err; |
284 | if (i2c_debug>=2) | 293 | if (i2c_debug >= 2) |
285 | printk("\n"); | 294 | printk("\n"); |
286 | } | 295 | } |
287 | 296 | ||
288 | return num; | 297 | return num; |
289 | err: | 298 | err: |
290 | dprintk2(2," ERROR: %i\n", rc); | 299 | dprintk2(2, " ERROR: %i\n", rc); |
291 | return rc; | 300 | return rc; |
292 | } | 301 | } |
293 | 302 | ||
@@ -330,7 +339,9 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) | |||
330 | return -1; | 339 | return -1; |
331 | 340 | ||
332 | buf = 0; | 341 | buf = 0; |
333 | if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) { | 342 | |
343 | err = i2c_master_send(&dev->i2c_client, &buf, 1); | ||
344 | if (err != 1) { | ||
334 | printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", | 345 | printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", |
335 | dev->name, err); | 346 | dev->name, err); |
336 | return -1; | 347 | return -1; |
@@ -403,8 +414,10 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) | |||
403 | break; | 414 | break; |
404 | } | 415 | } |
405 | printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", | 416 | printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", |
406 | em_eeprom->string_idx_table,em_eeprom->string1, | 417 | em_eeprom->string_idx_table, |
407 | em_eeprom->string2,em_eeprom->string3); | 418 | em_eeprom->string1, |
419 | em_eeprom->string2, | ||
420 | em_eeprom->string3); | ||
408 | 421 | ||
409 | return 0; | 422 | return 0; |
410 | } | 423 | } |
@@ -430,58 +443,61 @@ static int attach_inform(struct i2c_client *client) | |||
430 | struct em28xx *dev = client->adapter->algo_data; | 443 | struct em28xx *dev = client->adapter->algo_data; |
431 | 444 | ||
432 | switch (client->addr << 1) { | 445 | switch (client->addr << 1) { |
433 | case 0x86: | 446 | case 0x86: |
434 | case 0x84: | 447 | case 0x84: |
435 | case 0x96: | 448 | case 0x96: |
436 | case 0x94: | 449 | case 0x94: |
437 | { | 450 | { |
438 | struct v4l2_priv_tun_config tda9887_cfg; | 451 | struct v4l2_priv_tun_config tda9887_cfg; |
439 | 452 | ||
440 | struct tuner_setup tun_setup; | 453 | struct tuner_setup tun_setup; |
441 | 454 | ||
442 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; | 455 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; |
443 | tun_setup.type = TUNER_TDA9887; | 456 | tun_setup.type = TUNER_TDA9887; |
444 | tun_setup.addr = client->addr; | 457 | tun_setup.addr = client->addr; |
445 | 458 | ||
446 | em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); | 459 | em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, |
447 | 460 | &tun_setup); | |
448 | tda9887_cfg.tuner = TUNER_TDA9887; | 461 | |
449 | tda9887_cfg.priv = &dev->tda9887_conf; | 462 | tda9887_cfg.tuner = TUNER_TDA9887; |
450 | em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, | 463 | tda9887_cfg.priv = &dev->tda9887_conf; |
451 | &tda9887_cfg); | 464 | em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, |
452 | break; | 465 | &tda9887_cfg); |
453 | } | 466 | break; |
454 | case 0x42: | 467 | } |
455 | dprintk1(1,"attach_inform: saa7114 detected.\n"); | 468 | case 0x42: |
456 | break; | 469 | dprintk1(1, "attach_inform: saa7114 detected.\n"); |
457 | case 0x4a: | 470 | break; |
458 | dprintk1(1,"attach_inform: saa7113 detected.\n"); | 471 | case 0x4a: |
459 | break; | 472 | dprintk1(1, "attach_inform: saa7113 detected.\n"); |
460 | case 0xa0: | 473 | break; |
461 | dprintk1(1,"attach_inform: eeprom detected.\n"); | 474 | case 0xa0: |
462 | break; | 475 | dprintk1(1, "attach_inform: eeprom detected.\n"); |
463 | case 0x60: | 476 | break; |
464 | case 0x8e: | 477 | case 0x60: |
465 | { | 478 | case 0x8e: |
466 | struct IR_i2c *ir = i2c_get_clientdata(client); | 479 | { |
467 | dprintk1(1,"attach_inform: IR detected (%s).\n",ir->phys); | 480 | struct IR_i2c *ir = i2c_get_clientdata(client); |
468 | em28xx_set_ir(dev,ir); | 481 | dprintk1(1, "attach_inform: IR detected (%s).\n", |
469 | break; | 482 | ir->phys); |
470 | } | 483 | em28xx_set_ir(dev, ir); |
471 | case 0x80: | 484 | break; |
472 | case 0x88: | 485 | } |
473 | dprintk1(1,"attach_inform: msp34xx detected.\n"); | 486 | case 0x80: |
474 | break; | 487 | case 0x88: |
475 | case 0xb8: | 488 | dprintk1(1, "attach_inform: msp34xx detected.\n"); |
476 | case 0xba: | 489 | break; |
477 | dprintk1(1,"attach_inform: tvp5150 detected.\n"); | 490 | case 0xb8: |
478 | break; | 491 | case 0xba: |
479 | 492 | dprintk1(1, "attach_inform: tvp5150 detected.\n"); | |
480 | default: | 493 | break; |
481 | if (!dev->tuner_addr) | 494 | |
482 | dev->tuner_addr = client->addr; | 495 | default: |
483 | 496 | if (!dev->tuner_addr) | |
484 | dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1); | 497 | dev->tuner_addr = client->addr; |
498 | |||
499 | dprintk1(1, "attach inform: detected I2C address %x\n", | ||
500 | client->addr << 1); | ||
485 | 501 | ||
486 | } | 502 | } |
487 | 503 | ||
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 10da2fd8d987..bb5807159b8d 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -32,10 +32,12 @@ | |||
32 | 32 | ||
33 | static unsigned int ir_debug; | 33 | static unsigned int ir_debug; |
34 | module_param(ir_debug, int, 0644); | 34 | module_param(ir_debug, int, 0644); |
35 | MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); | 35 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); |
36 | 36 | ||
37 | #define dprintk(fmt, arg...) if (ir_debug) \ | 37 | #define dprintk(fmt, arg...) \ |
38 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) | 38 | if (ir_debug) { \ |
39 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \ | ||
40 | } | ||
39 | 41 | ||
40 | /* ----------------------------------------------------------------------- */ | 42 | /* ----------------------------------------------------------------------- */ |
41 | 43 | ||
@@ -44,7 +46,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
44 | unsigned char b; | 46 | unsigned char b; |
45 | 47 | ||
46 | /* poll IR chip */ | 48 | /* poll IR chip */ |
47 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 49 | if (1 != i2c_master_recv(&ir->c, &b, 1)) { |
48 | dprintk("read error\n"); | 50 | dprintk("read error\n"); |
49 | return -EIO; | 51 | return -EIO; |
50 | } | 52 | } |
@@ -74,24 +76,25 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
74 | unsigned char code; | 76 | unsigned char code; |
75 | 77 | ||
76 | /* poll IR chip */ | 78 | /* poll IR chip */ |
77 | if (2 != i2c_master_recv(&ir->c,buf,2)) | 79 | if (2 != i2c_master_recv(&ir->c, buf, 2)) |
78 | return -EIO; | 80 | return -EIO; |
79 | 81 | ||
80 | /* Does eliminate repeated parity code */ | 82 | /* Does eliminate repeated parity code */ |
81 | if (buf[1]==0xff) | 83 | if (buf[1] == 0xff) |
82 | return 0; | 84 | return 0; |
83 | 85 | ||
84 | ir->old=buf[1]; | 86 | ir->old = buf[1]; |
85 | 87 | ||
86 | /* Rearranges bits to the right order */ | 88 | /* Rearranges bits to the right order */ |
87 | code= ((buf[0]&0x01)<<5) | /* 0010 0000 */ | 89 | code = ((buf[0]&0x01)<<5) | /* 0010 0000 */ |
88 | ((buf[0]&0x02)<<3) | /* 0001 0000 */ | 90 | ((buf[0]&0x02)<<3) | /* 0001 0000 */ |
89 | ((buf[0]&0x04)<<1) | /* 0000 1000 */ | 91 | ((buf[0]&0x04)<<1) | /* 0000 1000 */ |
90 | ((buf[0]&0x08)>>1) | /* 0000 0100 */ | 92 | ((buf[0]&0x08)>>1) | /* 0000 0100 */ |
91 | ((buf[0]&0x10)>>3) | /* 0000 0010 */ | 93 | ((buf[0]&0x10)>>3) | /* 0000 0010 */ |
92 | ((buf[0]&0x20)>>5); /* 0000 0001 */ | 94 | ((buf[0]&0x20)>>5); /* 0000 0001 */ |
93 | 95 | ||
94 | dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",code,buf[0]); | 96 | dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n", |
97 | code, buf[0]); | ||
95 | 98 | ||
96 | /* return key */ | 99 | /* return key */ |
97 | *ir_key = code; | 100 | *ir_key = code; |
@@ -106,15 +109,14 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, | |||
106 | 109 | ||
107 | /* poll IR chip */ | 110 | /* poll IR chip */ |
108 | 111 | ||
109 | if (3 != i2c_master_recv(&ir->c,buf,3)) { | 112 | if (3 != i2c_master_recv(&ir->c, buf, 3)) { |
110 | dprintk("read error\n"); | 113 | dprintk("read error\n"); |
111 | return -EIO; | 114 | return -EIO; |
112 | } | 115 | } |
113 | 116 | ||
114 | dprintk("key %02x\n", buf[2]&0x3f); | 117 | dprintk("key %02x\n", buf[2]&0x3f); |
115 | if (buf[0]!=0x00){ | 118 | if (buf[0] != 0x00) |
116 | return 0; | 119 | return 0; |
117 | } | ||
118 | 120 | ||
119 | *ir_key = buf[2]&0x3f; | 121 | *ir_key = buf[2]&0x3f; |
120 | *ir_raw = buf[2]&0x3f; | 122 | *ir_raw = buf[2]&0x3f; |
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h new file mode 100644 index 000000000000..9058bed07953 --- /dev/null +++ b/drivers/media/video/em28xx/em28xx-reg.h | |||
@@ -0,0 +1,88 @@ | |||
1 | #define EM_GPIO_0 (1 << 0) | ||
2 | #define EM_GPIO_1 (1 << 1) | ||
3 | #define EM_GPIO_2 (1 << 2) | ||
4 | #define EM_GPIO_3 (1 << 3) | ||
5 | #define EM_GPIO_4 (1 << 4) | ||
6 | #define EM_GPIO_5 (1 << 5) | ||
7 | #define EM_GPIO_6 (1 << 6) | ||
8 | #define EM_GPIO_7 (1 << 7) | ||
9 | |||
10 | #define EM_GPO_0 (1 << 0) | ||
11 | #define EM_GPO_1 (1 << 1) | ||
12 | #define EM_GPO_2 (1 << 2) | ||
13 | #define EM_GPO_3 (1 << 3) | ||
14 | |||
15 | /* em2800 registers */ | ||
16 | #define EM2800_R08_AUDIOSRC 0x08 | ||
17 | |||
18 | /* em28xx registers */ | ||
19 | |||
20 | /* GPIO/GPO registers */ | ||
21 | #define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ | ||
22 | #define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ | ||
23 | |||
24 | #define EM28XX_R06_I2C_CLK 0x06 | ||
25 | #define EM28XX_R0A_CHIPID 0x0a | ||
26 | #define EM28XX_R0C_USBSUSP 0x0c /* */ | ||
27 | |||
28 | #define EM28XX_R0E_AUDIOSRC 0x0e | ||
29 | #define EM28XX_R0F_XCLK 0x0f | ||
30 | |||
31 | #define EM28XX_R10_VINMODE 0x10 | ||
32 | #define EM28XX_R11_VINCTRL 0x11 | ||
33 | #define EM28XX_R12_VINENABLE 0x12 /* */ | ||
34 | |||
35 | #define EM28XX_R14_GAMMA 0x14 | ||
36 | #define EM28XX_R15_RGAIN 0x15 | ||
37 | #define EM28XX_R16_GGAIN 0x16 | ||
38 | #define EM28XX_R17_BGAIN 0x17 | ||
39 | #define EM28XX_R18_ROFFSET 0x18 | ||
40 | #define EM28XX_R19_GOFFSET 0x19 | ||
41 | #define EM28XX_R1A_BOFFSET 0x1a | ||
42 | |||
43 | #define EM28XX_R1B_OFLOW 0x1b | ||
44 | #define EM28XX_R1C_HSTART 0x1c | ||
45 | #define EM28XX_R1D_VSTART 0x1d | ||
46 | #define EM28XX_R1E_CWIDTH 0x1e | ||
47 | #define EM28XX_R1F_CHEIGHT 0x1f | ||
48 | |||
49 | #define EM28XX_R20_YGAIN 0x20 | ||
50 | #define EM28XX_R21_YOFFSET 0x21 | ||
51 | #define EM28XX_R22_UVGAIN 0x22 | ||
52 | #define EM28XX_R23_UOFFSET 0x23 | ||
53 | #define EM28XX_R24_VOFFSET 0x24 | ||
54 | #define EM28XX_R25_SHARPNESS 0x25 | ||
55 | |||
56 | #define EM28XX_R26_COMPR 0x26 | ||
57 | #define EM28XX_R27_OUTFMT 0x27 | ||
58 | |||
59 | #define EM28XX_R28_XMIN 0x28 | ||
60 | #define EM28XX_R29_XMAX 0x29 | ||
61 | #define EM28XX_R2A_YMIN 0x2a | ||
62 | #define EM28XX_R2B_YMAX 0x2b | ||
63 | |||
64 | #define EM28XX_R30_HSCALELOW 0x30 | ||
65 | #define EM28XX_R31_HSCALEHIGH 0x31 | ||
66 | #define EM28XX_R32_VSCALELOW 0x32 | ||
67 | #define EM28XX_R33_VSCALEHIGH 0x33 | ||
68 | |||
69 | #define EM28XX_R40_AC97LSB 0x40 | ||
70 | #define EM28XX_R41_AC97MSB 0x41 | ||
71 | #define EM28XX_R42_AC97ADDR 0x42 | ||
72 | #define EM28XX_R43_AC97BUSY 0x43 | ||
73 | |||
74 | /* em202 registers */ | ||
75 | #define EM28XX_R02_MASTER_AC97 0x02 | ||
76 | #define EM28XX_R10_LINE_IN_AC97 0x10 | ||
77 | #define EM28XX_R14_VIDEO_AC97 0x14 | ||
78 | |||
79 | /* register settings */ | ||
80 | #define EM2800_AUDIO_SRC_TUNER 0x0d | ||
81 | #define EM2800_AUDIO_SRC_LINE 0x0c | ||
82 | #define EM28XX_AUDIO_SRC_TUNER 0xc0 | ||
83 | #define EM28XX_AUDIO_SRC_LINE 0x80 | ||
84 | |||
85 | /* FIXME: Need to be populated with the other chip ID's */ | ||
86 | enum em28xx_chip_id { | ||
87 | CHIP_ID_EM2883 = 36, | ||
88 | }; | ||
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 4abe6701a770..8996175cc950 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | 2 | em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB |
3 | video capture devices | ||
3 | 4 | ||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 5 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
5 | Markus Rechberger <mrechberger@gmail.com> | 6 | Markus Rechberger <mrechberger@gmail.com> |
@@ -52,7 +53,19 @@ | |||
52 | #define em28xx_videodbg(fmt, arg...) do {\ | 53 | #define em28xx_videodbg(fmt, arg...) do {\ |
53 | if (video_debug) \ | 54 | if (video_debug) \ |
54 | printk(KERN_INFO "%s %s :"fmt, \ | 55 | printk(KERN_INFO "%s %s :"fmt, \ |
55 | dev->name, __FUNCTION__ , ##arg); } while (0) | 56 | dev->name, __func__ , ##arg); } while (0) |
57 | |||
58 | static unsigned int isoc_debug; | ||
59 | module_param(isoc_debug, int, 0644); | ||
60 | MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]"); | ||
61 | |||
62 | #define em28xx_isocdbg(fmt, arg...) \ | ||
63 | do {\ | ||
64 | if (isoc_debug) { \ | ||
65 | printk(KERN_INFO "%s %s :"fmt, \ | ||
66 | dev->name, __func__ , ##arg); \ | ||
67 | } \ | ||
68 | } while (0) | ||
56 | 69 | ||
57 | MODULE_AUTHOR(DRIVER_AUTHOR); | 70 | MODULE_AUTHOR(DRIVER_AUTHOR); |
58 | MODULE_DESCRIPTION(DRIVER_DESC); | 71 | MODULE_DESCRIPTION(DRIVER_DESC); |
@@ -74,9 +87,9 @@ MODULE_PARM_DESC(video_nr, "video device numbers"); | |||
74 | MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); | 87 | MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); |
75 | MODULE_PARM_DESC(radio_nr, "radio device numbers"); | 88 | MODULE_PARM_DESC(radio_nr, "radio device numbers"); |
76 | 89 | ||
77 | static unsigned int video_debug = 0; | 90 | static unsigned int video_debug; |
78 | module_param(video_debug,int,0644); | 91 | module_param(video_debug, int, 0644); |
79 | MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); | 92 | MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); |
80 | 93 | ||
81 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ | 94 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ |
82 | static unsigned long em28xx_devused; | 95 | static unsigned long em28xx_devused; |
@@ -93,7 +106,7 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { | |||
93 | .step = 0x1, | 106 | .step = 0x1, |
94 | .default_value = 0x1f, | 107 | .default_value = 0x1f, |
95 | .flags = 0, | 108 | .flags = 0, |
96 | },{ | 109 | }, { |
97 | .id = V4L2_CID_AUDIO_MUTE, | 110 | .id = V4L2_CID_AUDIO_MUTE, |
98 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 111 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
99 | .name = "Mute", | 112 | .name = "Mute", |
@@ -107,8 +120,391 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { | |||
107 | 120 | ||
108 | static struct usb_driver em28xx_usb_driver; | 121 | static struct usb_driver em28xx_usb_driver; |
109 | 122 | ||
123 | /* ------------------------------------------------------------------ | ||
124 | DMA and thread functions | ||
125 | ------------------------------------------------------------------*/ | ||
126 | |||
127 | /* | ||
128 | * Announces that a buffer were filled and request the next | ||
129 | */ | ||
130 | static inline void buffer_filled(struct em28xx *dev, | ||
131 | struct em28xx_dmaqueue *dma_q, | ||
132 | struct em28xx_buffer *buf) | ||
133 | { | ||
134 | /* Advice that buffer was filled */ | ||
135 | em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i); | ||
136 | buf->vb.state = VIDEOBUF_DONE; | ||
137 | buf->vb.field_count++; | ||
138 | do_gettimeofday(&buf->vb.ts); | ||
110 | 139 | ||
111 | /********************* v4l2 interface ******************************************/ | 140 | dev->isoc_ctl.buf = NULL; |
141 | |||
142 | list_del(&buf->vb.queue); | ||
143 | wake_up(&buf->vb.done); | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * Identify the buffer header type and properly handles | ||
148 | */ | ||
149 | static void em28xx_copy_video(struct em28xx *dev, | ||
150 | struct em28xx_dmaqueue *dma_q, | ||
151 | struct em28xx_buffer *buf, | ||
152 | unsigned char *p, | ||
153 | unsigned char *outp, unsigned long len) | ||
154 | { | ||
155 | void *fieldstart, *startwrite, *startread; | ||
156 | int linesdone, currlinedone, offset, lencopy, remain; | ||
157 | int bytesperline = dev->width << 1; | ||
158 | |||
159 | if (dma_q->pos + len > buf->vb.size) | ||
160 | len = buf->vb.size - dma_q->pos; | ||
161 | |||
162 | if (p[0] != 0x88 && p[0] != 0x22) { | ||
163 | em28xx_isocdbg("frame is not complete\n"); | ||
164 | len += 4; | ||
165 | } else | ||
166 | p += 4; | ||
167 | |||
168 | startread = p; | ||
169 | remain = len; | ||
170 | |||
171 | /* Interlaces frame */ | ||
172 | if (buf->top_field) | ||
173 | fieldstart = outp; | ||
174 | else | ||
175 | fieldstart = outp + bytesperline; | ||
176 | |||
177 | linesdone = dma_q->pos / bytesperline; | ||
178 | currlinedone = dma_q->pos % bytesperline; | ||
179 | offset = linesdone * bytesperline * 2 + currlinedone; | ||
180 | startwrite = fieldstart + offset; | ||
181 | lencopy = bytesperline - currlinedone; | ||
182 | lencopy = lencopy > remain ? remain : lencopy; | ||
183 | |||
184 | if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) { | ||
185 | em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n", | ||
186 | ((char *)startwrite + lencopy) - | ||
187 | ((char *)outp + buf->vb.size)); | ||
188 | lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite; | ||
189 | } | ||
190 | if (lencopy <= 0) | ||
191 | return; | ||
192 | memcpy(startwrite, startread, lencopy); | ||
193 | |||
194 | remain -= lencopy; | ||
195 | |||
196 | while (remain > 0) { | ||
197 | startwrite += lencopy + bytesperline; | ||
198 | startread += lencopy; | ||
199 | if (bytesperline > remain) | ||
200 | lencopy = remain; | ||
201 | else | ||
202 | lencopy = bytesperline; | ||
203 | |||
204 | if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) { | ||
205 | em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n", | ||
206 | ((char *)startwrite + lencopy) - | ||
207 | ((char *)outp + buf->vb.size)); | ||
208 | lencopy = remain = (char *)outp + buf->vb.size - | ||
209 | (char *)startwrite; | ||
210 | } | ||
211 | if (lencopy <= 0) | ||
212 | break; | ||
213 | |||
214 | memcpy(startwrite, startread, lencopy); | ||
215 | |||
216 | remain -= lencopy; | ||
217 | } | ||
218 | |||
219 | dma_q->pos += len; | ||
220 | } | ||
221 | |||
222 | static inline void print_err_status(struct em28xx *dev, | ||
223 | int packet, int status) | ||
224 | { | ||
225 | char *errmsg = "Unknown"; | ||
226 | |||
227 | switch (status) { | ||
228 | case -ENOENT: | ||
229 | errmsg = "unlinked synchronuously"; | ||
230 | break; | ||
231 | case -ECONNRESET: | ||
232 | errmsg = "unlinked asynchronuously"; | ||
233 | break; | ||
234 | case -ENOSR: | ||
235 | errmsg = "Buffer error (overrun)"; | ||
236 | break; | ||
237 | case -EPIPE: | ||
238 | errmsg = "Stalled (device not responding)"; | ||
239 | break; | ||
240 | case -EOVERFLOW: | ||
241 | errmsg = "Babble (bad cable?)"; | ||
242 | break; | ||
243 | case -EPROTO: | ||
244 | errmsg = "Bit-stuff error (bad cable?)"; | ||
245 | break; | ||
246 | case -EILSEQ: | ||
247 | errmsg = "CRC/Timeout (could be anything)"; | ||
248 | break; | ||
249 | case -ETIME: | ||
250 | errmsg = "Device does not respond"; | ||
251 | break; | ||
252 | } | ||
253 | if (packet < 0) { | ||
254 | em28xx_isocdbg("URB status %d [%s].\n", status, errmsg); | ||
255 | } else { | ||
256 | em28xx_isocdbg("URB packet %d, status %d [%s].\n", | ||
257 | packet, status, errmsg); | ||
258 | } | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * video-buf generic routine to get the next available buffer | ||
263 | */ | ||
264 | static inline void get_next_buf(struct em28xx_dmaqueue *dma_q, | ||
265 | struct em28xx_buffer **buf) | ||
266 | { | ||
267 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); | ||
268 | char *outp; | ||
269 | |||
270 | if (list_empty(&dma_q->active)) { | ||
271 | em28xx_isocdbg("No active queue to serve\n"); | ||
272 | dev->isoc_ctl.buf = NULL; | ||
273 | *buf = NULL; | ||
274 | return; | ||
275 | } | ||
276 | |||
277 | /* Get the next buffer */ | ||
278 | *buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue); | ||
279 | |||
280 | /* Cleans up buffer - Usefull for testing for frame/URB loss */ | ||
281 | outp = videobuf_to_vmalloc(&(*buf)->vb); | ||
282 | memset(outp, 0, (*buf)->vb.size); | ||
283 | |||
284 | dev->isoc_ctl.buf = *buf; | ||
285 | |||
286 | return; | ||
287 | } | ||
288 | |||
289 | /* | ||
290 | * Controls the isoc copy of each urb packet | ||
291 | */ | ||
292 | static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) | ||
293 | { | ||
294 | struct em28xx_buffer *buf; | ||
295 | struct em28xx_dmaqueue *dma_q = urb->context; | ||
296 | unsigned char *outp = NULL; | ||
297 | int i, len = 0, rc = 1; | ||
298 | unsigned char *p; | ||
299 | |||
300 | if (!dev) | ||
301 | return 0; | ||
302 | |||
303 | if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) | ||
304 | return 0; | ||
305 | |||
306 | if (urb->status < 0) { | ||
307 | print_err_status(dev, -1, urb->status); | ||
308 | if (urb->status == -ENOENT) | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | buf = dev->isoc_ctl.buf; | ||
313 | if (buf != NULL) | ||
314 | outp = videobuf_to_vmalloc(&buf->vb); | ||
315 | |||
316 | for (i = 0; i < urb->number_of_packets; i++) { | ||
317 | int status = urb->iso_frame_desc[i].status; | ||
318 | |||
319 | if (status < 0) { | ||
320 | print_err_status(dev, i, status); | ||
321 | if (urb->iso_frame_desc[i].status != -EPROTO) | ||
322 | continue; | ||
323 | } | ||
324 | |||
325 | len = urb->iso_frame_desc[i].actual_length - 4; | ||
326 | |||
327 | if (urb->iso_frame_desc[i].actual_length <= 0) { | ||
328 | /* em28xx_isocdbg("packet %d is empty",i); - spammy */ | ||
329 | continue; | ||
330 | } | ||
331 | if (urb->iso_frame_desc[i].actual_length > | ||
332 | dev->max_pkt_size) { | ||
333 | em28xx_isocdbg("packet bigger than packet size"); | ||
334 | continue; | ||
335 | } | ||
336 | |||
337 | p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | ||
338 | |||
339 | /* FIXME: incomplete buffer checks where removed to make | ||
340 | logic simpler. Impacts of those changes should be evaluated | ||
341 | */ | ||
342 | if (p[0] == 0x33 && p[1] == 0x95 && p[2] == 0x00) { | ||
343 | em28xx_isocdbg("VBI HEADER!!!\n"); | ||
344 | /* FIXME: Should add vbi copy */ | ||
345 | continue; | ||
346 | } | ||
347 | if (p[0] == 0x22 && p[1] == 0x5a) { | ||
348 | em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2], | ||
349 | len, (p[2] & 1)? "odd" : "even"); | ||
350 | |||
351 | if (!(p[2] & 1)) { | ||
352 | if (buf != NULL) | ||
353 | buffer_filled(dev, dma_q, buf); | ||
354 | get_next_buf(dma_q, &buf); | ||
355 | if (buf == NULL) | ||
356 | outp = NULL; | ||
357 | else | ||
358 | outp = videobuf_to_vmalloc(&buf->vb); | ||
359 | } | ||
360 | |||
361 | if (buf != NULL) { | ||
362 | if (p[2] & 1) | ||
363 | buf->top_field = 0; | ||
364 | else | ||
365 | buf->top_field = 1; | ||
366 | } | ||
367 | |||
368 | dma_q->pos = 0; | ||
369 | } | ||
370 | if (buf != NULL) | ||
371 | em28xx_copy_video(dev, dma_q, buf, p, outp, len); | ||
372 | } | ||
373 | return rc; | ||
374 | } | ||
375 | |||
376 | /* ------------------------------------------------------------------ | ||
377 | Videobuf operations | ||
378 | ------------------------------------------------------------------*/ | ||
379 | |||
380 | static int | ||
381 | buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | ||
382 | { | ||
383 | struct em28xx_fh *fh = vq->priv_data; | ||
384 | struct em28xx *dev = fh->dev; | ||
385 | struct v4l2_frequency f; | ||
386 | |||
387 | *size = 16 * fh->dev->width * fh->dev->height >> 3; | ||
388 | if (0 == *count) | ||
389 | *count = EM28XX_DEF_BUF; | ||
390 | |||
391 | if (*count < EM28XX_MIN_BUF) | ||
392 | *count = EM28XX_MIN_BUF; | ||
393 | |||
394 | /* Ask tuner to go to analog mode */ | ||
395 | memset(&f, 0, sizeof(f)); | ||
396 | f.frequency = dev->ctl_freq; | ||
397 | |||
398 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f); | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | /* This is called *without* dev->slock held; please keep it that way */ | ||
404 | static void free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf) | ||
405 | { | ||
406 | struct em28xx_fh *fh = vq->priv_data; | ||
407 | struct em28xx *dev = fh->dev; | ||
408 | unsigned long flags = 0; | ||
409 | if (in_interrupt()) | ||
410 | BUG(); | ||
411 | |||
412 | /* We used to wait for the buffer to finish here, but this didn't work | ||
413 | because, as we were keeping the state as VIDEOBUF_QUEUED, | ||
414 | videobuf_queue_cancel marked it as finished for us. | ||
415 | (Also, it could wedge forever if the hardware was misconfigured.) | ||
416 | |||
417 | This should be safe; by the time we get here, the buffer isn't | ||
418 | queued anymore. If we ever start marking the buffers as | ||
419 | VIDEOBUF_ACTIVE, it won't be, though. | ||
420 | */ | ||
421 | spin_lock_irqsave(&dev->slock, flags); | ||
422 | if (dev->isoc_ctl.buf == buf) | ||
423 | dev->isoc_ctl.buf = NULL; | ||
424 | spin_unlock_irqrestore(&dev->slock, flags); | ||
425 | |||
426 | videobuf_vmalloc_free(&buf->vb); | ||
427 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
428 | } | ||
429 | |||
430 | static int | ||
431 | buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | ||
432 | enum v4l2_field field) | ||
433 | { | ||
434 | struct em28xx_fh *fh = vq->priv_data; | ||
435 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | ||
436 | struct em28xx *dev = fh->dev; | ||
437 | int rc = 0, urb_init = 0; | ||
438 | |||
439 | /* FIXME: It assumes depth = 16 */ | ||
440 | /* The only currently supported format is 16 bits/pixel */ | ||
441 | buf->vb.size = 16 * dev->width * dev->height >> 3; | ||
442 | |||
443 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | ||
444 | return -EINVAL; | ||
445 | |||
446 | buf->vb.width = dev->width; | ||
447 | buf->vb.height = dev->height; | ||
448 | buf->vb.field = field; | ||
449 | |||
450 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | ||
451 | rc = videobuf_iolock(vq, &buf->vb, NULL); | ||
452 | if (rc < 0) | ||
453 | goto fail; | ||
454 | } | ||
455 | |||
456 | if (!dev->isoc_ctl.num_bufs) | ||
457 | urb_init = 1; | ||
458 | |||
459 | if (urb_init) { | ||
460 | rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS, | ||
461 | EM28XX_NUM_BUFS, dev->max_pkt_size, | ||
462 | em28xx_isoc_copy); | ||
463 | if (rc < 0) | ||
464 | goto fail; | ||
465 | } | ||
466 | |||
467 | buf->vb.state = VIDEOBUF_PREPARED; | ||
468 | return 0; | ||
469 | |||
470 | fail: | ||
471 | free_buffer(vq, buf); | ||
472 | return rc; | ||
473 | } | ||
474 | |||
475 | static void | ||
476 | buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | ||
477 | { | ||
478 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | ||
479 | struct em28xx_fh *fh = vq->priv_data; | ||
480 | struct em28xx *dev = fh->dev; | ||
481 | struct em28xx_dmaqueue *vidq = &dev->vidq; | ||
482 | |||
483 | buf->vb.state = VIDEOBUF_QUEUED; | ||
484 | list_add_tail(&buf->vb.queue, &vidq->active); | ||
485 | |||
486 | } | ||
487 | |||
488 | static void buffer_release(struct videobuf_queue *vq, | ||
489 | struct videobuf_buffer *vb) | ||
490 | { | ||
491 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | ||
492 | struct em28xx_fh *fh = vq->priv_data; | ||
493 | struct em28xx *dev = (struct em28xx *)fh->dev; | ||
494 | |||
495 | em28xx_isocdbg("em28xx: called buffer_release\n"); | ||
496 | |||
497 | free_buffer(vq, buf); | ||
498 | } | ||
499 | |||
500 | static struct videobuf_queue_ops em28xx_video_qops = { | ||
501 | .buf_setup = buffer_setup, | ||
502 | .buf_prepare = buffer_prepare, | ||
503 | .buf_queue = buffer_queue, | ||
504 | .buf_release = buffer_release, | ||
505 | }; | ||
506 | |||
507 | /********************* v4l2 interface **************************************/ | ||
112 | 508 | ||
113 | /* | 509 | /* |
114 | * em28xx_config() | 510 | * em28xx_config() |
@@ -123,9 +519,9 @@ static int em28xx_config(struct em28xx *dev) | |||
123 | 519 | ||
124 | /* enable vbi capturing */ | 520 | /* enable vbi capturing */ |
125 | 521 | ||
126 | /* em28xx_write_regs_req(dev,0x00,0x0e,"\xC0",1); audio register */ | 522 | /* em28xx_write_regs_req(dev, 0x00, 0x0e, "\xC0", 1); audio register */ |
127 | /* em28xx_write_regs_req(dev,0x00,0x0f,"\x80",1); clk register */ | 523 | /* em28xx_write_regs_req(dev, 0x00, 0x0f, "\x80", 1); clk register */ |
128 | em28xx_write_regs_req(dev,0x00,0x11,"\x51",1); | 524 | em28xx_write_regs_req(dev, 0x00, 0x11, "\x51", 1); |
129 | 525 | ||
130 | dev->mute = 1; /* maybe not the right place... */ | 526 | dev->mute = 1; /* maybe not the right place... */ |
131 | dev->volume = 0x1f; | 527 | dev->volume = 0x1f; |
@@ -152,23 +548,6 @@ static void em28xx_config_i2c(struct em28xx *dev) | |||
152 | em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); | 548 | em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); |
153 | } | 549 | } |
154 | 550 | ||
155 | /* | ||
156 | * em28xx_empty_framequeues() | ||
157 | * prepare queues for incoming and outgoing frames | ||
158 | */ | ||
159 | static void em28xx_empty_framequeues(struct em28xx *dev) | ||
160 | { | ||
161 | u32 i; | ||
162 | |||
163 | INIT_LIST_HEAD(&dev->inqueue); | ||
164 | INIT_LIST_HEAD(&dev->outqueue); | ||
165 | |||
166 | for (i = 0; i < EM28XX_NUM_FRAMES; i++) { | ||
167 | dev->frame[i].state = F_UNUSED; | ||
168 | dev->frame[i].buf.bytesused = 0; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | static void video_mux(struct em28xx *dev, int index) | 551 | static void video_mux(struct em28xx *dev, int index) |
173 | { | 552 | { |
174 | struct v4l2_routing route; | 553 | struct v4l2_routing route; |
@@ -181,12 +560,15 @@ static void video_mux(struct em28xx *dev, int index) | |||
181 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); | 560 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); |
182 | 561 | ||
183 | if (dev->has_msp34xx) { | 562 | if (dev->has_msp34xx) { |
184 | if (dev->i2s_speed) | 563 | if (dev->i2s_speed) { |
185 | em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); | 564 | em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, |
565 | &dev->i2s_speed); | ||
566 | } | ||
186 | route.input = dev->ctl_ainput; | 567 | route.input = dev->ctl_ainput; |
187 | route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); | 568 | route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); |
188 | /* Note: this is msp3400 specific */ | 569 | /* Note: this is msp3400 specific */ |
189 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route); | 570 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, |
571 | &route); | ||
190 | } | 572 | } |
191 | 573 | ||
192 | em28xx_audio_analog_set(dev); | 574 | em28xx_audio_analog_set(dev); |
@@ -202,15 +584,12 @@ static int res_get(struct em28xx_fh *fh) | |||
202 | if (fh->stream_on) | 584 | if (fh->stream_on) |
203 | return rc; | 585 | return rc; |
204 | 586 | ||
205 | mutex_lock(&dev->lock); | ||
206 | |||
207 | if (dev->stream_on) | 587 | if (dev->stream_on) |
208 | rc = -EINVAL; | 588 | return -EINVAL; |
209 | else { | ||
210 | dev->stream_on = 1; | ||
211 | fh->stream_on = 1; | ||
212 | } | ||
213 | 589 | ||
590 | mutex_lock(&dev->lock); | ||
591 | dev->stream_on = 1; | ||
592 | fh->stream_on = 1; | ||
214 | mutex_unlock(&dev->lock); | 593 | mutex_unlock(&dev->lock); |
215 | return rc; | 594 | return rc; |
216 | } | 595 | } |
@@ -231,33 +610,6 @@ static void res_free(struct em28xx_fh *fh) | |||
231 | } | 610 | } |
232 | 611 | ||
233 | /* | 612 | /* |
234 | * em28xx_vm_open() | ||
235 | */ | ||
236 | static void em28xx_vm_open(struct vm_area_struct *vma) | ||
237 | { | ||
238 | struct em28xx_frame_t *f = vma->vm_private_data; | ||
239 | f->vma_use_count++; | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * em28xx_vm_close() | ||
244 | */ | ||
245 | static void em28xx_vm_close(struct vm_area_struct *vma) | ||
246 | { | ||
247 | /* NOTE: buffers are not freed here */ | ||
248 | struct em28xx_frame_t *f = vma->vm_private_data; | ||
249 | |||
250 | if (f->vma_use_count) | ||
251 | f->vma_use_count--; | ||
252 | } | ||
253 | |||
254 | static struct vm_operations_struct em28xx_vm_ops = { | ||
255 | .open = em28xx_vm_open, | ||
256 | .close = em28xx_vm_close, | ||
257 | }; | ||
258 | |||
259 | |||
260 | /* | ||
261 | * em28xx_get_ctrl() | 613 | * em28xx_get_ctrl() |
262 | * return the current saturation, brightness or contrast, mute state | 614 | * return the current saturation, brightness or contrast, mute state |
263 | */ | 615 | */ |
@@ -296,34 +648,6 @@ static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) | |||
296 | } | 648 | } |
297 | } | 649 | } |
298 | 650 | ||
299 | /* | ||
300 | * em28xx_stream_interrupt() | ||
301 | * stops streaming | ||
302 | */ | ||
303 | static int em28xx_stream_interrupt(struct em28xx *dev) | ||
304 | { | ||
305 | int rc = 0; | ||
306 | |||
307 | /* stop reading from the device */ | ||
308 | |||
309 | dev->stream = STREAM_INTERRUPT; | ||
310 | rc = wait_event_timeout(dev->wait_stream, | ||
311 | (dev->stream == STREAM_OFF) || | ||
312 | (dev->state & DEV_DISCONNECTED), | ||
313 | EM28XX_URB_TIMEOUT); | ||
314 | |||
315 | if (rc) { | ||
316 | dev->state |= DEV_MISCONFIGURED; | ||
317 | em28xx_videodbg("device is misconfigured; close and " | ||
318 | "open /dev/video%d again\n", | ||
319 | dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN); | ||
320 | return rc; | ||
321 | } | ||
322 | |||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | |||
327 | static int check_dev(struct em28xx *dev) | 651 | static int check_dev(struct em28xx *dev) |
328 | { | 652 | { |
329 | if (dev->state & DEV_DISCONNECTED) { | 653 | if (dev->state & DEV_DISCONNECTED) { |
@@ -370,8 +694,8 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, | |||
370 | f->fmt.pix.width = dev->width; | 694 | f->fmt.pix.width = dev->width; |
371 | f->fmt.pix.height = dev->height; | 695 | f->fmt.pix.height = dev->height; |
372 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | 696 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; |
373 | f->fmt.pix.bytesperline = dev->bytesperline; | 697 | f->fmt.pix.bytesperline = dev->width * 2; |
374 | f->fmt.pix.sizeimage = dev->frame_size; | 698 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; |
375 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 699 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
376 | 700 | ||
377 | /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ | 701 | /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ |
@@ -447,7 +771,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
447 | { | 771 | { |
448 | struct em28xx_fh *fh = priv; | 772 | struct em28xx_fh *fh = priv; |
449 | struct em28xx *dev = fh->dev; | 773 | struct em28xx *dev = fh->dev; |
450 | int rc, i; | 774 | int rc; |
451 | 775 | ||
452 | rc = check_dev(dev); | 776 | rc = check_dev(dev); |
453 | if (rc < 0) | 777 | if (rc < 0) |
@@ -457,49 +781,34 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
457 | 781 | ||
458 | mutex_lock(&dev->lock); | 782 | mutex_lock(&dev->lock); |
459 | 783 | ||
460 | for (i = 0; i < dev->num_frames; i++) | 784 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { |
461 | if (dev->frame[i].vma_use_count) { | 785 | em28xx_errdev("%s queue busy\n", __func__); |
462 | em28xx_videodbg("VIDIOC_S_FMT failed. " | 786 | rc = -EBUSY; |
463 | "Unmap the buffers first.\n"); | 787 | goto out; |
464 | rc = -EINVAL; | ||
465 | goto err; | ||
466 | } | ||
467 | |||
468 | /* stop io in case it is already in progress */ | ||
469 | if (dev->stream == STREAM_ON) { | ||
470 | em28xx_videodbg("VIDIOC_SET_FMT: interrupting stream\n"); | ||
471 | rc = em28xx_stream_interrupt(dev); | ||
472 | if (rc < 0) | ||
473 | goto err; | ||
474 | } | 788 | } |
475 | 789 | ||
476 | em28xx_release_buffers(dev); | 790 | if (dev->stream_on && !fh->stream_on) { |
477 | dev->io = IO_NONE; | 791 | em28xx_errdev("%s device in use by another fh\n", __func__); |
792 | rc = -EBUSY; | ||
793 | goto out; | ||
794 | } | ||
478 | 795 | ||
479 | /* set new image size */ | 796 | /* set new image size */ |
480 | dev->width = f->fmt.pix.width; | 797 | dev->width = f->fmt.pix.width; |
481 | dev->height = f->fmt.pix.height; | 798 | dev->height = f->fmt.pix.height; |
482 | dev->frame_size = dev->width * dev->height * 2; | ||
483 | dev->field_size = dev->frame_size >> 1; | ||
484 | dev->bytesperline = dev->width * 2; | ||
485 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | 799 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); |
486 | 800 | ||
487 | /* FIXME: This is really weird! Why capture is starting with | ||
488 | this ioctl ??? | ||
489 | */ | ||
490 | em28xx_uninit_isoc(dev); | ||
491 | em28xx_set_alternate(dev); | 801 | em28xx_set_alternate(dev); |
492 | em28xx_capture_start(dev, 1); | ||
493 | em28xx_resolution_set(dev); | 802 | em28xx_resolution_set(dev); |
494 | em28xx_init_isoc(dev); | 803 | |
495 | rc = 0; | 804 | rc = 0; |
496 | 805 | ||
497 | err: | 806 | out: |
498 | mutex_unlock(&dev->lock); | 807 | mutex_unlock(&dev->lock); |
499 | return rc; | 808 | return rc; |
500 | } | 809 | } |
501 | 810 | ||
502 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) | 811 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) |
503 | { | 812 | { |
504 | struct em28xx_fh *fh = priv; | 813 | struct em28xx_fh *fh = priv; |
505 | struct em28xx *dev = fh->dev; | 814 | struct em28xx *dev = fh->dev; |
@@ -524,9 +833,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) | |||
524 | /* set new image size */ | 833 | /* set new image size */ |
525 | dev->width = f.fmt.pix.width; | 834 | dev->width = f.fmt.pix.width; |
526 | dev->height = f.fmt.pix.height; | 835 | dev->height = f.fmt.pix.height; |
527 | dev->frame_size = dev->width * dev->height * 2; | ||
528 | dev->field_size = dev->frame_size >> 1; | ||
529 | dev->bytesperline = dev->width * 2; | ||
530 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | 836 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); |
531 | 837 | ||
532 | em28xx_resolution_set(dev); | 838 | em28xx_resolution_set(dev); |
@@ -619,11 +925,11 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) | |||
619 | 925 | ||
620 | index = dev->ctl_ainput; | 926 | index = dev->ctl_ainput; |
621 | 927 | ||
622 | if (index == 0) { | 928 | if (index == 0) |
623 | strcpy(a->name, "Television"); | 929 | strcpy(a->name, "Television"); |
624 | } else { | 930 | else |
625 | strcpy(a->name, "Line In"); | 931 | strcpy(a->name, "Line In"); |
626 | } | 932 | |
627 | a->capability = V4L2_AUDCAP_STEREO; | 933 | a->capability = V4L2_AUDCAP_STEREO; |
628 | a->index = index; | 934 | a->index = index; |
629 | 935 | ||
@@ -834,9 +1140,9 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
834 | static int em28xx_reg_len(int reg) | 1140 | static int em28xx_reg_len(int reg) |
835 | { | 1141 | { |
836 | switch (reg) { | 1142 | switch (reg) { |
837 | case AC97LSB_REG: | 1143 | case EM28XX_R40_AC97LSB: |
838 | case HSCALELOW_REG: | 1144 | case EM28XX_R30_HSCALELOW: |
839 | case VSCALELOW_REG: | 1145 | case EM28XX_R32_VSCALELOW: |
840 | return 2; | 1146 | return 2; |
841 | default: | 1147 | default: |
842 | return 1; | 1148 | return 1; |
@@ -918,23 +1224,11 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
918 | if (rc < 0) | 1224 | if (rc < 0) |
919 | return rc; | 1225 | return rc; |
920 | 1226 | ||
921 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || dev->io != IO_MMAP) | ||
922 | return -EINVAL; | ||
923 | |||
924 | if (list_empty(&dev->inqueue)) | ||
925 | return -EINVAL; | ||
926 | |||
927 | mutex_lock(&dev->lock); | ||
928 | 1227 | ||
929 | if (unlikely(res_get(fh) < 0)) { | 1228 | if (unlikely(res_get(fh) < 0)) |
930 | mutex_unlock(&dev->lock); | ||
931 | return -EBUSY; | 1229 | return -EBUSY; |
932 | } | ||
933 | 1230 | ||
934 | dev->stream = STREAM_ON; /* FIXME: Start video capture here? */ | 1231 | return (videobuf_streamon(&fh->vb_vidq)); |
935 | |||
936 | mutex_unlock(&dev->lock); | ||
937 | return 0; | ||
938 | } | 1232 | } |
939 | 1233 | ||
940 | static int vidioc_streamoff(struct file *file, void *priv, | 1234 | static int vidioc_streamoff(struct file *file, void *priv, |
@@ -948,23 +1242,14 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
948 | if (rc < 0) | 1242 | if (rc < 0) |
949 | return rc; | 1243 | return rc; |
950 | 1244 | ||
951 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || dev->io != IO_MMAP) | 1245 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1246 | return -EINVAL; | ||
1247 | if (type != fh->type) | ||
952 | return -EINVAL; | 1248 | return -EINVAL; |
953 | 1249 | ||
954 | mutex_lock(&dev->lock); | 1250 | videobuf_streamoff(&fh->vb_vidq); |
955 | 1251 | res_free(fh); | |
956 | if (dev->stream == STREAM_ON) { | ||
957 | em28xx_videodbg("VIDIOC_STREAMOFF: interrupting stream\n"); | ||
958 | rc = em28xx_stream_interrupt(dev); | ||
959 | if (rc < 0) { | ||
960 | mutex_unlock(&dev->lock); | ||
961 | return rc; | ||
962 | } | ||
963 | } | ||
964 | |||
965 | em28xx_empty_framequeues(dev); | ||
966 | 1252 | ||
967 | mutex_unlock(&dev->lock); | ||
968 | return 0; | 1253 | return 0; |
969 | } | 1254 | } |
970 | 1255 | ||
@@ -1058,53 +1343,13 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1058 | { | 1343 | { |
1059 | struct em28xx_fh *fh = priv; | 1344 | struct em28xx_fh *fh = priv; |
1060 | struct em28xx *dev = fh->dev; | 1345 | struct em28xx *dev = fh->dev; |
1061 | u32 i; | ||
1062 | int rc; | 1346 | int rc; |
1063 | 1347 | ||
1064 | rc = check_dev(dev); | 1348 | rc = check_dev(dev); |
1065 | if (rc < 0) | 1349 | if (rc < 0) |
1066 | return rc; | 1350 | return rc; |
1067 | 1351 | ||
1068 | if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | 1352 | return (videobuf_reqbufs(&fh->vb_vidq, rb)); |
1069 | rb->memory != V4L2_MEMORY_MMAP) | ||
1070 | return -EINVAL; | ||
1071 | |||
1072 | if (dev->io == IO_READ) { | ||
1073 | em28xx_videodbg("method is set to read;" | ||
1074 | " close and open the device again to" | ||
1075 | " choose the mmap I/O method\n"); | ||
1076 | return -EINVAL; | ||
1077 | } | ||
1078 | |||
1079 | for (i = 0; i < dev->num_frames; i++) | ||
1080 | if (dev->frame[i].vma_use_count) { | ||
1081 | em28xx_videodbg("VIDIOC_REQBUFS failed; " | ||
1082 | "previous buffers are still mapped\n"); | ||
1083 | return -EINVAL; | ||
1084 | } | ||
1085 | |||
1086 | mutex_lock(&dev->lock); | ||
1087 | |||
1088 | if (dev->stream == STREAM_ON) { | ||
1089 | em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n"); | ||
1090 | rc = em28xx_stream_interrupt(dev); | ||
1091 | if (rc < 0) { | ||
1092 | mutex_unlock(&dev->lock); | ||
1093 | return rc; | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1097 | em28xx_empty_framequeues(dev); | ||
1098 | |||
1099 | em28xx_release_buffers(dev); | ||
1100 | if (rb->count) | ||
1101 | rb->count = em28xx_request_buffers(dev, rb->count); | ||
1102 | |||
1103 | dev->frame_current = NULL; | ||
1104 | dev->io = rb->count ? IO_MMAP : IO_NONE; | ||
1105 | |||
1106 | mutex_unlock(&dev->lock); | ||
1107 | return 0; | ||
1108 | } | 1353 | } |
1109 | 1354 | ||
1110 | static int vidioc_querybuf(struct file *file, void *priv, | 1355 | static int vidioc_querybuf(struct file *file, void *priv, |
@@ -1118,52 +1363,20 @@ static int vidioc_querybuf(struct file *file, void *priv, | |||
1118 | if (rc < 0) | 1363 | if (rc < 0) |
1119 | return rc; | 1364 | return rc; |
1120 | 1365 | ||
1121 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | 1366 | return (videobuf_querybuf(&fh->vb_vidq, b)); |
1122 | b->index >= dev->num_frames || dev->io != IO_MMAP) | ||
1123 | return -EINVAL; | ||
1124 | |||
1125 | mutex_lock(&dev->lock); | ||
1126 | |||
1127 | memcpy(b, &dev->frame[b->index].buf, sizeof(*b)); | ||
1128 | |||
1129 | if (dev->frame[b->index].vma_use_count) | ||
1130 | b->flags |= V4L2_BUF_FLAG_MAPPED; | ||
1131 | |||
1132 | if (dev->frame[b->index].state == F_DONE) | ||
1133 | b->flags |= V4L2_BUF_FLAG_DONE; | ||
1134 | else if (dev->frame[b->index].state != F_UNUSED) | ||
1135 | b->flags |= V4L2_BUF_FLAG_QUEUED; | ||
1136 | |||
1137 | mutex_unlock(&dev->lock); | ||
1138 | return 0; | ||
1139 | } | 1367 | } |
1140 | 1368 | ||
1141 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) | 1369 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) |
1142 | { | 1370 | { |
1143 | struct em28xx_fh *fh = priv; | 1371 | struct em28xx_fh *fh = priv; |
1144 | struct em28xx *dev = fh->dev; | 1372 | struct em28xx *dev = fh->dev; |
1145 | unsigned long lock_flags; | ||
1146 | int rc; | 1373 | int rc; |
1147 | 1374 | ||
1148 | rc = check_dev(dev); | 1375 | rc = check_dev(dev); |
1149 | if (rc < 0) | 1376 | if (rc < 0) |
1150 | return rc; | 1377 | return rc; |
1151 | 1378 | ||
1152 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || dev->io != IO_MMAP || | 1379 | return (videobuf_qbuf(&fh->vb_vidq, b)); |
1153 | b->index >= dev->num_frames) | ||
1154 | return -EINVAL; | ||
1155 | |||
1156 | if (dev->frame[b->index].state != F_UNUSED) | ||
1157 | return -EAGAIN; | ||
1158 | |||
1159 | dev->frame[b->index].state = F_QUEUED; | ||
1160 | |||
1161 | /* add frame to fifo */ | ||
1162 | spin_lock_irqsave(&dev->queue_lock, lock_flags); | ||
1163 | list_add_tail(&dev->frame[b->index].frame, &dev->inqueue); | ||
1164 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); | ||
1165 | |||
1166 | return 0; | ||
1167 | } | 1380 | } |
1168 | 1381 | ||
1169 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | 1382 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) |
@@ -1171,46 +1384,24 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | |||
1171 | struct em28xx_fh *fh = priv; | 1384 | struct em28xx_fh *fh = priv; |
1172 | struct em28xx *dev = fh->dev; | 1385 | struct em28xx *dev = fh->dev; |
1173 | int rc; | 1386 | int rc; |
1174 | struct em28xx_frame_t *f; | ||
1175 | unsigned long lock_flags; | ||
1176 | 1387 | ||
1177 | rc = check_dev(dev); | 1388 | rc = check_dev(dev); |
1178 | if (rc < 0) | 1389 | if (rc < 0) |
1179 | return rc; | 1390 | return rc; |
1180 | 1391 | ||
1181 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || dev->io != IO_MMAP) | 1392 | return (videobuf_dqbuf(&fh->vb_vidq, b, |
1182 | return -EINVAL; | 1393 | file->f_flags & O_NONBLOCK)); |
1183 | 1394 | } | |
1184 | if (list_empty(&dev->outqueue)) { | ||
1185 | if (dev->stream == STREAM_OFF) | ||
1186 | return -EINVAL; | ||
1187 | |||
1188 | if (file->f_flags & O_NONBLOCK) | ||
1189 | return -EAGAIN; | ||
1190 | |||
1191 | rc = wait_event_interruptible(dev->wait_frame, | ||
1192 | (!list_empty(&dev->outqueue)) || | ||
1193 | (dev->state & DEV_DISCONNECTED)); | ||
1194 | if (rc) | ||
1195 | return rc; | ||
1196 | |||
1197 | if (dev->state & DEV_DISCONNECTED) | ||
1198 | return -ENODEV; | ||
1199 | } | ||
1200 | |||
1201 | spin_lock_irqsave(&dev->queue_lock, lock_flags); | ||
1202 | f = list_entry(dev->outqueue.next, struct em28xx_frame_t, frame); | ||
1203 | list_del(dev->outqueue.next); | ||
1204 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); | ||
1205 | |||
1206 | f->state = F_UNUSED; | ||
1207 | memcpy(b, &f->buf, sizeof(*b)); | ||
1208 | 1395 | ||
1209 | if (f->vma_use_count) | 1396 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1210 | b->flags |= V4L2_BUF_FLAG_MAPPED; | 1397 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) |
1398 | { | ||
1399 | struct em28xx_fh *fh = priv; | ||
1211 | 1400 | ||
1212 | return 0; | 1401 | return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); |
1213 | } | 1402 | } |
1403 | #endif | ||
1404 | |||
1214 | 1405 | ||
1215 | /* ----------------------------------------------------------- */ | 1406 | /* ----------------------------------------------------------- */ |
1216 | /* RADIO ESPECIFIC IOCTLS */ | 1407 | /* RADIO ESPECIFIC IOCTLS */ |
@@ -1316,17 +1507,18 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1316 | { | 1507 | { |
1317 | int minor = iminor(inode); | 1508 | int minor = iminor(inode); |
1318 | int errCode = 0, radio = 0; | 1509 | int errCode = 0, radio = 0; |
1319 | struct em28xx *h,*dev = NULL; | 1510 | struct em28xx *h, *dev = NULL; |
1320 | struct em28xx_fh *fh; | 1511 | struct em28xx_fh *fh; |
1512 | enum v4l2_buf_type fh_type = 0; | ||
1321 | 1513 | ||
1322 | list_for_each_entry(h, &em28xx_devlist, devlist) { | 1514 | list_for_each_entry(h, &em28xx_devlist, devlist) { |
1323 | if (h->vdev->minor == minor) { | 1515 | if (h->vdev->minor == minor) { |
1324 | dev = h; | 1516 | dev = h; |
1325 | dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1517 | fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1326 | } | 1518 | } |
1327 | if (h->vbi_dev->minor == minor) { | 1519 | if (h->vbi_dev->minor == minor) { |
1328 | dev = h; | 1520 | dev = h; |
1329 | dev->type = V4L2_BUF_TYPE_VBI_CAPTURE; | 1521 | fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; |
1330 | } | 1522 | } |
1331 | if (h->radio_dev && | 1523 | if (h->radio_dev && |
1332 | h->radio_dev->minor == minor) { | 1524 | h->radio_dev->minor == minor) { |
@@ -1338,10 +1530,10 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1338 | return -ENODEV; | 1530 | return -ENODEV; |
1339 | 1531 | ||
1340 | em28xx_videodbg("open minor=%d type=%s users=%d\n", | 1532 | em28xx_videodbg("open minor=%d type=%s users=%d\n", |
1341 | minor,v4l2_type_names[dev->type],dev->users); | 1533 | minor, v4l2_type_names[fh_type], dev->users); |
1342 | 1534 | ||
1343 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); | ||
1344 | 1535 | ||
1536 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); | ||
1345 | if (!fh) { | 1537 | if (!fh) { |
1346 | em28xx_errdev("em28xx-video.c: Out of memory?!\n"); | 1538 | em28xx_errdev("em28xx-video.c: Out of memory?!\n"); |
1347 | return -ENOMEM; | 1539 | return -ENOMEM; |
@@ -1349,28 +1541,24 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1349 | mutex_lock(&dev->lock); | 1541 | mutex_lock(&dev->lock); |
1350 | fh->dev = dev; | 1542 | fh->dev = dev; |
1351 | fh->radio = radio; | 1543 | fh->radio = radio; |
1544 | fh->type = fh_type; | ||
1352 | filp->private_data = fh; | 1545 | filp->private_data = fh; |
1353 | 1546 | ||
1354 | if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { | 1547 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { |
1355 | dev->width = norm_maxw(dev); | 1548 | dev->width = norm_maxw(dev); |
1356 | dev->height = norm_maxh(dev); | 1549 | dev->height = norm_maxh(dev); |
1357 | dev->frame_size = dev->width * dev->height * 2; | ||
1358 | dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ | ||
1359 | dev->bytesperline = dev->width * 2; | ||
1360 | dev->hscale = 0; | 1550 | dev->hscale = 0; |
1361 | dev->vscale = 0; | 1551 | dev->vscale = 0; |
1362 | 1552 | ||
1553 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | ||
1363 | em28xx_set_alternate(dev); | 1554 | em28xx_set_alternate(dev); |
1364 | em28xx_capture_start(dev, 1); | ||
1365 | em28xx_resolution_set(dev); | 1555 | em28xx_resolution_set(dev); |
1366 | 1556 | ||
1557 | /* Needed, since GPIO might have disabled power of | ||
1558 | some i2c device | ||
1559 | */ | ||
1560 | em28xx_config_i2c(dev); | ||
1367 | 1561 | ||
1368 | /* start the transfer */ | ||
1369 | errCode = em28xx_init_isoc(dev); | ||
1370 | if (errCode) | ||
1371 | goto err; | ||
1372 | |||
1373 | em28xx_empty_framequeues(dev); | ||
1374 | } | 1562 | } |
1375 | if (fh->radio) { | 1563 | if (fh->radio) { |
1376 | em28xx_videodbg("video_open: setting radio device\n"); | 1564 | em28xx_videodbg("video_open: setting radio device\n"); |
@@ -1379,8 +1567,12 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1379 | 1567 | ||
1380 | dev->users++; | 1568 | dev->users++; |
1381 | 1569 | ||
1382 | err: | 1570 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, |
1571 | NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED, | ||
1572 | sizeof(struct em28xx_buffer), fh); | ||
1573 | |||
1383 | mutex_unlock(&dev->lock); | 1574 | mutex_unlock(&dev->lock); |
1575 | |||
1384 | return errCode; | 1576 | return errCode; |
1385 | } | 1577 | } |
1386 | 1578 | ||
@@ -1423,12 +1615,13 @@ static void em28xx_release_resources(struct em28xx *dev) | |||
1423 | usb_put_dev(dev->udev); | 1615 | usb_put_dev(dev->udev); |
1424 | 1616 | ||
1425 | /* Mark device as unused */ | 1617 | /* Mark device as unused */ |
1426 | em28xx_devused&=~(1<<dev->devno); | 1618 | em28xx_devused &= ~(1<<dev->devno); |
1427 | } | 1619 | } |
1428 | 1620 | ||
1429 | /* | 1621 | /* |
1430 | * em28xx_v4l2_close() | 1622 | * em28xx_v4l2_close() |
1431 | * stops streaming and deallocates all resources allocated by the v4l2 calls and ioctls | 1623 | * stops streaming and deallocates all resources allocated by the v4l2 |
1624 | * calls and ioctls | ||
1432 | */ | 1625 | */ |
1433 | static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | 1626 | static int em28xx_v4l2_close(struct inode *inode, struct file *filp) |
1434 | { | 1627 | { |
@@ -1445,9 +1638,8 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
1445 | mutex_lock(&dev->lock); | 1638 | mutex_lock(&dev->lock); |
1446 | 1639 | ||
1447 | if (dev->users == 1) { | 1640 | if (dev->users == 1) { |
1448 | em28xx_uninit_isoc(dev); | 1641 | videobuf_stop(&fh->vb_vidq); |
1449 | em28xx_release_buffers(dev); | 1642 | videobuf_mmap_free(&fh->vb_vidq); |
1450 | dev->io = IO_NONE; | ||
1451 | 1643 | ||
1452 | /* the device is already disconnect, | 1644 | /* the device is already disconnect, |
1453 | free the remaining resources */ | 1645 | free the remaining resources */ |
@@ -1458,6 +1650,10 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
1458 | return 0; | 1650 | return 0; |
1459 | } | 1651 | } |
1460 | 1652 | ||
1653 | /* do this before setting alternate! */ | ||
1654 | em28xx_uninit_isoc(dev); | ||
1655 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | ||
1656 | |||
1461 | /* set alternate 0 */ | 1657 | /* set alternate 0 */ |
1462 | dev->alt = 0; | 1658 | dev->alt = 0; |
1463 | em28xx_videodbg("setting alternate 0\n"); | 1659 | em28xx_videodbg("setting alternate 0\n"); |
@@ -1479,135 +1675,29 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
1479 | * will allocate buffers when called for the first time | 1675 | * will allocate buffers when called for the first time |
1480 | */ | 1676 | */ |
1481 | static ssize_t | 1677 | static ssize_t |
1482 | em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, | 1678 | em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count, |
1483 | loff_t * f_pos) | 1679 | loff_t *pos) |
1484 | { | 1680 | { |
1485 | struct em28xx_frame_t *f, *i; | ||
1486 | unsigned long lock_flags; | ||
1487 | int ret = 0; | ||
1488 | struct em28xx_fh *fh = filp->private_data; | 1681 | struct em28xx_fh *fh = filp->private_data; |
1489 | struct em28xx *dev = fh->dev; | 1682 | struct em28xx *dev = fh->dev; |
1683 | int rc; | ||
1684 | |||
1685 | rc = check_dev(dev); | ||
1686 | if (rc < 0) | ||
1687 | return rc; | ||
1490 | 1688 | ||
1491 | /* FIXME: read() is not prepared to allow changing the video | 1689 | /* FIXME: read() is not prepared to allow changing the video |
1492 | resolution while streaming. Seems a bug at em28xx_set_fmt | 1690 | resolution while streaming. Seems a bug at em28xx_set_fmt |
1493 | */ | 1691 | */ |
1494 | 1692 | ||
1495 | if (unlikely(res_get(fh) < 0)) | 1693 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1496 | return -EBUSY; | 1694 | if (unlikely(res_get(fh))) |
1497 | 1695 | return -EBUSY; | |
1498 | mutex_lock(&dev->lock); | ||
1499 | |||
1500 | if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1501 | em28xx_videodbg("V4l2_Buf_type_videocapture is set\n"); | ||
1502 | 1696 | ||
1503 | if (dev->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 1697 | return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, |
1504 | em28xx_videodbg("V4L2_BUF_TYPE_VBI_CAPTURE is set\n"); | 1698 | filp->f_flags & O_NONBLOCK); |
1505 | em28xx_videodbg("not supported yet! ...\n"); | ||
1506 | if (copy_to_user(buf, "", 1)) { | ||
1507 | mutex_unlock(&dev->lock); | ||
1508 | return -EFAULT; | ||
1509 | } | ||
1510 | mutex_unlock(&dev->lock); | ||
1511 | return (1); | ||
1512 | } | ||
1513 | if (dev->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { | ||
1514 | em28xx_videodbg("V4L2_BUF_TYPE_SLICED_VBI_CAPTURE is set\n"); | ||
1515 | em28xx_videodbg("not supported yet! ...\n"); | ||
1516 | if (copy_to_user(buf, "", 1)) { | ||
1517 | mutex_unlock(&dev->lock); | ||
1518 | return -EFAULT; | ||
1519 | } | ||
1520 | mutex_unlock(&dev->lock); | ||
1521 | return (1); | ||
1522 | } | 1699 | } |
1523 | 1700 | return 0; | |
1524 | if (dev->state & DEV_DISCONNECTED) { | ||
1525 | em28xx_videodbg("device not present\n"); | ||
1526 | mutex_unlock(&dev->lock); | ||
1527 | return -ENODEV; | ||
1528 | } | ||
1529 | |||
1530 | if (dev->state & DEV_MISCONFIGURED) { | ||
1531 | em28xx_videodbg("device misconfigured; close and open it again\n"); | ||
1532 | mutex_unlock(&dev->lock); | ||
1533 | return -EIO; | ||
1534 | } | ||
1535 | |||
1536 | if (dev->io == IO_MMAP) { | ||
1537 | em28xx_videodbg ("IO method is set to mmap; close and open" | ||
1538 | " the device again to choose the read method\n"); | ||
1539 | mutex_unlock(&dev->lock); | ||
1540 | return -EINVAL; | ||
1541 | } | ||
1542 | |||
1543 | if (dev->io == IO_NONE) { | ||
1544 | if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) { | ||
1545 | em28xx_errdev("read failed, not enough memory\n"); | ||
1546 | mutex_unlock(&dev->lock); | ||
1547 | return -ENOMEM; | ||
1548 | } | ||
1549 | dev->io = IO_READ; | ||
1550 | dev->stream = STREAM_ON; | ||
1551 | em28xx_queue_unusedframes(dev); | ||
1552 | } | ||
1553 | |||
1554 | if (!count) { | ||
1555 | mutex_unlock(&dev->lock); | ||
1556 | return 0; | ||
1557 | } | ||
1558 | |||
1559 | if (list_empty(&dev->outqueue)) { | ||
1560 | if (filp->f_flags & O_NONBLOCK) { | ||
1561 | mutex_unlock(&dev->lock); | ||
1562 | return -EAGAIN; | ||
1563 | } | ||
1564 | ret = wait_event_interruptible | ||
1565 | (dev->wait_frame, | ||
1566 | (!list_empty(&dev->outqueue)) || | ||
1567 | (dev->state & DEV_DISCONNECTED)); | ||
1568 | if (ret) { | ||
1569 | mutex_unlock(&dev->lock); | ||
1570 | return ret; | ||
1571 | } | ||
1572 | if (dev->state & DEV_DISCONNECTED) { | ||
1573 | mutex_unlock(&dev->lock); | ||
1574 | return -ENODEV; | ||
1575 | } | ||
1576 | dev->video_bytesread = 0; | ||
1577 | } | ||
1578 | |||
1579 | f = list_entry(dev->outqueue.prev, struct em28xx_frame_t, frame); | ||
1580 | |||
1581 | em28xx_queue_unusedframes(dev); | ||
1582 | |||
1583 | if (count > f->buf.length) | ||
1584 | count = f->buf.length; | ||
1585 | |||
1586 | if ((dev->video_bytesread + count) > dev->frame_size) | ||
1587 | count = dev->frame_size - dev->video_bytesread; | ||
1588 | |||
1589 | if (copy_to_user(buf, f->bufmem+dev->video_bytesread, count)) { | ||
1590 | em28xx_err("Error while copying to user\n"); | ||
1591 | return -EFAULT; | ||
1592 | } | ||
1593 | dev->video_bytesread += count; | ||
1594 | |||
1595 | if (dev->video_bytesread == dev->frame_size) { | ||
1596 | spin_lock_irqsave(&dev->queue_lock, lock_flags); | ||
1597 | list_for_each_entry(i, &dev->outqueue, frame) | ||
1598 | i->state = F_UNUSED; | ||
1599 | INIT_LIST_HEAD(&dev->outqueue); | ||
1600 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); | ||
1601 | |||
1602 | em28xx_queue_unusedframes(dev); | ||
1603 | dev->video_bytesread = 0; | ||
1604 | } | ||
1605 | |||
1606 | *f_pos += count; | ||
1607 | |||
1608 | mutex_unlock(&dev->lock); | ||
1609 | |||
1610 | return count; | ||
1611 | } | 1701 | } |
1612 | 1702 | ||
1613 | /* | 1703 | /* |
@@ -1616,46 +1706,21 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, | |||
1616 | */ | 1706 | */ |
1617 | static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) | 1707 | static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) |
1618 | { | 1708 | { |
1619 | unsigned int mask = 0; | ||
1620 | struct em28xx_fh *fh = filp->private_data; | 1709 | struct em28xx_fh *fh = filp->private_data; |
1621 | struct em28xx *dev = fh->dev; | 1710 | struct em28xx *dev = fh->dev; |
1711 | int rc; | ||
1712 | |||
1713 | rc = check_dev(dev); | ||
1714 | if (rc < 0) | ||
1715 | return rc; | ||
1622 | 1716 | ||
1623 | if (unlikely(res_get(fh) < 0)) | 1717 | if (unlikely(res_get(fh) < 0)) |
1624 | return POLLERR; | 1718 | return POLLERR; |
1625 | 1719 | ||
1626 | mutex_lock(&dev->lock); | 1720 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) |
1627 | 1721 | return POLLERR; | |
1628 | if (dev->state & DEV_DISCONNECTED) { | ||
1629 | em28xx_videodbg("device not present\n"); | ||
1630 | } else if (dev->state & DEV_MISCONFIGURED) { | ||
1631 | em28xx_videodbg("device is misconfigured; close and open it again\n"); | ||
1632 | } else { | ||
1633 | if (dev->io == IO_NONE) { | ||
1634 | if (!em28xx_request_buffers | ||
1635 | (dev, EM28XX_NUM_READ_FRAMES)) { | ||
1636 | em28xx_warn | ||
1637 | ("poll() failed, not enough memory\n"); | ||
1638 | } else { | ||
1639 | dev->io = IO_READ; | ||
1640 | dev->stream = STREAM_ON; | ||
1641 | } | ||
1642 | } | ||
1643 | |||
1644 | if (dev->io == IO_READ) { | ||
1645 | em28xx_queue_unusedframes(dev); | ||
1646 | poll_wait(filp, &dev->wait_frame, wait); | ||
1647 | |||
1648 | if (!list_empty(&dev->outqueue)) | ||
1649 | mask |= POLLIN | POLLRDNORM; | ||
1650 | |||
1651 | mutex_unlock(&dev->lock); | ||
1652 | |||
1653 | return mask; | ||
1654 | } | ||
1655 | } | ||
1656 | 1722 | ||
1657 | mutex_unlock(&dev->lock); | 1723 | return videobuf_poll_stream(filp, &fh->vb_vidq, wait); |
1658 | return POLLERR; | ||
1659 | } | 1724 | } |
1660 | 1725 | ||
1661 | /* | 1726 | /* |
@@ -1665,69 +1730,23 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
1665 | { | 1730 | { |
1666 | struct em28xx_fh *fh = filp->private_data; | 1731 | struct em28xx_fh *fh = filp->private_data; |
1667 | struct em28xx *dev = fh->dev; | 1732 | struct em28xx *dev = fh->dev; |
1668 | unsigned long size = vma->vm_end - vma->vm_start; | 1733 | int rc; |
1669 | unsigned long start = vma->vm_start; | ||
1670 | void *pos; | ||
1671 | u32 i; | ||
1672 | 1734 | ||
1673 | if (unlikely(res_get(fh) < 0)) | 1735 | if (unlikely(res_get(fh) < 0)) |
1674 | return -EBUSY; | 1736 | return -EBUSY; |
1675 | 1737 | ||
1676 | mutex_lock(&dev->lock); | 1738 | rc = check_dev(dev); |
1677 | 1739 | if (rc < 0) | |
1678 | if (dev->state & DEV_DISCONNECTED) { | 1740 | return rc; |
1679 | em28xx_videodbg("mmap: device not present\n"); | ||
1680 | mutex_unlock(&dev->lock); | ||
1681 | return -ENODEV; | ||
1682 | } | ||
1683 | |||
1684 | if (dev->state & DEV_MISCONFIGURED) { | ||
1685 | em28xx_videodbg ("mmap: Device is misconfigured; close and " | ||
1686 | "open it again\n"); | ||
1687 | mutex_unlock(&dev->lock); | ||
1688 | return -EIO; | ||
1689 | } | ||
1690 | |||
1691 | if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE)) { | ||
1692 | mutex_unlock(&dev->lock); | ||
1693 | return -EINVAL; | ||
1694 | } | ||
1695 | |||
1696 | if (size > PAGE_ALIGN(dev->frame[0].buf.length)) | ||
1697 | size = PAGE_ALIGN(dev->frame[0].buf.length); | ||
1698 | |||
1699 | for (i = 0; i < dev->num_frames; i++) { | ||
1700 | if ((dev->frame[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
1701 | break; | ||
1702 | } | ||
1703 | if (i == dev->num_frames) { | ||
1704 | em28xx_videodbg("mmap: user supplied mapping address is out of range\n"); | ||
1705 | mutex_unlock(&dev->lock); | ||
1706 | return -EINVAL; | ||
1707 | } | ||
1708 | |||
1709 | /* VM_IO is eventually going to replace PageReserved altogether */ | ||
1710 | vma->vm_flags |= VM_IO; | ||
1711 | vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ | ||
1712 | 1741 | ||
1713 | pos = dev->frame[i].bufmem; | 1742 | rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); |
1714 | while (size > 0) { /* size is page-aligned */ | ||
1715 | if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { | ||
1716 | em28xx_videodbg("mmap: vm_insert_page failed\n"); | ||
1717 | mutex_unlock(&dev->lock); | ||
1718 | return -EAGAIN; | ||
1719 | } | ||
1720 | start += PAGE_SIZE; | ||
1721 | pos += PAGE_SIZE; | ||
1722 | size -= PAGE_SIZE; | ||
1723 | } | ||
1724 | 1743 | ||
1725 | vma->vm_ops = &em28xx_vm_ops; | 1744 | em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", |
1726 | vma->vm_private_data = &dev->frame[i]; | 1745 | (unsigned long)vma->vm_start, |
1746 | (unsigned long)vma->vm_end-(unsigned long)vma->vm_start, | ||
1747 | rc); | ||
1727 | 1748 | ||
1728 | em28xx_vm_open(vma); | 1749 | return rc; |
1729 | mutex_unlock(&dev->lock); | ||
1730 | return 0; | ||
1731 | } | 1750 | } |
1732 | 1751 | ||
1733 | static const struct file_operations em28xx_v4l_fops = { | 1752 | static const struct file_operations em28xx_v4l_fops = { |
@@ -1790,6 +1809,9 @@ static const struct video_device em28xx_video_template = { | |||
1790 | .vidioc_g_register = vidioc_g_register, | 1809 | .vidioc_g_register = vidioc_g_register, |
1791 | .vidioc_s_register = vidioc_s_register, | 1810 | .vidioc_s_register = vidioc_s_register, |
1792 | #endif | 1811 | #endif |
1812 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1813 | .vidiocgmbuf = vidiocgmbuf, | ||
1814 | #endif | ||
1793 | 1815 | ||
1794 | .tvnorms = V4L2_STD_ALL, | 1816 | .tvnorms = V4L2_STD_ALL, |
1795 | .current_norm = V4L2_STD_PAL, | 1817 | .current_norm = V4L2_STD_PAL, |
@@ -1818,7 +1840,7 @@ static struct video_device em28xx_radio_template = { | |||
1818 | #endif | 1840 | #endif |
1819 | }; | 1841 | }; |
1820 | 1842 | ||
1821 | /******************************** usb interface *****************************************/ | 1843 | /******************************** usb interface ******************************/ |
1822 | 1844 | ||
1823 | 1845 | ||
1824 | static LIST_HEAD(em28xx_extension_devlist); | 1846 | static LIST_HEAD(em28xx_extension_devlist); |
@@ -1875,6 +1897,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, | |||
1875 | vfd->dev = &dev->udev->dev; | 1897 | vfd->dev = &dev->udev->dev; |
1876 | vfd->release = video_device_release; | 1898 | vfd->release = video_device_release; |
1877 | vfd->type = type; | 1899 | vfd->type = type; |
1900 | vfd->debug = video_debug; | ||
1878 | 1901 | ||
1879 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", | 1902 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", |
1880 | dev->name, type_name); | 1903 | dev->name, type_name); |
@@ -1898,7 +1921,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
1898 | 1921 | ||
1899 | dev->udev = udev; | 1922 | dev->udev = udev; |
1900 | mutex_init(&dev->lock); | 1923 | mutex_init(&dev->lock); |
1901 | spin_lock_init(&dev->queue_lock); | 1924 | spin_lock_init(&dev->slock); |
1902 | init_waitqueue_head(&dev->open); | 1925 | init_waitqueue_head(&dev->open); |
1903 | init_waitqueue_head(&dev->wait_frame); | 1926 | init_waitqueue_head(&dev->wait_frame); |
1904 | init_waitqueue_head(&dev->wait_stream); | 1927 | init_waitqueue_head(&dev->wait_stream); |
@@ -1910,10 +1933,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
1910 | dev->em28xx_read_reg_req = em28xx_read_reg_req; | 1933 | dev->em28xx_read_reg_req = em28xx_read_reg_req; |
1911 | dev->is_em2800 = em28xx_boards[dev->model].is_em2800; | 1934 | dev->is_em2800 = em28xx_boards[dev->model].is_em2800; |
1912 | 1935 | ||
1913 | errCode = em28xx_read_reg(dev, CHIPID_REG); | ||
1914 | if (errCode >= 0) | ||
1915 | em28xx_info("em28xx chip ID = %d\n", errCode); | ||
1916 | |||
1917 | em28xx_pre_card_setup(dev); | 1936 | em28xx_pre_card_setup(dev); |
1918 | 1937 | ||
1919 | errCode = em28xx_config(dev); | 1938 | errCode = em28xx_config(dev); |
@@ -1946,10 +1965,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
1946 | dev->width = maxw; | 1965 | dev->width = maxw; |
1947 | dev->height = maxh; | 1966 | dev->height = maxh; |
1948 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; | 1967 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; |
1949 | dev->field_size = dev->width * dev->height; | ||
1950 | dev->frame_size = | ||
1951 | dev->interlaced ? dev->field_size << 1 : dev->field_size; | ||
1952 | dev->bytesperline = dev->width * 2; | ||
1953 | dev->hscale = 0; | 1968 | dev->hscale = 0; |
1954 | dev->vscale = 0; | 1969 | dev->vscale = 0; |
1955 | dev->ctl_input = 2; | 1970 | dev->ctl_input = 2; |
@@ -2005,6 +2020,10 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
2005 | dev->radio_dev->minor & 0x1f); | 2020 | dev->radio_dev->minor & 0x1f); |
2006 | } | 2021 | } |
2007 | 2022 | ||
2023 | /* init video dma queues */ | ||
2024 | INIT_LIST_HEAD(&dev->vidq.active); | ||
2025 | INIT_LIST_HEAD(&dev->vidq.queued); | ||
2026 | |||
2008 | 2027 | ||
2009 | if (dev->has_msp34xx) { | 2028 | if (dev->has_msp34xx) { |
2010 | /* Send a reset to other chips via gpio */ | 2029 | /* Send a reset to other chips via gpio */ |
@@ -2048,6 +2067,9 @@ static void request_module_async(struct work_struct *work) | |||
2048 | request_module("snd-usb-audio"); | 2067 | request_module("snd-usb-audio"); |
2049 | else | 2068 | else |
2050 | request_module("em28xx-alsa"); | 2069 | request_module("em28xx-alsa"); |
2070 | |||
2071 | if (dev->has_dvb) | ||
2072 | request_module("em28xx-dvb"); | ||
2051 | } | 2073 | } |
2052 | 2074 | ||
2053 | static void request_modules(struct em28xx *dev) | 2075 | static void request_modules(struct em28xx *dev) |
@@ -2077,22 +2099,24 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
2077 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; | 2099 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; |
2078 | 2100 | ||
2079 | /* Check to see next free device and mark as used */ | 2101 | /* Check to see next free device and mark as used */ |
2080 | nr=find_first_zero_bit(&em28xx_devused,EM28XX_MAXBOARDS); | 2102 | nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS); |
2081 | em28xx_devused|=1<<nr; | 2103 | em28xx_devused |= 1<<nr; |
2082 | 2104 | ||
2083 | /* Don't register audio interfaces */ | 2105 | /* Don't register audio interfaces */ |
2084 | if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | 2106 | if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { |
2085 | em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n", | 2107 | em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n", |
2086 | udev->descriptor.idVendor,udev->descriptor.idProduct, | 2108 | udev->descriptor.idVendor, |
2109 | udev->descriptor.idProduct, | ||
2087 | ifnum, | 2110 | ifnum, |
2088 | interface->altsetting[0].desc.bInterfaceClass); | 2111 | interface->altsetting[0].desc.bInterfaceClass); |
2089 | 2112 | ||
2090 | em28xx_devused&=~(1<<nr); | 2113 | em28xx_devused &= ~(1<<nr); |
2091 | return -ENODEV; | 2114 | return -ENODEV; |
2092 | } | 2115 | } |
2093 | 2116 | ||
2094 | em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n", | 2117 | em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n", |
2095 | udev->descriptor.idVendor,udev->descriptor.idProduct, | 2118 | udev->descriptor.idVendor, |
2119 | udev->descriptor.idProduct, | ||
2096 | ifnum, | 2120 | ifnum, |
2097 | interface->altsetting[0].desc.bInterfaceClass); | 2121 | interface->altsetting[0].desc.bInterfaceClass); |
2098 | 2122 | ||
@@ -2102,18 +2126,19 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
2102 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != | 2126 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != |
2103 | USB_ENDPOINT_XFER_ISOC) { | 2127 | USB_ENDPOINT_XFER_ISOC) { |
2104 | em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); | 2128 | em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); |
2105 | em28xx_devused&=~(1<<nr); | 2129 | em28xx_devused &= ~(1<<nr); |
2106 | return -ENODEV; | 2130 | return -ENODEV; |
2107 | } | 2131 | } |
2108 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { | 2132 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { |
2109 | em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); | 2133 | em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); |
2110 | em28xx_devused&=~(1<<nr); | 2134 | em28xx_devused &= ~(1<<nr); |
2111 | return -ENODEV; | 2135 | return -ENODEV; |
2112 | } | 2136 | } |
2113 | 2137 | ||
2114 | if (nr >= EM28XX_MAXBOARDS) { | 2138 | if (nr >= EM28XX_MAXBOARDS) { |
2115 | printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS); | 2139 | printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", |
2116 | em28xx_devused&=~(1<<nr); | 2140 | EM28XX_MAXBOARDS); |
2141 | em28xx_devused &= ~(1<<nr); | ||
2117 | return -ENOMEM; | 2142 | return -ENOMEM; |
2118 | } | 2143 | } |
2119 | 2144 | ||
@@ -2121,7 +2146,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
2121 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 2146 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
2122 | if (dev == NULL) { | 2147 | if (dev == NULL) { |
2123 | em28xx_err(DRIVER_NAME ": out of memory!\n"); | 2148 | em28xx_err(DRIVER_NAME ": out of memory!\n"); |
2124 | em28xx_devused&=~(1<<nr); | 2149 | em28xx_devused &= ~(1<<nr); |
2125 | return -ENOMEM; | 2150 | return -ENOMEM; |
2126 | } | 2151 | } |
2127 | 2152 | ||
@@ -2145,14 +2170,14 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
2145 | /* compute alternate max packet sizes */ | 2170 | /* compute alternate max packet sizes */ |
2146 | uif = udev->actconfig->interface[0]; | 2171 | uif = udev->actconfig->interface[0]; |
2147 | 2172 | ||
2148 | dev->num_alt=uif->num_altsetting; | 2173 | dev->num_alt = uif->num_altsetting; |
2149 | em28xx_info("Alternate settings: %i\n",dev->num_alt); | 2174 | em28xx_info("Alternate settings: %i\n", dev->num_alt); |
2150 | // dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* | 2175 | /* dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* */ |
2151 | dev->alt_max_pkt_size = kmalloc(32* | 2176 | dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL); |
2152 | dev->num_alt,GFP_KERNEL); | 2177 | |
2153 | if (dev->alt_max_pkt_size == NULL) { | 2178 | if (dev->alt_max_pkt_size == NULL) { |
2154 | em28xx_errdev("out of memory!\n"); | 2179 | em28xx_errdev("out of memory!\n"); |
2155 | em28xx_devused&=~(1<<nr); | 2180 | em28xx_devused &= ~(1<<nr); |
2156 | kfree(dev); | 2181 | kfree(dev); |
2157 | return -ENOMEM; | 2182 | return -ENOMEM; |
2158 | } | 2183 | } |
@@ -2162,11 +2187,11 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
2162 | wMaxPacketSize); | 2187 | wMaxPacketSize); |
2163 | dev->alt_max_pkt_size[i] = | 2188 | dev->alt_max_pkt_size[i] = |
2164 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | 2189 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); |
2165 | em28xx_info("Alternate setting %i, max size= %i\n",i, | 2190 | em28xx_info("Alternate setting %i, max size= %i\n", i, |
2166 | dev->alt_max_pkt_size[i]); | 2191 | dev->alt_max_pkt_size[i]); |
2167 | } | 2192 | } |
2168 | 2193 | ||
2169 | if ((card[nr]>=0)&&(card[nr]<em28xx_bcount)) | 2194 | if ((card[nr] >= 0) && (card[nr] < em28xx_bcount)) |
2170 | dev->model = card[nr]; | 2195 | dev->model = card[nr]; |
2171 | 2196 | ||
2172 | /* allocate device struct */ | 2197 | /* allocate device struct */ |
@@ -2202,7 +2227,8 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) | |||
2202 | 2227 | ||
2203 | em28xx_info("disconnecting %s\n", dev->vdev->name); | 2228 | em28xx_info("disconnecting %s\n", dev->vdev->name); |
2204 | 2229 | ||
2205 | /* wait until all current v4l2 io is finished then deallocate resources */ | 2230 | /* wait until all current v4l2 io is finished then deallocate |
2231 | resources */ | ||
2206 | mutex_lock(&dev->lock); | 2232 | mutex_lock(&dev->lock); |
2207 | 2233 | ||
2208 | wake_up_interruptible_all(&dev->open); | 2234 | wake_up_interruptible_all(&dev->open); |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 04e0e48ecabe..002f170b211a 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -26,11 +26,39 @@ | |||
26 | #define _EM28XX_H | 26 | #define _EM28XX_H |
27 | 27 | ||
28 | #include <linux/videodev2.h> | 28 | #include <linux/videodev2.h> |
29 | #include <media/videobuf-vmalloc.h> | ||
30 | |||
29 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
30 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
31 | #include <media/ir-kbd-i2c.h> | 33 | #include <media/ir-kbd-i2c.h> |
32 | 34 | #if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE) | |
33 | #define UNSET -1 | 35 | #include <media/videobuf-dvb.h> |
36 | #endif | ||
37 | #include "tuner-xc2028.h" | ||
38 | #include "em28xx-reg.h" | ||
39 | |||
40 | /* Boards supported by driver */ | ||
41 | #define EM2800_BOARD_UNKNOWN 0 | ||
42 | #define EM2820_BOARD_UNKNOWN 1 | ||
43 | #define EM2820_BOARD_TERRATEC_CINERGY_250 2 | ||
44 | #define EM2820_BOARD_PINNACLE_USB_2 3 | ||
45 | #define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4 | ||
46 | #define EM2820_BOARD_MSI_VOX_USB_2 5 | ||
47 | #define EM2800_BOARD_TERRATEC_CINERGY_200 6 | ||
48 | #define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 | ||
49 | #define EM2800_BOARD_KWORLD_USB2800 8 | ||
50 | #define EM2820_BOARD_PINNACLE_DVC_90 9 | ||
51 | #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 10 | ||
52 | #define EM2880_BOARD_TERRATEC_HYBRID_XS 11 | ||
53 | #define EM2820_BOARD_KWORLD_PVRTV2800RF 12 | ||
54 | #define EM2880_BOARD_TERRATEC_PRODIGY_XS 13 | ||
55 | #define EM2820_BOARD_PROLINK_PLAYTV_USB2 14 | ||
56 | #define EM2800_BOARD_VGEAR_POCKETTV 15 | ||
57 | #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16 | ||
58 | |||
59 | /* Limits minimum and default number of buffers */ | ||
60 | #define EM28XX_MIN_BUF 4 | ||
61 | #define EM28XX_DEF_BUF 8 | ||
34 | 62 | ||
35 | /* maximum number of em28xx boards */ | 63 | /* maximum number of em28xx boards */ |
36 | #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ | 64 | #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ |
@@ -81,31 +109,78 @@ | |||
81 | /* time in msecs to wait for i2c writes to finish */ | 109 | /* time in msecs to wait for i2c writes to finish */ |
82 | #define EM2800_I2C_WRITE_TIMEOUT 20 | 110 | #define EM2800_I2C_WRITE_TIMEOUT 20 |
83 | 111 | ||
84 | /* the various frame states */ | 112 | enum em28xx_mode { |
85 | enum em28xx_frame_state { | 113 | EM28XX_MODE_UNDEFINED, |
86 | F_UNUSED = 0, | 114 | EM28XX_ANALOG_MODE, |
87 | F_QUEUED, | 115 | EM28XX_DIGITAL_MODE, |
88 | F_GRABBING, | ||
89 | F_DONE, | ||
90 | F_ERROR, | ||
91 | }; | 116 | }; |
92 | 117 | ||
93 | /* stream states */ | ||
94 | enum em28xx_stream_state { | 118 | enum em28xx_stream_state { |
95 | STREAM_OFF, | 119 | STREAM_OFF, |
96 | STREAM_INTERRUPT, | 120 | STREAM_INTERRUPT, |
97 | STREAM_ON, | 121 | STREAM_ON, |
98 | }; | 122 | }; |
99 | 123 | ||
100 | /* frames */ | 124 | struct em28xx; |
101 | struct em28xx_frame_t { | 125 | |
102 | void *bufmem; | 126 | struct em28xx_usb_isoc_ctl { |
103 | struct v4l2_buffer buf; | 127 | /* max packet size of isoc transaction */ |
104 | enum em28xx_frame_state state; | 128 | int max_pkt_size; |
129 | |||
130 | /* number of allocated urbs */ | ||
131 | int num_bufs; | ||
132 | |||
133 | /* urb for isoc transfers */ | ||
134 | struct urb **urb; | ||
135 | |||
136 | /* transfer buffers for isoc transfer */ | ||
137 | char **transfer_buffer; | ||
138 | |||
139 | /* Last buffer command and region */ | ||
140 | u8 cmd; | ||
141 | int pos, size, pktsize; | ||
142 | |||
143 | /* Last field: ODD or EVEN? */ | ||
144 | int field; | ||
145 | |||
146 | /* Stores incomplete commands */ | ||
147 | u32 tmp_buf; | ||
148 | int tmp_buf_len; | ||
149 | |||
150 | /* Stores already requested buffers */ | ||
151 | struct em28xx_buffer *buf; | ||
152 | |||
153 | /* Stores the number of received fields */ | ||
154 | int nfields; | ||
155 | |||
156 | /* isoc urb callback */ | ||
157 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb); | ||
158 | |||
159 | }; | ||
160 | |||
161 | struct em28xx_fmt { | ||
162 | char *name; | ||
163 | u32 fourcc; /* v4l2 format id */ | ||
164 | }; | ||
165 | |||
166 | /* buffer for one video frame */ | ||
167 | struct em28xx_buffer { | ||
168 | /* common v4l buffer stuff -- must be first */ | ||
169 | struct videobuf_buffer vb; | ||
170 | |||
105 | struct list_head frame; | 171 | struct list_head frame; |
106 | unsigned long vma_use_count; | ||
107 | int top_field; | 172 | int top_field; |
108 | int fieldbytesused; | 173 | int receiving; |
174 | }; | ||
175 | |||
176 | struct em28xx_dmaqueue { | ||
177 | struct list_head active; | ||
178 | struct list_head queued; | ||
179 | |||
180 | wait_queue_head_t wq; | ||
181 | |||
182 | /* Counters to control buffer fill */ | ||
183 | int pos; | ||
109 | }; | 184 | }; |
110 | 185 | ||
111 | /* io methods */ | 186 | /* io methods */ |
@@ -152,6 +227,12 @@ enum em28xx_decoder { | |||
152 | EM28XX_SAA7114 | 227 | EM28XX_SAA7114 |
153 | }; | 228 | }; |
154 | 229 | ||
230 | struct em28xx_reg_seq { | ||
231 | int reg; | ||
232 | unsigned char val, mask; | ||
233 | int sleep; | ||
234 | }; | ||
235 | |||
155 | struct em28xx_board { | 236 | struct em28xx_board { |
156 | char *name; | 237 | char *name; |
157 | int vchannels; | 238 | int vchannels; |
@@ -165,8 +246,7 @@ struct em28xx_board { | |||
165 | unsigned int mts_firmware:1; | 246 | unsigned int mts_firmware:1; |
166 | unsigned int has_12mhz_i2s:1; | 247 | unsigned int has_12mhz_i2s:1; |
167 | unsigned int max_range_640_480:1; | 248 | unsigned int max_range_640_480:1; |
168 | 249 | unsigned int has_dvb:1; | |
169 | unsigned int analog_gpio; | ||
170 | 250 | ||
171 | enum em28xx_decoder decoder; | 251 | enum em28xx_decoder decoder; |
172 | 252 | ||
@@ -199,7 +279,10 @@ enum em28xx_dev_state { | |||
199 | #define EM28XX_NUM_AUDIO_PACKETS 64 | 279 | #define EM28XX_NUM_AUDIO_PACKETS 64 |
200 | #define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */ | 280 | #define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */ |
201 | #define EM28XX_CAPTURE_STREAM_EN 1 | 281 | #define EM28XX_CAPTURE_STREAM_EN 1 |
282 | |||
283 | /* em28xx extensions */ | ||
202 | #define EM28XX_AUDIO 0x10 | 284 | #define EM28XX_AUDIO 0x10 |
285 | #define EM28XX_DVB 0x20 | ||
203 | 286 | ||
204 | struct em28xx_audio { | 287 | struct em28xx_audio { |
205 | char name[50]; | 288 | char name[50]; |
@@ -217,13 +300,24 @@ struct em28xx_audio { | |||
217 | spinlock_t slock; | 300 | spinlock_t slock; |
218 | }; | 301 | }; |
219 | 302 | ||
303 | struct em28xx; | ||
304 | |||
305 | struct em28xx_fh { | ||
306 | struct em28xx *dev; | ||
307 | unsigned int stream_on:1; /* Locks streams */ | ||
308 | int radio; | ||
309 | |||
310 | struct videobuf_queue vb_vidq; | ||
311 | |||
312 | enum v4l2_buf_type type; | ||
313 | }; | ||
314 | |||
220 | /* main device struct */ | 315 | /* main device struct */ |
221 | struct em28xx { | 316 | struct em28xx { |
222 | /* generic device properties */ | 317 | /* generic device properties */ |
223 | char name[30]; /* name (including minor) of the device */ | 318 | char name[30]; /* name (including minor) of the device */ |
224 | int model; /* index in the device_data struct */ | 319 | int model; /* index in the device_data struct */ |
225 | int devno; /* marks the number of this device */ | 320 | int devno; /* marks the number of this device */ |
226 | unsigned int analog_gpio; | ||
227 | unsigned int is_em2800:1; | 321 | unsigned int is_em2800:1; |
228 | unsigned int has_msp34xx:1; | 322 | unsigned int has_msp34xx:1; |
229 | unsigned int has_tda9887:1; | 323 | unsigned int has_tda9887:1; |
@@ -231,6 +325,16 @@ struct em28xx { | |||
231 | unsigned int has_audio_class:1; | 325 | unsigned int has_audio_class:1; |
232 | unsigned int has_12mhz_i2s:1; | 326 | unsigned int has_12mhz_i2s:1; |
233 | unsigned int max_range_640_480:1; | 327 | unsigned int max_range_640_480:1; |
328 | unsigned int has_dvb:1; | ||
329 | |||
330 | /* Some older em28xx chips needs a waiting time after writing */ | ||
331 | unsigned int wait_after_write; | ||
332 | |||
333 | /* GPIO sequences for analog and digital mode */ | ||
334 | struct em28xx_reg_seq *analog_gpio, *digital_gpio; | ||
335 | |||
336 | /* GPIO sequences for tuner callbacks */ | ||
337 | struct em28xx_reg_seq *tun_analog_gpio, *tun_digital_gpio; | ||
234 | 338 | ||
235 | int video_inputs; /* number of video inputs */ | 339 | int video_inputs; /* number of video inputs */ |
236 | struct list_head devlist; | 340 | struct list_head devlist; |
@@ -255,36 +359,28 @@ struct em28xx { | |||
255 | int mute; | 359 | int mute; |
256 | int volume; | 360 | int volume; |
257 | /* frame properties */ | 361 | /* frame properties */ |
258 | struct em28xx_frame_t frame[EM28XX_NUM_FRAMES]; /* list of frames */ | ||
259 | int num_frames; /* number of frames currently in use */ | ||
260 | unsigned int frame_count; /* total number of transfered frames */ | ||
261 | struct em28xx_frame_t *frame_current; /* the frame that is being filled */ | ||
262 | int width; /* current frame width */ | 362 | int width; /* current frame width */ |
263 | int height; /* current frame height */ | 363 | int height; /* current frame height */ |
264 | int frame_size; /* current frame size */ | ||
265 | int field_size; /* current field size */ | ||
266 | int bytesperline; | ||
267 | int hscale; /* horizontal scale factor (see datasheet) */ | 364 | int hscale; /* horizontal scale factor (see datasheet) */ |
268 | int vscale; /* vertical scale factor (see datasheet) */ | 365 | int vscale; /* vertical scale factor (see datasheet) */ |
269 | int interlaced; /* 1=interlace fileds, 0=just top fileds */ | 366 | int interlaced; /* 1=interlace fileds, 0=just top fileds */ |
270 | int type; | ||
271 | unsigned int video_bytesread; /* Number of bytes read */ | 367 | unsigned int video_bytesread; /* Number of bytes read */ |
272 | 368 | ||
273 | unsigned long hash; /* eeprom hash - for boards with generic ID */ | 369 | unsigned long hash; /* eeprom hash - for boards with generic ID */ |
274 | unsigned long i2c_hash; /* i2c devicelist hash - for boards with generic ID */ | 370 | unsigned long i2c_hash; /* i2c devicelist hash - |
371 | for boards with generic ID */ | ||
275 | 372 | ||
276 | struct em28xx_audio *adev; | 373 | struct em28xx_audio *adev; |
277 | 374 | ||
278 | /* states */ | 375 | /* states */ |
279 | enum em28xx_dev_state state; | 376 | enum em28xx_dev_state state; |
280 | enum em28xx_stream_state stream; | ||
281 | enum em28xx_io_method io; | 377 | enum em28xx_io_method io; |
282 | 378 | ||
283 | struct work_struct request_module_wk; | 379 | struct work_struct request_module_wk; |
284 | 380 | ||
285 | /* locks */ | 381 | /* locks */ |
286 | struct mutex lock; | 382 | struct mutex lock; |
287 | spinlock_t queue_lock; | 383 | /* spinlock_t queue_lock; */ |
288 | struct list_head inqueue, outqueue; | 384 | struct list_head inqueue, outqueue; |
289 | wait_queue_head_t open, wait_frame, wait_stream; | 385 | wait_queue_head_t open, wait_frame, wait_stream; |
290 | struct video_device *vbi_dev; | 386 | struct video_device *vbi_dev; |
@@ -292,6 +388,11 @@ struct em28xx { | |||
292 | 388 | ||
293 | unsigned char eedata[256]; | 389 | unsigned char eedata[256]; |
294 | 390 | ||
391 | /* Isoc control struct */ | ||
392 | struct em28xx_dmaqueue vidq; | ||
393 | struct em28xx_usb_isoc_ctl isoc_ctl; | ||
394 | spinlock_t slock; | ||
395 | |||
295 | /* usb transfer */ | 396 | /* usb transfer */ |
296 | struct usb_device *udev; /* the usb device */ | 397 | struct usb_device *udev; /* the usb device */ |
297 | int alt; /* alternate */ | 398 | int alt; /* alternate */ |
@@ -301,20 +402,21 @@ struct em28xx { | |||
301 | struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ | 402 | struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ |
302 | char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */ | 403 | char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */ |
303 | /* helper funcs that call usb_control_msg */ | 404 | /* helper funcs that call usb_control_msg */ |
304 | int (*em28xx_write_regs) (struct em28xx * dev, u16 reg, char *buf, | 405 | int (*em28xx_write_regs) (struct em28xx *dev, u16 reg, |
305 | int len); | ||
306 | int (*em28xx_read_reg) (struct em28xx * dev, u16 reg); | ||
307 | int (*em28xx_read_reg_req_len) (struct em28xx * dev, u8 req, u16 reg, | ||
308 | char *buf, int len); | 406 | char *buf, int len); |
309 | int (*em28xx_write_regs_req) (struct em28xx * dev, u8 req, u16 reg, | 407 | int (*em28xx_read_reg) (struct em28xx *dev, u16 reg); |
408 | int (*em28xx_read_reg_req_len) (struct em28xx *dev, u8 req, u16 reg, | ||
409 | char *buf, int len); | ||
410 | int (*em28xx_write_regs_req) (struct em28xx *dev, u8 req, u16 reg, | ||
310 | char *buf, int len); | 411 | char *buf, int len); |
311 | int (*em28xx_read_reg_req) (struct em28xx * dev, u8 req, u16 reg); | 412 | int (*em28xx_read_reg_req) (struct em28xx *dev, u8 req, u16 reg); |
312 | }; | ||
313 | 413 | ||
314 | struct em28xx_fh { | 414 | enum em28xx_mode mode; |
315 | struct em28xx *dev; | 415 | |
316 | unsigned int stream_on:1; /* Locks streams */ | 416 | /* Caches GPO and GPIO registers */ |
317 | int radio; | 417 | unsigned char reg_gpo, reg_gpio; |
418 | |||
419 | struct em28xx_dvb *dvb; | ||
318 | }; | 420 | }; |
319 | 421 | ||
320 | struct em28xx_ops { | 422 | struct em28xx_ops { |
@@ -351,22 +453,27 @@ int em28xx_colorlevels_set_default(struct em28xx *dev); | |||
351 | int em28xx_capture_start(struct em28xx *dev, int start); | 453 | int em28xx_capture_start(struct em28xx *dev, int start); |
352 | int em28xx_outfmt_set_yuv422(struct em28xx *dev); | 454 | int em28xx_outfmt_set_yuv422(struct em28xx *dev); |
353 | int em28xx_resolution_set(struct em28xx *dev); | 455 | int em28xx_resolution_set(struct em28xx *dev); |
354 | int em28xx_init_isoc(struct em28xx *dev); | ||
355 | void em28xx_uninit_isoc(struct em28xx *dev); | ||
356 | int em28xx_set_alternate(struct em28xx *dev); | 456 | int em28xx_set_alternate(struct em28xx *dev); |
457 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, | ||
458 | int num_bufs, int max_pkt_size, | ||
459 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); | ||
460 | void em28xx_uninit_isoc(struct em28xx *dev); | ||
461 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); | ||
462 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); | ||
357 | 463 | ||
358 | /* Provided by em28xx-video.c */ | 464 | /* Provided by em28xx-video.c */ |
359 | int em28xx_register_extension(struct em28xx_ops *dev); | 465 | int em28xx_register_extension(struct em28xx_ops *dev); |
360 | void em28xx_unregister_extension(struct em28xx_ops *dev); | 466 | void em28xx_unregister_extension(struct em28xx_ops *dev); |
361 | 467 | ||
362 | /* Provided by em28xx-cards.c */ | 468 | /* Provided by em28xx-cards.c */ |
363 | extern int em2800_variant_detect(struct usb_device* udev,int model); | 469 | extern int em2800_variant_detect(struct usb_device *udev, int model); |
364 | extern void em28xx_pre_card_setup(struct em28xx *dev); | 470 | extern void em28xx_pre_card_setup(struct em28xx *dev); |
365 | extern void em28xx_card_setup(struct em28xx *dev); | 471 | extern void em28xx_card_setup(struct em28xx *dev); |
366 | extern struct em28xx_board em28xx_boards[]; | 472 | extern struct em28xx_board em28xx_boards[]; |
367 | extern struct usb_device_id em28xx_id_table[]; | 473 | extern struct usb_device_id em28xx_id_table[]; |
368 | extern const unsigned int em28xx_bcount; | 474 | extern const unsigned int em28xx_bcount; |
369 | void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); | 475 | void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); |
476 | int em28xx_tuner_callback(void *ptr, int command, int arg); | ||
370 | 477 | ||
371 | /* Provided by em28xx-input.c */ | 478 | /* Provided by em28xx-input.c */ |
372 | /* TODO: Check if the standard get_key handlers on ir-common can be used */ | 479 | /* TODO: Check if the standard get_key handlers on ir-common can be used */ |
@@ -375,71 +482,6 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); | |||
375 | int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, | 482 | int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, |
376 | u32 *ir_raw); | 483 | u32 *ir_raw); |
377 | 484 | ||
378 | /* em2800 registers */ | ||
379 | #define EM2800_AUDIOSRC_REG 0x08 | ||
380 | |||
381 | /* em28xx registers */ | ||
382 | #define I2C_CLK_REG 0x06 | ||
383 | #define CHIPID_REG 0x0a | ||
384 | #define USBSUSP_REG 0x0c /* */ | ||
385 | |||
386 | #define AUDIOSRC_REG 0x0e | ||
387 | #define XCLK_REG 0x0f | ||
388 | |||
389 | #define VINMODE_REG 0x10 | ||
390 | #define VINCTRL_REG 0x11 | ||
391 | #define VINENABLE_REG 0x12 /* */ | ||
392 | |||
393 | #define GAMMA_REG 0x14 | ||
394 | #define RGAIN_REG 0x15 | ||
395 | #define GGAIN_REG 0x16 | ||
396 | #define BGAIN_REG 0x17 | ||
397 | #define ROFFSET_REG 0x18 | ||
398 | #define GOFFSET_REG 0x19 | ||
399 | #define BOFFSET_REG 0x1a | ||
400 | |||
401 | #define OFLOW_REG 0x1b | ||
402 | #define HSTART_REG 0x1c | ||
403 | #define VSTART_REG 0x1d | ||
404 | #define CWIDTH_REG 0x1e | ||
405 | #define CHEIGHT_REG 0x1f | ||
406 | |||
407 | #define YGAIN_REG 0x20 | ||
408 | #define YOFFSET_REG 0x21 | ||
409 | #define UVGAIN_REG 0x22 | ||
410 | #define UOFFSET_REG 0x23 | ||
411 | #define VOFFSET_REG 0x24 | ||
412 | #define SHARPNESS_REG 0x25 | ||
413 | |||
414 | #define COMPR_REG 0x26 | ||
415 | #define OUTFMT_REG 0x27 | ||
416 | |||
417 | #define XMIN_REG 0x28 | ||
418 | #define XMAX_REG 0x29 | ||
419 | #define YMIN_REG 0x2a | ||
420 | #define YMAX_REG 0x2b | ||
421 | |||
422 | #define HSCALELOW_REG 0x30 | ||
423 | #define HSCALEHIGH_REG 0x31 | ||
424 | #define VSCALELOW_REG 0x32 | ||
425 | #define VSCALEHIGH_REG 0x33 | ||
426 | |||
427 | #define AC97LSB_REG 0x40 | ||
428 | #define AC97MSB_REG 0x41 | ||
429 | #define AC97ADDR_REG 0x42 | ||
430 | #define AC97BUSY_REG 0x43 | ||
431 | |||
432 | /* em202 registers */ | ||
433 | #define MASTER_AC97 0x02 | ||
434 | #define LINE_IN_AC97 0x10 | ||
435 | #define VIDEO_AC97 0x14 | ||
436 | |||
437 | /* register settings */ | ||
438 | #define EM2800_AUDIO_SRC_TUNER 0x0d | ||
439 | #define EM2800_AUDIO_SRC_LINE 0x0c | ||
440 | #define EM28XX_AUDIO_SRC_TUNER 0xc0 | ||
441 | #define EM28XX_AUDIO_SRC_LINE 0x80 | ||
442 | |||
443 | /* printk macros */ | 485 | /* printk macros */ |
444 | 486 | ||
445 | #define em28xx_err(fmt, arg...) do {\ | 487 | #define em28xx_err(fmt, arg...) do {\ |
@@ -456,80 +498,80 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, | |||
456 | printk(KERN_WARNING "%s: "fmt,\ | 498 | printk(KERN_WARNING "%s: "fmt,\ |
457 | dev->name , ##arg); } while (0) | 499 | dev->name , ##arg); } while (0) |
458 | 500 | ||
459 | inline static int em28xx_compression_disable(struct em28xx *dev) | 501 | static inline int em28xx_compression_disable(struct em28xx *dev) |
460 | { | 502 | { |
461 | /* side effect of disabling scaler and mixer */ | 503 | /* side effect of disabling scaler and mixer */ |
462 | return em28xx_write_regs(dev, COMPR_REG, "\x00", 1); | 504 | return em28xx_write_regs(dev, EM28XX_R26_COMPR, "\x00", 1); |
463 | } | 505 | } |
464 | 506 | ||
465 | inline static int em28xx_contrast_get(struct em28xx *dev) | 507 | static inline int em28xx_contrast_get(struct em28xx *dev) |
466 | { | 508 | { |
467 | return em28xx_read_reg(dev, YGAIN_REG) & 0x1f; | 509 | return em28xx_read_reg(dev, EM28XX_R20_YGAIN) & 0x1f; |
468 | } | 510 | } |
469 | 511 | ||
470 | inline static int em28xx_brightness_get(struct em28xx *dev) | 512 | static inline int em28xx_brightness_get(struct em28xx *dev) |
471 | { | 513 | { |
472 | return em28xx_read_reg(dev, YOFFSET_REG); | 514 | return em28xx_read_reg(dev, EM28XX_R21_YOFFSET); |
473 | } | 515 | } |
474 | 516 | ||
475 | inline static int em28xx_saturation_get(struct em28xx *dev) | 517 | static inline int em28xx_saturation_get(struct em28xx *dev) |
476 | { | 518 | { |
477 | return em28xx_read_reg(dev, UVGAIN_REG) & 0x1f; | 519 | return em28xx_read_reg(dev, EM28XX_R22_UVGAIN) & 0x1f; |
478 | } | 520 | } |
479 | 521 | ||
480 | inline static int em28xx_u_balance_get(struct em28xx *dev) | 522 | static inline int em28xx_u_balance_get(struct em28xx *dev) |
481 | { | 523 | { |
482 | return em28xx_read_reg(dev, UOFFSET_REG); | 524 | return em28xx_read_reg(dev, EM28XX_R23_UOFFSET); |
483 | } | 525 | } |
484 | 526 | ||
485 | inline static int em28xx_v_balance_get(struct em28xx *dev) | 527 | static inline int em28xx_v_balance_get(struct em28xx *dev) |
486 | { | 528 | { |
487 | return em28xx_read_reg(dev, VOFFSET_REG); | 529 | return em28xx_read_reg(dev, EM28XX_R24_VOFFSET); |
488 | } | 530 | } |
489 | 531 | ||
490 | inline static int em28xx_gamma_get(struct em28xx *dev) | 532 | static inline int em28xx_gamma_get(struct em28xx *dev) |
491 | { | 533 | { |
492 | return em28xx_read_reg(dev, GAMMA_REG) & 0x3f; | 534 | return em28xx_read_reg(dev, EM28XX_R14_GAMMA) & 0x3f; |
493 | } | 535 | } |
494 | 536 | ||
495 | inline static int em28xx_contrast_set(struct em28xx *dev, s32 val) | 537 | static inline int em28xx_contrast_set(struct em28xx *dev, s32 val) |
496 | { | 538 | { |
497 | u8 tmp = (u8) val; | 539 | u8 tmp = (u8) val; |
498 | return em28xx_write_regs(dev, YGAIN_REG, &tmp, 1); | 540 | return em28xx_write_regs(dev, EM28XX_R20_YGAIN, &tmp, 1); |
499 | } | 541 | } |
500 | 542 | ||
501 | inline static int em28xx_brightness_set(struct em28xx *dev, s32 val) | 543 | static inline int em28xx_brightness_set(struct em28xx *dev, s32 val) |
502 | { | 544 | { |
503 | u8 tmp = (u8) val; | 545 | u8 tmp = (u8) val; |
504 | return em28xx_write_regs(dev, YOFFSET_REG, &tmp, 1); | 546 | return em28xx_write_regs(dev, EM28XX_R21_YOFFSET, &tmp, 1); |
505 | } | 547 | } |
506 | 548 | ||
507 | inline static int em28xx_saturation_set(struct em28xx *dev, s32 val) | 549 | static inline int em28xx_saturation_set(struct em28xx *dev, s32 val) |
508 | { | 550 | { |
509 | u8 tmp = (u8) val; | 551 | u8 tmp = (u8) val; |
510 | return em28xx_write_regs(dev, UVGAIN_REG, &tmp, 1); | 552 | return em28xx_write_regs(dev, EM28XX_R22_UVGAIN, &tmp, 1); |
511 | } | 553 | } |
512 | 554 | ||
513 | inline static int em28xx_u_balance_set(struct em28xx *dev, s32 val) | 555 | static inline int em28xx_u_balance_set(struct em28xx *dev, s32 val) |
514 | { | 556 | { |
515 | u8 tmp = (u8) val; | 557 | u8 tmp = (u8) val; |
516 | return em28xx_write_regs(dev, UOFFSET_REG, &tmp, 1); | 558 | return em28xx_write_regs(dev, EM28XX_R23_UOFFSET, &tmp, 1); |
517 | } | 559 | } |
518 | 560 | ||
519 | inline static int em28xx_v_balance_set(struct em28xx *dev, s32 val) | 561 | static inline int em28xx_v_balance_set(struct em28xx *dev, s32 val) |
520 | { | 562 | { |
521 | u8 tmp = (u8) val; | 563 | u8 tmp = (u8) val; |
522 | return em28xx_write_regs(dev, VOFFSET_REG, &tmp, 1); | 564 | return em28xx_write_regs(dev, EM28XX_R24_VOFFSET, &tmp, 1); |
523 | } | 565 | } |
524 | 566 | ||
525 | inline static int em28xx_gamma_set(struct em28xx *dev, s32 val) | 567 | static inline int em28xx_gamma_set(struct em28xx *dev, s32 val) |
526 | { | 568 | { |
527 | u8 tmp = (u8) val; | 569 | u8 tmp = (u8) val; |
528 | return em28xx_write_regs(dev, GAMMA_REG, &tmp, 1); | 570 | return em28xx_write_regs(dev, EM28XX_R14_GAMMA, &tmp, 1); |
529 | } | 571 | } |
530 | 572 | ||
531 | /*FIXME: maxw should be dependent of alt mode */ | 573 | /*FIXME: maxw should be dependent of alt mode */ |
532 | inline static unsigned int norm_maxw(struct em28xx *dev) | 574 | static inline unsigned int norm_maxw(struct em28xx *dev) |
533 | { | 575 | { |
534 | if (dev->max_range_640_480) | 576 | if (dev->max_range_640_480) |
535 | return 640; | 577 | return 640; |
@@ -537,7 +579,7 @@ inline static unsigned int norm_maxw(struct em28xx *dev) | |||
537 | return 720; | 579 | return 720; |
538 | } | 580 | } |
539 | 581 | ||
540 | inline static unsigned int norm_maxh(struct em28xx *dev) | 582 | static inline unsigned int norm_maxh(struct em28xx *dev) |
541 | { | 583 | { |
542 | if (dev->max_range_640_480) | 584 | if (dev->max_range_640_480) |
543 | return 480; | 585 | return 480; |
diff --git a/drivers/media/video/et61x251/et61x251.h b/drivers/media/video/et61x251/et61x251.h index 02c741d8f85a..cc77d144df3c 100644 --- a/drivers/media/video/et61x251/et61x251.h +++ b/drivers/media/video/et61x251/et61x251.h | |||
@@ -199,7 +199,7 @@ do { \ | |||
199 | dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ | 199 | dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ |
200 | else if ((level) >= 3) \ | 200 | else if ((level) >= 3) \ |
201 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \ | 201 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \ |
202 | __FILE__, __FUNCTION__, __LINE__ , ## args); \ | 202 | __FILE__, __func__, __LINE__ , ## args); \ |
203 | } \ | 203 | } \ |
204 | } while (0) | 204 | } while (0) |
205 | # define KDBG(level, fmt, args...) \ | 205 | # define KDBG(level, fmt, args...) \ |
@@ -209,7 +209,7 @@ do { \ | |||
209 | pr_info("et61x251: " fmt "\n", ## args); \ | 209 | pr_info("et61x251: " fmt "\n", ## args); \ |
210 | else if ((level) == 3) \ | 210 | else if ((level) == 3) \ |
211 | pr_debug("sn9c102: [%s:%s:%d] " fmt "\n", __FILE__, \ | 211 | pr_debug("sn9c102: [%s:%s:%d] " fmt "\n", __FILE__, \ |
212 | __FUNCTION__, __LINE__ , ## args); \ | 212 | __func__, __LINE__ , ## args); \ |
213 | } \ | 213 | } \ |
214 | } while (0) | 214 | } while (0) |
215 | # define V4LDBG(level, name, cmd) \ | 215 | # define V4LDBG(level, name, cmd) \ |
@@ -225,7 +225,7 @@ do { \ | |||
225 | 225 | ||
226 | #undef PDBG | 226 | #undef PDBG |
227 | #define PDBG(fmt, args...) \ | 227 | #define PDBG(fmt, args...) \ |
228 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \ | 228 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \ |
229 | __LINE__ , ## args) | 229 | __LINE__ , ## args) |
230 | 230 | ||
231 | #undef PDBGG | 231 | #undef PDBGG |
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index 06b6a3ae06c4..5e749c528a62 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c | |||
@@ -2523,7 +2523,9 @@ static const struct file_operations et61x251_fops = { | |||
2523 | .open = et61x251_open, | 2523 | .open = et61x251_open, |
2524 | .release = et61x251_release, | 2524 | .release = et61x251_release, |
2525 | .ioctl = et61x251_ioctl, | 2525 | .ioctl = et61x251_ioctl, |
2526 | #ifdef CONFIG_COMPAT | ||
2526 | .compat_ioctl = v4l_compat_ioctl32, | 2527 | .compat_ioctl = v4l_compat_ioctl32, |
2528 | #endif | ||
2527 | .read = et61x251_read, | 2529 | .read = et61x251_read, |
2528 | .poll = et61x251_poll, | 2530 | .poll = et61x251_poll, |
2529 | .mmap = et61x251_mmap, | 2531 | .mmap = et61x251_mmap, |
@@ -2538,7 +2540,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2538 | { | 2540 | { |
2539 | struct usb_device *udev = interface_to_usbdev(intf); | 2541 | struct usb_device *udev = interface_to_usbdev(intf); |
2540 | struct et61x251_device* cam; | 2542 | struct et61x251_device* cam; |
2541 | static unsigned int dev_nr = 0; | 2543 | static unsigned int dev_nr; |
2542 | unsigned int i; | 2544 | unsigned int i; |
2543 | int err = 0; | 2545 | int err = 0; |
2544 | 2546 | ||
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index c7fed3405655..352f84d440fb 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c | |||
@@ -25,12 +25,12 @@ | |||
25 | 25 | ||
26 | #include <media/saa7146_vv.h> | 26 | #include <media/saa7146_vv.h> |
27 | 27 | ||
28 | static int debug = 0; | 28 | static int debug; |
29 | module_param(debug, int, 0); | 29 | module_param(debug, int, 0); |
30 | MODULE_PARM_DESC(debug, "debug verbosity"); | 30 | MODULE_PARM_DESC(debug, "debug verbosity"); |
31 | 31 | ||
32 | /* global variables */ | 32 | /* global variables */ |
33 | static int hexium_num = 0; | 33 | static int hexium_num; |
34 | 34 | ||
35 | #define HEXIUM_GEMINI 4 | 35 | #define HEXIUM_GEMINI 4 |
36 | #define HEXIUM_GEMINI_DUAL 5 | 36 | #define HEXIUM_GEMINI_DUAL 5 |
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index 137c4736da04..8d3c1482e7ea 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c | |||
@@ -25,12 +25,12 @@ | |||
25 | 25 | ||
26 | #include <media/saa7146_vv.h> | 26 | #include <media/saa7146_vv.h> |
27 | 27 | ||
28 | static int debug = 0; | 28 | static int debug; |
29 | module_param(debug, int, 0); | 29 | module_param(debug, int, 0); |
30 | MODULE_PARM_DESC(debug, "debug verbosity"); | 30 | MODULE_PARM_DESC(debug, "debug verbosity"); |
31 | 31 | ||
32 | /* global variables */ | 32 | /* global variables */ |
33 | static int hexium_num = 0; | 33 | static int hexium_num; |
34 | 34 | ||
35 | #define HEXIUM_HV_PCI6_ORION 1 | 35 | #define HEXIUM_HV_PCI6_ORION 1 |
36 | #define HEXIUM_ORION_1SVHS_3BNC 2 | 36 | #define HEXIUM_ORION_1SVHS_3BNC 2 |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index dabafdf71e60..11c5fdedc23b 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -50,7 +50,7 @@ | |||
50 | static int debug; | 50 | static int debug; |
51 | module_param(debug, int, 0644); /* debug level (0,1,2) */ | 51 | module_param(debug, int, 0644); /* debug level (0,1,2) */ |
52 | 52 | ||
53 | static int hauppauge = 0; | 53 | static int hauppauge; |
54 | module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */ | 54 | module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */ |
55 | MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)"); | 55 | MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)"); |
56 | 56 | ||
@@ -153,7 +153,7 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
153 | } | 153 | } |
154 | 154 | ||
155 | if(buf[0] !=0 || buf[1] !=0 || buf[2] !=0 || buf[3] != 0) | 155 | if(buf[0] !=0 || buf[1] !=0 || buf[2] !=0 || buf[3] != 0) |
156 | dprintk(2, "%s: 0x%2x 0x%2x 0x%2x 0x%2x\n", __FUNCTION__, | 156 | dprintk(2, "%s: 0x%2x 0x%2x 0x%2x 0x%2x\n", __func__, |
157 | buf[0], buf[1], buf[2], buf[3]); | 157 | buf[0], buf[1], buf[2], buf[3]); |
158 | 158 | ||
159 | /* no key pressed or signal from other ir remote */ | 159 | /* no key pressed or signal from other ir remote */ |
@@ -508,10 +508,10 @@ static int ir_probe(struct i2c_adapter *adap) | |||
508 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; | 508 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; |
509 | static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; | 509 | static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; |
510 | static const int probe_cx23885[] = { 0x6b, -1 }; | 510 | static const int probe_cx23885[] = { 0x6b, -1 }; |
511 | const int *probe = NULL; | 511 | const int *probe; |
512 | struct i2c_client c; | 512 | struct i2c_client *c; |
513 | unsigned char buf; | 513 | unsigned char buf; |
514 | int i,rc; | 514 | int i, rc; |
515 | 515 | ||
516 | switch (adap->id) { | 516 | switch (adap->id) { |
517 | case I2C_HW_B_BT848: | 517 | case I2C_HW_B_BT848: |
@@ -532,23 +532,27 @@ static int ir_probe(struct i2c_adapter *adap) | |||
532 | case I2C_HW_B_CX23885: | 532 | case I2C_HW_B_CX23885: |
533 | probe = probe_cx23885; | 533 | probe = probe_cx23885; |
534 | break; | 534 | break; |
535 | } | 535 | default: |
536 | if (NULL == probe) | ||
537 | return 0; | 536 | return 0; |
537 | } | ||
538 | |||
539 | c = kzalloc(sizeof(*c), GFP_KERNEL); | ||
540 | if (!c) | ||
541 | return -ENOMEM; | ||
538 | 542 | ||
539 | memset(&c,0,sizeof(c)); | 543 | c->adapter = adap; |
540 | c.adapter = adap; | ||
541 | for (i = 0; -1 != probe[i]; i++) { | 544 | for (i = 0; -1 != probe[i]; i++) { |
542 | c.addr = probe[i]; | 545 | c->addr = probe[i]; |
543 | rc = i2c_master_recv(&c,&buf,0); | 546 | rc = i2c_master_recv(c, &buf, 0); |
544 | dprintk(1,"probe 0x%02x @ %s: %s\n", | 547 | dprintk(1,"probe 0x%02x @ %s: %s\n", |
545 | probe[i], adap->name, | 548 | probe[i], adap->name, |
546 | (0 == rc) ? "yes" : "no"); | 549 | (0 == rc) ? "yes" : "no"); |
547 | if (0 == rc) { | 550 | if (0 == rc) { |
548 | ir_attach(adap,probe[i],0,0); | 551 | ir_attach(adap, probe[i], 0, 0); |
549 | break; | 552 | break; |
550 | } | 553 | } |
551 | } | 554 | } |
555 | kfree(c); | ||
552 | return 0; | 556 | return 0; |
553 | } | 557 | } |
554 | 558 | ||
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig index 270906fc3146..b6171702c4d0 100644 --- a/drivers/media/video/ivtv/Kconfig +++ b/drivers/media/video/ivtv/Kconfig | |||
@@ -10,6 +10,7 @@ config VIDEO_IVTV | |||
10 | select VIDEO_CX25840 | 10 | select VIDEO_CX25840 |
11 | select VIDEO_MSP3400 | 11 | select VIDEO_MSP3400 |
12 | select VIDEO_SAA711X | 12 | select VIDEO_SAA711X |
13 | select VIDEO_SAA717X | ||
13 | select VIDEO_SAA7127 | 14 | select VIDEO_SAA7127 |
14 | select VIDEO_TVAUDIO | 15 | select VIDEO_TVAUDIO |
15 | select VIDEO_CS53L32A | 16 | select VIDEO_CS53L32A |
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c index f23c6b8d6911..e908649ea37c 100644 --- a/drivers/media/video/ivtv/ivtv-cards.c +++ b/drivers/media/video/ivtv/ivtv-cards.c | |||
@@ -416,11 +416,10 @@ static const struct ivtv_card ivtv_card_avc2410 = { | |||
416 | on the country/region setting of the user to decide which tuner | 416 | on the country/region setting of the user to decide which tuner |
417 | is available. */ | 417 | is available. */ |
418 | .tuners = { | 418 | .tuners = { |
419 | /* This tuner has been verified for the AVC2410 */ | ||
420 | { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, | 419 | { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, |
421 | /* This is a good guess, but I'm not totally sure this is | 420 | { .std = V4L2_STD_ALL - V4L2_STD_NTSC_M_JP, |
422 | the correct tuner for NTSC. */ | 421 | .tuner = TUNER_PHILIPS_FM1236_MK3 }, |
423 | { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, | 422 | { .std = V4L2_STD_NTSC_M_JP, .tuner = TUNER_PHILIPS_FQ1286 }, |
424 | }, | 423 | }, |
425 | .pci_list = ivtv_pci_avc2410, | 424 | .pci_list = ivtv_pci_avc2410, |
426 | .i2c = &ivtv_i2c_std, | 425 | .i2c = &ivtv_i2c_std, |
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h index 191aafdd9968..9186fa2ee5fc 100644 --- a/drivers/media/video/ivtv/ivtv-cards.h +++ b/drivers/media/video/ivtv/ivtv-cards.h | |||
@@ -119,7 +119,7 @@ | |||
119 | 119 | ||
120 | #define IVTV_CARD_MAX_VIDEO_INPUTS 6 | 120 | #define IVTV_CARD_MAX_VIDEO_INPUTS 6 |
121 | #define IVTV_CARD_MAX_AUDIO_INPUTS 3 | 121 | #define IVTV_CARD_MAX_AUDIO_INPUTS 3 |
122 | #define IVTV_CARD_MAX_TUNERS 2 | 122 | #define IVTV_CARD_MAX_TUNERS 3 |
123 | 123 | ||
124 | /* SAA71XX HW inputs */ | 124 | /* SAA71XX HW inputs */ |
125 | #define IVTV_SAA71XX_COMPOSITE0 0 | 125 | #define IVTV_SAA71XX_COMPOSITE0 0 |
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 948ca35e7ee8..065df53f80fd 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -101,7 +101,7 @@ static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, | |||
101 | static unsigned int cardtype_c = 1; | 101 | static unsigned int cardtype_c = 1; |
102 | static unsigned int tuner_c = 1; | 102 | static unsigned int tuner_c = 1; |
103 | static unsigned int radio_c = 1; | 103 | static unsigned int radio_c = 1; |
104 | static char pal[] = "--"; | 104 | static char pal[] = "---"; |
105 | static char secam[] = "--"; | 105 | static char secam[] = "--"; |
106 | static char ntsc[] = "-"; | 106 | static char ntsc[] = "-"; |
107 | 107 | ||
@@ -126,12 +126,13 @@ static int dec_mpg_buffers = IVTV_DEFAULT_DEC_MPG_BUFFERS; | |||
126 | static int dec_yuv_buffers = IVTV_DEFAULT_DEC_YUV_BUFFERS; | 126 | static int dec_yuv_buffers = IVTV_DEFAULT_DEC_YUV_BUFFERS; |
127 | static int dec_vbi_buffers = IVTV_DEFAULT_DEC_VBI_BUFFERS; | 127 | static int dec_vbi_buffers = IVTV_DEFAULT_DEC_VBI_BUFFERS; |
128 | 128 | ||
129 | static int ivtv_yuv_mode = 0; | 129 | static int ivtv_yuv_mode; |
130 | static int ivtv_yuv_threshold=-1; | 130 | static int ivtv_yuv_threshold = -1; |
131 | static int ivtv_pci_latency = 1; | 131 | static int ivtv_pci_latency = 1; |
132 | 132 | ||
133 | int ivtv_debug = 0; | 133 | int ivtv_debug; |
134 | 134 | ||
135 | static int tunertype = -1; | ||
135 | static int newi2c = -1; | 136 | static int newi2c = -1; |
136 | 137 | ||
137 | module_param_array(tuner, int, &tuner_c, 0644); | 138 | module_param_array(tuner, int, &tuner_c, 0644); |
@@ -154,6 +155,7 @@ module_param(dec_mpg_buffers, int, 0644); | |||
154 | module_param(dec_yuv_buffers, int, 0644); | 155 | module_param(dec_yuv_buffers, int, 0644); |
155 | module_param(dec_vbi_buffers, int, 0644); | 156 | module_param(dec_vbi_buffers, int, 0644); |
156 | 157 | ||
158 | module_param(tunertype, int, 0644); | ||
157 | module_param(newi2c, int, 0644); | 159 | module_param(newi2c, int, 0644); |
158 | 160 | ||
159 | MODULE_PARM_DESC(tuner, "Tuner type selection,\n" | 161 | MODULE_PARM_DESC(tuner, "Tuner type selection,\n" |
@@ -190,9 +192,14 @@ MODULE_PARM_DESC(cardtype, | |||
190 | "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n" | 192 | "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n" |
191 | "\t\t\t 0 = Autodetect (default)\n" | 193 | "\t\t\t 0 = Autodetect (default)\n" |
192 | "\t\t\t-1 = Ignore this card\n\t\t"); | 194 | "\t\t\t-1 = Ignore this card\n\t\t"); |
193 | MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); | 195 | MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60"); |
194 | MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC"); | 196 | MODULE_PARM_DESC(secam, "Set SECAM standard: BGH, DK, L, LC"); |
195 | MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K"); | 197 | MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J (Japan), K (South Korea)"); |
198 | MODULE_PARM_DESC(tunertype, | ||
199 | "Specify tuner type:\n" | ||
200 | "\t\t\t 0 = tuner for PAL-B/G/H/D/K/I, SECAM-B/G/H/D/K/L/Lc\n" | ||
201 | "\t\t\t 1 = tuner for NTSC-M/J/K, PAL-M/N/Nc\n" | ||
202 | "\t\t\t-1 = Autodetect (default)\n"); | ||
196 | MODULE_PARM_DESC(debug, | 203 | MODULE_PARM_DESC(debug, |
197 | "Debug level (bitmask). Default: 0\n" | 204 | "Debug level (bitmask). Default: 0\n" |
198 | "\t\t\t 1/0x0001: warning\n" | 205 | "\t\t\t 1/0x0001: warning\n" |
@@ -490,30 +497,35 @@ static v4l2_std_id ivtv_parse_std(struct ivtv *itv) | |||
490 | { | 497 | { |
491 | switch (pal[0]) { | 498 | switch (pal[0]) { |
492 | case '6': | 499 | case '6': |
500 | tunertype = 0; | ||
493 | return V4L2_STD_PAL_60; | 501 | return V4L2_STD_PAL_60; |
494 | case 'b': | 502 | case 'b': |
495 | case 'B': | 503 | case 'B': |
496 | case 'g': | 504 | case 'g': |
497 | case 'G': | 505 | case 'G': |
498 | return V4L2_STD_PAL_BG; | ||
499 | case 'h': | 506 | case 'h': |
500 | case 'H': | 507 | case 'H': |
501 | return V4L2_STD_PAL_H; | 508 | tunertype = 0; |
509 | return V4L2_STD_PAL_BG | V4L2_STD_PAL_H; | ||
502 | case 'n': | 510 | case 'n': |
503 | case 'N': | 511 | case 'N': |
512 | tunertype = 1; | ||
504 | if (pal[1] == 'c' || pal[1] == 'C') | 513 | if (pal[1] == 'c' || pal[1] == 'C') |
505 | return V4L2_STD_PAL_Nc; | 514 | return V4L2_STD_PAL_Nc; |
506 | return V4L2_STD_PAL_N; | 515 | return V4L2_STD_PAL_N; |
507 | case 'i': | 516 | case 'i': |
508 | case 'I': | 517 | case 'I': |
518 | tunertype = 0; | ||
509 | return V4L2_STD_PAL_I; | 519 | return V4L2_STD_PAL_I; |
510 | case 'd': | 520 | case 'd': |
511 | case 'D': | 521 | case 'D': |
512 | case 'k': | 522 | case 'k': |
513 | case 'K': | 523 | case 'K': |
524 | tunertype = 0; | ||
514 | return V4L2_STD_PAL_DK; | 525 | return V4L2_STD_PAL_DK; |
515 | case 'M': | 526 | case 'M': |
516 | case 'm': | 527 | case 'm': |
528 | tunertype = 1; | ||
517 | return V4L2_STD_PAL_M; | 529 | return V4L2_STD_PAL_M; |
518 | case '-': | 530 | case '-': |
519 | break; | 531 | break; |
@@ -529,14 +541,17 @@ static v4l2_std_id ivtv_parse_std(struct ivtv *itv) | |||
529 | case 'G': | 541 | case 'G': |
530 | case 'h': | 542 | case 'h': |
531 | case 'H': | 543 | case 'H': |
544 | tunertype = 0; | ||
532 | return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; | 545 | return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; |
533 | case 'd': | 546 | case 'd': |
534 | case 'D': | 547 | case 'D': |
535 | case 'k': | 548 | case 'k': |
536 | case 'K': | 549 | case 'K': |
550 | tunertype = 0; | ||
537 | return V4L2_STD_SECAM_DK; | 551 | return V4L2_STD_SECAM_DK; |
538 | case 'l': | 552 | case 'l': |
539 | case 'L': | 553 | case 'L': |
554 | tunertype = 0; | ||
540 | if (secam[1] == 'C' || secam[1] == 'c') | 555 | if (secam[1] == 'C' || secam[1] == 'c') |
541 | return V4L2_STD_SECAM_LC; | 556 | return V4L2_STD_SECAM_LC; |
542 | return V4L2_STD_SECAM_L; | 557 | return V4L2_STD_SECAM_L; |
@@ -550,12 +565,15 @@ static v4l2_std_id ivtv_parse_std(struct ivtv *itv) | |||
550 | switch (ntsc[0]) { | 565 | switch (ntsc[0]) { |
551 | case 'm': | 566 | case 'm': |
552 | case 'M': | 567 | case 'M': |
568 | tunertype = 1; | ||
553 | return V4L2_STD_NTSC_M; | 569 | return V4L2_STD_NTSC_M; |
554 | case 'j': | 570 | case 'j': |
555 | case 'J': | 571 | case 'J': |
572 | tunertype = 1; | ||
556 | return V4L2_STD_NTSC_M_JP; | 573 | return V4L2_STD_NTSC_M_JP; |
557 | case 'k': | 574 | case 'k': |
558 | case 'K': | 575 | case 'K': |
576 | tunertype = 1; | ||
559 | return V4L2_STD_NTSC_M_KR; | 577 | return V4L2_STD_NTSC_M_KR; |
560 | case '-': | 578 | case '-': |
561 | break; | 579 | break; |
@@ -584,8 +602,13 @@ static void ivtv_process_options(struct ivtv *itv) | |||
584 | itv->options.tuner = tuner[itv->num]; | 602 | itv->options.tuner = tuner[itv->num]; |
585 | itv->options.radio = radio[itv->num]; | 603 | itv->options.radio = radio[itv->num]; |
586 | itv->options.newi2c = newi2c; | 604 | itv->options.newi2c = newi2c; |
587 | 605 | if (tunertype < -1 || tunertype > 1) { | |
606 | IVTV_WARN("Invalid tunertype argument, will autodetect instead\n"); | ||
607 | tunertype = -1; | ||
608 | } | ||
588 | itv->std = ivtv_parse_std(itv); | 609 | itv->std = ivtv_parse_std(itv); |
610 | if (itv->std == 0 && tunertype >= 0) | ||
611 | itv->std = tunertype ? V4L2_STD_MN : (V4L2_STD_ALL & ~V4L2_STD_MN); | ||
589 | itv->has_cx23415 = (itv->dev->device == PCI_DEVICE_ID_IVTV15); | 612 | itv->has_cx23415 = (itv->dev->device == PCI_DEVICE_ID_IVTV15); |
590 | chipname = itv->has_cx23415 ? "cx23415" : "cx23416"; | 613 | chipname = itv->has_cx23415 ? "cx23415" : "cx23416"; |
591 | if (itv->options.cardtype == -1) { | 614 | if (itv->options.cardtype == -1) { |
@@ -711,6 +734,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) | |||
711 | itv->yuv_info.lace_mode = ivtv_yuv_mode; | 734 | itv->yuv_info.lace_mode = ivtv_yuv_mode; |
712 | itv->yuv_info.lace_threshold = ivtv_yuv_threshold; | 735 | itv->yuv_info.lace_threshold = ivtv_yuv_threshold; |
713 | itv->yuv_info.max_frames_buffered = 3; | 736 | itv->yuv_info.max_frames_buffered = 3; |
737 | itv->yuv_info.track_osd = 1; | ||
714 | return 0; | 738 | return 0; |
715 | } | 739 | } |
716 | 740 | ||
@@ -859,7 +883,9 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) | |||
859 | #ifndef CONFIG_VIDEO_SAA7127 | 883 | #ifndef CONFIG_VIDEO_SAA7127 |
860 | hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127); | 884 | hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127); |
861 | #endif | 885 | #endif |
886 | #ifndef CONFIG_VIDEO_SAA717X | ||
862 | hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X); | 887 | hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X); |
888 | #endif | ||
863 | #ifndef CONFIG_VIDEO_UPD64031A | 889 | #ifndef CONFIG_VIDEO_UPD64031A |
864 | hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A); | 890 | hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A); |
865 | #endif | 891 | #endif |
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 536140f0c19e..ba06e813c58c 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -456,6 +456,8 @@ struct yuv_playback_info | |||
456 | int v_filter_2; | 456 | int v_filter_2; |
457 | int h_filter; | 457 | int h_filter; |
458 | 458 | ||
459 | u8 track_osd; /* Should yuv output track the OSD size & position */ | ||
460 | |||
459 | u32 osd_x_offset; | 461 | u32 osd_x_offset; |
460 | u32 osd_y_offset; | 462 | u32 osd_y_offset; |
461 | 463 | ||
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 6fb96f19a866..a7640c49f1d8 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -219,7 +219,9 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, | |||
219 | /* Process pending program info updates and pending VBI data */ | 219 | /* Process pending program info updates and pending VBI data */ |
220 | ivtv_update_pgm_info(itv); | 220 | ivtv_update_pgm_info(itv); |
221 | 221 | ||
222 | if (jiffies - itv->dualwatch_jiffies > msecs_to_jiffies(1000)) { | 222 | if (time_after(jiffies, |
223 | itv->dualwatch_jiffies + | ||
224 | msecs_to_jiffies(1000))) { | ||
223 | itv->dualwatch_jiffies = jiffies; | 225 | itv->dualwatch_jiffies = jiffies; |
224 | ivtv_dualwatch(itv); | 226 | ivtv_dualwatch(itv); |
225 | } | 227 | } |
@@ -753,7 +755,7 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait) | |||
753 | IVTV_DEBUG_HI_FILE("Encoder poll\n"); | 755 | IVTV_DEBUG_HI_FILE("Encoder poll\n"); |
754 | poll_wait(filp, &s->waitq, wait); | 756 | poll_wait(filp, &s->waitq, wait); |
755 | 757 | ||
756 | if (eof || s->q_full.length) | 758 | if (eof || s->q_full.length || s->q_io.length) |
757 | return POLLIN | POLLRDNORM; | 759 | return POLLIN | POLLRDNORM; |
758 | return 0; | 760 | return 0; |
759 | } | 761 | } |
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index fa5ab1eb1800..9824eafee021 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c | |||
@@ -177,10 +177,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | if (id != I2C_DRIVERID_TUNER) { | 179 | if (id != I2C_DRIVERID_TUNER) { |
180 | c = i2c_new_device(&itv->i2c_adap, &info); | 180 | if (id == I2C_DRIVERID_UPD64031A || |
181 | if (c->driver == NULL) | 181 | id == I2C_DRIVERID_UPD64083) { |
182 | unsigned short addrs[2] = { info.addr, I2C_CLIENT_END }; | ||
183 | |||
184 | c = i2c_new_probed_device(&itv->i2c_adap, &info, addrs); | ||
185 | } else | ||
186 | c = i2c_new_device(&itv->i2c_adap, &info); | ||
187 | if (c && c->driver == NULL) | ||
182 | i2c_unregister_device(c); | 188 | i2c_unregister_device(c); |
183 | else | 189 | else if (c) |
184 | itv->i2c_clients[i] = c; | 190 | itv->i2c_clients[i] = c; |
185 | return itv->i2c_clients[i] ? 0 : -ENODEV; | 191 | return itv->i2c_clients[i] ? 0 : -ENODEV; |
186 | } | 192 | } |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index edef2a579617..15cac1812122 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -712,6 +712,7 @@ static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg) | |||
712 | int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg) | 712 | int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg) |
713 | { | 713 | { |
714 | struct ivtv_open_id *id = NULL; | 714 | struct ivtv_open_id *id = NULL; |
715 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
715 | u32 data[CX2341X_MBOX_MAX_DATA]; | 716 | u32 data[CX2341X_MBOX_MAX_DATA]; |
716 | int streamtype = 0; | 717 | int streamtype = 0; |
717 | 718 | ||
@@ -741,7 +742,8 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
741 | 742 | ||
742 | memset(vcap, 0, sizeof(*vcap)); | 743 | memset(vcap, 0, sizeof(*vcap)); |
743 | strcpy(vcap->driver, IVTV_DRIVER_NAME); /* driver name */ | 744 | strcpy(vcap->driver, IVTV_DRIVER_NAME); /* driver name */ |
744 | strcpy(vcap->card, itv->card_name); /* card type */ | 745 | strncpy(vcap->card, itv->card_name, |
746 | sizeof(vcap->card)-1); /* card type */ | ||
745 | strcpy(vcap->bus_info, pci_name(itv->dev)); /* bus info... */ | 747 | strcpy(vcap->bus_info, pci_name(itv->dev)); /* bus info... */ |
746 | vcap->version = IVTV_DRIVER_VERSION; /* version */ | 748 | vcap->version = IVTV_DRIVER_VERSION; /* version */ |
747 | vcap->capabilities = itv->v4l2_cap; /* capabilities */ | 749 | vcap->capabilities = itv->v4l2_cap; /* capabilities */ |
@@ -827,8 +829,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
827 | case VIDIOC_CROPCAP: { | 829 | case VIDIOC_CROPCAP: { |
828 | struct v4l2_cropcap *cropcap = arg; | 830 | struct v4l2_cropcap *cropcap = arg; |
829 | 831 | ||
830 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | 832 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) |
831 | cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
832 | return -EINVAL; | 833 | return -EINVAL; |
833 | cropcap->bounds.top = cropcap->bounds.left = 0; | 834 | cropcap->bounds.top = cropcap->bounds.left = 0; |
834 | cropcap->bounds.width = 720; | 835 | cropcap->bounds.width = 720; |
@@ -837,8 +838,14 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
837 | cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; | 838 | cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; |
838 | cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; | 839 | cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; |
839 | } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | 840 | } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { |
840 | cropcap->bounds.width = itv->yuv_info.osd_full_w; | 841 | if (yi->track_osd) { |
841 | cropcap->bounds.height = itv->yuv_info.osd_full_h; | 842 | cropcap->bounds.width = yi->osd_full_w; |
843 | cropcap->bounds.height = yi->osd_full_h; | ||
844 | } else { | ||
845 | cropcap->bounds.width = 720; | ||
846 | cropcap->bounds.height = | ||
847 | itv->is_out_50hz ? 576 : 480; | ||
848 | } | ||
842 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; | 849 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; |
843 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; | 850 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; |
844 | } else { | 851 | } else { |
@@ -856,7 +863,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
856 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | 863 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && |
857 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | 864 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { |
858 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | 865 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { |
859 | itv->yuv_info.main_rect = crop->c; | 866 | yi->main_rect = crop->c; |
860 | return 0; | 867 | return 0; |
861 | } else { | 868 | } else { |
862 | if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | 869 | if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, |
@@ -867,9 +874,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
867 | } | 874 | } |
868 | return -EINVAL; | 875 | return -EINVAL; |
869 | } | 876 | } |
870 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 877 | return -EINVAL; |
871 | return -EINVAL; | ||
872 | return itv->video_dec_func(itv, VIDIOC_S_CROP, arg); | ||
873 | } | 878 | } |
874 | 879 | ||
875 | case VIDIOC_G_CROP: { | 880 | case VIDIOC_G_CROP: { |
@@ -878,14 +883,12 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
878 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | 883 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && |
879 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | 884 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { |
880 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) | 885 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) |
881 | crop->c = itv->yuv_info.main_rect; | 886 | crop->c = yi->main_rect; |
882 | else | 887 | else |
883 | crop->c = itv->main_rect; | 888 | crop->c = itv->main_rect; |
884 | return 0; | 889 | return 0; |
885 | } | 890 | } |
886 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 891 | return -EINVAL; |
887 | return -EINVAL; | ||
888 | return itv->video_dec_func(itv, VIDIOC_G_CROP, arg); | ||
889 | } | 892 | } |
890 | 893 | ||
891 | case VIDIOC_ENUM_FMT: { | 894 | case VIDIOC_ENUM_FMT: { |
@@ -1070,11 +1073,10 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1070 | itv->main_rect.height = itv->params.height; | 1073 | itv->main_rect.height = itv->params.height; |
1071 | ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | 1074 | ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, |
1072 | 720, itv->main_rect.height, 0, 0); | 1075 | 720, itv->main_rect.height, 0, 0); |
1073 | itv->yuv_info.main_rect = itv->main_rect; | 1076 | yi->main_rect = itv->main_rect; |
1074 | if (!itv->osd_info) { | 1077 | if (!itv->osd_info) { |
1075 | itv->yuv_info.osd_full_w = 720; | 1078 | yi->osd_full_w = 720; |
1076 | itv->yuv_info.osd_full_h = | 1079 | yi->osd_full_h = itv->is_out_50hz ? 576 : 480; |
1077 | itv->is_out_50hz ? 576 : 480; | ||
1078 | } | 1080 | } |
1079 | } | 1081 | } |
1080 | break; | 1082 | break; |
@@ -1272,6 +1274,8 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1272 | else | 1274 | else |
1273 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; | 1275 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; |
1274 | } | 1276 | } |
1277 | if (yi->track_osd) | ||
1278 | fb->flags |= V4L2_FBUF_FLAG_OVERLAY; | ||
1275 | break; | 1279 | break; |
1276 | } | 1280 | } |
1277 | 1281 | ||
@@ -1285,6 +1289,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1285 | (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0; | 1289 | (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0; |
1286 | itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; | 1290 | itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; |
1287 | ivtv_set_osd_alpha(itv); | 1291 | ivtv_set_osd_alpha(itv); |
1292 | yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0; | ||
1288 | break; | 1293 | break; |
1289 | } | 1294 | } |
1290 | 1295 | ||
@@ -1628,6 +1633,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, | |||
1628 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { | 1633 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { |
1629 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); | 1634 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); |
1630 | v4l_printk_ioctl(cmd); | 1635 | v4l_printk_ioctl(cmd); |
1636 | printk("\n"); | ||
1631 | } | 1637 | } |
1632 | return ivtv_debug_ioctls(filp, cmd, arg); | 1638 | return ivtv_debug_ioctls(filp, cmd, arg); |
1633 | 1639 | ||
@@ -1671,6 +1677,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, | |||
1671 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { | 1677 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { |
1672 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); | 1678 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); |
1673 | v4l_printk_ioctl(cmd); | 1679 | v4l_printk_ioctl(cmd); |
1680 | printk("\n"); | ||
1674 | } | 1681 | } |
1675 | return ivtv_v4l2_ioctls(itv, filp, cmd, arg); | 1682 | return ivtv_v4l2_ioctls(itv, filp, cmd, arg); |
1676 | 1683 | ||
@@ -1684,6 +1691,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, | |||
1684 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { | 1691 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { |
1685 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); | 1692 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); |
1686 | v4l_printk_ioctl(cmd); | 1693 | v4l_printk_ioctl(cmd); |
1694 | printk("\n"); | ||
1687 | } | 1695 | } |
1688 | return ivtv_control_ioctls(itv, cmd, arg); | 1696 | return ivtv_control_ioctls(itv, cmd, arg); |
1689 | 1697 | ||
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index 65604dde9726..a329c4689dbf 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c | |||
@@ -384,6 +384,8 @@ static void ivtv_dma_enc_start_xfer(struct ivtv_stream *s) | |||
384 | ivtv_stream_sync_for_device(s); | 384 | ivtv_stream_sync_for_device(s); |
385 | write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR); | 385 | write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR); |
386 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER); | 386 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER); |
387 | itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); | ||
388 | add_timer(&itv->dma_timer); | ||
387 | } | 389 | } |
388 | 390 | ||
389 | static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s) | 391 | static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s) |
@@ -398,6 +400,8 @@ static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s) | |||
398 | ivtv_stream_sync_for_device(s); | 400 | ivtv_stream_sync_for_device(s); |
399 | write_reg(s->sg_handle, IVTV_REG_DECDMAADDR); | 401 | write_reg(s->sg_handle, IVTV_REG_DECDMAADDR); |
400 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); | 402 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); |
403 | itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); | ||
404 | add_timer(&itv->dma_timer); | ||
401 | } | 405 | } |
402 | 406 | ||
403 | /* start the encoder DMA */ | 407 | /* start the encoder DMA */ |
@@ -459,8 +463,6 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) | |||
459 | ivtv_dma_enc_start_xfer(s); | 463 | ivtv_dma_enc_start_xfer(s); |
460 | set_bit(IVTV_F_I_DMA, &itv->i_flags); | 464 | set_bit(IVTV_F_I_DMA, &itv->i_flags); |
461 | itv->cur_dma_stream = s->type; | 465 | itv->cur_dma_stream = s->type; |
462 | itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); | ||
463 | add_timer(&itv->dma_timer); | ||
464 | } | 466 | } |
465 | } | 467 | } |
466 | 468 | ||
@@ -481,8 +483,6 @@ static void ivtv_dma_dec_start(struct ivtv_stream *s) | |||
481 | ivtv_dma_dec_start_xfer(s); | 483 | ivtv_dma_dec_start_xfer(s); |
482 | set_bit(IVTV_F_I_DMA, &itv->i_flags); | 484 | set_bit(IVTV_F_I_DMA, &itv->i_flags); |
483 | itv->cur_dma_stream = s->type; | 485 | itv->cur_dma_stream = s->type; |
484 | itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); | ||
485 | add_timer(&itv->dma_timer); | ||
486 | } | 486 | } |
487 | 487 | ||
488 | static void ivtv_irq_dma_read(struct ivtv *itv) | 488 | static void ivtv_irq_dma_read(struct ivtv *itv) |
@@ -492,10 +492,11 @@ static void ivtv_irq_dma_read(struct ivtv *itv) | |||
492 | int hw_stream_type = 0; | 492 | int hw_stream_type = 0; |
493 | 493 | ||
494 | IVTV_DEBUG_HI_IRQ("DEC DMA READ\n"); | 494 | IVTV_DEBUG_HI_IRQ("DEC DMA READ\n"); |
495 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0) { | 495 | |
496 | del_timer(&itv->dma_timer); | 496 | del_timer(&itv->dma_timer); |
497 | |||
498 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0) | ||
497 | return; | 499 | return; |
498 | } | ||
499 | 500 | ||
500 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { | 501 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { |
501 | s = &itv->streams[itv->cur_dma_stream]; | 502 | s = &itv->streams[itv->cur_dma_stream]; |
@@ -543,7 +544,6 @@ static void ivtv_irq_dma_read(struct ivtv *itv) | |||
543 | } | 544 | } |
544 | wake_up(&s->waitq); | 545 | wake_up(&s->waitq); |
545 | } | 546 | } |
546 | del_timer(&itv->dma_timer); | ||
547 | clear_bit(IVTV_F_I_UDMA, &itv->i_flags); | 547 | clear_bit(IVTV_F_I_UDMA, &itv->i_flags); |
548 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); | 548 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); |
549 | itv->cur_dma_stream = -1; | 549 | itv->cur_dma_stream = -1; |
@@ -557,10 +557,12 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv) | |||
557 | 557 | ||
558 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); | 558 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); |
559 | IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream); | 559 | IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream); |
560 | if (itv->cur_dma_stream < 0) { | 560 | |
561 | del_timer(&itv->dma_timer); | 561 | del_timer(&itv->dma_timer); |
562 | |||
563 | if (itv->cur_dma_stream < 0) | ||
562 | return; | 564 | return; |
563 | } | 565 | |
564 | s = &itv->streams[itv->cur_dma_stream]; | 566 | s = &itv->streams[itv->cur_dma_stream]; |
565 | ivtv_stream_sync_for_cpu(s); | 567 | ivtv_stream_sync_for_cpu(s); |
566 | 568 | ||
@@ -585,7 +587,6 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv) | |||
585 | ivtv_dma_enc_start_xfer(s); | 587 | ivtv_dma_enc_start_xfer(s); |
586 | return; | 588 | return; |
587 | } | 589 | } |
588 | del_timer(&itv->dma_timer); | ||
589 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); | 590 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); |
590 | itv->cur_dma_stream = -1; | 591 | itv->cur_dma_stream = -1; |
591 | dma_post(s); | 592 | dma_post(s); |
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c index 13a6c374d2db..1b5c0ac09a85 100644 --- a/drivers/media/video/ivtv/ivtv-mailbox.c +++ b/drivers/media/video/ivtv/ivtv-mailbox.c | |||
@@ -177,7 +177,8 @@ static int get_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int f | |||
177 | 177 | ||
178 | /* Sleep before a retry, if not atomic */ | 178 | /* Sleep before a retry, if not atomic */ |
179 | if (!(flags & API_NO_WAIT_MB)) { | 179 | if (!(flags & API_NO_WAIT_MB)) { |
180 | if (jiffies - then > msecs_to_jiffies(10*retries)) | 180 | if (time_after(jiffies, |
181 | then + msecs_to_jiffies(10*retries))) | ||
181 | break; | 182 | break; |
182 | ivtv_msleep_timeout(10, 0); | 183 | ivtv_msleep_timeout(10, 0); |
183 | } | 184 | } |
@@ -244,7 +245,9 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) | |||
244 | data, then just return 0 as there is no need to issue this command again. | 245 | data, then just return 0 as there is no need to issue this command again. |
245 | Just an optimization to prevent unnecessary use of mailboxes. */ | 246 | Just an optimization to prevent unnecessary use of mailboxes. */ |
246 | if (itv->api_cache[cmd].last_jiffies && | 247 | if (itv->api_cache[cmd].last_jiffies && |
247 | jiffies - itv->api_cache[cmd].last_jiffies < msecs_to_jiffies(1800000) && | 248 | time_before(jiffies, |
249 | itv->api_cache[cmd].last_jiffies + | ||
250 | msecs_to_jiffies(1800000)) && | ||
248 | !memcmp(data, itv->api_cache[cmd].data, sizeof(itv->api_cache[cmd].data))) { | 251 | !memcmp(data, itv->api_cache[cmd].data, sizeof(itv->api_cache[cmd].data))) { |
249 | itv->api_cache[cmd].last_jiffies = jiffies; | 252 | itv->api_cache[cmd].last_jiffies = jiffies; |
250 | return 0; | 253 | return 0; |
@@ -299,7 +302,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) | |||
299 | } | 302 | } |
300 | } | 303 | } |
301 | while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) { | 304 | while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) { |
302 | if (jiffies - then > api_timeout) { | 305 | if (time_after(jiffies, then + api_timeout)) { |
303 | IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name); | 306 | IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name); |
304 | /* reset the mailbox, but it is likely too late already */ | 307 | /* reset the mailbox, but it is likely too late already */ |
305 | write_sync(0, &mbox->flags); | 308 | write_sync(0, &mbox->flags); |
@@ -311,7 +314,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) | |||
311 | else | 314 | else |
312 | ivtv_msleep_timeout(1, 0); | 315 | ivtv_msleep_timeout(1, 0); |
313 | } | 316 | } |
314 | if (jiffies - then > msecs_to_jiffies(100)) | 317 | if (time_after(jiffies, then + msecs_to_jiffies(100))) |
315 | IVTV_DEBUG_WARN("%s took %u jiffies\n", | 318 | IVTV_DEBUG_WARN("%s took %u jiffies\n", |
316 | api_info[cmd].name, | 319 | api_info[cmd].name, |
317 | jiffies_to_msecs(jiffies - then)); | 320 | jiffies_to_msecs(jiffies - then)); |
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c index 39a216713244..3e1deec67a5e 100644 --- a/drivers/media/video/ivtv/ivtv-queue.c +++ b/drivers/media/video/ivtv/ivtv-queue.c | |||
@@ -51,7 +51,7 @@ void ivtv_queue_init(struct ivtv_queue *q) | |||
51 | 51 | ||
52 | void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_queue *q) | 52 | void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_queue *q) |
53 | { | 53 | { |
54 | unsigned long flags = 0; | 54 | unsigned long flags; |
55 | 55 | ||
56 | /* clear the buffer if it is going to be enqueued to the free queue */ | 56 | /* clear the buffer if it is going to be enqueued to the free queue */ |
57 | if (q == &s->q_free) { | 57 | if (q == &s->q_free) { |
@@ -71,7 +71,7 @@ void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_qu | |||
71 | struct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q) | 71 | struct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q) |
72 | { | 72 | { |
73 | struct ivtv_buffer *buf = NULL; | 73 | struct ivtv_buffer *buf = NULL; |
74 | unsigned long flags = 0; | 74 | unsigned long flags; |
75 | 75 | ||
76 | spin_lock_irqsave(&s->qlock, flags); | 76 | spin_lock_irqsave(&s->qlock, flags); |
77 | if (!list_empty(&q->list)) { | 77 | if (!list_empty(&q->list)) { |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 24d98ecf35ad..4ab8d36831ba 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -768,7 +768,8 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) | |||
768 | 768 | ||
769 | /* wait 2s for EOS interrupt */ | 769 | /* wait 2s for EOS interrupt */ |
770 | while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) && | 770 | while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) && |
771 | jiffies < then + msecs_to_jiffies (2000)) { | 771 | time_before(jiffies, |
772 | then + msecs_to_jiffies(2000))) { | ||
772 | schedule_timeout(msecs_to_jiffies(10)); | 773 | schedule_timeout(msecs_to_jiffies(10)); |
773 | } | 774 | } |
774 | 775 | ||
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index 85183480a225..393d917cd672 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.c +++ b/drivers/media/video/ivtv/ivtv-yuv.c | |||
@@ -718,9 +718,11 @@ static u32 ivtv_yuv_window_setup(struct ivtv *itv, struct yuv_frame_info *f) | |||
718 | f->src_w -= (osd_scale * osd_crop) >> 16; | 718 | f->src_w -= (osd_scale * osd_crop) >> 16; |
719 | } | 719 | } |
720 | 720 | ||
721 | /* The OSD can be moved. Track to it */ | 721 | if (itv->yuv_info.track_osd) { |
722 | f->dst_x += itv->yuv_info.osd_x_offset; | 722 | /* The OSD can be moved. Track to it */ |
723 | f->dst_y += itv->yuv_info.osd_y_offset; | 723 | f->dst_x += itv->yuv_info.osd_x_offset; |
724 | f->dst_y += itv->yuv_info.osd_y_offset; | ||
725 | } | ||
724 | 726 | ||
725 | /* Width & height for both src & dst must be even. | 727 | /* Width & height for both src & dst must be even. |
726 | Same for coordinates. */ | 728 | Same for coordinates. */ |
@@ -792,11 +794,19 @@ void ivtv_yuv_work_handler(struct ivtv *itv) | |||
792 | IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame); | 794 | IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame); |
793 | f = yi->new_frame_info[frame]; | 795 | f = yi->new_frame_info[frame]; |
794 | 796 | ||
795 | /* Update the osd pan info */ | 797 | if (yi->track_osd) { |
796 | f.pan_x = yi->osd_x_pan; | 798 | /* Snapshot the osd pan info */ |
797 | f.pan_y = yi->osd_y_pan; | 799 | f.pan_x = yi->osd_x_pan; |
798 | f.vis_w = yi->osd_vis_w; | 800 | f.pan_y = yi->osd_y_pan; |
799 | f.vis_h = yi->osd_vis_h; | 801 | f.vis_w = yi->osd_vis_w; |
802 | f.vis_h = yi->osd_vis_h; | ||
803 | } else { | ||
804 | /* Not tracking the osd, so assume full screen */ | ||
805 | f.pan_x = 0; | ||
806 | f.pan_y = 0; | ||
807 | f.vis_w = 720; | ||
808 | f.vis_h = yi->decode_height; | ||
809 | } | ||
800 | 810 | ||
801 | /* Calculate the display window coordinates. Exit if nothing left */ | 811 | /* Calculate the display window coordinates. Exit if nothing left */ |
802 | if (!(yuv_update = ivtv_yuv_window_setup(itv, &f))) | 812 | if (!(yuv_update = ivtv_yuv_window_setup(itv, &f))) |
@@ -914,7 +924,7 @@ static void ivtv_yuv_init(struct ivtv *itv) | |||
914 | } | 924 | } |
915 | 925 | ||
916 | /* Get next available yuv buffer on PVR350 */ | 926 | /* Get next available yuv buffer on PVR350 */ |
917 | void ivtv_yuv_next_free(struct ivtv *itv) | 927 | static void ivtv_yuv_next_free(struct ivtv *itv) |
918 | { | 928 | { |
919 | int draw, display; | 929 | int draw, display; |
920 | struct yuv_playback_info *yi = &itv->yuv_info; | 930 | struct yuv_playback_info *yi = &itv->yuv_info; |
@@ -937,7 +947,7 @@ void ivtv_yuv_next_free(struct ivtv *itv) | |||
937 | } | 947 | } |
938 | 948 | ||
939 | /* Set up frame according to ivtv_dma_frame parameters */ | 949 | /* Set up frame according to ivtv_dma_frame parameters */ |
940 | void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | 950 | static void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args) |
941 | { | 951 | { |
942 | struct yuv_playback_info *yi = &itv->yuv_info; | 952 | struct yuv_playback_info *yi = &itv->yuv_info; |
943 | u8 frame = yi->draw_frame; | 953 | u8 frame = yi->draw_frame; |
@@ -965,12 +975,6 @@ void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | |||
965 | /* Are we going to offset the Y plane */ | 975 | /* Are we going to offset the Y plane */ |
966 | nf->offset_y = (nf->tru_h + nf->src_x < 512 - 16) ? 1 : 0; | 976 | nf->offset_y = (nf->tru_h + nf->src_x < 512 - 16) ? 1 : 0; |
967 | 977 | ||
968 | /* Snapshot the osd pan info */ | ||
969 | nf->pan_x = yi->osd_x_pan; | ||
970 | nf->pan_y = yi->osd_y_pan; | ||
971 | nf->vis_w = yi->osd_vis_w; | ||
972 | nf->vis_h = yi->osd_vis_h; | ||
973 | |||
974 | nf->update = 0; | 978 | nf->update = 0; |
975 | nf->interlaced_y = 0; | 979 | nf->interlaced_y = 0; |
976 | nf->interlaced_uv = 0; | 980 | nf->interlaced_uv = 0; |
@@ -1042,7 +1046,7 @@ void ivtv_yuv_frame_complete(struct ivtv *itv) | |||
1042 | (itv->yuv_info.draw_frame + 1) % IVTV_YUV_BUFFERS); | 1046 | (itv->yuv_info.draw_frame + 1) % IVTV_YUV_BUFFERS); |
1043 | } | 1047 | } |
1044 | 1048 | ||
1045 | int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | 1049 | static int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args) |
1046 | { | 1050 | { |
1047 | DEFINE_WAIT(wait); | 1051 | DEFINE_WAIT(wait); |
1048 | int rc = 0; | 1052 | int rc = 0; |
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 3d51fa0a52b6..e7ccbc895d7a 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
@@ -42,15 +42,10 @@ | |||
42 | #include <linux/meye.h> | 42 | #include <linux/meye.h> |
43 | 43 | ||
44 | MODULE_AUTHOR("Stelian Pop <stelian@popies.net>"); | 44 | MODULE_AUTHOR("Stelian Pop <stelian@popies.net>"); |
45 | MODULE_DESCRIPTION("v4l/v4l2 driver for the MotionEye camera"); | 45 | MODULE_DESCRIPTION("v4l2 driver for the MotionEye camera"); |
46 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL"); |
47 | MODULE_VERSION(MEYE_DRIVER_VERSION); | 47 | MODULE_VERSION(MEYE_DRIVER_VERSION); |
48 | 48 | ||
49 | /* force usage of V4L1 API */ | ||
50 | static int forcev4l1; /* = 0 */ | ||
51 | module_param(forcev4l1, int, 0644); | ||
52 | MODULE_PARM_DESC(forcev4l1, "force use of V4L1 instead of V4L2"); | ||
53 | |||
54 | /* number of grab buffers */ | 49 | /* number of grab buffers */ |
55 | static unsigned int gbuffers = 2; | 50 | static unsigned int gbuffers = 2; |
56 | module_param(gbuffers, int, 0444); | 51 | module_param(gbuffers, int, 0444); |
@@ -789,7 +784,7 @@ static irqreturn_t meye_irq(int irq, void *dev_id) | |||
789 | { | 784 | { |
790 | u32 v; | 785 | u32 v; |
791 | int reqnr; | 786 | int reqnr; |
792 | static int sequence = 0; | 787 | static int sequence; |
793 | 788 | ||
794 | v = mchip_read(MCHIP_MM_INTA); | 789 | v = mchip_read(MCHIP_MM_INTA); |
795 | 790 | ||
@@ -876,795 +871,735 @@ static int meye_release(struct inode *inode, struct file *file) | |||
876 | return 0; | 871 | return 0; |
877 | } | 872 | } |
878 | 873 | ||
879 | static int meye_do_ioctl(struct inode *inode, struct file *file, | 874 | static int meyeioc_g_params(struct meye_params *p) |
880 | unsigned int cmd, void *arg) | ||
881 | { | 875 | { |
882 | switch (cmd) { | 876 | *p = meye.params; |
877 | return 0; | ||
878 | } | ||
883 | 879 | ||
884 | case VIDIOCGCAP: { | 880 | static int meyeioc_s_params(struct meye_params *jp) |
885 | struct video_capability *b = arg; | 881 | { |
886 | strcpy(b->name,meye.video_dev->name); | 882 | if (jp->subsample > 1) |
887 | b->type = VID_TYPE_CAPTURE; | 883 | return -EINVAL; |
888 | b->channels = 1; | ||
889 | b->audios = 0; | ||
890 | b->maxwidth = 640; | ||
891 | b->maxheight = 480; | ||
892 | b->minwidth = 320; | ||
893 | b->minheight = 240; | ||
894 | break; | ||
895 | } | ||
896 | 884 | ||
897 | case VIDIOCGCHAN: { | 885 | if (jp->quality > 10) |
898 | struct video_channel *v = arg; | 886 | return -EINVAL; |
899 | v->flags = 0; | ||
900 | v->tuners = 0; | ||
901 | v->type = VIDEO_TYPE_CAMERA; | ||
902 | if (v->channel != 0) | ||
903 | return -EINVAL; | ||
904 | strcpy(v->name,"Camera"); | ||
905 | break; | ||
906 | } | ||
907 | 887 | ||
908 | case VIDIOCSCHAN: { | 888 | if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63) |
909 | struct video_channel *v = arg; | 889 | return -EINVAL; |
910 | if (v->channel != 0) | ||
911 | return -EINVAL; | ||
912 | break; | ||
913 | } | ||
914 | 890 | ||
915 | case VIDIOCGPICT: { | 891 | if (jp->framerate > 31) |
916 | struct video_picture *p = arg; | 892 | return -EINVAL; |
917 | *p = meye.picture; | ||
918 | break; | ||
919 | } | ||
920 | 893 | ||
921 | case VIDIOCSPICT: { | 894 | mutex_lock(&meye.lock); |
922 | struct video_picture *p = arg; | ||
923 | if (p->depth != 16) | ||
924 | return -EINVAL; | ||
925 | if (p->palette != VIDEO_PALETTE_YUV422 && p->palette != VIDEO_PALETTE_YUYV) | ||
926 | return -EINVAL; | ||
927 | mutex_lock(&meye.lock); | ||
928 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, | ||
929 | p->brightness >> 10); | ||
930 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAHUE, | ||
931 | p->hue >> 10); | ||
932 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACOLOR, | ||
933 | p->colour >> 10); | ||
934 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACONTRAST, | ||
935 | p->contrast >> 10); | ||
936 | meye.picture = *p; | ||
937 | mutex_unlock(&meye.lock); | ||
938 | break; | ||
939 | } | ||
940 | 895 | ||
941 | case VIDIOCSYNC: { | 896 | if (meye.params.subsample != jp->subsample || |
942 | int *i = arg; | 897 | meye.params.quality != jp->quality) |
943 | int unused; | 898 | mchip_hic_stop(); /* need restart */ |
899 | |||
900 | meye.params = *jp; | ||
901 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERASHARPNESS, | ||
902 | meye.params.sharpness); | ||
903 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, | ||
904 | meye.params.agc); | ||
905 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, | ||
906 | meye.params.picture); | ||
907 | mutex_unlock(&meye.lock); | ||
944 | 908 | ||
945 | if (*i < 0 || *i >= gbuffers) | 909 | return 0; |
946 | return -EINVAL; | 910 | } |
947 | 911 | ||
948 | mutex_lock(&meye.lock); | 912 | static int meyeioc_qbuf_capt(int *nb) |
913 | { | ||
914 | if (!meye.grab_fbuffer) | ||
915 | return -EINVAL; | ||
949 | 916 | ||
950 | switch (meye.grab_buffer[*i].state) { | 917 | if (*nb >= gbuffers) |
918 | return -EINVAL; | ||
951 | 919 | ||
952 | case MEYE_BUF_UNUSED: | 920 | if (*nb < 0) { |
953 | mutex_unlock(&meye.lock); | 921 | /* stop capture */ |
954 | return -EINVAL; | 922 | mchip_hic_stop(); |
955 | case MEYE_BUF_USING: | 923 | return 0; |
956 | if (file->f_flags & O_NONBLOCK) { | ||
957 | mutex_unlock(&meye.lock); | ||
958 | return -EAGAIN; | ||
959 | } | ||
960 | if (wait_event_interruptible(meye.proc_list, | ||
961 | (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { | ||
962 | mutex_unlock(&meye.lock); | ||
963 | return -EINTR; | ||
964 | } | ||
965 | /* fall through */ | ||
966 | case MEYE_BUF_DONE: | ||
967 | meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; | ||
968 | kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); | ||
969 | } | ||
970 | mutex_unlock(&meye.lock); | ||
971 | break; | ||
972 | } | 924 | } |
973 | 925 | ||
974 | case VIDIOCMCAPTURE: { | 926 | if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED) |
975 | struct video_mmap *vm = arg; | 927 | return -EBUSY; |
976 | int restart = 0; | ||
977 | |||
978 | if (vm->frame >= gbuffers || vm->frame < 0) | ||
979 | return -EINVAL; | ||
980 | if (vm->format != VIDEO_PALETTE_YUV422 && vm->format != VIDEO_PALETTE_YUYV) | ||
981 | return -EINVAL; | ||
982 | if (vm->height * vm->width * 2 > gbufsize) | ||
983 | return -EINVAL; | ||
984 | if (!meye.grab_fbuffer) | ||
985 | return -EINVAL; | ||
986 | if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED) | ||
987 | return -EBUSY; | ||
988 | |||
989 | mutex_lock(&meye.lock); | ||
990 | if (vm->width == 640 && vm->height == 480) { | ||
991 | if (meye.params.subsample) { | ||
992 | meye.params.subsample = 0; | ||
993 | restart = 1; | ||
994 | } | ||
995 | } else if (vm->width == 320 && vm->height == 240) { | ||
996 | if (!meye.params.subsample) { | ||
997 | meye.params.subsample = 1; | ||
998 | restart = 1; | ||
999 | } | ||
1000 | } else { | ||
1001 | mutex_unlock(&meye.lock); | ||
1002 | return -EINVAL; | ||
1003 | } | ||
1004 | 928 | ||
1005 | if (restart || meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT) | 929 | mutex_lock(&meye.lock); |
1006 | mchip_continuous_start(); | ||
1007 | meye.grab_buffer[vm->frame].state = MEYE_BUF_USING; | ||
1008 | kfifo_put(meye.grabq, (unsigned char *)&vm->frame, sizeof(int)); | ||
1009 | mutex_unlock(&meye.lock); | ||
1010 | break; | ||
1011 | } | ||
1012 | 930 | ||
1013 | case VIDIOCGMBUF: { | 931 | if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP) |
1014 | struct video_mbuf *vm = arg; | 932 | mchip_cont_compression_start(); |
1015 | int i; | ||
1016 | 933 | ||
1017 | memset(vm, 0 , sizeof(*vm)); | 934 | meye.grab_buffer[*nb].state = MEYE_BUF_USING; |
1018 | vm->size = gbufsize * gbuffers; | 935 | kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int)); |
1019 | vm->frames = gbuffers; | 936 | mutex_unlock(&meye.lock); |
1020 | for (i = 0; i < gbuffers; i++) | ||
1021 | vm->offsets[i] = i * gbufsize; | ||
1022 | break; | ||
1023 | } | ||
1024 | 937 | ||
1025 | case MEYEIOC_G_PARAMS: { | 938 | return 0; |
1026 | struct meye_params *p = arg; | 939 | } |
1027 | *p = meye.params; | ||
1028 | break; | ||
1029 | } | ||
1030 | 940 | ||
1031 | case MEYEIOC_S_PARAMS: { | 941 | static int meyeioc_sync(struct file *file, void *fh, int *i) |
1032 | struct meye_params *jp = arg; | 942 | { |
1033 | if (jp->subsample > 1) | 943 | int unused; |
1034 | return -EINVAL; | ||
1035 | if (jp->quality > 10) | ||
1036 | return -EINVAL; | ||
1037 | if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63) | ||
1038 | return -EINVAL; | ||
1039 | if (jp->framerate > 31) | ||
1040 | return -EINVAL; | ||
1041 | mutex_lock(&meye.lock); | ||
1042 | if (meye.params.subsample != jp->subsample || | ||
1043 | meye.params.quality != jp->quality) | ||
1044 | mchip_hic_stop(); /* need restart */ | ||
1045 | meye.params = *jp; | ||
1046 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERASHARPNESS, | ||
1047 | meye.params.sharpness); | ||
1048 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, | ||
1049 | meye.params.agc); | ||
1050 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, | ||
1051 | meye.params.picture); | ||
1052 | mutex_unlock(&meye.lock); | ||
1053 | break; | ||
1054 | } | ||
1055 | 944 | ||
1056 | case MEYEIOC_QBUF_CAPT: { | 945 | if (*i < 0 || *i >= gbuffers) |
1057 | int *nb = arg; | 946 | return -EINVAL; |
1058 | 947 | ||
1059 | if (!meye.grab_fbuffer) | 948 | mutex_lock(&meye.lock); |
1060 | return -EINVAL; | 949 | switch (meye.grab_buffer[*i].state) { |
1061 | if (*nb >= gbuffers) | 950 | |
1062 | return -EINVAL; | 951 | case MEYE_BUF_UNUSED: |
1063 | if (*nb < 0) { | ||
1064 | /* stop capture */ | ||
1065 | mchip_hic_stop(); | ||
1066 | return 0; | ||
1067 | } | ||
1068 | if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED) | ||
1069 | return -EBUSY; | ||
1070 | mutex_lock(&meye.lock); | ||
1071 | if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP) | ||
1072 | mchip_cont_compression_start(); | ||
1073 | meye.grab_buffer[*nb].state = MEYE_BUF_USING; | ||
1074 | kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int)); | ||
1075 | mutex_unlock(&meye.lock); | 952 | mutex_unlock(&meye.lock); |
1076 | break; | 953 | return -EINVAL; |
954 | case MEYE_BUF_USING: | ||
955 | if (file->f_flags & O_NONBLOCK) { | ||
956 | mutex_unlock(&meye.lock); | ||
957 | return -EAGAIN; | ||
958 | } | ||
959 | if (wait_event_interruptible(meye.proc_list, | ||
960 | (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { | ||
961 | mutex_unlock(&meye.lock); | ||
962 | return -EINTR; | ||
963 | } | ||
964 | /* fall through */ | ||
965 | case MEYE_BUF_DONE: | ||
966 | meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; | ||
967 | kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); | ||
1077 | } | 968 | } |
969 | *i = meye.grab_buffer[*i].size; | ||
970 | mutex_unlock(&meye.lock); | ||
971 | return 0; | ||
972 | } | ||
1078 | 973 | ||
1079 | case MEYEIOC_SYNC: { | 974 | static int meyeioc_stillcapt(void) |
1080 | int *i = arg; | 975 | { |
1081 | int unused; | 976 | if (!meye.grab_fbuffer) |
977 | return -EINVAL; | ||
1082 | 978 | ||
1083 | if (*i < 0 || *i >= gbuffers) | 979 | if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) |
1084 | return -EINVAL; | 980 | return -EBUSY; |
1085 | 981 | ||
1086 | mutex_lock(&meye.lock); | 982 | mutex_lock(&meye.lock); |
1087 | switch (meye.grab_buffer[*i].state) { | 983 | meye.grab_buffer[0].state = MEYE_BUF_USING; |
984 | mchip_take_picture(); | ||
1088 | 985 | ||
1089 | case MEYE_BUF_UNUSED: | 986 | mchip_get_picture(meye.grab_fbuffer, |
1090 | mutex_unlock(&meye.lock); | 987 | mchip_hsize() * mchip_vsize() * 2); |
1091 | return -EINVAL; | ||
1092 | case MEYE_BUF_USING: | ||
1093 | if (file->f_flags & O_NONBLOCK) { | ||
1094 | mutex_unlock(&meye.lock); | ||
1095 | return -EAGAIN; | ||
1096 | } | ||
1097 | if (wait_event_interruptible(meye.proc_list, | ||
1098 | (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { | ||
1099 | mutex_unlock(&meye.lock); | ||
1100 | return -EINTR; | ||
1101 | } | ||
1102 | /* fall through */ | ||
1103 | case MEYE_BUF_DONE: | ||
1104 | meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; | ||
1105 | kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); | ||
1106 | } | ||
1107 | *i = meye.grab_buffer[*i].size; | ||
1108 | mutex_unlock(&meye.lock); | ||
1109 | break; | ||
1110 | } | ||
1111 | 988 | ||
1112 | case MEYEIOC_STILLCAPT: { | 989 | meye.grab_buffer[0].state = MEYE_BUF_DONE; |
990 | mutex_unlock(&meye.lock); | ||
1113 | 991 | ||
1114 | if (!meye.grab_fbuffer) | 992 | return 0; |
1115 | return -EINVAL; | 993 | } |
1116 | if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) | 994 | |
1117 | return -EBUSY; | 995 | static int meyeioc_stilljcapt(int *len) |
1118 | mutex_lock(&meye.lock); | 996 | { |
1119 | meye.grab_buffer[0].state = MEYE_BUF_USING; | 997 | if (!meye.grab_fbuffer) |
998 | return -EINVAL; | ||
999 | |||
1000 | if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) | ||
1001 | return -EBUSY; | ||
1002 | |||
1003 | mutex_lock(&meye.lock); | ||
1004 | meye.grab_buffer[0].state = MEYE_BUF_USING; | ||
1005 | *len = -1; | ||
1006 | |||
1007 | while (*len == -1) { | ||
1120 | mchip_take_picture(); | 1008 | mchip_take_picture(); |
1121 | mchip_get_picture( | 1009 | *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize); |
1122 | meye.grab_fbuffer, | ||
1123 | mchip_hsize() * mchip_vsize() * 2); | ||
1124 | meye.grab_buffer[0].state = MEYE_BUF_DONE; | ||
1125 | mutex_unlock(&meye.lock); | ||
1126 | break; | ||
1127 | } | 1010 | } |
1128 | 1011 | ||
1129 | case MEYEIOC_STILLJCAPT: { | 1012 | meye.grab_buffer[0].state = MEYE_BUF_DONE; |
1130 | int *len = arg; | 1013 | mutex_unlock(&meye.lock); |
1131 | 1014 | return 0; | |
1132 | if (!meye.grab_fbuffer) | 1015 | } |
1133 | return -EINVAL; | ||
1134 | if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) | ||
1135 | return -EBUSY; | ||
1136 | mutex_lock(&meye.lock); | ||
1137 | meye.grab_buffer[0].state = MEYE_BUF_USING; | ||
1138 | *len = -1; | ||
1139 | while (*len == -1) { | ||
1140 | mchip_take_picture(); | ||
1141 | *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize); | ||
1142 | } | ||
1143 | meye.grab_buffer[0].state = MEYE_BUF_DONE; | ||
1144 | mutex_unlock(&meye.lock); | ||
1145 | break; | ||
1146 | } | ||
1147 | 1016 | ||
1148 | case VIDIOC_QUERYCAP: { | 1017 | static int vidioc_querycap(struct file *file, void *fh, |
1149 | struct v4l2_capability *cap = arg; | 1018 | struct v4l2_capability *cap) |
1019 | { | ||
1020 | memset(cap, 0, sizeof(*cap)); | ||
1021 | strcpy(cap->driver, "meye"); | ||
1022 | strcpy(cap->card, "meye"); | ||
1023 | sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev)); | ||
1150 | 1024 | ||
1151 | if (forcev4l1) | 1025 | cap->version = (MEYE_DRIVER_MAJORVERSION << 8) + |
1152 | return -EINVAL; | 1026 | MEYE_DRIVER_MINORVERSION; |
1153 | 1027 | ||
1154 | memset(cap, 0, sizeof(*cap)); | 1028 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | |
1155 | strcpy(cap->driver, "meye"); | 1029 | V4L2_CAP_STREAMING; |
1156 | strcpy(cap->card, "meye"); | 1030 | |
1157 | sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev)); | 1031 | return 0; |
1158 | cap->version = (MEYE_DRIVER_MAJORVERSION << 8) + | 1032 | } |
1159 | MEYE_DRIVER_MINORVERSION; | 1033 | |
1160 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | | 1034 | static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) |
1161 | V4L2_CAP_STREAMING; | 1035 | { |
1162 | break; | 1036 | if (i->index != 0) |
1163 | } | 1037 | return -EINVAL; |
1164 | 1038 | ||
1165 | case VIDIOC_ENUMINPUT: { | 1039 | memset(i, 0, sizeof(*i)); |
1166 | struct v4l2_input *i = arg; | 1040 | i->index = 0; |
1041 | strcpy(i->name, "Camera"); | ||
1042 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
1167 | 1043 | ||
1168 | if (i->index != 0) | 1044 | return 0; |
1169 | return -EINVAL; | 1045 | } |
1170 | memset(i, 0, sizeof(*i)); | 1046 | |
1171 | i->index = 0; | 1047 | static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) |
1172 | strcpy(i->name, "Camera"); | 1048 | { |
1173 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1049 | *i = 0; |
1050 | return 0; | ||
1051 | } | ||
1052 | |||
1053 | static int vidioc_s_input(struct file *file, void *fh, unsigned int i) | ||
1054 | { | ||
1055 | if (i != 0) | ||
1056 | return -EINVAL; | ||
1057 | |||
1058 | return 0; | ||
1059 | } | ||
1060 | |||
1061 | static int vidioc_queryctrl(struct file *file, void *fh, | ||
1062 | struct v4l2_queryctrl *c) | ||
1063 | { | ||
1064 | switch (c->id) { | ||
1065 | |||
1066 | case V4L2_CID_BRIGHTNESS: | ||
1067 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1068 | strcpy(c->name, "Brightness"); | ||
1069 | c->minimum = 0; | ||
1070 | c->maximum = 63; | ||
1071 | c->step = 1; | ||
1072 | c->default_value = 32; | ||
1073 | c->flags = 0; | ||
1074 | break; | ||
1075 | case V4L2_CID_HUE: | ||
1076 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1077 | strcpy(c->name, "Hue"); | ||
1078 | c->minimum = 0; | ||
1079 | c->maximum = 63; | ||
1080 | c->step = 1; | ||
1081 | c->default_value = 32; | ||
1082 | c->flags = 0; | ||
1083 | break; | ||
1084 | case V4L2_CID_CONTRAST: | ||
1085 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1086 | strcpy(c->name, "Contrast"); | ||
1087 | c->minimum = 0; | ||
1088 | c->maximum = 63; | ||
1089 | c->step = 1; | ||
1090 | c->default_value = 32; | ||
1091 | c->flags = 0; | ||
1092 | break; | ||
1093 | case V4L2_CID_SATURATION: | ||
1094 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1095 | strcpy(c->name, "Saturation"); | ||
1096 | c->minimum = 0; | ||
1097 | c->maximum = 63; | ||
1098 | c->step = 1; | ||
1099 | c->default_value = 32; | ||
1100 | c->flags = 0; | ||
1101 | break; | ||
1102 | case V4L2_CID_AGC: | ||
1103 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1104 | strcpy(c->name, "Agc"); | ||
1105 | c->minimum = 0; | ||
1106 | c->maximum = 63; | ||
1107 | c->step = 1; | ||
1108 | c->default_value = 48; | ||
1109 | c->flags = 0; | ||
1174 | break; | 1110 | break; |
1111 | case V4L2_CID_MEYE_SHARPNESS: | ||
1112 | case V4L2_CID_SHARPNESS: | ||
1113 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1114 | strcpy(c->name, "Sharpness"); | ||
1115 | c->minimum = 0; | ||
1116 | c->maximum = 63; | ||
1117 | c->step = 1; | ||
1118 | c->default_value = 32; | ||
1119 | |||
1120 | /* Continue to report legacy private SHARPNESS ctrl but | ||
1121 | * say it is disabled in preference to ctrl in the spec | ||
1122 | */ | ||
1123 | c->flags = (c->id == V4L2_CID_SHARPNESS) ? 0 : | ||
1124 | V4L2_CTRL_FLAG_DISABLED; | ||
1125 | break; | ||
1126 | case V4L2_CID_PICTURE: | ||
1127 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1128 | strcpy(c->name, "Picture"); | ||
1129 | c->minimum = 0; | ||
1130 | c->maximum = 63; | ||
1131 | c->step = 1; | ||
1132 | c->default_value = 0; | ||
1133 | c->flags = 0; | ||
1134 | break; | ||
1135 | case V4L2_CID_JPEGQUAL: | ||
1136 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1137 | strcpy(c->name, "JPEG quality"); | ||
1138 | c->minimum = 0; | ||
1139 | c->maximum = 10; | ||
1140 | c->step = 1; | ||
1141 | c->default_value = 8; | ||
1142 | c->flags = 0; | ||
1143 | break; | ||
1144 | case V4L2_CID_FRAMERATE: | ||
1145 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1146 | strcpy(c->name, "Framerate"); | ||
1147 | c->minimum = 0; | ||
1148 | c->maximum = 31; | ||
1149 | c->step = 1; | ||
1150 | c->default_value = 0; | ||
1151 | c->flags = 0; | ||
1152 | break; | ||
1153 | default: | ||
1154 | return -EINVAL; | ||
1175 | } | 1155 | } |
1176 | 1156 | ||
1177 | case VIDIOC_G_INPUT: { | 1157 | return 0; |
1178 | int *i = arg; | 1158 | } |
1179 | 1159 | ||
1180 | *i = 0; | 1160 | static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) |
1161 | { | ||
1162 | mutex_lock(&meye.lock); | ||
1163 | switch (c->id) { | ||
1164 | case V4L2_CID_BRIGHTNESS: | ||
1165 | sony_pic_camera_command( | ||
1166 | SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, c->value); | ||
1167 | meye.picture.brightness = c->value << 10; | ||
1168 | break; | ||
1169 | case V4L2_CID_HUE: | ||
1170 | sony_pic_camera_command( | ||
1171 | SONY_PIC_COMMAND_SETCAMERAHUE, c->value); | ||
1172 | meye.picture.hue = c->value << 10; | ||
1173 | break; | ||
1174 | case V4L2_CID_CONTRAST: | ||
1175 | sony_pic_camera_command( | ||
1176 | SONY_PIC_COMMAND_SETCAMERACONTRAST, c->value); | ||
1177 | meye.picture.contrast = c->value << 10; | ||
1178 | break; | ||
1179 | case V4L2_CID_SATURATION: | ||
1180 | sony_pic_camera_command( | ||
1181 | SONY_PIC_COMMAND_SETCAMERACOLOR, c->value); | ||
1182 | meye.picture.colour = c->value << 10; | ||
1183 | break; | ||
1184 | case V4L2_CID_AGC: | ||
1185 | sony_pic_camera_command( | ||
1186 | SONY_PIC_COMMAND_SETCAMERAAGC, c->value); | ||
1187 | meye.params.agc = c->value; | ||
1188 | break; | ||
1189 | case V4L2_CID_SHARPNESS: | ||
1190 | case V4L2_CID_MEYE_SHARPNESS: | ||
1191 | sony_pic_camera_command( | ||
1192 | SONY_PIC_COMMAND_SETCAMERASHARPNESS, c->value); | ||
1193 | meye.params.sharpness = c->value; | ||
1194 | break; | ||
1195 | case V4L2_CID_PICTURE: | ||
1196 | sony_pic_camera_command( | ||
1197 | SONY_PIC_COMMAND_SETCAMERAPICTURE, c->value); | ||
1198 | meye.params.picture = c->value; | ||
1199 | break; | ||
1200 | case V4L2_CID_JPEGQUAL: | ||
1201 | meye.params.quality = c->value; | ||
1202 | break; | ||
1203 | case V4L2_CID_FRAMERATE: | ||
1204 | meye.params.framerate = c->value; | ||
1181 | break; | 1205 | break; |
1206 | default: | ||
1207 | mutex_unlock(&meye.lock); | ||
1208 | return -EINVAL; | ||
1182 | } | 1209 | } |
1210 | mutex_unlock(&meye.lock); | ||
1183 | 1211 | ||
1184 | case VIDIOC_S_INPUT: { | 1212 | return 0; |
1185 | int *i = arg; | 1213 | } |
1186 | 1214 | ||
1187 | if (*i != 0) | 1215 | static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) |
1188 | return -EINVAL; | 1216 | { |
1217 | mutex_lock(&meye.lock); | ||
1218 | switch (c->id) { | ||
1219 | case V4L2_CID_BRIGHTNESS: | ||
1220 | c->value = meye.picture.brightness >> 10; | ||
1221 | break; | ||
1222 | case V4L2_CID_HUE: | ||
1223 | c->value = meye.picture.hue >> 10; | ||
1224 | break; | ||
1225 | case V4L2_CID_CONTRAST: | ||
1226 | c->value = meye.picture.contrast >> 10; | ||
1227 | break; | ||
1228 | case V4L2_CID_SATURATION: | ||
1229 | c->value = meye.picture.colour >> 10; | ||
1230 | break; | ||
1231 | case V4L2_CID_AGC: | ||
1232 | c->value = meye.params.agc; | ||
1233 | break; | ||
1234 | case V4L2_CID_SHARPNESS: | ||
1235 | case V4L2_CID_MEYE_SHARPNESS: | ||
1236 | c->value = meye.params.sharpness; | ||
1189 | break; | 1237 | break; |
1238 | case V4L2_CID_PICTURE: | ||
1239 | c->value = meye.params.picture; | ||
1240 | break; | ||
1241 | case V4L2_CID_JPEGQUAL: | ||
1242 | c->value = meye.params.quality; | ||
1243 | break; | ||
1244 | case V4L2_CID_FRAMERATE: | ||
1245 | c->value = meye.params.framerate; | ||
1246 | break; | ||
1247 | default: | ||
1248 | mutex_unlock(&meye.lock); | ||
1249 | return -EINVAL; | ||
1190 | } | 1250 | } |
1251 | mutex_unlock(&meye.lock); | ||
1191 | 1252 | ||
1192 | case VIDIOC_QUERYCTRL: { | 1253 | return 0; |
1193 | struct v4l2_queryctrl *c = arg; | 1254 | } |
1194 | 1255 | ||
1195 | switch (c->id) { | 1256 | static int vidioc_enum_fmt_cap(struct file *file, void *fh, |
1257 | struct v4l2_fmtdesc *f) | ||
1258 | { | ||
1259 | if (f->index > 1) | ||
1260 | return -EINVAL; | ||
1196 | 1261 | ||
1197 | case V4L2_CID_BRIGHTNESS: | 1262 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1198 | c->type = V4L2_CTRL_TYPE_INTEGER; | 1263 | return -EINVAL; |
1199 | strcpy(c->name, "Brightness"); | 1264 | |
1200 | c->minimum = 0; | 1265 | if (f->index == 0) { |
1201 | c->maximum = 63; | 1266 | /* standard YUV 422 capture */ |
1202 | c->step = 1; | 1267 | memset(f, 0, sizeof(*f)); |
1203 | c->default_value = 32; | 1268 | f->index = 0; |
1204 | c->flags = 0; | 1269 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1205 | break; | 1270 | f->flags = 0; |
1206 | case V4L2_CID_HUE: | 1271 | strcpy(f->description, "YUV422"); |
1207 | c->type = V4L2_CTRL_TYPE_INTEGER; | 1272 | f->pixelformat = V4L2_PIX_FMT_YUYV; |
1208 | strcpy(c->name, "Hue"); | 1273 | } else { |
1209 | c->minimum = 0; | 1274 | /* compressed MJPEG capture */ |
1210 | c->maximum = 63; | 1275 | memset(f, 0, sizeof(*f)); |
1211 | c->step = 1; | 1276 | f->index = 1; |
1212 | c->default_value = 32; | 1277 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1213 | c->flags = 0; | 1278 | f->flags = V4L2_FMT_FLAG_COMPRESSED; |
1214 | break; | 1279 | strcpy(f->description, "MJPEG"); |
1215 | case V4L2_CID_CONTRAST: | 1280 | f->pixelformat = V4L2_PIX_FMT_MJPEG; |
1216 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1217 | strcpy(c->name, "Contrast"); | ||
1218 | c->minimum = 0; | ||
1219 | c->maximum = 63; | ||
1220 | c->step = 1; | ||
1221 | c->default_value = 32; | ||
1222 | c->flags = 0; | ||
1223 | break; | ||
1224 | case V4L2_CID_SATURATION: | ||
1225 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1226 | strcpy(c->name, "Saturation"); | ||
1227 | c->minimum = 0; | ||
1228 | c->maximum = 63; | ||
1229 | c->step = 1; | ||
1230 | c->default_value = 32; | ||
1231 | c->flags = 0; | ||
1232 | break; | ||
1233 | case V4L2_CID_AGC: | ||
1234 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1235 | strcpy(c->name, "Agc"); | ||
1236 | c->minimum = 0; | ||
1237 | c->maximum = 63; | ||
1238 | c->step = 1; | ||
1239 | c->default_value = 48; | ||
1240 | c->flags = 0; | ||
1241 | break; | ||
1242 | case V4L2_CID_SHARPNESS: | ||
1243 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1244 | strcpy(c->name, "Sharpness"); | ||
1245 | c->minimum = 0; | ||
1246 | c->maximum = 63; | ||
1247 | c->step = 1; | ||
1248 | c->default_value = 32; | ||
1249 | c->flags = 0; | ||
1250 | break; | ||
1251 | case V4L2_CID_PICTURE: | ||
1252 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1253 | strcpy(c->name, "Picture"); | ||
1254 | c->minimum = 0; | ||
1255 | c->maximum = 63; | ||
1256 | c->step = 1; | ||
1257 | c->default_value = 0; | ||
1258 | c->flags = 0; | ||
1259 | break; | ||
1260 | case V4L2_CID_JPEGQUAL: | ||
1261 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1262 | strcpy(c->name, "JPEG quality"); | ||
1263 | c->minimum = 0; | ||
1264 | c->maximum = 10; | ||
1265 | c->step = 1; | ||
1266 | c->default_value = 8; | ||
1267 | c->flags = 0; | ||
1268 | break; | ||
1269 | case V4L2_CID_FRAMERATE: | ||
1270 | c->type = V4L2_CTRL_TYPE_INTEGER; | ||
1271 | strcpy(c->name, "Framerate"); | ||
1272 | c->minimum = 0; | ||
1273 | c->maximum = 31; | ||
1274 | c->step = 1; | ||
1275 | c->default_value = 0; | ||
1276 | c->flags = 0; | ||
1277 | break; | ||
1278 | default: | ||
1279 | return -EINVAL; | ||
1280 | } | ||
1281 | break; | ||
1282 | } | 1281 | } |
1283 | 1282 | ||
1284 | case VIDIOC_S_CTRL: { | 1283 | return 0; |
1285 | struct v4l2_control *c = arg; | 1284 | } |
1286 | 1285 | ||
1287 | mutex_lock(&meye.lock); | 1286 | static int vidioc_try_fmt_cap(struct file *file, void *fh, |
1288 | switch (c->id) { | 1287 | struct v4l2_format *f) |
1289 | case V4L2_CID_BRIGHTNESS: | 1288 | { |
1290 | sony_pic_camera_command( | 1289 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1291 | SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, c->value); | 1290 | return -EINVAL; |
1292 | meye.picture.brightness = c->value << 10; | 1291 | |
1293 | break; | 1292 | if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV && |
1294 | case V4L2_CID_HUE: | 1293 | f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) |
1295 | sony_pic_camera_command( | 1294 | return -EINVAL; |
1296 | SONY_PIC_COMMAND_SETCAMERAHUE, c->value); | 1295 | |
1297 | meye.picture.hue = c->value << 10; | 1296 | if (f->fmt.pix.field != V4L2_FIELD_ANY && |
1298 | break; | 1297 | f->fmt.pix.field != V4L2_FIELD_NONE) |
1299 | case V4L2_CID_CONTRAST: | 1298 | return -EINVAL; |
1300 | sony_pic_camera_command( | 1299 | |
1301 | SONY_PIC_COMMAND_SETCAMERACONTRAST, c->value); | 1300 | f->fmt.pix.field = V4L2_FIELD_NONE; |
1302 | meye.picture.contrast = c->value << 10; | 1301 | |
1303 | break; | 1302 | if (f->fmt.pix.width <= 320) { |
1304 | case V4L2_CID_SATURATION: | 1303 | f->fmt.pix.width = 320; |
1305 | sony_pic_camera_command( | 1304 | f->fmt.pix.height = 240; |
1306 | SONY_PIC_COMMAND_SETCAMERACOLOR, c->value); | 1305 | } else { |
1307 | meye.picture.colour = c->value << 10; | 1306 | f->fmt.pix.width = 640; |
1308 | break; | 1307 | f->fmt.pix.height = 480; |
1309 | case V4L2_CID_AGC: | ||
1310 | sony_pic_camera_command( | ||
1311 | SONY_PIC_COMMAND_SETCAMERAAGC, c->value); | ||
1312 | meye.params.agc = c->value; | ||
1313 | break; | ||
1314 | case V4L2_CID_SHARPNESS: | ||
1315 | sony_pic_camera_command( | ||
1316 | SONY_PIC_COMMAND_SETCAMERASHARPNESS, c->value); | ||
1317 | meye.params.sharpness = c->value; | ||
1318 | break; | ||
1319 | case V4L2_CID_PICTURE: | ||
1320 | sony_pic_camera_command( | ||
1321 | SONY_PIC_COMMAND_SETCAMERAPICTURE, c->value); | ||
1322 | meye.params.picture = c->value; | ||
1323 | break; | ||
1324 | case V4L2_CID_JPEGQUAL: | ||
1325 | meye.params.quality = c->value; | ||
1326 | break; | ||
1327 | case V4L2_CID_FRAMERATE: | ||
1328 | meye.params.framerate = c->value; | ||
1329 | break; | ||
1330 | default: | ||
1331 | mutex_unlock(&meye.lock); | ||
1332 | return -EINVAL; | ||
1333 | } | ||
1334 | mutex_unlock(&meye.lock); | ||
1335 | break; | ||
1336 | } | 1308 | } |
1337 | 1309 | ||
1338 | case VIDIOC_G_CTRL: { | 1310 | f->fmt.pix.bytesperline = f->fmt.pix.width * 2; |
1339 | struct v4l2_control *c = arg; | 1311 | f->fmt.pix.sizeimage = f->fmt.pix.height * |
1312 | f->fmt.pix.bytesperline; | ||
1313 | f->fmt.pix.colorspace = 0; | ||
1314 | f->fmt.pix.priv = 0; | ||
1340 | 1315 | ||
1341 | mutex_lock(&meye.lock); | 1316 | return 0; |
1342 | switch (c->id) { | 1317 | } |
1343 | case V4L2_CID_BRIGHTNESS: | 1318 | |
1344 | c->value = meye.picture.brightness >> 10; | 1319 | static int vidioc_g_fmt_cap(struct file *file, void *fh, struct v4l2_format *f) |
1345 | break; | 1320 | { |
1346 | case V4L2_CID_HUE: | 1321 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1347 | c->value = meye.picture.hue >> 10; | 1322 | return -EINVAL; |
1348 | break; | 1323 | |
1349 | case V4L2_CID_CONTRAST: | 1324 | memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); |
1350 | c->value = meye.picture.contrast >> 10; | 1325 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1351 | break; | 1326 | |
1352 | case V4L2_CID_SATURATION: | 1327 | switch (meye.mchip_mode) { |
1353 | c->value = meye.picture.colour >> 10; | 1328 | case MCHIP_HIC_MODE_CONT_OUT: |
1354 | break; | 1329 | default: |
1355 | case V4L2_CID_AGC: | 1330 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; |
1356 | c->value = meye.params.agc; | 1331 | break; |
1357 | break; | 1332 | case MCHIP_HIC_MODE_CONT_COMP: |
1358 | case V4L2_CID_SHARPNESS: | 1333 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; |
1359 | c->value = meye.params.sharpness; | ||
1360 | break; | ||
1361 | case V4L2_CID_PICTURE: | ||
1362 | c->value = meye.params.picture; | ||
1363 | break; | ||
1364 | case V4L2_CID_JPEGQUAL: | ||
1365 | c->value = meye.params.quality; | ||
1366 | break; | ||
1367 | case V4L2_CID_FRAMERATE: | ||
1368 | c->value = meye.params.framerate; | ||
1369 | break; | ||
1370 | default: | ||
1371 | mutex_unlock(&meye.lock); | ||
1372 | return -EINVAL; | ||
1373 | } | ||
1374 | mutex_unlock(&meye.lock); | ||
1375 | break; | 1334 | break; |
1376 | } | 1335 | } |
1377 | 1336 | ||
1378 | case VIDIOC_ENUM_FMT: { | 1337 | f->fmt.pix.field = V4L2_FIELD_NONE; |
1379 | struct v4l2_fmtdesc *f = arg; | 1338 | f->fmt.pix.width = mchip_hsize(); |
1380 | 1339 | f->fmt.pix.height = mchip_vsize(); | |
1381 | if (f->index > 1) | 1340 | f->fmt.pix.bytesperline = f->fmt.pix.width * 2; |
1382 | return -EINVAL; | 1341 | f->fmt.pix.sizeimage = f->fmt.pix.height * |
1383 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1342 | f->fmt.pix.bytesperline; |
1384 | return -EINVAL; | 1343 | f->fmt.pix.colorspace = 0; |
1385 | if (f->index == 0) { | 1344 | f->fmt.pix.priv = 0; |
1386 | /* standard YUV 422 capture */ | 1345 | |
1387 | memset(f, 0, sizeof(*f)); | 1346 | return 0; |
1388 | f->index = 0; | 1347 | } |
1389 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1348 | |
1390 | f->flags = 0; | 1349 | static int vidioc_s_fmt_cap(struct file *file, void *fh, struct v4l2_format *f) |
1391 | strcpy(f->description, "YUV422"); | 1350 | { |
1392 | f->pixelformat = V4L2_PIX_FMT_YUYV; | 1351 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1393 | } else { | 1352 | return -EINVAL; |
1394 | /* compressed MJPEG capture */ | 1353 | |
1395 | memset(f, 0, sizeof(*f)); | 1354 | if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV && |
1396 | f->index = 1; | 1355 | f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) |
1397 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1356 | return -EINVAL; |
1398 | f->flags = V4L2_FMT_FLAG_COMPRESSED; | 1357 | |
1399 | strcpy(f->description, "MJPEG"); | 1358 | if (f->fmt.pix.field != V4L2_FIELD_ANY && |
1400 | f->pixelformat = V4L2_PIX_FMT_MJPEG; | 1359 | f->fmt.pix.field != V4L2_FIELD_NONE) |
1401 | } | 1360 | return -EINVAL; |
1402 | break; | 1361 | |
1362 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
1363 | mutex_lock(&meye.lock); | ||
1364 | |||
1365 | if (f->fmt.pix.width <= 320) { | ||
1366 | f->fmt.pix.width = 320; | ||
1367 | f->fmt.pix.height = 240; | ||
1368 | meye.params.subsample = 1; | ||
1369 | } else { | ||
1370 | f->fmt.pix.width = 640; | ||
1371 | f->fmt.pix.height = 480; | ||
1372 | meye.params.subsample = 0; | ||
1403 | } | 1373 | } |
1404 | 1374 | ||
1405 | case VIDIOC_TRY_FMT: { | 1375 | switch (f->fmt.pix.pixelformat) { |
1406 | struct v4l2_format *f = arg; | 1376 | case V4L2_PIX_FMT_YUYV: |
1407 | 1377 | meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT; | |
1408 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1378 | break; |
1409 | return -EINVAL; | 1379 | case V4L2_PIX_FMT_MJPEG: |
1410 | if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV && | 1380 | meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP; |
1411 | f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) | ||
1412 | return -EINVAL; | ||
1413 | if (f->fmt.pix.field != V4L2_FIELD_ANY && | ||
1414 | f->fmt.pix.field != V4L2_FIELD_NONE) | ||
1415 | return -EINVAL; | ||
1416 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
1417 | if (f->fmt.pix.width <= 320) { | ||
1418 | f->fmt.pix.width = 320; | ||
1419 | f->fmt.pix.height = 240; | ||
1420 | } else { | ||
1421 | f->fmt.pix.width = 640; | ||
1422 | f->fmt.pix.height = 480; | ||
1423 | } | ||
1424 | f->fmt.pix.bytesperline = f->fmt.pix.width * 2; | ||
1425 | f->fmt.pix.sizeimage = f->fmt.pix.height * | ||
1426 | f->fmt.pix.bytesperline; | ||
1427 | f->fmt.pix.colorspace = 0; | ||
1428 | f->fmt.pix.priv = 0; | ||
1429 | break; | 1381 | break; |
1430 | } | 1382 | } |
1431 | 1383 | ||
1432 | case VIDIOC_G_FMT: { | 1384 | mutex_unlock(&meye.lock); |
1433 | struct v4l2_format *f = arg; | 1385 | f->fmt.pix.bytesperline = f->fmt.pix.width * 2; |
1386 | f->fmt.pix.sizeimage = f->fmt.pix.height * | ||
1387 | f->fmt.pix.bytesperline; | ||
1388 | f->fmt.pix.colorspace = 0; | ||
1389 | f->fmt.pix.priv = 0; | ||
1434 | 1390 | ||
1435 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1391 | return 0; |
1436 | return -EINVAL; | 1392 | } |
1437 | memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); | ||
1438 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1439 | switch (meye.mchip_mode) { | ||
1440 | case MCHIP_HIC_MODE_CONT_OUT: | ||
1441 | default: | ||
1442 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | ||
1443 | break; | ||
1444 | case MCHIP_HIC_MODE_CONT_COMP: | ||
1445 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; | ||
1446 | break; | ||
1447 | } | ||
1448 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
1449 | f->fmt.pix.width = mchip_hsize(); | ||
1450 | f->fmt.pix.height = mchip_vsize(); | ||
1451 | f->fmt.pix.bytesperline = f->fmt.pix.width * 2; | ||
1452 | f->fmt.pix.sizeimage = f->fmt.pix.height * | ||
1453 | f->fmt.pix.bytesperline; | ||
1454 | f->fmt.pix.colorspace = 0; | ||
1455 | f->fmt.pix.priv = 0; | ||
1456 | break; | ||
1457 | } | ||
1458 | 1393 | ||
1459 | case VIDIOC_S_FMT: { | 1394 | static int vidioc_reqbufs(struct file *file, void *fh, |
1460 | struct v4l2_format *f = arg; | 1395 | struct v4l2_requestbuffers *req) |
1461 | 1396 | { | |
1462 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1397 | int i; |
1463 | return -EINVAL; | ||
1464 | if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV && | ||
1465 | f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) | ||
1466 | return -EINVAL; | ||
1467 | if (f->fmt.pix.field != V4L2_FIELD_ANY && | ||
1468 | f->fmt.pix.field != V4L2_FIELD_NONE) | ||
1469 | return -EINVAL; | ||
1470 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
1471 | mutex_lock(&meye.lock); | ||
1472 | if (f->fmt.pix.width <= 320) { | ||
1473 | f->fmt.pix.width = 320; | ||
1474 | f->fmt.pix.height = 240; | ||
1475 | meye.params.subsample = 1; | ||
1476 | } else { | ||
1477 | f->fmt.pix.width = 640; | ||
1478 | f->fmt.pix.height = 480; | ||
1479 | meye.params.subsample = 0; | ||
1480 | } | ||
1481 | switch (f->fmt.pix.pixelformat) { | ||
1482 | case V4L2_PIX_FMT_YUYV: | ||
1483 | meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT; | ||
1484 | break; | ||
1485 | case V4L2_PIX_FMT_MJPEG: | ||
1486 | meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP; | ||
1487 | break; | ||
1488 | } | ||
1489 | mutex_unlock(&meye.lock); | ||
1490 | f->fmt.pix.bytesperline = f->fmt.pix.width * 2; | ||
1491 | f->fmt.pix.sizeimage = f->fmt.pix.height * | ||
1492 | f->fmt.pix.bytesperline; | ||
1493 | f->fmt.pix.colorspace = 0; | ||
1494 | f->fmt.pix.priv = 0; | ||
1495 | 1398 | ||
1496 | break; | 1399 | if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1497 | } | 1400 | return -EINVAL; |
1498 | 1401 | ||
1499 | case VIDIOC_REQBUFS: { | 1402 | if (req->memory != V4L2_MEMORY_MMAP) |
1500 | struct v4l2_requestbuffers *req = arg; | 1403 | return -EINVAL; |
1501 | int i; | ||
1502 | 1404 | ||
1503 | if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1405 | if (meye.grab_fbuffer && req->count == gbuffers) { |
1504 | return -EINVAL; | 1406 | /* already allocated, no modifications */ |
1505 | if (req->memory != V4L2_MEMORY_MMAP) | 1407 | return 0; |
1506 | return -EINVAL; | ||
1507 | if (meye.grab_fbuffer && req->count == gbuffers) { | ||
1508 | /* already allocated, no modifications */ | ||
1509 | break; | ||
1510 | } | ||
1511 | mutex_lock(&meye.lock); | ||
1512 | if (meye.grab_fbuffer) { | ||
1513 | for (i = 0; i < gbuffers; i++) | ||
1514 | if (meye.vma_use_count[i]) { | ||
1515 | mutex_unlock(&meye.lock); | ||
1516 | return -EINVAL; | ||
1517 | } | ||
1518 | rvfree(meye.grab_fbuffer, gbuffers * gbufsize); | ||
1519 | meye.grab_fbuffer = NULL; | ||
1520 | } | ||
1521 | gbuffers = max(2, min((int)req->count, MEYE_MAX_BUFNBRS)); | ||
1522 | req->count = gbuffers; | ||
1523 | meye.grab_fbuffer = rvmalloc(gbuffers * gbufsize); | ||
1524 | if (!meye.grab_fbuffer) { | ||
1525 | printk(KERN_ERR "meye: v4l framebuffer allocation" | ||
1526 | " failed\n"); | ||
1527 | mutex_unlock(&meye.lock); | ||
1528 | return -ENOMEM; | ||
1529 | } | ||
1530 | for (i = 0; i < gbuffers; i++) | ||
1531 | meye.vma_use_count[i] = 0; | ||
1532 | mutex_unlock(&meye.lock); | ||
1533 | break; | ||
1534 | } | 1408 | } |
1535 | 1409 | ||
1536 | case VIDIOC_QUERYBUF: { | 1410 | mutex_lock(&meye.lock); |
1537 | struct v4l2_buffer *buf = arg; | 1411 | if (meye.grab_fbuffer) { |
1538 | int index = buf->index; | 1412 | for (i = 0; i < gbuffers; i++) |
1539 | 1413 | if (meye.vma_use_count[i]) { | |
1540 | if (index < 0 || index >= gbuffers) | 1414 | mutex_unlock(&meye.lock); |
1541 | return -EINVAL; | 1415 | return -EINVAL; |
1542 | memset(buf, 0, sizeof(*buf)); | 1416 | } |
1543 | buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1417 | rvfree(meye.grab_fbuffer, gbuffers * gbufsize); |
1544 | buf->index = index; | 1418 | meye.grab_fbuffer = NULL; |
1545 | buf->bytesused = meye.grab_buffer[index].size; | ||
1546 | buf->flags = V4L2_BUF_FLAG_MAPPED; | ||
1547 | if (meye.grab_buffer[index].state == MEYE_BUF_USING) | ||
1548 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
1549 | if (meye.grab_buffer[index].state == MEYE_BUF_DONE) | ||
1550 | buf->flags |= V4L2_BUF_FLAG_DONE; | ||
1551 | buf->field = V4L2_FIELD_NONE; | ||
1552 | buf->timestamp = meye.grab_buffer[index].timestamp; | ||
1553 | buf->sequence = meye.grab_buffer[index].sequence; | ||
1554 | buf->memory = V4L2_MEMORY_MMAP; | ||
1555 | buf->m.offset = index * gbufsize; | ||
1556 | buf->length = gbufsize; | ||
1557 | break; | ||
1558 | } | 1419 | } |
1559 | 1420 | ||
1560 | case VIDIOC_QBUF: { | 1421 | gbuffers = max(2, min((int)req->count, MEYE_MAX_BUFNBRS)); |
1561 | struct v4l2_buffer *buf = arg; | 1422 | req->count = gbuffers; |
1562 | 1423 | meye.grab_fbuffer = rvmalloc(gbuffers * gbufsize); | |
1563 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1424 | |
1564 | return -EINVAL; | 1425 | if (!meye.grab_fbuffer) { |
1565 | if (buf->memory != V4L2_MEMORY_MMAP) | 1426 | printk(KERN_ERR "meye: v4l framebuffer allocation" |
1566 | return -EINVAL; | 1427 | " failed\n"); |
1567 | if (buf->index < 0 || buf->index >= gbuffers) | ||
1568 | return -EINVAL; | ||
1569 | if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED) | ||
1570 | return -EINVAL; | ||
1571 | mutex_lock(&meye.lock); | ||
1572 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
1573 | buf->flags &= ~V4L2_BUF_FLAG_DONE; | ||
1574 | meye.grab_buffer[buf->index].state = MEYE_BUF_USING; | ||
1575 | kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int)); | ||
1576 | mutex_unlock(&meye.lock); | 1428 | mutex_unlock(&meye.lock); |
1577 | break; | 1429 | return -ENOMEM; |
1578 | } | 1430 | } |
1579 | 1431 | ||
1580 | case VIDIOC_DQBUF: { | 1432 | for (i = 0; i < gbuffers; i++) |
1581 | struct v4l2_buffer *buf = arg; | 1433 | meye.vma_use_count[i] = 0; |
1582 | int reqnr; | ||
1583 | 1434 | ||
1584 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1435 | mutex_unlock(&meye.lock); |
1585 | return -EINVAL; | ||
1586 | if (buf->memory != V4L2_MEMORY_MMAP) | ||
1587 | return -EINVAL; | ||
1588 | 1436 | ||
1589 | mutex_lock(&meye.lock); | 1437 | return 0; |
1590 | if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { | 1438 | } |
1591 | mutex_unlock(&meye.lock); | 1439 | |
1592 | return -EAGAIN; | 1440 | static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) |
1593 | } | 1441 | { |
1594 | if (wait_event_interruptible(meye.proc_list, | 1442 | int index = buf->index; |
1595 | kfifo_len(meye.doneq) != 0) < 0) { | 1443 | |
1596 | mutex_unlock(&meye.lock); | 1444 | if (index < 0 || index >= gbuffers) |
1597 | return -EINTR; | 1445 | return -EINVAL; |
1598 | } | 1446 | |
1599 | if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr, | 1447 | memset(buf, 0, sizeof(*buf)); |
1600 | sizeof(int))) { | 1448 | |
1601 | mutex_unlock(&meye.lock); | 1449 | buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1602 | return -EBUSY; | 1450 | buf->index = index; |
1603 | } | 1451 | buf->bytesused = meye.grab_buffer[index].size; |
1604 | if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) { | 1452 | buf->flags = V4L2_BUF_FLAG_MAPPED; |
1605 | mutex_unlock(&meye.lock); | 1453 | |
1606 | return -EINVAL; | 1454 | if (meye.grab_buffer[index].state == MEYE_BUF_USING) |
1607 | } | 1455 | buf->flags |= V4L2_BUF_FLAG_QUEUED; |
1608 | buf->index = reqnr; | 1456 | |
1609 | buf->bytesused = meye.grab_buffer[reqnr].size; | 1457 | if (meye.grab_buffer[index].state == MEYE_BUF_DONE) |
1610 | buf->flags = V4L2_BUF_FLAG_MAPPED; | 1458 | buf->flags |= V4L2_BUF_FLAG_DONE; |
1611 | buf->field = V4L2_FIELD_NONE; | 1459 | |
1612 | buf->timestamp = meye.grab_buffer[reqnr].timestamp; | 1460 | buf->field = V4L2_FIELD_NONE; |
1613 | buf->sequence = meye.grab_buffer[reqnr].sequence; | 1461 | buf->timestamp = meye.grab_buffer[index].timestamp; |
1614 | buf->memory = V4L2_MEMORY_MMAP; | 1462 | buf->sequence = meye.grab_buffer[index].sequence; |
1615 | buf->m.offset = reqnr * gbufsize; | 1463 | buf->memory = V4L2_MEMORY_MMAP; |
1616 | buf->length = gbufsize; | 1464 | buf->m.offset = index * gbufsize; |
1617 | meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED; | 1465 | buf->length = gbufsize; |
1466 | |||
1467 | return 0; | ||
1468 | } | ||
1469 | |||
1470 | static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | ||
1471 | { | ||
1472 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1473 | return -EINVAL; | ||
1474 | |||
1475 | if (buf->memory != V4L2_MEMORY_MMAP) | ||
1476 | return -EINVAL; | ||
1477 | |||
1478 | if (buf->index < 0 || buf->index >= gbuffers) | ||
1479 | return -EINVAL; | ||
1480 | |||
1481 | if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED) | ||
1482 | return -EINVAL; | ||
1483 | |||
1484 | mutex_lock(&meye.lock); | ||
1485 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
1486 | buf->flags &= ~V4L2_BUF_FLAG_DONE; | ||
1487 | meye.grab_buffer[buf->index].state = MEYE_BUF_USING; | ||
1488 | kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int)); | ||
1489 | mutex_unlock(&meye.lock); | ||
1490 | |||
1491 | return 0; | ||
1492 | } | ||
1493 | |||
1494 | static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | ||
1495 | { | ||
1496 | int reqnr; | ||
1497 | |||
1498 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1499 | return -EINVAL; | ||
1500 | |||
1501 | if (buf->memory != V4L2_MEMORY_MMAP) | ||
1502 | return -EINVAL; | ||
1503 | |||
1504 | mutex_lock(&meye.lock); | ||
1505 | |||
1506 | if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { | ||
1618 | mutex_unlock(&meye.lock); | 1507 | mutex_unlock(&meye.lock); |
1619 | break; | 1508 | return -EAGAIN; |
1620 | } | 1509 | } |
1621 | 1510 | ||
1622 | case VIDIOC_STREAMON: { | 1511 | if (wait_event_interruptible(meye.proc_list, |
1623 | mutex_lock(&meye.lock); | 1512 | kfifo_len(meye.doneq) != 0) < 0) { |
1624 | switch (meye.mchip_mode) { | ||
1625 | case MCHIP_HIC_MODE_CONT_OUT: | ||
1626 | mchip_continuous_start(); | ||
1627 | break; | ||
1628 | case MCHIP_HIC_MODE_CONT_COMP: | ||
1629 | mchip_cont_compression_start(); | ||
1630 | break; | ||
1631 | default: | ||
1632 | mutex_unlock(&meye.lock); | ||
1633 | return -EINVAL; | ||
1634 | } | ||
1635 | mutex_unlock(&meye.lock); | 1513 | mutex_unlock(&meye.lock); |
1636 | break; | 1514 | return -EINTR; |
1637 | } | 1515 | } |
1638 | 1516 | ||
1639 | case VIDIOC_STREAMOFF: { | 1517 | if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr, |
1640 | int i; | 1518 | sizeof(int))) { |
1519 | mutex_unlock(&meye.lock); | ||
1520 | return -EBUSY; | ||
1521 | } | ||
1641 | 1522 | ||
1642 | mutex_lock(&meye.lock); | 1523 | if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) { |
1643 | mchip_hic_stop(); | ||
1644 | kfifo_reset(meye.grabq); | ||
1645 | kfifo_reset(meye.doneq); | ||
1646 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) | ||
1647 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; | ||
1648 | mutex_unlock(&meye.lock); | 1524 | mutex_unlock(&meye.lock); |
1649 | break; | 1525 | return -EINVAL; |
1650 | } | 1526 | } |
1651 | 1527 | ||
1652 | /* | 1528 | buf->index = reqnr; |
1653 | * XXX what about private snapshot ioctls ? | 1529 | buf->bytesused = meye.grab_buffer[reqnr].size; |
1654 | * Do they need to be converted to V4L2 ? | 1530 | buf->flags = V4L2_BUF_FLAG_MAPPED; |
1655 | */ | 1531 | buf->field = V4L2_FIELD_NONE; |
1532 | buf->timestamp = meye.grab_buffer[reqnr].timestamp; | ||
1533 | buf->sequence = meye.grab_buffer[reqnr].sequence; | ||
1534 | buf->memory = V4L2_MEMORY_MMAP; | ||
1535 | buf->m.offset = reqnr * gbufsize; | ||
1536 | buf->length = gbufsize; | ||
1537 | meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED; | ||
1538 | mutex_unlock(&meye.lock); | ||
1539 | |||
1540 | return 0; | ||
1541 | } | ||
1656 | 1542 | ||
1543 | static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) | ||
1544 | { | ||
1545 | mutex_lock(&meye.lock); | ||
1546 | |||
1547 | switch (meye.mchip_mode) { | ||
1548 | case MCHIP_HIC_MODE_CONT_OUT: | ||
1549 | mchip_continuous_start(); | ||
1550 | break; | ||
1551 | case MCHIP_HIC_MODE_CONT_COMP: | ||
1552 | mchip_cont_compression_start(); | ||
1553 | break; | ||
1657 | default: | 1554 | default: |
1658 | return -ENOIOCTLCMD; | 1555 | mutex_unlock(&meye.lock); |
1556 | return -EINVAL; | ||
1659 | } | 1557 | } |
1660 | 1558 | ||
1559 | mutex_unlock(&meye.lock); | ||
1560 | |||
1661 | return 0; | 1561 | return 0; |
1662 | } | 1562 | } |
1663 | 1563 | ||
1664 | static int meye_ioctl(struct inode *inode, struct file *file, | 1564 | static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) |
1665 | unsigned int cmd, unsigned long arg) | ||
1666 | { | 1565 | { |
1667 | return video_usercopy(inode, file, cmd, arg, meye_do_ioctl); | 1566 | mutex_lock(&meye.lock); |
1567 | mchip_hic_stop(); | ||
1568 | kfifo_reset(meye.grabq); | ||
1569 | kfifo_reset(meye.doneq); | ||
1570 | |||
1571 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) | ||
1572 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; | ||
1573 | |||
1574 | mutex_unlock(&meye.lock); | ||
1575 | return 0; | ||
1576 | } | ||
1577 | |||
1578 | static int vidioc_default(struct file *file, void *fh, int cmd, void *arg) | ||
1579 | { | ||
1580 | switch (cmd) { | ||
1581 | case MEYEIOC_G_PARAMS: | ||
1582 | return meyeioc_g_params((struct meye_params *) arg); | ||
1583 | |||
1584 | case MEYEIOC_S_PARAMS: | ||
1585 | return meyeioc_s_params((struct meye_params *) arg); | ||
1586 | |||
1587 | case MEYEIOC_QBUF_CAPT: | ||
1588 | return meyeioc_qbuf_capt((int *) arg); | ||
1589 | |||
1590 | case MEYEIOC_SYNC: | ||
1591 | return meyeioc_sync(file, fh, (int *) arg); | ||
1592 | |||
1593 | case MEYEIOC_STILLCAPT: | ||
1594 | return meyeioc_stillcapt(); | ||
1595 | |||
1596 | case MEYEIOC_STILLJCAPT: | ||
1597 | return meyeioc_stilljcapt((int *) arg); | ||
1598 | |||
1599 | default: | ||
1600 | return -EINVAL; | ||
1601 | } | ||
1602 | |||
1668 | } | 1603 | } |
1669 | 1604 | ||
1670 | static unsigned int meye_poll(struct file *file, poll_table *wait) | 1605 | static unsigned int meye_poll(struct file *file, poll_table *wait) |
@@ -1752,8 +1687,10 @@ static const struct file_operations meye_fops = { | |||
1752 | .open = meye_open, | 1687 | .open = meye_open, |
1753 | .release = meye_release, | 1688 | .release = meye_release, |
1754 | .mmap = meye_mmap, | 1689 | .mmap = meye_mmap, |
1755 | .ioctl = meye_ioctl, | 1690 | .ioctl = video_ioctl2, |
1691 | #ifdef CONFIG_COMPAT | ||
1756 | .compat_ioctl = v4l_compat_ioctl32, | 1692 | .compat_ioctl = v4l_compat_ioctl32, |
1693 | #endif | ||
1757 | .poll = meye_poll, | 1694 | .poll = meye_poll, |
1758 | .llseek = no_llseek, | 1695 | .llseek = no_llseek, |
1759 | }; | 1696 | }; |
@@ -1765,6 +1702,24 @@ static struct video_device meye_template = { | |||
1765 | .fops = &meye_fops, | 1702 | .fops = &meye_fops, |
1766 | .release = video_device_release, | 1703 | .release = video_device_release, |
1767 | .minor = -1, | 1704 | .minor = -1, |
1705 | .vidioc_querycap = vidioc_querycap, | ||
1706 | .vidioc_enum_input = vidioc_enum_input, | ||
1707 | .vidioc_g_input = vidioc_g_input, | ||
1708 | .vidioc_s_input = vidioc_s_input, | ||
1709 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1710 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1711 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1712 | .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, | ||
1713 | .vidioc_try_fmt_cap = vidioc_try_fmt_cap, | ||
1714 | .vidioc_g_fmt_cap = vidioc_g_fmt_cap, | ||
1715 | .vidioc_s_fmt_cap = vidioc_s_fmt_cap, | ||
1716 | .vidioc_reqbufs = vidioc_reqbufs, | ||
1717 | .vidioc_querybuf = vidioc_querybuf, | ||
1718 | .vidioc_qbuf = vidioc_qbuf, | ||
1719 | .vidioc_dqbuf = vidioc_dqbuf, | ||
1720 | .vidioc_streamon = vidioc_streamon, | ||
1721 | .vidioc_streamoff = vidioc_streamoff, | ||
1722 | .vidioc_default = vidioc_default, | ||
1768 | }; | 1723 | }; |
1769 | 1724 | ||
1770 | #ifdef CONFIG_PM | 1725 | #ifdef CONFIG_PM |
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 7a11f3159e32..b73c740f7fb2 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -366,7 +366,7 @@ int msp_sleep(struct msp_state *state, int timeout) | |||
366 | } | 366 | } |
367 | 367 | ||
368 | /* ------------------------------------------------------------------------ */ | 368 | /* ------------------------------------------------------------------------ */ |
369 | #ifdef CONFIG_VIDEO_V4L1 | 369 | #ifdef CONFIG_VIDEO_ALLOW_V4L1 |
370 | static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode) | 370 | static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode) |
371 | { | 371 | { |
372 | if (rxsubchans == V4L2_TUNER_SUB_MONO) | 372 | if (rxsubchans == V4L2_TUNER_SUB_MONO) |
@@ -514,7 +514,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
514 | /* --- v4l ioctls --- */ | 514 | /* --- v4l ioctls --- */ |
515 | /* take care: bttv does userspace copying, we'll get a | 515 | /* take care: bttv does userspace copying, we'll get a |
516 | kernel pointer here... */ | 516 | kernel pointer here... */ |
517 | #ifdef CONFIG_VIDEO_V4L1 | 517 | #ifdef CONFIG_VIDEO_ALLOW_V4L1 |
518 | case VIDIOCGAUDIO: | 518 | case VIDIOCGAUDIO: |
519 | { | 519 | { |
520 | struct video_audio *va = arg; | 520 | struct video_audio *va = arg; |
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 61ec794a737e..7f5568592793 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c | |||
@@ -833,11 +833,6 @@ static int msp34xxg_modus(struct i2c_client *client) | |||
833 | v4l_dbg(1, msp_debug, client, "selected radio modus\n"); | 833 | v4l_dbg(1, msp_debug, client, "selected radio modus\n"); |
834 | return 0x0001; | 834 | return 0x0001; |
835 | } | 835 | } |
836 | |||
837 | if (state->v4l2_std & V4L2_STD_PAL) { | ||
838 | v4l_dbg(1, msp_debug, client, "selected PAL modus\n"); | ||
839 | return 0x7001; | ||
840 | } | ||
841 | if (state->v4l2_std == V4L2_STD_NTSC_M_JP) { | 836 | if (state->v4l2_std == V4L2_STD_NTSC_M_JP) { |
842 | v4l_dbg(1, msp_debug, client, "selected M (EIA-J) modus\n"); | 837 | v4l_dbg(1, msp_debug, client, "selected M (EIA-J) modus\n"); |
843 | return 0x4001; | 838 | return 0x4001; |
@@ -846,15 +841,15 @@ static int msp34xxg_modus(struct i2c_client *client) | |||
846 | v4l_dbg(1, msp_debug, client, "selected M (A2) modus\n"); | 841 | v4l_dbg(1, msp_debug, client, "selected M (A2) modus\n"); |
847 | return 0x0001; | 842 | return 0x0001; |
848 | } | 843 | } |
844 | if (state->v4l2_std == V4L2_STD_SECAM_L) { | ||
845 | v4l_dbg(1, msp_debug, client, "selected SECAM-L modus\n"); | ||
846 | return 0x6001; | ||
847 | } | ||
849 | if (state->v4l2_std & V4L2_STD_MN) { | 848 | if (state->v4l2_std & V4L2_STD_MN) { |
850 | v4l_dbg(1, msp_debug, client, "selected M (BTSC) modus\n"); | 849 | v4l_dbg(1, msp_debug, client, "selected M (BTSC) modus\n"); |
851 | return 0x2001; | 850 | return 0x2001; |
852 | } | 851 | } |
853 | if (state->v4l2_std & V4L2_STD_SECAM) { | 852 | return 0x7001; |
854 | v4l_dbg(1, msp_debug, client, "selected SECAM modus\n"); | ||
855 | return 0x6001; | ||
856 | } | ||
857 | return 0x0001; | ||
858 | } | 853 | } |
859 | 854 | ||
860 | static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) | 855 | static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) |
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c index 74fd6a01d4c4..fbcb28233737 100644 --- a/drivers/media/video/mt20xx.c +++ b/drivers/media/video/mt20xx.c | |||
@@ -10,12 +10,10 @@ | |||
10 | #include "tuner-i2c.h" | 10 | #include "tuner-i2c.h" |
11 | #include "mt20xx.h" | 11 | #include "mt20xx.h" |
12 | 12 | ||
13 | static int debug = 0; | 13 | static int debug; |
14 | module_param(debug, int, 0644); | 14 | module_param(debug, int, 0644); |
15 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | 15 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); |
16 | 16 | ||
17 | #define PREFIX "mt20xx" | ||
18 | |||
19 | /* ---------------------------------------------------------------------- */ | 17 | /* ---------------------------------------------------------------------- */ |
20 | 18 | ||
21 | static unsigned int optimize_vco = 1; | 19 | static unsigned int optimize_vco = 1; |
@@ -24,7 +22,7 @@ module_param(optimize_vco, int, 0644); | |||
24 | static unsigned int tv_antenna = 1; | 22 | static unsigned int tv_antenna = 1; |
25 | module_param(tv_antenna, int, 0644); | 23 | module_param(tv_antenna, int, 0644); |
26 | 24 | ||
27 | static unsigned int radio_antenna = 0; | 25 | static unsigned int radio_antenna; |
28 | module_param(radio_antenna, int, 0644); | 26 | module_param(radio_antenna, int, 0644); |
29 | 27 | ||
30 | /* ---------------------------------------------------------------------- */ | 28 | /* ---------------------------------------------------------------------- */ |
@@ -611,6 +609,7 @@ struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, | |||
611 | 609 | ||
612 | priv->i2c_props.addr = i2c_addr; | 610 | priv->i2c_props.addr = i2c_addr; |
613 | priv->i2c_props.adap = i2c_adap; | 611 | priv->i2c_props.adap = i2c_adap; |
612 | priv->i2c_props.name = "mt20xx"; | ||
614 | 613 | ||
615 | //priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ | 614 | //priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ |
616 | 615 | ||
diff --git a/drivers/media/video/mt20xx.h b/drivers/media/video/mt20xx.h index 5e9c825d2e91..aa848e14ce5e 100644 --- a/drivers/media/video/mt20xx.h +++ b/drivers/media/video/mt20xx.h | |||
@@ -29,7 +29,7 @@ static inline struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, | |||
29 | struct i2c_adapter* i2c_adap, | 29 | struct i2c_adapter* i2c_adap, |
30 | u8 i2c_addr) | 30 | u8 i2c_addr) |
31 | { | 31 | { |
32 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | 32 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
33 | return NULL; | 33 | return NULL; |
34 | } | 34 | } |
35 | #endif | 35 | #endif |
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c new file mode 100644 index 000000000000..3fb5f63df1e6 --- /dev/null +++ b/drivers/media/video/mt9m001.c | |||
@@ -0,0 +1,722 @@ | |||
1 | /* | ||
2 | * Driver for MT9M001 CMOS Image Sensor from Micron | ||
3 | * | ||
4 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/videodev2.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/log2.h> | ||
15 | |||
16 | #include <media/v4l2-common.h> | ||
17 | #include <media/v4l2-chip-ident.h> | ||
18 | #include <media/soc_camera.h> | ||
19 | |||
20 | #ifdef CONFIG_MT9M001_PCA9536_SWITCH | ||
21 | #include <asm/gpio.h> | ||
22 | #endif | ||
23 | |||
24 | /* mt9m001 i2c address 0x5d | ||
25 | * The platform has to define i2c_board_info | ||
26 | * and call i2c_register_board_info() */ | ||
27 | |||
28 | /* mt9m001 selected register addresses */ | ||
29 | #define MT9M001_CHIP_VERSION 0x00 | ||
30 | #define MT9M001_ROW_START 0x01 | ||
31 | #define MT9M001_COLUMN_START 0x02 | ||
32 | #define MT9M001_WINDOW_HEIGHT 0x03 | ||
33 | #define MT9M001_WINDOW_WIDTH 0x04 | ||
34 | #define MT9M001_HORIZONTAL_BLANKING 0x05 | ||
35 | #define MT9M001_VERTICAL_BLANKING 0x06 | ||
36 | #define MT9M001_OUTPUT_CONTROL 0x07 | ||
37 | #define MT9M001_SHUTTER_WIDTH 0x09 | ||
38 | #define MT9M001_FRAME_RESTART 0x0b | ||
39 | #define MT9M001_SHUTTER_DELAY 0x0c | ||
40 | #define MT9M001_RESET 0x0d | ||
41 | #define MT9M001_READ_OPTIONS1 0x1e | ||
42 | #define MT9M001_READ_OPTIONS2 0x20 | ||
43 | #define MT9M001_GLOBAL_GAIN 0x35 | ||
44 | #define MT9M001_CHIP_ENABLE 0xF1 | ||
45 | |||
46 | static const struct soc_camera_data_format mt9m001_colour_formats[] = { | ||
47 | /* Order important: first natively supported, | ||
48 | * second supported with a GPIO extender */ | ||
49 | { | ||
50 | .name = "Bayer (sRGB) 10 bit", | ||
51 | .depth = 10, | ||
52 | .fourcc = V4L2_PIX_FMT_SBGGR16, | ||
53 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
54 | }, { | ||
55 | .name = "Bayer (sRGB) 8 bit", | ||
56 | .depth = 8, | ||
57 | .fourcc = V4L2_PIX_FMT_SBGGR8, | ||
58 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
59 | } | ||
60 | }; | ||
61 | |||
62 | static const struct soc_camera_data_format mt9m001_monochrome_formats[] = { | ||
63 | /* Order important - see above */ | ||
64 | { | ||
65 | .name = "Monochrome 10 bit", | ||
66 | .depth = 10, | ||
67 | .fourcc = V4L2_PIX_FMT_Y16, | ||
68 | }, { | ||
69 | .name = "Monochrome 8 bit", | ||
70 | .depth = 8, | ||
71 | .fourcc = V4L2_PIX_FMT_GREY, | ||
72 | }, | ||
73 | }; | ||
74 | |||
75 | struct mt9m001 { | ||
76 | struct i2c_client *client; | ||
77 | struct soc_camera_device icd; | ||
78 | int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ | ||
79 | int switch_gpio; | ||
80 | unsigned char autoexposure; | ||
81 | unsigned char datawidth; | ||
82 | }; | ||
83 | |||
84 | static int reg_read(struct soc_camera_device *icd, const u8 reg) | ||
85 | { | ||
86 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
87 | struct i2c_client *client = mt9m001->client; | ||
88 | s32 data = i2c_smbus_read_word_data(client, reg); | ||
89 | return data < 0 ? data : swab16(data); | ||
90 | } | ||
91 | |||
92 | static int reg_write(struct soc_camera_device *icd, const u8 reg, | ||
93 | const u16 data) | ||
94 | { | ||
95 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
96 | return i2c_smbus_write_word_data(mt9m001->client, reg, swab16(data)); | ||
97 | } | ||
98 | |||
99 | static int reg_set(struct soc_camera_device *icd, const u8 reg, | ||
100 | const u16 data) | ||
101 | { | ||
102 | int ret; | ||
103 | |||
104 | ret = reg_read(icd, reg); | ||
105 | if (ret < 0) | ||
106 | return ret; | ||
107 | return reg_write(icd, reg, ret | data); | ||
108 | } | ||
109 | |||
110 | static int reg_clear(struct soc_camera_device *icd, const u8 reg, | ||
111 | const u16 data) | ||
112 | { | ||
113 | int ret; | ||
114 | |||
115 | ret = reg_read(icd, reg); | ||
116 | if (ret < 0) | ||
117 | return ret; | ||
118 | return reg_write(icd, reg, ret & ~data); | ||
119 | } | ||
120 | |||
121 | static int mt9m001_init(struct soc_camera_device *icd) | ||
122 | { | ||
123 | int ret; | ||
124 | |||
125 | /* Disable chip, synchronous option update */ | ||
126 | dev_dbg(icd->vdev->dev, "%s\n", __func__); | ||
127 | |||
128 | ret = reg_write(icd, MT9M001_RESET, 1); | ||
129 | if (ret >= 0) | ||
130 | ret = reg_write(icd, MT9M001_RESET, 0); | ||
131 | if (ret >= 0) | ||
132 | ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); | ||
133 | |||
134 | return ret >= 0 ? 0 : -EIO; | ||
135 | } | ||
136 | |||
137 | static int mt9m001_release(struct soc_camera_device *icd) | ||
138 | { | ||
139 | /* Disable the chip */ | ||
140 | reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int mt9m001_start_capture(struct soc_camera_device *icd) | ||
145 | { | ||
146 | /* Switch to master "normal" mode */ | ||
147 | if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 2) < 0) | ||
148 | return -EIO; | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static int mt9m001_stop_capture(struct soc_camera_device *icd) | ||
153 | { | ||
154 | /* Stop sensor readout */ | ||
155 | if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 0) < 0) | ||
156 | return -EIO; | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int bus_switch_request(struct mt9m001 *mt9m001, | ||
161 | struct soc_camera_link *icl) | ||
162 | { | ||
163 | #ifdef CONFIG_MT9M001_PCA9536_SWITCH | ||
164 | int ret; | ||
165 | unsigned int gpio = icl->gpio; | ||
166 | |||
167 | if (gpio_is_valid(gpio)) { | ||
168 | /* We have a data bus switch. */ | ||
169 | ret = gpio_request(gpio, "mt9m001"); | ||
170 | if (ret < 0) { | ||
171 | dev_err(&mt9m001->client->dev, "Cannot get GPIO %u\n", | ||
172 | gpio); | ||
173 | return ret; | ||
174 | } | ||
175 | |||
176 | ret = gpio_direction_output(gpio, 0); | ||
177 | if (ret < 0) { | ||
178 | dev_err(&mt9m001->client->dev, | ||
179 | "Cannot set GPIO %u to output\n", gpio); | ||
180 | gpio_free(gpio); | ||
181 | return ret; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | mt9m001->switch_gpio = gpio; | ||
186 | #else | ||
187 | mt9m001->switch_gpio = -EINVAL; | ||
188 | #endif | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static void bus_switch_release(struct mt9m001 *mt9m001) | ||
193 | { | ||
194 | #ifdef CONFIG_MT9M001_PCA9536_SWITCH | ||
195 | if (gpio_is_valid(mt9m001->switch_gpio)) | ||
196 | gpio_free(mt9m001->switch_gpio); | ||
197 | #endif | ||
198 | } | ||
199 | |||
200 | static int bus_switch_act(struct mt9m001 *mt9m001, int go8bit) | ||
201 | { | ||
202 | #ifdef CONFIG_MT9M001_PCA9536_SWITCH | ||
203 | if (!gpio_is_valid(mt9m001->switch_gpio)) | ||
204 | return -ENODEV; | ||
205 | |||
206 | gpio_set_value_cansleep(mt9m001->switch_gpio, go8bit); | ||
207 | return 0; | ||
208 | #else | ||
209 | return -ENODEV; | ||
210 | #endif | ||
211 | } | ||
212 | |||
213 | static int bus_switch_possible(struct mt9m001 *mt9m001) | ||
214 | { | ||
215 | #ifdef CONFIG_MT9M001_PCA9536_SWITCH | ||
216 | return gpio_is_valid(mt9m001->switch_gpio); | ||
217 | #else | ||
218 | return 0; | ||
219 | #endif | ||
220 | } | ||
221 | |||
222 | static int mt9m001_set_bus_param(struct soc_camera_device *icd, | ||
223 | unsigned long flags) | ||
224 | { | ||
225 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
226 | unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; | ||
227 | int ret; | ||
228 | |||
229 | /* Flags validity verified in test_bus_param */ | ||
230 | |||
231 | if ((mt9m001->datawidth != 10 && (width_flag == SOCAM_DATAWIDTH_10)) || | ||
232 | (mt9m001->datawidth != 9 && (width_flag == SOCAM_DATAWIDTH_9)) || | ||
233 | (mt9m001->datawidth != 8 && (width_flag == SOCAM_DATAWIDTH_8))) { | ||
234 | /* Well, we actually only can do 10 or 8 bits... */ | ||
235 | if (width_flag == SOCAM_DATAWIDTH_9) | ||
236 | return -EINVAL; | ||
237 | ret = bus_switch_act(mt9m001, | ||
238 | width_flag == SOCAM_DATAWIDTH_8); | ||
239 | if (ret < 0) | ||
240 | return ret; | ||
241 | |||
242 | mt9m001->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10; | ||
243 | } | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) | ||
249 | { | ||
250 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
251 | unsigned int width_flag = SOCAM_DATAWIDTH_10; | ||
252 | |||
253 | if (bus_switch_possible(mt9m001)) | ||
254 | width_flag |= SOCAM_DATAWIDTH_8; | ||
255 | |||
256 | /* MT9M001 has all capture_format parameters fixed */ | ||
257 | return SOCAM_PCLK_SAMPLE_RISING | | ||
258 | SOCAM_HSYNC_ACTIVE_HIGH | | ||
259 | SOCAM_VSYNC_ACTIVE_HIGH | | ||
260 | SOCAM_MASTER | | ||
261 | width_flag; | ||
262 | } | ||
263 | |||
264 | static int mt9m001_set_fmt_cap(struct soc_camera_device *icd, | ||
265 | __u32 pixfmt, struct v4l2_rect *rect) | ||
266 | { | ||
267 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
268 | int ret; | ||
269 | const u16 hblank = 9, vblank = 25; | ||
270 | |||
271 | /* Blanking and start values - default... */ | ||
272 | ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank); | ||
273 | if (ret >= 0) | ||
274 | ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank); | ||
275 | |||
276 | /* The caller provides a supported format, as verified per | ||
277 | * call to icd->try_fmt_cap() */ | ||
278 | if (ret >= 0) | ||
279 | ret = reg_write(icd, MT9M001_COLUMN_START, rect->left); | ||
280 | if (ret >= 0) | ||
281 | ret = reg_write(icd, MT9M001_ROW_START, rect->top); | ||
282 | if (ret >= 0) | ||
283 | ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1); | ||
284 | if (ret >= 0) | ||
285 | ret = reg_write(icd, MT9M001_WINDOW_HEIGHT, | ||
286 | rect->height + icd->y_skip_top - 1); | ||
287 | if (ret >= 0 && mt9m001->autoexposure) { | ||
288 | ret = reg_write(icd, MT9M001_SHUTTER_WIDTH, | ||
289 | rect->height + icd->y_skip_top + vblank); | ||
290 | if (ret >= 0) { | ||
291 | const struct v4l2_queryctrl *qctrl = | ||
292 | soc_camera_find_qctrl(icd->ops, | ||
293 | V4L2_CID_EXPOSURE); | ||
294 | icd->exposure = (524 + (rect->height + icd->y_skip_top + | ||
295 | vblank - 1) * | ||
296 | (qctrl->maximum - qctrl->minimum)) / | ||
297 | 1048 + qctrl->minimum; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | return ret < 0 ? ret : 0; | ||
302 | } | ||
303 | |||
304 | static int mt9m001_try_fmt_cap(struct soc_camera_device *icd, | ||
305 | struct v4l2_format *f) | ||
306 | { | ||
307 | if (f->fmt.pix.height < 32 + icd->y_skip_top) | ||
308 | f->fmt.pix.height = 32 + icd->y_skip_top; | ||
309 | if (f->fmt.pix.height > 1024 + icd->y_skip_top) | ||
310 | f->fmt.pix.height = 1024 + icd->y_skip_top; | ||
311 | if (f->fmt.pix.width < 48) | ||
312 | f->fmt.pix.width = 48; | ||
313 | if (f->fmt.pix.width > 1280) | ||
314 | f->fmt.pix.width = 1280; | ||
315 | f->fmt.pix.width &= ~0x01; /* has to be even, unsure why was ~3 */ | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int mt9m001_get_chip_id(struct soc_camera_device *icd, | ||
321 | struct v4l2_chip_ident *id) | ||
322 | { | ||
323 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
324 | |||
325 | if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) | ||
326 | return -EINVAL; | ||
327 | |||
328 | if (id->match_chip != mt9m001->client->addr) | ||
329 | return -ENODEV; | ||
330 | |||
331 | id->ident = mt9m001->model; | ||
332 | id->revision = 0; | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
338 | static int mt9m001_get_register(struct soc_camera_device *icd, | ||
339 | struct v4l2_register *reg) | ||
340 | { | ||
341 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
342 | |||
343 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | ||
344 | return -EINVAL; | ||
345 | |||
346 | if (reg->match_chip != mt9m001->client->addr) | ||
347 | return -ENODEV; | ||
348 | |||
349 | reg->val = reg_read(icd, reg->reg); | ||
350 | |||
351 | if (reg->val > 0xffff) | ||
352 | return -EIO; | ||
353 | |||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | static int mt9m001_set_register(struct soc_camera_device *icd, | ||
358 | struct v4l2_register *reg) | ||
359 | { | ||
360 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
361 | |||
362 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | ||
363 | return -EINVAL; | ||
364 | |||
365 | if (reg->match_chip != mt9m001->client->addr) | ||
366 | return -ENODEV; | ||
367 | |||
368 | if (reg_write(icd, reg->reg, reg->val) < 0) | ||
369 | return -EIO; | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | #endif | ||
374 | |||
375 | const struct v4l2_queryctrl mt9m001_controls[] = { | ||
376 | { | ||
377 | .id = V4L2_CID_VFLIP, | ||
378 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
379 | .name = "Flip Vertically", | ||
380 | .minimum = 0, | ||
381 | .maximum = 1, | ||
382 | .step = 1, | ||
383 | .default_value = 0, | ||
384 | }, { | ||
385 | .id = V4L2_CID_GAIN, | ||
386 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
387 | .name = "Gain", | ||
388 | .minimum = 0, | ||
389 | .maximum = 127, | ||
390 | .step = 1, | ||
391 | .default_value = 64, | ||
392 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
393 | }, { | ||
394 | .id = V4L2_CID_EXPOSURE, | ||
395 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
396 | .name = "Exposure", | ||
397 | .minimum = 1, | ||
398 | .maximum = 255, | ||
399 | .step = 1, | ||
400 | .default_value = 255, | ||
401 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
402 | }, { | ||
403 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
404 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
405 | .name = "Automatic Exposure", | ||
406 | .minimum = 0, | ||
407 | .maximum = 1, | ||
408 | .step = 1, | ||
409 | .default_value = 1, | ||
410 | } | ||
411 | }; | ||
412 | |||
413 | static int mt9m001_video_probe(struct soc_camera_device *); | ||
414 | static void mt9m001_video_remove(struct soc_camera_device *); | ||
415 | static int mt9m001_get_control(struct soc_camera_device *, struct v4l2_control *); | ||
416 | static int mt9m001_set_control(struct soc_camera_device *, struct v4l2_control *); | ||
417 | |||
418 | static struct soc_camera_ops mt9m001_ops = { | ||
419 | .owner = THIS_MODULE, | ||
420 | .probe = mt9m001_video_probe, | ||
421 | .remove = mt9m001_video_remove, | ||
422 | .init = mt9m001_init, | ||
423 | .release = mt9m001_release, | ||
424 | .start_capture = mt9m001_start_capture, | ||
425 | .stop_capture = mt9m001_stop_capture, | ||
426 | .set_fmt_cap = mt9m001_set_fmt_cap, | ||
427 | .try_fmt_cap = mt9m001_try_fmt_cap, | ||
428 | .set_bus_param = mt9m001_set_bus_param, | ||
429 | .query_bus_param = mt9m001_query_bus_param, | ||
430 | .controls = mt9m001_controls, | ||
431 | .num_controls = ARRAY_SIZE(mt9m001_controls), | ||
432 | .get_control = mt9m001_get_control, | ||
433 | .set_control = mt9m001_set_control, | ||
434 | .get_chip_id = mt9m001_get_chip_id, | ||
435 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
436 | .get_register = mt9m001_get_register, | ||
437 | .set_register = mt9m001_set_register, | ||
438 | #endif | ||
439 | }; | ||
440 | |||
441 | static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | ||
442 | { | ||
443 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
444 | int data; | ||
445 | |||
446 | switch (ctrl->id) { | ||
447 | case V4L2_CID_VFLIP: | ||
448 | data = reg_read(icd, MT9M001_READ_OPTIONS2); | ||
449 | if (data < 0) | ||
450 | return -EIO; | ||
451 | ctrl->value = !!(data & 0x8000); | ||
452 | break; | ||
453 | case V4L2_CID_EXPOSURE_AUTO: | ||
454 | ctrl->value = mt9m001->autoexposure; | ||
455 | break; | ||
456 | } | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | ||
461 | { | ||
462 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
463 | const struct v4l2_queryctrl *qctrl; | ||
464 | int data; | ||
465 | |||
466 | qctrl = soc_camera_find_qctrl(&mt9m001_ops, ctrl->id); | ||
467 | |||
468 | if (!qctrl) | ||
469 | return -EINVAL; | ||
470 | |||
471 | switch (ctrl->id) { | ||
472 | case V4L2_CID_VFLIP: | ||
473 | if (ctrl->value) | ||
474 | data = reg_set(icd, MT9M001_READ_OPTIONS2, 0x8000); | ||
475 | else | ||
476 | data = reg_clear(icd, MT9M001_READ_OPTIONS2, 0x8000); | ||
477 | if (data < 0) | ||
478 | return -EIO; | ||
479 | break; | ||
480 | case V4L2_CID_GAIN: | ||
481 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) | ||
482 | return -EINVAL; | ||
483 | /* See Datasheet Table 7, Gain settings. */ | ||
484 | if (ctrl->value <= qctrl->default_value) { | ||
485 | /* Pack it into 0..1 step 0.125, register values 0..8 */ | ||
486 | unsigned long range = qctrl->default_value - qctrl->minimum; | ||
487 | data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; | ||
488 | |||
489 | dev_dbg(&icd->dev, "Setting gain %d\n", data); | ||
490 | data = reg_write(icd, MT9M001_GLOBAL_GAIN, data); | ||
491 | if (data < 0) | ||
492 | return -EIO; | ||
493 | } else { | ||
494 | /* Pack it into 1.125..15 variable step, register values 9..67 */ | ||
495 | /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */ | ||
496 | unsigned long range = qctrl->maximum - qctrl->default_value - 1; | ||
497 | unsigned long gain = ((ctrl->value - qctrl->default_value - 1) * | ||
498 | 111 + range / 2) / range + 9; | ||
499 | |||
500 | if (gain <= 32) | ||
501 | data = gain; | ||
502 | else if (gain <= 64) | ||
503 | data = ((gain - 32) * 16 + 16) / 32 + 80; | ||
504 | else | ||
505 | data = ((gain - 64) * 7 + 28) / 56 + 96; | ||
506 | |||
507 | dev_dbg(&icd->dev, "Setting gain from %d to %d\n", | ||
508 | reg_read(icd, MT9M001_GLOBAL_GAIN), data); | ||
509 | data = reg_write(icd, MT9M001_GLOBAL_GAIN, data); | ||
510 | if (data < 0) | ||
511 | return -EIO; | ||
512 | } | ||
513 | |||
514 | /* Success */ | ||
515 | icd->gain = ctrl->value; | ||
516 | break; | ||
517 | case V4L2_CID_EXPOSURE: | ||
518 | /* mt9m001 has maximum == default */ | ||
519 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) | ||
520 | return -EINVAL; | ||
521 | else { | ||
522 | unsigned long range = qctrl->maximum - qctrl->minimum; | ||
523 | unsigned long shutter = ((ctrl->value - qctrl->minimum) * 1048 + | ||
524 | range / 2) / range + 1; | ||
525 | |||
526 | dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n", | ||
527 | reg_read(icd, MT9M001_SHUTTER_WIDTH), shutter); | ||
528 | if (reg_write(icd, MT9M001_SHUTTER_WIDTH, shutter) < 0) | ||
529 | return -EIO; | ||
530 | icd->exposure = ctrl->value; | ||
531 | mt9m001->autoexposure = 0; | ||
532 | } | ||
533 | break; | ||
534 | case V4L2_CID_EXPOSURE_AUTO: | ||
535 | if (ctrl->value) { | ||
536 | const u16 vblank = 25; | ||
537 | if (reg_write(icd, MT9M001_SHUTTER_WIDTH, icd->height + | ||
538 | icd->y_skip_top + vblank) < 0) | ||
539 | return -EIO; | ||
540 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | ||
541 | icd->exposure = (524 + (icd->height + icd->y_skip_top + vblank - 1) * | ||
542 | (qctrl->maximum - qctrl->minimum)) / | ||
543 | 1048 + qctrl->minimum; | ||
544 | mt9m001->autoexposure = 1; | ||
545 | } else | ||
546 | mt9m001->autoexposure = 0; | ||
547 | break; | ||
548 | } | ||
549 | return 0; | ||
550 | } | ||
551 | |||
552 | /* Interface active, can use i2c. If it fails, it can indeed mean, that | ||
553 | * this wasn't our capture interface, so, we wait for the right one */ | ||
554 | static int mt9m001_video_probe(struct soc_camera_device *icd) | ||
555 | { | ||
556 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
557 | s32 data; | ||
558 | int ret; | ||
559 | |||
560 | /* We must have a parent by now. And it cannot be a wrong one. | ||
561 | * So this entire test is completely redundant. */ | ||
562 | if (!icd->dev.parent || | ||
563 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) | ||
564 | return -ENODEV; | ||
565 | |||
566 | /* Enable the chip */ | ||
567 | data = reg_write(&mt9m001->icd, MT9M001_CHIP_ENABLE, 1); | ||
568 | dev_dbg(&icd->dev, "write: %d\n", data); | ||
569 | |||
570 | /* Read out the chip version register */ | ||
571 | data = reg_read(icd, MT9M001_CHIP_VERSION); | ||
572 | |||
573 | /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ | ||
574 | switch (data) { | ||
575 | case 0x8411: | ||
576 | case 0x8421: | ||
577 | mt9m001->model = V4L2_IDENT_MT9M001C12ST; | ||
578 | icd->formats = mt9m001_colour_formats; | ||
579 | if (mt9m001->client->dev.platform_data) | ||
580 | icd->num_formats = ARRAY_SIZE(mt9m001_colour_formats); | ||
581 | else | ||
582 | icd->num_formats = 1; | ||
583 | break; | ||
584 | case 0x8431: | ||
585 | mt9m001->model = V4L2_IDENT_MT9M001C12STM; | ||
586 | icd->formats = mt9m001_monochrome_formats; | ||
587 | if (mt9m001->client->dev.platform_data) | ||
588 | icd->num_formats = ARRAY_SIZE(mt9m001_monochrome_formats); | ||
589 | else | ||
590 | icd->num_formats = 1; | ||
591 | break; | ||
592 | default: | ||
593 | ret = -ENODEV; | ||
594 | dev_err(&icd->dev, | ||
595 | "No MT9M001 chip detected, register read %x\n", data); | ||
596 | goto ei2c; | ||
597 | } | ||
598 | |||
599 | dev_info(&icd->dev, "Detected a MT9M001 chip ID %x (%s)\n", data, | ||
600 | data == 0x8431 ? "C12STM" : "C12ST"); | ||
601 | |||
602 | /* Now that we know the model, we can start video */ | ||
603 | ret = soc_camera_video_start(icd); | ||
604 | if (ret) | ||
605 | goto eisis; | ||
606 | |||
607 | return 0; | ||
608 | |||
609 | eisis: | ||
610 | ei2c: | ||
611 | return ret; | ||
612 | } | ||
613 | |||
614 | static void mt9m001_video_remove(struct soc_camera_device *icd) | ||
615 | { | ||
616 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
617 | |||
618 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, | ||
619 | mt9m001->icd.dev.parent, mt9m001->icd.vdev); | ||
620 | soc_camera_video_stop(&mt9m001->icd); | ||
621 | } | ||
622 | |||
623 | static int mt9m001_probe(struct i2c_client *client) | ||
624 | { | ||
625 | struct mt9m001 *mt9m001; | ||
626 | struct soc_camera_device *icd; | ||
627 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | ||
628 | struct soc_camera_link *icl = client->dev.platform_data; | ||
629 | int ret; | ||
630 | |||
631 | if (!icl) { | ||
632 | dev_err(&client->dev, "MT9M001 driver needs platform data\n"); | ||
633 | return -EINVAL; | ||
634 | } | ||
635 | |||
636 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { | ||
637 | dev_warn(&adapter->dev, | ||
638 | "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); | ||
639 | return -EIO; | ||
640 | } | ||
641 | |||
642 | mt9m001 = kzalloc(sizeof(struct mt9m001), GFP_KERNEL); | ||
643 | if (!mt9m001) | ||
644 | return -ENOMEM; | ||
645 | |||
646 | mt9m001->client = client; | ||
647 | i2c_set_clientdata(client, mt9m001); | ||
648 | |||
649 | /* Second stage probe - when a capture adapter is there */ | ||
650 | icd = &mt9m001->icd; | ||
651 | icd->ops = &mt9m001_ops; | ||
652 | icd->control = &client->dev; | ||
653 | icd->x_min = 20; | ||
654 | icd->y_min = 12; | ||
655 | icd->x_current = 20; | ||
656 | icd->y_current = 12; | ||
657 | icd->width_min = 48; | ||
658 | icd->width_max = 1280; | ||
659 | icd->height_min = 32; | ||
660 | icd->height_max = 1024; | ||
661 | icd->y_skip_top = 1; | ||
662 | icd->iface = icl->bus_id; | ||
663 | /* Default datawidth - this is the only width this camera (normally) | ||
664 | * supports. It is only with extra logic that it can support | ||
665 | * other widths. Therefore it seems to be a sensible default. */ | ||
666 | mt9m001->datawidth = 10; | ||
667 | /* Simulated autoexposure. If enabled, we calculate shutter width | ||
668 | * ourselves in the driver based on vertical blanking and frame width */ | ||
669 | mt9m001->autoexposure = 1; | ||
670 | |||
671 | ret = bus_switch_request(mt9m001, icl); | ||
672 | if (ret) | ||
673 | goto eswinit; | ||
674 | |||
675 | ret = soc_camera_device_register(icd); | ||
676 | if (ret) | ||
677 | goto eisdr; | ||
678 | |||
679 | return 0; | ||
680 | |||
681 | eisdr: | ||
682 | bus_switch_release(mt9m001); | ||
683 | eswinit: | ||
684 | kfree(mt9m001); | ||
685 | return ret; | ||
686 | } | ||
687 | |||
688 | static int mt9m001_remove(struct i2c_client *client) | ||
689 | { | ||
690 | struct mt9m001 *mt9m001 = i2c_get_clientdata(client); | ||
691 | |||
692 | soc_camera_device_unregister(&mt9m001->icd); | ||
693 | bus_switch_release(mt9m001); | ||
694 | kfree(mt9m001); | ||
695 | |||
696 | return 0; | ||
697 | } | ||
698 | |||
699 | static struct i2c_driver mt9m001_i2c_driver = { | ||
700 | .driver = { | ||
701 | .name = "mt9m001", | ||
702 | }, | ||
703 | .probe = mt9m001_probe, | ||
704 | .remove = mt9m001_remove, | ||
705 | }; | ||
706 | |||
707 | static int __init mt9m001_mod_init(void) | ||
708 | { | ||
709 | return i2c_add_driver(&mt9m001_i2c_driver); | ||
710 | } | ||
711 | |||
712 | static void __exit mt9m001_mod_exit(void) | ||
713 | { | ||
714 | i2c_del_driver(&mt9m001_i2c_driver); | ||
715 | } | ||
716 | |||
717 | module_init(mt9m001_mod_init); | ||
718 | module_exit(mt9m001_mod_exit); | ||
719 | |||
720 | MODULE_DESCRIPTION("Micron MT9M001 Camera driver"); | ||
721 | MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); | ||
722 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c new file mode 100644 index 000000000000..d4b9e2744343 --- /dev/null +++ b/drivers/media/video/mt9v022.c | |||
@@ -0,0 +1,844 @@ | |||
1 | /* | ||
2 | * Driver for MT9V022 CMOS Image Sensor from Micron | ||
3 | * | ||
4 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/videodev2.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/log2.h> | ||
16 | |||
17 | #include <media/v4l2-common.h> | ||
18 | #include <media/v4l2-chip-ident.h> | ||
19 | #include <media/soc_camera.h> | ||
20 | |||
21 | #ifdef CONFIG_MT9M001_PCA9536_SWITCH | ||
22 | #include <asm/gpio.h> | ||
23 | #endif | ||
24 | |||
25 | /* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c | ||
26 | * The platform has to define i2c_board_info | ||
27 | * and call i2c_register_board_info() */ | ||
28 | |||
29 | static char *sensor_type; | ||
30 | module_param(sensor_type, charp, S_IRUGO); | ||
31 | MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"\n"); | ||
32 | |||
33 | /* mt9v022 selected register addresses */ | ||
34 | #define MT9V022_CHIP_VERSION 0x00 | ||
35 | #define MT9V022_COLUMN_START 0x01 | ||
36 | #define MT9V022_ROW_START 0x02 | ||
37 | #define MT9V022_WINDOW_HEIGHT 0x03 | ||
38 | #define MT9V022_WINDOW_WIDTH 0x04 | ||
39 | #define MT9V022_HORIZONTAL_BLANKING 0x05 | ||
40 | #define MT9V022_VERTICAL_BLANKING 0x06 | ||
41 | #define MT9V022_CHIP_CONTROL 0x07 | ||
42 | #define MT9V022_SHUTTER_WIDTH1 0x08 | ||
43 | #define MT9V022_SHUTTER_WIDTH2 0x09 | ||
44 | #define MT9V022_SHUTTER_WIDTH_CTRL 0x0a | ||
45 | #define MT9V022_TOTAL_SHUTTER_WIDTH 0x0b | ||
46 | #define MT9V022_RESET 0x0c | ||
47 | #define MT9V022_READ_MODE 0x0d | ||
48 | #define MT9V022_MONITOR_MODE 0x0e | ||
49 | #define MT9V022_PIXEL_OPERATION_MODE 0x0f | ||
50 | #define MT9V022_LED_OUT_CONTROL 0x1b | ||
51 | #define MT9V022_ADC_MODE_CONTROL 0x1c | ||
52 | #define MT9V022_ANALOG_GAIN 0x34 | ||
53 | #define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47 | ||
54 | #define MT9V022_PIXCLK_FV_LV 0x74 | ||
55 | #define MT9V022_DIGITAL_TEST_PATTERN 0x7f | ||
56 | #define MT9V022_AEC_AGC_ENABLE 0xAF | ||
57 | #define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD | ||
58 | |||
59 | /* Progressive scan, master, defaults */ | ||
60 | #define MT9V022_CHIP_CONTROL_DEFAULT 0x188 | ||
61 | |||
62 | static const struct soc_camera_data_format mt9v022_colour_formats[] = { | ||
63 | /* Order important: first natively supported, | ||
64 | * second supported with a GPIO extender */ | ||
65 | { | ||
66 | .name = "Bayer (sRGB) 10 bit", | ||
67 | .depth = 10, | ||
68 | .fourcc = V4L2_PIX_FMT_SBGGR16, | ||
69 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
70 | }, { | ||
71 | .name = "Bayer (sRGB) 8 bit", | ||
72 | .depth = 8, | ||
73 | .fourcc = V4L2_PIX_FMT_SBGGR8, | ||
74 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
75 | } | ||
76 | }; | ||
77 | |||
78 | static const struct soc_camera_data_format mt9v022_monochrome_formats[] = { | ||
79 | /* Order important - see above */ | ||
80 | { | ||
81 | .name = "Monochrome 10 bit", | ||
82 | .depth = 10, | ||
83 | .fourcc = V4L2_PIX_FMT_Y16, | ||
84 | }, { | ||
85 | .name = "Monochrome 8 bit", | ||
86 | .depth = 8, | ||
87 | .fourcc = V4L2_PIX_FMT_GREY, | ||
88 | }, | ||
89 | }; | ||
90 | |||
91 | struct mt9v022 { | ||
92 | struct i2c_client *client; | ||
93 | struct soc_camera_device icd; | ||
94 | int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ | ||
95 | int switch_gpio; | ||
96 | u16 chip_control; | ||
97 | unsigned char datawidth; | ||
98 | }; | ||
99 | |||
100 | static int reg_read(struct soc_camera_device *icd, const u8 reg) | ||
101 | { | ||
102 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
103 | struct i2c_client *client = mt9v022->client; | ||
104 | s32 data = i2c_smbus_read_word_data(client, reg); | ||
105 | return data < 0 ? data : swab16(data); | ||
106 | } | ||
107 | |||
108 | static int reg_write(struct soc_camera_device *icd, const u8 reg, | ||
109 | const u16 data) | ||
110 | { | ||
111 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
112 | return i2c_smbus_write_word_data(mt9v022->client, reg, swab16(data)); | ||
113 | } | ||
114 | |||
115 | static int reg_set(struct soc_camera_device *icd, const u8 reg, | ||
116 | const u16 data) | ||
117 | { | ||
118 | int ret; | ||
119 | |||
120 | ret = reg_read(icd, reg); | ||
121 | if (ret < 0) | ||
122 | return ret; | ||
123 | return reg_write(icd, reg, ret | data); | ||
124 | } | ||
125 | |||
126 | static int reg_clear(struct soc_camera_device *icd, const u8 reg, | ||
127 | const u16 data) | ||
128 | { | ||
129 | int ret; | ||
130 | |||
131 | ret = reg_read(icd, reg); | ||
132 | if (ret < 0) | ||
133 | return ret; | ||
134 | return reg_write(icd, reg, ret & ~data); | ||
135 | } | ||
136 | |||
137 | static int mt9v022_init(struct soc_camera_device *icd) | ||
138 | { | ||
139 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
140 | int ret; | ||
141 | |||
142 | /* Almost the default mode: master, parallel, simultaneous, and an | ||
143 | * undocumented bit 0x200, which is present in table 7, but not in 8, | ||
144 | * plus snapshot mode to disable scan for now */ | ||
145 | mt9v022->chip_control |= 0x10; | ||
146 | ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); | ||
147 | if (ret >= 0) | ||
148 | reg_write(icd, MT9V022_READ_MODE, 0x300); | ||
149 | |||
150 | /* All defaults */ | ||
151 | if (ret >= 0) | ||
152 | /* AEC, AGC on */ | ||
153 | ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3); | ||
154 | if (ret >= 0) | ||
155 | ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); | ||
156 | if (ret >= 0) | ||
157 | /* default - auto */ | ||
158 | ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); | ||
159 | if (ret >= 0) | ||
160 | ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0); | ||
161 | |||
162 | return ret >= 0 ? 0 : -EIO; | ||
163 | } | ||
164 | |||
165 | static int mt9v022_release(struct soc_camera_device *icd) | ||
166 | { | ||
167 | /* Nothing? */ | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | static int mt9v022_start_capture(struct soc_camera_device *icd) | ||
172 | { | ||
173 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
174 | /* Switch to master "normal" mode */ | ||
175 | mt9v022->chip_control &= ~0x10; | ||
176 | if (reg_write(icd, MT9V022_CHIP_CONTROL, | ||
177 | mt9v022->chip_control) < 0) | ||
178 | return -EIO; | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int mt9v022_stop_capture(struct soc_camera_device *icd) | ||
183 | { | ||
184 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
185 | /* Switch to snapshot mode */ | ||
186 | mt9v022->chip_control |= 0x10; | ||
187 | if (reg_write(icd, MT9V022_CHIP_CONTROL, | ||
188 | mt9v022->chip_control) < 0) | ||
189 | return -EIO; | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int bus_switch_request(struct mt9v022 *mt9v022, struct soc_camera_link *icl) | ||
194 | { | ||
195 | #ifdef CONFIG_MT9V022_PCA9536_SWITCH | ||
196 | int ret; | ||
197 | unsigned int gpio = icl->gpio; | ||
198 | |||
199 | if (gpio_is_valid(gpio)) { | ||
200 | /* We have a data bus switch. */ | ||
201 | ret = gpio_request(gpio, "mt9v022"); | ||
202 | if (ret < 0) { | ||
203 | dev_err(&mt9v022->client->dev, "Cannot get GPIO %u\n", gpio); | ||
204 | return ret; | ||
205 | } | ||
206 | |||
207 | ret = gpio_direction_output(gpio, 0); | ||
208 | if (ret < 0) { | ||
209 | dev_err(&mt9v022->client->dev, | ||
210 | "Cannot set GPIO %u to output\n", gpio); | ||
211 | gpio_free(gpio); | ||
212 | return ret; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | mt9v022->switch_gpio = gpio; | ||
217 | #else | ||
218 | mt9v022->switch_gpio = -EINVAL; | ||
219 | #endif | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static void bus_switch_release(struct mt9v022 *mt9v022) | ||
224 | { | ||
225 | #ifdef CONFIG_MT9V022_PCA9536_SWITCH | ||
226 | if (gpio_is_valid(mt9v022->switch_gpio)) | ||
227 | gpio_free(mt9v022->switch_gpio); | ||
228 | #endif | ||
229 | } | ||
230 | |||
231 | static int bus_switch_act(struct mt9v022 *mt9v022, int go8bit) | ||
232 | { | ||
233 | #ifdef CONFIG_MT9V022_PCA9536_SWITCH | ||
234 | if (!gpio_is_valid(mt9v022->switch_gpio)) | ||
235 | return -ENODEV; | ||
236 | |||
237 | gpio_set_value_cansleep(mt9v022->switch_gpio, go8bit); | ||
238 | return 0; | ||
239 | #else | ||
240 | return -ENODEV; | ||
241 | #endif | ||
242 | } | ||
243 | |||
244 | static int bus_switch_possible(struct mt9v022 *mt9v022) | ||
245 | { | ||
246 | #ifdef CONFIG_MT9V022_PCA9536_SWITCH | ||
247 | return gpio_is_valid(mt9v022->switch_gpio); | ||
248 | #else | ||
249 | return 0; | ||
250 | #endif | ||
251 | } | ||
252 | |||
253 | static int mt9v022_set_bus_param(struct soc_camera_device *icd, | ||
254 | unsigned long flags) | ||
255 | { | ||
256 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
257 | unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; | ||
258 | int ret; | ||
259 | u16 pixclk = 0; | ||
260 | |||
261 | /* Only one width bit may be set */ | ||
262 | if (!is_power_of_2(width_flag)) | ||
263 | return -EINVAL; | ||
264 | |||
265 | if ((mt9v022->datawidth != 10 && (width_flag == SOCAM_DATAWIDTH_10)) || | ||
266 | (mt9v022->datawidth != 9 && (width_flag == SOCAM_DATAWIDTH_9)) || | ||
267 | (mt9v022->datawidth != 8 && (width_flag == SOCAM_DATAWIDTH_8))) { | ||
268 | /* Well, we actually only can do 10 or 8 bits... */ | ||
269 | if (width_flag == SOCAM_DATAWIDTH_9) | ||
270 | return -EINVAL; | ||
271 | |||
272 | ret = bus_switch_act(mt9v022, | ||
273 | width_flag == SOCAM_DATAWIDTH_8); | ||
274 | if (ret < 0) | ||
275 | return ret; | ||
276 | |||
277 | mt9v022->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10; | ||
278 | } | ||
279 | |||
280 | if (flags & SOCAM_PCLK_SAMPLE_RISING) | ||
281 | pixclk |= 0x10; | ||
282 | |||
283 | if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH)) | ||
284 | pixclk |= 0x1; | ||
285 | |||
286 | if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH)) | ||
287 | pixclk |= 0x2; | ||
288 | |||
289 | ret = reg_write(icd, MT9V022_PIXCLK_FV_LV, pixclk); | ||
290 | if (ret < 0) | ||
291 | return ret; | ||
292 | |||
293 | if (!(flags & SOCAM_MASTER)) | ||
294 | mt9v022->chip_control &= ~0x8; | ||
295 | |||
296 | ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); | ||
297 | if (ret < 0) | ||
298 | return ret; | ||
299 | |||
300 | dev_dbg(&icd->dev, "Calculated pixclk 0x%x, chip control 0x%x\n", | ||
301 | pixclk, mt9v022->chip_control); | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) | ||
307 | { | ||
308 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
309 | unsigned int width_flag = SOCAM_DATAWIDTH_10; | ||
310 | |||
311 | if (bus_switch_possible(mt9v022)) | ||
312 | width_flag |= SOCAM_DATAWIDTH_8; | ||
313 | |||
314 | return SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | | ||
315 | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW | | ||
316 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW | | ||
317 | SOCAM_MASTER | SOCAM_SLAVE | | ||
318 | width_flag; | ||
319 | } | ||
320 | |||
321 | static int mt9v022_set_fmt_cap(struct soc_camera_device *icd, | ||
322 | __u32 pixfmt, struct v4l2_rect *rect) | ||
323 | { | ||
324 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
325 | int ret; | ||
326 | |||
327 | /* The caller provides a supported format, as verified per call to | ||
328 | * icd->try_fmt_cap(), datawidth is from our supported format list */ | ||
329 | switch (pixfmt) { | ||
330 | case V4L2_PIX_FMT_GREY: | ||
331 | case V4L2_PIX_FMT_Y16: | ||
332 | if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) | ||
333 | return -EINVAL; | ||
334 | break; | ||
335 | case V4L2_PIX_FMT_SBGGR8: | ||
336 | case V4L2_PIX_FMT_SBGGR16: | ||
337 | if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) | ||
338 | return -EINVAL; | ||
339 | break; | ||
340 | case 0: | ||
341 | /* No format change, only geometry */ | ||
342 | break; | ||
343 | default: | ||
344 | return -EINVAL; | ||
345 | } | ||
346 | |||
347 | /* Like in example app. Contradicts the datasheet though */ | ||
348 | ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | ||
349 | if (ret >= 0) { | ||
350 | if (ret & 1) /* Autoexposure */ | ||
351 | ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, | ||
352 | rect->height + icd->y_skip_top + 43); | ||
353 | else | ||
354 | ret = reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, | ||
355 | rect->height + icd->y_skip_top + 43); | ||
356 | } | ||
357 | /* Setup frame format: defaults apart from width and height */ | ||
358 | if (ret >= 0) | ||
359 | ret = reg_write(icd, MT9V022_COLUMN_START, rect->left); | ||
360 | if (ret >= 0) | ||
361 | ret = reg_write(icd, MT9V022_ROW_START, rect->top); | ||
362 | if (ret >= 0) | ||
363 | /* Default 94, Phytec driver says: | ||
364 | * "width + horizontal blank >= 660" */ | ||
365 | ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING, | ||
366 | rect->width > 660 - 43 ? 43 : | ||
367 | 660 - rect->width); | ||
368 | if (ret >= 0) | ||
369 | ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45); | ||
370 | if (ret >= 0) | ||
371 | ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width); | ||
372 | if (ret >= 0) | ||
373 | ret = reg_write(icd, MT9V022_WINDOW_HEIGHT, | ||
374 | rect->height + icd->y_skip_top); | ||
375 | |||
376 | if (ret < 0) | ||
377 | return ret; | ||
378 | |||
379 | dev_dbg(&icd->dev, "Frame %ux%u pixel\n", rect->width, rect->height); | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static int mt9v022_try_fmt_cap(struct soc_camera_device *icd, | ||
385 | struct v4l2_format *f) | ||
386 | { | ||
387 | if (f->fmt.pix.height < 32 + icd->y_skip_top) | ||
388 | f->fmt.pix.height = 32 + icd->y_skip_top; | ||
389 | if (f->fmt.pix.height > 480 + icd->y_skip_top) | ||
390 | f->fmt.pix.height = 480 + icd->y_skip_top; | ||
391 | if (f->fmt.pix.width < 48) | ||
392 | f->fmt.pix.width = 48; | ||
393 | if (f->fmt.pix.width > 752) | ||
394 | f->fmt.pix.width = 752; | ||
395 | f->fmt.pix.width &= ~0x03; /* ? */ | ||
396 | |||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | static int mt9v022_get_chip_id(struct soc_camera_device *icd, | ||
401 | struct v4l2_chip_ident *id) | ||
402 | { | ||
403 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
404 | |||
405 | if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) | ||
406 | return -EINVAL; | ||
407 | |||
408 | if (id->match_chip != mt9v022->client->addr) | ||
409 | return -ENODEV; | ||
410 | |||
411 | id->ident = mt9v022->model; | ||
412 | id->revision = 0; | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
418 | static int mt9v022_get_register(struct soc_camera_device *icd, | ||
419 | struct v4l2_register *reg) | ||
420 | { | ||
421 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
422 | |||
423 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | ||
424 | return -EINVAL; | ||
425 | |||
426 | if (reg->match_chip != mt9v022->client->addr) | ||
427 | return -ENODEV; | ||
428 | |||
429 | reg->val = reg_read(icd, reg->reg); | ||
430 | |||
431 | if (reg->val > 0xffff) | ||
432 | return -EIO; | ||
433 | |||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | static int mt9v022_set_register(struct soc_camera_device *icd, | ||
438 | struct v4l2_register *reg) | ||
439 | { | ||
440 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
441 | |||
442 | if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | ||
443 | return -EINVAL; | ||
444 | |||
445 | if (reg->match_chip != mt9v022->client->addr) | ||
446 | return -ENODEV; | ||
447 | |||
448 | if (reg_write(icd, reg->reg, reg->val) < 0) | ||
449 | return -EIO; | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | #endif | ||
454 | |||
455 | const struct v4l2_queryctrl mt9v022_controls[] = { | ||
456 | { | ||
457 | .id = V4L2_CID_VFLIP, | ||
458 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
459 | .name = "Flip Vertically", | ||
460 | .minimum = 0, | ||
461 | .maximum = 1, | ||
462 | .step = 1, | ||
463 | .default_value = 0, | ||
464 | }, { | ||
465 | .id = V4L2_CID_HFLIP, | ||
466 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
467 | .name = "Flip Horizontally", | ||
468 | .minimum = 0, | ||
469 | .maximum = 1, | ||
470 | .step = 1, | ||
471 | .default_value = 0, | ||
472 | }, { | ||
473 | .id = V4L2_CID_GAIN, | ||
474 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
475 | .name = "Analog Gain", | ||
476 | .minimum = 64, | ||
477 | .maximum = 127, | ||
478 | .step = 1, | ||
479 | .default_value = 64, | ||
480 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
481 | }, { | ||
482 | .id = V4L2_CID_EXPOSURE, | ||
483 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
484 | .name = "Exposure", | ||
485 | .minimum = 1, | ||
486 | .maximum = 255, | ||
487 | .step = 1, | ||
488 | .default_value = 255, | ||
489 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
490 | }, { | ||
491 | .id = V4L2_CID_AUTOGAIN, | ||
492 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
493 | .name = "Automatic Gain", | ||
494 | .minimum = 0, | ||
495 | .maximum = 1, | ||
496 | .step = 1, | ||
497 | .default_value = 1, | ||
498 | }, { | ||
499 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
500 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
501 | .name = "Automatic Exposure", | ||
502 | .minimum = 0, | ||
503 | .maximum = 1, | ||
504 | .step = 1, | ||
505 | .default_value = 1, | ||
506 | } | ||
507 | }; | ||
508 | |||
509 | static int mt9v022_video_probe(struct soc_camera_device *); | ||
510 | static void mt9v022_video_remove(struct soc_camera_device *); | ||
511 | static int mt9v022_get_control(struct soc_camera_device *, struct v4l2_control *); | ||
512 | static int mt9v022_set_control(struct soc_camera_device *, struct v4l2_control *); | ||
513 | |||
514 | static struct soc_camera_ops mt9v022_ops = { | ||
515 | .owner = THIS_MODULE, | ||
516 | .probe = mt9v022_video_probe, | ||
517 | .remove = mt9v022_video_remove, | ||
518 | .init = mt9v022_init, | ||
519 | .release = mt9v022_release, | ||
520 | .start_capture = mt9v022_start_capture, | ||
521 | .stop_capture = mt9v022_stop_capture, | ||
522 | .set_fmt_cap = mt9v022_set_fmt_cap, | ||
523 | .try_fmt_cap = mt9v022_try_fmt_cap, | ||
524 | .set_bus_param = mt9v022_set_bus_param, | ||
525 | .query_bus_param = mt9v022_query_bus_param, | ||
526 | .controls = mt9v022_controls, | ||
527 | .num_controls = ARRAY_SIZE(mt9v022_controls), | ||
528 | .get_control = mt9v022_get_control, | ||
529 | .set_control = mt9v022_set_control, | ||
530 | .get_chip_id = mt9v022_get_chip_id, | ||
531 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
532 | .get_register = mt9v022_get_register, | ||
533 | .set_register = mt9v022_set_register, | ||
534 | #endif | ||
535 | }; | ||
536 | |||
537 | static int mt9v022_get_control(struct soc_camera_device *icd, | ||
538 | struct v4l2_control *ctrl) | ||
539 | { | ||
540 | int data; | ||
541 | |||
542 | switch (ctrl->id) { | ||
543 | case V4L2_CID_VFLIP: | ||
544 | data = reg_read(icd, MT9V022_READ_MODE); | ||
545 | if (data < 0) | ||
546 | return -EIO; | ||
547 | ctrl->value = !!(data & 0x10); | ||
548 | break; | ||
549 | case V4L2_CID_HFLIP: | ||
550 | data = reg_read(icd, MT9V022_READ_MODE); | ||
551 | if (data < 0) | ||
552 | return -EIO; | ||
553 | ctrl->value = !!(data & 0x20); | ||
554 | break; | ||
555 | case V4L2_CID_EXPOSURE_AUTO: | ||
556 | data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | ||
557 | if (data < 0) | ||
558 | return -EIO; | ||
559 | ctrl->value = !!(data & 0x1); | ||
560 | break; | ||
561 | case V4L2_CID_AUTOGAIN: | ||
562 | data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | ||
563 | if (data < 0) | ||
564 | return -EIO; | ||
565 | ctrl->value = !!(data & 0x2); | ||
566 | break; | ||
567 | } | ||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | static int mt9v022_set_control(struct soc_camera_device *icd, | ||
572 | struct v4l2_control *ctrl) | ||
573 | { | ||
574 | int data; | ||
575 | const struct v4l2_queryctrl *qctrl; | ||
576 | |||
577 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); | ||
578 | |||
579 | if (!qctrl) | ||
580 | return -EINVAL; | ||
581 | |||
582 | switch (ctrl->id) { | ||
583 | case V4L2_CID_VFLIP: | ||
584 | if (ctrl->value) | ||
585 | data = reg_set(icd, MT9V022_READ_MODE, 0x10); | ||
586 | else | ||
587 | data = reg_clear(icd, MT9V022_READ_MODE, 0x10); | ||
588 | if (data < 0) | ||
589 | return -EIO; | ||
590 | break; | ||
591 | case V4L2_CID_HFLIP: | ||
592 | if (ctrl->value) | ||
593 | data = reg_set(icd, MT9V022_READ_MODE, 0x20); | ||
594 | else | ||
595 | data = reg_clear(icd, MT9V022_READ_MODE, 0x20); | ||
596 | if (data < 0) | ||
597 | return -EIO; | ||
598 | break; | ||
599 | case V4L2_CID_GAIN: | ||
600 | /* mt9v022 has minimum == default */ | ||
601 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) | ||
602 | return -EINVAL; | ||
603 | else { | ||
604 | unsigned long range = qctrl->maximum - qctrl->minimum; | ||
605 | /* Datasheet says 16 to 64. autogain only works properly | ||
606 | * after setting gain to maximum 14. Larger values | ||
607 | * produce "white fly" noise effect. On the whole, | ||
608 | * manually setting analog gain does no good. */ | ||
609 | unsigned long gain = ((ctrl->value - qctrl->minimum) * | ||
610 | 10 + range / 2) / range + 4; | ||
611 | if (gain >= 32) | ||
612 | gain &= ~1; | ||
613 | /* The user wants to set gain manually, hope, she | ||
614 | * knows, what she's doing... Switch AGC off. */ | ||
615 | |||
616 | if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) | ||
617 | return -EIO; | ||
618 | |||
619 | dev_info(&icd->dev, "Setting gain from %d to %lu\n", | ||
620 | reg_read(icd, MT9V022_ANALOG_GAIN), gain); | ||
621 | if (reg_write(icd, MT9V022_ANALOG_GAIN, gain) < 0) | ||
622 | return -EIO; | ||
623 | icd->gain = ctrl->value; | ||
624 | } | ||
625 | break; | ||
626 | case V4L2_CID_EXPOSURE: | ||
627 | /* mt9v022 has maximum == default */ | ||
628 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) | ||
629 | return -EINVAL; | ||
630 | else { | ||
631 | unsigned long range = qctrl->maximum - qctrl->minimum; | ||
632 | unsigned long shutter = ((ctrl->value - qctrl->minimum) * | ||
633 | 479 + range / 2) / range + 1; | ||
634 | /* The user wants to set shutter width manually, hope, | ||
635 | * she knows, what she's doing... Switch AEC off. */ | ||
636 | |||
637 | if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) | ||
638 | return -EIO; | ||
639 | |||
640 | dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", | ||
641 | reg_read(icd, MT9V022_TOTAL_SHUTTER_WIDTH), | ||
642 | shutter); | ||
643 | if (reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, | ||
644 | shutter) < 0) | ||
645 | return -EIO; | ||
646 | icd->exposure = ctrl->value; | ||
647 | } | ||
648 | break; | ||
649 | case V4L2_CID_AUTOGAIN: | ||
650 | if (ctrl->value) | ||
651 | data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x2); | ||
652 | else | ||
653 | data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2); | ||
654 | if (data < 0) | ||
655 | return -EIO; | ||
656 | break; | ||
657 | case V4L2_CID_EXPOSURE_AUTO: | ||
658 | if (ctrl->value) | ||
659 | data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x1); | ||
660 | else | ||
661 | data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1); | ||
662 | if (data < 0) | ||
663 | return -EIO; | ||
664 | break; | ||
665 | } | ||
666 | return 0; | ||
667 | } | ||
668 | |||
669 | /* Interface active, can use i2c. If it fails, it can indeed mean, that | ||
670 | * this wasn't our capture interface, so, we wait for the right one */ | ||
671 | static int mt9v022_video_probe(struct soc_camera_device *icd) | ||
672 | { | ||
673 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
674 | s32 data; | ||
675 | int ret; | ||
676 | |||
677 | if (!icd->dev.parent || | ||
678 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) | ||
679 | return -ENODEV; | ||
680 | |||
681 | /* Read out the chip version register */ | ||
682 | data = reg_read(icd, MT9V022_CHIP_VERSION); | ||
683 | |||
684 | /* must be 0x1311 or 0x1313 */ | ||
685 | if (data != 0x1311 && data != 0x1313) { | ||
686 | ret = -ENODEV; | ||
687 | dev_info(&icd->dev, "No MT9V022 detected, ID register 0x%x\n", | ||
688 | data); | ||
689 | goto ei2c; | ||
690 | } | ||
691 | |||
692 | /* Soft reset */ | ||
693 | ret = reg_write(icd, MT9V022_RESET, 1); | ||
694 | if (ret < 0) | ||
695 | goto ei2c; | ||
696 | /* 15 clock cycles */ | ||
697 | udelay(200); | ||
698 | if (reg_read(icd, MT9V022_RESET)) { | ||
699 | dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); | ||
700 | goto ei2c; | ||
701 | } | ||
702 | |||
703 | /* Set monochrome or colour sensor type */ | ||
704 | if (sensor_type && (!strcmp("colour", sensor_type) || | ||
705 | !strcmp("color", sensor_type))) { | ||
706 | ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); | ||
707 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; | ||
708 | icd->formats = mt9v022_colour_formats; | ||
709 | if (mt9v022->client->dev.platform_data) | ||
710 | icd->num_formats = ARRAY_SIZE(mt9v022_colour_formats); | ||
711 | else | ||
712 | icd->num_formats = 1; | ||
713 | } else { | ||
714 | ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11); | ||
715 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; | ||
716 | icd->formats = mt9v022_monochrome_formats; | ||
717 | if (mt9v022->client->dev.platform_data) | ||
718 | icd->num_formats = ARRAY_SIZE(mt9v022_monochrome_formats); | ||
719 | else | ||
720 | icd->num_formats = 1; | ||
721 | } | ||
722 | |||
723 | if (ret >= 0) | ||
724 | ret = soc_camera_video_start(icd); | ||
725 | if (ret < 0) | ||
726 | goto eisis; | ||
727 | |||
728 | dev_info(&icd->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", | ||
729 | data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ? | ||
730 | "monochrome" : "colour"); | ||
731 | |||
732 | return 0; | ||
733 | |||
734 | eisis: | ||
735 | ei2c: | ||
736 | return ret; | ||
737 | } | ||
738 | |||
739 | static void mt9v022_video_remove(struct soc_camera_device *icd) | ||
740 | { | ||
741 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
742 | |||
743 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, | ||
744 | mt9v022->icd.dev.parent, mt9v022->icd.vdev); | ||
745 | soc_camera_video_stop(&mt9v022->icd); | ||
746 | } | ||
747 | |||
748 | static int mt9v022_probe(struct i2c_client *client) | ||
749 | { | ||
750 | struct mt9v022 *mt9v022; | ||
751 | struct soc_camera_device *icd; | ||
752 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | ||
753 | struct soc_camera_link *icl = client->dev.platform_data; | ||
754 | int ret; | ||
755 | |||
756 | if (!icl) { | ||
757 | dev_err(&client->dev, "MT9V022 driver needs platform data\n"); | ||
758 | return -EINVAL; | ||
759 | } | ||
760 | |||
761 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { | ||
762 | dev_warn(&adapter->dev, | ||
763 | "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); | ||
764 | return -EIO; | ||
765 | } | ||
766 | |||
767 | mt9v022 = kzalloc(sizeof(struct mt9v022), GFP_KERNEL); | ||
768 | if (!mt9v022) | ||
769 | return -ENOMEM; | ||
770 | |||
771 | mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; | ||
772 | mt9v022->client = client; | ||
773 | i2c_set_clientdata(client, mt9v022); | ||
774 | |||
775 | icd = &mt9v022->icd; | ||
776 | icd->ops = &mt9v022_ops; | ||
777 | icd->control = &client->dev; | ||
778 | icd->x_min = 1; | ||
779 | icd->y_min = 4; | ||
780 | icd->x_current = 1; | ||
781 | icd->y_current = 4; | ||
782 | icd->width_min = 48; | ||
783 | icd->width_max = 752; | ||
784 | icd->height_min = 32; | ||
785 | icd->height_max = 480; | ||
786 | icd->y_skip_top = 1; | ||
787 | icd->iface = icl->bus_id; | ||
788 | /* Default datawidth - this is the only width this camera (normally) | ||
789 | * supports. It is only with extra logic that it can support | ||
790 | * other widths. Therefore it seems to be a sensible default. */ | ||
791 | mt9v022->datawidth = 10; | ||
792 | |||
793 | ret = bus_switch_request(mt9v022, icl); | ||
794 | if (ret) | ||
795 | goto eswinit; | ||
796 | |||
797 | ret = soc_camera_device_register(icd); | ||
798 | if (ret) | ||
799 | goto eisdr; | ||
800 | |||
801 | return 0; | ||
802 | |||
803 | eisdr: | ||
804 | bus_switch_release(mt9v022); | ||
805 | eswinit: | ||
806 | kfree(mt9v022); | ||
807 | return ret; | ||
808 | } | ||
809 | |||
810 | static int mt9v022_remove(struct i2c_client *client) | ||
811 | { | ||
812 | struct mt9v022 *mt9v022 = i2c_get_clientdata(client); | ||
813 | |||
814 | soc_camera_device_unregister(&mt9v022->icd); | ||
815 | bus_switch_release(mt9v022); | ||
816 | kfree(mt9v022); | ||
817 | |||
818 | return 0; | ||
819 | } | ||
820 | |||
821 | static struct i2c_driver mt9v022_i2c_driver = { | ||
822 | .driver = { | ||
823 | .name = "mt9v022", | ||
824 | }, | ||
825 | .probe = mt9v022_probe, | ||
826 | .remove = mt9v022_remove, | ||
827 | }; | ||
828 | |||
829 | static int __init mt9v022_mod_init(void) | ||
830 | { | ||
831 | return i2c_add_driver(&mt9v022_i2c_driver); | ||
832 | } | ||
833 | |||
834 | static void __exit mt9v022_mod_exit(void) | ||
835 | { | ||
836 | i2c_del_driver(&mt9v022_i2c_driver); | ||
837 | } | ||
838 | |||
839 | module_init(mt9v022_mod_init); | ||
840 | module_exit(mt9v022_mod_exit); | ||
841 | |||
842 | MODULE_DESCRIPTION("Micron MT9V022 Camera driver"); | ||
843 | MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); | ||
844 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index cb5a510f9251..f68e91fbe7fb 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) | 38 | #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) |
39 | 39 | ||
40 | /* global variable */ | 40 | /* global variable */ |
41 | static int mxb_num = 0; | 41 | static int mxb_num; |
42 | 42 | ||
43 | /* initial frequence the tuner will be tuned to. | 43 | /* initial frequence the tuner will be tuned to. |
44 | in verden (lower saxony, germany) 4148 is a | 44 | in verden (lower saxony, germany) 4148 is a |
@@ -47,7 +47,7 @@ static int freq = 4148; | |||
47 | module_param(freq, int, 0644); | 47 | module_param(freq, int, 0644); |
48 | MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup"); | 48 | MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup"); |
49 | 49 | ||
50 | static int debug = 0; | 50 | static int debug; |
51 | module_param(debug, int, 0644); | 51 | module_param(debug, int, 0644); |
52 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | 52 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); |
53 | 53 | ||
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 6590058e8ff0..eafb0c7736e6 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c | |||
@@ -4659,7 +4659,9 @@ static const struct file_operations ov511_fops = { | |||
4659 | .read = ov51x_v4l1_read, | 4659 | .read = ov51x_v4l1_read, |
4660 | .mmap = ov51x_v4l1_mmap, | 4660 | .mmap = ov51x_v4l1_mmap, |
4661 | .ioctl = ov51x_v4l1_ioctl, | 4661 | .ioctl = ov51x_v4l1_ioctl, |
4662 | #ifdef CONFIG_COMPAT | ||
4662 | .compat_ioctl = v4l_compat_ioctl32, | 4663 | .compat_ioctl = v4l_compat_ioctl32, |
4664 | #endif | ||
4663 | .llseek = no_llseek, | 4665 | .llseek = no_llseek, |
4664 | }; | 4666 | }; |
4665 | 4667 | ||
@@ -5831,7 +5833,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
5831 | goto error; | 5833 | goto error; |
5832 | 5834 | ||
5833 | memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev)); | 5835 | memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev)); |
5834 | ov->vdev->dev = &dev->dev; | 5836 | ov->vdev->dev = &intf->dev; |
5835 | video_set_drvdata(ov->vdev, ov); | 5837 | video_set_drvdata(ov->vdev, ov); |
5836 | 5838 | ||
5837 | for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { | 5839 | for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { |
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h index 18c64222dd11..1010e51189b7 100644 --- a/drivers/media/video/ov511.h +++ b/drivers/media/video/ov511.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #ifdef OV511_DEBUG | 12 | #ifdef OV511_DEBUG |
13 | #define PDEBUG(level, fmt, args...) \ | 13 | #define PDEBUG(level, fmt, args...) \ |
14 | if (debug >= (level)) info("[%s:%d] " fmt, \ | 14 | if (debug >= (level)) info("[%s:%d] " fmt, \ |
15 | __FUNCTION__, __LINE__ , ## args) | 15 | __func__, __LINE__ , ## args) |
16 | #else | 16 | #else |
17 | #define PDEBUG(level, fmt, args...) do {} while(0) | 17 | #define PDEBUG(level, fmt, args...) do {} while(0) |
18 | #endif | 18 | #endif |
diff --git a/drivers/media/video/ovcamchip/ovcamchip_priv.h b/drivers/media/video/ovcamchip/ovcamchip_priv.h index 50c7763d44b3..9afa4fe47726 100644 --- a/drivers/media/video/ovcamchip/ovcamchip_priv.h +++ b/drivers/media/video/ovcamchip/ovcamchip_priv.h | |||
@@ -24,11 +24,11 @@ extern int ovcamchip_debug; | |||
24 | 24 | ||
25 | #define PDEBUG(level, fmt, args...) \ | 25 | #define PDEBUG(level, fmt, args...) \ |
26 | if (ovcamchip_debug >= (level)) pr_debug("[%s:%d] " fmt "\n", \ | 26 | if (ovcamchip_debug >= (level)) pr_debug("[%s:%d] " fmt "\n", \ |
27 | __FUNCTION__, __LINE__ , ## args) | 27 | __func__, __LINE__ , ## args) |
28 | 28 | ||
29 | #define DDEBUG(level, dev, fmt, args...) \ | 29 | #define DDEBUG(level, dev, fmt, args...) \ |
30 | if (ovcamchip_debug >= (level)) dev_dbg(dev, "[%s:%d] " fmt "\n", \ | 30 | if (ovcamchip_debug >= (level)) dev_dbg(dev, "[%s:%d] " fmt "\n", \ |
31 | __FUNCTION__, __LINE__ , ## args) | 31 | __func__, __LINE__ , ## args) |
32 | 32 | ||
33 | /* Number of times to retry chip detection. Increase this if you are getting | 33 | /* Number of times to retry chip detection. Increase this if you are getting |
34 | * "Failed to init camera chip" */ | 34 | * "Failed to init camera chip" */ |
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 6820c2aabd30..51b1461d8fb6 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
@@ -57,11 +57,11 @@ struct i2c_info | |||
57 | u8 hits; | 57 | u8 hits; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | static int i2c_count = 0; | 60 | static int i2c_count; |
61 | static struct i2c_info i2cinfo[64]; | 61 | static struct i2c_info i2cinfo[64]; |
62 | 62 | ||
63 | static int decoder = PHILIPS2; | 63 | static int decoder = PHILIPS2; |
64 | static int standard = 0; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */ | 64 | static int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */ |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * I/O ports and Shared Memory | 67 | * I/O ports and Shared Memory |
@@ -885,7 +885,9 @@ static const struct file_operations pms_fops = { | |||
885 | .open = video_exclusive_open, | 885 | .open = video_exclusive_open, |
886 | .release = video_exclusive_release, | 886 | .release = video_exclusive_release, |
887 | .ioctl = pms_ioctl, | 887 | .ioctl = pms_ioctl, |
888 | #ifdef CONFIG_COMPAT | ||
888 | .compat_ioctl = v4l_compat_ioctl32, | 889 | .compat_ioctl = v4l_compat_ioctl32, |
890 | #endif | ||
889 | .read = pms_read, | 891 | .read = pms_read, |
890 | .llseek = no_llseek, | 892 | .llseek = no_llseek, |
891 | }; | 893 | }; |
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig index 6fc1b8be1a1f..a8da90f69dd9 100644 --- a/drivers/media/video/pvrusb2/Kconfig +++ b/drivers/media/video/pvrusb2/Kconfig | |||
@@ -58,6 +58,30 @@ config VIDEO_PVRUSB2_SYSFS | |||
58 | 58 | ||
59 | Note: This feature is experimental and subject to change. | 59 | Note: This feature is experimental and subject to change. |
60 | 60 | ||
61 | config VIDEO_PVRUSB2_DVB | ||
62 | bool "pvrusb2 DVB support (EXPERIMENTAL)" | ||
63 | default n | ||
64 | depends on VIDEO_PVRUSB2 && DVB_CORE && EXPERIMENTAL | ||
65 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | ||
66 | select DVB_S5H1409 if !DVB_FE_CUSTOMISE | ||
67 | select DVB_TDA10048 if !DVB_FE_CUSTOMIZE | ||
68 | select DVB_TDA18271 if !DVB_FE_CUSTOMIZE | ||
69 | select TUNER_SIMPLE if !DVB_FE_CUSTOMISE | ||
70 | select TUNER_TDA8290 if !DVB_FE_CUSTOMIZE | ||
71 | ---help--- | ||
72 | |||
73 | This option enables compilation of a DVB interface for the | ||
74 | pvrusb2 driver. Currently this is very very experimental. | ||
75 | It is also limiting - the DVB interface can only access the | ||
76 | digital side of hybrid devices, and there are going to be | ||
77 | issues if you attempt to mess with the V4L side at the same | ||
78 | time. Don't turn this on unless you know what you are | ||
79 | doing. | ||
80 | |||
81 | If you are in doubt, say N. | ||
82 | |||
83 | Note: This feature is very experimental and might break | ||
84 | |||
61 | config VIDEO_PVRUSB2_DEBUGIFC | 85 | config VIDEO_PVRUSB2_DEBUGIFC |
62 | bool "pvrusb2 debug interface" | 86 | bool "pvrusb2 debug interface" |
63 | depends on VIDEO_PVRUSB2_SYSFS | 87 | depends on VIDEO_PVRUSB2_SYSFS |
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile index 47284e558648..5b3083c89aa9 100644 --- a/drivers/media/video/pvrusb2/Makefile +++ b/drivers/media/video/pvrusb2/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o | 1 | obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o |
2 | obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o | 2 | obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o |
3 | obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o | ||
3 | 4 | ||
4 | pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ | 5 | pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ |
5 | pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \ | 6 | pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \ |
@@ -9,6 +10,11 @@ pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ | |||
9 | pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \ | 10 | pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \ |
10 | pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \ | 11 | pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \ |
11 | pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \ | 12 | pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \ |
13 | $(obj-pvrusb2-dvb-y) \ | ||
12 | $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y) | 14 | $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y) |
13 | 15 | ||
14 | obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o | 16 | obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o |
17 | |||
18 | EXTRA_CFLAGS += -Idrivers/media/video | ||
19 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | ||
20 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c index 160437b21e6d..b5db6a5bab31 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-context.c +++ b/drivers/media/video/pvrusb2/pvrusb2-context.c | |||
@@ -23,39 +23,193 @@ | |||
23 | #include "pvrusb2-ioread.h" | 23 | #include "pvrusb2-ioread.h" |
24 | #include "pvrusb2-hdw.h" | 24 | #include "pvrusb2-hdw.h" |
25 | #include "pvrusb2-debug.h" | 25 | #include "pvrusb2-debug.h" |
26 | #include <linux/wait.h> | ||
27 | #include <linux/kthread.h> | ||
26 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
27 | #include <linux/string.h> | 29 | #include <linux/string.h> |
28 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
29 | 31 | ||
32 | static struct pvr2_context *pvr2_context_exist_first; | ||
33 | static struct pvr2_context *pvr2_context_exist_last; | ||
34 | static struct pvr2_context *pvr2_context_notify_first; | ||
35 | static struct pvr2_context *pvr2_context_notify_last; | ||
36 | static DEFINE_MUTEX(pvr2_context_mutex); | ||
37 | static DECLARE_WAIT_QUEUE_HEAD(pvr2_context_sync_data); | ||
38 | static DECLARE_WAIT_QUEUE_HEAD(pvr2_context_cleanup_data); | ||
39 | static int pvr2_context_cleanup_flag; | ||
40 | static int pvr2_context_cleaned_flag; | ||
41 | static struct task_struct *pvr2_context_thread_ptr; | ||
42 | |||
43 | |||
44 | static void pvr2_context_set_notify(struct pvr2_context *mp, int fl) | ||
45 | { | ||
46 | int signal_flag = 0; | ||
47 | mutex_lock(&pvr2_context_mutex); | ||
48 | if (fl) { | ||
49 | if (!mp->notify_flag) { | ||
50 | signal_flag = (pvr2_context_notify_first == NULL); | ||
51 | mp->notify_prev = pvr2_context_notify_last; | ||
52 | mp->notify_next = NULL; | ||
53 | pvr2_context_notify_last = mp; | ||
54 | if (mp->notify_prev) { | ||
55 | mp->notify_prev->notify_next = mp; | ||
56 | } else { | ||
57 | pvr2_context_notify_first = mp; | ||
58 | } | ||
59 | mp->notify_flag = !0; | ||
60 | } | ||
61 | } else { | ||
62 | if (mp->notify_flag) { | ||
63 | mp->notify_flag = 0; | ||
64 | if (mp->notify_next) { | ||
65 | mp->notify_next->notify_prev = mp->notify_prev; | ||
66 | } else { | ||
67 | pvr2_context_notify_last = mp->notify_prev; | ||
68 | } | ||
69 | if (mp->notify_prev) { | ||
70 | mp->notify_prev->notify_next = mp->notify_next; | ||
71 | } else { | ||
72 | pvr2_context_notify_first = mp->notify_next; | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | mutex_unlock(&pvr2_context_mutex); | ||
77 | if (signal_flag) wake_up(&pvr2_context_sync_data); | ||
78 | } | ||
79 | |||
30 | 80 | ||
31 | static void pvr2_context_destroy(struct pvr2_context *mp) | 81 | static void pvr2_context_destroy(struct pvr2_context *mp) |
32 | { | 82 | { |
33 | pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr_main id=%p",mp); | 83 | pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (destroy)",mp); |
34 | if (mp->hdw) pvr2_hdw_destroy(mp->hdw); | 84 | if (mp->hdw) pvr2_hdw_destroy(mp->hdw); |
85 | pvr2_context_set_notify(mp, 0); | ||
86 | mutex_lock(&pvr2_context_mutex); | ||
87 | if (mp->exist_next) { | ||
88 | mp->exist_next->exist_prev = mp->exist_prev; | ||
89 | } else { | ||
90 | pvr2_context_exist_last = mp->exist_prev; | ||
91 | } | ||
92 | if (mp->exist_prev) { | ||
93 | mp->exist_prev->exist_next = mp->exist_next; | ||
94 | } else { | ||
95 | pvr2_context_exist_first = mp->exist_next; | ||
96 | } | ||
97 | if (!pvr2_context_exist_first) { | ||
98 | /* Trigger wakeup on control thread in case it is waiting | ||
99 | for an exit condition. */ | ||
100 | wake_up(&pvr2_context_sync_data); | ||
101 | } | ||
102 | mutex_unlock(&pvr2_context_mutex); | ||
35 | kfree(mp); | 103 | kfree(mp); |
36 | } | 104 | } |
37 | 105 | ||
38 | 106 | ||
39 | static void pvr2_context_state_check(struct pvr2_context *mp) | 107 | static void pvr2_context_notify(struct pvr2_context *mp) |
40 | { | 108 | { |
41 | if (mp->init_flag) return; | 109 | pvr2_context_set_notify(mp,!0); |
110 | } | ||
111 | |||
42 | 112 | ||
43 | switch (pvr2_hdw_get_state(mp->hdw)) { | 113 | static void pvr2_context_check(struct pvr2_context *mp) |
44 | case PVR2_STATE_WARM: break; | 114 | { |
45 | case PVR2_STATE_ERROR: break; | 115 | struct pvr2_channel *ch1, *ch2; |
46 | case PVR2_STATE_READY: break; | 116 | pvr2_trace(PVR2_TRACE_CTXT, |
47 | case PVR2_STATE_RUN: break; | 117 | "pvr2_context %p (notify)", mp); |
48 | default: return; | 118 | if (!mp->initialized_flag && !mp->disconnect_flag) { |
119 | mp->initialized_flag = !0; | ||
120 | pvr2_trace(PVR2_TRACE_CTXT, | ||
121 | "pvr2_context %p (initialize)", mp); | ||
122 | /* Finish hardware initialization */ | ||
123 | if (pvr2_hdw_initialize(mp->hdw, | ||
124 | (void (*)(void *))pvr2_context_notify, | ||
125 | mp)) { | ||
126 | mp->video_stream.stream = | ||
127 | pvr2_hdw_get_video_stream(mp->hdw); | ||
128 | /* Trigger interface initialization. By doing this | ||
129 | here initialization runs in our own safe and | ||
130 | cozy thread context. */ | ||
131 | if (mp->setup_func) mp->setup_func(mp); | ||
132 | } else { | ||
133 | pvr2_trace(PVR2_TRACE_CTXT, | ||
134 | "pvr2_context %p (thread skipping setup)", | ||
135 | mp); | ||
136 | /* Even though initialization did not succeed, | ||
137 | we're still going to continue anyway. We need | ||
138 | to do this in order to await the expected | ||
139 | disconnect (which we will detect in the normal | ||
140 | course of operation). */ | ||
141 | } | ||
49 | } | 142 | } |
50 | 143 | ||
51 | pvr2_context_enter(mp); do { | 144 | for (ch1 = mp->mc_first; ch1; ch1 = ch2) { |
52 | mp->init_flag = !0; | 145 | ch2 = ch1->mc_next; |
53 | mp->video_stream.stream = pvr2_hdw_get_video_stream(mp->hdw); | 146 | if (ch1->check_func) ch1->check_func(ch1); |
54 | if (mp->setup_func) { | 147 | } |
55 | mp->setup_func(mp); | 148 | |
149 | if (mp->disconnect_flag && !mp->mc_first) { | ||
150 | /* Go away... */ | ||
151 | pvr2_context_destroy(mp); | ||
152 | return; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | |||
157 | static int pvr2_context_shutok(void) | ||
158 | { | ||
159 | return pvr2_context_cleanup_flag && (pvr2_context_exist_first == NULL); | ||
160 | } | ||
161 | |||
162 | |||
163 | static int pvr2_context_thread_func(void *foo) | ||
164 | { | ||
165 | struct pvr2_context *mp; | ||
166 | |||
167 | pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread start"); | ||
168 | |||
169 | do { | ||
170 | while ((mp = pvr2_context_notify_first) != NULL) { | ||
171 | pvr2_context_set_notify(mp, 0); | ||
172 | pvr2_context_check(mp); | ||
56 | } | 173 | } |
57 | } while (0); pvr2_context_exit(mp); | 174 | wait_event_interruptible( |
58 | } | 175 | pvr2_context_sync_data, |
176 | ((pvr2_context_notify_first != NULL) || | ||
177 | pvr2_context_shutok())); | ||
178 | } while (!pvr2_context_shutok()); | ||
179 | |||
180 | pvr2_context_cleaned_flag = !0; | ||
181 | wake_up(&pvr2_context_cleanup_data); | ||
182 | |||
183 | pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread cleaned up"); | ||
184 | |||
185 | wait_event_interruptible( | ||
186 | pvr2_context_sync_data, | ||
187 | kthread_should_stop()); | ||
188 | |||
189 | pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread end"); | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | |||
195 | int pvr2_context_global_init(void) | ||
196 | { | ||
197 | pvr2_context_thread_ptr = kthread_run(pvr2_context_thread_func, | ||
198 | 0, | ||
199 | "pvrusb2-context"); | ||
200 | return (pvr2_context_thread_ptr ? 0 : -ENOMEM); | ||
201 | } | ||
202 | |||
203 | |||
204 | void pvr2_context_global_done(void) | ||
205 | { | ||
206 | pvr2_context_cleanup_flag = !0; | ||
207 | wake_up(&pvr2_context_sync_data); | ||
208 | wait_event_interruptible( | ||
209 | pvr2_context_cleanup_data, | ||
210 | pvr2_context_cleaned_flag); | ||
211 | kthread_stop(pvr2_context_thread_ptr); | ||
212 | } | ||
59 | 213 | ||
60 | 214 | ||
61 | struct pvr2_context *pvr2_context_create( | 215 | struct pvr2_context *pvr2_context_create( |
@@ -66,67 +220,75 @@ struct pvr2_context *pvr2_context_create( | |||
66 | struct pvr2_context *mp = NULL; | 220 | struct pvr2_context *mp = NULL; |
67 | mp = kzalloc(sizeof(*mp),GFP_KERNEL); | 221 | mp = kzalloc(sizeof(*mp),GFP_KERNEL); |
68 | if (!mp) goto done; | 222 | if (!mp) goto done; |
69 | pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_main id=%p",mp); | 223 | pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (create)",mp); |
70 | mp->setup_func = setup_func; | 224 | mp->setup_func = setup_func; |
71 | mutex_init(&mp->mutex); | 225 | mutex_init(&mp->mutex); |
226 | mutex_lock(&pvr2_context_mutex); | ||
227 | mp->exist_prev = pvr2_context_exist_last; | ||
228 | mp->exist_next = NULL; | ||
229 | pvr2_context_exist_last = mp; | ||
230 | if (mp->exist_prev) { | ||
231 | mp->exist_prev->exist_next = mp; | ||
232 | } else { | ||
233 | pvr2_context_exist_first = mp; | ||
234 | } | ||
235 | mutex_unlock(&pvr2_context_mutex); | ||
72 | mp->hdw = pvr2_hdw_create(intf,devid); | 236 | mp->hdw = pvr2_hdw_create(intf,devid); |
73 | if (!mp->hdw) { | 237 | if (!mp->hdw) { |
74 | pvr2_context_destroy(mp); | 238 | pvr2_context_destroy(mp); |
75 | mp = NULL; | 239 | mp = NULL; |
76 | goto done; | 240 | goto done; |
77 | } | 241 | } |
78 | pvr2_hdw_set_state_callback(mp->hdw, | 242 | pvr2_context_set_notify(mp, !0); |
79 | (void (*)(void *))pvr2_context_state_check, | ||
80 | mp); | ||
81 | pvr2_context_state_check(mp); | ||
82 | done: | 243 | done: |
83 | return mp; | 244 | return mp; |
84 | } | 245 | } |
85 | 246 | ||
86 | 247 | ||
87 | void pvr2_context_enter(struct pvr2_context *mp) | 248 | static void pvr2_context_reset_input_limits(struct pvr2_context *mp) |
249 | { | ||
250 | unsigned int tmsk,mmsk; | ||
251 | struct pvr2_channel *cp; | ||
252 | struct pvr2_hdw *hdw = mp->hdw; | ||
253 | mmsk = pvr2_hdw_get_input_available(hdw); | ||
254 | tmsk = mmsk; | ||
255 | for (cp = mp->mc_first; cp; cp = cp->mc_next) { | ||
256 | if (!cp->input_mask) continue; | ||
257 | tmsk &= cp->input_mask; | ||
258 | } | ||
259 | pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk); | ||
260 | pvr2_hdw_commit_ctl(hdw); | ||
261 | } | ||
262 | |||
263 | |||
264 | static void pvr2_context_enter(struct pvr2_context *mp) | ||
88 | { | 265 | { |
89 | mutex_lock(&mp->mutex); | 266 | mutex_lock(&mp->mutex); |
90 | pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_enter(id=%p)",mp); | ||
91 | } | 267 | } |
92 | 268 | ||
93 | 269 | ||
94 | void pvr2_context_exit(struct pvr2_context *mp) | 270 | static void pvr2_context_exit(struct pvr2_context *mp) |
95 | { | 271 | { |
96 | int destroy_flag = 0; | 272 | int destroy_flag = 0; |
97 | if (!(mp->mc_first || !mp->disconnect_flag)) { | 273 | if (!(mp->mc_first || !mp->disconnect_flag)) { |
98 | destroy_flag = !0; | 274 | destroy_flag = !0; |
99 | } | 275 | } |
100 | pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_exit(id=%p) outside",mp); | ||
101 | mutex_unlock(&mp->mutex); | 276 | mutex_unlock(&mp->mutex); |
102 | if (destroy_flag) pvr2_context_destroy(mp); | 277 | if (destroy_flag) pvr2_context_notify(mp); |
103 | } | ||
104 | |||
105 | |||
106 | static void pvr2_context_run_checks(struct pvr2_context *mp) | ||
107 | { | ||
108 | struct pvr2_channel *ch1,*ch2; | ||
109 | for (ch1 = mp->mc_first; ch1; ch1 = ch2) { | ||
110 | ch2 = ch1->mc_next; | ||
111 | if (ch1->check_func) { | ||
112 | ch1->check_func(ch1); | ||
113 | } | ||
114 | } | ||
115 | } | 278 | } |
116 | 279 | ||
117 | 280 | ||
118 | void pvr2_context_disconnect(struct pvr2_context *mp) | 281 | void pvr2_context_disconnect(struct pvr2_context *mp) |
119 | { | 282 | { |
120 | pvr2_context_enter(mp); do { | 283 | pvr2_hdw_disconnect(mp->hdw); |
121 | pvr2_hdw_disconnect(mp->hdw); | 284 | mp->disconnect_flag = !0; |
122 | mp->disconnect_flag = !0; | 285 | pvr2_context_notify(mp); |
123 | pvr2_context_run_checks(mp); | ||
124 | } while (0); pvr2_context_exit(mp); | ||
125 | } | 286 | } |
126 | 287 | ||
127 | 288 | ||
128 | void pvr2_channel_init(struct pvr2_channel *cp,struct pvr2_context *mp) | 289 | void pvr2_channel_init(struct pvr2_channel *cp,struct pvr2_context *mp) |
129 | { | 290 | { |
291 | pvr2_context_enter(mp); | ||
130 | cp->hdw = mp->hdw; | 292 | cp->hdw = mp->hdw; |
131 | cp->mc_head = mp; | 293 | cp->mc_head = mp; |
132 | cp->mc_next = NULL; | 294 | cp->mc_next = NULL; |
@@ -137,6 +299,7 @@ void pvr2_channel_init(struct pvr2_channel *cp,struct pvr2_context *mp) | |||
137 | mp->mc_first = cp; | 299 | mp->mc_first = cp; |
138 | } | 300 | } |
139 | mp->mc_last = cp; | 301 | mp->mc_last = cp; |
302 | pvr2_context_exit(mp); | ||
140 | } | 303 | } |
141 | 304 | ||
142 | 305 | ||
@@ -152,7 +315,10 @@ static void pvr2_channel_disclaim_stream(struct pvr2_channel *cp) | |||
152 | void pvr2_channel_done(struct pvr2_channel *cp) | 315 | void pvr2_channel_done(struct pvr2_channel *cp) |
153 | { | 316 | { |
154 | struct pvr2_context *mp = cp->mc_head; | 317 | struct pvr2_context *mp = cp->mc_head; |
318 | pvr2_context_enter(mp); | ||
319 | cp->input_mask = 0; | ||
155 | pvr2_channel_disclaim_stream(cp); | 320 | pvr2_channel_disclaim_stream(cp); |
321 | pvr2_context_reset_input_limits(mp); | ||
156 | if (cp->mc_next) { | 322 | if (cp->mc_next) { |
157 | cp->mc_next->mc_prev = cp->mc_prev; | 323 | cp->mc_next->mc_prev = cp->mc_prev; |
158 | } else { | 324 | } else { |
@@ -164,6 +330,58 @@ void pvr2_channel_done(struct pvr2_channel *cp) | |||
164 | mp->mc_first = cp->mc_next; | 330 | mp->mc_first = cp->mc_next; |
165 | } | 331 | } |
166 | cp->hdw = NULL; | 332 | cp->hdw = NULL; |
333 | pvr2_context_exit(mp); | ||
334 | } | ||
335 | |||
336 | |||
337 | int pvr2_channel_limit_inputs(struct pvr2_channel *cp,unsigned int cmsk) | ||
338 | { | ||
339 | unsigned int tmsk,mmsk; | ||
340 | int ret = 0; | ||
341 | struct pvr2_channel *p2; | ||
342 | struct pvr2_hdw *hdw = cp->hdw; | ||
343 | |||
344 | mmsk = pvr2_hdw_get_input_available(hdw); | ||
345 | cmsk &= mmsk; | ||
346 | if (cmsk == cp->input_mask) { | ||
347 | /* No change; nothing to do */ | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | pvr2_context_enter(cp->mc_head); | ||
352 | do { | ||
353 | if (!cmsk) { | ||
354 | cp->input_mask = 0; | ||
355 | pvr2_context_reset_input_limits(cp->mc_head); | ||
356 | break; | ||
357 | } | ||
358 | tmsk = mmsk; | ||
359 | for (p2 = cp->mc_head->mc_first; p2; p2 = p2->mc_next) { | ||
360 | if (p2 == cp) continue; | ||
361 | if (!p2->input_mask) continue; | ||
362 | tmsk &= p2->input_mask; | ||
363 | } | ||
364 | if (!(tmsk & cmsk)) { | ||
365 | ret = -EPERM; | ||
366 | break; | ||
367 | } | ||
368 | tmsk &= cmsk; | ||
369 | if ((ret = pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk)) != 0) { | ||
370 | /* Internal failure changing allowed list; probably | ||
371 | should not happen, but react if it does. */ | ||
372 | break; | ||
373 | } | ||
374 | cp->input_mask = cmsk; | ||
375 | pvr2_hdw_commit_ctl(hdw); | ||
376 | } while (0); | ||
377 | pvr2_context_exit(cp->mc_head); | ||
378 | return ret; | ||
379 | } | ||
380 | |||
381 | |||
382 | unsigned int pvr2_channel_get_limited_inputs(struct pvr2_channel *cp) | ||
383 | { | ||
384 | return cp->input_mask; | ||
167 | } | 385 | } |
168 | 386 | ||
169 | 387 | ||
@@ -173,7 +391,7 @@ int pvr2_channel_claim_stream(struct pvr2_channel *cp, | |||
173 | int code = 0; | 391 | int code = 0; |
174 | pvr2_context_enter(cp->mc_head); do { | 392 | pvr2_context_enter(cp->mc_head); do { |
175 | if (sp == cp->stream) break; | 393 | if (sp == cp->stream) break; |
176 | if (sp->user) { | 394 | if (sp && sp->user) { |
177 | code = -EBUSY; | 395 | code = -EBUSY; |
178 | break; | 396 | break; |
179 | } | 397 | } |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h index a04187a93225..745e270233c2 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-context.h +++ b/drivers/media/video/pvrusb2/pvrusb2-context.h | |||
@@ -30,7 +30,6 @@ struct pvr2_stream; /* stream interface - defined elsewhere */ | |||
30 | struct pvr2_context; /* All central state */ | 30 | struct pvr2_context; /* All central state */ |
31 | struct pvr2_channel; /* One I/O pathway to a user */ | 31 | struct pvr2_channel; /* One I/O pathway to a user */ |
32 | struct pvr2_context_stream; /* Wrapper for a stream */ | 32 | struct pvr2_context_stream; /* Wrapper for a stream */ |
33 | struct pvr2_crit_reg; /* Critical region pointer */ | ||
34 | struct pvr2_ioread; /* Low level stream structure */ | 33 | struct pvr2_ioread; /* Low level stream structure */ |
35 | 34 | ||
36 | struct pvr2_context_stream { | 35 | struct pvr2_context_stream { |
@@ -41,11 +40,16 @@ struct pvr2_context_stream { | |||
41 | struct pvr2_context { | 40 | struct pvr2_context { |
42 | struct pvr2_channel *mc_first; | 41 | struct pvr2_channel *mc_first; |
43 | struct pvr2_channel *mc_last; | 42 | struct pvr2_channel *mc_last; |
43 | struct pvr2_context *exist_next; | ||
44 | struct pvr2_context *exist_prev; | ||
45 | struct pvr2_context *notify_next; | ||
46 | struct pvr2_context *notify_prev; | ||
44 | struct pvr2_hdw *hdw; | 47 | struct pvr2_hdw *hdw; |
45 | struct pvr2_context_stream video_stream; | 48 | struct pvr2_context_stream video_stream; |
46 | struct mutex mutex; | 49 | struct mutex mutex; |
50 | int notify_flag; | ||
51 | int initialized_flag; | ||
47 | int disconnect_flag; | 52 | int disconnect_flag; |
48 | int init_flag; | ||
49 | 53 | ||
50 | /* Called after pvr2_context initialization is complete */ | 54 | /* Called after pvr2_context initialization is complete */ |
51 | void (*setup_func)(struct pvr2_context *); | 55 | void (*setup_func)(struct pvr2_context *); |
@@ -58,12 +62,10 @@ struct pvr2_channel { | |||
58 | struct pvr2_channel *mc_prev; | 62 | struct pvr2_channel *mc_prev; |
59 | struct pvr2_context_stream *stream; | 63 | struct pvr2_context_stream *stream; |
60 | struct pvr2_hdw *hdw; | 64 | struct pvr2_hdw *hdw; |
65 | unsigned int input_mask; | ||
61 | void (*check_func)(struct pvr2_channel *); | 66 | void (*check_func)(struct pvr2_channel *); |
62 | }; | 67 | }; |
63 | 68 | ||
64 | void pvr2_context_enter(struct pvr2_context *); | ||
65 | void pvr2_context_exit(struct pvr2_context *); | ||
66 | |||
67 | struct pvr2_context *pvr2_context_create(struct usb_interface *intf, | 69 | struct pvr2_context *pvr2_context_create(struct usb_interface *intf, |
68 | const struct usb_device_id *devid, | 70 | const struct usb_device_id *devid, |
69 | void (*setup_func)(struct pvr2_context *)); | 71 | void (*setup_func)(struct pvr2_context *)); |
@@ -71,11 +73,15 @@ void pvr2_context_disconnect(struct pvr2_context *); | |||
71 | 73 | ||
72 | void pvr2_channel_init(struct pvr2_channel *,struct pvr2_context *); | 74 | void pvr2_channel_init(struct pvr2_channel *,struct pvr2_context *); |
73 | void pvr2_channel_done(struct pvr2_channel *); | 75 | void pvr2_channel_done(struct pvr2_channel *); |
76 | int pvr2_channel_limit_inputs(struct pvr2_channel *,unsigned int); | ||
77 | unsigned int pvr2_channel_get_limited_inputs(struct pvr2_channel *); | ||
74 | int pvr2_channel_claim_stream(struct pvr2_channel *, | 78 | int pvr2_channel_claim_stream(struct pvr2_channel *, |
75 | struct pvr2_context_stream *); | 79 | struct pvr2_context_stream *); |
76 | struct pvr2_ioread *pvr2_channel_create_mpeg_stream( | 80 | struct pvr2_ioread *pvr2_channel_create_mpeg_stream( |
77 | struct pvr2_context_stream *); | 81 | struct pvr2_context_stream *); |
78 | 82 | ||
83 | int pvr2_context_global_init(void); | ||
84 | void pvr2_context_global_done(void); | ||
79 | 85 | ||
80 | #endif /* __PVRUSB2_CONTEXT_H */ | 86 | #endif /* __PVRUSB2_CONTEXT_H */ |
81 | /* | 87 | /* |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c index 5a3e8d21a38a..91a42f2473a7 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c | |||
@@ -30,6 +30,9 @@ static int pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val) | |||
30 | { | 30 | { |
31 | if (cptr->info->check_value) { | 31 | if (cptr->info->check_value) { |
32 | if (!cptr->info->check_value(cptr,val)) return -ERANGE; | 32 | if (!cptr->info->check_value(cptr,val)) return -ERANGE; |
33 | } else if (cptr->info->type == pvr2_ctl_enum) { | ||
34 | if (val < 0) return -ERANGE; | ||
35 | if (val >= cptr->info->def.type_enum.count) return -ERANGE; | ||
33 | } else { | 36 | } else { |
34 | int lim; | 37 | int lim; |
35 | lim = cptr->info->def.type_int.min_value; | 38 | lim = cptr->info->def.type_int.min_value; |
@@ -63,13 +66,10 @@ int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val) | |||
63 | if (cptr->info->set_value) { | 66 | if (cptr->info->set_value) { |
64 | if (cptr->info->type == pvr2_ctl_bitmask) { | 67 | if (cptr->info->type == pvr2_ctl_bitmask) { |
65 | mask &= cptr->info->def.type_bitmask.valid_bits; | 68 | mask &= cptr->info->def.type_bitmask.valid_bits; |
66 | } else if (cptr->info->type == pvr2_ctl_int) { | 69 | } else if ((cptr->info->type == pvr2_ctl_int)|| |
70 | (cptr->info->type == pvr2_ctl_enum)) { | ||
67 | ret = pvr2_ctrl_range_check(cptr,val); | 71 | ret = pvr2_ctrl_range_check(cptr,val); |
68 | if (ret < 0) break; | 72 | if (ret < 0) break; |
69 | } else if (cptr->info->type == pvr2_ctl_enum) { | ||
70 | if (val >= cptr->info->def.type_enum.count) { | ||
71 | break; | ||
72 | } | ||
73 | } else if (cptr->info->type != pvr2_ctl_bool) { | 73 | } else if (cptr->info->type != pvr2_ctl_bool) { |
74 | break; | 74 | break; |
75 | } | 75 | } |
@@ -204,8 +204,7 @@ int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val, | |||
204 | if (cptr->info->type == pvr2_ctl_enum) { | 204 | if (cptr->info->type == pvr2_ctl_enum) { |
205 | const char **names; | 205 | const char **names; |
206 | names = cptr->info->def.type_enum.value_names; | 206 | names = cptr->info->def.type_enum.value_names; |
207 | if ((val >= 0) && | 207 | if (pvr2_ctrl_range_check(cptr,val) == 0) { |
208 | (val < cptr->info->def.type_enum.count)) { | ||
209 | if (names[val]) { | 208 | if (names[val]) { |
210 | *blen = scnprintf( | 209 | *blen = scnprintf( |
211 | bptr,bmax,"%s", | 210 | bptr,bmax,"%s", |
@@ -528,10 +527,8 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, | |||
528 | ptr,len,valptr, | 527 | ptr,len,valptr, |
529 | cptr->info->def.type_enum.value_names, | 528 | cptr->info->def.type_enum.value_names, |
530 | cptr->info->def.type_enum.count); | 529 | cptr->info->def.type_enum.count); |
531 | if ((ret >= 0) && | 530 | if (ret >= 0) { |
532 | ((*valptr < 0) || | 531 | ret = pvr2_ctrl_range_check(cptr,*valptr); |
533 | (*valptr >= cptr->info->def.type_enum.count))) { | ||
534 | ret = -ERANGE; | ||
535 | } | 532 | } |
536 | if (maskptr) *maskptr = ~0; | 533 | if (maskptr) *maskptr = ~0; |
537 | } else if (cptr->info->type == pvr2_ctl_bitmask) { | 534 | } else if (cptr->info->type == pvr2_ctl_bitmask) { |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c index ffdc45c324e5..97350b048b8d 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | |||
@@ -84,7 +84,9 @@ static const struct routing_scheme_item routing_schemegv[] = { | |||
84 | .vid = CX25840_COMPOSITE2, | 84 | .vid = CX25840_COMPOSITE2, |
85 | .aud = CX25840_AUDIO5, | 85 | .aud = CX25840_AUDIO5, |
86 | }, | 86 | }, |
87 | [PVR2_CVAL_INPUT_RADIO] = { /* Treat the same as composite */ | 87 | [PVR2_CVAL_INPUT_RADIO] = { |
88 | /* line-in is used for radio and composite. A GPIO is | ||
89 | used to switch between the two choices. */ | ||
88 | .vid = CX25840_COMPOSITE1, | 90 | .vid = CX25840_COMPOSITE1, |
89 | .aud = CX25840_AUDIO_SERIAL, | 91 | .aud = CX25840_AUDIO_SERIAL, |
90 | }, | 92 | }, |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/video/pvrusb2/pvrusb2-debug.h index fca49d8a9311..11537ddf8aa3 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-debug.h +++ b/drivers/media/video/pvrusb2/pvrusb2-debug.h | |||
@@ -39,7 +39,7 @@ extern int pvrusb2_debug; | |||
39 | #define PVR2_TRACE_EEPROM (1 << 10) /* eeprom parsing / report */ | 39 | #define PVR2_TRACE_EEPROM (1 << 10) /* eeprom parsing / report */ |
40 | #define PVR2_TRACE_STRUCT (1 << 11) /* internal struct creation */ | 40 | #define PVR2_TRACE_STRUCT (1 << 11) /* internal struct creation */ |
41 | #define PVR2_TRACE_OPEN_CLOSE (1 << 12) /* application open / close */ | 41 | #define PVR2_TRACE_OPEN_CLOSE (1 << 12) /* application open / close */ |
42 | #define PVR2_TRACE_CREG (1 << 13) /* Main critical region entry / exit */ | 42 | #define PVR2_TRACE_CTXT (1 << 13) /* Main context tracking */ |
43 | #define PVR2_TRACE_SYSFS (1 << 14) /* Sysfs driven I/O */ | 43 | #define PVR2_TRACE_SYSFS (1 << 14) /* Sysfs driven I/O */ |
44 | #define PVR2_TRACE_FIRMWARE (1 << 15) /* firmware upload actions */ | 44 | #define PVR2_TRACE_FIRMWARE (1 << 15) /* firmware upload actions */ |
45 | #define PVR2_TRACE_CHIPS (1 << 16) /* chip broadcast operation */ | 45 | #define PVR2_TRACE_CHIPS (1 << 16) /* chip broadcast operation */ |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c index b0687430fdd4..b53121c78ff9 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c | |||
@@ -164,6 +164,8 @@ int pvr2_debugifc_print_status(struct pvr2_hdw *hdw, | |||
164 | int ccnt; | 164 | int ccnt; |
165 | int ret; | 165 | int ret; |
166 | u32 gpio_dir,gpio_in,gpio_out; | 166 | u32 gpio_dir,gpio_in,gpio_out; |
167 | struct pvr2_stream_stats stats; | ||
168 | struct pvr2_stream *sp; | ||
167 | 169 | ||
168 | ret = pvr2_hdw_is_hsm(hdw); | 170 | ret = pvr2_hdw_is_hsm(hdw); |
169 | ccnt = scnprintf(buf,acnt,"USB link speed: %s\n", | 171 | ccnt = scnprintf(buf,acnt,"USB link speed: %s\n", |
@@ -182,6 +184,24 @@ int pvr2_debugifc_print_status(struct pvr2_hdw *hdw, | |||
182 | pvr2_hdw_get_streaming(hdw) ? "on" : "off"); | 184 | pvr2_hdw_get_streaming(hdw) ? "on" : "off"); |
183 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | 185 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; |
184 | 186 | ||
187 | |||
188 | sp = pvr2_hdw_get_video_stream(hdw); | ||
189 | if (sp) { | ||
190 | pvr2_stream_get_stats(sp, &stats, 0); | ||
191 | ccnt = scnprintf( | ||
192 | buf,acnt, | ||
193 | "Bytes streamed=%u" | ||
194 | " URBs: queued=%u idle=%u ready=%u" | ||
195 | " processed=%u failed=%u\n", | ||
196 | stats.bytes_processed, | ||
197 | stats.buffers_in_queue, | ||
198 | stats.buffers_in_idle, | ||
199 | stats.buffers_in_ready, | ||
200 | stats.buffers_processed, | ||
201 | stats.buffers_failed); | ||
202 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
203 | } | ||
204 | |||
185 | return bcnt; | 205 | return bcnt; |
186 | } | 206 | } |
187 | 207 | ||
@@ -220,6 +240,10 @@ static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, | |||
220 | return pvr2_hdw_cmd_decoder_reset(hdw); | 240 | return pvr2_hdw_cmd_decoder_reset(hdw); |
221 | } else if (debugifc_match_keyword(wptr,wlen,"worker")) { | 241 | } else if (debugifc_match_keyword(wptr,wlen,"worker")) { |
222 | return pvr2_hdw_untrip(hdw); | 242 | return pvr2_hdw_untrip(hdw); |
243 | } else if (debugifc_match_keyword(wptr,wlen,"usbstats")) { | ||
244 | pvr2_stream_get_stats(pvr2_hdw_get_video_stream(hdw), | ||
245 | NULL, !0); | ||
246 | return 0; | ||
223 | } | 247 | } |
224 | return -EINVAL; | 248 | return -EINVAL; |
225 | } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) { | 249 | } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) { |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index fe9991c10cf4..2dd06a90adce 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c | |||
@@ -32,7 +32,15 @@ pvr2_device_desc structures. | |||
32 | /* This is needed in order to pull in tuner type ids... */ | 32 | /* This is needed in order to pull in tuner type ids... */ |
33 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
34 | #include <media/tuner.h> | 34 | #include <media/tuner.h> |
35 | 35 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB | |
36 | #include "pvrusb2-hdw-internal.h" | ||
37 | #include "lgdt330x.h" | ||
38 | #include "s5h1409.h" | ||
39 | #include "tda10048.h" | ||
40 | #include "tda18271.h" | ||
41 | #include "tda8290.h" | ||
42 | #include "tuner-simple.h" | ||
43 | #endif | ||
36 | 44 | ||
37 | 45 | ||
38 | /*------------------------------------------------------------------------*/ | 46 | /*------------------------------------------------------------------------*/ |
@@ -49,14 +57,19 @@ static const char *pvr2_fw1_names_29xxx[] = { | |||
49 | }; | 57 | }; |
50 | 58 | ||
51 | static const struct pvr2_device_desc pvr2_device_29xxx = { | 59 | static const struct pvr2_device_desc pvr2_device_29xxx = { |
52 | .description = "WinTV PVR USB2 Model Category 29xxxx", | 60 | .description = "WinTV PVR USB2 Model Category 29xxx", |
53 | .shortname = "29xxx", | 61 | .shortname = "29xxx", |
54 | .client_modules.lst = pvr2_client_29xxx, | 62 | .client_modules.lst = pvr2_client_29xxx, |
55 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_29xxx), | 63 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_29xxx), |
56 | .fx2_firmware.lst = pvr2_fw1_names_29xxx, | 64 | .fx2_firmware.lst = pvr2_fw1_names_29xxx, |
57 | .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx), | 65 | .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx), |
58 | .flag_has_hauppauge_rom = !0, | 66 | .flag_has_hauppauge_rom = !0, |
67 | .flag_has_analogtuner = !0, | ||
68 | .flag_has_fmradio = !0, | ||
69 | .flag_has_composite = !0, | ||
70 | .flag_has_svideo = !0, | ||
59 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, | 71 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, |
72 | .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, | ||
60 | }; | 73 | }; |
61 | 74 | ||
62 | 75 | ||
@@ -75,7 +88,7 @@ static const char *pvr2_fw1_names_24xxx[] = { | |||
75 | }; | 88 | }; |
76 | 89 | ||
77 | static const struct pvr2_device_desc pvr2_device_24xxx = { | 90 | static const struct pvr2_device_desc pvr2_device_24xxx = { |
78 | .description = "WinTV PVR USB2 Model Category 24xxxx", | 91 | .description = "WinTV PVR USB2 Model Category 24xxx", |
79 | .shortname = "24xxx", | 92 | .shortname = "24xxx", |
80 | .client_modules.lst = pvr2_client_24xxx, | 93 | .client_modules.lst = pvr2_client_24xxx, |
81 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_24xxx), | 94 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_24xxx), |
@@ -85,7 +98,12 @@ static const struct pvr2_device_desc pvr2_device_24xxx = { | |||
85 | .flag_has_wm8775 = !0, | 98 | .flag_has_wm8775 = !0, |
86 | .flag_has_hauppauge_rom = !0, | 99 | .flag_has_hauppauge_rom = !0, |
87 | .flag_has_hauppauge_custom_ir = !0, | 100 | .flag_has_hauppauge_custom_ir = !0, |
101 | .flag_has_analogtuner = !0, | ||
102 | .flag_has_fmradio = !0, | ||
103 | .flag_has_composite = !0, | ||
104 | .flag_has_svideo = !0, | ||
88 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, | 105 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, |
106 | .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, | ||
89 | }; | 107 | }; |
90 | 108 | ||
91 | 109 | ||
@@ -105,6 +123,30 @@ static const struct pvr2_device_desc pvr2_device_gotview_2 = { | |||
105 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2), | 123 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2), |
106 | .flag_has_cx25840 = !0, | 124 | .flag_has_cx25840 = !0, |
107 | .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 125 | .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
126 | .flag_has_analogtuner = !0, | ||
127 | .flag_has_fmradio = !0, | ||
128 | .flag_has_composite = !0, | ||
129 | .flag_has_svideo = !0, | ||
130 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_GOTVIEW, | ||
131 | }; | ||
132 | |||
133 | |||
134 | |||
135 | /*------------------------------------------------------------------------*/ | ||
136 | /* GOTVIEW USB2.0 DVD Deluxe */ | ||
137 | |||
138 | /* (same module list as gotview_2) */ | ||
139 | |||
140 | static const struct pvr2_device_desc pvr2_device_gotview_2d = { | ||
141 | .description = "Gotview USB 2.0 DVD Deluxe", | ||
142 | .shortname = "gv2d", | ||
143 | .client_modules.lst = pvr2_client_gotview_2, | ||
144 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2), | ||
145 | .flag_has_cx25840 = !0, | ||
146 | .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
147 | .flag_has_analogtuner = !0, | ||
148 | .flag_has_composite = !0, | ||
149 | .flag_has_svideo = !0, | ||
108 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_GOTVIEW, | 150 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_GOTVIEW, |
109 | }; | 151 | }; |
110 | 152 | ||
@@ -114,6 +156,38 @@ static const struct pvr2_device_desc pvr2_device_gotview_2 = { | |||
114 | /*------------------------------------------------------------------------*/ | 156 | /*------------------------------------------------------------------------*/ |
115 | /* OnAir Creator */ | 157 | /* OnAir Creator */ |
116 | 158 | ||
159 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB | ||
160 | static struct lgdt330x_config pvr2_lgdt3303_config = { | ||
161 | .demod_address = 0x0e, | ||
162 | .demod_chip = LGDT3303, | ||
163 | .clock_polarity_flip = 1, | ||
164 | }; | ||
165 | |||
166 | static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap) | ||
167 | { | ||
168 | adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config, | ||
169 | &adap->channel.hdw->i2c_adap); | ||
170 | if (adap->fe) | ||
171 | return 0; | ||
172 | |||
173 | return -EIO; | ||
174 | } | ||
175 | |||
176 | static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap) | ||
177 | { | ||
178 | dvb_attach(simple_tuner_attach, adap->fe, | ||
179 | &adap->channel.hdw->i2c_adap, 0x61, | ||
180 | TUNER_LG_TDVS_H06XF); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | struct pvr2_dvb_props pvr2_onair_creator_fe_props = { | ||
186 | .frontend_attach = pvr2_lgdt3303_attach, | ||
187 | .tuner_attach = pvr2_lgh06xf_attach, | ||
188 | }; | ||
189 | #endif | ||
190 | |||
117 | static const char *pvr2_client_onair_creator[] = { | 191 | static const char *pvr2_client_onair_creator[] = { |
118 | "saa7115", | 192 | "saa7115", |
119 | "tuner", | 193 | "tuner", |
@@ -126,7 +200,16 @@ static const struct pvr2_device_desc pvr2_device_onair_creator = { | |||
126 | .client_modules.lst = pvr2_client_onair_creator, | 200 | .client_modules.lst = pvr2_client_onair_creator, |
127 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_creator), | 201 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_creator), |
128 | .default_tuner_type = TUNER_LG_TDVS_H06XF, | 202 | .default_tuner_type = TUNER_LG_TDVS_H06XF, |
203 | .flag_has_analogtuner = !0, | ||
204 | .flag_has_composite = !0, | ||
205 | .flag_has_svideo = !0, | ||
206 | .flag_digital_requires_cx23416 = !0, | ||
129 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, | 207 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, |
208 | .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR, | ||
209 | .default_std_mask = V4L2_STD_NTSC_M, | ||
210 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB | ||
211 | .dvb_props = &pvr2_onair_creator_fe_props, | ||
212 | #endif | ||
130 | }; | 213 | }; |
131 | #endif | 214 | #endif |
132 | 215 | ||
@@ -136,6 +219,37 @@ static const struct pvr2_device_desc pvr2_device_onair_creator = { | |||
136 | /*------------------------------------------------------------------------*/ | 219 | /*------------------------------------------------------------------------*/ |
137 | /* OnAir USB 2.0 */ | 220 | /* OnAir USB 2.0 */ |
138 | 221 | ||
222 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB | ||
223 | static struct lgdt330x_config pvr2_lgdt3302_config = { | ||
224 | .demod_address = 0x0e, | ||
225 | .demod_chip = LGDT3302, | ||
226 | }; | ||
227 | |||
228 | static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap) | ||
229 | { | ||
230 | adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config, | ||
231 | &adap->channel.hdw->i2c_adap); | ||
232 | if (adap->fe) | ||
233 | return 0; | ||
234 | |||
235 | return -EIO; | ||
236 | } | ||
237 | |||
238 | static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap) | ||
239 | { | ||
240 | dvb_attach(simple_tuner_attach, adap->fe, | ||
241 | &adap->channel.hdw->i2c_adap, 0x61, | ||
242 | TUNER_PHILIPS_FCV1236D); | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | struct pvr2_dvb_props pvr2_onair_usb2_fe_props = { | ||
248 | .frontend_attach = pvr2_lgdt3302_attach, | ||
249 | .tuner_attach = pvr2_fcv1236d_attach, | ||
250 | }; | ||
251 | #endif | ||
252 | |||
139 | static const char *pvr2_client_onair_usb2[] = { | 253 | static const char *pvr2_client_onair_usb2[] = { |
140 | "saa7115", | 254 | "saa7115", |
141 | "tuner", | 255 | "tuner", |
@@ -147,8 +261,17 @@ static const struct pvr2_device_desc pvr2_device_onair_usb2 = { | |||
147 | .shortname = "oa2", | 261 | .shortname = "oa2", |
148 | .client_modules.lst = pvr2_client_onair_usb2, | 262 | .client_modules.lst = pvr2_client_onair_usb2, |
149 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_usb2), | 263 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_usb2), |
150 | .default_tuner_type = TUNER_PHILIPS_ATSC, | 264 | .default_tuner_type = TUNER_PHILIPS_FCV1236D, |
265 | .flag_has_analogtuner = !0, | ||
266 | .flag_has_composite = !0, | ||
267 | .flag_has_svideo = !0, | ||
268 | .flag_digital_requires_cx23416 = !0, | ||
151 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, | 269 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, |
270 | .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR, | ||
271 | .default_std_mask = V4L2_STD_NTSC_M, | ||
272 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB | ||
273 | .dvb_props = &pvr2_onair_usb2_fe_props, | ||
274 | #endif | ||
152 | }; | 275 | }; |
153 | #endif | 276 | #endif |
154 | 277 | ||
@@ -157,6 +280,50 @@ static const struct pvr2_device_desc pvr2_device_onair_usb2 = { | |||
157 | /*------------------------------------------------------------------------*/ | 280 | /*------------------------------------------------------------------------*/ |
158 | /* Hauppauge PVR-USB2 Model 73xxx */ | 281 | /* Hauppauge PVR-USB2 Model 73xxx */ |
159 | 282 | ||
283 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB | ||
284 | static struct tda10048_config hauppauge_tda10048_config = { | ||
285 | .demod_address = 0x10 >> 1, | ||
286 | .output_mode = TDA10048_PARALLEL_OUTPUT, | ||
287 | .fwbulkwritelen = TDA10048_BULKWRITE_50, | ||
288 | .inversion = TDA10048_INVERSION_ON, | ||
289 | }; | ||
290 | |||
291 | static struct tda829x_config tda829x_no_probe = { | ||
292 | .probe_tuner = TDA829X_DONT_PROBE, | ||
293 | }; | ||
294 | |||
295 | static struct tda18271_config hauppauge_tda18271_dvb_config = { | ||
296 | .gate = TDA18271_GATE_ANALOG, | ||
297 | }; | ||
298 | |||
299 | static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap) | ||
300 | { | ||
301 | adap->fe = dvb_attach(tda10048_attach, &hauppauge_tda10048_config, | ||
302 | &adap->channel.hdw->i2c_adap); | ||
303 | if (adap->fe) | ||
304 | return 0; | ||
305 | |||
306 | return -EIO; | ||
307 | } | ||
308 | |||
309 | static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap) | ||
310 | { | ||
311 | dvb_attach(tda829x_attach, adap->fe, | ||
312 | &adap->channel.hdw->i2c_adap, 0x42, | ||
313 | &tda829x_no_probe); | ||
314 | dvb_attach(tda18271_attach, adap->fe, 0x60, | ||
315 | &adap->channel.hdw->i2c_adap, | ||
316 | &hauppauge_tda18271_dvb_config); | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | struct pvr2_dvb_props pvr2_73xxx_dvb_props = { | ||
322 | .frontend_attach = pvr2_tda10048_attach, | ||
323 | .tuner_attach = pvr2_73xxx_tda18271_8295_attach, | ||
324 | }; | ||
325 | #endif | ||
326 | |||
160 | static const char *pvr2_client_73xxx[] = { | 327 | static const char *pvr2_client_73xxx[] = { |
161 | "cx25840", | 328 | "cx25840", |
162 | "tuner", | 329 | "tuner", |
@@ -167,7 +334,7 @@ static const char *pvr2_fw1_names_73xxx[] = { | |||
167 | }; | 334 | }; |
168 | 335 | ||
169 | static const struct pvr2_device_desc pvr2_device_73xxx = { | 336 | static const struct pvr2_device_desc pvr2_device_73xxx = { |
170 | .description = "WinTV PVR USB2 Model Category 73xxxx", | 337 | .description = "WinTV PVR USB2 Model Category 73xxx", |
171 | .shortname = "73xxx", | 338 | .shortname = "73xxx", |
172 | .client_modules.lst = pvr2_client_73xxx, | 339 | .client_modules.lst = pvr2_client_73xxx, |
173 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_73xxx), | 340 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_73xxx), |
@@ -175,15 +342,14 @@ static const struct pvr2_device_desc pvr2_device_73xxx = { | |||
175 | .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_73xxx), | 342 | .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_73xxx), |
176 | .flag_has_cx25840 = !0, | 343 | .flag_has_cx25840 = !0, |
177 | .flag_has_hauppauge_rom = !0, | 344 | .flag_has_hauppauge_rom = !0, |
178 | #if 0 | ||
179 | .flag_has_analogtuner = !0, | 345 | .flag_has_analogtuner = !0, |
180 | .flag_has_composite = !0, | 346 | .flag_has_composite = !0, |
181 | .flag_has_svideo = !0, | 347 | .flag_has_svideo = !0, |
182 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, | 348 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, |
183 | .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, | 349 | .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, |
184 | .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, | 350 | .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, |
185 | #else | 351 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB |
186 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, | 352 | .dvb_props = &pvr2_73xxx_dvb_props, |
187 | #endif | 353 | #endif |
188 | }; | 354 | }; |
189 | 355 | ||
@@ -192,6 +358,56 @@ static const struct pvr2_device_desc pvr2_device_73xxx = { | |||
192 | /*------------------------------------------------------------------------*/ | 358 | /*------------------------------------------------------------------------*/ |
193 | /* Hauppauge PVR-USB2 Model 75xxx */ | 359 | /* Hauppauge PVR-USB2 Model 75xxx */ |
194 | 360 | ||
361 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB | ||
362 | static struct s5h1409_config pvr2_s5h1409_config = { | ||
363 | .demod_address = 0x32 >> 1, | ||
364 | .output_mode = S5H1409_PARALLEL_OUTPUT, | ||
365 | .gpio = S5H1409_GPIO_OFF, | ||
366 | .qam_if = 4000, | ||
367 | .inversion = S5H1409_INVERSION_ON, | ||
368 | .status_mode = S5H1409_DEMODLOCKING, | ||
369 | }; | ||
370 | |||
371 | static struct tda18271_std_map hauppauge_tda18271_std_map = { | ||
372 | .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, | ||
373 | .if_lvl = 6, .rfagc_top = 0x37, }, | ||
374 | .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, | ||
375 | .if_lvl = 6, .rfagc_top = 0x37, }, | ||
376 | }; | ||
377 | |||
378 | static struct tda18271_config hauppauge_tda18271_config = { | ||
379 | .std_map = &hauppauge_tda18271_std_map, | ||
380 | .gate = TDA18271_GATE_ANALOG, | ||
381 | }; | ||
382 | |||
383 | static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap) | ||
384 | { | ||
385 | adap->fe = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config, | ||
386 | &adap->channel.hdw->i2c_adap); | ||
387 | if (adap->fe) | ||
388 | return 0; | ||
389 | |||
390 | return -EIO; | ||
391 | } | ||
392 | |||
393 | static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap) | ||
394 | { | ||
395 | dvb_attach(tda829x_attach, adap->fe, | ||
396 | &adap->channel.hdw->i2c_adap, 0x42, | ||
397 | &tda829x_no_probe); | ||
398 | dvb_attach(tda18271_attach, adap->fe, 0x60, | ||
399 | &adap->channel.hdw->i2c_adap, | ||
400 | &hauppauge_tda18271_config); | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | struct pvr2_dvb_props pvr2_750xx_dvb_props = { | ||
406 | .frontend_attach = pvr2_s5h1409_attach, | ||
407 | .tuner_attach = pvr2_tda18271_8295_attach, | ||
408 | }; | ||
409 | #endif | ||
410 | |||
195 | static const char *pvr2_client_75xxx[] = { | 411 | static const char *pvr2_client_75xxx[] = { |
196 | "cx25840", | 412 | "cx25840", |
197 | "tuner", | 413 | "tuner", |
@@ -201,17 +417,43 @@ static const char *pvr2_fw1_names_75xxx[] = { | |||
201 | "v4l-pvrusb2-73xxx-01.fw", | 417 | "v4l-pvrusb2-73xxx-01.fw", |
202 | }; | 418 | }; |
203 | 419 | ||
204 | static const struct pvr2_device_desc pvr2_device_75xxx = { | 420 | static const struct pvr2_device_desc pvr2_device_750xx = { |
205 | .description = "WinTV PVR USB2 Model Category 75xxxx", | 421 | .description = "WinTV PVR USB2 Model Category 750xx", |
206 | .shortname = "75xxx", | 422 | .shortname = "750xx", |
423 | .client_modules.lst = pvr2_client_75xxx, | ||
424 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx), | ||
425 | .fx2_firmware.lst = pvr2_fw1_names_75xxx, | ||
426 | .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx), | ||
427 | .flag_has_cx25840 = !0, | ||
428 | .flag_has_hauppauge_rom = !0, | ||
429 | .flag_has_analogtuner = !0, | ||
430 | .flag_has_composite = !0, | ||
431 | .flag_has_svideo = !0, | ||
432 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, | ||
433 | .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, | ||
434 | .default_std_mask = V4L2_STD_NTSC_M, | ||
435 | .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, | ||
436 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB | ||
437 | .dvb_props = &pvr2_750xx_dvb_props, | ||
438 | #endif | ||
439 | }; | ||
440 | |||
441 | static const struct pvr2_device_desc pvr2_device_751xx = { | ||
442 | .description = "WinTV PVR USB2 Model Category 751xx", | ||
443 | .shortname = "751xx", | ||
207 | .client_modules.lst = pvr2_client_75xxx, | 444 | .client_modules.lst = pvr2_client_75xxx, |
208 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx), | 445 | .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx), |
209 | .fx2_firmware.lst = pvr2_fw1_names_75xxx, | 446 | .fx2_firmware.lst = pvr2_fw1_names_75xxx, |
210 | .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx), | 447 | .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx), |
211 | .flag_has_cx25840 = !0, | 448 | .flag_has_cx25840 = !0, |
212 | .flag_has_hauppauge_rom = !0, | 449 | .flag_has_hauppauge_rom = !0, |
450 | .flag_has_analogtuner = !0, | ||
451 | .flag_has_composite = !0, | ||
452 | .flag_has_svideo = !0, | ||
213 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, | 453 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, |
454 | .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, | ||
214 | .default_std_mask = V4L2_STD_NTSC_M, | 455 | .default_std_mask = V4L2_STD_NTSC_M, |
456 | .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, | ||
215 | }; | 457 | }; |
216 | 458 | ||
217 | 459 | ||
@@ -225,6 +467,8 @@ struct usb_device_id pvr2_device_table[] = { | |||
225 | .driver_info = (kernel_ulong_t)&pvr2_device_24xxx}, | 467 | .driver_info = (kernel_ulong_t)&pvr2_device_24xxx}, |
226 | { USB_DEVICE(0x1164, 0x0622), | 468 | { USB_DEVICE(0x1164, 0x0622), |
227 | .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2}, | 469 | .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2}, |
470 | { USB_DEVICE(0x1164, 0x0602), | ||
471 | .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2d}, | ||
228 | #ifdef CONFIG_VIDEO_PVRUSB2_ONAIR_CREATOR | 472 | #ifdef CONFIG_VIDEO_PVRUSB2_ONAIR_CREATOR |
229 | { USB_DEVICE(0x11ba, 0x1003), | 473 | { USB_DEVICE(0x11ba, 0x1003), |
230 | .driver_info = (kernel_ulong_t)&pvr2_device_onair_creator}, | 474 | .driver_info = (kernel_ulong_t)&pvr2_device_onair_creator}, |
@@ -236,9 +480,9 @@ struct usb_device_id pvr2_device_table[] = { | |||
236 | { USB_DEVICE(0x2040, 0x7300), | 480 | { USB_DEVICE(0x2040, 0x7300), |
237 | .driver_info = (kernel_ulong_t)&pvr2_device_73xxx}, | 481 | .driver_info = (kernel_ulong_t)&pvr2_device_73xxx}, |
238 | { USB_DEVICE(0x2040, 0x7500), | 482 | { USB_DEVICE(0x2040, 0x7500), |
239 | .driver_info = (kernel_ulong_t)&pvr2_device_75xxx}, | 483 | .driver_info = (kernel_ulong_t)&pvr2_device_750xx}, |
240 | { USB_DEVICE(0x2040, 0x7501), | 484 | { USB_DEVICE(0x2040, 0x7501), |
241 | .driver_info = (kernel_ulong_t)&pvr2_device_75xxx}, | 485 | .driver_info = (kernel_ulong_t)&pvr2_device_751xx}, |
242 | { } | 486 | { } |
243 | }; | 487 | }; |
244 | 488 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h index 64b467f0637f..c2e2b06fe2e0 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h | |||
@@ -23,6 +23,9 @@ | |||
23 | 23 | ||
24 | #include <linux/mod_devicetable.h> | 24 | #include <linux/mod_devicetable.h> |
25 | #include <linux/videodev2.h> | 25 | #include <linux/videodev2.h> |
26 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB | ||
27 | #include "pvrusb2-dvb.h" | ||
28 | #endif | ||
26 | 29 | ||
27 | /* | 30 | /* |
28 | 31 | ||
@@ -39,6 +42,13 @@ struct pvr2_string_table { | |||
39 | #define PVR2_ROUTING_SCHEME_HAUPPAUGE 0 | 42 | #define PVR2_ROUTING_SCHEME_HAUPPAUGE 0 |
40 | #define PVR2_ROUTING_SCHEME_GOTVIEW 1 | 43 | #define PVR2_ROUTING_SCHEME_GOTVIEW 1 |
41 | 44 | ||
45 | #define PVR2_DIGITAL_SCHEME_NONE 0 | ||
46 | #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1 | ||
47 | #define PVR2_DIGITAL_SCHEME_ONAIR 2 | ||
48 | |||
49 | #define PVR2_LED_SCHEME_NONE 0 | ||
50 | #define PVR2_LED_SCHEME_HAUPPAUGE 1 | ||
51 | |||
42 | /* This describes a particular hardware type (except for the USB device ID | 52 | /* This describes a particular hardware type (except for the USB device ID |
43 | which must live in a separate structure due to environmental | 53 | which must live in a separate structure due to environmental |
44 | constraints). See the top of pvrusb2-hdw.c for where this is | 54 | constraints). See the top of pvrusb2-hdw.c for where this is |
@@ -58,40 +68,64 @@ struct pvr2_device_desc { | |||
58 | was initialized from internal ROM. */ | 68 | was initialized from internal ROM. */ |
59 | struct pvr2_string_table fx2_firmware; | 69 | struct pvr2_string_table fx2_firmware; |
60 | 70 | ||
71 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB | ||
72 | /* callback functions to handle attachment of digital tuner & demod */ | ||
73 | struct pvr2_dvb_props *dvb_props; | ||
74 | |||
75 | #endif | ||
76 | /* Initial standard bits to use for this device, if not zero. | ||
77 | Anything set here is also implied as an available standard. | ||
78 | Note: This is ignored if overridden on the module load line via | ||
79 | the video_std module option. */ | ||
80 | v4l2_std_id default_std_mask; | ||
81 | |||
82 | /* V4L tuner type ID to use with this device (only used if the | ||
83 | driver could not discover the type any other way). */ | ||
84 | int default_tuner_type; | ||
85 | |||
61 | /* Signal routing scheme used by device, contains one of | 86 | /* Signal routing scheme used by device, contains one of |
62 | PVR2_ROUTING_SCHEME_XXX. Schemes have to be defined as we | 87 | PVR2_ROUTING_SCHEME_XXX. Schemes have to be defined as we |
63 | encounter them. This is an arbitrary integer scheme id; its | 88 | encounter them. This is an arbitrary integer scheme id; its |
64 | meaning is contained entirely within the driver and is | 89 | meaning is contained entirely within the driver and is |
65 | interpreted by logic which must send commands to the chip-level | 90 | interpreted by logic which must send commands to the chip-level |
66 | drivers (search for things which touch this field). */ | 91 | drivers (search for things which touch this field). */ |
67 | unsigned int signal_routing_scheme; | 92 | unsigned char signal_routing_scheme; |
68 | 93 | ||
69 | /* V4L tuner type ID to use with this device (only used if the | 94 | /* Indicates scheme for controlling device's LED (if any). The |
70 | driver could not discover the type any other way). */ | 95 | driver will turn on the LED when streaming is underway. This |
71 | int default_tuner_type; | 96 | contains one of PVR2_LED_SCHEME_XXX. */ |
97 | unsigned char led_scheme; | ||
72 | 98 | ||
73 | /* Initial standard bits to use for this device, if not zero. | 99 | /* Control scheme to use if there is a digital tuner. This |
74 | Anything set here is also implied as an available standard. | 100 | contains one of PVR2_DIGITAL_SCHEME_XXX. This is an arbitrary |
75 | Note: This is ignored if overridden on the module load line via | 101 | integer scheme id; its meaning is contained entirely within the |
76 | the video_std module option. */ | 102 | driver and is interpreted by logic which must control the |
77 | v4l2_std_id default_std_mask; | 103 | streaming pathway (search for things which touch this field). */ |
104 | unsigned char digital_control_scheme; | ||
78 | 105 | ||
79 | /* If set, we don't bother trying to load cx23416 firmware. */ | 106 | /* If set, we don't bother trying to load cx23416 firmware. */ |
80 | char flag_skip_cx23416_firmware; | 107 | int flag_skip_cx23416_firmware:1; |
108 | |||
109 | /* If set, the encoder must be healthy in order for digital mode to | ||
110 | work (otherwise we assume that digital streaming will work even | ||
111 | if we fail to locate firmware for the encoder). If the device | ||
112 | doesn't support digital streaming then this flag has no | ||
113 | effect. */ | ||
114 | int flag_digital_requires_cx23416:1; | ||
81 | 115 | ||
82 | /* Device has a hauppauge eeprom which we can interrogate. */ | 116 | /* Device has a hauppauge eeprom which we can interrogate. */ |
83 | char flag_has_hauppauge_rom; | 117 | int flag_has_hauppauge_rom:1; |
84 | 118 | ||
85 | /* Device does not require a powerup command to be issued. */ | 119 | /* Device does not require a powerup command to be issued. */ |
86 | char flag_no_powerup; | 120 | int flag_no_powerup:1; |
87 | 121 | ||
88 | /* Device has a cx25840 - this enables special additional logic to | 122 | /* Device has a cx25840 - this enables special additional logic to |
89 | handle it. */ | 123 | handle it. */ |
90 | char flag_has_cx25840; | 124 | int flag_has_cx25840:1; |
91 | 125 | ||
92 | /* Device has a wm8775 - this enables special additional logic to | 126 | /* Device has a wm8775 - this enables special additional logic to |
93 | ensure that it is found. */ | 127 | ensure that it is found. */ |
94 | char flag_has_wm8775; | 128 | int flag_has_wm8775:1; |
95 | 129 | ||
96 | /* Device has IR hardware that can be faked into looking like a | 130 | /* Device has IR hardware that can be faked into looking like a |
97 | normal Hauppauge i2c IR receiver. This is currently very | 131 | normal Hauppauge i2c IR receiver. This is currently very |
@@ -101,7 +135,15 @@ struct pvr2_device_desc { | |||
101 | to virtualize the presence of the non-existant IR receiver chip and | 135 | to virtualize the presence of the non-existant IR receiver chip and |
102 | implement the virtual receiver in terms of appropriate FX2 | 136 | implement the virtual receiver in terms of appropriate FX2 |
103 | commands. */ | 137 | commands. */ |
104 | char flag_has_hauppauge_custom_ir; | 138 | int flag_has_hauppauge_custom_ir:1; |
139 | |||
140 | /* These bits define which kinds of sources the device can handle. | ||
141 | Note: Digital tuner presence is inferred by the | ||
142 | digital_control_scheme enumeration. */ | ||
143 | int flag_has_fmradio:1; /* Has FM radio receiver */ | ||
144 | int flag_has_analogtuner:1; /* Has analog tuner */ | ||
145 | int flag_has_composite:1; /* Has composite input */ | ||
146 | int flag_has_svideo:1; /* Has s-video input */ | ||
105 | }; | 147 | }; |
106 | 148 | ||
107 | extern struct usb_device_id pvr2_device_table[]; | 149 | extern struct usb_device_id pvr2_device_table[]; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c new file mode 100644 index 000000000000..2e64f98d1241 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c | |||
@@ -0,0 +1,425 @@ | |||
1 | /* | ||
2 | * pvrusb2-dvb.c - linux-dvb api interface to the pvrusb2 driver. | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org> | ||
5 | * | ||
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 | ||
8 | * the Free Software Foundation; either version 2 of the License | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/kthread.h> | ||
22 | #include <linux/freezer.h> | ||
23 | #include "dvbdev.h" | ||
24 | #include "pvrusb2-hdw-internal.h" | ||
25 | #include "pvrusb2-hdw.h" | ||
26 | #include "pvrusb2-io.h" | ||
27 | #include "pvrusb2-dvb.h" | ||
28 | |||
29 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
30 | |||
31 | static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap) | ||
32 | { | ||
33 | int ret; | ||
34 | unsigned int count; | ||
35 | struct pvr2_buffer *bp; | ||
36 | struct pvr2_stream *stream; | ||
37 | |||
38 | printk(KERN_DEBUG "dvb thread started\n"); | ||
39 | set_freezable(); | ||
40 | |||
41 | stream = adap->channel.stream->stream; | ||
42 | |||
43 | for (;;) { | ||
44 | if (kthread_should_stop()) break; | ||
45 | |||
46 | /* Not sure about this... */ | ||
47 | try_to_freeze(); | ||
48 | |||
49 | bp = pvr2_stream_get_ready_buffer(stream); | ||
50 | if (bp != NULL) { | ||
51 | count = pvr2_buffer_get_count(bp); | ||
52 | if (count) { | ||
53 | dvb_dmx_swfilter( | ||
54 | &adap->demux, | ||
55 | adap->buffer_storage[ | ||
56 | pvr2_buffer_get_id(bp)], | ||
57 | count); | ||
58 | } else { | ||
59 | ret = pvr2_buffer_get_status(bp); | ||
60 | if (ret < 0) break; | ||
61 | } | ||
62 | ret = pvr2_buffer_queue(bp); | ||
63 | if (ret < 0) break; | ||
64 | |||
65 | /* Since we know we did something to a buffer, | ||
66 | just go back and try again. No point in | ||
67 | blocking unless we really ran out of | ||
68 | buffers to process. */ | ||
69 | continue; | ||
70 | } | ||
71 | |||
72 | |||
73 | /* Wait until more buffers become available or we're | ||
74 | told not to wait any longer. */ | ||
75 | ret = wait_event_interruptible( | ||
76 | adap->buffer_wait_data, | ||
77 | (pvr2_stream_get_ready_count(stream) > 0) || | ||
78 | kthread_should_stop()); | ||
79 | if (ret < 0) break; | ||
80 | } | ||
81 | |||
82 | /* If we get here and ret is < 0, then an error has occurred. | ||
83 | Probably would be a good idea to communicate that to DVB core... */ | ||
84 | |||
85 | printk(KERN_DEBUG "dvb thread stopped\n"); | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static int pvr2_dvb_feed_thread(void *data) | ||
91 | { | ||
92 | int stat = pvr2_dvb_feed_func(data); | ||
93 | /* from videobuf-dvb.c: */ | ||
94 | while (!kthread_should_stop()) { | ||
95 | set_current_state(TASK_INTERRUPTIBLE); | ||
96 | schedule(); | ||
97 | } | ||
98 | return stat; | ||
99 | } | ||
100 | |||
101 | static void pvr2_dvb_notify(struct pvr2_dvb_adapter *adap) | ||
102 | { | ||
103 | wake_up(&adap->buffer_wait_data); | ||
104 | } | ||
105 | |||
106 | static void pvr2_dvb_stream_end(struct pvr2_dvb_adapter *adap) | ||
107 | { | ||
108 | unsigned int idx; | ||
109 | struct pvr2_stream *stream; | ||
110 | |||
111 | if (adap->thread) { | ||
112 | kthread_stop(adap->thread); | ||
113 | adap->thread = NULL; | ||
114 | } | ||
115 | |||
116 | if (adap->channel.stream) { | ||
117 | stream = adap->channel.stream->stream; | ||
118 | } else { | ||
119 | stream = NULL; | ||
120 | } | ||
121 | if (stream) { | ||
122 | pvr2_hdw_set_streaming(adap->channel.hdw, 0); | ||
123 | pvr2_stream_set_callback(stream, NULL, NULL); | ||
124 | pvr2_stream_kill(stream); | ||
125 | pvr2_stream_set_buffer_count(stream, 0); | ||
126 | pvr2_channel_claim_stream(&adap->channel, NULL); | ||
127 | } | ||
128 | |||
129 | if (adap->stream_run) { | ||
130 | for (idx = 0; idx < PVR2_DVB_BUFFER_COUNT; idx++) { | ||
131 | if (!(adap->buffer_storage[idx])) continue; | ||
132 | kfree(adap->buffer_storage[idx]); | ||
133 | adap->buffer_storage[idx] = 0; | ||
134 | } | ||
135 | adap->stream_run = 0; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | static int pvr2_dvb_stream_do_start(struct pvr2_dvb_adapter *adap) | ||
140 | { | ||
141 | struct pvr2_context *pvr = adap->channel.mc_head; | ||
142 | unsigned int idx; | ||
143 | int ret; | ||
144 | struct pvr2_buffer *bp; | ||
145 | struct pvr2_stream *stream = 0; | ||
146 | |||
147 | if (adap->stream_run) return -EIO; | ||
148 | |||
149 | ret = pvr2_channel_claim_stream(&adap->channel, &pvr->video_stream); | ||
150 | /* somebody else already has the stream */ | ||
151 | if (ret < 0) return ret; | ||
152 | |||
153 | stream = adap->channel.stream->stream; | ||
154 | |||
155 | for (idx = 0; idx < PVR2_DVB_BUFFER_COUNT; idx++) { | ||
156 | adap->buffer_storage[idx] = kmalloc(PVR2_DVB_BUFFER_SIZE, | ||
157 | GFP_KERNEL); | ||
158 | if (!(adap->buffer_storage[idx])) return -ENOMEM; | ||
159 | } | ||
160 | |||
161 | pvr2_stream_set_callback(pvr->video_stream.stream, | ||
162 | (pvr2_stream_callback) pvr2_dvb_notify, adap); | ||
163 | |||
164 | ret = pvr2_stream_set_buffer_count(stream, PVR2_DVB_BUFFER_COUNT); | ||
165 | if (ret < 0) return ret; | ||
166 | |||
167 | for (idx = 0; idx < PVR2_DVB_BUFFER_COUNT; idx++) { | ||
168 | bp = pvr2_stream_get_buffer(stream, idx); | ||
169 | pvr2_buffer_set_buffer(bp, | ||
170 | adap->buffer_storage[idx], | ||
171 | PVR2_DVB_BUFFER_SIZE); | ||
172 | } | ||
173 | |||
174 | ret = pvr2_hdw_set_streaming(adap->channel.hdw, 1); | ||
175 | if (ret < 0) return ret; | ||
176 | |||
177 | while ((bp = pvr2_stream_get_idle_buffer(stream)) != 0) { | ||
178 | ret = pvr2_buffer_queue(bp); | ||
179 | if (ret < 0) return ret; | ||
180 | } | ||
181 | |||
182 | adap->thread = kthread_run(pvr2_dvb_feed_thread, adap, "pvrusb2-dvb"); | ||
183 | |||
184 | if (IS_ERR(adap->thread)) { | ||
185 | ret = PTR_ERR(adap->thread); | ||
186 | adap->thread = NULL; | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | adap->stream_run = !0; | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int pvr2_dvb_stream_start(struct pvr2_dvb_adapter *adap) | ||
196 | { | ||
197 | int ret = pvr2_dvb_stream_do_start(adap); | ||
198 | if (ret < 0) pvr2_dvb_stream_end(adap); | ||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | static int pvr2_dvb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) | ||
203 | { | ||
204 | struct pvr2_dvb_adapter *adap = dvbdmxfeed->demux->priv; | ||
205 | int ret = 0; | ||
206 | |||
207 | if (adap == NULL) return -ENODEV; | ||
208 | |||
209 | mutex_lock(&adap->lock); | ||
210 | do { | ||
211 | if (onoff) { | ||
212 | if (!adap->feedcount) { | ||
213 | printk(KERN_DEBUG "start feeding\n"); | ||
214 | ret = pvr2_dvb_stream_start(adap); | ||
215 | if (ret < 0) break; | ||
216 | } | ||
217 | (adap->feedcount)++; | ||
218 | } else if (adap->feedcount > 0) { | ||
219 | (adap->feedcount)--; | ||
220 | if (!adap->feedcount) { | ||
221 | printk(KERN_DEBUG "stop feeding\n"); | ||
222 | pvr2_dvb_stream_end(adap); | ||
223 | } | ||
224 | } | ||
225 | } while (0); | ||
226 | mutex_unlock(&adap->lock); | ||
227 | |||
228 | return ret; | ||
229 | } | ||
230 | |||
231 | static int pvr2_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
232 | { | ||
233 | printk(KERN_DEBUG "start pid: 0x%04x, feedtype: %d\n", | ||
234 | dvbdmxfeed->pid, dvbdmxfeed->type); | ||
235 | return pvr2_dvb_ctrl_feed(dvbdmxfeed, 1); | ||
236 | } | ||
237 | |||
238 | static int pvr2_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
239 | { | ||
240 | printk(KERN_DEBUG "stop pid: 0x%04x, feedtype: %d\n", | ||
241 | dvbdmxfeed->pid, dvbdmxfeed->type); | ||
242 | return pvr2_dvb_ctrl_feed(dvbdmxfeed, 0); | ||
243 | } | ||
244 | |||
245 | static int pvr2_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) | ||
246 | { | ||
247 | struct pvr2_dvb_adapter *adap = fe->dvb->priv; | ||
248 | return pvr2_channel_limit_inputs( | ||
249 | &adap->channel, | ||
250 | (acquire ? (1 << PVR2_CVAL_INPUT_DTV) : 0)); | ||
251 | } | ||
252 | |||
253 | static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap) | ||
254 | { | ||
255 | int ret; | ||
256 | |||
257 | ret = dvb_register_adapter(&adap->dvb_adap, "pvrusb2-dvb", | ||
258 | THIS_MODULE/*&hdw->usb_dev->owner*/, | ||
259 | &adap->channel.hdw->usb_dev->dev, | ||
260 | adapter_nr); | ||
261 | if (ret < 0) { | ||
262 | err("dvb_register_adapter failed: error %d", ret); | ||
263 | goto err; | ||
264 | } | ||
265 | adap->dvb_adap.priv = adap; | ||
266 | |||
267 | adap->demux.dmx.capabilities = DMX_TS_FILTERING | | ||
268 | DMX_SECTION_FILTERING | | ||
269 | DMX_MEMORY_BASED_FILTERING; | ||
270 | adap->demux.priv = adap; | ||
271 | adap->demux.filternum = 256; | ||
272 | adap->demux.feednum = 256; | ||
273 | adap->demux.start_feed = pvr2_dvb_start_feed; | ||
274 | adap->demux.stop_feed = pvr2_dvb_stop_feed; | ||
275 | adap->demux.write_to_decoder = NULL; | ||
276 | |||
277 | ret = dvb_dmx_init(&adap->demux); | ||
278 | if (ret < 0) { | ||
279 | err("dvb_dmx_init failed: error %d", ret); | ||
280 | goto err_dmx; | ||
281 | } | ||
282 | |||
283 | adap->dmxdev.filternum = adap->demux.filternum; | ||
284 | adap->dmxdev.demux = &adap->demux.dmx; | ||
285 | adap->dmxdev.capabilities = 0; | ||
286 | |||
287 | ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap); | ||
288 | if (ret < 0) { | ||
289 | err("dvb_dmxdev_init failed: error %d", ret); | ||
290 | goto err_dmx_dev; | ||
291 | } | ||
292 | |||
293 | dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx); | ||
294 | |||
295 | return 0; | ||
296 | |||
297 | err_dmx_dev: | ||
298 | dvb_dmx_release(&adap->demux); | ||
299 | err_dmx: | ||
300 | dvb_unregister_adapter(&adap->dvb_adap); | ||
301 | err: | ||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap) | ||
306 | { | ||
307 | printk(KERN_DEBUG "unregistering DVB devices\n"); | ||
308 | dvb_net_release(&adap->dvb_net); | ||
309 | adap->demux.dmx.close(&adap->demux.dmx); | ||
310 | dvb_dmxdev_release(&adap->dmxdev); | ||
311 | dvb_dmx_release(&adap->demux); | ||
312 | dvb_unregister_adapter(&adap->dvb_adap); | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap) | ||
317 | { | ||
318 | struct pvr2_hdw *hdw = adap->channel.hdw; | ||
319 | struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props; | ||
320 | int ret = 0; | ||
321 | |||
322 | if (dvb_props == NULL) { | ||
323 | err("fe_props not defined!"); | ||
324 | return -EINVAL; | ||
325 | } | ||
326 | |||
327 | ret = pvr2_channel_limit_inputs( | ||
328 | &adap->channel, | ||
329 | (1 << PVR2_CVAL_INPUT_DTV)); | ||
330 | if (ret) { | ||
331 | err("failed to grab control of dtv input (code=%d)", | ||
332 | ret); | ||
333 | return ret; | ||
334 | } | ||
335 | |||
336 | if (dvb_props->frontend_attach == NULL) { | ||
337 | err("frontend_attach not defined!"); | ||
338 | ret = -EINVAL; | ||
339 | goto done; | ||
340 | } | ||
341 | |||
342 | if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) { | ||
343 | |||
344 | if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) { | ||
345 | err("frontend registration failed!"); | ||
346 | dvb_frontend_detach(adap->fe); | ||
347 | adap->fe = NULL; | ||
348 | ret = -ENODEV; | ||
349 | goto done; | ||
350 | } | ||
351 | |||
352 | if (dvb_props->tuner_attach) | ||
353 | dvb_props->tuner_attach(adap); | ||
354 | |||
355 | if (adap->fe->ops.analog_ops.standby) | ||
356 | adap->fe->ops.analog_ops.standby(adap->fe); | ||
357 | |||
358 | /* Ensure all frontends negotiate bus access */ | ||
359 | adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl; | ||
360 | |||
361 | } else { | ||
362 | err("no frontend was attached!"); | ||
363 | ret = -ENODEV; | ||
364 | return ret; | ||
365 | } | ||
366 | |||
367 | done: | ||
368 | pvr2_channel_limit_inputs(&adap->channel, 0); | ||
369 | return ret; | ||
370 | } | ||
371 | |||
372 | static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap) | ||
373 | { | ||
374 | if (adap->fe != NULL) { | ||
375 | dvb_unregister_frontend(adap->fe); | ||
376 | dvb_frontend_detach(adap->fe); | ||
377 | } | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static void pvr2_dvb_destroy(struct pvr2_dvb_adapter *adap) | ||
382 | { | ||
383 | pvr2_dvb_stream_end(adap); | ||
384 | pvr2_dvb_frontend_exit(adap); | ||
385 | pvr2_dvb_adapter_exit(adap); | ||
386 | pvr2_channel_done(&adap->channel); | ||
387 | kfree(adap); | ||
388 | } | ||
389 | |||
390 | static void pvr2_dvb_internal_check(struct pvr2_channel *chp) | ||
391 | { | ||
392 | struct pvr2_dvb_adapter *adap; | ||
393 | adap = container_of(chp, struct pvr2_dvb_adapter, channel); | ||
394 | if (!adap->channel.mc_head->disconnect_flag) return; | ||
395 | pvr2_dvb_destroy(adap); | ||
396 | } | ||
397 | |||
398 | struct pvr2_dvb_adapter *pvr2_dvb_create(struct pvr2_context *pvr) | ||
399 | { | ||
400 | int ret = 0; | ||
401 | struct pvr2_dvb_adapter *adap; | ||
402 | if (!pvr->hdw->hdw_desc->dvb_props) { | ||
403 | /* Device lacks a digital interface so don't set up | ||
404 | the DVB side of the driver either. For now. */ | ||
405 | return NULL; | ||
406 | } | ||
407 | adap = kzalloc(sizeof(*adap), GFP_KERNEL); | ||
408 | if (!adap) return adap; | ||
409 | pvr2_channel_init(&adap->channel, pvr); | ||
410 | adap->channel.check_func = pvr2_dvb_internal_check; | ||
411 | init_waitqueue_head(&adap->buffer_wait_data); | ||
412 | mutex_init(&adap->lock); | ||
413 | ret = pvr2_dvb_adapter_init(adap); | ||
414 | if (ret < 0) goto fail1; | ||
415 | ret = pvr2_dvb_frontend_init(adap); | ||
416 | if (ret < 0) goto fail2; | ||
417 | return adap; | ||
418 | |||
419 | fail2: | ||
420 | pvr2_dvb_adapter_exit(adap); | ||
421 | fail1: | ||
422 | pvr2_channel_done(&adap->channel); | ||
423 | return NULL; | ||
424 | } | ||
425 | |||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.h b/drivers/media/video/pvrusb2/pvrusb2-dvb.h new file mode 100644 index 000000000000..884ff916a352 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.h | |||
@@ -0,0 +1,41 @@ | |||
1 | #ifndef __PVRUSB2_DVB_H__ | ||
2 | #define __PVRUSB2_DVB_H__ | ||
3 | |||
4 | #include "dvb_frontend.h" | ||
5 | #include "dvb_demux.h" | ||
6 | #include "dvb_net.h" | ||
7 | #include "dmxdev.h" | ||
8 | #include "pvrusb2-context.h" | ||
9 | |||
10 | #define PVR2_DVB_BUFFER_COUNT 32 | ||
11 | #define PVR2_DVB_BUFFER_SIZE PAGE_ALIGN(0x4000) | ||
12 | |||
13 | struct pvr2_dvb_adapter { | ||
14 | struct pvr2_channel channel; | ||
15 | |||
16 | struct dvb_adapter dvb_adap; | ||
17 | struct dmxdev dmxdev; | ||
18 | struct dvb_demux demux; | ||
19 | struct dvb_net dvb_net; | ||
20 | struct dvb_frontend *fe; | ||
21 | |||
22 | int feedcount; | ||
23 | int max_feed_count; | ||
24 | |||
25 | struct task_struct *thread; | ||
26 | struct mutex lock; | ||
27 | |||
28 | unsigned int stream_run:1; | ||
29 | |||
30 | wait_queue_head_t buffer_wait_data; | ||
31 | char *buffer_storage[PVR2_DVB_BUFFER_COUNT]; | ||
32 | }; | ||
33 | |||
34 | struct pvr2_dvb_props { | ||
35 | int (*frontend_attach) (struct pvr2_dvb_adapter *); | ||
36 | int (*tuner_attach) (struct pvr2_dvb_adapter *); | ||
37 | }; | ||
38 | |||
39 | struct pvr2_dvb_adapter *pvr2_dvb_create(struct pvr2_context *pvr); | ||
40 | |||
41 | #endif /* __PVRUSB2_DVB_H__ */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 64062879981e..c46d367f7472 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c | |||
@@ -278,11 +278,20 @@ static int pvr2_encoder_cmd(void *ctxt, | |||
278 | ret = -EBUSY; | 278 | ret = -EBUSY; |
279 | } | 279 | } |
280 | if (ret) { | 280 | if (ret) { |
281 | del_timer_sync(&hdw->encoder_run_timer); | ||
281 | hdw->state_encoder_ok = 0; | 282 | hdw->state_encoder_ok = 0; |
282 | pvr2_trace(PVR2_TRACE_STBITS, | 283 | pvr2_trace(PVR2_TRACE_STBITS, |
283 | "State bit %s <-- %s", | 284 | "State bit %s <-- %s", |
284 | "state_encoder_ok", | 285 | "state_encoder_ok", |
285 | (hdw->state_encoder_ok ? "true" : "false")); | 286 | (hdw->state_encoder_ok ? "true" : "false")); |
287 | if (hdw->state_encoder_runok) { | ||
288 | hdw->state_encoder_runok = 0; | ||
289 | pvr2_trace(PVR2_TRACE_STBITS, | ||
290 | "State bit %s <-- %s", | ||
291 | "state_encoder_runok", | ||
292 | (hdw->state_encoder_runok ? | ||
293 | "true" : "false")); | ||
294 | } | ||
286 | pvr2_trace( | 295 | pvr2_trace( |
287 | PVR2_TRACE_ERROR_LEGS, | 296 | PVR2_TRACE_ERROR_LEGS, |
288 | "Giving up on command." | 297 | "Giving up on command." |
@@ -480,10 +489,6 @@ int pvr2_encoder_start(struct pvr2_hdw *hdw) | |||
480 | /* unmask some interrupts */ | 489 | /* unmask some interrupts */ |
481 | pvr2_write_register(hdw, 0x0048, 0xbfffffff); | 490 | pvr2_write_register(hdw, 0x0048, 0xbfffffff); |
482 | 491 | ||
483 | /* change some GPIO data */ | ||
484 | pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000481); | ||
485 | pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); | ||
486 | |||
487 | pvr2_encoder_vcmd(hdw,CX2341X_ENC_MUTE_VIDEO,1, | 492 | pvr2_encoder_vcmd(hdw,CX2341X_ENC_MUTE_VIDEO,1, |
488 | hdw->input_val == PVR2_CVAL_INPUT_RADIO ? 1 : 0); | 493 | hdw->input_val == PVR2_CVAL_INPUT_RADIO ? 1 : 0); |
489 | 494 | ||
@@ -526,12 +531,6 @@ int pvr2_encoder_stop(struct pvr2_hdw *hdw) | |||
526 | break; | 531 | break; |
527 | } | 532 | } |
528 | 533 | ||
529 | /* change some GPIO data */ | ||
530 | /* Note: Bit d7 of dir appears to control the LED. So we shut it | ||
531 | off here. */ | ||
532 | pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401); | ||
533 | pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); | ||
534 | |||
535 | return status; | 534 | return status; |
536 | } | 535 | } |
537 | 536 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h index ffbc6d096108..abaada31e66e 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h +++ b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h | |||
@@ -22,32 +22,41 @@ | |||
22 | #ifndef _PVRUSB2_FX2_CMD_H_ | 22 | #ifndef _PVRUSB2_FX2_CMD_H_ |
23 | #define _PVRUSB2_FX2_CMD_H_ | 23 | #define _PVRUSB2_FX2_CMD_H_ |
24 | 24 | ||
25 | #define FX2CMD_MEM_WRITE_DWORD 0x01 | 25 | #define FX2CMD_MEM_WRITE_DWORD 0x01u |
26 | #define FX2CMD_MEM_READ_DWORD 0x02 | 26 | #define FX2CMD_MEM_READ_DWORD 0x02u |
27 | 27 | ||
28 | #define FX2CMD_MEM_READ_64BYTES 0x28 | 28 | #define FX2CMD_MEM_READ_64BYTES 0x28u |
29 | 29 | ||
30 | #define FX2CMD_REG_WRITE 0x04 | 30 | #define FX2CMD_REG_WRITE 0x04u |
31 | #define FX2CMD_REG_READ 0x05 | 31 | #define FX2CMD_REG_READ 0x05u |
32 | #define FX2CMD_MEMSEL 0x06 | 32 | #define FX2CMD_MEMSEL 0x06u |
33 | 33 | ||
34 | #define FX2CMD_I2C_WRITE 0x08 | 34 | #define FX2CMD_I2C_WRITE 0x08u |
35 | #define FX2CMD_I2C_READ 0x09 | 35 | #define FX2CMD_I2C_READ 0x09u |
36 | 36 | ||
37 | #define FX2CMD_GET_USB_SPEED 0x0b | 37 | #define FX2CMD_GET_USB_SPEED 0x0bu |
38 | 38 | ||
39 | #define FX2CMD_STREAMING_ON 0x36 | 39 | #define FX2CMD_STREAMING_ON 0x36u |
40 | #define FX2CMD_STREAMING_OFF 0x37 | 40 | #define FX2CMD_STREAMING_OFF 0x37u |
41 | 41 | ||
42 | #define FX2CMD_FWPOST1 0x52 | 42 | #define FX2CMD_FWPOST1 0x52u |
43 | 43 | ||
44 | #define FX2CMD_POWER_OFF 0xdc | 44 | #define FX2CMD_POWER_OFF 0xdcu |
45 | #define FX2CMD_POWER_ON 0xde | 45 | #define FX2CMD_POWER_ON 0xdeu |
46 | 46 | ||
47 | #define FX2CMD_DEEP_RESET 0xdd | 47 | #define FX2CMD_DEEP_RESET 0xddu |
48 | 48 | ||
49 | #define FX2CMD_GET_EEPROM_ADDR 0xeb | 49 | #define FX2CMD_GET_EEPROM_ADDR 0xebu |
50 | #define FX2CMD_GET_IR_CODE 0xec | 50 | #define FX2CMD_GET_IR_CODE 0xecu |
51 | |||
52 | #define FX2CMD_HCW_DEMOD_RESETIN 0xf0u | ||
53 | #define FX2CMD_HCW_DTV_STREAMING_ON 0xf1u | ||
54 | #define FX2CMD_HCW_DTV_STREAMING_OFF 0xf2u | ||
55 | |||
56 | #define FX2CMD_ONAIR_DTV_STREAMING_ON 0xa0u | ||
57 | #define FX2CMD_ONAIR_DTV_STREAMING_OFF 0xa1u | ||
58 | #define FX2CMD_ONAIR_DTV_POWER_ON 0xa2u | ||
59 | #define FX2CMD_ONAIR_DTV_POWER_OFF 0xa3u | ||
51 | 60 | ||
52 | #endif /* _PVRUSB2_FX2_CMD_H_ */ | 61 | #endif /* _PVRUSB2_FX2_CMD_H_ */ |
53 | 62 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index d7a216b41b72..a3fe251d6fd9 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | |||
@@ -163,6 +163,11 @@ struct pvr2_decoder_ctrl { | |||
163 | #define FW1_STATE_RELOAD 3 | 163 | #define FW1_STATE_RELOAD 3 |
164 | #define FW1_STATE_OK 4 | 164 | #define FW1_STATE_OK 4 |
165 | 165 | ||
166 | /* What state the device is in if it is a hybrid */ | ||
167 | #define PVR2_PATHWAY_UNKNOWN 0 | ||
168 | #define PVR2_PATHWAY_ANALOG 1 | ||
169 | #define PVR2_PATHWAY_DIGITAL 2 | ||
170 | |||
166 | typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16); | 171 | typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16); |
167 | #define PVR2_I2C_FUNC_CNT 128 | 172 | #define PVR2_I2C_FUNC_CNT 128 |
168 | 173 | ||
@@ -182,7 +187,6 @@ struct pvr2_hdw { | |||
182 | struct workqueue_struct *workqueue; | 187 | struct workqueue_struct *workqueue; |
183 | struct work_struct workpoll; /* Update driver state */ | 188 | struct work_struct workpoll; /* Update driver state */ |
184 | struct work_struct worki2csync; /* Update i2c clients */ | 189 | struct work_struct worki2csync; /* Update i2c clients */ |
185 | struct work_struct workinit; /* Driver initialization sequence */ | ||
186 | 190 | ||
187 | /* Video spigot */ | 191 | /* Video spigot */ |
188 | struct pvr2_stream *vid_stream; | 192 | struct pvr2_stream *vid_stream; |
@@ -229,17 +233,19 @@ struct pvr2_hdw { | |||
229 | 233 | ||
230 | /* Bits of state that describe what is going on with various parts | 234 | /* Bits of state that describe what is going on with various parts |
231 | of the driver. */ | 235 | of the driver. */ |
236 | int state_pathway_ok; /* Pathway config is ok */ | ||
232 | int state_encoder_ok; /* Encoder is operational */ | 237 | int state_encoder_ok; /* Encoder is operational */ |
233 | int state_encoder_run; /* Encoder is running */ | 238 | int state_encoder_run; /* Encoder is running */ |
234 | int state_encoder_config; /* Encoder is configured */ | 239 | int state_encoder_config; /* Encoder is configured */ |
235 | int state_encoder_waitok; /* Encoder pre-wait done */ | 240 | int state_encoder_waitok; /* Encoder pre-wait done */ |
241 | int state_encoder_runok; /* Encoder has run for >= .25 sec */ | ||
236 | int state_decoder_run; /* Decoder is running */ | 242 | int state_decoder_run; /* Decoder is running */ |
237 | int state_usbstream_run; /* FX2 is streaming */ | 243 | int state_usbstream_run; /* FX2 is streaming */ |
238 | int state_decoder_quiescent; /* Decoder idle for > 50msec */ | 244 | int state_decoder_quiescent; /* Decoder idle for > 50msec */ |
239 | int state_pipeline_config; /* Pipeline is configured */ | 245 | int state_pipeline_config; /* Pipeline is configured */ |
240 | int state_pipeline_req; /* Somebody wants to stream */ | 246 | int state_pipeline_req; /* Somebody wants to stream */ |
241 | int state_pipeline_pause; /* Pipeline must be paused */ | 247 | int state_pipeline_pause; /* Pipeline must be paused */ |
242 | int state_pipeline_idle; /* Pipeline not running */ | 248 | int state_pipeline_idle; /* Pipeline not running */ |
243 | 249 | ||
244 | /* This is the master state of the driver. It is the combined | 250 | /* This is the master state of the driver. It is the combined |
245 | result of other bits of state. Examining this will indicate the | 251 | result of other bits of state. Examining this will indicate the |
@@ -247,6 +253,9 @@ struct pvr2_hdw { | |||
247 | PVR2_STATE_xxxx */ | 253 | PVR2_STATE_xxxx */ |
248 | unsigned int master_state; | 254 | unsigned int master_state; |
249 | 255 | ||
256 | /* True if device led is currently on */ | ||
257 | int led_on; | ||
258 | |||
250 | /* True if states must be re-evaluated */ | 259 | /* True if states must be re-evaluated */ |
251 | int state_stale; | 260 | int state_stale; |
252 | 261 | ||
@@ -259,6 +268,9 @@ struct pvr2_hdw { | |||
259 | /* Timer for measuring encoder pre-wait time */ | 268 | /* Timer for measuring encoder pre-wait time */ |
260 | struct timer_list encoder_wait_timer; | 269 | struct timer_list encoder_wait_timer; |
261 | 270 | ||
271 | /* Timer for measuring encoder minimum run time */ | ||
272 | struct timer_list encoder_run_timer; | ||
273 | |||
262 | /* Place to block while waiting for state changes */ | 274 | /* Place to block while waiting for state changes */ |
263 | wait_queue_head_t state_wait_data; | 275 | wait_queue_head_t state_wait_data; |
264 | 276 | ||
@@ -267,6 +279,7 @@ struct pvr2_hdw { | |||
267 | int flag_disconnected; /* flag_ok == 0 due to disconnect */ | 279 | int flag_disconnected; /* flag_ok == 0 due to disconnect */ |
268 | int flag_init_ok; /* true if structure is fully initialized */ | 280 | int flag_init_ok; /* true if structure is fully initialized */ |
269 | int fw1_state; /* current situation with fw1 */ | 281 | int fw1_state; /* current situation with fw1 */ |
282 | int pathway_state; /* one of PVR2_PATHWAY_xxx */ | ||
270 | int flag_decoder_missed;/* We've noticed missing decoder */ | 283 | int flag_decoder_missed;/* We've noticed missing decoder */ |
271 | int flag_tripped; /* Indicates overall failure to start */ | 284 | int flag_tripped; /* Indicates overall failure to start */ |
272 | 285 | ||
@@ -323,6 +336,11 @@ struct pvr2_hdw { | |||
323 | int v4l_minor_number_vbi; | 336 | int v4l_minor_number_vbi; |
324 | int v4l_minor_number_radio; | 337 | int v4l_minor_number_radio; |
325 | 338 | ||
339 | /* Bit mask of PVR2_CVAL_INPUT choices which are valid for the hardware */ | ||
340 | unsigned int input_avail_mask; | ||
341 | /* Bit mask of PVR2_CVAL_INPUT choices which are currenly allowed */ | ||
342 | unsigned int input_allowed_mask; | ||
343 | |||
326 | /* Location of eeprom or a negative number if none */ | 344 | /* Location of eeprom or a negative number if none */ |
327 | int eeprom_addr; | 345 | int eeprom_addr; |
328 | 346 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 2404053a4d85..0a868888f389 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -43,13 +43,13 @@ | |||
43 | static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL}; | 43 | static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL}; |
44 | static DEFINE_MUTEX(pvr2_unit_mtx); | 44 | static DEFINE_MUTEX(pvr2_unit_mtx); |
45 | 45 | ||
46 | static int ctlchg = 0; | 46 | static int ctlchg; |
47 | static int initusbreset = 1; | 47 | static int initusbreset = 1; |
48 | static int procreload = 0; | 48 | static int procreload; |
49 | static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 }; | 49 | static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 }; |
50 | static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; | 50 | static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; |
51 | static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; | 51 | static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; |
52 | static int init_pause_msec = 0; | 52 | static int init_pause_msec; |
53 | 53 | ||
54 | module_param(ctlchg, int, S_IRUGO|S_IWUSR); | 54 | module_param(ctlchg, int, S_IRUGO|S_IWUSR); |
55 | MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value"); | 55 | MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value"); |
@@ -182,6 +182,7 @@ static const char *control_values_srate[] = { | |||
182 | 182 | ||
183 | static const char *control_values_input[] = { | 183 | static const char *control_values_input[] = { |
184 | [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/ | 184 | [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/ |
185 | [PVR2_CVAL_INPUT_DTV] = "dtv", | ||
185 | [PVR2_CVAL_INPUT_RADIO] = "radio", | 186 | [PVR2_CVAL_INPUT_RADIO] = "radio", |
186 | [PVR2_CVAL_INPUT_SVIDEO] = "s-video", | 187 | [PVR2_CVAL_INPUT_SVIDEO] = "s-video", |
187 | [PVR2_CVAL_INPUT_COMPOSITE] = "composite", | 188 | [PVR2_CVAL_INPUT_COMPOSITE] = "composite", |
@@ -215,12 +216,45 @@ static const char *pvr2_state_names[] = { | |||
215 | }; | 216 | }; |
216 | 217 | ||
217 | 218 | ||
219 | struct pvr2_fx2cmd_descdef { | ||
220 | unsigned char id; | ||
221 | unsigned char *desc; | ||
222 | }; | ||
223 | |||
224 | static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = { | ||
225 | {FX2CMD_MEM_WRITE_DWORD, "write encoder dword"}, | ||
226 | {FX2CMD_MEM_READ_DWORD, "read encoder dword"}, | ||
227 | {FX2CMD_MEM_READ_64BYTES, "read encoder 64bytes"}, | ||
228 | {FX2CMD_REG_WRITE, "write encoder register"}, | ||
229 | {FX2CMD_REG_READ, "read encoder register"}, | ||
230 | {FX2CMD_MEMSEL, "encoder memsel"}, | ||
231 | {FX2CMD_I2C_WRITE, "i2c write"}, | ||
232 | {FX2CMD_I2C_READ, "i2c read"}, | ||
233 | {FX2CMD_GET_USB_SPEED, "get USB speed"}, | ||
234 | {FX2CMD_STREAMING_ON, "stream on"}, | ||
235 | {FX2CMD_STREAMING_OFF, "stream off"}, | ||
236 | {FX2CMD_FWPOST1, "fwpost1"}, | ||
237 | {FX2CMD_POWER_OFF, "power off"}, | ||
238 | {FX2CMD_POWER_ON, "power on"}, | ||
239 | {FX2CMD_DEEP_RESET, "deep reset"}, | ||
240 | {FX2CMD_GET_EEPROM_ADDR, "get rom addr"}, | ||
241 | {FX2CMD_GET_IR_CODE, "get IR code"}, | ||
242 | {FX2CMD_HCW_DEMOD_RESETIN, "hcw demod resetin"}, | ||
243 | {FX2CMD_HCW_DTV_STREAMING_ON, "hcw dtv stream on"}, | ||
244 | {FX2CMD_HCW_DTV_STREAMING_OFF, "hcw dtv stream off"}, | ||
245 | {FX2CMD_ONAIR_DTV_STREAMING_ON, "onair dtv stream on"}, | ||
246 | {FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"}, | ||
247 | {FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"}, | ||
248 | {FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"}, | ||
249 | }; | ||
250 | |||
251 | |||
252 | static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v); | ||
218 | static void pvr2_hdw_state_sched(struct pvr2_hdw *); | 253 | static void pvr2_hdw_state_sched(struct pvr2_hdw *); |
219 | static int pvr2_hdw_state_eval(struct pvr2_hdw *); | 254 | static int pvr2_hdw_state_eval(struct pvr2_hdw *); |
220 | static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long); | 255 | static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long); |
221 | static void pvr2_hdw_worker_i2c(struct work_struct *work); | 256 | static void pvr2_hdw_worker_i2c(struct work_struct *work); |
222 | static void pvr2_hdw_worker_poll(struct work_struct *work); | 257 | static void pvr2_hdw_worker_poll(struct work_struct *work); |
223 | static void pvr2_hdw_worker_init(struct work_struct *work); | ||
224 | static int pvr2_hdw_wait(struct pvr2_hdw *,int state); | 258 | static int pvr2_hdw_wait(struct pvr2_hdw *,int state); |
225 | static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *); | 259 | static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *); |
226 | static void pvr2_hdw_state_log_state(struct pvr2_hdw *); | 260 | static void pvr2_hdw_state_log_state(struct pvr2_hdw *); |
@@ -231,6 +265,8 @@ static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); | |||
231 | static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); | 265 | static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); |
232 | static void pvr2_hdw_quiescent_timeout(unsigned long); | 266 | static void pvr2_hdw_quiescent_timeout(unsigned long); |
233 | static void pvr2_hdw_encoder_wait_timeout(unsigned long); | 267 | static void pvr2_hdw_encoder_wait_timeout(unsigned long); |
268 | static void pvr2_hdw_encoder_run_timeout(unsigned long); | ||
269 | static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32); | ||
234 | static int pvr2_send_request_ex(struct pvr2_hdw *hdw, | 270 | static int pvr2_send_request_ex(struct pvr2_hdw *hdw, |
235 | unsigned int timeout,int probe_fl, | 271 | unsigned int timeout,int probe_fl, |
236 | void *write_data,unsigned int write_len, | 272 | void *write_data,unsigned int write_len, |
@@ -367,26 +403,14 @@ static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp) | |||
367 | return 0; | 403 | return 0; |
368 | } | 404 | } |
369 | 405 | ||
370 | static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v) | 406 | static int ctrl_check_input(struct pvr2_ctrl *cptr,int v) |
371 | { | 407 | { |
372 | struct pvr2_hdw *hdw = cptr->hdw; | 408 | return ((1 << v) & cptr->hdw->input_allowed_mask) != 0; |
373 | 409 | } | |
374 | if (hdw->input_val != v) { | ||
375 | hdw->input_val = v; | ||
376 | hdw->input_dirty = !0; | ||
377 | } | ||
378 | 410 | ||
379 | /* Handle side effects - if we switch to a mode that needs the RF | 411 | static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v) |
380 | tuner, then select the right frequency choice as well and mark | 412 | { |
381 | it dirty. */ | 413 | return pvr2_hdw_set_input(cptr->hdw,v); |
382 | if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { | ||
383 | hdw->freqSelector = 0; | ||
384 | hdw->freqDirty = !0; | ||
385 | } else if (hdw->input_val == PVR2_CVAL_INPUT_TV) { | ||
386 | hdw->freqSelector = 1; | ||
387 | hdw->freqDirty = !0; | ||
388 | } | ||
389 | return 0; | ||
390 | } | 414 | } |
391 | 415 | ||
392 | static int ctrl_isdirty_input(struct pvr2_ctrl *cptr) | 416 | static int ctrl_isdirty_input(struct pvr2_ctrl *cptr) |
@@ -803,6 +827,7 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
803 | .name = "input", | 827 | .name = "input", |
804 | .internal_id = PVR2_CID_INPUT, | 828 | .internal_id = PVR2_CID_INPUT, |
805 | .default_value = PVR2_CVAL_INPUT_TV, | 829 | .default_value = PVR2_CVAL_INPUT_TV, |
830 | .check_value = ctrl_check_input, | ||
806 | DEFREF(input), | 831 | DEFREF(input), |
807 | DEFENUM(control_values_input), | 832 | DEFENUM(control_values_input), |
808 | },{ | 833 | },{ |
@@ -982,7 +1007,7 @@ unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw) | |||
982 | 1007 | ||
983 | /* Set the currently tuned frequency and account for all possible | 1008 | /* Set the currently tuned frequency and account for all possible |
984 | driver-core side effects of this action. */ | 1009 | driver-core side effects of this action. */ |
985 | void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val) | 1010 | static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val) |
986 | { | 1011 | { |
987 | if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { | 1012 | if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { |
988 | if (hdw->freqSelector) { | 1013 | if (hdw->freqSelector) { |
@@ -1195,6 +1220,14 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1195 | time we configure the encoder, then we'll fully configure it. */ | 1220 | time we configure the encoder, then we'll fully configure it. */ |
1196 | hdw->enc_cur_valid = 0; | 1221 | hdw->enc_cur_valid = 0; |
1197 | 1222 | ||
1223 | /* Encoder is about to be reset so note that as far as we're | ||
1224 | concerned now, the encoder has never been run. */ | ||
1225 | del_timer_sync(&hdw->encoder_run_timer); | ||
1226 | if (hdw->state_encoder_runok) { | ||
1227 | hdw->state_encoder_runok = 0; | ||
1228 | trace_stbit("state_encoder_runok",hdw->state_encoder_runok); | ||
1229 | } | ||
1230 | |||
1198 | /* First prepare firmware loading */ | 1231 | /* First prepare firmware loading */ |
1199 | ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ | 1232 | ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ |
1200 | ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/ | 1233 | ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/ |
@@ -1212,19 +1245,14 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1212 | ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/ | 1245 | ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/ |
1213 | ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/ | 1246 | ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/ |
1214 | ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ | 1247 | ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ |
1215 | LOCK_TAKE(hdw->ctl_lock); do { | 1248 | ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_FWPOST1); |
1216 | hdw->cmd_buffer[0] = FX2CMD_FWPOST1; | 1249 | ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16)); |
1217 | ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | ||
1218 | hdw->cmd_buffer[0] = FX2CMD_MEMSEL; | ||
1219 | hdw->cmd_buffer[1] = 0; | ||
1220 | ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0); | ||
1221 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
1222 | 1250 | ||
1223 | if (ret) { | 1251 | if (ret) { |
1224 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 1252 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
1225 | "firmware2 upload prep failed, ret=%d",ret); | 1253 | "firmware2 upload prep failed, ret=%d",ret); |
1226 | release_firmware(fw_entry); | 1254 | release_firmware(fw_entry); |
1227 | return ret; | 1255 | goto done; |
1228 | } | 1256 | } |
1229 | 1257 | ||
1230 | /* Now send firmware */ | 1258 | /* Now send firmware */ |
@@ -1237,7 +1265,8 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1237 | " must be a multiple of %zu bytes", | 1265 | " must be a multiple of %zu bytes", |
1238 | fw_files[fwidx],sizeof(u32)); | 1266 | fw_files[fwidx],sizeof(u32)); |
1239 | release_firmware(fw_entry); | 1267 | release_firmware(fw_entry); |
1240 | return -1; | 1268 | ret = -EINVAL; |
1269 | goto done; | ||
1241 | } | 1270 | } |
1242 | 1271 | ||
1243 | fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); | 1272 | fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); |
@@ -1245,7 +1274,8 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1245 | release_firmware(fw_entry); | 1274 | release_firmware(fw_entry); |
1246 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 1275 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
1247 | "failed to allocate memory for firmware2 upload"); | 1276 | "failed to allocate memory for firmware2 upload"); |
1248 | return -ENOMEM; | 1277 | ret = -ENOMEM; |
1278 | goto done; | ||
1249 | } | 1279 | } |
1250 | 1280 | ||
1251 | pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT); | 1281 | pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT); |
@@ -1276,23 +1306,27 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1276 | if (ret) { | 1306 | if (ret) { |
1277 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 1307 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
1278 | "firmware2 upload transfer failure"); | 1308 | "firmware2 upload transfer failure"); |
1279 | return ret; | 1309 | goto done; |
1280 | } | 1310 | } |
1281 | 1311 | ||
1282 | /* Finish upload */ | 1312 | /* Finish upload */ |
1283 | 1313 | ||
1284 | ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/ | 1314 | ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/ |
1285 | ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/ | 1315 | ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/ |
1286 | LOCK_TAKE(hdw->ctl_lock); do { | 1316 | ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16)); |
1287 | hdw->cmd_buffer[0] = FX2CMD_MEMSEL; | ||
1288 | hdw->cmd_buffer[1] = 0; | ||
1289 | ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0); | ||
1290 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
1291 | 1317 | ||
1292 | if (ret) { | 1318 | if (ret) { |
1293 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 1319 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
1294 | "firmware2 upload post-proc failure"); | 1320 | "firmware2 upload post-proc failure"); |
1295 | } | 1321 | } |
1322 | |||
1323 | done: | ||
1324 | if (hdw->hdw_desc->signal_routing_scheme == | ||
1325 | PVR2_ROUTING_SCHEME_GOTVIEW) { | ||
1326 | /* Ensure that GPIO 11 is set to output for GOTVIEW | ||
1327 | hardware. */ | ||
1328 | pvr2_hdw_gpio_chg_dir(hdw,(1 << 11),~0); | ||
1329 | } | ||
1296 | return ret; | 1330 | return ret; |
1297 | } | 1331 | } |
1298 | 1332 | ||
@@ -1364,11 +1398,6 @@ int pvr2_hdw_untrip(struct pvr2_hdw *hdw) | |||
1364 | } | 1398 | } |
1365 | 1399 | ||
1366 | 1400 | ||
1367 | const char *pvr2_hdw_get_state_name(unsigned int id) | ||
1368 | { | ||
1369 | if (id >= ARRAY_SIZE(pvr2_state_names)) return NULL; | ||
1370 | return pvr2_state_names[id]; | ||
1371 | } | ||
1372 | 1401 | ||
1373 | 1402 | ||
1374 | int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw) | 1403 | int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw) |
@@ -1495,7 +1524,7 @@ struct pvr2_std_hack { | |||
1495 | default - which can always be overridden explicitly - and if the user | 1524 | default - which can always be overridden explicitly - and if the user |
1496 | has otherwise named a default then that default will always be used in | 1525 | has otherwise named a default then that default will always be used in |
1497 | place of this table. */ | 1526 | place of this table. */ |
1498 | const static struct pvr2_std_hack std_eeprom_maps[] = { | 1527 | static const struct pvr2_std_hack std_eeprom_maps[] = { |
1499 | { /* PAL(B/G) */ | 1528 | { /* PAL(B/G) */ |
1500 | .pat = V4L2_STD_B|V4L2_STD_GH, | 1529 | .pat = V4L2_STD_B|V4L2_STD_GH, |
1501 | .std = V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_PAL_G, | 1530 | .std = V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_PAL_G, |
@@ -1712,6 +1741,13 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) | |||
1712 | 1741 | ||
1713 | if (!pvr2_hdw_dev_ok(hdw)) return; | 1742 | if (!pvr2_hdw_dev_ok(hdw)) return; |
1714 | 1743 | ||
1744 | if (hdw->hdw_desc->signal_routing_scheme == | ||
1745 | PVR2_ROUTING_SCHEME_GOTVIEW) { | ||
1746 | /* Ensure that GPIO 11 is set to output for GOTVIEW | ||
1747 | hardware. */ | ||
1748 | pvr2_hdw_gpio_chg_dir(hdw,(1 << 11),~0); | ||
1749 | } | ||
1750 | |||
1715 | pvr2_hdw_commit_setup(hdw); | 1751 | pvr2_hdw_commit_setup(hdw); |
1716 | 1752 | ||
1717 | hdw->vid_stream = pvr2_stream_create(); | 1753 | hdw->vid_stream = pvr2_stream_create(); |
@@ -1805,12 +1841,37 @@ static void pvr2_hdw_setup(struct pvr2_hdw *hdw) | |||
1805 | } | 1841 | } |
1806 | 1842 | ||
1807 | 1843 | ||
1808 | /* Create and return a structure for interacting with the underlying | 1844 | /* Perform second stage initialization. Set callback pointer first so that |
1809 | hardware */ | 1845 | we can avoid a possible initialization race (if the kernel thread runs |
1846 | before the callback has been set). */ | ||
1847 | int pvr2_hdw_initialize(struct pvr2_hdw *hdw, | ||
1848 | void (*callback_func)(void *), | ||
1849 | void *callback_data) | ||
1850 | { | ||
1851 | LOCK_TAKE(hdw->big_lock); do { | ||
1852 | if (hdw->flag_disconnected) { | ||
1853 | /* Handle a race here: If we're already | ||
1854 | disconnected by this point, then give up. If we | ||
1855 | get past this then we'll remain connected for | ||
1856 | the duration of initialization since the entire | ||
1857 | initialization sequence is now protected by the | ||
1858 | big_lock. */ | ||
1859 | break; | ||
1860 | } | ||
1861 | hdw->state_data = callback_data; | ||
1862 | hdw->state_func = callback_func; | ||
1863 | pvr2_hdw_setup(hdw); | ||
1864 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
1865 | return hdw->flag_init_ok; | ||
1866 | } | ||
1867 | |||
1868 | |||
1869 | /* Create, set up, and return a structure for interacting with the | ||
1870 | underlying hardware. */ | ||
1810 | struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | 1871 | struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, |
1811 | const struct usb_device_id *devid) | 1872 | const struct usb_device_id *devid) |
1812 | { | 1873 | { |
1813 | unsigned int idx,cnt1,cnt2; | 1874 | unsigned int idx,cnt1,cnt2,m; |
1814 | struct pvr2_hdw *hdw; | 1875 | struct pvr2_hdw *hdw; |
1815 | int valid_std_mask; | 1876 | int valid_std_mask; |
1816 | struct pvr2_ctrl *cptr; | 1877 | struct pvr2_ctrl *cptr; |
@@ -1834,6 +1895,10 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1834 | hdw->encoder_wait_timer.data = (unsigned long)hdw; | 1895 | hdw->encoder_wait_timer.data = (unsigned long)hdw; |
1835 | hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout; | 1896 | hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout; |
1836 | 1897 | ||
1898 | init_timer(&hdw->encoder_run_timer); | ||
1899 | hdw->encoder_run_timer.data = (unsigned long)hdw; | ||
1900 | hdw->encoder_run_timer.function = pvr2_hdw_encoder_run_timeout; | ||
1901 | |||
1837 | hdw->master_state = PVR2_STATE_DEAD; | 1902 | hdw->master_state = PVR2_STATE_DEAD; |
1838 | 1903 | ||
1839 | init_waitqueue_head(&hdw->state_wait_data); | 1904 | init_waitqueue_head(&hdw->state_wait_data); |
@@ -1841,6 +1906,26 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1841 | hdw->tuner_signal_stale = !0; | 1906 | hdw->tuner_signal_stale = !0; |
1842 | cx2341x_fill_defaults(&hdw->enc_ctl_state); | 1907 | cx2341x_fill_defaults(&hdw->enc_ctl_state); |
1843 | 1908 | ||
1909 | /* Calculate which inputs are OK */ | ||
1910 | m = 0; | ||
1911 | if (hdw_desc->flag_has_analogtuner) m |= 1 << PVR2_CVAL_INPUT_TV; | ||
1912 | if (hdw_desc->digital_control_scheme != PVR2_DIGITAL_SCHEME_NONE) { | ||
1913 | m |= 1 << PVR2_CVAL_INPUT_DTV; | ||
1914 | } | ||
1915 | if (hdw_desc->flag_has_svideo) m |= 1 << PVR2_CVAL_INPUT_SVIDEO; | ||
1916 | if (hdw_desc->flag_has_composite) m |= 1 << PVR2_CVAL_INPUT_COMPOSITE; | ||
1917 | if (hdw_desc->flag_has_fmradio) m |= 1 << PVR2_CVAL_INPUT_RADIO; | ||
1918 | hdw->input_avail_mask = m; | ||
1919 | hdw->input_allowed_mask = hdw->input_avail_mask; | ||
1920 | |||
1921 | /* If not a hybrid device, pathway_state never changes. So | ||
1922 | initialize it here to what it should forever be. */ | ||
1923 | if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_DTV))) { | ||
1924 | hdw->pathway_state = PVR2_PATHWAY_ANALOG; | ||
1925 | } else if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_TV))) { | ||
1926 | hdw->pathway_state = PVR2_PATHWAY_DIGITAL; | ||
1927 | } | ||
1928 | |||
1844 | hdw->control_cnt = CTRLDEF_COUNT; | 1929 | hdw->control_cnt = CTRLDEF_COUNT; |
1845 | hdw->control_cnt += MPEGDEF_COUNT; | 1930 | hdw->control_cnt += MPEGDEF_COUNT; |
1846 | hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt, | 1931 | hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt, |
@@ -1858,6 +1943,15 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1858 | cptr = hdw->controls + idx; | 1943 | cptr = hdw->controls + idx; |
1859 | cptr->info = control_defs+idx; | 1944 | cptr->info = control_defs+idx; |
1860 | } | 1945 | } |
1946 | |||
1947 | /* Ensure that default input choice is a valid one. */ | ||
1948 | m = hdw->input_avail_mask; | ||
1949 | if (m) for (idx = 0; idx < (sizeof(m) << 3); idx++) { | ||
1950 | if (!((1 << idx) & m)) continue; | ||
1951 | hdw->input_val = idx; | ||
1952 | break; | ||
1953 | } | ||
1954 | |||
1861 | /* Define and configure additional controls from cx2341x module. */ | 1955 | /* Define and configure additional controls from cx2341x module. */ |
1862 | hdw->mpeg_ctrl_info = kzalloc( | 1956 | hdw->mpeg_ctrl_info = kzalloc( |
1863 | sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL); | 1957 | sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL); |
@@ -1981,7 +2075,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1981 | hdw->workqueue = create_singlethread_workqueue(hdw->name); | 2075 | hdw->workqueue = create_singlethread_workqueue(hdw->name); |
1982 | INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll); | 2076 | INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll); |
1983 | INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c); | 2077 | INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c); |
1984 | INIT_WORK(&hdw->workinit,pvr2_hdw_worker_init); | ||
1985 | 2078 | ||
1986 | pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", | 2079 | pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", |
1987 | hdw->unit_number,hdw->name); | 2080 | hdw->unit_number,hdw->name); |
@@ -2003,11 +2096,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
2003 | mutex_init(&hdw->ctl_lock_mutex); | 2096 | mutex_init(&hdw->ctl_lock_mutex); |
2004 | mutex_init(&hdw->big_lock_mutex); | 2097 | mutex_init(&hdw->big_lock_mutex); |
2005 | 2098 | ||
2006 | queue_work(hdw->workqueue,&hdw->workinit); | ||
2007 | return hdw; | 2099 | return hdw; |
2008 | fail: | 2100 | fail: |
2009 | if (hdw) { | 2101 | if (hdw) { |
2010 | del_timer_sync(&hdw->quiescent_timer); | 2102 | del_timer_sync(&hdw->quiescent_timer); |
2103 | del_timer_sync(&hdw->encoder_run_timer); | ||
2011 | del_timer_sync(&hdw->encoder_wait_timer); | 2104 | del_timer_sync(&hdw->encoder_wait_timer); |
2012 | if (hdw->workqueue) { | 2105 | if (hdw->workqueue) { |
2013 | flush_workqueue(hdw->workqueue); | 2106 | flush_workqueue(hdw->workqueue); |
@@ -2064,13 +2157,14 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) | |||
2064 | { | 2157 | { |
2065 | if (!hdw) return; | 2158 | if (!hdw) return; |
2066 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw); | 2159 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw); |
2067 | del_timer_sync(&hdw->quiescent_timer); | ||
2068 | del_timer_sync(&hdw->encoder_wait_timer); | ||
2069 | if (hdw->workqueue) { | 2160 | if (hdw->workqueue) { |
2070 | flush_workqueue(hdw->workqueue); | 2161 | flush_workqueue(hdw->workqueue); |
2071 | destroy_workqueue(hdw->workqueue); | 2162 | destroy_workqueue(hdw->workqueue); |
2072 | hdw->workqueue = NULL; | 2163 | hdw->workqueue = NULL; |
2073 | } | 2164 | } |
2165 | del_timer_sync(&hdw->quiescent_timer); | ||
2166 | del_timer_sync(&hdw->encoder_run_timer); | ||
2167 | del_timer_sync(&hdw->encoder_wait_timer); | ||
2074 | if (hdw->fw_buffer) { | 2168 | if (hdw->fw_buffer) { |
2075 | kfree(hdw->fw_buffer); | 2169 | kfree(hdw->fw_buffer); |
2076 | hdw->fw_buffer = NULL; | 2170 | hdw->fw_buffer = NULL; |
@@ -2352,6 +2446,18 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) | |||
2352 | } | 2446 | } |
2353 | } | 2447 | } |
2354 | 2448 | ||
2449 | if (hdw->input_dirty && hdw->state_pathway_ok && | ||
2450 | (((hdw->input_val == PVR2_CVAL_INPUT_DTV) ? | ||
2451 | PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG) != | ||
2452 | hdw->pathway_state)) { | ||
2453 | /* Change of mode being asked for... */ | ||
2454 | hdw->state_pathway_ok = 0; | ||
2455 | trace_stbit("state_pathway_ok",hdw->state_pathway_ok); | ||
2456 | } | ||
2457 | if (!hdw->state_pathway_ok) { | ||
2458 | /* Can't commit anything until pathway is ok. */ | ||
2459 | return 0; | ||
2460 | } | ||
2355 | /* If any of the below has changed, then we can't do the update | 2461 | /* If any of the below has changed, then we can't do the update |
2356 | while the pipeline is running. Pipeline must be paused first | 2462 | while the pipeline is running. Pipeline must be paused first |
2357 | and decoder -> encoder connection be made quiescent before we | 2463 | and decoder -> encoder connection be made quiescent before we |
@@ -2405,12 +2511,28 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) | |||
2405 | hdw->active_stream_type = hdw->desired_stream_type; | 2511 | hdw->active_stream_type = hdw->desired_stream_type; |
2406 | } | 2512 | } |
2407 | 2513 | ||
2514 | if (hdw->hdw_desc->signal_routing_scheme == | ||
2515 | PVR2_ROUTING_SCHEME_GOTVIEW) { | ||
2516 | u32 b; | ||
2517 | /* Handle GOTVIEW audio switching */ | ||
2518 | pvr2_hdw_gpio_get_out(hdw,&b); | ||
2519 | if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { | ||
2520 | /* Set GPIO 11 */ | ||
2521 | pvr2_hdw_gpio_chg_out(hdw,(1 << 11),~0); | ||
2522 | } else { | ||
2523 | /* Clear GPIO 11 */ | ||
2524 | pvr2_hdw_gpio_chg_out(hdw,(1 << 11),0); | ||
2525 | } | ||
2526 | } | ||
2527 | |||
2408 | /* Now execute i2c core update */ | 2528 | /* Now execute i2c core update */ |
2409 | pvr2_i2c_core_sync(hdw); | 2529 | pvr2_i2c_core_sync(hdw); |
2410 | 2530 | ||
2411 | if (hdw->state_encoder_run) { | 2531 | if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) && |
2412 | /* If encoder isn't running, then this will get worked out | 2532 | hdw->state_encoder_run) { |
2413 | later when we start the encoder. */ | 2533 | /* If encoder isn't running or it can't be touched, then |
2534 | this will get worked out later when we start the | ||
2535 | encoder. */ | ||
2414 | if (pvr2_encoder_adjust(hdw) < 0) return !0; | 2536 | if (pvr2_encoder_adjust(hdw) < 0) return !0; |
2415 | } | 2537 | } |
2416 | 2538 | ||
@@ -2453,15 +2575,6 @@ static void pvr2_hdw_worker_poll(struct work_struct *work) | |||
2453 | } | 2575 | } |
2454 | 2576 | ||
2455 | 2577 | ||
2456 | static void pvr2_hdw_worker_init(struct work_struct *work) | ||
2457 | { | ||
2458 | struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,workinit); | ||
2459 | LOCK_TAKE(hdw->big_lock); do { | ||
2460 | pvr2_hdw_setup(hdw); | ||
2461 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2462 | } | ||
2463 | |||
2464 | |||
2465 | static int pvr2_hdw_wait(struct pvr2_hdw *hdw,int state) | 2578 | static int pvr2_hdw_wait(struct pvr2_hdw *hdw,int state) |
2466 | { | 2579 | { |
2467 | return wait_event_interruptible( | 2580 | return wait_event_interruptible( |
@@ -2471,17 +2584,6 @@ static int pvr2_hdw_wait(struct pvr2_hdw *hdw,int state) | |||
2471 | } | 2584 | } |
2472 | 2585 | ||
2473 | 2586 | ||
2474 | void pvr2_hdw_set_state_callback(struct pvr2_hdw *hdw, | ||
2475 | void (*callback_func)(void *), | ||
2476 | void *callback_data) | ||
2477 | { | ||
2478 | LOCK_TAKE(hdw->big_lock); do { | ||
2479 | hdw->state_data = callback_data; | ||
2480 | hdw->state_func = callback_func; | ||
2481 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2482 | } | ||
2483 | |||
2484 | |||
2485 | /* Return name for this driver instance */ | 2587 | /* Return name for this driver instance */ |
2486 | const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) | 2588 | const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) |
2487 | { | 2589 | { |
@@ -3050,6 +3152,67 @@ int pvr2_send_request(struct pvr2_hdw *hdw, | |||
3050 | read_data,read_len); | 3152 | read_data,read_len); |
3051 | } | 3153 | } |
3052 | 3154 | ||
3155 | |||
3156 | static int pvr2_issue_simple_cmd(struct pvr2_hdw *hdw,u32 cmdcode) | ||
3157 | { | ||
3158 | int ret; | ||
3159 | unsigned int cnt = 1; | ||
3160 | unsigned int args = 0; | ||
3161 | LOCK_TAKE(hdw->ctl_lock); | ||
3162 | hdw->cmd_buffer[0] = cmdcode & 0xffu; | ||
3163 | args = (cmdcode >> 8) & 0xffu; | ||
3164 | args = (args > 2) ? 2 : args; | ||
3165 | if (args) { | ||
3166 | cnt += args; | ||
3167 | hdw->cmd_buffer[1] = (cmdcode >> 16) & 0xffu; | ||
3168 | if (args > 1) { | ||
3169 | hdw->cmd_buffer[2] = (cmdcode >> 24) & 0xffu; | ||
3170 | } | ||
3171 | } | ||
3172 | if (pvrusb2_debug & PVR2_TRACE_INIT) { | ||
3173 | unsigned int idx; | ||
3174 | unsigned int ccnt,bcnt; | ||
3175 | char tbuf[50]; | ||
3176 | cmdcode &= 0xffu; | ||
3177 | bcnt = 0; | ||
3178 | ccnt = scnprintf(tbuf+bcnt, | ||
3179 | sizeof(tbuf)-bcnt, | ||
3180 | "Sending FX2 command 0x%x",cmdcode); | ||
3181 | bcnt += ccnt; | ||
3182 | for (idx = 0; idx < ARRAY_SIZE(pvr2_fx2cmd_desc); idx++) { | ||
3183 | if (pvr2_fx2cmd_desc[idx].id == cmdcode) { | ||
3184 | ccnt = scnprintf(tbuf+bcnt, | ||
3185 | sizeof(tbuf)-bcnt, | ||
3186 | " \"%s\"", | ||
3187 | pvr2_fx2cmd_desc[idx].desc); | ||
3188 | bcnt += ccnt; | ||
3189 | break; | ||
3190 | } | ||
3191 | } | ||
3192 | if (args) { | ||
3193 | ccnt = scnprintf(tbuf+bcnt, | ||
3194 | sizeof(tbuf)-bcnt, | ||
3195 | " (%u",hdw->cmd_buffer[1]); | ||
3196 | bcnt += ccnt; | ||
3197 | if (args > 1) { | ||
3198 | ccnt = scnprintf(tbuf+bcnt, | ||
3199 | sizeof(tbuf)-bcnt, | ||
3200 | ",%u",hdw->cmd_buffer[2]); | ||
3201 | bcnt += ccnt; | ||
3202 | } | ||
3203 | ccnt = scnprintf(tbuf+bcnt, | ||
3204 | sizeof(tbuf)-bcnt, | ||
3205 | ")"); | ||
3206 | bcnt += ccnt; | ||
3207 | } | ||
3208 | pvr2_trace(PVR2_TRACE_INIT,"%.*s",bcnt,tbuf); | ||
3209 | } | ||
3210 | ret = pvr2_send_request(hdw,hdw->cmd_buffer,cnt,NULL,0); | ||
3211 | LOCK_GIVE(hdw->ctl_lock); | ||
3212 | return ret; | ||
3213 | } | ||
3214 | |||
3215 | |||
3053 | int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) | 3216 | int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) |
3054 | { | 3217 | { |
3055 | int ret; | 3218 | int ret; |
@@ -3157,25 +3320,19 @@ void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) | |||
3157 | 3320 | ||
3158 | int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) | 3321 | int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) |
3159 | { | 3322 | { |
3160 | int status; | 3323 | return pvr2_issue_simple_cmd(hdw,FX2CMD_DEEP_RESET); |
3161 | LOCK_TAKE(hdw->ctl_lock); do { | ||
3162 | pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset"); | ||
3163 | hdw->cmd_buffer[0] = FX2CMD_DEEP_RESET; | ||
3164 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | ||
3165 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
3166 | return status; | ||
3167 | } | 3324 | } |
3168 | 3325 | ||
3169 | 3326 | ||
3170 | int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) | 3327 | int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) |
3171 | { | 3328 | { |
3172 | int status; | 3329 | return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_ON); |
3173 | LOCK_TAKE(hdw->ctl_lock); do { | 3330 | } |
3174 | pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup"); | 3331 | |
3175 | hdw->cmd_buffer[0] = FX2CMD_POWER_ON; | 3332 | |
3176 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | 3333 | int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw) |
3177 | } while (0); LOCK_GIVE(hdw->ctl_lock); | 3334 | { |
3178 | return status; | 3335 | return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_OFF); |
3179 | } | 3336 | } |
3180 | 3337 | ||
3181 | 3338 | ||
@@ -3200,16 +3357,173 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) | |||
3200 | } | 3357 | } |
3201 | 3358 | ||
3202 | 3359 | ||
3360 | static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff) | ||
3361 | { | ||
3362 | hdw->flag_ok = !0; | ||
3363 | return pvr2_issue_simple_cmd(hdw, | ||
3364 | FX2CMD_HCW_DEMOD_RESETIN | | ||
3365 | (1 << 8) | | ||
3366 | ((onoff ? 1 : 0) << 16)); | ||
3367 | } | ||
3368 | |||
3369 | |||
3370 | static int pvr2_hdw_cmd_onair_fe_power_ctrl(struct pvr2_hdw *hdw, int onoff) | ||
3371 | { | ||
3372 | hdw->flag_ok = !0; | ||
3373 | return pvr2_issue_simple_cmd(hdw,(onoff ? | ||
3374 | FX2CMD_ONAIR_DTV_POWER_ON : | ||
3375 | FX2CMD_ONAIR_DTV_POWER_OFF)); | ||
3376 | } | ||
3377 | |||
3378 | |||
3379 | static int pvr2_hdw_cmd_onair_digital_path_ctrl(struct pvr2_hdw *hdw, | ||
3380 | int onoff) | ||
3381 | { | ||
3382 | return pvr2_issue_simple_cmd(hdw,(onoff ? | ||
3383 | FX2CMD_ONAIR_DTV_STREAMING_ON : | ||
3384 | FX2CMD_ONAIR_DTV_STREAMING_OFF)); | ||
3385 | } | ||
3386 | |||
3387 | |||
3388 | static void pvr2_hdw_cmd_modeswitch(struct pvr2_hdw *hdw,int digitalFl) | ||
3389 | { | ||
3390 | int cmode; | ||
3391 | /* Compare digital/analog desired setting with current setting. If | ||
3392 | they don't match, fix it... */ | ||
3393 | cmode = (digitalFl ? PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG); | ||
3394 | if (cmode == hdw->pathway_state) { | ||
3395 | /* They match; nothing to do */ | ||
3396 | return; | ||
3397 | } | ||
3398 | |||
3399 | switch (hdw->hdw_desc->digital_control_scheme) { | ||
3400 | case PVR2_DIGITAL_SCHEME_HAUPPAUGE: | ||
3401 | pvr2_hdw_cmd_hcw_demod_reset(hdw,digitalFl); | ||
3402 | if (cmode == PVR2_PATHWAY_ANALOG) { | ||
3403 | /* If moving to analog mode, also force the decoder | ||
3404 | to reset. If no decoder is attached, then it's | ||
3405 | ok to ignore this because if/when the decoder | ||
3406 | attaches, it will reset itself at that time. */ | ||
3407 | pvr2_hdw_cmd_decoder_reset(hdw); | ||
3408 | } | ||
3409 | break; | ||
3410 | case PVR2_DIGITAL_SCHEME_ONAIR: | ||
3411 | /* Supposedly we should always have the power on whether in | ||
3412 | digital or analog mode. But for now do what appears to | ||
3413 | work... */ | ||
3414 | pvr2_hdw_cmd_onair_fe_power_ctrl(hdw,digitalFl); | ||
3415 | break; | ||
3416 | default: break; | ||
3417 | } | ||
3418 | |||
3419 | pvr2_hdw_untrip_unlocked(hdw); | ||
3420 | hdw->pathway_state = cmode; | ||
3421 | } | ||
3422 | |||
3423 | |||
3424 | void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff) | ||
3425 | { | ||
3426 | /* change some GPIO data | ||
3427 | * | ||
3428 | * note: bit d7 of dir appears to control the LED, | ||
3429 | * so we shut it off here. | ||
3430 | * | ||
3431 | */ | ||
3432 | if (onoff) { | ||
3433 | pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000481); | ||
3434 | } else { | ||
3435 | pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000401); | ||
3436 | } | ||
3437 | pvr2_hdw_gpio_chg_out(hdw, 0xffffffff, 0x00000000); | ||
3438 | } | ||
3439 | |||
3440 | |||
3441 | typedef void (*led_method_func)(struct pvr2_hdw *,int); | ||
3442 | |||
3443 | static led_method_func led_methods[] = { | ||
3444 | [PVR2_LED_SCHEME_HAUPPAUGE] = pvr2_led_ctrl_hauppauge, | ||
3445 | }; | ||
3446 | |||
3447 | |||
3448 | /* Toggle LED */ | ||
3449 | static void pvr2_led_ctrl(struct pvr2_hdw *hdw,int onoff) | ||
3450 | { | ||
3451 | unsigned int scheme_id; | ||
3452 | led_method_func fp; | ||
3453 | |||
3454 | if ((!onoff) == (!hdw->led_on)) return; | ||
3455 | |||
3456 | hdw->led_on = onoff != 0; | ||
3457 | |||
3458 | scheme_id = hdw->hdw_desc->led_scheme; | ||
3459 | if (scheme_id < ARRAY_SIZE(led_methods)) { | ||
3460 | fp = led_methods[scheme_id]; | ||
3461 | } else { | ||
3462 | fp = NULL; | ||
3463 | } | ||
3464 | |||
3465 | if (fp) (*fp)(hdw,onoff); | ||
3466 | } | ||
3467 | |||
3468 | |||
3203 | /* Stop / start video stream transport */ | 3469 | /* Stop / start video stream transport */ |
3204 | static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) | 3470 | static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) |
3205 | { | 3471 | { |
3206 | int status; | 3472 | int ret; |
3207 | LOCK_TAKE(hdw->ctl_lock); do { | 3473 | |
3208 | hdw->cmd_buffer[0] = | 3474 | /* If we're in analog mode, then just issue the usual analog |
3209 | (runFl ? FX2CMD_STREAMING_ON : FX2CMD_STREAMING_OFF); | 3475 | command. */ |
3210 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | 3476 | if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) { |
3211 | } while (0); LOCK_GIVE(hdw->ctl_lock); | 3477 | return pvr2_issue_simple_cmd(hdw, |
3212 | return status; | 3478 | (runFl ? |
3479 | FX2CMD_STREAMING_ON : | ||
3480 | FX2CMD_STREAMING_OFF)); | ||
3481 | /*Note: Not reached */ | ||
3482 | } | ||
3483 | |||
3484 | if (hdw->pathway_state != PVR2_PATHWAY_DIGITAL) { | ||
3485 | /* Whoops, we don't know what mode we're in... */ | ||
3486 | return -EINVAL; | ||
3487 | } | ||
3488 | |||
3489 | /* To get here we have to be in digital mode. The mechanism here | ||
3490 | is unfortunately different for different vendors. So we switch | ||
3491 | on the device's digital scheme attribute in order to figure out | ||
3492 | what to do. */ | ||
3493 | switch (hdw->hdw_desc->digital_control_scheme) { | ||
3494 | case PVR2_DIGITAL_SCHEME_HAUPPAUGE: | ||
3495 | return pvr2_issue_simple_cmd(hdw, | ||
3496 | (runFl ? | ||
3497 | FX2CMD_HCW_DTV_STREAMING_ON : | ||
3498 | FX2CMD_HCW_DTV_STREAMING_OFF)); | ||
3499 | case PVR2_DIGITAL_SCHEME_ONAIR: | ||
3500 | ret = pvr2_issue_simple_cmd(hdw, | ||
3501 | (runFl ? | ||
3502 | FX2CMD_STREAMING_ON : | ||
3503 | FX2CMD_STREAMING_OFF)); | ||
3504 | if (ret) return ret; | ||
3505 | return pvr2_hdw_cmd_onair_digital_path_ctrl(hdw,runFl); | ||
3506 | default: | ||
3507 | return -EINVAL; | ||
3508 | } | ||
3509 | } | ||
3510 | |||
3511 | |||
3512 | /* Evaluate whether or not state_pathway_ok can change */ | ||
3513 | static int state_eval_pathway_ok(struct pvr2_hdw *hdw) | ||
3514 | { | ||
3515 | if (hdw->state_pathway_ok) { | ||
3516 | /* Nothing to do if pathway is already ok */ | ||
3517 | return 0; | ||
3518 | } | ||
3519 | if (!hdw->state_pipeline_idle) { | ||
3520 | /* Not allowed to change anything if pipeline is not idle */ | ||
3521 | return 0; | ||
3522 | } | ||
3523 | pvr2_hdw_cmd_modeswitch(hdw,hdw->input_val == PVR2_CVAL_INPUT_DTV); | ||
3524 | hdw->state_pathway_ok = !0; | ||
3525 | trace_stbit("state_pathway_ok",hdw->state_pathway_ok); | ||
3526 | return !0; | ||
3213 | } | 3527 | } |
3214 | 3528 | ||
3215 | 3529 | ||
@@ -3222,6 +3536,12 @@ static int state_eval_encoder_ok(struct pvr2_hdw *hdw) | |||
3222 | if (hdw->state_encoder_config) return 0; | 3536 | if (hdw->state_encoder_config) return 0; |
3223 | if (hdw->state_decoder_run) return 0; | 3537 | if (hdw->state_decoder_run) return 0; |
3224 | if (hdw->state_usbstream_run) return 0; | 3538 | if (hdw->state_usbstream_run) return 0; |
3539 | if (hdw->pathway_state == PVR2_PATHWAY_DIGITAL) { | ||
3540 | if (!hdw->hdw_desc->flag_digital_requires_cx23416) return 0; | ||
3541 | } else if (hdw->pathway_state != PVR2_PATHWAY_ANALOG) { | ||
3542 | return 0; | ||
3543 | } | ||
3544 | |||
3225 | if (pvr2_upload_firmware2(hdw) < 0) { | 3545 | if (pvr2_upload_firmware2(hdw) < 0) { |
3226 | hdw->flag_tripped = !0; | 3546 | hdw->flag_tripped = !0; |
3227 | trace_stbit("flag_tripped",hdw->flag_tripped); | 3547 | trace_stbit("flag_tripped",hdw->flag_tripped); |
@@ -3247,7 +3567,9 @@ static int state_eval_encoder_config(struct pvr2_hdw *hdw) | |||
3247 | /* paranoia - solve race if timer just completed */ | 3567 | /* paranoia - solve race if timer just completed */ |
3248 | del_timer_sync(&hdw->encoder_wait_timer); | 3568 | del_timer_sync(&hdw->encoder_wait_timer); |
3249 | } else { | 3569 | } else { |
3250 | if (!hdw->state_encoder_ok || | 3570 | if (!hdw->state_pathway_ok || |
3571 | (hdw->pathway_state != PVR2_PATHWAY_ANALOG) || | ||
3572 | !hdw->state_encoder_ok || | ||
3251 | !hdw->state_pipeline_idle || | 3573 | !hdw->state_pipeline_idle || |
3252 | hdw->state_pipeline_pause || | 3574 | hdw->state_pipeline_pause || |
3253 | !hdw->state_pipeline_req || | 3575 | !hdw->state_pipeline_req || |
@@ -3296,20 +3618,116 @@ static int state_eval_encoder_config(struct pvr2_hdw *hdw) | |||
3296 | } | 3618 | } |
3297 | 3619 | ||
3298 | 3620 | ||
3621 | /* Return true if the encoder should not be running. */ | ||
3622 | static int state_check_disable_encoder_run(struct pvr2_hdw *hdw) | ||
3623 | { | ||
3624 | if (!hdw->state_encoder_ok) { | ||
3625 | /* Encoder isn't healthy at the moment, so stop it. */ | ||
3626 | return !0; | ||
3627 | } | ||
3628 | if (!hdw->state_pathway_ok) { | ||
3629 | /* Mode is not understood at the moment (i.e. it wants to | ||
3630 | change), so encoder must be stopped. */ | ||
3631 | return !0; | ||
3632 | } | ||
3633 | |||
3634 | switch (hdw->pathway_state) { | ||
3635 | case PVR2_PATHWAY_ANALOG: | ||
3636 | if (!hdw->state_decoder_run) { | ||
3637 | /* We're in analog mode and the decoder is not | ||
3638 | running; thus the encoder should be stopped as | ||
3639 | well. */ | ||
3640 | return !0; | ||
3641 | } | ||
3642 | break; | ||
3643 | case PVR2_PATHWAY_DIGITAL: | ||
3644 | if (hdw->state_encoder_runok) { | ||
3645 | /* This is a funny case. We're in digital mode so | ||
3646 | really the encoder should be stopped. However | ||
3647 | if it really is running, only kill it after | ||
3648 | runok has been set. This gives a chance for the | ||
3649 | onair quirk to function (encoder must run | ||
3650 | briefly first, at least once, before onair | ||
3651 | digital streaming can work). */ | ||
3652 | return !0; | ||
3653 | } | ||
3654 | break; | ||
3655 | default: | ||
3656 | /* Unknown mode; so encoder should be stopped. */ | ||
3657 | return !0; | ||
3658 | } | ||
3659 | |||
3660 | /* If we get here, we haven't found a reason to stop the | ||
3661 | encoder. */ | ||
3662 | return 0; | ||
3663 | } | ||
3664 | |||
3665 | |||
3666 | /* Return true if the encoder should be running. */ | ||
3667 | static int state_check_enable_encoder_run(struct pvr2_hdw *hdw) | ||
3668 | { | ||
3669 | if (!hdw->state_encoder_ok) { | ||
3670 | /* Don't run the encoder if it isn't healthy... */ | ||
3671 | return 0; | ||
3672 | } | ||
3673 | if (!hdw->state_pathway_ok) { | ||
3674 | /* Don't run the encoder if we don't (yet) know what mode | ||
3675 | we need to be in... */ | ||
3676 | return 0; | ||
3677 | } | ||
3678 | |||
3679 | switch (hdw->pathway_state) { | ||
3680 | case PVR2_PATHWAY_ANALOG: | ||
3681 | if (hdw->state_decoder_run) { | ||
3682 | /* In analog mode, if the decoder is running, then | ||
3683 | run the encoder. */ | ||
3684 | return !0; | ||
3685 | } | ||
3686 | break; | ||
3687 | case PVR2_PATHWAY_DIGITAL: | ||
3688 | if ((hdw->hdw_desc->digital_control_scheme == | ||
3689 | PVR2_DIGITAL_SCHEME_ONAIR) && | ||
3690 | !hdw->state_encoder_runok) { | ||
3691 | /* This is a quirk. OnAir hardware won't stream | ||
3692 | digital until the encoder has been run at least | ||
3693 | once, for a minimal period of time (empiricially | ||
3694 | measured to be 1/4 second). So if we're on | ||
3695 | OnAir hardware and the encoder has never been | ||
3696 | run at all, then start the encoder. Normal | ||
3697 | state machine logic in the driver will | ||
3698 | automatically handle the remaining bits. */ | ||
3699 | return !0; | ||
3700 | } | ||
3701 | break; | ||
3702 | default: | ||
3703 | /* For completeness (unknown mode; encoder won't run ever) */ | ||
3704 | break; | ||
3705 | } | ||
3706 | /* If we get here, then we haven't found any reason to run the | ||
3707 | encoder, so don't run it. */ | ||
3708 | return 0; | ||
3709 | } | ||
3710 | |||
3711 | |||
3299 | /* Evaluate whether or not state_encoder_run can change */ | 3712 | /* Evaluate whether or not state_encoder_run can change */ |
3300 | static int state_eval_encoder_run(struct pvr2_hdw *hdw) | 3713 | static int state_eval_encoder_run(struct pvr2_hdw *hdw) |
3301 | { | 3714 | { |
3302 | if (hdw->state_encoder_run) { | 3715 | if (hdw->state_encoder_run) { |
3716 | if (!state_check_disable_encoder_run(hdw)) return 0; | ||
3303 | if (hdw->state_encoder_ok) { | 3717 | if (hdw->state_encoder_ok) { |
3304 | if (hdw->state_decoder_run) return 0; | 3718 | del_timer_sync(&hdw->encoder_run_timer); |
3305 | if (pvr2_encoder_stop(hdw) < 0) return !0; | 3719 | if (pvr2_encoder_stop(hdw) < 0) return !0; |
3306 | } | 3720 | } |
3307 | hdw->state_encoder_run = 0; | 3721 | hdw->state_encoder_run = 0; |
3308 | } else { | 3722 | } else { |
3309 | if (!hdw->state_encoder_ok) return 0; | 3723 | if (!state_check_enable_encoder_run(hdw)) return 0; |
3310 | if (!hdw->state_decoder_run) return 0; | ||
3311 | if (pvr2_encoder_start(hdw) < 0) return !0; | 3724 | if (pvr2_encoder_start(hdw) < 0) return !0; |
3312 | hdw->state_encoder_run = !0; | 3725 | hdw->state_encoder_run = !0; |
3726 | if (!hdw->state_encoder_runok) { | ||
3727 | hdw->encoder_run_timer.expires = | ||
3728 | jiffies + (HZ*250/1000); | ||
3729 | add_timer(&hdw->encoder_run_timer); | ||
3730 | } | ||
3313 | } | 3731 | } |
3314 | trace_stbit("state_encoder_run",hdw->state_encoder_run); | 3732 | trace_stbit("state_encoder_run",hdw->state_encoder_run); |
3315 | return !0; | 3733 | return !0; |
@@ -3338,13 +3756,27 @@ static void pvr2_hdw_encoder_wait_timeout(unsigned long data) | |||
3338 | } | 3756 | } |
3339 | 3757 | ||
3340 | 3758 | ||
3759 | /* Timeout function for encoder run timer. */ | ||
3760 | static void pvr2_hdw_encoder_run_timeout(unsigned long data) | ||
3761 | { | ||
3762 | struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; | ||
3763 | if (!hdw->state_encoder_runok) { | ||
3764 | hdw->state_encoder_runok = !0; | ||
3765 | trace_stbit("state_encoder_runok",hdw->state_encoder_runok); | ||
3766 | hdw->state_stale = !0; | ||
3767 | queue_work(hdw->workqueue,&hdw->workpoll); | ||
3768 | } | ||
3769 | } | ||
3770 | |||
3771 | |||
3341 | /* Evaluate whether or not state_decoder_run can change */ | 3772 | /* Evaluate whether or not state_decoder_run can change */ |
3342 | static int state_eval_decoder_run(struct pvr2_hdw *hdw) | 3773 | static int state_eval_decoder_run(struct pvr2_hdw *hdw) |
3343 | { | 3774 | { |
3344 | if (hdw->state_decoder_run) { | 3775 | if (hdw->state_decoder_run) { |
3345 | if (hdw->state_encoder_ok) { | 3776 | if (hdw->state_encoder_ok) { |
3346 | if (hdw->state_pipeline_req && | 3777 | if (hdw->state_pipeline_req && |
3347 | !hdw->state_pipeline_pause) return 0; | 3778 | !hdw->state_pipeline_pause && |
3779 | hdw->state_pathway_ok) return 0; | ||
3348 | } | 3780 | } |
3349 | if (!hdw->flag_decoder_missed) { | 3781 | if (!hdw->flag_decoder_missed) { |
3350 | pvr2_decoder_enable(hdw,0); | 3782 | pvr2_decoder_enable(hdw,0); |
@@ -3377,7 +3809,9 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw) | |||
3377 | hopefully further stabilize the encoder. */ | 3809 | hopefully further stabilize the encoder. */ |
3378 | return 0; | 3810 | return 0; |
3379 | } | 3811 | } |
3380 | if (!hdw->state_pipeline_req || | 3812 | if (!hdw->state_pathway_ok || |
3813 | (hdw->pathway_state != PVR2_PATHWAY_ANALOG) || | ||
3814 | !hdw->state_pipeline_req || | ||
3381 | hdw->state_pipeline_pause || | 3815 | hdw->state_pipeline_pause || |
3382 | !hdw->state_pipeline_config || | 3816 | !hdw->state_pipeline_config || |
3383 | !hdw->state_encoder_config || | 3817 | !hdw->state_encoder_config || |
@@ -3398,16 +3832,43 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw) | |||
3398 | static int state_eval_usbstream_run(struct pvr2_hdw *hdw) | 3832 | static int state_eval_usbstream_run(struct pvr2_hdw *hdw) |
3399 | { | 3833 | { |
3400 | if (hdw->state_usbstream_run) { | 3834 | if (hdw->state_usbstream_run) { |
3401 | if (hdw->state_encoder_ok) { | 3835 | int fl = !0; |
3402 | if (hdw->state_encoder_run) return 0; | 3836 | if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) { |
3837 | fl = (hdw->state_encoder_ok && | ||
3838 | hdw->state_encoder_run); | ||
3839 | } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) && | ||
3840 | (hdw->hdw_desc->flag_digital_requires_cx23416)) { | ||
3841 | fl = hdw->state_encoder_ok; | ||
3842 | } | ||
3843 | if (fl && | ||
3844 | hdw->state_pipeline_req && | ||
3845 | !hdw->state_pipeline_pause && | ||
3846 | hdw->state_pathway_ok) { | ||
3847 | return 0; | ||
3403 | } | 3848 | } |
3404 | pvr2_hdw_cmd_usbstream(hdw,0); | 3849 | pvr2_hdw_cmd_usbstream(hdw,0); |
3405 | hdw->state_usbstream_run = 0; | 3850 | hdw->state_usbstream_run = 0; |
3406 | } else { | 3851 | } else { |
3407 | if (!hdw->state_encoder_ok || | 3852 | if (!hdw->state_pipeline_req || |
3408 | !hdw->state_encoder_run || | 3853 | hdw->state_pipeline_pause || |
3409 | !hdw->state_pipeline_req || | 3854 | !hdw->state_pathway_ok) return 0; |
3410 | hdw->state_pipeline_pause) return 0; | 3855 | if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) { |
3856 | if (!hdw->state_encoder_ok || | ||
3857 | !hdw->state_encoder_run) return 0; | ||
3858 | } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) && | ||
3859 | (hdw->hdw_desc->flag_digital_requires_cx23416)) { | ||
3860 | if (!hdw->state_encoder_ok) return 0; | ||
3861 | if (hdw->state_encoder_run) return 0; | ||
3862 | if (hdw->hdw_desc->digital_control_scheme == | ||
3863 | PVR2_DIGITAL_SCHEME_ONAIR) { | ||
3864 | /* OnAir digital receivers won't stream | ||
3865 | unless the analog encoder has run first. | ||
3866 | Why? I have no idea. But don't even | ||
3867 | try until we know the analog side is | ||
3868 | known to have run. */ | ||
3869 | if (!hdw->state_encoder_runok) return 0; | ||
3870 | } | ||
3871 | } | ||
3411 | if (pvr2_hdw_cmd_usbstream(hdw,!0) < 0) return 0; | 3872 | if (pvr2_hdw_cmd_usbstream(hdw,!0) < 0) return 0; |
3412 | hdw->state_usbstream_run = !0; | 3873 | hdw->state_usbstream_run = !0; |
3413 | } | 3874 | } |
@@ -3453,7 +3914,8 @@ static int state_update_pipeline_state(struct pvr2_hdw *hdw) | |||
3453 | typedef int (*state_eval_func)(struct pvr2_hdw *); | 3914 | typedef int (*state_eval_func)(struct pvr2_hdw *); |
3454 | 3915 | ||
3455 | /* Set of functions to be run to evaluate various states in the driver. */ | 3916 | /* Set of functions to be run to evaluate various states in the driver. */ |
3456 | const static state_eval_func eval_funcs[] = { | 3917 | static const state_eval_func eval_funcs[] = { |
3918 | state_eval_pathway_ok, | ||
3457 | state_eval_pipeline_config, | 3919 | state_eval_pipeline_config, |
3458 | state_eval_encoder_ok, | 3920 | state_eval_encoder_ok, |
3459 | state_eval_encoder_config, | 3921 | state_eval_encoder_config, |
@@ -3501,6 +3963,34 @@ static int pvr2_hdw_state_update(struct pvr2_hdw *hdw) | |||
3501 | } | 3963 | } |
3502 | 3964 | ||
3503 | 3965 | ||
3966 | static unsigned int print_input_mask(unsigned int msk, | ||
3967 | char *buf,unsigned int acnt) | ||
3968 | { | ||
3969 | unsigned int idx,ccnt; | ||
3970 | unsigned int tcnt = 0; | ||
3971 | for (idx = 0; idx < ARRAY_SIZE(control_values_input); idx++) { | ||
3972 | if (!((1 << idx) & msk)) continue; | ||
3973 | ccnt = scnprintf(buf+tcnt, | ||
3974 | acnt-tcnt, | ||
3975 | "%s%s", | ||
3976 | (tcnt ? ", " : ""), | ||
3977 | control_values_input[idx]); | ||
3978 | tcnt += ccnt; | ||
3979 | } | ||
3980 | return tcnt; | ||
3981 | } | ||
3982 | |||
3983 | |||
3984 | static const char *pvr2_pathway_state_name(int id) | ||
3985 | { | ||
3986 | switch (id) { | ||
3987 | case PVR2_PATHWAY_ANALOG: return "analog"; | ||
3988 | case PVR2_PATHWAY_DIGITAL: return "digital"; | ||
3989 | default: return "unknown"; | ||
3990 | } | ||
3991 | } | ||
3992 | |||
3993 | |||
3504 | static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, | 3994 | static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, |
3505 | char *buf,unsigned int acnt) | 3995 | char *buf,unsigned int acnt) |
3506 | { | 3996 | { |
@@ -3508,13 +3998,15 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, | |||
3508 | case 0: | 3998 | case 0: |
3509 | return scnprintf( | 3999 | return scnprintf( |
3510 | buf,acnt, | 4000 | buf,acnt, |
3511 | "driver:%s%s%s%s%s", | 4001 | "driver:%s%s%s%s%s <mode=%s>", |
3512 | (hdw->flag_ok ? " <ok>" : " <fail>"), | 4002 | (hdw->flag_ok ? " <ok>" : " <fail>"), |
3513 | (hdw->flag_init_ok ? " <init>" : " <uninitialized>"), | 4003 | (hdw->flag_init_ok ? " <init>" : " <uninitialized>"), |
3514 | (hdw->flag_disconnected ? " <disconnected>" : | 4004 | (hdw->flag_disconnected ? " <disconnected>" : |
3515 | " <connected>"), | 4005 | " <connected>"), |
3516 | (hdw->flag_tripped ? " <tripped>" : ""), | 4006 | (hdw->flag_tripped ? " <tripped>" : ""), |
3517 | (hdw->flag_decoder_missed ? " <no decoder>" : "")); | 4007 | (hdw->flag_decoder_missed ? " <no decoder>" : ""), |
4008 | pvr2_pathway_state_name(hdw->pathway_state)); | ||
4009 | |||
3518 | case 1: | 4010 | case 1: |
3519 | return scnprintf( | 4011 | return scnprintf( |
3520 | buf,acnt, | 4012 | buf,acnt, |
@@ -3527,7 +4019,7 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, | |||
3527 | case 2: | 4019 | case 2: |
3528 | return scnprintf( | 4020 | return scnprintf( |
3529 | buf,acnt, | 4021 | buf,acnt, |
3530 | "worker:%s%s%s%s%s%s", | 4022 | "worker:%s%s%s%s%s%s%s", |
3531 | (hdw->state_decoder_run ? | 4023 | (hdw->state_decoder_run ? |
3532 | " <decode:run>" : | 4024 | " <decode:run>" : |
3533 | (hdw->state_decoder_quiescent ? | 4025 | (hdw->state_decoder_quiescent ? |
@@ -3537,20 +4029,65 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, | |||
3537 | (hdw->state_encoder_ok ? | 4029 | (hdw->state_encoder_ok ? |
3538 | "" : " <encode:init>"), | 4030 | "" : " <encode:init>"), |
3539 | (hdw->state_encoder_run ? | 4031 | (hdw->state_encoder_run ? |
3540 | " <encode:run>" : " <encode:stop>"), | 4032 | (hdw->state_encoder_runok ? |
4033 | " <encode:run>" : | ||
4034 | " <encode:firstrun>") : | ||
4035 | (hdw->state_encoder_runok ? | ||
4036 | " <encode:stop>" : | ||
4037 | " <encode:virgin>")), | ||
3541 | (hdw->state_encoder_config ? | 4038 | (hdw->state_encoder_config ? |
3542 | " <encode:configok>" : | 4039 | " <encode:configok>" : |
3543 | (hdw->state_encoder_waitok ? | 4040 | (hdw->state_encoder_waitok ? |
3544 | "" : " <encode:wait>")), | 4041 | "" : " <encode:waitok>")), |
3545 | (hdw->state_usbstream_run ? | 4042 | (hdw->state_usbstream_run ? |
3546 | " <usb:run>" : " <usb:stop>")); | 4043 | " <usb:run>" : " <usb:stop>"), |
3547 | break; | 4044 | (hdw->state_pathway_ok ? |
4045 | " <pathway:ok>" : "")); | ||
3548 | case 3: | 4046 | case 3: |
3549 | return scnprintf( | 4047 | return scnprintf( |
3550 | buf,acnt, | 4048 | buf,acnt, |
3551 | "state: %s", | 4049 | "state: %s", |
3552 | pvr2_get_state_name(hdw->master_state)); | 4050 | pvr2_get_state_name(hdw->master_state)); |
3553 | break; | 4051 | case 4: { |
4052 | unsigned int tcnt = 0; | ||
4053 | unsigned int ccnt; | ||
4054 | |||
4055 | ccnt = scnprintf(buf, | ||
4056 | acnt, | ||
4057 | "Hardware supported inputs: "); | ||
4058 | tcnt += ccnt; | ||
4059 | tcnt += print_input_mask(hdw->input_avail_mask, | ||
4060 | buf+tcnt, | ||
4061 | acnt-tcnt); | ||
4062 | if (hdw->input_avail_mask != hdw->input_allowed_mask) { | ||
4063 | ccnt = scnprintf(buf+tcnt, | ||
4064 | acnt-tcnt, | ||
4065 | "; allowed inputs: "); | ||
4066 | tcnt += ccnt; | ||
4067 | tcnt += print_input_mask(hdw->input_allowed_mask, | ||
4068 | buf+tcnt, | ||
4069 | acnt-tcnt); | ||
4070 | } | ||
4071 | return tcnt; | ||
4072 | } | ||
4073 | case 5: { | ||
4074 | struct pvr2_stream_stats stats; | ||
4075 | if (!hdw->vid_stream) break; | ||
4076 | pvr2_stream_get_stats(hdw->vid_stream, | ||
4077 | &stats, | ||
4078 | 0); | ||
4079 | return scnprintf( | ||
4080 | buf,acnt, | ||
4081 | "Bytes streamed=%u" | ||
4082 | " URBs: queued=%u idle=%u ready=%u" | ||
4083 | " processed=%u failed=%u", | ||
4084 | stats.bytes_processed, | ||
4085 | stats.buffers_in_queue, | ||
4086 | stats.buffers_in_idle, | ||
4087 | stats.buffers_in_ready, | ||
4088 | stats.buffers_processed, | ||
4089 | stats.buffers_failed); | ||
4090 | } | ||
3554 | default: break; | 4091 | default: break; |
3555 | } | 4092 | } |
3556 | return 0; | 4093 | return 0; |
@@ -3596,6 +4133,7 @@ static int pvr2_hdw_state_eval(struct pvr2_hdw *hdw) | |||
3596 | unsigned int st; | 4133 | unsigned int st; |
3597 | int state_updated = 0; | 4134 | int state_updated = 0; |
3598 | int callback_flag = 0; | 4135 | int callback_flag = 0; |
4136 | int analog_mode; | ||
3599 | 4137 | ||
3600 | pvr2_trace(PVR2_TRACE_STBITS, | 4138 | pvr2_trace(PVR2_TRACE_STBITS, |
3601 | "Drive state check START"); | 4139 | "Drive state check START"); |
@@ -3606,18 +4144,23 @@ static int pvr2_hdw_state_eval(struct pvr2_hdw *hdw) | |||
3606 | /* Process all state and get back over disposition */ | 4144 | /* Process all state and get back over disposition */ |
3607 | state_updated = pvr2_hdw_state_update(hdw); | 4145 | state_updated = pvr2_hdw_state_update(hdw); |
3608 | 4146 | ||
4147 | analog_mode = (hdw->pathway_state != PVR2_PATHWAY_DIGITAL); | ||
4148 | |||
3609 | /* Update master state based upon all other states. */ | 4149 | /* Update master state based upon all other states. */ |
3610 | if (!hdw->flag_ok) { | 4150 | if (!hdw->flag_ok) { |
3611 | st = PVR2_STATE_DEAD; | 4151 | st = PVR2_STATE_DEAD; |
3612 | } else if (hdw->fw1_state != FW1_STATE_OK) { | 4152 | } else if (hdw->fw1_state != FW1_STATE_OK) { |
3613 | st = PVR2_STATE_COLD; | 4153 | st = PVR2_STATE_COLD; |
3614 | } else if (!hdw->state_encoder_ok) { | 4154 | } else if ((analog_mode || |
4155 | hdw->hdw_desc->flag_digital_requires_cx23416) && | ||
4156 | !hdw->state_encoder_ok) { | ||
3615 | st = PVR2_STATE_WARM; | 4157 | st = PVR2_STATE_WARM; |
3616 | } else if (hdw->flag_tripped || hdw->flag_decoder_missed) { | 4158 | } else if (hdw->flag_tripped || |
4159 | (analog_mode && hdw->flag_decoder_missed)) { | ||
3617 | st = PVR2_STATE_ERROR; | 4160 | st = PVR2_STATE_ERROR; |
3618 | } else if (hdw->state_encoder_run && | 4161 | } else if (hdw->state_usbstream_run && |
3619 | hdw->state_decoder_run && | 4162 | (!analog_mode || |
3620 | hdw->state_usbstream_run) { | 4163 | (hdw->state_encoder_run && hdw->state_decoder_run))) { |
3621 | st = PVR2_STATE_RUN; | 4164 | st = PVR2_STATE_RUN; |
3622 | } else { | 4165 | } else { |
3623 | st = PVR2_STATE_READY; | 4166 | st = PVR2_STATE_READY; |
@@ -3627,6 +4170,7 @@ static int pvr2_hdw_state_eval(struct pvr2_hdw *hdw) | |||
3627 | "Device state change from %s to %s", | 4170 | "Device state change from %s to %s", |
3628 | pvr2_get_state_name(hdw->master_state), | 4171 | pvr2_get_state_name(hdw->master_state), |
3629 | pvr2_get_state_name(st)); | 4172 | pvr2_get_state_name(st)); |
4173 | pvr2_led_ctrl(hdw,st == PVR2_STATE_RUN); | ||
3630 | hdw->master_state = st; | 4174 | hdw->master_state = st; |
3631 | state_updated = !0; | 4175 | state_updated = !0; |
3632 | callback_flag = !0; | 4176 | callback_flag = !0; |
@@ -3656,47 +4200,6 @@ static void pvr2_hdw_state_sched(struct pvr2_hdw *hdw) | |||
3656 | } | 4200 | } |
3657 | 4201 | ||
3658 | 4202 | ||
3659 | void pvr2_hdw_get_debug_info_unlocked(const struct pvr2_hdw *hdw, | ||
3660 | struct pvr2_hdw_debug_info *ptr) | ||
3661 | { | ||
3662 | ptr->big_lock_held = hdw->big_lock_held; | ||
3663 | ptr->ctl_lock_held = hdw->ctl_lock_held; | ||
3664 | ptr->flag_disconnected = hdw->flag_disconnected; | ||
3665 | ptr->flag_init_ok = hdw->flag_init_ok; | ||
3666 | ptr->flag_ok = hdw->flag_ok; | ||
3667 | ptr->fw1_state = hdw->fw1_state; | ||
3668 | ptr->flag_decoder_missed = hdw->flag_decoder_missed; | ||
3669 | ptr->flag_tripped = hdw->flag_tripped; | ||
3670 | ptr->state_encoder_ok = hdw->state_encoder_ok; | ||
3671 | ptr->state_encoder_run = hdw->state_encoder_run; | ||
3672 | ptr->state_decoder_run = hdw->state_decoder_run; | ||
3673 | ptr->state_usbstream_run = hdw->state_usbstream_run; | ||
3674 | ptr->state_decoder_quiescent = hdw->state_decoder_quiescent; | ||
3675 | ptr->state_pipeline_config = hdw->state_pipeline_config; | ||
3676 | ptr->state_pipeline_req = hdw->state_pipeline_req; | ||
3677 | ptr->state_pipeline_pause = hdw->state_pipeline_pause; | ||
3678 | ptr->state_pipeline_idle = hdw->state_pipeline_idle; | ||
3679 | ptr->cmd_debug_state = hdw->cmd_debug_state; | ||
3680 | ptr->cmd_code = hdw->cmd_debug_code; | ||
3681 | ptr->cmd_debug_write_len = hdw->cmd_debug_write_len; | ||
3682 | ptr->cmd_debug_read_len = hdw->cmd_debug_read_len; | ||
3683 | ptr->cmd_debug_timeout = hdw->ctl_timeout_flag; | ||
3684 | ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag; | ||
3685 | ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag; | ||
3686 | ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status; | ||
3687 | ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status; | ||
3688 | } | ||
3689 | |||
3690 | |||
3691 | void pvr2_hdw_get_debug_info_locked(struct pvr2_hdw *hdw, | ||
3692 | struct pvr2_hdw_debug_info *ptr) | ||
3693 | { | ||
3694 | LOCK_TAKE(hdw->ctl_lock); do { | ||
3695 | pvr2_hdw_get_debug_info_unlocked(hdw,ptr); | ||
3696 | } while(0); LOCK_GIVE(hdw->ctl_lock); | ||
3697 | } | ||
3698 | |||
3699 | |||
3700 | int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp) | 4203 | int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp) |
3701 | { | 4204 | { |
3702 | return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp); | 4205 | return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp); |
@@ -3756,6 +4259,80 @@ int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val) | |||
3756 | } | 4259 | } |
3757 | 4260 | ||
3758 | 4261 | ||
4262 | unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw) | ||
4263 | { | ||
4264 | return hdw->input_avail_mask; | ||
4265 | } | ||
4266 | |||
4267 | |||
4268 | unsigned int pvr2_hdw_get_input_allowed(struct pvr2_hdw *hdw) | ||
4269 | { | ||
4270 | return hdw->input_allowed_mask; | ||
4271 | } | ||
4272 | |||
4273 | |||
4274 | static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v) | ||
4275 | { | ||
4276 | if (hdw->input_val != v) { | ||
4277 | hdw->input_val = v; | ||
4278 | hdw->input_dirty = !0; | ||
4279 | } | ||
4280 | |||
4281 | /* Handle side effects - if we switch to a mode that needs the RF | ||
4282 | tuner, then select the right frequency choice as well and mark | ||
4283 | it dirty. */ | ||
4284 | if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { | ||
4285 | hdw->freqSelector = 0; | ||
4286 | hdw->freqDirty = !0; | ||
4287 | } else if ((hdw->input_val == PVR2_CVAL_INPUT_TV) || | ||
4288 | (hdw->input_val == PVR2_CVAL_INPUT_DTV)) { | ||
4289 | hdw->freqSelector = 1; | ||
4290 | hdw->freqDirty = !0; | ||
4291 | } | ||
4292 | return 0; | ||
4293 | } | ||
4294 | |||
4295 | |||
4296 | int pvr2_hdw_set_input_allowed(struct pvr2_hdw *hdw, | ||
4297 | unsigned int change_mask, | ||
4298 | unsigned int change_val) | ||
4299 | { | ||
4300 | int ret = 0; | ||
4301 | unsigned int nv,m,idx; | ||
4302 | LOCK_TAKE(hdw->big_lock); | ||
4303 | do { | ||
4304 | nv = hdw->input_allowed_mask & ~change_mask; | ||
4305 | nv |= (change_val & change_mask); | ||
4306 | nv &= hdw->input_avail_mask; | ||
4307 | if (!nv) { | ||
4308 | /* No legal modes left; return error instead. */ | ||
4309 | ret = -EPERM; | ||
4310 | break; | ||
4311 | } | ||
4312 | hdw->input_allowed_mask = nv; | ||
4313 | if ((1 << hdw->input_val) & hdw->input_allowed_mask) { | ||
4314 | /* Current mode is still in the allowed mask, so | ||
4315 | we're done. */ | ||
4316 | break; | ||
4317 | } | ||
4318 | /* Select and switch to a mode that is still in the allowed | ||
4319 | mask */ | ||
4320 | if (!hdw->input_allowed_mask) { | ||
4321 | /* Nothing legal; give up */ | ||
4322 | break; | ||
4323 | } | ||
4324 | m = hdw->input_allowed_mask; | ||
4325 | for (idx = 0; idx < (sizeof(m) << 3); idx++) { | ||
4326 | if (!((1 << idx) & m)) continue; | ||
4327 | pvr2_hdw_set_input(hdw,idx); | ||
4328 | break; | ||
4329 | } | ||
4330 | } while (0); | ||
4331 | LOCK_GIVE(hdw->big_lock); | ||
4332 | return ret; | ||
4333 | } | ||
4334 | |||
4335 | |||
3759 | /* Find I2C address of eeprom */ | 4336 | /* Find I2C address of eeprom */ |
3760 | static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) | 4337 | static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) |
3761 | { | 4338 | { |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 3ad7a13d6c39..20295e0c1995 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h | |||
@@ -40,9 +40,10 @@ | |||
40 | 40 | ||
41 | /* Legal values for the INPUT state variable */ | 41 | /* Legal values for the INPUT state variable */ |
42 | #define PVR2_CVAL_INPUT_TV 0 | 42 | #define PVR2_CVAL_INPUT_TV 0 |
43 | #define PVR2_CVAL_INPUT_SVIDEO 1 | 43 | #define PVR2_CVAL_INPUT_DTV 1 |
44 | #define PVR2_CVAL_INPUT_COMPOSITE 2 | 44 | #define PVR2_CVAL_INPUT_COMPOSITE 2 |
45 | #define PVR2_CVAL_INPUT_RADIO 3 | 45 | #define PVR2_CVAL_INPUT_SVIDEO 3 |
46 | #define PVR2_CVAL_INPUT_RADIO 4 | ||
46 | 47 | ||
47 | enum pvr2_config { | 48 | enum pvr2_config { |
48 | pvr2_config_empty, /* No configuration */ | 49 | pvr2_config_empty, /* No configuration */ |
@@ -90,9 +91,6 @@ enum pvr2_v4l_type { | |||
90 | /* Translate configuration enum to a string label */ | 91 | /* Translate configuration enum to a string label */ |
91 | const char *pvr2_config_get_name(enum pvr2_config); | 92 | const char *pvr2_config_get_name(enum pvr2_config); |
92 | 93 | ||
93 | /* Translate a master state enum to a string label */ | ||
94 | const char *pvr2_hdw_get_state_name(unsigned int); | ||
95 | |||
96 | struct pvr2_hdw; | 94 | struct pvr2_hdw; |
97 | 95 | ||
98 | /* Create and return a structure for interacting with the underlying | 96 | /* Create and return a structure for interacting with the underlying |
@@ -100,14 +98,15 @@ struct pvr2_hdw; | |||
100 | struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | 98 | struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, |
101 | const struct usb_device_id *devid); | 99 | const struct usb_device_id *devid); |
102 | 100 | ||
101 | /* Perform second stage initialization, passing in a notification callback | ||
102 | for when the master state changes. */ | ||
103 | int pvr2_hdw_initialize(struct pvr2_hdw *, | ||
104 | void (*callback_func)(void *), | ||
105 | void *callback_data); | ||
106 | |||
103 | /* Destroy hardware interaction structure */ | 107 | /* Destroy hardware interaction structure */ |
104 | void pvr2_hdw_destroy(struct pvr2_hdw *); | 108 | void pvr2_hdw_destroy(struct pvr2_hdw *); |
105 | 109 | ||
106 | /* Register a function to be called whenever the master state changes. */ | ||
107 | void pvr2_hdw_set_state_callback(struct pvr2_hdw *, | ||
108 | void (*callback_func)(void *), | ||
109 | void *callback_data); | ||
110 | |||
111 | /* Return true if in the ready (normal) state */ | 110 | /* Return true if in the ready (normal) state */ |
112 | int pvr2_hdw_dev_ok(struct pvr2_hdw *); | 111 | int pvr2_hdw_dev_ok(struct pvr2_hdw *); |
113 | 112 | ||
@@ -146,6 +145,23 @@ struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *, | |||
146 | /* Commit all control changes made up to this point */ | 145 | /* Commit all control changes made up to this point */ |
147 | int pvr2_hdw_commit_ctl(struct pvr2_hdw *); | 146 | int pvr2_hdw_commit_ctl(struct pvr2_hdw *); |
148 | 147 | ||
148 | /* Return a bit mask of valid input selections for this device. Mask bits | ||
149 | * will be according to PVR_CVAL_INPUT_xxxx definitions. */ | ||
150 | unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *); | ||
151 | |||
152 | /* Return a bit mask of allowed input selections for this device. Mask bits | ||
153 | * will be according to PVR_CVAL_INPUT_xxxx definitions. */ | ||
154 | unsigned int pvr2_hdw_get_input_allowed(struct pvr2_hdw *); | ||
155 | |||
156 | /* Change the set of allowed input selections for this device. Both | ||
157 | change_mask and change_valu are mask bits according to | ||
158 | PVR_CVAL_INPUT_xxxx definitions. The change_mask parameter indicate | ||
159 | which settings are being changed and the change_val parameter indicates | ||
160 | whether corresponding settings are being set or cleared. */ | ||
161 | int pvr2_hdw_set_input_allowed(struct pvr2_hdw *, | ||
162 | unsigned int change_mask, | ||
163 | unsigned int change_val); | ||
164 | |||
149 | /* Return name for this driver instance */ | 165 | /* Return name for this driver instance */ |
150 | const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *); | 166 | const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *); |
151 | 167 | ||
@@ -250,6 +266,9 @@ int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *); | |||
250 | /* Execute simple reset command */ | 266 | /* Execute simple reset command */ |
251 | int pvr2_hdw_cmd_powerup(struct pvr2_hdw *); | 267 | int pvr2_hdw_cmd_powerup(struct pvr2_hdw *); |
252 | 268 | ||
269 | /* suspend */ | ||
270 | int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *); | ||
271 | |||
253 | /* Order decoder to reset */ | 272 | /* Order decoder to reset */ |
254 | int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *); | 273 | int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *); |
255 | 274 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 62867fa3517a..793c89a8d672 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | */ | 36 | */ |
37 | 37 | ||
38 | static unsigned int i2c_scan = 0; | 38 | static unsigned int i2c_scan; |
39 | module_param(i2c_scan, int, S_IRUGO|S_IWUSR); | 39 | module_param(i2c_scan, int, S_IRUGO|S_IWUSR); |
40 | MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); | 40 | MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); |
41 | 41 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.c b/drivers/media/video/pvrusb2/pvrusb2-io.c index a9889ff96ecc..7aff8b720064 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-io.c +++ b/drivers/media/video/pvrusb2/pvrusb2-io.c | |||
@@ -80,6 +80,10 @@ struct pvr2_stream { | |||
80 | /* Tracking state for tolerating errors */ | 80 | /* Tracking state for tolerating errors */ |
81 | unsigned int fail_count; | 81 | unsigned int fail_count; |
82 | unsigned int fail_tolerance; | 82 | unsigned int fail_tolerance; |
83 | |||
84 | unsigned int buffers_processed; | ||
85 | unsigned int buffers_failed; | ||
86 | unsigned int bytes_processed; | ||
83 | }; | 87 | }; |
84 | 88 | ||
85 | struct pvr2_buffer { | 89 | struct pvr2_buffer { |
@@ -446,6 +450,8 @@ static void buffer_complete(struct urb *urb) | |||
446 | (urb->status == -ENOENT) || | 450 | (urb->status == -ENOENT) || |
447 | (urb->status == -ECONNRESET) || | 451 | (urb->status == -ECONNRESET) || |
448 | (urb->status == -ESHUTDOWN)) { | 452 | (urb->status == -ESHUTDOWN)) { |
453 | (sp->buffers_processed)++; | ||
454 | sp->bytes_processed += urb->actual_length; | ||
449 | bp->used_count = urb->actual_length; | 455 | bp->used_count = urb->actual_length; |
450 | if (sp->fail_count) { | 456 | if (sp->fail_count) { |
451 | pvr2_trace(PVR2_TRACE_TOLERANCE, | 457 | pvr2_trace(PVR2_TRACE_TOLERANCE, |
@@ -457,11 +463,13 @@ static void buffer_complete(struct urb *urb) | |||
457 | // We can tolerate this error, because we're below the | 463 | // We can tolerate this error, because we're below the |
458 | // threshold... | 464 | // threshold... |
459 | (sp->fail_count)++; | 465 | (sp->fail_count)++; |
466 | (sp->buffers_failed)++; | ||
460 | pvr2_trace(PVR2_TRACE_TOLERANCE, | 467 | pvr2_trace(PVR2_TRACE_TOLERANCE, |
461 | "stream %p ignoring error %d" | 468 | "stream %p ignoring error %d" |
462 | " - fail count increased to %u", | 469 | " - fail count increased to %u", |
463 | sp,urb->status,sp->fail_count); | 470 | sp,urb->status,sp->fail_count); |
464 | } else { | 471 | } else { |
472 | (sp->buffers_failed)++; | ||
465 | bp->status = urb->status; | 473 | bp->status = urb->status; |
466 | } | 474 | } |
467 | spin_unlock_irqrestore(&sp->list_lock,irq_flags); | 475 | spin_unlock_irqrestore(&sp->list_lock,irq_flags); |
@@ -515,6 +523,28 @@ void pvr2_stream_set_callback(struct pvr2_stream *sp, | |||
515 | } while(0); mutex_unlock(&sp->mutex); | 523 | } while(0); mutex_unlock(&sp->mutex); |
516 | } | 524 | } |
517 | 525 | ||
526 | void pvr2_stream_get_stats(struct pvr2_stream *sp, | ||
527 | struct pvr2_stream_stats *stats, | ||
528 | int zero_counts) | ||
529 | { | ||
530 | unsigned long irq_flags; | ||
531 | spin_lock_irqsave(&sp->list_lock,irq_flags); | ||
532 | if (stats) { | ||
533 | stats->buffers_in_queue = sp->q_count; | ||
534 | stats->buffers_in_idle = sp->i_count; | ||
535 | stats->buffers_in_ready = sp->r_count; | ||
536 | stats->buffers_processed = sp->buffers_processed; | ||
537 | stats->buffers_failed = sp->buffers_failed; | ||
538 | stats->bytes_processed = sp->bytes_processed; | ||
539 | } | ||
540 | if (zero_counts) { | ||
541 | sp->buffers_processed = 0; | ||
542 | sp->buffers_failed = 0; | ||
543 | sp->bytes_processed = 0; | ||
544 | } | ||
545 | spin_unlock_irqrestore(&sp->list_lock,irq_flags); | ||
546 | } | ||
547 | |||
518 | /* Query / set the nominal buffer count */ | 548 | /* Query / set the nominal buffer count */ |
519 | int pvr2_stream_get_buffer_count(struct pvr2_stream *sp) | 549 | int pvr2_stream_get_buffer_count(struct pvr2_stream *sp) |
520 | { | 550 | { |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.h b/drivers/media/video/pvrusb2/pvrusb2-io.h index 93279cc2a35e..42fcf8281a87 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-io.h +++ b/drivers/media/video/pvrusb2/pvrusb2-io.h | |||
@@ -36,6 +36,15 @@ enum pvr2_buffer_state { | |||
36 | struct pvr2_stream; | 36 | struct pvr2_stream; |
37 | struct pvr2_buffer; | 37 | struct pvr2_buffer; |
38 | 38 | ||
39 | struct pvr2_stream_stats { | ||
40 | unsigned int buffers_in_queue; | ||
41 | unsigned int buffers_in_idle; | ||
42 | unsigned int buffers_in_ready; | ||
43 | unsigned int buffers_processed; | ||
44 | unsigned int buffers_failed; | ||
45 | unsigned int bytes_processed; | ||
46 | }; | ||
47 | |||
39 | /* Initialize / tear down stream structure */ | 48 | /* Initialize / tear down stream structure */ |
40 | struct pvr2_stream *pvr2_stream_create(void); | 49 | struct pvr2_stream *pvr2_stream_create(void); |
41 | void pvr2_stream_destroy(struct pvr2_stream *); | 50 | void pvr2_stream_destroy(struct pvr2_stream *); |
@@ -45,6 +54,9 @@ void pvr2_stream_setup(struct pvr2_stream *, | |||
45 | void pvr2_stream_set_callback(struct pvr2_stream *, | 54 | void pvr2_stream_set_callback(struct pvr2_stream *, |
46 | pvr2_stream_callback func, | 55 | pvr2_stream_callback func, |
47 | void *data); | 56 | void *data); |
57 | void pvr2_stream_get_stats(struct pvr2_stream *, | ||
58 | struct pvr2_stream_stats *, | ||
59 | int zero_counts); | ||
48 | 60 | ||
49 | /* Query / set the nominal buffer count */ | 61 | /* Query / set the nominal buffer count */ |
50 | int pvr2_stream_get_buffer_count(struct pvr2_stream *); | 62 | int pvr2_stream_get_buffer_count(struct pvr2_stream *); |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c index b63b2265503a..332aced8a5a1 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/drivers/media/video/pvrusb2/pvrusb2-main.c | |||
@@ -60,6 +60,10 @@ static void pvr_setup_attach(struct pvr2_context *pvr) | |||
60 | { | 60 | { |
61 | /* Create association with v4l layer */ | 61 | /* Create association with v4l layer */ |
62 | pvr2_v4l2_create(pvr); | 62 | pvr2_v4l2_create(pvr); |
63 | #ifdef CONFIG_VIDEO_PVRUSB2_DVB | ||
64 | /* Create association with dvb layer */ | ||
65 | pvr2_dvb_create(pvr); | ||
66 | #endif | ||
63 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS | 67 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS |
64 | pvr2_sysfs_create(pvr,class_ptr); | 68 | pvr2_sysfs_create(pvr,class_ptr); |
65 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ | 69 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ |
@@ -121,6 +125,12 @@ static int __init pvr_init(void) | |||
121 | 125 | ||
122 | pvr2_trace(PVR2_TRACE_INIT,"pvr_init"); | 126 | pvr2_trace(PVR2_TRACE_INIT,"pvr_init"); |
123 | 127 | ||
128 | ret = pvr2_context_global_init(); | ||
129 | if (ret != 0) { | ||
130 | pvr2_trace(PVR2_TRACE_INIT,"pvr_init failure code=%d",ret); | ||
131 | return ret; | ||
132 | } | ||
133 | |||
124 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS | 134 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS |
125 | class_ptr = pvr2_sysfs_class_create(); | 135 | class_ptr = pvr2_sysfs_class_create(); |
126 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ | 136 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ |
@@ -132,6 +142,8 @@ static int __init pvr_init(void) | |||
132 | if (pvrusb2_debug) info("Debug mask is %d (0x%x)", | 142 | if (pvrusb2_debug) info("Debug mask is %d (0x%x)", |
133 | pvrusb2_debug,pvrusb2_debug); | 143 | pvrusb2_debug,pvrusb2_debug); |
134 | 144 | ||
145 | pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete"); | ||
146 | |||
135 | return ret; | 147 | return ret; |
136 | } | 148 | } |
137 | 149 | ||
@@ -144,6 +156,10 @@ static void __exit pvr_exit(void) | |||
144 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS | 156 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS |
145 | pvr2_sysfs_class_destroy(class_ptr); | 157 | pvr2_sysfs_class_destroy(class_ptr); |
146 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ | 158 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ |
159 | |||
160 | pvr2_context_global_done(); | ||
161 | |||
162 | pvr2_trace(PVR2_TRACE_INIT,"pvr_exit complete"); | ||
147 | } | 163 | } |
148 | 164 | ||
149 | module_init(pvr_init); | 165 | module_init(pvr_init); |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c index da309288daa4..fdc5a2b49ca8 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-std.c +++ b/drivers/media/video/pvrusb2/pvrusb2-std.c | |||
@@ -79,7 +79,7 @@ struct std_name { | |||
79 | #define TSTD_Nc (V4L2_STD_PAL_Nc) | 79 | #define TSTD_Nc (V4L2_STD_PAL_Nc) |
80 | #define TSTD_60 (V4L2_STD_PAL_60) | 80 | #define TSTD_60 (V4L2_STD_PAL_60) |
81 | 81 | ||
82 | #define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_SECAM) | 82 | #define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_ATSC|CSTD_SECAM) |
83 | 83 | ||
84 | /* Mapping of standard bits to color system */ | 84 | /* Mapping of standard bits to color system */ |
85 | static const struct std_name std_groups[] = { | 85 | static const struct std_name std_groups[] = { |
@@ -328,7 +328,7 @@ struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, | |||
328 | struct v4l2_standard *stddefs; | 328 | struct v4l2_standard *stddefs; |
329 | 329 | ||
330 | if (pvrusb2_debug & PVR2_TRACE_STD) { | 330 | if (pvrusb2_debug & PVR2_TRACE_STD) { |
331 | char buf[50]; | 331 | char buf[100]; |
332 | bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id); | 332 | bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id); |
333 | pvr2_trace( | 333 | pvr2_trace( |
334 | PVR2_TRACE_STD,"Mapping standards mask=0x%x (%.*s)", | 334 | PVR2_TRACE_STD,"Mapping standards mask=0x%x (%.*s)", |
@@ -352,8 +352,11 @@ struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, | |||
352 | if ((id & std_mixes[idx2]) == std_mixes[idx2]) std_cnt++; | 352 | if ((id & std_mixes[idx2]) == std_mixes[idx2]) std_cnt++; |
353 | } | 353 | } |
354 | 354 | ||
355 | /* Don't complain about ATSC standard values */ | ||
356 | fmsk &= ~CSTD_ATSC; | ||
357 | |||
355 | if (fmsk) { | 358 | if (fmsk) { |
356 | char buf[50]; | 359 | char buf[100]; |
357 | bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk); | 360 | bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk); |
358 | pvr2_trace( | 361 | pvr2_trace( |
359 | PVR2_TRACE_ERROR_LEGS, | 362 | PVR2_TRACE_ERROR_LEGS, |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 07f4eae18433..0ff7a836a8a2 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | |||
@@ -287,6 +287,8 @@ static ssize_t store_val_norm(int id,struct device *class_dev, | |||
287 | struct pvr2_sysfs *sfp; | 287 | struct pvr2_sysfs *sfp; |
288 | int ret; | 288 | int ret; |
289 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | 289 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; |
290 | pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"", | ||
291 | sfp,id,(int)count,buf); | ||
290 | ret = store_val_any(id,0,sfp,buf,count); | 292 | ret = store_val_any(id,0,sfp,buf,count); |
291 | if (!ret) ret = count; | 293 | if (!ret) ret = count; |
292 | return ret; | 294 | return ret; |
@@ -298,6 +300,8 @@ static ssize_t store_val_custom(int id,struct device *class_dev, | |||
298 | struct pvr2_sysfs *sfp; | 300 | struct pvr2_sysfs *sfp; |
299 | int ret; | 301 | int ret; |
300 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | 302 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; |
303 | pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"", | ||
304 | sfp,id,(int)count,buf); | ||
301 | ret = store_val_any(id,1,sfp,buf,count); | 305 | ret = store_val_any(id,1,sfp,buf,count); |
302 | if (!ret) ret = count; | 306 | if (!ret) ret = count; |
303 | return ret; | 307 | return ret; |
@@ -604,8 +608,9 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | |||
604 | 608 | ||
605 | ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp); | 609 | ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp); |
606 | if (ret) { | 610 | if (ret) { |
607 | printk(KERN_WARNING "%s: sysfs_create_group error: %d\n", | 611 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
608 | __FUNCTION__, ret); | 612 | "sysfs_create_group error: %d", |
613 | ret); | ||
609 | return; | 614 | return; |
610 | } | 615 | } |
611 | cip->created_ok = !0; | 616 | cip->created_ok = !0; |
@@ -636,15 +641,17 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) | |||
636 | sfp->debugifc = dip; | 641 | sfp->debugifc = dip; |
637 | ret = device_create_file(sfp->class_dev,&dip->attr_debugcmd); | 642 | ret = device_create_file(sfp->class_dev,&dip->attr_debugcmd); |
638 | if (ret < 0) { | 643 | if (ret < 0) { |
639 | printk(KERN_WARNING "%s: device_create_file error: %d\n", | 644 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
640 | __FUNCTION__, ret); | 645 | "device_create_file error: %d", |
646 | ret); | ||
641 | } else { | 647 | } else { |
642 | dip->debugcmd_created_ok = !0; | 648 | dip->debugcmd_created_ok = !0; |
643 | } | 649 | } |
644 | ret = device_create_file(sfp->class_dev,&dip->attr_debuginfo); | 650 | ret = device_create_file(sfp->class_dev,&dip->attr_debuginfo); |
645 | if (ret < 0) { | 651 | if (ret < 0) { |
646 | printk(KERN_WARNING "%s: device_create_file error: %d\n", | 652 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
647 | __FUNCTION__, ret); | 653 | "device_create_file error: %d", |
654 | ret); | ||
648 | } else { | 655 | } else { |
649 | dip->debuginfo_created_ok = !0; | 656 | dip->debuginfo_created_ok = !0; |
650 | } | 657 | } |
@@ -847,8 +854,8 @@ static void class_dev_create(struct pvr2_sysfs *sfp, | |||
847 | class_dev->driver_data = sfp; | 854 | class_dev->driver_data = sfp; |
848 | ret = device_register(class_dev); | 855 | ret = device_register(class_dev); |
849 | if (ret) { | 856 | if (ret) { |
850 | printk(KERN_ERR "%s: device_register failed\n", | 857 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
851 | __FUNCTION__); | 858 | "device_register failed"); |
852 | kfree(class_dev); | 859 | kfree(class_dev); |
853 | return; | 860 | return; |
854 | } | 861 | } |
@@ -860,8 +867,9 @@ static void class_dev_create(struct pvr2_sysfs *sfp, | |||
860 | ret = device_create_file(sfp->class_dev, | 867 | ret = device_create_file(sfp->class_dev, |
861 | &sfp->attr_v4l_minor_number); | 868 | &sfp->attr_v4l_minor_number); |
862 | if (ret < 0) { | 869 | if (ret < 0) { |
863 | printk(KERN_WARNING "%s: device_create_file error: %d\n", | 870 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
864 | __FUNCTION__, ret); | 871 | "device_create_file error: %d", |
872 | ret); | ||
865 | } else { | 873 | } else { |
866 | sfp->v4l_minor_number_created_ok = !0; | 874 | sfp->v4l_minor_number_created_ok = !0; |
867 | } | 875 | } |
@@ -873,8 +881,9 @@ static void class_dev_create(struct pvr2_sysfs *sfp, | |||
873 | ret = device_create_file(sfp->class_dev, | 881 | ret = device_create_file(sfp->class_dev, |
874 | &sfp->attr_v4l_radio_minor_number); | 882 | &sfp->attr_v4l_radio_minor_number); |
875 | if (ret < 0) { | 883 | if (ret < 0) { |
876 | printk(KERN_WARNING "%s: device_create_file error: %d\n", | 884 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
877 | __FUNCTION__, ret); | 885 | "device_create_file error: %d", |
886 | ret); | ||
878 | } else { | 887 | } else { |
879 | sfp->v4l_radio_minor_number_created_ok = !0; | 888 | sfp->v4l_radio_minor_number_created_ok = !0; |
880 | } | 889 | } |
@@ -885,8 +894,9 @@ static void class_dev_create(struct pvr2_sysfs *sfp, | |||
885 | sfp->attr_unit_number.store = NULL; | 894 | sfp->attr_unit_number.store = NULL; |
886 | ret = device_create_file(sfp->class_dev,&sfp->attr_unit_number); | 895 | ret = device_create_file(sfp->class_dev,&sfp->attr_unit_number); |
887 | if (ret < 0) { | 896 | if (ret < 0) { |
888 | printk(KERN_WARNING "%s: device_create_file error: %d\n", | 897 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
889 | __FUNCTION__, ret); | 898 | "device_create_file error: %d", |
899 | ret); | ||
890 | } else { | 900 | } else { |
891 | sfp->unit_number_created_ok = !0; | 901 | sfp->unit_number_created_ok = !0; |
892 | } | 902 | } |
@@ -898,8 +908,9 @@ static void class_dev_create(struct pvr2_sysfs *sfp, | |||
898 | ret = device_create_file(sfp->class_dev, | 908 | ret = device_create_file(sfp->class_dev, |
899 | &sfp->attr_bus_info); | 909 | &sfp->attr_bus_info); |
900 | if (ret < 0) { | 910 | if (ret < 0) { |
901 | printk(KERN_WARNING "%s: device_create_file error: %d\n", | 911 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
902 | __FUNCTION__, ret); | 912 | "device_create_file error: %d", |
913 | ret); | ||
903 | } else { | 914 | } else { |
904 | sfp->bus_info_created_ok = !0; | 915 | sfp->bus_info_created_ok = !0; |
905 | } | 916 | } |
@@ -911,8 +922,9 @@ static void class_dev_create(struct pvr2_sysfs *sfp, | |||
911 | ret = device_create_file(sfp->class_dev, | 922 | ret = device_create_file(sfp->class_dev, |
912 | &sfp->attr_hdw_name); | 923 | &sfp->attr_hdw_name); |
913 | if (ret < 0) { | 924 | if (ret < 0) { |
914 | printk(KERN_WARNING "%s: device_create_file error: %d\n", | 925 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
915 | __FUNCTION__, ret); | 926 | "device_create_file error: %d", |
927 | ret); | ||
916 | } else { | 928 | } else { |
917 | sfp->hdw_name_created_ok = !0; | 929 | sfp->hdw_name_created_ok = !0; |
918 | } | 930 | } |
@@ -924,8 +936,9 @@ static void class_dev_create(struct pvr2_sysfs *sfp, | |||
924 | ret = device_create_file(sfp->class_dev, | 936 | ret = device_create_file(sfp->class_dev, |
925 | &sfp->attr_hdw_desc); | 937 | &sfp->attr_hdw_desc); |
926 | if (ret < 0) { | 938 | if (ret < 0) { |
927 | printk(KERN_WARNING "%s: device_create_file error: %d\n", | 939 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
928 | __FUNCTION__, ret); | 940 | "device_create_file error: %d", |
941 | ret); | ||
929 | } else { | 942 | } else { |
930 | sfp->hdw_desc_created_ok = !0; | 943 | sfp->hdw_desc_created_ok = !0; |
931 | } | 944 | } |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 8f0587ebd4bd..087a18245560 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
@@ -57,7 +57,9 @@ struct pvr2_v4l2_fh { | |||
57 | struct pvr2_v4l2_fh *vprev; | 57 | struct pvr2_v4l2_fh *vprev; |
58 | wait_queue_head_t wait_data; | 58 | wait_queue_head_t wait_data; |
59 | int fw_mode_flag; | 59 | int fw_mode_flag; |
60 | int prev_input_val; | 60 | /* Map contiguous ordinal value to input id */ |
61 | unsigned char *input_map; | ||
62 | unsigned int input_cnt; | ||
61 | }; | 63 | }; |
62 | 64 | ||
63 | struct pvr2_v4l2 { | 65 | struct pvr2_v4l2 { |
@@ -259,14 +261,21 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
259 | struct v4l2_input *vi = (struct v4l2_input *)arg; | 261 | struct v4l2_input *vi = (struct v4l2_input *)arg; |
260 | struct v4l2_input tmp; | 262 | struct v4l2_input tmp; |
261 | unsigned int cnt; | 263 | unsigned int cnt; |
264 | int val; | ||
262 | 265 | ||
263 | cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); | 266 | cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); |
264 | 267 | ||
265 | memset(&tmp,0,sizeof(tmp)); | 268 | memset(&tmp,0,sizeof(tmp)); |
266 | tmp.index = vi->index; | 269 | tmp.index = vi->index; |
267 | ret = 0; | 270 | ret = 0; |
268 | switch (vi->index) { | 271 | if ((vi->index < 0) || (vi->index >= fh->input_cnt)) { |
272 | ret = -EINVAL; | ||
273 | break; | ||
274 | } | ||
275 | val = fh->input_map[vi->index]; | ||
276 | switch (val) { | ||
269 | case PVR2_CVAL_INPUT_TV: | 277 | case PVR2_CVAL_INPUT_TV: |
278 | case PVR2_CVAL_INPUT_DTV: | ||
270 | case PVR2_CVAL_INPUT_RADIO: | 279 | case PVR2_CVAL_INPUT_RADIO: |
271 | tmp.type = V4L2_INPUT_TYPE_TUNER; | 280 | tmp.type = V4L2_INPUT_TYPE_TUNER; |
272 | break; | 281 | break; |
@@ -281,7 +290,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
281 | if (ret < 0) break; | 290 | if (ret < 0) break; |
282 | 291 | ||
283 | cnt = 0; | 292 | cnt = 0; |
284 | pvr2_ctrl_get_valname(cptr,vi->index, | 293 | pvr2_ctrl_get_valname(cptr,val, |
285 | tmp.name,sizeof(tmp.name)-1,&cnt); | 294 | tmp.name,sizeof(tmp.name)-1,&cnt); |
286 | tmp.name[cnt] = 0; | 295 | tmp.name[cnt] = 0; |
287 | 296 | ||
@@ -303,22 +312,33 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
303 | 312 | ||
304 | case VIDIOC_G_INPUT: | 313 | case VIDIOC_G_INPUT: |
305 | { | 314 | { |
315 | unsigned int idx; | ||
306 | struct pvr2_ctrl *cptr; | 316 | struct pvr2_ctrl *cptr; |
307 | struct v4l2_input *vi = (struct v4l2_input *)arg; | 317 | struct v4l2_input *vi = (struct v4l2_input *)arg; |
308 | int val; | 318 | int val; |
309 | cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); | 319 | cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); |
310 | val = 0; | 320 | val = 0; |
311 | ret = pvr2_ctrl_get_value(cptr,&val); | 321 | ret = pvr2_ctrl_get_value(cptr,&val); |
312 | vi->index = val; | 322 | vi->index = 0; |
323 | for (idx = 0; idx < fh->input_cnt; idx++) { | ||
324 | if (fh->input_map[idx] == val) { | ||
325 | vi->index = idx; | ||
326 | break; | ||
327 | } | ||
328 | } | ||
313 | break; | 329 | break; |
314 | } | 330 | } |
315 | 331 | ||
316 | case VIDIOC_S_INPUT: | 332 | case VIDIOC_S_INPUT: |
317 | { | 333 | { |
318 | struct v4l2_input *vi = (struct v4l2_input *)arg; | 334 | struct v4l2_input *vi = (struct v4l2_input *)arg; |
335 | if ((vi->index < 0) || (vi->index >= fh->input_cnt)) { | ||
336 | ret = -ERANGE; | ||
337 | break; | ||
338 | } | ||
319 | ret = pvr2_ctrl_set_value( | 339 | ret = pvr2_ctrl_set_value( |
320 | pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT), | 340 | pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT), |
321 | vi->index); | 341 | fh->input_map[vi->index]); |
322 | break; | 342 | break; |
323 | } | 343 | } |
324 | 344 | ||
@@ -858,7 +878,6 @@ static int pvr2_v4l2_release(struct inode *inode, struct file *file) | |||
858 | { | 878 | { |
859 | struct pvr2_v4l2_fh *fhp = file->private_data; | 879 | struct pvr2_v4l2_fh *fhp = file->private_data; |
860 | struct pvr2_v4l2 *vp = fhp->vhead; | 880 | struct pvr2_v4l2 *vp = fhp->vhead; |
861 | struct pvr2_context *mp = fhp->vhead->channel.mc_head; | ||
862 | struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw; | 881 | struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw; |
863 | 882 | ||
864 | pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release"); | 883 | pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release"); |
@@ -875,42 +894,30 @@ static int pvr2_v4l2_release(struct inode *inode, struct file *file) | |||
875 | v4l2_prio_close(&vp->prio, &fhp->prio); | 894 | v4l2_prio_close(&vp->prio, &fhp->prio); |
876 | file->private_data = NULL; | 895 | file->private_data = NULL; |
877 | 896 | ||
878 | pvr2_context_enter(mp); do { | 897 | if (fhp->vnext) { |
879 | /* Restore the previous input selection, if it makes sense | 898 | fhp->vnext->vprev = fhp->vprev; |
880 | to do so. */ | 899 | } else { |
881 | if (fhp->dev_info->v4l_type == VFL_TYPE_RADIO) { | 900 | vp->vlast = fhp->vprev; |
882 | struct pvr2_ctrl *cp; | 901 | } |
883 | int pval; | 902 | if (fhp->vprev) { |
884 | cp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); | 903 | fhp->vprev->vnext = fhp->vnext; |
885 | pvr2_ctrl_get_value(cp,&pval); | 904 | } else { |
886 | /* Only restore if we're still selecting the radio */ | 905 | vp->vfirst = fhp->vnext; |
887 | if (pval == PVR2_CVAL_INPUT_RADIO) { | 906 | } |
888 | pvr2_ctrl_set_value(cp,fhp->prev_input_val); | 907 | fhp->vnext = NULL; |
889 | pvr2_hdw_commit_ctl(hdw); | 908 | fhp->vprev = NULL; |
890 | } | 909 | fhp->vhead = NULL; |
891 | } | 910 | pvr2_channel_done(&fhp->channel); |
892 | 911 | pvr2_trace(PVR2_TRACE_STRUCT, | |
893 | if (fhp->vnext) { | 912 | "Destroying pvr_v4l2_fh id=%p",fhp); |
894 | fhp->vnext->vprev = fhp->vprev; | 913 | if (fhp->input_map) { |
895 | } else { | 914 | kfree(fhp->input_map); |
896 | vp->vlast = fhp->vprev; | 915 | fhp->input_map = NULL; |
897 | } | 916 | } |
898 | if (fhp->vprev) { | 917 | kfree(fhp); |
899 | fhp->vprev->vnext = fhp->vnext; | 918 | if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) { |
900 | } else { | 919 | pvr2_v4l2_destroy_no_lock(vp); |
901 | vp->vfirst = fhp->vnext; | 920 | } |
902 | } | ||
903 | fhp->vnext = NULL; | ||
904 | fhp->vprev = NULL; | ||
905 | fhp->vhead = NULL; | ||
906 | pvr2_channel_done(&fhp->channel); | ||
907 | pvr2_trace(PVR2_TRACE_STRUCT, | ||
908 | "Destroying pvr_v4l2_fh id=%p",fhp); | ||
909 | kfree(fhp); | ||
910 | if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) { | ||
911 | pvr2_v4l2_destroy_no_lock(vp); | ||
912 | } | ||
913 | } while (0); pvr2_context_exit(mp); | ||
914 | return 0; | 921 | return 0; |
915 | } | 922 | } |
916 | 923 | ||
@@ -921,6 +928,9 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file) | |||
921 | struct pvr2_v4l2_fh *fhp; | 928 | struct pvr2_v4l2_fh *fhp; |
922 | struct pvr2_v4l2 *vp; | 929 | struct pvr2_v4l2 *vp; |
923 | struct pvr2_hdw *hdw; | 930 | struct pvr2_hdw *hdw; |
931 | unsigned int input_mask = 0; | ||
932 | unsigned int input_cnt,idx; | ||
933 | int ret = 0; | ||
924 | 934 | ||
925 | dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase); | 935 | dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase); |
926 | 936 | ||
@@ -943,32 +953,62 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file) | |||
943 | init_waitqueue_head(&fhp->wait_data); | 953 | init_waitqueue_head(&fhp->wait_data); |
944 | fhp->dev_info = dip; | 954 | fhp->dev_info = dip; |
945 | 955 | ||
946 | pvr2_context_enter(vp->channel.mc_head); do { | 956 | pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp); |
947 | pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp); | 957 | pvr2_channel_init(&fhp->channel,vp->channel.mc_head); |
948 | pvr2_channel_init(&fhp->channel,vp->channel.mc_head); | ||
949 | 958 | ||
950 | fhp->vnext = NULL; | 959 | if (dip->v4l_type == VFL_TYPE_RADIO) { |
951 | fhp->vprev = vp->vlast; | 960 | /* Opening device as a radio, legal input selection subset |
952 | if (vp->vlast) { | 961 | is just the radio. */ |
953 | vp->vlast->vnext = fhp; | 962 | input_mask = (1 << PVR2_CVAL_INPUT_RADIO); |
954 | } else { | 963 | } else { |
955 | vp->vfirst = fhp; | 964 | /* Opening the main V4L device, legal input selection |
956 | } | 965 | subset includes all analog inputs. */ |
957 | vp->vlast = fhp; | 966 | input_mask = ((1 << PVR2_CVAL_INPUT_RADIO) | |
958 | fhp->vhead = vp; | 967 | (1 << PVR2_CVAL_INPUT_TV) | |
959 | 968 | (1 << PVR2_CVAL_INPUT_COMPOSITE) | | |
960 | /* Opening the /dev/radioX device implies a mode switch. | 969 | (1 << PVR2_CVAL_INPUT_SVIDEO)); |
961 | So execute that here. Note that you can get the | 970 | } |
962 | IDENTICAL effect merely by opening the normal video | 971 | ret = pvr2_channel_limit_inputs(&fhp->channel,input_mask); |
963 | device and setting the input appropriately. */ | 972 | if (ret) { |
964 | if (dip->v4l_type == VFL_TYPE_RADIO) { | 973 | pvr2_channel_done(&fhp->channel); |
965 | struct pvr2_ctrl *cp; | 974 | pvr2_trace(PVR2_TRACE_STRUCT, |
966 | cp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); | 975 | "Destroying pvr_v4l2_fh id=%p (input mask error)", |
967 | pvr2_ctrl_get_value(cp,&fhp->prev_input_val); | 976 | fhp); |
968 | pvr2_ctrl_set_value(cp,PVR2_CVAL_INPUT_RADIO); | 977 | |
969 | pvr2_hdw_commit_ctl(hdw); | 978 | kfree(fhp); |
970 | } | 979 | return ret; |
971 | } while (0); pvr2_context_exit(vp->channel.mc_head); | 980 | } |
981 | |||
982 | input_mask &= pvr2_hdw_get_input_available(hdw); | ||
983 | input_cnt = 0; | ||
984 | for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) { | ||
985 | if (input_mask & (1 << idx)) input_cnt++; | ||
986 | } | ||
987 | fhp->input_cnt = input_cnt; | ||
988 | fhp->input_map = kzalloc(input_cnt,GFP_KERNEL); | ||
989 | if (!fhp->input_map) { | ||
990 | pvr2_channel_done(&fhp->channel); | ||
991 | pvr2_trace(PVR2_TRACE_STRUCT, | ||
992 | "Destroying pvr_v4l2_fh id=%p (input map failure)", | ||
993 | fhp); | ||
994 | kfree(fhp); | ||
995 | return -ENOMEM; | ||
996 | } | ||
997 | input_cnt = 0; | ||
998 | for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) { | ||
999 | if (!(input_mask & (1 << idx))) continue; | ||
1000 | fhp->input_map[input_cnt++] = idx; | ||
1001 | } | ||
1002 | |||
1003 | fhp->vnext = NULL; | ||
1004 | fhp->vprev = vp->vlast; | ||
1005 | if (vp->vlast) { | ||
1006 | vp->vlast->vnext = fhp; | ||
1007 | } else { | ||
1008 | vp->vfirst = fhp; | ||
1009 | } | ||
1010 | vp->vlast = fhp; | ||
1011 | fhp->vhead = vp; | ||
972 | 1012 | ||
973 | fhp->file = file; | 1013 | fhp->file = file; |
974 | file->private_data = fhp; | 1014 | file->private_data = fhp; |
@@ -1201,24 +1241,27 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) | |||
1201 | 1241 | ||
1202 | vp = kzalloc(sizeof(*vp),GFP_KERNEL); | 1242 | vp = kzalloc(sizeof(*vp),GFP_KERNEL); |
1203 | if (!vp) return vp; | 1243 | if (!vp) return vp; |
1204 | vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL); | ||
1205 | vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL); | ||
1206 | if (!(vp->dev_video && vp->dev_radio)) { | ||
1207 | kfree(vp->dev_video); | ||
1208 | kfree(vp->dev_radio); | ||
1209 | kfree(vp); | ||
1210 | return NULL; | ||
1211 | } | ||
1212 | pvr2_channel_init(&vp->channel,mnp); | 1244 | pvr2_channel_init(&vp->channel,mnp); |
1213 | pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp); | 1245 | pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp); |
1214 | 1246 | ||
1215 | vp->channel.check_func = pvr2_v4l2_internal_check; | 1247 | vp->channel.check_func = pvr2_v4l2_internal_check; |
1216 | 1248 | ||
1217 | /* register streams */ | 1249 | /* register streams */ |
1250 | vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL); | ||
1251 | if (!vp->dev_video) goto fail; | ||
1218 | pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_GRABBER); | 1252 | pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_GRABBER); |
1219 | pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO); | 1253 | if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) & |
1254 | (1 << PVR2_CVAL_INPUT_RADIO)) { | ||
1255 | vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL); | ||
1256 | if (!vp->dev_radio) goto fail; | ||
1257 | pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO); | ||
1258 | } | ||
1220 | 1259 | ||
1221 | return vp; | 1260 | return vp; |
1261 | fail: | ||
1262 | pvr2_trace(PVR2_TRACE_STRUCT,"Failure creating pvr2_v4l2 id=%p",vp); | ||
1263 | pvr2_v4l2_destroy_no_lock(vp); | ||
1264 | return 0; | ||
1222 | } | 1265 | } |
1223 | 1266 | ||
1224 | /* | 1267 | /* |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index e0a453a6543d..423fa7c2d0c9 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -130,8 +130,8 @@ static int default_fbufs = 3; /* Default number of frame buffers */ | |||
130 | #ifdef CONFIG_USB_PWC_DEBUG | 130 | #ifdef CONFIG_USB_PWC_DEBUG |
131 | int pwc_trace = PWC_DEBUG_LEVEL; | 131 | int pwc_trace = PWC_DEBUG_LEVEL; |
132 | #endif | 132 | #endif |
133 | static int power_save = 0; | 133 | static int power_save; |
134 | static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */ | 134 | static int led_on = 100, led_off; /* defaults to LED that is on while in use */ |
135 | static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */ | 135 | static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */ |
136 | static struct { | 136 | static struct { |
137 | int type; | 137 | int type; |
@@ -159,7 +159,9 @@ static const struct file_operations pwc_fops = { | |||
159 | .poll = pwc_video_poll, | 159 | .poll = pwc_video_poll, |
160 | .mmap = pwc_video_mmap, | 160 | .mmap = pwc_video_mmap, |
161 | .ioctl = pwc_video_ioctl, | 161 | .ioctl = pwc_video_ioctl, |
162 | #ifdef CONFIG_COMPAT | ||
162 | .compat_ioctl = v4l_compat_ioctl32, | 163 | .compat_ioctl = v4l_compat_ioctl32, |
164 | #endif | ||
163 | .llseek = no_llseek, | 165 | .llseek = no_llseek, |
164 | }; | 166 | }; |
165 | static struct video_device pwc_template = { | 167 | static struct video_device pwc_template = { |
@@ -487,7 +489,7 @@ static void pwc_reset_buffers(struct pwc_device *pdev) | |||
487 | int i; | 489 | int i; |
488 | unsigned long flags; | 490 | unsigned long flags; |
489 | 491 | ||
490 | PWC_DEBUG_MEMORY(">> %s __enter__\n", __FUNCTION__); | 492 | PWC_DEBUG_MEMORY(">> %s __enter__\n", __func__); |
491 | 493 | ||
492 | spin_lock_irqsave(&pdev->ptrlock, flags); | 494 | spin_lock_irqsave(&pdev->ptrlock, flags); |
493 | pdev->full_frames = NULL; | 495 | pdev->full_frames = NULL; |
@@ -509,7 +511,7 @@ static void pwc_reset_buffers(struct pwc_device *pdev) | |||
509 | pdev->fill_image = 0; | 511 | pdev->fill_image = 0; |
510 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | 512 | spin_unlock_irqrestore(&pdev->ptrlock, flags); |
511 | 513 | ||
512 | PWC_DEBUG_MEMORY("<< %s __leaving__\n", __FUNCTION__); | 514 | PWC_DEBUG_MEMORY("<< %s __leaving__\n", __func__); |
513 | } | 515 | } |
514 | 516 | ||
515 | 517 | ||
@@ -786,8 +788,8 @@ static void pwc_isoc_handler(struct urb *urb) | |||
786 | } /* ..status == 0 */ | 788 | } /* ..status == 0 */ |
787 | else { | 789 | else { |
788 | /* This is normally not interesting to the user, unless | 790 | /* This is normally not interesting to the user, unless |
789 | * you are really debugging something */ | 791 | * you are really debugging something, default = 0 */ |
790 | static int iso_error = 0; | 792 | static int iso_error; |
791 | iso_error++; | 793 | iso_error++; |
792 | if (iso_error < 20) | 794 | if (iso_error < 20) |
793 | PWC_DEBUG_FLOW("Iso frame %d of USB has error %d\n", i, fst); | 795 | PWC_DEBUG_FLOW("Iso frame %d of USB has error %d\n", i, fst); |
@@ -1426,7 +1428,7 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) | |||
1426 | unsigned long page, pos = 0; | 1428 | unsigned long page, pos = 0; |
1427 | int index; | 1429 | int index; |
1428 | 1430 | ||
1429 | PWC_DEBUG_MEMORY(">> %s\n", __FUNCTION__); | 1431 | PWC_DEBUG_MEMORY(">> %s\n", __func__); |
1430 | pdev = vdev->priv; | 1432 | pdev = vdev->priv; |
1431 | size = vma->vm_end - vma->vm_start; | 1433 | size = vma->vm_end - vma->vm_start; |
1432 | start = vma->vm_start; | 1434 | start = vma->vm_start; |
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 32fbe1ae6251..1742889874df 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
@@ -351,8 +351,10 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file, | |||
351 | return -EFAULT; | 351 | return -EFAULT; |
352 | 352 | ||
353 | #ifdef CONFIG_USB_PWC_DEBUG | 353 | #ifdef CONFIG_USB_PWC_DEBUG |
354 | if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace) | 354 | if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace) { |
355 | v4l_printk_ioctl(cmd); | 355 | v4l_printk_ioctl(cmd); |
356 | printk("\n"); | ||
357 | } | ||
356 | #endif | 358 | #endif |
357 | 359 | ||
358 | 360 | ||
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c new file mode 100644 index 000000000000..7cc8e9b19fb7 --- /dev/null +++ b/drivers/media/video/pxa_camera.c | |||
@@ -0,0 +1,1206 @@ | |||
1 | /* | ||
2 | * V4L2 Driver for PXA camera host | ||
3 | * | ||
4 | * Copyright (C) 2006, Sascha Hauer, Pengutronix | ||
5 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | ||
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 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/dma-mapping.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/fs.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/mm.h> | ||
23 | #include <linux/moduleparam.h> | ||
24 | #include <linux/time.h> | ||
25 | #include <linux/version.h> | ||
26 | #include <linux/device.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <linux/clk.h> | ||
30 | |||
31 | #include <media/v4l2-common.h> | ||
32 | #include <media/v4l2-dev.h> | ||
33 | #include <media/soc_camera.h> | ||
34 | |||
35 | #include <linux/videodev2.h> | ||
36 | |||
37 | #include <asm/dma.h> | ||
38 | #include <asm/arch/pxa-regs.h> | ||
39 | #include <asm/arch/camera.h> | ||
40 | |||
41 | #define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5) | ||
42 | #define PXA_CAM_DRV_NAME "pxa27x-camera" | ||
43 | |||
44 | #define CICR0_SIM_MP (0 << 24) | ||
45 | #define CICR0_SIM_SP (1 << 24) | ||
46 | #define CICR0_SIM_MS (2 << 24) | ||
47 | #define CICR0_SIM_EP (3 << 24) | ||
48 | #define CICR0_SIM_ES (4 << 24) | ||
49 | |||
50 | #define CICR1_DW_VAL(x) ((x) & CICR1_DW) /* Data bus width */ | ||
51 | #define CICR1_PPL_VAL(x) (((x) << 15) & CICR1_PPL) /* Pixels per line */ | ||
52 | #define CICR1_COLOR_SP_VAL(x) (((x) << 3) & CICR1_COLOR_SP) /* color space */ | ||
53 | #define CICR1_RGB_BPP_VAL(x) (((x) << 7) & CICR1_RGB_BPP) /* bpp for rgb */ | ||
54 | #define CICR1_RGBT_CONV_VAL(x) (((x) << 29) & CICR1_RGBT_CONV) /* rgbt conv */ | ||
55 | |||
56 | #define CICR2_BLW_VAL(x) (((x) << 24) & CICR2_BLW) /* Beginning-of-line pixel clock wait count */ | ||
57 | #define CICR2_ELW_VAL(x) (((x) << 16) & CICR2_ELW) /* End-of-line pixel clock wait count */ | ||
58 | #define CICR2_HSW_VAL(x) (((x) << 10) & CICR2_HSW) /* Horizontal sync pulse width */ | ||
59 | #define CICR2_BFPW_VAL(x) (((x) << 3) & CICR2_BFPW) /* Beginning-of-frame pixel clock wait count */ | ||
60 | #define CICR2_FSW_VAL(x) (((x) << 0) & CICR2_FSW) /* Frame stabilization wait count */ | ||
61 | |||
62 | #define CICR3_BFW_VAL(x) (((x) << 24) & CICR3_BFW) /* Beginning-of-frame line clock wait count */ | ||
63 | #define CICR3_EFW_VAL(x) (((x) << 16) & CICR3_EFW) /* End-of-frame line clock wait count */ | ||
64 | #define CICR3_VSW_VAL(x) (((x) << 11) & CICR3_VSW) /* Vertical sync pulse width */ | ||
65 | #define CICR3_LPF_VAL(x) (((x) << 0) & CICR3_LPF) /* Lines per frame */ | ||
66 | |||
67 | #define CICR0_IRQ_MASK (CICR0_TOM | CICR0_RDAVM | CICR0_FEM | CICR0_EOLM | \ | ||
68 | CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \ | ||
69 | CICR0_EOFM | CICR0_FOM) | ||
70 | |||
71 | static DEFINE_MUTEX(camera_lock); | ||
72 | |||
73 | /* | ||
74 | * Structures | ||
75 | */ | ||
76 | enum pxa_camera_active_dma { | ||
77 | DMA_Y = 0x1, | ||
78 | DMA_U = 0x2, | ||
79 | DMA_V = 0x4, | ||
80 | }; | ||
81 | |||
82 | /* descriptor needed for the PXA DMA engine */ | ||
83 | struct pxa_cam_dma { | ||
84 | dma_addr_t sg_dma; | ||
85 | struct pxa_dma_desc *sg_cpu; | ||
86 | size_t sg_size; | ||
87 | int sglen; | ||
88 | }; | ||
89 | |||
90 | /* buffer for one video frame */ | ||
91 | struct pxa_buffer { | ||
92 | /* common v4l buffer stuff -- must be first */ | ||
93 | struct videobuf_buffer vb; | ||
94 | |||
95 | const struct soc_camera_data_format *fmt; | ||
96 | |||
97 | /* our descriptor lists for Y, U and V channels */ | ||
98 | struct pxa_cam_dma dmas[3]; | ||
99 | |||
100 | int inwork; | ||
101 | |||
102 | enum pxa_camera_active_dma active_dma; | ||
103 | }; | ||
104 | |||
105 | struct pxa_camera_dev { | ||
106 | struct device *dev; | ||
107 | /* PXA27x is only supposed to handle one camera on its Quick Capture | ||
108 | * interface. If anyone ever builds hardware to enable more than | ||
109 | * one camera, they will have to modify this driver too */ | ||
110 | struct soc_camera_device *icd; | ||
111 | struct clk *clk; | ||
112 | |||
113 | unsigned int irq; | ||
114 | void __iomem *base; | ||
115 | |||
116 | int channels; | ||
117 | unsigned int dma_chans[3]; | ||
118 | |||
119 | struct pxacamera_platform_data *pdata; | ||
120 | struct resource *res; | ||
121 | unsigned long platform_flags; | ||
122 | unsigned long platform_mclk_10khz; | ||
123 | |||
124 | struct list_head capture; | ||
125 | |||
126 | spinlock_t lock; | ||
127 | |||
128 | struct pxa_buffer *active; | ||
129 | struct pxa_dma_desc *sg_tail[3]; | ||
130 | }; | ||
131 | |||
132 | static const char *pxa_cam_driver_description = "PXA_Camera"; | ||
133 | |||
134 | static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ | ||
135 | |||
136 | /* | ||
137 | * Videobuf operations | ||
138 | */ | ||
139 | static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, | ||
140 | unsigned int *size) | ||
141 | { | ||
142 | struct soc_camera_device *icd = vq->priv_data; | ||
143 | struct soc_camera_host *ici = | ||
144 | to_soc_camera_host(icd->dev.parent); | ||
145 | struct pxa_camera_dev *pcdev = ici->priv; | ||
146 | |||
147 | dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); | ||
148 | |||
149 | /* planar capture requires Y, U and V buffers to be page aligned */ | ||
150 | if (pcdev->channels == 3) { | ||
151 | *size = PAGE_ALIGN(icd->width * icd->height); /* Y pages */ | ||
152 | *size += PAGE_ALIGN(icd->width * icd->height / 2); /* U pages */ | ||
153 | *size += PAGE_ALIGN(icd->width * icd->height / 2); /* V pages */ | ||
154 | } else { | ||
155 | *size = icd->width * icd->height * | ||
156 | ((icd->current_fmt->depth + 7) >> 3); | ||
157 | } | ||
158 | |||
159 | if (0 == *count) | ||
160 | *count = 32; | ||
161 | while (*size * *count > vid_limit * 1024 * 1024) | ||
162 | (*count)--; | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) | ||
168 | { | ||
169 | struct soc_camera_device *icd = vq->priv_data; | ||
170 | struct soc_camera_host *ici = | ||
171 | to_soc_camera_host(icd->dev.parent); | ||
172 | struct pxa_camera_dev *pcdev = ici->priv; | ||
173 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | ||
174 | int i; | ||
175 | |||
176 | BUG_ON(in_interrupt()); | ||
177 | |||
178 | dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | ||
179 | &buf->vb, buf->vb.baddr, buf->vb.bsize); | ||
180 | |||
181 | /* This waits until this buffer is out of danger, i.e., until it is no | ||
182 | * longer in STATE_QUEUED or STATE_ACTIVE */ | ||
183 | videobuf_waiton(&buf->vb, 0, 0); | ||
184 | videobuf_dma_unmap(vq, dma); | ||
185 | videobuf_dma_free(dma); | ||
186 | |||
187 | for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) { | ||
188 | if (buf->dmas[i].sg_cpu) | ||
189 | dma_free_coherent(pcdev->dev, buf->dmas[i].sg_size, | ||
190 | buf->dmas[i].sg_cpu, | ||
191 | buf->dmas[i].sg_dma); | ||
192 | buf->dmas[i].sg_cpu = NULL; | ||
193 | } | ||
194 | |||
195 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
196 | } | ||
197 | |||
198 | static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev, | ||
199 | struct pxa_buffer *buf, | ||
200 | struct videobuf_dmabuf *dma, int channel, | ||
201 | int sglen, int sg_start, int cibr, | ||
202 | unsigned int size) | ||
203 | { | ||
204 | struct pxa_cam_dma *pxa_dma = &buf->dmas[channel]; | ||
205 | int i; | ||
206 | |||
207 | if (pxa_dma->sg_cpu) | ||
208 | dma_free_coherent(pcdev->dev, pxa_dma->sg_size, | ||
209 | pxa_dma->sg_cpu, pxa_dma->sg_dma); | ||
210 | |||
211 | pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc); | ||
212 | pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->dev, pxa_dma->sg_size, | ||
213 | &pxa_dma->sg_dma, GFP_KERNEL); | ||
214 | if (!pxa_dma->sg_cpu) | ||
215 | return -ENOMEM; | ||
216 | |||
217 | pxa_dma->sglen = sglen; | ||
218 | |||
219 | for (i = 0; i < sglen; i++) { | ||
220 | int sg_i = sg_start + i; | ||
221 | struct scatterlist *sg = dma->sglist; | ||
222 | unsigned int dma_len = sg_dma_len(&sg[sg_i]), xfer_len; | ||
223 | |||
224 | pxa_dma->sg_cpu[i].dsadr = pcdev->res->start + cibr; | ||
225 | pxa_dma->sg_cpu[i].dtadr = sg_dma_address(&sg[sg_i]); | ||
226 | |||
227 | /* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */ | ||
228 | xfer_len = (min(dma_len, size) + 7) & ~7; | ||
229 | |||
230 | pxa_dma->sg_cpu[i].dcmd = | ||
231 | DCMD_FLOWSRC | DCMD_BURST8 | DCMD_INCTRGADDR | xfer_len; | ||
232 | size -= dma_len; | ||
233 | pxa_dma->sg_cpu[i].ddadr = | ||
234 | pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc); | ||
235 | } | ||
236 | |||
237 | pxa_dma->sg_cpu[sglen - 1].ddadr = DDADR_STOP; | ||
238 | pxa_dma->sg_cpu[sglen - 1].dcmd |= DCMD_ENDIRQEN; | ||
239 | |||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static int pxa_videobuf_prepare(struct videobuf_queue *vq, | ||
244 | struct videobuf_buffer *vb, enum v4l2_field field) | ||
245 | { | ||
246 | struct soc_camera_device *icd = vq->priv_data; | ||
247 | struct soc_camera_host *ici = | ||
248 | to_soc_camera_host(icd->dev.parent); | ||
249 | struct pxa_camera_dev *pcdev = ici->priv; | ||
250 | struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); | ||
251 | int ret; | ||
252 | int sglen_y, sglen_yu = 0, sglen_u = 0, sglen_v = 0; | ||
253 | int size_y, size_u = 0, size_v = 0; | ||
254 | |||
255 | dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | ||
256 | vb, vb->baddr, vb->bsize); | ||
257 | |||
258 | /* Added list head initialization on alloc */ | ||
259 | WARN_ON(!list_empty(&vb->queue)); | ||
260 | |||
261 | #ifdef DEBUG | ||
262 | /* This can be useful if you want to see if we actually fill | ||
263 | * the buffer with something */ | ||
264 | memset((void *)vb->baddr, 0xaa, vb->bsize); | ||
265 | #endif | ||
266 | |||
267 | BUG_ON(NULL == icd->current_fmt); | ||
268 | |||
269 | /* I think, in buf_prepare you only have to protect global data, | ||
270 | * the actual buffer is yours */ | ||
271 | buf->inwork = 1; | ||
272 | |||
273 | if (buf->fmt != icd->current_fmt || | ||
274 | vb->width != icd->width || | ||
275 | vb->height != icd->height || | ||
276 | vb->field != field) { | ||
277 | buf->fmt = icd->current_fmt; | ||
278 | vb->width = icd->width; | ||
279 | vb->height = icd->height; | ||
280 | vb->field = field; | ||
281 | vb->state = VIDEOBUF_NEEDS_INIT; | ||
282 | } | ||
283 | |||
284 | vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); | ||
285 | if (0 != vb->baddr && vb->bsize < vb->size) { | ||
286 | ret = -EINVAL; | ||
287 | goto out; | ||
288 | } | ||
289 | |||
290 | if (vb->state == VIDEOBUF_NEEDS_INIT) { | ||
291 | unsigned int size = vb->size; | ||
292 | struct videobuf_dmabuf *dma = videobuf_to_dma(vb); | ||
293 | |||
294 | ret = videobuf_iolock(vq, vb, NULL); | ||
295 | if (ret) | ||
296 | goto fail; | ||
297 | |||
298 | if (pcdev->channels == 3) { | ||
299 | /* FIXME the calculations should be more precise */ | ||
300 | sglen_y = dma->sglen / 2; | ||
301 | sglen_u = sglen_v = dma->sglen / 4 + 1; | ||
302 | sglen_yu = sglen_y + sglen_u; | ||
303 | size_y = size / 2; | ||
304 | size_u = size_v = size / 4; | ||
305 | } else { | ||
306 | sglen_y = dma->sglen; | ||
307 | size_y = size; | ||
308 | } | ||
309 | |||
310 | /* init DMA for Y channel */ | ||
311 | ret = pxa_init_dma_channel(pcdev, buf, dma, 0, sglen_y, | ||
312 | 0, 0x28, size_y); | ||
313 | |||
314 | if (ret) { | ||
315 | dev_err(pcdev->dev, | ||
316 | "DMA initialization for Y/RGB failed\n"); | ||
317 | goto fail; | ||
318 | } | ||
319 | |||
320 | if (pcdev->channels == 3) { | ||
321 | /* init DMA for U channel */ | ||
322 | ret = pxa_init_dma_channel(pcdev, buf, dma, 1, sglen_u, | ||
323 | sglen_y, 0x30, size_u); | ||
324 | if (ret) { | ||
325 | dev_err(pcdev->dev, | ||
326 | "DMA initialization for U failed\n"); | ||
327 | goto fail_u; | ||
328 | } | ||
329 | |||
330 | /* init DMA for V channel */ | ||
331 | ret = pxa_init_dma_channel(pcdev, buf, dma, 2, sglen_v, | ||
332 | sglen_yu, 0x38, size_v); | ||
333 | if (ret) { | ||
334 | dev_err(pcdev->dev, | ||
335 | "DMA initialization for V failed\n"); | ||
336 | goto fail_v; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | vb->state = VIDEOBUF_PREPARED; | ||
341 | } | ||
342 | |||
343 | buf->inwork = 0; | ||
344 | buf->active_dma = DMA_Y; | ||
345 | if (pcdev->channels == 3) | ||
346 | buf->active_dma |= DMA_U | DMA_V; | ||
347 | |||
348 | return 0; | ||
349 | |||
350 | fail_v: | ||
351 | dma_free_coherent(pcdev->dev, buf->dmas[1].sg_size, | ||
352 | buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma); | ||
353 | fail_u: | ||
354 | dma_free_coherent(pcdev->dev, buf->dmas[0].sg_size, | ||
355 | buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma); | ||
356 | fail: | ||
357 | free_buffer(vq, buf); | ||
358 | out: | ||
359 | buf->inwork = 0; | ||
360 | return ret; | ||
361 | } | ||
362 | |||
363 | static void pxa_videobuf_queue(struct videobuf_queue *vq, | ||
364 | struct videobuf_buffer *vb) | ||
365 | { | ||
366 | struct soc_camera_device *icd = vq->priv_data; | ||
367 | struct soc_camera_host *ici = | ||
368 | to_soc_camera_host(icd->dev.parent); | ||
369 | struct pxa_camera_dev *pcdev = ici->priv; | ||
370 | struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); | ||
371 | struct pxa_buffer *active; | ||
372 | unsigned long flags; | ||
373 | int i; | ||
374 | |||
375 | dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | ||
376 | vb, vb->baddr, vb->bsize); | ||
377 | spin_lock_irqsave(&pcdev->lock, flags); | ||
378 | |||
379 | list_add_tail(&vb->queue, &pcdev->capture); | ||
380 | |||
381 | vb->state = VIDEOBUF_ACTIVE; | ||
382 | active = pcdev->active; | ||
383 | |||
384 | if (!active) { | ||
385 | CIFR |= CIFR_RESET_F; | ||
386 | |||
387 | for (i = 0; i < pcdev->channels; i++) { | ||
388 | DDADR(pcdev->dma_chans[i]) = buf->dmas[i].sg_dma; | ||
389 | DCSR(pcdev->dma_chans[i]) = DCSR_RUN; | ||
390 | pcdev->sg_tail[i] = buf->dmas[i].sg_cpu + buf->dmas[i].sglen - 1; | ||
391 | } | ||
392 | |||
393 | pcdev->active = buf; | ||
394 | CICR0 |= CICR0_ENB; | ||
395 | } else { | ||
396 | struct pxa_cam_dma *buf_dma; | ||
397 | struct pxa_cam_dma *act_dma; | ||
398 | int nents; | ||
399 | |||
400 | for (i = 0; i < pcdev->channels; i++) { | ||
401 | buf_dma = &buf->dmas[i]; | ||
402 | act_dma = &active->dmas[i]; | ||
403 | nents = buf_dma->sglen; | ||
404 | |||
405 | /* Stop DMA engine */ | ||
406 | DCSR(pcdev->dma_chans[i]) = 0; | ||
407 | |||
408 | /* Add the descriptors we just initialized to | ||
409 | the currently running chain */ | ||
410 | pcdev->sg_tail[i]->ddadr = buf_dma->sg_dma; | ||
411 | pcdev->sg_tail[i] = buf_dma->sg_cpu + buf_dma->sglen - 1; | ||
412 | |||
413 | /* Setup a dummy descriptor with the DMA engines current | ||
414 | * state | ||
415 | */ | ||
416 | buf_dma->sg_cpu[nents].dsadr = | ||
417 | pcdev->res->start + 0x28 + i*8; /* CIBRx */ | ||
418 | buf_dma->sg_cpu[nents].dtadr = | ||
419 | DTADR(pcdev->dma_chans[i]); | ||
420 | buf_dma->sg_cpu[nents].dcmd = | ||
421 | DCMD(pcdev->dma_chans[i]); | ||
422 | |||
423 | if (DDADR(pcdev->dma_chans[i]) == DDADR_STOP) { | ||
424 | /* The DMA engine is on the last | ||
425 | descriptor, set the next descriptors | ||
426 | address to the descriptors we just | ||
427 | initialized */ | ||
428 | buf_dma->sg_cpu[nents].ddadr = buf_dma->sg_dma; | ||
429 | } else { | ||
430 | buf_dma->sg_cpu[nents].ddadr = | ||
431 | DDADR(pcdev->dma_chans[i]); | ||
432 | } | ||
433 | |||
434 | /* The next descriptor is the dummy descriptor */ | ||
435 | DDADR(pcdev->dma_chans[i]) = buf_dma->sg_dma + nents * | ||
436 | sizeof(struct pxa_dma_desc); | ||
437 | |||
438 | DCSR(pcdev->dma_chans[i]) = DCSR_RUN; | ||
439 | } | ||
440 | } | ||
441 | |||
442 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
443 | } | ||
444 | |||
445 | static void pxa_videobuf_release(struct videobuf_queue *vq, | ||
446 | struct videobuf_buffer *vb) | ||
447 | { | ||
448 | struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); | ||
449 | #ifdef DEBUG | ||
450 | struct soc_camera_device *icd = vq->priv_data; | ||
451 | |||
452 | dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | ||
453 | vb, vb->baddr, vb->bsize); | ||
454 | |||
455 | switch (vb->state) { | ||
456 | case VIDEOBUF_ACTIVE: | ||
457 | dev_dbg(&icd->dev, "%s (active)\n", __func__); | ||
458 | break; | ||
459 | case VIDEOBUF_QUEUED: | ||
460 | dev_dbg(&icd->dev, "%s (queued)\n", __func__); | ||
461 | break; | ||
462 | case VIDEOBUF_PREPARED: | ||
463 | dev_dbg(&icd->dev, "%s (prepared)\n", __func__); | ||
464 | break; | ||
465 | default: | ||
466 | dev_dbg(&icd->dev, "%s (unknown)\n", __func__); | ||
467 | break; | ||
468 | } | ||
469 | #endif | ||
470 | |||
471 | free_buffer(vq, buf); | ||
472 | } | ||
473 | |||
474 | static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev, | ||
475 | struct videobuf_buffer *vb, | ||
476 | struct pxa_buffer *buf) | ||
477 | { | ||
478 | /* _init is used to debug races, see comment in pxa_camera_reqbufs() */ | ||
479 | list_del_init(&vb->queue); | ||
480 | vb->state = VIDEOBUF_DONE; | ||
481 | do_gettimeofday(&vb->ts); | ||
482 | vb->field_count++; | ||
483 | wake_up(&vb->done); | ||
484 | |||
485 | if (list_empty(&pcdev->capture)) { | ||
486 | pcdev->active = NULL; | ||
487 | DCSR(pcdev->dma_chans[0]) = 0; | ||
488 | DCSR(pcdev->dma_chans[1]) = 0; | ||
489 | DCSR(pcdev->dma_chans[2]) = 0; | ||
490 | CICR0 &= ~CICR0_ENB; | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | pcdev->active = list_entry(pcdev->capture.next, | ||
495 | struct pxa_buffer, vb.queue); | ||
496 | } | ||
497 | |||
498 | static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, | ||
499 | enum pxa_camera_active_dma act_dma) | ||
500 | { | ||
501 | struct pxa_buffer *buf; | ||
502 | unsigned long flags; | ||
503 | u32 status, camera_status, overrun; | ||
504 | struct videobuf_buffer *vb; | ||
505 | |||
506 | spin_lock_irqsave(&pcdev->lock, flags); | ||
507 | |||
508 | status = DCSR(channel); | ||
509 | DCSR(channel) = status | DCSR_ENDINTR; | ||
510 | |||
511 | if (status & DCSR_BUSERR) { | ||
512 | dev_err(pcdev->dev, "DMA Bus Error IRQ!\n"); | ||
513 | goto out; | ||
514 | } | ||
515 | |||
516 | if (!(status & DCSR_ENDINTR)) { | ||
517 | dev_err(pcdev->dev, "Unknown DMA IRQ source, " | ||
518 | "status: 0x%08x\n", status); | ||
519 | goto out; | ||
520 | } | ||
521 | |||
522 | if (!pcdev->active) { | ||
523 | dev_err(pcdev->dev, "DMA End IRQ with no active buffer!\n"); | ||
524 | goto out; | ||
525 | } | ||
526 | |||
527 | camera_status = CISR; | ||
528 | overrun = CISR_IFO_0; | ||
529 | if (pcdev->channels == 3) | ||
530 | overrun |= CISR_IFO_1 | CISR_IFO_2; | ||
531 | if (camera_status & overrun) { | ||
532 | dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", camera_status); | ||
533 | /* Stop the Capture Interface */ | ||
534 | CICR0 &= ~CICR0_ENB; | ||
535 | /* Stop DMA */ | ||
536 | DCSR(channel) = 0; | ||
537 | /* Reset the FIFOs */ | ||
538 | CIFR |= CIFR_RESET_F; | ||
539 | /* Enable End-Of-Frame Interrupt */ | ||
540 | CICR0 &= ~CICR0_EOFM; | ||
541 | /* Restart the Capture Interface */ | ||
542 | CICR0 |= CICR0_ENB; | ||
543 | goto out; | ||
544 | } | ||
545 | |||
546 | vb = &pcdev->active->vb; | ||
547 | buf = container_of(vb, struct pxa_buffer, vb); | ||
548 | WARN_ON(buf->inwork || list_empty(&vb->queue)); | ||
549 | dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | ||
550 | vb, vb->baddr, vb->bsize); | ||
551 | |||
552 | buf->active_dma &= ~act_dma; | ||
553 | if (!buf->active_dma) | ||
554 | pxa_camera_wakeup(pcdev, vb, buf); | ||
555 | |||
556 | out: | ||
557 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
558 | } | ||
559 | |||
560 | static void pxa_camera_dma_irq_y(int channel, void *data) | ||
561 | { | ||
562 | struct pxa_camera_dev *pcdev = data; | ||
563 | pxa_camera_dma_irq(channel, pcdev, DMA_Y); | ||
564 | } | ||
565 | |||
566 | static void pxa_camera_dma_irq_u(int channel, void *data) | ||
567 | { | ||
568 | struct pxa_camera_dev *pcdev = data; | ||
569 | pxa_camera_dma_irq(channel, pcdev, DMA_U); | ||
570 | } | ||
571 | |||
572 | static void pxa_camera_dma_irq_v(int channel, void *data) | ||
573 | { | ||
574 | struct pxa_camera_dev *pcdev = data; | ||
575 | pxa_camera_dma_irq(channel, pcdev, DMA_V); | ||
576 | } | ||
577 | |||
578 | static struct videobuf_queue_ops pxa_videobuf_ops = { | ||
579 | .buf_setup = pxa_videobuf_setup, | ||
580 | .buf_prepare = pxa_videobuf_prepare, | ||
581 | .buf_queue = pxa_videobuf_queue, | ||
582 | .buf_release = pxa_videobuf_release, | ||
583 | }; | ||
584 | |||
585 | static int mclk_get_divisor(struct pxa_camera_dev *pcdev) | ||
586 | { | ||
587 | unsigned int mclk_10khz = pcdev->platform_mclk_10khz; | ||
588 | unsigned long div; | ||
589 | unsigned long lcdclk; | ||
590 | |||
591 | lcdclk = clk_get_rate(pcdev->clk) / 10000; | ||
592 | |||
593 | /* We verify platform_mclk_10khz != 0, so if anyone breaks it, here | ||
594 | * they get a nice Oops */ | ||
595 | div = (lcdclk + 2 * mclk_10khz - 1) / (2 * mclk_10khz) - 1; | ||
596 | |||
597 | dev_dbg(pcdev->dev, "LCD clock %lukHz, target freq %dkHz, " | ||
598 | "divisor %lu\n", lcdclk * 10, mclk_10khz * 10, div); | ||
599 | |||
600 | return div; | ||
601 | } | ||
602 | |||
603 | static void pxa_camera_activate(struct pxa_camera_dev *pcdev) | ||
604 | { | ||
605 | struct pxacamera_platform_data *pdata = pcdev->pdata; | ||
606 | u32 cicr4 = 0; | ||
607 | |||
608 | dev_dbg(pcdev->dev, "Registered platform device at %p data %p\n", | ||
609 | pcdev, pdata); | ||
610 | |||
611 | if (pdata && pdata->init) { | ||
612 | dev_dbg(pcdev->dev, "%s: Init gpios\n", __func__); | ||
613 | pdata->init(pcdev->dev); | ||
614 | } | ||
615 | |||
616 | if (pdata && pdata->power) { | ||
617 | dev_dbg(pcdev->dev, "%s: Power on camera\n", __func__); | ||
618 | pdata->power(pcdev->dev, 1); | ||
619 | } | ||
620 | |||
621 | if (pdata && pdata->reset) { | ||
622 | dev_dbg(pcdev->dev, "%s: Releasing camera reset\n", | ||
623 | __func__); | ||
624 | pdata->reset(pcdev->dev, 1); | ||
625 | } | ||
626 | |||
627 | CICR0 = 0x3FF; /* disable all interrupts */ | ||
628 | |||
629 | if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) | ||
630 | cicr4 |= CICR4_PCLK_EN; | ||
631 | if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) | ||
632 | cicr4 |= CICR4_MCLK_EN; | ||
633 | if (pcdev->platform_flags & PXA_CAMERA_PCP) | ||
634 | cicr4 |= CICR4_PCP; | ||
635 | if (pcdev->platform_flags & PXA_CAMERA_HSP) | ||
636 | cicr4 |= CICR4_HSP; | ||
637 | if (pcdev->platform_flags & PXA_CAMERA_VSP) | ||
638 | cicr4 |= CICR4_VSP; | ||
639 | |||
640 | CICR4 = mclk_get_divisor(pcdev) | cicr4; | ||
641 | |||
642 | clk_enable(pcdev->clk); | ||
643 | } | ||
644 | |||
645 | static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev) | ||
646 | { | ||
647 | struct pxacamera_platform_data *board = pcdev->pdata; | ||
648 | |||
649 | clk_disable(pcdev->clk); | ||
650 | |||
651 | if (board && board->reset) { | ||
652 | dev_dbg(pcdev->dev, "%s: Asserting camera reset\n", | ||
653 | __func__); | ||
654 | board->reset(pcdev->dev, 0); | ||
655 | } | ||
656 | |||
657 | if (board && board->power) { | ||
658 | dev_dbg(pcdev->dev, "%s: Power off camera\n", __func__); | ||
659 | board->power(pcdev->dev, 0); | ||
660 | } | ||
661 | } | ||
662 | |||
663 | static irqreturn_t pxa_camera_irq(int irq, void *data) | ||
664 | { | ||
665 | struct pxa_camera_dev *pcdev = data; | ||
666 | unsigned int status = CISR; | ||
667 | |||
668 | dev_dbg(pcdev->dev, "Camera interrupt status 0x%x\n", status); | ||
669 | |||
670 | if (!status) | ||
671 | return IRQ_NONE; | ||
672 | |||
673 | CISR = status; | ||
674 | |||
675 | if (status & CISR_EOF) { | ||
676 | int i; | ||
677 | for (i = 0; i < pcdev->channels; i++) { | ||
678 | DDADR(pcdev->dma_chans[i]) = | ||
679 | pcdev->active->dmas[i].sg_dma; | ||
680 | DCSR(pcdev->dma_chans[i]) = DCSR_RUN; | ||
681 | } | ||
682 | CICR0 |= CICR0_EOFM; | ||
683 | } | ||
684 | |||
685 | return IRQ_HANDLED; | ||
686 | } | ||
687 | |||
688 | /* The following two functions absolutely depend on the fact, that | ||
689 | * there can be only one camera on PXA quick capture interface */ | ||
690 | static int pxa_camera_add_device(struct soc_camera_device *icd) | ||
691 | { | ||
692 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
693 | struct pxa_camera_dev *pcdev = ici->priv; | ||
694 | int ret; | ||
695 | |||
696 | mutex_lock(&camera_lock); | ||
697 | |||
698 | if (pcdev->icd) { | ||
699 | ret = -EBUSY; | ||
700 | goto ebusy; | ||
701 | } | ||
702 | |||
703 | dev_info(&icd->dev, "PXA Camera driver attached to camera %d\n", | ||
704 | icd->devnum); | ||
705 | |||
706 | pxa_camera_activate(pcdev); | ||
707 | ret = icd->ops->init(icd); | ||
708 | |||
709 | if (!ret) | ||
710 | pcdev->icd = icd; | ||
711 | |||
712 | ebusy: | ||
713 | mutex_unlock(&camera_lock); | ||
714 | |||
715 | return ret; | ||
716 | } | ||
717 | |||
718 | static void pxa_camera_remove_device(struct soc_camera_device *icd) | ||
719 | { | ||
720 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
721 | struct pxa_camera_dev *pcdev = ici->priv; | ||
722 | |||
723 | BUG_ON(icd != pcdev->icd); | ||
724 | |||
725 | dev_info(&icd->dev, "PXA Camera driver detached from camera %d\n", | ||
726 | icd->devnum); | ||
727 | |||
728 | /* disable capture, disable interrupts */ | ||
729 | CICR0 = 0x3ff; | ||
730 | |||
731 | /* Stop DMA engine */ | ||
732 | DCSR(pcdev->dma_chans[0]) = 0; | ||
733 | DCSR(pcdev->dma_chans[1]) = 0; | ||
734 | DCSR(pcdev->dma_chans[2]) = 0; | ||
735 | |||
736 | icd->ops->release(icd); | ||
737 | |||
738 | pxa_camera_deactivate(pcdev); | ||
739 | |||
740 | pcdev->icd = NULL; | ||
741 | } | ||
742 | |||
743 | static int test_platform_param(struct pxa_camera_dev *pcdev, | ||
744 | unsigned char buswidth, unsigned long *flags) | ||
745 | { | ||
746 | /* | ||
747 | * Platform specified synchronization and pixel clock polarities are | ||
748 | * only a recommendation and are only used during probing. The PXA270 | ||
749 | * quick capture interface supports both. | ||
750 | */ | ||
751 | *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ? | ||
752 | SOCAM_MASTER : SOCAM_SLAVE) | | ||
753 | SOCAM_HSYNC_ACTIVE_HIGH | | ||
754 | SOCAM_HSYNC_ACTIVE_LOW | | ||
755 | SOCAM_VSYNC_ACTIVE_HIGH | | ||
756 | SOCAM_VSYNC_ACTIVE_LOW | | ||
757 | SOCAM_PCLK_SAMPLE_RISING | | ||
758 | SOCAM_PCLK_SAMPLE_FALLING; | ||
759 | |||
760 | /* If requested data width is supported by the platform, use it */ | ||
761 | switch (buswidth) { | ||
762 | case 10: | ||
763 | if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10)) | ||
764 | return -EINVAL; | ||
765 | *flags |= SOCAM_DATAWIDTH_10; | ||
766 | break; | ||
767 | case 9: | ||
768 | if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9)) | ||
769 | return -EINVAL; | ||
770 | *flags |= SOCAM_DATAWIDTH_9; | ||
771 | break; | ||
772 | case 8: | ||
773 | if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8)) | ||
774 | return -EINVAL; | ||
775 | *flags |= SOCAM_DATAWIDTH_8; | ||
776 | } | ||
777 | |||
778 | return 0; | ||
779 | } | ||
780 | |||
781 | static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | ||
782 | { | ||
783 | struct soc_camera_host *ici = | ||
784 | to_soc_camera_host(icd->dev.parent); | ||
785 | struct pxa_camera_dev *pcdev = ici->priv; | ||
786 | unsigned long dw, bpp, bus_flags, camera_flags, common_flags; | ||
787 | u32 cicr0, cicr1, cicr4 = 0; | ||
788 | int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags); | ||
789 | |||
790 | if (ret < 0) | ||
791 | return ret; | ||
792 | |||
793 | camera_flags = icd->ops->query_bus_param(icd); | ||
794 | |||
795 | common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); | ||
796 | if (!common_flags) | ||
797 | return -EINVAL; | ||
798 | |||
799 | pcdev->channels = 1; | ||
800 | |||
801 | /* Make choises, based on platform preferences */ | ||
802 | if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && | ||
803 | (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { | ||
804 | if (pcdev->platform_flags & PXA_CAMERA_HSP) | ||
805 | common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; | ||
806 | else | ||
807 | common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; | ||
808 | } | ||
809 | |||
810 | if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && | ||
811 | (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { | ||
812 | if (pcdev->platform_flags & PXA_CAMERA_VSP) | ||
813 | common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; | ||
814 | else | ||
815 | common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; | ||
816 | } | ||
817 | |||
818 | if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && | ||
819 | (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { | ||
820 | if (pcdev->platform_flags & PXA_CAMERA_PCP) | ||
821 | common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; | ||
822 | else | ||
823 | common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; | ||
824 | } | ||
825 | |||
826 | ret = icd->ops->set_bus_param(icd, common_flags); | ||
827 | if (ret < 0) | ||
828 | return ret; | ||
829 | |||
830 | /* Datawidth is now guaranteed to be equal to one of the three values. | ||
831 | * We fix bit-per-pixel equal to data-width... */ | ||
832 | switch (common_flags & SOCAM_DATAWIDTH_MASK) { | ||
833 | case SOCAM_DATAWIDTH_10: | ||
834 | icd->buswidth = 10; | ||
835 | dw = 4; | ||
836 | bpp = 0x40; | ||
837 | break; | ||
838 | case SOCAM_DATAWIDTH_9: | ||
839 | icd->buswidth = 9; | ||
840 | dw = 3; | ||
841 | bpp = 0x20; | ||
842 | break; | ||
843 | default: | ||
844 | /* Actually it can only be 8 now, | ||
845 | * default is just to silence compiler warnings */ | ||
846 | case SOCAM_DATAWIDTH_8: | ||
847 | icd->buswidth = 8; | ||
848 | dw = 2; | ||
849 | bpp = 0; | ||
850 | } | ||
851 | |||
852 | if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) | ||
853 | cicr4 |= CICR4_PCLK_EN; | ||
854 | if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) | ||
855 | cicr4 |= CICR4_MCLK_EN; | ||
856 | if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) | ||
857 | cicr4 |= CICR4_PCP; | ||
858 | if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) | ||
859 | cicr4 |= CICR4_HSP; | ||
860 | if (common_flags & SOCAM_VSYNC_ACTIVE_LOW) | ||
861 | cicr4 |= CICR4_VSP; | ||
862 | |||
863 | cicr0 = CICR0; | ||
864 | if (cicr0 & CICR0_ENB) | ||
865 | CICR0 = cicr0 & ~CICR0_ENB; | ||
866 | |||
867 | cicr1 = CICR1_PPL_VAL(icd->width - 1) | bpp | dw; | ||
868 | |||
869 | switch (pixfmt) { | ||
870 | case V4L2_PIX_FMT_YUV422P: | ||
871 | pcdev->channels = 3; | ||
872 | cicr1 |= CICR1_YCBCR_F; | ||
873 | case V4L2_PIX_FMT_YUYV: | ||
874 | cicr1 |= CICR1_COLOR_SP_VAL(2); | ||
875 | break; | ||
876 | case V4L2_PIX_FMT_RGB555: | ||
877 | cicr1 |= CICR1_RGB_BPP_VAL(1) | CICR1_RGBT_CONV_VAL(2) | | ||
878 | CICR1_TBIT | CICR1_COLOR_SP_VAL(1); | ||
879 | break; | ||
880 | case V4L2_PIX_FMT_RGB565: | ||
881 | cicr1 |= CICR1_COLOR_SP_VAL(1) | CICR1_RGB_BPP_VAL(2); | ||
882 | break; | ||
883 | } | ||
884 | |||
885 | CICR1 = cicr1; | ||
886 | CICR2 = 0; | ||
887 | CICR3 = CICR3_LPF_VAL(icd->height - 1) | | ||
888 | CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top)); | ||
889 | CICR4 = mclk_get_divisor(pcdev) | cicr4; | ||
890 | |||
891 | /* CIF interrupts are not used, only DMA */ | ||
892 | CICR0 = (pcdev->platform_flags & PXA_CAMERA_MASTER ? | ||
893 | CICR0_SIM_MP : (CICR0_SL_CAP_EN | CICR0_SIM_SP)) | | ||
894 | CICR0_DMAEN | CICR0_IRQ_MASK | (cicr0 & CICR0_ENB); | ||
895 | |||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | static int pxa_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | ||
900 | { | ||
901 | struct soc_camera_host *ici = | ||
902 | to_soc_camera_host(icd->dev.parent); | ||
903 | struct pxa_camera_dev *pcdev = ici->priv; | ||
904 | unsigned long bus_flags, camera_flags; | ||
905 | int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags); | ||
906 | |||
907 | if (ret < 0) | ||
908 | return ret; | ||
909 | |||
910 | camera_flags = icd->ops->query_bus_param(icd); | ||
911 | |||
912 | return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL; | ||
913 | } | ||
914 | |||
915 | static int pxa_camera_set_fmt_cap(struct soc_camera_device *icd, | ||
916 | __u32 pixfmt, struct v4l2_rect *rect) | ||
917 | { | ||
918 | return icd->ops->set_fmt_cap(icd, pixfmt, rect); | ||
919 | } | ||
920 | |||
921 | static int pxa_camera_try_fmt_cap(struct soc_camera_device *icd, | ||
922 | struct v4l2_format *f) | ||
923 | { | ||
924 | /* limit to pxa hardware capabilities */ | ||
925 | if (f->fmt.pix.height < 32) | ||
926 | f->fmt.pix.height = 32; | ||
927 | if (f->fmt.pix.height > 2048) | ||
928 | f->fmt.pix.height = 2048; | ||
929 | if (f->fmt.pix.width < 48) | ||
930 | f->fmt.pix.width = 48; | ||
931 | if (f->fmt.pix.width > 2048) | ||
932 | f->fmt.pix.width = 2048; | ||
933 | f->fmt.pix.width &= ~0x01; | ||
934 | |||
935 | /* limit to sensor capabilities */ | ||
936 | return icd->ops->try_fmt_cap(icd, f); | ||
937 | } | ||
938 | |||
939 | static int pxa_camera_reqbufs(struct soc_camera_file *icf, | ||
940 | struct v4l2_requestbuffers *p) | ||
941 | { | ||
942 | int i; | ||
943 | |||
944 | /* This is for locking debugging only. I removed spinlocks and now I | ||
945 | * check whether .prepare is ever called on a linked buffer, or whether | ||
946 | * a dma IRQ can occur for an in-work or unlinked buffer. Until now | ||
947 | * it hadn't triggered */ | ||
948 | for (i = 0; i < p->count; i++) { | ||
949 | struct pxa_buffer *buf = container_of(icf->vb_vidq.bufs[i], | ||
950 | struct pxa_buffer, vb); | ||
951 | buf->inwork = 0; | ||
952 | INIT_LIST_HEAD(&buf->vb.queue); | ||
953 | } | ||
954 | |||
955 | return 0; | ||
956 | } | ||
957 | |||
958 | static unsigned int pxa_camera_poll(struct file *file, poll_table *pt) | ||
959 | { | ||
960 | struct soc_camera_file *icf = file->private_data; | ||
961 | struct pxa_buffer *buf; | ||
962 | |||
963 | buf = list_entry(icf->vb_vidq.stream.next, struct pxa_buffer, | ||
964 | vb.stream); | ||
965 | |||
966 | poll_wait(file, &buf->vb.done, pt); | ||
967 | |||
968 | if (buf->vb.state == VIDEOBUF_DONE || | ||
969 | buf->vb.state == VIDEOBUF_ERROR) | ||
970 | return POLLIN|POLLRDNORM; | ||
971 | |||
972 | return 0; | ||
973 | } | ||
974 | |||
975 | static int pxa_camera_querycap(struct soc_camera_host *ici, | ||
976 | struct v4l2_capability *cap) | ||
977 | { | ||
978 | /* cap->name is set by the firendly caller:-> */ | ||
979 | strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card)); | ||
980 | cap->version = PXA_CAM_VERSION_CODE; | ||
981 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | ||
982 | |||
983 | return 0; | ||
984 | } | ||
985 | |||
986 | static spinlock_t *pxa_camera_spinlock_alloc(struct soc_camera_file *icf) | ||
987 | { | ||
988 | struct soc_camera_host *ici = | ||
989 | to_soc_camera_host(icf->icd->dev.parent); | ||
990 | struct pxa_camera_dev *pcdev = ici->priv; | ||
991 | |||
992 | return &pcdev->lock; | ||
993 | } | ||
994 | |||
995 | static struct soc_camera_host_ops pxa_soc_camera_host_ops = { | ||
996 | .owner = THIS_MODULE, | ||
997 | .add = pxa_camera_add_device, | ||
998 | .remove = pxa_camera_remove_device, | ||
999 | .set_fmt_cap = pxa_camera_set_fmt_cap, | ||
1000 | .try_fmt_cap = pxa_camera_try_fmt_cap, | ||
1001 | .reqbufs = pxa_camera_reqbufs, | ||
1002 | .poll = pxa_camera_poll, | ||
1003 | .querycap = pxa_camera_querycap, | ||
1004 | .try_bus_param = pxa_camera_try_bus_param, | ||
1005 | .set_bus_param = pxa_camera_set_bus_param, | ||
1006 | .spinlock_alloc = pxa_camera_spinlock_alloc, | ||
1007 | }; | ||
1008 | |||
1009 | /* Should be allocated dynamically too, but we have only one. */ | ||
1010 | static struct soc_camera_host pxa_soc_camera_host = { | ||
1011 | .drv_name = PXA_CAM_DRV_NAME, | ||
1012 | .vbq_ops = &pxa_videobuf_ops, | ||
1013 | .msize = sizeof(struct pxa_buffer), | ||
1014 | .ops = &pxa_soc_camera_host_ops, | ||
1015 | }; | ||
1016 | |||
1017 | static int pxa_camera_probe(struct platform_device *pdev) | ||
1018 | { | ||
1019 | struct pxa_camera_dev *pcdev; | ||
1020 | struct resource *res; | ||
1021 | void __iomem *base; | ||
1022 | unsigned int irq; | ||
1023 | int err = 0; | ||
1024 | |||
1025 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1026 | irq = platform_get_irq(pdev, 0); | ||
1027 | if (!res || !irq) { | ||
1028 | err = -ENODEV; | ||
1029 | goto exit; | ||
1030 | } | ||
1031 | |||
1032 | pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL); | ||
1033 | if (!pcdev) { | ||
1034 | dev_err(&pdev->dev, "Could not allocate pcdev\n"); | ||
1035 | err = -ENOMEM; | ||
1036 | goto exit; | ||
1037 | } | ||
1038 | |||
1039 | pcdev->clk = clk_get(&pdev->dev, "CAMCLK"); | ||
1040 | if (IS_ERR(pcdev->clk)) { | ||
1041 | err = PTR_ERR(pcdev->clk); | ||
1042 | goto exit_kfree; | ||
1043 | } | ||
1044 | |||
1045 | dev_set_drvdata(&pdev->dev, pcdev); | ||
1046 | pcdev->res = res; | ||
1047 | |||
1048 | pcdev->pdata = pdev->dev.platform_data; | ||
1049 | pcdev->platform_flags = pcdev->pdata->flags; | ||
1050 | if (!(pcdev->platform_flags & (PXA_CAMERA_DATAWIDTH_8 | | ||
1051 | PXA_CAMERA_DATAWIDTH_9 | PXA_CAMERA_DATAWIDTH_10))) { | ||
1052 | /* Platform hasn't set available data widths. This is bad. | ||
1053 | * Warn and use a default. */ | ||
1054 | dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " | ||
1055 | "data widths, using default 10 bit\n"); | ||
1056 | pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10; | ||
1057 | } | ||
1058 | pcdev->platform_mclk_10khz = pcdev->pdata->mclk_10khz; | ||
1059 | if (!pcdev->platform_mclk_10khz) { | ||
1060 | dev_warn(&pdev->dev, | ||
1061 | "mclk_10khz == 0! Please, fix your platform data. " | ||
1062 | "Using default 20MHz\n"); | ||
1063 | pcdev->platform_mclk_10khz = 2000; | ||
1064 | } | ||
1065 | |||
1066 | INIT_LIST_HEAD(&pcdev->capture); | ||
1067 | spin_lock_init(&pcdev->lock); | ||
1068 | |||
1069 | /* | ||
1070 | * Request the regions. | ||
1071 | */ | ||
1072 | if (!request_mem_region(res->start, res->end - res->start + 1, | ||
1073 | PXA_CAM_DRV_NAME)) { | ||
1074 | err = -EBUSY; | ||
1075 | goto exit_clk; | ||
1076 | } | ||
1077 | |||
1078 | base = ioremap(res->start, res->end - res->start + 1); | ||
1079 | if (!base) { | ||
1080 | err = -ENOMEM; | ||
1081 | goto exit_release; | ||
1082 | } | ||
1083 | pcdev->irq = irq; | ||
1084 | pcdev->base = base; | ||
1085 | pcdev->dev = &pdev->dev; | ||
1086 | |||
1087 | /* request dma */ | ||
1088 | pcdev->dma_chans[0] = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, | ||
1089 | pxa_camera_dma_irq_y, pcdev); | ||
1090 | if (pcdev->dma_chans[0] < 0) { | ||
1091 | dev_err(pcdev->dev, "Can't request DMA for Y\n"); | ||
1092 | err = -ENOMEM; | ||
1093 | goto exit_iounmap; | ||
1094 | } | ||
1095 | dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]); | ||
1096 | |||
1097 | pcdev->dma_chans[1] = pxa_request_dma("CI_U", DMA_PRIO_HIGH, | ||
1098 | pxa_camera_dma_irq_u, pcdev); | ||
1099 | if (pcdev->dma_chans[1] < 0) { | ||
1100 | dev_err(pcdev->dev, "Can't request DMA for U\n"); | ||
1101 | err = -ENOMEM; | ||
1102 | goto exit_free_dma_y; | ||
1103 | } | ||
1104 | dev_dbg(pcdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]); | ||
1105 | |||
1106 | pcdev->dma_chans[2] = pxa_request_dma("CI_V", DMA_PRIO_HIGH, | ||
1107 | pxa_camera_dma_irq_v, pcdev); | ||
1108 | if (pcdev->dma_chans[0] < 0) { | ||
1109 | dev_err(pcdev->dev, "Can't request DMA for V\n"); | ||
1110 | err = -ENOMEM; | ||
1111 | goto exit_free_dma_u; | ||
1112 | } | ||
1113 | dev_dbg(pcdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]); | ||
1114 | |||
1115 | DRCMR68 = pcdev->dma_chans[0] | DRCMR_MAPVLD; | ||
1116 | DRCMR69 = pcdev->dma_chans[1] | DRCMR_MAPVLD; | ||
1117 | DRCMR70 = pcdev->dma_chans[2] | DRCMR_MAPVLD; | ||
1118 | |||
1119 | /* request irq */ | ||
1120 | err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME, | ||
1121 | pcdev); | ||
1122 | if (err) { | ||
1123 | dev_err(pcdev->dev, "Camera interrupt register failed \n"); | ||
1124 | goto exit_free_dma; | ||
1125 | } | ||
1126 | |||
1127 | pxa_soc_camera_host.priv = pcdev; | ||
1128 | pxa_soc_camera_host.dev.parent = &pdev->dev; | ||
1129 | pxa_soc_camera_host.nr = pdev->id; | ||
1130 | err = soc_camera_host_register(&pxa_soc_camera_host); | ||
1131 | if (err) | ||
1132 | goto exit_free_irq; | ||
1133 | |||
1134 | return 0; | ||
1135 | |||
1136 | exit_free_irq: | ||
1137 | free_irq(pcdev->irq, pcdev); | ||
1138 | exit_free_dma: | ||
1139 | pxa_free_dma(pcdev->dma_chans[2]); | ||
1140 | exit_free_dma_u: | ||
1141 | pxa_free_dma(pcdev->dma_chans[1]); | ||
1142 | exit_free_dma_y: | ||
1143 | pxa_free_dma(pcdev->dma_chans[0]); | ||
1144 | exit_iounmap: | ||
1145 | iounmap(base); | ||
1146 | exit_release: | ||
1147 | release_mem_region(res->start, res->end - res->start + 1); | ||
1148 | exit_clk: | ||
1149 | clk_put(pcdev->clk); | ||
1150 | exit_kfree: | ||
1151 | kfree(pcdev); | ||
1152 | exit: | ||
1153 | return err; | ||
1154 | } | ||
1155 | |||
1156 | static int __devexit pxa_camera_remove(struct platform_device *pdev) | ||
1157 | { | ||
1158 | struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev); | ||
1159 | struct resource *res; | ||
1160 | |||
1161 | clk_put(pcdev->clk); | ||
1162 | |||
1163 | pxa_free_dma(pcdev->dma_chans[0]); | ||
1164 | pxa_free_dma(pcdev->dma_chans[1]); | ||
1165 | pxa_free_dma(pcdev->dma_chans[2]); | ||
1166 | free_irq(pcdev->irq, pcdev); | ||
1167 | |||
1168 | soc_camera_host_unregister(&pxa_soc_camera_host); | ||
1169 | |||
1170 | iounmap(pcdev->base); | ||
1171 | |||
1172 | res = pcdev->res; | ||
1173 | release_mem_region(res->start, res->end - res->start + 1); | ||
1174 | |||
1175 | kfree(pcdev); | ||
1176 | |||
1177 | dev_info(&pdev->dev, "PXA Camera driver unloaded\n"); | ||
1178 | |||
1179 | return 0; | ||
1180 | } | ||
1181 | |||
1182 | static struct platform_driver pxa_camera_driver = { | ||
1183 | .driver = { | ||
1184 | .name = PXA_CAM_DRV_NAME, | ||
1185 | }, | ||
1186 | .probe = pxa_camera_probe, | ||
1187 | .remove = __exit_p(pxa_camera_remove), | ||
1188 | }; | ||
1189 | |||
1190 | |||
1191 | static int __devinit pxa_camera_init(void) | ||
1192 | { | ||
1193 | return platform_driver_register(&pxa_camera_driver); | ||
1194 | } | ||
1195 | |||
1196 | static void __exit pxa_camera_exit(void) | ||
1197 | { | ||
1198 | return platform_driver_unregister(&pxa_camera_driver); | ||
1199 | } | ||
1200 | |||
1201 | module_init(pxa_camera_init); | ||
1202 | module_exit(pxa_camera_exit); | ||
1203 | |||
1204 | MODULE_DESCRIPTION("PXA27x SoC Camera Host driver"); | ||
1205 | MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); | ||
1206 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index f55d6e85f20f..ec8c65dc8408 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c | |||
@@ -701,7 +701,9 @@ static const struct file_operations saa_fops = { | |||
701 | .open = saa5249_open, | 701 | .open = saa5249_open, |
702 | .release = saa5249_release, | 702 | .release = saa5249_release, |
703 | .ioctl = saa5249_ioctl, | 703 | .ioctl = saa5249_ioctl, |
704 | #ifdef CONFIG_COMPAT | ||
704 | .compat_ioctl = v4l_compat_ioctl32, | 705 | .compat_ioctl = v4l_compat_ioctl32, |
706 | #endif | ||
705 | .llseek = no_llseek, | 707 | .llseek = no_llseek, |
706 | }; | 708 | }; |
707 | 709 | ||
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c index 72e344a12c79..716ee7f64df3 100644 --- a/drivers/media/video/saa6588.c +++ b/drivers/media/video/saa6588.c | |||
@@ -44,10 +44,10 @@ static unsigned short normal_i2c[] = { | |||
44 | I2C_CLIENT_INSMOD; | 44 | I2C_CLIENT_INSMOD; |
45 | 45 | ||
46 | /* insmod options */ | 46 | /* insmod options */ |
47 | static unsigned int debug = 0; | 47 | static unsigned int debug; |
48 | static unsigned int xtal = 0; | 48 | static unsigned int xtal; |
49 | static unsigned int rbds = 0; | 49 | static unsigned int rbds; |
50 | static unsigned int plvl = 0; | 50 | static unsigned int plvl; |
51 | static unsigned int bufblocks = 100; | 51 | static unsigned int bufblocks = 100; |
52 | 52 | ||
53 | module_param(debug, int, 0644); | 53 | module_param(debug, int, 0644); |
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index 1df2602cd184..4aa82b310708 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c | |||
@@ -46,7 +46,7 @@ MODULE_LICENSE("GPL"); | |||
46 | #include <media/v4l2-common.h> | 46 | #include <media/v4l2-common.h> |
47 | #include <linux/video_decoder.h> | 47 | #include <linux/video_decoder.h> |
48 | 48 | ||
49 | static int debug = 0; | 49 | static int debug; |
50 | module_param(debug, int, 0); | 50 | module_param(debug, int, 0); |
51 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 51 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
52 | 52 | ||
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index a0772c53bb1f..96c3d4357722 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c | |||
@@ -55,7 +55,7 @@ MODULE_LICENSE("GPL"); | |||
55 | #define I2C_NAME(s) (s)->name | 55 | #define I2C_NAME(s) (s)->name |
56 | 56 | ||
57 | 57 | ||
58 | static int debug = 0; | 58 | static int debug; |
59 | module_param(debug, int, 0644); | 59 | module_param(debug, int, 0644); |
60 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 60 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
61 | 61 | ||
diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index bf91a4faa706..e79075533beb 100644 --- a/drivers/media/video/saa7114.c +++ b/drivers/media/video/saa7114.c | |||
@@ -56,7 +56,7 @@ MODULE_LICENSE("GPL"); | |||
56 | #define I2C_NAME(x) (x)->name | 56 | #define I2C_NAME(x) (x)->name |
57 | 57 | ||
58 | 58 | ||
59 | static int debug = 0; | 59 | static int debug; |
60 | module_param(debug, int, 0); | 60 | module_param(debug, int, 0); |
61 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 61 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
62 | 62 | ||
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 41e5e518a47e..416d05d4a969 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
@@ -57,7 +57,7 @@ MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, " | |||
57 | "Hans Verkuil, Mauro Carvalho Chehab"); | 57 | "Hans Verkuil, Mauro Carvalho Chehab"); |
58 | MODULE_LICENSE("GPL"); | 58 | MODULE_LICENSE("GPL"); |
59 | 59 | ||
60 | static int debug = 0; | 60 | static int debug; |
61 | module_param(debug, bool, 0644); | 61 | module_param(debug, bool, 0644); |
62 | 62 | ||
63 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 63 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
@@ -957,7 +957,7 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
957 | 957 | ||
958 | if (std == V4L2_STD_PAL_M) { | 958 | if (std == V4L2_STD_PAL_M) { |
959 | reg |= 0x30; | 959 | reg |= 0x30; |
960 | } else if (std == V4L2_STD_PAL_N) { | 960 | } else if (std == V4L2_STD_PAL_Nc) { |
961 | reg |= 0x20; | 961 | reg |= 0x20; |
962 | } else if (std == V4L2_STD_PAL_60) { | 962 | } else if (std == V4L2_STD_PAL_60) { |
963 | reg |= 0x10; | 963 | reg |= 0x10; |
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c index 80bf91187856..cedb988574bd 100644 --- a/drivers/media/video/saa711x.c +++ b/drivers/media/video/saa711x.c | |||
@@ -48,7 +48,7 @@ MODULE_LICENSE("GPL"); | |||
48 | 48 | ||
49 | #include <linux/video_decoder.h> | 49 | #include <linux/video_decoder.h> |
50 | 50 | ||
51 | static int debug = 0; | 51 | static int debug; |
52 | module_param(debug, int, 0644); | 52 | module_param(debug, int, 0644); |
53 | MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)"); | 53 | MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)"); |
54 | 54 | ||
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index 96bc3b1298a2..e086f14d5663 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig | |||
@@ -37,6 +37,7 @@ config VIDEO_SAA7134_DVB | |||
37 | select DVB_TDA826X if !DVB_FE_CUSTOMISE | 37 | select DVB_TDA826X if !DVB_FE_CUSTOMISE |
38 | select DVB_TDA827X if !DVB_FE_CUSTOMISE | 38 | select DVB_TDA827X if !DVB_FE_CUSTOMISE |
39 | select DVB_ISL6421 if !DVB_FE_CUSTOMISE | 39 | select DVB_ISL6421 if !DVB_FE_CUSTOMISE |
40 | select TUNER_SIMPLE if !DVB_FE_CUSTOMISE | ||
40 | ---help--- | 41 | ---help--- |
41 | This adds support for DVB cards based on the | 42 | This adds support for DVB cards based on the |
42 | Philips saa7134 chip. | 43 | Philips saa7134 chip. |
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index ec6bdb9680a3..ba3082422a01 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include "saa7134.h" | 31 | #include "saa7134.h" |
32 | #include "saa7134-reg.h" | 32 | #include "saa7134-reg.h" |
33 | 33 | ||
34 | static unsigned int debug = 0; | 34 | static unsigned int debug; |
35 | module_param(debug, int, 0644); | 35 | module_param(debug, int, 0644); |
36 | MODULE_PARM_DESC(debug,"enable debug messages [alsa]"); | 36 | MODULE_PARM_DESC(debug,"enable debug messages [alsa]"); |
37 | 37 | ||
@@ -503,7 +503,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, | |||
503 | /* release the old buffer */ | 503 | /* release the old buffer */ |
504 | if (substream->runtime->dma_area) { | 504 | if (substream->runtime->dma_area) { |
505 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); | 505 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); |
506 | videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma); | 506 | videobuf_sg_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); |
507 | dsp_buffer_free(dev); | 507 | dsp_buffer_free(dev); |
508 | substream->runtime->dma_area = NULL; | 508 | substream->runtime->dma_area = NULL; |
509 | } | 509 | } |
@@ -519,12 +519,12 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, | |||
519 | return err; | 519 | return err; |
520 | } | 520 | } |
521 | 521 | ||
522 | if (0 != (err = videobuf_pci_dma_map(dev->pci, &dev->dmasound.dma))) { | 522 | if (0 != (err = videobuf_sg_dma_map(&dev->pci->dev, &dev->dmasound.dma))) { |
523 | dsp_buffer_free(dev); | 523 | dsp_buffer_free(dev); |
524 | return err; | 524 | return err; |
525 | } | 525 | } |
526 | if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) { | 526 | if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) { |
527 | videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma); | 527 | videobuf_sg_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); |
528 | dsp_buffer_free(dev); | 528 | dsp_buffer_free(dev); |
529 | return err; | 529 | return err; |
530 | } | 530 | } |
@@ -533,7 +533,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, | |||
533 | dev->dmasound.dma.sglen, | 533 | dev->dmasound.dma.sglen, |
534 | 0))) { | 534 | 0))) { |
535 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); | 535 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); |
536 | videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma); | 536 | videobuf_sg_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); |
537 | dsp_buffer_free(dev); | 537 | dsp_buffer_free(dev); |
538 | return err; | 538 | return err; |
539 | } | 539 | } |
@@ -569,7 +569,7 @@ static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream) | |||
569 | 569 | ||
570 | if (substream->runtime->dma_area) { | 570 | if (substream->runtime->dma_area) { |
571 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); | 571 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); |
572 | videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma); | 572 | videobuf_sg_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); |
573 | dsp_buffer_free(dev); | 573 | dsp_buffer_free(dev); |
574 | substream->runtime->dma_area = NULL; | 574 | substream->runtime->dma_area = NULL; |
575 | } | 575 | } |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 6f5744286e8c..98375955a84b 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -22,11 +22,15 @@ | |||
22 | 22 | ||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/i2c.h> | ||
26 | #include <linux/i2c-algo-bit.h> | ||
25 | 27 | ||
26 | #include "saa7134-reg.h" | 28 | #include "saa7134-reg.h" |
27 | #include "saa7134.h" | 29 | #include "saa7134.h" |
30 | #include "tuner-xc2028.h" | ||
28 | #include <media/v4l2-common.h> | 31 | #include <media/v4l2-common.h> |
29 | #include <media/tveeprom.h> | 32 | #include <media/tveeprom.h> |
33 | #include "tea5767.h" | ||
30 | 34 | ||
31 | /* commly used strings */ | 35 | /* commly used strings */ |
32 | static char name_mute[] = "mute"; | 36 | static char name_mute[] = "mute"; |
@@ -1046,7 +1050,7 @@ struct saa7134_board saa7134_boards[] = { | |||
1046 | }, | 1050 | }, |
1047 | [SAA7134_BOARD_MANLI_MTV002] = { | 1051 | [SAA7134_BOARD_MANLI_MTV002] = { |
1048 | /* Ognjen Nastic <ognjen@logosoft.ba> */ | 1052 | /* Ognjen Nastic <ognjen@logosoft.ba> */ |
1049 | .name = "Manli MuchTV M-TV002/Behold TV 403 FM", | 1053 | .name = "Manli MuchTV M-TV002", |
1050 | .audio_clock = 0x00200000, | 1054 | .audio_clock = 0x00200000, |
1051 | .tuner_type = TUNER_PHILIPS_PAL, | 1055 | .tuner_type = TUNER_PHILIPS_PAL, |
1052 | .radio_type = UNSET, | 1056 | .radio_type = UNSET, |
@@ -1073,7 +1077,7 @@ struct saa7134_board saa7134_boards[] = { | |||
1073 | }, | 1077 | }, |
1074 | [SAA7134_BOARD_MANLI_MTV001] = { | 1078 | [SAA7134_BOARD_MANLI_MTV001] = { |
1075 | /* Ognjen Nastic <ognjen@logosoft.ba> UNTESTED */ | 1079 | /* Ognjen Nastic <ognjen@logosoft.ba> UNTESTED */ |
1076 | .name = "Manli MuchTV M-TV001/Behold TV 401", | 1080 | .name = "Manli MuchTV M-TV001", |
1077 | .audio_clock = 0x00200000, | 1081 | .audio_clock = 0x00200000, |
1078 | .tuner_type = TUNER_PHILIPS_PAL, | 1082 | .tuner_type = TUNER_PHILIPS_PAL, |
1079 | .radio_type = UNSET, | 1083 | .radio_type = UNSET, |
@@ -2195,6 +2199,8 @@ struct saa7134_board saa7134_boards[] = { | |||
2195 | }, | 2199 | }, |
2196 | [SAA7134_BOARD_BEHOLD_409FM] = { | 2200 | [SAA7134_BOARD_BEHOLD_409FM] = { |
2197 | /* <http://tuner.beholder.ru>, Sergey <skiv@orel.ru> */ | 2201 | /* <http://tuner.beholder.ru>, Sergey <skiv@orel.ru> */ |
2202 | /* Beholder Intl. Ltd. 2008 */ | ||
2203 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
2198 | .name = "Beholder BeholdTV 409 FM", | 2204 | .name = "Beholder BeholdTV 409 FM", |
2199 | .audio_clock = 0x00187de7, | 2205 | .audio_clock = 0x00187de7, |
2200 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 2206 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
@@ -2202,6 +2208,7 @@ struct saa7134_board saa7134_boards[] = { | |||
2202 | .tuner_addr = ADDR_UNSET, | 2208 | .tuner_addr = ADDR_UNSET, |
2203 | .radio_addr = ADDR_UNSET, | 2209 | .radio_addr = ADDR_UNSET, |
2204 | .tda9887_conf = TDA9887_PRESENT, | 2210 | .tda9887_conf = TDA9887_PRESENT, |
2211 | .gpiomask = 0x00008000, | ||
2205 | .inputs = {{ | 2212 | .inputs = {{ |
2206 | .name = name_tv, | 2213 | .name = name_tv, |
2207 | .vmux = 3, | 2214 | .vmux = 3, |
@@ -2908,15 +2915,13 @@ struct saa7134_board saa7134_boards[] = { | |||
2908 | }}, | 2915 | }}, |
2909 | }, | 2916 | }, |
2910 | [SAA7134_BOARD_MD7134_BRIDGE_2] = { | 2917 | [SAA7134_BOARD_MD7134_BRIDGE_2] = { |
2911 | /* This card has two saa7134 chips on it, | 2918 | /* The second saa7134 on this card only serves as DVB-S host bridge */ |
2912 | but only one of them is currently working. | ||
2913 | The programming for the primary decoder is | ||
2914 | in SAA7134_BOARD_MD7134 */ | ||
2915 | .name = "Medion 7134 Bridge #2", | 2919 | .name = "Medion 7134 Bridge #2", |
2916 | .audio_clock = 0x00187de7, | 2920 | .audio_clock = 0x00187de7, |
2917 | .radio_type = UNSET, | 2921 | .radio_type = UNSET, |
2918 | .tuner_addr = ADDR_UNSET, | 2922 | .tuner_addr = ADDR_UNSET, |
2919 | .radio_addr = ADDR_UNSET, | 2923 | .radio_addr = ADDR_UNSET, |
2924 | .mpeg = SAA7134_MPEG_DVB, | ||
2920 | }, | 2925 | }, |
2921 | [SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS] = { | 2926 | [SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS] = { |
2922 | .name = "LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB", | 2927 | .name = "LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB", |
@@ -3330,7 +3335,7 @@ struct saa7134_board saa7134_boards[] = { | |||
3330 | /* Juan Pablo Sormani <sorman@gmail.com> */ | 3335 | /* Juan Pablo Sormani <sorman@gmail.com> */ |
3331 | .name = "Encore ENLTV-FM", | 3336 | .name = "Encore ENLTV-FM", |
3332 | .audio_clock = 0x00200000, | 3337 | .audio_clock = 0x00200000, |
3333 | .tuner_type = TUNER_PHILIPS_ATSC, | 3338 | .tuner_type = TUNER_PHILIPS_FCV1236D, |
3334 | .radio_type = UNSET, | 3339 | .radio_type = UNSET, |
3335 | .tuner_addr = ADDR_UNSET, | 3340 | .tuner_addr = ADDR_UNSET, |
3336 | .radio_addr = ADDR_UNSET, | 3341 | .radio_addr = ADDR_UNSET, |
@@ -3575,12 +3580,15 @@ struct saa7134_board saa7134_boards[] = { | |||
3575 | }}, | 3580 | }}, |
3576 | }, | 3581 | }, |
3577 | [SAA7134_BOARD_BEHOLD_401] = { | 3582 | [SAA7134_BOARD_BEHOLD_401] = { |
3583 | /* Beholder Intl. Ltd. 2008 */ | ||
3584 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
3578 | .name = "Beholder BeholdTV 401", | 3585 | .name = "Beholder BeholdTV 401", |
3579 | .audio_clock = 0x00187de7, | 3586 | .audio_clock = 0x00187de7, |
3580 | .tuner_type = TUNER_PHILIPS_FQ1216ME, | 3587 | .tuner_type = TUNER_PHILIPS_FQ1216ME, |
3581 | .radio_type = UNSET, | 3588 | .radio_type = UNSET, |
3582 | .tuner_addr = ADDR_UNSET, | 3589 | .tuner_addr = ADDR_UNSET, |
3583 | .radio_addr = ADDR_UNSET, | 3590 | .radio_addr = ADDR_UNSET, |
3591 | .gpiomask = 0x00008000, | ||
3584 | .inputs = {{ | 3592 | .inputs = {{ |
3585 | .name = name_svideo, | 3593 | .name = name_svideo, |
3586 | .vmux = 8, | 3594 | .vmux = 8, |
@@ -3601,12 +3609,15 @@ struct saa7134_board saa7134_boards[] = { | |||
3601 | }, | 3609 | }, |
3602 | }, | 3610 | }, |
3603 | [SAA7134_BOARD_BEHOLD_403] = { | 3611 | [SAA7134_BOARD_BEHOLD_403] = { |
3612 | /* Beholder Intl. Ltd. 2008 */ | ||
3613 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
3604 | .name = "Beholder BeholdTV 403", | 3614 | .name = "Beholder BeholdTV 403", |
3605 | .audio_clock = 0x00187de7, | 3615 | .audio_clock = 0x00187de7, |
3606 | .tuner_type = TUNER_PHILIPS_FQ1216ME, | 3616 | .tuner_type = TUNER_PHILIPS_FQ1216ME, |
3607 | .radio_type = UNSET, | 3617 | .radio_type = UNSET, |
3608 | .tuner_addr = ADDR_UNSET, | 3618 | .tuner_addr = ADDR_UNSET, |
3609 | .radio_addr = ADDR_UNSET, | 3619 | .radio_addr = ADDR_UNSET, |
3620 | .gpiomask = 0x00008000, | ||
3610 | .inputs = {{ | 3621 | .inputs = {{ |
3611 | .name = name_svideo, | 3622 | .name = name_svideo, |
3612 | .vmux = 8, | 3623 | .vmux = 8, |
@@ -3623,12 +3634,15 @@ struct saa7134_board saa7134_boards[] = { | |||
3623 | }}, | 3634 | }}, |
3624 | }, | 3635 | }, |
3625 | [SAA7134_BOARD_BEHOLD_403FM] = { | 3636 | [SAA7134_BOARD_BEHOLD_403FM] = { |
3637 | /* Beholder Intl. Ltd. 2008 */ | ||
3638 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
3626 | .name = "Beholder BeholdTV 403 FM", | 3639 | .name = "Beholder BeholdTV 403 FM", |
3627 | .audio_clock = 0x00187de7, | 3640 | .audio_clock = 0x00187de7, |
3628 | .tuner_type = TUNER_PHILIPS_FQ1216ME, | 3641 | .tuner_type = TUNER_PHILIPS_FQ1216ME, |
3629 | .radio_type = UNSET, | 3642 | .radio_type = UNSET, |
3630 | .tuner_addr = ADDR_UNSET, | 3643 | .tuner_addr = ADDR_UNSET, |
3631 | .radio_addr = ADDR_UNSET, | 3644 | .radio_addr = ADDR_UNSET, |
3645 | .gpiomask = 0x00008000, | ||
3632 | .inputs = {{ | 3646 | .inputs = {{ |
3633 | .name = name_svideo, | 3647 | .name = name_svideo, |
3634 | .vmux = 8, | 3648 | .vmux = 8, |
@@ -3649,6 +3663,8 @@ struct saa7134_board saa7134_boards[] = { | |||
3649 | }, | 3663 | }, |
3650 | }, | 3664 | }, |
3651 | [SAA7134_BOARD_BEHOLD_405] = { | 3665 | [SAA7134_BOARD_BEHOLD_405] = { |
3666 | /* Beholder Intl. Ltd. 2008 */ | ||
3667 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
3652 | .name = "Beholder BeholdTV 405", | 3668 | .name = "Beholder BeholdTV 405", |
3653 | .audio_clock = 0x00187de7, | 3669 | .audio_clock = 0x00187de7, |
3654 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 3670 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
@@ -3656,6 +3672,7 @@ struct saa7134_board saa7134_boards[] = { | |||
3656 | .tuner_addr = ADDR_UNSET, | 3672 | .tuner_addr = ADDR_UNSET, |
3657 | .radio_addr = ADDR_UNSET, | 3673 | .radio_addr = ADDR_UNSET, |
3658 | .tda9887_conf = TDA9887_PRESENT, | 3674 | .tda9887_conf = TDA9887_PRESENT, |
3675 | .gpiomask = 0x00008000, | ||
3659 | .inputs = {{ | 3676 | .inputs = {{ |
3660 | .name = name_svideo, | 3677 | .name = name_svideo, |
3661 | .vmux = 8, | 3678 | .vmux = 8, |
@@ -3673,6 +3690,8 @@ struct saa7134_board saa7134_boards[] = { | |||
3673 | }, | 3690 | }, |
3674 | [SAA7134_BOARD_BEHOLD_405FM] = { | 3691 | [SAA7134_BOARD_BEHOLD_405FM] = { |
3675 | /* Sergey <skiv@orel.ru> */ | 3692 | /* Sergey <skiv@orel.ru> */ |
3693 | /* Beholder Intl. Ltd. 2008 */ | ||
3694 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
3676 | .name = "Beholder BeholdTV 405 FM", | 3695 | .name = "Beholder BeholdTV 405 FM", |
3677 | .audio_clock = 0x00187de7, | 3696 | .audio_clock = 0x00187de7, |
3678 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 3697 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
@@ -3680,6 +3699,7 @@ struct saa7134_board saa7134_boards[] = { | |||
3680 | .tuner_addr = ADDR_UNSET, | 3699 | .tuner_addr = ADDR_UNSET, |
3681 | .radio_addr = ADDR_UNSET, | 3700 | .radio_addr = ADDR_UNSET, |
3682 | .tda9887_conf = TDA9887_PRESENT, | 3701 | .tda9887_conf = TDA9887_PRESENT, |
3702 | .gpiomask = 0x00008000, | ||
3683 | .inputs = {{ | 3703 | .inputs = {{ |
3684 | .name = name_svideo, | 3704 | .name = name_svideo, |
3685 | .vmux = 8, | 3705 | .vmux = 8, |
@@ -3700,6 +3720,8 @@ struct saa7134_board saa7134_boards[] = { | |||
3700 | }, | 3720 | }, |
3701 | }, | 3721 | }, |
3702 | [SAA7134_BOARD_BEHOLD_407] = { | 3722 | [SAA7134_BOARD_BEHOLD_407] = { |
3723 | /* Beholder Intl. Ltd. 2008 */ | ||
3724 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
3703 | .name = "Beholder BeholdTV 407", | 3725 | .name = "Beholder BeholdTV 407", |
3704 | .audio_clock = 0x00187de7, | 3726 | .audio_clock = 0x00187de7, |
3705 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 3727 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
@@ -3707,7 +3729,7 @@ struct saa7134_board saa7134_boards[] = { | |||
3707 | .tuner_addr = ADDR_UNSET, | 3729 | .tuner_addr = ADDR_UNSET, |
3708 | .radio_addr = ADDR_UNSET, | 3730 | .radio_addr = ADDR_UNSET, |
3709 | .tda9887_conf = TDA9887_PRESENT, | 3731 | .tda9887_conf = TDA9887_PRESENT, |
3710 | .gpiomask = 0xc0c000, | 3732 | .gpiomask = 0x00008000, |
3711 | .inputs = {{ | 3733 | .inputs = {{ |
3712 | .name = name_svideo, | 3734 | .name = name_svideo, |
3713 | .vmux = 8, | 3735 | .vmux = 8, |
@@ -3727,6 +3749,8 @@ struct saa7134_board saa7134_boards[] = { | |||
3727 | }}, | 3749 | }}, |
3728 | }, | 3750 | }, |
3729 | [SAA7134_BOARD_BEHOLD_407FM] = { | 3751 | [SAA7134_BOARD_BEHOLD_407FM] = { |
3752 | /* Beholder Intl. Ltd. 2008 */ | ||
3753 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
3730 | .name = "Beholder BeholdTV 407 FM", | 3754 | .name = "Beholder BeholdTV 407 FM", |
3731 | .audio_clock = 0x00187de7, | 3755 | .audio_clock = 0x00187de7, |
3732 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 3756 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
@@ -3734,7 +3758,7 @@ struct saa7134_board saa7134_boards[] = { | |||
3734 | .tuner_addr = ADDR_UNSET, | 3758 | .tuner_addr = ADDR_UNSET, |
3735 | .radio_addr = ADDR_UNSET, | 3759 | .radio_addr = ADDR_UNSET, |
3736 | .tda9887_conf = TDA9887_PRESENT, | 3760 | .tda9887_conf = TDA9887_PRESENT, |
3737 | .gpiomask = 0xc0c000, | 3761 | .gpiomask = 0x00008000, |
3738 | .inputs = {{ | 3762 | .inputs = {{ |
3739 | .name = name_svideo, | 3763 | .name = name_svideo, |
3740 | .vmux = 8, | 3764 | .vmux = 8, |
@@ -3759,6 +3783,8 @@ struct saa7134_board saa7134_boards[] = { | |||
3759 | }, | 3783 | }, |
3760 | }, | 3784 | }, |
3761 | [SAA7134_BOARD_BEHOLD_409] = { | 3785 | [SAA7134_BOARD_BEHOLD_409] = { |
3786 | /* Beholder Intl. Ltd. 2008 */ | ||
3787 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
3762 | .name = "Beholder BeholdTV 409", | 3788 | .name = "Beholder BeholdTV 409", |
3763 | .audio_clock = 0x00187de7, | 3789 | .audio_clock = 0x00187de7, |
3764 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 3790 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
@@ -3766,6 +3792,7 @@ struct saa7134_board saa7134_boards[] = { | |||
3766 | .tuner_addr = ADDR_UNSET, | 3792 | .tuner_addr = ADDR_UNSET, |
3767 | .radio_addr = ADDR_UNSET, | 3793 | .radio_addr = ADDR_UNSET, |
3768 | .tda9887_conf = TDA9887_PRESENT, | 3794 | .tda9887_conf = TDA9887_PRESENT, |
3795 | .gpiomask = 0x00008000, | ||
3769 | .inputs = {{ | 3796 | .inputs = {{ |
3770 | .name = name_tv, | 3797 | .name = name_tv, |
3771 | .vmux = 3, | 3798 | .vmux = 3, |
@@ -3782,6 +3809,8 @@ struct saa7134_board saa7134_boards[] = { | |||
3782 | }}, | 3809 | }}, |
3783 | }, | 3810 | }, |
3784 | [SAA7134_BOARD_BEHOLD_505FM] = { | 3811 | [SAA7134_BOARD_BEHOLD_505FM] = { |
3812 | /* Beholder Intl. Ltd. 2008 */ | ||
3813 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
3785 | .name = "Beholder BeholdTV 505 FM/RDS", | 3814 | .name = "Beholder BeholdTV 505 FM/RDS", |
3786 | .audio_clock = 0x00200000, | 3815 | .audio_clock = 0x00200000, |
3787 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 3816 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
@@ -3789,6 +3818,7 @@ struct saa7134_board saa7134_boards[] = { | |||
3789 | .tuner_addr = ADDR_UNSET, | 3818 | .tuner_addr = ADDR_UNSET, |
3790 | .radio_addr = ADDR_UNSET, | 3819 | .radio_addr = ADDR_UNSET, |
3791 | .tda9887_conf = TDA9887_PRESENT, | 3820 | .tda9887_conf = TDA9887_PRESENT, |
3821 | .gpiomask = 0x00008000, | ||
3792 | .inputs = {{ | 3822 | .inputs = {{ |
3793 | .name = name_tv, | 3823 | .name = name_tv, |
3794 | .vmux = 3, | 3824 | .vmux = 3, |
@@ -3813,6 +3843,8 @@ struct saa7134_board saa7134_boards[] = { | |||
3813 | }, | 3843 | }, |
3814 | }, | 3844 | }, |
3815 | [SAA7134_BOARD_BEHOLD_507_9FM] = { | 3845 | [SAA7134_BOARD_BEHOLD_507_9FM] = { |
3846 | /* Beholder Intl. Ltd. 2008 */ | ||
3847 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
3816 | .name = "Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM", | 3848 | .name = "Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM", |
3817 | .audio_clock = 0x00187de7, | 3849 | .audio_clock = 0x00187de7, |
3818 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 3850 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
@@ -3820,6 +3852,7 @@ struct saa7134_board saa7134_boards[] = { | |||
3820 | .tuner_addr = ADDR_UNSET, | 3852 | .tuner_addr = ADDR_UNSET, |
3821 | .radio_addr = ADDR_UNSET, | 3853 | .radio_addr = ADDR_UNSET, |
3822 | .tda9887_conf = TDA9887_PRESENT, | 3854 | .tda9887_conf = TDA9887_PRESENT, |
3855 | .gpiomask = 0x00008000, | ||
3823 | .inputs = {{ | 3856 | .inputs = {{ |
3824 | .name = name_tv, | 3857 | .name = name_tv, |
3825 | .vmux = 3, | 3858 | .vmux = 3, |
@@ -3840,6 +3873,8 @@ struct saa7134_board saa7134_boards[] = { | |||
3840 | }, | 3873 | }, |
3841 | }, | 3874 | }, |
3842 | [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { | 3875 | [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { |
3876 | /* Beholder Intl. Ltd. 2008 */ | ||
3877 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
3843 | .name = "Beholder BeholdTV Columbus TVFM", | 3878 | .name = "Beholder BeholdTV Columbus TVFM", |
3844 | .audio_clock = 0x00187de7, | 3879 | .audio_clock = 0x00187de7, |
3845 | .tuner_type = TUNER_ALPS_TSBE5_PAL, | 3880 | .tuner_type = TUNER_ALPS_TSBE5_PAL, |
@@ -3847,23 +3882,28 @@ struct saa7134_board saa7134_boards[] = { | |||
3847 | .tuner_addr = ADDR_UNSET, | 3882 | .tuner_addr = ADDR_UNSET, |
3848 | .radio_addr = ADDR_UNSET, | 3883 | .radio_addr = ADDR_UNSET, |
3849 | .tda9887_conf = TDA9887_PRESENT, | 3884 | .tda9887_conf = TDA9887_PRESENT, |
3885 | .gpiomask = 0x000A8004, | ||
3850 | .inputs = {{ | 3886 | .inputs = {{ |
3851 | .name = name_tv, | 3887 | .name = name_tv, |
3852 | .vmux = 3, | 3888 | .vmux = 3, |
3853 | .amux = TV, | 3889 | .amux = TV, |
3854 | .tv = 1, | 3890 | .tv = 1, |
3855 | },{ | 3891 | .gpio = 0x000A8004, |
3892 | }, { | ||
3856 | .name = name_comp1, | 3893 | .name = name_comp1, |
3857 | .vmux = 1, | 3894 | .vmux = 1, |
3858 | .amux = LINE1, | 3895 | .amux = LINE1, |
3859 | },{ | 3896 | .gpio = 0x000A8000, |
3897 | }, { | ||
3860 | .name = name_svideo, | 3898 | .name = name_svideo, |
3861 | .vmux = 8, | 3899 | .vmux = 8, |
3862 | .amux = LINE1, | 3900 | .amux = LINE1, |
3863 | }}, | 3901 | .gpio = 0x000A8000, |
3902 | } }, | ||
3864 | .radio = { | 3903 | .radio = { |
3865 | .name = name_radio, | 3904 | .name = name_radio, |
3866 | .amux = LINE2, | 3905 | .amux = LINE2, |
3906 | .gpio = 0x000A8000, | ||
3867 | }, | 3907 | }, |
3868 | }, | 3908 | }, |
3869 | [SAA7134_BOARD_BEHOLD_607_9FM] = { | 3909 | [SAA7134_BOARD_BEHOLD_607_9FM] = { |
@@ -3992,6 +4032,221 @@ struct saa7134_board saa7134_boards[] = { | |||
3992 | .gpio = 0x6000, | 4032 | .gpio = 0x6000, |
3993 | }, | 4033 | }, |
3994 | }, | 4034 | }, |
4035 | [SAA7134_BOARD_PHILIPS_SNAKE] = { | ||
4036 | .name = "NXP Snake DVB-S reference design", | ||
4037 | .audio_clock = 0x00200000, | ||
4038 | .tuner_type = TUNER_ABSENT, | ||
4039 | .radio_type = UNSET, | ||
4040 | .tuner_addr = ADDR_UNSET, | ||
4041 | .radio_addr = ADDR_UNSET, | ||
4042 | .mpeg = SAA7134_MPEG_DVB, | ||
4043 | .inputs = {{ | ||
4044 | .name = name_comp1, | ||
4045 | .vmux = 3, | ||
4046 | .amux = LINE1, | ||
4047 | }, { | ||
4048 | .name = name_svideo, | ||
4049 | .vmux = 8, | ||
4050 | .amux = LINE1, | ||
4051 | } }, | ||
4052 | }, | ||
4053 | [SAA7134_BOARD_CREATIX_CTX953] = { | ||
4054 | .name = "Medion/Creatix CTX953 Hybrid", | ||
4055 | .audio_clock = 0x00187de7, | ||
4056 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
4057 | .radio_type = UNSET, | ||
4058 | .tuner_addr = ADDR_UNSET, | ||
4059 | .radio_addr = ADDR_UNSET, | ||
4060 | .tuner_config = 0, | ||
4061 | .mpeg = SAA7134_MPEG_DVB, | ||
4062 | .inputs = {{ | ||
4063 | .name = name_tv, | ||
4064 | .vmux = 1, | ||
4065 | .amux = TV, | ||
4066 | .tv = 1, | ||
4067 | }, { | ||
4068 | .name = name_comp1, | ||
4069 | .vmux = 0, | ||
4070 | .amux = LINE1, | ||
4071 | }, { | ||
4072 | .name = name_svideo, | ||
4073 | .vmux = 8, | ||
4074 | .amux = LINE1, | ||
4075 | } }, | ||
4076 | }, | ||
4077 | [SAA7134_BOARD_MSI_TVANYWHERE_AD11] = { | ||
4078 | .name = "MSI TV@nywhere A/D v1.1", | ||
4079 | .audio_clock = 0x00187de7, | ||
4080 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
4081 | .radio_type = UNSET, | ||
4082 | .tuner_addr = ADDR_UNSET, | ||
4083 | .radio_addr = ADDR_UNSET, | ||
4084 | .tuner_config = 2, | ||
4085 | .mpeg = SAA7134_MPEG_DVB, | ||
4086 | .gpiomask = 0x0200000, | ||
4087 | .inputs = { { | ||
4088 | .name = name_tv, | ||
4089 | .vmux = 1, | ||
4090 | .amux = TV, | ||
4091 | .tv = 1, | ||
4092 | }, { | ||
4093 | .name = name_comp1, | ||
4094 | .vmux = 3, | ||
4095 | .amux = LINE1, | ||
4096 | }, { | ||
4097 | .name = name_svideo, | ||
4098 | .vmux = 8, | ||
4099 | .amux = LINE1, | ||
4100 | } }, | ||
4101 | .radio = { | ||
4102 | .name = name_radio, | ||
4103 | .amux = TV, | ||
4104 | .gpio = 0x0200000, | ||
4105 | }, | ||
4106 | }, | ||
4107 | [SAA7134_BOARD_AVERMEDIA_CARDBUS_506] = { | ||
4108 | .name = "AVerMedia Cardbus TV/Radio (E506R)", | ||
4109 | .audio_clock = 0x187de7, | ||
4110 | .tuner_type = TUNER_XC2028, | ||
4111 | .radio_type = UNSET, | ||
4112 | .tuner_addr = ADDR_UNSET, | ||
4113 | .radio_addr = ADDR_UNSET, | ||
4114 | /* | ||
4115 | TODO: | ||
4116 | .mpeg = SAA7134_MPEG_DVB, | ||
4117 | */ | ||
4118 | |||
4119 | .inputs = {{ | ||
4120 | .name = name_tv, | ||
4121 | .vmux = 1, | ||
4122 | .amux = TV, | ||
4123 | .tv = 1, | ||
4124 | }, { | ||
4125 | .name = name_comp1, | ||
4126 | .vmux = 3, | ||
4127 | .amux = LINE2, | ||
4128 | }, { | ||
4129 | .name = name_svideo, | ||
4130 | .vmux = 8, | ||
4131 | .amux = LINE1, | ||
4132 | } }, | ||
4133 | .radio = { | ||
4134 | .name = name_radio, | ||
4135 | .amux = TV, | ||
4136 | }, | ||
4137 | }, | ||
4138 | [SAA7134_BOARD_AVERMEDIA_A16D] = { | ||
4139 | .name = "AVerMedia Hybrid TV/Radio (A16D)", | ||
4140 | .audio_clock = 0x187de7, | ||
4141 | .tuner_type = TUNER_XC2028, | ||
4142 | .radio_type = UNSET, | ||
4143 | .tuner_addr = ADDR_UNSET, | ||
4144 | .radio_addr = ADDR_UNSET, | ||
4145 | .inputs = {{ | ||
4146 | .name = name_tv, | ||
4147 | .vmux = 1, | ||
4148 | .amux = TV, | ||
4149 | .tv = 1, | ||
4150 | }, { | ||
4151 | .name = name_svideo, | ||
4152 | .vmux = 8, | ||
4153 | .amux = LINE1, | ||
4154 | } }, | ||
4155 | .radio = { | ||
4156 | .name = name_radio, | ||
4157 | .amux = LINE1, | ||
4158 | }, | ||
4159 | }, | ||
4160 | [SAA7134_BOARD_AVERMEDIA_M115] = { | ||
4161 | .name = "Avermedia M115", | ||
4162 | .audio_clock = 0x187de7, | ||
4163 | .tuner_type = TUNER_XC2028, | ||
4164 | .radio_type = UNSET, | ||
4165 | .tuner_addr = ADDR_UNSET, | ||
4166 | .radio_addr = ADDR_UNSET, | ||
4167 | .inputs = {{ | ||
4168 | .name = name_tv, | ||
4169 | .vmux = 1, | ||
4170 | .amux = TV, | ||
4171 | .tv = 1, | ||
4172 | }, { | ||
4173 | .name = name_comp1, | ||
4174 | .vmux = 3, | ||
4175 | .amux = LINE1, | ||
4176 | }, { | ||
4177 | .name = name_svideo, | ||
4178 | .vmux = 8, | ||
4179 | .amux = LINE2, | ||
4180 | } }, | ||
4181 | }, | ||
4182 | [SAA7134_BOARD_VIDEOMATE_T750] = { | ||
4183 | /* John Newbigin <jn@it.swin.edu.au> */ | ||
4184 | .name = "Compro VideoMate T750", | ||
4185 | .audio_clock = 0x00187de7, | ||
4186 | .tuner_type = TUNER_XC2028, | ||
4187 | .radio_type = UNSET, | ||
4188 | .tuner_addr = ADDR_UNSET, | ||
4189 | .radio_addr = ADDR_UNSET, | ||
4190 | .mpeg = SAA7134_MPEG_DVB, | ||
4191 | .inputs = {{ | ||
4192 | .name = name_tv, | ||
4193 | .vmux = 3, | ||
4194 | .amux = TV, | ||
4195 | .tv = 1, | ||
4196 | }, { | ||
4197 | .name = name_comp1, | ||
4198 | .vmux = 1, | ||
4199 | .amux = LINE2, | ||
4200 | }, { | ||
4201 | .name = name_svideo, | ||
4202 | .vmux = 8, | ||
4203 | .amux = LINE2, | ||
4204 | } }, | ||
4205 | .radio = { | ||
4206 | .name = name_radio, | ||
4207 | .amux = TV, | ||
4208 | } | ||
4209 | }, | ||
4210 | [SAA7134_BOARD_AVERMEDIA_A700_PRO] = { | ||
4211 | /* Matthias Schwarzott <zzam@gentoo.org> */ | ||
4212 | .name = "Avermedia DVB-S Pro A700", | ||
4213 | .audio_clock = 0x00187de7, | ||
4214 | .tuner_type = TUNER_ABSENT, | ||
4215 | .radio_type = UNSET, | ||
4216 | .tuner_addr = ADDR_UNSET, | ||
4217 | .radio_addr = ADDR_UNSET, | ||
4218 | /* no DVB support for now */ | ||
4219 | /* .mpeg = SAA7134_MPEG_DVB, */ | ||
4220 | .inputs = { { | ||
4221 | .name = name_comp, | ||
4222 | .vmux = 1, | ||
4223 | .amux = LINE1, | ||
4224 | }, { | ||
4225 | .name = name_svideo, | ||
4226 | .vmux = 6, | ||
4227 | .amux = LINE1, | ||
4228 | } }, | ||
4229 | }, | ||
4230 | [SAA7134_BOARD_AVERMEDIA_A700_HYBRID] = { | ||
4231 | /* Matthias Schwarzott <zzam@gentoo.org> */ | ||
4232 | .name = "Avermedia DVB-S Hybrid+FM A700", | ||
4233 | .audio_clock = 0x00187de7, | ||
4234 | .tuner_type = TUNER_ABSENT, /* TUNER_XC2028 */ | ||
4235 | .radio_type = UNSET, | ||
4236 | .tuner_addr = ADDR_UNSET, | ||
4237 | .radio_addr = ADDR_UNSET, | ||
4238 | /* no DVB support for now */ | ||
4239 | /* .mpeg = SAA7134_MPEG_DVB, */ | ||
4240 | .inputs = { { | ||
4241 | .name = name_comp, | ||
4242 | .vmux = 1, | ||
4243 | .amux = LINE1, | ||
4244 | }, { | ||
4245 | .name = name_svideo, | ||
4246 | .vmux = 6, | ||
4247 | .amux = LINE1, | ||
4248 | } }, | ||
4249 | }, | ||
3995 | }; | 4250 | }; |
3996 | 4251 | ||
3997 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); | 4252 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); |
@@ -4224,6 +4479,18 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
4224 | .driver_data = SAA7134_BOARD_MD2819, | 4479 | .driver_data = SAA7134_BOARD_MD2819, |
4225 | },{ | 4480 | },{ |
4226 | .vendor = PCI_VENDOR_ID_PHILIPS, | 4481 | .vendor = PCI_VENDOR_ID_PHILIPS, |
4482 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
4483 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
4484 | .subdevice = 0xa7a1, | ||
4485 | .driver_data = SAA7134_BOARD_AVERMEDIA_A700_PRO, | ||
4486 | }, { | ||
4487 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
4488 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
4489 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
4490 | .subdevice = 0xa7a2, | ||
4491 | .driver_data = SAA7134_BOARD_AVERMEDIA_A700_HYBRID, | ||
4492 | }, { | ||
4493 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
4227 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | 4494 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, |
4228 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | 4495 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ |
4229 | .subdevice = 0x2115, | 4496 | .subdevice = 0x2115, |
@@ -4942,7 +5209,43 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
4942 | .subvendor = 0x1822, /*Twinhan Technology Co. Ltd*/ | 5209 | .subvendor = 0x1822, /*Twinhan Technology Co. Ltd*/ |
4943 | .subdevice = 0x0022, | 5210 | .subdevice = 0x0022, |
4944 | .driver_data = SAA7134_BOARD_TWINHAN_DTV_DVB_3056, | 5211 | .driver_data = SAA7134_BOARD_TWINHAN_DTV_DVB_3056, |
5212 | }, { | ||
5213 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5214 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
5215 | .subvendor = 0x16be, | ||
5216 | .subdevice = 0x0010, /* Medion version CTX953_V.1.4.3 */ | ||
5217 | .driver_data = SAA7134_BOARD_CREATIX_CTX953, | ||
5218 | }, { | ||
5219 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5220 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
5221 | .subvendor = 0x1462, /* MSI */ | ||
5222 | .subdevice = 0x8625, /* TV@nywhere A/D v1.1 */ | ||
5223 | .driver_data = SAA7134_BOARD_MSI_TVANYWHERE_AD11, | ||
4945 | },{ | 5224 | },{ |
5225 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5226 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
5227 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
5228 | .subdevice = 0xf436, | ||
5229 | .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS_506, | ||
5230 | }, { | ||
5231 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5232 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
5233 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
5234 | .subdevice = 0xf936, | ||
5235 | .driver_data = SAA7134_BOARD_AVERMEDIA_A16D, | ||
5236 | }, { | ||
5237 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5238 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
5239 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
5240 | .subdevice = 0xa836, | ||
5241 | .driver_data = SAA7134_BOARD_AVERMEDIA_M115, | ||
5242 | }, { | ||
5243 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5244 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
5245 | .subvendor = 0x185b, | ||
5246 | .subdevice = 0xc900, | ||
5247 | .driver_data = SAA7134_BOARD_VIDEOMATE_T750, | ||
5248 | }, { | ||
4946 | /* --- boards without eeprom + subsystem ID --- */ | 5249 | /* --- boards without eeprom + subsystem ID --- */ |
4947 | .vendor = PCI_VENDOR_ID_PHILIPS, | 5250 | .vendor = PCI_VENDOR_ID_PHILIPS, |
4948 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 5251 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
@@ -4998,6 +5301,77 @@ static void board_flyvideo(struct saa7134_dev *dev) | |||
4998 | dev->name, dev->name, dev->name); | 5301 | dev->name, dev->name, dev->name); |
4999 | } | 5302 | } |
5000 | 5303 | ||
5304 | static int saa7134_xc2028_callback(struct saa7134_dev *dev, | ||
5305 | int command, int arg) | ||
5306 | { | ||
5307 | switch (command) { | ||
5308 | case XC2028_TUNER_RESET: | ||
5309 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000); | ||
5310 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000); | ||
5311 | mdelay(250); | ||
5312 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0); | ||
5313 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0); | ||
5314 | mdelay(250); | ||
5315 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000); | ||
5316 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000); | ||
5317 | mdelay(250); | ||
5318 | saa_andorl(SAA7133_ANALOG_IO_SELECT >> 2, 0x02, 0x02); | ||
5319 | saa_andorl(SAA7134_ANALOG_IN_CTRL1 >> 2, 0x81, 0x81); | ||
5320 | saa_andorl(SAA7134_AUDIO_CLOCK0 >> 2, 0x03187de7, 0x03187de7); | ||
5321 | saa_andorl(SAA7134_AUDIO_PLL_CTRL >> 2, 0x03, 0x03); | ||
5322 | saa_andorl(SAA7134_AUDIO_CLOCKS_PER_FIELD0 >> 2, | ||
5323 | 0x0001e000, 0x0001e000); | ||
5324 | return 0; | ||
5325 | } | ||
5326 | return -EINVAL; | ||
5327 | } | ||
5328 | |||
5329 | |||
5330 | static int saa7134_tda8290_callback(struct saa7134_dev *dev, | ||
5331 | int command, int arg) | ||
5332 | { | ||
5333 | u8 sync_control; | ||
5334 | |||
5335 | switch (command) { | ||
5336 | case 0: /* switch LNA gain through GPIO 22*/ | ||
5337 | saa7134_set_gpio(dev, 22, arg) ; | ||
5338 | break; | ||
5339 | case 1: /* vsync output at GPIO22. 50 / 60Hz */ | ||
5340 | saa_andorb(SAA7134_VIDEO_PORT_CTRL3, 0x80, 0x80); | ||
5341 | saa_andorb(SAA7134_VIDEO_PORT_CTRL6, 0x0f, 0x03); | ||
5342 | if (arg == 1) | ||
5343 | sync_control = 11; | ||
5344 | else | ||
5345 | sync_control = 17; | ||
5346 | saa_writeb(SAA7134_VGATE_START, sync_control); | ||
5347 | saa_writeb(SAA7134_VGATE_STOP, sync_control + 1); | ||
5348 | saa_andorb(SAA7134_MISC_VGATE_MSB, 0x03, 0x00); | ||
5349 | break; | ||
5350 | default: | ||
5351 | return -EINVAL; | ||
5352 | } | ||
5353 | |||
5354 | return 0; | ||
5355 | } | ||
5356 | |||
5357 | int saa7134_tuner_callback(void *priv, int command, int arg) | ||
5358 | { | ||
5359 | struct saa7134_dev *dev = priv; | ||
5360 | if (dev != NULL) { | ||
5361 | switch (dev->tuner_type) { | ||
5362 | case TUNER_PHILIPS_TDA8290: | ||
5363 | return saa7134_tda8290_callback(dev, command, arg); | ||
5364 | case TUNER_XC2028: | ||
5365 | return saa7134_xc2028_callback(dev, command, arg); | ||
5366 | } | ||
5367 | } else { | ||
5368 | printk(KERN_ERR "saa7134: Error - device struct undefined.\n"); | ||
5369 | return -EINVAL; | ||
5370 | } | ||
5371 | return -EINVAL; | ||
5372 | } | ||
5373 | EXPORT_SYMBOL(saa7134_tuner_callback); | ||
5374 | |||
5001 | /* ----------------------------------------------------------- */ | 5375 | /* ----------------------------------------------------------- */ |
5002 | 5376 | ||
5003 | static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data) | 5377 | static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data) |
@@ -5067,6 +5441,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
5067 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | 5441 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: |
5068 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: | 5442 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: |
5069 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: | 5443 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: |
5444 | case SAA7134_BOARD_VIDEOMATE_T750: | ||
5070 | case SAA7134_BOARD_MANLI_MTV001: | 5445 | case SAA7134_BOARD_MANLI_MTV001: |
5071 | case SAA7134_BOARD_MANLI_MTV002: | 5446 | case SAA7134_BOARD_MANLI_MTV002: |
5072 | case SAA7134_BOARD_BEHOLD_409FM: | 5447 | case SAA7134_BOARD_BEHOLD_409FM: |
@@ -5133,11 +5508,29 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
5133 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000); | 5508 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000); |
5134 | break; | 5509 | break; |
5135 | case SAA7134_BOARD_AVERMEDIA_CARDBUS: | 5510 | case SAA7134_BOARD_AVERMEDIA_CARDBUS: |
5136 | case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: | 5511 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: |
5512 | case SAA7134_BOARD_AVERMEDIA_M115: | ||
5513 | case SAA7134_BOARD_AVERMEDIA_A16D: | ||
5514 | /* power-down tuner chip */ | ||
5515 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0); | ||
5516 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0); | ||
5517 | msleep(10); | ||
5137 | /* power-up tuner chip */ | 5518 | /* power-up tuner chip */ |
5138 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff); | 5519 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff); |
5139 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); | 5520 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); |
5140 | msleep(1); | 5521 | msleep(10); |
5522 | break; | ||
5523 | case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: | ||
5524 | /* power-down tuner chip */ | ||
5525 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x000A8004, 0x000A8004); | ||
5526 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x000A8004, 0); | ||
5527 | msleep(10); | ||
5528 | /* power-up tuner chip */ | ||
5529 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x000A8004, 0x000A8004); | ||
5530 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x000A8004, 0x000A8004); | ||
5531 | msleep(10); | ||
5532 | /* remote via GPIO */ | ||
5533 | dev->has_remote = SAA7134_REMOTE_GPIO; | ||
5141 | break; | 5534 | break; |
5142 | case SAA7134_BOARD_RTD_VFG7350: | 5535 | case SAA7134_BOARD_RTD_VFG7350: |
5143 | 5536 | ||
@@ -5160,7 +5553,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
5160 | dev->has_remote = SAA7134_REMOTE_I2C; | 5553 | dev->has_remote = SAA7134_REMOTE_I2C; |
5161 | break; | 5554 | break; |
5162 | case SAA7134_BOARD_AVERMEDIA_A169_B: | 5555 | case SAA7134_BOARD_AVERMEDIA_A169_B: |
5163 | case SAA7134_BOARD_MD7134_BRIDGE_2: | ||
5164 | printk("%s: %s: dual saa713x broadcast decoders\n" | 5556 | printk("%s: %s: dual saa713x broadcast decoders\n" |
5165 | "%s: Sorry, none of the inputs to this chip are supported yet.\n" | 5557 | "%s: Sorry, none of the inputs to this chip are supported yet.\n" |
5166 | "%s: Dual decoder functionality is disabled for now, use the other chip.\n", | 5558 | "%s: Dual decoder functionality is disabled for now, use the other chip.\n", |
@@ -5172,6 +5564,15 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
5172 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x8c040007, 0x8c040007); | 5564 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x8c040007, 0x8c040007); |
5173 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd); | 5565 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd); |
5174 | break; | 5566 | break; |
5567 | case SAA7134_BOARD_AVERMEDIA_A700_PRO: | ||
5568 | case SAA7134_BOARD_AVERMEDIA_A700_HYBRID: | ||
5569 | /* write windows gpio values */ | ||
5570 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100); | ||
5571 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100); | ||
5572 | printk("%s: %s: hybrid analog/dvb card\n" | ||
5573 | "%s: Sorry, only the analog inputs are supported for now.\n", | ||
5574 | dev->name, card(dev).name, dev->name); | ||
5575 | break; | ||
5175 | } | 5576 | } |
5176 | return 0; | 5577 | return 0; |
5177 | } | 5578 | } |
@@ -5200,11 +5601,16 @@ int saa7134_board_init2(struct saa7134_dev *dev) | |||
5200 | dev->tuner_type = saa7134_boards[dev->board].tuner_type; | 5601 | dev->tuner_type = saa7134_boards[dev->board].tuner_type; |
5201 | 5602 | ||
5202 | if (TUNER_ABSENT != dev->tuner_type) { | 5603 | if (TUNER_ABSENT != dev->tuner_type) { |
5203 | tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; | 5604 | tun_setup.mode_mask = T_RADIO | |
5204 | tun_setup.type = dev->tuner_type; | 5605 | T_ANALOG_TV | |
5205 | tun_setup.addr = ADDR_UNSET; | 5606 | T_DIGITAL_TV; |
5607 | tun_setup.type = dev->tuner_type; | ||
5608 | tun_setup.addr = ADDR_UNSET; | ||
5609 | tun_setup.tuner_callback = saa7134_tuner_callback; | ||
5206 | 5610 | ||
5207 | saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup); | 5611 | saa7134_i2c_call_clients(dev, |
5612 | TUNER_SET_TYPE_ADDR, | ||
5613 | &tun_setup); | ||
5208 | } | 5614 | } |
5209 | break; | 5615 | break; |
5210 | case SAA7134_BOARD_MD7134: | 5616 | case SAA7134_BOARD_MD7134: |
@@ -5275,14 +5681,25 @@ int saa7134_board_init2(struct saa7134_dev *dev) | |||
5275 | &tda9887_cfg); | 5681 | &tda9887_cfg); |
5276 | } | 5682 | } |
5277 | 5683 | ||
5278 | tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; | 5684 | tun_setup.mode_mask = T_RADIO | |
5685 | T_ANALOG_TV | | ||
5686 | T_DIGITAL_TV; | ||
5279 | tun_setup.type = dev->tuner_type; | 5687 | tun_setup.type = dev->tuner_type; |
5280 | tun_setup.addr = ADDR_UNSET; | 5688 | tun_setup.addr = ADDR_UNSET; |
5281 | 5689 | ||
5282 | saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup); | 5690 | saa7134_i2c_call_clients(dev, |
5691 | TUNER_SET_TYPE_ADDR, &tun_setup); | ||
5283 | } | 5692 | } |
5284 | break; | 5693 | break; |
5285 | case SAA7134_BOARD_PHILIPS_EUROPA: | 5694 | case SAA7134_BOARD_PHILIPS_EUROPA: |
5695 | if (dev->autodetected && (dev->eedata[0x41] == 0x1c)) { | ||
5696 | /* Reconfigure board as Snake reference design */ | ||
5697 | dev->board = SAA7134_BOARD_PHILIPS_SNAKE; | ||
5698 | dev->tuner_type = saa7134_boards[dev->board].tuner_type; | ||
5699 | printk(KERN_INFO "%s: Reconfigured board as %s\n", | ||
5700 | dev->name, saa7134_boards[dev->board].name); | ||
5701 | break; | ||
5702 | } | ||
5286 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | 5703 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: |
5287 | case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: | 5704 | case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: |
5288 | /* The Philips EUROPA based hybrid boards have the tuner connected through | 5705 | /* The Philips EUROPA based hybrid boards have the tuner connected through |
@@ -5333,6 +5750,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) | |||
5333 | case SAA7134_BOARD_MEDION_MD8800_QUADRO: | 5750 | case SAA7134_BOARD_MEDION_MD8800_QUADRO: |
5334 | case SAA7134_BOARD_AVERMEDIA_SUPER_007: | 5751 | case SAA7134_BOARD_AVERMEDIA_SUPER_007: |
5335 | case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: | 5752 | case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: |
5753 | case SAA7134_BOARD_CREATIX_CTX953: | ||
5336 | /* this is a hybrid board, initialize to analog mode | 5754 | /* this is a hybrid board, initialize to analog mode |
5337 | * and configure firmware eeprom address | 5755 | * and configure firmware eeprom address |
5338 | */ | 5756 | */ |
@@ -5402,13 +5820,46 @@ int saa7134_board_init2(struct saa7134_dev *dev) | |||
5402 | break; | 5820 | break; |
5403 | } | 5821 | } |
5404 | break; | 5822 | break; |
5823 | case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: | ||
5824 | { | ||
5825 | struct v4l2_priv_tun_config tea5767_cfg; | ||
5826 | struct tea5767_ctrl ctl; | ||
5827 | |||
5828 | dev->i2c_client.addr = 0xC0; | ||
5829 | /* set TEA5767(analog FM) defines */ | ||
5830 | memset(&ctl, 0, sizeof(ctl)); | ||
5831 | ctl.xtal_freq = TEA5767_HIGH_LO_13MHz; | ||
5832 | tea5767_cfg.tuner = TUNER_TEA5767; | ||
5833 | tea5767_cfg.priv = &ctl; | ||
5834 | saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tea5767_cfg); | ||
5835 | } | ||
5836 | break; | ||
5405 | } | 5837 | } |
5838 | |||
5839 | if (dev->tuner_type == TUNER_XC2028) { | ||
5840 | struct v4l2_priv_tun_config xc2028_cfg; | ||
5841 | struct xc2028_ctrl ctl; | ||
5842 | |||
5843 | memset(&xc2028_cfg, 0, sizeof(ctl)); | ||
5844 | memset(&ctl, 0, sizeof(ctl)); | ||
5845 | |||
5846 | ctl.fname = XC2028_DEFAULT_FIRMWARE; | ||
5847 | ctl.max_len = 64; | ||
5848 | |||
5849 | switch (dev->board) { | ||
5850 | case SAA7134_BOARD_AVERMEDIA_A16D: | ||
5851 | ctl.demod = XC3028_FE_ZARLINK456; | ||
5852 | break; | ||
5853 | default: | ||
5854 | ctl.demod = XC3028_FE_OREN538; | ||
5855 | ctl.mts = 1; | ||
5856 | } | ||
5857 | |||
5858 | xc2028_cfg.tuner = TUNER_XC2028; | ||
5859 | xc2028_cfg.priv = &ctl; | ||
5860 | |||
5861 | saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg); | ||
5862 | } | ||
5863 | |||
5406 | return 0; | 5864 | return 0; |
5407 | } | 5865 | } |
5408 | |||
5409 | /* ----------------------------------------------------------- */ | ||
5410 | /* | ||
5411 | * Local variables: | ||
5412 | * c-basic-offset: 8 | ||
5413 | * End: | ||
5414 | */ | ||
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 58ab163fdbd7..eec127864fe3 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -42,23 +42,23 @@ MODULE_LICENSE("GPL"); | |||
42 | 42 | ||
43 | /* ------------------------------------------------------------------ */ | 43 | /* ------------------------------------------------------------------ */ |
44 | 44 | ||
45 | static unsigned int irq_debug = 0; | 45 | static unsigned int irq_debug; |
46 | module_param(irq_debug, int, 0644); | 46 | module_param(irq_debug, int, 0644); |
47 | MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]"); | 47 | MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]"); |
48 | 48 | ||
49 | static unsigned int core_debug = 0; | 49 | static unsigned int core_debug; |
50 | module_param(core_debug, int, 0644); | 50 | module_param(core_debug, int, 0644); |
51 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); | 51 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); |
52 | 52 | ||
53 | static unsigned int gpio_tracking = 0; | 53 | static unsigned int gpio_tracking; |
54 | module_param(gpio_tracking, int, 0644); | 54 | module_param(gpio_tracking, int, 0644); |
55 | MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]"); | 55 | MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]"); |
56 | 56 | ||
57 | static unsigned int alsa = 0; | 57 | static unsigned int alsa; |
58 | module_param(alsa, int, 0644); | 58 | module_param(alsa, int, 0644); |
59 | MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]"); | 59 | MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]"); |
60 | 60 | ||
61 | static unsigned int oss = 0; | 61 | static unsigned int oss; |
62 | module_param(oss, int, 0644); | 62 | module_param(oss, int, 0644); |
63 | MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]"); | 63 | MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]"); |
64 | 64 | ||
@@ -142,39 +142,6 @@ void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value) | |||
142 | } | 142 | } |
143 | } | 143 | } |
144 | 144 | ||
145 | int saa7134_tuner_callback(void *ptr, int command, int arg) | ||
146 | { | ||
147 | u8 sync_control; | ||
148 | struct saa7134_dev *dev = ptr; | ||
149 | |||
150 | switch (dev->tuner_type) { | ||
151 | case TUNER_PHILIPS_TDA8290: | ||
152 | switch (command) { | ||
153 | case 0: /* switch LNA gain through GPIO 22*/ | ||
154 | saa7134_set_gpio(dev, 22, arg) ; | ||
155 | break; | ||
156 | case 1: /* vsync output at GPIO22. 50 / 60Hz */ | ||
157 | dprintk("setting GPIO22 to vsync %d\n", arg); | ||
158 | saa_andorb(SAA7134_VIDEO_PORT_CTRL3, 0x80, 0x80); | ||
159 | saa_andorb(SAA7134_VIDEO_PORT_CTRL6, 0x0f, 0x03); | ||
160 | if (arg == 1) | ||
161 | sync_control = 11; | ||
162 | else | ||
163 | sync_control = 17; | ||
164 | saa_writeb(SAA7134_VGATE_START, sync_control); | ||
165 | saa_writeb(SAA7134_VGATE_STOP, sync_control + 1); | ||
166 | saa_andorb(SAA7134_MISC_VGATE_MSB, 0x03, 0x00); | ||
167 | break; | ||
168 | default: | ||
169 | return -EINVAL; | ||
170 | } | ||
171 | break; | ||
172 | default: | ||
173 | return -ENODEV; | ||
174 | } | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | /* ------------------------------------------------------------------ */ | 145 | /* ------------------------------------------------------------------ */ |
179 | 146 | ||
180 | 147 | ||
@@ -897,6 +864,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
897 | struct saa7134_dev *dev; | 864 | struct saa7134_dev *dev; |
898 | struct saa7134_mpeg_ops *mops; | 865 | struct saa7134_mpeg_ops *mops; |
899 | int err; | 866 | int err; |
867 | int mask; | ||
868 | |||
869 | if (saa7134_devcount == SAA7134_MAXBOARDS) | ||
870 | return -ENOMEM; | ||
900 | 871 | ||
901 | dev = kzalloc(sizeof(*dev),GFP_KERNEL); | 872 | dev = kzalloc(sizeof(*dev),GFP_KERNEL); |
902 | if (NULL == dev) | 873 | if (NULL == dev) |
@@ -1094,6 +1065,11 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1094 | if (TUNER_ABSENT != dev->tuner_type) | 1065 | if (TUNER_ABSENT != dev->tuner_type) |
1095 | saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL); | 1066 | saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL); |
1096 | 1067 | ||
1068 | if (card(dev).gpiomask != 0) { | ||
1069 | mask = card(dev).gpiomask; | ||
1070 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask); | ||
1071 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, 0); | ||
1072 | } | ||
1097 | return 0; | 1073 | return 0; |
1098 | 1074 | ||
1099 | fail4: | 1075 | fail4: |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index ea2be9eceeb8..2d16be2259db 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -33,33 +33,40 @@ | |||
33 | #include "saa7134.h" | 33 | #include "saa7134.h" |
34 | #include <media/v4l2-common.h> | 34 | #include <media/v4l2-common.h> |
35 | #include "dvb-pll.h" | 35 | #include "dvb-pll.h" |
36 | #include <dvb_frontend.h> | ||
36 | 37 | ||
37 | #include "mt352.h" | 38 | #include "mt352.h" |
38 | #include "mt352_priv.h" /* FIXME */ | 39 | #include "mt352_priv.h" /* FIXME */ |
39 | #include "tda1004x.h" | 40 | #include "tda1004x.h" |
40 | #include "nxt200x.h" | 41 | #include "nxt200x.h" |
42 | #include "tuner-xc2028.h" | ||
41 | 43 | ||
42 | #include "tda10086.h" | 44 | #include "tda10086.h" |
43 | #include "tda826x.h" | 45 | #include "tda826x.h" |
44 | #include "tda827x.h" | 46 | #include "tda827x.h" |
45 | #include "isl6421.h" | 47 | #include "isl6421.h" |
48 | #include "isl6405.h" | ||
49 | #include "lnbp21.h" | ||
50 | #include "tuner-simple.h" | ||
46 | 51 | ||
47 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 52 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
48 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
49 | 54 | ||
50 | static unsigned int antenna_pwr = 0; | 55 | static unsigned int antenna_pwr; |
51 | 56 | ||
52 | module_param(antenna_pwr, int, 0444); | 57 | module_param(antenna_pwr, int, 0444); |
53 | MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)"); | 58 | MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)"); |
54 | 59 | ||
55 | static int use_frontend = 0; | 60 | static int use_frontend; |
56 | module_param(use_frontend, int, 0644); | 61 | module_param(use_frontend, int, 0644); |
57 | MODULE_PARM_DESC(use_frontend,"for cards with multiple frontends (0: terrestrial, 1: satellite)"); | 62 | MODULE_PARM_DESC(use_frontend,"for cards with multiple frontends (0: terrestrial, 1: satellite)"); |
58 | 63 | ||
59 | static int debug = 0; | 64 | static int debug; |
60 | module_param(debug, int, 0644); | 65 | module_param(debug, int, 0644); |
61 | MODULE_PARM_DESC(debug, "Turn on/off module debugging (default:off)."); | 66 | MODULE_PARM_DESC(debug, "Turn on/off module debugging (default:off)."); |
62 | 67 | ||
68 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
69 | |||
63 | #define dprintk(fmt, arg...) do { if (debug) \ | 70 | #define dprintk(fmt, arg...) do { if (debug) \ |
64 | printk(KERN_DEBUG "%s/dvb: " fmt, dev->name , ## arg); } while(0) | 71 | printk(KERN_DEBUG "%s/dvb: " fmt, dev->name , ## arg); } while(0) |
65 | 72 | ||
@@ -91,7 +98,7 @@ static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on) | |||
91 | saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28)); | 98 | saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28)); |
92 | udelay(10); | 99 | udelay(10); |
93 | ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27); | 100 | ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27); |
94 | dprintk("%s %s\n", __FUNCTION__, ok ? "on" : "off"); | 101 | dprintk("%s %s\n", __func__, ok ? "on" : "off"); |
95 | 102 | ||
96 | if (!ok) | 103 | if (!ok) |
97 | saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26)); | 104 | saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26)); |
@@ -111,7 +118,7 @@ static int mt352_pinnacle_init(struct dvb_frontend* fe) | |||
111 | static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 }; | 118 | static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 }; |
112 | struct saa7134_dev *dev= fe->dvb->priv; | 119 | struct saa7134_dev *dev= fe->dvb->priv; |
113 | 120 | ||
114 | dprintk("%s called\n", __FUNCTION__); | 121 | dprintk("%s called\n", __func__); |
115 | 122 | ||
116 | mt352_write(fe, clock_config, sizeof(clock_config)); | 123 | mt352_write(fe, clock_config, sizeof(clock_config)); |
117 | udelay(200); | 124 | udelay(200); |
@@ -146,6 +153,26 @@ static int mt352_aver777_init(struct dvb_frontend* fe) | |||
146 | return 0; | 153 | return 0; |
147 | } | 154 | } |
148 | 155 | ||
156 | static int mt352_aver_a16d_init(struct dvb_frontend *fe) | ||
157 | { | ||
158 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d }; | ||
159 | static u8 reset [] = { RESET, 0x80 }; | ||
160 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | ||
161 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 }; | ||
162 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x33 }; | ||
163 | |||
164 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
165 | udelay(200); | ||
166 | mt352_write(fe, reset, sizeof(reset)); | ||
167 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
168 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
169 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | |||
175 | |||
149 | static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe, | 176 | static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe, |
150 | struct dvb_frontend_parameters* params) | 177 | struct dvb_frontend_parameters* params) |
151 | { | 178 | { |
@@ -188,6 +215,16 @@ static struct mt352_config avermedia_777 = { | |||
188 | .demod_init = mt352_aver777_init, | 215 | .demod_init = mt352_aver777_init, |
189 | }; | 216 | }; |
190 | 217 | ||
218 | static struct mt352_config avermedia_16d = { | ||
219 | .demod_address = 0xf, | ||
220 | .demod_init = mt352_aver_a16d_init, | ||
221 | }; | ||
222 | |||
223 | static struct mt352_config avermedia_e506r_mt352_dev = { | ||
224 | .demod_address = (0x1e >> 1), | ||
225 | .no_tuner = 1, | ||
226 | }; | ||
227 | |||
191 | /* ================================================================== | 228 | /* ================================================================== |
192 | * tda1004x based DVB-T cards, helper functions | 229 | * tda1004x based DVB-T cards, helper functions |
193 | */ | 230 | */ |
@@ -430,8 +467,6 @@ static struct tda1004x_config philips_europa_config = { | |||
430 | .request_firmware = philips_tda1004x_request_firmware | 467 | .request_firmware = philips_tda1004x_request_firmware |
431 | }; | 468 | }; |
432 | 469 | ||
433 | /* ------------------------------------------------------------------ */ | ||
434 | |||
435 | static struct tda1004x_config medion_cardbus = { | 470 | static struct tda1004x_config medion_cardbus = { |
436 | .demod_address = 0x08, | 471 | .demod_address = 0x08, |
437 | .invert = 1, | 472 | .invert = 1, |
@@ -447,47 +482,6 @@ static struct tda1004x_config medion_cardbus = { | |||
447 | * tda 1004x based cards with philips silicon tuner | 482 | * tda 1004x based cards with philips silicon tuner |
448 | */ | 483 | */ |
449 | 484 | ||
450 | static void philips_tda827x_lna_gain(struct dvb_frontend *fe, int high) | ||
451 | { | ||
452 | struct saa7134_dev *dev = fe->dvb->priv; | ||
453 | struct tda1004x_state *state = fe->demodulator_priv; | ||
454 | u8 addr = state->config->i2c_gate; | ||
455 | u8 config = state->config->tuner_config; | ||
456 | u8 GP00_CF[] = {0x20, 0x01}; | ||
457 | u8 GP00_LEV[] = {0x22, 0x00}; | ||
458 | |||
459 | struct i2c_msg msg = {.addr = addr,.flags = 0,.buf = GP00_CF, .len = 2}; | ||
460 | if (config) { | ||
461 | if (high) { | ||
462 | dprintk("setting LNA to high gain\n"); | ||
463 | } else { | ||
464 | dprintk("setting LNA to low gain\n"); | ||
465 | } | ||
466 | } | ||
467 | switch (config) { | ||
468 | case 0: /* no LNA */ | ||
469 | break; | ||
470 | case 1: /* switch is GPIO 0 of tda8290 */ | ||
471 | case 2: | ||
472 | /* turn Vsync off */ | ||
473 | saa7134_set_gpio(dev, 22, 0); | ||
474 | GP00_LEV[1] = high ? 0 : 1; | ||
475 | if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) { | ||
476 | wprintk("could not access tda8290 at addr: 0x%02x\n", | ||
477 | addr << 1); | ||
478 | return; | ||
479 | } | ||
480 | msg.buf = GP00_LEV; | ||
481 | if (config == 2) | ||
482 | GP00_LEV[1] = high ? 1 : 0; | ||
483 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
484 | break; | ||
485 | case 3: /* switch with GPIO of saa713x */ | ||
486 | saa7134_set_gpio(dev, 22, high); | ||
487 | break; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | static int tda8290_i2c_gate_ctrl( struct dvb_frontend* fe, int enable) | 485 | static int tda8290_i2c_gate_ctrl( struct dvb_frontend* fe, int enable) |
492 | { | 486 | { |
493 | struct tda1004x_state *state = fe->demodulator_priv; | 487 | struct tda1004x_state *state = fe->demodulator_priv; |
@@ -510,8 +504,6 @@ static int tda8290_i2c_gate_ctrl( struct dvb_frontend* fe, int enable) | |||
510 | return 0; | 504 | return 0; |
511 | } | 505 | } |
512 | 506 | ||
513 | /* ------------------------------------------------------------------ */ | ||
514 | |||
515 | static int philips_tda827x_tuner_init(struct dvb_frontend *fe) | 507 | static int philips_tda827x_tuner_init(struct dvb_frontend *fe) |
516 | { | 508 | { |
517 | struct saa7134_dev *dev = fe->dvb->priv; | 509 | struct saa7134_dev *dev = fe->dvb->priv; |
@@ -546,28 +538,57 @@ static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe) | |||
546 | return 0; | 538 | return 0; |
547 | } | 539 | } |
548 | 540 | ||
549 | static struct tda827x_config tda827x_cfg = { | 541 | static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config *cdec_conf, |
550 | .lna_gain = philips_tda827x_lna_gain, | 542 | struct tda827x_config *tuner_conf) |
551 | .init = philips_tda827x_tuner_init, | ||
552 | .sleep = philips_tda827x_tuner_sleep | ||
553 | }; | ||
554 | |||
555 | static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config *tda_conf) | ||
556 | { | 543 | { |
557 | dev->dvb.frontend = dvb_attach(tda10046_attach, tda_conf, &dev->i2c_adap); | 544 | dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap); |
558 | if (dev->dvb.frontend) { | 545 | if (dev->dvb.frontend) { |
559 | if (tda_conf->i2c_gate) | 546 | if (cdec_conf->i2c_gate) |
560 | dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; | 547 | dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; |
561 | if (dvb_attach(tda827x_attach, dev->dvb.frontend, tda_conf->tuner_address, | 548 | if (dvb_attach(tda827x_attach, dev->dvb.frontend, cdec_conf->tuner_address, |
562 | &dev->i2c_adap,&tda827x_cfg) == NULL) { | 549 | &dev->i2c_adap, tuner_conf) == NULL) { |
563 | wprintk("no tda827x tuner found at addr: %02x\n", | 550 | wprintk("no tda827x tuner found at addr: %02x\n", |
564 | tda_conf->tuner_address); | 551 | cdec_conf->tuner_address); |
565 | } | 552 | } |
566 | } | 553 | } |
567 | } | 554 | } |
568 | 555 | ||
569 | /* ------------------------------------------------------------------ */ | 556 | /* ------------------------------------------------------------------ */ |
570 | 557 | ||
558 | static struct tda827x_config tda827x_cfg_0 = { | ||
559 | .tuner_callback = saa7134_tuner_callback, | ||
560 | .init = philips_tda827x_tuner_init, | ||
561 | .sleep = philips_tda827x_tuner_sleep, | ||
562 | .config = 0, | ||
563 | .switch_addr = 0 | ||
564 | }; | ||
565 | |||
566 | static struct tda827x_config tda827x_cfg_1 = { | ||
567 | .tuner_callback = saa7134_tuner_callback, | ||
568 | .init = philips_tda827x_tuner_init, | ||
569 | .sleep = philips_tda827x_tuner_sleep, | ||
570 | .config = 1, | ||
571 | .switch_addr = 0x4b | ||
572 | }; | ||
573 | |||
574 | static struct tda827x_config tda827x_cfg_2 = { | ||
575 | .tuner_callback = saa7134_tuner_callback, | ||
576 | .init = philips_tda827x_tuner_init, | ||
577 | .sleep = philips_tda827x_tuner_sleep, | ||
578 | .config = 2, | ||
579 | .switch_addr = 0x4b | ||
580 | }; | ||
581 | |||
582 | static struct tda827x_config tda827x_cfg_2_sw42 = { | ||
583 | .tuner_callback = saa7134_tuner_callback, | ||
584 | .init = philips_tda827x_tuner_init, | ||
585 | .sleep = philips_tda827x_tuner_sleep, | ||
586 | .config = 2, | ||
587 | .switch_addr = 0x42 | ||
588 | }; | ||
589 | |||
590 | /* ------------------------------------------------------------------ */ | ||
591 | |||
571 | static struct tda1004x_config tda827x_lifeview_config = { | 592 | static struct tda1004x_config tda827x_lifeview_config = { |
572 | .demod_address = 0x08, | 593 | .demod_address = 0x08, |
573 | .invert = 1, | 594 | .invert = 1, |
@@ -590,7 +611,6 @@ static struct tda1004x_config philips_tiger_config = { | |||
590 | .if_freq = TDA10046_FREQ_045, | 611 | .if_freq = TDA10046_FREQ_045, |
591 | .i2c_gate = 0x4b, | 612 | .i2c_gate = 0x4b, |
592 | .tuner_address = 0x61, | 613 | .tuner_address = 0x61, |
593 | .tuner_config = 0, | ||
594 | .antenna_switch= 1, | 614 | .antenna_switch= 1, |
595 | .request_firmware = philips_tda1004x_request_firmware | 615 | .request_firmware = philips_tda1004x_request_firmware |
596 | }; | 616 | }; |
@@ -605,7 +625,6 @@ static struct tda1004x_config cinergy_ht_config = { | |||
605 | .if_freq = TDA10046_FREQ_045, | 625 | .if_freq = TDA10046_FREQ_045, |
606 | .i2c_gate = 0x4b, | 626 | .i2c_gate = 0x4b, |
607 | .tuner_address = 0x61, | 627 | .tuner_address = 0x61, |
608 | .tuner_config = 0, | ||
609 | .request_firmware = philips_tda1004x_request_firmware | 628 | .request_firmware = philips_tda1004x_request_firmware |
610 | }; | 629 | }; |
611 | 630 | ||
@@ -619,7 +638,6 @@ static struct tda1004x_config cinergy_ht_pci_config = { | |||
619 | .if_freq = TDA10046_FREQ_045, | 638 | .if_freq = TDA10046_FREQ_045, |
620 | .i2c_gate = 0x4b, | 639 | .i2c_gate = 0x4b, |
621 | .tuner_address = 0x60, | 640 | .tuner_address = 0x60, |
622 | .tuner_config = 0, | ||
623 | .request_firmware = philips_tda1004x_request_firmware | 641 | .request_firmware = philips_tda1004x_request_firmware |
624 | }; | 642 | }; |
625 | 643 | ||
@@ -633,7 +651,6 @@ static struct tda1004x_config philips_tiger_s_config = { | |||
633 | .if_freq = TDA10046_FREQ_045, | 651 | .if_freq = TDA10046_FREQ_045, |
634 | .i2c_gate = 0x4b, | 652 | .i2c_gate = 0x4b, |
635 | .tuner_address = 0x61, | 653 | .tuner_address = 0x61, |
636 | .tuner_config = 2, | ||
637 | .antenna_switch= 1, | 654 | .antenna_switch= 1, |
638 | .request_firmware = philips_tda1004x_request_firmware | 655 | .request_firmware = philips_tda1004x_request_firmware |
639 | }; | 656 | }; |
@@ -648,7 +665,6 @@ static struct tda1004x_config pinnacle_pctv_310i_config = { | |||
648 | .if_freq = TDA10046_FREQ_045, | 665 | .if_freq = TDA10046_FREQ_045, |
649 | .i2c_gate = 0x4b, | 666 | .i2c_gate = 0x4b, |
650 | .tuner_address = 0x61, | 667 | .tuner_address = 0x61, |
651 | .tuner_config = 1, | ||
652 | .request_firmware = philips_tda1004x_request_firmware | 668 | .request_firmware = philips_tda1004x_request_firmware |
653 | }; | 669 | }; |
654 | 670 | ||
@@ -662,7 +678,6 @@ static struct tda1004x_config hauppauge_hvr_1110_config = { | |||
662 | .if_freq = TDA10046_FREQ_045, | 678 | .if_freq = TDA10046_FREQ_045, |
663 | .i2c_gate = 0x4b, | 679 | .i2c_gate = 0x4b, |
664 | .tuner_address = 0x61, | 680 | .tuner_address = 0x61, |
665 | .tuner_config = 1, | ||
666 | .request_firmware = philips_tda1004x_request_firmware | 681 | .request_firmware = philips_tda1004x_request_firmware |
667 | }; | 682 | }; |
668 | 683 | ||
@@ -676,7 +691,6 @@ static struct tda1004x_config asus_p7131_dual_config = { | |||
676 | .if_freq = TDA10046_FREQ_045, | 691 | .if_freq = TDA10046_FREQ_045, |
677 | .i2c_gate = 0x4b, | 692 | .i2c_gate = 0x4b, |
678 | .tuner_address = 0x61, | 693 | .tuner_address = 0x61, |
679 | .tuner_config = 0, | ||
680 | .antenna_switch= 2, | 694 | .antenna_switch= 2, |
681 | .request_firmware = philips_tda1004x_request_firmware | 695 | .request_firmware = philips_tda1004x_request_firmware |
682 | }; | 696 | }; |
@@ -715,7 +729,6 @@ static struct tda1004x_config md8800_dvbt_config = { | |||
715 | .if_freq = TDA10046_FREQ_045, | 729 | .if_freq = TDA10046_FREQ_045, |
716 | .i2c_gate = 0x4b, | 730 | .i2c_gate = 0x4b, |
717 | .tuner_address = 0x60, | 731 | .tuner_address = 0x60, |
718 | .tuner_config = 0, | ||
719 | .request_firmware = philips_tda1004x_request_firmware | 732 | .request_firmware = philips_tda1004x_request_firmware |
720 | }; | 733 | }; |
721 | 734 | ||
@@ -729,7 +742,6 @@ static struct tda1004x_config asus_p7131_4871_config = { | |||
729 | .if_freq = TDA10046_FREQ_045, | 742 | .if_freq = TDA10046_FREQ_045, |
730 | .i2c_gate = 0x4b, | 743 | .i2c_gate = 0x4b, |
731 | .tuner_address = 0x61, | 744 | .tuner_address = 0x61, |
732 | .tuner_config = 2, | ||
733 | .antenna_switch= 2, | 745 | .antenna_switch= 2, |
734 | .request_firmware = philips_tda1004x_request_firmware | 746 | .request_firmware = philips_tda1004x_request_firmware |
735 | }; | 747 | }; |
@@ -744,7 +756,6 @@ static struct tda1004x_config asus_p7131_hybrid_lna_config = { | |||
744 | .if_freq = TDA10046_FREQ_045, | 756 | .if_freq = TDA10046_FREQ_045, |
745 | .i2c_gate = 0x4b, | 757 | .i2c_gate = 0x4b, |
746 | .tuner_address = 0x61, | 758 | .tuner_address = 0x61, |
747 | .tuner_config = 2, | ||
748 | .antenna_switch= 2, | 759 | .antenna_switch= 2, |
749 | .request_firmware = philips_tda1004x_request_firmware | 760 | .request_firmware = philips_tda1004x_request_firmware |
750 | }; | 761 | }; |
@@ -759,7 +770,6 @@ static struct tda1004x_config kworld_dvb_t_210_config = { | |||
759 | .if_freq = TDA10046_FREQ_045, | 770 | .if_freq = TDA10046_FREQ_045, |
760 | .i2c_gate = 0x4b, | 771 | .i2c_gate = 0x4b, |
761 | .tuner_address = 0x61, | 772 | .tuner_address = 0x61, |
762 | .tuner_config = 2, | ||
763 | .antenna_switch= 1, | 773 | .antenna_switch= 1, |
764 | .request_firmware = philips_tda1004x_request_firmware | 774 | .request_firmware = philips_tda1004x_request_firmware |
765 | }; | 775 | }; |
@@ -774,7 +784,6 @@ static struct tda1004x_config avermedia_super_007_config = { | |||
774 | .if_freq = TDA10046_FREQ_045, | 784 | .if_freq = TDA10046_FREQ_045, |
775 | .i2c_gate = 0x4b, | 785 | .i2c_gate = 0x4b, |
776 | .tuner_address = 0x60, | 786 | .tuner_address = 0x60, |
777 | .tuner_config = 0, | ||
778 | .antenna_switch= 1, | 787 | .antenna_switch= 1, |
779 | .request_firmware = philips_tda1004x_request_firmware | 788 | .request_firmware = philips_tda1004x_request_firmware |
780 | }; | 789 | }; |
@@ -789,7 +798,6 @@ static struct tda1004x_config twinhan_dtv_dvb_3056_config = { | |||
789 | .if_freq = TDA10046_FREQ_045, | 798 | .if_freq = TDA10046_FREQ_045, |
790 | .i2c_gate = 0x42, | 799 | .i2c_gate = 0x42, |
791 | .tuner_address = 0x61, | 800 | .tuner_address = 0x61, |
792 | .tuner_config = 2, | ||
793 | .antenna_switch = 1, | 801 | .antenna_switch = 1, |
794 | .request_firmware = philips_tda1004x_request_firmware | 802 | .request_firmware = philips_tda1004x_request_firmware |
795 | }; | 803 | }; |
@@ -817,9 +825,10 @@ static int ads_duo_tuner_sleep(struct dvb_frontend *fe) | |||
817 | } | 825 | } |
818 | 826 | ||
819 | static struct tda827x_config ads_duo_cfg = { | 827 | static struct tda827x_config ads_duo_cfg = { |
820 | .lna_gain = philips_tda827x_lna_gain, | 828 | .tuner_callback = saa7134_tuner_callback, |
821 | .init = ads_duo_tuner_init, | 829 | .init = ads_duo_tuner_init, |
822 | .sleep = ads_duo_tuner_sleep | 830 | .sleep = ads_duo_tuner_sleep, |
831 | .config = 0 | ||
823 | }; | 832 | }; |
824 | 833 | ||
825 | static struct tda1004x_config ads_tech_duo_config = { | 834 | static struct tda1004x_config ads_tech_duo_config = { |
@@ -842,8 +851,73 @@ static struct tda10086_config flydvbs = { | |||
842 | .demod_address = 0x0e, | 851 | .demod_address = 0x0e, |
843 | .invert = 0, | 852 | .invert = 0, |
844 | .diseqc_tone = 0, | 853 | .diseqc_tone = 0, |
854 | .xtal_freq = TDA10086_XTAL_16M, | ||
845 | }; | 855 | }; |
846 | 856 | ||
857 | static struct tda10086_config sd1878_4m = { | ||
858 | .demod_address = 0x0e, | ||
859 | .invert = 0, | ||
860 | .diseqc_tone = 0, | ||
861 | .xtal_freq = TDA10086_XTAL_4M, | ||
862 | }; | ||
863 | |||
864 | /* ------------------------------------------------------------------ | ||
865 | * special case: lnb supply is connected to the gated i2c | ||
866 | */ | ||
867 | |||
868 | static int md8800_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
869 | { | ||
870 | int res = -EIO; | ||
871 | struct saa7134_dev *dev = fe->dvb->priv; | ||
872 | if (fe->ops.i2c_gate_ctrl) { | ||
873 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
874 | if (dev->original_set_voltage) | ||
875 | res = dev->original_set_voltage(fe, voltage); | ||
876 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
877 | } | ||
878 | return res; | ||
879 | }; | ||
880 | |||
881 | static int md8800_set_high_voltage(struct dvb_frontend *fe, long arg) | ||
882 | { | ||
883 | int res = -EIO; | ||
884 | struct saa7134_dev *dev = fe->dvb->priv; | ||
885 | if (fe->ops.i2c_gate_ctrl) { | ||
886 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
887 | if (dev->original_set_high_voltage) | ||
888 | res = dev->original_set_high_voltage(fe, arg); | ||
889 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
890 | } | ||
891 | return res; | ||
892 | }; | ||
893 | |||
894 | static int md8800_set_voltage2(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
895 | { | ||
896 | struct saa7134_dev *dev = fe->dvb->priv; | ||
897 | u8 wbuf[2] = { 0x1f, 00 }; | ||
898 | u8 rbuf; | ||
899 | struct i2c_msg msg[] = { { .addr = 0x08, .flags = 0, .buf = wbuf, .len = 1 }, | ||
900 | { .addr = 0x08, .flags = I2C_M_RD, .buf = &rbuf, .len = 1 } }; | ||
901 | |||
902 | if (i2c_transfer(&dev->i2c_adap, msg, 2) != 2) | ||
903 | return -EIO; | ||
904 | /* NOTE: this assumes that gpo1 is used, it might be bit 5 (gpo2) */ | ||
905 | if (voltage == SEC_VOLTAGE_18) | ||
906 | wbuf[1] = rbuf | 0x10; | ||
907 | else | ||
908 | wbuf[1] = rbuf & 0xef; | ||
909 | msg[0].len = 2; | ||
910 | i2c_transfer(&dev->i2c_adap, msg, 1); | ||
911 | return 0; | ||
912 | } | ||
913 | |||
914 | static int md8800_set_high_voltage2(struct dvb_frontend *fe, long arg) | ||
915 | { | ||
916 | struct saa7134_dev *dev = fe->dvb->priv; | ||
917 | wprintk("%s: sorry can't set high LNB supply voltage from here\n", __func__); | ||
918 | return -EIO; | ||
919 | } | ||
920 | |||
847 | /* ================================================================== | 921 | /* ================================================================== |
848 | * nxt200x based ATSC cards, helper functions | 922 | * nxt200x based ATSC cards, helper functions |
849 | */ | 923 | */ |
@@ -863,12 +937,14 @@ static struct nxt200x_config kworldatsc110 = { | |||
863 | static int dvb_init(struct saa7134_dev *dev) | 937 | static int dvb_init(struct saa7134_dev *dev) |
864 | { | 938 | { |
865 | int ret; | 939 | int ret; |
940 | int attach_xc3028 = 0; | ||
941 | |||
866 | /* init struct videobuf_dvb */ | 942 | /* init struct videobuf_dvb */ |
867 | dev->ts.nr_bufs = 32; | 943 | dev->ts.nr_bufs = 32; |
868 | dev->ts.nr_packets = 32*4; | 944 | dev->ts.nr_packets = 32*4; |
869 | dev->dvb.name = dev->name; | 945 | dev->dvb.name = dev->name; |
870 | videobuf_queue_pci_init(&dev->dvb.dvbq, &saa7134_ts_qops, | 946 | videobuf_queue_sg_init(&dev->dvb.dvbq, &saa7134_ts_qops, |
871 | dev->pci, &dev->slock, | 947 | &dev->pci->dev, &dev->slock, |
872 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 948 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
873 | V4L2_FIELD_ALTERNATE, | 949 | V4L2_FIELD_ALTERNATE, |
874 | sizeof(struct saa7134_buf), | 950 | sizeof(struct saa7134_buf), |
@@ -889,17 +965,25 @@ static int dvb_init(struct saa7134_dev *dev) | |||
889 | dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, | 965 | dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, |
890 | &dev->i2c_adap); | 966 | &dev->i2c_adap); |
891 | if (dev->dvb.frontend) { | 967 | if (dev->dvb.frontend) { |
892 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 968 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
893 | NULL, DVB_PLL_PHILIPS_TD1316); | 969 | &dev->i2c_adap, 0x61, |
970 | TUNER_PHILIPS_TD1316); | ||
894 | } | 971 | } |
895 | break; | 972 | break; |
973 | case SAA7134_BOARD_AVERMEDIA_A16D: | ||
974 | dprintk("avertv A16D dvb setup\n"); | ||
975 | dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_16d, | ||
976 | &dev->i2c_adap); | ||
977 | attach_xc3028 = 1; | ||
978 | break; | ||
896 | case SAA7134_BOARD_MD7134: | 979 | case SAA7134_BOARD_MD7134: |
897 | dev->dvb.frontend = dvb_attach(tda10046_attach, | 980 | dev->dvb.frontend = dvb_attach(tda10046_attach, |
898 | &medion_cardbus, | 981 | &medion_cardbus, |
899 | &dev->i2c_adap); | 982 | &dev->i2c_adap); |
900 | if (dev->dvb.frontend) { | 983 | if (dev->dvb.frontend) { |
901 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, medion_cardbus.tuner_address, | 984 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
902 | &dev->i2c_adap, DVB_PLL_FMD1216ME); | 985 | &dev->i2c_adap, medion_cardbus.tuner_address, |
986 | TUNER_PHILIPS_FMD1216ME_MK3); | ||
903 | } | 987 | } |
904 | break; | 988 | break; |
905 | case SAA7134_BOARD_PHILIPS_TOUGH: | 989 | case SAA7134_BOARD_PHILIPS_TOUGH: |
@@ -913,7 +997,7 @@ static int dvb_init(struct saa7134_dev *dev) | |||
913 | break; | 997 | break; |
914 | case SAA7134_BOARD_FLYDVBTDUO: | 998 | case SAA7134_BOARD_FLYDVBTDUO: |
915 | case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: | 999 | case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: |
916 | configure_tda827x_fe(dev, &tda827x_lifeview_config); | 1000 | configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0); |
917 | break; | 1001 | break; |
918 | case SAA7134_BOARD_PHILIPS_EUROPA: | 1002 | case SAA7134_BOARD_PHILIPS_EUROPA: |
919 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | 1003 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: |
@@ -938,36 +1022,36 @@ static int dvb_init(struct saa7134_dev *dev) | |||
938 | } | 1022 | } |
939 | break; | 1023 | break; |
940 | case SAA7134_BOARD_KWORLD_DVBT_210: | 1024 | case SAA7134_BOARD_KWORLD_DVBT_210: |
941 | configure_tda827x_fe(dev, &kworld_dvb_t_210_config); | 1025 | configure_tda827x_fe(dev, &kworld_dvb_t_210_config, &tda827x_cfg_2); |
942 | break; | 1026 | break; |
943 | case SAA7134_BOARD_PHILIPS_TIGER: | 1027 | case SAA7134_BOARD_PHILIPS_TIGER: |
944 | configure_tda827x_fe(dev, &philips_tiger_config); | 1028 | configure_tda827x_fe(dev, &philips_tiger_config, &tda827x_cfg_0); |
945 | break; | 1029 | break; |
946 | case SAA7134_BOARD_PINNACLE_PCTV_310i: | 1030 | case SAA7134_BOARD_PINNACLE_PCTV_310i: |
947 | configure_tda827x_fe(dev, &pinnacle_pctv_310i_config); | 1031 | configure_tda827x_fe(dev, &pinnacle_pctv_310i_config, &tda827x_cfg_1); |
948 | break; | 1032 | break; |
949 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: | 1033 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: |
950 | configure_tda827x_fe(dev, &hauppauge_hvr_1110_config); | 1034 | configure_tda827x_fe(dev, &hauppauge_hvr_1110_config, &tda827x_cfg_1); |
951 | break; | 1035 | break; |
952 | case SAA7134_BOARD_ASUSTeK_P7131_DUAL: | 1036 | case SAA7134_BOARD_ASUSTeK_P7131_DUAL: |
953 | configure_tda827x_fe(dev, &asus_p7131_dual_config); | 1037 | configure_tda827x_fe(dev, &asus_p7131_dual_config, &tda827x_cfg_0); |
954 | break; | 1038 | break; |
955 | case SAA7134_BOARD_FLYDVBT_LR301: | 1039 | case SAA7134_BOARD_FLYDVBT_LR301: |
956 | configure_tda827x_fe(dev, &tda827x_lifeview_config); | 1040 | configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0); |
957 | break; | 1041 | break; |
958 | case SAA7134_BOARD_FLYDVB_TRIO: | 1042 | case SAA7134_BOARD_FLYDVB_TRIO: |
959 | if(! use_frontend) { /* terrestrial */ | 1043 | if(! use_frontend) { /* terrestrial */ |
960 | configure_tda827x_fe(dev, &lifeview_trio_config); | 1044 | configure_tda827x_fe(dev, &lifeview_trio_config, &tda827x_cfg_0); |
961 | } else { /* satellite */ | 1045 | } else { /* satellite */ |
962 | dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); | 1046 | dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); |
963 | if (dev->dvb.frontend) { | 1047 | if (dev->dvb.frontend) { |
964 | if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, | 1048 | if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, |
965 | &dev->i2c_adap, 0) == NULL) { | 1049 | &dev->i2c_adap, 0) == NULL) { |
966 | wprintk("%s: Lifeview Trio, No tda826x found!\n", __FUNCTION__); | 1050 | wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__); |
967 | } | 1051 | } |
968 | if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, | 1052 | if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, |
969 | 0x08, 0, 0) == NULL) { | 1053 | 0x08, 0, 0) == NULL) { |
970 | wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __FUNCTION__); | 1054 | wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__); |
971 | } | 1055 | } |
972 | } | 1056 | } |
973 | } | 1057 | } |
@@ -979,18 +1063,56 @@ static int dvb_init(struct saa7134_dev *dev) | |||
979 | &dev->i2c_adap); | 1063 | &dev->i2c_adap); |
980 | if (dev->dvb.frontend) { | 1064 | if (dev->dvb.frontend) { |
981 | if (dvb_attach(tda827x_attach,dev->dvb.frontend, | 1065 | if (dvb_attach(tda827x_attach,dev->dvb.frontend, |
982 | ads_tech_duo_config.tuner_address, | 1066 | ads_tech_duo_config.tuner_address, &dev->i2c_adap, |
983 | &dev->i2c_adap,&ads_duo_cfg) == NULL) { | 1067 | &ads_duo_cfg) == NULL) { |
984 | wprintk("no tda827x tuner found at addr: %02x\n", | 1068 | wprintk("no tda827x tuner found at addr: %02x\n", |
985 | ads_tech_duo_config.tuner_address); | 1069 | ads_tech_duo_config.tuner_address); |
986 | } | 1070 | } |
987 | } | 1071 | } |
988 | break; | 1072 | break; |
989 | case SAA7134_BOARD_TEVION_DVBT_220RF: | 1073 | case SAA7134_BOARD_TEVION_DVBT_220RF: |
990 | configure_tda827x_fe(dev, &tevion_dvbt220rf_config); | 1074 | configure_tda827x_fe(dev, &tevion_dvbt220rf_config, &tda827x_cfg_0); |
991 | break; | 1075 | break; |
992 | case SAA7134_BOARD_MEDION_MD8800_QUADRO: | 1076 | case SAA7134_BOARD_MEDION_MD8800_QUADRO: |
993 | configure_tda827x_fe(dev, &md8800_dvbt_config); | 1077 | if (!use_frontend) { /* terrestrial */ |
1078 | configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0); | ||
1079 | } else { /* satellite */ | ||
1080 | dev->dvb.frontend = dvb_attach(tda10086_attach, | ||
1081 | &flydvbs, &dev->i2c_adap); | ||
1082 | if (dev->dvb.frontend) { | ||
1083 | struct dvb_frontend *fe = dev->dvb.frontend; | ||
1084 | u8 dev_id = dev->eedata[2]; | ||
1085 | u8 data = 0xc4; | ||
1086 | struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1}; | ||
1087 | |||
1088 | if (dvb_attach(tda826x_attach, dev->dvb.frontend, | ||
1089 | 0x60, &dev->i2c_adap, 0) == NULL) | ||
1090 | wprintk("%s: Medion Quadro, no tda826x " | ||
1091 | "found !\n", __func__); | ||
1092 | if (dev_id != 0x08) { | ||
1093 | /* we need to open the i2c gate (we know it exists) */ | ||
1094 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1095 | if (dvb_attach(isl6405_attach, fe, | ||
1096 | &dev->i2c_adap, 0x08, 0, 0) == NULL) | ||
1097 | wprintk("%s: Medion Quadro, no ISL6405 " | ||
1098 | "found !\n", __func__); | ||
1099 | if (dev_id == 0x07) { | ||
1100 | /* fire up the 2nd section of the LNB supply since | ||
1101 | we can't do this from the other section */ | ||
1102 | msg.buf = &data; | ||
1103 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
1104 | } | ||
1105 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
1106 | dev->original_set_voltage = fe->ops.set_voltage; | ||
1107 | fe->ops.set_voltage = md8800_set_voltage; | ||
1108 | dev->original_set_high_voltage = fe->ops.enable_high_lnb_voltage; | ||
1109 | fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage; | ||
1110 | } else { | ||
1111 | fe->ops.set_voltage = md8800_set_voltage2; | ||
1112 | fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage2; | ||
1113 | } | ||
1114 | } | ||
1115 | } | ||
994 | break; | 1116 | break; |
995 | case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: | 1117 | case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: |
996 | dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180, | 1118 | dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180, |
@@ -1004,8 +1126,9 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1004 | dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110, | 1126 | dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110, |
1005 | &dev->i2c_adap); | 1127 | &dev->i2c_adap); |
1006 | if (dev->dvb.frontend) { | 1128 | if (dev->dvb.frontend) { |
1007 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 1129 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
1008 | NULL, DVB_PLL_TUV1236D); | 1130 | &dev->i2c_adap, 0x61, |
1131 | TUNER_PHILIPS_TUV1236D); | ||
1009 | } | 1132 | } |
1010 | break; | 1133 | break; |
1011 | case SAA7134_BOARD_FLYDVBS_LR300: | 1134 | case SAA7134_BOARD_FLYDVBS_LR300: |
@@ -1014,11 +1137,11 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1014 | if (dev->dvb.frontend) { | 1137 | if (dev->dvb.frontend) { |
1015 | if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, | 1138 | if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, |
1016 | &dev->i2c_adap, 0) == NULL) { | 1139 | &dev->i2c_adap, 0) == NULL) { |
1017 | wprintk("%s: No tda826x found!\n", __FUNCTION__); | 1140 | wprintk("%s: No tda826x found!\n", __func__); |
1018 | } | 1141 | } |
1019 | if (dvb_attach(isl6421_attach, dev->dvb.frontend, | 1142 | if (dvb_attach(isl6421_attach, dev->dvb.frontend, |
1020 | &dev->i2c_adap, 0x08, 0, 0) == NULL) { | 1143 | &dev->i2c_adap, 0x08, 0, 0) == NULL) { |
1021 | wprintk("%s: No ISL6421 found!\n", __FUNCTION__); | 1144 | wprintk("%s: No ISL6421 found!\n", __func__); |
1022 | } | 1145 | } |
1023 | } | 1146 | } |
1024 | break; | 1147 | break; |
@@ -1030,8 +1153,9 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1030 | dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; | 1153 | dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; |
1031 | dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; | 1154 | dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; |
1032 | 1155 | ||
1033 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, medion_cardbus.tuner_address, | 1156 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, |
1034 | &dev->i2c_adap, DVB_PLL_FMD1216ME); | 1157 | &dev->i2c_adap, medion_cardbus.tuner_address, |
1158 | TUNER_PHILIPS_FMD1216ME_MK3); | ||
1035 | } | 1159 | } |
1036 | break; | 1160 | break; |
1037 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: | 1161 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: |
@@ -1044,38 +1168,107 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1044 | } | 1168 | } |
1045 | break; | 1169 | break; |
1046 | case SAA7134_BOARD_CINERGY_HT_PCMCIA: | 1170 | case SAA7134_BOARD_CINERGY_HT_PCMCIA: |
1047 | configure_tda827x_fe(dev, &cinergy_ht_config); | 1171 | configure_tda827x_fe(dev, &cinergy_ht_config, &tda827x_cfg_0); |
1048 | break; | 1172 | break; |
1049 | case SAA7134_BOARD_CINERGY_HT_PCI: | 1173 | case SAA7134_BOARD_CINERGY_HT_PCI: |
1050 | configure_tda827x_fe(dev, &cinergy_ht_pci_config); | 1174 | configure_tda827x_fe(dev, &cinergy_ht_pci_config, &tda827x_cfg_0); |
1051 | break; | 1175 | break; |
1052 | case SAA7134_BOARD_PHILIPS_TIGER_S: | 1176 | case SAA7134_BOARD_PHILIPS_TIGER_S: |
1053 | configure_tda827x_fe(dev, &philips_tiger_s_config); | 1177 | configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2); |
1054 | break; | 1178 | break; |
1055 | case SAA7134_BOARD_ASUS_P7131_4871: | 1179 | case SAA7134_BOARD_ASUS_P7131_4871: |
1056 | configure_tda827x_fe(dev, &asus_p7131_4871_config); | 1180 | configure_tda827x_fe(dev, &asus_p7131_4871_config, &tda827x_cfg_2); |
1057 | break; | 1181 | break; |
1058 | case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: | 1182 | case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: |
1059 | configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config); | 1183 | configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config, &tda827x_cfg_2); |
1060 | break; | 1184 | break; |
1061 | case SAA7134_BOARD_AVERMEDIA_SUPER_007: | 1185 | case SAA7134_BOARD_AVERMEDIA_SUPER_007: |
1062 | configure_tda827x_fe(dev, &avermedia_super_007_config); | 1186 | configure_tda827x_fe(dev, &avermedia_super_007_config, &tda827x_cfg_0); |
1063 | break; | 1187 | break; |
1064 | case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: | 1188 | case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: |
1065 | configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config); | 1189 | configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config, &tda827x_cfg_2_sw42); |
1190 | break; | ||
1191 | case SAA7134_BOARD_PHILIPS_SNAKE: | ||
1192 | dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, | ||
1193 | &dev->i2c_adap); | ||
1194 | if (dev->dvb.frontend) { | ||
1195 | if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, | ||
1196 | &dev->i2c_adap, 0) == NULL) | ||
1197 | wprintk("%s: No tda826x found!\n", __func__); | ||
1198 | if (dvb_attach(lnbp21_attach, dev->dvb.frontend, | ||
1199 | &dev->i2c_adap, 0, 0) == NULL) | ||
1200 | wprintk("%s: No lnbp21 found!\n", __func__); | ||
1201 | } | ||
1202 | break; | ||
1203 | case SAA7134_BOARD_CREATIX_CTX953: | ||
1204 | configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0); | ||
1205 | break; | ||
1206 | case SAA7134_BOARD_MSI_TVANYWHERE_AD11: | ||
1207 | configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2); | ||
1208 | break; | ||
1209 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: | ||
1210 | dev->dvb.frontend = dvb_attach(mt352_attach, | ||
1211 | &avermedia_e506r_mt352_dev, | ||
1212 | &dev->i2c_adap); | ||
1213 | attach_xc3028 = 1; | ||
1214 | break; | ||
1215 | case SAA7134_BOARD_MD7134_BRIDGE_2: | ||
1216 | dev->dvb.frontend = dvb_attach(tda10086_attach, | ||
1217 | &sd1878_4m, &dev->i2c_adap); | ||
1218 | if (dev->dvb.frontend) { | ||
1219 | struct dvb_frontend *fe; | ||
1220 | if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, | ||
1221 | &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) | ||
1222 | wprintk("%s: MD7134 DVB-S, no SD1878 " | ||
1223 | "found !\n", __func__); | ||
1224 | /* we need to open the i2c gate (we know it exists) */ | ||
1225 | fe = dev->dvb.frontend; | ||
1226 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1227 | if (dvb_attach(isl6405_attach, fe, | ||
1228 | &dev->i2c_adap, 0x08, 0, 0) == NULL) | ||
1229 | wprintk("%s: MD7134 DVB-S, no ISL6405 " | ||
1230 | "found !\n", __func__); | ||
1231 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
1232 | dev->original_set_voltage = fe->ops.set_voltage; | ||
1233 | fe->ops.set_voltage = md8800_set_voltage; | ||
1234 | dev->original_set_high_voltage = fe->ops.enable_high_lnb_voltage; | ||
1235 | fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage; | ||
1236 | } | ||
1066 | break; | 1237 | break; |
1067 | default: | 1238 | default: |
1068 | wprintk("Huh? unknown DVB card?\n"); | 1239 | wprintk("Huh? unknown DVB card?\n"); |
1069 | break; | 1240 | break; |
1070 | } | 1241 | } |
1071 | 1242 | ||
1243 | if (attach_xc3028) { | ||
1244 | struct dvb_frontend *fe; | ||
1245 | struct xc2028_config cfg = { | ||
1246 | .i2c_adap = &dev->i2c_adap, | ||
1247 | .i2c_addr = 0x61, | ||
1248 | }; | ||
1249 | |||
1250 | if (!dev->dvb.frontend) | ||
1251 | return -1; | ||
1252 | |||
1253 | fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); | ||
1254 | if (!fe) { | ||
1255 | printk(KERN_ERR "%s/2: xc3028 attach failed\n", | ||
1256 | dev->name); | ||
1257 | dvb_frontend_detach(dev->dvb.frontend); | ||
1258 | dvb_unregister_frontend(dev->dvb.frontend); | ||
1259 | dev->dvb.frontend = NULL; | ||
1260 | return -1; | ||
1261 | } | ||
1262 | } | ||
1263 | |||
1072 | if (NULL == dev->dvb.frontend) { | 1264 | if (NULL == dev->dvb.frontend) { |
1073 | printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); | 1265 | printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); |
1074 | return -1; | 1266 | return -1; |
1075 | } | 1267 | } |
1076 | 1268 | ||
1077 | /* register everything else */ | 1269 | /* register everything else */ |
1078 | ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); | 1270 | ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev, |
1271 | adapter_nr); | ||
1079 | 1272 | ||
1080 | /* this sequence is necessary to make the tda1004x load its firmware | 1273 | /* this sequence is necessary to make the tda1004x load its firmware |
1081 | * and to enter analog mode of hybrid boards | 1274 | * and to enter analog mode of hybrid boards |
@@ -1106,9 +1299,22 @@ static int dvb_fini(struct saa7134_dev *dev) | |||
1106 | 1299 | ||
1107 | /* otherwise we don't detect the tuner on next insmod */ | 1300 | /* otherwise we don't detect the tuner on next insmod */ |
1108 | saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg); | 1301 | saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg); |
1302 | } else if (dev->board == SAA7134_BOARD_MEDION_MD8800_QUADRO) { | ||
1303 | if ((dev->eedata[2] == 0x07) && use_frontend) { | ||
1304 | /* turn off the 2nd lnb supply */ | ||
1305 | u8 data = 0x80; | ||
1306 | struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1}; | ||
1307 | struct dvb_frontend *fe; | ||
1308 | fe = dev->dvb.frontend; | ||
1309 | if (fe->ops.i2c_gate_ctrl) { | ||
1310 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1311 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
1312 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
1313 | } | ||
1314 | } | ||
1109 | } | 1315 | } |
1110 | 1316 | if (dev->dvb.frontend) | |
1111 | videobuf_dvb_unregister(&dev->dvb); | 1317 | videobuf_dvb_unregister(&dev->dvb); |
1112 | return 0; | 1318 | return 0; |
1113 | } | 1319 | } |
1114 | 1320 | ||
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 3d2ec30de227..1314522a8130 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -40,7 +40,7 @@ static unsigned int empress_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | |||
40 | module_param_array(empress_nr, int, NULL, 0444); | 40 | module_param_array(empress_nr, int, NULL, 0444); |
41 | MODULE_PARM_DESC(empress_nr,"ts device number"); | 41 | MODULE_PARM_DESC(empress_nr,"ts device number"); |
42 | 42 | ||
43 | static unsigned int debug = 0; | 43 | static unsigned int debug; |
44 | module_param(debug, int, 0644); | 44 | module_param(debug, int, 0644); |
45 | MODULE_PARM_DESC(debug,"enable debug messages"); | 45 | MODULE_PARM_DESC(debug,"enable debug messages"); |
46 | 46 | ||
@@ -402,7 +402,7 @@ static int empress_init(struct saa7134_dev *dev) | |||
402 | { | 402 | { |
403 | int err; | 403 | int err; |
404 | 404 | ||
405 | dprintk("%s: %s\n",dev->name,__FUNCTION__); | 405 | dprintk("%s: %s\n",dev->name,__func__); |
406 | dev->empress_dev = video_device_alloc(); | 406 | dev->empress_dev = video_device_alloc(); |
407 | if (NULL == dev->empress_dev) | 407 | if (NULL == dev->empress_dev) |
408 | return -ENOMEM; | 408 | return -ENOMEM; |
@@ -427,8 +427,8 @@ static int empress_init(struct saa7134_dev *dev) | |||
427 | printk(KERN_INFO "%s: registered device video%d [mpeg]\n", | 427 | printk(KERN_INFO "%s: registered device video%d [mpeg]\n", |
428 | dev->name,dev->empress_dev->minor & 0x1f); | 428 | dev->name,dev->empress_dev->minor & 0x1f); |
429 | 429 | ||
430 | videobuf_queue_pci_init(&dev->empress_tsq, &saa7134_ts_qops, | 430 | videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops, |
431 | dev->pci, &dev->slock, | 431 | &dev->pci->dev, &dev->slock, |
432 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 432 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
433 | V4L2_FIELD_ALTERNATE, | 433 | V4L2_FIELD_ALTERNATE, |
434 | sizeof(struct saa7134_buf), | 434 | sizeof(struct saa7134_buf), |
@@ -440,7 +440,7 @@ static int empress_init(struct saa7134_dev *dev) | |||
440 | 440 | ||
441 | static int empress_fini(struct saa7134_dev *dev) | 441 | static int empress_fini(struct saa7134_dev *dev) |
442 | { | 442 | { |
443 | dprintk("%s: %s\n",dev->name,__FUNCTION__); | 443 | dprintk("%s: %s\n",dev->name,__func__); |
444 | 444 | ||
445 | if (NULL == dev->empress_dev) | 445 | if (NULL == dev->empress_dev) |
446 | return 0; | 446 | return 0; |
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index d3322c3018f2..2ccfaba0c490 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c | |||
@@ -33,11 +33,11 @@ | |||
33 | 33 | ||
34 | /* ----------------------------------------------------------- */ | 34 | /* ----------------------------------------------------------- */ |
35 | 35 | ||
36 | static unsigned int i2c_debug = 0; | 36 | static unsigned int i2c_debug; |
37 | module_param(i2c_debug, int, 0644); | 37 | module_param(i2c_debug, int, 0644); |
38 | MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]"); | 38 | MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]"); |
39 | 39 | ||
40 | static unsigned int i2c_scan = 0; | 40 | static unsigned int i2c_scan; |
41 | module_param(i2c_scan, int, 0444); | 41 | module_param(i2c_scan, int, 0444); |
42 | MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); | 42 | MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); |
43 | 43 | ||
@@ -140,6 +140,8 @@ static inline int i2c_is_busy(enum i2c_status status) | |||
140 | { | 140 | { |
141 | switch (status) { | 141 | switch (status) { |
142 | case BUSY: | 142 | case BUSY: |
143 | case TO_SCL: | ||
144 | case TO_ARB: | ||
143 | return true; | 145 | return true; |
144 | default: | 146 | default: |
145 | return false; | 147 | return false; |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index b4188819782f..767ff30832f2 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -27,15 +27,15 @@ | |||
27 | #include "saa7134-reg.h" | 27 | #include "saa7134-reg.h" |
28 | #include "saa7134.h" | 28 | #include "saa7134.h" |
29 | 29 | ||
30 | static unsigned int disable_ir = 0; | 30 | static unsigned int disable_ir; |
31 | module_param(disable_ir, int, 0444); | 31 | module_param(disable_ir, int, 0444); |
32 | MODULE_PARM_DESC(disable_ir,"disable infrared remote support"); | 32 | MODULE_PARM_DESC(disable_ir,"disable infrared remote support"); |
33 | 33 | ||
34 | static unsigned int ir_debug = 0; | 34 | static unsigned int ir_debug; |
35 | module_param(ir_debug, int, 0644); | 35 | module_param(ir_debug, int, 0644); |
36 | MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); | 36 | MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); |
37 | 37 | ||
38 | static int pinnacle_remote = 0; | 38 | static int pinnacle_remote; |
39 | module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ | 39 | module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ |
40 | MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); | 40 | MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); |
41 | 41 | ||
@@ -331,6 +331,11 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
331 | break; | 331 | break; |
332 | case SAA7134_BOARD_MANLI_MTV001: | 332 | case SAA7134_BOARD_MANLI_MTV001: |
333 | case SAA7134_BOARD_MANLI_MTV002: | 333 | case SAA7134_BOARD_MANLI_MTV002: |
334 | ir_codes = ir_codes_manli; | ||
335 | mask_keycode = 0x001f00; | ||
336 | mask_keyup = 0x004000; | ||
337 | polling = 50; /* ms */ | ||
338 | break; | ||
334 | case SAA7134_BOARD_BEHOLD_409FM: | 339 | case SAA7134_BOARD_BEHOLD_409FM: |
335 | case SAA7134_BOARD_BEHOLD_401: | 340 | case SAA7134_BOARD_BEHOLD_401: |
336 | case SAA7134_BOARD_BEHOLD_403: | 341 | case SAA7134_BOARD_BEHOLD_403: |
@@ -343,7 +348,13 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
343 | case SAA7134_BOARD_BEHOLD_505FM: | 348 | case SAA7134_BOARD_BEHOLD_505FM: |
344 | case SAA7134_BOARD_BEHOLD_507_9FM: | 349 | case SAA7134_BOARD_BEHOLD_507_9FM: |
345 | ir_codes = ir_codes_manli; | 350 | ir_codes = ir_codes_manli; |
346 | mask_keycode = 0x001f00; | 351 | mask_keycode = 0x003f00; |
352 | mask_keyup = 0x004000; | ||
353 | polling = 50; /* ms */ | ||
354 | break; | ||
355 | case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: | ||
356 | ir_codes = ir_codes_behold_columbus; | ||
357 | mask_keycode = 0x003f00; | ||
347 | mask_keyup = 0x004000; | 358 | mask_keyup = 0x004000; |
348 | polling = 50; // ms | 359 | polling = 50; // ms |
349 | break; | 360 | break; |
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h index ac6431ba4fc3..86f5eefdb0f6 100644 --- a/drivers/media/video/saa7134/saa7134-reg.h +++ b/drivers/media/video/saa7134/saa7134-reg.h | |||
@@ -365,6 +365,9 @@ | |||
365 | #define SAA7135_DSP_RWSTATE_RDB (1 << 1) | 365 | #define SAA7135_DSP_RWSTATE_RDB (1 << 1) |
366 | #define SAA7135_DSP_RWSTATE_WRR (1 << 0) | 366 | #define SAA7135_DSP_RWSTATE_WRR (1 << 0) |
367 | 367 | ||
368 | #define SAA7135_DSP_RWCLEAR 0x586 | ||
369 | #define SAA7135_DSP_RWCLEAR_RERR 1 | ||
370 | |||
368 | /* ------------------------------------------------------------------ */ | 371 | /* ------------------------------------------------------------------ */ |
369 | /* | 372 | /* |
370 | * Local variables: | 373 | * Local variables: |
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c index f1b8fcaeb43a..eae72fd60cec 100644 --- a/drivers/media/video/saa7134/saa7134-ts.c +++ b/drivers/media/video/saa7134/saa7134-ts.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | /* ------------------------------------------------------------------ */ | 33 | /* ------------------------------------------------------------------ */ |
34 | 34 | ||
35 | static unsigned int ts_debug = 0; | 35 | static unsigned int ts_debug; |
36 | module_param(ts_debug, int, 0644); | 36 | module_param(ts_debug, int, 0644); |
37 | MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]"); | 37 | MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]"); |
38 | 38 | ||
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index 4e9810469ae3..232af598d947 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c | |||
@@ -35,18 +35,18 @@ | |||
35 | 35 | ||
36 | /* ------------------------------------------------------------------ */ | 36 | /* ------------------------------------------------------------------ */ |
37 | 37 | ||
38 | static unsigned int audio_debug = 0; | 38 | static unsigned int audio_debug; |
39 | module_param(audio_debug, int, 0644); | 39 | module_param(audio_debug, int, 0644); |
40 | MODULE_PARM_DESC(audio_debug,"enable debug messages [tv audio]"); | 40 | MODULE_PARM_DESC(audio_debug,"enable debug messages [tv audio]"); |
41 | 41 | ||
42 | static unsigned int audio_ddep = 0; | 42 | static unsigned int audio_ddep; |
43 | module_param(audio_ddep, int, 0644); | 43 | module_param(audio_ddep, int, 0644); |
44 | MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite"); | 44 | MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite"); |
45 | 45 | ||
46 | static int audio_clock_override = UNSET; | 46 | static int audio_clock_override = UNSET; |
47 | module_param(audio_clock_override, int, 0644); | 47 | module_param(audio_clock_override, int, 0644); |
48 | 48 | ||
49 | static int audio_clock_tweak = 0; | 49 | static int audio_clock_tweak; |
50 | module_param(audio_clock_tweak, int, 0644); | 50 | module_param(audio_clock_tweak, int, 0644); |
51 | MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])"); | 51 | MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])"); |
52 | 52 | ||
@@ -653,6 +653,17 @@ static char *stdres[0x20] = { | |||
653 | 653 | ||
654 | #define DSP_RETRY 32 | 654 | #define DSP_RETRY 32 |
655 | #define DSP_DELAY 16 | 655 | #define DSP_DELAY 16 |
656 | #define SAA7135_DSP_RWCLEAR_RERR 1 | ||
657 | |||
658 | static inline int saa_dsp_reset_error_bit(struct saa7134_dev *dev) | ||
659 | { | ||
660 | int state = saa_readb(SAA7135_DSP_RWSTATE); | ||
661 | if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) { | ||
662 | d2printk("%s: resetting error bit\n", dev->name); | ||
663 | saa_writeb(SAA7135_DSP_RWCLEAR, SAA7135_DSP_RWCLEAR_RERR); | ||
664 | } | ||
665 | return 0; | ||
666 | } | ||
656 | 667 | ||
657 | static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit) | 668 | static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit) |
658 | { | 669 | { |
@@ -660,8 +671,8 @@ static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit) | |||
660 | 671 | ||
661 | state = saa_readb(SAA7135_DSP_RWSTATE); | 672 | state = saa_readb(SAA7135_DSP_RWSTATE); |
662 | if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) { | 673 | if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) { |
663 | printk("%s: dsp access error\n",dev->name); | 674 | printk(KERN_WARNING "%s: dsp access error\n", dev->name); |
664 | /* FIXME: send ack ... */ | 675 | saa_dsp_reset_error_bit(dev); |
665 | return -EIO; | 676 | return -EIO; |
666 | } | 677 | } |
667 | while (0 == (state & bit)) { | 678 | while (0 == (state & bit)) { |
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c index f0d5ed9c2b06..cb0304298a96 100644 --- a/drivers/media/video/saa7134/saa7134-vbi.c +++ b/drivers/media/video/saa7134/saa7134-vbi.c | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | /* ------------------------------------------------------------------ */ | 32 | /* ------------------------------------------------------------------ */ |
33 | 33 | ||
34 | static unsigned int vbi_debug = 0; | 34 | static unsigned int vbi_debug; |
35 | module_param(vbi_debug, int, 0644); | 35 | module_param(vbi_debug, int, 0644); |
36 | MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); | 36 | MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); |
37 | 37 | ||
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 39c41ad97d0e..a0baf2d0ba7f 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -40,7 +40,7 @@ | |||
40 | 40 | ||
41 | unsigned int video_debug; | 41 | unsigned int video_debug; |
42 | static unsigned int gbuffers = 8; | 42 | static unsigned int gbuffers = 8; |
43 | static unsigned int noninterlaced = 0; | 43 | static unsigned int noninterlaced; /* 0 */ |
44 | static unsigned int gbufsize = 720*576*4; | 44 | static unsigned int gbufsize = 720*576*4; |
45 | static unsigned int gbufsize_max = 720*576*4; | 45 | static unsigned int gbufsize_max = 720*576*4; |
46 | static char secam[] = "--"; | 46 | static char secam[] = "--"; |
@@ -626,13 +626,8 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev) | |||
626 | { | 626 | { |
627 | saa7134_set_decoder(dev); | 627 | saa7134_set_decoder(dev); |
628 | 628 | ||
629 | if (card_in(dev, dev->ctl_input).tv) { | 629 | if (card_in(dev, dev->ctl_input).tv) |
630 | if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290) | ||
631 | && ((card(dev).tuner_config == 1) | ||
632 | || (card(dev).tuner_config == 2))) | ||
633 | saa7134_set_gpio(dev, 22, 5); | ||
634 | saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id); | 630 | saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id); |
635 | } | ||
636 | } | 631 | } |
637 | 632 | ||
638 | static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale) | 633 | static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale) |
@@ -1350,14 +1345,14 @@ static int video_open(struct inode *inode, struct file *file) | |||
1350 | fh->height = 576; | 1345 | fh->height = 576; |
1351 | v4l2_prio_open(&dev->prio,&fh->prio); | 1346 | v4l2_prio_open(&dev->prio,&fh->prio); |
1352 | 1347 | ||
1353 | videobuf_queue_pci_init(&fh->cap, &video_qops, | 1348 | videobuf_queue_sg_init(&fh->cap, &video_qops, |
1354 | dev->pci, &dev->slock, | 1349 | &dev->pci->dev, &dev->slock, |
1355 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1350 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1356 | V4L2_FIELD_INTERLACED, | 1351 | V4L2_FIELD_INTERLACED, |
1357 | sizeof(struct saa7134_buf), | 1352 | sizeof(struct saa7134_buf), |
1358 | fh); | 1353 | fh); |
1359 | videobuf_queue_pci_init(&fh->vbi, &saa7134_vbi_qops, | 1354 | videobuf_queue_sg_init(&fh->vbi, &saa7134_vbi_qops, |
1360 | dev->pci, &dev->slock, | 1355 | &dev->pci->dev, &dev->slock, |
1361 | V4L2_BUF_TYPE_VBI_CAPTURE, | 1356 | V4L2_BUF_TYPE_VBI_CAPTURE, |
1362 | V4L2_FIELD_SEQ_TB, | 1357 | V4L2_FIELD_SEQ_TB, |
1363 | sizeof(struct saa7134_buf), | 1358 | sizeof(struct saa7134_buf), |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index f940d0254798..924ffd13637e 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -253,7 +253,17 @@ struct saa7134_format { | |||
253 | #define SAA7134_BOARD_BEHOLD_607_9FM 129 | 253 | #define SAA7134_BOARD_BEHOLD_607_9FM 129 |
254 | #define SAA7134_BOARD_BEHOLD_M6 130 | 254 | #define SAA7134_BOARD_BEHOLD_M6 130 |
255 | #define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131 | 255 | #define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131 |
256 | #define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132 | 256 | #define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132 |
257 | #define SAA7134_BOARD_PHILIPS_SNAKE 133 | ||
258 | #define SAA7134_BOARD_CREATIX_CTX953 134 | ||
259 | #define SAA7134_BOARD_MSI_TVANYWHERE_AD11 135 | ||
260 | #define SAA7134_BOARD_AVERMEDIA_CARDBUS_506 136 | ||
261 | #define SAA7134_BOARD_AVERMEDIA_A16D 137 | ||
262 | #define SAA7134_BOARD_AVERMEDIA_M115 138 | ||
263 | #define SAA7134_BOARD_VIDEOMATE_T750 139 | ||
264 | #define SAA7134_BOARD_AVERMEDIA_A700_PRO 140 | ||
265 | #define SAA7134_BOARD_AVERMEDIA_A700_HYBRID 141 | ||
266 | |||
257 | 267 | ||
258 | #define SAA7134_MAXBOARDS 8 | 268 | #define SAA7134_MAXBOARDS 8 |
259 | #define SAA7134_INPUT_MAX 8 | 269 | #define SAA7134_INPUT_MAX 8 |
@@ -380,9 +390,7 @@ struct saa7134_fh { | |||
380 | unsigned int radio; | 390 | unsigned int radio; |
381 | enum v4l2_buf_type type; | 391 | enum v4l2_buf_type type; |
382 | unsigned int resources; | 392 | unsigned int resources; |
383 | #ifdef VIDIOC_G_PRIORITY | ||
384 | enum v4l2_priority prio; | 393 | enum v4l2_priority prio; |
385 | #endif | ||
386 | 394 | ||
387 | /* video overlay */ | 395 | /* video overlay */ |
388 | struct v4l2_window win; | 396 | struct v4l2_window win; |
@@ -454,9 +462,7 @@ struct saa7134_dev { | |||
454 | struct list_head devlist; | 462 | struct list_head devlist; |
455 | struct mutex lock; | 463 | struct mutex lock; |
456 | spinlock_t slock; | 464 | spinlock_t slock; |
457 | #ifdef VIDIOC_G_PRIORITY | ||
458 | struct v4l2_prio_state prio; | 465 | struct v4l2_prio_state prio; |
459 | #endif | ||
460 | /* workstruct for loading modules */ | 466 | /* workstruct for loading modules */ |
461 | struct work_struct request_module_wk; | 467 | struct work_struct request_module_wk; |
462 | 468 | ||
@@ -556,7 +562,9 @@ struct saa7134_dev { | |||
556 | #if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE) | 562 | #if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE) |
557 | /* SAA7134_MPEG_DVB only */ | 563 | /* SAA7134_MPEG_DVB only */ |
558 | struct videobuf_dvb dvb; | 564 | struct videobuf_dvb dvb; |
559 | int (*original_demod_sleep)(struct dvb_frontend* fe); | 565 | int (*original_demod_sleep)(struct dvb_frontend *fe); |
566 | int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); | ||
567 | int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg); | ||
560 | #endif | 568 | #endif |
561 | }; | 569 | }; |
562 | 570 | ||
@@ -594,7 +602,6 @@ extern int saa7134_no_overlay; | |||
594 | 602 | ||
595 | void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); | 603 | void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); |
596 | void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value); | 604 | void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value); |
597 | int saa7134_tuner_callback(void *ptr, int command, int arg); | ||
598 | 605 | ||
599 | #define SAA7134_PGTABLE_SIZE 4096 | 606 | #define SAA7134_PGTABLE_SIZE 4096 |
600 | 607 | ||
@@ -631,6 +638,7 @@ extern struct pci_device_id __devinitdata saa7134_pci_tbl[]; | |||
631 | 638 | ||
632 | extern int saa7134_board_init1(struct saa7134_dev *dev); | 639 | extern int saa7134_board_init1(struct saa7134_dev *dev); |
633 | extern int saa7134_board_init2(struct saa7134_dev *dev); | 640 | extern int saa7134_board_init2(struct saa7134_dev *dev); |
641 | int saa7134_tuner_callback(void *priv, int command, int arg); | ||
634 | 642 | ||
635 | 643 | ||
636 | /* ----------------------------------------------------------- */ | 644 | /* ----------------------------------------------------------- */ |
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c new file mode 100644 index 000000000000..53c5edbcf7ea --- /dev/null +++ b/drivers/media/video/saa717x.c | |||
@@ -0,0 +1,1516 @@ | |||
1 | /* | ||
2 | * saa717x - Philips SAA717xHL video decoder driver | ||
3 | * | ||
4 | * Based on the saa7115 driver | ||
5 | * | ||
6 | * Changes by Ohta Kyuma <alpha292@bremen.or.jp> | ||
7 | * - Apply to SAA717x,NEC uPD64031,uPD64083. (1/31/2004) | ||
8 | * | ||
9 | * Changes by T.Adachi (tadachi@tadachi-net.com) | ||
10 | * - support audio, video scaler etc, and checked the initialize sequence. | ||
11 | * | ||
12 | * Cleaned up by Hans Verkuil <hverkuil@xs4all.nl> | ||
13 | * | ||
14 | * Note: this is a reversed engineered driver based on captures from | ||
15 | * the I2C bus under Windows. This chip is very similar to the saa7134, | ||
16 | * though. Unfortunately, this driver is currently only working for NTSC. | ||
17 | * | ||
18 | * This program is free software; you can redistribute it and/or modify | ||
19 | * it under the terms of the GNU General Public License as published by | ||
20 | * the Free Software Foundation; either version 2 of the License, or | ||
21 | * (at your option) any later version. | ||
22 | * | ||
23 | * This program is distributed in the hope that it will be useful, | ||
24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
26 | * GNU General Public License for more details. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License | ||
29 | * along with this program; if not, write to the Free Software | ||
30 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
31 | */ | ||
32 | |||
33 | #include <linux/version.h> | ||
34 | #include <linux/module.h> | ||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/sched.h> | ||
37 | |||
38 | #include <linux/videodev.h> | ||
39 | #include <linux/videodev2.h> | ||
40 | #include <linux/i2c.h> | ||
41 | #include <media/v4l2-common.h> | ||
42 | #include <media/v4l2-i2c-drv.h> | ||
43 | |||
44 | MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver"); | ||
45 | MODULE_AUTHOR("K. Ohta, T. Adachi, Hans Verkuil"); | ||
46 | MODULE_LICENSE("GPL"); | ||
47 | |||
48 | static int debug; | ||
49 | module_param(debug, int, 0644); | ||
50 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | ||
51 | |||
52 | /* | ||
53 | * Generic i2c probe | ||
54 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
55 | */ | ||
56 | |||
57 | struct saa717x_state { | ||
58 | v4l2_std_id std; | ||
59 | int input; | ||
60 | int enable; | ||
61 | int radio; | ||
62 | int bright; | ||
63 | int contrast; | ||
64 | int hue; | ||
65 | int sat; | ||
66 | int playback; | ||
67 | int audio; | ||
68 | int tuner_audio_mode; | ||
69 | int audio_main_mute; | ||
70 | int audio_main_vol_r; | ||
71 | int audio_main_vol_l; | ||
72 | u16 audio_main_bass; | ||
73 | u16 audio_main_treble; | ||
74 | u16 audio_main_volume; | ||
75 | u16 audio_main_balance; | ||
76 | int audio_input; | ||
77 | }; | ||
78 | |||
79 | /* ----------------------------------------------------------------------- */ | ||
80 | |||
81 | /* for audio mode */ | ||
82 | #define TUNER_AUDIO_MONO 0 /* LL */ | ||
83 | #define TUNER_AUDIO_STEREO 1 /* LR */ | ||
84 | #define TUNER_AUDIO_LANG1 2 /* LL */ | ||
85 | #define TUNER_AUDIO_LANG2 3 /* RR */ | ||
86 | |||
87 | #define SAA717X_NTSC_WIDTH (704) | ||
88 | #define SAA717X_NTSC_HEIGHT (480) | ||
89 | |||
90 | /* ----------------------------------------------------------------------- */ | ||
91 | |||
92 | static int saa717x_write(struct i2c_client *client, u32 reg, u32 value) | ||
93 | { | ||
94 | struct i2c_adapter *adap = client->adapter; | ||
95 | int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488; | ||
96 | unsigned char mm1[6]; | ||
97 | struct i2c_msg msg; | ||
98 | |||
99 | msg.flags = 0; | ||
100 | msg.addr = client->addr; | ||
101 | mm1[0] = (reg >> 8) & 0xff; | ||
102 | mm1[1] = reg & 0xff; | ||
103 | |||
104 | if (fw_addr) { | ||
105 | mm1[4] = (value >> 16) & 0xff; | ||
106 | mm1[3] = (value >> 8) & 0xff; | ||
107 | mm1[2] = value & 0xff; | ||
108 | } else { | ||
109 | mm1[2] = value & 0xff; | ||
110 | } | ||
111 | msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */ | ||
112 | msg.buf = mm1; | ||
113 | v4l_dbg(2, debug, client, "wrote: reg 0x%03x=%08x\n", reg, value); | ||
114 | return i2c_transfer(adap, &msg, 1) == 1; | ||
115 | } | ||
116 | |||
117 | static void saa717x_write_regs(struct i2c_client *client, u32 *data) | ||
118 | { | ||
119 | while (data[0] || data[1]) { | ||
120 | saa717x_write(client, data[0], data[1]); | ||
121 | data += 2; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static u32 saa717x_read(struct i2c_client *client, u32 reg) | ||
126 | { | ||
127 | struct i2c_adapter *adap = client->adapter; | ||
128 | int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528; | ||
129 | unsigned char mm1[2]; | ||
130 | unsigned char mm2[4] = { 0, 0, 0, 0 }; | ||
131 | struct i2c_msg msgs[2]; | ||
132 | u32 value; | ||
133 | |||
134 | msgs[0].flags = 0; | ||
135 | msgs[1].flags = I2C_M_RD; | ||
136 | msgs[0].addr = msgs[1].addr = client->addr; | ||
137 | mm1[0] = (reg >> 8) & 0xff; | ||
138 | mm1[1] = reg & 0xff; | ||
139 | msgs[0].len = 2; | ||
140 | msgs[0].buf = mm1; | ||
141 | msgs[1].len = fw_addr ? 3 : 1; /* Multibyte Registers contains *only* 3 bytes */ | ||
142 | msgs[1].buf = mm2; | ||
143 | i2c_transfer(adap, msgs, 2); | ||
144 | |||
145 | if (fw_addr) | ||
146 | value = (mm2[2] & 0xff) | ((mm2[1] & 0xff) >> 8) | ((mm2[0] & 0xff) >> 16); | ||
147 | else | ||
148 | value = mm2[0] & 0xff; | ||
149 | |||
150 | v4l_dbg(2, debug, client, "read: reg 0x%03x=0x%08x\n", reg, value); | ||
151 | return value; | ||
152 | } | ||
153 | |||
154 | /* ----------------------------------------------------------------------- */ | ||
155 | |||
156 | static u32 reg_init_initialize[] = | ||
157 | { | ||
158 | /* from linux driver */ | ||
159 | 0x101, 0x008, /* Increment delay */ | ||
160 | |||
161 | 0x103, 0x000, /* Analog input control 2 */ | ||
162 | 0x104, 0x090, /* Analog input control 3 */ | ||
163 | 0x105, 0x090, /* Analog input control 4 */ | ||
164 | 0x106, 0x0eb, /* Horizontal sync start */ | ||
165 | 0x107, 0x0e0, /* Horizontal sync stop */ | ||
166 | 0x109, 0x055, /* Luminance control */ | ||
167 | |||
168 | 0x10f, 0x02a, /* Chroma gain control */ | ||
169 | 0x110, 0x000, /* Chroma control 2 */ | ||
170 | |||
171 | 0x114, 0x045, /* analog/ADC */ | ||
172 | |||
173 | 0x118, 0x040, /* RAW data gain */ | ||
174 | 0x119, 0x080, /* RAW data offset */ | ||
175 | |||
176 | 0x044, 0x000, /* VBI horizontal input window start (L) TASK A */ | ||
177 | 0x045, 0x000, /* VBI horizontal input window start (H) TASK A */ | ||
178 | 0x046, 0x0cf, /* VBI horizontal input window stop (L) TASK A */ | ||
179 | 0x047, 0x002, /* VBI horizontal input window stop (H) TASK A */ | ||
180 | |||
181 | 0x049, 0x000, /* VBI vertical input window start (H) TASK A */ | ||
182 | |||
183 | 0x04c, 0x0d0, /* VBI horizontal output length (L) TASK A */ | ||
184 | 0x04d, 0x002, /* VBI horizontal output length (H) TASK A */ | ||
185 | |||
186 | 0x064, 0x080, /* Lumina brightness TASK A */ | ||
187 | 0x065, 0x040, /* Luminance contrast TASK A */ | ||
188 | 0x066, 0x040, /* Chroma saturation TASK A */ | ||
189 | /* 067H: Reserved */ | ||
190 | 0x068, 0x000, /* VBI horizontal scaling increment (L) TASK A */ | ||
191 | 0x069, 0x004, /* VBI horizontal scaling increment (H) TASK A */ | ||
192 | 0x06a, 0x000, /* VBI phase offset TASK A */ | ||
193 | |||
194 | 0x06e, 0x000, /* Horizontal phase offset Luma TASK A */ | ||
195 | 0x06f, 0x000, /* Horizontal phase offset Chroma TASK A */ | ||
196 | |||
197 | 0x072, 0x000, /* Vertical filter mode TASK A */ | ||
198 | |||
199 | 0x084, 0x000, /* VBI horizontal input window start (L) TAKS B */ | ||
200 | 0x085, 0x000, /* VBI horizontal input window start (H) TAKS B */ | ||
201 | 0x086, 0x0cf, /* VBI horizontal input window stop (L) TAKS B */ | ||
202 | 0x087, 0x002, /* VBI horizontal input window stop (H) TAKS B */ | ||
203 | |||
204 | 0x089, 0x000, /* VBI vertical input window start (H) TAKS B */ | ||
205 | |||
206 | 0x08c, 0x0d0, /* VBI horizontal output length (L) TASK B */ | ||
207 | 0x08d, 0x002, /* VBI horizontal output length (H) TASK B */ | ||
208 | |||
209 | 0x0a4, 0x080, /* Lumina brightness TASK B */ | ||
210 | 0x0a5, 0x040, /* Luminance contrast TASK B */ | ||
211 | 0x0a6, 0x040, /* Chroma saturation TASK B */ | ||
212 | /* 0A7H reserved */ | ||
213 | 0x0a8, 0x000, /* VBI horizontal scaling increment (L) TASK B */ | ||
214 | 0x0a9, 0x004, /* VBI horizontal scaling increment (H) TASK B */ | ||
215 | 0x0aa, 0x000, /* VBI phase offset TASK B */ | ||
216 | |||
217 | 0x0ae, 0x000, /* Horizontal phase offset Luma TASK B */ | ||
218 | 0x0af, 0x000, /*Horizontal phase offset Chroma TASK B */ | ||
219 | |||
220 | 0x0b2, 0x000, /* Vertical filter mode TASK B */ | ||
221 | |||
222 | 0x00c, 0x000, /* Start point GREEN path */ | ||
223 | 0x00d, 0x000, /* Start point BLUE path */ | ||
224 | 0x00e, 0x000, /* Start point RED path */ | ||
225 | |||
226 | 0x010, 0x010, /* GREEN path gamma curve --- */ | ||
227 | 0x011, 0x020, | ||
228 | 0x012, 0x030, | ||
229 | 0x013, 0x040, | ||
230 | 0x014, 0x050, | ||
231 | 0x015, 0x060, | ||
232 | 0x016, 0x070, | ||
233 | 0x017, 0x080, | ||
234 | 0x018, 0x090, | ||
235 | 0x019, 0x0a0, | ||
236 | 0x01a, 0x0b0, | ||
237 | 0x01b, 0x0c0, | ||
238 | 0x01c, 0x0d0, | ||
239 | 0x01d, 0x0e0, | ||
240 | 0x01e, 0x0f0, | ||
241 | 0x01f, 0x0ff, /* --- GREEN path gamma curve */ | ||
242 | |||
243 | 0x020, 0x010, /* BLUE path gamma curve --- */ | ||
244 | 0x021, 0x020, | ||
245 | 0x022, 0x030, | ||
246 | 0x023, 0x040, | ||
247 | 0x024, 0x050, | ||
248 | 0x025, 0x060, | ||
249 | 0x026, 0x070, | ||
250 | 0x027, 0x080, | ||
251 | 0x028, 0x090, | ||
252 | 0x029, 0x0a0, | ||
253 | 0x02a, 0x0b0, | ||
254 | 0x02b, 0x0c0, | ||
255 | 0x02c, 0x0d0, | ||
256 | 0x02d, 0x0e0, | ||
257 | 0x02e, 0x0f0, | ||
258 | 0x02f, 0x0ff, /* --- BLUE path gamma curve */ | ||
259 | |||
260 | 0x030, 0x010, /* RED path gamma curve --- */ | ||
261 | 0x031, 0x020, | ||
262 | 0x032, 0x030, | ||
263 | 0x033, 0x040, | ||
264 | 0x034, 0x050, | ||
265 | 0x035, 0x060, | ||
266 | 0x036, 0x070, | ||
267 | 0x037, 0x080, | ||
268 | 0x038, 0x090, | ||
269 | 0x039, 0x0a0, | ||
270 | 0x03a, 0x0b0, | ||
271 | 0x03b, 0x0c0, | ||
272 | 0x03c, 0x0d0, | ||
273 | 0x03d, 0x0e0, | ||
274 | 0x03e, 0x0f0, | ||
275 | 0x03f, 0x0ff, /* --- RED path gamma curve */ | ||
276 | |||
277 | 0x109, 0x085, /* Luminance control */ | ||
278 | |||
279 | /**** from app start ****/ | ||
280 | 0x584, 0x000, /* AGC gain control */ | ||
281 | 0x585, 0x000, /* Program count */ | ||
282 | 0x586, 0x003, /* Status reset */ | ||
283 | 0x588, 0x0ff, /* Number of audio samples (L) */ | ||
284 | 0x589, 0x00f, /* Number of audio samples (M) */ | ||
285 | 0x58a, 0x000, /* Number of audio samples (H) */ | ||
286 | 0x58b, 0x000, /* Audio select */ | ||
287 | 0x58c, 0x010, /* Audio channel assign1 */ | ||
288 | 0x58d, 0x032, /* Audio channel assign2 */ | ||
289 | 0x58e, 0x054, /* Audio channel assign3 */ | ||
290 | 0x58f, 0x023, /* Audio format */ | ||
291 | 0x590, 0x000, /* SIF control */ | ||
292 | |||
293 | 0x595, 0x000, /* ?? */ | ||
294 | 0x596, 0x000, /* ?? */ | ||
295 | 0x597, 0x000, /* ?? */ | ||
296 | |||
297 | 0x464, 0x00, /* Digital input crossbar1 */ | ||
298 | |||
299 | 0x46c, 0xbbbb10, /* Digital output selection1-3 */ | ||
300 | 0x470, 0x101010, /* Digital output selection4-6 */ | ||
301 | |||
302 | 0x478, 0x00, /* Sound feature control */ | ||
303 | |||
304 | 0x474, 0x18, /* Softmute control */ | ||
305 | |||
306 | 0x454, 0x0425b9, /* Sound Easy programming(reset) */ | ||
307 | 0x454, 0x042539, /* Sound Easy programming(reset) */ | ||
308 | |||
309 | |||
310 | /**** common setting( of DVD play, including scaler commands) ****/ | ||
311 | 0x042, 0x003, /* Data path configuration for VBI (TASK A) */ | ||
312 | |||
313 | 0x082, 0x003, /* Data path configuration for VBI (TASK B) */ | ||
314 | |||
315 | 0x108, 0x0f8, /* Sync control */ | ||
316 | 0x2a9, 0x0fd, /* ??? */ | ||
317 | 0x102, 0x089, /* select video input "mode 9" */ | ||
318 | 0x111, 0x000, /* Mode/delay control */ | ||
319 | |||
320 | 0x10e, 0x00a, /* Chroma control 1 */ | ||
321 | |||
322 | 0x594, 0x002, /* SIF, analog I/O select */ | ||
323 | |||
324 | 0x454, 0x0425b9, /* Sound */ | ||
325 | 0x454, 0x042539, | ||
326 | |||
327 | 0x111, 0x000, | ||
328 | 0x10e, 0x00a, | ||
329 | 0x464, 0x000, | ||
330 | 0x300, 0x000, | ||
331 | 0x301, 0x006, | ||
332 | 0x302, 0x000, | ||
333 | 0x303, 0x006, | ||
334 | 0x308, 0x040, | ||
335 | 0x309, 0x000, | ||
336 | 0x30a, 0x000, | ||
337 | 0x30b, 0x000, | ||
338 | 0x000, 0x002, | ||
339 | 0x001, 0x000, | ||
340 | 0x002, 0x000, | ||
341 | 0x003, 0x000, | ||
342 | 0x004, 0x033, | ||
343 | 0x040, 0x01d, | ||
344 | 0x041, 0x001, | ||
345 | 0x042, 0x004, | ||
346 | 0x043, 0x000, | ||
347 | 0x080, 0x01e, | ||
348 | 0x081, 0x001, | ||
349 | 0x082, 0x004, | ||
350 | 0x083, 0x000, | ||
351 | 0x190, 0x018, | ||
352 | 0x115, 0x000, | ||
353 | 0x116, 0x012, | ||
354 | 0x117, 0x018, | ||
355 | 0x04a, 0x011, | ||
356 | 0x08a, 0x011, | ||
357 | 0x04b, 0x000, | ||
358 | 0x08b, 0x000, | ||
359 | 0x048, 0x000, | ||
360 | 0x088, 0x000, | ||
361 | 0x04e, 0x012, | ||
362 | 0x08e, 0x012, | ||
363 | 0x058, 0x012, | ||
364 | 0x098, 0x012, | ||
365 | 0x059, 0x000, | ||
366 | 0x099, 0x000, | ||
367 | 0x05a, 0x003, | ||
368 | 0x09a, 0x003, | ||
369 | 0x05b, 0x001, | ||
370 | 0x09b, 0x001, | ||
371 | 0x054, 0x008, | ||
372 | 0x094, 0x008, | ||
373 | 0x055, 0x000, | ||
374 | 0x095, 0x000, | ||
375 | 0x056, 0x0c7, | ||
376 | 0x096, 0x0c7, | ||
377 | 0x057, 0x002, | ||
378 | 0x097, 0x002, | ||
379 | 0x0ff, 0x0ff, | ||
380 | 0x060, 0x001, | ||
381 | 0x0a0, 0x001, | ||
382 | 0x061, 0x000, | ||
383 | 0x0a1, 0x000, | ||
384 | 0x062, 0x000, | ||
385 | 0x0a2, 0x000, | ||
386 | 0x063, 0x000, | ||
387 | 0x0a3, 0x000, | ||
388 | 0x070, 0x000, | ||
389 | 0x0b0, 0x000, | ||
390 | 0x071, 0x004, | ||
391 | 0x0b1, 0x004, | ||
392 | 0x06c, 0x0e9, | ||
393 | 0x0ac, 0x0e9, | ||
394 | 0x06d, 0x003, | ||
395 | 0x0ad, 0x003, | ||
396 | 0x05c, 0x0d0, | ||
397 | 0x09c, 0x0d0, | ||
398 | 0x05d, 0x002, | ||
399 | 0x09d, 0x002, | ||
400 | 0x05e, 0x0f2, | ||
401 | 0x09e, 0x0f2, | ||
402 | 0x05f, 0x000, | ||
403 | 0x09f, 0x000, | ||
404 | 0x074, 0x000, | ||
405 | 0x0b4, 0x000, | ||
406 | 0x075, 0x000, | ||
407 | 0x0b5, 0x000, | ||
408 | 0x076, 0x000, | ||
409 | 0x0b6, 0x000, | ||
410 | 0x077, 0x000, | ||
411 | 0x0b7, 0x000, | ||
412 | 0x195, 0x008, | ||
413 | 0x0ff, 0x0ff, | ||
414 | 0x108, 0x0f8, | ||
415 | 0x111, 0x000, | ||
416 | 0x10e, 0x00a, | ||
417 | 0x2a9, 0x0fd, | ||
418 | 0x464, 0x001, | ||
419 | 0x454, 0x042135, | ||
420 | 0x598, 0x0e7, | ||
421 | 0x599, 0x07d, | ||
422 | 0x59a, 0x018, | ||
423 | 0x59c, 0x066, | ||
424 | 0x59d, 0x090, | ||
425 | 0x59e, 0x001, | ||
426 | 0x584, 0x000, | ||
427 | 0x585, 0x000, | ||
428 | 0x586, 0x003, | ||
429 | 0x588, 0x0ff, | ||
430 | 0x589, 0x00f, | ||
431 | 0x58a, 0x000, | ||
432 | 0x58b, 0x000, | ||
433 | 0x58c, 0x010, | ||
434 | 0x58d, 0x032, | ||
435 | 0x58e, 0x054, | ||
436 | 0x58f, 0x023, | ||
437 | 0x590, 0x000, | ||
438 | 0x595, 0x000, | ||
439 | 0x596, 0x000, | ||
440 | 0x597, 0x000, | ||
441 | 0x464, 0x000, | ||
442 | 0x46c, 0xbbbb10, | ||
443 | 0x470, 0x101010, | ||
444 | |||
445 | |||
446 | 0x478, 0x000, | ||
447 | 0x474, 0x018, | ||
448 | 0x454, 0x042135, | ||
449 | 0x598, 0x0e7, | ||
450 | 0x599, 0x07d, | ||
451 | 0x59a, 0x018, | ||
452 | 0x59c, 0x066, | ||
453 | 0x59d, 0x090, | ||
454 | 0x59e, 0x001, | ||
455 | 0x584, 0x000, | ||
456 | 0x585, 0x000, | ||
457 | 0x586, 0x003, | ||
458 | 0x588, 0x0ff, | ||
459 | 0x589, 0x00f, | ||
460 | 0x58a, 0x000, | ||
461 | 0x58b, 0x000, | ||
462 | 0x58c, 0x010, | ||
463 | 0x58d, 0x032, | ||
464 | 0x58e, 0x054, | ||
465 | 0x58f, 0x023, | ||
466 | 0x590, 0x000, | ||
467 | 0x595, 0x000, | ||
468 | 0x596, 0x000, | ||
469 | 0x597, 0x000, | ||
470 | 0x464, 0x000, | ||
471 | 0x46c, 0xbbbb10, | ||
472 | 0x470, 0x101010, | ||
473 | |||
474 | 0x478, 0x000, | ||
475 | 0x474, 0x018, | ||
476 | 0x454, 0x042135, | ||
477 | 0x598, 0x0e7, | ||
478 | 0x599, 0x07d, | ||
479 | 0x59a, 0x018, | ||
480 | 0x59c, 0x066, | ||
481 | 0x59d, 0x090, | ||
482 | 0x59e, 0x001, | ||
483 | 0x584, 0x000, | ||
484 | 0x585, 0x000, | ||
485 | 0x586, 0x003, | ||
486 | 0x588, 0x0ff, | ||
487 | 0x589, 0x00f, | ||
488 | 0x58a, 0x000, | ||
489 | 0x58b, 0x000, | ||
490 | 0x58c, 0x010, | ||
491 | 0x58d, 0x032, | ||
492 | 0x58e, 0x054, | ||
493 | 0x58f, 0x023, | ||
494 | 0x590, 0x000, | ||
495 | 0x595, 0x000, | ||
496 | 0x596, 0x000, | ||
497 | 0x597, 0x000, | ||
498 | 0x464, 0x000, | ||
499 | 0x46c, 0xbbbb10, | ||
500 | 0x470, 0x101010, | ||
501 | 0x478, 0x000, | ||
502 | 0x474, 0x018, | ||
503 | 0x454, 0x042135, | ||
504 | 0x193, 0x000, | ||
505 | 0x300, 0x000, | ||
506 | 0x301, 0x006, | ||
507 | 0x302, 0x000, | ||
508 | 0x303, 0x006, | ||
509 | 0x308, 0x040, | ||
510 | 0x309, 0x000, | ||
511 | 0x30a, 0x000, | ||
512 | 0x30b, 0x000, | ||
513 | 0x000, 0x002, | ||
514 | 0x001, 0x000, | ||
515 | 0x002, 0x000, | ||
516 | 0x003, 0x000, | ||
517 | 0x004, 0x033, | ||
518 | 0x040, 0x01d, | ||
519 | 0x041, 0x001, | ||
520 | 0x042, 0x004, | ||
521 | 0x043, 0x000, | ||
522 | 0x080, 0x01e, | ||
523 | 0x081, 0x001, | ||
524 | 0x082, 0x004, | ||
525 | 0x083, 0x000, | ||
526 | 0x190, 0x018, | ||
527 | 0x115, 0x000, | ||
528 | 0x116, 0x012, | ||
529 | 0x117, 0x018, | ||
530 | 0x04a, 0x011, | ||
531 | 0x08a, 0x011, | ||
532 | 0x04b, 0x000, | ||
533 | 0x08b, 0x000, | ||
534 | 0x048, 0x000, | ||
535 | 0x088, 0x000, | ||
536 | 0x04e, 0x012, | ||
537 | 0x08e, 0x012, | ||
538 | 0x058, 0x012, | ||
539 | 0x098, 0x012, | ||
540 | 0x059, 0x000, | ||
541 | 0x099, 0x000, | ||
542 | 0x05a, 0x003, | ||
543 | 0x09a, 0x003, | ||
544 | 0x05b, 0x001, | ||
545 | 0x09b, 0x001, | ||
546 | 0x054, 0x008, | ||
547 | 0x094, 0x008, | ||
548 | 0x055, 0x000, | ||
549 | 0x095, 0x000, | ||
550 | 0x056, 0x0c7, | ||
551 | 0x096, 0x0c7, | ||
552 | 0x057, 0x002, | ||
553 | 0x097, 0x002, | ||
554 | 0x060, 0x001, | ||
555 | 0x0a0, 0x001, | ||
556 | 0x061, 0x000, | ||
557 | 0x0a1, 0x000, | ||
558 | 0x062, 0x000, | ||
559 | 0x0a2, 0x000, | ||
560 | 0x063, 0x000, | ||
561 | 0x0a3, 0x000, | ||
562 | 0x070, 0x000, | ||
563 | 0x0b0, 0x000, | ||
564 | 0x071, 0x004, | ||
565 | 0x0b1, 0x004, | ||
566 | 0x06c, 0x0e9, | ||
567 | 0x0ac, 0x0e9, | ||
568 | 0x06d, 0x003, | ||
569 | 0x0ad, 0x003, | ||
570 | 0x05c, 0x0d0, | ||
571 | 0x09c, 0x0d0, | ||
572 | 0x05d, 0x002, | ||
573 | 0x09d, 0x002, | ||
574 | 0x05e, 0x0f2, | ||
575 | 0x09e, 0x0f2, | ||
576 | 0x05f, 0x000, | ||
577 | 0x09f, 0x000, | ||
578 | 0x074, 0x000, | ||
579 | 0x0b4, 0x000, | ||
580 | 0x075, 0x000, | ||
581 | 0x0b5, 0x000, | ||
582 | 0x076, 0x000, | ||
583 | 0x0b6, 0x000, | ||
584 | 0x077, 0x000, | ||
585 | 0x0b7, 0x000, | ||
586 | 0x195, 0x008, | ||
587 | 0x598, 0x0e7, | ||
588 | 0x599, 0x07d, | ||
589 | 0x59a, 0x018, | ||
590 | 0x59c, 0x066, | ||
591 | 0x59d, 0x090, | ||
592 | 0x59e, 0x001, | ||
593 | 0x584, 0x000, | ||
594 | 0x585, 0x000, | ||
595 | 0x586, 0x003, | ||
596 | 0x588, 0x0ff, | ||
597 | 0x589, 0x00f, | ||
598 | 0x58a, 0x000, | ||
599 | 0x58b, 0x000, | ||
600 | 0x58c, 0x010, | ||
601 | 0x58d, 0x032, | ||
602 | 0x58e, 0x054, | ||
603 | 0x58f, 0x023, | ||
604 | 0x590, 0x000, | ||
605 | 0x595, 0x000, | ||
606 | 0x596, 0x000, | ||
607 | 0x597, 0x000, | ||
608 | 0x464, 0x000, | ||
609 | 0x46c, 0xbbbb10, | ||
610 | 0x470, 0x101010, | ||
611 | 0x478, 0x000, | ||
612 | 0x474, 0x018, | ||
613 | 0x454, 0x042135, | ||
614 | 0x193, 0x0a6, | ||
615 | 0x108, 0x0f8, | ||
616 | 0x042, 0x003, | ||
617 | 0x082, 0x003, | ||
618 | 0x454, 0x0425b9, | ||
619 | 0x454, 0x042539, | ||
620 | 0x193, 0x000, | ||
621 | 0x193, 0x0a6, | ||
622 | 0x464, 0x000, | ||
623 | |||
624 | 0, 0 | ||
625 | }; | ||
626 | |||
627 | /* Tuner */ | ||
628 | static u32 reg_init_tuner_input[] = { | ||
629 | 0x108, 0x0f8, /* Sync control */ | ||
630 | 0x111, 0x000, /* Mode/delay control */ | ||
631 | 0x10e, 0x00a, /* Chroma control 1 */ | ||
632 | 0, 0 | ||
633 | }; | ||
634 | |||
635 | /* Composite */ | ||
636 | static u32 reg_init_composite_input[] = { | ||
637 | 0x108, 0x0e8, /* Sync control */ | ||
638 | 0x111, 0x000, /* Mode/delay control */ | ||
639 | 0x10e, 0x04a, /* Chroma control 1 */ | ||
640 | 0, 0 | ||
641 | }; | ||
642 | |||
643 | /* S-Video */ | ||
644 | static u32 reg_init_svideo_input[] = { | ||
645 | 0x108, 0x0e8, /* Sync control */ | ||
646 | 0x111, 0x000, /* Mode/delay control */ | ||
647 | 0x10e, 0x04a, /* Chroma control 1 */ | ||
648 | 0, 0 | ||
649 | }; | ||
650 | |||
651 | static u32 reg_set_audio_template[4][2] = | ||
652 | { | ||
653 | { /* for MONO | ||
654 | tadachi 6/29 DMA audio output select? | ||
655 | Register 0x46c | ||
656 | 7-4: DMA2, 3-0: DMA1 ch. DMA4, DMA3 DMA2, DMA1 | ||
657 | 0: MAIN left, 1: MAIN right | ||
658 | 2: AUX1 left, 3: AUX1 right | ||
659 | 4: AUX2 left, 5: AUX2 right | ||
660 | 6: DPL left, 7: DPL right | ||
661 | 8: DPL center, 9: DPL surround | ||
662 | A: monitor output, B: digital sense */ | ||
663 | 0xbbbb00, | ||
664 | |||
665 | /* tadachi 6/29 DAC and I2S output select? | ||
666 | Register 0x470 | ||
667 | 7-4:DAC right ch. 3-0:DAC left ch. | ||
668 | I2S1 right,left I2S2 right,left */ | ||
669 | 0x00, | ||
670 | }, | ||
671 | { /* for STEREO */ | ||
672 | 0xbbbb10, 0x101010, | ||
673 | }, | ||
674 | { /* for LANG1 */ | ||
675 | 0xbbbb00, 0x00, | ||
676 | }, | ||
677 | { /* for LANG2/SAP */ | ||
678 | 0xbbbb11, 0x111111, | ||
679 | } | ||
680 | }; | ||
681 | |||
682 | |||
683 | /* Get detected audio flags (from saa7134 driver) */ | ||
684 | static void get_inf_dev_status(struct i2c_client *client, | ||
685 | int *dual_flag, int *stereo_flag) | ||
686 | { | ||
687 | u32 reg_data3; | ||
688 | |||
689 | static char *stdres[0x20] = { | ||
690 | [0x00] = "no standard detected", | ||
691 | [0x01] = "B/G (in progress)", | ||
692 | [0x02] = "D/K (in progress)", | ||
693 | [0x03] = "M (in progress)", | ||
694 | |||
695 | [0x04] = "B/G A2", | ||
696 | [0x05] = "B/G NICAM", | ||
697 | [0x06] = "D/K A2 (1)", | ||
698 | [0x07] = "D/K A2 (2)", | ||
699 | [0x08] = "D/K A2 (3)", | ||
700 | [0x09] = "D/K NICAM", | ||
701 | [0x0a] = "L NICAM", | ||
702 | [0x0b] = "I NICAM", | ||
703 | |||
704 | [0x0c] = "M Korea", | ||
705 | [0x0d] = "M BTSC ", | ||
706 | [0x0e] = "M EIAJ", | ||
707 | |||
708 | [0x0f] = "FM radio / IF 10.7 / 50 deemp", | ||
709 | [0x10] = "FM radio / IF 10.7 / 75 deemp", | ||
710 | [0x11] = "FM radio / IF sel / 50 deemp", | ||
711 | [0x12] = "FM radio / IF sel / 75 deemp", | ||
712 | |||
713 | [0x13 ... 0x1e] = "unknown", | ||
714 | [0x1f] = "??? [in progress]", | ||
715 | }; | ||
716 | |||
717 | |||
718 | *dual_flag = *stereo_flag = 0; | ||
719 | |||
720 | /* (demdec status: 0x528) */ | ||
721 | |||
722 | /* read current status */ | ||
723 | reg_data3 = saa717x_read(client, 0x0528); | ||
724 | |||
725 | v4l_dbg(1, debug, client, "tvaudio thread status: 0x%x [%s%s%s]\n", | ||
726 | reg_data3, stdres[reg_data3 & 0x1f], | ||
727 | (reg_data3 & 0x000020) ? ",stereo" : "", | ||
728 | (reg_data3 & 0x000040) ? ",dual" : ""); | ||
729 | v4l_dbg(1, debug, client, "detailed status: " | ||
730 | "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n", | ||
731 | (reg_data3 & 0x000080) ? " A2/EIAJ pilot tone " : "", | ||
732 | (reg_data3 & 0x000100) ? " A2/EIAJ dual " : "", | ||
733 | (reg_data3 & 0x000200) ? " A2/EIAJ stereo " : "", | ||
734 | (reg_data3 & 0x000400) ? " A2/EIAJ noise mute " : "", | ||
735 | |||
736 | (reg_data3 & 0x000800) ? " BTSC/FM radio pilot " : "", | ||
737 | (reg_data3 & 0x001000) ? " SAP carrier " : "", | ||
738 | (reg_data3 & 0x002000) ? " BTSC stereo noise mute " : "", | ||
739 | (reg_data3 & 0x004000) ? " SAP noise mute " : "", | ||
740 | (reg_data3 & 0x008000) ? " VDSP " : "", | ||
741 | |||
742 | (reg_data3 & 0x010000) ? " NICST " : "", | ||
743 | (reg_data3 & 0x020000) ? " NICDU " : "", | ||
744 | (reg_data3 & 0x040000) ? " NICAM muted " : "", | ||
745 | (reg_data3 & 0x080000) ? " NICAM reserve sound " : "", | ||
746 | |||
747 | (reg_data3 & 0x100000) ? " init done " : ""); | ||
748 | |||
749 | if (reg_data3 & 0x000220) { | ||
750 | v4l_dbg(1, debug, client, "ST!!!\n"); | ||
751 | *stereo_flag = 1; | ||
752 | } | ||
753 | |||
754 | if (reg_data3 & 0x000140) { | ||
755 | v4l_dbg(1, debug, client, "DUAL!!!\n"); | ||
756 | *dual_flag = 1; | ||
757 | } | ||
758 | } | ||
759 | |||
760 | /* regs write to set audio mode */ | ||
761 | static void set_audio_mode(struct i2c_client *client, int audio_mode) | ||
762 | { | ||
763 | v4l_dbg(1, debug, client, "writing registers to set audio mode by set %d\n", | ||
764 | audio_mode); | ||
765 | |||
766 | saa717x_write(client, 0x46c, reg_set_audio_template[audio_mode][0]); | ||
767 | saa717x_write(client, 0x470, reg_set_audio_template[audio_mode][1]); | ||
768 | } | ||
769 | |||
770 | /* write regs to video output level (bright,contrast,hue,sat) */ | ||
771 | static void set_video_output_level_regs(struct i2c_client *client, | ||
772 | struct saa717x_state *decoder) | ||
773 | { | ||
774 | /* brightness ffh (bright) - 80h (ITU level) - 00h (dark) */ | ||
775 | saa717x_write(client, 0x10a, decoder->bright); | ||
776 | |||
777 | /* contrast 7fh (max: 1.984) - 44h (ITU) - 40h (1.0) - | ||
778 | 0h (luminance off) 40: i2c dump | ||
779 | c0h (-1.0 inverse chrominance) | ||
780 | 80h (-2.0 inverse chrominance) */ | ||
781 | saa717x_write(client, 0x10b, decoder->contrast); | ||
782 | |||
783 | /* saturation? 7fh(max)-40h(ITU)-0h(color off) | ||
784 | c0h (-1.0 inverse chrominance) | ||
785 | 80h (-2.0 inverse chrominance) */ | ||
786 | saa717x_write(client, 0x10c, decoder->sat); | ||
787 | |||
788 | /* color hue (phase) control | ||
789 | 7fh (+178.6) - 0h (0 normal) - 80h (-180.0) */ | ||
790 | saa717x_write(client, 0x10d, decoder->hue); | ||
791 | } | ||
792 | |||
793 | /* write regs to set audio volume, bass and treble */ | ||
794 | static int set_audio_regs(struct i2c_client *client, | ||
795 | struct saa717x_state *decoder) | ||
796 | { | ||
797 | u8 mute = 0xac; /* -84 dB */ | ||
798 | u32 val; | ||
799 | unsigned int work_l, work_r; | ||
800 | |||
801 | /* set SIF analog I/O select */ | ||
802 | saa717x_write(client, 0x0594, decoder->audio_input); | ||
803 | v4l_dbg(1, debug, client, "set audio input %d\n", | ||
804 | decoder->audio_input); | ||
805 | |||
806 | /* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */ | ||
807 | work_l = (min(65536 - decoder->audio_main_balance, 32768) * decoder->audio_main_volume) / 32768; | ||
808 | work_r = (min(decoder->audio_main_balance, (u16)32768) * decoder->audio_main_volume) / 32768; | ||
809 | decoder->audio_main_vol_l = (long)work_l * (24 - (-40)) / 65535 - 40; | ||
810 | decoder->audio_main_vol_r = (long)work_r * (24 - (-40)) / 65535 - 40; | ||
811 | |||
812 | /* set main volume */ | ||
813 | /* main volume L[7-0],R[7-0],0x00 24=24dB,-83dB, -84(mute) */ | ||
814 | /* def:0dB->6dB(MPG600GR) */ | ||
815 | /* if mute is on, set mute */ | ||
816 | if (decoder->audio_main_mute) { | ||
817 | val = mute | (mute << 8); | ||
818 | } else { | ||
819 | val = (u8)decoder->audio_main_vol_l | | ||
820 | ((u8)decoder->audio_main_vol_r << 8); | ||
821 | } | ||
822 | |||
823 | saa717x_write(client, 0x480, val); | ||
824 | |||
825 | /* bass and treble; go to another function */ | ||
826 | /* set bass and treble */ | ||
827 | val = decoder->audio_main_bass | (decoder->audio_main_treble << 8); | ||
828 | saa717x_write(client, 0x488, val); | ||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | /********** scaling staff ***********/ | ||
833 | static void set_h_prescale(struct i2c_client *client, | ||
834 | int task, int prescale) | ||
835 | { | ||
836 | static const struct { | ||
837 | int xpsc; | ||
838 | int xacl; | ||
839 | int xc2_1; | ||
840 | int xdcg; | ||
841 | int vpfy; | ||
842 | } vals[] = { | ||
843 | /* XPSC XACL XC2_1 XDCG VPFY */ | ||
844 | { 1, 0, 0, 0, 0 }, | ||
845 | { 2, 2, 1, 2, 2 }, | ||
846 | { 3, 4, 1, 3, 2 }, | ||
847 | { 4, 8, 1, 4, 2 }, | ||
848 | { 5, 8, 1, 4, 2 }, | ||
849 | { 6, 8, 1, 4, 3 }, | ||
850 | { 7, 8, 1, 4, 3 }, | ||
851 | { 8, 15, 0, 4, 3 }, | ||
852 | { 9, 15, 0, 4, 3 }, | ||
853 | { 10, 16, 1, 5, 3 }, | ||
854 | }; | ||
855 | static const int count = ARRAY_SIZE(vals); | ||
856 | int i, task_shift; | ||
857 | |||
858 | task_shift = task * 0x40; | ||
859 | for (i = 0; i < count; i++) | ||
860 | if (vals[i].xpsc == prescale) | ||
861 | break; | ||
862 | if (i == count) | ||
863 | return; | ||
864 | |||
865 | /* horizonal prescaling */ | ||
866 | saa717x_write(client, 0x60 + task_shift, vals[i].xpsc); | ||
867 | /* accumulation length */ | ||
868 | saa717x_write(client, 0x61 + task_shift, vals[i].xacl); | ||
869 | /* level control */ | ||
870 | saa717x_write(client, 0x62 + task_shift, | ||
871 | (vals[i].xc2_1 << 3) | vals[i].xdcg); | ||
872 | /*FIR prefilter control */ | ||
873 | saa717x_write(client, 0x63 + task_shift, | ||
874 | (vals[i].vpfy << 2) | vals[i].vpfy); | ||
875 | } | ||
876 | |||
877 | /********** scaling staff ***********/ | ||
878 | static void set_v_scale(struct i2c_client *client, int task, int yscale) | ||
879 | { | ||
880 | int task_shift; | ||
881 | |||
882 | task_shift = task * 0x40; | ||
883 | /* Vertical scaling ratio (LOW) */ | ||
884 | saa717x_write(client, 0x70 + task_shift, yscale & 0xff); | ||
885 | /* Vertical scaling ratio (HI) */ | ||
886 | saa717x_write(client, 0x71 + task_shift, yscale >> 8); | ||
887 | } | ||
888 | |||
889 | static int saa717x_set_audio_clock_freq(struct i2c_client *client, u32 freq) | ||
890 | { | ||
891 | /* not yet implament, so saa717x_cfg_??hz_??_audio is not defined. */ | ||
892 | return 0; | ||
893 | } | ||
894 | |||
895 | static int saa717x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | ||
896 | { | ||
897 | struct saa717x_state *state = i2c_get_clientdata(client); | ||
898 | |||
899 | switch (ctrl->id) { | ||
900 | case V4L2_CID_BRIGHTNESS: | ||
901 | if (ctrl->value < 0 || ctrl->value > 255) { | ||
902 | v4l_err(client, "invalid brightness setting %d\n", ctrl->value); | ||
903 | return -ERANGE; | ||
904 | } | ||
905 | |||
906 | state->bright = ctrl->value; | ||
907 | v4l_dbg(1, debug, client, "bright:%d\n", state->bright); | ||
908 | saa717x_write(client, 0x10a, state->bright); | ||
909 | break; | ||
910 | |||
911 | case V4L2_CID_CONTRAST: | ||
912 | if (ctrl->value < 0 || ctrl->value > 127) { | ||
913 | v4l_err(client, "invalid contrast setting %d\n", ctrl->value); | ||
914 | return -ERANGE; | ||
915 | } | ||
916 | |||
917 | state->contrast = ctrl->value; | ||
918 | v4l_dbg(1, debug, client, "contrast:%d\n", state->contrast); | ||
919 | saa717x_write(client, 0x10b, state->contrast); | ||
920 | break; | ||
921 | |||
922 | case V4L2_CID_SATURATION: | ||
923 | if (ctrl->value < 0 || ctrl->value > 127) { | ||
924 | v4l_err(client, "invalid saturation setting %d\n", ctrl->value); | ||
925 | return -ERANGE; | ||
926 | } | ||
927 | |||
928 | state->sat = ctrl->value; | ||
929 | v4l_dbg(1, debug, client, "sat:%d\n", state->sat); | ||
930 | saa717x_write(client, 0x10c, state->sat); | ||
931 | break; | ||
932 | |||
933 | case V4L2_CID_HUE: | ||
934 | if (ctrl->value < -127 || ctrl->value > 127) { | ||
935 | v4l_err(client, "invalid hue setting %d\n", ctrl->value); | ||
936 | return -ERANGE; | ||
937 | } | ||
938 | |||
939 | state->hue = ctrl->value; | ||
940 | v4l_dbg(1, debug, client, "hue:%d\n", state->hue); | ||
941 | saa717x_write(client, 0x10d, state->hue); | ||
942 | break; | ||
943 | |||
944 | case V4L2_CID_AUDIO_MUTE: | ||
945 | state->audio_main_mute = ctrl->value; | ||
946 | set_audio_regs(client, state); | ||
947 | break; | ||
948 | |||
949 | case V4L2_CID_AUDIO_VOLUME: | ||
950 | state->audio_main_volume = ctrl->value; | ||
951 | set_audio_regs(client, state); | ||
952 | break; | ||
953 | |||
954 | case V4L2_CID_AUDIO_BALANCE: | ||
955 | state->audio_main_balance = ctrl->value; | ||
956 | set_audio_regs(client, state); | ||
957 | break; | ||
958 | |||
959 | case V4L2_CID_AUDIO_TREBLE: | ||
960 | state->audio_main_treble = ctrl->value; | ||
961 | set_audio_regs(client, state); | ||
962 | break; | ||
963 | |||
964 | case V4L2_CID_AUDIO_BASS: | ||
965 | state->audio_main_bass = ctrl->value; | ||
966 | set_audio_regs(client, state); | ||
967 | break; | ||
968 | |||
969 | default: | ||
970 | return -EINVAL; | ||
971 | } | ||
972 | |||
973 | return 0; | ||
974 | } | ||
975 | |||
976 | static int saa717x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | ||
977 | { | ||
978 | struct saa717x_state *state = i2c_get_clientdata(client); | ||
979 | |||
980 | switch (ctrl->id) { | ||
981 | case V4L2_CID_BRIGHTNESS: | ||
982 | ctrl->value = state->bright; | ||
983 | break; | ||
984 | |||
985 | case V4L2_CID_CONTRAST: | ||
986 | ctrl->value = state->contrast; | ||
987 | break; | ||
988 | |||
989 | case V4L2_CID_SATURATION: | ||
990 | ctrl->value = state->sat; | ||
991 | break; | ||
992 | |||
993 | case V4L2_CID_HUE: | ||
994 | ctrl->value = state->hue; | ||
995 | break; | ||
996 | |||
997 | case V4L2_CID_AUDIO_MUTE: | ||
998 | ctrl->value = state->audio_main_mute; | ||
999 | break; | ||
1000 | |||
1001 | case V4L2_CID_AUDIO_VOLUME: | ||
1002 | ctrl->value = state->audio_main_volume; | ||
1003 | break; | ||
1004 | |||
1005 | case V4L2_CID_AUDIO_BALANCE: | ||
1006 | ctrl->value = state->audio_main_balance; | ||
1007 | break; | ||
1008 | |||
1009 | case V4L2_CID_AUDIO_TREBLE: | ||
1010 | ctrl->value = state->audio_main_treble; | ||
1011 | break; | ||
1012 | |||
1013 | case V4L2_CID_AUDIO_BASS: | ||
1014 | ctrl->value = state->audio_main_bass; | ||
1015 | break; | ||
1016 | |||
1017 | default: | ||
1018 | return -EINVAL; | ||
1019 | } | ||
1020 | |||
1021 | return 0; | ||
1022 | } | ||
1023 | |||
1024 | static struct v4l2_queryctrl saa717x_qctrl[] = { | ||
1025 | { | ||
1026 | .id = V4L2_CID_BRIGHTNESS, | ||
1027 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1028 | .name = "Brightness", | ||
1029 | .minimum = 0, | ||
1030 | .maximum = 255, | ||
1031 | .step = 1, | ||
1032 | .default_value = 128, | ||
1033 | .flags = 0, | ||
1034 | }, { | ||
1035 | .id = V4L2_CID_CONTRAST, | ||
1036 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1037 | .name = "Contrast", | ||
1038 | .minimum = 0, | ||
1039 | .maximum = 255, | ||
1040 | .step = 1, | ||
1041 | .default_value = 64, | ||
1042 | .flags = 0, | ||
1043 | }, { | ||
1044 | .id = V4L2_CID_SATURATION, | ||
1045 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1046 | .name = "Saturation", | ||
1047 | .minimum = 0, | ||
1048 | .maximum = 255, | ||
1049 | .step = 1, | ||
1050 | .default_value = 64, | ||
1051 | .flags = 0, | ||
1052 | }, { | ||
1053 | .id = V4L2_CID_HUE, | ||
1054 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1055 | .name = "Hue", | ||
1056 | .minimum = -128, | ||
1057 | .maximum = 127, | ||
1058 | .step = 1, | ||
1059 | .default_value = 0, | ||
1060 | .flags = 0, | ||
1061 | }, { | ||
1062 | .id = V4L2_CID_AUDIO_VOLUME, | ||
1063 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1064 | .name = "Volume", | ||
1065 | .minimum = 0, | ||
1066 | .maximum = 65535, | ||
1067 | .step = 65535 / 100, | ||
1068 | .default_value = 58880, | ||
1069 | .flags = 0, | ||
1070 | }, { | ||
1071 | .id = V4L2_CID_AUDIO_BALANCE, | ||
1072 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1073 | .name = "Balance", | ||
1074 | .minimum = 0, | ||
1075 | .maximum = 65535, | ||
1076 | .step = 65535 / 100, | ||
1077 | .default_value = 32768, | ||
1078 | .flags = 0, | ||
1079 | }, { | ||
1080 | .id = V4L2_CID_AUDIO_MUTE, | ||
1081 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1082 | .name = "Mute", | ||
1083 | .minimum = 0, | ||
1084 | .maximum = 1, | ||
1085 | .step = 1, | ||
1086 | .default_value = 1, | ||
1087 | .flags = 0, | ||
1088 | }, { | ||
1089 | .id = V4L2_CID_AUDIO_BASS, | ||
1090 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1091 | .name = "Bass", | ||
1092 | .minimum = 0, | ||
1093 | .maximum = 65535, | ||
1094 | .step = 65535 / 100, | ||
1095 | .default_value = 32768, | ||
1096 | }, { | ||
1097 | .id = V4L2_CID_AUDIO_TREBLE, | ||
1098 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1099 | .name = "Treble", | ||
1100 | .minimum = 0, | ||
1101 | .maximum = 65535, | ||
1102 | .step = 65535 / 100, | ||
1103 | .default_value = 32768, | ||
1104 | }, | ||
1105 | }; | ||
1106 | |||
1107 | static int saa717x_set_video_input(struct i2c_client *client, struct saa717x_state *decoder, int inp) | ||
1108 | { | ||
1109 | int is_tuner = inp & 0x80; /* tuner input flag */ | ||
1110 | |||
1111 | inp &= 0x7f; | ||
1112 | |||
1113 | v4l_dbg(1, debug, client, "decoder set input (%d)\n", inp); | ||
1114 | /* inputs from 0-9 are available*/ | ||
1115 | /* saa717x have mode0-mode9 but mode5 is reserved. */ | ||
1116 | if (inp < 0 || inp > 9 || inp == 5) | ||
1117 | return -EINVAL; | ||
1118 | |||
1119 | if (decoder->input != inp) { | ||
1120 | int input_line = inp; | ||
1121 | |||
1122 | decoder->input = input_line; | ||
1123 | v4l_dbg(1, debug, client, "now setting %s input %d\n", | ||
1124 | input_line >= 6 ? "S-Video" : "Composite", | ||
1125 | input_line); | ||
1126 | |||
1127 | /* select mode */ | ||
1128 | saa717x_write(client, 0x102, | ||
1129 | (saa717x_read(client, 0x102) & 0xf0) | | ||
1130 | input_line); | ||
1131 | |||
1132 | /* bypass chrominance trap for modes 6..9 */ | ||
1133 | saa717x_write(client, 0x109, | ||
1134 | (saa717x_read(client, 0x109) & 0x7f) | | ||
1135 | (input_line < 6 ? 0x0 : 0x80)); | ||
1136 | |||
1137 | /* change audio_mode */ | ||
1138 | if (is_tuner) { | ||
1139 | /* tuner */ | ||
1140 | set_audio_mode(client, decoder->tuner_audio_mode); | ||
1141 | } else { | ||
1142 | /* Force to STEREO mode if Composite or | ||
1143 | * S-Video were chosen */ | ||
1144 | set_audio_mode(client, TUNER_AUDIO_STEREO); | ||
1145 | } | ||
1146 | /* change initialize procedure (Composite/S-Video) */ | ||
1147 | if (is_tuner) | ||
1148 | saa717x_write_regs(client, reg_init_tuner_input); | ||
1149 | else if (input_line >= 6) | ||
1150 | saa717x_write_regs(client, reg_init_svideo_input); | ||
1151 | else | ||
1152 | saa717x_write_regs(client, reg_init_composite_input); | ||
1153 | } | ||
1154 | |||
1155 | return 0; | ||
1156 | } | ||
1157 | |||
1158 | static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg) | ||
1159 | { | ||
1160 | struct saa717x_state *decoder = i2c_get_clientdata(client); | ||
1161 | |||
1162 | v4l_dbg(1, debug, client, "IOCTL: %08x\n", cmd); | ||
1163 | |||
1164 | switch (cmd) { | ||
1165 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | ||
1166 | return saa717x_set_audio_clock_freq(client, *(u32 *)arg); | ||
1167 | |||
1168 | case VIDIOC_G_CTRL: | ||
1169 | return saa717x_get_v4lctrl(client, (struct v4l2_control *)arg); | ||
1170 | |||
1171 | case VIDIOC_S_CTRL: | ||
1172 | return saa717x_set_v4lctrl(client, (struct v4l2_control *)arg); | ||
1173 | |||
1174 | case VIDIOC_QUERYCTRL: { | ||
1175 | struct v4l2_queryctrl *qc = arg; | ||
1176 | int i; | ||
1177 | |||
1178 | for (i = 0; i < ARRAY_SIZE(saa717x_qctrl); i++) | ||
1179 | if (qc->id && qc->id == saa717x_qctrl[i].id) { | ||
1180 | memcpy(qc, &saa717x_qctrl[i], sizeof(*qc)); | ||
1181 | return 0; | ||
1182 | } | ||
1183 | return -EINVAL; | ||
1184 | } | ||
1185 | |||
1186 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1187 | case VIDIOC_DBG_G_REGISTER: { | ||
1188 | struct v4l2_register *reg = arg; | ||
1189 | |||
1190 | if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) | ||
1191 | return -EINVAL; | ||
1192 | if (!capable(CAP_SYS_ADMIN)) | ||
1193 | return -EPERM; | ||
1194 | reg->val = saa717x_read(client, reg->reg); | ||
1195 | break; | ||
1196 | } | ||
1197 | |||
1198 | case VIDIOC_DBG_S_REGISTER: { | ||
1199 | struct v4l2_register *reg = arg; | ||
1200 | u16 addr = reg->reg & 0xffff; | ||
1201 | u8 val = reg->val & 0xff; | ||
1202 | |||
1203 | if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) | ||
1204 | return -EINVAL; | ||
1205 | if (!capable(CAP_SYS_ADMIN)) | ||
1206 | return -EPERM; | ||
1207 | saa717x_write(client, addr, val); | ||
1208 | break; | ||
1209 | } | ||
1210 | #endif | ||
1211 | |||
1212 | case VIDIOC_S_FMT: { | ||
1213 | struct v4l2_format *fmt = (struct v4l2_format *)arg; | ||
1214 | struct v4l2_pix_format *pix; | ||
1215 | int prescale, h_scale, v_scale; | ||
1216 | |||
1217 | pix = &fmt->fmt.pix; | ||
1218 | v4l_dbg(1, debug, client, "decoder set size\n"); | ||
1219 | |||
1220 | /* FIXME need better bounds checking here */ | ||
1221 | if (pix->width < 1 || pix->width > 1440) | ||
1222 | return -EINVAL; | ||
1223 | if (pix->height < 1 || pix->height > 960) | ||
1224 | return -EINVAL; | ||
1225 | |||
1226 | /* scaling setting */ | ||
1227 | /* NTSC and interlace only */ | ||
1228 | prescale = SAA717X_NTSC_WIDTH / pix->width; | ||
1229 | if (prescale == 0) | ||
1230 | prescale = 1; | ||
1231 | h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / pix->width; | ||
1232 | /* interlace */ | ||
1233 | v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / pix->height; | ||
1234 | |||
1235 | /* Horizontal prescaling etc */ | ||
1236 | set_h_prescale(client, 0, prescale); | ||
1237 | set_h_prescale(client, 1, prescale); | ||
1238 | |||
1239 | /* Horizontal scaling increment */ | ||
1240 | /* TASK A */ | ||
1241 | saa717x_write(client, 0x6C, (u8)(h_scale & 0xFF)); | ||
1242 | saa717x_write(client, 0x6D, (u8)((h_scale >> 8) & 0xFF)); | ||
1243 | /* TASK B */ | ||
1244 | saa717x_write(client, 0xAC, (u8)(h_scale & 0xFF)); | ||
1245 | saa717x_write(client, 0xAD, (u8)((h_scale >> 8) & 0xFF)); | ||
1246 | |||
1247 | /* Vertical prescaling etc */ | ||
1248 | set_v_scale(client, 0, v_scale); | ||
1249 | set_v_scale(client, 1, v_scale); | ||
1250 | |||
1251 | /* set video output size */ | ||
1252 | /* video number of pixels at output */ | ||
1253 | /* TASK A */ | ||
1254 | saa717x_write(client, 0x5C, (u8)(pix->width & 0xFF)); | ||
1255 | saa717x_write(client, 0x5D, (u8)((pix->width >> 8) & 0xFF)); | ||
1256 | /* TASK B */ | ||
1257 | saa717x_write(client, 0x9C, (u8)(pix->width & 0xFF)); | ||
1258 | saa717x_write(client, 0x9D, (u8)((pix->width >> 8) & 0xFF)); | ||
1259 | |||
1260 | /* video number of lines at output */ | ||
1261 | /* TASK A */ | ||
1262 | saa717x_write(client, 0x5E, (u8)(pix->height & 0xFF)); | ||
1263 | saa717x_write(client, 0x5F, (u8)((pix->height >> 8) & 0xFF)); | ||
1264 | /* TASK B */ | ||
1265 | saa717x_write(client, 0x9E, (u8)(pix->height & 0xFF)); | ||
1266 | saa717x_write(client, 0x9F, (u8)((pix->height >> 8) & 0xFF)); | ||
1267 | break; | ||
1268 | } | ||
1269 | |||
1270 | case AUDC_SET_RADIO: | ||
1271 | decoder->radio = 1; | ||
1272 | break; | ||
1273 | |||
1274 | case VIDIOC_S_STD: { | ||
1275 | v4l2_std_id std = *(v4l2_std_id *) arg; | ||
1276 | |||
1277 | v4l_dbg(1, debug, client, "decoder set norm "); | ||
1278 | v4l_dbg(1, debug, client, "(not yet implementd)\n"); | ||
1279 | |||
1280 | decoder->radio = 0; | ||
1281 | decoder->std = std; | ||
1282 | break; | ||
1283 | } | ||
1284 | |||
1285 | case VIDIOC_INT_G_AUDIO_ROUTING: { | ||
1286 | struct v4l2_routing *route = arg; | ||
1287 | |||
1288 | route->input = decoder->audio_input; | ||
1289 | route->output = 0; | ||
1290 | break; | ||
1291 | } | ||
1292 | |||
1293 | case VIDIOC_INT_S_AUDIO_ROUTING: { | ||
1294 | struct v4l2_routing *route = arg; | ||
1295 | |||
1296 | if (route->input < 3) { /* FIXME! --tadachi */ | ||
1297 | decoder->audio_input = route->input; | ||
1298 | v4l_dbg(1, debug, client, | ||
1299 | "set decoder audio input to %d\n", | ||
1300 | decoder->audio_input); | ||
1301 | set_audio_regs(client, decoder); | ||
1302 | break; | ||
1303 | } | ||
1304 | return -ERANGE; | ||
1305 | } | ||
1306 | |||
1307 | case VIDIOC_INT_S_VIDEO_ROUTING: { | ||
1308 | struct v4l2_routing *route = arg; | ||
1309 | int inp = route->input; | ||
1310 | |||
1311 | return saa717x_set_video_input(client, decoder, inp); | ||
1312 | } | ||
1313 | |||
1314 | case VIDIOC_STREAMON: { | ||
1315 | v4l_dbg(1, debug, client, "decoder enable output\n"); | ||
1316 | decoder->enable = 1; | ||
1317 | saa717x_write(client, 0x193, 0xa6); | ||
1318 | break; | ||
1319 | } | ||
1320 | |||
1321 | case VIDIOC_STREAMOFF: { | ||
1322 | v4l_dbg(1, debug, client, "decoder disable output\n"); | ||
1323 | decoder->enable = 0; | ||
1324 | saa717x_write(client, 0x193, 0x26); /* right? FIXME!--tadachi */ | ||
1325 | break; | ||
1326 | } | ||
1327 | |||
1328 | /* change audio mode */ | ||
1329 | case VIDIOC_S_TUNER: { | ||
1330 | struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; | ||
1331 | int audio_mode; | ||
1332 | char *mes[4] = { | ||
1333 | "MONO", "STEREO", "LANG1", "LANG2/SAP" | ||
1334 | }; | ||
1335 | |||
1336 | audio_mode = V4L2_TUNER_MODE_STEREO; | ||
1337 | |||
1338 | switch (vt->audmode) { | ||
1339 | case V4L2_TUNER_MODE_MONO: | ||
1340 | audio_mode = TUNER_AUDIO_MONO; | ||
1341 | break; | ||
1342 | case V4L2_TUNER_MODE_STEREO: | ||
1343 | audio_mode = TUNER_AUDIO_STEREO; | ||
1344 | break; | ||
1345 | case V4L2_TUNER_MODE_LANG2: | ||
1346 | audio_mode = TUNER_AUDIO_LANG2; | ||
1347 | break; | ||
1348 | case V4L2_TUNER_MODE_LANG1: | ||
1349 | audio_mode = TUNER_AUDIO_LANG1; | ||
1350 | break; | ||
1351 | } | ||
1352 | |||
1353 | v4l_dbg(1, debug, client, "change audio mode to %s\n", | ||
1354 | mes[audio_mode]); | ||
1355 | decoder->tuner_audio_mode = audio_mode; | ||
1356 | /* The registers are not changed here. */ | ||
1357 | /* See DECODER_ENABLE_OUTPUT section. */ | ||
1358 | set_audio_mode(client, decoder->tuner_audio_mode); | ||
1359 | break; | ||
1360 | } | ||
1361 | |||
1362 | case VIDIOC_G_TUNER: { | ||
1363 | struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; | ||
1364 | int dual_f, stereo_f; | ||
1365 | |||
1366 | if (decoder->radio) | ||
1367 | break; | ||
1368 | get_inf_dev_status(client, &dual_f, &stereo_f); | ||
1369 | |||
1370 | v4l_dbg(1, debug, client, "DETECT==st:%d dual:%d\n", | ||
1371 | stereo_f, dual_f); | ||
1372 | |||
1373 | /* mono */ | ||
1374 | if ((dual_f == 0) && (stereo_f == 0)) { | ||
1375 | vt->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
1376 | v4l_dbg(1, debug, client, "DETECT==MONO\n"); | ||
1377 | } | ||
1378 | |||
1379 | /* stereo */ | ||
1380 | if (stereo_f == 1) { | ||
1381 | if (vt->audmode == V4L2_TUNER_MODE_STEREO || | ||
1382 | vt->audmode == V4L2_TUNER_MODE_LANG1) { | ||
1383 | vt->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
1384 | v4l_dbg(1, debug, client, "DETECT==ST(ST)\n"); | ||
1385 | } else { | ||
1386 | vt->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
1387 | v4l_dbg(1, debug, client, "DETECT==ST(MONO)\n"); | ||
1388 | } | ||
1389 | } | ||
1390 | |||
1391 | /* dual */ | ||
1392 | if (dual_f == 1) { | ||
1393 | if (vt->audmode == V4L2_TUNER_MODE_LANG2) { | ||
1394 | vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO; | ||
1395 | v4l_dbg(1, debug, client, "DETECT==DUAL1\n"); | ||
1396 | } else { | ||
1397 | vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO; | ||
1398 | v4l_dbg(1, debug, client, "DETECT==DUAL2\n"); | ||
1399 | } | ||
1400 | } | ||
1401 | break; | ||
1402 | } | ||
1403 | |||
1404 | case VIDIOC_LOG_STATUS: | ||
1405 | /* not yet implemented */ | ||
1406 | break; | ||
1407 | |||
1408 | default: | ||
1409 | return -EINVAL; | ||
1410 | } | ||
1411 | |||
1412 | return 0; | ||
1413 | } | ||
1414 | |||
1415 | /* ----------------------------------------------------------------------- */ | ||
1416 | |||
1417 | |||
1418 | /* i2c implementation */ | ||
1419 | |||
1420 | /* ----------------------------------------------------------------------- */ | ||
1421 | static int saa717x_probe(struct i2c_client *client) | ||
1422 | { | ||
1423 | struct saa717x_state *decoder; | ||
1424 | u8 id = 0; | ||
1425 | char *p = ""; | ||
1426 | |||
1427 | /* Check if the adapter supports the needed features */ | ||
1428 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
1429 | return -EIO; | ||
1430 | |||
1431 | snprintf(client->name, sizeof(client->name) - 1, "saa717x"); | ||
1432 | |||
1433 | if (saa717x_write(client, 0x5a4, 0xfe) && | ||
1434 | saa717x_write(client, 0x5a5, 0x0f) && | ||
1435 | saa717x_write(client, 0x5a6, 0x00) && | ||
1436 | saa717x_write(client, 0x5a7, 0x01)) | ||
1437 | id = saa717x_read(client, 0x5a0); | ||
1438 | if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) { | ||
1439 | v4l_dbg(1, debug, client, "saa717x not found (id=%02x)\n", id); | ||
1440 | return -ENODEV; | ||
1441 | } | ||
1442 | if (id == 0xc2) | ||
1443 | p = "saa7173"; | ||
1444 | else if (id == 0x32) | ||
1445 | p = "saa7174A"; | ||
1446 | else if (id == 0x6c) | ||
1447 | p = "saa7174HL"; | ||
1448 | else | ||
1449 | p = "saa7171"; | ||
1450 | v4l_info(client, "%s found @ 0x%x (%s)\n", p, | ||
1451 | client->addr << 1, client->adapter->name); | ||
1452 | |||
1453 | decoder = kzalloc(sizeof(struct saa717x_state), GFP_KERNEL); | ||
1454 | i2c_set_clientdata(client, decoder); | ||
1455 | |||
1456 | if (decoder == NULL) | ||
1457 | return -ENOMEM; | ||
1458 | decoder->std = V4L2_STD_NTSC; | ||
1459 | decoder->input = -1; | ||
1460 | decoder->enable = 1; | ||
1461 | |||
1462 | /* tune these parameters */ | ||
1463 | decoder->bright = 0x80; | ||
1464 | decoder->contrast = 0x44; | ||
1465 | decoder->sat = 0x40; | ||
1466 | decoder->hue = 0x00; | ||
1467 | |||
1468 | /* FIXME!! */ | ||
1469 | decoder->playback = 0; /* initially capture mode used */ | ||
1470 | decoder->audio = 1; /* DECODER_AUDIO_48_KHZ */ | ||
1471 | |||
1472 | decoder->audio_input = 2; /* FIXME!! */ | ||
1473 | |||
1474 | decoder->tuner_audio_mode = TUNER_AUDIO_STEREO; | ||
1475 | /* set volume, bass and treble */ | ||
1476 | decoder->audio_main_vol_l = 6; | ||
1477 | decoder->audio_main_vol_r = 6; | ||
1478 | decoder->audio_main_bass = 0; | ||
1479 | decoder->audio_main_treble = 0; | ||
1480 | decoder->audio_main_mute = 0; | ||
1481 | decoder->audio_main_balance = 32768; | ||
1482 | /* normalize (24 to -40 (not -84) -> 65535 to 0) */ | ||
1483 | decoder->audio_main_volume = | ||
1484 | (decoder->audio_main_vol_r + 41) * 65535 / (24 - (-40)); | ||
1485 | |||
1486 | v4l_dbg(1, debug, client, "writing init values\n"); | ||
1487 | |||
1488 | /* FIXME!! */ | ||
1489 | saa717x_write_regs(client, reg_init_initialize); | ||
1490 | set_video_output_level_regs(client, decoder); | ||
1491 | /* set bass,treble to 0db 20041101 K.Ohta */ | ||
1492 | decoder->audio_main_bass = 0; | ||
1493 | decoder->audio_main_treble = 0; | ||
1494 | set_audio_regs(client, decoder); | ||
1495 | |||
1496 | set_current_state(TASK_INTERRUPTIBLE); | ||
1497 | schedule_timeout(2*HZ); | ||
1498 | return 0; | ||
1499 | } | ||
1500 | |||
1501 | static int saa717x_remove(struct i2c_client *client) | ||
1502 | { | ||
1503 | kfree(i2c_get_clientdata(client)); | ||
1504 | return 0; | ||
1505 | } | ||
1506 | |||
1507 | /* ----------------------------------------------------------------------- */ | ||
1508 | |||
1509 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | ||
1510 | .name = "saa717x", | ||
1511 | .driverid = I2C_DRIVERID_SAA717X, | ||
1512 | .command = saa717x_command, | ||
1513 | .probe = saa717x_probe, | ||
1514 | .remove = saa717x_remove, | ||
1515 | .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, | ||
1516 | }; | ||
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 41f70440fd3b..02fda4eecea3 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c | |||
@@ -52,7 +52,7 @@ MODULE_LICENSE("GPL"); | |||
52 | #define I2C_NAME(s) (s)->name | 52 | #define I2C_NAME(s) (s)->name |
53 | 53 | ||
54 | 54 | ||
55 | static int debug = 0; | 55 | static int debug; |
56 | module_param(debug, int, 0); | 56 | module_param(debug, int, 0); |
57 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 57 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
58 | 58 | ||
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index d5d7d6cf734a..1cd629380f71 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c | |||
@@ -35,7 +35,7 @@ static const char version[] = "0.24"; | |||
35 | #include <linux/usb.h> | 35 | #include <linux/usb.h> |
36 | #include "se401.h" | 36 | #include "se401.h" |
37 | 37 | ||
38 | static int flickerless=0; | 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 [] = { |
@@ -300,10 +300,10 @@ static void se401_button_irq(struct urb *urb) | |||
300 | case -ENOENT: | 300 | case -ENOENT: |
301 | case -ESHUTDOWN: | 301 | case -ESHUTDOWN: |
302 | /* this urb is terminated, clean up */ | 302 | /* this urb is terminated, clean up */ |
303 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | 303 | dbg("%s - urb shutting down with status: %d", __func__, urb->status); |
304 | return; | 304 | return; |
305 | default: | 305 | default: |
306 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | 306 | dbg("%s - nonzero urb status received: %d", __func__, urb->status); |
307 | goto exit; | 307 | goto exit; |
308 | } | 308 | } |
309 | 309 | ||
@@ -315,7 +315,7 @@ exit: | |||
315 | status = usb_submit_urb (urb, GFP_ATOMIC); | 315 | status = usb_submit_urb (urb, GFP_ATOMIC); |
316 | if (status) | 316 | if (status) |
317 | err ("%s - usb_submit_urb failed with result %d", | 317 | err ("%s - usb_submit_urb failed with result %d", |
318 | __FUNCTION__, status); | 318 | __func__, status); |
319 | } | 319 | } |
320 | 320 | ||
321 | static void se401_video_irq(struct urb *urb) | 321 | static void se401_video_irq(struct urb *urb) |
@@ -1224,7 +1224,9 @@ static const struct file_operations se401_fops = { | |||
1224 | .read = se401_read, | 1224 | .read = se401_read, |
1225 | .mmap = se401_mmap, | 1225 | .mmap = se401_mmap, |
1226 | .ioctl = se401_ioctl, | 1226 | .ioctl = se401_ioctl, |
1227 | #ifdef CONFIG_COMPAT | ||
1227 | .compat_ioctl = v4l_compat_ioctl32, | 1228 | .compat_ioctl = v4l_compat_ioctl32, |
1229 | #endif | ||
1228 | .llseek = no_llseek, | 1230 | .llseek = no_llseek, |
1229 | }; | 1231 | }; |
1230 | static struct video_device se401_template = { | 1232 | static struct video_device se401_template = { |
@@ -1279,7 +1281,7 @@ static int se401_init(struct usb_se401 *se401, int button) | |||
1279 | rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp)); | 1281 | rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp)); |
1280 | se401->cheight=cp[0]+cp[1]*256; | 1282 | se401->cheight=cp[0]+cp[1]*256; |
1281 | 1283 | ||
1282 | if (!cp[2] && SE401_FORMAT_BAYER) { | 1284 | if (!(cp[2] & SE401_FORMAT_BAYER)) { |
1283 | err("Bayer format not supported!"); | 1285 | err("Bayer format not supported!"); |
1284 | return 1; | 1286 | return 1; |
1285 | } | 1287 | } |
diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/media/video/sn9c102/sn9c102.h index 2e3c3de793a7..0c8d87d8d18d 100644 --- a/drivers/media/video/sn9c102/sn9c102.h +++ b/drivers/media/video/sn9c102/sn9c102.h | |||
@@ -176,7 +176,7 @@ do { \ | |||
176 | dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ | 176 | dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ |
177 | else if ((level) >= 3) \ | 177 | else if ((level) >= 3) \ |
178 | dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ | 178 | dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ |
179 | __FUNCTION__, __LINE__ , ## args); \ | 179 | __func__, __LINE__ , ## args); \ |
180 | } \ | 180 | } \ |
181 | } while (0) | 181 | } while (0) |
182 | # define V4LDBG(level, name, cmd) \ | 182 | # define V4LDBG(level, name, cmd) \ |
@@ -191,7 +191,7 @@ do { \ | |||
191 | pr_info("sn9c102: " fmt "\n", ## args); \ | 191 | pr_info("sn9c102: " fmt "\n", ## args); \ |
192 | else if ((level) == 3) \ | 192 | else if ((level) == 3) \ |
193 | pr_debug("sn9c102: [%s:%d] " fmt "\n", \ | 193 | pr_debug("sn9c102: [%s:%d] " fmt "\n", \ |
194 | __FUNCTION__, __LINE__ , ## args); \ | 194 | __func__, __LINE__ , ## args); \ |
195 | } \ | 195 | } \ |
196 | } while (0) | 196 | } while (0) |
197 | #else | 197 | #else |
@@ -202,7 +202,7 @@ do { \ | |||
202 | 202 | ||
203 | #undef PDBG | 203 | #undef PDBG |
204 | #define PDBG(fmt, args...) \ | 204 | #define PDBG(fmt, args...) \ |
205 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \ | 205 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \ |
206 | __LINE__ , ## args) | 206 | __LINE__ , ## args) |
207 | 207 | ||
208 | #undef PDBGG | 208 | #undef PDBGG |
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index c40ba3adab21..5748b1e1a128 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
@@ -464,9 +464,9 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam, | |||
464 | } | 464 | } |
465 | 465 | ||
466 | 466 | ||
467 | int | 467 | static int sn9c102_i2c_try_write(struct sn9c102_device* cam, |
468 | sn9c102_i2c_try_write(struct sn9c102_device* cam, | 468 | const struct sn9c102_sensor* sensor, |
469 | const struct sn9c102_sensor* sensor, u8 address, u8 value) | 469 | u8 address, u8 value) |
470 | { | 470 | { |
471 | return sn9c102_i2c_try_raw_write(cam, sensor, 3, | 471 | return sn9c102_i2c_try_raw_write(cam, sensor, 3, |
472 | sensor->i2c_slave_id, address, | 472 | sensor->i2c_slave_id, address, |
@@ -528,7 +528,7 @@ sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) | |||
528 | 528 | ||
529 | /* Search for the SOF marker (fixed part) in the header */ | 529 | /* Search for the SOF marker (fixed part) in the header */ |
530 | for (j = 0, b=cam->sof.bytesread; j+b < sizeof(marker); j++) { | 530 | for (j = 0, b=cam->sof.bytesread; j+b < sizeof(marker); j++) { |
531 | if (unlikely(i+j) == len) | 531 | if (unlikely(i+j == len)) |
532 | return NULL; | 532 | return NULL; |
533 | if (*(m+i+j) == marker[cam->sof.bytesread]) { | 533 | if (*(m+i+j) == marker[cam->sof.bytesread]) { |
534 | cam->sof.header[cam->sof.bytesread] = *(m+i+j); | 534 | cam->sof.header[cam->sof.bytesread] = *(m+i+j); |
@@ -3224,7 +3224,9 @@ static const struct file_operations sn9c102_fops = { | |||
3224 | .open = sn9c102_open, | 3224 | .open = sn9c102_open, |
3225 | .release = sn9c102_release, | 3225 | .release = sn9c102_release, |
3226 | .ioctl = sn9c102_ioctl, | 3226 | .ioctl = sn9c102_ioctl, |
3227 | #ifdef CONFIG_COMPAT | ||
3227 | .compat_ioctl = v4l_compat_ioctl32, | 3228 | .compat_ioctl = v4l_compat_ioctl32, |
3229 | #endif | ||
3228 | .read = sn9c102_read, | 3230 | .read = sn9c102_read, |
3229 | .poll = sn9c102_poll, | 3231 | .poll = sn9c102_poll, |
3230 | .mmap = sn9c102_mmap, | 3232 | .mmap = sn9c102_mmap, |
@@ -3239,7 +3241,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3239 | { | 3241 | { |
3240 | struct usb_device *udev = interface_to_usbdev(intf); | 3242 | struct usb_device *udev = interface_to_usbdev(intf); |
3241 | struct sn9c102_device* cam; | 3243 | struct sn9c102_device* cam; |
3242 | static unsigned int dev_nr = 0; | 3244 | static unsigned int dev_nr; |
3243 | unsigned int i; | 3245 | unsigned int i; |
3244 | int err = 0, r; | 3246 | int err = 0, r; |
3245 | 3247 | ||
diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h index 2dc7c6869484..4af7382da5c5 100644 --- a/drivers/media/video/sn9c102/sn9c102_sensor.h +++ b/drivers/media/video/sn9c102/sn9c102_sensor.h | |||
@@ -85,9 +85,6 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, | |||
85 | */ | 85 | */ |
86 | 86 | ||
87 | /* The "try" I2C I/O versions are used when probing the sensor */ | 87 | /* The "try" I2C I/O versions are used when probing the sensor */ |
88 | extern int sn9c102_i2c_try_write(struct sn9c102_device*, | ||
89 | const struct sn9c102_sensor*, u8 address, | ||
90 | u8 value); | ||
91 | extern int sn9c102_i2c_try_read(struct sn9c102_device*, | 88 | extern int sn9c102_i2c_try_read(struct sn9c102_device*, |
92 | const struct sn9c102_sensor*, u8 address); | 89 | const struct sn9c102_sensor*, u8 address); |
93 | 90 | ||
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c new file mode 100644 index 000000000000..a1b92446c8b4 --- /dev/null +++ b/drivers/media/video/soc_camera.c | |||
@@ -0,0 +1,1031 @@ | |||
1 | /* | ||
2 | * camera image capture (abstract) bus driver | ||
3 | * | ||
4 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | ||
5 | * | ||
6 | * This driver provides an interface between platform-specific camera | ||
7 | * busses and camera devices. It should be used if the camera is | ||
8 | * connected not over a "proper" bus like PCI or USB, but over a | ||
9 | * special bus, like, for example, the Quick Capture interface on PXA270 | ||
10 | * SoCs. Later it should also be used for i.MX31 SoCs from Freescale. | ||
11 | * It can handle multiple cameras and / or multiple busses, which can | ||
12 | * be used, e.g., in stereo-vision applications. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License version 2 as | ||
16 | * published by the Free Software Foundation. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/list.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <linux/mutex.h> | ||
25 | #include <linux/vmalloc.h> | ||
26 | |||
27 | #include <media/v4l2-common.h> | ||
28 | #include <media/v4l2-dev.h> | ||
29 | #include <media/soc_camera.h> | ||
30 | |||
31 | static LIST_HEAD(hosts); | ||
32 | static LIST_HEAD(devices); | ||
33 | static DEFINE_MUTEX(list_lock); | ||
34 | static DEFINE_MUTEX(video_lock); | ||
35 | |||
36 | const static struct soc_camera_data_format* | ||
37 | format_by_fourcc(struct soc_camera_device *icd, unsigned int fourcc) | ||
38 | { | ||
39 | unsigned int i; | ||
40 | |||
41 | for (i = 0; i < icd->num_formats; i++) | ||
42 | if (icd->formats[i].fourcc == fourcc) | ||
43 | return icd->formats + i; | ||
44 | return NULL; | ||
45 | } | ||
46 | |||
47 | static int soc_camera_try_fmt_cap(struct file *file, void *priv, | ||
48 | struct v4l2_format *f) | ||
49 | { | ||
50 | struct soc_camera_file *icf = file->private_data; | ||
51 | struct soc_camera_device *icd = icf->icd; | ||
52 | struct soc_camera_host *ici = | ||
53 | to_soc_camera_host(icd->dev.parent); | ||
54 | enum v4l2_field field; | ||
55 | const struct soc_camera_data_format *fmt; | ||
56 | int ret; | ||
57 | |||
58 | WARN_ON(priv != file->private_data); | ||
59 | |||
60 | fmt = format_by_fourcc(icd, f->fmt.pix.pixelformat); | ||
61 | if (!fmt) { | ||
62 | dev_dbg(&icd->dev, "invalid format 0x%08x\n", | ||
63 | f->fmt.pix.pixelformat); | ||
64 | return -EINVAL; | ||
65 | } | ||
66 | |||
67 | dev_dbg(&icd->dev, "fmt: 0x%08x\n", fmt->fourcc); | ||
68 | |||
69 | field = f->fmt.pix.field; | ||
70 | |||
71 | if (field == V4L2_FIELD_ANY) { | ||
72 | field = V4L2_FIELD_NONE; | ||
73 | } else if (V4L2_FIELD_NONE != field) { | ||
74 | dev_err(&icd->dev, "Field type invalid.\n"); | ||
75 | return -EINVAL; | ||
76 | } | ||
77 | |||
78 | /* test physical bus parameters */ | ||
79 | ret = ici->ops->try_bus_param(icd, f->fmt.pix.pixelformat); | ||
80 | if (ret) | ||
81 | return ret; | ||
82 | |||
83 | /* limit format to hardware capabilities */ | ||
84 | ret = ici->ops->try_fmt_cap(icd, f); | ||
85 | |||
86 | /* calculate missing fields */ | ||
87 | f->fmt.pix.field = field; | ||
88 | f->fmt.pix.bytesperline = | ||
89 | (f->fmt.pix.width * fmt->depth) >> 3; | ||
90 | f->fmt.pix.sizeimage = | ||
91 | f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
92 | |||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | static int soc_camera_enum_input(struct file *file, void *priv, | ||
97 | struct v4l2_input *inp) | ||
98 | { | ||
99 | if (inp->index != 0) | ||
100 | return -EINVAL; | ||
101 | |||
102 | inp->type = V4L2_INPUT_TYPE_CAMERA; | ||
103 | inp->std = V4L2_STD_UNKNOWN; | ||
104 | strcpy(inp->name, "Camera"); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int soc_camera_g_input(struct file *file, void *priv, unsigned int *i) | ||
110 | { | ||
111 | *i = 0; | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int soc_camera_s_input(struct file *file, void *priv, unsigned int i) | ||
117 | { | ||
118 | if (i > 0) | ||
119 | return -EINVAL; | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a) | ||
125 | { | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int soc_camera_reqbufs(struct file *file, void *priv, | ||
130 | struct v4l2_requestbuffers *p) | ||
131 | { | ||
132 | int ret; | ||
133 | struct soc_camera_file *icf = file->private_data; | ||
134 | struct soc_camera_device *icd = icf->icd; | ||
135 | struct soc_camera_host *ici = | ||
136 | to_soc_camera_host(icd->dev.parent); | ||
137 | |||
138 | WARN_ON(priv != file->private_data); | ||
139 | |||
140 | dev_dbg(&icd->dev, "%s: %d\n", __func__, p->memory); | ||
141 | |||
142 | ret = videobuf_reqbufs(&icf->vb_vidq, p); | ||
143 | if (ret < 0) | ||
144 | return ret; | ||
145 | |||
146 | return ici->ops->reqbufs(icf, p); | ||
147 | } | ||
148 | |||
149 | static int soc_camera_querybuf(struct file *file, void *priv, | ||
150 | struct v4l2_buffer *p) | ||
151 | { | ||
152 | struct soc_camera_file *icf = file->private_data; | ||
153 | |||
154 | WARN_ON(priv != file->private_data); | ||
155 | |||
156 | return videobuf_querybuf(&icf->vb_vidq, p); | ||
157 | } | ||
158 | |||
159 | static int soc_camera_qbuf(struct file *file, void *priv, | ||
160 | struct v4l2_buffer *p) | ||
161 | { | ||
162 | struct soc_camera_file *icf = file->private_data; | ||
163 | |||
164 | WARN_ON(priv != file->private_data); | ||
165 | |||
166 | return videobuf_qbuf(&icf->vb_vidq, p); | ||
167 | } | ||
168 | |||
169 | static int soc_camera_dqbuf(struct file *file, void *priv, | ||
170 | struct v4l2_buffer *p) | ||
171 | { | ||
172 | struct soc_camera_file *icf = file->private_data; | ||
173 | |||
174 | WARN_ON(priv != file->private_data); | ||
175 | |||
176 | return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK); | ||
177 | } | ||
178 | |||
179 | static int soc_camera_open(struct inode *inode, struct file *file) | ||
180 | { | ||
181 | struct video_device *vdev; | ||
182 | struct soc_camera_device *icd; | ||
183 | struct soc_camera_host *ici; | ||
184 | struct soc_camera_file *icf; | ||
185 | spinlock_t *lock; | ||
186 | int ret; | ||
187 | |||
188 | icf = vmalloc(sizeof(*icf)); | ||
189 | if (!icf) | ||
190 | return -ENOMEM; | ||
191 | |||
192 | /* Protect against icd->remove() until we module_get() both drivers. */ | ||
193 | mutex_lock(&video_lock); | ||
194 | |||
195 | vdev = video_devdata(file); | ||
196 | icd = container_of(vdev->dev, struct soc_camera_device, dev); | ||
197 | ici = to_soc_camera_host(icd->dev.parent); | ||
198 | |||
199 | if (!try_module_get(icd->ops->owner)) { | ||
200 | dev_err(&icd->dev, "Couldn't lock sensor driver.\n"); | ||
201 | ret = -EINVAL; | ||
202 | goto emgd; | ||
203 | } | ||
204 | |||
205 | if (!try_module_get(ici->ops->owner)) { | ||
206 | dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); | ||
207 | ret = -EINVAL; | ||
208 | goto emgi; | ||
209 | } | ||
210 | |||
211 | icf->icd = icd; | ||
212 | |||
213 | icf->lock = ici->ops->spinlock_alloc(icf); | ||
214 | if (!icf->lock) { | ||
215 | ret = -ENOMEM; | ||
216 | goto esla; | ||
217 | } | ||
218 | |||
219 | icd->use_count++; | ||
220 | |||
221 | /* Now we really have to activate the camera */ | ||
222 | if (icd->use_count == 1) { | ||
223 | ret = ici->ops->add(icd); | ||
224 | if (ret < 0) { | ||
225 | dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret); | ||
226 | icd->use_count--; | ||
227 | goto eiciadd; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | mutex_unlock(&video_lock); | ||
232 | |||
233 | file->private_data = icf; | ||
234 | dev_dbg(&icd->dev, "camera device open\n"); | ||
235 | |||
236 | /* We must pass NULL as dev pointer, then all pci_* dma operations | ||
237 | * transform to normal dma_* ones. */ | ||
238 | videobuf_queue_sg_init(&icf->vb_vidq, ici->vbq_ops, NULL, icf->lock, | ||
239 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | ||
240 | ici->msize, icd); | ||
241 | |||
242 | return 0; | ||
243 | |||
244 | /* All errors are entered with the video_lock held */ | ||
245 | eiciadd: | ||
246 | lock = icf->lock; | ||
247 | icf->lock = NULL; | ||
248 | if (ici->ops->spinlock_free) | ||
249 | ici->ops->spinlock_free(lock); | ||
250 | esla: | ||
251 | module_put(ici->ops->owner); | ||
252 | emgi: | ||
253 | module_put(icd->ops->owner); | ||
254 | emgd: | ||
255 | mutex_unlock(&video_lock); | ||
256 | vfree(icf); | ||
257 | return ret; | ||
258 | } | ||
259 | |||
260 | static int soc_camera_close(struct inode *inode, struct file *file) | ||
261 | { | ||
262 | struct soc_camera_file *icf = file->private_data; | ||
263 | struct soc_camera_device *icd = icf->icd; | ||
264 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
265 | struct video_device *vdev = icd->vdev; | ||
266 | spinlock_t *lock = icf->lock; | ||
267 | |||
268 | mutex_lock(&video_lock); | ||
269 | icd->use_count--; | ||
270 | if (!icd->use_count) | ||
271 | ici->ops->remove(icd); | ||
272 | icf->lock = NULL; | ||
273 | if (ici->ops->spinlock_free) | ||
274 | ici->ops->spinlock_free(lock); | ||
275 | module_put(icd->ops->owner); | ||
276 | module_put(ici->ops->owner); | ||
277 | mutex_unlock(&video_lock); | ||
278 | |||
279 | vfree(icf); | ||
280 | |||
281 | dev_dbg(vdev->dev, "camera device close\n"); | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static ssize_t soc_camera_read(struct file *file, char __user *buf, | ||
287 | size_t count, loff_t *ppos) | ||
288 | { | ||
289 | struct soc_camera_file *icf = file->private_data; | ||
290 | struct soc_camera_device *icd = icf->icd; | ||
291 | struct video_device *vdev = icd->vdev; | ||
292 | int err = -EINVAL; | ||
293 | |||
294 | dev_err(vdev->dev, "camera device read not implemented\n"); | ||
295 | |||
296 | return err; | ||
297 | } | ||
298 | |||
299 | static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) | ||
300 | { | ||
301 | struct soc_camera_file *icf = file->private_data; | ||
302 | struct soc_camera_device *icd = icf->icd; | ||
303 | int err; | ||
304 | |||
305 | dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma); | ||
306 | |||
307 | err = videobuf_mmap_mapper(&icf->vb_vidq, vma); | ||
308 | |||
309 | dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n", | ||
310 | (unsigned long)vma->vm_start, | ||
311 | (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, | ||
312 | err); | ||
313 | |||
314 | return err; | ||
315 | } | ||
316 | |||
317 | static unsigned int soc_camera_poll(struct file *file, poll_table *pt) | ||
318 | { | ||
319 | struct soc_camera_file *icf = file->private_data; | ||
320 | struct soc_camera_device *icd = icf->icd; | ||
321 | struct soc_camera_host *ici = | ||
322 | to_soc_camera_host(icd->dev.parent); | ||
323 | |||
324 | if (list_empty(&icf->vb_vidq.stream)) { | ||
325 | dev_err(&icd->dev, "Trying to poll with no queued buffers!\n"); | ||
326 | return POLLERR; | ||
327 | } | ||
328 | |||
329 | return ici->ops->poll(file, pt); | ||
330 | } | ||
331 | |||
332 | |||
333 | static struct file_operations soc_camera_fops = { | ||
334 | .owner = THIS_MODULE, | ||
335 | .open = soc_camera_open, | ||
336 | .release = soc_camera_close, | ||
337 | .ioctl = video_ioctl2, | ||
338 | .read = soc_camera_read, | ||
339 | .mmap = soc_camera_mmap, | ||
340 | .poll = soc_camera_poll, | ||
341 | .llseek = no_llseek, | ||
342 | }; | ||
343 | |||
344 | |||
345 | static int soc_camera_s_fmt_cap(struct file *file, void *priv, | ||
346 | struct v4l2_format *f) | ||
347 | { | ||
348 | struct soc_camera_file *icf = file->private_data; | ||
349 | struct soc_camera_device *icd = icf->icd; | ||
350 | struct soc_camera_host *ici = | ||
351 | to_soc_camera_host(icd->dev.parent); | ||
352 | int ret; | ||
353 | struct v4l2_rect rect; | ||
354 | const static struct soc_camera_data_format *data_fmt; | ||
355 | |||
356 | WARN_ON(priv != file->private_data); | ||
357 | |||
358 | data_fmt = format_by_fourcc(icd, f->fmt.pix.pixelformat); | ||
359 | if (!data_fmt) | ||
360 | return -EINVAL; | ||
361 | |||
362 | /* buswidth may be further adjusted by the ici */ | ||
363 | icd->buswidth = data_fmt->depth; | ||
364 | |||
365 | ret = soc_camera_try_fmt_cap(file, icf, f); | ||
366 | if (ret < 0) | ||
367 | return ret; | ||
368 | |||
369 | rect.left = icd->x_current; | ||
370 | rect.top = icd->y_current; | ||
371 | rect.width = f->fmt.pix.width; | ||
372 | rect.height = f->fmt.pix.height; | ||
373 | ret = ici->ops->set_fmt_cap(icd, f->fmt.pix.pixelformat, &rect); | ||
374 | if (ret < 0) | ||
375 | return ret; | ||
376 | |||
377 | icd->current_fmt = data_fmt; | ||
378 | icd->width = rect.width; | ||
379 | icd->height = rect.height; | ||
380 | icf->vb_vidq.field = f->fmt.pix.field; | ||
381 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != f->type) | ||
382 | dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n", | ||
383 | f->type); | ||
384 | |||
385 | dev_dbg(&icd->dev, "set width: %d height: %d\n", | ||
386 | icd->width, icd->height); | ||
387 | |||
388 | /* set physical bus parameters */ | ||
389 | return ici->ops->set_bus_param(icd, f->fmt.pix.pixelformat); | ||
390 | } | ||
391 | |||
392 | static int soc_camera_enum_fmt_cap(struct file *file, void *priv, | ||
393 | struct v4l2_fmtdesc *f) | ||
394 | { | ||
395 | struct soc_camera_file *icf = file->private_data; | ||
396 | struct soc_camera_device *icd = icf->icd; | ||
397 | const struct soc_camera_data_format *format; | ||
398 | |||
399 | WARN_ON(priv != file->private_data); | ||
400 | |||
401 | if (f->index >= icd->num_formats) | ||
402 | return -EINVAL; | ||
403 | |||
404 | format = &icd->formats[f->index]; | ||
405 | |||
406 | strlcpy(f->description, format->name, sizeof(f->description)); | ||
407 | f->pixelformat = format->fourcc; | ||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | static int soc_camera_g_fmt_cap(struct file *file, void *priv, | ||
412 | struct v4l2_format *f) | ||
413 | { | ||
414 | struct soc_camera_file *icf = file->private_data; | ||
415 | struct soc_camera_device *icd = icf->icd; | ||
416 | |||
417 | WARN_ON(priv != file->private_data); | ||
418 | |||
419 | f->fmt.pix.width = icd->width; | ||
420 | f->fmt.pix.height = icd->height; | ||
421 | f->fmt.pix.field = icf->vb_vidq.field; | ||
422 | f->fmt.pix.pixelformat = icd->current_fmt->fourcc; | ||
423 | f->fmt.pix.bytesperline = | ||
424 | (f->fmt.pix.width * icd->current_fmt->depth) >> 3; | ||
425 | f->fmt.pix.sizeimage = | ||
426 | f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
427 | dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n", | ||
428 | icd->current_fmt->fourcc); | ||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static int soc_camera_querycap(struct file *file, void *priv, | ||
433 | struct v4l2_capability *cap) | ||
434 | { | ||
435 | struct soc_camera_file *icf = file->private_data; | ||
436 | struct soc_camera_device *icd = icf->icd; | ||
437 | struct soc_camera_host *ici = | ||
438 | to_soc_camera_host(icd->dev.parent); | ||
439 | |||
440 | WARN_ON(priv != file->private_data); | ||
441 | |||
442 | strlcpy(cap->driver, ici->drv_name, sizeof(cap->driver)); | ||
443 | return ici->ops->querycap(ici, cap); | ||
444 | } | ||
445 | |||
446 | static int soc_camera_streamon(struct file *file, void *priv, | ||
447 | enum v4l2_buf_type i) | ||
448 | { | ||
449 | struct soc_camera_file *icf = file->private_data; | ||
450 | struct soc_camera_device *icd = icf->icd; | ||
451 | |||
452 | WARN_ON(priv != file->private_data); | ||
453 | |||
454 | dev_dbg(&icd->dev, "%s\n", __func__); | ||
455 | |||
456 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
457 | return -EINVAL; | ||
458 | |||
459 | icd->ops->start_capture(icd); | ||
460 | |||
461 | /* This calls buf_queue from host driver's videobuf_queue_ops */ | ||
462 | return videobuf_streamon(&icf->vb_vidq); | ||
463 | } | ||
464 | |||
465 | static int soc_camera_streamoff(struct file *file, void *priv, | ||
466 | enum v4l2_buf_type i) | ||
467 | { | ||
468 | struct soc_camera_file *icf = file->private_data; | ||
469 | struct soc_camera_device *icd = icf->icd; | ||
470 | |||
471 | WARN_ON(priv != file->private_data); | ||
472 | |||
473 | dev_dbg(&icd->dev, "%s\n", __func__); | ||
474 | |||
475 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
476 | return -EINVAL; | ||
477 | |||
478 | /* This calls buf_release from host driver's videobuf_queue_ops for all | ||
479 | * remaining buffers. When the last buffer is freed, stop capture */ | ||
480 | videobuf_streamoff(&icf->vb_vidq); | ||
481 | |||
482 | icd->ops->stop_capture(icd); | ||
483 | |||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static int soc_camera_queryctrl(struct file *file, void *priv, | ||
488 | struct v4l2_queryctrl *qc) | ||
489 | { | ||
490 | struct soc_camera_file *icf = file->private_data; | ||
491 | struct soc_camera_device *icd = icf->icd; | ||
492 | int i; | ||
493 | |||
494 | WARN_ON(priv != file->private_data); | ||
495 | |||
496 | if (!qc->id) | ||
497 | return -EINVAL; | ||
498 | |||
499 | for (i = 0; i < icd->ops->num_controls; i++) | ||
500 | if (qc->id == icd->ops->controls[i].id) { | ||
501 | memcpy(qc, &(icd->ops->controls[i]), | ||
502 | sizeof(*qc)); | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | return -EINVAL; | ||
507 | } | ||
508 | |||
509 | static int soc_camera_g_ctrl(struct file *file, void *priv, | ||
510 | struct v4l2_control *ctrl) | ||
511 | { | ||
512 | struct soc_camera_file *icf = file->private_data; | ||
513 | struct soc_camera_device *icd = icf->icd; | ||
514 | |||
515 | WARN_ON(priv != file->private_data); | ||
516 | |||
517 | switch (ctrl->id) { | ||
518 | case V4L2_CID_GAIN: | ||
519 | if (icd->gain == (unsigned short)~0) | ||
520 | return -EINVAL; | ||
521 | ctrl->value = icd->gain; | ||
522 | return 0; | ||
523 | case V4L2_CID_EXPOSURE: | ||
524 | if (icd->exposure == (unsigned short)~0) | ||
525 | return -EINVAL; | ||
526 | ctrl->value = icd->exposure; | ||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | if (icd->ops->get_control) | ||
531 | return icd->ops->get_control(icd, ctrl); | ||
532 | return -EINVAL; | ||
533 | } | ||
534 | |||
535 | static int soc_camera_s_ctrl(struct file *file, void *priv, | ||
536 | struct v4l2_control *ctrl) | ||
537 | { | ||
538 | struct soc_camera_file *icf = file->private_data; | ||
539 | struct soc_camera_device *icd = icf->icd; | ||
540 | |||
541 | WARN_ON(priv != file->private_data); | ||
542 | |||
543 | if (icd->ops->set_control) | ||
544 | return icd->ops->set_control(icd, ctrl); | ||
545 | return -EINVAL; | ||
546 | } | ||
547 | |||
548 | static int soc_camera_cropcap(struct file *file, void *fh, | ||
549 | struct v4l2_cropcap *a) | ||
550 | { | ||
551 | struct soc_camera_file *icf = file->private_data; | ||
552 | struct soc_camera_device *icd = icf->icd; | ||
553 | |||
554 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
555 | a->bounds.left = icd->x_min; | ||
556 | a->bounds.top = icd->y_min; | ||
557 | a->bounds.width = icd->width_max; | ||
558 | a->bounds.height = icd->height_max; | ||
559 | a->defrect.left = icd->x_min; | ||
560 | a->defrect.top = icd->y_min; | ||
561 | a->defrect.width = 640; | ||
562 | a->defrect.height = 480; | ||
563 | a->pixelaspect.numerator = 1; | ||
564 | a->pixelaspect.denominator = 1; | ||
565 | |||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | static int soc_camera_g_crop(struct file *file, void *fh, | ||
570 | struct v4l2_crop *a) | ||
571 | { | ||
572 | struct soc_camera_file *icf = file->private_data; | ||
573 | struct soc_camera_device *icd = icf->icd; | ||
574 | |||
575 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
576 | a->c.left = icd->x_current; | ||
577 | a->c.top = icd->y_current; | ||
578 | a->c.width = icd->width; | ||
579 | a->c.height = icd->height; | ||
580 | |||
581 | return 0; | ||
582 | } | ||
583 | |||
584 | static int soc_camera_s_crop(struct file *file, void *fh, | ||
585 | struct v4l2_crop *a) | ||
586 | { | ||
587 | struct soc_camera_file *icf = file->private_data; | ||
588 | struct soc_camera_device *icd = icf->icd; | ||
589 | struct soc_camera_host *ici = | ||
590 | to_soc_camera_host(icd->dev.parent); | ||
591 | int ret; | ||
592 | |||
593 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
594 | return -EINVAL; | ||
595 | |||
596 | ret = ici->ops->set_fmt_cap(icd, 0, &a->c); | ||
597 | if (!ret) { | ||
598 | icd->width = a->c.width; | ||
599 | icd->height = a->c.height; | ||
600 | icd->x_current = a->c.left; | ||
601 | icd->y_current = a->c.top; | ||
602 | } | ||
603 | |||
604 | return ret; | ||
605 | } | ||
606 | |||
607 | static int soc_camera_g_chip_ident(struct file *file, void *fh, | ||
608 | struct v4l2_chip_ident *id) | ||
609 | { | ||
610 | struct soc_camera_file *icf = file->private_data; | ||
611 | struct soc_camera_device *icd = icf->icd; | ||
612 | |||
613 | if (!icd->ops->get_chip_id) | ||
614 | return -EINVAL; | ||
615 | |||
616 | return icd->ops->get_chip_id(icd, id); | ||
617 | } | ||
618 | |||
619 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
620 | static int soc_camera_g_register(struct file *file, void *fh, | ||
621 | struct v4l2_register *reg) | ||
622 | { | ||
623 | struct soc_camera_file *icf = file->private_data; | ||
624 | struct soc_camera_device *icd = icf->icd; | ||
625 | |||
626 | if (!icd->ops->get_register) | ||
627 | return -EINVAL; | ||
628 | |||
629 | return icd->ops->get_register(icd, reg); | ||
630 | } | ||
631 | |||
632 | static int soc_camera_s_register(struct file *file, void *fh, | ||
633 | struct v4l2_register *reg) | ||
634 | { | ||
635 | struct soc_camera_file *icf = file->private_data; | ||
636 | struct soc_camera_device *icd = icf->icd; | ||
637 | |||
638 | if (!icd->ops->set_register) | ||
639 | return -EINVAL; | ||
640 | |||
641 | return icd->ops->set_register(icd, reg); | ||
642 | } | ||
643 | #endif | ||
644 | |||
645 | static int device_register_link(struct soc_camera_device *icd) | ||
646 | { | ||
647 | int ret = device_register(&icd->dev); | ||
648 | |||
649 | if (ret < 0) { | ||
650 | /* Prevent calling device_unregister() */ | ||
651 | icd->dev.parent = NULL; | ||
652 | dev_err(&icd->dev, "Cannot register device: %d\n", ret); | ||
653 | /* Even if probe() was unsuccessful for all registered drivers, | ||
654 | * device_register() returns 0, and we add the link, just to | ||
655 | * document this camera's control device */ | ||
656 | } else if (icd->control) | ||
657 | /* Have to sysfs_remove_link() before device_unregister()? */ | ||
658 | if (sysfs_create_link(&icd->dev.kobj, &icd->control->kobj, | ||
659 | "control")) | ||
660 | dev_warn(&icd->dev, | ||
661 | "Failed creating the control symlink\n"); | ||
662 | return ret; | ||
663 | } | ||
664 | |||
665 | /* So far this function cannot fail */ | ||
666 | static void scan_add_host(struct soc_camera_host *ici) | ||
667 | { | ||
668 | struct soc_camera_device *icd; | ||
669 | |||
670 | mutex_lock(&list_lock); | ||
671 | |||
672 | list_for_each_entry(icd, &devices, list) { | ||
673 | if (icd->iface == ici->nr) { | ||
674 | icd->dev.parent = &ici->dev; | ||
675 | device_register_link(icd); | ||
676 | } | ||
677 | } | ||
678 | |||
679 | mutex_unlock(&list_lock); | ||
680 | } | ||
681 | |||
682 | /* return: 0 if no match found or a match found and | ||
683 | * device_register() successful, error code otherwise */ | ||
684 | static int scan_add_device(struct soc_camera_device *icd) | ||
685 | { | ||
686 | struct soc_camera_host *ici; | ||
687 | int ret = 0; | ||
688 | |||
689 | mutex_lock(&list_lock); | ||
690 | |||
691 | list_add_tail(&icd->list, &devices); | ||
692 | |||
693 | /* Watch out for class_for_each_device / class_find_device API by | ||
694 | * Dave Young <hidave.darkstar@gmail.com> */ | ||
695 | list_for_each_entry(ici, &hosts, list) { | ||
696 | if (icd->iface == ici->nr) { | ||
697 | ret = 1; | ||
698 | icd->dev.parent = &ici->dev; | ||
699 | break; | ||
700 | } | ||
701 | } | ||
702 | |||
703 | mutex_unlock(&list_lock); | ||
704 | |||
705 | if (ret) | ||
706 | ret = device_register_link(icd); | ||
707 | |||
708 | return ret; | ||
709 | } | ||
710 | |||
711 | static int soc_camera_probe(struct device *dev) | ||
712 | { | ||
713 | struct soc_camera_device *icd = to_soc_camera_dev(dev); | ||
714 | struct soc_camera_host *ici = | ||
715 | to_soc_camera_host(icd->dev.parent); | ||
716 | int ret; | ||
717 | |||
718 | if (!icd->ops->probe) | ||
719 | return -ENODEV; | ||
720 | |||
721 | /* We only call ->add() here to activate and probe the camera. | ||
722 | * We shall ->remove() and deactivate it immediately afterwards. */ | ||
723 | ret = ici->ops->add(icd); | ||
724 | if (ret < 0) | ||
725 | return ret; | ||
726 | |||
727 | ret = icd->ops->probe(icd); | ||
728 | if (ret >= 0) { | ||
729 | const struct v4l2_queryctrl *qctrl; | ||
730 | |||
731 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN); | ||
732 | icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0; | ||
733 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | ||
734 | icd->exposure = qctrl ? qctrl->default_value : | ||
735 | (unsigned short)~0; | ||
736 | } | ||
737 | ici->ops->remove(icd); | ||
738 | |||
739 | return ret; | ||
740 | } | ||
741 | |||
742 | /* This is called on device_unregister, which only means we have to disconnect | ||
743 | * from the host, but not remove ourselves from the device list */ | ||
744 | static int soc_camera_remove(struct device *dev) | ||
745 | { | ||
746 | struct soc_camera_device *icd = to_soc_camera_dev(dev); | ||
747 | |||
748 | if (icd->ops->remove) | ||
749 | icd->ops->remove(icd); | ||
750 | |||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | static struct bus_type soc_camera_bus_type = { | ||
755 | .name = "soc-camera", | ||
756 | .probe = soc_camera_probe, | ||
757 | .remove = soc_camera_remove, | ||
758 | }; | ||
759 | |||
760 | static struct device_driver ic_drv = { | ||
761 | .name = "camera", | ||
762 | .bus = &soc_camera_bus_type, | ||
763 | .owner = THIS_MODULE, | ||
764 | }; | ||
765 | |||
766 | /* | ||
767 | * Image capture host - this is a host device, not a bus device, so, | ||
768 | * no bus reference, no probing. | ||
769 | */ | ||
770 | static struct class soc_camera_host_class = { | ||
771 | .owner = THIS_MODULE, | ||
772 | .name = "camera_host", | ||
773 | }; | ||
774 | |||
775 | static void dummy_release(struct device *dev) | ||
776 | { | ||
777 | } | ||
778 | |||
779 | static spinlock_t *spinlock_alloc(struct soc_camera_file *icf) | ||
780 | { | ||
781 | spinlock_t *lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL); | ||
782 | |||
783 | if (lock) | ||
784 | spin_lock_init(lock); | ||
785 | |||
786 | return lock; | ||
787 | } | ||
788 | |||
789 | static void spinlock_free(spinlock_t *lock) | ||
790 | { | ||
791 | kfree(lock); | ||
792 | } | ||
793 | |||
794 | int soc_camera_host_register(struct soc_camera_host *ici) | ||
795 | { | ||
796 | int ret; | ||
797 | struct soc_camera_host *ix; | ||
798 | |||
799 | if (!ici->vbq_ops || !ici->ops->add || !ici->ops->remove) | ||
800 | return -EINVAL; | ||
801 | |||
802 | /* Number might be equal to the platform device ID */ | ||
803 | sprintf(ici->dev.bus_id, "camera_host%d", ici->nr); | ||
804 | ici->dev.class = &soc_camera_host_class; | ||
805 | |||
806 | mutex_lock(&list_lock); | ||
807 | list_for_each_entry(ix, &hosts, list) { | ||
808 | if (ix->nr == ici->nr) { | ||
809 | mutex_unlock(&list_lock); | ||
810 | return -EBUSY; | ||
811 | } | ||
812 | } | ||
813 | |||
814 | list_add_tail(&ici->list, &hosts); | ||
815 | mutex_unlock(&list_lock); | ||
816 | |||
817 | ici->dev.release = dummy_release; | ||
818 | |||
819 | ret = device_register(&ici->dev); | ||
820 | |||
821 | if (ret) | ||
822 | goto edevr; | ||
823 | |||
824 | if (!ici->ops->spinlock_alloc) { | ||
825 | ici->ops->spinlock_alloc = spinlock_alloc; | ||
826 | ici->ops->spinlock_free = spinlock_free; | ||
827 | } | ||
828 | |||
829 | scan_add_host(ici); | ||
830 | |||
831 | return 0; | ||
832 | |||
833 | edevr: | ||
834 | mutex_lock(&list_lock); | ||
835 | list_del(&ici->list); | ||
836 | mutex_unlock(&list_lock); | ||
837 | |||
838 | return ret; | ||
839 | } | ||
840 | EXPORT_SYMBOL(soc_camera_host_register); | ||
841 | |||
842 | /* Unregister all clients! */ | ||
843 | void soc_camera_host_unregister(struct soc_camera_host *ici) | ||
844 | { | ||
845 | struct soc_camera_device *icd; | ||
846 | |||
847 | mutex_lock(&list_lock); | ||
848 | |||
849 | list_del(&ici->list); | ||
850 | |||
851 | list_for_each_entry(icd, &devices, list) { | ||
852 | if (icd->dev.parent == &ici->dev) { | ||
853 | device_unregister(&icd->dev); | ||
854 | /* Not before device_unregister(), .remove | ||
855 | * needs parent to call ici->ops->remove() */ | ||
856 | icd->dev.parent = NULL; | ||
857 | memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj)); | ||
858 | } | ||
859 | } | ||
860 | |||
861 | mutex_unlock(&list_lock); | ||
862 | |||
863 | device_unregister(&ici->dev); | ||
864 | } | ||
865 | EXPORT_SYMBOL(soc_camera_host_unregister); | ||
866 | |||
867 | /* Image capture device */ | ||
868 | int soc_camera_device_register(struct soc_camera_device *icd) | ||
869 | { | ||
870 | struct soc_camera_device *ix; | ||
871 | int num = -1, i; | ||
872 | |||
873 | if (!icd) | ||
874 | return -EINVAL; | ||
875 | |||
876 | for (i = 0; i < 256 && num < 0; i++) { | ||
877 | num = i; | ||
878 | list_for_each_entry(ix, &devices, list) { | ||
879 | if (ix->iface == icd->iface && ix->devnum == i) { | ||
880 | num = -1; | ||
881 | break; | ||
882 | } | ||
883 | } | ||
884 | } | ||
885 | |||
886 | if (num < 0) | ||
887 | /* ok, we have 256 cameras on this host... | ||
888 | * man, stay reasonable... */ | ||
889 | return -ENOMEM; | ||
890 | |||
891 | icd->devnum = num; | ||
892 | icd->dev.bus = &soc_camera_bus_type; | ||
893 | snprintf(icd->dev.bus_id, sizeof(icd->dev.bus_id), | ||
894 | "%u-%u", icd->iface, icd->devnum); | ||
895 | |||
896 | icd->dev.release = dummy_release; | ||
897 | |||
898 | return scan_add_device(icd); | ||
899 | } | ||
900 | EXPORT_SYMBOL(soc_camera_device_register); | ||
901 | |||
902 | void soc_camera_device_unregister(struct soc_camera_device *icd) | ||
903 | { | ||
904 | mutex_lock(&list_lock); | ||
905 | list_del(&icd->list); | ||
906 | |||
907 | /* The bus->remove will be eventually called */ | ||
908 | if (icd->dev.parent) | ||
909 | device_unregister(&icd->dev); | ||
910 | mutex_unlock(&list_lock); | ||
911 | } | ||
912 | EXPORT_SYMBOL(soc_camera_device_unregister); | ||
913 | |||
914 | int soc_camera_video_start(struct soc_camera_device *icd) | ||
915 | { | ||
916 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
917 | int err = -ENOMEM; | ||
918 | struct video_device *vdev; | ||
919 | |||
920 | if (!icd->dev.parent) | ||
921 | return -ENODEV; | ||
922 | |||
923 | vdev = video_device_alloc(); | ||
924 | if (!vdev) | ||
925 | goto evidallocd; | ||
926 | dev_dbg(&ici->dev, "Allocated video_device %p\n", vdev); | ||
927 | |||
928 | strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); | ||
929 | /* Maybe better &ici->dev */ | ||
930 | vdev->dev = &icd->dev; | ||
931 | vdev->type = VID_TYPE_CAPTURE; | ||
932 | vdev->current_norm = V4L2_STD_UNKNOWN; | ||
933 | vdev->fops = &soc_camera_fops; | ||
934 | vdev->release = video_device_release; | ||
935 | vdev->minor = -1; | ||
936 | vdev->tvnorms = V4L2_STD_UNKNOWN, | ||
937 | vdev->vidioc_querycap = soc_camera_querycap; | ||
938 | vdev->vidioc_g_fmt_cap = soc_camera_g_fmt_cap; | ||
939 | vdev->vidioc_enum_fmt_cap = soc_camera_enum_fmt_cap; | ||
940 | vdev->vidioc_s_fmt_cap = soc_camera_s_fmt_cap; | ||
941 | vdev->vidioc_enum_input = soc_camera_enum_input; | ||
942 | vdev->vidioc_g_input = soc_camera_g_input; | ||
943 | vdev->vidioc_s_input = soc_camera_s_input; | ||
944 | vdev->vidioc_s_std = soc_camera_s_std; | ||
945 | vdev->vidioc_reqbufs = soc_camera_reqbufs; | ||
946 | vdev->vidioc_try_fmt_cap = soc_camera_try_fmt_cap; | ||
947 | vdev->vidioc_querybuf = soc_camera_querybuf; | ||
948 | vdev->vidioc_qbuf = soc_camera_qbuf; | ||
949 | vdev->vidioc_dqbuf = soc_camera_dqbuf; | ||
950 | vdev->vidioc_streamon = soc_camera_streamon; | ||
951 | vdev->vidioc_streamoff = soc_camera_streamoff; | ||
952 | vdev->vidioc_queryctrl = soc_camera_queryctrl; | ||
953 | vdev->vidioc_g_ctrl = soc_camera_g_ctrl; | ||
954 | vdev->vidioc_s_ctrl = soc_camera_s_ctrl; | ||
955 | vdev->vidioc_cropcap = soc_camera_cropcap; | ||
956 | vdev->vidioc_g_crop = soc_camera_g_crop; | ||
957 | vdev->vidioc_s_crop = soc_camera_s_crop; | ||
958 | vdev->vidioc_g_chip_ident = soc_camera_g_chip_ident; | ||
959 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
960 | vdev->vidioc_g_register = soc_camera_g_register; | ||
961 | vdev->vidioc_s_register = soc_camera_s_register; | ||
962 | #endif | ||
963 | |||
964 | icd->current_fmt = &icd->formats[0]; | ||
965 | |||
966 | err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor); | ||
967 | if (err < 0) { | ||
968 | dev_err(vdev->dev, "video_register_device failed\n"); | ||
969 | goto evidregd; | ||
970 | } | ||
971 | icd->vdev = vdev; | ||
972 | |||
973 | return 0; | ||
974 | |||
975 | evidregd: | ||
976 | video_device_release(vdev); | ||
977 | evidallocd: | ||
978 | return err; | ||
979 | } | ||
980 | EXPORT_SYMBOL(soc_camera_video_start); | ||
981 | |||
982 | void soc_camera_video_stop(struct soc_camera_device *icd) | ||
983 | { | ||
984 | struct video_device *vdev = icd->vdev; | ||
985 | |||
986 | dev_dbg(&icd->dev, "%s\n", __func__); | ||
987 | |||
988 | if (!icd->dev.parent || !vdev) | ||
989 | return; | ||
990 | |||
991 | mutex_lock(&video_lock); | ||
992 | video_unregister_device(vdev); | ||
993 | icd->vdev = NULL; | ||
994 | mutex_unlock(&video_lock); | ||
995 | } | ||
996 | EXPORT_SYMBOL(soc_camera_video_stop); | ||
997 | |||
998 | static int __init soc_camera_init(void) | ||
999 | { | ||
1000 | int ret = bus_register(&soc_camera_bus_type); | ||
1001 | if (ret) | ||
1002 | return ret; | ||
1003 | ret = driver_register(&ic_drv); | ||
1004 | if (ret) | ||
1005 | goto edrvr; | ||
1006 | ret = class_register(&soc_camera_host_class); | ||
1007 | if (ret) | ||
1008 | goto eclr; | ||
1009 | |||
1010 | return 0; | ||
1011 | |||
1012 | eclr: | ||
1013 | driver_unregister(&ic_drv); | ||
1014 | edrvr: | ||
1015 | bus_unregister(&soc_camera_bus_type); | ||
1016 | return ret; | ||
1017 | } | ||
1018 | |||
1019 | static void __exit soc_camera_exit(void) | ||
1020 | { | ||
1021 | class_unregister(&soc_camera_host_class); | ||
1022 | driver_unregister(&ic_drv); | ||
1023 | bus_unregister(&soc_camera_bus_type); | ||
1024 | } | ||
1025 | |||
1026 | module_init(soc_camera_init); | ||
1027 | module_exit(soc_camera_exit); | ||
1028 | |||
1029 | MODULE_DESCRIPTION("Image capture bus driver"); | ||
1030 | MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); | ||
1031 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index ceba45ad0294..9276ed997388 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c | |||
@@ -1100,7 +1100,7 @@ static int stk_setup_format(struct stk_camera *dev) | |||
1100 | && i < ARRAY_SIZE(stk_sizes)) | 1100 | && i < ARRAY_SIZE(stk_sizes)) |
1101 | i++; | 1101 | i++; |
1102 | if (i == ARRAY_SIZE(stk_sizes)) { | 1102 | if (i == ARRAY_SIZE(stk_sizes)) { |
1103 | STK_ERROR("Something is broken in %s\n", __FUNCTION__); | 1103 | STK_ERROR("Something is broken in %s\n", __func__); |
1104 | return -EFAULT; | 1104 | return -EFAULT; |
1105 | } | 1105 | } |
1106 | /* This registers controls some timings, not sure of what. */ | 1106 | /* This registers controls some timings, not sure of what. */ |
@@ -1465,7 +1465,7 @@ static void stk_camera_disconnect(struct usb_interface *interface) | |||
1465 | } | 1465 | } |
1466 | 1466 | ||
1467 | #ifdef CONFIG_PM | 1467 | #ifdef CONFIG_PM |
1468 | int stk_camera_suspend(struct usb_interface *intf, pm_message_t message) | 1468 | static int stk_camera_suspend(struct usb_interface *intf, pm_message_t message) |
1469 | { | 1469 | { |
1470 | struct stk_camera *dev = usb_get_intfdata(intf); | 1470 | struct stk_camera *dev = usb_get_intfdata(intf); |
1471 | if (is_streaming(dev)) { | 1471 | if (is_streaming(dev)) { |
@@ -1476,7 +1476,7 @@ int stk_camera_suspend(struct usb_interface *intf, pm_message_t message) | |||
1476 | return 0; | 1476 | return 0; |
1477 | } | 1477 | } |
1478 | 1478 | ||
1479 | int stk_camera_resume(struct usb_interface *intf) | 1479 | static int stk_camera_resume(struct usb_interface *intf) |
1480 | { | 1480 | { |
1481 | struct stk_camera *dev = usb_get_intfdata(intf); | 1481 | struct stk_camera *dev = usb_get_intfdata(intf); |
1482 | if (!is_initialised(dev)) | 1482 | if (!is_initialised(dev)) |
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 3fb85af5d1f2..c109511f21ea 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
@@ -58,7 +58,7 @@ | |||
58 | 58 | ||
59 | static struct saa7146 saa7146s[SAA7146_MAX]; | 59 | static struct saa7146 saa7146s[SAA7146_MAX]; |
60 | 60 | ||
61 | static int saa_num = 0; /* number of SAA7146s in use */ | 61 | static int saa_num; /* number of SAA7146s in use */ |
62 | 62 | ||
63 | static int video_nr = -1; | 63 | static int video_nr = -1; |
64 | module_param(video_nr, int, 0); | 64 | module_param(video_nr, int, 0); |
@@ -248,7 +248,7 @@ static void I2CBusScan(struct saa7146 *saa) | |||
248 | attach_inform(saa, i); | 248 | attach_inform(saa, i); |
249 | } | 249 | } |
250 | 250 | ||
251 | static int debiwait_maxwait = 0; | 251 | static int debiwait_maxwait; |
252 | 252 | ||
253 | static int wait_for_debi_done(struct saa7146 *saa) | 253 | static int wait_for_debi_done(struct saa7146 *saa) |
254 | { | 254 | { |
@@ -1906,7 +1906,9 @@ static const struct file_operations saa_fops = { | |||
1906 | .open = saa_open, | 1906 | .open = saa_open, |
1907 | .release = saa_release, | 1907 | .release = saa_release, |
1908 | .ioctl = saa_ioctl, | 1908 | .ioctl = saa_ioctl, |
1909 | #ifdef CONFIG_COMPAT | ||
1909 | .compat_ioctl = v4l_compat_ioctl32, | 1910 | .compat_ioctl = v4l_compat_ioctl32, |
1911 | #endif | ||
1910 | .read = saa_read, | 1912 | .read = saa_read, |
1911 | .llseek = no_llseek, | 1913 | .llseek = no_llseek, |
1912 | .write = saa_write, | 1914 | .write = saa_write, |
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index afc32aa56fde..d7f130bedb5f 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c | |||
@@ -72,15 +72,18 @@ | |||
72 | #include "stv680.h" | 72 | #include "stv680.h" |
73 | 73 | ||
74 | static int video_nr = -1; | 74 | static int video_nr = -1; |
75 | static int swapRGB = 0; /* default for auto sleect */ | ||
76 | static int swapRGB_on = 0; /* default to allow auto select; -1=swap never, +1= swap always */ | ||
77 | 75 | ||
78 | static unsigned int debug = 0; | 76 | static int swapRGB; /* 0 = default for auto select */ |
77 | |||
78 | /* 0 = default to allow auto select; -1 = swap never, +1 = swap always */ | ||
79 | static int swapRGB_on; | ||
80 | |||
81 | static unsigned int debug; | ||
79 | 82 | ||
80 | #define PDEBUG(level, fmt, args...) \ | 83 | #define PDEBUG(level, fmt, args...) \ |
81 | do { \ | 84 | do { \ |
82 | if (debug >= level) \ | 85 | if (debug >= level) \ |
83 | info("[%s:%d] " fmt, __FUNCTION__, __LINE__ , ## args); \ | 86 | info("[%s:%d] " fmt, __func__, __LINE__ , ## args); \ |
84 | } while (0) | 87 | } while (0) |
85 | 88 | ||
86 | 89 | ||
@@ -1391,7 +1394,9 @@ static const struct file_operations stv680_fops = { | |||
1391 | .read = stv680_read, | 1394 | .read = stv680_read, |
1392 | .mmap = stv680_mmap, | 1395 | .mmap = stv680_mmap, |
1393 | .ioctl = stv680_ioctl, | 1396 | .ioctl = stv680_ioctl, |
1397 | #ifdef CONFIG_COMPAT | ||
1394 | .compat_ioctl = v4l_compat_ioctl32, | 1398 | .compat_ioctl = v4l_compat_ioctl32, |
1399 | #endif | ||
1395 | .llseek = no_llseek, | 1400 | .llseek = no_llseek, |
1396 | }; | 1401 | }; |
1397 | static struct video_device stv680_template = { | 1402 | static struct video_device stv680_template = { |
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c index fb895f6684a3..6943b447a1bd 100644 --- a/drivers/media/video/tcm825x.c +++ b/drivers/media/video/tcm825x.c | |||
@@ -906,7 +906,7 @@ static int __init tcm825x_init(void) | |||
906 | rval = i2c_add_driver(&tcm825x_i2c_driver); | 906 | rval = i2c_add_driver(&tcm825x_i2c_driver); |
907 | if (rval) | 907 | if (rval) |
908 | printk(KERN_INFO "%s: failed registering " TCM825X_NAME "\n", | 908 | printk(KERN_INFO "%s: failed registering " TCM825X_NAME "\n", |
909 | __FUNCTION__); | 909 | __func__); |
910 | 910 | ||
911 | return rval; | 911 | return rval; |
912 | } | 912 | } |
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index 55bc89a6f069..0ebb5b525e57 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c | |||
@@ -32,8 +32,6 @@ static int debug; | |||
32 | module_param(debug, int, 0644); | 32 | module_param(debug, int, 0644); |
33 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | 33 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); |
34 | 34 | ||
35 | #define PREFIX "tda8290" | ||
36 | |||
37 | /* ---------------------------------------------------------------------- */ | 35 | /* ---------------------------------------------------------------------- */ |
38 | 36 | ||
39 | struct tda8290_priv { | 37 | struct tda8290_priv { |
@@ -174,7 +172,7 @@ static void tda8290_set_params(struct dvb_frontend *fe, | |||
174 | set_audio(fe, params); | 172 | set_audio(fe, params); |
175 | 173 | ||
176 | if (priv->cfg.config) | 174 | if (priv->cfg.config) |
177 | tuner_dbg("tda827xa config is 0x%02x\n", *priv->cfg.config); | 175 | tuner_dbg("tda827xa config is 0x%02x\n", priv->cfg.config); |
178 | tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2); | 176 | tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2); |
179 | tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2); | 177 | tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2); |
180 | tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2); | 178 | tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2); |
@@ -365,7 +363,7 @@ static void tda8295_set_params(struct dvb_frontend *fe, | |||
365 | 363 | ||
366 | set_audio(fe, params); | 364 | set_audio(fe, params); |
367 | 365 | ||
368 | tuner_dbg("%s: freq = %d\n", __FUNCTION__, params->frequency); | 366 | tuner_dbg("%s: freq = %d\n", __func__, params->frequency); |
369 | 367 | ||
370 | tda8295_power(fe, 1); | 368 | tda8295_power(fe, 1); |
371 | tda8295_agc1_out(fe, 1); | 369 | tda8295_agc1_out(fe, 1); |
@@ -444,8 +442,7 @@ static void tda8290_init_if(struct dvb_frontend *fe) | |||
444 | unsigned char set_GP00_CF[] = { 0x20, 0x01 }; | 442 | unsigned char set_GP00_CF[] = { 0x20, 0x01 }; |
445 | unsigned char set_GP01_CF[] = { 0x20, 0x0B }; | 443 | unsigned char set_GP01_CF[] = { 0x20, 0x0B }; |
446 | 444 | ||
447 | if ((priv->cfg.config) && | 445 | if ((priv->cfg.config == 1) || (priv->cfg.config == 2)) |
448 | ((*priv->cfg.config == 1) || (*priv->cfg.config == 2))) | ||
449 | tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2); | 446 | tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2); |
450 | else | 447 | else |
451 | tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2); | 448 | tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2); |
@@ -590,8 +587,8 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) | |||
590 | else | 587 | else |
591 | priv->ver |= TDA8275A; | 588 | priv->ver |= TDA8275A; |
592 | 589 | ||
593 | tda827x_attach(fe, priv->tda827x_addr, | 590 | tda827x_attach(fe, priv->tda827x_addr, priv->i2c_props.adap, &priv->cfg); |
594 | priv->i2c_props.adap, &priv->cfg); | 591 | priv->cfg.switch_addr = priv->i2c_props.addr; |
595 | } | 592 | } |
596 | if (fe->ops.tuner_ops.init) | 593 | if (fe->ops.tuner_ops.init) |
597 | fe->ops.tuner_ops.init(fe); | 594 | fe->ops.tuner_ops.init(fe); |
@@ -616,7 +613,7 @@ static int tda8290_probe(struct tuner_i2c_props *i2c_props) | |||
616 | if (tda8290_id[1] == TDA8290_ID) { | 613 | if (tda8290_id[1] == TDA8290_ID) { |
617 | if (debug) | 614 | if (debug) |
618 | printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", | 615 | printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", |
619 | __FUNCTION__, i2c_adapter_id(i2c_props->adap), | 616 | __func__, i2c_adapter_id(i2c_props->adap), |
620 | i2c_props->addr); | 617 | i2c_props->addr); |
621 | return 0; | 618 | return 0; |
622 | } | 619 | } |
@@ -636,7 +633,7 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props) | |||
636 | if (tda8295_id[1] == TDA8295_ID) { | 633 | if (tda8295_id[1] == TDA8295_ID) { |
637 | if (debug) | 634 | if (debug) |
638 | printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n", | 635 | printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n", |
639 | __FUNCTION__, i2c_adapter_id(i2c_props->adap), | 636 | __func__, i2c_adapter_id(i2c_props->adap), |
640 | i2c_props->addr); | 637 | i2c_props->addr); |
641 | return 0; | 638 | return 0; |
642 | } | 639 | } |
@@ -674,6 +671,7 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, | |||
674 | 671 | ||
675 | priv->i2c_props.addr = i2c_addr; | 672 | priv->i2c_props.addr = i2c_addr; |
676 | priv->i2c_props.adap = i2c_adap; | 673 | priv->i2c_props.adap = i2c_adap; |
674 | priv->i2c_props.name = "tda829x"; | ||
677 | if (cfg) { | 675 | if (cfg) { |
678 | priv->cfg.config = cfg->lna_cfg; | 676 | priv->cfg.config = cfg->lna_cfg; |
679 | priv->cfg.tuner_callback = cfg->tuner_callback; | 677 | priv->cfg.tuner_callback = cfg->tuner_callback; |
diff --git a/drivers/media/video/tda8290.h b/drivers/media/video/tda8290.h index dc8ef310b7b2..d3bbf276a469 100644 --- a/drivers/media/video/tda8290.h +++ b/drivers/media/video/tda8290.h | |||
@@ -21,7 +21,7 @@ | |||
21 | #include "dvb_frontend.h" | 21 | #include "dvb_frontend.h" |
22 | 22 | ||
23 | struct tda829x_config { | 23 | struct tda829x_config { |
24 | unsigned int *lna_cfg; | 24 | unsigned int lna_cfg; |
25 | int (*tuner_callback) (void *dev, int command, int arg); | 25 | int (*tuner_callback) (void *dev, int command, int arg); |
26 | 26 | ||
27 | unsigned int probe_tuner:1; | 27 | unsigned int probe_tuner:1; |
@@ -39,7 +39,7 @@ extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, | |||
39 | #else | 39 | #else |
40 | static inline int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) | 40 | static inline int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) |
41 | { | 41 | { |
42 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | 42 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
43 | return -EINVAL; | 43 | return -EINVAL; |
44 | } | 44 | } |
45 | 45 | ||
@@ -49,7 +49,7 @@ static inline struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, | |||
49 | struct tda829x_config *cfg) | 49 | struct tda829x_config *cfg) |
50 | { | 50 | { |
51 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", | 51 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", |
52 | __FUNCTION__); | 52 | __func__); |
53 | return NULL; | 53 | return NULL; |
54 | } | 54 | } |
55 | #endif | 55 | #endif |
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index bdca5d278978..0cee00242782 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c | |||
@@ -31,11 +31,11 @@ | |||
31 | 31 | ||
32 | #include "tda9840.h" | 32 | #include "tda9840.h" |
33 | 33 | ||
34 | static int debug = 0; /* insmod parameter */ | 34 | static int debug; /* insmod parameter */ |
35 | module_param(debug, int, 0644); | 35 | module_param(debug, int, 0644); |
36 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | 36 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); |
37 | #define dprintk(args...) \ | 37 | #define dprintk(args...) \ |
38 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) | 38 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) |
39 | 39 | ||
40 | #define SWITCH 0x00 | 40 | #define SWITCH 0x00 |
41 | #define LEVEL_ADJUST 0x02 | 41 | #define LEVEL_ADJUST 0x02 |
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 106c93b8203f..a0545ba957b0 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c | |||
@@ -25,10 +25,12 @@ static int debug; | |||
25 | module_param(debug, int, 0644); | 25 | module_param(debug, int, 0644); |
26 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | 26 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); |
27 | 27 | ||
28 | #define PREFIX "tda9887" | 28 | static DEFINE_MUTEX(tda9887_list_mutex); |
29 | static LIST_HEAD(hybrid_tuner_instance_list); | ||
29 | 30 | ||
30 | struct tda9887_priv { | 31 | struct tda9887_priv { |
31 | struct tuner_i2c_props i2c_props; | 32 | struct tuner_i2c_props i2c_props; |
33 | struct list_head hybrid_tuner_instance_list; | ||
32 | 34 | ||
33 | unsigned char data[4]; | 35 | unsigned char data[4]; |
34 | unsigned int config; | 36 | unsigned int config; |
@@ -644,7 +646,15 @@ static int tda9887_set_config(struct dvb_frontend *fe, void *priv_cfg) | |||
644 | 646 | ||
645 | static void tda9887_release(struct dvb_frontend *fe) | 647 | static void tda9887_release(struct dvb_frontend *fe) |
646 | { | 648 | { |
647 | kfree(fe->analog_demod_priv); | 649 | struct tda9887_priv *priv = fe->analog_demod_priv; |
650 | |||
651 | mutex_lock(&tda9887_list_mutex); | ||
652 | |||
653 | if (priv) | ||
654 | hybrid_tuner_release_state(priv); | ||
655 | |||
656 | mutex_unlock(&tda9887_list_mutex); | ||
657 | |||
648 | fe->analog_demod_priv = NULL; | 658 | fe->analog_demod_priv = NULL; |
649 | } | 659 | } |
650 | 660 | ||
@@ -665,17 +675,29 @@ struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, | |||
665 | u8 i2c_addr) | 675 | u8 i2c_addr) |
666 | { | 676 | { |
667 | struct tda9887_priv *priv = NULL; | 677 | struct tda9887_priv *priv = NULL; |
678 | int instance; | ||
668 | 679 | ||
669 | priv = kzalloc(sizeof(struct tda9887_priv), GFP_KERNEL); | 680 | mutex_lock(&tda9887_list_mutex); |
670 | if (priv == NULL) | ||
671 | return NULL; | ||
672 | fe->analog_demod_priv = priv; | ||
673 | 681 | ||
674 | priv->i2c_props.addr = i2c_addr; | 682 | instance = hybrid_tuner_request_state(struct tda9887_priv, priv, |
675 | priv->i2c_props.adap = i2c_adap; | 683 | hybrid_tuner_instance_list, |
676 | priv->mode = T_STANDBY; | 684 | i2c_adap, i2c_addr, "tda9887"); |
685 | switch (instance) { | ||
686 | case 0: | ||
687 | mutex_unlock(&tda9887_list_mutex); | ||
688 | return NULL; | ||
689 | break; | ||
690 | case 1: | ||
691 | fe->analog_demod_priv = priv; | ||
692 | priv->mode = T_STANDBY; | ||
693 | tuner_info("tda988[5/6/7] found\n"); | ||
694 | break; | ||
695 | default: | ||
696 | fe->analog_demod_priv = priv; | ||
697 | break; | ||
698 | } | ||
677 | 699 | ||
678 | tuner_info("tda988[5/6/7] found\n"); | 700 | mutex_unlock(&tda9887_list_mutex); |
679 | 701 | ||
680 | memcpy(&fe->ops.analog_ops, &tda9887_ops, | 702 | memcpy(&fe->ops.analog_ops, &tda9887_ops, |
681 | sizeof(struct analog_demod_ops)); | 703 | sizeof(struct analog_demod_ops)); |
diff --git a/drivers/media/video/tda9887.h b/drivers/media/video/tda9887.h index 8f873a8e6ed2..be49dcbfc70e 100644 --- a/drivers/media/video/tda9887.h +++ b/drivers/media/video/tda9887.h | |||
@@ -30,7 +30,7 @@ static inline struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, | |||
30 | struct i2c_adapter *i2c_adap, | 30 | struct i2c_adapter *i2c_adap, |
31 | u8 i2c_addr) | 31 | u8 i2c_addr) |
32 | { | 32 | { |
33 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | 33 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
34 | return NULL; | 34 | return NULL; |
35 | } | 35 | } |
36 | #endif | 36 | #endif |
diff --git a/drivers/media/video/tea5761.c b/drivers/media/video/tea5761.c index 5326eeceaacd..b93cdef9ac73 100644 --- a/drivers/media/video/tea5761.c +++ b/drivers/media/video/tea5761.c | |||
@@ -14,12 +14,10 @@ | |||
14 | #include "tuner-i2c.h" | 14 | #include "tuner-i2c.h" |
15 | #include "tea5761.h" | 15 | #include "tea5761.h" |
16 | 16 | ||
17 | static int debug = 0; | 17 | static int debug; |
18 | module_param(debug, int, 0644); | 18 | module_param(debug, int, 0644); |
19 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | 19 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); |
20 | 20 | ||
21 | #define PREFIX "tea5761" | ||
22 | |||
23 | struct tea5761_priv { | 21 | struct tea5761_priv { |
24 | struct tuner_i2c_props i2c_props; | 22 | struct tuner_i2c_props i2c_props; |
25 | 23 | ||
@@ -131,7 +129,7 @@ static void tea5761_status_dump(unsigned char *buffer) | |||
131 | 129 | ||
132 | frq = 1000 * (div * 32768 / 1000 + FREQ_OFFSET + 225) / 4; /* Freq in KHz */ | 130 | frq = 1000 * (div * 32768 / 1000 + FREQ_OFFSET + 225) / 4; /* Freq in KHz */ |
133 | 131 | ||
134 | printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n", | 132 | printk(KERN_INFO "tea5761: Frequency %d.%03d KHz (divider = 0x%04x)\n", |
135 | frq / 1000, frq % 1000, div); | 133 | frq / 1000, frq % 1000, div); |
136 | } | 134 | } |
137 | 135 | ||
@@ -249,14 +247,19 @@ int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) | |||
249 | 247 | ||
250 | if (16 != (rc = tuner_i2c_xfer_recv(&i2c, buffer, 16))) { | 248 | if (16 != (rc = tuner_i2c_xfer_recv(&i2c, buffer, 16))) { |
251 | printk(KERN_WARNING "it is not a TEA5761. Received %i chars.\n", rc); | 249 | printk(KERN_WARNING "it is not a TEA5761. Received %i chars.\n", rc); |
252 | return EINVAL; | 250 | return -EINVAL; |
253 | } | 251 | } |
254 | 252 | ||
255 | if (!((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061))) { | 253 | if ((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061)) { |
256 | printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x. It is not a TEA5761\n",buffer[13],buffer[14],buffer[15]); | 254 | printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x." |
257 | return EINVAL; | 255 | " It is not a TEA5761\n", |
256 | buffer[13], buffer[14], buffer[15]); | ||
257 | return -EINVAL; | ||
258 | } | 258 | } |
259 | printk(KERN_WARNING "TEA5761 detected.\n"); | 259 | printk(KERN_WARNING "tea5761: TEA%02x%02x detected. " |
260 | "Manufacturer ID= 0x%02x\n", | ||
261 | buffer[14], buffer[15], buffer[13]); | ||
262 | |||
260 | return 0; | 263 | return 0; |
261 | } | 264 | } |
262 | 265 | ||
@@ -302,6 +305,7 @@ struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, | |||
302 | 305 | ||
303 | priv->i2c_props.addr = i2c_addr; | 306 | priv->i2c_props.addr = i2c_addr; |
304 | priv->i2c_props.adap = i2c_adap; | 307 | priv->i2c_props.adap = i2c_adap; |
308 | priv->i2c_props.name = "tea5761"; | ||
305 | 309 | ||
306 | memcpy(&fe->ops.tuner_ops, &tea5761_tuner_ops, | 310 | memcpy(&fe->ops.tuner_ops, &tea5761_tuner_ops, |
307 | sizeof(struct dvb_tuner_ops)); | 311 | sizeof(struct dvb_tuner_ops)); |
diff --git a/drivers/media/video/tea5761.h b/drivers/media/video/tea5761.h index 73a03b427843..8eb62722b988 100644 --- a/drivers/media/video/tea5761.h +++ b/drivers/media/video/tea5761.h | |||
@@ -31,7 +31,7 @@ static inline int tea5761_autodetection(struct i2c_adapter* i2c_adap, | |||
31 | u8 i2c_addr) | 31 | u8 i2c_addr) |
32 | { | 32 | { |
33 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", | 33 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", |
34 | __FUNCTION__); | 34 | __func__); |
35 | return -EINVAL; | 35 | return -EINVAL; |
36 | } | 36 | } |
37 | 37 | ||
@@ -39,7 +39,7 @@ static inline struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, | |||
39 | struct i2c_adapter* i2c_adap, | 39 | struct i2c_adapter* i2c_adap, |
40 | u8 i2c_addr) | 40 | u8 i2c_addr) |
41 | { | 41 | { |
42 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | 42 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
43 | return NULL; | 43 | return NULL; |
44 | } | 44 | } |
45 | #endif | 45 | #endif |
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c index e1b48d87e7b7..f6e7d7ad8424 100644 --- a/drivers/media/video/tea5767.c +++ b/drivers/media/video/tea5767.c | |||
@@ -16,12 +16,10 @@ | |||
16 | #include "tuner-i2c.h" | 16 | #include "tuner-i2c.h" |
17 | #include "tea5767.h" | 17 | #include "tea5767.h" |
18 | 18 | ||
19 | static int debug = 0; | 19 | static int debug; |
20 | module_param(debug, int, 0644); | 20 | module_param(debug, int, 0644); |
21 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | 21 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); |
22 | 22 | ||
23 | #define PREFIX "tea5767" | ||
24 | |||
25 | /*****************************************************************************/ | 23 | /*****************************************************************************/ |
26 | 24 | ||
27 | struct tea5767_priv { | 25 | struct tea5767_priv { |
@@ -137,14 +135,14 @@ static void tea5767_status_dump(struct tea5767_priv *priv, | |||
137 | unsigned int div, frq; | 135 | unsigned int div, frq; |
138 | 136 | ||
139 | if (TEA5767_READY_FLAG_MASK & buffer[0]) | 137 | if (TEA5767_READY_FLAG_MASK & buffer[0]) |
140 | printk(PREFIX "Ready Flag ON\n"); | 138 | tuner_info("Ready Flag ON\n"); |
141 | else | 139 | else |
142 | printk(PREFIX "Ready Flag OFF\n"); | 140 | tuner_info("Ready Flag OFF\n"); |
143 | 141 | ||
144 | if (TEA5767_BAND_LIMIT_MASK & buffer[0]) | 142 | if (TEA5767_BAND_LIMIT_MASK & buffer[0]) |
145 | printk(PREFIX "Tuner at band limit\n"); | 143 | tuner_info("Tuner at band limit\n"); |
146 | else | 144 | else |
147 | printk(PREFIX "Tuner not at band limit\n"); | 145 | tuner_info("Tuner not at band limit\n"); |
148 | 146 | ||
149 | div = ((buffer[0] & 0x3f) << 8) | buffer[1]; | 147 | div = ((buffer[0] & 0x3f) << 8) | buffer[1]; |
150 | 148 | ||
@@ -166,23 +164,23 @@ static void tea5767_status_dump(struct tea5767_priv *priv, | |||
166 | buffer[0] = (div >> 8) & 0x3f; | 164 | buffer[0] = (div >> 8) & 0x3f; |
167 | buffer[1] = div & 0xff; | 165 | buffer[1] = div & 0xff; |
168 | 166 | ||
169 | printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n", | 167 | tuner_info("Frequency %d.%03d KHz (divider = 0x%04x)\n", |
170 | frq / 1000, frq % 1000, div); | 168 | frq / 1000, frq % 1000, div); |
171 | 169 | ||
172 | if (TEA5767_STEREO_MASK & buffer[2]) | 170 | if (TEA5767_STEREO_MASK & buffer[2]) |
173 | printk(PREFIX "Stereo\n"); | 171 | tuner_info("Stereo\n"); |
174 | else | 172 | else |
175 | printk(PREFIX "Mono\n"); | 173 | tuner_info("Mono\n"); |
176 | 174 | ||
177 | printk(PREFIX "IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK); | 175 | tuner_info("IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK); |
178 | 176 | ||
179 | printk(PREFIX "ADC Level = %d\n", | 177 | tuner_info("ADC Level = %d\n", |
180 | (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4); | 178 | (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4); |
181 | 179 | ||
182 | printk(PREFIX "Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK)); | 180 | tuner_info("Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK)); |
183 | 181 | ||
184 | printk(PREFIX "Reserved = 0x%02x\n", | 182 | tuner_info("Reserved = 0x%02x\n", |
185 | (buffer[4] & TEA5767_RESERVED_MASK)); | 183 | (buffer[4] & TEA5767_RESERVED_MASK)); |
186 | } | 184 | } |
187 | 185 | ||
188 | /* Freq should be specifyed at 62.5 Hz */ | 186 | /* Freq should be specifyed at 62.5 Hz */ |
@@ -395,11 +393,6 @@ int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) | |||
395 | return EINVAL; | 393 | return EINVAL; |
396 | } | 394 | } |
397 | 395 | ||
398 | /* It seems that tea5767 returns 0xff after the 5th byte */ | ||
399 | if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) { | ||
400 | printk(KERN_WARNING "Returned more than 5 bytes. It is not a TEA5767\n"); | ||
401 | return EINVAL; | ||
402 | } | ||
403 | 396 | ||
404 | return 0; | 397 | return 0; |
405 | } | 398 | } |
@@ -456,6 +449,8 @@ struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, | |||
456 | 449 | ||
457 | priv->i2c_props.addr = i2c_addr; | 450 | priv->i2c_props.addr = i2c_addr; |
458 | priv->i2c_props.adap = i2c_adap; | 451 | priv->i2c_props.adap = i2c_adap; |
452 | priv->i2c_props.name = "tea5767"; | ||
453 | |||
459 | priv->ctrl.xtal_freq = TEA5767_HIGH_LO_32768; | 454 | priv->ctrl.xtal_freq = TEA5767_HIGH_LO_32768; |
460 | priv->ctrl.port1 = 1; | 455 | priv->ctrl.port1 = 1; |
461 | priv->ctrl.port2 = 1; | 456 | priv->ctrl.port2 = 1; |
diff --git a/drivers/media/video/tea5767.h b/drivers/media/video/tea5767.h index a44451f61145..7b547c092e25 100644 --- a/drivers/media/video/tea5767.h +++ b/drivers/media/video/tea5767.h | |||
@@ -50,7 +50,7 @@ static inline int tea5767_autodetection(struct i2c_adapter* i2c_adap, | |||
50 | u8 i2c_addr) | 50 | u8 i2c_addr) |
51 | { | 51 | { |
52 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", | 52 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", |
53 | __FUNCTION__); | 53 | __func__); |
54 | return -EINVAL; | 54 | return -EINVAL; |
55 | } | 55 | } |
56 | 56 | ||
@@ -58,7 +58,7 @@ static inline struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, | |||
58 | struct i2c_adapter* i2c_adap, | 58 | struct i2c_adapter* i2c_adap, |
59 | u8 i2c_addr) | 59 | u8 i2c_addr) |
60 | { | 60 | { |
61 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | 61 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
62 | return NULL; | 62 | return NULL; |
63 | } | 63 | } |
64 | #endif | 64 | #endif |
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index df2fad9f391e..9513d8611e87 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c | |||
@@ -33,11 +33,11 @@ | |||
33 | 33 | ||
34 | #include "tea6415c.h" | 34 | #include "tea6415c.h" |
35 | 35 | ||
36 | static int debug = 0; /* insmod parameter */ | 36 | static int debug; /* insmod parameter */ |
37 | module_param(debug, int, 0644); | 37 | module_param(debug, int, 0644); |
38 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | 38 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); |
39 | #define dprintk(args...) \ | 39 | #define dprintk(args...) \ |
40 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) | 40 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) |
41 | 41 | ||
42 | #define TEA6415C_NUM_INPUTS 8 | 42 | #define TEA6415C_NUM_INPUTS 8 |
43 | #define TEA6415C_NUM_OUTPUTS 6 | 43 | #define TEA6415C_NUM_OUTPUTS 6 |
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 4ff6c63f7237..7fd53367c07c 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c | |||
@@ -33,11 +33,11 @@ | |||
33 | 33 | ||
34 | #include "tea6420.h" | 34 | #include "tea6420.h" |
35 | 35 | ||
36 | static int debug = 0; /* insmod parameter */ | 36 | static int debug; /* insmod parameter */ |
37 | module_param(debug, int, 0644); | 37 | module_param(debug, int, 0644); |
38 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | 38 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); |
39 | #define dprintk(args...) \ | 39 | #define dprintk(args...) \ |
40 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) | 40 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) |
41 | 41 | ||
42 | /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ | 42 | /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ |
43 | static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END }; | 43 | static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END }; |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 78a09a2a4857..529e00952a8d 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -68,9 +68,9 @@ static unsigned short normal_i2c[] = { | |||
68 | I2C_CLIENT_INSMOD; | 68 | I2C_CLIENT_INSMOD; |
69 | 69 | ||
70 | /* insmod options used at init time => read/only */ | 70 | /* insmod options used at init time => read/only */ |
71 | static unsigned int addr = 0; | 71 | static unsigned int addr; |
72 | static unsigned int no_autodetect = 0; | 72 | static unsigned int no_autodetect; |
73 | static unsigned int show_i2c = 0; | 73 | static unsigned int show_i2c; |
74 | 74 | ||
75 | /* insmod options used at runtime => read/write */ | 75 | /* insmod options used at runtime => read/write */ |
76 | static int tuner_debug; | 76 | static int tuner_debug; |
@@ -313,24 +313,14 @@ static void tuner_i2c_address_check(struct tuner *t) | |||
313 | tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n"); | 313 | tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n"); |
314 | tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n"); | 314 | tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n"); |
315 | tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n", | 315 | tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n", |
316 | t->i2c->adapter->name, t->i2c->addr, t->type, | 316 | t->i2c->adapter->name, t->i2c->addr, t->type, t->i2c->name); |
317 | tuners[t->type].name); | ||
318 | tuner_warn("====================== WARNING! ======================\n"); | 317 | tuner_warn("====================== WARNING! ======================\n"); |
319 | } | 318 | } |
320 | 319 | ||
321 | static void attach_simple_tuner(struct tuner *t) | ||
322 | { | ||
323 | struct simple_tuner_config cfg = { | ||
324 | .type = t->type, | ||
325 | .tun = &tuners[t->type] | ||
326 | }; | ||
327 | simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg); | ||
328 | } | ||
329 | |||
330 | static void attach_tda829x(struct tuner *t) | 320 | static void attach_tda829x(struct tuner *t) |
331 | { | 321 | { |
332 | struct tda829x_config cfg = { | 322 | struct tda829x_config cfg = { |
333 | .lna_cfg = &t->config, | 323 | .lna_cfg = t->config, |
334 | .tuner_callback = t->tuner_callback, | 324 | .tuner_callback = t->tuner_callback, |
335 | }; | 325 | }; |
336 | tda829x_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg); | 326 | tda829x_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg); |
@@ -352,11 +342,6 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
352 | return; | 342 | return; |
353 | } | 343 | } |
354 | 344 | ||
355 | if (type >= tuner_count) { | ||
356 | tuner_warn ("tuner 0x%02x: Tuner count greater than %d\n",c->addr,tuner_count); | ||
357 | return; | ||
358 | } | ||
359 | |||
360 | t->type = type; | 345 | t->type = type; |
361 | t->config = new_config; | 346 | t->config = new_config; |
362 | if (tuner_callback != NULL) { | 347 | if (tuner_callback != NULL) { |
@@ -409,7 +394,12 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
409 | buffer[2] = 0x86; | 394 | buffer[2] = 0x86; |
410 | buffer[3] = 0x54; | 395 | buffer[3] = 0x54; |
411 | i2c_master_send(c, buffer, 4); | 396 | i2c_master_send(c, buffer, 4); |
412 | attach_simple_tuner(t); | 397 | if (simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, |
398 | t->type) == NULL) { | ||
399 | t->type = TUNER_ABSENT; | ||
400 | t->mode_mask = T_UNINITIALIZED; | ||
401 | return; | ||
402 | } | ||
413 | break; | 403 | break; |
414 | case TUNER_PHILIPS_TD1316: | 404 | case TUNER_PHILIPS_TD1316: |
415 | buffer[0] = 0x0b; | 405 | buffer[0] = 0x0b; |
@@ -417,14 +407,18 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
417 | buffer[2] = 0x86; | 407 | buffer[2] = 0x86; |
418 | buffer[3] = 0xa4; | 408 | buffer[3] = 0xa4; |
419 | i2c_master_send(c,buffer,4); | 409 | i2c_master_send(c,buffer,4); |
420 | attach_simple_tuner(t); | 410 | if (simple_tuner_attach(&t->fe, t->i2c->adapter, |
411 | t->i2c->addr, t->type) == NULL) { | ||
412 | t->type = TUNER_ABSENT; | ||
413 | t->mode_mask = T_UNINITIALIZED; | ||
414 | return; | ||
415 | } | ||
421 | break; | 416 | break; |
422 | case TUNER_XC2028: | 417 | case TUNER_XC2028: |
423 | { | 418 | { |
424 | struct xc2028_config cfg = { | 419 | struct xc2028_config cfg = { |
425 | .i2c_adap = t->i2c->adapter, | 420 | .i2c_adap = t->i2c->adapter, |
426 | .i2c_addr = t->i2c->addr, | 421 | .i2c_addr = t->i2c->addr, |
427 | .video_dev = c->adapter->algo_data, | ||
428 | .callback = t->tuner_callback, | 422 | .callback = t->tuner_callback, |
429 | }; | 423 | }; |
430 | if (!xc2028_attach(&t->fe, &cfg)) { | 424 | if (!xc2028_attach(&t->fe, &cfg)) { |
@@ -455,7 +449,12 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
455 | } | 449 | } |
456 | break; | 450 | break; |
457 | default: | 451 | default: |
458 | attach_simple_tuner(t); | 452 | if (simple_tuner_attach(&t->fe, t->i2c->adapter, |
453 | t->i2c->addr, t->type) == NULL) { | ||
454 | t->type = TUNER_ABSENT; | ||
455 | t->mode_mask = T_UNINITIALIZED; | ||
456 | return; | ||
457 | } | ||
459 | break; | 458 | break; |
460 | } | 459 | } |
461 | 460 | ||
@@ -759,7 +758,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
759 | if (analog_ops->standby) | 758 | if (analog_ops->standby) |
760 | analog_ops->standby(&t->fe); | 759 | analog_ops->standby(&t->fe); |
761 | break; | 760 | break; |
762 | #ifdef CONFIG_VIDEO_V4L1 | 761 | #ifdef CONFIG_VIDEO_ALLOW_V4L1 |
763 | case VIDIOCSAUDIO: | 762 | case VIDIOCSAUDIO: |
764 | if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) | 763 | if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) |
765 | return 0; | 764 | return 0; |
@@ -1112,8 +1111,8 @@ static int tuner_probe(struct i2c_client *client) | |||
1112 | if (!no_autodetect) { | 1111 | if (!no_autodetect) { |
1113 | switch (client->addr) { | 1112 | switch (client->addr) { |
1114 | case 0x10: | 1113 | case 0x10: |
1115 | if (tea5761_autodetection(t->i2c->adapter, t->i2c->addr) | 1114 | if (tea5761_autodetection(t->i2c->adapter, |
1116 | != EINVAL) { | 1115 | t->i2c->addr) >= 0) { |
1117 | t->type = TUNER_TEA5761; | 1116 | t->type = TUNER_TEA5761; |
1118 | t->mode_mask = T_RADIO; | 1117 | t->mode_mask = T_RADIO; |
1119 | t->mode = T_STANDBY; | 1118 | t->mode = T_STANDBY; |
@@ -1125,7 +1124,7 @@ static int tuner_probe(struct i2c_client *client) | |||
1125 | 1124 | ||
1126 | goto register_client; | 1125 | goto register_client; |
1127 | } | 1126 | } |
1128 | break; | 1127 | return -ENODEV; |
1129 | case 0x42: | 1128 | case 0x42: |
1130 | case 0x43: | 1129 | case 0x43: |
1131 | case 0x4a: | 1130 | case 0x4a: |
diff --git a/drivers/media/video/tuner-i2c.h b/drivers/media/video/tuner-i2c.h index de52e8ffd347..3ad6c8e0b04c 100644 --- a/drivers/media/video/tuner-i2c.h +++ b/drivers/media/video/tuner-i2c.h | |||
@@ -26,6 +26,10 @@ | |||
26 | struct tuner_i2c_props { | 26 | struct tuner_i2c_props { |
27 | u8 addr; | 27 | u8 addr; |
28 | struct i2c_adapter *adap; | 28 | struct i2c_adapter *adap; |
29 | |||
30 | /* used for tuner instance management */ | ||
31 | int count; | ||
32 | char *name; | ||
29 | }; | 33 | }; |
30 | 34 | ||
31 | static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len) | 35 | static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len) |
@@ -59,29 +63,111 @@ static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props, | |||
59 | return (ret == 2) ? ilen : ret; | 63 | return (ret == 2) ? ilen : ret; |
60 | } | 64 | } |
61 | 65 | ||
62 | #define tuner_warn(fmt, arg...) do { \ | 66 | /* Callers must declare as a global for the module: |
63 | printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \ | 67 | * |
64 | i2c_adapter_id(priv->i2c_props.adap), \ | 68 | * static LIST_HEAD(hybrid_tuner_instance_list); |
65 | priv->i2c_props.addr, ##arg); \ | 69 | * |
70 | * hybrid_tuner_instance_list should be the third argument | ||
71 | * passed into hybrid_tuner_request_state(). | ||
72 | * | ||
73 | * state structure must contain the following: | ||
74 | * | ||
75 | * struct list_head hybrid_tuner_instance_list; | ||
76 | * struct tuner_i2c_props i2c_props; | ||
77 | * | ||
78 | * hybrid_tuner_instance_list (both within state structure and globally) | ||
79 | * is only required if the driver is using hybrid_tuner_request_state | ||
80 | * and hybrid_tuner_release_state to manage state sharing between | ||
81 | * multiple instances of hybrid tuners. | ||
82 | */ | ||
83 | |||
84 | #define tuner_printk(kernlvl, i2cprops, fmt, arg...) do { \ | ||
85 | printk(kernlvl "%s %d-%04x: " fmt, i2cprops.name, \ | ||
86 | i2cprops.adap ? \ | ||
87 | i2c_adapter_id(i2cprops.adap) : -1, \ | ||
88 | i2cprops.addr, ##arg); \ | ||
66 | } while (0) | 89 | } while (0) |
67 | 90 | ||
68 | #define tuner_info(fmt, arg...) do { \ | 91 | /* TO DO: convert all callers of these macros to pass in |
69 | printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX, \ | 92 | * struct tuner_i2c_props, then remove the macro wrappers */ |
70 | i2c_adapter_id(priv->i2c_props.adap), \ | 93 | |
71 | priv->i2c_props.addr , ##arg); \ | 94 | #define __tuner_warn(i2cprops, fmt, arg...) do { \ |
95 | tuner_printk(KERN_WARNING, i2cprops, fmt, ##arg); \ | ||
72 | } while (0) | 96 | } while (0) |
73 | 97 | ||
74 | #define tuner_err(fmt, arg...) do { \ | 98 | #define __tuner_info(i2cprops, fmt, arg...) do { \ |
75 | printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX, \ | 99 | tuner_printk(KERN_INFO, i2cprops, fmt, ##arg); \ |
76 | i2c_adapter_id(priv->i2c_props.adap), \ | ||
77 | priv->i2c_props.addr , ##arg); \ | ||
78 | } while (0) | 100 | } while (0) |
79 | 101 | ||
80 | #define tuner_dbg(fmt, arg...) do { \ | 102 | #define __tuner_err(i2cprops, fmt, arg...) do { \ |
103 | tuner_printk(KERN_ERR, i2cprops, fmt, ##arg); \ | ||
104 | } while (0) | ||
105 | |||
106 | #define __tuner_dbg(i2cprops, fmt, arg...) do { \ | ||
81 | if ((debug)) \ | 107 | if ((debug)) \ |
82 | printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX, \ | 108 | tuner_printk(KERN_DEBUG, i2cprops, fmt, ##arg); \ |
83 | i2c_adapter_id(priv->i2c_props.adap), \ | ||
84 | priv->i2c_props.addr , ##arg); \ | ||
85 | } while (0) | 109 | } while (0) |
86 | 110 | ||
111 | #define tuner_warn(fmt, arg...) __tuner_warn(priv->i2c_props, fmt, ##arg) | ||
112 | #define tuner_info(fmt, arg...) __tuner_info(priv->i2c_props, fmt, ##arg) | ||
113 | #define tuner_err(fmt, arg...) __tuner_err(priv->i2c_props, fmt, ##arg) | ||
114 | #define tuner_dbg(fmt, arg...) __tuner_dbg(priv->i2c_props, fmt, ##arg) | ||
115 | |||
116 | /****************************************************************************/ | ||
117 | |||
118 | /* The return value of hybrid_tuner_request_state indicates the number of | ||
119 | * instances using this tuner object. | ||
120 | * | ||
121 | * 0 - no instances, indicates an error - kzalloc must have failed | ||
122 | * | ||
123 | * 1 - one instance, indicates that the tuner object was created successfully | ||
124 | * | ||
125 | * 2 (or more) instances, indicates that an existing tuner object was found | ||
126 | */ | ||
127 | |||
128 | #define hybrid_tuner_request_state(type, state, list, i2cadap, i2caddr, devname)\ | ||
129 | ({ \ | ||
130 | int __ret = 0; \ | ||
131 | list_for_each_entry(state, &list, hybrid_tuner_instance_list) { \ | ||
132 | if (((i2cadap) && (state->i2c_props.adap)) && \ | ||
133 | ((i2c_adapter_id(state->i2c_props.adap) == \ | ||
134 | i2c_adapter_id(i2cadap)) && \ | ||
135 | (i2caddr == state->i2c_props.addr))) { \ | ||
136 | __tuner_info(state->i2c_props, \ | ||
137 | "attaching existing instance\n"); \ | ||
138 | state->i2c_props.count++; \ | ||
139 | __ret = state->i2c_props.count; \ | ||
140 | break; \ | ||
141 | } \ | ||
142 | } \ | ||
143 | if (0 == __ret) { \ | ||
144 | state = kzalloc(sizeof(type), GFP_KERNEL); \ | ||
145 | if (NULL == state) \ | ||
146 | goto __fail; \ | ||
147 | state->i2c_props.addr = i2caddr; \ | ||
148 | state->i2c_props.adap = i2cadap; \ | ||
149 | state->i2c_props.name = devname; \ | ||
150 | __tuner_info(state->i2c_props, \ | ||
151 | "creating new instance\n"); \ | ||
152 | list_add_tail(&state->hybrid_tuner_instance_list, &list);\ | ||
153 | state->i2c_props.count++; \ | ||
154 | __ret = state->i2c_props.count; \ | ||
155 | } \ | ||
156 | __fail: \ | ||
157 | __ret; \ | ||
158 | }) | ||
159 | |||
160 | #define hybrid_tuner_release_state(state) \ | ||
161 | ({ \ | ||
162 | int __ret; \ | ||
163 | state->i2c_props.count--; \ | ||
164 | __ret = state->i2c_props.count; \ | ||
165 | if (!state->i2c_props.count) { \ | ||
166 | __tuner_info(state->i2c_props, "destroying instance\n");\ | ||
167 | list_del(&state->hybrid_tuner_instance_list); \ | ||
168 | kfree(state); \ | ||
169 | } \ | ||
170 | __ret; \ | ||
171 | }) | ||
172 | |||
87 | #endif /* __TUNER_I2C_H__ */ | 173 | #endif /* __TUNER_I2C_H__ */ |
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index c1db576696c6..be8d903171b7 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c | |||
@@ -13,15 +13,25 @@ | |||
13 | #include "tuner-i2c.h" | 13 | #include "tuner-i2c.h" |
14 | #include "tuner-simple.h" | 14 | #include "tuner-simple.h" |
15 | 15 | ||
16 | static int debug = 0; | 16 | static int debug; |
17 | module_param(debug, int, 0644); | 17 | module_param(debug, int, 0644); |
18 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | 18 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); |
19 | 19 | ||
20 | #define PREFIX "tuner-simple" | 20 | #define TUNER_SIMPLE_MAX 64 |
21 | static unsigned int simple_devcount; | ||
21 | 22 | ||
22 | static int offset = 0; | 23 | static int offset; |
23 | module_param(offset, int, 0664); | 24 | module_param(offset, int, 0664); |
24 | MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); | 25 | MODULE_PARM_DESC(offset, "Allows to specify an offset for tuner"); |
26 | |||
27 | static unsigned int atv_input[TUNER_SIMPLE_MAX] = \ | ||
28 | { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 }; | ||
29 | static unsigned int dtv_input[TUNER_SIMPLE_MAX] = \ | ||
30 | { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 }; | ||
31 | module_param_array(atv_input, int, NULL, 0644); | ||
32 | module_param_array(dtv_input, int, NULL, 0644); | ||
33 | MODULE_PARM_DESC(atv_input, "specify atv rf input, 0 for autoselect"); | ||
34 | MODULE_PARM_DESC(dtv_input, "specify dtv rf input, 0 for autoselect"); | ||
25 | 35 | ||
26 | /* ---------------------------------------------------------------------- */ | 36 | /* ---------------------------------------------------------------------- */ |
27 | 37 | ||
@@ -36,8 +46,8 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); | |||
36 | */ | 46 | */ |
37 | #define TEMIC_SET_PAL_I 0x05 | 47 | #define TEMIC_SET_PAL_I 0x05 |
38 | #define TEMIC_SET_PAL_DK 0x09 | 48 | #define TEMIC_SET_PAL_DK 0x09 |
39 | #define TEMIC_SET_PAL_L 0x0a // SECAM ? | 49 | #define TEMIC_SET_PAL_L 0x0a /* SECAM ? */ |
40 | #define TEMIC_SET_PAL_L2 0x0b // change IF ! | 50 | #define TEMIC_SET_PAL_L2 0x0b /* change IF ! */ |
41 | #define TEMIC_SET_PAL_BG 0x0c | 51 | #define TEMIC_SET_PAL_BG 0x0c |
42 | 52 | ||
43 | /* tv tuner system standard selection for Philips FQ1216ME | 53 | /* tv tuner system standard selection for Philips FQ1216ME |
@@ -90,14 +100,21 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); | |||
90 | #define TUNER_PLL_LOCKED 0x40 | 100 | #define TUNER_PLL_LOCKED 0x40 |
91 | #define TUNER_STEREO_MK3 0x04 | 101 | #define TUNER_STEREO_MK3 0x04 |
92 | 102 | ||
103 | static DEFINE_MUTEX(tuner_simple_list_mutex); | ||
104 | static LIST_HEAD(hybrid_tuner_instance_list); | ||
105 | |||
93 | struct tuner_simple_priv { | 106 | struct tuner_simple_priv { |
107 | unsigned int nr; | ||
94 | u16 last_div; | 108 | u16 last_div; |
109 | |||
95 | struct tuner_i2c_props i2c_props; | 110 | struct tuner_i2c_props i2c_props; |
111 | struct list_head hybrid_tuner_instance_list; | ||
96 | 112 | ||
97 | unsigned int type; | 113 | unsigned int type; |
98 | struct tunertype *tun; | 114 | struct tunertype *tun; |
99 | 115 | ||
100 | u32 frequency; | 116 | u32 frequency; |
117 | u32 bandwidth; | ||
101 | }; | 118 | }; |
102 | 119 | ||
103 | /* ---------------------------------------------------------------------- */ | 120 | /* ---------------------------------------------------------------------- */ |
@@ -107,7 +124,7 @@ static int tuner_read_status(struct dvb_frontend *fe) | |||
107 | struct tuner_simple_priv *priv = fe->tuner_priv; | 124 | struct tuner_simple_priv *priv = fe->tuner_priv; |
108 | unsigned char byte; | 125 | unsigned char byte; |
109 | 126 | ||
110 | if (1 != tuner_i2c_xfer_recv(&priv->i2c_props,&byte,1)) | 127 | if (1 != tuner_i2c_xfer_recv(&priv->i2c_props, &byte, 1)) |
111 | return 0; | 128 | return 0; |
112 | 129 | ||
113 | return byte; | 130 | return byte; |
@@ -121,13 +138,13 @@ static inline int tuner_signal(const int status) | |||
121 | static inline int tuner_stereo(const int type, const int status) | 138 | static inline int tuner_stereo(const int type, const int status) |
122 | { | 139 | { |
123 | switch (type) { | 140 | switch (type) { |
124 | case TUNER_PHILIPS_FM1216ME_MK3: | 141 | case TUNER_PHILIPS_FM1216ME_MK3: |
125 | case TUNER_PHILIPS_FM1236_MK3: | 142 | case TUNER_PHILIPS_FM1236_MK3: |
126 | case TUNER_PHILIPS_FM1256_IH3: | 143 | case TUNER_PHILIPS_FM1256_IH3: |
127 | case TUNER_LG_NTSC_TAPE: | 144 | case TUNER_LG_NTSC_TAPE: |
128 | return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); | 145 | return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); |
129 | default: | 146 | default: |
130 | return status & TUNER_STEREO; | 147 | return status & TUNER_STEREO; |
131 | } | 148 | } |
132 | } | 149 | } |
133 | 150 | ||
@@ -145,7 +162,12 @@ static inline int tuner_afcstatus(const int status) | |||
145 | static int simple_get_status(struct dvb_frontend *fe, u32 *status) | 162 | static int simple_get_status(struct dvb_frontend *fe, u32 *status) |
146 | { | 163 | { |
147 | struct tuner_simple_priv *priv = fe->tuner_priv; | 164 | struct tuner_simple_priv *priv = fe->tuner_priv; |
148 | int tuner_status = tuner_read_status(fe); | 165 | int tuner_status; |
166 | |||
167 | if (priv->i2c_props.adap == NULL) | ||
168 | return -EINVAL; | ||
169 | |||
170 | tuner_status = tuner_read_status(fe); | ||
149 | 171 | ||
150 | *status = 0; | 172 | *status = 0; |
151 | 173 | ||
@@ -162,7 +184,12 @@ static int simple_get_status(struct dvb_frontend *fe, u32 *status) | |||
162 | static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength) | 184 | static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength) |
163 | { | 185 | { |
164 | struct tuner_simple_priv *priv = fe->tuner_priv; | 186 | struct tuner_simple_priv *priv = fe->tuner_priv; |
165 | int signal = tuner_signal(tuner_read_status(fe)); | 187 | int signal; |
188 | |||
189 | if (priv->i2c_props.adap == NULL) | ||
190 | return -EINVAL; | ||
191 | |||
192 | signal = tuner_signal(tuner_read_status(fe)); | ||
166 | 193 | ||
167 | *strength = signal; | 194 | *strength = signal; |
168 | 195 | ||
@@ -173,174 +200,378 @@ static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength) | |||
173 | 200 | ||
174 | /* ---------------------------------------------------------------------- */ | 201 | /* ---------------------------------------------------------------------- */ |
175 | 202 | ||
176 | static int simple_set_tv_freq(struct dvb_frontend *fe, | 203 | static inline char *tuner_param_name(enum param_type type) |
177 | struct analog_parameters *params) | ||
178 | { | 204 | { |
179 | struct tuner_simple_priv *priv = fe->tuner_priv; | 205 | char *name; |
180 | u8 config, cb, tuneraddr; | ||
181 | u16 div; | ||
182 | struct tunertype *tun; | ||
183 | u8 buffer[4]; | ||
184 | int rc, IFPCoff, i, j; | ||
185 | enum param_type desired_type; | ||
186 | struct tuner_params *t_params; | ||
187 | 206 | ||
188 | tun = priv->tun; | 207 | switch (type) { |
208 | case TUNER_PARAM_TYPE_RADIO: | ||
209 | name = "radio"; | ||
210 | break; | ||
211 | case TUNER_PARAM_TYPE_PAL: | ||
212 | name = "pal"; | ||
213 | break; | ||
214 | case TUNER_PARAM_TYPE_SECAM: | ||
215 | name = "secam"; | ||
216 | break; | ||
217 | case TUNER_PARAM_TYPE_NTSC: | ||
218 | name = "ntsc"; | ||
219 | break; | ||
220 | case TUNER_PARAM_TYPE_DIGITAL: | ||
221 | name = "digital"; | ||
222 | break; | ||
223 | default: | ||
224 | name = "unknown"; | ||
225 | break; | ||
226 | } | ||
227 | return name; | ||
228 | } | ||
189 | 229 | ||
190 | /* IFPCoff = Video Intermediate Frequency - Vif: | 230 | static struct tuner_params *simple_tuner_params(struct dvb_frontend *fe, |
191 | 940 =16*58.75 NTSC/J (Japan) | 231 | enum param_type desired_type) |
192 | 732 =16*45.75 M/N STD | 232 | { |
193 | 704 =16*44 ATSC (at DVB code) | 233 | struct tuner_simple_priv *priv = fe->tuner_priv; |
194 | 632 =16*39.50 I U.K. | 234 | struct tunertype *tun = priv->tun; |
195 | 622.4=16*38.90 B/G D/K I, L STD | 235 | int i; |
196 | 592 =16*37.00 D China | ||
197 | 590 =16.36.875 B Australia | ||
198 | 543.2=16*33.95 L' STD | ||
199 | 171.2=16*10.70 FM Radio (at set_radio_freq) | ||
200 | */ | ||
201 | 236 | ||
202 | if (params->std == V4L2_STD_NTSC_M_JP) { | 237 | for (i = 0; i < tun->count; i++) |
203 | IFPCoff = 940; | 238 | if (desired_type == tun->params[i].type) |
204 | desired_type = TUNER_PARAM_TYPE_NTSC; | 239 | break; |
205 | } else if ((params->std & V4L2_STD_MN) && | ||
206 | !(params->std & ~V4L2_STD_MN)) { | ||
207 | IFPCoff = 732; | ||
208 | desired_type = TUNER_PARAM_TYPE_NTSC; | ||
209 | } else if (params->std == V4L2_STD_SECAM_LC) { | ||
210 | IFPCoff = 543; | ||
211 | desired_type = TUNER_PARAM_TYPE_SECAM; | ||
212 | } else { | ||
213 | IFPCoff = 623; | ||
214 | desired_type = TUNER_PARAM_TYPE_PAL; | ||
215 | } | ||
216 | 240 | ||
217 | for (j = 0; j < tun->count-1; j++) { | 241 | /* use default tuner params if desired_type not available */ |
218 | if (desired_type != tun->params[j].type) | 242 | if (i == tun->count) { |
219 | continue; | 243 | tuner_dbg("desired params (%s) undefined for tuner %d\n", |
220 | break; | 244 | tuner_param_name(desired_type), priv->type); |
221 | } | 245 | i = 0; |
222 | /* use default tuner_t_params if desired_type not available */ | ||
223 | if (desired_type != tun->params[j].type) { | ||
224 | tuner_dbg("IFPCoff = %d: tuner_t_params undefined for tuner %d\n", | ||
225 | IFPCoff, priv->type); | ||
226 | j = 0; | ||
227 | } | 246 | } |
228 | t_params = &tun->params[j]; | 247 | |
248 | tuner_dbg("using tuner params #%d (%s)\n", i, | ||
249 | tuner_param_name(tun->params[i].type)); | ||
250 | |||
251 | return &tun->params[i]; | ||
252 | } | ||
253 | |||
254 | static int simple_config_lookup(struct dvb_frontend *fe, | ||
255 | struct tuner_params *t_params, | ||
256 | int *frequency, u8 *config, u8 *cb) | ||
257 | { | ||
258 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
259 | int i; | ||
229 | 260 | ||
230 | for (i = 0; i < t_params->count; i++) { | 261 | for (i = 0; i < t_params->count; i++) { |
231 | if (params->frequency > t_params->ranges[i].limit) | 262 | if (*frequency > t_params->ranges[i].limit) |
232 | continue; | 263 | continue; |
233 | break; | 264 | break; |
234 | } | 265 | } |
235 | if (i == t_params->count) { | 266 | if (i == t_params->count) { |
236 | tuner_dbg("TV frequency out of range (%d > %d)", | 267 | tuner_dbg("frequency out of range (%d > %d)\n", |
237 | params->frequency, t_params->ranges[i - 1].limit); | 268 | *frequency, t_params->ranges[i - 1].limit); |
238 | params->frequency = t_params->ranges[--i].limit; | 269 | *frequency = t_params->ranges[--i].limit; |
239 | } | 270 | } |
240 | config = t_params->ranges[i].config; | 271 | *config = t_params->ranges[i].config; |
241 | cb = t_params->ranges[i].cb; | 272 | *cb = t_params->ranges[i].cb; |
242 | /* i == 0 -> VHF_LO | 273 | |
243 | * i == 1 -> VHF_HI | 274 | tuner_dbg("freq = %d.%02d (%d), range = %d, " |
244 | * i == 2 -> UHF */ | 275 | "config = 0x%02x, cb = 0x%02x\n", |
245 | tuner_dbg("tv: param %d, range %d\n",j,i); | 276 | *frequency / 16, *frequency % 16 * 100 / 16, *frequency, |
277 | i, *config, *cb); | ||
278 | |||
279 | return i; | ||
280 | } | ||
281 | |||
282 | /* ---------------------------------------------------------------------- */ | ||
283 | |||
284 | static void simple_set_rf_input(struct dvb_frontend *fe, | ||
285 | u8 *config, u8 *cb, unsigned int rf) | ||
286 | { | ||
287 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
246 | 288 | ||
247 | div=params->frequency + IFPCoff + offset; | 289 | switch (priv->type) { |
290 | case TUNER_PHILIPS_TUV1236D: | ||
291 | switch (rf) { | ||
292 | case 1: | ||
293 | *cb |= 0x08; | ||
294 | break; | ||
295 | default: | ||
296 | *cb &= ~0x08; | ||
297 | break; | ||
298 | } | ||
299 | break; | ||
300 | case TUNER_PHILIPS_FCV1236D: | ||
301 | switch (rf) { | ||
302 | case 1: | ||
303 | *cb |= 0x01; | ||
304 | break; | ||
305 | default: | ||
306 | *cb &= ~0x01; | ||
307 | break; | ||
308 | } | ||
309 | break; | ||
310 | default: | ||
311 | break; | ||
312 | } | ||
313 | } | ||
248 | 314 | ||
249 | tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n", | 315 | static int simple_std_setup(struct dvb_frontend *fe, |
250 | params->frequency / 16, params->frequency % 16 * 100 / 16, | 316 | struct analog_parameters *params, |
251 | IFPCoff / 16, IFPCoff % 16 * 100 / 16, | 317 | u8 *config, u8 *cb) |
252 | offset / 16, offset % 16 * 100 / 16, | 318 | { |
253 | div); | 319 | struct tuner_simple_priv *priv = fe->tuner_priv; |
320 | u8 tuneraddr; | ||
321 | int rc; | ||
254 | 322 | ||
255 | /* tv norm specific stuff for multi-norm tuners */ | 323 | /* tv norm specific stuff for multi-norm tuners */ |
256 | switch (priv->type) { | 324 | switch (priv->type) { |
257 | case TUNER_PHILIPS_SECAM: // FI1216MF | 325 | case TUNER_PHILIPS_SECAM: /* FI1216MF */ |
258 | /* 0x01 -> ??? no change ??? */ | 326 | /* 0x01 -> ??? no change ??? */ |
259 | /* 0x02 -> PAL BDGHI / SECAM L */ | 327 | /* 0x02 -> PAL BDGHI / SECAM L */ |
260 | /* 0x04 -> ??? PAL others / SECAM others ??? */ | 328 | /* 0x04 -> ??? PAL others / SECAM others ??? */ |
261 | cb &= ~0x03; | 329 | *cb &= ~0x03; |
262 | if (params->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM | 330 | if (params->std & V4L2_STD_SECAM_L) |
263 | cb |= PHILIPS_MF_SET_STD_L; | 331 | /* also valid for V4L2_STD_SECAM */ |
332 | *cb |= PHILIPS_MF_SET_STD_L; | ||
264 | else if (params->std & V4L2_STD_SECAM_LC) | 333 | else if (params->std & V4L2_STD_SECAM_LC) |
265 | cb |= PHILIPS_MF_SET_STD_LC; | 334 | *cb |= PHILIPS_MF_SET_STD_LC; |
266 | else /* V4L2_STD_B|V4L2_STD_GH */ | 335 | else /* V4L2_STD_B|V4L2_STD_GH */ |
267 | cb |= PHILIPS_MF_SET_STD_BG; | 336 | *cb |= PHILIPS_MF_SET_STD_BG; |
268 | break; | 337 | break; |
269 | 338 | ||
270 | case TUNER_TEMIC_4046FM5: | 339 | case TUNER_TEMIC_4046FM5: |
271 | cb &= ~0x0f; | 340 | *cb &= ~0x0f; |
272 | 341 | ||
273 | if (params->std & V4L2_STD_PAL_BG) { | 342 | if (params->std & V4L2_STD_PAL_BG) { |
274 | cb |= TEMIC_SET_PAL_BG; | 343 | *cb |= TEMIC_SET_PAL_BG; |
275 | 344 | ||
276 | } else if (params->std & V4L2_STD_PAL_I) { | 345 | } else if (params->std & V4L2_STD_PAL_I) { |
277 | cb |= TEMIC_SET_PAL_I; | 346 | *cb |= TEMIC_SET_PAL_I; |
278 | 347 | ||
279 | } else if (params->std & V4L2_STD_PAL_DK) { | 348 | } else if (params->std & V4L2_STD_PAL_DK) { |
280 | cb |= TEMIC_SET_PAL_DK; | 349 | *cb |= TEMIC_SET_PAL_DK; |
281 | 350 | ||
282 | } else if (params->std & V4L2_STD_SECAM_L) { | 351 | } else if (params->std & V4L2_STD_SECAM_L) { |
283 | cb |= TEMIC_SET_PAL_L; | 352 | *cb |= TEMIC_SET_PAL_L; |
284 | 353 | ||
285 | } | 354 | } |
286 | break; | 355 | break; |
287 | 356 | ||
288 | case TUNER_PHILIPS_FQ1216ME: | 357 | case TUNER_PHILIPS_FQ1216ME: |
289 | cb &= ~0x0f; | 358 | *cb &= ~0x0f; |
290 | 359 | ||
291 | if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { | 360 | if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { |
292 | cb |= PHILIPS_SET_PAL_BGDK; | 361 | *cb |= PHILIPS_SET_PAL_BGDK; |
293 | 362 | ||
294 | } else if (params->std & V4L2_STD_PAL_I) { | 363 | } else if (params->std & V4L2_STD_PAL_I) { |
295 | cb |= PHILIPS_SET_PAL_I; | 364 | *cb |= PHILIPS_SET_PAL_I; |
296 | 365 | ||
297 | } else if (params->std & V4L2_STD_SECAM_L) { | 366 | } else if (params->std & V4L2_STD_SECAM_L) { |
298 | cb |= PHILIPS_SET_PAL_L; | 367 | *cb |= PHILIPS_SET_PAL_L; |
299 | 368 | ||
300 | } | 369 | } |
301 | break; | 370 | break; |
302 | 371 | ||
303 | case TUNER_PHILIPS_ATSC: | 372 | case TUNER_PHILIPS_FCV1236D: |
304 | /* 0x00 -> ATSC antenna input 1 */ | 373 | /* 0x00 -> ATSC antenna input 1 */ |
305 | /* 0x01 -> ATSC antenna input 2 */ | 374 | /* 0x01 -> ATSC antenna input 2 */ |
306 | /* 0x02 -> NTSC antenna input 1 */ | 375 | /* 0x02 -> NTSC antenna input 1 */ |
307 | /* 0x03 -> NTSC antenna input 2 */ | 376 | /* 0x03 -> NTSC antenna input 2 */ |
308 | cb &= ~0x03; | 377 | *cb &= ~0x03; |
309 | if (!(params->std & V4L2_STD_ATSC)) | 378 | if (!(params->std & V4L2_STD_ATSC)) |
310 | cb |= 2; | 379 | *cb |= 2; |
311 | /* FIXME: input */ | ||
312 | break; | 380 | break; |
313 | 381 | ||
314 | case TUNER_MICROTUNE_4042FI5: | 382 | case TUNER_MICROTUNE_4042FI5: |
315 | /* Set the charge pump for fast tuning */ | 383 | /* Set the charge pump for fast tuning */ |
316 | config |= TUNER_CHARGE_PUMP; | 384 | *config |= TUNER_CHARGE_PUMP; |
317 | break; | 385 | break; |
318 | 386 | ||
319 | case TUNER_PHILIPS_TUV1236D: | 387 | case TUNER_PHILIPS_TUV1236D: |
388 | { | ||
320 | /* 0x40 -> ATSC antenna input 1 */ | 389 | /* 0x40 -> ATSC antenna input 1 */ |
321 | /* 0x48 -> ATSC antenna input 2 */ | 390 | /* 0x48 -> ATSC antenna input 2 */ |
322 | /* 0x00 -> NTSC antenna input 1 */ | 391 | /* 0x00 -> NTSC antenna input 1 */ |
323 | /* 0x08 -> NTSC antenna input 2 */ | 392 | /* 0x08 -> NTSC antenna input 2 */ |
324 | buffer[0] = 0x14; | 393 | u8 buffer[4] = { 0x14, 0x00, 0x17, 0x00}; |
325 | buffer[1] = 0x00; | 394 | *cb &= ~0x40; |
326 | buffer[2] = 0x17; | ||
327 | buffer[3] = 0x00; | ||
328 | cb &= ~0x40; | ||
329 | if (params->std & V4L2_STD_ATSC) { | 395 | if (params->std & V4L2_STD_ATSC) { |
330 | cb |= 0x40; | 396 | *cb |= 0x40; |
331 | buffer[1] = 0x04; | 397 | buffer[1] = 0x04; |
332 | } | 398 | } |
333 | /* set to the correct mode (analog or digital) */ | 399 | /* set to the correct mode (analog or digital) */ |
334 | tuneraddr = priv->i2c_props.addr; | 400 | tuneraddr = priv->i2c_props.addr; |
335 | priv->i2c_props.addr = 0x0a; | 401 | priv->i2c_props.addr = 0x0a; |
336 | if (2 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,&buffer[0],2))) | 402 | rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[0], 2); |
337 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc); | 403 | if (2 != rc) |
338 | if (2 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,&buffer[2],2))) | 404 | tuner_warn("i2c i/o error: rc == %d " |
339 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc); | 405 | "(should be 2)\n", rc); |
406 | rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[2], 2); | ||
407 | if (2 != rc) | ||
408 | tuner_warn("i2c i/o error: rc == %d " | ||
409 | "(should be 2)\n", rc); | ||
340 | priv->i2c_props.addr = tuneraddr; | 410 | priv->i2c_props.addr = tuneraddr; |
341 | /* FIXME: input */ | ||
342 | break; | 411 | break; |
343 | } | 412 | } |
413 | } | ||
414 | if (atv_input[priv->nr]) | ||
415 | simple_set_rf_input(fe, config, cb, atv_input[priv->nr]); | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, | ||
421 | u16 div, u8 config, u8 cb) | ||
422 | { | ||
423 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
424 | int rc; | ||
425 | |||
426 | switch (priv->type) { | ||
427 | case TUNER_LG_TDVS_H06XF: | ||
428 | /* Set the Auxiliary Byte. */ | ||
429 | buffer[0] = buffer[2]; | ||
430 | buffer[0] &= ~0x20; | ||
431 | buffer[0] |= 0x18; | ||
432 | buffer[1] = 0x20; | ||
433 | tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]); | ||
434 | |||
435 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2); | ||
436 | if (2 != rc) | ||
437 | tuner_warn("i2c i/o error: rc == %d " | ||
438 | "(should be 2)\n", rc); | ||
439 | break; | ||
440 | case TUNER_MICROTUNE_4042FI5: | ||
441 | { | ||
442 | /* FIXME - this may also work for other tuners */ | ||
443 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
444 | u8 status_byte = 0; | ||
445 | |||
446 | /* Wait until the PLL locks */ | ||
447 | for (;;) { | ||
448 | if (time_after(jiffies, timeout)) | ||
449 | return 0; | ||
450 | rc = tuner_i2c_xfer_recv(&priv->i2c_props, | ||
451 | &status_byte, 1); | ||
452 | if (1 != rc) { | ||
453 | tuner_warn("i2c i/o read error: rc == %d " | ||
454 | "(should be 1)\n", rc); | ||
455 | break; | ||
456 | } | ||
457 | if (status_byte & TUNER_PLL_LOCKED) | ||
458 | break; | ||
459 | udelay(10); | ||
460 | } | ||
461 | |||
462 | /* Set the charge pump for optimized phase noise figure */ | ||
463 | config &= ~TUNER_CHARGE_PUMP; | ||
464 | buffer[0] = (div>>8) & 0x7f; | ||
465 | buffer[1] = div & 0xff; | ||
466 | buffer[2] = config; | ||
467 | buffer[3] = cb; | ||
468 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
469 | buffer[0], buffer[1], buffer[2], buffer[3]); | ||
470 | |||
471 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); | ||
472 | if (4 != rc) | ||
473 | tuner_warn("i2c i/o error: rc == %d " | ||
474 | "(should be 4)\n", rc); | ||
475 | break; | ||
476 | } | ||
477 | } | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) | ||
483 | { | ||
484 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
485 | |||
486 | switch (priv->type) { | ||
487 | case TUNER_TENA_9533_DI: | ||
488 | case TUNER_YMEC_TVF_5533MF: | ||
489 | tuner_dbg("This tuner doesn't have FM. " | ||
490 | "Most cards have a TEA5767 for FM\n"); | ||
491 | return 0; | ||
492 | case TUNER_PHILIPS_FM1216ME_MK3: | ||
493 | case TUNER_PHILIPS_FM1236_MK3: | ||
494 | case TUNER_PHILIPS_FMD1216ME_MK3: | ||
495 | case TUNER_LG_NTSC_TAPE: | ||
496 | case TUNER_PHILIPS_FM1256_IH3: | ||
497 | buffer[3] = 0x19; | ||
498 | break; | ||
499 | case TUNER_TNF_5335MF: | ||
500 | buffer[3] = 0x11; | ||
501 | break; | ||
502 | case TUNER_LG_PAL_FM: | ||
503 | buffer[3] = 0xa5; | ||
504 | break; | ||
505 | case TUNER_THOMSON_DTT761X: | ||
506 | buffer[3] = 0x39; | ||
507 | break; | ||
508 | case TUNER_MICROTUNE_4049FM5: | ||
509 | default: | ||
510 | buffer[3] = 0xa4; | ||
511 | break; | ||
512 | } | ||
513 | |||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | /* ---------------------------------------------------------------------- */ | ||
518 | |||
519 | static int simple_set_tv_freq(struct dvb_frontend *fe, | ||
520 | struct analog_parameters *params) | ||
521 | { | ||
522 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
523 | u8 config, cb; | ||
524 | u16 div; | ||
525 | struct tunertype *tun; | ||
526 | u8 buffer[4]; | ||
527 | int rc, IFPCoff, i; | ||
528 | enum param_type desired_type; | ||
529 | struct tuner_params *t_params; | ||
530 | |||
531 | tun = priv->tun; | ||
532 | |||
533 | /* IFPCoff = Video Intermediate Frequency - Vif: | ||
534 | 940 =16*58.75 NTSC/J (Japan) | ||
535 | 732 =16*45.75 M/N STD | ||
536 | 704 =16*44 ATSC (at DVB code) | ||
537 | 632 =16*39.50 I U.K. | ||
538 | 622.4=16*38.90 B/G D/K I, L STD | ||
539 | 592 =16*37.00 D China | ||
540 | 590 =16.36.875 B Australia | ||
541 | 543.2=16*33.95 L' STD | ||
542 | 171.2=16*10.70 FM Radio (at set_radio_freq) | ||
543 | */ | ||
544 | |||
545 | if (params->std == V4L2_STD_NTSC_M_JP) { | ||
546 | IFPCoff = 940; | ||
547 | desired_type = TUNER_PARAM_TYPE_NTSC; | ||
548 | } else if ((params->std & V4L2_STD_MN) && | ||
549 | !(params->std & ~V4L2_STD_MN)) { | ||
550 | IFPCoff = 732; | ||
551 | desired_type = TUNER_PARAM_TYPE_NTSC; | ||
552 | } else if (params->std == V4L2_STD_SECAM_LC) { | ||
553 | IFPCoff = 543; | ||
554 | desired_type = TUNER_PARAM_TYPE_SECAM; | ||
555 | } else { | ||
556 | IFPCoff = 623; | ||
557 | desired_type = TUNER_PARAM_TYPE_PAL; | ||
558 | } | ||
559 | |||
560 | t_params = simple_tuner_params(fe, desired_type); | ||
561 | |||
562 | i = simple_config_lookup(fe, t_params, ¶ms->frequency, | ||
563 | &config, &cb); | ||
564 | |||
565 | div = params->frequency + IFPCoff + offset; | ||
566 | |||
567 | tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, " | ||
568 | "Offset=%d.%02d MHz, div=%0d\n", | ||
569 | params->frequency / 16, params->frequency % 16 * 100 / 16, | ||
570 | IFPCoff / 16, IFPCoff % 16 * 100 / 16, | ||
571 | offset / 16, offset % 16 * 100 / 16, div); | ||
572 | |||
573 | /* tv norm specific stuff for multi-norm tuners */ | ||
574 | simple_std_setup(fe, params, &config, &cb); | ||
344 | 575 | ||
345 | if (t_params->cb_first_if_lower_freq && div < priv->last_div) { | 576 | if (t_params->cb_first_if_lower_freq && div < priv->last_div) { |
346 | buffer[0] = config; | 577 | buffer[0] = config; |
@@ -357,8 +588,10 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, | |||
357 | if (t_params->has_tda9887) { | 588 | if (t_params->has_tda9887) { |
358 | struct v4l2_priv_tun_config tda9887_cfg; | 589 | struct v4l2_priv_tun_config tda9887_cfg; |
359 | int config = 0; | 590 | int config = 0; |
360 | int is_secam_l = (params->std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) && | 591 | int is_secam_l = (params->std & (V4L2_STD_SECAM_L | |
361 | !(params->std & ~(V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)); | 592 | V4L2_STD_SECAM_LC)) && |
593 | !(params->std & ~(V4L2_STD_SECAM_L | | ||
594 | V4L2_STD_SECAM_LC)); | ||
362 | 595 | ||
363 | tda9887_cfg.tuner = TUNER_TDA9887; | 596 | tda9887_cfg.tuner = TUNER_TDA9887; |
364 | tda9887_cfg.priv = &config; | 597 | tda9887_cfg.priv = &config; |
@@ -368,8 +601,7 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, | |||
368 | config |= TDA9887_PORT1_ACTIVE; | 601 | config |= TDA9887_PORT1_ACTIVE; |
369 | if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc) | 602 | if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc) |
370 | config |= TDA9887_PORT2_ACTIVE; | 603 | config |= TDA9887_PORT2_ACTIVE; |
371 | } | 604 | } else { |
372 | else { | ||
373 | if (t_params->port1_active) | 605 | if (t_params->port1_active) |
374 | config |= TDA9887_PORT1_ACTIVE; | 606 | config |= TDA9887_PORT1_ACTIVE; |
375 | if (t_params->port2_active) | 607 | if (t_params->port2_active) |
@@ -384,8 +616,7 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, | |||
384 | config |= TDA9887_TOP(t_params->default_top_secam_mid); | 616 | config |= TDA9887_TOP(t_params->default_top_secam_mid); |
385 | else if (t_params->default_top_secam_high) | 617 | else if (t_params->default_top_secam_high) |
386 | config |= TDA9887_TOP(t_params->default_top_secam_high); | 618 | config |= TDA9887_TOP(t_params->default_top_secam_high); |
387 | } | 619 | } else { |
388 | else { | ||
389 | if (i == 0 && t_params->default_top_low) | 620 | if (i == 0 && t_params->default_top_low) |
390 | config |= TDA9887_TOP(t_params->default_top_low); | 621 | config |= TDA9887_TOP(t_params->default_top_low); |
391 | else if (i == 1 && t_params->default_top_mid) | 622 | else if (i == 1 && t_params->default_top_mid) |
@@ -399,56 +630,14 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, | |||
399 | &tda9887_cfg); | 630 | &tda9887_cfg); |
400 | } | 631 | } |
401 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | 632 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", |
402 | buffer[0],buffer[1],buffer[2],buffer[3]); | 633 | buffer[0], buffer[1], buffer[2], buffer[3]); |
403 | |||
404 | if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4))) | ||
405 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | ||
406 | |||
407 | switch (priv->type) { | ||
408 | case TUNER_LG_TDVS_H06XF: | ||
409 | /* Set the Auxiliary Byte. */ | ||
410 | buffer[0] = buffer[2]; | ||
411 | buffer[0] &= ~0x20; | ||
412 | buffer[0] |= 0x18; | ||
413 | buffer[1] = 0x20; | ||
414 | tuner_dbg("tv 0x%02x 0x%02x\n",buffer[0],buffer[1]); | ||
415 | |||
416 | if (2 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,2))) | ||
417 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc); | ||
418 | break; | ||
419 | case TUNER_MICROTUNE_4042FI5: | ||
420 | { | ||
421 | // FIXME - this may also work for other tuners | ||
422 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
423 | u8 status_byte = 0; | ||
424 | 634 | ||
425 | /* Wait until the PLL locks */ | 635 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); |
426 | for (;;) { | 636 | if (4 != rc) |
427 | if (time_after(jiffies,timeout)) | 637 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); |
428 | return 0; | ||
429 | if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,&status_byte,1))) { | ||
430 | tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc); | ||
431 | break; | ||
432 | } | ||
433 | if (status_byte & TUNER_PLL_LOCKED) | ||
434 | break; | ||
435 | udelay(10); | ||
436 | } | ||
437 | 638 | ||
438 | /* Set the charge pump for optimized phase noise figure */ | 639 | simple_post_tune(fe, &buffer[0], div, config, cb); |
439 | config &= ~TUNER_CHARGE_PUMP; | ||
440 | buffer[0] = (div>>8) & 0x7f; | ||
441 | buffer[1] = div & 0xff; | ||
442 | buffer[2] = config; | ||
443 | buffer[3] = cb; | ||
444 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
445 | buffer[0],buffer[1],buffer[2],buffer[3]); | ||
446 | 640 | ||
447 | if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4))) | ||
448 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | ||
449 | break; | ||
450 | } | ||
451 | } | ||
452 | return 0; | 641 | return 0; |
453 | } | 642 | } |
454 | 643 | ||
@@ -483,37 +672,13 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, | |||
483 | freq += (unsigned int)(41.3*16000); | 672 | freq += (unsigned int)(41.3*16000); |
484 | break; | 673 | break; |
485 | default: | 674 | default: |
486 | tuner_warn("Unsupported radio_if value %d\n", t_params->radio_if); | 675 | tuner_warn("Unsupported radio_if value %d\n", |
676 | t_params->radio_if); | ||
487 | return 0; | 677 | return 0; |
488 | } | 678 | } |
489 | 679 | ||
490 | /* Bandswitch byte */ | 680 | /* Bandswitch byte */ |
491 | switch (priv->type) { | 681 | simple_radio_bandswitch(fe, &buffer[0]); |
492 | case TUNER_TENA_9533_DI: | ||
493 | case TUNER_YMEC_TVF_5533MF: | ||
494 | tuner_dbg("This tuner doesn't have FM. Most cards have a TEA5767 for FM\n"); | ||
495 | return 0; | ||
496 | case TUNER_PHILIPS_FM1216ME_MK3: | ||
497 | case TUNER_PHILIPS_FM1236_MK3: | ||
498 | case TUNER_PHILIPS_FMD1216ME_MK3: | ||
499 | case TUNER_LG_NTSC_TAPE: | ||
500 | case TUNER_PHILIPS_FM1256_IH3: | ||
501 | buffer[3] = 0x19; | ||
502 | break; | ||
503 | case TUNER_TNF_5335MF: | ||
504 | buffer[3] = 0x11; | ||
505 | break; | ||
506 | case TUNER_LG_PAL_FM: | ||
507 | buffer[3] = 0xa5; | ||
508 | break; | ||
509 | case TUNER_THOMSON_DTT761X: | ||
510 | buffer[3] = 0x39; | ||
511 | break; | ||
512 | case TUNER_MICROTUNE_4049FM5: | ||
513 | default: | ||
514 | buffer[3] = 0xa4; | ||
515 | break; | ||
516 | } | ||
517 | 682 | ||
518 | buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) | | 683 | buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) | |
519 | TUNER_RATIO_SELECT_50; /* 50 kHz step */ | 684 | TUNER_RATIO_SELECT_50; /* 50 kHz step */ |
@@ -534,7 +699,7 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, | |||
534 | } | 699 | } |
535 | 700 | ||
536 | tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", | 701 | tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", |
537 | buffer[0],buffer[1],buffer[2],buffer[3]); | 702 | buffer[0], buffer[1], buffer[2], buffer[3]); |
538 | priv->last_div = div; | 703 | priv->last_div = div; |
539 | 704 | ||
540 | if (t_params->has_tda9887) { | 705 | if (t_params->has_tda9887) { |
@@ -544,9 +709,11 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, | |||
544 | tda9887_cfg.tuner = TUNER_TDA9887; | 709 | tda9887_cfg.tuner = TUNER_TDA9887; |
545 | tda9887_cfg.priv = &config; | 710 | tda9887_cfg.priv = &config; |
546 | 711 | ||
547 | if (t_params->port1_active && !t_params->port1_fm_high_sensitivity) | 712 | if (t_params->port1_active && |
713 | !t_params->port1_fm_high_sensitivity) | ||
548 | config |= TDA9887_PORT1_ACTIVE; | 714 | config |= TDA9887_PORT1_ACTIVE; |
549 | if (t_params->port2_active && !t_params->port2_fm_high_sensitivity) | 715 | if (t_params->port2_active && |
716 | !t_params->port2_fm_high_sensitivity) | ||
550 | config |= TDA9887_PORT2_ACTIVE; | 717 | config |= TDA9887_PORT2_ACTIVE; |
551 | if (t_params->intercarrier_mode) | 718 | if (t_params->intercarrier_mode) |
552 | config |= TDA9887_INTERCARRIER; | 719 | config |= TDA9887_INTERCARRIER; |
@@ -557,10 +724,11 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, | |||
557 | if (t_params->radio_if == 2) | 724 | if (t_params->radio_if == 2) |
558 | config |= TDA9887_RIF_41_3; | 725 | config |= TDA9887_RIF_41_3; |
559 | i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG, | 726 | i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG, |
560 | &tda9887_cfg); | 727 | &tda9887_cfg); |
561 | } | 728 | } |
562 | if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4))) | 729 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); |
563 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | 730 | if (4 != rc) |
731 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); | ||
564 | 732 | ||
565 | return 0; | 733 | return 0; |
566 | } | 734 | } |
@@ -571,6 +739,9 @@ static int simple_set_params(struct dvb_frontend *fe, | |||
571 | struct tuner_simple_priv *priv = fe->tuner_priv; | 739 | struct tuner_simple_priv *priv = fe->tuner_priv; |
572 | int ret = -EINVAL; | 740 | int ret = -EINVAL; |
573 | 741 | ||
742 | if (priv->i2c_props.adap == NULL) | ||
743 | return -EINVAL; | ||
744 | |||
574 | switch (params->mode) { | 745 | switch (params->mode) { |
575 | case V4L2_TUNER_RADIO: | 746 | case V4L2_TUNER_RADIO: |
576 | ret = simple_set_radio_freq(fe, params); | 747 | ret = simple_set_radio_freq(fe, params); |
@@ -582,14 +753,210 @@ static int simple_set_params(struct dvb_frontend *fe, | |||
582 | priv->frequency = params->frequency * 62500; | 753 | priv->frequency = params->frequency * 62500; |
583 | break; | 754 | break; |
584 | } | 755 | } |
756 | priv->bandwidth = 0; | ||
585 | 757 | ||
586 | return ret; | 758 | return ret; |
587 | } | 759 | } |
588 | 760 | ||
761 | static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf, | ||
762 | const struct dvb_frontend_parameters *params) | ||
763 | { | ||
764 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
765 | |||
766 | switch (priv->type) { | ||
767 | case TUNER_PHILIPS_FMD1216ME_MK3: | ||
768 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ && | ||
769 | params->frequency >= 158870000) | ||
770 | buf[3] |= 0x08; | ||
771 | break; | ||
772 | case TUNER_PHILIPS_TD1316: | ||
773 | /* determine band */ | ||
774 | buf[3] |= (params->frequency < 161000000) ? 1 : | ||
775 | (params->frequency < 444000000) ? 2 : 4; | ||
776 | |||
777 | /* setup PLL filter */ | ||
778 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) | ||
779 | buf[3] |= 1 << 3; | ||
780 | break; | ||
781 | case TUNER_PHILIPS_TUV1236D: | ||
782 | case TUNER_PHILIPS_FCV1236D: | ||
783 | { | ||
784 | unsigned int new_rf; | ||
785 | |||
786 | if (dtv_input[priv->nr]) | ||
787 | new_rf = dtv_input[priv->nr]; | ||
788 | else | ||
789 | switch (params->u.vsb.modulation) { | ||
790 | case QAM_64: | ||
791 | case QAM_256: | ||
792 | new_rf = 1; | ||
793 | break; | ||
794 | case VSB_8: | ||
795 | default: | ||
796 | new_rf = 0; | ||
797 | break; | ||
798 | } | ||
799 | simple_set_rf_input(fe, &buf[2], &buf[3], new_rf); | ||
800 | break; | ||
801 | } | ||
802 | default: | ||
803 | break; | ||
804 | } | ||
805 | } | ||
806 | |||
807 | static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf, | ||
808 | const struct dvb_frontend_parameters *params) | ||
809 | { | ||
810 | /* This function returns the tuned frequency on success, 0 on error */ | ||
811 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
812 | struct tunertype *tun = priv->tun; | ||
813 | static struct tuner_params *t_params; | ||
814 | u8 config, cb; | ||
815 | u32 div; | ||
816 | int ret, frequency = params->frequency / 62500; | ||
817 | |||
818 | t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL); | ||
819 | ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb); | ||
820 | if (ret < 0) | ||
821 | return 0; /* failure */ | ||
822 | |||
823 | div = ((frequency + t_params->iffreq) * 62500 + offset + | ||
824 | tun->stepsize/2) / tun->stepsize; | ||
825 | |||
826 | buf[0] = div >> 8; | ||
827 | buf[1] = div & 0xff; | ||
828 | buf[2] = config; | ||
829 | buf[3] = cb; | ||
830 | |||
831 | simple_set_dvb(fe, buf, params); | ||
832 | |||
833 | tuner_dbg("%s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", | ||
834 | tun->name, div, buf[0], buf[1], buf[2], buf[3]); | ||
835 | |||
836 | /* calculate the frequency we set it to */ | ||
837 | return (div * tun->stepsize) - t_params->iffreq; | ||
838 | } | ||
839 | |||
840 | static int simple_dvb_calc_regs(struct dvb_frontend *fe, | ||
841 | struct dvb_frontend_parameters *params, | ||
842 | u8 *buf, int buf_len) | ||
843 | { | ||
844 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
845 | u32 frequency; | ||
846 | |||
847 | if (buf_len < 5) | ||
848 | return -EINVAL; | ||
849 | |||
850 | frequency = simple_dvb_configure(fe, buf+1, params); | ||
851 | if (frequency == 0) | ||
852 | return -EINVAL; | ||
853 | |||
854 | buf[0] = priv->i2c_props.addr; | ||
855 | |||
856 | priv->frequency = frequency; | ||
857 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? | ||
858 | params->u.ofdm.bandwidth : 0; | ||
859 | |||
860 | return 5; | ||
861 | } | ||
862 | |||
863 | static int simple_dvb_set_params(struct dvb_frontend *fe, | ||
864 | struct dvb_frontend_parameters *params) | ||
865 | { | ||
866 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
867 | u32 prev_freq, prev_bw; | ||
868 | int ret; | ||
869 | u8 buf[5]; | ||
870 | |||
871 | if (priv->i2c_props.adap == NULL) | ||
872 | return -EINVAL; | ||
873 | |||
874 | prev_freq = priv->frequency; | ||
875 | prev_bw = priv->bandwidth; | ||
876 | |||
877 | ret = simple_dvb_calc_regs(fe, params, buf, 5); | ||
878 | if (ret != 5) | ||
879 | goto fail; | ||
880 | |||
881 | /* put analog demod in standby when tuning digital */ | ||
882 | if (fe->ops.analog_ops.standby) | ||
883 | fe->ops.analog_ops.standby(fe); | ||
884 | |||
885 | if (fe->ops.i2c_gate_ctrl) | ||
886 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
887 | |||
888 | /* buf[0] contains the i2c address, but * | ||
889 | * we already have it in i2c_props.addr */ | ||
890 | ret = tuner_i2c_xfer_send(&priv->i2c_props, buf+1, 4); | ||
891 | if (ret != 4) | ||
892 | goto fail; | ||
893 | |||
894 | return 0; | ||
895 | fail: | ||
896 | /* calc_regs sets frequency and bandwidth. if we failed, unset them */ | ||
897 | priv->frequency = prev_freq; | ||
898 | priv->bandwidth = prev_bw; | ||
899 | |||
900 | return ret; | ||
901 | } | ||
902 | |||
903 | static int simple_init(struct dvb_frontend *fe) | ||
904 | { | ||
905 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
906 | |||
907 | if (priv->i2c_props.adap == NULL) | ||
908 | return -EINVAL; | ||
909 | |||
910 | if (priv->tun->initdata) { | ||
911 | int ret; | ||
912 | |||
913 | if (fe->ops.i2c_gate_ctrl) | ||
914 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
915 | |||
916 | ret = tuner_i2c_xfer_send(&priv->i2c_props, | ||
917 | priv->tun->initdata + 1, | ||
918 | priv->tun->initdata[0]); | ||
919 | if (ret != priv->tun->initdata[0]) | ||
920 | return ret; | ||
921 | } | ||
922 | |||
923 | return 0; | ||
924 | } | ||
925 | |||
926 | static int simple_sleep(struct dvb_frontend *fe) | ||
927 | { | ||
928 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
929 | |||
930 | if (priv->i2c_props.adap == NULL) | ||
931 | return -EINVAL; | ||
932 | |||
933 | if (priv->tun->sleepdata) { | ||
934 | int ret; | ||
935 | |||
936 | if (fe->ops.i2c_gate_ctrl) | ||
937 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
938 | |||
939 | ret = tuner_i2c_xfer_send(&priv->i2c_props, | ||
940 | priv->tun->sleepdata + 1, | ||
941 | priv->tun->sleepdata[0]); | ||
942 | if (ret != priv->tun->sleepdata[0]) | ||
943 | return ret; | ||
944 | } | ||
945 | |||
946 | return 0; | ||
947 | } | ||
589 | 948 | ||
590 | static int simple_release(struct dvb_frontend *fe) | 949 | static int simple_release(struct dvb_frontend *fe) |
591 | { | 950 | { |
592 | kfree(fe->tuner_priv); | 951 | struct tuner_simple_priv *priv = fe->tuner_priv; |
952 | |||
953 | mutex_lock(&tuner_simple_list_mutex); | ||
954 | |||
955 | if (priv) | ||
956 | hybrid_tuner_release_state(priv); | ||
957 | |||
958 | mutex_unlock(&tuner_simple_list_mutex); | ||
959 | |||
593 | fe->tuner_priv = NULL; | 960 | fe->tuner_priv = NULL; |
594 | 961 | ||
595 | return 0; | 962 | return 0; |
@@ -602,10 +969,22 @@ static int simple_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
602 | return 0; | 969 | return 0; |
603 | } | 970 | } |
604 | 971 | ||
972 | static int simple_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | ||
973 | { | ||
974 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
975 | *bandwidth = priv->bandwidth; | ||
976 | return 0; | ||
977 | } | ||
978 | |||
605 | static struct dvb_tuner_ops simple_tuner_ops = { | 979 | static struct dvb_tuner_ops simple_tuner_ops = { |
980 | .init = simple_init, | ||
981 | .sleep = simple_sleep, | ||
606 | .set_analog_params = simple_set_params, | 982 | .set_analog_params = simple_set_params, |
983 | .set_params = simple_dvb_set_params, | ||
984 | .calc_regs = simple_dvb_calc_regs, | ||
607 | .release = simple_release, | 985 | .release = simple_release, |
608 | .get_frequency = simple_get_frequency, | 986 | .get_frequency = simple_get_frequency, |
987 | .get_bandwidth = simple_get_bandwidth, | ||
609 | .get_status = simple_get_status, | 988 | .get_status = simple_get_status, |
610 | .get_rf_strength = simple_get_rf_strength, | 989 | .get_rf_strength = simple_get_rf_strength, |
611 | }; | 990 | }; |
@@ -613,30 +992,92 @@ static struct dvb_tuner_ops simple_tuner_ops = { | |||
613 | struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, | 992 | struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, |
614 | struct i2c_adapter *i2c_adap, | 993 | struct i2c_adapter *i2c_adap, |
615 | u8 i2c_addr, | 994 | u8 i2c_addr, |
616 | struct simple_tuner_config *cfg) | 995 | unsigned int type) |
617 | { | 996 | { |
618 | struct tuner_simple_priv *priv = NULL; | 997 | struct tuner_simple_priv *priv = NULL; |
998 | int instance; | ||
619 | 999 | ||
620 | priv = kzalloc(sizeof(struct tuner_simple_priv), GFP_KERNEL); | 1000 | if (type >= tuner_count) { |
621 | if (priv == NULL) | 1001 | printk(KERN_WARNING "%s: invalid tuner type: %d (max: %d)\n", |
1002 | __func__, type, tuner_count-1); | ||
622 | return NULL; | 1003 | return NULL; |
623 | fe->tuner_priv = priv; | 1004 | } |
624 | 1005 | ||
625 | priv->i2c_props.addr = i2c_addr; | 1006 | /* If i2c_adap is set, check that the tuner is at the correct address. |
626 | priv->i2c_props.adap = i2c_adap; | 1007 | * Otherwise, if i2c_adap is NULL, the tuner will be programmed directly |
627 | priv->type = cfg->type; | 1008 | * by the digital demod via calc_regs. |
628 | priv->tun = cfg->tun; | 1009 | */ |
1010 | if (i2c_adap != NULL) { | ||
1011 | u8 b[1]; | ||
1012 | struct i2c_msg msg = { | ||
1013 | .addr = i2c_addr, .flags = I2C_M_RD, | ||
1014 | .buf = b, .len = 1, | ||
1015 | }; | ||
1016 | |||
1017 | if (fe->ops.i2c_gate_ctrl) | ||
1018 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1019 | |||
1020 | if (1 != i2c_transfer(i2c_adap, &msg, 1)) | ||
1021 | tuner_warn("unable to probe %s, proceeding anyway.", | ||
1022 | tuners[type].name); | ||
1023 | |||
1024 | if (fe->ops.i2c_gate_ctrl) | ||
1025 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
1026 | } | ||
629 | 1027 | ||
630 | memcpy(&fe->ops.tuner_ops, &simple_tuner_ops, sizeof(struct dvb_tuner_ops)); | 1028 | mutex_lock(&tuner_simple_list_mutex); |
631 | 1029 | ||
632 | tuner_info("type set to %d (%s)\n", cfg->type, cfg->tun->name); | 1030 | instance = hybrid_tuner_request_state(struct tuner_simple_priv, priv, |
1031 | hybrid_tuner_instance_list, | ||
1032 | i2c_adap, i2c_addr, | ||
1033 | "tuner-simple"); | ||
1034 | switch (instance) { | ||
1035 | case 0: | ||
1036 | mutex_unlock(&tuner_simple_list_mutex); | ||
1037 | return NULL; | ||
1038 | break; | ||
1039 | case 1: | ||
1040 | fe->tuner_priv = priv; | ||
633 | 1041 | ||
634 | strlcpy(fe->ops.tuner_ops.info.name, cfg->tun->name, sizeof(fe->ops.tuner_ops.info.name)); | 1042 | priv->type = type; |
1043 | priv->tun = &tuners[type]; | ||
1044 | priv->nr = simple_devcount++; | ||
1045 | break; | ||
1046 | default: | ||
1047 | fe->tuner_priv = priv; | ||
1048 | break; | ||
1049 | } | ||
635 | 1050 | ||
636 | return fe; | 1051 | mutex_unlock(&tuner_simple_list_mutex); |
637 | } | 1052 | |
1053 | memcpy(&fe->ops.tuner_ops, &simple_tuner_ops, | ||
1054 | sizeof(struct dvb_tuner_ops)); | ||
1055 | |||
1056 | tuner_info("type set to %d (%s)\n", type, priv->tun->name); | ||
1057 | |||
1058 | if ((debug) || ((atv_input[priv->nr] > 0) || | ||
1059 | (dtv_input[priv->nr] > 0))) { | ||
1060 | if (0 == atv_input[priv->nr]) | ||
1061 | tuner_info("tuner %d atv rf input will be " | ||
1062 | "autoselected\n", priv->nr); | ||
1063 | else | ||
1064 | tuner_info("tuner %d atv rf input will be " | ||
1065 | "set to input %d (insmod option)\n", | ||
1066 | priv->nr, atv_input[priv->nr]); | ||
1067 | if (0 == dtv_input[priv->nr]) | ||
1068 | tuner_info("tuner %d dtv rf input will be " | ||
1069 | "autoselected\n", priv->nr); | ||
1070 | else | ||
1071 | tuner_info("tuner %d dtv rf input will be " | ||
1072 | "set to input %d (insmod option)\n", | ||
1073 | priv->nr, dtv_input[priv->nr]); | ||
1074 | } | ||
638 | 1075 | ||
1076 | strlcpy(fe->ops.tuner_ops.info.name, priv->tun->name, | ||
1077 | sizeof(fe->ops.tuner_ops.info.name)); | ||
639 | 1078 | ||
1079 | return fe; | ||
1080 | } | ||
640 | EXPORT_SYMBOL_GPL(simple_tuner_attach); | 1081 | EXPORT_SYMBOL_GPL(simple_tuner_attach); |
641 | 1082 | ||
642 | MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver"); | 1083 | MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver"); |
diff --git a/drivers/media/video/tuner-simple.h b/drivers/media/video/tuner-simple.h index 9089939a8c02..e46cf0121e03 100644 --- a/drivers/media/video/tuner-simple.h +++ b/drivers/media/video/tuner-simple.h | |||
@@ -20,25 +20,18 @@ | |||
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include "dvb_frontend.h" | 21 | #include "dvb_frontend.h" |
22 | 22 | ||
23 | struct simple_tuner_config | ||
24 | { | ||
25 | /* chip type */ | ||
26 | unsigned int type; | ||
27 | struct tunertype *tun; | ||
28 | }; | ||
29 | |||
30 | #if defined(CONFIG_TUNER_SIMPLE) || (defined(CONFIG_TUNER_SIMPLE_MODULE) && defined(MODULE)) | 23 | #if defined(CONFIG_TUNER_SIMPLE) || (defined(CONFIG_TUNER_SIMPLE_MODULE) && defined(MODULE)) |
31 | extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, | 24 | extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, |
32 | struct i2c_adapter *i2c_adap, | 25 | struct i2c_adapter *i2c_adap, |
33 | u8 i2c_addr, | 26 | u8 i2c_addr, |
34 | struct simple_tuner_config *cfg); | 27 | unsigned int type); |
35 | #else | 28 | #else |
36 | static inline struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, | 29 | static inline struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, |
37 | struct i2c_adapter *i2c_adap, | 30 | struct i2c_adapter *i2c_adap, |
38 | u8 i2c_addr, | 31 | u8 i2c_addr, |
39 | struct simple_tuner_config *cfg) | 32 | unsigned int type) |
40 | { | 33 | { |
41 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | 34 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
42 | return NULL; | 35 | return NULL; |
43 | } | 36 | } |
44 | #endif | 37 | #endif |
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index 883047f9c28c..10dddca8b5d1 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c | |||
@@ -35,6 +35,27 @@ | |||
35 | * based on the video standard in use. | 35 | * based on the video standard in use. |
36 | */ | 36 | */ |
37 | 37 | ||
38 | /* The following was taken from dvb-pll.c: */ | ||
39 | |||
40 | /* Set AGC TOP value to 103 dBuV: | ||
41 | * 0x80 = Control Byte | ||
42 | * 0x40 = 250 uA charge pump (irrelevant) | ||
43 | * 0x18 = Aux Byte to follow | ||
44 | * 0x06 = 64.5 kHz divider (irrelevant) | ||
45 | * 0x01 = Disable Vt (aka sleep) | ||
46 | * | ||
47 | * 0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA) | ||
48 | * 0x50 = AGC Take over point = 103 dBuV | ||
49 | */ | ||
50 | static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 }; | ||
51 | |||
52 | /* 0x04 = 166.67 kHz divider | ||
53 | * | ||
54 | * 0x80 = AGC Time constant 50ms Iagc = 9 uA | ||
55 | * 0x20 = AGC Take over point = 112 dBuV | ||
56 | */ | ||
57 | static u8 tua603x_agc112[] = { 2, 0x80|0x40|0x18|0x04|0x01, 0x80|0x20 }; | ||
58 | |||
38 | /* 0-9 */ | 59 | /* 0-9 */ |
39 | /* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */ | 60 | /* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */ |
40 | 61 | ||
@@ -594,19 +615,31 @@ static struct tuner_params tuner_philips_pal_mk_params[] = { | |||
594 | }, | 615 | }, |
595 | }; | 616 | }; |
596 | 617 | ||
597 | /* ---- TUNER_PHILIPS_ATSC - Philips FCV1236D (ATSC/NTSC) ---- */ | 618 | /* ---- TUNER_PHILIPS_FCV1236D - Philips FCV1236D (ATSC/NTSC) ---- */ |
598 | 619 | ||
599 | static struct tuner_range tuner_philips_fcv1236d_ranges[] = { | 620 | static struct tuner_range tuner_philips_fcv1236d_ntsc_ranges[] = { |
600 | { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, }, | 621 | { 16 * 157.25 /*MHz*/, 0x8e, 0xa2, }, |
601 | { 16 * 451.25 /*MHz*/, 0x8e, 0x90, }, | 622 | { 16 * 451.25 /*MHz*/, 0x8e, 0x92, }, |
623 | { 16 * 999.99 , 0x8e, 0x32, }, | ||
624 | }; | ||
625 | |||
626 | static struct tuner_range tuner_philips_fcv1236d_atsc_ranges[] = { | ||
627 | { 16 * 159.00 /*MHz*/, 0x8e, 0xa0, }, | ||
628 | { 16 * 453.00 /*MHz*/, 0x8e, 0x90, }, | ||
602 | { 16 * 999.99 , 0x8e, 0x30, }, | 629 | { 16 * 999.99 , 0x8e, 0x30, }, |
603 | }; | 630 | }; |
604 | 631 | ||
605 | static struct tuner_params tuner_philips_fcv1236d_params[] = { | 632 | static struct tuner_params tuner_philips_fcv1236d_params[] = { |
606 | { | 633 | { |
607 | .type = TUNER_PARAM_TYPE_NTSC, | 634 | .type = TUNER_PARAM_TYPE_NTSC, |
608 | .ranges = tuner_philips_fcv1236d_ranges, | 635 | .ranges = tuner_philips_fcv1236d_ntsc_ranges, |
609 | .count = ARRAY_SIZE(tuner_philips_fcv1236d_ranges), | 636 | .count = ARRAY_SIZE(tuner_philips_fcv1236d_ntsc_ranges), |
637 | }, | ||
638 | { | ||
639 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
640 | .ranges = tuner_philips_fcv1236d_atsc_ranges, | ||
641 | .count = ARRAY_SIZE(tuner_philips_fcv1236d_atsc_ranges), | ||
642 | .iffreq = 16 * 44.00, | ||
610 | }, | 643 | }, |
611 | }; | 644 | }; |
612 | 645 | ||
@@ -701,12 +734,24 @@ static struct tuner_range tuner_microtune_4042fi5_ntsc_ranges[] = { | |||
701 | { 16 * 999.99 , 0x8e, 0x31, }, | 734 | { 16 * 999.99 , 0x8e, 0x31, }, |
702 | }; | 735 | }; |
703 | 736 | ||
737 | static struct tuner_range tuner_microtune_4042fi5_atsc_ranges[] = { | ||
738 | { 16 * 162.00 /*MHz*/, 0x8e, 0xa1, }, | ||
739 | { 16 * 457.00 /*MHz*/, 0x8e, 0x91, }, | ||
740 | { 16 * 999.99 , 0x8e, 0x31, }, | ||
741 | }; | ||
742 | |||
704 | static struct tuner_params tuner_microtune_4042fi5_params[] = { | 743 | static struct tuner_params tuner_microtune_4042fi5_params[] = { |
705 | { | 744 | { |
706 | .type = TUNER_PARAM_TYPE_NTSC, | 745 | .type = TUNER_PARAM_TYPE_NTSC, |
707 | .ranges = tuner_microtune_4042fi5_ntsc_ranges, | 746 | .ranges = tuner_microtune_4042fi5_ntsc_ranges, |
708 | .count = ARRAY_SIZE(tuner_microtune_4042fi5_ntsc_ranges), | 747 | .count = ARRAY_SIZE(tuner_microtune_4042fi5_ntsc_ranges), |
709 | }, | 748 | }, |
749 | { | ||
750 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
751 | .ranges = tuner_microtune_4042fi5_atsc_ranges, | ||
752 | .count = ARRAY_SIZE(tuner_microtune_4042fi5_atsc_ranges), | ||
753 | .iffreq = 16 * 44.00 /*MHz*/, | ||
754 | }, | ||
710 | }; | 755 | }; |
711 | 756 | ||
712 | /* 50-59 */ | 757 | /* 50-59 */ |
@@ -740,6 +785,7 @@ static struct tuner_params tuner_philips_fm1256_ih3_params[] = { | |||
740 | 785 | ||
741 | /* ------------ TUNER_THOMSON_DTT7610 - THOMSON ATSC ------------ */ | 786 | /* ------------ TUNER_THOMSON_DTT7610 - THOMSON ATSC ------------ */ |
742 | 787 | ||
788 | /* single range used for both ntsc and atsc */ | ||
743 | static struct tuner_range tuner_thomson_dtt7610_ntsc_ranges[] = { | 789 | static struct tuner_range tuner_thomson_dtt7610_ntsc_ranges[] = { |
744 | { 16 * 157.25 /*MHz*/, 0x8e, 0x39, }, | 790 | { 16 * 157.25 /*MHz*/, 0x8e, 0x39, }, |
745 | { 16 * 454.00 /*MHz*/, 0x8e, 0x3a, }, | 791 | { 16 * 454.00 /*MHz*/, 0x8e, 0x3a, }, |
@@ -752,6 +798,12 @@ static struct tuner_params tuner_thomson_dtt7610_params[] = { | |||
752 | .ranges = tuner_thomson_dtt7610_ntsc_ranges, | 798 | .ranges = tuner_thomson_dtt7610_ntsc_ranges, |
753 | .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges), | 799 | .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges), |
754 | }, | 800 | }, |
801 | { | ||
802 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
803 | .ranges = tuner_thomson_dtt7610_ntsc_ranges, | ||
804 | .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges), | ||
805 | .iffreq = 16 * 44.00 /*MHz*/, | ||
806 | }, | ||
755 | }; | 807 | }; |
756 | 808 | ||
757 | /* ------------ TUNER_PHILIPS_FQ1286 - Philips NTSC ------------ */ | 809 | /* ------------ TUNER_PHILIPS_FQ1286 - Philips NTSC ------------ */ |
@@ -855,6 +907,11 @@ static struct tuner_range tuner_thomson_dtt761x_ntsc_ranges[] = { | |||
855 | { 16 * 999.99 , 0x8e, 0x3c, }, | 907 | { 16 * 999.99 , 0x8e, 0x3c, }, |
856 | }; | 908 | }; |
857 | 909 | ||
910 | static struct tuner_range tuner_thomson_dtt761x_atsc_ranges[] = { | ||
911 | { 16 * 147.00 /*MHz*/, 0x8e, 0x39, }, | ||
912 | { 16 * 417.00 /*MHz*/, 0x8e, 0x3a, }, | ||
913 | { 16 * 999.99 , 0x8e, 0x3c, }, | ||
914 | }; | ||
858 | 915 | ||
859 | static struct tuner_params tuner_thomson_dtt761x_params[] = { | 916 | static struct tuner_params tuner_thomson_dtt761x_params[] = { |
860 | { | 917 | { |
@@ -865,6 +922,12 @@ static struct tuner_params tuner_thomson_dtt761x_params[] = { | |||
865 | .fm_gain_normal = 1, | 922 | .fm_gain_normal = 1, |
866 | .radio_if = 2, /* 41.3 MHz */ | 923 | .radio_if = 2, /* 41.3 MHz */ |
867 | }, | 924 | }, |
925 | { | ||
926 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
927 | .ranges = tuner_thomson_dtt761x_atsc_ranges, | ||
928 | .count = ARRAY_SIZE(tuner_thomson_dtt761x_atsc_ranges), | ||
929 | .iffreq = 16 * 44.00, /*MHz*/ | ||
930 | }, | ||
868 | }; | 931 | }; |
869 | 932 | ||
870 | /* ------------ TUNER_TENA_9533_DI - Philips PAL ------------ */ | 933 | /* ------------ TUNER_TENA_9533_DI - Philips PAL ------------ */ |
@@ -891,6 +954,15 @@ static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = { | |||
891 | { 16 * 999.99 , 0x86, 0x54, }, | 954 | { 16 * 999.99 , 0x86, 0x54, }, |
892 | }; | 955 | }; |
893 | 956 | ||
957 | static struct tuner_range tuner_philips_fmd1216me_mk3_dvb_ranges[] = { | ||
958 | { 16 * 143.87 /*MHz*/, 0xbc, 0x41 }, | ||
959 | { 16 * 158.87 /*MHz*/, 0xf4, 0x41 }, | ||
960 | { 16 * 329.87 /*MHz*/, 0xbc, 0x42 }, | ||
961 | { 16 * 441.87 /*MHz*/, 0xf4, 0x42 }, | ||
962 | { 16 * 625.87 /*MHz*/, 0xbc, 0x44 }, | ||
963 | { 16 * 803.87 /*MHz*/, 0xf4, 0x44 }, | ||
964 | { 16 * 999.99 , 0xfc, 0x44 }, | ||
965 | }; | ||
894 | 966 | ||
895 | static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { | 967 | static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { |
896 | { | 968 | { |
@@ -904,6 +976,12 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { | |||
904 | .port2_invert_for_secam_lc = 1, | 976 | .port2_invert_for_secam_lc = 1, |
905 | .port1_set_for_fm_mono = 1, | 977 | .port1_set_for_fm_mono = 1, |
906 | }, | 978 | }, |
979 | { | ||
980 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
981 | .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges, | ||
982 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges), | ||
983 | .iffreq = 16 * 36.125, /*MHz*/ | ||
984 | }, | ||
907 | }; | 985 | }; |
908 | 986 | ||
909 | 987 | ||
@@ -915,6 +993,11 @@ static struct tuner_range tuner_tua6034_ntsc_ranges[] = { | |||
915 | { 16 * 999.99 , 0x8e, 0x04 }, | 993 | { 16 * 999.99 , 0x8e, 0x04 }, |
916 | }; | 994 | }; |
917 | 995 | ||
996 | static struct tuner_range tuner_tua6034_atsc_ranges[] = { | ||
997 | { 16 * 165.00 /*MHz*/, 0xce, 0x01 }, | ||
998 | { 16 * 450.00 /*MHz*/, 0xce, 0x02 }, | ||
999 | { 16 * 999.99 , 0xce, 0x04 }, | ||
1000 | }; | ||
918 | 1001 | ||
919 | static struct tuner_params tuner_lg_tdvs_h06xf_params[] = { | 1002 | static struct tuner_params tuner_lg_tdvs_h06xf_params[] = { |
920 | { | 1003 | { |
@@ -922,6 +1005,12 @@ static struct tuner_params tuner_lg_tdvs_h06xf_params[] = { | |||
922 | .ranges = tuner_tua6034_ntsc_ranges, | 1005 | .ranges = tuner_tua6034_ntsc_ranges, |
923 | .count = ARRAY_SIZE(tuner_tua6034_ntsc_ranges), | 1006 | .count = ARRAY_SIZE(tuner_tua6034_ntsc_ranges), |
924 | }, | 1007 | }, |
1008 | { | ||
1009 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
1010 | .ranges = tuner_tua6034_atsc_ranges, | ||
1011 | .count = ARRAY_SIZE(tuner_tua6034_atsc_ranges), | ||
1012 | .iffreq = 16 * 44.00, | ||
1013 | }, | ||
925 | }; | 1014 | }; |
926 | 1015 | ||
927 | /* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */ | 1016 | /* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */ |
@@ -974,12 +1063,30 @@ static struct tuner_range tuner_philips_td1316_pal_ranges[] = { | |||
974 | { 16 * 999.99 , 0xc8, 0xa4, }, | 1063 | { 16 * 999.99 , 0xc8, 0xa4, }, |
975 | }; | 1064 | }; |
976 | 1065 | ||
1066 | static struct tuner_range tuner_philips_td1316_dvb_ranges[] = { | ||
1067 | { 16 * 93.834 /*MHz*/, 0xca, 0x60, }, | ||
1068 | { 16 * 123.834 /*MHz*/, 0xca, 0xa0, }, | ||
1069 | { 16 * 163.834 /*MHz*/, 0xca, 0xc0, }, | ||
1070 | { 16 * 253.834 /*MHz*/, 0xca, 0x60, }, | ||
1071 | { 16 * 383.834 /*MHz*/, 0xca, 0xa0, }, | ||
1072 | { 16 * 443.834 /*MHz*/, 0xca, 0xc0, }, | ||
1073 | { 16 * 583.834 /*MHz*/, 0xca, 0x60, }, | ||
1074 | { 16 * 793.834 /*MHz*/, 0xca, 0xa0, }, | ||
1075 | { 16 * 999.999 , 0xca, 0xe0, }, | ||
1076 | }; | ||
1077 | |||
977 | static struct tuner_params tuner_philips_td1316_params[] = { | 1078 | static struct tuner_params tuner_philips_td1316_params[] = { |
978 | { | 1079 | { |
979 | .type = TUNER_PARAM_TYPE_PAL, | 1080 | .type = TUNER_PARAM_TYPE_PAL, |
980 | .ranges = tuner_philips_td1316_pal_ranges, | 1081 | .ranges = tuner_philips_td1316_pal_ranges, |
981 | .count = ARRAY_SIZE(tuner_philips_td1316_pal_ranges), | 1082 | .count = ARRAY_SIZE(tuner_philips_td1316_pal_ranges), |
982 | }, | 1083 | }, |
1084 | { | ||
1085 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
1086 | .ranges = tuner_philips_td1316_dvb_ranges, | ||
1087 | .count = ARRAY_SIZE(tuner_philips_td1316_dvb_ranges), | ||
1088 | .iffreq = 16 * 36.166667 /*MHz*/, | ||
1089 | }, | ||
983 | }; | 1090 | }; |
984 | 1091 | ||
985 | /* ------------ TUNER_PHILIPS_TUV1236D - Philips ATSC ------------ */ | 1092 | /* ------------ TUNER_PHILIPS_TUV1236D - Philips ATSC ------------ */ |
@@ -990,6 +1097,11 @@ static struct tuner_range tuner_tuv1236d_ntsc_ranges[] = { | |||
990 | { 16 * 999.99 , 0xce, 0x04, }, | 1097 | { 16 * 999.99 , 0xce, 0x04, }, |
991 | }; | 1098 | }; |
992 | 1099 | ||
1100 | static struct tuner_range tuner_tuv1236d_atsc_ranges[] = { | ||
1101 | { 16 * 157.25 /*MHz*/, 0xc6, 0x41, }, | ||
1102 | { 16 * 454.00 /*MHz*/, 0xc6, 0x42, }, | ||
1103 | { 16 * 999.99 , 0xc6, 0x44, }, | ||
1104 | }; | ||
993 | 1105 | ||
994 | static struct tuner_params tuner_tuv1236d_params[] = { | 1106 | static struct tuner_params tuner_tuv1236d_params[] = { |
995 | { | 1107 | { |
@@ -997,6 +1109,12 @@ static struct tuner_params tuner_tuv1236d_params[] = { | |||
997 | .ranges = tuner_tuv1236d_ntsc_ranges, | 1109 | .ranges = tuner_tuv1236d_ntsc_ranges, |
998 | .count = ARRAY_SIZE(tuner_tuv1236d_ntsc_ranges), | 1110 | .count = ARRAY_SIZE(tuner_tuv1236d_ntsc_ranges), |
999 | }, | 1111 | }, |
1112 | { | ||
1113 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
1114 | .ranges = tuner_tuv1236d_atsc_ranges, | ||
1115 | .count = ARRAY_SIZE(tuner_tuv1236d_atsc_ranges), | ||
1116 | .iffreq = 16 * 44.00, | ||
1117 | }, | ||
1000 | }; | 1118 | }; |
1001 | 1119 | ||
1002 | /* ------------ TUNER_TNF_xxx5 - Texas Instruments--------- */ | 1120 | /* ------------ TUNER_TNF_xxx5 - Texas Instruments--------- */ |
@@ -1050,17 +1168,30 @@ static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = { | |||
1050 | 1168 | ||
1051 | /* ------------ TUNER_THOMSON_FE6600 - DViCO Hybrid PAL ------------ */ | 1169 | /* ------------ TUNER_THOMSON_FE6600 - DViCO Hybrid PAL ------------ */ |
1052 | 1170 | ||
1053 | static struct tuner_range tuner_thomson_fe6600_ranges[] = { | 1171 | static struct tuner_range tuner_thomson_fe6600_pal_ranges[] = { |
1054 | { 16 * 160.00 /*MHz*/, 0xfe, 0x11, }, | 1172 | { 16 * 160.00 /*MHz*/, 0xfe, 0x11, }, |
1055 | { 16 * 442.00 /*MHz*/, 0xf6, 0x12, }, | 1173 | { 16 * 442.00 /*MHz*/, 0xf6, 0x12, }, |
1056 | { 16 * 999.99 , 0xf6, 0x18, }, | 1174 | { 16 * 999.99 , 0xf6, 0x18, }, |
1057 | }; | 1175 | }; |
1058 | 1176 | ||
1177 | static struct tuner_range tuner_thomson_fe6600_dvb_ranges[] = { | ||
1178 | { 16 * 250.00 /*MHz*/, 0xb4, 0x12, }, | ||
1179 | { 16 * 455.00 /*MHz*/, 0xfe, 0x11, }, | ||
1180 | { 16 * 775.50 /*MHz*/, 0xbc, 0x18, }, | ||
1181 | { 16 * 999.99 , 0xf4, 0x18, }, | ||
1182 | }; | ||
1183 | |||
1059 | static struct tuner_params tuner_thomson_fe6600_params[] = { | 1184 | static struct tuner_params tuner_thomson_fe6600_params[] = { |
1060 | { | 1185 | { |
1061 | .type = TUNER_PARAM_TYPE_PAL, | 1186 | .type = TUNER_PARAM_TYPE_PAL, |
1062 | .ranges = tuner_thomson_fe6600_ranges, | 1187 | .ranges = tuner_thomson_fe6600_pal_ranges, |
1063 | .count = ARRAY_SIZE(tuner_thomson_fe6600_ranges), | 1188 | .count = ARRAY_SIZE(tuner_thomson_fe6600_pal_ranges), |
1189 | }, | ||
1190 | { | ||
1191 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
1192 | .ranges = tuner_thomson_fe6600_dvb_ranges, | ||
1193 | .count = ARRAY_SIZE(tuner_thomson_fe6600_dvb_ranges), | ||
1194 | .iffreq = 16 * 36.125 /*MHz*/, | ||
1064 | }, | 1195 | }, |
1065 | }; | 1196 | }; |
1066 | 1197 | ||
@@ -1303,10 +1434,13 @@ struct tunertype tuners[] = { | |||
1303 | .params = tuner_philips_pal_mk_params, | 1434 | .params = tuner_philips_pal_mk_params, |
1304 | .count = ARRAY_SIZE(tuner_philips_pal_mk_params), | 1435 | .count = ARRAY_SIZE(tuner_philips_pal_mk_params), |
1305 | }, | 1436 | }, |
1306 | [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */ | 1437 | [TUNER_PHILIPS_FCV1236D] = { /* Philips ATSC */ |
1307 | .name = "Philips FCV1236D ATSC/NTSC dual in", | 1438 | .name = "Philips FCV1236D ATSC/NTSC dual in", |
1308 | .params = tuner_philips_fcv1236d_params, | 1439 | .params = tuner_philips_fcv1236d_params, |
1309 | .count = ARRAY_SIZE(tuner_philips_fcv1236d_params), | 1440 | .count = ARRAY_SIZE(tuner_philips_fcv1236d_params), |
1441 | .min = 16 * 53.00, | ||
1442 | .max = 16 * 803.00, | ||
1443 | .stepsize = 62500, | ||
1310 | }, | 1444 | }, |
1311 | [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */ | 1445 | [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */ |
1312 | .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", | 1446 | .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", |
@@ -1342,6 +1476,9 @@ struct tunertype tuners[] = { | |||
1342 | .name = "Microtune 4042 FI5 ATSC/NTSC dual in", | 1476 | .name = "Microtune 4042 FI5 ATSC/NTSC dual in", |
1343 | .params = tuner_microtune_4042fi5_params, | 1477 | .params = tuner_microtune_4042fi5_params, |
1344 | .count = ARRAY_SIZE(tuner_microtune_4042fi5_params), | 1478 | .count = ARRAY_SIZE(tuner_microtune_4042fi5_params), |
1479 | .min = 16 * 57.00, | ||
1480 | .max = 16 * 858.00, | ||
1481 | .stepsize = 62500, | ||
1345 | }, | 1482 | }, |
1346 | 1483 | ||
1347 | /* 50-59 */ | 1484 | /* 50-59 */ |
@@ -1359,6 +1496,9 @@ struct tunertype tuners[] = { | |||
1359 | .name = "Thomson DTT 7610 (ATSC/NTSC)", | 1496 | .name = "Thomson DTT 7610 (ATSC/NTSC)", |
1360 | .params = tuner_thomson_dtt7610_params, | 1497 | .params = tuner_thomson_dtt7610_params, |
1361 | .count = ARRAY_SIZE(tuner_thomson_dtt7610_params), | 1498 | .count = ARRAY_SIZE(tuner_thomson_dtt7610_params), |
1499 | .min = 16 * 44.00, | ||
1500 | .max = 16 * 958.00, | ||
1501 | .stepsize = 62500, | ||
1362 | }, | 1502 | }, |
1363 | [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */ | 1503 | [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */ |
1364 | .name = "Philips FQ1286", | 1504 | .name = "Philips FQ1286", |
@@ -1400,6 +1540,10 @@ struct tunertype tuners[] = { | |||
1400 | .name = "Thomson DTT 761X (ATSC/NTSC)", | 1540 | .name = "Thomson DTT 761X (ATSC/NTSC)", |
1401 | .params = tuner_thomson_dtt761x_params, | 1541 | .params = tuner_thomson_dtt761x_params, |
1402 | .count = ARRAY_SIZE(tuner_thomson_dtt761x_params), | 1542 | .count = ARRAY_SIZE(tuner_thomson_dtt761x_params), |
1543 | .min = 16 * 57.00, | ||
1544 | .max = 16 * 863.00, | ||
1545 | .stepsize = 62500, | ||
1546 | .initdata = tua603x_agc103, | ||
1403 | }, | 1547 | }, |
1404 | [TUNER_TENA_9533_DI] = { /* Philips PAL */ | 1548 | [TUNER_TENA_9533_DI] = { /* Philips PAL */ |
1405 | .name = "Tena TNF9533-D/IF/TNF9533-B/DF", | 1549 | .name = "Tena TNF9533-D/IF/TNF9533-B/DF", |
@@ -1414,11 +1558,20 @@ struct tunertype tuners[] = { | |||
1414 | .name = "Philips FMD1216ME MK3 Hybrid Tuner", | 1558 | .name = "Philips FMD1216ME MK3 Hybrid Tuner", |
1415 | .params = tuner_philips_fmd1216me_mk3_params, | 1559 | .params = tuner_philips_fmd1216me_mk3_params, |
1416 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params), | 1560 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params), |
1561 | .min = 16 * 50.87, | ||
1562 | .max = 16 * 858.00, | ||
1563 | .stepsize = 166667, | ||
1564 | .initdata = tua603x_agc112, | ||
1565 | .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, | ||
1417 | }, | 1566 | }, |
1418 | [TUNER_LG_TDVS_H06XF] = { /* LGINNOTEK ATSC */ | 1567 | [TUNER_LG_TDVS_H06XF] = { /* LGINNOTEK ATSC */ |
1419 | .name = "LG TDVS-H06xF", /* H061F, H062F & H064F */ | 1568 | .name = "LG TDVS-H06xF", /* H061F, H062F & H064F */ |
1420 | .params = tuner_lg_tdvs_h06xf_params, | 1569 | .params = tuner_lg_tdvs_h06xf_params, |
1421 | .count = ARRAY_SIZE(tuner_lg_tdvs_h06xf_params), | 1570 | .count = ARRAY_SIZE(tuner_lg_tdvs_h06xf_params), |
1571 | .min = 16 * 54.00, | ||
1572 | .max = 16 * 863.00, | ||
1573 | .stepsize = 62500, | ||
1574 | .initdata = tua603x_agc103, | ||
1422 | }, | 1575 | }, |
1423 | [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ | 1576 | [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ |
1424 | .name = "Ymec TVF66T5-B/DFF", | 1577 | .name = "Ymec TVF66T5-B/DFF", |
@@ -1434,11 +1587,17 @@ struct tunertype tuners[] = { | |||
1434 | .name = "Philips TD1316 Hybrid Tuner", | 1587 | .name = "Philips TD1316 Hybrid Tuner", |
1435 | .params = tuner_philips_td1316_params, | 1588 | .params = tuner_philips_td1316_params, |
1436 | .count = ARRAY_SIZE(tuner_philips_td1316_params), | 1589 | .count = ARRAY_SIZE(tuner_philips_td1316_params), |
1590 | .min = 16 * 87.00, | ||
1591 | .max = 16 * 895.00, | ||
1592 | .stepsize = 166667, | ||
1437 | }, | 1593 | }, |
1438 | [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */ | 1594 | [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */ |
1439 | .name = "Philips TUV1236D ATSC/NTSC dual in", | 1595 | .name = "Philips TUV1236D ATSC/NTSC dual in", |
1440 | .params = tuner_tuv1236d_params, | 1596 | .params = tuner_tuv1236d_params, |
1441 | .count = ARRAY_SIZE(tuner_tuv1236d_params), | 1597 | .count = ARRAY_SIZE(tuner_tuv1236d_params), |
1598 | .min = 16 * 54.00, | ||
1599 | .max = 16 * 864.00, | ||
1600 | .stepsize = 62500, | ||
1442 | }, | 1601 | }, |
1443 | [TUNER_TNF_5335MF] = { /* Tenna PAL/NTSC */ | 1602 | [TUNER_TNF_5335MF] = { /* Tenna PAL/NTSC */ |
1444 | .name = "Tena TNF 5335 and similar models", | 1603 | .name = "Tena TNF 5335 and similar models", |
@@ -1460,6 +1619,9 @@ struct tunertype tuners[] = { | |||
1460 | .name = "Thomson FE6600", | 1619 | .name = "Thomson FE6600", |
1461 | .params = tuner_thomson_fe6600_params, | 1620 | .params = tuner_thomson_fe6600_params, |
1462 | .count = ARRAY_SIZE(tuner_thomson_fe6600_params), | 1621 | .count = ARRAY_SIZE(tuner_thomson_fe6600_params), |
1622 | .min = 16 * 44.25, | ||
1623 | .max = 16 * 858.00, | ||
1624 | .stepsize = 166667, | ||
1463 | }, | 1625 | }, |
1464 | [TUNER_SAMSUNG_TCPG_6121P30A] = { /* Samsung PAL */ | 1626 | [TUNER_SAMSUNG_TCPG_6121P30A] = { /* Samsung PAL */ |
1465 | .name = "Samsung TCPG 6121P30A", | 1627 | .name = "Samsung TCPG 6121P30A", |
@@ -1480,5 +1642,11 @@ struct tunertype tuners[] = { | |||
1480 | /* see xc5000.c for details */ | 1642 | /* see xc5000.c for details */ |
1481 | }, | 1643 | }, |
1482 | }; | 1644 | }; |
1645 | EXPORT_SYMBOL(tuners); | ||
1483 | 1646 | ||
1484 | unsigned const int tuner_count = ARRAY_SIZE(tuners); | 1647 | unsigned const int tuner_count = ARRAY_SIZE(tuners); |
1648 | EXPORT_SYMBOL(tuner_count); | ||
1649 | |||
1650 | MODULE_DESCRIPTION("Simple tuner device type database"); | ||
1651 | MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); | ||
1652 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/tuner-xc2028-types.h b/drivers/media/video/tuner-xc2028-types.h index d0057fbf0ec7..74dc46a71f64 100644 --- a/drivers/media/video/tuner-xc2028-types.h +++ b/drivers/media/video/tuner-xc2028-types.h | |||
@@ -1,6 +1,9 @@ | |||
1 | /* tuner-xc2028_types | 1 | /* tuner-xc2028_types |
2 | * | 2 | * |
3 | * Copyright (c) 2007 Mauro Carvalho Chehab (mchehab@infradead.org) | 3 | * This file includes internal tipes to be used inside tuner-xc2028. |
4 | * Shouldn't be included outside tuner-xc2028 | ||
5 | * | ||
6 | * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) | ||
4 | * This code is placed under the terms of the GNU General Public License v2 | 7 | * This code is placed under the terms of the GNU General Public License v2 |
5 | */ | 8 | */ |
6 | 9 | ||
@@ -54,11 +57,13 @@ | |||
54 | /* LCD firmwares exist only for MTS STD/MN (PAL or NTSC/M) | 57 | /* LCD firmwares exist only for MTS STD/MN (PAL or NTSC/M) |
55 | and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr) | 58 | and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr) |
56 | There are variants both with and without NOGD | 59 | There are variants both with and without NOGD |
60 | Those firmwares produce better result with LCD displays | ||
57 | */ | 61 | */ |
58 | #define LCD (1<<12) | 62 | #define LCD (1<<12) |
59 | 63 | ||
60 | /* NOGD firmwares exist only for MTS STD/MN (PAL or NTSC/M) | 64 | /* NOGD firmwares exist only for MTS STD/MN (PAL or NTSC/M) |
61 | and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr) | 65 | and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr) |
66 | The NOGD firmwares don't have group delay compensation filter | ||
62 | */ | 67 | */ |
63 | #define NOGD (1<<13) | 68 | #define NOGD (1<<13) |
64 | 69 | ||
@@ -85,11 +90,19 @@ | |||
85 | /* This flag identifies that the scode table has a new format */ | 90 | /* This flag identifies that the scode table has a new format */ |
86 | #define HAS_IF (1 << 30) | 91 | #define HAS_IF (1 << 30) |
87 | 92 | ||
88 | #define SCODE_TYPES (MTS|DTV6|QAM|DTV7|DTV78|DTV8|LCD|NOGD|MONO|ATSC|IF| \ | 93 | /* There are different scode tables for MTS and non-MTS. |
89 | LG60|ATI638|OREN538|OREN36|TOYOTA388|TOYOTA794| \ | 94 | The MTS firmwares support mono only |
90 | DIBCOM52|ZARLINK456|CHINA|F6MHZ|SCODE) | 95 | */ |
96 | #define SCODE_TYPES (SCODE | MTS) | ||
97 | |||
91 | 98 | ||
92 | /* Newer types to be moved to videodev2.h */ | 99 | /* Newer types not defined on videodev2.h. |
100 | The original idea were to move all those types to videodev2.h, but | ||
101 | it seemed overkill, since, with the exception of SECAM/K3, the other | ||
102 | types seem to be autodetected. | ||
103 | It is not clear where secam/k3 is used, nor we have a feedback of this | ||
104 | working or being autodetected by the standard secam firmware. | ||
105 | */ | ||
93 | 106 | ||
94 | #define V4L2_STD_SECAM_K3 (0x04000000) | 107 | #define V4L2_STD_SECAM_K3 (0x04000000) |
95 | 108 | ||
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c index 50cf876f020f..cc3db7d79a0d 100644 --- a/drivers/media/video/tuner-xc2028.c +++ b/drivers/media/video/tuner-xc2028.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* tuner-xc2028 | 1 | /* tuner-xc2028 |
2 | * | 2 | * |
3 | * Copyright (c) 2007 Mauro Carvalho Chehab (mchehab@infradead.org) | 3 | * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) |
4 | * | 4 | * |
5 | * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com) | 5 | * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com) |
6 | * - frontend interface | 6 | * - frontend interface |
@@ -23,8 +23,6 @@ | |||
23 | #include "dvb_frontend.h" | 23 | #include "dvb_frontend.h" |
24 | 24 | ||
25 | 25 | ||
26 | #define PREFIX "xc2028" | ||
27 | |||
28 | static int debug; | 26 | static int debug; |
29 | module_param(debug, int, 0644); | 27 | module_param(debug, int, 0644); |
30 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | 28 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); |
@@ -43,6 +41,11 @@ MODULE_PARM_DESC(audio_std, | |||
43 | "NICAM/A\n" | 41 | "NICAM/A\n" |
44 | "NICAM/B\n"); | 42 | "NICAM/B\n"); |
45 | 43 | ||
44 | static char firmware_name[FIRMWARE_NAME_MAX]; | ||
45 | module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0); | ||
46 | MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the " | ||
47 | "default firmware name\n"); | ||
48 | |||
46 | static LIST_HEAD(xc2028_list); | 49 | static LIST_HEAD(xc2028_list); |
47 | static DEFINE_MUTEX(xc2028_list_mutex); | 50 | static DEFINE_MUTEX(xc2028_list_mutex); |
48 | 51 | ||
@@ -127,12 +130,12 @@ struct xc2028_data { | |||
127 | _rc; \ | 130 | _rc; \ |
128 | }) | 131 | }) |
129 | 132 | ||
130 | static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val) | 133 | static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val) |
131 | { | 134 | { |
132 | unsigned char buf[2]; | 135 | unsigned char buf[2]; |
133 | unsigned char ibuf[2]; | 136 | unsigned char ibuf[2]; |
134 | 137 | ||
135 | tuner_dbg("%s %04x called\n", __FUNCTION__, reg); | 138 | tuner_dbg("%s %04x called\n", __func__, reg); |
136 | 139 | ||
137 | buf[0] = reg >> 8; | 140 | buf[0] = reg >> 8; |
138 | buf[1] = (unsigned char) reg; | 141 | buf[1] = (unsigned char) reg; |
@@ -145,7 +148,7 @@ static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val) | |||
145 | } | 148 | } |
146 | 149 | ||
147 | #define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0) | 150 | #define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0) |
148 | void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq) | 151 | static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq) |
149 | { | 152 | { |
150 | if (type & BASE) | 153 | if (type & BASE) |
151 | printk("BASE "); | 154 | printk("BASE "); |
@@ -232,6 +235,7 @@ static v4l2_std_id parse_audio_std_option(void) | |||
232 | static void free_firmware(struct xc2028_data *priv) | 235 | static void free_firmware(struct xc2028_data *priv) |
233 | { | 236 | { |
234 | int i; | 237 | int i; |
238 | tuner_dbg("%s called\n", __func__); | ||
235 | 239 | ||
236 | if (!priv->firm) | 240 | if (!priv->firm) |
237 | return; | 241 | return; |
@@ -255,19 +259,24 @@ static int load_all_firmwares(struct dvb_frontend *fe) | |||
255 | int rc = 0; | 259 | int rc = 0; |
256 | int n, n_array; | 260 | int n, n_array; |
257 | char name[33]; | 261 | char name[33]; |
262 | char *fname; | ||
263 | |||
264 | tuner_dbg("%s called\n", __func__); | ||
258 | 265 | ||
259 | tuner_dbg("%s called\n", __FUNCTION__); | 266 | if (!firmware_name[0]) |
267 | fname = priv->ctrl.fname; | ||
268 | else | ||
269 | fname = firmware_name; | ||
260 | 270 | ||
261 | tuner_dbg("Reading firmware %s\n", priv->ctrl.fname); | 271 | tuner_dbg("Reading firmware %s\n", fname); |
262 | rc = request_firmware(&fw, priv->ctrl.fname, | 272 | rc = request_firmware(&fw, fname, &priv->i2c_props.adap->dev); |
263 | &priv->i2c_props.adap->dev); | ||
264 | if (rc < 0) { | 273 | if (rc < 0) { |
265 | if (rc == -ENOENT) | 274 | if (rc == -ENOENT) |
266 | tuner_err("Error: firmware %s not found.\n", | 275 | tuner_err("Error: firmware %s not found.\n", |
267 | priv->ctrl.fname); | 276 | fname); |
268 | else | 277 | else |
269 | tuner_err("Error %d while requesting firmware %s \n", | 278 | tuner_err("Error %d while requesting firmware %s \n", |
270 | rc, priv->ctrl.fname); | 279 | rc, fname); |
271 | 280 | ||
272 | return rc; | 281 | return rc; |
273 | } | 282 | } |
@@ -276,7 +285,7 @@ static int load_all_firmwares(struct dvb_frontend *fe) | |||
276 | 285 | ||
277 | if (fw->size < sizeof(name) - 1 + 2 + 2) { | 286 | if (fw->size < sizeof(name) - 1 + 2 + 2) { |
278 | tuner_err("Error: firmware file %s has invalid size!\n", | 287 | tuner_err("Error: firmware file %s has invalid size!\n", |
279 | priv->ctrl.fname); | 288 | fname); |
280 | goto corrupt; | 289 | goto corrupt; |
281 | } | 290 | } |
282 | 291 | ||
@@ -291,7 +300,7 @@ static int load_all_firmwares(struct dvb_frontend *fe) | |||
291 | p += 2; | 300 | p += 2; |
292 | 301 | ||
293 | tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n", | 302 | tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n", |
294 | n_array, priv->ctrl.fname, name, | 303 | n_array, fname, name, |
295 | priv->firm_version >> 8, priv->firm_version & 0xff); | 304 | priv->firm_version >> 8, priv->firm_version & 0xff); |
296 | 305 | ||
297 | priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL); | 306 | priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL); |
@@ -395,9 +404,9 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, | |||
395 | { | 404 | { |
396 | struct xc2028_data *priv = fe->tuner_priv; | 405 | struct xc2028_data *priv = fe->tuner_priv; |
397 | int i, best_i = -1, best_nr_matches = 0; | 406 | int i, best_i = -1, best_nr_matches = 0; |
398 | unsigned int ign_firm_type_mask = 0; | 407 | unsigned int type_mask = 0; |
399 | 408 | ||
400 | tuner_dbg("%s called, want type=", __FUNCTION__); | 409 | tuner_dbg("%s called, want type=", __func__); |
401 | if (debug) { | 410 | if (debug) { |
402 | dump_firm_type(type); | 411 | dump_firm_type(type); |
403 | printk("(%x), id %016llx.\n", type, (unsigned long long)*id); | 412 | printk("(%x), id %016llx.\n", type, (unsigned long long)*id); |
@@ -412,18 +421,23 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, | |||
412 | *id = V4L2_STD_PAL; | 421 | *id = V4L2_STD_PAL; |
413 | 422 | ||
414 | if (type & BASE) | 423 | if (type & BASE) |
415 | type &= BASE_TYPES; | 424 | type_mask = BASE_TYPES; |
416 | else if (type & SCODE) { | 425 | else if (type & SCODE) { |
417 | type &= SCODE_TYPES; | 426 | type &= SCODE_TYPES; |
418 | ign_firm_type_mask = HAS_IF; | 427 | type_mask = SCODE_TYPES & ~HAS_IF; |
419 | } else if (type & DTV_TYPES) | 428 | } else if (type & DTV_TYPES) |
420 | type &= DTV_TYPES; | 429 | type_mask = DTV_TYPES; |
421 | else if (type & STD_SPECIFIC_TYPES) | 430 | else if (type & STD_SPECIFIC_TYPES) |
422 | type &= STD_SPECIFIC_TYPES; | 431 | type_mask = STD_SPECIFIC_TYPES; |
432 | |||
433 | type &= type_mask; | ||
434 | |||
435 | if (!type & SCODE) | ||
436 | type_mask = ~0; | ||
423 | 437 | ||
424 | /* Seek for exact match */ | 438 | /* Seek for exact match */ |
425 | for (i = 0; i < priv->firm_size; i++) { | 439 | for (i = 0; i < priv->firm_size; i++) { |
426 | if ((type == (priv->firm[i].type & ~ign_firm_type_mask)) && | 440 | if ((type == (priv->firm[i].type & type_mask)) && |
427 | (*id == priv->firm[i].id)) | 441 | (*id == priv->firm[i].id)) |
428 | goto found; | 442 | goto found; |
429 | } | 443 | } |
@@ -433,7 +447,7 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, | |||
433 | v4l2_std_id match_mask; | 447 | v4l2_std_id match_mask; |
434 | int nr_matches; | 448 | int nr_matches; |
435 | 449 | ||
436 | if (type != (priv->firm[i].type & ~ign_firm_type_mask)) | 450 | if (type != (priv->firm[i].type & type_mask)) |
437 | continue; | 451 | continue; |
438 | 452 | ||
439 | match_mask = *id & priv->firm[i].id; | 453 | match_mask = *id & priv->firm[i].id; |
@@ -483,7 +497,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, | |||
483 | int pos, rc; | 497 | int pos, rc; |
484 | unsigned char *p, *endp, buf[priv->ctrl.max_len]; | 498 | unsigned char *p, *endp, buf[priv->ctrl.max_len]; |
485 | 499 | ||
486 | tuner_dbg("%s called\n", __FUNCTION__); | 500 | tuner_dbg("%s called\n", __func__); |
487 | 501 | ||
488 | pos = seek_firmware(fe, type, id); | 502 | pos = seek_firmware(fe, type, id); |
489 | if (pos < 0) | 503 | if (pos < 0) |
@@ -586,7 +600,7 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type, | |||
586 | int pos, rc; | 600 | int pos, rc; |
587 | unsigned char *p; | 601 | unsigned char *p; |
588 | 602 | ||
589 | tuner_dbg("%s called\n", __FUNCTION__); | 603 | tuner_dbg("%s called\n", __func__); |
590 | 604 | ||
591 | if (!int_freq) { | 605 | if (!int_freq) { |
592 | pos = seek_firmware(fe, type, id); | 606 | pos = seek_firmware(fe, type, id); |
@@ -650,7 +664,7 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type, | |||
650 | u16 version, hwmodel; | 664 | u16 version, hwmodel; |
651 | v4l2_std_id std0; | 665 | v4l2_std_id std0; |
652 | 666 | ||
653 | tuner_dbg("%s called\n", __FUNCTION__); | 667 | tuner_dbg("%s called\n", __func__); |
654 | 668 | ||
655 | if (!priv->firm) { | 669 | if (!priv->firm) { |
656 | if (!priv->ctrl.fname) { | 670 | if (!priv->ctrl.fname) { |
@@ -770,10 +784,10 @@ check_device: | |||
770 | goto fail; | 784 | goto fail; |
771 | } | 785 | } |
772 | 786 | ||
773 | tuner_info("Device is Xceive %d version %d.%d, " | 787 | tuner_dbg("Device is Xceive %d version %d.%d, " |
774 | "firmware version %d.%d\n", | 788 | "firmware version %d.%d\n", |
775 | hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8, | 789 | hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8, |
776 | (version & 0xf0) >> 4, version & 0xf); | 790 | (version & 0xf0) >> 4, version & 0xf); |
777 | 791 | ||
778 | /* Check firmware version against what we downloaded. */ | 792 | /* Check firmware version against what we downloaded. */ |
779 | if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) { | 793 | if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) { |
@@ -824,27 +838,34 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) | |||
824 | u16 frq_lock, signal = 0; | 838 | u16 frq_lock, signal = 0; |
825 | int rc; | 839 | int rc; |
826 | 840 | ||
827 | tuner_dbg("%s called\n", __FUNCTION__); | 841 | tuner_dbg("%s called\n", __func__); |
828 | 842 | ||
829 | mutex_lock(&priv->lock); | 843 | mutex_lock(&priv->lock); |
830 | 844 | ||
831 | /* Sync Lock Indicator */ | 845 | /* Sync Lock Indicator */ |
832 | rc = xc2028_get_reg(priv, 0x0002, &frq_lock); | 846 | rc = xc2028_get_reg(priv, 0x0002, &frq_lock); |
833 | if (rc < 0 || frq_lock == 0) | 847 | if (rc < 0) |
834 | goto ret; | 848 | goto ret; |
835 | 849 | ||
836 | /* Frequency is locked. Return signal quality */ | 850 | /* Frequency is locked */ |
851 | if (frq_lock == 1) | ||
852 | signal = 32768; | ||
837 | 853 | ||
838 | /* Get SNR of the video signal */ | 854 | /* Get SNR of the video signal */ |
839 | rc = xc2028_get_reg(priv, 0x0040, &signal); | 855 | rc = xc2028_get_reg(priv, 0x0040, &signal); |
840 | if (rc < 0) | 856 | if (rc < 0) |
841 | signal = -frq_lock; | 857 | goto ret; |
858 | |||
859 | /* Use both frq_lock and signal to generate the result */ | ||
860 | signal = signal || ((signal & 0x07) << 12); | ||
842 | 861 | ||
843 | ret: | 862 | ret: |
844 | mutex_unlock(&priv->lock); | 863 | mutex_unlock(&priv->lock); |
845 | 864 | ||
846 | *strength = signal; | 865 | *strength = signal; |
847 | 866 | ||
867 | tuner_dbg("signal strength is %d\n", signal); | ||
868 | |||
848 | return rc; | 869 | return rc; |
849 | } | 870 | } |
850 | 871 | ||
@@ -861,7 +882,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | |||
861 | unsigned char buf[4]; | 882 | unsigned char buf[4]; |
862 | u32 div, offset = 0; | 883 | u32 div, offset = 0; |
863 | 884 | ||
864 | tuner_dbg("%s called\n", __FUNCTION__); | 885 | tuner_dbg("%s called\n", __func__); |
865 | 886 | ||
866 | mutex_lock(&priv->lock); | 887 | mutex_lock(&priv->lock); |
867 | 888 | ||
@@ -906,9 +927,11 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | |||
906 | if (rc < 0) | 927 | if (rc < 0) |
907 | goto ret; | 928 | goto ret; |
908 | 929 | ||
909 | rc = priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1); | 930 | /* Return code shouldn't be checked. |
910 | if (rc < 0) | 931 | The reset CLK is needed only with tm6000. |
911 | goto ret; | 932 | Driver should work fine even if this fails. |
933 | */ | ||
934 | priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1); | ||
912 | 935 | ||
913 | msleep(10); | 936 | msleep(10); |
914 | 937 | ||
@@ -942,7 +965,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe, | |||
942 | struct xc2028_data *priv = fe->tuner_priv; | 965 | struct xc2028_data *priv = fe->tuner_priv; |
943 | unsigned int type=0; | 966 | unsigned int type=0; |
944 | 967 | ||
945 | tuner_dbg("%s called\n", __FUNCTION__); | 968 | tuner_dbg("%s called\n", __func__); |
946 | 969 | ||
947 | if (p->mode == V4L2_TUNER_RADIO) { | 970 | if (p->mode == V4L2_TUNER_RADIO) { |
948 | type |= FM; | 971 | type |= FM; |
@@ -975,7 +998,7 @@ static int xc2028_set_params(struct dvb_frontend *fe, | |||
975 | fe_bandwidth_t bw = BANDWIDTH_8_MHZ; | 998 | fe_bandwidth_t bw = BANDWIDTH_8_MHZ; |
976 | u16 demod = 0; | 999 | u16 demod = 0; |
977 | 1000 | ||
978 | tuner_dbg("%s called\n", __FUNCTION__); | 1001 | tuner_dbg("%s called\n", __func__); |
979 | 1002 | ||
980 | if (priv->ctrl.d2633) | 1003 | if (priv->ctrl.d2633) |
981 | type |= D2633; | 1004 | type |= D2633; |
@@ -1040,33 +1063,12 @@ static int xc2028_set_params(struct dvb_frontend *fe, | |||
1040 | T_DIGITAL_TV, type, 0, demod); | 1063 | T_DIGITAL_TV, type, 0, demod); |
1041 | } | 1064 | } |
1042 | 1065 | ||
1043 | static int xc2028_sleep(struct dvb_frontend *fe) | ||
1044 | { | ||
1045 | struct xc2028_data *priv = fe->tuner_priv; | ||
1046 | int rc = 0; | ||
1047 | |||
1048 | tuner_dbg("%s called\n", __FUNCTION__); | ||
1049 | |||
1050 | mutex_lock(&priv->lock); | ||
1051 | |||
1052 | if (priv->firm_version < 0x0202) | ||
1053 | rc = send_seq(priv, {0x00, 0x08, 0x00, 0x00}); | ||
1054 | else | ||
1055 | rc = send_seq(priv, {0x80, 0x08, 0x00, 0x00}); | ||
1056 | |||
1057 | priv->cur_fw.type = 0; /* need firmware reload */ | ||
1058 | |||
1059 | mutex_unlock(&priv->lock); | ||
1060 | |||
1061 | return rc; | ||
1062 | } | ||
1063 | |||
1064 | 1066 | ||
1065 | static int xc2028_dvb_release(struct dvb_frontend *fe) | 1067 | static int xc2028_dvb_release(struct dvb_frontend *fe) |
1066 | { | 1068 | { |
1067 | struct xc2028_data *priv = fe->tuner_priv; | 1069 | struct xc2028_data *priv = fe->tuner_priv; |
1068 | 1070 | ||
1069 | tuner_dbg("%s called\n", __FUNCTION__); | 1071 | tuner_dbg("%s called\n", __func__); |
1070 | 1072 | ||
1071 | mutex_lock(&xc2028_list_mutex); | 1073 | mutex_lock(&xc2028_list_mutex); |
1072 | 1074 | ||
@@ -1091,7 +1093,7 @@ static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
1091 | { | 1093 | { |
1092 | struct xc2028_data *priv = fe->tuner_priv; | 1094 | struct xc2028_data *priv = fe->tuner_priv; |
1093 | 1095 | ||
1094 | tuner_dbg("%s called\n", __FUNCTION__); | 1096 | tuner_dbg("%s called\n", __func__); |
1095 | 1097 | ||
1096 | *frequency = priv->frequency; | 1098 | *frequency = priv->frequency; |
1097 | 1099 | ||
@@ -1104,25 +1106,25 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) | |||
1104 | struct xc2028_ctrl *p = priv_cfg; | 1106 | struct xc2028_ctrl *p = priv_cfg; |
1105 | int rc = 0; | 1107 | int rc = 0; |
1106 | 1108 | ||
1107 | tuner_dbg("%s called\n", __FUNCTION__); | 1109 | tuner_dbg("%s called\n", __func__); |
1108 | 1110 | ||
1109 | mutex_lock(&priv->lock); | 1111 | mutex_lock(&priv->lock); |
1110 | 1112 | ||
1111 | kfree(priv->ctrl.fname); | ||
1112 | free_firmware(priv); | ||
1113 | |||
1114 | memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); | 1113 | memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); |
1115 | priv->ctrl.fname = NULL; | 1114 | if (priv->ctrl.max_len < 9) |
1115 | priv->ctrl.max_len = 13; | ||
1116 | 1116 | ||
1117 | if (p->fname) { | 1117 | if (p->fname) { |
1118 | if (priv->ctrl.fname && strcmp(p->fname, priv->ctrl.fname)) { | ||
1119 | kfree(priv->ctrl.fname); | ||
1120 | free_firmware(priv); | ||
1121 | } | ||
1122 | |||
1118 | priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); | 1123 | priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); |
1119 | if (priv->ctrl.fname == NULL) | 1124 | if (priv->ctrl.fname == NULL) |
1120 | rc = -ENOMEM; | 1125 | rc = -ENOMEM; |
1121 | } | 1126 | } |
1122 | 1127 | ||
1123 | if (priv->ctrl.max_len < 9) | ||
1124 | priv->ctrl.max_len = 13; | ||
1125 | |||
1126 | mutex_unlock(&priv->lock); | 1128 | mutex_unlock(&priv->lock); |
1127 | 1129 | ||
1128 | return rc; | 1130 | return rc; |
@@ -1142,8 +1144,6 @@ static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = { | |||
1142 | .get_frequency = xc2028_get_frequency, | 1144 | .get_frequency = xc2028_get_frequency, |
1143 | .get_rf_strength = xc2028_signal, | 1145 | .get_rf_strength = xc2028_signal, |
1144 | .set_params = xc2028_set_params, | 1146 | .set_params = xc2028_set_params, |
1145 | .sleep = xc2028_sleep, | ||
1146 | |||
1147 | }; | 1147 | }; |
1148 | 1148 | ||
1149 | struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | 1149 | struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, |
@@ -1153,23 +1153,29 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | |||
1153 | void *video_dev; | 1153 | void *video_dev; |
1154 | 1154 | ||
1155 | if (debug) | 1155 | if (debug) |
1156 | printk(KERN_DEBUG PREFIX ": Xcv2028/3028 init called!\n"); | 1156 | printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n"); |
1157 | 1157 | ||
1158 | if (NULL == cfg || NULL == cfg->video_dev) | 1158 | if (NULL == cfg) |
1159 | return NULL; | 1159 | return NULL; |
1160 | 1160 | ||
1161 | if (!fe) { | 1161 | if (!fe) { |
1162 | printk(KERN_ERR PREFIX ": No frontend!\n"); | 1162 | printk(KERN_ERR "xc2028: No frontend!\n"); |
1163 | return NULL; | 1163 | return NULL; |
1164 | } | 1164 | } |
1165 | 1165 | ||
1166 | video_dev = cfg->video_dev; | 1166 | video_dev = cfg->i2c_adap->algo_data; |
1167 | |||
1168 | if (debug) | ||
1169 | printk(KERN_DEBUG "xc2028: video_dev =%p\n", video_dev); | ||
1167 | 1170 | ||
1168 | mutex_lock(&xc2028_list_mutex); | 1171 | mutex_lock(&xc2028_list_mutex); |
1169 | 1172 | ||
1170 | list_for_each_entry(priv, &xc2028_list, xc2028_list) { | 1173 | list_for_each_entry(priv, &xc2028_list, xc2028_list) { |
1171 | if (priv->video_dev == cfg->video_dev) { | 1174 | if (&priv->i2c_props.adap->dev == &cfg->i2c_adap->dev) { |
1172 | video_dev = NULL; | 1175 | video_dev = NULL; |
1176 | if (debug) | ||
1177 | printk(KERN_DEBUG "xc2028: reusing device\n"); | ||
1178 | |||
1173 | break; | 1179 | break; |
1174 | } | 1180 | } |
1175 | } | 1181 | } |
@@ -1183,6 +1189,8 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | |||
1183 | 1189 | ||
1184 | priv->i2c_props.addr = cfg->i2c_addr; | 1190 | priv->i2c_props.addr = cfg->i2c_addr; |
1185 | priv->i2c_props.adap = cfg->i2c_adap; | 1191 | priv->i2c_props.adap = cfg->i2c_adap; |
1192 | priv->i2c_props.name = "xc2028"; | ||
1193 | |||
1186 | priv->video_dev = video_dev; | 1194 | priv->video_dev = video_dev; |
1187 | priv->tuner_callback = cfg->callback; | 1195 | priv->tuner_callback = cfg->callback; |
1188 | priv->ctrl.max_len = 13; | 1196 | priv->ctrl.max_len = 13; |
@@ -1195,6 +1203,9 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | |||
1195 | fe->tuner_priv = priv; | 1203 | fe->tuner_priv = priv; |
1196 | priv->count++; | 1204 | priv->count++; |
1197 | 1205 | ||
1206 | if (debug) | ||
1207 | printk(KERN_DEBUG "xc2028: usage count is %i\n", priv->count); | ||
1208 | |||
1198 | memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops, | 1209 | memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops, |
1199 | sizeof(xc2028_dvb_tuner_ops)); | 1210 | sizeof(xc2028_dvb_tuner_ops)); |
1200 | 1211 | ||
diff --git a/drivers/media/video/tuner-xc2028.h b/drivers/media/video/tuner-xc2028.h index 3eb8420379a4..fc2f132a5541 100644 --- a/drivers/media/video/tuner-xc2028.h +++ b/drivers/media/video/tuner-xc2028.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* tuner-xc2028 | 1 | /* tuner-xc2028 |
2 | * | 2 | * |
3 | * Copyright (c) 2007 Mauro Carvalho Chehab (mchehab@infradead.org) | 3 | * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) |
4 | * This code is placed under the terms of the GNU General Public License v2 | 4 | * This code is placed under the terms of the GNU General Public License v2 |
5 | */ | 5 | */ |
6 | 6 | ||
@@ -12,7 +12,7 @@ | |||
12 | #define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw" | 12 | #define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw" |
13 | 13 | ||
14 | /* Dmoduler IF (kHz) */ | 14 | /* Dmoduler IF (kHz) */ |
15 | #define XC3028_FE_DEFAULT 0 | 15 | #define XC3028_FE_DEFAULT 0 /* Don't load SCODE */ |
16 | #define XC3028_FE_LG60 6000 | 16 | #define XC3028_FE_LG60 6000 |
17 | #define XC3028_FE_ATI638 6380 | 17 | #define XC3028_FE_ATI638 6380 |
18 | #define XC3028_FE_OREN538 5380 | 18 | #define XC3028_FE_OREN538 5380 |
@@ -55,7 +55,7 @@ static inline struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | |||
55 | struct xc2028_config *cfg) | 55 | struct xc2028_config *cfg) |
56 | { | 56 | { |
57 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", | 57 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", |
58 | __FUNCTION__); | 58 | __func__); |
59 | return NULL; | 59 | return NULL; |
60 | } | 60 | } |
61 | #endif | 61 | #endif |
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 01ebcec040c4..f29a2cd0f2f2 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
@@ -38,7 +38,7 @@ | |||
38 | /* ---------------------------------------------------------------------- */ | 38 | /* ---------------------------------------------------------------------- */ |
39 | /* insmod args */ | 39 | /* insmod args */ |
40 | 40 | ||
41 | static int debug = 0; /* insmod parameter */ | 41 | static int debug; /* insmod parameter */ |
42 | module_param(debug, int, 0644); | 42 | module_param(debug, int, 0644); |
43 | 43 | ||
44 | MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips"); | 44 | MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips"); |
@@ -1235,11 +1235,11 @@ static int tda9850 = 1; | |||
1235 | static int tda9855 = 1; | 1235 | static int tda9855 = 1; |
1236 | static int tda9873 = 1; | 1236 | static int tda9873 = 1; |
1237 | static int tda9874a = 1; | 1237 | static int tda9874a = 1; |
1238 | static int tea6300 = 0; /* address clash with msp34xx */ | 1238 | static int tea6300; /* default 0 - address clash with msp34xx */ |
1239 | static int tea6320 = 0; /* address clash with msp34xx */ | 1239 | static int tea6320; /* default 0 - address clash with msp34xx */ |
1240 | static int tea6420 = 1; | 1240 | static int tea6420 = 1; |
1241 | static int pic16c54 = 1; | 1241 | static int pic16c54 = 1; |
1242 | static int ta8874z = 0; /* address clash with tda9840 */ | 1242 | static int ta8874z; /* default 0 - address clash with tda9840 */ |
1243 | 1243 | ||
1244 | module_param(tda8425, int, 0444); | 1244 | module_param(tda8425, int, 0444); |
1245 | module_param(tda9840, int, 0444); | 1245 | module_param(tda9840, int, 0444); |
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index dc0da44a5af6..3cf8a8e801e5 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -745,109 +745,6 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len) | |||
745 | } | 745 | } |
746 | EXPORT_SYMBOL(tveeprom_read); | 746 | EXPORT_SYMBOL(tveeprom_read); |
747 | 747 | ||
748 | /* ----------------------------------------------------------------------- */ | ||
749 | /* needed for ivtv.sf.net at the moment. Should go away in the long */ | ||
750 | /* run, just call the exported tveeprom_* directly, there is no point in */ | ||
751 | /* using the indirect way via i2c_driver->command() */ | ||
752 | |||
753 | static unsigned short normal_i2c[] = { | ||
754 | 0xa0 >> 1, | ||
755 | I2C_CLIENT_END, | ||
756 | }; | ||
757 | |||
758 | I2C_CLIENT_INSMOD; | ||
759 | |||
760 | static struct i2c_driver i2c_driver_tveeprom; | ||
761 | |||
762 | static int | ||
763 | tveeprom_command(struct i2c_client *client, | ||
764 | unsigned int cmd, | ||
765 | void *arg) | ||
766 | { | ||
767 | struct tveeprom eeprom; | ||
768 | u32 *eeprom_props = arg; | ||
769 | u8 *buf; | ||
770 | |||
771 | switch (cmd) { | ||
772 | case 0: | ||
773 | buf = kzalloc(256, GFP_KERNEL); | ||
774 | tveeprom_read(client, buf, 256); | ||
775 | tveeprom_hauppauge_analog(client, &eeprom, buf); | ||
776 | kfree(buf); | ||
777 | eeprom_props[0] = eeprom.tuner_type; | ||
778 | eeprom_props[1] = eeprom.tuner_formats; | ||
779 | eeprom_props[2] = eeprom.model; | ||
780 | eeprom_props[3] = eeprom.revision; | ||
781 | eeprom_props[4] = eeprom.has_radio; | ||
782 | break; | ||
783 | default: | ||
784 | return -EINVAL; | ||
785 | } | ||
786 | return 0; | ||
787 | } | ||
788 | |||
789 | static int | ||
790 | tveeprom_detect_client(struct i2c_adapter *adapter, | ||
791 | int address, | ||
792 | int kind) | ||
793 | { | ||
794 | struct i2c_client *client; | ||
795 | |||
796 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
797 | if (NULL == client) | ||
798 | return -ENOMEM; | ||
799 | client->addr = address; | ||
800 | client->adapter = adapter; | ||
801 | client->driver = &i2c_driver_tveeprom; | ||
802 | snprintf(client->name, sizeof(client->name), "tveeprom"); | ||
803 | i2c_attach_client(client); | ||
804 | |||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | static int | ||
809 | tveeprom_attach_adapter(struct i2c_adapter *adapter) | ||
810 | { | ||
811 | if (adapter->class & I2C_CLASS_TV_ANALOG) | ||
812 | return i2c_probe(adapter, &addr_data, tveeprom_detect_client); | ||
813 | return 0; | ||
814 | } | ||
815 | |||
816 | static int | ||
817 | tveeprom_detach_client(struct i2c_client *client) | ||
818 | { | ||
819 | int err; | ||
820 | |||
821 | err = i2c_detach_client(client); | ||
822 | if (err < 0) | ||
823 | return err; | ||
824 | kfree(client); | ||
825 | return 0; | ||
826 | } | ||
827 | |||
828 | static struct i2c_driver i2c_driver_tveeprom = { | ||
829 | .driver = { | ||
830 | .name = "tveeprom", | ||
831 | }, | ||
832 | .id = I2C_DRIVERID_TVEEPROM, | ||
833 | .attach_adapter = tveeprom_attach_adapter, | ||
834 | .detach_client = tveeprom_detach_client, | ||
835 | .command = tveeprom_command, | ||
836 | }; | ||
837 | |||
838 | static int __init tveeprom_init(void) | ||
839 | { | ||
840 | return i2c_add_driver(&i2c_driver_tveeprom); | ||
841 | } | ||
842 | |||
843 | static void __exit tveeprom_exit(void) | ||
844 | { | ||
845 | i2c_del_driver(&i2c_driver_tveeprom); | ||
846 | } | ||
847 | |||
848 | module_init(tveeprom_init); | ||
849 | module_exit(tveeprom_exit); | ||
850 | |||
851 | /* | 748 | /* |
852 | * Local variables: | 749 | * Local variables: |
853 | * c-basic-offset: 8 | 750 | * c-basic-offset: 8 |
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index b6e24e714a23..6a3af1005f03 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
@@ -27,7 +27,7 @@ static unsigned short normal_i2c[] = { | |||
27 | 27 | ||
28 | I2C_CLIENT_INSMOD; | 28 | I2C_CLIENT_INSMOD; |
29 | 29 | ||
30 | static int debug = 0; | 30 | static int debug; |
31 | module_param(debug, int, 0); | 31 | module_param(debug, int, 0); |
32 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 32 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
33 | 33 | ||
diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c index 14db95e10cfe..59166b760104 100644 --- a/drivers/media/video/usbvideo/ibmcam.c +++ b/drivers/media/video/usbvideo/ibmcam.c | |||
@@ -121,7 +121,7 @@ static int init_model2_yb = -1; | |||
121 | 121 | ||
122 | /* 01.01.08 - Added for RCA video in support -LO */ | 122 | /* 01.01.08 - Added for RCA video in support -LO */ |
123 | /* Settings for camera model 3 */ | 123 | /* Settings for camera model 3 */ |
124 | static int init_model3_input = 0; | 124 | static int init_model3_input; |
125 | 125 | ||
126 | module_param(debug, int, 0); | 126 | module_param(debug, int, 0); |
127 | MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); | 127 | MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); |
@@ -802,6 +802,21 @@ static enum ParseState ibmcam_model2_320x240_parse_lines( | |||
802 | return scan_Continue; | 802 | return scan_Continue; |
803 | } | 803 | } |
804 | 804 | ||
805 | /* | ||
806 | * ibmcam_model3_parse_lines() | ||
807 | * | ||
808 | * | Even lines | Odd Lines | | ||
809 | * -----------------------------------| | ||
810 | * |YYY........Y|UYVYUYVY.........UYVY| | ||
811 | * |YYY........Y|UYVYUYVY.........UYVY| | ||
812 | * |............|.....................| | ||
813 | * |YYY........Y|UYVYUYVY.........UYVY| | ||
814 | * |------------+---------------------| | ||
815 | * | ||
816 | * There is one (U, V) chroma pair for every four luma (Y) values. This | ||
817 | * function reads a pair of lines at a time and obtains missing chroma values | ||
818 | * from adjacent pixels. | ||
819 | */ | ||
805 | static enum ParseState ibmcam_model3_parse_lines( | 820 | static enum ParseState ibmcam_model3_parse_lines( |
806 | struct uvd *uvd, | 821 | struct uvd *uvd, |
807 | struct usbvideo_frame *frame, | 822 | struct usbvideo_frame *frame, |
@@ -816,6 +831,7 @@ static enum ParseState ibmcam_model3_parse_lines( | |||
816 | const int ccm = 128; /* Color correction median - see below */ | 831 | const int ccm = 128; /* Color correction median - see below */ |
817 | int i, u, v, rw, data_w=0, data_h=0, color_corr; | 832 | int i, u, v, rw, data_w=0, data_h=0, color_corr; |
818 | static unsigned char lineBuffer[640*3]; | 833 | static unsigned char lineBuffer[640*3]; |
834 | int line; | ||
819 | 835 | ||
820 | color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/ | 836 | color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/ |
821 | RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1); | 837 | RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1); |
@@ -869,15 +885,15 @@ static enum ParseState ibmcam_model3_parse_lines( | |||
869 | return scan_NextFrame; | 885 | return scan_NextFrame; |
870 | } | 886 | } |
871 | 887 | ||
872 | /* Make sure there's enough data for the entire line */ | 888 | /* Make sure that lineBuffer can store two lines of data */ |
873 | len = 3 * data_w; /* <y-data> <uv-data> */ | 889 | len = 3 * data_w; /* <y-data> <uyvy-data> */ |
874 | assert(len <= sizeof(lineBuffer)); | 890 | assert(len <= sizeof(lineBuffer)); |
875 | 891 | ||
876 | /* Make sure there's enough data for the entire line */ | 892 | /* Make sure there's enough data for two lines */ |
877 | if (RingQueue_GetLength(&uvd->dp) < len) | 893 | if (RingQueue_GetLength(&uvd->dp) < len) |
878 | return scan_Out; | 894 | return scan_Out; |
879 | 895 | ||
880 | /* Suck one line out of the ring queue */ | 896 | /* Suck two lines of data out of the ring queue */ |
881 | RingQueue_Dequeue(&uvd->dp, lineBuffer, len); | 897 | RingQueue_Dequeue(&uvd->dp, lineBuffer, len); |
882 | 898 | ||
883 | data = lineBuffer; | 899 | data = lineBuffer; |
@@ -887,15 +903,23 @@ static enum ParseState ibmcam_model3_parse_lines( | |||
887 | rw = (int)VIDEOSIZE_Y(frame->request) - (int)(frame->curline) - 1; | 903 | rw = (int)VIDEOSIZE_Y(frame->request) - (int)(frame->curline) - 1; |
888 | RESTRICT_TO_RANGE(rw, 0, VIDEOSIZE_Y(frame->request)-1); | 904 | RESTRICT_TO_RANGE(rw, 0, VIDEOSIZE_Y(frame->request)-1); |
889 | 905 | ||
890 | for (i = 0; i < VIDEOSIZE_X(frame->request); i++) { | 906 | /* Iterate over two lines. */ |
891 | int y, rv, gv, bv; /* RGB components */ | 907 | for (line = 0; line < 2; line++) { |
908 | for (i = 0; i < VIDEOSIZE_X(frame->request); i++) { | ||
909 | int y; | ||
910 | int rv, gv, bv; /* RGB components */ | ||
892 | 911 | ||
893 | if (i < data_w) { | 912 | if (i >= data_w) { |
894 | y = data[i]; /* Luminosity is the first line */ | 913 | RGB24_PUTPIXEL(frame, i, rw, 0, 0, 0); |
914 | continue; | ||
915 | } | ||
916 | |||
917 | /* first line is YYY...Y; second is UYVY...UYVY */ | ||
918 | y = data[(line == 0) ? i : (i*2 + 1)]; | ||
895 | 919 | ||
896 | /* Apply static color correction */ | 920 | /* Apply static color correction */ |
897 | u = color[i*2] + hue_corr; | 921 | u = color[(i/2)*4] + hue_corr; |
898 | v = color[i*2 + 1] + hue2_corr; | 922 | v = color[(i/2)*4 + 2] + hue2_corr; |
899 | 923 | ||
900 | /* Apply color correction */ | 924 | /* Apply color correction */ |
901 | if (color_corr != 0) { | 925 | if (color_corr != 0) { |
@@ -903,13 +927,21 @@ static enum ParseState ibmcam_model3_parse_lines( | |||
903 | u = 128 + ((ccm + color_corr) * (u - 128)) / ccm; | 927 | u = 128 + ((ccm + color_corr) * (u - 128)) / ccm; |
904 | v = 128 + ((ccm + color_corr) * (v - 128)) / ccm; | 928 | v = 128 + ((ccm + color_corr) * (v - 128)) / ccm; |
905 | } | 929 | } |
906 | } else | ||
907 | y = 0, u = v = 128; | ||
908 | 930 | ||
909 | YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv); | 931 | |
910 | RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* Done by deinterlacing now */ | 932 | YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv); |
933 | RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* No deinterlacing */ | ||
934 | } | ||
935 | |||
936 | /* Check for the end of requested data */ | ||
937 | if (rw == 0) | ||
938 | break; | ||
939 | |||
940 | /* Prepare for the second line */ | ||
941 | rw--; | ||
942 | data = lineBuffer + data_w; | ||
911 | } | 943 | } |
912 | frame->deinterlace = Deinterlace_FillEvenLines; | 944 | frame->deinterlace = Deinterlace_None; |
913 | 945 | ||
914 | /* | 946 | /* |
915 | * Account for number of bytes that we wrote into output V4L frame. | 947 | * Account for number of bytes that we wrote into output V4L frame. |
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c index 719b17ce83f8..1c180284ec6c 100644 --- a/drivers/media/video/usbvideo/konicawc.c +++ b/drivers/media/video/usbvideo/konicawc.c | |||
@@ -57,11 +57,11 @@ static struct usbvideo *cams; | |||
57 | static int debug; | 57 | static int debug; |
58 | #define DEBUG(n, format, arg...) \ | 58 | #define DEBUG(n, format, arg...) \ |
59 | if (n <= debug) { \ | 59 | if (n <= debug) { \ |
60 | printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \ | 60 | printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \ |
61 | } | 61 | } |
62 | #else | 62 | #else |
63 | #define DEBUG(n, arg...) | 63 | #define DEBUG(n, arg...) |
64 | static const int debug = 0; | 64 | static const int debug; |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | 67 | ||
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c index a2acba0bcc47..32e536edf09d 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/drivers/media/video/usbvideo/quickcam_messenger.c | |||
@@ -46,11 +46,11 @@ | |||
46 | static int debug; | 46 | static int debug; |
47 | #define DEBUG(n, format, arg...) \ | 47 | #define DEBUG(n, format, arg...) \ |
48 | if (n <= debug) { \ | 48 | if (n <= debug) { \ |
49 | printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \ | 49 | printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \ |
50 | } | 50 | } |
51 | #else | 51 | #else |
52 | #define DEBUG(n, arg...) | 52 | #define DEBUG(n, arg...) |
53 | static const int debug = 0; | 53 | static const int debug; |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | #define DRIVER_VERSION "v0.01" | 56 | #define DRIVER_VERSION "v0.01" |
diff --git a/drivers/media/video/usbvideo/ultracam.c b/drivers/media/video/usbvideo/ultracam.c index 95453c108d40..9544e644bf0d 100644 --- a/drivers/media/video/usbvideo/ultracam.c +++ b/drivers/media/video/usbvideo/ultracam.c | |||
@@ -28,9 +28,9 @@ typedef struct { | |||
28 | 28 | ||
29 | static struct usbvideo *cams = NULL; | 29 | static struct usbvideo *cams = NULL; |
30 | 30 | ||
31 | static int debug = 0; | 31 | static int debug; |
32 | 32 | ||
33 | static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */ | 33 | static int flags; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */ |
34 | 34 | ||
35 | static const int min_canvasWidth = 8; | 35 | static const int min_canvasWidth = 8; |
36 | static const int min_canvasHeight = 4; | 36 | static const int min_canvasHeight = 4; |
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c index 5d363be7bc73..4128ee20b64e 100644 --- a/drivers/media/video/usbvideo/usbvideo.c +++ b/drivers/media/video/usbvideo/usbvideo.c | |||
@@ -522,14 +522,14 @@ void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode) | |||
522 | struct usbvideo_frame *frame; | 522 | struct usbvideo_frame *frame; |
523 | int num_cell = 0; | 523 | int num_cell = 0; |
524 | int scan_length = 0; | 524 | int scan_length = 0; |
525 | static int num_pass = 0; | 525 | static int num_pass; |
526 | 526 | ||
527 | if (uvd == NULL) { | 527 | if (uvd == NULL) { |
528 | err("%s: uvd == NULL", __FUNCTION__); | 528 | err("%s: uvd == NULL", __func__); |
529 | return; | 529 | return; |
530 | } | 530 | } |
531 | if ((uvd->curframe < 0) || (uvd->curframe >= USBVIDEO_NUMFRAMES)) { | 531 | if ((uvd->curframe < 0) || (uvd->curframe >= USBVIDEO_NUMFRAMES)) { |
532 | err("%s: uvd->curframe=%d.", __FUNCTION__, uvd->curframe); | 532 | err("%s: uvd->curframe=%d.", __func__, uvd->curframe); |
533 | return; | 533 | return; |
534 | } | 534 | } |
535 | 535 | ||
@@ -630,15 +630,15 @@ EXPORT_SYMBOL(usbvideo_HexDump); | |||
630 | static int usbvideo_ClientIncModCount(struct uvd *uvd) | 630 | static int usbvideo_ClientIncModCount(struct uvd *uvd) |
631 | { | 631 | { |
632 | if (uvd == NULL) { | 632 | if (uvd == NULL) { |
633 | err("%s: uvd == NULL", __FUNCTION__); | 633 | err("%s: uvd == NULL", __func__); |
634 | return -EINVAL; | 634 | return -EINVAL; |
635 | } | 635 | } |
636 | if (uvd->handle == NULL) { | 636 | if (uvd->handle == NULL) { |
637 | err("%s: uvd->handle == NULL", __FUNCTION__); | 637 | err("%s: uvd->handle == NULL", __func__); |
638 | return -EINVAL; | 638 | return -EINVAL; |
639 | } | 639 | } |
640 | if (!try_module_get(uvd->handle->md_module)) { | 640 | if (!try_module_get(uvd->handle->md_module)) { |
641 | err("%s: try_module_get() == 0", __FUNCTION__); | 641 | err("%s: try_module_get() == 0", __func__); |
642 | return -ENODEV; | 642 | return -ENODEV; |
643 | } | 643 | } |
644 | return 0; | 644 | return 0; |
@@ -647,15 +647,15 @@ static int usbvideo_ClientIncModCount(struct uvd *uvd) | |||
647 | static void usbvideo_ClientDecModCount(struct uvd *uvd) | 647 | static void usbvideo_ClientDecModCount(struct uvd *uvd) |
648 | { | 648 | { |
649 | if (uvd == NULL) { | 649 | if (uvd == NULL) { |
650 | err("%s: uvd == NULL", __FUNCTION__); | 650 | err("%s: uvd == NULL", __func__); |
651 | return; | 651 | return; |
652 | } | 652 | } |
653 | if (uvd->handle == NULL) { | 653 | if (uvd->handle == NULL) { |
654 | err("%s: uvd->handle == NULL", __FUNCTION__); | 654 | err("%s: uvd->handle == NULL", __func__); |
655 | return; | 655 | return; |
656 | } | 656 | } |
657 | if (uvd->handle->md_module == NULL) { | 657 | if (uvd->handle->md_module == NULL) { |
658 | err("%s: uvd->handle->md_module == NULL", __FUNCTION__); | 658 | err("%s: uvd->handle->md_module == NULL", __func__); |
659 | return; | 659 | return; |
660 | } | 660 | } |
661 | module_put(uvd->handle->md_module); | 661 | module_put(uvd->handle->md_module); |
@@ -675,13 +675,13 @@ int usbvideo_register( | |||
675 | 675 | ||
676 | /* Check parameters for sanity */ | 676 | /* Check parameters for sanity */ |
677 | if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) { | 677 | if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) { |
678 | err("%s: Illegal call", __FUNCTION__); | 678 | err("%s: Illegal call", __func__); |
679 | return -EINVAL; | 679 | return -EINVAL; |
680 | } | 680 | } |
681 | 681 | ||
682 | /* Check registration callback - must be set! */ | 682 | /* Check registration callback - must be set! */ |
683 | if (cbTbl->probe == NULL) { | 683 | if (cbTbl->probe == NULL) { |
684 | err("%s: probe() is required!", __FUNCTION__); | 684 | err("%s: probe() is required!", __func__); |
685 | return -EINVAL; | 685 | return -EINVAL; |
686 | } | 686 | } |
687 | 687 | ||
@@ -692,7 +692,7 @@ int usbvideo_register( | |||
692 | return -ENOMEM; | 692 | return -ENOMEM; |
693 | } | 693 | } |
694 | dbg("%s: Allocated $%p (%d. bytes) for %d. cameras", | 694 | dbg("%s: Allocated $%p (%d. bytes) for %d. cameras", |
695 | __FUNCTION__, cams, base_size, num_cams); | 695 | __func__, cams, base_size, num_cams); |
696 | 696 | ||
697 | /* Copy callbacks, apply defaults for those that are not set */ | 697 | /* Copy callbacks, apply defaults for those that are not set */ |
698 | memmove(&cams->cb, cbTbl, sizeof(cams->cb)); | 698 | memmove(&cams->cb, cbTbl, sizeof(cams->cb)); |
@@ -721,7 +721,7 @@ int usbvideo_register( | |||
721 | up->user_data = kmalloc(up->user_size, GFP_KERNEL); | 721 | up->user_data = kmalloc(up->user_size, GFP_KERNEL); |
722 | if (up->user_data == NULL) { | 722 | if (up->user_data == NULL) { |
723 | err("%s: Failed to allocate user_data (%d. bytes)", | 723 | err("%s: Failed to allocate user_data (%d. bytes)", |
724 | __FUNCTION__, up->user_size); | 724 | __func__, up->user_size); |
725 | while (i) { | 725 | while (i) { |
726 | up = &cams->cam[--i]; | 726 | up = &cams->cam[--i]; |
727 | kfree(up->user_data); | 727 | kfree(up->user_data); |
@@ -730,7 +730,7 @@ int usbvideo_register( | |||
730 | return -ENOMEM; | 730 | return -ENOMEM; |
731 | } | 731 | } |
732 | dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)", | 732 | dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)", |
733 | __FUNCTION__, i, up->user_data, up->user_size); | 733 | __func__, i, up->user_data, up->user_size); |
734 | } | 734 | } |
735 | } | 735 | } |
736 | 736 | ||
@@ -776,19 +776,19 @@ void usbvideo_Deregister(struct usbvideo **pCams) | |||
776 | int i; | 776 | int i; |
777 | 777 | ||
778 | if (pCams == NULL) { | 778 | if (pCams == NULL) { |
779 | err("%s: pCams == NULL", __FUNCTION__); | 779 | err("%s: pCams == NULL", __func__); |
780 | return; | 780 | return; |
781 | } | 781 | } |
782 | cams = *pCams; | 782 | cams = *pCams; |
783 | if (cams == NULL) { | 783 | if (cams == NULL) { |
784 | err("%s: cams == NULL", __FUNCTION__); | 784 | err("%s: cams == NULL", __func__); |
785 | return; | 785 | return; |
786 | } | 786 | } |
787 | 787 | ||
788 | dbg("%s: Deregistering %s driver.", __FUNCTION__, cams->drvName); | 788 | dbg("%s: Deregistering %s driver.", __func__, cams->drvName); |
789 | usb_deregister(&cams->usbdrv); | 789 | usb_deregister(&cams->usbdrv); |
790 | 790 | ||
791 | dbg("%s: Deallocating cams=$%p (%d. cameras)", __FUNCTION__, cams, cams->num_cameras); | 791 | dbg("%s: Deallocating cams=$%p (%d. cameras)", __func__, cams, cams->num_cameras); |
792 | for (i=0; i < cams->num_cameras; i++) { | 792 | for (i=0; i < cams->num_cameras; i++) { |
793 | struct uvd *up = &cams->cam[i]; | 793 | struct uvd *up = &cams->cam[i]; |
794 | int warning = 0; | 794 | int warning = 0; |
@@ -802,16 +802,16 @@ void usbvideo_Deregister(struct usbvideo **pCams) | |||
802 | } | 802 | } |
803 | if (warning) { | 803 | if (warning) { |
804 | err("%s: Warning: user_data=$%p user_size=%d.", | 804 | err("%s: Warning: user_data=$%p user_size=%d.", |
805 | __FUNCTION__, up->user_data, up->user_size); | 805 | __func__, up->user_data, up->user_size); |
806 | } else { | 806 | } else { |
807 | dbg("%s: Freeing %d. $%p->user_data=$%p", | 807 | dbg("%s: Freeing %d. $%p->user_data=$%p", |
808 | __FUNCTION__, i, up, up->user_data); | 808 | __func__, i, up, up->user_data); |
809 | kfree(up->user_data); | 809 | kfree(up->user_data); |
810 | } | 810 | } |
811 | } | 811 | } |
812 | /* Whole array was allocated in one chunk */ | 812 | /* Whole array was allocated in one chunk */ |
813 | dbg("%s: Freed %d uvd structures", | 813 | dbg("%s: Freed %d uvd structures", |
814 | __FUNCTION__, cams->num_cameras); | 814 | __func__, cams->num_cameras); |
815 | kfree(cams); | 815 | kfree(cams); |
816 | *pCams = NULL; | 816 | *pCams = NULL; |
817 | } | 817 | } |
@@ -846,7 +846,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) | |||
846 | int i; | 846 | int i; |
847 | 847 | ||
848 | if (uvd == NULL) { | 848 | if (uvd == NULL) { |
849 | err("%s($%p): Illegal call.", __FUNCTION__, intf); | 849 | err("%s($%p): Illegal call.", __func__, intf); |
850 | return; | 850 | return; |
851 | } | 851 | } |
852 | 852 | ||
@@ -854,7 +854,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) | |||
854 | 854 | ||
855 | usbvideo_ClientIncModCount(uvd); | 855 | usbvideo_ClientIncModCount(uvd); |
856 | if (uvd->debug > 0) | 856 | if (uvd->debug > 0) |
857 | info("%s(%p.)", __FUNCTION__, intf); | 857 | info("%s(%p.)", __func__, intf); |
858 | 858 | ||
859 | mutex_lock(&uvd->lock); | 859 | mutex_lock(&uvd->lock); |
860 | uvd->remove_pending = 1; /* Now all ISO data will be ignored */ | 860 | uvd->remove_pending = 1; /* Now all ISO data will be ignored */ |
@@ -870,10 +870,10 @@ static void usbvideo_Disconnect(struct usb_interface *intf) | |||
870 | 870 | ||
871 | video_unregister_device(&uvd->vdev); | 871 | video_unregister_device(&uvd->vdev); |
872 | if (uvd->debug > 0) | 872 | if (uvd->debug > 0) |
873 | info("%s: Video unregistered.", __FUNCTION__); | 873 | info("%s: Video unregistered.", __func__); |
874 | 874 | ||
875 | if (uvd->user) | 875 | if (uvd->user) |
876 | info("%s: In use, disconnect pending.", __FUNCTION__); | 876 | info("%s: In use, disconnect pending.", __func__); |
877 | else | 877 | else |
878 | usbvideo_CameraRelease(uvd); | 878 | usbvideo_CameraRelease(uvd); |
879 | mutex_unlock(&uvd->lock); | 879 | mutex_unlock(&uvd->lock); |
@@ -895,7 +895,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) | |||
895 | static void usbvideo_CameraRelease(struct uvd *uvd) | 895 | static void usbvideo_CameraRelease(struct uvd *uvd) |
896 | { | 896 | { |
897 | if (uvd == NULL) { | 897 | if (uvd == NULL) { |
898 | err("%s: Illegal call", __FUNCTION__); | 898 | err("%s: Illegal call", __func__); |
899 | return; | 899 | return; |
900 | } | 900 | } |
901 | 901 | ||
@@ -946,7 +946,9 @@ static const struct file_operations usbvideo_fops = { | |||
946 | .read = usbvideo_v4l_read, | 946 | .read = usbvideo_v4l_read, |
947 | .mmap = usbvideo_v4l_mmap, | 947 | .mmap = usbvideo_v4l_mmap, |
948 | .ioctl = usbvideo_v4l_ioctl, | 948 | .ioctl = usbvideo_v4l_ioctl, |
949 | #ifdef CONFIG_COMPAT | ||
949 | .compat_ioctl = v4l_compat_ioctl32, | 950 | .compat_ioctl = v4l_compat_ioctl32, |
951 | #endif | ||
950 | .llseek = no_llseek, | 952 | .llseek = no_llseek, |
951 | }; | 953 | }; |
952 | static const struct video_device usbvideo_template = { | 954 | static const struct video_device usbvideo_template = { |
@@ -1011,18 +1013,18 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) | |||
1011 | char tmp1[20], tmp2[20]; /* Buffers for printing */ | 1013 | char tmp1[20], tmp2[20]; /* Buffers for printing */ |
1012 | 1014 | ||
1013 | if (uvd == NULL) { | 1015 | if (uvd == NULL) { |
1014 | err("%s: Illegal call.", __FUNCTION__); | 1016 | err("%s: Illegal call.", __func__); |
1015 | return -EINVAL; | 1017 | return -EINVAL; |
1016 | } | 1018 | } |
1017 | if (uvd->video_endp == 0) { | 1019 | if (uvd->video_endp == 0) { |
1018 | info("%s: No video endpoint specified; data pump disabled.", __FUNCTION__); | 1020 | info("%s: No video endpoint specified; data pump disabled.", __func__); |
1019 | } | 1021 | } |
1020 | if (uvd->paletteBits == 0) { | 1022 | if (uvd->paletteBits == 0) { |
1021 | err("%s: No palettes specified!", __FUNCTION__); | 1023 | err("%s: No palettes specified!", __func__); |
1022 | return -EINVAL; | 1024 | return -EINVAL; |
1023 | } | 1025 | } |
1024 | if (uvd->defaultPalette == 0) { | 1026 | if (uvd->defaultPalette == 0) { |
1025 | info("%s: No default palette!", __FUNCTION__); | 1027 | info("%s: No default palette!", __func__); |
1026 | } | 1028 | } |
1027 | 1029 | ||
1028 | uvd->max_frame_size = VIDEOSIZE_X(uvd->canvas) * | 1030 | uvd->max_frame_size = VIDEOSIZE_X(uvd->canvas) * |
@@ -1032,19 +1034,19 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) | |||
1032 | 1034 | ||
1033 | if (uvd->debug > 0) { | 1035 | if (uvd->debug > 0) { |
1034 | info("%s: iface=%d. endpoint=$%02x paletteBits=$%08lx", | 1036 | info("%s: iface=%d. endpoint=$%02x paletteBits=$%08lx", |
1035 | __FUNCTION__, uvd->iface, uvd->video_endp, uvd->paletteBits); | 1037 | __func__, uvd->iface, uvd->video_endp, uvd->paletteBits); |
1036 | } | 1038 | } |
1037 | if (uvd->dev == NULL) { | 1039 | if (uvd->dev == NULL) { |
1038 | err("%s: uvd->dev == NULL", __FUNCTION__); | 1040 | err("%s: uvd->dev == NULL", __func__); |
1039 | return -EINVAL; | 1041 | return -EINVAL; |
1040 | } | 1042 | } |
1041 | uvd->vdev.dev=&(uvd->dev->dev); | 1043 | uvd->vdev.dev = &uvd->dev->dev; |
1042 | if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { | 1044 | if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { |
1043 | err("%s: video_register_device failed", __FUNCTION__); | 1045 | err("%s: video_register_device failed", __func__); |
1044 | return -EPIPE; | 1046 | return -EPIPE; |
1045 | } | 1047 | } |
1046 | if (uvd->debug > 1) { | 1048 | if (uvd->debug > 1) { |
1047 | info("%s: video_register_device() successful", __FUNCTION__); | 1049 | info("%s: video_register_device() successful", __func__); |
1048 | } | 1050 | } |
1049 | 1051 | ||
1050 | info("%s on /dev/video%d: canvas=%s videosize=%s", | 1052 | info("%s on /dev/video%d: canvas=%s videosize=%s", |
@@ -1111,14 +1113,14 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) | |||
1111 | int i, errCode = 0; | 1113 | int i, errCode = 0; |
1112 | 1114 | ||
1113 | if (uvd->debug > 1) | 1115 | if (uvd->debug > 1) |
1114 | info("%s($%p)", __FUNCTION__, dev); | 1116 | info("%s($%p)", __func__, dev); |
1115 | 1117 | ||
1116 | if (0 < usbvideo_ClientIncModCount(uvd)) | 1118 | if (0 < usbvideo_ClientIncModCount(uvd)) |
1117 | return -ENODEV; | 1119 | return -ENODEV; |
1118 | mutex_lock(&uvd->lock); | 1120 | mutex_lock(&uvd->lock); |
1119 | 1121 | ||
1120 | if (uvd->user) { | 1122 | if (uvd->user) { |
1121 | err("%s: Someone tried to open an already opened device!", __FUNCTION__); | 1123 | err("%s: Someone tried to open an already opened device!", __func__); |
1122 | errCode = -EBUSY; | 1124 | errCode = -EBUSY; |
1123 | } else { | 1125 | } else { |
1124 | /* Clear statistics */ | 1126 | /* Clear statistics */ |
@@ -1134,7 +1136,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) | |||
1134 | RingQueue_Allocate(&uvd->dp, RING_QUEUE_SIZE); | 1136 | RingQueue_Allocate(&uvd->dp, RING_QUEUE_SIZE); |
1135 | if ((uvd->fbuf == NULL) || | 1137 | if ((uvd->fbuf == NULL) || |
1136 | (!RingQueue_IsAllocated(&uvd->dp))) { | 1138 | (!RingQueue_IsAllocated(&uvd->dp))) { |
1137 | err("%s: Failed to allocate fbuf or dp", __FUNCTION__); | 1139 | err("%s: Failed to allocate fbuf or dp", __func__); |
1138 | errCode = -ENOMEM; | 1140 | errCode = -ENOMEM; |
1139 | } else { | 1141 | } else { |
1140 | /* Allocate all buffers */ | 1142 | /* Allocate all buffers */ |
@@ -1178,19 +1180,19 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) | |||
1178 | if (errCode == 0) { | 1180 | if (errCode == 0) { |
1179 | if (VALID_CALLBACK(uvd, setupOnOpen)) { | 1181 | if (VALID_CALLBACK(uvd, setupOnOpen)) { |
1180 | if (uvd->debug > 1) | 1182 | if (uvd->debug > 1) |
1181 | info("%s: setupOnOpen callback", __FUNCTION__); | 1183 | info("%s: setupOnOpen callback", __func__); |
1182 | errCode = GET_CALLBACK(uvd, setupOnOpen)(uvd); | 1184 | errCode = GET_CALLBACK(uvd, setupOnOpen)(uvd); |
1183 | if (errCode < 0) { | 1185 | if (errCode < 0) { |
1184 | err("%s: setupOnOpen callback failed (%d.).", | 1186 | err("%s: setupOnOpen callback failed (%d.).", |
1185 | __FUNCTION__, errCode); | 1187 | __func__, errCode); |
1186 | } else if (uvd->debug > 1) { | 1188 | } else if (uvd->debug > 1) { |
1187 | info("%s: setupOnOpen callback successful", __FUNCTION__); | 1189 | info("%s: setupOnOpen callback successful", __func__); |
1188 | } | 1190 | } |
1189 | } | 1191 | } |
1190 | if (errCode == 0) { | 1192 | if (errCode == 0) { |
1191 | uvd->settingsAdjusted = 0; | 1193 | uvd->settingsAdjusted = 0; |
1192 | if (uvd->debug > 1) | 1194 | if (uvd->debug > 1) |
1193 | info("%s: Open succeeded.", __FUNCTION__); | 1195 | info("%s: Open succeeded.", __func__); |
1194 | uvd->user++; | 1196 | uvd->user++; |
1195 | file->private_data = uvd; | 1197 | file->private_data = uvd; |
1196 | } | 1198 | } |
@@ -1200,7 +1202,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) | |||
1200 | if (errCode != 0) | 1202 | if (errCode != 0) |
1201 | usbvideo_ClientDecModCount(uvd); | 1203 | usbvideo_ClientDecModCount(uvd); |
1202 | if (uvd->debug > 0) | 1204 | if (uvd->debug > 0) |
1203 | info("%s: Returning %d.", __FUNCTION__, errCode); | 1205 | info("%s: Returning %d.", __func__, errCode); |
1204 | return errCode; | 1206 | return errCode; |
1205 | } | 1207 | } |
1206 | 1208 | ||
@@ -1223,7 +1225,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) | |||
1223 | int i; | 1225 | int i; |
1224 | 1226 | ||
1225 | if (uvd->debug > 1) | 1227 | if (uvd->debug > 1) |
1226 | info("%s($%p)", __FUNCTION__, dev); | 1228 | info("%s($%p)", __func__, dev); |
1227 | 1229 | ||
1228 | mutex_lock(&uvd->lock); | 1230 | mutex_lock(&uvd->lock); |
1229 | GET_CALLBACK(uvd, stopDataPump)(uvd); | 1231 | GET_CALLBACK(uvd, stopDataPump)(uvd); |
@@ -1250,7 +1252,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) | |||
1250 | usbvideo_ClientDecModCount(uvd); | 1252 | usbvideo_ClientDecModCount(uvd); |
1251 | 1253 | ||
1252 | if (uvd->debug > 1) | 1254 | if (uvd->debug > 1) |
1253 | info("%s: Completed.", __FUNCTION__); | 1255 | info("%s: Completed.", __func__); |
1254 | file->private_data = NULL; | 1256 | file->private_data = NULL; |
1255 | return 0; | 1257 | return 0; |
1256 | } | 1258 | } |
@@ -1504,7 +1506,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, | |||
1504 | return -EFAULT; | 1506 | return -EFAULT; |
1505 | 1507 | ||
1506 | if (uvd->debug >= 1) | 1508 | if (uvd->debug >= 1) |
1507 | info("%s: %Zd. bytes, noblock=%d.", __FUNCTION__, count, noblock); | 1509 | info("%s: %Zd. bytes, noblock=%d.", __func__, count, noblock); |
1508 | 1510 | ||
1509 | mutex_lock(&uvd->lock); | 1511 | mutex_lock(&uvd->lock); |
1510 | 1512 | ||
@@ -1551,7 +1553,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, | |||
1551 | */ | 1553 | */ |
1552 | if (frmx == -1) { | 1554 | if (frmx == -1) { |
1553 | if (uvd->defaultPalette == 0) { | 1555 | if (uvd->defaultPalette == 0) { |
1554 | err("%s: No default palette; don't know what to do!", __FUNCTION__); | 1556 | err("%s: No default palette; don't know what to do!", __func__); |
1555 | count = -EFAULT; | 1557 | count = -EFAULT; |
1556 | goto read_done; | 1558 | goto read_done; |
1557 | } | 1559 | } |
@@ -1623,7 +1625,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, | |||
1623 | frame->seqRead_Index += count; | 1625 | frame->seqRead_Index += count; |
1624 | if (uvd->debug >= 1) { | 1626 | if (uvd->debug >= 1) { |
1625 | err("%s: {copy} count used=%Zd, new seqRead_Index=%ld", | 1627 | err("%s: {copy} count used=%Zd, new seqRead_Index=%ld", |
1626 | __FUNCTION__, count, frame->seqRead_Index); | 1628 | __func__, count, frame->seqRead_Index); |
1627 | } | 1629 | } |
1628 | 1630 | ||
1629 | /* Finally check if the frame is done with and "release" it */ | 1631 | /* Finally check if the frame is done with and "release" it */ |
@@ -1634,7 +1636,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, | |||
1634 | /* Mark it as available to be used again. */ | 1636 | /* Mark it as available to be used again. */ |
1635 | uvd->frame[frmx].frameState = FrameState_Unused; | 1637 | uvd->frame[frmx].frameState = FrameState_Unused; |
1636 | if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES)) { | 1638 | if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES)) { |
1637 | err("%s: usbvideo_NewFrame failed.", __FUNCTION__); | 1639 | err("%s: usbvideo_NewFrame failed.", __func__); |
1638 | } | 1640 | } |
1639 | } | 1641 | } |
1640 | read_done: | 1642 | read_done: |
@@ -1741,10 +1743,10 @@ static int usbvideo_StartDataPump(struct uvd *uvd) | |||
1741 | int i, errFlag; | 1743 | int i, errFlag; |
1742 | 1744 | ||
1743 | if (uvd->debug > 1) | 1745 | if (uvd->debug > 1) |
1744 | info("%s($%p)", __FUNCTION__, uvd); | 1746 | info("%s($%p)", __func__, uvd); |
1745 | 1747 | ||
1746 | if (!CAMERA_IS_OPERATIONAL(uvd)) { | 1748 | if (!CAMERA_IS_OPERATIONAL(uvd)) { |
1747 | err("%s: Camera is not operational", __FUNCTION__); | 1749 | err("%s: Camera is not operational", __func__); |
1748 | return -EFAULT; | 1750 | return -EFAULT; |
1749 | } | 1751 | } |
1750 | uvd->curframe = -1; | 1752 | uvd->curframe = -1; |
@@ -1752,14 +1754,14 @@ static int usbvideo_StartDataPump(struct uvd *uvd) | |||
1752 | /* Alternate interface 1 is is the biggest frame size */ | 1754 | /* Alternate interface 1 is is the biggest frame size */ |
1753 | i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive); | 1755 | i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive); |
1754 | if (i < 0) { | 1756 | if (i < 0) { |
1755 | err("%s: usb_set_interface error", __FUNCTION__); | 1757 | err("%s: usb_set_interface error", __func__); |
1756 | uvd->last_error = i; | 1758 | uvd->last_error = i; |
1757 | return -EBUSY; | 1759 | return -EBUSY; |
1758 | } | 1760 | } |
1759 | if (VALID_CALLBACK(uvd, videoStart)) | 1761 | if (VALID_CALLBACK(uvd, videoStart)) |
1760 | GET_CALLBACK(uvd, videoStart)(uvd); | 1762 | GET_CALLBACK(uvd, videoStart)(uvd); |
1761 | else | 1763 | else |
1762 | err("%s: videoStart not set", __FUNCTION__); | 1764 | err("%s: videoStart not set", __func__); |
1763 | 1765 | ||
1764 | /* We double buffer the Iso lists */ | 1766 | /* We double buffer the Iso lists */ |
1765 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | 1767 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { |
@@ -1784,12 +1786,12 @@ static int usbvideo_StartDataPump(struct uvd *uvd) | |||
1784 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | 1786 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { |
1785 | errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); | 1787 | errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); |
1786 | if (errFlag) | 1788 | if (errFlag) |
1787 | err("%s: usb_submit_isoc(%d) ret %d", __FUNCTION__, i, errFlag); | 1789 | err("%s: usb_submit_isoc(%d) ret %d", __func__, i, errFlag); |
1788 | } | 1790 | } |
1789 | 1791 | ||
1790 | uvd->streaming = 1; | 1792 | uvd->streaming = 1; |
1791 | if (uvd->debug > 1) | 1793 | if (uvd->debug > 1) |
1792 | info("%s: streaming=1 video_endp=$%02x", __FUNCTION__, uvd->video_endp); | 1794 | info("%s: streaming=1 video_endp=$%02x", __func__, uvd->video_endp); |
1793 | return 0; | 1795 | return 0; |
1794 | } | 1796 | } |
1795 | 1797 | ||
@@ -1811,14 +1813,14 @@ static void usbvideo_StopDataPump(struct uvd *uvd) | |||
1811 | return; | 1813 | return; |
1812 | 1814 | ||
1813 | if (uvd->debug > 1) | 1815 | if (uvd->debug > 1) |
1814 | info("%s($%p)", __FUNCTION__, uvd); | 1816 | info("%s($%p)", __func__, uvd); |
1815 | 1817 | ||
1816 | /* Unschedule all of the iso td's */ | 1818 | /* Unschedule all of the iso td's */ |
1817 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | 1819 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { |
1818 | usb_kill_urb(uvd->sbuf[i].urb); | 1820 | usb_kill_urb(uvd->sbuf[i].urb); |
1819 | } | 1821 | } |
1820 | if (uvd->debug > 1) | 1822 | if (uvd->debug > 1) |
1821 | info("%s: streaming=0", __FUNCTION__); | 1823 | info("%s: streaming=0", __func__); |
1822 | uvd->streaming = 0; | 1824 | uvd->streaming = 0; |
1823 | 1825 | ||
1824 | if (!uvd->remove_pending) { | 1826 | if (!uvd->remove_pending) { |
@@ -1826,12 +1828,12 @@ static void usbvideo_StopDataPump(struct uvd *uvd) | |||
1826 | if (VALID_CALLBACK(uvd, videoStop)) | 1828 | if (VALID_CALLBACK(uvd, videoStop)) |
1827 | GET_CALLBACK(uvd, videoStop)(uvd); | 1829 | GET_CALLBACK(uvd, videoStop)(uvd); |
1828 | else | 1830 | else |
1829 | err("%s: videoStop not set", __FUNCTION__); | 1831 | err("%s: videoStop not set", __func__); |
1830 | 1832 | ||
1831 | /* Set packet size to 0 */ | 1833 | /* Set packet size to 0 */ |
1832 | j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive); | 1834 | j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive); |
1833 | if (j < 0) { | 1835 | if (j < 0) { |
1834 | err("%s: usb_set_interface() error %d.", __FUNCTION__, j); | 1836 | err("%s: usb_set_interface() error %d.", __func__, j); |
1835 | uvd->last_error = j; | 1837 | uvd->last_error = j; |
1836 | } | 1838 | } |
1837 | } | 1839 | } |
@@ -1955,12 +1957,12 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) | |||
1955 | struct usbvideo_frame *frame = &uvd->frame[frameNum]; | 1957 | struct usbvideo_frame *frame = &uvd->frame[frameNum]; |
1956 | 1958 | ||
1957 | if (uvd->debug >= 2) | 1959 | if (uvd->debug >= 2) |
1958 | info("%s($%p,%d.)", __FUNCTION__, uvd, frameNum); | 1960 | info("%s($%p,%d.)", __func__, uvd, frameNum); |
1959 | 1961 | ||
1960 | switch (frame->frameState) { | 1962 | switch (frame->frameState) { |
1961 | case FrameState_Unused: | 1963 | case FrameState_Unused: |
1962 | if (uvd->debug >= 2) | 1964 | if (uvd->debug >= 2) |
1963 | info("%s: FrameState_Unused", __FUNCTION__); | 1965 | info("%s: FrameState_Unused", __func__); |
1964 | return -EINVAL; | 1966 | return -EINVAL; |
1965 | case FrameState_Ready: | 1967 | case FrameState_Ready: |
1966 | case FrameState_Grabbing: | 1968 | case FrameState_Grabbing: |
@@ -1970,7 +1972,7 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) | |||
1970 | redo: | 1972 | redo: |
1971 | if (!CAMERA_IS_OPERATIONAL(uvd)) { | 1973 | if (!CAMERA_IS_OPERATIONAL(uvd)) { |
1972 | if (uvd->debug >= 2) | 1974 | if (uvd->debug >= 2) |
1973 | info("%s: Camera is not operational (1)", __FUNCTION__); | 1975 | info("%s: Camera is not operational (1)", __func__); |
1974 | return -EIO; | 1976 | return -EIO; |
1975 | } | 1977 | } |
1976 | ntries = 0; | 1978 | ntries = 0; |
@@ -1979,24 +1981,24 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) | |||
1979 | signalPending = signal_pending(current); | 1981 | signalPending = signal_pending(current); |
1980 | if (!CAMERA_IS_OPERATIONAL(uvd)) { | 1982 | if (!CAMERA_IS_OPERATIONAL(uvd)) { |
1981 | if (uvd->debug >= 2) | 1983 | if (uvd->debug >= 2) |
1982 | info("%s: Camera is not operational (2)", __FUNCTION__); | 1984 | info("%s: Camera is not operational (2)", __func__); |
1983 | return -EIO; | 1985 | return -EIO; |
1984 | } | 1986 | } |
1985 | assert(uvd->fbuf != NULL); | 1987 | assert(uvd->fbuf != NULL); |
1986 | if (signalPending) { | 1988 | if (signalPending) { |
1987 | if (uvd->debug >= 2) | 1989 | if (uvd->debug >= 2) |
1988 | info("%s: Signal=$%08x", __FUNCTION__, signalPending); | 1990 | info("%s: Signal=$%08x", __func__, signalPending); |
1989 | if (uvd->flags & FLAGS_RETRY_VIDIOCSYNC) { | 1991 | if (uvd->flags & FLAGS_RETRY_VIDIOCSYNC) { |
1990 | usbvideo_TestPattern(uvd, 1, 0); | 1992 | usbvideo_TestPattern(uvd, 1, 0); |
1991 | uvd->curframe = -1; | 1993 | uvd->curframe = -1; |
1992 | uvd->stats.frame_num++; | 1994 | uvd->stats.frame_num++; |
1993 | if (uvd->debug >= 2) | 1995 | if (uvd->debug >= 2) |
1994 | info("%s: Forced test pattern screen", __FUNCTION__); | 1996 | info("%s: Forced test pattern screen", __func__); |
1995 | return 0; | 1997 | return 0; |
1996 | } else { | 1998 | } else { |
1997 | /* Standard answer: Interrupted! */ | 1999 | /* Standard answer: Interrupted! */ |
1998 | if (uvd->debug >= 2) | 2000 | if (uvd->debug >= 2) |
1999 | info("%s: Interrupted!", __FUNCTION__); | 2001 | info("%s: Interrupted!", __func__); |
2000 | return -EINTR; | 2002 | return -EINTR; |
2001 | } | 2003 | } |
2002 | } else { | 2004 | } else { |
@@ -2006,17 +2008,17 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) | |||
2006 | else if (VALID_CALLBACK(uvd, processData)) | 2008 | else if (VALID_CALLBACK(uvd, processData)) |
2007 | GET_CALLBACK(uvd, processData)(uvd, frame); | 2009 | GET_CALLBACK(uvd, processData)(uvd, frame); |
2008 | else | 2010 | else |
2009 | err("%s: processData not set", __FUNCTION__); | 2011 | err("%s: processData not set", __func__); |
2010 | } | 2012 | } |
2011 | } while (frame->frameState == FrameState_Grabbing); | 2013 | } while (frame->frameState == FrameState_Grabbing); |
2012 | if (uvd->debug >= 2) { | 2014 | if (uvd->debug >= 2) { |
2013 | info("%s: Grabbing done; state=%d. (%lu. bytes)", | 2015 | info("%s: Grabbing done; state=%d. (%lu. bytes)", |
2014 | __FUNCTION__, frame->frameState, frame->seqRead_Length); | 2016 | __func__, frame->frameState, frame->seqRead_Length); |
2015 | } | 2017 | } |
2016 | if (frame->frameState == FrameState_Error) { | 2018 | if (frame->frameState == FrameState_Error) { |
2017 | int ret = usbvideo_NewFrame(uvd, frameNum); | 2019 | int ret = usbvideo_NewFrame(uvd, frameNum); |
2018 | if (ret < 0) { | 2020 | if (ret < 0) { |
2019 | err("%s: usbvideo_NewFrame() failed (%d.)", __FUNCTION__, ret); | 2021 | err("%s: usbvideo_NewFrame() failed (%d.)", __func__, ret); |
2020 | return ret; | 2022 | return ret; |
2021 | } | 2023 | } |
2022 | goto redo; | 2024 | goto redo; |
@@ -2048,7 +2050,7 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) | |||
2048 | } | 2050 | } |
2049 | frame->frameState = FrameState_Done_Hold; | 2051 | frame->frameState = FrameState_Done_Hold; |
2050 | if (uvd->debug >= 2) | 2052 | if (uvd->debug >= 2) |
2051 | info("%s: Entered FrameState_Done_Hold state.", __FUNCTION__); | 2053 | info("%s: Entered FrameState_Done_Hold state.", __func__); |
2052 | return 0; | 2054 | return 0; |
2053 | 2055 | ||
2054 | case FrameState_Done_Hold: | 2056 | case FrameState_Done_Hold: |
@@ -2059,12 +2061,12 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) | |||
2059 | * it will be released back into the wild to roam freely. | 2061 | * it will be released back into the wild to roam freely. |
2060 | */ | 2062 | */ |
2061 | if (uvd->debug >= 2) | 2063 | if (uvd->debug >= 2) |
2062 | info("%s: FrameState_Done_Hold state.", __FUNCTION__); | 2064 | info("%s: FrameState_Done_Hold state.", __func__); |
2063 | return 0; | 2065 | return 0; |
2064 | } | 2066 | } |
2065 | 2067 | ||
2066 | /* Catch-all for other cases. We shall not be here. */ | 2068 | /* Catch-all for other cases. We shall not be here. */ |
2067 | err("%s: Invalid state %d.", __FUNCTION__, frame->frameState); | 2069 | err("%s: Invalid state %d.", __func__, frame->frameState); |
2068 | frame->frameState = FrameState_Unused; | 2070 | frame->frameState = FrameState_Unused; |
2069 | return 0; | 2071 | return 0; |
2070 | } | 2072 | } |
@@ -2160,7 +2162,7 @@ static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd, | |||
2160 | const int ccm = 128; /* Color correction median - see below */ | 2162 | const int ccm = 128; /* Color correction median - see below */ |
2161 | 2163 | ||
2162 | if ((uvd == NULL) || (frame == NULL)) { | 2164 | if ((uvd == NULL) || (frame == NULL)) { |
2163 | err("%s: Illegal call.", __FUNCTION__); | 2165 | err("%s: Illegal call.", __func__); |
2164 | return; | 2166 | return; |
2165 | } | 2167 | } |
2166 | adj = (uvd->vpic.contrast - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/ | 2168 | adj = (uvd->vpic.contrast - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/ |
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index da1ba0211108..64819353276a 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c | |||
@@ -48,7 +48,7 @@ | |||
48 | // #define VICAM_DEBUG | 48 | // #define VICAM_DEBUG |
49 | 49 | ||
50 | #ifdef VICAM_DEBUG | 50 | #ifdef VICAM_DEBUG |
51 | #define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __FUNCTION__, lineno, ##args) | 51 | #define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __func__, lineno, ##args) |
52 | #define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args) | 52 | #define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args) |
53 | #else | 53 | #else |
54 | #define DBG(fmn,args...) do {} while(0) | 54 | #define DBG(fmn,args...) do {} while(0) |
@@ -1066,7 +1066,9 @@ static const struct file_operations vicam_fops = { | |||
1066 | .read = vicam_read, | 1066 | .read = vicam_read, |
1067 | .mmap = vicam_mmap, | 1067 | .mmap = vicam_mmap, |
1068 | .ioctl = vicam_ioctl, | 1068 | .ioctl = vicam_ioctl, |
1069 | #ifdef CONFIG_COMPAT | ||
1069 | .compat_ioctl = v4l_compat_ioctl32, | 1070 | .compat_ioctl = v4l_compat_ioctl32, |
1071 | #endif | ||
1070 | .llseek = no_llseek, | 1072 | .llseek = no_llseek, |
1071 | }; | 1073 | }; |
1072 | 1074 | ||
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index 56775ab8b75d..a9c5e5adba3a 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c | |||
@@ -53,19 +53,21 @@ | |||
53 | 53 | ||
54 | #include "usbvision.h" | 54 | #include "usbvision.h" |
55 | 55 | ||
56 | static unsigned int core_debug = 0; | 56 | static unsigned int core_debug; |
57 | module_param(core_debug,int,0644); | 57 | module_param(core_debug,int,0644); |
58 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); | 58 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); |
59 | 59 | ||
60 | static unsigned int force_testpattern = 0; | 60 | static unsigned int force_testpattern; |
61 | module_param(force_testpattern,int,0644); | 61 | module_param(force_testpattern,int,0644); |
62 | MODULE_PARM_DESC(force_testpattern,"enable test pattern display [core]"); | 62 | MODULE_PARM_DESC(force_testpattern,"enable test pattern display [core]"); |
63 | 63 | ||
64 | static int adjustCompression = 1; // Set the compression to be adaptive | 64 | static int adjustCompression = 1; /* Set the compression to be adaptive */ |
65 | module_param(adjustCompression, int, 0444); | 65 | module_param(adjustCompression, int, 0444); |
66 | MODULE_PARM_DESC(adjustCompression, " Set the ADPCM compression for the device. Default: 1 (On)"); | 66 | MODULE_PARM_DESC(adjustCompression, " Set the ADPCM compression for the device. Default: 1 (On)"); |
67 | 67 | ||
68 | static int SwitchSVideoInput = 0; // To help people with Black and White output with using s-video input. Some cables and input device are wired differently. | 68 | /* To help people with Black and White output with using s-video input. |
69 | * Some cables and input device are wired differently. */ | ||
70 | static int SwitchSVideoInput; | ||
69 | module_param(SwitchSVideoInput, int, 0444); | 71 | module_param(SwitchSVideoInput, int, 0444); |
70 | MODULE_PARM_DESC(SwitchSVideoInput, " Set the S-Video input. Some cables and input device are wired differently. Default: 0 (Off)"); | 72 | MODULE_PARM_DESC(SwitchSVideoInput, " Set the S-Video input. Some cables and input device are wired differently. Default: 0 (Off)"); |
71 | 73 | ||
@@ -82,8 +84,10 @@ MODULE_PARM_DESC(adjust_Y_Offset, "adjust Y offset display [core]"); | |||
82 | 84 | ||
83 | 85 | ||
84 | #ifdef USBVISION_DEBUG | 86 | #ifdef USBVISION_DEBUG |
85 | #define PDEBUG(level, fmt, args...) \ | 87 | #define PDEBUG(level, fmt, args...) { \ |
86 | if (core_debug & (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , ## args) | 88 | if (core_debug & (level)) \ |
89 | info("[%s:%d] " fmt, __func__, __LINE__ , ## args); \ | ||
90 | } | ||
87 | #else | 91 | #else |
88 | #define PDEBUG(level, fmt, args...) do {} while(0) | 92 | #define PDEBUG(level, fmt, args...) do {} while(0) |
89 | #endif | 93 | #endif |
@@ -384,7 +388,7 @@ int usbvision_scratch_alloc(struct usb_usbvision *usbvision) | |||
384 | scratch_reset(usbvision); | 388 | scratch_reset(usbvision); |
385 | if(usbvision->scratch == NULL) { | 389 | if(usbvision->scratch == NULL) { |
386 | err("%s: unable to allocate %d bytes for scratch", | 390 | err("%s: unable to allocate %d bytes for scratch", |
387 | __FUNCTION__, scratch_buf_size); | 391 | __func__, scratch_buf_size); |
388 | return -ENOMEM; | 392 | return -ENOMEM; |
389 | } | 393 | } |
390 | return 0; | 394 | return 0; |
@@ -418,7 +422,7 @@ static void usbvision_testpattern(struct usb_usbvision *usbvision, | |||
418 | unsigned char *f; | 422 | unsigned char *f; |
419 | int num_cell = 0; | 423 | int num_cell = 0; |
420 | int scan_length = 0; | 424 | int scan_length = 0; |
421 | static int num_pass = 0; | 425 | static int num_pass; |
422 | 426 | ||
423 | if (usbvision == NULL) { | 427 | if (usbvision == NULL) { |
424 | printk(KERN_ERR "%s: usbvision == NULL\n", proc); | 428 | printk(KERN_ERR "%s: usbvision == NULL\n", proc); |
@@ -493,7 +497,8 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision) | |||
493 | int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2; | 497 | int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2; |
494 | usbvision->IntraFrameBuffer = vmalloc_32(IFB_size); | 498 | usbvision->IntraFrameBuffer = vmalloc_32(IFB_size); |
495 | if (usbvision->IntraFrameBuffer == NULL) { | 499 | if (usbvision->IntraFrameBuffer == NULL) { |
496 | err("%s: unable to allocate %d for compr. frame buffer", __FUNCTION__, IFB_size); | 500 | err("%s: unable to allocate %d for compr. frame buffer", |
501 | __func__, IFB_size); | ||
497 | return -ENOMEM; | 502 | return -ENOMEM; |
498 | } | 503 | } |
499 | return 0; | 504 | return 0; |
@@ -1430,7 +1435,7 @@ static int usbvision_compress_isochronous(struct usb_usbvision *usbvision, | |||
1430 | } | 1435 | } |
1431 | #if ENABLE_HEXDUMP | 1436 | #if ENABLE_HEXDUMP |
1432 | if (totlen > 0) { | 1437 | if (totlen > 0) { |
1433 | static int foo = 0; | 1438 | static int foo; |
1434 | if (foo < 1) { | 1439 | if (foo < 1) { |
1435 | printk(KERN_DEBUG "+%d.\n", usbvision->scratchlen); | 1440 | printk(KERN_DEBUG "+%d.\n", usbvision->scratchlen); |
1436 | usbvision_hexdump(data0, (totlen > 64) ? 64 : totlen); | 1441 | usbvision_hexdump(data0, (totlen > 64) ? 64 : totlen); |
@@ -1516,7 +1521,7 @@ static void usbvision_isocIrq(struct urb *urb) | |||
1516 | 1521 | ||
1517 | if(errCode) { | 1522 | if(errCode) { |
1518 | err("%s: usb_submit_urb failed: error %d", | 1523 | err("%s: usb_submit_urb failed: error %d", |
1519 | __FUNCTION__, errCode); | 1524 | __func__, errCode); |
1520 | } | 1525 | } |
1521 | 1526 | ||
1522 | return; | 1527 | return; |
@@ -1547,7 +1552,7 @@ int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg) | |||
1547 | 0, (__u16) reg, buffer, 1, HZ); | 1552 | 0, (__u16) reg, buffer, 1, HZ); |
1548 | 1553 | ||
1549 | if (errCode < 0) { | 1554 | if (errCode < 0) { |
1550 | err("%s: failed: error %d", __FUNCTION__, errCode); | 1555 | err("%s: failed: error %d", __func__, errCode); |
1551 | return errCode; | 1556 | return errCode; |
1552 | } | 1557 | } |
1553 | return buffer[0]; | 1558 | return buffer[0]; |
@@ -1575,7 +1580,7 @@ int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg, | |||
1575 | USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ); | 1580 | USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ); |
1576 | 1581 | ||
1577 | if (errCode < 0) { | 1582 | if (errCode < 0) { |
1578 | err("%s: failed: error %d", __FUNCTION__, errCode); | 1583 | err("%s: failed: error %d", __func__, errCode); |
1579 | } | 1584 | } |
1580 | return errCode; | 1585 | return errCode; |
1581 | } | 1586 | } |
@@ -1851,7 +1856,7 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width, | |||
1851 | 0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ); | 1856 | 0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ); |
1852 | 1857 | ||
1853 | if (errCode < 0) { | 1858 | if (errCode < 0) { |
1854 | err("%s failed: error %d", __FUNCTION__, errCode); | 1859 | err("%s failed: error %d", __func__, errCode); |
1855 | return errCode; | 1860 | return errCode; |
1856 | } | 1861 | } |
1857 | usbvision->curwidth = usbvision->stretch_width * UsbWidth; | 1862 | usbvision->curwidth = usbvision->stretch_width * UsbWidth; |
@@ -2237,7 +2242,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision) | |||
2237 | (__u16) USBVISION_DRM_PRM1, value, 8, HZ); | 2242 | (__u16) USBVISION_DRM_PRM1, value, 8, HZ); |
2238 | 2243 | ||
2239 | if (rc < 0) { | 2244 | if (rc < 0) { |
2240 | err("%sERROR=%d", __FUNCTION__, rc); | 2245 | err("%sERROR=%d", __func__, rc); |
2241 | return rc; | 2246 | return rc; |
2242 | } | 2247 | } |
2243 | 2248 | ||
@@ -2486,7 +2491,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2486 | 2491 | ||
2487 | urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL); | 2492 | urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL); |
2488 | if (urb == NULL) { | 2493 | if (urb == NULL) { |
2489 | err("%s: usb_alloc_urb() failed", __FUNCTION__); | 2494 | err("%s: usb_alloc_urb() failed", __func__); |
2490 | return -ENOMEM; | 2495 | return -ENOMEM; |
2491 | } | 2496 | } |
2492 | usbvision->sbuf[bufIdx].urb = urb; | 2497 | usbvision->sbuf[bufIdx].urb = urb; |
@@ -2520,13 +2525,13 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2520 | GFP_KERNEL); | 2525 | GFP_KERNEL); |
2521 | if (errCode) { | 2526 | if (errCode) { |
2522 | err("%s: usb_submit_urb(%d) failed: error %d", | 2527 | err("%s: usb_submit_urb(%d) failed: error %d", |
2523 | __FUNCTION__, bufIdx, errCode); | 2528 | __func__, bufIdx, errCode); |
2524 | } | 2529 | } |
2525 | } | 2530 | } |
2526 | 2531 | ||
2527 | usbvision->streaming = Stream_Idle; | 2532 | usbvision->streaming = Stream_Idle; |
2528 | PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", | 2533 | PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", |
2529 | __FUNCTION__, | 2534 | __func__, |
2530 | usbvision->video_endp); | 2535 | usbvision->video_endp); |
2531 | return 0; | 2536 | return 0; |
2532 | } | 2537 | } |
@@ -2560,7 +2565,7 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) | |||
2560 | } | 2565 | } |
2561 | 2566 | ||
2562 | 2567 | ||
2563 | PDEBUG(DBG_ISOC, "%s: streaming=Stream_Off\n", __FUNCTION__); | 2568 | PDEBUG(DBG_ISOC, "%s: streaming=Stream_Off\n", __func__); |
2564 | usbvision->streaming = Stream_Off; | 2569 | usbvision->streaming = Stream_Off; |
2565 | 2570 | ||
2566 | if (!usbvision->remove_pending) { | 2571 | if (!usbvision->remove_pending) { |
@@ -2571,7 +2576,7 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) | |||
2571 | usbvision->ifaceAlt); | 2576 | usbvision->ifaceAlt); |
2572 | if (errCode < 0) { | 2577 | if (errCode < 0) { |
2573 | err("%s: usb_set_interface() failed: error %d", | 2578 | err("%s: usb_set_interface() failed: error %d", |
2574 | __FUNCTION__, errCode); | 2579 | __func__, errCode); |
2575 | usbvision->last_error = errCode; | 2580 | usbvision->last_error = errCode; |
2576 | } | 2581 | } |
2577 | regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; | 2582 | regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; |
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index aabc42cae9c7..e2274d77ea29 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c | |||
@@ -40,13 +40,15 @@ | |||
40 | 40 | ||
41 | #define DBG_I2C 1<<0 | 41 | #define DBG_I2C 1<<0 |
42 | 42 | ||
43 | static int i2c_debug = 0; | 43 | static int i2c_debug; |
44 | 44 | ||
45 | module_param (i2c_debug, int, 0644); // debug_i2c_usb mode of the device driver | 45 | module_param (i2c_debug, int, 0644); // debug_i2c_usb mode of the device driver |
46 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | 46 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); |
47 | 47 | ||
48 | #define PDEBUG(level, fmt, args...) \ | 48 | #define PDEBUG(level, fmt, args...) { \ |
49 | if (i2c_debug & (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , ## args) | 49 | if (i2c_debug & (level)) \ |
50 | info("[%s:%d] " fmt, __func__, __LINE__ , ## args); \ | ||
51 | } | ||
50 | 52 | ||
51 | static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf, | 53 | static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf, |
52 | short len); | 54 | short len); |
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index df52f8a60215..d97261ab430f 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -97,10 +97,10 @@ USBVISION_DRIVER_VERSION_PATCHLEVEL) | |||
97 | 97 | ||
98 | 98 | ||
99 | #ifdef USBVISION_DEBUG | 99 | #ifdef USBVISION_DEBUG |
100 | #define PDEBUG(level, fmt, args...) \ | 100 | #define PDEBUG(level, fmt, args...) { \ |
101 | if (video_debug & (level)) \ | 101 | if (video_debug & (level)) \ |
102 | info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ ,\ | 102 | info("[%s:%d] " fmt, __func__, __LINE__ , ## args); \ |
103 | ## args) | 103 | } |
104 | #else | 104 | #else |
105 | #define PDEBUG(level, fmt, args...) do {} while(0) | 105 | #define PDEBUG(level, fmt, args...) do {} while(0) |
106 | #endif | 106 | #endif |
@@ -115,7 +115,7 @@ USBVISION_DRIVER_VERSION_PATCHLEVEL) | |||
115 | 115 | ||
116 | 116 | ||
117 | /* sequential number of usbvision device */ | 117 | /* sequential number of usbvision device */ |
118 | static int usbvision_nr = 0; | 118 | static int usbvision_nr; |
119 | 119 | ||
120 | static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = { | 120 | static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = { |
121 | { 1, 1, 8, V4L2_PIX_FMT_GREY , "GREY" }, | 121 | { 1, 1, 8, V4L2_PIX_FMT_GREY , "GREY" }, |
@@ -135,7 +135,7 @@ static void usbvision_release(struct usb_usbvision *usbvision); | |||
135 | /* Set the default format for ISOC endpoint */ | 135 | /* Set the default format for ISOC endpoint */ |
136 | static int isocMode = ISOC_MODE_COMPRESS; | 136 | static int isocMode = ISOC_MODE_COMPRESS; |
137 | /* Set the default Debug Mode of the device driver */ | 137 | /* Set the default Debug Mode of the device driver */ |
138 | static int video_debug = 0; | 138 | static int video_debug; |
139 | /* Set the default device to power on at startup */ | 139 | /* Set the default device to power on at startup */ |
140 | static int PowerOnAtOpen = 1; | 140 | static int PowerOnAtOpen = 1; |
141 | /* Sequential Number of Video Device */ | 141 | /* Sequential Number of Video Device */ |
@@ -343,7 +343,7 @@ static void usbvision_create_sysfs(struct video_device *vdev) | |||
343 | return; | 343 | return; |
344 | } while (0); | 344 | } while (0); |
345 | 345 | ||
346 | err("%s error: %d\n", __FUNCTION__, res); | 346 | err("%s error: %d\n", __func__, res); |
347 | } | 347 | } |
348 | 348 | ||
349 | static void usbvision_remove_sysfs(struct video_device *vdev) | 349 | static void usbvision_remove_sysfs(struct video_device *vdev) |
@@ -490,7 +490,7 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file) | |||
490 | mutex_unlock(&usbvision->lock); | 490 | mutex_unlock(&usbvision->lock); |
491 | 491 | ||
492 | if (usbvision->remove_pending) { | 492 | if (usbvision->remove_pending) { |
493 | printk(KERN_INFO "%s: Final disconnect\n", __FUNCTION__); | 493 | printk(KERN_INFO "%s: Final disconnect\n", __func__); |
494 | usbvision_release(usbvision); | 494 | usbvision_release(usbvision); |
495 | } | 495 | } |
496 | 496 | ||
@@ -522,7 +522,7 @@ static int vidioc_g_register (struct file *file, void *priv, | |||
522 | errCode = usbvision_read_reg(usbvision, reg->reg&0xff); | 522 | errCode = usbvision_read_reg(usbvision, reg->reg&0xff); |
523 | if (errCode < 0) { | 523 | if (errCode < 0) { |
524 | err("%s: VIDIOC_DBG_G_REGISTER failed: error %d", | 524 | err("%s: VIDIOC_DBG_G_REGISTER failed: error %d", |
525 | __FUNCTION__, errCode); | 525 | __func__, errCode); |
526 | return errCode; | 526 | return errCode; |
527 | } | 527 | } |
528 | reg->val = errCode; | 528 | reg->val = errCode; |
@@ -543,7 +543,7 @@ static int vidioc_s_register (struct file *file, void *priv, | |||
543 | errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); | 543 | errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); |
544 | if (errCode < 0) { | 544 | if (errCode < 0) { |
545 | err("%s: VIDIOC_DBG_S_REGISTER failed: error %d", | 545 | err("%s: VIDIOC_DBG_S_REGISTER failed: error %d", |
546 | __FUNCTION__, errCode); | 546 | __func__, errCode); |
547 | return errCode; | 547 | return errCode; |
548 | } | 548 | } |
549 | return 0; | 549 | return 0; |
@@ -1102,7 +1102,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1102 | int ret,i; | 1102 | int ret,i; |
1103 | struct usbvision_frame *frame; | 1103 | struct usbvision_frame *frame; |
1104 | 1104 | ||
1105 | PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __FUNCTION__, | 1105 | PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __func__, |
1106 | (unsigned long)count, noblock); | 1106 | (unsigned long)count, noblock); |
1107 | 1107 | ||
1108 | if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL)) | 1108 | if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL)) |
@@ -1171,7 +1171,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1171 | } | 1171 | } |
1172 | 1172 | ||
1173 | PDEBUG(DBG_IO, "%s: frmx=%d, bytes_read=%ld, scanlength=%ld", | 1173 | PDEBUG(DBG_IO, "%s: frmx=%d, bytes_read=%ld, scanlength=%ld", |
1174 | __FUNCTION__, | 1174 | __func__, |
1175 | frame->index, frame->bytes_read, frame->scanlength); | 1175 | frame->index, frame->bytes_read, frame->scanlength); |
1176 | 1176 | ||
1177 | /* copy bytes to user space; we allow for partials reads */ | 1177 | /* copy bytes to user space; we allow for partials reads */ |
@@ -1184,7 +1184,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1184 | 1184 | ||
1185 | frame->bytes_read += count; | 1185 | frame->bytes_read += count; |
1186 | PDEBUG(DBG_IO, "%s: {copy} count used=%ld, new bytes_read=%ld", | 1186 | PDEBUG(DBG_IO, "%s: {copy} count used=%ld, new bytes_read=%ld", |
1187 | __FUNCTION__, | 1187 | __func__, |
1188 | (unsigned long)count, frame->bytes_read); | 1188 | (unsigned long)count, frame->bytes_read); |
1189 | 1189 | ||
1190 | /* For now, forget the frame if it has not been read in one shot. */ | 1190 | /* For now, forget the frame if it has not been read in one shot. */ |
@@ -1269,12 +1269,12 @@ static int usbvision_radio_open(struct inode *inode, struct file *file) | |||
1269 | (struct usb_usbvision *) video_get_drvdata(dev); | 1269 | (struct usb_usbvision *) video_get_drvdata(dev); |
1270 | int errCode = 0; | 1270 | int errCode = 0; |
1271 | 1271 | ||
1272 | PDEBUG(DBG_IO, "%s:", __FUNCTION__); | 1272 | PDEBUG(DBG_IO, "%s:", __func__); |
1273 | 1273 | ||
1274 | mutex_lock(&usbvision->lock); | 1274 | mutex_lock(&usbvision->lock); |
1275 | 1275 | ||
1276 | if (usbvision->user) { | 1276 | if (usbvision->user) { |
1277 | err("%s: Someone tried to open an already opened USBVision Radio!", __FUNCTION__); | 1277 | err("%s: Someone tried to open an already opened USBVision Radio!", __func__); |
1278 | errCode = -EBUSY; | 1278 | errCode = -EBUSY; |
1279 | } | 1279 | } |
1280 | else { | 1280 | else { |
@@ -1342,7 +1342,7 @@ static int usbvision_radio_close(struct inode *inode, struct file *file) | |||
1342 | mutex_unlock(&usbvision->lock); | 1342 | mutex_unlock(&usbvision->lock); |
1343 | 1343 | ||
1344 | if (usbvision->remove_pending) { | 1344 | if (usbvision->remove_pending) { |
1345 | printk(KERN_INFO "%s: Final disconnect\n", __FUNCTION__); | 1345 | printk(KERN_INFO "%s: Final disconnect\n", __func__); |
1346 | usbvision_release(usbvision); | 1346 | usbvision_release(usbvision); |
1347 | } | 1347 | } |
1348 | 1348 | ||
@@ -1507,7 +1507,7 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, | |||
1507 | struct video_device *vdev; | 1507 | struct video_device *vdev; |
1508 | 1508 | ||
1509 | if (usb_dev == NULL) { | 1509 | if (usb_dev == NULL) { |
1510 | err("%s: usbvision->dev is not set", __FUNCTION__); | 1510 | err("%s: usbvision->dev is not set", __func__); |
1511 | return NULL; | 1511 | return NULL; |
1512 | } | 1512 | } |
1513 | 1513 | ||
@@ -1759,7 +1759,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, | |||
1759 | PDEBUG(DBG_PROBE, "model out of bounds %d",model); | 1759 | PDEBUG(DBG_PROBE, "model out of bounds %d",model); |
1760 | return -ENODEV; | 1760 | return -ENODEV; |
1761 | } | 1761 | } |
1762 | printk(KERN_INFO "%s: %s found\n", __FUNCTION__, | 1762 | printk(KERN_INFO "%s: %s found\n", __func__, |
1763 | usbvision_device_data[model].ModelString); | 1763 | usbvision_device_data[model].ModelString); |
1764 | 1764 | ||
1765 | if (usbvision_device_data[model].Interface >= 0) { | 1765 | if (usbvision_device_data[model].Interface >= 0) { |
@@ -1771,20 +1771,20 @@ static int __devinit usbvision_probe(struct usb_interface *intf, | |||
1771 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != | 1771 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != |
1772 | USB_ENDPOINT_XFER_ISOC) { | 1772 | USB_ENDPOINT_XFER_ISOC) { |
1773 | err("%s: interface %d. has non-ISO endpoint!", | 1773 | err("%s: interface %d. has non-ISO endpoint!", |
1774 | __FUNCTION__, ifnum); | 1774 | __func__, ifnum); |
1775 | err("%s: Endpoint attributes %d", | 1775 | err("%s: Endpoint attributes %d", |
1776 | __FUNCTION__, endpoint->bmAttributes); | 1776 | __func__, endpoint->bmAttributes); |
1777 | return -ENODEV; | 1777 | return -ENODEV; |
1778 | } | 1778 | } |
1779 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == | 1779 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == |
1780 | USB_DIR_OUT) { | 1780 | USB_DIR_OUT) { |
1781 | err("%s: interface %d. has ISO OUT endpoint!", | 1781 | err("%s: interface %d. has ISO OUT endpoint!", |
1782 | __FUNCTION__, ifnum); | 1782 | __func__, ifnum); |
1783 | return -ENODEV; | 1783 | return -ENODEV; |
1784 | } | 1784 | } |
1785 | 1785 | ||
1786 | if ((usbvision = usbvision_alloc(dev)) == NULL) { | 1786 | if ((usbvision = usbvision_alloc(dev)) == NULL) { |
1787 | err("%s: couldn't allocate USBVision struct", __FUNCTION__); | 1787 | err("%s: couldn't allocate USBVision struct", __func__); |
1788 | return -ENOMEM; | 1788 | return -ENOMEM; |
1789 | } | 1789 | } |
1790 | 1790 | ||
@@ -1868,7 +1868,7 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) | |||
1868 | PDEBUG(DBG_PROBE, ""); | 1868 | PDEBUG(DBG_PROBE, ""); |
1869 | 1869 | ||
1870 | if (usbvision == NULL) { | 1870 | if (usbvision == NULL) { |
1871 | err("%s: usb_get_intfdata() failed", __FUNCTION__); | 1871 | err("%s: usb_get_intfdata() failed", __func__); |
1872 | return; | 1872 | return; |
1873 | } | 1873 | } |
1874 | usb_set_intfdata (intf, NULL); | 1874 | usb_set_intfdata (intf, NULL); |
@@ -1891,7 +1891,7 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) | |||
1891 | 1891 | ||
1892 | if (usbvision->user) { | 1892 | if (usbvision->user) { |
1893 | printk(KERN_INFO "%s: In use, disconnect pending\n", | 1893 | printk(KERN_INFO "%s: In use, disconnect pending\n", |
1894 | __FUNCTION__); | 1894 | __func__); |
1895 | wake_up_interruptible(&usbvision->wait_frame); | 1895 | wake_up_interruptible(&usbvision->wait_frame); |
1896 | wake_up_interruptible(&usbvision->wait_stream); | 1896 | wake_up_interruptible(&usbvision->wait_stream); |
1897 | } else { | 1897 | } else { |
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index e3ac5e686075..a0f6c60279ec 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c | |||
@@ -39,15 +39,18 @@ | |||
39 | #include <linux/kmod.h> | 39 | #include <linux/kmod.h> |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | static unsigned int debug = 0; | 42 | static unsigned int debug; |
43 | module_param(debug, int, 0644); | 43 | module_param(debug, int, 0644); |
44 | MODULE_PARM_DESC(debug,"enable debug messages"); | 44 | MODULE_PARM_DESC(debug, "enable debug messages"); |
45 | MODULE_AUTHOR("Bill Dirks"); | 45 | MODULE_AUTHOR("Bill Dirks"); |
46 | MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers."); | 46 | MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers."); |
47 | MODULE_LICENSE("GPL"); | 47 | MODULE_LICENSE("GPL"); |
48 | 48 | ||
49 | #define dprintk(fmt, arg...) if (debug) \ | 49 | #define dprintk(fmt, arg...) \ |
50 | printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg) | 50 | do { \ |
51 | if (debug) \ | ||
52 | printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg);\ | ||
53 | } while (0) | ||
51 | 54 | ||
52 | /* | 55 | /* |
53 | * I O C T L T R A N S L A T I O N | 56 | * I O C T L T R A N S L A T I O N |
@@ -69,14 +72,12 @@ get_v4l_control(struct inode *inode, | |||
69 | qctrl2.id = cid; | 72 | qctrl2.id = cid; |
70 | err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2); | 73 | err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2); |
71 | if (err < 0) | 74 | if (err < 0) |
72 | dprintk("VIDIOC_QUERYCTRL: %d\n",err); | 75 | dprintk("VIDIOC_QUERYCTRL: %d\n", err); |
73 | if (err == 0 && | 76 | if (err == 0 && !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) { |
74 | !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) | ||
75 | { | ||
76 | ctrl2.id = qctrl2.id; | 77 | ctrl2.id = qctrl2.id; |
77 | err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2); | 78 | err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2); |
78 | if (err < 0) { | 79 | if (err < 0) { |
79 | dprintk("VIDIOC_G_CTRL: %d\n",err); | 80 | dprintk("VIDIOC_G_CTRL: %d\n", err); |
80 | return 0; | 81 | return 0; |
81 | } | 82 | } |
82 | return ((ctrl2.value - qctrl2.minimum) * 65535 | 83 | return ((ctrl2.value - qctrl2.minimum) * 65535 |
@@ -100,11 +101,10 @@ set_v4l_control(struct inode *inode, | |||
100 | qctrl2.id = cid; | 101 | qctrl2.id = cid; |
101 | err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2); | 102 | err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2); |
102 | if (err < 0) | 103 | if (err < 0) |
103 | dprintk("VIDIOC_QUERYCTRL: %d\n",err); | 104 | dprintk("VIDIOC_QUERYCTRL: %d\n", err); |
104 | if (err == 0 && | 105 | if (err == 0 && |
105 | !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) && | 106 | !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) && |
106 | !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED)) | 107 | !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED)) { |
107 | { | ||
108 | if (value < 0) | 108 | if (value < 0) |
109 | value = 0; | 109 | value = 0; |
110 | if (value > 65535) | 110 | if (value > 65535) |
@@ -119,7 +119,7 @@ set_v4l_control(struct inode *inode, | |||
119 | ctrl2.value += qctrl2.minimum; | 119 | ctrl2.value += qctrl2.minimum; |
120 | err = drv(inode, file, VIDIOC_S_CTRL, &ctrl2); | 120 | err = drv(inode, file, VIDIOC_S_CTRL, &ctrl2); |
121 | if (err < 0) | 121 | if (err < 0) |
122 | dprintk("VIDIOC_S_CTRL: %d\n",err); | 122 | dprintk("VIDIOC_S_CTRL: %d\n", err); |
123 | } | 123 | } |
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
@@ -157,8 +157,7 @@ static unsigned int __attribute_const__ | |||
157 | pixelformat_to_palette(unsigned int pixelformat) | 157 | pixelformat_to_palette(unsigned int pixelformat) |
158 | { | 158 | { |
159 | int palette = 0; | 159 | int palette = 0; |
160 | switch (pixelformat) | 160 | switch (pixelformat) { |
161 | { | ||
162 | case V4L2_PIX_FMT_GREY: | 161 | case V4L2_PIX_FMT_GREY: |
163 | palette = VIDEO_PALETTE_GREY; | 162 | palette = VIDEO_PALETTE_GREY; |
164 | break; | 163 | break; |
@@ -200,14 +199,13 @@ pixelformat_to_palette(unsigned int pixelformat) | |||
200 | 199 | ||
201 | /* ----------------------------------------------------------------- */ | 200 | /* ----------------------------------------------------------------- */ |
202 | 201 | ||
203 | static int poll_one(struct file *file) | 202 | static int poll_one(struct file *file, struct poll_wqueues *pwq) |
204 | { | 203 | { |
205 | int retval = 1; | 204 | int retval = 1; |
206 | poll_table *table; | 205 | poll_table *table; |
207 | struct poll_wqueues pwq; | ||
208 | 206 | ||
209 | poll_initwait(&pwq); | 207 | poll_initwait(pwq); |
210 | table = &pwq.pt; | 208 | table = &pwq->pt; |
211 | for (;;) { | 209 | for (;;) { |
212 | int mask; | 210 | int mask; |
213 | set_current_state(TASK_INTERRUPTIBLE); | 211 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -222,878 +220,1073 @@ static int poll_one(struct file *file) | |||
222 | schedule(); | 220 | schedule(); |
223 | } | 221 | } |
224 | set_current_state(TASK_RUNNING); | 222 | set_current_state(TASK_RUNNING); |
225 | poll_freewait(&pwq); | 223 | poll_freewait(pwq); |
226 | return retval; | 224 | return retval; |
227 | } | 225 | } |
228 | 226 | ||
229 | static int count_inputs(struct inode *inode, | 227 | static int count_inputs( |
230 | struct file *file, | 228 | struct inode *inode, |
231 | v4l2_kioctl drv) | 229 | struct file *file, |
230 | v4l2_kioctl drv) | ||
232 | { | 231 | { |
233 | struct v4l2_input input2; | 232 | struct v4l2_input input2; |
234 | int i; | 233 | int i; |
235 | 234 | ||
236 | for (i = 0;; i++) { | 235 | for (i = 0;; i++) { |
237 | memset(&input2,0,sizeof(input2)); | 236 | memset(&input2, 0, sizeof(input2)); |
238 | input2.index = i; | 237 | input2.index = i; |
239 | if (0 != drv(inode,file,VIDIOC_ENUMINPUT, &input2)) | 238 | if (0 != drv(inode, file, VIDIOC_ENUMINPUT, &input2)) |
240 | break; | 239 | break; |
241 | } | 240 | } |
242 | return i; | 241 | return i; |
243 | } | 242 | } |
244 | 243 | ||
245 | static int check_size(struct inode *inode, | 244 | static int check_size( |
246 | struct file *file, | 245 | struct inode *inode, |
247 | v4l2_kioctl drv, | 246 | struct file *file, |
248 | int *maxw, int *maxh) | 247 | v4l2_kioctl drv, |
248 | int *maxw, | ||
249 | int *maxh) | ||
249 | { | 250 | { |
250 | struct v4l2_fmtdesc desc2; | 251 | struct v4l2_fmtdesc desc2; |
251 | struct v4l2_format fmt2; | 252 | struct v4l2_format fmt2; |
252 | 253 | ||
253 | memset(&desc2,0,sizeof(desc2)); | 254 | memset(&desc2, 0, sizeof(desc2)); |
254 | memset(&fmt2,0,sizeof(fmt2)); | 255 | memset(&fmt2, 0, sizeof(fmt2)); |
255 | 256 | ||
256 | desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 257 | desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
257 | if (0 != drv(inode,file,VIDIOC_ENUM_FMT, &desc2)) | 258 | if (0 != drv(inode, file, VIDIOC_ENUM_FMT, &desc2)) |
258 | goto done; | 259 | goto done; |
259 | 260 | ||
260 | fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 261 | fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
261 | fmt2.fmt.pix.width = 10000; | 262 | fmt2.fmt.pix.width = 10000; |
262 | fmt2.fmt.pix.height = 10000; | 263 | fmt2.fmt.pix.height = 10000; |
263 | fmt2.fmt.pix.pixelformat = desc2.pixelformat; | 264 | fmt2.fmt.pix.pixelformat = desc2.pixelformat; |
264 | if (0 != drv(inode,file,VIDIOC_TRY_FMT, &fmt2)) | 265 | if (0 != drv(inode, file, VIDIOC_TRY_FMT, &fmt2)) |
265 | goto done; | 266 | goto done; |
266 | 267 | ||
267 | *maxw = fmt2.fmt.pix.width; | 268 | *maxw = fmt2.fmt.pix.width; |
268 | *maxh = fmt2.fmt.pix.height; | 269 | *maxh = fmt2.fmt.pix.height; |
269 | 270 | ||
270 | done: | 271 | done: |
271 | return 0; | 272 | return 0; |
272 | } | 273 | } |
273 | 274 | ||
274 | /* ----------------------------------------------------------------- */ | 275 | /* ----------------------------------------------------------------- */ |
275 | 276 | ||
276 | /* | 277 | static noinline int v4l1_compat_get_capabilities( |
277 | * This function is exported. | 278 | struct video_capability *cap, |
278 | */ | 279 | struct inode *inode, |
279 | int | 280 | struct file *file, |
280 | v4l_compat_translate_ioctl(struct inode *inode, | 281 | v4l2_kioctl drv) |
281 | struct file *file, | ||
282 | int cmd, | ||
283 | void *arg, | ||
284 | v4l2_kioctl drv) | ||
285 | { | 282 | { |
286 | struct v4l2_capability *cap2 = NULL; | 283 | int err; |
287 | struct v4l2_format *fmt2 = NULL; | 284 | struct v4l2_framebuffer fbuf; |
288 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 285 | struct v4l2_capability *cap2; |
289 | 286 | ||
290 | struct v4l2_framebuffer fbuf2; | 287 | cap2 = kzalloc(sizeof(*cap2), GFP_KERNEL); |
291 | struct v4l2_input input2; | 288 | if (!cap2) { |
292 | struct v4l2_tuner tun2; | 289 | err = -ENOMEM; |
293 | struct v4l2_standard std2; | 290 | return err; |
294 | struct v4l2_frequency freq2; | 291 | } |
295 | struct v4l2_audio aud2; | 292 | memset(cap, 0, sizeof(*cap)); |
296 | struct v4l2_queryctrl qctrl2; | 293 | memset(&fbuf, 0, sizeof(fbuf)); |
297 | struct v4l2_buffer buf2; | ||
298 | v4l2_std_id sid; | ||
299 | int i, err = 0; | ||
300 | |||
301 | switch (cmd) { | ||
302 | case VIDIOCGCAP: /* capability */ | ||
303 | { | ||
304 | struct video_capability *cap = arg; | ||
305 | |||
306 | cap2 = kzalloc(sizeof(*cap2), GFP_KERNEL); | ||
307 | if (!cap2) { | ||
308 | err = -ENOMEM; | ||
309 | break; | ||
310 | } | ||
311 | memset(cap, 0, sizeof(*cap)); | ||
312 | memset(&fbuf2, 0, sizeof(fbuf2)); | ||
313 | 294 | ||
314 | err = drv(inode, file, VIDIOC_QUERYCAP, cap2); | 295 | err = drv(inode, file, VIDIOC_QUERYCAP, cap2); |
296 | if (err < 0) { | ||
297 | dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n", err); | ||
298 | goto done; | ||
299 | } | ||
300 | if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) { | ||
301 | err = drv(inode, file, VIDIOC_G_FBUF, &fbuf); | ||
315 | if (err < 0) { | 302 | if (err < 0) { |
316 | dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n",err); | 303 | dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n", err); |
317 | break; | 304 | memset(&fbuf, 0, sizeof(fbuf)); |
318 | } | 305 | } |
319 | if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) { | 306 | err = 0; |
320 | err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2); | ||
321 | if (err < 0) { | ||
322 | dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n",err); | ||
323 | memset(&fbuf2, 0, sizeof(fbuf2)); | ||
324 | } | ||
325 | err = 0; | ||
326 | } | ||
327 | |||
328 | memcpy(cap->name, cap2->card, | ||
329 | min(sizeof(cap->name), sizeof(cap2->card))); | ||
330 | cap->name[sizeof(cap->name) - 1] = 0; | ||
331 | if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE) | ||
332 | cap->type |= VID_TYPE_CAPTURE; | ||
333 | if (cap2->capabilities & V4L2_CAP_TUNER) | ||
334 | cap->type |= VID_TYPE_TUNER; | ||
335 | if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE) | ||
336 | cap->type |= VID_TYPE_TELETEXT; | ||
337 | if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) | ||
338 | cap->type |= VID_TYPE_OVERLAY; | ||
339 | if (fbuf2.capability & V4L2_FBUF_CAP_LIST_CLIPPING) | ||
340 | cap->type |= VID_TYPE_CLIPPING; | ||
341 | |||
342 | cap->channels = count_inputs(inode,file,drv); | ||
343 | check_size(inode,file,drv, | ||
344 | &cap->maxwidth,&cap->maxheight); | ||
345 | cap->audios = 0; /* FIXME */ | ||
346 | cap->minwidth = 48; /* FIXME */ | ||
347 | cap->minheight = 32; /* FIXME */ | ||
348 | break; | ||
349 | } | 307 | } |
350 | case VIDIOCGFBUF: /* get frame buffer */ | ||
351 | { | ||
352 | struct video_buffer *buffer = arg; | ||
353 | 308 | ||
354 | memset(buffer, 0, sizeof(*buffer)); | 309 | memcpy(cap->name, cap2->card, |
355 | memset(&fbuf2, 0, sizeof(fbuf2)); | 310 | min(sizeof(cap->name), sizeof(cap2->card))); |
311 | cap->name[sizeof(cap->name) - 1] = 0; | ||
312 | if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE) | ||
313 | cap->type |= VID_TYPE_CAPTURE; | ||
314 | if (cap2->capabilities & V4L2_CAP_TUNER) | ||
315 | cap->type |= VID_TYPE_TUNER; | ||
316 | if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE) | ||
317 | cap->type |= VID_TYPE_TELETEXT; | ||
318 | if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) | ||
319 | cap->type |= VID_TYPE_OVERLAY; | ||
320 | if (fbuf.capability & V4L2_FBUF_CAP_LIST_CLIPPING) | ||
321 | cap->type |= VID_TYPE_CLIPPING; | ||
322 | |||
323 | cap->channels = count_inputs(inode, file, drv); | ||
324 | check_size(inode, file, drv, | ||
325 | &cap->maxwidth, &cap->maxheight); | ||
326 | cap->audios = 0; /* FIXME */ | ||
327 | cap->minwidth = 48; /* FIXME */ | ||
328 | cap->minheight = 32; /* FIXME */ | ||
329 | |||
330 | done: | ||
331 | kfree(cap2); | ||
332 | return err; | ||
333 | } | ||
356 | 334 | ||
357 | err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2); | 335 | static noinline int v4l1_compat_get_frame_buffer( |
358 | if (err < 0) { | 336 | struct video_buffer *buffer, |
359 | dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n",err); | 337 | struct inode *inode, |
360 | break; | 338 | struct file *file, |
361 | } | 339 | v4l2_kioctl drv) |
362 | buffer->base = fbuf2.base; | 340 | { |
363 | buffer->height = fbuf2.fmt.height; | 341 | int err; |
364 | buffer->width = fbuf2.fmt.width; | 342 | struct v4l2_framebuffer fbuf; |
365 | 343 | ||
366 | switch (fbuf2.fmt.pixelformat) { | 344 | memset(buffer, 0, sizeof(*buffer)); |
367 | case V4L2_PIX_FMT_RGB332: | 345 | memset(&fbuf, 0, sizeof(fbuf)); |
368 | buffer->depth = 8; | 346 | |
369 | break; | 347 | err = drv(inode, file, VIDIOC_G_FBUF, &fbuf); |
370 | case V4L2_PIX_FMT_RGB555: | 348 | if (err < 0) { |
371 | buffer->depth = 15; | 349 | dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n", err); |
372 | break; | 350 | goto done; |
373 | case V4L2_PIX_FMT_RGB565: | 351 | } |
374 | buffer->depth = 16; | 352 | buffer->base = fbuf.base; |
375 | break; | 353 | buffer->height = fbuf.fmt.height; |
376 | case V4L2_PIX_FMT_BGR24: | 354 | buffer->width = fbuf.fmt.width; |
377 | buffer->depth = 24; | 355 | |
378 | break; | 356 | switch (fbuf.fmt.pixelformat) { |
379 | case V4L2_PIX_FMT_BGR32: | 357 | case V4L2_PIX_FMT_RGB332: |
380 | buffer->depth = 32; | 358 | buffer->depth = 8; |
381 | break; | 359 | break; |
382 | default: | 360 | case V4L2_PIX_FMT_RGB555: |
383 | buffer->depth = 0; | 361 | buffer->depth = 15; |
384 | } | 362 | break; |
385 | if (fbuf2.fmt.bytesperline) { | 363 | case V4L2_PIX_FMT_RGB565: |
386 | buffer->bytesperline = fbuf2.fmt.bytesperline; | 364 | buffer->depth = 16; |
387 | if (!buffer->depth && buffer->width) | 365 | break; |
388 | buffer->depth = ((fbuf2.fmt.bytesperline<<3) | 366 | case V4L2_PIX_FMT_BGR24: |
389 | + (buffer->width-1) ) | 367 | buffer->depth = 24; |
390 | /buffer->width; | 368 | break; |
391 | } else { | 369 | case V4L2_PIX_FMT_BGR32: |
392 | buffer->bytesperline = | 370 | buffer->depth = 32; |
393 | (buffer->width * buffer->depth + 7) & 7; | ||
394 | buffer->bytesperline >>= 3; | ||
395 | } | ||
396 | break; | 371 | break; |
372 | default: | ||
373 | buffer->depth = 0; | ||
397 | } | 374 | } |
398 | case VIDIOCSFBUF: /* set frame buffer */ | 375 | if (fbuf.fmt.bytesperline) { |
399 | { | 376 | buffer->bytesperline = fbuf.fmt.bytesperline; |
400 | struct video_buffer *buffer = arg; | 377 | if (!buffer->depth && buffer->width) |
401 | 378 | buffer->depth = ((fbuf.fmt.bytesperline<<3) | |
402 | memset(&fbuf2, 0, sizeof(fbuf2)); | 379 | + (buffer->width-1)) |
403 | fbuf2.base = buffer->base; | 380 | / buffer->width; |
404 | fbuf2.fmt.height = buffer->height; | 381 | } else { |
405 | fbuf2.fmt.width = buffer->width; | 382 | buffer->bytesperline = |
406 | switch (buffer->depth) { | 383 | (buffer->width * buffer->depth + 7) & 7; |
407 | case 8: | 384 | buffer->bytesperline >>= 3; |
408 | fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB332; | 385 | } |
409 | break; | 386 | done: |
410 | case 15: | 387 | return err; |
411 | fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB555; | 388 | } |
412 | break; | 389 | |
413 | case 16: | 390 | static noinline int v4l1_compat_set_frame_buffer( |
414 | fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB565; | 391 | struct video_buffer *buffer, |
415 | break; | 392 | struct inode *inode, |
416 | case 24: | 393 | struct file *file, |
417 | fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR24; | 394 | v4l2_kioctl drv) |
418 | break; | 395 | { |
419 | case 32: | 396 | int err; |
420 | fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR32; | 397 | struct v4l2_framebuffer fbuf; |
421 | break; | 398 | |
422 | } | 399 | memset(&fbuf, 0, sizeof(fbuf)); |
423 | fbuf2.fmt.bytesperline = buffer->bytesperline; | 400 | fbuf.base = buffer->base; |
424 | err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2); | 401 | fbuf.fmt.height = buffer->height; |
425 | if (err < 0) | 402 | fbuf.fmt.width = buffer->width; |
426 | dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n",err); | 403 | switch (buffer->depth) { |
404 | case 8: | ||
405 | fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB332; | ||
406 | break; | ||
407 | case 15: | ||
408 | fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB555; | ||
409 | break; | ||
410 | case 16: | ||
411 | fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB565; | ||
412 | break; | ||
413 | case 24: | ||
414 | fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR24; | ||
415 | break; | ||
416 | case 32: | ||
417 | fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR32; | ||
427 | break; | 418 | break; |
428 | } | 419 | } |
429 | case VIDIOCGWIN: /* get window or capture dimensions */ | 420 | fbuf.fmt.bytesperline = buffer->bytesperline; |
430 | { | 421 | err = drv(inode, file, VIDIOC_S_FBUF, &fbuf); |
431 | struct video_window *win = arg; | 422 | if (err < 0) |
423 | dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n", err); | ||
424 | return err; | ||
425 | } | ||
432 | 426 | ||
433 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); | 427 | static noinline int v4l1_compat_get_win_cap_dimensions( |
434 | if (!fmt2) { | 428 | struct video_window *win, |
435 | err = -ENOMEM; | 429 | struct inode *inode, |
436 | break; | 430 | struct file *file, |
437 | } | 431 | v4l2_kioctl drv) |
438 | memset(win,0,sizeof(*win)); | 432 | { |
433 | int err; | ||
434 | struct v4l2_format *fmt; | ||
439 | 435 | ||
440 | fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; | 436 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); |
441 | err = drv(inode, file, VIDIOC_G_FMT, fmt2); | 437 | if (!fmt) { |
442 | if (err < 0) | 438 | err = -ENOMEM; |
443 | dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n",err); | 439 | return err; |
444 | if (err == 0) { | 440 | } |
445 | win->x = fmt2->fmt.win.w.left; | 441 | memset(win, 0, sizeof(*win)); |
446 | win->y = fmt2->fmt.win.w.top; | ||
447 | win->width = fmt2->fmt.win.w.width; | ||
448 | win->height = fmt2->fmt.win.w.height; | ||
449 | win->chromakey = fmt2->fmt.win.chromakey; | ||
450 | win->clips = NULL; | ||
451 | win->clipcount = 0; | ||
452 | break; | ||
453 | } | ||
454 | 442 | ||
455 | fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 443 | fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; |
456 | err = drv(inode, file, VIDIOC_G_FMT, fmt2); | 444 | err = drv(inode, file, VIDIOC_G_FMT, fmt); |
457 | if (err < 0) { | 445 | if (err < 0) |
458 | dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n",err); | 446 | dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n", err); |
459 | break; | 447 | if (err == 0) { |
460 | } | 448 | win->x = fmt->fmt.win.w.left; |
461 | win->x = 0; | 449 | win->y = fmt->fmt.win.w.top; |
462 | win->y = 0; | 450 | win->width = fmt->fmt.win.w.width; |
463 | win->width = fmt2->fmt.pix.width; | 451 | win->height = fmt->fmt.win.w.height; |
464 | win->height = fmt2->fmt.pix.height; | 452 | win->chromakey = fmt->fmt.win.chromakey; |
465 | win->chromakey = 0; | ||
466 | win->clips = NULL; | 453 | win->clips = NULL; |
467 | win->clipcount = 0; | 454 | win->clipcount = 0; |
468 | break; | 455 | goto done; |
469 | } | 456 | } |
470 | case VIDIOCSWIN: /* set window and/or capture dimensions */ | ||
471 | { | ||
472 | struct video_window *win = arg; | ||
473 | int err1,err2; | ||
474 | 457 | ||
475 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); | 458 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
476 | if (!fmt2) { | 459 | err = drv(inode, file, VIDIOC_G_FMT, fmt); |
477 | err = -ENOMEM; | 460 | if (err < 0) { |
478 | break; | 461 | dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n", err); |
479 | } | 462 | goto done; |
480 | fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 463 | } |
481 | drv(inode, file, VIDIOC_STREAMOFF, &fmt2->type); | 464 | win->x = 0; |
482 | err1 = drv(inode, file, VIDIOC_G_FMT, fmt2); | 465 | win->y = 0; |
483 | if (err1 < 0) | 466 | win->width = fmt->fmt.pix.width; |
484 | dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n",err); | 467 | win->height = fmt->fmt.pix.height; |
485 | if (err1 == 0) { | 468 | win->chromakey = 0; |
486 | fmt2->fmt.pix.width = win->width; | 469 | win->clips = NULL; |
487 | fmt2->fmt.pix.height = win->height; | 470 | win->clipcount = 0; |
488 | fmt2->fmt.pix.field = V4L2_FIELD_ANY; | 471 | done: |
489 | fmt2->fmt.pix.bytesperline = 0; | 472 | kfree(fmt); |
490 | err = drv(inode, file, VIDIOC_S_FMT, fmt2); | 473 | return err; |
491 | if (err < 0) | 474 | } |
492 | dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n", | ||
493 | err); | ||
494 | win->width = fmt2->fmt.pix.width; | ||
495 | win->height = fmt2->fmt.pix.height; | ||
496 | } | ||
497 | 475 | ||
498 | memset(fmt2,0,sizeof(*fmt2)); | 476 | static noinline int v4l1_compat_set_win_cap_dimensions( |
499 | fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; | 477 | struct video_window *win, |
500 | fmt2->fmt.win.w.left = win->x; | 478 | struct inode *inode, |
501 | fmt2->fmt.win.w.top = win->y; | 479 | struct file *file, |
502 | fmt2->fmt.win.w.width = win->width; | 480 | v4l2_kioctl drv) |
503 | fmt2->fmt.win.w.height = win->height; | 481 | { |
504 | fmt2->fmt.win.chromakey = win->chromakey; | 482 | int err, err1, err2; |
505 | fmt2->fmt.win.clips = (void __user *)win->clips; | 483 | struct v4l2_format *fmt; |
506 | fmt2->fmt.win.clipcount = win->clipcount; | 484 | |
507 | err2 = drv(inode, file, VIDIOC_S_FMT, fmt2); | 485 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); |
508 | if (err2 < 0) | 486 | if (!fmt) { |
509 | dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n",err); | 487 | err = -ENOMEM; |
510 | 488 | return err; | |
511 | if (err1 != 0 && err2 != 0) | ||
512 | err = err1; | ||
513 | break; | ||
514 | } | 489 | } |
515 | case VIDIOCCAPTURE: /* turn on/off preview */ | 490 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
516 | { | 491 | drv(inode, file, VIDIOC_STREAMOFF, &fmt->type); |
517 | int *on = arg; | 492 | err1 = drv(inode, file, VIDIOC_G_FMT, fmt); |
518 | 493 | if (err1 < 0) | |
519 | if (0 == *on) { | 494 | dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n", err1); |
520 | /* dirty hack time. But v4l1 has no STREAMOFF | 495 | if (err1 == 0) { |
521 | * equivalent in the API, and this one at | 496 | fmt->fmt.pix.width = win->width; |
522 | * least comes close ... */ | 497 | fmt->fmt.pix.height = win->height; |
523 | drv(inode, file, VIDIOC_STREAMOFF, &captype); | 498 | fmt->fmt.pix.field = V4L2_FIELD_ANY; |
524 | } | 499 | fmt->fmt.pix.bytesperline = 0; |
525 | err = drv(inode, file, VIDIOC_OVERLAY, arg); | 500 | err = drv(inode, file, VIDIOC_S_FMT, fmt); |
526 | if (err < 0) | 501 | if (err < 0) |
527 | dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n",err); | 502 | dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n", |
528 | break; | 503 | err); |
504 | win->width = fmt->fmt.pix.width; | ||
505 | win->height = fmt->fmt.pix.height; | ||
529 | } | 506 | } |
530 | case VIDIOCGCHAN: /* get input information */ | ||
531 | { | ||
532 | struct video_channel *chan = arg; | ||
533 | 507 | ||
534 | memset(&input2,0,sizeof(input2)); | 508 | memset(fmt, 0, sizeof(*fmt)); |
535 | input2.index = chan->channel; | 509 | fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; |
536 | err = drv(inode, file, VIDIOC_ENUMINPUT, &input2); | 510 | fmt->fmt.win.w.left = win->x; |
537 | if (err < 0) { | 511 | fmt->fmt.win.w.top = win->y; |
538 | dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: " | 512 | fmt->fmt.win.w.width = win->width; |
539 | "channel=%d err=%d\n",chan->channel,err); | 513 | fmt->fmt.win.w.height = win->height; |
540 | break; | 514 | fmt->fmt.win.chromakey = win->chromakey; |
541 | } | 515 | fmt->fmt.win.clips = (void __user *)win->clips; |
542 | chan->channel = input2.index; | 516 | fmt->fmt.win.clipcount = win->clipcount; |
543 | memcpy(chan->name, input2.name, | 517 | err2 = drv(inode, file, VIDIOC_S_FMT, fmt); |
544 | min(sizeof(chan->name), sizeof(input2.name))); | 518 | if (err2 < 0) |
545 | chan->name[sizeof(chan->name) - 1] = 0; | 519 | dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n", err2); |
546 | chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0; | 520 | |
547 | chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0; | 521 | if (err1 != 0 && err2 != 0) |
548 | switch (input2.type) { | 522 | err = err1; |
549 | case V4L2_INPUT_TYPE_TUNER: | 523 | else |
550 | chan->type = VIDEO_TYPE_TV; | 524 | err = 0; |
551 | break; | 525 | kfree(fmt); |
552 | default: | 526 | return err; |
553 | case V4L2_INPUT_TYPE_CAMERA: | 527 | } |
554 | chan->type = VIDEO_TYPE_CAMERA; | ||
555 | break; | ||
556 | } | ||
557 | chan->norm = 0; | ||
558 | err = drv(inode, file, VIDIOC_G_STD, &sid); | ||
559 | if (err < 0) | ||
560 | dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n",err); | ||
561 | if (err == 0) { | ||
562 | if (sid & V4L2_STD_PAL) | ||
563 | chan->norm = VIDEO_MODE_PAL; | ||
564 | if (sid & V4L2_STD_NTSC) | ||
565 | chan->norm = VIDEO_MODE_NTSC; | ||
566 | if (sid & V4L2_STD_SECAM) | ||
567 | chan->norm = VIDEO_MODE_SECAM; | ||
568 | } | ||
569 | break; | ||
570 | } | ||
571 | case VIDIOCSCHAN: /* set input */ | ||
572 | { | ||
573 | struct video_channel *chan = arg; | ||
574 | 528 | ||
575 | sid = 0; | 529 | static noinline int v4l1_compat_turn_preview_on_off( |
576 | err = drv(inode, file, VIDIOC_S_INPUT, &chan->channel); | 530 | int *on, |
577 | if (err < 0) | 531 | struct inode *inode, |
578 | dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n",err); | 532 | struct file *file, |
579 | switch (chan->norm) { | 533 | v4l2_kioctl drv) |
580 | case VIDEO_MODE_PAL: | 534 | { |
581 | sid = V4L2_STD_PAL; | 535 | int err; |
582 | break; | 536 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
583 | case VIDEO_MODE_NTSC: | 537 | |
584 | sid = V4L2_STD_NTSC; | 538 | if (0 == *on) { |
585 | break; | 539 | /* dirty hack time. But v4l1 has no STREAMOFF |
586 | case VIDEO_MODE_SECAM: | 540 | * equivalent in the API, and this one at |
587 | sid = V4L2_STD_SECAM; | 541 | * least comes close ... */ |
588 | break; | 542 | drv(inode, file, VIDIOC_STREAMOFF, &captype); |
589 | } | ||
590 | if (0 != sid) { | ||
591 | err = drv(inode, file, VIDIOC_S_STD, &sid); | ||
592 | if (err < 0) | ||
593 | dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n",err); | ||
594 | } | ||
595 | break; | ||
596 | } | 543 | } |
597 | case VIDIOCGPICT: /* get tone controls & partial capture format */ | 544 | err = drv(inode, file, VIDIOC_OVERLAY, on); |
598 | { | 545 | if (err < 0) |
599 | struct video_picture *pict = arg; | 546 | dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n", err); |
600 | 547 | return err; | |
601 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); | 548 | } |
602 | if (!fmt2) { | ||
603 | err = -ENOMEM; | ||
604 | break; | ||
605 | } | ||
606 | 549 | ||
607 | pict->brightness = get_v4l_control(inode, file, | 550 | static noinline int v4l1_compat_get_input_info( |
608 | V4L2_CID_BRIGHTNESS,drv); | 551 | struct video_channel *chan, |
609 | pict->hue = get_v4l_control(inode, file, | 552 | struct inode *inode, |
610 | V4L2_CID_HUE, drv); | 553 | struct file *file, |
611 | pict->contrast = get_v4l_control(inode, file, | 554 | v4l2_kioctl drv) |
612 | V4L2_CID_CONTRAST, drv); | 555 | { |
613 | pict->colour = get_v4l_control(inode, file, | 556 | int err; |
614 | V4L2_CID_SATURATION, drv); | 557 | struct v4l2_input input2; |
615 | pict->whiteness = get_v4l_control(inode, file, | 558 | v4l2_std_id sid; |
616 | V4L2_CID_WHITENESS, drv); | ||
617 | |||
618 | fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
619 | err = drv(inode, file, VIDIOC_G_FMT, fmt2); | ||
620 | if (err < 0) { | ||
621 | dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err); | ||
622 | break; | ||
623 | } | ||
624 | 559 | ||
625 | pict->depth = ((fmt2->fmt.pix.bytesperline<<3) | 560 | memset(&input2, 0, sizeof(input2)); |
626 | + (fmt2->fmt.pix.width-1) ) | 561 | input2.index = chan->channel; |
627 | /fmt2->fmt.pix.width; | 562 | err = drv(inode, file, VIDIOC_ENUMINPUT, &input2); |
628 | pict->palette = pixelformat_to_palette( | 563 | if (err < 0) { |
629 | fmt2->fmt.pix.pixelformat); | 564 | dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: " |
565 | "channel=%d err=%d\n", chan->channel, err); | ||
566 | goto done; | ||
567 | } | ||
568 | chan->channel = input2.index; | ||
569 | memcpy(chan->name, input2.name, | ||
570 | min(sizeof(chan->name), sizeof(input2.name))); | ||
571 | chan->name[sizeof(chan->name) - 1] = 0; | ||
572 | chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0; | ||
573 | chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0; | ||
574 | switch (input2.type) { | ||
575 | case V4L2_INPUT_TYPE_TUNER: | ||
576 | chan->type = VIDEO_TYPE_TV; | ||
577 | break; | ||
578 | default: | ||
579 | case V4L2_INPUT_TYPE_CAMERA: | ||
580 | chan->type = VIDEO_TYPE_CAMERA; | ||
630 | break; | 581 | break; |
631 | } | 582 | } |
632 | case VIDIOCSPICT: /* set tone controls & partial capture format */ | 583 | chan->norm = 0; |
633 | { | 584 | err = drv(inode, file, VIDIOC_G_STD, &sid); |
634 | struct video_picture *pict = arg; | 585 | if (err < 0) |
635 | int mem_err = 0, ovl_err = 0; | 586 | dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n", err); |
587 | if (err == 0) { | ||
588 | if (sid & V4L2_STD_PAL) | ||
589 | chan->norm = VIDEO_MODE_PAL; | ||
590 | if (sid & V4L2_STD_NTSC) | ||
591 | chan->norm = VIDEO_MODE_NTSC; | ||
592 | if (sid & V4L2_STD_SECAM) | ||
593 | chan->norm = VIDEO_MODE_SECAM; | ||
594 | } | ||
595 | done: | ||
596 | return err; | ||
597 | } | ||
636 | 598 | ||
637 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); | 599 | static noinline int v4l1_compat_set_input( |
638 | if (!fmt2) { | 600 | struct video_channel *chan, |
639 | err = -ENOMEM; | 601 | struct inode *inode, |
640 | break; | 602 | struct file *file, |
641 | } | 603 | v4l2_kioctl drv) |
642 | memset(&fbuf2, 0, sizeof(fbuf2)); | 604 | { |
643 | 605 | int err; | |
644 | set_v4l_control(inode, file, | 606 | v4l2_std_id sid = 0; |
645 | V4L2_CID_BRIGHTNESS, pict->brightness, drv); | ||
646 | set_v4l_control(inode, file, | ||
647 | V4L2_CID_HUE, pict->hue, drv); | ||
648 | set_v4l_control(inode, file, | ||
649 | V4L2_CID_CONTRAST, pict->contrast, drv); | ||
650 | set_v4l_control(inode, file, | ||
651 | V4L2_CID_SATURATION, pict->colour, drv); | ||
652 | set_v4l_control(inode, file, | ||
653 | V4L2_CID_WHITENESS, pict->whiteness, drv); | ||
654 | /* | ||
655 | * V4L1 uses this ioctl to set both memory capture and overlay | ||
656 | * pixel format, while V4L2 has two different ioctls for this. | ||
657 | * Some cards may not support one or the other, and may support | ||
658 | * different pixel formats for memory vs overlay. | ||
659 | */ | ||
660 | |||
661 | fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
662 | err = drv(inode, file, VIDIOC_G_FMT, fmt2); | ||
663 | /* If VIDIOC_G_FMT failed, then the driver likely doesn't | ||
664 | support memory capture. Trying to set the memory capture | ||
665 | parameters would be pointless. */ | ||
666 | if (err < 0) { | ||
667 | dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err); | ||
668 | mem_err = -1000; /* didn't even try */ | ||
669 | } else if (fmt2->fmt.pix.pixelformat != | ||
670 | palette_to_pixelformat(pict->palette)) { | ||
671 | fmt2->fmt.pix.pixelformat = palette_to_pixelformat( | ||
672 | pict->palette); | ||
673 | mem_err = drv(inode, file, VIDIOC_S_FMT, fmt2); | ||
674 | if (mem_err < 0) | ||
675 | dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n", | ||
676 | mem_err); | ||
677 | } | ||
678 | 607 | ||
679 | err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2); | 608 | err = drv(inode, file, VIDIOC_S_INPUT, &chan->channel); |
680 | /* If VIDIOC_G_FBUF failed, then the driver likely doesn't | 609 | if (err < 0) |
681 | support overlay. Trying to set the overlay parameters | 610 | dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n", err); |
682 | would be quite pointless. */ | 611 | switch (chan->norm) { |
683 | if (err < 0) { | 612 | case VIDEO_MODE_PAL: |
684 | dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err); | 613 | sid = V4L2_STD_PAL; |
685 | ovl_err = -1000; /* didn't even try */ | 614 | break; |
686 | } else if (fbuf2.fmt.pixelformat != | 615 | case VIDEO_MODE_NTSC: |
687 | palette_to_pixelformat(pict->palette)) { | 616 | sid = V4L2_STD_NTSC; |
688 | fbuf2.fmt.pixelformat = palette_to_pixelformat( | 617 | break; |
689 | pict->palette); | 618 | case VIDEO_MODE_SECAM: |
690 | ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2); | 619 | sid = V4L2_STD_SECAM; |
691 | if (ovl_err < 0) | ||
692 | dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n", | ||
693 | ovl_err); | ||
694 | } | ||
695 | if (ovl_err < 0 && mem_err < 0) | ||
696 | /* ioctl failed, couldn't set either parameter */ | ||
697 | if (mem_err != -1000) { | ||
698 | err = mem_err; | ||
699 | } else if (ovl_err == -EPERM) { | ||
700 | err = 0; | ||
701 | } else { | ||
702 | err = ovl_err; | ||
703 | } | ||
704 | else | ||
705 | err = 0; | ||
706 | break; | 620 | break; |
707 | } | 621 | } |
708 | case VIDIOCGTUNER: /* get tuner information */ | 622 | if (0 != sid) { |
709 | { | 623 | err = drv(inode, file, VIDIOC_S_STD, &sid); |
710 | struct video_tuner *tun = arg; | ||
711 | |||
712 | memset(&tun2,0,sizeof(tun2)); | ||
713 | err = drv(inode, file, VIDIOC_G_TUNER, &tun2); | ||
714 | if (err < 0) { | ||
715 | dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n",err); | ||
716 | break; | ||
717 | } | ||
718 | memcpy(tun->name, tun2.name, | ||
719 | min(sizeof(tun->name), sizeof(tun2.name))); | ||
720 | tun->name[sizeof(tun->name) - 1] = 0; | ||
721 | tun->rangelow = tun2.rangelow; | ||
722 | tun->rangehigh = tun2.rangehigh; | ||
723 | tun->flags = 0; | ||
724 | tun->mode = VIDEO_MODE_AUTO; | ||
725 | |||
726 | for (i = 0; i < 64; i++) { | ||
727 | memset(&std2,0,sizeof(std2)); | ||
728 | std2.index = i; | ||
729 | if (0 != drv(inode, file, VIDIOC_ENUMSTD, &std2)) | ||
730 | break; | ||
731 | if (std2.id & V4L2_STD_PAL) | ||
732 | tun->flags |= VIDEO_TUNER_PAL; | ||
733 | if (std2.id & V4L2_STD_NTSC) | ||
734 | tun->flags |= VIDEO_TUNER_NTSC; | ||
735 | if (std2.id & V4L2_STD_SECAM) | ||
736 | tun->flags |= VIDEO_TUNER_SECAM; | ||
737 | } | ||
738 | |||
739 | err = drv(inode, file, VIDIOC_G_STD, &sid); | ||
740 | if (err < 0) | 624 | if (err < 0) |
741 | dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n",err); | 625 | dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n", err); |
742 | if (err == 0) { | ||
743 | if (sid & V4L2_STD_PAL) | ||
744 | tun->mode = VIDEO_MODE_PAL; | ||
745 | if (sid & V4L2_STD_NTSC) | ||
746 | tun->mode = VIDEO_MODE_NTSC; | ||
747 | if (sid & V4L2_STD_SECAM) | ||
748 | tun->mode = VIDEO_MODE_SECAM; | ||
749 | } | ||
750 | |||
751 | if (tun2.capability & V4L2_TUNER_CAP_LOW) | ||
752 | tun->flags |= VIDEO_TUNER_LOW; | ||
753 | if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
754 | tun->flags |= VIDEO_TUNER_STEREO_ON; | ||
755 | tun->signal = tun2.signal; | ||
756 | break; | ||
757 | } | 626 | } |
758 | case VIDIOCSTUNER: /* select a tuner input */ | 627 | return err; |
759 | { | 628 | } |
760 | struct video_tuner *tun = arg; | ||
761 | struct v4l2_tuner t; | ||
762 | memset(&t,0,sizeof(t)); | ||
763 | |||
764 | t.index=tun->tuner; | ||
765 | 629 | ||
766 | err = drv(inode, file, VIDIOC_S_INPUT, &t); | 630 | static noinline int v4l1_compat_get_picture( |
767 | if (err < 0) | 631 | struct video_picture *pict, |
768 | dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err); | 632 | struct inode *inode, |
633 | struct file *file, | ||
634 | v4l2_kioctl drv) | ||
635 | { | ||
636 | int err; | ||
637 | struct v4l2_format *fmt; | ||
769 | 638 | ||
770 | break; | 639 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); |
640 | if (!fmt) { | ||
641 | err = -ENOMEM; | ||
642 | return err; | ||
771 | } | 643 | } |
772 | case VIDIOCGFREQ: /* get frequency */ | ||
773 | { | ||
774 | unsigned long *freq = arg; | ||
775 | memset(&freq2,0,sizeof(freq2)); | ||
776 | 644 | ||
777 | freq2.tuner = 0; | 645 | pict->brightness = get_v4l_control(inode, file, |
778 | err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); | 646 | V4L2_CID_BRIGHTNESS, drv); |
779 | if (err < 0) | 647 | pict->hue = get_v4l_control(inode, file, |
780 | dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n",err); | 648 | V4L2_CID_HUE, drv); |
781 | if (0 == err) | 649 | pict->contrast = get_v4l_control(inode, file, |
782 | *freq = freq2.frequency; | 650 | V4L2_CID_CONTRAST, drv); |
783 | break; | 651 | pict->colour = get_v4l_control(inode, file, |
652 | V4L2_CID_SATURATION, drv); | ||
653 | pict->whiteness = get_v4l_control(inode, file, | ||
654 | V4L2_CID_WHITENESS, drv); | ||
655 | |||
656 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
657 | err = drv(inode, file, VIDIOC_G_FMT, fmt); | ||
658 | if (err < 0) { | ||
659 | dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n", err); | ||
660 | goto done; | ||
784 | } | 661 | } |
785 | case VIDIOCSFREQ: /* set frequency */ | ||
786 | { | ||
787 | unsigned long *freq = arg; | ||
788 | memset(&freq2,0,sizeof(freq2)); | ||
789 | 662 | ||
790 | drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); | 663 | pict->depth = ((fmt->fmt.pix.bytesperline << 3) |
791 | freq2.frequency = *freq; | 664 | + (fmt->fmt.pix.width - 1)) |
792 | err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2); | 665 | / fmt->fmt.pix.width; |
793 | if (err < 0) | 666 | pict->palette = pixelformat_to_palette( |
794 | dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n",err); | 667 | fmt->fmt.pix.pixelformat); |
795 | break; | 668 | done: |
669 | kfree(fmt); | ||
670 | return err; | ||
671 | } | ||
672 | |||
673 | static noinline int v4l1_compat_set_picture( | ||
674 | struct video_picture *pict, | ||
675 | struct inode *inode, | ||
676 | struct file *file, | ||
677 | v4l2_kioctl drv) | ||
678 | { | ||
679 | int err; | ||
680 | struct v4l2_framebuffer fbuf; | ||
681 | int mem_err = 0, ovl_err = 0; | ||
682 | struct v4l2_format *fmt; | ||
683 | |||
684 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); | ||
685 | if (!fmt) { | ||
686 | err = -ENOMEM; | ||
687 | return err; | ||
688 | } | ||
689 | memset(&fbuf, 0, sizeof(fbuf)); | ||
690 | |||
691 | set_v4l_control(inode, file, | ||
692 | V4L2_CID_BRIGHTNESS, pict->brightness, drv); | ||
693 | set_v4l_control(inode, file, | ||
694 | V4L2_CID_HUE, pict->hue, drv); | ||
695 | set_v4l_control(inode, file, | ||
696 | V4L2_CID_CONTRAST, pict->contrast, drv); | ||
697 | set_v4l_control(inode, file, | ||
698 | V4L2_CID_SATURATION, pict->colour, drv); | ||
699 | set_v4l_control(inode, file, | ||
700 | V4L2_CID_WHITENESS, pict->whiteness, drv); | ||
701 | /* | ||
702 | * V4L1 uses this ioctl to set both memory capture and overlay | ||
703 | * pixel format, while V4L2 has two different ioctls for this. | ||
704 | * Some cards may not support one or the other, and may support | ||
705 | * different pixel formats for memory vs overlay. | ||
706 | */ | ||
707 | |||
708 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
709 | err = drv(inode, file, VIDIOC_G_FMT, fmt); | ||
710 | /* If VIDIOC_G_FMT failed, then the driver likely doesn't | ||
711 | support memory capture. Trying to set the memory capture | ||
712 | parameters would be pointless. */ | ||
713 | if (err < 0) { | ||
714 | dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n", err); | ||
715 | mem_err = -1000; /* didn't even try */ | ||
716 | } else if (fmt->fmt.pix.pixelformat != | ||
717 | palette_to_pixelformat(pict->palette)) { | ||
718 | fmt->fmt.pix.pixelformat = palette_to_pixelformat( | ||
719 | pict->palette); | ||
720 | mem_err = drv(inode, file, VIDIOC_S_FMT, fmt); | ||
721 | if (mem_err < 0) | ||
722 | dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n", | ||
723 | mem_err); | ||
796 | } | 724 | } |
797 | case VIDIOCGAUDIO: /* get audio properties/controls */ | ||
798 | { | ||
799 | struct video_audio *aud = arg; | ||
800 | memset(&aud2,0,sizeof(aud2)); | ||
801 | 725 | ||
802 | err = drv(inode, file, VIDIOC_G_AUDIO, &aud2); | 726 | err = drv(inode, file, VIDIOC_G_FBUF, &fbuf); |
803 | if (err < 0) { | 727 | /* If VIDIOC_G_FBUF failed, then the driver likely doesn't |
804 | dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n",err); | 728 | support overlay. Trying to set the overlay parameters |
805 | break; | 729 | would be quite pointless. */ |
806 | } | 730 | if (err < 0) { |
807 | memcpy(aud->name, aud2.name, | 731 | dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n", err); |
808 | min(sizeof(aud->name), sizeof(aud2.name))); | 732 | ovl_err = -1000; /* didn't even try */ |
809 | aud->name[sizeof(aud->name) - 1] = 0; | 733 | } else if (fbuf.fmt.pixelformat != |
810 | aud->audio = aud2.index; | 734 | palette_to_pixelformat(pict->palette)) { |
811 | aud->flags = 0; | 735 | fbuf.fmt.pixelformat = palette_to_pixelformat( |
812 | i = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv); | 736 | pict->palette); |
813 | if (i >= 0) { | 737 | ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf); |
814 | aud->volume = i; | 738 | if (ovl_err < 0) |
815 | aud->flags |= VIDEO_AUDIO_VOLUME; | 739 | dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n", |
816 | } | 740 | ovl_err); |
817 | i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv); | 741 | } |
818 | if (i >= 0) { | 742 | if (ovl_err < 0 && mem_err < 0) { |
819 | aud->bass = i; | 743 | /* ioctl failed, couldn't set either parameter */ |
820 | aud->flags |= VIDEO_AUDIO_BASS; | 744 | if (mem_err != -1000) |
821 | } | 745 | err = mem_err; |
822 | i = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv); | 746 | else if (ovl_err == -EPERM) |
823 | if (i >= 0) { | ||
824 | aud->treble = i; | ||
825 | aud->flags |= VIDEO_AUDIO_TREBLE; | ||
826 | } | ||
827 | i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv); | ||
828 | if (i >= 0) { | ||
829 | aud->balance = i; | ||
830 | aud->flags |= VIDEO_AUDIO_BALANCE; | ||
831 | } | ||
832 | i = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv); | ||
833 | if (i >= 0) { | ||
834 | if (i) | ||
835 | aud->flags |= VIDEO_AUDIO_MUTE; | ||
836 | aud->flags |= VIDEO_AUDIO_MUTABLE; | ||
837 | } | ||
838 | aud->step = 1; | ||
839 | qctrl2.id = V4L2_CID_AUDIO_VOLUME; | ||
840 | if (drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2) == 0 && | ||
841 | !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) | ||
842 | aud->step = qctrl2.step; | ||
843 | aud->mode = 0; | ||
844 | |||
845 | memset(&tun2,0,sizeof(tun2)); | ||
846 | err = drv(inode, file, VIDIOC_G_TUNER, &tun2); | ||
847 | if (err < 0) { | ||
848 | dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err); | ||
849 | err = 0; | 747 | err = 0; |
748 | else | ||
749 | err = ovl_err; | ||
750 | } else | ||
751 | err = 0; | ||
752 | kfree(fmt); | ||
753 | return err; | ||
754 | } | ||
755 | |||
756 | static noinline int v4l1_compat_get_tuner( | ||
757 | struct video_tuner *tun, | ||
758 | struct inode *inode, | ||
759 | struct file *file, | ||
760 | v4l2_kioctl drv) | ||
761 | { | ||
762 | int err, i; | ||
763 | struct v4l2_tuner tun2; | ||
764 | struct v4l2_standard std2; | ||
765 | v4l2_std_id sid; | ||
766 | |||
767 | memset(&tun2, 0, sizeof(tun2)); | ||
768 | err = drv(inode, file, VIDIOC_G_TUNER, &tun2); | ||
769 | if (err < 0) { | ||
770 | dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n", err); | ||
771 | goto done; | ||
772 | } | ||
773 | memcpy(tun->name, tun2.name, | ||
774 | min(sizeof(tun->name), sizeof(tun2.name))); | ||
775 | tun->name[sizeof(tun->name) - 1] = 0; | ||
776 | tun->rangelow = tun2.rangelow; | ||
777 | tun->rangehigh = tun2.rangehigh; | ||
778 | tun->flags = 0; | ||
779 | tun->mode = VIDEO_MODE_AUTO; | ||
780 | |||
781 | for (i = 0; i < 64; i++) { | ||
782 | memset(&std2, 0, sizeof(std2)); | ||
783 | std2.index = i; | ||
784 | if (0 != drv(inode, file, VIDIOC_ENUMSTD, &std2)) | ||
850 | break; | 785 | break; |
851 | } | 786 | if (std2.id & V4L2_STD_PAL) |
787 | tun->flags |= VIDEO_TUNER_PAL; | ||
788 | if (std2.id & V4L2_STD_NTSC) | ||
789 | tun->flags |= VIDEO_TUNER_NTSC; | ||
790 | if (std2.id & V4L2_STD_SECAM) | ||
791 | tun->flags |= VIDEO_TUNER_SECAM; | ||
792 | } | ||
852 | 793 | ||
853 | if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2) | 794 | err = drv(inode, file, VIDIOC_G_STD, &sid); |
854 | aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; | 795 | if (err < 0) |
855 | else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO) | 796 | dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n", err); |
856 | aud->mode = VIDEO_SOUND_STEREO; | 797 | if (err == 0) { |
857 | else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO) | 798 | if (sid & V4L2_STD_PAL) |
858 | aud->mode = VIDEO_SOUND_MONO; | 799 | tun->mode = VIDEO_MODE_PAL; |
859 | break; | 800 | if (sid & V4L2_STD_NTSC) |
801 | tun->mode = VIDEO_MODE_NTSC; | ||
802 | if (sid & V4L2_STD_SECAM) | ||
803 | tun->mode = VIDEO_MODE_SECAM; | ||
860 | } | 804 | } |
861 | case VIDIOCSAUDIO: /* set audio controls */ | ||
862 | { | ||
863 | struct video_audio *aud = arg; | ||
864 | 805 | ||
865 | memset(&aud2,0,sizeof(aud2)); | 806 | if (tun2.capability & V4L2_TUNER_CAP_LOW) |
866 | memset(&tun2,0,sizeof(tun2)); | 807 | tun->flags |= VIDEO_TUNER_LOW; |
808 | if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
809 | tun->flags |= VIDEO_TUNER_STEREO_ON; | ||
810 | tun->signal = tun2.signal; | ||
811 | done: | ||
812 | return err; | ||
813 | } | ||
867 | 814 | ||
868 | aud2.index = aud->audio; | 815 | static noinline int v4l1_compat_select_tuner( |
869 | err = drv(inode, file, VIDIOC_S_AUDIO, &aud2); | 816 | struct video_tuner *tun, |
870 | if (err < 0) { | 817 | struct inode *inode, |
871 | dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n",err); | 818 | struct file *file, |
872 | break; | 819 | v4l2_kioctl drv) |
873 | } | 820 | { |
821 | int err; | ||
822 | struct v4l2_tuner t;/*84 bytes on x86_64*/ | ||
823 | memset(&t, 0, sizeof(t)); | ||
874 | 824 | ||
875 | set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, | 825 | t.index = tun->tuner; |
876 | aud->volume, drv); | 826 | |
877 | set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, | 827 | err = drv(inode, file, VIDIOC_S_INPUT, &t); |
878 | aud->bass, drv); | 828 | if (err < 0) |
879 | set_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, | 829 | dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n", err); |
880 | aud->treble, drv); | 830 | return err; |
881 | set_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, | 831 | } |
882 | aud->balance, drv); | 832 | |
883 | set_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, | 833 | static noinline int v4l1_compat_get_frequency( |
884 | !!(aud->flags & VIDEO_AUDIO_MUTE), drv); | 834 | unsigned long *freq, |
885 | 835 | struct inode *inode, | |
886 | err = drv(inode, file, VIDIOC_G_TUNER, &tun2); | 836 | struct file *file, |
887 | if (err < 0) | 837 | v4l2_kioctl drv) |
888 | dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n",err); | 838 | { |
889 | if (err == 0) { | 839 | int err; |
890 | switch (aud->mode) { | 840 | struct v4l2_frequency freq2; |
891 | default: | 841 | memset(&freq2, 0, sizeof(freq2)); |
892 | case VIDEO_SOUND_MONO: | 842 | |
893 | case VIDEO_SOUND_LANG1: | 843 | freq2.tuner = 0; |
894 | tun2.audmode = V4L2_TUNER_MODE_MONO; | 844 | err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); |
895 | break; | 845 | if (err < 0) |
896 | case VIDEO_SOUND_STEREO: | 846 | dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n", err); |
897 | tun2.audmode = V4L2_TUNER_MODE_STEREO; | 847 | if (0 == err) |
898 | break; | 848 | *freq = freq2.frequency; |
899 | case VIDEO_SOUND_LANG2: | 849 | return err; |
900 | tun2.audmode = V4L2_TUNER_MODE_LANG2; | 850 | } |
901 | break; | 851 | |
902 | } | 852 | static noinline int v4l1_compat_set_frequency( |
903 | err = drv(inode, file, VIDIOC_S_TUNER, &tun2); | 853 | unsigned long *freq, |
904 | if (err < 0) | 854 | struct inode *inode, |
905 | dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n",err); | 855 | struct file *file, |
906 | } | 856 | v4l2_kioctl drv) |
857 | { | ||
858 | int err; | ||
859 | struct v4l2_frequency freq2; | ||
860 | memset(&freq2, 0, sizeof(freq2)); | ||
861 | |||
862 | drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); | ||
863 | freq2.frequency = *freq; | ||
864 | err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2); | ||
865 | if (err < 0) | ||
866 | dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n", err); | ||
867 | return err; | ||
868 | } | ||
869 | |||
870 | static noinline int v4l1_compat_get_audio( | ||
871 | struct video_audio *aud, | ||
872 | struct inode *inode, | ||
873 | struct file *file, | ||
874 | v4l2_kioctl drv) | ||
875 | { | ||
876 | int err, i; | ||
877 | struct v4l2_queryctrl qctrl2; | ||
878 | struct v4l2_audio aud2; | ||
879 | struct v4l2_tuner tun2; | ||
880 | memset(&aud2, 0, sizeof(aud2)); | ||
881 | |||
882 | err = drv(inode, file, VIDIOC_G_AUDIO, &aud2); | ||
883 | if (err < 0) { | ||
884 | dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n", err); | ||
885 | goto done; | ||
886 | } | ||
887 | memcpy(aud->name, aud2.name, | ||
888 | min(sizeof(aud->name), sizeof(aud2.name))); | ||
889 | aud->name[sizeof(aud->name) - 1] = 0; | ||
890 | aud->audio = aud2.index; | ||
891 | aud->flags = 0; | ||
892 | i = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv); | ||
893 | if (i >= 0) { | ||
894 | aud->volume = i; | ||
895 | aud->flags |= VIDEO_AUDIO_VOLUME; | ||
896 | } | ||
897 | i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv); | ||
898 | if (i >= 0) { | ||
899 | aud->bass = i; | ||
900 | aud->flags |= VIDEO_AUDIO_BASS; | ||
901 | } | ||
902 | i = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv); | ||
903 | if (i >= 0) { | ||
904 | aud->treble = i; | ||
905 | aud->flags |= VIDEO_AUDIO_TREBLE; | ||
906 | } | ||
907 | i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv); | ||
908 | if (i >= 0) { | ||
909 | aud->balance = i; | ||
910 | aud->flags |= VIDEO_AUDIO_BALANCE; | ||
911 | } | ||
912 | i = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv); | ||
913 | if (i >= 0) { | ||
914 | if (i) | ||
915 | aud->flags |= VIDEO_AUDIO_MUTE; | ||
916 | aud->flags |= VIDEO_AUDIO_MUTABLE; | ||
917 | } | ||
918 | aud->step = 1; | ||
919 | qctrl2.id = V4L2_CID_AUDIO_VOLUME; | ||
920 | if (drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2) == 0 && | ||
921 | !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) | ||
922 | aud->step = qctrl2.step; | ||
923 | aud->mode = 0; | ||
924 | |||
925 | memset(&tun2, 0, sizeof(tun2)); | ||
926 | err = drv(inode, file, VIDIOC_G_TUNER, &tun2); | ||
927 | if (err < 0) { | ||
928 | dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n", err); | ||
907 | err = 0; | 929 | err = 0; |
908 | break; | 930 | goto done; |
909 | } | 931 | } |
910 | case VIDIOCMCAPTURE: /* capture a frame */ | ||
911 | { | ||
912 | struct video_mmap *mm = arg; | ||
913 | 932 | ||
914 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); | 933 | if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2) |
915 | if (!fmt2) { | 934 | aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; |
916 | err = -ENOMEM; | 935 | else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO) |
917 | break; | 936 | aud->mode = VIDEO_SOUND_STEREO; |
918 | } | 937 | else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO) |
919 | memset(&buf2,0,sizeof(buf2)); | 938 | aud->mode = VIDEO_SOUND_MONO; |
939 | done: | ||
940 | return err; | ||
941 | } | ||
920 | 942 | ||
921 | fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 943 | static noinline int v4l1_compat_set_audio( |
922 | err = drv(inode, file, VIDIOC_G_FMT, fmt2); | 944 | struct video_audio *aud, |
923 | if (err < 0) { | 945 | struct inode *inode, |
924 | dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n",err); | 946 | struct file *file, |
947 | v4l2_kioctl drv) | ||
948 | { | ||
949 | int err; | ||
950 | struct v4l2_audio aud2; | ||
951 | struct v4l2_tuner tun2; | ||
952 | |||
953 | memset(&aud2, 0, sizeof(aud2)); | ||
954 | memset(&tun2, 0, sizeof(tun2)); | ||
955 | |||
956 | aud2.index = aud->audio; | ||
957 | err = drv(inode, file, VIDIOC_S_AUDIO, &aud2); | ||
958 | if (err < 0) { | ||
959 | dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n", err); | ||
960 | goto done; | ||
961 | } | ||
962 | |||
963 | set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, | ||
964 | aud->volume, drv); | ||
965 | set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, | ||
966 | aud->bass, drv); | ||
967 | set_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, | ||
968 | aud->treble, drv); | ||
969 | set_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, | ||
970 | aud->balance, drv); | ||
971 | set_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, | ||
972 | !!(aud->flags & VIDEO_AUDIO_MUTE), drv); | ||
973 | |||
974 | err = drv(inode, file, VIDIOC_G_TUNER, &tun2); | ||
975 | if (err < 0) | ||
976 | dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n", err); | ||
977 | if (err == 0) { | ||
978 | switch (aud->mode) { | ||
979 | default: | ||
980 | case VIDEO_SOUND_MONO: | ||
981 | case VIDEO_SOUND_LANG1: | ||
982 | tun2.audmode = V4L2_TUNER_MODE_MONO; | ||
925 | break; | 983 | break; |
926 | } | 984 | case VIDEO_SOUND_STEREO: |
927 | if (mm->width != fmt2->fmt.pix.width || | 985 | tun2.audmode = V4L2_TUNER_MODE_STEREO; |
928 | mm->height != fmt2->fmt.pix.height || | ||
929 | palette_to_pixelformat(mm->format) != | ||
930 | fmt2->fmt.pix.pixelformat) | ||
931 | {/* New capture format... */ | ||
932 | fmt2->fmt.pix.width = mm->width; | ||
933 | fmt2->fmt.pix.height = mm->height; | ||
934 | fmt2->fmt.pix.pixelformat = | ||
935 | palette_to_pixelformat(mm->format); | ||
936 | fmt2->fmt.pix.field = V4L2_FIELD_ANY; | ||
937 | fmt2->fmt.pix.bytesperline = 0; | ||
938 | err = drv(inode, file, VIDIOC_S_FMT, fmt2); | ||
939 | if (err < 0) { | ||
940 | dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n",err); | ||
941 | break; | ||
942 | } | ||
943 | } | ||
944 | buf2.index = mm->frame; | ||
945 | buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
946 | err = drv(inode, file, VIDIOC_QUERYBUF, &buf2); | ||
947 | if (err < 0) { | ||
948 | dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n",err); | ||
949 | break; | 986 | break; |
950 | } | 987 | case VIDEO_SOUND_LANG2: |
951 | err = drv(inode, file, VIDIOC_QBUF, &buf2); | 988 | tun2.audmode = V4L2_TUNER_MODE_LANG2; |
952 | if (err < 0) { | ||
953 | dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n",err); | ||
954 | break; | 989 | break; |
955 | } | 990 | } |
956 | err = drv(inode, file, VIDIOC_STREAMON, &captype); | 991 | err = drv(inode, file, VIDIOC_S_TUNER, &tun2); |
957 | if (err < 0) | 992 | if (err < 0) |
958 | dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n",err); | 993 | dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n", err); |
959 | break; | ||
960 | } | 994 | } |
961 | case VIDIOCSYNC: /* wait for a frame */ | 995 | err = 0; |
962 | { | 996 | done: |
963 | int *i = arg; | 997 | return err; |
998 | } | ||
964 | 999 | ||
965 | memset(&buf2,0,sizeof(buf2)); | 1000 | static noinline int v4l1_compat_capture_frame( |
966 | buf2.index = *i; | 1001 | struct video_mmap *mm, |
967 | buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1002 | struct inode *inode, |
968 | err = drv(inode, file, VIDIOC_QUERYBUF, &buf2); | 1003 | struct file *file, |
969 | if (err < 0) { | 1004 | v4l2_kioctl drv) |
970 | /* No such buffer */ | 1005 | { |
971 | dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err); | 1006 | int err; |
972 | break; | 1007 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
973 | } | 1008 | struct v4l2_buffer buf; |
974 | if (!(buf2.flags & V4L2_BUF_FLAG_MAPPED)) { | 1009 | struct v4l2_format *fmt; |
975 | /* Buffer is not mapped */ | 1010 | |
976 | err = -EINVAL; | 1011 | fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); |
977 | break; | 1012 | if (!fmt) { |
978 | } | 1013 | err = -ENOMEM; |
1014 | return err; | ||
1015 | } | ||
1016 | memset(&buf, 0, sizeof(buf)); | ||
979 | 1017 | ||
980 | /* make sure capture actually runs so we don't block forever */ | 1018 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
981 | err = drv(inode, file, VIDIOC_STREAMON, &captype); | 1019 | err = drv(inode, file, VIDIOC_G_FMT, fmt); |
1020 | if (err < 0) { | ||
1021 | dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n", err); | ||
1022 | goto done; | ||
1023 | } | ||
1024 | if (mm->width != fmt->fmt.pix.width || | ||
1025 | mm->height != fmt->fmt.pix.height || | ||
1026 | palette_to_pixelformat(mm->format) != | ||
1027 | fmt->fmt.pix.pixelformat) { | ||
1028 | /* New capture format... */ | ||
1029 | fmt->fmt.pix.width = mm->width; | ||
1030 | fmt->fmt.pix.height = mm->height; | ||
1031 | fmt->fmt.pix.pixelformat = | ||
1032 | palette_to_pixelformat(mm->format); | ||
1033 | fmt->fmt.pix.field = V4L2_FIELD_ANY; | ||
1034 | fmt->fmt.pix.bytesperline = 0; | ||
1035 | err = drv(inode, file, VIDIOC_S_FMT, fmt); | ||
982 | if (err < 0) { | 1036 | if (err < 0) { |
983 | dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %d\n",err); | 1037 | dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n", err); |
984 | break; | 1038 | goto done; |
985 | } | 1039 | } |
1040 | } | ||
1041 | buf.index = mm->frame; | ||
1042 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1043 | err = drv(inode, file, VIDIOC_QUERYBUF, &buf); | ||
1044 | if (err < 0) { | ||
1045 | dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n", err); | ||
1046 | goto done; | ||
1047 | } | ||
1048 | err = drv(inode, file, VIDIOC_QBUF, &buf); | ||
1049 | if (err < 0) { | ||
1050 | dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n", err); | ||
1051 | goto done; | ||
1052 | } | ||
1053 | err = drv(inode, file, VIDIOC_STREAMON, &captype); | ||
1054 | if (err < 0) | ||
1055 | dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n", err); | ||
1056 | done: | ||
1057 | kfree(fmt); | ||
1058 | return err; | ||
1059 | } | ||
986 | 1060 | ||
987 | /* Loop as long as the buffer is queued, but not done */ | 1061 | static noinline int v4l1_compat_sync( |
988 | while ((buf2.flags & | 1062 | int *i, |
989 | (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) | 1063 | struct inode *inode, |
990 | == V4L2_BUF_FLAG_QUEUED) | 1064 | struct file *file, |
991 | { | 1065 | v4l2_kioctl drv) |
992 | err = poll_one(file); | 1066 | { |
993 | if (err < 0 || /* error or sleep was interrupted */ | 1067 | int err; |
994 | err == 0) /* timeout? Shouldn't occur. */ | 1068 | enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
995 | break; | 1069 | struct v4l2_buffer buf; |
996 | err = drv(inode, file, VIDIOC_QUERYBUF, &buf2); | 1070 | struct poll_wqueues *pwq; |
997 | if (err < 0) | 1071 | |
998 | dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err); | 1072 | memset(&buf, 0, sizeof(buf)); |
999 | } | 1073 | buf.index = *i; |
1000 | if (!(buf2.flags & V4L2_BUF_FLAG_DONE)) /* not done */ | 1074 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1001 | break; | 1075 | err = drv(inode, file, VIDIOC_QUERYBUF, &buf); |
1002 | do { | 1076 | if (err < 0) { |
1003 | err = drv(inode, file, VIDIOC_DQBUF, &buf2); | 1077 | /* No such buffer */ |
1004 | if (err < 0) | 1078 | dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err); |
1005 | dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n",err); | 1079 | goto done; |
1006 | } while (err == 0 && buf2.index != *i); | 1080 | } |
1007 | break; | 1081 | if (!(buf.flags & V4L2_BUF_FLAG_MAPPED)) { |
1082 | /* Buffer is not mapped */ | ||
1083 | err = -EINVAL; | ||
1084 | goto done; | ||
1008 | } | 1085 | } |
1009 | 1086 | ||
1010 | case VIDIOCGVBIFMT: /* query VBI data capture format */ | 1087 | /* make sure capture actually runs so we don't block forever */ |
1011 | { | 1088 | err = drv(inode, file, VIDIOC_STREAMON, &captype); |
1012 | struct vbi_format *fmt = arg; | 1089 | if (err < 0) { |
1090 | dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %d\n", err); | ||
1091 | goto done; | ||
1092 | } | ||
1013 | 1093 | ||
1014 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); | 1094 | pwq = kmalloc(sizeof(*pwq), GFP_KERNEL); |
1015 | if (!fmt2) { | 1095 | /* Loop as long as the buffer is queued, but not done */ |
1016 | err = -ENOMEM; | 1096 | while ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) |
1097 | == V4L2_BUF_FLAG_QUEUED) { | ||
1098 | err = poll_one(file, pwq); | ||
1099 | if (err < 0 || /* error or sleep was interrupted */ | ||
1100 | err == 0) /* timeout? Shouldn't occur. */ | ||
1017 | break; | 1101 | break; |
1018 | } | 1102 | err = drv(inode, file, VIDIOC_QUERYBUF, &buf); |
1019 | fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE; | 1103 | if (err < 0) |
1104 | dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err); | ||
1105 | } | ||
1106 | kfree(pwq); | ||
1107 | if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */ | ||
1108 | goto done; | ||
1109 | do { | ||
1110 | err = drv(inode, file, VIDIOC_DQBUF, &buf); | ||
1111 | if (err < 0) | ||
1112 | dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n", err); | ||
1113 | } while (err == 0 && buf.index != *i); | ||
1114 | done: | ||
1115 | return err; | ||
1116 | } | ||
1020 | 1117 | ||
1021 | err = drv(inode, file, VIDIOC_G_FMT, fmt2); | 1118 | static noinline int v4l1_compat_get_vbi_format( |
1022 | if (err < 0) { | 1119 | struct vbi_format *fmt, |
1023 | dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err); | 1120 | struct inode *inode, |
1024 | break; | 1121 | struct file *file, |
1025 | } | 1122 | v4l2_kioctl drv) |
1026 | if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) { | 1123 | { |
1027 | err = -EINVAL; | 1124 | int err; |
1028 | break; | 1125 | struct v4l2_format *fmt2; |
1029 | } | 1126 | |
1030 | memset(fmt, 0, sizeof(*fmt)); | 1127 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); |
1031 | fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line; | 1128 | if (!fmt2) { |
1032 | fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate; | 1129 | err = -ENOMEM; |
1033 | fmt->sample_format = VIDEO_PALETTE_RAW; | 1130 | return err; |
1034 | fmt->start[0] = fmt2->fmt.vbi.start[0]; | ||
1035 | fmt->count[0] = fmt2->fmt.vbi.count[0]; | ||
1036 | fmt->start[1] = fmt2->fmt.vbi.start[1]; | ||
1037 | fmt->count[1] = fmt2->fmt.vbi.count[1]; | ||
1038 | fmt->flags = fmt2->fmt.vbi.flags & 0x03; | ||
1039 | break; | ||
1040 | } | 1131 | } |
1041 | case VIDIOCSVBIFMT: | 1132 | fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE; |
1042 | { | ||
1043 | struct vbi_format *fmt = arg; | ||
1044 | 1133 | ||
1045 | if (VIDEO_PALETTE_RAW != fmt->sample_format) { | 1134 | err = drv(inode, file, VIDIOC_G_FMT, fmt2); |
1046 | err = -EINVAL; | 1135 | if (err < 0) { |
1047 | break; | 1136 | dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err); |
1048 | } | 1137 | goto done; |
1138 | } | ||
1139 | if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) { | ||
1140 | err = -EINVAL; | ||
1141 | goto done; | ||
1142 | } | ||
1143 | memset(fmt, 0, sizeof(*fmt)); | ||
1144 | fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line; | ||
1145 | fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate; | ||
1146 | fmt->sample_format = VIDEO_PALETTE_RAW; | ||
1147 | fmt->start[0] = fmt2->fmt.vbi.start[0]; | ||
1148 | fmt->count[0] = fmt2->fmt.vbi.count[0]; | ||
1149 | fmt->start[1] = fmt2->fmt.vbi.start[1]; | ||
1150 | fmt->count[1] = fmt2->fmt.vbi.count[1]; | ||
1151 | fmt->flags = fmt2->fmt.vbi.flags & 0x03; | ||
1152 | done: | ||
1153 | kfree(fmt2); | ||
1154 | return err; | ||
1155 | } | ||
1049 | 1156 | ||
1050 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); | 1157 | static noinline int v4l1_compat_set_vbi_format( |
1051 | if (!fmt2) { | 1158 | struct vbi_format *fmt, |
1052 | err = -ENOMEM; | 1159 | struct inode *inode, |
1053 | break; | 1160 | struct file *file, |
1054 | } | 1161 | v4l2_kioctl drv) |
1055 | fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE; | 1162 | { |
1056 | fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line; | 1163 | int err; |
1057 | fmt2->fmt.vbi.sampling_rate = fmt->sampling_rate; | 1164 | struct v4l2_format *fmt2 = NULL; |
1058 | fmt2->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
1059 | fmt2->fmt.vbi.start[0] = fmt->start[0]; | ||
1060 | fmt2->fmt.vbi.count[0] = fmt->count[0]; | ||
1061 | fmt2->fmt.vbi.start[1] = fmt->start[1]; | ||
1062 | fmt2->fmt.vbi.count[1] = fmt->count[1]; | ||
1063 | fmt2->fmt.vbi.flags = fmt->flags; | ||
1064 | err = drv(inode, file, VIDIOC_TRY_FMT, fmt2); | ||
1065 | if (err < 0) { | ||
1066 | dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %d\n", err); | ||
1067 | break; | ||
1068 | } | ||
1069 | 1165 | ||
1070 | if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line || | 1166 | if (VIDEO_PALETTE_RAW != fmt->sample_format) { |
1071 | fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate || | 1167 | err = -EINVAL; |
1072 | fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY || | 1168 | return err; |
1073 | fmt2->fmt.vbi.start[0] != fmt->start[0] || | ||
1074 | fmt2->fmt.vbi.count[0] != fmt->count[0] || | ||
1075 | fmt2->fmt.vbi.start[1] != fmt->start[1] || | ||
1076 | fmt2->fmt.vbi.count[1] != fmt->count[1] || | ||
1077 | fmt2->fmt.vbi.flags != fmt->flags) { | ||
1078 | err = -EINVAL; | ||
1079 | break; | ||
1080 | } | ||
1081 | err = drv(inode, file, VIDIOC_S_FMT, fmt2); | ||
1082 | if (err < 0) | ||
1083 | dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err); | ||
1084 | break; | ||
1085 | } | 1169 | } |
1086 | 1170 | ||
1171 | fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); | ||
1172 | if (!fmt2) { | ||
1173 | err = -ENOMEM; | ||
1174 | return err; | ||
1175 | } | ||
1176 | fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
1177 | fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line; | ||
1178 | fmt2->fmt.vbi.sampling_rate = fmt->sampling_rate; | ||
1179 | fmt2->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
1180 | fmt2->fmt.vbi.start[0] = fmt->start[0]; | ||
1181 | fmt2->fmt.vbi.count[0] = fmt->count[0]; | ||
1182 | fmt2->fmt.vbi.start[1] = fmt->start[1]; | ||
1183 | fmt2->fmt.vbi.count[1] = fmt->count[1]; | ||
1184 | fmt2->fmt.vbi.flags = fmt->flags; | ||
1185 | err = drv(inode, file, VIDIOC_TRY_FMT, fmt2); | ||
1186 | if (err < 0) { | ||
1187 | dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %d\n", err); | ||
1188 | goto done; | ||
1189 | } | ||
1190 | |||
1191 | if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line || | ||
1192 | fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate || | ||
1193 | fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY || | ||
1194 | fmt2->fmt.vbi.start[0] != fmt->start[0] || | ||
1195 | fmt2->fmt.vbi.count[0] != fmt->count[0] || | ||
1196 | fmt2->fmt.vbi.start[1] != fmt->start[1] || | ||
1197 | fmt2->fmt.vbi.count[1] != fmt->count[1] || | ||
1198 | fmt2->fmt.vbi.flags != fmt->flags) { | ||
1199 | err = -EINVAL; | ||
1200 | goto done; | ||
1201 | } | ||
1202 | err = drv(inode, file, VIDIOC_S_FMT, fmt2); | ||
1203 | if (err < 0) | ||
1204 | dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err); | ||
1205 | done: | ||
1206 | kfree(fmt2); | ||
1207 | return err; | ||
1208 | } | ||
1209 | |||
1210 | /* | ||
1211 | * This function is exported. | ||
1212 | */ | ||
1213 | int | ||
1214 | v4l_compat_translate_ioctl(struct inode *inode, | ||
1215 | struct file *file, | ||
1216 | int cmd, | ||
1217 | void *arg, | ||
1218 | v4l2_kioctl drv) | ||
1219 | { | ||
1220 | int err; | ||
1221 | |||
1222 | switch (cmd) { | ||
1223 | case VIDIOCGCAP: /* capability */ | ||
1224 | err = v4l1_compat_get_capabilities(arg, inode, file, drv); | ||
1225 | break; | ||
1226 | case VIDIOCGFBUF: /* get frame buffer */ | ||
1227 | err = v4l1_compat_get_frame_buffer(arg, inode, file, drv); | ||
1228 | break; | ||
1229 | case VIDIOCSFBUF: /* set frame buffer */ | ||
1230 | err = v4l1_compat_set_frame_buffer(arg, inode, file, drv); | ||
1231 | break; | ||
1232 | case VIDIOCGWIN: /* get window or capture dimensions */ | ||
1233 | err = v4l1_compat_get_win_cap_dimensions(arg, inode, file, drv); | ||
1234 | break; | ||
1235 | case VIDIOCSWIN: /* set window and/or capture dimensions */ | ||
1236 | err = v4l1_compat_set_win_cap_dimensions(arg, inode, file, drv); | ||
1237 | break; | ||
1238 | case VIDIOCCAPTURE: /* turn on/off preview */ | ||
1239 | err = v4l1_compat_turn_preview_on_off(arg, inode, file, drv); | ||
1240 | break; | ||
1241 | case VIDIOCGCHAN: /* get input information */ | ||
1242 | err = v4l1_compat_get_input_info(arg, inode, file, drv); | ||
1243 | break; | ||
1244 | case VIDIOCSCHAN: /* set input */ | ||
1245 | err = v4l1_compat_set_input(arg, inode, file, drv); | ||
1246 | break; | ||
1247 | case VIDIOCGPICT: /* get tone controls & partial capture format */ | ||
1248 | err = v4l1_compat_get_picture(arg, inode, file, drv); | ||
1249 | break; | ||
1250 | case VIDIOCSPICT: /* set tone controls & partial capture format */ | ||
1251 | err = v4l1_compat_set_picture(arg, inode, file, drv); | ||
1252 | break; | ||
1253 | case VIDIOCGTUNER: /* get tuner information */ | ||
1254 | err = v4l1_compat_get_tuner(arg, inode, file, drv); | ||
1255 | break; | ||
1256 | case VIDIOCSTUNER: /* select a tuner input */ | ||
1257 | err = v4l1_compat_select_tuner(arg, inode, file, drv); | ||
1258 | break; | ||
1259 | case VIDIOCGFREQ: /* get frequency */ | ||
1260 | err = v4l1_compat_get_frequency(arg, inode, file, drv); | ||
1261 | break; | ||
1262 | case VIDIOCSFREQ: /* set frequency */ | ||
1263 | err = v4l1_compat_set_frequency(arg, inode, file, drv); | ||
1264 | break; | ||
1265 | case VIDIOCGAUDIO: /* get audio properties/controls */ | ||
1266 | err = v4l1_compat_get_audio(arg, inode, file, drv); | ||
1267 | break; | ||
1268 | case VIDIOCSAUDIO: /* set audio controls */ | ||
1269 | err = v4l1_compat_set_audio(arg, inode, file, drv); | ||
1270 | break; | ||
1271 | case VIDIOCMCAPTURE: /* capture a frame */ | ||
1272 | err = v4l1_compat_capture_frame(arg, inode, file, drv); | ||
1273 | break; | ||
1274 | case VIDIOCSYNC: /* wait for a frame */ | ||
1275 | err = v4l1_compat_sync(arg, inode, file, drv); | ||
1276 | break; | ||
1277 | case VIDIOCGVBIFMT: /* query VBI data capture format */ | ||
1278 | err = v4l1_compat_get_vbi_format(arg, inode, file, drv); | ||
1279 | break; | ||
1280 | case VIDIOCSVBIFMT: | ||
1281 | err = v4l1_compat_set_vbi_format(arg, inode, file, drv); | ||
1282 | break; | ||
1087 | default: | 1283 | default: |
1088 | err = -ENOIOCTLCMD; | 1284 | err = -ENOIOCTLCMD; |
1089 | break; | 1285 | break; |
1090 | } | 1286 | } |
1091 | 1287 | ||
1092 | kfree(cap2); | ||
1093 | kfree(fmt2); | ||
1094 | return err; | 1288 | return err; |
1095 | } | 1289 | } |
1096 | |||
1097 | EXPORT_SYMBOL(v4l_compat_translate_ioctl); | 1290 | EXPORT_SYMBOL(v4l_compat_translate_ioctl); |
1098 | 1291 | ||
1099 | /* | 1292 | /* |
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index eab79ffdf56a..fc51e4918bbf 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c | |||
@@ -64,32 +64,25 @@ void *videobuf_alloc(struct videobuf_queue *q) | |||
64 | return vb; | 64 | return vb; |
65 | } | 65 | } |
66 | 66 | ||
67 | #define WAITON_CONDITION (vb->state != VIDEOBUF_ACTIVE &&\ | ||
68 | vb->state != VIDEOBUF_QUEUED) | ||
67 | int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr) | 69 | int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr) |
68 | { | 70 | { |
69 | int retval = 0; | ||
70 | DECLARE_WAITQUEUE(wait, current); | ||
71 | |||
72 | MAGIC_CHECK(vb->magic, MAGIC_BUFFER); | 71 | MAGIC_CHECK(vb->magic, MAGIC_BUFFER); |
73 | add_wait_queue(&vb->done, &wait); | 72 | |
74 | while (vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) { | 73 | if (non_blocking) { |
75 | if (non_blocking) { | 74 | if (WAITON_CONDITION) |
76 | retval = -EAGAIN; | 75 | return 0; |
77 | break; | 76 | else |
78 | } | 77 | return -EAGAIN; |
79 | set_current_state(intr ? TASK_INTERRUPTIBLE | ||
80 | : TASK_UNINTERRUPTIBLE); | ||
81 | if (vb->state == VIDEOBUF_ACTIVE || | ||
82 | vb->state == VIDEOBUF_QUEUED) | ||
83 | schedule(); | ||
84 | set_current_state(TASK_RUNNING); | ||
85 | if (intr && signal_pending(current)) { | ||
86 | dprintk(1, "buffer waiton: -EINTR\n"); | ||
87 | retval = -EINTR; | ||
88 | break; | ||
89 | } | ||
90 | } | 78 | } |
91 | remove_wait_queue(&vb->done, &wait); | 79 | |
92 | return retval; | 80 | if (intr) |
81 | return wait_event_interruptible(vb->done, WAITON_CONDITION); | ||
82 | else | ||
83 | wait_event(vb->done, WAITON_CONDITION); | ||
84 | |||
85 | return 0; | ||
93 | } | 86 | } |
94 | 87 | ||
95 | int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, | 88 | int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, |
@@ -98,29 +91,22 @@ int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
98 | MAGIC_CHECK(vb->magic, MAGIC_BUFFER); | 91 | MAGIC_CHECK(vb->magic, MAGIC_BUFFER); |
99 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | 92 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); |
100 | 93 | ||
101 | /* This is required to avoid OOPS on some cases, | ||
102 | since mmap_mapper() method should be called before _iolock. | ||
103 | On some cases, the mmap_mapper() is called only after scheduling. | ||
104 | */ | ||
105 | if (vb->memory == V4L2_MEMORY_MMAP) { | ||
106 | wait_event_timeout(vb->done, q->is_mmapped, | ||
107 | msecs_to_jiffies(100)); | ||
108 | if (!q->is_mmapped) { | ||
109 | printk(KERN_ERR | ||
110 | "Error: mmap_mapper() never called!\n"); | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | return CALL(q, iolock, q, vb, fbuf); | 94 | return CALL(q, iolock, q, vb, fbuf); |
116 | } | 95 | } |
117 | 96 | ||
97 | void *videobuf_queue_to_vmalloc (struct videobuf_queue *q, | ||
98 | struct videobuf_buffer *buf) | ||
99 | { | ||
100 | return CALL(q, vmalloc, buf); | ||
101 | } | ||
102 | EXPORT_SYMBOL_GPL(videobuf_queue_to_vmalloc); | ||
103 | |||
118 | /* --------------------------------------------------------------------- */ | 104 | /* --------------------------------------------------------------------- */ |
119 | 105 | ||
120 | 106 | ||
121 | void videobuf_queue_core_init(struct videobuf_queue *q, | 107 | void videobuf_queue_core_init(struct videobuf_queue *q, |
122 | struct videobuf_queue_ops *ops, | 108 | struct videobuf_queue_ops *ops, |
123 | void *dev, | 109 | struct device *dev, |
124 | spinlock_t *irqlock, | 110 | spinlock_t *irqlock, |
125 | enum v4l2_buf_type type, | 111 | enum v4l2_buf_type type, |
126 | enum v4l2_field field, | 112 | enum v4l2_field field, |
@@ -144,10 +130,14 @@ void videobuf_queue_core_init(struct videobuf_queue *q, | |||
144 | BUG_ON(!q->ops->buf_queue); | 130 | BUG_ON(!q->ops->buf_queue); |
145 | BUG_ON(!q->ops->buf_release); | 131 | BUG_ON(!q->ops->buf_release); |
146 | 132 | ||
133 | /* Lock is mandatory for queue_cancel to work */ | ||
134 | BUG_ON(!irqlock); | ||
135 | |||
147 | /* Having implementations for abstract methods are mandatory */ | 136 | /* Having implementations for abstract methods are mandatory */ |
148 | BUG_ON(!q->int_ops); | 137 | BUG_ON(!q->int_ops); |
149 | 138 | ||
150 | mutex_init(&q->vb_lock); | 139 | mutex_init(&q->vb_lock); |
140 | init_waitqueue_head(&q->wait); | ||
151 | INIT_LIST_HEAD(&q->stream); | 141 | INIT_LIST_HEAD(&q->stream); |
152 | } | 142 | } |
153 | 143 | ||
@@ -195,19 +185,22 @@ void videobuf_queue_cancel(struct videobuf_queue *q) | |||
195 | unsigned long flags = 0; | 185 | unsigned long flags = 0; |
196 | int i; | 186 | int i; |
197 | 187 | ||
188 | q->streaming = 0; | ||
189 | q->reading = 0; | ||
190 | wake_up_interruptible_sync(&q->wait); | ||
191 | |||
198 | /* remove queued buffers from list */ | 192 | /* remove queued buffers from list */ |
199 | if (q->irqlock) | 193 | spin_lock_irqsave(q->irqlock, flags); |
200 | spin_lock_irqsave(q->irqlock, flags); | ||
201 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | 194 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
202 | if (NULL == q->bufs[i]) | 195 | if (NULL == q->bufs[i]) |
203 | continue; | 196 | continue; |
204 | if (q->bufs[i]->state == VIDEOBUF_QUEUED) { | 197 | if (q->bufs[i]->state == VIDEOBUF_QUEUED) { |
205 | list_del(&q->bufs[i]->queue); | 198 | list_del(&q->bufs[i]->queue); |
206 | q->bufs[i]->state = VIDEOBUF_ERROR; | 199 | q->bufs[i]->state = VIDEOBUF_ERROR; |
200 | wake_up_all(&q->bufs[i]->done); | ||
207 | } | 201 | } |
208 | } | 202 | } |
209 | if (q->irqlock) | 203 | spin_unlock_irqrestore(q->irqlock, flags); |
210 | spin_unlock_irqrestore(q->irqlock, flags); | ||
211 | 204 | ||
212 | /* free all buffers + clear queue */ | 205 | /* free all buffers + clear queue */ |
213 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | 206 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
@@ -563,14 +556,13 @@ int videobuf_qbuf(struct videobuf_queue *q, | |||
563 | 556 | ||
564 | list_add_tail(&buf->stream, &q->stream); | 557 | list_add_tail(&buf->stream, &q->stream); |
565 | if (q->streaming) { | 558 | if (q->streaming) { |
566 | if (q->irqlock) | 559 | spin_lock_irqsave(q->irqlock, flags); |
567 | spin_lock_irqsave(q->irqlock, flags); | ||
568 | q->ops->buf_queue(q, buf); | 560 | q->ops->buf_queue(q, buf); |
569 | if (q->irqlock) | 561 | spin_unlock_irqrestore(q->irqlock, flags); |
570 | spin_unlock_irqrestore(q->irqlock, flags); | ||
571 | } | 562 | } |
572 | dprintk(1, "qbuf: succeded\n"); | 563 | dprintk(1, "qbuf: succeded\n"); |
573 | retval = 0; | 564 | retval = 0; |
565 | wake_up_interruptible_sync(&q->wait); | ||
574 | 566 | ||
575 | done: | 567 | done: |
576 | mutex_unlock(&q->vb_lock); | 568 | mutex_unlock(&q->vb_lock); |
@@ -581,35 +573,88 @@ int videobuf_qbuf(struct videobuf_queue *q, | |||
581 | return retval; | 573 | return retval; |
582 | } | 574 | } |
583 | 575 | ||
584 | int videobuf_dqbuf(struct videobuf_queue *q, | 576 | |
585 | struct v4l2_buffer *b, int nonblocking) | 577 | /* Locking: Caller holds q->vb_lock */ |
578 | static int stream_next_buffer_check_queue(struct videobuf_queue *q, int noblock) | ||
586 | { | 579 | { |
587 | struct videobuf_buffer *buf; | ||
588 | int retval; | 580 | int retval; |
589 | 581 | ||
590 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | 582 | checks: |
591 | 583 | if (!q->streaming) { | |
592 | mutex_lock(&q->vb_lock); | 584 | dprintk(1, "next_buffer: Not streaming\n"); |
593 | retval = -EBUSY; | 585 | retval = -EINVAL; |
594 | if (q->reading) { | ||
595 | dprintk(1, "dqbuf: Reading running...\n"); | ||
596 | goto done; | ||
597 | } | ||
598 | retval = -EINVAL; | ||
599 | if (b->type != q->type) { | ||
600 | dprintk(1, "dqbuf: Wrong type.\n"); | ||
601 | goto done; | 586 | goto done; |
602 | } | 587 | } |
588 | |||
603 | if (list_empty(&q->stream)) { | 589 | if (list_empty(&q->stream)) { |
604 | dprintk(1, "dqbuf: stream running\n"); | 590 | if (noblock) { |
605 | goto done; | 591 | retval = -EAGAIN; |
592 | dprintk(2, "next_buffer: no buffers to dequeue\n"); | ||
593 | goto done; | ||
594 | } else { | ||
595 | dprintk(2, "next_buffer: waiting on buffer\n"); | ||
596 | |||
597 | /* Drop lock to avoid deadlock with qbuf */ | ||
598 | mutex_unlock(&q->vb_lock); | ||
599 | |||
600 | /* Checking list_empty and streaming is safe without | ||
601 | * locks because we goto checks to validate while | ||
602 | * holding locks before proceeding */ | ||
603 | retval = wait_event_interruptible(q->wait, | ||
604 | !list_empty(&q->stream) || !q->streaming); | ||
605 | mutex_lock(&q->vb_lock); | ||
606 | |||
607 | if (retval) | ||
608 | goto done; | ||
609 | |||
610 | goto checks; | ||
611 | } | ||
606 | } | 612 | } |
613 | |||
614 | retval = 0; | ||
615 | |||
616 | done: | ||
617 | return retval; | ||
618 | } | ||
619 | |||
620 | |||
621 | /* Locking: Caller holds q->vb_lock */ | ||
622 | static int stream_next_buffer(struct videobuf_queue *q, | ||
623 | struct videobuf_buffer **vb, int nonblocking) | ||
624 | { | ||
625 | int retval; | ||
626 | struct videobuf_buffer *buf = NULL; | ||
627 | |||
628 | retval = stream_next_buffer_check_queue(q, nonblocking); | ||
629 | if (retval) | ||
630 | goto done; | ||
631 | |||
607 | buf = list_entry(q->stream.next, struct videobuf_buffer, stream); | 632 | buf = list_entry(q->stream.next, struct videobuf_buffer, stream); |
608 | retval = videobuf_waiton(buf, nonblocking, 1); | 633 | retval = videobuf_waiton(buf, nonblocking, 1); |
634 | if (retval < 0) | ||
635 | goto done; | ||
636 | |||
637 | *vb = buf; | ||
638 | done: | ||
639 | return retval; | ||
640 | } | ||
641 | |||
642 | int videobuf_dqbuf(struct videobuf_queue *q, | ||
643 | struct v4l2_buffer *b, int nonblocking) | ||
644 | { | ||
645 | struct videobuf_buffer *buf = NULL; | ||
646 | int retval; | ||
647 | |||
648 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | ||
649 | |||
650 | mutex_lock(&q->vb_lock); | ||
651 | |||
652 | retval = stream_next_buffer(q, &buf, nonblocking); | ||
609 | if (retval < 0) { | 653 | if (retval < 0) { |
610 | dprintk(1, "dqbuf: waiton returned %d\n", retval); | 654 | dprintk(1, "dqbuf: next_buffer error: %i\n", retval); |
611 | goto done; | 655 | goto done; |
612 | } | 656 | } |
657 | |||
613 | switch (buf->state) { | 658 | switch (buf->state) { |
614 | case VIDEOBUF_ERROR: | 659 | case VIDEOBUF_ERROR: |
615 | dprintk(1, "dqbuf: state is error\n"); | 660 | dprintk(1, "dqbuf: state is error\n"); |
@@ -650,14 +695,13 @@ int videobuf_streamon(struct videobuf_queue *q) | |||
650 | if (q->streaming) | 695 | if (q->streaming) |
651 | goto done; | 696 | goto done; |
652 | q->streaming = 1; | 697 | q->streaming = 1; |
653 | if (q->irqlock) | 698 | spin_lock_irqsave(q->irqlock, flags); |
654 | spin_lock_irqsave(q->irqlock, flags); | ||
655 | list_for_each_entry(buf, &q->stream, stream) | 699 | list_for_each_entry(buf, &q->stream, stream) |
656 | if (buf->state == VIDEOBUF_PREPARED) | 700 | if (buf->state == VIDEOBUF_PREPARED) |
657 | q->ops->buf_queue(q, buf); | 701 | q->ops->buf_queue(q, buf); |
658 | if (q->irqlock) | 702 | spin_unlock_irqrestore(q->irqlock, flags); |
659 | spin_unlock_irqrestore(q->irqlock, flags); | ||
660 | 703 | ||
704 | wake_up_interruptible_sync(&q->wait); | ||
661 | done: | 705 | done: |
662 | mutex_unlock(&q->vb_lock); | 706 | mutex_unlock(&q->vb_lock); |
663 | return retval; | 707 | return retval; |
@@ -670,7 +714,6 @@ static int __videobuf_streamoff(struct videobuf_queue *q) | |||
670 | return -EINVAL; | 714 | return -EINVAL; |
671 | 715 | ||
672 | videobuf_queue_cancel(q); | 716 | videobuf_queue_cancel(q); |
673 | q->streaming = 0; | ||
674 | 717 | ||
675 | return 0; | 718 | return 0; |
676 | } | 719 | } |
@@ -712,11 +755,9 @@ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q, | |||
712 | goto done; | 755 | goto done; |
713 | 756 | ||
714 | /* start capture & wait */ | 757 | /* start capture & wait */ |
715 | if (q->irqlock) | 758 | spin_lock_irqsave(q->irqlock, flags); |
716 | spin_lock_irqsave(q->irqlock, flags); | ||
717 | q->ops->buf_queue(q, q->read_buf); | 759 | q->ops->buf_queue(q, q->read_buf); |
718 | if (q->irqlock) | 760 | spin_unlock_irqrestore(q->irqlock, flags); |
719 | spin_unlock_irqrestore(q->irqlock, flags); | ||
720 | retval = videobuf_waiton(q->read_buf, 0, 0); | 761 | retval = videobuf_waiton(q->read_buf, 0, 0); |
721 | if (0 == retval) { | 762 | if (0 == retval) { |
722 | CALL(q, sync, q, q->read_buf); | 763 | CALL(q, sync, q, q->read_buf); |
@@ -740,14 +781,13 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, | |||
740 | { | 781 | { |
741 | enum v4l2_field field; | 782 | enum v4l2_field field; |
742 | unsigned long flags = 0; | 783 | unsigned long flags = 0; |
743 | unsigned size, nbufs; | 784 | unsigned size = 0, nbufs = 1; |
744 | int retval; | 785 | int retval; |
745 | 786 | ||
746 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | 787 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); |
747 | 788 | ||
748 | mutex_lock(&q->vb_lock); | 789 | mutex_lock(&q->vb_lock); |
749 | 790 | ||
750 | nbufs = 1; size = 0; | ||
751 | q->ops->buf_setup(q, &nbufs, &size); | 791 | q->ops->buf_setup(q, &nbufs, &size); |
752 | 792 | ||
753 | if (NULL == q->read_buf && | 793 | if (NULL == q->read_buf && |
@@ -778,12 +818,11 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, | |||
778 | q->read_buf = NULL; | 818 | q->read_buf = NULL; |
779 | goto done; | 819 | goto done; |
780 | } | 820 | } |
781 | if (q->irqlock) | ||
782 | spin_lock_irqsave(q->irqlock, flags); | ||
783 | 821 | ||
822 | spin_lock_irqsave(q->irqlock, flags); | ||
784 | q->ops->buf_queue(q, q->read_buf); | 823 | q->ops->buf_queue(q, q->read_buf); |
785 | if (q->irqlock) | 824 | spin_unlock_irqrestore(q->irqlock, flags); |
786 | spin_unlock_irqrestore(q->irqlock, flags); | 825 | |
787 | q->read_off = 0; | 826 | q->read_off = 0; |
788 | } | 827 | } |
789 | 828 | ||
@@ -849,12 +888,10 @@ static int __videobuf_read_start(struct videobuf_queue *q) | |||
849 | return err; | 888 | return err; |
850 | list_add_tail(&q->bufs[i]->stream, &q->stream); | 889 | list_add_tail(&q->bufs[i]->stream, &q->stream); |
851 | } | 890 | } |
852 | if (q->irqlock) | 891 | spin_lock_irqsave(q->irqlock, flags); |
853 | spin_lock_irqsave(q->irqlock, flags); | ||
854 | for (i = 0; i < count; i++) | 892 | for (i = 0; i < count; i++) |
855 | q->ops->buf_queue(q, q->bufs[i]); | 893 | q->ops->buf_queue(q, q->bufs[i]); |
856 | if (q->irqlock) | 894 | spin_unlock_irqrestore(q->irqlock, flags); |
857 | spin_unlock_irqrestore(q->irqlock, flags); | ||
858 | q->reading = 1; | 895 | q->reading = 1; |
859 | return 0; | 896 | return 0; |
860 | } | 897 | } |
@@ -863,7 +900,6 @@ static void __videobuf_read_stop(struct videobuf_queue *q) | |||
863 | { | 900 | { |
864 | int i; | 901 | int i; |
865 | 902 | ||
866 | |||
867 | videobuf_queue_cancel(q); | 903 | videobuf_queue_cancel(q); |
868 | __videobuf_mmap_free(q); | 904 | __videobuf_mmap_free(q); |
869 | INIT_LIST_HEAD(&q->stream); | 905 | INIT_LIST_HEAD(&q->stream); |
@@ -874,7 +910,6 @@ static void __videobuf_read_stop(struct videobuf_queue *q) | |||
874 | q->bufs[i] = NULL; | 910 | q->bufs[i] = NULL; |
875 | } | 911 | } |
876 | q->read_buf = NULL; | 912 | q->read_buf = NULL; |
877 | q->reading = 0; | ||
878 | 913 | ||
879 | } | 914 | } |
880 | 915 | ||
@@ -919,7 +954,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, | |||
919 | 954 | ||
920 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | 955 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); |
921 | 956 | ||
922 | dprintk(2, "%s\n", __FUNCTION__); | 957 | dprintk(2, "%s\n", __func__); |
923 | mutex_lock(&q->vb_lock); | 958 | mutex_lock(&q->vb_lock); |
924 | retval = -EBUSY; | 959 | retval = -EBUSY; |
925 | if (q->streaming) | 960 | if (q->streaming) |
@@ -968,11 +1003,9 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, | |||
968 | if (q->read_off == q->read_buf->size) { | 1003 | if (q->read_off == q->read_buf->size) { |
969 | list_add_tail(&q->read_buf->stream, | 1004 | list_add_tail(&q->read_buf->stream, |
970 | &q->stream); | 1005 | &q->stream); |
971 | if (q->irqlock) | 1006 | spin_lock_irqsave(q->irqlock, flags); |
972 | spin_lock_irqsave(q->irqlock, flags); | ||
973 | q->ops->buf_queue(q, q->read_buf); | 1007 | q->ops->buf_queue(q, q->read_buf); |
974 | if (q->irqlock) | 1008 | spin_unlock_irqrestore(q->irqlock, flags); |
975 | spin_unlock_irqrestore(q->irqlock, flags); | ||
976 | q->read_buf = NULL; | 1009 | q->read_buf = NULL; |
977 | } | 1010 | } |
978 | if (retval < 0) | 1011 | if (retval < 0) |
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 53fed4b74ce9..03a7b946bd54 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * helper functions for PCI DMA video4linux capture buffers | 2 | * helper functions for SG DMA video4linux capture buffers |
3 | * | 3 | * |
4 | * The functions expect the hardware being able to scatter gatter | 4 | * The functions expect the hardware being able to scatter gatter |
5 | * (i.e. the buffers are not linear in physical memory, but fragmented | 5 | * (i.e. the buffers are not linear in physical memory, but fragmented |
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | 26 | ||
27 | #include <linux/pci.h> | 27 | #include <linux/dma-mapping.h> |
28 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
29 | #include <linux/pagemap.h> | 29 | #include <linux/pagemap.h> |
30 | #include <linux/scatterlist.h> | 30 | #include <linux/scatterlist.h> |
@@ -39,10 +39,10 @@ | |||
39 | #define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \ | 39 | #define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \ |
40 | { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); } | 40 | { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); } |
41 | 41 | ||
42 | static int debug = 0; | 42 | static int debug; |
43 | module_param(debug, int, 0644); | 43 | module_param(debug, int, 0644); |
44 | 44 | ||
45 | MODULE_DESCRIPTION("helper module to manage video4linux pci dma sg buffers"); | 45 | MODULE_DESCRIPTION("helper module to manage video4linux dma sg buffers"); |
46 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 46 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); |
47 | MODULE_LICENSE("GPL"); | 47 | MODULE_LICENSE("GPL"); |
48 | 48 | ||
@@ -119,10 +119,10 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset) | |||
119 | 119 | ||
120 | struct videobuf_dmabuf *videobuf_to_dma (struct videobuf_buffer *buf) | 120 | struct videobuf_dmabuf *videobuf_to_dma (struct videobuf_buffer *buf) |
121 | { | 121 | { |
122 | struct videbuf_pci_sg_memory *mem=buf->priv; | 122 | struct videobuf_dma_sg_memory *mem = buf->priv; |
123 | BUG_ON (!mem); | 123 | BUG_ON(!mem); |
124 | 124 | ||
125 | MAGIC_CHECK(mem->magic,MAGIC_SG_MEM); | 125 | MAGIC_CHECK(mem->magic, MAGIC_SG_MEM); |
126 | 126 | ||
127 | return &mem->dma; | 127 | return &mem->dma; |
128 | } | 128 | } |
@@ -141,9 +141,14 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, | |||
141 | 141 | ||
142 | dma->direction = direction; | 142 | dma->direction = direction; |
143 | switch (dma->direction) { | 143 | switch (dma->direction) { |
144 | case PCI_DMA_FROMDEVICE: rw = READ; break; | 144 | case DMA_FROM_DEVICE: |
145 | case PCI_DMA_TODEVICE: rw = WRITE; break; | 145 | rw = READ; |
146 | default: BUG(); | 146 | break; |
147 | case DMA_TO_DEVICE: | ||
148 | rw = WRITE; | ||
149 | break; | ||
150 | default: | ||
151 | BUG(); | ||
147 | } | 152 | } |
148 | 153 | ||
149 | first = (data & PAGE_MASK) >> PAGE_SHIFT; | 154 | first = (data & PAGE_MASK) >> PAGE_SHIFT; |
@@ -157,9 +162,6 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, | |||
157 | dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n", | 162 | dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n", |
158 | data,size,dma->nr_pages); | 163 | data,size,dma->nr_pages); |
159 | 164 | ||
160 | dma->varea = (void *) data; | ||
161 | |||
162 | |||
163 | err = get_user_pages(current,current->mm, | 165 | err = get_user_pages(current,current->mm, |
164 | data & PAGE_MASK, dma->nr_pages, | 166 | data & PAGE_MASK, dma->nr_pages, |
165 | rw == READ, 1, /* force */ | 167 | rw == READ, 1, /* force */ |
@@ -216,10 +218,8 @@ int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction, | |||
216 | return 0; | 218 | return 0; |
217 | } | 219 | } |
218 | 220 | ||
219 | int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma) | 221 | int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma) |
220 | { | 222 | { |
221 | void *dev=q->dev; | ||
222 | |||
223 | MAGIC_CHECK(dma->magic,MAGIC_DMABUF); | 223 | MAGIC_CHECK(dma->magic,MAGIC_DMABUF); |
224 | BUG_ON(0 == dma->nr_pages); | 224 | BUG_ON(0 == dma->nr_pages); |
225 | 225 | ||
@@ -245,11 +245,11 @@ int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma) | |||
245 | return -ENOMEM; | 245 | return -ENOMEM; |
246 | } | 246 | } |
247 | if (!dma->bus_addr) { | 247 | if (!dma->bus_addr) { |
248 | dma->sglen = pci_map_sg(dev,dma->sglist, | 248 | dma->sglen = dma_map_sg(q->dev, dma->sglist, |
249 | dma->nr_pages, dma->direction); | 249 | dma->nr_pages, dma->direction); |
250 | if (0 == dma->sglen) { | 250 | if (0 == dma->sglen) { |
251 | printk(KERN_WARNING | 251 | printk(KERN_WARNING |
252 | "%s: videobuf_map_sg failed\n",__FUNCTION__); | 252 | "%s: videobuf_map_sg failed\n",__func__); |
253 | kfree(dma->sglist); | 253 | kfree(dma->sglist); |
254 | dma->sglist = NULL; | 254 | dma->sglist = NULL; |
255 | dma->sglen = 0; | 255 | dma->sglen = 0; |
@@ -259,26 +259,22 @@ int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma) | |||
259 | return 0; | 259 | return 0; |
260 | } | 260 | } |
261 | 261 | ||
262 | int videobuf_dma_sync(struct videobuf_queue *q,struct videobuf_dmabuf *dma) | 262 | int videobuf_dma_sync(struct videobuf_queue *q, struct videobuf_dmabuf *dma) |
263 | { | 263 | { |
264 | void *dev=q->dev; | 264 | MAGIC_CHECK(dma->magic, MAGIC_DMABUF); |
265 | |||
266 | MAGIC_CHECK(dma->magic,MAGIC_DMABUF); | ||
267 | BUG_ON(!dma->sglen); | 265 | BUG_ON(!dma->sglen); |
268 | 266 | ||
269 | pci_dma_sync_sg_for_cpu (dev,dma->sglist,dma->nr_pages,dma->direction); | 267 | dma_sync_sg_for_cpu(q->dev, dma->sglist, dma->nr_pages, dma->direction); |
270 | return 0; | 268 | return 0; |
271 | } | 269 | } |
272 | 270 | ||
273 | int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma) | 271 | int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma) |
274 | { | 272 | { |
275 | void *dev=q->dev; | 273 | MAGIC_CHECK(dma->magic, MAGIC_DMABUF); |
276 | |||
277 | MAGIC_CHECK(dma->magic,MAGIC_DMABUF); | ||
278 | if (!dma->sglen) | 274 | if (!dma->sglen) |
279 | return 0; | 275 | return 0; |
280 | 276 | ||
281 | pci_unmap_sg (dev,dma->sglist,dma->nr_pages,dma->direction); | 277 | dma_unmap_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction); |
282 | 278 | ||
283 | kfree(dma->sglist); | 279 | kfree(dma->sglist); |
284 | dma->sglist = NULL; | 280 | dma->sglist = NULL; |
@@ -301,33 +297,32 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma) | |||
301 | 297 | ||
302 | vfree(dma->vmalloc); | 298 | vfree(dma->vmalloc); |
303 | dma->vmalloc = NULL; | 299 | dma->vmalloc = NULL; |
304 | dma->varea = NULL; | ||
305 | 300 | ||
306 | if (dma->bus_addr) { | 301 | if (dma->bus_addr) { |
307 | dma->bus_addr = 0; | 302 | dma->bus_addr = 0; |
308 | } | 303 | } |
309 | dma->direction = PCI_DMA_NONE; | 304 | dma->direction = DMA_NONE; |
310 | return 0; | 305 | return 0; |
311 | } | 306 | } |
312 | 307 | ||
313 | /* --------------------------------------------------------------------- */ | 308 | /* --------------------------------------------------------------------- */ |
314 | 309 | ||
315 | int videobuf_pci_dma_map(struct pci_dev *pci,struct videobuf_dmabuf *dma) | 310 | int videobuf_sg_dma_map(struct device *dev, struct videobuf_dmabuf *dma) |
316 | { | 311 | { |
317 | struct videobuf_queue q; | 312 | struct videobuf_queue q; |
318 | 313 | ||
319 | q.dev=pci; | 314 | q.dev = dev; |
320 | 315 | ||
321 | return (videobuf_dma_map(&q,dma)); | 316 | return videobuf_dma_map(&q, dma); |
322 | } | 317 | } |
323 | 318 | ||
324 | int videobuf_pci_dma_unmap(struct pci_dev *pci,struct videobuf_dmabuf *dma) | 319 | int videobuf_sg_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma) |
325 | { | 320 | { |
326 | struct videobuf_queue q; | 321 | struct videobuf_queue q; |
327 | 322 | ||
328 | q.dev=pci; | 323 | q.dev = dev; |
329 | 324 | ||
330 | return (videobuf_dma_unmap(&q,dma)); | 325 | return videobuf_dma_unmap(&q, dma); |
331 | } | 326 | } |
332 | 327 | ||
333 | /* --------------------------------------------------------------------- */ | 328 | /* --------------------------------------------------------------------- */ |
@@ -347,7 +342,7 @@ videobuf_vm_close(struct vm_area_struct *vma) | |||
347 | { | 342 | { |
348 | struct videobuf_mapping *map = vma->vm_private_data; | 343 | struct videobuf_mapping *map = vma->vm_private_data; |
349 | struct videobuf_queue *q = map->q; | 344 | struct videobuf_queue *q = map->q; |
350 | struct videbuf_pci_sg_memory *mem; | 345 | struct videobuf_dma_sg_memory *mem; |
351 | int i; | 346 | int i; |
352 | 347 | ||
353 | dprintk(2,"vm_close %p [count=%d,vma=%08lx-%08lx]\n",map, | 348 | dprintk(2,"vm_close %p [count=%d,vma=%08lx-%08lx]\n",map, |
@@ -409,18 +404,18 @@ static struct vm_operations_struct videobuf_vm_ops = | |||
409 | }; | 404 | }; |
410 | 405 | ||
411 | /* --------------------------------------------------------------------- | 406 | /* --------------------------------------------------------------------- |
412 | * PCI handlers for the generic methods | 407 | * SG handlers for the generic methods |
413 | */ | 408 | */ |
414 | 409 | ||
415 | /* Allocated area consists on 3 parts: | 410 | /* Allocated area consists on 3 parts: |
416 | struct video_buffer | 411 | struct video_buffer |
417 | struct <driver>_buffer (cx88_buffer, saa7134_buf, ...) | 412 | struct <driver>_buffer (cx88_buffer, saa7134_buf, ...) |
418 | struct videobuf_pci_sg_memory | 413 | struct videobuf_dma_sg_memory |
419 | */ | 414 | */ |
420 | 415 | ||
421 | static void *__videobuf_alloc(size_t size) | 416 | static void *__videobuf_alloc(size_t size) |
422 | { | 417 | { |
423 | struct videbuf_pci_sg_memory *mem; | 418 | struct videobuf_dma_sg_memory *mem; |
424 | struct videobuf_buffer *vb; | 419 | struct videobuf_buffer *vb; |
425 | 420 | ||
426 | vb = kzalloc(size+sizeof(*mem),GFP_KERNEL); | 421 | vb = kzalloc(size+sizeof(*mem),GFP_KERNEL); |
@@ -431,22 +426,32 @@ static void *__videobuf_alloc(size_t size) | |||
431 | videobuf_dma_init(&mem->dma); | 426 | videobuf_dma_init(&mem->dma); |
432 | 427 | ||
433 | dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n", | 428 | dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n", |
434 | __FUNCTION__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb), | 429 | __func__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb), |
435 | mem,(long)sizeof(*mem)); | 430 | mem,(long)sizeof(*mem)); |
436 | 431 | ||
437 | return vb; | 432 | return vb; |
438 | } | 433 | } |
439 | 434 | ||
435 | static void *__videobuf_to_vmalloc (struct videobuf_buffer *buf) | ||
436 | { | ||
437 | struct videobuf_dma_sg_memory *mem = buf->priv; | ||
438 | BUG_ON(!mem); | ||
439 | |||
440 | MAGIC_CHECK(mem->magic, MAGIC_SG_MEM); | ||
441 | |||
442 | return mem->dma.vmalloc; | ||
443 | } | ||
444 | |||
440 | static int __videobuf_iolock (struct videobuf_queue* q, | 445 | static int __videobuf_iolock (struct videobuf_queue* q, |
441 | struct videobuf_buffer *vb, | 446 | struct videobuf_buffer *vb, |
442 | struct v4l2_framebuffer *fbuf) | 447 | struct v4l2_framebuffer *fbuf) |
443 | { | 448 | { |
444 | int err,pages; | 449 | int err,pages; |
445 | dma_addr_t bus; | 450 | dma_addr_t bus; |
446 | struct videbuf_pci_sg_memory *mem=vb->priv; | 451 | struct videobuf_dma_sg_memory *mem = vb->priv; |
447 | BUG_ON(!mem); | 452 | BUG_ON(!mem); |
448 | 453 | ||
449 | MAGIC_CHECK(mem->magic,MAGIC_SG_MEM); | 454 | MAGIC_CHECK(mem->magic, MAGIC_SG_MEM); |
450 | 455 | ||
451 | switch (vb->memory) { | 456 | switch (vb->memory) { |
452 | case V4L2_MEMORY_MMAP: | 457 | case V4L2_MEMORY_MMAP: |
@@ -455,14 +460,14 @@ static int __videobuf_iolock (struct videobuf_queue* q, | |||
455 | /* no userspace addr -- kernel bounce buffer */ | 460 | /* no userspace addr -- kernel bounce buffer */ |
456 | pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT; | 461 | pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT; |
457 | err = videobuf_dma_init_kernel( &mem->dma, | 462 | err = videobuf_dma_init_kernel( &mem->dma, |
458 | PCI_DMA_FROMDEVICE, | 463 | DMA_FROM_DEVICE, |
459 | pages ); | 464 | pages ); |
460 | if (0 != err) | 465 | if (0 != err) |
461 | return err; | 466 | return err; |
462 | } else if (vb->memory == V4L2_MEMORY_USERPTR) { | 467 | } else if (vb->memory == V4L2_MEMORY_USERPTR) { |
463 | /* dma directly to userspace */ | 468 | /* dma directly to userspace */ |
464 | err = videobuf_dma_init_user( &mem->dma, | 469 | err = videobuf_dma_init_user( &mem->dma, |
465 | PCI_DMA_FROMDEVICE, | 470 | DMA_FROM_DEVICE, |
466 | vb->baddr,vb->bsize ); | 471 | vb->baddr,vb->bsize ); |
467 | if (0 != err) | 472 | if (0 != err) |
468 | return err; | 473 | return err; |
@@ -473,7 +478,7 @@ static int __videobuf_iolock (struct videobuf_queue* q, | |||
473 | locking inversion, so don't take it here */ | 478 | locking inversion, so don't take it here */ |
474 | 479 | ||
475 | err = videobuf_dma_init_user_locked(&mem->dma, | 480 | err = videobuf_dma_init_user_locked(&mem->dma, |
476 | PCI_DMA_FROMDEVICE, | 481 | DMA_FROM_DEVICE, |
477 | vb->baddr, vb->bsize); | 482 | vb->baddr, vb->bsize); |
478 | if (0 != err) | 483 | if (0 != err) |
479 | return err; | 484 | return err; |
@@ -490,7 +495,7 @@ static int __videobuf_iolock (struct videobuf_queue* q, | |||
490 | */ | 495 | */ |
491 | bus = (dma_addr_t)(unsigned long)fbuf->base + vb->boff; | 496 | bus = (dma_addr_t)(unsigned long)fbuf->base + vb->boff; |
492 | pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT; | 497 | pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT; |
493 | err = videobuf_dma_init_overlay(&mem->dma,PCI_DMA_FROMDEVICE, | 498 | err = videobuf_dma_init_overlay(&mem->dma, DMA_FROM_DEVICE, |
494 | bus, pages); | 499 | bus, pages); |
495 | if (0 != err) | 500 | if (0 != err) |
496 | return err; | 501 | return err; |
@@ -498,7 +503,7 @@ static int __videobuf_iolock (struct videobuf_queue* q, | |||
498 | default: | 503 | default: |
499 | BUG(); | 504 | BUG(); |
500 | } | 505 | } |
501 | err = videobuf_dma_map(q,&mem->dma); | 506 | err = videobuf_dma_map(q, &mem->dma); |
502 | if (0 != err) | 507 | if (0 != err) |
503 | return err; | 508 | return err; |
504 | 509 | ||
@@ -508,8 +513,8 @@ static int __videobuf_iolock (struct videobuf_queue* q, | |||
508 | static int __videobuf_sync(struct videobuf_queue *q, | 513 | static int __videobuf_sync(struct videobuf_queue *q, |
509 | struct videobuf_buffer *buf) | 514 | struct videobuf_buffer *buf) |
510 | { | 515 | { |
511 | struct videbuf_pci_sg_memory *mem=buf->priv; | 516 | struct videobuf_dma_sg_memory *mem = buf->priv; |
512 | BUG_ON (!mem); | 517 | BUG_ON(!mem); |
513 | MAGIC_CHECK(mem->magic,MAGIC_SG_MEM); | 518 | MAGIC_CHECK(mem->magic,MAGIC_SG_MEM); |
514 | 519 | ||
515 | return videobuf_dma_sync(q,&mem->dma); | 520 | return videobuf_dma_sync(q,&mem->dma); |
@@ -532,7 +537,7 @@ static int __videobuf_mmap_free(struct videobuf_queue *q) | |||
532 | static int __videobuf_mmap_mapper(struct videobuf_queue *q, | 537 | static int __videobuf_mmap_mapper(struct videobuf_queue *q, |
533 | struct vm_area_struct *vma) | 538 | struct vm_area_struct *vma) |
534 | { | 539 | { |
535 | struct videbuf_pci_sg_memory *mem; | 540 | struct videobuf_dma_sg_memory *mem; |
536 | struct videobuf_mapping *map; | 541 | struct videobuf_mapping *map; |
537 | unsigned int first,last,size,i; | 542 | unsigned int first,last,size,i; |
538 | int retval; | 543 | int retval; |
@@ -547,12 +552,20 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, | |||
547 | goto done; | 552 | goto done; |
548 | } | 553 | } |
549 | 554 | ||
555 | /* This function maintains backwards compatibility with V4L1 and will | ||
556 | * map more than one buffer if the vma length is equal to the combined | ||
557 | * size of multiple buffers than it will map them together. See | ||
558 | * VIDIOCGMBUF in the v4l spec | ||
559 | * | ||
560 | * TODO: Allow drivers to specify if they support this mode | ||
561 | */ | ||
562 | |||
550 | /* look for first buffer to map */ | 563 | /* look for first buffer to map */ |
551 | for (first = 0; first < VIDEO_MAX_FRAME; first++) { | 564 | for (first = 0; first < VIDEO_MAX_FRAME; first++) { |
552 | if (NULL == q->bufs[first]) | 565 | if (NULL == q->bufs[first]) |
553 | continue; | 566 | continue; |
554 | mem=q->bufs[first]->priv; | 567 | mem=q->bufs[first]->priv; |
555 | BUG_ON (!mem); | 568 | BUG_ON(!mem); |
556 | MAGIC_CHECK(mem->magic,MAGIC_SG_MEM); | 569 | MAGIC_CHECK(mem->magic,MAGIC_SG_MEM); |
557 | 570 | ||
558 | if (V4L2_MEMORY_MMAP != q->bufs[first]->memory) | 571 | if (V4L2_MEMORY_MMAP != q->bufs[first]->memory) |
@@ -591,10 +604,16 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, | |||
591 | map = kmalloc(sizeof(struct videobuf_mapping),GFP_KERNEL); | 604 | map = kmalloc(sizeof(struct videobuf_mapping),GFP_KERNEL); |
592 | if (NULL == map) | 605 | if (NULL == map) |
593 | goto done; | 606 | goto done; |
594 | for (size = 0, i = first; i <= last; size += q->bufs[i++]->bsize) { | 607 | |
608 | size = 0; | ||
609 | for (i = first; i <= last; i++) { | ||
610 | if (NULL == q->bufs[i]) | ||
611 | continue; | ||
595 | q->bufs[i]->map = map; | 612 | q->bufs[i]->map = map; |
596 | q->bufs[i]->baddr = vma->vm_start + size; | 613 | q->bufs[i]->baddr = vma->vm_start + size; |
614 | size += q->bufs[i]->bsize; | ||
597 | } | 615 | } |
616 | |||
598 | map->count = 1; | 617 | map->count = 1; |
599 | map->start = vma->vm_start; | 618 | map->start = vma->vm_start; |
600 | map->end = vma->vm_end; | 619 | map->end = vma->vm_end; |
@@ -615,8 +634,8 @@ static int __videobuf_copy_to_user ( struct videobuf_queue *q, | |||
615 | char __user *data, size_t count, | 634 | char __user *data, size_t count, |
616 | int nonblocking ) | 635 | int nonblocking ) |
617 | { | 636 | { |
618 | struct videbuf_pci_sg_memory *mem=q->read_buf->priv; | 637 | struct videobuf_dma_sg_memory *mem = q->read_buf->priv; |
619 | BUG_ON (!mem); | 638 | BUG_ON(!mem); |
620 | MAGIC_CHECK(mem->magic,MAGIC_SG_MEM); | 639 | MAGIC_CHECK(mem->magic,MAGIC_SG_MEM); |
621 | 640 | ||
622 | /* copy to userspace */ | 641 | /* copy to userspace */ |
@@ -634,8 +653,8 @@ static int __videobuf_copy_stream ( struct videobuf_queue *q, | |||
634 | int vbihack, int nonblocking ) | 653 | int vbihack, int nonblocking ) |
635 | { | 654 | { |
636 | unsigned int *fc; | 655 | unsigned int *fc; |
637 | struct videbuf_pci_sg_memory *mem=q->read_buf->priv; | 656 | struct videobuf_dma_sg_memory *mem = q->read_buf->priv; |
638 | BUG_ON (!mem); | 657 | BUG_ON(!mem); |
639 | MAGIC_CHECK(mem->magic,MAGIC_SG_MEM); | 658 | MAGIC_CHECK(mem->magic,MAGIC_SG_MEM); |
640 | 659 | ||
641 | if (vbihack) { | 660 | if (vbihack) { |
@@ -658,7 +677,7 @@ static int __videobuf_copy_stream ( struct videobuf_queue *q, | |||
658 | return count; | 677 | return count; |
659 | } | 678 | } |
660 | 679 | ||
661 | static struct videobuf_qtype_ops pci_ops = { | 680 | static struct videobuf_qtype_ops sg_ops = { |
662 | .magic = MAGIC_QTYPE_OPS, | 681 | .magic = MAGIC_QTYPE_OPS, |
663 | 682 | ||
664 | .alloc = __videobuf_alloc, | 683 | .alloc = __videobuf_alloc, |
@@ -668,23 +687,24 @@ static struct videobuf_qtype_ops pci_ops = { | |||
668 | .mmap_mapper = __videobuf_mmap_mapper, | 687 | .mmap_mapper = __videobuf_mmap_mapper, |
669 | .video_copy_to_user = __videobuf_copy_to_user, | 688 | .video_copy_to_user = __videobuf_copy_to_user, |
670 | .copy_stream = __videobuf_copy_stream, | 689 | .copy_stream = __videobuf_copy_stream, |
690 | .vmalloc = __videobuf_to_vmalloc, | ||
671 | }; | 691 | }; |
672 | 692 | ||
673 | void *videobuf_pci_alloc (size_t size) | 693 | void *videobuf_sg_alloc(size_t size) |
674 | { | 694 | { |
675 | struct videobuf_queue q; | 695 | struct videobuf_queue q; |
676 | 696 | ||
677 | /* Required to make generic handler to call __videobuf_alloc */ | 697 | /* Required to make generic handler to call __videobuf_alloc */ |
678 | q.int_ops=&pci_ops; | 698 | q.int_ops = &sg_ops; |
679 | 699 | ||
680 | q.msize=size; | 700 | q.msize = size; |
681 | 701 | ||
682 | return videobuf_alloc (&q); | 702 | return videobuf_alloc(&q); |
683 | } | 703 | } |
684 | 704 | ||
685 | void videobuf_queue_pci_init(struct videobuf_queue* q, | 705 | void videobuf_queue_sg_init(struct videobuf_queue* q, |
686 | struct videobuf_queue_ops *ops, | 706 | struct videobuf_queue_ops *ops, |
687 | void *dev, | 707 | struct device *dev, |
688 | spinlock_t *irqlock, | 708 | spinlock_t *irqlock, |
689 | enum v4l2_buf_type type, | 709 | enum v4l2_buf_type type, |
690 | enum v4l2_field field, | 710 | enum v4l2_field field, |
@@ -692,7 +712,7 @@ void videobuf_queue_pci_init(struct videobuf_queue* q, | |||
692 | void *priv) | 712 | void *priv) |
693 | { | 713 | { |
694 | videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, | 714 | videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, |
695 | priv, &pci_ops); | 715 | priv, &sg_ops); |
696 | } | 716 | } |
697 | 717 | ||
698 | /* --------------------------------------------------------------------- */ | 718 | /* --------------------------------------------------------------------- */ |
@@ -709,11 +729,11 @@ EXPORT_SYMBOL_GPL(videobuf_dma_sync); | |||
709 | EXPORT_SYMBOL_GPL(videobuf_dma_unmap); | 729 | EXPORT_SYMBOL_GPL(videobuf_dma_unmap); |
710 | EXPORT_SYMBOL_GPL(videobuf_dma_free); | 730 | EXPORT_SYMBOL_GPL(videobuf_dma_free); |
711 | 731 | ||
712 | EXPORT_SYMBOL_GPL(videobuf_pci_dma_map); | 732 | EXPORT_SYMBOL_GPL(videobuf_sg_dma_map); |
713 | EXPORT_SYMBOL_GPL(videobuf_pci_dma_unmap); | 733 | EXPORT_SYMBOL_GPL(videobuf_sg_dma_unmap); |
714 | EXPORT_SYMBOL_GPL(videobuf_pci_alloc); | 734 | EXPORT_SYMBOL_GPL(videobuf_sg_alloc); |
715 | 735 | ||
716 | EXPORT_SYMBOL_GPL(videobuf_queue_pci_init); | 736 | EXPORT_SYMBOL_GPL(videobuf_queue_sg_init); |
717 | 737 | ||
718 | /* | 738 | /* |
719 | * Local variables: | 739 | * Local variables: |
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c index b73aba65d21d..6e4d73ec6855 100644 --- a/drivers/media/video/videobuf-dvb.c +++ b/drivers/media/video/videobuf-dvb.c | |||
@@ -20,9 +20,10 @@ | |||
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <linux/kthread.h> | 21 | #include <linux/kthread.h> |
22 | #include <linux/file.h> | 22 | #include <linux/file.h> |
23 | |||
23 | #include <linux/freezer.h> | 24 | #include <linux/freezer.h> |
24 | 25 | ||
25 | #include <media/videobuf-dma-sg.h> | 26 | #include <media/videobuf-core.h> |
26 | #include <media/videobuf-dvb.h> | 27 | #include <media/videobuf-dvb.h> |
27 | 28 | ||
28 | /* ------------------------------------------------------------------ */ | 29 | /* ------------------------------------------------------------------ */ |
@@ -30,7 +31,7 @@ | |||
30 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 31 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
31 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
32 | 33 | ||
33 | static unsigned int debug = 0; | 34 | static unsigned int debug; |
34 | module_param(debug, int, 0644); | 35 | module_param(debug, int, 0644); |
35 | MODULE_PARM_DESC(debug,"enable debug messages"); | 36 | MODULE_PARM_DESC(debug,"enable debug messages"); |
36 | 37 | ||
@@ -45,7 +46,7 @@ static int videobuf_dvb_thread(void *data) | |||
45 | struct videobuf_buffer *buf; | 46 | struct videobuf_buffer *buf; |
46 | unsigned long flags; | 47 | unsigned long flags; |
47 | int err; | 48 | int err; |
48 | struct videobuf_dmabuf *dma; | 49 | void *outp; |
49 | 50 | ||
50 | dprintk("dvb thread started\n"); | 51 | dprintk("dvb thread started\n"); |
51 | set_freezable(); | 52 | set_freezable(); |
@@ -66,9 +67,10 @@ static int videobuf_dvb_thread(void *data) | |||
66 | try_to_freeze(); | 67 | try_to_freeze(); |
67 | 68 | ||
68 | /* feed buffer data to demux */ | 69 | /* feed buffer data to demux */ |
69 | dma=videobuf_to_dma(buf); | 70 | outp = videobuf_queue_to_vmalloc (&dvb->dvbq, buf); |
71 | |||
70 | if (buf->state == VIDEOBUF_DONE) | 72 | if (buf->state == VIDEOBUF_DONE) |
71 | dvb_dmx_swfilter(&dvb->demux, dma->vmalloc, | 73 | dvb_dmx_swfilter(&dvb->demux, outp, |
72 | buf->size); | 74 | buf->size); |
73 | 75 | ||
74 | /* requeue buffer */ | 76 | /* requeue buffer */ |
@@ -138,14 +140,16 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed) | |||
138 | int videobuf_dvb_register(struct videobuf_dvb *dvb, | 140 | int videobuf_dvb_register(struct videobuf_dvb *dvb, |
139 | struct module *module, | 141 | struct module *module, |
140 | void *adapter_priv, | 142 | void *adapter_priv, |
141 | struct device *device) | 143 | struct device *device, |
144 | short *adapter_nr) | ||
142 | { | 145 | { |
143 | int result; | 146 | int result; |
144 | 147 | ||
145 | mutex_init(&dvb->lock); | 148 | mutex_init(&dvb->lock); |
146 | 149 | ||
147 | /* register adapter */ | 150 | /* register adapter */ |
148 | result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device); | 151 | result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device, |
152 | adapter_nr); | ||
149 | if (result < 0) { | 153 | if (result < 0) { |
150 | printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", | 154 | printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", |
151 | dvb->name, result); | 155 | dvb->name, result); |
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c index 5266ecc91dab..c91e1d8e3802 100644 --- a/drivers/media/video/videobuf-vmalloc.c +++ b/drivers/media/video/videobuf-vmalloc.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \ | 33 | #define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \ |
34 | { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); } | 34 | { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); } |
35 | 35 | ||
36 | static int debug = 0; | 36 | static int debug; |
37 | module_param(debug, int, 0644); | 37 | module_param(debug, int, 0644); |
38 | 38 | ||
39 | MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers"); | 39 | MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers"); |
@@ -57,20 +57,26 @@ videobuf_vm_open(struct vm_area_struct *vma) | |||
57 | map->count++; | 57 | map->count++; |
58 | } | 58 | } |
59 | 59 | ||
60 | static void | 60 | static void videobuf_vm_close(struct vm_area_struct *vma) |
61 | videobuf_vm_close(struct vm_area_struct *vma) | ||
62 | { | 61 | { |
63 | struct videobuf_mapping *map = vma->vm_private_data; | 62 | struct videobuf_mapping *map = vma->vm_private_data; |
64 | struct videobuf_queue *q = map->q; | 63 | struct videobuf_queue *q = map->q; |
65 | int i; | 64 | int i; |
66 | 65 | ||
67 | dprintk(2,"vm_close %p [count=%u,vma=%08lx-%08lx]\n",map, | 66 | dprintk(2,"vm_close %p [count=%u,vma=%08lx-%08lx]\n", map, |
68 | map->count,vma->vm_start,vma->vm_end); | 67 | map->count, vma->vm_start, vma->vm_end); |
69 | 68 | ||
70 | map->count--; | 69 | map->count--; |
71 | if (0 == map->count) { | 70 | if (0 == map->count) { |
72 | dprintk(1,"munmap %p q=%p\n",map,q); | 71 | struct videobuf_vmalloc_memory *mem; |
72 | |||
73 | dprintk(1, "munmap %p q=%p\n", map, q); | ||
73 | mutex_lock(&q->vb_lock); | 74 | mutex_lock(&q->vb_lock); |
75 | |||
76 | /* We need first to cancel streams, before unmapping */ | ||
77 | if (q->streaming) | ||
78 | videobuf_queue_cancel(q); | ||
79 | |||
74 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | 80 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
75 | if (NULL == q->bufs[i]) | 81 | if (NULL == q->bufs[i]) |
76 | continue; | 82 | continue; |
@@ -78,14 +84,35 @@ videobuf_vm_close(struct vm_area_struct *vma) | |||
78 | if (q->bufs[i]->map != map) | 84 | if (q->bufs[i]->map != map) |
79 | continue; | 85 | continue; |
80 | 86 | ||
81 | q->ops->buf_release(q,q->bufs[i]); | 87 | mem = q->bufs[i]->priv; |
88 | if (mem) { | ||
89 | /* This callback is called only if kernel has | ||
90 | allocated memory and this memory is mmapped. | ||
91 | In this case, memory should be freed, | ||
92 | in order to do memory unmap. | ||
93 | */ | ||
94 | |||
95 | MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); | ||
96 | |||
97 | /* vfree is not atomic - can't be | ||
98 | called with IRQ's disabled | ||
99 | */ | ||
100 | dprintk(1, "%s: buf[%d] freeing (%p)\n", | ||
101 | __func__, i, mem->vmalloc); | ||
102 | |||
103 | vfree(mem->vmalloc); | ||
104 | mem->vmalloc = NULL; | ||
105 | } | ||
82 | 106 | ||
83 | q->bufs[i]->map = NULL; | 107 | q->bufs[i]->map = NULL; |
84 | q->bufs[i]->baddr = 0; | 108 | q->bufs[i]->baddr = 0; |
85 | } | 109 | } |
86 | mutex_unlock(&q->vb_lock); | 110 | |
87 | kfree(map); | 111 | kfree(map); |
112 | |||
113 | mutex_unlock(&q->vb_lock); | ||
88 | } | 114 | } |
115 | |||
89 | return; | 116 | return; |
90 | } | 117 | } |
91 | 118 | ||
@@ -102,7 +129,7 @@ static struct vm_operations_struct videobuf_vm_ops = | |||
102 | /* Allocated area consists on 3 parts: | 129 | /* Allocated area consists on 3 parts: |
103 | struct video_buffer | 130 | struct video_buffer |
104 | struct <driver>_buffer (cx88_buffer, saa7134_buf, ...) | 131 | struct <driver>_buffer (cx88_buffer, saa7134_buf, ...) |
105 | struct videobuf_pci_sg_memory | 132 | struct videobuf_dma_sg_memory |
106 | */ | 133 | */ |
107 | 134 | ||
108 | static void *__videobuf_alloc(size_t size) | 135 | static void *__videobuf_alloc(size_t size) |
@@ -116,7 +143,7 @@ static void *__videobuf_alloc(size_t size) | |||
116 | mem->magic=MAGIC_VMAL_MEM; | 143 | mem->magic=MAGIC_VMAL_MEM; |
117 | 144 | ||
118 | dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n", | 145 | dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n", |
119 | __FUNCTION__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb), | 146 | __func__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb), |
120 | mem,(long)sizeof(*mem)); | 147 | mem,(long)sizeof(*mem)); |
121 | 148 | ||
122 | return vb; | 149 | return vb; |
@@ -126,45 +153,74 @@ static int __videobuf_iolock (struct videobuf_queue* q, | |||
126 | struct videobuf_buffer *vb, | 153 | struct videobuf_buffer *vb, |
127 | struct v4l2_framebuffer *fbuf) | 154 | struct v4l2_framebuffer *fbuf) |
128 | { | 155 | { |
156 | struct videobuf_vmalloc_memory *mem = vb->priv; | ||
129 | int pages; | 157 | int pages; |
130 | struct videobuf_vmalloc_memory *mem=vb->priv; | ||
131 | 158 | ||
132 | BUG_ON(!mem); | 159 | BUG_ON(!mem); |
133 | 160 | ||
134 | MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); | 161 | MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); |
135 | 162 | ||
136 | pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT; | 163 | switch (vb->memory) { |
164 | case V4L2_MEMORY_MMAP: | ||
165 | dprintk(1, "%s memory method MMAP\n", __func__); | ||
137 | 166 | ||
138 | /* Currently, doesn't support V4L2_MEMORY_OVERLAY */ | 167 | /* All handling should be done by __videobuf_mmap_mapper() */ |
139 | if ((vb->memory != V4L2_MEMORY_MMAP) && | 168 | if (!mem->vmalloc) { |
140 | (vb->memory != V4L2_MEMORY_USERPTR) ) { | 169 | printk(KERN_ERR "memory is not alloced/mmapped.\n"); |
141 | printk(KERN_ERR "Method currently unsupported.\n"); | 170 | return -EINVAL; |
142 | return -EINVAL; | 171 | } |
143 | } | 172 | break; |
173 | case V4L2_MEMORY_USERPTR: | ||
174 | pages = PAGE_ALIGN(vb->size); | ||
144 | 175 | ||
145 | /* FIXME: should be tested with kernel mmap mem */ | 176 | dprintk(1, "%s memory method USERPTR\n", __func__); |
146 | mem->vmalloc=vmalloc_user (PAGE_ALIGN(vb->size)); | ||
147 | if (NULL == mem->vmalloc) { | ||
148 | printk(KERN_ERR "vmalloc (%d pages) failed\n",pages); | ||
149 | return -ENOMEM; | ||
150 | } | ||
151 | 177 | ||
152 | dprintk(1,"vmalloc is at addr 0x%08lx, size=%d\n", | 178 | #if 1 |
153 | (unsigned long)mem->vmalloc, | 179 | if (vb->baddr) { |
154 | pages << PAGE_SHIFT); | 180 | printk(KERN_ERR "USERPTR is currently not supported\n"); |
181 | return -EINVAL; | ||
182 | } | ||
183 | #endif | ||
155 | 184 | ||
156 | /* It seems that some kernel versions need to do remap *after* | 185 | /* The only USERPTR currently supported is the one needed for |
157 | the mmap() call | 186 | read() method. |
158 | */ | 187 | */ |
159 | if (mem->vma) { | 188 | |
160 | int retval=remap_vmalloc_range(mem->vma, mem->vmalloc,0); | 189 | mem->vmalloc = vmalloc_user(pages); |
161 | kfree(mem->vma); | 190 | if (!mem->vmalloc) { |
162 | mem->vma=NULL; | 191 | printk(KERN_ERR "vmalloc (%d pages) failed\n", pages); |
163 | if (retval<0) { | 192 | return -ENOMEM; |
164 | dprintk(1,"mmap app bug: remap_vmalloc_range area %p error %d\n", | 193 | } |
165 | mem->vmalloc,retval); | 194 | dprintk(1, "vmalloc is at addr %p (%d pages)\n", |
166 | return retval; | 195 | mem->vmalloc, pages); |
196 | |||
197 | #if 0 | ||
198 | int rc; | ||
199 | /* Kernel userptr is used also by read() method. In this case, | ||
200 | there's no need to remap, since data will be copied to user | ||
201 | */ | ||
202 | if (!vb->baddr) | ||
203 | return 0; | ||
204 | |||
205 | /* FIXME: to properly support USERPTR, remap should occur. | ||
206 | The code bellow won't work, since mem->vma = NULL | ||
207 | */ | ||
208 | /* Try to remap memory */ | ||
209 | rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0); | ||
210 | if (rc < 0) { | ||
211 | printk(KERN_ERR "mmap: remap failed with error %d. ", rc); | ||
212 | return -ENOMEM; | ||
167 | } | 213 | } |
214 | #endif | ||
215 | |||
216 | break; | ||
217 | case V4L2_MEMORY_OVERLAY: | ||
218 | default: | ||
219 | dprintk(1, "%s memory method OVERLAY/unknown\n", __func__); | ||
220 | |||
221 | /* Currently, doesn't support V4L2_MEMORY_OVERLAY */ | ||
222 | printk(KERN_ERR "Memory method currently unsupported.\n"); | ||
223 | return -EINVAL; | ||
168 | } | 224 | } |
169 | 225 | ||
170 | return 0; | 226 | return 0; |
@@ -180,6 +236,7 @@ static int __videobuf_mmap_free(struct videobuf_queue *q) | |||
180 | { | 236 | { |
181 | unsigned int i; | 237 | unsigned int i; |
182 | 238 | ||
239 | dprintk(1, "%s\n", __func__); | ||
183 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | 240 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
184 | if (q->bufs[i]) { | 241 | if (q->bufs[i]) { |
185 | if (q->bufs[i]->map) | 242 | if (q->bufs[i]->map) |
@@ -196,10 +253,11 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, | |||
196 | struct videobuf_vmalloc_memory *mem; | 253 | struct videobuf_vmalloc_memory *mem; |
197 | struct videobuf_mapping *map; | 254 | struct videobuf_mapping *map; |
198 | unsigned int first; | 255 | unsigned int first; |
199 | int retval; | 256 | int retval, pages; |
200 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | 257 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; |
201 | 258 | ||
202 | if (! (vma->vm_flags & VM_WRITE) || ! (vma->vm_flags & VM_SHARED)) | 259 | dprintk(1, "%s\n", __func__); |
260 | if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) | ||
203 | return -EINVAL; | 261 | return -EINVAL; |
204 | 262 | ||
205 | /* look for first buffer to map */ | 263 | /* look for first buffer to map */ |
@@ -219,46 +277,55 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, | |||
219 | } | 277 | } |
220 | 278 | ||
221 | /* create mapping + update buffer list */ | 279 | /* create mapping + update buffer list */ |
222 | map = q->bufs[first]->map = kzalloc(sizeof(struct videobuf_mapping),GFP_KERNEL); | 280 | map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); |
223 | if (NULL == map) | 281 | if (NULL == map) |
224 | return -ENOMEM; | 282 | return -ENOMEM; |
225 | 283 | ||
284 | q->bufs[first]->map = map; | ||
226 | map->start = vma->vm_start; | 285 | map->start = vma->vm_start; |
227 | map->end = vma->vm_end; | 286 | map->end = vma->vm_end; |
228 | map->q = q; | 287 | map->q = q; |
229 | 288 | ||
230 | q->bufs[first]->baddr = vma->vm_start; | 289 | q->bufs[first]->baddr = vma->vm_start; |
231 | 290 | ||
232 | vma->vm_ops = &videobuf_vm_ops; | 291 | mem = q->bufs[first]->priv; |
233 | vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; | 292 | BUG_ON(!mem); |
234 | vma->vm_private_data = map; | 293 | MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); |
235 | 294 | ||
236 | mem=q->bufs[first]->priv; | 295 | pages = PAGE_ALIGN(vma->vm_end - vma->vm_start); |
237 | BUG_ON (!mem); | 296 | mem->vmalloc = vmalloc_user(pages); |
238 | MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); | 297 | if (!mem->vmalloc) { |
298 | printk(KERN_ERR "vmalloc (%d pages) failed\n", pages); | ||
299 | goto error; | ||
300 | } | ||
301 | dprintk(1, "vmalloc is at addr %p (%d pages)\n", | ||
302 | mem->vmalloc, pages); | ||
239 | 303 | ||
240 | /* Try to remap memory */ | 304 | /* Try to remap memory */ |
241 | retval=remap_vmalloc_range(vma, mem->vmalloc,0); | 305 | retval = remap_vmalloc_range(vma, mem->vmalloc, 0); |
242 | if (retval<0) { | 306 | if (retval < 0) { |
243 | dprintk(1,"mmap: postponing remap_vmalloc_range\n"); | 307 | printk(KERN_ERR "mmap: remap failed with error %d. ", retval); |
244 | 308 | vfree(mem->vmalloc); | |
245 | mem->vma=kmalloc(sizeof(*vma),GFP_KERNEL); | 309 | goto error; |
246 | if (!mem->vma) { | ||
247 | kfree(map); | ||
248 | q->bufs[first]->map=NULL; | ||
249 | return -ENOMEM; | ||
250 | } | ||
251 | memcpy(mem->vma,vma,sizeof(*vma)); | ||
252 | } | 310 | } |
253 | 311 | ||
312 | vma->vm_ops = &videobuf_vm_ops; | ||
313 | vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; | ||
314 | vma->vm_private_data = map; | ||
315 | |||
254 | dprintk(1,"mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", | 316 | dprintk(1,"mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", |
255 | map,q,vma->vm_start,vma->vm_end, | 317 | map, q, vma->vm_start, vma->vm_end, |
256 | (long int) q->bufs[first]->bsize, | 318 | (long int) q->bufs[first]->bsize, |
257 | vma->vm_pgoff,first); | 319 | vma->vm_pgoff, first); |
258 | 320 | ||
259 | videobuf_vm_open(vma); | 321 | videobuf_vm_open(vma); |
260 | 322 | ||
261 | return (0); | 323 | return 0; |
324 | |||
325 | error: | ||
326 | mem = NULL; | ||
327 | kfree(map); | ||
328 | return -ENOMEM; | ||
262 | } | 329 | } |
263 | 330 | ||
264 | static int __videobuf_copy_to_user ( struct videobuf_queue *q, | 331 | static int __videobuf_copy_to_user ( struct videobuf_queue *q, |
@@ -320,6 +387,7 @@ static struct videobuf_qtype_ops qops = { | |||
320 | .mmap_mapper = __videobuf_mmap_mapper, | 387 | .mmap_mapper = __videobuf_mmap_mapper, |
321 | .video_copy_to_user = __videobuf_copy_to_user, | 388 | .video_copy_to_user = __videobuf_copy_to_user, |
322 | .copy_stream = __videobuf_copy_stream, | 389 | .copy_stream = __videobuf_copy_stream, |
390 | .vmalloc = videobuf_to_vmalloc, | ||
323 | }; | 391 | }; |
324 | 392 | ||
325 | void videobuf_queue_vmalloc_init(struct videobuf_queue* q, | 393 | void videobuf_queue_vmalloc_init(struct videobuf_queue* q, |
@@ -349,13 +417,24 @@ EXPORT_SYMBOL_GPL(videobuf_to_vmalloc); | |||
349 | 417 | ||
350 | void videobuf_vmalloc_free (struct videobuf_buffer *buf) | 418 | void videobuf_vmalloc_free (struct videobuf_buffer *buf) |
351 | { | 419 | { |
352 | struct videobuf_vmalloc_memory *mem=buf->priv; | 420 | struct videobuf_vmalloc_memory *mem = buf->priv; |
353 | BUG_ON (!mem); | ||
354 | 421 | ||
355 | MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); | 422 | /* mmapped memory can't be freed here, otherwise mmapped region |
423 | would be released, while still needed. In this case, the memory | ||
424 | release should happen inside videobuf_vm_close(). | ||
425 | So, it should free memory only if the memory were allocated for | ||
426 | read() operation. | ||
427 | */ | ||
428 | if ((buf->memory != V4L2_MEMORY_USERPTR) || (buf->baddr == 0)) | ||
429 | return; | ||
430 | |||
431 | if (!mem) | ||
432 | return; | ||
433 | |||
434 | MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); | ||
356 | 435 | ||
357 | vfree(mem->vmalloc); | 436 | vfree(mem->vmalloc); |
358 | mem->vmalloc=NULL; | 437 | mem->vmalloc = NULL; |
359 | 438 | ||
360 | return; | 439 | return; |
361 | } | 440 | } |
diff --git a/drivers/media/video/videocodec.c b/drivers/media/video/videocodec.c index 87951ec8254f..cf24956f3204 100644 --- a/drivers/media/video/videocodec.c +++ b/drivers/media/video/videocodec.c | |||
@@ -39,12 +39,13 @@ | |||
39 | 39 | ||
40 | #ifdef CONFIG_PROC_FS | 40 | #ifdef CONFIG_PROC_FS |
41 | #include <linux/proc_fs.h> | 41 | #include <linux/proc_fs.h> |
42 | #include <linux/seq_file.h> | ||
42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
43 | #endif | 44 | #endif |
44 | 45 | ||
45 | #include "videocodec.h" | 46 | #include "videocodec.h" |
46 | 47 | ||
47 | static int debug = 0; | 48 | static int debug; |
48 | module_param(debug, int, 0); | 49 | module_param(debug, int, 0); |
49 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | 50 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); |
50 | 51 | ||
@@ -320,56 +321,22 @@ videocodec_unregister (const struct videocodec *codec) | |||
320 | } | 321 | } |
321 | 322 | ||
322 | #ifdef CONFIG_PROC_FS | 323 | #ifdef CONFIG_PROC_FS |
323 | /* ============ */ | 324 | static int proc_videocodecs_show(struct seq_file *m, void *v) |
324 | /* procfs stuff */ | ||
325 | /* ============ */ | ||
326 | |||
327 | static char *videocodec_buf = NULL; | ||
328 | static int videocodec_bufsize = 0; | ||
329 | |||
330 | static int | ||
331 | videocodec_build_table (void) | ||
332 | { | 325 | { |
333 | struct codec_list *h = codeclist_top; | 326 | struct codec_list *h = codeclist_top; |
334 | struct attached_list *a; | 327 | struct attached_list *a; |
335 | int i = 0, size; | ||
336 | |||
337 | // sum up amount of slaves plus their attached masters | ||
338 | while (h) { | ||
339 | i += h->attached + 1; | ||
340 | h = h->next; | ||
341 | } | ||
342 | #define LINESIZE 100 | ||
343 | size = LINESIZE * (i + 1); | ||
344 | 328 | ||
345 | dprintk(3, "videocodec_build table: %d entries, %d bytes\n", i, | 329 | seq_printf(m, "<S>lave or attached <M>aster name type flags magic "); |
346 | size); | 330 | seq_printf(m, "(connected as)\n"); |
347 | |||
348 | kfree(videocodec_buf); | ||
349 | videocodec_buf = kmalloc(size, GFP_KERNEL); | ||
350 | |||
351 | if (!videocodec_buf) | ||
352 | return 0; | ||
353 | |||
354 | i = 0; | ||
355 | i += scnprintf(videocodec_buf + i, size - 1, | ||
356 | "<S>lave or attached <M>aster name type flags magic "); | ||
357 | i += scnprintf(videocodec_buf + i, size -i - 1, "(connected as)\n"); | ||
358 | 331 | ||
359 | h = codeclist_top; | 332 | h = codeclist_top; |
360 | while (h) { | 333 | while (h) { |
361 | if (i > (size - LINESIZE)) | 334 | seq_printf(m, "S %32s %04x %08lx %08lx (TEMPLATE)\n", |
362 | break; // security check | ||
363 | i += scnprintf(videocodec_buf + i, size -i -1, | ||
364 | "S %32s %04x %08lx %08lx (TEMPLATE)\n", | ||
365 | h->codec->name, h->codec->type, | 335 | h->codec->name, h->codec->type, |
366 | h->codec->flags, h->codec->magic); | 336 | h->codec->flags, h->codec->magic); |
367 | a = h->list; | 337 | a = h->list; |
368 | while (a) { | 338 | while (a) { |
369 | if (i > (size - LINESIZE)) | 339 | seq_printf(m, "M %32s %04x %08lx %08lx (%s)\n", |
370 | break; // security check | ||
371 | i += scnprintf(videocodec_buf + i, size -i -1, | ||
372 | "M %32s %04x %08lx %08lx (%s)\n", | ||
373 | a->codec->master_data->name, | 340 | a->codec->master_data->name, |
374 | a->codec->master_data->type, | 341 | a->codec->master_data->type, |
375 | a->codec->master_data->flags, | 342 | a->codec->master_data->flags, |
@@ -380,54 +347,21 @@ videocodec_build_table (void) | |||
380 | h = h->next; | 347 | h = h->next; |
381 | } | 348 | } |
382 | 349 | ||
383 | return i; | 350 | return 0; |
384 | } | 351 | } |
385 | 352 | ||
386 | //The definition: | 353 | static int proc_videocodecs_open(struct inode *inode, struct file *file) |
387 | //typedef int (read_proc_t)(char *page, char **start, off_t off, | ||
388 | // int count, int *eof, void *data); | ||
389 | |||
390 | static int | ||
391 | videocodec_info (char *buffer, | ||
392 | char **buffer_location, | ||
393 | off_t offset, | ||
394 | int buffer_length, | ||
395 | int *eof, | ||
396 | void *data) | ||
397 | { | 354 | { |
398 | int size; | 355 | return single_open(file, proc_videocodecs_show, NULL); |
399 | |||
400 | dprintk(3, "videocodec_info: offset: %ld, len %d / size %d\n", | ||
401 | offset, buffer_length, videocodec_bufsize); | ||
402 | |||
403 | if (offset == 0) { | ||
404 | videocodec_bufsize = videocodec_build_table(); | ||
405 | } | ||
406 | if ((offset < 0) || (offset >= videocodec_bufsize)) { | ||
407 | dprintk(4, | ||
408 | "videocodec_info: call delivers no result, return 0\n"); | ||
409 | *eof = 1; | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | if (buffer_length < (videocodec_bufsize - offset)) { | ||
414 | dprintk(4, "videocodec_info: %ld needed, %d got\n", | ||
415 | videocodec_bufsize - offset, buffer_length); | ||
416 | size = buffer_length; | ||
417 | } else { | ||
418 | dprintk(4, "videocodec_info: last reading of %ld bytes\n", | ||
419 | videocodec_bufsize - offset); | ||
420 | size = videocodec_bufsize - offset; | ||
421 | *eof = 1; | ||
422 | } | ||
423 | |||
424 | memcpy(buffer, videocodec_buf + offset, size); | ||
425 | /* doesn't work... */ | ||
426 | /* copy_to_user(buffer, videocodec_buf+offset, size); */ | ||
427 | /* *buffer_location = videocodec_buf+offset; */ | ||
428 | |||
429 | return size; | ||
430 | } | 356 | } |
357 | |||
358 | static const struct file_operations videocodecs_proc_fops = { | ||
359 | .owner = THIS_MODULE, | ||
360 | .open = proc_videocodecs_open, | ||
361 | .read = seq_read, | ||
362 | .llseek = seq_lseek, | ||
363 | .release = single_release, | ||
364 | }; | ||
431 | #endif | 365 | #endif |
432 | 366 | ||
433 | /* ===================== */ | 367 | /* ===================== */ |
@@ -444,16 +378,8 @@ videocodec_init (void) | |||
444 | VIDEOCODEC_VERSION); | 378 | VIDEOCODEC_VERSION); |
445 | 379 | ||
446 | #ifdef CONFIG_PROC_FS | 380 | #ifdef CONFIG_PROC_FS |
447 | videocodec_buf = NULL; | 381 | videocodec_proc_entry = proc_create("videocodecs", 0, NULL, &videocodecs_proc_fops); |
448 | videocodec_bufsize = 0; | 382 | if (!videocodec_proc_entry) { |
449 | |||
450 | videocodec_proc_entry = create_proc_entry("videocodecs", 0, NULL); | ||
451 | if (videocodec_proc_entry) { | ||
452 | videocodec_proc_entry->read_proc = videocodec_info; | ||
453 | videocodec_proc_entry->write_proc = NULL; | ||
454 | videocodec_proc_entry->data = NULL; | ||
455 | videocodec_proc_entry->owner = THIS_MODULE; | ||
456 | } else { | ||
457 | dprintk(1, KERN_ERR "videocodec: can't init procfs.\n"); | 383 | dprintk(1, KERN_ERR "videocodec: can't init procfs.\n"); |
458 | } | 384 | } |
459 | #endif | 385 | #endif |
@@ -465,7 +391,6 @@ videocodec_exit (void) | |||
465 | { | 391 | { |
466 | #ifdef CONFIG_PROC_FS | 392 | #ifdef CONFIG_PROC_FS |
467 | remove_proc_entry("videocodecs", NULL); | 393 | remove_proc_entry("videocodecs", NULL); |
468 | kfree(videocodec_buf); | ||
469 | #endif | 394 | #endif |
470 | } | 395 | } |
471 | 396 | ||
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 0d9b63762a48..31e8af0ba278 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c | |||
@@ -18,14 +18,14 @@ | |||
18 | 18 | ||
19 | #define dbgarg(cmd, fmt, arg...) \ | 19 | #define dbgarg(cmd, fmt, arg...) \ |
20 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ | 20 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ |
21 | printk (KERN_DEBUG "%s: ", vfd->name); \ | 21 | printk(KERN_DEBUG "%s: ", vfd->name); \ |
22 | v4l_printk_ioctl(cmd); \ | 22 | v4l_printk_ioctl(cmd); \ |
23 | printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); \ | 23 | printk(" " fmt, ## arg); \ |
24 | } | 24 | } |
25 | 25 | ||
26 | #define dbgarg2(fmt, arg...) \ | 26 | #define dbgarg2(fmt, arg...) \ |
27 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ | 27 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ |
28 | printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); | 28 | printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg); |
29 | 29 | ||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
@@ -378,38 +378,45 @@ static const char *v4l2_int_ioctls[] = { | |||
378 | external ioctl messages as well as internal V4L ioctl */ | 378 | external ioctl messages as well as internal V4L ioctl */ |
379 | void v4l_printk_ioctl(unsigned int cmd) | 379 | void v4l_printk_ioctl(unsigned int cmd) |
380 | { | 380 | { |
381 | char *dir; | 381 | char *dir, *type; |
382 | 382 | ||
383 | switch (_IOC_DIR(cmd)) { | ||
384 | case _IOC_NONE: dir = "--"; break; | ||
385 | case _IOC_READ: dir = "r-"; break; | ||
386 | case _IOC_WRITE: dir = "-w"; break; | ||
387 | case _IOC_READ | _IOC_WRITE: dir = "rw"; break; | ||
388 | default: dir = "*ERR*"; break; | ||
389 | } | ||
390 | switch (_IOC_TYPE(cmd)) { | 383 | switch (_IOC_TYPE(cmd)) { |
391 | case 'd': | 384 | case 'd': |
392 | printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n", | 385 | if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) { |
393 | (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? | 386 | type = "v4l2_int"; |
394 | v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); | 387 | break; |
395 | break; | 388 | } |
389 | printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]); | ||
390 | return; | ||
396 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 391 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
397 | case 'v': | 392 | case 'v': |
398 | printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", | 393 | if (_IOC_NR(cmd) >= V4L1_IOCTLS) { |
399 | (_IOC_NR(cmd) < V4L1_IOCTLS) ? | 394 | type = "v4l1"; |
400 | v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); | 395 | break; |
401 | break; | 396 | } |
397 | printk("%s", v4l1_ioctls[_IOC_NR(cmd)]); | ||
398 | return; | ||
402 | #endif | 399 | #endif |
403 | case 'V': | 400 | case 'V': |
404 | printk("v4l2 ioctl %s, dir=%s (0x%08x)\n", | 401 | if (_IOC_NR(cmd) >= V4L2_IOCTLS) { |
405 | (_IOC_NR(cmd) < V4L2_IOCTLS) ? | 402 | type = "v4l2"; |
406 | v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); | 403 | break; |
407 | break; | 404 | } |
408 | 405 | printk("%s", v4l2_ioctls[_IOC_NR(cmd)]); | |
406 | return; | ||
409 | default: | 407 | default: |
410 | printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n", | 408 | type = "unknown"; |
411 | _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); | 409 | } |
410 | |||
411 | switch (_IOC_DIR(cmd)) { | ||
412 | case _IOC_NONE: dir = "--"; break; | ||
413 | case _IOC_READ: dir = "r-"; break; | ||
414 | case _IOC_WRITE: dir = "-w"; break; | ||
415 | case _IOC_READ | _IOC_WRITE: dir = "rw"; break; | ||
416 | default: dir = "*ERR*"; break; | ||
412 | } | 417 | } |
418 | printk("%s ioctl '%c', dir=%s, #%d (0x%08x)", | ||
419 | type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); | ||
413 | } | 420 | } |
414 | EXPORT_SYMBOL(v4l_printk_ioctl); | 421 | EXPORT_SYMBOL(v4l_printk_ioctl); |
415 | 422 | ||
@@ -774,6 +781,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
774 | if ( (vfd->debug & V4L2_DEBUG_IOCTL) && | 781 | if ( (vfd->debug & V4L2_DEBUG_IOCTL) && |
775 | !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { | 782 | !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { |
776 | v4l_print_ioctl(vfd->name, cmd); | 783 | v4l_print_ioctl(vfd->name, cmd); |
784 | printk("\n"); | ||
777 | } | 785 | } |
778 | 786 | ||
779 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 787 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
@@ -1853,12 +1861,20 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1853 | dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); | 1861 | dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); |
1854 | break; | 1862 | break; |
1855 | } | 1863 | } |
1864 | default: | ||
1865 | { | ||
1866 | if (!vfd->vidioc_default) | ||
1867 | break; | ||
1868 | ret = vfd->vidioc_default(file, fh, cmd, arg); | ||
1869 | break; | ||
1870 | } | ||
1856 | } /* switch */ | 1871 | } /* switch */ |
1857 | 1872 | ||
1858 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { | 1873 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { |
1859 | if (ret<0) { | 1874 | if (ret<0) { |
1860 | printk ("%s: err:\n", vfd->name); | 1875 | printk("%s: err: on ", vfd->name); |
1861 | v4l_print_ioctl(vfd->name, cmd); | 1876 | v4l_print_ioctl(vfd->name, cmd); |
1877 | printk("\n"); | ||
1862 | } | 1878 | } |
1863 | } | 1879 | } |
1864 | 1880 | ||
@@ -2019,7 +2035,7 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
2019 | break; | 2035 | break; |
2020 | default: | 2036 | default: |
2021 | printk(KERN_ERR "%s called with unknown type: %d\n", | 2037 | printk(KERN_ERR "%s called with unknown type: %d\n", |
2022 | __FUNCTION__, type); | 2038 | __func__, type); |
2023 | return -1; | 2039 | return -1; |
2024 | } | 2040 | } |
2025 | 2041 | ||
@@ -2057,7 +2073,7 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
2057 | ret = device_register(&vfd->class_dev); | 2073 | ret = device_register(&vfd->class_dev); |
2058 | if (ret < 0) { | 2074 | if (ret < 0) { |
2059 | printk(KERN_ERR "%s: device_register failed\n", | 2075 | printk(KERN_ERR "%s: device_register failed\n", |
2060 | __FUNCTION__); | 2076 | __func__); |
2061 | goto fail_minor; | 2077 | goto fail_minor; |
2062 | } | 2078 | } |
2063 | 2079 | ||
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 5bb75294b5aa..d545c98dd5e7 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
@@ -333,7 +333,7 @@ struct vino_settings { | |||
333 | * | 333 | * |
334 | * Use non-zero value to enable conversion. | 334 | * Use non-zero value to enable conversion. |
335 | */ | 335 | */ |
336 | static int vino_pixel_conversion = 0; | 336 | static int vino_pixel_conversion; |
337 | 337 | ||
338 | module_param_named(pixelconv, vino_pixel_conversion, int, 0); | 338 | module_param_named(pixelconv, vino_pixel_conversion, int, 0); |
339 | 339 | ||
@@ -4370,8 +4370,8 @@ static int vino_ioctl(struct inode *inode, struct file *file, | |||
4370 | 4370 | ||
4371 | /* Initialization and cleanup */ | 4371 | /* Initialization and cleanup */ |
4372 | 4372 | ||
4373 | // __initdata | 4373 | /* __initdata */ |
4374 | static int vino_init_stage = 0; | 4374 | static int vino_init_stage; |
4375 | 4375 | ||
4376 | static const struct file_operations vino_fops = { | 4376 | static const struct file_operations vino_fops = { |
4377 | .owner = THIS_MODULE, | 4377 | .owner = THIS_MODULE, |
@@ -4385,8 +4385,8 @@ static const struct file_operations vino_fops = { | |||
4385 | 4385 | ||
4386 | static struct video_device v4l_device_template = { | 4386 | static struct video_device v4l_device_template = { |
4387 | .name = "NOT SET", | 4387 | .name = "NOT SET", |
4388 | //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | | 4388 | /*.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | */ |
4389 | // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY | 4389 | /* VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY */ |
4390 | .fops = &vino_fops, | 4390 | .fops = &vino_fops, |
4391 | .minor = -1, | 4391 | .minor = -1, |
4392 | }; | 4392 | }; |
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 1db067c02815..b1e9592acb90 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -146,8 +146,6 @@ struct vivi_buffer { | |||
146 | 146 | ||
147 | struct vivi_dmaqueue { | 147 | struct vivi_dmaqueue { |
148 | struct list_head active; | 148 | struct list_head active; |
149 | struct list_head queued; | ||
150 | struct timer_list timeout; | ||
151 | 149 | ||
152 | /* thread for generating video stream*/ | 150 | /* thread for generating video stream*/ |
153 | struct task_struct *kthread; | 151 | struct task_struct *kthread; |
@@ -162,8 +160,8 @@ static LIST_HEAD(vivi_devlist); | |||
162 | struct vivi_dev { | 160 | struct vivi_dev { |
163 | struct list_head vivi_devlist; | 161 | struct list_head vivi_devlist; |
164 | 162 | ||
165 | struct mutex lock; | ||
166 | spinlock_t slock; | 163 | spinlock_t slock; |
164 | struct mutex mutex; | ||
167 | 165 | ||
168 | int users; | 166 | int users; |
169 | 167 | ||
@@ -322,24 +320,26 @@ static void gen_line(char *basep, int inipos, int wmax, | |||
322 | end: | 320 | end: |
323 | return; | 321 | return; |
324 | } | 322 | } |
323 | |||
325 | static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) | 324 | static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) |
326 | { | 325 | { |
327 | int h , pos = 0; | 326 | int h , pos = 0; |
328 | int hmax = buf->vb.height; | 327 | int hmax = buf->vb.height; |
329 | int wmax = buf->vb.width; | 328 | int wmax = buf->vb.width; |
330 | struct timeval ts; | 329 | struct timeval ts; |
331 | char *tmpbuf = kmalloc(wmax * 2, GFP_KERNEL); | 330 | char *tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC); |
332 | void *vbuf = videobuf_to_vmalloc(&buf->vb); | 331 | void *vbuf = videobuf_to_vmalloc(&buf->vb); |
333 | 332 | ||
334 | if (!tmpbuf) | 333 | if (!tmpbuf) |
335 | return; | 334 | return; |
336 | 335 | ||
336 | if (!vbuf) | ||
337 | return; | ||
338 | |||
337 | for (h = 0; h < hmax; h++) { | 339 | for (h = 0; h < hmax; h++) { |
338 | gen_line(tmpbuf, 0, wmax, hmax, h, dev->mv_count, | 340 | gen_line(tmpbuf, 0, wmax, hmax, h, dev->mv_count, |
339 | dev->timestr); | 341 | dev->timestr); |
340 | /* FIXME: replacing to __copy_to_user */ | 342 | memcpy(vbuf + pos, tmpbuf, wmax * 2); |
341 | if (copy_to_user(vbuf + pos, tmpbuf, wmax * 2) != 0) | ||
342 | dprintk(dev, 2, "vivifill copy_to_user failed.\n"); | ||
343 | pos += wmax*2; | 343 | pos += wmax*2; |
344 | } | 344 | } |
345 | 345 | ||
@@ -372,107 +372,71 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) | |||
372 | dev->timestr, (unsigned long)tmpbuf, pos); | 372 | dev->timestr, (unsigned long)tmpbuf, pos); |
373 | 373 | ||
374 | /* Advice that buffer was filled */ | 374 | /* Advice that buffer was filled */ |
375 | buf->vb.state = VIDEOBUF_DONE; | ||
376 | buf->vb.field_count++; | 375 | buf->vb.field_count++; |
377 | do_gettimeofday(&ts); | 376 | do_gettimeofday(&ts); |
378 | buf->vb.ts = ts; | 377 | buf->vb.ts = ts; |
379 | 378 | buf->vb.state = VIDEOBUF_DONE; | |
380 | list_del(&buf->vb.queue); | ||
381 | wake_up(&buf->vb.done); | ||
382 | } | 379 | } |
383 | 380 | ||
384 | static int restart_video_queue(struct vivi_dmaqueue *dma_q); | 381 | static void vivi_thread_tick(struct vivi_fh *fh) |
385 | |||
386 | static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) | ||
387 | { | 382 | { |
388 | struct vivi_buffer *buf; | 383 | struct vivi_buffer *buf; |
389 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 384 | struct vivi_dev *dev = fh->dev; |
385 | struct vivi_dmaqueue *dma_q = &dev->vidq; | ||
390 | 386 | ||
391 | int bc; | 387 | unsigned long flags = 0; |
392 | 388 | ||
393 | spin_lock(&dev->slock); | 389 | dprintk(dev, 1, "Thread tick\n"); |
394 | /* Announces videobuf that all went ok */ | ||
395 | for (bc = 0;; bc++) { | ||
396 | if (list_empty(&dma_q->active)) { | ||
397 | dprintk(dev, 1, "No active queue to serve\n"); | ||
398 | break; | ||
399 | } | ||
400 | 390 | ||
401 | buf = list_entry(dma_q->active.next, | 391 | spin_lock_irqsave(&dev->slock, flags); |
402 | struct vivi_buffer, vb.queue); | 392 | if (list_empty(&dma_q->active)) { |
393 | dprintk(dev, 1, "No active queue to serve\n"); | ||
394 | goto unlock; | ||
395 | } | ||
403 | 396 | ||
404 | /* Nobody is waiting something to be done, just return */ | 397 | buf = list_entry(dma_q->active.next, |
405 | if (!waitqueue_active(&buf->vb.done)) { | 398 | struct vivi_buffer, vb.queue); |
406 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | 399 | |
407 | spin_unlock(&dev->slock); | 400 | /* Nobody is waiting on this buffer, return */ |
408 | return; | 401 | if (!waitqueue_active(&buf->vb.done)) |
409 | } | 402 | goto unlock; |
410 | 403 | ||
411 | do_gettimeofday(&buf->vb.ts); | 404 | list_del(&buf->vb.queue); |
412 | dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); | ||
413 | 405 | ||
414 | /* Fill buffer */ | 406 | do_gettimeofday(&buf->vb.ts); |
415 | vivi_fillbuff(dev, buf); | ||
416 | 407 | ||
417 | if (list_empty(&dma_q->active)) { | 408 | /* Fill buffer */ |
418 | del_timer(&dma_q->timeout); | 409 | vivi_fillbuff(dev, buf); |
419 | } else { | 410 | dprintk(dev, 1, "filled buffer %p\n", buf); |
420 | mod_timer(&dma_q->timeout, jiffies + BUFFER_TIMEOUT); | 411 | |
421 | } | 412 | wake_up(&buf->vb.done); |
422 | } | 413 | dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); |
423 | if (bc != 1) | 414 | unlock: |
424 | dprintk(dev, 1, "%s: %d buffers handled (should be 1)\n", | 415 | spin_unlock_irqrestore(&dev->slock, flags); |
425 | __FUNCTION__, bc); | 416 | return; |
426 | spin_unlock(&dev->slock); | ||
427 | } | 417 | } |
428 | 418 | ||
429 | #define frames_to_ms(frames) \ | 419 | #define frames_to_ms(frames) \ |
430 | ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR) | 420 | ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR) |
431 | 421 | ||
432 | static void vivi_sleep(struct vivi_dmaqueue *dma_q) | 422 | static void vivi_sleep(struct vivi_fh *fh) |
433 | { | 423 | { |
434 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 424 | struct vivi_dev *dev = fh->dev; |
435 | int timeout, running_time; | 425 | struct vivi_dmaqueue *dma_q = &dev->vidq; |
426 | int timeout; | ||
436 | DECLARE_WAITQUEUE(wait, current); | 427 | DECLARE_WAITQUEUE(wait, current); |
437 | 428 | ||
438 | dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__, | 429 | dprintk(dev, 1, "%s dma_q=0x%08lx\n", __func__, |
439 | (unsigned long)dma_q); | 430 | (unsigned long)dma_q); |
440 | 431 | ||
441 | add_wait_queue(&dma_q->wq, &wait); | 432 | add_wait_queue(&dma_q->wq, &wait); |
442 | if (kthread_should_stop()) | 433 | if (kthread_should_stop()) |
443 | goto stop_task; | 434 | goto stop_task; |
444 | 435 | ||
445 | running_time = jiffies - dma_q->ini_jiffies; | ||
446 | dma_q->frame++; | ||
447 | |||
448 | /* Calculate time to wake up */ | 436 | /* Calculate time to wake up */ |
449 | timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame)) - running_time; | 437 | timeout = msecs_to_jiffies(frames_to_ms(1)); |
450 | |||
451 | if (timeout > msecs_to_jiffies(frames_to_ms(2)) || timeout <= 0) { | ||
452 | int old = dma_q->frame; | ||
453 | int nframes; | ||
454 | |||
455 | dma_q->frame = (jiffies_to_msecs(running_time) / | ||
456 | frames_to_ms(1)) + 1; | ||
457 | |||
458 | timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame)) | ||
459 | - running_time; | ||
460 | |||
461 | if (unlikely (timeout <= 0)) | ||
462 | timeout = 1; | ||
463 | |||
464 | nframes = (dma_q->frame > old)? | ||
465 | dma_q->frame - old : old - dma_q->frame; | ||
466 | |||
467 | dprintk(dev, 1, "%ld: %s %d frames. " | ||
468 | "Current frame is %d. Will sleep for %d jiffies\n", | ||
469 | jiffies, | ||
470 | (dma_q->frame > old)? "Underrun, losed" : "Overrun of", | ||
471 | nframes, dma_q->frame, timeout); | ||
472 | } else | ||
473 | dprintk(dev, 1, "will sleep for %d jiffies\n", timeout); | ||
474 | 438 | ||
475 | vivi_thread_tick(dma_q); | 439 | vivi_thread_tick(fh); |
476 | 440 | ||
477 | schedule_timeout_interruptible(timeout); | 441 | schedule_timeout_interruptible(timeout); |
478 | 442 | ||
@@ -483,16 +447,15 @@ stop_task: | |||
483 | 447 | ||
484 | static int vivi_thread(void *data) | 448 | static int vivi_thread(void *data) |
485 | { | 449 | { |
486 | struct vivi_dmaqueue *dma_q = data; | 450 | struct vivi_fh *fh = data; |
487 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 451 | struct vivi_dev *dev = fh->dev; |
488 | 452 | ||
489 | dprintk(dev, 1, "thread started\n"); | 453 | dprintk(dev, 1, "thread started\n"); |
490 | 454 | ||
491 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | ||
492 | set_freezable(); | 455 | set_freezable(); |
493 | 456 | ||
494 | for (;;) { | 457 | for (;;) { |
495 | vivi_sleep(dma_q); | 458 | vivi_sleep(fh); |
496 | 459 | ||
497 | if (kthread_should_stop()) | 460 | if (kthread_should_stop()) |
498 | break; | 461 | break; |
@@ -501,16 +464,17 @@ static int vivi_thread(void *data) | |||
501 | return 0; | 464 | return 0; |
502 | } | 465 | } |
503 | 466 | ||
504 | static int vivi_start_thread(struct vivi_dmaqueue *dma_q) | 467 | static int vivi_start_thread(struct vivi_fh *fh) |
505 | { | 468 | { |
506 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 469 | struct vivi_dev *dev = fh->dev; |
470 | struct vivi_dmaqueue *dma_q = &dev->vidq; | ||
507 | 471 | ||
508 | dma_q->frame = 0; | 472 | dma_q->frame = 0; |
509 | dma_q->ini_jiffies = jiffies; | 473 | dma_q->ini_jiffies = jiffies; |
510 | 474 | ||
511 | dprintk(dev, 1, "%s\n", __FUNCTION__); | 475 | dprintk(dev, 1, "%s\n", __func__); |
512 | 476 | ||
513 | dma_q->kthread = kthread_run(vivi_thread, dma_q, "vivi"); | 477 | dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); |
514 | 478 | ||
515 | if (IS_ERR(dma_q->kthread)) { | 479 | if (IS_ERR(dma_q->kthread)) { |
516 | printk(KERN_ERR "vivi: kernel_thread() failed\n"); | 480 | printk(KERN_ERR "vivi: kernel_thread() failed\n"); |
@@ -519,7 +483,7 @@ static int vivi_start_thread(struct vivi_dmaqueue *dma_q) | |||
519 | /* Wakes thread */ | 483 | /* Wakes thread */ |
520 | wake_up_interruptible(&dma_q->wq); | 484 | wake_up_interruptible(&dma_q->wq); |
521 | 485 | ||
522 | dprintk(dev, 1, "returning from %s\n", __FUNCTION__); | 486 | dprintk(dev, 1, "returning from %s\n", __func__); |
523 | return 0; | 487 | return 0; |
524 | } | 488 | } |
525 | 489 | ||
@@ -527,7 +491,7 @@ static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) | |||
527 | { | 491 | { |
528 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | 492 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); |
529 | 493 | ||
530 | dprintk(dev, 1, "%s\n", __FUNCTION__); | 494 | dprintk(dev, 1, "%s\n", __func__); |
531 | /* shutdown control thread */ | 495 | /* shutdown control thread */ |
532 | if (dma_q->kthread) { | 496 | if (dma_q->kthread) { |
533 | kthread_stop(dma_q->kthread); | 497 | kthread_stop(dma_q->kthread); |
@@ -535,91 +499,6 @@ static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) | |||
535 | } | 499 | } |
536 | } | 500 | } |
537 | 501 | ||
538 | static int restart_video_queue(struct vivi_dmaqueue *dma_q) | ||
539 | { | ||
540 | struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); | ||
541 | struct vivi_buffer *buf, *prev; | ||
542 | |||
543 | dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__, | ||
544 | (unsigned long)dma_q); | ||
545 | |||
546 | if (!list_empty(&dma_q->active)) { | ||
547 | buf = list_entry(dma_q->active.next, | ||
548 | struct vivi_buffer, vb.queue); | ||
549 | dprintk(dev, 2, "restart_queue [%p/%d]: restart dma\n", | ||
550 | buf, buf->vb.i); | ||
551 | |||
552 | dprintk(dev, 1, "Restarting video dma\n"); | ||
553 | vivi_stop_thread(dma_q); | ||
554 | |||
555 | /* cancel all outstanding capture / vbi requests */ | ||
556 | list_for_each_entry_safe(buf, prev, &dma_q->active, vb.queue) { | ||
557 | list_del(&buf->vb.queue); | ||
558 | buf->vb.state = VIDEOBUF_ERROR; | ||
559 | wake_up(&buf->vb.done); | ||
560 | } | ||
561 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | ||
562 | |||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | prev = NULL; | ||
567 | for (;;) { | ||
568 | if (list_empty(&dma_q->queued)) | ||
569 | return 0; | ||
570 | buf = list_entry(dma_q->queued.next, | ||
571 | struct vivi_buffer, vb.queue); | ||
572 | if (NULL == prev) { | ||
573 | list_del(&buf->vb.queue); | ||
574 | list_add_tail(&buf->vb.queue, &dma_q->active); | ||
575 | |||
576 | dprintk(dev, 1, "Restarting video dma\n"); | ||
577 | vivi_stop_thread(dma_q); | ||
578 | vivi_start_thread(dma_q); | ||
579 | |||
580 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
581 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | ||
582 | dprintk(dev, 2, | ||
583 | "[%p/%d] restart_queue - first active\n", | ||
584 | buf, buf->vb.i); | ||
585 | |||
586 | } else if (prev->vb.width == buf->vb.width && | ||
587 | prev->vb.height == buf->vb.height && | ||
588 | prev->fmt == buf->fmt) { | ||
589 | list_del(&buf->vb.queue); | ||
590 | list_add_tail(&buf->vb.queue, &dma_q->active); | ||
591 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
592 | dprintk(dev, 2, | ||
593 | "[%p/%d] restart_queue - move to active\n", | ||
594 | buf, buf->vb.i); | ||
595 | } else { | ||
596 | return 0; | ||
597 | } | ||
598 | prev = buf; | ||
599 | } | ||
600 | } | ||
601 | |||
602 | static void vivi_vid_timeout(unsigned long data) | ||
603 | { | ||
604 | struct vivi_dev *dev = (struct vivi_dev *)data; | ||
605 | struct vivi_dmaqueue *vidq = &dev->vidq; | ||
606 | struct vivi_buffer *buf; | ||
607 | |||
608 | spin_lock(&dev->slock); | ||
609 | |||
610 | while (!list_empty(&vidq->active)) { | ||
611 | buf = list_entry(vidq->active.next, | ||
612 | struct vivi_buffer, vb.queue); | ||
613 | list_del(&buf->vb.queue); | ||
614 | buf->vb.state = VIDEOBUF_ERROR; | ||
615 | wake_up(&buf->vb.done); | ||
616 | printk(KERN_INFO "vivi/0: [%p/%d] timeout\n", buf, buf->vb.i); | ||
617 | } | ||
618 | restart_video_queue(vidq); | ||
619 | |||
620 | spin_unlock(&dev->slock); | ||
621 | } | ||
622 | |||
623 | /* ------------------------------------------------------------------ | 502 | /* ------------------------------------------------------------------ |
624 | Videobuf operations | 503 | Videobuf operations |
625 | ------------------------------------------------------------------*/ | 504 | ------------------------------------------------------------------*/ |
@@ -637,7 +516,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | |||
637 | while (*size * *count > vid_limit * 1024 * 1024) | 516 | while (*size * *count > vid_limit * 1024 * 1024) |
638 | (*count)--; | 517 | (*count)--; |
639 | 518 | ||
640 | dprintk(dev, 1, "%s, count=%d, size=%d\n", __FUNCTION__, | 519 | dprintk(dev, 1, "%s, count=%d, size=%d\n", __func__, |
641 | *count, *size); | 520 | *count, *size); |
642 | 521 | ||
643 | return 0; | 522 | return 0; |
@@ -648,13 +527,13 @@ static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) | |||
648 | struct vivi_fh *fh = vq->priv_data; | 527 | struct vivi_fh *fh = vq->priv_data; |
649 | struct vivi_dev *dev = fh->dev; | 528 | struct vivi_dev *dev = fh->dev; |
650 | 529 | ||
651 | dprintk(dev, 1, "%s\n", __FUNCTION__); | 530 | dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); |
652 | 531 | ||
653 | if (in_interrupt()) | 532 | if (in_interrupt()) |
654 | BUG(); | 533 | BUG(); |
655 | 534 | ||
656 | videobuf_waiton(&buf->vb, 0, 0); | ||
657 | videobuf_vmalloc_free(&buf->vb); | 535 | videobuf_vmalloc_free(&buf->vb); |
536 | dprintk(dev, 1, "free_buffer: freed\n"); | ||
658 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 537 | buf->vb.state = VIDEOBUF_NEEDS_INIT; |
659 | } | 538 | } |
660 | 539 | ||
@@ -667,28 +546,25 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
667 | struct vivi_fh *fh = vq->priv_data; | 546 | struct vivi_fh *fh = vq->priv_data; |
668 | struct vivi_dev *dev = fh->dev; | 547 | struct vivi_dev *dev = fh->dev; |
669 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 548 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); |
670 | int rc, init_buffer = 0; | 549 | int rc; |
671 | 550 | ||
672 | dprintk(dev, 1, "%s, field=%d\n", __FUNCTION__, field); | 551 | dprintk(dev, 1, "%s, field=%d\n", __func__, field); |
673 | 552 | ||
674 | BUG_ON(NULL == fh->fmt); | 553 | BUG_ON(NULL == fh->fmt); |
554 | |||
675 | if (fh->width < 48 || fh->width > norm_maxw() || | 555 | if (fh->width < 48 || fh->width > norm_maxw() || |
676 | fh->height < 32 || fh->height > norm_maxh()) | 556 | fh->height < 32 || fh->height > norm_maxh()) |
677 | return -EINVAL; | 557 | return -EINVAL; |
558 | |||
678 | buf->vb.size = fh->width*fh->height*2; | 559 | buf->vb.size = fh->width*fh->height*2; |
679 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 560 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
680 | return -EINVAL; | 561 | return -EINVAL; |
681 | 562 | ||
682 | if (buf->fmt != fh->fmt || | 563 | /* These properties only change when queue is idle, see s_fmt */ |
683 | buf->vb.width != fh->width || | 564 | buf->fmt = fh->fmt; |
684 | buf->vb.height != fh->height || | 565 | buf->vb.width = fh->width; |
685 | buf->vb.field != field) { | 566 | buf->vb.height = fh->height; |
686 | buf->fmt = fh->fmt; | 567 | buf->vb.field = field; |
687 | buf->vb.width = fh->width; | ||
688 | buf->vb.height = fh->height; | ||
689 | buf->vb.field = field; | ||
690 | init_buffer = 1; | ||
691 | } | ||
692 | 568 | ||
693 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 569 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
694 | rc = videobuf_iolock(vq, &buf->vb, NULL); | 570 | rc = videobuf_iolock(vq, &buf->vb, NULL); |
@@ -711,45 +587,12 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
711 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 587 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); |
712 | struct vivi_fh *fh = vq->priv_data; | 588 | struct vivi_fh *fh = vq->priv_data; |
713 | struct vivi_dev *dev = fh->dev; | 589 | struct vivi_dev *dev = fh->dev; |
714 | struct vivi_dmaqueue *vidq = &dev->vidq; | 590 | struct vivi_dmaqueue *vidq = &dev->vidq; |
715 | struct vivi_buffer *prev; | 591 | |
716 | 592 | dprintk(dev, 1, "%s\n", __func__); | |
717 | if (!list_empty(&vidq->queued)) { | 593 | |
718 | dprintk(dev, 1, "adding vb queue=0x%08lx\n", | 594 | buf->vb.state = VIDEOBUF_QUEUED; |
719 | (unsigned long)&buf->vb.queue); | 595 | list_add_tail(&buf->vb.queue, &vidq->active); |
720 | list_add_tail(&buf->vb.queue, &vidq->queued); | ||
721 | buf->vb.state = VIDEOBUF_QUEUED; | ||
722 | dprintk(dev, 2, "[%p/%d] buffer_queue - append to queued\n", | ||
723 | buf, buf->vb.i); | ||
724 | } else if (list_empty(&vidq->active)) { | ||
725 | list_add_tail(&buf->vb.queue, &vidq->active); | ||
726 | |||
727 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
728 | mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT); | ||
729 | dprintk(dev, 2, "[%p/%d] buffer_queue - first active\n", | ||
730 | buf, buf->vb.i); | ||
731 | |||
732 | vivi_start_thread(vidq); | ||
733 | } else { | ||
734 | prev = list_entry(vidq->active.prev, | ||
735 | struct vivi_buffer, vb.queue); | ||
736 | if (prev->vb.width == buf->vb.width && | ||
737 | prev->vb.height == buf->vb.height && | ||
738 | prev->fmt == buf->fmt) { | ||
739 | list_add_tail(&buf->vb.queue, &vidq->active); | ||
740 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
741 | dprintk(dev, 2, | ||
742 | "[%p/%d] buffer_queue - append to active\n", | ||
743 | buf, buf->vb.i); | ||
744 | |||
745 | } else { | ||
746 | list_add_tail(&buf->vb.queue, &vidq->queued); | ||
747 | buf->vb.state = VIDEOBUF_QUEUED; | ||
748 | dprintk(dev, 2, | ||
749 | "[%p/%d] buffer_queue - first queued\n", | ||
750 | buf, buf->vb.i); | ||
751 | } | ||
752 | } | ||
753 | } | 596 | } |
754 | 597 | ||
755 | static void buffer_release(struct videobuf_queue *vq, | 598 | static void buffer_release(struct videobuf_queue *vq, |
@@ -758,11 +601,8 @@ static void buffer_release(struct videobuf_queue *vq, | |||
758 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 601 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); |
759 | struct vivi_fh *fh = vq->priv_data; | 602 | struct vivi_fh *fh = vq->priv_data; |
760 | struct vivi_dev *dev = (struct vivi_dev *)fh->dev; | 603 | struct vivi_dev *dev = (struct vivi_dev *)fh->dev; |
761 | struct vivi_dmaqueue *vidq = &dev->vidq; | ||
762 | |||
763 | dprintk(dev, 1, "%s\n", __FUNCTION__); | ||
764 | 604 | ||
765 | vivi_stop_thread(vidq); | 605 | dprintk(dev, 1, "%s\n", __func__); |
766 | 606 | ||
767 | free_buffer(vq, buf); | 607 | free_buffer(vq, buf); |
768 | } | 608 | } |
@@ -869,17 +709,31 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
869 | struct v4l2_format *f) | 709 | struct v4l2_format *f) |
870 | { | 710 | { |
871 | struct vivi_fh *fh = priv; | 711 | struct vivi_fh *fh = priv; |
712 | struct videobuf_queue *q = &fh->vb_vidq; | ||
713 | |||
872 | int ret = vidioc_try_fmt_cap(file, fh, f); | 714 | int ret = vidioc_try_fmt_cap(file, fh, f); |
873 | if (ret < 0) | 715 | if (ret < 0) |
874 | return (ret); | 716 | return (ret); |
875 | 717 | ||
718 | mutex_lock(&q->vb_lock); | ||
719 | |||
720 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { | ||
721 | dprintk(fh->dev, 1, "%s queue busy\n", __func__); | ||
722 | ret = -EBUSY; | ||
723 | goto out; | ||
724 | } | ||
725 | |||
876 | fh->fmt = &format; | 726 | fh->fmt = &format; |
877 | fh->width = f->fmt.pix.width; | 727 | fh->width = f->fmt.pix.width; |
878 | fh->height = f->fmt.pix.height; | 728 | fh->height = f->fmt.pix.height; |
879 | fh->vb_vidq.field = f->fmt.pix.field; | 729 | fh->vb_vidq.field = f->fmt.pix.field; |
880 | fh->type = f->type; | 730 | fh->type = f->type; |
881 | 731 | ||
882 | return (0); | 732 | ret = 0; |
733 | out: | ||
734 | mutex_unlock(&q->vb_lock); | ||
735 | |||
736 | return (ret); | ||
883 | } | 737 | } |
884 | 738 | ||
885 | static int vidioc_reqbufs(struct file *file, void *priv, | 739 | static int vidioc_reqbufs(struct file *file, void *priv, |
@@ -1036,6 +890,7 @@ static int vivi_open(struct inode *inode, struct file *file) | |||
1036 | struct vivi_dev *dev; | 890 | struct vivi_dev *dev; |
1037 | struct vivi_fh *fh; | 891 | struct vivi_fh *fh; |
1038 | int i; | 892 | int i; |
893 | int retval = 0; | ||
1039 | 894 | ||
1040 | printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); | 895 | printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); |
1041 | 896 | ||
@@ -1045,9 +900,15 @@ static int vivi_open(struct inode *inode, struct file *file) | |||
1045 | return -ENODEV; | 900 | return -ENODEV; |
1046 | 901 | ||
1047 | found: | 902 | found: |
1048 | /* If more than one user, mutex should be added */ | 903 | mutex_lock(&dev->mutex); |
1049 | dev->users++; | 904 | dev->users++; |
1050 | 905 | ||
906 | if (dev->users > 1) { | ||
907 | dev->users--; | ||
908 | retval = -EBUSY; | ||
909 | goto unlock; | ||
910 | } | ||
911 | |||
1051 | dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, | 912 | dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, |
1052 | v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); | 913 | v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); |
1053 | 914 | ||
@@ -1055,8 +916,13 @@ found: | |||
1055 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 916 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
1056 | if (NULL == fh) { | 917 | if (NULL == fh) { |
1057 | dev->users--; | 918 | dev->users--; |
1058 | return -ENOMEM; | 919 | retval = -ENOMEM; |
920 | goto unlock; | ||
1059 | } | 921 | } |
922 | unlock: | ||
923 | mutex_unlock(&dev->mutex); | ||
924 | if (retval) | ||
925 | return retval; | ||
1060 | 926 | ||
1061 | file->private_data = fh; | 927 | file->private_data = fh; |
1062 | fh->dev = dev; | 928 | fh->dev = dev; |
@@ -1084,6 +950,8 @@ found: | |||
1084 | NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED, | 950 | NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED, |
1085 | sizeof(struct vivi_buffer), fh); | 951 | sizeof(struct vivi_buffer), fh); |
1086 | 952 | ||
953 | vivi_start_thread(fh); | ||
954 | |||
1087 | return 0; | 955 | return 0; |
1088 | } | 956 | } |
1089 | 957 | ||
@@ -1106,7 +974,7 @@ vivi_poll(struct file *file, struct poll_table_struct *wait) | |||
1106 | struct vivi_dev *dev = fh->dev; | 974 | struct vivi_dev *dev = fh->dev; |
1107 | struct videobuf_queue *q = &fh->vb_vidq; | 975 | struct videobuf_queue *q = &fh->vb_vidq; |
1108 | 976 | ||
1109 | dprintk(dev, 1, "%s\n", __FUNCTION__); | 977 | dprintk(dev, 1, "%s\n", __func__); |
1110 | 978 | ||
1111 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) | 979 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) |
1112 | return POLLERR; | 980 | return POLLERR; |
@@ -1128,7 +996,9 @@ static int vivi_close(struct inode *inode, struct file *file) | |||
1128 | 996 | ||
1129 | kfree(fh); | 997 | kfree(fh); |
1130 | 998 | ||
999 | mutex_lock(&dev->mutex); | ||
1131 | dev->users--; | 1000 | dev->users--; |
1001 | mutex_unlock(&dev->mutex); | ||
1132 | 1002 | ||
1133 | dprintk(dev, 1, "close called (minor=%d, users=%d)\n", | 1003 | dprintk(dev, 1, "close called (minor=%d, users=%d)\n", |
1134 | minor, dev->users); | 1004 | minor, dev->users); |
@@ -1182,6 +1052,7 @@ static const struct file_operations vivi_fops = { | |||
1182 | .read = vivi_read, | 1052 | .read = vivi_read, |
1183 | .poll = vivi_poll, | 1053 | .poll = vivi_poll, |
1184 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ | 1054 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ |
1055 | .compat_ioctl = v4l_compat_ioctl32, | ||
1185 | .mmap = vivi_mmap, | 1056 | .mmap = vivi_mmap, |
1186 | .llseek = no_llseek, | 1057 | .llseek = no_llseek, |
1187 | }; | 1058 | }; |
@@ -1236,16 +1107,11 @@ static int __init vivi_init(void) | |||
1236 | 1107 | ||
1237 | /* init video dma queues */ | 1108 | /* init video dma queues */ |
1238 | INIT_LIST_HEAD(&dev->vidq.active); | 1109 | INIT_LIST_HEAD(&dev->vidq.active); |
1239 | INIT_LIST_HEAD(&dev->vidq.queued); | ||
1240 | init_waitqueue_head(&dev->vidq.wq); | 1110 | init_waitqueue_head(&dev->vidq.wq); |
1241 | 1111 | ||
1242 | /* initialize locks */ | 1112 | /* initialize locks */ |
1243 | mutex_init(&dev->lock); | ||
1244 | spin_lock_init(&dev->slock); | 1113 | spin_lock_init(&dev->slock); |
1245 | 1114 | mutex_init(&dev->mutex); | |
1246 | dev->vidq.timeout.function = vivi_vid_timeout; | ||
1247 | dev->vidq.timeout.data = (unsigned long)dev; | ||
1248 | init_timer(&dev->vidq.timeout); | ||
1249 | 1115 | ||
1250 | vfd = video_device_alloc(); | 1116 | vfd = video_device_alloc(); |
1251 | if (NULL == vfd) | 1117 | if (NULL == vfd) |
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index a9133858e913..35293029da02 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #define I2C_VPX3220 0x86 | 40 | #define I2C_VPX3220 0x86 |
41 | #define VPX3220_DEBUG KERN_DEBUG "vpx3220: " | 41 | #define VPX3220_DEBUG KERN_DEBUG "vpx3220: " |
42 | 42 | ||
43 | static int debug = 0; | 43 | static int debug; |
44 | module_param(debug, int, 0); | 44 | module_param(debug, int, 0); |
45 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 45 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
46 | 46 | ||
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 08aaae07c7e0..33f702698a56 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c | |||
@@ -61,10 +61,10 @@ | |||
61 | #include <media/v4l2-common.h> | 61 | #include <media/v4l2-common.h> |
62 | #include <linux/parport.h> | 62 | #include <linux/parport.h> |
63 | 63 | ||
64 | //#define DEBUG // Undef me for production | 64 | /*#define DEBUG*/ /* Undef me for production */ |
65 | 65 | ||
66 | #ifdef DEBUG | 66 | #ifdef DEBUG |
67 | #define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __FUNCTION__ , ##a) | 67 | #define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __func__ , ##a) |
68 | #else | 68 | #else |
69 | #define DPRINTF(x...) | 69 | #define DPRINTF(x...) |
70 | #endif | 70 | #endif |
@@ -134,7 +134,7 @@ MODULE_PARM_DESC(pardev, "pardev: where to search for\n\ | |||
134 | \tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n\ | 134 | \tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n\ |
135 | \tcam 1 to parport3 and search every parport for cam 2 etc..."); | 135 | \tcam 1 to parport3 and search every parport for cam 2 etc..."); |
136 | 136 | ||
137 | static int parmode = 0; | 137 | static int parmode; |
138 | module_param(parmode, int, 0); | 138 | module_param(parmode, int, 0); |
139 | MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp"); | 139 | MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp"); |
140 | 140 | ||
@@ -188,7 +188,9 @@ static const struct file_operations w9966_fops = { | |||
188 | .open = video_exclusive_open, | 188 | .open = video_exclusive_open, |
189 | .release = video_exclusive_release, | 189 | .release = video_exclusive_release, |
190 | .ioctl = w9966_v4l_ioctl, | 190 | .ioctl = w9966_v4l_ioctl, |
191 | #ifdef CONFIG_COMPAT | ||
191 | .compat_ioctl = v4l_compat_ioctl32, | 192 | .compat_ioctl = v4l_compat_ioctl32, |
193 | #endif | ||
192 | .read = w9966_v4l_read, | 194 | .read = w9966_v4l_read, |
193 | .llseek = no_llseek, | 195 | .llseek = no_llseek, |
194 | }; | 196 | }; |
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index 2ae1430f5f7d..840522442d07 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c | |||
@@ -3461,7 +3461,9 @@ static const struct file_operations w9968cf_fops = { | |||
3461 | .release = w9968cf_release, | 3461 | .release = w9968cf_release, |
3462 | .read = w9968cf_read, | 3462 | .read = w9968cf_read, |
3463 | .ioctl = w9968cf_ioctl, | 3463 | .ioctl = w9968cf_ioctl, |
3464 | #ifdef CONFIG_COMPAT | ||
3464 | .compat_ioctl = v4l_compat_ioctl32, | 3465 | .compat_ioctl = v4l_compat_ioctl32, |
3466 | #endif | ||
3465 | .mmap = w9968cf_mmap, | 3467 | .mmap = w9968cf_mmap, |
3466 | .llseek = no_llseek, | 3468 | .llseek = no_llseek, |
3467 | }; | 3469 | }; |
@@ -3481,7 +3483,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3481 | enum w9968cf_model_id mod_id; | 3483 | enum w9968cf_model_id mod_id; |
3482 | struct list_head* ptr; | 3484 | struct list_head* ptr; |
3483 | u8 sc = 0; /* number of simultaneous cameras */ | 3485 | u8 sc = 0; /* number of simultaneous cameras */ |
3484 | static unsigned short dev_nr = 0; /* we are handling device number n */ | 3486 | static unsigned short dev_nr; /* 0 - we are handling device number n */ |
3485 | 3487 | ||
3486 | if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor && | 3488 | if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor && |
3487 | le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct) | 3489 | le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct) |
diff --git a/drivers/media/video/w9968cf.h b/drivers/media/video/w9968cf.h index ec7696e8f1fa..3c95316bc030 100644 --- a/drivers/media/video/w9968cf.h +++ b/drivers/media/video/w9968cf.h | |||
@@ -298,7 +298,7 @@ struct w9968cf_device { | |||
298 | dev_warn(&cam->dev, fmt "\n", ## args); \ | 298 | dev_warn(&cam->dev, fmt "\n", ## args); \ |
299 | else if ((level) >= 5) \ | 299 | else if ((level) >= 5) \ |
300 | dev_info(&cam->dev, "[%s:%d] " fmt "\n", \ | 300 | dev_info(&cam->dev, "[%s:%d] " fmt "\n", \ |
301 | __FUNCTION__, __LINE__ , ## args); \ | 301 | __func__, __LINE__ , ## args); \ |
302 | } \ | 302 | } \ |
303 | } | 303 | } |
304 | /* For generic kernel (not device specific) messages */ | 304 | /* For generic kernel (not device specific) messages */ |
@@ -309,7 +309,7 @@ struct w9968cf_device { | |||
309 | if ((level) >= 1 && (level) <= 4) \ | 309 | if ((level) >= 1 && (level) <= 4) \ |
310 | pr_info("w9968cf: " fmt "\n", ## args); \ | 310 | pr_info("w9968cf: " fmt "\n", ## args); \ |
311 | else if ((level) >= 5) \ | 311 | else if ((level) >= 5) \ |
312 | pr_debug("w9968cf: [%s:%d] " fmt "\n", __FUNCTION__, \ | 312 | pr_debug("w9968cf: [%s:%d] " fmt "\n", __func__, \ |
313 | __LINE__ , ## args); \ | 313 | __LINE__ , ## args); \ |
314 | } \ | 314 | } \ |
315 | } | 315 | } |
@@ -321,7 +321,7 @@ struct w9968cf_device { | |||
321 | 321 | ||
322 | #undef PDBG | 322 | #undef PDBG |
323 | #define PDBG(fmt, args...) \ | 323 | #define PDBG(fmt, args...) \ |
324 | dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args); | 324 | dev_info(&cam->dev, "[%s:%d] " fmt "\n", __func__, __LINE__ , ## args); |
325 | 325 | ||
326 | #undef PDBGG | 326 | #undef PDBGG |
327 | #define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */ | 327 | #define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */ |
diff --git a/drivers/media/video/zc0301/zc0301.h b/drivers/media/video/zc0301/zc0301.h index a2de50efa31a..7bbab541a309 100644 --- a/drivers/media/video/zc0301/zc0301.h +++ b/drivers/media/video/zc0301/zc0301.h | |||
@@ -160,7 +160,7 @@ do { \ | |||
160 | dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ | 160 | dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ |
161 | else if ((level) >= 3) \ | 161 | else if ((level) >= 3) \ |
162 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \ | 162 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \ |
163 | __FILE__, __FUNCTION__, __LINE__ , ## args); \ | 163 | __FILE__, __func__, __LINE__ , ## args); \ |
164 | } \ | 164 | } \ |
165 | } while (0) | 165 | } while (0) |
166 | # define KDBG(level, fmt, args...) \ | 166 | # define KDBG(level, fmt, args...) \ |
@@ -170,7 +170,7 @@ do { \ | |||
170 | pr_info("zc0301: " fmt "\n", ## args); \ | 170 | pr_info("zc0301: " fmt "\n", ## args); \ |
171 | else if ((level) == 3) \ | 171 | else if ((level) == 3) \ |
172 | pr_debug("sn9c102: [%s:%s:%d] " fmt "\n", __FILE__, \ | 172 | pr_debug("sn9c102: [%s:%s:%d] " fmt "\n", __FILE__, \ |
173 | __FUNCTION__, __LINE__ , ## args); \ | 173 | __func__, __LINE__ , ## args); \ |
174 | } \ | 174 | } \ |
175 | } while (0) | 175 | } while (0) |
176 | # define V4LDBG(level, name, cmd) \ | 176 | # define V4LDBG(level, name, cmd) \ |
@@ -186,7 +186,7 @@ do { \ | |||
186 | 186 | ||
187 | #undef PDBG | 187 | #undef PDBG |
188 | #define PDBG(fmt, args...) \ | 188 | #define PDBG(fmt, args...) \ |
189 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \ | 189 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \ |
190 | __LINE__ , ## args) | 190 | __LINE__ , ## args) |
191 | 191 | ||
192 | #undef PDBGG | 192 | #undef PDBGG |
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c index 2c5665c82442..363dd2b9475c 100644 --- a/drivers/media/video/zc0301/zc0301_core.c +++ b/drivers/media/video/zc0301/zc0301_core.c | |||
@@ -1925,7 +1925,9 @@ static const struct file_operations zc0301_fops = { | |||
1925 | .open = zc0301_open, | 1925 | .open = zc0301_open, |
1926 | .release = zc0301_release, | 1926 | .release = zc0301_release, |
1927 | .ioctl = zc0301_ioctl, | 1927 | .ioctl = zc0301_ioctl, |
1928 | #ifdef CONFIG_COMPAT | ||
1928 | .compat_ioctl = v4l_compat_ioctl32, | 1929 | .compat_ioctl = v4l_compat_ioctl32, |
1930 | #endif | ||
1929 | .read = zc0301_read, | 1931 | .read = zc0301_read, |
1930 | .poll = zc0301_poll, | 1932 | .poll = zc0301_poll, |
1931 | .mmap = zc0301_mmap, | 1933 | .mmap = zc0301_mmap, |
@@ -1939,7 +1941,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
1939 | { | 1941 | { |
1940 | struct usb_device *udev = interface_to_usbdev(intf); | 1942 | struct usb_device *udev = interface_to_usbdev(intf); |
1941 | struct zc0301_device* cam; | 1943 | struct zc0301_device* cam; |
1942 | static unsigned int dev_nr = 0; | 1944 | static unsigned int dev_nr; |
1943 | unsigned int i; | 1945 | unsigned int i; |
1944 | int err = 0; | 1946 | int err = 0; |
1945 | 1947 | ||
diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h index 498a43c1f2b1..81cc3b00a079 100644 --- a/drivers/media/video/zoran.h +++ b/drivers/media/video/zoran.h | |||
@@ -243,10 +243,8 @@ struct zoran_format { | |||
243 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 243 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
244 | int palette; | 244 | int palette; |
245 | #endif | 245 | #endif |
246 | #ifdef CONFIG_VIDEO_V4L2 | ||
247 | __u32 fourcc; | 246 | __u32 fourcc; |
248 | int colorspace; | 247 | int colorspace; |
249 | #endif | ||
250 | int depth; | 248 | int depth; |
251 | __u32 flags; | 249 | __u32 flags; |
252 | __u32 vfespfr; | 250 | __u32 vfespfr; |
@@ -271,20 +269,6 @@ struct zoran_v4l_settings { | |||
271 | const struct zoran_format *format; /* capture format */ | 269 | const struct zoran_format *format; /* capture format */ |
272 | }; | 270 | }; |
273 | 271 | ||
274 | /* whoops, this one is undeclared if !v4l2 */ | ||
275 | #ifndef CONFIG_VIDEO_V4L2 | ||
276 | struct v4l2_jpegcompression { | ||
277 | int quality; | ||
278 | int APPn; | ||
279 | int APP_len; | ||
280 | char APP_data[60]; | ||
281 | int COM_len; | ||
282 | char COM_data[60]; | ||
283 | __u32 jpeg_markers; | ||
284 | __u8 reserved[116]; | ||
285 | }; | ||
286 | #endif | ||
287 | |||
288 | /* jpg-capture/-playback settings */ | 272 | /* jpg-capture/-playback settings */ |
289 | struct zoran_jpg_settings { | 273 | struct zoran_jpg_settings { |
290 | int decimation; /* this bit is used to set everything to default */ | 274 | int decimation; /* this bit is used to set everything to default */ |
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c index 690281bb59ee..006d48847e24 100644 --- a/drivers/media/video/zoran_card.c +++ b/drivers/media/video/zoran_card.c | |||
@@ -83,7 +83,7 @@ MODULE_PARM_DESC(decoder, "i2c TV decoder"); | |||
83 | or set in in a VIDIOCSFBUF ioctl | 83 | or set in in a VIDIOCSFBUF ioctl |
84 | */ | 84 | */ |
85 | 85 | ||
86 | static unsigned long vidmem = 0; /* Video memory base address */ | 86 | static unsigned long vidmem; /* default = 0 - Video memory base address */ |
87 | module_param(vidmem, ulong, 0444); | 87 | module_param(vidmem, ulong, 0444); |
88 | MODULE_PARM_DESC(vidmem, "Default video memory base address"); | 88 | MODULE_PARM_DESC(vidmem, "Default video memory base address"); |
89 | 89 | ||
@@ -91,7 +91,7 @@ MODULE_PARM_DESC(vidmem, "Default video memory base address"); | |||
91 | Default input and video norm at startup of the driver. | 91 | Default input and video norm at startup of the driver. |
92 | */ | 92 | */ |
93 | 93 | ||
94 | static unsigned int default_input = 0; /* 0=Composite, 1=S-Video */ | 94 | static unsigned int default_input; /* default 0 = Composite, 1 = S-Video */ |
95 | module_param(default_input, uint, 0444); | 95 | module_param(default_input, uint, 0444); |
96 | MODULE_PARM_DESC(default_input, | 96 | MODULE_PARM_DESC(default_input, |
97 | "Default input (0=Composite, 1=S-Video, 2=Internal)"); | 97 | "Default input (0=Composite, 1=S-Video, 2=Internal)"); |
@@ -101,7 +101,7 @@ module_param(default_mux, int, 0644); | |||
101 | MODULE_PARM_DESC(default_mux, | 101 | MODULE_PARM_DESC(default_mux, |
102 | "Default 6 Eyes mux setting (Input selection)"); | 102 | "Default 6 Eyes mux setting (Input selection)"); |
103 | 103 | ||
104 | static int default_norm = 0; /* 0=PAL, 1=NTSC 2=SECAM */ | 104 | static int default_norm; /* default 0 = PAL, 1 = NTSC 2 = SECAM */ |
105 | module_param(default_norm, int, 0444); | 105 | module_param(default_norm, int, 0444); |
106 | MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); | 106 | MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); |
107 | 107 | ||
diff --git a/drivers/media/video/zoran_card.h b/drivers/media/video/zoran_card.h index 8444ca0a5f3f..1b5c4171cf9c 100644 --- a/drivers/media/video/zoran_card.h +++ b/drivers/media/video/zoran_card.h | |||
@@ -50,4 +50,6 @@ extern int zoran_check_jpg_settings(struct zoran *zr, | |||
50 | extern void zoran_open_init_params(struct zoran *zr); | 50 | extern void zoran_open_init_params(struct zoran *zr); |
51 | extern void zoran_vdev_release(struct video_device *vdev); | 51 | extern void zoran_vdev_release(struct video_device *vdev); |
52 | 52 | ||
53 | void zr36016_write(struct videocodec *codec, u16 reg, u32 val); | ||
54 | |||
53 | #endif /* __ZORAN_CARD_H__ */ | 55 | #endif /* __ZORAN_CARD_H__ */ |
diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c index f97c20692057..7b60533efe45 100644 --- a/drivers/media/video/zoran_device.c +++ b/drivers/media/video/zoran_device.c | |||
@@ -60,7 +60,8 @@ | |||
60 | 60 | ||
61 | extern const struct zoran_format zoran_formats[]; | 61 | extern const struct zoran_format zoran_formats[]; |
62 | 62 | ||
63 | static int lml33dpath = 0; /* 1 will use digital path in capture | 63 | static int lml33dpath; /* default = 0 |
64 | * 1 will use digital path in capture | ||
64 | * mode instead of analog. It can be | 65 | * mode instead of analog. It can be |
65 | * used for picture adjustments using | 66 | * used for picture adjustments using |
66 | * tool like xawtv while watching image | 67 | * tool like xawtv while watching image |
@@ -927,11 +928,6 @@ count_reset_interrupt (struct zoran *zr) | |||
927 | return isr; | 928 | return isr; |
928 | } | 929 | } |
929 | 930 | ||
930 | /* hack */ | ||
931 | extern void zr36016_write (struct videocodec *codec, | ||
932 | u16 reg, | ||
933 | u32 val); | ||
934 | |||
935 | void | 931 | void |
936 | jpeg_start (struct zoran *zr) | 932 | jpeg_start (struct zoran *zr) |
937 | { | 933 | { |
@@ -987,7 +983,7 @@ void | |||
987 | zr36057_enable_jpg (struct zoran *zr, | 983 | zr36057_enable_jpg (struct zoran *zr, |
988 | enum zoran_codec_mode mode) | 984 | enum zoran_codec_mode mode) |
989 | { | 985 | { |
990 | static int zero = 0; | 986 | static int zero; |
991 | static int one = 1; | 987 | static int one = 1; |
992 | struct vfe_settings cap; | 988 | struct vfe_settings cap; |
993 | int field_size = | 989 | int field_size = |
@@ -1726,7 +1722,7 @@ decoder_command (struct zoran *zr, | |||
1726 | return -EIO; | 1722 | return -EIO; |
1727 | 1723 | ||
1728 | if (zr->card.type == LML33 && | 1724 | if (zr->card.type == LML33 && |
1729 | (cmd == DECODER_SET_NORM || DECODER_SET_INPUT)) { | 1725 | (cmd == DECODER_SET_NORM || cmd == DECODER_SET_INPUT)) { |
1730 | int res; | 1726 | int res; |
1731 | 1727 | ||
1732 | // Bt819 needs to reset its FIFO buffer using #FRST pin and | 1728 | // Bt819 needs to reset its FIFO buffer using #FRST pin and |
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index fea4946ee713..0134bec1e399 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c | |||
@@ -85,7 +85,6 @@ | |||
85 | #include "zoran_device.h" | 85 | #include "zoran_device.h" |
86 | #include "zoran_card.h" | 86 | #include "zoran_card.h" |
87 | 87 | ||
88 | #ifdef CONFIG_VIDEO_V4L2 | ||
89 | /* we declare some card type definitions here, they mean | 88 | /* we declare some card type definitions here, they mean |
90 | * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */ | 89 | * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */ |
91 | #define ZORAN_V4L2_VID_FLAGS ( \ | 90 | #define ZORAN_V4L2_VID_FLAGS ( \ |
@@ -94,19 +93,15 @@ | |||
94 | V4L2_CAP_VIDEO_OUTPUT |\ | 93 | V4L2_CAP_VIDEO_OUTPUT |\ |
95 | V4L2_CAP_VIDEO_OVERLAY \ | 94 | V4L2_CAP_VIDEO_OVERLAY \ |
96 | ) | 95 | ) |
97 | #endif | ||
98 | 96 | ||
99 | #include <asm/byteorder.h> | 97 | #include <asm/byteorder.h> |
100 | 98 | ||
101 | #if defined(CONFIG_VIDEO_V4L2) && defined(CONFIG_VIDEO_V4L1_COMPAT) | 99 | #if defined(CONFIG_VIDEO_V4L1_COMPAT) |
102 | #define ZFMT(pal, fcc, cs) \ | 100 | #define ZFMT(pal, fcc, cs) \ |
103 | .palette = (pal), .fourcc = (fcc), .colorspace = (cs) | 101 | .palette = (pal), .fourcc = (fcc), .colorspace = (cs) |
104 | #elif defined(CONFIG_VIDEO_V4L2) | ||
105 | #define ZFMT(pal, fcc, cs) \ | ||
106 | .fourcc = (fcc), .colorspace = (cs) | ||
107 | #else | 102 | #else |
108 | #define ZFMT(pal, fcc, cs) \ | 103 | #define ZFMT(pal, fcc, cs) \ |
109 | .palette = (pal) | 104 | .fourcc = (fcc), .colorspace = (cs) |
110 | #endif | 105 | #endif |
111 | 106 | ||
112 | const struct zoran_format zoran_formats[] = { | 107 | const struct zoran_format zoran_formats[] = { |
@@ -205,11 +200,10 @@ extern int jpg_nbufs; | |||
205 | extern int jpg_bufsize; | 200 | extern int jpg_bufsize; |
206 | extern int pass_through; | 201 | extern int pass_through; |
207 | 202 | ||
208 | static int lock_norm = 0; /* 1=Don't change TV standard (norm) */ | 203 | static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */ |
209 | module_param(lock_norm, int, 0644); | 204 | module_param(lock_norm, int, 0644); |
210 | MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)"); | 205 | MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)"); |
211 | 206 | ||
212 | #ifdef CONFIG_VIDEO_V4L2 | ||
213 | /* small helper function for calculating buffersizes for v4l2 | 207 | /* small helper function for calculating buffersizes for v4l2 |
214 | * we calculate the nearest higher power-of-two, which | 208 | * we calculate the nearest higher power-of-two, which |
215 | * will be the recommended buffersize */ | 209 | * will be the recommended buffersize */ |
@@ -232,7 +226,6 @@ zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings) | |||
232 | return 8192; | 226 | return 8192; |
233 | return result; | 227 | return result; |
234 | } | 228 | } |
235 | #endif | ||
236 | 229 | ||
237 | /* forward references */ | 230 | /* forward references */ |
238 | static void v4l_fbuffer_free(struct file *file); | 231 | static void v4l_fbuffer_free(struct file *file); |
@@ -1709,7 +1702,6 @@ setup_overlay (struct file *file, | |||
1709 | return wait_grab_pending(zr); | 1702 | return wait_grab_pending(zr); |
1710 | } | 1703 | } |
1711 | 1704 | ||
1712 | #ifdef CONFIG_VIDEO_V4L2 | ||
1713 | /* get the status of a buffer in the clients buffer queue */ | 1705 | /* get the status of a buffer in the clients buffer queue */ |
1714 | static int | 1706 | static int |
1715 | zoran_v4l2_buffer_status (struct file *file, | 1707 | zoran_v4l2_buffer_status (struct file *file, |
@@ -1815,7 +1807,6 @@ zoran_v4l2_buffer_status (struct file *file, | |||
1815 | 1807 | ||
1816 | return 0; | 1808 | return 0; |
1817 | } | 1809 | } |
1818 | #endif | ||
1819 | 1810 | ||
1820 | static int | 1811 | static int |
1821 | zoran_set_norm (struct zoran *zr, | 1812 | zoran_set_norm (struct zoran *zr, |
@@ -2624,8 +2615,6 @@ zoran_do_ioctl (struct inode *inode, | |||
2624 | } | 2615 | } |
2625 | break; | 2616 | break; |
2626 | 2617 | ||
2627 | #ifdef CONFIG_VIDEO_V4L2 | ||
2628 | |||
2629 | /* The new video4linux2 capture interface - much nicer than video4linux1, since | 2618 | /* The new video4linux2 capture interface - much nicer than video4linux1, since |
2630 | * it allows for integrating the JPEG capturing calls inside standard v4l2 | 2619 | * it allows for integrating the JPEG capturing calls inside standard v4l2 |
2631 | */ | 2620 | */ |
@@ -4197,7 +4186,6 @@ zoran_do_ioctl (struct inode *inode, | |||
4197 | return 0; | 4186 | return 0; |
4198 | } | 4187 | } |
4199 | break; | 4188 | break; |
4200 | #endif | ||
4201 | 4189 | ||
4202 | default: | 4190 | default: |
4203 | dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n", | 4191 | dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n", |
@@ -4247,7 +4235,7 @@ zoran_poll (struct file *file, | |||
4247 | dprintk(3, | 4235 | dprintk(3, |
4248 | KERN_DEBUG | 4236 | KERN_DEBUG |
4249 | "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n", | 4237 | "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n", |
4250 | ZR_DEVNAME(zr), __FUNCTION__, | 4238 | ZR_DEVNAME(zr), __func__, |
4251 | "FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail, | 4239 | "FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail, |
4252 | "UPMD"[zr->v4l_buffers.buffer[frame].state], | 4240 | "UPMD"[zr->v4l_buffers.buffer[frame].state], |
4253 | zr->v4l_pend_tail, zr->v4l_pend_head); | 4241 | zr->v4l_pend_tail, zr->v4l_pend_head); |
@@ -4269,7 +4257,7 @@ zoran_poll (struct file *file, | |||
4269 | dprintk(3, | 4257 | dprintk(3, |
4270 | KERN_DEBUG | 4258 | KERN_DEBUG |
4271 | "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n", | 4259 | "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n", |
4272 | ZR_DEVNAME(zr), __FUNCTION__, | 4260 | ZR_DEVNAME(zr), __func__, |
4273 | "FAL"[fh->jpg_buffers.active], zr->jpg_que_tail, | 4261 | "FAL"[fh->jpg_buffers.active], zr->jpg_que_tail, |
4274 | "UPMD"[zr->jpg_buffers.buffer[frame].state], | 4262 | "UPMD"[zr->jpg_buffers.buffer[frame].state], |
4275 | zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head); | 4263 | zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head); |
@@ -4644,7 +4632,9 @@ static const struct file_operations zoran_fops = { | |||
4644 | .open = zoran_open, | 4632 | .open = zoran_open, |
4645 | .release = zoran_close, | 4633 | .release = zoran_close, |
4646 | .ioctl = zoran_ioctl, | 4634 | .ioctl = zoran_ioctl, |
4635 | #ifdef CONFIG_COMPAT | ||
4647 | .compat_ioctl = v4l_compat_ioctl32, | 4636 | .compat_ioctl = v4l_compat_ioctl32, |
4637 | #endif | ||
4648 | .llseek = no_llseek, | 4638 | .llseek = no_llseek, |
4649 | .read = zoran_read, | 4639 | .read = zoran_read, |
4650 | .write = zoran_write, | 4640 | .write = zoran_write, |
@@ -4655,9 +4645,7 @@ static const struct file_operations zoran_fops = { | |||
4655 | struct video_device zoran_template __devinitdata = { | 4645 | struct video_device zoran_template __devinitdata = { |
4656 | .name = ZORAN_NAME, | 4646 | .name = ZORAN_NAME, |
4657 | .type = ZORAN_VID_TYPE, | 4647 | .type = ZORAN_VID_TYPE, |
4658 | #ifdef CONFIG_VIDEO_V4L2 | ||
4659 | .type2 = ZORAN_V4L2_VID_FLAGS, | 4648 | .type2 = ZORAN_V4L2_VID_FLAGS, |
4660 | #endif | ||
4661 | .fops = &zoran_fops, | 4649 | .fops = &zoran_fops, |
4662 | .release = &zoran_vdev_release, | 4650 | .release = &zoran_vdev_release, |
4663 | .minor = -1 | 4651 | .minor = -1 |
diff --git a/drivers/media/video/zr36016.c b/drivers/media/video/zr36016.c index dd084555da8f..00d132bcd1e4 100644 --- a/drivers/media/video/zr36016.c +++ b/drivers/media/video/zr36016.c | |||
@@ -55,11 +55,10 @@ | |||
55 | #define MAX_CODECS 20 | 55 | #define MAX_CODECS 20 |
56 | 56 | ||
57 | /* amount of chips attached via this driver */ | 57 | /* amount of chips attached via this driver */ |
58 | static int zr36016_codecs = 0; | 58 | static int zr36016_codecs; |
59 | 59 | ||
60 | /* debugging is available via module parameter */ | 60 | /* debugging is available via module parameter */ |
61 | 61 | static int debug; | |
62 | static int debug = 0; | ||
63 | module_param(debug, int, 0); | 62 | module_param(debug, int, 0); |
64 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | 63 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); |
65 | 64 | ||
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c index faae4ec3ea0b..cf8b271a1c8f 100644 --- a/drivers/media/video/zr36050.c +++ b/drivers/media/video/zr36050.c | |||
@@ -52,11 +52,10 @@ | |||
52 | #define MAX_CODECS 20 | 52 | #define MAX_CODECS 20 |
53 | 53 | ||
54 | /* amount of chips attached via this driver */ | 54 | /* amount of chips attached via this driver */ |
55 | static int zr36050_codecs = 0; | 55 | static int zr36050_codecs; |
56 | 56 | ||
57 | /* debugging is available via module parameter */ | 57 | /* debugging is available via module parameter */ |
58 | 58 | static int debug; | |
59 | static int debug = 0; | ||
60 | module_param(debug, int, 0); | 59 | module_param(debug, int, 0); |
61 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | 60 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); |
62 | 61 | ||
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c index 7849b65969d0..8e74054d5ef1 100644 --- a/drivers/media/video/zr36060.c +++ b/drivers/media/video/zr36060.c | |||
@@ -52,14 +52,14 @@ | |||
52 | #define MAX_CODECS 20 | 52 | #define MAX_CODECS 20 |
53 | 53 | ||
54 | /* amount of chips attached via this driver */ | 54 | /* amount of chips attached via this driver */ |
55 | static int zr36060_codecs = 0; | 55 | static int zr36060_codecs; |
56 | 56 | ||
57 | static int low_bitrate = 0; | 57 | static int low_bitrate; |
58 | module_param(low_bitrate, bool, 0); | 58 | module_param(low_bitrate, bool, 0); |
59 | MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate"); | 59 | MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate"); |
60 | 60 | ||
61 | /* debugging is available via module parameter */ | 61 | /* debugging is available via module parameter */ |
62 | static int debug = 0; | 62 | static int debug; |
63 | module_param(debug, int, 0); | 63 | module_param(debug, int, 0); |
64 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | 64 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); |
65 | 65 | ||
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index 04949c823654..a0e49dc66301 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c | |||
@@ -62,8 +62,8 @@ | |||
62 | 62 | ||
63 | 63 | ||
64 | /* Module parameters */ | 64 | /* Module parameters */ |
65 | static int debug = 0; | 65 | static int debug; |
66 | static int mode = 0; | 66 | static int mode; |
67 | 67 | ||
68 | 68 | ||
69 | /* Module parameters interface */ | 69 | /* Module parameters interface */ |