diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/davinci/vpif.c | 76 | ||||
-rw-r--r-- | drivers/media/video/davinci/vpif.h | 48 |
2 files changed, 98 insertions, 26 deletions
diff --git a/drivers/media/video/davinci/vpif.c b/drivers/media/video/davinci/vpif.c index aa771268a5a5..3b8eac31ecae 100644 --- a/drivers/media/video/davinci/vpif.c +++ b/drivers/media/video/davinci/vpif.c | |||
@@ -19,7 +19,11 @@ | |||
19 | 19 | ||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/spinlock.h> | ||
22 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/io.h> | ||
26 | #include <mach/hardware.h> | ||
23 | 27 | ||
24 | #include "vpif.h" | 28 | #include "vpif.h" |
25 | 29 | ||
@@ -31,6 +35,12 @@ MODULE_LICENSE("GPL"); | |||
31 | #define VPIF_CH2_MAX_MODES (15) | 35 | #define VPIF_CH2_MAX_MODES (15) |
32 | #define VPIF_CH3_MAX_MODES (02) | 36 | #define VPIF_CH3_MAX_MODES (02) |
33 | 37 | ||
38 | static resource_size_t res_len; | ||
39 | static struct resource *res; | ||
40 | spinlock_t vpif_lock; | ||
41 | |||
42 | void __iomem *vpif_base; | ||
43 | |||
34 | static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val) | 44 | static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val) |
35 | { | 45 | { |
36 | if (val) | 46 | if (val) |
@@ -151,17 +161,17 @@ static void config_vpif_params(struct vpif_params *vpifparams, | |||
151 | else if (config->capture_format) { | 161 | else if (config->capture_format) { |
152 | /* Set the polarity of various pins */ | 162 | /* Set the polarity of various pins */ |
153 | vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT, | 163 | vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT, |
154 | vpifparams->params.raw_params.fid_pol); | 164 | vpifparams->iface.fid_pol); |
155 | vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT, | 165 | vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT, |
156 | vpifparams->params.raw_params.vd_pol); | 166 | vpifparams->iface.vd_pol); |
157 | vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT, | 167 | vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT, |
158 | vpifparams->params.raw_params.hd_pol); | 168 | vpifparams->iface.hd_pol); |
159 | 169 | ||
160 | value = regr(reg); | 170 | value = regr(reg); |
161 | /* Set data width */ | 171 | /* Set data width */ |
162 | value &= ((~(unsigned int)(0x3)) << | 172 | value &= ((~(unsigned int)(0x3)) << |
163 | VPIF_CH_DATA_WIDTH_BIT); | 173 | VPIF_CH_DATA_WIDTH_BIT); |
164 | value |= ((vpifparams->params.raw_params.data_sz) << | 174 | value |= ((vpifparams->params.data_sz) << |
165 | VPIF_CH_DATA_WIDTH_BIT); | 175 | VPIF_CH_DATA_WIDTH_BIT); |
166 | regw(value, reg); | 176 | regw(value, reg); |
167 | } | 177 | } |
@@ -227,8 +237,60 @@ int vpif_channel_getfid(u8 channel_id) | |||
227 | } | 237 | } |
228 | EXPORT_SYMBOL(vpif_channel_getfid); | 238 | EXPORT_SYMBOL(vpif_channel_getfid); |
229 | 239 | ||
230 | void vpif_base_addr_init(void __iomem *base) | 240 | static int __init vpif_probe(struct platform_device *pdev) |
241 | { | ||
242 | int status = 0; | ||
243 | |||
244 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
245 | if (!res) | ||
246 | return -ENOENT; | ||
247 | |||
248 | res_len = res->end - res->start + 1; | ||
249 | |||
250 | res = request_mem_region(res->start, res_len, res->name); | ||
251 | if (!res) | ||
252 | return -EBUSY; | ||
253 | |||
254 | vpif_base = ioremap(res->start, res_len); | ||
255 | if (!vpif_base) { | ||
256 | status = -EBUSY; | ||
257 | goto fail; | ||
258 | } | ||
259 | |||
260 | spin_lock_init(&vpif_lock); | ||
261 | dev_info(&pdev->dev, "vpif probe success\n"); | ||
262 | return 0; | ||
263 | |||
264 | fail: | ||
265 | release_mem_region(res->start, res_len); | ||
266 | return status; | ||
267 | } | ||
268 | |||
269 | static int vpif_remove(struct platform_device *pdev) | ||
231 | { | 270 | { |
232 | vpif_base = base; | 271 | iounmap(vpif_base); |
272 | release_mem_region(res->start, res_len); | ||
273 | return 0; | ||
233 | } | 274 | } |
234 | EXPORT_SYMBOL(vpif_base_addr_init); | 275 | |
276 | static struct platform_driver vpif_driver = { | ||
277 | .driver = { | ||
278 | .name = "vpif", | ||
279 | .owner = THIS_MODULE, | ||
280 | }, | ||
281 | .remove = __devexit_p(vpif_remove), | ||
282 | .probe = vpif_probe, | ||
283 | }; | ||
284 | |||
285 | static void vpif_exit(void) | ||
286 | { | ||
287 | platform_driver_unregister(&vpif_driver); | ||
288 | } | ||
289 | |||
290 | static int __init vpif_init(void) | ||
291 | { | ||
292 | return platform_driver_register(&vpif_driver); | ||
293 | } | ||
294 | subsys_initcall(vpif_init); | ||
295 | module_exit(vpif_exit); | ||
296 | |||
diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h index fca26dcb54de..188841b476e0 100644 --- a/drivers/media/video/davinci/vpif.h +++ b/drivers/media/video/davinci/vpif.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/videodev2.h> | 20 | #include <linux/videodev2.h> |
21 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
22 | #include <mach/dm646x.h> | ||
22 | 23 | ||
23 | /* Maximum channel allowed */ | 24 | /* Maximum channel allowed */ |
24 | #define VPIF_NUM_CHANNELS (4) | 25 | #define VPIF_NUM_CHANNELS (4) |
@@ -26,7 +27,9 @@ | |||
26 | #define VPIF_DISPLAY_NUM_CHANNELS (2) | 27 | #define VPIF_DISPLAY_NUM_CHANNELS (2) |
27 | 28 | ||
28 | /* Macros to read/write registers */ | 29 | /* Macros to read/write registers */ |
29 | static void __iomem *vpif_base; | 30 | extern void __iomem *vpif_base; |
31 | extern spinlock_t vpif_lock; | ||
32 | |||
30 | #define regr(reg) readl((reg) + vpif_base) | 33 | #define regr(reg) readl((reg) + vpif_base) |
31 | #define regw(value, reg) writel(value, (reg + vpif_base)) | 34 | #define regw(value, reg) writel(value, (reg + vpif_base)) |
32 | 35 | ||
@@ -280,6 +283,10 @@ static inline void enable_channel1(int enable) | |||
280 | /* inline function to enable interrupt for channel0 */ | 283 | /* inline function to enable interrupt for channel0 */ |
281 | static inline void channel0_intr_enable(int enable) | 284 | static inline void channel0_intr_enable(int enable) |
282 | { | 285 | { |
286 | unsigned long flags; | ||
287 | |||
288 | spin_lock_irqsave(&vpif_lock, flags); | ||
289 | |||
283 | if (enable) { | 290 | if (enable) { |
284 | regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); | 291 | regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); |
285 | regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); | 292 | regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); |
@@ -292,11 +299,16 @@ static inline void channel0_intr_enable(int enable) | |||
292 | regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0), | 299 | regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0), |
293 | VPIF_INTEN_SET); | 300 | VPIF_INTEN_SET); |
294 | } | 301 | } |
302 | spin_unlock_irqrestore(&vpif_lock, flags); | ||
295 | } | 303 | } |
296 | 304 | ||
297 | /* inline function to enable interrupt for channel1 */ | 305 | /* inline function to enable interrupt for channel1 */ |
298 | static inline void channel1_intr_enable(int enable) | 306 | static inline void channel1_intr_enable(int enable) |
299 | { | 307 | { |
308 | unsigned long flags; | ||
309 | |||
310 | spin_lock_irqsave(&vpif_lock, flags); | ||
311 | |||
300 | if (enable) { | 312 | if (enable) { |
301 | regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); | 313 | regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); |
302 | regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); | 314 | regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); |
@@ -309,6 +321,7 @@ static inline void channel1_intr_enable(int enable) | |||
309 | regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1), | 321 | regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1), |
310 | VPIF_INTEN_SET); | 322 | VPIF_INTEN_SET); |
311 | } | 323 | } |
324 | spin_unlock_irqrestore(&vpif_lock, flags); | ||
312 | } | 325 | } |
313 | 326 | ||
314 | /* inline function to set buffer addresses in case of Y/C non mux mode */ | 327 | /* inline function to set buffer addresses in case of Y/C non mux mode */ |
@@ -431,6 +444,10 @@ static inline void enable_channel3(int enable) | |||
431 | /* inline function to enable interrupt for channel2 */ | 444 | /* inline function to enable interrupt for channel2 */ |
432 | static inline void channel2_intr_enable(int enable) | 445 | static inline void channel2_intr_enable(int enable) |
433 | { | 446 | { |
447 | unsigned long flags; | ||
448 | |||
449 | spin_lock_irqsave(&vpif_lock, flags); | ||
450 | |||
434 | if (enable) { | 451 | if (enable) { |
435 | regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); | 452 | regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); |
436 | regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); | 453 | regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); |
@@ -442,11 +459,16 @@ static inline void channel2_intr_enable(int enable) | |||
442 | regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2), | 459 | regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2), |
443 | VPIF_INTEN_SET); | 460 | VPIF_INTEN_SET); |
444 | } | 461 | } |
462 | spin_unlock_irqrestore(&vpif_lock, flags); | ||
445 | } | 463 | } |
446 | 464 | ||
447 | /* inline function to enable interrupt for channel3 */ | 465 | /* inline function to enable interrupt for channel3 */ |
448 | static inline void channel3_intr_enable(int enable) | 466 | static inline void channel3_intr_enable(int enable) |
449 | { | 467 | { |
468 | unsigned long flags; | ||
469 | |||
470 | spin_lock_irqsave(&vpif_lock, flags); | ||
471 | |||
450 | if (enable) { | 472 | if (enable) { |
451 | regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); | 473 | regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); |
452 | regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); | 474 | regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); |
@@ -459,6 +481,7 @@ static inline void channel3_intr_enable(int enable) | |||
459 | regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3), | 481 | regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3), |
460 | VPIF_INTEN_SET); | 482 | VPIF_INTEN_SET); |
461 | } | 483 | } |
484 | spin_unlock_irqrestore(&vpif_lock, flags); | ||
462 | } | 485 | } |
463 | 486 | ||
464 | /* inline function to enable raw vbi data for channel2 */ | 487 | /* inline function to enable raw vbi data for channel2 */ |
@@ -571,7 +594,7 @@ struct vpif_channel_config_params { | |||
571 | v4l2_std_id stdid; | 594 | v4l2_std_id stdid; |
572 | }; | 595 | }; |
573 | 596 | ||
574 | struct vpif_interface; | 597 | struct vpif_video_params; |
575 | struct vpif_params; | 598 | struct vpif_params; |
576 | struct vpif_vbi_params; | 599 | struct vpif_vbi_params; |
577 | 600 | ||
@@ -579,13 +602,6 @@ int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id); | |||
579 | void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams, | 602 | void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams, |
580 | u8 channel_id); | 603 | u8 channel_id); |
581 | int vpif_channel_getfid(u8 channel_id); | 604 | int vpif_channel_getfid(u8 channel_id); |
582 | void vpif_base_addr_init(void __iomem *base); | ||
583 | |||
584 | /* Enumerated data types */ | ||
585 | enum vpif_capture_pinpol { | ||
586 | VPIF_CAPTURE_PINPOL_SAME = 0, | ||
587 | VPIF_CAPTURE_PINPOL_INVERT = 1 | ||
588 | }; | ||
589 | 605 | ||
590 | enum data_size { | 606 | enum data_size { |
591 | _8BITS = 0, | 607 | _8BITS = 0, |
@@ -593,13 +609,6 @@ enum data_size { | |||
593 | _12BITS, | 609 | _12BITS, |
594 | }; | 610 | }; |
595 | 611 | ||
596 | struct vpif_capture_params_raw { | ||
597 | enum data_size data_sz; | ||
598 | enum vpif_capture_pinpol fid_pol; | ||
599 | enum vpif_capture_pinpol vd_pol; | ||
600 | enum vpif_capture_pinpol hd_pol; | ||
601 | }; | ||
602 | |||
603 | /* Structure for vpif parameters for raw vbi data */ | 612 | /* Structure for vpif parameters for raw vbi data */ |
604 | struct vpif_vbi_params { | 613 | struct vpif_vbi_params { |
605 | __u32 hstart0; /* Horizontal start of raw vbi data for first field */ | 614 | __u32 hstart0; /* Horizontal start of raw vbi data for first field */ |
@@ -613,18 +622,19 @@ struct vpif_vbi_params { | |||
613 | }; | 622 | }; |
614 | 623 | ||
615 | /* structure for vpif parameters */ | 624 | /* structure for vpif parameters */ |
616 | struct vpif_interface { | 625 | struct vpif_video_params { |
617 | __u8 storage_mode; /* Indicates field or frame mode */ | 626 | __u8 storage_mode; /* Indicates field or frame mode */ |
618 | unsigned long hpitch; | 627 | unsigned long hpitch; |
619 | v4l2_std_id stdid; | 628 | v4l2_std_id stdid; |
620 | }; | 629 | }; |
621 | 630 | ||
622 | struct vpif_params { | 631 | struct vpif_params { |
623 | struct vpif_interface video_params; | 632 | struct vpif_interface iface; |
633 | struct vpif_video_params video_params; | ||
624 | struct vpif_channel_config_params std_info; | 634 | struct vpif_channel_config_params std_info; |
625 | union param { | 635 | union param { |
626 | struct vpif_vbi_params vbi_params; | 636 | struct vpif_vbi_params vbi_params; |
627 | struct vpif_capture_params_raw raw_params; | 637 | enum data_size data_sz; |
628 | } params; | 638 | } params; |
629 | }; | 639 | }; |
630 | 640 | ||