diff options
Diffstat (limited to 'drivers/media/video/cx18/cx18-cards.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-cards.c | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c new file mode 100644 index 000000000000..f5e3ba1f5354 --- /dev/null +++ b/drivers/media/video/cx18/cx18-cards.c | |||
@@ -0,0 +1,277 @@ | |||
1 | /* | ||
2 | * cx18 functions to query card hardware | ||
3 | * | ||
4 | * Derived from ivtv-cards.c | ||
5 | * | ||
6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
21 | * 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include "cx18-driver.h" | ||
25 | #include "cx18-cards.h" | ||
26 | #include "cx18-i2c.h" | ||
27 | #include <media/cs5345.h> | ||
28 | |||
29 | /********************** card configuration *******************************/ | ||
30 | |||
31 | /* usual i2c tuner addresses to probe */ | ||
32 | static struct cx18_card_tuner_i2c cx18_i2c_std = { | ||
33 | .radio = { I2C_CLIENT_END }, | ||
34 | .demod = { 0x43, I2C_CLIENT_END }, | ||
35 | .tv = { 0x61, 0x60, I2C_CLIENT_END }, | ||
36 | }; | ||
37 | |||
38 | /* Please add new PCI IDs to: http://pci-ids.ucw.cz/iii | ||
39 | This keeps the PCI ID database up to date. Note that the entries | ||
40 | must be added under vendor 0x4444 (Conexant) as subsystem IDs. | ||
41 | New vendor IDs should still be added to the vendor ID list. */ | ||
42 | |||
43 | /* Hauppauge HVR-1600 cards */ | ||
44 | |||
45 | /* Note: for Hauppauge cards the tveeprom information is used instead | ||
46 | of PCI IDs */ | ||
47 | static const struct cx18_card cx18_card_hvr1600_esmt = { | ||
48 | .type = CX18_CARD_HVR_1600_ESMT, | ||
49 | .name = "Hauppauge HVR-1600", | ||
50 | .comment = "DVB & VBI are not yet supported\n", | ||
51 | .v4l2_capabilities = CX18_CAP_ENCODER, | ||
52 | .hw_audio_ctrl = CX18_HW_CX23418, | ||
53 | .hw_muxer = CX18_HW_CS5345, | ||
54 | .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345, | ||
55 | .video_inputs = { | ||
56 | { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, | ||
57 | { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, | ||
58 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, | ||
59 | { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 }, | ||
60 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 }, | ||
61 | }, | ||
62 | .audio_inputs = { | ||
63 | { CX18_CARD_INPUT_AUD_TUNER, | ||
64 | CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, | ||
65 | { CX18_CARD_INPUT_LINE_IN1, | ||
66 | CX23418_AUDIO_SERIAL, CS5345_IN_2 }, | ||
67 | { CX18_CARD_INPUT_LINE_IN2, | ||
68 | CX23418_AUDIO_SERIAL, CS5345_IN_2 }, | ||
69 | }, | ||
70 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | ||
71 | CX23418_AUDIO_SERIAL, 0 }, | ||
72 | .ddr = { | ||
73 | /* ESMT M13S128324A-5B memory */ | ||
74 | .chip_config = 0x003, | ||
75 | .refresh = 0x30c, | ||
76 | .timing1 = 0x44220e82, | ||
77 | .timing2 = 0x08, | ||
78 | .tune_lane = 0, | ||
79 | .initial_emrs = 0, | ||
80 | }, | ||
81 | .gpio_init.initial_value = 0x3001, | ||
82 | .gpio_init.direction = 0x3001, | ||
83 | .i2c = &cx18_i2c_std, | ||
84 | }; | ||
85 | |||
86 | static const struct cx18_card cx18_card_hvr1600_samsung = { | ||
87 | .type = CX18_CARD_HVR_1600_SAMSUNG, | ||
88 | .name = "Hauppauge HVR-1600 (Preproduction)", | ||
89 | .comment = "DVB & VBI are not yet supported\n", | ||
90 | .v4l2_capabilities = CX18_CAP_ENCODER, | ||
91 | .hw_audio_ctrl = CX18_HW_CX23418, | ||
92 | .hw_muxer = CX18_HW_CS5345, | ||
93 | .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345, | ||
94 | .video_inputs = { | ||
95 | { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, | ||
96 | { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, | ||
97 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, | ||
98 | { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 }, | ||
99 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 }, | ||
100 | }, | ||
101 | .audio_inputs = { | ||
102 | { CX18_CARD_INPUT_AUD_TUNER, | ||
103 | CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, | ||
104 | { CX18_CARD_INPUT_LINE_IN1, | ||
105 | CX23418_AUDIO_SERIAL, CS5345_IN_2 }, | ||
106 | { CX18_CARD_INPUT_LINE_IN2, | ||
107 | CX23418_AUDIO_SERIAL, CS5345_IN_2 }, | ||
108 | }, | ||
109 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | ||
110 | CX23418_AUDIO_SERIAL, 0 }, | ||
111 | .ddr = { | ||
112 | /* Samsung K4D263238G-VC33 memory */ | ||
113 | .chip_config = 0x003, | ||
114 | .refresh = 0x30c, | ||
115 | .timing1 = 0x23230b73, | ||
116 | .timing2 = 0x08, | ||
117 | .tune_lane = 0, | ||
118 | .initial_emrs = 2, | ||
119 | }, | ||
120 | .gpio_init.initial_value = 0x3001, | ||
121 | .gpio_init.direction = 0x3001, | ||
122 | .i2c = &cx18_i2c_std, | ||
123 | }; | ||
124 | |||
125 | /* ------------------------------------------------------------------------- */ | ||
126 | |||
127 | /* Compro VideoMate H900: not working at the moment! */ | ||
128 | |||
129 | static const struct cx18_card_pci_info cx18_pci_h900[] = { | ||
130 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 }, | ||
131 | { 0, 0, 0 } | ||
132 | }; | ||
133 | |||
134 | static const struct cx18_card cx18_card_h900 = { | ||
135 | .type = CX18_CARD_COMPRO_H900, | ||
136 | .name = "Compro VideoMate H900", | ||
137 | .comment = "Not yet supported!\n", | ||
138 | .v4l2_capabilities = 0, | ||
139 | .hw_audio_ctrl = CX18_HW_CX23418, | ||
140 | .hw_all = CX18_HW_TUNER, | ||
141 | .video_inputs = { | ||
142 | { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, | ||
143 | { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, | ||
144 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, | ||
145 | }, | ||
146 | .audio_inputs = { | ||
147 | { CX18_CARD_INPUT_AUD_TUNER, | ||
148 | CX23418_AUDIO8, 0 }, | ||
149 | { CX18_CARD_INPUT_LINE_IN1, | ||
150 | CX23418_AUDIO_SERIAL, 0 }, | ||
151 | }, | ||
152 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | ||
153 | CX23418_AUDIO_SERIAL, 0 }, | ||
154 | .tuners = { | ||
155 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | ||
156 | }, | ||
157 | .ddr = { | ||
158 | /* EtronTech EM6A9160TS-5G memory */ | ||
159 | .chip_config = 0x50003, | ||
160 | .refresh = 0x753, | ||
161 | .timing1 = 0x24330e84, | ||
162 | .timing2 = 0x1f, | ||
163 | .tune_lane = 0, | ||
164 | .initial_emrs = 0, | ||
165 | }, | ||
166 | .pci_list = cx18_pci_h900, | ||
167 | .i2c = &cx18_i2c_std, | ||
168 | }; | ||
169 | |||
170 | /* ------------------------------------------------------------------------- */ | ||
171 | |||
172 | /* Yuan MPC718: not working at the moment! */ | ||
173 | |||
174 | static const struct cx18_card_pci_info cx18_pci_mpc718[] = { | ||
175 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_YUAN, 0x0718 }, | ||
176 | { 0, 0, 0 } | ||
177 | }; | ||
178 | |||
179 | static const struct cx18_card cx18_card_mpc718 = { | ||
180 | .type = CX18_CARD_YUAN_MPC718, | ||
181 | .name = "Yuan MPC718", | ||
182 | .comment = "Not yet supported!\n", | ||
183 | .v4l2_capabilities = 0, | ||
184 | .hw_audio_ctrl = CX18_HW_CX23418, | ||
185 | .hw_all = CX18_HW_TUNER, | ||
186 | .video_inputs = { | ||
187 | { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, | ||
188 | { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, | ||
189 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, | ||
190 | }, | ||
191 | .audio_inputs = { | ||
192 | { CX18_CARD_INPUT_AUD_TUNER, | ||
193 | CX23418_AUDIO8, 0 }, | ||
194 | { CX18_CARD_INPUT_LINE_IN1, | ||
195 | CX23418_AUDIO_SERIAL, 0 }, | ||
196 | }, | ||
197 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | ||
198 | CX23418_AUDIO_SERIAL, 0 }, | ||
199 | .tuners = { | ||
200 | /* XC3028 tuner */ | ||
201 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | ||
202 | }, | ||
203 | /* tuner reset */ | ||
204 | .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, | ||
205 | .ddr = { | ||
206 | /* Probably Samsung K4D263238G-VC33 memory */ | ||
207 | .chip_config = 0x003, | ||
208 | .refresh = 0x30c, | ||
209 | .timing1 = 0x23230b73, | ||
210 | .timing2 = 0x08, | ||
211 | .tune_lane = 0, | ||
212 | .initial_emrs = 2, | ||
213 | }, | ||
214 | .pci_list = cx18_pci_mpc718, | ||
215 | .i2c = &cx18_i2c_std, | ||
216 | }; | ||
217 | |||
218 | static const struct cx18_card *cx18_card_list[] = { | ||
219 | &cx18_card_hvr1600_esmt, | ||
220 | &cx18_card_hvr1600_samsung, | ||
221 | &cx18_card_h900, | ||
222 | &cx18_card_mpc718, | ||
223 | }; | ||
224 | |||
225 | const struct cx18_card *cx18_get_card(u16 index) | ||
226 | { | ||
227 | if (index >= ARRAY_SIZE(cx18_card_list)) | ||
228 | return NULL; | ||
229 | return cx18_card_list[index]; | ||
230 | } | ||
231 | |||
232 | int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input) | ||
233 | { | ||
234 | const struct cx18_card_video_input *card_input = | ||
235 | cx->card->video_inputs + index; | ||
236 | static const char * const input_strs[] = { | ||
237 | "Tuner 1", | ||
238 | "S-Video 1", | ||
239 | "S-Video 2", | ||
240 | "Composite 1", | ||
241 | "Composite 2", | ||
242 | "Composite 3" | ||
243 | }; | ||
244 | |||
245 | memset(input, 0, sizeof(*input)); | ||
246 | if (index >= cx->nof_inputs) | ||
247 | return -EINVAL; | ||
248 | input->index = index; | ||
249 | strlcpy(input->name, input_strs[card_input->video_type - 1], | ||
250 | sizeof(input->name)); | ||
251 | input->type = (card_input->video_type == CX18_CARD_INPUT_VID_TUNER ? | ||
252 | V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA); | ||
253 | input->audioset = (1 << cx->nof_audio_inputs) - 1; | ||
254 | input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ? | ||
255 | cx->tuner_std : V4L2_STD_ALL; | ||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *audio) | ||
260 | { | ||
261 | const struct cx18_card_audio_input *aud_input = | ||
262 | cx->card->audio_inputs + index; | ||
263 | static const char * const input_strs[] = { | ||
264 | "Tuner 1", | ||
265 | "Line In 1", | ||
266 | "Line In 2" | ||
267 | }; | ||
268 | |||
269 | memset(audio, 0, sizeof(*audio)); | ||
270 | if (index >= cx->nof_audio_inputs) | ||
271 | return -EINVAL; | ||
272 | strlcpy(audio->name, input_strs[aud_input->audio_type - 1], | ||
273 | sizeof(audio->name)); | ||
274 | audio->index = index; | ||
275 | audio->capability = V4L2_AUDCAP_STEREO; | ||
276 | return 0; | ||
277 | } | ||