1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * |
4 | * Support for a cx23417 mpeg encoder via cx231xx host port. |
5 | * |
6 | * (c) 2004 Jelle Foks <jelle@foks.us> |
7 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> |
8 | * (c) 2008 Steven Toth <stoth@linuxtv.org> |
9 | * - CX23885/7/8 support |
10 | * |
11 | * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/), |
12 | */ |
13 | |
14 | #include "cx231xx.h" |
15 | |
16 | #include <linux/module.h> |
17 | #include <linux/moduleparam.h> |
18 | #include <linux/init.h> |
19 | #include <linux/fs.h> |
20 | #include <linux/delay.h> |
21 | #include <linux/device.h> |
22 | #include <linux/firmware.h> |
23 | #include <linux/slab.h> |
24 | #include <linux/vmalloc.h> |
25 | #include <media/v4l2-common.h> |
26 | #include <media/v4l2-ioctl.h> |
27 | #include <media/v4l2-event.h> |
28 | #include <media/drv-intf/cx2341x.h> |
29 | #include <media/tuner.h> |
30 | |
31 | #define CX231xx_FIRM_IMAGE_SIZE 376836 |
32 | #define CX231xx_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" |
33 | |
34 | /* for polaris ITVC */ |
35 | #define ITVC_WRITE_DIR 0x03FDFC00 |
36 | #define ITVC_READ_DIR 0x0001FC00 |
37 | |
38 | #define MCI_MEMORY_DATA_BYTE0 0x00 |
39 | #define MCI_MEMORY_DATA_BYTE1 0x08 |
40 | #define MCI_MEMORY_DATA_BYTE2 0x10 |
41 | #define MCI_MEMORY_DATA_BYTE3 0x18 |
42 | |
43 | #define MCI_MEMORY_ADDRESS_BYTE2 0x20 |
44 | #define MCI_MEMORY_ADDRESS_BYTE1 0x28 |
45 | #define MCI_MEMORY_ADDRESS_BYTE0 0x30 |
46 | |
47 | #define MCI_REGISTER_DATA_BYTE0 0x40 |
48 | #define MCI_REGISTER_DATA_BYTE1 0x48 |
49 | #define MCI_REGISTER_DATA_BYTE2 0x50 |
50 | #define MCI_REGISTER_DATA_BYTE3 0x58 |
51 | |
52 | #define MCI_REGISTER_ADDRESS_BYTE0 0x60 |
53 | #define MCI_REGISTER_ADDRESS_BYTE1 0x68 |
54 | |
55 | #define MCI_REGISTER_MODE 0x70 |
56 | |
57 | /* Read and write modes for polaris ITVC */ |
58 | #define MCI_MODE_REGISTER_READ 0x000 |
59 | #define MCI_MODE_REGISTER_WRITE 0x100 |
60 | #define MCI_MODE_MEMORY_READ 0x000 |
61 | #define MCI_MODE_MEMORY_WRITE 0x4000 |
62 | |
63 | static unsigned int mpeglines = 128; |
64 | module_param(mpeglines, int, 0644); |
65 | MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32" ); |
66 | |
67 | static unsigned int mpeglinesize = 512; |
68 | module_param(mpeglinesize, int, 0644); |
69 | MODULE_PARM_DESC(mpeglinesize, |
70 | "number of bytes in each line of an MPEG buffer, range 512-1024" ); |
71 | |
72 | static unsigned int v4l_debug = 1; |
73 | module_param(v4l_debug, int, 0644); |
74 | MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages" ); |
75 | |
76 | #define dprintk(level, fmt, arg...) \ |
77 | do { \ |
78 | if (v4l_debug >= level) \ |
79 | printk(KERN_DEBUG pr_fmt(fmt), ## arg); \ |
80 | } while (0) |
81 | |
82 | static struct cx231xx_tvnorm cx231xx_tvnorms[] = { |
83 | { |
84 | .name = "NTSC-M" , |
85 | .id = V4L2_STD_NTSC_M, |
86 | }, { |
87 | .name = "NTSC-JP" , |
88 | .id = V4L2_STD_NTSC_M_JP, |
89 | }, { |
90 | .name = "PAL-BG" , |
91 | .id = V4L2_STD_PAL_BG, |
92 | }, { |
93 | .name = "PAL-DK" , |
94 | .id = V4L2_STD_PAL_DK, |
95 | }, { |
96 | .name = "PAL-I" , |
97 | .id = V4L2_STD_PAL_I, |
98 | }, { |
99 | .name = "PAL-M" , |
100 | .id = V4L2_STD_PAL_M, |
101 | }, { |
102 | .name = "PAL-N" , |
103 | .id = V4L2_STD_PAL_N, |
104 | }, { |
105 | .name = "PAL-Nc" , |
106 | .id = V4L2_STD_PAL_Nc, |
107 | }, { |
108 | .name = "PAL-60" , |
109 | .id = V4L2_STD_PAL_60, |
110 | }, { |
111 | .name = "SECAM-L" , |
112 | .id = V4L2_STD_SECAM_L, |
113 | }, { |
114 | .name = "SECAM-DK" , |
115 | .id = V4L2_STD_SECAM_DK, |
116 | } |
117 | }; |
118 | |
119 | /* ------------------------------------------------------------------ */ |
120 | |
121 | enum cx231xx_capture_type { |
122 | CX231xx_MPEG_CAPTURE, |
123 | CX231xx_RAW_CAPTURE, |
124 | CX231xx_RAW_PASSTHRU_CAPTURE |
125 | }; |
126 | |
127 | enum cx231xx_capture_bits { |
128 | CX231xx_RAW_BITS_NONE = 0x00, |
129 | CX231xx_RAW_BITS_YUV_CAPTURE = 0x01, |
130 | CX231xx_RAW_BITS_PCM_CAPTURE = 0x02, |
131 | CX231xx_RAW_BITS_VBI_CAPTURE = 0x04, |
132 | CX231xx_RAW_BITS_PASSTHRU_CAPTURE = 0x08, |
133 | CX231xx_RAW_BITS_TO_HOST_CAPTURE = 0x10 |
134 | }; |
135 | |
136 | enum cx231xx_capture_end { |
137 | CX231xx_END_AT_GOP, /* stop at the end of gop, generate irq */ |
138 | CX231xx_END_NOW, /* stop immediately, no irq */ |
139 | }; |
140 | |
141 | enum cx231xx_framerate { |
142 | CX231xx_FRAMERATE_NTSC_30, /* NTSC: 30fps */ |
143 | CX231xx_FRAMERATE_PAL_25 /* PAL: 25fps */ |
144 | }; |
145 | |
146 | enum cx231xx_stream_port { |
147 | CX231xx_OUTPUT_PORT_MEMORY, |
148 | CX231xx_OUTPUT_PORT_STREAMING, |
149 | CX231xx_OUTPUT_PORT_SERIAL |
150 | }; |
151 | |
152 | enum cx231xx_data_xfer_status { |
153 | CX231xx_MORE_BUFFERS_FOLLOW, |
154 | CX231xx_LAST_BUFFER, |
155 | }; |
156 | |
157 | enum cx231xx_picture_mask { |
158 | CX231xx_PICTURE_MASK_NONE, |
159 | CX231xx_PICTURE_MASK_I_FRAMES, |
160 | CX231xx_PICTURE_MASK_I_P_FRAMES = 0x3, |
161 | CX231xx_PICTURE_MASK_ALL_FRAMES = 0x7, |
162 | }; |
163 | |
164 | enum cx231xx_vbi_mode_bits { |
165 | CX231xx_VBI_BITS_SLICED, |
166 | CX231xx_VBI_BITS_RAW, |
167 | }; |
168 | |
169 | enum cx231xx_vbi_insertion_bits { |
170 | CX231xx_VBI_BITS_INSERT_IN_XTENSION_USR_DATA, |
171 | CX231xx_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1, |
172 | CX231xx_VBI_BITS_SEPARATE_STREAM = 0x2 << 1, |
173 | CX231xx_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, |
174 | CX231xx_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, |
175 | }; |
176 | |
177 | enum cx231xx_dma_unit { |
178 | CX231xx_DMA_BYTES, |
179 | CX231xx_DMA_FRAMES, |
180 | }; |
181 | |
182 | enum cx231xx_dma_transfer_status_bits { |
183 | CX231xx_DMA_TRANSFER_BITS_DONE = 0x01, |
184 | CX231xx_DMA_TRANSFER_BITS_ERROR = 0x04, |
185 | CX231xx_DMA_TRANSFER_BITS_LL_ERROR = 0x10, |
186 | }; |
187 | |
188 | enum cx231xx_pause { |
189 | CX231xx_PAUSE_ENCODING, |
190 | CX231xx_RESUME_ENCODING, |
191 | }; |
192 | |
193 | enum cx231xx_copyright { |
194 | CX231xx_COPYRIGHT_OFF, |
195 | CX231xx_COPYRIGHT_ON, |
196 | }; |
197 | |
198 | enum cx231xx_notification_type { |
199 | CX231xx_NOTIFICATION_REFRESH, |
200 | }; |
201 | |
202 | enum cx231xx_notification_status { |
203 | CX231xx_NOTIFICATION_OFF, |
204 | CX231xx_NOTIFICATION_ON, |
205 | }; |
206 | |
207 | enum cx231xx_notification_mailbox { |
208 | CX231xx_NOTIFICATION_NO_MAILBOX = -1, |
209 | }; |
210 | |
211 | enum cx231xx_field1_lines { |
212 | CX231xx_FIELD1_SAA7114 = 0x00EF, /* 239 */ |
213 | CX231xx_FIELD1_SAA7115 = 0x00F0, /* 240 */ |
214 | CX231xx_FIELD1_MICRONAS = 0x0105, /* 261 */ |
215 | }; |
216 | |
217 | enum cx231xx_field2_lines { |
218 | CX231xx_FIELD2_SAA7114 = 0x00EF, /* 239 */ |
219 | CX231xx_FIELD2_SAA7115 = 0x00F0, /* 240 */ |
220 | CX231xx_FIELD2_MICRONAS = 0x0106, /* 262 */ |
221 | }; |
222 | |
223 | enum cx231xx_custom_data_type { |
224 | CX231xx_CUSTOM_EXTENSION_USR_DATA, |
225 | CX231xx_CUSTOM_PRIVATE_PACKET, |
226 | }; |
227 | |
228 | enum cx231xx_mute { |
229 | CX231xx_UNMUTE, |
230 | CX231xx_MUTE, |
231 | }; |
232 | |
233 | enum cx231xx_mute_video_mask { |
234 | CX231xx_MUTE_VIDEO_V_MASK = 0x0000FF00, |
235 | CX231xx_MUTE_VIDEO_U_MASK = 0x00FF0000, |
236 | CX231xx_MUTE_VIDEO_Y_MASK = 0xFF000000, |
237 | }; |
238 | |
239 | enum cx231xx_mute_video_shift { |
240 | CX231xx_MUTE_VIDEO_V_SHIFT = 8, |
241 | CX231xx_MUTE_VIDEO_U_SHIFT = 16, |
242 | CX231xx_MUTE_VIDEO_Y_SHIFT = 24, |
243 | }; |
244 | |
245 | /* defines below are from ivtv-driver.h */ |
246 | #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF |
247 | |
248 | /* Firmware API commands */ |
249 | #define IVTV_API_STD_TIMEOUT 500 |
250 | |
251 | /* Registers */ |
252 | /* IVTV_REG_OFFSET */ |
253 | #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8) |
254 | #define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC) |
255 | #define IVTV_REG_SPU (0x9050) |
256 | #define IVTV_REG_HW_BLOCKS (0x9054) |
257 | #define IVTV_REG_VPU (0x9058) |
258 | #define IVTV_REG_APU (0xA064) |
259 | |
260 | /* |
261 | * Bit definitions for MC417_RWD and MC417_OEN registers |
262 | * |
263 | * bits 31-16 |
264 | *+-----------+ |
265 | *| Reserved | |
266 | *|+-----------+ |
267 | *| bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8 |
268 | *|+-------+-------+-------+-------+-------+-------+-------+-------+ |
269 | *|| MIWR# | MIRD# | MICS# |MIRDY# |MIADDR3|MIADDR2|MIADDR1|MIADDR0| |
270 | *|+-------+-------+-------+-------+-------+-------+-------+-------+ |
271 | *| bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 |
272 | *|+-------+-------+-------+-------+-------+-------+-------+-------+ |
273 | *||MIDATA7|MIDATA6|MIDATA5|MIDATA4|MIDATA3|MIDATA2|MIDATA1|MIDATA0| |
274 | *|+-------+-------+-------+-------+-------+-------+-------+-------+ |
275 | */ |
276 | #define MC417_MIWR 0x8000 |
277 | #define MC417_MIRD 0x4000 |
278 | #define MC417_MICS 0x2000 |
279 | #define MC417_MIRDY 0x1000 |
280 | #define MC417_MIADDR 0x0F00 |
281 | #define MC417_MIDATA 0x00FF |
282 | |
283 | |
284 | /* Bit definitions for MC417_CTL register **** |
285 | *bits 31-6 bits 5-4 bit 3 bits 2-1 Bit 0 |
286 | *+--------+-------------+--------+--------------+------------+ |
287 | *|Reserved|MC417_SPD_CTL|Reserved|MC417_GPIO_SEL|UART_GPIO_EN| |
288 | *+--------+-------------+--------+--------------+------------+ |
289 | */ |
290 | #define MC417_SPD_CTL(x) (((x) << 4) & 0x00000030) |
291 | #define MC417_GPIO_SEL(x) (((x) << 1) & 0x00000006) |
292 | #define MC417_UART_GPIO_EN 0x00000001 |
293 | |
294 | /* Values for speed control */ |
295 | #define MC417_SPD_CTL_SLOW 0x1 |
296 | #define MC417_SPD_CTL_MEDIUM 0x0 |
297 | #define MC417_SPD_CTL_FAST 0x3 /* b'1x, but we use b'11 */ |
298 | |
299 | /* Values for GPIO select */ |
300 | #define MC417_GPIO_SEL_GPIO3 0x3 |
301 | #define MC417_GPIO_SEL_GPIO2 0x2 |
302 | #define MC417_GPIO_SEL_GPIO1 0x1 |
303 | #define MC417_GPIO_SEL_GPIO0 0x0 |
304 | |
305 | |
306 | #define CX23417_GPIO_MASK 0xFC0003FF |
307 | |
308 | static int set_itvc_reg(struct cx231xx *dev, u32 gpio_direction, u32 value) |
309 | { |
310 | int status = 0; |
311 | u32 _gpio_direction = 0; |
312 | |
313 | _gpio_direction = _gpio_direction & CX23417_GPIO_MASK; |
314 | _gpio_direction = _gpio_direction | gpio_direction; |
315 | status = cx231xx_send_gpio_cmd(dev, gpio_bit: _gpio_direction, |
316 | gpio_val: (u8 *)&value, len: 4, request: 0, direction: 0); |
317 | return status; |
318 | } |
319 | |
320 | static int get_itvc_reg(struct cx231xx *dev, u32 gpio_direction, u32 *val_ptr) |
321 | { |
322 | int status = 0; |
323 | u32 _gpio_direction = 0; |
324 | |
325 | _gpio_direction = _gpio_direction & CX23417_GPIO_MASK; |
326 | _gpio_direction = _gpio_direction | gpio_direction; |
327 | |
328 | status = cx231xx_send_gpio_cmd(dev, gpio_bit: _gpio_direction, |
329 | gpio_val: (u8 *)val_ptr, len: 4, request: 0, direction: 1); |
330 | return status; |
331 | } |
332 | |
333 | static int wait_for_mci_complete(struct cx231xx *dev) |
334 | { |
335 | u32 gpio; |
336 | u32 gpio_direction = 0; |
337 | u8 count = 0; |
338 | get_itvc_reg(dev, gpio_direction, val_ptr: &gpio); |
339 | |
340 | while (!(gpio&0x020000)) { |
341 | msleep(msecs: 10); |
342 | |
343 | get_itvc_reg(dev, gpio_direction, val_ptr: &gpio); |
344 | |
345 | if (count++ > 100) { |
346 | dprintk(3, "ERROR: Timeout - gpio=%x\n" , gpio); |
347 | return -EIO; |
348 | } |
349 | } |
350 | return 0; |
351 | } |
352 | |
353 | static int mc417_register_write(struct cx231xx *dev, u16 address, u32 value) |
354 | { |
355 | u32 temp; |
356 | int status = 0; |
357 | |
358 | temp = 0x82 | MCI_REGISTER_DATA_BYTE0 | ((value & 0x000000FF) << 8); |
359 | temp = temp << 10; |
360 | status = set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
361 | if (status < 0) |
362 | return status; |
363 | temp = temp | (0x05 << 10); |
364 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
365 | |
366 | /*write data byte 1;*/ |
367 | temp = 0x82 | MCI_REGISTER_DATA_BYTE1 | (value & 0x0000FF00); |
368 | temp = temp << 10; |
369 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
370 | temp = temp | (0x05 << 10); |
371 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
372 | |
373 | /*write data byte 2;*/ |
374 | temp = 0x82 | MCI_REGISTER_DATA_BYTE2 | ((value & 0x00FF0000) >> 8); |
375 | temp = temp << 10; |
376 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
377 | temp = temp | (0x05 << 10); |
378 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
379 | |
380 | /*write data byte 3;*/ |
381 | temp = 0x82 | MCI_REGISTER_DATA_BYTE3 | ((value & 0xFF000000) >> 16); |
382 | temp = temp << 10; |
383 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
384 | temp = temp | (0x05 << 10); |
385 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
386 | |
387 | /*write address byte 0;*/ |
388 | temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE0 | ((address & 0x000000FF) << 8); |
389 | temp = temp << 10; |
390 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
391 | temp = temp | (0x05 << 10); |
392 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
393 | |
394 | /*write address byte 1;*/ |
395 | temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE1 | (address & 0x0000FF00); |
396 | temp = temp << 10; |
397 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
398 | temp = temp | (0x05 << 10); |
399 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
400 | |
401 | /*Write that the mode is write.*/ |
402 | temp = 0x82 | MCI_REGISTER_MODE | MCI_MODE_REGISTER_WRITE; |
403 | temp = temp << 10; |
404 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
405 | temp = temp | (0x05 << 10); |
406 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
407 | |
408 | return wait_for_mci_complete(dev); |
409 | } |
410 | |
411 | static int mc417_register_read(struct cx231xx *dev, u16 address, u32 *value) |
412 | { |
413 | /*write address byte 0;*/ |
414 | u32 temp; |
415 | u32 return_value = 0; |
416 | int ret = 0; |
417 | |
418 | temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE0 | ((address & 0x00FF) << 8); |
419 | temp = temp << 10; |
420 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
421 | temp = temp | ((0x05) << 10); |
422 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
423 | |
424 | /*write address byte 1;*/ |
425 | temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE1 | (address & 0xFF00); |
426 | temp = temp << 10; |
427 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
428 | temp = temp | ((0x05) << 10); |
429 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
430 | |
431 | /*write that the mode is read;*/ |
432 | temp = 0x82 | MCI_REGISTER_MODE | MCI_MODE_REGISTER_READ; |
433 | temp = temp << 10; |
434 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
435 | temp = temp | ((0x05) << 10); |
436 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
437 | |
438 | /*wait for the MIRDY line to be asserted , |
439 | signalling that the read is done;*/ |
440 | ret = wait_for_mci_complete(dev); |
441 | |
442 | /*switch the DATA- GPIO to input mode;*/ |
443 | |
444 | /*Read data byte 0;*/ |
445 | temp = (0x82 | MCI_REGISTER_DATA_BYTE0) << 10; |
446 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
447 | temp = ((0x81 | MCI_REGISTER_DATA_BYTE0) << 10); |
448 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
449 | get_itvc_reg(dev, ITVC_READ_DIR, val_ptr: &temp); |
450 | return_value |= ((temp & 0x03FC0000) >> 18); |
451 | set_itvc_reg(dev, ITVC_READ_DIR, value: (0x87 << 10)); |
452 | |
453 | /* Read data byte 1;*/ |
454 | temp = (0x82 | MCI_REGISTER_DATA_BYTE1) << 10; |
455 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
456 | temp = ((0x81 | MCI_REGISTER_DATA_BYTE1) << 10); |
457 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
458 | get_itvc_reg(dev, ITVC_READ_DIR, val_ptr: &temp); |
459 | |
460 | return_value |= ((temp & 0x03FC0000) >> 10); |
461 | set_itvc_reg(dev, ITVC_READ_DIR, value: (0x87 << 10)); |
462 | |
463 | /*Read data byte 2;*/ |
464 | temp = (0x82 | MCI_REGISTER_DATA_BYTE2) << 10; |
465 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
466 | temp = ((0x81 | MCI_REGISTER_DATA_BYTE2) << 10); |
467 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
468 | get_itvc_reg(dev, ITVC_READ_DIR, val_ptr: &temp); |
469 | return_value |= ((temp & 0x03FC0000) >> 2); |
470 | set_itvc_reg(dev, ITVC_READ_DIR, value: (0x87 << 10)); |
471 | |
472 | /*Read data byte 3;*/ |
473 | temp = (0x82 | MCI_REGISTER_DATA_BYTE3) << 10; |
474 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
475 | temp = ((0x81 | MCI_REGISTER_DATA_BYTE3) << 10); |
476 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
477 | get_itvc_reg(dev, ITVC_READ_DIR, val_ptr: &temp); |
478 | return_value |= ((temp & 0x03FC0000) << 6); |
479 | set_itvc_reg(dev, ITVC_READ_DIR, value: (0x87 << 10)); |
480 | |
481 | *value = return_value; |
482 | return ret; |
483 | } |
484 | |
485 | static int mc417_memory_write(struct cx231xx *dev, u32 address, u32 value) |
486 | { |
487 | /*write data byte 0;*/ |
488 | |
489 | u32 temp; |
490 | int ret = 0; |
491 | |
492 | temp = 0x82 | MCI_MEMORY_DATA_BYTE0 | ((value & 0x000000FF) << 8); |
493 | temp = temp << 10; |
494 | ret = set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
495 | if (ret < 0) |
496 | return ret; |
497 | temp = temp | (0x05 << 10); |
498 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
499 | |
500 | /*write data byte 1;*/ |
501 | temp = 0x82 | MCI_MEMORY_DATA_BYTE1 | (value & 0x0000FF00); |
502 | temp = temp << 10; |
503 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
504 | temp = temp | (0x05 << 10); |
505 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
506 | |
507 | /*write data byte 2;*/ |
508 | temp = 0x82 | MCI_MEMORY_DATA_BYTE2 | ((value & 0x00FF0000) >> 8); |
509 | temp = temp << 10; |
510 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
511 | temp = temp | (0x05 << 10); |
512 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
513 | |
514 | /*write data byte 3;*/ |
515 | temp = 0x82 | MCI_MEMORY_DATA_BYTE3 | ((value & 0xFF000000) >> 16); |
516 | temp = temp << 10; |
517 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
518 | temp = temp | (0x05 << 10); |
519 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
520 | |
521 | /* write address byte 2;*/ |
522 | temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE | |
523 | ((address & 0x003F0000) >> 8); |
524 | temp = temp << 10; |
525 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
526 | temp = temp | (0x05 << 10); |
527 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
528 | |
529 | /* write address byte 1;*/ |
530 | temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); |
531 | temp = temp << 10; |
532 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
533 | temp = temp | (0x05 << 10); |
534 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
535 | |
536 | /* write address byte 0;*/ |
537 | temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF) << 8); |
538 | temp = temp << 10; |
539 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
540 | temp = temp | (0x05 << 10); |
541 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
542 | |
543 | /*wait for MIRDY line;*/ |
544 | wait_for_mci_complete(dev); |
545 | |
546 | return 0; |
547 | } |
548 | |
549 | static int mc417_memory_read(struct cx231xx *dev, u32 address, u32 *value) |
550 | { |
551 | u32 temp = 0; |
552 | u32 return_value = 0; |
553 | int ret = 0; |
554 | |
555 | /*write address byte 2;*/ |
556 | temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_READ | |
557 | ((address & 0x003F0000) >> 8); |
558 | temp = temp << 10; |
559 | ret = set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
560 | if (ret < 0) |
561 | return ret; |
562 | temp = temp | (0x05 << 10); |
563 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
564 | |
565 | /*write address byte 1*/ |
566 | temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); |
567 | temp = temp << 10; |
568 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
569 | temp = temp | (0x05 << 10); |
570 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
571 | |
572 | /*write address byte 0*/ |
573 | temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF) << 8); |
574 | temp = temp << 10; |
575 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
576 | temp = temp | (0x05 << 10); |
577 | set_itvc_reg(dev, ITVC_WRITE_DIR, value: temp); |
578 | |
579 | /*Wait for MIRDY line*/ |
580 | ret = wait_for_mci_complete(dev); |
581 | |
582 | |
583 | /*Read data byte 3;*/ |
584 | temp = (0x82 | MCI_MEMORY_DATA_BYTE3) << 10; |
585 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
586 | temp = ((0x81 | MCI_MEMORY_DATA_BYTE3) << 10); |
587 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
588 | get_itvc_reg(dev, ITVC_READ_DIR, val_ptr: &temp); |
589 | return_value |= ((temp & 0x03FC0000) << 6); |
590 | set_itvc_reg(dev, ITVC_READ_DIR, value: (0x87 << 10)); |
591 | |
592 | /*Read data byte 2;*/ |
593 | temp = (0x82 | MCI_MEMORY_DATA_BYTE2) << 10; |
594 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
595 | temp = ((0x81 | MCI_MEMORY_DATA_BYTE2) << 10); |
596 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
597 | get_itvc_reg(dev, ITVC_READ_DIR, val_ptr: &temp); |
598 | return_value |= ((temp & 0x03FC0000) >> 2); |
599 | set_itvc_reg(dev, ITVC_READ_DIR, value: (0x87 << 10)); |
600 | |
601 | /* Read data byte 1;*/ |
602 | temp = (0x82 | MCI_MEMORY_DATA_BYTE1) << 10; |
603 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
604 | temp = ((0x81 | MCI_MEMORY_DATA_BYTE1) << 10); |
605 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
606 | get_itvc_reg(dev, ITVC_READ_DIR, val_ptr: &temp); |
607 | return_value |= ((temp & 0x03FC0000) >> 10); |
608 | set_itvc_reg(dev, ITVC_READ_DIR, value: (0x87 << 10)); |
609 | |
610 | /*Read data byte 0;*/ |
611 | temp = (0x82 | MCI_MEMORY_DATA_BYTE0) << 10; |
612 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
613 | temp = ((0x81 | MCI_MEMORY_DATA_BYTE0) << 10); |
614 | set_itvc_reg(dev, ITVC_READ_DIR, value: temp); |
615 | get_itvc_reg(dev, ITVC_READ_DIR, val_ptr: &temp); |
616 | return_value |= ((temp & 0x03FC0000) >> 18); |
617 | set_itvc_reg(dev, ITVC_READ_DIR, value: (0x87 << 10)); |
618 | |
619 | *value = return_value; |
620 | return ret; |
621 | } |
622 | |
623 | /* ------------------------------------------------------------------ */ |
624 | |
625 | /* MPEG encoder API */ |
626 | static char *cmd_to_str(int cmd) |
627 | { |
628 | switch (cmd) { |
629 | case CX2341X_ENC_PING_FW: |
630 | return "PING_FW" ; |
631 | case CX2341X_ENC_START_CAPTURE: |
632 | return "START_CAPTURE" ; |
633 | case CX2341X_ENC_STOP_CAPTURE: |
634 | return "STOP_CAPTURE" ; |
635 | case CX2341X_ENC_SET_AUDIO_ID: |
636 | return "SET_AUDIO_ID" ; |
637 | case CX2341X_ENC_SET_VIDEO_ID: |
638 | return "SET_VIDEO_ID" ; |
639 | case CX2341X_ENC_SET_PCR_ID: |
640 | return "SET_PCR_PID" ; |
641 | case CX2341X_ENC_SET_FRAME_RATE: |
642 | return "SET_FRAME_RATE" ; |
643 | case CX2341X_ENC_SET_FRAME_SIZE: |
644 | return "SET_FRAME_SIZE" ; |
645 | case CX2341X_ENC_SET_BIT_RATE: |
646 | return "SET_BIT_RATE" ; |
647 | case CX2341X_ENC_SET_GOP_PROPERTIES: |
648 | return "SET_GOP_PROPERTIES" ; |
649 | case CX2341X_ENC_SET_ASPECT_RATIO: |
650 | return "SET_ASPECT_RATIO" ; |
651 | case CX2341X_ENC_SET_DNR_FILTER_MODE: |
652 | return "SET_DNR_FILTER_PROPS" ; |
653 | case CX2341X_ENC_SET_DNR_FILTER_PROPS: |
654 | return "SET_DNR_FILTER_PROPS" ; |
655 | case CX2341X_ENC_SET_CORING_LEVELS: |
656 | return "SET_CORING_LEVELS" ; |
657 | case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE: |
658 | return "SET_SPATIAL_FILTER_TYPE" ; |
659 | case CX2341X_ENC_SET_VBI_LINE: |
660 | return "SET_VBI_LINE" ; |
661 | case CX2341X_ENC_SET_STREAM_TYPE: |
662 | return "SET_STREAM_TYPE" ; |
663 | case CX2341X_ENC_SET_OUTPUT_PORT: |
664 | return "SET_OUTPUT_PORT" ; |
665 | case CX2341X_ENC_SET_AUDIO_PROPERTIES: |
666 | return "SET_AUDIO_PROPERTIES" ; |
667 | case CX2341X_ENC_HALT_FW: |
668 | return "HALT_FW" ; |
669 | case CX2341X_ENC_GET_VERSION: |
670 | return "GET_VERSION" ; |
671 | case CX2341X_ENC_SET_GOP_CLOSURE: |
672 | return "SET_GOP_CLOSURE" ; |
673 | case CX2341X_ENC_GET_SEQ_END: |
674 | return "GET_SEQ_END" ; |
675 | case CX2341X_ENC_SET_PGM_INDEX_INFO: |
676 | return "SET_PGM_INDEX_INFO" ; |
677 | case CX2341X_ENC_SET_VBI_CONFIG: |
678 | return "SET_VBI_CONFIG" ; |
679 | case CX2341X_ENC_SET_DMA_BLOCK_SIZE: |
680 | return "SET_DMA_BLOCK_SIZE" ; |
681 | case CX2341X_ENC_GET_PREV_DMA_INFO_MB_10: |
682 | return "GET_PREV_DMA_INFO_MB_10" ; |
683 | case CX2341X_ENC_GET_PREV_DMA_INFO_MB_9: |
684 | return "GET_PREV_DMA_INFO_MB_9" ; |
685 | case CX2341X_ENC_SCHED_DMA_TO_HOST: |
686 | return "SCHED_DMA_TO_HOST" ; |
687 | case CX2341X_ENC_INITIALIZE_INPUT: |
688 | return "INITIALIZE_INPUT" ; |
689 | case CX2341X_ENC_SET_FRAME_DROP_RATE: |
690 | return "SET_FRAME_DROP_RATE" ; |
691 | case CX2341X_ENC_PAUSE_ENCODER: |
692 | return "PAUSE_ENCODER" ; |
693 | case CX2341X_ENC_REFRESH_INPUT: |
694 | return "REFRESH_INPUT" ; |
695 | case CX2341X_ENC_SET_COPYRIGHT: |
696 | return "SET_COPYRIGHT" ; |
697 | case CX2341X_ENC_SET_EVENT_NOTIFICATION: |
698 | return "SET_EVENT_NOTIFICATION" ; |
699 | case CX2341X_ENC_SET_NUM_VSYNC_LINES: |
700 | return "SET_NUM_VSYNC_LINES" ; |
701 | case CX2341X_ENC_SET_PLACEHOLDER: |
702 | return "SET_PLACEHOLDER" ; |
703 | case CX2341X_ENC_MUTE_VIDEO: |
704 | return "MUTE_VIDEO" ; |
705 | case CX2341X_ENC_MUTE_AUDIO: |
706 | return "MUTE_AUDIO" ; |
707 | case CX2341X_ENC_MISC: |
708 | return "MISC" ; |
709 | default: |
710 | return "UNKNOWN" ; |
711 | } |
712 | } |
713 | |
714 | static int cx231xx_mbox_func(void *priv, u32 command, int in, int out, |
715 | u32 data[CX2341X_MBOX_MAX_DATA]) |
716 | { |
717 | struct cx231xx *dev = priv; |
718 | unsigned long timeout; |
719 | u32 value, flag, retval = 0; |
720 | int i; |
721 | |
722 | dprintk(3, "%s: command(0x%X) = %s\n" , __func__, command, |
723 | cmd_to_str(command)); |
724 | |
725 | /* this may not be 100% safe if we can't read any memory location |
726 | without side effects */ |
727 | mc417_memory_read(dev, address: dev->cx23417_mailbox - 4, value: &value); |
728 | if (value != 0x12345678) { |
729 | dprintk(3, "Firmware and/or mailbox pointer not initialized or corrupted, signature = 0x%x, cmd = %s\n" , |
730 | value, cmd_to_str(command)); |
731 | return -EIO; |
732 | } |
733 | |
734 | /* This read looks at 32 bits, but flag is only 8 bits. |
735 | * Seems we also bail if CMD or TIMEOUT bytes are set??? |
736 | */ |
737 | mc417_memory_read(dev, address: dev->cx23417_mailbox, value: &flag); |
738 | if (flag) { |
739 | dprintk(3, "ERROR: Mailbox appears to be in use (%x), cmd = %s\n" , |
740 | flag, cmd_to_str(command)); |
741 | return -EBUSY; |
742 | } |
743 | |
744 | flag |= 1; /* tell 'em we're working on it */ |
745 | mc417_memory_write(dev, address: dev->cx23417_mailbox, value: flag); |
746 | |
747 | /* write command + args + fill remaining with zeros */ |
748 | /* command code */ |
749 | mc417_memory_write(dev, address: dev->cx23417_mailbox + 1, value: command); |
750 | mc417_memory_write(dev, address: dev->cx23417_mailbox + 3, |
751 | IVTV_API_STD_TIMEOUT); /* timeout */ |
752 | for (i = 0; i < in; i++) { |
753 | mc417_memory_write(dev, address: dev->cx23417_mailbox + 4 + i, value: data[i]); |
754 | dprintk(3, "API Input %d = %d\n" , i, data[i]); |
755 | } |
756 | for (; i < CX2341X_MBOX_MAX_DATA; i++) |
757 | mc417_memory_write(dev, address: dev->cx23417_mailbox + 4 + i, value: 0); |
758 | |
759 | flag |= 3; /* tell 'em we're done writing */ |
760 | mc417_memory_write(dev, address: dev->cx23417_mailbox, value: flag); |
761 | |
762 | /* wait for firmware to handle the API command */ |
763 | timeout = jiffies + msecs_to_jiffies(m: 10); |
764 | for (;;) { |
765 | mc417_memory_read(dev, address: dev->cx23417_mailbox, value: &flag); |
766 | if (0 != (flag & 4)) |
767 | break; |
768 | if (time_after(jiffies, timeout)) { |
769 | dprintk(3, "ERROR: API Mailbox timeout\n" ); |
770 | return -EIO; |
771 | } |
772 | udelay(10); |
773 | } |
774 | |
775 | /* read output values */ |
776 | for (i = 0; i < out; i++) { |
777 | mc417_memory_read(dev, address: dev->cx23417_mailbox + 4 + i, value: data + i); |
778 | dprintk(3, "API Output %d = %d\n" , i, data[i]); |
779 | } |
780 | |
781 | mc417_memory_read(dev, address: dev->cx23417_mailbox + 2, value: &retval); |
782 | dprintk(3, "API result = %d\n" , retval); |
783 | |
784 | flag = 0; |
785 | mc417_memory_write(dev, address: dev->cx23417_mailbox, value: flag); |
786 | |
787 | return 0; |
788 | } |
789 | |
790 | /* We don't need to call the API often, so using just one |
791 | * mailbox will probably suffice |
792 | */ |
793 | static int cx231xx_api_cmd(struct cx231xx *dev, u32 command, |
794 | u32 inputcnt, u32 outputcnt, ...) |
795 | { |
796 | u32 data[CX2341X_MBOX_MAX_DATA]; |
797 | va_list vargs; |
798 | int i, err; |
799 | |
800 | dprintk(3, "%s() cmds = 0x%08x\n" , __func__, command); |
801 | |
802 | va_start(vargs, outputcnt); |
803 | for (i = 0; i < inputcnt; i++) |
804 | data[i] = va_arg(vargs, int); |
805 | |
806 | err = cx231xx_mbox_func(priv: dev, command, in: inputcnt, out: outputcnt, data); |
807 | for (i = 0; i < outputcnt; i++) { |
808 | int *vptr = va_arg(vargs, int *); |
809 | *vptr = data[i]; |
810 | } |
811 | va_end(vargs); |
812 | |
813 | return err; |
814 | } |
815 | |
816 | |
817 | static int cx231xx_find_mailbox(struct cx231xx *dev) |
818 | { |
819 | u32 signature[4] = { |
820 | 0x12345678, 0x34567812, 0x56781234, 0x78123456 |
821 | }; |
822 | int signaturecnt = 0; |
823 | u32 value; |
824 | int i; |
825 | int ret = 0; |
826 | |
827 | dprintk(2, "%s()\n" , __func__); |
828 | |
829 | for (i = 0; i < 0x100; i++) {/*CX231xx_FIRM_IMAGE_SIZE*/ |
830 | ret = mc417_memory_read(dev, address: i, value: &value); |
831 | if (ret < 0) |
832 | return ret; |
833 | if (value == signature[signaturecnt]) |
834 | signaturecnt++; |
835 | else |
836 | signaturecnt = 0; |
837 | if (4 == signaturecnt) { |
838 | dprintk(1, "Mailbox signature found at 0x%x\n" , i + 1); |
839 | return i + 1; |
840 | } |
841 | } |
842 | dprintk(3, "Mailbox signature values not found!\n" ); |
843 | return -EIO; |
844 | } |
845 | |
846 | static void mci_write_memory_to_gpio(struct cx231xx *dev, u32 address, u32 value, |
847 | u32 *p_fw_image) |
848 | { |
849 | u32 temp = 0; |
850 | int i = 0; |
851 | |
852 | temp = 0x82 | MCI_MEMORY_DATA_BYTE0 | ((value & 0x000000FF) << 8); |
853 | temp = temp << 10; |
854 | *p_fw_image = temp; |
855 | p_fw_image++; |
856 | temp = temp | (0x05 << 10); |
857 | *p_fw_image = temp; |
858 | p_fw_image++; |
859 | |
860 | /*write data byte 1;*/ |
861 | temp = 0x82 | MCI_MEMORY_DATA_BYTE1 | (value & 0x0000FF00); |
862 | temp = temp << 10; |
863 | *p_fw_image = temp; |
864 | p_fw_image++; |
865 | temp = temp | (0x05 << 10); |
866 | *p_fw_image = temp; |
867 | p_fw_image++; |
868 | |
869 | /*write data byte 2;*/ |
870 | temp = 0x82 | MCI_MEMORY_DATA_BYTE2 | ((value & 0x00FF0000) >> 8); |
871 | temp = temp << 10; |
872 | *p_fw_image = temp; |
873 | p_fw_image++; |
874 | temp = temp | (0x05 << 10); |
875 | *p_fw_image = temp; |
876 | p_fw_image++; |
877 | |
878 | /*write data byte 3;*/ |
879 | temp = 0x82 | MCI_MEMORY_DATA_BYTE3 | ((value & 0xFF000000) >> 16); |
880 | temp = temp << 10; |
881 | *p_fw_image = temp; |
882 | p_fw_image++; |
883 | temp = temp | (0x05 << 10); |
884 | *p_fw_image = temp; |
885 | p_fw_image++; |
886 | |
887 | /* write address byte 2;*/ |
888 | temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE | |
889 | ((address & 0x003F0000) >> 8); |
890 | temp = temp << 10; |
891 | *p_fw_image = temp; |
892 | p_fw_image++; |
893 | temp = temp | (0x05 << 10); |
894 | *p_fw_image = temp; |
895 | p_fw_image++; |
896 | |
897 | /* write address byte 1;*/ |
898 | temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); |
899 | temp = temp << 10; |
900 | *p_fw_image = temp; |
901 | p_fw_image++; |
902 | temp = temp | (0x05 << 10); |
903 | *p_fw_image = temp; |
904 | p_fw_image++; |
905 | |
906 | /* write address byte 0;*/ |
907 | temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF) << 8); |
908 | temp = temp << 10; |
909 | *p_fw_image = temp; |
910 | p_fw_image++; |
911 | temp = temp | (0x05 << 10); |
912 | *p_fw_image = temp; |
913 | p_fw_image++; |
914 | |
915 | for (i = 0; i < 6; i++) { |
916 | *p_fw_image = 0xFFFFFFFF; |
917 | p_fw_image++; |
918 | } |
919 | } |
920 | |
921 | |
922 | static int cx231xx_load_firmware(struct cx231xx *dev) |
923 | { |
924 | static const unsigned char magic[8] = { |
925 | 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa |
926 | }; |
927 | const struct firmware *firmware; |
928 | int i, retval = 0; |
929 | u32 value = 0; |
930 | u32 gpio_output = 0; |
931 | /*u32 checksum = 0;*/ |
932 | /*u32 *dataptr;*/ |
933 | u32 transfer_size = 0; |
934 | u32 fw_data = 0; |
935 | u32 address = 0; |
936 | /*u32 current_fw[800];*/ |
937 | u32 *p_current_fw, *p_fw; |
938 | u32 *p_fw_data; |
939 | int frame = 0; |
940 | u8 *p_buffer; |
941 | |
942 | p_current_fw = vmalloc(size: 1884180 * 4); |
943 | p_fw = p_current_fw; |
944 | if (p_current_fw == NULL) { |
945 | dprintk(2, "FAIL!!!\n" ); |
946 | return -ENOMEM; |
947 | } |
948 | |
949 | p_buffer = vmalloc(EP5_BUF_SIZE); |
950 | if (p_buffer == NULL) { |
951 | dprintk(2, "FAIL!!!\n" ); |
952 | vfree(addr: p_current_fw); |
953 | return -ENOMEM; |
954 | } |
955 | |
956 | dprintk(2, "%s()\n" , __func__); |
957 | |
958 | /* Save GPIO settings before reset of APU */ |
959 | retval |= mc417_memory_read(dev, address: 0x9020, value: &gpio_output); |
960 | retval |= mc417_memory_read(dev, address: 0x900C, value: &value); |
961 | |
962 | retval = mc417_register_write(dev, |
963 | IVTV_REG_VPU, value: 0xFFFFFFED); |
964 | retval |= mc417_register_write(dev, |
965 | IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); |
966 | retval |= mc417_register_write(dev, |
967 | IVTV_REG_ENC_SDRAM_REFRESH, value: 0x80000800); |
968 | retval |= mc417_register_write(dev, |
969 | IVTV_REG_ENC_SDRAM_PRECHARGE, value: 0x1A); |
970 | retval |= mc417_register_write(dev, |
971 | IVTV_REG_APU, value: 0); |
972 | |
973 | if (retval != 0) { |
974 | dev_err(dev->dev, |
975 | "%s: Error with mc417_register_write\n" , __func__); |
976 | vfree(addr: p_current_fw); |
977 | vfree(addr: p_buffer); |
978 | return retval; |
979 | } |
980 | |
981 | retval = request_firmware(fw: &firmware, CX231xx_FIRM_IMAGE_NAME, |
982 | device: dev->dev); |
983 | |
984 | if (retval != 0) { |
985 | dev_err(dev->dev, |
986 | "ERROR: Hotplug firmware request failed (%s).\n" , |
987 | CX231xx_FIRM_IMAGE_NAME); |
988 | dev_err(dev->dev, |
989 | "Please fix your hotplug setup, the board will not work without firmware loaded!\n" ); |
990 | vfree(addr: p_current_fw); |
991 | vfree(addr: p_buffer); |
992 | return retval; |
993 | } |
994 | |
995 | if (firmware->size != CX231xx_FIRM_IMAGE_SIZE) { |
996 | dev_err(dev->dev, |
997 | "ERROR: Firmware size mismatch (have %zd, expected %d)\n" , |
998 | firmware->size, CX231xx_FIRM_IMAGE_SIZE); |
999 | release_firmware(fw: firmware); |
1000 | vfree(addr: p_current_fw); |
1001 | vfree(addr: p_buffer); |
1002 | return -EINVAL; |
1003 | } |
1004 | |
1005 | if (0 != memcmp(p: firmware->data, q: magic, size: 8)) { |
1006 | dev_err(dev->dev, |
1007 | "ERROR: Firmware magic mismatch, wrong file?\n" ); |
1008 | release_firmware(fw: firmware); |
1009 | vfree(addr: p_current_fw); |
1010 | vfree(addr: p_buffer); |
1011 | return -EINVAL; |
1012 | } |
1013 | |
1014 | initGPIO(dev); |
1015 | |
1016 | /* transfer to the chip */ |
1017 | dprintk(2, "Loading firmware to GPIO...\n" ); |
1018 | p_fw_data = (u32 *)firmware->data; |
1019 | dprintk(2, "firmware->size=%zd\n" , firmware->size); |
1020 | for (transfer_size = 0; transfer_size < firmware->size; |
1021 | transfer_size += 4) { |
1022 | fw_data = *p_fw_data; |
1023 | |
1024 | mci_write_memory_to_gpio(dev, address, value: fw_data, p_fw_image: p_current_fw); |
1025 | address = address + 1; |
1026 | p_current_fw += 20; |
1027 | p_fw_data += 1; |
1028 | } |
1029 | |
1030 | /*download the firmware by ep5-out*/ |
1031 | |
1032 | for (frame = 0; frame < (int)(CX231xx_FIRM_IMAGE_SIZE*20/EP5_BUF_SIZE); |
1033 | frame++) { |
1034 | for (i = 0; i < EP5_BUF_SIZE; i++) { |
1035 | *(p_buffer + i) = (u8)(*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x000000FF); |
1036 | i++; |
1037 | *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x0000FF00) >> 8); |
1038 | i++; |
1039 | *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x00FF0000) >> 16); |
1040 | i++; |
1041 | *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0xFF000000) >> 24); |
1042 | } |
1043 | cx231xx_ep5_bulkout(dev, firmware: p_buffer, EP5_BUF_SIZE); |
1044 | } |
1045 | |
1046 | p_current_fw = p_fw; |
1047 | vfree(addr: p_current_fw); |
1048 | p_current_fw = NULL; |
1049 | vfree(addr: p_buffer); |
1050 | uninitGPIO(dev); |
1051 | release_firmware(fw: firmware); |
1052 | dprintk(1, "Firmware upload successful.\n" ); |
1053 | |
1054 | retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS, |
1055 | IVTV_CMD_HW_BLOCKS_RST); |
1056 | if (retval < 0) { |
1057 | dev_err(dev->dev, |
1058 | "%s: Error with mc417_register_write\n" , |
1059 | __func__); |
1060 | return retval; |
1061 | } |
1062 | /* F/W power up disturbs the GPIOs, restore state */ |
1063 | retval |= mc417_register_write(dev, address: 0x9020, value: gpio_output); |
1064 | retval |= mc417_register_write(dev, address: 0x900C, value); |
1065 | |
1066 | retval |= mc417_register_read(dev, IVTV_REG_VPU, value: &value); |
1067 | retval |= mc417_register_write(dev, IVTV_REG_VPU, value: value & 0xFFFFFFE8); |
1068 | |
1069 | if (retval < 0) { |
1070 | dev_err(dev->dev, |
1071 | "%s: Error with mc417_register_write\n" , |
1072 | __func__); |
1073 | return retval; |
1074 | } |
1075 | return 0; |
1076 | } |
1077 | |
1078 | static void cx231xx_codec_settings(struct cx231xx *dev) |
1079 | { |
1080 | dprintk(1, "%s()\n" , __func__); |
1081 | |
1082 | /* assign frame size */ |
1083 | cx231xx_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, inputcnt: 2, outputcnt: 0, |
1084 | dev->ts1.height, dev->ts1.width); |
1085 | |
1086 | dev->mpeg_ctrl_handler.width = dev->ts1.width; |
1087 | dev->mpeg_ctrl_handler.height = dev->ts1.height; |
1088 | |
1089 | cx2341x_handler_setup(cxhdl: &dev->mpeg_ctrl_handler); |
1090 | |
1091 | cx231xx_api_cmd(dev, CX2341X_ENC_MISC, inputcnt: 2, outputcnt: 0, 3, 1); |
1092 | cx231xx_api_cmd(dev, CX2341X_ENC_MISC, inputcnt: 2, outputcnt: 0, 4, 1); |
1093 | } |
1094 | |
1095 | static int cx231xx_initialize_codec(struct cx231xx *dev) |
1096 | { |
1097 | int version; |
1098 | int retval; |
1099 | u32 i; |
1100 | u32 val = 0; |
1101 | |
1102 | dprintk(1, "%s()\n" , __func__); |
1103 | cx231xx_disable656(dev); |
1104 | retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, inputcnt: 0, outputcnt: 0); /* ping */ |
1105 | if (retval < 0) { |
1106 | dprintk(2, "%s: PING OK\n" , __func__); |
1107 | retval = cx231xx_load_firmware(dev); |
1108 | if (retval < 0) { |
1109 | dev_err(dev->dev, |
1110 | "%s: f/w load failed\n" , __func__); |
1111 | return retval; |
1112 | } |
1113 | retval = cx231xx_find_mailbox(dev); |
1114 | if (retval < 0) { |
1115 | dev_err(dev->dev, "%s: mailbox < 0, error\n" , |
1116 | __func__); |
1117 | return retval; |
1118 | } |
1119 | dev->cx23417_mailbox = retval; |
1120 | retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, inputcnt: 0, outputcnt: 0); |
1121 | if (retval < 0) { |
1122 | dev_err(dev->dev, |
1123 | "ERROR: cx23417 firmware ping failed!\n" ); |
1124 | return retval; |
1125 | } |
1126 | retval = cx231xx_api_cmd(dev, CX2341X_ENC_GET_VERSION, inputcnt: 0, outputcnt: 1, |
1127 | &version); |
1128 | if (retval < 0) { |
1129 | dev_err(dev->dev, |
1130 | "ERROR: cx23417 firmware get encoder: version failed!\n" ); |
1131 | return retval; |
1132 | } |
1133 | dprintk(1, "cx23417 firmware version is 0x%08x\n" , version); |
1134 | msleep(msecs: 200); |
1135 | } |
1136 | |
1137 | for (i = 0; i < 1; i++) { |
1138 | retval = mc417_register_read(dev, address: 0x20f8, value: &val); |
1139 | dprintk(3, "***before enable656() VIM Capture Lines = %d ***\n" , |
1140 | val); |
1141 | if (retval < 0) |
1142 | return retval; |
1143 | } |
1144 | |
1145 | cx231xx_enable656(dev); |
1146 | |
1147 | /* stop mpeg capture */ |
1148 | cx231xx_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, inputcnt: 3, outputcnt: 0, 1, 3, 4); |
1149 | |
1150 | cx231xx_codec_settings(dev); |
1151 | msleep(msecs: 60); |
1152 | |
1153 | /* cx231xx_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0, |
1154 | CX231xx_FIELD1_SAA7115, CX231xx_FIELD2_SAA7115); |
1155 | cx231xx_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0, |
1156 | CX231xx_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
1157 | 0, 0); |
1158 | */ |
1159 | |
1160 | #if 0 |
1161 | /* TODO */ |
1162 | u32 data[7]; |
1163 | |
1164 | /* Setup to capture VBI */ |
1165 | data[0] = 0x0001BD00; |
1166 | data[1] = 1; /* frames per interrupt */ |
1167 | data[2] = 4; /* total bufs */ |
1168 | data[3] = 0x91559155; /* start codes */ |
1169 | data[4] = 0x206080C0; /* stop codes */ |
1170 | data[5] = 6; /* lines */ |
1171 | data[6] = 64; /* BPL */ |
1172 | |
1173 | cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1], |
1174 | data[2], data[3], data[4], data[5], data[6]); |
1175 | |
1176 | for (i = 2; i <= 24; i++) { |
1177 | int valid; |
1178 | |
1179 | valid = ((i >= 19) && (i <= 21)); |
1180 | cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, i, |
1181 | valid, 0 , 0, 0); |
1182 | cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, |
1183 | i | 0x80000000, valid, 0, 0, 0); |
1184 | } |
1185 | #endif |
1186 | /* cx231xx_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX231xx_UNMUTE); |
1187 | msleep(60); |
1188 | */ |
1189 | /* initialize the video input */ |
1190 | retval = cx231xx_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, inputcnt: 0, outputcnt: 0); |
1191 | if (retval < 0) |
1192 | return retval; |
1193 | msleep(msecs: 60); |
1194 | |
1195 | /* Enable VIP style pixel invalidation so we work with scaled mode */ |
1196 | mc417_memory_write(dev, address: 2120, value: 0x00000080); |
1197 | |
1198 | /* start capturing to the host interface */ |
1199 | retval = cx231xx_api_cmd(dev, CX2341X_ENC_START_CAPTURE, inputcnt: 2, outputcnt: 0, |
1200 | CX231xx_MPEG_CAPTURE, CX231xx_RAW_BITS_NONE); |
1201 | if (retval < 0) |
1202 | return retval; |
1203 | msleep(msecs: 10); |
1204 | |
1205 | for (i = 0; i < 1; i++) { |
1206 | mc417_register_read(dev, address: 0x20f8, value: &val); |
1207 | dprintk(3, "***VIM Capture Lines =%d ***\n" , val); |
1208 | } |
1209 | |
1210 | return 0; |
1211 | } |
1212 | |
1213 | /* ------------------------------------------------------------------ */ |
1214 | |
1215 | static int queue_setup(struct vb2_queue *vq, |
1216 | unsigned int *nbuffers, unsigned int *nplanes, |
1217 | unsigned int sizes[], struct device *alloc_devs[]) |
1218 | { |
1219 | struct cx231xx *dev = vb2_get_drv_priv(q: vq); |
1220 | unsigned int size = mpeglinesize * mpeglines; |
1221 | unsigned int q_num_bufs = vb2_get_num_buffers(q: vq); |
1222 | |
1223 | dev->ts1.ts_packet_size = mpeglinesize; |
1224 | dev->ts1.ts_packet_count = mpeglines; |
1225 | |
1226 | if (q_num_bufs + *nbuffers < CX231XX_MIN_BUF) |
1227 | *nbuffers = CX231XX_MIN_BUF - q_num_bufs; |
1228 | |
1229 | if (*nplanes) |
1230 | return sizes[0] < size ? -EINVAL : 0; |
1231 | *nplanes = 1; |
1232 | sizes[0] = mpeglinesize * mpeglines; |
1233 | |
1234 | return 0; |
1235 | } |
1236 | |
1237 | static void buffer_copy(struct cx231xx *dev, char *data, int len, struct urb *urb, |
1238 | struct cx231xx_dmaqueue *dma_q) |
1239 | { |
1240 | void *vbuf; |
1241 | struct cx231xx_buffer *buf; |
1242 | u32 tail_data = 0; |
1243 | char *p_data; |
1244 | |
1245 | if (dma_q->mpeg_buffer_done == 0) { |
1246 | if (list_empty(head: &dma_q->active)) |
1247 | return; |
1248 | |
1249 | buf = list_entry(dma_q->active.next, |
1250 | struct cx231xx_buffer, list); |
1251 | dev->video_mode.isoc_ctl.buf = buf; |
1252 | dma_q->mpeg_buffer_done = 1; |
1253 | } |
1254 | /* Fill buffer */ |
1255 | buf = dev->video_mode.isoc_ctl.buf; |
1256 | vbuf = vb2_plane_vaddr(vb: &buf->vb.vb2_buf, plane_no: 0); |
1257 | |
1258 | if ((dma_q->mpeg_buffer_completed+len) < |
1259 | mpeglines*mpeglinesize) { |
1260 | if (dma_q->add_ps_package_head == |
1261 | CX231XX_NEED_ADD_PS_PACKAGE_HEAD) { |
1262 | memcpy(vbuf+dma_q->mpeg_buffer_completed, |
1263 | dma_q->ps_head, 3); |
1264 | dma_q->mpeg_buffer_completed = |
1265 | dma_q->mpeg_buffer_completed + 3; |
1266 | dma_q->add_ps_package_head = |
1267 | CX231XX_NONEED_PS_PACKAGE_HEAD; |
1268 | } |
1269 | memcpy(vbuf+dma_q->mpeg_buffer_completed, data, len); |
1270 | dma_q->mpeg_buffer_completed = |
1271 | dma_q->mpeg_buffer_completed + len; |
1272 | } else { |
1273 | dma_q->mpeg_buffer_done = 0; |
1274 | |
1275 | tail_data = |
1276 | mpeglines*mpeglinesize - dma_q->mpeg_buffer_completed; |
1277 | memcpy(vbuf+dma_q->mpeg_buffer_completed, |
1278 | data, tail_data); |
1279 | |
1280 | buf->vb.vb2_buf.timestamp = ktime_get_ns(); |
1281 | buf->vb.sequence = dma_q->sequence++; |
1282 | list_del(entry: &buf->list); |
1283 | vb2_buffer_done(vb: &buf->vb.vb2_buf, state: VB2_BUF_STATE_DONE); |
1284 | dma_q->mpeg_buffer_completed = 0; |
1285 | |
1286 | if (len - tail_data > 0) { |
1287 | p_data = data + tail_data; |
1288 | dma_q->left_data_count = len - tail_data; |
1289 | memcpy(dma_q->p_left_data, |
1290 | p_data, len - tail_data); |
1291 | } |
1292 | } |
1293 | } |
1294 | |
1295 | static void buffer_filled(char *data, int len, struct urb *urb, |
1296 | struct cx231xx_dmaqueue *dma_q) |
1297 | { |
1298 | void *vbuf; |
1299 | struct cx231xx_buffer *buf; |
1300 | |
1301 | if (list_empty(head: &dma_q->active)) |
1302 | return; |
1303 | |
1304 | buf = list_entry(dma_q->active.next, struct cx231xx_buffer, list); |
1305 | |
1306 | /* Fill buffer */ |
1307 | vbuf = vb2_plane_vaddr(vb: &buf->vb.vb2_buf, plane_no: 0); |
1308 | memcpy(vbuf, data, len); |
1309 | buf->vb.sequence = dma_q->sequence++; |
1310 | buf->vb.vb2_buf.timestamp = ktime_get_ns(); |
1311 | list_del(entry: &buf->list); |
1312 | vb2_buffer_done(vb: &buf->vb.vb2_buf, state: VB2_BUF_STATE_DONE); |
1313 | } |
1314 | |
1315 | static int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb) |
1316 | { |
1317 | struct cx231xx_dmaqueue *dma_q = urb->context; |
1318 | unsigned char *p_buffer; |
1319 | u32 buffer_size = 0; |
1320 | u32 i = 0; |
1321 | |
1322 | for (i = 0; i < urb->number_of_packets; i++) { |
1323 | if (dma_q->left_data_count > 0) { |
1324 | buffer_copy(dev, data: dma_q->p_left_data, |
1325 | len: dma_q->left_data_count, urb, dma_q); |
1326 | dma_q->mpeg_buffer_completed = dma_q->left_data_count; |
1327 | dma_q->left_data_count = 0; |
1328 | } |
1329 | |
1330 | p_buffer = urb->transfer_buffer + |
1331 | urb->iso_frame_desc[i].offset; |
1332 | buffer_size = urb->iso_frame_desc[i].actual_length; |
1333 | |
1334 | if (buffer_size > 0) |
1335 | buffer_copy(dev, data: p_buffer, len: buffer_size, urb, dma_q); |
1336 | } |
1337 | |
1338 | return 0; |
1339 | } |
1340 | |
1341 | static int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb) |
1342 | { |
1343 | struct cx231xx_dmaqueue *dma_q = urb->context; |
1344 | unsigned char *p_buffer, *buffer; |
1345 | u32 buffer_size = 0; |
1346 | |
1347 | p_buffer = urb->transfer_buffer; |
1348 | buffer_size = urb->actual_length; |
1349 | |
1350 | buffer = kmalloc(size: buffer_size, GFP_ATOMIC); |
1351 | if (!buffer) |
1352 | return -ENOMEM; |
1353 | |
1354 | memcpy(buffer, dma_q->ps_head, 3); |
1355 | memcpy(buffer+3, p_buffer, buffer_size-3); |
1356 | memcpy(dma_q->ps_head, p_buffer+buffer_size-3, 3); |
1357 | |
1358 | p_buffer = buffer; |
1359 | buffer_filled(data: p_buffer, len: buffer_size, urb, dma_q); |
1360 | |
1361 | kfree(objp: buffer); |
1362 | return 0; |
1363 | } |
1364 | |
1365 | static void buffer_queue(struct vb2_buffer *vb) |
1366 | { |
1367 | struct cx231xx_buffer *buf = |
1368 | container_of(vb, struct cx231xx_buffer, vb.vb2_buf); |
1369 | struct cx231xx *dev = vb2_get_drv_priv(q: vb->vb2_queue); |
1370 | struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; |
1371 | unsigned long flags; |
1372 | |
1373 | spin_lock_irqsave(&dev->video_mode.slock, flags); |
1374 | list_add_tail(new: &buf->list, head: &vidq->active); |
1375 | spin_unlock_irqrestore(lock: &dev->video_mode.slock, flags); |
1376 | } |
1377 | |
1378 | static void return_all_buffers(struct cx231xx *dev, |
1379 | enum vb2_buffer_state state) |
1380 | { |
1381 | struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; |
1382 | struct cx231xx_buffer *buf, *node; |
1383 | unsigned long flags; |
1384 | |
1385 | spin_lock_irqsave(&dev->video_mode.slock, flags); |
1386 | list_for_each_entry_safe(buf, node, &vidq->active, list) { |
1387 | vb2_buffer_done(vb: &buf->vb.vb2_buf, state); |
1388 | list_del(entry: &buf->list); |
1389 | } |
1390 | spin_unlock_irqrestore(lock: &dev->video_mode.slock, flags); |
1391 | } |
1392 | |
1393 | static int start_streaming(struct vb2_queue *vq, unsigned int count) |
1394 | { |
1395 | struct cx231xx *dev = vb2_get_drv_priv(q: vq); |
1396 | struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; |
1397 | int ret = 0; |
1398 | |
1399 | vidq->sequence = 0; |
1400 | dev->mode_tv = 1; |
1401 | |
1402 | cx231xx_set_alt_setting(dev, index: INDEX_VANC, alt: 1); |
1403 | cx231xx_set_gpio_value(dev, pin_number: 2, pin_value: 0); |
1404 | |
1405 | cx231xx_initialize_codec(dev); |
1406 | |
1407 | cx231xx_start_TS1(dev); |
1408 | |
1409 | cx231xx_set_alt_setting(dev, index: INDEX_TS1, alt: 0); |
1410 | cx231xx_set_mode(dev, set_mode: CX231XX_DIGITAL_MODE); |
1411 | if (dev->USE_ISO) |
1412 | ret = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, |
1413 | CX231XX_NUM_BUFS, |
1414 | max_pkt_size: dev->ts1_mode.max_pkt_size, |
1415 | isoc_copy: cx231xx_isoc_copy); |
1416 | else |
1417 | ret = cx231xx_init_bulk(dev, max_packets: 320, num_bufs: 5, |
1418 | max_pkt_size: dev->ts1_mode.max_pkt_size, |
1419 | bulk_copy: cx231xx_bulk_copy); |
1420 | if (ret) |
1421 | return_all_buffers(dev, state: VB2_BUF_STATE_QUEUED); |
1422 | |
1423 | call_all(dev, video, s_stream, 1); |
1424 | return ret; |
1425 | } |
1426 | |
1427 | static void stop_streaming(struct vb2_queue *vq) |
1428 | { |
1429 | struct cx231xx *dev = vb2_get_drv_priv(q: vq); |
1430 | unsigned long flags; |
1431 | |
1432 | call_all(dev, video, s_stream, 0); |
1433 | |
1434 | cx231xx_stop_TS1(dev); |
1435 | |
1436 | /* do this before setting alternate! */ |
1437 | if (dev->USE_ISO) |
1438 | cx231xx_uninit_isoc(dev); |
1439 | else |
1440 | cx231xx_uninit_bulk(dev); |
1441 | cx231xx_set_mode(dev, set_mode: CX231XX_SUSPEND); |
1442 | |
1443 | cx231xx_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, inputcnt: 3, outputcnt: 0, |
1444 | CX231xx_END_NOW, CX231xx_MPEG_CAPTURE, |
1445 | CX231xx_RAW_BITS_NONE); |
1446 | |
1447 | spin_lock_irqsave(&dev->video_mode.slock, flags); |
1448 | if (dev->USE_ISO) |
1449 | dev->video_mode.isoc_ctl.buf = NULL; |
1450 | else |
1451 | dev->video_mode.bulk_ctl.buf = NULL; |
1452 | spin_unlock_irqrestore(lock: &dev->video_mode.slock, flags); |
1453 | return_all_buffers(dev, state: VB2_BUF_STATE_ERROR); |
1454 | } |
1455 | |
1456 | static struct vb2_ops cx231xx_video_qops = { |
1457 | .queue_setup = queue_setup, |
1458 | .buf_queue = buffer_queue, |
1459 | .start_streaming = start_streaming, |
1460 | .stop_streaming = stop_streaming, |
1461 | .wait_prepare = vb2_ops_wait_prepare, |
1462 | .wait_finish = vb2_ops_wait_finish, |
1463 | }; |
1464 | |
1465 | /* ------------------------------------------------------------------ */ |
1466 | |
1467 | static int vidioc_g_pixelaspect(struct file *file, void *priv, |
1468 | int type, struct v4l2_fract *f) |
1469 | { |
1470 | struct cx231xx *dev = video_drvdata(file); |
1471 | bool is_50hz = dev->encodernorm.id & V4L2_STD_625_50; |
1472 | |
1473 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1474 | return -EINVAL; |
1475 | |
1476 | f->numerator = is_50hz ? 54 : 11; |
1477 | f->denominator = is_50hz ? 59 : 10; |
1478 | |
1479 | return 0; |
1480 | } |
1481 | |
1482 | static int vidioc_g_selection(struct file *file, void *priv, |
1483 | struct v4l2_selection *s) |
1484 | { |
1485 | struct cx231xx *dev = video_drvdata(file); |
1486 | |
1487 | if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1488 | return -EINVAL; |
1489 | |
1490 | switch (s->target) { |
1491 | case V4L2_SEL_TGT_CROP_BOUNDS: |
1492 | case V4L2_SEL_TGT_CROP_DEFAULT: |
1493 | s->r.left = 0; |
1494 | s->r.top = 0; |
1495 | s->r.width = dev->ts1.width; |
1496 | s->r.height = dev->ts1.height; |
1497 | break; |
1498 | default: |
1499 | return -EINVAL; |
1500 | } |
1501 | return 0; |
1502 | } |
1503 | |
1504 | static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm) |
1505 | { |
1506 | struct cx231xx *dev = video_drvdata(file); |
1507 | |
1508 | *norm = dev->encodernorm.id; |
1509 | return 0; |
1510 | } |
1511 | |
1512 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) |
1513 | { |
1514 | struct cx231xx *dev = video_drvdata(file); |
1515 | unsigned int i; |
1516 | |
1517 | for (i = 0; i < ARRAY_SIZE(cx231xx_tvnorms); i++) |
1518 | if (id & cx231xx_tvnorms[i].id) |
1519 | break; |
1520 | if (i == ARRAY_SIZE(cx231xx_tvnorms)) |
1521 | return -EINVAL; |
1522 | dev->encodernorm = cx231xx_tvnorms[i]; |
1523 | |
1524 | if (dev->encodernorm.id & 0xb000) { |
1525 | dprintk(3, "encodernorm set to NTSC\n" ); |
1526 | dev->norm = V4L2_STD_NTSC; |
1527 | dev->ts1.height = 480; |
1528 | cx2341x_handler_set_50hz(cxhdl: &dev->mpeg_ctrl_handler, is_50hz: false); |
1529 | } else { |
1530 | dprintk(3, "encodernorm set to PAL\n" ); |
1531 | dev->norm = V4L2_STD_PAL_B; |
1532 | dev->ts1.height = 576; |
1533 | cx2341x_handler_set_50hz(cxhdl: &dev->mpeg_ctrl_handler, is_50hz: true); |
1534 | } |
1535 | call_all(dev, video, s_std, dev->norm); |
1536 | /* do mode control overrides */ |
1537 | cx231xx_do_mode_ctrl_overrides(dev); |
1538 | |
1539 | dprintk(3, "exit vidioc_s_std() i=0x%x\n" , i); |
1540 | return 0; |
1541 | } |
1542 | |
1543 | static int vidioc_s_ctrl(struct file *file, void *priv, |
1544 | struct v4l2_control *ctl) |
1545 | { |
1546 | struct cx231xx *dev = video_drvdata(file); |
1547 | struct v4l2_subdev *sd; |
1548 | |
1549 | dprintk(3, "enter vidioc_s_ctrl()\n" ); |
1550 | /* Update the A/V core */ |
1551 | v4l2_device_for_each_subdev(sd, &dev->v4l2_dev) |
1552 | v4l2_s_ctrl(NULL, hdl: sd->ctrl_handler, ctrl: ctl); |
1553 | dprintk(3, "exit vidioc_s_ctrl()\n" ); |
1554 | return 0; |
1555 | } |
1556 | |
1557 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, |
1558 | struct v4l2_fmtdesc *f) |
1559 | { |
1560 | if (f->index != 0) |
1561 | return -EINVAL; |
1562 | |
1563 | f->pixelformat = V4L2_PIX_FMT_MPEG; |
1564 | |
1565 | return 0; |
1566 | } |
1567 | |
1568 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, |
1569 | struct v4l2_format *f) |
1570 | { |
1571 | struct cx231xx *dev = video_drvdata(file); |
1572 | |
1573 | dprintk(3, "enter vidioc_g_fmt_vid_cap()\n" ); |
1574 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
1575 | f->fmt.pix.bytesperline = 0; |
1576 | f->fmt.pix.sizeimage = mpeglines * mpeglinesize; |
1577 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
1578 | f->fmt.pix.width = dev->ts1.width; |
1579 | f->fmt.pix.height = dev->ts1.height; |
1580 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; |
1581 | dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n" , |
1582 | dev->ts1.width, dev->ts1.height); |
1583 | dprintk(3, "exit vidioc_g_fmt_vid_cap()\n" ); |
1584 | return 0; |
1585 | } |
1586 | |
1587 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, |
1588 | struct v4l2_format *f) |
1589 | { |
1590 | struct cx231xx *dev = video_drvdata(file); |
1591 | |
1592 | dprintk(3, "enter vidioc_try_fmt_vid_cap()\n" ); |
1593 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
1594 | f->fmt.pix.bytesperline = 0; |
1595 | f->fmt.pix.sizeimage = mpeglines * mpeglinesize; |
1596 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; |
1597 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
1598 | dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n" , |
1599 | dev->ts1.width, dev->ts1.height); |
1600 | dprintk(3, "exit vidioc_try_fmt_vid_cap()\n" ); |
1601 | return 0; |
1602 | } |
1603 | |
1604 | static int vidioc_log_status(struct file *file, void *priv) |
1605 | { |
1606 | struct cx231xx *dev = video_drvdata(file); |
1607 | |
1608 | call_all(dev, core, log_status); |
1609 | return v4l2_ctrl_log_status(file, fh: priv); |
1610 | } |
1611 | |
1612 | static const struct v4l2_file_operations mpeg_fops = { |
1613 | .owner = THIS_MODULE, |
1614 | .open = v4l2_fh_open, |
1615 | .release = vb2_fop_release, |
1616 | .read = vb2_fop_read, |
1617 | .poll = vb2_fop_poll, |
1618 | .mmap = vb2_fop_mmap, |
1619 | .unlocked_ioctl = video_ioctl2, |
1620 | }; |
1621 | |
1622 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { |
1623 | .vidioc_s_std = vidioc_s_std, |
1624 | .vidioc_g_std = vidioc_g_std, |
1625 | .vidioc_g_tuner = cx231xx_g_tuner, |
1626 | .vidioc_s_tuner = cx231xx_s_tuner, |
1627 | .vidioc_g_frequency = cx231xx_g_frequency, |
1628 | .vidioc_s_frequency = cx231xx_s_frequency, |
1629 | .vidioc_enum_input = cx231xx_enum_input, |
1630 | .vidioc_g_input = cx231xx_g_input, |
1631 | .vidioc_s_input = cx231xx_s_input, |
1632 | .vidioc_s_ctrl = vidioc_s_ctrl, |
1633 | .vidioc_g_pixelaspect = vidioc_g_pixelaspect, |
1634 | .vidioc_g_selection = vidioc_g_selection, |
1635 | .vidioc_querycap = cx231xx_querycap, |
1636 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, |
1637 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, |
1638 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, |
1639 | .vidioc_s_fmt_vid_cap = vidioc_try_fmt_vid_cap, |
1640 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
1641 | .vidioc_querybuf = vb2_ioctl_querybuf, |
1642 | .vidioc_qbuf = vb2_ioctl_qbuf, |
1643 | .vidioc_dqbuf = vb2_ioctl_dqbuf, |
1644 | .vidioc_streamon = vb2_ioctl_streamon, |
1645 | .vidioc_streamoff = vb2_ioctl_streamoff, |
1646 | .vidioc_log_status = vidioc_log_status, |
1647 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1648 | .vidioc_g_register = cx231xx_g_register, |
1649 | .vidioc_s_register = cx231xx_s_register, |
1650 | #endif |
1651 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, |
1652 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, |
1653 | }; |
1654 | |
1655 | static struct video_device cx231xx_mpeg_template = { |
1656 | .name = "cx231xx" , |
1657 | .fops = &mpeg_fops, |
1658 | .ioctl_ops = &mpeg_ioctl_ops, |
1659 | .minor = -1, |
1660 | .tvnorms = V4L2_STD_ALL, |
1661 | }; |
1662 | |
1663 | void cx231xx_417_unregister(struct cx231xx *dev) |
1664 | { |
1665 | dprintk(1, "%s()\n" , __func__); |
1666 | dprintk(3, "%s()\n" , __func__); |
1667 | |
1668 | if (video_is_registered(vdev: &dev->v4l_device)) { |
1669 | video_unregister_device(vdev: &dev->v4l_device); |
1670 | v4l2_ctrl_handler_free(hdl: &dev->mpeg_ctrl_handler.hdl); |
1671 | } |
1672 | } |
1673 | |
1674 | static int cx231xx_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val) |
1675 | { |
1676 | struct cx231xx *dev = container_of(cxhdl, struct cx231xx, mpeg_ctrl_handler); |
1677 | int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; |
1678 | struct v4l2_subdev_format format = { |
1679 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, |
1680 | }; |
1681 | |
1682 | /* fix videodecoder resolution */ |
1683 | format.format.width = cxhdl->width / (is_mpeg1 ? 2 : 1); |
1684 | format.format.height = cxhdl->height; |
1685 | format.format.code = MEDIA_BUS_FMT_FIXED; |
1686 | v4l2_subdev_call(dev->sd_cx25840, pad, set_fmt, NULL, &format); |
1687 | return 0; |
1688 | } |
1689 | |
1690 | static int cx231xx_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx) |
1691 | { |
1692 | static const u32 freqs[3] = { 44100, 48000, 32000 }; |
1693 | struct cx231xx *dev = container_of(cxhdl, struct cx231xx, mpeg_ctrl_handler); |
1694 | |
1695 | /* The audio clock of the digitizer must match the codec sample |
1696 | rate otherwise you get some very strange effects. */ |
1697 | if (idx < ARRAY_SIZE(freqs)) |
1698 | call_all(dev, audio, s_clock_freq, freqs[idx]); |
1699 | return 0; |
1700 | } |
1701 | |
1702 | static const struct cx2341x_handler_ops cx231xx_ops = { |
1703 | /* needed for the video clock freq */ |
1704 | .s_audio_sampling_freq = cx231xx_s_audio_sampling_freq, |
1705 | /* needed for setting up the video resolution */ |
1706 | .s_video_encoding = cx231xx_s_video_encoding, |
1707 | }; |
1708 | |
1709 | static void cx231xx_video_dev_init( |
1710 | struct cx231xx *dev, |
1711 | struct usb_device *usbdev, |
1712 | struct video_device *vfd, |
1713 | const struct video_device *template, |
1714 | const char *type) |
1715 | { |
1716 | dprintk(1, "%s()\n" , __func__); |
1717 | *vfd = *template; |
1718 | snprintf(buf: vfd->name, size: sizeof(vfd->name), fmt: "%s %s (%s)" , dev->name, |
1719 | type, cx231xx_boards[dev->model].name); |
1720 | |
1721 | vfd->v4l2_dev = &dev->v4l2_dev; |
1722 | vfd->lock = &dev->lock; |
1723 | vfd->release = video_device_release_empty; |
1724 | vfd->ctrl_handler = &dev->mpeg_ctrl_handler.hdl; |
1725 | video_set_drvdata(vdev: vfd, data: dev); |
1726 | if (dev->tuner_type == TUNER_ABSENT) { |
1727 | v4l2_disable_ioctl(vdev: vfd, VIDIOC_G_FREQUENCY); |
1728 | v4l2_disable_ioctl(vdev: vfd, VIDIOC_S_FREQUENCY); |
1729 | v4l2_disable_ioctl(vdev: vfd, VIDIOC_G_TUNER); |
1730 | v4l2_disable_ioctl(vdev: vfd, VIDIOC_S_TUNER); |
1731 | } |
1732 | } |
1733 | |
1734 | int cx231xx_417_register(struct cx231xx *dev) |
1735 | { |
1736 | /* FIXME: Port1 hardcoded here */ |
1737 | int err; |
1738 | struct cx231xx_tsport *tsport = &dev->ts1; |
1739 | struct vb2_queue *q; |
1740 | |
1741 | dprintk(1, "%s()\n" , __func__); |
1742 | |
1743 | /* Set default TV standard */ |
1744 | dev->encodernorm = cx231xx_tvnorms[0]; |
1745 | |
1746 | if (dev->encodernorm.id & V4L2_STD_525_60) |
1747 | tsport->height = 480; |
1748 | else |
1749 | tsport->height = 576; |
1750 | |
1751 | tsport->width = 720; |
1752 | err = cx2341x_handler_init(cxhdl: &dev->mpeg_ctrl_handler, nr_of_controls_hint: 50); |
1753 | if (err) { |
1754 | dprintk(3, "%s: can't init cx2341x controls\n" , dev->name); |
1755 | return err; |
1756 | } |
1757 | dev->mpeg_ctrl_handler.func = cx231xx_mbox_func; |
1758 | dev->mpeg_ctrl_handler.priv = dev; |
1759 | dev->mpeg_ctrl_handler.ops = &cx231xx_ops; |
1760 | if (dev->sd_cx25840) |
1761 | v4l2_ctrl_add_handler(hdl: &dev->mpeg_ctrl_handler.hdl, |
1762 | add: dev->sd_cx25840->ctrl_handler, NULL, from_other_dev: true); |
1763 | if (dev->mpeg_ctrl_handler.hdl.error) { |
1764 | err = dev->mpeg_ctrl_handler.hdl.error; |
1765 | dprintk(3, "%s: can't add cx25840 controls\n" , dev->name); |
1766 | v4l2_ctrl_handler_free(hdl: &dev->mpeg_ctrl_handler.hdl); |
1767 | return err; |
1768 | } |
1769 | dev->norm = V4L2_STD_NTSC; |
1770 | |
1771 | dev->mpeg_ctrl_handler.port = CX2341X_PORT_SERIAL; |
1772 | cx2341x_handler_set_50hz(cxhdl: &dev->mpeg_ctrl_handler, is_50hz: false); |
1773 | |
1774 | /* Allocate and initialize V4L video device */ |
1775 | cx231xx_video_dev_init(dev, usbdev: dev->udev, |
1776 | vfd: &dev->v4l_device, template: &cx231xx_mpeg_template, type: "mpeg" ); |
1777 | q = &dev->mpegq; |
1778 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1779 | q->io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF | VB2_READ; |
1780 | q->drv_priv = dev; |
1781 | q->buf_struct_size = sizeof(struct cx231xx_buffer); |
1782 | q->ops = &cx231xx_video_qops; |
1783 | q->mem_ops = &vb2_vmalloc_memops; |
1784 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
1785 | q->min_queued_buffers = 1; |
1786 | q->lock = &dev->lock; |
1787 | err = vb2_queue_init(q); |
1788 | if (err) |
1789 | return err; |
1790 | dev->v4l_device.queue = q; |
1791 | |
1792 | err = video_register_device(vdev: &dev->v4l_device, |
1793 | type: VFL_TYPE_VIDEO, nr: -1); |
1794 | if (err < 0) { |
1795 | dprintk(3, "%s: can't register mpeg device\n" , dev->name); |
1796 | v4l2_ctrl_handler_free(hdl: &dev->mpeg_ctrl_handler.hdl); |
1797 | return err; |
1798 | } |
1799 | |
1800 | dprintk(3, "%s: registered device video%d [mpeg]\n" , |
1801 | dev->name, dev->v4l_device.num); |
1802 | |
1803 | return 0; |
1804 | } |
1805 | |
1806 | MODULE_FIRMWARE(CX231xx_FIRM_IMAGE_NAME); |
1807 | |