Commit b1526421eac9a912b2cda7e147f1da2aa31be278

Authored by Andy Walls
Committed by Mauro Carvalho Chehab
1 parent 4519064c1c

V4L/DVB (8913): cx18: Create cx18_ specific wrappers for all pci mmio accessesors.

cx18: Create cx18_ specific wrappers for all pci mmio accessesors.  This is a
first step in instrumenting all CX23418 PCI bus IO, to debug problems with
accessing the CX23418's PCI memory mapped IO.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Showing 19 changed files with 468 additions and 263 deletions Inline Diff

drivers/media/video/cx18/Makefile
1 cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.o \ 1 cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.o \
2 cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \ 2 cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \
3 cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \ 3 cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
4 cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \ 4 cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \
5 cx18-dvb.o 5 cx18-dvb.o cx18-io.o
6 6
7 obj-$(CONFIG_VIDEO_CX18) += cx18.o 7 obj-$(CONFIG_VIDEO_CX18) += cx18.o
8 8
9 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 9 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
10 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 10 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
11 EXTRA_CFLAGS += -Idrivers/media/common/tuners 11 EXTRA_CFLAGS += -Idrivers/media/common/tuners
12 12
drivers/media/video/cx18/cx18-audio.c
1 /* 1 /*
2 * cx18 audio-related functions 2 * cx18 audio-related functions
3 * 3 *
4 * Derived from ivtv-audio.c 4 * Derived from ivtv-audio.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 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 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 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 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24 #include "cx18-driver.h" 24 #include "cx18-driver.h"
25 #include "cx18-io.h"
25 #include "cx18-i2c.h" 26 #include "cx18-i2c.h"
26 #include "cx18-cards.h" 27 #include "cx18-cards.h"
27 #include "cx18-audio.h" 28 #include "cx18-audio.h"
28 29
29 #define CX18_AUDIO_ENABLE 0xc72014 30 #define CX18_AUDIO_ENABLE 0xc72014
30 31
31 /* Selects the audio input and output according to the current 32 /* Selects the audio input and output according to the current
32 settings. */ 33 settings. */
33 int cx18_audio_set_io(struct cx18 *cx) 34 int cx18_audio_set_io(struct cx18 *cx)
34 { 35 {
35 struct v4l2_routing route; 36 struct v4l2_routing route;
36 u32 audio_input; 37 u32 audio_input;
37 u32 val; 38 u32 val;
38 int mux_input; 39 int mux_input;
39 int err; 40 int err;
40 41
41 /* Determine which input to use */ 42 /* Determine which input to use */
42 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { 43 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
43 audio_input = cx->card->radio_input.audio_input; 44 audio_input = cx->card->radio_input.audio_input;
44 mux_input = cx->card->radio_input.muxer_input; 45 mux_input = cx->card->radio_input.muxer_input;
45 } else { 46 } else {
46 audio_input = 47 audio_input =
47 cx->card->audio_inputs[cx->audio_input].audio_input; 48 cx->card->audio_inputs[cx->audio_input].audio_input;
48 mux_input = 49 mux_input =
49 cx->card->audio_inputs[cx->audio_input].muxer_input; 50 cx->card->audio_inputs[cx->audio_input].muxer_input;
50 } 51 }
51 52
52 /* handle muxer chips */ 53 /* handle muxer chips */
53 route.input = mux_input; 54 route.input = mux_input;
54 route.output = 0; 55 route.output = 0;
55 cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route); 56 cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
56 57
57 route.input = audio_input; 58 route.input = audio_input;
58 err = cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, 59 err = cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
59 VIDIOC_INT_S_AUDIO_ROUTING, &route); 60 VIDIOC_INT_S_AUDIO_ROUTING, &route);
60 if (err) 61 if (err)
61 return err; 62 return err;
62 63
63 val = read_reg(CX18_AUDIO_ENABLE) & ~0x30; 64 val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30;
64 val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : 65 val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
65 (audio_input << 4); 66 (audio_input << 4);
66 write_reg(val | 0xb00, CX18_AUDIO_ENABLE); 67 cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE);
67 cx18_vapi(cx, CX18_APU_RESETAI, 1, 0); 68 cx18_vapi(cx, CX18_APU_RESETAI, 1, 0);
68 return 0; 69 return 0;
69 } 70 }
70 71
71 void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route) 72 void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route)
72 { 73 {
73 cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, 74 cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
74 VIDIOC_INT_S_AUDIO_ROUTING, route); 75 VIDIOC_INT_S_AUDIO_ROUTING, route);
75 } 76 }
76 77
77 void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq) 78 void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq)
78 { 79 {
79 static u32 freqs[3] = { 44100, 48000, 32000 }; 80 static u32 freqs[3] = { 44100, 48000, 32000 };
80 81
81 /* The audio clock of the digitizer must match the codec sample 82 /* The audio clock of the digitizer must match the codec sample
82 rate otherwise you get some very strange effects. */ 83 rate otherwise you get some very strange effects. */
83 if (freq > 2) 84 if (freq > 2)
84 return; 85 return;
85 cx18_call_i2c_clients(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[freq]); 86 cx18_call_i2c_clients(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[freq]);
86 } 87 }
87 88
drivers/media/video/cx18/cx18-av-core.c
1 /* 1 /*
2 * cx18 ADEC audio functions 2 * cx18 ADEC audio functions
3 * 3 *
4 * Derived from cx25840-core.c 4 * Derived from cx25840-core.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2 10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version. 11 * of the License, or (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 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 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA. 21 * 02110-1301, USA.
22 */ 22 */
23 23
24 #include "cx18-driver.h" 24 #include "cx18-driver.h"
25 #include "cx18-io.h"
25 26
26 int cx18_av_write(struct cx18 *cx, u16 addr, u8 value) 27 int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
27 { 28 {
28 u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3)); 29 u32 reg = 0xc40000 + (addr & ~3);
29 u32 mask = 0xff; 30 u32 mask = 0xff;
30 int shift = (addr & 3) * 8; 31 int shift = (addr & 3) * 8;
32 u32 x = cx18_read_reg(cx, reg);
31 33
32 x = (x & ~(mask << shift)) | ((u32)value << shift); 34 x = (x & ~(mask << shift)) | ((u32)value << shift);
33 writel(x, cx->reg_mem + 0xc40000 + (addr & ~3)); 35 cx18_write_reg(cx, x, reg);
34 return 0; 36 return 0;
35 } 37 }
36 38
37 int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value) 39 int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
38 { 40 {
39 writel(value, cx->reg_mem + 0xc40000 + addr); 41 cx18_write_reg(cx, value, 0xc40000 + addr);
40 return 0; 42 return 0;
41 } 43 }
42 44
43 u8 cx18_av_read(struct cx18 *cx, u16 addr) 45 u8 cx18_av_read(struct cx18 *cx, u16 addr)
44 { 46 {
45 u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3)); 47 u32 x = cx18_read_reg(cx, 0xc40000 + (addr & ~3));
46 int shift = (addr & 3) * 8; 48 int shift = (addr & 3) * 8;
47 49
48 return (x >> shift) & 0xff; 50 return (x >> shift) & 0xff;
49 } 51 }
50 52
51 u32 cx18_av_read4(struct cx18 *cx, u16 addr) 53 u32 cx18_av_read4(struct cx18 *cx, u16 addr)
52 { 54 {
53 return readl(cx->reg_mem + 0xc40000 + addr); 55 return cx18_read_reg(cx, 0xc40000 + addr);
54 } 56 }
55 57
56 int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask, 58 int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
57 u8 or_value) 59 u8 or_value)
58 { 60 {
59 return cx18_av_write(cx, addr, 61 return cx18_av_write(cx, addr,
60 (cx18_av_read(cx, addr) & and_mask) | 62 (cx18_av_read(cx, addr) & and_mask) |
61 or_value); 63 or_value);
62 } 64 }
63 65
64 int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, 66 int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
65 u32 or_value) 67 u32 or_value)
66 { 68 {
67 return cx18_av_write4(cx, addr, 69 return cx18_av_write4(cx, addr,
68 (cx18_av_read4(cx, addr) & and_mask) | 70 (cx18_av_read4(cx, addr) & and_mask) |
69 or_value); 71 or_value);
70 } 72 }
71 73
72 /* ----------------------------------------------------------------------- */ 74 /* ----------------------------------------------------------------------- */
73 75
74 static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, 76 static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
75 enum cx18_av_audio_input aud_input); 77 enum cx18_av_audio_input aud_input);
76 static void log_audio_status(struct cx18 *cx); 78 static void log_audio_status(struct cx18 *cx);
77 static void log_video_status(struct cx18 *cx); 79 static void log_video_status(struct cx18 *cx);
78 80
79 /* ----------------------------------------------------------------------- */ 81 /* ----------------------------------------------------------------------- */
80 82
81 static void cx18_av_initialize(struct cx18 *cx) 83 static void cx18_av_initialize(struct cx18 *cx)
82 { 84 {
83 struct cx18_av_state *state = &cx->av_state; 85 struct cx18_av_state *state = &cx->av_state;
84 u32 v; 86 u32 v;
85 87
86 cx18_av_loadfw(cx); 88 cx18_av_loadfw(cx);
87 /* Stop 8051 code execution */ 89 /* Stop 8051 code execution */
88 cx18_av_write4(cx, CXADEC_DL_CTL, 0x03000000); 90 cx18_av_write4(cx, CXADEC_DL_CTL, 0x03000000);
89 91
90 /* initallize the PLL by toggling sleep bit */ 92 /* initallize the PLL by toggling sleep bit */
91 v = cx18_av_read4(cx, CXADEC_HOST_REG1); 93 v = cx18_av_read4(cx, CXADEC_HOST_REG1);
92 /* enable sleep mode */ 94 /* enable sleep mode */
93 cx18_av_write4(cx, CXADEC_HOST_REG1, v | 1); 95 cx18_av_write4(cx, CXADEC_HOST_REG1, v | 1);
94 /* disable sleep mode */ 96 /* disable sleep mode */
95 cx18_av_write4(cx, CXADEC_HOST_REG1, v & 0xfffe); 97 cx18_av_write4(cx, CXADEC_HOST_REG1, v & 0xfffe);
96 98
97 /* initialize DLLs */ 99 /* initialize DLLs */
98 v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF; 100 v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF;
99 /* disable FLD */ 101 /* disable FLD */
100 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v); 102 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v);
101 /* enable FLD */ 103 /* enable FLD */
102 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v | 0x10000100); 104 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v | 0x10000100);
103 105
104 v = cx18_av_read4(cx, CXADEC_DLL2_DIAG_CTRL) & 0xE1FFFEFF; 106 v = cx18_av_read4(cx, CXADEC_DLL2_DIAG_CTRL) & 0xE1FFFEFF;
105 /* disable FLD */ 107 /* disable FLD */
106 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v); 108 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v);
107 /* enable FLD */ 109 /* enable FLD */
108 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v | 0x06000100); 110 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v | 0x06000100);
109 111
110 /* set analog bias currents. Set Vreg to 1.20V. */ 112 /* set analog bias currents. Set Vreg to 1.20V. */
111 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL1, 0x000A1802); 113 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL1, 0x000A1802);
112 114
113 v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1; 115 v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1;
114 /* enable TUNE_FIL_RST */ 116 /* enable TUNE_FIL_RST */
115 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v); 117 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v);
116 /* disable TUNE_FIL_RST */ 118 /* disable TUNE_FIL_RST */
117 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v & 0xFFFFFFFE); 119 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v & 0xFFFFFFFE);
118 120
119 /* enable 656 output */ 121 /* enable 656 output */
120 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00); 122 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00);
121 123
122 /* video output drive strength */ 124 /* video output drive strength */
123 cx18_av_and_or4(cx, CXADEC_PIN_CTRL2, ~0, 0x2); 125 cx18_av_and_or4(cx, CXADEC_PIN_CTRL2, ~0, 0x2);
124 126
125 /* reset video */ 127 /* reset video */
126 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000); 128 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
127 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0); 129 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
128 130
129 /* set video to auto-detect */ 131 /* set video to auto-detect */
130 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */ 132 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
131 /* set the comb notch = 1 */ 133 /* set the comb notch = 1 */
132 cx18_av_and_or4(cx, CXADEC_MODE_CTRL, 0xFFF7E7F0, 0x02040800); 134 cx18_av_and_or4(cx, CXADEC_MODE_CTRL, 0xFFF7E7F0, 0x02040800);
133 135
134 /* Enable wtw_en in CRUSH_CTRL (Set bit 22) */ 136 /* Enable wtw_en in CRUSH_CTRL (Set bit 22) */
135 /* Enable maj_sel in CRUSH_CTRL (Set bit 20) */ 137 /* Enable maj_sel in CRUSH_CTRL (Set bit 20) */
136 cx18_av_and_or4(cx, CXADEC_CRUSH_CTRL, ~0, 0x00500000); 138 cx18_av_and_or4(cx, CXADEC_CRUSH_CTRL, ~0, 0x00500000);
137 139
138 /* Set VGA_TRACK_RANGE to 0x20 */ 140 /* Set VGA_TRACK_RANGE to 0x20 */
139 cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000); 141 cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
140 142
141 /* Enable VBI capture */ 143 /* Enable VBI capture */
142 cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F); 144 cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F);
143 /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */ 145 /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */
144 146
145 /* Set the video input. 147 /* Set the video input.
146 The setting in MODE_CTRL gets lost when we do the above setup */ 148 The setting in MODE_CTRL gets lost when we do the above setup */
147 /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */ 149 /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
148 /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */ 150 /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
149 151
150 v = cx18_av_read4(cx, CXADEC_AFE_CTRL); 152 v = cx18_av_read4(cx, CXADEC_AFE_CTRL);
151 v &= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */ 153 v &= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */
152 v &= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */ 154 v &= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */
153 v &= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */ 155 v &= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */
154 /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */ 156 /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */
155 cx18_av_write4(cx, CXADEC_AFE_CTRL, v); 157 cx18_av_write4(cx, CXADEC_AFE_CTRL, v);
156 158
157 /* if(dwEnable && dw3DCombAvailable) { */ 159 /* if(dwEnable && dw3DCombAvailable) { */
158 /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */ 160 /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
159 /* } else { */ 161 /* } else { */
160 /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */ 162 /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
161 /* } */ 163 /* } */
162 cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F); 164 cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
163 state->default_volume = 228 - cx18_av_read(cx, 0x8d4); 165 state->default_volume = 228 - cx18_av_read(cx, 0x8d4);
164 state->default_volume = ((state->default_volume / 2) + 23) << 9; 166 state->default_volume = ((state->default_volume / 2) + 23) << 9;
165 } 167 }
166 168
167 /* ----------------------------------------------------------------------- */ 169 /* ----------------------------------------------------------------------- */
168 170
169 void cx18_av_std_setup(struct cx18 *cx) 171 void cx18_av_std_setup(struct cx18 *cx)
170 { 172 {
171 struct cx18_av_state *state = &cx->av_state; 173 struct cx18_av_state *state = &cx->av_state;
172 v4l2_std_id std = state->std; 174 v4l2_std_id std = state->std;
173 int hblank, hactive, burst, vblank, vactive, sc; 175 int hblank, hactive, burst, vblank, vactive, sc;
174 int vblank656, src_decimation; 176 int vblank656, src_decimation;
175 int luma_lpf, uv_lpf, comb; 177 int luma_lpf, uv_lpf, comb;
176 u32 pll_int, pll_frac, pll_post; 178 u32 pll_int, pll_frac, pll_post;
177 179
178 /* datasheet startup, step 8d */ 180 /* datasheet startup, step 8d */
179 if (std & ~V4L2_STD_NTSC) 181 if (std & ~V4L2_STD_NTSC)
180 cx18_av_write(cx, 0x49f, 0x11); 182 cx18_av_write(cx, 0x49f, 0x11);
181 else 183 else
182 cx18_av_write(cx, 0x49f, 0x14); 184 cx18_av_write(cx, 0x49f, 0x14);
183 185
184 if (std & V4L2_STD_625_50) { 186 if (std & V4L2_STD_625_50) {
185 hblank = 132; 187 hblank = 132;
186 hactive = 720; 188 hactive = 720;
187 burst = 93; 189 burst = 93;
188 vblank = 36; 190 vblank = 36;
189 vactive = 580; 191 vactive = 580;
190 vblank656 = 40; 192 vblank656 = 40;
191 src_decimation = 0x21f; 193 src_decimation = 0x21f;
192 194
193 luma_lpf = 2; 195 luma_lpf = 2;
194 if (std & V4L2_STD_PAL) { 196 if (std & V4L2_STD_PAL) {
195 uv_lpf = 1; 197 uv_lpf = 1;
196 comb = 0x20; 198 comb = 0x20;
197 sc = 688739; 199 sc = 688739;
198 } else if (std == V4L2_STD_PAL_Nc) { 200 } else if (std == V4L2_STD_PAL_Nc) {
199 uv_lpf = 1; 201 uv_lpf = 1;
200 comb = 0x20; 202 comb = 0x20;
201 sc = 556453; 203 sc = 556453;
202 } else { /* SECAM */ 204 } else { /* SECAM */
203 uv_lpf = 0; 205 uv_lpf = 0;
204 comb = 0; 206 comb = 0;
205 sc = 672351; 207 sc = 672351;
206 } 208 }
207 } else { 209 } else {
208 hactive = 720; 210 hactive = 720;
209 hblank = 122; 211 hblank = 122;
210 vactive = 487; 212 vactive = 487;
211 luma_lpf = 1; 213 luma_lpf = 1;
212 uv_lpf = 1; 214 uv_lpf = 1;
213 vblank = 26; 215 vblank = 26;
214 vblank656 = 26; 216 vblank656 = 26;
215 217
216 src_decimation = 0x21f; 218 src_decimation = 0x21f;
217 if (std == V4L2_STD_PAL_60) { 219 if (std == V4L2_STD_PAL_60) {
218 burst = 0x5b; 220 burst = 0x5b;
219 luma_lpf = 2; 221 luma_lpf = 2;
220 comb = 0x20; 222 comb = 0x20;
221 sc = 688739; 223 sc = 688739;
222 } else if (std == V4L2_STD_PAL_M) { 224 } else if (std == V4L2_STD_PAL_M) {
223 burst = 0x61; 225 burst = 0x61;
224 comb = 0x20; 226 comb = 0x20;
225 sc = 555452; 227 sc = 555452;
226 } else { 228 } else {
227 burst = 0x5b; 229 burst = 0x5b;
228 comb = 0x66; 230 comb = 0x66;
229 sc = 556063; 231 sc = 556063;
230 } 232 }
231 } 233 }
232 234
233 /* DEBUG: Displays configured PLL frequency */ 235 /* DEBUG: Displays configured PLL frequency */
234 pll_int = cx18_av_read(cx, 0x108); 236 pll_int = cx18_av_read(cx, 0x108);
235 pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff; 237 pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
236 pll_post = cx18_av_read(cx, 0x109); 238 pll_post = cx18_av_read(cx, 0x109);
237 CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n", 239 CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n",
238 pll_int, pll_frac, pll_post); 240 pll_int, pll_frac, pll_post);
239 241
240 if (pll_post) { 242 if (pll_post) {
241 int fin, fsc; 243 int fin, fsc;
242 int pll = 28636363L * ((((u64)pll_int) << 25) + pll_frac); 244 int pll = 28636363L * ((((u64)pll_int) << 25) + pll_frac);
243 245
244 pll >>= 25; 246 pll >>= 25;
245 pll /= pll_post; 247 pll /= pll_post;
246 CX18_DEBUG_INFO("PLL = %d.%06d MHz\n", 248 CX18_DEBUG_INFO("PLL = %d.%06d MHz\n",
247 pll / 1000000, pll % 1000000); 249 pll / 1000000, pll % 1000000);
248 CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n", 250 CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n",
249 pll / 8000000, (pll / 8) % 1000000); 251 pll / 8000000, (pll / 8) % 1000000);
250 252
251 fin = ((u64)src_decimation * pll) >> 12; 253 fin = ((u64)src_decimation * pll) >> 12;
252 CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n", 254 CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n",
253 fin / 1000000, fin % 1000000); 255 fin / 1000000, fin % 1000000);
254 256
255 fsc = (((u64)sc) * pll) >> 24L; 257 fsc = (((u64)sc) * pll) >> 24L;
256 CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n", 258 CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n",
257 fsc / 1000000, fsc % 1000000); 259 fsc / 1000000, fsc % 1000000);
258 260
259 CX18_DEBUG_INFO("hblank %i, hactive %i, " 261 CX18_DEBUG_INFO("hblank %i, hactive %i, "
260 "vblank %i , vactive %i, vblank656 %i, src_dec %i," 262 "vblank %i , vactive %i, vblank656 %i, src_dec %i,"
261 "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x," 263 "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x,"
262 " sc 0x%06x\n", 264 " sc 0x%06x\n",
263 hblank, hactive, vblank, vactive, vblank656, 265 hblank, hactive, vblank, vactive, vblank656,
264 src_decimation, burst, luma_lpf, uv_lpf, comb, sc); 266 src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
265 } 267 }
266 268
267 /* Sets horizontal blanking delay and active lines */ 269 /* Sets horizontal blanking delay and active lines */
268 cx18_av_write(cx, 0x470, hblank); 270 cx18_av_write(cx, 0x470, hblank);
269 cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) | 271 cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) |
270 (hactive << 4))); 272 (hactive << 4)));
271 cx18_av_write(cx, 0x472, hactive >> 4); 273 cx18_av_write(cx, 0x472, hactive >> 4);
272 274
273 /* Sets burst gate delay */ 275 /* Sets burst gate delay */
274 cx18_av_write(cx, 0x473, burst); 276 cx18_av_write(cx, 0x473, burst);
275 277
276 /* Sets vertical blanking delay and active duration */ 278 /* Sets vertical blanking delay and active duration */
277 cx18_av_write(cx, 0x474, vblank); 279 cx18_av_write(cx, 0x474, vblank);
278 cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) | 280 cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) |
279 (vactive << 4))); 281 (vactive << 4)));
280 cx18_av_write(cx, 0x476, vactive >> 4); 282 cx18_av_write(cx, 0x476, vactive >> 4);
281 cx18_av_write(cx, 0x477, vblank656); 283 cx18_av_write(cx, 0x477, vblank656);
282 284
283 /* Sets src decimation rate */ 285 /* Sets src decimation rate */
284 cx18_av_write(cx, 0x478, 0xff & src_decimation); 286 cx18_av_write(cx, 0x478, 0xff & src_decimation);
285 cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8)); 287 cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8));
286 288
287 /* Sets Luma and UV Low pass filters */ 289 /* Sets Luma and UV Low pass filters */
288 cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30)); 290 cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
289 291
290 /* Enables comb filters */ 292 /* Enables comb filters */
291 cx18_av_write(cx, 0x47b, comb); 293 cx18_av_write(cx, 0x47b, comb);
292 294
293 /* Sets SC Step*/ 295 /* Sets SC Step*/
294 cx18_av_write(cx, 0x47c, sc); 296 cx18_av_write(cx, 0x47c, sc);
295 cx18_av_write(cx, 0x47d, 0xff & sc >> 8); 297 cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
296 cx18_av_write(cx, 0x47e, 0xff & sc >> 16); 298 cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
297 299
298 /* Sets VBI parameters */ 300 /* Sets VBI parameters */
299 if (std & V4L2_STD_625_50) { 301 if (std & V4L2_STD_625_50) {
300 cx18_av_write(cx, 0x47f, 0x01); 302 cx18_av_write(cx, 0x47f, 0x01);
301 state->vbi_line_offset = 5; 303 state->vbi_line_offset = 5;
302 } else { 304 } else {
303 cx18_av_write(cx, 0x47f, 0x00); 305 cx18_av_write(cx, 0x47f, 0x00);
304 state->vbi_line_offset = 8; 306 state->vbi_line_offset = 8;
305 } 307 }
306 } 308 }
307 309
308 /* ----------------------------------------------------------------------- */ 310 /* ----------------------------------------------------------------------- */
309 311
310 static void input_change(struct cx18 *cx) 312 static void input_change(struct cx18 *cx)
311 { 313 {
312 struct cx18_av_state *state = &cx->av_state; 314 struct cx18_av_state *state = &cx->av_state;
313 v4l2_std_id std = state->std; 315 v4l2_std_id std = state->std;
314 316
315 /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */ 317 /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
316 cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); 318 cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
317 cx18_av_and_or(cx, 0x401, ~0x60, 0); 319 cx18_av_and_or(cx, 0x401, ~0x60, 0);
318 cx18_av_and_or(cx, 0x401, ~0x60, 0x60); 320 cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
319 321
320 if (std & V4L2_STD_525_60) { 322 if (std & V4L2_STD_525_60) {
321 if (std == V4L2_STD_NTSC_M_JP) { 323 if (std == V4L2_STD_NTSC_M_JP) {
322 /* Japan uses EIAJ audio standard */ 324 /* Japan uses EIAJ audio standard */
323 cx18_av_write(cx, 0x808, 0xf7); 325 cx18_av_write(cx, 0x808, 0xf7);
324 cx18_av_write(cx, 0x80b, 0x02); 326 cx18_av_write(cx, 0x80b, 0x02);
325 } else if (std == V4L2_STD_NTSC_M_KR) { 327 } else if (std == V4L2_STD_NTSC_M_KR) {
326 /* South Korea uses A2 audio standard */ 328 /* South Korea uses A2 audio standard */
327 cx18_av_write(cx, 0x808, 0xf8); 329 cx18_av_write(cx, 0x808, 0xf8);
328 cx18_av_write(cx, 0x80b, 0x03); 330 cx18_av_write(cx, 0x80b, 0x03);
329 } else { 331 } else {
330 /* Others use the BTSC audio standard */ 332 /* Others use the BTSC audio standard */
331 cx18_av_write(cx, 0x808, 0xf6); 333 cx18_av_write(cx, 0x808, 0xf6);
332 cx18_av_write(cx, 0x80b, 0x01); 334 cx18_av_write(cx, 0x80b, 0x01);
333 } 335 }
334 } else if (std & V4L2_STD_PAL) { 336 } else if (std & V4L2_STD_PAL) {
335 /* Follow tuner change procedure for PAL */ 337 /* Follow tuner change procedure for PAL */
336 cx18_av_write(cx, 0x808, 0xff); 338 cx18_av_write(cx, 0x808, 0xff);
337 cx18_av_write(cx, 0x80b, 0x03); 339 cx18_av_write(cx, 0x80b, 0x03);
338 } else if (std & V4L2_STD_SECAM) { 340 } else if (std & V4L2_STD_SECAM) {
339 /* Select autodetect for SECAM */ 341 /* Select autodetect for SECAM */
340 cx18_av_write(cx, 0x808, 0xff); 342 cx18_av_write(cx, 0x808, 0xff);
341 cx18_av_write(cx, 0x80b, 0x03); 343 cx18_av_write(cx, 0x80b, 0x03);
342 } 344 }
343 345
344 if (cx18_av_read(cx, 0x803) & 0x10) { 346 if (cx18_av_read(cx, 0x803) & 0x10) {
345 /* restart audio decoder microcontroller */ 347 /* restart audio decoder microcontroller */
346 cx18_av_and_or(cx, 0x803, ~0x10, 0x00); 348 cx18_av_and_or(cx, 0x803, ~0x10, 0x00);
347 cx18_av_and_or(cx, 0x803, ~0x10, 0x10); 349 cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
348 } 350 }
349 } 351 }
350 352
351 static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, 353 static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
352 enum cx18_av_audio_input aud_input) 354 enum cx18_av_audio_input aud_input)
353 { 355 {
354 struct cx18_av_state *state = &cx->av_state; 356 struct cx18_av_state *state = &cx->av_state;
355 u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 && 357 u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 &&
356 vid_input <= CX18_AV_COMPOSITE8); 358 vid_input <= CX18_AV_COMPOSITE8);
357 u8 reg; 359 u8 reg;
358 360
359 CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n", 361 CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n",
360 vid_input, aud_input); 362 vid_input, aud_input);
361 363
362 if (is_composite) { 364 if (is_composite) {
363 reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1); 365 reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
364 } else { 366 } else {
365 int luma = vid_input & 0xf0; 367 int luma = vid_input & 0xf0;
366 int chroma = vid_input & 0xf00; 368 int chroma = vid_input & 0xf00;
367 369
368 if ((vid_input & ~0xff0) || 370 if ((vid_input & ~0xff0) ||
369 luma < CX18_AV_SVIDEO_LUMA1 || 371 luma < CX18_AV_SVIDEO_LUMA1 ||
370 luma > CX18_AV_SVIDEO_LUMA8 || 372 luma > CX18_AV_SVIDEO_LUMA8 ||
371 chroma < CX18_AV_SVIDEO_CHROMA4 || 373 chroma < CX18_AV_SVIDEO_CHROMA4 ||
372 chroma > CX18_AV_SVIDEO_CHROMA8) { 374 chroma > CX18_AV_SVIDEO_CHROMA8) {
373 CX18_ERR("0x%04x is not a valid video input!\n", 375 CX18_ERR("0x%04x is not a valid video input!\n",
374 vid_input); 376 vid_input);
375 return -EINVAL; 377 return -EINVAL;
376 } 378 }
377 reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4); 379 reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
378 if (chroma >= CX18_AV_SVIDEO_CHROMA7) { 380 if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
379 reg &= 0x3f; 381 reg &= 0x3f;
380 reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2; 382 reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
381 } else { 383 } else {
382 reg &= 0xcf; 384 reg &= 0xcf;
383 reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4; 385 reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
384 } 386 }
385 } 387 }
386 388
387 switch (aud_input) { 389 switch (aud_input) {
388 case CX18_AV_AUDIO_SERIAL1: 390 case CX18_AV_AUDIO_SERIAL1:
389 case CX18_AV_AUDIO_SERIAL2: 391 case CX18_AV_AUDIO_SERIAL2:
390 /* do nothing, use serial audio input */ 392 /* do nothing, use serial audio input */
391 break; 393 break;
392 case CX18_AV_AUDIO4: reg &= ~0x30; break; 394 case CX18_AV_AUDIO4: reg &= ~0x30; break;
393 case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break; 395 case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
394 case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break; 396 case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
395 case CX18_AV_AUDIO7: reg &= ~0xc0; break; 397 case CX18_AV_AUDIO7: reg &= ~0xc0; break;
396 case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; 398 case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
397 399
398 default: 400 default:
399 CX18_ERR("0x%04x is not a valid audio input!\n", aud_input); 401 CX18_ERR("0x%04x is not a valid audio input!\n", aud_input);
400 return -EINVAL; 402 return -EINVAL;
401 } 403 }
402 404
403 cx18_av_write(cx, 0x103, reg); 405 cx18_av_write(cx, 0x103, reg);
404 /* Set INPUT_MODE to Composite (0) or S-Video (1) */ 406 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
405 cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); 407 cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
406 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ 408 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
407 cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); 409 cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
408 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ 410 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
409 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) 411 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
410 cx18_av_and_or(cx, 0x102, ~0x4, 4); 412 cx18_av_and_or(cx, 0x102, ~0x4, 4);
411 else 413 else
412 cx18_av_and_or(cx, 0x102, ~0x4, 0); 414 cx18_av_and_or(cx, 0x102, ~0x4, 0);
413 /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/ 415 /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/
414 416
415 state->vid_input = vid_input; 417 state->vid_input = vid_input;
416 state->aud_input = aud_input; 418 state->aud_input = aud_input;
417 cx18_av_audio_set_path(cx); 419 cx18_av_audio_set_path(cx);
418 input_change(cx); 420 input_change(cx);
419 return 0; 421 return 0;
420 } 422 }
421 423
422 /* ----------------------------------------------------------------------- */ 424 /* ----------------------------------------------------------------------- */
423 425
424 static int set_v4lstd(struct cx18 *cx) 426 static int set_v4lstd(struct cx18 *cx)
425 { 427 {
426 struct cx18_av_state *state = &cx->av_state; 428 struct cx18_av_state *state = &cx->av_state;
427 u8 fmt = 0; /* zero is autodetect */ 429 u8 fmt = 0; /* zero is autodetect */
428 u8 pal_m = 0; 430 u8 pal_m = 0;
429 431
430 /* First tests should be against specific std */ 432 /* First tests should be against specific std */
431 if (state->std == V4L2_STD_NTSC_M_JP) { 433 if (state->std == V4L2_STD_NTSC_M_JP) {
432 fmt = 0x2; 434 fmt = 0x2;
433 } else if (state->std == V4L2_STD_NTSC_443) { 435 } else if (state->std == V4L2_STD_NTSC_443) {
434 fmt = 0x3; 436 fmt = 0x3;
435 } else if (state->std == V4L2_STD_PAL_M) { 437 } else if (state->std == V4L2_STD_PAL_M) {
436 pal_m = 1; 438 pal_m = 1;
437 fmt = 0x5; 439 fmt = 0x5;
438 } else if (state->std == V4L2_STD_PAL_N) { 440 } else if (state->std == V4L2_STD_PAL_N) {
439 fmt = 0x6; 441 fmt = 0x6;
440 } else if (state->std == V4L2_STD_PAL_Nc) { 442 } else if (state->std == V4L2_STD_PAL_Nc) {
441 fmt = 0x7; 443 fmt = 0x7;
442 } else if (state->std == V4L2_STD_PAL_60) { 444 } else if (state->std == V4L2_STD_PAL_60) {
443 fmt = 0x8; 445 fmt = 0x8;
444 } else { 446 } else {
445 /* Then, test against generic ones */ 447 /* Then, test against generic ones */
446 if (state->std & V4L2_STD_NTSC) 448 if (state->std & V4L2_STD_NTSC)
447 fmt = 0x1; 449 fmt = 0x1;
448 else if (state->std & V4L2_STD_PAL) 450 else if (state->std & V4L2_STD_PAL)
449 fmt = 0x4; 451 fmt = 0x4;
450 else if (state->std & V4L2_STD_SECAM) 452 else if (state->std & V4L2_STD_SECAM)
451 fmt = 0xc; 453 fmt = 0xc;
452 } 454 }
453 455
454 CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt); 456 CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt);
455 457
456 /* Follow step 9 of section 3.16 in the cx18_av datasheet. 458 /* Follow step 9 of section 3.16 in the cx18_av datasheet.
457 Without this PAL may display a vertical ghosting effect. 459 Without this PAL may display a vertical ghosting effect.
458 This happens for example with the Yuan MPC622. */ 460 This happens for example with the Yuan MPC622. */
459 if (fmt >= 4 && fmt < 8) { 461 if (fmt >= 4 && fmt < 8) {
460 /* Set format to NTSC-M */ 462 /* Set format to NTSC-M */
461 cx18_av_and_or(cx, 0x400, ~0xf, 1); 463 cx18_av_and_or(cx, 0x400, ~0xf, 1);
462 /* Turn off LCOMB */ 464 /* Turn off LCOMB */
463 cx18_av_and_or(cx, 0x47b, ~6, 0); 465 cx18_av_and_or(cx, 0x47b, ~6, 0);
464 } 466 }
465 cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20); 467 cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20);
466 cx18_av_and_or(cx, 0x403, ~0x3, pal_m); 468 cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
467 cx18_av_std_setup(cx); 469 cx18_av_std_setup(cx);
468 input_change(cx); 470 input_change(cx);
469 return 0; 471 return 0;
470 } 472 }
471 473
472 /* ----------------------------------------------------------------------- */ 474 /* ----------------------------------------------------------------------- */
473 475
474 static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) 476 static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
475 { 477 {
476 switch (ctrl->id) { 478 switch (ctrl->id) {
477 case V4L2_CID_BRIGHTNESS: 479 case V4L2_CID_BRIGHTNESS:
478 if (ctrl->value < 0 || ctrl->value > 255) { 480 if (ctrl->value < 0 || ctrl->value > 255) {
479 CX18_ERR("invalid brightness setting %d\n", 481 CX18_ERR("invalid brightness setting %d\n",
480 ctrl->value); 482 ctrl->value);
481 return -ERANGE; 483 return -ERANGE;
482 } 484 }
483 485
484 cx18_av_write(cx, 0x414, ctrl->value - 128); 486 cx18_av_write(cx, 0x414, ctrl->value - 128);
485 break; 487 break;
486 488
487 case V4L2_CID_CONTRAST: 489 case V4L2_CID_CONTRAST:
488 if (ctrl->value < 0 || ctrl->value > 127) { 490 if (ctrl->value < 0 || ctrl->value > 127) {
489 CX18_ERR("invalid contrast setting %d\n", 491 CX18_ERR("invalid contrast setting %d\n",
490 ctrl->value); 492 ctrl->value);
491 return -ERANGE; 493 return -ERANGE;
492 } 494 }
493 495
494 cx18_av_write(cx, 0x415, ctrl->value << 1); 496 cx18_av_write(cx, 0x415, ctrl->value << 1);
495 break; 497 break;
496 498
497 case V4L2_CID_SATURATION: 499 case V4L2_CID_SATURATION:
498 if (ctrl->value < 0 || ctrl->value > 127) { 500 if (ctrl->value < 0 || ctrl->value > 127) {
499 CX18_ERR("invalid saturation setting %d\n", 501 CX18_ERR("invalid saturation setting %d\n",
500 ctrl->value); 502 ctrl->value);
501 return -ERANGE; 503 return -ERANGE;
502 } 504 }
503 505
504 cx18_av_write(cx, 0x420, ctrl->value << 1); 506 cx18_av_write(cx, 0x420, ctrl->value << 1);
505 cx18_av_write(cx, 0x421, ctrl->value << 1); 507 cx18_av_write(cx, 0x421, ctrl->value << 1);
506 break; 508 break;
507 509
508 case V4L2_CID_HUE: 510 case V4L2_CID_HUE:
509 if (ctrl->value < -127 || ctrl->value > 127) { 511 if (ctrl->value < -127 || ctrl->value > 127) {
510 CX18_ERR("invalid hue setting %d\n", ctrl->value); 512 CX18_ERR("invalid hue setting %d\n", ctrl->value);
511 return -ERANGE; 513 return -ERANGE;
512 } 514 }
513 515
514 cx18_av_write(cx, 0x422, ctrl->value); 516 cx18_av_write(cx, 0x422, ctrl->value);
515 break; 517 break;
516 518
517 case V4L2_CID_AUDIO_VOLUME: 519 case V4L2_CID_AUDIO_VOLUME:
518 case V4L2_CID_AUDIO_BASS: 520 case V4L2_CID_AUDIO_BASS:
519 case V4L2_CID_AUDIO_TREBLE: 521 case V4L2_CID_AUDIO_TREBLE:
520 case V4L2_CID_AUDIO_BALANCE: 522 case V4L2_CID_AUDIO_BALANCE:
521 case V4L2_CID_AUDIO_MUTE: 523 case V4L2_CID_AUDIO_MUTE:
522 return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl); 524 return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl);
523 525
524 default: 526 default:
525 return -EINVAL; 527 return -EINVAL;
526 } 528 }
527 529
528 return 0; 530 return 0;
529 } 531 }
530 532
531 static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) 533 static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
532 { 534 {
533 switch (ctrl->id) { 535 switch (ctrl->id) {
534 case V4L2_CID_BRIGHTNESS: 536 case V4L2_CID_BRIGHTNESS:
535 ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128; 537 ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128;
536 break; 538 break;
537 case V4L2_CID_CONTRAST: 539 case V4L2_CID_CONTRAST:
538 ctrl->value = cx18_av_read(cx, 0x415) >> 1; 540 ctrl->value = cx18_av_read(cx, 0x415) >> 1;
539 break; 541 break;
540 case V4L2_CID_SATURATION: 542 case V4L2_CID_SATURATION:
541 ctrl->value = cx18_av_read(cx, 0x420) >> 1; 543 ctrl->value = cx18_av_read(cx, 0x420) >> 1;
542 break; 544 break;
543 case V4L2_CID_HUE: 545 case V4L2_CID_HUE:
544 ctrl->value = (s8)cx18_av_read(cx, 0x422); 546 ctrl->value = (s8)cx18_av_read(cx, 0x422);
545 break; 547 break;
546 case V4L2_CID_AUDIO_VOLUME: 548 case V4L2_CID_AUDIO_VOLUME:
547 case V4L2_CID_AUDIO_BASS: 549 case V4L2_CID_AUDIO_BASS:
548 case V4L2_CID_AUDIO_TREBLE: 550 case V4L2_CID_AUDIO_TREBLE:
549 case V4L2_CID_AUDIO_BALANCE: 551 case V4L2_CID_AUDIO_BALANCE:
550 case V4L2_CID_AUDIO_MUTE: 552 case V4L2_CID_AUDIO_MUTE:
551 return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl); 553 return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl);
552 default: 554 default:
553 return -EINVAL; 555 return -EINVAL;
554 } 556 }
555 557
556 return 0; 558 return 0;
557 } 559 }
558 560
559 /* ----------------------------------------------------------------------- */ 561 /* ----------------------------------------------------------------------- */
560 562
561 static int get_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) 563 static int get_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
562 { 564 {
563 switch (fmt->type) { 565 switch (fmt->type) {
564 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 566 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
565 return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt); 567 return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt);
566 default: 568 default:
567 return -EINVAL; 569 return -EINVAL;
568 } 570 }
569 571
570 return 0; 572 return 0;
571 } 573 }
572 574
573 static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) 575 static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
574 { 576 {
575 struct cx18_av_state *state = &cx->av_state; 577 struct cx18_av_state *state = &cx->av_state;
576 struct v4l2_pix_format *pix; 578 struct v4l2_pix_format *pix;
577 int HSC, VSC, Vsrc, Hsrc, filter, Vlines; 579 int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
578 int is_50Hz = !(state->std & V4L2_STD_525_60); 580 int is_50Hz = !(state->std & V4L2_STD_525_60);
579 581
580 switch (fmt->type) { 582 switch (fmt->type) {
581 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 583 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
582 pix = &(fmt->fmt.pix); 584 pix = &(fmt->fmt.pix);
583 585
584 Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4; 586 Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4;
585 Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4; 587 Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4;
586 588
587 Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4; 589 Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
588 Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4; 590 Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
589 591
590 Vlines = pix->height + (is_50Hz ? 4 : 7); 592 Vlines = pix->height + (is_50Hz ? 4 : 7);
591 593
592 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || 594 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
593 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { 595 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
594 CX18_ERR("%dx%d is not a valid size!\n", 596 CX18_ERR("%dx%d is not a valid size!\n",
595 pix->width, pix->height); 597 pix->width, pix->height);
596 return -ERANGE; 598 return -ERANGE;
597 } 599 }
598 600
599 HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20); 601 HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
600 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); 602 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
601 VSC &= 0x1fff; 603 VSC &= 0x1fff;
602 604
603 if (pix->width >= 385) 605 if (pix->width >= 385)
604 filter = 0; 606 filter = 0;
605 else if (pix->width > 192) 607 else if (pix->width > 192)
606 filter = 1; 608 filter = 1;
607 else if (pix->width > 96) 609 else if (pix->width > 96)
608 filter = 2; 610 filter = 2;
609 else 611 else
610 filter = 3; 612 filter = 3;
611 613
612 CX18_DEBUG_INFO("decoder set size %dx%d -> scale %ux%u\n", 614 CX18_DEBUG_INFO("decoder set size %dx%d -> scale %ux%u\n",
613 pix->width, pix->height, HSC, VSC); 615 pix->width, pix->height, HSC, VSC);
614 616
615 /* HSCALE=HSC */ 617 /* HSCALE=HSC */
616 cx18_av_write(cx, 0x418, HSC & 0xff); 618 cx18_av_write(cx, 0x418, HSC & 0xff);
617 cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff); 619 cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
618 cx18_av_write(cx, 0x41a, HSC >> 16); 620 cx18_av_write(cx, 0x41a, HSC >> 16);
619 /* VSCALE=VSC */ 621 /* VSCALE=VSC */
620 cx18_av_write(cx, 0x41c, VSC & 0xff); 622 cx18_av_write(cx, 0x41c, VSC & 0xff);
621 cx18_av_write(cx, 0x41d, VSC >> 8); 623 cx18_av_write(cx, 0x41d, VSC >> 8);
622 /* VS_INTRLACE=1 VFILT=filter */ 624 /* VS_INTRLACE=1 VFILT=filter */
623 cx18_av_write(cx, 0x41e, 0x8 | filter); 625 cx18_av_write(cx, 0x41e, 0x8 | filter);
624 break; 626 break;
625 627
626 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 628 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
627 return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt); 629 return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
628 630
629 case V4L2_BUF_TYPE_VBI_CAPTURE: 631 case V4L2_BUF_TYPE_VBI_CAPTURE:
630 return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt); 632 return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
631 633
632 default: 634 default:
633 return -EINVAL; 635 return -EINVAL;
634 } 636 }
635 637
636 return 0; 638 return 0;
637 } 639 }
638 640
639 /* ----------------------------------------------------------------------- */ 641 /* ----------------------------------------------------------------------- */
640 642
641 int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg) 643 int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg)
642 { 644 {
643 struct cx18_av_state *state = &cx->av_state; 645 struct cx18_av_state *state = &cx->av_state;
644 struct v4l2_tuner *vt = arg; 646 struct v4l2_tuner *vt = arg;
645 struct v4l2_routing *route = arg; 647 struct v4l2_routing *route = arg;
646 648
647 /* ignore these commands */ 649 /* ignore these commands */
648 switch (cmd) { 650 switch (cmd) {
649 case TUNER_SET_TYPE_ADDR: 651 case TUNER_SET_TYPE_ADDR:
650 return 0; 652 return 0;
651 } 653 }
652 654
653 if (!state->is_initialized) { 655 if (!state->is_initialized) {
654 CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd); 656 CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd);
655 /* initialize on first use */ 657 /* initialize on first use */
656 state->is_initialized = 1; 658 state->is_initialized = 1;
657 cx18_av_initialize(cx); 659 cx18_av_initialize(cx);
658 } 660 }
659 661
660 switch (cmd) { 662 switch (cmd) {
661 case VIDIOC_INT_DECODE_VBI_LINE: 663 case VIDIOC_INT_DECODE_VBI_LINE:
662 return cx18_av_vbi(cx, cmd, arg); 664 return cx18_av_vbi(cx, cmd, arg);
663 665
664 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 666 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
665 return cx18_av_audio(cx, cmd, arg); 667 return cx18_av_audio(cx, cmd, arg);
666 668
667 case VIDIOC_STREAMON: 669 case VIDIOC_STREAMON:
668 CX18_DEBUG_INFO("enable output\n"); 670 CX18_DEBUG_INFO("enable output\n");
669 cx18_av_write(cx, 0x115, 0x8c); 671 cx18_av_write(cx, 0x115, 0x8c);
670 cx18_av_write(cx, 0x116, 0x07); 672 cx18_av_write(cx, 0x116, 0x07);
671 break; 673 break;
672 674
673 case VIDIOC_STREAMOFF: 675 case VIDIOC_STREAMOFF:
674 CX18_DEBUG_INFO("disable output\n"); 676 CX18_DEBUG_INFO("disable output\n");
675 cx18_av_write(cx, 0x115, 0x00); 677 cx18_av_write(cx, 0x115, 0x00);
676 cx18_av_write(cx, 0x116, 0x00); 678 cx18_av_write(cx, 0x116, 0x00);
677 break; 679 break;
678 680
679 case VIDIOC_LOG_STATUS: 681 case VIDIOC_LOG_STATUS:
680 log_video_status(cx); 682 log_video_status(cx);
681 log_audio_status(cx); 683 log_audio_status(cx);
682 break; 684 break;
683 685
684 case VIDIOC_G_CTRL: 686 case VIDIOC_G_CTRL:
685 return get_v4lctrl(cx, (struct v4l2_control *)arg); 687 return get_v4lctrl(cx, (struct v4l2_control *)arg);
686 688
687 case VIDIOC_S_CTRL: 689 case VIDIOC_S_CTRL:
688 return set_v4lctrl(cx, (struct v4l2_control *)arg); 690 return set_v4lctrl(cx, (struct v4l2_control *)arg);
689 691
690 case VIDIOC_QUERYCTRL: 692 case VIDIOC_QUERYCTRL:
691 { 693 {
692 struct v4l2_queryctrl *qc = arg; 694 struct v4l2_queryctrl *qc = arg;
693 695
694 switch (qc->id) { 696 switch (qc->id) {
695 case V4L2_CID_BRIGHTNESS: 697 case V4L2_CID_BRIGHTNESS:
696 case V4L2_CID_CONTRAST: 698 case V4L2_CID_CONTRAST:
697 case V4L2_CID_SATURATION: 699 case V4L2_CID_SATURATION:
698 case V4L2_CID_HUE: 700 case V4L2_CID_HUE:
699 return v4l2_ctrl_query_fill_std(qc); 701 return v4l2_ctrl_query_fill_std(qc);
700 default: 702 default:
701 break; 703 break;
702 } 704 }
703 705
704 switch (qc->id) { 706 switch (qc->id) {
705 case V4L2_CID_AUDIO_VOLUME: 707 case V4L2_CID_AUDIO_VOLUME:
706 return v4l2_ctrl_query_fill(qc, 0, 65535, 708 return v4l2_ctrl_query_fill(qc, 0, 65535,
707 65535 / 100, state->default_volume); 709 65535 / 100, state->default_volume);
708 case V4L2_CID_AUDIO_MUTE: 710 case V4L2_CID_AUDIO_MUTE:
709 case V4L2_CID_AUDIO_BALANCE: 711 case V4L2_CID_AUDIO_BALANCE:
710 case V4L2_CID_AUDIO_BASS: 712 case V4L2_CID_AUDIO_BASS:
711 case V4L2_CID_AUDIO_TREBLE: 713 case V4L2_CID_AUDIO_TREBLE:
712 return v4l2_ctrl_query_fill_std(qc); 714 return v4l2_ctrl_query_fill_std(qc);
713 default: 715 default:
714 return -EINVAL; 716 return -EINVAL;
715 } 717 }
716 return -EINVAL; 718 return -EINVAL;
717 } 719 }
718 720
719 case VIDIOC_G_STD: 721 case VIDIOC_G_STD:
720 *(v4l2_std_id *)arg = state->std; 722 *(v4l2_std_id *)arg = state->std;
721 break; 723 break;
722 724
723 case VIDIOC_S_STD: 725 case VIDIOC_S_STD:
724 if (state->radio == 0 && state->std == *(v4l2_std_id *)arg) 726 if (state->radio == 0 && state->std == *(v4l2_std_id *)arg)
725 return 0; 727 return 0;
726 state->radio = 0; 728 state->radio = 0;
727 state->std = *(v4l2_std_id *)arg; 729 state->std = *(v4l2_std_id *)arg;
728 return set_v4lstd(cx); 730 return set_v4lstd(cx);
729 731
730 case AUDC_SET_RADIO: 732 case AUDC_SET_RADIO:
731 state->radio = 1; 733 state->radio = 1;
732 break; 734 break;
733 735
734 case VIDIOC_INT_G_VIDEO_ROUTING: 736 case VIDIOC_INT_G_VIDEO_ROUTING:
735 route->input = state->vid_input; 737 route->input = state->vid_input;
736 route->output = 0; 738 route->output = 0;
737 break; 739 break;
738 740
739 case VIDIOC_INT_S_VIDEO_ROUTING: 741 case VIDIOC_INT_S_VIDEO_ROUTING:
740 return set_input(cx, route->input, state->aud_input); 742 return set_input(cx, route->input, state->aud_input);
741 743
742 case VIDIOC_INT_G_AUDIO_ROUTING: 744 case VIDIOC_INT_G_AUDIO_ROUTING:
743 route->input = state->aud_input; 745 route->input = state->aud_input;
744 route->output = 0; 746 route->output = 0;
745 break; 747 break;
746 748
747 case VIDIOC_INT_S_AUDIO_ROUTING: 749 case VIDIOC_INT_S_AUDIO_ROUTING:
748 return set_input(cx, state->vid_input, route->input); 750 return set_input(cx, state->vid_input, route->input);
749 751
750 case VIDIOC_S_FREQUENCY: 752 case VIDIOC_S_FREQUENCY:
751 input_change(cx); 753 input_change(cx);
752 break; 754 break;
753 755
754 case VIDIOC_G_TUNER: 756 case VIDIOC_G_TUNER:
755 { 757 {
756 u8 vpres = cx18_av_read(cx, 0x40e) & 0x20; 758 u8 vpres = cx18_av_read(cx, 0x40e) & 0x20;
757 u8 mode; 759 u8 mode;
758 int val = 0; 760 int val = 0;
759 761
760 if (state->radio) 762 if (state->radio)
761 break; 763 break;
762 764
763 vt->signal = vpres ? 0xffff : 0x0; 765 vt->signal = vpres ? 0xffff : 0x0;
764 766
765 vt->capability |= 767 vt->capability |=
766 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | 768 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
767 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; 769 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
768 770
769 mode = cx18_av_read(cx, 0x804); 771 mode = cx18_av_read(cx, 0x804);
770 772
771 /* get rxsubchans and audmode */ 773 /* get rxsubchans and audmode */
772 if ((mode & 0xf) == 1) 774 if ((mode & 0xf) == 1)
773 val |= V4L2_TUNER_SUB_STEREO; 775 val |= V4L2_TUNER_SUB_STEREO;
774 else 776 else
775 val |= V4L2_TUNER_SUB_MONO; 777 val |= V4L2_TUNER_SUB_MONO;
776 778
777 if (mode == 2 || mode == 4) 779 if (mode == 2 || mode == 4)
778 val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; 780 val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
779 781
780 if (mode & 0x10) 782 if (mode & 0x10)
781 val |= V4L2_TUNER_SUB_SAP; 783 val |= V4L2_TUNER_SUB_SAP;
782 784
783 vt->rxsubchans = val; 785 vt->rxsubchans = val;
784 vt->audmode = state->audmode; 786 vt->audmode = state->audmode;
785 break; 787 break;
786 } 788 }
787 789
788 case VIDIOC_S_TUNER: 790 case VIDIOC_S_TUNER:
789 if (state->radio) 791 if (state->radio)
790 break; 792 break;
791 793
792 switch (vt->audmode) { 794 switch (vt->audmode) {
793 case V4L2_TUNER_MODE_MONO: 795 case V4L2_TUNER_MODE_MONO:
794 /* mono -> mono 796 /* mono -> mono
795 stereo -> mono 797 stereo -> mono
796 bilingual -> lang1 */ 798 bilingual -> lang1 */
797 cx18_av_and_or(cx, 0x809, ~0xf, 0x00); 799 cx18_av_and_or(cx, 0x809, ~0xf, 0x00);
798 break; 800 break;
799 case V4L2_TUNER_MODE_STEREO: 801 case V4L2_TUNER_MODE_STEREO:
800 case V4L2_TUNER_MODE_LANG1: 802 case V4L2_TUNER_MODE_LANG1:
801 /* mono -> mono 803 /* mono -> mono
802 stereo -> stereo 804 stereo -> stereo
803 bilingual -> lang1 */ 805 bilingual -> lang1 */
804 cx18_av_and_or(cx, 0x809, ~0xf, 0x04); 806 cx18_av_and_or(cx, 0x809, ~0xf, 0x04);
805 break; 807 break;
806 case V4L2_TUNER_MODE_LANG1_LANG2: 808 case V4L2_TUNER_MODE_LANG1_LANG2:
807 /* mono -> mono 809 /* mono -> mono
808 stereo -> stereo 810 stereo -> stereo
809 bilingual -> lang1/lang2 */ 811 bilingual -> lang1/lang2 */
810 cx18_av_and_or(cx, 0x809, ~0xf, 0x07); 812 cx18_av_and_or(cx, 0x809, ~0xf, 0x07);
811 break; 813 break;
812 case V4L2_TUNER_MODE_LANG2: 814 case V4L2_TUNER_MODE_LANG2:
813 /* mono -> mono 815 /* mono -> mono
814 stereo -> stereo 816 stereo -> stereo
815 bilingual -> lang2 */ 817 bilingual -> lang2 */
816 cx18_av_and_or(cx, 0x809, ~0xf, 0x01); 818 cx18_av_and_or(cx, 0x809, ~0xf, 0x01);
817 break; 819 break;
818 default: 820 default:
819 return -EINVAL; 821 return -EINVAL;
820 } 822 }
821 state->audmode = vt->audmode; 823 state->audmode = vt->audmode;
822 break; 824 break;
823 825
824 case VIDIOC_G_FMT: 826 case VIDIOC_G_FMT:
825 return get_v4lfmt(cx, (struct v4l2_format *)arg); 827 return get_v4lfmt(cx, (struct v4l2_format *)arg);
826 828
827 case VIDIOC_S_FMT: 829 case VIDIOC_S_FMT:
828 return set_v4lfmt(cx, (struct v4l2_format *)arg); 830 return set_v4lfmt(cx, (struct v4l2_format *)arg);
829 831
830 case VIDIOC_INT_RESET: 832 case VIDIOC_INT_RESET:
831 cx18_av_initialize(cx); 833 cx18_av_initialize(cx);
832 break; 834 break;
833 835
834 default: 836 default:
835 return -EINVAL; 837 return -EINVAL;
836 } 838 }
837 839
838 return 0; 840 return 0;
839 } 841 }
840 842
841 /* ----------------------------------------------------------------------- */ 843 /* ----------------------------------------------------------------------- */
842 844
843 /* ----------------------------------------------------------------------- */ 845 /* ----------------------------------------------------------------------- */
844 846
845 static void log_video_status(struct cx18 *cx) 847 static void log_video_status(struct cx18 *cx)
846 { 848 {
847 static const char *const fmt_strs[] = { 849 static const char *const fmt_strs[] = {
848 "0x0", 850 "0x0",
849 "NTSC-M", "NTSC-J", "NTSC-4.43", 851 "NTSC-M", "NTSC-J", "NTSC-4.43",
850 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60", 852 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
851 "0x9", "0xA", "0xB", 853 "0x9", "0xA", "0xB",
852 "SECAM", 854 "SECAM",
853 "0xD", "0xE", "0xF" 855 "0xD", "0xE", "0xF"
854 }; 856 };
855 857
856 struct cx18_av_state *state = &cx->av_state; 858 struct cx18_av_state *state = &cx->av_state;
857 u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf; 859 u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf;
858 u8 gen_stat1 = cx18_av_read(cx, 0x40d); 860 u8 gen_stat1 = cx18_av_read(cx, 0x40d);
859 u8 gen_stat2 = cx18_av_read(cx, 0x40e); 861 u8 gen_stat2 = cx18_av_read(cx, 0x40e);
860 int vid_input = state->vid_input; 862 int vid_input = state->vid_input;
861 863
862 CX18_INFO("Video signal: %spresent\n", 864 CX18_INFO("Video signal: %spresent\n",
863 (gen_stat2 & 0x20) ? "" : "not "); 865 (gen_stat2 & 0x20) ? "" : "not ");
864 CX18_INFO("Detected format: %s\n", 866 CX18_INFO("Detected format: %s\n",
865 fmt_strs[gen_stat1 & 0xf]); 867 fmt_strs[gen_stat1 & 0xf]);
866 868
867 CX18_INFO("Specified standard: %s\n", 869 CX18_INFO("Specified standard: %s\n",
868 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); 870 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
869 871
870 if (vid_input >= CX18_AV_COMPOSITE1 && 872 if (vid_input >= CX18_AV_COMPOSITE1 &&
871 vid_input <= CX18_AV_COMPOSITE8) { 873 vid_input <= CX18_AV_COMPOSITE8) {
872 CX18_INFO("Specified video input: Composite %d\n", 874 CX18_INFO("Specified video input: Composite %d\n",
873 vid_input - CX18_AV_COMPOSITE1 + 1); 875 vid_input - CX18_AV_COMPOSITE1 + 1);
874 } else { 876 } else {
875 CX18_INFO("Specified video input: S-Video (Luma In%d, Chroma In%d)\n", 877 CX18_INFO("Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
876 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); 878 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
877 } 879 }
878 880
879 CX18_INFO("Specified audioclock freq: %d Hz\n", state->audclk_freq); 881 CX18_INFO("Specified audioclock freq: %d Hz\n", state->audclk_freq);
880 } 882 }
881 883
882 /* ----------------------------------------------------------------------- */ 884 /* ----------------------------------------------------------------------- */
883 885
884 static void log_audio_status(struct cx18 *cx) 886 static void log_audio_status(struct cx18 *cx)
885 { 887 {
886 struct cx18_av_state *state = &cx->av_state; 888 struct cx18_av_state *state = &cx->av_state;
887 u8 download_ctl = cx18_av_read(cx, 0x803); 889 u8 download_ctl = cx18_av_read(cx, 0x803);
888 u8 mod_det_stat0 = cx18_av_read(cx, 0x804); 890 u8 mod_det_stat0 = cx18_av_read(cx, 0x804);
889 u8 mod_det_stat1 = cx18_av_read(cx, 0x805); 891 u8 mod_det_stat1 = cx18_av_read(cx, 0x805);
890 u8 audio_config = cx18_av_read(cx, 0x808); 892 u8 audio_config = cx18_av_read(cx, 0x808);
891 u8 pref_mode = cx18_av_read(cx, 0x809); 893 u8 pref_mode = cx18_av_read(cx, 0x809);
892 u8 afc0 = cx18_av_read(cx, 0x80b); 894 u8 afc0 = cx18_av_read(cx, 0x80b);
893 u8 mute_ctl = cx18_av_read(cx, 0x8d3); 895 u8 mute_ctl = cx18_av_read(cx, 0x8d3);
894 int aud_input = state->aud_input; 896 int aud_input = state->aud_input;
895 char *p; 897 char *p;
896 898
897 switch (mod_det_stat0) { 899 switch (mod_det_stat0) {
898 case 0x00: p = "mono"; break; 900 case 0x00: p = "mono"; break;
899 case 0x01: p = "stereo"; break; 901 case 0x01: p = "stereo"; break;
900 case 0x02: p = "dual"; break; 902 case 0x02: p = "dual"; break;
901 case 0x04: p = "tri"; break; 903 case 0x04: p = "tri"; break;
902 case 0x10: p = "mono with SAP"; break; 904 case 0x10: p = "mono with SAP"; break;
903 case 0x11: p = "stereo with SAP"; break; 905 case 0x11: p = "stereo with SAP"; break;
904 case 0x12: p = "dual with SAP"; break; 906 case 0x12: p = "dual with SAP"; break;
905 case 0x14: p = "tri with SAP"; break; 907 case 0x14: p = "tri with SAP"; break;
906 case 0xfe: p = "forced mode"; break; 908 case 0xfe: p = "forced mode"; break;
907 default: p = "not defined"; break; 909 default: p = "not defined"; break;
908 } 910 }
909 CX18_INFO("Detected audio mode: %s\n", p); 911 CX18_INFO("Detected audio mode: %s\n", p);
910 912
911 switch (mod_det_stat1) { 913 switch (mod_det_stat1) {
912 case 0x00: p = "not defined"; break; 914 case 0x00: p = "not defined"; break;
913 case 0x01: p = "EIAJ"; break; 915 case 0x01: p = "EIAJ"; break;
914 case 0x02: p = "A2-M"; break; 916 case 0x02: p = "A2-M"; break;
915 case 0x03: p = "A2-BG"; break; 917 case 0x03: p = "A2-BG"; break;
916 case 0x04: p = "A2-DK1"; break; 918 case 0x04: p = "A2-DK1"; break;
917 case 0x05: p = "A2-DK2"; break; 919 case 0x05: p = "A2-DK2"; break;
918 case 0x06: p = "A2-DK3"; break; 920 case 0x06: p = "A2-DK3"; break;
919 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break; 921 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
920 case 0x08: p = "AM-L"; break; 922 case 0x08: p = "AM-L"; break;
921 case 0x09: p = "NICAM-BG"; break; 923 case 0x09: p = "NICAM-BG"; break;
922 case 0x0a: p = "NICAM-DK"; break; 924 case 0x0a: p = "NICAM-DK"; break;
923 case 0x0b: p = "NICAM-I"; break; 925 case 0x0b: p = "NICAM-I"; break;
924 case 0x0c: p = "NICAM-L"; break; 926 case 0x0c: p = "NICAM-L"; break;
925 case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break; 927 case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
926 case 0x0e: p = "IF FM Radio"; break; 928 case 0x0e: p = "IF FM Radio"; break;
927 case 0x0f: p = "BTSC"; break; 929 case 0x0f: p = "BTSC"; break;
928 case 0x10: p = "detected chrominance"; break; 930 case 0x10: p = "detected chrominance"; break;
929 case 0xfd: p = "unknown audio standard"; break; 931 case 0xfd: p = "unknown audio standard"; break;
930 case 0xfe: p = "forced audio standard"; break; 932 case 0xfe: p = "forced audio standard"; break;
931 case 0xff: p = "no detected audio standard"; break; 933 case 0xff: p = "no detected audio standard"; break;
932 default: p = "not defined"; break; 934 default: p = "not defined"; break;
933 } 935 }
934 CX18_INFO("Detected audio standard: %s\n", p); 936 CX18_INFO("Detected audio standard: %s\n", p);
935 CX18_INFO("Audio muted: %s\n", 937 CX18_INFO("Audio muted: %s\n",
936 (mute_ctl & 0x2) ? "yes" : "no"); 938 (mute_ctl & 0x2) ? "yes" : "no");
937 CX18_INFO("Audio microcontroller: %s\n", 939 CX18_INFO("Audio microcontroller: %s\n",
938 (download_ctl & 0x10) ? "running" : "stopped"); 940 (download_ctl & 0x10) ? "running" : "stopped");
939 941
940 switch (audio_config >> 4) { 942 switch (audio_config >> 4) {
941 case 0x00: p = "undefined"; break; 943 case 0x00: p = "undefined"; break;
942 case 0x01: p = "BTSC"; break; 944 case 0x01: p = "BTSC"; break;
943 case 0x02: p = "EIAJ"; break; 945 case 0x02: p = "EIAJ"; break;
944 case 0x03: p = "A2-M"; break; 946 case 0x03: p = "A2-M"; break;
945 case 0x04: p = "A2-BG"; break; 947 case 0x04: p = "A2-BG"; break;
946 case 0x05: p = "A2-DK1"; break; 948 case 0x05: p = "A2-DK1"; break;
947 case 0x06: p = "A2-DK2"; break; 949 case 0x06: p = "A2-DK2"; break;
948 case 0x07: p = "A2-DK3"; break; 950 case 0x07: p = "A2-DK3"; break;
949 case 0x08: p = "A1 (6.0 MHz FM Mono)"; break; 951 case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
950 case 0x09: p = "AM-L"; break; 952 case 0x09: p = "AM-L"; break;
951 case 0x0a: p = "NICAM-BG"; break; 953 case 0x0a: p = "NICAM-BG"; break;
952 case 0x0b: p = "NICAM-DK"; break; 954 case 0x0b: p = "NICAM-DK"; break;
953 case 0x0c: p = "NICAM-I"; break; 955 case 0x0c: p = "NICAM-I"; break;
954 case 0x0d: p = "NICAM-L"; break; 956 case 0x0d: p = "NICAM-L"; break;
955 case 0x0e: p = "FM radio"; break; 957 case 0x0e: p = "FM radio"; break;
956 case 0x0f: p = "automatic detection"; break; 958 case 0x0f: p = "automatic detection"; break;
957 default: p = "undefined"; break; 959 default: p = "undefined"; break;
958 } 960 }
959 CX18_INFO("Configured audio standard: %s\n", p); 961 CX18_INFO("Configured audio standard: %s\n", p);
960 962
961 if ((audio_config >> 4) < 0xF) { 963 if ((audio_config >> 4) < 0xF) {
962 switch (audio_config & 0xF) { 964 switch (audio_config & 0xF) {
963 case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break; 965 case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
964 case 0x01: p = "MONO2 (LANGUAGE B)"; break; 966 case 0x01: p = "MONO2 (LANGUAGE B)"; break;
965 case 0x02: p = "MONO3 (STEREO forced MONO)"; break; 967 case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
966 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break; 968 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
967 case 0x04: p = "STEREO"; break; 969 case 0x04: p = "STEREO"; break;
968 case 0x05: p = "DUAL1 (AC)"; break; 970 case 0x05: p = "DUAL1 (AC)"; break;
969 case 0x06: p = "DUAL2 (BC)"; break; 971 case 0x06: p = "DUAL2 (BC)"; break;
970 case 0x07: p = "DUAL3 (AB)"; break; 972 case 0x07: p = "DUAL3 (AB)"; break;
971 default: p = "undefined"; 973 default: p = "undefined";
972 } 974 }
973 CX18_INFO("Configured audio mode: %s\n", p); 975 CX18_INFO("Configured audio mode: %s\n", p);
974 } else { 976 } else {
975 switch (audio_config & 0xF) { 977 switch (audio_config & 0xF) {
976 case 0x00: p = "BG"; break; 978 case 0x00: p = "BG"; break;
977 case 0x01: p = "DK1"; break; 979 case 0x01: p = "DK1"; break;
978 case 0x02: p = "DK2"; break; 980 case 0x02: p = "DK2"; break;
979 case 0x03: p = "DK3"; break; 981 case 0x03: p = "DK3"; break;
980 case 0x04: p = "I"; break; 982 case 0x04: p = "I"; break;
981 case 0x05: p = "L"; break; 983 case 0x05: p = "L"; break;
982 case 0x06: p = "BTSC"; break; 984 case 0x06: p = "BTSC"; break;
983 case 0x07: p = "EIAJ"; break; 985 case 0x07: p = "EIAJ"; break;
984 case 0x08: p = "A2-M"; break; 986 case 0x08: p = "A2-M"; break;
985 case 0x09: p = "FM Radio (4.5 MHz)"; break; 987 case 0x09: p = "FM Radio (4.5 MHz)"; break;
986 case 0x0a: p = "FM Radio (5.5 MHz)"; break; 988 case 0x0a: p = "FM Radio (5.5 MHz)"; break;
987 case 0x0b: p = "S-Video"; break; 989 case 0x0b: p = "S-Video"; break;
988 case 0x0f: p = "automatic standard and mode detection"; break; 990 case 0x0f: p = "automatic standard and mode detection"; break;
989 default: p = "undefined"; break; 991 default: p = "undefined"; break;
990 } 992 }
991 CX18_INFO("Configured audio system: %s\n", p); 993 CX18_INFO("Configured audio system: %s\n", p);
992 } 994 }
993 995
994 if (aud_input) 996 if (aud_input)
995 CX18_INFO("Specified audio input: Tuner (In%d)\n", 997 CX18_INFO("Specified audio input: Tuner (In%d)\n",
996 aud_input); 998 aud_input);
997 else 999 else
998 CX18_INFO("Specified audio input: External\n"); 1000 CX18_INFO("Specified audio input: External\n");
999 1001
1000 switch (pref_mode & 0xf) { 1002 switch (pref_mode & 0xf) {
1001 case 0: p = "mono/language A"; break; 1003 case 0: p = "mono/language A"; break;
1002 case 1: p = "language B"; break; 1004 case 1: p = "language B"; break;
1003 case 2: p = "language C"; break; 1005 case 2: p = "language C"; break;
1004 case 3: p = "analog fallback"; break; 1006 case 3: p = "analog fallback"; break;
1005 case 4: p = "stereo"; break; 1007 case 4: p = "stereo"; break;
1006 case 5: p = "language AC"; break; 1008 case 5: p = "language AC"; break;
1007 case 6: p = "language BC"; break; 1009 case 6: p = "language BC"; break;
1008 case 7: p = "language AB"; break; 1010 case 7: p = "language AB"; break;
1009 default: p = "undefined"; break; 1011 default: p = "undefined"; break;
1010 } 1012 }
1011 CX18_INFO("Preferred audio mode: %s\n", p); 1013 CX18_INFO("Preferred audio mode: %s\n", p);
1012 1014
1013 if ((audio_config & 0xf) == 0xf) { 1015 if ((audio_config & 0xf) == 0xf) {
1014 switch ((afc0 >> 3) & 0x1) { 1016 switch ((afc0 >> 3) & 0x1) {
1015 case 0: p = "system DK"; break; 1017 case 0: p = "system DK"; break;
1016 case 1: p = "system L"; break; 1018 case 1: p = "system L"; break;
1017 } 1019 }
1018 CX18_INFO("Selected 65 MHz format: %s\n", p); 1020 CX18_INFO("Selected 65 MHz format: %s\n", p);
1019 1021
1020 switch (afc0 & 0x7) { 1022 switch (afc0 & 0x7) {
1021 case 0: p = "Chroma"; break; 1023 case 0: p = "Chroma"; break;
1022 case 1: p = "BTSC"; break; 1024 case 1: p = "BTSC"; break;
1023 case 2: p = "EIAJ"; break; 1025 case 2: p = "EIAJ"; break;
1024 case 3: p = "A2-M"; break; 1026 case 3: p = "A2-M"; break;
1025 case 4: p = "autodetect"; break; 1027 case 4: p = "autodetect"; break;
1026 default: p = "undefined"; break; 1028 default: p = "undefined"; break;
1027 } 1029 }
1028 CX18_INFO("Selected 45 MHz format: %s\n", p); 1030 CX18_INFO("Selected 45 MHz format: %s\n", p);
1029 } 1031 }
1030 } 1032 }
1031 1033
drivers/media/video/cx18/cx18-av-firmware.c
1 /* 1 /*
2 * cx18 ADEC firmware functions 2 * cx18 ADEC firmware functions
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2 8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version. 9 * of the License, or (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301, USA. 19 * 02110-1301, USA.
20 */ 20 */
21 21
22 #include "cx18-driver.h" 22 #include "cx18-driver.h"
23 #include "cx18-io.h"
23 #include <linux/firmware.h> 24 #include <linux/firmware.h>
24 25
25 #define CX18_AUDIO_ENABLE 0xc72014 26 #define CX18_AUDIO_ENABLE 0xc72014
26 #define FWFILE "v4l-cx23418-dig.fw" 27 #define FWFILE "v4l-cx23418-dig.fw"
27 28
28 int cx18_av_loadfw(struct cx18 *cx) 29 int cx18_av_loadfw(struct cx18 *cx)
29 { 30 {
30 const struct firmware *fw = NULL; 31 const struct firmware *fw = NULL;
31 u32 size; 32 u32 size;
32 u32 v; 33 u32 v;
33 const u8 *ptr; 34 const u8 *ptr;
34 int i; 35 int i;
35 int retries1 = 0; 36 int retries1 = 0;
36 37
37 if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { 38 if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
38 CX18_ERR("unable to open firmware %s\n", FWFILE); 39 CX18_ERR("unable to open firmware %s\n", FWFILE);
39 return -EINVAL; 40 return -EINVAL;
40 } 41 }
41 42
42 /* The firmware load often has byte errors, so allow for several 43 /* The firmware load often has byte errors, so allow for several
43 retries, both at byte level and at the firmware load level. */ 44 retries, both at byte level and at the firmware load level. */
44 while (retries1 < 5) { 45 while (retries1 < 5) {
45 cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000); 46 cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000);
46 cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); 47 cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6);
47 48
48 /* Reset the Mako core (Register is undocumented.) */ 49 /* Reset the Mako core (Register is undocumented.) */
49 cx18_av_write4(cx, 0x8100, 0x00010000); 50 cx18_av_write4(cx, 0x8100, 0x00010000);
50 51
51 /* Put the 8051 in reset and enable firmware upload */ 52 /* Put the 8051 in reset and enable firmware upload */
52 cx18_av_write4(cx, CXADEC_DL_CTL, 0x0F000000); 53 cx18_av_write4(cx, CXADEC_DL_CTL, 0x0F000000);
53 54
54 ptr = fw->data; 55 ptr = fw->data;
55 size = fw->size; 56 size = fw->size;
56 57
57 for (i = 0; i < size; i++) { 58 for (i = 0; i < size; i++) {
58 u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16); 59 u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16);
59 u32 value = 0; 60 u32 value = 0;
60 int retries2; 61 int retries2;
61 62
62 for (retries2 = 0; retries2 < 5; retries2++) { 63 for (retries2 = 0; retries2 < 5; retries2++) {
63 cx18_av_write4(cx, CXADEC_DL_CTL, dl_control); 64 cx18_av_write4(cx, CXADEC_DL_CTL, dl_control);
64 udelay(10); 65 udelay(10);
65 value = cx18_av_read4(cx, CXADEC_DL_CTL); 66 value = cx18_av_read4(cx, CXADEC_DL_CTL);
66 if (value == dl_control) 67 if (value == dl_control)
67 break; 68 break;
68 /* Check if we can correct the byte by changing 69 /* Check if we can correct the byte by changing
69 the address. We can only write the lower 70 the address. We can only write the lower
70 address byte of the address. */ 71 address byte of the address. */
71 if ((value & 0x3F00) != (dl_control & 0x3F00)) { 72 if ((value & 0x3F00) != (dl_control & 0x3F00)) {
72 retries2 = 5; 73 retries2 = 5;
73 break; 74 break;
74 } 75 }
75 } 76 }
76 if (retries2 >= 5) 77 if (retries2 >= 5)
77 break; 78 break;
78 } 79 }
79 if (i == size) 80 if (i == size)
80 break; 81 break;
81 retries1++; 82 retries1++;
82 } 83 }
83 if (retries1 >= 5) { 84 if (retries1 >= 5) {
84 CX18_ERR("unable to load firmware %s\n", FWFILE); 85 CX18_ERR("unable to load firmware %s\n", FWFILE);
85 release_firmware(fw); 86 release_firmware(fw);
86 return -EIO; 87 return -EIO;
87 } 88 }
88 89
89 cx18_av_write4(cx, CXADEC_DL_CTL, 0x13000000 | fw->size); 90 cx18_av_write4(cx, CXADEC_DL_CTL, 0x13000000 | fw->size);
90 91
91 /* Output to the 416 */ 92 /* Output to the 416 */
92 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000); 93 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000);
93 94
94 /* Audio input control 1 set to Sony mode */ 95 /* Audio input control 1 set to Sony mode */
95 /* Audio output input 2 is 0 for slave operation input */ 96 /* Audio output input 2 is 0 for slave operation input */
96 /* 0xC4000914[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */ 97 /* 0xC4000914[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
97 /* 0xC4000914[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge 98 /* 0xC4000914[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
98 after WS transition for first bit of audio word. */ 99 after WS transition for first bit of audio word. */
99 cx18_av_write4(cx, CXADEC_I2S_IN_CTL, 0x000000A0); 100 cx18_av_write4(cx, CXADEC_I2S_IN_CTL, 0x000000A0);
100 101
101 /* Audio output control 1 is set to Sony mode */ 102 /* Audio output control 1 is set to Sony mode */
102 /* Audio output control 2 is set to 1 for master mode */ 103 /* Audio output control 2 is set to 1 for master mode */
103 /* 0xC4000918[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */ 104 /* 0xC4000918[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
104 /* 0xC4000918[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge 105 /* 0xC4000918[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
105 after WS transition for first bit of audio word. */ 106 after WS transition for first bit of audio word. */
106 /* 0xC4000918[8]: 0 = slave operation, 1 = master (SCK_OUT and WS_OUT 107 /* 0xC4000918[8]: 0 = slave operation, 1 = master (SCK_OUT and WS_OUT
107 are generated) */ 108 are generated) */
108 cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0); 109 cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);
109 110
110 /* set alt I2s master clock to /16 and enable alt divider i2s 111 /* set alt I2s master clock to /16 and enable alt divider i2s
111 passthrough */ 112 passthrough */
112 cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687); 113 cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687);
113 114
114 cx18_av_write4(cx, CXADEC_STD_DET_CTL, 0x000000F6); 115 cx18_av_write4(cx, CXADEC_STD_DET_CTL, 0x000000F6);
115 /* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */ 116 /* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */
116 117
117 /* Set bit 0 in register 0x9CC to signify that this is MiniMe. */ 118 /* Set bit 0 in register 0x9CC to signify that this is MiniMe. */
118 /* Register 0x09CC is defined by the Merlin firmware, and doesn't 119 /* Register 0x09CC is defined by the Merlin firmware, and doesn't
119 have a name in the spec. */ 120 have a name in the spec. */
120 cx18_av_write4(cx, 0x09CC, 1); 121 cx18_av_write4(cx, 0x09CC, 1);
121 122
122 v = read_reg(CX18_AUDIO_ENABLE); 123 v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
123 /* If bit 11 is 1 */ 124 /* If bit 11 is 1, clear bit 10 */
124 if (v & 0x800) 125 if (v & 0x800)
125 write_reg(v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); /* Clear bit 10 */ 126 cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE);
126 127
127 /* Enable WW auto audio standard detection */ 128 /* Enable WW auto audio standard detection */
128 v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); 129 v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
129 v |= 0xFF; /* Auto by default */ 130 v |= 0xFF; /* Auto by default */
130 v |= 0x400; /* Stereo by default */ 131 v |= 0x400; /* Stereo by default */
131 v |= 0x14000000; 132 v |= 0x14000000;
132 cx18_av_write4(cx, CXADEC_STD_DET_CTL, v); 133 cx18_av_write4(cx, CXADEC_STD_DET_CTL, v);
133 134
134 release_firmware(fw); 135 release_firmware(fw);
135 136
136 CX18_INFO("loaded %s firmware (%d bytes)\n", FWFILE, size); 137 CX18_INFO("loaded %s firmware (%d bytes)\n", FWFILE, size);
137 return 0; 138 return 0;
138 } 139 }
139 140
drivers/media/video/cx18/cx18-driver.c
1 /* 1 /*
2 * cx18 driver initialization and card probing 2 * cx18 driver initialization and card probing
3 * 3 *
4 * Derived from ivtv-driver.c 4 * Derived from ivtv-driver.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 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 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 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 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24 #include "cx18-driver.h" 24 #include "cx18-driver.h"
25 #include "cx18-io.h"
25 #include "cx18-version.h" 26 #include "cx18-version.h"
26 #include "cx18-cards.h" 27 #include "cx18-cards.h"
27 #include "cx18-i2c.h" 28 #include "cx18-i2c.h"
28 #include "cx18-irq.h" 29 #include "cx18-irq.h"
29 #include "cx18-gpio.h" 30 #include "cx18-gpio.h"
30 #include "cx18-firmware.h" 31 #include "cx18-firmware.h"
31 #include "cx18-streams.h" 32 #include "cx18-streams.h"
32 #include "cx18-av-core.h" 33 #include "cx18-av-core.h"
33 #include "cx18-scb.h" 34 #include "cx18-scb.h"
34 #include "cx18-mailbox.h" 35 #include "cx18-mailbox.h"
35 #include "cx18-ioctl.h" 36 #include "cx18-ioctl.h"
36 #include "tuner-xc2028.h" 37 #include "tuner-xc2028.h"
37 38
38 #include <media/tveeprom.h> 39 #include <media/tveeprom.h>
39 40
40 41
41 /* var to keep track of the number of array elements in use */ 42 /* var to keep track of the number of array elements in use */
42 int cx18_cards_active; 43 int cx18_cards_active;
43 44
44 /* If you have already X v4l cards, then set this to X. This way 45 /* If you have already X v4l cards, then set this to X. This way
45 the device numbers stay matched. Example: you have a WinTV card 46 the device numbers stay matched. Example: you have a WinTV card
46 without radio and a Compro H900 with. Normally this would give a 47 without radio and a Compro H900 with. Normally this would give a
47 video1 device together with a radio0 device for the Compro. By 48 video1 device together with a radio0 device for the Compro. By
48 setting this to 1 you ensure that radio0 is now also radio1. */ 49 setting this to 1 you ensure that radio0 is now also radio1. */
49 int cx18_first_minor; 50 int cx18_first_minor;
50 51
51 /* Master variable for all cx18 info */ 52 /* Master variable for all cx18 info */
52 struct cx18 *cx18_cards[CX18_MAX_CARDS]; 53 struct cx18 *cx18_cards[CX18_MAX_CARDS];
53 54
54 /* Protects cx18_cards_active */ 55 /* Protects cx18_cards_active */
55 DEFINE_SPINLOCK(cx18_cards_lock); 56 DEFINE_SPINLOCK(cx18_cards_lock);
56 57
57 /* add your revision and whatnot here */ 58 /* add your revision and whatnot here */
58 static struct pci_device_id cx18_pci_tbl[] __devinitdata = { 59 static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
59 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, 60 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
60 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 61 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
61 {0,} 62 {0,}
62 }; 63 };
63 64
64 MODULE_DEVICE_TABLE(pci, cx18_pci_tbl); 65 MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
65 66
66 /* Parameter declarations */ 67 /* Parameter declarations */
67 static int cardtype[CX18_MAX_CARDS]; 68 static int cardtype[CX18_MAX_CARDS];
68 static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, 69 static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
69 -1, -1, -1, -1, -1, -1, -1, -1, 70 -1, -1, -1, -1, -1, -1, -1, -1,
70 -1, -1, -1, -1, -1, -1, -1, -1, 71 -1, -1, -1, -1, -1, -1, -1, -1,
71 -1, -1, -1, -1, -1, -1, -1, -1 }; 72 -1, -1, -1, -1, -1, -1, -1, -1 };
72 static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, 73 static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
73 -1, -1, -1, -1, -1, -1, -1, -1, 74 -1, -1, -1, -1, -1, -1, -1, -1,
74 -1, -1, -1, -1, -1, -1, -1, -1, 75 -1, -1, -1, -1, -1, -1, -1, -1,
75 -1, -1, -1, -1, -1, -1, -1, -1 }; 76 -1, -1, -1, -1, -1, -1, -1, -1 };
76 77
77 static unsigned cardtype_c = 1; 78 static unsigned cardtype_c = 1;
78 static unsigned tuner_c = 1; 79 static unsigned tuner_c = 1;
79 static unsigned radio_c = 1; 80 static unsigned radio_c = 1;
80 static char pal[] = "--"; 81 static char pal[] = "--";
81 static char secam[] = "--"; 82 static char secam[] = "--";
82 static char ntsc[] = "-"; 83 static char ntsc[] = "-";
83 84
84 /* Buffers */ 85 /* Buffers */
85 static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS; 86 static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
86 static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS; 87 static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS;
87 static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS; 88 static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS;
88 static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS; 89 static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS;
89 static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS; 90 static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
90 91
91 static int cx18_pci_latency = 1; 92 static int cx18_pci_latency = 1;
92 93
93 int cx18_debug; 94 int cx18_debug;
94 95
95 module_param_array(tuner, int, &tuner_c, 0644); 96 module_param_array(tuner, int, &tuner_c, 0644);
96 module_param_array(radio, bool, &radio_c, 0644); 97 module_param_array(radio, bool, &radio_c, 0644);
97 module_param_array(cardtype, int, &cardtype_c, 0644); 98 module_param_array(cardtype, int, &cardtype_c, 0644);
98 module_param_string(pal, pal, sizeof(pal), 0644); 99 module_param_string(pal, pal, sizeof(pal), 0644);
99 module_param_string(secam, secam, sizeof(secam), 0644); 100 module_param_string(secam, secam, sizeof(secam), 0644);
100 module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); 101 module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
101 module_param_named(debug, cx18_debug, int, 0644); 102 module_param_named(debug, cx18_debug, int, 0644);
102 module_param(cx18_pci_latency, int, 0644); 103 module_param(cx18_pci_latency, int, 0644);
103 module_param(cx18_first_minor, int, 0644); 104 module_param(cx18_first_minor, int, 0644);
104 105
105 module_param(enc_mpg_buffers, int, 0644); 106 module_param(enc_mpg_buffers, int, 0644);
106 module_param(enc_ts_buffers, int, 0644); 107 module_param(enc_ts_buffers, int, 0644);
107 module_param(enc_yuv_buffers, int, 0644); 108 module_param(enc_yuv_buffers, int, 0644);
108 module_param(enc_vbi_buffers, int, 0644); 109 module_param(enc_vbi_buffers, int, 0644);
109 module_param(enc_pcm_buffers, int, 0644); 110 module_param(enc_pcm_buffers, int, 0644);
110 111
111 MODULE_PARM_DESC(tuner, "Tuner type selection,\n" 112 MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
112 "\t\t\tsee tuner.h for values"); 113 "\t\t\tsee tuner.h for values");
113 MODULE_PARM_DESC(radio, 114 MODULE_PARM_DESC(radio,
114 "Enable or disable the radio. Use only if autodetection\n" 115 "Enable or disable the radio. Use only if autodetection\n"
115 "\t\t\tfails. 0 = disable, 1 = enable"); 116 "\t\t\tfails. 0 = disable, 1 = enable");
116 MODULE_PARM_DESC(cardtype, 117 MODULE_PARM_DESC(cardtype,
117 "Only use this option if your card is not detected properly.\n" 118 "Only use this option if your card is not detected properly.\n"
118 "\t\tSpecify card type:\n" 119 "\t\tSpecify card type:\n"
119 "\t\t\t 1 = Hauppauge HVR 1600 (ESMT memory)\n" 120 "\t\t\t 1 = Hauppauge HVR 1600 (ESMT memory)\n"
120 "\t\t\t 2 = Hauppauge HVR 1600 (Samsung memory)\n" 121 "\t\t\t 2 = Hauppauge HVR 1600 (Samsung memory)\n"
121 "\t\t\t 3 = Compro VideoMate H900\n" 122 "\t\t\t 3 = Compro VideoMate H900\n"
122 "\t\t\t 4 = Yuan MPC718\n" 123 "\t\t\t 4 = Yuan MPC718\n"
123 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" 124 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
124 "\t\t\t 0 = Autodetect (default)\n" 125 "\t\t\t 0 = Autodetect (default)\n"
125 "\t\t\t-1 = Ignore this card\n\t\t"); 126 "\t\t\t-1 = Ignore this card\n\t\t");
126 MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); 127 MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
127 MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC"); 128 MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC");
128 MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K"); 129 MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K");
129 MODULE_PARM_DESC(debug, 130 MODULE_PARM_DESC(debug,
130 "Debug level (bitmask). Default: 0\n" 131 "Debug level (bitmask). Default: 0\n"
131 "\t\t\t 1/0x0001: warning\n" 132 "\t\t\t 1/0x0001: warning\n"
132 "\t\t\t 2/0x0002: info\n" 133 "\t\t\t 2/0x0002: info\n"
133 "\t\t\t 4/0x0004: mailbox\n" 134 "\t\t\t 4/0x0004: mailbox\n"
134 "\t\t\t 8/0x0008: dma\n" 135 "\t\t\t 8/0x0008: dma\n"
135 "\t\t\t 16/0x0010: ioctl\n" 136 "\t\t\t 16/0x0010: ioctl\n"
136 "\t\t\t 32/0x0020: file\n" 137 "\t\t\t 32/0x0020: file\n"
137 "\t\t\t 64/0x0040: i2c\n" 138 "\t\t\t 64/0x0040: i2c\n"
138 "\t\t\t128/0x0080: irq\n" 139 "\t\t\t128/0x0080: irq\n"
139 "\t\t\t256/0x0100: high volume\n"); 140 "\t\t\t256/0x0100: high volume\n");
140 MODULE_PARM_DESC(cx18_pci_latency, 141 MODULE_PARM_DESC(cx18_pci_latency,
141 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n" 142 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
142 "\t\t\tDefault: Yes"); 143 "\t\t\tDefault: Yes");
143 MODULE_PARM_DESC(enc_mpg_buffers, 144 MODULE_PARM_DESC(enc_mpg_buffers,
144 "Encoder MPG Buffers (in MB)\n" 145 "Encoder MPG Buffers (in MB)\n"
145 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS)); 146 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
146 MODULE_PARM_DESC(enc_ts_buffers, 147 MODULE_PARM_DESC(enc_ts_buffers,
147 "Encoder TS Buffers (in MB)\n" 148 "Encoder TS Buffers (in MB)\n"
148 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS)); 149 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS));
149 MODULE_PARM_DESC(enc_yuv_buffers, 150 MODULE_PARM_DESC(enc_yuv_buffers,
150 "Encoder YUV Buffers (in MB)\n" 151 "Encoder YUV Buffers (in MB)\n"
151 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); 152 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
152 MODULE_PARM_DESC(enc_vbi_buffers, 153 MODULE_PARM_DESC(enc_vbi_buffers,
153 "Encoder VBI Buffers (in MB)\n" 154 "Encoder VBI Buffers (in MB)\n"
154 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS)); 155 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
155 MODULE_PARM_DESC(enc_pcm_buffers, 156 MODULE_PARM_DESC(enc_pcm_buffers,
156 "Encoder PCM buffers (in MB)\n" 157 "Encoder PCM buffers (in MB)\n"
157 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); 158 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
158 159
159 MODULE_PARM_DESC(cx18_first_minor, "Set minor assigned to first card"); 160 MODULE_PARM_DESC(cx18_first_minor, "Set minor assigned to first card");
160 161
161 MODULE_AUTHOR("Hans Verkuil"); 162 MODULE_AUTHOR("Hans Verkuil");
162 MODULE_DESCRIPTION("CX23418 driver"); 163 MODULE_DESCRIPTION("CX23418 driver");
163 MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder"); 164 MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
164 MODULE_LICENSE("GPL"); 165 MODULE_LICENSE("GPL");
165 166
166 MODULE_VERSION(CX18_VERSION); 167 MODULE_VERSION(CX18_VERSION);
167 168
168 /* Generic utility functions */ 169 /* Generic utility functions */
169 int cx18_msleep_timeout(unsigned int msecs, int intr) 170 int cx18_msleep_timeout(unsigned int msecs, int intr)
170 { 171 {
171 int timeout = msecs_to_jiffies(msecs); 172 int timeout = msecs_to_jiffies(msecs);
172 int sig; 173 int sig;
173 174
174 do { 175 do {
175 set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); 176 set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
176 timeout = schedule_timeout(timeout); 177 timeout = schedule_timeout(timeout);
177 sig = intr ? signal_pending(current) : 0; 178 sig = intr ? signal_pending(current) : 0;
178 } while (!sig && timeout); 179 } while (!sig && timeout);
179 return sig; 180 return sig;
180 } 181 }
181 182
182 /* Release ioremapped memory */ 183 /* Release ioremapped memory */
183 static void cx18_iounmap(struct cx18 *cx) 184 static void cx18_iounmap(struct cx18 *cx)
184 { 185 {
185 if (cx == NULL) 186 if (cx == NULL)
186 return; 187 return;
187 188
188 /* Release io memory */ 189 /* Release io memory */
189 if (cx->enc_mem != NULL) { 190 if (cx->enc_mem != NULL) {
190 CX18_DEBUG_INFO("releasing enc_mem\n"); 191 CX18_DEBUG_INFO("releasing enc_mem\n");
191 iounmap(cx->enc_mem); 192 iounmap(cx->enc_mem);
192 cx->enc_mem = NULL; 193 cx->enc_mem = NULL;
193 } 194 }
194 } 195 }
195 196
196 /* Hauppauge card? get values from tveeprom */ 197 /* Hauppauge card? get values from tveeprom */
197 void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv) 198 void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
198 { 199 {
199 u8 eedata[256]; 200 u8 eedata[256];
200 201
201 cx->i2c_client[0].addr = 0xA0 >> 1; 202 cx->i2c_client[0].addr = 0xA0 >> 1;
202 tveeprom_read(&cx->i2c_client[0], eedata, sizeof(eedata)); 203 tveeprom_read(&cx->i2c_client[0], eedata, sizeof(eedata));
203 tveeprom_hauppauge_analog(&cx->i2c_client[0], tv, eedata); 204 tveeprom_hauppauge_analog(&cx->i2c_client[0], tv, eedata);
204 } 205 }
205 206
206 static void cx18_process_eeprom(struct cx18 *cx) 207 static void cx18_process_eeprom(struct cx18 *cx)
207 { 208 {
208 struct tveeprom tv; 209 struct tveeprom tv;
209 210
210 cx18_read_eeprom(cx, &tv); 211 cx18_read_eeprom(cx, &tv);
211 212
212 /* Many thanks to Steven Toth from Hauppauge for providing the 213 /* Many thanks to Steven Toth from Hauppauge for providing the
213 model numbers */ 214 model numbers */
214 /* Note: the Samsung memory models cannot be reliably determined 215 /* Note: the Samsung memory models cannot be reliably determined
215 from the model number. Use the cardtype module option if you 216 from the model number. Use the cardtype module option if you
216 have one of these preproduction models. */ 217 have one of these preproduction models. */
217 switch (tv.model) { 218 switch (tv.model) {
218 case 74000 ... 74999: 219 case 74000 ... 74999:
219 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); 220 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
220 break; 221 break;
221 case 0: 222 case 0:
222 CX18_ERR("Invalid EEPROM\n"); 223 CX18_ERR("Invalid EEPROM\n");
223 return; 224 return;
224 default: 225 default:
225 CX18_ERR("Unknown model %d, defaulting to HVR-1600\n", tv.model); 226 CX18_ERR("Unknown model %d, defaulting to HVR-1600\n", tv.model);
226 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); 227 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
227 break; 228 break;
228 } 229 }
229 230
230 cx->v4l2_cap = cx->card->v4l2_capabilities; 231 cx->v4l2_cap = cx->card->v4l2_capabilities;
231 cx->card_name = cx->card->name; 232 cx->card_name = cx->card->name;
232 cx->card_i2c = cx->card->i2c; 233 cx->card_i2c = cx->card->i2c;
233 234
234 CX18_INFO("Autodetected %s\n", cx->card_name); 235 CX18_INFO("Autodetected %s\n", cx->card_name);
235 236
236 if (tv.tuner_type == TUNER_ABSENT) 237 if (tv.tuner_type == TUNER_ABSENT)
237 CX18_ERR("tveeprom cannot autodetect tuner!"); 238 CX18_ERR("tveeprom cannot autodetect tuner!");
238 239
239 if (cx->options.tuner == -1) 240 if (cx->options.tuner == -1)
240 cx->options.tuner = tv.tuner_type; 241 cx->options.tuner = tv.tuner_type;
241 if (cx->options.radio == -1) 242 if (cx->options.radio == -1)
242 cx->options.radio = (tv.has_radio != 0); 243 cx->options.radio = (tv.has_radio != 0);
243 244
244 if (cx->std != 0) 245 if (cx->std != 0)
245 /* user specified tuner standard */ 246 /* user specified tuner standard */
246 return; 247 return;
247 248
248 /* autodetect tuner standard */ 249 /* autodetect tuner standard */
249 if (tv.tuner_formats & V4L2_STD_PAL) { 250 if (tv.tuner_formats & V4L2_STD_PAL) {
250 CX18_DEBUG_INFO("PAL tuner detected\n"); 251 CX18_DEBUG_INFO("PAL tuner detected\n");
251 cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; 252 cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
252 } else if (tv.tuner_formats & V4L2_STD_NTSC) { 253 } else if (tv.tuner_formats & V4L2_STD_NTSC) {
253 CX18_DEBUG_INFO("NTSC tuner detected\n"); 254 CX18_DEBUG_INFO("NTSC tuner detected\n");
254 cx->std |= V4L2_STD_NTSC_M; 255 cx->std |= V4L2_STD_NTSC_M;
255 } else if (tv.tuner_formats & V4L2_STD_SECAM) { 256 } else if (tv.tuner_formats & V4L2_STD_SECAM) {
256 CX18_DEBUG_INFO("SECAM tuner detected\n"); 257 CX18_DEBUG_INFO("SECAM tuner detected\n");
257 cx->std |= V4L2_STD_SECAM_L; 258 cx->std |= V4L2_STD_SECAM_L;
258 } else { 259 } else {
259 CX18_INFO("No tuner detected, default to NTSC-M\n"); 260 CX18_INFO("No tuner detected, default to NTSC-M\n");
260 cx->std |= V4L2_STD_NTSC_M; 261 cx->std |= V4L2_STD_NTSC_M;
261 } 262 }
262 } 263 }
263 264
264 static v4l2_std_id cx18_parse_std(struct cx18 *cx) 265 static v4l2_std_id cx18_parse_std(struct cx18 *cx)
265 { 266 {
266 switch (pal[0]) { 267 switch (pal[0]) {
267 case '6': 268 case '6':
268 return V4L2_STD_PAL_60; 269 return V4L2_STD_PAL_60;
269 case 'b': 270 case 'b':
270 case 'B': 271 case 'B':
271 case 'g': 272 case 'g':
272 case 'G': 273 case 'G':
273 return V4L2_STD_PAL_BG; 274 return V4L2_STD_PAL_BG;
274 case 'h': 275 case 'h':
275 case 'H': 276 case 'H':
276 return V4L2_STD_PAL_H; 277 return V4L2_STD_PAL_H;
277 case 'n': 278 case 'n':
278 case 'N': 279 case 'N':
279 if (pal[1] == 'c' || pal[1] == 'C') 280 if (pal[1] == 'c' || pal[1] == 'C')
280 return V4L2_STD_PAL_Nc; 281 return V4L2_STD_PAL_Nc;
281 return V4L2_STD_PAL_N; 282 return V4L2_STD_PAL_N;
282 case 'i': 283 case 'i':
283 case 'I': 284 case 'I':
284 return V4L2_STD_PAL_I; 285 return V4L2_STD_PAL_I;
285 case 'd': 286 case 'd':
286 case 'D': 287 case 'D':
287 case 'k': 288 case 'k':
288 case 'K': 289 case 'K':
289 return V4L2_STD_PAL_DK; 290 return V4L2_STD_PAL_DK;
290 case 'M': 291 case 'M':
291 case 'm': 292 case 'm':
292 return V4L2_STD_PAL_M; 293 return V4L2_STD_PAL_M;
293 case '-': 294 case '-':
294 break; 295 break;
295 default: 296 default:
296 CX18_WARN("pal= argument not recognised\n"); 297 CX18_WARN("pal= argument not recognised\n");
297 return 0; 298 return 0;
298 } 299 }
299 300
300 switch (secam[0]) { 301 switch (secam[0]) {
301 case 'b': 302 case 'b':
302 case 'B': 303 case 'B':
303 case 'g': 304 case 'g':
304 case 'G': 305 case 'G':
305 case 'h': 306 case 'h':
306 case 'H': 307 case 'H':
307 return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; 308 return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
308 case 'd': 309 case 'd':
309 case 'D': 310 case 'D':
310 case 'k': 311 case 'k':
311 case 'K': 312 case 'K':
312 return V4L2_STD_SECAM_DK; 313 return V4L2_STD_SECAM_DK;
313 case 'l': 314 case 'l':
314 case 'L': 315 case 'L':
315 if (secam[1] == 'C' || secam[1] == 'c') 316 if (secam[1] == 'C' || secam[1] == 'c')
316 return V4L2_STD_SECAM_LC; 317 return V4L2_STD_SECAM_LC;
317 return V4L2_STD_SECAM_L; 318 return V4L2_STD_SECAM_L;
318 case '-': 319 case '-':
319 break; 320 break;
320 default: 321 default:
321 CX18_WARN("secam= argument not recognised\n"); 322 CX18_WARN("secam= argument not recognised\n");
322 return 0; 323 return 0;
323 } 324 }
324 325
325 switch (ntsc[0]) { 326 switch (ntsc[0]) {
326 case 'm': 327 case 'm':
327 case 'M': 328 case 'M':
328 return V4L2_STD_NTSC_M; 329 return V4L2_STD_NTSC_M;
329 case 'j': 330 case 'j':
330 case 'J': 331 case 'J':
331 return V4L2_STD_NTSC_M_JP; 332 return V4L2_STD_NTSC_M_JP;
332 case 'k': 333 case 'k':
333 case 'K': 334 case 'K':
334 return V4L2_STD_NTSC_M_KR; 335 return V4L2_STD_NTSC_M_KR;
335 case '-': 336 case '-':
336 break; 337 break;
337 default: 338 default:
338 CX18_WARN("ntsc= argument not recognised\n"); 339 CX18_WARN("ntsc= argument not recognised\n");
339 return 0; 340 return 0;
340 } 341 }
341 342
342 /* no match found */ 343 /* no match found */
343 return 0; 344 return 0;
344 } 345 }
345 346
346 static void cx18_process_options(struct cx18 *cx) 347 static void cx18_process_options(struct cx18 *cx)
347 { 348 {
348 int i, j; 349 int i, j;
349 350
350 cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers; 351 cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
351 cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers; 352 cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers;
352 cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers; 353 cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
353 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers; 354 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
354 cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers; 355 cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
355 cx->options.cardtype = cardtype[cx->num]; 356 cx->options.cardtype = cardtype[cx->num];
356 cx->options.tuner = tuner[cx->num]; 357 cx->options.tuner = tuner[cx->num];
357 cx->options.radio = radio[cx->num]; 358 cx->options.radio = radio[cx->num];
358 359
359 cx->std = cx18_parse_std(cx); 360 cx->std = cx18_parse_std(cx);
360 if (cx->options.cardtype == -1) { 361 if (cx->options.cardtype == -1) {
361 CX18_INFO("Ignore card\n"); 362 CX18_INFO("Ignore card\n");
362 return; 363 return;
363 } 364 }
364 cx->card = cx18_get_card(cx->options.cardtype - 1); 365 cx->card = cx18_get_card(cx->options.cardtype - 1);
365 if (cx->card) 366 if (cx->card)
366 CX18_INFO("User specified %s card\n", cx->card->name); 367 CX18_INFO("User specified %s card\n", cx->card->name);
367 else if (cx->options.cardtype != 0) 368 else if (cx->options.cardtype != 0)
368 CX18_ERR("Unknown user specified type, trying to autodetect card\n"); 369 CX18_ERR("Unknown user specified type, trying to autodetect card\n");
369 if (cx->card == NULL) { 370 if (cx->card == NULL) {
370 if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) { 371 if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
371 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); 372 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
372 CX18_INFO("Autodetected Hauppauge card\n"); 373 CX18_INFO("Autodetected Hauppauge card\n");
373 } 374 }
374 } 375 }
375 if (cx->card == NULL) { 376 if (cx->card == NULL) {
376 for (i = 0; (cx->card = cx18_get_card(i)); i++) { 377 for (i = 0; (cx->card = cx18_get_card(i)); i++) {
377 if (cx->card->pci_list == NULL) 378 if (cx->card->pci_list == NULL)
378 continue; 379 continue;
379 for (j = 0; cx->card->pci_list[j].device; j++) { 380 for (j = 0; cx->card->pci_list[j].device; j++) {
380 if (cx->dev->device != 381 if (cx->dev->device !=
381 cx->card->pci_list[j].device) 382 cx->card->pci_list[j].device)
382 continue; 383 continue;
383 if (cx->dev->subsystem_vendor != 384 if (cx->dev->subsystem_vendor !=
384 cx->card->pci_list[j].subsystem_vendor) 385 cx->card->pci_list[j].subsystem_vendor)
385 continue; 386 continue;
386 if (cx->dev->subsystem_device != 387 if (cx->dev->subsystem_device !=
387 cx->card->pci_list[j].subsystem_device) 388 cx->card->pci_list[j].subsystem_device)
388 continue; 389 continue;
389 CX18_INFO("Autodetected %s card\n", cx->card->name); 390 CX18_INFO("Autodetected %s card\n", cx->card->name);
390 goto done; 391 goto done;
391 } 392 }
392 } 393 }
393 } 394 }
394 done: 395 done:
395 396
396 if (cx->card == NULL) { 397 if (cx->card == NULL) {
397 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); 398 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
398 CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n", 399 CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
399 cx->dev->vendor, cx->dev->device); 400 cx->dev->vendor, cx->dev->device);
400 CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n", 401 CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n",
401 cx->dev->subsystem_vendor, cx->dev->subsystem_device); 402 cx->dev->subsystem_vendor, cx->dev->subsystem_device);
402 CX18_ERR("Defaulting to %s card\n", cx->card->name); 403 CX18_ERR("Defaulting to %s card\n", cx->card->name);
403 CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); 404 CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
404 CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n"); 405 CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
405 CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n"); 406 CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n");
406 } 407 }
407 cx->v4l2_cap = cx->card->v4l2_capabilities; 408 cx->v4l2_cap = cx->card->v4l2_capabilities;
408 cx->card_name = cx->card->name; 409 cx->card_name = cx->card->name;
409 cx->card_i2c = cx->card->i2c; 410 cx->card_i2c = cx->card->i2c;
410 } 411 }
411 412
412 /* Precondition: the cx18 structure has been memset to 0. Only 413 /* Precondition: the cx18 structure has been memset to 0. Only
413 the dev and num fields have been filled in. 414 the dev and num fields have been filled in.
414 No assumptions on the card type may be made here (see cx18_init_struct2 415 No assumptions on the card type may be made here (see cx18_init_struct2
415 for that). 416 for that).
416 */ 417 */
417 static int __devinit cx18_init_struct1(struct cx18 *cx) 418 static int __devinit cx18_init_struct1(struct cx18 *cx)
418 { 419 {
419 cx->base_addr = pci_resource_start(cx->dev, 0); 420 cx->base_addr = pci_resource_start(cx->dev, 0);
420 421
421 mutex_init(&cx->serialize_lock); 422 mutex_init(&cx->serialize_lock);
422 mutex_init(&cx->i2c_bus_lock[0]); 423 mutex_init(&cx->i2c_bus_lock[0]);
423 mutex_init(&cx->i2c_bus_lock[1]); 424 mutex_init(&cx->i2c_bus_lock[1]);
424 mutex_init(&cx->gpio_lock); 425 mutex_init(&cx->gpio_lock);
425 426
426 spin_lock_init(&cx->lock); 427 spin_lock_init(&cx->lock);
427 spin_lock_init(&cx->dma_reg_lock); 428 spin_lock_init(&cx->dma_reg_lock);
428 429
429 /* start counting open_id at 1 */ 430 /* start counting open_id at 1 */
430 cx->open_id = 1; 431 cx->open_id = 1;
431 432
432 /* Initial settings */ 433 /* Initial settings */
433 cx2341x_fill_defaults(&cx->params); 434 cx2341x_fill_defaults(&cx->params);
434 cx->temporal_strength = cx->params.video_temporal_filter; 435 cx->temporal_strength = cx->params.video_temporal_filter;
435 cx->spatial_strength = cx->params.video_spatial_filter; 436 cx->spatial_strength = cx->params.video_spatial_filter;
436 cx->filter_mode = cx->params.video_spatial_filter_mode | 437 cx->filter_mode = cx->params.video_spatial_filter_mode |
437 (cx->params.video_temporal_filter_mode << 1) | 438 (cx->params.video_temporal_filter_mode << 1) |
438 (cx->params.video_median_filter_type << 2); 439 (cx->params.video_median_filter_type << 2);
439 cx->params.port = CX2341X_PORT_MEMORY; 440 cx->params.port = CX2341X_PORT_MEMORY;
440 cx->params.capabilities = CX2341X_CAP_HAS_TS; 441 cx->params.capabilities = CX2341X_CAP_HAS_TS;
441 init_waitqueue_head(&cx->cap_w); 442 init_waitqueue_head(&cx->cap_w);
442 init_waitqueue_head(&cx->mb_apu_waitq); 443 init_waitqueue_head(&cx->mb_apu_waitq);
443 init_waitqueue_head(&cx->mb_cpu_waitq); 444 init_waitqueue_head(&cx->mb_cpu_waitq);
444 init_waitqueue_head(&cx->mb_epu_waitq); 445 init_waitqueue_head(&cx->mb_epu_waitq);
445 init_waitqueue_head(&cx->mb_hpu_waitq); 446 init_waitqueue_head(&cx->mb_hpu_waitq);
446 init_waitqueue_head(&cx->dma_waitq); 447 init_waitqueue_head(&cx->dma_waitq);
447 448
448 /* VBI */ 449 /* VBI */
449 cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; 450 cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
450 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; 451 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
451 cx->vbi.raw_size = 1456; 452 cx->vbi.raw_size = 1456;
452 cx->vbi.raw_decoder_line_size = 1456; 453 cx->vbi.raw_decoder_line_size = 1456;
453 cx->vbi.raw_decoder_sav_odd_field = 0x20; 454 cx->vbi.raw_decoder_sav_odd_field = 0x20;
454 cx->vbi.raw_decoder_sav_even_field = 0x60; 455 cx->vbi.raw_decoder_sav_even_field = 0x60;
455 cx->vbi.sliced_decoder_line_size = 272; 456 cx->vbi.sliced_decoder_line_size = 272;
456 cx->vbi.sliced_decoder_sav_odd_field = 0xB0; 457 cx->vbi.sliced_decoder_sav_odd_field = 0xB0;
457 cx->vbi.sliced_decoder_sav_even_field = 0xF0; 458 cx->vbi.sliced_decoder_sav_even_field = 0xF0;
458 return 0; 459 return 0;
459 } 460 }
460 461
461 /* Second initialization part. Here the card type has been 462 /* Second initialization part. Here the card type has been
462 autodetected. */ 463 autodetected. */
463 static void __devinit cx18_init_struct2(struct cx18 *cx) 464 static void __devinit cx18_init_struct2(struct cx18 *cx)
464 { 465 {
465 int i; 466 int i;
466 467
467 for (i = 0; i < CX18_CARD_MAX_VIDEO_INPUTS; i++) 468 for (i = 0; i < CX18_CARD_MAX_VIDEO_INPUTS; i++)
468 if (cx->card->video_inputs[i].video_type == 0) 469 if (cx->card->video_inputs[i].video_type == 0)
469 break; 470 break;
470 cx->nof_inputs = i; 471 cx->nof_inputs = i;
471 for (i = 0; i < CX18_CARD_MAX_AUDIO_INPUTS; i++) 472 for (i = 0; i < CX18_CARD_MAX_AUDIO_INPUTS; i++)
472 if (cx->card->audio_inputs[i].audio_type == 0) 473 if (cx->card->audio_inputs[i].audio_type == 0)
473 break; 474 break;
474 cx->nof_audio_inputs = i; 475 cx->nof_audio_inputs = i;
475 476
476 /* Find tuner input */ 477 /* Find tuner input */
477 for (i = 0; i < cx->nof_inputs; i++) { 478 for (i = 0; i < cx->nof_inputs; i++) {
478 if (cx->card->video_inputs[i].video_type == 479 if (cx->card->video_inputs[i].video_type ==
479 CX18_CARD_INPUT_VID_TUNER) 480 CX18_CARD_INPUT_VID_TUNER)
480 break; 481 break;
481 } 482 }
482 if (i == cx->nof_inputs) 483 if (i == cx->nof_inputs)
483 i = 0; 484 i = 0;
484 cx->active_input = i; 485 cx->active_input = i;
485 cx->audio_input = cx->card->video_inputs[i].audio_index; 486 cx->audio_input = cx->card->video_inputs[i].audio_index;
486 cx->av_state.vid_input = CX18_AV_COMPOSITE7; 487 cx->av_state.vid_input = CX18_AV_COMPOSITE7;
487 cx->av_state.aud_input = CX18_AV_AUDIO8; 488 cx->av_state.aud_input = CX18_AV_AUDIO8;
488 cx->av_state.audclk_freq = 48000; 489 cx->av_state.audclk_freq = 48000;
489 cx->av_state.audmode = V4L2_TUNER_MODE_LANG1; 490 cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
490 cx->av_state.vbi_line_offset = 8; 491 cx->av_state.vbi_line_offset = 8;
491 } 492 }
492 493
493 static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev, 494 static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
494 const struct pci_device_id *pci_id) 495 const struct pci_device_id *pci_id)
495 { 496 {
496 u16 cmd; 497 u16 cmd;
497 unsigned char pci_latency; 498 unsigned char pci_latency;
498 499
499 CX18_DEBUG_INFO("Enabling pci device\n"); 500 CX18_DEBUG_INFO("Enabling pci device\n");
500 501
501 if (pci_enable_device(dev)) { 502 if (pci_enable_device(dev)) {
502 CX18_ERR("Can't enable device %d!\n", cx->num); 503 CX18_ERR("Can't enable device %d!\n", cx->num);
503 return -EIO; 504 return -EIO;
504 } 505 }
505 if (pci_set_dma_mask(dev, 0xffffffff)) { 506 if (pci_set_dma_mask(dev, 0xffffffff)) {
506 CX18_ERR("No suitable DMA available on card %d.\n", cx->num); 507 CX18_ERR("No suitable DMA available on card %d.\n", cx->num);
507 return -EIO; 508 return -EIO;
508 } 509 }
509 if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) { 510 if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
510 CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num); 511 CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num);
511 return -EIO; 512 return -EIO;
512 } 513 }
513 514
514 /* Enable bus mastering and memory mapped IO for the CX23418 */ 515 /* Enable bus mastering and memory mapped IO for the CX23418 */
515 pci_read_config_word(dev, PCI_COMMAND, &cmd); 516 pci_read_config_word(dev, PCI_COMMAND, &cmd);
516 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; 517 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
517 pci_write_config_word(dev, PCI_COMMAND, cmd); 518 pci_write_config_word(dev, PCI_COMMAND, cmd);
518 519
519 pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev); 520 pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev);
520 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); 521 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
521 522
522 if (pci_latency < 64 && cx18_pci_latency) { 523 if (pci_latency < 64 && cx18_pci_latency) {
523 CX18_INFO("Unreasonably low latency timer, " 524 CX18_INFO("Unreasonably low latency timer, "
524 "setting to 64 (was %d)\n", pci_latency); 525 "setting to 64 (was %d)\n", pci_latency);
525 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); 526 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
526 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); 527 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
527 } 528 }
528 529
529 CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, " 530 CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, "
530 "irq: %d, latency: %d, memory: 0x%lx\n", 531 "irq: %d, latency: %d, memory: 0x%lx\n",
531 cx->dev->device, cx->card_rev, dev->bus->number, 532 cx->dev->device, cx->card_rev, dev->bus->number,
532 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), 533 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
533 cx->dev->irq, pci_latency, (unsigned long)cx->base_addr); 534 cx->dev->irq, pci_latency, (unsigned long)cx->base_addr);
534 535
535 return 0; 536 return 0;
536 } 537 }
537 538
538 #ifdef MODULE 539 #ifdef MODULE
539 static u32 cx18_request_module(struct cx18 *cx, u32 hw, 540 static u32 cx18_request_module(struct cx18 *cx, u32 hw,
540 const char *name, u32 id) 541 const char *name, u32 id)
541 { 542 {
542 if ((hw & id) == 0) 543 if ((hw & id) == 0)
543 return hw; 544 return hw;
544 if (request_module(name) != 0) { 545 if (request_module(name) != 0) {
545 CX18_ERR("Failed to load module %s\n", name); 546 CX18_ERR("Failed to load module %s\n", name);
546 return hw & ~id; 547 return hw & ~id;
547 } 548 }
548 CX18_DEBUG_INFO("Loaded module %s\n", name); 549 CX18_DEBUG_INFO("Loaded module %s\n", name);
549 return hw; 550 return hw;
550 } 551 }
551 #endif 552 #endif
552 553
553 static void cx18_load_and_init_modules(struct cx18 *cx) 554 static void cx18_load_and_init_modules(struct cx18 *cx)
554 { 555 {
555 u32 hw = cx->card->hw_all; 556 u32 hw = cx->card->hw_all;
556 int i; 557 int i;
557 558
558 #ifdef MODULE 559 #ifdef MODULE
559 /* load modules */ 560 /* load modules */
560 #ifndef CONFIG_MEDIA_TUNER 561 #ifndef CONFIG_MEDIA_TUNER
561 hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); 562 hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
562 #endif 563 #endif
563 #ifndef CONFIG_VIDEO_CS5345 564 #ifndef CONFIG_VIDEO_CS5345
564 hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); 565 hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
565 #endif 566 #endif
566 #endif 567 #endif
567 568
568 /* check which i2c devices are actually found */ 569 /* check which i2c devices are actually found */
569 for (i = 0; i < 32; i++) { 570 for (i = 0; i < 32; i++) {
570 u32 device = 1 << i; 571 u32 device = 1 << i;
571 572
572 if (!(device & hw)) 573 if (!(device & hw))
573 continue; 574 continue;
574 if (device == CX18_HW_GPIO || device == CX18_HW_TVEEPROM || 575 if (device == CX18_HW_GPIO || device == CX18_HW_TVEEPROM ||
575 device == CX18_HW_CX23418 || device == CX18_HW_DVB) { 576 device == CX18_HW_CX23418 || device == CX18_HW_DVB) {
576 /* These 'devices' do not use i2c probing */ 577 /* These 'devices' do not use i2c probing */
577 cx->hw_flags |= device; 578 cx->hw_flags |= device;
578 continue; 579 continue;
579 } 580 }
580 cx18_i2c_register(cx, i); 581 cx18_i2c_register(cx, i);
581 if (cx18_i2c_hw_addr(cx, device) > 0) 582 if (cx18_i2c_hw_addr(cx, device) > 0)
582 cx->hw_flags |= device; 583 cx->hw_flags |= device;
583 } 584 }
584 585
585 hw = cx->hw_flags; 586 hw = cx->hw_flags;
586 } 587 }
587 588
588 static int __devinit cx18_probe(struct pci_dev *dev, 589 static int __devinit cx18_probe(struct pci_dev *dev,
589 const struct pci_device_id *pci_id) 590 const struct pci_device_id *pci_id)
590 { 591 {
591 int retval = 0; 592 int retval = 0;
592 int vbi_buf_size; 593 int vbi_buf_size;
593 u32 devtype; 594 u32 devtype;
594 struct cx18 *cx; 595 struct cx18 *cx;
595 596
596 spin_lock(&cx18_cards_lock); 597 spin_lock(&cx18_cards_lock);
597 598
598 /* Make sure we've got a place for this card */ 599 /* Make sure we've got a place for this card */
599 if (cx18_cards_active == CX18_MAX_CARDS) { 600 if (cx18_cards_active == CX18_MAX_CARDS) {
600 printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n", 601 printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n",
601 cx18_cards_active); 602 cx18_cards_active);
602 spin_unlock(&cx18_cards_lock); 603 spin_unlock(&cx18_cards_lock);
603 return -ENOMEM; 604 return -ENOMEM;
604 } 605 }
605 606
606 cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC); 607 cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
607 if (!cx) { 608 if (!cx) {
608 spin_unlock(&cx18_cards_lock); 609 spin_unlock(&cx18_cards_lock);
609 return -ENOMEM; 610 return -ENOMEM;
610 } 611 }
611 cx18_cards[cx18_cards_active] = cx; 612 cx18_cards[cx18_cards_active] = cx;
612 cx->dev = dev; 613 cx->dev = dev;
613 cx->num = cx18_cards_active++; 614 cx->num = cx18_cards_active++;
614 snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num); 615 snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num);
615 CX18_INFO("Initializing card #%d\n", cx->num); 616 CX18_INFO("Initializing card #%d\n", cx->num);
616 617
617 spin_unlock(&cx18_cards_lock); 618 spin_unlock(&cx18_cards_lock);
618 619
619 cx18_process_options(cx); 620 cx18_process_options(cx);
620 if (cx->options.cardtype == -1) { 621 if (cx->options.cardtype == -1) {
621 retval = -ENODEV; 622 retval = -ENODEV;
622 goto err; 623 goto err;
623 } 624 }
624 if (cx18_init_struct1(cx)) { 625 if (cx18_init_struct1(cx)) {
625 retval = -ENOMEM; 626 retval = -ENOMEM;
626 goto err; 627 goto err;
627 } 628 }
628 629
629 CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); 630 CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
630 631
631 /* PCI Device Setup */ 632 /* PCI Device Setup */
632 retval = cx18_setup_pci(cx, dev, pci_id); 633 retval = cx18_setup_pci(cx, dev, pci_id);
633 if (retval != 0) { 634 if (retval != 0) {
634 if (retval == -EIO) 635 if (retval == -EIO)
635 goto free_workqueue; 636 goto free_workqueue;
636 else if (retval == -ENXIO) 637 else if (retval == -ENXIO)
637 goto free_mem; 638 goto free_mem;
638 } 639 }
639 /* save cx in the pci struct for later use */ 640 /* save cx in the pci struct for later use */
640 pci_set_drvdata(dev, cx); 641 pci_set_drvdata(dev, cx);
641 642
642 /* map io memory */ 643 /* map io memory */
643 CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", 644 CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
644 cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); 645 cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE);
645 cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET, 646 cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET,
646 CX18_MEM_SIZE); 647 CX18_MEM_SIZE);
647 if (!cx->enc_mem) { 648 if (!cx->enc_mem) {
648 CX18_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n"); 649 CX18_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
649 CX18_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n"); 650 CX18_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n");
650 retval = -ENOMEM; 651 retval = -ENOMEM;
651 goto free_mem; 652 goto free_mem;
652 } 653 }
653 cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET; 654 cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET;
654 devtype = read_reg(0xC72028); 655 devtype = cx18_read_reg(cx, 0xC72028);
655 switch (devtype & 0xff000000) { 656 switch (devtype & 0xff000000) {
656 case 0xff000000: 657 case 0xff000000:
657 CX18_INFO("cx23418 revision %08x (A)\n", devtype); 658 CX18_INFO("cx23418 revision %08x (A)\n", devtype);
658 break; 659 break;
659 case 0x01000000: 660 case 0x01000000:
660 CX18_INFO("cx23418 revision %08x (B)\n", devtype); 661 CX18_INFO("cx23418 revision %08x (B)\n", devtype);
661 break; 662 break;
662 default: 663 default:
663 CX18_INFO("cx23418 revision %08x (Unknown)\n", devtype); 664 CX18_INFO("cx23418 revision %08x (Unknown)\n", devtype);
664 break; 665 break;
665 } 666 }
666 667
667 cx18_init_power(cx, 1); 668 cx18_init_power(cx, 1);
668 cx18_init_memory(cx); 669 cx18_init_memory(cx);
669 670
670 cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET); 671 cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET);
671 cx18_init_scb(cx); 672 cx18_init_scb(cx);
672 673
673 cx18_gpio_init(cx); 674 cx18_gpio_init(cx);
674 675
675 /* active i2c */ 676 /* active i2c */
676 CX18_DEBUG_INFO("activating i2c...\n"); 677 CX18_DEBUG_INFO("activating i2c...\n");
677 if (init_cx18_i2c(cx)) { 678 if (init_cx18_i2c(cx)) {
678 CX18_ERR("Could not initialize i2c\n"); 679 CX18_ERR("Could not initialize i2c\n");
679 goto free_map; 680 goto free_map;
680 } 681 }
681 682
682 CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active); 683 CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active);
683 684
684 if (cx->card->hw_all & CX18_HW_TVEEPROM) { 685 if (cx->card->hw_all & CX18_HW_TVEEPROM) {
685 /* Based on the model number the cardtype may be changed. 686 /* Based on the model number the cardtype may be changed.
686 The PCI IDs are not always reliable. */ 687 The PCI IDs are not always reliable. */
687 cx18_process_eeprom(cx); 688 cx18_process_eeprom(cx);
688 } 689 }
689 if (cx->card->comment) 690 if (cx->card->comment)
690 CX18_INFO("%s", cx->card->comment); 691 CX18_INFO("%s", cx->card->comment);
691 if (cx->card->v4l2_capabilities == 0) { 692 if (cx->card->v4l2_capabilities == 0) {
692 retval = -ENODEV; 693 retval = -ENODEV;
693 goto free_i2c; 694 goto free_i2c;
694 } 695 }
695 cx18_init_memory(cx); 696 cx18_init_memory(cx);
696 697
697 /* Register IRQ */ 698 /* Register IRQ */
698 retval = request_irq(cx->dev->irq, cx18_irq_handler, 699 retval = request_irq(cx->dev->irq, cx18_irq_handler,
699 IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx); 700 IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx);
700 if (retval) { 701 if (retval) {
701 CX18_ERR("Failed to register irq %d\n", retval); 702 CX18_ERR("Failed to register irq %d\n", retval);
702 goto free_i2c; 703 goto free_i2c;
703 } 704 }
704 705
705 if (cx->std == 0) 706 if (cx->std == 0)
706 cx->std = V4L2_STD_NTSC_M; 707 cx->std = V4L2_STD_NTSC_M;
707 708
708 if (cx->options.tuner == -1) { 709 if (cx->options.tuner == -1) {
709 int i; 710 int i;
710 711
711 for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) { 712 for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) {
712 if ((cx->std & cx->card->tuners[i].std) == 0) 713 if ((cx->std & cx->card->tuners[i].std) == 0)
713 continue; 714 continue;
714 cx->options.tuner = cx->card->tuners[i].tuner; 715 cx->options.tuner = cx->card->tuners[i].tuner;
715 break; 716 break;
716 } 717 }
717 } 718 }
718 /* if no tuner was found, then pick the first tuner in the card list */ 719 /* if no tuner was found, then pick the first tuner in the card list */
719 if (cx->options.tuner == -1 && cx->card->tuners[0].std) { 720 if (cx->options.tuner == -1 && cx->card->tuners[0].std) {
720 cx->std = cx->card->tuners[0].std; 721 cx->std = cx->card->tuners[0].std;
721 if (cx->std & V4L2_STD_PAL) 722 if (cx->std & V4L2_STD_PAL)
722 cx->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H; 723 cx->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
723 else if (cx->std & V4L2_STD_NTSC) 724 else if (cx->std & V4L2_STD_NTSC)
724 cx->std = V4L2_STD_NTSC_M; 725 cx->std = V4L2_STD_NTSC_M;
725 else if (cx->std & V4L2_STD_SECAM) 726 else if (cx->std & V4L2_STD_SECAM)
726 cx->std = V4L2_STD_SECAM_L; 727 cx->std = V4L2_STD_SECAM_L;
727 cx->options.tuner = cx->card->tuners[0].tuner; 728 cx->options.tuner = cx->card->tuners[0].tuner;
728 } 729 }
729 if (cx->options.radio == -1) 730 if (cx->options.radio == -1)
730 cx->options.radio = (cx->card->radio_input.audio_type != 0); 731 cx->options.radio = (cx->card->radio_input.audio_type != 0);
731 732
732 /* The card is now fully identified, continue with card-specific 733 /* The card is now fully identified, continue with card-specific
733 initialization. */ 734 initialization. */
734 cx18_init_struct2(cx); 735 cx18_init_struct2(cx);
735 736
736 cx18_load_and_init_modules(cx); 737 cx18_load_and_init_modules(cx);
737 738
738 if (cx->std & V4L2_STD_525_60) { 739 if (cx->std & V4L2_STD_525_60) {
739 cx->is_60hz = 1; 740 cx->is_60hz = 1;
740 cx->is_out_60hz = 1; 741 cx->is_out_60hz = 1;
741 } else { 742 } else {
742 cx->is_50hz = 1; 743 cx->is_50hz = 1;
743 cx->is_out_50hz = 1; 744 cx->is_out_50hz = 1;
744 } 745 }
745 cx->params.video_gop_size = cx->is_60hz ? 15 : 12; 746 cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
746 747
747 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = 0x08000; 748 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = 0x08000;
748 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = 0x08000; 749 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = 0x08000;
749 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = 0x01200; 750 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = 0x01200;
750 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = 0x20000; 751 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = 0x20000;
751 vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2; 752 vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2;
752 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size; 753 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
753 754
754 if (cx->options.radio > 0) 755 if (cx->options.radio > 0)
755 cx->v4l2_cap |= V4L2_CAP_RADIO; 756 cx->v4l2_cap |= V4L2_CAP_RADIO;
756 757
757 if (cx->options.tuner > -1) { 758 if (cx->options.tuner > -1) {
758 struct tuner_setup setup; 759 struct tuner_setup setup;
759 760
760 setup.addr = ADDR_UNSET; 761 setup.addr = ADDR_UNSET;
761 setup.type = cx->options.tuner; 762 setup.type = cx->options.tuner;
762 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ 763 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
763 setup.tuner_callback = (setup.type == TUNER_XC2028) ? 764 setup.tuner_callback = (setup.type == TUNER_XC2028) ?
764 cx18_reset_tuner_gpio : NULL; 765 cx18_reset_tuner_gpio : NULL;
765 cx18_call_i2c_clients(cx, TUNER_SET_TYPE_ADDR, &setup); 766 cx18_call_i2c_clients(cx, TUNER_SET_TYPE_ADDR, &setup);
766 if (setup.type == TUNER_XC2028) { 767 if (setup.type == TUNER_XC2028) {
767 static struct xc2028_ctrl ctrl = { 768 static struct xc2028_ctrl ctrl = {
768 .fname = XC2028_DEFAULT_FIRMWARE, 769 .fname = XC2028_DEFAULT_FIRMWARE,
769 .max_len = 64, 770 .max_len = 64,
770 }; 771 };
771 struct v4l2_priv_tun_config cfg = { 772 struct v4l2_priv_tun_config cfg = {
772 .tuner = cx->options.tuner, 773 .tuner = cx->options.tuner,
773 .priv = &ctrl, 774 .priv = &ctrl,
774 }; 775 };
775 cx18_call_i2c_clients(cx, TUNER_SET_CONFIG, &cfg); 776 cx18_call_i2c_clients(cx, TUNER_SET_CONFIG, &cfg);
776 } 777 }
777 } 778 }
778 779
779 /* The tuner is fixed to the standard. The other inputs (e.g. S-Video) 780 /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
780 are not. */ 781 are not. */
781 cx->tuner_std = cx->std; 782 cx->tuner_std = cx->std;
782 783
783 retval = cx18_streams_setup(cx); 784 retval = cx18_streams_setup(cx);
784 if (retval) { 785 if (retval) {
785 CX18_ERR("Error %d setting up streams\n", retval); 786 CX18_ERR("Error %d setting up streams\n", retval);
786 goto free_irq; 787 goto free_irq;
787 } 788 }
788 retval = cx18_streams_register(cx); 789 retval = cx18_streams_register(cx);
789 if (retval) { 790 if (retval) {
790 CX18_ERR("Error %d registering devices\n", retval); 791 CX18_ERR("Error %d registering devices\n", retval);
791 goto free_streams; 792 goto free_streams;
792 } 793 }
793 794
794 CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name); 795 CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name);
795 796
796 return 0; 797 return 0;
797 798
798 free_streams: 799 free_streams:
799 cx18_streams_cleanup(cx, 1); 800 cx18_streams_cleanup(cx, 1);
800 free_irq: 801 free_irq:
801 free_irq(cx->dev->irq, (void *)cx); 802 free_irq(cx->dev->irq, (void *)cx);
802 free_i2c: 803 free_i2c:
803 exit_cx18_i2c(cx); 804 exit_cx18_i2c(cx);
804 free_map: 805 free_map:
805 cx18_iounmap(cx); 806 cx18_iounmap(cx);
806 free_mem: 807 free_mem:
807 release_mem_region(cx->base_addr, CX18_MEM_SIZE); 808 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
808 free_workqueue: 809 free_workqueue:
809 err: 810 err:
810 if (retval == 0) 811 if (retval == 0)
811 retval = -ENODEV; 812 retval = -ENODEV;
812 CX18_ERR("Error %d on initialization\n", retval); 813 CX18_ERR("Error %d on initialization\n", retval);
813 814
814 kfree(cx18_cards[cx18_cards_active]); 815 kfree(cx18_cards[cx18_cards_active]);
815 cx18_cards[cx18_cards_active] = NULL; 816 cx18_cards[cx18_cards_active] = NULL;
816 return retval; 817 return retval;
817 } 818 }
818 819
819 int cx18_init_on_first_open(struct cx18 *cx) 820 int cx18_init_on_first_open(struct cx18 *cx)
820 { 821 {
821 int video_input; 822 int video_input;
822 int fw_retry_count = 3; 823 int fw_retry_count = 3;
823 struct v4l2_frequency vf; 824 struct v4l2_frequency vf;
824 struct cx18_open_id fh; 825 struct cx18_open_id fh;
825 826
826 fh.cx = cx; 827 fh.cx = cx;
827 828
828 if (test_bit(CX18_F_I_FAILED, &cx->i_flags)) 829 if (test_bit(CX18_F_I_FAILED, &cx->i_flags))
829 return -ENXIO; 830 return -ENXIO;
830 831
831 if (test_and_set_bit(CX18_F_I_INITED, &cx->i_flags)) 832 if (test_and_set_bit(CX18_F_I_INITED, &cx->i_flags))
832 return 0; 833 return 0;
833 834
834 while (--fw_retry_count > 0) { 835 while (--fw_retry_count > 0) {
835 /* load firmware */ 836 /* load firmware */
836 if (cx18_firmware_init(cx) == 0) 837 if (cx18_firmware_init(cx) == 0)
837 break; 838 break;
838 if (fw_retry_count > 1) 839 if (fw_retry_count > 1)
839 CX18_WARN("Retry loading firmware\n"); 840 CX18_WARN("Retry loading firmware\n");
840 } 841 }
841 842
842 if (fw_retry_count == 0) { 843 if (fw_retry_count == 0) {
843 set_bit(CX18_F_I_FAILED, &cx->i_flags); 844 set_bit(CX18_F_I_FAILED, &cx->i_flags);
844 return -ENXIO; 845 return -ENXIO;
845 } 846 }
846 set_bit(CX18_F_I_LOADED_FW, &cx->i_flags); 847 set_bit(CX18_F_I_LOADED_FW, &cx->i_flags);
847 848
848 /* Init the firmware twice to work around a silicon bug 849 /* Init the firmware twice to work around a silicon bug
849 * transport related. */ 850 * transport related. */
850 851
851 fw_retry_count = 3; 852 fw_retry_count = 3;
852 while (--fw_retry_count > 0) { 853 while (--fw_retry_count > 0) {
853 /* load firmware */ 854 /* load firmware */
854 if (cx18_firmware_init(cx) == 0) 855 if (cx18_firmware_init(cx) == 0)
855 break; 856 break;
856 if (fw_retry_count > 1) 857 if (fw_retry_count > 1)
857 CX18_WARN("Retry loading firmware\n"); 858 CX18_WARN("Retry loading firmware\n");
858 } 859 }
859 860
860 if (fw_retry_count == 0) { 861 if (fw_retry_count == 0) {
861 set_bit(CX18_F_I_FAILED, &cx->i_flags); 862 set_bit(CX18_F_I_FAILED, &cx->i_flags);
862 return -ENXIO; 863 return -ENXIO;
863 } 864 }
864 865
865 vf.tuner = 0; 866 vf.tuner = 0;
866 vf.type = V4L2_TUNER_ANALOG_TV; 867 vf.type = V4L2_TUNER_ANALOG_TV;
867 vf.frequency = 6400; /* the tuner 'baseline' frequency */ 868 vf.frequency = 6400; /* the tuner 'baseline' frequency */
868 869
869 /* Set initial frequency. For PAL/SECAM broadcasts no 870 /* Set initial frequency. For PAL/SECAM broadcasts no
870 'default' channel exists AFAIK. */ 871 'default' channel exists AFAIK. */
871 if (cx->std == V4L2_STD_NTSC_M_JP) 872 if (cx->std == V4L2_STD_NTSC_M_JP)
872 vf.frequency = 1460; /* ch. 1 91250*16/1000 */ 873 vf.frequency = 1460; /* ch. 1 91250*16/1000 */
873 else if (cx->std & V4L2_STD_NTSC_M) 874 else if (cx->std & V4L2_STD_NTSC_M)
874 vf.frequency = 1076; /* ch. 4 67250*16/1000 */ 875 vf.frequency = 1076; /* ch. 4 67250*16/1000 */
875 876
876 video_input = cx->active_input; 877 video_input = cx->active_input;
877 cx->active_input++; /* Force update of input */ 878 cx->active_input++; /* Force update of input */
878 cx18_s_input(NULL, &fh, video_input); 879 cx18_s_input(NULL, &fh, video_input);
879 880
880 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code 881 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
881 in one place. */ 882 in one place. */
882 cx->std++; /* Force full standard initialization */ 883 cx->std++; /* Force full standard initialization */
883 cx18_s_std(NULL, &fh, &cx->tuner_std); 884 cx18_s_std(NULL, &fh, &cx->tuner_std);
884 cx18_s_frequency(NULL, &fh, &vf); 885 cx18_s_frequency(NULL, &fh, &vf);
885 return 0; 886 return 0;
886 } 887 }
887 888
888 static void cx18_remove(struct pci_dev *pci_dev) 889 static void cx18_remove(struct pci_dev *pci_dev)
889 { 890 {
890 struct cx18 *cx = pci_get_drvdata(pci_dev); 891 struct cx18 *cx = pci_get_drvdata(pci_dev);
891 892
892 CX18_DEBUG_INFO("Removing Card #%d\n", cx->num); 893 CX18_DEBUG_INFO("Removing Card #%d\n", cx->num);
893 894
894 /* Stop all captures */ 895 /* Stop all captures */
895 CX18_DEBUG_INFO("Stopping all streams\n"); 896 CX18_DEBUG_INFO("Stopping all streams\n");
896 if (atomic_read(&cx->tot_capturing) > 0) 897 if (atomic_read(&cx->tot_capturing) > 0)
897 cx18_stop_all_captures(cx); 898 cx18_stop_all_captures(cx);
898 899
899 /* Interrupts */ 900 /* Interrupts */
900 sw1_irq_disable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); 901 cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
901 sw2_irq_disable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); 902 cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
902 903
903 cx18_halt_firmware(cx); 904 cx18_halt_firmware(cx);
904 905
905 cx18_streams_cleanup(cx, 1); 906 cx18_streams_cleanup(cx, 1);
906 907
907 exit_cx18_i2c(cx); 908 exit_cx18_i2c(cx);
908 909
909 free_irq(cx->dev->irq, (void *)cx); 910 free_irq(cx->dev->irq, (void *)cx);
910 911
911 cx18_iounmap(cx); 912 cx18_iounmap(cx);
912 913
913 release_mem_region(cx->base_addr, CX18_MEM_SIZE); 914 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
914 915
915 pci_disable_device(cx->dev); 916 pci_disable_device(cx->dev);
916 917
917 CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num); 918 CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
918 } 919 }
919 920
920 /* define a pci_driver for card detection */ 921 /* define a pci_driver for card detection */
921 static struct pci_driver cx18_pci_driver = { 922 static struct pci_driver cx18_pci_driver = {
922 .name = "cx18", 923 .name = "cx18",
923 .id_table = cx18_pci_tbl, 924 .id_table = cx18_pci_tbl,
924 .probe = cx18_probe, 925 .probe = cx18_probe,
925 .remove = cx18_remove, 926 .remove = cx18_remove,
926 }; 927 };
927 928
928 static int module_start(void) 929 static int module_start(void)
929 { 930 {
930 printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION); 931 printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION);
931 932
932 memset(cx18_cards, 0, sizeof(cx18_cards)); 933 memset(cx18_cards, 0, sizeof(cx18_cards));
933 934
934 /* Validate parameters */ 935 /* Validate parameters */
935 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { 936 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
936 printk(KERN_ERR "cx18: Exiting, ivtv_first_minor must be between 0 and %d\n", 937 printk(KERN_ERR "cx18: Exiting, ivtv_first_minor must be between 0 and %d\n",
937 CX18_MAX_CARDS - 1); 938 CX18_MAX_CARDS - 1);
938 return -1; 939 return -1;
939 } 940 }
940 941
941 if (cx18_debug < 0 || cx18_debug > 511) { 942 if (cx18_debug < 0 || cx18_debug > 511) {
942 cx18_debug = 0; 943 cx18_debug = 0;
943 printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n"); 944 printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n");
944 } 945 }
945 946
946 if (pci_register_driver(&cx18_pci_driver)) { 947 if (pci_register_driver(&cx18_pci_driver)) {
947 printk(KERN_ERR "cx18: Error detecting PCI card\n"); 948 printk(KERN_ERR "cx18: Error detecting PCI card\n");
948 return -ENODEV; 949 return -ENODEV;
949 } 950 }
950 printk(KERN_INFO "cx18: End initialization\n"); 951 printk(KERN_INFO "cx18: End initialization\n");
951 return 0; 952 return 0;
952 } 953 }
953 954
954 static void module_cleanup(void) 955 static void module_cleanup(void)
955 { 956 {
956 int i; 957 int i;
957 958
958 pci_unregister_driver(&cx18_pci_driver); 959 pci_unregister_driver(&cx18_pci_driver);
959 960
960 for (i = 0; i < cx18_cards_active; i++) { 961 for (i = 0; i < cx18_cards_active; i++) {
961 if (cx18_cards[i] == NULL) 962 if (cx18_cards[i] == NULL)
962 continue; 963 continue;
963 kfree(cx18_cards[i]); 964 kfree(cx18_cards[i]);
964 } 965 }
965 } 966 }
966 967
967 module_init(module_start); 968 module_init(module_start);
968 module_exit(module_cleanup); 969 module_exit(module_cleanup);
969 970
drivers/media/video/cx18/cx18-driver.h
1 /* 1 /*
2 * cx18 driver internal defines and structures 2 * cx18 driver internal defines and structures
3 * 3 *
4 * Derived from ivtv-driver.h 4 * Derived from ivtv-driver.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 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 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 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 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24 #ifndef CX18_DRIVER_H 24 #ifndef CX18_DRIVER_H
25 #define CX18_DRIVER_H 25 #define CX18_DRIVER_H
26 26
27 #include <linux/version.h> 27 #include <linux/version.h>
28 #include <linux/module.h> 28 #include <linux/module.h>
29 #include <linux/moduleparam.h> 29 #include <linux/moduleparam.h>
30 #include <linux/init.h> 30 #include <linux/init.h>
31 #include <linux/delay.h> 31 #include <linux/delay.h>
32 #include <linux/sched.h> 32 #include <linux/sched.h>
33 #include <linux/fs.h> 33 #include <linux/fs.h>
34 #include <linux/pci.h> 34 #include <linux/pci.h>
35 #include <linux/interrupt.h> 35 #include <linux/interrupt.h>
36 #include <linux/spinlock.h> 36 #include <linux/spinlock.h>
37 #include <linux/i2c.h> 37 #include <linux/i2c.h>
38 #include <linux/i2c-algo-bit.h> 38 #include <linux/i2c-algo-bit.h>
39 #include <linux/list.h> 39 #include <linux/list.h>
40 #include <linux/unistd.h> 40 #include <linux/unistd.h>
41 #include <linux/pagemap.h> 41 #include <linux/pagemap.h>
42 #include <linux/workqueue.h> 42 #include <linux/workqueue.h>
43 #include <linux/mutex.h> 43 #include <linux/mutex.h>
44 44
45 #include <linux/dvb/video.h> 45 #include <linux/dvb/video.h>
46 #include <linux/dvb/audio.h> 46 #include <linux/dvb/audio.h>
47 #include <media/v4l2-common.h> 47 #include <media/v4l2-common.h>
48 #include <media/v4l2-ioctl.h> 48 #include <media/v4l2-ioctl.h>
49 #include <media/tuner.h> 49 #include <media/tuner.h>
50 #include "cx18-mailbox.h" 50 #include "cx18-mailbox.h"
51 #include "cx18-av-core.h" 51 #include "cx18-av-core.h"
52 #include "cx23418.h" 52 #include "cx23418.h"
53 53
54 /* DVB */ 54 /* DVB */
55 #include "demux.h" 55 #include "demux.h"
56 #include "dmxdev.h" 56 #include "dmxdev.h"
57 #include "dvb_demux.h" 57 #include "dvb_demux.h"
58 #include "dvb_frontend.h" 58 #include "dvb_frontend.h"
59 #include "dvb_net.h" 59 #include "dvb_net.h"
60 #include "dvbdev.h" 60 #include "dvbdev.h"
61 61
62 #ifndef CONFIG_PCI 62 #ifndef CONFIG_PCI
63 # error "This driver requires kernel PCI support." 63 # error "This driver requires kernel PCI support."
64 #endif 64 #endif
65 65
66 #define CX18_MEM_OFFSET 0x00000000 66 #define CX18_MEM_OFFSET 0x00000000
67 #define CX18_MEM_SIZE 0x04000000 67 #define CX18_MEM_SIZE 0x04000000
68 #define CX18_REG_OFFSET 0x02000000 68 #define CX18_REG_OFFSET 0x02000000
69 69
70 /* Maximum cx18 driver instances. */ 70 /* Maximum cx18 driver instances. */
71 #define CX18_MAX_CARDS 32 71 #define CX18_MAX_CARDS 32
72 72
73 /* Supported cards */ 73 /* Supported cards */
74 #define CX18_CARD_HVR_1600_ESMT 0 /* Hauppauge HVR 1600 (ESMT memory) */ 74 #define CX18_CARD_HVR_1600_ESMT 0 /* Hauppauge HVR 1600 (ESMT memory) */
75 #define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */ 75 #define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */
76 #define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */ 76 #define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */
77 #define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ 77 #define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
78 #define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ 78 #define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
79 #define CX18_CARD_LAST 4 79 #define CX18_CARD_LAST 4
80 80
81 #define CX18_ENC_STREAM_TYPE_MPG 0 81 #define CX18_ENC_STREAM_TYPE_MPG 0
82 #define CX18_ENC_STREAM_TYPE_TS 1 82 #define CX18_ENC_STREAM_TYPE_TS 1
83 #define CX18_ENC_STREAM_TYPE_YUV 2 83 #define CX18_ENC_STREAM_TYPE_YUV 2
84 #define CX18_ENC_STREAM_TYPE_VBI 3 84 #define CX18_ENC_STREAM_TYPE_VBI 3
85 #define CX18_ENC_STREAM_TYPE_PCM 4 85 #define CX18_ENC_STREAM_TYPE_PCM 4
86 #define CX18_ENC_STREAM_TYPE_IDX 5 86 #define CX18_ENC_STREAM_TYPE_IDX 5
87 #define CX18_ENC_STREAM_TYPE_RAD 6 87 #define CX18_ENC_STREAM_TYPE_RAD 6
88 #define CX18_MAX_STREAMS 7 88 #define CX18_MAX_STREAMS 7
89 89
90 /* system vendor and device IDs */ 90 /* system vendor and device IDs */
91 #define PCI_VENDOR_ID_CX 0x14f1 91 #define PCI_VENDOR_ID_CX 0x14f1
92 #define PCI_DEVICE_ID_CX23418 0x5b7a 92 #define PCI_DEVICE_ID_CX23418 0x5b7a
93 93
94 /* subsystem vendor ID */ 94 /* subsystem vendor ID */
95 #define CX18_PCI_ID_HAUPPAUGE 0x0070 95 #define CX18_PCI_ID_HAUPPAUGE 0x0070
96 #define CX18_PCI_ID_COMPRO 0x185b 96 #define CX18_PCI_ID_COMPRO 0x185b
97 #define CX18_PCI_ID_YUAN 0x12ab 97 #define CX18_PCI_ID_YUAN 0x12ab
98 #define CX18_PCI_ID_CONEXANT 0x14f1 98 #define CX18_PCI_ID_CONEXANT 0x14f1
99 99
100 /* ======================================================================== */ 100 /* ======================================================================== */
101 /* ========================== START USER SETTABLE DMA VARIABLES =========== */ 101 /* ========================== START USER SETTABLE DMA VARIABLES =========== */
102 /* ======================================================================== */ 102 /* ======================================================================== */
103 103
104 /* DMA Buffers, Default size in MB allocated */ 104 /* DMA Buffers, Default size in MB allocated */
105 #define CX18_DEFAULT_ENC_TS_BUFFERS 1 105 #define CX18_DEFAULT_ENC_TS_BUFFERS 1
106 #define CX18_DEFAULT_ENC_MPG_BUFFERS 2 106 #define CX18_DEFAULT_ENC_MPG_BUFFERS 2
107 #define CX18_DEFAULT_ENC_IDX_BUFFERS 1 107 #define CX18_DEFAULT_ENC_IDX_BUFFERS 1
108 #define CX18_DEFAULT_ENC_YUV_BUFFERS 2 108 #define CX18_DEFAULT_ENC_YUV_BUFFERS 2
109 #define CX18_DEFAULT_ENC_VBI_BUFFERS 1 109 #define CX18_DEFAULT_ENC_VBI_BUFFERS 1
110 #define CX18_DEFAULT_ENC_PCM_BUFFERS 1 110 #define CX18_DEFAULT_ENC_PCM_BUFFERS 1
111 111
112 /* i2c stuff */ 112 /* i2c stuff */
113 #define I2C_CLIENTS_MAX 16 113 #define I2C_CLIENTS_MAX 16
114 114
115 /* debugging */ 115 /* debugging */
116 116
117 /* Flag to turn on high volume debugging */ 117 /* Flag to turn on high volume debugging */
118 #define CX18_DBGFLG_WARN (1 << 0) 118 #define CX18_DBGFLG_WARN (1 << 0)
119 #define CX18_DBGFLG_INFO (1 << 1) 119 #define CX18_DBGFLG_INFO (1 << 1)
120 #define CX18_DBGFLG_API (1 << 2) 120 #define CX18_DBGFLG_API (1 << 2)
121 #define CX18_DBGFLG_DMA (1 << 3) 121 #define CX18_DBGFLG_DMA (1 << 3)
122 #define CX18_DBGFLG_IOCTL (1 << 4) 122 #define CX18_DBGFLG_IOCTL (1 << 4)
123 #define CX18_DBGFLG_FILE (1 << 5) 123 #define CX18_DBGFLG_FILE (1 << 5)
124 #define CX18_DBGFLG_I2C (1 << 6) 124 #define CX18_DBGFLG_I2C (1 << 6)
125 #define CX18_DBGFLG_IRQ (1 << 7) 125 #define CX18_DBGFLG_IRQ (1 << 7)
126 /* Flag to turn on high volume debugging */ 126 /* Flag to turn on high volume debugging */
127 #define CX18_DBGFLG_HIGHVOL (1 << 8) 127 #define CX18_DBGFLG_HIGHVOL (1 << 8)
128 128
129 /* NOTE: extra space before comma in 'cx->num , ## args' is required for 129 /* NOTE: extra space before comma in 'cx->num , ## args' is required for
130 gcc-2.95, otherwise it won't compile. */ 130 gcc-2.95, otherwise it won't compile. */
131 #define CX18_DEBUG(x, type, fmt, args...) \ 131 #define CX18_DEBUG(x, type, fmt, args...) \
132 do { \ 132 do { \
133 if ((x) & cx18_debug) \ 133 if ((x) & cx18_debug) \
134 printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \ 134 printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \
135 } while (0) 135 } while (0)
136 #define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args) 136 #define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
137 #define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args) 137 #define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
138 #define CX18_DEBUG_API(fmt, args...) CX18_DEBUG(CX18_DBGFLG_API, "api", fmt , ## args) 138 #define CX18_DEBUG_API(fmt, args...) CX18_DEBUG(CX18_DBGFLG_API, "api", fmt , ## args)
139 #define CX18_DEBUG_DMA(fmt, args...) CX18_DEBUG(CX18_DBGFLG_DMA, "dma", fmt , ## args) 139 #define CX18_DEBUG_DMA(fmt, args...) CX18_DEBUG(CX18_DBGFLG_DMA, "dma", fmt , ## args)
140 #define CX18_DEBUG_IOCTL(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args) 140 #define CX18_DEBUG_IOCTL(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
141 #define CX18_DEBUG_FILE(fmt, args...) CX18_DEBUG(CX18_DBGFLG_FILE, "file", fmt , ## args) 141 #define CX18_DEBUG_FILE(fmt, args...) CX18_DEBUG(CX18_DBGFLG_FILE, "file", fmt , ## args)
142 #define CX18_DEBUG_I2C(fmt, args...) CX18_DEBUG(CX18_DBGFLG_I2C, "i2c", fmt , ## args) 142 #define CX18_DEBUG_I2C(fmt, args...) CX18_DEBUG(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
143 #define CX18_DEBUG_IRQ(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IRQ, "irq", fmt , ## args) 143 #define CX18_DEBUG_IRQ(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
144 144
145 #define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \ 145 #define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
146 do { \ 146 do { \
147 if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \ 147 if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
148 printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \ 148 printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \
149 } while (0) 149 } while (0)
150 #define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args) 150 #define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
151 #define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args) 151 #define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
152 #define CX18_DEBUG_HI_API(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_API, "api", fmt , ## args) 152 #define CX18_DEBUG_HI_API(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_API, "api", fmt , ## args)
153 #define CX18_DEBUG_HI_DMA(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_DMA, "dma", fmt , ## args) 153 #define CX18_DEBUG_HI_DMA(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_DMA, "dma", fmt , ## args)
154 #define CX18_DEBUG_HI_IOCTL(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args) 154 #define CX18_DEBUG_HI_IOCTL(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
155 #define CX18_DEBUG_HI_FILE(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_FILE, "file", fmt , ## args) 155 #define CX18_DEBUG_HI_FILE(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_FILE, "file", fmt , ## args)
156 #define CX18_DEBUG_HI_I2C(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_I2C, "i2c", fmt , ## args) 156 #define CX18_DEBUG_HI_I2C(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
157 #define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args) 157 #define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
158 158
159 /* Standard kernel messages */ 159 /* Standard kernel messages */
160 #define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args) 160 #define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args)
161 #define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args) 161 #define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args)
162 #define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args) 162 #define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args)
163 163
164 /* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */ 164 /* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
165 #define MPEG_FRAME_TYPE_IFRAME 1 165 #define MPEG_FRAME_TYPE_IFRAME 1
166 #define MPEG_FRAME_TYPE_IFRAME_PFRAME 3 166 #define MPEG_FRAME_TYPE_IFRAME_PFRAME 3
167 #define MPEG_FRAME_TYPE_ALL 7 167 #define MPEG_FRAME_TYPE_ALL 7
168 168
169 #define CX18_MAX_PGM_INDEX (400) 169 #define CX18_MAX_PGM_INDEX (400)
170 170
171 extern int cx18_debug; 171 extern int cx18_debug;
172 172
173 173
174 struct cx18_options { 174 struct cx18_options {
175 int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */ 175 int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */
176 int cardtype; /* force card type on load */ 176 int cardtype; /* force card type on load */
177 int tuner; /* set tuner on load */ 177 int tuner; /* set tuner on load */
178 int radio; /* enable/disable radio */ 178 int radio; /* enable/disable radio */
179 }; 179 };
180 180
181 /* per-buffer bit flags */ 181 /* per-buffer bit flags */
182 #define CX18_F_B_NEED_BUF_SWAP 0 /* this buffer should be byte swapped */ 182 #define CX18_F_B_NEED_BUF_SWAP 0 /* this buffer should be byte swapped */
183 183
184 /* per-stream, s_flags */ 184 /* per-stream, s_flags */
185 #define CX18_F_S_CLAIMED 3 /* this stream is claimed */ 185 #define CX18_F_S_CLAIMED 3 /* this stream is claimed */
186 #define CX18_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */ 186 #define CX18_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
187 #define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ 187 #define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
188 #define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */ 188 #define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */
189 #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ 189 #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */
190 190
191 /* per-cx18, i_flags */ 191 /* per-cx18, i_flags */
192 #define CX18_F_I_LOADED_FW 0 /* Loaded the firmware the first time */ 192 #define CX18_F_I_LOADED_FW 0 /* Loaded the firmware the first time */
193 #define CX18_F_I_EOS 4 /* End of encoder stream reached */ 193 #define CX18_F_I_EOS 4 /* End of encoder stream reached */
194 #define CX18_F_I_RADIO_USER 5 /* The radio tuner is selected */ 194 #define CX18_F_I_RADIO_USER 5 /* The radio tuner is selected */
195 #define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */ 195 #define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */
196 #define CX18_F_I_INITED 21 /* set after first open */ 196 #define CX18_F_I_INITED 21 /* set after first open */
197 #define CX18_F_I_FAILED 22 /* set if first open failed */ 197 #define CX18_F_I_FAILED 22 /* set if first open failed */
198 198
199 /* These are the VBI types as they appear in the embedded VBI private packets. */ 199 /* These are the VBI types as they appear in the embedded VBI private packets. */
200 #define CX18_SLICED_TYPE_TELETEXT_B (1) 200 #define CX18_SLICED_TYPE_TELETEXT_B (1)
201 #define CX18_SLICED_TYPE_CAPTION_525 (4) 201 #define CX18_SLICED_TYPE_CAPTION_525 (4)
202 #define CX18_SLICED_TYPE_WSS_625 (5) 202 #define CX18_SLICED_TYPE_WSS_625 (5)
203 #define CX18_SLICED_TYPE_VPS (7) 203 #define CX18_SLICED_TYPE_VPS (7)
204 204
205 struct cx18_buffer { 205 struct cx18_buffer {
206 struct list_head list; 206 struct list_head list;
207 dma_addr_t dma_handle; 207 dma_addr_t dma_handle;
208 u32 id; 208 u32 id;
209 unsigned long b_flags; 209 unsigned long b_flags;
210 char *buf; 210 char *buf;
211 211
212 u32 bytesused; 212 u32 bytesused;
213 u32 readpos; 213 u32 readpos;
214 }; 214 };
215 215
216 struct cx18_queue { 216 struct cx18_queue {
217 struct list_head list; 217 struct list_head list;
218 atomic_t buffers; 218 atomic_t buffers;
219 u32 bytesused; 219 u32 bytesused;
220 }; 220 };
221 221
222 struct cx18_dvb { 222 struct cx18_dvb {
223 struct dmx_frontend hw_frontend; 223 struct dmx_frontend hw_frontend;
224 struct dmx_frontend mem_frontend; 224 struct dmx_frontend mem_frontend;
225 struct dmxdev dmxdev; 225 struct dmxdev dmxdev;
226 struct dvb_adapter dvb_adapter; 226 struct dvb_adapter dvb_adapter;
227 struct dvb_demux demux; 227 struct dvb_demux demux;
228 struct dvb_frontend *fe; 228 struct dvb_frontend *fe;
229 struct dvb_net dvbnet; 229 struct dvb_net dvbnet;
230 int enabled; 230 int enabled;
231 int feeding; 231 int feeding;
232 struct mutex feedlock; 232 struct mutex feedlock;
233 }; 233 };
234 234
235 struct cx18; /* forward reference */ 235 struct cx18; /* forward reference */
236 struct cx18_scb; /* forward reference */ 236 struct cx18_scb; /* forward reference */
237 237
238 #define CX18_INVALID_TASK_HANDLE 0xffffffff 238 #define CX18_INVALID_TASK_HANDLE 0xffffffff
239 239
240 struct cx18_stream { 240 struct cx18_stream {
241 /* These first four fields are always set, even if the stream 241 /* These first four fields are always set, even if the stream
242 is not actually created. */ 242 is not actually created. */
243 struct video_device *v4l2dev; /* NULL when stream not created */ 243 struct video_device *v4l2dev; /* NULL when stream not created */
244 struct cx18 *cx; /* for ease of use */ 244 struct cx18 *cx; /* for ease of use */
245 const char *name; /* name of the stream */ 245 const char *name; /* name of the stream */
246 int type; /* stream type */ 246 int type; /* stream type */
247 u32 handle; /* task handle */ 247 u32 handle; /* task handle */
248 unsigned mdl_offset; 248 unsigned mdl_offset;
249 249
250 u32 id; 250 u32 id;
251 spinlock_t qlock; /* locks access to the queues */ 251 spinlock_t qlock; /* locks access to the queues */
252 unsigned long s_flags; /* status flags, see above */ 252 unsigned long s_flags; /* status flags, see above */
253 int dma; /* can be PCI_DMA_TODEVICE, 253 int dma; /* can be PCI_DMA_TODEVICE,
254 PCI_DMA_FROMDEVICE or 254 PCI_DMA_FROMDEVICE or
255 PCI_DMA_NONE */ 255 PCI_DMA_NONE */
256 u64 dma_pts; 256 u64 dma_pts;
257 wait_queue_head_t waitq; 257 wait_queue_head_t waitq;
258 258
259 /* Buffer Stats */ 259 /* Buffer Stats */
260 u32 buffers; 260 u32 buffers;
261 u32 buf_size; 261 u32 buf_size;
262 262
263 /* Buffer Queues */ 263 /* Buffer Queues */
264 struct cx18_queue q_free; /* free buffers */ 264 struct cx18_queue q_free; /* free buffers */
265 struct cx18_queue q_full; /* full buffers */ 265 struct cx18_queue q_full; /* full buffers */
266 struct cx18_queue q_io; /* waiting for I/O */ 266 struct cx18_queue q_io; /* waiting for I/O */
267 267
268 /* DVB / Digital Transport */ 268 /* DVB / Digital Transport */
269 struct cx18_dvb dvb; 269 struct cx18_dvb dvb;
270 }; 270 };
271 271
272 struct cx18_open_id { 272 struct cx18_open_id {
273 u32 open_id; 273 u32 open_id;
274 int type; 274 int type;
275 enum v4l2_priority prio; 275 enum v4l2_priority prio;
276 struct cx18 *cx; 276 struct cx18 *cx;
277 }; 277 };
278 278
279 /* forward declaration of struct defined in cx18-cards.h */ 279 /* forward declaration of struct defined in cx18-cards.h */
280 struct cx18_card; 280 struct cx18_card;
281 281
282 282
283 #define CX18_VBI_FRAMES 32 283 #define CX18_VBI_FRAMES 32
284 284
285 /* VBI data */ 285 /* VBI data */
286 struct vbi_info { 286 struct vbi_info {
287 u32 enc_size; 287 u32 enc_size;
288 u32 frame; 288 u32 frame;
289 u8 cc_data_odd[256]; 289 u8 cc_data_odd[256];
290 u8 cc_data_even[256]; 290 u8 cc_data_even[256];
291 int cc_pos; 291 int cc_pos;
292 u8 cc_no_update; 292 u8 cc_no_update;
293 u8 vps[5]; 293 u8 vps[5];
294 u8 vps_found; 294 u8 vps_found;
295 int wss; 295 int wss;
296 u8 wss_found; 296 u8 wss_found;
297 u8 wss_no_update; 297 u8 wss_no_update;
298 u32 raw_decoder_line_size; 298 u32 raw_decoder_line_size;
299 u8 raw_decoder_sav_odd_field; 299 u8 raw_decoder_sav_odd_field;
300 u8 raw_decoder_sav_even_field; 300 u8 raw_decoder_sav_even_field;
301 u32 sliced_decoder_line_size; 301 u32 sliced_decoder_line_size;
302 u8 sliced_decoder_sav_odd_field; 302 u8 sliced_decoder_sav_odd_field;
303 u8 sliced_decoder_sav_even_field; 303 u8 sliced_decoder_sav_even_field;
304 struct v4l2_format in; 304 struct v4l2_format in;
305 /* convenience pointer to sliced struct in vbi_in union */ 305 /* convenience pointer to sliced struct in vbi_in union */
306 struct v4l2_sliced_vbi_format *sliced_in; 306 struct v4l2_sliced_vbi_format *sliced_in;
307 u32 service_set_in; 307 u32 service_set_in;
308 int insert_mpeg; 308 int insert_mpeg;
309 309
310 /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines. 310 /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
311 One for /dev/vbi0 and one for /dev/vbi8 */ 311 One for /dev/vbi0 and one for /dev/vbi8 */
312 struct v4l2_sliced_vbi_data sliced_data[36]; 312 struct v4l2_sliced_vbi_data sliced_data[36];
313 313
314 /* Buffer for VBI data inserted into MPEG stream. 314 /* Buffer for VBI data inserted into MPEG stream.
315 The first byte is a dummy byte that's never used. 315 The first byte is a dummy byte that's never used.
316 The next 16 bytes contain the MPEG header for the VBI data, 316 The next 16 bytes contain the MPEG header for the VBI data,
317 the remainder is the actual VBI data. 317 the remainder is the actual VBI data.
318 The max size accepted by the MPEG VBI reinsertion turns out 318 The max size accepted by the MPEG VBI reinsertion turns out
319 to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes, 319 to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes,
320 where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is 320 where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is
321 a single line header byte and 2 * 18 is the number of VBI lines per frame. 321 a single line header byte and 2 * 18 is the number of VBI lines per frame.
322 322
323 However, it seems that the data must be 1K aligned, so we have to 323 However, it seems that the data must be 1K aligned, so we have to
324 pad the data until the 1 or 2 K boundary. 324 pad the data until the 1 or 2 K boundary.
325 325
326 This pointer array will allocate 2049 bytes to store each VBI frame. */ 326 This pointer array will allocate 2049 bytes to store each VBI frame. */
327 u8 *sliced_mpeg_data[CX18_VBI_FRAMES]; 327 u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
328 u32 sliced_mpeg_size[CX18_VBI_FRAMES]; 328 u32 sliced_mpeg_size[CX18_VBI_FRAMES];
329 struct cx18_buffer sliced_mpeg_buf; 329 struct cx18_buffer sliced_mpeg_buf;
330 u32 inserted_frame; 330 u32 inserted_frame;
331 331
332 u32 start[2], count; 332 u32 start[2], count;
333 u32 raw_size; 333 u32 raw_size;
334 u32 sliced_size; 334 u32 sliced_size;
335 }; 335 };
336 336
337 /* Per cx23418, per I2C bus private algo callback data */ 337 /* Per cx23418, per I2C bus private algo callback data */
338 struct cx18_i2c_algo_callback_data { 338 struct cx18_i2c_algo_callback_data {
339 struct cx18 *cx; 339 struct cx18 *cx;
340 int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */ 340 int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */
341 }; 341 };
342 342
343 /* Struct to hold info about cx18 cards */ 343 /* Struct to hold info about cx18 cards */
344 struct cx18 { 344 struct cx18 {
345 int num; /* board number, -1 during init! */ 345 int num; /* board number, -1 during init! */
346 char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */ 346 char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */
347 struct pci_dev *dev; /* PCI device */ 347 struct pci_dev *dev; /* PCI device */
348 const struct cx18_card *card; /* card information */ 348 const struct cx18_card *card; /* card information */
349 const char *card_name; /* full name of the card */ 349 const char *card_name; /* full name of the card */
350 const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */ 350 const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
351 u8 is_50hz; 351 u8 is_50hz;
352 u8 is_60hz; 352 u8 is_60hz;
353 u8 is_out_50hz; 353 u8 is_out_50hz;
354 u8 is_out_60hz; 354 u8 is_out_60hz;
355 u8 nof_inputs; /* number of video inputs */ 355 u8 nof_inputs; /* number of video inputs */
356 u8 nof_audio_inputs; /* number of audio inputs */ 356 u8 nof_audio_inputs; /* number of audio inputs */
357 u16 buffer_id; /* buffer ID counter */ 357 u16 buffer_id; /* buffer ID counter */
358 u32 v4l2_cap; /* V4L2 capabilities of card */ 358 u32 v4l2_cap; /* V4L2 capabilities of card */
359 u32 hw_flags; /* Hardware description of the board */ 359 u32 hw_flags; /* Hardware description of the board */
360 unsigned mdl_offset; 360 unsigned mdl_offset;
361 struct cx18_scb __iomem *scb; /* pointer to SCB */ 361 struct cx18_scb __iomem *scb; /* pointer to SCB */
362 362
363 struct cx18_av_state av_state; 363 struct cx18_av_state av_state;
364 364
365 /* codec settings */ 365 /* codec settings */
366 struct cx2341x_mpeg_params params; 366 struct cx2341x_mpeg_params params;
367 u32 filter_mode; 367 u32 filter_mode;
368 u32 temporal_strength; 368 u32 temporal_strength;
369 u32 spatial_strength; 369 u32 spatial_strength;
370 370
371 /* dualwatch */ 371 /* dualwatch */
372 unsigned long dualwatch_jiffies; 372 unsigned long dualwatch_jiffies;
373 u16 dualwatch_stereo_mode; 373 u16 dualwatch_stereo_mode;
374 374
375 /* Digitizer type */ 375 /* Digitizer type */
376 int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */ 376 int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */
377 377
378 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */ 378 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
379 struct cx18_options options; /* User options */ 379 struct cx18_options options; /* User options */
380 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ 380 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
381 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ 381 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
382 unsigned long i_flags; /* global cx18 flags */ 382 unsigned long i_flags; /* global cx18 flags */
383 atomic_t ana_capturing; /* count number of active analog capture streams */ 383 atomic_t ana_capturing; /* count number of active analog capture streams */
384 atomic_t tot_capturing; /* total count number of active capture streams */ 384 atomic_t tot_capturing; /* total count number of active capture streams */
385 spinlock_t lock; /* lock access to this struct */ 385 spinlock_t lock; /* lock access to this struct */
386 int search_pack_header; 386 int search_pack_header;
387 387
388 spinlock_t dma_reg_lock; /* lock access to DMA engine registers */ 388 spinlock_t dma_reg_lock; /* lock access to DMA engine registers */
389 389
390 int open_id; /* incremented each time an open occurs, used as 390 int open_id; /* incremented each time an open occurs, used as
391 unique ID. Starts at 1, so 0 can be used as 391 unique ID. Starts at 1, so 0 can be used as
392 uninitialized value in the stream->id. */ 392 uninitialized value in the stream->id. */
393 393
394 u32 base_addr; 394 u32 base_addr;
395 struct v4l2_prio_state prio; 395 struct v4l2_prio_state prio;
396 396
397 u8 card_rev; 397 u8 card_rev;
398 void __iomem *enc_mem, *reg_mem; 398 void __iomem *enc_mem, *reg_mem;
399 399
400 struct vbi_info vbi; 400 struct vbi_info vbi;
401 401
402 u32 pgm_info_offset; 402 u32 pgm_info_offset;
403 u32 pgm_info_num; 403 u32 pgm_info_num;
404 u32 pgm_info_write_idx; 404 u32 pgm_info_write_idx;
405 u32 pgm_info_read_idx; 405 u32 pgm_info_read_idx;
406 struct v4l2_enc_idx_entry pgm_info[CX18_MAX_PGM_INDEX]; 406 struct v4l2_enc_idx_entry pgm_info[CX18_MAX_PGM_INDEX];
407 407
408 u64 mpg_data_received; 408 u64 mpg_data_received;
409 u64 vbi_data_inserted; 409 u64 vbi_data_inserted;
410 410
411 wait_queue_head_t mb_apu_waitq; 411 wait_queue_head_t mb_apu_waitq;
412 wait_queue_head_t mb_cpu_waitq; 412 wait_queue_head_t mb_cpu_waitq;
413 wait_queue_head_t mb_epu_waitq; 413 wait_queue_head_t mb_epu_waitq;
414 wait_queue_head_t mb_hpu_waitq; 414 wait_queue_head_t mb_hpu_waitq;
415 wait_queue_head_t cap_w; 415 wait_queue_head_t cap_w;
416 /* when the current DMA is finished this queue is woken up */ 416 /* when the current DMA is finished this queue is woken up */
417 wait_queue_head_t dma_waitq; 417 wait_queue_head_t dma_waitq;
418 418
419 /* i2c */ 419 /* i2c */
420 struct i2c_adapter i2c_adap[2]; 420 struct i2c_adapter i2c_adap[2];
421 struct i2c_algo_bit_data i2c_algo[2]; 421 struct i2c_algo_bit_data i2c_algo[2];
422 struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2]; 422 struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
423 struct i2c_client i2c_client[2]; 423 struct i2c_client i2c_client[2];
424 struct mutex i2c_bus_lock[2]; 424 struct mutex i2c_bus_lock[2];
425 struct i2c_client *i2c_clients[I2C_CLIENTS_MAX]; 425 struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
426 426
427 /* gpio */ 427 /* gpio */
428 u32 gpio_dir; 428 u32 gpio_dir;
429 u32 gpio_val; 429 u32 gpio_val;
430 struct mutex gpio_lock; 430 struct mutex gpio_lock;
431 431
432 /* v4l2 and User settings */ 432 /* v4l2 and User settings */
433 433
434 /* codec settings */ 434 /* codec settings */
435 u32 audio_input; 435 u32 audio_input;
436 u32 active_input; 436 u32 active_input;
437 u32 active_output; 437 u32 active_output;
438 v4l2_std_id std; 438 v4l2_std_id std;
439 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */ 439 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
440 }; 440 };
441 441
442 /* Globals */ 442 /* Globals */
443 extern struct cx18 *cx18_cards[]; 443 extern struct cx18 *cx18_cards[];
444 extern int cx18_cards_active; 444 extern int cx18_cards_active;
445 extern int cx18_first_minor; 445 extern int cx18_first_minor;
446 extern spinlock_t cx18_cards_lock; 446 extern spinlock_t cx18_cards_lock;
447 447
448 /*==============Prototypes==================*/ 448 /*==============Prototypes==================*/
449 449
450 /* Return non-zero if a signal is pending */ 450 /* Return non-zero if a signal is pending */
451 int cx18_msleep_timeout(unsigned int msecs, int intr); 451 int cx18_msleep_timeout(unsigned int msecs, int intr);
452 452
453 /* Read Hauppauge eeprom */ 453 /* Read Hauppauge eeprom */
454 struct tveeprom; /* forward reference */ 454 struct tveeprom; /* forward reference */
455 void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv); 455 void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
456 456
457 /* First-open initialization: load firmware, etc. */ 457 /* First-open initialization: load firmware, etc. */
458 int cx18_init_on_first_open(struct cx18 *cx); 458 int cx18_init_on_first_open(struct cx18 *cx);
459 459
460 /* This is a PCI post thing, where if the pci register is not read, then
461 the write doesn't always take effect right away. By reading back the
462 register any pending PCI writes will be performed (in order), and so
463 you can be sure that the writes are guaranteed to be done.
464
465 Rarely needed, only in some timing sensitive cases.
466 Apparently if this is not done some motherboards seem
467 to kill the firmware and get into the broken state until computer is
468 rebooted. */
469 #define write_sync(val, reg) \
470 do { writel(val, reg); readl(reg); } while (0)
471
472 #define read_reg(reg) readl(cx->reg_mem + (reg))
473 #define write_reg(val, reg) writel(val, cx->reg_mem + (reg))
474 #define write_reg_sync(val, reg) \
475 do { write_reg(val, reg); read_reg(reg); } while (0)
476
477 #define read_enc(addr) readl(cx->enc_mem + (u32)(addr))
478 #define write_enc(val, addr) writel(val, cx->enc_mem + (u32)(addr))
479 #define write_enc_sync(val, addr) \
480 do { write_enc(val, addr); read_enc(addr); } while (0)
481
482 #define sw1_irq_enable(val) do { \
483 write_reg(val, SW1_INT_STATUS); \
484 write_reg(read_reg(SW1_INT_ENABLE_PCI) | (val), SW1_INT_ENABLE_PCI); \
485 } while (0)
486
487 #define sw1_irq_disable(val) \
488 write_reg(read_reg(SW1_INT_ENABLE_PCI) & ~(val), SW1_INT_ENABLE_PCI);
489
490 #define sw2_irq_enable(val) do { \
491 write_reg(val, SW2_INT_STATUS); \
492 write_reg(read_reg(SW2_INT_ENABLE_PCI) | (val), SW2_INT_ENABLE_PCI); \
493 } while (0)
494
495 #define sw2_irq_disable(val) \
496 write_reg(read_reg(SW2_INT_ENABLE_PCI) & ~(val), SW2_INT_ENABLE_PCI);
497
498 #define setup_page(addr) do { \
499 u32 val = read_reg(0xD000F8) & ~0x1f00; \
500 write_reg(val | (((addr) >> 17) & 0x1f00), 0xD000F8); \
501 } while (0)
502
503 #endif /* CX18_DRIVER_H */ 460 #endif /* CX18_DRIVER_H */
504 461
drivers/media/video/cx18/cx18-dvb.c
1 /* 1 /*
2 * cx18 functions for DVB support 2 * cx18 functions for DVB support
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 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 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 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * 14 *
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 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 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */ 20 */
21 21
22 #include "cx18-version.h" 22 #include "cx18-version.h"
23 #include "cx18-dvb.h" 23 #include "cx18-dvb.h"
24 #include "cx18-io.h"
24 #include "cx18-streams.h" 25 #include "cx18-streams.h"
25 #include "cx18-cards.h" 26 #include "cx18-cards.h"
26 #include "s5h1409.h" 27 #include "s5h1409.h"
27 #include "mxl5005s.h" 28 #include "mxl5005s.h"
28 29
29 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 30 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
30 31
31 #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000 32 #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
32 33
33 static struct mxl5005s_config hauppauge_hvr1600_tuner = { 34 static struct mxl5005s_config hauppauge_hvr1600_tuner = {
34 .i2c_address = 0xC6 >> 1, 35 .i2c_address = 0xC6 >> 1,
35 .if_freq = IF_FREQ_5380000HZ, 36 .if_freq = IF_FREQ_5380000HZ,
36 .xtal_freq = CRYSTAL_FREQ_16000000HZ, 37 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
37 .agc_mode = MXL_SINGLE_AGC, 38 .agc_mode = MXL_SINGLE_AGC,
38 .tracking_filter = MXL_TF_C_H, 39 .tracking_filter = MXL_TF_C_H,
39 .rssi_enable = MXL_RSSI_ENABLE, 40 .rssi_enable = MXL_RSSI_ENABLE,
40 .cap_select = MXL_CAP_SEL_ENABLE, 41 .cap_select = MXL_CAP_SEL_ENABLE,
41 .div_out = MXL_DIV_OUT_4, 42 .div_out = MXL_DIV_OUT_4,
42 .clock_out = MXL_CLOCK_OUT_DISABLE, 43 .clock_out = MXL_CLOCK_OUT_DISABLE,
43 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, 44 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
44 .top = MXL5005S_TOP_25P2, 45 .top = MXL5005S_TOP_25P2,
45 .mod_mode = MXL_DIGITAL_MODE, 46 .mod_mode = MXL_DIGITAL_MODE,
46 .if_mode = MXL_ZERO_IF, 47 .if_mode = MXL_ZERO_IF,
47 .AgcMasterByte = 0x00, 48 .AgcMasterByte = 0x00,
48 }; 49 };
49 50
50 static struct s5h1409_config hauppauge_hvr1600_config = { 51 static struct s5h1409_config hauppauge_hvr1600_config = {
51 .demod_address = 0x32 >> 1, 52 .demod_address = 0x32 >> 1,
52 .output_mode = S5H1409_SERIAL_OUTPUT, 53 .output_mode = S5H1409_SERIAL_OUTPUT,
53 .gpio = S5H1409_GPIO_ON, 54 .gpio = S5H1409_GPIO_ON,
54 .qam_if = 44000, 55 .qam_if = 44000,
55 .inversion = S5H1409_INVERSION_OFF, 56 .inversion = S5H1409_INVERSION_OFF,
56 .status_mode = S5H1409_DEMODLOCKING, 57 .status_mode = S5H1409_DEMODLOCKING,
57 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 58 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
58 59
59 }; 60 };
60 61
61 static int dvb_register(struct cx18_stream *stream); 62 static int dvb_register(struct cx18_stream *stream);
62 63
63 /* Kernel DVB framework calls this when the feed needs to start. 64 /* Kernel DVB framework calls this when the feed needs to start.
64 * The CX18 framework should enable the transport DMA handling 65 * The CX18 framework should enable the transport DMA handling
65 * and queue processing. 66 * and queue processing.
66 */ 67 */
67 static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) 68 static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
68 { 69 {
69 struct dvb_demux *demux = feed->demux; 70 struct dvb_demux *demux = feed->demux;
70 struct cx18_stream *stream = (struct cx18_stream *) demux->priv; 71 struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
71 struct cx18 *cx = stream->cx; 72 struct cx18 *cx = stream->cx;
72 int ret; 73 int ret;
73 u32 v; 74 u32 v;
74 75
75 CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n", 76 CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
76 feed->pid, feed->index); 77 feed->pid, feed->index);
77 78
78 mutex_lock(&cx->serialize_lock); 79 mutex_lock(&cx->serialize_lock);
79 ret = cx18_init_on_first_open(cx); 80 ret = cx18_init_on_first_open(cx);
80 mutex_unlock(&cx->serialize_lock); 81 mutex_unlock(&cx->serialize_lock);
81 if (ret) { 82 if (ret) {
82 CX18_ERR("Failed to initialize firmware starting DVB feed\n"); 83 CX18_ERR("Failed to initialize firmware starting DVB feed\n");
83 return ret; 84 return ret;
84 } 85 }
85 ret = -EINVAL; 86 ret = -EINVAL;
86 87
87 switch (cx->card->type) { 88 switch (cx->card->type) {
88 case CX18_CARD_HVR_1600_ESMT: 89 case CX18_CARD_HVR_1600_ESMT:
89 case CX18_CARD_HVR_1600_SAMSUNG: 90 case CX18_CARD_HVR_1600_SAMSUNG:
90 v = read_reg(CX18_REG_DMUX_NUM_PORT_0_CONTROL); 91 v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
91 v |= 0x00400000; /* Serial Mode */ 92 v |= 0x00400000; /* Serial Mode */
92 v |= 0x00002000; /* Data Length - Byte */ 93 v |= 0x00002000; /* Data Length - Byte */
93 v |= 0x00010000; /* Error - Polarity */ 94 v |= 0x00010000; /* Error - Polarity */
94 v |= 0x00020000; /* Error - Passthru */ 95 v |= 0x00020000; /* Error - Passthru */
95 v |= 0x000c0000; /* Error - Ignore */ 96 v |= 0x000c0000; /* Error - Ignore */
96 write_reg(v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); 97 cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
97 break; 98 break;
98 99
99 default: 100 default:
100 /* Assumption - Parallel transport - Signalling 101 /* Assumption - Parallel transport - Signalling
101 * undefined or default. 102 * undefined or default.
102 */ 103 */
103 break; 104 break;
104 } 105 }
105 106
106 if (!demux->dmx.frontend) 107 if (!demux->dmx.frontend)
107 return -EINVAL; 108 return -EINVAL;
108 109
109 if (stream) { 110 if (stream) {
110 mutex_lock(&stream->dvb.feedlock); 111 mutex_lock(&stream->dvb.feedlock);
111 if (stream->dvb.feeding++ == 0) { 112 if (stream->dvb.feeding++ == 0) {
112 CX18_DEBUG_INFO("Starting Transport DMA\n"); 113 CX18_DEBUG_INFO("Starting Transport DMA\n");
113 ret = cx18_start_v4l2_encode_stream(stream); 114 ret = cx18_start_v4l2_encode_stream(stream);
114 if (ret < 0) { 115 if (ret < 0) {
115 CX18_DEBUG_INFO( 116 CX18_DEBUG_INFO(
116 "Failed to start Transport DMA\n"); 117 "Failed to start Transport DMA\n");
117 stream->dvb.feeding--; 118 stream->dvb.feeding--;
118 } 119 }
119 } else 120 } else
120 ret = 0; 121 ret = 0;
121 mutex_unlock(&stream->dvb.feedlock); 122 mutex_unlock(&stream->dvb.feedlock);
122 } 123 }
123 124
124 return ret; 125 return ret;
125 } 126 }
126 127
127 /* Kernel DVB framework calls this when the feed needs to stop. */ 128 /* Kernel DVB framework calls this when the feed needs to stop. */
128 static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed) 129 static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
129 { 130 {
130 struct dvb_demux *demux = feed->demux; 131 struct dvb_demux *demux = feed->demux;
131 struct cx18_stream *stream = (struct cx18_stream *)demux->priv; 132 struct cx18_stream *stream = (struct cx18_stream *)demux->priv;
132 struct cx18 *cx = stream->cx; 133 struct cx18 *cx = stream->cx;
133 int ret = -EINVAL; 134 int ret = -EINVAL;
134 135
135 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n", 136 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
136 feed->pid, feed->index); 137 feed->pid, feed->index);
137 138
138 if (stream) { 139 if (stream) {
139 mutex_lock(&stream->dvb.feedlock); 140 mutex_lock(&stream->dvb.feedlock);
140 if (--stream->dvb.feeding == 0) { 141 if (--stream->dvb.feeding == 0) {
141 CX18_DEBUG_INFO("Stopping Transport DMA\n"); 142 CX18_DEBUG_INFO("Stopping Transport DMA\n");
142 ret = cx18_stop_v4l2_encode_stream(stream, 0); 143 ret = cx18_stop_v4l2_encode_stream(stream, 0);
143 } else 144 } else
144 ret = 0; 145 ret = 0;
145 mutex_unlock(&stream->dvb.feedlock); 146 mutex_unlock(&stream->dvb.feedlock);
146 } 147 }
147 148
148 return ret; 149 return ret;
149 } 150 }
150 151
151 int cx18_dvb_register(struct cx18_stream *stream) 152 int cx18_dvb_register(struct cx18_stream *stream)
152 { 153 {
153 struct cx18 *cx = stream->cx; 154 struct cx18 *cx = stream->cx;
154 struct cx18_dvb *dvb = &stream->dvb; 155 struct cx18_dvb *dvb = &stream->dvb;
155 struct dvb_adapter *dvb_adapter; 156 struct dvb_adapter *dvb_adapter;
156 struct dvb_demux *dvbdemux; 157 struct dvb_demux *dvbdemux;
157 struct dmx_demux *dmx; 158 struct dmx_demux *dmx;
158 int ret; 159 int ret;
159 160
160 if (!dvb) 161 if (!dvb)
161 return -EINVAL; 162 return -EINVAL;
162 163
163 ret = dvb_register_adapter(&dvb->dvb_adapter, 164 ret = dvb_register_adapter(&dvb->dvb_adapter,
164 CX18_DRIVER_NAME, 165 CX18_DRIVER_NAME,
165 THIS_MODULE, &cx->dev->dev, adapter_nr); 166 THIS_MODULE, &cx->dev->dev, adapter_nr);
166 if (ret < 0) 167 if (ret < 0)
167 goto err_out; 168 goto err_out;
168 169
169 dvb_adapter = &dvb->dvb_adapter; 170 dvb_adapter = &dvb->dvb_adapter;
170 171
171 dvbdemux = &dvb->demux; 172 dvbdemux = &dvb->demux;
172 173
173 dvbdemux->priv = (void *)stream; 174 dvbdemux->priv = (void *)stream;
174 175
175 dvbdemux->filternum = 256; 176 dvbdemux->filternum = 256;
176 dvbdemux->feednum = 256; 177 dvbdemux->feednum = 256;
177 dvbdemux->start_feed = cx18_dvb_start_feed; 178 dvbdemux->start_feed = cx18_dvb_start_feed;
178 dvbdemux->stop_feed = cx18_dvb_stop_feed; 179 dvbdemux->stop_feed = cx18_dvb_stop_feed;
179 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | 180 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
180 DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); 181 DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
181 ret = dvb_dmx_init(dvbdemux); 182 ret = dvb_dmx_init(dvbdemux);
182 if (ret < 0) 183 if (ret < 0)
183 goto err_dvb_unregister_adapter; 184 goto err_dvb_unregister_adapter;
184 185
185 dmx = &dvbdemux->dmx; 186 dmx = &dvbdemux->dmx;
186 187
187 dvb->hw_frontend.source = DMX_FRONTEND_0; 188 dvb->hw_frontend.source = DMX_FRONTEND_0;
188 dvb->mem_frontend.source = DMX_MEMORY_FE; 189 dvb->mem_frontend.source = DMX_MEMORY_FE;
189 dvb->dmxdev.filternum = 256; 190 dvb->dmxdev.filternum = 256;
190 dvb->dmxdev.demux = dmx; 191 dvb->dmxdev.demux = dmx;
191 192
192 ret = dvb_dmxdev_init(&dvb->dmxdev, dvb_adapter); 193 ret = dvb_dmxdev_init(&dvb->dmxdev, dvb_adapter);
193 if (ret < 0) 194 if (ret < 0)
194 goto err_dvb_dmx_release; 195 goto err_dvb_dmx_release;
195 196
196 ret = dmx->add_frontend(dmx, &dvb->hw_frontend); 197 ret = dmx->add_frontend(dmx, &dvb->hw_frontend);
197 if (ret < 0) 198 if (ret < 0)
198 goto err_dvb_dmxdev_release; 199 goto err_dvb_dmxdev_release;
199 200
200 ret = dmx->add_frontend(dmx, &dvb->mem_frontend); 201 ret = dmx->add_frontend(dmx, &dvb->mem_frontend);
201 if (ret < 0) 202 if (ret < 0)
202 goto err_remove_hw_frontend; 203 goto err_remove_hw_frontend;
203 204
204 ret = dmx->connect_frontend(dmx, &dvb->hw_frontend); 205 ret = dmx->connect_frontend(dmx, &dvb->hw_frontend);
205 if (ret < 0) 206 if (ret < 0)
206 goto err_remove_mem_frontend; 207 goto err_remove_mem_frontend;
207 208
208 ret = dvb_register(stream); 209 ret = dvb_register(stream);
209 if (ret < 0) 210 if (ret < 0)
210 goto err_disconnect_frontend; 211 goto err_disconnect_frontend;
211 212
212 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx); 213 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
213 214
214 CX18_INFO("DVB Frontend registered\n"); 215 CX18_INFO("DVB Frontend registered\n");
215 mutex_init(&dvb->feedlock); 216 mutex_init(&dvb->feedlock);
216 dvb->enabled = 1; 217 dvb->enabled = 1;
217 return ret; 218 return ret;
218 219
219 err_disconnect_frontend: 220 err_disconnect_frontend:
220 dmx->disconnect_frontend(dmx); 221 dmx->disconnect_frontend(dmx);
221 err_remove_mem_frontend: 222 err_remove_mem_frontend:
222 dmx->remove_frontend(dmx, &dvb->mem_frontend); 223 dmx->remove_frontend(dmx, &dvb->mem_frontend);
223 err_remove_hw_frontend: 224 err_remove_hw_frontend:
224 dmx->remove_frontend(dmx, &dvb->hw_frontend); 225 dmx->remove_frontend(dmx, &dvb->hw_frontend);
225 err_dvb_dmxdev_release: 226 err_dvb_dmxdev_release:
226 dvb_dmxdev_release(&dvb->dmxdev); 227 dvb_dmxdev_release(&dvb->dmxdev);
227 err_dvb_dmx_release: 228 err_dvb_dmx_release:
228 dvb_dmx_release(dvbdemux); 229 dvb_dmx_release(dvbdemux);
229 err_dvb_unregister_adapter: 230 err_dvb_unregister_adapter:
230 dvb_unregister_adapter(dvb_adapter); 231 dvb_unregister_adapter(dvb_adapter);
231 err_out: 232 err_out:
232 return ret; 233 return ret;
233 } 234 }
234 235
235 void cx18_dvb_unregister(struct cx18_stream *stream) 236 void cx18_dvb_unregister(struct cx18_stream *stream)
236 { 237 {
237 struct cx18 *cx = stream->cx; 238 struct cx18 *cx = stream->cx;
238 struct cx18_dvb *dvb = &stream->dvb; 239 struct cx18_dvb *dvb = &stream->dvb;
239 struct dvb_adapter *dvb_adapter; 240 struct dvb_adapter *dvb_adapter;
240 struct dvb_demux *dvbdemux; 241 struct dvb_demux *dvbdemux;
241 struct dmx_demux *dmx; 242 struct dmx_demux *dmx;
242 243
243 CX18_INFO("unregister DVB\n"); 244 CX18_INFO("unregister DVB\n");
244 245
245 dvb_adapter = &dvb->dvb_adapter; 246 dvb_adapter = &dvb->dvb_adapter;
246 dvbdemux = &dvb->demux; 247 dvbdemux = &dvb->demux;
247 dmx = &dvbdemux->dmx; 248 dmx = &dvbdemux->dmx;
248 249
249 dmx->close(dmx); 250 dmx->close(dmx);
250 dvb_net_release(&dvb->dvbnet); 251 dvb_net_release(&dvb->dvbnet);
251 dmx->remove_frontend(dmx, &dvb->mem_frontend); 252 dmx->remove_frontend(dmx, &dvb->mem_frontend);
252 dmx->remove_frontend(dmx, &dvb->hw_frontend); 253 dmx->remove_frontend(dmx, &dvb->hw_frontend);
253 dvb_dmxdev_release(&dvb->dmxdev); 254 dvb_dmxdev_release(&dvb->dmxdev);
254 dvb_dmx_release(dvbdemux); 255 dvb_dmx_release(dvbdemux);
255 dvb_unregister_frontend(dvb->fe); 256 dvb_unregister_frontend(dvb->fe);
256 dvb_frontend_detach(dvb->fe); 257 dvb_frontend_detach(dvb->fe);
257 dvb_unregister_adapter(dvb_adapter); 258 dvb_unregister_adapter(dvb_adapter);
258 } 259 }
259 260
260 /* All the DVB attach calls go here, this function get's modified 261 /* All the DVB attach calls go here, this function get's modified
261 * for each new card. No other function in this file needs 262 * for each new card. No other function in this file needs
262 * to change. 263 * to change.
263 */ 264 */
264 static int dvb_register(struct cx18_stream *stream) 265 static int dvb_register(struct cx18_stream *stream)
265 { 266 {
266 struct cx18_dvb *dvb = &stream->dvb; 267 struct cx18_dvb *dvb = &stream->dvb;
267 struct cx18 *cx = stream->cx; 268 struct cx18 *cx = stream->cx;
268 int ret = 0; 269 int ret = 0;
269 270
270 switch (cx->card->type) { 271 switch (cx->card->type) {
271 case CX18_CARD_HVR_1600_ESMT: 272 case CX18_CARD_HVR_1600_ESMT:
272 case CX18_CARD_HVR_1600_SAMSUNG: 273 case CX18_CARD_HVR_1600_SAMSUNG:
273 dvb->fe = dvb_attach(s5h1409_attach, 274 dvb->fe = dvb_attach(s5h1409_attach,
274 &hauppauge_hvr1600_config, 275 &hauppauge_hvr1600_config,
275 &cx->i2c_adap[0]); 276 &cx->i2c_adap[0]);
276 if (dvb->fe != NULL) { 277 if (dvb->fe != NULL) {
277 dvb_attach(mxl5005s_attach, dvb->fe, 278 dvb_attach(mxl5005s_attach, dvb->fe,
278 &cx->i2c_adap[0], 279 &cx->i2c_adap[0],
279 &hauppauge_hvr1600_tuner); 280 &hauppauge_hvr1600_tuner);
280 ret = 0; 281 ret = 0;
281 } 282 }
282 break; 283 break;
283 default: 284 default:
284 /* No Digital Tv Support */ 285 /* No Digital Tv Support */
285 break; 286 break;
286 } 287 }
287 288
288 if (dvb->fe == NULL) { 289 if (dvb->fe == NULL) {
289 CX18_ERR("frontend initialization failed\n"); 290 CX18_ERR("frontend initialization failed\n");
290 return -1; 291 return -1;
291 } 292 }
292 293
293 ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe); 294 ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe);
294 if (ret < 0) { 295 if (ret < 0) {
295 if (dvb->fe->ops.release) 296 if (dvb->fe->ops.release)
296 dvb->fe->ops.release(dvb->fe); 297 dvb->fe->ops.release(dvb->fe);
297 return ret; 298 return ret;
298 } 299 }
299 300
300 return ret; 301 return ret;
301 } 302 }
302 303
drivers/media/video/cx18/cx18-firmware.c
1 /* 1 /*
2 * cx18 firmware functions 2 * cx18 firmware functions
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 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 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 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA 19 * 02111-1307 USA
20 */ 20 */
21 21
22 #include "cx18-driver.h" 22 #include "cx18-driver.h"
23 #include "cx18-io.h"
23 #include "cx18-scb.h" 24 #include "cx18-scb.h"
24 #include "cx18-irq.h" 25 #include "cx18-irq.h"
25 #include "cx18-firmware.h" 26 #include "cx18-firmware.h"
26 #include "cx18-cards.h" 27 #include "cx18-cards.h"
27 #include <linux/firmware.h> 28 #include <linux/firmware.h>
28 29
29 #define CX18_PROC_SOFT_RESET 0xc70010 30 #define CX18_PROC_SOFT_RESET 0xc70010
30 #define CX18_DDR_SOFT_RESET 0xc70014 31 #define CX18_DDR_SOFT_RESET 0xc70014
31 #define CX18_CLOCK_SELECT1 0xc71000 32 #define CX18_CLOCK_SELECT1 0xc71000
32 #define CX18_CLOCK_SELECT2 0xc71004 33 #define CX18_CLOCK_SELECT2 0xc71004
33 #define CX18_HALF_CLOCK_SELECT1 0xc71008 34 #define CX18_HALF_CLOCK_SELECT1 0xc71008
34 #define CX18_HALF_CLOCK_SELECT2 0xc7100C 35 #define CX18_HALF_CLOCK_SELECT2 0xc7100C
35 #define CX18_CLOCK_POLARITY1 0xc71010 36 #define CX18_CLOCK_POLARITY1 0xc71010
36 #define CX18_CLOCK_POLARITY2 0xc71014 37 #define CX18_CLOCK_POLARITY2 0xc71014
37 #define CX18_ADD_DELAY_ENABLE1 0xc71018 38 #define CX18_ADD_DELAY_ENABLE1 0xc71018
38 #define CX18_ADD_DELAY_ENABLE2 0xc7101C 39 #define CX18_ADD_DELAY_ENABLE2 0xc7101C
39 #define CX18_CLOCK_ENABLE1 0xc71020 40 #define CX18_CLOCK_ENABLE1 0xc71020
40 #define CX18_CLOCK_ENABLE2 0xc71024 41 #define CX18_CLOCK_ENABLE2 0xc71024
41 42
42 #define CX18_REG_BUS_TIMEOUT_EN 0xc72024 43 #define CX18_REG_BUS_TIMEOUT_EN 0xc72024
43 44
44 #define CX18_FAST_CLOCK_PLL_INT 0xc78000 45 #define CX18_FAST_CLOCK_PLL_INT 0xc78000
45 #define CX18_FAST_CLOCK_PLL_FRAC 0xc78004 46 #define CX18_FAST_CLOCK_PLL_FRAC 0xc78004
46 #define CX18_FAST_CLOCK_PLL_POST 0xc78008 47 #define CX18_FAST_CLOCK_PLL_POST 0xc78008
47 #define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C 48 #define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C
48 #define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010 49 #define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010
49 50
50 #define CX18_SLOW_CLOCK_PLL_INT 0xc78014 51 #define CX18_SLOW_CLOCK_PLL_INT 0xc78014
51 #define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018 52 #define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018
52 #define CX18_SLOW_CLOCK_PLL_POST 0xc7801C 53 #define CX18_SLOW_CLOCK_PLL_POST 0xc7801C
53 #define CX18_MPEG_CLOCK_PLL_INT 0xc78040 54 #define CX18_MPEG_CLOCK_PLL_INT 0xc78040
54 #define CX18_MPEG_CLOCK_PLL_FRAC 0xc78044 55 #define CX18_MPEG_CLOCK_PLL_FRAC 0xc78044
55 #define CX18_MPEG_CLOCK_PLL_POST 0xc78048 56 #define CX18_MPEG_CLOCK_PLL_POST 0xc78048
56 #define CX18_PLL_POWER_DOWN 0xc78088 57 #define CX18_PLL_POWER_DOWN 0xc78088
57 #define CX18_SW1_INT_STATUS 0xc73104 58 #define CX18_SW1_INT_STATUS 0xc73104
58 #define CX18_SW1_INT_ENABLE_PCI 0xc7311C 59 #define CX18_SW1_INT_ENABLE_PCI 0xc7311C
59 #define CX18_SW2_INT_SET 0xc73140 60 #define CX18_SW2_INT_SET 0xc73140
60 #define CX18_SW2_INT_STATUS 0xc73144 61 #define CX18_SW2_INT_STATUS 0xc73144
61 #define CX18_ADEC_CONTROL 0xc78120 62 #define CX18_ADEC_CONTROL 0xc78120
62 63
63 #define CX18_DDR_REQUEST_ENABLE 0xc80000 64 #define CX18_DDR_REQUEST_ENABLE 0xc80000
64 #define CX18_DDR_CHIP_CONFIG 0xc80004 65 #define CX18_DDR_CHIP_CONFIG 0xc80004
65 #define CX18_DDR_REFRESH 0xc80008 66 #define CX18_DDR_REFRESH 0xc80008
66 #define CX18_DDR_TIMING1 0xc8000C 67 #define CX18_DDR_TIMING1 0xc8000C
67 #define CX18_DDR_TIMING2 0xc80010 68 #define CX18_DDR_TIMING2 0xc80010
68 #define CX18_DDR_POWER_REG 0xc8001C 69 #define CX18_DDR_POWER_REG 0xc8001C
69 70
70 #define CX18_DDR_TUNE_LANE 0xc80048 71 #define CX18_DDR_TUNE_LANE 0xc80048
71 #define CX18_DDR_INITIAL_EMRS 0xc80054 72 #define CX18_DDR_INITIAL_EMRS 0xc80054
72 #define CX18_DDR_MB_PER_ROW_7 0xc8009C 73 #define CX18_DDR_MB_PER_ROW_7 0xc8009C
73 #define CX18_DDR_BASE_63_ADDR 0xc804FC 74 #define CX18_DDR_BASE_63_ADDR 0xc804FC
74 75
75 #define CX18_WMB_CLIENT02 0xc90108 76 #define CX18_WMB_CLIENT02 0xc90108
76 #define CX18_WMB_CLIENT05 0xc90114 77 #define CX18_WMB_CLIENT05 0xc90114
77 #define CX18_WMB_CLIENT06 0xc90118 78 #define CX18_WMB_CLIENT06 0xc90118
78 #define CX18_WMB_CLIENT07 0xc9011C 79 #define CX18_WMB_CLIENT07 0xc9011C
79 #define CX18_WMB_CLIENT08 0xc90120 80 #define CX18_WMB_CLIENT08 0xc90120
80 #define CX18_WMB_CLIENT09 0xc90124 81 #define CX18_WMB_CLIENT09 0xc90124
81 #define CX18_WMB_CLIENT10 0xc90128 82 #define CX18_WMB_CLIENT10 0xc90128
82 #define CX18_WMB_CLIENT11 0xc9012C 83 #define CX18_WMB_CLIENT11 0xc9012C
83 #define CX18_WMB_CLIENT12 0xc90130 84 #define CX18_WMB_CLIENT12 0xc90130
84 #define CX18_WMB_CLIENT13 0xc90134 85 #define CX18_WMB_CLIENT13 0xc90134
85 #define CX18_WMB_CLIENT14 0xc90138 86 #define CX18_WMB_CLIENT14 0xc90138
86 87
87 #define CX18_DSP0_INTERRUPT_MASK 0xd0004C 88 #define CX18_DSP0_INTERRUPT_MASK 0xd0004C
88 89
89 #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */ 90 #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
90 #define APU_ROM_SYNC2 0x72646548 /* "rdeH" */ 91 #define APU_ROM_SYNC2 0x72646548 /* "rdeH" */
91 92
92 struct cx18_apu_rom_seghdr { 93 struct cx18_apu_rom_seghdr {
93 u32 sync1; 94 u32 sync1;
94 u32 sync2; 95 u32 sync2;
95 u32 addr; 96 u32 addr;
96 u32 size; 97 u32 size;
97 }; 98 };
98 99
99 static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx) 100 static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
100 { 101 {
101 const struct firmware *fw = NULL; 102 const struct firmware *fw = NULL;
102 int i, j; 103 int i, j;
103 unsigned size; 104 unsigned size;
104 u32 __iomem *dst = (u32 __iomem *)mem; 105 u32 __iomem *dst = (u32 __iomem *)mem;
105 const u32 *src; 106 const u32 *src;
106 107
107 if (request_firmware(&fw, fn, &cx->dev->dev)) { 108 if (request_firmware(&fw, fn, &cx->dev->dev)) {
108 CX18_ERR("Unable to open firmware %s\n", fn); 109 CX18_ERR("Unable to open firmware %s\n", fn);
109 CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n"); 110 CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
110 return -ENOMEM; 111 return -ENOMEM;
111 } 112 }
112 113
113 src = (const u32 *)fw->data; 114 src = (const u32 *)fw->data;
114 115
115 for (i = 0; i < fw->size; i += 4096) { 116 for (i = 0; i < fw->size; i += 4096) {
116 setup_page(i); 117 cx18_setup_page(cx, i);
117 for (j = i; j < fw->size && j < i + 4096; j += 4) { 118 for (j = i; j < fw->size && j < i + 4096; j += 4) {
118 /* no need for endianness conversion on the ppc */ 119 /* no need for endianness conversion on the ppc */
119 __raw_writel(*src, dst); 120 cx18_raw_writel(cx, *src, dst);
120 if (__raw_readl(dst) != *src) { 121 if (cx18_raw_readl(cx, dst) != *src) {
121 CX18_ERR("Mismatch at offset %x\n", i); 122 CX18_ERR("Mismatch at offset %x\n", i);
122 release_firmware(fw); 123 release_firmware(fw);
123 return -EIO; 124 return -EIO;
124 } 125 }
125 dst++; 126 dst++;
126 src++; 127 src++;
127 } 128 }
128 } 129 }
129 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) 130 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
130 CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size); 131 CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
131 size = fw->size; 132 size = fw->size;
132 release_firmware(fw); 133 release_firmware(fw);
133 return size; 134 return size;
134 } 135 }
135 136
136 static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) 137 static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
137 { 138 {
138 const struct firmware *fw = NULL; 139 const struct firmware *fw = NULL;
139 int i, j; 140 int i, j;
140 unsigned size; 141 unsigned size;
141 const u32 *src; 142 const u32 *src;
142 struct cx18_apu_rom_seghdr seghdr; 143 struct cx18_apu_rom_seghdr seghdr;
143 const u8 *vers; 144 const u8 *vers;
144 u32 offset = 0; 145 u32 offset = 0;
145 u32 apu_version = 0; 146 u32 apu_version = 0;
146 int sz; 147 int sz;
147 148
148 if (request_firmware(&fw, fn, &cx->dev->dev)) { 149 if (request_firmware(&fw, fn, &cx->dev->dev)) {
149 CX18_ERR("unable to open firmware %s\n", fn); 150 CX18_ERR("unable to open firmware %s\n", fn);
150 CX18_ERR("did you put the firmware in the hotplug firmware directory?\n"); 151 CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
151 return -ENOMEM; 152 return -ENOMEM;
152 } 153 }
153 154
154 src = (const u32 *)fw->data; 155 src = (const u32 *)fw->data;
155 vers = fw->data + sizeof(seghdr); 156 vers = fw->data + sizeof(seghdr);
156 sz = fw->size; 157 sz = fw->size;
157 158
158 apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32]; 159 apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
159 while (offset + sizeof(seghdr) < fw->size) { 160 while (offset + sizeof(seghdr) < fw->size) {
160 /* TODO: byteswapping */ 161 /* TODO: byteswapping */
161 memcpy(&seghdr, src + offset / 4, sizeof(seghdr)); 162 memcpy(&seghdr, src + offset / 4, sizeof(seghdr));
162 offset += sizeof(seghdr); 163 offset += sizeof(seghdr);
163 if (seghdr.sync1 != APU_ROM_SYNC1 || 164 if (seghdr.sync1 != APU_ROM_SYNC1 ||
164 seghdr.sync2 != APU_ROM_SYNC2) { 165 seghdr.sync2 != APU_ROM_SYNC2) {
165 offset += seghdr.size; 166 offset += seghdr.size;
166 continue; 167 continue;
167 } 168 }
168 CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr, 169 CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
169 seghdr.addr + seghdr.size - 1); 170 seghdr.addr + seghdr.size - 1);
170 if (offset + seghdr.size > sz) 171 if (offset + seghdr.size > sz)
171 break; 172 break;
172 for (i = 0; i < seghdr.size; i += 4096) { 173 for (i = 0; i < seghdr.size; i += 4096) {
173 setup_page(offset + i); 174 cx18_setup_page(cx, offset + i);
174 for (j = i; j < seghdr.size && j < i + 4096; j += 4) { 175 for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
175 /* no need for endianness conversion on the ppc */ 176 /* no need for endianness conversion on the ppc */
176 __raw_writel(src[(offset + j) / 4], dst + seghdr.addr + j); 177 cx18_raw_writel(cx, src[(offset + j) / 4],
177 if (__raw_readl(dst + seghdr.addr + j) != src[(offset + j) / 4]) { 178 dst + seghdr.addr + j);
178 CX18_ERR("Mismatch at offset %x\n", offset + j); 179 if (cx18_raw_readl(cx, dst + seghdr.addr + j)
180 != src[(offset + j) / 4]) {
181 CX18_ERR("Mismatch at offset %x\n",
182 offset + j);
179 release_firmware(fw); 183 release_firmware(fw);
180 return -EIO; 184 return -EIO;
181 } 185 }
182 } 186 }
183 } 187 }
184 offset += seghdr.size; 188 offset += seghdr.size;
185 } 189 }
186 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) 190 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
187 CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n", 191 CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
188 fn, apu_version, fw->size); 192 fn, apu_version, fw->size);
189 size = fw->size; 193 size = fw->size;
190 release_firmware(fw); 194 release_firmware(fw);
191 /* Clear bit0 for APU to start from 0 */ 195 /* Clear bit0 for APU to start from 0 */
192 write_reg(read_reg(0xc72030) & ~1, 0xc72030); 196 cx18_write_reg(cx, cx18_read_reg(cx, 0xc72030) & ~1, 0xc72030);
193 return size; 197 return size;
194 } 198 }
195 199
196 void cx18_halt_firmware(struct cx18 *cx) 200 void cx18_halt_firmware(struct cx18 *cx)
197 { 201 {
198 CX18_DEBUG_INFO("Preparing for firmware halt.\n"); 202 CX18_DEBUG_INFO("Preparing for firmware halt.\n");
199 write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */ 203 cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
200 write_reg(0x00020002, CX18_ADEC_CONTROL); 204 cx18_write_reg(cx, 0x00020002, CX18_ADEC_CONTROL);
201 } 205 }
202 206
203 void cx18_init_power(struct cx18 *cx, int lowpwr) 207 void cx18_init_power(struct cx18 *cx, int lowpwr)
204 { 208 {
205 /* power-down Spare and AOM PLLs */ 209 /* power-down Spare and AOM PLLs */
206 /* power-up fast, slow and mpeg PLLs */ 210 /* power-up fast, slow and mpeg PLLs */
207 write_reg(0x00000008, CX18_PLL_POWER_DOWN); 211 cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN);
208 212
209 /* ADEC out of sleep */ 213 /* ADEC out of sleep */
210 write_reg(0x00020000, CX18_ADEC_CONTROL); 214 cx18_write_reg(cx, 0x00020000, CX18_ADEC_CONTROL);
211 215
212 /* The fast clock is at 200/245 MHz */ 216 /* The fast clock is at 200/245 MHz */
213 write_reg(lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT); 217 cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
214 write_reg(lowpwr ? 0x1EFBF37 : 0x038E3D7, CX18_FAST_CLOCK_PLL_FRAC); 218 cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7,
219 CX18_FAST_CLOCK_PLL_FRAC);
215 220
216 write_reg(2, CX18_FAST_CLOCK_PLL_POST); 221 cx18_write_reg(cx, 2, CX18_FAST_CLOCK_PLL_POST);
217 write_reg(1, CX18_FAST_CLOCK_PLL_PRESCALE); 222 cx18_write_reg(cx, 1, CX18_FAST_CLOCK_PLL_PRESCALE);
218 write_reg(4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH); 223 cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
219 224
220 /* set slow clock to 125/120 MHz */ 225 /* set slow clock to 125/120 MHz */
221 write_reg(lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT); 226 cx18_write_reg(cx, lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT);
222 write_reg(lowpwr ? 0xEBAF05 : 0x18618A8, CX18_SLOW_CLOCK_PLL_FRAC); 227 cx18_write_reg(cx, lowpwr ? 0xEBAF05 : 0x18618A8,
223 write_reg(4, CX18_SLOW_CLOCK_PLL_POST); 228 CX18_SLOW_CLOCK_PLL_FRAC);
229 cx18_write_reg(cx, 4, CX18_SLOW_CLOCK_PLL_POST);
224 230
225 /* mpeg clock pll 54MHz */ 231 /* mpeg clock pll 54MHz */
226 write_reg(0xF, CX18_MPEG_CLOCK_PLL_INT); 232 cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT);
227 write_reg(0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC); 233 cx18_write_reg(cx, 0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC);
228 write_reg(8, CX18_MPEG_CLOCK_PLL_POST); 234 cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
229 235
230 /* Defaults */ 236 /* Defaults */
231 /* APU = SC or SC/2 = 125/62.5 */ 237 /* APU = SC or SC/2 = 125/62.5 */
232 /* EPU = SC = 125 */ 238 /* EPU = SC = 125 */
233 /* DDR = FC = 180 */ 239 /* DDR = FC = 180 */
234 /* ENC = SC = 125 */ 240 /* ENC = SC = 125 */
235 /* AI1 = SC = 125 */ 241 /* AI1 = SC = 125 */
236 /* VIM2 = disabled */ 242 /* VIM2 = disabled */
237 /* PCI = FC/2 = 90 */ 243 /* PCI = FC/2 = 90 */
238 /* AI2 = disabled */ 244 /* AI2 = disabled */
239 /* DEMUX = disabled */ 245 /* DEMUX = disabled */
240 /* AO = SC/2 = 62.5 */ 246 /* AO = SC/2 = 62.5 */
241 /* SER = 54MHz */ 247 /* SER = 54MHz */
242 /* VFC = disabled */ 248 /* VFC = disabled */
243 /* USB = disabled */ 249 /* USB = disabled */
244 250
245 write_reg(lowpwr ? 0xFFFF0020 : 0x00060004, CX18_CLOCK_SELECT1); 251 cx18_write_reg(cx, lowpwr ? 0xFFFF0020 : 0x00060004,
246 write_reg(lowpwr ? 0xFFFF0004 : 0x00060006, CX18_CLOCK_SELECT2); 252 CX18_CLOCK_SELECT1);
253 cx18_write_reg(cx, lowpwr ? 0xFFFF0004 : 0x00060006,
254 CX18_CLOCK_SELECT2);
247 255
248 write_reg(0xFFFF0002, CX18_HALF_CLOCK_SELECT1); 256 cx18_write_reg(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1);
249 write_reg(0xFFFF0104, CX18_HALF_CLOCK_SELECT2); 257 cx18_write_reg(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2);
250 258
251 write_reg(0xFFFF9026, CX18_CLOCK_ENABLE1); 259 cx18_write_reg(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1);
252 write_reg(0xFFFF3105, CX18_CLOCK_ENABLE2); 260 cx18_write_reg(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2);
253 } 261 }
254 262
255 void cx18_init_memory(struct cx18 *cx) 263 void cx18_init_memory(struct cx18 *cx)
256 { 264 {
257 cx18_msleep_timeout(10, 0); 265 cx18_msleep_timeout(10, 0);
258 write_reg(0x10000, CX18_DDR_SOFT_RESET); 266 cx18_write_reg(cx, 0x10000, CX18_DDR_SOFT_RESET);
259 cx18_msleep_timeout(10, 0); 267 cx18_msleep_timeout(10, 0);
260 268
261 write_reg(cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG); 269 cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
262 270
263 cx18_msleep_timeout(10, 0); 271 cx18_msleep_timeout(10, 0);
264 272
265 write_reg(cx->card->ddr.refresh, CX18_DDR_REFRESH); 273 cx18_write_reg(cx, cx->card->ddr.refresh, CX18_DDR_REFRESH);
266 write_reg(cx->card->ddr.timing1, CX18_DDR_TIMING1); 274 cx18_write_reg(cx, cx->card->ddr.timing1, CX18_DDR_TIMING1);
267 write_reg(cx->card->ddr.timing2, CX18_DDR_TIMING2); 275 cx18_write_reg(cx, cx->card->ddr.timing2, CX18_DDR_TIMING2);
268 276
269 cx18_msleep_timeout(10, 0); 277 cx18_msleep_timeout(10, 0);
270 278
271 /* Initialize DQS pad time */ 279 /* Initialize DQS pad time */
272 write_reg(cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE); 280 cx18_write_reg(cx, cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE);
273 write_reg(cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS); 281 cx18_write_reg(cx, cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS);
274 282
275 cx18_msleep_timeout(10, 0); 283 cx18_msleep_timeout(10, 0);
276 284
277 write_reg(0x20000, CX18_DDR_SOFT_RESET); 285 cx18_write_reg(cx, 0x20000, CX18_DDR_SOFT_RESET);
278 cx18_msleep_timeout(10, 0); 286 cx18_msleep_timeout(10, 0);
279 287
280 /* use power-down mode when idle */ 288 /* use power-down mode when idle */
281 write_reg(0x00000010, CX18_DDR_POWER_REG); 289 cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG);
282 290
283 write_reg(0x10001, CX18_REG_BUS_TIMEOUT_EN); 291 cx18_write_reg(cx, 0x10001, CX18_REG_BUS_TIMEOUT_EN);
284 292
285 write_reg(0x48, CX18_DDR_MB_PER_ROW_7); 293 cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7);
286 write_reg(0xE0000, CX18_DDR_BASE_63_ADDR); 294 cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR);
287 295
288 write_reg(0x00000101, CX18_WMB_CLIENT02); /* AO */ 296 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT02); /* AO */
289 write_reg(0x00000101, CX18_WMB_CLIENT09); /* AI2 */ 297 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT09); /* AI2 */
290 write_reg(0x00000101, CX18_WMB_CLIENT05); /* VIM1 */ 298 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT05); /* VIM1 */
291 write_reg(0x00000101, CX18_WMB_CLIENT06); /* AI1 */ 299 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT06); /* AI1 */
292 write_reg(0x00000101, CX18_WMB_CLIENT07); /* 3D comb */ 300 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT07); /* 3D comb */
293 write_reg(0x00000101, CX18_WMB_CLIENT10); /* ME */ 301 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT10); /* ME */
294 write_reg(0x00000101, CX18_WMB_CLIENT12); /* ENC */ 302 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT12); /* ENC */
295 write_reg(0x00000101, CX18_WMB_CLIENT13); /* PK */ 303 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT13); /* PK */
296 write_reg(0x00000101, CX18_WMB_CLIENT11); /* RC */ 304 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT11); /* RC */
297 write_reg(0x00000101, CX18_WMB_CLIENT14); /* AVO */ 305 cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT14); /* AVO */
298 } 306 }
299 307
300 int cx18_firmware_init(struct cx18 *cx) 308 int cx18_firmware_init(struct cx18 *cx)
301 { 309 {
302 /* Allow chip to control CLKRUN */ 310 /* Allow chip to control CLKRUN */
303 write_reg(0x5, CX18_DSP0_INTERRUPT_MASK); 311 cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);
304 312
305 write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */ 313 cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
306 314
307 cx18_msleep_timeout(1, 0); 315 cx18_msleep_timeout(1, 0);
308 316
309 sw1_irq_enable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); 317 cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
310 sw2_irq_enable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); 318 cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
311 319
312 /* Only if the processor is not running */ 320 /* Only if the processor is not running */
313 if (read_reg(CX18_PROC_SOFT_RESET) & 8) { 321 if (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) {
314 int sz = load_apu_fw_direct("v4l-cx23418-apu.fw", 322 int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
315 cx->enc_mem, cx); 323 cx->enc_mem, cx);
316 324
317 write_enc(0xE51FF004, 0); 325 cx18_write_enc(cx, 0xE51FF004, 0);
318 write_enc(0xa00000, 4); /* todo: not hardcoded */ 326 cx18_write_enc(cx, 0xa00000, 4); /* todo: not hardcoded */
319 write_reg(0x00010000, CX18_PROC_SOFT_RESET); /* Start APU */ 327 /* Start APU */
328 cx18_write_reg(cx, 0x00010000, CX18_PROC_SOFT_RESET);
320 cx18_msleep_timeout(500, 0); 329 cx18_msleep_timeout(500, 0);
321 330
322 sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw", 331 sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
323 cx->enc_mem, cx); 332 cx->enc_mem, cx);
324 333
325 if (sz > 0) { 334 if (sz > 0) {
326 int retries = 0; 335 int retries = 0;
327 336
328 /* start the CPU */ 337 /* start the CPU */
329 write_reg(0x00080000, CX18_PROC_SOFT_RESET); 338 cx18_write_reg(cx, 0x00080000, CX18_PROC_SOFT_RESET);
330 while (retries++ < 50) { /* Loop for max 500mS */ 339 while (retries++ < 50) { /* Loop for max 500mS */
331 if ((read_reg(CX18_PROC_SOFT_RESET) & 1) == 0) 340 if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET)
341 & 1) == 0)
332 break; 342 break;
333 cx18_msleep_timeout(10, 0); 343 cx18_msleep_timeout(10, 0);
334 } 344 }
335 cx18_msleep_timeout(200, 0); 345 cx18_msleep_timeout(200, 0);
336 if (retries == 51) { 346 if (retries == 51) {
337 CX18_ERR("Could not start the CPU\n"); 347 CX18_ERR("Could not start the CPU\n");
338 return -EIO; 348 return -EIO;
339 } 349 }
340 } 350 }
341 if (sz <= 0) 351 if (sz <= 0)
342 return -EIO; 352 return -EIO;
343 } 353 }
344 /* initialize GPIO */ 354 /* initialize GPIO */
345 write_reg(0x14001400, 0xC78110); 355 cx18_write_reg(cx, 0x14001400, 0xC78110);
346 return 0; 356 return 0;
347 } 357 }
348 358
drivers/media/video/cx18/cx18-gpio.c
1 /* 1 /*
2 * cx18 gpio functions 2 * cx18 gpio functions
3 * 3 *
4 * Derived from ivtv-gpio.c 4 * Derived from ivtv-gpio.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 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 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 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 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24 #include "cx18-driver.h" 24 #include "cx18-driver.h"
25 #include "cx18-io.h"
25 #include "cx18-cards.h" 26 #include "cx18-cards.h"
26 #include "cx18-gpio.h" 27 #include "cx18-gpio.h"
27 #include "tuner-xc2028.h" 28 #include "tuner-xc2028.h"
28 29
29 /********************* GPIO stuffs *********************/ 30 /********************* GPIO stuffs *********************/
30 31
31 /* GPIO registers */ 32 /* GPIO registers */
32 #define CX18_REG_GPIO_IN 0xc72010 33 #define CX18_REG_GPIO_IN 0xc72010
33 #define CX18_REG_GPIO_OUT1 0xc78100 34 #define CX18_REG_GPIO_OUT1 0xc78100
34 #define CX18_REG_GPIO_DIR1 0xc78108 35 #define CX18_REG_GPIO_DIR1 0xc78108
35 #define CX18_REG_GPIO_OUT2 0xc78104 36 #define CX18_REG_GPIO_OUT2 0xc78104
36 #define CX18_REG_GPIO_DIR2 0xc7810c 37 #define CX18_REG_GPIO_DIR2 0xc7810c
37 38
38 /* 39 /*
39 * HVR-1600 GPIO pins, courtesy of Hauppauge: 40 * HVR-1600 GPIO pins, courtesy of Hauppauge:
40 * 41 *
41 * gpio0: zilog ir process reset pin 42 * gpio0: zilog ir process reset pin
42 * gpio1: zilog programming pin (you should never use this) 43 * gpio1: zilog programming pin (you should never use this)
43 * gpio12: cx24227 reset pin 44 * gpio12: cx24227 reset pin
44 * gpio13: cs5345 reset pin 45 * gpio13: cs5345 reset pin
45 */ 46 */
46 47
47 static void gpio_write(struct cx18 *cx) 48 static void gpio_write(struct cx18 *cx)
48 { 49 {
49 u32 dir = cx->gpio_dir; 50 u32 dir = cx->gpio_dir;
50 u32 val = cx->gpio_val; 51 u32 val = cx->gpio_val;
51 52
52 write_reg((dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); 53 cx18_write_reg(cx, (dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
53 write_reg(((dir & 0xffff) << 16) | (val & 0xffff), 54 cx18_write_reg(cx, ((dir & 0xffff) << 16) | (val & 0xffff),
54 CX18_REG_GPIO_OUT1); 55 CX18_REG_GPIO_OUT1);
55 write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2); 56 cx18_write_reg(cx, dir & 0xffff0000, CX18_REG_GPIO_DIR2);
56 write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), 57 cx18_write_reg_sync(cx, (dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
57 CX18_REG_GPIO_OUT2); 58 CX18_REG_GPIO_OUT2);
58 } 59 }
59 60
60 void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) 61 void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
61 { 62 {
62 const struct cx18_gpio_i2c_slave_reset *p; 63 const struct cx18_gpio_i2c_slave_reset *p;
63 64
64 p = &cx->card->gpio_i2c_slave_reset; 65 p = &cx->card->gpio_i2c_slave_reset;
65 66
66 if ((p->active_lo_mask | p->active_hi_mask) == 0) 67 if ((p->active_lo_mask | p->active_hi_mask) == 0)
67 return; 68 return;
68 69
69 /* Assuming that the masks are a subset of the bits in gpio_dir */ 70 /* Assuming that the masks are a subset of the bits in gpio_dir */
70 71
71 /* Assert */ 72 /* Assert */
72 mutex_lock(&cx->gpio_lock); 73 mutex_lock(&cx->gpio_lock);
73 cx->gpio_val = 74 cx->gpio_val =
74 (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); 75 (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
75 gpio_write(cx); 76 gpio_write(cx);
76 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); 77 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
77 78
78 /* Deassert */ 79 /* Deassert */
79 cx->gpio_val = 80 cx->gpio_val =
80 (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); 81 (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
81 gpio_write(cx); 82 gpio_write(cx);
82 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); 83 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
83 mutex_unlock(&cx->gpio_lock); 84 mutex_unlock(&cx->gpio_lock);
84 } 85 }
85 86
86 void cx18_reset_ir_gpio(void *data) 87 void cx18_reset_ir_gpio(void *data)
87 { 88 {
88 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; 89 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
89 const struct cx18_gpio_i2c_slave_reset *p; 90 const struct cx18_gpio_i2c_slave_reset *p;
90 91
91 p = &cx->card->gpio_i2c_slave_reset; 92 p = &cx->card->gpio_i2c_slave_reset;
92 93
93 if (p->ir_reset_mask == 0) 94 if (p->ir_reset_mask == 0)
94 return; 95 return;
95 96
96 CX18_DEBUG_INFO("Resetting IR microcontroller\n"); 97 CX18_DEBUG_INFO("Resetting IR microcontroller\n");
97 98
98 /* 99 /*
99 Assert timing for the Z8F0811 on HVR-1600 boards: 100 Assert timing for the Z8F0811 on HVR-1600 boards:
100 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate 101 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate
101 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles 102 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles
102 (6,601,085 nanoseconds ~= 7 milliseconds) 103 (6,601,085 nanoseconds ~= 7 milliseconds)
103 3. DBG pin must be high before chip exits reset for normal operation. 104 3. DBG pin must be high before chip exits reset for normal operation.
104 DBG is open drain and hopefully pulled high since we don't 105 DBG is open drain and hopefully pulled high since we don't
105 normally drive it (GPIO 1?) for the HVR-1600 106 normally drive it (GPIO 1?) for the HVR-1600
106 4. Z8F0811 won't exit reset until RESET is deasserted 107 4. Z8F0811 won't exit reset until RESET is deasserted
107 */ 108 */
108 mutex_lock(&cx->gpio_lock); 109 mutex_lock(&cx->gpio_lock);
109 cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask; 110 cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask;
110 gpio_write(cx); 111 gpio_write(cx);
111 mutex_unlock(&cx->gpio_lock); 112 mutex_unlock(&cx->gpio_lock);
112 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); 113 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
113 114
114 /* 115 /*
115 Zilog comes out of reset, loads reset vector address and executes 116 Zilog comes out of reset, loads reset vector address and executes
116 from there. Required recovery delay unknown. 117 from there. Required recovery delay unknown.
117 */ 118 */
118 mutex_lock(&cx->gpio_lock); 119 mutex_lock(&cx->gpio_lock);
119 cx->gpio_val = cx->gpio_val | p->ir_reset_mask; 120 cx->gpio_val = cx->gpio_val | p->ir_reset_mask;
120 gpio_write(cx); 121 gpio_write(cx);
121 mutex_unlock(&cx->gpio_lock); 122 mutex_unlock(&cx->gpio_lock);
122 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); 123 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
123 } 124 }
124 EXPORT_SYMBOL(cx18_reset_ir_gpio); 125 EXPORT_SYMBOL(cx18_reset_ir_gpio);
125 /* This symbol is exported for use by an infrared module for the IR-blaster */ 126 /* This symbol is exported for use by an infrared module for the IR-blaster */
126 127
127 void cx18_gpio_init(struct cx18 *cx) 128 void cx18_gpio_init(struct cx18 *cx)
128 { 129 {
129 mutex_lock(&cx->gpio_lock); 130 mutex_lock(&cx->gpio_lock);
130 cx->gpio_dir = cx->card->gpio_init.direction; 131 cx->gpio_dir = cx->card->gpio_init.direction;
131 cx->gpio_val = cx->card->gpio_init.initial_value; 132 cx->gpio_val = cx->card->gpio_init.initial_value;
132 133
133 if (cx->card->tuners[0].tuner == TUNER_XC2028) { 134 if (cx->card->tuners[0].tuner == TUNER_XC2028) {
134 cx->gpio_dir |= 1 << cx->card->xceive_pin; 135 cx->gpio_dir |= 1 << cx->card->xceive_pin;
135 cx->gpio_val |= 1 << cx->card->xceive_pin; 136 cx->gpio_val |= 1 << cx->card->xceive_pin;
136 } 137 }
137 138
138 if (cx->gpio_dir == 0) { 139 if (cx->gpio_dir == 0) {
139 mutex_unlock(&cx->gpio_lock); 140 mutex_unlock(&cx->gpio_lock);
140 return; 141 return;
141 } 142 }
142 143
143 CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", 144 CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
144 read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), 145 cx18_read_reg(cx, CX18_REG_GPIO_DIR1),
145 read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); 146 cx18_read_reg(cx, CX18_REG_GPIO_DIR2),
147 cx18_read_reg(cx, CX18_REG_GPIO_OUT1),
148 cx18_read_reg(cx, CX18_REG_GPIO_OUT2));
146 149
147 gpio_write(cx); 150 gpio_write(cx);
148 mutex_unlock(&cx->gpio_lock); 151 mutex_unlock(&cx->gpio_lock);
149 } 152 }
150 153
151 /* Xceive tuner reset function */ 154 /* Xceive tuner reset function */
152 int cx18_reset_tuner_gpio(void *dev, int cmd, int value) 155 int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
153 { 156 {
154 struct i2c_algo_bit_data *algo = dev; 157 struct i2c_algo_bit_data *algo = dev;
155 struct cx18_i2c_algo_callback_data *cb_data = algo->data; 158 struct cx18_i2c_algo_callback_data *cb_data = algo->data;
156 struct cx18 *cx = cb_data->cx; 159 struct cx18 *cx = cb_data->cx;
157 160
158 if (cmd != XC2028_TUNER_RESET) 161 if (cmd != XC2028_TUNER_RESET)
159 return 0; 162 return 0;
160 CX18_DEBUG_INFO("Resetting tuner\n"); 163 CX18_DEBUG_INFO("Resetting tuner\n");
161 164
162 mutex_lock(&cx->gpio_lock); 165 mutex_lock(&cx->gpio_lock);
163 cx->gpio_val &= ~(1 << cx->card->xceive_pin); 166 cx->gpio_val &= ~(1 << cx->card->xceive_pin);
164 gpio_write(cx); 167 gpio_write(cx);
165 mutex_unlock(&cx->gpio_lock); 168 mutex_unlock(&cx->gpio_lock);
166 schedule_timeout_interruptible(msecs_to_jiffies(1)); 169 schedule_timeout_interruptible(msecs_to_jiffies(1));
167 170
168 mutex_lock(&cx->gpio_lock); 171 mutex_lock(&cx->gpio_lock);
169 cx->gpio_val |= 1 << cx->card->xceive_pin; 172 cx->gpio_val |= 1 << cx->card->xceive_pin;
170 gpio_write(cx); 173 gpio_write(cx);
171 mutex_unlock(&cx->gpio_lock); 174 mutex_unlock(&cx->gpio_lock);
172 schedule_timeout_interruptible(msecs_to_jiffies(1)); 175 schedule_timeout_interruptible(msecs_to_jiffies(1));
173 return 0; 176 return 0;
174 } 177 }
175 178
176 int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg) 179 int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg)
177 { 180 {
178 struct v4l2_routing *route = arg; 181 struct v4l2_routing *route = arg;
179 u32 mask, data; 182 u32 mask, data;
180 183
181 switch (command) { 184 switch (command) {
182 case VIDIOC_INT_S_AUDIO_ROUTING: 185 case VIDIOC_INT_S_AUDIO_ROUTING:
183 if (route->input > 2) 186 if (route->input > 2)
184 return -EINVAL; 187 return -EINVAL;
185 mask = cx->card->gpio_audio_input.mask; 188 mask = cx->card->gpio_audio_input.mask;
186 switch (route->input) { 189 switch (route->input) {
187 case 0: 190 case 0:
188 data = cx->card->gpio_audio_input.tuner; 191 data = cx->card->gpio_audio_input.tuner;
189 break; 192 break;
190 case 1: 193 case 1:
191 data = cx->card->gpio_audio_input.linein; 194 data = cx->card->gpio_audio_input.linein;
192 break; 195 break;
193 case 2: 196 case 2:
194 default: 197 default:
195 data = cx->card->gpio_audio_input.radio; 198 data = cx->card->gpio_audio_input.radio;
196 break; 199 break;
197 } 200 }
198 break; 201 break;
199 202
200 default: 203 default:
201 return -EINVAL; 204 return -EINVAL;
202 } 205 }
203 if (mask) { 206 if (mask) {
204 mutex_lock(&cx->gpio_lock); 207 mutex_lock(&cx->gpio_lock);
205 cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); 208 cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
206 gpio_write(cx); 209 gpio_write(cx);
207 mutex_unlock(&cx->gpio_lock); 210 mutex_unlock(&cx->gpio_lock);
208 } 211 }
209 return 0; 212 return 0;
210 } 213 }
211 214
drivers/media/video/cx18/cx18-i2c.c
1 /* 1 /*
2 * cx18 I2C functions 2 * cx18 I2C functions
3 * 3 *
4 * Derived from ivtv-i2c.c 4 * Derived from ivtv-i2c.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 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 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 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 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24 #include "cx18-driver.h" 24 #include "cx18-driver.h"
25 #include "cx18-io.h"
25 #include "cx18-cards.h" 26 #include "cx18-cards.h"
26 #include "cx18-gpio.h" 27 #include "cx18-gpio.h"
27 #include "cx18-av-core.h" 28 #include "cx18-av-core.h"
28 #include "cx18-i2c.h" 29 #include "cx18-i2c.h"
29 30
30 #define CX18_REG_I2C_1_WR 0xf15000 31 #define CX18_REG_I2C_1_WR 0xf15000
31 #define CX18_REG_I2C_1_RD 0xf15008 32 #define CX18_REG_I2C_1_RD 0xf15008
32 #define CX18_REG_I2C_2_WR 0xf25100 33 #define CX18_REG_I2C_2_WR 0xf25100
33 #define CX18_REG_I2C_2_RD 0xf25108 34 #define CX18_REG_I2C_2_RD 0xf25108
34 35
35 #define SETSCL_BIT 0x0001 36 #define SETSCL_BIT 0x0001
36 #define SETSDL_BIT 0x0002 37 #define SETSDL_BIT 0x0002
37 #define GETSCL_BIT 0x0004 38 #define GETSCL_BIT 0x0004
38 #define GETSDL_BIT 0x0008 39 #define GETSDL_BIT 0x0008
39 40
40 #define CX18_CS5345_I2C_ADDR 0x4c 41 #define CX18_CS5345_I2C_ADDR 0x4c
41 42
42 /* This array should match the CX18_HW_ defines */ 43 /* This array should match the CX18_HW_ defines */
43 static const u8 hw_driverids[] = { 44 static const u8 hw_driverids[] = {
44 I2C_DRIVERID_TUNER, 45 I2C_DRIVERID_TUNER,
45 I2C_DRIVERID_TVEEPROM, 46 I2C_DRIVERID_TVEEPROM,
46 I2C_DRIVERID_CS5345, 47 I2C_DRIVERID_CS5345,
47 0, /* CX18_HW_GPIO dummy driver ID */ 48 0, /* CX18_HW_GPIO dummy driver ID */
48 0 /* CX18_HW_CX23418 dummy driver ID */ 49 0 /* CX18_HW_CX23418 dummy driver ID */
49 }; 50 };
50 51
51 /* This array should match the CX18_HW_ defines */ 52 /* This array should match the CX18_HW_ defines */
52 static const u8 hw_addrs[] = { 53 static const u8 hw_addrs[] = {
53 0, 54 0,
54 0, 55 0,
55 CX18_CS5345_I2C_ADDR, 56 CX18_CS5345_I2C_ADDR,
56 0, /* CX18_HW_GPIO dummy driver ID */ 57 0, /* CX18_HW_GPIO dummy driver ID */
57 0, /* CX18_HW_CX23418 dummy driver ID */ 58 0, /* CX18_HW_CX23418 dummy driver ID */
58 }; 59 };
59 60
60 /* This array should match the CX18_HW_ defines */ 61 /* This array should match the CX18_HW_ defines */
61 /* This might well become a card-specific array */ 62 /* This might well become a card-specific array */
62 static const u8 hw_bus[] = { 63 static const u8 hw_bus[] = {
63 0, 64 0,
64 0, 65 0,
65 0, 66 0,
66 0, /* CX18_HW_GPIO dummy driver ID */ 67 0, /* CX18_HW_GPIO dummy driver ID */
67 0, /* CX18_HW_CX23418 dummy driver ID */ 68 0, /* CX18_HW_CX23418 dummy driver ID */
68 }; 69 };
69 70
70 /* This array should match the CX18_HW_ defines */ 71 /* This array should match the CX18_HW_ defines */
71 static const char * const hw_devicenames[] = { 72 static const char * const hw_devicenames[] = {
72 "tuner", 73 "tuner",
73 "tveeprom", 74 "tveeprom",
74 "cs5345", 75 "cs5345",
75 "gpio", 76 "gpio",
76 "cx23418", 77 "cx23418",
77 }; 78 };
78 79
79 int cx18_i2c_register(struct cx18 *cx, unsigned idx) 80 int cx18_i2c_register(struct cx18 *cx, unsigned idx)
80 { 81 {
81 struct i2c_board_info info; 82 struct i2c_board_info info;
82 struct i2c_client *c; 83 struct i2c_client *c;
83 u8 id, bus; 84 u8 id, bus;
84 int i; 85 int i;
85 86
86 CX18_DEBUG_I2C("i2c client register\n"); 87 CX18_DEBUG_I2C("i2c client register\n");
87 if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0) 88 if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0)
88 return -1; 89 return -1;
89 id = hw_driverids[idx]; 90 id = hw_driverids[idx];
90 bus = hw_bus[idx]; 91 bus = hw_bus[idx];
91 memset(&info, 0, sizeof(info)); 92 memset(&info, 0, sizeof(info));
92 strlcpy(info.type, hw_devicenames[idx], sizeof(info.type)); 93 strlcpy(info.type, hw_devicenames[idx], sizeof(info.type));
93 info.addr = hw_addrs[idx]; 94 info.addr = hw_addrs[idx];
94 for (i = 0; i < I2C_CLIENTS_MAX; i++) 95 for (i = 0; i < I2C_CLIENTS_MAX; i++)
95 if (cx->i2c_clients[i] == NULL) 96 if (cx->i2c_clients[i] == NULL)
96 break; 97 break;
97 98
98 if (i == I2C_CLIENTS_MAX) { 99 if (i == I2C_CLIENTS_MAX) {
99 CX18_ERR("insufficient room for new I2C client!\n"); 100 CX18_ERR("insufficient room for new I2C client!\n");
100 return -ENOMEM; 101 return -ENOMEM;
101 } 102 }
102 103
103 if (id != I2C_DRIVERID_TUNER) { 104 if (id != I2C_DRIVERID_TUNER) {
104 c = i2c_new_device(&cx->i2c_adap[bus], &info); 105 c = i2c_new_device(&cx->i2c_adap[bus], &info);
105 if (c->driver == NULL) 106 if (c->driver == NULL)
106 i2c_unregister_device(c); 107 i2c_unregister_device(c);
107 else 108 else
108 cx->i2c_clients[i] = c; 109 cx->i2c_clients[i] = c;
109 return cx->i2c_clients[i] ? 0 : -ENODEV; 110 return cx->i2c_clients[i] ? 0 : -ENODEV;
110 } 111 }
111 112
112 /* special tuner handling */ 113 /* special tuner handling */
113 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->radio); 114 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->radio);
114 if (c && c->driver == NULL) 115 if (c && c->driver == NULL)
115 i2c_unregister_device(c); 116 i2c_unregister_device(c);
116 else if (c) 117 else if (c)
117 cx->i2c_clients[i++] = c; 118 cx->i2c_clients[i++] = c;
118 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->demod); 119 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->demod);
119 if (c && c->driver == NULL) 120 if (c && c->driver == NULL)
120 i2c_unregister_device(c); 121 i2c_unregister_device(c);
121 else if (c) 122 else if (c)
122 cx->i2c_clients[i++] = c; 123 cx->i2c_clients[i++] = c;
123 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->tv); 124 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->tv);
124 if (c && c->driver == NULL) 125 if (c && c->driver == NULL)
125 i2c_unregister_device(c); 126 i2c_unregister_device(c);
126 else if (c) 127 else if (c)
127 cx->i2c_clients[i++] = c; 128 cx->i2c_clients[i++] = c;
128 return 0; 129 return 0;
129 } 130 }
130 131
131 static int attach_inform(struct i2c_client *client) 132 static int attach_inform(struct i2c_client *client)
132 { 133 {
133 return 0; 134 return 0;
134 } 135 }
135 136
136 static int detach_inform(struct i2c_client *client) 137 static int detach_inform(struct i2c_client *client)
137 { 138 {
138 int i; 139 int i;
139 struct cx18 *cx = (struct cx18 *)i2c_get_adapdata(client->adapter); 140 struct cx18 *cx = (struct cx18 *)i2c_get_adapdata(client->adapter);
140 141
141 CX18_DEBUG_I2C("i2c client detach\n"); 142 CX18_DEBUG_I2C("i2c client detach\n");
142 for (i = 0; i < I2C_CLIENTS_MAX; i++) { 143 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
143 if (cx->i2c_clients[i] == client) { 144 if (cx->i2c_clients[i] == client) {
144 cx->i2c_clients[i] = NULL; 145 cx->i2c_clients[i] = NULL;
145 break; 146 break;
146 } 147 }
147 } 148 }
148 CX18_DEBUG_I2C("i2c detach [client=%s,%s]\n", 149 CX18_DEBUG_I2C("i2c detach [client=%s,%s]\n",
149 client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed"); 150 client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");
150 151
151 return 0; 152 return 0;
152 } 153 }
153 154
154 static void cx18_setscl(void *data, int state) 155 static void cx18_setscl(void *data, int state)
155 { 156 {
156 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; 157 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
157 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; 158 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
158 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR; 159 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
159 u32 r = read_reg(addr); 160 u32 r = cx18_read_reg(cx, addr);
160 161
161 if (state) 162 if (state)
162 write_reg_sync(r | SETSCL_BIT, addr); 163 cx18_write_reg_sync(cx, r | SETSCL_BIT, addr);
163 else 164 else
164 write_reg_sync(r & ~SETSCL_BIT, addr); 165 cx18_write_reg_sync(cx, r & ~SETSCL_BIT, addr);
165 } 166 }
166 167
167 static void cx18_setsda(void *data, int state) 168 static void cx18_setsda(void *data, int state)
168 { 169 {
169 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; 170 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
170 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; 171 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
171 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR; 172 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
172 u32 r = read_reg(addr); 173 u32 r = cx18_read_reg(cx, addr);
173 174
174 if (state) 175 if (state)
175 write_reg_sync(r | SETSDL_BIT, addr); 176 cx18_write_reg_sync(cx, r | SETSDL_BIT, addr);
176 else 177 else
177 write_reg_sync(r & ~SETSDL_BIT, addr); 178 cx18_write_reg_sync(cx, r & ~SETSDL_BIT, addr);
178 } 179 }
179 180
180 static int cx18_getscl(void *data) 181 static int cx18_getscl(void *data)
181 { 182 {
182 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; 183 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
183 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; 184 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
184 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD; 185 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
185 186
186 return read_reg(addr) & GETSCL_BIT; 187 return cx18_read_reg(cx, addr) & GETSCL_BIT;
187 } 188 }
188 189
189 static int cx18_getsda(void *data) 190 static int cx18_getsda(void *data)
190 { 191 {
191 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; 192 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
192 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; 193 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
193 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD; 194 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
194 195
195 return read_reg(addr) & GETSDL_BIT; 196 return cx18_read_reg(cx, addr) & GETSDL_BIT;
196 } 197 }
197 198
198 /* template for i2c-bit-algo */ 199 /* template for i2c-bit-algo */
199 static struct i2c_adapter cx18_i2c_adap_template = { 200 static struct i2c_adapter cx18_i2c_adap_template = {
200 .name = "cx18 i2c driver", 201 .name = "cx18 i2c driver",
201 .id = I2C_HW_B_CX2341X, 202 .id = I2C_HW_B_CX2341X,
202 .algo = NULL, /* set by i2c-algo-bit */ 203 .algo = NULL, /* set by i2c-algo-bit */
203 .algo_data = NULL, /* filled from template */ 204 .algo_data = NULL, /* filled from template */
204 .client_register = attach_inform, 205 .client_register = attach_inform,
205 .client_unregister = detach_inform, 206 .client_unregister = detach_inform,
206 .owner = THIS_MODULE, 207 .owner = THIS_MODULE,
207 }; 208 };
208 209
209 #define CX18_SCL_PERIOD (10) /* usecs. 10 usec is period for a 100 KHz clock */ 210 #define CX18_SCL_PERIOD (10) /* usecs. 10 usec is period for a 100 KHz clock */
210 #define CX18_ALGO_BIT_TIMEOUT (2) /* seconds */ 211 #define CX18_ALGO_BIT_TIMEOUT (2) /* seconds */
211 212
212 static struct i2c_algo_bit_data cx18_i2c_algo_template = { 213 static struct i2c_algo_bit_data cx18_i2c_algo_template = {
213 .setsda = cx18_setsda, 214 .setsda = cx18_setsda,
214 .setscl = cx18_setscl, 215 .setscl = cx18_setscl,
215 .getsda = cx18_getsda, 216 .getsda = cx18_getsda,
216 .getscl = cx18_getscl, 217 .getscl = cx18_getscl,
217 .udelay = CX18_SCL_PERIOD/2, /* 1/2 clock period in usec*/ 218 .udelay = CX18_SCL_PERIOD/2, /* 1/2 clock period in usec*/
218 .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */ 219 .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
219 }; 220 };
220 221
221 static struct i2c_client cx18_i2c_client_template = { 222 static struct i2c_client cx18_i2c_client_template = {
222 .name = "cx18 internal", 223 .name = "cx18 internal",
223 }; 224 };
224 225
225 int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg) 226 int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg)
226 { 227 {
227 struct i2c_client *client; 228 struct i2c_client *client;
228 int retval; 229 int retval;
229 int i; 230 int i;
230 231
231 CX18_DEBUG_I2C("call_i2c_client addr=%02x\n", addr); 232 CX18_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
232 for (i = 0; i < I2C_CLIENTS_MAX; i++) { 233 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
233 client = cx->i2c_clients[i]; 234 client = cx->i2c_clients[i];
234 if (client == NULL || client->driver == NULL || 235 if (client == NULL || client->driver == NULL ||
235 client->driver->command == NULL) 236 client->driver->command == NULL)
236 continue; 237 continue;
237 if (addr == client->addr) { 238 if (addr == client->addr) {
238 retval = client->driver->command(client, cmd, arg); 239 retval = client->driver->command(client, cmd, arg);
239 return retval; 240 return retval;
240 } 241 }
241 } 242 }
242 if (cmd != VIDIOC_G_CHIP_IDENT) 243 if (cmd != VIDIOC_G_CHIP_IDENT)
243 CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n", 244 CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n",
244 addr, cmd); 245 addr, cmd);
245 return -ENODEV; 246 return -ENODEV;
246 } 247 }
247 248
248 /* Find the i2c device based on the driver ID and return 249 /* Find the i2c device based on the driver ID and return
249 its i2c address or -ENODEV if no matching device was found. */ 250 its i2c address or -ENODEV if no matching device was found. */
250 static int cx18_i2c_id_addr(struct cx18 *cx, u32 id) 251 static int cx18_i2c_id_addr(struct cx18 *cx, u32 id)
251 { 252 {
252 struct i2c_client *client; 253 struct i2c_client *client;
253 int retval = -ENODEV; 254 int retval = -ENODEV;
254 int i; 255 int i;
255 256
256 for (i = 0; i < I2C_CLIENTS_MAX; i++) { 257 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
257 client = cx->i2c_clients[i]; 258 client = cx->i2c_clients[i];
258 if (client == NULL || client->driver == NULL) 259 if (client == NULL || client->driver == NULL)
259 continue; 260 continue;
260 if (id == client->driver->id) { 261 if (id == client->driver->id) {
261 retval = client->addr; 262 retval = client->addr;
262 break; 263 break;
263 } 264 }
264 } 265 }
265 return retval; 266 return retval;
266 } 267 }
267 268
268 /* Find the i2c device name matching the DRIVERID */ 269 /* Find the i2c device name matching the DRIVERID */
269 static const char *cx18_i2c_id_name(u32 id) 270 static const char *cx18_i2c_id_name(u32 id)
270 { 271 {
271 int i; 272 int i;
272 273
273 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) 274 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
274 if (hw_driverids[i] == id) 275 if (hw_driverids[i] == id)
275 return hw_devicenames[i]; 276 return hw_devicenames[i];
276 return "unknown device"; 277 return "unknown device";
277 } 278 }
278 279
279 /* Find the i2c device name matching the CX18_HW_ flag */ 280 /* Find the i2c device name matching the CX18_HW_ flag */
280 static const char *cx18_i2c_hw_name(u32 hw) 281 static const char *cx18_i2c_hw_name(u32 hw)
281 { 282 {
282 int i; 283 int i;
283 284
284 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) 285 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
285 if (1 << i == hw) 286 if (1 << i == hw)
286 return hw_devicenames[i]; 287 return hw_devicenames[i];
287 return "unknown device"; 288 return "unknown device";
288 } 289 }
289 290
290 /* Find the i2c device matching the CX18_HW_ flag and return 291 /* Find the i2c device matching the CX18_HW_ flag and return
291 its i2c address or -ENODEV if no matching device was found. */ 292 its i2c address or -ENODEV if no matching device was found. */
292 int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw) 293 int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw)
293 { 294 {
294 int i; 295 int i;
295 296
296 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) 297 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
297 if (1 << i == hw) 298 if (1 << i == hw)
298 return cx18_i2c_id_addr(cx, hw_driverids[i]); 299 return cx18_i2c_id_addr(cx, hw_driverids[i]);
299 return -ENODEV; 300 return -ENODEV;
300 } 301 }
301 302
302 /* Calls i2c device based on CX18_HW_ flag. If hw == 0, then do nothing. 303 /* Calls i2c device based on CX18_HW_ flag. If hw == 0, then do nothing.
303 If hw == CX18_HW_GPIO then call the gpio handler. */ 304 If hw == CX18_HW_GPIO then call the gpio handler. */
304 int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg) 305 int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg)
305 { 306 {
306 int addr; 307 int addr;
307 308
308 if (hw == 0) 309 if (hw == 0)
309 return 0; 310 return 0;
310 311
311 if (hw == CX18_HW_GPIO) 312 if (hw == CX18_HW_GPIO)
312 return cx18_gpio(cx, cmd, arg); 313 return cx18_gpio(cx, cmd, arg);
313 314
314 if (hw == CX18_HW_CX23418) 315 if (hw == CX18_HW_CX23418)
315 return cx18_av_cmd(cx, cmd, arg); 316 return cx18_av_cmd(cx, cmd, arg);
316 317
317 addr = cx18_i2c_hw_addr(cx, hw); 318 addr = cx18_i2c_hw_addr(cx, hw);
318 if (addr < 0) { 319 if (addr < 0) {
319 CX18_ERR("i2c hardware 0x%08x (%s) not found for cmd 0x%x!\n", 320 CX18_ERR("i2c hardware 0x%08x (%s) not found for cmd 0x%x!\n",
320 hw, cx18_i2c_hw_name(hw), cmd); 321 hw, cx18_i2c_hw_name(hw), cmd);
321 return addr; 322 return addr;
322 } 323 }
323 return cx18_call_i2c_client(cx, addr, cmd, arg); 324 return cx18_call_i2c_client(cx, addr, cmd, arg);
324 } 325 }
325 326
326 /* Calls i2c device based on I2C driver ID. */ 327 /* Calls i2c device based on I2C driver ID. */
327 int cx18_i2c_id(struct cx18 *cx, u32 id, unsigned int cmd, void *arg) 328 int cx18_i2c_id(struct cx18 *cx, u32 id, unsigned int cmd, void *arg)
328 { 329 {
329 int addr; 330 int addr;
330 331
331 addr = cx18_i2c_id_addr(cx, id); 332 addr = cx18_i2c_id_addr(cx, id);
332 if (addr < 0) { 333 if (addr < 0) {
333 if (cmd != VIDIOC_G_CHIP_IDENT) 334 if (cmd != VIDIOC_G_CHIP_IDENT)
334 CX18_ERR("i2c ID 0x%08x (%s) not found for cmd 0x%x!\n", 335 CX18_ERR("i2c ID 0x%08x (%s) not found for cmd 0x%x!\n",
335 id, cx18_i2c_id_name(id), cmd); 336 id, cx18_i2c_id_name(id), cmd);
336 return addr; 337 return addr;
337 } 338 }
338 return cx18_call_i2c_client(cx, addr, cmd, arg); 339 return cx18_call_i2c_client(cx, addr, cmd, arg);
339 } 340 }
340 341
341 /* broadcast cmd for all I2C clients and for the gpio subsystem */ 342 /* broadcast cmd for all I2C clients and for the gpio subsystem */
342 void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg) 343 void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg)
343 { 344 {
344 if (cx->i2c_adap[0].algo == NULL || cx->i2c_adap[1].algo == NULL) { 345 if (cx->i2c_adap[0].algo == NULL || cx->i2c_adap[1].algo == NULL) {
345 CX18_ERR("adapter is not set\n"); 346 CX18_ERR("adapter is not set\n");
346 return; 347 return;
347 } 348 }
348 cx18_av_cmd(cx, cmd, arg); 349 cx18_av_cmd(cx, cmd, arg);
349 i2c_clients_command(&cx->i2c_adap[0], cmd, arg); 350 i2c_clients_command(&cx->i2c_adap[0], cmd, arg);
350 i2c_clients_command(&cx->i2c_adap[1], cmd, arg); 351 i2c_clients_command(&cx->i2c_adap[1], cmd, arg);
351 if (cx->hw_flags & CX18_HW_GPIO) 352 if (cx->hw_flags & CX18_HW_GPIO)
352 cx18_gpio(cx, cmd, arg); 353 cx18_gpio(cx, cmd, arg);
353 } 354 }
354 355
355 /* init + register i2c algo-bit adapter */ 356 /* init + register i2c algo-bit adapter */
356 int init_cx18_i2c(struct cx18 *cx) 357 int init_cx18_i2c(struct cx18 *cx)
357 { 358 {
358 int i; 359 int i;
359 CX18_DEBUG_I2C("i2c init\n"); 360 CX18_DEBUG_I2C("i2c init\n");
360 361
361 /* Sanity checks for the I2C hardware arrays. They must be the 362 /* Sanity checks for the I2C hardware arrays. They must be the
362 * same size and GPIO/CX23418 must be the last entries. 363 * same size and GPIO/CX23418 must be the last entries.
363 */ 364 */
364 if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) || 365 if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) ||
365 ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) || 366 ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
366 CX18_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 2)) || 367 CX18_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 2)) ||
367 CX18_HW_CX23418 != (1 << (ARRAY_SIZE(hw_addrs) - 1)) || 368 CX18_HW_CX23418 != (1 << (ARRAY_SIZE(hw_addrs) - 1)) ||
368 hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) { 369 hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) {
369 CX18_ERR("Mismatched I2C hardware arrays\n"); 370 CX18_ERR("Mismatched I2C hardware arrays\n");
370 return -ENODEV; 371 return -ENODEV;
371 } 372 }
372 373
373 for (i = 0; i < 2; i++) { 374 for (i = 0; i < 2; i++) {
374 memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template, 375 memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
375 sizeof(struct i2c_adapter)); 376 sizeof(struct i2c_adapter));
376 memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template, 377 memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template,
377 sizeof(struct i2c_algo_bit_data)); 378 sizeof(struct i2c_algo_bit_data));
378 cx->i2c_algo_cb_data[i].cx = cx; 379 cx->i2c_algo_cb_data[i].cx = cx;
379 cx->i2c_algo_cb_data[i].bus_index = i; 380 cx->i2c_algo_cb_data[i].bus_index = i;
380 cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i]; 381 cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i];
381 cx->i2c_adap[i].algo_data = &cx->i2c_algo[i]; 382 cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
382 383
383 sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name), 384 sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
384 " #%d-%d", cx->num, i); 385 " #%d-%d", cx->num, i);
385 i2c_set_adapdata(&cx->i2c_adap[i], cx); 386 i2c_set_adapdata(&cx->i2c_adap[i], cx);
386 387
387 memcpy(&cx->i2c_client[i], &cx18_i2c_client_template, 388 memcpy(&cx->i2c_client[i], &cx18_i2c_client_template,
388 sizeof(struct i2c_client)); 389 sizeof(struct i2c_client));
389 sprintf(cx->i2c_client[i].name + 390 sprintf(cx->i2c_client[i].name +
390 strlen(cx->i2c_client[i].name), "%d", i); 391 strlen(cx->i2c_client[i].name), "%d", i);
391 cx->i2c_client[i].adapter = &cx->i2c_adap[i]; 392 cx->i2c_client[i].adapter = &cx->i2c_adap[i];
392 cx->i2c_adap[i].dev.parent = &cx->dev->dev; 393 cx->i2c_adap[i].dev.parent = &cx->dev->dev;
393 } 394 }
394 395
395 if (read_reg(CX18_REG_I2C_2_WR) != 0x0003c02f) { 396 if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
396 /* Reset/Unreset I2C hardware block */ 397 /* Reset/Unreset I2C hardware block */
397 write_reg(0x10000000, 0xc71004); /* Clock select 220MHz */ 398 /* Clock select 220MHz */
398 write_reg_sync(0x10001000, 0xc71024); /* Clock Enable */ 399 cx18_write_reg(cx, 0x10000000, 0xc71004);
400 /* Clock Enable */
401 cx18_write_reg_sync(cx, 0x10001000, 0xc71024);
399 } 402 }
400 /* courtesy of Steven Toth <stoth@hauppauge.com> */ 403 /* courtesy of Steven Toth <stoth@hauppauge.com> */
401 write_reg_sync(0x00c00000, 0xc7001c); 404 cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c);
402 mdelay(10); 405 mdelay(10);
403 write_reg_sync(0x00c000c0, 0xc7001c); 406 cx18_write_reg_sync(cx, 0x00c000c0, 0xc7001c);
404 mdelay(10); 407 mdelay(10);
405 write_reg_sync(0x00c00000, 0xc7001c); 408 cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c);
406 mdelay(10); 409 mdelay(10);
407 410
408 write_reg_sync(0x00c00000, 0xc730c8); /* Set to edge-triggered intrs. */ 411 /* Set to edge-triggered intrs. */
409 write_reg_sync(0x00c00000, 0xc730c4); /* Clear any stale intrs */ 412 cx18_write_reg_sync(cx, 0x00c00000, 0xc730c8);
413 /* Clear any stale intrs */
414 cx18_write_reg_sync(cx, 0x00c00000, 0xc730c4);
410 415
411 /* Hw I2C1 Clock Freq ~100kHz */ 416 /* Hw I2C1 Clock Freq ~100kHz */
412 write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_1_WR); 417 cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
413 cx18_setscl(&cx->i2c_algo_cb_data[0], 1); 418 cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
414 cx18_setsda(&cx->i2c_algo_cb_data[0], 1); 419 cx18_setsda(&cx->i2c_algo_cb_data[0], 1);
415 420
416 /* Hw I2C2 Clock Freq ~100kHz */ 421 /* Hw I2C2 Clock Freq ~100kHz */
417 write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_2_WR); 422 cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR);
418 cx18_setscl(&cx->i2c_algo_cb_data[1], 1); 423 cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
419 cx18_setsda(&cx->i2c_algo_cb_data[1], 1); 424 cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
420 425
421 cx18_reset_i2c_slaves_gpio(cx); 426 cx18_reset_i2c_slaves_gpio(cx);
422 427
423 return i2c_bit_add_bus(&cx->i2c_adap[0]) || 428 return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
424 i2c_bit_add_bus(&cx->i2c_adap[1]); 429 i2c_bit_add_bus(&cx->i2c_adap[1]);
425 } 430 }
426 431
427 void exit_cx18_i2c(struct cx18 *cx) 432 void exit_cx18_i2c(struct cx18 *cx)
428 { 433 {
429 int i; 434 int i;
430 CX18_DEBUG_I2C("i2c exit\n"); 435 CX18_DEBUG_I2C("i2c exit\n");
431 write_reg(read_reg(CX18_REG_I2C_1_WR) | 4, CX18_REG_I2C_1_WR); 436 cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_1_WR) | 4,
432 write_reg(read_reg(CX18_REG_I2C_2_WR) | 4, CX18_REG_I2C_2_WR); 437 CX18_REG_I2C_1_WR);
438 cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_2_WR) | 4,
439 CX18_REG_I2C_2_WR);
433 440
434 for (i = 0; i < 2; i++) { 441 for (i = 0; i < 2; i++) {
435 i2c_del_adapter(&cx->i2c_adap[i]); 442 i2c_del_adapter(&cx->i2c_adap[i]);
436 } 443 }
437 } 444 }
438 445
439 /* 446 /*
440 Hauppauge HVR1600 should have: 447 Hauppauge HVR1600 should have:
441 32 cx24227 448 32 cx24227
442 98 unknown 449 98 unknown
443 a0 eeprom 450 a0 eeprom
444 c2 tuner 451 c2 tuner
445 e? zilog ir 452 e? zilog ir
446 */ 453 */
447 454
drivers/media/video/cx18/cx18-io.c
File was created 1 /*
2 * cx18 driver PCI memory mapped IO access routines
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
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 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23 #include "cx18-driver.h"
24 #include "cx18-irq.h"
25
26 void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
27 {
28 __raw_writel(val, addr);
29 }
30
31 u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
32 {
33 return __raw_readl(addr);
34 }
35
36 u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr)
37 {
38 writel(val, addr);
39 return readl(addr);
40 }
41
42 void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
43 {
44 writel(val, addr);
45 }
46
47 u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
48 {
49 return readl(addr);
50 }
51
52
53 /* Access "register" region of CX23418 memory mapped I/O */
54 u32 cx18_read_reg(struct cx18 *cx, u32 reg)
55 {
56 return readl(cx->reg_mem + reg);
57 }
58
59 void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
60 {
61 writel(val, cx->reg_mem + reg);
62 }
63
64 u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg)
65 {
66 return cx18_write_sync(cx, val, cx->reg_mem + reg);
67 }
68
69 /* Access "encoder memory" region of CX23418 memory mapped I/O */
70 u32 cx18_read_enc(struct cx18 *cx, u32 addr)
71 {
72 return readl(cx->enc_mem + addr);
73 }
74
75 void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
76 {
77 writel(val, cx->enc_mem + addr);
78 }
79
80 u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr)
81 {
82 return cx18_write_sync(cx, val, cx->enc_mem + addr);
83 }
84
85 void cx18_memcpy_fromio(struct cx18 *cx, void *to,
86 const void __iomem *from, unsigned int len)
87 {
88 memcpy_fromio(to, from, len);
89 }
90
91 void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count)
92 {
93 memset_io(addr, val, count);
94 }
95
96 void cx18_sw1_irq_enable(struct cx18 *cx, u32 val)
97 {
98 u32 r;
99 cx18_write_reg(cx, val, SW1_INT_STATUS);
100 r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI);
101 cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI);
102 }
103
104 void cx18_sw1_irq_disable(struct cx18 *cx, u32 val)
105 {
106 u32 r;
107 r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI);
108 cx18_write_reg(cx, r & ~val, SW1_INT_ENABLE_PCI);
109 }
110
111 void cx18_sw2_irq_enable(struct cx18 *cx, u32 val)
112 {
113 u32 r;
114 cx18_write_reg(cx, val, SW2_INT_STATUS);
115 r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI);
116 cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI);
117 }
118
119 void cx18_sw2_irq_disable(struct cx18 *cx, u32 val)
120 {
121 u32 r;
122 r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI);
123 cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_PCI);
124 }
125
126 void cx18_setup_page(struct cx18 *cx, u32 addr)
127 {
128 u32 val;
129 val = cx18_read_reg(cx, 0xD000F8);
130 val = (val & ~0x1f00) | ((addr >> 17) & 0x1f00);
131 cx18_write_reg(cx, val, 0xD000F8);
132 }
133
134 /* Tries to recover from the CX23418 responding improperly on the PCI bus */
135 int cx18_pci_try_recover(struct cx18 *cx)
136 {
137 u16 status;
138
139 pci_read_config_word(cx->dev, PCI_STATUS, &status);
140 pci_write_config_word(cx->dev, PCI_STATUS, status);
141 return 0;
142 }
143
drivers/media/video/cx18/cx18-io.h
File was created 1 /*
2 * cx18 driver PCI memory mapped IO access routines
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
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 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 */
22
23 #ifndef CX18_IO_H
24 #define CX18_IO_H
25
26 #include "cx18-driver.h"
27
28 /* This is a PCI post thing, where if the pci register is not read, then
29 the write doesn't always take effect right away. By reading back the
30 register any pending PCI writes will be performed (in order), and so
31 you can be sure that the writes are guaranteed to be done.
32
33 Rarely needed, only in some timing sensitive cases.
34 Apparently if this is not done some motherboards seem
35 to kill the firmware and get into the broken state until computer is
36 rebooted. */
37 u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr);
38
39 void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr);
40 u32 cx18_readl(struct cx18 *cx, const void __iomem *addr);
41
42 /* No endiannes conversion calls */
43 void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr);
44 u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr);
45
46 /* Access "register" region of CX23418 memory mapped I/O */
47 u32 cx18_read_reg(struct cx18 *cx, u32 reg);
48 void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg);
49 u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg);
50
51 /* Access "encoder memory" region of CX23418 memory mapped I/O */
52 u32 cx18_read_enc(struct cx18 *cx, u32 addr);
53 void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr);
54 u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr);
55
56 void cx18_memcpy_fromio(struct cx18 *cx, void *to,
57 const void __iomem *from, unsigned int len);
58 void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count);
59
60 void cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
61 void cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
62 void cx18_sw2_irq_enable(struct cx18 *cx, u32 val);
63 void cx18_sw2_irq_disable(struct cx18 *cx, u32 val);
64 void cx18_setup_page(struct cx18 *cx, u32 addr);
65
66 /* Tries to recover from the CX23418 responding improperly on the PCI bus */
67 int cx18_pci_try_recover(struct cx18 *cx);
68
69 #endif /* CX18_IO_H */
70
drivers/media/video/cx18/cx18-ioctl.c
1 /* 1 /*
2 * cx18 ioctl system call 2 * cx18 ioctl system call
3 * 3 *
4 * Derived from ivtv-ioctl.c 4 * Derived from ivtv-ioctl.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 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 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 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 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24 #include "cx18-driver.h" 24 #include "cx18-driver.h"
25 #include "cx18-io.h"
25 #include "cx18-version.h" 26 #include "cx18-version.h"
26 #include "cx18-mailbox.h" 27 #include "cx18-mailbox.h"
27 #include "cx18-i2c.h" 28 #include "cx18-i2c.h"
28 #include "cx18-queue.h" 29 #include "cx18-queue.h"
29 #include "cx18-fileops.h" 30 #include "cx18-fileops.h"
30 #include "cx18-vbi.h" 31 #include "cx18-vbi.h"
31 #include "cx18-audio.h" 32 #include "cx18-audio.h"
32 #include "cx18-video.h" 33 #include "cx18-video.h"
33 #include "cx18-streams.h" 34 #include "cx18-streams.h"
34 #include "cx18-ioctl.h" 35 #include "cx18-ioctl.h"
35 #include "cx18-gpio.h" 36 #include "cx18-gpio.h"
36 #include "cx18-controls.h" 37 #include "cx18-controls.h"
37 #include "cx18-cards.h" 38 #include "cx18-cards.h"
38 #include "cx18-av-core.h" 39 #include "cx18-av-core.h"
39 #include <media/tveeprom.h> 40 #include <media/tveeprom.h>
40 #include <media/v4l2-chip-ident.h> 41 #include <media/v4l2-chip-ident.h>
41 #include <linux/i2c-id.h> 42 #include <linux/i2c-id.h>
42 43
43 u16 cx18_service2vbi(int type) 44 u16 cx18_service2vbi(int type)
44 { 45 {
45 switch (type) { 46 switch (type) {
46 case V4L2_SLICED_TELETEXT_B: 47 case V4L2_SLICED_TELETEXT_B:
47 return CX18_SLICED_TYPE_TELETEXT_B; 48 return CX18_SLICED_TYPE_TELETEXT_B;
48 case V4L2_SLICED_CAPTION_525: 49 case V4L2_SLICED_CAPTION_525:
49 return CX18_SLICED_TYPE_CAPTION_525; 50 return CX18_SLICED_TYPE_CAPTION_525;
50 case V4L2_SLICED_WSS_625: 51 case V4L2_SLICED_WSS_625:
51 return CX18_SLICED_TYPE_WSS_625; 52 return CX18_SLICED_TYPE_WSS_625;
52 case V4L2_SLICED_VPS: 53 case V4L2_SLICED_VPS:
53 return CX18_SLICED_TYPE_VPS; 54 return CX18_SLICED_TYPE_VPS;
54 default: 55 default:
55 return 0; 56 return 0;
56 } 57 }
57 } 58 }
58 59
59 static int valid_service_line(int field, int line, int is_pal) 60 static int valid_service_line(int field, int line, int is_pal)
60 { 61 {
61 return (is_pal && line >= 6 && (line != 23 || field == 0)) || 62 return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
62 (!is_pal && line >= 10 && line < 22); 63 (!is_pal && line >= 10 && line < 22);
63 } 64 }
64 65
65 static u16 select_service_from_set(int field, int line, u16 set, int is_pal) 66 static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
66 { 67 {
67 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525); 68 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
68 int i; 69 int i;
69 70
70 set = set & valid_set; 71 set = set & valid_set;
71 if (set == 0 || !valid_service_line(field, line, is_pal)) 72 if (set == 0 || !valid_service_line(field, line, is_pal))
72 return 0; 73 return 0;
73 if (!is_pal) { 74 if (!is_pal) {
74 if (line == 21 && (set & V4L2_SLICED_CAPTION_525)) 75 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
75 return V4L2_SLICED_CAPTION_525; 76 return V4L2_SLICED_CAPTION_525;
76 } else { 77 } else {
77 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS)) 78 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
78 return V4L2_SLICED_VPS; 79 return V4L2_SLICED_VPS;
79 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625)) 80 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
80 return V4L2_SLICED_WSS_625; 81 return V4L2_SLICED_WSS_625;
81 if (line == 23) 82 if (line == 23)
82 return 0; 83 return 0;
83 } 84 }
84 for (i = 0; i < 32; i++) { 85 for (i = 0; i < 32; i++) {
85 if ((1 << i) & set) 86 if ((1 << i) & set)
86 return 1 << i; 87 return 1 << i;
87 } 88 }
88 return 0; 89 return 0;
89 } 90 }
90 91
91 void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) 92 void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
92 { 93 {
93 u16 set = fmt->service_set; 94 u16 set = fmt->service_set;
94 int f, l; 95 int f, l;
95 96
96 fmt->service_set = 0; 97 fmt->service_set = 0;
97 for (f = 0; f < 2; f++) { 98 for (f = 0; f < 2; f++) {
98 for (l = 0; l < 24; l++) 99 for (l = 0; l < 24; l++)
99 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal); 100 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
100 } 101 }
101 } 102 }
102 103
103 104
104 u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt) 105 u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
105 { 106 {
106 int f, l; 107 int f, l;
107 u16 set = 0; 108 u16 set = 0;
108 109
109 for (f = 0; f < 2; f++) { 110 for (f = 0; f < 2; f++) {
110 for (l = 0; l < 24; l++) 111 for (l = 0; l < 24; l++)
111 set |= fmt->service_lines[f][l]; 112 set |= fmt->service_lines[f][l];
112 } 113 }
113 return set; 114 return set;
114 } 115 }
115 116
116 static int cx18_g_fmt_vid_cap(struct file *file, void *fh, 117 static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
117 struct v4l2_format *fmt) 118 struct v4l2_format *fmt)
118 { 119 {
119 struct cx18_open_id *id = fh; 120 struct cx18_open_id *id = fh;
120 struct cx18 *cx = id->cx; 121 struct cx18 *cx = id->cx;
121 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 122 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
122 123
123 pixfmt->width = cx->params.width; 124 pixfmt->width = cx->params.width;
124 pixfmt->height = cx->params.height; 125 pixfmt->height = cx->params.height;
125 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; 126 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
126 pixfmt->field = V4L2_FIELD_INTERLACED; 127 pixfmt->field = V4L2_FIELD_INTERLACED;
127 pixfmt->priv = 0; 128 pixfmt->priv = 0;
128 if (id->type == CX18_ENC_STREAM_TYPE_YUV) { 129 if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
129 pixfmt->pixelformat = V4L2_PIX_FMT_HM12; 130 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
130 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ 131 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
131 pixfmt->sizeimage = 132 pixfmt->sizeimage =
132 pixfmt->height * pixfmt->width + 133 pixfmt->height * pixfmt->width +
133 pixfmt->height * (pixfmt->width / 2); 134 pixfmt->height * (pixfmt->width / 2);
134 pixfmt->bytesperline = 720; 135 pixfmt->bytesperline = 720;
135 } else { 136 } else {
136 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; 137 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
137 pixfmt->sizeimage = 128 * 1024; 138 pixfmt->sizeimage = 128 * 1024;
138 pixfmt->bytesperline = 0; 139 pixfmt->bytesperline = 0;
139 } 140 }
140 return 0; 141 return 0;
141 } 142 }
142 143
143 static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, 144 static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
144 struct v4l2_format *fmt) 145 struct v4l2_format *fmt)
145 { 146 {
146 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 147 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
147 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; 148 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
148 149
149 vbifmt->sampling_rate = 27000000; 150 vbifmt->sampling_rate = 27000000;
150 vbifmt->offset = 248; 151 vbifmt->offset = 248;
151 vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4; 152 vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4;
152 vbifmt->sample_format = V4L2_PIX_FMT_GREY; 153 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
153 vbifmt->start[0] = cx->vbi.start[0]; 154 vbifmt->start[0] = cx->vbi.start[0];
154 vbifmt->start[1] = cx->vbi.start[1]; 155 vbifmt->start[1] = cx->vbi.start[1];
155 vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count; 156 vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count;
156 vbifmt->flags = 0; 157 vbifmt->flags = 0;
157 vbifmt->reserved[0] = 0; 158 vbifmt->reserved[0] = 0;
158 vbifmt->reserved[1] = 0; 159 vbifmt->reserved[1] = 0;
159 return 0; 160 return 0;
160 } 161 }
161 162
162 static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, 163 static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
163 struct v4l2_format *fmt) 164 struct v4l2_format *fmt)
164 { 165 {
165 return -EINVAL; 166 return -EINVAL;
166 } 167 }
167 168
168 static int cx18_try_fmt_vid_cap(struct file *file, void *fh, 169 static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
169 struct v4l2_format *fmt) 170 struct v4l2_format *fmt)
170 { 171 {
171 struct cx18_open_id *id = fh; 172 struct cx18_open_id *id = fh;
172 struct cx18 *cx = id->cx; 173 struct cx18 *cx = id->cx;
173 174
174 int w = fmt->fmt.pix.width; 175 int w = fmt->fmt.pix.width;
175 int h = fmt->fmt.pix.height; 176 int h = fmt->fmt.pix.height;
176 177
177 w = min(w, 720); 178 w = min(w, 720);
178 w = max(w, 1); 179 w = max(w, 1);
179 h = min(h, cx->is_50hz ? 576 : 480); 180 h = min(h, cx->is_50hz ? 576 : 480);
180 h = max(h, 2); 181 h = max(h, 2);
181 cx18_g_fmt_vid_cap(file, fh, fmt); 182 cx18_g_fmt_vid_cap(file, fh, fmt);
182 fmt->fmt.pix.width = w; 183 fmt->fmt.pix.width = w;
183 fmt->fmt.pix.height = h; 184 fmt->fmt.pix.height = h;
184 return 0; 185 return 0;
185 } 186 }
186 187
187 static int cx18_try_fmt_vbi_cap(struct file *file, void *fh, 188 static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
188 struct v4l2_format *fmt) 189 struct v4l2_format *fmt)
189 { 190 {
190 return cx18_g_fmt_vbi_cap(file, fh, fmt); 191 return cx18_g_fmt_vbi_cap(file, fh, fmt);
191 } 192 }
192 193
193 static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, 194 static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
194 struct v4l2_format *fmt) 195 struct v4l2_format *fmt)
195 { 196 {
196 return -EINVAL; 197 return -EINVAL;
197 } 198 }
198 199
199 static int cx18_s_fmt_vid_cap(struct file *file, void *fh, 200 static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
200 struct v4l2_format *fmt) 201 struct v4l2_format *fmt)
201 { 202 {
202 struct cx18_open_id *id = fh; 203 struct cx18_open_id *id = fh;
203 struct cx18 *cx = id->cx; 204 struct cx18 *cx = id->cx;
204 int ret; 205 int ret;
205 int w = fmt->fmt.pix.width; 206 int w = fmt->fmt.pix.width;
206 int h = fmt->fmt.pix.height; 207 int h = fmt->fmt.pix.height;
207 208
208 ret = v4l2_prio_check(&cx->prio, &id->prio); 209 ret = v4l2_prio_check(&cx->prio, &id->prio);
209 if (ret) 210 if (ret)
210 return ret; 211 return ret;
211 212
212 ret = cx18_try_fmt_vid_cap(file, fh, fmt); 213 ret = cx18_try_fmt_vid_cap(file, fh, fmt);
213 if (ret) 214 if (ret)
214 return ret; 215 return ret;
215 216
216 if (cx->params.width == w && cx->params.height == h) 217 if (cx->params.width == w && cx->params.height == h)
217 return 0; 218 return 0;
218 219
219 if (atomic_read(&cx->ana_capturing) > 0) 220 if (atomic_read(&cx->ana_capturing) > 0)
220 return -EBUSY; 221 return -EBUSY;
221 222
222 cx->params.width = w; 223 cx->params.width = w;
223 cx->params.height = h; 224 cx->params.height = h;
224 cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); 225 cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
225 return cx18_g_fmt_vid_cap(file, fh, fmt); 226 return cx18_g_fmt_vid_cap(file, fh, fmt);
226 } 227 }
227 228
228 static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, 229 static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
229 struct v4l2_format *fmt) 230 struct v4l2_format *fmt)
230 { 231 {
231 struct cx18_open_id *id = fh; 232 struct cx18_open_id *id = fh;
232 struct cx18 *cx = id->cx; 233 struct cx18 *cx = id->cx;
233 int ret; 234 int ret;
234 235
235 ret = v4l2_prio_check(&cx->prio, &id->prio); 236 ret = v4l2_prio_check(&cx->prio, &id->prio);
236 if (ret) 237 if (ret)
237 return ret; 238 return ret;
238 239
239 if (id->type == CX18_ENC_STREAM_TYPE_VBI && 240 if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
240 cx->vbi.sliced_in->service_set && 241 cx->vbi.sliced_in->service_set &&
241 atomic_read(&cx->ana_capturing) > 0) 242 atomic_read(&cx->ana_capturing) > 0)
242 return -EBUSY; 243 return -EBUSY;
243 244
244 cx->vbi.sliced_in->service_set = 0; 245 cx->vbi.sliced_in->service_set = 0;
245 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); 246 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
246 return cx18_g_fmt_vbi_cap(file, fh, fmt); 247 return cx18_g_fmt_vbi_cap(file, fh, fmt);
247 } 248 }
248 249
249 static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, 250 static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
250 struct v4l2_format *fmt) 251 struct v4l2_format *fmt)
251 { 252 {
252 return -EINVAL; 253 return -EINVAL;
253 } 254 }
254 255
255 static int cx18_g_chip_ident(struct file *file, void *fh, 256 static int cx18_g_chip_ident(struct file *file, void *fh,
256 struct v4l2_chip_ident *chip) 257 struct v4l2_chip_ident *chip)
257 { 258 {
258 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 259 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
259 260
260 chip->ident = V4L2_IDENT_NONE; 261 chip->ident = V4L2_IDENT_NONE;
261 chip->revision = 0; 262 chip->revision = 0;
262 if (chip->match_type == V4L2_CHIP_MATCH_HOST) { 263 if (chip->match_type == V4L2_CHIP_MATCH_HOST) {
263 if (v4l2_chip_match_host(chip->match_type, chip->match_chip)) 264 if (v4l2_chip_match_host(chip->match_type, chip->match_chip))
264 chip->ident = V4L2_IDENT_CX23418; 265 chip->ident = V4L2_IDENT_CX23418;
265 return 0; 266 return 0;
266 } 267 }
267 if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) 268 if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
268 return cx18_i2c_id(cx, chip->match_chip, VIDIOC_G_CHIP_IDENT, 269 return cx18_i2c_id(cx, chip->match_chip, VIDIOC_G_CHIP_IDENT,
269 chip); 270 chip);
270 if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR) 271 if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
271 return cx18_call_i2c_client(cx, chip->match_chip, 272 return cx18_call_i2c_client(cx, chip->match_chip,
272 VIDIOC_G_CHIP_IDENT, chip); 273 VIDIOC_G_CHIP_IDENT, chip);
273 return -EINVAL; 274 return -EINVAL;
274 } 275 }
275 276
276 #ifdef CONFIG_VIDEO_ADV_DEBUG 277 #ifdef CONFIG_VIDEO_ADV_DEBUG
277 static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) 278 static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
278 { 279 {
279 struct v4l2_register *regs = arg; 280 struct v4l2_register *regs = arg;
280 unsigned long flags; 281 unsigned long flags;
281 282
282 if (!capable(CAP_SYS_ADMIN)) 283 if (!capable(CAP_SYS_ADMIN))
283 return -EPERM; 284 return -EPERM;
284 if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) 285 if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
285 return -EINVAL; 286 return -EINVAL;
286 287
287 spin_lock_irqsave(&cx18_cards_lock, flags); 288 spin_lock_irqsave(&cx18_cards_lock, flags);
288 if (cmd == VIDIOC_DBG_G_REGISTER) 289 if (cmd == VIDIOC_DBG_G_REGISTER)
289 regs->val = read_enc(regs->reg); 290 regs->val = cx18_read_enc(cx, regs->reg);
290 else 291 else
291 write_enc(regs->val, regs->reg); 292 cx18_write_enc(cx, regs->val, regs->reg);
292 spin_unlock_irqrestore(&cx18_cards_lock, flags); 293 spin_unlock_irqrestore(&cx18_cards_lock, flags);
293 return 0; 294 return 0;
294 } 295 }
295 296
296 static int cx18_g_register(struct file *file, void *fh, 297 static int cx18_g_register(struct file *file, void *fh,
297 struct v4l2_register *reg) 298 struct v4l2_register *reg)
298 { 299 {
299 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 300 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
300 301
301 if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) 302 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
302 return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); 303 return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
303 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) 304 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
304 return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER, 305 return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER,
305 reg); 306 reg);
306 return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER, 307 return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER,
307 reg); 308 reg);
308 } 309 }
309 310
310 static int cx18_s_register(struct file *file, void *fh, 311 static int cx18_s_register(struct file *file, void *fh,
311 struct v4l2_register *reg) 312 struct v4l2_register *reg)
312 { 313 {
313 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 314 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
314 315
315 if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) 316 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
316 return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); 317 return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
317 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) 318 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
318 return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER, 319 return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER,
319 reg); 320 reg);
320 return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER, 321 return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER,
321 reg); 322 reg);
322 } 323 }
323 #endif 324 #endif
324 325
325 static int cx18_g_priority(struct file *file, void *fh, enum v4l2_priority *p) 326 static int cx18_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
326 { 327 {
327 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 328 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
328 329
329 *p = v4l2_prio_max(&cx->prio); 330 *p = v4l2_prio_max(&cx->prio);
330 return 0; 331 return 0;
331 } 332 }
332 333
333 static int cx18_s_priority(struct file *file, void *fh, enum v4l2_priority prio) 334 static int cx18_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
334 { 335 {
335 struct cx18_open_id *id = fh; 336 struct cx18_open_id *id = fh;
336 struct cx18 *cx = id->cx; 337 struct cx18 *cx = id->cx;
337 338
338 return v4l2_prio_change(&cx->prio, &id->prio, prio); 339 return v4l2_prio_change(&cx->prio, &id->prio, prio);
339 } 340 }
340 341
341 static int cx18_querycap(struct file *file, void *fh, 342 static int cx18_querycap(struct file *file, void *fh,
342 struct v4l2_capability *vcap) 343 struct v4l2_capability *vcap)
343 { 344 {
344 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 345 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
345 346
346 strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); 347 strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
347 strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); 348 strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
348 strlcpy(vcap->bus_info, pci_name(cx->dev), sizeof(vcap->bus_info)); 349 strlcpy(vcap->bus_info, pci_name(cx->dev), sizeof(vcap->bus_info));
349 vcap->version = CX18_DRIVER_VERSION; /* version */ 350 vcap->version = CX18_DRIVER_VERSION; /* version */
350 vcap->capabilities = cx->v4l2_cap; /* capabilities */ 351 vcap->capabilities = cx->v4l2_cap; /* capabilities */
351 return 0; 352 return 0;
352 } 353 }
353 354
354 static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) 355 static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
355 { 356 {
356 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 357 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
357 358
358 return cx18_get_audio_input(cx, vin->index, vin); 359 return cx18_get_audio_input(cx, vin->index, vin);
359 } 360 }
360 361
361 static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) 362 static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
362 { 363 {
363 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 364 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
364 365
365 vin->index = cx->audio_input; 366 vin->index = cx->audio_input;
366 return cx18_get_audio_input(cx, vin->index, vin); 367 return cx18_get_audio_input(cx, vin->index, vin);
367 } 368 }
368 369
369 static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout) 370 static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
370 { 371 {
371 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 372 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
372 373
373 if (vout->index >= cx->nof_audio_inputs) 374 if (vout->index >= cx->nof_audio_inputs)
374 return -EINVAL; 375 return -EINVAL;
375 cx->audio_input = vout->index; 376 cx->audio_input = vout->index;
376 cx18_audio_set_io(cx); 377 cx18_audio_set_io(cx);
377 return 0; 378 return 0;
378 } 379 }
379 380
380 static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin) 381 static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
381 { 382 {
382 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 383 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
383 384
384 /* set it to defaults from our table */ 385 /* set it to defaults from our table */
385 return cx18_get_input(cx, vin->index, vin); 386 return cx18_get_input(cx, vin->index, vin);
386 } 387 }
387 388
388 static int cx18_cropcap(struct file *file, void *fh, 389 static int cx18_cropcap(struct file *file, void *fh,
389 struct v4l2_cropcap *cropcap) 390 struct v4l2_cropcap *cropcap)
390 { 391 {
391 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 392 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
392 393
393 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 394 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
394 return -EINVAL; 395 return -EINVAL;
395 cropcap->bounds.top = cropcap->bounds.left = 0; 396 cropcap->bounds.top = cropcap->bounds.left = 0;
396 cropcap->bounds.width = 720; 397 cropcap->bounds.width = 720;
397 cropcap->bounds.height = cx->is_50hz ? 576 : 480; 398 cropcap->bounds.height = cx->is_50hz ? 576 : 480;
398 cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10; 399 cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
399 cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11; 400 cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
400 cropcap->defrect = cropcap->bounds; 401 cropcap->defrect = cropcap->bounds;
401 return 0; 402 return 0;
402 } 403 }
403 404
404 static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) 405 static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
405 { 406 {
406 struct cx18_open_id *id = fh; 407 struct cx18_open_id *id = fh;
407 struct cx18 *cx = id->cx; 408 struct cx18 *cx = id->cx;
408 int ret; 409 int ret;
409 410
410 ret = v4l2_prio_check(&cx->prio, &id->prio); 411 ret = v4l2_prio_check(&cx->prio, &id->prio);
411 if (ret) 412 if (ret)
412 return ret; 413 return ret;
413 414
414 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 415 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
415 return -EINVAL; 416 return -EINVAL;
416 return cx18_av_cmd(cx, VIDIOC_S_CROP, crop); 417 return cx18_av_cmd(cx, VIDIOC_S_CROP, crop);
417 } 418 }
418 419
419 static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) 420 static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
420 { 421 {
421 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 422 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
422 423
423 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 424 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
424 return -EINVAL; 425 return -EINVAL;
425 return cx18_av_cmd(cx, VIDIOC_G_CROP, crop); 426 return cx18_av_cmd(cx, VIDIOC_G_CROP, crop);
426 } 427 }
427 428
428 static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, 429 static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
429 struct v4l2_fmtdesc *fmt) 430 struct v4l2_fmtdesc *fmt)
430 { 431 {
431 static struct v4l2_fmtdesc formats[] = { 432 static struct v4l2_fmtdesc formats[] = {
432 { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0, 433 { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
433 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 } 434 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
434 }, 435 },
435 { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED, 436 { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
436 "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 } 437 "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
437 } 438 }
438 }; 439 };
439 440
440 if (fmt->index > 1) 441 if (fmt->index > 1)
441 return -EINVAL; 442 return -EINVAL;
442 *fmt = formats[fmt->index]; 443 *fmt = formats[fmt->index];
443 return 0; 444 return 0;
444 } 445 }
445 446
446 static int cx18_g_input(struct file *file, void *fh, unsigned int *i) 447 static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
447 { 448 {
448 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 449 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
449 450
450 *i = cx->active_input; 451 *i = cx->active_input;
451 return 0; 452 return 0;
452 } 453 }
453 454
454 int cx18_s_input(struct file *file, void *fh, unsigned int inp) 455 int cx18_s_input(struct file *file, void *fh, unsigned int inp)
455 { 456 {
456 struct cx18_open_id *id = fh; 457 struct cx18_open_id *id = fh;
457 struct cx18 *cx = id->cx; 458 struct cx18 *cx = id->cx;
458 int ret; 459 int ret;
459 460
460 ret = v4l2_prio_check(&cx->prio, &id->prio); 461 ret = v4l2_prio_check(&cx->prio, &id->prio);
461 if (ret) 462 if (ret)
462 return ret; 463 return ret;
463 464
464 if (inp < 0 || inp >= cx->nof_inputs) 465 if (inp < 0 || inp >= cx->nof_inputs)
465 return -EINVAL; 466 return -EINVAL;
466 467
467 if (inp == cx->active_input) { 468 if (inp == cx->active_input) {
468 CX18_DEBUG_INFO("Input unchanged\n"); 469 CX18_DEBUG_INFO("Input unchanged\n");
469 return 0; 470 return 0;
470 } 471 }
471 472
472 CX18_DEBUG_INFO("Changing input from %d to %d\n", 473 CX18_DEBUG_INFO("Changing input from %d to %d\n",
473 cx->active_input, inp); 474 cx->active_input, inp);
474 475
475 cx->active_input = inp; 476 cx->active_input = inp;
476 /* Set the audio input to whatever is appropriate for the input type. */ 477 /* Set the audio input to whatever is appropriate for the input type. */
477 cx->audio_input = cx->card->video_inputs[inp].audio_index; 478 cx->audio_input = cx->card->video_inputs[inp].audio_index;
478 479
479 /* prevent others from messing with the streams until 480 /* prevent others from messing with the streams until
480 we're finished changing inputs. */ 481 we're finished changing inputs. */
481 cx18_mute(cx); 482 cx18_mute(cx);
482 cx18_video_set_io(cx); 483 cx18_video_set_io(cx);
483 cx18_audio_set_io(cx); 484 cx18_audio_set_io(cx);
484 cx18_unmute(cx); 485 cx18_unmute(cx);
485 return 0; 486 return 0;
486 } 487 }
487 488
488 static int cx18_g_frequency(struct file *file, void *fh, 489 static int cx18_g_frequency(struct file *file, void *fh,
489 struct v4l2_frequency *vf) 490 struct v4l2_frequency *vf)
490 { 491 {
491 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 492 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
492 493
493 if (vf->tuner != 0) 494 if (vf->tuner != 0)
494 return -EINVAL; 495 return -EINVAL;
495 496
496 cx18_call_i2c_clients(cx, VIDIOC_G_FREQUENCY, vf); 497 cx18_call_i2c_clients(cx, VIDIOC_G_FREQUENCY, vf);
497 return 0; 498 return 0;
498 } 499 }
499 500
500 int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) 501 int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
501 { 502 {
502 struct cx18_open_id *id = fh; 503 struct cx18_open_id *id = fh;
503 struct cx18 *cx = id->cx; 504 struct cx18 *cx = id->cx;
504 int ret; 505 int ret;
505 506
506 ret = v4l2_prio_check(&cx->prio, &id->prio); 507 ret = v4l2_prio_check(&cx->prio, &id->prio);
507 if (ret) 508 if (ret)
508 return ret; 509 return ret;
509 510
510 if (vf->tuner != 0) 511 if (vf->tuner != 0)
511 return -EINVAL; 512 return -EINVAL;
512 513
513 cx18_mute(cx); 514 cx18_mute(cx);
514 CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency); 515 CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
515 cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf); 516 cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf);
516 cx18_unmute(cx); 517 cx18_unmute(cx);
517 return 0; 518 return 0;
518 } 519 }
519 520
520 static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std) 521 static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
521 { 522 {
522 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 523 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
523 524
524 *std = cx->std; 525 *std = cx->std;
525 return 0; 526 return 0;
526 } 527 }
527 528
528 int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std) 529 int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
529 { 530 {
530 struct cx18_open_id *id = fh; 531 struct cx18_open_id *id = fh;
531 struct cx18 *cx = id->cx; 532 struct cx18 *cx = id->cx;
532 int ret; 533 int ret;
533 534
534 ret = v4l2_prio_check(&cx->prio, &id->prio); 535 ret = v4l2_prio_check(&cx->prio, &id->prio);
535 if (ret) 536 if (ret)
536 return ret; 537 return ret;
537 538
538 if ((*std & V4L2_STD_ALL) == 0) 539 if ((*std & V4L2_STD_ALL) == 0)
539 return -EINVAL; 540 return -EINVAL;
540 541
541 if (*std == cx->std) 542 if (*std == cx->std)
542 return 0; 543 return 0;
543 544
544 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) || 545 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
545 atomic_read(&cx->ana_capturing) > 0) { 546 atomic_read(&cx->ana_capturing) > 0) {
546 /* Switching standard would turn off the radio or mess 547 /* Switching standard would turn off the radio or mess
547 with already running streams, prevent that by 548 with already running streams, prevent that by
548 returning EBUSY. */ 549 returning EBUSY. */
549 return -EBUSY; 550 return -EBUSY;
550 } 551 }
551 552
552 cx->std = *std; 553 cx->std = *std;
553 cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; 554 cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
554 cx->params.is_50hz = cx->is_50hz = !cx->is_60hz; 555 cx->params.is_50hz = cx->is_50hz = !cx->is_60hz;
555 cx->params.width = 720; 556 cx->params.width = 720;
556 cx->params.height = cx->is_50hz ? 576 : 480; 557 cx->params.height = cx->is_50hz ? 576 : 480;
557 cx->vbi.count = cx->is_50hz ? 18 : 12; 558 cx->vbi.count = cx->is_50hz ? 18 : 12;
558 cx->vbi.start[0] = cx->is_50hz ? 6 : 10; 559 cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
559 cx->vbi.start[1] = cx->is_50hz ? 318 : 273; 560 cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
560 cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284; 561 cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284;
561 CX18_DEBUG_INFO("Switching standard to %llx.\n", 562 CX18_DEBUG_INFO("Switching standard to %llx.\n",
562 (unsigned long long) cx->std); 563 (unsigned long long) cx->std);
563 564
564 /* Tuner */ 565 /* Tuner */
565 cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); 566 cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
566 return 0; 567 return 0;
567 } 568 }
568 569
569 static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) 570 static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
570 { 571 {
571 struct cx18_open_id *id = fh; 572 struct cx18_open_id *id = fh;
572 struct cx18 *cx = id->cx; 573 struct cx18 *cx = id->cx;
573 int ret; 574 int ret;
574 575
575 ret = v4l2_prio_check(&cx->prio, &id->prio); 576 ret = v4l2_prio_check(&cx->prio, &id->prio);
576 if (ret) 577 if (ret)
577 return ret; 578 return ret;
578 579
579 if (vt->index != 0) 580 if (vt->index != 0)
580 return -EINVAL; 581 return -EINVAL;
581 582
582 /* Setting tuner can only set audio mode */ 583 /* Setting tuner can only set audio mode */
583 cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt); 584 cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt);
584 585
585 return 0; 586 return 0;
586 } 587 }
587 588
588 static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) 589 static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
589 { 590 {
590 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 591 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
591 592
592 if (vt->index != 0) 593 if (vt->index != 0)
593 return -EINVAL; 594 return -EINVAL;
594 595
595 cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt); 596 cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt);
596 597
597 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { 598 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
598 strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); 599 strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
599 vt->type = V4L2_TUNER_RADIO; 600 vt->type = V4L2_TUNER_RADIO;
600 } else { 601 } else {
601 strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name)); 602 strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
602 vt->type = V4L2_TUNER_ANALOG_TV; 603 vt->type = V4L2_TUNER_ANALOG_TV;
603 } 604 }
604 605
605 return 0; 606 return 0;
606 } 607 }
607 608
608 static int cx18_g_sliced_vbi_cap(struct file *file, void *fh, 609 static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
609 struct v4l2_sliced_vbi_cap *cap) 610 struct v4l2_sliced_vbi_cap *cap)
610 { 611 {
611 return -EINVAL; 612 return -EINVAL;
612 } 613 }
613 614
614 static int cx18_g_enc_index(struct file *file, void *fh, 615 static int cx18_g_enc_index(struct file *file, void *fh,
615 struct v4l2_enc_idx *idx) 616 struct v4l2_enc_idx *idx)
616 { 617 {
617 return -EINVAL; 618 return -EINVAL;
618 } 619 }
619 620
620 static int cx18_encoder_cmd(struct file *file, void *fh, 621 static int cx18_encoder_cmd(struct file *file, void *fh,
621 struct v4l2_encoder_cmd *enc) 622 struct v4l2_encoder_cmd *enc)
622 { 623 {
623 struct cx18_open_id *id = fh; 624 struct cx18_open_id *id = fh;
624 struct cx18 *cx = id->cx; 625 struct cx18 *cx = id->cx;
625 u32 h; 626 u32 h;
626 627
627 switch (enc->cmd) { 628 switch (enc->cmd) {
628 case V4L2_ENC_CMD_START: 629 case V4L2_ENC_CMD_START:
629 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); 630 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
630 enc->flags = 0; 631 enc->flags = 0;
631 return cx18_start_capture(id); 632 return cx18_start_capture(id);
632 633
633 case V4L2_ENC_CMD_STOP: 634 case V4L2_ENC_CMD_STOP:
634 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); 635 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
635 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; 636 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
636 cx18_stop_capture(id, 637 cx18_stop_capture(id,
637 enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); 638 enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
638 break; 639 break;
639 640
640 case V4L2_ENC_CMD_PAUSE: 641 case V4L2_ENC_CMD_PAUSE:
641 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); 642 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
642 enc->flags = 0; 643 enc->flags = 0;
643 if (!atomic_read(&cx->ana_capturing)) 644 if (!atomic_read(&cx->ana_capturing))
644 return -EPERM; 645 return -EPERM;
645 if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) 646 if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
646 return 0; 647 return 0;
647 h = cx18_find_handle(cx); 648 h = cx18_find_handle(cx);
648 if (h == CX18_INVALID_TASK_HANDLE) { 649 if (h == CX18_INVALID_TASK_HANDLE) {
649 CX18_ERR("Can't find valid task handle for " 650 CX18_ERR("Can't find valid task handle for "
650 "V4L2_ENC_CMD_PAUSE\n"); 651 "V4L2_ENC_CMD_PAUSE\n");
651 return -EBADFD; 652 return -EBADFD;
652 } 653 }
653 cx18_mute(cx); 654 cx18_mute(cx);
654 cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h); 655 cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h);
655 break; 656 break;
656 657
657 case V4L2_ENC_CMD_RESUME: 658 case V4L2_ENC_CMD_RESUME:
658 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); 659 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
659 enc->flags = 0; 660 enc->flags = 0;
660 if (!atomic_read(&cx->ana_capturing)) 661 if (!atomic_read(&cx->ana_capturing))
661 return -EPERM; 662 return -EPERM;
662 if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) 663 if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
663 return 0; 664 return 0;
664 h = cx18_find_handle(cx); 665 h = cx18_find_handle(cx);
665 if (h == CX18_INVALID_TASK_HANDLE) { 666 if (h == CX18_INVALID_TASK_HANDLE) {
666 CX18_ERR("Can't find valid task handle for " 667 CX18_ERR("Can't find valid task handle for "
667 "V4L2_ENC_CMD_RESUME\n"); 668 "V4L2_ENC_CMD_RESUME\n");
668 return -EBADFD; 669 return -EBADFD;
669 } 670 }
670 cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h); 671 cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h);
671 cx18_unmute(cx); 672 cx18_unmute(cx);
672 break; 673 break;
673 674
674 default: 675 default:
675 CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); 676 CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
676 return -EINVAL; 677 return -EINVAL;
677 } 678 }
678 return 0; 679 return 0;
679 } 680 }
680 681
681 static int cx18_try_encoder_cmd(struct file *file, void *fh, 682 static int cx18_try_encoder_cmd(struct file *file, void *fh,
682 struct v4l2_encoder_cmd *enc) 683 struct v4l2_encoder_cmd *enc)
683 { 684 {
684 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 685 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
685 686
686 switch (enc->cmd) { 687 switch (enc->cmd) {
687 case V4L2_ENC_CMD_START: 688 case V4L2_ENC_CMD_START:
688 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); 689 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
689 enc->flags = 0; 690 enc->flags = 0;
690 break; 691 break;
691 692
692 case V4L2_ENC_CMD_STOP: 693 case V4L2_ENC_CMD_STOP:
693 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); 694 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
694 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; 695 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
695 break; 696 break;
696 697
697 case V4L2_ENC_CMD_PAUSE: 698 case V4L2_ENC_CMD_PAUSE:
698 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); 699 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
699 enc->flags = 0; 700 enc->flags = 0;
700 break; 701 break;
701 702
702 case V4L2_ENC_CMD_RESUME: 703 case V4L2_ENC_CMD_RESUME:
703 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); 704 CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
704 enc->flags = 0; 705 enc->flags = 0;
705 break; 706 break;
706 707
707 default: 708 default:
708 CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); 709 CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
709 return -EINVAL; 710 return -EINVAL;
710 } 711 }
711 return 0; 712 return 0;
712 } 713 }
713 714
714 static int cx18_log_status(struct file *file, void *fh) 715 static int cx18_log_status(struct file *file, void *fh)
715 { 716 {
716 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 717 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
717 struct v4l2_input vidin; 718 struct v4l2_input vidin;
718 struct v4l2_audio audin; 719 struct v4l2_audio audin;
719 int i; 720 int i;
720 721
721 CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num); 722 CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num);
722 if (cx->hw_flags & CX18_HW_TVEEPROM) { 723 if (cx->hw_flags & CX18_HW_TVEEPROM) {
723 struct tveeprom tv; 724 struct tveeprom tv;
724 725
725 cx18_read_eeprom(cx, &tv); 726 cx18_read_eeprom(cx, &tv);
726 } 727 }
727 cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL); 728 cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL);
728 cx18_get_input(cx, cx->active_input, &vidin); 729 cx18_get_input(cx, cx->active_input, &vidin);
729 cx18_get_audio_input(cx, cx->audio_input, &audin); 730 cx18_get_audio_input(cx, cx->audio_input, &audin);
730 CX18_INFO("Video Input: %s\n", vidin.name); 731 CX18_INFO("Video Input: %s\n", vidin.name);
731 CX18_INFO("Audio Input: %s\n", audin.name); 732 CX18_INFO("Audio Input: %s\n", audin.name);
732 mutex_lock(&cx->gpio_lock); 733 mutex_lock(&cx->gpio_lock);
733 CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n", 734 CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n",
734 cx->gpio_dir, cx->gpio_val); 735 cx->gpio_dir, cx->gpio_val);
735 mutex_unlock(&cx->gpio_lock); 736 mutex_unlock(&cx->gpio_lock);
736 CX18_INFO("Tuner: %s\n", 737 CX18_INFO("Tuner: %s\n",
737 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); 738 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
738 cx2341x_log_status(&cx->params, cx->name); 739 cx2341x_log_status(&cx->params, cx->name);
739 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags); 740 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
740 for (i = 0; i < CX18_MAX_STREAMS; i++) { 741 for (i = 0; i < CX18_MAX_STREAMS; i++) {
741 struct cx18_stream *s = &cx->streams[i]; 742 struct cx18_stream *s = &cx->streams[i];
742 743
743 if (s->v4l2dev == NULL || s->buffers == 0) 744 if (s->v4l2dev == NULL || s->buffers == 0)
744 continue; 745 continue;
745 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", 746 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
746 s->name, s->s_flags, 747 s->name, s->s_flags,
747 (s->buffers - atomic_read(&s->q_free.buffers)) 748 (s->buffers - atomic_read(&s->q_free.buffers))
748 * 100 / s->buffers, 749 * 100 / s->buffers,
749 (s->buffers * s->buf_size) / 1024, s->buffers); 750 (s->buffers * s->buf_size) / 1024, s->buffers);
750 } 751 }
751 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", 752 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
752 (long long)cx->mpg_data_received, 753 (long long)cx->mpg_data_received,
753 (long long)cx->vbi_data_inserted); 754 (long long)cx->vbi_data_inserted);
754 CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num); 755 CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num);
755 return 0; 756 return 0;
756 } 757 }
757 758
758 static int cx18_default(struct file *file, void *fh, int cmd, void *arg) 759 static int cx18_default(struct file *file, void *fh, int cmd, void *arg)
759 { 760 {
760 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 761 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
761 762
762 switch (cmd) { 763 switch (cmd) {
763 case VIDIOC_INT_S_AUDIO_ROUTING: { 764 case VIDIOC_INT_S_AUDIO_ROUTING: {
764 struct v4l2_routing *route = arg; 765 struct v4l2_routing *route = arg;
765 766
766 CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n", 767 CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n",
767 route->input, route->output); 768 route->input, route->output);
768 cx18_audio_set_route(cx, route); 769 cx18_audio_set_route(cx, route);
769 break; 770 break;
770 } 771 }
771 772
772 case VIDIOC_INT_RESET: { 773 case VIDIOC_INT_RESET: {
773 u32 val = *(u32 *)arg; 774 u32 val = *(u32 *)arg;
774 775
775 if ((val == 0) || (val & 0x01)) 776 if ((val == 0) || (val & 0x01))
776 cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]); 777 cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]);
777 break; 778 break;
778 } 779 }
779 780
780 default: 781 default:
781 return -EINVAL; 782 return -EINVAL;
782 } 783 }
783 return 0; 784 return 0;
784 } 785 }
785 786
786 int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 787 int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
787 unsigned long arg) 788 unsigned long arg)
788 { 789 {
789 struct video_device *vfd = video_devdata(filp); 790 struct video_device *vfd = video_devdata(filp);
790 struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data; 791 struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data;
791 struct cx18 *cx = id->cx; 792 struct cx18 *cx = id->cx;
792 int res; 793 int res;
793 794
794 mutex_lock(&cx->serialize_lock); 795 mutex_lock(&cx->serialize_lock);
795 796
796 if (cx18_debug & CX18_DBGFLG_IOCTL) 797 if (cx18_debug & CX18_DBGFLG_IOCTL)
797 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; 798 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
798 res = video_ioctl2(inode, filp, cmd, arg); 799 res = video_ioctl2(inode, filp, cmd, arg);
799 vfd->debug = 0; 800 vfd->debug = 0;
800 mutex_unlock(&cx->serialize_lock); 801 mutex_unlock(&cx->serialize_lock);
801 return res; 802 return res;
802 } 803 }
803 804
804 static const struct v4l2_ioctl_ops cx18_ioctl_ops = { 805 static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
805 .vidioc_querycap = cx18_querycap, 806 .vidioc_querycap = cx18_querycap,
806 .vidioc_g_priority = cx18_g_priority, 807 .vidioc_g_priority = cx18_g_priority,
807 .vidioc_s_priority = cx18_s_priority, 808 .vidioc_s_priority = cx18_s_priority,
808 .vidioc_s_audio = cx18_s_audio, 809 .vidioc_s_audio = cx18_s_audio,
809 .vidioc_g_audio = cx18_g_audio, 810 .vidioc_g_audio = cx18_g_audio,
810 .vidioc_enumaudio = cx18_enumaudio, 811 .vidioc_enumaudio = cx18_enumaudio,
811 .vidioc_enum_input = cx18_enum_input, 812 .vidioc_enum_input = cx18_enum_input,
812 .vidioc_cropcap = cx18_cropcap, 813 .vidioc_cropcap = cx18_cropcap,
813 .vidioc_s_crop = cx18_s_crop, 814 .vidioc_s_crop = cx18_s_crop,
814 .vidioc_g_crop = cx18_g_crop, 815 .vidioc_g_crop = cx18_g_crop,
815 .vidioc_g_input = cx18_g_input, 816 .vidioc_g_input = cx18_g_input,
816 .vidioc_s_input = cx18_s_input, 817 .vidioc_s_input = cx18_s_input,
817 .vidioc_g_frequency = cx18_g_frequency, 818 .vidioc_g_frequency = cx18_g_frequency,
818 .vidioc_s_frequency = cx18_s_frequency, 819 .vidioc_s_frequency = cx18_s_frequency,
819 .vidioc_s_tuner = cx18_s_tuner, 820 .vidioc_s_tuner = cx18_s_tuner,
820 .vidioc_g_tuner = cx18_g_tuner, 821 .vidioc_g_tuner = cx18_g_tuner,
821 .vidioc_g_enc_index = cx18_g_enc_index, 822 .vidioc_g_enc_index = cx18_g_enc_index,
822 .vidioc_g_std = cx18_g_std, 823 .vidioc_g_std = cx18_g_std,
823 .vidioc_s_std = cx18_s_std, 824 .vidioc_s_std = cx18_s_std,
824 .vidioc_log_status = cx18_log_status, 825 .vidioc_log_status = cx18_log_status,
825 .vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap, 826 .vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap,
826 .vidioc_encoder_cmd = cx18_encoder_cmd, 827 .vidioc_encoder_cmd = cx18_encoder_cmd,
827 .vidioc_try_encoder_cmd = cx18_try_encoder_cmd, 828 .vidioc_try_encoder_cmd = cx18_try_encoder_cmd,
828 .vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap, 829 .vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap,
829 .vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap, 830 .vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap,
830 .vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap, 831 .vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap,
831 .vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap, 832 .vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap,
832 .vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap, 833 .vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap,
833 .vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap, 834 .vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap,
834 .vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap, 835 .vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap,
835 .vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap, 836 .vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap,
836 .vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap, 837 .vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap,
837 .vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap, 838 .vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap,
838 .vidioc_g_chip_ident = cx18_g_chip_ident, 839 .vidioc_g_chip_ident = cx18_g_chip_ident,
839 #ifdef CONFIG_VIDEO_ADV_DEBUG 840 #ifdef CONFIG_VIDEO_ADV_DEBUG
840 .vidioc_g_register = cx18_g_register, 841 .vidioc_g_register = cx18_g_register,
841 .vidioc_s_register = cx18_s_register, 842 .vidioc_s_register = cx18_s_register,
842 #endif 843 #endif
843 .vidioc_default = cx18_default, 844 .vidioc_default = cx18_default,
844 .vidioc_queryctrl = cx18_queryctrl, 845 .vidioc_queryctrl = cx18_queryctrl,
845 .vidioc_querymenu = cx18_querymenu, 846 .vidioc_querymenu = cx18_querymenu,
846 .vidioc_g_ext_ctrls = cx18_g_ext_ctrls, 847 .vidioc_g_ext_ctrls = cx18_g_ext_ctrls,
847 .vidioc_s_ext_ctrls = cx18_s_ext_ctrls, 848 .vidioc_s_ext_ctrls = cx18_s_ext_ctrls,
848 .vidioc_try_ext_ctrls = cx18_try_ext_ctrls, 849 .vidioc_try_ext_ctrls = cx18_try_ext_ctrls,
849 }; 850 };
850 851
851 void cx18_set_funcs(struct video_device *vdev) 852 void cx18_set_funcs(struct video_device *vdev)
852 { 853 {
853 vdev->ioctl_ops = &cx18_ioctl_ops; 854 vdev->ioctl_ops = &cx18_ioctl_ops;
854 } 855 }
855 856
drivers/media/video/cx18/cx18-irq.c
1 /* 1 /*
2 * cx18 interrupt handling 2 * cx18 interrupt handling
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 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 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 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA 19 * 02111-1307 USA
20 */ 20 */
21 21
22 #include "cx18-driver.h" 22 #include "cx18-driver.h"
23 #include "cx18-io.h"
23 #include "cx18-firmware.h" 24 #include "cx18-firmware.h"
24 #include "cx18-fileops.h" 25 #include "cx18-fileops.h"
25 #include "cx18-queue.h" 26 #include "cx18-queue.h"
26 #include "cx18-irq.h" 27 #include "cx18-irq.h"
27 #include "cx18-ioctl.h" 28 #include "cx18-ioctl.h"
28 #include "cx18-mailbox.h" 29 #include "cx18-mailbox.h"
29 #include "cx18-vbi.h" 30 #include "cx18-vbi.h"
30 #include "cx18-scb.h" 31 #include "cx18-scb.h"
31 32
32 #define DMA_MAGIC_COOKIE 0x000001fe 33 #define DMA_MAGIC_COOKIE 0x000001fe
33 34
34 static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) 35 static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
35 { 36 {
36 u32 handle = mb->args[0]; 37 u32 handle = mb->args[0];
37 struct cx18_stream *s = NULL; 38 struct cx18_stream *s = NULL;
38 struct cx18_buffer *buf; 39 struct cx18_buffer *buf;
39 u32 off; 40 u32 off;
40 int i; 41 int i;
41 int id; 42 int id;
42 43
43 for (i = 0; i < CX18_MAX_STREAMS; i++) { 44 for (i = 0; i < CX18_MAX_STREAMS; i++) {
44 s = &cx->streams[i]; 45 s = &cx->streams[i];
45 if ((handle == s->handle) && (s->dvb.enabled)) 46 if ((handle == s->handle) && (s->dvb.enabled))
46 break; 47 break;
47 if (s->v4l2dev && handle == s->handle) 48 if (s->v4l2dev && handle == s->handle)
48 break; 49 break;
49 } 50 }
50 if (i == CX18_MAX_STREAMS) { 51 if (i == CX18_MAX_STREAMS) {
51 CX18_WARN("DMA done for unknown handle %d for stream %s\n", 52 CX18_WARN("DMA done for unknown handle %d for stream %s\n",
52 handle, s->name); 53 handle, s->name);
53 mb->error = CXERR_NOT_OPEN; 54 mb->error = CXERR_NOT_OPEN;
54 mb->cmd = 0; 55 mb->cmd = 0;
55 cx18_mb_ack(cx, mb); 56 cx18_mb_ack(cx, mb);
56 return; 57 return;
57 } 58 }
58 59
59 off = mb->args[1]; 60 off = mb->args[1];
60 if (mb->args[2] != 1) 61 if (mb->args[2] != 1)
61 CX18_WARN("Ack struct = %d for %s\n", 62 CX18_WARN("Ack struct = %d for %s\n",
62 mb->args[2], s->name); 63 mb->args[2], s->name);
63 id = read_enc(off); 64 id = cx18_read_enc(cx, off);
64 buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4)); 65 buf = cx18_queue_get_buf_irq(s, id, cx18_read_enc(cx, off + 4));
65 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); 66 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
66 if (buf) { 67 if (buf) {
67 cx18_buf_sync_for_cpu(s, buf); 68 cx18_buf_sync_for_cpu(s, buf);
68 if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { 69 if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) {
69 /* process the buffer here */ 70 /* process the buffer here */
70 CX18_DEBUG_HI_DMA("TS recv and sent bytesused=%d\n", 71 CX18_DEBUG_HI_DMA("TS recv and sent bytesused=%d\n",
71 buf->bytesused); 72 buf->bytesused);
72 73
73 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, 74 dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
74 buf->bytesused); 75 buf->bytesused);
75 76
76 cx18_buf_sync_for_device(s, buf); 77 cx18_buf_sync_for_device(s, buf);
77 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, 78 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
78 (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 79 (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
79 1, buf->id, s->buf_size); 80 1, buf->id, s->buf_size);
80 } else 81 } else
81 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); 82 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
82 } else { 83 } else {
83 CX18_WARN("Could not find buf %d for stream %s\n", 84 CX18_WARN("Could not find buf %d for stream %s\n",
84 read_enc(off), s->name); 85 cx18_read_enc(cx, off), s->name);
85 } 86 }
86 mb->error = 0; 87 mb->error = 0;
87 mb->cmd = 0; 88 mb->cmd = 0;
88 cx18_mb_ack(cx, mb); 89 cx18_mb_ack(cx, mb);
89 wake_up(&cx->dma_waitq); 90 wake_up(&cx->dma_waitq);
90 if (s->id != -1) 91 if (s->id != -1)
91 wake_up(&s->waitq); 92 wake_up(&s->waitq);
92 } 93 }
93 94
94 static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb) 95 static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb)
95 { 96 {
96 char str[256] = { 0 }; 97 char str[256] = { 0 };
97 char *p; 98 char *p;
98 99
99 if (mb->args[1]) { 100 if (mb->args[1]) {
100 setup_page(mb->args[1]); 101 cx18_setup_page(cx, mb->args[1]);
101 memcpy_fromio(str, cx->enc_mem + mb->args[1], 252); 102 cx18_memcpy_fromio(cx, str, cx->enc_mem + mb->args[1], 252);
102 str[252] = 0; 103 str[252] = 0;
103 } 104 }
104 cx18_mb_ack(cx, mb); 105 cx18_mb_ack(cx, mb);
105 CX18_DEBUG_INFO("%x %s\n", mb->args[0], str); 106 CX18_DEBUG_INFO("%x %s\n", mb->args[0], str);
106 p = strchr(str, '.'); 107 p = strchr(str, '.');
107 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags) && p && p > str) 108 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags) && p && p > str)
108 CX18_INFO("FW version: %s\n", p - 1); 109 CX18_INFO("FW version: %s\n", p - 1);
109 } 110 }
110 111
111 static void hpu_cmd(struct cx18 *cx, u32 sw1) 112 static void hpu_cmd(struct cx18 *cx, u32 sw1)
112 { 113 {
113 struct cx18_mailbox mb; 114 struct cx18_mailbox mb;
114 115
115 if (sw1 & IRQ_CPU_TO_EPU) { 116 if (sw1 & IRQ_CPU_TO_EPU) {
116 memcpy_fromio(&mb, &cx->scb->cpu2epu_mb, sizeof(mb)); 117 cx18_memcpy_fromio(cx, &mb, &cx->scb->cpu2epu_mb, sizeof(mb));
117 mb.error = 0; 118 mb.error = 0;
118 119
119 switch (mb.cmd) { 120 switch (mb.cmd) {
120 case CX18_EPU_DMA_DONE: 121 case CX18_EPU_DMA_DONE:
121 epu_dma_done(cx, &mb); 122 epu_dma_done(cx, &mb);
122 break; 123 break;
123 case CX18_EPU_DEBUG: 124 case CX18_EPU_DEBUG:
124 epu_debug(cx, &mb); 125 epu_debug(cx, &mb);
125 break; 126 break;
126 default: 127 default:
127 CX18_WARN("Unexpected mailbox command %08x\n", mb.cmd); 128 CX18_WARN("Unexpected mailbox command %08x\n", mb.cmd);
128 break; 129 break;
129 } 130 }
130 } 131 }
131 if (sw1 & (IRQ_APU_TO_EPU | IRQ_HPU_TO_EPU)) 132 if (sw1 & (IRQ_APU_TO_EPU | IRQ_HPU_TO_EPU))
132 CX18_WARN("Unexpected interrupt %08x\n", sw1); 133 CX18_WARN("Unexpected interrupt %08x\n", sw1);
133 } 134 }
134 135
135 irqreturn_t cx18_irq_handler(int irq, void *dev_id) 136 irqreturn_t cx18_irq_handler(int irq, void *dev_id)
136 { 137 {
137 struct cx18 *cx = (struct cx18 *)dev_id; 138 struct cx18 *cx = (struct cx18 *)dev_id;
138 u32 sw1, sw1_mask; 139 u32 sw1, sw1_mask;
139 u32 sw2, sw2_mask; 140 u32 sw2, sw2_mask;
140 u32 hw2, hw2_mask; 141 u32 hw2, hw2_mask;
141 142
142 spin_lock(&cx->dma_reg_lock); 143 spin_lock(&cx->dma_reg_lock);
143 144
144 hw2_mask = read_reg(HW2_INT_MASK5_PCI); 145 hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI);
145 hw2 = read_reg(HW2_INT_CLR_STATUS) & hw2_mask; 146 hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask;
146 sw2_mask = read_reg(SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK; 147 sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK;
147 sw2 = read_reg(SW2_INT_STATUS) & sw2_mask; 148 sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask;
148 sw1_mask = read_reg(SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU; 149 sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU;
149 sw1 = read_reg(SW1_INT_STATUS) & sw1_mask; 150 sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask;
150 151
151 write_reg(sw2&sw2_mask, SW2_INT_STATUS); 152 cx18_write_reg(cx, sw2&sw2_mask, SW2_INT_STATUS);
152 write_reg(sw1&sw1_mask, SW1_INT_STATUS); 153 cx18_write_reg(cx, sw1&sw1_mask, SW1_INT_STATUS);
153 write_reg(hw2&hw2_mask, HW2_INT_CLR_STATUS); 154 cx18_write_reg(cx, hw2&hw2_mask, HW2_INT_CLR_STATUS);
154 155
155 if (sw1 || sw2 || hw2) 156 if (sw1 || sw2 || hw2)
156 CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); 157 CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2);
157 158
158 /* To do: interrupt-based I2C handling 159 /* To do: interrupt-based I2C handling
159 if (hw2 & 0x00c00000) { 160 if (hw2 & 0x00c00000) {
160 } 161 }
161 */ 162 */
162 163
163 if (sw2) { 164 if (sw2) {
164 if (sw2 & (readl(&cx->scb->cpu2hpu_irq_ack) | 165 if (sw2 & (cx18_readl(cx, &cx->scb->cpu2hpu_irq_ack) |
165 readl(&cx->scb->cpu2epu_irq_ack))) 166 cx18_readl(cx, &cx->scb->cpu2epu_irq_ack)))
166 wake_up(&cx->mb_cpu_waitq); 167 wake_up(&cx->mb_cpu_waitq);
167 if (sw2 & (readl(&cx->scb->apu2hpu_irq_ack) | 168 if (sw2 & (cx18_readl(cx, &cx->scb->apu2hpu_irq_ack) |
168 readl(&cx->scb->apu2epu_irq_ack))) 169 cx18_readl(cx, &cx->scb->apu2epu_irq_ack)))
169 wake_up(&cx->mb_apu_waitq); 170 wake_up(&cx->mb_apu_waitq);
170 if (sw2 & readl(&cx->scb->epu2hpu_irq_ack)) 171 if (sw2 & cx18_readl(cx, &cx->scb->epu2hpu_irq_ack))
171 wake_up(&cx->mb_epu_waitq); 172 wake_up(&cx->mb_epu_waitq);
172 if (sw2 & readl(&cx->scb->hpu2epu_irq_ack)) 173 if (sw2 & cx18_readl(cx, &cx->scb->hpu2epu_irq_ack))
173 wake_up(&cx->mb_hpu_waitq); 174 wake_up(&cx->mb_hpu_waitq);
174 } 175 }
175 176
176 if (sw1) 177 if (sw1)
177 hpu_cmd(cx, sw1); 178 hpu_cmd(cx, sw1);
178 spin_unlock(&cx->dma_reg_lock); 179 spin_unlock(&cx->dma_reg_lock);
179 180
180 return (hw2 | sw1 | sw2) ? IRQ_HANDLED : IRQ_NONE; 181 return (hw2 | sw1 | sw2) ? IRQ_HANDLED : IRQ_NONE;
181 } 182 }
182 183
drivers/media/video/cx18/cx18-mailbox.c
1 /* 1 /*
2 * cx18 mailbox functions 2 * cx18 mailbox functions
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 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 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 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA 19 * 02111-1307 USA
20 */ 20 */
21 21
22 #include <stdarg.h> 22 #include <stdarg.h>
23 23
24 #include "cx18-driver.h" 24 #include "cx18-driver.h"
25 #include "cx18-io.h"
25 #include "cx18-scb.h" 26 #include "cx18-scb.h"
26 #include "cx18-irq.h" 27 #include "cx18-irq.h"
27 #include "cx18-mailbox.h" 28 #include "cx18-mailbox.h"
28 29
29 #define API_FAST (1 << 2) /* Short timeout */ 30 #define API_FAST (1 << 2) /* Short timeout */
30 #define API_SLOW (1 << 3) /* Additional 300ms timeout */ 31 #define API_SLOW (1 << 3) /* Additional 300ms timeout */
31 32
32 #define APU 0 33 #define APU 0
33 #define CPU 1 34 #define CPU 1
34 #define EPU 2 35 #define EPU 2
35 #define HPU 3 36 #define HPU 3
36 37
37 struct cx18_api_info { 38 struct cx18_api_info {
38 u32 cmd; 39 u32 cmd;
39 u8 flags; /* Flags, see above */ 40 u8 flags; /* Flags, see above */
40 u8 rpu; /* Processing unit */ 41 u8 rpu; /* Processing unit */
41 const char *name; /* The name of the command */ 42 const char *name; /* The name of the command */
42 }; 43 };
43 44
44 #define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x } 45 #define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x }
45 46
46 static const struct cx18_api_info api_info[] = { 47 static const struct cx18_api_info api_info[] = {
47 /* MPEG encoder API */ 48 /* MPEG encoder API */
48 API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0), 49 API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
49 API_ENTRY(CPU, CX18_EPU_DEBUG, 0), 50 API_ENTRY(CPU, CX18_EPU_DEBUG, 0),
50 API_ENTRY(CPU, CX18_CREATE_TASK, 0), 51 API_ENTRY(CPU, CX18_CREATE_TASK, 0),
51 API_ENTRY(CPU, CX18_DESTROY_TASK, 0), 52 API_ENTRY(CPU, CX18_DESTROY_TASK, 0),
52 API_ENTRY(CPU, CX18_CPU_CAPTURE_START, API_SLOW), 53 API_ENTRY(CPU, CX18_CPU_CAPTURE_START, API_SLOW),
53 API_ENTRY(CPU, CX18_CPU_CAPTURE_STOP, API_SLOW), 54 API_ENTRY(CPU, CX18_CPU_CAPTURE_STOP, API_SLOW),
54 API_ENTRY(CPU, CX18_CPU_CAPTURE_PAUSE, 0), 55 API_ENTRY(CPU, CX18_CPU_CAPTURE_PAUSE, 0),
55 API_ENTRY(CPU, CX18_CPU_CAPTURE_RESUME, 0), 56 API_ENTRY(CPU, CX18_CPU_CAPTURE_RESUME, 0),
56 API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0), 57 API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
57 API_ENTRY(CPU, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 0), 58 API_ENTRY(CPU, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 0),
58 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_IN, 0), 59 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_IN, 0),
59 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RATE, 0), 60 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RATE, 0),
60 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RESOLUTION, 0), 61 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RESOLUTION, 0),
61 API_ENTRY(CPU, CX18_CPU_SET_FILTER_PARAM, 0), 62 API_ENTRY(CPU, CX18_CPU_SET_FILTER_PARAM, 0),
62 API_ENTRY(CPU, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 0), 63 API_ENTRY(CPU, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 0),
63 API_ENTRY(CPU, CX18_CPU_SET_MEDIAN_CORING, 0), 64 API_ENTRY(CPU, CX18_CPU_SET_MEDIAN_CORING, 0),
64 API_ENTRY(CPU, CX18_CPU_SET_INDEXTABLE, 0), 65 API_ENTRY(CPU, CX18_CPU_SET_INDEXTABLE, 0),
65 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PARAMETERS, 0), 66 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PARAMETERS, 0),
66 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_MUTE, 0), 67 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_MUTE, 0),
67 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_MUTE, 0), 68 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_MUTE, 0),
68 API_ENTRY(CPU, CX18_CPU_SET_MISC_PARAMETERS, 0), 69 API_ENTRY(CPU, CX18_CPU_SET_MISC_PARAMETERS, 0),
69 API_ENTRY(CPU, CX18_CPU_SET_RAW_VBI_PARAM, API_SLOW), 70 API_ENTRY(CPU, CX18_CPU_SET_RAW_VBI_PARAM, API_SLOW),
70 API_ENTRY(CPU, CX18_CPU_SET_CAPTURE_LINE_NO, 0), 71 API_ENTRY(CPU, CX18_CPU_SET_CAPTURE_LINE_NO, 0),
71 API_ENTRY(CPU, CX18_CPU_SET_COPYRIGHT, 0), 72 API_ENTRY(CPU, CX18_CPU_SET_COPYRIGHT, 0),
72 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PID, 0), 73 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PID, 0),
73 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_PID, 0), 74 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_PID, 0),
74 API_ENTRY(CPU, CX18_CPU_SET_VER_CROP_LINE, 0), 75 API_ENTRY(CPU, CX18_CPU_SET_VER_CROP_LINE, 0),
75 API_ENTRY(CPU, CX18_CPU_SET_GOP_STRUCTURE, 0), 76 API_ENTRY(CPU, CX18_CPU_SET_GOP_STRUCTURE, 0),
76 API_ENTRY(CPU, CX18_CPU_SET_SCENE_CHANGE_DETECTION, 0), 77 API_ENTRY(CPU, CX18_CPU_SET_SCENE_CHANGE_DETECTION, 0),
77 API_ENTRY(CPU, CX18_CPU_SET_ASPECT_RATIO, 0), 78 API_ENTRY(CPU, CX18_CPU_SET_ASPECT_RATIO, 0),
78 API_ENTRY(CPU, CX18_CPU_SET_SKIP_INPUT_FRAME, 0), 79 API_ENTRY(CPU, CX18_CPU_SET_SKIP_INPUT_FRAME, 0),
79 API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0), 80 API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0),
80 API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0), 81 API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0),
81 API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0), 82 API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0),
82 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), 83 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
83 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), 84 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
84 API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST), 85 API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST),
85 API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, 0), 86 API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, 0),
86 API_ENTRY(0, 0, 0), 87 API_ENTRY(0, 0, 0),
87 }; 88 };
88 89
89 static const struct cx18_api_info *find_api_info(u32 cmd) 90 static const struct cx18_api_info *find_api_info(u32 cmd)
90 { 91 {
91 int i; 92 int i;
92 93
93 for (i = 0; api_info[i].cmd; i++) 94 for (i = 0; api_info[i].cmd; i++)
94 if (api_info[i].cmd == cmd) 95 if (api_info[i].cmd == cmd)
95 return &api_info[i]; 96 return &api_info[i];
96 return NULL; 97 return NULL;
97 } 98 }
98 99
99 static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu, 100 static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu,
100 u32 *state, u32 *irq, u32 *req) 101 u32 *state, u32 *irq, u32 *req)
101 { 102 {
102 struct cx18_mailbox __iomem *mb = NULL; 103 struct cx18_mailbox __iomem *mb = NULL;
103 int wait_count = 0; 104 int wait_count = 0;
104 u32 ack; 105 u32 ack;
105 106
106 switch (rpu) { 107 switch (rpu) {
107 case APU: 108 case APU:
108 mb = &cx->scb->epu2apu_mb; 109 mb = &cx->scb->epu2apu_mb;
109 *state = readl(&cx->scb->apu_state); 110 *state = cx18_readl(cx, &cx->scb->apu_state);
110 *irq = readl(&cx->scb->epu2apu_irq); 111 *irq = cx18_readl(cx, &cx->scb->epu2apu_irq);
111 break; 112 break;
112 113
113 case CPU: 114 case CPU:
114 mb = &cx->scb->epu2cpu_mb; 115 mb = &cx->scb->epu2cpu_mb;
115 *state = readl(&cx->scb->cpu_state); 116 *state = cx18_readl(cx, &cx->scb->cpu_state);
116 *irq = readl(&cx->scb->epu2cpu_irq); 117 *irq = cx18_readl(cx, &cx->scb->epu2cpu_irq);
117 break; 118 break;
118 119
119 case HPU: 120 case HPU:
120 mb = &cx->scb->epu2hpu_mb; 121 mb = &cx->scb->epu2hpu_mb;
121 *state = readl(&cx->scb->hpu_state); 122 *state = cx18_readl(cx, &cx->scb->hpu_state);
122 *irq = readl(&cx->scb->epu2hpu_irq); 123 *irq = cx18_readl(cx, &cx->scb->epu2hpu_irq);
123 break; 124 break;
124 } 125 }
125 126
126 if (mb == NULL) 127 if (mb == NULL)
127 return mb; 128 return mb;
128 129
129 do { 130 do {
130 *req = readl(&mb->request); 131 *req = cx18_readl(cx, &mb->request);
131 ack = readl(&mb->ack); 132 ack = cx18_readl(cx, &mb->ack);
132 wait_count++; 133 wait_count++;
133 } while (*req != ack && wait_count < 600); 134 } while (*req != ack && wait_count < 600);
134 135
135 if (*req == ack) { 136 if (*req == ack) {
136 (*req)++; 137 (*req)++;
137 if (*req == 0 || *req == 0xffffffff) 138 if (*req == 0 || *req == 0xffffffff)
138 *req = 1; 139 *req = 1;
139 return mb; 140 return mb;
140 } 141 }
141 return NULL; 142 return NULL;
142 } 143 }
143 144
144 long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) 145 long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb)
145 { 146 {
146 const struct cx18_api_info *info = find_api_info(mb->cmd); 147 const struct cx18_api_info *info = find_api_info(mb->cmd);
147 struct cx18_mailbox __iomem *ack_mb; 148 struct cx18_mailbox __iomem *ack_mb;
148 u32 ack_irq; 149 u32 ack_irq;
149 u8 rpu = CPU; 150 u8 rpu = CPU;
150 151
151 if (info == NULL && mb->cmd) { 152 if (info == NULL && mb->cmd) {
152 CX18_WARN("Cannot ack unknown command %x\n", mb->cmd); 153 CX18_WARN("Cannot ack unknown command %x\n", mb->cmd);
153 return -EINVAL; 154 return -EINVAL;
154 } 155 }
155 if (info) 156 if (info)
156 rpu = info->rpu; 157 rpu = info->rpu;
157 158
158 switch (rpu) { 159 switch (rpu) {
159 case HPU: 160 case HPU:
160 ack_irq = IRQ_EPU_TO_HPU_ACK; 161 ack_irq = IRQ_EPU_TO_HPU_ACK;
161 ack_mb = &cx->scb->hpu2epu_mb; 162 ack_mb = &cx->scb->hpu2epu_mb;
162 break; 163 break;
163 case APU: 164 case APU:
164 ack_irq = IRQ_EPU_TO_APU_ACK; 165 ack_irq = IRQ_EPU_TO_APU_ACK;
165 ack_mb = &cx->scb->apu2epu_mb; 166 ack_mb = &cx->scb->apu2epu_mb;
166 break; 167 break;
167 case CPU: 168 case CPU:
168 ack_irq = IRQ_EPU_TO_CPU_ACK; 169 ack_irq = IRQ_EPU_TO_CPU_ACK;
169 ack_mb = &cx->scb->cpu2epu_mb; 170 ack_mb = &cx->scb->cpu2epu_mb;
170 break; 171 break;
171 default: 172 default:
172 CX18_WARN("Unknown RPU for command %x\n", mb->cmd); 173 CX18_WARN("Unknown RPU for command %x\n", mb->cmd);
173 return -EINVAL; 174 return -EINVAL;
174 } 175 }
175 176
176 setup_page(SCB_OFFSET); 177 cx18_setup_page(cx, SCB_OFFSET);
177 write_sync(mb->request, &ack_mb->ack); 178 cx18_write_sync(cx, mb->request, &ack_mb->ack);
178 write_reg(ack_irq, SW2_INT_SET); 179 cx18_write_reg(cx, ack_irq, SW2_INT_SET);
179 return 0; 180 return 0;
180 } 181 }
181 182
182 183
183 static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) 184 static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
184 { 185 {
185 const struct cx18_api_info *info = find_api_info(cmd); 186 const struct cx18_api_info *info = find_api_info(cmd);
186 u32 state = 0, irq = 0, req, oldreq, err; 187 u32 state = 0, irq = 0, req, oldreq, err;
187 struct cx18_mailbox __iomem *mb; 188 struct cx18_mailbox __iomem *mb;
188 wait_queue_head_t *waitq; 189 wait_queue_head_t *waitq;
189 int timeout = 100; 190 int timeout = 100;
190 int cnt = 0; 191 int cnt = 0;
191 int sig = 0; 192 int sig = 0;
192 int i; 193 int i;
193 194
194 if (info == NULL) { 195 if (info == NULL) {
195 CX18_WARN("unknown cmd %x\n", cmd); 196 CX18_WARN("unknown cmd %x\n", cmd);
196 return -EINVAL; 197 return -EINVAL;
197 } 198 }
198 199
199 if (cmd == CX18_CPU_DE_SET_MDL) 200 if (cmd == CX18_CPU_DE_SET_MDL)
200 CX18_DEBUG_HI_API("%s\n", info->name); 201 CX18_DEBUG_HI_API("%s\n", info->name);
201 else 202 else
202 CX18_DEBUG_API("%s\n", info->name); 203 CX18_DEBUG_API("%s\n", info->name);
203 setup_page(SCB_OFFSET); 204 cx18_setup_page(cx, SCB_OFFSET);
204 mb = cx18_mb_is_complete(cx, info->rpu, &state, &irq, &req); 205 mb = cx18_mb_is_complete(cx, info->rpu, &state, &irq, &req);
205 206
206 if (mb == NULL) { 207 if (mb == NULL) {
207 CX18_ERR("mb %s busy\n", info->name); 208 CX18_ERR("mb %s busy\n", info->name);
208 return -EBUSY; 209 return -EBUSY;
209 } 210 }
210 211
211 oldreq = req - 1; 212 oldreq = req - 1;
212 writel(cmd, &mb->cmd); 213 cx18_writel(cx, cmd, &mb->cmd);
213 for (i = 0; i < args; i++) 214 for (i = 0; i < args; i++)
214 writel(data[i], &mb->args[i]); 215 cx18_writel(cx, data[i], &mb->args[i]);
215 writel(0, &mb->error); 216 cx18_writel(cx, 0, &mb->error);
216 writel(req, &mb->request); 217 cx18_writel(cx, req, &mb->request);
217 218
218 switch (info->rpu) { 219 switch (info->rpu) {
219 case APU: waitq = &cx->mb_apu_waitq; break; 220 case APU: waitq = &cx->mb_apu_waitq; break;
220 case CPU: waitq = &cx->mb_cpu_waitq; break; 221 case CPU: waitq = &cx->mb_cpu_waitq; break;
221 case EPU: waitq = &cx->mb_epu_waitq; break; 222 case EPU: waitq = &cx->mb_epu_waitq; break;
222 case HPU: waitq = &cx->mb_hpu_waitq; break; 223 case HPU: waitq = &cx->mb_hpu_waitq; break;
223 default: return -EINVAL; 224 default: return -EINVAL;
224 } 225 }
225 if (info->flags & API_FAST) 226 if (info->flags & API_FAST)
226 timeout /= 2; 227 timeout /= 2;
227 write_reg(irq, SW1_INT_SET); 228 cx18_write_reg(cx, irq, SW1_INT_SET);
228 229
229 while (!sig && readl(&mb->ack) != readl(&mb->request) && cnt < 660) { 230 while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request)
231 && cnt < 660) {
230 if (cnt > 200 && !in_atomic()) 232 if (cnt > 200 && !in_atomic())
231 sig = cx18_msleep_timeout(10, 1); 233 sig = cx18_msleep_timeout(10, 1);
232 cnt++; 234 cnt++;
233 } 235 }
234 if (sig) 236 if (sig)
235 return -EINTR; 237 return -EINTR;
236 if (cnt == 660) { 238 if (cnt == 660) {
237 writel(oldreq, &mb->request); 239 cx18_writel(cx, oldreq, &mb->request);
238 CX18_ERR("mb %s failed\n", info->name); 240 CX18_ERR("mb %s failed\n", info->name);
239 return -EINVAL; 241 return -EINVAL;
240 } 242 }
241 for (i = 0; i < MAX_MB_ARGUMENTS; i++) 243 for (i = 0; i < MAX_MB_ARGUMENTS; i++)
242 data[i] = readl(&mb->args[i]); 244 data[i] = cx18_readl(cx, &mb->args[i]);
243 err = readl(&mb->error); 245 err = cx18_readl(cx, &mb->error);
244 if (!in_atomic() && (info->flags & API_SLOW)) 246 if (!in_atomic() && (info->flags & API_SLOW))
245 cx18_msleep_timeout(300, 0); 247 cx18_msleep_timeout(300, 0);
246 if (err) 248 if (err)
247 CX18_DEBUG_API("mailbox error %08x for command %s\n", err, 249 CX18_DEBUG_API("mailbox error %08x for command %s\n", err,
248 info->name); 250 info->name);
249 return err ? -EIO : 0; 251 return err ? -EIO : 0;
250 } 252 }
251 253
252 int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]) 254 int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[])
253 { 255 {
254 int res = cx18_api_call(cx, cmd, args, data); 256 int res = cx18_api_call(cx, cmd, args, data);
255 257
256 /* Allow a single retry, probably already too late though. 258 /* Allow a single retry, probably already too late though.
257 If there is no free mailbox then that is usually an indication 259 If there is no free mailbox then that is usually an indication
258 of a more serious problem. */ 260 of a more serious problem. */
259 return (res == -EBUSY) ? cx18_api_call(cx, cmd, args, data) : res; 261 return (res == -EBUSY) ? cx18_api_call(cx, cmd, args, data) : res;
260 } 262 }
261 263
262 static int cx18_set_filter_param(struct cx18_stream *s) 264 static int cx18_set_filter_param(struct cx18_stream *s)
263 { 265 {
264 struct cx18 *cx = s->cx; 266 struct cx18 *cx = s->cx;
265 u32 mode; 267 u32 mode;
266 int ret; 268 int ret;
267 269
268 mode = (cx->filter_mode & 1) ? 2 : (cx->spatial_strength ? 1 : 0); 270 mode = (cx->filter_mode & 1) ? 2 : (cx->spatial_strength ? 1 : 0);
269 ret = cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4, 271 ret = cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
270 s->handle, 1, mode, cx->spatial_strength); 272 s->handle, 1, mode, cx->spatial_strength);
271 mode = (cx->filter_mode & 2) ? 2 : (cx->temporal_strength ? 1 : 0); 273 mode = (cx->filter_mode & 2) ? 2 : (cx->temporal_strength ? 1 : 0);
272 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4, 274 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
273 s->handle, 0, mode, cx->temporal_strength); 275 s->handle, 0, mode, cx->temporal_strength);
274 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4, 276 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
275 s->handle, 2, cx->filter_mode >> 2, 0); 277 s->handle, 2, cx->filter_mode >> 2, 0);
276 return ret; 278 return ret;
277 } 279 }
278 280
279 int cx18_api_func(void *priv, u32 cmd, int in, int out, 281 int cx18_api_func(void *priv, u32 cmd, int in, int out,
280 u32 data[CX2341X_MBOX_MAX_DATA]) 282 u32 data[CX2341X_MBOX_MAX_DATA])
281 { 283 {
282 struct cx18 *cx = priv; 284 struct cx18 *cx = priv;
283 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; 285 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
284 286
285 switch (cmd) { 287 switch (cmd) {
286 case CX2341X_ENC_SET_OUTPUT_PORT: 288 case CX2341X_ENC_SET_OUTPUT_PORT:
287 return 0; 289 return 0;
288 case CX2341X_ENC_SET_FRAME_RATE: 290 case CX2341X_ENC_SET_FRAME_RATE:
289 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_IN, 6, 291 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_IN, 6,
290 s->handle, 0, 0, 0, 0, data[0]); 292 s->handle, 0, 0, 0, 0, data[0]);
291 case CX2341X_ENC_SET_FRAME_SIZE: 293 case CX2341X_ENC_SET_FRAME_SIZE:
292 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RESOLUTION, 3, 294 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RESOLUTION, 3,
293 s->handle, data[1], data[0]); 295 s->handle, data[1], data[0]);
294 case CX2341X_ENC_SET_STREAM_TYPE: 296 case CX2341X_ENC_SET_STREAM_TYPE:
295 return cx18_vapi(cx, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 2, 297 return cx18_vapi(cx, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 2,
296 s->handle, data[0]); 298 s->handle, data[0]);
297 case CX2341X_ENC_SET_ASPECT_RATIO: 299 case CX2341X_ENC_SET_ASPECT_RATIO:
298 return cx18_vapi(cx, CX18_CPU_SET_ASPECT_RATIO, 2, 300 return cx18_vapi(cx, CX18_CPU_SET_ASPECT_RATIO, 2,
299 s->handle, data[0]); 301 s->handle, data[0]);
300 302
301 case CX2341X_ENC_SET_GOP_PROPERTIES: 303 case CX2341X_ENC_SET_GOP_PROPERTIES:
302 return cx18_vapi(cx, CX18_CPU_SET_GOP_STRUCTURE, 3, 304 return cx18_vapi(cx, CX18_CPU_SET_GOP_STRUCTURE, 3,
303 s->handle, data[0], data[1]); 305 s->handle, data[0], data[1]);
304 case CX2341X_ENC_SET_GOP_CLOSURE: 306 case CX2341X_ENC_SET_GOP_CLOSURE:
305 return 0; 307 return 0;
306 case CX2341X_ENC_SET_AUDIO_PROPERTIES: 308 case CX2341X_ENC_SET_AUDIO_PROPERTIES:
307 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2, 309 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2,
308 s->handle, data[0]); 310 s->handle, data[0]);
309 case CX2341X_ENC_MUTE_AUDIO: 311 case CX2341X_ENC_MUTE_AUDIO:
310 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, 312 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
311 s->handle, data[0]); 313 s->handle, data[0]);
312 case CX2341X_ENC_SET_BIT_RATE: 314 case CX2341X_ENC_SET_BIT_RATE:
313 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RATE, 5, 315 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RATE, 5,
314 s->handle, data[0], data[1], data[2], data[3]); 316 s->handle, data[0], data[1], data[2], data[3]);
315 case CX2341X_ENC_MUTE_VIDEO: 317 case CX2341X_ENC_MUTE_VIDEO:
316 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, 318 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
317 s->handle, data[0]); 319 s->handle, data[0]);
318 case CX2341X_ENC_SET_FRAME_DROP_RATE: 320 case CX2341X_ENC_SET_FRAME_DROP_RATE:
319 return cx18_vapi(cx, CX18_CPU_SET_SKIP_INPUT_FRAME, 2, 321 return cx18_vapi(cx, CX18_CPU_SET_SKIP_INPUT_FRAME, 2,
320 s->handle, data[0]); 322 s->handle, data[0]);
321 case CX2341X_ENC_MISC: 323 case CX2341X_ENC_MISC:
322 return cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 4, 324 return cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 4,
323 s->handle, data[0], data[1], data[2]); 325 s->handle, data[0], data[1], data[2]);
324 case CX2341X_ENC_SET_DNR_FILTER_MODE: 326 case CX2341X_ENC_SET_DNR_FILTER_MODE:
325 cx->filter_mode = (data[0] & 3) | (data[1] << 2); 327 cx->filter_mode = (data[0] & 3) | (data[1] << 2);
326 return cx18_set_filter_param(s); 328 return cx18_set_filter_param(s);
327 case CX2341X_ENC_SET_DNR_FILTER_PROPS: 329 case CX2341X_ENC_SET_DNR_FILTER_PROPS:
328 cx->spatial_strength = data[0]; 330 cx->spatial_strength = data[0];
329 cx->temporal_strength = data[1]; 331 cx->temporal_strength = data[1];
330 return cx18_set_filter_param(s); 332 return cx18_set_filter_param(s);
331 case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE: 333 case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE:
332 return cx18_vapi(cx, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 3, 334 return cx18_vapi(cx, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 3,
333 s->handle, data[0], data[1]); 335 s->handle, data[0], data[1]);
334 case CX2341X_ENC_SET_CORING_LEVELS: 336 case CX2341X_ENC_SET_CORING_LEVELS:
335 return cx18_vapi(cx, CX18_CPU_SET_MEDIAN_CORING, 5, 337 return cx18_vapi(cx, CX18_CPU_SET_MEDIAN_CORING, 5,
336 s->handle, data[0], data[1], data[2], data[3]); 338 s->handle, data[0], data[1], data[2], data[3]);
337 } 339 }
338 CX18_WARN("Unknown cmd %x\n", cmd); 340 CX18_WARN("Unknown cmd %x\n", cmd);
339 return 0; 341 return 0;
340 } 342 }
341 343
342 int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], 344 int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS],
343 u32 cmd, int args, ...) 345 u32 cmd, int args, ...)
344 { 346 {
345 va_list ap; 347 va_list ap;
346 int i; 348 int i;
347 349
348 va_start(ap, args); 350 va_start(ap, args);
349 for (i = 0; i < args; i++) 351 for (i = 0; i < args; i++)
350 data[i] = va_arg(ap, u32); 352 data[i] = va_arg(ap, u32);
351 va_end(ap); 353 va_end(ap);
352 return cx18_api(cx, cmd, args, data); 354 return cx18_api(cx, cmd, args, data);
353 } 355 }
354 356
355 int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...) 357 int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...)
356 { 358 {
357 u32 data[MAX_MB_ARGUMENTS]; 359 u32 data[MAX_MB_ARGUMENTS];
358 va_list ap; 360 va_list ap;
359 int i; 361 int i;
360 362
361 if (cx == NULL) { 363 if (cx == NULL) {
362 CX18_ERR("cx == NULL (cmd=%x)\n", cmd); 364 CX18_ERR("cx == NULL (cmd=%x)\n", cmd);
363 return 0; 365 return 0;
364 } 366 }
365 if (args > MAX_MB_ARGUMENTS) { 367 if (args > MAX_MB_ARGUMENTS) {
366 CX18_ERR("args too big (cmd=%x)\n", cmd); 368 CX18_ERR("args too big (cmd=%x)\n", cmd);
367 args = MAX_MB_ARGUMENTS; 369 args = MAX_MB_ARGUMENTS;
368 } 370 }
369 va_start(ap, args); 371 va_start(ap, args);
370 for (i = 0; i < args; i++) 372 for (i = 0; i < args; i++)
371 data[i] = va_arg(ap, u32); 373 data[i] = va_arg(ap, u32);
372 va_end(ap); 374 va_end(ap);
373 return cx18_api(cx, cmd, args, data); 375 return cx18_api(cx, cmd, args, data);
374 } 376 }
375 377
drivers/media/video/cx18/cx18-queue.c
1 /* 1 /*
2 * cx18 buffer queues 2 * cx18 buffer queues
3 * 3 *
4 * Derived from ivtv-queue.c 4 * Derived from ivtv-queue.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 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 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 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 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24 #include "cx18-driver.h" 24 #include "cx18-driver.h"
25 #include "cx18-streams.h" 25 #include "cx18-streams.h"
26 #include "cx18-queue.h" 26 #include "cx18-queue.h"
27 #include "cx18-scb.h" 27 #include "cx18-scb.h"
28 28
29 void cx18_buf_swap(struct cx18_buffer *buf) 29 void cx18_buf_swap(struct cx18_buffer *buf)
30 { 30 {
31 int i; 31 int i;
32 32
33 for (i = 0; i < buf->bytesused; i += 4) 33 for (i = 0; i < buf->bytesused; i += 4)
34 swab32s((u32 *)(buf->buf + i)); 34 swab32s((u32 *)(buf->buf + i));
35 } 35 }
36 36
37 void cx18_queue_init(struct cx18_queue *q) 37 void cx18_queue_init(struct cx18_queue *q)
38 { 38 {
39 INIT_LIST_HEAD(&q->list); 39 INIT_LIST_HEAD(&q->list);
40 atomic_set(&q->buffers, 0); 40 atomic_set(&q->buffers, 0);
41 q->bytesused = 0; 41 q->bytesused = 0;
42 } 42 }
43 43
44 void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 44 void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
45 struct cx18_queue *q) 45 struct cx18_queue *q)
46 { 46 {
47 unsigned long flags = 0; 47 unsigned long flags = 0;
48 48
49 /* clear the buffer if it is going to be enqueued to the free queue */ 49 /* clear the buffer if it is going to be enqueued to the free queue */
50 if (q == &s->q_free) { 50 if (q == &s->q_free) {
51 buf->bytesused = 0; 51 buf->bytesused = 0;
52 buf->readpos = 0; 52 buf->readpos = 0;
53 buf->b_flags = 0; 53 buf->b_flags = 0;
54 } 54 }
55 spin_lock_irqsave(&s->qlock, flags); 55 spin_lock_irqsave(&s->qlock, flags);
56 list_add_tail(&buf->list, &q->list); 56 list_add_tail(&buf->list, &q->list);
57 atomic_inc(&q->buffers); 57 atomic_inc(&q->buffers);
58 q->bytesused += buf->bytesused - buf->readpos; 58 q->bytesused += buf->bytesused - buf->readpos;
59 spin_unlock_irqrestore(&s->qlock, flags); 59 spin_unlock_irqrestore(&s->qlock, flags);
60 } 60 }
61 61
62 struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) 62 struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
63 { 63 {
64 struct cx18_buffer *buf = NULL; 64 struct cx18_buffer *buf = NULL;
65 unsigned long flags = 0; 65 unsigned long flags = 0;
66 66
67 spin_lock_irqsave(&s->qlock, flags); 67 spin_lock_irqsave(&s->qlock, flags);
68 if (!list_empty(&q->list)) { 68 if (!list_empty(&q->list)) {
69 buf = list_entry(q->list.next, struct cx18_buffer, list); 69 buf = list_entry(q->list.next, struct cx18_buffer, list);
70 list_del_init(q->list.next); 70 list_del_init(q->list.next);
71 atomic_dec(&q->buffers); 71 atomic_dec(&q->buffers);
72 q->bytesused -= buf->bytesused - buf->readpos; 72 q->bytesused -= buf->bytesused - buf->readpos;
73 } 73 }
74 spin_unlock_irqrestore(&s->qlock, flags); 74 spin_unlock_irqrestore(&s->qlock, flags);
75 return buf; 75 return buf;
76 } 76 }
77 77
78 struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, 78 struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id,
79 u32 bytesused) 79 u32 bytesused)
80 { 80 {
81 struct cx18 *cx = s->cx; 81 struct cx18 *cx = s->cx;
82 struct list_head *p; 82 struct list_head *p;
83 83
84 spin_lock(&s->qlock); 84 spin_lock(&s->qlock);
85 list_for_each(p, &s->q_free.list) { 85 list_for_each(p, &s->q_free.list) {
86 struct cx18_buffer *buf = 86 struct cx18_buffer *buf =
87 list_entry(p, struct cx18_buffer, list); 87 list_entry(p, struct cx18_buffer, list);
88 88
89 if (buf->id != id) 89 if (buf->id != id)
90 continue; 90 continue;
91 buf->bytesused = bytesused; 91 buf->bytesused = bytesused;
92 /* the transport buffers are handled differently, 92 /* the transport buffers are handled differently,
93 they are not moved to the full queue */ 93 they are not moved to the full queue */
94 if (s->type != CX18_ENC_STREAM_TYPE_TS) { 94 if (s->type != CX18_ENC_STREAM_TYPE_TS) {
95 atomic_dec(&s->q_free.buffers); 95 atomic_dec(&s->q_free.buffers);
96 atomic_inc(&s->q_full.buffers); 96 atomic_inc(&s->q_full.buffers);
97 s->q_full.bytesused += buf->bytesused; 97 s->q_full.bytesused += buf->bytesused;
98 list_move_tail(&buf->list, &s->q_full.list); 98 list_move_tail(&buf->list, &s->q_full.list);
99 } 99 }
100 spin_unlock(&s->qlock); 100 spin_unlock(&s->qlock);
101 return buf; 101 return buf;
102 } 102 }
103 spin_unlock(&s->qlock); 103 spin_unlock(&s->qlock);
104 CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); 104 CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name);
105 return NULL; 105 return NULL;
106 } 106 }
107 107
108 /* Move all buffers of a queue to q_free, while flushing the buffers */ 108 /* Move all buffers of a queue to q_free, while flushing the buffers */
109 static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) 109 static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
110 { 110 {
111 unsigned long flags; 111 unsigned long flags;
112 struct cx18_buffer *buf; 112 struct cx18_buffer *buf;
113 113
114 if (q == &s->q_free) 114 if (q == &s->q_free)
115 return; 115 return;
116 116
117 spin_lock_irqsave(&s->qlock, flags); 117 spin_lock_irqsave(&s->qlock, flags);
118 while (!list_empty(&q->list)) { 118 while (!list_empty(&q->list)) {
119 buf = list_entry(q->list.next, struct cx18_buffer, list); 119 buf = list_entry(q->list.next, struct cx18_buffer, list);
120 list_move_tail(q->list.next, &s->q_free.list); 120 list_move_tail(q->list.next, &s->q_free.list);
121 buf->bytesused = buf->readpos = buf->b_flags = 0; 121 buf->bytesused = buf->readpos = buf->b_flags = 0;
122 atomic_inc(&s->q_free.buffers); 122 atomic_inc(&s->q_free.buffers);
123 } 123 }
124 cx18_queue_init(q); 124 cx18_queue_init(q);
125 spin_unlock_irqrestore(&s->qlock, flags); 125 spin_unlock_irqrestore(&s->qlock, flags);
126 } 126 }
127 127
128 void cx18_flush_queues(struct cx18_stream *s) 128 void cx18_flush_queues(struct cx18_stream *s)
129 { 129 {
130 cx18_queue_flush(s, &s->q_io); 130 cx18_queue_flush(s, &s->q_io);
131 cx18_queue_flush(s, &s->q_full); 131 cx18_queue_flush(s, &s->q_full);
132 } 132 }
133 133
134 int cx18_stream_alloc(struct cx18_stream *s) 134 int cx18_stream_alloc(struct cx18_stream *s)
135 { 135 {
136 struct cx18 *cx = s->cx; 136 struct cx18 *cx = s->cx;
137 int i; 137 int i;
138 138
139 if (s->buffers == 0) 139 if (s->buffers == 0)
140 return 0; 140 return 0;
141 141
142 CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n", 142 CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n",
143 s->name, s->buffers, s->buf_size, 143 s->name, s->buffers, s->buf_size,
144 s->buffers * s->buf_size / 1024); 144 s->buffers * s->buf_size / 1024);
145 145
146 if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] - 146 if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] -
147 (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) { 147 (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
148 unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE - 148 unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE -
149 ((char __iomem *)cx->scb->cpu_mdl)); 149 ((char __iomem *)cx->scb->cpu_mdl));
150 150
151 CX18_ERR("Too many buffers, cannot fit in SCB area\n"); 151 CX18_ERR("Too many buffers, cannot fit in SCB area\n");
152 CX18_ERR("Max buffers = %zd\n", 152 CX18_ERR("Max buffers = %zd\n",
153 bufsz / sizeof(struct cx18_mdl)); 153 bufsz / sizeof(struct cx18_mdl));
154 return -ENOMEM; 154 return -ENOMEM;
155 } 155 }
156 156
157 s->mdl_offset = cx->mdl_offset; 157 s->mdl_offset = cx->mdl_offset;
158 158
159 /* allocate stream buffers. Initially all buffers are in q_free. */ 159 /* allocate stream buffers. Initially all buffers are in q_free. */
160 for (i = 0; i < s->buffers; i++) { 160 for (i = 0; i < s->buffers; i++) {
161 struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer), 161 struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer),
162 GFP_KERNEL|__GFP_NOWARN); 162 GFP_KERNEL|__GFP_NOWARN);
163 163
164 if (buf == NULL) 164 if (buf == NULL)
165 break; 165 break;
166 buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN); 166 buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
167 if (buf->buf == NULL) { 167 if (buf->buf == NULL) {
168 kfree(buf); 168 kfree(buf);
169 break; 169 break;
170 } 170 }
171 buf->id = cx->buffer_id++; 171 buf->id = cx->buffer_id++;
172 INIT_LIST_HEAD(&buf->list); 172 INIT_LIST_HEAD(&buf->list);
173 /* FIXME - check for mmio */
173 buf->dma_handle = pci_map_single(s->cx->dev, 174 buf->dma_handle = pci_map_single(s->cx->dev,
174 buf->buf, s->buf_size, s->dma); 175 buf->buf, s->buf_size, s->dma);
175 cx18_buf_sync_for_cpu(s, buf); 176 cx18_buf_sync_for_cpu(s, buf);
176 cx18_enqueue(s, buf, &s->q_free); 177 cx18_enqueue(s, buf, &s->q_free);
177 } 178 }
178 if (i == s->buffers) { 179 if (i == s->buffers) {
179 cx->mdl_offset += s->buffers; 180 cx->mdl_offset += s->buffers;
180 return 0; 181 return 0;
181 } 182 }
182 CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name); 183 CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name);
183 cx18_stream_free(s); 184 cx18_stream_free(s);
184 return -ENOMEM; 185 return -ENOMEM;
185 } 186 }
186 187
187 void cx18_stream_free(struct cx18_stream *s) 188 void cx18_stream_free(struct cx18_stream *s)
188 { 189 {
189 struct cx18_buffer *buf; 190 struct cx18_buffer *buf;
190 191
191 /* move all buffers to q_free */ 192 /* move all buffers to q_free */
192 cx18_flush_queues(s); 193 cx18_flush_queues(s);
193 194
194 /* empty q_free */ 195 /* empty q_free */
195 while ((buf = cx18_dequeue(s, &s->q_free))) { 196 while ((buf = cx18_dequeue(s, &s->q_free))) {
197 /* FIXME - check for mmio */
196 pci_unmap_single(s->cx->dev, buf->dma_handle, 198 pci_unmap_single(s->cx->dev, buf->dma_handle,
197 s->buf_size, s->dma); 199 s->buf_size, s->dma);
198 kfree(buf->buf); 200 kfree(buf->buf);
199 kfree(buf); 201 kfree(buf);
200 } 202 }
201 } 203 }
202 204
drivers/media/video/cx18/cx18-queue.h
1 /* 1 /*
2 * cx18 buffer queues 2 * cx18 buffer queues
3 * 3 *
4 * Derived from ivtv-queue.h 4 * Derived from ivtv-queue.h
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 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 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 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 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24 #define CX18_DMA_UNMAPPED ((u32) -1) 24 #define CX18_DMA_UNMAPPED ((u32) -1)
25 25
26 /* cx18_buffer utility functions */ 26 /* cx18_buffer utility functions */
27 27
28 static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s, 28 static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
29 struct cx18_buffer *buf) 29 struct cx18_buffer *buf)
30 { 30 {
31 /* FIXME check IO transfers */
31 pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle, 32 pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle,
32 s->buf_size, s->dma); 33 s->buf_size, s->dma);
33 } 34 }
34 35
35 static inline void cx18_buf_sync_for_device(struct cx18_stream *s, 36 static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
36 struct cx18_buffer *buf) 37 struct cx18_buffer *buf)
37 { 38 {
39 /* FIXME check IO transfers */
38 pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle, 40 pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle,
39 s->buf_size, s->dma); 41 s->buf_size, s->dma);
40 } 42 }
41 43
42 void cx18_buf_swap(struct cx18_buffer *buf); 44 void cx18_buf_swap(struct cx18_buffer *buf);
43 45
44 /* cx18_queue utility functions */ 46 /* cx18_queue utility functions */
45 void cx18_queue_init(struct cx18_queue *q); 47 void cx18_queue_init(struct cx18_queue *q);
46 void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 48 void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
47 struct cx18_queue *q); 49 struct cx18_queue *q);
48 struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); 50 struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
49 struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, 51 struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id,
50 u32 bytesused); 52 u32 bytesused);
51 void cx18_flush_queues(struct cx18_stream *s); 53 void cx18_flush_queues(struct cx18_stream *s);
52 54
53 /* cx18_stream utility functions */ 55 /* cx18_stream utility functions */
54 int cx18_stream_alloc(struct cx18_stream *s); 56 int cx18_stream_alloc(struct cx18_stream *s);
55 void cx18_stream_free(struct cx18_stream *s); 57 void cx18_stream_free(struct cx18_stream *s);
56 58
drivers/media/video/cx18/cx18-scb.c
1 /* 1 /*
2 * cx18 System Control Block initialization 2 * cx18 System Control Block initialization
3 * 3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 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 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 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA 19 * 02111-1307 USA
20 */ 20 */
21 21
22 #include "cx18-driver.h" 22 #include "cx18-driver.h"
23 #include "cx18-io.h"
23 #include "cx18-scb.h" 24 #include "cx18-scb.h"
24 25
25 void cx18_init_scb(struct cx18 *cx) 26 void cx18_init_scb(struct cx18 *cx)
26 { 27 {
27 setup_page(SCB_OFFSET); 28 cx18_setup_page(cx, SCB_OFFSET);
28 memset_io(cx->scb, 0, 0x10000); 29 cx18_memset_io(cx, cx->scb, 0, 0x10000);
29 30
30 writel(IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq); 31 cx18_writel(cx, IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq);
31 writel(IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack); 32 cx18_writel(cx, IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack);
32 writel(IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq); 33 cx18_writel(cx, IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq);
33 writel(IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack); 34 cx18_writel(cx, IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack);
34 writel(IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq); 35 cx18_writel(cx, IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq);
35 writel(IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack); 36 cx18_writel(cx, IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack);
36 writel(IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq); 37 cx18_writel(cx, IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq);
37 writel(IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack); 38 cx18_writel(cx, IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack);
38 39
39 writel(IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq); 40 cx18_writel(cx, IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq);
40 writel(IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack); 41 cx18_writel(cx, IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack);
41 writel(IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq); 42 cx18_writel(cx, IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq);
42 writel(IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack); 43 cx18_writel(cx, IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack);
43 writel(IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq); 44 cx18_writel(cx, IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq);
44 writel(IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack); 45 cx18_writel(cx, IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack);
45 writel(IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq); 46 cx18_writel(cx, IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq);
46 writel(IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack); 47 cx18_writel(cx, IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack);
47 48
48 writel(IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq); 49 cx18_writel(cx, IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq);
49 writel(IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack); 50 cx18_writel(cx, IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack);
50 writel(IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq); 51 cx18_writel(cx, IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq);
51 writel(IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack); 52 cx18_writel(cx, IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack);
52 writel(IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq); 53 cx18_writel(cx, IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq);
53 writel(IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack); 54 cx18_writel(cx, IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack);
54 writel(IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq); 55 cx18_writel(cx, IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq);
55 writel(IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack); 56 cx18_writel(cx, IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack);
56 57
57 writel(IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq); 58 cx18_writel(cx, IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq);
58 writel(IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack); 59 cx18_writel(cx, IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack);
59 writel(IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq); 60 cx18_writel(cx, IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq);
60 writel(IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack); 61 cx18_writel(cx, IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack);
61 writel(IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq); 62 cx18_writel(cx, IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq);
62 writel(IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack); 63 cx18_writel(cx, IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack);
63 writel(IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq); 64 cx18_writel(cx, IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq);
64 writel(IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack); 65 cx18_writel(cx, IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack);
65 66
66 writel(IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq); 67 cx18_writel(cx, IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq);
67 writel(IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack); 68 cx18_writel(cx, IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack);
68 writel(IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq); 69 cx18_writel(cx, IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq);
69 writel(IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack); 70 cx18_writel(cx, IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack);
70 writel(IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq); 71 cx18_writel(cx, IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq);
71 writel(IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack); 72 cx18_writel(cx, IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack);
72 writel(IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq); 73 cx18_writel(cx, IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq);
73 writel(IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack); 74 cx18_writel(cx, IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack);
74 75
75 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb), 76 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb),
76 &cx->scb->apu2cpu_mb_offset); 77 &cx->scb->apu2cpu_mb_offset);
77 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb), 78 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb),
78 &cx->scb->hpu2cpu_mb_offset); 79 &cx->scb->hpu2cpu_mb_offset);
79 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb), 80 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb),
80 &cx->scb->ppu2cpu_mb_offset); 81 &cx->scb->ppu2cpu_mb_offset);
81 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb), 82 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb),
82 &cx->scb->epu2cpu_mb_offset); 83 &cx->scb->epu2cpu_mb_offset);
83 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb), 84 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb),
84 &cx->scb->cpu2apu_mb_offset); 85 &cx->scb->cpu2apu_mb_offset);
85 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb), 86 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb),
86 &cx->scb->hpu2apu_mb_offset); 87 &cx->scb->hpu2apu_mb_offset);
87 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb), 88 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb),
88 &cx->scb->ppu2apu_mb_offset); 89 &cx->scb->ppu2apu_mb_offset);
89 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb), 90 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb),
90 &cx->scb->epu2apu_mb_offset); 91 &cx->scb->epu2apu_mb_offset);
91 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb), 92 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb),
92 &cx->scb->cpu2hpu_mb_offset); 93 &cx->scb->cpu2hpu_mb_offset);
93 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb), 94 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb),
94 &cx->scb->apu2hpu_mb_offset); 95 &cx->scb->apu2hpu_mb_offset);
95 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb), 96 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb),
96 &cx->scb->ppu2hpu_mb_offset); 97 &cx->scb->ppu2hpu_mb_offset);
97 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb), 98 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb),
98 &cx->scb->epu2hpu_mb_offset); 99 &cx->scb->epu2hpu_mb_offset);
99 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb), 100 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb),
100 &cx->scb->cpu2ppu_mb_offset); 101 &cx->scb->cpu2ppu_mb_offset);
101 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb), 102 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb),
102 &cx->scb->apu2ppu_mb_offset); 103 &cx->scb->apu2ppu_mb_offset);
103 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb), 104 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb),
104 &cx->scb->hpu2ppu_mb_offset); 105 &cx->scb->hpu2ppu_mb_offset);
105 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb), 106 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb),
106 &cx->scb->epu2ppu_mb_offset); 107 &cx->scb->epu2ppu_mb_offset);
107 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb), 108 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb),
108 &cx->scb->cpu2epu_mb_offset); 109 &cx->scb->cpu2epu_mb_offset);
109 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb), 110 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb),
110 &cx->scb->apu2epu_mb_offset); 111 &cx->scb->apu2epu_mb_offset);
111 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb), 112 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb),
112 &cx->scb->hpu2epu_mb_offset); 113 &cx->scb->hpu2epu_mb_offset);
113 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb), 114 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb),
114 &cx->scb->ppu2epu_mb_offset); 115 &cx->scb->ppu2epu_mb_offset);
115 116
116 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu_state), 117 cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu_state),
117 &cx->scb->ipc_offset); 118 &cx->scb->ipc_offset);
118 119
119 writel(1, &cx->scb->hpu_state); 120 cx18_writel(cx, 1, &cx->scb->hpu_state);
120 writel(1, &cx->scb->epu_state); 121 cx18_writel(cx, 1, &cx->scb->epu_state);
121 } 122 }
122 123
drivers/media/video/cx18/cx18-streams.c
1 /* 1 /*
2 * cx18 init/start/stop/exit stream functions 2 * cx18 init/start/stop/exit stream functions
3 * 3 *
4 * Derived from ivtv-streams.c 4 * Derived from ivtv-streams.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 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 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 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 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24 #include "cx18-driver.h" 24 #include "cx18-driver.h"
25 #include "cx18-io.h"
25 #include "cx18-fileops.h" 26 #include "cx18-fileops.h"
26 #include "cx18-mailbox.h" 27 #include "cx18-mailbox.h"
27 #include "cx18-i2c.h" 28 #include "cx18-i2c.h"
28 #include "cx18-queue.h" 29 #include "cx18-queue.h"
29 #include "cx18-ioctl.h" 30 #include "cx18-ioctl.h"
30 #include "cx18-streams.h" 31 #include "cx18-streams.h"
31 #include "cx18-cards.h" 32 #include "cx18-cards.h"
32 #include "cx18-scb.h" 33 #include "cx18-scb.h"
33 #include "cx18-av-core.h" 34 #include "cx18-av-core.h"
34 #include "cx18-dvb.h" 35 #include "cx18-dvb.h"
35 36
36 #define CX18_DSP0_INTERRUPT_MASK 0xd0004C 37 #define CX18_DSP0_INTERRUPT_MASK 0xd0004C
37 38
38 static struct file_operations cx18_v4l2_enc_fops = { 39 static struct file_operations cx18_v4l2_enc_fops = {
39 .owner = THIS_MODULE, 40 .owner = THIS_MODULE,
40 .read = cx18_v4l2_read, 41 .read = cx18_v4l2_read,
41 .open = cx18_v4l2_open, 42 .open = cx18_v4l2_open,
42 /* FIXME change to video_ioctl2 if serialization lock can be removed */ 43 /* FIXME change to video_ioctl2 if serialization lock can be removed */
43 .ioctl = cx18_v4l2_ioctl, 44 .ioctl = cx18_v4l2_ioctl,
44 .compat_ioctl = v4l_compat_ioctl32, 45 .compat_ioctl = v4l_compat_ioctl32,
45 .release = cx18_v4l2_close, 46 .release = cx18_v4l2_close,
46 .poll = cx18_v4l2_enc_poll, 47 .poll = cx18_v4l2_enc_poll,
47 }; 48 };
48 49
49 /* offset from 0 to register ts v4l2 minors on */ 50 /* offset from 0 to register ts v4l2 minors on */
50 #define CX18_V4L2_ENC_TS_OFFSET 16 51 #define CX18_V4L2_ENC_TS_OFFSET 16
51 /* offset from 0 to register pcm v4l2 minors on */ 52 /* offset from 0 to register pcm v4l2 minors on */
52 #define CX18_V4L2_ENC_PCM_OFFSET 24 53 #define CX18_V4L2_ENC_PCM_OFFSET 24
53 /* offset from 0 to register yuv v4l2 minors on */ 54 /* offset from 0 to register yuv v4l2 minors on */
54 #define CX18_V4L2_ENC_YUV_OFFSET 32 55 #define CX18_V4L2_ENC_YUV_OFFSET 32
55 56
56 static struct { 57 static struct {
57 const char *name; 58 const char *name;
58 int vfl_type; 59 int vfl_type;
59 int minor_offset; 60 int minor_offset;
60 int dma; 61 int dma;
61 enum v4l2_buf_type buf_type; 62 enum v4l2_buf_type buf_type;
62 struct file_operations *fops; 63 struct file_operations *fops;
63 } cx18_stream_info[] = { 64 } cx18_stream_info[] = {
64 { /* CX18_ENC_STREAM_TYPE_MPG */ 65 { /* CX18_ENC_STREAM_TYPE_MPG */
65 "encoder MPEG", 66 "encoder MPEG",
66 VFL_TYPE_GRABBER, 0, 67 VFL_TYPE_GRABBER, 0,
67 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, 68 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
68 &cx18_v4l2_enc_fops 69 &cx18_v4l2_enc_fops
69 }, 70 },
70 { /* CX18_ENC_STREAM_TYPE_TS */ 71 { /* CX18_ENC_STREAM_TYPE_TS */
71 "TS", 72 "TS",
72 VFL_TYPE_GRABBER, -1, 73 VFL_TYPE_GRABBER, -1,
73 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, 74 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
74 &cx18_v4l2_enc_fops 75 &cx18_v4l2_enc_fops
75 }, 76 },
76 { /* CX18_ENC_STREAM_TYPE_YUV */ 77 { /* CX18_ENC_STREAM_TYPE_YUV */
77 "encoder YUV", 78 "encoder YUV",
78 VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET, 79 VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET,
79 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, 80 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
80 &cx18_v4l2_enc_fops 81 &cx18_v4l2_enc_fops
81 }, 82 },
82 { /* CX18_ENC_STREAM_TYPE_VBI */ 83 { /* CX18_ENC_STREAM_TYPE_VBI */
83 "encoder VBI", 84 "encoder VBI",
84 VFL_TYPE_VBI, 0, 85 VFL_TYPE_VBI, 0,
85 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE, 86 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE,
86 &cx18_v4l2_enc_fops 87 &cx18_v4l2_enc_fops
87 }, 88 },
88 { /* CX18_ENC_STREAM_TYPE_PCM */ 89 { /* CX18_ENC_STREAM_TYPE_PCM */
89 "encoder PCM audio", 90 "encoder PCM audio",
90 VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET, 91 VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET,
91 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE, 92 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE,
92 &cx18_v4l2_enc_fops 93 &cx18_v4l2_enc_fops
93 }, 94 },
94 { /* CX18_ENC_STREAM_TYPE_IDX */ 95 { /* CX18_ENC_STREAM_TYPE_IDX */
95 "encoder IDX", 96 "encoder IDX",
96 VFL_TYPE_GRABBER, -1, 97 VFL_TYPE_GRABBER, -1,
97 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, 98 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
98 &cx18_v4l2_enc_fops 99 &cx18_v4l2_enc_fops
99 }, 100 },
100 { /* CX18_ENC_STREAM_TYPE_RAD */ 101 { /* CX18_ENC_STREAM_TYPE_RAD */
101 "encoder radio", 102 "encoder radio",
102 VFL_TYPE_RADIO, 0, 103 VFL_TYPE_RADIO, 0,
103 PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE, 104 PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE,
104 &cx18_v4l2_enc_fops 105 &cx18_v4l2_enc_fops
105 }, 106 },
106 }; 107 };
107 108
108 static void cx18_stream_init(struct cx18 *cx, int type) 109 static void cx18_stream_init(struct cx18 *cx, int type)
109 { 110 {
110 struct cx18_stream *s = &cx->streams[type]; 111 struct cx18_stream *s = &cx->streams[type];
111 struct video_device *dev = s->v4l2dev; 112 struct video_device *dev = s->v4l2dev;
112 u32 max_size = cx->options.megabytes[type] * 1024 * 1024; 113 u32 max_size = cx->options.megabytes[type] * 1024 * 1024;
113 114
114 /* we need to keep v4l2dev, so restore it afterwards */ 115 /* we need to keep v4l2dev, so restore it afterwards */
115 memset(s, 0, sizeof(*s)); 116 memset(s, 0, sizeof(*s));
116 s->v4l2dev = dev; 117 s->v4l2dev = dev;
117 118
118 /* initialize cx18_stream fields */ 119 /* initialize cx18_stream fields */
119 s->cx = cx; 120 s->cx = cx;
120 s->type = type; 121 s->type = type;
121 s->name = cx18_stream_info[type].name; 122 s->name = cx18_stream_info[type].name;
122 s->handle = CX18_INVALID_TASK_HANDLE; 123 s->handle = CX18_INVALID_TASK_HANDLE;
123 124
124 s->dma = cx18_stream_info[type].dma; 125 s->dma = cx18_stream_info[type].dma;
125 s->buf_size = cx->stream_buf_size[type]; 126 s->buf_size = cx->stream_buf_size[type];
126 if (s->buf_size) 127 if (s->buf_size)
127 s->buffers = max_size / s->buf_size; 128 s->buffers = max_size / s->buf_size;
128 if (s->buffers > 63) { 129 if (s->buffers > 63) {
129 /* Each stream has a maximum of 63 buffers, 130 /* Each stream has a maximum of 63 buffers,
130 ensure we do not exceed that. */ 131 ensure we do not exceed that. */
131 s->buffers = 63; 132 s->buffers = 63;
132 s->buf_size = (max_size / s->buffers) & ~0xfff; 133 s->buf_size = (max_size / s->buffers) & ~0xfff;
133 } 134 }
134 spin_lock_init(&s->qlock); 135 spin_lock_init(&s->qlock);
135 init_waitqueue_head(&s->waitq); 136 init_waitqueue_head(&s->waitq);
136 s->id = -1; 137 s->id = -1;
137 cx18_queue_init(&s->q_free); 138 cx18_queue_init(&s->q_free);
138 cx18_queue_init(&s->q_full); 139 cx18_queue_init(&s->q_full);
139 cx18_queue_init(&s->q_io); 140 cx18_queue_init(&s->q_io);
140 } 141 }
141 142
142 static int cx18_prep_dev(struct cx18 *cx, int type) 143 static int cx18_prep_dev(struct cx18 *cx, int type)
143 { 144 {
144 struct cx18_stream *s = &cx->streams[type]; 145 struct cx18_stream *s = &cx->streams[type];
145 u32 cap = cx->v4l2_cap; 146 u32 cap = cx->v4l2_cap;
146 int minor_offset = cx18_stream_info[type].minor_offset; 147 int minor_offset = cx18_stream_info[type].minor_offset;
147 int minor; 148 int minor;
148 149
149 /* These four fields are always initialized. If v4l2dev == NULL, then 150 /* These four fields are always initialized. If v4l2dev == NULL, then
150 this stream is not in use. In that case no other fields but these 151 this stream is not in use. In that case no other fields but these
151 four can be used. */ 152 four can be used. */
152 s->v4l2dev = NULL; 153 s->v4l2dev = NULL;
153 s->cx = cx; 154 s->cx = cx;
154 s->type = type; 155 s->type = type;
155 s->name = cx18_stream_info[type].name; 156 s->name = cx18_stream_info[type].name;
156 157
157 /* Check whether the radio is supported */ 158 /* Check whether the radio is supported */
158 if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO)) 159 if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO))
159 return 0; 160 return 0;
160 161
161 /* Check whether VBI is supported */ 162 /* Check whether VBI is supported */
162 if (type == CX18_ENC_STREAM_TYPE_VBI && 163 if (type == CX18_ENC_STREAM_TYPE_VBI &&
163 !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE))) 164 !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)))
164 return 0; 165 return 0;
165 166
166 /* card number + user defined offset + device offset */ 167 /* card number + user defined offset + device offset */
167 minor = cx->num + cx18_first_minor + minor_offset; 168 minor = cx->num + cx18_first_minor + minor_offset;
168 169
169 /* User explicitly selected 0 buffers for these streams, so don't 170 /* User explicitly selected 0 buffers for these streams, so don't
170 create them. */ 171 create them. */
171 if (cx18_stream_info[type].dma != PCI_DMA_NONE && 172 if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
172 cx->options.megabytes[type] == 0) { 173 cx->options.megabytes[type] == 0) {
173 CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name); 174 CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name);
174 return 0; 175 return 0;
175 } 176 }
176 177
177 cx18_stream_init(cx, type); 178 cx18_stream_init(cx, type);
178 179
179 if (minor_offset == -1) 180 if (minor_offset == -1)
180 return 0; 181 return 0;
181 182
182 /* allocate and initialize the v4l2 video device structure */ 183 /* allocate and initialize the v4l2 video device structure */
183 s->v4l2dev = video_device_alloc(); 184 s->v4l2dev = video_device_alloc();
184 if (s->v4l2dev == NULL) { 185 if (s->v4l2dev == NULL) {
185 CX18_ERR("Couldn't allocate v4l2 video_device for %s\n", 186 CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
186 s->name); 187 s->name);
187 return -ENOMEM; 188 return -ENOMEM;
188 } 189 }
189 190
190 snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", 191 snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d",
191 cx->num); 192 cx->num);
192 193
193 s->v4l2dev->minor = minor; 194 s->v4l2dev->minor = minor;
194 s->v4l2dev->parent = &cx->dev->dev; 195 s->v4l2dev->parent = &cx->dev->dev;
195 s->v4l2dev->fops = cx18_stream_info[type].fops; 196 s->v4l2dev->fops = cx18_stream_info[type].fops;
196 s->v4l2dev->release = video_device_release; 197 s->v4l2dev->release = video_device_release;
197 s->v4l2dev->tvnorms = V4L2_STD_ALL; 198 s->v4l2dev->tvnorms = V4L2_STD_ALL;
198 cx18_set_funcs(s->v4l2dev); 199 cx18_set_funcs(s->v4l2dev);
199 return 0; 200 return 0;
200 } 201 }
201 202
202 /* Initialize v4l2 variables and register v4l2 devices */ 203 /* Initialize v4l2 variables and register v4l2 devices */
203 int cx18_streams_setup(struct cx18 *cx) 204 int cx18_streams_setup(struct cx18 *cx)
204 { 205 {
205 int type; 206 int type;
206 207
207 /* Setup V4L2 Devices */ 208 /* Setup V4L2 Devices */
208 for (type = 0; type < CX18_MAX_STREAMS; type++) { 209 for (type = 0; type < CX18_MAX_STREAMS; type++) {
209 /* Prepare device */ 210 /* Prepare device */
210 if (cx18_prep_dev(cx, type)) 211 if (cx18_prep_dev(cx, type))
211 break; 212 break;
212 213
213 /* Allocate Stream */ 214 /* Allocate Stream */
214 if (cx18_stream_alloc(&cx->streams[type])) 215 if (cx18_stream_alloc(&cx->streams[type]))
215 break; 216 break;
216 } 217 }
217 if (type == CX18_MAX_STREAMS) 218 if (type == CX18_MAX_STREAMS)
218 return 0; 219 return 0;
219 220
220 /* One or more streams could not be initialized. Clean 'em all up. */ 221 /* One or more streams could not be initialized. Clean 'em all up. */
221 cx18_streams_cleanup(cx, 0); 222 cx18_streams_cleanup(cx, 0);
222 return -ENOMEM; 223 return -ENOMEM;
223 } 224 }
224 225
225 static int cx18_reg_dev(struct cx18 *cx, int type) 226 static int cx18_reg_dev(struct cx18 *cx, int type)
226 { 227 {
227 struct cx18_stream *s = &cx->streams[type]; 228 struct cx18_stream *s = &cx->streams[type];
228 int vfl_type = cx18_stream_info[type].vfl_type; 229 int vfl_type = cx18_stream_info[type].vfl_type;
229 int minor; 230 int minor;
230 231
231 /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? 232 /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something?
232 * We need a VFL_TYPE_TS defined. 233 * We need a VFL_TYPE_TS defined.
233 */ 234 */
234 if (strcmp("TS", s->name) == 0) { 235 if (strcmp("TS", s->name) == 0) {
235 /* just return if no DVB is supported */ 236 /* just return if no DVB is supported */
236 if ((cx->card->hw_all & CX18_HW_DVB) == 0) 237 if ((cx->card->hw_all & CX18_HW_DVB) == 0)
237 return 0; 238 return 0;
238 if (cx18_dvb_register(s) < 0) { 239 if (cx18_dvb_register(s) < 0) {
239 CX18_ERR("DVB failed to register\n"); 240 CX18_ERR("DVB failed to register\n");
240 return -EINVAL; 241 return -EINVAL;
241 } 242 }
242 } 243 }
243 244
244 if (s->v4l2dev == NULL) 245 if (s->v4l2dev == NULL)
245 return 0; 246 return 0;
246 247
247 minor = s->v4l2dev->minor; 248 minor = s->v4l2dev->minor;
248 249
249 /* Register device. First try the desired minor, then any free one. */ 250 /* Register device. First try the desired minor, then any free one. */
250 if (video_register_device(s->v4l2dev, vfl_type, minor) && 251 if (video_register_device(s->v4l2dev, vfl_type, minor) &&
251 video_register_device(s->v4l2dev, vfl_type, -1)) { 252 video_register_device(s->v4l2dev, vfl_type, -1)) {
252 CX18_ERR("Couldn't register v4l2 device for %s minor %d\n", 253 CX18_ERR("Couldn't register v4l2 device for %s minor %d\n",
253 s->name, minor); 254 s->name, minor);
254 video_device_release(s->v4l2dev); 255 video_device_release(s->v4l2dev);
255 s->v4l2dev = NULL; 256 s->v4l2dev = NULL;
256 return -ENOMEM; 257 return -ENOMEM;
257 } 258 }
258 minor = s->v4l2dev->minor; 259 minor = s->v4l2dev->minor;
259 260
260 switch (vfl_type) { 261 switch (vfl_type) {
261 case VFL_TYPE_GRABBER: 262 case VFL_TYPE_GRABBER:
262 CX18_INFO("Registered device video%d for %s (%d MB)\n", 263 CX18_INFO("Registered device video%d for %s (%d MB)\n",
263 minor, s->name, cx->options.megabytes[type]); 264 minor, s->name, cx->options.megabytes[type]);
264 break; 265 break;
265 266
266 case VFL_TYPE_RADIO: 267 case VFL_TYPE_RADIO:
267 CX18_INFO("Registered device radio%d for %s\n", 268 CX18_INFO("Registered device radio%d for %s\n",
268 minor - MINOR_VFL_TYPE_RADIO_MIN, s->name); 269 minor - MINOR_VFL_TYPE_RADIO_MIN, s->name);
269 break; 270 break;
270 271
271 case VFL_TYPE_VBI: 272 case VFL_TYPE_VBI:
272 if (cx->options.megabytes[type]) 273 if (cx->options.megabytes[type])
273 CX18_INFO("Registered device vbi%d for %s (%d MB)\n", 274 CX18_INFO("Registered device vbi%d for %s (%d MB)\n",
274 minor - MINOR_VFL_TYPE_VBI_MIN, 275 minor - MINOR_VFL_TYPE_VBI_MIN,
275 s->name, cx->options.megabytes[type]); 276 s->name, cx->options.megabytes[type]);
276 else 277 else
277 CX18_INFO("Registered device vbi%d for %s\n", 278 CX18_INFO("Registered device vbi%d for %s\n",
278 minor - MINOR_VFL_TYPE_VBI_MIN, s->name); 279 minor - MINOR_VFL_TYPE_VBI_MIN, s->name);
279 break; 280 break;
280 } 281 }
281 282
282 return 0; 283 return 0;
283 } 284 }
284 285
285 /* Register v4l2 devices */ 286 /* Register v4l2 devices */
286 int cx18_streams_register(struct cx18 *cx) 287 int cx18_streams_register(struct cx18 *cx)
287 { 288 {
288 int type; 289 int type;
289 int err = 0; 290 int err = 0;
290 291
291 /* Register V4L2 devices */ 292 /* Register V4L2 devices */
292 for (type = 0; type < CX18_MAX_STREAMS; type++) 293 for (type = 0; type < CX18_MAX_STREAMS; type++)
293 err |= cx18_reg_dev(cx, type); 294 err |= cx18_reg_dev(cx, type);
294 295
295 if (err == 0) 296 if (err == 0)
296 return 0; 297 return 0;
297 298
298 /* One or more streams could not be initialized. Clean 'em all up. */ 299 /* One or more streams could not be initialized. Clean 'em all up. */
299 cx18_streams_cleanup(cx, 1); 300 cx18_streams_cleanup(cx, 1);
300 return -ENOMEM; 301 return -ENOMEM;
301 } 302 }
302 303
303 /* Unregister v4l2 devices */ 304 /* Unregister v4l2 devices */
304 void cx18_streams_cleanup(struct cx18 *cx, int unregister) 305 void cx18_streams_cleanup(struct cx18 *cx, int unregister)
305 { 306 {
306 struct video_device *vdev; 307 struct video_device *vdev;
307 int type; 308 int type;
308 309
309 /* Teardown all streams */ 310 /* Teardown all streams */
310 for (type = 0; type < CX18_MAX_STREAMS; type++) { 311 for (type = 0; type < CX18_MAX_STREAMS; type++) {
311 if (cx->streams[type].dvb.enabled) { 312 if (cx->streams[type].dvb.enabled) {
312 cx18_dvb_unregister(&cx->streams[type]); 313 cx18_dvb_unregister(&cx->streams[type]);
313 cx->streams[type].dvb.enabled = false; 314 cx->streams[type].dvb.enabled = false;
314 } 315 }
315 316
316 vdev = cx->streams[type].v4l2dev; 317 vdev = cx->streams[type].v4l2dev;
317 318
318 cx->streams[type].v4l2dev = NULL; 319 cx->streams[type].v4l2dev = NULL;
319 if (vdev == NULL) 320 if (vdev == NULL)
320 continue; 321 continue;
321 322
322 cx18_stream_free(&cx->streams[type]); 323 cx18_stream_free(&cx->streams[type]);
323 324
324 /* Unregister or release device */ 325 /* Unregister or release device */
325 if (unregister) 326 if (unregister)
326 video_unregister_device(vdev); 327 video_unregister_device(vdev);
327 else 328 else
328 video_device_release(vdev); 329 video_device_release(vdev);
329 } 330 }
330 } 331 }
331 332
332 static void cx18_vbi_setup(struct cx18_stream *s) 333 static void cx18_vbi_setup(struct cx18_stream *s)
333 { 334 {
334 struct cx18 *cx = s->cx; 335 struct cx18 *cx = s->cx;
335 int raw = cx->vbi.sliced_in->service_set == 0; 336 int raw = cx->vbi.sliced_in->service_set == 0;
336 u32 data[CX2341X_MBOX_MAX_DATA]; 337 u32 data[CX2341X_MBOX_MAX_DATA];
337 int lines; 338 int lines;
338 339
339 if (cx->is_60hz) { 340 if (cx->is_60hz) {
340 cx->vbi.count = 12; 341 cx->vbi.count = 12;
341 cx->vbi.start[0] = 10; 342 cx->vbi.start[0] = 10;
342 cx->vbi.start[1] = 273; 343 cx->vbi.start[1] = 273;
343 } else { /* PAL/SECAM */ 344 } else { /* PAL/SECAM */
344 cx->vbi.count = 18; 345 cx->vbi.count = 18;
345 cx->vbi.start[0] = 6; 346 cx->vbi.start[0] = 6;
346 cx->vbi.start[1] = 318; 347 cx->vbi.start[1] = 318;
347 } 348 }
348 349
349 /* setup VBI registers */ 350 /* setup VBI registers */
350 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); 351 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
351 352
352 /* determine number of lines and total number of VBI bytes. 353 /* determine number of lines and total number of VBI bytes.
353 A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1 354 A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1
354 The '- 1' byte is probably an unused U or V byte. Or something... 355 The '- 1' byte is probably an unused U or V byte. Or something...
355 A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal 356 A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
356 header, 42 data bytes + checksum (to be confirmed) */ 357 header, 42 data bytes + checksum (to be confirmed) */
357 if (raw) { 358 if (raw) {
358 lines = cx->vbi.count * 2; 359 lines = cx->vbi.count * 2;
359 } else { 360 } else {
360 lines = cx->is_60hz ? 24 : 38; 361 lines = cx->is_60hz ? 24 : 38;
361 if (cx->is_60hz) 362 if (cx->is_60hz)
362 lines += 2; 363 lines += 2;
363 } 364 }
364 365
365 cx->vbi.enc_size = lines * 366 cx->vbi.enc_size = lines *
366 (raw ? cx->vbi.raw_size : cx->vbi.sliced_size); 367 (raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
367 368
368 data[0] = s->handle; 369 data[0] = s->handle;
369 /* Lines per field */ 370 /* Lines per field */
370 data[1] = (lines / 2) | ((lines / 2) << 16); 371 data[1] = (lines / 2) | ((lines / 2) << 16);
371 /* bytes per line */ 372 /* bytes per line */
372 data[2] = (raw ? cx->vbi.raw_size : cx->vbi.sliced_size); 373 data[2] = (raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
373 /* Every X number of frames a VBI interrupt arrives 374 /* Every X number of frames a VBI interrupt arrives
374 (frames as in 25 or 30 fps) */ 375 (frames as in 25 or 30 fps) */
375 data[3] = 1; 376 data[3] = 1;
376 /* Setup VBI for the cx25840 digitizer */ 377 /* Setup VBI for the cx25840 digitizer */
377 if (raw) { 378 if (raw) {
378 data[4] = 0x20602060; 379 data[4] = 0x20602060;
379 data[5] = 0x30703070; 380 data[5] = 0x30703070;
380 } else { 381 } else {
381 data[4] = 0xB0F0B0F0; 382 data[4] = 0xB0F0B0F0;
382 data[5] = 0xA0E0A0E0; 383 data[5] = 0xA0E0A0E0;
383 } 384 }
384 385
385 CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n", 386 CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
386 data[0], data[1], data[2], data[3], data[4], data[5]); 387 data[0], data[1], data[2], data[3], data[4], data[5]);
387 388
388 if (s->type == CX18_ENC_STREAM_TYPE_VBI) 389 if (s->type == CX18_ENC_STREAM_TYPE_VBI)
389 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); 390 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
390 } 391 }
391 392
392 int cx18_start_v4l2_encode_stream(struct cx18_stream *s) 393 int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
393 { 394 {
394 u32 data[MAX_MB_ARGUMENTS]; 395 u32 data[MAX_MB_ARGUMENTS];
395 struct cx18 *cx = s->cx; 396 struct cx18 *cx = s->cx;
396 struct list_head *p; 397 struct list_head *p;
397 int ts = 0; 398 int ts = 0;
398 int captype = 0; 399 int captype = 0;
399 400
400 if (s->v4l2dev == NULL && s->dvb.enabled == 0) 401 if (s->v4l2dev == NULL && s->dvb.enabled == 0)
401 return -EINVAL; 402 return -EINVAL;
402 403
403 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name); 404 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
404 405
405 switch (s->type) { 406 switch (s->type) {
406 case CX18_ENC_STREAM_TYPE_MPG: 407 case CX18_ENC_STREAM_TYPE_MPG:
407 captype = CAPTURE_CHANNEL_TYPE_MPEG; 408 captype = CAPTURE_CHANNEL_TYPE_MPEG;
408 cx->mpg_data_received = cx->vbi_data_inserted = 0; 409 cx->mpg_data_received = cx->vbi_data_inserted = 0;
409 cx->dualwatch_jiffies = jiffies; 410 cx->dualwatch_jiffies = jiffies;
410 cx->dualwatch_stereo_mode = cx->params.audio_properties & 0x300; 411 cx->dualwatch_stereo_mode = cx->params.audio_properties & 0x300;
411 cx->search_pack_header = 0; 412 cx->search_pack_header = 0;
412 break; 413 break;
413 414
414 case CX18_ENC_STREAM_TYPE_TS: 415 case CX18_ENC_STREAM_TYPE_TS:
415 captype = CAPTURE_CHANNEL_TYPE_TS; 416 captype = CAPTURE_CHANNEL_TYPE_TS;
416 ts = 1; 417 ts = 1;
417 break; 418 break;
418 case CX18_ENC_STREAM_TYPE_YUV: 419 case CX18_ENC_STREAM_TYPE_YUV:
419 captype = CAPTURE_CHANNEL_TYPE_YUV; 420 captype = CAPTURE_CHANNEL_TYPE_YUV;
420 break; 421 break;
421 case CX18_ENC_STREAM_TYPE_PCM: 422 case CX18_ENC_STREAM_TYPE_PCM:
422 captype = CAPTURE_CHANNEL_TYPE_PCM; 423 captype = CAPTURE_CHANNEL_TYPE_PCM;
423 break; 424 break;
424 case CX18_ENC_STREAM_TYPE_VBI: 425 case CX18_ENC_STREAM_TYPE_VBI:
425 captype = cx->vbi.sliced_in->service_set ? 426 captype = cx->vbi.sliced_in->service_set ?
426 CAPTURE_CHANNEL_TYPE_SLICED_VBI : CAPTURE_CHANNEL_TYPE_VBI; 427 CAPTURE_CHANNEL_TYPE_SLICED_VBI : CAPTURE_CHANNEL_TYPE_VBI;
427 cx->vbi.frame = 0; 428 cx->vbi.frame = 0;
428 cx->vbi.inserted_frame = 0; 429 cx->vbi.inserted_frame = 0;
429 memset(cx->vbi.sliced_mpeg_size, 430 memset(cx->vbi.sliced_mpeg_size,
430 0, sizeof(cx->vbi.sliced_mpeg_size)); 431 0, sizeof(cx->vbi.sliced_mpeg_size));
431 break; 432 break;
432 default: 433 default:
433 return -EINVAL; 434 return -EINVAL;
434 } 435 }
435 436
436 /* mute/unmute video */ 437 /* mute/unmute video */
437 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, 438 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
438 s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)); 439 s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags));
439 440
440 /* Clear Streamoff flags in case left from last capture */ 441 /* Clear Streamoff flags in case left from last capture */
441 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags); 442 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
442 443
443 cx18_vapi_result(cx, data, CX18_CREATE_TASK, 1, CPU_CMD_MASK_CAPTURE); 444 cx18_vapi_result(cx, data, CX18_CREATE_TASK, 1, CPU_CMD_MASK_CAPTURE);
444 s->handle = data[0]; 445 s->handle = data[0];
445 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype); 446 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
446 447
447 if (atomic_read(&cx->ana_capturing) == 0 && !ts) { 448 if (atomic_read(&cx->ana_capturing) == 0 && !ts) {
448 /* Stuff from Windows, we don't know what it is */ 449 /* Stuff from Windows, we don't know what it is */
449 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0); 450 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
450 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1); 451 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
451 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0); 452 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
452 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1); 453 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
453 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12); 454 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12);
454 455
455 cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3, 456 cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
456 s->handle, cx->digitizer, cx->digitizer); 457 s->handle, cx->digitizer, cx->digitizer);
457 458
458 /* Setup VBI */ 459 /* Setup VBI */
459 if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE) 460 if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
460 cx18_vbi_setup(s); 461 cx18_vbi_setup(s);
461 462
462 /* assign program index info. 463 /* assign program index info.
463 Mask 7: select I/P/B, Num_req: 400 max */ 464 Mask 7: select I/P/B, Num_req: 400 max */
464 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0); 465 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0);
465 466
466 /* Setup API for Stream */ 467 /* Setup API for Stream */
467 cx2341x_update(cx, cx18_api_func, NULL, &cx->params); 468 cx2341x_update(cx, cx18_api_func, NULL, &cx->params);
468 } 469 }
469 470
470 if (atomic_read(&cx->tot_capturing) == 0) { 471 if (atomic_read(&cx->tot_capturing) == 0) {
471 clear_bit(CX18_F_I_EOS, &cx->i_flags); 472 clear_bit(CX18_F_I_EOS, &cx->i_flags);
472 write_reg(7, CX18_DSP0_INTERRUPT_MASK); 473 cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK);
473 } 474 }
474 475
475 cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle, 476 cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle,
476 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem, 477 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem,
477 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); 478 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
478 479
479 list_for_each(p, &s->q_free.list) { 480 list_for_each(p, &s->q_free.list) {
480 struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list); 481 struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list);
481 482
482 writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr); 483 cx18_writel(cx, buf->dma_handle,
483 writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length); 484 &cx->scb->cpu_mdl[buf->id].paddr);
485 cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
484 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, 486 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
485 (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 487 (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
486 1, buf->id, s->buf_size); 488 1, buf->id, s->buf_size);
487 } 489 }
488 /* begin_capture */ 490 /* begin_capture */
489 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { 491 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
490 CX18_DEBUG_WARN("Error starting capture!\n"); 492 CX18_DEBUG_WARN("Error starting capture!\n");
491 /* Ensure we're really not capturing before releasing MDLs */ 493 /* Ensure we're really not capturing before releasing MDLs */
492 if (s->type == CX18_ENC_STREAM_TYPE_MPG) 494 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
493 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1); 495 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1);
494 else 496 else
495 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle); 497 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
496 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); 498 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
497 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); 499 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
498 /* FIXME - clean-up DSP0_INT mask, i_flags, s_flags, etc. */ 500 /* FIXME - clean-up DSP0_INT mask, i_flags, s_flags, etc. */
499 return -EINVAL; 501 return -EINVAL;
500 } 502 }
501 503
502 /* you're live! sit back and await interrupts :) */ 504 /* you're live! sit back and await interrupts :) */
503 if (!ts) 505 if (!ts)
504 atomic_inc(&cx->ana_capturing); 506 atomic_inc(&cx->ana_capturing);
505 atomic_inc(&cx->tot_capturing); 507 atomic_inc(&cx->tot_capturing);
506 return 0; 508 return 0;
507 } 509 }
508 510
509 void cx18_stop_all_captures(struct cx18 *cx) 511 void cx18_stop_all_captures(struct cx18 *cx)
510 { 512 {
511 int i; 513 int i;
512 514
513 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) { 515 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
514 struct cx18_stream *s = &cx->streams[i]; 516 struct cx18_stream *s = &cx->streams[i];
515 517
516 if (s->v4l2dev == NULL && s->dvb.enabled == 0) 518 if (s->v4l2dev == NULL && s->dvb.enabled == 0)
517 continue; 519 continue;
518 if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) 520 if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
519 cx18_stop_v4l2_encode_stream(s, 0); 521 cx18_stop_v4l2_encode_stream(s, 0);
520 } 522 }
521 } 523 }
522 524
523 int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) 525 int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
524 { 526 {
525 struct cx18 *cx = s->cx; 527 struct cx18 *cx = s->cx;
526 unsigned long then; 528 unsigned long then;
527 529
528 if (s->v4l2dev == NULL && s->dvb.enabled == 0) 530 if (s->v4l2dev == NULL && s->dvb.enabled == 0)
529 return -EINVAL; 531 return -EINVAL;
530 532
531 /* This function assumes that you are allowed to stop the capture 533 /* This function assumes that you are allowed to stop the capture
532 and that we are actually capturing */ 534 and that we are actually capturing */
533 535
534 CX18_DEBUG_INFO("Stop Capture\n"); 536 CX18_DEBUG_INFO("Stop Capture\n");
535 537
536 if (atomic_read(&cx->tot_capturing) == 0) 538 if (atomic_read(&cx->tot_capturing) == 0)
537 return 0; 539 return 0;
538 540
539 if (s->type == CX18_ENC_STREAM_TYPE_MPG) 541 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
540 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end); 542 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
541 else 543 else
542 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle); 544 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
543 545
544 then = jiffies; 546 then = jiffies;
545 547
546 if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) { 548 if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) {
547 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n"); 549 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
548 } 550 }
549 551
550 /* Tell the CX23418 it can't use our buffers anymore */ 552 /* Tell the CX23418 it can't use our buffers anymore */
551 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); 553 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
552 554
553 if (s->type != CX18_ENC_STREAM_TYPE_TS) 555 if (s->type != CX18_ENC_STREAM_TYPE_TS)
554 atomic_dec(&cx->ana_capturing); 556 atomic_dec(&cx->ana_capturing);
555 atomic_dec(&cx->tot_capturing); 557 atomic_dec(&cx->tot_capturing);
556 558
557 /* Clear capture and no-read bits */ 559 /* Clear capture and no-read bits */
558 clear_bit(CX18_F_S_STREAMING, &s->s_flags); 560 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
559 561
560 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); 562 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
561 s->handle = CX18_INVALID_TASK_HANDLE; 563 s->handle = CX18_INVALID_TASK_HANDLE;
562 564
563 if (atomic_read(&cx->tot_capturing) > 0) 565 if (atomic_read(&cx->tot_capturing) > 0)
564 return 0; 566 return 0;
565 567
566 write_reg(5, CX18_DSP0_INTERRUPT_MASK); 568 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
567 wake_up(&s->waitq); 569 wake_up(&s->waitq);
568 570
569 return 0; 571 return 0;
570 } 572 }
571 573
572 u32 cx18_find_handle(struct cx18 *cx) 574 u32 cx18_find_handle(struct cx18 *cx)
573 { 575 {
574 int i; 576 int i;
575 577
576 /* find first available handle to be used for global settings */ 578 /* find first available handle to be used for global settings */
577 for (i = 0; i < CX18_MAX_STREAMS; i++) { 579 for (i = 0; i < CX18_MAX_STREAMS; i++) {
578 struct cx18_stream *s = &cx->streams[i]; 580 struct cx18_stream *s = &cx->streams[i];
579 581
580 if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE)) 582 if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE))
581 return s->handle; 583 return s->handle;
582 } 584 }
583 return CX18_INVALID_TASK_HANDLE; 585 return CX18_INVALID_TASK_HANDLE;
584 } 586 }
585 587