diff options
Diffstat (limited to 'drivers/media/video/davinci/vpbe.c')
-rw-r--r-- | drivers/media/video/davinci/vpbe.c | 76 |
1 files changed, 49 insertions, 27 deletions
diff --git a/drivers/media/video/davinci/vpbe.c b/drivers/media/video/davinci/vpbe.c index d773d30de221..c4a82a1a8a97 100644 --- a/drivers/media/video/davinci/vpbe.c +++ b/drivers/media/video/davinci/vpbe.c | |||
@@ -141,11 +141,12 @@ static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev, | |||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
144 | static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode) | 144 | static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode, |
145 | int output_index) | ||
145 | { | 146 | { |
146 | struct vpbe_config *cfg = vpbe_dev->cfg; | 147 | struct vpbe_config *cfg = vpbe_dev->cfg; |
147 | struct vpbe_enc_mode_info var; | 148 | struct vpbe_enc_mode_info var; |
148 | int curr_output = vpbe_dev->current_out_index; | 149 | int curr_output = output_index; |
149 | int i; | 150 | int i; |
150 | 151 | ||
151 | if (NULL == mode) | 152 | if (NULL == mode) |
@@ -245,6 +246,8 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) | |||
245 | struct encoder_config_info *curr_enc_info = | 246 | struct encoder_config_info *curr_enc_info = |
246 | vpbe_current_encoder_info(vpbe_dev); | 247 | vpbe_current_encoder_info(vpbe_dev); |
247 | struct vpbe_config *cfg = vpbe_dev->cfg; | 248 | struct vpbe_config *cfg = vpbe_dev->cfg; |
249 | struct venc_platform_data *venc_device = vpbe_dev->venc_device; | ||
250 | enum v4l2_mbus_pixelcode if_params; | ||
248 | int enc_out_index; | 251 | int enc_out_index; |
249 | int sd_index; | 252 | int sd_index; |
250 | int ret = 0; | 253 | int ret = 0; |
@@ -274,6 +277,8 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) | |||
274 | goto out; | 277 | goto out; |
275 | } | 278 | } |
276 | 279 | ||
280 | if_params = cfg->outputs[index].if_params; | ||
281 | venc_device->setup_if_config(if_params); | ||
277 | if (ret) | 282 | if (ret) |
278 | goto out; | 283 | goto out; |
279 | } | 284 | } |
@@ -293,7 +298,7 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) | |||
293 | * encoder. | 298 | * encoder. |
294 | */ | 299 | */ |
295 | ret = vpbe_get_mode_info(vpbe_dev, | 300 | ret = vpbe_get_mode_info(vpbe_dev, |
296 | cfg->outputs[index].default_mode); | 301 | cfg->outputs[index].default_mode, index); |
297 | if (!ret) { | 302 | if (!ret) { |
298 | struct osd_state *osd_device = vpbe_dev->osd_device; | 303 | struct osd_state *osd_device = vpbe_dev->osd_device; |
299 | 304 | ||
@@ -367,6 +372,11 @@ static int vpbe_s_dv_preset(struct vpbe_device *vpbe_dev, | |||
367 | 372 | ||
368 | ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, | 373 | ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, |
369 | s_dv_preset, dv_preset); | 374 | s_dv_preset, dv_preset); |
375 | if (!ret && (vpbe_dev->amp != NULL)) { | ||
376 | /* Call amplifier subdevice */ | ||
377 | ret = v4l2_subdev_call(vpbe_dev->amp, video, | ||
378 | s_dv_preset, dv_preset); | ||
379 | } | ||
370 | /* set the lcd controller output for the given mode */ | 380 | /* set the lcd controller output for the given mode */ |
371 | if (!ret) { | 381 | if (!ret) { |
372 | struct osd_state *osd_device = vpbe_dev->osd_device; | 382 | struct osd_state *osd_device = vpbe_dev->osd_device; |
@@ -566,6 +576,8 @@ static int platform_device_get(struct device *dev, void *data) | |||
566 | 576 | ||
567 | if (strcmp("vpbe-osd", pdev->name) == 0) | 577 | if (strcmp("vpbe-osd", pdev->name) == 0) |
568 | vpbe_dev->osd_device = platform_get_drvdata(pdev); | 578 | vpbe_dev->osd_device = platform_get_drvdata(pdev); |
579 | if (strcmp("vpbe-venc", pdev->name) == 0) | ||
580 | vpbe_dev->venc_device = dev_get_platdata(&pdev->dev); | ||
569 | 581 | ||
570 | return 0; | 582 | return 0; |
571 | } | 583 | } |
@@ -584,6 +596,7 @@ static int platform_device_get(struct device *dev, void *data) | |||
584 | static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) | 596 | static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) |
585 | { | 597 | { |
586 | struct encoder_config_info *enc_info; | 598 | struct encoder_config_info *enc_info; |
599 | struct amp_config_info *amp_info; | ||
587 | struct v4l2_subdev **enc_subdev; | 600 | struct v4l2_subdev **enc_subdev; |
588 | struct osd_state *osd_device; | 601 | struct osd_state *osd_device; |
589 | struct i2c_adapter *i2c_adap; | 602 | struct i2c_adapter *i2c_adap; |
@@ -704,6 +717,32 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) | |||
704 | v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders" | 717 | v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders" |
705 | " currently not supported"); | 718 | " currently not supported"); |
706 | } | 719 | } |
720 | /* Add amplifier subdevice for dm365 */ | ||
721 | if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) && | ||
722 | vpbe_dev->cfg->amp != NULL) { | ||
723 | amp_info = vpbe_dev->cfg->amp; | ||
724 | if (amp_info->is_i2c) { | ||
725 | vpbe_dev->amp = v4l2_i2c_new_subdev_board( | ||
726 | &vpbe_dev->v4l2_dev, i2c_adap, | ||
727 | &_info->board_info, NULL); | ||
728 | if (!vpbe_dev->amp) { | ||
729 | v4l2_err(&vpbe_dev->v4l2_dev, | ||
730 | "amplifier %s failed to register", | ||
731 | amp_info->module_name); | ||
732 | ret = -ENODEV; | ||
733 | goto vpbe_fail_amp_register; | ||
734 | } | ||
735 | v4l2_info(&vpbe_dev->v4l2_dev, | ||
736 | "v4l2 sub device %s registered\n", | ||
737 | amp_info->module_name); | ||
738 | } else { | ||
739 | vpbe_dev->amp = NULL; | ||
740 | v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers" | ||
741 | " currently not supported"); | ||
742 | } | ||
743 | } else { | ||
744 | vpbe_dev->amp = NULL; | ||
745 | } | ||
707 | 746 | ||
708 | /* set the current encoder and output to that of venc by default */ | 747 | /* set the current encoder and output to that of venc by default */ |
709 | vpbe_dev->current_sd_index = 0; | 748 | vpbe_dev->current_sd_index = 0; |
@@ -731,6 +770,8 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) | |||
731 | /* TBD handling of bootargs for default output and mode */ | 770 | /* TBD handling of bootargs for default output and mode */ |
732 | return 0; | 771 | return 0; |
733 | 772 | ||
773 | vpbe_fail_amp_register: | ||
774 | kfree(vpbe_dev->amp); | ||
734 | vpbe_fail_sd_register: | 775 | vpbe_fail_sd_register: |
735 | kfree(vpbe_dev->encoders); | 776 | kfree(vpbe_dev->encoders); |
736 | vpbe_fail_v4l2_device: | 777 | vpbe_fail_v4l2_device: |
@@ -757,6 +798,7 @@ static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev) | |||
757 | if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) | 798 | if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) |
758 | clk_put(vpbe_dev->dac_clk); | 799 | clk_put(vpbe_dev->dac_clk); |
759 | 800 | ||
801 | kfree(vpbe_dev->amp); | ||
760 | kfree(vpbe_dev->encoders); | 802 | kfree(vpbe_dev->encoders); |
761 | vpbe_dev->initialized = 0; | 803 | vpbe_dev->initialized = 0; |
762 | /* disable vpss clocks */ | 804 | /* disable vpss clocks */ |
@@ -811,8 +853,10 @@ static __devinit int vpbe_probe(struct platform_device *pdev) | |||
811 | 853 | ||
812 | if (cfg->outputs->num_modes > 0) | 854 | if (cfg->outputs->num_modes > 0) |
813 | vpbe_dev->current_timings = vpbe_dev->cfg->outputs[0].modes[0]; | 855 | vpbe_dev->current_timings = vpbe_dev->cfg->outputs[0].modes[0]; |
814 | else | 856 | else { |
857 | kfree(vpbe_dev); | ||
815 | return -ENODEV; | 858 | return -ENODEV; |
859 | } | ||
816 | 860 | ||
817 | /* set the driver data in platform device */ | 861 | /* set the driver data in platform device */ |
818 | platform_set_drvdata(pdev, vpbe_dev); | 862 | platform_set_drvdata(pdev, vpbe_dev); |
@@ -839,26 +883,4 @@ static struct platform_driver vpbe_driver = { | |||
839 | .remove = vpbe_remove, | 883 | .remove = vpbe_remove, |
840 | }; | 884 | }; |
841 | 885 | ||
842 | /** | 886 | module_platform_driver(vpbe_driver); |
843 | * vpbe_init: initialize the vpbe driver | ||
844 | * | ||
845 | * This function registers device and driver to the kernel | ||
846 | */ | ||
847 | static __init int vpbe_init(void) | ||
848 | { | ||
849 | return platform_driver_register(&vpbe_driver); | ||
850 | } | ||
851 | |||
852 | /** | ||
853 | * vpbe_cleanup : cleanup function for vpbe driver | ||
854 | * | ||
855 | * This will un-registers the device and driver to the kernel | ||
856 | */ | ||
857 | static void vpbe_cleanup(void) | ||
858 | { | ||
859 | platform_driver_unregister(&vpbe_driver); | ||
860 | } | ||
861 | |||
862 | /* Function for module initialization and cleanup */ | ||
863 | module_init(vpbe_init); | ||
864 | module_exit(vpbe_cleanup); | ||