diff options
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r-- | drivers/media/video/cx18/Kconfig | 2 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-av-audio.c | 111 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.h | 1 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-firmware.c | 54 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-ioctl.c | 92 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-streams.c | 5 |
6 files changed, 157 insertions, 108 deletions
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig index 9aefdc5ea79a..ef48565de7f1 100644 --- a/drivers/media/video/cx18/Kconfig +++ b/drivers/media/video/cx18/Kconfig | |||
@@ -2,9 +2,7 @@ config VIDEO_CX18 | |||
2 | tristate "Conexant cx23418 MPEG encoder support" | 2 | tristate "Conexant cx23418 MPEG encoder support" |
3 | depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL | 3 | depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL |
4 | depends on INPUT # due to VIDEO_IR | 4 | depends on INPUT # due to VIDEO_IR |
5 | depends on HOTPLUG # due to FW_LOADER | ||
6 | select I2C_ALGOBIT | 5 | select I2C_ALGOBIT |
7 | select FW_LOADER | ||
8 | select VIDEO_IR | 6 | select VIDEO_IR |
9 | select VIDEO_TUNER | 7 | select VIDEO_TUNER |
10 | select VIDEO_TVEEPROM | 8 | select VIDEO_TVEEPROM |
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c index c40a286de1b9..0b55837880a7 100644 --- a/drivers/media/video/cx18/cx18-av-audio.c +++ b/drivers/media/video/cx18/cx18-av-audio.c | |||
@@ -30,7 +30,6 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
30 | if (freq != 32000 && freq != 44100 && freq != 48000) | 30 | if (freq != 32000 && freq != 44100 && freq != 48000) |
31 | return -EINVAL; | 31 | return -EINVAL; |
32 | 32 | ||
33 | /* common for all inputs and rates */ | ||
34 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ | 33 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ |
35 | cx18_av_write(cx, 0x127, 0x50); | 34 | cx18_av_write(cx, 0x127, 0x50); |
36 | 35 | ||
@@ -38,15 +37,30 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
38 | switch (freq) { | 37 | switch (freq) { |
39 | case 32000: | 38 | case 32000: |
40 | /* VID_PLL and AUX_PLL */ | 39 | /* VID_PLL and AUX_PLL */ |
41 | cx18_av_write4(cx, 0x108, 0x1006040f); | 40 | cx18_av_write4(cx, 0x108, 0x1408040f); |
42 | 41 | ||
43 | /* AUX_PLL_FRAC */ | 42 | /* AUX_PLL_FRAC */ |
44 | cx18_av_write4(cx, 0x110, 0x01bb39ee); | 43 | /* 0x8.9504318a * 28,636,363.636 / 0x14 = 32000 * 384 */ |
44 | cx18_av_write4(cx, 0x110, 0x012a0863); | ||
45 | 45 | ||
46 | /* src3/4/6_ctl = 0x0801f77f */ | 46 | /* src3/4/6_ctl */ |
47 | /* 0x1.f77f = (4 * 15734.26) / 32000 */ | ||
47 | cx18_av_write4(cx, 0x900, 0x0801f77f); | 48 | cx18_av_write4(cx, 0x900, 0x0801f77f); |
48 | cx18_av_write4(cx, 0x904, 0x0801f77f); | 49 | cx18_av_write4(cx, 0x904, 0x0801f77f); |
49 | cx18_av_write4(cx, 0x90c, 0x0801f77f); | 50 | cx18_av_write4(cx, 0x90c, 0x0801f77f); |
51 | |||
52 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ | ||
53 | cx18_av_write(cx, 0x127, 0x54); | ||
54 | |||
55 | /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */ | ||
56 | cx18_av_write4(cx, 0x12c, 0x11202fff); | ||
57 | |||
58 | /* | ||
59 | * EN_AV_LOCK = 1 | ||
60 | * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 = | ||
61 | * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8 | ||
62 | */ | ||
63 | cx18_av_write4(cx, 0x128, 0xa10d2ef8); | ||
50 | break; | 64 | break; |
51 | 65 | ||
52 | case 44100: | 66 | case 44100: |
@@ -54,12 +68,24 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
54 | cx18_av_write4(cx, 0x108, 0x1009040f); | 68 | cx18_av_write4(cx, 0x108, 0x1009040f); |
55 | 69 | ||
56 | /* AUX_PLL_FRAC */ | 70 | /* AUX_PLL_FRAC */ |
57 | cx18_av_write4(cx, 0x110, 0x00ec6bd6); | 71 | /* 0x9.7635e7 * 28,636,363.63 / 0x10 = 44100 * 384 */ |
72 | cx18_av_write4(cx, 0x110, 0x00ec6bce); | ||
58 | 73 | ||
59 | /* src3/4/6_ctl = 0x08016d59 */ | 74 | /* src3/4/6_ctl */ |
75 | /* 0x1.6d59 = (4 * 15734.26) / 44100 */ | ||
60 | cx18_av_write4(cx, 0x900, 0x08016d59); | 76 | cx18_av_write4(cx, 0x900, 0x08016d59); |
61 | cx18_av_write4(cx, 0x904, 0x08016d59); | 77 | cx18_av_write4(cx, 0x904, 0x08016d59); |
62 | cx18_av_write4(cx, 0x90c, 0x08016d59); | 78 | cx18_av_write4(cx, 0x90c, 0x08016d59); |
79 | |||
80 | /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */ | ||
81 | cx18_av_write4(cx, 0x12c, 0x112092ff); | ||
82 | |||
83 | /* | ||
84 | * EN_AV_LOCK = 1 | ||
85 | * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 = | ||
86 | * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8 | ||
87 | */ | ||
88 | cx18_av_write4(cx, 0x128, 0xa11d4bf8); | ||
63 | break; | 89 | break; |
64 | 90 | ||
65 | case 48000: | 91 | case 48000: |
@@ -67,12 +93,24 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
67 | cx18_av_write4(cx, 0x108, 0x100a040f); | 93 | cx18_av_write4(cx, 0x108, 0x100a040f); |
68 | 94 | ||
69 | /* AUX_PLL_FRAC */ | 95 | /* AUX_PLL_FRAC */ |
70 | cx18_av_write4(cx, 0x110, 0x0098d6e5); | 96 | /* 0xa.4c6b6ea * 28,636,363.63 / 0x10 = 48000 * 384 */ |
97 | cx18_av_write4(cx, 0x110, 0x0098d6dd); | ||
71 | 98 | ||
72 | /* src3/4/6_ctl = 0x08014faa */ | 99 | /* src3/4/6_ctl */ |
100 | /* 0x1.4faa = (4 * 15734.26) / 48000 */ | ||
73 | cx18_av_write4(cx, 0x900, 0x08014faa); | 101 | cx18_av_write4(cx, 0x900, 0x08014faa); |
74 | cx18_av_write4(cx, 0x904, 0x08014faa); | 102 | cx18_av_write4(cx, 0x904, 0x08014faa); |
75 | cx18_av_write4(cx, 0x90c, 0x08014faa); | 103 | cx18_av_write4(cx, 0x90c, 0x08014faa); |
104 | |||
105 | /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */ | ||
106 | cx18_av_write4(cx, 0x12c, 0x11205fff); | ||
107 | |||
108 | /* | ||
109 | * EN_AV_LOCK = 1 | ||
110 | * VID_COUNT = 0x1193f8 = 143999.000 * 8 = | ||
111 | * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8 | ||
112 | */ | ||
113 | cx18_av_write4(cx, 0x128, 0xa11193f8); | ||
76 | break; | 114 | break; |
77 | } | 115 | } |
78 | } else { | 116 | } else { |
@@ -82,18 +120,31 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
82 | cx18_av_write4(cx, 0x108, 0x1e08040f); | 120 | cx18_av_write4(cx, 0x108, 0x1e08040f); |
83 | 121 | ||
84 | /* AUX_PLL_FRAC */ | 122 | /* AUX_PLL_FRAC */ |
85 | cx18_av_write4(cx, 0x110, 0x012a0869); | 123 | /* 0x8.9504318 * 28,636,363.63 / 0x1e = 32000 * 256 */ |
124 | cx18_av_write4(cx, 0x110, 0x012a0863); | ||
86 | 125 | ||
87 | /* src1_ctl = 0x08010000 */ | 126 | /* src1_ctl */ |
127 | /* 0x1.0000 = 32000/32000 */ | ||
88 | cx18_av_write4(cx, 0x8f8, 0x08010000); | 128 | cx18_av_write4(cx, 0x8f8, 0x08010000); |
89 | 129 | ||
90 | /* src3/4/6_ctl = 0x08020000 */ | 130 | /* src3/4/6_ctl */ |
131 | /* 0x2.0000 = 2 * (32000/32000) */ | ||
91 | cx18_av_write4(cx, 0x900, 0x08020000); | 132 | cx18_av_write4(cx, 0x900, 0x08020000); |
92 | cx18_av_write4(cx, 0x904, 0x08020000); | 133 | cx18_av_write4(cx, 0x904, 0x08020000); |
93 | cx18_av_write4(cx, 0x90c, 0x08020000); | 134 | cx18_av_write4(cx, 0x90c, 0x08020000); |
94 | 135 | ||
95 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ | 136 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ |
96 | cx18_av_write(cx, 0x127, 0x54); | 137 | cx18_av_write(cx, 0x127, 0x54); |
138 | |||
139 | /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */ | ||
140 | cx18_av_write4(cx, 0x12c, 0x11201fff); | ||
141 | |||
142 | /* | ||
143 | * EN_AV_LOCK = 1 | ||
144 | * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 = | ||
145 | * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8 | ||
146 | */ | ||
147 | cx18_av_write4(cx, 0x128, 0xa10d2ef8); | ||
97 | break; | 148 | break; |
98 | 149 | ||
99 | case 44100: | 150 | case 44100: |
@@ -101,15 +152,28 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
101 | cx18_av_write4(cx, 0x108, 0x1809040f); | 152 | cx18_av_write4(cx, 0x108, 0x1809040f); |
102 | 153 | ||
103 | /* AUX_PLL_FRAC */ | 154 | /* AUX_PLL_FRAC */ |
104 | cx18_av_write4(cx, 0x110, 0x00ec6bd6); | 155 | /* 0x9.7635e74 * 28,636,363.63 / 0x18 = 44100 * 256 */ |
156 | cx18_av_write4(cx, 0x110, 0x00ec6bce); | ||
105 | 157 | ||
106 | /* src1_ctl = 0x08010000 */ | 158 | /* src1_ctl */ |
159 | /* 0x1.60cd = 44100/32000 */ | ||
107 | cx18_av_write4(cx, 0x8f8, 0x080160cd); | 160 | cx18_av_write4(cx, 0x8f8, 0x080160cd); |
108 | 161 | ||
109 | /* src3/4/6_ctl = 0x08020000 */ | 162 | /* src3/4/6_ctl */ |
163 | /* 0x1.7385 = 2 * (32000/44100) */ | ||
110 | cx18_av_write4(cx, 0x900, 0x08017385); | 164 | cx18_av_write4(cx, 0x900, 0x08017385); |
111 | cx18_av_write4(cx, 0x904, 0x08017385); | 165 | cx18_av_write4(cx, 0x904, 0x08017385); |
112 | cx18_av_write4(cx, 0x90c, 0x08017385); | 166 | cx18_av_write4(cx, 0x90c, 0x08017385); |
167 | |||
168 | /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */ | ||
169 | cx18_av_write4(cx, 0x12c, 0x112061ff); | ||
170 | |||
171 | /* | ||
172 | * EN_AV_LOCK = 1 | ||
173 | * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 = | ||
174 | * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8 | ||
175 | */ | ||
176 | cx18_av_write4(cx, 0x128, 0xa11d4bf8); | ||
113 | break; | 177 | break; |
114 | 178 | ||
115 | case 48000: | 179 | case 48000: |
@@ -117,15 +181,28 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
117 | cx18_av_write4(cx, 0x108, 0x180a040f); | 181 | cx18_av_write4(cx, 0x108, 0x180a040f); |
118 | 182 | ||
119 | /* AUX_PLL_FRAC */ | 183 | /* AUX_PLL_FRAC */ |
120 | cx18_av_write4(cx, 0x110, 0x0098d6e5); | 184 | /* 0xa.4c6b6ea * 28,636,363.63 / 0x18 = 48000 * 256 */ |
185 | cx18_av_write4(cx, 0x110, 0x0098d6dd); | ||
121 | 186 | ||
122 | /* src1_ctl = 0x08010000 */ | 187 | /* src1_ctl */ |
188 | /* 0x1.8000 = 48000/32000 */ | ||
123 | cx18_av_write4(cx, 0x8f8, 0x08018000); | 189 | cx18_av_write4(cx, 0x8f8, 0x08018000); |
124 | 190 | ||
125 | /* src3/4/6_ctl = 0x08020000 */ | 191 | /* src3/4/6_ctl */ |
192 | /* 0x1.5555 = 2 * (32000/48000) */ | ||
126 | cx18_av_write4(cx, 0x900, 0x08015555); | 193 | cx18_av_write4(cx, 0x900, 0x08015555); |
127 | cx18_av_write4(cx, 0x904, 0x08015555); | 194 | cx18_av_write4(cx, 0x904, 0x08015555); |
128 | cx18_av_write4(cx, 0x90c, 0x08015555); | 195 | cx18_av_write4(cx, 0x90c, 0x08015555); |
196 | |||
197 | /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */ | ||
198 | cx18_av_write4(cx, 0x12c, 0x11203fff); | ||
199 | |||
200 | /* | ||
201 | * EN_AV_LOCK = 1 | ||
202 | * VID_COUNT = 0x1193f8 = 143999.000 * 8 = | ||
203 | * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8 | ||
204 | */ | ||
205 | cx18_av_write4(cx, 0x128, 0xa11193f8); | ||
129 | break; | 206 | break; |
130 | } | 207 | } |
131 | } | 208 | } |
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 45e31b04730e..4801bc7fb5b2 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/dvb/video.h> | 46 | #include <linux/dvb/video.h> |
47 | #include <linux/dvb/audio.h> | 47 | #include <linux/dvb/audio.h> |
48 | #include <media/v4l2-common.h> | 48 | #include <media/v4l2-common.h> |
49 | #include <media/v4l2-ioctl.h> | ||
49 | #include <media/tuner.h> | 50 | #include <media/tuner.h> |
50 | #include "cx18-mailbox.h" | 51 | #include "cx18-mailbox.h" |
51 | #include "cx18-av-core.h" | 52 | #include "cx18-av-core.h" |
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c index 2d630d9f7496..78fadd2ada5d 100644 --- a/drivers/media/video/cx18/cx18-firmware.c +++ b/drivers/media/video/cx18/cx18-firmware.c | |||
@@ -86,10 +86,6 @@ | |||
86 | 86 | ||
87 | #define CX18_DSP0_INTERRUPT_MASK 0xd0004C | 87 | #define CX18_DSP0_INTERRUPT_MASK 0xd0004C |
88 | 88 | ||
89 | /* Encoder/decoder firmware sizes */ | ||
90 | #define CX18_FW_CPU_SIZE (158332) | ||
91 | #define CX18_FW_APU_SIZE (141200) | ||
92 | |||
93 | #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */ | 89 | #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */ |
94 | #define APU_ROM_SYNC2 0x72646548 /* "rdeH" */ | 90 | #define APU_ROM_SYNC2 0x72646548 /* "rdeH" */ |
95 | 91 | ||
@@ -100,35 +96,22 @@ struct cx18_apu_rom_seghdr { | |||
100 | u32 size; | 96 | u32 size; |
101 | }; | 97 | }; |
102 | 98 | ||
103 | static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx, long size) | 99 | static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx) |
104 | { | 100 | { |
105 | const struct firmware *fw = NULL; | 101 | const struct firmware *fw = NULL; |
106 | int retries = 3; | ||
107 | int i, j; | 102 | int i, j; |
103 | unsigned size; | ||
108 | u32 __iomem *dst = (u32 __iomem *)mem; | 104 | u32 __iomem *dst = (u32 __iomem *)mem; |
109 | const u32 *src; | 105 | const u32 *src; |
110 | 106 | ||
111 | retry: | 107 | if (request_firmware(&fw, fn, &cx->dev->dev)) { |
112 | if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) { | 108 | CX18_ERR("Unable to open firmware %s\n", fn); |
113 | CX18_ERR("Unable to open firmware %s (must be %ld bytes)\n", | ||
114 | fn, size); | ||
115 | CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n"); | 109 | CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n"); |
116 | return -ENOMEM; | 110 | return -ENOMEM; |
117 | } | 111 | } |
118 | 112 | ||
119 | src = (const u32 *)fw->data; | 113 | src = (const u32 *)fw->data; |
120 | 114 | ||
121 | if (fw->size != size) { | ||
122 | /* Due to race conditions in firmware loading (esp. with | ||
123 | udev <0.95) the wrong file was sometimes loaded. So we check | ||
124 | filesizes to see if at least the right-sized file was | ||
125 | loaded. If not, then we retry. */ | ||
126 | CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n", | ||
127 | fn, size, fw->size); | ||
128 | release_firmware(fw); | ||
129 | retries--; | ||
130 | goto retry; | ||
131 | } | ||
132 | for (i = 0; i < fw->size; i += 4096) { | 115 | for (i = 0; i < fw->size; i += 4096) { |
133 | setup_page(i); | 116 | setup_page(i); |
134 | for (j = i; j < fw->size && j < i + 4096; j += 4) { | 117 | for (j = i; j < fw->size && j < i + 4096; j += 4) { |
@@ -145,15 +128,16 @@ retry: | |||
145 | } | 128 | } |
146 | if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) | 129 | if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) |
147 | CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size); | 130 | CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size); |
131 | size = fw->size; | ||
148 | release_firmware(fw); | 132 | release_firmware(fw); |
149 | return size; | 133 | return size; |
150 | } | 134 | } |
151 | 135 | ||
152 | static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, long size) | 136 | static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) |
153 | { | 137 | { |
154 | const struct firmware *fw = NULL; | 138 | const struct firmware *fw = NULL; |
155 | int retries = 3; | ||
156 | int i, j; | 139 | int i, j; |
140 | unsigned size; | ||
157 | const u32 *src; | 141 | const u32 *src; |
158 | struct cx18_apu_rom_seghdr seghdr; | 142 | struct cx18_apu_rom_seghdr seghdr; |
159 | const u8 *vers; | 143 | const u8 *vers; |
@@ -161,10 +145,8 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, | |||
161 | u32 apu_version = 0; | 145 | u32 apu_version = 0; |
162 | int sz; | 146 | int sz; |
163 | 147 | ||
164 | retry: | 148 | if (request_firmware(&fw, fn, &cx->dev->dev)) { |
165 | if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) { | 149 | CX18_ERR("unable to open firmware %s\n", fn); |
166 | CX18_ERR("unable to open firmware %s (must be %ld bytes)\n", | ||
167 | fn, size); | ||
168 | CX18_ERR("did you put the firmware in the hotplug firmware directory?\n"); | 150 | CX18_ERR("did you put the firmware in the hotplug firmware directory?\n"); |
169 | return -ENOMEM; | 151 | return -ENOMEM; |
170 | } | 152 | } |
@@ -173,19 +155,8 @@ retry: | |||
173 | vers = fw->data + sizeof(seghdr); | 155 | vers = fw->data + sizeof(seghdr); |
174 | sz = fw->size; | 156 | sz = fw->size; |
175 | 157 | ||
176 | if (fw->size != size) { | ||
177 | /* Due to race conditions in firmware loading (esp. with | ||
178 | udev <0.95) the wrong file was sometimes loaded. So we check | ||
179 | filesizes to see if at least the right-sized file was | ||
180 | loaded. If not, then we retry. */ | ||
181 | CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n", | ||
182 | fn, size, fw->size); | ||
183 | release_firmware(fw); | ||
184 | retries--; | ||
185 | goto retry; | ||
186 | } | ||
187 | apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32]; | 158 | apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32]; |
188 | while (offset + sizeof(seghdr) < size) { | 159 | while (offset + sizeof(seghdr) < fw->size) { |
189 | /* TODO: byteswapping */ | 160 | /* TODO: byteswapping */ |
190 | memcpy(&seghdr, src + offset / 4, sizeof(seghdr)); | 161 | memcpy(&seghdr, src + offset / 4, sizeof(seghdr)); |
191 | offset += sizeof(seghdr); | 162 | offset += sizeof(seghdr); |
@@ -215,6 +186,7 @@ retry: | |||
215 | if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) | 186 | if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) |
216 | CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n", | 187 | CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n", |
217 | fn, apu_version, fw->size); | 188 | fn, apu_version, fw->size); |
189 | size = fw->size; | ||
218 | release_firmware(fw); | 190 | release_firmware(fw); |
219 | /* Clear bit0 for APU to start from 0 */ | 191 | /* Clear bit0 for APU to start from 0 */ |
220 | write_reg(read_reg(0xc72030) & ~1, 0xc72030); | 192 | write_reg(read_reg(0xc72030) & ~1, 0xc72030); |
@@ -340,7 +312,7 @@ int cx18_firmware_init(struct cx18 *cx) | |||
340 | /* Only if the processor is not running */ | 312 | /* Only if the processor is not running */ |
341 | if (read_reg(CX18_PROC_SOFT_RESET) & 8) { | 313 | if (read_reg(CX18_PROC_SOFT_RESET) & 8) { |
342 | int sz = load_apu_fw_direct("v4l-cx23418-apu.fw", | 314 | int sz = load_apu_fw_direct("v4l-cx23418-apu.fw", |
343 | cx->enc_mem, cx, CX18_FW_APU_SIZE); | 315 | cx->enc_mem, cx); |
344 | 316 | ||
345 | write_enc(0xE51FF004, 0); | 317 | write_enc(0xE51FF004, 0); |
346 | write_enc(0xa00000, 4); /* todo: not hardcoded */ | 318 | write_enc(0xa00000, 4); /* todo: not hardcoded */ |
@@ -348,7 +320,7 @@ int cx18_firmware_init(struct cx18 *cx) | |||
348 | cx18_msleep_timeout(500, 0); | 320 | cx18_msleep_timeout(500, 0); |
349 | 321 | ||
350 | sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw", | 322 | sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw", |
351 | cx->enc_mem, cx, CX18_FW_CPU_SIZE); | 323 | cx->enc_mem, cx); |
352 | 324 | ||
353 | if (sz > 0) { | 325 | if (sz > 0) { |
354 | int retries = 0; | 326 | int retries = 0; |
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 0d74e59e503e..a7f839631d6a 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c | |||
@@ -787,50 +787,54 @@ int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
787 | return res; | 787 | return res; |
788 | } | 788 | } |
789 | 789 | ||
790 | void cx18_set_funcs(struct video_device *vdev) | 790 | static const struct v4l2_ioctl_ops cx18_ioctl_ops = { |
791 | { | 791 | .vidioc_querycap = cx18_querycap, |
792 | vdev->vidioc_querycap = cx18_querycap; | 792 | .vidioc_g_priority = cx18_g_priority, |
793 | vdev->vidioc_g_priority = cx18_g_priority; | 793 | .vidioc_s_priority = cx18_s_priority, |
794 | vdev->vidioc_s_priority = cx18_s_priority; | 794 | .vidioc_s_audio = cx18_s_audio, |
795 | vdev->vidioc_s_audio = cx18_s_audio; | 795 | .vidioc_g_audio = cx18_g_audio, |
796 | vdev->vidioc_g_audio = cx18_g_audio; | 796 | .vidioc_enumaudio = cx18_enumaudio, |
797 | vdev->vidioc_enumaudio = cx18_enumaudio; | 797 | .vidioc_enum_input = cx18_enum_input, |
798 | vdev->vidioc_enum_input = cx18_enum_input; | 798 | .vidioc_cropcap = cx18_cropcap, |
799 | vdev->vidioc_cropcap = cx18_cropcap; | 799 | .vidioc_s_crop = cx18_s_crop, |
800 | vdev->vidioc_s_crop = cx18_s_crop; | 800 | .vidioc_g_crop = cx18_g_crop, |
801 | vdev->vidioc_g_crop = cx18_g_crop; | 801 | .vidioc_g_input = cx18_g_input, |
802 | vdev->vidioc_g_input = cx18_g_input; | 802 | .vidioc_s_input = cx18_s_input, |
803 | vdev->vidioc_s_input = cx18_s_input; | 803 | .vidioc_g_frequency = cx18_g_frequency, |
804 | vdev->vidioc_g_frequency = cx18_g_frequency; | 804 | .vidioc_s_frequency = cx18_s_frequency, |
805 | vdev->vidioc_s_frequency = cx18_s_frequency; | 805 | .vidioc_s_tuner = cx18_s_tuner, |
806 | vdev->vidioc_s_tuner = cx18_s_tuner; | 806 | .vidioc_g_tuner = cx18_g_tuner, |
807 | vdev->vidioc_g_tuner = cx18_g_tuner; | 807 | .vidioc_g_enc_index = cx18_g_enc_index, |
808 | vdev->vidioc_g_enc_index = cx18_g_enc_index; | 808 | .vidioc_g_std = cx18_g_std, |
809 | vdev->vidioc_g_std = cx18_g_std; | 809 | .vidioc_s_std = cx18_s_std, |
810 | vdev->vidioc_s_std = cx18_s_std; | 810 | .vidioc_log_status = cx18_log_status, |
811 | vdev->vidioc_log_status = cx18_log_status; | 811 | .vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap, |
812 | vdev->vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap; | 812 | .vidioc_encoder_cmd = cx18_encoder_cmd, |
813 | vdev->vidioc_encoder_cmd = cx18_encoder_cmd; | 813 | .vidioc_try_encoder_cmd = cx18_try_encoder_cmd, |
814 | vdev->vidioc_try_encoder_cmd = cx18_try_encoder_cmd; | 814 | .vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap, |
815 | vdev->vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap; | 815 | .vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap, |
816 | vdev->vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap; | 816 | .vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap, |
817 | vdev->vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap; | 817 | .vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap, |
818 | vdev->vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap; | 818 | .vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap, |
819 | vdev->vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap; | 819 | .vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap, |
820 | vdev->vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap; | 820 | .vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap, |
821 | vdev->vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap; | 821 | .vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap, |
822 | vdev->vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap; | 822 | .vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap, |
823 | vdev->vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap; | 823 | .vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap, |
824 | vdev->vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap; | 824 | .vidioc_g_chip_ident = cx18_g_chip_ident, |
825 | vdev->vidioc_g_chip_ident = cx18_g_chip_ident; | ||
826 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 825 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
827 | vdev->vidioc_g_register = cx18_g_register; | 826 | .vidioc_g_register = cx18_g_register, |
828 | vdev->vidioc_s_register = cx18_s_register; | 827 | .vidioc_s_register = cx18_s_register, |
829 | #endif | 828 | #endif |
830 | vdev->vidioc_default = cx18_default; | 829 | .vidioc_default = cx18_default, |
831 | vdev->vidioc_queryctrl = cx18_queryctrl; | 830 | .vidioc_queryctrl = cx18_queryctrl, |
832 | vdev->vidioc_querymenu = cx18_querymenu; | 831 | .vidioc_querymenu = cx18_querymenu, |
833 | vdev->vidioc_g_ext_ctrls = cx18_g_ext_ctrls; | 832 | .vidioc_g_ext_ctrls = cx18_g_ext_ctrls, |
834 | vdev->vidioc_s_ext_ctrls = cx18_s_ext_ctrls; | 833 | .vidioc_s_ext_ctrls = cx18_s_ext_ctrls, |
835 | vdev->vidioc_try_ext_ctrls = cx18_try_ext_ctrls; | 834 | .vidioc_try_ext_ctrls = cx18_try_ext_ctrls, |
835 | }; | ||
836 | |||
837 | void cx18_set_funcs(struct video_device *vdev) | ||
838 | { | ||
839 | vdev->ioctl_ops = &cx18_ioctl_ops; | ||
836 | } | 840 | } |
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 1728b1d832a9..0da57f583bf7 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -187,14 +187,11 @@ static int cx18_prep_dev(struct cx18 *cx, int type) | |||
187 | return -ENOMEM; | 187 | return -ENOMEM; |
188 | } | 188 | } |
189 | 189 | ||
190 | s->v4l2dev->type = | ||
191 | VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT | | ||
192 | VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER; | ||
193 | snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", | 190 | snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", |
194 | cx->num); | 191 | cx->num); |
195 | 192 | ||
196 | s->v4l2dev->minor = minor; | 193 | s->v4l2dev->minor = minor; |
197 | s->v4l2dev->dev = &cx->dev->dev; | 194 | s->v4l2dev->parent = &cx->dev->dev; |
198 | s->v4l2dev->fops = cx18_stream_info[type].fops; | 195 | s->v4l2dev->fops = cx18_stream_info[type].fops; |
199 | s->v4l2dev->release = video_device_release; | 196 | s->v4l2dev->release = video_device_release; |
200 | s->v4l2dev->tvnorms = V4L2_STD_ALL; | 197 | s->v4l2dev->tvnorms = V4L2_STD_ALL; |