diff options
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r-- | drivers/video/omap2/displays/Kconfig | 8 | ||||
-rw-r--r-- | drivers/video/omap2/displays/Makefile | 2 | ||||
-rw-r--r-- | drivers/video/omap2/displays/panel-taal.c | 22 | ||||
-rw-r--r-- | drivers/video/omap2/displays/panel-tfp410.c (renamed from drivers/video/omap2/displays/panel-dvi.c) | 134 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 133 |
5 files changed, 171 insertions, 128 deletions
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index 408a9927be9..c3853c92279 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -10,12 +10,12 @@ config PANEL_GENERIC_DPI Supports LCD Panel used in TI SDP3430 and EVM boards, OMAP3517 EVM boards and CM-T35. -config PANEL_DVI - tristate "DVI output" +config PANEL_TFP410 + tristate "TFP410 DPI-to-DVI chip" depends on OMAP2_DSS_DPI && I2C help - Driver for external monitors, connected via DVI. The driver uses i2c - to read EDID information from the monitor. + Driver for TFP410 DPI-to-DVI chip. The driver uses i2c to read EDID + information from the monitor. config PANEL_LGPHILIPS_LB035Q02 tristate "LG.Philips LB035Q02 LCD Panel" diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile index fbfafc6eebb..58a5176b07b 100644 --- a/drivers/video/omap2/displays/Makefile +++ b/drivers/video/omap2/displays/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o -obj-$(CONFIG_PANEL_DVI) += panel-dvi.o +obj-$(CONFIG_PANEL_TFP410) += panel-tfp410.o obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 0f21fa5a16a..b2dd88b4842 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -993,6 +993,15 @@ static int taal_probe(struct omap_dss_device *dssdev) dev_set_drvdata(&dssdev->dev, td); + if (gpio_is_valid(panel_data->reset_gpio)) { + r = gpio_request_one(panel_data->reset_gpio, GPIOF_OUT_INIT_LOW, + "taal rst"); + if (r) { + dev_err(&dssdev->dev, "failed to request reset gpio\n"); + goto err_rst_gpio; + } + } + taal_hw_reset(dssdev); if (panel_data->use_dsi_backlight) { @@ -1073,6 +1082,9 @@ err_gpio: if (bldev != NULL) backlight_device_unregister(bldev); err_bl: + if (gpio_is_valid(panel_data->reset_gpio)) + gpio_free(panel_data->reset_gpio); +err_rst_gpio: destroy_workqueue(td->workqueue); err_wq: free_regulators(panel_config->regulators, panel_config->num_regulators); @@ -1116,15 +1128,25 @@ static void __exit taal_remove(struct omap_dss_device *dssdev) free_regulators(td->panel_config->regulators, td->panel_config->num_regulators); + if (gpio_is_valid(panel_data->reset_gpio)) + gpio_free(panel_data->reset_gpio); + kfree(td); } static int taal_power_on(struct omap_dss_device *dssdev) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); + struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); u8 id1, id2, id3; int r; + r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config); + if (r) { + dev_err(&dssdev->dev, "failed to configure DSI pins\n"); + goto err0; + }; + r = omapdss_dsi_display_enable(dssdev); if (r) { dev_err(&dssdev->dev, "failed to enable DSI\n"); diff --git a/drivers/video/omap2/displays/panel-dvi.c b/drivers/video/omap2/displays/panel-tfp410.c index 03eb14af33e..52637fa8fda 100644 --- a/drivers/video/omap2/displays/panel-dvi.c +++ b/drivers/video/omap2/displays/panel-tfp410.c @@ -1,5 +1,5 @@ /* - * DVI output support + * TFP410 DPI-to-DVI chip * * Copyright (C) 2011 Texas Instruments Inc * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> @@ -21,11 +21,12 @@ #include <linux/slab.h> #include <video/omapdss.h> #include <linux/i2c.h> +#include <linux/gpio.h> #include <drm/drm_edid.h> -#include <video/omap-panel-dvi.h> +#include <video/omap-panel-tfp410.h> -static const struct omap_video_timings panel_dvi_default_timings = { +static const struct omap_video_timings tfp410_default_timings = { .x_res = 640, .y_res = 480, @@ -44,17 +45,19 @@ struct panel_drv_data { struct omap_dss_device *dssdev; struct mutex lock; + + int pd_gpio; }; -static inline struct panel_dvi_platform_data +static inline struct tfp410_platform_data *get_pdata(const struct omap_dss_device *dssdev) { return dssdev->data; } -static int panel_dvi_power_on(struct omap_dss_device *dssdev) +static int tfp410_power_on(struct omap_dss_device *dssdev) { - struct panel_dvi_platform_data *pdata = get_pdata(dssdev); + struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); int r; if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) @@ -64,57 +67,72 @@ static int panel_dvi_power_on(struct omap_dss_device *dssdev) if (r) goto err0; - if (pdata->platform_enable) { - r = pdata->platform_enable(dssdev); - if (r) - goto err1; - } + if (gpio_is_valid(ddata->pd_gpio)) + gpio_set_value(ddata->pd_gpio, 1); return 0; -err1: - omapdss_dpi_display_disable(dssdev); err0: return r; } -static void panel_dvi_power_off(struct omap_dss_device *dssdev) +static void tfp410_power_off(struct omap_dss_device *dssdev) { - struct panel_dvi_platform_data *pdata = get_pdata(dssdev); + struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) return; - if (pdata->platform_disable) - pdata->platform_disable(dssdev); + if (gpio_is_valid(ddata->pd_gpio)) + gpio_set_value(ddata->pd_gpio, 0); omapdss_dpi_display_disable(dssdev); } -static int panel_dvi_probe(struct omap_dss_device *dssdev) +static int tfp410_probe(struct omap_dss_device *dssdev) { + struct tfp410_platform_data *pdata = get_pdata(dssdev); struct panel_drv_data *ddata; + int r; ddata = kzalloc(sizeof(*ddata), GFP_KERNEL); if (!ddata) return -ENOMEM; - dssdev->panel.timings = panel_dvi_default_timings; + dssdev->panel.timings = tfp410_default_timings; dssdev->panel.config = OMAP_DSS_LCD_TFT; ddata->dssdev = dssdev; mutex_init(&ddata->lock); + if (pdata) + ddata->pd_gpio = pdata->power_down_gpio; + else + ddata->pd_gpio = -1; + + if (gpio_is_valid(ddata->pd_gpio)) { + r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW, + "tfp410 pd"); + if (r) { + dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n", + ddata->pd_gpio); + ddata->pd_gpio = -1; + } + } + dev_set_drvdata(&dssdev->dev, ddata); return 0; } -static void __exit panel_dvi_remove(struct omap_dss_device *dssdev) +static void __exit tfp410_remove(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); mutex_lock(&ddata->lock); + if (gpio_is_valid(ddata->pd_gpio)) + gpio_free(ddata->pd_gpio); + dev_set_drvdata(&dssdev->dev, NULL); mutex_unlock(&ddata->lock); @@ -122,14 +140,14 @@ static void __exit panel_dvi_remove(struct omap_dss_device *dssdev) kfree(ddata); } -static int panel_dvi_enable(struct omap_dss_device *dssdev) +static int tfp410_enable(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); int r; mutex_lock(&ddata->lock); - r = panel_dvi_power_on(dssdev); + r = tfp410_power_on(dssdev); if (r == 0) dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; @@ -138,26 +156,26 @@ static int panel_dvi_enable(struct omap_dss_device *dssdev) return r; } -static void panel_dvi_disable(struct omap_dss_device *dssdev) +static void tfp410_disable(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); mutex_lock(&ddata->lock); - panel_dvi_power_off(dssdev); + tfp410_power_off(dssdev); dssdev->state = OMAP_DSS_DISPLAY_DISABLED; mutex_unlock(&ddata->lock); } -static int panel_dvi_suspend(struct omap_dss_device *dssdev) +static int tfp410_suspend(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); mutex_lock(&ddata->lock); - panel_dvi_power_off(dssdev); + tfp410_power_off(dssdev); dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; @@ -166,14 +184,14 @@ static int panel_dvi_suspend(struct omap_dss_device *dssdev) return 0; } -static int panel_dvi_resume(struct omap_dss_device *dssdev) +static int tfp410_resume(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); int r; mutex_lock(&ddata->lock); - r = panel_dvi_power_on(dssdev); + r = tfp410_power_on(dssdev); if (r == 0) dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; @@ -182,7 +200,7 @@ static int panel_dvi_resume(struct omap_dss_device *dssdev) return r; } -static void panel_dvi_set_timings(struct omap_dss_device *dssdev, +static void tfp410_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); @@ -192,7 +210,7 @@ static void panel_dvi_set_timings(struct omap_dss_device *dssdev, mutex_unlock(&ddata->lock); } -static void panel_dvi_get_timings(struct omap_dss_device *dssdev, +static void tfp410_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); @@ -202,7 +220,7 @@ static void panel_dvi_get_timings(struct omap_dss_device *dssdev, mutex_unlock(&ddata->lock); } -static int panel_dvi_check_timings(struct omap_dss_device *dssdev, +static int tfp410_check_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); @@ -216,7 +234,7 @@ static int panel_dvi_check_timings(struct omap_dss_device *dssdev, } -static int panel_dvi_ddc_read(struct i2c_adapter *adapter, +static int tfp410_ddc_read(struct i2c_adapter *adapter, unsigned char *buf, u16 count, u8 offset) { int r, retries; @@ -247,11 +265,11 @@ static int panel_dvi_ddc_read(struct i2c_adapter *adapter, return r < 0 ? r : -EIO; } -static int panel_dvi_read_edid(struct omap_dss_device *dssdev, +static int tfp410_read_edid(struct omap_dss_device *dssdev, u8 *edid, int len) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); - struct panel_dvi_platform_data *pdata = get_pdata(dssdev); + struct tfp410_platform_data *pdata = get_pdata(dssdev); struct i2c_adapter *adapter; int r, l, bytes_read; @@ -271,7 +289,7 @@ static int panel_dvi_read_edid(struct omap_dss_device *dssdev, } l = min(EDID_LENGTH, len); - r = panel_dvi_ddc_read(adapter, edid, l, 0); + r = tfp410_ddc_read(adapter, edid, l, 0); if (r) goto err; @@ -281,7 +299,7 @@ static int panel_dvi_read_edid(struct omap_dss_device *dssdev, if (len > EDID_LENGTH && edid[0x7e] > 0) { l = min(EDID_LENGTH, len - EDID_LENGTH); - r = panel_dvi_ddc_read(adapter, edid + EDID_LENGTH, + r = tfp410_ddc_read(adapter, edid + EDID_LENGTH, l, EDID_LENGTH); if (r) goto err; @@ -298,10 +316,10 @@ err: return r; } -static bool panel_dvi_detect(struct omap_dss_device *dssdev) +static bool tfp410_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); - struct panel_dvi_platform_data *pdata = get_pdata(dssdev); + struct tfp410_platform_data *pdata = get_pdata(dssdev); struct i2c_adapter *adapter; unsigned char out; int r; @@ -315,7 +333,7 @@ static bool panel_dvi_detect(struct omap_dss_device *dssdev) if (!adapter) goto out; - r = panel_dvi_ddc_read(adapter, &out, 1, 0); + r = tfp410_ddc_read(adapter, &out, 1, 0); mutex_unlock(&ddata->lock); @@ -326,38 +344,38 @@ out: return true; } -static struct omap_dss_driver panel_dvi_driver = { - .probe = panel_dvi_probe, - .remove = __exit_p(panel_dvi_remove), +static struct omap_dss_driver tfp410_driver = { + .probe = tfp410_probe, + .remove = __exit_p(tfp410_remove), - .enable = panel_dvi_enable, - .disable = panel_dvi_disable, - .suspend = panel_dvi_suspend, - .resume = panel_dvi_resume, + .enable = tfp410_enable, + .disable = tfp410_disable, + .suspend = tfp410_suspend, + .resume = tfp410_resume, - .set_timings = panel_dvi_set_timings, - .get_timings = panel_dvi_get_timings, - .check_timings = panel_dvi_check_timings, + .set_timings = tfp410_set_timings, + .get_timings = tfp410_get_timings, + .check_timings = tfp410_check_timings, - .read_edid = panel_dvi_read_edid, - .detect = panel_dvi_detect, + .read_edid = tfp410_read_edid, + .detect = tfp410_detect, .driver = { - .name = "dvi", + .name = "tfp410", .owner = THIS_MODULE, }, }; -static int __init panel_dvi_init(void) +static int __init tfp410_init(void) { - return omap_dss_register_driver(&panel_dvi_driver); + return omap_dss_register_driver(&tfp410_driver); } -static void __exit panel_dvi_exit(void) +static void __exit tfp410_exit(void) { - omap_dss_unregister_driver(&panel_dvi_driver); + omap_dss_unregister_driver(&tfp410_driver); } -module_init(panel_dvi_init); -module_exit(panel_dvi_exit); +module_init(tfp410_init); +module_exit(tfp410_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 662d14f8c2c..210a3c4f615 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2076,65 +2076,6 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev) } } -static int dsi_parse_lane_config(struct omap_dss_device *dssdev) -{ - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); - u8 lanes[DSI_MAX_NR_LANES]; - u8 polarities[DSI_MAX_NR_LANES]; - int num_lanes, i; - - static const enum dsi_lane_function functions[] = { - DSI_LANE_CLK, - DSI_LANE_DATA1, - DSI_LANE_DATA2, - DSI_LANE_DATA3, - DSI_LANE_DATA4, - }; - - lanes[0] = dssdev->phy.dsi.clk_lane; - lanes[1] = dssdev->phy.dsi.data1_lane; - lanes[2] = dssdev->phy.dsi.data2_lane; - lanes[3] = dssdev->phy.dsi.data3_lane; - lanes[4] = dssdev->phy.dsi.data4_lane; - polarities[0] = dssdev->phy.dsi.clk_pol; - polarities[1] = dssdev->phy.dsi.data1_pol; - polarities[2] = dssdev->phy.dsi.data2_pol; - polarities[3] = dssdev->phy.dsi.data3_pol; - polarities[4] = dssdev->phy.dsi.data4_pol; - - num_lanes = 0; - - for (i = 0; i < dsi->num_lanes_supported; ++i) - dsi->lanes[i].function = DSI_LANE_UNUSED; - - for (i = 0; i < dsi->num_lanes_supported; ++i) { - int num; - - if (lanes[i] == DSI_LANE_UNUSED) - break; - - num = lanes[i] - 1; - - if (num >= dsi->num_lanes_supported) - return -EINVAL; - - if (dsi->lanes[num].function != DSI_LANE_UNUSED) - return -EINVAL; - - dsi->lanes[num].function = functions[i]; - dsi->lanes[num].polarity = polarities[i]; - num_lanes++; - } - - if (num_lanes < 2 || num_lanes > dsi->num_lanes_supported) - return -EINVAL; - - dsi->num_lanes_used = num_lanes; - - return 0; -} - static int dsi_set_lane_config(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); @@ -3975,6 +3916,74 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) } } +int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, + const struct omap_dsi_pin_config *pin_cfg) +{ + struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + int num_pins; + const int *pins; + struct dsi_lane_config lanes[DSI_MAX_NR_LANES]; + int num_lanes; + int i; + + static const enum dsi_lane_function functions[] = { + DSI_LANE_CLK, + DSI_LANE_DATA1, + DSI_LANE_DATA2, + DSI_LANE_DATA3, + DSI_LANE_DATA4, + }; + + num_pins = pin_cfg->num_pins; + pins = pin_cfg->pins; + + if (num_pins < 4 || num_pins > dsi->num_lanes_supported * 2 + || num_pins % 2 != 0) + return -EINVAL; + + for (i = 0; i < DSI_MAX_NR_LANES; ++i) + lanes[i].function = DSI_LANE_UNUSED; + + num_lanes = 0; + + for (i = 0; i < num_pins; i += 2) { + u8 lane, pol; + int dx, dy; + + dx = pins[i]; + dy = pins[i + 1]; + + if (dx < 0 || dx >= dsi->num_lanes_supported * 2) + return -EINVAL; + + if (dy < 0 || dy >= dsi->num_lanes_supported * 2) + return -EINVAL; + + if (dx & 1) { + if (dy != dx - 1) + return -EINVAL; + pol = 1; + } else { + if (dy != dx + 1) + return -EINVAL; + pol = 0; + } + + lane = dx / 2; + + lanes[lane].function = functions[i / 2]; + lanes[lane].polarity = pol; + num_lanes++; + } + + memcpy(dsi->lanes, lanes, sizeof(dsi->lanes)); + dsi->num_lanes_used = num_lanes; + + return 0; +} +EXPORT_SYMBOL(omapdss_dsi_configure_pins); + int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); @@ -4339,12 +4348,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) int dsi_module = dsi_get_dsidev_id(dsidev); int r; - r = dsi_parse_lane_config(dssdev); - if (r) { - DSSERR("illegal lane config"); - goto err0; - } - r = dsi_pll_init(dsidev, true, true); if (r) goto err0; |