Commit | Line | Data |
---|---|---|
1c1e45d1 HV |
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" | |
d3d9b803 | 26 | #include "cx18-av-core.h" |
1c1e45d1 HV |
27 | #include "cx18-i2c.h" |
28 | #include <media/cs5345.h> | |
29 | ||
30 | /********************** card configuration *******************************/ | |
31 | ||
32 | /* usual i2c tuner addresses to probe */ | |
33 | static struct cx18_card_tuner_i2c cx18_i2c_std = { | |
34 | .radio = { I2C_CLIENT_END }, | |
35 | .demod = { 0x43, I2C_CLIENT_END }, | |
36 | .tv = { 0x61, 0x60, I2C_CLIENT_END }, | |
37 | }; | |
38 | ||
39 | /* Please add new PCI IDs to: http://pci-ids.ucw.cz/iii | |
40 | This keeps the PCI ID database up to date. Note that the entries | |
41 | must be added under vendor 0x4444 (Conexant) as subsystem IDs. | |
42 | New vendor IDs should still be added to the vendor ID list. */ | |
43 | ||
44 | /* Hauppauge HVR-1600 cards */ | |
45 | ||
46 | /* Note: for Hauppauge cards the tveeprom information is used instead | |
47 | of PCI IDs */ | |
48 | static const struct cx18_card cx18_card_hvr1600_esmt = { | |
49 | .type = CX18_CARD_HVR_1600_ESMT, | |
50 | .name = "Hauppauge HVR-1600", | |
6b13cf16 | 51 | .comment = "VBI is not yet supported\n", |
1c1e45d1 HV |
52 | .v4l2_capabilities = CX18_CAP_ENCODER, |
53 | .hw_audio_ctrl = CX18_HW_CX23418, | |
54 | .hw_muxer = CX18_HW_CS5345, | |
6b13cf16 HV |
55 | .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | |
56 | CX18_HW_CS5345 | CX18_HW_DVB, | |
1c1e45d1 | 57 | .video_inputs = { |
d3d9b803 HV |
58 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, |
59 | { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, | |
60 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, | |
61 | { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, | |
62 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, | |
1c1e45d1 HV |
63 | }, |
64 | .audio_inputs = { | |
65 | { CX18_CARD_INPUT_AUD_TUNER, | |
d3d9b803 | 66 | CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, |
1c1e45d1 | 67 | { CX18_CARD_INPUT_LINE_IN1, |
d3d9b803 | 68 | CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, |
1c1e45d1 | 69 | { CX18_CARD_INPUT_LINE_IN2, |
d3d9b803 | 70 | CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, |
1c1e45d1 HV |
71 | }, |
72 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | |
d3d9b803 | 73 | CX18_AV_AUDIO_SERIAL, 0 }, |
1c1e45d1 HV |
74 | .ddr = { |
75 | /* ESMT M13S128324A-5B memory */ | |
76 | .chip_config = 0x003, | |
77 | .refresh = 0x30c, | |
78 | .timing1 = 0x44220e82, | |
79 | .timing2 = 0x08, | |
80 | .tune_lane = 0, | |
81 | .initial_emrs = 0, | |
82 | }, | |
83 | .gpio_init.initial_value = 0x3001, | |
84 | .gpio_init.direction = 0x3001, | |
85 | .i2c = &cx18_i2c_std, | |
86 | }; | |
87 | ||
88 | static const struct cx18_card cx18_card_hvr1600_samsung = { | |
89 | .type = CX18_CARD_HVR_1600_SAMSUNG, | |
90 | .name = "Hauppauge HVR-1600 (Preproduction)", | |
1d081601 | 91 | .comment = "VBI is not yet supported\n", |
1c1e45d1 HV |
92 | .v4l2_capabilities = CX18_CAP_ENCODER, |
93 | .hw_audio_ctrl = CX18_HW_CX23418, | |
94 | .hw_muxer = CX18_HW_CS5345, | |
1d081601 HV |
95 | .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | |
96 | CX18_HW_CS5345 | CX18_HW_DVB, | |
1c1e45d1 | 97 | .video_inputs = { |
d3d9b803 HV |
98 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, |
99 | { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, | |
100 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, | |
101 | { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, | |
102 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, | |
1c1e45d1 HV |
103 | }, |
104 | .audio_inputs = { | |
105 | { CX18_CARD_INPUT_AUD_TUNER, | |
d3d9b803 | 106 | CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, |
1c1e45d1 | 107 | { CX18_CARD_INPUT_LINE_IN1, |
d3d9b803 | 108 | CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, |
1c1e45d1 | 109 | { CX18_CARD_INPUT_LINE_IN2, |
d3d9b803 | 110 | CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, |
1c1e45d1 HV |
111 | }, |
112 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | |
d3d9b803 | 113 | CX18_AV_AUDIO_SERIAL, 0 }, |
1c1e45d1 HV |
114 | .ddr = { |
115 | /* Samsung K4D263238G-VC33 memory */ | |
116 | .chip_config = 0x003, | |
117 | .refresh = 0x30c, | |
118 | .timing1 = 0x23230b73, | |
119 | .timing2 = 0x08, | |
120 | .tune_lane = 0, | |
121 | .initial_emrs = 2, | |
122 | }, | |
123 | .gpio_init.initial_value = 0x3001, | |
124 | .gpio_init.direction = 0x3001, | |
125 | .i2c = &cx18_i2c_std, | |
126 | }; | |
127 | ||
128 | /* ------------------------------------------------------------------------- */ | |
129 | ||
8f993573 | 130 | /* Compro VideoMate H900: note that this card is analog only! */ |
1c1e45d1 HV |
131 | |
132 | static const struct cx18_card_pci_info cx18_pci_h900[] = { | |
133 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 }, | |
134 | { 0, 0, 0 } | |
135 | }; | |
136 | ||
137 | static const struct cx18_card cx18_card_h900 = { | |
138 | .type = CX18_CARD_COMPRO_H900, | |
139 | .name = "Compro VideoMate H900", | |
8f993573 | 140 | .comment = "VBI is not yet supported\n", |
9dcbf35a | 141 | .v4l2_capabilities = CX18_CAP_ENCODER, |
1c1e45d1 HV |
142 | .hw_audio_ctrl = CX18_HW_CX23418, |
143 | .hw_all = CX18_HW_TUNER, | |
144 | .video_inputs = { | |
d3d9b803 | 145 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, |
9dcbf35a | 146 | { CX18_CARD_INPUT_SVIDEO1, 1, |
d3d9b803 HV |
147 | CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, |
148 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, | |
1c1e45d1 HV |
149 | }, |
150 | .audio_inputs = { | |
151 | { CX18_CARD_INPUT_AUD_TUNER, | |
d3d9b803 | 152 | CX18_AV_AUDIO8, 0 }, |
1c1e45d1 | 153 | { CX18_CARD_INPUT_LINE_IN1, |
d3d9b803 | 154 | CX18_AV_AUDIO_SERIAL, 0 }, |
1c1e45d1 HV |
155 | }, |
156 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | |
d3d9b803 | 157 | CX18_AV_AUDIO_SERIAL, 0 }, |
1c1e45d1 HV |
158 | .tuners = { |
159 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | |
160 | }, | |
161 | .ddr = { | |
162 | /* EtronTech EM6A9160TS-5G memory */ | |
163 | .chip_config = 0x50003, | |
164 | .refresh = 0x753, | |
165 | .timing1 = 0x24330e84, | |
166 | .timing2 = 0x1f, | |
167 | .tune_lane = 0, | |
168 | .initial_emrs = 0, | |
169 | }, | |
9dcbf35a | 170 | .xceive_pin = 15, |
1c1e45d1 HV |
171 | .pci_list = cx18_pci_h900, |
172 | .i2c = &cx18_i2c_std, | |
173 | }; | |
174 | ||
175 | /* ------------------------------------------------------------------------- */ | |
176 | ||
177 | /* Yuan MPC718: not working at the moment! */ | |
178 | ||
179 | static const struct cx18_card_pci_info cx18_pci_mpc718[] = { | |
180 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_YUAN, 0x0718 }, | |
181 | { 0, 0, 0 } | |
182 | }; | |
183 | ||
184 | static const struct cx18_card cx18_card_mpc718 = { | |
185 | .type = CX18_CARD_YUAN_MPC718, | |
186 | .name = "Yuan MPC718", | |
187 | .comment = "Not yet supported!\n", | |
188 | .v4l2_capabilities = 0, | |
189 | .hw_audio_ctrl = CX18_HW_CX23418, | |
190 | .hw_all = CX18_HW_TUNER, | |
191 | .video_inputs = { | |
d3d9b803 HV |
192 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, |
193 | { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, | |
194 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, | |
1c1e45d1 HV |
195 | }, |
196 | .audio_inputs = { | |
197 | { CX18_CARD_INPUT_AUD_TUNER, | |
d3d9b803 | 198 | CX18_AV_AUDIO8, 0 }, |
1c1e45d1 | 199 | { CX18_CARD_INPUT_LINE_IN1, |
d3d9b803 | 200 | CX18_AV_AUDIO_SERIAL, 0 }, |
1c1e45d1 HV |
201 | }, |
202 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | |
d3d9b803 | 203 | CX18_AV_AUDIO_SERIAL, 0 }, |
1c1e45d1 HV |
204 | .tuners = { |
205 | /* XC3028 tuner */ | |
206 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | |
207 | }, | |
1c1e45d1 HV |
208 | .ddr = { |
209 | /* Probably Samsung K4D263238G-VC33 memory */ | |
210 | .chip_config = 0x003, | |
211 | .refresh = 0x30c, | |
212 | .timing1 = 0x23230b73, | |
213 | .timing2 = 0x08, | |
214 | .tune_lane = 0, | |
215 | .initial_emrs = 2, | |
216 | }, | |
6b13cf16 | 217 | .xceive_pin = 15, |
1c1e45d1 HV |
218 | .pci_list = cx18_pci_mpc718, |
219 | .i2c = &cx18_i2c_std, | |
220 | }; | |
221 | ||
222 | static const struct cx18_card *cx18_card_list[] = { | |
223 | &cx18_card_hvr1600_esmt, | |
224 | &cx18_card_hvr1600_samsung, | |
225 | &cx18_card_h900, | |
226 | &cx18_card_mpc718, | |
227 | }; | |
228 | ||
229 | const struct cx18_card *cx18_get_card(u16 index) | |
230 | { | |
231 | if (index >= ARRAY_SIZE(cx18_card_list)) | |
232 | return NULL; | |
233 | return cx18_card_list[index]; | |
234 | } | |
235 | ||
236 | int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input) | |
237 | { | |
238 | const struct cx18_card_video_input *card_input = | |
239 | cx->card->video_inputs + index; | |
240 | static const char * const input_strs[] = { | |
241 | "Tuner 1", | |
242 | "S-Video 1", | |
243 | "S-Video 2", | |
244 | "Composite 1", | |
245 | "Composite 2", | |
246 | "Composite 3" | |
247 | }; | |
248 | ||
249 | memset(input, 0, sizeof(*input)); | |
250 | if (index >= cx->nof_inputs) | |
251 | return -EINVAL; | |
252 | input->index = index; | |
253 | strlcpy(input->name, input_strs[card_input->video_type - 1], | |
254 | sizeof(input->name)); | |
255 | input->type = (card_input->video_type == CX18_CARD_INPUT_VID_TUNER ? | |
256 | V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA); | |
257 | input->audioset = (1 << cx->nof_audio_inputs) - 1; | |
258 | input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ? | |
259 | cx->tuner_std : V4L2_STD_ALL; | |
260 | return 0; | |
261 | } | |
262 | ||
263 | int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *audio) | |
264 | { | |
265 | const struct cx18_card_audio_input *aud_input = | |
266 | cx->card->audio_inputs + index; | |
267 | static const char * const input_strs[] = { | |
268 | "Tuner 1", | |
269 | "Line In 1", | |
270 | "Line In 2" | |
271 | }; | |
272 | ||
273 | memset(audio, 0, sizeof(*audio)); | |
274 | if (index >= cx->nof_audio_inputs) | |
275 | return -EINVAL; | |
276 | strlcpy(audio->name, input_strs[aud_input->audio_type - 1], | |
277 | sizeof(audio->name)); | |
278 | audio->index = index; | |
279 | audio->capability = V4L2_AUDCAP_STEREO; | |
280 | return 0; | |
281 | } |