diff options
Diffstat (limited to 'drivers/media/video/cx18/cx18-driver.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 70 |
1 files changed, 60 insertions, 10 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 7f65a47f12e1..c95a86ba33b0 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -47,6 +47,10 @@ | |||
47 | setting this to 1 you ensure that radio0 is now also radio1. */ | 47 | setting this to 1 you ensure that radio0 is now also radio1. */ |
48 | int cx18_first_minor; | 48 | int cx18_first_minor; |
49 | 49 | ||
50 | /* Callback for registering extensions */ | ||
51 | int (*cx18_ext_init)(struct cx18 *); | ||
52 | EXPORT_SYMBOL(cx18_ext_init); | ||
53 | |||
50 | /* add your revision and whatnot here */ | 54 | /* add your revision and whatnot here */ |
51 | static struct pci_device_id cx18_pci_tbl[] __devinitdata = { | 55 | static struct pci_device_id cx18_pci_tbl[] __devinitdata = { |
52 | {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, | 56 | {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, |
@@ -91,7 +95,7 @@ static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE; | |||
91 | 95 | ||
92 | static int enc_ts_bufs = -1; | 96 | static int enc_ts_bufs = -1; |
93 | static int enc_mpg_bufs = -1; | 97 | static int enc_mpg_bufs = -1; |
94 | static int enc_idx_bufs = -1; | 98 | static int enc_idx_bufs = CX18_MAX_FW_MDLS_PER_STREAM; |
95 | static int enc_yuv_bufs = -1; | 99 | static int enc_yuv_bufs = -1; |
96 | static int enc_vbi_bufs = -1; | 100 | static int enc_vbi_bufs = -1; |
97 | static int enc_pcm_bufs = -1; | 101 | static int enc_pcm_bufs = -1; |
@@ -196,14 +200,17 @@ MODULE_PARM_DESC(enc_mpg_bufs, | |||
196 | "Number of encoder MPG buffers\n" | 200 | "Number of encoder MPG buffers\n" |
197 | "\t\t\tDefault is computed from other enc_mpg_* parameters"); | 201 | "\t\t\tDefault is computed from other enc_mpg_* parameters"); |
198 | MODULE_PARM_DESC(enc_idx_buffers, | 202 | MODULE_PARM_DESC(enc_idx_buffers, |
199 | "Encoder IDX buffer memory (MB). (enc_idx_bufs can override)\n" | 203 | "(Deprecated) Encoder IDX buffer memory (MB)\n" |
200 | "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFFERS)); | 204 | "\t\t\tIgnored, except 0 disables IDX buffer allocations\n" |
205 | "\t\t\tDefault: 1 [Enabled]"); | ||
201 | MODULE_PARM_DESC(enc_idx_bufsize, | 206 | MODULE_PARM_DESC(enc_idx_bufsize, |
202 | "Size of an encoder IDX buffer (kB)\n" | 207 | "Size of an encoder IDX buffer (kB)\n" |
203 | "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFSIZE)); | 208 | "\t\t\tAllowed values are multiples of 1.5 kB rounded up\n" |
209 | "\t\t\t(multiples of size required for 64 index entries)\n" | ||
210 | "\t\t\tDefault: 2"); | ||
204 | MODULE_PARM_DESC(enc_idx_bufs, | 211 | MODULE_PARM_DESC(enc_idx_bufs, |
205 | "Number of encoder IDX buffers\n" | 212 | "Number of encoder IDX buffers\n" |
206 | "\t\t\tDefault is computed from other enc_idx_* parameters"); | 213 | "\t\t\tDefault: " __stringify(CX18_MAX_FW_MDLS_PER_STREAM)); |
207 | MODULE_PARM_DESC(enc_yuv_buffers, | 214 | MODULE_PARM_DESC(enc_yuv_buffers, |
208 | "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n" | 215 | "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n" |
209 | "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); | 216 | "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); |
@@ -231,7 +238,8 @@ MODULE_PARM_DESC(enc_pcm_bufs, | |||
231 | "Number of encoder PCM buffers\n" | 238 | "Number of encoder PCM buffers\n" |
232 | "\t\t\tDefault is computed from other enc_pcm_* parameters"); | 239 | "\t\t\tDefault is computed from other enc_pcm_* parameters"); |
233 | 240 | ||
234 | MODULE_PARM_DESC(cx18_first_minor, "Set device node number assigned to first card"); | 241 | MODULE_PARM_DESC(cx18_first_minor, |
242 | "Set device node number assigned to first card"); | ||
235 | 243 | ||
236 | MODULE_AUTHOR("Hans Verkuil"); | 244 | MODULE_AUTHOR("Hans Verkuil"); |
237 | MODULE_DESCRIPTION("CX23418 driver"); | 245 | MODULE_DESCRIPTION("CX23418 driver"); |
@@ -240,6 +248,28 @@ MODULE_LICENSE("GPL"); | |||
240 | 248 | ||
241 | MODULE_VERSION(CX18_VERSION); | 249 | MODULE_VERSION(CX18_VERSION); |
242 | 250 | ||
251 | #if defined(CONFIG_MODULES) && defined(MODULE) | ||
252 | static void request_module_async(struct work_struct *work) | ||
253 | { | ||
254 | struct cx18 *dev = container_of(work, struct cx18, request_module_wk); | ||
255 | |||
256 | /* Make sure cx18-alsa module is loaded */ | ||
257 | request_module("cx18-alsa"); | ||
258 | |||
259 | /* Initialize cx18-alsa for this instance of the cx18 device */ | ||
260 | if (cx18_ext_init != NULL) | ||
261 | cx18_ext_init(dev); | ||
262 | } | ||
263 | |||
264 | static void request_modules(struct cx18 *dev) | ||
265 | { | ||
266 | INIT_WORK(&dev->request_module_wk, request_module_async); | ||
267 | schedule_work(&dev->request_module_wk); | ||
268 | } | ||
269 | #else | ||
270 | #define request_modules(dev) | ||
271 | #endif /* CONFIG_MODULES */ | ||
272 | |||
243 | /* Generic utility functions */ | 273 | /* Generic utility functions */ |
244 | int cx18_msleep_timeout(unsigned int msecs, int intr) | 274 | int cx18_msleep_timeout(unsigned int msecs, int intr) |
245 | { | 275 | { |
@@ -501,7 +531,12 @@ static void cx18_process_options(struct cx18 *cx) | |||
501 | /* | 531 | /* |
502 | * YUV is a special case where the stream_buf_size needs to be | 532 | * YUV is a special case where the stream_buf_size needs to be |
503 | * an integral multiple of 33.75 kB (storage for 32 screens | 533 | * an integral multiple of 33.75 kB (storage for 32 screens |
504 | * lines to maintain alignment in case of lost buffers | 534 | * lines to maintain alignment in case of lost buffers). |
535 | * | ||
536 | * IDX is a special case where the stream_buf_size should be | ||
537 | * an integral multiple of 1.5 kB (storage for 64 index entries | ||
538 | * to maintain alignment in case of lost buffers). | ||
539 | * | ||
505 | */ | 540 | */ |
506 | if (i == CX18_ENC_STREAM_TYPE_YUV) { | 541 | if (i == CX18_ENC_STREAM_TYPE_YUV) { |
507 | cx->stream_buf_size[i] *= 1024; | 542 | cx->stream_buf_size[i] *= 1024; |
@@ -511,15 +546,24 @@ static void cx18_process_options(struct cx18 *cx) | |||
511 | if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE) | 546 | if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE) |
512 | cx->stream_buf_size[i] = | 547 | cx->stream_buf_size[i] = |
513 | CX18_UNIT_ENC_YUV_BUFSIZE; | 548 | CX18_UNIT_ENC_YUV_BUFSIZE; |
549 | } else if (i == CX18_ENC_STREAM_TYPE_IDX) { | ||
550 | cx->stream_buf_size[i] *= 1024; | ||
551 | cx->stream_buf_size[i] -= | ||
552 | (cx->stream_buf_size[i] % CX18_UNIT_ENC_IDX_BUFSIZE); | ||
553 | |||
554 | if (cx->stream_buf_size[i] < CX18_UNIT_ENC_IDX_BUFSIZE) | ||
555 | cx->stream_buf_size[i] = | ||
556 | CX18_UNIT_ENC_IDX_BUFSIZE; | ||
514 | } | 557 | } |
515 | /* | 558 | /* |
516 | * YUV is a special case where the stream_buf_size is | 559 | * YUV and IDX are special cases where the stream_buf_size is |
517 | * now in bytes. | 560 | * now in bytes. |
518 | * VBI is a special case where the stream_buf_size is fixed | 561 | * VBI is a special case where the stream_buf_size is fixed |
519 | * and already in bytes | 562 | * and already in bytes |
520 | */ | 563 | */ |
521 | if (i == CX18_ENC_STREAM_TYPE_VBI || | 564 | if (i == CX18_ENC_STREAM_TYPE_VBI || |
522 | i == CX18_ENC_STREAM_TYPE_YUV) { | 565 | i == CX18_ENC_STREAM_TYPE_YUV || |
566 | i == CX18_ENC_STREAM_TYPE_IDX) { | ||
523 | if (cx->stream_buffers[i] < 0) { | 567 | if (cx->stream_buffers[i] < 0) { |
524 | cx->stream_buffers[i] = | 568 | cx->stream_buffers[i] = |
525 | cx->options.megabytes[i] * 1024 * 1024 | 569 | cx->options.megabytes[i] * 1024 * 1024 |
@@ -1032,6 +1076,10 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, | |||
1032 | } | 1076 | } |
1033 | 1077 | ||
1034 | CX18_INFO("Initialized card: %s\n", cx->card_name); | 1078 | CX18_INFO("Initialized card: %s\n", cx->card_name); |
1079 | |||
1080 | /* Load cx18 submodules (cx18-alsa) */ | ||
1081 | request_modules(cx); | ||
1082 | |||
1035 | return 0; | 1083 | return 0; |
1036 | 1084 | ||
1037 | free_streams: | 1085 | free_streams: |
@@ -1220,6 +1268,7 @@ static void cx18_remove(struct pci_dev *pci_dev) | |||
1220 | kfree(cx); | 1268 | kfree(cx); |
1221 | } | 1269 | } |
1222 | 1270 | ||
1271 | |||
1223 | /* define a pci_driver for card detection */ | 1272 | /* define a pci_driver for card detection */ |
1224 | static struct pci_driver cx18_pci_driver = { | 1273 | static struct pci_driver cx18_pci_driver = { |
1225 | .name = "cx18", | 1274 | .name = "cx18", |
@@ -1230,7 +1279,8 @@ static struct pci_driver cx18_pci_driver = { | |||
1230 | 1279 | ||
1231 | static int __init module_start(void) | 1280 | static int __init module_start(void) |
1232 | { | 1281 | { |
1233 | printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION); | 1282 | printk(KERN_INFO "cx18: Start initialization, version %s\n", |
1283 | CX18_VERSION); | ||
1234 | 1284 | ||
1235 | /* Validate parameters */ | 1285 | /* Validate parameters */ |
1236 | if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { | 1286 | if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { |