diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-16 16:44:11 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-16 16:44:11 -0300 |
commit | c7b38fa86c8174233108c89a0f13243486eeced4 (patch) | |
tree | 29a2f342ffb4b0835325c0621f7d6d93d51d65a0 /linux | |
parent | e3255aa9a39e6d17b11bdc91e55782c9a7d940dc (diff) | |
download | mediapointer-dvb-s2-c7b38fa86c8174233108c89a0f13243486eeced4.tar.gz mediapointer-dvb-s2-c7b38fa86c8174233108c89a0f13243486eeced4.tar.bz2 |
backport git changes on DaVinci driver
From: Mauro Carvalho Chehab <mchehab@redhat.com>
Due to several conflicts with OMAP arch files, the DaVinci patches were
applied directly to the -git tree. So, we need to backport those changes
to -hg.
Priority: normal
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux')
-rw-r--r-- | linux/drivers/media/video/Kconfig | 15 | ||||
-rw-r--r-- | linux/drivers/media/video/davinci/Makefile | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/davinci/vpif.c | 76 | ||||
-rw-r--r-- | linux/drivers/media/video/davinci/vpif.h | 48 | ||||
-rw-r--r-- | linux/drivers/media/video/davinci/vpif_display.c | 49 |
5 files changed, 126 insertions, 64 deletions
diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 14a1b6160..298eb937e 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -501,10 +501,21 @@ config DISPLAY_DAVINCI_DM646X_EVM select VIDEO_ADV7343 select VIDEO_THS7303 help - Support for DaVinci based display device. + Support for DM6467 based display device. To compile this driver as a module, choose M here: the - module will be called davincihd_display. + module will be called vpif_display. + +config CAPTURE_DAVINCI_DM646X_EVM + tristate "DM646x EVM Video Capture" + depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM + select VIDEOBUF_DMA_CONTIG + select VIDEO_DAVINCI_VPIF + help + Support for DM6467 based capture device. + + To compile this driver as a module, choose M here: the + module will be called vpif_capture. config VIDEO_DAVINCI_VPIF tristate "DaVinci VPIF Driver" diff --git a/linux/drivers/media/video/davinci/Makefile b/linux/drivers/media/video/davinci/Makefile index f44cad2f5..1a8b8f3f1 100644 --- a/linux/drivers/media/video/davinci/Makefile +++ b/linux/drivers/media/video/davinci/Makefile @@ -7,6 +7,8 @@ obj-$(CONFIG_VIDEO_DAVINCI_VPIF) += vpif.o #DM646x EVM Display driver obj-$(CONFIG_DISPLAY_DAVINCI_DM646X_EVM) += vpif_display.o +#DM646x EVM Capture driver +obj-$(CONFIG_CAPTURE_DAVINCI_DM646X_EVM) += vpif_capture.o # Capture: DM6446 and DM355 obj-$(CONFIG_VIDEO_VPSS_SYSTEM) += vpss.o diff --git a/linux/drivers/media/video/davinci/vpif.c b/linux/drivers/media/video/davinci/vpif.c index aa771268a..3b8eac31e 100644 --- a/linux/drivers/media/video/davinci/vpif.c +++ b/linux/drivers/media/video/davinci/vpif.c @@ -19,7 +19,11 @@ #include <linux/init.h> #include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spinlock.h> #include <linux/kernel.h> +#include <linux/io.h> +#include <mach/hardware.h> #include "vpif.h" @@ -31,6 +35,12 @@ MODULE_LICENSE("GPL"); #define VPIF_CH2_MAX_MODES (15) #define VPIF_CH3_MAX_MODES (02) +static resource_size_t res_len; +static struct resource *res; +spinlock_t vpif_lock; + +void __iomem *vpif_base; + static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val) { if (val) @@ -151,17 +161,17 @@ static void config_vpif_params(struct vpif_params *vpifparams, else if (config->capture_format) { /* Set the polarity of various pins */ vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT, - vpifparams->params.raw_params.fid_pol); + vpifparams->iface.fid_pol); vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT, - vpifparams->params.raw_params.vd_pol); + vpifparams->iface.vd_pol); vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT, - vpifparams->params.raw_params.hd_pol); + vpifparams->iface.hd_pol); value = regr(reg); /* Set data width */ value &= ((~(unsigned int)(0x3)) << VPIF_CH_DATA_WIDTH_BIT); - value |= ((vpifparams->params.raw_params.data_sz) << + value |= ((vpifparams->params.data_sz) << VPIF_CH_DATA_WIDTH_BIT); regw(value, reg); } @@ -227,8 +237,60 @@ int vpif_channel_getfid(u8 channel_id) } EXPORT_SYMBOL(vpif_channel_getfid); -void vpif_base_addr_init(void __iomem *base) +static int __init vpif_probe(struct platform_device *pdev) +{ + int status = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENOENT; + + res_len = res->end - res->start + 1; + + res = request_mem_region(res->start, res_len, res->name); + if (!res) + return -EBUSY; + + vpif_base = ioremap(res->start, res_len); + if (!vpif_base) { + status = -EBUSY; + goto fail; + } + + spin_lock_init(&vpif_lock); + dev_info(&pdev->dev, "vpif probe success\n"); + return 0; + +fail: + release_mem_region(res->start, res_len); + return status; +} + +static int vpif_remove(struct platform_device *pdev) { - vpif_base = base; + iounmap(vpif_base); + release_mem_region(res->start, res_len); + return 0; } -EXPORT_SYMBOL(vpif_base_addr_init); + +static struct platform_driver vpif_driver = { + .driver = { + .name = "vpif", + .owner = THIS_MODULE, + }, + .remove = __devexit_p(vpif_remove), + .probe = vpif_probe, +}; + +static void vpif_exit(void) +{ + platform_driver_unregister(&vpif_driver); +} + +static int __init vpif_init(void) +{ + return platform_driver_register(&vpif_driver); +} +subsys_initcall(vpif_init); +module_exit(vpif_exit); + diff --git a/linux/drivers/media/video/davinci/vpif.h b/linux/drivers/media/video/davinci/vpif.h index fca26dcb5..188841b47 100644 --- a/linux/drivers/media/video/davinci/vpif.h +++ b/linux/drivers/media/video/davinci/vpif.h @@ -19,6 +19,7 @@ #include <linux/io.h> #include <linux/videodev2.h> #include <mach/hardware.h> +#include <mach/dm646x.h> /* Maximum channel allowed */ #define VPIF_NUM_CHANNELS (4) @@ -26,7 +27,9 @@ #define VPIF_DISPLAY_NUM_CHANNELS (2) /* Macros to read/write registers */ -static void __iomem *vpif_base; +extern void __iomem *vpif_base; +extern spinlock_t vpif_lock; + #define regr(reg) readl((reg) + vpif_base) #define regw(value, reg) writel(value, (reg + vpif_base)) @@ -280,6 +283,10 @@ static inline void enable_channel1(int enable) /* inline function to enable interrupt for channel0 */ static inline void channel0_intr_enable(int enable) { + unsigned long flags; + + spin_lock_irqsave(&vpif_lock, flags); + if (enable) { regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); @@ -292,11 +299,16 @@ static inline void channel0_intr_enable(int enable) regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0), VPIF_INTEN_SET); } + spin_unlock_irqrestore(&vpif_lock, flags); } /* inline function to enable interrupt for channel1 */ static inline void channel1_intr_enable(int enable) { + unsigned long flags; + + spin_lock_irqsave(&vpif_lock, flags); + if (enable) { regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); @@ -309,6 +321,7 @@ static inline void channel1_intr_enable(int enable) regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1), VPIF_INTEN_SET); } + spin_unlock_irqrestore(&vpif_lock, flags); } /* 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) /* inline function to enable interrupt for channel2 */ static inline void channel2_intr_enable(int enable) { + unsigned long flags; + + spin_lock_irqsave(&vpif_lock, flags); + if (enable) { regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); @@ -442,11 +459,16 @@ static inline void channel2_intr_enable(int enable) regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2), VPIF_INTEN_SET); } + spin_unlock_irqrestore(&vpif_lock, flags); } /* inline function to enable interrupt for channel3 */ static inline void channel3_intr_enable(int enable) { + unsigned long flags; + + spin_lock_irqsave(&vpif_lock, flags); + if (enable) { regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN); regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET); @@ -459,6 +481,7 @@ static inline void channel3_intr_enable(int enable) regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3), VPIF_INTEN_SET); } + spin_unlock_irqrestore(&vpif_lock, flags); } /* inline function to enable raw vbi data for channel2 */ @@ -571,7 +594,7 @@ struct vpif_channel_config_params { v4l2_std_id stdid; }; -struct vpif_interface; +struct vpif_video_params; struct vpif_params; struct vpif_vbi_params; @@ -579,13 +602,6 @@ int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id); void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams, u8 channel_id); int vpif_channel_getfid(u8 channel_id); -void vpif_base_addr_init(void __iomem *base); - -/* Enumerated data types */ -enum vpif_capture_pinpol { - VPIF_CAPTURE_PINPOL_SAME = 0, - VPIF_CAPTURE_PINPOL_INVERT = 1 -}; enum data_size { _8BITS = 0, @@ -593,13 +609,6 @@ enum data_size { _12BITS, }; -struct vpif_capture_params_raw { - enum data_size data_sz; - enum vpif_capture_pinpol fid_pol; - enum vpif_capture_pinpol vd_pol; - enum vpif_capture_pinpol hd_pol; -}; - /* Structure for vpif parameters for raw vbi data */ struct vpif_vbi_params { __u32 hstart0; /* Horizontal start of raw vbi data for first field */ @@ -613,18 +622,19 @@ struct vpif_vbi_params { }; /* structure for vpif parameters */ -struct vpif_interface { +struct vpif_video_params { __u8 storage_mode; /* Indicates field or frame mode */ unsigned long hpitch; v4l2_std_id stdid; }; struct vpif_params { - struct vpif_interface video_params; + struct vpif_interface iface; + struct vpif_video_params video_params; struct vpif_channel_config_params std_info; union param { struct vpif_vbi_params vbi_params; - struct vpif_capture_params_raw raw_params; + enum data_size data_sz; } params; }; diff --git a/linux/drivers/media/video/davinci/vpif_display.c b/linux/drivers/media/video/davinci/vpif_display.c index a125a452d..c015da813 100644 --- a/linux/drivers/media/video/davinci/vpif_display.c +++ b/linux/drivers/media/video/davinci/vpif_display.c @@ -683,7 +683,7 @@ static int vpif_release(struct file *filep) static int vpif_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct vpif_config *config = vpif_dev->platform_data; + struct vpif_display_config *config = vpif_dev->platform_data; cap->version = VPIF_DISPLAY_VERSION_CODE; cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; @@ -1053,7 +1053,7 @@ static int vpif_streamon(struct file *file, void *priv, struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id]; struct vpif_params *vpif = &ch->vpifparams; - struct vpif_config *vpif_config_data = + struct vpif_display_config *vpif_config_data = vpif_dev->platform_data; unsigned long addr = 0; int ret = 0; @@ -1239,7 +1239,7 @@ static int vpif_enum_output(struct file *file, void *fh, struct v4l2_output *output) { - struct vpif_config *config = vpif_dev->platform_data; + struct vpif_display_config *config = vpif_dev->platform_data; if (output->index >= config->output_count) { vpif_dbg(1, debug, "Invalid output index\n"); @@ -1422,7 +1422,8 @@ vpif_init_free_channel_objects: */ static __init int vpif_probe(struct platform_device *pdev) { - const struct vpif_subdev_info *subdevdata; + struct vpif_subdev_info *subdevdata; + struct vpif_display_config *config; int i, j = 0, k, q, m, err = 0; struct i2c_adapter *i2c_adap; struct vpif_config *config; @@ -1433,30 +1434,14 @@ static __init int vpif_probe(struct platform_device *pdev) int subdev_count; vpif_dev = &pdev->dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - v4l2_err(vpif_dev->driver, - "Error getting platform resource\n"); - return -ENOENT; - } - if (!request_mem_region(res->start, res->end - res->start + 1, - vpif_dev->driver->name)) { - v4l2_err(vpif_dev->driver, "VPIF: failed request_mem_region\n"); - return -ENXIO; - } + err = initialize_vpif(); - vpif_base = ioremap_nocache(res->start, res->end - res->start + 1); - if (!vpif_base) { - v4l2_err(vpif_dev->driver, "Unable to ioremap VPIF reg\n"); - err = -ENXIO; - goto resource_exit; + if (err) { + v4l2_err(vpif_dev->driver, "Error initializing vpif\n"); + return err; } - vpif_base_addr_init(vpif_base); - - initialize_vpif(); - err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev); if (err) { v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n"); @@ -1489,7 +1474,7 @@ static __init int vpif_probe(struct platform_device *pdev) video_device_release(ch->video_dev); } err = -ENOMEM; - goto video_dev_alloc_exit; + goto vpif_int_err; } /* Initialize field of video device */ @@ -1566,10 +1551,10 @@ static __init int vpif_probe(struct platform_device *pdev) } for (i = 0; i < subdev_count; i++) { - vpif_obj.sd[i] = v4l2_i2c_new_subdev(&vpif_obj.v4l2_dev, + vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, i2c_adap, subdevdata[i].name, - subdevdata[i].name, - 0, I2C_ADDRS(subdevdata[i].addr)); + &subdevdata[i].board_info, + NULL); if (!vpif_obj.sd[i]) { vpif_err("Error registering v4l2 subdevice\n"); goto probe_subdev_out; @@ -1599,11 +1584,6 @@ vpif_int_err: res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1); m = res->end; } -video_dev_alloc_exit: - iounmap(vpif_base); -resource_exit: - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, res->end - res->start + 1); return err; } @@ -1666,9 +1646,6 @@ static void vpif_cleanup(void) i++; } - iounmap(vpif_base); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, res->end - res->start + 1); platform_driver_unregister(&vpif_driver); kfree(vpif_obj.sd); for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) |