diff options
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r-- | drivers/media/video/cx18/Kconfig | 4 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-av-core.c | 73 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-av-core.h | 16 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-cards.c | 84 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-cards.h | 50 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-dvb.c | 17 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-gpio.c | 26 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-gpio.h | 1 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-i2c.c | 2 |
9 files changed, 183 insertions, 90 deletions
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig index 5f942690570c..9aefdc5ea79a 100644 --- a/drivers/media/video/cx18/Kconfig +++ b/drivers/media/video/cx18/Kconfig | |||
@@ -10,8 +10,8 @@ config VIDEO_CX18 | |||
10 | select VIDEO_TVEEPROM | 10 | select VIDEO_TVEEPROM |
11 | select VIDEO_CX2341X | 11 | select VIDEO_CX2341X |
12 | select VIDEO_CS5345 | 12 | select VIDEO_CS5345 |
13 | select DVB_S5H1409 | 13 | select DVB_S5H1409 if !DVB_FE_CUSTOMISE |
14 | select MEDIA_TUNER_MXL5005S | 14 | select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE |
15 | ---help--- | 15 | ---help--- |
16 | This is a video4linux driver for Conexant cx23418 based | 16 | This is a video4linux driver for Conexant cx23418 based |
17 | PCI combo video recorder devices. | 17 | PCI combo video recorder devices. |
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index 9a26751615c6..faca43eb940f 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c | |||
@@ -69,6 +69,58 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, | |||
69 | or_value); | 69 | or_value); |
70 | } | 70 | } |
71 | 71 | ||
72 | int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, int no_acfg_mask) | ||
73 | { | ||
74 | int retval; | ||
75 | u32 saved_reg[8] = {0}; | ||
76 | |||
77 | if (no_acfg_mask & CXADEC_NO_ACFG_AFE) { | ||
78 | saved_reg[0] = cx18_av_read4(cx, CXADEC_CHIP_CTRL); | ||
79 | saved_reg[1] = cx18_av_read4(cx, CXADEC_AFE_CTRL); | ||
80 | } | ||
81 | |||
82 | if (no_acfg_mask & CXADEC_NO_ACFG_PLL) { | ||
83 | saved_reg[2] = cx18_av_read4(cx, CXADEC_PLL_CTRL1); | ||
84 | saved_reg[3] = cx18_av_read4(cx, CXADEC_VID_PLL_FRAC); | ||
85 | } | ||
86 | |||
87 | if (no_acfg_mask & CXADEC_NO_ACFG_VID) { | ||
88 | saved_reg[4] = cx18_av_read4(cx, CXADEC_HORIZ_TIM_CTRL); | ||
89 | saved_reg[5] = cx18_av_read4(cx, CXADEC_VERT_TIM_CTRL); | ||
90 | saved_reg[6] = cx18_av_read4(cx, CXADEC_SRC_COMB_CFG); | ||
91 | saved_reg[7] = cx18_av_read4(cx, CXADEC_CHROMA_VBIOFF_CFG); | ||
92 | } | ||
93 | |||
94 | retval = cx18_av_write(cx, addr, value); | ||
95 | |||
96 | if (no_acfg_mask & CXADEC_NO_ACFG_AFE) { | ||
97 | cx18_av_write4(cx, CXADEC_CHIP_CTRL, saved_reg[0]); | ||
98 | cx18_av_write4(cx, CXADEC_AFE_CTRL, saved_reg[1]); | ||
99 | } | ||
100 | |||
101 | if (no_acfg_mask & CXADEC_NO_ACFG_PLL) { | ||
102 | cx18_av_write4(cx, CXADEC_PLL_CTRL1, saved_reg[2]); | ||
103 | cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, saved_reg[3]); | ||
104 | } | ||
105 | |||
106 | if (no_acfg_mask & CXADEC_NO_ACFG_VID) { | ||
107 | cx18_av_write4(cx, CXADEC_HORIZ_TIM_CTRL, saved_reg[4]); | ||
108 | cx18_av_write4(cx, CXADEC_VERT_TIM_CTRL, saved_reg[5]); | ||
109 | cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, saved_reg[6]); | ||
110 | cx18_av_write4(cx, CXADEC_CHROMA_VBIOFF_CFG, saved_reg[7]); | ||
111 | } | ||
112 | |||
113 | return retval; | ||
114 | } | ||
115 | |||
116 | int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned and_mask, | ||
117 | u8 or_value, int no_acfg_mask) | ||
118 | { | ||
119 | return cx18_av_write_no_acfg(cx, addr, | ||
120 | (cx18_av_read(cx, addr) & and_mask) | | ||
121 | or_value, no_acfg_mask); | ||
122 | } | ||
123 | |||
72 | /* ----------------------------------------------------------------------- */ | 124 | /* ----------------------------------------------------------------------- */ |
73 | 125 | ||
74 | static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, | 126 | static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, |
@@ -170,13 +222,15 @@ static void input_change(struct cx18 *cx) | |||
170 | 222 | ||
171 | /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */ | 223 | /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */ |
172 | if (std & V4L2_STD_SECAM) | 224 | if (std & V4L2_STD_SECAM) |
173 | cx18_av_write(cx, 0x402, 0); | 225 | cx18_av_write_no_acfg(cx, 0x402, 0, CXADEC_NO_ACFG_ALL); |
174 | else { | 226 | else { |
175 | cx18_av_write(cx, 0x402, 0x04); | 227 | cx18_av_write_no_acfg(cx, 0x402, 0x04, CXADEC_NO_ACFG_ALL); |
176 | cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); | 228 | cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); |
177 | } | 229 | } |
178 | cx18_av_and_or(cx, 0x401, ~0x60, 0); | 230 | cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0, |
179 | cx18_av_and_or(cx, 0x401, ~0x60, 0x60); | 231 | CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); |
232 | cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0x60, | ||
233 | CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); | ||
180 | 234 | ||
181 | if (std & V4L2_STD_525_60) { | 235 | if (std & V4L2_STD_525_60) { |
182 | if (std == V4L2_STD_NTSC_M_JP) { | 236 | if (std == V4L2_STD_NTSC_M_JP) { |
@@ -228,7 +282,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, | |||
228 | 282 | ||
229 | if ((vid_input & ~0xff0) || | 283 | if ((vid_input & ~0xff0) || |
230 | luma < CX18_AV_SVIDEO_LUMA1 || | 284 | luma < CX18_AV_SVIDEO_LUMA1 || |
231 | luma > CX18_AV_SVIDEO_LUMA4 || | 285 | luma > CX18_AV_SVIDEO_LUMA8 || |
232 | chroma < CX18_AV_SVIDEO_CHROMA4 || | 286 | chroma < CX18_AV_SVIDEO_CHROMA4 || |
233 | chroma > CX18_AV_SVIDEO_CHROMA8) { | 287 | chroma > CX18_AV_SVIDEO_CHROMA8) { |
234 | CX18_ERR("0x%04x is not a valid video input!\n", | 288 | CX18_ERR("0x%04x is not a valid video input!\n", |
@@ -262,7 +316,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, | |||
262 | 316 | ||
263 | cx18_av_write(cx, 0x103, reg); | 317 | cx18_av_write(cx, 0x103, reg); |
264 | /* Set INPUT_MODE to Composite (0) or S-Video (1) */ | 318 | /* Set INPUT_MODE to Composite (0) or S-Video (1) */ |
265 | cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); | 319 | cx18_av_and_or_no_acfg(cx, 0x401, ~0x6, is_composite ? 0 : 0x02, |
320 | CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); | ||
266 | /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ | 321 | /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ |
267 | cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); | 322 | cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); |
268 | /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ | 323 | /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ |
@@ -318,12 +373,12 @@ static int set_v4lstd(struct cx18 *cx) | |||
318 | This happens for example with the Yuan MPC622. */ | 373 | This happens for example with the Yuan MPC622. */ |
319 | if (fmt >= 4 && fmt < 8) { | 374 | if (fmt >= 4 && fmt < 8) { |
320 | /* Set format to NTSC-M */ | 375 | /* Set format to NTSC-M */ |
321 | cx18_av_and_or(cx, 0x400, ~0xf, 1); | 376 | cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, 1, CXADEC_NO_ACFG_AFE); |
322 | /* Turn off LCOMB */ | 377 | /* Turn off LCOMB */ |
323 | cx18_av_and_or(cx, 0x47b, ~6, 0); | 378 | cx18_av_and_or(cx, 0x47b, ~6, 0); |
324 | } | 379 | } |
325 | cx18_av_and_or(cx, 0x400, ~0xf, fmt); | 380 | cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, fmt, CXADEC_NO_ACFG_AFE); |
326 | cx18_av_and_or(cx, 0x403, ~0x3, pal_m); | 381 | cx18_av_and_or_no_acfg(cx, 0x403, ~0x3, pal_m, CXADEC_NO_ACFG_ALL); |
327 | cx18_av_vbi_setup(cx); | 382 | cx18_av_vbi_setup(cx); |
328 | input_change(cx); | 383 | input_change(cx); |
329 | return 0; | 384 | return 0; |
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index 786901d72e9a..c172823ce1d8 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h | |||
@@ -37,12 +37,16 @@ enum cx18_av_video_input { | |||
37 | CX18_AV_COMPOSITE7, | 37 | CX18_AV_COMPOSITE7, |
38 | CX18_AV_COMPOSITE8, | 38 | CX18_AV_COMPOSITE8, |
39 | 39 | ||
40 | /* S-Video inputs consist of one luma input (In1-In4) ORed with one | 40 | /* S-Video inputs consist of one luma input (In1-In8) ORed with one |
41 | chroma input (In5-In8) */ | 41 | chroma input (In5-In8) */ |
42 | CX18_AV_SVIDEO_LUMA1 = 0x10, | 42 | CX18_AV_SVIDEO_LUMA1 = 0x10, |
43 | CX18_AV_SVIDEO_LUMA2 = 0x20, | 43 | CX18_AV_SVIDEO_LUMA2 = 0x20, |
44 | CX18_AV_SVIDEO_LUMA3 = 0x30, | 44 | CX18_AV_SVIDEO_LUMA3 = 0x30, |
45 | CX18_AV_SVIDEO_LUMA4 = 0x40, | 45 | CX18_AV_SVIDEO_LUMA4 = 0x40, |
46 | CX18_AV_SVIDEO_LUMA5 = 0x50, | ||
47 | CX18_AV_SVIDEO_LUMA6 = 0x60, | ||
48 | CX18_AV_SVIDEO_LUMA7 = 0x70, | ||
49 | CX18_AV_SVIDEO_LUMA8 = 0x80, | ||
46 | CX18_AV_SVIDEO_CHROMA4 = 0x400, | 50 | CX18_AV_SVIDEO_CHROMA4 = 0x400, |
47 | CX18_AV_SVIDEO_CHROMA5 = 0x500, | 51 | CX18_AV_SVIDEO_CHROMA5 = 0x500, |
48 | CX18_AV_SVIDEO_CHROMA6 = 0x600, | 52 | CX18_AV_SVIDEO_CHROMA6 = 0x600, |
@@ -291,14 +295,24 @@ struct cx18_av_state { | |||
291 | #define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */ | 295 | #define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */ |
292 | #define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */ | 296 | #define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */ |
293 | 297 | ||
298 | /* Flags on what to preserve on write to 0x400-0x403 with cx18_av_.*_no_acfg()*/ | ||
299 | #define CXADEC_NO_ACFG_AFE 0x01 /* Preserve 0x100-0x107 */ | ||
300 | #define CXADEC_NO_ACFG_PLL 0x02 /* Preserve 0x108-0x10f */ | ||
301 | #define CXADEC_NO_ACFG_VID 0x04 /* Preserve 0x470-0x47f */ | ||
302 | #define CXADEC_NO_ACFG_ALL 0x07 | ||
303 | |||
294 | /* ----------------------------------------------------------------------- */ | 304 | /* ----------------------------------------------------------------------- */ |
295 | /* cx18_av-core.c */ | 305 | /* cx18_av-core.c */ |
296 | int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); | 306 | int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); |
297 | int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); | 307 | int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); |
308 | int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, | ||
309 | int no_acfg_mask); | ||
298 | u8 cx18_av_read(struct cx18 *cx, u16 addr); | 310 | u8 cx18_av_read(struct cx18 *cx, u16 addr); |
299 | u32 cx18_av_read4(struct cx18 *cx, u16 addr); | 311 | u32 cx18_av_read4(struct cx18 *cx, u16 addr); |
300 | int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); | 312 | int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); |
301 | int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); | 313 | int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); |
314 | int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned mask, u8 value, | ||
315 | int no_acfg_mask); | ||
302 | int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); | 316 | int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); |
303 | 317 | ||
304 | /* ----------------------------------------------------------------------- */ | 318 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index baccd079243d..c26e0ef5b075 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include "cx18-driver.h" | 24 | #include "cx18-driver.h" |
25 | #include "cx18-cards.h" | 25 | #include "cx18-cards.h" |
26 | #include "cx18-av-core.h" | ||
26 | #include "cx18-i2c.h" | 27 | #include "cx18-i2c.h" |
27 | #include <media/cs5345.h> | 28 | #include <media/cs5345.h> |
28 | 29 | ||
@@ -54,22 +55,22 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { | |||
54 | .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | | 55 | .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | |
55 | CX18_HW_CS5345 | CX18_HW_DVB, | 56 | CX18_HW_CS5345 | CX18_HW_DVB, |
56 | .video_inputs = { | 57 | .video_inputs = { |
57 | { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, | 58 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, |
58 | { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, | 59 | { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, |
59 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, | 60 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, |
60 | { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 }, | 61 | { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, |
61 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 }, | 62 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, |
62 | }, | 63 | }, |
63 | .audio_inputs = { | 64 | .audio_inputs = { |
64 | { CX18_CARD_INPUT_AUD_TUNER, | 65 | { CX18_CARD_INPUT_AUD_TUNER, |
65 | CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, | 66 | CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, |
66 | { CX18_CARD_INPUT_LINE_IN1, | 67 | { CX18_CARD_INPUT_LINE_IN1, |
67 | CX23418_AUDIO_SERIAL, CS5345_IN_2 }, | 68 | CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, |
68 | { CX18_CARD_INPUT_LINE_IN2, | 69 | { CX18_CARD_INPUT_LINE_IN2, |
69 | CX23418_AUDIO_SERIAL, CS5345_IN_2 }, | 70 | CX18_AV_AUDIO_SERIAL, CS5345_IN_3 }, |
70 | }, | 71 | }, |
71 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | 72 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, |
72 | CX23418_AUDIO_SERIAL, 0 }, | 73 | CX18_AV_AUDIO_SERIAL, CS5345_IN_4 }, |
73 | .ddr = { | 74 | .ddr = { |
74 | /* ESMT M13S128324A-5B memory */ | 75 | /* ESMT M13S128324A-5B memory */ |
75 | .chip_config = 0x003, | 76 | .chip_config = 0x003, |
@@ -81,6 +82,11 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { | |||
81 | }, | 82 | }, |
82 | .gpio_init.initial_value = 0x3001, | 83 | .gpio_init.initial_value = 0x3001, |
83 | .gpio_init.direction = 0x3001, | 84 | .gpio_init.direction = 0x3001, |
85 | .gpio_i2c_slave_reset = { | ||
86 | .active_lo_mask = 0x3001, | ||
87 | .msecs_asserted = 10, | ||
88 | .msecs_recovery = 40, | ||
89 | }, | ||
84 | .i2c = &cx18_i2c_std, | 90 | .i2c = &cx18_i2c_std, |
85 | }; | 91 | }; |
86 | 92 | ||
@@ -94,22 +100,22 @@ static const struct cx18_card cx18_card_hvr1600_samsung = { | |||
94 | .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | | 100 | .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | |
95 | CX18_HW_CS5345 | CX18_HW_DVB, | 101 | CX18_HW_CS5345 | CX18_HW_DVB, |
96 | .video_inputs = { | 102 | .video_inputs = { |
97 | { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, | 103 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, |
98 | { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, | 104 | { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, |
99 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, | 105 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, |
100 | { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 }, | 106 | { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, |
101 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 }, | 107 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, |
102 | }, | 108 | }, |
103 | .audio_inputs = { | 109 | .audio_inputs = { |
104 | { CX18_CARD_INPUT_AUD_TUNER, | 110 | { CX18_CARD_INPUT_AUD_TUNER, |
105 | CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, | 111 | CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, |
106 | { CX18_CARD_INPUT_LINE_IN1, | 112 | { CX18_CARD_INPUT_LINE_IN1, |
107 | CX23418_AUDIO_SERIAL, CS5345_IN_2 }, | 113 | CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, |
108 | { CX18_CARD_INPUT_LINE_IN2, | 114 | { CX18_CARD_INPUT_LINE_IN2, |
109 | CX23418_AUDIO_SERIAL, CS5345_IN_2 }, | 115 | CX18_AV_AUDIO_SERIAL, CS5345_IN_3 }, |
110 | }, | 116 | }, |
111 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | 117 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, |
112 | CX23418_AUDIO_SERIAL, 0 }, | 118 | CX18_AV_AUDIO_SERIAL, CS5345_IN_4 }, |
113 | .ddr = { | 119 | .ddr = { |
114 | /* Samsung K4D263238G-VC33 memory */ | 120 | /* Samsung K4D263238G-VC33 memory */ |
115 | .chip_config = 0x003, | 121 | .chip_config = 0x003, |
@@ -121,6 +127,11 @@ static const struct cx18_card cx18_card_hvr1600_samsung = { | |||
121 | }, | 127 | }, |
122 | .gpio_init.initial_value = 0x3001, | 128 | .gpio_init.initial_value = 0x3001, |
123 | .gpio_init.direction = 0x3001, | 129 | .gpio_init.direction = 0x3001, |
130 | .gpio_i2c_slave_reset = { | ||
131 | .active_lo_mask = 0x3001, | ||
132 | .msecs_asserted = 10, | ||
133 | .msecs_recovery = 40, | ||
134 | }, | ||
124 | .i2c = &cx18_i2c_std, | 135 | .i2c = &cx18_i2c_std, |
125 | }; | 136 | }; |
126 | 137 | ||
@@ -141,19 +152,19 @@ static const struct cx18_card cx18_card_h900 = { | |||
141 | .hw_audio_ctrl = CX18_HW_CX23418, | 152 | .hw_audio_ctrl = CX18_HW_CX23418, |
142 | .hw_all = CX18_HW_TUNER, | 153 | .hw_all = CX18_HW_TUNER, |
143 | .video_inputs = { | 154 | .video_inputs = { |
144 | { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE2 }, | 155 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, |
145 | { CX18_CARD_INPUT_SVIDEO1, 1, | 156 | { CX18_CARD_INPUT_SVIDEO1, 1, |
146 | CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 }, | 157 | CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, |
147 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 }, | 158 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, |
148 | }, | 159 | }, |
149 | .audio_inputs = { | 160 | .audio_inputs = { |
150 | { CX18_CARD_INPUT_AUD_TUNER, | 161 | { CX18_CARD_INPUT_AUD_TUNER, |
151 | CX23418_AUDIO8, 0 }, | 162 | CX18_AV_AUDIO8, 0 }, |
152 | { CX18_CARD_INPUT_LINE_IN1, | 163 | { CX18_CARD_INPUT_LINE_IN1, |
153 | CX23418_AUDIO_SERIAL, 0 }, | 164 | CX18_AV_AUDIO_SERIAL, 0 }, |
154 | }, | 165 | }, |
155 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | 166 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, |
156 | CX23418_AUDIO_SERIAL, 0 }, | 167 | CX18_AV_AUDIO_SERIAL, 0 }, |
157 | .tuners = { | 168 | .tuners = { |
158 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | 169 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, |
159 | }, | 170 | }, |
@@ -183,23 +194,26 @@ static const struct cx18_card_pci_info cx18_pci_mpc718[] = { | |||
183 | static const struct cx18_card cx18_card_mpc718 = { | 194 | static const struct cx18_card cx18_card_mpc718 = { |
184 | .type = CX18_CARD_YUAN_MPC718, | 195 | .type = CX18_CARD_YUAN_MPC718, |
185 | .name = "Yuan MPC718", | 196 | .name = "Yuan MPC718", |
186 | .comment = "Not yet supported!\n", | 197 | .comment = "Some Composite and S-Video inputs are currently working.\n", |
187 | .v4l2_capabilities = 0, | 198 | .v4l2_capabilities = CX18_CAP_ENCODER, |
188 | .hw_audio_ctrl = CX18_HW_CX23418, | 199 | .hw_audio_ctrl = CX18_HW_CX23418, |
189 | .hw_all = CX18_HW_TUNER, | 200 | .hw_all = CX18_HW_TUNER, |
190 | .video_inputs = { | 201 | .video_inputs = { |
191 | { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, | 202 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, |
192 | { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, | 203 | { CX18_CARD_INPUT_SVIDEO1, 1, |
193 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, | 204 | CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, |
205 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, | ||
206 | { CX18_CARD_INPUT_SVIDEO2, 2, | ||
207 | CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 }, | ||
208 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, | ||
209 | { CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 }, | ||
194 | }, | 210 | }, |
195 | .audio_inputs = { | 211 | .audio_inputs = { |
196 | { CX18_CARD_INPUT_AUD_TUNER, | 212 | { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, |
197 | CX23418_AUDIO8, 0 }, | 213 | { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 0 }, |
198 | { CX18_CARD_INPUT_LINE_IN1, | 214 | { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 0 }, |
199 | CX23418_AUDIO_SERIAL, 0 }, | ||
200 | }, | 215 | }, |
201 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, | 216 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 }, |
202 | CX23418_AUDIO_SERIAL, 0 }, | ||
203 | .tuners = { | 217 | .tuners = { |
204 | /* XC3028 tuner */ | 218 | /* XC3028 tuner */ |
205 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | 219 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, |
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h index bccb67f0db16..dc2dd945d4c3 100644 --- a/drivers/media/video/cx18/cx18-cards.h +++ b/drivers/media/video/cx18/cx18-cards.h | |||
@@ -36,36 +36,6 @@ | |||
36 | #define CX18_CARD_INPUT_COMPOSITE2 5 | 36 | #define CX18_CARD_INPUT_COMPOSITE2 5 |
37 | #define CX18_CARD_INPUT_COMPOSITE3 6 | 37 | #define CX18_CARD_INPUT_COMPOSITE3 6 |
38 | 38 | ||
39 | enum cx34180_video_input { | ||
40 | /* Composite video inputs In1-In8 */ | ||
41 | CX23418_COMPOSITE1 = 1, | ||
42 | CX23418_COMPOSITE2, | ||
43 | CX23418_COMPOSITE3, | ||
44 | CX23418_COMPOSITE4, | ||
45 | CX23418_COMPOSITE5, | ||
46 | CX23418_COMPOSITE6, | ||
47 | CX23418_COMPOSITE7, | ||
48 | CX23418_COMPOSITE8, | ||
49 | |||
50 | /* S-Video inputs consist of one luma input (In1-In4) ORed with one | ||
51 | chroma input (In5-In8) */ | ||
52 | CX23418_SVIDEO_LUMA1 = 0x10, | ||
53 | CX23418_SVIDEO_LUMA2 = 0x20, | ||
54 | CX23418_SVIDEO_LUMA3 = 0x30, | ||
55 | CX23418_SVIDEO_LUMA4 = 0x40, | ||
56 | CX23418_SVIDEO_CHROMA4 = 0x400, | ||
57 | CX23418_SVIDEO_CHROMA5 = 0x500, | ||
58 | CX23418_SVIDEO_CHROMA6 = 0x600, | ||
59 | CX23418_SVIDEO_CHROMA7 = 0x700, | ||
60 | CX23418_SVIDEO_CHROMA8 = 0x800, | ||
61 | |||
62 | /* S-Video aliases for common luma/chroma combinations */ | ||
63 | CX23418_SVIDEO1 = 0x510, | ||
64 | CX23418_SVIDEO2 = 0x620, | ||
65 | CX23418_SVIDEO3 = 0x730, | ||
66 | CX23418_SVIDEO4 = 0x840, | ||
67 | }; | ||
68 | |||
69 | /* audio inputs */ | 39 | /* audio inputs */ |
70 | #define CX18_CARD_INPUT_AUD_TUNER 1 | 40 | #define CX18_CARD_INPUT_AUD_TUNER 1 |
71 | #define CX18_CARD_INPUT_LINE_IN1 2 | 41 | #define CX18_CARD_INPUT_LINE_IN1 2 |
@@ -75,16 +45,6 @@ enum cx34180_video_input { | |||
75 | #define CX18_CARD_MAX_AUDIO_INPUTS 3 | 45 | #define CX18_CARD_MAX_AUDIO_INPUTS 3 |
76 | #define CX18_CARD_MAX_TUNERS 2 | 46 | #define CX18_CARD_MAX_TUNERS 2 |
77 | 47 | ||
78 | enum cx23418_audio_input { | ||
79 | /* Audio inputs: serial or In4-In8 */ | ||
80 | CX23418_AUDIO_SERIAL, | ||
81 | CX23418_AUDIO4 = 4, | ||
82 | CX23418_AUDIO5, | ||
83 | CX23418_AUDIO6, | ||
84 | CX23418_AUDIO7, | ||
85 | CX23418_AUDIO8, | ||
86 | }; | ||
87 | |||
88 | /* V4L2 capability aliases */ | 48 | /* V4L2 capability aliases */ |
89 | #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ | 49 | #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ |
90 | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE) | 50 | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE) |
@@ -118,6 +78,13 @@ struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */ | |||
118 | u32 initial_value; | 78 | u32 initial_value; |
119 | }; | 79 | }; |
120 | 80 | ||
81 | struct cx18_gpio_i2c_slave_reset { | ||
82 | u32 active_lo_mask; /* GPIO outputs that reset i2c chips when low */ | ||
83 | u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */ | ||
84 | int msecs_asserted; /* time period reset must remain asserted */ | ||
85 | int msecs_recovery; /* time after deassert for chips to be ready */ | ||
86 | }; | ||
87 | |||
121 | struct cx18_card_tuner { | 88 | struct cx18_card_tuner { |
122 | v4l2_std_id std; /* standard for which the tuner is suitable */ | 89 | v4l2_std_id std; /* standard for which the tuner is suitable */ |
123 | int tuner; /* tuner ID (from tuner.h) */ | 90 | int tuner; /* tuner ID (from tuner.h) */ |
@@ -154,7 +121,8 @@ struct cx18_card { | |||
154 | 121 | ||
155 | /* GPIO card-specific settings */ | 122 | /* GPIO card-specific settings */ |
156 | u8 xceive_pin; /* XCeive tuner GPIO reset pin */ | 123 | u8 xceive_pin; /* XCeive tuner GPIO reset pin */ |
157 | struct cx18_gpio_init gpio_init; | 124 | struct cx18_gpio_init gpio_init; |
125 | struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset; | ||
158 | 126 | ||
159 | struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS]; | 127 | struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS]; |
160 | struct cx18_card_tuner_i2c *i2c; | 128 | struct cx18_card_tuner_i2c *i2c; |
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index c9744173f969..cae38985b131 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c | |||
@@ -69,11 +69,21 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) | |||
69 | struct dvb_demux *demux = feed->demux; | 69 | struct dvb_demux *demux = feed->demux; |
70 | struct cx18_stream *stream = (struct cx18_stream *) demux->priv; | 70 | struct cx18_stream *stream = (struct cx18_stream *) demux->priv; |
71 | struct cx18 *cx = stream->cx; | 71 | struct cx18 *cx = stream->cx; |
72 | int ret = -EINVAL; | 72 | int ret; |
73 | u32 v; | 73 | u32 v; |
74 | 74 | ||
75 | CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n", | 75 | CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n", |
76 | feed->pid, feed->index); | 76 | feed->pid, feed->index); |
77 | |||
78 | mutex_lock(&cx->serialize_lock); | ||
79 | ret = cx18_init_on_first_open(cx); | ||
80 | mutex_unlock(&cx->serialize_lock); | ||
81 | if (ret) { | ||
82 | CX18_ERR("Failed to initialize firmware starting DVB feed\n"); | ||
83 | return ret; | ||
84 | } | ||
85 | ret = -EINVAL; | ||
86 | |||
77 | switch (cx->card->type) { | 87 | switch (cx->card->type) { |
78 | case CX18_CARD_HVR_1600_ESMT: | 88 | case CX18_CARD_HVR_1600_ESMT: |
79 | case CX18_CARD_HVR_1600_SAMSUNG: | 89 | case CX18_CARD_HVR_1600_SAMSUNG: |
@@ -101,6 +111,11 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) | |||
101 | if (stream->dvb.feeding++ == 0) { | 111 | if (stream->dvb.feeding++ == 0) { |
102 | CX18_DEBUG_INFO("Starting Transport DMA\n"); | 112 | CX18_DEBUG_INFO("Starting Transport DMA\n"); |
103 | ret = cx18_start_v4l2_encode_stream(stream); | 113 | ret = cx18_start_v4l2_encode_stream(stream); |
114 | if (ret < 0) { | ||
115 | CX18_DEBUG_INFO( | ||
116 | "Failed to start Transport DMA\n"); | ||
117 | stream->dvb.feeding--; | ||
118 | } | ||
104 | } else | 119 | } else |
105 | ret = 0; | 120 | ret = 0; |
106 | mutex_unlock(&stream->dvb.feedlock); | 121 | mutex_unlock(&stream->dvb.feedlock); |
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index ceb63653c926..b302833f6f9d 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c | |||
@@ -53,10 +53,34 @@ static void gpio_write(struct cx18 *cx) | |||
53 | write_reg(((dir & 0xffff) << 16) | (val & 0xffff), | 53 | write_reg(((dir & 0xffff) << 16) | (val & 0xffff), |
54 | CX18_REG_GPIO_OUT1); | 54 | CX18_REG_GPIO_OUT1); |
55 | write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2); | 55 | write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2); |
56 | write_reg((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), | 56 | write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), |
57 | CX18_REG_GPIO_OUT2); | 57 | CX18_REG_GPIO_OUT2); |
58 | } | 58 | } |
59 | 59 | ||
60 | void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) | ||
61 | { | ||
62 | const struct cx18_gpio_i2c_slave_reset *p; | ||
63 | |||
64 | p = &cx->card->gpio_i2c_slave_reset; | ||
65 | |||
66 | if ((p->active_lo_mask | p->active_hi_mask) == 0) | ||
67 | return; | ||
68 | |||
69 | /* Assuming that the masks are a subset of the bits in gpio_dir */ | ||
70 | |||
71 | /* Assert */ | ||
72 | cx->gpio_val = | ||
73 | (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); | ||
74 | gpio_write(cx); | ||
75 | schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); | ||
76 | |||
77 | /* Deassert */ | ||
78 | cx->gpio_val = | ||
79 | (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); | ||
80 | gpio_write(cx); | ||
81 | schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); | ||
82 | } | ||
83 | |||
60 | void cx18_gpio_init(struct cx18 *cx) | 84 | void cx18_gpio_init(struct cx18 *cx) |
61 | { | 85 | { |
62 | cx->gpio_dir = cx->card->gpio_init.direction; | 86 | cx->gpio_dir = cx->card->gpio_init.direction; |
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h index 41bac8856b50..525c328f748a 100644 --- a/drivers/media/video/cx18/cx18-gpio.h +++ b/drivers/media/video/cx18/cx18-gpio.h | |||
@@ -21,4 +21,5 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | void cx18_gpio_init(struct cx18 *cx); | 23 | void cx18_gpio_init(struct cx18 *cx); |
24 | void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); | ||
24 | int cx18_reset_tuner_gpio(void *dev, int cmd, int value); | 25 | int cx18_reset_tuner_gpio(void *dev, int cmd, int value); |
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 1d6c51a75313..680bc4e35b79 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c | |||
@@ -405,6 +405,8 @@ int init_cx18_i2c(struct cx18 *cx) | |||
405 | cx18_setscl(&cx->i2c_algo_cb_data[1], 1); | 405 | cx18_setscl(&cx->i2c_algo_cb_data[1], 1); |
406 | cx18_setsda(&cx->i2c_algo_cb_data[1], 1); | 406 | cx18_setsda(&cx->i2c_algo_cb_data[1], 1); |
407 | 407 | ||
408 | cx18_reset_i2c_slaves_gpio(cx); | ||
409 | |||
408 | return i2c_bit_add_bus(&cx->i2c_adap[0]) || | 410 | return i2c_bit_add_bus(&cx->i2c_adap[0]) || |
409 | i2c_bit_add_bus(&cx->i2c_adap[1]); | 411 | i2c_bit_add_bus(&cx->i2c_adap[1]); |
410 | } | 412 | } |