Commit 22b4e64f0a119e94090ef45285a5c311f1f6855f
Committed by
Mauro Carvalho Chehab
1 parent
94205c7a48
Exists in
master
and in
4 other branches
V4L/DVB (7520): media/video/cx23885 replace remaining __FUNCTION__ occurrences
__FUNCTION__ is gcc-specific, use __func__ Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Showing 5 changed files with 90 additions and 90 deletions Inline Diff
drivers/media/video/cx23885/cx23885-cards.c
1 | /* | 1 | /* |
2 | * Driver for the Conexant CX23885 PCIe bridge | 2 | * Driver for the Conexant CX23885 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> | 4 | * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> |
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 <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <media/cx25840.h> | 26 | #include <media/cx25840.h> |
27 | 27 | ||
28 | #include "cx23885.h" | 28 | #include "cx23885.h" |
29 | 29 | ||
30 | /* ------------------------------------------------------------------ */ | 30 | /* ------------------------------------------------------------------ */ |
31 | /* board config info */ | 31 | /* board config info */ |
32 | 32 | ||
33 | struct cx23885_board cx23885_boards[] = { | 33 | struct cx23885_board cx23885_boards[] = { |
34 | [CX23885_BOARD_UNKNOWN] = { | 34 | [CX23885_BOARD_UNKNOWN] = { |
35 | .name = "UNKNOWN/GENERIC", | 35 | .name = "UNKNOWN/GENERIC", |
36 | /* Ensure safe default for unknown boards */ | 36 | /* Ensure safe default for unknown boards */ |
37 | .clk_freq = 0, | 37 | .clk_freq = 0, |
38 | .input = {{ | 38 | .input = {{ |
39 | .type = CX23885_VMUX_COMPOSITE1, | 39 | .type = CX23885_VMUX_COMPOSITE1, |
40 | .vmux = 0, | 40 | .vmux = 0, |
41 | },{ | 41 | },{ |
42 | .type = CX23885_VMUX_COMPOSITE2, | 42 | .type = CX23885_VMUX_COMPOSITE2, |
43 | .vmux = 1, | 43 | .vmux = 1, |
44 | },{ | 44 | },{ |
45 | .type = CX23885_VMUX_COMPOSITE3, | 45 | .type = CX23885_VMUX_COMPOSITE3, |
46 | .vmux = 2, | 46 | .vmux = 2, |
47 | },{ | 47 | },{ |
48 | .type = CX23885_VMUX_COMPOSITE4, | 48 | .type = CX23885_VMUX_COMPOSITE4, |
49 | .vmux = 3, | 49 | .vmux = 3, |
50 | }}, | 50 | }}, |
51 | }, | 51 | }, |
52 | [CX23885_BOARD_HAUPPAUGE_HVR1800lp] = { | 52 | [CX23885_BOARD_HAUPPAUGE_HVR1800lp] = { |
53 | .name = "Hauppauge WinTV-HVR1800lp", | 53 | .name = "Hauppauge WinTV-HVR1800lp", |
54 | .portc = CX23885_MPEG_DVB, | 54 | .portc = CX23885_MPEG_DVB, |
55 | .input = {{ | 55 | .input = {{ |
56 | .type = CX23885_VMUX_TELEVISION, | 56 | .type = CX23885_VMUX_TELEVISION, |
57 | .vmux = 0, | 57 | .vmux = 0, |
58 | .gpio0 = 0xff00, | 58 | .gpio0 = 0xff00, |
59 | },{ | 59 | },{ |
60 | .type = CX23885_VMUX_DEBUG, | 60 | .type = CX23885_VMUX_DEBUG, |
61 | .vmux = 0, | 61 | .vmux = 0, |
62 | .gpio0 = 0xff01, | 62 | .gpio0 = 0xff01, |
63 | },{ | 63 | },{ |
64 | .type = CX23885_VMUX_COMPOSITE1, | 64 | .type = CX23885_VMUX_COMPOSITE1, |
65 | .vmux = 1, | 65 | .vmux = 1, |
66 | .gpio0 = 0xff02, | 66 | .gpio0 = 0xff02, |
67 | },{ | 67 | },{ |
68 | .type = CX23885_VMUX_SVIDEO, | 68 | .type = CX23885_VMUX_SVIDEO, |
69 | .vmux = 2, | 69 | .vmux = 2, |
70 | .gpio0 = 0xff02, | 70 | .gpio0 = 0xff02, |
71 | }}, | 71 | }}, |
72 | }, | 72 | }, |
73 | [CX23885_BOARD_HAUPPAUGE_HVR1800] = { | 73 | [CX23885_BOARD_HAUPPAUGE_HVR1800] = { |
74 | .name = "Hauppauge WinTV-HVR1800", | 74 | .name = "Hauppauge WinTV-HVR1800", |
75 | .porta = CX23885_ANALOG_VIDEO, | 75 | .porta = CX23885_ANALOG_VIDEO, |
76 | .portc = CX23885_MPEG_DVB, | 76 | .portc = CX23885_MPEG_DVB, |
77 | .tuner_type = TUNER_PHILIPS_TDA8290, | 77 | .tuner_type = TUNER_PHILIPS_TDA8290, |
78 | .tuner_addr = 0x42, /* 0x84 >> 1 */ | 78 | .tuner_addr = 0x42, /* 0x84 >> 1 */ |
79 | .input = {{ | 79 | .input = {{ |
80 | .type = CX23885_VMUX_TELEVISION, | 80 | .type = CX23885_VMUX_TELEVISION, |
81 | .vmux = CX25840_VIN7_CH3 | | 81 | .vmux = CX25840_VIN7_CH3 | |
82 | CX25840_VIN5_CH2 | | 82 | CX25840_VIN5_CH2 | |
83 | CX25840_VIN2_CH1, | 83 | CX25840_VIN2_CH1, |
84 | .gpio0 = 0, | 84 | .gpio0 = 0, |
85 | },{ | 85 | },{ |
86 | .type = CX23885_VMUX_COMPOSITE1, | 86 | .type = CX23885_VMUX_COMPOSITE1, |
87 | .vmux = CX25840_VIN7_CH3 | | 87 | .vmux = CX25840_VIN7_CH3 | |
88 | CX25840_VIN4_CH2 | | 88 | CX25840_VIN4_CH2 | |
89 | CX25840_VIN6_CH1, | 89 | CX25840_VIN6_CH1, |
90 | .gpio0 = 0, | 90 | .gpio0 = 0, |
91 | },{ | 91 | },{ |
92 | .type = CX23885_VMUX_SVIDEO, | 92 | .type = CX23885_VMUX_SVIDEO, |
93 | .vmux = CX25840_VIN7_CH3 | | 93 | .vmux = CX25840_VIN7_CH3 | |
94 | CX25840_VIN4_CH2 | | 94 | CX25840_VIN4_CH2 | |
95 | CX25840_VIN8_CH1 | | 95 | CX25840_VIN8_CH1 | |
96 | CX25840_SVIDEO_ON, | 96 | CX25840_SVIDEO_ON, |
97 | .gpio0 = 0, | 97 | .gpio0 = 0, |
98 | }}, | 98 | }}, |
99 | }, | 99 | }, |
100 | [CX23885_BOARD_HAUPPAUGE_HVR1250] = { | 100 | [CX23885_BOARD_HAUPPAUGE_HVR1250] = { |
101 | .name = "Hauppauge WinTV-HVR1250", | 101 | .name = "Hauppauge WinTV-HVR1250", |
102 | .portc = CX23885_MPEG_DVB, | 102 | .portc = CX23885_MPEG_DVB, |
103 | .input = {{ | 103 | .input = {{ |
104 | .type = CX23885_VMUX_TELEVISION, | 104 | .type = CX23885_VMUX_TELEVISION, |
105 | .vmux = 0, | 105 | .vmux = 0, |
106 | .gpio0 = 0xff00, | 106 | .gpio0 = 0xff00, |
107 | },{ | 107 | },{ |
108 | .type = CX23885_VMUX_DEBUG, | 108 | .type = CX23885_VMUX_DEBUG, |
109 | .vmux = 0, | 109 | .vmux = 0, |
110 | .gpio0 = 0xff01, | 110 | .gpio0 = 0xff01, |
111 | },{ | 111 | },{ |
112 | .type = CX23885_VMUX_COMPOSITE1, | 112 | .type = CX23885_VMUX_COMPOSITE1, |
113 | .vmux = 1, | 113 | .vmux = 1, |
114 | .gpio0 = 0xff02, | 114 | .gpio0 = 0xff02, |
115 | },{ | 115 | },{ |
116 | .type = CX23885_VMUX_SVIDEO, | 116 | .type = CX23885_VMUX_SVIDEO, |
117 | .vmux = 2, | 117 | .vmux = 2, |
118 | .gpio0 = 0xff02, | 118 | .gpio0 = 0xff02, |
119 | }}, | 119 | }}, |
120 | }, | 120 | }, |
121 | [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = { | 121 | [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = { |
122 | .name = "DViCO FusionHDTV5 Express", | 122 | .name = "DViCO FusionHDTV5 Express", |
123 | .portb = CX23885_MPEG_DVB, | 123 | .portb = CX23885_MPEG_DVB, |
124 | }, | 124 | }, |
125 | [CX23885_BOARD_HAUPPAUGE_HVR1500Q] = { | 125 | [CX23885_BOARD_HAUPPAUGE_HVR1500Q] = { |
126 | .name = "Hauppauge WinTV-HVR1500Q", | 126 | .name = "Hauppauge WinTV-HVR1500Q", |
127 | .portc = CX23885_MPEG_DVB, | 127 | .portc = CX23885_MPEG_DVB, |
128 | }, | 128 | }, |
129 | [CX23885_BOARD_HAUPPAUGE_HVR1500] = { | 129 | [CX23885_BOARD_HAUPPAUGE_HVR1500] = { |
130 | .name = "Hauppauge WinTV-HVR1500", | 130 | .name = "Hauppauge WinTV-HVR1500", |
131 | .portc = CX23885_MPEG_DVB, | 131 | .portc = CX23885_MPEG_DVB, |
132 | }, | 132 | }, |
133 | }; | 133 | }; |
134 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); | 134 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); |
135 | 135 | ||
136 | /* ------------------------------------------------------------------ */ | 136 | /* ------------------------------------------------------------------ */ |
137 | /* PCI subsystem IDs */ | 137 | /* PCI subsystem IDs */ |
138 | 138 | ||
139 | struct cx23885_subid cx23885_subids[] = { | 139 | struct cx23885_subid cx23885_subids[] = { |
140 | { | 140 | { |
141 | .subvendor = 0x0070, | 141 | .subvendor = 0x0070, |
142 | .subdevice = 0x3400, | 142 | .subdevice = 0x3400, |
143 | .card = CX23885_BOARD_UNKNOWN, | 143 | .card = CX23885_BOARD_UNKNOWN, |
144 | },{ | 144 | },{ |
145 | .subvendor = 0x0070, | 145 | .subvendor = 0x0070, |
146 | .subdevice = 0x7600, | 146 | .subdevice = 0x7600, |
147 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800lp, | 147 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800lp, |
148 | },{ | 148 | },{ |
149 | .subvendor = 0x0070, | 149 | .subvendor = 0x0070, |
150 | .subdevice = 0x7800, | 150 | .subdevice = 0x7800, |
151 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, | 151 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, |
152 | },{ | 152 | },{ |
153 | .subvendor = 0x0070, | 153 | .subvendor = 0x0070, |
154 | .subdevice = 0x7801, | 154 | .subdevice = 0x7801, |
155 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, | 155 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, |
156 | },{ | 156 | },{ |
157 | .subvendor = 0x0070, | 157 | .subvendor = 0x0070, |
158 | .subdevice = 0x7809, | 158 | .subdevice = 0x7809, |
159 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, | 159 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, |
160 | },{ | 160 | },{ |
161 | .subvendor = 0x0070, | 161 | .subvendor = 0x0070, |
162 | .subdevice = 0x7911, | 162 | .subdevice = 0x7911, |
163 | .card = CX23885_BOARD_HAUPPAUGE_HVR1250, | 163 | .card = CX23885_BOARD_HAUPPAUGE_HVR1250, |
164 | },{ | 164 | },{ |
165 | .subvendor = 0x18ac, | 165 | .subvendor = 0x18ac, |
166 | .subdevice = 0xd500, | 166 | .subdevice = 0xd500, |
167 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP, | 167 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP, |
168 | },{ | 168 | },{ |
169 | .subvendor = 0x0070, | 169 | .subvendor = 0x0070, |
170 | .subdevice = 0x7790, | 170 | .subdevice = 0x7790, |
171 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, | 171 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, |
172 | },{ | 172 | },{ |
173 | .subvendor = 0x0070, | 173 | .subvendor = 0x0070, |
174 | .subdevice = 0x7797, | 174 | .subdevice = 0x7797, |
175 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, | 175 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, |
176 | },{ | 176 | },{ |
177 | .subvendor = 0x0070, | 177 | .subvendor = 0x0070, |
178 | .subdevice = 0x7710, | 178 | .subdevice = 0x7710, |
179 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500, | 179 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500, |
180 | },{ | 180 | },{ |
181 | .subvendor = 0x0070, | 181 | .subvendor = 0x0070, |
182 | .subdevice = 0x7717, | 182 | .subdevice = 0x7717, |
183 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500, | 183 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500, |
184 | }, | 184 | }, |
185 | }; | 185 | }; |
186 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); | 186 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); |
187 | 187 | ||
188 | void cx23885_card_list(struct cx23885_dev *dev) | 188 | void cx23885_card_list(struct cx23885_dev *dev) |
189 | { | 189 | { |
190 | int i; | 190 | int i; |
191 | 191 | ||
192 | if (0 == dev->pci->subsystem_vendor && | 192 | if (0 == dev->pci->subsystem_vendor && |
193 | 0 == dev->pci->subsystem_device) { | 193 | 0 == dev->pci->subsystem_device) { |
194 | printk("%s: Your board has no valid PCIe Subsystem ID and thus can't\n" | 194 | printk("%s: Your board has no valid PCIe Subsystem ID and thus can't\n" |
195 | "%s: be autodetected. Please pass card=<n> insmod option to\n" | 195 | "%s: be autodetected. Please pass card=<n> insmod option to\n" |
196 | "%s: workaround that. Redirect complaints to the vendor of\n" | 196 | "%s: workaround that. Redirect complaints to the vendor of\n" |
197 | "%s: the TV card. Best regards,\n" | 197 | "%s: the TV card. Best regards,\n" |
198 | "%s: -- tux\n", | 198 | "%s: -- tux\n", |
199 | dev->name, dev->name, dev->name, dev->name, dev->name); | 199 | dev->name, dev->name, dev->name, dev->name, dev->name); |
200 | } else { | 200 | } else { |
201 | printk("%s: Your board isn't known (yet) to the driver. You can\n" | 201 | printk("%s: Your board isn't known (yet) to the driver. You can\n" |
202 | "%s: try to pick one of the existing card configs via\n" | 202 | "%s: try to pick one of the existing card configs via\n" |
203 | "%s: card=<n> insmod option. Updating to the latest\n" | 203 | "%s: card=<n> insmod option. Updating to the latest\n" |
204 | "%s: version might help as well.\n", | 204 | "%s: version might help as well.\n", |
205 | dev->name, dev->name, dev->name, dev->name); | 205 | dev->name, dev->name, dev->name, dev->name); |
206 | } | 206 | } |
207 | printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n", | 207 | printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n", |
208 | dev->name); | 208 | dev->name); |
209 | for (i = 0; i < cx23885_bcount; i++) | 209 | for (i = 0; i < cx23885_bcount; i++) |
210 | printk("%s: card=%d -> %s\n", | 210 | printk("%s: card=%d -> %s\n", |
211 | dev->name, i, cx23885_boards[i].name); | 211 | dev->name, i, cx23885_boards[i].name); |
212 | } | 212 | } |
213 | 213 | ||
214 | static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) | 214 | static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) |
215 | { | 215 | { |
216 | struct tveeprom tv; | 216 | struct tveeprom tv; |
217 | 217 | ||
218 | tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, eeprom_data); | 218 | tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, eeprom_data); |
219 | 219 | ||
220 | /* Make sure we support the board model */ | 220 | /* Make sure we support the board model */ |
221 | switch (tv.model) | 221 | switch (tv.model) |
222 | { | 222 | { |
223 | case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */ | 223 | case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */ |
224 | case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */ | 224 | case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */ |
225 | case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */ | 225 | case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */ |
226 | case 77041: /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM and Basic analog */ | 226 | case 77041: /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM and Basic analog */ |
227 | case 77051: /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM and Basic analog */ | 227 | case 77051: /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM and Basic analog */ |
228 | case 78011: /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ | 228 | case 78011: /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ |
229 | case 78501: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ | 229 | case 78501: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ |
230 | case 78521: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ | 230 | case 78521: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ |
231 | case 78531: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ | 231 | case 78531: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ |
232 | case 78631: /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ | 232 | case 78631: /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ |
233 | case 79001: /* WinTV-HVR1250 (PCIe, Retail, IR, full height, ATSC and Basic analog */ | 233 | case 79001: /* WinTV-HVR1250 (PCIe, Retail, IR, full height, ATSC and Basic analog */ |
234 | case 79101: /* WinTV-HVR1250 (PCIe, Retail, IR, half height, ATSC and Basic analog */ | 234 | case 79101: /* WinTV-HVR1250 (PCIe, Retail, IR, half height, ATSC and Basic analog */ |
235 | case 79561: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ | 235 | case 79561: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ |
236 | case 79571: /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, ATSC and Basic analog */ | 236 | case 79571: /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, ATSC and Basic analog */ |
237 | case 79671: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ | 237 | case 79671: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ |
238 | break; | 238 | break; |
239 | default: | 239 | default: |
240 | printk("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model); | 240 | printk("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model); |
241 | break; | 241 | break; |
242 | } | 242 | } |
243 | 243 | ||
244 | printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", | 244 | printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", |
245 | dev->name, tv.model); | 245 | dev->name, tv.model); |
246 | } | 246 | } |
247 | 247 | ||
248 | /* Tuner callback function for cx23885 boards. Currently only needed | 248 | /* Tuner callback function for cx23885 boards. Currently only needed |
249 | * for HVR1500Q, which has an xc5000 tuner. | 249 | * for HVR1500Q, which has an xc5000 tuner. |
250 | */ | 250 | */ |
251 | int cx23885_tuner_callback(void *priv, int command, int arg) | 251 | int cx23885_tuner_callback(void *priv, int command, int arg) |
252 | { | 252 | { |
253 | struct cx23885_i2c *bus = priv; | 253 | struct cx23885_i2c *bus = priv; |
254 | struct cx23885_dev *dev = bus->dev; | 254 | struct cx23885_dev *dev = bus->dev; |
255 | 255 | ||
256 | switch(dev->board) { | 256 | switch(dev->board) { |
257 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 257 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
258 | if(command == 0) { /* Tuner Reset Command from xc5000 */ | 258 | if(command == 0) { /* Tuner Reset Command from xc5000 */ |
259 | /* Drive the tuner into reset and out */ | 259 | /* Drive the tuner into reset and out */ |
260 | cx_clear(GP0_IO, 0x00000004); | 260 | cx_clear(GP0_IO, 0x00000004); |
261 | mdelay(200); | 261 | mdelay(200); |
262 | cx_set(GP0_IO, 0x00000004); | 262 | cx_set(GP0_IO, 0x00000004); |
263 | return 0; | 263 | return 0; |
264 | } | 264 | } |
265 | else { | 265 | else { |
266 | printk(KERN_ERR | 266 | printk(KERN_ERR |
267 | "%s(): Unknow command.\n", __FUNCTION__); | 267 | "%s(): Unknow command.\n", __func__); |
268 | return -EINVAL; | 268 | return -EINVAL; |
269 | } | 269 | } |
270 | break; | 270 | break; |
271 | } | 271 | } |
272 | 272 | ||
273 | return 0; /* Should never be here */ | 273 | return 0; /* Should never be here */ |
274 | } | 274 | } |
275 | 275 | ||
276 | void cx23885_gpio_setup(struct cx23885_dev *dev) | 276 | void cx23885_gpio_setup(struct cx23885_dev *dev) |
277 | { | 277 | { |
278 | switch(dev->board) { | 278 | switch(dev->board) { |
279 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 279 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
280 | /* GPIO-0 cx24227 demodulator reset */ | 280 | /* GPIO-0 cx24227 demodulator reset */ |
281 | cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ | 281 | cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ |
282 | break; | 282 | break; |
283 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 283 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
284 | /* GPIO-0 cx24227 demodulator */ | 284 | /* GPIO-0 cx24227 demodulator */ |
285 | /* GPIO-2 xc3028 tuner */ | 285 | /* GPIO-2 xc3028 tuner */ |
286 | 286 | ||
287 | /* Put the parts into reset */ | 287 | /* Put the parts into reset */ |
288 | cx_set(GP0_IO, 0x00050000); | 288 | cx_set(GP0_IO, 0x00050000); |
289 | cx_clear(GP0_IO, 0x00000005); | 289 | cx_clear(GP0_IO, 0x00000005); |
290 | msleep(5); | 290 | msleep(5); |
291 | 291 | ||
292 | /* Bring the parts out of reset */ | 292 | /* Bring the parts out of reset */ |
293 | cx_set(GP0_IO, 0x00050005); | 293 | cx_set(GP0_IO, 0x00050005); |
294 | break; | 294 | break; |
295 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 295 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
296 | /* GPIO-0 cx24227 demodulator reset */ | 296 | /* GPIO-0 cx24227 demodulator reset */ |
297 | /* GPIO-2 xc5000 tuner reset */ | 297 | /* GPIO-2 xc5000 tuner reset */ |
298 | cx_set(GP0_IO, 0x00050005); /* Bring the part out of reset */ | 298 | cx_set(GP0_IO, 0x00050005); /* Bring the part out of reset */ |
299 | break; | 299 | break; |
300 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | 300 | case CX23885_BOARD_HAUPPAUGE_HVR1800: |
301 | /* GPIO-0 656_CLK */ | 301 | /* GPIO-0 656_CLK */ |
302 | /* GPIO-1 656_D0 */ | 302 | /* GPIO-1 656_D0 */ |
303 | /* GPIO-2 8295A Reset */ | 303 | /* GPIO-2 8295A Reset */ |
304 | /* GPIO-3-10 cx23417 data0-7 */ | 304 | /* GPIO-3-10 cx23417 data0-7 */ |
305 | /* GPIO-11-14 cx23417 addr0-3 */ | 305 | /* GPIO-11-14 cx23417 addr0-3 */ |
306 | /* GPIO-15-18 cx23417 READY, CS, RD, WR */ | 306 | /* GPIO-15-18 cx23417 READY, CS, RD, WR */ |
307 | /* GPIO-19 IR_RX */ | 307 | /* GPIO-19 IR_RX */ |
308 | 308 | ||
309 | /* Force the TDA8295A into reset and back */ | 309 | /* Force the TDA8295A into reset and back */ |
310 | cx_set(GP0_IO, 0x00040004); | 310 | cx_set(GP0_IO, 0x00040004); |
311 | mdelay(20); | 311 | mdelay(20); |
312 | cx_clear(GP0_IO, 0x00000004); | 312 | cx_clear(GP0_IO, 0x00000004); |
313 | mdelay(20); | 313 | mdelay(20); |
314 | cx_set(GP0_IO, 0x00040004); | 314 | cx_set(GP0_IO, 0x00040004); |
315 | mdelay(20); | 315 | mdelay(20); |
316 | break; | 316 | break; |
317 | } | 317 | } |
318 | } | 318 | } |
319 | 319 | ||
320 | int cx23885_ir_init(struct cx23885_dev *dev) | 320 | int cx23885_ir_init(struct cx23885_dev *dev) |
321 | { | 321 | { |
322 | switch (dev->board) { | 322 | switch (dev->board) { |
323 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 323 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
324 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 324 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
325 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 325 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
326 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | 326 | case CX23885_BOARD_HAUPPAUGE_HVR1800: |
327 | /* FIXME: Implement me */ | 327 | /* FIXME: Implement me */ |
328 | break; | 328 | break; |
329 | } | 329 | } |
330 | 330 | ||
331 | return 0; | 331 | return 0; |
332 | } | 332 | } |
333 | 333 | ||
334 | void cx23885_card_setup(struct cx23885_dev *dev) | 334 | void cx23885_card_setup(struct cx23885_dev *dev) |
335 | { | 335 | { |
336 | struct cx23885_tsport *ts1 = &dev->ts1; | 336 | struct cx23885_tsport *ts1 = &dev->ts1; |
337 | struct cx23885_tsport *ts2 = &dev->ts2; | 337 | struct cx23885_tsport *ts2 = &dev->ts2; |
338 | 338 | ||
339 | static u8 eeprom[256]; | 339 | static u8 eeprom[256]; |
340 | 340 | ||
341 | if (dev->i2c_bus[0].i2c_rc == 0) { | 341 | if (dev->i2c_bus[0].i2c_rc == 0) { |
342 | dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; | 342 | dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; |
343 | tveeprom_read(&dev->i2c_bus[0].i2c_client, | 343 | tveeprom_read(&dev->i2c_bus[0].i2c_client, |
344 | eeprom, sizeof(eeprom)); | 344 | eeprom, sizeof(eeprom)); |
345 | } | 345 | } |
346 | 346 | ||
347 | switch (dev->board) { | 347 | switch (dev->board) { |
348 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 348 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
349 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 349 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
350 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 350 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
351 | if (dev->i2c_bus[0].i2c_rc == 0) | 351 | if (dev->i2c_bus[0].i2c_rc == 0) |
352 | hauppauge_eeprom(dev, eeprom+0x80); | 352 | hauppauge_eeprom(dev, eeprom+0x80); |
353 | break; | 353 | break; |
354 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | 354 | case CX23885_BOARD_HAUPPAUGE_HVR1800: |
355 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: | 355 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: |
356 | if (dev->i2c_bus[0].i2c_rc == 0) | 356 | if (dev->i2c_bus[0].i2c_rc == 0) |
357 | hauppauge_eeprom(dev, eeprom+0xc0); | 357 | hauppauge_eeprom(dev, eeprom+0xc0); |
358 | break; | 358 | break; |
359 | } | 359 | } |
360 | 360 | ||
361 | switch (dev->board) { | 361 | switch (dev->board) { |
362 | case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: | 362 | case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: |
363 | ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ | 363 | ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ |
364 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 364 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
365 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 365 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
366 | break; | 366 | break; |
367 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 367 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
368 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 368 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
369 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 369 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
370 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | 370 | case CX23885_BOARD_HAUPPAUGE_HVR1800: |
371 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: | 371 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: |
372 | default: | 372 | default: |
373 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ | 373 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ |
374 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 374 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
375 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 375 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
376 | } | 376 | } |
377 | 377 | ||
378 | } | 378 | } |
379 | 379 | ||
380 | /* ------------------------------------------------------------------ */ | 380 | /* ------------------------------------------------------------------ */ |
381 | 381 | ||
382 | /* | 382 | /* |
383 | * Local variables: | 383 | * Local variables: |
384 | * c-basic-offset: 8 | 384 | * c-basic-offset: 8 |
385 | * End: | 385 | * End: |
386 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off | 386 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off |
387 | */ | 387 | */ |
388 | 388 |
drivers/media/video/cx23885/cx23885-core.c
1 | /* | 1 | /* |
2 | * Driver for the Conexant CX23885 PCIe bridge | 2 | * Driver for the Conexant CX23885 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> | 4 | * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> |
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 <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
26 | #include <linux/kmod.h> | 26 | #include <linux/kmod.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <asm/div64.h> | 31 | #include <asm/div64.h> |
32 | 32 | ||
33 | #include "cx23885.h" | 33 | #include "cx23885.h" |
34 | 34 | ||
35 | MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); | 35 | MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); |
36 | MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); | 36 | MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); |
37 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
38 | 38 | ||
39 | static unsigned int debug; | 39 | static unsigned int debug; |
40 | module_param(debug,int,0644); | 40 | module_param(debug,int,0644); |
41 | MODULE_PARM_DESC(debug,"enable debug messages"); | 41 | MODULE_PARM_DESC(debug,"enable debug messages"); |
42 | 42 | ||
43 | static unsigned int card[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; | 43 | static unsigned int card[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; |
44 | module_param_array(card, int, NULL, 0444); | 44 | module_param_array(card, int, NULL, 0444); |
45 | MODULE_PARM_DESC(card,"card type"); | 45 | MODULE_PARM_DESC(card,"card type"); |
46 | 46 | ||
47 | #define dprintk(level, fmt, arg...)\ | 47 | #define dprintk(level, fmt, arg...)\ |
48 | do { if (debug >= level)\ | 48 | do { if (debug >= level)\ |
49 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ | 49 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ |
50 | } while (0) | 50 | } while (0) |
51 | 51 | ||
52 | static unsigned int cx23885_devcount; | 52 | static unsigned int cx23885_devcount; |
53 | 53 | ||
54 | static DEFINE_MUTEX(devlist); | 54 | static DEFINE_MUTEX(devlist); |
55 | LIST_HEAD(cx23885_devlist); | 55 | LIST_HEAD(cx23885_devlist); |
56 | 56 | ||
57 | #define NO_SYNC_LINE (-1U) | 57 | #define NO_SYNC_LINE (-1U) |
58 | 58 | ||
59 | /* FIXME, these allocations will change when | 59 | /* FIXME, these allocations will change when |
60 | * analog arrives. The be reviewed. | 60 | * analog arrives. The be reviewed. |
61 | * CX23887 Assumptions | 61 | * CX23887 Assumptions |
62 | * 1 line = 16 bytes of CDT | 62 | * 1 line = 16 bytes of CDT |
63 | * cmds size = 80 | 63 | * cmds size = 80 |
64 | * cdt size = 16 * linesize | 64 | * cdt size = 16 * linesize |
65 | * iqsize = 64 | 65 | * iqsize = 64 |
66 | * maxlines = 6 | 66 | * maxlines = 6 |
67 | * | 67 | * |
68 | * Address Space: | 68 | * Address Space: |
69 | * 0x00000000 0x00008fff FIFO clusters | 69 | * 0x00000000 0x00008fff FIFO clusters |
70 | * 0x00010000 0x000104af Channel Management Data Structures | 70 | * 0x00010000 0x000104af Channel Management Data Structures |
71 | * 0x000104b0 0x000104ff Free | 71 | * 0x000104b0 0x000104ff Free |
72 | * 0x00010500 0x000108bf 15 channels * iqsize | 72 | * 0x00010500 0x000108bf 15 channels * iqsize |
73 | * 0x000108c0 0x000108ff Free | 73 | * 0x000108c0 0x000108ff Free |
74 | * 0x00010900 0x00010e9f IQ's + Cluster Descriptor Tables | 74 | * 0x00010900 0x00010e9f IQ's + Cluster Descriptor Tables |
75 | * 15 channels * (iqsize + (maxlines * linesize)) | 75 | * 15 channels * (iqsize + (maxlines * linesize)) |
76 | * 0x00010ea0 0x00010xxx Free | 76 | * 0x00010ea0 0x00010xxx Free |
77 | */ | 77 | */ |
78 | 78 | ||
79 | static struct sram_channel cx23887_sram_channels[] = { | 79 | static struct sram_channel cx23887_sram_channels[] = { |
80 | [SRAM_CH01] = { | 80 | [SRAM_CH01] = { |
81 | .name = "VID A", | 81 | .name = "VID A", |
82 | .cmds_start = 0x10000, | 82 | .cmds_start = 0x10000, |
83 | .ctrl_start = 0x105b0, | 83 | .ctrl_start = 0x105b0, |
84 | .cdt = 0x107b0, | 84 | .cdt = 0x107b0, |
85 | .fifo_start = 0x40, | 85 | .fifo_start = 0x40, |
86 | .fifo_size = 0x2800, | 86 | .fifo_size = 0x2800, |
87 | .ptr1_reg = DMA1_PTR1, | 87 | .ptr1_reg = DMA1_PTR1, |
88 | .ptr2_reg = DMA1_PTR2, | 88 | .ptr2_reg = DMA1_PTR2, |
89 | .cnt1_reg = DMA1_CNT1, | 89 | .cnt1_reg = DMA1_CNT1, |
90 | .cnt2_reg = DMA1_CNT2, | 90 | .cnt2_reg = DMA1_CNT2, |
91 | }, | 91 | }, |
92 | [SRAM_CH02] = { | 92 | [SRAM_CH02] = { |
93 | .name = "ch2", | 93 | .name = "ch2", |
94 | .cmds_start = 0x0, | 94 | .cmds_start = 0x0, |
95 | .ctrl_start = 0x0, | 95 | .ctrl_start = 0x0, |
96 | .cdt = 0x0, | 96 | .cdt = 0x0, |
97 | .fifo_start = 0x0, | 97 | .fifo_start = 0x0, |
98 | .fifo_size = 0x0, | 98 | .fifo_size = 0x0, |
99 | .ptr1_reg = DMA2_PTR1, | 99 | .ptr1_reg = DMA2_PTR1, |
100 | .ptr2_reg = DMA2_PTR2, | 100 | .ptr2_reg = DMA2_PTR2, |
101 | .cnt1_reg = DMA2_CNT1, | 101 | .cnt1_reg = DMA2_CNT1, |
102 | .cnt2_reg = DMA2_CNT2, | 102 | .cnt2_reg = DMA2_CNT2, |
103 | }, | 103 | }, |
104 | [SRAM_CH03] = { | 104 | [SRAM_CH03] = { |
105 | .name = "TS1 B", | 105 | .name = "TS1 B", |
106 | .cmds_start = 0x100A0, | 106 | .cmds_start = 0x100A0, |
107 | .ctrl_start = 0x10780, | 107 | .ctrl_start = 0x10780, |
108 | .cdt = 0x10400, | 108 | .cdt = 0x10400, |
109 | .fifo_start = 0x5000, | 109 | .fifo_start = 0x5000, |
110 | .fifo_size = 0x1000, | 110 | .fifo_size = 0x1000, |
111 | .ptr1_reg = DMA3_PTR1, | 111 | .ptr1_reg = DMA3_PTR1, |
112 | .ptr2_reg = DMA3_PTR2, | 112 | .ptr2_reg = DMA3_PTR2, |
113 | .cnt1_reg = DMA3_CNT1, | 113 | .cnt1_reg = DMA3_CNT1, |
114 | .cnt2_reg = DMA3_CNT2, | 114 | .cnt2_reg = DMA3_CNT2, |
115 | }, | 115 | }, |
116 | [SRAM_CH04] = { | 116 | [SRAM_CH04] = { |
117 | .name = "ch4", | 117 | .name = "ch4", |
118 | .cmds_start = 0x0, | 118 | .cmds_start = 0x0, |
119 | .ctrl_start = 0x0, | 119 | .ctrl_start = 0x0, |
120 | .cdt = 0x0, | 120 | .cdt = 0x0, |
121 | .fifo_start = 0x0, | 121 | .fifo_start = 0x0, |
122 | .fifo_size = 0x0, | 122 | .fifo_size = 0x0, |
123 | .ptr1_reg = DMA4_PTR1, | 123 | .ptr1_reg = DMA4_PTR1, |
124 | .ptr2_reg = DMA4_PTR2, | 124 | .ptr2_reg = DMA4_PTR2, |
125 | .cnt1_reg = DMA4_CNT1, | 125 | .cnt1_reg = DMA4_CNT1, |
126 | .cnt2_reg = DMA4_CNT2, | 126 | .cnt2_reg = DMA4_CNT2, |
127 | }, | 127 | }, |
128 | [SRAM_CH05] = { | 128 | [SRAM_CH05] = { |
129 | .name = "ch5", | 129 | .name = "ch5", |
130 | .cmds_start = 0x0, | 130 | .cmds_start = 0x0, |
131 | .ctrl_start = 0x0, | 131 | .ctrl_start = 0x0, |
132 | .cdt = 0x0, | 132 | .cdt = 0x0, |
133 | .fifo_start = 0x0, | 133 | .fifo_start = 0x0, |
134 | .fifo_size = 0x0, | 134 | .fifo_size = 0x0, |
135 | .ptr1_reg = DMA5_PTR1, | 135 | .ptr1_reg = DMA5_PTR1, |
136 | .ptr2_reg = DMA5_PTR2, | 136 | .ptr2_reg = DMA5_PTR2, |
137 | .cnt1_reg = DMA5_CNT1, | 137 | .cnt1_reg = DMA5_CNT1, |
138 | .cnt2_reg = DMA5_CNT2, | 138 | .cnt2_reg = DMA5_CNT2, |
139 | }, | 139 | }, |
140 | [SRAM_CH06] = { | 140 | [SRAM_CH06] = { |
141 | .name = "TS2 C", | 141 | .name = "TS2 C", |
142 | .cmds_start = 0x10140, | 142 | .cmds_start = 0x10140, |
143 | .ctrl_start = 0x10680, | 143 | .ctrl_start = 0x10680, |
144 | .cdt = 0x108d0, | 144 | .cdt = 0x108d0, |
145 | .fifo_start = 0x6000, | 145 | .fifo_start = 0x6000, |
146 | .fifo_size = 0x1000, | 146 | .fifo_size = 0x1000, |
147 | .ptr1_reg = DMA5_PTR1, | 147 | .ptr1_reg = DMA5_PTR1, |
148 | .ptr2_reg = DMA5_PTR2, | 148 | .ptr2_reg = DMA5_PTR2, |
149 | .cnt1_reg = DMA5_CNT1, | 149 | .cnt1_reg = DMA5_CNT1, |
150 | .cnt2_reg = DMA5_CNT2, | 150 | .cnt2_reg = DMA5_CNT2, |
151 | }, | 151 | }, |
152 | [SRAM_CH07] = { | 152 | [SRAM_CH07] = { |
153 | .name = "ch7", | 153 | .name = "ch7", |
154 | .cmds_start = 0x0, | 154 | .cmds_start = 0x0, |
155 | .ctrl_start = 0x0, | 155 | .ctrl_start = 0x0, |
156 | .cdt = 0x0, | 156 | .cdt = 0x0, |
157 | .fifo_start = 0x0, | 157 | .fifo_start = 0x0, |
158 | .fifo_size = 0x0, | 158 | .fifo_size = 0x0, |
159 | .ptr1_reg = DMA6_PTR1, | 159 | .ptr1_reg = DMA6_PTR1, |
160 | .ptr2_reg = DMA6_PTR2, | 160 | .ptr2_reg = DMA6_PTR2, |
161 | .cnt1_reg = DMA6_CNT1, | 161 | .cnt1_reg = DMA6_CNT1, |
162 | .cnt2_reg = DMA6_CNT2, | 162 | .cnt2_reg = DMA6_CNT2, |
163 | }, | 163 | }, |
164 | [SRAM_CH08] = { | 164 | [SRAM_CH08] = { |
165 | .name = "ch8", | 165 | .name = "ch8", |
166 | .cmds_start = 0x0, | 166 | .cmds_start = 0x0, |
167 | .ctrl_start = 0x0, | 167 | .ctrl_start = 0x0, |
168 | .cdt = 0x0, | 168 | .cdt = 0x0, |
169 | .fifo_start = 0x0, | 169 | .fifo_start = 0x0, |
170 | .fifo_size = 0x0, | 170 | .fifo_size = 0x0, |
171 | .ptr1_reg = DMA7_PTR1, | 171 | .ptr1_reg = DMA7_PTR1, |
172 | .ptr2_reg = DMA7_PTR2, | 172 | .ptr2_reg = DMA7_PTR2, |
173 | .cnt1_reg = DMA7_CNT1, | 173 | .cnt1_reg = DMA7_CNT1, |
174 | .cnt2_reg = DMA7_CNT2, | 174 | .cnt2_reg = DMA7_CNT2, |
175 | }, | 175 | }, |
176 | [SRAM_CH09] = { | 176 | [SRAM_CH09] = { |
177 | .name = "ch9", | 177 | .name = "ch9", |
178 | .cmds_start = 0x0, | 178 | .cmds_start = 0x0, |
179 | .ctrl_start = 0x0, | 179 | .ctrl_start = 0x0, |
180 | .cdt = 0x0, | 180 | .cdt = 0x0, |
181 | .fifo_start = 0x0, | 181 | .fifo_start = 0x0, |
182 | .fifo_size = 0x0, | 182 | .fifo_size = 0x0, |
183 | .ptr1_reg = DMA8_PTR1, | 183 | .ptr1_reg = DMA8_PTR1, |
184 | .ptr2_reg = DMA8_PTR2, | 184 | .ptr2_reg = DMA8_PTR2, |
185 | .cnt1_reg = DMA8_CNT1, | 185 | .cnt1_reg = DMA8_CNT1, |
186 | .cnt2_reg = DMA8_CNT2, | 186 | .cnt2_reg = DMA8_CNT2, |
187 | }, | 187 | }, |
188 | }; | 188 | }; |
189 | 189 | ||
190 | static int cx23885_risc_decode(u32 risc) | 190 | static int cx23885_risc_decode(u32 risc) |
191 | { | 191 | { |
192 | static char *instr[16] = { | 192 | static char *instr[16] = { |
193 | [ RISC_SYNC >> 28 ] = "sync", | 193 | [ RISC_SYNC >> 28 ] = "sync", |
194 | [ RISC_WRITE >> 28 ] = "write", | 194 | [ RISC_WRITE >> 28 ] = "write", |
195 | [ RISC_WRITEC >> 28 ] = "writec", | 195 | [ RISC_WRITEC >> 28 ] = "writec", |
196 | [ RISC_READ >> 28 ] = "read", | 196 | [ RISC_READ >> 28 ] = "read", |
197 | [ RISC_READC >> 28 ] = "readc", | 197 | [ RISC_READC >> 28 ] = "readc", |
198 | [ RISC_JUMP >> 28 ] = "jump", | 198 | [ RISC_JUMP >> 28 ] = "jump", |
199 | [ RISC_SKIP >> 28 ] = "skip", | 199 | [ RISC_SKIP >> 28 ] = "skip", |
200 | [ RISC_WRITERM >> 28 ] = "writerm", | 200 | [ RISC_WRITERM >> 28 ] = "writerm", |
201 | [ RISC_WRITECM >> 28 ] = "writecm", | 201 | [ RISC_WRITECM >> 28 ] = "writecm", |
202 | [ RISC_WRITECR >> 28 ] = "writecr", | 202 | [ RISC_WRITECR >> 28 ] = "writecr", |
203 | }; | 203 | }; |
204 | static int incr[16] = { | 204 | static int incr[16] = { |
205 | [ RISC_WRITE >> 28 ] = 3, | 205 | [ RISC_WRITE >> 28 ] = 3, |
206 | [ RISC_JUMP >> 28 ] = 3, | 206 | [ RISC_JUMP >> 28 ] = 3, |
207 | [ RISC_SKIP >> 28 ] = 1, | 207 | [ RISC_SKIP >> 28 ] = 1, |
208 | [ RISC_SYNC >> 28 ] = 1, | 208 | [ RISC_SYNC >> 28 ] = 1, |
209 | [ RISC_WRITERM >> 28 ] = 3, | 209 | [ RISC_WRITERM >> 28 ] = 3, |
210 | [ RISC_WRITECM >> 28 ] = 3, | 210 | [ RISC_WRITECM >> 28 ] = 3, |
211 | [ RISC_WRITECR >> 28 ] = 4, | 211 | [ RISC_WRITECR >> 28 ] = 4, |
212 | }; | 212 | }; |
213 | static char *bits[] = { | 213 | static char *bits[] = { |
214 | "12", "13", "14", "resync", | 214 | "12", "13", "14", "resync", |
215 | "cnt0", "cnt1", "18", "19", | 215 | "cnt0", "cnt1", "18", "19", |
216 | "20", "21", "22", "23", | 216 | "20", "21", "22", "23", |
217 | "irq1", "irq2", "eol", "sol", | 217 | "irq1", "irq2", "eol", "sol", |
218 | }; | 218 | }; |
219 | int i; | 219 | int i; |
220 | 220 | ||
221 | printk("0x%08x [ %s", risc, | 221 | printk("0x%08x [ %s", risc, |
222 | instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); | 222 | instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); |
223 | for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) | 223 | for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) |
224 | if (risc & (1 << (i + 12))) | 224 | if (risc & (1 << (i + 12))) |
225 | printk(" %s", bits[i]); | 225 | printk(" %s", bits[i]); |
226 | printk(" count=%d ]\n", risc & 0xfff); | 226 | printk(" count=%d ]\n", risc & 0xfff); |
227 | return incr[risc >> 28] ? incr[risc >> 28] : 1; | 227 | return incr[risc >> 28] ? incr[risc >> 28] : 1; |
228 | } | 228 | } |
229 | 229 | ||
230 | void cx23885_wakeup(struct cx23885_tsport *port, | 230 | void cx23885_wakeup(struct cx23885_tsport *port, |
231 | struct cx23885_dmaqueue *q, u32 count) | 231 | struct cx23885_dmaqueue *q, u32 count) |
232 | { | 232 | { |
233 | struct cx23885_dev *dev = port->dev; | 233 | struct cx23885_dev *dev = port->dev; |
234 | struct cx23885_buffer *buf; | 234 | struct cx23885_buffer *buf; |
235 | int bc; | 235 | int bc; |
236 | 236 | ||
237 | for (bc = 0;; bc++) { | 237 | for (bc = 0;; bc++) { |
238 | if (list_empty(&q->active)) | 238 | if (list_empty(&q->active)) |
239 | break; | 239 | break; |
240 | buf = list_entry(q->active.next, | 240 | buf = list_entry(q->active.next, |
241 | struct cx23885_buffer, vb.queue); | 241 | struct cx23885_buffer, vb.queue); |
242 | 242 | ||
243 | /* count comes from the hw and is is 16bit wide -- | 243 | /* count comes from the hw and is is 16bit wide -- |
244 | * this trick handles wrap-arounds correctly for | 244 | * this trick handles wrap-arounds correctly for |
245 | * up to 32767 buffers in flight... */ | 245 | * up to 32767 buffers in flight... */ |
246 | if ((s16) (count - buf->count) < 0) | 246 | if ((s16) (count - buf->count) < 0) |
247 | break; | 247 | break; |
248 | 248 | ||
249 | do_gettimeofday(&buf->vb.ts); | 249 | do_gettimeofday(&buf->vb.ts); |
250 | dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, | 250 | dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, |
251 | count, buf->count); | 251 | count, buf->count); |
252 | buf->vb.state = VIDEOBUF_DONE; | 252 | buf->vb.state = VIDEOBUF_DONE; |
253 | list_del(&buf->vb.queue); | 253 | list_del(&buf->vb.queue); |
254 | wake_up(&buf->vb.done); | 254 | wake_up(&buf->vb.done); |
255 | } | 255 | } |
256 | if (list_empty(&q->active)) { | 256 | if (list_empty(&q->active)) { |
257 | del_timer(&q->timeout); | 257 | del_timer(&q->timeout); |
258 | } else { | 258 | } else { |
259 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); | 259 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); |
260 | } | 260 | } |
261 | if (bc != 1) | 261 | if (bc != 1) |
262 | printk("%s: %d buffers handled (should be 1)\n", | 262 | printk("%s: %d buffers handled (should be 1)\n", |
263 | __FUNCTION__, bc); | 263 | __func__, bc); |
264 | } | 264 | } |
265 | 265 | ||
266 | int cx23885_sram_channel_setup(struct cx23885_dev *dev, | 266 | int cx23885_sram_channel_setup(struct cx23885_dev *dev, |
267 | struct sram_channel *ch, | 267 | struct sram_channel *ch, |
268 | unsigned int bpl, u32 risc) | 268 | unsigned int bpl, u32 risc) |
269 | { | 269 | { |
270 | unsigned int i, lines; | 270 | unsigned int i, lines; |
271 | u32 cdt; | 271 | u32 cdt; |
272 | 272 | ||
273 | if (ch->cmds_start == 0) | 273 | if (ch->cmds_start == 0) |
274 | { | 274 | { |
275 | dprintk(1, "%s() Erasing channel [%s]\n", __FUNCTION__, | 275 | dprintk(1, "%s() Erasing channel [%s]\n", __func__, |
276 | ch->name); | 276 | ch->name); |
277 | cx_write(ch->ptr1_reg, 0); | 277 | cx_write(ch->ptr1_reg, 0); |
278 | cx_write(ch->ptr2_reg, 0); | 278 | cx_write(ch->ptr2_reg, 0); |
279 | cx_write(ch->cnt2_reg, 0); | 279 | cx_write(ch->cnt2_reg, 0); |
280 | cx_write(ch->cnt1_reg, 0); | 280 | cx_write(ch->cnt1_reg, 0); |
281 | return 0; | 281 | return 0; |
282 | } else { | 282 | } else { |
283 | dprintk(1, "%s() Configuring channel [%s]\n", __FUNCTION__, | 283 | dprintk(1, "%s() Configuring channel [%s]\n", __func__, |
284 | ch->name); | 284 | ch->name); |
285 | } | 285 | } |
286 | 286 | ||
287 | bpl = (bpl + 7) & ~7; /* alignment */ | 287 | bpl = (bpl + 7) & ~7; /* alignment */ |
288 | cdt = ch->cdt; | 288 | cdt = ch->cdt; |
289 | lines = ch->fifo_size / bpl; | 289 | lines = ch->fifo_size / bpl; |
290 | if (lines > 6) | 290 | if (lines > 6) |
291 | lines = 6; | 291 | lines = 6; |
292 | BUG_ON(lines < 2); | 292 | BUG_ON(lines < 2); |
293 | 293 | ||
294 | cx_write(8 + 0, cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC) ); | 294 | cx_write(8 + 0, cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC) ); |
295 | cx_write(8 + 4, cpu_to_le32(8) ); | 295 | cx_write(8 + 4, cpu_to_le32(8) ); |
296 | cx_write(8 + 8, cpu_to_le32(0) ); | 296 | cx_write(8 + 8, cpu_to_le32(0) ); |
297 | 297 | ||
298 | /* write CDT */ | 298 | /* write CDT */ |
299 | for (i = 0; i < lines; i++) { | 299 | for (i = 0; i < lines; i++) { |
300 | dprintk(2, "%s() 0x%08x <- 0x%08x\n", __FUNCTION__, cdt + 16*i, | 300 | dprintk(2, "%s() 0x%08x <- 0x%08x\n", __func__, cdt + 16*i, |
301 | ch->fifo_start + bpl*i); | 301 | ch->fifo_start + bpl*i); |
302 | cx_write(cdt + 16*i, ch->fifo_start + bpl*i); | 302 | cx_write(cdt + 16*i, ch->fifo_start + bpl*i); |
303 | cx_write(cdt + 16*i + 4, 0); | 303 | cx_write(cdt + 16*i + 4, 0); |
304 | cx_write(cdt + 16*i + 8, 0); | 304 | cx_write(cdt + 16*i + 8, 0); |
305 | cx_write(cdt + 16*i + 12, 0); | 305 | cx_write(cdt + 16*i + 12, 0); |
306 | } | 306 | } |
307 | 307 | ||
308 | /* write CMDS */ | 308 | /* write CMDS */ |
309 | if (ch->jumponly) | 309 | if (ch->jumponly) |
310 | cx_write(ch->cmds_start + 0, 8); | 310 | cx_write(ch->cmds_start + 0, 8); |
311 | else | 311 | else |
312 | cx_write(ch->cmds_start + 0, risc); | 312 | cx_write(ch->cmds_start + 0, risc); |
313 | cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */ | 313 | cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */ |
314 | cx_write(ch->cmds_start + 8, cdt); | 314 | cx_write(ch->cmds_start + 8, cdt); |
315 | cx_write(ch->cmds_start + 12, (lines*16) >> 3); | 315 | cx_write(ch->cmds_start + 12, (lines*16) >> 3); |
316 | cx_write(ch->cmds_start + 16, ch->ctrl_start); | 316 | cx_write(ch->cmds_start + 16, ch->ctrl_start); |
317 | if (ch->jumponly) | 317 | if (ch->jumponly) |
318 | cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2) ); | 318 | cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2) ); |
319 | else | 319 | else |
320 | cx_write(ch->cmds_start + 20, 64 >> 2); | 320 | cx_write(ch->cmds_start + 20, 64 >> 2); |
321 | for (i = 24; i < 80; i += 4) | 321 | for (i = 24; i < 80; i += 4) |
322 | cx_write(ch->cmds_start + i, 0); | 322 | cx_write(ch->cmds_start + i, 0); |
323 | 323 | ||
324 | /* fill registers */ | 324 | /* fill registers */ |
325 | cx_write(ch->ptr1_reg, ch->fifo_start); | 325 | cx_write(ch->ptr1_reg, ch->fifo_start); |
326 | cx_write(ch->ptr2_reg, cdt); | 326 | cx_write(ch->ptr2_reg, cdt); |
327 | cx_write(ch->cnt2_reg, (lines*16) >> 3); | 327 | cx_write(ch->cnt2_reg, (lines*16) >> 3); |
328 | cx_write(ch->cnt1_reg, (bpl >> 3) -1); | 328 | cx_write(ch->cnt1_reg, (bpl >> 3) -1); |
329 | 329 | ||
330 | dprintk(2,"[bridge %d] sram setup %s: bpl=%d lines=%d\n", | 330 | dprintk(2,"[bridge %d] sram setup %s: bpl=%d lines=%d\n", |
331 | dev->bridge, | 331 | dev->bridge, |
332 | ch->name, | 332 | ch->name, |
333 | bpl, | 333 | bpl, |
334 | lines); | 334 | lines); |
335 | 335 | ||
336 | return 0; | 336 | return 0; |
337 | } | 337 | } |
338 | 338 | ||
339 | void cx23885_sram_channel_dump(struct cx23885_dev *dev, | 339 | void cx23885_sram_channel_dump(struct cx23885_dev *dev, |
340 | struct sram_channel *ch) | 340 | struct sram_channel *ch) |
341 | { | 341 | { |
342 | static char *name[] = { | 342 | static char *name[] = { |
343 | "init risc lo", | 343 | "init risc lo", |
344 | "init risc hi", | 344 | "init risc hi", |
345 | "cdt base", | 345 | "cdt base", |
346 | "cdt size", | 346 | "cdt size", |
347 | "iq base", | 347 | "iq base", |
348 | "iq size", | 348 | "iq size", |
349 | "risc pc lo", | 349 | "risc pc lo", |
350 | "risc pc hi", | 350 | "risc pc hi", |
351 | "iq wr ptr", | 351 | "iq wr ptr", |
352 | "iq rd ptr", | 352 | "iq rd ptr", |
353 | "cdt current", | 353 | "cdt current", |
354 | "pci target lo", | 354 | "pci target lo", |
355 | "pci target hi", | 355 | "pci target hi", |
356 | "line / byte", | 356 | "line / byte", |
357 | }; | 357 | }; |
358 | u32 risc; | 358 | u32 risc; |
359 | unsigned int i, j, n; | 359 | unsigned int i, j, n; |
360 | 360 | ||
361 | printk("%s: %s - dma channel status dump\n", | 361 | printk("%s: %s - dma channel status dump\n", |
362 | dev->name, ch->name); | 362 | dev->name, ch->name); |
363 | for (i = 0; i < ARRAY_SIZE(name); i++) | 363 | for (i = 0; i < ARRAY_SIZE(name); i++) |
364 | printk("%s: cmds: %-15s: 0x%08x\n", | 364 | printk("%s: cmds: %-15s: 0x%08x\n", |
365 | dev->name, name[i], | 365 | dev->name, name[i], |
366 | cx_read(ch->cmds_start + 4*i)); | 366 | cx_read(ch->cmds_start + 4*i)); |
367 | 367 | ||
368 | for (i = 0; i < 4; i++) { | 368 | for (i = 0; i < 4; i++) { |
369 | risc = cx_read(ch->cmds_start + 4 * (i + 14)); | 369 | risc = cx_read(ch->cmds_start + 4 * (i + 14)); |
370 | printk("%s: risc%d: ", dev->name, i); | 370 | printk("%s: risc%d: ", dev->name, i); |
371 | cx23885_risc_decode(risc); | 371 | cx23885_risc_decode(risc); |
372 | } | 372 | } |
373 | for (i = 0; i < (64 >> 2); i += n) { | 373 | for (i = 0; i < (64 >> 2); i += n) { |
374 | risc = cx_read(ch->ctrl_start + 4 * i); | 374 | risc = cx_read(ch->ctrl_start + 4 * i); |
375 | /* No consideration for bits 63-32 */ | 375 | /* No consideration for bits 63-32 */ |
376 | 376 | ||
377 | printk("%s: (0x%08x) iq %x: ", dev->name, | 377 | printk("%s: (0x%08x) iq %x: ", dev->name, |
378 | ch->ctrl_start + 4 * i, i); | 378 | ch->ctrl_start + 4 * i, i); |
379 | n = cx23885_risc_decode(risc); | 379 | n = cx23885_risc_decode(risc); |
380 | for (j = 1; j < n; j++) { | 380 | for (j = 1; j < n; j++) { |
381 | risc = cx_read(ch->ctrl_start + 4 * (i + j)); | 381 | risc = cx_read(ch->ctrl_start + 4 * (i + j)); |
382 | printk("%s: iq %x: 0x%08x [ arg #%d ]\n", | 382 | printk("%s: iq %x: 0x%08x [ arg #%d ]\n", |
383 | dev->name, i+j, risc, j); | 383 | dev->name, i+j, risc, j); |
384 | } | 384 | } |
385 | } | 385 | } |
386 | 386 | ||
387 | printk("%s: fifo: 0x%08x -> 0x%x\n", | 387 | printk("%s: fifo: 0x%08x -> 0x%x\n", |
388 | dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); | 388 | dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); |
389 | printk("%s: ctrl: 0x%08x -> 0x%x\n", | 389 | printk("%s: ctrl: 0x%08x -> 0x%x\n", |
390 | dev->name, ch->ctrl_start, ch->ctrl_start + 6*16); | 390 | dev->name, ch->ctrl_start, ch->ctrl_start + 6*16); |
391 | printk("%s: ptr1_reg: 0x%08x\n", | 391 | printk("%s: ptr1_reg: 0x%08x\n", |
392 | dev->name, cx_read(ch->ptr1_reg)); | 392 | dev->name, cx_read(ch->ptr1_reg)); |
393 | printk("%s: ptr2_reg: 0x%08x\n", | 393 | printk("%s: ptr2_reg: 0x%08x\n", |
394 | dev->name, cx_read(ch->ptr2_reg)); | 394 | dev->name, cx_read(ch->ptr2_reg)); |
395 | printk("%s: cnt1_reg: 0x%08x\n", | 395 | printk("%s: cnt1_reg: 0x%08x\n", |
396 | dev->name, cx_read(ch->cnt1_reg)); | 396 | dev->name, cx_read(ch->cnt1_reg)); |
397 | printk("%s: cnt2_reg: 0x%08x\n", | 397 | printk("%s: cnt2_reg: 0x%08x\n", |
398 | dev->name, cx_read(ch->cnt2_reg)); | 398 | dev->name, cx_read(ch->cnt2_reg)); |
399 | } | 399 | } |
400 | 400 | ||
401 | static void cx23885_risc_disasm(struct cx23885_tsport *port, | 401 | static void cx23885_risc_disasm(struct cx23885_tsport *port, |
402 | struct btcx_riscmem *risc) | 402 | struct btcx_riscmem *risc) |
403 | { | 403 | { |
404 | struct cx23885_dev *dev = port->dev; | 404 | struct cx23885_dev *dev = port->dev; |
405 | unsigned int i, j, n; | 405 | unsigned int i, j, n; |
406 | 406 | ||
407 | printk("%s: risc disasm: %p [dma=0x%08lx]\n", | 407 | printk("%s: risc disasm: %p [dma=0x%08lx]\n", |
408 | dev->name, risc->cpu, (unsigned long)risc->dma); | 408 | dev->name, risc->cpu, (unsigned long)risc->dma); |
409 | for (i = 0; i < (risc->size >> 2); i += n) { | 409 | for (i = 0; i < (risc->size >> 2); i += n) { |
410 | printk("%s: %04d: ", dev->name, i); | 410 | printk("%s: %04d: ", dev->name, i); |
411 | n = cx23885_risc_decode(risc->cpu[i]); | 411 | n = cx23885_risc_decode(risc->cpu[i]); |
412 | for (j = 1; j < n; j++) | 412 | for (j = 1; j < n; j++) |
413 | printk("%s: %04d: 0x%08x [ arg #%d ]\n", | 413 | printk("%s: %04d: 0x%08x [ arg #%d ]\n", |
414 | dev->name, i + j, risc->cpu[i + j], j); | 414 | dev->name, i + j, risc->cpu[i + j], j); |
415 | if (risc->cpu[i] == RISC_JUMP) | 415 | if (risc->cpu[i] == RISC_JUMP) |
416 | break; | 416 | break; |
417 | } | 417 | } |
418 | } | 418 | } |
419 | 419 | ||
420 | static void cx23885_shutdown(struct cx23885_dev *dev) | 420 | static void cx23885_shutdown(struct cx23885_dev *dev) |
421 | { | 421 | { |
422 | /* disable RISC controller */ | 422 | /* disable RISC controller */ |
423 | cx_write(DEV_CNTRL2, 0); | 423 | cx_write(DEV_CNTRL2, 0); |
424 | 424 | ||
425 | /* Disable all IR activity */ | 425 | /* Disable all IR activity */ |
426 | cx_write(IR_CNTRL_REG, 0); | 426 | cx_write(IR_CNTRL_REG, 0); |
427 | 427 | ||
428 | /* Disable Video A/B activity */ | 428 | /* Disable Video A/B activity */ |
429 | cx_write(VID_A_DMA_CTL, 0); | 429 | cx_write(VID_A_DMA_CTL, 0); |
430 | cx_write(VID_B_DMA_CTL, 0); | 430 | cx_write(VID_B_DMA_CTL, 0); |
431 | cx_write(VID_C_DMA_CTL, 0); | 431 | cx_write(VID_C_DMA_CTL, 0); |
432 | 432 | ||
433 | /* Disable Audio activity */ | 433 | /* Disable Audio activity */ |
434 | cx_write(AUD_INT_DMA_CTL, 0); | 434 | cx_write(AUD_INT_DMA_CTL, 0); |
435 | cx_write(AUD_EXT_DMA_CTL, 0); | 435 | cx_write(AUD_EXT_DMA_CTL, 0); |
436 | 436 | ||
437 | /* Disable Serial port */ | 437 | /* Disable Serial port */ |
438 | cx_write(UART_CTL, 0); | 438 | cx_write(UART_CTL, 0); |
439 | 439 | ||
440 | /* Disable Interrupts */ | 440 | /* Disable Interrupts */ |
441 | cx_write(PCI_INT_MSK, 0); | 441 | cx_write(PCI_INT_MSK, 0); |
442 | cx_write(VID_A_INT_MSK, 0); | 442 | cx_write(VID_A_INT_MSK, 0); |
443 | cx_write(VID_B_INT_MSK, 0); | 443 | cx_write(VID_B_INT_MSK, 0); |
444 | cx_write(VID_C_INT_MSK, 0); | 444 | cx_write(VID_C_INT_MSK, 0); |
445 | cx_write(AUDIO_INT_INT_MSK, 0); | 445 | cx_write(AUDIO_INT_INT_MSK, 0); |
446 | cx_write(AUDIO_EXT_INT_MSK, 0); | 446 | cx_write(AUDIO_EXT_INT_MSK, 0); |
447 | 447 | ||
448 | } | 448 | } |
449 | 449 | ||
450 | static void cx23885_reset(struct cx23885_dev *dev) | 450 | static void cx23885_reset(struct cx23885_dev *dev) |
451 | { | 451 | { |
452 | dprintk(1, "%s()\n", __FUNCTION__); | 452 | dprintk(1, "%s()\n", __func__); |
453 | 453 | ||
454 | cx23885_shutdown(dev); | 454 | cx23885_shutdown(dev); |
455 | 455 | ||
456 | cx_write(PCI_INT_STAT, 0xffffffff); | 456 | cx_write(PCI_INT_STAT, 0xffffffff); |
457 | cx_write(VID_A_INT_STAT, 0xffffffff); | 457 | cx_write(VID_A_INT_STAT, 0xffffffff); |
458 | cx_write(VID_B_INT_STAT, 0xffffffff); | 458 | cx_write(VID_B_INT_STAT, 0xffffffff); |
459 | cx_write(VID_C_INT_STAT, 0xffffffff); | 459 | cx_write(VID_C_INT_STAT, 0xffffffff); |
460 | cx_write(AUDIO_INT_INT_STAT, 0xffffffff); | 460 | cx_write(AUDIO_INT_INT_STAT, 0xffffffff); |
461 | cx_write(AUDIO_EXT_INT_STAT, 0xffffffff); | 461 | cx_write(AUDIO_EXT_INT_STAT, 0xffffffff); |
462 | cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000); | 462 | cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000); |
463 | 463 | ||
464 | mdelay(100); | 464 | mdelay(100); |
465 | 465 | ||
466 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01], | 466 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01], |
467 | 720*4, 0); | 467 | 720*4, 0); |
468 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02], 128, 0); | 468 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02], 128, 0); |
469 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH03], | 469 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH03], |
470 | 188*4, 0); | 470 | 188*4, 0); |
471 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH04], 128, 0); | 471 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH04], 128, 0); |
472 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH05], 128, 0); | 472 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH05], 128, 0); |
473 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH06], | 473 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH06], |
474 | 188*4, 0); | 474 | 188*4, 0); |
475 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH07], 128, 0); | 475 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH07], 128, 0); |
476 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH08], 128, 0); | 476 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH08], 128, 0); |
477 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH09], 128, 0); | 477 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH09], 128, 0); |
478 | 478 | ||
479 | cx23885_gpio_setup(dev); | 479 | cx23885_gpio_setup(dev); |
480 | } | 480 | } |
481 | 481 | ||
482 | 482 | ||
483 | static int cx23885_pci_quirks(struct cx23885_dev *dev) | 483 | static int cx23885_pci_quirks(struct cx23885_dev *dev) |
484 | { | 484 | { |
485 | dprintk(1, "%s()\n", __FUNCTION__); | 485 | dprintk(1, "%s()\n", __func__); |
486 | 486 | ||
487 | /* The cx23885 bridge has a weird bug which causes NMI to be asserted | 487 | /* The cx23885 bridge has a weird bug which causes NMI to be asserted |
488 | * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not | 488 | * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not |
489 | * occur on the cx23887 bridge. | 489 | * occur on the cx23887 bridge. |
490 | */ | 490 | */ |
491 | if(dev->bridge == CX23885_BRIDGE_885) | 491 | if(dev->bridge == CX23885_BRIDGE_885) |
492 | cx_clear(RDR_TLCTL0, 1 << 4); | 492 | cx_clear(RDR_TLCTL0, 1 << 4); |
493 | 493 | ||
494 | return 0; | 494 | return 0; |
495 | } | 495 | } |
496 | 496 | ||
497 | static int get_resources(struct cx23885_dev *dev) | 497 | static int get_resources(struct cx23885_dev *dev) |
498 | { | 498 | { |
499 | if (request_mem_region(pci_resource_start(dev->pci,0), | 499 | if (request_mem_region(pci_resource_start(dev->pci,0), |
500 | pci_resource_len(dev->pci,0), | 500 | pci_resource_len(dev->pci,0), |
501 | dev->name)) | 501 | dev->name)) |
502 | return 0; | 502 | return 0; |
503 | 503 | ||
504 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", | 504 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", |
505 | dev->name, (unsigned long long)pci_resource_start(dev->pci,0)); | 505 | dev->name, (unsigned long long)pci_resource_start(dev->pci,0)); |
506 | 506 | ||
507 | return -EBUSY; | 507 | return -EBUSY; |
508 | } | 508 | } |
509 | 509 | ||
510 | static void cx23885_timeout(unsigned long data); | 510 | static void cx23885_timeout(unsigned long data); |
511 | int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | 511 | int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, |
512 | u32 reg, u32 mask, u32 value); | 512 | u32 reg, u32 mask, u32 value); |
513 | 513 | ||
514 | static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno) | 514 | static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno) |
515 | { | 515 | { |
516 | dprintk(1, "%s(portno=%d)\n", __FUNCTION__, portno); | 516 | dprintk(1, "%s(portno=%d)\n", __func__, portno); |
517 | 517 | ||
518 | /* Transport bus init dma queue - Common settings */ | 518 | /* Transport bus init dma queue - Common settings */ |
519 | port->dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */ | 519 | port->dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */ |
520 | port->ts_int_msk_val = 0x1111; /* TS port bits for RISC */ | 520 | port->ts_int_msk_val = 0x1111; /* TS port bits for RISC */ |
521 | 521 | ||
522 | spin_lock_init(&port->slock); | 522 | spin_lock_init(&port->slock); |
523 | port->dev = dev; | 523 | port->dev = dev; |
524 | port->nr = portno; | 524 | port->nr = portno; |
525 | 525 | ||
526 | INIT_LIST_HEAD(&port->mpegq.active); | 526 | INIT_LIST_HEAD(&port->mpegq.active); |
527 | INIT_LIST_HEAD(&port->mpegq.queued); | 527 | INIT_LIST_HEAD(&port->mpegq.queued); |
528 | port->mpegq.timeout.function = cx23885_timeout; | 528 | port->mpegq.timeout.function = cx23885_timeout; |
529 | port->mpegq.timeout.data = (unsigned long)port; | 529 | port->mpegq.timeout.data = (unsigned long)port; |
530 | init_timer(&port->mpegq.timeout); | 530 | init_timer(&port->mpegq.timeout); |
531 | 531 | ||
532 | switch(portno) { | 532 | switch(portno) { |
533 | case 1: | 533 | case 1: |
534 | port->reg_gpcnt = VID_B_GPCNT; | 534 | port->reg_gpcnt = VID_B_GPCNT; |
535 | port->reg_gpcnt_ctl = VID_B_GPCNT_CTL; | 535 | port->reg_gpcnt_ctl = VID_B_GPCNT_CTL; |
536 | port->reg_dma_ctl = VID_B_DMA_CTL; | 536 | port->reg_dma_ctl = VID_B_DMA_CTL; |
537 | port->reg_lngth = VID_B_LNGTH; | 537 | port->reg_lngth = VID_B_LNGTH; |
538 | port->reg_hw_sop_ctrl = VID_B_HW_SOP_CTL; | 538 | port->reg_hw_sop_ctrl = VID_B_HW_SOP_CTL; |
539 | port->reg_gen_ctrl = VID_B_GEN_CTL; | 539 | port->reg_gen_ctrl = VID_B_GEN_CTL; |
540 | port->reg_bd_pkt_status = VID_B_BD_PKT_STATUS; | 540 | port->reg_bd_pkt_status = VID_B_BD_PKT_STATUS; |
541 | port->reg_sop_status = VID_B_SOP_STATUS; | 541 | port->reg_sop_status = VID_B_SOP_STATUS; |
542 | port->reg_fifo_ovfl_stat = VID_B_FIFO_OVFL_STAT; | 542 | port->reg_fifo_ovfl_stat = VID_B_FIFO_OVFL_STAT; |
543 | port->reg_vld_misc = VID_B_VLD_MISC; | 543 | port->reg_vld_misc = VID_B_VLD_MISC; |
544 | port->reg_ts_clk_en = VID_B_TS_CLK_EN; | 544 | port->reg_ts_clk_en = VID_B_TS_CLK_EN; |
545 | port->reg_src_sel = VID_B_SRC_SEL; | 545 | port->reg_src_sel = VID_B_SRC_SEL; |
546 | port->reg_ts_int_msk = VID_B_INT_MSK; | 546 | port->reg_ts_int_msk = VID_B_INT_MSK; |
547 | port->reg_ts_int_stat = VID_B_INT_STAT; | 547 | port->reg_ts_int_stat = VID_B_INT_STAT; |
548 | port->sram_chno = SRAM_CH03; /* VID_B */ | 548 | port->sram_chno = SRAM_CH03; /* VID_B */ |
549 | port->pci_irqmask = 0x02; /* VID_B bit1 */ | 549 | port->pci_irqmask = 0x02; /* VID_B bit1 */ |
550 | break; | 550 | break; |
551 | case 2: | 551 | case 2: |
552 | port->reg_gpcnt = VID_C_GPCNT; | 552 | port->reg_gpcnt = VID_C_GPCNT; |
553 | port->reg_gpcnt_ctl = VID_C_GPCNT_CTL; | 553 | port->reg_gpcnt_ctl = VID_C_GPCNT_CTL; |
554 | port->reg_dma_ctl = VID_C_DMA_CTL; | 554 | port->reg_dma_ctl = VID_C_DMA_CTL; |
555 | port->reg_lngth = VID_C_LNGTH; | 555 | port->reg_lngth = VID_C_LNGTH; |
556 | port->reg_hw_sop_ctrl = VID_C_HW_SOP_CTL; | 556 | port->reg_hw_sop_ctrl = VID_C_HW_SOP_CTL; |
557 | port->reg_gen_ctrl = VID_C_GEN_CTL; | 557 | port->reg_gen_ctrl = VID_C_GEN_CTL; |
558 | port->reg_bd_pkt_status = VID_C_BD_PKT_STATUS; | 558 | port->reg_bd_pkt_status = VID_C_BD_PKT_STATUS; |
559 | port->reg_sop_status = VID_C_SOP_STATUS; | 559 | port->reg_sop_status = VID_C_SOP_STATUS; |
560 | port->reg_fifo_ovfl_stat = VID_C_FIFO_OVFL_STAT; | 560 | port->reg_fifo_ovfl_stat = VID_C_FIFO_OVFL_STAT; |
561 | port->reg_vld_misc = VID_C_VLD_MISC; | 561 | port->reg_vld_misc = VID_C_VLD_MISC; |
562 | port->reg_ts_clk_en = VID_C_TS_CLK_EN; | 562 | port->reg_ts_clk_en = VID_C_TS_CLK_EN; |
563 | port->reg_src_sel = 0; | 563 | port->reg_src_sel = 0; |
564 | port->reg_ts_int_msk = VID_C_INT_MSK; | 564 | port->reg_ts_int_msk = VID_C_INT_MSK; |
565 | port->reg_ts_int_stat = VID_C_INT_STAT; | 565 | port->reg_ts_int_stat = VID_C_INT_STAT; |
566 | port->sram_chno = SRAM_CH06; /* VID_C */ | 566 | port->sram_chno = SRAM_CH06; /* VID_C */ |
567 | port->pci_irqmask = 0x04; /* VID_C bit2 */ | 567 | port->pci_irqmask = 0x04; /* VID_C bit2 */ |
568 | break; | 568 | break; |
569 | default: | 569 | default: |
570 | BUG(); | 570 | BUG(); |
571 | } | 571 | } |
572 | 572 | ||
573 | cx23885_risc_stopper(dev->pci, &port->mpegq.stopper, | 573 | cx23885_risc_stopper(dev->pci, &port->mpegq.stopper, |
574 | port->reg_dma_ctl, port->dma_ctl_val, 0x00); | 574 | port->reg_dma_ctl, port->dma_ctl_val, 0x00); |
575 | 575 | ||
576 | return 0; | 576 | return 0; |
577 | } | 577 | } |
578 | 578 | ||
579 | static void cx23885_dev_checkrevision(struct cx23885_dev *dev) | 579 | static void cx23885_dev_checkrevision(struct cx23885_dev *dev) |
580 | { | 580 | { |
581 | switch (cx_read(RDR_CFG2) & 0xff) { | 581 | switch (cx_read(RDR_CFG2) & 0xff) { |
582 | case 0x00: | 582 | case 0x00: |
583 | /* cx23885 */ | 583 | /* cx23885 */ |
584 | dev->hwrevision = 0xa0; | 584 | dev->hwrevision = 0xa0; |
585 | break; | 585 | break; |
586 | case 0x01: | 586 | case 0x01: |
587 | /* CX23885-12Z */ | 587 | /* CX23885-12Z */ |
588 | dev->hwrevision = 0xa1; | 588 | dev->hwrevision = 0xa1; |
589 | break; | 589 | break; |
590 | case 0x02: | 590 | case 0x02: |
591 | /* CX23885-13Z */ | 591 | /* CX23885-13Z */ |
592 | dev->hwrevision = 0xb0; | 592 | dev->hwrevision = 0xb0; |
593 | break; | 593 | break; |
594 | case 0x03: | 594 | case 0x03: |
595 | /* CX23888-22Z */ | 595 | /* CX23888-22Z */ |
596 | dev->hwrevision = 0xc0; | 596 | dev->hwrevision = 0xc0; |
597 | break; | 597 | break; |
598 | case 0x0e: | 598 | case 0x0e: |
599 | /* CX23887-15Z */ | 599 | /* CX23887-15Z */ |
600 | dev->hwrevision = 0xc0; | 600 | dev->hwrevision = 0xc0; |
601 | case 0x0f: | 601 | case 0x0f: |
602 | /* CX23887-14Z */ | 602 | /* CX23887-14Z */ |
603 | dev->hwrevision = 0xb1; | 603 | dev->hwrevision = 0xb1; |
604 | break; | 604 | break; |
605 | default: | 605 | default: |
606 | printk(KERN_ERR "%s() New hardware revision found 0x%x\n", | 606 | printk(KERN_ERR "%s() New hardware revision found 0x%x\n", |
607 | __FUNCTION__, dev->hwrevision); | 607 | __func__, dev->hwrevision); |
608 | } | 608 | } |
609 | if (dev->hwrevision) | 609 | if (dev->hwrevision) |
610 | printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", | 610 | printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", |
611 | __FUNCTION__, dev->hwrevision); | 611 | __func__, dev->hwrevision); |
612 | else | 612 | else |
613 | printk(KERN_ERR "%s() Hardware revision unknown 0x%x\n", | 613 | printk(KERN_ERR "%s() Hardware revision unknown 0x%x\n", |
614 | __FUNCTION__, dev->hwrevision); | 614 | __func__, dev->hwrevision); |
615 | } | 615 | } |
616 | 616 | ||
617 | static int cx23885_dev_setup(struct cx23885_dev *dev) | 617 | static int cx23885_dev_setup(struct cx23885_dev *dev) |
618 | { | 618 | { |
619 | int i; | 619 | int i; |
620 | 620 | ||
621 | mutex_init(&dev->lock); | 621 | mutex_init(&dev->lock); |
622 | 622 | ||
623 | atomic_inc(&dev->refcount); | 623 | atomic_inc(&dev->refcount); |
624 | 624 | ||
625 | dev->nr = cx23885_devcount++; | 625 | dev->nr = cx23885_devcount++; |
626 | dev->sram_channels = cx23887_sram_channels; | 626 | dev->sram_channels = cx23887_sram_channels; |
627 | sprintf(dev->name, "cx23885[%d]", dev->nr); | 627 | sprintf(dev->name, "cx23885[%d]", dev->nr); |
628 | 628 | ||
629 | mutex_lock(&devlist); | 629 | mutex_lock(&devlist); |
630 | list_add_tail(&dev->devlist, &cx23885_devlist); | 630 | list_add_tail(&dev->devlist, &cx23885_devlist); |
631 | mutex_unlock(&devlist); | 631 | mutex_unlock(&devlist); |
632 | 632 | ||
633 | /* Configure the internal memory */ | 633 | /* Configure the internal memory */ |
634 | if(dev->pci->device == 0x8880) { | 634 | if(dev->pci->device == 0x8880) { |
635 | dev->bridge = CX23885_BRIDGE_887; | 635 | dev->bridge = CX23885_BRIDGE_887; |
636 | /* Apply a sensible clock frequency for the PCIe bridge */ | 636 | /* Apply a sensible clock frequency for the PCIe bridge */ |
637 | dev->clk_freq = 25000000; | 637 | dev->clk_freq = 25000000; |
638 | } else | 638 | } else |
639 | if(dev->pci->device == 0x8852) { | 639 | if(dev->pci->device == 0x8852) { |
640 | dev->bridge = CX23885_BRIDGE_885; | 640 | dev->bridge = CX23885_BRIDGE_885; |
641 | /* Apply a sensible clock frequency for the PCIe bridge */ | 641 | /* Apply a sensible clock frequency for the PCIe bridge */ |
642 | dev->clk_freq = 28000000; | 642 | dev->clk_freq = 28000000; |
643 | } else | 643 | } else |
644 | BUG(); | 644 | BUG(); |
645 | 645 | ||
646 | dprintk(1, "%s() Memory configured for PCIe bridge type %d\n", | 646 | dprintk(1, "%s() Memory configured for PCIe bridge type %d\n", |
647 | __FUNCTION__, dev->bridge); | 647 | __func__, dev->bridge); |
648 | 648 | ||
649 | /* board config */ | 649 | /* board config */ |
650 | dev->board = UNSET; | 650 | dev->board = UNSET; |
651 | if (card[dev->nr] < cx23885_bcount) | 651 | if (card[dev->nr] < cx23885_bcount) |
652 | dev->board = card[dev->nr]; | 652 | dev->board = card[dev->nr]; |
653 | for (i = 0; UNSET == dev->board && i < cx23885_idcount; i++) | 653 | for (i = 0; UNSET == dev->board && i < cx23885_idcount; i++) |
654 | if (dev->pci->subsystem_vendor == cx23885_subids[i].subvendor && | 654 | if (dev->pci->subsystem_vendor == cx23885_subids[i].subvendor && |
655 | dev->pci->subsystem_device == cx23885_subids[i].subdevice) | 655 | dev->pci->subsystem_device == cx23885_subids[i].subdevice) |
656 | dev->board = cx23885_subids[i].card; | 656 | dev->board = cx23885_subids[i].card; |
657 | if (UNSET == dev->board) { | 657 | if (UNSET == dev->board) { |
658 | dev->board = CX23885_BOARD_UNKNOWN; | 658 | dev->board = CX23885_BOARD_UNKNOWN; |
659 | cx23885_card_list(dev); | 659 | cx23885_card_list(dev); |
660 | } | 660 | } |
661 | 661 | ||
662 | /* If the user specific a clk freq override, apply it */ | 662 | /* If the user specific a clk freq override, apply it */ |
663 | if (cx23885_boards[dev->board].clk_freq > 0) | 663 | if (cx23885_boards[dev->board].clk_freq > 0) |
664 | dev->clk_freq = cx23885_boards[dev->board].clk_freq; | 664 | dev->clk_freq = cx23885_boards[dev->board].clk_freq; |
665 | 665 | ||
666 | dev->pci_bus = dev->pci->bus->number; | 666 | dev->pci_bus = dev->pci->bus->number; |
667 | dev->pci_slot = PCI_SLOT(dev->pci->devfn); | 667 | dev->pci_slot = PCI_SLOT(dev->pci->devfn); |
668 | dev->pci_irqmask = 0x001f00; | 668 | dev->pci_irqmask = 0x001f00; |
669 | 669 | ||
670 | /* External Master 1 Bus */ | 670 | /* External Master 1 Bus */ |
671 | dev->i2c_bus[0].nr = 0; | 671 | dev->i2c_bus[0].nr = 0; |
672 | dev->i2c_bus[0].dev = dev; | 672 | dev->i2c_bus[0].dev = dev; |
673 | dev->i2c_bus[0].reg_stat = I2C1_STAT; | 673 | dev->i2c_bus[0].reg_stat = I2C1_STAT; |
674 | dev->i2c_bus[0].reg_ctrl = I2C1_CTRL; | 674 | dev->i2c_bus[0].reg_ctrl = I2C1_CTRL; |
675 | dev->i2c_bus[0].reg_addr = I2C1_ADDR; | 675 | dev->i2c_bus[0].reg_addr = I2C1_ADDR; |
676 | dev->i2c_bus[0].reg_rdata = I2C1_RDATA; | 676 | dev->i2c_bus[0].reg_rdata = I2C1_RDATA; |
677 | dev->i2c_bus[0].reg_wdata = I2C1_WDATA; | 677 | dev->i2c_bus[0].reg_wdata = I2C1_WDATA; |
678 | dev->i2c_bus[0].i2c_period = (0x9d << 24); /* 100kHz */ | 678 | dev->i2c_bus[0].i2c_period = (0x9d << 24); /* 100kHz */ |
679 | 679 | ||
680 | /* External Master 2 Bus */ | 680 | /* External Master 2 Bus */ |
681 | dev->i2c_bus[1].nr = 1; | 681 | dev->i2c_bus[1].nr = 1; |
682 | dev->i2c_bus[1].dev = dev; | 682 | dev->i2c_bus[1].dev = dev; |
683 | dev->i2c_bus[1].reg_stat = I2C2_STAT; | 683 | dev->i2c_bus[1].reg_stat = I2C2_STAT; |
684 | dev->i2c_bus[1].reg_ctrl = I2C2_CTRL; | 684 | dev->i2c_bus[1].reg_ctrl = I2C2_CTRL; |
685 | dev->i2c_bus[1].reg_addr = I2C2_ADDR; | 685 | dev->i2c_bus[1].reg_addr = I2C2_ADDR; |
686 | dev->i2c_bus[1].reg_rdata = I2C2_RDATA; | 686 | dev->i2c_bus[1].reg_rdata = I2C2_RDATA; |
687 | dev->i2c_bus[1].reg_wdata = I2C2_WDATA; | 687 | dev->i2c_bus[1].reg_wdata = I2C2_WDATA; |
688 | dev->i2c_bus[1].i2c_period = (0x9d << 24); /* 100kHz */ | 688 | dev->i2c_bus[1].i2c_period = (0x9d << 24); /* 100kHz */ |
689 | 689 | ||
690 | /* Internal Master 3 Bus */ | 690 | /* Internal Master 3 Bus */ |
691 | dev->i2c_bus[2].nr = 2; | 691 | dev->i2c_bus[2].nr = 2; |
692 | dev->i2c_bus[2].dev = dev; | 692 | dev->i2c_bus[2].dev = dev; |
693 | dev->i2c_bus[2].reg_stat = I2C3_STAT; | 693 | dev->i2c_bus[2].reg_stat = I2C3_STAT; |
694 | dev->i2c_bus[2].reg_ctrl = I2C3_CTRL; | 694 | dev->i2c_bus[2].reg_ctrl = I2C3_CTRL; |
695 | dev->i2c_bus[2].reg_addr = I2C3_ADDR; | 695 | dev->i2c_bus[2].reg_addr = I2C3_ADDR; |
696 | dev->i2c_bus[2].reg_rdata = I2C3_RDATA; | 696 | dev->i2c_bus[2].reg_rdata = I2C3_RDATA; |
697 | dev->i2c_bus[2].reg_wdata = I2C3_WDATA; | 697 | dev->i2c_bus[2].reg_wdata = I2C3_WDATA; |
698 | dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */ | 698 | dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */ |
699 | 699 | ||
700 | if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) | 700 | if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) |
701 | cx23885_init_tsport(dev, &dev->ts1, 1); | 701 | cx23885_init_tsport(dev, &dev->ts1, 1); |
702 | 702 | ||
703 | if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) | 703 | if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) |
704 | cx23885_init_tsport(dev, &dev->ts2, 2); | 704 | cx23885_init_tsport(dev, &dev->ts2, 2); |
705 | 705 | ||
706 | if (get_resources(dev) < 0) { | 706 | if (get_resources(dev) < 0) { |
707 | printk(KERN_ERR "CORE %s No more PCIe resources for " | 707 | printk(KERN_ERR "CORE %s No more PCIe resources for " |
708 | "subsystem: %04x:%04x\n", | 708 | "subsystem: %04x:%04x\n", |
709 | dev->name, dev->pci->subsystem_vendor, | 709 | dev->name, dev->pci->subsystem_vendor, |
710 | dev->pci->subsystem_device); | 710 | dev->pci->subsystem_device); |
711 | 711 | ||
712 | cx23885_devcount--; | 712 | cx23885_devcount--; |
713 | return -ENODEV; | 713 | return -ENODEV; |
714 | } | 714 | } |
715 | 715 | ||
716 | /* PCIe stuff */ | 716 | /* PCIe stuff */ |
717 | dev->lmmio = ioremap(pci_resource_start(dev->pci,0), | 717 | dev->lmmio = ioremap(pci_resource_start(dev->pci,0), |
718 | pci_resource_len(dev->pci,0)); | 718 | pci_resource_len(dev->pci,0)); |
719 | 719 | ||
720 | dev->bmmio = (u8 __iomem *)dev->lmmio; | 720 | dev->bmmio = (u8 __iomem *)dev->lmmio; |
721 | 721 | ||
722 | printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", | 722 | printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", |
723 | dev->name, dev->pci->subsystem_vendor, | 723 | dev->name, dev->pci->subsystem_vendor, |
724 | dev->pci->subsystem_device, cx23885_boards[dev->board].name, | 724 | dev->pci->subsystem_device, cx23885_boards[dev->board].name, |
725 | dev->board, card[dev->nr] == dev->board ? | 725 | dev->board, card[dev->nr] == dev->board ? |
726 | "insmod option" : "autodetected"); | 726 | "insmod option" : "autodetected"); |
727 | 727 | ||
728 | cx23885_pci_quirks(dev); | 728 | cx23885_pci_quirks(dev); |
729 | 729 | ||
730 | /* Assume some sensible defaults */ | 730 | /* Assume some sensible defaults */ |
731 | dev->tuner_type = cx23885_boards[dev->board].tuner_type; | 731 | dev->tuner_type = cx23885_boards[dev->board].tuner_type; |
732 | dev->tuner_addr = cx23885_boards[dev->board].tuner_addr; | 732 | dev->tuner_addr = cx23885_boards[dev->board].tuner_addr; |
733 | dev->radio_type = cx23885_boards[dev->board].radio_type; | 733 | dev->radio_type = cx23885_boards[dev->board].radio_type; |
734 | dev->radio_addr = cx23885_boards[dev->board].radio_addr; | 734 | dev->radio_addr = cx23885_boards[dev->board].radio_addr; |
735 | 735 | ||
736 | dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x\n", | 736 | dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x\n", |
737 | __FUNCTION__, dev->tuner_type, dev->tuner_addr); | 737 | __func__, dev->tuner_type, dev->tuner_addr); |
738 | dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n", | 738 | dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n", |
739 | __FUNCTION__, dev->radio_type, dev->radio_addr); | 739 | __func__, dev->radio_type, dev->radio_addr); |
740 | 740 | ||
741 | /* init hardware */ | 741 | /* init hardware */ |
742 | cx23885_reset(dev); | 742 | cx23885_reset(dev); |
743 | 743 | ||
744 | cx23885_i2c_register(&dev->i2c_bus[0]); | 744 | cx23885_i2c_register(&dev->i2c_bus[0]); |
745 | cx23885_i2c_register(&dev->i2c_bus[1]); | 745 | cx23885_i2c_register(&dev->i2c_bus[1]); |
746 | cx23885_i2c_register(&dev->i2c_bus[2]); | 746 | cx23885_i2c_register(&dev->i2c_bus[2]); |
747 | cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); | 747 | cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); |
748 | cx23885_card_setup(dev); | 748 | cx23885_card_setup(dev); |
749 | cx23885_ir_init(dev); | 749 | cx23885_ir_init(dev); |
750 | 750 | ||
751 | if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { | 751 | if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { |
752 | if (cx23885_video_register(dev) < 0) { | 752 | if (cx23885_video_register(dev) < 0) { |
753 | printk(KERN_ERR "%s() Failed to register analog " | 753 | printk(KERN_ERR "%s() Failed to register analog " |
754 | "video adapters on VID_A\n", __FUNCTION__); | 754 | "video adapters on VID_A\n", __func__); |
755 | } | 755 | } |
756 | } | 756 | } |
757 | 757 | ||
758 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { | 758 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { |
759 | if (cx23885_dvb_register(&dev->ts1) < 0) { | 759 | if (cx23885_dvb_register(&dev->ts1) < 0) { |
760 | printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", | 760 | printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", |
761 | __FUNCTION__); | 761 | __func__); |
762 | } | 762 | } |
763 | } | 763 | } |
764 | 764 | ||
765 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { | 765 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { |
766 | if (cx23885_dvb_register(&dev->ts2) < 0) { | 766 | if (cx23885_dvb_register(&dev->ts2) < 0) { |
767 | printk(KERN_ERR "%s() Failed to register dvb adapters on VID_C\n", | 767 | printk(KERN_ERR "%s() Failed to register dvb adapters on VID_C\n", |
768 | __FUNCTION__); | 768 | __func__); |
769 | } | 769 | } |
770 | } | 770 | } |
771 | 771 | ||
772 | cx23885_dev_checkrevision(dev); | 772 | cx23885_dev_checkrevision(dev); |
773 | 773 | ||
774 | return 0; | 774 | return 0; |
775 | } | 775 | } |
776 | 776 | ||
777 | static void cx23885_dev_unregister(struct cx23885_dev *dev) | 777 | static void cx23885_dev_unregister(struct cx23885_dev *dev) |
778 | { | 778 | { |
779 | release_mem_region(pci_resource_start(dev->pci,0), | 779 | release_mem_region(pci_resource_start(dev->pci,0), |
780 | pci_resource_len(dev->pci,0)); | 780 | pci_resource_len(dev->pci,0)); |
781 | 781 | ||
782 | if (!atomic_dec_and_test(&dev->refcount)) | 782 | if (!atomic_dec_and_test(&dev->refcount)) |
783 | return; | 783 | return; |
784 | 784 | ||
785 | if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) | 785 | if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) |
786 | cx23885_video_unregister(dev); | 786 | cx23885_video_unregister(dev); |
787 | 787 | ||
788 | if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) | 788 | if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) |
789 | cx23885_dvb_unregister(&dev->ts1); | 789 | cx23885_dvb_unregister(&dev->ts1); |
790 | 790 | ||
791 | if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) | 791 | if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) |
792 | cx23885_dvb_unregister(&dev->ts2); | 792 | cx23885_dvb_unregister(&dev->ts2); |
793 | 793 | ||
794 | cx23885_i2c_unregister(&dev->i2c_bus[2]); | 794 | cx23885_i2c_unregister(&dev->i2c_bus[2]); |
795 | cx23885_i2c_unregister(&dev->i2c_bus[1]); | 795 | cx23885_i2c_unregister(&dev->i2c_bus[1]); |
796 | cx23885_i2c_unregister(&dev->i2c_bus[0]); | 796 | cx23885_i2c_unregister(&dev->i2c_bus[0]); |
797 | 797 | ||
798 | iounmap(dev->lmmio); | 798 | iounmap(dev->lmmio); |
799 | } | 799 | } |
800 | 800 | ||
801 | static u32* cx23885_risc_field(u32 *rp, struct scatterlist *sglist, | 801 | static u32* cx23885_risc_field(u32 *rp, struct scatterlist *sglist, |
802 | unsigned int offset, u32 sync_line, | 802 | unsigned int offset, u32 sync_line, |
803 | unsigned int bpl, unsigned int padding, | 803 | unsigned int bpl, unsigned int padding, |
804 | unsigned int lines) | 804 | unsigned int lines) |
805 | { | 805 | { |
806 | struct scatterlist *sg; | 806 | struct scatterlist *sg; |
807 | unsigned int line, todo; | 807 | unsigned int line, todo; |
808 | 808 | ||
809 | /* sync instruction */ | 809 | /* sync instruction */ |
810 | if (sync_line != NO_SYNC_LINE) | 810 | if (sync_line != NO_SYNC_LINE) |
811 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | 811 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); |
812 | 812 | ||
813 | /* scan lines */ | 813 | /* scan lines */ |
814 | sg = sglist; | 814 | sg = sglist; |
815 | for (line = 0; line < lines; line++) { | 815 | for (line = 0; line < lines; line++) { |
816 | while (offset && offset >= sg_dma_len(sg)) { | 816 | while (offset && offset >= sg_dma_len(sg)) { |
817 | offset -= sg_dma_len(sg); | 817 | offset -= sg_dma_len(sg); |
818 | sg++; | 818 | sg++; |
819 | } | 819 | } |
820 | if (bpl <= sg_dma_len(sg)-offset) { | 820 | if (bpl <= sg_dma_len(sg)-offset) { |
821 | /* fits into current chunk */ | 821 | /* fits into current chunk */ |
822 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); | 822 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); |
823 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); | 823 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); |
824 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ | 824 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ |
825 | offset+=bpl; | 825 | offset+=bpl; |
826 | } else { | 826 | } else { |
827 | /* scanline needs to be split */ | 827 | /* scanline needs to be split */ |
828 | todo = bpl; | 828 | todo = bpl; |
829 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL| | 829 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL| |
830 | (sg_dma_len(sg)-offset)); | 830 | (sg_dma_len(sg)-offset)); |
831 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); | 831 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); |
832 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ | 832 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ |
833 | todo -= (sg_dma_len(sg)-offset); | 833 | todo -= (sg_dma_len(sg)-offset); |
834 | offset = 0; | 834 | offset = 0; |
835 | sg++; | 835 | sg++; |
836 | while (todo > sg_dma_len(sg)) { | 836 | while (todo > sg_dma_len(sg)) { |
837 | *(rp++)=cpu_to_le32(RISC_WRITE| | 837 | *(rp++)=cpu_to_le32(RISC_WRITE| |
838 | sg_dma_len(sg)); | 838 | sg_dma_len(sg)); |
839 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); | 839 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); |
840 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ | 840 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ |
841 | todo -= sg_dma_len(sg); | 841 | todo -= sg_dma_len(sg); |
842 | sg++; | 842 | sg++; |
843 | } | 843 | } |
844 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); | 844 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); |
845 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); | 845 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); |
846 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ | 846 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ |
847 | offset += todo; | 847 | offset += todo; |
848 | } | 848 | } |
849 | offset += padding; | 849 | offset += padding; |
850 | } | 850 | } |
851 | 851 | ||
852 | return rp; | 852 | return rp; |
853 | } | 853 | } |
854 | 854 | ||
855 | int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | 855 | int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, |
856 | struct scatterlist *sglist, unsigned int top_offset, | 856 | struct scatterlist *sglist, unsigned int top_offset, |
857 | unsigned int bottom_offset, unsigned int bpl, | 857 | unsigned int bottom_offset, unsigned int bpl, |
858 | unsigned int padding, unsigned int lines) | 858 | unsigned int padding, unsigned int lines) |
859 | { | 859 | { |
860 | u32 instructions, fields; | 860 | u32 instructions, fields; |
861 | u32 *rp; | 861 | u32 *rp; |
862 | int rc; | 862 | int rc; |
863 | 863 | ||
864 | fields = 0; | 864 | fields = 0; |
865 | if (UNSET != top_offset) | 865 | if (UNSET != top_offset) |
866 | fields++; | 866 | fields++; |
867 | if (UNSET != bottom_offset) | 867 | if (UNSET != bottom_offset) |
868 | fields++; | 868 | fields++; |
869 | 869 | ||
870 | /* estimate risc mem: worst case is one write per page border + | 870 | /* estimate risc mem: worst case is one write per page border + |
871 | one write per scan line + syncs + jump (all 2 dwords). Padding | 871 | one write per scan line + syncs + jump (all 2 dwords). Padding |
872 | can cause next bpl to start close to a page border. First DMA | 872 | can cause next bpl to start close to a page border. First DMA |
873 | region may be smaller than PAGE_SIZE */ | 873 | region may be smaller than PAGE_SIZE */ |
874 | /* write and jump need and extra dword */ | 874 | /* write and jump need and extra dword */ |
875 | instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines); | 875 | instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines); |
876 | instructions += 2; | 876 | instructions += 2; |
877 | if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0) | 877 | if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0) |
878 | return rc; | 878 | return rc; |
879 | 879 | ||
880 | /* write risc instructions */ | 880 | /* write risc instructions */ |
881 | rp = risc->cpu; | 881 | rp = risc->cpu; |
882 | if (UNSET != top_offset) | 882 | if (UNSET != top_offset) |
883 | rp = cx23885_risc_field(rp, sglist, top_offset, 0, | 883 | rp = cx23885_risc_field(rp, sglist, top_offset, 0, |
884 | bpl, padding, lines); | 884 | bpl, padding, lines); |
885 | if (UNSET != bottom_offset) | 885 | if (UNSET != bottom_offset) |
886 | rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200, | 886 | rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200, |
887 | bpl, padding, lines); | 887 | bpl, padding, lines); |
888 | 888 | ||
889 | /* save pointer to jmp instruction address */ | 889 | /* save pointer to jmp instruction address */ |
890 | risc->jmp = rp; | 890 | risc->jmp = rp; |
891 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); | 891 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); |
892 | return 0; | 892 | return 0; |
893 | } | 893 | } |
894 | 894 | ||
895 | static int cx23885_risc_databuffer(struct pci_dev *pci, | 895 | static int cx23885_risc_databuffer(struct pci_dev *pci, |
896 | struct btcx_riscmem *risc, | 896 | struct btcx_riscmem *risc, |
897 | struct scatterlist *sglist, | 897 | struct scatterlist *sglist, |
898 | unsigned int bpl, | 898 | unsigned int bpl, |
899 | unsigned int lines) | 899 | unsigned int lines) |
900 | { | 900 | { |
901 | u32 instructions; | 901 | u32 instructions; |
902 | u32 *rp; | 902 | u32 *rp; |
903 | int rc; | 903 | int rc; |
904 | 904 | ||
905 | /* estimate risc mem: worst case is one write per page border + | 905 | /* estimate risc mem: worst case is one write per page border + |
906 | one write per scan line + syncs + jump (all 2 dwords). Here | 906 | one write per scan line + syncs + jump (all 2 dwords). Here |
907 | there is no padding and no sync. First DMA region may be smaller | 907 | there is no padding and no sync. First DMA region may be smaller |
908 | than PAGE_SIZE */ | 908 | than PAGE_SIZE */ |
909 | /* Jump and write need an extra dword */ | 909 | /* Jump and write need an extra dword */ |
910 | instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; | 910 | instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; |
911 | instructions += 1; | 911 | instructions += 1; |
912 | 912 | ||
913 | if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0) | 913 | if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0) |
914 | return rc; | 914 | return rc; |
915 | 915 | ||
916 | /* write risc instructions */ | 916 | /* write risc instructions */ |
917 | rp = risc->cpu; | 917 | rp = risc->cpu; |
918 | rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines); | 918 | rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines); |
919 | 919 | ||
920 | /* save pointer to jmp instruction address */ | 920 | /* save pointer to jmp instruction address */ |
921 | risc->jmp = rp; | 921 | risc->jmp = rp; |
922 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); | 922 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); |
923 | return 0; | 923 | return 0; |
924 | } | 924 | } |
925 | 925 | ||
926 | int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | 926 | int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, |
927 | u32 reg, u32 mask, u32 value) | 927 | u32 reg, u32 mask, u32 value) |
928 | { | 928 | { |
929 | u32 *rp; | 929 | u32 *rp; |
930 | int rc; | 930 | int rc; |
931 | 931 | ||
932 | if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0) | 932 | if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0) |
933 | return rc; | 933 | return rc; |
934 | 934 | ||
935 | /* write risc instructions */ | 935 | /* write risc instructions */ |
936 | rp = risc->cpu; | 936 | rp = risc->cpu; |
937 | *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2); | 937 | *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2); |
938 | *(rp++) = cpu_to_le32(reg); | 938 | *(rp++) = cpu_to_le32(reg); |
939 | *(rp++) = cpu_to_le32(value); | 939 | *(rp++) = cpu_to_le32(value); |
940 | *(rp++) = cpu_to_le32(mask); | 940 | *(rp++) = cpu_to_le32(mask); |
941 | *(rp++) = cpu_to_le32(RISC_JUMP); | 941 | *(rp++) = cpu_to_le32(RISC_JUMP); |
942 | *(rp++) = cpu_to_le32(risc->dma); | 942 | *(rp++) = cpu_to_le32(risc->dma); |
943 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 943 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
944 | return 0; | 944 | return 0; |
945 | } | 945 | } |
946 | 946 | ||
947 | void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf) | 947 | void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf) |
948 | { | 948 | { |
949 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | 949 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); |
950 | 950 | ||
951 | BUG_ON(in_interrupt()); | 951 | BUG_ON(in_interrupt()); |
952 | videobuf_waiton(&buf->vb, 0, 0); | 952 | videobuf_waiton(&buf->vb, 0, 0); |
953 | videobuf_dma_unmap(q, dma); | 953 | videobuf_dma_unmap(q, dma); |
954 | videobuf_dma_free(dma); | 954 | videobuf_dma_free(dma); |
955 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); | 955 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); |
956 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 956 | buf->vb.state = VIDEOBUF_NEEDS_INIT; |
957 | } | 957 | } |
958 | 958 | ||
959 | static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) | 959 | static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) |
960 | { | 960 | { |
961 | struct cx23885_dev *dev = port->dev; | 961 | struct cx23885_dev *dev = port->dev; |
962 | 962 | ||
963 | dprintk(1, "%s() Register Dump\n", __FUNCTION__); | 963 | dprintk(1, "%s() Register Dump\n", __func__); |
964 | dprintk(1, "%s() DEV_CNTRL2 0x%08X\n", __FUNCTION__, | 964 | dprintk(1, "%s() DEV_CNTRL2 0x%08X\n", __func__, |
965 | cx_read(DEV_CNTRL2)); | 965 | cx_read(DEV_CNTRL2)); |
966 | dprintk(1, "%s() PCI_INT_MSK 0x%08X\n", __FUNCTION__, | 966 | dprintk(1, "%s() PCI_INT_MSK 0x%08X\n", __func__, |
967 | cx_read(PCI_INT_MSK)); | 967 | cx_read(PCI_INT_MSK)); |
968 | dprintk(1, "%s() AUD_INT_INT_MSK 0x%08X\n", __FUNCTION__, | 968 | dprintk(1, "%s() AUD_INT_INT_MSK 0x%08X\n", __func__, |
969 | cx_read(AUDIO_INT_INT_MSK)); | 969 | cx_read(AUDIO_INT_INT_MSK)); |
970 | dprintk(1, "%s() AUD_INT_DMA_CTL 0x%08X\n", __FUNCTION__, | 970 | dprintk(1, "%s() AUD_INT_DMA_CTL 0x%08X\n", __func__, |
971 | cx_read(AUD_INT_DMA_CTL)); | 971 | cx_read(AUD_INT_DMA_CTL)); |
972 | dprintk(1, "%s() AUD_EXT_INT_MSK 0x%08X\n", __FUNCTION__, | 972 | dprintk(1, "%s() AUD_EXT_INT_MSK 0x%08X\n", __func__, |
973 | cx_read(AUDIO_EXT_INT_MSK)); | 973 | cx_read(AUDIO_EXT_INT_MSK)); |
974 | dprintk(1, "%s() AUD_EXT_DMA_CTL 0x%08X\n", __FUNCTION__, | 974 | dprintk(1, "%s() AUD_EXT_DMA_CTL 0x%08X\n", __func__, |
975 | cx_read(AUD_EXT_DMA_CTL)); | 975 | cx_read(AUD_EXT_DMA_CTL)); |
976 | dprintk(1, "%s() PAD_CTRL 0x%08X\n", __FUNCTION__, | 976 | dprintk(1, "%s() PAD_CTRL 0x%08X\n", __func__, |
977 | cx_read(PAD_CTRL)); | 977 | cx_read(PAD_CTRL)); |
978 | dprintk(1, "%s() ALT_PIN_OUT_SEL 0x%08X\n", __FUNCTION__, | 978 | dprintk(1, "%s() ALT_PIN_OUT_SEL 0x%08X\n", __func__, |
979 | cx_read(ALT_PIN_OUT_SEL)); | 979 | cx_read(ALT_PIN_OUT_SEL)); |
980 | dprintk(1, "%s() GPIO2 0x%08X\n", __FUNCTION__, | 980 | dprintk(1, "%s() GPIO2 0x%08X\n", __func__, |
981 | cx_read(GPIO2)); | 981 | cx_read(GPIO2)); |
982 | dprintk(1, "%s() gpcnt(0x%08X) 0x%08X\n", __FUNCTION__, | 982 | dprintk(1, "%s() gpcnt(0x%08X) 0x%08X\n", __func__, |
983 | port->reg_gpcnt, cx_read(port->reg_gpcnt)); | 983 | port->reg_gpcnt, cx_read(port->reg_gpcnt)); |
984 | dprintk(1, "%s() gpcnt_ctl(0x%08X) 0x%08x\n", __FUNCTION__, | 984 | dprintk(1, "%s() gpcnt_ctl(0x%08X) 0x%08x\n", __func__, |
985 | port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl)); | 985 | port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl)); |
986 | dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __FUNCTION__, | 986 | dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __func__, |
987 | port->reg_dma_ctl, cx_read(port->reg_dma_ctl)); | 987 | port->reg_dma_ctl, cx_read(port->reg_dma_ctl)); |
988 | dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __FUNCTION__, | 988 | dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__, |
989 | port->reg_src_sel, cx_read(port->reg_src_sel)); | 989 | port->reg_src_sel, cx_read(port->reg_src_sel)); |
990 | dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __FUNCTION__, | 990 | dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __func__, |
991 | port->reg_lngth, cx_read(port->reg_lngth)); | 991 | port->reg_lngth, cx_read(port->reg_lngth)); |
992 | dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __FUNCTION__, | 992 | dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __func__, |
993 | port->reg_hw_sop_ctrl, cx_read(port->reg_hw_sop_ctrl)); | 993 | port->reg_hw_sop_ctrl, cx_read(port->reg_hw_sop_ctrl)); |
994 | dprintk(1, "%s() gen_ctrl(0x%08X) 0x%08x\n", __FUNCTION__, | 994 | dprintk(1, "%s() gen_ctrl(0x%08X) 0x%08x\n", __func__, |
995 | port->reg_gen_ctrl, cx_read(port->reg_gen_ctrl)); | 995 | port->reg_gen_ctrl, cx_read(port->reg_gen_ctrl)); |
996 | dprintk(1, "%s() bd_pkt_status(0x%08X) 0x%08x\n", __FUNCTION__, | 996 | dprintk(1, "%s() bd_pkt_status(0x%08X) 0x%08x\n", __func__, |
997 | port->reg_bd_pkt_status, cx_read(port->reg_bd_pkt_status)); | 997 | port->reg_bd_pkt_status, cx_read(port->reg_bd_pkt_status)); |
998 | dprintk(1, "%s() sop_status(0x%08X) 0x%08x\n", __FUNCTION__, | 998 | dprintk(1, "%s() sop_status(0x%08X) 0x%08x\n", __func__, |
999 | port->reg_sop_status, cx_read(port->reg_sop_status)); | 999 | port->reg_sop_status, cx_read(port->reg_sop_status)); |
1000 | dprintk(1, "%s() fifo_ovfl_stat(0x%08X) 0x%08x\n", __FUNCTION__, | 1000 | dprintk(1, "%s() fifo_ovfl_stat(0x%08X) 0x%08x\n", __func__, |
1001 | port->reg_fifo_ovfl_stat, cx_read(port->reg_fifo_ovfl_stat)); | 1001 | port->reg_fifo_ovfl_stat, cx_read(port->reg_fifo_ovfl_stat)); |
1002 | dprintk(1, "%s() vld_misc(0x%08X) 0x%08x\n", __FUNCTION__, | 1002 | dprintk(1, "%s() vld_misc(0x%08X) 0x%08x\n", __func__, |
1003 | port->reg_vld_misc, cx_read(port->reg_vld_misc)); | 1003 | port->reg_vld_misc, cx_read(port->reg_vld_misc)); |
1004 | dprintk(1, "%s() ts_clk_en(0x%08X) 0x%08x\n", __FUNCTION__, | 1004 | dprintk(1, "%s() ts_clk_en(0x%08X) 0x%08x\n", __func__, |
1005 | port->reg_ts_clk_en, cx_read(port->reg_ts_clk_en)); | 1005 | port->reg_ts_clk_en, cx_read(port->reg_ts_clk_en)); |
1006 | dprintk(1, "%s() ts_int_msk(0x%08X) 0x%08x\n", __FUNCTION__, | 1006 | dprintk(1, "%s() ts_int_msk(0x%08X) 0x%08x\n", __func__, |
1007 | port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk)); | 1007 | port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk)); |
1008 | } | 1008 | } |
1009 | 1009 | ||
1010 | static int cx23885_start_dma(struct cx23885_tsport *port, | 1010 | static int cx23885_start_dma(struct cx23885_tsport *port, |
1011 | struct cx23885_dmaqueue *q, | 1011 | struct cx23885_dmaqueue *q, |
1012 | struct cx23885_buffer *buf) | 1012 | struct cx23885_buffer *buf) |
1013 | { | 1013 | { |
1014 | struct cx23885_dev *dev = port->dev; | 1014 | struct cx23885_dev *dev = port->dev; |
1015 | 1015 | ||
1016 | dprintk(1, "%s() w: %d, h: %d, f: %d\n", __FUNCTION__, | 1016 | dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__, |
1017 | buf->vb.width, buf->vb.height, buf->vb.field); | 1017 | buf->vb.width, buf->vb.height, buf->vb.field); |
1018 | 1018 | ||
1019 | /* setup fifo + format */ | 1019 | /* setup fifo + format */ |
1020 | cx23885_sram_channel_setup(dev, | 1020 | cx23885_sram_channel_setup(dev, |
1021 | &dev->sram_channels[ port->sram_chno ], | 1021 | &dev->sram_channels[ port->sram_chno ], |
1022 | port->ts_packet_size, buf->risc.dma); | 1022 | port->ts_packet_size, buf->risc.dma); |
1023 | if(debug > 5) { | 1023 | if(debug > 5) { |
1024 | cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ] ); | 1024 | cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ] ); |
1025 | cx23885_risc_disasm(port, &buf->risc); | 1025 | cx23885_risc_disasm(port, &buf->risc); |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | /* write TS length to chip */ | 1028 | /* write TS length to chip */ |
1029 | cx_write(port->reg_lngth, buf->vb.width); | 1029 | cx_write(port->reg_lngth, buf->vb.width); |
1030 | 1030 | ||
1031 | if ( (!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && | 1031 | if ( (!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && |
1032 | (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) ) { | 1032 | (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) ) { |
1033 | printk( "%s() Failed. Unsupported value in .portb/c (0x%08x)/(0x%08x)\n", | 1033 | printk( "%s() Failed. Unsupported value in .portb/c (0x%08x)/(0x%08x)\n", |
1034 | __FUNCTION__, | 1034 | __func__, |
1035 | cx23885_boards[dev->board].portb, | 1035 | cx23885_boards[dev->board].portb, |
1036 | cx23885_boards[dev->board].portc ); | 1036 | cx23885_boards[dev->board].portc ); |
1037 | return -EINVAL; | 1037 | return -EINVAL; |
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | udelay(100); | 1040 | udelay(100); |
1041 | 1041 | ||
1042 | /* If the port supports SRC SELECT, configure it */ | 1042 | /* If the port supports SRC SELECT, configure it */ |
1043 | if(port->reg_src_sel) | 1043 | if(port->reg_src_sel) |
1044 | cx_write(port->reg_src_sel, port->src_sel_val); | 1044 | cx_write(port->reg_src_sel, port->src_sel_val); |
1045 | 1045 | ||
1046 | cx_write(port->reg_hw_sop_ctrl, 0x47 << 16 | 188 << 4); | 1046 | cx_write(port->reg_hw_sop_ctrl, 0x47 << 16 | 188 << 4); |
1047 | cx_write(port->reg_ts_clk_en, port->ts_clk_en_val); | 1047 | cx_write(port->reg_ts_clk_en, port->ts_clk_en_val); |
1048 | cx_write(port->reg_vld_misc, 0x00); | 1048 | cx_write(port->reg_vld_misc, 0x00); |
1049 | cx_write(port->reg_gen_ctrl, port->gen_ctrl_val); | 1049 | cx_write(port->reg_gen_ctrl, port->gen_ctrl_val); |
1050 | udelay(100); | 1050 | udelay(100); |
1051 | 1051 | ||
1052 | // NOTE: this is 2 (reserved) for portb, does it matter? | 1052 | // NOTE: this is 2 (reserved) for portb, does it matter? |
1053 | /* reset counter to zero */ | 1053 | /* reset counter to zero */ |
1054 | cx_write(port->reg_gpcnt_ctl, 3); | 1054 | cx_write(port->reg_gpcnt_ctl, 3); |
1055 | q->count = 1; | 1055 | q->count = 1; |
1056 | 1056 | ||
1057 | switch(dev->bridge) { | 1057 | switch(dev->bridge) { |
1058 | case CX23885_BRIDGE_885: | 1058 | case CX23885_BRIDGE_885: |
1059 | case CX23885_BRIDGE_887: | 1059 | case CX23885_BRIDGE_887: |
1060 | /* enable irqs */ | 1060 | /* enable irqs */ |
1061 | dprintk(1, "%s() enabling TS int's and DMA\n", __FUNCTION__ ); | 1061 | dprintk(1, "%s() enabling TS int's and DMA\n", __func__ ); |
1062 | cx_set(port->reg_ts_int_msk, port->ts_int_msk_val); | 1062 | cx_set(port->reg_ts_int_msk, port->ts_int_msk_val); |
1063 | cx_set(port->reg_dma_ctl, port->dma_ctl_val); | 1063 | cx_set(port->reg_dma_ctl, port->dma_ctl_val); |
1064 | cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask); | 1064 | cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask); |
1065 | break; | 1065 | break; |
1066 | default: | 1066 | default: |
1067 | BUG(); | 1067 | BUG(); |
1068 | } | 1068 | } |
1069 | 1069 | ||
1070 | cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */ | 1070 | cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */ |
1071 | 1071 | ||
1072 | if (debug > 4) | 1072 | if (debug > 4) |
1073 | cx23885_tsport_reg_dump(port); | 1073 | cx23885_tsport_reg_dump(port); |
1074 | 1074 | ||
1075 | return 0; | 1075 | return 0; |
1076 | } | 1076 | } |
1077 | 1077 | ||
1078 | static int cx23885_stop_dma(struct cx23885_tsport *port) | 1078 | static int cx23885_stop_dma(struct cx23885_tsport *port) |
1079 | { | 1079 | { |
1080 | struct cx23885_dev *dev = port->dev; | 1080 | struct cx23885_dev *dev = port->dev; |
1081 | dprintk(1, "%s()\n", __FUNCTION__); | 1081 | dprintk(1, "%s()\n", __func__); |
1082 | 1082 | ||
1083 | /* Stop interrupts and DMA */ | 1083 | /* Stop interrupts and DMA */ |
1084 | cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val); | 1084 | cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val); |
1085 | cx_clear(port->reg_dma_ctl, port->dma_ctl_val); | 1085 | cx_clear(port->reg_dma_ctl, port->dma_ctl_val); |
1086 | 1086 | ||
1087 | return 0; | 1087 | return 0; |
1088 | } | 1088 | } |
1089 | 1089 | ||
1090 | int cx23885_restart_queue(struct cx23885_tsport *port, | 1090 | int cx23885_restart_queue(struct cx23885_tsport *port, |
1091 | struct cx23885_dmaqueue *q) | 1091 | struct cx23885_dmaqueue *q) |
1092 | { | 1092 | { |
1093 | struct cx23885_dev *dev = port->dev; | 1093 | struct cx23885_dev *dev = port->dev; |
1094 | struct cx23885_buffer *buf; | 1094 | struct cx23885_buffer *buf; |
1095 | 1095 | ||
1096 | dprintk(5, "%s()\n", __FUNCTION__); | 1096 | dprintk(5, "%s()\n", __func__); |
1097 | if (list_empty(&q->active)) | 1097 | if (list_empty(&q->active)) |
1098 | { | 1098 | { |
1099 | struct cx23885_buffer *prev; | 1099 | struct cx23885_buffer *prev; |
1100 | prev = NULL; | 1100 | prev = NULL; |
1101 | 1101 | ||
1102 | dprintk(5, "%s() queue is empty\n", __FUNCTION__); | 1102 | dprintk(5, "%s() queue is empty\n", __func__); |
1103 | 1103 | ||
1104 | for (;;) { | 1104 | for (;;) { |
1105 | if (list_empty(&q->queued)) | 1105 | if (list_empty(&q->queued)) |
1106 | return 0; | 1106 | return 0; |
1107 | buf = list_entry(q->queued.next, struct cx23885_buffer, | 1107 | buf = list_entry(q->queued.next, struct cx23885_buffer, |
1108 | vb.queue); | 1108 | vb.queue); |
1109 | if (NULL == prev) { | 1109 | if (NULL == prev) { |
1110 | list_del(&buf->vb.queue); | 1110 | list_del(&buf->vb.queue); |
1111 | list_add_tail(&buf->vb.queue, &q->active); | 1111 | list_add_tail(&buf->vb.queue, &q->active); |
1112 | cx23885_start_dma(port, q, buf); | 1112 | cx23885_start_dma(port, q, buf); |
1113 | buf->vb.state = VIDEOBUF_ACTIVE; | 1113 | buf->vb.state = VIDEOBUF_ACTIVE; |
1114 | buf->count = q->count++; | 1114 | buf->count = q->count++; |
1115 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | 1115 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); |
1116 | dprintk(5, "[%p/%d] restart_queue - first active\n", | 1116 | dprintk(5, "[%p/%d] restart_queue - first active\n", |
1117 | buf, buf->vb.i); | 1117 | buf, buf->vb.i); |
1118 | 1118 | ||
1119 | } else if (prev->vb.width == buf->vb.width && | 1119 | } else if (prev->vb.width == buf->vb.width && |
1120 | prev->vb.height == buf->vb.height && | 1120 | prev->vb.height == buf->vb.height && |
1121 | prev->fmt == buf->fmt) { | 1121 | prev->fmt == buf->fmt) { |
1122 | list_del(&buf->vb.queue); | 1122 | list_del(&buf->vb.queue); |
1123 | list_add_tail(&buf->vb.queue, &q->active); | 1123 | list_add_tail(&buf->vb.queue, &q->active); |
1124 | buf->vb.state = VIDEOBUF_ACTIVE; | 1124 | buf->vb.state = VIDEOBUF_ACTIVE; |
1125 | buf->count = q->count++; | 1125 | buf->count = q->count++; |
1126 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 1126 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
1127 | prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ | 1127 | prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ |
1128 | dprintk(5,"[%p/%d] restart_queue - move to active\n", | 1128 | dprintk(5,"[%p/%d] restart_queue - move to active\n", |
1129 | buf, buf->vb.i); | 1129 | buf, buf->vb.i); |
1130 | } else { | 1130 | } else { |
1131 | return 0; | 1131 | return 0; |
1132 | } | 1132 | } |
1133 | prev = buf; | 1133 | prev = buf; |
1134 | } | 1134 | } |
1135 | return 0; | 1135 | return 0; |
1136 | } | 1136 | } |
1137 | 1137 | ||
1138 | buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue); | 1138 | buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue); |
1139 | dprintk(2, "restart_queue [%p/%d]: restart dma\n", | 1139 | dprintk(2, "restart_queue [%p/%d]: restart dma\n", |
1140 | buf, buf->vb.i); | 1140 | buf, buf->vb.i); |
1141 | cx23885_start_dma(port, q, buf); | 1141 | cx23885_start_dma(port, q, buf); |
1142 | list_for_each_entry(buf, &q->active, vb.queue) | 1142 | list_for_each_entry(buf, &q->active, vb.queue) |
1143 | buf->count = q->count++; | 1143 | buf->count = q->count++; |
1144 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); | 1144 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); |
1145 | return 0; | 1145 | return 0; |
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | /* ------------------------------------------------------------------ */ | 1148 | /* ------------------------------------------------------------------ */ |
1149 | 1149 | ||
1150 | int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, | 1150 | int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, |
1151 | struct cx23885_buffer *buf, enum v4l2_field field) | 1151 | struct cx23885_buffer *buf, enum v4l2_field field) |
1152 | { | 1152 | { |
1153 | struct cx23885_dev *dev = port->dev; | 1153 | struct cx23885_dev *dev = port->dev; |
1154 | int size = port->ts_packet_size * port->ts_packet_count; | 1154 | int size = port->ts_packet_size * port->ts_packet_count; |
1155 | int rc; | 1155 | int rc; |
1156 | 1156 | ||
1157 | dprintk(1, "%s: %p\n", __FUNCTION__, buf); | 1157 | dprintk(1, "%s: %p\n", __func__, buf); |
1158 | if (0 != buf->vb.baddr && buf->vb.bsize < size) | 1158 | if (0 != buf->vb.baddr && buf->vb.bsize < size) |
1159 | return -EINVAL; | 1159 | return -EINVAL; |
1160 | 1160 | ||
1161 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 1161 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
1162 | buf->vb.width = port->ts_packet_size; | 1162 | buf->vb.width = port->ts_packet_size; |
1163 | buf->vb.height = port->ts_packet_count; | 1163 | buf->vb.height = port->ts_packet_count; |
1164 | buf->vb.size = size; | 1164 | buf->vb.size = size; |
1165 | buf->vb.field = field /*V4L2_FIELD_TOP*/; | 1165 | buf->vb.field = field /*V4L2_FIELD_TOP*/; |
1166 | 1166 | ||
1167 | if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) | 1167 | if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) |
1168 | goto fail; | 1168 | goto fail; |
1169 | cx23885_risc_databuffer(dev->pci, &buf->risc, | 1169 | cx23885_risc_databuffer(dev->pci, &buf->risc, |
1170 | videobuf_to_dma(&buf->vb)->sglist, | 1170 | videobuf_to_dma(&buf->vb)->sglist, |
1171 | buf->vb.width, buf->vb.height); | 1171 | buf->vb.width, buf->vb.height); |
1172 | } | 1172 | } |
1173 | buf->vb.state = VIDEOBUF_PREPARED; | 1173 | buf->vb.state = VIDEOBUF_PREPARED; |
1174 | return 0; | 1174 | return 0; |
1175 | 1175 | ||
1176 | fail: | 1176 | fail: |
1177 | cx23885_free_buffer(q, buf); | 1177 | cx23885_free_buffer(q, buf); |
1178 | return rc; | 1178 | return rc; |
1179 | } | 1179 | } |
1180 | 1180 | ||
1181 | void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) | 1181 | void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) |
1182 | { | 1182 | { |
1183 | struct cx23885_buffer *prev; | 1183 | struct cx23885_buffer *prev; |
1184 | struct cx23885_dev *dev = port->dev; | 1184 | struct cx23885_dev *dev = port->dev; |
1185 | struct cx23885_dmaqueue *cx88q = &port->mpegq; | 1185 | struct cx23885_dmaqueue *cx88q = &port->mpegq; |
1186 | 1186 | ||
1187 | /* add jump to stopper */ | 1187 | /* add jump to stopper */ |
1188 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | 1188 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); |
1189 | buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); | 1189 | buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); |
1190 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ | 1190 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ |
1191 | 1191 | ||
1192 | if (list_empty(&cx88q->active)) { | 1192 | if (list_empty(&cx88q->active)) { |
1193 | dprintk( 1, "queue is empty - first active\n" ); | 1193 | dprintk( 1, "queue is empty - first active\n" ); |
1194 | list_add_tail(&buf->vb.queue, &cx88q->active); | 1194 | list_add_tail(&buf->vb.queue, &cx88q->active); |
1195 | cx23885_start_dma(port, cx88q, buf); | 1195 | cx23885_start_dma(port, cx88q, buf); |
1196 | buf->vb.state = VIDEOBUF_ACTIVE; | 1196 | buf->vb.state = VIDEOBUF_ACTIVE; |
1197 | buf->count = cx88q->count++; | 1197 | buf->count = cx88q->count++; |
1198 | mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT); | 1198 | mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT); |
1199 | dprintk(1, "[%p/%d] %s - first active\n", | 1199 | dprintk(1, "[%p/%d] %s - first active\n", |
1200 | buf, buf->vb.i, __FUNCTION__); | 1200 | buf, buf->vb.i, __func__); |
1201 | } else { | 1201 | } else { |
1202 | dprintk( 1, "queue is not empty - append to active\n" ); | 1202 | dprintk( 1, "queue is not empty - append to active\n" ); |
1203 | prev = list_entry(cx88q->active.prev, struct cx23885_buffer, | 1203 | prev = list_entry(cx88q->active.prev, struct cx23885_buffer, |
1204 | vb.queue); | 1204 | vb.queue); |
1205 | list_add_tail(&buf->vb.queue, &cx88q->active); | 1205 | list_add_tail(&buf->vb.queue, &cx88q->active); |
1206 | buf->vb.state = VIDEOBUF_ACTIVE; | 1206 | buf->vb.state = VIDEOBUF_ACTIVE; |
1207 | buf->count = cx88q->count++; | 1207 | buf->count = cx88q->count++; |
1208 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 1208 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
1209 | prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ | 1209 | prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ |
1210 | dprintk( 1, "[%p/%d] %s - append to active\n", | 1210 | dprintk( 1, "[%p/%d] %s - append to active\n", |
1211 | buf, buf->vb.i, __FUNCTION__); | 1211 | buf, buf->vb.i, __func__); |
1212 | } | 1212 | } |
1213 | } | 1213 | } |
1214 | 1214 | ||
1215 | /* ----------------------------------------------------------- */ | 1215 | /* ----------------------------------------------------------- */ |
1216 | 1216 | ||
1217 | static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, | 1217 | static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, |
1218 | int restart) | 1218 | int restart) |
1219 | { | 1219 | { |
1220 | struct cx23885_dev *dev = port->dev; | 1220 | struct cx23885_dev *dev = port->dev; |
1221 | struct cx23885_dmaqueue *q = &port->mpegq; | 1221 | struct cx23885_dmaqueue *q = &port->mpegq; |
1222 | struct cx23885_buffer *buf; | 1222 | struct cx23885_buffer *buf; |
1223 | unsigned long flags; | 1223 | unsigned long flags; |
1224 | 1224 | ||
1225 | spin_lock_irqsave(&port->slock, flags); | 1225 | spin_lock_irqsave(&port->slock, flags); |
1226 | while (!list_empty(&q->active)) { | 1226 | while (!list_empty(&q->active)) { |
1227 | buf = list_entry(q->active.next, struct cx23885_buffer, | 1227 | buf = list_entry(q->active.next, struct cx23885_buffer, |
1228 | vb.queue); | 1228 | vb.queue); |
1229 | list_del(&buf->vb.queue); | 1229 | list_del(&buf->vb.queue); |
1230 | buf->vb.state = VIDEOBUF_ERROR; | 1230 | buf->vb.state = VIDEOBUF_ERROR; |
1231 | wake_up(&buf->vb.done); | 1231 | wake_up(&buf->vb.done); |
1232 | dprintk(1, "[%p/%d] %s - dma=0x%08lx\n", | 1232 | dprintk(1, "[%p/%d] %s - dma=0x%08lx\n", |
1233 | buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); | 1233 | buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); |
1234 | } | 1234 | } |
1235 | if (restart) { | 1235 | if (restart) { |
1236 | dprintk(1, "restarting queue\n" ); | 1236 | dprintk(1, "restarting queue\n" ); |
1237 | cx23885_restart_queue(port, q); | 1237 | cx23885_restart_queue(port, q); |
1238 | } | 1238 | } |
1239 | spin_unlock_irqrestore(&port->slock, flags); | 1239 | spin_unlock_irqrestore(&port->slock, flags); |
1240 | } | 1240 | } |
1241 | 1241 | ||
1242 | 1242 | ||
1243 | static void cx23885_timeout(unsigned long data) | 1243 | static void cx23885_timeout(unsigned long data) |
1244 | { | 1244 | { |
1245 | struct cx23885_tsport *port = (struct cx23885_tsport *)data; | 1245 | struct cx23885_tsport *port = (struct cx23885_tsport *)data; |
1246 | struct cx23885_dev *dev = port->dev; | 1246 | struct cx23885_dev *dev = port->dev; |
1247 | 1247 | ||
1248 | dprintk(1, "%s()\n",__FUNCTION__); | 1248 | dprintk(1, "%s()\n",__func__); |
1249 | 1249 | ||
1250 | if (debug > 5) | 1250 | if (debug > 5) |
1251 | cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); | 1251 | cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); |
1252 | 1252 | ||
1253 | cx23885_stop_dma(port); | 1253 | cx23885_stop_dma(port); |
1254 | do_cancel_buffers(port, "timeout", 1); | 1254 | do_cancel_buffers(port, "timeout", 1); |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) | 1257 | static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) |
1258 | { | 1258 | { |
1259 | struct cx23885_dev *dev = port->dev; | 1259 | struct cx23885_dev *dev = port->dev; |
1260 | int handled = 0; | 1260 | int handled = 0; |
1261 | u32 count; | 1261 | u32 count; |
1262 | 1262 | ||
1263 | if ( (status & VID_BC_MSK_OPC_ERR) || | 1263 | if ( (status & VID_BC_MSK_OPC_ERR) || |
1264 | (status & VID_BC_MSK_BAD_PKT) || | 1264 | (status & VID_BC_MSK_BAD_PKT) || |
1265 | (status & VID_BC_MSK_SYNC) || | 1265 | (status & VID_BC_MSK_SYNC) || |
1266 | (status & VID_BC_MSK_OF)) | 1266 | (status & VID_BC_MSK_OF)) |
1267 | { | 1267 | { |
1268 | if (status & VID_BC_MSK_OPC_ERR) | 1268 | if (status & VID_BC_MSK_OPC_ERR) |
1269 | dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR); | 1269 | dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR); |
1270 | if (status & VID_BC_MSK_BAD_PKT) | 1270 | if (status & VID_BC_MSK_BAD_PKT) |
1271 | dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", VID_BC_MSK_BAD_PKT); | 1271 | dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", VID_BC_MSK_BAD_PKT); |
1272 | if (status & VID_BC_MSK_SYNC) | 1272 | if (status & VID_BC_MSK_SYNC) |
1273 | dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n", VID_BC_MSK_SYNC); | 1273 | dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n", VID_BC_MSK_SYNC); |
1274 | if (status & VID_BC_MSK_OF) | 1274 | if (status & VID_BC_MSK_OF) |
1275 | dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n", VID_BC_MSK_OF); | 1275 | dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n", VID_BC_MSK_OF); |
1276 | 1276 | ||
1277 | printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); | 1277 | printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); |
1278 | 1278 | ||
1279 | cx_clear(port->reg_dma_ctl, port->dma_ctl_val); | 1279 | cx_clear(port->reg_dma_ctl, port->dma_ctl_val); |
1280 | cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); | 1280 | cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); |
1281 | 1281 | ||
1282 | } else if (status & VID_BC_MSK_RISCI1) { | 1282 | } else if (status & VID_BC_MSK_RISCI1) { |
1283 | 1283 | ||
1284 | dprintk(7, " (RISCI1 0x%08x)\n", VID_BC_MSK_RISCI1); | 1284 | dprintk(7, " (RISCI1 0x%08x)\n", VID_BC_MSK_RISCI1); |
1285 | 1285 | ||
1286 | spin_lock(&port->slock); | 1286 | spin_lock(&port->slock); |
1287 | count = cx_read(port->reg_gpcnt); | 1287 | count = cx_read(port->reg_gpcnt); |
1288 | cx23885_wakeup(port, &port->mpegq, count); | 1288 | cx23885_wakeup(port, &port->mpegq, count); |
1289 | spin_unlock(&port->slock); | 1289 | spin_unlock(&port->slock); |
1290 | 1290 | ||
1291 | } else if (status & VID_BC_MSK_RISCI2) { | 1291 | } else if (status & VID_BC_MSK_RISCI2) { |
1292 | 1292 | ||
1293 | dprintk(7, " (RISCI2 0x%08x)\n", VID_BC_MSK_RISCI2); | 1293 | dprintk(7, " (RISCI2 0x%08x)\n", VID_BC_MSK_RISCI2); |
1294 | 1294 | ||
1295 | spin_lock(&port->slock); | 1295 | spin_lock(&port->slock); |
1296 | cx23885_restart_queue(port, &port->mpegq); | 1296 | cx23885_restart_queue(port, &port->mpegq); |
1297 | spin_unlock(&port->slock); | 1297 | spin_unlock(&port->slock); |
1298 | 1298 | ||
1299 | } | 1299 | } |
1300 | if (status) { | 1300 | if (status) { |
1301 | cx_write(port->reg_ts_int_stat, status); | 1301 | cx_write(port->reg_ts_int_stat, status); |
1302 | handled = 1; | 1302 | handled = 1; |
1303 | } | 1303 | } |
1304 | 1304 | ||
1305 | return handled; | 1305 | return handled; |
1306 | } | 1306 | } |
1307 | 1307 | ||
1308 | static irqreturn_t cx23885_irq(int irq, void *dev_id) | 1308 | static irqreturn_t cx23885_irq(int irq, void *dev_id) |
1309 | { | 1309 | { |
1310 | struct cx23885_dev *dev = dev_id; | 1310 | struct cx23885_dev *dev = dev_id; |
1311 | struct cx23885_tsport *ts1 = &dev->ts1; | 1311 | struct cx23885_tsport *ts1 = &dev->ts1; |
1312 | struct cx23885_tsport *ts2 = &dev->ts2; | 1312 | struct cx23885_tsport *ts2 = &dev->ts2; |
1313 | u32 pci_status, pci_mask; | 1313 | u32 pci_status, pci_mask; |
1314 | u32 vida_status, vida_mask; | 1314 | u32 vida_status, vida_mask; |
1315 | u32 ts1_status, ts1_mask; | 1315 | u32 ts1_status, ts1_mask; |
1316 | u32 ts2_status, ts2_mask; | 1316 | u32 ts2_status, ts2_mask; |
1317 | int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0; | 1317 | int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0; |
1318 | 1318 | ||
1319 | pci_status = cx_read(PCI_INT_STAT); | 1319 | pci_status = cx_read(PCI_INT_STAT); |
1320 | pci_mask = cx_read(PCI_INT_MSK); | 1320 | pci_mask = cx_read(PCI_INT_MSK); |
1321 | vida_status = cx_read(VID_A_INT_STAT); | 1321 | vida_status = cx_read(VID_A_INT_STAT); |
1322 | vida_mask = cx_read(VID_A_INT_MSK); | 1322 | vida_mask = cx_read(VID_A_INT_MSK); |
1323 | ts1_status = cx_read(VID_B_INT_STAT); | 1323 | ts1_status = cx_read(VID_B_INT_STAT); |
1324 | ts1_mask = cx_read(VID_B_INT_MSK); | 1324 | ts1_mask = cx_read(VID_B_INT_MSK); |
1325 | ts2_status = cx_read(VID_C_INT_STAT); | 1325 | ts2_status = cx_read(VID_C_INT_STAT); |
1326 | ts2_mask = cx_read(VID_C_INT_MSK); | 1326 | ts2_mask = cx_read(VID_C_INT_MSK); |
1327 | 1327 | ||
1328 | if ( (pci_status == 0) && (ts2_status == 0) && (ts1_status == 0) ) | 1328 | if ( (pci_status == 0) && (ts2_status == 0) && (ts1_status == 0) ) |
1329 | goto out; | 1329 | goto out; |
1330 | 1330 | ||
1331 | vida_count = cx_read(VID_A_GPCNT); | 1331 | vida_count = cx_read(VID_A_GPCNT); |
1332 | ts1_count = cx_read(ts1->reg_gpcnt); | 1332 | ts1_count = cx_read(ts1->reg_gpcnt); |
1333 | ts2_count = cx_read(ts2->reg_gpcnt); | 1333 | ts2_count = cx_read(ts2->reg_gpcnt); |
1334 | dprintk(7, "pci_status: 0x%08x pci_mask: 0x%08x\n", | 1334 | dprintk(7, "pci_status: 0x%08x pci_mask: 0x%08x\n", |
1335 | pci_status, pci_mask); | 1335 | pci_status, pci_mask); |
1336 | dprintk(7, "vida_status: 0x%08x vida_mask: 0x%08x count: 0x%x\n", | 1336 | dprintk(7, "vida_status: 0x%08x vida_mask: 0x%08x count: 0x%x\n", |
1337 | vida_status, vida_mask, vida_count); | 1337 | vida_status, vida_mask, vida_count); |
1338 | dprintk(7, "ts1_status: 0x%08x ts1_mask: 0x%08x count: 0x%x\n", | 1338 | dprintk(7, "ts1_status: 0x%08x ts1_mask: 0x%08x count: 0x%x\n", |
1339 | ts1_status, ts1_mask, ts1_count); | 1339 | ts1_status, ts1_mask, ts1_count); |
1340 | dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", | 1340 | dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", |
1341 | ts2_status, ts2_mask, ts2_count); | 1341 | ts2_status, ts2_mask, ts2_count); |
1342 | 1342 | ||
1343 | if ( (pci_status & PCI_MSK_RISC_RD) || | 1343 | if ( (pci_status & PCI_MSK_RISC_RD) || |
1344 | (pci_status & PCI_MSK_RISC_WR) || | 1344 | (pci_status & PCI_MSK_RISC_WR) || |
1345 | (pci_status & PCI_MSK_AL_RD) || | 1345 | (pci_status & PCI_MSK_AL_RD) || |
1346 | (pci_status & PCI_MSK_AL_WR) || | 1346 | (pci_status & PCI_MSK_AL_WR) || |
1347 | (pci_status & PCI_MSK_APB_DMA) || | 1347 | (pci_status & PCI_MSK_APB_DMA) || |
1348 | (pci_status & PCI_MSK_VID_C) || | 1348 | (pci_status & PCI_MSK_VID_C) || |
1349 | (pci_status & PCI_MSK_VID_B) || | 1349 | (pci_status & PCI_MSK_VID_B) || |
1350 | (pci_status & PCI_MSK_VID_A) || | 1350 | (pci_status & PCI_MSK_VID_A) || |
1351 | (pci_status & PCI_MSK_AUD_INT) || | 1351 | (pci_status & PCI_MSK_AUD_INT) || |
1352 | (pci_status & PCI_MSK_AUD_EXT) ) | 1352 | (pci_status & PCI_MSK_AUD_EXT) ) |
1353 | { | 1353 | { |
1354 | 1354 | ||
1355 | if (pci_status & PCI_MSK_RISC_RD) | 1355 | if (pci_status & PCI_MSK_RISC_RD) |
1356 | dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", PCI_MSK_RISC_RD); | 1356 | dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", PCI_MSK_RISC_RD); |
1357 | if (pci_status & PCI_MSK_RISC_WR) | 1357 | if (pci_status & PCI_MSK_RISC_WR) |
1358 | dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n", PCI_MSK_RISC_WR); | 1358 | dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n", PCI_MSK_RISC_WR); |
1359 | if (pci_status & PCI_MSK_AL_RD) | 1359 | if (pci_status & PCI_MSK_AL_RD) |
1360 | dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n", PCI_MSK_AL_RD); | 1360 | dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n", PCI_MSK_AL_RD); |
1361 | if (pci_status & PCI_MSK_AL_WR) | 1361 | if (pci_status & PCI_MSK_AL_WR) |
1362 | dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n", PCI_MSK_AL_WR); | 1362 | dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n", PCI_MSK_AL_WR); |
1363 | if (pci_status & PCI_MSK_APB_DMA) | 1363 | if (pci_status & PCI_MSK_APB_DMA) |
1364 | dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n", PCI_MSK_APB_DMA); | 1364 | dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n", PCI_MSK_APB_DMA); |
1365 | if (pci_status & PCI_MSK_VID_C) | 1365 | if (pci_status & PCI_MSK_VID_C) |
1366 | dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n", PCI_MSK_VID_C); | 1366 | dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n", PCI_MSK_VID_C); |
1367 | if (pci_status & PCI_MSK_VID_B) | 1367 | if (pci_status & PCI_MSK_VID_B) |
1368 | dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n", PCI_MSK_VID_B); | 1368 | dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n", PCI_MSK_VID_B); |
1369 | if (pci_status & PCI_MSK_VID_A) | 1369 | if (pci_status & PCI_MSK_VID_A) |
1370 | dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n", PCI_MSK_VID_A); | 1370 | dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n", PCI_MSK_VID_A); |
1371 | if (pci_status & PCI_MSK_AUD_INT) | 1371 | if (pci_status & PCI_MSK_AUD_INT) |
1372 | dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n", PCI_MSK_AUD_INT); | 1372 | dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n", PCI_MSK_AUD_INT); |
1373 | if (pci_status & PCI_MSK_AUD_EXT) | 1373 | if (pci_status & PCI_MSK_AUD_EXT) |
1374 | dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n", PCI_MSK_AUD_EXT); | 1374 | dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n", PCI_MSK_AUD_EXT); |
1375 | 1375 | ||
1376 | } | 1376 | } |
1377 | 1377 | ||
1378 | if (ts1_status) { | 1378 | if (ts1_status) { |
1379 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) | 1379 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) |
1380 | handled += cx23885_irq_ts(ts1, ts1_status); | 1380 | handled += cx23885_irq_ts(ts1, ts1_status); |
1381 | } | 1381 | } |
1382 | 1382 | ||
1383 | if (ts2_status) { | 1383 | if (ts2_status) { |
1384 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) | 1384 | if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) |
1385 | handled += cx23885_irq_ts(ts2, ts2_status); | 1385 | handled += cx23885_irq_ts(ts2, ts2_status); |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | if (vida_status) | 1388 | if (vida_status) |
1389 | handled += cx23885_video_irq(dev, vida_status); | 1389 | handled += cx23885_video_irq(dev, vida_status); |
1390 | 1390 | ||
1391 | if (handled) | 1391 | if (handled) |
1392 | cx_write(PCI_INT_STAT, pci_status); | 1392 | cx_write(PCI_INT_STAT, pci_status); |
1393 | out: | 1393 | out: |
1394 | return IRQ_RETVAL(handled); | 1394 | return IRQ_RETVAL(handled); |
1395 | } | 1395 | } |
1396 | 1396 | ||
1397 | static int __devinit cx23885_initdev(struct pci_dev *pci_dev, | 1397 | static int __devinit cx23885_initdev(struct pci_dev *pci_dev, |
1398 | const struct pci_device_id *pci_id) | 1398 | const struct pci_device_id *pci_id) |
1399 | { | 1399 | { |
1400 | struct cx23885_dev *dev; | 1400 | struct cx23885_dev *dev; |
1401 | int err; | 1401 | int err; |
1402 | 1402 | ||
1403 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1403 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
1404 | if (NULL == dev) | 1404 | if (NULL == dev) |
1405 | return -ENOMEM; | 1405 | return -ENOMEM; |
1406 | 1406 | ||
1407 | /* pci init */ | 1407 | /* pci init */ |
1408 | dev->pci = pci_dev; | 1408 | dev->pci = pci_dev; |
1409 | if (pci_enable_device(pci_dev)) { | 1409 | if (pci_enable_device(pci_dev)) { |
1410 | err = -EIO; | 1410 | err = -EIO; |
1411 | goto fail_free; | 1411 | goto fail_free; |
1412 | } | 1412 | } |
1413 | 1413 | ||
1414 | if (cx23885_dev_setup(dev) < 0) { | 1414 | if (cx23885_dev_setup(dev) < 0) { |
1415 | err = -EINVAL; | 1415 | err = -EINVAL; |
1416 | goto fail_free; | 1416 | goto fail_free; |
1417 | } | 1417 | } |
1418 | 1418 | ||
1419 | /* print pci info */ | 1419 | /* print pci info */ |
1420 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); | 1420 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); |
1421 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); | 1421 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); |
1422 | printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " | 1422 | printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " |
1423 | "latency: %d, mmio: 0x%llx\n", dev->name, | 1423 | "latency: %d, mmio: 0x%llx\n", dev->name, |
1424 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, | 1424 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, |
1425 | dev->pci_lat, (unsigned long long)pci_resource_start(pci_dev,0)); | 1425 | dev->pci_lat, (unsigned long long)pci_resource_start(pci_dev,0)); |
1426 | 1426 | ||
1427 | pci_set_master(pci_dev); | 1427 | pci_set_master(pci_dev); |
1428 | if (!pci_dma_supported(pci_dev, 0xffffffff)) { | 1428 | if (!pci_dma_supported(pci_dev, 0xffffffff)) { |
1429 | printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); | 1429 | printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); |
1430 | err = -EIO; | 1430 | err = -EIO; |
1431 | goto fail_irq; | 1431 | goto fail_irq; |
1432 | } | 1432 | } |
1433 | 1433 | ||
1434 | err = request_irq(pci_dev->irq, cx23885_irq, | 1434 | err = request_irq(pci_dev->irq, cx23885_irq, |
1435 | IRQF_SHARED | IRQF_DISABLED, dev->name, dev); | 1435 | IRQF_SHARED | IRQF_DISABLED, dev->name, dev); |
1436 | if (err < 0) { | 1436 | if (err < 0) { |
1437 | printk(KERN_ERR "%s: can't get IRQ %d\n", | 1437 | printk(KERN_ERR "%s: can't get IRQ %d\n", |
1438 | dev->name, pci_dev->irq); | 1438 | dev->name, pci_dev->irq); |
1439 | goto fail_irq; | 1439 | goto fail_irq; |
1440 | } | 1440 | } |
1441 | 1441 | ||
1442 | pci_set_drvdata(pci_dev, dev); | 1442 | pci_set_drvdata(pci_dev, dev); |
1443 | return 0; | 1443 | return 0; |
1444 | 1444 | ||
1445 | fail_irq: | 1445 | fail_irq: |
1446 | cx23885_dev_unregister(dev); | 1446 | cx23885_dev_unregister(dev); |
1447 | fail_free: | 1447 | fail_free: |
1448 | kfree(dev); | 1448 | kfree(dev); |
1449 | return err; | 1449 | return err; |
1450 | } | 1450 | } |
1451 | 1451 | ||
1452 | static void __devexit cx23885_finidev(struct pci_dev *pci_dev) | 1452 | static void __devexit cx23885_finidev(struct pci_dev *pci_dev) |
1453 | { | 1453 | { |
1454 | struct cx23885_dev *dev = pci_get_drvdata(pci_dev); | 1454 | struct cx23885_dev *dev = pci_get_drvdata(pci_dev); |
1455 | 1455 | ||
1456 | cx23885_shutdown(dev); | 1456 | cx23885_shutdown(dev); |
1457 | 1457 | ||
1458 | pci_disable_device(pci_dev); | 1458 | pci_disable_device(pci_dev); |
1459 | 1459 | ||
1460 | /* unregister stuff */ | 1460 | /* unregister stuff */ |
1461 | free_irq(pci_dev->irq, dev); | 1461 | free_irq(pci_dev->irq, dev); |
1462 | pci_set_drvdata(pci_dev, NULL); | 1462 | pci_set_drvdata(pci_dev, NULL); |
1463 | 1463 | ||
1464 | mutex_lock(&devlist); | 1464 | mutex_lock(&devlist); |
1465 | list_del(&dev->devlist); | 1465 | list_del(&dev->devlist); |
1466 | mutex_unlock(&devlist); | 1466 | mutex_unlock(&devlist); |
1467 | 1467 | ||
1468 | cx23885_dev_unregister(dev); | 1468 | cx23885_dev_unregister(dev); |
1469 | kfree(dev); | 1469 | kfree(dev); |
1470 | } | 1470 | } |
1471 | 1471 | ||
1472 | static struct pci_device_id cx23885_pci_tbl[] = { | 1472 | static struct pci_device_id cx23885_pci_tbl[] = { |
1473 | { | 1473 | { |
1474 | /* CX23885 */ | 1474 | /* CX23885 */ |
1475 | .vendor = 0x14f1, | 1475 | .vendor = 0x14f1, |
1476 | .device = 0x8852, | 1476 | .device = 0x8852, |
1477 | .subvendor = PCI_ANY_ID, | 1477 | .subvendor = PCI_ANY_ID, |
1478 | .subdevice = PCI_ANY_ID, | 1478 | .subdevice = PCI_ANY_ID, |
1479 | },{ | 1479 | },{ |
1480 | /* CX23887 Rev 2 */ | 1480 | /* CX23887 Rev 2 */ |
1481 | .vendor = 0x14f1, | 1481 | .vendor = 0x14f1, |
1482 | .device = 0x8880, | 1482 | .device = 0x8880, |
1483 | .subvendor = PCI_ANY_ID, | 1483 | .subvendor = PCI_ANY_ID, |
1484 | .subdevice = PCI_ANY_ID, | 1484 | .subdevice = PCI_ANY_ID, |
1485 | },{ | 1485 | },{ |
1486 | /* --- end of list --- */ | 1486 | /* --- end of list --- */ |
1487 | } | 1487 | } |
1488 | }; | 1488 | }; |
1489 | MODULE_DEVICE_TABLE(pci, cx23885_pci_tbl); | 1489 | MODULE_DEVICE_TABLE(pci, cx23885_pci_tbl); |
1490 | 1490 | ||
1491 | static struct pci_driver cx23885_pci_driver = { | 1491 | static struct pci_driver cx23885_pci_driver = { |
1492 | .name = "cx23885", | 1492 | .name = "cx23885", |
1493 | .id_table = cx23885_pci_tbl, | 1493 | .id_table = cx23885_pci_tbl, |
1494 | .probe = cx23885_initdev, | 1494 | .probe = cx23885_initdev, |
1495 | .remove = __devexit_p(cx23885_finidev), | 1495 | .remove = __devexit_p(cx23885_finidev), |
1496 | /* TODO */ | 1496 | /* TODO */ |
1497 | .suspend = NULL, | 1497 | .suspend = NULL, |
1498 | .resume = NULL, | 1498 | .resume = NULL, |
1499 | }; | 1499 | }; |
1500 | 1500 | ||
1501 | static int cx23885_init(void) | 1501 | static int cx23885_init(void) |
1502 | { | 1502 | { |
1503 | printk(KERN_INFO "cx23885 driver version %d.%d.%d loaded\n", | 1503 | printk(KERN_INFO "cx23885 driver version %d.%d.%d loaded\n", |
1504 | (CX23885_VERSION_CODE >> 16) & 0xff, | 1504 | (CX23885_VERSION_CODE >> 16) & 0xff, |
1505 | (CX23885_VERSION_CODE >> 8) & 0xff, | 1505 | (CX23885_VERSION_CODE >> 8) & 0xff, |
1506 | CX23885_VERSION_CODE & 0xff); | 1506 | CX23885_VERSION_CODE & 0xff); |
1507 | #ifdef SNAPSHOT | 1507 | #ifdef SNAPSHOT |
1508 | printk(KERN_INFO "cx23885: snapshot date %04d-%02d-%02d\n", | 1508 | printk(KERN_INFO "cx23885: snapshot date %04d-%02d-%02d\n", |
1509 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); | 1509 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); |
1510 | #endif | 1510 | #endif |
1511 | return pci_register_driver(&cx23885_pci_driver); | 1511 | return pci_register_driver(&cx23885_pci_driver); |
1512 | } | 1512 | } |
1513 | 1513 | ||
1514 | static void cx23885_fini(void) | 1514 | static void cx23885_fini(void) |
1515 | { | 1515 | { |
1516 | pci_unregister_driver(&cx23885_pci_driver); | 1516 | pci_unregister_driver(&cx23885_pci_driver); |
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | module_init(cx23885_init); | 1519 | module_init(cx23885_init); |
1520 | module_exit(cx23885_fini); | 1520 | module_exit(cx23885_fini); |
1521 | 1521 | ||
1522 | /* ----------------------------------------------------------- */ | 1522 | /* ----------------------------------------------------------- */ |
1523 | /* | 1523 | /* |
1524 | * Local variables: | 1524 | * Local variables: |
1525 | * c-basic-offset: 8 | 1525 | * c-basic-offset: 8 |
1526 | * End: | 1526 | * End: |
1527 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off | 1527 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off |
1528 | */ | 1528 | */ |
1529 | 1529 |
drivers/media/video/cx23885/cx23885-dvb.c
1 | /* | 1 | /* |
2 | * Driver for the Conexant CX23885 PCIe bridge | 2 | * Driver for the Conexant CX23885 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> | 4 | * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> |
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 <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/kthread.h> | 26 | #include <linux/kthread.h> |
27 | #include <linux/file.h> | 27 | #include <linux/file.h> |
28 | #include <linux/suspend.h> | 28 | #include <linux/suspend.h> |
29 | 29 | ||
30 | #include "cx23885.h" | 30 | #include "cx23885.h" |
31 | #include <media/v4l2-common.h> | 31 | #include <media/v4l2-common.h> |
32 | 32 | ||
33 | #include "s5h1409.h" | 33 | #include "s5h1409.h" |
34 | #include "mt2131.h" | 34 | #include "mt2131.h" |
35 | #include "tda8290.h" | 35 | #include "tda8290.h" |
36 | #include "tda18271.h" | 36 | #include "tda18271.h" |
37 | #include "lgdt330x.h" | 37 | #include "lgdt330x.h" |
38 | #include "xc5000.h" | 38 | #include "xc5000.h" |
39 | #include "dvb-pll.h" | 39 | #include "dvb-pll.h" |
40 | #include "tuner-xc2028.h" | 40 | #include "tuner-xc2028.h" |
41 | #include "tuner-xc2028-types.h" | 41 | #include "tuner-xc2028-types.h" |
42 | #include "tuner-simple.h" | 42 | #include "tuner-simple.h" |
43 | 43 | ||
44 | static unsigned int debug; | 44 | static unsigned int debug; |
45 | 45 | ||
46 | #define dprintk(level, fmt, arg...)\ | 46 | #define dprintk(level, fmt, arg...)\ |
47 | do { if (debug >= level)\ | 47 | do { if (debug >= level)\ |
48 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ | 48 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ |
49 | } while (0) | 49 | } while (0) |
50 | 50 | ||
51 | /* ------------------------------------------------------------------ */ | 51 | /* ------------------------------------------------------------------ */ |
52 | 52 | ||
53 | static unsigned int alt_tuner; | 53 | static unsigned int alt_tuner; |
54 | module_param(alt_tuner, int, 0644); | 54 | module_param(alt_tuner, int, 0644); |
55 | MODULE_PARM_DESC(alt_tuner, "Enable alternate tuner configuration"); | 55 | MODULE_PARM_DESC(alt_tuner, "Enable alternate tuner configuration"); |
56 | 56 | ||
57 | /* ------------------------------------------------------------------ */ | 57 | /* ------------------------------------------------------------------ */ |
58 | 58 | ||
59 | static int dvb_buf_setup(struct videobuf_queue *q, | 59 | static int dvb_buf_setup(struct videobuf_queue *q, |
60 | unsigned int *count, unsigned int *size) | 60 | unsigned int *count, unsigned int *size) |
61 | { | 61 | { |
62 | struct cx23885_tsport *port = q->priv_data; | 62 | struct cx23885_tsport *port = q->priv_data; |
63 | 63 | ||
64 | port->ts_packet_size = 188 * 4; | 64 | port->ts_packet_size = 188 * 4; |
65 | port->ts_packet_count = 32; | 65 | port->ts_packet_count = 32; |
66 | 66 | ||
67 | *size = port->ts_packet_size * port->ts_packet_count; | 67 | *size = port->ts_packet_size * port->ts_packet_count; |
68 | *count = 32; | 68 | *count = 32; |
69 | return 0; | 69 | return 0; |
70 | } | 70 | } |
71 | 71 | ||
72 | static int dvb_buf_prepare(struct videobuf_queue *q, | 72 | static int dvb_buf_prepare(struct videobuf_queue *q, |
73 | struct videobuf_buffer *vb, enum v4l2_field field) | 73 | struct videobuf_buffer *vb, enum v4l2_field field) |
74 | { | 74 | { |
75 | struct cx23885_tsport *port = q->priv_data; | 75 | struct cx23885_tsport *port = q->priv_data; |
76 | return cx23885_buf_prepare(q, port, (struct cx23885_buffer*)vb, field); | 76 | return cx23885_buf_prepare(q, port, (struct cx23885_buffer*)vb, field); |
77 | } | 77 | } |
78 | 78 | ||
79 | static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | 79 | static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) |
80 | { | 80 | { |
81 | struct cx23885_tsport *port = q->priv_data; | 81 | struct cx23885_tsport *port = q->priv_data; |
82 | cx23885_buf_queue(port, (struct cx23885_buffer*)vb); | 82 | cx23885_buf_queue(port, (struct cx23885_buffer*)vb); |
83 | } | 83 | } |
84 | 84 | ||
85 | static void dvb_buf_release(struct videobuf_queue *q, | 85 | static void dvb_buf_release(struct videobuf_queue *q, |
86 | struct videobuf_buffer *vb) | 86 | struct videobuf_buffer *vb) |
87 | { | 87 | { |
88 | cx23885_free_buffer(q, (struct cx23885_buffer*)vb); | 88 | cx23885_free_buffer(q, (struct cx23885_buffer*)vb); |
89 | } | 89 | } |
90 | 90 | ||
91 | static struct videobuf_queue_ops dvb_qops = { | 91 | static struct videobuf_queue_ops dvb_qops = { |
92 | .buf_setup = dvb_buf_setup, | 92 | .buf_setup = dvb_buf_setup, |
93 | .buf_prepare = dvb_buf_prepare, | 93 | .buf_prepare = dvb_buf_prepare, |
94 | .buf_queue = dvb_buf_queue, | 94 | .buf_queue = dvb_buf_queue, |
95 | .buf_release = dvb_buf_release, | 95 | .buf_release = dvb_buf_release, |
96 | }; | 96 | }; |
97 | 97 | ||
98 | static struct s5h1409_config hauppauge_generic_config = { | 98 | static struct s5h1409_config hauppauge_generic_config = { |
99 | .demod_address = 0x32 >> 1, | 99 | .demod_address = 0x32 >> 1, |
100 | .output_mode = S5H1409_SERIAL_OUTPUT, | 100 | .output_mode = S5H1409_SERIAL_OUTPUT, |
101 | .gpio = S5H1409_GPIO_ON, | 101 | .gpio = S5H1409_GPIO_ON, |
102 | .qam_if = 44000, | 102 | .qam_if = 44000, |
103 | .inversion = S5H1409_INVERSION_OFF, | 103 | .inversion = S5H1409_INVERSION_OFF, |
104 | .status_mode = S5H1409_DEMODLOCKING, | 104 | .status_mode = S5H1409_DEMODLOCKING, |
105 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 105 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | static struct s5h1409_config hauppauge_ezqam_config = { | 108 | static struct s5h1409_config hauppauge_ezqam_config = { |
109 | .demod_address = 0x32 >> 1, | 109 | .demod_address = 0x32 >> 1, |
110 | .output_mode = S5H1409_SERIAL_OUTPUT, | 110 | .output_mode = S5H1409_SERIAL_OUTPUT, |
111 | .gpio = S5H1409_GPIO_OFF, | 111 | .gpio = S5H1409_GPIO_OFF, |
112 | .qam_if = 4000, | 112 | .qam_if = 4000, |
113 | .inversion = S5H1409_INVERSION_ON, | 113 | .inversion = S5H1409_INVERSION_ON, |
114 | .status_mode = S5H1409_DEMODLOCKING, | 114 | .status_mode = S5H1409_DEMODLOCKING, |
115 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 115 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
116 | }; | 116 | }; |
117 | 117 | ||
118 | static struct s5h1409_config hauppauge_hvr1800lp_config = { | 118 | static struct s5h1409_config hauppauge_hvr1800lp_config = { |
119 | .demod_address = 0x32 >> 1, | 119 | .demod_address = 0x32 >> 1, |
120 | .output_mode = S5H1409_SERIAL_OUTPUT, | 120 | .output_mode = S5H1409_SERIAL_OUTPUT, |
121 | .gpio = S5H1409_GPIO_OFF, | 121 | .gpio = S5H1409_GPIO_OFF, |
122 | .qam_if = 44000, | 122 | .qam_if = 44000, |
123 | .inversion = S5H1409_INVERSION_OFF, | 123 | .inversion = S5H1409_INVERSION_OFF, |
124 | .status_mode = S5H1409_DEMODLOCKING, | 124 | .status_mode = S5H1409_DEMODLOCKING, |
125 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 125 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
126 | }; | 126 | }; |
127 | 127 | ||
128 | static struct s5h1409_config hauppauge_hvr1500_config = { | 128 | static struct s5h1409_config hauppauge_hvr1500_config = { |
129 | .demod_address = 0x32 >> 1, | 129 | .demod_address = 0x32 >> 1, |
130 | .output_mode = S5H1409_SERIAL_OUTPUT, | 130 | .output_mode = S5H1409_SERIAL_OUTPUT, |
131 | .gpio = S5H1409_GPIO_OFF, | 131 | .gpio = S5H1409_GPIO_OFF, |
132 | .inversion = S5H1409_INVERSION_OFF, | 132 | .inversion = S5H1409_INVERSION_OFF, |
133 | .status_mode = S5H1409_DEMODLOCKING, | 133 | .status_mode = S5H1409_DEMODLOCKING, |
134 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 134 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
135 | }; | 135 | }; |
136 | 136 | ||
137 | static struct mt2131_config hauppauge_generic_tunerconfig = { | 137 | static struct mt2131_config hauppauge_generic_tunerconfig = { |
138 | 0x61 | 138 | 0x61 |
139 | }; | 139 | }; |
140 | 140 | ||
141 | static struct lgdt330x_config fusionhdtv_5_express = { | 141 | static struct lgdt330x_config fusionhdtv_5_express = { |
142 | .demod_address = 0x0e, | 142 | .demod_address = 0x0e, |
143 | .demod_chip = LGDT3303, | 143 | .demod_chip = LGDT3303, |
144 | .serial_mpeg = 0x40, | 144 | .serial_mpeg = 0x40, |
145 | }; | 145 | }; |
146 | 146 | ||
147 | static struct s5h1409_config hauppauge_hvr1500q_config = { | 147 | static struct s5h1409_config hauppauge_hvr1500q_config = { |
148 | .demod_address = 0x32 >> 1, | 148 | .demod_address = 0x32 >> 1, |
149 | .output_mode = S5H1409_SERIAL_OUTPUT, | 149 | .output_mode = S5H1409_SERIAL_OUTPUT, |
150 | .gpio = S5H1409_GPIO_ON, | 150 | .gpio = S5H1409_GPIO_ON, |
151 | .qam_if = 44000, | 151 | .qam_if = 44000, |
152 | .inversion = S5H1409_INVERSION_OFF, | 152 | .inversion = S5H1409_INVERSION_OFF, |
153 | .status_mode = S5H1409_DEMODLOCKING, | 153 | .status_mode = S5H1409_DEMODLOCKING, |
154 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 154 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
155 | }; | 155 | }; |
156 | 156 | ||
157 | static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { | 157 | static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { |
158 | .i2c_address = 0x61, | 158 | .i2c_address = 0x61, |
159 | .if_khz = 5380, | 159 | .if_khz = 5380, |
160 | .tuner_callback = cx23885_tuner_callback | 160 | .tuner_callback = cx23885_tuner_callback |
161 | }; | 161 | }; |
162 | 162 | ||
163 | static struct tda829x_config tda829x_no_probe = { | 163 | static struct tda829x_config tda829x_no_probe = { |
164 | .probe_tuner = TDA829X_DONT_PROBE, | 164 | .probe_tuner = TDA829X_DONT_PROBE, |
165 | }; | 165 | }; |
166 | 166 | ||
167 | static struct tda18271_std_map hauppauge_tda18271_std_map = { | 167 | static struct tda18271_std_map hauppauge_tda18271_std_map = { |
168 | .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, | 168 | .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, |
169 | .if_lvl = 6, .rfagc_top = 0x37 }, | 169 | .if_lvl = 6, .rfagc_top = 0x37 }, |
170 | .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, | 170 | .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, |
171 | .if_lvl = 6, .rfagc_top = 0x37 }, | 171 | .if_lvl = 6, .rfagc_top = 0x37 }, |
172 | }; | 172 | }; |
173 | 173 | ||
174 | static struct tda18271_config hauppauge_tda18271_config = { | 174 | static struct tda18271_config hauppauge_tda18271_config = { |
175 | .std_map = &hauppauge_tda18271_std_map, | 175 | .std_map = &hauppauge_tda18271_std_map, |
176 | .gate = TDA18271_GATE_ANALOG, | 176 | .gate = TDA18271_GATE_ANALOG, |
177 | }; | 177 | }; |
178 | 178 | ||
179 | static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) | 179 | static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) |
180 | { | 180 | { |
181 | struct cx23885_tsport *port = ptr; | 181 | struct cx23885_tsport *port = ptr; |
182 | struct cx23885_dev *dev = port->dev; | 182 | struct cx23885_dev *dev = port->dev; |
183 | 183 | ||
184 | switch (command) { | 184 | switch (command) { |
185 | case XC2028_TUNER_RESET: | 185 | case XC2028_TUNER_RESET: |
186 | /* Send the tuner in then out of reset */ | 186 | /* Send the tuner in then out of reset */ |
187 | /* GPIO-2 xc3028 tuner */ | 187 | /* GPIO-2 xc3028 tuner */ |
188 | dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __FUNCTION__, arg); | 188 | dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg); |
189 | 189 | ||
190 | cx_set(GP0_IO, 0x00040000); | 190 | cx_set(GP0_IO, 0x00040000); |
191 | cx_clear(GP0_IO, 0x00000004); | 191 | cx_clear(GP0_IO, 0x00000004); |
192 | msleep(5); | 192 | msleep(5); |
193 | 193 | ||
194 | cx_set(GP0_IO, 0x00040004); | 194 | cx_set(GP0_IO, 0x00040004); |
195 | msleep(5); | 195 | msleep(5); |
196 | break; | 196 | break; |
197 | case XC2028_RESET_CLK: | 197 | case XC2028_RESET_CLK: |
198 | dprintk(1, "%s: XC2028_RESET_CLK %d\n", __FUNCTION__, arg); | 198 | dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg); |
199 | break; | 199 | break; |
200 | default: | 200 | default: |
201 | dprintk(1, "%s: unknown command %d, arg %d\n", __FUNCTION__, | 201 | dprintk(1, "%s: unknown command %d, arg %d\n", __func__, |
202 | command, arg); | 202 | command, arg); |
203 | return -EINVAL; | 203 | return -EINVAL; |
204 | } | 204 | } |
205 | 205 | ||
206 | return 0; | 206 | return 0; |
207 | } | 207 | } |
208 | 208 | ||
209 | static int dvb_register(struct cx23885_tsport *port) | 209 | static int dvb_register(struct cx23885_tsport *port) |
210 | { | 210 | { |
211 | struct cx23885_dev *dev = port->dev; | 211 | struct cx23885_dev *dev = port->dev; |
212 | struct cx23885_i2c *i2c_bus = NULL; | 212 | struct cx23885_i2c *i2c_bus = NULL; |
213 | 213 | ||
214 | /* init struct videobuf_dvb */ | 214 | /* init struct videobuf_dvb */ |
215 | port->dvb.name = dev->name; | 215 | port->dvb.name = dev->name; |
216 | 216 | ||
217 | /* init frontend */ | 217 | /* init frontend */ |
218 | switch (dev->board) { | 218 | switch (dev->board) { |
219 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 219 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
220 | i2c_bus = &dev->i2c_bus[0]; | 220 | i2c_bus = &dev->i2c_bus[0]; |
221 | port->dvb.frontend = dvb_attach(s5h1409_attach, | 221 | port->dvb.frontend = dvb_attach(s5h1409_attach, |
222 | &hauppauge_generic_config, | 222 | &hauppauge_generic_config, |
223 | &i2c_bus->i2c_adap); | 223 | &i2c_bus->i2c_adap); |
224 | if (port->dvb.frontend != NULL) { | 224 | if (port->dvb.frontend != NULL) { |
225 | dvb_attach(mt2131_attach, port->dvb.frontend, | 225 | dvb_attach(mt2131_attach, port->dvb.frontend, |
226 | &i2c_bus->i2c_adap, | 226 | &i2c_bus->i2c_adap, |
227 | &hauppauge_generic_tunerconfig, 0); | 227 | &hauppauge_generic_tunerconfig, 0); |
228 | } | 228 | } |
229 | break; | 229 | break; |
230 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | 230 | case CX23885_BOARD_HAUPPAUGE_HVR1800: |
231 | i2c_bus = &dev->i2c_bus[0]; | 231 | i2c_bus = &dev->i2c_bus[0]; |
232 | switch (alt_tuner) { | 232 | switch (alt_tuner) { |
233 | case 1: | 233 | case 1: |
234 | port->dvb.frontend = | 234 | port->dvb.frontend = |
235 | dvb_attach(s5h1409_attach, | 235 | dvb_attach(s5h1409_attach, |
236 | &hauppauge_ezqam_config, | 236 | &hauppauge_ezqam_config, |
237 | &i2c_bus->i2c_adap); | 237 | &i2c_bus->i2c_adap); |
238 | if (port->dvb.frontend != NULL) { | 238 | if (port->dvb.frontend != NULL) { |
239 | dvb_attach(tda829x_attach, port->dvb.frontend, | 239 | dvb_attach(tda829x_attach, port->dvb.frontend, |
240 | &dev->i2c_bus[1].i2c_adap, 0x42, | 240 | &dev->i2c_bus[1].i2c_adap, 0x42, |
241 | &tda829x_no_probe); | 241 | &tda829x_no_probe); |
242 | dvb_attach(tda18271_attach, port->dvb.frontend, | 242 | dvb_attach(tda18271_attach, port->dvb.frontend, |
243 | 0x60, &dev->i2c_bus[1].i2c_adap, | 243 | 0x60, &dev->i2c_bus[1].i2c_adap, |
244 | &hauppauge_tda18271_config); | 244 | &hauppauge_tda18271_config); |
245 | } | 245 | } |
246 | break; | 246 | break; |
247 | case 0: | 247 | case 0: |
248 | default: | 248 | default: |
249 | port->dvb.frontend = | 249 | port->dvb.frontend = |
250 | dvb_attach(s5h1409_attach, | 250 | dvb_attach(s5h1409_attach, |
251 | &hauppauge_generic_config, | 251 | &hauppauge_generic_config, |
252 | &i2c_bus->i2c_adap); | 252 | &i2c_bus->i2c_adap); |
253 | if (port->dvb.frontend != NULL) | 253 | if (port->dvb.frontend != NULL) |
254 | dvb_attach(mt2131_attach, port->dvb.frontend, | 254 | dvb_attach(mt2131_attach, port->dvb.frontend, |
255 | &i2c_bus->i2c_adap, | 255 | &i2c_bus->i2c_adap, |
256 | &hauppauge_generic_tunerconfig, 0); | 256 | &hauppauge_generic_tunerconfig, 0); |
257 | break; | 257 | break; |
258 | } | 258 | } |
259 | break; | 259 | break; |
260 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: | 260 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: |
261 | i2c_bus = &dev->i2c_bus[0]; | 261 | i2c_bus = &dev->i2c_bus[0]; |
262 | port->dvb.frontend = dvb_attach(s5h1409_attach, | 262 | port->dvb.frontend = dvb_attach(s5h1409_attach, |
263 | &hauppauge_hvr1800lp_config, | 263 | &hauppauge_hvr1800lp_config, |
264 | &i2c_bus->i2c_adap); | 264 | &i2c_bus->i2c_adap); |
265 | if (port->dvb.frontend != NULL) { | 265 | if (port->dvb.frontend != NULL) { |
266 | dvb_attach(mt2131_attach, port->dvb.frontend, | 266 | dvb_attach(mt2131_attach, port->dvb.frontend, |
267 | &i2c_bus->i2c_adap, | 267 | &i2c_bus->i2c_adap, |
268 | &hauppauge_generic_tunerconfig, 0); | 268 | &hauppauge_generic_tunerconfig, 0); |
269 | } | 269 | } |
270 | break; | 270 | break; |
271 | case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: | 271 | case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: |
272 | i2c_bus = &dev->i2c_bus[0]; | 272 | i2c_bus = &dev->i2c_bus[0]; |
273 | port->dvb.frontend = dvb_attach(lgdt330x_attach, | 273 | port->dvb.frontend = dvb_attach(lgdt330x_attach, |
274 | &fusionhdtv_5_express, | 274 | &fusionhdtv_5_express, |
275 | &i2c_bus->i2c_adap); | 275 | &i2c_bus->i2c_adap); |
276 | if (port->dvb.frontend != NULL) { | 276 | if (port->dvb.frontend != NULL) { |
277 | dvb_attach(simple_tuner_attach, port->dvb.frontend, | 277 | dvb_attach(simple_tuner_attach, port->dvb.frontend, |
278 | &i2c_bus->i2c_adap, 0x61, | 278 | &i2c_bus->i2c_adap, 0x61, |
279 | TUNER_LG_TDVS_H06XF); | 279 | TUNER_LG_TDVS_H06XF); |
280 | } | 280 | } |
281 | break; | 281 | break; |
282 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 282 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
283 | i2c_bus = &dev->i2c_bus[1]; | 283 | i2c_bus = &dev->i2c_bus[1]; |
284 | port->dvb.frontend = dvb_attach(s5h1409_attach, | 284 | port->dvb.frontend = dvb_attach(s5h1409_attach, |
285 | &hauppauge_hvr1500q_config, | 285 | &hauppauge_hvr1500q_config, |
286 | &dev->i2c_bus[0].i2c_adap); | 286 | &dev->i2c_bus[0].i2c_adap); |
287 | if (port->dvb.frontend != NULL) { | 287 | if (port->dvb.frontend != NULL) { |
288 | hauppauge_hvr1500q_tunerconfig.priv = i2c_bus; | 288 | hauppauge_hvr1500q_tunerconfig.priv = i2c_bus; |
289 | dvb_attach(xc5000_attach, port->dvb.frontend, | 289 | dvb_attach(xc5000_attach, port->dvb.frontend, |
290 | &i2c_bus->i2c_adap, | 290 | &i2c_bus->i2c_adap, |
291 | &hauppauge_hvr1500q_tunerconfig); | 291 | &hauppauge_hvr1500q_tunerconfig); |
292 | } | 292 | } |
293 | break; | 293 | break; |
294 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 294 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
295 | i2c_bus = &dev->i2c_bus[1]; | 295 | i2c_bus = &dev->i2c_bus[1]; |
296 | port->dvb.frontend = dvb_attach(s5h1409_attach, | 296 | port->dvb.frontend = dvb_attach(s5h1409_attach, |
297 | &hauppauge_hvr1500_config, | 297 | &hauppauge_hvr1500_config, |
298 | &dev->i2c_bus[0].i2c_adap); | 298 | &dev->i2c_bus[0].i2c_adap); |
299 | if (port->dvb.frontend != NULL) { | 299 | if (port->dvb.frontend != NULL) { |
300 | struct dvb_frontend *fe; | 300 | struct dvb_frontend *fe; |
301 | struct xc2028_config cfg = { | 301 | struct xc2028_config cfg = { |
302 | .i2c_adap = &i2c_bus->i2c_adap, | 302 | .i2c_adap = &i2c_bus->i2c_adap, |
303 | .i2c_addr = 0x61, | 303 | .i2c_addr = 0x61, |
304 | .callback = cx23885_hvr1500_xc3028_callback, | 304 | .callback = cx23885_hvr1500_xc3028_callback, |
305 | }; | 305 | }; |
306 | static struct xc2028_ctrl ctl = { | 306 | static struct xc2028_ctrl ctl = { |
307 | .fname = "xc3028-v27.fw", | 307 | .fname = "xc3028-v27.fw", |
308 | .max_len = 64, | 308 | .max_len = 64, |
309 | .scode_table = OREN538, | 309 | .scode_table = OREN538, |
310 | }; | 310 | }; |
311 | 311 | ||
312 | fe = dvb_attach(xc2028_attach, | 312 | fe = dvb_attach(xc2028_attach, |
313 | port->dvb.frontend, &cfg); | 313 | port->dvb.frontend, &cfg); |
314 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | 314 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) |
315 | fe->ops.tuner_ops.set_config(fe, &ctl); | 315 | fe->ops.tuner_ops.set_config(fe, &ctl); |
316 | } | 316 | } |
317 | break; | 317 | break; |
318 | default: | 318 | default: |
319 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", | 319 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", |
320 | dev->name); | 320 | dev->name); |
321 | break; | 321 | break; |
322 | } | 322 | } |
323 | if (NULL == port->dvb.frontend) { | 323 | if (NULL == port->dvb.frontend) { |
324 | printk("%s: frontend initialization failed\n", dev->name); | 324 | printk("%s: frontend initialization failed\n", dev->name); |
325 | return -1; | 325 | return -1; |
326 | } | 326 | } |
327 | 327 | ||
328 | /* Put the analog decoder in standby to keep it quiet */ | 328 | /* Put the analog decoder in standby to keep it quiet */ |
329 | cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); | 329 | cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); |
330 | 330 | ||
331 | if (port->dvb.frontend->ops.analog_ops.standby) | 331 | if (port->dvb.frontend->ops.analog_ops.standby) |
332 | port->dvb.frontend->ops.analog_ops.standby(port->dvb.frontend); | 332 | port->dvb.frontend->ops.analog_ops.standby(port->dvb.frontend); |
333 | 333 | ||
334 | /* register everything */ | 334 | /* register everything */ |
335 | return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, | 335 | return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, |
336 | &dev->pci->dev); | 336 | &dev->pci->dev); |
337 | } | 337 | } |
338 | 338 | ||
339 | int cx23885_dvb_register(struct cx23885_tsport *port) | 339 | int cx23885_dvb_register(struct cx23885_tsport *port) |
340 | { | 340 | { |
341 | struct cx23885_dev *dev = port->dev; | 341 | struct cx23885_dev *dev = port->dev; |
342 | int err; | 342 | int err; |
343 | 343 | ||
344 | dprintk(1, "%s\n", __FUNCTION__); | 344 | dprintk(1, "%s\n", __func__); |
345 | dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", | 345 | dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", |
346 | dev->board, | 346 | dev->board, |
347 | dev->name, | 347 | dev->name, |
348 | dev->pci_bus, | 348 | dev->pci_bus, |
349 | dev->pci_slot); | 349 | dev->pci_slot); |
350 | 350 | ||
351 | err = -ENODEV; | 351 | err = -ENODEV; |
352 | 352 | ||
353 | /* dvb stuff */ | 353 | /* dvb stuff */ |
354 | printk("%s: cx23885 based dvb card\n", dev->name); | 354 | printk("%s: cx23885 based dvb card\n", dev->name); |
355 | videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, | 355 | videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, |
356 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, | 356 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, |
357 | sizeof(struct cx23885_buffer), port); | 357 | sizeof(struct cx23885_buffer), port); |
358 | err = dvb_register(port); | 358 | err = dvb_register(port); |
359 | if (err != 0) | 359 | if (err != 0) |
360 | printk("%s() dvb_register failed err = %d\n", __FUNCTION__, err); | 360 | printk("%s() dvb_register failed err = %d\n", __func__, err); |
361 | 361 | ||
362 | return err; | 362 | return err; |
363 | } | 363 | } |
364 | 364 | ||
365 | int cx23885_dvb_unregister(struct cx23885_tsport *port) | 365 | int cx23885_dvb_unregister(struct cx23885_tsport *port) |
366 | { | 366 | { |
367 | /* dvb */ | 367 | /* dvb */ |
368 | if(port->dvb.frontend) | 368 | if(port->dvb.frontend) |
369 | videobuf_dvb_unregister(&port->dvb); | 369 | videobuf_dvb_unregister(&port->dvb); |
370 | 370 | ||
371 | return 0; | 371 | return 0; |
372 | } | 372 | } |
373 | 373 | ||
374 | /* | 374 | /* |
375 | * Local variables: | 375 | * Local variables: |
376 | * c-basic-offset: 8 | 376 | * c-basic-offset: 8 |
377 | * End: | 377 | * End: |
378 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off | 378 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off |
379 | */ | 379 | */ |
380 | 380 |
drivers/media/video/cx23885/cx23885-i2c.c
1 | /* | 1 | /* |
2 | * Driver for the Conexant CX23885 PCIe bridge | 2 | * Driver for the Conexant CX23885 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> | 4 | * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> |
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 <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/moduleparam.h> | 23 | #include <linux/moduleparam.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | 27 | ||
28 | #include "cx23885.h" | 28 | #include "cx23885.h" |
29 | 29 | ||
30 | #include <media/v4l2-common.h> | 30 | #include <media/v4l2-common.h> |
31 | 31 | ||
32 | static unsigned int i2c_debug; | 32 | static unsigned int i2c_debug; |
33 | module_param(i2c_debug, int, 0644); | 33 | module_param(i2c_debug, int, 0644); |
34 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | 34 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); |
35 | 35 | ||
36 | static unsigned int i2c_scan; | 36 | static unsigned int i2c_scan; |
37 | module_param(i2c_scan, int, 0444); | 37 | module_param(i2c_scan, int, 0444); |
38 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); | 38 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); |
39 | 39 | ||
40 | #define dprintk(level, fmt, arg...)\ | 40 | #define dprintk(level, fmt, arg...)\ |
41 | do { if (i2c_debug >= level)\ | 41 | do { if (i2c_debug >= level)\ |
42 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ | 42 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ |
43 | } while (0) | 43 | } while (0) |
44 | 44 | ||
45 | #define I2C_WAIT_DELAY 32 | 45 | #define I2C_WAIT_DELAY 32 |
46 | #define I2C_WAIT_RETRY 64 | 46 | #define I2C_WAIT_RETRY 64 |
47 | 47 | ||
48 | #define I2C_EXTEND (1 << 3) | 48 | #define I2C_EXTEND (1 << 3) |
49 | #define I2C_NOSTOP (1 << 4) | 49 | #define I2C_NOSTOP (1 << 4) |
50 | 50 | ||
51 | static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap) | 51 | static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap) |
52 | { | 52 | { |
53 | struct cx23885_i2c *bus = i2c_adap->algo_data; | 53 | struct cx23885_i2c *bus = i2c_adap->algo_data; |
54 | struct cx23885_dev *dev = bus->dev; | 54 | struct cx23885_dev *dev = bus->dev; |
55 | return cx_read(bus->reg_stat) & 0x01; | 55 | return cx_read(bus->reg_stat) & 0x01; |
56 | } | 56 | } |
57 | 57 | ||
58 | static inline int i2c_is_busy(struct i2c_adapter *i2c_adap) | 58 | static inline int i2c_is_busy(struct i2c_adapter *i2c_adap) |
59 | { | 59 | { |
60 | struct cx23885_i2c *bus = i2c_adap->algo_data; | 60 | struct cx23885_i2c *bus = i2c_adap->algo_data; |
61 | struct cx23885_dev *dev = bus->dev; | 61 | struct cx23885_dev *dev = bus->dev; |
62 | return cx_read(bus->reg_stat) & 0x02 ? 1 : 0; | 62 | return cx_read(bus->reg_stat) & 0x02 ? 1 : 0; |
63 | } | 63 | } |
64 | 64 | ||
65 | static int i2c_wait_done(struct i2c_adapter *i2c_adap) | 65 | static int i2c_wait_done(struct i2c_adapter *i2c_adap) |
66 | { | 66 | { |
67 | int count; | 67 | int count; |
68 | 68 | ||
69 | for (count = 0; count < I2C_WAIT_RETRY; count++) { | 69 | for (count = 0; count < I2C_WAIT_RETRY; count++) { |
70 | if (!i2c_is_busy(i2c_adap)) | 70 | if (!i2c_is_busy(i2c_adap)) |
71 | break; | 71 | break; |
72 | udelay(I2C_WAIT_DELAY); | 72 | udelay(I2C_WAIT_DELAY); |
73 | } | 73 | } |
74 | 74 | ||
75 | if (I2C_WAIT_RETRY == count) | 75 | if (I2C_WAIT_RETRY == count) |
76 | return 0; | 76 | return 0; |
77 | 77 | ||
78 | return 1; | 78 | return 1; |
79 | } | 79 | } |
80 | 80 | ||
81 | static int i2c_sendbytes(struct i2c_adapter *i2c_adap, | 81 | static int i2c_sendbytes(struct i2c_adapter *i2c_adap, |
82 | const struct i2c_msg *msg, int joined_rlen) | 82 | const struct i2c_msg *msg, int joined_rlen) |
83 | { | 83 | { |
84 | struct cx23885_i2c *bus = i2c_adap->algo_data; | 84 | struct cx23885_i2c *bus = i2c_adap->algo_data; |
85 | struct cx23885_dev *dev = bus->dev; | 85 | struct cx23885_dev *dev = bus->dev; |
86 | u32 wdata, addr, ctrl; | 86 | u32 wdata, addr, ctrl; |
87 | int retval, cnt; | 87 | int retval, cnt; |
88 | 88 | ||
89 | if (joined_rlen) | 89 | if (joined_rlen) |
90 | dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __FUNCTION__, | 90 | dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__, |
91 | msg->len, joined_rlen); | 91 | msg->len, joined_rlen); |
92 | else | 92 | else |
93 | dprintk(1, "%s(msg->len=%d)\n", __FUNCTION__, msg->len); | 93 | dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); |
94 | 94 | ||
95 | /* Deal with i2c probe functions with zero payload */ | 95 | /* Deal with i2c probe functions with zero payload */ |
96 | if (msg->len == 0) { | 96 | if (msg->len == 0) { |
97 | cx_write(bus->reg_addr, msg->addr << 25); | 97 | cx_write(bus->reg_addr, msg->addr << 25); |
98 | cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2)); | 98 | cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2)); |
99 | if (!i2c_wait_done(i2c_adap)) | 99 | if (!i2c_wait_done(i2c_adap)) |
100 | return -EIO; | 100 | return -EIO; |
101 | if (!i2c_slave_did_ack(i2c_adap)) | 101 | if (!i2c_slave_did_ack(i2c_adap)) |
102 | return -EIO; | 102 | return -EIO; |
103 | 103 | ||
104 | dprintk(1, "%s() returns 0\n", __FUNCTION__); | 104 | dprintk(1, "%s() returns 0\n", __func__); |
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | 107 | ||
108 | 108 | ||
109 | /* dev, reg + first byte */ | 109 | /* dev, reg + first byte */ |
110 | addr = (msg->addr << 25) | msg->buf[0]; | 110 | addr = (msg->addr << 25) | msg->buf[0]; |
111 | wdata = msg->buf[0]; | 111 | wdata = msg->buf[0]; |
112 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2); | 112 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2); |
113 | 113 | ||
114 | if (msg->len > 1) | 114 | if (msg->len > 1) |
115 | ctrl |= I2C_NOSTOP | I2C_EXTEND; | 115 | ctrl |= I2C_NOSTOP | I2C_EXTEND; |
116 | else if (joined_rlen) | 116 | else if (joined_rlen) |
117 | ctrl |= I2C_NOSTOP; | 117 | ctrl |= I2C_NOSTOP; |
118 | 118 | ||
119 | cx_write(bus->reg_addr, addr); | 119 | cx_write(bus->reg_addr, addr); |
120 | cx_write(bus->reg_wdata, wdata); | 120 | cx_write(bus->reg_wdata, wdata); |
121 | cx_write(bus->reg_ctrl, ctrl); | 121 | cx_write(bus->reg_ctrl, ctrl); |
122 | 122 | ||
123 | retval = i2c_wait_done(i2c_adap); | 123 | retval = i2c_wait_done(i2c_adap); |
124 | if (retval < 0) | 124 | if (retval < 0) |
125 | goto err; | 125 | goto err; |
126 | if (retval == 0) | 126 | if (retval == 0) |
127 | goto eio; | 127 | goto eio; |
128 | if (i2c_debug) { | 128 | if (i2c_debug) { |
129 | printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]); | 129 | printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]); |
130 | if (!(ctrl & I2C_NOSTOP)) | 130 | if (!(ctrl & I2C_NOSTOP)) |
131 | printk(" >\n"); | 131 | printk(" >\n"); |
132 | } | 132 | } |
133 | 133 | ||
134 | for (cnt = 1; cnt < msg->len; cnt++ ) { | 134 | for (cnt = 1; cnt < msg->len; cnt++ ) { |
135 | /* following bytes */ | 135 | /* following bytes */ |
136 | wdata = msg->buf[cnt]; | 136 | wdata = msg->buf[cnt]; |
137 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2); | 137 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2); |
138 | 138 | ||
139 | if (cnt < msg->len - 1) | 139 | if (cnt < msg->len - 1) |
140 | ctrl |= I2C_NOSTOP | I2C_EXTEND; | 140 | ctrl |= I2C_NOSTOP | I2C_EXTEND; |
141 | else if (joined_rlen) | 141 | else if (joined_rlen) |
142 | ctrl |= I2C_NOSTOP; | 142 | ctrl |= I2C_NOSTOP; |
143 | 143 | ||
144 | cx_write(bus->reg_addr, addr); | 144 | cx_write(bus->reg_addr, addr); |
145 | cx_write(bus->reg_wdata, wdata); | 145 | cx_write(bus->reg_wdata, wdata); |
146 | cx_write(bus->reg_ctrl, ctrl); | 146 | cx_write(bus->reg_ctrl, ctrl); |
147 | 147 | ||
148 | retval = i2c_wait_done(i2c_adap); | 148 | retval = i2c_wait_done(i2c_adap); |
149 | if (retval < 0) | 149 | if (retval < 0) |
150 | goto err; | 150 | goto err; |
151 | if (retval == 0) | 151 | if (retval == 0) |
152 | goto eio; | 152 | goto eio; |
153 | if (i2c_debug) { | 153 | if (i2c_debug) { |
154 | printk(" %02x", msg->buf[cnt]); | 154 | printk(" %02x", msg->buf[cnt]); |
155 | if (!(ctrl & I2C_NOSTOP)) | 155 | if (!(ctrl & I2C_NOSTOP)) |
156 | printk(" >\n"); | 156 | printk(" >\n"); |
157 | } | 157 | } |
158 | } | 158 | } |
159 | return msg->len; | 159 | return msg->len; |
160 | 160 | ||
161 | eio: | 161 | eio: |
162 | retval = -EIO; | 162 | retval = -EIO; |
163 | err: | 163 | err: |
164 | if (i2c_debug) | 164 | if (i2c_debug) |
165 | printk(" ERR: %d\n", retval); | 165 | printk(" ERR: %d\n", retval); |
166 | return retval; | 166 | return retval; |
167 | } | 167 | } |
168 | 168 | ||
169 | static int i2c_readbytes(struct i2c_adapter *i2c_adap, | 169 | static int i2c_readbytes(struct i2c_adapter *i2c_adap, |
170 | const struct i2c_msg *msg, int joined) | 170 | const struct i2c_msg *msg, int joined) |
171 | { | 171 | { |
172 | struct cx23885_i2c *bus = i2c_adap->algo_data; | 172 | struct cx23885_i2c *bus = i2c_adap->algo_data; |
173 | struct cx23885_dev *dev = bus->dev; | 173 | struct cx23885_dev *dev = bus->dev; |
174 | u32 ctrl, cnt; | 174 | u32 ctrl, cnt; |
175 | int retval; | 175 | int retval; |
176 | 176 | ||
177 | 177 | ||
178 | if (i2c_debug && !joined) | 178 | if (i2c_debug && !joined) |
179 | dprintk(1, "%s(msg->len=%d)\n", __FUNCTION__, msg->len); | 179 | dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); |
180 | 180 | ||
181 | /* Deal with i2c probe functions with zero payload */ | 181 | /* Deal with i2c probe functions with zero payload */ |
182 | if (msg->len == 0) { | 182 | if (msg->len == 0) { |
183 | cx_write(bus->reg_addr, msg->addr << 25); | 183 | cx_write(bus->reg_addr, msg->addr << 25); |
184 | cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1); | 184 | cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1); |
185 | if (!i2c_wait_done(i2c_adap)) | 185 | if (!i2c_wait_done(i2c_adap)) |
186 | return -EIO; | 186 | return -EIO; |
187 | if (!i2c_slave_did_ack(i2c_adap)) | 187 | if (!i2c_slave_did_ack(i2c_adap)) |
188 | return -EIO; | 188 | return -EIO; |
189 | 189 | ||
190 | 190 | ||
191 | dprintk(1, "%s() returns 0\n", __FUNCTION__); | 191 | dprintk(1, "%s() returns 0\n", __func__); |
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | 194 | ||
195 | if (i2c_debug) { | 195 | if (i2c_debug) { |
196 | if (joined) | 196 | if (joined) |
197 | printk(" R"); | 197 | printk(" R"); |
198 | else | 198 | else |
199 | printk(" <R %02x", (msg->addr << 1) + 1); | 199 | printk(" <R %02x", (msg->addr << 1) + 1); |
200 | } | 200 | } |
201 | 201 | ||
202 | for(cnt = 0; cnt < msg->len; cnt++) { | 202 | for(cnt = 0; cnt < msg->len; cnt++) { |
203 | 203 | ||
204 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1; | 204 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1; |
205 | 205 | ||
206 | if (cnt < msg->len - 1) | 206 | if (cnt < msg->len - 1) |
207 | ctrl |= I2C_NOSTOP | I2C_EXTEND; | 207 | ctrl |= I2C_NOSTOP | I2C_EXTEND; |
208 | 208 | ||
209 | cx_write(bus->reg_addr, msg->addr << 25); | 209 | cx_write(bus->reg_addr, msg->addr << 25); |
210 | cx_write(bus->reg_ctrl, ctrl); | 210 | cx_write(bus->reg_ctrl, ctrl); |
211 | 211 | ||
212 | retval = i2c_wait_done(i2c_adap); | 212 | retval = i2c_wait_done(i2c_adap); |
213 | if (retval < 0) | 213 | if (retval < 0) |
214 | goto err; | 214 | goto err; |
215 | if (retval == 0) | 215 | if (retval == 0) |
216 | goto eio; | 216 | goto eio; |
217 | msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; | 217 | msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; |
218 | if (i2c_debug) { | 218 | if (i2c_debug) { |
219 | printk(" %02x", msg->buf[cnt]); | 219 | printk(" %02x", msg->buf[cnt]); |
220 | if (!(ctrl & I2C_NOSTOP)) | 220 | if (!(ctrl & I2C_NOSTOP)) |
221 | printk(" >\n"); | 221 | printk(" >\n"); |
222 | } | 222 | } |
223 | } | 223 | } |
224 | return msg->len; | 224 | return msg->len; |
225 | 225 | ||
226 | eio: | 226 | eio: |
227 | retval = -EIO; | 227 | retval = -EIO; |
228 | err: | 228 | err: |
229 | if (i2c_debug) | 229 | if (i2c_debug) |
230 | printk(" ERR: %d\n", retval); | 230 | printk(" ERR: %d\n", retval); |
231 | return retval; | 231 | return retval; |
232 | } | 232 | } |
233 | 233 | ||
234 | static int i2c_xfer(struct i2c_adapter *i2c_adap, | 234 | static int i2c_xfer(struct i2c_adapter *i2c_adap, |
235 | struct i2c_msg *msgs, int num) | 235 | struct i2c_msg *msgs, int num) |
236 | { | 236 | { |
237 | struct cx23885_i2c *bus = i2c_adap->algo_data; | 237 | struct cx23885_i2c *bus = i2c_adap->algo_data; |
238 | struct cx23885_dev *dev = bus->dev; | 238 | struct cx23885_dev *dev = bus->dev; |
239 | int i, retval = 0; | 239 | int i, retval = 0; |
240 | 240 | ||
241 | dprintk(1, "%s(num = %d)\n", __FUNCTION__, num); | 241 | dprintk(1, "%s(num = %d)\n", __func__, num); |
242 | 242 | ||
243 | for (i = 0 ; i < num; i++) { | 243 | for (i = 0 ; i < num; i++) { |
244 | dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n", | 244 | dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n", |
245 | __FUNCTION__, num, msgs[i].addr, msgs[i].len); | 245 | __func__, num, msgs[i].addr, msgs[i].len); |
246 | if (msgs[i].flags & I2C_M_RD) { | 246 | if (msgs[i].flags & I2C_M_RD) { |
247 | /* read */ | 247 | /* read */ |
248 | retval = i2c_readbytes(i2c_adap, &msgs[i], 0); | 248 | retval = i2c_readbytes(i2c_adap, &msgs[i], 0); |
249 | } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && | 249 | } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && |
250 | msgs[i].addr == msgs[i + 1].addr) { | 250 | msgs[i].addr == msgs[i + 1].addr) { |
251 | /* write then read from same address */ | 251 | /* write then read from same address */ |
252 | retval = i2c_sendbytes(i2c_adap, &msgs[i], | 252 | retval = i2c_sendbytes(i2c_adap, &msgs[i], |
253 | msgs[i + 1].len); | 253 | msgs[i + 1].len); |
254 | if (retval < 0) | 254 | if (retval < 0) |
255 | goto err; | 255 | goto err; |
256 | i++; | 256 | i++; |
257 | retval = i2c_readbytes(i2c_adap, &msgs[i], 1); | 257 | retval = i2c_readbytes(i2c_adap, &msgs[i], 1); |
258 | } else { | 258 | } else { |
259 | /* write */ | 259 | /* write */ |
260 | retval = i2c_sendbytes(i2c_adap, &msgs[i], 0); | 260 | retval = i2c_sendbytes(i2c_adap, &msgs[i], 0); |
261 | } | 261 | } |
262 | if (retval < 0) | 262 | if (retval < 0) |
263 | goto err; | 263 | goto err; |
264 | } | 264 | } |
265 | return num; | 265 | return num; |
266 | 266 | ||
267 | err: | 267 | err: |
268 | return retval; | 268 | return retval; |
269 | } | 269 | } |
270 | 270 | ||
271 | static int attach_inform(struct i2c_client *client) | 271 | static int attach_inform(struct i2c_client *client) |
272 | { | 272 | { |
273 | struct cx23885_i2c *bus = i2c_get_adapdata(client->adapter); | 273 | struct cx23885_i2c *bus = i2c_get_adapdata(client->adapter); |
274 | struct cx23885_dev *dev = bus->dev; | 274 | struct cx23885_dev *dev = bus->dev; |
275 | struct tuner_setup tun_setup; | 275 | struct tuner_setup tun_setup; |
276 | 276 | ||
277 | dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", | 277 | dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", |
278 | client->driver->driver.name, client->addr, client->name); | 278 | client->driver->driver.name, client->addr, client->name); |
279 | 279 | ||
280 | if (!client->driver->command) | 280 | if (!client->driver->command) |
281 | return 0; | 281 | return 0; |
282 | 282 | ||
283 | if (dev->tuner_type != UNSET) { | 283 | if (dev->tuner_type != UNSET) { |
284 | 284 | ||
285 | dprintk(1, "%s (tuner) i2c attach [addr=0x%x,client=%s]\n", | 285 | dprintk(1, "%s (tuner) i2c attach [addr=0x%x,client=%s]\n", |
286 | client->driver->driver.name, client->addr, | 286 | client->driver->driver.name, client->addr, |
287 | client->name); | 287 | client->name); |
288 | 288 | ||
289 | if ((dev->tuner_addr == ADDR_UNSET) || | 289 | if ((dev->tuner_addr == ADDR_UNSET) || |
290 | (dev->tuner_addr == client->addr)) { | 290 | (dev->tuner_addr == client->addr)) { |
291 | 291 | ||
292 | dprintk(1, "%s (tuner || addr UNSET)\n", | 292 | dprintk(1, "%s (tuner || addr UNSET)\n", |
293 | client->driver->driver.name); | 293 | client->driver->driver.name); |
294 | 294 | ||
295 | dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", | 295 | dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", |
296 | client->driver->driver.name, | 296 | client->driver->driver.name, |
297 | client->addr, client->name); | 297 | client->addr, client->name); |
298 | 298 | ||
299 | tun_setup.mode_mask = T_ANALOG_TV; | 299 | tun_setup.mode_mask = T_ANALOG_TV; |
300 | tun_setup.type = dev->tuner_type; | 300 | tun_setup.type = dev->tuner_type; |
301 | tun_setup.addr = dev->tuner_addr; | 301 | tun_setup.addr = dev->tuner_addr; |
302 | 302 | ||
303 | client->driver->command(client, TUNER_SET_TYPE_ADDR, | 303 | client->driver->command(client, TUNER_SET_TYPE_ADDR, |
304 | &tun_setup); | 304 | &tun_setup); |
305 | } | 305 | } |
306 | } | 306 | } |
307 | 307 | ||
308 | return 0; | 308 | return 0; |
309 | } | 309 | } |
310 | 310 | ||
311 | static int detach_inform(struct i2c_client *client) | 311 | static int detach_inform(struct i2c_client *client) |
312 | { | 312 | { |
313 | struct cx23885_dev *dev = i2c_get_adapdata(client->adapter); | 313 | struct cx23885_dev *dev = i2c_get_adapdata(client->adapter); |
314 | 314 | ||
315 | dprintk(1, "i2c detach [client=%s]\n", client->name); | 315 | dprintk(1, "i2c detach [client=%s]\n", client->name); |
316 | 316 | ||
317 | return 0; | 317 | return 0; |
318 | } | 318 | } |
319 | 319 | ||
320 | void cx23885_call_i2c_clients(struct cx23885_i2c *bus, | 320 | void cx23885_call_i2c_clients(struct cx23885_i2c *bus, |
321 | unsigned int cmd, void *arg) | 321 | unsigned int cmd, void *arg) |
322 | { | 322 | { |
323 | if (bus->i2c_rc != 0) | 323 | if (bus->i2c_rc != 0) |
324 | return; | 324 | return; |
325 | 325 | ||
326 | i2c_clients_command(&bus->i2c_adap, cmd, arg); | 326 | i2c_clients_command(&bus->i2c_adap, cmd, arg); |
327 | } | 327 | } |
328 | 328 | ||
329 | static u32 cx23885_functionality(struct i2c_adapter *adap) | 329 | static u32 cx23885_functionality(struct i2c_adapter *adap) |
330 | { | 330 | { |
331 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; | 331 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; |
332 | } | 332 | } |
333 | 333 | ||
334 | static struct i2c_algorithm cx23885_i2c_algo_template = { | 334 | static struct i2c_algorithm cx23885_i2c_algo_template = { |
335 | .master_xfer = i2c_xfer, | 335 | .master_xfer = i2c_xfer, |
336 | .functionality = cx23885_functionality, | 336 | .functionality = cx23885_functionality, |
337 | }; | 337 | }; |
338 | 338 | ||
339 | /* ----------------------------------------------------------------------- */ | 339 | /* ----------------------------------------------------------------------- */ |
340 | 340 | ||
341 | static struct i2c_adapter cx23885_i2c_adap_template = { | 341 | static struct i2c_adapter cx23885_i2c_adap_template = { |
342 | .name = "cx23885", | 342 | .name = "cx23885", |
343 | .owner = THIS_MODULE, | 343 | .owner = THIS_MODULE, |
344 | .id = I2C_HW_B_CX23885, | 344 | .id = I2C_HW_B_CX23885, |
345 | .algo = &cx23885_i2c_algo_template, | 345 | .algo = &cx23885_i2c_algo_template, |
346 | .class = I2C_CLASS_TV_ANALOG, | 346 | .class = I2C_CLASS_TV_ANALOG, |
347 | .client_register = attach_inform, | 347 | .client_register = attach_inform, |
348 | .client_unregister = detach_inform, | 348 | .client_unregister = detach_inform, |
349 | }; | 349 | }; |
350 | 350 | ||
351 | static struct i2c_client cx23885_i2c_client_template = { | 351 | static struct i2c_client cx23885_i2c_client_template = { |
352 | .name = "cx23885 internal", | 352 | .name = "cx23885 internal", |
353 | }; | 353 | }; |
354 | 354 | ||
355 | static char *i2c_devs[128] = { | 355 | static char *i2c_devs[128] = { |
356 | [ 0x1c >> 1 ] = "lgdt3303", | 356 | [ 0x1c >> 1 ] = "lgdt3303", |
357 | [ 0x86 >> 1 ] = "tda9887", | 357 | [ 0x86 >> 1 ] = "tda9887", |
358 | [ 0x32 >> 1 ] = "cx24227", | 358 | [ 0x32 >> 1 ] = "cx24227", |
359 | [ 0x88 >> 1 ] = "cx25837", | 359 | [ 0x88 >> 1 ] = "cx25837", |
360 | [ 0x84 >> 1 ] = "tda8295", | 360 | [ 0x84 >> 1 ] = "tda8295", |
361 | [ 0xa0 >> 1 ] = "eeprom", | 361 | [ 0xa0 >> 1 ] = "eeprom", |
362 | [ 0xc0 >> 1 ] = "tuner/mt2131/tda8275", | 362 | [ 0xc0 >> 1 ] = "tuner/mt2131/tda8275", |
363 | [ 0xc2 >> 1 ] = "tuner/mt2131/tda8275/xc5000", | 363 | [ 0xc2 >> 1 ] = "tuner/mt2131/tda8275/xc5000", |
364 | }; | 364 | }; |
365 | 365 | ||
366 | static void do_i2c_scan(char *name, struct i2c_client *c) | 366 | static void do_i2c_scan(char *name, struct i2c_client *c) |
367 | { | 367 | { |
368 | unsigned char buf; | 368 | unsigned char buf; |
369 | int i, rc; | 369 | int i, rc; |
370 | 370 | ||
371 | for (i = 0; i < 128; i++) { | 371 | for (i = 0; i < 128; i++) { |
372 | c->addr = i; | 372 | c->addr = i; |
373 | rc = i2c_master_recv(c, &buf, 0); | 373 | rc = i2c_master_recv(c, &buf, 0); |
374 | if (rc < 0) | 374 | if (rc < 0) |
375 | continue; | 375 | continue; |
376 | printk("%s: i2c scan: found device @ 0x%x [%s]\n", | 376 | printk("%s: i2c scan: found device @ 0x%x [%s]\n", |
377 | name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); | 377 | name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); |
378 | } | 378 | } |
379 | } | 379 | } |
380 | 380 | ||
381 | /* init + register i2c algo-bit adapter */ | 381 | /* init + register i2c algo-bit adapter */ |
382 | int cx23885_i2c_register(struct cx23885_i2c *bus) | 382 | int cx23885_i2c_register(struct cx23885_i2c *bus) |
383 | { | 383 | { |
384 | struct cx23885_dev *dev = bus->dev; | 384 | struct cx23885_dev *dev = bus->dev; |
385 | 385 | ||
386 | dprintk(1, "%s(bus = %d)\n", __FUNCTION__, bus->nr); | 386 | dprintk(1, "%s(bus = %d)\n", __func__, bus->nr); |
387 | 387 | ||
388 | memcpy(&bus->i2c_adap, &cx23885_i2c_adap_template, | 388 | memcpy(&bus->i2c_adap, &cx23885_i2c_adap_template, |
389 | sizeof(bus->i2c_adap)); | 389 | sizeof(bus->i2c_adap)); |
390 | memcpy(&bus->i2c_algo, &cx23885_i2c_algo_template, | 390 | memcpy(&bus->i2c_algo, &cx23885_i2c_algo_template, |
391 | sizeof(bus->i2c_algo)); | 391 | sizeof(bus->i2c_algo)); |
392 | memcpy(&bus->i2c_client, &cx23885_i2c_client_template, | 392 | memcpy(&bus->i2c_client, &cx23885_i2c_client_template, |
393 | sizeof(bus->i2c_client)); | 393 | sizeof(bus->i2c_client)); |
394 | 394 | ||
395 | bus->i2c_adap.dev.parent = &dev->pci->dev; | 395 | bus->i2c_adap.dev.parent = &dev->pci->dev; |
396 | 396 | ||
397 | strlcpy(bus->i2c_adap.name, bus->dev->name, | 397 | strlcpy(bus->i2c_adap.name, bus->dev->name, |
398 | sizeof(bus->i2c_adap.name)); | 398 | sizeof(bus->i2c_adap.name)); |
399 | 399 | ||
400 | bus->i2c_algo.data = bus; | 400 | bus->i2c_algo.data = bus; |
401 | bus->i2c_adap.algo_data = bus; | 401 | bus->i2c_adap.algo_data = bus; |
402 | i2c_set_adapdata(&bus->i2c_adap, bus); | 402 | i2c_set_adapdata(&bus->i2c_adap, bus); |
403 | i2c_add_adapter(&bus->i2c_adap); | 403 | i2c_add_adapter(&bus->i2c_adap); |
404 | 404 | ||
405 | bus->i2c_client.adapter = &bus->i2c_adap; | 405 | bus->i2c_client.adapter = &bus->i2c_adap; |
406 | 406 | ||
407 | if (0 == bus->i2c_rc) { | 407 | if (0 == bus->i2c_rc) { |
408 | printk("%s: i2c bus %d registered\n", dev->name, bus->nr); | 408 | printk("%s: i2c bus %d registered\n", dev->name, bus->nr); |
409 | if (i2c_scan) | 409 | if (i2c_scan) |
410 | do_i2c_scan(dev->name, &bus->i2c_client); | 410 | do_i2c_scan(dev->name, &bus->i2c_client); |
411 | } else | 411 | } else |
412 | printk("%s: i2c bus %d register FAILED\n", dev->name, bus->nr); | 412 | printk("%s: i2c bus %d register FAILED\n", dev->name, bus->nr); |
413 | 413 | ||
414 | return bus->i2c_rc; | 414 | return bus->i2c_rc; |
415 | } | 415 | } |
416 | 416 | ||
417 | int cx23885_i2c_unregister(struct cx23885_i2c *bus) | 417 | int cx23885_i2c_unregister(struct cx23885_i2c *bus) |
418 | { | 418 | { |
419 | i2c_del_adapter(&bus->i2c_adap); | 419 | i2c_del_adapter(&bus->i2c_adap); |
420 | return 0; | 420 | return 0; |
421 | } | 421 | } |
422 | 422 | ||
423 | /* ----------------------------------------------------------------------- */ | 423 | /* ----------------------------------------------------------------------- */ |
424 | 424 | ||
425 | /* | 425 | /* |
426 | * Local variables: | 426 | * Local variables: |
427 | * c-basic-offset: 8 | 427 | * c-basic-offset: 8 |
428 | * End: | 428 | * End: |
429 | */ | 429 | */ |
430 | 430 |
drivers/media/video/cx23885/cx23885-video.c
1 | /* | 1 | /* |
2 | * Driver for the Conexant CX23885 PCIe bridge | 2 | * Driver for the Conexant CX23885 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> | 4 | * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> |
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 <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
26 | #include <linux/kmod.h> | 26 | #include <linux/kmod.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/kthread.h> | 31 | #include <linux/kthread.h> |
32 | #include <asm/div64.h> | 32 | #include <asm/div64.h> |
33 | 33 | ||
34 | #include "cx23885.h" | 34 | #include "cx23885.h" |
35 | #include <media/v4l2-common.h> | 35 | #include <media/v4l2-common.h> |
36 | 36 | ||
37 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 37 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
38 | /* Include V4L1 specific functions. Should be removed soon */ | 38 | /* Include V4L1 specific functions. Should be removed soon */ |
39 | #include <linux/videodev.h> | 39 | #include <linux/videodev.h> |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); | 42 | MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); |
43 | MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); | 43 | MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); |
44 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
45 | 45 | ||
46 | /* ------------------------------------------------------------------ */ | 46 | /* ------------------------------------------------------------------ */ |
47 | 47 | ||
48 | static unsigned int video_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; | 48 | static unsigned int video_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; |
49 | static unsigned int vbi_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; | 49 | static unsigned int vbi_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; |
50 | static unsigned int radio_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; | 50 | static unsigned int radio_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; |
51 | 51 | ||
52 | module_param_array(video_nr, int, NULL, 0444); | 52 | module_param_array(video_nr, int, NULL, 0444); |
53 | module_param_array(vbi_nr, int, NULL, 0444); | 53 | module_param_array(vbi_nr, int, NULL, 0444); |
54 | module_param_array(radio_nr, int, NULL, 0444); | 54 | module_param_array(radio_nr, int, NULL, 0444); |
55 | 55 | ||
56 | MODULE_PARM_DESC(video_nr, "video device numbers"); | 56 | MODULE_PARM_DESC(video_nr, "video device numbers"); |
57 | MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); | 57 | MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); |
58 | MODULE_PARM_DESC(radio_nr, "radio device numbers"); | 58 | MODULE_PARM_DESC(radio_nr, "radio device numbers"); |
59 | 59 | ||
60 | static unsigned int video_debug; | 60 | static unsigned int video_debug; |
61 | module_param(video_debug, int, 0644); | 61 | module_param(video_debug, int, 0644); |
62 | MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); | 62 | MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); |
63 | 63 | ||
64 | static unsigned int irq_debug; | 64 | static unsigned int irq_debug; |
65 | module_param(irq_debug, int, 0644); | 65 | module_param(irq_debug, int, 0644); |
66 | MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]"); | 66 | MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]"); |
67 | 67 | ||
68 | static unsigned int vid_limit = 16; | 68 | static unsigned int vid_limit = 16; |
69 | module_param(vid_limit, int, 0644); | 69 | module_param(vid_limit, int, 0644); |
70 | MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); | 70 | MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); |
71 | 71 | ||
72 | #define dprintk(level, fmt, arg...)\ | 72 | #define dprintk(level, fmt, arg...)\ |
73 | do { if (video_debug >= level)\ | 73 | do { if (video_debug >= level)\ |
74 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ | 74 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ |
75 | } while (0) | 75 | } while (0) |
76 | 76 | ||
77 | /* ------------------------------------------------------------------- */ | 77 | /* ------------------------------------------------------------------- */ |
78 | /* static data */ | 78 | /* static data */ |
79 | 79 | ||
80 | #define FORMAT_FLAGS_PACKED 0x01 | 80 | #define FORMAT_FLAGS_PACKED 0x01 |
81 | 81 | ||
82 | static struct cx23885_fmt formats[] = { | 82 | static struct cx23885_fmt formats[] = { |
83 | { | 83 | { |
84 | .name = "8 bpp, gray", | 84 | .name = "8 bpp, gray", |
85 | .fourcc = V4L2_PIX_FMT_GREY, | 85 | .fourcc = V4L2_PIX_FMT_GREY, |
86 | .depth = 8, | 86 | .depth = 8, |
87 | .flags = FORMAT_FLAGS_PACKED, | 87 | .flags = FORMAT_FLAGS_PACKED, |
88 | }, { | 88 | }, { |
89 | .name = "15 bpp RGB, le", | 89 | .name = "15 bpp RGB, le", |
90 | .fourcc = V4L2_PIX_FMT_RGB555, | 90 | .fourcc = V4L2_PIX_FMT_RGB555, |
91 | .depth = 16, | 91 | .depth = 16, |
92 | .flags = FORMAT_FLAGS_PACKED, | 92 | .flags = FORMAT_FLAGS_PACKED, |
93 | }, { | 93 | }, { |
94 | .name = "15 bpp RGB, be", | 94 | .name = "15 bpp RGB, be", |
95 | .fourcc = V4L2_PIX_FMT_RGB555X, | 95 | .fourcc = V4L2_PIX_FMT_RGB555X, |
96 | .depth = 16, | 96 | .depth = 16, |
97 | .flags = FORMAT_FLAGS_PACKED, | 97 | .flags = FORMAT_FLAGS_PACKED, |
98 | }, { | 98 | }, { |
99 | .name = "16 bpp RGB, le", | 99 | .name = "16 bpp RGB, le", |
100 | .fourcc = V4L2_PIX_FMT_RGB565, | 100 | .fourcc = V4L2_PIX_FMT_RGB565, |
101 | .depth = 16, | 101 | .depth = 16, |
102 | .flags = FORMAT_FLAGS_PACKED, | 102 | .flags = FORMAT_FLAGS_PACKED, |
103 | }, { | 103 | }, { |
104 | .name = "16 bpp RGB, be", | 104 | .name = "16 bpp RGB, be", |
105 | .fourcc = V4L2_PIX_FMT_RGB565X, | 105 | .fourcc = V4L2_PIX_FMT_RGB565X, |
106 | .depth = 16, | 106 | .depth = 16, |
107 | .flags = FORMAT_FLAGS_PACKED, | 107 | .flags = FORMAT_FLAGS_PACKED, |
108 | }, { | 108 | }, { |
109 | .name = "24 bpp RGB, le", | 109 | .name = "24 bpp RGB, le", |
110 | .fourcc = V4L2_PIX_FMT_BGR24, | 110 | .fourcc = V4L2_PIX_FMT_BGR24, |
111 | .depth = 24, | 111 | .depth = 24, |
112 | .flags = FORMAT_FLAGS_PACKED, | 112 | .flags = FORMAT_FLAGS_PACKED, |
113 | }, { | 113 | }, { |
114 | .name = "32 bpp RGB, le", | 114 | .name = "32 bpp RGB, le", |
115 | .fourcc = V4L2_PIX_FMT_BGR32, | 115 | .fourcc = V4L2_PIX_FMT_BGR32, |
116 | .depth = 32, | 116 | .depth = 32, |
117 | .flags = FORMAT_FLAGS_PACKED, | 117 | .flags = FORMAT_FLAGS_PACKED, |
118 | }, { | 118 | }, { |
119 | .name = "32 bpp RGB, be", | 119 | .name = "32 bpp RGB, be", |
120 | .fourcc = V4L2_PIX_FMT_RGB32, | 120 | .fourcc = V4L2_PIX_FMT_RGB32, |
121 | .depth = 32, | 121 | .depth = 32, |
122 | .flags = FORMAT_FLAGS_PACKED, | 122 | .flags = FORMAT_FLAGS_PACKED, |
123 | }, { | 123 | }, { |
124 | .name = "4:2:2, packed, YUYV", | 124 | .name = "4:2:2, packed, YUYV", |
125 | .fourcc = V4L2_PIX_FMT_YUYV, | 125 | .fourcc = V4L2_PIX_FMT_YUYV, |
126 | .depth = 16, | 126 | .depth = 16, |
127 | .flags = FORMAT_FLAGS_PACKED, | 127 | .flags = FORMAT_FLAGS_PACKED, |
128 | }, { | 128 | }, { |
129 | .name = "4:2:2, packed, UYVY", | 129 | .name = "4:2:2, packed, UYVY", |
130 | .fourcc = V4L2_PIX_FMT_UYVY, | 130 | .fourcc = V4L2_PIX_FMT_UYVY, |
131 | .depth = 16, | 131 | .depth = 16, |
132 | .flags = FORMAT_FLAGS_PACKED, | 132 | .flags = FORMAT_FLAGS_PACKED, |
133 | }, | 133 | }, |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc) | 136 | static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc) |
137 | { | 137 | { |
138 | unsigned int i; | 138 | unsigned int i; |
139 | 139 | ||
140 | for (i = 0; i < ARRAY_SIZE(formats); i++) | 140 | for (i = 0; i < ARRAY_SIZE(formats); i++) |
141 | if (formats[i].fourcc == fourcc) | 141 | if (formats[i].fourcc == fourcc) |
142 | return formats+i; | 142 | return formats+i; |
143 | 143 | ||
144 | printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __FUNCTION__, fourcc); | 144 | printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc); |
145 | return NULL; | 145 | return NULL; |
146 | } | 146 | } |
147 | 147 | ||
148 | /* ------------------------------------------------------------------- */ | 148 | /* ------------------------------------------------------------------- */ |
149 | 149 | ||
150 | static const struct v4l2_queryctrl no_ctl = { | 150 | static const struct v4l2_queryctrl no_ctl = { |
151 | .name = "42", | 151 | .name = "42", |
152 | .flags = V4L2_CTRL_FLAG_DISABLED, | 152 | .flags = V4L2_CTRL_FLAG_DISABLED, |
153 | }; | 153 | }; |
154 | 154 | ||
155 | static struct cx23885_ctrl cx23885_ctls[] = { | 155 | static struct cx23885_ctrl cx23885_ctls[] = { |
156 | /* --- video --- */ | 156 | /* --- video --- */ |
157 | { | 157 | { |
158 | .v = { | 158 | .v = { |
159 | .id = V4L2_CID_BRIGHTNESS, | 159 | .id = V4L2_CID_BRIGHTNESS, |
160 | .name = "Brightness", | 160 | .name = "Brightness", |
161 | .minimum = 0x00, | 161 | .minimum = 0x00, |
162 | .maximum = 0xff, | 162 | .maximum = 0xff, |
163 | .step = 1, | 163 | .step = 1, |
164 | .default_value = 0x7f, | 164 | .default_value = 0x7f, |
165 | .type = V4L2_CTRL_TYPE_INTEGER, | 165 | .type = V4L2_CTRL_TYPE_INTEGER, |
166 | }, | 166 | }, |
167 | .off = 128, | 167 | .off = 128, |
168 | .reg = LUMA_CTRL, | 168 | .reg = LUMA_CTRL, |
169 | .mask = 0x00ff, | 169 | .mask = 0x00ff, |
170 | .shift = 0, | 170 | .shift = 0, |
171 | }, { | 171 | }, { |
172 | .v = { | 172 | .v = { |
173 | .id = V4L2_CID_CONTRAST, | 173 | .id = V4L2_CID_CONTRAST, |
174 | .name = "Contrast", | 174 | .name = "Contrast", |
175 | .minimum = 0, | 175 | .minimum = 0, |
176 | .maximum = 0xff, | 176 | .maximum = 0xff, |
177 | .step = 1, | 177 | .step = 1, |
178 | .default_value = 0x3f, | 178 | .default_value = 0x3f, |
179 | .type = V4L2_CTRL_TYPE_INTEGER, | 179 | .type = V4L2_CTRL_TYPE_INTEGER, |
180 | }, | 180 | }, |
181 | .off = 0, | 181 | .off = 0, |
182 | .reg = LUMA_CTRL, | 182 | .reg = LUMA_CTRL, |
183 | .mask = 0xff00, | 183 | .mask = 0xff00, |
184 | .shift = 8, | 184 | .shift = 8, |
185 | }, { | 185 | }, { |
186 | .v = { | 186 | .v = { |
187 | .id = V4L2_CID_HUE, | 187 | .id = V4L2_CID_HUE, |
188 | .name = "Hue", | 188 | .name = "Hue", |
189 | .minimum = 0, | 189 | .minimum = 0, |
190 | .maximum = 0xff, | 190 | .maximum = 0xff, |
191 | .step = 1, | 191 | .step = 1, |
192 | .default_value = 0x7f, | 192 | .default_value = 0x7f, |
193 | .type = V4L2_CTRL_TYPE_INTEGER, | 193 | .type = V4L2_CTRL_TYPE_INTEGER, |
194 | }, | 194 | }, |
195 | .off = 128, | 195 | .off = 128, |
196 | .reg = CHROMA_CTRL, | 196 | .reg = CHROMA_CTRL, |
197 | .mask = 0xff0000, | 197 | .mask = 0xff0000, |
198 | .shift = 16, | 198 | .shift = 16, |
199 | }, { | 199 | }, { |
200 | /* strictly, this only describes only U saturation. | 200 | /* strictly, this only describes only U saturation. |
201 | * V saturation is handled specially through code. | 201 | * V saturation is handled specially through code. |
202 | */ | 202 | */ |
203 | .v = { | 203 | .v = { |
204 | .id = V4L2_CID_SATURATION, | 204 | .id = V4L2_CID_SATURATION, |
205 | .name = "Saturation", | 205 | .name = "Saturation", |
206 | .minimum = 0, | 206 | .minimum = 0, |
207 | .maximum = 0xff, | 207 | .maximum = 0xff, |
208 | .step = 1, | 208 | .step = 1, |
209 | .default_value = 0x7f, | 209 | .default_value = 0x7f, |
210 | .type = V4L2_CTRL_TYPE_INTEGER, | 210 | .type = V4L2_CTRL_TYPE_INTEGER, |
211 | }, | 211 | }, |
212 | .off = 0, | 212 | .off = 0, |
213 | .reg = CHROMA_CTRL, | 213 | .reg = CHROMA_CTRL, |
214 | .mask = 0x00ff, | 214 | .mask = 0x00ff, |
215 | .shift = 0, | 215 | .shift = 0, |
216 | }, { | 216 | }, { |
217 | /* --- audio --- */ | 217 | /* --- audio --- */ |
218 | .v = { | 218 | .v = { |
219 | .id = V4L2_CID_AUDIO_MUTE, | 219 | .id = V4L2_CID_AUDIO_MUTE, |
220 | .name = "Mute", | 220 | .name = "Mute", |
221 | .minimum = 0, | 221 | .minimum = 0, |
222 | .maximum = 1, | 222 | .maximum = 1, |
223 | .default_value = 1, | 223 | .default_value = 1, |
224 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 224 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
225 | }, | 225 | }, |
226 | .reg = PATH1_CTL1, | 226 | .reg = PATH1_CTL1, |
227 | .mask = (0x1f << 24), | 227 | .mask = (0x1f << 24), |
228 | .shift = 24, | 228 | .shift = 24, |
229 | }, { | 229 | }, { |
230 | .v = { | 230 | .v = { |
231 | .id = V4L2_CID_AUDIO_VOLUME, | 231 | .id = V4L2_CID_AUDIO_VOLUME, |
232 | .name = "Volume", | 232 | .name = "Volume", |
233 | .minimum = 0, | 233 | .minimum = 0, |
234 | .maximum = 0x3f, | 234 | .maximum = 0x3f, |
235 | .step = 1, | 235 | .step = 1, |
236 | .default_value = 0x3f, | 236 | .default_value = 0x3f, |
237 | .type = V4L2_CTRL_TYPE_INTEGER, | 237 | .type = V4L2_CTRL_TYPE_INTEGER, |
238 | }, | 238 | }, |
239 | .reg = PATH1_VOL_CTL, | 239 | .reg = PATH1_VOL_CTL, |
240 | .mask = 0xff, | 240 | .mask = 0xff, |
241 | .shift = 0, | 241 | .shift = 0, |
242 | } | 242 | } |
243 | }; | 243 | }; |
244 | static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls); | 244 | static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls); |
245 | 245 | ||
246 | const u32 cx23885_user_ctrls[] = { | 246 | const u32 cx23885_user_ctrls[] = { |
247 | V4L2_CID_USER_CLASS, | 247 | V4L2_CID_USER_CLASS, |
248 | V4L2_CID_BRIGHTNESS, | 248 | V4L2_CID_BRIGHTNESS, |
249 | V4L2_CID_CONTRAST, | 249 | V4L2_CID_CONTRAST, |
250 | V4L2_CID_SATURATION, | 250 | V4L2_CID_SATURATION, |
251 | V4L2_CID_HUE, | 251 | V4L2_CID_HUE, |
252 | V4L2_CID_AUDIO_VOLUME, | 252 | V4L2_CID_AUDIO_VOLUME, |
253 | V4L2_CID_AUDIO_MUTE, | 253 | V4L2_CID_AUDIO_MUTE, |
254 | 0 | 254 | 0 |
255 | }; | 255 | }; |
256 | EXPORT_SYMBOL(cx23885_user_ctrls); | 256 | EXPORT_SYMBOL(cx23885_user_ctrls); |
257 | 257 | ||
258 | static const u32 *ctrl_classes[] = { | 258 | static const u32 *ctrl_classes[] = { |
259 | cx23885_user_ctrls, | 259 | cx23885_user_ctrls, |
260 | NULL | 260 | NULL |
261 | }; | 261 | }; |
262 | 262 | ||
263 | void cx23885_video_wakeup(struct cx23885_dev *dev, | 263 | void cx23885_video_wakeup(struct cx23885_dev *dev, |
264 | struct cx23885_dmaqueue *q, u32 count) | 264 | struct cx23885_dmaqueue *q, u32 count) |
265 | { | 265 | { |
266 | struct cx23885_buffer *buf; | 266 | struct cx23885_buffer *buf; |
267 | int bc; | 267 | int bc; |
268 | 268 | ||
269 | for (bc = 0;; bc++) { | 269 | for (bc = 0;; bc++) { |
270 | if (list_empty(&q->active)) | 270 | if (list_empty(&q->active)) |
271 | break; | 271 | break; |
272 | buf = list_entry(q->active.next, | 272 | buf = list_entry(q->active.next, |
273 | struct cx23885_buffer, vb.queue); | 273 | struct cx23885_buffer, vb.queue); |
274 | 274 | ||
275 | /* count comes from the hw and is is 16bit wide -- | 275 | /* count comes from the hw and is is 16bit wide -- |
276 | * this trick handles wrap-arounds correctly for | 276 | * this trick handles wrap-arounds correctly for |
277 | * up to 32767 buffers in flight... */ | 277 | * up to 32767 buffers in flight... */ |
278 | if ((s16) (count - buf->count) < 0) | 278 | if ((s16) (count - buf->count) < 0) |
279 | break; | 279 | break; |
280 | 280 | ||
281 | do_gettimeofday(&buf->vb.ts); | 281 | do_gettimeofday(&buf->vb.ts); |
282 | dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, | 282 | dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, |
283 | count, buf->count); | 283 | count, buf->count); |
284 | buf->vb.state = VIDEOBUF_DONE; | 284 | buf->vb.state = VIDEOBUF_DONE; |
285 | list_del(&buf->vb.queue); | 285 | list_del(&buf->vb.queue); |
286 | wake_up(&buf->vb.done); | 286 | wake_up(&buf->vb.done); |
287 | } | 287 | } |
288 | if (list_empty(&q->active)) { | 288 | if (list_empty(&q->active)) { |
289 | del_timer(&q->timeout); | 289 | del_timer(&q->timeout); |
290 | } else { | 290 | } else { |
291 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | 291 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); |
292 | } | 292 | } |
293 | if (bc != 1) | 293 | if (bc != 1) |
294 | printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", | 294 | printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", |
295 | __FUNCTION__, bc); | 295 | __func__, bc); |
296 | } | 296 | } |
297 | 297 | ||
298 | int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) | 298 | int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) |
299 | { | 299 | { |
300 | dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", | 300 | dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", |
301 | __FUNCTION__, | 301 | __func__, |
302 | (unsigned int)norm, | 302 | (unsigned int)norm, |
303 | v4l2_norm_to_name(norm)); | 303 | v4l2_norm_to_name(norm)); |
304 | 304 | ||
305 | dev->tvnorm = norm; | 305 | dev->tvnorm = norm; |
306 | 306 | ||
307 | /* Tell the analog tuner/demods */ | 307 | /* Tell the analog tuner/demods */ |
308 | cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, &norm); | 308 | cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, &norm); |
309 | 309 | ||
310 | /* Tell the internal A/V decoder */ | 310 | /* Tell the internal A/V decoder */ |
311 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_STD, &norm); | 311 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_STD, &norm); |
312 | 312 | ||
313 | return 0; | 313 | return 0; |
314 | } | 314 | } |
315 | 315 | ||
316 | struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, | 316 | struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, |
317 | struct pci_dev *pci, | 317 | struct pci_dev *pci, |
318 | struct video_device *template, | 318 | struct video_device *template, |
319 | char *type) | 319 | char *type) |
320 | { | 320 | { |
321 | struct video_device *vfd; | 321 | struct video_device *vfd; |
322 | dprintk(1, "%s()\n", __FUNCTION__); | 322 | dprintk(1, "%s()\n", __func__); |
323 | 323 | ||
324 | vfd = video_device_alloc(); | 324 | vfd = video_device_alloc(); |
325 | if (NULL == vfd) | 325 | if (NULL == vfd) |
326 | return NULL; | 326 | return NULL; |
327 | *vfd = *template; | 327 | *vfd = *template; |
328 | vfd->minor = -1; | 328 | vfd->minor = -1; |
329 | vfd->dev = &pci->dev; | 329 | vfd->dev = &pci->dev; |
330 | vfd->release = video_device_release; | 330 | vfd->release = video_device_release; |
331 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", | 331 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", |
332 | dev->name, type, cx23885_boards[dev->board].name); | 332 | dev->name, type, cx23885_boards[dev->board].name); |
333 | return vfd; | 333 | return vfd; |
334 | } | 334 | } |
335 | 335 | ||
336 | int cx23885_ctrl_query(struct v4l2_queryctrl *qctrl) | 336 | int cx23885_ctrl_query(struct v4l2_queryctrl *qctrl) |
337 | { | 337 | { |
338 | int i; | 338 | int i; |
339 | 339 | ||
340 | if (qctrl->id < V4L2_CID_BASE || | 340 | if (qctrl->id < V4L2_CID_BASE || |
341 | qctrl->id >= V4L2_CID_LASTP1) | 341 | qctrl->id >= V4L2_CID_LASTP1) |
342 | return -EINVAL; | 342 | return -EINVAL; |
343 | for (i = 0; i < CX23885_CTLS; i++) | 343 | for (i = 0; i < CX23885_CTLS; i++) |
344 | if (cx23885_ctls[i].v.id == qctrl->id) | 344 | if (cx23885_ctls[i].v.id == qctrl->id) |
345 | break; | 345 | break; |
346 | if (i == CX23885_CTLS) { | 346 | if (i == CX23885_CTLS) { |
347 | *qctrl = no_ctl; | 347 | *qctrl = no_ctl; |
348 | return 0; | 348 | return 0; |
349 | } | 349 | } |
350 | *qctrl = cx23885_ctls[i].v; | 350 | *qctrl = cx23885_ctls[i].v; |
351 | return 0; | 351 | return 0; |
352 | } | 352 | } |
353 | EXPORT_SYMBOL(cx23885_ctrl_query); | 353 | EXPORT_SYMBOL(cx23885_ctrl_query); |
354 | 354 | ||
355 | /* ------------------------------------------------------------------- */ | 355 | /* ------------------------------------------------------------------- */ |
356 | /* resource management */ | 356 | /* resource management */ |
357 | 357 | ||
358 | static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh, | 358 | static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh, |
359 | unsigned int bit) | 359 | unsigned int bit) |
360 | { | 360 | { |
361 | dprintk(1, "%s()\n", __FUNCTION__); | 361 | dprintk(1, "%s()\n", __func__); |
362 | if (fh->resources & bit) | 362 | if (fh->resources & bit) |
363 | /* have it already allocated */ | 363 | /* have it already allocated */ |
364 | return 1; | 364 | return 1; |
365 | 365 | ||
366 | /* is it free? */ | 366 | /* is it free? */ |
367 | mutex_lock(&dev->lock); | 367 | mutex_lock(&dev->lock); |
368 | if (dev->resources & bit) { | 368 | if (dev->resources & bit) { |
369 | /* no, someone else uses it */ | 369 | /* no, someone else uses it */ |
370 | mutex_unlock(&dev->lock); | 370 | mutex_unlock(&dev->lock); |
371 | return 0; | 371 | return 0; |
372 | } | 372 | } |
373 | /* it's free, grab it */ | 373 | /* it's free, grab it */ |
374 | fh->resources |= bit; | 374 | fh->resources |= bit; |
375 | dev->resources |= bit; | 375 | dev->resources |= bit; |
376 | dprintk(1, "res: get %d\n", bit); | 376 | dprintk(1, "res: get %d\n", bit); |
377 | mutex_unlock(&dev->lock); | 377 | mutex_unlock(&dev->lock); |
378 | return 1; | 378 | return 1; |
379 | } | 379 | } |
380 | 380 | ||
381 | static int res_check(struct cx23885_fh *fh, unsigned int bit) | 381 | static int res_check(struct cx23885_fh *fh, unsigned int bit) |
382 | { | 382 | { |
383 | return (fh->resources & bit); | 383 | return (fh->resources & bit); |
384 | } | 384 | } |
385 | 385 | ||
386 | static int res_locked(struct cx23885_dev *dev, unsigned int bit) | 386 | static int res_locked(struct cx23885_dev *dev, unsigned int bit) |
387 | { | 387 | { |
388 | return (dev->resources & bit); | 388 | return (dev->resources & bit); |
389 | } | 389 | } |
390 | 390 | ||
391 | static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh, | 391 | static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh, |
392 | unsigned int bits) | 392 | unsigned int bits) |
393 | { | 393 | { |
394 | BUG_ON((fh->resources & bits) != bits); | 394 | BUG_ON((fh->resources & bits) != bits); |
395 | dprintk(1, "%s()\n", __FUNCTION__); | 395 | dprintk(1, "%s()\n", __func__); |
396 | 396 | ||
397 | mutex_lock(&dev->lock); | 397 | mutex_lock(&dev->lock); |
398 | fh->resources &= ~bits; | 398 | fh->resources &= ~bits; |
399 | dev->resources &= ~bits; | 399 | dev->resources &= ~bits; |
400 | dprintk(1, "res: put %d\n", bits); | 400 | dprintk(1, "res: put %d\n", bits); |
401 | mutex_unlock(&dev->lock); | 401 | mutex_unlock(&dev->lock); |
402 | } | 402 | } |
403 | 403 | ||
404 | int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) | 404 | int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) |
405 | { | 405 | { |
406 | struct v4l2_routing route; | 406 | struct v4l2_routing route; |
407 | memset(&route, 0, sizeof(route)); | 407 | memset(&route, 0, sizeof(route)); |
408 | 408 | ||
409 | dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n", | 409 | dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n", |
410 | __FUNCTION__, | 410 | __func__, |
411 | input, INPUT(input)->vmux, | 411 | input, INPUT(input)->vmux, |
412 | INPUT(input)->gpio0, INPUT(input)->gpio1, | 412 | INPUT(input)->gpio0, INPUT(input)->gpio1, |
413 | INPUT(input)->gpio2, INPUT(input)->gpio3); | 413 | INPUT(input)->gpio2, INPUT(input)->gpio3); |
414 | dev->input = input; | 414 | dev->input = input; |
415 | 415 | ||
416 | route.input = INPUT(input)->vmux; | 416 | route.input = INPUT(input)->vmux; |
417 | 417 | ||
418 | /* Tell the internal A/V decoder */ | 418 | /* Tell the internal A/V decoder */ |
419 | cx23885_call_i2c_clients(&dev->i2c_bus[2], | 419 | cx23885_call_i2c_clients(&dev->i2c_bus[2], |
420 | VIDIOC_INT_S_VIDEO_ROUTING, &route); | 420 | VIDIOC_INT_S_VIDEO_ROUTING, &route); |
421 | 421 | ||
422 | return 0; | 422 | return 0; |
423 | } | 423 | } |
424 | EXPORT_SYMBOL(cx23885_video_mux); | 424 | EXPORT_SYMBOL(cx23885_video_mux); |
425 | 425 | ||
426 | /* ------------------------------------------------------------------ */ | 426 | /* ------------------------------------------------------------------ */ |
427 | int cx23885_set_scale(struct cx23885_dev *dev, unsigned int width, | 427 | int cx23885_set_scale(struct cx23885_dev *dev, unsigned int width, |
428 | unsigned int height, enum v4l2_field field) | 428 | unsigned int height, enum v4l2_field field) |
429 | { | 429 | { |
430 | dprintk(1, "%s()\n", __FUNCTION__); | 430 | dprintk(1, "%s()\n", __func__); |
431 | return 0; | 431 | return 0; |
432 | } | 432 | } |
433 | 433 | ||
434 | static int cx23885_start_video_dma(struct cx23885_dev *dev, | 434 | static int cx23885_start_video_dma(struct cx23885_dev *dev, |
435 | struct cx23885_dmaqueue *q, | 435 | struct cx23885_dmaqueue *q, |
436 | struct cx23885_buffer *buf) | 436 | struct cx23885_buffer *buf) |
437 | { | 437 | { |
438 | dprintk(1, "%s()\n", __FUNCTION__); | 438 | dprintk(1, "%s()\n", __func__); |
439 | 439 | ||
440 | /* setup fifo + format */ | 440 | /* setup fifo + format */ |
441 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01], | 441 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01], |
442 | buf->bpl, buf->risc.dma); | 442 | buf->bpl, buf->risc.dma); |
443 | cx23885_set_scale(dev, buf->vb.width, buf->vb.height, buf->vb.field); | 443 | cx23885_set_scale(dev, buf->vb.width, buf->vb.height, buf->vb.field); |
444 | 444 | ||
445 | /* reset counter */ | 445 | /* reset counter */ |
446 | cx_write(VID_A_GPCNT_CTL, 3); | 446 | cx_write(VID_A_GPCNT_CTL, 3); |
447 | q->count = 1; | 447 | q->count = 1; |
448 | 448 | ||
449 | /* enable irq */ | 449 | /* enable irq */ |
450 | cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | 0x01); | 450 | cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | 0x01); |
451 | cx_set(VID_A_INT_MSK, 0x000011); | 451 | cx_set(VID_A_INT_MSK, 0x000011); |
452 | 452 | ||
453 | /* start dma */ | 453 | /* start dma */ |
454 | cx_set(DEV_CNTRL2, (1<<5)); | 454 | cx_set(DEV_CNTRL2, (1<<5)); |
455 | cx_set(VID_A_DMA_CTL, 0x11); /* FIFO and RISC enable */ | 455 | cx_set(VID_A_DMA_CTL, 0x11); /* FIFO and RISC enable */ |
456 | 456 | ||
457 | return 0; | 457 | return 0; |
458 | } | 458 | } |
459 | 459 | ||
460 | 460 | ||
461 | static int cx23885_restart_video_queue(struct cx23885_dev *dev, | 461 | static int cx23885_restart_video_queue(struct cx23885_dev *dev, |
462 | struct cx23885_dmaqueue *q) | 462 | struct cx23885_dmaqueue *q) |
463 | { | 463 | { |
464 | struct cx23885_buffer *buf, *prev; | 464 | struct cx23885_buffer *buf, *prev; |
465 | struct list_head *item; | 465 | struct list_head *item; |
466 | dprintk(1, "%s()\n", __FUNCTION__); | 466 | dprintk(1, "%s()\n", __func__); |
467 | 467 | ||
468 | if (!list_empty(&q->active)) { | 468 | if (!list_empty(&q->active)) { |
469 | buf = list_entry(q->active.next, struct cx23885_buffer, | 469 | buf = list_entry(q->active.next, struct cx23885_buffer, |
470 | vb.queue); | 470 | vb.queue); |
471 | dprintk(2, "restart_queue [%p/%d]: restart dma\n", | 471 | dprintk(2, "restart_queue [%p/%d]: restart dma\n", |
472 | buf, buf->vb.i); | 472 | buf, buf->vb.i); |
473 | cx23885_start_video_dma(dev, q, buf); | 473 | cx23885_start_video_dma(dev, q, buf); |
474 | list_for_each(item, &q->active) { | 474 | list_for_each(item, &q->active) { |
475 | buf = list_entry(item, struct cx23885_buffer, | 475 | buf = list_entry(item, struct cx23885_buffer, |
476 | vb.queue); | 476 | vb.queue); |
477 | buf->count = q->count++; | 477 | buf->count = q->count++; |
478 | } | 478 | } |
479 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | 479 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); |
480 | return 0; | 480 | return 0; |
481 | } | 481 | } |
482 | 482 | ||
483 | prev = NULL; | 483 | prev = NULL; |
484 | for (;;) { | 484 | for (;;) { |
485 | if (list_empty(&q->queued)) | 485 | if (list_empty(&q->queued)) |
486 | return 0; | 486 | return 0; |
487 | buf = list_entry(q->queued.next, struct cx23885_buffer, | 487 | buf = list_entry(q->queued.next, struct cx23885_buffer, |
488 | vb.queue); | 488 | vb.queue); |
489 | if (NULL == prev) { | 489 | if (NULL == prev) { |
490 | list_move_tail(&buf->vb.queue, &q->active); | 490 | list_move_tail(&buf->vb.queue, &q->active); |
491 | cx23885_start_video_dma(dev, q, buf); | 491 | cx23885_start_video_dma(dev, q, buf); |
492 | buf->vb.state = VIDEOBUF_ACTIVE; | 492 | buf->vb.state = VIDEOBUF_ACTIVE; |
493 | buf->count = q->count++; | 493 | buf->count = q->count++; |
494 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | 494 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); |
495 | dprintk(2, "[%p/%d] restart_queue - first active\n", | 495 | dprintk(2, "[%p/%d] restart_queue - first active\n", |
496 | buf, buf->vb.i); | 496 | buf, buf->vb.i); |
497 | 497 | ||
498 | } else if (prev->vb.width == buf->vb.width && | 498 | } else if (prev->vb.width == buf->vb.width && |
499 | prev->vb.height == buf->vb.height && | 499 | prev->vb.height == buf->vb.height && |
500 | prev->fmt == buf->fmt) { | 500 | prev->fmt == buf->fmt) { |
501 | list_move_tail(&buf->vb.queue, &q->active); | 501 | list_move_tail(&buf->vb.queue, &q->active); |
502 | buf->vb.state = VIDEOBUF_ACTIVE; | 502 | buf->vb.state = VIDEOBUF_ACTIVE; |
503 | buf->count = q->count++; | 503 | buf->count = q->count++; |
504 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 504 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
505 | prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */ | 505 | prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */ |
506 | dprintk(2, "[%p/%d] restart_queue - move to active\n", | 506 | dprintk(2, "[%p/%d] restart_queue - move to active\n", |
507 | buf, buf->vb.i); | 507 | buf, buf->vb.i); |
508 | } else { | 508 | } else { |
509 | return 0; | 509 | return 0; |
510 | } | 510 | } |
511 | prev = buf; | 511 | prev = buf; |
512 | } | 512 | } |
513 | } | 513 | } |
514 | 514 | ||
515 | static int buffer_setup(struct videobuf_queue *q, unsigned int *count, | 515 | static int buffer_setup(struct videobuf_queue *q, unsigned int *count, |
516 | unsigned int *size) | 516 | unsigned int *size) |
517 | { | 517 | { |
518 | struct cx23885_fh *fh = q->priv_data; | 518 | struct cx23885_fh *fh = q->priv_data; |
519 | 519 | ||
520 | *size = fh->fmt->depth*fh->width*fh->height >> 3; | 520 | *size = fh->fmt->depth*fh->width*fh->height >> 3; |
521 | if (0 == *count) | 521 | if (0 == *count) |
522 | *count = 32; | 522 | *count = 32; |
523 | while (*size * *count > vid_limit * 1024 * 1024) | 523 | while (*size * *count > vid_limit * 1024 * 1024) |
524 | (*count)--; | 524 | (*count)--; |
525 | return 0; | 525 | return 0; |
526 | } | 526 | } |
527 | 527 | ||
528 | static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | 528 | static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, |
529 | enum v4l2_field field) | 529 | enum v4l2_field field) |
530 | { | 530 | { |
531 | struct cx23885_fh *fh = q->priv_data; | 531 | struct cx23885_fh *fh = q->priv_data; |
532 | struct cx23885_dev *dev = fh->dev; | 532 | struct cx23885_dev *dev = fh->dev; |
533 | struct cx23885_buffer *buf = | 533 | struct cx23885_buffer *buf = |
534 | container_of(vb, struct cx23885_buffer, vb); | 534 | container_of(vb, struct cx23885_buffer, vb); |
535 | int rc, init_buffer = 0; | 535 | int rc, init_buffer = 0; |
536 | u32 line0_offset, line1_offset; | 536 | u32 line0_offset, line1_offset; |
537 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | 537 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); |
538 | 538 | ||
539 | BUG_ON(NULL == fh->fmt); | 539 | BUG_ON(NULL == fh->fmt); |
540 | if (fh->width < 48 || fh->width > norm_maxw(dev->tvnorm) || | 540 | if (fh->width < 48 || fh->width > norm_maxw(dev->tvnorm) || |
541 | fh->height < 32 || fh->height > norm_maxh(dev->tvnorm)) | 541 | fh->height < 32 || fh->height > norm_maxh(dev->tvnorm)) |
542 | return -EINVAL; | 542 | return -EINVAL; |
543 | buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; | 543 | buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; |
544 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 544 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
545 | return -EINVAL; | 545 | return -EINVAL; |
546 | 546 | ||
547 | if (buf->fmt != fh->fmt || | 547 | if (buf->fmt != fh->fmt || |
548 | buf->vb.width != fh->width || | 548 | buf->vb.width != fh->width || |
549 | buf->vb.height != fh->height || | 549 | buf->vb.height != fh->height || |
550 | buf->vb.field != field) { | 550 | buf->vb.field != field) { |
551 | buf->fmt = fh->fmt; | 551 | buf->fmt = fh->fmt; |
552 | buf->vb.width = fh->width; | 552 | buf->vb.width = fh->width; |
553 | buf->vb.height = fh->height; | 553 | buf->vb.height = fh->height; |
554 | buf->vb.field = field; | 554 | buf->vb.field = field; |
555 | init_buffer = 1; | 555 | init_buffer = 1; |
556 | } | 556 | } |
557 | 557 | ||
558 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 558 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
559 | init_buffer = 1; | 559 | init_buffer = 1; |
560 | rc = videobuf_iolock(q, &buf->vb, NULL); | 560 | rc = videobuf_iolock(q, &buf->vb, NULL); |
561 | if (0 != rc) | 561 | if (0 != rc) |
562 | goto fail; | 562 | goto fail; |
563 | } | 563 | } |
564 | 564 | ||
565 | if (init_buffer) { | 565 | if (init_buffer) { |
566 | buf->bpl = buf->vb.width * buf->fmt->depth >> 3; | 566 | buf->bpl = buf->vb.width * buf->fmt->depth >> 3; |
567 | switch (buf->vb.field) { | 567 | switch (buf->vb.field) { |
568 | case V4L2_FIELD_TOP: | 568 | case V4L2_FIELD_TOP: |
569 | cx23885_risc_buffer(dev->pci, &buf->risc, | 569 | cx23885_risc_buffer(dev->pci, &buf->risc, |
570 | dma->sglist, 0, UNSET, | 570 | dma->sglist, 0, UNSET, |
571 | buf->bpl, 0, buf->vb.height); | 571 | buf->bpl, 0, buf->vb.height); |
572 | break; | 572 | break; |
573 | case V4L2_FIELD_BOTTOM: | 573 | case V4L2_FIELD_BOTTOM: |
574 | cx23885_risc_buffer(dev->pci, &buf->risc, | 574 | cx23885_risc_buffer(dev->pci, &buf->risc, |
575 | dma->sglist, UNSET, 0, | 575 | dma->sglist, UNSET, 0, |
576 | buf->bpl, 0, buf->vb.height); | 576 | buf->bpl, 0, buf->vb.height); |
577 | break; | 577 | break; |
578 | case V4L2_FIELD_INTERLACED: | 578 | case V4L2_FIELD_INTERLACED: |
579 | if (dev->tvnorm & V4L2_STD_NTSC) { | 579 | if (dev->tvnorm & V4L2_STD_NTSC) { |
580 | /* cx25840 transmits NTSC bottom field first */ | 580 | /* cx25840 transmits NTSC bottom field first */ |
581 | dprintk(1, "%s() Creating NTSC risc\n", | 581 | dprintk(1, "%s() Creating NTSC risc\n", |
582 | __FUNCTION__); | 582 | __func__); |
583 | line0_offset = buf->bpl; | 583 | line0_offset = buf->bpl; |
584 | line1_offset = 0; | 584 | line1_offset = 0; |
585 | } else { | 585 | } else { |
586 | /* All other formats are top field first */ | 586 | /* All other formats are top field first */ |
587 | dprintk(1, "%s() Creating PAL/SECAM risc\n", | 587 | dprintk(1, "%s() Creating PAL/SECAM risc\n", |
588 | __FUNCTION__); | 588 | __func__); |
589 | line0_offset = 0; | 589 | line0_offset = 0; |
590 | line1_offset = buf->bpl; | 590 | line1_offset = buf->bpl; |
591 | } | 591 | } |
592 | cx23885_risc_buffer(dev->pci, &buf->risc, | 592 | cx23885_risc_buffer(dev->pci, &buf->risc, |
593 | dma->sglist, line0_offset, | 593 | dma->sglist, line0_offset, |
594 | line1_offset, | 594 | line1_offset, |
595 | buf->bpl, buf->bpl, | 595 | buf->bpl, buf->bpl, |
596 | buf->vb.height >> 1); | 596 | buf->vb.height >> 1); |
597 | break; | 597 | break; |
598 | case V4L2_FIELD_SEQ_TB: | 598 | case V4L2_FIELD_SEQ_TB: |
599 | cx23885_risc_buffer(dev->pci, &buf->risc, | 599 | cx23885_risc_buffer(dev->pci, &buf->risc, |
600 | dma->sglist, | 600 | dma->sglist, |
601 | 0, buf->bpl * (buf->vb.height >> 1), | 601 | 0, buf->bpl * (buf->vb.height >> 1), |
602 | buf->bpl, 0, | 602 | buf->bpl, 0, |
603 | buf->vb.height >> 1); | 603 | buf->vb.height >> 1); |
604 | break; | 604 | break; |
605 | case V4L2_FIELD_SEQ_BT: | 605 | case V4L2_FIELD_SEQ_BT: |
606 | cx23885_risc_buffer(dev->pci, &buf->risc, | 606 | cx23885_risc_buffer(dev->pci, &buf->risc, |
607 | dma->sglist, | 607 | dma->sglist, |
608 | buf->bpl * (buf->vb.height >> 1), 0, | 608 | buf->bpl * (buf->vb.height >> 1), 0, |
609 | buf->bpl, 0, | 609 | buf->bpl, 0, |
610 | buf->vb.height >> 1); | 610 | buf->vb.height >> 1); |
611 | break; | 611 | break; |
612 | default: | 612 | default: |
613 | BUG(); | 613 | BUG(); |
614 | } | 614 | } |
615 | } | 615 | } |
616 | dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", | 616 | dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", |
617 | buf, buf->vb.i, | 617 | buf, buf->vb.i, |
618 | fh->width, fh->height, fh->fmt->depth, fh->fmt->name, | 618 | fh->width, fh->height, fh->fmt->depth, fh->fmt->name, |
619 | (unsigned long)buf->risc.dma); | 619 | (unsigned long)buf->risc.dma); |
620 | 620 | ||
621 | buf->vb.state = VIDEOBUF_PREPARED; | 621 | buf->vb.state = VIDEOBUF_PREPARED; |
622 | return 0; | 622 | return 0; |
623 | 623 | ||
624 | fail: | 624 | fail: |
625 | cx23885_free_buffer(q, buf); | 625 | cx23885_free_buffer(q, buf); |
626 | return rc; | 626 | return rc; |
627 | } | 627 | } |
628 | 628 | ||
629 | static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | 629 | static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) |
630 | { | 630 | { |
631 | struct cx23885_buffer *buf = container_of(vb, | 631 | struct cx23885_buffer *buf = container_of(vb, |
632 | struct cx23885_buffer, vb); | 632 | struct cx23885_buffer, vb); |
633 | struct cx23885_buffer *prev; | 633 | struct cx23885_buffer *prev; |
634 | struct cx23885_fh *fh = vq->priv_data; | 634 | struct cx23885_fh *fh = vq->priv_data; |
635 | struct cx23885_dev *dev = fh->dev; | 635 | struct cx23885_dev *dev = fh->dev; |
636 | struct cx23885_dmaqueue *q = &dev->vidq; | 636 | struct cx23885_dmaqueue *q = &dev->vidq; |
637 | 637 | ||
638 | /* add jump to stopper */ | 638 | /* add jump to stopper */ |
639 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | 639 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); |
640 | buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); | 640 | buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); |
641 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ | 641 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ |
642 | 642 | ||
643 | if (!list_empty(&q->queued)) { | 643 | if (!list_empty(&q->queued)) { |
644 | list_add_tail(&buf->vb.queue, &q->queued); | 644 | list_add_tail(&buf->vb.queue, &q->queued); |
645 | buf->vb.state = VIDEOBUF_QUEUED; | 645 | buf->vb.state = VIDEOBUF_QUEUED; |
646 | dprintk(2, "[%p/%d] buffer_queue - append to queued\n", | 646 | dprintk(2, "[%p/%d] buffer_queue - append to queued\n", |
647 | buf, buf->vb.i); | 647 | buf, buf->vb.i); |
648 | 648 | ||
649 | } else if (list_empty(&q->active)) { | 649 | } else if (list_empty(&q->active)) { |
650 | list_add_tail(&buf->vb.queue, &q->active); | 650 | list_add_tail(&buf->vb.queue, &q->active); |
651 | cx23885_start_video_dma(dev, q, buf); | 651 | cx23885_start_video_dma(dev, q, buf); |
652 | buf->vb.state = VIDEOBUF_ACTIVE; | 652 | buf->vb.state = VIDEOBUF_ACTIVE; |
653 | buf->count = q->count++; | 653 | buf->count = q->count++; |
654 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | 654 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); |
655 | dprintk(2, "[%p/%d] buffer_queue - first active\n", | 655 | dprintk(2, "[%p/%d] buffer_queue - first active\n", |
656 | buf, buf->vb.i); | 656 | buf, buf->vb.i); |
657 | 657 | ||
658 | } else { | 658 | } else { |
659 | prev = list_entry(q->active.prev, struct cx23885_buffer, | 659 | prev = list_entry(q->active.prev, struct cx23885_buffer, |
660 | vb.queue); | 660 | vb.queue); |
661 | if (prev->vb.width == buf->vb.width && | 661 | if (prev->vb.width == buf->vb.width && |
662 | prev->vb.height == buf->vb.height && | 662 | prev->vb.height == buf->vb.height && |
663 | prev->fmt == buf->fmt) { | 663 | prev->fmt == buf->fmt) { |
664 | list_add_tail(&buf->vb.queue, &q->active); | 664 | list_add_tail(&buf->vb.queue, &q->active); |
665 | buf->vb.state = VIDEOBUF_ACTIVE; | 665 | buf->vb.state = VIDEOBUF_ACTIVE; |
666 | buf->count = q->count++; | 666 | buf->count = q->count++; |
667 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 667 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
668 | /* 64 bit bits 63-32 */ | 668 | /* 64 bit bits 63-32 */ |
669 | prev->risc.jmp[2] = cpu_to_le32(0); | 669 | prev->risc.jmp[2] = cpu_to_le32(0); |
670 | dprintk(2, "[%p/%d] buffer_queue - append to active\n", | 670 | dprintk(2, "[%p/%d] buffer_queue - append to active\n", |
671 | buf, buf->vb.i); | 671 | buf, buf->vb.i); |
672 | 672 | ||
673 | } else { | 673 | } else { |
674 | list_add_tail(&buf->vb.queue, &q->queued); | 674 | list_add_tail(&buf->vb.queue, &q->queued); |
675 | buf->vb.state = VIDEOBUF_QUEUED; | 675 | buf->vb.state = VIDEOBUF_QUEUED; |
676 | dprintk(2, "[%p/%d] buffer_queue - first queued\n", | 676 | dprintk(2, "[%p/%d] buffer_queue - first queued\n", |
677 | buf, buf->vb.i); | 677 | buf, buf->vb.i); |
678 | } | 678 | } |
679 | } | 679 | } |
680 | } | 680 | } |
681 | 681 | ||
682 | static void buffer_release(struct videobuf_queue *q, | 682 | static void buffer_release(struct videobuf_queue *q, |
683 | struct videobuf_buffer *vb) | 683 | struct videobuf_buffer *vb) |
684 | { | 684 | { |
685 | struct cx23885_buffer *buf = container_of(vb, | 685 | struct cx23885_buffer *buf = container_of(vb, |
686 | struct cx23885_buffer, vb); | 686 | struct cx23885_buffer, vb); |
687 | 687 | ||
688 | cx23885_free_buffer(q, buf); | 688 | cx23885_free_buffer(q, buf); |
689 | } | 689 | } |
690 | 690 | ||
691 | static struct videobuf_queue_ops cx23885_video_qops = { | 691 | static struct videobuf_queue_ops cx23885_video_qops = { |
692 | .buf_setup = buffer_setup, | 692 | .buf_setup = buffer_setup, |
693 | .buf_prepare = buffer_prepare, | 693 | .buf_prepare = buffer_prepare, |
694 | .buf_queue = buffer_queue, | 694 | .buf_queue = buffer_queue, |
695 | .buf_release = buffer_release, | 695 | .buf_release = buffer_release, |
696 | }; | 696 | }; |
697 | 697 | ||
698 | static struct videobuf_queue *get_queue(struct cx23885_fh *fh) | 698 | static struct videobuf_queue *get_queue(struct cx23885_fh *fh) |
699 | { | 699 | { |
700 | switch (fh->type) { | 700 | switch (fh->type) { |
701 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 701 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
702 | return &fh->vidq; | 702 | return &fh->vidq; |
703 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 703 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
704 | return &fh->vbiq; | 704 | return &fh->vbiq; |
705 | default: | 705 | default: |
706 | BUG(); | 706 | BUG(); |
707 | return NULL; | 707 | return NULL; |
708 | } | 708 | } |
709 | } | 709 | } |
710 | 710 | ||
711 | static int get_resource(struct cx23885_fh *fh) | 711 | static int get_resource(struct cx23885_fh *fh) |
712 | { | 712 | { |
713 | switch (fh->type) { | 713 | switch (fh->type) { |
714 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 714 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
715 | return RESOURCE_VIDEO; | 715 | return RESOURCE_VIDEO; |
716 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 716 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
717 | return RESOURCE_VBI; | 717 | return RESOURCE_VBI; |
718 | default: | 718 | default: |
719 | BUG(); | 719 | BUG(); |
720 | return 0; | 720 | return 0; |
721 | } | 721 | } |
722 | } | 722 | } |
723 | 723 | ||
724 | static int video_open(struct inode *inode, struct file *file) | 724 | static int video_open(struct inode *inode, struct file *file) |
725 | { | 725 | { |
726 | int minor = iminor(inode); | 726 | int minor = iminor(inode); |
727 | struct cx23885_dev *h, *dev = NULL; | 727 | struct cx23885_dev *h, *dev = NULL; |
728 | struct cx23885_fh *fh; | 728 | struct cx23885_fh *fh; |
729 | struct list_head *list; | 729 | struct list_head *list; |
730 | enum v4l2_buf_type type = 0; | 730 | enum v4l2_buf_type type = 0; |
731 | int radio = 0; | 731 | int radio = 0; |
732 | 732 | ||
733 | list_for_each(list, &cx23885_devlist) { | 733 | list_for_each(list, &cx23885_devlist) { |
734 | h = list_entry(list, struct cx23885_dev, devlist); | 734 | h = list_entry(list, struct cx23885_dev, devlist); |
735 | if (h->video_dev->minor == minor) { | 735 | if (h->video_dev->minor == minor) { |
736 | dev = h; | 736 | dev = h; |
737 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 737 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
738 | } | 738 | } |
739 | if (h->vbi_dev && | 739 | if (h->vbi_dev && |
740 | h->vbi_dev->minor == minor) { | 740 | h->vbi_dev->minor == minor) { |
741 | dev = h; | 741 | dev = h; |
742 | type = V4L2_BUF_TYPE_VBI_CAPTURE; | 742 | type = V4L2_BUF_TYPE_VBI_CAPTURE; |
743 | } | 743 | } |
744 | if (h->radio_dev && | 744 | if (h->radio_dev && |
745 | h->radio_dev->minor == minor) { | 745 | h->radio_dev->minor == minor) { |
746 | radio = 1; | 746 | radio = 1; |
747 | dev = h; | 747 | dev = h; |
748 | } | 748 | } |
749 | } | 749 | } |
750 | if (NULL == dev) | 750 | if (NULL == dev) |
751 | return -ENODEV; | 751 | return -ENODEV; |
752 | 752 | ||
753 | dprintk(1, "open minor=%d radio=%d type=%s\n", | 753 | dprintk(1, "open minor=%d radio=%d type=%s\n", |
754 | minor, radio, v4l2_type_names[type]); | 754 | minor, radio, v4l2_type_names[type]); |
755 | 755 | ||
756 | /* allocate + initialize per filehandle data */ | 756 | /* allocate + initialize per filehandle data */ |
757 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 757 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
758 | if (NULL == fh) | 758 | if (NULL == fh) |
759 | return -ENOMEM; | 759 | return -ENOMEM; |
760 | file->private_data = fh; | 760 | file->private_data = fh; |
761 | fh->dev = dev; | 761 | fh->dev = dev; |
762 | fh->radio = radio; | 762 | fh->radio = radio; |
763 | fh->type = type; | 763 | fh->type = type; |
764 | fh->width = 320; | 764 | fh->width = 320; |
765 | fh->height = 240; | 765 | fh->height = 240; |
766 | fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); | 766 | fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); |
767 | 767 | ||
768 | videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops, | 768 | videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops, |
769 | &dev->pci->dev, &dev->slock, | 769 | &dev->pci->dev, &dev->slock, |
770 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 770 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
771 | V4L2_FIELD_INTERLACED, | 771 | V4L2_FIELD_INTERLACED, |
772 | sizeof(struct cx23885_buffer), | 772 | sizeof(struct cx23885_buffer), |
773 | fh); | 773 | fh); |
774 | 774 | ||
775 | dprintk(1, "post videobuf_queue_init()\n"); | 775 | dprintk(1, "post videobuf_queue_init()\n"); |
776 | 776 | ||
777 | 777 | ||
778 | return 0; | 778 | return 0; |
779 | } | 779 | } |
780 | 780 | ||
781 | static ssize_t video_read(struct file *file, char __user *data, | 781 | static ssize_t video_read(struct file *file, char __user *data, |
782 | size_t count, loff_t *ppos) | 782 | size_t count, loff_t *ppos) |
783 | { | 783 | { |
784 | struct cx23885_fh *fh = file->private_data; | 784 | struct cx23885_fh *fh = file->private_data; |
785 | 785 | ||
786 | switch (fh->type) { | 786 | switch (fh->type) { |
787 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 787 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
788 | if (res_locked(fh->dev, RESOURCE_VIDEO)) | 788 | if (res_locked(fh->dev, RESOURCE_VIDEO)) |
789 | return -EBUSY; | 789 | return -EBUSY; |
790 | return videobuf_read_one(&fh->vidq, data, count, ppos, | 790 | return videobuf_read_one(&fh->vidq, data, count, ppos, |
791 | file->f_flags & O_NONBLOCK); | 791 | file->f_flags & O_NONBLOCK); |
792 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 792 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
793 | if (!res_get(fh->dev, fh, RESOURCE_VBI)) | 793 | if (!res_get(fh->dev, fh, RESOURCE_VBI)) |
794 | return -EBUSY; | 794 | return -EBUSY; |
795 | return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1, | 795 | return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1, |
796 | file->f_flags & O_NONBLOCK); | 796 | file->f_flags & O_NONBLOCK); |
797 | default: | 797 | default: |
798 | BUG(); | 798 | BUG(); |
799 | return 0; | 799 | return 0; |
800 | } | 800 | } |
801 | } | 801 | } |
802 | 802 | ||
803 | static unsigned int video_poll(struct file *file, | 803 | static unsigned int video_poll(struct file *file, |
804 | struct poll_table_struct *wait) | 804 | struct poll_table_struct *wait) |
805 | { | 805 | { |
806 | struct cx23885_fh *fh = file->private_data; | 806 | struct cx23885_fh *fh = file->private_data; |
807 | struct cx23885_buffer *buf; | 807 | struct cx23885_buffer *buf; |
808 | 808 | ||
809 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { | 809 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { |
810 | if (!res_get(fh->dev, fh, RESOURCE_VBI)) | 810 | if (!res_get(fh->dev, fh, RESOURCE_VBI)) |
811 | return POLLERR; | 811 | return POLLERR; |
812 | return videobuf_poll_stream(file, &fh->vbiq, wait); | 812 | return videobuf_poll_stream(file, &fh->vbiq, wait); |
813 | } | 813 | } |
814 | 814 | ||
815 | if (res_check(fh, RESOURCE_VIDEO)) { | 815 | if (res_check(fh, RESOURCE_VIDEO)) { |
816 | /* streaming capture */ | 816 | /* streaming capture */ |
817 | if (list_empty(&fh->vidq.stream)) | 817 | if (list_empty(&fh->vidq.stream)) |
818 | return POLLERR; | 818 | return POLLERR; |
819 | buf = list_entry(fh->vidq.stream.next, | 819 | buf = list_entry(fh->vidq.stream.next, |
820 | struct cx23885_buffer, vb.stream); | 820 | struct cx23885_buffer, vb.stream); |
821 | } else { | 821 | } else { |
822 | /* read() capture */ | 822 | /* read() capture */ |
823 | buf = (struct cx23885_buffer *)fh->vidq.read_buf; | 823 | buf = (struct cx23885_buffer *)fh->vidq.read_buf; |
824 | if (NULL == buf) | 824 | if (NULL == buf) |
825 | return POLLERR; | 825 | return POLLERR; |
826 | } | 826 | } |
827 | poll_wait(file, &buf->vb.done, wait); | 827 | poll_wait(file, &buf->vb.done, wait); |
828 | if (buf->vb.state == VIDEOBUF_DONE || | 828 | if (buf->vb.state == VIDEOBUF_DONE || |
829 | buf->vb.state == VIDEOBUF_ERROR) | 829 | buf->vb.state == VIDEOBUF_ERROR) |
830 | return POLLIN|POLLRDNORM; | 830 | return POLLIN|POLLRDNORM; |
831 | return 0; | 831 | return 0; |
832 | } | 832 | } |
833 | 833 | ||
834 | static int video_release(struct inode *inode, struct file *file) | 834 | static int video_release(struct inode *inode, struct file *file) |
835 | { | 835 | { |
836 | struct cx23885_fh *fh = file->private_data; | 836 | struct cx23885_fh *fh = file->private_data; |
837 | struct cx23885_dev *dev = fh->dev; | 837 | struct cx23885_dev *dev = fh->dev; |
838 | 838 | ||
839 | /* turn off overlay */ | 839 | /* turn off overlay */ |
840 | if (res_check(fh, RESOURCE_OVERLAY)) { | 840 | if (res_check(fh, RESOURCE_OVERLAY)) { |
841 | /* FIXME */ | 841 | /* FIXME */ |
842 | res_free(dev, fh, RESOURCE_OVERLAY); | 842 | res_free(dev, fh, RESOURCE_OVERLAY); |
843 | } | 843 | } |
844 | 844 | ||
845 | /* stop video capture */ | 845 | /* stop video capture */ |
846 | if (res_check(fh, RESOURCE_VIDEO)) { | 846 | if (res_check(fh, RESOURCE_VIDEO)) { |
847 | videobuf_queue_cancel(&fh->vidq); | 847 | videobuf_queue_cancel(&fh->vidq); |
848 | res_free(dev, fh, RESOURCE_VIDEO); | 848 | res_free(dev, fh, RESOURCE_VIDEO); |
849 | } | 849 | } |
850 | if (fh->vidq.read_buf) { | 850 | if (fh->vidq.read_buf) { |
851 | buffer_release(&fh->vidq, fh->vidq.read_buf); | 851 | buffer_release(&fh->vidq, fh->vidq.read_buf); |
852 | kfree(fh->vidq.read_buf); | 852 | kfree(fh->vidq.read_buf); |
853 | } | 853 | } |
854 | 854 | ||
855 | /* stop vbi capture */ | 855 | /* stop vbi capture */ |
856 | if (res_check(fh, RESOURCE_VBI)) { | 856 | if (res_check(fh, RESOURCE_VBI)) { |
857 | if (fh->vbiq.streaming) | 857 | if (fh->vbiq.streaming) |
858 | videobuf_streamoff(&fh->vbiq); | 858 | videobuf_streamoff(&fh->vbiq); |
859 | if (fh->vbiq.reading) | 859 | if (fh->vbiq.reading) |
860 | videobuf_read_stop(&fh->vbiq); | 860 | videobuf_read_stop(&fh->vbiq); |
861 | res_free(dev, fh, RESOURCE_VBI); | 861 | res_free(dev, fh, RESOURCE_VBI); |
862 | } | 862 | } |
863 | 863 | ||
864 | videobuf_mmap_free(&fh->vidq); | 864 | videobuf_mmap_free(&fh->vidq); |
865 | file->private_data = NULL; | 865 | file->private_data = NULL; |
866 | kfree(fh); | 866 | kfree(fh); |
867 | 867 | ||
868 | /* We are not putting the tuner to sleep here on exit, because | 868 | /* We are not putting the tuner to sleep here on exit, because |
869 | * we want to use the mpeg encoder in another session to capture | 869 | * we want to use the mpeg encoder in another session to capture |
870 | * tuner video. Closing this will result in no video to the encoder. | 870 | * tuner video. Closing this will result in no video to the encoder. |
871 | */ | 871 | */ |
872 | 872 | ||
873 | return 0; | 873 | return 0; |
874 | } | 874 | } |
875 | 875 | ||
876 | static int video_mmap(struct file *file, struct vm_area_struct *vma) | 876 | static int video_mmap(struct file *file, struct vm_area_struct *vma) |
877 | { | 877 | { |
878 | struct cx23885_fh *fh = file->private_data; | 878 | struct cx23885_fh *fh = file->private_data; |
879 | 879 | ||
880 | return videobuf_mmap_mapper(get_queue(fh), vma); | 880 | return videobuf_mmap_mapper(get_queue(fh), vma); |
881 | } | 881 | } |
882 | 882 | ||
883 | /* ------------------------------------------------------------------ */ | 883 | /* ------------------------------------------------------------------ */ |
884 | /* VIDEO CTRL IOCTLS */ | 884 | /* VIDEO CTRL IOCTLS */ |
885 | 885 | ||
886 | int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl) | 886 | int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl) |
887 | { | 887 | { |
888 | dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __FUNCTION__); | 888 | dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__); |
889 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); | 889 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); |
890 | return 0; | 890 | return 0; |
891 | } | 891 | } |
892 | EXPORT_SYMBOL(cx23885_get_control); | 892 | EXPORT_SYMBOL(cx23885_get_control); |
893 | 893 | ||
894 | int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl) | 894 | int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl) |
895 | { | 895 | { |
896 | dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)" | 896 | dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)" |
897 | " (disabled - no action)\n", __FUNCTION__); | 897 | " (disabled - no action)\n", __func__); |
898 | return 0; | 898 | return 0; |
899 | } | 899 | } |
900 | EXPORT_SYMBOL(cx23885_set_control); | 900 | EXPORT_SYMBOL(cx23885_set_control); |
901 | 901 | ||
902 | static void init_controls(struct cx23885_dev *dev) | 902 | static void init_controls(struct cx23885_dev *dev) |
903 | { | 903 | { |
904 | struct v4l2_control ctrl; | 904 | struct v4l2_control ctrl; |
905 | int i; | 905 | int i; |
906 | 906 | ||
907 | for (i = 0; i < CX23885_CTLS; i++) { | 907 | for (i = 0; i < CX23885_CTLS; i++) { |
908 | ctrl.id = cx23885_ctls[i].v.id; | 908 | ctrl.id = cx23885_ctls[i].v.id; |
909 | ctrl.value = cx23885_ctls[i].v.default_value; | 909 | ctrl.value = cx23885_ctls[i].v.default_value; |
910 | 910 | ||
911 | cx23885_set_control(dev, &ctrl); | 911 | cx23885_set_control(dev, &ctrl); |
912 | } | 912 | } |
913 | } | 913 | } |
914 | 914 | ||
915 | /* ------------------------------------------------------------------ */ | 915 | /* ------------------------------------------------------------------ */ |
916 | /* VIDEO IOCTLS */ | 916 | /* VIDEO IOCTLS */ |
917 | 917 | ||
918 | static int vidioc_g_fmt_cap(struct file *file, void *priv, | 918 | static int vidioc_g_fmt_cap(struct file *file, void *priv, |
919 | struct v4l2_format *f) | 919 | struct v4l2_format *f) |
920 | { | 920 | { |
921 | struct cx23885_fh *fh = priv; | 921 | struct cx23885_fh *fh = priv; |
922 | 922 | ||
923 | f->fmt.pix.width = fh->width; | 923 | f->fmt.pix.width = fh->width; |
924 | f->fmt.pix.height = fh->height; | 924 | f->fmt.pix.height = fh->height; |
925 | f->fmt.pix.field = fh->vidq.field; | 925 | f->fmt.pix.field = fh->vidq.field; |
926 | f->fmt.pix.pixelformat = fh->fmt->fourcc; | 926 | f->fmt.pix.pixelformat = fh->fmt->fourcc; |
927 | f->fmt.pix.bytesperline = | 927 | f->fmt.pix.bytesperline = |
928 | (f->fmt.pix.width * fh->fmt->depth) >> 3; | 928 | (f->fmt.pix.width * fh->fmt->depth) >> 3; |
929 | f->fmt.pix.sizeimage = | 929 | f->fmt.pix.sizeimage = |
930 | f->fmt.pix.height * f->fmt.pix.bytesperline; | 930 | f->fmt.pix.height * f->fmt.pix.bytesperline; |
931 | 931 | ||
932 | return 0; | 932 | return 0; |
933 | } | 933 | } |
934 | 934 | ||
935 | static int vidioc_try_fmt_cap(struct file *file, void *priv, | 935 | static int vidioc_try_fmt_cap(struct file *file, void *priv, |
936 | struct v4l2_format *f) | 936 | struct v4l2_format *f) |
937 | { | 937 | { |
938 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 938 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
939 | struct cx23885_fmt *fmt; | 939 | struct cx23885_fmt *fmt; |
940 | enum v4l2_field field; | 940 | enum v4l2_field field; |
941 | unsigned int maxw, maxh; | 941 | unsigned int maxw, maxh; |
942 | 942 | ||
943 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 943 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
944 | if (NULL == fmt) | 944 | if (NULL == fmt) |
945 | return -EINVAL; | 945 | return -EINVAL; |
946 | 946 | ||
947 | field = f->fmt.pix.field; | 947 | field = f->fmt.pix.field; |
948 | maxw = norm_maxw(dev->tvnorm); | 948 | maxw = norm_maxw(dev->tvnorm); |
949 | maxh = norm_maxh(dev->tvnorm); | 949 | maxh = norm_maxh(dev->tvnorm); |
950 | 950 | ||
951 | if (V4L2_FIELD_ANY == field) { | 951 | if (V4L2_FIELD_ANY == field) { |
952 | field = (f->fmt.pix.height > maxh/2) | 952 | field = (f->fmt.pix.height > maxh/2) |
953 | ? V4L2_FIELD_INTERLACED | 953 | ? V4L2_FIELD_INTERLACED |
954 | : V4L2_FIELD_BOTTOM; | 954 | : V4L2_FIELD_BOTTOM; |
955 | } | 955 | } |
956 | 956 | ||
957 | switch (field) { | 957 | switch (field) { |
958 | case V4L2_FIELD_TOP: | 958 | case V4L2_FIELD_TOP: |
959 | case V4L2_FIELD_BOTTOM: | 959 | case V4L2_FIELD_BOTTOM: |
960 | maxh = maxh / 2; | 960 | maxh = maxh / 2; |
961 | break; | 961 | break; |
962 | case V4L2_FIELD_INTERLACED: | 962 | case V4L2_FIELD_INTERLACED: |
963 | break; | 963 | break; |
964 | default: | 964 | default: |
965 | return -EINVAL; | 965 | return -EINVAL; |
966 | } | 966 | } |
967 | 967 | ||
968 | f->fmt.pix.field = field; | 968 | f->fmt.pix.field = field; |
969 | if (f->fmt.pix.height < 32) | 969 | if (f->fmt.pix.height < 32) |
970 | f->fmt.pix.height = 32; | 970 | f->fmt.pix.height = 32; |
971 | if (f->fmt.pix.height > maxh) | 971 | if (f->fmt.pix.height > maxh) |
972 | f->fmt.pix.height = maxh; | 972 | f->fmt.pix.height = maxh; |
973 | if (f->fmt.pix.width < 48) | 973 | if (f->fmt.pix.width < 48) |
974 | f->fmt.pix.width = 48; | 974 | f->fmt.pix.width = 48; |
975 | if (f->fmt.pix.width > maxw) | 975 | if (f->fmt.pix.width > maxw) |
976 | f->fmt.pix.width = maxw; | 976 | f->fmt.pix.width = maxw; |
977 | f->fmt.pix.width &= ~0x03; | 977 | f->fmt.pix.width &= ~0x03; |
978 | f->fmt.pix.bytesperline = | 978 | f->fmt.pix.bytesperline = |
979 | (f->fmt.pix.width * fmt->depth) >> 3; | 979 | (f->fmt.pix.width * fmt->depth) >> 3; |
980 | f->fmt.pix.sizeimage = | 980 | f->fmt.pix.sizeimage = |
981 | f->fmt.pix.height * f->fmt.pix.bytesperline; | 981 | f->fmt.pix.height * f->fmt.pix.bytesperline; |
982 | 982 | ||
983 | return 0; | 983 | return 0; |
984 | } | 984 | } |
985 | 985 | ||
986 | static int vidioc_s_fmt_cap(struct file *file, void *priv, | 986 | static int vidioc_s_fmt_cap(struct file *file, void *priv, |
987 | struct v4l2_format *f) | 987 | struct v4l2_format *f) |
988 | { | 988 | { |
989 | struct cx23885_fh *fh = priv; | 989 | struct cx23885_fh *fh = priv; |
990 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 990 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
991 | int err; | 991 | int err; |
992 | 992 | ||
993 | dprintk(2, "%s()\n", __FUNCTION__); | 993 | dprintk(2, "%s()\n", __func__); |
994 | err = vidioc_try_fmt_cap(file, priv, f); | 994 | err = vidioc_try_fmt_cap(file, priv, f); |
995 | 995 | ||
996 | if (0 != err) | 996 | if (0 != err) |
997 | return err; | 997 | return err; |
998 | fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 998 | fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
999 | fh->width = f->fmt.pix.width; | 999 | fh->width = f->fmt.pix.width; |
1000 | fh->height = f->fmt.pix.height; | 1000 | fh->height = f->fmt.pix.height; |
1001 | fh->vidq.field = f->fmt.pix.field; | 1001 | fh->vidq.field = f->fmt.pix.field; |
1002 | dprintk(2, "%s() width=%d height=%d field=%d\n", __FUNCTION__, | 1002 | dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, |
1003 | fh->width, fh->height, fh->vidq.field); | 1003 | fh->width, fh->height, fh->vidq.field); |
1004 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f); | 1004 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f); |
1005 | return 0; | 1005 | return 0; |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | static int vidioc_querycap(struct file *file, void *priv, | 1008 | static int vidioc_querycap(struct file *file, void *priv, |
1009 | struct v4l2_capability *cap) | 1009 | struct v4l2_capability *cap) |
1010 | { | 1010 | { |
1011 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1011 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1012 | 1012 | ||
1013 | strcpy(cap->driver, "cx23885"); | 1013 | strcpy(cap->driver, "cx23885"); |
1014 | strlcpy(cap->card, cx23885_boards[dev->board].name, | 1014 | strlcpy(cap->card, cx23885_boards[dev->board].name, |
1015 | sizeof(cap->card)); | 1015 | sizeof(cap->card)); |
1016 | sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); | 1016 | sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); |
1017 | cap->version = CX23885_VERSION_CODE; | 1017 | cap->version = CX23885_VERSION_CODE; |
1018 | cap->capabilities = | 1018 | cap->capabilities = |
1019 | V4L2_CAP_VIDEO_CAPTURE | | 1019 | V4L2_CAP_VIDEO_CAPTURE | |
1020 | V4L2_CAP_READWRITE | | 1020 | V4L2_CAP_READWRITE | |
1021 | V4L2_CAP_STREAMING | | 1021 | V4L2_CAP_STREAMING | |
1022 | V4L2_CAP_VBI_CAPTURE; | 1022 | V4L2_CAP_VBI_CAPTURE; |
1023 | if (UNSET != dev->tuner_type) | 1023 | if (UNSET != dev->tuner_type) |
1024 | cap->capabilities |= V4L2_CAP_TUNER; | 1024 | cap->capabilities |= V4L2_CAP_TUNER; |
1025 | return 0; | 1025 | return 0; |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | static int vidioc_enum_fmt_cap(struct file *file, void *priv, | 1028 | static int vidioc_enum_fmt_cap(struct file *file, void *priv, |
1029 | struct v4l2_fmtdesc *f) | 1029 | struct v4l2_fmtdesc *f) |
1030 | { | 1030 | { |
1031 | if (unlikely(f->index >= ARRAY_SIZE(formats))) | 1031 | if (unlikely(f->index >= ARRAY_SIZE(formats))) |
1032 | return -EINVAL; | 1032 | return -EINVAL; |
1033 | 1033 | ||
1034 | strlcpy(f->description, formats[f->index].name, | 1034 | strlcpy(f->description, formats[f->index].name, |
1035 | sizeof(f->description)); | 1035 | sizeof(f->description)); |
1036 | f->pixelformat = formats[f->index].fourcc; | 1036 | f->pixelformat = formats[f->index].fourcc; |
1037 | 1037 | ||
1038 | return 0; | 1038 | return 0; |
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1041 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1042 | static int vidiocgmbuf(struct file *file, void *priv, | 1042 | static int vidiocgmbuf(struct file *file, void *priv, |
1043 | struct video_mbuf *mbuf) | 1043 | struct video_mbuf *mbuf) |
1044 | { | 1044 | { |
1045 | struct cx23885_fh *fh = priv; | 1045 | struct cx23885_fh *fh = priv; |
1046 | struct videobuf_queue *q; | 1046 | struct videobuf_queue *q; |
1047 | struct v4l2_requestbuffers req; | 1047 | struct v4l2_requestbuffers req; |
1048 | unsigned int i; | 1048 | unsigned int i; |
1049 | int err; | 1049 | int err; |
1050 | 1050 | ||
1051 | q = get_queue(fh); | 1051 | q = get_queue(fh); |
1052 | memset(&req, 0, sizeof(req)); | 1052 | memset(&req, 0, sizeof(req)); |
1053 | req.type = q->type; | 1053 | req.type = q->type; |
1054 | req.count = 8; | 1054 | req.count = 8; |
1055 | req.memory = V4L2_MEMORY_MMAP; | 1055 | req.memory = V4L2_MEMORY_MMAP; |
1056 | err = videobuf_reqbufs(q, &req); | 1056 | err = videobuf_reqbufs(q, &req); |
1057 | if (err < 0) | 1057 | if (err < 0) |
1058 | return err; | 1058 | return err; |
1059 | 1059 | ||
1060 | mbuf->frames = req.count; | 1060 | mbuf->frames = req.count; |
1061 | mbuf->size = 0; | 1061 | mbuf->size = 0; |
1062 | for (i = 0; i < mbuf->frames; i++) { | 1062 | for (i = 0; i < mbuf->frames; i++) { |
1063 | mbuf->offsets[i] = q->bufs[i]->boff; | 1063 | mbuf->offsets[i] = q->bufs[i]->boff; |
1064 | mbuf->size += q->bufs[i]->bsize; | 1064 | mbuf->size += q->bufs[i]->bsize; |
1065 | } | 1065 | } |
1066 | return 0; | 1066 | return 0; |
1067 | } | 1067 | } |
1068 | #endif | 1068 | #endif |
1069 | 1069 | ||
1070 | static int vidioc_reqbufs(struct file *file, void *priv, | 1070 | static int vidioc_reqbufs(struct file *file, void *priv, |
1071 | struct v4l2_requestbuffers *p) | 1071 | struct v4l2_requestbuffers *p) |
1072 | { | 1072 | { |
1073 | struct cx23885_fh *fh = priv; | 1073 | struct cx23885_fh *fh = priv; |
1074 | return (videobuf_reqbufs(get_queue(fh), p)); | 1074 | return (videobuf_reqbufs(get_queue(fh), p)); |
1075 | } | 1075 | } |
1076 | 1076 | ||
1077 | static int vidioc_querybuf(struct file *file, void *priv, | 1077 | static int vidioc_querybuf(struct file *file, void *priv, |
1078 | struct v4l2_buffer *p) | 1078 | struct v4l2_buffer *p) |
1079 | { | 1079 | { |
1080 | struct cx23885_fh *fh = priv; | 1080 | struct cx23885_fh *fh = priv; |
1081 | return (videobuf_querybuf(get_queue(fh), p)); | 1081 | return (videobuf_querybuf(get_queue(fh), p)); |
1082 | } | 1082 | } |
1083 | 1083 | ||
1084 | static int vidioc_qbuf(struct file *file, void *priv, | 1084 | static int vidioc_qbuf(struct file *file, void *priv, |
1085 | struct v4l2_buffer *p) | 1085 | struct v4l2_buffer *p) |
1086 | { | 1086 | { |
1087 | struct cx23885_fh *fh = priv; | 1087 | struct cx23885_fh *fh = priv; |
1088 | return (videobuf_qbuf(get_queue(fh), p)); | 1088 | return (videobuf_qbuf(get_queue(fh), p)); |
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | static int vidioc_dqbuf(struct file *file, void *priv, | 1091 | static int vidioc_dqbuf(struct file *file, void *priv, |
1092 | struct v4l2_buffer *p) | 1092 | struct v4l2_buffer *p) |
1093 | { | 1093 | { |
1094 | struct cx23885_fh *fh = priv; | 1094 | struct cx23885_fh *fh = priv; |
1095 | return (videobuf_dqbuf(get_queue(fh), p, | 1095 | return (videobuf_dqbuf(get_queue(fh), p, |
1096 | file->f_flags & O_NONBLOCK)); | 1096 | file->f_flags & O_NONBLOCK)); |
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | static int vidioc_streamon(struct file *file, void *priv, | 1099 | static int vidioc_streamon(struct file *file, void *priv, |
1100 | enum v4l2_buf_type i) | 1100 | enum v4l2_buf_type i) |
1101 | { | 1101 | { |
1102 | struct cx23885_fh *fh = priv; | 1102 | struct cx23885_fh *fh = priv; |
1103 | struct cx23885_dev *dev = fh->dev; | 1103 | struct cx23885_dev *dev = fh->dev; |
1104 | dprintk(1, "%s()\n", __FUNCTION__); | 1104 | dprintk(1, "%s()\n", __func__); |
1105 | 1105 | ||
1106 | if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) | 1106 | if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) |
1107 | return -EINVAL; | 1107 | return -EINVAL; |
1108 | if (unlikely(i != fh->type)) | 1108 | if (unlikely(i != fh->type)) |
1109 | return -EINVAL; | 1109 | return -EINVAL; |
1110 | 1110 | ||
1111 | if (unlikely(!res_get(dev, fh, get_resource(fh)))) | 1111 | if (unlikely(!res_get(dev, fh, get_resource(fh)))) |
1112 | return -EBUSY; | 1112 | return -EBUSY; |
1113 | return videobuf_streamon(get_queue(fh)); | 1113 | return videobuf_streamon(get_queue(fh)); |
1114 | } | 1114 | } |
1115 | 1115 | ||
1116 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | 1116 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) |
1117 | { | 1117 | { |
1118 | struct cx23885_fh *fh = priv; | 1118 | struct cx23885_fh *fh = priv; |
1119 | struct cx23885_dev *dev = fh->dev; | 1119 | struct cx23885_dev *dev = fh->dev; |
1120 | int err, res; | 1120 | int err, res; |
1121 | dprintk(1, "%s()\n", __FUNCTION__); | 1121 | dprintk(1, "%s()\n", __func__); |
1122 | 1122 | ||
1123 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1123 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1124 | return -EINVAL; | 1124 | return -EINVAL; |
1125 | if (i != fh->type) | 1125 | if (i != fh->type) |
1126 | return -EINVAL; | 1126 | return -EINVAL; |
1127 | 1127 | ||
1128 | res = get_resource(fh); | 1128 | res = get_resource(fh); |
1129 | err = videobuf_streamoff(get_queue(fh)); | 1129 | err = videobuf_streamoff(get_queue(fh)); |
1130 | if (err < 0) | 1130 | if (err < 0) |
1131 | return err; | 1131 | return err; |
1132 | res_free(dev, fh, res); | 1132 | res_free(dev, fh, res); |
1133 | return 0; | 1133 | return 0; |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms) | 1136 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms) |
1137 | { | 1137 | { |
1138 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1138 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1139 | dprintk(1, "%s()\n", __FUNCTION__); | 1139 | dprintk(1, "%s()\n", __func__); |
1140 | 1140 | ||
1141 | mutex_lock(&dev->lock); | 1141 | mutex_lock(&dev->lock); |
1142 | cx23885_set_tvnorm(dev, *tvnorms); | 1142 | cx23885_set_tvnorm(dev, *tvnorms); |
1143 | mutex_unlock(&dev->lock); | 1143 | mutex_unlock(&dev->lock); |
1144 | 1144 | ||
1145 | return 0; | 1145 | return 0; |
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) | 1148 | int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) |
1149 | { | 1149 | { |
1150 | static const char *iname[] = { | 1150 | static const char *iname[] = { |
1151 | [CX23885_VMUX_COMPOSITE1] = "Composite1", | 1151 | [CX23885_VMUX_COMPOSITE1] = "Composite1", |
1152 | [CX23885_VMUX_COMPOSITE2] = "Composite2", | 1152 | [CX23885_VMUX_COMPOSITE2] = "Composite2", |
1153 | [CX23885_VMUX_COMPOSITE3] = "Composite3", | 1153 | [CX23885_VMUX_COMPOSITE3] = "Composite3", |
1154 | [CX23885_VMUX_COMPOSITE4] = "Composite4", | 1154 | [CX23885_VMUX_COMPOSITE4] = "Composite4", |
1155 | [CX23885_VMUX_SVIDEO] = "S-Video", | 1155 | [CX23885_VMUX_SVIDEO] = "S-Video", |
1156 | [CX23885_VMUX_TELEVISION] = "Television", | 1156 | [CX23885_VMUX_TELEVISION] = "Television", |
1157 | [CX23885_VMUX_CABLE] = "Cable TV", | 1157 | [CX23885_VMUX_CABLE] = "Cable TV", |
1158 | [CX23885_VMUX_DVB] = "DVB", | 1158 | [CX23885_VMUX_DVB] = "DVB", |
1159 | [CX23885_VMUX_DEBUG] = "for debug only", | 1159 | [CX23885_VMUX_DEBUG] = "for debug only", |
1160 | }; | 1160 | }; |
1161 | unsigned int n; | 1161 | unsigned int n; |
1162 | dprintk(1, "%s()\n", __FUNCTION__); | 1162 | dprintk(1, "%s()\n", __func__); |
1163 | 1163 | ||
1164 | n = i->index; | 1164 | n = i->index; |
1165 | if (n >= 4) | 1165 | if (n >= 4) |
1166 | return -EINVAL; | 1166 | return -EINVAL; |
1167 | 1167 | ||
1168 | if (0 == INPUT(n)->type) | 1168 | if (0 == INPUT(n)->type) |
1169 | return -EINVAL; | 1169 | return -EINVAL; |
1170 | 1170 | ||
1171 | memset(i, 0, sizeof(*i)); | 1171 | memset(i, 0, sizeof(*i)); |
1172 | i->index = n; | 1172 | i->index = n; |
1173 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1173 | i->type = V4L2_INPUT_TYPE_CAMERA; |
1174 | strcpy(i->name, iname[INPUT(n)->type]); | 1174 | strcpy(i->name, iname[INPUT(n)->type]); |
1175 | if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) || | 1175 | if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) || |
1176 | (CX23885_VMUX_CABLE == INPUT(n)->type)) | 1176 | (CX23885_VMUX_CABLE == INPUT(n)->type)) |
1177 | i->type = V4L2_INPUT_TYPE_TUNER; | 1177 | i->type = V4L2_INPUT_TYPE_TUNER; |
1178 | i->std = CX23885_NORMS; | 1178 | i->std = CX23885_NORMS; |
1179 | return 0; | 1179 | return 0; |
1180 | } | 1180 | } |
1181 | EXPORT_SYMBOL(cx23885_enum_input); | 1181 | EXPORT_SYMBOL(cx23885_enum_input); |
1182 | 1182 | ||
1183 | static int vidioc_enum_input(struct file *file, void *priv, | 1183 | static int vidioc_enum_input(struct file *file, void *priv, |
1184 | struct v4l2_input *i) | 1184 | struct v4l2_input *i) |
1185 | { | 1185 | { |
1186 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1186 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1187 | dprintk(1, "%s()\n", __FUNCTION__); | 1187 | dprintk(1, "%s()\n", __func__); |
1188 | return cx23885_enum_input(dev, i); | 1188 | return cx23885_enum_input(dev, i); |
1189 | } | 1189 | } |
1190 | 1190 | ||
1191 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | 1191 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) |
1192 | { | 1192 | { |
1193 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1193 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1194 | 1194 | ||
1195 | *i = dev->input; | 1195 | *i = dev->input; |
1196 | dprintk(1, "%s() returns %d\n", __FUNCTION__, *i); | 1196 | dprintk(1, "%s() returns %d\n", __func__, *i); |
1197 | return 0; | 1197 | return 0; |
1198 | } | 1198 | } |
1199 | 1199 | ||
1200 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | 1200 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) |
1201 | { | 1201 | { |
1202 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1202 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1203 | 1203 | ||
1204 | dprintk(1, "%s(%d)\n", __FUNCTION__, i); | 1204 | dprintk(1, "%s(%d)\n", __func__, i); |
1205 | 1205 | ||
1206 | if (i >= 4) { | 1206 | if (i >= 4) { |
1207 | dprintk(1, "%s() -EINVAL\n", __FUNCTION__); | 1207 | dprintk(1, "%s() -EINVAL\n", __func__); |
1208 | return -EINVAL; | 1208 | return -EINVAL; |
1209 | } | 1209 | } |
1210 | 1210 | ||
1211 | mutex_lock(&dev->lock); | 1211 | mutex_lock(&dev->lock); |
1212 | cx23885_video_mux(dev, i); | 1212 | cx23885_video_mux(dev, i); |
1213 | mutex_unlock(&dev->lock); | 1213 | mutex_unlock(&dev->lock); |
1214 | return 0; | 1214 | return 0; |
1215 | } | 1215 | } |
1216 | 1216 | ||
1217 | static int vidioc_queryctrl(struct file *file, void *priv, | 1217 | static int vidioc_queryctrl(struct file *file, void *priv, |
1218 | struct v4l2_queryctrl *qctrl) | 1218 | struct v4l2_queryctrl *qctrl) |
1219 | { | 1219 | { |
1220 | qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); | 1220 | qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); |
1221 | if (unlikely(qctrl->id == 0)) | 1221 | if (unlikely(qctrl->id == 0)) |
1222 | return -EINVAL; | 1222 | return -EINVAL; |
1223 | return cx23885_ctrl_query(qctrl); | 1223 | return cx23885_ctrl_query(qctrl); |
1224 | } | 1224 | } |
1225 | 1225 | ||
1226 | static int vidioc_g_ctrl(struct file *file, void *priv, | 1226 | static int vidioc_g_ctrl(struct file *file, void *priv, |
1227 | struct v4l2_control *ctl) | 1227 | struct v4l2_control *ctl) |
1228 | { | 1228 | { |
1229 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1229 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1230 | 1230 | ||
1231 | return cx23885_get_control(dev, ctl); | 1231 | return cx23885_get_control(dev, ctl); |
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | static int vidioc_s_ctrl(struct file *file, void *priv, | 1234 | static int vidioc_s_ctrl(struct file *file, void *priv, |
1235 | struct v4l2_control *ctl) | 1235 | struct v4l2_control *ctl) |
1236 | { | 1236 | { |
1237 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1237 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1238 | 1238 | ||
1239 | return cx23885_set_control(dev, ctl); | 1239 | return cx23885_set_control(dev, ctl); |
1240 | } | 1240 | } |
1241 | 1241 | ||
1242 | static int vidioc_g_tuner(struct file *file, void *priv, | 1242 | static int vidioc_g_tuner(struct file *file, void *priv, |
1243 | struct v4l2_tuner *t) | 1243 | struct v4l2_tuner *t) |
1244 | { | 1244 | { |
1245 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1245 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1246 | 1246 | ||
1247 | if (unlikely(UNSET == dev->tuner_type)) | 1247 | if (unlikely(UNSET == dev->tuner_type)) |
1248 | return -EINVAL; | 1248 | return -EINVAL; |
1249 | if (0 != t->index) | 1249 | if (0 != t->index) |
1250 | return -EINVAL; | 1250 | return -EINVAL; |
1251 | 1251 | ||
1252 | strcpy(t->name, "Television"); | 1252 | strcpy(t->name, "Television"); |
1253 | t->type = V4L2_TUNER_ANALOG_TV; | 1253 | t->type = V4L2_TUNER_ANALOG_TV; |
1254 | t->capability = V4L2_TUNER_CAP_NORM; | 1254 | t->capability = V4L2_TUNER_CAP_NORM; |
1255 | t->rangehigh = 0xffffffffUL; | 1255 | t->rangehigh = 0xffffffffUL; |
1256 | t->signal = 0xffff ; /* LOCKED */ | 1256 | t->signal = 0xffff ; /* LOCKED */ |
1257 | return 0; | 1257 | return 0; |
1258 | } | 1258 | } |
1259 | 1259 | ||
1260 | static int vidioc_s_tuner(struct file *file, void *priv, | 1260 | static int vidioc_s_tuner(struct file *file, void *priv, |
1261 | struct v4l2_tuner *t) | 1261 | struct v4l2_tuner *t) |
1262 | { | 1262 | { |
1263 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; | 1263 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
1264 | 1264 | ||
1265 | if (UNSET == dev->tuner_type) | 1265 | if (UNSET == dev->tuner_type) |
1266 | return -EINVAL; | 1266 | return -EINVAL; |
1267 | if (0 != t->index) | 1267 | if (0 != t->index) |
1268 | return -EINVAL; | 1268 | return -EINVAL; |
1269 | return 0; | 1269 | return 0; |
1270 | } | 1270 | } |
1271 | 1271 | ||
1272 | static int vidioc_g_frequency(struct file *file, void *priv, | 1272 | static int vidioc_g_frequency(struct file *file, void *priv, |
1273 | struct v4l2_frequency *f) | 1273 | struct v4l2_frequency *f) |
1274 | { | 1274 | { |
1275 | struct cx23885_fh *fh = priv; | 1275 | struct cx23885_fh *fh = priv; |
1276 | struct cx23885_dev *dev = fh->dev; | 1276 | struct cx23885_dev *dev = fh->dev; |
1277 | 1277 | ||
1278 | if (unlikely(UNSET == dev->tuner_type)) | 1278 | if (unlikely(UNSET == dev->tuner_type)) |
1279 | return -EINVAL; | 1279 | return -EINVAL; |
1280 | 1280 | ||
1281 | /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */ | 1281 | /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */ |
1282 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1282 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
1283 | f->frequency = dev->freq; | 1283 | f->frequency = dev->freq; |
1284 | 1284 | ||
1285 | cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f); | 1285 | cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f); |
1286 | 1286 | ||
1287 | return 0; | 1287 | return 0; |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f) | 1290 | int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f) |
1291 | { | 1291 | { |
1292 | if (unlikely(UNSET == dev->tuner_type)) | 1292 | if (unlikely(UNSET == dev->tuner_type)) |
1293 | return -EINVAL; | 1293 | return -EINVAL; |
1294 | if (unlikely(f->tuner != 0)) | 1294 | if (unlikely(f->tuner != 0)) |
1295 | return -EINVAL; | 1295 | return -EINVAL; |
1296 | 1296 | ||
1297 | mutex_lock(&dev->lock); | 1297 | mutex_lock(&dev->lock); |
1298 | dev->freq = f->frequency; | 1298 | dev->freq = f->frequency; |
1299 | 1299 | ||
1300 | cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f); | 1300 | cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f); |
1301 | 1301 | ||
1302 | /* When changing channels it is required to reset TVAUDIO */ | 1302 | /* When changing channels it is required to reset TVAUDIO */ |
1303 | msleep(10); | 1303 | msleep(10); |
1304 | 1304 | ||
1305 | mutex_unlock(&dev->lock); | 1305 | mutex_unlock(&dev->lock); |
1306 | 1306 | ||
1307 | return 0; | 1307 | return 0; |
1308 | } | 1308 | } |
1309 | EXPORT_SYMBOL(cx23885_set_freq); | 1309 | EXPORT_SYMBOL(cx23885_set_freq); |
1310 | 1310 | ||
1311 | static int vidioc_s_frequency(struct file *file, void *priv, | 1311 | static int vidioc_s_frequency(struct file *file, void *priv, |
1312 | struct v4l2_frequency *f) | 1312 | struct v4l2_frequency *f) |
1313 | { | 1313 | { |
1314 | struct cx23885_fh *fh = priv; | 1314 | struct cx23885_fh *fh = priv; |
1315 | struct cx23885_dev *dev = fh->dev; | 1315 | struct cx23885_dev *dev = fh->dev; |
1316 | 1316 | ||
1317 | if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV)) | 1317 | if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV)) |
1318 | return -EINVAL; | 1318 | return -EINVAL; |
1319 | if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO)) | 1319 | if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO)) |
1320 | return -EINVAL; | 1320 | return -EINVAL; |
1321 | 1321 | ||
1322 | return | 1322 | return |
1323 | cx23885_set_freq(dev, f); | 1323 | cx23885_set_freq(dev, f); |
1324 | } | 1324 | } |
1325 | 1325 | ||
1326 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1326 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1327 | static int vidioc_g_register(struct file *file, void *fh, | 1327 | static int vidioc_g_register(struct file *file, void *fh, |
1328 | struct v4l2_register *reg) | 1328 | struct v4l2_register *reg) |
1329 | { | 1329 | { |
1330 | struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; | 1330 | struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; |
1331 | 1331 | ||
1332 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 1332 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) |
1333 | return -EINVAL; | 1333 | return -EINVAL; |
1334 | 1334 | ||
1335 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg); | 1335 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg); |
1336 | 1336 | ||
1337 | return 0; | 1337 | return 0; |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | static int vidioc_s_register(struct file *file, void *fh, | 1340 | static int vidioc_s_register(struct file *file, void *fh, |
1341 | struct v4l2_register *reg) | 1341 | struct v4l2_register *reg) |
1342 | { | 1342 | { |
1343 | struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; | 1343 | struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; |
1344 | 1344 | ||
1345 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 1345 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) |
1346 | return -EINVAL; | 1346 | return -EINVAL; |
1347 | 1347 | ||
1348 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg); | 1348 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg); |
1349 | 1349 | ||
1350 | return 0; | 1350 | return 0; |
1351 | } | 1351 | } |
1352 | #endif | 1352 | #endif |
1353 | 1353 | ||
1354 | /* ----------------------------------------------------------- */ | 1354 | /* ----------------------------------------------------------- */ |
1355 | 1355 | ||
1356 | static void cx23885_vid_timeout(unsigned long data) | 1356 | static void cx23885_vid_timeout(unsigned long data) |
1357 | { | 1357 | { |
1358 | struct cx23885_dev *dev = (struct cx23885_dev *)data; | 1358 | struct cx23885_dev *dev = (struct cx23885_dev *)data; |
1359 | struct cx23885_dmaqueue *q = &dev->vidq; | 1359 | struct cx23885_dmaqueue *q = &dev->vidq; |
1360 | struct cx23885_buffer *buf; | 1360 | struct cx23885_buffer *buf; |
1361 | unsigned long flags; | 1361 | unsigned long flags; |
1362 | 1362 | ||
1363 | cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH01]); | 1363 | cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH01]); |
1364 | 1364 | ||
1365 | cx_clear(VID_A_DMA_CTL, 0x11); | 1365 | cx_clear(VID_A_DMA_CTL, 0x11); |
1366 | 1366 | ||
1367 | spin_lock_irqsave(&dev->slock, flags); | 1367 | spin_lock_irqsave(&dev->slock, flags); |
1368 | while (!list_empty(&q->active)) { | 1368 | while (!list_empty(&q->active)) { |
1369 | buf = list_entry(q->active.next, | 1369 | buf = list_entry(q->active.next, |
1370 | struct cx23885_buffer, vb.queue); | 1370 | struct cx23885_buffer, vb.queue); |
1371 | list_del(&buf->vb.queue); | 1371 | list_del(&buf->vb.queue); |
1372 | buf->vb.state = VIDEOBUF_ERROR; | 1372 | buf->vb.state = VIDEOBUF_ERROR; |
1373 | wake_up(&buf->vb.done); | 1373 | wake_up(&buf->vb.done); |
1374 | printk(KERN_ERR "%s/0: [%p/%d] timeout - dma=0x%08lx\n", | 1374 | printk(KERN_ERR "%s/0: [%p/%d] timeout - dma=0x%08lx\n", |
1375 | dev->name, buf, buf->vb.i, | 1375 | dev->name, buf, buf->vb.i, |
1376 | (unsigned long)buf->risc.dma); | 1376 | (unsigned long)buf->risc.dma); |
1377 | } | 1377 | } |
1378 | cx23885_restart_video_queue(dev, q); | 1378 | cx23885_restart_video_queue(dev, q); |
1379 | spin_unlock_irqrestore(&dev->slock, flags); | 1379 | spin_unlock_irqrestore(&dev->slock, flags); |
1380 | } | 1380 | } |
1381 | 1381 | ||
1382 | int cx23885_video_irq(struct cx23885_dev *dev, u32 status) | 1382 | int cx23885_video_irq(struct cx23885_dev *dev, u32 status) |
1383 | { | 1383 | { |
1384 | u32 mask, count; | 1384 | u32 mask, count; |
1385 | int handled = 0; | 1385 | int handled = 0; |
1386 | 1386 | ||
1387 | mask = cx_read(VID_A_INT_MSK); | 1387 | mask = cx_read(VID_A_INT_MSK); |
1388 | if (0 == (status & mask)) | 1388 | if (0 == (status & mask)) |
1389 | return handled; | 1389 | return handled; |
1390 | cx_write(VID_A_INT_STAT, status); | 1390 | cx_write(VID_A_INT_STAT, status); |
1391 | 1391 | ||
1392 | dprintk(2, "%s() status = 0x%08x\n", __FUNCTION__, status); | 1392 | dprintk(2, "%s() status = 0x%08x\n", __func__, status); |
1393 | /* risc op code error */ | 1393 | /* risc op code error */ |
1394 | if (status & (1 << 16)) { | 1394 | if (status & (1 << 16)) { |
1395 | printk(KERN_WARNING "%s/0: video risc op code error\n", | 1395 | printk(KERN_WARNING "%s/0: video risc op code error\n", |
1396 | dev->name); | 1396 | dev->name); |
1397 | cx_clear(VID_A_DMA_CTL, 0x11); | 1397 | cx_clear(VID_A_DMA_CTL, 0x11); |
1398 | cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH01]); | 1398 | cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH01]); |
1399 | } | 1399 | } |
1400 | 1400 | ||
1401 | /* risc1 y */ | 1401 | /* risc1 y */ |
1402 | if (status & 0x01) { | 1402 | if (status & 0x01) { |
1403 | spin_lock(&dev->slock); | 1403 | spin_lock(&dev->slock); |
1404 | count = cx_read(VID_A_GPCNT); | 1404 | count = cx_read(VID_A_GPCNT); |
1405 | cx23885_video_wakeup(dev, &dev->vidq, count); | 1405 | cx23885_video_wakeup(dev, &dev->vidq, count); |
1406 | spin_unlock(&dev->slock); | 1406 | spin_unlock(&dev->slock); |
1407 | handled++; | 1407 | handled++; |
1408 | } | 1408 | } |
1409 | /* risc2 y */ | 1409 | /* risc2 y */ |
1410 | if (status & 0x10) { | 1410 | if (status & 0x10) { |
1411 | dprintk(2, "stopper video\n"); | 1411 | dprintk(2, "stopper video\n"); |
1412 | spin_lock(&dev->slock); | 1412 | spin_lock(&dev->slock); |
1413 | cx23885_restart_video_queue(dev, &dev->vidq); | 1413 | cx23885_restart_video_queue(dev, &dev->vidq); |
1414 | spin_unlock(&dev->slock); | 1414 | spin_unlock(&dev->slock); |
1415 | handled++; | 1415 | handled++; |
1416 | } | 1416 | } |
1417 | 1417 | ||
1418 | return handled; | 1418 | return handled; |
1419 | } | 1419 | } |
1420 | 1420 | ||
1421 | /* ----------------------------------------------------------- */ | 1421 | /* ----------------------------------------------------------- */ |
1422 | /* exported stuff */ | 1422 | /* exported stuff */ |
1423 | 1423 | ||
1424 | static const struct file_operations video_fops = { | 1424 | static const struct file_operations video_fops = { |
1425 | .owner = THIS_MODULE, | 1425 | .owner = THIS_MODULE, |
1426 | .open = video_open, | 1426 | .open = video_open, |
1427 | .release = video_release, | 1427 | .release = video_release, |
1428 | .read = video_read, | 1428 | .read = video_read, |
1429 | .poll = video_poll, | 1429 | .poll = video_poll, |
1430 | .mmap = video_mmap, | 1430 | .mmap = video_mmap, |
1431 | .ioctl = video_ioctl2, | 1431 | .ioctl = video_ioctl2, |
1432 | .compat_ioctl = v4l_compat_ioctl32, | 1432 | .compat_ioctl = v4l_compat_ioctl32, |
1433 | .llseek = no_llseek, | 1433 | .llseek = no_llseek, |
1434 | }; | 1434 | }; |
1435 | 1435 | ||
1436 | static struct video_device cx23885_vbi_template; | 1436 | static struct video_device cx23885_vbi_template; |
1437 | static struct video_device cx23885_video_template = { | 1437 | static struct video_device cx23885_video_template = { |
1438 | .name = "cx23885-video", | 1438 | .name = "cx23885-video", |
1439 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, | 1439 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, |
1440 | .fops = &video_fops, | 1440 | .fops = &video_fops, |
1441 | .minor = -1, | 1441 | .minor = -1, |
1442 | .vidioc_querycap = vidioc_querycap, | 1442 | .vidioc_querycap = vidioc_querycap, |
1443 | .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, | 1443 | .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, |
1444 | .vidioc_g_fmt_cap = vidioc_g_fmt_cap, | 1444 | .vidioc_g_fmt_cap = vidioc_g_fmt_cap, |
1445 | .vidioc_try_fmt_cap = vidioc_try_fmt_cap, | 1445 | .vidioc_try_fmt_cap = vidioc_try_fmt_cap, |
1446 | .vidioc_s_fmt_cap = vidioc_s_fmt_cap, | 1446 | .vidioc_s_fmt_cap = vidioc_s_fmt_cap, |
1447 | .vidioc_g_fmt_vbi = cx23885_vbi_fmt, | 1447 | .vidioc_g_fmt_vbi = cx23885_vbi_fmt, |
1448 | .vidioc_try_fmt_vbi = cx23885_vbi_fmt, | 1448 | .vidioc_try_fmt_vbi = cx23885_vbi_fmt, |
1449 | .vidioc_s_fmt_vbi = cx23885_vbi_fmt, | 1449 | .vidioc_s_fmt_vbi = cx23885_vbi_fmt, |
1450 | .vidioc_reqbufs = vidioc_reqbufs, | 1450 | .vidioc_reqbufs = vidioc_reqbufs, |
1451 | .vidioc_querybuf = vidioc_querybuf, | 1451 | .vidioc_querybuf = vidioc_querybuf, |
1452 | .vidioc_qbuf = vidioc_qbuf, | 1452 | .vidioc_qbuf = vidioc_qbuf, |
1453 | .vidioc_dqbuf = vidioc_dqbuf, | 1453 | .vidioc_dqbuf = vidioc_dqbuf, |
1454 | .vidioc_s_std = vidioc_s_std, | 1454 | .vidioc_s_std = vidioc_s_std, |
1455 | .vidioc_enum_input = vidioc_enum_input, | 1455 | .vidioc_enum_input = vidioc_enum_input, |
1456 | .vidioc_g_input = vidioc_g_input, | 1456 | .vidioc_g_input = vidioc_g_input, |
1457 | .vidioc_s_input = vidioc_s_input, | 1457 | .vidioc_s_input = vidioc_s_input, |
1458 | .vidioc_queryctrl = vidioc_queryctrl, | 1458 | .vidioc_queryctrl = vidioc_queryctrl, |
1459 | .vidioc_g_ctrl = vidioc_g_ctrl, | 1459 | .vidioc_g_ctrl = vidioc_g_ctrl, |
1460 | .vidioc_s_ctrl = vidioc_s_ctrl, | 1460 | .vidioc_s_ctrl = vidioc_s_ctrl, |
1461 | .vidioc_streamon = vidioc_streamon, | 1461 | .vidioc_streamon = vidioc_streamon, |
1462 | .vidioc_streamoff = vidioc_streamoff, | 1462 | .vidioc_streamoff = vidioc_streamoff, |
1463 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1463 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1464 | .vidiocgmbuf = vidiocgmbuf, | 1464 | .vidiocgmbuf = vidiocgmbuf, |
1465 | #endif | 1465 | #endif |
1466 | .vidioc_g_tuner = vidioc_g_tuner, | 1466 | .vidioc_g_tuner = vidioc_g_tuner, |
1467 | .vidioc_s_tuner = vidioc_s_tuner, | 1467 | .vidioc_s_tuner = vidioc_s_tuner, |
1468 | .vidioc_g_frequency = vidioc_g_frequency, | 1468 | .vidioc_g_frequency = vidioc_g_frequency, |
1469 | .vidioc_s_frequency = vidioc_s_frequency, | 1469 | .vidioc_s_frequency = vidioc_s_frequency, |
1470 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1470 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1471 | .vidioc_g_register = vidioc_g_register, | 1471 | .vidioc_g_register = vidioc_g_register, |
1472 | .vidioc_s_register = vidioc_s_register, | 1472 | .vidioc_s_register = vidioc_s_register, |
1473 | #endif | 1473 | #endif |
1474 | .tvnorms = CX23885_NORMS, | 1474 | .tvnorms = CX23885_NORMS, |
1475 | .current_norm = V4L2_STD_NTSC_M, | 1475 | .current_norm = V4L2_STD_NTSC_M, |
1476 | }; | 1476 | }; |
1477 | 1477 | ||
1478 | static const struct file_operations radio_fops = { | 1478 | static const struct file_operations radio_fops = { |
1479 | .owner = THIS_MODULE, | 1479 | .owner = THIS_MODULE, |
1480 | .open = video_open, | 1480 | .open = video_open, |
1481 | .release = video_release, | 1481 | .release = video_release, |
1482 | .ioctl = video_ioctl2, | 1482 | .ioctl = video_ioctl2, |
1483 | .compat_ioctl = v4l_compat_ioctl32, | 1483 | .compat_ioctl = v4l_compat_ioctl32, |
1484 | .llseek = no_llseek, | 1484 | .llseek = no_llseek, |
1485 | }; | 1485 | }; |
1486 | 1486 | ||
1487 | 1487 | ||
1488 | void cx23885_video_unregister(struct cx23885_dev *dev) | 1488 | void cx23885_video_unregister(struct cx23885_dev *dev) |
1489 | { | 1489 | { |
1490 | dprintk(1, "%s()\n", __FUNCTION__); | 1490 | dprintk(1, "%s()\n", __func__); |
1491 | cx_clear(PCI_INT_MSK, 1); | 1491 | cx_clear(PCI_INT_MSK, 1); |
1492 | 1492 | ||
1493 | if (dev->video_dev) { | 1493 | if (dev->video_dev) { |
1494 | if (-1 != dev->video_dev->minor) | 1494 | if (-1 != dev->video_dev->minor) |
1495 | video_unregister_device(dev->video_dev); | 1495 | video_unregister_device(dev->video_dev); |
1496 | else | 1496 | else |
1497 | video_device_release(dev->video_dev); | 1497 | video_device_release(dev->video_dev); |
1498 | dev->video_dev = NULL; | 1498 | dev->video_dev = NULL; |
1499 | 1499 | ||
1500 | btcx_riscmem_free(dev->pci, &dev->vidq.stopper); | 1500 | btcx_riscmem_free(dev->pci, &dev->vidq.stopper); |
1501 | } | 1501 | } |
1502 | } | 1502 | } |
1503 | 1503 | ||
1504 | int cx23885_video_register(struct cx23885_dev *dev) | 1504 | int cx23885_video_register(struct cx23885_dev *dev) |
1505 | { | 1505 | { |
1506 | int err; | 1506 | int err; |
1507 | 1507 | ||
1508 | dprintk(1, "%s()\n", __FUNCTION__); | 1508 | dprintk(1, "%s()\n", __func__); |
1509 | spin_lock_init(&dev->slock); | 1509 | spin_lock_init(&dev->slock); |
1510 | 1510 | ||
1511 | /* Initialize VBI template */ | 1511 | /* Initialize VBI template */ |
1512 | memcpy(&cx23885_vbi_template, &cx23885_video_template, | 1512 | memcpy(&cx23885_vbi_template, &cx23885_video_template, |
1513 | sizeof(cx23885_vbi_template)); | 1513 | sizeof(cx23885_vbi_template)); |
1514 | strcpy(cx23885_vbi_template.name, "cx23885-vbi"); | 1514 | strcpy(cx23885_vbi_template.name, "cx23885-vbi"); |
1515 | cx23885_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER; | 1515 | cx23885_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER; |
1516 | 1516 | ||
1517 | dev->tvnorm = cx23885_video_template.current_norm; | 1517 | dev->tvnorm = cx23885_video_template.current_norm; |
1518 | 1518 | ||
1519 | /* init video dma queues */ | 1519 | /* init video dma queues */ |
1520 | INIT_LIST_HEAD(&dev->vidq.active); | 1520 | INIT_LIST_HEAD(&dev->vidq.active); |
1521 | INIT_LIST_HEAD(&dev->vidq.queued); | 1521 | INIT_LIST_HEAD(&dev->vidq.queued); |
1522 | dev->vidq.timeout.function = cx23885_vid_timeout; | 1522 | dev->vidq.timeout.function = cx23885_vid_timeout; |
1523 | dev->vidq.timeout.data = (unsigned long)dev; | 1523 | dev->vidq.timeout.data = (unsigned long)dev; |
1524 | init_timer(&dev->vidq.timeout); | 1524 | init_timer(&dev->vidq.timeout); |
1525 | cx23885_risc_stopper(dev->pci, &dev->vidq.stopper, | 1525 | cx23885_risc_stopper(dev->pci, &dev->vidq.stopper, |
1526 | VID_A_DMA_CTL, 0x11, 0x00); | 1526 | VID_A_DMA_CTL, 0x11, 0x00); |
1527 | 1527 | ||
1528 | /* Don't enable VBI yet */ | 1528 | /* Don't enable VBI yet */ |
1529 | cx_set(PCI_INT_MSK, 1); | 1529 | cx_set(PCI_INT_MSK, 1); |
1530 | 1530 | ||
1531 | 1531 | ||
1532 | /* register v4l devices */ | 1532 | /* register v4l devices */ |
1533 | dev->video_dev = cx23885_vdev_init(dev, dev->pci, | 1533 | dev->video_dev = cx23885_vdev_init(dev, dev->pci, |
1534 | &cx23885_video_template, "video"); | 1534 | &cx23885_video_template, "video"); |
1535 | err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, | 1535 | err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, |
1536 | video_nr[dev->nr]); | 1536 | video_nr[dev->nr]); |
1537 | if (err < 0) { | 1537 | if (err < 0) { |
1538 | printk(KERN_INFO "%s: can't register video device\n", | 1538 | printk(KERN_INFO "%s: can't register video device\n", |
1539 | dev->name); | 1539 | dev->name); |
1540 | goto fail_unreg; | 1540 | goto fail_unreg; |
1541 | } | 1541 | } |
1542 | printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n", | 1542 | printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n", |
1543 | dev->name, dev->video_dev->minor & 0x1f); | 1543 | dev->name, dev->video_dev->minor & 0x1f); |
1544 | /* initial device configuration */ | 1544 | /* initial device configuration */ |
1545 | mutex_lock(&dev->lock); | 1545 | mutex_lock(&dev->lock); |
1546 | cx23885_set_tvnorm(dev, dev->tvnorm); | 1546 | cx23885_set_tvnorm(dev, dev->tvnorm); |
1547 | init_controls(dev); | 1547 | init_controls(dev); |
1548 | cx23885_video_mux(dev, 0); | 1548 | cx23885_video_mux(dev, 0); |
1549 | mutex_unlock(&dev->lock); | 1549 | mutex_unlock(&dev->lock); |
1550 | 1550 | ||
1551 | return 0; | 1551 | return 0; |
1552 | 1552 | ||
1553 | fail_unreg: | 1553 | fail_unreg: |
1554 | cx23885_video_unregister(dev); | 1554 | cx23885_video_unregister(dev); |
1555 | return err; | 1555 | return err; |
1556 | } | 1556 | } |
1557 | 1557 | ||
1558 | 1558 |