aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/video/fsl,imx-fb.txt51
-rw-r--r--Documentation/devicetree/bindings/video/ssd1307fb.txt10
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c46
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c27
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h1
-rw-r--r--drivers/video/Kconfig4
-rw-r--r--drivers/video/aty/aty128fb.c2
-rw-r--r--drivers/video/aty/atyfb_base.c9
-rw-r--r--drivers/video/aty/radeon_pm.c2
-rw-r--r--drivers/video/au1100fb.c1
-rw-r--r--drivers/video/bf54x-lq043fb.c1
-rw-r--r--drivers/video/bfin-lq035q1-fb.c24
-rw-r--r--drivers/video/bfin-t350mcqb-fb.c2
-rw-r--r--drivers/video/ep93xx-fb.c2
-rw-r--r--drivers/video/fbmem.c6
-rw-r--r--drivers/video/fsl-diu-fb.c4
-rw-r--r--drivers/video/i740fb.c2
-rw-r--r--drivers/video/imxfb.c201
-rw-r--r--drivers/video/jz4740_fb.c2
-rw-r--r--drivers/video/mmp/fb/mmpfb.c1
-rw-r--r--drivers/video/mmp/hw/mmp_ctrl.c9
-rw-r--r--drivers/video/mxsfb.c3
-rw-r--r--drivers/video/nuc900fb.c1
-rw-r--r--drivers/video/of_display_timing.c55
-rw-r--r--drivers/video/omap2/Kconfig1
-rw-r--r--drivers/video/omap2/Makefile1
-rw-r--r--drivers/video/omap2/displays-new/Kconfig73
-rw-r--r--drivers/video/omap2/displays-new/Makefile12
-rw-r--r--drivers/video/omap2/displays-new/connector-analog-tv.c265
-rw-r--r--drivers/video/omap2/displays-new/connector-dvi.c351
-rw-r--r--drivers/video/omap2/displays-new/connector-hdmi.c375
-rw-r--r--drivers/video/omap2/displays-new/encoder-tfp410.c267
-rw-r--r--drivers/video/omap2/displays-new/encoder-tpd12s015.c395
-rw-r--r--drivers/video/omap2/displays-new/panel-dpi.c270
-rw-r--r--drivers/video/omap2/displays-new/panel-dsi-cm.c1336
-rw-r--r--drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c358
-rw-r--r--drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c394
-rw-r--r--drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c324
-rw-r--r--drivers/video/omap2/displays-new/panel-sony-acx565akm.c865
-rw-r--r--drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c646
-rw-r--r--drivers/video/omap2/displays/Kconfig2
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c16
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c26
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c10
-rw-r--r--drivers/video/omap2/displays/panel-n8x0.c30
-rw-r--r--drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c4
-rw-r--r--drivers/video/omap2/displays/panel-picodlp.c34
-rw-r--r--drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c10
-rw-r--r--drivers/video/omap2/displays/panel-taal.c170
-rw-r--r--drivers/video/omap2/displays/panel-tfp410.c32
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c36
-rw-r--r--drivers/video/omap2/dss/Kconfig1
-rw-r--r--drivers/video/omap2/dss/apply.c59
-rw-r--r--drivers/video/omap2/dss/core.c108
-rw-r--r--drivers/video/omap2/dss/dispc-compat.c3
-rw-r--r--drivers/video/omap2/dss/dispc.c24
-rw-r--r--drivers/video/omap2/dss/display-sysfs.c154
-rw-r--r--drivers/video/omap2/dss/display.c247
-rw-r--r--drivers/video/omap2/dss/dpi.c209
-rw-r--r--drivers/video/omap2/dss/dsi.c232
-rw-r--r--drivers/video/omap2/dss/dss.c3
-rw-r--r--drivers/video/omap2/dss/dss.h35
-rw-r--r--drivers/video/omap2/dss/dss_features.c1
-rw-r--r--drivers/video/omap2/dss/hdmi.c345
-rw-r--r--drivers/video/omap2/dss/manager-sysfs.c47
-rw-r--r--drivers/video/omap2/dss/manager.c29
-rw-r--r--drivers/video/omap2/dss/output.c87
-rw-r--r--drivers/video/omap2/dss/rfbi.c43
-rw-r--r--drivers/video/omap2/dss/sdi.c143
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h5
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c87
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h1
-rw-r--r--drivers/video/omap2/dss/venc.c163
-rw-r--r--drivers/video/omap2/dss/venc_panel.c16
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c9
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c27
-rw-r--r--drivers/video/pxa3xx-gcu.c2
-rw-r--r--drivers/video/pxafb.c1
-rw-r--r--drivers/video/s3c2410fb.c2
-rw-r--r--drivers/video/sa1100fb.c1
-rw-r--r--drivers/video/sh7760fb.c1
-rw-r--r--drivers/video/sh_mipi_dsi.c1
-rw-r--r--drivers/video/smscufx.c2
-rw-r--r--drivers/video/ssd1307fb.c392
-rw-r--r--drivers/video/tmiofb.c3
-rw-r--r--drivers/video/udlfb.c12
-rw-r--r--drivers/video/uvesafb.c4
-rw-r--r--drivers/video/vga16fb.c1
-rw-r--r--drivers/video/vt8500lcdfb.c1
-rw-r--r--drivers/video/wm8505fb.c2
-rw-r--r--drivers/video/xilinxfb.c135
-rw-r--r--include/linux/fb.h2
-rw-r--r--include/video/of_display_timing.h3
-rw-r--r--include/video/omap-panel-data.h209
-rw-r--r--include/video/omapdss.h293
95 files changed, 8700 insertions, 1214 deletions
diff --git a/Documentation/devicetree/bindings/video/fsl,imx-fb.txt b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
new file mode 100644
index 000000000000..46da08db186a
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
@@ -0,0 +1,51 @@
1Freescale imx21 Framebuffer
2
3This framebuffer driver supports devices imx1, imx21, imx25, and imx27.
4
5Required properties:
6- compatible : "fsl,<chip>-fb", chip should be imx1 or imx21
7- reg : Should contain 1 register ranges(address and length)
8- interrupts : One interrupt of the fb dev
9
10Required nodes:
11- display: Phandle to a display node as described in
12 Documentation/devicetree/bindings/video/display-timing.txt
13 Additional, the display node has to define properties:
14 - bits-per-pixel: Bits per pixel
15 - fsl,pcr: LCDC PCR value
16
17Optional properties:
18- fsl,dmacr: DMA Control Register value. This is optional. By default, the
19 register is not modified as recommended by the datasheet.
20- fsl,lscr1: LCDC Sharp Configuration Register value.
21
22Example:
23
24 imxfb: fb@10021000 {
25 compatible = "fsl,imx21-fb";
26 interrupts = <61>;
27 reg = <0x10021000 0x1000>;
28 display = <&display0>;
29 };
30
31 ...
32
33 display0: display0 {
34 model = "Primeview-PD050VL1";
35 native-mode = <&timing_disp0>;
36 bits-per-pixel = <16>;
37 fsl,pcr = <0xf0c88080>; /* non-standard but required */
38 display-timings {
39 timing_disp0: 640x480 {
40 hactive = <640>;
41 vactive = <480>;
42 hback-porch = <112>;
43 hfront-porch = <36>;
44 hsync-len = <32>;
45 vback-porch = <33>;
46 vfront-porch = <33>;
47 vsync-len = <2>;
48 clock-frequency = <25000000>;
49 };
50 };
51 };
diff --git a/Documentation/devicetree/bindings/video/ssd1307fb.txt b/Documentation/devicetree/bindings/video/ssd1307fb.txt
index 3d0060cff062..7a125427ff4b 100644
--- a/Documentation/devicetree/bindings/video/ssd1307fb.txt
+++ b/Documentation/devicetree/bindings/video/ssd1307fb.txt
@@ -1,13 +1,17 @@
1* Solomon SSD1307 Framebuffer Driver 1* Solomon SSD1307 Framebuffer Driver
2 2
3Required properties: 3Required properties:
4 - compatible: Should be "solomon,ssd1307fb-<bus>". The only supported bus for 4 - compatible: Should be "solomon,<chip>fb-<bus>". The only supported bus for
5 now is i2c. 5 now is i2c, and the supported chips are ssd1306 and ssd1307.
6 - reg: Should contain address of the controller on the I2C bus. Most likely 6 - reg: Should contain address of the controller on the I2C bus. Most likely
7 0x3c or 0x3d 7 0x3c or 0x3d
8 - pwm: Should contain the pwm to use according to the OF device tree PWM 8 - pwm: Should contain the pwm to use according to the OF device tree PWM
9 specification [0] 9 specification [0]. Only required for the ssd1307.
10 - reset-gpios: Should contain the GPIO used to reset the OLED display 10 - reset-gpios: Should contain the GPIO used to reset the OLED display
11 - solomon,height: Height in pixel of the screen driven by the controller
12 - solomon,width: Width in pixel of the screen driven by the controller
13 - solomon,page-offset: Offset of pages (band of 8 pixels) that the screen is
14 mapped to.
11 15
12Optional properties: 16Optional properties:
13 - reset-active-low: Is the reset gpio is active on physical low? 17 - reset-active-low: Is the reset gpio is active on physical low?
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 79b200aee18a..4cec678dba94 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -40,7 +40,7 @@ struct omap_crtc {
40 * mgr->id.) Eventually this will be replaced w/ something 40 * mgr->id.) Eventually this will be replaced w/ something
41 * more common-panel-framework-y 41 * more common-panel-framework-y
42 */ 42 */
43 struct omap_overlay_manager mgr; 43 struct omap_overlay_manager *mgr;
44 44
45 struct omap_video_timings timings; 45 struct omap_video_timings timings;
46 bool enabled; 46 bool enabled;
@@ -90,7 +90,32 @@ uint32_t pipe2vbl(struct drm_crtc *crtc)
90 * job of sequencing the setup of the video pipe in the proper order 90 * job of sequencing the setup of the video pipe in the proper order
91 */ 91 */
92 92
93/* ovl-mgr-id -> crtc */
94static struct omap_crtc *omap_crtcs[8];
95
93/* we can probably ignore these until we support command-mode panels: */ 96/* we can probably ignore these until we support command-mode panels: */
97static int omap_crtc_connect(struct omap_overlay_manager *mgr,
98 struct omap_dss_device *dst)
99{
100 if (mgr->output)
101 return -EINVAL;
102
103 if ((mgr->supported_outputs & dst->id) == 0)
104 return -EINVAL;
105
106 dst->manager = mgr;
107 mgr->output = dst;
108
109 return 0;
110}
111
112static void omap_crtc_disconnect(struct omap_overlay_manager *mgr,
113 struct omap_dss_device *dst)
114{
115 mgr->output->manager = NULL;
116 mgr->output = NULL;
117}
118
94static void omap_crtc_start_update(struct omap_overlay_manager *mgr) 119static void omap_crtc_start_update(struct omap_overlay_manager *mgr)
95{ 120{
96} 121}
@@ -107,7 +132,7 @@ static void omap_crtc_disable(struct omap_overlay_manager *mgr)
107static void omap_crtc_set_timings(struct omap_overlay_manager *mgr, 132static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
108 const struct omap_video_timings *timings) 133 const struct omap_video_timings *timings)
109{ 134{
110 struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr); 135 struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
111 DBG("%s", omap_crtc->name); 136 DBG("%s", omap_crtc->name);
112 omap_crtc->timings = *timings; 137 omap_crtc->timings = *timings;
113 omap_crtc->full_update = true; 138 omap_crtc->full_update = true;
@@ -116,7 +141,7 @@ static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
116static void omap_crtc_set_lcd_config(struct omap_overlay_manager *mgr, 141static void omap_crtc_set_lcd_config(struct omap_overlay_manager *mgr,
117 const struct dss_lcd_mgr_config *config) 142 const struct dss_lcd_mgr_config *config)
118{ 143{
119 struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr); 144 struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
120 DBG("%s", omap_crtc->name); 145 DBG("%s", omap_crtc->name);
121 dispc_mgr_set_lcd_config(omap_crtc->channel, config); 146 dispc_mgr_set_lcd_config(omap_crtc->channel, config);
122} 147}
@@ -135,6 +160,8 @@ static void omap_crtc_unregister_framedone_handler(
135} 160}
136 161
137static const struct dss_mgr_ops mgr_ops = { 162static const struct dss_mgr_ops mgr_ops = {
163 .connect = omap_crtc_connect,
164 .disconnect = omap_crtc_disconnect,
138 .start_update = omap_crtc_start_update, 165 .start_update = omap_crtc_start_update,
139 .enable = omap_crtc_enable, 166 .enable = omap_crtc_enable,
140 .disable = omap_crtc_disable, 167 .disable = omap_crtc_disable,
@@ -569,7 +596,7 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
569 } else { 596 } else {
570 if (encoder) { 597 if (encoder) {
571 omap_encoder_set_enabled(encoder, false); 598 omap_encoder_set_enabled(encoder, false);
572 omap_encoder_update(encoder, &omap_crtc->mgr, 599 omap_encoder_update(encoder, omap_crtc->mgr,
573 &omap_crtc->timings); 600 &omap_crtc->timings);
574 omap_encoder_set_enabled(encoder, true); 601 omap_encoder_set_enabled(encoder, true);
575 omap_crtc->full_update = false; 602 omap_crtc->full_update = false;
@@ -595,6 +622,11 @@ static const char *channel_names[] = {
595 [OMAP_DSS_CHANNEL_LCD2] = "lcd2", 622 [OMAP_DSS_CHANNEL_LCD2] = "lcd2",
596}; 623};
597 624
625void omap_crtc_pre_init(void)
626{
627 dss_install_mgr_ops(&mgr_ops);
628}
629
598/* initialize crtc */ 630/* initialize crtc */
599struct drm_crtc *omap_crtc_init(struct drm_device *dev, 631struct drm_crtc *omap_crtc_init(struct drm_device *dev,
600 struct drm_plane *plane, enum omap_channel channel, int id) 632 struct drm_plane *plane, enum omap_channel channel, int id)
@@ -635,9 +667,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
635 omap_irq_register(dev, &omap_crtc->error_irq); 667 omap_irq_register(dev, &omap_crtc->error_irq);
636 668
637 /* temporary: */ 669 /* temporary: */
638 omap_crtc->mgr.id = channel; 670 omap_crtc->mgr = omap_dss_get_overlay_manager(channel);
639
640 dss_install_mgr_ops(&mgr_ops);
641 671
642 /* TODO: fix hard-coded setup.. add properties! */ 672 /* TODO: fix hard-coded setup.. add properties! */
643 info = &omap_crtc->info; 673 info = &omap_crtc->info;
@@ -651,6 +681,8 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
651 681
652 omap_plane_install_properties(omap_crtc->plane, &crtc->base); 682 omap_plane_install_properties(omap_crtc->plane, &crtc->base);
653 683
684 omap_crtcs[channel] = omap_crtc;
685
654 return crtc; 686 return crtc;
655 687
656fail: 688fail:
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 826586ffbe83..a3004f12b9a3 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -65,10 +65,8 @@ static int get_connector_type(struct omap_dss_device *dssdev)
65 switch (dssdev->type) { 65 switch (dssdev->type) {
66 case OMAP_DISPLAY_TYPE_HDMI: 66 case OMAP_DISPLAY_TYPE_HDMI:
67 return DRM_MODE_CONNECTOR_HDMIA; 67 return DRM_MODE_CONNECTOR_HDMIA;
68 case OMAP_DISPLAY_TYPE_DPI: 68 case OMAP_DISPLAY_TYPE_DVI:
69 if (!strcmp(dssdev->name, "dvi")) 69 return DRM_MODE_CONNECTOR_DVID;
70 return DRM_MODE_CONNECTOR_DVID;
71 /* fallthrough */
72 default: 70 default:
73 return DRM_MODE_CONNECTOR_Unknown; 71 return DRM_MODE_CONNECTOR_Unknown;
74 } 72 }
@@ -97,6 +95,9 @@ static int omap_modeset_init(struct drm_device *dev)
97 int num_mgrs = dss_feat_get_num_mgrs(); 95 int num_mgrs = dss_feat_get_num_mgrs();
98 int num_crtcs; 96 int num_crtcs;
99 int i, id = 0; 97 int i, id = 0;
98 int r;
99
100 omap_crtc_pre_init();
100 101
101 drm_mode_config_init(dev); 102 drm_mode_config_init(dev);
102 103
@@ -116,6 +117,7 @@ static int omap_modeset_init(struct drm_device *dev)
116 struct drm_connector *connector; 117 struct drm_connector *connector;
117 struct drm_encoder *encoder; 118 struct drm_encoder *encoder;
118 enum omap_channel channel; 119 enum omap_channel channel;
120 struct omap_overlay_manager *mgr;
119 121
120 if (!dssdev->driver) { 122 if (!dssdev->driver) {
121 dev_warn(dev->dev, "%s has no driver.. skipping it\n", 123 dev_warn(dev->dev, "%s has no driver.. skipping it\n",
@@ -131,6 +133,13 @@ static int omap_modeset_init(struct drm_device *dev)
131 continue; 133 continue;
132 } 134 }
133 135
136 r = dssdev->driver->connect(dssdev);
137 if (r) {
138 dev_err(dev->dev, "could not connect display: %s\n",
139 dssdev->name);
140 continue;
141 }
142
134 encoder = omap_encoder_init(dev, dssdev); 143 encoder = omap_encoder_init(dev, dssdev);
135 144
136 if (!encoder) { 145 if (!encoder) {
@@ -172,8 +181,9 @@ static int omap_modeset_init(struct drm_device *dev)
172 * other possible channels to which the encoder can connect are 181 * other possible channels to which the encoder can connect are
173 * not considered. 182 * not considered.
174 */ 183 */
175 channel = dssdev->output->dispc_channel;
176 184
185 mgr = omapdss_find_mgr_from_display(dssdev);
186 channel = mgr->id;
177 /* 187 /*
178 * if this channel hasn't already been taken by a previously 188 * if this channel hasn't already been taken by a previously
179 * allocated crtc, we create a new crtc for it 189 * allocated crtc, we create a new crtc for it
@@ -247,6 +257,9 @@ static int omap_modeset_init(struct drm_device *dev)
247 struct drm_encoder *encoder = priv->encoders[i]; 257 struct drm_encoder *encoder = priv->encoders[i];
248 struct omap_dss_device *dssdev = 258 struct omap_dss_device *dssdev =
249 omap_encoder_get_dssdev(encoder); 259 omap_encoder_get_dssdev(encoder);
260 struct omap_dss_device *output;
261
262 output = omapdss_find_output_from_display(dssdev);
250 263
251 /* figure out which crtc's we can connect the encoder to: */ 264 /* figure out which crtc's we can connect the encoder to: */
252 encoder->possible_crtcs = 0; 265 encoder->possible_crtcs = 0;
@@ -259,9 +272,11 @@ static int omap_modeset_init(struct drm_device *dev)
259 supported_outputs = 272 supported_outputs =
260 dss_feat_get_supported_outputs(crtc_channel); 273 dss_feat_get_supported_outputs(crtc_channel);
261 274
262 if (supported_outputs & dssdev->output->id) 275 if (supported_outputs & output->id)
263 encoder->possible_crtcs |= (1 << id); 276 encoder->possible_crtcs |= (1 << id);
264 } 277 }
278
279 omap_dss_put_device(output);
265 } 280 }
266 281
267 DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n", 282 DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n",
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 215a20dd340c..14f17da2ce25 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -157,6 +157,7 @@ const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc);
157enum omap_channel omap_crtc_channel(struct drm_crtc *crtc); 157enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
158int omap_crtc_apply(struct drm_crtc *crtc, 158int omap_crtc_apply(struct drm_crtc *crtc,
159 struct omap_drm_apply *apply); 159 struct omap_drm_apply *apply);
160void omap_crtc_pre_init(void);
160struct drm_crtc *omap_crtc_init(struct drm_device *dev, 161struct drm_crtc *omap_crtc_init(struct drm_device *dev,
161 struct drm_plane *plane, enum omap_channel channel, int id); 162 struct drm_plane *plane, enum omap_channel channel, int id);
162 163
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2e937bdace6f..4cf1e1dd5621 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -367,6 +367,8 @@ config FB_IMX
367 select FB_CFB_FILLRECT 367 select FB_CFB_FILLRECT
368 select FB_CFB_COPYAREA 368 select FB_CFB_COPYAREA
369 select FB_CFB_IMAGEBLIT 369 select FB_CFB_IMAGEBLIT
370 select FB_MODE_HELPERS
371 select VIDEOMODE_HELPERS
370 372
371config FB_CYBER2000 373config FB_CYBER2000
372 tristate "CyberPro 2000/2010/5000 support" 374 tristate "CyberPro 2000/2010/5000 support"
@@ -2188,7 +2190,7 @@ config FB_PS3_DEFAULT_SIZE_M
2188 2190
2189config FB_XILINX 2191config FB_XILINX
2190 tristate "Xilinx frame buffer support" 2192 tristate "Xilinx frame buffer support"
2191 depends on FB && (XILINX_VIRTEX || MICROBLAZE) 2193 depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ)
2192 select FB_CFB_FILLRECT 2194 select FB_CFB_FILLRECT
2193 select FB_CFB_COPYAREA 2195 select FB_CFB_COPYAREA
2194 select FB_CFB_IMAGEBLIT 2196 select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 8c55011313dc..a4dfe8cb0a0a 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -2016,7 +2016,7 @@ static int aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)
2016 2016
2017 aty128_init_engine(par); 2017 aty128_init_engine(par);
2018 2018
2019 par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM); 2019 par->pm_reg = pdev->pm_cap;
2020 par->pdev = pdev; 2020 par->pdev = pdev;
2021 par->asleep = 0; 2021 par->asleep = 0;
2022 par->lock_blank = 0; 2022 par->lock_blank = 0;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 4f27fdc58d84..a89c15de9f45 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -58,6 +58,7 @@
58#include <linux/slab.h> 58#include <linux/slab.h>
59#include <linux/vmalloc.h> 59#include <linux/vmalloc.h>
60#include <linux/delay.h> 60#include <linux/delay.h>
61#include <linux/compiler.h>
61#include <linux/console.h> 62#include <linux/console.h>
62#include <linux/fb.h> 63#include <linux/fb.h>
63#include <linux/init.h> 64#include <linux/init.h>
@@ -434,8 +435,8 @@ static int correct_chipset(struct atyfb_par *par)
434 const char *name; 435 const char *name;
435 int i; 436 int i;
436 437
437 for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--) 438 for (i = ARRAY_SIZE(aty_chips); i > 0; i--)
438 if (par->pci_id == aty_chips[i].pci_id) 439 if (par->pci_id == aty_chips[i - 1].pci_id)
439 break; 440 break;
440 441
441 if (i < 0) 442 if (i < 0)
@@ -531,8 +532,8 @@ static int correct_chipset(struct atyfb_par *par)
531 return 0; 532 return 0;
532} 533}
533 534
534static char ram_dram[] = "DRAM"; 535static char ram_dram[] __maybe_unused = "DRAM";
535static char ram_resv[] = "RESV"; 536static char ram_resv[] __maybe_unused = "RESV";
536#ifdef CONFIG_FB_ATY_GX 537#ifdef CONFIG_FB_ATY_GX
537static char ram_vram[] = "VRAM"; 538static char ram_vram[] = "VRAM";
538#endif /* CONFIG_FB_ATY_GX */ 539#endif /* CONFIG_FB_ATY_GX */
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 92bda5848516..f7091ece580d 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -2805,7 +2805,7 @@ static void radeonfb_early_resume(void *data)
2805void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep) 2805void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep)
2806{ 2806{
2807 /* Find PM registers in config space if any*/ 2807 /* Find PM registers in config space if any*/
2808 rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM); 2808 rinfo->pm_reg = rinfo->pdev->pm_cap;
2809 2809
2810 /* Enable/Disable dynamic clocks: TODO add sysfs access */ 2810 /* Enable/Disable dynamic clocks: TODO add sysfs access */
2811 if (rinfo->family == CHIP_FAMILY_RS480) 2811 if (rinfo->family == CHIP_FAMILY_RS480)
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index ebeb9715f061..a54ccdc4d661 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -577,7 +577,6 @@ failed:
577 if (fbdev->info.cmap.len != 0) { 577 if (fbdev->info.cmap.len != 0) {
578 fb_dealloc_cmap(&fbdev->info.cmap); 578 fb_dealloc_cmap(&fbdev->info.cmap);
579 } 579 }
580 platform_set_drvdata(dev, NULL);
581 580
582 return -ENODEV; 581 return -ENODEV;
583} 582}
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index 2726a5b66741..87f288bfc58c 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -681,7 +681,6 @@ out3:
681out2: 681out2:
682 free_dma(CH_EPPI0); 682 free_dma(CH_EPPI0);
683out1: 683out1:
684 platform_set_drvdata(pdev, NULL);
685 684
686 return ret; 685 return ret;
687} 686}
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c
index 29d8c0443a1f..b594a58ff21d 100644
--- a/drivers/video/bfin-lq035q1-fb.c
+++ b/drivers/video/bfin-lq035q1-fb.c
@@ -170,16 +170,19 @@ static int lq035q1_spidev_remove(struct spi_device *spi)
170 return lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_SHUT); 170 return lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_SHUT);
171} 171}
172 172
173#ifdef CONFIG_PM 173#ifdef CONFIG_PM_SLEEP
174static int lq035q1_spidev_suspend(struct spi_device *spi, pm_message_t state) 174static int lq035q1_spidev_suspend(struct device *dev)
175{ 175{
176 struct spi_device *spi = to_spi_device(dev);
177
176 return lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_SHUT); 178 return lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_SHUT);
177} 179}
178 180
179static int lq035q1_spidev_resume(struct spi_device *spi) 181static int lq035q1_spidev_resume(struct device *dev)
180{ 182{
181 int ret; 183 struct spi_device *spi = to_spi_device(dev);
182 struct spi_control *ctl = spi_get_drvdata(spi); 184 struct spi_control *ctl = spi_get_drvdata(spi);
185 int ret;
183 186
184 ret = lq035q1_control(spi, LQ035_DRIVER_OUTPUT_CTL, ctl->mode); 187 ret = lq035q1_control(spi, LQ035_DRIVER_OUTPUT_CTL, ctl->mode);
185 if (ret) 188 if (ret)
@@ -187,9 +190,13 @@ static int lq035q1_spidev_resume(struct spi_device *spi)
187 190
188 return lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_ON); 191 return lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_ON);
189} 192}
193
194static SIMPLE_DEV_PM_OPS(lq035q1_spidev_pm_ops, lq035q1_spidev_suspend,
195 lq035q1_spidev_resume);
196#define LQ035Q1_SPIDEV_PM_OPS (&lq035q1_spidev_pm_ops)
197
190#else 198#else
191# define lq035q1_spidev_suspend NULL 199#define LQ035Q1_SPIDEV_PM_OPS NULL
192# define lq035q1_spidev_resume NULL
193#endif 200#endif
194 201
195/* Power down all displays on reboot, poweroff or halt */ 202/* Power down all displays on reboot, poweroff or halt */
@@ -708,8 +715,7 @@ static int bfin_lq035q1_probe(struct platform_device *pdev)
708 info->spidrv.probe = lq035q1_spidev_probe; 715 info->spidrv.probe = lq035q1_spidev_probe;
709 info->spidrv.remove = lq035q1_spidev_remove; 716 info->spidrv.remove = lq035q1_spidev_remove;
710 info->spidrv.shutdown = lq035q1_spidev_shutdown; 717 info->spidrv.shutdown = lq035q1_spidev_shutdown;
711 info->spidrv.suspend = lq035q1_spidev_suspend; 718 info->spidrv.driver.pm = LQ035Q1_SPIDEV_PM_OPS;
712 info->spidrv.resume = lq035q1_spidev_resume;
713 719
714 ret = spi_register_driver(&info->spidrv); 720 ret = spi_register_driver(&info->spidrv);
715 if (ret < 0) { 721 if (ret < 0) {
@@ -759,7 +765,6 @@ static int bfin_lq035q1_probe(struct platform_device *pdev)
759 out2: 765 out2:
760 free_dma(CH_PPI); 766 free_dma(CH_PPI);
761 out1: 767 out1:
762 platform_set_drvdata(pdev, NULL);
763 768
764 return ret; 769 return ret;
765} 770}
@@ -788,7 +793,6 @@ static int bfin_lq035q1_remove(struct platform_device *pdev)
788 bfin_lq035q1_free_ports(info->disp_info->ppi_mode == 793 bfin_lq035q1_free_ports(info->disp_info->ppi_mode ==
789 USE_RGB565_16_BIT_PPI); 794 USE_RGB565_16_BIT_PPI);
790 795
791 platform_set_drvdata(pdev, NULL);
792 framebuffer_release(fbinfo); 796 framebuffer_release(fbinfo);
793 797
794 dev_info(&pdev->dev, "unregistered LCD driver\n"); 798 dev_info(&pdev->dev, "unregistered LCD driver\n");
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index d46da01c31ae..48c0c4e38a62 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -578,7 +578,6 @@ out3:
578out2: 578out2:
579 free_dma(CH_PPI); 579 free_dma(CH_PPI);
580out1: 580out1:
581 platform_set_drvdata(pdev, NULL);
582 581
583 return ret; 582 return ret;
584} 583}
@@ -608,7 +607,6 @@ static int bfin_t350mcqb_remove(struct platform_device *pdev)
608 607
609 bfin_t350mcqb_request_ports(0); 608 bfin_t350mcqb_request_ports(0);
610 609
611 platform_set_drvdata(pdev, NULL);
612 framebuffer_release(fbinfo); 610 framebuffer_release(fbinfo);
613 611
614 printk(KERN_INFO DRIVER_NAME ": Unregister LCD driver.\n"); 612 printk(KERN_INFO DRIVER_NAME ": Unregister LCD driver.\n");
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c
index ee1ee5401544..28a837dfddd1 100644
--- a/drivers/video/ep93xx-fb.c
+++ b/drivers/video/ep93xx-fb.c
@@ -595,7 +595,6 @@ failed_videomem:
595 fb_dealloc_cmap(&info->cmap); 595 fb_dealloc_cmap(&info->cmap);
596failed_cmap: 596failed_cmap:
597 kfree(info); 597 kfree(info);
598 platform_set_drvdata(pdev, NULL);
599 598
600 return err; 599 return err;
601} 600}
@@ -614,7 +613,6 @@ static int ep93xxfb_remove(struct platform_device *pdev)
614 fbi->mach_info->teardown(pdev); 613 fbi->mach_info->teardown(pdev);
615 614
616 kfree(info); 615 kfree(info);
617 platform_set_drvdata(pdev, NULL);
618 616
619 return 0; 617 return 0;
620} 618}
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 098bfc64cfb9..36e1fe21b9b5 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1305,7 +1305,9 @@ static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
1305 err |= copy_to_user(fix32->reserved, fix->reserved, 1305 err |= copy_to_user(fix32->reserved, fix->reserved,
1306 sizeof(fix->reserved)); 1306 sizeof(fix->reserved));
1307 1307
1308 return err; 1308 if (err)
1309 return -EFAULT;
1310 return 0;
1309} 1311}
1310 1312
1311static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd, 1313static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd,
@@ -1881,7 +1883,7 @@ static int ofonly __read_mostly;
1881 * 1883 *
1882 * NOTE: Needed to maintain backwards compatibility 1884 * NOTE: Needed to maintain backwards compatibility
1883 */ 1885 */
1884int fb_get_options(char *name, char **option) 1886int fb_get_options(const char *name, char **option)
1885{ 1887{
1886 char *opt, *options = NULL; 1888 char *opt, *options = NULL;
1887 int retval = 0; 1889 int retval = 0;
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 6c278056fc60..6dd72250111e 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -469,7 +469,7 @@ static enum fsl_diu_monitor_port fsl_diu_name_to_port(const char *s)
469 unsigned long val; 469 unsigned long val;
470 470
471 if (s) { 471 if (s) {
472 if (!strict_strtoul(s, 10, &val) && (val <= 2)) 472 if (!kstrtoul(s, 10, &val) && (val <= 2))
473 port = (enum fsl_diu_monitor_port) val; 473 port = (enum fsl_diu_monitor_port) val;
474 else if (strncmp(s, "lvds", 4) == 0) 474 else if (strncmp(s, "lvds", 4) == 0)
475 port = FSL_DIU_PORT_LVDS; 475 port = FSL_DIU_PORT_LVDS;
@@ -1853,7 +1853,7 @@ static int __init fsl_diu_setup(char *options)
1853 if (!strncmp(opt, "monitor=", 8)) { 1853 if (!strncmp(opt, "monitor=", 8)) {
1854 monitor_port = fsl_diu_name_to_port(opt + 8); 1854 monitor_port = fsl_diu_name_to_port(opt + 8);
1855 } else if (!strncmp(opt, "bpp=", 4)) { 1855 } else if (!strncmp(opt, "bpp=", 4)) {
1856 if (!strict_strtoul(opt + 4, 10, &val)) 1856 if (!kstrtoul(opt + 4, 10, &val))
1857 default_bpp = val; 1857 default_bpp = val;
1858 } else 1858 } else
1859 fb_mode = opt; 1859 fb_mode = opt;
diff --git a/drivers/video/i740fb.c b/drivers/video/i740fb.c
index cfd0c52e8f73..6c4838818950 100644
--- a/drivers/video/i740fb.c
+++ b/drivers/video/i740fb.c
@@ -1302,7 +1302,7 @@ static int __init i740fb_setup(char *options)
1302} 1302}
1303#endif 1303#endif
1304 1304
1305int __init i740fb_init(void) 1305static int __init i740fb_init(void)
1306{ 1306{
1307#ifndef MODULE 1307#ifndef MODULE
1308 char *option = NULL; 1308 char *option = NULL;
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 0abf2bf20836..38733ac2b698 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -31,6 +31,12 @@
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/math64.h> 33#include <linux/math64.h>
34#include <linux/of.h>
35#include <linux/of_device.h>
36
37#include <video/of_display_timing.h>
38#include <video/of_videomode.h>
39#include <video/videomode.h>
34 40
35#include <linux/platform_data/video-imxfb.h> 41#include <linux/platform_data/video-imxfb.h>
36 42
@@ -112,10 +118,11 @@
112#define LCDISR_EOF (1<<1) 118#define LCDISR_EOF (1<<1)
113#define LCDISR_BOF (1<<0) 119#define LCDISR_BOF (1<<0)
114 120
121#define IMXFB_LSCR1_DEFAULT 0x00120300
122
115/* Used fb-mode. Can be set on kernel command line, therefore file-static. */ 123/* Used fb-mode. Can be set on kernel command line, therefore file-static. */
116static const char *fb_mode; 124static const char *fb_mode;
117 125
118
119/* 126/*
120 * These are the bitfields for each 127 * These are the bitfields for each
121 * display depth that we support. 128 * display depth that we support.
@@ -187,6 +194,19 @@ static struct platform_device_id imxfb_devtype[] = {
187}; 194};
188MODULE_DEVICE_TABLE(platform, imxfb_devtype); 195MODULE_DEVICE_TABLE(platform, imxfb_devtype);
189 196
197static struct of_device_id imxfb_of_dev_id[] = {
198 {
199 .compatible = "fsl,imx1-fb",
200 .data = &imxfb_devtype[IMX1_FB],
201 }, {
202 .compatible = "fsl,imx21-fb",
203 .data = &imxfb_devtype[IMX21_FB],
204 }, {
205 /* sentinel */
206 }
207};
208MODULE_DEVICE_TABLE(of, imxfb_of_dev_id);
209
190static inline int is_imx1_fb(struct imxfb_info *fbi) 210static inline int is_imx1_fb(struct imxfb_info *fbi)
191{ 211{
192 return fbi->devtype == IMX1_FB; 212 return fbi->devtype == IMX1_FB;
@@ -319,6 +339,9 @@ static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi)
319 struct imx_fb_videomode *m; 339 struct imx_fb_videomode *m;
320 int i; 340 int i;
321 341
342 if (!fb_mode)
343 return &fbi->mode[0];
344
322 for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) { 345 for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) {
323 if (!strcmp(m->mode.name, fb_mode)) 346 if (!strcmp(m->mode.name, fb_mode))
324 return m; 347 return m;
@@ -474,6 +497,9 @@ static int imxfb_bl_update_status(struct backlight_device *bl)
474 struct imxfb_info *fbi = bl_get_data(bl); 497 struct imxfb_info *fbi = bl_get_data(bl);
475 int brightness = bl->props.brightness; 498 int brightness = bl->props.brightness;
476 499
500 if (!fbi->pwmr)
501 return 0;
502
477 if (bl->props.power != FB_BLANK_UNBLANK) 503 if (bl->props.power != FB_BLANK_UNBLANK)
478 brightness = 0; 504 brightness = 0;
479 if (bl->props.fb_blank != FB_BLANK_UNBLANK) 505 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
@@ -684,10 +710,14 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
684 710
685 writel(fbi->pcr, fbi->regs + LCDC_PCR); 711 writel(fbi->pcr, fbi->regs + LCDC_PCR);
686#ifndef PWMR_BACKLIGHT_AVAILABLE 712#ifndef PWMR_BACKLIGHT_AVAILABLE
687 writel(fbi->pwmr, fbi->regs + LCDC_PWMR); 713 if (fbi->pwmr)
714 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
688#endif 715#endif
689 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); 716 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
690 writel(fbi->dmacr, fbi->regs + LCDC_DMACR); 717
718 /* dmacr = 0 is no valid value, as we need DMA control marks. */
719 if (fbi->dmacr)
720 writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
691 721
692 return 0; 722 return 0;
693} 723}
@@ -723,13 +753,12 @@ static int imxfb_resume(struct platform_device *dev)
723#define imxfb_resume NULL 753#define imxfb_resume NULL
724#endif 754#endif
725 755
726static int __init imxfb_init_fbinfo(struct platform_device *pdev) 756static int imxfb_init_fbinfo(struct platform_device *pdev)
727{ 757{
728 struct imx_fb_platform_data *pdata = pdev->dev.platform_data; 758 struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
729 struct fb_info *info = dev_get_drvdata(&pdev->dev); 759 struct fb_info *info = dev_get_drvdata(&pdev->dev);
730 struct imxfb_info *fbi = info->par; 760 struct imxfb_info *fbi = info->par;
731 struct imx_fb_videomode *m; 761 struct device_node *np;
732 int i;
733 762
734 pr_debug("%s\n",__func__); 763 pr_debug("%s\n",__func__);
735 764
@@ -760,41 +789,95 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
760 info->fbops = &imxfb_ops; 789 info->fbops = &imxfb_ops;
761 info->flags = FBINFO_FLAG_DEFAULT | 790 info->flags = FBINFO_FLAG_DEFAULT |
762 FBINFO_READS_FAST; 791 FBINFO_READS_FAST;
763 info->var.grayscale = pdata->cmap_greyscale; 792 if (pdata) {
764 fbi->cmap_inverse = pdata->cmap_inverse; 793 info->var.grayscale = pdata->cmap_greyscale;
765 fbi->cmap_static = pdata->cmap_static; 794 fbi->cmap_inverse = pdata->cmap_inverse;
766 fbi->lscr1 = pdata->lscr1; 795 fbi->cmap_static = pdata->cmap_static;
767 fbi->dmacr = pdata->dmacr; 796 fbi->lscr1 = pdata->lscr1;
768 fbi->pwmr = pdata->pwmr; 797 fbi->dmacr = pdata->dmacr;
769 fbi->lcd_power = pdata->lcd_power; 798 fbi->pwmr = pdata->pwmr;
770 fbi->backlight_power = pdata->backlight_power; 799 fbi->lcd_power = pdata->lcd_power;
771 800 fbi->backlight_power = pdata->backlight_power;
772 for (i = 0, m = &pdata->mode[0]; i < pdata->num_modes; i++, m++) 801 } else {
773 info->fix.smem_len = max_t(size_t, info->fix.smem_len, 802 np = pdev->dev.of_node;
774 m->mode.xres * m->mode.yres * m->bpp / 8); 803 info->var.grayscale = of_property_read_bool(np,
804 "cmap-greyscale");
805 fbi->cmap_inverse = of_property_read_bool(np, "cmap-inverse");
806 fbi->cmap_static = of_property_read_bool(np, "cmap-static");
807
808 fbi->lscr1 = IMXFB_LSCR1_DEFAULT;
809 of_property_read_u32(np, "fsl,lscr1", &fbi->lscr1);
810
811 of_property_read_u32(np, "fsl,dmacr", &fbi->dmacr);
812
813 /* These two function pointers could be used by some specific
814 * platforms. */
815 fbi->lcd_power = NULL;
816 fbi->backlight_power = NULL;
817 }
775 818
776 return 0; 819 return 0;
777} 820}
778 821
779static int __init imxfb_probe(struct platform_device *pdev) 822static int imxfb_of_read_mode(struct device *dev, struct device_node *np,
823 struct imx_fb_videomode *imxfb_mode)
824{
825 int ret;
826 struct fb_videomode *of_mode = &imxfb_mode->mode;
827 u32 bpp;
828 u32 pcr;
829
830 ret = of_property_read_string(np, "model", &of_mode->name);
831 if (ret)
832 of_mode->name = NULL;
833
834 ret = of_get_fb_videomode(np, of_mode, OF_USE_NATIVE_MODE);
835 if (ret) {
836 dev_err(dev, "Failed to get videomode from DT\n");
837 return ret;
838 }
839
840 ret = of_property_read_u32(np, "bits-per-pixel", &bpp);
841 ret |= of_property_read_u32(np, "fsl,pcr", &pcr);
842
843 if (ret) {
844 dev_err(dev, "Failed to read bpp and pcr from DT\n");
845 return -EINVAL;
846 }
847
848 if (bpp < 1 || bpp > 255) {
849 dev_err(dev, "Bits per pixel have to be between 1 and 255\n");
850 return -EINVAL;
851 }
852
853 imxfb_mode->bpp = bpp;
854 imxfb_mode->pcr = pcr;
855
856 return 0;
857}
858
859static int imxfb_probe(struct platform_device *pdev)
780{ 860{
781 struct imxfb_info *fbi; 861 struct imxfb_info *fbi;
782 struct fb_info *info; 862 struct fb_info *info;
783 struct imx_fb_platform_data *pdata; 863 struct imx_fb_platform_data *pdata;
784 struct resource *res; 864 struct resource *res;
865 struct imx_fb_videomode *m;
866 const struct of_device_id *of_id;
785 int ret, i; 867 int ret, i;
868 int bytes_per_pixel;
786 869
787 dev_info(&pdev->dev, "i.MX Framebuffer driver\n"); 870 dev_info(&pdev->dev, "i.MX Framebuffer driver\n");
788 871
872 of_id = of_match_device(imxfb_of_dev_id, &pdev->dev);
873 if (of_id)
874 pdev->id_entry = of_id->data;
875
789 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 876 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
790 if (!res) 877 if (!res)
791 return -ENODEV; 878 return -ENODEV;
792 879
793 pdata = pdev->dev.platform_data; 880 pdata = pdev->dev.platform_data;
794 if (!pdata) {
795 dev_err(&pdev->dev,"No platform_data available\n");
796 return -ENOMEM;
797 }
798 881
799 info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev); 882 info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
800 if (!info) 883 if (!info)
@@ -802,15 +885,55 @@ static int __init imxfb_probe(struct platform_device *pdev)
802 885
803 fbi = info->par; 886 fbi = info->par;
804 887
805 if (!fb_mode)
806 fb_mode = pdata->mode[0].mode.name;
807
808 platform_set_drvdata(pdev, info); 888 platform_set_drvdata(pdev, info);
809 889
810 ret = imxfb_init_fbinfo(pdev); 890 ret = imxfb_init_fbinfo(pdev);
811 if (ret < 0) 891 if (ret < 0)
812 goto failed_init; 892 goto failed_init;
813 893
894 if (pdata) {
895 if (!fb_mode)
896 fb_mode = pdata->mode[0].mode.name;
897
898 fbi->mode = pdata->mode;
899 fbi->num_modes = pdata->num_modes;
900 } else {
901 struct device_node *display_np;
902 fb_mode = NULL;
903
904 display_np = of_parse_phandle(pdev->dev.of_node, "display", 0);
905 if (!display_np) {
906 dev_err(&pdev->dev, "No display defined in devicetree\n");
907 ret = -EINVAL;
908 goto failed_of_parse;
909 }
910
911 /*
912 * imxfb does not support more modes, we choose only the native
913 * mode.
914 */
915 fbi->num_modes = 1;
916
917 fbi->mode = devm_kzalloc(&pdev->dev,
918 sizeof(struct imx_fb_videomode), GFP_KERNEL);
919 if (!fbi->mode) {
920 ret = -ENOMEM;
921 goto failed_of_parse;
922 }
923
924 ret = imxfb_of_read_mode(&pdev->dev, display_np, fbi->mode);
925 if (ret)
926 goto failed_of_parse;
927 }
928
929 /* Calculate maximum bytes used per pixel. In most cases this should
930 * be the same as m->bpp/8 */
931 m = &fbi->mode[0];
932 bytes_per_pixel = (m->bpp + 7) / 8;
933 for (i = 0; i < fbi->num_modes; i++, m++)
934 info->fix.smem_len = max_t(size_t, info->fix.smem_len,
935 m->mode.xres * m->mode.yres * bytes_per_pixel);
936
814 res = request_mem_region(res->start, resource_size(res), 937 res = request_mem_region(res->start, resource_size(res),
815 DRIVER_NAME); 938 DRIVER_NAME);
816 if (!res) { 939 if (!res) {
@@ -843,7 +966,8 @@ static int __init imxfb_probe(struct platform_device *pdev)
843 goto failed_ioremap; 966 goto failed_ioremap;
844 } 967 }
845 968
846 if (!pdata->fixed_screen_cpu) { 969 /* Seems not being used by anyone, so no support for oftree */
970 if (!pdata || !pdata->fixed_screen_cpu) {
847 fbi->map_size = PAGE_ALIGN(info->fix.smem_len); 971 fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
848 fbi->map_cpu = dma_alloc_writecombine(&pdev->dev, 972 fbi->map_cpu = dma_alloc_writecombine(&pdev->dev,
849 fbi->map_size, &fbi->map_dma, GFP_KERNEL); 973 fbi->map_size, &fbi->map_dma, GFP_KERNEL);
@@ -868,18 +992,16 @@ static int __init imxfb_probe(struct platform_device *pdev)
868 info->fix.smem_start = fbi->screen_dma; 992 info->fix.smem_start = fbi->screen_dma;
869 } 993 }
870 994
871 if (pdata->init) { 995 if (pdata && pdata->init) {
872 ret = pdata->init(fbi->pdev); 996 ret = pdata->init(fbi->pdev);
873 if (ret) 997 if (ret)
874 goto failed_platform_init; 998 goto failed_platform_init;
875 } 999 }
876 1000
877 fbi->mode = pdata->mode;
878 fbi->num_modes = pdata->num_modes;
879 1001
880 INIT_LIST_HEAD(&info->modelist); 1002 INIT_LIST_HEAD(&info->modelist);
881 for (i = 0; i < pdata->num_modes; i++) 1003 for (i = 0; i < fbi->num_modes; i++)
882 fb_add_videomode(&pdata->mode[i].mode, &info->modelist); 1004 fb_add_videomode(&fbi->mode[i].mode, &info->modelist);
883 1005
884 /* 1006 /*
885 * This makes sure that our colour bitfield 1007 * This makes sure that our colour bitfield
@@ -909,10 +1031,10 @@ static int __init imxfb_probe(struct platform_device *pdev)
909failed_register: 1031failed_register:
910 fb_dealloc_cmap(&info->cmap); 1032 fb_dealloc_cmap(&info->cmap);
911failed_cmap: 1033failed_cmap:
912 if (pdata->exit) 1034 if (pdata && pdata->exit)
913 pdata->exit(fbi->pdev); 1035 pdata->exit(fbi->pdev);
914failed_platform_init: 1036failed_platform_init:
915 if (!pdata->fixed_screen_cpu) 1037 if (pdata && !pdata->fixed_screen_cpu)
916 dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu, 1038 dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
917 fbi->map_dma); 1039 fbi->map_dma);
918failed_map: 1040failed_map:
@@ -921,9 +1043,9 @@ failed_ioremap:
921failed_getclock: 1043failed_getclock:
922 release_mem_region(res->start, resource_size(res)); 1044 release_mem_region(res->start, resource_size(res));
923failed_req: 1045failed_req:
1046failed_of_parse:
924 kfree(info->pseudo_palette); 1047 kfree(info->pseudo_palette);
925failed_init: 1048failed_init:
926 platform_set_drvdata(pdev, NULL);
927 framebuffer_release(info); 1049 framebuffer_release(info);
928 return ret; 1050 return ret;
929} 1051}
@@ -945,7 +1067,7 @@ static int imxfb_remove(struct platform_device *pdev)
945 unregister_framebuffer(info); 1067 unregister_framebuffer(info);
946 1068
947 pdata = pdev->dev.platform_data; 1069 pdata = pdev->dev.platform_data;
948 if (pdata->exit) 1070 if (pdata && pdata->exit)
949 pdata->exit(fbi->pdev); 1071 pdata->exit(fbi->pdev);
950 1072
951 fb_dealloc_cmap(&info->cmap); 1073 fb_dealloc_cmap(&info->cmap);
@@ -955,12 +1077,10 @@ static int imxfb_remove(struct platform_device *pdev)
955 iounmap(fbi->regs); 1077 iounmap(fbi->regs);
956 release_mem_region(res->start, resource_size(res)); 1078 release_mem_region(res->start, resource_size(res));
957 1079
958 platform_set_drvdata(pdev, NULL);
959
960 return 0; 1080 return 0;
961} 1081}
962 1082
963void imxfb_shutdown(struct platform_device * dev) 1083static void imxfb_shutdown(struct platform_device *dev)
964{ 1084{
965 struct fb_info *info = platform_get_drvdata(dev); 1085 struct fb_info *info = platform_get_drvdata(dev);
966 struct imxfb_info *fbi = info->par; 1086 struct imxfb_info *fbi = info->par;
@@ -974,6 +1094,7 @@ static struct platform_driver imxfb_driver = {
974 .shutdown = imxfb_shutdown, 1094 .shutdown = imxfb_shutdown,
975 .driver = { 1095 .driver = {
976 .name = DRIVER_NAME, 1096 .name = DRIVER_NAME,
1097 .of_match_table = imxfb_of_dev_id,
977 }, 1098 },
978 .id_table = imxfb_devtype, 1099 .id_table = imxfb_devtype,
979}; 1100};
@@ -999,7 +1120,7 @@ static int imxfb_setup(void)
999 return 0; 1120 return 0;
1000} 1121}
1001 1122
1002int __init imxfb_init(void) 1123static int __init imxfb_init(void)
1003{ 1124{
1004 int ret = imxfb_setup(); 1125 int ret = imxfb_setup();
1005 1126
diff --git a/drivers/video/jz4740_fb.c b/drivers/video/jz4740_fb.c
index 36979b4131ab..2c49112fdd6c 100644
--- a/drivers/video/jz4740_fb.c
+++ b/drivers/video/jz4740_fb.c
@@ -737,8 +737,6 @@ static int jzfb_remove(struct platform_device *pdev)
737 fb_dealloc_cmap(&jzfb->fb->cmap); 737 fb_dealloc_cmap(&jzfb->fb->cmap);
738 jzfb_free_devmem(jzfb); 738 jzfb_free_devmem(jzfb);
739 739
740 platform_set_drvdata(pdev, NULL);
741
742 framebuffer_release(jzfb->fb); 740 framebuffer_release(jzfb->fb);
743 741
744 return 0; 742 return 0;
diff --git a/drivers/video/mmp/fb/mmpfb.c b/drivers/video/mmp/fb/mmpfb.c
index 6d1fa96c5cc3..4ab95b8daed3 100644
--- a/drivers/video/mmp/fb/mmpfb.c
+++ b/drivers/video/mmp/fb/mmpfb.c
@@ -659,7 +659,6 @@ failed_destroy_mutex:
659 mutex_destroy(&fbi->access_ok); 659 mutex_destroy(&fbi->access_ok);
660failed: 660failed:
661 dev_err(fbi->dev, "mmp-fb: frame buffer device init failed\n"); 661 dev_err(fbi->dev, "mmp-fb: frame buffer device init failed\n");
662 platform_set_drvdata(pdev, NULL);
663 662
664 framebuffer_release(info); 663 framebuffer_release(info);
665 664
diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/mmp/hw/mmp_ctrl.c
index 4bd31b2af398..75dca19bf214 100644
--- a/drivers/video/mmp/hw/mmp_ctrl.c
+++ b/drivers/video/mmp/hw/mmp_ctrl.c
@@ -165,9 +165,9 @@ static void overlay_set_win(struct mmp_overlay *overlay, struct mmp_win *win)
165 165
166static void dmafetch_onoff(struct mmp_overlay *overlay, int on) 166static void dmafetch_onoff(struct mmp_overlay *overlay, int on)
167{ 167{
168 u32 mask = overlay_is_vid(overlay) ? CFG_GRA_ENA_MASK : 168 u32 mask = overlay_is_vid(overlay) ? CFG_DMA_ENA_MASK :
169 CFG_DMA_ENA_MASK; 169 CFG_GRA_ENA_MASK;
170 u32 enable = overlay_is_vid(overlay) ? CFG_GRA_ENA(1) : CFG_DMA_ENA(1); 170 u32 enable = overlay_is_vid(overlay) ? CFG_DMA_ENA(1) : CFG_GRA_ENA(1);
171 u32 tmp; 171 u32 tmp;
172 struct mmp_path *path = overlay->path; 172 struct mmp_path *path = overlay->path;
173 173
@@ -238,7 +238,7 @@ static int overlay_set_addr(struct mmp_overlay *overlay, struct mmp_addr *addr)
238 struct lcd_regs *regs = path_regs(overlay->path); 238 struct lcd_regs *regs = path_regs(overlay->path);
239 239
240 /* FIXME: assert addr supported */ 240 /* FIXME: assert addr supported */
241 memcpy(&overlay->addr, addr, sizeof(struct mmp_win)); 241 memcpy(&overlay->addr, addr, sizeof(struct mmp_addr));
242 writel(addr->phys[0], &regs->g_0); 242 writel(addr->phys[0], &regs->g_0);
243 243
244 return overlay->addr.phys[0]; 244 return overlay->addr.phys[0];
@@ -566,7 +566,6 @@ failed:
566 devm_kfree(ctrl->dev, ctrl); 566 devm_kfree(ctrl->dev, ctrl);
567 } 567 }
568 568
569 platform_set_drvdata(pdev, NULL);
570 dev_err(&pdev->dev, "device init failed\n"); 569 dev_err(&pdev->dev, "device init failed\n");
571 570
572 return ret; 571 return ret;
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 21223d475b39..3ba37713b1f9 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -899,7 +899,6 @@ static int mxsfb_probe(struct platform_device *pdev)
899 899
900 host->base = devm_ioremap_resource(&pdev->dev, res); 900 host->base = devm_ioremap_resource(&pdev->dev, res);
901 if (IS_ERR(host->base)) { 901 if (IS_ERR(host->base)) {
902 dev_err(&pdev->dev, "ioremap failed\n");
903 ret = PTR_ERR(host->base); 902 ret = PTR_ERR(host->base);
904 goto fb_release; 903 goto fb_release;
905 } 904 }
@@ -986,8 +985,6 @@ static int mxsfb_remove(struct platform_device *pdev)
986 985
987 framebuffer_release(fb_info); 986 framebuffer_release(fb_info);
988 987
989 platform_set_drvdata(pdev, NULL);
990
991 return 0; 988 return 0;
992} 989}
993 990
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c
index 32581c72ad09..8c527e5b293c 100644
--- a/drivers/video/nuc900fb.c
+++ b/drivers/video/nuc900fb.c
@@ -707,7 +707,6 @@ static int nuc900fb_remove(struct platform_device *pdev)
707 release_resource(fbi->mem); 707 release_resource(fbi->mem);
708 kfree(fbi->mem); 708 kfree(fbi->mem);
709 709
710 platform_set_drvdata(pdev, NULL);
711 framebuffer_release(fbinfo); 710 framebuffer_release(fbinfo);
712 711
713 return 0; 712 return 0;
diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c
index 56009bc02b02..9c0f17b2e6fb 100644
--- a/drivers/video/of_display_timing.c
+++ b/drivers/video/of_display_timing.c
@@ -53,21 +53,16 @@ static int parse_timing_property(struct device_node *np, const char *name,
53} 53}
54 54
55/** 55/**
56 * of_get_display_timing - parse display_timing entry from device_node 56 * of_parse_display_timing - parse display_timing entry from device_node
57 * @np: device_node with the properties 57 * @np: device_node with the properties
58 **/ 58 **/
59static struct display_timing *of_get_display_timing(struct device_node *np) 59static int of_parse_display_timing(struct device_node *np,
60 struct display_timing *dt)
60{ 61{
61 struct display_timing *dt;
62 u32 val = 0; 62 u32 val = 0;
63 int ret = 0; 63 int ret = 0;
64 64
65 dt = kzalloc(sizeof(*dt), GFP_KERNEL); 65 memset(dt, 0, sizeof(*dt));
66 if (!dt) {
67 pr_err("%s: could not allocate display_timing struct\n",
68 of_node_full_name(np));
69 return NULL;
70 }
71 66
72 ret |= parse_timing_property(np, "hback-porch", &dt->hback_porch); 67 ret |= parse_timing_property(np, "hback-porch", &dt->hback_porch);
73 ret |= parse_timing_property(np, "hfront-porch", &dt->hfront_porch); 68 ret |= parse_timing_property(np, "hfront-porch", &dt->hfront_porch);
@@ -101,12 +96,38 @@ static struct display_timing *of_get_display_timing(struct device_node *np)
101 if (ret) { 96 if (ret) {
102 pr_err("%s: error reading timing properties\n", 97 pr_err("%s: error reading timing properties\n",
103 of_node_full_name(np)); 98 of_node_full_name(np));
104 kfree(dt); 99 return -EINVAL;
105 return NULL; 100 }
101
102 return 0;
103}
104
105/**
106 * of_get_display_timing - parse a display_timing entry
107 * @np: device_node with the timing subnode
108 * @name: name of the timing node
109 * @dt: display_timing struct to fill
110 **/
111int of_get_display_timing(struct device_node *np, const char *name,
112 struct display_timing *dt)
113{
114 struct device_node *timing_np;
115
116 if (!np) {
117 pr_err("%s: no devicenode given\n", of_node_full_name(np));
118 return -EINVAL;
106 } 119 }
107 120
108 return dt; 121 timing_np = of_find_node_by_name(np, name);
122 if (!timing_np) {
123 pr_err("%s: could not find node '%s'\n",
124 of_node_full_name(np), name);
125 return -ENOENT;
126 }
127
128 return of_parse_display_timing(timing_np, dt);
109} 129}
130EXPORT_SYMBOL_GPL(of_get_display_timing);
110 131
111/** 132/**
112 * of_get_display_timings - parse all display_timing entries from a device_node 133 * of_get_display_timings - parse all display_timing entries from a device_node
@@ -174,9 +195,17 @@ struct display_timings *of_get_display_timings(struct device_node *np)
174 195
175 for_each_child_of_node(timings_np, entry) { 196 for_each_child_of_node(timings_np, entry) {
176 struct display_timing *dt; 197 struct display_timing *dt;
198 int r;
177 199
178 dt = of_get_display_timing(entry); 200 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
179 if (!dt) { 201 if (!dt) {
202 pr_err("%s: could not allocate display_timing struct\n",
203 of_node_full_name(np));
204 goto timingfail;
205 }
206
207 r = of_parse_display_timing(entry, dt);
208 if (r) {
180 /* 209 /*
181 * to not encourage wrong devicetrees, fail in case of 210 * to not encourage wrong devicetrees, fail in case of
182 * an error 211 * an error
diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig
index b07b2b042e7e..56cad0f5386c 100644
--- a/drivers/video/omap2/Kconfig
+++ b/drivers/video/omap2/Kconfig
@@ -6,5 +6,6 @@ if ARCH_OMAP2PLUS
6source "drivers/video/omap2/dss/Kconfig" 6source "drivers/video/omap2/dss/Kconfig"
7source "drivers/video/omap2/omapfb/Kconfig" 7source "drivers/video/omap2/omapfb/Kconfig"
8source "drivers/video/omap2/displays/Kconfig" 8source "drivers/video/omap2/displays/Kconfig"
9source "drivers/video/omap2/displays-new/Kconfig"
9 10
10endif 11endif
diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile
index 296e5c5281c5..86873c2fbb27 100644
--- a/drivers/video/omap2/Makefile
+++ b/drivers/video/omap2/Makefile
@@ -2,4 +2,5 @@ obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
2 2
3obj-$(CONFIG_OMAP2_DSS) += dss/ 3obj-$(CONFIG_OMAP2_DSS) += dss/
4obj-y += displays/ 4obj-y += displays/
5obj-y += displays-new/
5obj-$(CONFIG_FB_OMAP2) += omapfb/ 6obj-$(CONFIG_FB_OMAP2) += omapfb/
diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig
new file mode 100644
index 000000000000..6c90885b0940
--- /dev/null
+++ b/drivers/video/omap2/displays-new/Kconfig
@@ -0,0 +1,73 @@
1menu "OMAP Display Device Drivers (new device model)"
2 depends on OMAP2_DSS
3
4config DISPLAY_ENCODER_TFP410
5 tristate "TFP410 DPI to DVI Encoder"
6 help
7 Driver for TFP410 DPI to DVI encoder.
8
9config DISPLAY_ENCODER_TPD12S015
10 tristate "TPD12S015 HDMI ESD protection and level shifter"
11 help
12 Driver for TPD12S015, which offers HDMI ESD protection and level
13 shifting.
14
15config DISPLAY_CONNECTOR_DVI
16 tristate "DVI Connector"
17 depends on I2C
18 help
19 Driver for a generic DVI connector.
20
21config DISPLAY_CONNECTOR_HDMI
22 tristate "HDMI Connector"
23 help
24 Driver for a generic HDMI connector.
25
26config DISPLAY_CONNECTOR_ANALOG_TV
27 tristate "Analog TV Connector"
28 help
29 Driver for a generic analog TV connector.
30
31config DISPLAY_PANEL_DPI
32 tristate "Generic DPI panel"
33 help
34 Driver for generic DPI panels.
35
36config DISPLAY_PANEL_DSI_CM
37 tristate "Generic DSI Command Mode Panel"
38 help
39 Driver for generic DSI command mode panels.
40
41config DISPLAY_PANEL_SONY_ACX565AKM
42 tristate "ACX565AKM Panel"
43 depends on SPI && BACKLIGHT_CLASS_DEVICE
44 help
45 This is the LCD panel used on Nokia N900
46
47config DISPLAY_PANEL_LGPHILIPS_LB035Q02
48 tristate "LG.Philips LB035Q02 LCD Panel"
49 depends on SPI
50 help
51 LCD Panel used on the Gumstix Overo Palo35
52
53config DISPLAY_PANEL_SHARP_LS037V7DW01
54 tristate "Sharp LS037V7DW01 LCD Panel"
55 depends on BACKLIGHT_CLASS_DEVICE
56 help
57 LCD Panel used in TI's SDP3430 and EVM boards
58
59config DISPLAY_PANEL_TPO_TD043MTEA1
60 tristate "TPO TD043MTEA1 LCD Panel"
61 depends on SPI
62 help
63 LCD Panel used in OMAP3 Pandora
64
65config DISPLAY_PANEL_NEC_NL8048HL11
66 tristate "NEC NL8048HL11 Panel"
67 depends on SPI
68 depends on BACKLIGHT_CLASS_DEVICE
69 help
70 This NEC NL8048HL11 panel is TFT LCD used in the
71 Zoom2/3/3630 sdp boards.
72
73endmenu
diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/omap2/displays-new/Makefile
new file mode 100644
index 000000000000..5aeb11b8fcd5
--- /dev/null
+++ b/drivers/video/omap2/displays-new/Makefile
@@ -0,0 +1,12 @@
1obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o
2obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o
3obj-$(CONFIG_DISPLAY_CONNECTOR_DVI) += connector-dvi.o
4obj-$(CONFIG_DISPLAY_CONNECTOR_HDMI) += connector-hdmi.o
5obj-$(CONFIG_DISPLAY_CONNECTOR_ANALOG_TV) += connector-analog-tv.o
6obj-$(CONFIG_DISPLAY_PANEL_DPI) += panel-dpi.o
7obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o
8obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
9obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
10obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
11obj-$(CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
12obj-$(CONFIG_DISPLAY_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
diff --git a/drivers/video/omap2/displays-new/connector-analog-tv.c b/drivers/video/omap2/displays-new/connector-analog-tv.c
new file mode 100644
index 000000000000..5338f362293b
--- /dev/null
+++ b/drivers/video/omap2/displays-new/connector-analog-tv.c
@@ -0,0 +1,265 @@
1/*
2 * Analog TV Connector driver
3 *
4 * Copyright (C) 2013 Texas Instruments
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12#include <linux/slab.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15
16#include <video/omapdss.h>
17#include <video/omap-panel-data.h>
18
19struct panel_drv_data {
20 struct omap_dss_device dssdev;
21 struct omap_dss_device *in;
22
23 struct device *dev;
24
25 struct omap_video_timings timings;
26
27 enum omap_dss_venc_type connector_type;
28 bool invert_polarity;
29};
30
31#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
32
33static int tvc_connect(struct omap_dss_device *dssdev)
34{
35 struct panel_drv_data *ddata = to_panel_data(dssdev);
36 struct omap_dss_device *in = ddata->in;
37 int r;
38
39 dev_dbg(ddata->dev, "connect\n");
40
41 if (omapdss_device_is_connected(dssdev))
42 return 0;
43
44 r = in->ops.atv->connect(in, dssdev);
45 if (r)
46 return r;
47
48 return 0;
49}
50
51static void tvc_disconnect(struct omap_dss_device *dssdev)
52{
53 struct panel_drv_data *ddata = to_panel_data(dssdev);
54 struct omap_dss_device *in = ddata->in;
55
56 dev_dbg(ddata->dev, "disconnect\n");
57
58 if (!omapdss_device_is_connected(dssdev))
59 return;
60
61 in->ops.atv->disconnect(in, dssdev);
62}
63
64static int tvc_enable(struct omap_dss_device *dssdev)
65{
66 struct panel_drv_data *ddata = to_panel_data(dssdev);
67 struct omap_dss_device *in = ddata->in;
68 int r;
69
70 dev_dbg(ddata->dev, "enable\n");
71
72 if (!omapdss_device_is_connected(dssdev))
73 return -ENODEV;
74
75 if (omapdss_device_is_enabled(dssdev))
76 return 0;
77
78 in->ops.atv->set_timings(in, &ddata->timings);
79
80 in->ops.atv->set_type(in, ddata->connector_type);
81 in->ops.atv->invert_vid_out_polarity(in, ddata->invert_polarity);
82
83 r = in->ops.atv->enable(in);
84 if (r)
85 return r;
86
87 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
88
89 return r;
90}
91
92static void tvc_disable(struct omap_dss_device *dssdev)
93{
94 struct panel_drv_data *ddata = to_panel_data(dssdev);
95 struct omap_dss_device *in = ddata->in;
96
97 dev_dbg(ddata->dev, "disable\n");
98
99 if (!omapdss_device_is_enabled(dssdev))
100 return;
101
102 in->ops.atv->disable(in);
103
104 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
105}
106
107static void tvc_set_timings(struct omap_dss_device *dssdev,
108 struct omap_video_timings *timings)
109{
110 struct panel_drv_data *ddata = to_panel_data(dssdev);
111 struct omap_dss_device *in = ddata->in;
112
113 ddata->timings = *timings;
114 dssdev->panel.timings = *timings;
115
116 in->ops.atv->set_timings(in, timings);
117}
118
119static void tvc_get_timings(struct omap_dss_device *dssdev,
120 struct omap_video_timings *timings)
121{
122 struct panel_drv_data *ddata = to_panel_data(dssdev);
123
124 *timings = ddata->timings;
125}
126
127static int tvc_check_timings(struct omap_dss_device *dssdev,
128 struct omap_video_timings *timings)
129{
130 struct panel_drv_data *ddata = to_panel_data(dssdev);
131 struct omap_dss_device *in = ddata->in;
132
133 return in->ops.atv->check_timings(in, timings);
134}
135
136static u32 tvc_get_wss(struct omap_dss_device *dssdev)
137{
138 struct panel_drv_data *ddata = to_panel_data(dssdev);
139 struct omap_dss_device *in = ddata->in;
140
141 return in->ops.atv->get_wss(in);
142}
143
144static int tvc_set_wss(struct omap_dss_device *dssdev, u32 wss)
145{
146 struct panel_drv_data *ddata = to_panel_data(dssdev);
147 struct omap_dss_device *in = ddata->in;
148
149 return in->ops.atv->set_wss(in, wss);
150}
151
152static struct omap_dss_driver tvc_driver = {
153 .connect = tvc_connect,
154 .disconnect = tvc_disconnect,
155
156 .enable = tvc_enable,
157 .disable = tvc_disable,
158
159 .set_timings = tvc_set_timings,
160 .get_timings = tvc_get_timings,
161 .check_timings = tvc_check_timings,
162
163 .get_resolution = omapdss_default_get_resolution,
164
165 .get_wss = tvc_get_wss,
166 .set_wss = tvc_set_wss,
167};
168
169static int tvc_probe_pdata(struct platform_device *pdev)
170{
171 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
172 struct connector_atv_platform_data *pdata;
173 struct omap_dss_device *in, *dssdev;
174
175 pdata = dev_get_platdata(&pdev->dev);
176
177 in = omap_dss_find_output(pdata->source);
178 if (in == NULL) {
179 dev_err(&pdev->dev, "Failed to find video source\n");
180 return -ENODEV;
181 }
182
183 ddata->in = in;
184
185 ddata->connector_type = pdata->connector_type;
186 ddata->invert_polarity = ddata->invert_polarity;
187
188 dssdev = &ddata->dssdev;
189 dssdev->name = pdata->name;
190
191 return 0;
192}
193
194static int tvc_probe(struct platform_device *pdev)
195{
196 struct panel_drv_data *ddata;
197 struct omap_dss_device *dssdev;
198 int r;
199
200 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
201 if (!ddata)
202 return -ENOMEM;
203
204 platform_set_drvdata(pdev, ddata);
205 ddata->dev = &pdev->dev;
206
207 if (dev_get_platdata(&pdev->dev)) {
208 r = tvc_probe_pdata(pdev);
209 if (r)
210 return r;
211 } else {
212 return -ENODEV;
213 }
214
215 ddata->timings = omap_dss_pal_timings;
216
217 dssdev = &ddata->dssdev;
218 dssdev->driver = &tvc_driver;
219 dssdev->dev = &pdev->dev;
220 dssdev->type = OMAP_DISPLAY_TYPE_VENC;
221 dssdev->owner = THIS_MODULE;
222 dssdev->panel.timings = omap_dss_pal_timings;
223
224 r = omapdss_register_display(dssdev);
225 if (r) {
226 dev_err(&pdev->dev, "Failed to register panel\n");
227 goto err_reg;
228 }
229
230 return 0;
231err_reg:
232 omap_dss_put_device(ddata->in);
233 return r;
234}
235
236static int __exit tvc_remove(struct platform_device *pdev)
237{
238 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
239 struct omap_dss_device *dssdev = &ddata->dssdev;
240 struct omap_dss_device *in = ddata->in;
241
242 omapdss_unregister_display(&ddata->dssdev);
243
244 tvc_disable(dssdev);
245 tvc_disconnect(dssdev);
246
247 omap_dss_put_device(in);
248
249 return 0;
250}
251
252static struct platform_driver tvc_connector_driver = {
253 .probe = tvc_probe,
254 .remove = __exit_p(tvc_remove),
255 .driver = {
256 .name = "connector-analog-tv",
257 .owner = THIS_MODULE,
258 },
259};
260
261module_platform_driver(tvc_connector_driver);
262
263MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
264MODULE_DESCRIPTION("Analog TV Connector driver");
265MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays-new/connector-dvi.c b/drivers/video/omap2/displays-new/connector-dvi.c
new file mode 100644
index 000000000000..bc5f8ceda371
--- /dev/null
+++ b/drivers/video/omap2/displays-new/connector-dvi.c
@@ -0,0 +1,351 @@
1/*
2 * Generic DVI Connector driver
3 *
4 * Copyright (C) 2013 Texas Instruments
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12#include <linux/i2c.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/slab.h>
16
17#include <drm/drm_edid.h>
18
19#include <video/omapdss.h>
20#include <video/omap-panel-data.h>
21
22static const struct omap_video_timings dvic_default_timings = {
23 .x_res = 640,
24 .y_res = 480,
25
26 .pixel_clock = 23500,
27
28 .hfp = 48,
29 .hsw = 32,
30 .hbp = 80,
31
32 .vfp = 3,
33 .vsw = 4,
34 .vbp = 7,
35
36 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
37 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
38 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
39 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
40 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
41};
42
43struct panel_drv_data {
44 struct omap_dss_device dssdev;
45 struct omap_dss_device *in;
46
47 struct omap_video_timings timings;
48
49 struct i2c_adapter *i2c_adapter;
50};
51
52#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
53
54static int dvic_connect(struct omap_dss_device *dssdev)
55{
56 struct panel_drv_data *ddata = to_panel_data(dssdev);
57 struct omap_dss_device *in = ddata->in;
58 int r;
59
60 if (omapdss_device_is_connected(dssdev))
61 return 0;
62
63 r = in->ops.dvi->connect(in, dssdev);
64 if (r)
65 return r;
66
67 return 0;
68}
69
70static void dvic_disconnect(struct omap_dss_device *dssdev)
71{
72 struct panel_drv_data *ddata = to_panel_data(dssdev);
73 struct omap_dss_device *in = ddata->in;
74
75 if (!omapdss_device_is_connected(dssdev))
76 return;
77
78 in->ops.dvi->disconnect(in, dssdev);
79}
80
81static int dvic_enable(struct omap_dss_device *dssdev)
82{
83 struct panel_drv_data *ddata = to_panel_data(dssdev);
84 struct omap_dss_device *in = ddata->in;
85 int r;
86
87 if (!omapdss_device_is_connected(dssdev))
88 return -ENODEV;
89
90 if (omapdss_device_is_enabled(dssdev))
91 return 0;
92
93 in->ops.dvi->set_timings(in, &ddata->timings);
94
95 r = in->ops.dvi->enable(in);
96 if (r)
97 return r;
98
99 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
100
101 return 0;
102}
103
104static void dvic_disable(struct omap_dss_device *dssdev)
105{
106 struct panel_drv_data *ddata = to_panel_data(dssdev);
107 struct omap_dss_device *in = ddata->in;
108
109 if (!omapdss_device_is_enabled(dssdev))
110 return;
111
112 in->ops.dvi->disable(in);
113
114 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
115}
116
117static void dvic_set_timings(struct omap_dss_device *dssdev,
118 struct omap_video_timings *timings)
119{
120 struct panel_drv_data *ddata = to_panel_data(dssdev);
121 struct omap_dss_device *in = ddata->in;
122
123 ddata->timings = *timings;
124 dssdev->panel.timings = *timings;
125
126 in->ops.dvi->set_timings(in, timings);
127}
128
129static void dvic_get_timings(struct omap_dss_device *dssdev,
130 struct omap_video_timings *timings)
131{
132 struct panel_drv_data *ddata = to_panel_data(dssdev);
133
134 *timings = ddata->timings;
135}
136
137static int dvic_check_timings(struct omap_dss_device *dssdev,
138 struct omap_video_timings *timings)
139{
140 struct panel_drv_data *ddata = to_panel_data(dssdev);
141 struct omap_dss_device *in = ddata->in;
142
143 return in->ops.dvi->check_timings(in, timings);
144}
145
146static int dvic_ddc_read(struct i2c_adapter *adapter,
147 unsigned char *buf, u16 count, u8 offset)
148{
149 int r, retries;
150
151 for (retries = 3; retries > 0; retries--) {
152 struct i2c_msg msgs[] = {
153 {
154 .addr = DDC_ADDR,
155 .flags = 0,
156 .len = 1,
157 .buf = &offset,
158 }, {
159 .addr = DDC_ADDR,
160 .flags = I2C_M_RD,
161 .len = count,
162 .buf = buf,
163 }
164 };
165
166 r = i2c_transfer(adapter, msgs, 2);
167 if (r == 2)
168 return 0;
169
170 if (r != -EAGAIN)
171 break;
172 }
173
174 return r < 0 ? r : -EIO;
175}
176
177static int dvic_read_edid(struct omap_dss_device *dssdev,
178 u8 *edid, int len)
179{
180 struct panel_drv_data *ddata = to_panel_data(dssdev);
181 int r, l, bytes_read;
182
183 if (!ddata->i2c_adapter)
184 return -ENODEV;
185
186 l = min(EDID_LENGTH, len);
187 r = dvic_ddc_read(ddata->i2c_adapter, edid, l, 0);
188 if (r)
189 return r;
190
191 bytes_read = l;
192
193 /* if there are extensions, read second block */
194 if (len > EDID_LENGTH && edid[0x7e] > 0) {
195 l = min(EDID_LENGTH, len - EDID_LENGTH);
196
197 r = dvic_ddc_read(ddata->i2c_adapter, edid + EDID_LENGTH,
198 l, EDID_LENGTH);
199 if (r)
200 return r;
201
202 bytes_read += l;
203 }
204
205 return bytes_read;
206}
207
208static bool dvic_detect(struct omap_dss_device *dssdev)
209{
210 struct panel_drv_data *ddata = to_panel_data(dssdev);
211 unsigned char out;
212 int r;
213
214 if (!ddata->i2c_adapter)
215 return true;
216
217 r = dvic_ddc_read(ddata->i2c_adapter, &out, 1, 0);
218
219 return r == 0;
220}
221
222static struct omap_dss_driver dvic_driver = {
223 .connect = dvic_connect,
224 .disconnect = dvic_disconnect,
225
226 .enable = dvic_enable,
227 .disable = dvic_disable,
228
229 .set_timings = dvic_set_timings,
230 .get_timings = dvic_get_timings,
231 .check_timings = dvic_check_timings,
232
233 .get_resolution = omapdss_default_get_resolution,
234
235 .read_edid = dvic_read_edid,
236 .detect = dvic_detect,
237};
238
239static int dvic_probe_pdata(struct platform_device *pdev)
240{
241 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
242 struct connector_dvi_platform_data *pdata;
243 struct omap_dss_device *in, *dssdev;
244 int i2c_bus_num;
245
246 pdata = dev_get_platdata(&pdev->dev);
247 i2c_bus_num = pdata->i2c_bus_num;
248
249 if (i2c_bus_num != -1) {
250 struct i2c_adapter *adapter;
251
252 adapter = i2c_get_adapter(i2c_bus_num);
253 if (!adapter) {
254 dev_err(&pdev->dev,
255 "Failed to get I2C adapter, bus %d\n",
256 i2c_bus_num);
257 return -EPROBE_DEFER;
258 }
259
260 ddata->i2c_adapter = adapter;
261 }
262
263 in = omap_dss_find_output(pdata->source);
264 if (in == NULL) {
265 dev_err(&pdev->dev, "Failed to find video source\n");
266 return -ENODEV;
267 }
268
269 ddata->in = in;
270
271 dssdev = &ddata->dssdev;
272 dssdev->name = pdata->name;
273
274 return 0;
275}
276
277static int dvic_probe(struct platform_device *pdev)
278{
279 struct panel_drv_data *ddata;
280 struct omap_dss_device *dssdev;
281 int r;
282
283 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
284 if (!ddata)
285 return -ENOMEM;
286
287 platform_set_drvdata(pdev, ddata);
288
289 if (dev_get_platdata(&pdev->dev)) {
290 r = dvic_probe_pdata(pdev);
291 if (r)
292 return r;
293 } else {
294 return -ENODEV;
295 }
296
297 ddata->timings = dvic_default_timings;
298
299 dssdev = &ddata->dssdev;
300 dssdev->driver = &dvic_driver;
301 dssdev->dev = &pdev->dev;
302 dssdev->type = OMAP_DISPLAY_TYPE_DVI;
303 dssdev->owner = THIS_MODULE;
304 dssdev->panel.timings = dvic_default_timings;
305
306 r = omapdss_register_display(dssdev);
307 if (r) {
308 dev_err(&pdev->dev, "Failed to register panel\n");
309 goto err_reg;
310 }
311
312 return 0;
313
314err_reg:
315 omap_dss_put_device(ddata->in);
316 return r;
317}
318
319static int __exit dvic_remove(struct platform_device *pdev)
320{
321 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
322 struct omap_dss_device *dssdev = &ddata->dssdev;
323 struct omap_dss_device *in = ddata->in;
324
325 omapdss_unregister_display(&ddata->dssdev);
326
327 dvic_disable(dssdev);
328 dvic_disconnect(dssdev);
329
330 omap_dss_put_device(in);
331
332 if (ddata->i2c_adapter)
333 i2c_put_adapter(ddata->i2c_adapter);
334
335 return 0;
336}
337
338static struct platform_driver dvi_connector_driver = {
339 .probe = dvic_probe,
340 .remove = __exit_p(dvic_remove),
341 .driver = {
342 .name = "connector-dvi",
343 .owner = THIS_MODULE,
344 },
345};
346
347module_platform_driver(dvi_connector_driver);
348
349MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
350MODULE_DESCRIPTION("Generic DVI Connector driver");
351MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays-new/connector-hdmi.c b/drivers/video/omap2/displays-new/connector-hdmi.c
new file mode 100644
index 000000000000..c5826716d6ab
--- /dev/null
+++ b/drivers/video/omap2/displays-new/connector-hdmi.c
@@ -0,0 +1,375 @@
1/*
2 * HDMI Connector driver
3 *
4 * Copyright (C) 2013 Texas Instruments
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12#include <linux/slab.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15
16#include <drm/drm_edid.h>
17
18#include <video/omapdss.h>
19#include <video/omap-panel-data.h>
20
21static const struct omap_video_timings hdmic_default_timings = {
22 .x_res = 640,
23 .y_res = 480,
24 .pixel_clock = 25175,
25 .hsw = 96,
26 .hfp = 16,
27 .hbp = 48,
28 .vsw = 2,
29 .vfp = 11,
30 .vbp = 31,
31
32 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
33 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
34
35 .interlace = false,
36};
37
38struct panel_drv_data {
39 struct omap_dss_device dssdev;
40 struct omap_dss_device *in;
41
42 struct device *dev;
43
44 struct omap_video_timings timings;
45};
46
47#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
48
49static int hdmic_connect(struct omap_dss_device *dssdev)
50{
51 struct panel_drv_data *ddata = to_panel_data(dssdev);
52 struct omap_dss_device *in = ddata->in;
53 int r;
54
55 dev_dbg(ddata->dev, "connect\n");
56
57 if (omapdss_device_is_connected(dssdev))
58 return 0;
59
60 r = in->ops.hdmi->connect(in, dssdev);
61 if (r)
62 return r;
63
64 return 0;
65}
66
67static void hdmic_disconnect(struct omap_dss_device *dssdev)
68{
69 struct panel_drv_data *ddata = to_panel_data(dssdev);
70 struct omap_dss_device *in = ddata->in;
71
72 dev_dbg(ddata->dev, "disconnect\n");
73
74 if (!omapdss_device_is_connected(dssdev))
75 return;
76
77 in->ops.hdmi->disconnect(in, dssdev);
78}
79
80static int hdmic_enable(struct omap_dss_device *dssdev)
81{
82 struct panel_drv_data *ddata = to_panel_data(dssdev);
83 struct omap_dss_device *in = ddata->in;
84 int r;
85
86 dev_dbg(ddata->dev, "enable\n");
87
88 if (!omapdss_device_is_connected(dssdev))
89 return -ENODEV;
90
91 if (omapdss_device_is_enabled(dssdev))
92 return 0;
93
94 in->ops.hdmi->set_timings(in, &ddata->timings);
95
96 r = in->ops.hdmi->enable(in);
97 if (r)
98 return r;
99
100 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
101
102 return r;
103}
104
105static void hdmic_disable(struct omap_dss_device *dssdev)
106{
107 struct panel_drv_data *ddata = to_panel_data(dssdev);
108 struct omap_dss_device *in = ddata->in;
109
110 dev_dbg(ddata->dev, "disable\n");
111
112 if (!omapdss_device_is_enabled(dssdev))
113 return;
114
115 in->ops.hdmi->disable(in);
116
117 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
118}
119
120static void hdmic_set_timings(struct omap_dss_device *dssdev,
121 struct omap_video_timings *timings)
122{
123 struct panel_drv_data *ddata = to_panel_data(dssdev);
124 struct omap_dss_device *in = ddata->in;
125
126 ddata->timings = *timings;
127 dssdev->panel.timings = *timings;
128
129 in->ops.hdmi->set_timings(in, timings);
130}
131
132static void hdmic_get_timings(struct omap_dss_device *dssdev,
133 struct omap_video_timings *timings)
134{
135 struct panel_drv_data *ddata = to_panel_data(dssdev);
136
137 *timings = ddata->timings;
138}
139
140static int hdmic_check_timings(struct omap_dss_device *dssdev,
141 struct omap_video_timings *timings)
142{
143 struct panel_drv_data *ddata = to_panel_data(dssdev);
144 struct omap_dss_device *in = ddata->in;
145
146 return in->ops.hdmi->check_timings(in, timings);
147}
148
149static int hdmic_read_edid(struct omap_dss_device *dssdev,
150 u8 *edid, int len)
151{
152 struct panel_drv_data *ddata = to_panel_data(dssdev);
153 struct omap_dss_device *in = ddata->in;
154
155 return in->ops.hdmi->read_edid(in, edid, len);
156}
157
158static bool hdmic_detect(struct omap_dss_device *dssdev)
159{
160 struct panel_drv_data *ddata = to_panel_data(dssdev);
161 struct omap_dss_device *in = ddata->in;
162
163 return in->ops.hdmi->detect(in);
164}
165
166static int hdmic_audio_enable(struct omap_dss_device *dssdev)
167{
168 struct panel_drv_data *ddata = to_panel_data(dssdev);
169 struct omap_dss_device *in = ddata->in;
170 int r;
171
172 /* enable audio only if the display is active */
173 if (!omapdss_device_is_enabled(dssdev))
174 return -EPERM;
175
176 r = in->ops.hdmi->audio_enable(in);
177 if (r)
178 return r;
179
180 dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
181
182 return 0;
183}
184
185static void hdmic_audio_disable(struct omap_dss_device *dssdev)
186{
187 struct panel_drv_data *ddata = to_panel_data(dssdev);
188 struct omap_dss_device *in = ddata->in;
189
190 in->ops.hdmi->audio_disable(in);
191
192 dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED;
193}
194
195static int hdmic_audio_start(struct omap_dss_device *dssdev)
196{
197 struct panel_drv_data *ddata = to_panel_data(dssdev);
198 struct omap_dss_device *in = ddata->in;
199 int r;
200
201 /*
202 * No need to check the panel state. It was checked when trasitioning
203 * to AUDIO_ENABLED.
204 */
205 if (dssdev->audio_state != OMAP_DSS_AUDIO_ENABLED)
206 return -EPERM;
207
208 r = in->ops.hdmi->audio_start(in);
209 if (r)
210 return r;
211
212 dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING;
213
214 return 0;
215}
216
217static void hdmic_audio_stop(struct omap_dss_device *dssdev)
218{
219 struct panel_drv_data *ddata = to_panel_data(dssdev);
220 struct omap_dss_device *in = ddata->in;
221
222 in->ops.hdmi->audio_stop(in);
223
224 dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
225}
226
227static bool hdmic_audio_supported(struct omap_dss_device *dssdev)
228{
229 struct panel_drv_data *ddata = to_panel_data(dssdev);
230 struct omap_dss_device *in = ddata->in;
231
232 if (!omapdss_device_is_enabled(dssdev))
233 return false;
234
235 return in->ops.hdmi->audio_supported(in);
236}
237
238static int hdmic_audio_config(struct omap_dss_device *dssdev,
239 struct omap_dss_audio *audio)
240{
241 struct panel_drv_data *ddata = to_panel_data(dssdev);
242 struct omap_dss_device *in = ddata->in;
243 int r;
244
245 /* config audio only if the display is active */
246 if (!omapdss_device_is_enabled(dssdev))
247 return -EPERM;
248
249 r = in->ops.hdmi->audio_config(in, audio);
250 if (r)
251 return r;
252
253 dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED;
254
255 return 0;
256}
257
258static struct omap_dss_driver hdmic_driver = {
259 .connect = hdmic_connect,
260 .disconnect = hdmic_disconnect,
261
262 .enable = hdmic_enable,
263 .disable = hdmic_disable,
264
265 .set_timings = hdmic_set_timings,
266 .get_timings = hdmic_get_timings,
267 .check_timings = hdmic_check_timings,
268
269 .get_resolution = omapdss_default_get_resolution,
270
271 .read_edid = hdmic_read_edid,
272 .detect = hdmic_detect,
273
274 .audio_enable = hdmic_audio_enable,
275 .audio_disable = hdmic_audio_disable,
276 .audio_start = hdmic_audio_start,
277 .audio_stop = hdmic_audio_stop,
278 .audio_supported = hdmic_audio_supported,
279 .audio_config = hdmic_audio_config,
280};
281
282static int hdmic_probe_pdata(struct platform_device *pdev)
283{
284 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
285 struct connector_hdmi_platform_data *pdata;
286 struct omap_dss_device *in, *dssdev;
287
288 pdata = dev_get_platdata(&pdev->dev);
289
290 in = omap_dss_find_output(pdata->source);
291 if (in == NULL) {
292 dev_err(&pdev->dev, "Failed to find video source\n");
293 return -ENODEV;
294 }
295
296 ddata->in = in;
297
298 dssdev = &ddata->dssdev;
299 dssdev->name = pdata->name;
300
301 return 0;
302}
303
304static int hdmic_probe(struct platform_device *pdev)
305{
306 struct panel_drv_data *ddata;
307 struct omap_dss_device *dssdev;
308 int r;
309
310 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
311 if (!ddata)
312 return -ENOMEM;
313
314 platform_set_drvdata(pdev, ddata);
315 ddata->dev = &pdev->dev;
316
317 if (dev_get_platdata(&pdev->dev)) {
318 r = hdmic_probe_pdata(pdev);
319 if (r)
320 return r;
321 } else {
322 return -ENODEV;
323 }
324
325 ddata->timings = hdmic_default_timings;
326
327 dssdev = &ddata->dssdev;
328 dssdev->driver = &hdmic_driver;
329 dssdev->dev = &pdev->dev;
330 dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
331 dssdev->owner = THIS_MODULE;
332 dssdev->panel.timings = hdmic_default_timings;
333
334 r = omapdss_register_display(dssdev);
335 if (r) {
336 dev_err(&pdev->dev, "Failed to register panel\n");
337 goto err_reg;
338 }
339
340 return 0;
341err_reg:
342 omap_dss_put_device(ddata->in);
343 return r;
344}
345
346static int __exit hdmic_remove(struct platform_device *pdev)
347{
348 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
349 struct omap_dss_device *dssdev = &ddata->dssdev;
350 struct omap_dss_device *in = ddata->in;
351
352 omapdss_unregister_display(&ddata->dssdev);
353
354 hdmic_disable(dssdev);
355 hdmic_disconnect(dssdev);
356
357 omap_dss_put_device(in);
358
359 return 0;
360}
361
362static struct platform_driver hdmi_connector_driver = {
363 .probe = hdmic_probe,
364 .remove = __exit_p(hdmic_remove),
365 .driver = {
366 .name = "connector-hdmi",
367 .owner = THIS_MODULE,
368 },
369};
370
371module_platform_driver(hdmi_connector_driver);
372
373MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
374MODULE_DESCRIPTION("HDMI Connector driver");
375MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays-new/encoder-tfp410.c b/drivers/video/omap2/displays-new/encoder-tfp410.c
new file mode 100644
index 000000000000..a04f65856d6b
--- /dev/null
+++ b/drivers/video/omap2/displays-new/encoder-tfp410.c
@@ -0,0 +1,267 @@
1/*
2 * TFP410 DPI-to-DVI encoder driver
3 *
4 * Copyright (C) 2013 Texas Instruments
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12#include <linux/gpio.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/slab.h>
16
17#include <video/omapdss.h>
18#include <video/omap-panel-data.h>
19
20struct panel_drv_data {
21 struct omap_dss_device dssdev;
22 struct omap_dss_device *in;
23
24 int pd_gpio;
25 int data_lines;
26
27 struct omap_video_timings timings;
28};
29
30#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
31
32static int tfp410_connect(struct omap_dss_device *dssdev,
33 struct omap_dss_device *dst)
34{
35 struct panel_drv_data *ddata = to_panel_data(dssdev);
36 struct omap_dss_device *in = ddata->in;
37 int r;
38
39 if (omapdss_device_is_connected(dssdev))
40 return -EBUSY;
41
42 r = in->ops.dpi->connect(in, dssdev);
43 if (r)
44 return r;
45
46 dst->output = dssdev;
47 dssdev->device = dst;
48
49 return 0;
50}
51
52static void tfp410_disconnect(struct omap_dss_device *dssdev,
53 struct omap_dss_device *dst)
54{
55 struct panel_drv_data *ddata = to_panel_data(dssdev);
56 struct omap_dss_device *in = ddata->in;
57
58 WARN_ON(!omapdss_device_is_connected(dssdev));
59 if (!omapdss_device_is_connected(dssdev))
60 return;
61
62 WARN_ON(dst != dssdev->device);
63 if (dst != dssdev->device)
64 return;
65
66 dst->output = NULL;
67 dssdev->device = NULL;
68
69 in->ops.dpi->disconnect(in, &ddata->dssdev);
70}
71
72static int tfp410_enable(struct omap_dss_device *dssdev)
73{
74 struct panel_drv_data *ddata = to_panel_data(dssdev);
75 struct omap_dss_device *in = ddata->in;
76 int r;
77
78 if (!omapdss_device_is_connected(dssdev))
79 return -ENODEV;
80
81 if (omapdss_device_is_enabled(dssdev))
82 return 0;
83
84 in->ops.dpi->set_timings(in, &ddata->timings);
85 in->ops.dpi->set_data_lines(in, ddata->data_lines);
86
87 r = in->ops.dpi->enable(in);
88 if (r)
89 return r;
90
91 if (gpio_is_valid(ddata->pd_gpio))
92 gpio_set_value_cansleep(ddata->pd_gpio, 1);
93
94 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
95
96 return 0;
97}
98
99static void tfp410_disable(struct omap_dss_device *dssdev)
100{
101 struct panel_drv_data *ddata = to_panel_data(dssdev);
102 struct omap_dss_device *in = ddata->in;
103
104 if (!omapdss_device_is_enabled(dssdev))
105 return;
106
107 if (gpio_is_valid(ddata->pd_gpio))
108 gpio_set_value_cansleep(ddata->pd_gpio, 0);
109
110 in->ops.dpi->disable(in);
111
112 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
113}
114
115static void tfp410_set_timings(struct omap_dss_device *dssdev,
116 struct omap_video_timings *timings)
117{
118 struct panel_drv_data *ddata = to_panel_data(dssdev);
119 struct omap_dss_device *in = ddata->in;
120
121 ddata->timings = *timings;
122 dssdev->panel.timings = *timings;
123
124 in->ops.dpi->set_timings(in, timings);
125}
126
127static void tfp410_get_timings(struct omap_dss_device *dssdev,
128 struct omap_video_timings *timings)
129{
130 struct panel_drv_data *ddata = to_panel_data(dssdev);
131
132 *timings = ddata->timings;
133}
134
135static int tfp410_check_timings(struct omap_dss_device *dssdev,
136 struct omap_video_timings *timings)
137{
138 struct panel_drv_data *ddata = to_panel_data(dssdev);
139 struct omap_dss_device *in = ddata->in;
140
141 return in->ops.dpi->check_timings(in, timings);
142}
143
144static const struct omapdss_dvi_ops tfp410_dvi_ops = {
145 .connect = tfp410_connect,
146 .disconnect = tfp410_disconnect,
147
148 .enable = tfp410_enable,
149 .disable = tfp410_disable,
150
151 .check_timings = tfp410_check_timings,
152 .set_timings = tfp410_set_timings,
153 .get_timings = tfp410_get_timings,
154};
155
156static int tfp410_probe_pdata(struct platform_device *pdev)
157{
158 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
159 struct encoder_tfp410_platform_data *pdata;
160 struct omap_dss_device *dssdev, *in;
161
162 pdata = dev_get_platdata(&pdev->dev);
163
164 ddata->pd_gpio = pdata->power_down_gpio;
165
166 ddata->data_lines = pdata->data_lines;
167
168 in = omap_dss_find_output(pdata->source);
169 if (in == NULL) {
170 dev_err(&pdev->dev, "Failed to find video source\n");
171 return -ENODEV;
172 }
173
174 ddata->in = in;
175
176 dssdev = &ddata->dssdev;
177 dssdev->name = pdata->name;
178
179 return 0;
180}
181
182static int tfp410_probe(struct platform_device *pdev)
183{
184 struct panel_drv_data *ddata;
185 struct omap_dss_device *dssdev;
186 int r;
187
188 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
189 if (!ddata)
190 return -ENOMEM;
191
192 platform_set_drvdata(pdev, ddata);
193
194 if (dev_get_platdata(&pdev->dev)) {
195 r = tfp410_probe_pdata(pdev);
196 if (r)
197 return r;
198 } else {
199 return -ENODEV;
200 }
201
202 if (gpio_is_valid(ddata->pd_gpio)) {
203 r = devm_gpio_request_one(&pdev->dev, ddata->pd_gpio,
204 GPIOF_OUT_INIT_LOW, "tfp410 PD");
205 if (r) {
206 dev_err(&pdev->dev, "Failed to request PD GPIO %d\n",
207 ddata->pd_gpio);
208 goto err_gpio;
209 }
210 }
211
212 dssdev = &ddata->dssdev;
213 dssdev->ops.dvi = &tfp410_dvi_ops;
214 dssdev->dev = &pdev->dev;
215 dssdev->type = OMAP_DISPLAY_TYPE_DPI;
216 dssdev->output_type = OMAP_DISPLAY_TYPE_DVI;
217 dssdev->owner = THIS_MODULE;
218 dssdev->phy.dpi.data_lines = ddata->data_lines;
219
220 r = omapdss_register_output(dssdev);
221 if (r) {
222 dev_err(&pdev->dev, "Failed to register output\n");
223 goto err_reg;
224 }
225
226 return 0;
227err_reg:
228err_gpio:
229 omap_dss_put_device(ddata->in);
230 return r;
231}
232
233static int __exit tfp410_remove(struct platform_device *pdev)
234{
235 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
236 struct omap_dss_device *dssdev = &ddata->dssdev;
237 struct omap_dss_device *in = ddata->in;
238
239 omapdss_unregister_output(&ddata->dssdev);
240
241 WARN_ON(omapdss_device_is_enabled(dssdev));
242 if (omapdss_device_is_enabled(dssdev))
243 tfp410_disable(dssdev);
244
245 WARN_ON(omapdss_device_is_connected(dssdev));
246 if (omapdss_device_is_connected(dssdev))
247 tfp410_disconnect(dssdev, dssdev->device);
248
249 omap_dss_put_device(in);
250
251 return 0;
252}
253
254static struct platform_driver tfp410_driver = {
255 .probe = tfp410_probe,
256 .remove = __exit_p(tfp410_remove),
257 .driver = {
258 .name = "tfp410",
259 .owner = THIS_MODULE,
260 },
261};
262
263module_platform_driver(tfp410_driver);
264
265MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
266MODULE_DESCRIPTION("TFP410 DPI to DVI encoder driver");
267MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/omap2/displays-new/encoder-tpd12s015.c
new file mode 100644
index 000000000000..ce0e010026cb
--- /dev/null
+++ b/drivers/video/omap2/displays-new/encoder-tpd12s015.c
@@ -0,0 +1,395 @@
1/*
2 * TPD12S015 HDMI ESD protection & level shifter chip driver
3 *
4 * Copyright (C) 2013 Texas Instruments
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12#include <linux/completion.h>
13#include <linux/delay.h>
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/gpio.h>
17#include <linux/platform_device.h>
18
19#include <video/omapdss.h>
20#include <video/omap-panel-data.h>
21
22struct panel_drv_data {
23 struct omap_dss_device dssdev;
24 struct omap_dss_device *in;
25
26 int ct_cp_hpd_gpio;
27 int ls_oe_gpio;
28 int hpd_gpio;
29
30 struct omap_video_timings timings;
31
32 struct completion hpd_completion;
33};
34
35#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
36
37static irqreturn_t tpd_hpd_irq_handler(int irq, void *data)
38{
39 struct panel_drv_data *ddata = data;
40 bool hpd;
41
42 hpd = gpio_get_value_cansleep(ddata->hpd_gpio);
43
44 dev_dbg(ddata->dssdev.dev, "hpd %d\n", hpd);
45
46 if (gpio_is_valid(ddata->ls_oe_gpio)) {
47 if (hpd)
48 gpio_set_value_cansleep(ddata->ls_oe_gpio, 1);
49 else
50 gpio_set_value_cansleep(ddata->ls_oe_gpio, 0);
51 }
52
53 complete_all(&ddata->hpd_completion);
54
55 return IRQ_HANDLED;
56}
57
58static int tpd_connect(struct omap_dss_device *dssdev,
59 struct omap_dss_device *dst)
60{
61 struct panel_drv_data *ddata = to_panel_data(dssdev);
62 struct omap_dss_device *in = ddata->in;
63 int r;
64
65 r = in->ops.hdmi->connect(in, dssdev);
66 if (r)
67 return r;
68
69 dst->output = dssdev;
70 dssdev->device = dst;
71
72 INIT_COMPLETION(ddata->hpd_completion);
73
74 gpio_set_value_cansleep(ddata->ct_cp_hpd_gpio, 1);
75 /* DC-DC converter needs at max 300us to get to 90% of 5V */
76 udelay(300);
77
78 /*
79 * If there's a cable connected, wait for the hpd irq to trigger,
80 * which turns on the level shifters.
81 */
82 if (gpio_get_value_cansleep(ddata->hpd_gpio)) {
83 unsigned long to;
84 to = wait_for_completion_timeout(&ddata->hpd_completion,
85 msecs_to_jiffies(250));
86 WARN_ON_ONCE(to == 0);
87 }
88
89 return 0;
90}
91
92static void tpd_disconnect(struct omap_dss_device *dssdev,
93 struct omap_dss_device *dst)
94{
95 struct panel_drv_data *ddata = to_panel_data(dssdev);
96 struct omap_dss_device *in = ddata->in;
97
98 WARN_ON(dst != dssdev->device);
99
100 if (dst != dssdev->device)
101 return;
102
103 gpio_set_value_cansleep(ddata->ct_cp_hpd_gpio, 0);
104
105 dst->output = NULL;
106 dssdev->device = NULL;
107
108 in->ops.hdmi->disconnect(in, &ddata->dssdev);
109}
110
111static int tpd_enable(struct omap_dss_device *dssdev)
112{
113 struct panel_drv_data *ddata = to_panel_data(dssdev);
114 struct omap_dss_device *in = ddata->in;
115 int r;
116
117 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
118 return 0;
119
120 in->ops.hdmi->set_timings(in, &ddata->timings);
121
122 r = in->ops.hdmi->enable(in);
123 if (r)
124 return r;
125
126 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
127
128 return r;
129}
130
131static void tpd_disable(struct omap_dss_device *dssdev)
132{
133 struct panel_drv_data *ddata = to_panel_data(dssdev);
134 struct omap_dss_device *in = ddata->in;
135
136 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
137 return;
138
139 in->ops.hdmi->disable(in);
140
141 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
142}
143
144static void tpd_set_timings(struct omap_dss_device *dssdev,
145 struct omap_video_timings *timings)
146{
147 struct panel_drv_data *ddata = to_panel_data(dssdev);
148 struct omap_dss_device *in = ddata->in;
149
150 ddata->timings = *timings;
151 dssdev->panel.timings = *timings;
152
153 in->ops.hdmi->set_timings(in, timings);
154}
155
156static void tpd_get_timings(struct omap_dss_device *dssdev,
157 struct omap_video_timings *timings)
158{
159 struct panel_drv_data *ddata = to_panel_data(dssdev);
160
161 *timings = ddata->timings;
162}
163
164static int tpd_check_timings(struct omap_dss_device *dssdev,
165 struct omap_video_timings *timings)
166{
167 struct panel_drv_data *ddata = to_panel_data(dssdev);
168 struct omap_dss_device *in = ddata->in;
169 int r;
170
171 r = in->ops.hdmi->check_timings(in, timings);
172
173 return r;
174}
175
176static int tpd_read_edid(struct omap_dss_device *dssdev,
177 u8 *edid, int len)
178{
179 struct panel_drv_data *ddata = to_panel_data(dssdev);
180 struct omap_dss_device *in = ddata->in;
181
182 if (!gpio_get_value_cansleep(ddata->hpd_gpio))
183 return -ENODEV;
184
185 return in->ops.hdmi->read_edid(in, edid, len);
186}
187
188static bool tpd_detect(struct omap_dss_device *dssdev)
189{
190 struct panel_drv_data *ddata = to_panel_data(dssdev);
191
192 return gpio_get_value_cansleep(ddata->hpd_gpio);
193}
194
195static int tpd_audio_enable(struct omap_dss_device *dssdev)
196{
197 struct panel_drv_data *ddata = to_panel_data(dssdev);
198 struct omap_dss_device *in = ddata->in;
199
200 return in->ops.hdmi->audio_enable(in);
201}
202
203static void tpd_audio_disable(struct omap_dss_device *dssdev)
204{
205 struct panel_drv_data *ddata = to_panel_data(dssdev);
206 struct omap_dss_device *in = ddata->in;
207
208 in->ops.hdmi->audio_disable(in);
209}
210
211static int tpd_audio_start(struct omap_dss_device *dssdev)
212{
213 struct panel_drv_data *ddata = to_panel_data(dssdev);
214 struct omap_dss_device *in = ddata->in;
215
216 return in->ops.hdmi->audio_start(in);
217}
218
219static void tpd_audio_stop(struct omap_dss_device *dssdev)
220{
221 struct panel_drv_data *ddata = to_panel_data(dssdev);
222 struct omap_dss_device *in = ddata->in;
223
224 in->ops.hdmi->audio_stop(in);
225}
226
227static bool tpd_audio_supported(struct omap_dss_device *dssdev)
228{
229 struct panel_drv_data *ddata = to_panel_data(dssdev);
230 struct omap_dss_device *in = ddata->in;
231
232 return in->ops.hdmi->audio_supported(in);
233}
234
235static int tpd_audio_config(struct omap_dss_device *dssdev,
236 struct omap_dss_audio *audio)
237{
238 struct panel_drv_data *ddata = to_panel_data(dssdev);
239 struct omap_dss_device *in = ddata->in;
240
241 return in->ops.hdmi->audio_config(in, audio);
242}
243
244static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
245 .connect = tpd_connect,
246 .disconnect = tpd_disconnect,
247
248 .enable = tpd_enable,
249 .disable = tpd_disable,
250
251 .check_timings = tpd_check_timings,
252 .set_timings = tpd_set_timings,
253 .get_timings = tpd_get_timings,
254
255 .read_edid = tpd_read_edid,
256 .detect = tpd_detect,
257
258 .audio_enable = tpd_audio_enable,
259 .audio_disable = tpd_audio_disable,
260 .audio_start = tpd_audio_start,
261 .audio_stop = tpd_audio_stop,
262 .audio_supported = tpd_audio_supported,
263 .audio_config = tpd_audio_config,
264};
265
266static int tpd_probe_pdata(struct platform_device *pdev)
267{
268 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
269 struct encoder_tpd12s015_platform_data *pdata;
270 struct omap_dss_device *dssdev, *in;
271
272 pdata = dev_get_platdata(&pdev->dev);
273
274 ddata->ct_cp_hpd_gpio = pdata->ct_cp_hpd_gpio;
275 ddata->ls_oe_gpio = pdata->ls_oe_gpio;
276 ddata->hpd_gpio = pdata->hpd_gpio;
277
278 in = omap_dss_find_output(pdata->source);
279 if (in == NULL) {
280 dev_err(&pdev->dev, "Failed to find video source\n");
281 return -ENODEV;
282 }
283
284 ddata->in = in;
285
286 dssdev = &ddata->dssdev;
287 dssdev->name = pdata->name;
288
289 return 0;
290}
291
292static int tpd_probe(struct platform_device *pdev)
293{
294 struct omap_dss_device *in, *dssdev;
295 struct panel_drv_data *ddata;
296 int r;
297
298 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
299 if (!ddata)
300 return -ENOMEM;
301
302 platform_set_drvdata(pdev, ddata);
303
304 init_completion(&ddata->hpd_completion);
305
306 if (dev_get_platdata(&pdev->dev)) {
307 r = tpd_probe_pdata(pdev);
308 if (r)
309 return r;
310 } else {
311 return -ENODEV;
312 }
313
314 r = devm_gpio_request_one(&pdev->dev, ddata->ct_cp_hpd_gpio,
315 GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd");
316 if (r)
317 goto err_gpio;
318
319 if (gpio_is_valid(ddata->ls_oe_gpio)) {
320 r = devm_gpio_request_one(&pdev->dev, ddata->ls_oe_gpio,
321 GPIOF_OUT_INIT_LOW, "hdmi_ls_oe");
322 if (r)
323 goto err_gpio;
324 }
325
326 r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio,
327 GPIOF_DIR_IN, "hdmi_hpd");
328 if (r)
329 goto err_gpio;
330
331 r = devm_request_threaded_irq(&pdev->dev, gpio_to_irq(ddata->hpd_gpio),
332 NULL, tpd_hpd_irq_handler,
333 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
334 IRQF_ONESHOT, "hpd", ddata);
335 if (r)
336 goto err_irq;
337
338 dssdev = &ddata->dssdev;
339 dssdev->ops.hdmi = &tpd_hdmi_ops;
340 dssdev->dev = &pdev->dev;
341 dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
342 dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI;
343 dssdev->owner = THIS_MODULE;
344
345 in = ddata->in;
346
347 r = omapdss_register_output(dssdev);
348 if (r) {
349 dev_err(&pdev->dev, "Failed to register output\n");
350 goto err_reg;
351 }
352
353 return 0;
354err_reg:
355err_irq:
356err_gpio:
357 omap_dss_put_device(ddata->in);
358 return r;
359}
360
361static int __exit tpd_remove(struct platform_device *pdev)
362{
363 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
364 struct omap_dss_device *dssdev = &ddata->dssdev;
365 struct omap_dss_device *in = ddata->in;
366
367 omapdss_unregister_output(&ddata->dssdev);
368
369 WARN_ON(omapdss_device_is_enabled(dssdev));
370 if (omapdss_device_is_enabled(dssdev))
371 tpd_disable(dssdev);
372
373 WARN_ON(omapdss_device_is_connected(dssdev));
374 if (omapdss_device_is_connected(dssdev))
375 tpd_disconnect(dssdev, dssdev->device);
376
377 omap_dss_put_device(in);
378
379 return 0;
380}
381
382static struct platform_driver tpd_driver = {
383 .probe = tpd_probe,
384 .remove = __exit_p(tpd_remove),
385 .driver = {
386 .name = "tpd12s015",
387 .owner = THIS_MODULE,
388 },
389};
390
391module_platform_driver(tpd_driver);
392
393MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
394MODULE_DESCRIPTION("TPD12S015 driver");
395MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays-new/panel-dpi.c b/drivers/video/omap2/displays-new/panel-dpi.c
new file mode 100644
index 000000000000..5f8f7e7c81ef
--- /dev/null
+++ b/drivers/video/omap2/displays-new/panel-dpi.c
@@ -0,0 +1,270 @@
1/*
2 * Generic MIPI DPI Panel Driver
3 *
4 * Copyright (C) 2013 Texas Instruments
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12#include <linux/gpio.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/slab.h>
16
17#include <video/omapdss.h>
18#include <video/omap-panel-data.h>
19
20struct panel_drv_data {
21 struct omap_dss_device dssdev;
22 struct omap_dss_device *in;
23
24 int data_lines;
25
26 struct omap_video_timings videomode;
27
28 int backlight_gpio;
29 int enable_gpio;
30};
31
32#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
33
34static int panel_dpi_connect(struct omap_dss_device *dssdev)
35{
36 struct panel_drv_data *ddata = to_panel_data(dssdev);
37 struct omap_dss_device *in = ddata->in;
38 int r;
39
40 if (omapdss_device_is_connected(dssdev))
41 return 0;
42
43 r = in->ops.dpi->connect(in, dssdev);
44 if (r)
45 return r;
46
47 return 0;
48}
49
50static void panel_dpi_disconnect(struct omap_dss_device *dssdev)
51{
52 struct panel_drv_data *ddata = to_panel_data(dssdev);
53 struct omap_dss_device *in = ddata->in;
54
55 if (!omapdss_device_is_connected(dssdev))
56 return;
57
58 in->ops.dpi->disconnect(in, dssdev);
59}
60
61static int panel_dpi_enable(struct omap_dss_device *dssdev)
62{
63 struct panel_drv_data *ddata = to_panel_data(dssdev);
64 struct omap_dss_device *in = ddata->in;
65 int r;
66
67 if (!omapdss_device_is_connected(dssdev))
68 return -ENODEV;
69
70 if (omapdss_device_is_enabled(dssdev))
71 return 0;
72
73 in->ops.dpi->set_data_lines(in, ddata->data_lines);
74 in->ops.dpi->set_timings(in, &ddata->videomode);
75
76 r = in->ops.dpi->enable(in);
77 if (r)
78 return r;
79
80 if (gpio_is_valid(ddata->enable_gpio))
81 gpio_set_value_cansleep(ddata->enable_gpio, 1);
82
83 if (gpio_is_valid(ddata->backlight_gpio))
84 gpio_set_value_cansleep(ddata->backlight_gpio, 1);
85
86 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
87
88 return 0;
89}
90
91static void panel_dpi_disable(struct omap_dss_device *dssdev)
92{
93 struct panel_drv_data *ddata = to_panel_data(dssdev);
94 struct omap_dss_device *in = ddata->in;
95
96 if (!omapdss_device_is_enabled(dssdev))
97 return;
98
99 if (gpio_is_valid(ddata->enable_gpio))
100 gpio_set_value_cansleep(ddata->enable_gpio, 0);
101
102 if (gpio_is_valid(ddata->backlight_gpio))
103 gpio_set_value_cansleep(ddata->backlight_gpio, 0);
104
105 in->ops.dpi->disable(in);
106
107 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
108}
109
110static void panel_dpi_set_timings(struct omap_dss_device *dssdev,
111 struct omap_video_timings *timings)
112{
113 struct panel_drv_data *ddata = to_panel_data(dssdev);
114 struct omap_dss_device *in = ddata->in;
115
116 ddata->videomode = *timings;
117 dssdev->panel.timings = *timings;
118
119 in->ops.dpi->set_timings(in, timings);
120}
121
122static void panel_dpi_get_timings(struct omap_dss_device *dssdev,
123 struct omap_video_timings *timings)
124{
125 struct panel_drv_data *ddata = to_panel_data(dssdev);
126
127 *timings = ddata->videomode;
128}
129
130static int panel_dpi_check_timings(struct omap_dss_device *dssdev,
131 struct omap_video_timings *timings)
132{
133 struct panel_drv_data *ddata = to_panel_data(dssdev);
134 struct omap_dss_device *in = ddata->in;
135
136 return in->ops.dpi->check_timings(in, timings);
137}
138
139static struct omap_dss_driver panel_dpi_ops = {
140 .connect = panel_dpi_connect,
141 .disconnect = panel_dpi_disconnect,
142
143 .enable = panel_dpi_enable,
144 .disable = panel_dpi_disable,
145
146 .set_timings = panel_dpi_set_timings,
147 .get_timings = panel_dpi_get_timings,
148 .check_timings = panel_dpi_check_timings,
149
150 .get_resolution = omapdss_default_get_resolution,
151};
152
153static int panel_dpi_probe_pdata(struct platform_device *pdev)
154{
155 const struct panel_dpi_platform_data *pdata;
156 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
157 struct omap_dss_device *dssdev, *in;
158 struct videomode vm;
159
160 pdata = dev_get_platdata(&pdev->dev);
161
162 in = omap_dss_find_output(pdata->source);
163 if (in == NULL) {
164 dev_err(&pdev->dev, "failed to find video source '%s'\n",
165 pdata->source);
166 return -EPROBE_DEFER;
167 }
168
169 ddata->in = in;
170
171 ddata->data_lines = pdata->data_lines;
172
173 videomode_from_timing(pdata->display_timing, &vm);
174 videomode_to_omap_video_timings(&vm, &ddata->videomode);
175
176 dssdev = &ddata->dssdev;
177 dssdev->name = pdata->name;
178
179 ddata->enable_gpio = pdata->enable_gpio;
180 ddata->backlight_gpio = pdata->backlight_gpio;
181
182 return 0;
183}
184
185static int panel_dpi_probe(struct platform_device *pdev)
186{
187 struct panel_drv_data *ddata;
188 struct omap_dss_device *dssdev;
189 int r;
190
191 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
192 if (ddata == NULL)
193 return -ENOMEM;
194
195 platform_set_drvdata(pdev, ddata);
196
197 if (dev_get_platdata(&pdev->dev)) {
198 r = panel_dpi_probe_pdata(pdev);
199 if (r)
200 return r;
201 } else {
202 return -ENODEV;
203 }
204
205 if (gpio_is_valid(ddata->enable_gpio)) {
206 r = devm_gpio_request_one(&pdev->dev, ddata->enable_gpio,
207 GPIOF_OUT_INIT_LOW, "panel enable");
208 if (r)
209 goto err_gpio;
210 }
211
212 if (gpio_is_valid(ddata->backlight_gpio)) {
213 r = devm_gpio_request_one(&pdev->dev, ddata->backlight_gpio,
214 GPIOF_OUT_INIT_LOW, "panel backlight");
215 if (r)
216 goto err_gpio;
217 }
218
219 dssdev = &ddata->dssdev;
220 dssdev->dev = &pdev->dev;
221 dssdev->driver = &panel_dpi_ops;
222 dssdev->type = OMAP_DISPLAY_TYPE_DPI;
223 dssdev->owner = THIS_MODULE;
224 dssdev->panel.timings = ddata->videomode;
225 dssdev->phy.dpi.data_lines = ddata->data_lines;
226
227 r = omapdss_register_display(dssdev);
228 if (r) {
229 dev_err(&pdev->dev, "Failed to register panel\n");
230 goto err_reg;
231 }
232
233 return 0;
234
235err_reg:
236err_gpio:
237 omap_dss_put_device(ddata->in);
238 return r;
239}
240
241static int __exit panel_dpi_remove(struct platform_device *pdev)
242{
243 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
244 struct omap_dss_device *dssdev = &ddata->dssdev;
245 struct omap_dss_device *in = ddata->in;
246
247 omapdss_unregister_display(dssdev);
248
249 panel_dpi_disable(dssdev);
250 panel_dpi_disconnect(dssdev);
251
252 omap_dss_put_device(in);
253
254 return 0;
255}
256
257static struct platform_driver panel_dpi_driver = {
258 .probe = panel_dpi_probe,
259 .remove = __exit_p(panel_dpi_remove),
260 .driver = {
261 .name = "panel-dpi",
262 .owner = THIS_MODULE,
263 },
264};
265
266module_platform_driver(panel_dpi_driver);
267
268MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
269MODULE_DESCRIPTION("Generic MIPI DPI Panel Driver");
270MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays-new/panel-dsi-cm.c b/drivers/video/omap2/displays-new/panel-dsi-cm.c
new file mode 100644
index 000000000000..aaaea6469cd9
--- /dev/null
+++ b/drivers/video/omap2/displays-new/panel-dsi-cm.c
@@ -0,0 +1,1336 @@
1/*
2 * Generic DSI Command Mode panel driver
3 *
4 * Copyright (C) 2013 Texas Instruments
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12/* #define DEBUG */
13
14#include <linux/backlight.h>
15#include <linux/delay.h>
16#include <linux/fb.h>
17#include <linux/gpio.h>
18#include <linux/interrupt.h>
19#include <linux/jiffies.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/sched.h>
23#include <linux/slab.h>
24#include <linux/workqueue.h>
25
26#include <video/omapdss.h>
27#include <video/omap-panel-data.h>
28#include <video/mipi_display.h>
29
30/* DSI Virtual channel. Hardcoded for now. */
31#define TCH 0
32
33#define DCS_READ_NUM_ERRORS 0x05
34#define DCS_BRIGHTNESS 0x51
35#define DCS_CTRL_DISPLAY 0x53
36#define DCS_GET_ID1 0xda
37#define DCS_GET_ID2 0xdb
38#define DCS_GET_ID3 0xdc
39
40struct panel_drv_data {
41 struct omap_dss_device dssdev;
42 struct omap_dss_device *in;
43
44 struct omap_video_timings timings;
45
46 struct platform_device *pdev;
47
48 struct mutex lock;
49
50 struct backlight_device *bldev;
51
52 unsigned long hw_guard_end; /* next value of jiffies when we can
53 * issue the next sleep in/out command
54 */
55 unsigned long hw_guard_wait; /* max guard time in jiffies */
56
57 /* panel HW configuration from DT or platform data */
58 int reset_gpio;
59 int ext_te_gpio;
60
61 bool use_dsi_backlight;
62
63 struct omap_dsi_pin_config pin_config;
64
65 /* runtime variables */
66 bool enabled;
67
68 bool te_enabled;
69
70 atomic_t do_update;
71 int channel;
72
73 struct delayed_work te_timeout_work;
74
75 bool intro_printed;
76
77 struct workqueue_struct *workqueue;
78
79 bool ulps_enabled;
80 unsigned ulps_timeout;
81 struct delayed_work ulps_work;
82};
83
84#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
85
86static irqreturn_t dsicm_te_isr(int irq, void *data);
87static void dsicm_te_timeout_work_callback(struct work_struct *work);
88static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
89
90static int dsicm_panel_reset(struct panel_drv_data *ddata);
91
92static void dsicm_ulps_work(struct work_struct *work);
93
94static void hw_guard_start(struct panel_drv_data *ddata, int guard_msec)
95{
96 ddata->hw_guard_wait = msecs_to_jiffies(guard_msec);
97 ddata->hw_guard_end = jiffies + ddata->hw_guard_wait;
98}
99
100static void hw_guard_wait(struct panel_drv_data *ddata)
101{
102 unsigned long wait = ddata->hw_guard_end - jiffies;
103
104 if ((long)wait > 0 && wait <= ddata->hw_guard_wait) {
105 set_current_state(TASK_UNINTERRUPTIBLE);
106 schedule_timeout(wait);
107 }
108}
109
110static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data)
111{
112 struct omap_dss_device *in = ddata->in;
113 int r;
114 u8 buf[1];
115
116 r = in->ops.dsi->dcs_read(in, ddata->channel, dcs_cmd, buf, 1);
117
118 if (r < 0)
119 return r;
120
121 *data = buf[0];
122
123 return 0;
124}
125
126static int dsicm_dcs_write_0(struct panel_drv_data *ddata, u8 dcs_cmd)
127{
128 struct omap_dss_device *in = ddata->in;
129 return in->ops.dsi->dcs_write(in, ddata->channel, &dcs_cmd, 1);
130}
131
132static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 param)
133{
134 struct omap_dss_device *in = ddata->in;
135 u8 buf[2] = { dcs_cmd, param };
136
137 return in->ops.dsi->dcs_write(in, ddata->channel, buf, 2);
138}
139
140static int dsicm_sleep_in(struct panel_drv_data *ddata)
141
142{
143 struct omap_dss_device *in = ddata->in;
144 u8 cmd;
145 int r;
146
147 hw_guard_wait(ddata);
148
149 cmd = MIPI_DCS_ENTER_SLEEP_MODE;
150 r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, &cmd, 1);
151 if (r)
152 return r;
153
154 hw_guard_start(ddata, 120);
155
156 usleep_range(5000, 10000);
157
158 return 0;
159}
160
161static int dsicm_sleep_out(struct panel_drv_data *ddata)
162{
163 int r;
164
165 hw_guard_wait(ddata);
166
167 r = dsicm_dcs_write_0(ddata, MIPI_DCS_EXIT_SLEEP_MODE);
168 if (r)
169 return r;
170
171 hw_guard_start(ddata, 120);
172
173 usleep_range(5000, 10000);
174
175 return 0;
176}
177
178static int dsicm_get_id(struct panel_drv_data *ddata, u8 *id1, u8 *id2, u8 *id3)
179{
180 int r;
181
182 r = dsicm_dcs_read_1(ddata, DCS_GET_ID1, id1);
183 if (r)
184 return r;
185 r = dsicm_dcs_read_1(ddata, DCS_GET_ID2, id2);
186 if (r)
187 return r;
188 r = dsicm_dcs_read_1(ddata, DCS_GET_ID3, id3);
189 if (r)
190 return r;
191
192 return 0;
193}
194
195static int dsicm_set_update_window(struct panel_drv_data *ddata,
196 u16 x, u16 y, u16 w, u16 h)
197{
198 struct omap_dss_device *in = ddata->in;
199 int r;
200 u16 x1 = x;
201 u16 x2 = x + w - 1;
202 u16 y1 = y;
203 u16 y2 = y + h - 1;
204
205 u8 buf[5];
206 buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
207 buf[1] = (x1 >> 8) & 0xff;
208 buf[2] = (x1 >> 0) & 0xff;
209 buf[3] = (x2 >> 8) & 0xff;
210 buf[4] = (x2 >> 0) & 0xff;
211
212 r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, buf, sizeof(buf));
213 if (r)
214 return r;
215
216 buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
217 buf[1] = (y1 >> 8) & 0xff;
218 buf[2] = (y1 >> 0) & 0xff;
219 buf[3] = (y2 >> 8) & 0xff;
220 buf[4] = (y2 >> 0) & 0xff;
221
222 r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, buf, sizeof(buf));
223 if (r)
224 return r;
225
226 in->ops.dsi->bta_sync(in, ddata->channel);
227
228 return r;
229}
230
231static void dsicm_queue_ulps_work(struct panel_drv_data *ddata)
232{
233 if (ddata->ulps_timeout > 0)
234 queue_delayed_work(ddata->workqueue, &ddata->ulps_work,
235 msecs_to_jiffies(ddata->ulps_timeout));
236}
237
238static void dsicm_cancel_ulps_work(struct panel_drv_data *ddata)
239{
240 cancel_delayed_work(&ddata->ulps_work);
241}
242
243static int dsicm_enter_ulps(struct panel_drv_data *ddata)
244{
245 struct omap_dss_device *in = ddata->in;
246 int r;
247
248 if (ddata->ulps_enabled)
249 return 0;
250
251 dsicm_cancel_ulps_work(ddata);
252
253 r = _dsicm_enable_te(ddata, false);
254 if (r)
255 goto err;
256
257 if (gpio_is_valid(ddata->ext_te_gpio))
258 disable_irq(gpio_to_irq(ddata->ext_te_gpio));
259
260 in->ops.dsi->disable(in, false, true);
261
262 ddata->ulps_enabled = true;
263
264 return 0;
265
266err:
267 dev_err(&ddata->pdev->dev, "enter ULPS failed");
268 dsicm_panel_reset(ddata);
269
270 ddata->ulps_enabled = false;
271
272 dsicm_queue_ulps_work(ddata);
273
274 return r;
275}
276
277static int dsicm_exit_ulps(struct panel_drv_data *ddata)
278{
279 struct omap_dss_device *in = ddata->in;
280 int r;
281
282 if (!ddata->ulps_enabled)
283 return 0;
284
285 r = in->ops.dsi->enable(in);
286 if (r) {
287 dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
288 goto err1;
289 }
290
291 in->ops.dsi->enable_hs(in, ddata->channel, true);
292
293 r = _dsicm_enable_te(ddata, true);
294 if (r) {
295 dev_err(&ddata->pdev->dev, "failed to re-enable TE");
296 goto err2;
297 }
298
299 if (gpio_is_valid(ddata->ext_te_gpio))
300 enable_irq(gpio_to_irq(ddata->ext_te_gpio));
301
302 dsicm_queue_ulps_work(ddata);
303
304 ddata->ulps_enabled = false;
305
306 return 0;
307
308err2:
309 dev_err(&ddata->pdev->dev, "failed to exit ULPS");
310
311 r = dsicm_panel_reset(ddata);
312 if (!r) {
313 if (gpio_is_valid(ddata->ext_te_gpio))
314 enable_irq(gpio_to_irq(ddata->ext_te_gpio));
315 ddata->ulps_enabled = false;
316 }
317err1:
318 dsicm_queue_ulps_work(ddata);
319
320 return r;
321}
322
323static int dsicm_wake_up(struct panel_drv_data *ddata)
324{
325 if (ddata->ulps_enabled)
326 return dsicm_exit_ulps(ddata);
327
328 dsicm_cancel_ulps_work(ddata);
329 dsicm_queue_ulps_work(ddata);
330 return 0;
331}
332
333static int dsicm_bl_update_status(struct backlight_device *dev)
334{
335 struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
336 struct omap_dss_device *in = ddata->in;
337 int r;
338 int level;
339
340 if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
341 dev->props.power == FB_BLANK_UNBLANK)
342 level = dev->props.brightness;
343 else
344 level = 0;
345
346 dev_dbg(&ddata->pdev->dev, "update brightness to %d\n", level);
347
348 mutex_lock(&ddata->lock);
349
350 if (ddata->enabled) {
351 in->ops.dsi->bus_lock(in);
352
353 r = dsicm_wake_up(ddata);
354 if (!r)
355 r = dsicm_dcs_write_1(ddata, DCS_BRIGHTNESS, level);
356
357 in->ops.dsi->bus_unlock(in);
358 } else {
359 r = 0;
360 }
361
362 mutex_unlock(&ddata->lock);
363
364 return r;
365}
366
367static int dsicm_bl_get_intensity(struct backlight_device *dev)
368{
369 if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
370 dev->props.power == FB_BLANK_UNBLANK)
371 return dev->props.brightness;
372
373 return 0;
374}
375
376static const struct backlight_ops dsicm_bl_ops = {
377 .get_brightness = dsicm_bl_get_intensity,
378 .update_status = dsicm_bl_update_status,
379};
380
381static void dsicm_get_resolution(struct omap_dss_device *dssdev,
382 u16 *xres, u16 *yres)
383{
384 *xres = dssdev->panel.timings.x_res;
385 *yres = dssdev->panel.timings.y_res;
386}
387
388static ssize_t dsicm_num_errors_show(struct device *dev,
389 struct device_attribute *attr, char *buf)
390{
391 struct platform_device *pdev = to_platform_device(dev);
392 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
393 struct omap_dss_device *in = ddata->in;
394 u8 errors = 0;
395 int r;
396
397 mutex_lock(&ddata->lock);
398
399 if (ddata->enabled) {
400 in->ops.dsi->bus_lock(in);
401
402 r = dsicm_wake_up(ddata);
403 if (!r)
404 r = dsicm_dcs_read_1(ddata, DCS_READ_NUM_ERRORS,
405 &errors);
406
407 in->ops.dsi->bus_unlock(in);
408 } else {
409 r = -ENODEV;
410 }
411
412 mutex_unlock(&ddata->lock);
413
414 if (r)
415 return r;
416
417 return snprintf(buf, PAGE_SIZE, "%d\n", errors);
418}
419
420static ssize_t dsicm_hw_revision_show(struct device *dev,
421 struct device_attribute *attr, char *buf)
422{
423 struct platform_device *pdev = to_platform_device(dev);
424 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
425 struct omap_dss_device *in = ddata->in;
426 u8 id1, id2, id3;
427 int r;
428
429 mutex_lock(&ddata->lock);
430
431 if (ddata->enabled) {
432 in->ops.dsi->bus_lock(in);
433
434 r = dsicm_wake_up(ddata);
435 if (!r)
436 r = dsicm_get_id(ddata, &id1, &id2, &id3);
437
438 in->ops.dsi->bus_unlock(in);
439 } else {
440 r = -ENODEV;
441 }
442
443 mutex_unlock(&ddata->lock);
444
445 if (r)
446 return r;
447
448 return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
449}
450
451static ssize_t dsicm_store_ulps(struct device *dev,
452 struct device_attribute *attr,
453 const char *buf, size_t count)
454{
455 struct platform_device *pdev = to_platform_device(dev);
456 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
457 struct omap_dss_device *in = ddata->in;
458 unsigned long t;
459 int r;
460
461 r = kstrtoul(buf, 0, &t);
462 if (r)
463 return r;
464
465 mutex_lock(&ddata->lock);
466
467 if (ddata->enabled) {
468 in->ops.dsi->bus_lock(in);
469
470 if (t)
471 r = dsicm_enter_ulps(ddata);
472 else
473 r = dsicm_wake_up(ddata);
474
475 in->ops.dsi->bus_unlock(in);
476 }
477
478 mutex_unlock(&ddata->lock);
479
480 if (r)
481 return r;
482
483 return count;
484}
485
486static ssize_t dsicm_show_ulps(struct device *dev,
487 struct device_attribute *attr,
488 char *buf)
489{
490 struct platform_device *pdev = to_platform_device(dev);
491 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
492 unsigned t;
493
494 mutex_lock(&ddata->lock);
495 t = ddata->ulps_enabled;
496 mutex_unlock(&ddata->lock);
497
498 return snprintf(buf, PAGE_SIZE, "%u\n", t);
499}
500
501static ssize_t dsicm_store_ulps_timeout(struct device *dev,
502 struct device_attribute *attr,
503 const char *buf, size_t count)
504{
505 struct platform_device *pdev = to_platform_device(dev);
506 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
507 struct omap_dss_device *in = ddata->in;
508 unsigned long t;
509 int r;
510
511 r = kstrtoul(buf, 0, &t);
512 if (r)
513 return r;
514
515 mutex_lock(&ddata->lock);
516 ddata->ulps_timeout = t;
517
518 if (ddata->enabled) {
519 /* dsicm_wake_up will restart the timer */
520 in->ops.dsi->bus_lock(in);
521 r = dsicm_wake_up(ddata);
522 in->ops.dsi->bus_unlock(in);
523 }
524
525 mutex_unlock(&ddata->lock);
526
527 if (r)
528 return r;
529
530 return count;
531}
532
533static ssize_t dsicm_show_ulps_timeout(struct device *dev,
534 struct device_attribute *attr,
535 char *buf)
536{
537 struct platform_device *pdev = to_platform_device(dev);
538 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
539 unsigned t;
540
541 mutex_lock(&ddata->lock);
542 t = ddata->ulps_timeout;
543 mutex_unlock(&ddata->lock);
544
545 return snprintf(buf, PAGE_SIZE, "%u\n", t);
546}
547
548static DEVICE_ATTR(num_dsi_errors, S_IRUGO, dsicm_num_errors_show, NULL);
549static DEVICE_ATTR(hw_revision, S_IRUGO, dsicm_hw_revision_show, NULL);
550static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
551 dsicm_show_ulps, dsicm_store_ulps);
552static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,
553 dsicm_show_ulps_timeout, dsicm_store_ulps_timeout);
554
555static struct attribute *dsicm_attrs[] = {
556 &dev_attr_num_dsi_errors.attr,
557 &dev_attr_hw_revision.attr,
558 &dev_attr_ulps.attr,
559 &dev_attr_ulps_timeout.attr,
560 NULL,
561};
562
563static struct attribute_group dsicm_attr_group = {
564 .attrs = dsicm_attrs,
565};
566
567static void dsicm_hw_reset(struct panel_drv_data *ddata)
568{
569 if (!gpio_is_valid(ddata->reset_gpio))
570 return;
571
572 gpio_set_value(ddata->reset_gpio, 1);
573 udelay(10);
574 /* reset the panel */
575 gpio_set_value(ddata->reset_gpio, 0);
576 /* assert reset */
577 udelay(10);
578 gpio_set_value(ddata->reset_gpio, 1);
579 /* wait after releasing reset */
580 usleep_range(5000, 10000);
581}
582
583static int dsicm_power_on(struct panel_drv_data *ddata)
584{
585 struct omap_dss_device *in = ddata->in;
586 u8 id1, id2, id3;
587 int r;
588 struct omap_dss_dsi_config dsi_config = {
589 .mode = OMAP_DSS_DSI_CMD_MODE,
590 .pixel_format = OMAP_DSS_DSI_FMT_RGB888,
591 .timings = &ddata->timings,
592 .hs_clk_min = 150000000,
593 .hs_clk_max = 300000000,
594 .lp_clk_min = 7000000,
595 .lp_clk_max = 10000000,
596 };
597
598 r = in->ops.dsi->configure_pins(in, &ddata->pin_config);
599 if (r) {
600 dev_err(&ddata->pdev->dev, "failed to configure DSI pins\n");
601 goto err0;
602 };
603
604 r = in->ops.dsi->set_config(in, &dsi_config);
605 if (r) {
606 dev_err(&ddata->pdev->dev, "failed to configure DSI\n");
607 goto err0;
608 }
609
610 r = in->ops.dsi->enable(in);
611 if (r) {
612 dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
613 goto err0;
614 }
615
616 dsicm_hw_reset(ddata);
617
618 in->ops.dsi->enable_hs(in, ddata->channel, false);
619
620 r = dsicm_sleep_out(ddata);
621 if (r)
622 goto err;
623
624 r = dsicm_get_id(ddata, &id1, &id2, &id3);
625 if (r)
626 goto err;
627
628 r = dsicm_dcs_write_1(ddata, DCS_BRIGHTNESS, 0xff);
629 if (r)
630 goto err;
631
632 r = dsicm_dcs_write_1(ddata, DCS_CTRL_DISPLAY,
633 (1<<2) | (1<<5)); /* BL | BCTRL */
634 if (r)
635 goto err;
636
637 r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_PIXEL_FORMAT,
638 MIPI_DCS_PIXEL_FMT_24BIT);
639 if (r)
640 goto err;
641
642 r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_DISPLAY_ON);
643 if (r)
644 goto err;
645
646 r = _dsicm_enable_te(ddata, ddata->te_enabled);
647 if (r)
648 goto err;
649
650 r = in->ops.dsi->enable_video_output(in, ddata->channel);
651 if (r)
652 goto err;
653
654 ddata->enabled = 1;
655
656 if (!ddata->intro_printed) {
657 dev_info(&ddata->pdev->dev, "panel revision %02x.%02x.%02x\n",
658 id1, id2, id3);
659 ddata->intro_printed = true;
660 }
661
662 in->ops.dsi->enable_hs(in, ddata->channel, true);
663
664 return 0;
665err:
666 dev_err(&ddata->pdev->dev, "error while enabling panel, issuing HW reset\n");
667
668 dsicm_hw_reset(ddata);
669
670 in->ops.dsi->disable(in, true, false);
671err0:
672 return r;
673}
674
675static void dsicm_power_off(struct panel_drv_data *ddata)
676{
677 struct omap_dss_device *in = ddata->in;
678 int r;
679
680 in->ops.dsi->disable_video_output(in, ddata->channel);
681
682 r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_DISPLAY_OFF);
683 if (!r)
684 r = dsicm_sleep_in(ddata);
685
686 if (r) {
687 dev_err(&ddata->pdev->dev,
688 "error disabling panel, issuing HW reset\n");
689 dsicm_hw_reset(ddata);
690 }
691
692 in->ops.dsi->disable(in, true, false);
693
694 ddata->enabled = 0;
695}
696
697static int dsicm_panel_reset(struct panel_drv_data *ddata)
698{
699 dev_err(&ddata->pdev->dev, "performing LCD reset\n");
700
701 dsicm_power_off(ddata);
702 dsicm_hw_reset(ddata);
703 return dsicm_power_on(ddata);
704}
705
706static int dsicm_connect(struct omap_dss_device *dssdev)
707{
708 struct panel_drv_data *ddata = to_panel_data(dssdev);
709 struct omap_dss_device *in = ddata->in;
710 struct device *dev = &ddata->pdev->dev;
711 int r;
712
713 if (omapdss_device_is_connected(dssdev))
714 return 0;
715
716 r = in->ops.dsi->connect(in, dssdev);
717 if (r) {
718 dev_err(dev, "Failed to connect to video source\n");
719 return r;
720 }
721
722 r = in->ops.dsi->request_vc(ddata->in, &ddata->channel);
723 if (r) {
724 dev_err(dev, "failed to get virtual channel\n");
725 goto err_req_vc;
726 }
727
728 r = in->ops.dsi->set_vc_id(ddata->in, ddata->channel, TCH);
729 if (r) {
730 dev_err(dev, "failed to set VC_ID\n");
731 goto err_vc_id;
732 }
733
734 return 0;
735
736err_vc_id:
737 in->ops.dsi->release_vc(ddata->in, ddata->channel);
738err_req_vc:
739 in->ops.dsi->disconnect(in, dssdev);
740 return r;
741}
742
743static void dsicm_disconnect(struct omap_dss_device *dssdev)
744{
745 struct panel_drv_data *ddata = to_panel_data(dssdev);
746 struct omap_dss_device *in = ddata->in;
747
748 if (!omapdss_device_is_connected(dssdev))
749 return;
750
751 in->ops.dsi->release_vc(in, ddata->channel);
752 in->ops.dsi->disconnect(in, dssdev);
753}
754
755static int dsicm_enable(struct omap_dss_device *dssdev)
756{
757 struct panel_drv_data *ddata = to_panel_data(dssdev);
758 struct omap_dss_device *in = ddata->in;
759 int r;
760
761 dev_dbg(&ddata->pdev->dev, "enable\n");
762
763 mutex_lock(&ddata->lock);
764
765 if (!omapdss_device_is_connected(dssdev)) {
766 r = -ENODEV;
767 goto err;
768 }
769
770 if (omapdss_device_is_enabled(dssdev)) {
771 r = 0;
772 goto err;
773 }
774
775 in->ops.dsi->bus_lock(in);
776
777 r = dsicm_power_on(ddata);
778
779 in->ops.dsi->bus_unlock(in);
780
781 if (r)
782 goto err;
783
784 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
785
786 mutex_unlock(&ddata->lock);
787
788 return 0;
789err:
790 dev_dbg(&ddata->pdev->dev, "enable failed\n");
791 mutex_unlock(&ddata->lock);
792 return r;
793}
794
795static void dsicm_disable(struct omap_dss_device *dssdev)
796{
797 struct panel_drv_data *ddata = to_panel_data(dssdev);
798 struct omap_dss_device *in = ddata->in;
799 int r;
800
801 dev_dbg(&ddata->pdev->dev, "disable\n");
802
803 mutex_lock(&ddata->lock);
804
805 dsicm_cancel_ulps_work(ddata);
806
807 in->ops.dsi->bus_lock(in);
808
809 if (omapdss_device_is_enabled(dssdev)) {
810 r = dsicm_wake_up(ddata);
811 if (!r)
812 dsicm_power_off(ddata);
813 }
814
815 in->ops.dsi->bus_unlock(in);
816
817 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
818
819 mutex_unlock(&ddata->lock);
820}
821
822static void dsicm_framedone_cb(int err, void *data)
823{
824 struct panel_drv_data *ddata = data;
825 struct omap_dss_device *in = ddata->in;
826
827 dev_dbg(&ddata->pdev->dev, "framedone, err %d\n", err);
828 in->ops.dsi->bus_unlock(ddata->in);
829}
830
831static irqreturn_t dsicm_te_isr(int irq, void *data)
832{
833 struct panel_drv_data *ddata = data;
834 struct omap_dss_device *in = ddata->in;
835 int old;
836 int r;
837
838 old = atomic_cmpxchg(&ddata->do_update, 1, 0);
839
840 if (old) {
841 cancel_delayed_work(&ddata->te_timeout_work);
842
843 r = in->ops.dsi->update(in, ddata->channel, dsicm_framedone_cb,
844 ddata);
845 if (r)
846 goto err;
847 }
848
849 return IRQ_HANDLED;
850err:
851 dev_err(&ddata->pdev->dev, "start update failed\n");
852 in->ops.dsi->bus_unlock(in);
853 return IRQ_HANDLED;
854}
855
856static void dsicm_te_timeout_work_callback(struct work_struct *work)
857{
858 struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
859 te_timeout_work.work);
860 struct omap_dss_device *in = ddata->in;
861
862 dev_err(&ddata->pdev->dev, "TE not received for 250ms!\n");
863
864 atomic_set(&ddata->do_update, 0);
865 in->ops.dsi->bus_unlock(in);
866}
867
868static int dsicm_update(struct omap_dss_device *dssdev,
869 u16 x, u16 y, u16 w, u16 h)
870{
871 struct panel_drv_data *ddata = to_panel_data(dssdev);
872 struct omap_dss_device *in = ddata->in;
873 int r;
874
875 dev_dbg(&ddata->pdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
876
877 mutex_lock(&ddata->lock);
878 in->ops.dsi->bus_lock(in);
879
880 r = dsicm_wake_up(ddata);
881 if (r)
882 goto err;
883
884 if (!ddata->enabled) {
885 r = 0;
886 goto err;
887 }
888
889 /* XXX no need to send this every frame, but dsi break if not done */
890 r = dsicm_set_update_window(ddata, 0, 0,
891 dssdev->panel.timings.x_res,
892 dssdev->panel.timings.y_res);
893 if (r)
894 goto err;
895
896 if (ddata->te_enabled && gpio_is_valid(ddata->ext_te_gpio)) {
897 schedule_delayed_work(&ddata->te_timeout_work,
898 msecs_to_jiffies(250));
899 atomic_set(&ddata->do_update, 1);
900 } else {
901 r = in->ops.dsi->update(in, ddata->channel, dsicm_framedone_cb,
902 ddata);
903 if (r)
904 goto err;
905 }
906
907 /* note: no bus_unlock here. unlock is in framedone_cb */
908 mutex_unlock(&ddata->lock);
909 return 0;
910err:
911 in->ops.dsi->bus_unlock(in);
912 mutex_unlock(&ddata->lock);
913 return r;
914}
915
916static int dsicm_sync(struct omap_dss_device *dssdev)
917{
918 struct panel_drv_data *ddata = to_panel_data(dssdev);
919 struct omap_dss_device *in = ddata->in;
920
921 dev_dbg(&ddata->pdev->dev, "sync\n");
922
923 mutex_lock(&ddata->lock);
924 in->ops.dsi->bus_lock(in);
925 in->ops.dsi->bus_unlock(in);
926 mutex_unlock(&ddata->lock);
927
928 dev_dbg(&ddata->pdev->dev, "sync done\n");
929
930 return 0;
931}
932
933static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
934{
935 struct omap_dss_device *in = ddata->in;
936 int r;
937
938 if (enable)
939 r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_TEAR_ON, 0);
940 else
941 r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_TEAR_OFF);
942
943 if (!gpio_is_valid(ddata->ext_te_gpio))
944 in->ops.dsi->enable_te(in, enable);
945
946 /* possible panel bug */
947 msleep(100);
948
949 return r;
950}
951
952static int dsicm_enable_te(struct omap_dss_device *dssdev, bool enable)
953{
954 struct panel_drv_data *ddata = to_panel_data(dssdev);
955 struct omap_dss_device *in = ddata->in;
956 int r;
957
958 mutex_lock(&ddata->lock);
959
960 if (ddata->te_enabled == enable)
961 goto end;
962
963 in->ops.dsi->bus_lock(in);
964
965 if (ddata->enabled) {
966 r = dsicm_wake_up(ddata);
967 if (r)
968 goto err;
969
970 r = _dsicm_enable_te(ddata, enable);
971 if (r)
972 goto err;
973 }
974
975 ddata->te_enabled = enable;
976
977 in->ops.dsi->bus_unlock(in);
978end:
979 mutex_unlock(&ddata->lock);
980
981 return 0;
982err:
983 in->ops.dsi->bus_unlock(in);
984 mutex_unlock(&ddata->lock);
985
986 return r;
987}
988
989static int dsicm_get_te(struct omap_dss_device *dssdev)
990{
991 struct panel_drv_data *ddata = to_panel_data(dssdev);
992 int r;
993
994 mutex_lock(&ddata->lock);
995 r = ddata->te_enabled;
996 mutex_unlock(&ddata->lock);
997
998 return r;
999}
1000
1001static int dsicm_memory_read(struct omap_dss_device *dssdev,
1002 void *buf, size_t size,
1003 u16 x, u16 y, u16 w, u16 h)
1004{
1005 struct panel_drv_data *ddata = to_panel_data(dssdev);
1006 struct omap_dss_device *in = ddata->in;
1007 int r;
1008 int first = 1;
1009 int plen;
1010 unsigned buf_used = 0;
1011
1012 if (size < w * h * 3)
1013 return -ENOMEM;
1014
1015 mutex_lock(&ddata->lock);
1016
1017 if (!ddata->enabled) {
1018 r = -ENODEV;
1019 goto err1;
1020 }
1021
1022 size = min(w * h * 3,
1023 dssdev->panel.timings.x_res *
1024 dssdev->panel.timings.y_res * 3);
1025
1026 in->ops.dsi->bus_lock(in);
1027
1028 r = dsicm_wake_up(ddata);
1029 if (r)
1030 goto err2;
1031
1032 /* plen 1 or 2 goes into short packet. until checksum error is fixed,
1033 * use short packets. plen 32 works, but bigger packets seem to cause
1034 * an error. */
1035 if (size % 2)
1036 plen = 1;
1037 else
1038 plen = 2;
1039
1040 dsicm_set_update_window(ddata, x, y, w, h);
1041
1042 r = in->ops.dsi->set_max_rx_packet_size(in, ddata->channel, plen);
1043 if (r)
1044 goto err2;
1045
1046 while (buf_used < size) {
1047 u8 dcs_cmd = first ? 0x2e : 0x3e;
1048 first = 0;
1049
1050 r = in->ops.dsi->dcs_read(in, ddata->channel, dcs_cmd,
1051 buf + buf_used, size - buf_used);
1052
1053 if (r < 0) {
1054 dev_err(dssdev->dev, "read error\n");
1055 goto err3;
1056 }
1057
1058 buf_used += r;
1059
1060 if (r < plen) {
1061 dev_err(&ddata->pdev->dev, "short read\n");
1062 break;
1063 }
1064
1065 if (signal_pending(current)) {
1066 dev_err(&ddata->pdev->dev, "signal pending, "
1067 "aborting memory read\n");
1068 r = -ERESTARTSYS;
1069 goto err3;
1070 }
1071 }
1072
1073 r = buf_used;
1074
1075err3:
1076 in->ops.dsi->set_max_rx_packet_size(in, ddata->channel, 1);
1077err2:
1078 in->ops.dsi->bus_unlock(in);
1079err1:
1080 mutex_unlock(&ddata->lock);
1081 return r;
1082}
1083
1084static void dsicm_ulps_work(struct work_struct *work)
1085{
1086 struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
1087 ulps_work.work);
1088 struct omap_dss_device *dssdev = &ddata->dssdev;
1089 struct omap_dss_device *in = ddata->in;
1090
1091 mutex_lock(&ddata->lock);
1092
1093 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !ddata->enabled) {
1094 mutex_unlock(&ddata->lock);
1095 return;
1096 }
1097
1098 in->ops.dsi->bus_lock(in);
1099
1100 dsicm_enter_ulps(ddata);
1101
1102 in->ops.dsi->bus_unlock(in);
1103 mutex_unlock(&ddata->lock);
1104}
1105
1106static struct omap_dss_driver dsicm_ops = {
1107 .connect = dsicm_connect,
1108 .disconnect = dsicm_disconnect,
1109
1110 .enable = dsicm_enable,
1111 .disable = dsicm_disable,
1112
1113 .update = dsicm_update,
1114 .sync = dsicm_sync,
1115
1116 .get_resolution = dsicm_get_resolution,
1117 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
1118
1119 .enable_te = dsicm_enable_te,
1120 .get_te = dsicm_get_te,
1121
1122 .memory_read = dsicm_memory_read,
1123};
1124
1125static int dsicm_probe_pdata(struct platform_device *pdev)
1126{
1127 const struct panel_dsicm_platform_data *pdata;
1128 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
1129 struct omap_dss_device *dssdev, *in;
1130
1131 pdata = dev_get_platdata(&pdev->dev);
1132
1133 in = omap_dss_find_output(pdata->source);
1134 if (in == NULL) {
1135 dev_err(&pdev->dev, "failed to find video source\n");
1136 return -EPROBE_DEFER;
1137 }
1138 ddata->in = in;
1139
1140 ddata->reset_gpio = pdata->reset_gpio;
1141
1142 if (pdata->use_ext_te)
1143 ddata->ext_te_gpio = pdata->ext_te_gpio;
1144 else
1145 ddata->ext_te_gpio = -1;
1146
1147 ddata->ulps_timeout = pdata->ulps_timeout;
1148
1149 ddata->use_dsi_backlight = pdata->use_dsi_backlight;
1150
1151 ddata->pin_config = pdata->pin_config;
1152
1153 dssdev = &ddata->dssdev;
1154 dssdev->name = pdata->name;
1155
1156 return 0;
1157}
1158
1159static int dsicm_probe(struct platform_device *pdev)
1160{
1161 struct backlight_properties props;
1162 struct panel_drv_data *ddata;
1163 struct backlight_device *bldev = NULL;
1164 struct device *dev = &pdev->dev;
1165 struct omap_dss_device *dssdev;
1166 int r;
1167
1168 dev_dbg(dev, "probe\n");
1169
1170 ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
1171 if (!ddata)
1172 return -ENOMEM;
1173
1174 platform_set_drvdata(pdev, ddata);
1175 ddata->pdev = pdev;
1176
1177 if (dev_get_platdata(dev)) {
1178 r = dsicm_probe_pdata(pdev);
1179 if (r)
1180 return r;
1181 } else {
1182 return -ENODEV;
1183 }
1184
1185 ddata->timings.x_res = 864;
1186 ddata->timings.y_res = 480;
1187 ddata->timings.pixel_clock = DIV_ROUND_UP(864 * 480 * 60, 1000);
1188
1189 dssdev = &ddata->dssdev;
1190 dssdev->dev = dev;
1191 dssdev->driver = &dsicm_ops;
1192 dssdev->panel.timings = ddata->timings;
1193 dssdev->type = OMAP_DISPLAY_TYPE_DSI;
1194 dssdev->owner = THIS_MODULE;
1195
1196 dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
1197 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
1198 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
1199
1200 r = omapdss_register_display(dssdev);
1201 if (r) {
1202 dev_err(dev, "Failed to register panel\n");
1203 goto err_reg;
1204 }
1205
1206 mutex_init(&ddata->lock);
1207
1208 atomic_set(&ddata->do_update, 0);
1209
1210 if (gpio_is_valid(ddata->reset_gpio)) {
1211 r = devm_gpio_request_one(dev, ddata->reset_gpio,
1212 GPIOF_OUT_INIT_LOW, "taal rst");
1213 if (r) {
1214 dev_err(dev, "failed to request reset gpio\n");
1215 return r;
1216 }
1217 }
1218
1219 if (gpio_is_valid(ddata->ext_te_gpio)) {
1220 r = devm_gpio_request_one(dev, ddata->ext_te_gpio,
1221 GPIOF_IN, "taal irq");
1222 if (r) {
1223 dev_err(dev, "GPIO request failed\n");
1224 return r;
1225 }
1226
1227 r = devm_request_irq(dev, gpio_to_irq(ddata->ext_te_gpio),
1228 dsicm_te_isr,
1229 IRQF_TRIGGER_RISING,
1230 "taal vsync", ddata);
1231
1232 if (r) {
1233 dev_err(dev, "IRQ request failed\n");
1234 return r;
1235 }
1236
1237 INIT_DEFERRABLE_WORK(&ddata->te_timeout_work,
1238 dsicm_te_timeout_work_callback);
1239
1240 dev_dbg(dev, "Using GPIO TE\n");
1241 }
1242
1243 ddata->workqueue = create_singlethread_workqueue("dsicm_wq");
1244 if (ddata->workqueue == NULL) {
1245 dev_err(dev, "can't create workqueue\n");
1246 return -ENOMEM;
1247 }
1248 INIT_DELAYED_WORK(&ddata->ulps_work, dsicm_ulps_work);
1249
1250 dsicm_hw_reset(ddata);
1251
1252 if (ddata->use_dsi_backlight) {
1253 memset(&props, 0, sizeof(struct backlight_properties));
1254 props.max_brightness = 255;
1255
1256 props.type = BACKLIGHT_RAW;
1257 bldev = backlight_device_register(dev_name(dev),
1258 dev, ddata, &dsicm_bl_ops, &props);
1259 if (IS_ERR(bldev)) {
1260 r = PTR_ERR(bldev);
1261 goto err_bl;
1262 }
1263
1264 ddata->bldev = bldev;
1265
1266 bldev->props.fb_blank = FB_BLANK_UNBLANK;
1267 bldev->props.power = FB_BLANK_UNBLANK;
1268 bldev->props.brightness = 255;
1269
1270 dsicm_bl_update_status(bldev);
1271 }
1272
1273 r = sysfs_create_group(&dev->kobj, &dsicm_attr_group);
1274 if (r) {
1275 dev_err(dev, "failed to create sysfs files\n");
1276 goto err_sysfs_create;
1277 }
1278
1279 return 0;
1280
1281err_sysfs_create:
1282 if (bldev != NULL)
1283 backlight_device_unregister(bldev);
1284err_bl:
1285 destroy_workqueue(ddata->workqueue);
1286err_reg:
1287 return r;
1288}
1289
1290static int __exit dsicm_remove(struct platform_device *pdev)
1291{
1292 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
1293 struct omap_dss_device *dssdev = &ddata->dssdev;
1294 struct backlight_device *bldev;
1295
1296 dev_dbg(&pdev->dev, "remove\n");
1297
1298 omapdss_unregister_display(dssdev);
1299
1300 dsicm_disable(dssdev);
1301 dsicm_disconnect(dssdev);
1302
1303 sysfs_remove_group(&pdev->dev.kobj, &dsicm_attr_group);
1304
1305 bldev = ddata->bldev;
1306 if (bldev != NULL) {
1307 bldev->props.power = FB_BLANK_POWERDOWN;
1308 dsicm_bl_update_status(bldev);
1309 backlight_device_unregister(bldev);
1310 }
1311
1312 omap_dss_put_device(ddata->in);
1313
1314 dsicm_cancel_ulps_work(ddata);
1315 destroy_workqueue(ddata->workqueue);
1316
1317 /* reset, to be sure that the panel is in a valid state */
1318 dsicm_hw_reset(ddata);
1319
1320 return 0;
1321}
1322
1323static struct platform_driver dsicm_driver = {
1324 .probe = dsicm_probe,
1325 .remove = __exit_p(dsicm_remove),
1326 .driver = {
1327 .name = "panel-dsi-cm",
1328 .owner = THIS_MODULE,
1329 },
1330};
1331
1332module_platform_driver(dsicm_driver);
1333
1334MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
1335MODULE_DESCRIPTION("Generic DSI Command Mode Panel Driver");
1336MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c
new file mode 100644
index 000000000000..6e8977b18950
--- /dev/null
+++ b/drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c
@@ -0,0 +1,358 @@
1/*
2 * LG.Philips LB035Q02 LCD Panel driver
3 *
4 * Copyright (C) 2013 Texas Instruments
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 * Based on a driver by: Steve Sakoman <steve@sakoman.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/delay.h>
15#include <linux/spi/spi.h>
16#include <linux/mutex.h>
17#include <linux/gpio.h>
18
19#include <video/omapdss.h>
20#include <video/omap-panel-data.h>
21
22static struct omap_video_timings lb035q02_timings = {
23 .x_res = 320,
24 .y_res = 240,
25
26 .pixel_clock = 6500,
27
28 .hsw = 2,
29 .hfp = 20,
30 .hbp = 68,
31
32 .vsw = 2,
33 .vfp = 4,
34 .vbp = 18,
35
36 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
37 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
38 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
39 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
40 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
41};
42
43struct panel_drv_data {
44 struct omap_dss_device dssdev;
45 struct omap_dss_device *in;
46
47 struct spi_device *spi;
48
49 int data_lines;
50
51 struct omap_video_timings videomode;
52
53 int reset_gpio;
54 int backlight_gpio;
55 int enable_gpio;
56};
57
58#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
59
60static int lb035q02_write_reg(struct spi_device *spi, u8 reg, u16 val)
61{
62 struct spi_message msg;
63 struct spi_transfer index_xfer = {
64 .len = 3,
65 .cs_change = 1,
66 };
67 struct spi_transfer value_xfer = {
68 .len = 3,
69 };
70 u8 buffer[16];
71
72 spi_message_init(&msg);
73
74 /* register index */
75 buffer[0] = 0x70;
76 buffer[1] = 0x00;
77 buffer[2] = reg & 0x7f;
78 index_xfer.tx_buf = buffer;
79 spi_message_add_tail(&index_xfer, &msg);
80
81 /* register value */
82 buffer[4] = 0x72;
83 buffer[5] = val >> 8;
84 buffer[6] = val;
85 value_xfer.tx_buf = buffer + 4;
86 spi_message_add_tail(&value_xfer, &msg);
87
88 return spi_sync(spi, &msg);
89}
90
91static void init_lb035q02_panel(struct spi_device *spi)
92{
93 /* Init sequence from page 28 of the lb035q02 spec */
94 lb035q02_write_reg(spi, 0x01, 0x6300);
95 lb035q02_write_reg(spi, 0x02, 0x0200);
96 lb035q02_write_reg(spi, 0x03, 0x0177);
97 lb035q02_write_reg(spi, 0x04, 0x04c7);
98 lb035q02_write_reg(spi, 0x05, 0xffc0);
99 lb035q02_write_reg(spi, 0x06, 0xe806);
100 lb035q02_write_reg(spi, 0x0a, 0x4008);
101 lb035q02_write_reg(spi, 0x0b, 0x0000);
102 lb035q02_write_reg(spi, 0x0d, 0x0030);
103 lb035q02_write_reg(spi, 0x0e, 0x2800);
104 lb035q02_write_reg(spi, 0x0f, 0x0000);
105 lb035q02_write_reg(spi, 0x16, 0x9f80);
106 lb035q02_write_reg(spi, 0x17, 0x0a0f);
107 lb035q02_write_reg(spi, 0x1e, 0x00c1);
108 lb035q02_write_reg(spi, 0x30, 0x0300);
109 lb035q02_write_reg(spi, 0x31, 0x0007);
110 lb035q02_write_reg(spi, 0x32, 0x0000);
111 lb035q02_write_reg(spi, 0x33, 0x0000);
112 lb035q02_write_reg(spi, 0x34, 0x0707);
113 lb035q02_write_reg(spi, 0x35, 0x0004);
114 lb035q02_write_reg(spi, 0x36, 0x0302);
115 lb035q02_write_reg(spi, 0x37, 0x0202);
116 lb035q02_write_reg(spi, 0x3a, 0x0a0d);
117 lb035q02_write_reg(spi, 0x3b, 0x0806);
118}
119
120static int lb035q02_connect(struct omap_dss_device *dssdev)
121{
122 struct panel_drv_data *ddata = to_panel_data(dssdev);
123 struct omap_dss_device *in = ddata->in;
124 int r;
125
126 if (omapdss_device_is_connected(dssdev))
127 return 0;
128
129 r = in->ops.dpi->connect(in, dssdev);
130 if (r)
131 return r;
132
133 init_lb035q02_panel(ddata->spi);
134
135 return 0;
136}
137
138static void lb035q02_disconnect(struct omap_dss_device *dssdev)
139{
140 struct panel_drv_data *ddata = to_panel_data(dssdev);
141 struct omap_dss_device *in = ddata->in;
142
143 if (!omapdss_device_is_connected(dssdev))
144 return;
145
146 in->ops.dpi->disconnect(in, dssdev);
147}
148
149static int lb035q02_enable(struct omap_dss_device *dssdev)
150{
151 struct panel_drv_data *ddata = to_panel_data(dssdev);
152 struct omap_dss_device *in = ddata->in;
153 int r;
154
155 if (!omapdss_device_is_connected(dssdev))
156 return -ENODEV;
157
158 if (omapdss_device_is_enabled(dssdev))
159 return 0;
160
161 in->ops.dpi->set_data_lines(in, ddata->data_lines);
162 in->ops.dpi->set_timings(in, &ddata->videomode);
163
164 r = in->ops.dpi->enable(in);
165 if (r)
166 return r;
167
168 if (gpio_is_valid(ddata->enable_gpio))
169 gpio_set_value_cansleep(ddata->enable_gpio, 1);
170
171 if (gpio_is_valid(ddata->backlight_gpio))
172 gpio_set_value_cansleep(ddata->backlight_gpio, 1);
173
174 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
175
176 return 0;
177}
178
179static void lb035q02_disable(struct omap_dss_device *dssdev)
180{
181 struct panel_drv_data *ddata = to_panel_data(dssdev);
182 struct omap_dss_device *in = ddata->in;
183
184 if (!omapdss_device_is_enabled(dssdev))
185 return;
186
187 if (gpio_is_valid(ddata->enable_gpio))
188 gpio_set_value_cansleep(ddata->enable_gpio, 0);
189
190 if (gpio_is_valid(ddata->backlight_gpio))
191 gpio_set_value_cansleep(ddata->backlight_gpio, 0);
192
193 in->ops.dpi->disable(in);
194
195 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
196}
197
198static void lb035q02_set_timings(struct omap_dss_device *dssdev,
199 struct omap_video_timings *timings)
200{
201 struct panel_drv_data *ddata = to_panel_data(dssdev);
202 struct omap_dss_device *in = ddata->in;
203
204 ddata->videomode = *timings;
205 dssdev->panel.timings = *timings;
206
207 in->ops.dpi->set_timings(in, timings);
208}
209
210static void lb035q02_get_timings(struct omap_dss_device *dssdev,
211 struct omap_video_timings *timings)
212{
213 struct panel_drv_data *ddata = to_panel_data(dssdev);
214
215 *timings = ddata->videomode;
216}
217
218static int lb035q02_check_timings(struct omap_dss_device *dssdev,
219 struct omap_video_timings *timings)
220{
221 struct panel_drv_data *ddata = to_panel_data(dssdev);
222 struct omap_dss_device *in = ddata->in;
223
224 return in->ops.dpi->check_timings(in, timings);
225}
226
227static struct omap_dss_driver lb035q02_ops = {
228 .connect = lb035q02_connect,
229 .disconnect = lb035q02_disconnect,
230
231 .enable = lb035q02_enable,
232 .disable = lb035q02_disable,
233
234 .set_timings = lb035q02_set_timings,
235 .get_timings = lb035q02_get_timings,
236 .check_timings = lb035q02_check_timings,
237
238 .get_resolution = omapdss_default_get_resolution,
239};
240
241static int lb035q02_probe_pdata(struct spi_device *spi)
242{
243 const struct panel_lb035q02_platform_data *pdata;
244 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
245 struct omap_dss_device *dssdev, *in;
246
247 pdata = dev_get_platdata(&spi->dev);
248
249 in = omap_dss_find_output(pdata->source);
250 if (in == NULL) {
251 dev_err(&spi->dev, "failed to find video source '%s'\n",
252 pdata->source);
253 return -EPROBE_DEFER;
254 }
255
256 ddata->in = in;
257
258 ddata->data_lines = pdata->data_lines;
259
260 dssdev = &ddata->dssdev;
261 dssdev->name = pdata->name;
262
263 ddata->enable_gpio = pdata->enable_gpio;
264 ddata->backlight_gpio = pdata->backlight_gpio;
265
266 return 0;
267}
268
269static int lb035q02_panel_spi_probe(struct spi_device *spi)
270{
271 struct panel_drv_data *ddata;
272 struct omap_dss_device *dssdev;
273 int r;
274
275 ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
276 if (ddata == NULL)
277 return -ENOMEM;
278
279 dev_set_drvdata(&spi->dev, ddata);
280
281 ddata->spi = spi;
282
283 if (dev_get_platdata(&spi->dev)) {
284 r = lb035q02_probe_pdata(spi);
285 if (r)
286 return r;
287 } else {
288 return -ENODEV;
289 }
290
291 if (gpio_is_valid(ddata->enable_gpio)) {
292 r = devm_gpio_request_one(&spi->dev, ddata->enable_gpio,
293 GPIOF_OUT_INIT_LOW, "panel enable");
294 if (r)
295 goto err_gpio;
296 }
297
298 if (gpio_is_valid(ddata->backlight_gpio)) {
299 r = devm_gpio_request_one(&spi->dev, ddata->backlight_gpio,
300 GPIOF_OUT_INIT_LOW, "panel backlight");
301 if (r)
302 goto err_gpio;
303 }
304
305 ddata->videomode = lb035q02_timings;
306
307 dssdev = &ddata->dssdev;
308 dssdev->dev = &spi->dev;
309 dssdev->driver = &lb035q02_ops;
310 dssdev->type = OMAP_DISPLAY_TYPE_DPI;
311 dssdev->owner = THIS_MODULE;
312 dssdev->panel.timings = ddata->videomode;
313 dssdev->phy.dpi.data_lines = ddata->data_lines;
314
315 r = omapdss_register_display(dssdev);
316 if (r) {
317 dev_err(&spi->dev, "Failed to register panel\n");
318 goto err_reg;
319 }
320
321 return 0;
322
323err_reg:
324err_gpio:
325 omap_dss_put_device(ddata->in);
326 return r;
327}
328
329static int lb035q02_panel_spi_remove(struct spi_device *spi)
330{
331 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
332 struct omap_dss_device *dssdev = &ddata->dssdev;
333 struct omap_dss_device *in = ddata->in;
334
335 omapdss_unregister_display(dssdev);
336
337 lb035q02_disable(dssdev);
338 lb035q02_disconnect(dssdev);
339
340 omap_dss_put_device(in);
341
342 return 0;
343}
344
345static struct spi_driver lb035q02_spi_driver = {
346 .probe = lb035q02_panel_spi_probe,
347 .remove = lb035q02_panel_spi_remove,
348 .driver = {
349 .name = "panel_lgphilips_lb035q02",
350 .owner = THIS_MODULE,
351 },
352};
353
354module_spi_driver(lb035q02_spi_driver);
355
356MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
357MODULE_DESCRIPTION("LG.Philips LB035Q02 LCD Panel driver");
358MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c b/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c
new file mode 100644
index 000000000000..bb217da65c5f
--- /dev/null
+++ b/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c
@@ -0,0 +1,394 @@
1/*
2 * NEC NL8048HL11 Panel driver
3 *
4 * Copyright (C) 2010 Texas Instruments Inc.
5 * Author: Erik Gilling <konkers@android.com>
6 * Converted to new DSS device model: Tomi Valkeinen <tomi.valkeinen@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/delay.h>
16#include <linux/spi/spi.h>
17#include <linux/fb.h>
18#include <linux/gpio.h>
19
20#include <video/omapdss.h>
21#include <video/omap-panel-data.h>
22
23struct panel_drv_data {
24 struct omap_dss_device dssdev;
25 struct omap_dss_device *in;
26
27 struct omap_video_timings videomode;
28
29 int data_lines;
30
31 int res_gpio;
32 int qvga_gpio;
33
34 struct spi_device *spi;
35};
36
37#define LCD_XRES 800
38#define LCD_YRES 480
39/*
40 * NEC PIX Clock Ratings
41 * MIN:21.8MHz TYP:23.8MHz MAX:25.7MHz
42 */
43#define LCD_PIXEL_CLOCK 23800
44
45static const struct {
46 unsigned char addr;
47 unsigned char dat;
48} nec_8048_init_seq[] = {
49 { 3, 0x01 }, { 0, 0x00 }, { 1, 0x01 }, { 4, 0x00 }, { 5, 0x14 },
50 { 6, 0x24 }, { 16, 0xD7 }, { 17, 0x00 }, { 18, 0x00 }, { 19, 0x55 },
51 { 20, 0x01 }, { 21, 0x70 }, { 22, 0x1E }, { 23, 0x25 }, { 24, 0x25 },
52 { 25, 0x02 }, { 26, 0x02 }, { 27, 0xA0 }, { 32, 0x2F }, { 33, 0x0F },
53 { 34, 0x0F }, { 35, 0x0F }, { 36, 0x0F }, { 37, 0x0F }, { 38, 0x0F },
54 { 39, 0x00 }, { 40, 0x02 }, { 41, 0x02 }, { 42, 0x02 }, { 43, 0x0F },
55 { 44, 0x0F }, { 45, 0x0F }, { 46, 0x0F }, { 47, 0x0F }, { 48, 0x0F },
56 { 49, 0x0F }, { 50, 0x00 }, { 51, 0x02 }, { 52, 0x02 }, { 53, 0x02 },
57 { 80, 0x0C }, { 83, 0x42 }, { 84, 0x42 }, { 85, 0x41 }, { 86, 0x14 },
58 { 89, 0x88 }, { 90, 0x01 }, { 91, 0x00 }, { 92, 0x02 }, { 93, 0x0C },
59 { 94, 0x1C }, { 95, 0x27 }, { 98, 0x49 }, { 99, 0x27 }, { 102, 0x76 },
60 { 103, 0x27 }, { 112, 0x01 }, { 113, 0x0E }, { 114, 0x02 },
61 { 115, 0x0C }, { 118, 0x0C }, { 121, 0x30 }, { 130, 0x00 },
62 { 131, 0x00 }, { 132, 0xFC }, { 134, 0x00 }, { 136, 0x00 },
63 { 138, 0x00 }, { 139, 0x00 }, { 140, 0x00 }, { 141, 0xFC },
64 { 143, 0x00 }, { 145, 0x00 }, { 147, 0x00 }, { 148, 0x00 },
65 { 149, 0x00 }, { 150, 0xFC }, { 152, 0x00 }, { 154, 0x00 },
66 { 156, 0x00 }, { 157, 0x00 }, { 2, 0x00 },
67};
68
69static const struct omap_video_timings nec_8048_panel_timings = {
70 .x_res = LCD_XRES,
71 .y_res = LCD_YRES,
72 .pixel_clock = LCD_PIXEL_CLOCK,
73 .hfp = 6,
74 .hsw = 1,
75 .hbp = 4,
76 .vfp = 3,
77 .vsw = 1,
78 .vbp = 4,
79
80 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
81 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
82 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
83 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
84 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
85};
86
87#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
88
89static int nec_8048_spi_send(struct spi_device *spi, unsigned char reg_addr,
90 unsigned char reg_data)
91{
92 int ret = 0;
93 unsigned int cmd = 0, data = 0;
94
95 cmd = 0x0000 | reg_addr; /* register address write */
96 data = 0x0100 | reg_data; /* register data write */
97 data = (cmd << 16) | data;
98
99 ret = spi_write(spi, (unsigned char *)&data, 4);
100 if (ret)
101 pr_err("error in spi_write %x\n", data);
102
103 return ret;
104}
105
106static int init_nec_8048_wvga_lcd(struct spi_device *spi)
107{
108 unsigned int i;
109 /* Initialization Sequence */
110 /* nec_8048_spi_send(spi, REG, VAL) */
111 for (i = 0; i < (ARRAY_SIZE(nec_8048_init_seq) - 1); i++)
112 nec_8048_spi_send(spi, nec_8048_init_seq[i].addr,
113 nec_8048_init_seq[i].dat);
114 udelay(20);
115 nec_8048_spi_send(spi, nec_8048_init_seq[i].addr,
116 nec_8048_init_seq[i].dat);
117 return 0;
118}
119
120static int nec_8048_connect(struct omap_dss_device *dssdev)
121{
122 struct panel_drv_data *ddata = to_panel_data(dssdev);
123 struct omap_dss_device *in = ddata->in;
124 int r;
125
126 if (omapdss_device_is_connected(dssdev))
127 return 0;
128
129 r = in->ops.dpi->connect(in, dssdev);
130 if (r)
131 return r;
132
133 return 0;
134}
135
136static void nec_8048_disconnect(struct omap_dss_device *dssdev)
137{
138 struct panel_drv_data *ddata = to_panel_data(dssdev);
139 struct omap_dss_device *in = ddata->in;
140
141 if (!omapdss_device_is_connected(dssdev))
142 return;
143
144 in->ops.dpi->disconnect(in, dssdev);
145}
146
147static int nec_8048_enable(struct omap_dss_device *dssdev)
148{
149 struct panel_drv_data *ddata = to_panel_data(dssdev);
150 struct omap_dss_device *in = ddata->in;
151 int r;
152
153 if (!omapdss_device_is_connected(dssdev))
154 return -ENODEV;
155
156 if (omapdss_device_is_enabled(dssdev))
157 return 0;
158
159 in->ops.dpi->set_data_lines(in, ddata->data_lines);
160 in->ops.dpi->set_timings(in, &ddata->videomode);
161
162 r = in->ops.dpi->enable(in);
163 if (r)
164 return r;
165
166 if (gpio_is_valid(ddata->res_gpio))
167 gpio_set_value_cansleep(ddata->res_gpio, 1);
168
169 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
170
171 return 0;
172}
173
174static void nec_8048_disable(struct omap_dss_device *dssdev)
175{
176 struct panel_drv_data *ddata = to_panel_data(dssdev);
177 struct omap_dss_device *in = ddata->in;
178
179 if (!omapdss_device_is_enabled(dssdev))
180 return;
181
182 if (gpio_is_valid(ddata->res_gpio))
183 gpio_set_value_cansleep(ddata->res_gpio, 0);
184
185 in->ops.dpi->disable(in);
186
187 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
188}
189
190static void nec_8048_set_timings(struct omap_dss_device *dssdev,
191 struct omap_video_timings *timings)
192{
193 struct panel_drv_data *ddata = to_panel_data(dssdev);
194 struct omap_dss_device *in = ddata->in;
195
196 ddata->videomode = *timings;
197 dssdev->panel.timings = *timings;
198
199 in->ops.dpi->set_timings(in, timings);
200}
201
202static void nec_8048_get_timings(struct omap_dss_device *dssdev,
203 struct omap_video_timings *timings)
204{
205 struct panel_drv_data *ddata = to_panel_data(dssdev);
206
207 *timings = ddata->videomode;
208}
209
210static int nec_8048_check_timings(struct omap_dss_device *dssdev,
211 struct omap_video_timings *timings)
212{
213 struct panel_drv_data *ddata = to_panel_data(dssdev);
214 struct omap_dss_device *in = ddata->in;
215
216 return in->ops.dpi->check_timings(in, timings);
217}
218
219static struct omap_dss_driver nec_8048_ops = {
220 .connect = nec_8048_connect,
221 .disconnect = nec_8048_disconnect,
222
223 .enable = nec_8048_enable,
224 .disable = nec_8048_disable,
225
226 .set_timings = nec_8048_set_timings,
227 .get_timings = nec_8048_get_timings,
228 .check_timings = nec_8048_check_timings,
229
230 .get_resolution = omapdss_default_get_resolution,
231};
232
233
234static int nec_8048_probe_pdata(struct spi_device *spi)
235{
236 const struct panel_nec_nl8048hl11_platform_data *pdata;
237 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
238 struct omap_dss_device *dssdev, *in;
239
240 pdata = dev_get_platdata(&spi->dev);
241
242 ddata->qvga_gpio = pdata->qvga_gpio;
243 ddata->res_gpio = pdata->res_gpio;
244
245 in = omap_dss_find_output(pdata->source);
246 if (in == NULL) {
247 dev_err(&spi->dev, "failed to find video source '%s'\n",
248 pdata->source);
249 return -EPROBE_DEFER;
250 }
251 ddata->in = in;
252
253 ddata->data_lines = pdata->data_lines;
254
255 dssdev = &ddata->dssdev;
256 dssdev->name = pdata->name;
257
258 return 0;
259}
260
261static int nec_8048_probe(struct spi_device *spi)
262{
263 struct panel_drv_data *ddata;
264 struct omap_dss_device *dssdev;
265 int r;
266
267 dev_dbg(&spi->dev, "%s\n", __func__);
268
269 spi->mode = SPI_MODE_0;
270 spi->bits_per_word = 32;
271
272 r = spi_setup(spi);
273 if (r < 0) {
274 dev_err(&spi->dev, "spi_setup failed: %d\n", r);
275 return r;
276 }
277
278 init_nec_8048_wvga_lcd(spi);
279
280 ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
281 if (ddata == NULL)
282 return -ENOMEM;
283
284 dev_set_drvdata(&spi->dev, ddata);
285
286 ddata->spi = spi;
287
288 if (dev_get_platdata(&spi->dev)) {
289 r = nec_8048_probe_pdata(spi);
290 if (r)
291 return r;
292 } else {
293 return -ENODEV;
294 }
295
296 if (gpio_is_valid(ddata->qvga_gpio)) {
297 r = devm_gpio_request_one(&spi->dev, ddata->qvga_gpio,
298 GPIOF_OUT_INIT_HIGH, "lcd QVGA");
299 if (r)
300 goto err_gpio;
301 }
302
303 if (gpio_is_valid(ddata->res_gpio)) {
304 r = devm_gpio_request_one(&spi->dev, ddata->res_gpio,
305 GPIOF_OUT_INIT_LOW, "lcd RES");
306 if (r)
307 goto err_gpio;
308 }
309
310 ddata->videomode = nec_8048_panel_timings;
311
312 dssdev = &ddata->dssdev;
313 dssdev->dev = &spi->dev;
314 dssdev->driver = &nec_8048_ops;
315 dssdev->type = OMAP_DISPLAY_TYPE_DPI;
316 dssdev->owner = THIS_MODULE;
317 dssdev->panel.timings = ddata->videomode;
318
319 r = omapdss_register_display(dssdev);
320 if (r) {
321 dev_err(&spi->dev, "Failed to register panel\n");
322 goto err_reg;
323 }
324
325 return 0;
326
327err_reg:
328err_gpio:
329 omap_dss_put_device(ddata->in);
330 return r;
331}
332
333static int nec_8048_remove(struct spi_device *spi)
334{
335 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
336 struct omap_dss_device *dssdev = &ddata->dssdev;
337 struct omap_dss_device *in = ddata->in;
338
339 dev_dbg(&ddata->spi->dev, "%s\n", __func__);
340
341 omapdss_unregister_display(dssdev);
342
343 nec_8048_disable(dssdev);
344 nec_8048_disconnect(dssdev);
345
346 omap_dss_put_device(in);
347
348 return 0;
349}
350
351#ifdef CONFIG_PM_SLEEP
352static int nec_8048_suspend(struct device *dev)
353{
354 struct spi_device *spi = to_spi_device(dev);
355
356 nec_8048_spi_send(spi, 2, 0x01);
357 mdelay(40);
358
359 return 0;
360}
361
362static int nec_8048_resume(struct device *dev)
363{
364 struct spi_device *spi = to_spi_device(dev);
365
366 /* reinitialize the panel */
367 spi_setup(spi);
368 nec_8048_spi_send(spi, 2, 0x00);
369 init_nec_8048_wvga_lcd(spi);
370
371 return 0;
372}
373static SIMPLE_DEV_PM_OPS(nec_8048_pm_ops, nec_8048_suspend,
374 nec_8048_resume);
375#define NEC_8048_PM_OPS (&nec_8048_pm_ops)
376#else
377#define NEC_8048_PM_OPS NULL
378#endif
379
380static struct spi_driver nec_8048_driver = {
381 .driver = {
382 .name = "panel-nec-nl8048hl11",
383 .owner = THIS_MODULE,
384 .pm = NEC_8048_PM_OPS,
385 },
386 .probe = nec_8048_probe,
387 .remove = nec_8048_remove,
388};
389
390module_spi_driver(nec_8048_driver);
391
392MODULE_AUTHOR("Erik Gilling <konkers@android.com>");
393MODULE_DESCRIPTION("NEC-NL8048HL11 Driver");
394MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c
new file mode 100644
index 000000000000..72a4fb5aa6b1
--- /dev/null
+++ b/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c
@@ -0,0 +1,324 @@
1/*
2 * LCD panel driver for Sharp LS037V7DW01
3 *
4 * Copyright (C) 2013 Texas Instruments
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12#include <linux/delay.h>
13#include <linux/gpio.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17
18#include <video/omapdss.h>
19#include <video/omap-panel-data.h>
20
21struct panel_drv_data {
22 struct omap_dss_device dssdev;
23 struct omap_dss_device *in;
24
25 int data_lines;
26
27 struct omap_video_timings videomode;
28
29 int resb_gpio;
30 int ini_gpio;
31 int mo_gpio;
32 int lr_gpio;
33 int ud_gpio;
34};
35
36static const struct omap_video_timings sharp_ls_timings = {
37 .x_res = 480,
38 .y_res = 640,
39
40 .pixel_clock = 19200,
41
42 .hsw = 2,
43 .hfp = 1,
44 .hbp = 28,
45
46 .vsw = 1,
47 .vfp = 1,
48 .vbp = 1,
49
50 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
51 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
52 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
53 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
54 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
55};
56
57#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
58
59static int sharp_ls_connect(struct omap_dss_device *dssdev)
60{
61 struct panel_drv_data *ddata = to_panel_data(dssdev);
62 struct omap_dss_device *in = ddata->in;
63 int r;
64
65 if (omapdss_device_is_connected(dssdev))
66 return 0;
67
68 r = in->ops.dpi->connect(in, dssdev);
69 if (r)
70 return r;
71
72 return 0;
73}
74
75static void sharp_ls_disconnect(struct omap_dss_device *dssdev)
76{
77 struct panel_drv_data *ddata = to_panel_data(dssdev);
78 struct omap_dss_device *in = ddata->in;
79
80 if (!omapdss_device_is_connected(dssdev))
81 return;
82
83 in->ops.dpi->disconnect(in, dssdev);
84}
85
86static int sharp_ls_enable(struct omap_dss_device *dssdev)
87{
88 struct panel_drv_data *ddata = to_panel_data(dssdev);
89 struct omap_dss_device *in = ddata->in;
90 int r;
91
92 if (!omapdss_device_is_connected(dssdev))
93 return -ENODEV;
94
95 if (omapdss_device_is_enabled(dssdev))
96 return 0;
97
98 in->ops.dpi->set_data_lines(in, ddata->data_lines);
99 in->ops.dpi->set_timings(in, &ddata->videomode);
100
101 r = in->ops.dpi->enable(in);
102 if (r)
103 return r;
104
105 /* wait couple of vsyncs until enabling the LCD */
106 msleep(50);
107
108 if (gpio_is_valid(ddata->resb_gpio))
109 gpio_set_value_cansleep(ddata->resb_gpio, 1);
110
111 if (gpio_is_valid(ddata->ini_gpio))
112 gpio_set_value_cansleep(ddata->ini_gpio, 1);
113
114 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
115
116 return 0;
117}
118
119static void sharp_ls_disable(struct omap_dss_device *dssdev)
120{
121 struct panel_drv_data *ddata = to_panel_data(dssdev);
122 struct omap_dss_device *in = ddata->in;
123
124 if (!omapdss_device_is_enabled(dssdev))
125 return;
126
127 if (gpio_is_valid(ddata->ini_gpio))
128 gpio_set_value_cansleep(ddata->ini_gpio, 0);
129
130 if (gpio_is_valid(ddata->resb_gpio))
131 gpio_set_value_cansleep(ddata->resb_gpio, 0);
132
133 /* wait at least 5 vsyncs after disabling the LCD */
134
135 msleep(100);
136
137 in->ops.dpi->disable(in);
138
139 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
140}
141
142static void sharp_ls_set_timings(struct omap_dss_device *dssdev,
143 struct omap_video_timings *timings)
144{
145 struct panel_drv_data *ddata = to_panel_data(dssdev);
146 struct omap_dss_device *in = ddata->in;
147
148 ddata->videomode = *timings;
149 dssdev->panel.timings = *timings;
150
151 in->ops.dpi->set_timings(in, timings);
152}
153
154static void sharp_ls_get_timings(struct omap_dss_device *dssdev,
155 struct omap_video_timings *timings)
156{
157 struct panel_drv_data *ddata = to_panel_data(dssdev);
158
159 *timings = ddata->videomode;
160}
161
162static int sharp_ls_check_timings(struct omap_dss_device *dssdev,
163 struct omap_video_timings *timings)
164{
165 struct panel_drv_data *ddata = to_panel_data(dssdev);
166 struct omap_dss_device *in = ddata->in;
167
168 return in->ops.dpi->check_timings(in, timings);
169}
170
171static struct omap_dss_driver sharp_ls_ops = {
172 .connect = sharp_ls_connect,
173 .disconnect = sharp_ls_disconnect,
174
175 .enable = sharp_ls_enable,
176 .disable = sharp_ls_disable,
177
178 .set_timings = sharp_ls_set_timings,
179 .get_timings = sharp_ls_get_timings,
180 .check_timings = sharp_ls_check_timings,
181
182 .get_resolution = omapdss_default_get_resolution,
183};
184
185static int sharp_ls_probe_pdata(struct platform_device *pdev)
186{
187 const struct panel_sharp_ls037v7dw01_platform_data *pdata;
188 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
189 struct omap_dss_device *dssdev, *in;
190
191 pdata = dev_get_platdata(&pdev->dev);
192
193 in = omap_dss_find_output(pdata->source);
194 if (in == NULL) {
195 dev_err(&pdev->dev, "failed to find video source '%s'\n",
196 pdata->source);
197 return -EPROBE_DEFER;
198 }
199
200 ddata->in = in;
201
202 ddata->data_lines = pdata->data_lines;
203
204 dssdev = &ddata->dssdev;
205 dssdev->name = pdata->name;
206
207 ddata->resb_gpio = pdata->resb_gpio;
208 ddata->ini_gpio = pdata->ini_gpio;
209 ddata->mo_gpio = pdata->mo_gpio;
210 ddata->lr_gpio = pdata->lr_gpio;
211 ddata->ud_gpio = pdata->ud_gpio;
212
213 return 0;
214}
215
216static int sharp_ls_probe(struct platform_device *pdev)
217{
218 struct panel_drv_data *ddata;
219 struct omap_dss_device *dssdev;
220 int r;
221
222 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
223 if (ddata == NULL)
224 return -ENOMEM;
225
226 platform_set_drvdata(pdev, ddata);
227
228 if (dev_get_platdata(&pdev->dev)) {
229 r = sharp_ls_probe_pdata(pdev);
230 if (r)
231 return r;
232 } else {
233 return -ENODEV;
234 }
235
236 if (gpio_is_valid(ddata->mo_gpio)) {
237 r = devm_gpio_request_one(&pdev->dev, ddata->mo_gpio,
238 GPIOF_OUT_INIT_LOW, "lcd MO");
239 if (r)
240 goto err_gpio;
241 }
242
243 if (gpio_is_valid(ddata->lr_gpio)) {
244 r = devm_gpio_request_one(&pdev->dev, ddata->lr_gpio,
245 GPIOF_OUT_INIT_HIGH, "lcd LR");
246 if (r)
247 goto err_gpio;
248 }
249
250 if (gpio_is_valid(ddata->ud_gpio)) {
251 r = devm_gpio_request_one(&pdev->dev, ddata->ud_gpio,
252 GPIOF_OUT_INIT_HIGH, "lcd UD");
253 if (r)
254 goto err_gpio;
255 }
256
257 if (gpio_is_valid(ddata->resb_gpio)) {
258 r = devm_gpio_request_one(&pdev->dev, ddata->resb_gpio,
259 GPIOF_OUT_INIT_LOW, "lcd RESB");
260 if (r)
261 goto err_gpio;
262 }
263
264 if (gpio_is_valid(ddata->ini_gpio)) {
265 r = devm_gpio_request_one(&pdev->dev, ddata->ini_gpio,
266 GPIOF_OUT_INIT_LOW, "lcd INI");
267 if (r)
268 goto err_gpio;
269 }
270
271 ddata->videomode = sharp_ls_timings;
272
273 dssdev = &ddata->dssdev;
274 dssdev->dev = &pdev->dev;
275 dssdev->driver = &sharp_ls_ops;
276 dssdev->type = OMAP_DISPLAY_TYPE_DPI;
277 dssdev->owner = THIS_MODULE;
278 dssdev->panel.timings = ddata->videomode;
279 dssdev->phy.dpi.data_lines = ddata->data_lines;
280
281 r = omapdss_register_display(dssdev);
282 if (r) {
283 dev_err(&pdev->dev, "Failed to register panel\n");
284 goto err_reg;
285 }
286
287 return 0;
288
289err_reg:
290err_gpio:
291 omap_dss_put_device(ddata->in);
292 return r;
293}
294
295static int __exit sharp_ls_remove(struct platform_device *pdev)
296{
297 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
298 struct omap_dss_device *dssdev = &ddata->dssdev;
299 struct omap_dss_device *in = ddata->in;
300
301 omapdss_unregister_display(dssdev);
302
303 sharp_ls_disable(dssdev);
304 sharp_ls_disconnect(dssdev);
305
306 omap_dss_put_device(in);
307
308 return 0;
309}
310
311static struct platform_driver sharp_ls_driver = {
312 .probe = sharp_ls_probe,
313 .remove = __exit_p(sharp_ls_remove),
314 .driver = {
315 .name = "panel-sharp-ls037v7dw01",
316 .owner = THIS_MODULE,
317 },
318};
319
320module_platform_driver(sharp_ls_driver);
321
322MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
323MODULE_DESCRIPTION("Sharp LS037V7DW01 Panel Driver");
324MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/omap2/displays-new/panel-sony-acx565akm.c
new file mode 100644
index 000000000000..e6d56f714ae4
--- /dev/null
+++ b/drivers/video/omap2/displays-new/panel-sony-acx565akm.c
@@ -0,0 +1,865 @@
1/*
2 * Sony ACX565AKM LCD Panel driver
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Original Driver Author: Imre Deak <imre.deak@nokia.com>
7 * Based on panel-generic.c by Tomi Valkeinen <tomi.valkeinen@nokia.com>
8 * Adapted to new DSS2 framework: Roger Quadros <roger.quadros@nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/delay.h>
27#include <linux/spi/spi.h>
28#include <linux/jiffies.h>
29#include <linux/sched.h>
30#include <linux/backlight.h>
31#include <linux/fb.h>
32#include <linux/gpio.h>
33
34#include <video/omapdss.h>
35#include <video/omap-panel-data.h>
36
37#define MIPID_CMD_READ_DISP_ID 0x04
38#define MIPID_CMD_READ_RED 0x06
39#define MIPID_CMD_READ_GREEN 0x07
40#define MIPID_CMD_READ_BLUE 0x08
41#define MIPID_CMD_READ_DISP_STATUS 0x09
42#define MIPID_CMD_RDDSDR 0x0F
43#define MIPID_CMD_SLEEP_IN 0x10
44#define MIPID_CMD_SLEEP_OUT 0x11
45#define MIPID_CMD_DISP_OFF 0x28
46#define MIPID_CMD_DISP_ON 0x29
47#define MIPID_CMD_WRITE_DISP_BRIGHTNESS 0x51
48#define MIPID_CMD_READ_DISP_BRIGHTNESS 0x52
49#define MIPID_CMD_WRITE_CTRL_DISP 0x53
50
51#define CTRL_DISP_BRIGHTNESS_CTRL_ON (1 << 5)
52#define CTRL_DISP_AMBIENT_LIGHT_CTRL_ON (1 << 4)
53#define CTRL_DISP_BACKLIGHT_ON (1 << 2)
54#define CTRL_DISP_AUTO_BRIGHTNESS_ON (1 << 1)
55
56#define MIPID_CMD_READ_CTRL_DISP 0x54
57#define MIPID_CMD_WRITE_CABC 0x55
58#define MIPID_CMD_READ_CABC 0x56
59
60#define MIPID_VER_LPH8923 3
61#define MIPID_VER_LS041Y3 4
62#define MIPID_VER_L4F00311 8
63#define MIPID_VER_ACX565AKM 9
64
65struct panel_drv_data {
66 struct omap_dss_device dssdev;
67 struct omap_dss_device *in;
68
69 int reset_gpio;
70 int datapairs;
71
72 struct omap_video_timings videomode;
73
74 char *name;
75 int enabled;
76 int model;
77 int revision;
78 u8 display_id[3];
79 unsigned has_bc:1;
80 unsigned has_cabc:1;
81 unsigned cabc_mode;
82 unsigned long hw_guard_end; /* next value of jiffies
83 when we can issue the
84 next sleep in/out command */
85 unsigned long hw_guard_wait; /* max guard time in jiffies */
86
87 struct spi_device *spi;
88 struct mutex mutex;
89
90 struct backlight_device *bl_dev;
91};
92
93static const struct omap_video_timings acx565akm_panel_timings = {
94 .x_res = 800,
95 .y_res = 480,
96 .pixel_clock = 24000,
97 .hfp = 28,
98 .hsw = 4,
99 .hbp = 24,
100 .vfp = 3,
101 .vsw = 3,
102 .vbp = 4,
103
104 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
105 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
106
107 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
108 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
109 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
110};
111
112#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
113
114static void acx565akm_transfer(struct panel_drv_data *ddata, int cmd,
115 const u8 *wbuf, int wlen, u8 *rbuf, int rlen)
116{
117 struct spi_message m;
118 struct spi_transfer *x, xfer[5];
119 int r;
120
121 BUG_ON(ddata->spi == NULL);
122
123 spi_message_init(&m);
124
125 memset(xfer, 0, sizeof(xfer));
126 x = &xfer[0];
127
128 cmd &= 0xff;
129 x->tx_buf = &cmd;
130 x->bits_per_word = 9;
131 x->len = 2;
132
133 if (rlen > 1 && wlen == 0) {
134 /*
135 * Between the command and the response data there is a
136 * dummy clock cycle. Add an extra bit after the command
137 * word to account for this.
138 */
139 x->bits_per_word = 10;
140 cmd <<= 1;
141 }
142 spi_message_add_tail(x, &m);
143
144 if (wlen) {
145 x++;
146 x->tx_buf = wbuf;
147 x->len = wlen;
148 x->bits_per_word = 9;
149 spi_message_add_tail(x, &m);
150 }
151
152 if (rlen) {
153 x++;
154 x->rx_buf = rbuf;
155 x->len = rlen;
156 spi_message_add_tail(x, &m);
157 }
158
159 r = spi_sync(ddata->spi, &m);
160 if (r < 0)
161 dev_dbg(&ddata->spi->dev, "spi_sync %d\n", r);
162}
163
164static inline void acx565akm_cmd(struct panel_drv_data *ddata, int cmd)
165{
166 acx565akm_transfer(ddata, cmd, NULL, 0, NULL, 0);
167}
168
169static inline void acx565akm_write(struct panel_drv_data *ddata,
170 int reg, const u8 *buf, int len)
171{
172 acx565akm_transfer(ddata, reg, buf, len, NULL, 0);
173}
174
175static inline void acx565akm_read(struct panel_drv_data *ddata,
176 int reg, u8 *buf, int len)
177{
178 acx565akm_transfer(ddata, reg, NULL, 0, buf, len);
179}
180
181static void hw_guard_start(struct panel_drv_data *ddata, int guard_msec)
182{
183 ddata->hw_guard_wait = msecs_to_jiffies(guard_msec);
184 ddata->hw_guard_end = jiffies + ddata->hw_guard_wait;
185}
186
187static void hw_guard_wait(struct panel_drv_data *ddata)
188{
189 unsigned long wait = ddata->hw_guard_end - jiffies;
190
191 if ((long)wait > 0 && wait <= ddata->hw_guard_wait) {
192 set_current_state(TASK_UNINTERRUPTIBLE);
193 schedule_timeout(wait);
194 }
195}
196
197static void set_sleep_mode(struct panel_drv_data *ddata, int on)
198{
199 int cmd;
200
201 if (on)
202 cmd = MIPID_CMD_SLEEP_IN;
203 else
204 cmd = MIPID_CMD_SLEEP_OUT;
205 /*
206 * We have to keep 120msec between sleep in/out commands.
207 * (8.2.15, 8.2.16).
208 */
209 hw_guard_wait(ddata);
210 acx565akm_cmd(ddata, cmd);
211 hw_guard_start(ddata, 120);
212}
213
214static void set_display_state(struct panel_drv_data *ddata, int enabled)
215{
216 int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF;
217
218 acx565akm_cmd(ddata, cmd);
219}
220
221static int panel_enabled(struct panel_drv_data *ddata)
222{
223 u32 disp_status;
224 int enabled;
225
226 acx565akm_read(ddata, MIPID_CMD_READ_DISP_STATUS,
227 (u8 *)&disp_status, 4);
228 disp_status = __be32_to_cpu(disp_status);
229 enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10));
230 dev_dbg(&ddata->spi->dev,
231 "LCD panel %senabled by bootloader (status 0x%04x)\n",
232 enabled ? "" : "not ", disp_status);
233 return enabled;
234}
235
236static int panel_detect(struct panel_drv_data *ddata)
237{
238 acx565akm_read(ddata, MIPID_CMD_READ_DISP_ID, ddata->display_id, 3);
239 dev_dbg(&ddata->spi->dev, "MIPI display ID: %02x%02x%02x\n",
240 ddata->display_id[0],
241 ddata->display_id[1],
242 ddata->display_id[2]);
243
244 switch (ddata->display_id[0]) {
245 case 0x10:
246 ddata->model = MIPID_VER_ACX565AKM;
247 ddata->name = "acx565akm";
248 ddata->has_bc = 1;
249 ddata->has_cabc = 1;
250 break;
251 case 0x29:
252 ddata->model = MIPID_VER_L4F00311;
253 ddata->name = "l4f00311";
254 break;
255 case 0x45:
256 ddata->model = MIPID_VER_LPH8923;
257 ddata->name = "lph8923";
258 break;
259 case 0x83:
260 ddata->model = MIPID_VER_LS041Y3;
261 ddata->name = "ls041y3";
262 break;
263 default:
264 ddata->name = "unknown";
265 dev_err(&ddata->spi->dev, "invalid display ID\n");
266 return -ENODEV;
267 }
268
269 ddata->revision = ddata->display_id[1];
270
271 dev_info(&ddata->spi->dev, "omapfb: %s rev %02x LCD detected\n",
272 ddata->name, ddata->revision);
273
274 return 0;
275}
276
277/*----------------------Backlight Control-------------------------*/
278
279static void enable_backlight_ctrl(struct panel_drv_data *ddata, int enable)
280{
281 u16 ctrl;
282
283 acx565akm_read(ddata, MIPID_CMD_READ_CTRL_DISP, (u8 *)&ctrl, 1);
284 if (enable) {
285 ctrl |= CTRL_DISP_BRIGHTNESS_CTRL_ON |
286 CTRL_DISP_BACKLIGHT_ON;
287 } else {
288 ctrl &= ~(CTRL_DISP_BRIGHTNESS_CTRL_ON |
289 CTRL_DISP_BACKLIGHT_ON);
290 }
291
292 ctrl |= 1 << 8;
293 acx565akm_write(ddata, MIPID_CMD_WRITE_CTRL_DISP, (u8 *)&ctrl, 2);
294}
295
296static void set_cabc_mode(struct panel_drv_data *ddata, unsigned mode)
297{
298 u16 cabc_ctrl;
299
300 ddata->cabc_mode = mode;
301 if (!ddata->enabled)
302 return;
303 cabc_ctrl = 0;
304 acx565akm_read(ddata, MIPID_CMD_READ_CABC, (u8 *)&cabc_ctrl, 1);
305 cabc_ctrl &= ~3;
306 cabc_ctrl |= (1 << 8) | (mode & 3);
307 acx565akm_write(ddata, MIPID_CMD_WRITE_CABC, (u8 *)&cabc_ctrl, 2);
308}
309
310static unsigned get_cabc_mode(struct panel_drv_data *ddata)
311{
312 return ddata->cabc_mode;
313}
314
315static unsigned get_hw_cabc_mode(struct panel_drv_data *ddata)
316{
317 u8 cabc_ctrl;
318
319 acx565akm_read(ddata, MIPID_CMD_READ_CABC, &cabc_ctrl, 1);
320 return cabc_ctrl & 3;
321}
322
323static void acx565akm_set_brightness(struct panel_drv_data *ddata, int level)
324{
325 int bv;
326
327 bv = level | (1 << 8);
328 acx565akm_write(ddata, MIPID_CMD_WRITE_DISP_BRIGHTNESS, (u8 *)&bv, 2);
329
330 if (level)
331 enable_backlight_ctrl(ddata, 1);
332 else
333 enable_backlight_ctrl(ddata, 0);
334}
335
336static int acx565akm_get_actual_brightness(struct panel_drv_data *ddata)
337{
338 u8 bv;
339
340 acx565akm_read(ddata, MIPID_CMD_READ_DISP_BRIGHTNESS, &bv, 1);
341
342 return bv;
343}
344
345
346static int acx565akm_bl_update_status(struct backlight_device *dev)
347{
348 struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
349 int r;
350 int level;
351
352 dev_dbg(&ddata->spi->dev, "%s\n", __func__);
353
354 mutex_lock(&ddata->mutex);
355
356 if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
357 dev->props.power == FB_BLANK_UNBLANK)
358 level = dev->props.brightness;
359 else
360 level = 0;
361
362 r = 0;
363 if (ddata->has_bc)
364 acx565akm_set_brightness(ddata, level);
365 else
366 r = -ENODEV;
367
368 mutex_unlock(&ddata->mutex);
369
370 return r;
371}
372
373static int acx565akm_bl_get_intensity(struct backlight_device *dev)
374{
375 struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
376
377 dev_dbg(&dev->dev, "%s\n", __func__);
378
379 if (!ddata->has_bc)
380 return -ENODEV;
381
382 if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
383 dev->props.power == FB_BLANK_UNBLANK) {
384 if (ddata->has_bc)
385 return acx565akm_get_actual_brightness(ddata);
386 else
387 return dev->props.brightness;
388 }
389
390 return 0;
391}
392
393static const struct backlight_ops acx565akm_bl_ops = {
394 .get_brightness = acx565akm_bl_get_intensity,
395 .update_status = acx565akm_bl_update_status,
396};
397
398/*--------------------Auto Brightness control via Sysfs---------------------*/
399
400static const char * const cabc_modes[] = {
401 "off", /* always used when CABC is not supported */
402 "ui",
403 "still-image",
404 "moving-image",
405};
406
407static ssize_t show_cabc_mode(struct device *dev,
408 struct device_attribute *attr,
409 char *buf)
410{
411 struct panel_drv_data *ddata = dev_get_drvdata(dev);
412 const char *mode_str;
413 int mode;
414 int len;
415
416 if (!ddata->has_cabc)
417 mode = 0;
418 else
419 mode = get_cabc_mode(ddata);
420 mode_str = "unknown";
421 if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes))
422 mode_str = cabc_modes[mode];
423 len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str);
424
425 return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1;
426}
427
428static ssize_t store_cabc_mode(struct device *dev,
429 struct device_attribute *attr,
430 const char *buf, size_t count)
431{
432 struct panel_drv_data *ddata = dev_get_drvdata(dev);
433 int i;
434
435 for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
436 const char *mode_str = cabc_modes[i];
437 int cmp_len = strlen(mode_str);
438
439 if (count > 0 && buf[count - 1] == '\n')
440 count--;
441 if (count != cmp_len)
442 continue;
443
444 if (strncmp(buf, mode_str, cmp_len) == 0)
445 break;
446 }
447
448 if (i == ARRAY_SIZE(cabc_modes))
449 return -EINVAL;
450
451 if (!ddata->has_cabc && i != 0)
452 return -EINVAL;
453
454 mutex_lock(&ddata->mutex);
455 set_cabc_mode(ddata, i);
456 mutex_unlock(&ddata->mutex);
457
458 return count;
459}
460
461static ssize_t show_cabc_available_modes(struct device *dev,
462 struct device_attribute *attr,
463 char *buf)
464{
465 struct panel_drv_data *ddata = dev_get_drvdata(dev);
466 int len;
467 int i;
468
469 if (!ddata->has_cabc)
470 return snprintf(buf, PAGE_SIZE, "%s\n", cabc_modes[0]);
471
472 for (i = 0, len = 0;
473 len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++)
474 len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s",
475 i ? " " : "", cabc_modes[i],
476 i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : "");
477
478 return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
479}
480
481static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
482 show_cabc_mode, store_cabc_mode);
483static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
484 show_cabc_available_modes, NULL);
485
486static struct attribute *bldev_attrs[] = {
487 &dev_attr_cabc_mode.attr,
488 &dev_attr_cabc_available_modes.attr,
489 NULL,
490};
491
492static struct attribute_group bldev_attr_group = {
493 .attrs = bldev_attrs,
494};
495
496static int acx565akm_connect(struct omap_dss_device *dssdev)
497{
498 struct panel_drv_data *ddata = to_panel_data(dssdev);
499 struct omap_dss_device *in = ddata->in;
500 int r;
501
502 if (omapdss_device_is_connected(dssdev))
503 return 0;
504
505 r = in->ops.sdi->connect(in, dssdev);
506 if (r)
507 return r;
508
509 return 0;
510}
511
512static void acx565akm_disconnect(struct omap_dss_device *dssdev)
513{
514 struct panel_drv_data *ddata = to_panel_data(dssdev);
515 struct omap_dss_device *in = ddata->in;
516
517 if (!omapdss_device_is_connected(dssdev))
518 return;
519
520 in->ops.sdi->disconnect(in, dssdev);
521}
522
523static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
524{
525 struct panel_drv_data *ddata = to_panel_data(dssdev);
526 struct omap_dss_device *in = ddata->in;
527 int r;
528
529 dev_dbg(&ddata->spi->dev, "%s\n", __func__);
530
531 in->ops.sdi->set_timings(in, &ddata->videomode);
532 in->ops.sdi->set_datapairs(in, ddata->datapairs);
533
534 r = in->ops.sdi->enable(in);
535 if (r) {
536 pr_err("%s sdi enable failed\n", __func__);
537 return r;
538 }
539
540 /*FIXME tweak me */
541 msleep(50);
542
543 if (gpio_is_valid(ddata->reset_gpio))
544 gpio_set_value(ddata->reset_gpio, 1);
545
546 if (ddata->enabled) {
547 dev_dbg(&ddata->spi->dev, "panel already enabled\n");
548 return 0;
549 }
550
551 /*
552 * We have to meet all the following delay requirements:
553 * 1. tRW: reset pulse width 10usec (7.12.1)
554 * 2. tRT: reset cancel time 5msec (7.12.1)
555 * 3. Providing PCLK,HS,VS signals for 2 frames = ~50msec worst
556 * case (7.6.2)
557 * 4. 120msec before the sleep out command (7.12.1)
558 */
559 msleep(120);
560
561 set_sleep_mode(ddata, 0);
562 ddata->enabled = 1;
563
564 /* 5msec between sleep out and the next command. (8.2.16) */
565 usleep_range(5000, 10000);
566 set_display_state(ddata, 1);
567 set_cabc_mode(ddata, ddata->cabc_mode);
568
569 mutex_unlock(&ddata->mutex);
570
571 return acx565akm_bl_update_status(ddata->bl_dev);
572}
573
574static void acx565akm_panel_power_off(struct omap_dss_device *dssdev)
575{
576 struct panel_drv_data *ddata = to_panel_data(dssdev);
577 struct omap_dss_device *in = ddata->in;
578
579 dev_dbg(dssdev->dev, "%s\n", __func__);
580
581 if (!ddata->enabled)
582 return;
583
584 set_display_state(ddata, 0);
585 set_sleep_mode(ddata, 1);
586 ddata->enabled = 0;
587 /*
588 * We have to provide PCLK,HS,VS signals for 2 frames (worst case
589 * ~50msec) after sending the sleep in command and asserting the
590 * reset signal. We probably could assert the reset w/o the delay
591 * but we still delay to avoid possible artifacts. (7.6.1)
592 */
593 msleep(50);
594
595 if (gpio_is_valid(ddata->reset_gpio))
596 gpio_set_value(ddata->reset_gpio, 0);
597
598 /* FIXME need to tweak this delay */
599 msleep(100);
600
601 in->ops.sdi->disable(in);
602}
603
604static int acx565akm_enable(struct omap_dss_device *dssdev)
605{
606 struct panel_drv_data *ddata = to_panel_data(dssdev);
607 int r;
608
609 dev_dbg(dssdev->dev, "%s\n", __func__);
610
611 if (!omapdss_device_is_connected(dssdev))
612 return -ENODEV;
613
614 if (omapdss_device_is_enabled(dssdev))
615 return 0;
616
617 mutex_lock(&ddata->mutex);
618 r = acx565akm_panel_power_on(dssdev);
619 mutex_unlock(&ddata->mutex);
620
621 if (r)
622 return r;
623
624 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
625
626 return 0;
627}
628
629static void acx565akm_disable(struct omap_dss_device *dssdev)
630{
631 struct panel_drv_data *ddata = to_panel_data(dssdev);
632
633 dev_dbg(dssdev->dev, "%s\n", __func__);
634
635 if (!omapdss_device_is_enabled(dssdev))
636 return;
637
638 mutex_lock(&ddata->mutex);
639 acx565akm_panel_power_off(dssdev);
640 mutex_unlock(&ddata->mutex);
641
642 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
643}
644
645static void acx565akm_set_timings(struct omap_dss_device *dssdev,
646 struct omap_video_timings *timings)
647{
648 struct panel_drv_data *ddata = to_panel_data(dssdev);
649 struct omap_dss_device *in = ddata->in;
650
651 ddata->videomode = *timings;
652 dssdev->panel.timings = *timings;
653
654 in->ops.sdi->set_timings(in, timings);
655}
656
657static void acx565akm_get_timings(struct omap_dss_device *dssdev,
658 struct omap_video_timings *timings)
659{
660 struct panel_drv_data *ddata = to_panel_data(dssdev);
661
662 *timings = ddata->videomode;
663}
664
665static int acx565akm_check_timings(struct omap_dss_device *dssdev,
666 struct omap_video_timings *timings)
667{
668 struct panel_drv_data *ddata = to_panel_data(dssdev);
669 struct omap_dss_device *in = ddata->in;
670
671 return in->ops.sdi->check_timings(in, timings);
672}
673
674static struct omap_dss_driver acx565akm_ops = {
675 .connect = acx565akm_connect,
676 .disconnect = acx565akm_disconnect,
677
678 .enable = acx565akm_enable,
679 .disable = acx565akm_disable,
680
681 .set_timings = acx565akm_set_timings,
682 .get_timings = acx565akm_get_timings,
683 .check_timings = acx565akm_check_timings,
684
685 .get_resolution = omapdss_default_get_resolution,
686};
687
688static int acx565akm_probe_pdata(struct spi_device *spi)
689{
690 const struct panel_acx565akm_platform_data *pdata;
691 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
692 struct omap_dss_device *dssdev, *in;
693
694 pdata = dev_get_platdata(&spi->dev);
695
696 ddata->reset_gpio = pdata->reset_gpio;
697
698 in = omap_dss_find_output(pdata->source);
699 if (in == NULL) {
700 dev_err(&spi->dev, "failed to find video source '%s'\n",
701 pdata->source);
702 return -EPROBE_DEFER;
703 }
704 ddata->in = in;
705
706 ddata->datapairs = pdata->datapairs;
707
708 dssdev = &ddata->dssdev;
709 dssdev->name = pdata->name;
710
711 return 0;
712}
713
714static int acx565akm_probe(struct spi_device *spi)
715{
716 struct panel_drv_data *ddata;
717 struct omap_dss_device *dssdev;
718 struct backlight_device *bldev;
719 int max_brightness, brightness;
720 struct backlight_properties props;
721 int r;
722
723 dev_dbg(&spi->dev, "%s\n", __func__);
724
725 spi->mode = SPI_MODE_3;
726
727 ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
728 if (ddata == NULL)
729 return -ENOMEM;
730
731 dev_set_drvdata(&spi->dev, ddata);
732
733 ddata->spi = spi;
734
735 mutex_init(&ddata->mutex);
736
737 if (dev_get_platdata(&spi->dev)) {
738 r = acx565akm_probe_pdata(spi);
739 if (r)
740 return r;
741 } else {
742 return -ENODEV;
743 }
744
745 if (gpio_is_valid(ddata->reset_gpio)) {
746 r = devm_gpio_request_one(&spi->dev, ddata->reset_gpio,
747 GPIOF_OUT_INIT_LOW, "lcd reset");
748 if (r)
749 goto err_gpio;
750 }
751
752 if (gpio_is_valid(ddata->reset_gpio))
753 gpio_set_value(ddata->reset_gpio, 1);
754
755 /*
756 * After reset we have to wait 5 msec before the first
757 * command can be sent.
758 */
759 usleep_range(5000, 10000);
760
761 ddata->enabled = panel_enabled(ddata);
762
763 r = panel_detect(ddata);
764
765 if (!ddata->enabled && gpio_is_valid(ddata->reset_gpio))
766 gpio_set_value(ddata->reset_gpio, 0);
767
768 if (r) {
769 dev_err(&spi->dev, "%s panel detect error\n", __func__);
770 goto err_detect;
771 }
772
773 memset(&props, 0, sizeof(props));
774 props.fb_blank = FB_BLANK_UNBLANK;
775 props.power = FB_BLANK_UNBLANK;
776 props.type = BACKLIGHT_RAW;
777
778 bldev = backlight_device_register("acx565akm", &ddata->spi->dev,
779 ddata, &acx565akm_bl_ops, &props);
780 ddata->bl_dev = bldev;
781 if (ddata->has_cabc) {
782 r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group);
783 if (r) {
784 dev_err(&bldev->dev,
785 "%s failed to create sysfs files\n", __func__);
786 goto err_sysfs;
787 }
788 ddata->cabc_mode = get_hw_cabc_mode(ddata);
789 }
790
791 max_brightness = 255;
792
793 if (ddata->has_bc)
794 brightness = acx565akm_get_actual_brightness(ddata);
795 else
796 brightness = 0;
797
798 bldev->props.max_brightness = max_brightness;
799 bldev->props.brightness = brightness;
800
801 acx565akm_bl_update_status(bldev);
802
803
804 ddata->videomode = acx565akm_panel_timings;
805
806 dssdev = &ddata->dssdev;
807 dssdev->dev = &spi->dev;
808 dssdev->driver = &acx565akm_ops;
809 dssdev->type = OMAP_DISPLAY_TYPE_SDI;
810 dssdev->owner = THIS_MODULE;
811 dssdev->panel.timings = ddata->videomode;
812
813 r = omapdss_register_display(dssdev);
814 if (r) {
815 dev_err(&spi->dev, "Failed to register panel\n");
816 goto err_reg;
817 }
818
819 return 0;
820
821err_reg:
822 sysfs_remove_group(&bldev->dev.kobj, &bldev_attr_group);
823err_sysfs:
824 backlight_device_unregister(bldev);
825err_detect:
826err_gpio:
827 omap_dss_put_device(ddata->in);
828 return r;
829}
830
831static int acx565akm_remove(struct spi_device *spi)
832{
833 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
834 struct omap_dss_device *dssdev = &ddata->dssdev;
835 struct omap_dss_device *in = ddata->in;
836
837 dev_dbg(&ddata->spi->dev, "%s\n", __func__);
838
839 sysfs_remove_group(&ddata->bl_dev->dev.kobj, &bldev_attr_group);
840 backlight_device_unregister(ddata->bl_dev);
841
842 omapdss_unregister_display(dssdev);
843
844 acx565akm_disable(dssdev);
845 acx565akm_disconnect(dssdev);
846
847 omap_dss_put_device(in);
848
849 return 0;
850}
851
852static struct spi_driver acx565akm_driver = {
853 .driver = {
854 .name = "acx565akm",
855 .owner = THIS_MODULE,
856 },
857 .probe = acx565akm_probe,
858 .remove = acx565akm_remove,
859};
860
861module_spi_driver(acx565akm_driver);
862
863MODULE_AUTHOR("Nokia Corporation");
864MODULE_DESCRIPTION("acx565akm LCD Driver");
865MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c
new file mode 100644
index 000000000000..eadc6529fa3d
--- /dev/null
+++ b/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c
@@ -0,0 +1,646 @@
1/*
2 * TPO TD043MTEA1 Panel driver
3 *
4 * Author: Gražvydas Ignotas <notasas@gmail.com>
5 * Converted to new DSS device model: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/delay.h>
15#include <linux/spi/spi.h>
16#include <linux/regulator/consumer.h>
17#include <linux/gpio.h>
18#include <linux/err.h>
19#include <linux/slab.h>
20
21#include <video/omapdss.h>
22#include <video/omap-panel-data.h>
23
24#define TPO_R02_MODE(x) ((x) & 7)
25#define TPO_R02_MODE_800x480 7
26#define TPO_R02_NCLK_RISING BIT(3)
27#define TPO_R02_HSYNC_HIGH BIT(4)
28#define TPO_R02_VSYNC_HIGH BIT(5)
29
30#define TPO_R03_NSTANDBY BIT(0)
31#define TPO_R03_EN_CP_CLK BIT(1)
32#define TPO_R03_EN_VGL_PUMP BIT(2)
33#define TPO_R03_EN_PWM BIT(3)
34#define TPO_R03_DRIVING_CAP_100 BIT(4)
35#define TPO_R03_EN_PRE_CHARGE BIT(6)
36#define TPO_R03_SOFTWARE_CTL BIT(7)
37
38#define TPO_R04_NFLIP_H BIT(0)
39#define TPO_R04_NFLIP_V BIT(1)
40#define TPO_R04_CP_CLK_FREQ_1H BIT(2)
41#define TPO_R04_VGL_FREQ_1H BIT(4)
42
43#define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \
44 TPO_R03_EN_VGL_PUMP | TPO_R03_EN_PWM | \
45 TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
46 TPO_R03_SOFTWARE_CTL)
47
48#define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \
49 TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
50
51static const u16 tpo_td043_def_gamma[12] = {
52 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
53};
54
55struct panel_drv_data {
56 struct omap_dss_device dssdev;
57 struct omap_dss_device *in;
58
59 struct omap_video_timings videomode;
60
61 int data_lines;
62
63 struct spi_device *spi;
64 struct regulator *vcc_reg;
65 int nreset_gpio;
66 u16 gamma[12];
67 u32 mode;
68 u32 hmirror:1;
69 u32 vmirror:1;
70 u32 powered_on:1;
71 u32 spi_suspended:1;
72 u32 power_on_resume:1;
73};
74
75static const struct omap_video_timings tpo_td043_timings = {
76 .x_res = 800,
77 .y_res = 480,
78
79 .pixel_clock = 36000,
80
81 .hsw = 1,
82 .hfp = 68,
83 .hbp = 214,
84
85 .vsw = 1,
86 .vfp = 39,
87 .vbp = 34,
88
89 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
90 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
91 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
92 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
93 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
94};
95
96#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
97
98static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
99{
100 struct spi_message m;
101 struct spi_transfer xfer;
102 u16 w;
103 int r;
104
105 spi_message_init(&m);
106
107 memset(&xfer, 0, sizeof(xfer));
108
109 w = ((u16)addr << 10) | (1 << 8) | data;
110 xfer.tx_buf = &w;
111 xfer.bits_per_word = 16;
112 xfer.len = 2;
113 spi_message_add_tail(&xfer, &m);
114
115 r = spi_sync(spi, &m);
116 if (r < 0)
117 dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r);
118 return r;
119}
120
121static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12])
122{
123 u8 i, val;
124
125 /* gamma bits [9:8] */
126 for (val = i = 0; i < 4; i++)
127 val |= (gamma[i] & 0x300) >> ((i + 1) * 2);
128 tpo_td043_write(spi, 0x11, val);
129
130 for (val = i = 0; i < 4; i++)
131 val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2);
132 tpo_td043_write(spi, 0x12, val);
133
134 for (val = i = 0; i < 4; i++)
135 val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2);
136 tpo_td043_write(spi, 0x13, val);
137
138 /* gamma bits [7:0] */
139 for (val = i = 0; i < 12; i++)
140 tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff);
141}
142
143static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v)
144{
145 u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V |
146 TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H;
147 if (h)
148 reg4 &= ~TPO_R04_NFLIP_H;
149 if (v)
150 reg4 &= ~TPO_R04_NFLIP_V;
151
152 return tpo_td043_write(spi, 4, reg4);
153}
154
155static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
156{
157 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
158
159 ddata->hmirror = enable;
160 return tpo_td043_write_mirror(ddata->spi, ddata->hmirror,
161 ddata->vmirror);
162}
163
164static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev)
165{
166 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
167
168 return ddata->hmirror;
169}
170
171static ssize_t tpo_td043_vmirror_show(struct device *dev,
172 struct device_attribute *attr, char *buf)
173{
174 struct panel_drv_data *ddata = dev_get_drvdata(dev);
175
176 return snprintf(buf, PAGE_SIZE, "%d\n", ddata->vmirror);
177}
178
179static ssize_t tpo_td043_vmirror_store(struct device *dev,
180 struct device_attribute *attr, const char *buf, size_t count)
181{
182 struct panel_drv_data *ddata = dev_get_drvdata(dev);
183 int val;
184 int ret;
185
186 ret = kstrtoint(buf, 0, &val);
187 if (ret < 0)
188 return ret;
189
190 val = !!val;
191
192 ret = tpo_td043_write_mirror(ddata->spi, ddata->hmirror, val);
193 if (ret < 0)
194 return ret;
195
196 ddata->vmirror = val;
197
198 return count;
199}
200
201static ssize_t tpo_td043_mode_show(struct device *dev,
202 struct device_attribute *attr, char *buf)
203{
204 struct panel_drv_data *ddata = dev_get_drvdata(dev);
205
206 return snprintf(buf, PAGE_SIZE, "%d\n", ddata->mode);
207}
208
209static ssize_t tpo_td043_mode_store(struct device *dev,
210 struct device_attribute *attr, const char *buf, size_t count)
211{
212 struct panel_drv_data *ddata = dev_get_drvdata(dev);
213 long val;
214 int ret;
215
216 ret = kstrtol(buf, 0, &val);
217 if (ret != 0 || val & ~7)
218 return -EINVAL;
219
220 ddata->mode = val;
221
222 val |= TPO_R02_NCLK_RISING;
223 tpo_td043_write(ddata->spi, 2, val);
224
225 return count;
226}
227
228static ssize_t tpo_td043_gamma_show(struct device *dev,
229 struct device_attribute *attr, char *buf)
230{
231 struct panel_drv_data *ddata = dev_get_drvdata(dev);
232 ssize_t len = 0;
233 int ret;
234 int i;
235
236 for (i = 0; i < ARRAY_SIZE(ddata->gamma); i++) {
237 ret = snprintf(buf + len, PAGE_SIZE - len, "%u ",
238 ddata->gamma[i]);
239 if (ret < 0)
240 return ret;
241 len += ret;
242 }
243 buf[len - 1] = '\n';
244
245 return len;
246}
247
248static ssize_t tpo_td043_gamma_store(struct device *dev,
249 struct device_attribute *attr, const char *buf, size_t count)
250{
251 struct panel_drv_data *ddata = dev_get_drvdata(dev);
252 unsigned int g[12];
253 int ret;
254 int i;
255
256 ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u",
257 &g[0], &g[1], &g[2], &g[3], &g[4], &g[5],
258 &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]);
259
260 if (ret != 12)
261 return -EINVAL;
262
263 for (i = 0; i < 12; i++)
264 ddata->gamma[i] = g[i];
265
266 tpo_td043_write_gamma(ddata->spi, ddata->gamma);
267
268 return count;
269}
270
271static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR,
272 tpo_td043_vmirror_show, tpo_td043_vmirror_store);
273static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
274 tpo_td043_mode_show, tpo_td043_mode_store);
275static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR,
276 tpo_td043_gamma_show, tpo_td043_gamma_store);
277
278static struct attribute *tpo_td043_attrs[] = {
279 &dev_attr_vmirror.attr,
280 &dev_attr_mode.attr,
281 &dev_attr_gamma.attr,
282 NULL,
283};
284
285static struct attribute_group tpo_td043_attr_group = {
286 .attrs = tpo_td043_attrs,
287};
288
289static int tpo_td043_power_on(struct panel_drv_data *ddata)
290{
291 int r;
292
293 if (ddata->powered_on)
294 return 0;
295
296 r = regulator_enable(ddata->vcc_reg);
297 if (r != 0)
298 return r;
299
300 /* wait for panel to stabilize */
301 msleep(160);
302
303 if (gpio_is_valid(ddata->nreset_gpio))
304 gpio_set_value(ddata->nreset_gpio, 1);
305
306 tpo_td043_write(ddata->spi, 2,
307 TPO_R02_MODE(ddata->mode) | TPO_R02_NCLK_RISING);
308 tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_NORMAL);
309 tpo_td043_write(ddata->spi, 0x20, 0xf0);
310 tpo_td043_write(ddata->spi, 0x21, 0xf0);
311 tpo_td043_write_mirror(ddata->spi, ddata->hmirror,
312 ddata->vmirror);
313 tpo_td043_write_gamma(ddata->spi, ddata->gamma);
314
315 ddata->powered_on = 1;
316 return 0;
317}
318
319static void tpo_td043_power_off(struct panel_drv_data *ddata)
320{
321 if (!ddata->powered_on)
322 return;
323
324 tpo_td043_write(ddata->spi, 3,
325 TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
326
327 if (gpio_is_valid(ddata->nreset_gpio))
328 gpio_set_value(ddata->nreset_gpio, 0);
329
330 /* wait for at least 2 vsyncs before cutting off power */
331 msleep(50);
332
333 tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_STANDBY);
334
335 regulator_disable(ddata->vcc_reg);
336
337 ddata->powered_on = 0;
338}
339
340static int tpo_td043_connect(struct omap_dss_device *dssdev)
341{
342 struct panel_drv_data *ddata = to_panel_data(dssdev);
343 struct omap_dss_device *in = ddata->in;
344 int r;
345
346 if (omapdss_device_is_connected(dssdev))
347 return 0;
348
349 r = in->ops.dpi->connect(in, dssdev);
350 if (r)
351 return r;
352
353 return 0;
354}
355
356static void tpo_td043_disconnect(struct omap_dss_device *dssdev)
357{
358 struct panel_drv_data *ddata = to_panel_data(dssdev);
359 struct omap_dss_device *in = ddata->in;
360
361 if (!omapdss_device_is_connected(dssdev))
362 return;
363
364 in->ops.dpi->disconnect(in, dssdev);
365}
366
367static int tpo_td043_enable(struct omap_dss_device *dssdev)
368{
369 struct panel_drv_data *ddata = to_panel_data(dssdev);
370 struct omap_dss_device *in = ddata->in;
371 int r;
372
373 if (!omapdss_device_is_connected(dssdev))
374 return -ENODEV;
375
376 if (omapdss_device_is_enabled(dssdev))
377 return 0;
378
379 in->ops.dpi->set_data_lines(in, ddata->data_lines);
380 in->ops.dpi->set_timings(in, &ddata->videomode);
381
382 r = in->ops.dpi->enable(in);
383 if (r)
384 return r;
385
386 /*
387 * If we are resuming from system suspend, SPI clocks might not be
388 * enabled yet, so we'll program the LCD from SPI PM resume callback.
389 */
390 if (!ddata->spi_suspended) {
391 r = tpo_td043_power_on(ddata);
392 if (r) {
393 in->ops.dpi->disable(in);
394 return r;
395 }
396 }
397
398 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
399
400 return 0;
401}
402
403static void tpo_td043_disable(struct omap_dss_device *dssdev)
404{
405 struct panel_drv_data *ddata = to_panel_data(dssdev);
406 struct omap_dss_device *in = ddata->in;
407
408 if (!omapdss_device_is_enabled(dssdev))
409 return;
410
411 in->ops.dpi->disable(in);
412
413 if (!ddata->spi_suspended)
414 tpo_td043_power_off(ddata);
415
416 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
417}
418
419static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
420 struct omap_video_timings *timings)
421{
422 struct panel_drv_data *ddata = to_panel_data(dssdev);
423 struct omap_dss_device *in = ddata->in;
424
425 ddata->videomode = *timings;
426 dssdev->panel.timings = *timings;
427
428 in->ops.dpi->set_timings(in, timings);
429}
430
431static void tpo_td043_get_timings(struct omap_dss_device *dssdev,
432 struct omap_video_timings *timings)
433{
434 struct panel_drv_data *ddata = to_panel_data(dssdev);
435
436 *timings = ddata->videomode;
437}
438
439static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
440 struct omap_video_timings *timings)
441{
442 struct panel_drv_data *ddata = to_panel_data(dssdev);
443 struct omap_dss_device *in = ddata->in;
444
445 return in->ops.dpi->check_timings(in, timings);
446}
447
448static struct omap_dss_driver tpo_td043_ops = {
449 .connect = tpo_td043_connect,
450 .disconnect = tpo_td043_disconnect,
451
452 .enable = tpo_td043_enable,
453 .disable = tpo_td043_disable,
454
455 .set_timings = tpo_td043_set_timings,
456 .get_timings = tpo_td043_get_timings,
457 .check_timings = tpo_td043_check_timings,
458
459 .set_mirror = tpo_td043_set_hmirror,
460 .get_mirror = tpo_td043_get_hmirror,
461
462 .get_resolution = omapdss_default_get_resolution,
463};
464
465
466static int tpo_td043_probe_pdata(struct spi_device *spi)
467{
468 const struct panel_tpo_td043mtea1_platform_data *pdata;
469 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
470 struct omap_dss_device *dssdev, *in;
471
472 pdata = dev_get_platdata(&spi->dev);
473
474 ddata->nreset_gpio = pdata->nreset_gpio;
475
476 in = omap_dss_find_output(pdata->source);
477 if (in == NULL) {
478 dev_err(&spi->dev, "failed to find video source '%s'\n",
479 pdata->source);
480 return -EPROBE_DEFER;
481 }
482 ddata->in = in;
483
484 ddata->data_lines = pdata->data_lines;
485
486 dssdev = &ddata->dssdev;
487 dssdev->name = pdata->name;
488
489 return 0;
490}
491
492static int tpo_td043_probe(struct spi_device *spi)
493{
494 struct panel_drv_data *ddata;
495 struct omap_dss_device *dssdev;
496 int r;
497
498 dev_dbg(&spi->dev, "%s\n", __func__);
499
500 spi->bits_per_word = 16;
501 spi->mode = SPI_MODE_0;
502
503 r = spi_setup(spi);
504 if (r < 0) {
505 dev_err(&spi->dev, "spi_setup failed: %d\n", r);
506 return r;
507 }
508
509 ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
510 if (ddata == NULL)
511 return -ENOMEM;
512
513 dev_set_drvdata(&spi->dev, ddata);
514
515 ddata->spi = spi;
516
517 if (dev_get_platdata(&spi->dev)) {
518 r = tpo_td043_probe_pdata(spi);
519 if (r)
520 return r;
521 } else {
522 return -ENODEV;
523 }
524
525 ddata->mode = TPO_R02_MODE_800x480;
526 memcpy(ddata->gamma, tpo_td043_def_gamma, sizeof(ddata->gamma));
527
528 ddata->vcc_reg = devm_regulator_get(&spi->dev, "vcc");
529 if (IS_ERR(ddata->vcc_reg)) {
530 dev_err(&spi->dev, "failed to get LCD VCC regulator\n");
531 r = PTR_ERR(ddata->vcc_reg);
532 goto err_regulator;
533 }
534
535 if (gpio_is_valid(ddata->nreset_gpio)) {
536 r = devm_gpio_request_one(&spi->dev,
537 ddata->nreset_gpio, GPIOF_OUT_INIT_LOW,
538 "lcd reset");
539 if (r < 0) {
540 dev_err(&spi->dev, "couldn't request reset GPIO\n");
541 goto err_gpio_req;
542 }
543 }
544
545 r = sysfs_create_group(&spi->dev.kobj, &tpo_td043_attr_group);
546 if (r) {
547 dev_err(&spi->dev, "failed to create sysfs files\n");
548 goto err_sysfs;
549 }
550
551 ddata->videomode = tpo_td043_timings;
552
553 dssdev = &ddata->dssdev;
554 dssdev->dev = &spi->dev;
555 dssdev->driver = &tpo_td043_ops;
556 dssdev->type = OMAP_DISPLAY_TYPE_DPI;
557 dssdev->owner = THIS_MODULE;
558 dssdev->panel.timings = ddata->videomode;
559
560 r = omapdss_register_display(dssdev);
561 if (r) {
562 dev_err(&spi->dev, "Failed to register panel\n");
563 goto err_reg;
564 }
565
566 return 0;
567
568err_reg:
569 sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);
570err_sysfs:
571err_gpio_req:
572err_regulator:
573 omap_dss_put_device(ddata->in);
574 return r;
575}
576
577static int tpo_td043_remove(struct spi_device *spi)
578{
579 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
580 struct omap_dss_device *dssdev = &ddata->dssdev;
581 struct omap_dss_device *in = ddata->in;
582
583 dev_dbg(&ddata->spi->dev, "%s\n", __func__);
584
585 omapdss_unregister_display(dssdev);
586
587 tpo_td043_disable(dssdev);
588 tpo_td043_disconnect(dssdev);
589
590 omap_dss_put_device(in);
591
592 sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);
593
594 return 0;
595}
596
597#ifdef CONFIG_PM_SLEEP
598static int tpo_td043_spi_suspend(struct device *dev)
599{
600 struct panel_drv_data *ddata = dev_get_drvdata(dev);
601
602 dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", ddata);
603
604 ddata->power_on_resume = ddata->powered_on;
605 tpo_td043_power_off(ddata);
606 ddata->spi_suspended = 1;
607
608 return 0;
609}
610
611static int tpo_td043_spi_resume(struct device *dev)
612{
613 struct panel_drv_data *ddata = dev_get_drvdata(dev);
614 int ret;
615
616 dev_dbg(dev, "tpo_td043_spi_resume\n");
617
618 if (ddata->power_on_resume) {
619 ret = tpo_td043_power_on(ddata);
620 if (ret)
621 return ret;
622 }
623 ddata->spi_suspended = 0;
624
625 return 0;
626}
627#endif
628
629static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,
630 tpo_td043_spi_suspend, tpo_td043_spi_resume);
631
632static struct spi_driver tpo_td043_spi_driver = {
633 .driver = {
634 .name = "panel-tpo-td043mtea1",
635 .owner = THIS_MODULE,
636 .pm = &tpo_td043_spi_pm,
637 },
638 .probe = tpo_td043_probe,
639 .remove = tpo_td043_remove,
640};
641
642module_spi_driver(tpo_td043_spi_driver);
643
644MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
645MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
646MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index c3853c92279b..e80ac1c79561 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -1,4 +1,4 @@
1menu "OMAP2/3 Display Device Drivers" 1menu "OMAP2/3 Display Device Drivers (old device model)"
2 depends on OMAP2_DSS 2 depends on OMAP2_DSS
3 3
4config PANEL_GENERIC_DPI 4config PANEL_GENERIC_DPI
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index d7f69c09ecf1..3fd100fc853e 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -510,7 +510,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
510 int max_brightness, brightness; 510 int max_brightness, brightness;
511 struct backlight_properties props; 511 struct backlight_properties props;
512 512
513 dev_dbg(&dssdev->dev, "%s\n", __func__); 513 dev_dbg(dssdev->dev, "%s\n", __func__);
514 514
515 if (!panel_data) 515 if (!panel_data)
516 return -EINVAL; 516 return -EINVAL;
@@ -519,7 +519,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
519 dssdev->panel.timings = acx_panel_timings; 519 dssdev->panel.timings = acx_panel_timings;
520 520
521 if (gpio_is_valid(panel_data->reset_gpio)) { 521 if (gpio_is_valid(panel_data->reset_gpio)) {
522 r = devm_gpio_request_one(&dssdev->dev, panel_data->reset_gpio, 522 r = devm_gpio_request_one(dssdev->dev, panel_data->reset_gpio,
523 GPIOF_OUT_INIT_LOW, "lcd reset"); 523 GPIOF_OUT_INIT_LOW, "lcd reset");
524 if (r) 524 if (r)
525 return r; 525 return r;
@@ -538,7 +538,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
538 538
539 r = panel_detect(md); 539 r = panel_detect(md);
540 if (r) { 540 if (r) {
541 dev_err(&dssdev->dev, "%s panel detect error\n", __func__); 541 dev_err(dssdev->dev, "%s panel detect error\n", __func__);
542 if (!md->enabled && gpio_is_valid(panel_data->reset_gpio)) 542 if (!md->enabled && gpio_is_valid(panel_data->reset_gpio))
543 gpio_set_value(panel_data->reset_gpio, 0); 543 gpio_set_value(panel_data->reset_gpio, 0);
544 544
@@ -593,7 +593,7 @@ static void acx_panel_remove(struct omap_dss_device *dssdev)
593{ 593{
594 struct acx565akm_device *md = &acx_dev; 594 struct acx565akm_device *md = &acx_dev;
595 595
596 dev_dbg(&dssdev->dev, "%s\n", __func__); 596 dev_dbg(dssdev->dev, "%s\n", __func__);
597 sysfs_remove_group(&md->bl_dev->dev.kobj, &bldev_attr_group); 597 sysfs_remove_group(&md->bl_dev->dev.kobj, &bldev_attr_group);
598 backlight_device_unregister(md->bl_dev); 598 backlight_device_unregister(md->bl_dev);
599 mutex_lock(&acx_dev.mutex); 599 mutex_lock(&acx_dev.mutex);
@@ -607,7 +607,7 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
607 struct panel_acx565akm_data *panel_data = get_panel_data(dssdev); 607 struct panel_acx565akm_data *panel_data = get_panel_data(dssdev);
608 int r; 608 int r;
609 609
610 dev_dbg(&dssdev->dev, "%s\n", __func__); 610 dev_dbg(dssdev->dev, "%s\n", __func__);
611 611
612 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 612 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
613 return 0; 613 return 0;
@@ -667,7 +667,7 @@ static void acx_panel_power_off(struct omap_dss_device *dssdev)
667 struct acx565akm_device *md = &acx_dev; 667 struct acx565akm_device *md = &acx_dev;
668 struct panel_acx565akm_data *panel_data = get_panel_data(dssdev); 668 struct panel_acx565akm_data *panel_data = get_panel_data(dssdev);
669 669
670 dev_dbg(&dssdev->dev, "%s\n", __func__); 670 dev_dbg(dssdev->dev, "%s\n", __func__);
671 671
672 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 672 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
673 return; 673 return;
@@ -704,7 +704,7 @@ static int acx_panel_enable(struct omap_dss_device *dssdev)
704{ 704{
705 int r; 705 int r;
706 706
707 dev_dbg(&dssdev->dev, "%s\n", __func__); 707 dev_dbg(dssdev->dev, "%s\n", __func__);
708 r = acx_panel_power_on(dssdev); 708 r = acx_panel_power_on(dssdev);
709 709
710 if (r) 710 if (r)
@@ -716,7 +716,7 @@ static int acx_panel_enable(struct omap_dss_device *dssdev)
716 716
717static void acx_panel_disable(struct omap_dss_device *dssdev) 717static void acx_panel_disable(struct omap_dss_device *dssdev)
718{ 718{
719 dev_dbg(&dssdev->dev, "%s\n", __func__); 719 dev_dbg(dssdev->dev, "%s\n", __func__);
720 acx_panel_power_off(dssdev); 720 acx_panel_power_off(dssdev);
721 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 721 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
722} 722}
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 97363f733683..bebebd45847f 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -536,7 +536,7 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
536{ 536{
537 int r, i; 537 int r, i;
538 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); 538 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
539 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); 539 struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
540 struct panel_config *panel_config = drv_data->panel_config; 540 struct panel_config *panel_config = drv_data->panel_config;
541 541
542 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 542 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
@@ -567,7 +567,7 @@ err0:
567static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev) 567static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
568{ 568{
569 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); 569 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
570 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); 570 struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
571 struct panel_config *panel_config = drv_data->panel_config; 571 struct panel_config *panel_config = drv_data->panel_config;
572 int i; 572 int i;
573 573
@@ -593,7 +593,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
593 struct panel_drv_data *drv_data = NULL; 593 struct panel_drv_data *drv_data = NULL;
594 int i, r; 594 int i, r;
595 595
596 dev_dbg(&dssdev->dev, "probe\n"); 596 dev_dbg(dssdev->dev, "probe\n");
597 597
598 if (!panel_data || !panel_data->name) 598 if (!panel_data || !panel_data->name)
599 return -EINVAL; 599 return -EINVAL;
@@ -609,7 +609,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
609 return -EINVAL; 609 return -EINVAL;
610 610
611 for (i = 0; i < panel_data->num_gpios; ++i) { 611 for (i = 0; i < panel_data->num_gpios; ++i) {
612 r = devm_gpio_request_one(&dssdev->dev, panel_data->gpios[i], 612 r = devm_gpio_request_one(dssdev->dev, panel_data->gpios[i],
613 panel_data->gpio_invert[i] ? 613 panel_data->gpio_invert[i] ?
614 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, 614 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
615 "panel gpio"); 615 "panel gpio");
@@ -619,7 +619,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
619 619
620 dssdev->panel.timings = panel_config->timings; 620 dssdev->panel.timings = panel_config->timings;
621 621
622 drv_data = devm_kzalloc(&dssdev->dev, sizeof(*drv_data), GFP_KERNEL); 622 drv_data = devm_kzalloc(dssdev->dev, sizeof(*drv_data), GFP_KERNEL);
623 if (!drv_data) 623 if (!drv_data)
624 return -ENOMEM; 624 return -ENOMEM;
625 625
@@ -628,21 +628,21 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
628 628
629 mutex_init(&drv_data->lock); 629 mutex_init(&drv_data->lock);
630 630
631 dev_set_drvdata(&dssdev->dev, drv_data); 631 dev_set_drvdata(dssdev->dev, drv_data);
632 632
633 return 0; 633 return 0;
634} 634}
635 635
636static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev) 636static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
637{ 637{
638 dev_dbg(&dssdev->dev, "remove\n"); 638 dev_dbg(dssdev->dev, "remove\n");
639 639
640 dev_set_drvdata(&dssdev->dev, NULL); 640 dev_set_drvdata(dssdev->dev, NULL);
641} 641}
642 642
643static int generic_dpi_panel_enable(struct omap_dss_device *dssdev) 643static int generic_dpi_panel_enable(struct omap_dss_device *dssdev)
644{ 644{
645 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); 645 struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
646 int r; 646 int r;
647 647
648 mutex_lock(&drv_data->lock); 648 mutex_lock(&drv_data->lock);
@@ -660,7 +660,7 @@ err:
660 660
661static void generic_dpi_panel_disable(struct omap_dss_device *dssdev) 661static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
662{ 662{
663 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); 663 struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
664 664
665 mutex_lock(&drv_data->lock); 665 mutex_lock(&drv_data->lock);
666 666
@@ -674,7 +674,7 @@ static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
674static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev, 674static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
675 struct omap_video_timings *timings) 675 struct omap_video_timings *timings)
676{ 676{
677 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); 677 struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
678 678
679 mutex_lock(&drv_data->lock); 679 mutex_lock(&drv_data->lock);
680 680
@@ -688,7 +688,7 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
688static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev, 688static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
689 struct omap_video_timings *timings) 689 struct omap_video_timings *timings)
690{ 690{
691 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); 691 struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
692 692
693 mutex_lock(&drv_data->lock); 693 mutex_lock(&drv_data->lock);
694 694
@@ -700,7 +700,7 @@ static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
700static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev, 700static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
701 struct omap_video_timings *timings) 701 struct omap_video_timings *timings)
702{ 702{
703 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); 703 struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev);
704 int r; 704 int r;
705 705
706 mutex_lock(&drv_data->lock); 706 mutex_lock(&drv_data->lock);
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 4ea6548c0ae9..6c51430ddb37 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -109,12 +109,12 @@ static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
109 109
110 dssdev->panel.timings = lb035q02_timings; 110 dssdev->panel.timings = lb035q02_timings;
111 111
112 ld = devm_kzalloc(&dssdev->dev, sizeof(*ld), GFP_KERNEL); 112 ld = devm_kzalloc(dssdev->dev, sizeof(*ld), GFP_KERNEL);
113 if (!ld) 113 if (!ld)
114 return -ENOMEM; 114 return -ENOMEM;
115 115
116 for (i = 0; i < panel_data->num_gpios; ++i) { 116 for (i = 0; i < panel_data->num_gpios; ++i) {
117 r = devm_gpio_request_one(&dssdev->dev, panel_data->gpios[i], 117 r = devm_gpio_request_one(dssdev->dev, panel_data->gpios[i],
118 panel_data->gpio_invert[i] ? 118 panel_data->gpio_invert[i] ?
119 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, 119 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
120 "panel gpio"); 120 "panel gpio");
@@ -123,7 +123,7 @@ static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
123 } 123 }
124 124
125 mutex_init(&ld->lock); 125 mutex_init(&ld->lock);
126 dev_set_drvdata(&dssdev->dev, ld); 126 dev_set_drvdata(dssdev->dev, ld);
127 127
128 return 0; 128 return 0;
129} 129}
@@ -134,7 +134,7 @@ static void lb035q02_panel_remove(struct omap_dss_device *dssdev)
134 134
135static int lb035q02_panel_enable(struct omap_dss_device *dssdev) 135static int lb035q02_panel_enable(struct omap_dss_device *dssdev)
136{ 136{
137 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev); 137 struct lb035q02_data *ld = dev_get_drvdata(dssdev->dev);
138 int r; 138 int r;
139 139
140 mutex_lock(&ld->lock); 140 mutex_lock(&ld->lock);
@@ -153,7 +153,7 @@ err:
153 153
154static void lb035q02_panel_disable(struct omap_dss_device *dssdev) 154static void lb035q02_panel_disable(struct omap_dss_device *dssdev)
155{ 155{
156 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev); 156 struct lb035q02_data *ld = dev_get_drvdata(dssdev->dev);
157 157
158 mutex_lock(&ld->lock); 158 mutex_lock(&ld->lock);
159 159
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 860b18014ad7..1d525fc84db9 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -311,16 +311,16 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
311 switch (rev & 0xfc) { 311 switch (rev & 0xfc) {
312 case 0x9c: 312 case 0x9c:
313 ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744; 313 ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744;
314 dev_info(&dssdev->dev, "s1d13744 LCD controller rev %d " 314 dev_info(dssdev->dev, "s1d13744 LCD controller rev %d "
315 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); 315 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
316 break; 316 break;
317 case 0xa4: 317 case 0xa4:
318 ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745; 318 ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745;
319 dev_info(&dssdev->dev, "s1d13745 LCD controller rev %d " 319 dev_info(dssdev->dev, "s1d13745 LCD controller rev %d "
320 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); 320 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
321 break; 321 break;
322 default: 322 default:
323 dev_err(&dssdev->dev, "invalid s1d1374x revision %02x\n", rev); 323 dev_err(dssdev->dev, "invalid s1d1374x revision %02x\n", rev);
324 r = -ENODEV; 324 r = -ENODEV;
325 goto err_inv_chip; 325 goto err_inv_chip;
326 } 326 }
@@ -341,13 +341,13 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
341 panel_name = "ls041y3"; 341 panel_name = "ls041y3";
342 break; 342 break;
343 default: 343 default:
344 dev_err(&dssdev->dev, "invalid display ID 0x%x\n", 344 dev_err(dssdev->dev, "invalid display ID 0x%x\n",
345 display_id[0]); 345 display_id[0]);
346 r = -ENODEV; 346 r = -ENODEV;
347 goto err_inv_panel; 347 goto err_inv_panel;
348 } 348 }
349 349
350 dev_info(&dssdev->dev, "%s rev %02x LCD detected\n", 350 dev_info(dssdev->dev, "%s rev %02x LCD detected\n",
351 panel_name, display_id[1]); 351 panel_name, display_id[1]);
352 352
353 send_sleep_out(spi); 353 send_sleep_out(spi);
@@ -416,7 +416,7 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
416 struct panel_drv_data *ddata; 416 struct panel_drv_data *ddata;
417 int r; 417 int r;
418 418
419 dev_dbg(&dssdev->dev, "probe\n"); 419 dev_dbg(dssdev->dev, "probe\n");
420 420
421 if (!bdata) 421 if (!bdata)
422 return -EINVAL; 422 return -EINVAL;
@@ -434,14 +434,14 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
434 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 434 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
435 435
436 if (gpio_is_valid(bdata->panel_reset)) { 436 if (gpio_is_valid(bdata->panel_reset)) {
437 r = devm_gpio_request_one(&dssdev->dev, bdata->panel_reset, 437 r = devm_gpio_request_one(dssdev->dev, bdata->panel_reset,
438 GPIOF_OUT_INIT_LOW, "PANEL RESET"); 438 GPIOF_OUT_INIT_LOW, "PANEL RESET");
439 if (r) 439 if (r)
440 return r; 440 return r;
441 } 441 }
442 442
443 if (gpio_is_valid(bdata->ctrl_pwrdown)) { 443 if (gpio_is_valid(bdata->ctrl_pwrdown)) {
444 r = devm_gpio_request_one(&dssdev->dev, bdata->ctrl_pwrdown, 444 r = devm_gpio_request_one(dssdev->dev, bdata->ctrl_pwrdown,
445 GPIOF_OUT_INIT_LOW, "PANEL PWRDOWN"); 445 GPIOF_OUT_INIT_LOW, "PANEL PWRDOWN");
446 if (r) 446 if (r)
447 return r; 447 return r;
@@ -452,9 +452,9 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
452 452
453static void n8x0_panel_remove(struct omap_dss_device *dssdev) 453static void n8x0_panel_remove(struct omap_dss_device *dssdev)
454{ 454{
455 dev_dbg(&dssdev->dev, "remove\n"); 455 dev_dbg(dssdev->dev, "remove\n");
456 456
457 dev_set_drvdata(&dssdev->dev, NULL); 457 dev_set_drvdata(dssdev->dev, NULL);
458} 458}
459 459
460static int n8x0_panel_enable(struct omap_dss_device *dssdev) 460static int n8x0_panel_enable(struct omap_dss_device *dssdev)
@@ -462,7 +462,7 @@ static int n8x0_panel_enable(struct omap_dss_device *dssdev)
462 struct panel_drv_data *ddata = get_drv_data(dssdev); 462 struct panel_drv_data *ddata = get_drv_data(dssdev);
463 int r; 463 int r;
464 464
465 dev_dbg(&dssdev->dev, "enable\n"); 465 dev_dbg(dssdev->dev, "enable\n");
466 466
467 mutex_lock(&ddata->lock); 467 mutex_lock(&ddata->lock);
468 468
@@ -488,7 +488,7 @@ static void n8x0_panel_disable(struct omap_dss_device *dssdev)
488{ 488{
489 struct panel_drv_data *ddata = get_drv_data(dssdev); 489 struct panel_drv_data *ddata = get_drv_data(dssdev);
490 490
491 dev_dbg(&dssdev->dev, "disable\n"); 491 dev_dbg(dssdev->dev, "disable\n");
492 492
493 mutex_lock(&ddata->lock); 493 mutex_lock(&ddata->lock);
494 494
@@ -521,13 +521,13 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev,
521 struct panel_drv_data *ddata = get_drv_data(dssdev); 521 struct panel_drv_data *ddata = get_drv_data(dssdev);
522 u16 dw, dh; 522 u16 dw, dh;
523 523
524 dev_dbg(&dssdev->dev, "update\n"); 524 dev_dbg(dssdev->dev, "update\n");
525 525
526 dw = dssdev->panel.timings.x_res; 526 dw = dssdev->panel.timings.x_res;
527 dh = dssdev->panel.timings.y_res; 527 dh = dssdev->panel.timings.y_res;
528 528
529 if (x != 0 || y != 0 || w != dw || h != dh) { 529 if (x != 0 || y != 0 || w != dw || h != dh) {
530 dev_err(&dssdev->dev, "invalid update region %d, %d, %d, %d\n", 530 dev_err(dssdev->dev, "invalid update region %d, %d, %d, %d\n",
531 x, y, w, h); 531 x, y, w, h);
532 return -EINVAL; 532 return -EINVAL;
533 } 533 }
@@ -548,7 +548,7 @@ static int n8x0_panel_sync(struct omap_dss_device *dssdev)
548{ 548{
549 struct panel_drv_data *ddata = get_drv_data(dssdev); 549 struct panel_drv_data *ddata = get_drv_data(dssdev);
550 550
551 dev_dbg(&dssdev->dev, "sync\n"); 551 dev_dbg(dssdev->dev, "sync\n");
552 552
553 mutex_lock(&ddata->lock); 553 mutex_lock(&ddata->lock);
554 rfbi_bus_lock(); 554 rfbi_bus_lock();
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 20c3cd91ff9b..6b9f7925e918 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -98,14 +98,14 @@ static int nec_8048_panel_probe(struct omap_dss_device *dssdev)
98 dssdev->panel.timings = nec_8048_panel_timings; 98 dssdev->panel.timings = nec_8048_panel_timings;
99 99
100 if (gpio_is_valid(pd->qvga_gpio)) { 100 if (gpio_is_valid(pd->qvga_gpio)) {
101 r = devm_gpio_request_one(&dssdev->dev, pd->qvga_gpio, 101 r = devm_gpio_request_one(dssdev->dev, pd->qvga_gpio,
102 GPIOF_OUT_INIT_HIGH, "lcd QVGA"); 102 GPIOF_OUT_INIT_HIGH, "lcd QVGA");
103 if (r) 103 if (r)
104 return r; 104 return r;
105 } 105 }
106 106
107 if (gpio_is_valid(pd->res_gpio)) { 107 if (gpio_is_valid(pd->res_gpio)) {
108 r = devm_gpio_request_one(&dssdev->dev, pd->res_gpio, 108 r = devm_gpio_request_one(dssdev->dev, pd->res_gpio,
109 GPIOF_OUT_INIT_LOW, "lcd RES"); 109 GPIOF_OUT_INIT_LOW, "lcd RES");
110 if (r) 110 if (r)
111 return r; 111 return r;
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 62f2db04fbc8..153e9bea0f6e 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -351,7 +351,7 @@ static struct i2c_driver picodlp_i2c_driver = {
351static int picodlp_panel_power_on(struct omap_dss_device *dssdev) 351static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
352{ 352{
353 int r, trial = 100; 353 int r, trial = 100;
354 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); 354 struct picodlp_data *picod = dev_get_drvdata(dssdev->dev);
355 struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev); 355 struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
356 356
357 gpio_set_value(picodlp_pdata->pwrgood_gpio, 0); 357 gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
@@ -360,7 +360,7 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
360 360
361 while (!gpio_get_value(picodlp_pdata->emu_done_gpio)) { 361 while (!gpio_get_value(picodlp_pdata->emu_done_gpio)) {
362 if (!trial--) { 362 if (!trial--) {
363 dev_err(&dssdev->dev, "emu_done signal not" 363 dev_err(dssdev->dev, "emu_done signal not"
364 " going high\n"); 364 " going high\n");
365 return -ETIMEDOUT; 365 return -ETIMEDOUT;
366 } 366 }
@@ -378,7 +378,7 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
378 378
379 r = omapdss_dpi_display_enable(dssdev); 379 r = omapdss_dpi_display_enable(dssdev);
380 if (r) { 380 if (r) {
381 dev_err(&dssdev->dev, "failed to enable DPI\n"); 381 dev_err(dssdev->dev, "failed to enable DPI\n");
382 goto err1; 382 goto err1;
383 } 383 }
384 384
@@ -418,7 +418,7 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
418 if (!picodlp_pdata) 418 if (!picodlp_pdata)
419 return -EINVAL; 419 return -EINVAL;
420 420
421 picod = devm_kzalloc(&dssdev->dev, sizeof(*picod), GFP_KERNEL); 421 picod = devm_kzalloc(dssdev->dev, sizeof(*picod), GFP_KERNEL);
422 if (!picod) 422 if (!picod)
423 return -ENOMEM; 423 return -ENOMEM;
424 424
@@ -428,23 +428,23 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
428 428
429 adapter = i2c_get_adapter(picodlp_adapter_id); 429 adapter = i2c_get_adapter(picodlp_adapter_id);
430 if (!adapter) { 430 if (!adapter) {
431 dev_err(&dssdev->dev, "can't get i2c adapter\n"); 431 dev_err(dssdev->dev, "can't get i2c adapter\n");
432 return -ENODEV; 432 return -ENODEV;
433 } 433 }
434 434
435 picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info); 435 picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info);
436 if (!picodlp_i2c_client) { 436 if (!picodlp_i2c_client) {
437 dev_err(&dssdev->dev, "can't add i2c device::" 437 dev_err(dssdev->dev, "can't add i2c device::"
438 " picodlp_i2c_client is NULL\n"); 438 " picodlp_i2c_client is NULL\n");
439 return -ENODEV; 439 return -ENODEV;
440 } 440 }
441 441
442 picod->picodlp_i2c_client = picodlp_i2c_client; 442 picod->picodlp_i2c_client = picodlp_i2c_client;
443 443
444 dev_set_drvdata(&dssdev->dev, picod); 444 dev_set_drvdata(dssdev->dev, picod);
445 445
446 if (gpio_is_valid(picodlp_pdata->emu_done_gpio)) { 446 if (gpio_is_valid(picodlp_pdata->emu_done_gpio)) {
447 r = devm_gpio_request_one(&dssdev->dev, 447 r = devm_gpio_request_one(dssdev->dev,
448 picodlp_pdata->emu_done_gpio, 448 picodlp_pdata->emu_done_gpio,
449 GPIOF_IN, "DLP EMU DONE"); 449 GPIOF_IN, "DLP EMU DONE");
450 if (r) 450 if (r)
@@ -452,7 +452,7 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
452 } 452 }
453 453
454 if (gpio_is_valid(picodlp_pdata->pwrgood_gpio)) { 454 if (gpio_is_valid(picodlp_pdata->pwrgood_gpio)) {
455 r = devm_gpio_request_one(&dssdev->dev, 455 r = devm_gpio_request_one(dssdev->dev,
456 picodlp_pdata->pwrgood_gpio, 456 picodlp_pdata->pwrgood_gpio,
457 GPIOF_OUT_INIT_LOW, "DLP PWRGOOD"); 457 GPIOF_OUT_INIT_LOW, "DLP PWRGOOD");
458 if (r) 458 if (r)
@@ -464,21 +464,19 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
464 464
465static void picodlp_panel_remove(struct omap_dss_device *dssdev) 465static void picodlp_panel_remove(struct omap_dss_device *dssdev)
466{ 466{
467 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); 467 struct picodlp_data *picod = dev_get_drvdata(dssdev->dev);
468 468
469 i2c_unregister_device(picod->picodlp_i2c_client); 469 i2c_unregister_device(picod->picodlp_i2c_client);
470 dev_set_drvdata(&dssdev->dev, NULL); 470 dev_set_drvdata(dssdev->dev, NULL);
471 dev_dbg(&dssdev->dev, "removing picodlp panel\n"); 471 dev_dbg(dssdev->dev, "removing picodlp panel\n");
472
473 kfree(picod);
474} 472}
475 473
476static int picodlp_panel_enable(struct omap_dss_device *dssdev) 474static int picodlp_panel_enable(struct omap_dss_device *dssdev)
477{ 475{
478 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); 476 struct picodlp_data *picod = dev_get_drvdata(dssdev->dev);
479 int r; 477 int r;
480 478
481 dev_dbg(&dssdev->dev, "enabling picodlp panel\n"); 479 dev_dbg(dssdev->dev, "enabling picodlp panel\n");
482 480
483 mutex_lock(&picod->lock); 481 mutex_lock(&picod->lock);
484 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { 482 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
@@ -494,7 +492,7 @@ static int picodlp_panel_enable(struct omap_dss_device *dssdev)
494 492
495static void picodlp_panel_disable(struct omap_dss_device *dssdev) 493static void picodlp_panel_disable(struct omap_dss_device *dssdev)
496{ 494{
497 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); 495 struct picodlp_data *picod = dev_get_drvdata(dssdev->dev);
498 496
499 mutex_lock(&picod->lock); 497 mutex_lock(&picod->lock);
500 /* Turn off DLP Power */ 498 /* Turn off DLP Power */
@@ -504,7 +502,7 @@ static void picodlp_panel_disable(struct omap_dss_device *dssdev)
504 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 502 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
505 mutex_unlock(&picod->lock); 503 mutex_unlock(&picod->lock);
506 504
507 dev_dbg(&dssdev->dev, "disabling picodlp panel\n"); 505 dev_dbg(dssdev->dev, "disabling picodlp panel\n");
508} 506}
509 507
510static void picodlp_get_resolution(struct omap_dss_device *dssdev, 508static void picodlp_get_resolution(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index 74cb0eb45311..78f0a6779756 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -66,35 +66,35 @@ static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
66 dssdev->panel.timings = sharp_ls_timings; 66 dssdev->panel.timings = sharp_ls_timings;
67 67
68 if (gpio_is_valid(pd->mo_gpio)) { 68 if (gpio_is_valid(pd->mo_gpio)) {
69 r = devm_gpio_request_one(&dssdev->dev, pd->mo_gpio, 69 r = devm_gpio_request_one(dssdev->dev, pd->mo_gpio,
70 GPIOF_OUT_INIT_LOW, "lcd MO"); 70 GPIOF_OUT_INIT_LOW, "lcd MO");
71 if (r) 71 if (r)
72 return r; 72 return r;
73 } 73 }
74 74
75 if (gpio_is_valid(pd->lr_gpio)) { 75 if (gpio_is_valid(pd->lr_gpio)) {
76 r = devm_gpio_request_one(&dssdev->dev, pd->lr_gpio, 76 r = devm_gpio_request_one(dssdev->dev, pd->lr_gpio,
77 GPIOF_OUT_INIT_HIGH, "lcd LR"); 77 GPIOF_OUT_INIT_HIGH, "lcd LR");
78 if (r) 78 if (r)
79 return r; 79 return r;
80 } 80 }
81 81
82 if (gpio_is_valid(pd->ud_gpio)) { 82 if (gpio_is_valid(pd->ud_gpio)) {
83 r = devm_gpio_request_one(&dssdev->dev, pd->ud_gpio, 83 r = devm_gpio_request_one(dssdev->dev, pd->ud_gpio,
84 GPIOF_OUT_INIT_HIGH, "lcd UD"); 84 GPIOF_OUT_INIT_HIGH, "lcd UD");
85 if (r) 85 if (r)
86 return r; 86 return r;
87 } 87 }
88 88
89 if (gpio_is_valid(pd->resb_gpio)) { 89 if (gpio_is_valid(pd->resb_gpio)) {
90 r = devm_gpio_request_one(&dssdev->dev, pd->resb_gpio, 90 r = devm_gpio_request_one(dssdev->dev, pd->resb_gpio,
91 GPIOF_OUT_INIT_LOW, "lcd RESB"); 91 GPIOF_OUT_INIT_LOW, "lcd RESB");
92 if (r) 92 if (r)
93 return r; 93 return r;
94 } 94 }
95 95
96 if (gpio_is_valid(pd->ini_gpio)) { 96 if (gpio_is_valid(pd->ini_gpio)) {
97 r = devm_gpio_request_one(&dssdev->dev, pd->ini_gpio, 97 r = devm_gpio_request_one(dssdev->dev, pd->ini_gpio,
98 GPIOF_OUT_INIT_LOW, "lcd INI"); 98 GPIOF_OUT_INIT_LOW, "lcd INI");
99 if (r) 99 if (r)
100 return r; 100 return r;
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index c4f78bda115a..54a07da8587a 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -237,7 +237,7 @@ static int taal_set_update_window(struct taal_data *td,
237 237
238static void taal_queue_esd_work(struct omap_dss_device *dssdev) 238static void taal_queue_esd_work(struct omap_dss_device *dssdev)
239{ 239{
240 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 240 struct taal_data *td = dev_get_drvdata(dssdev->dev);
241 241
242 if (td->esd_interval > 0) 242 if (td->esd_interval > 0)
243 queue_delayed_work(td->workqueue, &td->esd_work, 243 queue_delayed_work(td->workqueue, &td->esd_work,
@@ -246,14 +246,14 @@ static void taal_queue_esd_work(struct omap_dss_device *dssdev)
246 246
247static void taal_cancel_esd_work(struct omap_dss_device *dssdev) 247static void taal_cancel_esd_work(struct omap_dss_device *dssdev)
248{ 248{
249 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 249 struct taal_data *td = dev_get_drvdata(dssdev->dev);
250 250
251 cancel_delayed_work(&td->esd_work); 251 cancel_delayed_work(&td->esd_work);
252} 252}
253 253
254static void taal_queue_ulps_work(struct omap_dss_device *dssdev) 254static void taal_queue_ulps_work(struct omap_dss_device *dssdev)
255{ 255{
256 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 256 struct taal_data *td = dev_get_drvdata(dssdev->dev);
257 257
258 if (td->ulps_timeout > 0) 258 if (td->ulps_timeout > 0)
259 queue_delayed_work(td->workqueue, &td->ulps_work, 259 queue_delayed_work(td->workqueue, &td->ulps_work,
@@ -262,14 +262,14 @@ static void taal_queue_ulps_work(struct omap_dss_device *dssdev)
262 262
263static void taal_cancel_ulps_work(struct omap_dss_device *dssdev) 263static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
264{ 264{
265 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 265 struct taal_data *td = dev_get_drvdata(dssdev->dev);
266 266
267 cancel_delayed_work(&td->ulps_work); 267 cancel_delayed_work(&td->ulps_work);
268} 268}
269 269
270static int taal_enter_ulps(struct omap_dss_device *dssdev) 270static int taal_enter_ulps(struct omap_dss_device *dssdev)
271{ 271{
272 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 272 struct taal_data *td = dev_get_drvdata(dssdev->dev);
273 int r; 273 int r;
274 274
275 if (td->ulps_enabled) 275 if (td->ulps_enabled)
@@ -291,7 +291,7 @@ static int taal_enter_ulps(struct omap_dss_device *dssdev)
291 return 0; 291 return 0;
292 292
293err: 293err:
294 dev_err(&dssdev->dev, "enter ULPS failed"); 294 dev_err(dssdev->dev, "enter ULPS failed");
295 taal_panel_reset(dssdev); 295 taal_panel_reset(dssdev);
296 296
297 td->ulps_enabled = false; 297 td->ulps_enabled = false;
@@ -303,7 +303,7 @@ err:
303 303
304static int taal_exit_ulps(struct omap_dss_device *dssdev) 304static int taal_exit_ulps(struct omap_dss_device *dssdev)
305{ 305{
306 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 306 struct taal_data *td = dev_get_drvdata(dssdev->dev);
307 int r; 307 int r;
308 308
309 if (!td->ulps_enabled) 309 if (!td->ulps_enabled)
@@ -311,7 +311,7 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
311 311
312 r = omapdss_dsi_display_enable(dssdev); 312 r = omapdss_dsi_display_enable(dssdev);
313 if (r) { 313 if (r) {
314 dev_err(&dssdev->dev, "failed to enable DSI\n"); 314 dev_err(dssdev->dev, "failed to enable DSI\n");
315 goto err1; 315 goto err1;
316 } 316 }
317 317
@@ -319,7 +319,7 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
319 319
320 r = _taal_enable_te(dssdev, true); 320 r = _taal_enable_te(dssdev, true);
321 if (r) { 321 if (r) {
322 dev_err(&dssdev->dev, "failed to re-enable TE"); 322 dev_err(dssdev->dev, "failed to re-enable TE");
323 goto err2; 323 goto err2;
324 } 324 }
325 325
@@ -333,7 +333,7 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
333 return 0; 333 return 0;
334 334
335err2: 335err2:
336 dev_err(&dssdev->dev, "failed to exit ULPS"); 336 dev_err(dssdev->dev, "failed to exit ULPS");
337 337
338 r = taal_panel_reset(dssdev); 338 r = taal_panel_reset(dssdev);
339 if (!r) { 339 if (!r) {
@@ -349,7 +349,7 @@ err1:
349 349
350static int taal_wake_up(struct omap_dss_device *dssdev) 350static int taal_wake_up(struct omap_dss_device *dssdev)
351{ 351{
352 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 352 struct taal_data *td = dev_get_drvdata(dssdev->dev);
353 353
354 if (td->ulps_enabled) 354 if (td->ulps_enabled)
355 return taal_exit_ulps(dssdev); 355 return taal_exit_ulps(dssdev);
@@ -362,7 +362,7 @@ static int taal_wake_up(struct omap_dss_device *dssdev)
362static int taal_bl_update_status(struct backlight_device *dev) 362static int taal_bl_update_status(struct backlight_device *dev)
363{ 363{
364 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev); 364 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
365 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 365 struct taal_data *td = dev_get_drvdata(dssdev->dev);
366 int r; 366 int r;
367 int level; 367 int level;
368 368
@@ -372,7 +372,7 @@ static int taal_bl_update_status(struct backlight_device *dev)
372 else 372 else
373 level = 0; 373 level = 0;
374 374
375 dev_dbg(&dssdev->dev, "update brightness to %d\n", level); 375 dev_dbg(dssdev->dev, "update brightness to %d\n", level);
376 376
377 mutex_lock(&td->lock); 377 mutex_lock(&td->lock);
378 378
@@ -418,7 +418,7 @@ static ssize_t taal_num_errors_show(struct device *dev,
418 struct device_attribute *attr, char *buf) 418 struct device_attribute *attr, char *buf)
419{ 419{
420 struct omap_dss_device *dssdev = to_dss_device(dev); 420 struct omap_dss_device *dssdev = to_dss_device(dev);
421 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 421 struct taal_data *td = dev_get_drvdata(dssdev->dev);
422 u8 errors = 0; 422 u8 errors = 0;
423 int r; 423 int r;
424 424
@@ -448,7 +448,7 @@ static ssize_t taal_hw_revision_show(struct device *dev,
448 struct device_attribute *attr, char *buf) 448 struct device_attribute *attr, char *buf)
449{ 449{
450 struct omap_dss_device *dssdev = to_dss_device(dev); 450 struct omap_dss_device *dssdev = to_dss_device(dev);
451 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 451 struct taal_data *td = dev_get_drvdata(dssdev->dev);
452 u8 id1, id2, id3; 452 u8 id1, id2, id3;
453 int r; 453 int r;
454 454
@@ -486,7 +486,7 @@ static ssize_t show_cabc_mode(struct device *dev,
486 char *buf) 486 char *buf)
487{ 487{
488 struct omap_dss_device *dssdev = to_dss_device(dev); 488 struct omap_dss_device *dssdev = to_dss_device(dev);
489 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 489 struct taal_data *td = dev_get_drvdata(dssdev->dev);
490 const char *mode_str; 490 const char *mode_str;
491 int mode; 491 int mode;
492 int len; 492 int len;
@@ -506,7 +506,7 @@ static ssize_t store_cabc_mode(struct device *dev,
506 const char *buf, size_t count) 506 const char *buf, size_t count)
507{ 507{
508 struct omap_dss_device *dssdev = to_dss_device(dev); 508 struct omap_dss_device *dssdev = to_dss_device(dev);
509 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 509 struct taal_data *td = dev_get_drvdata(dssdev->dev);
510 int i; 510 int i;
511 int r; 511 int r;
512 512
@@ -568,12 +568,12 @@ static ssize_t taal_store_esd_interval(struct device *dev,
568 const char *buf, size_t count) 568 const char *buf, size_t count)
569{ 569{
570 struct omap_dss_device *dssdev = to_dss_device(dev); 570 struct omap_dss_device *dssdev = to_dss_device(dev);
571 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 571 struct taal_data *td = dev_get_drvdata(dssdev->dev);
572 572
573 unsigned long t; 573 unsigned long t;
574 int r; 574 int r;
575 575
576 r = strict_strtoul(buf, 10, &t); 576 r = kstrtoul(buf, 10, &t);
577 if (r) 577 if (r)
578 return r; 578 return r;
579 579
@@ -592,7 +592,7 @@ static ssize_t taal_show_esd_interval(struct device *dev,
592 char *buf) 592 char *buf)
593{ 593{
594 struct omap_dss_device *dssdev = to_dss_device(dev); 594 struct omap_dss_device *dssdev = to_dss_device(dev);
595 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 595 struct taal_data *td = dev_get_drvdata(dssdev->dev);
596 unsigned t; 596 unsigned t;
597 597
598 mutex_lock(&td->lock); 598 mutex_lock(&td->lock);
@@ -607,11 +607,11 @@ static ssize_t taal_store_ulps(struct device *dev,
607 const char *buf, size_t count) 607 const char *buf, size_t count)
608{ 608{
609 struct omap_dss_device *dssdev = to_dss_device(dev); 609 struct omap_dss_device *dssdev = to_dss_device(dev);
610 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 610 struct taal_data *td = dev_get_drvdata(dssdev->dev);
611 unsigned long t; 611 unsigned long t;
612 int r; 612 int r;
613 613
614 r = strict_strtoul(buf, 10, &t); 614 r = kstrtoul(buf, 10, &t);
615 if (r) 615 if (r)
616 return r; 616 return r;
617 617
@@ -641,7 +641,7 @@ static ssize_t taal_show_ulps(struct device *dev,
641 char *buf) 641 char *buf)
642{ 642{
643 struct omap_dss_device *dssdev = to_dss_device(dev); 643 struct omap_dss_device *dssdev = to_dss_device(dev);
644 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 644 struct taal_data *td = dev_get_drvdata(dssdev->dev);
645 unsigned t; 645 unsigned t;
646 646
647 mutex_lock(&td->lock); 647 mutex_lock(&td->lock);
@@ -656,11 +656,11 @@ static ssize_t taal_store_ulps_timeout(struct device *dev,
656 const char *buf, size_t count) 656 const char *buf, size_t count)
657{ 657{
658 struct omap_dss_device *dssdev = to_dss_device(dev); 658 struct omap_dss_device *dssdev = to_dss_device(dev);
659 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 659 struct taal_data *td = dev_get_drvdata(dssdev->dev);
660 unsigned long t; 660 unsigned long t;
661 int r; 661 int r;
662 662
663 r = strict_strtoul(buf, 10, &t); 663 r = kstrtoul(buf, 10, &t);
664 if (r) 664 if (r)
665 return r; 665 return r;
666 666
@@ -687,7 +687,7 @@ static ssize_t taal_show_ulps_timeout(struct device *dev,
687 char *buf) 687 char *buf)
688{ 688{
689 struct omap_dss_device *dssdev = to_dss_device(dev); 689 struct omap_dss_device *dssdev = to_dss_device(dev);
690 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 690 struct taal_data *td = dev_get_drvdata(dssdev->dev);
691 unsigned t; 691 unsigned t;
692 692
693 mutex_lock(&td->lock); 693 mutex_lock(&td->lock);
@@ -727,7 +727,7 @@ static struct attribute_group taal_attr_group = {
727 727
728static void taal_hw_reset(struct omap_dss_device *dssdev) 728static void taal_hw_reset(struct omap_dss_device *dssdev)
729{ 729{
730 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 730 struct taal_data *td = dev_get_drvdata(dssdev->dev);
731 731
732 if (!gpio_is_valid(td->reset_gpio)) 732 if (!gpio_is_valid(td->reset_gpio))
733 return; 733 return;
@@ -768,13 +768,13 @@ static int taal_probe(struct omap_dss_device *dssdev)
768 struct backlight_device *bldev = NULL; 768 struct backlight_device *bldev = NULL;
769 int r; 769 int r;
770 770
771 dev_dbg(&dssdev->dev, "probe\n"); 771 dev_dbg(dssdev->dev, "probe\n");
772 772
773 td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL); 773 td = devm_kzalloc(dssdev->dev, sizeof(*td), GFP_KERNEL);
774 if (!td) 774 if (!td)
775 return -ENOMEM; 775 return -ENOMEM;
776 776
777 dev_set_drvdata(&dssdev->dev, td); 777 dev_set_drvdata(dssdev->dev, td);
778 td->dssdev = dssdev; 778 td->dssdev = dssdev;
779 779
780 if (dssdev->data) { 780 if (dssdev->data) {
@@ -797,41 +797,41 @@ static int taal_probe(struct omap_dss_device *dssdev)
797 atomic_set(&td->do_update, 0); 797 atomic_set(&td->do_update, 0);
798 798
799 if (gpio_is_valid(td->reset_gpio)) { 799 if (gpio_is_valid(td->reset_gpio)) {
800 r = devm_gpio_request_one(&dssdev->dev, td->reset_gpio, 800 r = devm_gpio_request_one(dssdev->dev, td->reset_gpio,
801 GPIOF_OUT_INIT_LOW, "taal rst"); 801 GPIOF_OUT_INIT_LOW, "taal rst");
802 if (r) { 802 if (r) {
803 dev_err(&dssdev->dev, "failed to request reset gpio\n"); 803 dev_err(dssdev->dev, "failed to request reset gpio\n");
804 return r; 804 return r;
805 } 805 }
806 } 806 }
807 807
808 if (gpio_is_valid(td->ext_te_gpio)) { 808 if (gpio_is_valid(td->ext_te_gpio)) {
809 r = devm_gpio_request_one(&dssdev->dev, td->ext_te_gpio, 809 r = devm_gpio_request_one(dssdev->dev, td->ext_te_gpio,
810 GPIOF_IN, "taal irq"); 810 GPIOF_IN, "taal irq");
811 if (r) { 811 if (r) {
812 dev_err(&dssdev->dev, "GPIO request failed\n"); 812 dev_err(dssdev->dev, "GPIO request failed\n");
813 return r; 813 return r;
814 } 814 }
815 815
816 r = devm_request_irq(&dssdev->dev, gpio_to_irq(td->ext_te_gpio), 816 r = devm_request_irq(dssdev->dev, gpio_to_irq(td->ext_te_gpio),
817 taal_te_isr, 817 taal_te_isr,
818 IRQF_TRIGGER_RISING, 818 IRQF_TRIGGER_RISING,
819 "taal vsync", dssdev); 819 "taal vsync", dssdev);
820 820
821 if (r) { 821 if (r) {
822 dev_err(&dssdev->dev, "IRQ request failed\n"); 822 dev_err(dssdev->dev, "IRQ request failed\n");
823 return r; 823 return r;
824 } 824 }
825 825
826 INIT_DEFERRABLE_WORK(&td->te_timeout_work, 826 INIT_DEFERRABLE_WORK(&td->te_timeout_work,
827 taal_te_timeout_work_callback); 827 taal_te_timeout_work_callback);
828 828
829 dev_dbg(&dssdev->dev, "Using GPIO TE\n"); 829 dev_dbg(dssdev->dev, "Using GPIO TE\n");
830 } 830 }
831 831
832 td->workqueue = create_singlethread_workqueue("taal_esd"); 832 td->workqueue = create_singlethread_workqueue("taal_esd");
833 if (td->workqueue == NULL) { 833 if (td->workqueue == NULL) {
834 dev_err(&dssdev->dev, "can't create ESD workqueue\n"); 834 dev_err(dssdev->dev, "can't create ESD workqueue\n");
835 return -ENOMEM; 835 return -ENOMEM;
836 } 836 }
837 INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work); 837 INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work);
@@ -844,8 +844,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
844 props.max_brightness = 255; 844 props.max_brightness = 255;
845 845
846 props.type = BACKLIGHT_RAW; 846 props.type = BACKLIGHT_RAW;
847 bldev = backlight_device_register(dev_name(&dssdev->dev), 847 bldev = backlight_device_register(dev_name(dssdev->dev),
848 &dssdev->dev, dssdev, &taal_bl_ops, &props); 848 dssdev->dev, dssdev, &taal_bl_ops, &props);
849 if (IS_ERR(bldev)) { 849 if (IS_ERR(bldev)) {
850 r = PTR_ERR(bldev); 850 r = PTR_ERR(bldev);
851 goto err_bl; 851 goto err_bl;
@@ -862,19 +862,19 @@ static int taal_probe(struct omap_dss_device *dssdev)
862 862
863 r = omap_dsi_request_vc(dssdev, &td->channel); 863 r = omap_dsi_request_vc(dssdev, &td->channel);
864 if (r) { 864 if (r) {
865 dev_err(&dssdev->dev, "failed to get virtual channel\n"); 865 dev_err(dssdev->dev, "failed to get virtual channel\n");
866 goto err_req_vc; 866 goto err_req_vc;
867 } 867 }
868 868
869 r = omap_dsi_set_vc_id(dssdev, td->channel, TCH); 869 r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
870 if (r) { 870 if (r) {
871 dev_err(&dssdev->dev, "failed to set VC_ID\n"); 871 dev_err(dssdev->dev, "failed to set VC_ID\n");
872 goto err_vc_id; 872 goto err_vc_id;
873 } 873 }
874 874
875 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group); 875 r = sysfs_create_group(&dssdev->dev->kobj, &taal_attr_group);
876 if (r) { 876 if (r) {
877 dev_err(&dssdev->dev, "failed to create sysfs files\n"); 877 dev_err(dssdev->dev, "failed to create sysfs files\n");
878 goto err_vc_id; 878 goto err_vc_id;
879 } 879 }
880 880
@@ -892,12 +892,12 @@ err_bl:
892 892
893static void __exit taal_remove(struct omap_dss_device *dssdev) 893static void __exit taal_remove(struct omap_dss_device *dssdev)
894{ 894{
895 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 895 struct taal_data *td = dev_get_drvdata(dssdev->dev);
896 struct backlight_device *bldev; 896 struct backlight_device *bldev;
897 897
898 dev_dbg(&dssdev->dev, "remove\n"); 898 dev_dbg(dssdev->dev, "remove\n");
899 899
900 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); 900 sysfs_remove_group(&dssdev->dev->kobj, &taal_attr_group);
901 omap_dsi_release_vc(dssdev, td->channel); 901 omap_dsi_release_vc(dssdev, td->channel);
902 902
903 bldev = td->bldev; 903 bldev = td->bldev;
@@ -917,7 +917,7 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
917 917
918static int taal_power_on(struct omap_dss_device *dssdev) 918static int taal_power_on(struct omap_dss_device *dssdev)
919{ 919{
920 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 920 struct taal_data *td = dev_get_drvdata(dssdev->dev);
921 u8 id1, id2, id3; 921 u8 id1, id2, id3;
922 int r; 922 int r;
923 struct omap_dss_dsi_config dsi_config = { 923 struct omap_dss_dsi_config dsi_config = {
@@ -932,19 +932,19 @@ static int taal_power_on(struct omap_dss_device *dssdev)
932 932
933 r = omapdss_dsi_configure_pins(dssdev, &td->pin_config); 933 r = omapdss_dsi_configure_pins(dssdev, &td->pin_config);
934 if (r) { 934 if (r) {
935 dev_err(&dssdev->dev, "failed to configure DSI pins\n"); 935 dev_err(dssdev->dev, "failed to configure DSI pins\n");
936 goto err0; 936 goto err0;
937 }; 937 };
938 938
939 r = omapdss_dsi_set_config(dssdev, &dsi_config); 939 r = omapdss_dsi_set_config(dssdev, &dsi_config);
940 if (r) { 940 if (r) {
941 dev_err(&dssdev->dev, "failed to configure DSI\n"); 941 dev_err(dssdev->dev, "failed to configure DSI\n");
942 goto err0; 942 goto err0;
943 } 943 }
944 944
945 r = omapdss_dsi_display_enable(dssdev); 945 r = omapdss_dsi_display_enable(dssdev);
946 if (r) { 946 if (r) {
947 dev_err(&dssdev->dev, "failed to enable DSI\n"); 947 dev_err(dssdev->dev, "failed to enable DSI\n");
948 goto err0; 948 goto err0;
949 } 949 }
950 950
@@ -999,10 +999,10 @@ static int taal_power_on(struct omap_dss_device *dssdev)
999 td->enabled = 1; 999 td->enabled = 1;
1000 1000
1001 if (!td->intro_printed) { 1001 if (!td->intro_printed) {
1002 dev_info(&dssdev->dev, "panel revision %02x.%02x.%02x\n", 1002 dev_info(dssdev->dev, "panel revision %02x.%02x.%02x\n",
1003 id1, id2, id3); 1003 id1, id2, id3);
1004 if (td->cabc_broken) 1004 if (td->cabc_broken)
1005 dev_info(&dssdev->dev, 1005 dev_info(dssdev->dev,
1006 "old Taal version, CABC disabled\n"); 1006 "old Taal version, CABC disabled\n");
1007 td->intro_printed = true; 1007 td->intro_printed = true;
1008 } 1008 }
@@ -1011,7 +1011,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
1011 1011
1012 return 0; 1012 return 0;
1013err: 1013err:
1014 dev_err(&dssdev->dev, "error while enabling panel, issuing HW reset\n"); 1014 dev_err(dssdev->dev, "error while enabling panel, issuing HW reset\n");
1015 1015
1016 taal_hw_reset(dssdev); 1016 taal_hw_reset(dssdev);
1017 1017
@@ -1022,7 +1022,7 @@ err0:
1022 1022
1023static void taal_power_off(struct omap_dss_device *dssdev) 1023static void taal_power_off(struct omap_dss_device *dssdev)
1024{ 1024{
1025 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1025 struct taal_data *td = dev_get_drvdata(dssdev->dev);
1026 int r; 1026 int r;
1027 1027
1028 dsi_disable_video_output(dssdev, td->channel); 1028 dsi_disable_video_output(dssdev, td->channel);
@@ -1032,7 +1032,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
1032 r = taal_sleep_in(td); 1032 r = taal_sleep_in(td);
1033 1033
1034 if (r) { 1034 if (r) {
1035 dev_err(&dssdev->dev, 1035 dev_err(dssdev->dev,
1036 "error disabling panel, issuing HW reset\n"); 1036 "error disabling panel, issuing HW reset\n");
1037 taal_hw_reset(dssdev); 1037 taal_hw_reset(dssdev);
1038 } 1038 }
@@ -1044,7 +1044,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
1044 1044
1045static int taal_panel_reset(struct omap_dss_device *dssdev) 1045static int taal_panel_reset(struct omap_dss_device *dssdev)
1046{ 1046{
1047 dev_err(&dssdev->dev, "performing LCD reset\n"); 1047 dev_err(dssdev->dev, "performing LCD reset\n");
1048 1048
1049 taal_power_off(dssdev); 1049 taal_power_off(dssdev);
1050 taal_hw_reset(dssdev); 1050 taal_hw_reset(dssdev);
@@ -1053,10 +1053,10 @@ static int taal_panel_reset(struct omap_dss_device *dssdev)
1053 1053
1054static int taal_enable(struct omap_dss_device *dssdev) 1054static int taal_enable(struct omap_dss_device *dssdev)
1055{ 1055{
1056 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1056 struct taal_data *td = dev_get_drvdata(dssdev->dev);
1057 int r; 1057 int r;
1058 1058
1059 dev_dbg(&dssdev->dev, "enable\n"); 1059 dev_dbg(dssdev->dev, "enable\n");
1060 1060
1061 mutex_lock(&td->lock); 1061 mutex_lock(&td->lock);
1062 1062
@@ -1082,16 +1082,16 @@ static int taal_enable(struct omap_dss_device *dssdev)
1082 1082
1083 return 0; 1083 return 0;
1084err: 1084err:
1085 dev_dbg(&dssdev->dev, "enable failed\n"); 1085 dev_dbg(dssdev->dev, "enable failed\n");
1086 mutex_unlock(&td->lock); 1086 mutex_unlock(&td->lock);
1087 return r; 1087 return r;
1088} 1088}
1089 1089
1090static void taal_disable(struct omap_dss_device *dssdev) 1090static void taal_disable(struct omap_dss_device *dssdev)
1091{ 1091{
1092 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1092 struct taal_data *td = dev_get_drvdata(dssdev->dev);
1093 1093
1094 dev_dbg(&dssdev->dev, "disable\n"); 1094 dev_dbg(dssdev->dev, "disable\n");
1095 1095
1096 mutex_lock(&td->lock); 1096 mutex_lock(&td->lock);
1097 1097
@@ -1118,14 +1118,14 @@ static void taal_disable(struct omap_dss_device *dssdev)
1118static void taal_framedone_cb(int err, void *data) 1118static void taal_framedone_cb(int err, void *data)
1119{ 1119{
1120 struct omap_dss_device *dssdev = data; 1120 struct omap_dss_device *dssdev = data;
1121 dev_dbg(&dssdev->dev, "framedone, err %d\n", err); 1121 dev_dbg(dssdev->dev, "framedone, err %d\n", err);
1122 dsi_bus_unlock(dssdev); 1122 dsi_bus_unlock(dssdev);
1123} 1123}
1124 1124
1125static irqreturn_t taal_te_isr(int irq, void *data) 1125static irqreturn_t taal_te_isr(int irq, void *data)
1126{ 1126{
1127 struct omap_dss_device *dssdev = data; 1127 struct omap_dss_device *dssdev = data;
1128 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1128 struct taal_data *td = dev_get_drvdata(dssdev->dev);
1129 int old; 1129 int old;
1130 int r; 1130 int r;
1131 1131
@@ -1142,7 +1142,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
1142 1142
1143 return IRQ_HANDLED; 1143 return IRQ_HANDLED;
1144err: 1144err:
1145 dev_err(&dssdev->dev, "start update failed\n"); 1145 dev_err(dssdev->dev, "start update failed\n");
1146 dsi_bus_unlock(dssdev); 1146 dsi_bus_unlock(dssdev);
1147 return IRQ_HANDLED; 1147 return IRQ_HANDLED;
1148} 1148}
@@ -1153,7 +1153,7 @@ static void taal_te_timeout_work_callback(struct work_struct *work)
1153 te_timeout_work.work); 1153 te_timeout_work.work);
1154 struct omap_dss_device *dssdev = td->dssdev; 1154 struct omap_dss_device *dssdev = td->dssdev;
1155 1155
1156 dev_err(&dssdev->dev, "TE not received for 250ms!\n"); 1156 dev_err(dssdev->dev, "TE not received for 250ms!\n");
1157 1157
1158 atomic_set(&td->do_update, 0); 1158 atomic_set(&td->do_update, 0);
1159 dsi_bus_unlock(dssdev); 1159 dsi_bus_unlock(dssdev);
@@ -1162,10 +1162,10 @@ static void taal_te_timeout_work_callback(struct work_struct *work)
1162static int taal_update(struct omap_dss_device *dssdev, 1162static int taal_update(struct omap_dss_device *dssdev,
1163 u16 x, u16 y, u16 w, u16 h) 1163 u16 x, u16 y, u16 w, u16 h)
1164{ 1164{
1165 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1165 struct taal_data *td = dev_get_drvdata(dssdev->dev);
1166 int r; 1166 int r;
1167 1167
1168 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); 1168 dev_dbg(dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
1169 1169
1170 mutex_lock(&td->lock); 1170 mutex_lock(&td->lock);
1171 dsi_bus_lock(dssdev); 1171 dsi_bus_lock(dssdev);
@@ -1208,23 +1208,23 @@ err:
1208 1208
1209static int taal_sync(struct omap_dss_device *dssdev) 1209static int taal_sync(struct omap_dss_device *dssdev)
1210{ 1210{
1211 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1211 struct taal_data *td = dev_get_drvdata(dssdev->dev);
1212 1212
1213 dev_dbg(&dssdev->dev, "sync\n"); 1213 dev_dbg(dssdev->dev, "sync\n");
1214 1214
1215 mutex_lock(&td->lock); 1215 mutex_lock(&td->lock);
1216 dsi_bus_lock(dssdev); 1216 dsi_bus_lock(dssdev);
1217 dsi_bus_unlock(dssdev); 1217 dsi_bus_unlock(dssdev);
1218 mutex_unlock(&td->lock); 1218 mutex_unlock(&td->lock);
1219 1219
1220 dev_dbg(&dssdev->dev, "sync done\n"); 1220 dev_dbg(dssdev->dev, "sync done\n");
1221 1221
1222 return 0; 1222 return 0;
1223} 1223}
1224 1224
1225static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) 1225static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1226{ 1226{
1227 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1227 struct taal_data *td = dev_get_drvdata(dssdev->dev);
1228 int r; 1228 int r;
1229 1229
1230 if (enable) 1230 if (enable)
@@ -1243,7 +1243,7 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1243 1243
1244static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) 1244static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1245{ 1245{
1246 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1246 struct taal_data *td = dev_get_drvdata(dssdev->dev);
1247 int r; 1247 int r;
1248 1248
1249 mutex_lock(&td->lock); 1249 mutex_lock(&td->lock);
@@ -1279,7 +1279,7 @@ err:
1279 1279
1280static int taal_get_te(struct omap_dss_device *dssdev) 1280static int taal_get_te(struct omap_dss_device *dssdev)
1281{ 1281{
1282 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1282 struct taal_data *td = dev_get_drvdata(dssdev->dev);
1283 int r; 1283 int r;
1284 1284
1285 mutex_lock(&td->lock); 1285 mutex_lock(&td->lock);
@@ -1291,7 +1291,7 @@ static int taal_get_te(struct omap_dss_device *dssdev)
1291 1291
1292static int taal_run_test(struct omap_dss_device *dssdev, int test_num) 1292static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1293{ 1293{
1294 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1294 struct taal_data *td = dev_get_drvdata(dssdev->dev);
1295 u8 id1, id2, id3; 1295 u8 id1, id2, id3;
1296 int r; 1296 int r;
1297 1297
@@ -1336,7 +1336,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1336 int first = 1; 1336 int first = 1;
1337 int plen; 1337 int plen;
1338 unsigned buf_used = 0; 1338 unsigned buf_used = 0;
1339 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1339 struct taal_data *td = dev_get_drvdata(dssdev->dev);
1340 1340
1341 if (size < w * h * 3) 1341 if (size < w * h * 3)
1342 return -ENOMEM; 1342 return -ENOMEM;
@@ -1380,19 +1380,19 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1380 buf + buf_used, size - buf_used); 1380 buf + buf_used, size - buf_used);
1381 1381
1382 if (r < 0) { 1382 if (r < 0) {
1383 dev_err(&dssdev->dev, "read error\n"); 1383 dev_err(dssdev->dev, "read error\n");
1384 goto err3; 1384 goto err3;
1385 } 1385 }
1386 1386
1387 buf_used += r; 1387 buf_used += r;
1388 1388
1389 if (r < plen) { 1389 if (r < plen) {
1390 dev_err(&dssdev->dev, "short read\n"); 1390 dev_err(dssdev->dev, "short read\n");
1391 break; 1391 break;
1392 } 1392 }
1393 1393
1394 if (signal_pending(current)) { 1394 if (signal_pending(current)) {
1395 dev_err(&dssdev->dev, "signal pending, " 1395 dev_err(dssdev->dev, "signal pending, "
1396 "aborting memory read\n"); 1396 "aborting memory read\n");
1397 r = -ERESTARTSYS; 1397 r = -ERESTARTSYS;
1398 goto err3; 1398 goto err3;
@@ -1450,26 +1450,26 @@ static void taal_esd_work(struct work_struct *work)
1450 1450
1451 r = taal_wake_up(dssdev); 1451 r = taal_wake_up(dssdev);
1452 if (r) { 1452 if (r) {
1453 dev_err(&dssdev->dev, "failed to exit ULPS\n"); 1453 dev_err(dssdev->dev, "failed to exit ULPS\n");
1454 goto err; 1454 goto err;
1455 } 1455 }
1456 1456
1457 r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1); 1457 r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1);
1458 if (r) { 1458 if (r) {
1459 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1459 dev_err(dssdev->dev, "failed to read Taal status\n");
1460 goto err; 1460 goto err;
1461 } 1461 }
1462 1462
1463 /* Run self diagnostics */ 1463 /* Run self diagnostics */
1464 r = taal_sleep_out(td); 1464 r = taal_sleep_out(td);
1465 if (r) { 1465 if (r) {
1466 dev_err(&dssdev->dev, "failed to run Taal self-diagnostics\n"); 1466 dev_err(dssdev->dev, "failed to run Taal self-diagnostics\n");
1467 goto err; 1467 goto err;
1468 } 1468 }
1469 1469
1470 r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2); 1470 r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2);
1471 if (r) { 1471 if (r) {
1472 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1472 dev_err(dssdev->dev, "failed to read Taal status\n");
1473 goto err; 1473 goto err;
1474 } 1474 }
1475 1475
@@ -1477,7 +1477,7 @@ static void taal_esd_work(struct work_struct *work)
1477 * Bit6 if the test passes. 1477 * Bit6 if the test passes.
1478 */ 1478 */
1479 if (!((state1 ^ state2) & (1 << 6))) { 1479 if (!((state1 ^ state2) & (1 << 6))) {
1480 dev_err(&dssdev->dev, "LCD self diagnostics failed\n"); 1480 dev_err(dssdev->dev, "LCD self diagnostics failed\n");
1481 goto err; 1481 goto err;
1482 } 1482 }
1483 /* Self-diagnostics result is also shown on TE GPIO line. We need 1483 /* Self-diagnostics result is also shown on TE GPIO line. We need
@@ -1495,7 +1495,7 @@ static void taal_esd_work(struct work_struct *work)
1495 mutex_unlock(&td->lock); 1495 mutex_unlock(&td->lock);
1496 return; 1496 return;
1497err: 1497err:
1498 dev_err(&dssdev->dev, "performing LCD reset\n"); 1498 dev_err(dssdev->dev, "performing LCD reset\n");
1499 1499
1500 taal_panel_reset(dssdev); 1500 taal_panel_reset(dssdev);
1501 1501
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 46039c4bf1ed..1fdfb158a2a9 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -59,7 +59,7 @@ struct panel_drv_data {
59 59
60static int tfp410_power_on(struct omap_dss_device *dssdev) 60static int tfp410_power_on(struct omap_dss_device *dssdev)
61{ 61{
62 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 62 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
63 int r; 63 int r;
64 64
65 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 65 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
@@ -82,7 +82,7 @@ err0:
82 82
83static void tfp410_power_off(struct omap_dss_device *dssdev) 83static void tfp410_power_off(struct omap_dss_device *dssdev)
84{ 84{
85 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 85 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
86 86
87 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 87 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
88 return; 88 return;
@@ -99,7 +99,7 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
99 int r; 99 int r;
100 int i2c_bus_num; 100 int i2c_bus_num;
101 101
102 ddata = devm_kzalloc(&dssdev->dev, sizeof(*ddata), GFP_KERNEL); 102 ddata = devm_kzalloc(dssdev->dev, sizeof(*ddata), GFP_KERNEL);
103 if (!ddata) 103 if (!ddata)
104 return -ENOMEM; 104 return -ENOMEM;
105 105
@@ -119,10 +119,10 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
119 } 119 }
120 120
121 if (gpio_is_valid(ddata->pd_gpio)) { 121 if (gpio_is_valid(ddata->pd_gpio)) {
122 r = devm_gpio_request_one(&dssdev->dev, ddata->pd_gpio, 122 r = devm_gpio_request_one(dssdev->dev, ddata->pd_gpio,
123 GPIOF_OUT_INIT_LOW, "tfp410 pd"); 123 GPIOF_OUT_INIT_LOW, "tfp410 pd");
124 if (r) { 124 if (r) {
125 dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n", 125 dev_err(dssdev->dev, "Failed to request PD GPIO %d\n",
126 ddata->pd_gpio); 126 ddata->pd_gpio);
127 return r; 127 return r;
128 } 128 }
@@ -133,7 +133,7 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
133 133
134 adapter = i2c_get_adapter(i2c_bus_num); 134 adapter = i2c_get_adapter(i2c_bus_num);
135 if (!adapter) { 135 if (!adapter) {
136 dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n", 136 dev_err(dssdev->dev, "Failed to get I2C adapter, bus %d\n",
137 i2c_bus_num); 137 i2c_bus_num);
138 return -EPROBE_DEFER; 138 return -EPROBE_DEFER;
139 } 139 }
@@ -141,28 +141,28 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
141 ddata->i2c_adapter = adapter; 141 ddata->i2c_adapter = adapter;
142 } 142 }
143 143
144 dev_set_drvdata(&dssdev->dev, ddata); 144 dev_set_drvdata(dssdev->dev, ddata);
145 145
146 return 0; 146 return 0;
147} 147}
148 148
149static void __exit tfp410_remove(struct omap_dss_device *dssdev) 149static void __exit tfp410_remove(struct omap_dss_device *dssdev)
150{ 150{
151 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 151 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
152 152
153 mutex_lock(&ddata->lock); 153 mutex_lock(&ddata->lock);
154 154
155 if (ddata->i2c_adapter) 155 if (ddata->i2c_adapter)
156 i2c_put_adapter(ddata->i2c_adapter); 156 i2c_put_adapter(ddata->i2c_adapter);
157 157
158 dev_set_drvdata(&dssdev->dev, NULL); 158 dev_set_drvdata(dssdev->dev, NULL);
159 159
160 mutex_unlock(&ddata->lock); 160 mutex_unlock(&ddata->lock);
161} 161}
162 162
163static int tfp410_enable(struct omap_dss_device *dssdev) 163static int tfp410_enable(struct omap_dss_device *dssdev)
164{ 164{
165 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 165 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
166 int r; 166 int r;
167 167
168 mutex_lock(&ddata->lock); 168 mutex_lock(&ddata->lock);
@@ -178,7 +178,7 @@ static int tfp410_enable(struct omap_dss_device *dssdev)
178 178
179static void tfp410_disable(struct omap_dss_device *dssdev) 179static void tfp410_disable(struct omap_dss_device *dssdev)
180{ 180{
181 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 181 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
182 182
183 mutex_lock(&ddata->lock); 183 mutex_lock(&ddata->lock);
184 184
@@ -192,7 +192,7 @@ static void tfp410_disable(struct omap_dss_device *dssdev)
192static void tfp410_set_timings(struct omap_dss_device *dssdev, 192static void tfp410_set_timings(struct omap_dss_device *dssdev,
193 struct omap_video_timings *timings) 193 struct omap_video_timings *timings)
194{ 194{
195 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 195 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
196 196
197 mutex_lock(&ddata->lock); 197 mutex_lock(&ddata->lock);
198 omapdss_dpi_set_timings(dssdev, timings); 198 omapdss_dpi_set_timings(dssdev, timings);
@@ -203,7 +203,7 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
203static void tfp410_get_timings(struct omap_dss_device *dssdev, 203static void tfp410_get_timings(struct omap_dss_device *dssdev,
204 struct omap_video_timings *timings) 204 struct omap_video_timings *timings)
205{ 205{
206 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 206 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
207 207
208 mutex_lock(&ddata->lock); 208 mutex_lock(&ddata->lock);
209 *timings = dssdev->panel.timings; 209 *timings = dssdev->panel.timings;
@@ -213,7 +213,7 @@ static void tfp410_get_timings(struct omap_dss_device *dssdev,
213static int tfp410_check_timings(struct omap_dss_device *dssdev, 213static int tfp410_check_timings(struct omap_dss_device *dssdev,
214 struct omap_video_timings *timings) 214 struct omap_video_timings *timings)
215{ 215{
216 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 216 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
217 int r; 217 int r;
218 218
219 mutex_lock(&ddata->lock); 219 mutex_lock(&ddata->lock);
@@ -258,7 +258,7 @@ static int tfp410_ddc_read(struct i2c_adapter *adapter,
258static int tfp410_read_edid(struct omap_dss_device *dssdev, 258static int tfp410_read_edid(struct omap_dss_device *dssdev,
259 u8 *edid, int len) 259 u8 *edid, int len)
260{ 260{
261 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 261 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
262 int r, l, bytes_read; 262 int r, l, bytes_read;
263 263
264 mutex_lock(&ddata->lock); 264 mutex_lock(&ddata->lock);
@@ -298,7 +298,7 @@ err:
298 298
299static bool tfp410_detect(struct omap_dss_device *dssdev) 299static bool tfp410_detect(struct omap_dss_device *dssdev)
300{ 300{
301 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 301 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
302 unsigned char out; 302 unsigned char out;
303 int r; 303 int r;
304 304
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index abf2bc4a18ab..7729b6fa6f97 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -126,7 +126,7 @@ static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v)
126 126
127static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable) 127static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
128{ 128{
129 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 129 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev);
130 130
131 tpo_td043->hmirror = enable; 131 tpo_td043->hmirror = enable;
132 return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, 132 return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
@@ -135,7 +135,7 @@ static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
135 135
136static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev) 136static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev)
137{ 137{
138 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 138 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev);
139 139
140 return tpo_td043->hmirror; 140 return tpo_td043->hmirror;
141} 141}
@@ -338,7 +338,7 @@ static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
338 338
339static int tpo_td043_enable_dss(struct omap_dss_device *dssdev) 339static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
340{ 340{
341 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 341 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev);
342 int r; 342 int r;
343 343
344 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 344 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
@@ -372,7 +372,7 @@ err0:
372 372
373static void tpo_td043_disable_dss(struct omap_dss_device *dssdev) 373static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
374{ 374{
375 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 375 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev);
376 376
377 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 377 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
378 return; 378 return;
@@ -385,14 +385,14 @@ static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
385 385
386static int tpo_td043_enable(struct omap_dss_device *dssdev) 386static int tpo_td043_enable(struct omap_dss_device *dssdev)
387{ 387{
388 dev_dbg(&dssdev->dev, "enable\n"); 388 dev_dbg(dssdev->dev, "enable\n");
389 389
390 return tpo_td043_enable_dss(dssdev); 390 return tpo_td043_enable_dss(dssdev);
391} 391}
392 392
393static void tpo_td043_disable(struct omap_dss_device *dssdev) 393static void tpo_td043_disable(struct omap_dss_device *dssdev)
394{ 394{
395 dev_dbg(&dssdev->dev, "disable\n"); 395 dev_dbg(dssdev->dev, "disable\n");
396 396
397 tpo_td043_disable_dss(dssdev); 397 tpo_td043_disable_dss(dssdev);
398 398
@@ -405,10 +405,10 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
405 struct panel_tpo_td043_data *pdata = get_panel_data(dssdev); 405 struct panel_tpo_td043_data *pdata = get_panel_data(dssdev);
406 int ret = 0; 406 int ret = 0;
407 407
408 dev_dbg(&dssdev->dev, "probe\n"); 408 dev_dbg(dssdev->dev, "probe\n");
409 409
410 if (tpo_td043 == NULL) { 410 if (tpo_td043 == NULL) {
411 dev_err(&dssdev->dev, "missing tpo_td043_device\n"); 411 dev_err(dssdev->dev, "missing tpo_td043_device\n");
412 return -ENODEV; 412 return -ENODEV;
413 } 413 }
414 414
@@ -423,28 +423,28 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
423 tpo_td043->mode = TPO_R02_MODE_800x480; 423 tpo_td043->mode = TPO_R02_MODE_800x480;
424 memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma)); 424 memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma));
425 425
426 tpo_td043->vcc_reg = regulator_get(&dssdev->dev, "vcc"); 426 tpo_td043->vcc_reg = regulator_get(dssdev->dev, "vcc");
427 if (IS_ERR(tpo_td043->vcc_reg)) { 427 if (IS_ERR(tpo_td043->vcc_reg)) {
428 dev_err(&dssdev->dev, "failed to get LCD VCC regulator\n"); 428 dev_err(dssdev->dev, "failed to get LCD VCC regulator\n");
429 ret = PTR_ERR(tpo_td043->vcc_reg); 429 ret = PTR_ERR(tpo_td043->vcc_reg);
430 goto fail_regulator; 430 goto fail_regulator;
431 } 431 }
432 432
433 if (gpio_is_valid(tpo_td043->nreset_gpio)) { 433 if (gpio_is_valid(tpo_td043->nreset_gpio)) {
434 ret = devm_gpio_request_one(&dssdev->dev, 434 ret = devm_gpio_request_one(dssdev->dev,
435 tpo_td043->nreset_gpio, GPIOF_OUT_INIT_LOW, 435 tpo_td043->nreset_gpio, GPIOF_OUT_INIT_LOW,
436 "lcd reset"); 436 "lcd reset");
437 if (ret < 0) { 437 if (ret < 0) {
438 dev_err(&dssdev->dev, "couldn't request reset GPIO\n"); 438 dev_err(dssdev->dev, "couldn't request reset GPIO\n");
439 goto fail_gpio_req; 439 goto fail_gpio_req;
440 } 440 }
441 } 441 }
442 442
443 ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group); 443 ret = sysfs_create_group(&dssdev->dev->kobj, &tpo_td043_attr_group);
444 if (ret) 444 if (ret)
445 dev_warn(&dssdev->dev, "failed to create sysfs files\n"); 445 dev_warn(dssdev->dev, "failed to create sysfs files\n");
446 446
447 dev_set_drvdata(&dssdev->dev, tpo_td043); 447 dev_set_drvdata(dssdev->dev, tpo_td043);
448 448
449 return 0; 449 return 0;
450 450
@@ -457,11 +457,11 @@ fail_regulator:
457 457
458static void tpo_td043_remove(struct omap_dss_device *dssdev) 458static void tpo_td043_remove(struct omap_dss_device *dssdev)
459{ 459{
460 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 460 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev);
461 461
462 dev_dbg(&dssdev->dev, "remove\n"); 462 dev_dbg(dssdev->dev, "remove\n");
463 463
464 sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group); 464 sysfs_remove_group(&dssdev->dev->kobj, &tpo_td043_attr_group);
465 regulator_put(tpo_td043->vcc_reg); 465 regulator_put(tpo_td043->vcc_reg);
466} 466}
467 467
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index cb0f145c7077..8f70a8300b84 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -1,5 +1,6 @@
1menuconfig OMAP2_DSS 1menuconfig OMAP2_DSS
2 tristate "OMAP2+ Display Subsystem support" 2 tristate "OMAP2+ Display Subsystem support"
3 select VIDEOMODE_HELPERS
3 help 4 help
4 OMAP2+ Display Subsystem support. 5 OMAP2+ Display Subsystem support.
5 6
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index a4b356a9780d..d6212d63cfb2 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -420,16 +420,26 @@ static void wait_pending_extra_info_updates(void)
420 DSSWARN("timeout in wait_pending_extra_info_updates\n"); 420 DSSWARN("timeout in wait_pending_extra_info_updates\n");
421} 421}
422 422
423static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl) 423static struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
424{ 424{
425 return ovl->manager ? 425 struct omap_dss_device *dssdev;
426 (ovl->manager->output ? ovl->manager->output->device : NULL) : 426
427 NULL; 427 dssdev = mgr->output;
428 if (dssdev == NULL)
429 return NULL;
430
431 while (dssdev->device)
432 dssdev = dssdev->device;
433
434 if (dssdev->driver)
435 return dssdev;
436 else
437 return NULL;
428} 438}
429 439
430static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr) 440static struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
431{ 441{
432 return mgr->output ? mgr->output->device : NULL; 442 return ovl->manager ? dss_mgr_get_device(ovl->manager) : NULL;
433} 443}
434 444
435static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) 445static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
@@ -792,6 +802,18 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
792 } 802 }
793} 803}
794 804
805static int dss_mgr_connect_compat(struct omap_overlay_manager *mgr,
806 struct omap_dss_device *dst)
807{
808 return mgr->set_output(mgr, dst);
809}
810
811static void dss_mgr_disconnect_compat(struct omap_overlay_manager *mgr,
812 struct omap_dss_device *dst)
813{
814 mgr->unset_output(mgr);
815}
816
795static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr) 817static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr)
796{ 818{
797 struct mgr_priv_data *mp = get_mgr_priv(mgr); 819 struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1156,7 +1178,7 @@ static void dss_mgr_get_info(struct omap_overlay_manager *mgr,
1156} 1178}
1157 1179
1158static int dss_mgr_set_output(struct omap_overlay_manager *mgr, 1180static int dss_mgr_set_output(struct omap_overlay_manager *mgr,
1159 struct omap_dss_output *output) 1181 struct omap_dss_device *output)
1160{ 1182{
1161 int r; 1183 int r;
1162 1184
@@ -1554,6 +1576,8 @@ static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_mana
1554} 1576}
1555 1577
1556static const struct dss_mgr_ops apply_mgr_ops = { 1578static const struct dss_mgr_ops apply_mgr_ops = {
1579 .connect = dss_mgr_connect_compat,
1580 .disconnect = dss_mgr_disconnect_compat,
1557 .start_update = dss_mgr_start_update_compat, 1581 .start_update = dss_mgr_start_update_compat,
1558 .enable = dss_mgr_enable_compat, 1582 .enable = dss_mgr_enable_compat,
1559 .disable = dss_mgr_disable_compat, 1583 .disable = dss_mgr_disable_compat,
@@ -1569,7 +1593,6 @@ static DEFINE_MUTEX(compat_init_lock);
1569int omapdss_compat_init(void) 1593int omapdss_compat_init(void)
1570{ 1594{
1571 struct platform_device *pdev = dss_get_core_pdev(); 1595 struct platform_device *pdev = dss_get_core_pdev();
1572 struct omap_dss_device *dssdev = NULL;
1573 int i, r; 1596 int i, r;
1574 1597
1575 mutex_lock(&compat_init_lock); 1598 mutex_lock(&compat_init_lock);
@@ -1579,7 +1602,7 @@ int omapdss_compat_init(void)
1579 1602
1580 apply_init_priv(); 1603 apply_init_priv();
1581 1604
1582 dss_init_overlay_managers(pdev); 1605 dss_init_overlay_managers_sysfs(pdev);
1583 dss_init_overlays(pdev); 1606 dss_init_overlays(pdev);
1584 1607
1585 for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) { 1608 for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
@@ -1615,12 +1638,9 @@ int omapdss_compat_init(void)
1615 if (r) 1638 if (r)
1616 goto err_mgr_ops; 1639 goto err_mgr_ops;
1617 1640
1618 for_each_dss_dev(dssdev) { 1641 r = display_init_sysfs(pdev);
1619 r = display_init_sysfs(pdev, dssdev); 1642 if (r)
1620 /* XXX uninit sysfs files on error */ 1643 goto err_disp_sysfs;
1621 if (r)
1622 goto err_disp_sysfs;
1623 }
1624 1644
1625 dispc_runtime_get(); 1645 dispc_runtime_get();
1626 1646
@@ -1637,12 +1657,13 @@ out:
1637 1657
1638err_init_irq: 1658err_init_irq:
1639 dispc_runtime_put(); 1659 dispc_runtime_put();
1660 display_uninit_sysfs(pdev);
1640 1661
1641err_disp_sysfs: 1662err_disp_sysfs:
1642 dss_uninstall_mgr_ops(); 1663 dss_uninstall_mgr_ops();
1643 1664
1644err_mgr_ops: 1665err_mgr_ops:
1645 dss_uninit_overlay_managers(pdev); 1666 dss_uninit_overlay_managers_sysfs(pdev);
1646 dss_uninit_overlays(pdev); 1667 dss_uninit_overlays(pdev);
1647 1668
1648 compat_refcnt--; 1669 compat_refcnt--;
@@ -1656,7 +1677,6 @@ EXPORT_SYMBOL(omapdss_compat_init);
1656void omapdss_compat_uninit(void) 1677void omapdss_compat_uninit(void)
1657{ 1678{
1658 struct platform_device *pdev = dss_get_core_pdev(); 1679 struct platform_device *pdev = dss_get_core_pdev();
1659 struct omap_dss_device *dssdev = NULL;
1660 1680
1661 mutex_lock(&compat_init_lock); 1681 mutex_lock(&compat_init_lock);
1662 1682
@@ -1665,12 +1685,11 @@ void omapdss_compat_uninit(void)
1665 1685
1666 dss_dispc_uninitialize_irq(); 1686 dss_dispc_uninitialize_irq();
1667 1687
1668 for_each_dss_dev(dssdev) 1688 display_uninit_sysfs(pdev);
1669 display_uninit_sysfs(pdev, dssdev);
1670 1689
1671 dss_uninstall_mgr_ops(); 1690 dss_uninstall_mgr_ops();
1672 1691
1673 dss_uninit_overlay_managers(pdev); 1692 dss_uninit_overlay_managers_sysfs(pdev);
1674 dss_uninit_overlays(pdev); 1693 dss_uninit_overlays(pdev);
1675out: 1694out:
1676 mutex_unlock(&compat_init_lock); 1695 mutex_unlock(&compat_init_lock);
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index c9c2252e3719..1aeb274e30fc 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -88,7 +88,7 @@ struct regulator *dss_get_vdds_dsi(void)
88 if (core.vdds_dsi_reg != NULL) 88 if (core.vdds_dsi_reg != NULL)
89 return core.vdds_dsi_reg; 89 return core.vdds_dsi_reg;
90 90
91 reg = regulator_get(&core.pdev->dev, "vdds_dsi"); 91 reg = devm_regulator_get(&core.pdev->dev, "vdds_dsi");
92 if (!IS_ERR(reg)) 92 if (!IS_ERR(reg))
93 core.vdds_dsi_reg = reg; 93 core.vdds_dsi_reg = reg;
94 94
@@ -102,7 +102,7 @@ struct regulator *dss_get_vdds_sdi(void)
102 if (core.vdds_sdi_reg != NULL) 102 if (core.vdds_sdi_reg != NULL)
103 return core.vdds_sdi_reg; 103 return core.vdds_sdi_reg;
104 104
105 reg = regulator_get(&core.pdev->dev, "vdds_sdi"); 105 reg = devm_regulator_get(&core.pdev->dev, "vdds_sdi");
106 if (!IS_ERR(reg)) 106 if (!IS_ERR(reg))
107 core.vdds_sdi_reg = reg; 107 core.vdds_sdi_reg = reg;
108 108
@@ -243,6 +243,8 @@ static int __init omap_dss_probe(struct platform_device *pdev)
243 243
244 if (def_disp_name) 244 if (def_disp_name)
245 core.default_display_name = def_disp_name; 245 core.default_display_name = def_disp_name;
246 else if (pdata->default_display_name)
247 core.default_display_name = pdata->default_display_name;
246 else if (pdata->default_device) 248 else if (pdata->default_device)
247 core.default_display_name = pdata->default_device->name; 249 core.default_display_name = pdata->default_device->name;
248 250
@@ -290,37 +292,9 @@ static int dss_bus_match(struct device *dev, struct device_driver *driver)
290 return strcmp(dssdev->driver_name, driver->name) == 0; 292 return strcmp(dssdev->driver_name, driver->name) == 0;
291} 293}
292 294
293static ssize_t device_name_show(struct device *dev,
294 struct device_attribute *attr, char *buf)
295{
296 struct omap_dss_device *dssdev = to_dss_device(dev);
297 return snprintf(buf, PAGE_SIZE, "%s\n",
298 dssdev->name ?
299 dssdev->name : "");
300}
301
302static struct device_attribute default_dev_attrs[] = {
303 __ATTR(name, S_IRUGO, device_name_show, NULL),
304 __ATTR_NULL,
305};
306
307static ssize_t driver_name_show(struct device_driver *drv, char *buf)
308{
309 struct omap_dss_driver *dssdrv = to_dss_driver(drv);
310 return snprintf(buf, PAGE_SIZE, "%s\n",
311 dssdrv->driver.name ?
312 dssdrv->driver.name : "");
313}
314static struct driver_attribute default_drv_attrs[] = {
315 __ATTR(name, S_IRUGO, driver_name_show, NULL),
316 __ATTR_NULL,
317};
318
319static struct bus_type dss_bus_type = { 295static struct bus_type dss_bus_type = {
320 .name = "omapdss", 296 .name = "omapdss",
321 .match = dss_bus_match, 297 .match = dss_bus_match,
322 .dev_attrs = default_dev_attrs,
323 .drv_attrs = default_drv_attrs,
324}; 298};
325 299
326static void dss_bus_release(struct device *dev) 300static void dss_bus_release(struct device *dev)
@@ -377,6 +351,46 @@ static int dss_driver_remove(struct device *dev)
377 return 0; 351 return 0;
378} 352}
379 353
354static int omapdss_default_connect(struct omap_dss_device *dssdev)
355{
356 struct omap_dss_device *out;
357 struct omap_overlay_manager *mgr;
358 int r;
359
360 out = dssdev->output;
361
362 if (out == NULL)
363 return -ENODEV;
364
365 mgr = omap_dss_get_overlay_manager(out->dispc_channel);
366 if (!mgr)
367 return -ENODEV;
368
369 r = dss_mgr_connect(mgr, out);
370 if (r)
371 return r;
372
373 return 0;
374}
375
376static void omapdss_default_disconnect(struct omap_dss_device *dssdev)
377{
378 struct omap_dss_device *out;
379 struct omap_overlay_manager *mgr;
380
381 out = dssdev->output;
382
383 if (out == NULL)
384 return;
385
386 mgr = out->manager;
387
388 if (mgr == NULL)
389 return;
390
391 dss_mgr_disconnect(mgr, out);
392}
393
380int omap_dss_register_driver(struct omap_dss_driver *dssdriver) 394int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
381{ 395{
382 dssdriver->driver.bus = &dss_bus_type; 396 dssdriver->driver.bus = &dss_bus_type;
@@ -390,6 +404,10 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
390 omapdss_default_get_recommended_bpp; 404 omapdss_default_get_recommended_bpp;
391 if (dssdriver->get_timings == NULL) 405 if (dssdriver->get_timings == NULL)
392 dssdriver->get_timings = omapdss_default_get_timings; 406 dssdriver->get_timings = omapdss_default_get_timings;
407 if (dssdriver->connect == NULL)
408 dssdriver->connect = omapdss_default_connect;
409 if (dssdriver->disconnect == NULL)
410 dssdriver->disconnect = omapdss_default_disconnect;
393 411
394 return driver_register(&dssdriver->driver); 412 return driver_register(&dssdriver->driver);
395} 413}
@@ -419,29 +437,33 @@ struct omap_dss_device *dss_alloc_and_init_device(struct device *parent)
419 if (!dssdev) 437 if (!dssdev)
420 return NULL; 438 return NULL;
421 439
422 dssdev->dev.bus = &dss_bus_type; 440 dssdev->old_dev.bus = &dss_bus_type;
423 dssdev->dev.parent = parent; 441 dssdev->old_dev.parent = parent;
424 dssdev->dev.release = omap_dss_dev_release; 442 dssdev->old_dev.release = omap_dss_dev_release;
425 dev_set_name(&dssdev->dev, "display%d", disp_num_counter++); 443 dev_set_name(&dssdev->old_dev, "display%d", disp_num_counter++);
426 444
427 device_initialize(&dssdev->dev); 445 device_initialize(&dssdev->old_dev);
428 446
429 return dssdev; 447 return dssdev;
430} 448}
431 449
432int dss_add_device(struct omap_dss_device *dssdev) 450int dss_add_device(struct omap_dss_device *dssdev)
433{ 451{
434 return device_add(&dssdev->dev); 452 dssdev->dev = &dssdev->old_dev;
453
454 omapdss_register_display(dssdev);
455 return device_add(&dssdev->old_dev);
435} 456}
436 457
437void dss_put_device(struct omap_dss_device *dssdev) 458void dss_put_device(struct omap_dss_device *dssdev)
438{ 459{
439 put_device(&dssdev->dev); 460 put_device(&dssdev->old_dev);
440} 461}
441 462
442void dss_unregister_device(struct omap_dss_device *dssdev) 463void dss_unregister_device(struct omap_dss_device *dssdev)
443{ 464{
444 device_unregister(&dssdev->dev); 465 device_unregister(&dssdev->old_dev);
466 omapdss_unregister_display(dssdev);
445} 467}
446 468
447static int dss_unregister_dss_dev(struct device *dev, void *data) 469static int dss_unregister_dss_dev(struct device *dev, void *data)
@@ -618,16 +640,6 @@ static int __init omap_dss_init(void)
618 640
619static void __exit omap_dss_exit(void) 641static void __exit omap_dss_exit(void)
620{ 642{
621 if (core.vdds_dsi_reg != NULL) {
622 regulator_put(core.vdds_dsi_reg);
623 core.vdds_dsi_reg = NULL;
624 }
625
626 if (core.vdds_sdi_reg != NULL) {
627 regulator_put(core.vdds_sdi_reg);
628 core.vdds_sdi_reg = NULL;
629 }
630
631 omap_dss_unregister_drivers(); 643 omap_dss_unregister_drivers();
632 644
633 omap_dss_bus_unregister(); 645 omap_dss_bus_unregister();
diff --git a/drivers/video/omap2/dss/dispc-compat.c b/drivers/video/omap2/dss/dispc-compat.c
index 928884c9a0a9..83779c2b292a 100644
--- a/drivers/video/omap2/dss/dispc-compat.c
+++ b/drivers/video/omap2/dss/dispc-compat.c
@@ -360,8 +360,7 @@ static void dispc_error_worker(struct work_struct *work)
360 if (bit & errors) { 360 if (bit & errors) {
361 DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n", 361 DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n",
362 ovl->name); 362 ovl->name);
363 dispc_ovl_enable(ovl->id, false); 363 ovl->disable(ovl);
364 dispc_mgr_go(ovl->manager->id);
365 msleep(50); 364 msleep(50);
366 } 365 }
367 } 366 }
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index b33b0169bb3b..02a7340111df 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -103,6 +103,7 @@ static struct {
103 int irq; 103 int irq;
104 104
105 unsigned long core_clk_rate; 105 unsigned long core_clk_rate;
106 unsigned long tv_pclk_rate;
106 107
107 u32 fifo_size[DISPC_MAX_NR_FIFOS]; 108 u32 fifo_size[DISPC_MAX_NR_FIFOS];
108 /* maps which plane is using a fifo. fifo-id -> plane-id */ 109 /* maps which plane is using a fifo. fifo-id -> plane-id */
@@ -3071,22 +3072,15 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
3071 3072
3072 return r / pcd; 3073 return r / pcd;
3073 } else { 3074 } else {
3074 enum dss_hdmi_venc_clk_source_select source; 3075 return dispc.tv_pclk_rate;
3075
3076 source = dss_get_hdmi_venc_clk_source();
3077
3078 switch (source) {
3079 case DSS_VENC_TV_CLK:
3080 return venc_get_pixel_clock();
3081 case DSS_HDMI_M_PCLK:
3082 return hdmi_get_pixel_clock();
3083 default:
3084 BUG();
3085 return 0;
3086 }
3087 } 3076 }
3088} 3077}
3089 3078
3079void dispc_set_tv_pclk(unsigned long pclk)
3080{
3081 dispc.tv_pclk_rate = pclk;
3082}
3083
3090unsigned long dispc_core_clk_rate(void) 3084unsigned long dispc_core_clk_rate(void)
3091{ 3085{
3092 return dispc.core_clk_rate; 3086 return dispc.core_clk_rate;
@@ -3710,6 +3704,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
3710 3704
3711 dispc_runtime_put(); 3705 dispc_runtime_put();
3712 3706
3707 dss_init_overlay_managers();
3708
3713 dss_debugfs_create_file("dispc", dispc_dump_regs); 3709 dss_debugfs_create_file("dispc", dispc_dump_regs);
3714 3710
3715 return 0; 3711 return 0;
@@ -3723,6 +3719,8 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
3723{ 3719{
3724 pm_runtime_disable(&pdev->dev); 3720 pm_runtime_disable(&pdev->dev);
3725 3721
3722 dss_uninit_overlay_managers();
3723
3726 return 0; 3724 return 0;
3727} 3725}
3728 3726
diff --git a/drivers/video/omap2/dss/display-sysfs.c b/drivers/video/omap2/dss/display-sysfs.c
index 18211a9ab354..21d7f77df702 100644
--- a/drivers/video/omap2/dss/display-sysfs.c
+++ b/drivers/video/omap2/dss/display-sysfs.c
@@ -22,42 +22,69 @@
22 22
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/jiffies.h>
26#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/sysfs.h>
27 27
28#include <video/omapdss.h> 28#include <video/omapdss.h>
29#include "dss.h" 29#include "dss.h"
30#include "dss_features.h" 30
31static struct omap_dss_device *to_dss_device_sysfs(struct device *dev)
32{
33 struct omap_dss_device *dssdev = NULL;
34
35 for_each_dss_dev(dssdev) {
36 if (dssdev->dev == dev) {
37 omap_dss_put_device(dssdev);
38 return dssdev;
39 }
40 }
41
42 return NULL;
43}
44
45static ssize_t display_name_show(struct device *dev,
46 struct device_attribute *attr, char *buf)
47{
48 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
49
50 return snprintf(buf, PAGE_SIZE, "%s\n",
51 dssdev->name ?
52 dssdev->name : "");
53}
31 54
32static ssize_t display_enabled_show(struct device *dev, 55static ssize_t display_enabled_show(struct device *dev,
33 struct device_attribute *attr, char *buf) 56 struct device_attribute *attr, char *buf)
34{ 57{
35 struct omap_dss_device *dssdev = to_dss_device(dev); 58 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
36 bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED;
37 59
38 return snprintf(buf, PAGE_SIZE, "%d\n", enabled); 60 return snprintf(buf, PAGE_SIZE, "%d\n",
61 omapdss_device_is_enabled(dssdev));
39} 62}
40 63
41static ssize_t display_enabled_store(struct device *dev, 64static ssize_t display_enabled_store(struct device *dev,
42 struct device_attribute *attr, 65 struct device_attribute *attr,
43 const char *buf, size_t size) 66 const char *buf, size_t size)
44{ 67{
45 struct omap_dss_device *dssdev = to_dss_device(dev); 68 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
46 int r; 69 int r;
47 bool enabled; 70 bool enable;
48 71
49 r = strtobool(buf, &enabled); 72 r = strtobool(buf, &enable);
50 if (r) 73 if (r)
51 return r; 74 return r;
52 75
53 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { 76 if (enable == omapdss_device_is_enabled(dssdev))
54 if (enabled) { 77 return size;
55 r = dssdev->driver->enable(dssdev); 78
56 if (r) 79 if (omapdss_device_is_connected(dssdev) == false)
57 return r; 80 return -ENODEV;
58 } else { 81
59 dssdev->driver->disable(dssdev); 82 if (enable) {
60 } 83 r = dssdev->driver->enable(dssdev);
84 if (r)
85 return r;
86 } else {
87 dssdev->driver->disable(dssdev);
61 } 88 }
62 89
63 return size; 90 return size;
@@ -66,7 +93,7 @@ static ssize_t display_enabled_store(struct device *dev,
66static ssize_t display_tear_show(struct device *dev, 93static ssize_t display_tear_show(struct device *dev,
67 struct device_attribute *attr, char *buf) 94 struct device_attribute *attr, char *buf)
68{ 95{
69 struct omap_dss_device *dssdev = to_dss_device(dev); 96 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
70 return snprintf(buf, PAGE_SIZE, "%d\n", 97 return snprintf(buf, PAGE_SIZE, "%d\n",
71 dssdev->driver->get_te ? 98 dssdev->driver->get_te ?
72 dssdev->driver->get_te(dssdev) : 0); 99 dssdev->driver->get_te(dssdev) : 0);
@@ -75,7 +102,7 @@ static ssize_t display_tear_show(struct device *dev,
75static ssize_t display_tear_store(struct device *dev, 102static ssize_t display_tear_store(struct device *dev,
76 struct device_attribute *attr, const char *buf, size_t size) 103 struct device_attribute *attr, const char *buf, size_t size)
77{ 104{
78 struct omap_dss_device *dssdev = to_dss_device(dev); 105 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
79 int r; 106 int r;
80 bool te; 107 bool te;
81 108
@@ -96,7 +123,7 @@ static ssize_t display_tear_store(struct device *dev,
96static ssize_t display_timings_show(struct device *dev, 123static ssize_t display_timings_show(struct device *dev,
97 struct device_attribute *attr, char *buf) 124 struct device_attribute *attr, char *buf)
98{ 125{
99 struct omap_dss_device *dssdev = to_dss_device(dev); 126 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
100 struct omap_video_timings t; 127 struct omap_video_timings t;
101 128
102 if (!dssdev->driver->get_timings) 129 if (!dssdev->driver->get_timings)
@@ -113,7 +140,7 @@ static ssize_t display_timings_show(struct device *dev,
113static ssize_t display_timings_store(struct device *dev, 140static ssize_t display_timings_store(struct device *dev,
114 struct device_attribute *attr, const char *buf, size_t size) 141 struct device_attribute *attr, const char *buf, size_t size)
115{ 142{
116 struct omap_dss_device *dssdev = to_dss_device(dev); 143 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
117 struct omap_video_timings t = dssdev->panel.timings; 144 struct omap_video_timings t = dssdev->panel.timings;
118 int r, found; 145 int r, found;
119 146
@@ -152,7 +179,7 @@ static ssize_t display_timings_store(struct device *dev,
152static ssize_t display_rotate_show(struct device *dev, 179static ssize_t display_rotate_show(struct device *dev,
153 struct device_attribute *attr, char *buf) 180 struct device_attribute *attr, char *buf)
154{ 181{
155 struct omap_dss_device *dssdev = to_dss_device(dev); 182 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
156 int rotate; 183 int rotate;
157 if (!dssdev->driver->get_rotate) 184 if (!dssdev->driver->get_rotate)
158 return -ENOENT; 185 return -ENOENT;
@@ -163,7 +190,7 @@ static ssize_t display_rotate_show(struct device *dev,
163static ssize_t display_rotate_store(struct device *dev, 190static ssize_t display_rotate_store(struct device *dev,
164 struct device_attribute *attr, const char *buf, size_t size) 191 struct device_attribute *attr, const char *buf, size_t size)
165{ 192{
166 struct omap_dss_device *dssdev = to_dss_device(dev); 193 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
167 int rot, r; 194 int rot, r;
168 195
169 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) 196 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
@@ -183,7 +210,7 @@ static ssize_t display_rotate_store(struct device *dev,
183static ssize_t display_mirror_show(struct device *dev, 210static ssize_t display_mirror_show(struct device *dev,
184 struct device_attribute *attr, char *buf) 211 struct device_attribute *attr, char *buf)
185{ 212{
186 struct omap_dss_device *dssdev = to_dss_device(dev); 213 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
187 int mirror; 214 int mirror;
188 if (!dssdev->driver->get_mirror) 215 if (!dssdev->driver->get_mirror)
189 return -ENOENT; 216 return -ENOENT;
@@ -194,7 +221,7 @@ static ssize_t display_mirror_show(struct device *dev,
194static ssize_t display_mirror_store(struct device *dev, 221static ssize_t display_mirror_store(struct device *dev,
195 struct device_attribute *attr, const char *buf, size_t size) 222 struct device_attribute *attr, const char *buf, size_t size)
196{ 223{
197 struct omap_dss_device *dssdev = to_dss_device(dev); 224 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
198 int r; 225 int r;
199 bool mirror; 226 bool mirror;
200 227
@@ -215,7 +242,7 @@ static ssize_t display_mirror_store(struct device *dev,
215static ssize_t display_wss_show(struct device *dev, 242static ssize_t display_wss_show(struct device *dev,
216 struct device_attribute *attr, char *buf) 243 struct device_attribute *attr, char *buf)
217{ 244{
218 struct omap_dss_device *dssdev = to_dss_device(dev); 245 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
219 unsigned int wss; 246 unsigned int wss;
220 247
221 if (!dssdev->driver->get_wss) 248 if (!dssdev->driver->get_wss)
@@ -229,7 +256,7 @@ static ssize_t display_wss_show(struct device *dev,
229static ssize_t display_wss_store(struct device *dev, 256static ssize_t display_wss_store(struct device *dev,
230 struct device_attribute *attr, const char *buf, size_t size) 257 struct device_attribute *attr, const char *buf, size_t size)
231{ 258{
232 struct omap_dss_device *dssdev = to_dss_device(dev); 259 struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
233 u32 wss; 260 u32 wss;
234 int r; 261 int r;
235 262
@@ -250,6 +277,7 @@ static ssize_t display_wss_store(struct device *dev,
250 return size; 277 return size;
251} 278}
252 279
280static DEVICE_ATTR(name, S_IRUGO, display_name_show, NULL);
253static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR, 281static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
254 display_enabled_show, display_enabled_store); 282 display_enabled_show, display_enabled_store);
255static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR, 283static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
@@ -263,59 +291,55 @@ static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
263static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR, 291static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
264 display_wss_show, display_wss_store); 292 display_wss_show, display_wss_store);
265 293
266static struct device_attribute *display_sysfs_attrs[] = { 294static const struct attribute *display_sysfs_attrs[] = {
267 &dev_attr_enabled, 295 &dev_attr_name.attr,
268 &dev_attr_tear_elim, 296 &dev_attr_enabled.attr,
269 &dev_attr_timings, 297 &dev_attr_tear_elim.attr,
270 &dev_attr_rotate, 298 &dev_attr_timings.attr,
271 &dev_attr_mirror, 299 &dev_attr_rotate.attr,
272 &dev_attr_wss, 300 &dev_attr_mirror.attr,
301 &dev_attr_wss.attr,
273 NULL 302 NULL
274}; 303};
275 304
276int display_init_sysfs(struct platform_device *pdev, 305int display_init_sysfs(struct platform_device *pdev)
277 struct omap_dss_device *dssdev)
278{ 306{
279 struct device_attribute *attr; 307 struct omap_dss_device *dssdev = NULL;
280 int i, r; 308 int r;
281 309
282 /* create device sysfs files */ 310 for_each_dss_dev(dssdev) {
283 i = 0; 311 struct kobject *kobj = &dssdev->dev->kobj;
284 while ((attr = display_sysfs_attrs[i++]) != NULL) {
285 r = device_create_file(&dssdev->dev, attr);
286 if (r) {
287 for (i = i - 2; i >= 0; i--) {
288 attr = display_sysfs_attrs[i];
289 device_remove_file(&dssdev->dev, attr);
290 }
291 312
292 DSSERR("failed to create sysfs file\n"); 313 r = sysfs_create_files(kobj, display_sysfs_attrs);
293 return r; 314 if (r) {
315 DSSERR("failed to create sysfs files\n");
316 goto err;
294 } 317 }
295 }
296 318
297 /* create display? sysfs links */ 319 r = sysfs_create_link(&pdev->dev.kobj, kobj, dssdev->alias);
298 r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj, 320 if (r) {
299 dev_name(&dssdev->dev)); 321 sysfs_remove_files(kobj, display_sysfs_attrs);
300 if (r) {
301 while ((attr = display_sysfs_attrs[i++]) != NULL)
302 device_remove_file(&dssdev->dev, attr);
303 322
304 DSSERR("failed to create sysfs display link\n"); 323 DSSERR("failed to create sysfs display link\n");
305 return r; 324 goto err;
325 }
306 } 326 }
307 327
308 return 0; 328 return 0;
329
330err:
331 display_uninit_sysfs(pdev);
332
333 return r;
309} 334}
310 335
311void display_uninit_sysfs(struct platform_device *pdev, 336void display_uninit_sysfs(struct platform_device *pdev)
312 struct omap_dss_device *dssdev)
313{ 337{
314 struct device_attribute *attr; 338 struct omap_dss_device *dssdev = NULL;
315 int i = 0;
316
317 sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev));
318 339
319 while ((attr = display_sysfs_attrs[i++]) != NULL) 340 for_each_dss_dev(dssdev) {
320 device_remove_file(&dssdev->dev, attr); 341 sysfs_remove_link(&pdev->dev.kobj, dssdev->alias);
342 sysfs_remove_files(&dssdev->dev->kobj,
343 display_sysfs_attrs);
344 }
321} 345}
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 0aa8ad8f9667..fafe7c941a60 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -61,6 +61,7 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
61 case OMAP_DISPLAY_TYPE_VENC: 61 case OMAP_DISPLAY_TYPE_VENC:
62 case OMAP_DISPLAY_TYPE_SDI: 62 case OMAP_DISPLAY_TYPE_SDI:
63 case OMAP_DISPLAY_TYPE_HDMI: 63 case OMAP_DISPLAY_TYPE_HDMI:
64 case OMAP_DISPLAY_TYPE_DVI:
64 return 24; 65 return 24;
65 default: 66 default:
66 BUG(); 67 BUG();
@@ -76,110 +77,154 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
76} 77}
77EXPORT_SYMBOL(omapdss_default_get_timings); 78EXPORT_SYMBOL(omapdss_default_get_timings);
78 79
79static int dss_suspend_device(struct device *dev, void *data) 80int dss_suspend_all_devices(void)
80{ 81{
81 struct omap_dss_device *dssdev = to_dss_device(dev); 82 struct omap_dss_device *dssdev = NULL;
82
83 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
84 dssdev->activate_after_resume = false;
85 return 0;
86 }
87
88 dssdev->driver->disable(dssdev);
89
90 dssdev->activate_after_resume = true;
91 83
92 return 0; 84 for_each_dss_dev(dssdev) {
93} 85 if (!dssdev->driver)
86 continue;
94 87
95int dss_suspend_all_devices(void) 88 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
96{ 89 dssdev->driver->disable(dssdev);
97 int r; 90 dssdev->activate_after_resume = true;
98 struct bus_type *bus = dss_get_bus(); 91 } else {
99 92 dssdev->activate_after_resume = false;
100 r = bus_for_each_dev(bus, NULL, NULL, dss_suspend_device); 93 }
101 if (r) {
102 /* resume all displays that were suspended */
103 dss_resume_all_devices();
104 return r;
105 } 94 }
106 95
107 return 0; 96 return 0;
108} 97}
109 98
110static int dss_resume_device(struct device *dev, void *data) 99int dss_resume_all_devices(void)
111{ 100{
112 int r; 101 struct omap_dss_device *dssdev = NULL;
113 struct omap_dss_device *dssdev = to_dss_device(dev);
114 102
115 if (dssdev->activate_after_resume) { 103 for_each_dss_dev(dssdev) {
116 r = dssdev->driver->enable(dssdev); 104 if (!dssdev->driver)
117 if (r) 105 continue;
118 return r;
119 }
120 106
121 dssdev->activate_after_resume = false; 107 if (dssdev->activate_after_resume) {
108 dssdev->driver->enable(dssdev);
109 dssdev->activate_after_resume = false;
110 }
111 }
122 112
123 return 0; 113 return 0;
124} 114}
125 115
126int dss_resume_all_devices(void) 116void dss_disable_all_devices(void)
127{ 117{
128 struct bus_type *bus = dss_get_bus(); 118 struct omap_dss_device *dssdev = NULL;
119
120 for_each_dss_dev(dssdev) {
121 if (!dssdev->driver)
122 continue;
129 123
130 return bus_for_each_dev(bus, NULL, NULL, dss_resume_device); 124 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
125 dssdev->driver->disable(dssdev);
126 }
131} 127}
132 128
133static int dss_disable_device(struct device *dev, void *data) 129static LIST_HEAD(panel_list);
130static DEFINE_MUTEX(panel_list_mutex);
131static int disp_num_counter;
132
133int omapdss_register_display(struct omap_dss_device *dssdev)
134{ 134{
135 struct omap_dss_device *dssdev = to_dss_device(dev); 135 struct omap_dss_driver *drv = dssdev->driver;
136 136
137 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) 137 snprintf(dssdev->alias, sizeof(dssdev->alias),
138 dssdev->driver->disable(dssdev); 138 "display%d", disp_num_counter++);
139 139
140 if (drv && drv->get_resolution == NULL)
141 drv->get_resolution = omapdss_default_get_resolution;
142 if (drv && drv->get_recommended_bpp == NULL)
143 drv->get_recommended_bpp = omapdss_default_get_recommended_bpp;
144 if (drv && drv->get_timings == NULL)
145 drv->get_timings = omapdss_default_get_timings;
146
147 mutex_lock(&panel_list_mutex);
148 list_add_tail(&dssdev->panel_list, &panel_list);
149 mutex_unlock(&panel_list_mutex);
140 return 0; 150 return 0;
141} 151}
152EXPORT_SYMBOL(omapdss_register_display);
142 153
143void dss_disable_all_devices(void) 154void omapdss_unregister_display(struct omap_dss_device *dssdev)
144{ 155{
145 struct bus_type *bus = dss_get_bus(); 156 mutex_lock(&panel_list_mutex);
146 bus_for_each_dev(bus, NULL, NULL, dss_disable_device); 157 list_del(&dssdev->panel_list);
158 mutex_unlock(&panel_list_mutex);
147} 159}
160EXPORT_SYMBOL(omapdss_unregister_display);
148 161
149 162struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev)
150void omap_dss_get_device(struct omap_dss_device *dssdev)
151{ 163{
152 get_device(&dssdev->dev); 164 if (!try_module_get(dssdev->owner))
165 return NULL;
166
167 if (get_device(dssdev->dev) == NULL) {
168 module_put(dssdev->owner);
169 return NULL;
170 }
171
172 return dssdev;
153} 173}
154EXPORT_SYMBOL(omap_dss_get_device); 174EXPORT_SYMBOL(omap_dss_get_device);
155 175
156void omap_dss_put_device(struct omap_dss_device *dssdev) 176void omap_dss_put_device(struct omap_dss_device *dssdev)
157{ 177{
158 put_device(&dssdev->dev); 178 put_device(dssdev->dev);
179 module_put(dssdev->owner);
159} 180}
160EXPORT_SYMBOL(omap_dss_put_device); 181EXPORT_SYMBOL(omap_dss_put_device);
161 182
162/* ref count of the found device is incremented. ref count 183/*
163 * of from-device is decremented. */ 184 * ref count of the found device is incremented.
185 * ref count of from-device is decremented.
186 */
164struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from) 187struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
165{ 188{
166 struct device *dev; 189 struct list_head *l;
167 struct device *dev_start = NULL; 190 struct omap_dss_device *dssdev;
168 struct omap_dss_device *dssdev = NULL; 191
192 mutex_lock(&panel_list_mutex);
169 193
170 int match(struct device *dev, void *data) 194 if (list_empty(&panel_list)) {
171 { 195 dssdev = NULL;
172 return 1; 196 goto out;
173 } 197 }
174 198
175 if (from) 199 if (from == NULL) {
176 dev_start = &from->dev; 200 dssdev = list_first_entry(&panel_list, struct omap_dss_device,
177 dev = bus_find_device(dss_get_bus(), dev_start, NULL, match); 201 panel_list);
178 if (dev) 202 omap_dss_get_device(dssdev);
179 dssdev = to_dss_device(dev); 203 goto out;
180 if (from) 204 }
181 put_device(&from->dev); 205
206 omap_dss_put_device(from);
207
208 list_for_each(l, &panel_list) {
209 dssdev = list_entry(l, struct omap_dss_device, panel_list);
210 if (dssdev == from) {
211 if (list_is_last(l, &panel_list)) {
212 dssdev = NULL;
213 goto out;
214 }
215
216 dssdev = list_entry(l->next, struct omap_dss_device,
217 panel_list);
218 omap_dss_get_device(dssdev);
219 goto out;
220 }
221 }
182 222
223 WARN(1, "'from' dssdev not found\n");
224
225 dssdev = NULL;
226out:
227 mutex_unlock(&panel_list_mutex);
183 return dssdev; 228 return dssdev;
184} 229}
185EXPORT_SYMBOL(omap_dss_get_next_device); 230EXPORT_SYMBOL(omap_dss_get_next_device);
@@ -198,24 +243,72 @@ struct omap_dss_device *omap_dss_find_device(void *data,
198} 243}
199EXPORT_SYMBOL(omap_dss_find_device); 244EXPORT_SYMBOL(omap_dss_find_device);
200 245
201int omap_dss_start_device(struct omap_dss_device *dssdev) 246void videomode_to_omap_video_timings(const struct videomode *vm,
247 struct omap_video_timings *ovt)
202{ 248{
203 if (!dssdev->driver) { 249 memset(ovt, 0, sizeof(*ovt));
204 DSSDBG("no driver\n"); 250
205 return -ENODEV; 251 ovt->pixel_clock = vm->pixelclock / 1000;
206 } 252 ovt->x_res = vm->hactive;
207 253 ovt->hbp = vm->hback_porch;
208 if (!try_module_get(dssdev->dev.driver->owner)) { 254 ovt->hfp = vm->hfront_porch;
209 return -ENODEV; 255 ovt->hsw = vm->hsync_len;
210 } 256 ovt->y_res = vm->vactive;
211 257 ovt->vbp = vm->vback_porch;
212 return 0; 258 ovt->vfp = vm->vfront_porch;
259 ovt->vsw = vm->vsync_len;
260
261 ovt->vsync_level = vm->flags & DISPLAY_FLAGS_VSYNC_HIGH ?
262 OMAPDSS_SIG_ACTIVE_HIGH :
263 OMAPDSS_SIG_ACTIVE_LOW;
264 ovt->hsync_level = vm->flags & DISPLAY_FLAGS_HSYNC_HIGH ?
265 OMAPDSS_SIG_ACTIVE_HIGH :
266 OMAPDSS_SIG_ACTIVE_LOW;
267 ovt->de_level = vm->flags & DISPLAY_FLAGS_DE_HIGH ?
268 OMAPDSS_SIG_ACTIVE_HIGH :
269 OMAPDSS_SIG_ACTIVE_HIGH;
270 ovt->data_pclk_edge = vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE ?
271 OMAPDSS_DRIVE_SIG_RISING_EDGE :
272 OMAPDSS_DRIVE_SIG_FALLING_EDGE;
273
274 ovt->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
213} 275}
214EXPORT_SYMBOL(omap_dss_start_device); 276EXPORT_SYMBOL(videomode_to_omap_video_timings);
215 277
216void omap_dss_stop_device(struct omap_dss_device *dssdev) 278void omap_video_timings_to_videomode(const struct omap_video_timings *ovt,
279 struct videomode *vm)
217{ 280{
218 module_put(dssdev->dev.driver->owner); 281 memset(vm, 0, sizeof(*vm));
282
283 vm->pixelclock = ovt->pixel_clock * 1000;
284
285 vm->hactive = ovt->x_res;
286 vm->hback_porch = ovt->hbp;
287 vm->hfront_porch = ovt->hfp;
288 vm->hsync_len = ovt->hsw;
289 vm->vactive = ovt->y_res;
290 vm->vback_porch = ovt->vbp;
291 vm->vfront_porch = ovt->vfp;
292 vm->vsync_len = ovt->vsw;
293
294 if (ovt->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH)
295 vm->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
296 else
297 vm->flags |= DISPLAY_FLAGS_HSYNC_LOW;
298
299 if (ovt->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH)
300 vm->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
301 else
302 vm->flags |= DISPLAY_FLAGS_VSYNC_LOW;
303
304 if (ovt->de_level == OMAPDSS_SIG_ACTIVE_HIGH)
305 vm->flags |= DISPLAY_FLAGS_DE_HIGH;
306 else
307 vm->flags |= DISPLAY_FLAGS_DE_LOW;
308
309 if (ovt->data_pclk_edge == OMAPDSS_DRIVE_SIG_RISING_EDGE)
310 vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
311 else
312 vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
219} 313}
220EXPORT_SYMBOL(omap_dss_stop_device); 314EXPORT_SYMBOL(omap_video_timings_to_videomode);
221
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 757b57f7275a..a6b331ef7763 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -37,6 +37,8 @@
37#include "dss_features.h" 37#include "dss_features.h"
38 38
39static struct { 39static struct {
40 struct platform_device *pdev;
41
40 struct regulator *vdds_dsi_reg; 42 struct regulator *vdds_dsi_reg;
41 struct platform_device *dsidev; 43 struct platform_device *dsidev;
42 44
@@ -46,7 +48,7 @@ static struct {
46 struct dss_lcd_mgr_config mgr_config; 48 struct dss_lcd_mgr_config mgr_config;
47 int data_lines; 49 int data_lines;
48 50
49 struct omap_dss_output output; 51 struct omap_dss_device output;
50} dpi; 52} dpi;
51 53
52static struct platform_device *dpi_get_dsidev(enum omap_channel channel) 54static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
@@ -129,7 +131,7 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
129 * shifted. So skip all odd dividers when the pixel clock is on the 131 * shifted. So skip all odd dividers when the pixel clock is on the
130 * higher side. 132 * higher side.
131 */ 133 */
132 if (ctx->pck_min >= 1000000) { 134 if (ctx->pck_min >= 100000000) {
133 if (lckd > 1 && lckd % 2 != 0) 135 if (lckd > 1 && lckd % 2 != 0)
134 return false; 136 return false;
135 137
@@ -156,7 +158,7 @@ static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
156 * shifted. So skip all odd dividers when the pixel clock is on the 158 * shifted. So skip all odd dividers when the pixel clock is on the
157 * higher side. 159 * higher side.
158 */ 160 */
159 if (regm_dispc > 1 && regm_dispc % 2 != 0 && ctx->pck_min >= 1000000) 161 if (regm_dispc > 1 && regm_dispc % 2 != 0 && ctx->pck_min >= 100000000)
160 return false; 162 return false;
161 163
162 ctx->dsi_cinfo.regm_dispc = regm_dispc; 164 ctx->dsi_cinfo.regm_dispc = regm_dispc;
@@ -345,7 +347,7 @@ static void dpi_config_lcd_manager(struct omap_overlay_manager *mgr)
345 347
346int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) 348int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
347{ 349{
348 struct omap_dss_output *out = &dpi.output; 350 struct omap_dss_device *out = &dpi.output;
349 int r; 351 int r;
350 352
351 mutex_lock(&dpi.lock); 353 mutex_lock(&dpi.lock);
@@ -362,12 +364,6 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
362 goto err_no_out_mgr; 364 goto err_no_out_mgr;
363 } 365 }
364 366
365 r = omap_dss_start_device(dssdev);
366 if (r) {
367 DSSERR("failed to start device\n");
368 goto err_start_dev;
369 }
370
371 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) { 367 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
372 r = regulator_enable(dpi.vdds_dsi_reg); 368 r = regulator_enable(dpi.vdds_dsi_reg);
373 if (r) 369 if (r)
@@ -422,8 +418,6 @@ err_get_dispc:
422 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) 418 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
423 regulator_disable(dpi.vdds_dsi_reg); 419 regulator_disable(dpi.vdds_dsi_reg);
424err_reg_enable: 420err_reg_enable:
425 omap_dss_stop_device(dssdev);
426err_start_dev:
427err_no_out_mgr: 421err_no_out_mgr:
428err_no_reg: 422err_no_reg:
429 mutex_unlock(&dpi.lock); 423 mutex_unlock(&dpi.lock);
@@ -450,8 +444,6 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
450 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) 444 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
451 regulator_disable(dpi.vdds_dsi_reg); 445 regulator_disable(dpi.vdds_dsi_reg);
452 446
453 omap_dss_stop_device(dssdev);
454
455 mutex_unlock(&dpi.lock); 447 mutex_unlock(&dpi.lock);
456} 448}
457EXPORT_SYMBOL(omapdss_dpi_display_disable); 449EXPORT_SYMBOL(omapdss_dpi_display_disable);
@@ -469,6 +461,16 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
469} 461}
470EXPORT_SYMBOL(omapdss_dpi_set_timings); 462EXPORT_SYMBOL(omapdss_dpi_set_timings);
471 463
464static void dpi_get_timings(struct omap_dss_device *dssdev,
465 struct omap_video_timings *timings)
466{
467 mutex_lock(&dpi.lock);
468
469 *timings = dpi.timings;
470
471 mutex_unlock(&dpi.lock);
472}
473
472int dpi_check_timings(struct omap_dss_device *dssdev, 474int dpi_check_timings(struct omap_dss_device *dssdev,
473 struct omap_video_timings *timings) 475 struct omap_video_timings *timings)
474{ 476{
@@ -542,6 +544,50 @@ static int dpi_verify_dsi_pll(struct platform_device *dsidev)
542 return 0; 544 return 0;
543} 545}
544 546
547static int dpi_init_regulator(void)
548{
549 struct regulator *vdds_dsi;
550
551 if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
552 return 0;
553
554 if (dpi.vdds_dsi_reg)
555 return 0;
556
557 vdds_dsi = dss_get_vdds_dsi();
558
559 if (IS_ERR(vdds_dsi)) {
560 vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi");
561 if (IS_ERR(vdds_dsi)) {
562 DSSERR("can't get VDDS_DSI regulator\n");
563 return PTR_ERR(vdds_dsi);
564 }
565 }
566
567 dpi.vdds_dsi_reg = vdds_dsi;
568
569 return 0;
570}
571
572static void dpi_init_pll(void)
573{
574 struct platform_device *dsidev;
575
576 if (dpi.dsidev)
577 return;
578
579 dsidev = dpi_get_dsidev(dpi.output.dispc_channel);
580 if (!dsidev)
581 return;
582
583 if (dpi_verify_dsi_pll(dsidev)) {
584 DSSWARN("DSI PLL not operational\n");
585 return;
586 }
587
588 dpi.dsidev = dsidev;
589}
590
545/* 591/*
546 * Return a hardcoded channel for the DPI output. This should work for 592 * Return a hardcoded channel for the DPI output. This should work for
547 * current use cases, but this can be later expanded to either resolve 593 * current use cases, but this can be later expanded to either resolve
@@ -572,41 +618,6 @@ static enum omap_channel dpi_get_channel(void)
572 } 618 }
573} 619}
574 620
575static int dpi_init_display(struct omap_dss_device *dssdev)
576{
577 struct platform_device *dsidev;
578
579 DSSDBG("init_display\n");
580
581 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
582 dpi.vdds_dsi_reg == NULL) {
583 struct regulator *vdds_dsi;
584
585 vdds_dsi = dss_get_vdds_dsi();
586
587 if (IS_ERR(vdds_dsi)) {
588 DSSERR("can't get VDDS_DSI regulator\n");
589 return PTR_ERR(vdds_dsi);
590 }
591
592 dpi.vdds_dsi_reg = vdds_dsi;
593 }
594
595 dsidev = dpi_get_dsidev(dpi.output.dispc_channel);
596
597 if (dsidev && dpi_verify_dsi_pll(dsidev)) {
598 dsidev = NULL;
599 DSSWARN("DSI PLL not operational\n");
600 }
601
602 if (dsidev)
603 DSSDBG("using DSI PLL for DPI clock\n");
604
605 dpi.dsidev = dsidev;
606
607 return 0;
608}
609
610static struct omap_dss_device *dpi_find_dssdev(struct platform_device *pdev) 621static struct omap_dss_device *dpi_find_dssdev(struct platform_device *pdev)
611{ 622{
612 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 623 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
@@ -646,19 +657,18 @@ static int dpi_probe_pdata(struct platform_device *dpidev)
646 if (!plat_dssdev) 657 if (!plat_dssdev)
647 return 0; 658 return 0;
648 659
660 r = dpi_init_regulator();
661 if (r)
662 return r;
663
664 dpi_init_pll();
665
649 dssdev = dss_alloc_and_init_device(&dpidev->dev); 666 dssdev = dss_alloc_and_init_device(&dpidev->dev);
650 if (!dssdev) 667 if (!dssdev)
651 return -ENOMEM; 668 return -ENOMEM;
652 669
653 dss_copy_device_pdata(dssdev, plat_dssdev); 670 dss_copy_device_pdata(dssdev, plat_dssdev);
654 671
655 r = dpi_init_display(dssdev);
656 if (r) {
657 DSSERR("device %s init failed: %d\n", dssdev->name, r);
658 dss_put_device(dssdev);
659 return r;
660 }
661
662 r = omapdss_output_set_device(&dpi.output, dssdev); 672 r = omapdss_output_set_device(&dpi.output, dssdev);
663 if (r) { 673 if (r) {
664 DSSERR("failed to connect output to new device: %s\n", 674 DSSERR("failed to connect output to new device: %s\n",
@@ -678,41 +688,108 @@ static int dpi_probe_pdata(struct platform_device *dpidev)
678 return 0; 688 return 0;
679} 689}
680 690
691static int dpi_connect(struct omap_dss_device *dssdev,
692 struct omap_dss_device *dst)
693{
694 struct omap_overlay_manager *mgr;
695 int r;
696
697 r = dpi_init_regulator();
698 if (r)
699 return r;
700
701 dpi_init_pll();
702
703 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
704 if (!mgr)
705 return -ENODEV;
706
707 r = dss_mgr_connect(mgr, dssdev);
708 if (r)
709 return r;
710
711 r = omapdss_output_set_device(dssdev, dst);
712 if (r) {
713 DSSERR("failed to connect output to new device: %s\n",
714 dst->name);
715 dss_mgr_disconnect(mgr, dssdev);
716 return r;
717 }
718
719 return 0;
720}
721
722static void dpi_disconnect(struct omap_dss_device *dssdev,
723 struct omap_dss_device *dst)
724{
725 WARN_ON(dst != dssdev->device);
726
727 if (dst != dssdev->device)
728 return;
729
730 omapdss_output_unset_device(dssdev);
731
732 if (dssdev->manager)
733 dss_mgr_disconnect(dssdev->manager, dssdev);
734}
735
736static const struct omapdss_dpi_ops dpi_ops = {
737 .connect = dpi_connect,
738 .disconnect = dpi_disconnect,
739
740 .enable = omapdss_dpi_display_enable,
741 .disable = omapdss_dpi_display_disable,
742
743 .check_timings = dpi_check_timings,
744 .set_timings = omapdss_dpi_set_timings,
745 .get_timings = dpi_get_timings,
746
747 .set_data_lines = omapdss_dpi_set_data_lines,
748};
749
681static void dpi_init_output(struct platform_device *pdev) 750static void dpi_init_output(struct platform_device *pdev)
682{ 751{
683 struct omap_dss_output *out = &dpi.output; 752 struct omap_dss_device *out = &dpi.output;
684 753
685 out->pdev = pdev; 754 out->dev = &pdev->dev;
686 out->id = OMAP_DSS_OUTPUT_DPI; 755 out->id = OMAP_DSS_OUTPUT_DPI;
687 out->type = OMAP_DISPLAY_TYPE_DPI; 756 out->output_type = OMAP_DISPLAY_TYPE_DPI;
688 out->name = "dpi.0"; 757 out->name = "dpi.0";
689 out->dispc_channel = dpi_get_channel(); 758 out->dispc_channel = dpi_get_channel();
759 out->ops.dpi = &dpi_ops;
760 out->owner = THIS_MODULE;
690 761
691 dss_register_output(out); 762 omapdss_register_output(out);
692} 763}
693 764
694static void __exit dpi_uninit_output(struct platform_device *pdev) 765static void __exit dpi_uninit_output(struct platform_device *pdev)
695{ 766{
696 struct omap_dss_output *out = &dpi.output; 767 struct omap_dss_device *out = &dpi.output;
697 768
698 dss_unregister_output(out); 769 omapdss_unregister_output(out);
699} 770}
700 771
701static int omap_dpi_probe(struct platform_device *pdev) 772static int omap_dpi_probe(struct platform_device *pdev)
702{ 773{
703 int r; 774 int r;
704 775
776 dpi.pdev = pdev;
777
705 mutex_init(&dpi.lock); 778 mutex_init(&dpi.lock);
706 779
707 dpi_init_output(pdev); 780 dpi_init_output(pdev);
708 781
709 r = dpi_probe_pdata(pdev); 782 if (pdev->dev.platform_data) {
710 if (r) { 783 r = dpi_probe_pdata(pdev);
711 dpi_uninit_output(pdev); 784 if (r)
712 return r; 785 goto err_probe;
713 } 786 }
714 787
715 return 0; 788 return 0;
789
790err_probe:
791 dpi_uninit_output(pdev);
792 return r;
716} 793}
717 794
718static int __exit omap_dpi_remove(struct platform_device *pdev) 795static int __exit omap_dpi_remove(struct platform_device *pdev)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index a73dedc33101..99a043b08f0d 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -363,7 +363,7 @@ struct dsi_data {
363 enum omap_dss_dsi_mode mode; 363 enum omap_dss_dsi_mode mode;
364 struct omap_dss_dsi_videomode_timings vm_timings; 364 struct omap_dss_dsi_videomode_timings vm_timings;
365 365
366 struct omap_dss_output output; 366 struct omap_dss_device output;
367}; 367};
368 368
369struct dsi_packet_sent_handler_data { 369struct dsi_packet_sent_handler_data {
@@ -383,12 +383,21 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside
383 383
384static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) 384static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
385{ 385{
386 return dssdev->output->pdev; 386 /* HACK: dssdev can be either the panel device, when using old API, or
387 * the dsi device itself, when using the new API. So we solve this for
388 * now by checking the dssdev->id. This will be removed when the old API
389 * is removed.
390 */
391 if (dssdev->id == OMAP_DSS_OUTPUT_DSI1 ||
392 dssdev->id == OMAP_DSS_OUTPUT_DSI2)
393 return to_platform_device(dssdev->dev);
394
395 return to_platform_device(dssdev->output->dev);
387} 396}
388 397
389struct platform_device *dsi_get_dsidev_from_id(int module) 398struct platform_device *dsi_get_dsidev_from_id(int module)
390{ 399{
391 struct omap_dss_output *out; 400 struct omap_dss_device *out;
392 enum omap_dss_output_id id; 401 enum omap_dss_output_id id;
393 402
394 switch (module) { 403 switch (module) {
@@ -404,7 +413,7 @@ struct platform_device *dsi_get_dsidev_from_id(int module)
404 413
405 out = omap_dss_get_output(id); 414 out = omap_dss_get_output(id);
406 415
407 return out ? out->pdev : NULL; 416 return out ? to_platform_device(out->dev) : NULL;
408} 417}
409 418
410static inline void dsi_write_reg(struct platform_device *dsidev, 419static inline void dsi_write_reg(struct platform_device *dsidev,
@@ -1114,6 +1123,30 @@ void dsi_runtime_put(struct platform_device *dsidev)
1114 WARN_ON(r < 0 && r != -ENOSYS); 1123 WARN_ON(r < 0 && r != -ENOSYS);
1115} 1124}
1116 1125
1126static int dsi_regulator_init(struct platform_device *dsidev)
1127{
1128 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1129 struct regulator *vdds_dsi;
1130
1131 if (dsi->vdds_dsi_reg != NULL)
1132 return 0;
1133
1134 vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "vdds_dsi");
1135
1136 /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
1137 if (IS_ERR(vdds_dsi))
1138 vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "VCXIO");
1139
1140 if (IS_ERR(vdds_dsi)) {
1141 DSSERR("can't get VDDS_DSI regulator\n");
1142 return PTR_ERR(vdds_dsi);
1143 }
1144
1145 dsi->vdds_dsi_reg = vdds_dsi;
1146
1147 return 0;
1148}
1149
1117/* source clock for DSI PLL. this could also be PCLKFREE */ 1150/* source clock for DSI PLL. this could also be PCLKFREE */
1118static inline void dsi_enable_pll_clock(struct platform_device *dsidev, 1151static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
1119 bool enable) 1152 bool enable)
@@ -1592,22 +1625,9 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
1592 */ 1625 */
1593 enable_hsclk = enable_hsdiv = true; 1626 enable_hsclk = enable_hsdiv = true;
1594 1627
1595 if (dsi->vdds_dsi_reg == NULL) { 1628 r = dsi_regulator_init(dsidev);
1596 struct regulator *vdds_dsi; 1629 if (r)
1597 1630 return r;
1598 vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
1599
1600 /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
1601 if (IS_ERR(vdds_dsi))
1602 vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO");
1603
1604 if (IS_ERR(vdds_dsi)) {
1605 DSSERR("can't get VDDS_DSI regulator\n");
1606 return PTR_ERR(vdds_dsi);
1607 }
1608
1609 dsi->vdds_dsi_reg = vdds_dsi;
1610 }
1611 1631
1612 dsi_enable_pll_clock(dsidev, 1); 1632 dsi_enable_pll_clock(dsidev, 1);
1613 /* 1633 /*
@@ -4122,7 +4142,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
4122 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4142 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4123 struct omap_overlay_manager *mgr = dsi->output.manager; 4143 struct omap_overlay_manager *mgr = dsi->output.manager;
4124 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 4144 int bpp = dsi_get_pixel_size(dsi->pix_fmt);
4125 struct omap_dss_output *out = &dsi->output; 4145 struct omap_dss_device *out = &dsi->output;
4126 u8 data_type; 4146 u8 data_type;
4127 u16 word_count; 4147 u16 word_count;
4128 int r; 4148 int r;
@@ -4581,12 +4601,6 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4581 4601
4582 mutex_lock(&dsi->lock); 4602 mutex_lock(&dsi->lock);
4583 4603
4584 r = omap_dss_start_device(dssdev);
4585 if (r) {
4586 DSSERR("failed to start device\n");
4587 goto err_start_dev;
4588 }
4589
4590 r = dsi_runtime_get(dsidev); 4604 r = dsi_runtime_get(dsidev);
4591 if (r) 4605 if (r)
4592 goto err_get_dsi; 4606 goto err_get_dsi;
@@ -4607,8 +4621,6 @@ err_init_dsi:
4607 dsi_enable_pll_clock(dsidev, 0); 4621 dsi_enable_pll_clock(dsidev, 0);
4608 dsi_runtime_put(dsidev); 4622 dsi_runtime_put(dsidev);
4609err_get_dsi: 4623err_get_dsi:
4610 omap_dss_stop_device(dssdev);
4611err_start_dev:
4612 mutex_unlock(&dsi->lock); 4624 mutex_unlock(&dsi->lock);
4613 DSSDBG("dsi_display_enable FAILED\n"); 4625 DSSDBG("dsi_display_enable FAILED\n");
4614 return r; 4626 return r;
@@ -4637,8 +4649,6 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
4637 dsi_runtime_put(dsidev); 4649 dsi_runtime_put(dsidev);
4638 dsi_enable_pll_clock(dsidev, 0); 4650 dsi_enable_pll_clock(dsidev, 0);
4639 4651
4640 omap_dss_stop_device(dssdev);
4641
4642 mutex_unlock(&dsi->lock); 4652 mutex_unlock(&dsi->lock);
4643} 4653}
4644EXPORT_SYMBOL(omapdss_dsi_display_disable); 4654EXPORT_SYMBOL(omapdss_dsi_display_disable);
@@ -5225,34 +5235,6 @@ static enum omap_channel dsi_get_channel(int module_id)
5225 } 5235 }
5226} 5236}
5227 5237
5228static int dsi_init_display(struct omap_dss_device *dssdev)
5229{
5230 struct platform_device *dsidev =
5231 dsi_get_dsidev_from_id(dssdev->phy.dsi.module);
5232 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5233
5234 DSSDBG("DSI init\n");
5235
5236 if (dsi->vdds_dsi_reg == NULL) {
5237 struct regulator *vdds_dsi;
5238
5239 vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
5240
5241 /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
5242 if (IS_ERR(vdds_dsi))
5243 vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO");
5244
5245 if (IS_ERR(vdds_dsi)) {
5246 DSSERR("can't get VDDS_DSI regulator\n");
5247 return PTR_ERR(vdds_dsi);
5248 }
5249
5250 dsi->vdds_dsi_reg = vdds_dsi;
5251 }
5252
5253 return 0;
5254}
5255
5256int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel) 5238int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
5257{ 5239{
5258 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 5240 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -5410,19 +5392,16 @@ static int dsi_probe_pdata(struct platform_device *dsidev)
5410 if (!plat_dssdev) 5392 if (!plat_dssdev)
5411 return 0; 5393 return 0;
5412 5394
5395 r = dsi_regulator_init(dsidev);
5396 if (r)
5397 return r;
5398
5413 dssdev = dss_alloc_and_init_device(&dsidev->dev); 5399 dssdev = dss_alloc_and_init_device(&dsidev->dev);
5414 if (!dssdev) 5400 if (!dssdev)
5415 return -ENOMEM; 5401 return -ENOMEM;
5416 5402
5417 dss_copy_device_pdata(dssdev, plat_dssdev); 5403 dss_copy_device_pdata(dssdev, plat_dssdev);
5418 5404
5419 r = dsi_init_display(dssdev);
5420 if (r) {
5421 DSSERR("device %s init failed: %d\n", dssdev->name, r);
5422 dss_put_device(dssdev);
5423 return r;
5424 }
5425
5426 r = omapdss_output_set_device(&dsi->output, dssdev); 5405 r = omapdss_output_set_device(&dsi->output, dssdev);
5427 if (r) { 5406 if (r) {
5428 DSSERR("failed to connect output to new device: %s\n", 5407 DSSERR("failed to connect output to new device: %s\n",
@@ -5442,28 +5421,113 @@ static int dsi_probe_pdata(struct platform_device *dsidev)
5442 return 0; 5421 return 0;
5443} 5422}
5444 5423
5424static int dsi_connect(struct omap_dss_device *dssdev,
5425 struct omap_dss_device *dst)
5426{
5427 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
5428 struct omap_overlay_manager *mgr;
5429 int r;
5430
5431 r = dsi_regulator_init(dsidev);
5432 if (r)
5433 return r;
5434
5435 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
5436 if (!mgr)
5437 return -ENODEV;
5438
5439 r = dss_mgr_connect(mgr, dssdev);
5440 if (r)
5441 return r;
5442
5443 r = omapdss_output_set_device(dssdev, dst);
5444 if (r) {
5445 DSSERR("failed to connect output to new device: %s\n",
5446 dssdev->name);
5447 dss_mgr_disconnect(mgr, dssdev);
5448 return r;
5449 }
5450
5451 return 0;
5452}
5453
5454static void dsi_disconnect(struct omap_dss_device *dssdev,
5455 struct omap_dss_device *dst)
5456{
5457 WARN_ON(dst != dssdev->device);
5458
5459 if (dst != dssdev->device)
5460 return;
5461
5462 omapdss_output_unset_device(dssdev);
5463
5464 if (dssdev->manager)
5465 dss_mgr_disconnect(dssdev->manager, dssdev);
5466}
5467
5468static const struct omapdss_dsi_ops dsi_ops = {
5469 .connect = dsi_connect,
5470 .disconnect = dsi_disconnect,
5471
5472 .bus_lock = dsi_bus_lock,
5473 .bus_unlock = dsi_bus_unlock,
5474
5475 .enable = omapdss_dsi_display_enable,
5476 .disable = omapdss_dsi_display_disable,
5477
5478 .enable_hs = omapdss_dsi_vc_enable_hs,
5479
5480 .configure_pins = omapdss_dsi_configure_pins,
5481 .set_config = omapdss_dsi_set_config,
5482
5483 .enable_video_output = dsi_enable_video_output,
5484 .disable_video_output = dsi_disable_video_output,
5485
5486 .update = omap_dsi_update,
5487
5488 .enable_te = omapdss_dsi_enable_te,
5489
5490 .request_vc = omap_dsi_request_vc,
5491 .set_vc_id = omap_dsi_set_vc_id,
5492 .release_vc = omap_dsi_release_vc,
5493
5494 .dcs_write = dsi_vc_dcs_write,
5495 .dcs_write_nosync = dsi_vc_dcs_write_nosync,
5496 .dcs_read = dsi_vc_dcs_read,
5497
5498 .gen_write = dsi_vc_generic_write,
5499 .gen_write_nosync = dsi_vc_generic_write_nosync,
5500 .gen_read = dsi_vc_generic_read,
5501
5502 .bta_sync = dsi_vc_send_bta_sync,
5503
5504 .set_max_rx_packet_size = dsi_vc_set_max_rx_packet_size,
5505};
5506
5445static void dsi_init_output(struct platform_device *dsidev) 5507static void dsi_init_output(struct platform_device *dsidev)
5446{ 5508{
5447 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5509 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5448 struct omap_dss_output *out = &dsi->output; 5510 struct omap_dss_device *out = &dsi->output;
5449 5511
5450 out->pdev = dsidev; 5512 out->dev = &dsidev->dev;
5451 out->id = dsi->module_id == 0 ? 5513 out->id = dsi->module_id == 0 ?
5452 OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; 5514 OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
5453 5515
5454 out->type = OMAP_DISPLAY_TYPE_DSI; 5516 out->output_type = OMAP_DISPLAY_TYPE_DSI;
5455 out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1"; 5517 out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1";
5456 out->dispc_channel = dsi_get_channel(dsi->module_id); 5518 out->dispc_channel = dsi_get_channel(dsi->module_id);
5519 out->ops.dsi = &dsi_ops;
5520 out->owner = THIS_MODULE;
5457 5521
5458 dss_register_output(out); 5522 omapdss_register_output(out);
5459} 5523}
5460 5524
5461static void dsi_uninit_output(struct platform_device *dsidev) 5525static void dsi_uninit_output(struct platform_device *dsidev)
5462{ 5526{
5463 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5527 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5464 struct omap_dss_output *out = &dsi->output; 5528 struct omap_dss_device *out = &dsi->output;
5465 5529
5466 dss_unregister_output(out); 5530 omapdss_unregister_output(out);
5467} 5531}
5468 5532
5469/* DSI1 HW IP initialisation */ 5533/* DSI1 HW IP initialisation */
@@ -5563,12 +5627,10 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
5563 5627
5564 dsi_init_output(dsidev); 5628 dsi_init_output(dsidev);
5565 5629
5566 r = dsi_probe_pdata(dsidev); 5630 if (dsidev->dev.platform_data) {
5567 if (r) { 5631 r = dsi_probe_pdata(dsidev);
5568 dsi_runtime_put(dsidev); 5632 if (r)
5569 dsi_uninit_output(dsidev); 5633 goto err_probe;
5570 pm_runtime_disable(&dsidev->dev);
5571 return r;
5572 } 5634 }
5573 5635
5574 dsi_runtime_put(dsidev); 5636 dsi_runtime_put(dsidev);
@@ -5586,6 +5648,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
5586#endif 5648#endif
5587 return 0; 5649 return 0;
5588 5650
5651err_probe:
5652 dsi_runtime_put(dsidev);
5653 dsi_uninit_output(dsidev);
5589err_runtime_get: 5654err_runtime_get:
5590 pm_runtime_disable(&dsidev->dev); 5655 pm_runtime_disable(&dsidev->dev);
5591 return r; 5656 return r;
@@ -5603,14 +5668,9 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
5603 5668
5604 pm_runtime_disable(&dsidev->dev); 5669 pm_runtime_disable(&dsidev->dev);
5605 5670
5606 if (dsi->vdds_dsi_reg != NULL) { 5671 if (dsi->vdds_dsi_reg != NULL && dsi->vdds_dsi_enabled) {
5607 if (dsi->vdds_dsi_enabled) { 5672 regulator_disable(dsi->vdds_dsi_reg);
5608 regulator_disable(dsi->vdds_dsi_reg); 5673 dsi->vdds_dsi_enabled = false;
5609 dsi->vdds_dsi_enabled = false;
5610 }
5611
5612 regulator_put(dsi->vdds_dsi_reg);
5613 dsi->vdds_dsi_reg = NULL;
5614 } 5674 }
5615 5675
5616 return 0; 5676 return 0;
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 94f66f9f10a3..bd01608e67e2 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -157,7 +157,8 @@ static void dss_restore_context(void)
157 157
158int dss_get_ctx_loss_count(void) 158int dss_get_ctx_loss_count(void)
159{ 159{
160 struct omap_dss_board_info *board_data = dss.pdev->dev.platform_data; 160 struct platform_device *core_pdev = dss_get_core_pdev();
161 struct omap_dss_board_info *board_data = core_pdev->dev.platform_data;
161 int cnt; 162 int cnt;
162 163
163 if (!board_data->get_context_loss_count) 164 if (!board_data->get_context_loss_count)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 84758936429d..50a2362ef8f8 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -179,23 +179,19 @@ void dss_put_device(struct omap_dss_device *dssdev);
179void dss_copy_device_pdata(struct omap_dss_device *dst, 179void dss_copy_device_pdata(struct omap_dss_device *dst,
180 const struct omap_dss_device *src); 180 const struct omap_dss_device *src);
181 181
182/* output */
183void dss_register_output(struct omap_dss_output *out);
184void dss_unregister_output(struct omap_dss_output *out);
185
186/* display */ 182/* display */
187int dss_suspend_all_devices(void); 183int dss_suspend_all_devices(void);
188int dss_resume_all_devices(void); 184int dss_resume_all_devices(void);
189void dss_disable_all_devices(void); 185void dss_disable_all_devices(void);
190 186
191int display_init_sysfs(struct platform_device *pdev, 187int display_init_sysfs(struct platform_device *pdev);
192 struct omap_dss_device *dssdev); 188void display_uninit_sysfs(struct platform_device *pdev);
193void display_uninit_sysfs(struct platform_device *pdev,
194 struct omap_dss_device *dssdev);
195 189
196/* manager */ 190/* manager */
197int dss_init_overlay_managers(struct platform_device *pdev); 191int dss_init_overlay_managers(void);
198void dss_uninit_overlay_managers(struct platform_device *pdev); 192void dss_uninit_overlay_managers(void);
193int dss_init_overlay_managers_sysfs(struct platform_device *pdev);
194void dss_uninit_overlay_managers_sysfs(struct platform_device *pdev);
199int dss_mgr_simple_check(struct omap_overlay_manager *mgr, 195int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
200 const struct omap_overlay_manager_info *info); 196 const struct omap_overlay_manager_info *info);
201int dss_mgr_check_timings(struct omap_overlay_manager *mgr, 197int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
@@ -426,6 +422,7 @@ void dispc_mgr_set_clock_div(enum omap_channel channel,
426 const struct dispc_clock_info *cinfo); 422 const struct dispc_clock_info *cinfo);
427int dispc_mgr_get_clock_div(enum omap_channel channel, 423int dispc_mgr_get_clock_div(enum omap_channel channel,
428 struct dispc_clock_info *cinfo); 424 struct dispc_clock_info *cinfo);
425void dispc_set_tv_pclk(unsigned long pclk);
429 426
430u32 dispc_wb_get_framedone_irq(void); 427u32 dispc_wb_get_framedone_irq(void);
431bool dispc_wb_go_busy(void); 428bool dispc_wb_go_busy(void);
@@ -437,17 +434,8 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
437 bool mem_to_mem, const struct omap_video_timings *timings); 434 bool mem_to_mem, const struct omap_video_timings *timings);
438 435
439/* VENC */ 436/* VENC */
440#ifdef CONFIG_OMAP2_DSS_VENC
441int venc_init_platform_driver(void) __init; 437int venc_init_platform_driver(void) __init;
442void venc_uninit_platform_driver(void) __exit; 438void venc_uninit_platform_driver(void) __exit;
443unsigned long venc_get_pixel_clock(void);
444#else
445static inline unsigned long venc_get_pixel_clock(void)
446{
447 WARN("%s: VENC not compiled in, returning pclk as 0\n", __func__);
448 return 0;
449}
450#endif
451int omapdss_venc_display_enable(struct omap_dss_device *dssdev); 439int omapdss_venc_display_enable(struct omap_dss_device *dssdev);
452void omapdss_venc_display_disable(struct omap_dss_device *dssdev); 440void omapdss_venc_display_disable(struct omap_dss_device *dssdev);
453void omapdss_venc_set_timings(struct omap_dss_device *dssdev, 441void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
@@ -464,17 +452,8 @@ int venc_panel_init(void);
464void venc_panel_exit(void); 452void venc_panel_exit(void);
465 453
466/* HDMI */ 454/* HDMI */
467#ifdef CONFIG_OMAP4_DSS_HDMI
468int hdmi_init_platform_driver(void) __init; 455int hdmi_init_platform_driver(void) __init;
469void hdmi_uninit_platform_driver(void) __exit; 456void hdmi_uninit_platform_driver(void) __exit;
470unsigned long hdmi_get_pixel_clock(void);
471#else
472static inline unsigned long hdmi_get_pixel_clock(void)
473{
474 WARN("%s: HDMI not compiled in, returning pclk as 0\n", __func__);
475 return 0;
476}
477#endif
478int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); 457int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
479void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); 458void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
480int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev); 459int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 77dbe0cfb34c..b9cfebb378a2 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -797,7 +797,6 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
797 .phy_enable = ti_hdmi_4xxx_phy_enable, 797 .phy_enable = ti_hdmi_4xxx_phy_enable,
798 .phy_disable = ti_hdmi_4xxx_phy_disable, 798 .phy_disable = ti_hdmi_4xxx_phy_disable,
799 .read_edid = ti_hdmi_4xxx_read_edid, 799 .read_edid = ti_hdmi_4xxx_read_edid,
800 .detect = ti_hdmi_4xxx_detect,
801 .pll_enable = ti_hdmi_4xxx_pll_enable, 800 .pll_enable = ti_hdmi_4xxx_pll_enable,
802 .pll_disable = ti_hdmi_4xxx_pll_disable, 801 .pll_disable = ti_hdmi_4xxx_pll_disable,
803 .video_enable = ti_hdmi_4xxx_wp_video_start, 802 .video_enable = ti_hdmi_4xxx_wp_video_start,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index a109934c0478..44a885b92825 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -70,7 +70,9 @@ static struct {
70 int ls_oe_gpio; 70 int ls_oe_gpio;
71 int hpd_gpio; 71 int hpd_gpio;
72 72
73 struct omap_dss_output output; 73 bool core_enabled;
74
75 struct omap_dss_device output;
74} hdmi; 76} hdmi;
75 77
76/* 78/*
@@ -328,6 +330,29 @@ static void hdmi_runtime_put(void)
328 WARN_ON(r < 0 && r != -ENOSYS); 330 WARN_ON(r < 0 && r != -ENOSYS);
329} 331}
330 332
333static int hdmi_init_regulator(void)
334{
335 struct regulator *reg;
336
337 if (hdmi.vdda_hdmi_dac_reg != NULL)
338 return 0;
339
340 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
341
342 /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */
343 if (IS_ERR(reg))
344 reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
345
346 if (IS_ERR(reg)) {
347 DSSERR("can't get VDDA_HDMI_DAC regulator\n");
348 return PTR_ERR(reg);
349 }
350
351 hdmi.vdda_hdmi_dac_reg = reg;
352
353 return 0;
354}
355
331static int hdmi_init_display(struct omap_dss_device *dssdev) 356static int hdmi_init_display(struct omap_dss_device *dssdev)
332{ 357{
333 int r; 358 int r;
@@ -342,22 +367,9 @@ static int hdmi_init_display(struct omap_dss_device *dssdev)
342 367
343 dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version()); 368 dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
344 369
345 if (hdmi.vdda_hdmi_dac_reg == NULL) { 370 r = hdmi_init_regulator();
346 struct regulator *reg; 371 if (r)
347 372 return r;
348 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
349
350 /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */
351 if (IS_ERR(reg))
352 reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
353
354 if (IS_ERR(reg)) {
355 DSSERR("can't get VDDA_HDMI_DAC regulator\n");
356 return PTR_ERR(reg);
357 }
358
359 hdmi.vdda_hdmi_dac_reg = reg;
360 }
361 373
362 r = gpio_request_array(gpios, ARRAY_SIZE(gpios)); 374 r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
363 if (r) 375 if (r)
@@ -455,12 +467,6 @@ end: return cm;
455 467
456} 468}
457 469
458unsigned long hdmi_get_pixel_clock(void)
459{
460 /* HDMI Pixel Clock in Mhz */
461 return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
462}
463
464static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, 470static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
465 struct hdmi_pll_info *pi) 471 struct hdmi_pll_info *pi)
466{ 472{
@@ -511,8 +517,10 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
511{ 517{
512 int r; 518 int r;
513 519
514 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1); 520 if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
515 gpio_set_value(hdmi.ls_oe_gpio, 1); 521 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
522 if (gpio_is_valid(hdmi.ls_oe_gpio))
523 gpio_set_value(hdmi.ls_oe_gpio, 1);
516 524
517 /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */ 525 /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
518 udelay(300); 526 udelay(300);
@@ -528,29 +536,37 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
528 /* Make selection of HDMI in DSS */ 536 /* Make selection of HDMI in DSS */
529 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); 537 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
530 538
539 hdmi.core_enabled = true;
540
531 return 0; 541 return 0;
532 542
533err_runtime_get: 543err_runtime_get:
534 regulator_disable(hdmi.vdda_hdmi_dac_reg); 544 regulator_disable(hdmi.vdda_hdmi_dac_reg);
535err_vdac_enable: 545err_vdac_enable:
536 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); 546 if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
537 gpio_set_value(hdmi.ls_oe_gpio, 0); 547 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
548 if (gpio_is_valid(hdmi.ls_oe_gpio))
549 gpio_set_value(hdmi.ls_oe_gpio, 0);
538 return r; 550 return r;
539} 551}
540 552
541static void hdmi_power_off_core(struct omap_dss_device *dssdev) 553static void hdmi_power_off_core(struct omap_dss_device *dssdev)
542{ 554{
555 hdmi.core_enabled = false;
556
543 hdmi_runtime_put(); 557 hdmi_runtime_put();
544 regulator_disable(hdmi.vdda_hdmi_dac_reg); 558 regulator_disable(hdmi.vdda_hdmi_dac_reg);
545 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); 559 if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
546 gpio_set_value(hdmi.ls_oe_gpio, 0); 560 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
561 if (gpio_is_valid(hdmi.ls_oe_gpio))
562 gpio_set_value(hdmi.ls_oe_gpio, 0);
547} 563}
548 564
549static int hdmi_power_on_full(struct omap_dss_device *dssdev) 565static int hdmi_power_on_full(struct omap_dss_device *dssdev)
550{ 566{
551 int r; 567 int r;
552 struct omap_video_timings *p; 568 struct omap_video_timings *p;
553 struct omap_overlay_manager *mgr = dssdev->output->manager; 569 struct omap_overlay_manager *mgr = hdmi.output.manager;
554 unsigned long phy; 570 unsigned long phy;
555 571
556 r = hdmi_power_on_core(dssdev); 572 r = hdmi_power_on_core(dssdev);
@@ -613,7 +629,7 @@ err_pll_enable:
613 629
614static void hdmi_power_off_full(struct omap_dss_device *dssdev) 630static void hdmi_power_off_full(struct omap_dss_device *dssdev)
615{ 631{
616 struct omap_overlay_manager *mgr = dssdev->output->manager; 632 struct omap_overlay_manager *mgr = hdmi.output.manager;
617 633
618 dss_mgr_disable(mgr); 634 dss_mgr_disable(mgr);
619 635
@@ -653,9 +669,23 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
653 if (t != NULL) 669 if (t != NULL)
654 hdmi.ip_data.cfg = *t; 670 hdmi.ip_data.cfg = *t;
655 671
672 dispc_set_tv_pclk(t->timings.pixel_clock * 1000);
673
656 mutex_unlock(&hdmi.lock); 674 mutex_unlock(&hdmi.lock);
657} 675}
658 676
677static void omapdss_hdmi_display_get_timings(struct omap_dss_device *dssdev,
678 struct omap_video_timings *timings)
679{
680 const struct hdmi_config *cfg;
681
682 cfg = hdmi_get_timings();
683 if (cfg == NULL)
684 cfg = &vesa_timings[0];
685
686 memcpy(timings, &cfg->timings, sizeof(cfg->timings));
687}
688
659static void hdmi_dump_regs(struct seq_file *s) 689static void hdmi_dump_regs(struct seq_file *s)
660{ 690{
661 mutex_lock(&hdmi.lock); 691 mutex_lock(&hdmi.lock);
@@ -700,7 +730,7 @@ bool omapdss_hdmi_detect(void)
700 r = hdmi_runtime_get(); 730 r = hdmi_runtime_get();
701 BUG_ON(r); 731 BUG_ON(r);
702 732
703 r = hdmi.ip_data.ops->detect(&hdmi.ip_data); 733 r = gpio_get_value(hdmi.hpd_gpio);
704 734
705 hdmi_runtime_put(); 735 hdmi_runtime_put();
706 mutex_unlock(&hdmi.lock); 736 mutex_unlock(&hdmi.lock);
@@ -710,7 +740,7 @@ bool omapdss_hdmi_detect(void)
710 740
711int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) 741int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
712{ 742{
713 struct omap_dss_output *out = dssdev->output; 743 struct omap_dss_device *out = &hdmi.output;
714 int r = 0; 744 int r = 0;
715 745
716 DSSDBG("ENTER hdmi_display_enable\n"); 746 DSSDBG("ENTER hdmi_display_enable\n");
@@ -723,25 +753,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
723 goto err0; 753 goto err0;
724 } 754 }
725 755
726 hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
727
728 r = omap_dss_start_device(dssdev);
729 if (r) {
730 DSSERR("failed to start device\n");
731 goto err0;
732 }
733
734 r = hdmi_power_on_full(dssdev); 756 r = hdmi_power_on_full(dssdev);
735 if (r) { 757 if (r) {
736 DSSERR("failed to power on device\n"); 758 DSSERR("failed to power on device\n");
737 goto err1; 759 goto err0;
738 } 760 }
739 761
740 mutex_unlock(&hdmi.lock); 762 mutex_unlock(&hdmi.lock);
741 return 0; 763 return 0;
742 764
743err1:
744 omap_dss_stop_device(dssdev);
745err0: 765err0:
746 mutex_unlock(&hdmi.lock); 766 mutex_unlock(&hdmi.lock);
747 return r; 767 return r;
@@ -755,8 +775,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
755 775
756 hdmi_power_off_full(dssdev); 776 hdmi_power_off_full(dssdev);
757 777
758 omap_dss_stop_device(dssdev);
759
760 mutex_unlock(&hdmi.lock); 778 mutex_unlock(&hdmi.lock);
761} 779}
762 780
@@ -768,8 +786,6 @@ int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev)
768 786
769 mutex_lock(&hdmi.lock); 787 mutex_lock(&hdmi.lock);
770 788
771 hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
772
773 r = hdmi_power_on_core(dssdev); 789 r = hdmi_power_on_core(dssdev);
774 if (r) { 790 if (r) {
775 DSSERR("failed to power on device\n"); 791 DSSERR("failed to power on device\n");
@@ -1033,24 +1049,219 @@ static int hdmi_probe_pdata(struct platform_device *pdev)
1033 return 0; 1049 return 0;
1034} 1050}
1035 1051
1052static int hdmi_connect(struct omap_dss_device *dssdev,
1053 struct omap_dss_device *dst)
1054{
1055 struct omap_overlay_manager *mgr;
1056 int r;
1057
1058 dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
1059
1060 r = hdmi_init_regulator();
1061 if (r)
1062 return r;
1063
1064 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
1065 if (!mgr)
1066 return -ENODEV;
1067
1068 r = dss_mgr_connect(mgr, dssdev);
1069 if (r)
1070 return r;
1071
1072 r = omapdss_output_set_device(dssdev, dst);
1073 if (r) {
1074 DSSERR("failed to connect output to new device: %s\n",
1075 dst->name);
1076 dss_mgr_disconnect(mgr, dssdev);
1077 return r;
1078 }
1079
1080 return 0;
1081}
1082
1083static void hdmi_disconnect(struct omap_dss_device *dssdev,
1084 struct omap_dss_device *dst)
1085{
1086 WARN_ON(dst != dssdev->device);
1087
1088 if (dst != dssdev->device)
1089 return;
1090
1091 omapdss_output_unset_device(dssdev);
1092
1093 if (dssdev->manager)
1094 dss_mgr_disconnect(dssdev->manager, dssdev);
1095}
1096
1097static int hdmi_read_edid(struct omap_dss_device *dssdev,
1098 u8 *edid, int len)
1099{
1100 bool need_enable;
1101 int r;
1102
1103 need_enable = hdmi.core_enabled == false;
1104
1105 if (need_enable) {
1106 r = omapdss_hdmi_core_enable(dssdev);
1107 if (r)
1108 return r;
1109 }
1110
1111 r = omapdss_hdmi_read_edid(edid, len);
1112
1113 if (need_enable)
1114 omapdss_hdmi_core_disable(dssdev);
1115
1116 return r;
1117}
1118
1119#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
1120static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev)
1121{
1122 int r;
1123
1124 mutex_lock(&hdmi.lock);
1125
1126 if (!hdmi_mode_has_audio()) {
1127 r = -EPERM;
1128 goto err;
1129 }
1130
1131 r = hdmi_audio_enable();
1132 if (r)
1133 goto err;
1134
1135 mutex_unlock(&hdmi.lock);
1136 return 0;
1137
1138err:
1139 mutex_unlock(&hdmi.lock);
1140 return r;
1141}
1142
1143static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev)
1144{
1145 hdmi_audio_disable();
1146}
1147
1148static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev)
1149{
1150 return hdmi_audio_start();
1151}
1152
1153static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev)
1154{
1155 hdmi_audio_stop();
1156}
1157
1158static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev)
1159{
1160 bool r;
1161
1162 mutex_lock(&hdmi.lock);
1163
1164 r = hdmi_mode_has_audio();
1165
1166 mutex_unlock(&hdmi.lock);
1167 return r;
1168}
1169
1170static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev,
1171 struct omap_dss_audio *audio)
1172{
1173 int r;
1174
1175 mutex_lock(&hdmi.lock);
1176
1177 if (!hdmi_mode_has_audio()) {
1178 r = -EPERM;
1179 goto err;
1180 }
1181
1182 r = hdmi_audio_config(audio);
1183 if (r)
1184 goto err;
1185
1186 mutex_unlock(&hdmi.lock);
1187 return 0;
1188
1189err:
1190 mutex_unlock(&hdmi.lock);
1191 return r;
1192}
1193#else
1194static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev)
1195{
1196 return -EPERM;
1197}
1198
1199static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev)
1200{
1201}
1202
1203static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev)
1204{
1205 return -EPERM;
1206}
1207
1208static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev)
1209{
1210}
1211
1212static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev)
1213{
1214 return false;
1215}
1216
1217static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev,
1218 struct omap_dss_audio *audio)
1219{
1220 return -EPERM;
1221}
1222#endif
1223
1224static const struct omapdss_hdmi_ops hdmi_ops = {
1225 .connect = hdmi_connect,
1226 .disconnect = hdmi_disconnect,
1227
1228 .enable = omapdss_hdmi_display_enable,
1229 .disable = omapdss_hdmi_display_disable,
1230
1231 .check_timings = omapdss_hdmi_display_check_timing,
1232 .set_timings = omapdss_hdmi_display_set_timing,
1233 .get_timings = omapdss_hdmi_display_get_timings,
1234
1235 .read_edid = hdmi_read_edid,
1236
1237 .audio_enable = omapdss_hdmi_audio_enable,
1238 .audio_disable = omapdss_hdmi_audio_disable,
1239 .audio_start = omapdss_hdmi_audio_start,
1240 .audio_stop = omapdss_hdmi_audio_stop,
1241 .audio_supported = omapdss_hdmi_audio_supported,
1242 .audio_config = omapdss_hdmi_audio_config,
1243};
1244
1036static void hdmi_init_output(struct platform_device *pdev) 1245static void hdmi_init_output(struct platform_device *pdev)
1037{ 1246{
1038 struct omap_dss_output *out = &hdmi.output; 1247 struct omap_dss_device *out = &hdmi.output;
1039 1248
1040 out->pdev = pdev; 1249 out->dev = &pdev->dev;
1041 out->id = OMAP_DSS_OUTPUT_HDMI; 1250 out->id = OMAP_DSS_OUTPUT_HDMI;
1042 out->type = OMAP_DISPLAY_TYPE_HDMI; 1251 out->output_type = OMAP_DISPLAY_TYPE_HDMI;
1043 out->name = "hdmi.0"; 1252 out->name = "hdmi.0";
1044 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; 1253 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
1254 out->ops.hdmi = &hdmi_ops;
1255 out->owner = THIS_MODULE;
1045 1256
1046 dss_register_output(out); 1257 omapdss_register_output(out);
1047} 1258}
1048 1259
1049static void __exit hdmi_uninit_output(struct platform_device *pdev) 1260static void __exit hdmi_uninit_output(struct platform_device *pdev)
1050{ 1261{
1051 struct omap_dss_output *out = &hdmi.output; 1262 struct omap_dss_device *out = &hdmi.output;
1052 1263
1053 dss_unregister_output(out); 1264 omapdss_unregister_output(out);
1054} 1265}
1055 1266
1056/* HDMI HW IP initialisation */ 1267/* HDMI HW IP initialisation */
@@ -1071,6 +1282,12 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
1071 if (IS_ERR(hdmi.ip_data.base_wp)) 1282 if (IS_ERR(hdmi.ip_data.base_wp))
1072 return PTR_ERR(hdmi.ip_data.base_wp); 1283 return PTR_ERR(hdmi.ip_data.base_wp);
1073 1284
1285 hdmi.ip_data.irq = platform_get_irq(pdev, 0);
1286 if (hdmi.ip_data.irq < 0) {
1287 DSSERR("platform_get_irq failed\n");
1288 return -ENODEV;
1289 }
1290
1074 r = hdmi_get_clocks(pdev); 1291 r = hdmi_get_clocks(pdev);
1075 if (r) { 1292 if (r) {
1076 DSSERR("can't get clocks\n"); 1293 DSSERR("can't get clocks\n");
@@ -1084,6 +1301,10 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
1084 hdmi.ip_data.pll_offset = HDMI_PLLCTRL; 1301 hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
1085 hdmi.ip_data.phy_offset = HDMI_PHY; 1302 hdmi.ip_data.phy_offset = HDMI_PHY;
1086 1303
1304 hdmi.ct_cp_hpd_gpio = -1;
1305 hdmi.ls_oe_gpio = -1;
1306 hdmi.hpd_gpio = -1;
1307
1087 hdmi_init_output(pdev); 1308 hdmi_init_output(pdev);
1088 1309
1089 r = hdmi_panel_init(); 1310 r = hdmi_panel_init();
@@ -1094,15 +1315,19 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
1094 1315
1095 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 1316 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
1096 1317
1097 r = hdmi_probe_pdata(pdev); 1318 if (pdev->dev.platform_data) {
1098 if (r) { 1319 r = hdmi_probe_pdata(pdev);
1099 hdmi_panel_exit(); 1320 if (r)
1100 hdmi_uninit_output(pdev); 1321 goto err_probe;
1101 pm_runtime_disable(&pdev->dev);
1102 return r;
1103 } 1322 }
1104 1323
1105 return 0; 1324 return 0;
1325
1326err_probe:
1327 hdmi_panel_exit();
1328 hdmi_uninit_output(pdev);
1329 pm_runtime_disable(&pdev->dev);
1330 return r;
1106} 1331}
1107 1332
1108static int __exit hdmi_remove_child(struct device *dev, void *data) 1333static int __exit hdmi_remove_child(struct device *dev, void *data)
diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c
index 9a2fb59b6f89..de7e7b5b1b7c 100644
--- a/drivers/video/omap2/dss/manager-sysfs.c
+++ b/drivers/video/omap2/dss/manager-sysfs.c
@@ -50,6 +50,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
50 int r = 0; 50 int r = 0;
51 size_t len = size; 51 size_t len = size;
52 struct omap_dss_device *dssdev = NULL; 52 struct omap_dss_device *dssdev = NULL;
53 struct omap_dss_device *old_dssdev;
53 54
54 int match(struct omap_dss_device *dssdev, void *data) 55 int match(struct omap_dss_device *dssdev, void *data)
55 { 56 {
@@ -66,32 +67,44 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
66 if (len > 0 && dssdev == NULL) 67 if (len > 0 && dssdev == NULL)
67 return -EINVAL; 68 return -EINVAL;
68 69
69 if (dssdev) 70 if (dssdev) {
70 DSSDBG("display %s found\n", dssdev->name); 71 DSSDBG("display %s found\n", dssdev->name);
71 72
72 if (mgr->output) { 73 if (omapdss_device_is_connected(dssdev)) {
73 r = mgr->unset_output(mgr); 74 DSSERR("new display is already connected\n");
74 if (r) { 75 r = -EINVAL;
75 DSSERR("failed to unset current output\n"); 76 goto put_device;
77 }
78
79 if (omapdss_device_is_enabled(dssdev)) {
80 DSSERR("new display is not disabled\n");
81 r = -EINVAL;
76 goto put_device; 82 goto put_device;
77 } 83 }
78 } 84 }
79 85
80 if (dssdev) { 86 old_dssdev = mgr->get_device(mgr);
81 struct omap_dss_output *out = dssdev->output; 87 if (old_dssdev) {
82 88 if (omapdss_device_is_enabled(old_dssdev)) {
83 /* 89 DSSERR("old display is not disabled\n");
84 * a registered device should have an output connected to it 90 r = -EINVAL;
85 * already
86 */
87 if (!out) {
88 DSSERR("device has no output connected to it\n");
89 goto put_device; 91 goto put_device;
90 } 92 }
91 93
92 r = mgr->set_output(mgr, out); 94 old_dssdev->driver->disconnect(old_dssdev);
95 }
96
97 if (dssdev) {
98 r = dssdev->driver->connect(dssdev);
93 if (r) { 99 if (r) {
94 DSSERR("failed to set manager output\n"); 100 DSSERR("failed to connect new device\n");
101 goto put_device;
102 }
103
104 old_dssdev = mgr->get_device(mgr);
105 if (old_dssdev != dssdev) {
106 DSSERR("failed to connect device to this manager\n");
107 dssdev->driver->disconnect(dssdev);
95 goto put_device; 108 goto put_device;
96 } 109 }
97 110
@@ -509,4 +522,6 @@ void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr)
509{ 522{
510 kobject_del(&mgr->kobj); 523 kobject_del(&mgr->kobj);
511 kobject_put(&mgr->kobj); 524 kobject_put(&mgr->kobj);
525
526 memset(&mgr->kobj, 0, sizeof(mgr->kobj));
512} 527}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 2551eaa14c42..1aac9b4191a9 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -36,9 +36,9 @@
36static int num_managers; 36static int num_managers;
37static struct omap_overlay_manager *managers; 37static struct omap_overlay_manager *managers;
38 38
39int dss_init_overlay_managers(struct platform_device *pdev) 39int dss_init_overlay_managers(void)
40{ 40{
41 int i, r; 41 int i;
42 42
43 num_managers = dss_feat_get_num_mgrs(); 43 num_managers = dss_feat_get_num_mgrs();
44 44
@@ -76,6 +76,17 @@ int dss_init_overlay_managers(struct platform_device *pdev)
76 dss_feat_get_supported_outputs(mgr->id); 76 dss_feat_get_supported_outputs(mgr->id);
77 77
78 INIT_LIST_HEAD(&mgr->overlays); 78 INIT_LIST_HEAD(&mgr->overlays);
79 }
80
81 return 0;
82}
83
84int dss_init_overlay_managers_sysfs(struct platform_device *pdev)
85{
86 int i, r;
87
88 for (i = 0; i < num_managers; ++i) {
89 struct omap_overlay_manager *mgr = &managers[i];
79 90
80 r = dss_manager_kobj_init(mgr, pdev); 91 r = dss_manager_kobj_init(mgr, pdev);
81 if (r) 92 if (r)
@@ -85,18 +96,22 @@ int dss_init_overlay_managers(struct platform_device *pdev)
85 return 0; 96 return 0;
86} 97}
87 98
88void dss_uninit_overlay_managers(struct platform_device *pdev) 99void dss_uninit_overlay_managers(void)
100{
101 kfree(managers);
102 managers = NULL;
103 num_managers = 0;
104}
105
106void dss_uninit_overlay_managers_sysfs(struct platform_device *pdev)
89{ 107{
90 int i; 108 int i;
91 109
92 for (i = 0; i < num_managers; ++i) { 110 for (i = 0; i < num_managers; ++i) {
93 struct omap_overlay_manager *mgr = &managers[i]; 111 struct omap_overlay_manager *mgr = &managers[i];
112
94 dss_manager_kobj_uninit(mgr); 113 dss_manager_kobj_uninit(mgr);
95 } 114 }
96
97 kfree(managers);
98 managers = NULL;
99 num_managers = 0;
100} 115}
101 116
102int omap_dss_get_num_overlay_managers(void) 117int omap_dss_get_num_overlay_managers(void)
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 5214df63e0a9..3f5c0a758b32 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -27,7 +27,7 @@
27static LIST_HEAD(output_list); 27static LIST_HEAD(output_list);
28static DEFINE_MUTEX(output_lock); 28static DEFINE_MUTEX(output_lock);
29 29
30int omapdss_output_set_device(struct omap_dss_output *out, 30int omapdss_output_set_device(struct omap_dss_device *out,
31 struct omap_dss_device *dssdev) 31 struct omap_dss_device *dssdev)
32{ 32{
33 int r; 33 int r;
@@ -41,7 +41,7 @@ int omapdss_output_set_device(struct omap_dss_output *out,
41 goto err; 41 goto err;
42 } 42 }
43 43
44 if (out->type != dssdev->type) { 44 if (out->output_type != dssdev->type) {
45 DSSERR("output type and display type don't match\n"); 45 DSSERR("output type and display type don't match\n");
46 r = -EINVAL; 46 r = -EINVAL;
47 goto err; 47 goto err;
@@ -60,7 +60,7 @@ err:
60} 60}
61EXPORT_SYMBOL(omapdss_output_set_device); 61EXPORT_SYMBOL(omapdss_output_set_device);
62 62
63int omapdss_output_unset_device(struct omap_dss_output *out) 63int omapdss_output_unset_device(struct omap_dss_device *out)
64{ 64{
65 int r; 65 int r;
66 66
@@ -92,19 +92,22 @@ err:
92} 92}
93EXPORT_SYMBOL(omapdss_output_unset_device); 93EXPORT_SYMBOL(omapdss_output_unset_device);
94 94
95void dss_register_output(struct omap_dss_output *out) 95int omapdss_register_output(struct omap_dss_device *out)
96{ 96{
97 list_add_tail(&out->list, &output_list); 97 list_add_tail(&out->list, &output_list);
98 return 0;
98} 99}
100EXPORT_SYMBOL(omapdss_register_output);
99 101
100void dss_unregister_output(struct omap_dss_output *out) 102void omapdss_unregister_output(struct omap_dss_device *out)
101{ 103{
102 list_del(&out->list); 104 list_del(&out->list);
103} 105}
106EXPORT_SYMBOL(omapdss_unregister_output);
104 107
105struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id) 108struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id)
106{ 109{
107 struct omap_dss_output *out; 110 struct omap_dss_device *out;
108 111
109 list_for_each_entry(out, &output_list, list) { 112 list_for_each_entry(out, &output_list, list) {
110 if (out->id == id) 113 if (out->id == id)
@@ -115,6 +118,62 @@ struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
115} 118}
116EXPORT_SYMBOL(omap_dss_get_output); 119EXPORT_SYMBOL(omap_dss_get_output);
117 120
121struct omap_dss_device *omap_dss_find_output(const char *name)
122{
123 struct omap_dss_device *out;
124
125 list_for_each_entry(out, &output_list, list) {
126 if (strcmp(out->name, name) == 0)
127 return omap_dss_get_device(out);
128 }
129
130 return NULL;
131}
132EXPORT_SYMBOL(omap_dss_find_output);
133
134struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node)
135{
136 struct omap_dss_device *out;
137
138 list_for_each_entry(out, &output_list, list) {
139 if (out->dev->of_node == node)
140 return omap_dss_get_device(out);
141 }
142
143 return NULL;
144}
145EXPORT_SYMBOL(omap_dss_find_output_by_node);
146
147struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev)
148{
149 while (dssdev->output)
150 dssdev = dssdev->output;
151
152 if (dssdev->id != 0)
153 return omap_dss_get_device(dssdev);
154
155 return NULL;
156}
157EXPORT_SYMBOL(omapdss_find_output_from_display);
158
159struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev)
160{
161 struct omap_dss_device *out;
162 struct omap_overlay_manager *mgr;
163
164 out = omapdss_find_output_from_display(dssdev);
165
166 if (out == NULL)
167 return NULL;
168
169 mgr = out->manager;
170
171 omap_dss_put_device(out);
172
173 return mgr;
174}
175EXPORT_SYMBOL(omapdss_find_mgr_from_display);
176
118static const struct dss_mgr_ops *dss_mgr_ops; 177static const struct dss_mgr_ops *dss_mgr_ops;
119 178
120int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops) 179int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops)
@@ -134,6 +193,20 @@ void dss_uninstall_mgr_ops(void)
134} 193}
135EXPORT_SYMBOL(dss_uninstall_mgr_ops); 194EXPORT_SYMBOL(dss_uninstall_mgr_ops);
136 195
196int dss_mgr_connect(struct omap_overlay_manager *mgr,
197 struct omap_dss_device *dst)
198{
199 return dss_mgr_ops->connect(mgr, dst);
200}
201EXPORT_SYMBOL(dss_mgr_connect);
202
203void dss_mgr_disconnect(struct omap_overlay_manager *mgr,
204 struct omap_dss_device *dst)
205{
206 dss_mgr_ops->disconnect(mgr, dst);
207}
208EXPORT_SYMBOL(dss_mgr_disconnect);
209
137void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 210void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
138 const struct omap_video_timings *timings) 211 const struct omap_video_timings *timings)
139{ 212{
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 1a17dd1447dc..fdfe6e6f25df 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -117,7 +117,7 @@ static struct {
117 int data_lines; 117 int data_lines;
118 struct rfbi_timings intf_timings; 118 struct rfbi_timings intf_timings;
119 119
120 struct omap_dss_output output; 120 struct omap_dss_device output;
121} rfbi; 121} rfbi;
122 122
123static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) 123static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
@@ -312,7 +312,7 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
312{ 312{
313 u32 l; 313 u32 l;
314 int r; 314 int r;
315 struct omap_overlay_manager *mgr = dssdev->output->manager; 315 struct omap_overlay_manager *mgr = rfbi.output.manager;
316 u16 width = rfbi.timings.x_res; 316 u16 width = rfbi.timings.x_res;
317 u16 height = rfbi.timings.y_res; 317 u16 height = rfbi.timings.y_res;
318 318
@@ -852,7 +852,7 @@ static void rfbi_dump_regs(struct seq_file *s)
852 852
853static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) 853static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
854{ 854{
855 struct omap_overlay_manager *mgr = dssdev->output->manager; 855 struct omap_overlay_manager *mgr = rfbi.output.manager;
856 struct dss_lcd_mgr_config mgr_config; 856 struct dss_lcd_mgr_config mgr_config;
857 857
858 mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI; 858 mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
@@ -890,7 +890,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
890 890
891int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) 891int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
892{ 892{
893 struct omap_dss_output *out = dssdev->output; 893 struct omap_dss_device *out = &rfbi.output;
894 int r; 894 int r;
895 895
896 if (out == NULL || out->manager == NULL) { 896 if (out == NULL || out->manager == NULL) {
@@ -902,12 +902,6 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
902 if (r) 902 if (r)
903 return r; 903 return r;
904 904
905 r = omap_dss_start_device(dssdev);
906 if (r) {
907 DSSERR("failed to start device\n");
908 goto err0;
909 }
910
911 r = dss_mgr_register_framedone_handler(out->manager, 905 r = dss_mgr_register_framedone_handler(out->manager,
912 framedone_callback, NULL); 906 framedone_callback, NULL);
913 if (r) { 907 if (r) {
@@ -924,8 +918,6 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
924 918
925 return 0; 919 return 0;
926err1: 920err1:
927 omap_dss_stop_device(dssdev);
928err0:
929 rfbi_runtime_put(); 921 rfbi_runtime_put();
930 return r; 922 return r;
931} 923}
@@ -933,11 +925,10 @@ EXPORT_SYMBOL(omapdss_rfbi_display_enable);
933 925
934void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) 926void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
935{ 927{
936 struct omap_dss_output *out = dssdev->output; 928 struct omap_dss_device *out = &rfbi.output;
937 929
938 dss_mgr_unregister_framedone_handler(out->manager, 930 dss_mgr_unregister_framedone_handler(out->manager,
939 framedone_callback, NULL); 931 framedone_callback, NULL);
940 omap_dss_stop_device(dssdev);
941 932
942 rfbi_runtime_put(); 933 rfbi_runtime_put();
943} 934}
@@ -1022,22 +1013,23 @@ static int rfbi_probe_pdata(struct platform_device *rfbidev)
1022 1013
1023static void rfbi_init_output(struct platform_device *pdev) 1014static void rfbi_init_output(struct platform_device *pdev)
1024{ 1015{
1025 struct omap_dss_output *out = &rfbi.output; 1016 struct omap_dss_device *out = &rfbi.output;
1026 1017
1027 out->pdev = pdev; 1018 out->dev = &pdev->dev;
1028 out->id = OMAP_DSS_OUTPUT_DBI; 1019 out->id = OMAP_DSS_OUTPUT_DBI;
1029 out->type = OMAP_DISPLAY_TYPE_DBI; 1020 out->output_type = OMAP_DISPLAY_TYPE_DBI;
1030 out->name = "rfbi.0"; 1021 out->name = "rfbi.0";
1031 out->dispc_channel = OMAP_DSS_CHANNEL_LCD; 1022 out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
1023 out->owner = THIS_MODULE;
1032 1024
1033 dss_register_output(out); 1025 omapdss_register_output(out);
1034} 1026}
1035 1027
1036static void __exit rfbi_uninit_output(struct platform_device *pdev) 1028static void __exit rfbi_uninit_output(struct platform_device *pdev)
1037{ 1029{
1038 struct omap_dss_output *out = &rfbi.output; 1030 struct omap_dss_device *out = &rfbi.output;
1039 1031
1040 dss_unregister_output(out); 1032 omapdss_unregister_output(out);
1041} 1033}
1042 1034
1043/* RFBI HW IP initialisation */ 1035/* RFBI HW IP initialisation */
@@ -1093,15 +1085,16 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
1093 1085
1094 rfbi_init_output(pdev); 1086 rfbi_init_output(pdev);
1095 1087
1096 r = rfbi_probe_pdata(pdev); 1088 if (pdev->dev.platform_data) {
1097 if (r) { 1089 r = rfbi_probe_pdata(pdev);
1098 rfbi_uninit_output(pdev); 1090 if (r)
1099 pm_runtime_disable(&pdev->dev); 1091 goto err_probe;
1100 return r;
1101 } 1092 }
1102 1093
1103 return 0; 1094 return 0;
1104 1095
1096err_probe:
1097 rfbi_uninit_output(pdev);
1105err_runtime_get: 1098err_runtime_get:
1106 pm_runtime_disable(&pdev->dev); 1099 pm_runtime_disable(&pdev->dev);
1107 return r; 1100 return r;
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 0bcd30272f69..856af2e89760 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -31,6 +31,8 @@
31#include "dss.h" 31#include "dss.h"
32 32
33static struct { 33static struct {
34 struct platform_device *pdev;
35
34 bool update_enabled; 36 bool update_enabled;
35 struct regulator *vdds_sdi_reg; 37 struct regulator *vdds_sdi_reg;
36 38
@@ -38,7 +40,7 @@ static struct {
38 struct omap_video_timings timings; 40 struct omap_video_timings timings;
39 int datapairs; 41 int datapairs;
40 42
41 struct omap_dss_output output; 43 struct omap_dss_device output;
42} sdi; 44} sdi;
43 45
44struct sdi_clk_calc_ctx { 46struct sdi_clk_calc_ctx {
@@ -109,7 +111,7 @@ static int sdi_calc_clock_div(unsigned long pclk,
109 111
110static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) 112static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
111{ 113{
112 struct omap_overlay_manager *mgr = dssdev->output->manager; 114 struct omap_overlay_manager *mgr = sdi.output.manager;
113 115
114 sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; 116 sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
115 117
@@ -124,7 +126,7 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
124 126
125int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) 127int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
126{ 128{
127 struct omap_dss_output *out = dssdev->output; 129 struct omap_dss_device *out = &sdi.output;
128 struct omap_video_timings *t = &sdi.timings; 130 struct omap_video_timings *t = &sdi.timings;
129 struct dss_clock_info dss_cinfo; 131 struct dss_clock_info dss_cinfo;
130 struct dispc_clock_info dispc_cinfo; 132 struct dispc_clock_info dispc_cinfo;
@@ -136,12 +138,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
136 return -ENODEV; 138 return -ENODEV;
137 } 139 }
138 140
139 r = omap_dss_start_device(dssdev);
140 if (r) {
141 DSSERR("failed to start device\n");
142 goto err_start_dev;
143 }
144
145 r = regulator_enable(sdi.vdds_sdi_reg); 141 r = regulator_enable(sdi.vdds_sdi_reg);
146 if (r) 142 if (r)
147 goto err_reg_enable; 143 goto err_reg_enable;
@@ -213,15 +209,13 @@ err_calc_clock_div:
213err_get_dispc: 209err_get_dispc:
214 regulator_disable(sdi.vdds_sdi_reg); 210 regulator_disable(sdi.vdds_sdi_reg);
215err_reg_enable: 211err_reg_enable:
216 omap_dss_stop_device(dssdev);
217err_start_dev:
218 return r; 212 return r;
219} 213}
220EXPORT_SYMBOL(omapdss_sdi_display_enable); 214EXPORT_SYMBOL(omapdss_sdi_display_enable);
221 215
222void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) 216void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
223{ 217{
224 struct omap_overlay_manager *mgr = dssdev->output->manager; 218 struct omap_overlay_manager *mgr = sdi.output.manager;
225 219
226 dss_mgr_disable(mgr); 220 dss_mgr_disable(mgr);
227 221
@@ -230,8 +224,6 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
230 dispc_runtime_put(); 224 dispc_runtime_put();
231 225
232 regulator_disable(sdi.vdds_sdi_reg); 226 regulator_disable(sdi.vdds_sdi_reg);
233
234 omap_dss_stop_device(dssdev);
235} 227}
236EXPORT_SYMBOL(omapdss_sdi_display_disable); 228EXPORT_SYMBOL(omapdss_sdi_display_disable);
237 229
@@ -242,29 +234,51 @@ void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
242} 234}
243EXPORT_SYMBOL(omapdss_sdi_set_timings); 235EXPORT_SYMBOL(omapdss_sdi_set_timings);
244 236
237static void sdi_get_timings(struct omap_dss_device *dssdev,
238 struct omap_video_timings *timings)
239{
240 *timings = sdi.timings;
241}
242
243static int sdi_check_timings(struct omap_dss_device *dssdev,
244 struct omap_video_timings *timings)
245{
246 struct omap_overlay_manager *mgr = sdi.output.manager;
247
248 if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))
249 return -EINVAL;
250
251 if (timings->pixel_clock == 0)
252 return -EINVAL;
253
254 return 0;
255}
256
245void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs) 257void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs)
246{ 258{
247 sdi.datapairs = datapairs; 259 sdi.datapairs = datapairs;
248} 260}
249EXPORT_SYMBOL(omapdss_sdi_set_datapairs); 261EXPORT_SYMBOL(omapdss_sdi_set_datapairs);
250 262
251static int sdi_init_display(struct omap_dss_device *dssdev) 263static int sdi_init_regulator(void)
252{ 264{
253 DSSDBG("SDI init\n"); 265 struct regulator *vdds_sdi;
254 266
255 if (sdi.vdds_sdi_reg == NULL) { 267 if (sdi.vdds_sdi_reg)
256 struct regulator *vdds_sdi; 268 return 0;
257 269
258 vdds_sdi = dss_get_vdds_sdi(); 270 vdds_sdi = dss_get_vdds_sdi();
259 271
272 if (IS_ERR(vdds_sdi)) {
273 vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi");
260 if (IS_ERR(vdds_sdi)) { 274 if (IS_ERR(vdds_sdi)) {
261 DSSERR("can't get VDDS_SDI regulator\n"); 275 DSSERR("can't get VDDS_SDI regulator\n");
262 return PTR_ERR(vdds_sdi); 276 return PTR_ERR(vdds_sdi);
263 } 277 }
264
265 sdi.vdds_sdi_reg = vdds_sdi;
266 } 278 }
267 279
280 sdi.vdds_sdi_reg = vdds_sdi;
281
268 return 0; 282 return 0;
269} 283}
270 284
@@ -313,7 +327,7 @@ static int sdi_probe_pdata(struct platform_device *sdidev)
313 327
314 dss_copy_device_pdata(dssdev, plat_dssdev); 328 dss_copy_device_pdata(dssdev, plat_dssdev);
315 329
316 r = sdi_init_display(dssdev); 330 r = sdi_init_regulator();
317 if (r) { 331 if (r) {
318 DSSERR("device %s init failed: %d\n", dssdev->name, r); 332 DSSERR("device %s init failed: %d\n", dssdev->name, r);
319 dss_put_device(dssdev); 333 dss_put_device(dssdev);
@@ -339,39 +353,104 @@ static int sdi_probe_pdata(struct platform_device *sdidev)
339 return 0; 353 return 0;
340} 354}
341 355
356static int sdi_connect(struct omap_dss_device *dssdev,
357 struct omap_dss_device *dst)
358{
359 struct omap_overlay_manager *mgr;
360 int r;
361
362 r = sdi_init_regulator();
363 if (r)
364 return r;
365
366 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
367 if (!mgr)
368 return -ENODEV;
369
370 r = dss_mgr_connect(mgr, dssdev);
371 if (r)
372 return r;
373
374 r = omapdss_output_set_device(dssdev, dst);
375 if (r) {
376 DSSERR("failed to connect output to new device: %s\n",
377 dst->name);
378 dss_mgr_disconnect(mgr, dssdev);
379 return r;
380 }
381
382 return 0;
383}
384
385static void sdi_disconnect(struct omap_dss_device *dssdev,
386 struct omap_dss_device *dst)
387{
388 WARN_ON(dst != dssdev->device);
389
390 if (dst != dssdev->device)
391 return;
392
393 omapdss_output_unset_device(dssdev);
394
395 if (dssdev->manager)
396 dss_mgr_disconnect(dssdev->manager, dssdev);
397}
398
399static const struct omapdss_sdi_ops sdi_ops = {
400 .connect = sdi_connect,
401 .disconnect = sdi_disconnect,
402
403 .enable = omapdss_sdi_display_enable,
404 .disable = omapdss_sdi_display_disable,
405
406 .check_timings = sdi_check_timings,
407 .set_timings = omapdss_sdi_set_timings,
408 .get_timings = sdi_get_timings,
409
410 .set_datapairs = omapdss_sdi_set_datapairs,
411};
412
342static void sdi_init_output(struct platform_device *pdev) 413static void sdi_init_output(struct platform_device *pdev)
343{ 414{
344 struct omap_dss_output *out = &sdi.output; 415 struct omap_dss_device *out = &sdi.output;
345 416
346 out->pdev = pdev; 417 out->dev = &pdev->dev;
347 out->id = OMAP_DSS_OUTPUT_SDI; 418 out->id = OMAP_DSS_OUTPUT_SDI;
348 out->type = OMAP_DISPLAY_TYPE_SDI; 419 out->output_type = OMAP_DISPLAY_TYPE_SDI;
349 out->name = "sdi.0"; 420 out->name = "sdi.0";
350 out->dispc_channel = OMAP_DSS_CHANNEL_LCD; 421 out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
422 out->ops.sdi = &sdi_ops;
423 out->owner = THIS_MODULE;
351 424
352 dss_register_output(out); 425 omapdss_register_output(out);
353} 426}
354 427
355static void __exit sdi_uninit_output(struct platform_device *pdev) 428static void __exit sdi_uninit_output(struct platform_device *pdev)
356{ 429{
357 struct omap_dss_output *out = &sdi.output; 430 struct omap_dss_device *out = &sdi.output;
358 431
359 dss_unregister_output(out); 432 omapdss_unregister_output(out);
360} 433}
361 434
362static int omap_sdi_probe(struct platform_device *pdev) 435static int omap_sdi_probe(struct platform_device *pdev)
363{ 436{
364 int r; 437 int r;
365 438
439 sdi.pdev = pdev;
440
366 sdi_init_output(pdev); 441 sdi_init_output(pdev);
367 442
368 r = sdi_probe_pdata(pdev); 443 if (pdev->dev.platform_data) {
369 if (r) { 444 r = sdi_probe_pdata(pdev);
370 sdi_uninit_output(pdev); 445 if (r)
371 return r; 446 goto err_probe;
372 } 447 }
373 448
374 return 0; 449 return 0;
450
451err_probe:
452 sdi_uninit_output(pdev);
453 return r;
375} 454}
376 455
377static int __exit omap_sdi_remove(struct platform_device *pdev) 456static int __exit omap_sdi_remove(struct platform_device *pdev)
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index 216aa704f9d7..45215f44617c 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -73,8 +73,6 @@ struct ti_hdmi_ip_ops {
73 73
74 int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len); 74 int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len);
75 75
76 bool (*detect)(struct hdmi_ip_data *ip_data);
77
78 int (*pll_enable)(struct hdmi_ip_data *ip_data); 76 int (*pll_enable)(struct hdmi_ip_data *ip_data);
79 77
80 void (*pll_disable)(struct hdmi_ip_data *ip_data); 78 void (*pll_disable)(struct hdmi_ip_data *ip_data);
@@ -155,19 +153,18 @@ struct hdmi_ip_data {
155 unsigned long core_av_offset; 153 unsigned long core_av_offset;
156 unsigned long pll_offset; 154 unsigned long pll_offset;
157 unsigned long phy_offset; 155 unsigned long phy_offset;
156 int irq;
158 const struct ti_hdmi_ip_ops *ops; 157 const struct ti_hdmi_ip_ops *ops;
159 struct hdmi_config cfg; 158 struct hdmi_config cfg;
160 struct hdmi_pll_info pll_data; 159 struct hdmi_pll_info pll_data;
161 struct hdmi_core_infoframe_avi avi_cfg; 160 struct hdmi_core_infoframe_avi avi_cfg;
162 161
163 /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */ 162 /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */
164 int hpd_gpio;
165 struct mutex lock; 163 struct mutex lock;
166}; 164};
167int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); 165int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
168void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); 166void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
169int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); 167int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
170bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data);
171int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data); 168int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data);
172void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data); 169void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data);
173int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data); 170int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index e18b222ed739..e242ed85cb07 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -28,7 +28,6 @@
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/string.h> 29#include <linux/string.h>
30#include <linux/seq_file.h> 30#include <linux/seq_file.h>
31#include <linux/gpio.h>
32#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 31#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
33#include <sound/asound.h> 32#include <sound/asound.h>
34#include <sound/asoundef.h> 33#include <sound/asoundef.h>
@@ -38,6 +37,9 @@
38#include "dss.h" 37#include "dss.h"
39#include "dss_features.h" 38#include "dss_features.h"
40 39
40#define HDMI_IRQ_LINK_CONNECT (1 << 25)
41#define HDMI_IRQ_LINK_DISCONNECT (1 << 26)
42
41static inline void hdmi_write_reg(void __iomem *base_addr, 43static inline void hdmi_write_reg(void __iomem *base_addr,
42 const u16 idx, u32 val) 44 const u16 idx, u32 val)
43{ 45{
@@ -233,37 +235,39 @@ void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data)
233 hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF); 235 hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
234} 236}
235 237
236static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data) 238static irqreturn_t hdmi_irq_handler(int irq, void *data)
237{ 239{
238 bool hpd; 240 struct hdmi_ip_data *ip_data = data;
239 int r; 241 void __iomem *wp_base = hdmi_wp_base(ip_data);
240 242 u32 irqstatus;
241 mutex_lock(&ip_data->lock); 243
242 244 irqstatus = hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS);
243 hpd = gpio_get_value(ip_data->hpd_gpio); 245 hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS, irqstatus);
246 /* flush posted write */
247 hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS);
248
249 if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
250 irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
251 /*
252 * If we get both connect and disconnect interrupts at the same
253 * time, turn off the PHY, clear interrupts, and restart, which
254 * raises connect interrupt if a cable is connected, or nothing
255 * if cable is not connected.
256 */
257 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
244 258
245 if (hpd) 259 hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS,
246 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON); 260 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
247 else 261 /* flush posted write */
248 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); 262 hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS);
249 263
250 if (r) { 264 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
251 DSSERR("Failed to %s PHY TX power\n", 265 } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
252 hpd ? "enable" : "disable"); 266 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
253 goto err; 267 } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
268 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
254 } 269 }
255 270
256err:
257 mutex_unlock(&ip_data->lock);
258 return r;
259}
260
261static irqreturn_t hpd_irq_handler(int irq, void *data)
262{
263 struct hdmi_ip_data *ip_data = data;
264
265 hdmi_check_hpd_state(ip_data);
266
267 return IRQ_HANDLED; 271 return IRQ_HANDLED;
268} 272}
269 273
@@ -272,6 +276,12 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
272 u16 r = 0; 276 u16 r = 0;
273 void __iomem *phy_base = hdmi_phy_base(ip_data); 277 void __iomem *phy_base = hdmi_phy_base(ip_data);
274 278
279 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_CLR,
280 0xffffffff);
281
282 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQSTATUS,
283 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
284
275 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); 285 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
276 if (r) 286 if (r)
277 return r; 287 return r;
@@ -297,29 +307,23 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
297 /* Write to phy address 3 to change the polarity control */ 307 /* Write to phy address 3 to change the polarity control */
298 REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); 308 REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
299 309
300 r = request_threaded_irq(gpio_to_irq(ip_data->hpd_gpio), 310 r = request_threaded_irq(ip_data->irq, NULL, hdmi_irq_handler,
301 NULL, hpd_irq_handler, 311 IRQF_ONESHOT, "OMAP HDMI", ip_data);
302 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
303 IRQF_ONESHOT, "hpd", ip_data);
304 if (r) { 312 if (r) {
305 DSSERR("HPD IRQ request failed\n"); 313 DSSERR("HDMI IRQ request failed\n");
306 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); 314 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
307 return r; 315 return r;
308 } 316 }
309 317
310 r = hdmi_check_hpd_state(ip_data); 318 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_SET,
311 if (r) { 319 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
312 free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
313 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
314 return r;
315 }
316 320
317 return 0; 321 return 0;
318} 322}
319 323
320void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data) 324void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
321{ 325{
322 free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data); 326 free_irq(ip_data->irq, ip_data);
323 327
324 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); 328 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
325} 329}
@@ -476,11 +480,6 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
476 return l; 480 return l;
477} 481}
478 482
479bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data)
480{
481 return gpio_get_value(ip_data->hpd_gpio);
482}
483
484static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, 483static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
485 struct hdmi_core_infoframe_avi *avi_cfg, 484 struct hdmi_core_infoframe_avi *avi_cfg,
486 struct hdmi_core_packet_enable_repeat *repeat_cfg) 485 struct hdmi_core_packet_enable_repeat *repeat_cfg)
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
index 8366ae19e82e..6ef2f929a76d 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
@@ -33,6 +33,7 @@
33#define HDMI_WP_IRQSTATUS 0x28 33#define HDMI_WP_IRQSTATUS 0x28
34#define HDMI_WP_PWR_CTRL 0x40 34#define HDMI_WP_PWR_CTRL 0x40
35#define HDMI_WP_IRQENABLE_SET 0x2C 35#define HDMI_WP_IRQENABLE_SET 0x2C
36#define HDMI_WP_IRQENABLE_CLR 0x30
36#define HDMI_WP_VIDEO_CFG 0x50 37#define HDMI_WP_VIDEO_CFG 0x50
37#define HDMI_WP_VIDEO_SIZE 0x60 38#define HDMI_WP_VIDEO_SIZE 0x60
38#define HDMI_WP_VIDEO_TIMING_H 0x68 39#define HDMI_WP_VIDEO_TIMING_H 0x68
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 74fdb3ee209e..496a106fe823 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -304,7 +304,7 @@ static struct {
304 enum omap_dss_venc_type type; 304 enum omap_dss_venc_type type;
305 bool invert_polarity; 305 bool invert_polarity;
306 306
307 struct omap_dss_output output; 307 struct omap_dss_device output;
308} venc; 308} venc;
309 309
310static inline void venc_write_reg(int idx, u32 val) 310static inline void venc_write_reg(int idx, u32 val)
@@ -429,7 +429,7 @@ static const struct venc_config *venc_timings_to_config(
429 429
430static int venc_power_on(struct omap_dss_device *dssdev) 430static int venc_power_on(struct omap_dss_device *dssdev)
431{ 431{
432 struct omap_overlay_manager *mgr = dssdev->output->manager; 432 struct omap_overlay_manager *mgr = venc.output.manager;
433 u32 l; 433 u32 l;
434 int r; 434 int r;
435 435
@@ -480,7 +480,7 @@ err0:
480 480
481static void venc_power_off(struct omap_dss_device *dssdev) 481static void venc_power_off(struct omap_dss_device *dssdev)
482{ 482{
483 struct omap_overlay_manager *mgr = dssdev->output->manager; 483 struct omap_overlay_manager *mgr = venc.output.manager;
484 484
485 venc_write_reg(VENC_OUTPUT_CONTROL, 0); 485 venc_write_reg(VENC_OUTPUT_CONTROL, 0);
486 dss_set_dac_pwrdn_bgz(0); 486 dss_set_dac_pwrdn_bgz(0);
@@ -492,15 +492,9 @@ static void venc_power_off(struct omap_dss_device *dssdev)
492 venc_runtime_put(); 492 venc_runtime_put();
493} 493}
494 494
495unsigned long venc_get_pixel_clock(void)
496{
497 /* VENC Pixel Clock in Mhz */
498 return 13500000;
499}
500
501int omapdss_venc_display_enable(struct omap_dss_device *dssdev) 495int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
502{ 496{
503 struct omap_dss_output *out = dssdev->output; 497 struct omap_dss_device *out = &venc.output;
504 int r; 498 int r;
505 499
506 DSSDBG("venc_display_enable\n"); 500 DSSDBG("venc_display_enable\n");
@@ -513,23 +507,15 @@ int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
513 goto err0; 507 goto err0;
514 } 508 }
515 509
516 r = omap_dss_start_device(dssdev);
517 if (r) {
518 DSSERR("failed to start device\n");
519 goto err0;
520 }
521
522 r = venc_power_on(dssdev); 510 r = venc_power_on(dssdev);
523 if (r) 511 if (r)
524 goto err1; 512 goto err0;
525 513
526 venc.wss_data = 0; 514 venc.wss_data = 0;
527 515
528 mutex_unlock(&venc.venc_lock); 516 mutex_unlock(&venc.venc_lock);
529 517
530 return 0; 518 return 0;
531err1:
532 omap_dss_stop_device(dssdev);
533err0: 519err0:
534 mutex_unlock(&venc.venc_lock); 520 mutex_unlock(&venc.venc_lock);
535 return r; 521 return r;
@@ -543,8 +529,6 @@ void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
543 529
544 venc_power_off(dssdev); 530 venc_power_off(dssdev);
545 531
546 omap_dss_stop_device(dssdev);
547
548 mutex_unlock(&venc.venc_lock); 532 mutex_unlock(&venc.venc_lock);
549} 533}
550 534
@@ -561,6 +545,8 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
561 545
562 venc.timings = *timings; 546 venc.timings = *timings;
563 547
548 dispc_set_tv_pclk(13500000);
549
564 mutex_unlock(&venc.venc_lock); 550 mutex_unlock(&venc.venc_lock);
565} 551}
566 552
@@ -578,6 +564,16 @@ int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
578 return -EINVAL; 564 return -EINVAL;
579} 565}
580 566
567static void venc_get_timings(struct omap_dss_device *dssdev,
568 struct omap_video_timings *timings)
569{
570 mutex_lock(&venc.venc_lock);
571
572 *timings = venc.timings;
573
574 mutex_unlock(&venc.venc_lock);
575}
576
581u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev) 577u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
582{ 578{
583 /* Invert due to VENC_L21_WC_CTL:INV=1 */ 579 /* Invert due to VENC_L21_WC_CTL:INV=1 */
@@ -633,23 +629,22 @@ void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
633 mutex_unlock(&venc.venc_lock); 629 mutex_unlock(&venc.venc_lock);
634} 630}
635 631
636static int venc_init_display(struct omap_dss_device *dssdev) 632static int venc_init_regulator(void)
637{ 633{
638 DSSDBG("init_display\n"); 634 struct regulator *vdda_dac;
639
640 if (venc.vdda_dac_reg == NULL) {
641 struct regulator *vdda_dac;
642 635
643 vdda_dac = regulator_get(&venc.pdev->dev, "vdda_dac"); 636 if (venc.vdda_dac_reg != NULL)
637 return 0;
644 638
645 if (IS_ERR(vdda_dac)) { 639 vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda_dac");
646 DSSERR("can't get VDDA_DAC regulator\n");
647 return PTR_ERR(vdda_dac);
648 }
649 640
650 venc.vdda_dac_reg = vdda_dac; 641 if (IS_ERR(vdda_dac)) {
642 DSSERR("can't get VDDA_DAC regulator\n");
643 return PTR_ERR(vdda_dac);
651 } 644 }
652 645
646 venc.vdda_dac_reg = vdda_dac;
647
653 return 0; 648 return 0;
654} 649}
655 650
@@ -765,19 +760,16 @@ static int venc_probe_pdata(struct platform_device *vencdev)
765 if (!plat_dssdev) 760 if (!plat_dssdev)
766 return 0; 761 return 0;
767 762
763 r = venc_init_regulator();
764 if (r)
765 return r;
766
768 dssdev = dss_alloc_and_init_device(&vencdev->dev); 767 dssdev = dss_alloc_and_init_device(&vencdev->dev);
769 if (!dssdev) 768 if (!dssdev)
770 return -ENOMEM; 769 return -ENOMEM;
771 770
772 dss_copy_device_pdata(dssdev, plat_dssdev); 771 dss_copy_device_pdata(dssdev, plat_dssdev);
773 772
774 r = venc_init_display(dssdev);
775 if (r) {
776 DSSERR("device %s init failed: %d\n", dssdev->name, r);
777 dss_put_device(dssdev);
778 return r;
779 }
780
781 r = omapdss_output_set_device(&venc.output, dssdev); 773 r = omapdss_output_set_device(&venc.output, dssdev);
782 if (r) { 774 if (r) {
783 DSSERR("failed to connect output to new device: %s\n", 775 DSSERR("failed to connect output to new device: %s\n",
@@ -797,24 +789,87 @@ static int venc_probe_pdata(struct platform_device *vencdev)
797 return 0; 789 return 0;
798} 790}
799 791
792static int venc_connect(struct omap_dss_device *dssdev,
793 struct omap_dss_device *dst)
794{
795 struct omap_overlay_manager *mgr;
796 int r;
797
798 r = venc_init_regulator();
799 if (r)
800 return r;
801
802 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
803 if (!mgr)
804 return -ENODEV;
805
806 r = dss_mgr_connect(mgr, dssdev);
807 if (r)
808 return r;
809
810 r = omapdss_output_set_device(dssdev, dst);
811 if (r) {
812 DSSERR("failed to connect output to new device: %s\n",
813 dst->name);
814 dss_mgr_disconnect(mgr, dssdev);
815 return r;
816 }
817
818 return 0;
819}
820
821static void venc_disconnect(struct omap_dss_device *dssdev,
822 struct omap_dss_device *dst)
823{
824 WARN_ON(dst != dssdev->device);
825
826 if (dst != dssdev->device)
827 return;
828
829 omapdss_output_unset_device(dssdev);
830
831 if (dssdev->manager)
832 dss_mgr_disconnect(dssdev->manager, dssdev);
833}
834
835static const struct omapdss_atv_ops venc_ops = {
836 .connect = venc_connect,
837 .disconnect = venc_disconnect,
838
839 .enable = omapdss_venc_display_enable,
840 .disable = omapdss_venc_display_disable,
841
842 .check_timings = omapdss_venc_check_timings,
843 .set_timings = omapdss_venc_set_timings,
844 .get_timings = venc_get_timings,
845
846 .set_type = omapdss_venc_set_type,
847 .invert_vid_out_polarity = omapdss_venc_invert_vid_out_polarity,
848
849 .set_wss = omapdss_venc_set_wss,
850 .get_wss = omapdss_venc_get_wss,
851};
852
800static void venc_init_output(struct platform_device *pdev) 853static void venc_init_output(struct platform_device *pdev)
801{ 854{
802 struct omap_dss_output *out = &venc.output; 855 struct omap_dss_device *out = &venc.output;
803 856
804 out->pdev = pdev; 857 out->dev = &pdev->dev;
805 out->id = OMAP_DSS_OUTPUT_VENC; 858 out->id = OMAP_DSS_OUTPUT_VENC;
806 out->type = OMAP_DISPLAY_TYPE_VENC; 859 out->output_type = OMAP_DISPLAY_TYPE_VENC;
807 out->name = "venc.0"; 860 out->name = "venc.0";
808 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; 861 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
862 out->ops.atv = &venc_ops;
863 out->owner = THIS_MODULE;
809 864
810 dss_register_output(out); 865 omapdss_register_output(out);
811} 866}
812 867
813static void __exit venc_uninit_output(struct platform_device *pdev) 868static void __exit venc_uninit_output(struct platform_device *pdev)
814{ 869{
815 struct omap_dss_output *out = &venc.output; 870 struct omap_dss_device *out = &venc.output;
816 871
817 dss_unregister_output(out); 872 omapdss_unregister_output(out);
818} 873}
819 874
820/* VENC HW IP initialisation */ 875/* VENC HW IP initialisation */
@@ -866,16 +921,17 @@ static int omap_venchw_probe(struct platform_device *pdev)
866 921
867 venc_init_output(pdev); 922 venc_init_output(pdev);
868 923
869 r = venc_probe_pdata(pdev); 924 if (pdev->dev.platform_data) {
870 if (r) { 925 r = venc_probe_pdata(pdev);
871 venc_panel_exit(); 926 if (r)
872 venc_uninit_output(pdev); 927 goto err_probe;
873 pm_runtime_disable(&pdev->dev);
874 return r;
875 } 928 }
876 929
877 return 0; 930 return 0;
878 931
932err_probe:
933 venc_panel_exit();
934 venc_uninit_output(pdev);
879err_panel_init: 935err_panel_init:
880err_runtime_get: 936err_runtime_get:
881 pm_runtime_disable(&pdev->dev); 937 pm_runtime_disable(&pdev->dev);
@@ -886,11 +942,6 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
886{ 942{
887 dss_unregister_child_devices(&pdev->dev); 943 dss_unregister_child_devices(&pdev->dev);
888 944
889 if (venc.vdda_dac_reg != NULL) {
890 regulator_put(venc.vdda_dac_reg);
891 venc.vdda_dac_reg = NULL;
892 }
893
894 venc_panel_exit(); 945 venc_panel_exit();
895 946
896 venc_uninit_output(pdev); 947 venc_uninit_output(pdev);
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index 0d2b1a0834a0..f7d92c57bd73 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -107,19 +107,19 @@ static int venc_panel_probe(struct omap_dss_device *dssdev)
107 107
108 dssdev->panel.timings = default_timings; 108 dssdev->panel.timings = default_timings;
109 109
110 return device_create_file(&dssdev->dev, &dev_attr_output_type); 110 return device_create_file(dssdev->dev, &dev_attr_output_type);
111} 111}
112 112
113static void venc_panel_remove(struct omap_dss_device *dssdev) 113static void venc_panel_remove(struct omap_dss_device *dssdev)
114{ 114{
115 device_remove_file(&dssdev->dev, &dev_attr_output_type); 115 device_remove_file(dssdev->dev, &dev_attr_output_type);
116} 116}
117 117
118static int venc_panel_enable(struct omap_dss_device *dssdev) 118static int venc_panel_enable(struct omap_dss_device *dssdev)
119{ 119{
120 int r; 120 int r;
121 121
122 dev_dbg(&dssdev->dev, "venc_panel_enable\n"); 122 dev_dbg(dssdev->dev, "venc_panel_enable\n");
123 123
124 mutex_lock(&venc_panel.lock); 124 mutex_lock(&venc_panel.lock);
125 125
@@ -150,7 +150,7 @@ err:
150 150
151static void venc_panel_disable(struct omap_dss_device *dssdev) 151static void venc_panel_disable(struct omap_dss_device *dssdev)
152{ 152{
153 dev_dbg(&dssdev->dev, "venc_panel_disable\n"); 153 dev_dbg(dssdev->dev, "venc_panel_disable\n");
154 154
155 mutex_lock(&venc_panel.lock); 155 mutex_lock(&venc_panel.lock);
156 156
@@ -167,7 +167,7 @@ end:
167static void venc_panel_set_timings(struct omap_dss_device *dssdev, 167static void venc_panel_set_timings(struct omap_dss_device *dssdev,
168 struct omap_video_timings *timings) 168 struct omap_video_timings *timings)
169{ 169{
170 dev_dbg(&dssdev->dev, "venc_panel_set_timings\n"); 170 dev_dbg(dssdev->dev, "venc_panel_set_timings\n");
171 171
172 mutex_lock(&venc_panel.lock); 172 mutex_lock(&venc_panel.lock);
173 173
@@ -180,21 +180,21 @@ static void venc_panel_set_timings(struct omap_dss_device *dssdev,
180static int venc_panel_check_timings(struct omap_dss_device *dssdev, 180static int venc_panel_check_timings(struct omap_dss_device *dssdev,
181 struct omap_video_timings *timings) 181 struct omap_video_timings *timings)
182{ 182{
183 dev_dbg(&dssdev->dev, "venc_panel_check_timings\n"); 183 dev_dbg(dssdev->dev, "venc_panel_check_timings\n");
184 184
185 return omapdss_venc_check_timings(dssdev, timings); 185 return omapdss_venc_check_timings(dssdev, timings);
186} 186}
187 187
188static u32 venc_panel_get_wss(struct omap_dss_device *dssdev) 188static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
189{ 189{
190 dev_dbg(&dssdev->dev, "venc_panel_get_wss\n"); 190 dev_dbg(dssdev->dev, "venc_panel_get_wss\n");
191 191
192 return omapdss_venc_get_wss(dssdev); 192 return omapdss_venc_get_wss(dssdev);
193} 193}
194 194
195static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss) 195static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
196{ 196{
197 dev_dbg(&dssdev->dev, "venc_panel_set_wss\n"); 197 dev_dbg(dssdev->dev, "venc_panel_set_wss\n");
198 198
199 return omapdss_venc_set_wss(dssdev, wss); 199 return omapdss_venc_set_wss(dssdev, wss);
200} 200}
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index d30b45d72649..146b6f5428db 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -770,12 +770,17 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
770 770
771 case OMAPFB_WAITFORVSYNC: 771 case OMAPFB_WAITFORVSYNC:
772 DBG("ioctl WAITFORVSYNC\n"); 772 DBG("ioctl WAITFORVSYNC\n");
773 if (!display || !display->output || !display->output->manager) { 773
774 if (!display) {
774 r = -EINVAL; 775 r = -EINVAL;
775 break; 776 break;
776 } 777 }
777 778
778 mgr = display->output->manager; 779 mgr = omapdss_find_mgr_from_display(display);
780 if (!mgr) {
781 r = -EINVAL;
782 break;
783 }
779 784
780 r = mgr->wait_for_vsync(mgr); 785 r = mgr->wait_for_vsync(mgr);
781 break; 786 break;
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 856917b33616..27d6905683f3 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1853,6 +1853,8 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
1853 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) 1853 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
1854 dssdev->driver->disable(dssdev); 1854 dssdev->driver->disable(dssdev);
1855 1855
1856 dssdev->driver->disconnect(dssdev);
1857
1856 omap_dss_put_device(dssdev); 1858 omap_dss_put_device(dssdev);
1857 } 1859 }
1858 1860
@@ -2363,27 +2365,26 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev,
2363 int i, r; 2365 int i, r;
2364 struct omap_overlay_manager *mgr; 2366 struct omap_overlay_manager *mgr;
2365 2367
2366 if (!def_dssdev->output) { 2368 r = def_dssdev->driver->connect(def_dssdev);
2367 dev_err(fbdev->dev, "no output for the default display\n"); 2369 if (r) {
2368 return -EINVAL; 2370 dev_err(fbdev->dev, "failed to connect default display\n");
2371 return r;
2369 } 2372 }
2370 2373
2371 for (i = 0; i < fbdev->num_displays; ++i) { 2374 for (i = 0; i < fbdev->num_displays; ++i) {
2372 struct omap_dss_device *dssdev = fbdev->displays[i].dssdev; 2375 struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
2373 struct omap_dss_output *out = dssdev->output;
2374
2375 mgr = omap_dss_get_overlay_manager(out->dispc_channel);
2376 2376
2377 if (!mgr || !out) 2377 if (dssdev == def_dssdev)
2378 continue; 2378 continue;
2379 2379
2380 if (mgr->output) 2380 /*
2381 mgr->unset_output(mgr); 2381 * We don't care if the connect succeeds or not. We just want to
2382 2382 * connect as many displays as possible.
2383 mgr->set_output(mgr, out); 2383 */
2384 dssdev->driver->connect(dssdev);
2384 } 2385 }
2385 2386
2386 mgr = def_dssdev->output->manager; 2387 mgr = omapdss_find_mgr_from_display(def_dssdev);
2387 2388
2388 if (!mgr) { 2389 if (!mgr) {
2389 dev_err(fbdev->dev, "no ovl manager for the default display\n"); 2390 dev_err(fbdev->dev, "no ovl manager for the default display\n");
@@ -2502,7 +2503,7 @@ static int omapfb_probe(struct platform_device *pdev)
2502 2503
2503 if (def_display == NULL) { 2504 if (def_display == NULL) {
2504 dev_err(fbdev->dev, "failed to find default display\n"); 2505 dev_err(fbdev->dev, "failed to find default display\n");
2505 r = -EINVAL; 2506 r = -EPROBE_DEFER;
2506 goto cleanup; 2507 goto cleanup;
2507 } 2508 }
2508 2509
diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/pxa3xx-gcu.c
index 7cf0b13d061b..ad382b3396cd 100644
--- a/drivers/video/pxa3xx-gcu.c
+++ b/drivers/video/pxa3xx-gcu.c
@@ -710,7 +710,6 @@ err_misc_deregister:
710 misc_deregister(&priv->misc_dev); 710 misc_deregister(&priv->misc_dev);
711 711
712err_free_priv: 712err_free_priv:
713 platform_set_drvdata(dev, NULL);
714 free_buffers(dev, priv); 713 free_buffers(dev, priv);
715 kfree(priv); 714 kfree(priv);
716 return ret; 715 return ret;
@@ -728,7 +727,6 @@ static int pxa3xx_gcu_remove(struct platform_device *dev)
728 priv->shared, priv->shared_phys); 727 priv->shared, priv->shared_phys);
729 iounmap(priv->mmio_base); 728 iounmap(priv->mmio_base);
730 release_mem_region(r->start, resource_size(r)); 729 release_mem_region(r->start, resource_size(r));
731 platform_set_drvdata(dev, NULL);
732 clk_disable(priv->clk); 730 clk_disable(priv->clk);
733 free_buffers(dev, priv); 731 free_buffers(dev, priv);
734 kfree(priv); 732 kfree(priv);
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 580f80cc586f..eca2de45f7a6 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -2256,7 +2256,6 @@ failed_free_res:
2256 release_mem_region(r->start, resource_size(r)); 2256 release_mem_region(r->start, resource_size(r));
2257failed_fbi: 2257failed_fbi:
2258 clk_put(fbi->clk); 2258 clk_put(fbi->clk);
2259 platform_set_drvdata(dev, NULL);
2260 kfree(fbi); 2259 kfree(fbi);
2261failed: 2260failed:
2262 return ret; 2261 return ret;
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 76a0e7fbd692..21a32adbb8ea 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -1005,7 +1005,6 @@ release_regs:
1005release_mem: 1005release_mem:
1006 release_mem_region(res->start, size); 1006 release_mem_region(res->start, size);
1007dealloc_fb: 1007dealloc_fb:
1008 platform_set_drvdata(pdev, NULL);
1009 framebuffer_release(fbinfo); 1008 framebuffer_release(fbinfo);
1010 return ret; 1009 return ret;
1011} 1010}
@@ -1051,7 +1050,6 @@ static int s3c2410fb_remove(struct platform_device *pdev)
1051 1050
1052 release_mem_region(info->mem->start, resource_size(info->mem)); 1051 release_mem_region(info->mem->start, resource_size(info->mem));
1053 1052
1054 platform_set_drvdata(pdev, NULL);
1055 framebuffer_release(fbinfo); 1053 framebuffer_release(fbinfo);
1056 1054
1057 return 0; 1055 return 0;
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index f34c858642e8..de76da0c6429 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -1271,7 +1271,6 @@ static int sa1100fb_probe(struct platform_device *pdev)
1271 failed: 1271 failed:
1272 if (fbi) 1272 if (fbi)
1273 iounmap(fbi->base); 1273 iounmap(fbi->base);
1274 platform_set_drvdata(pdev, NULL);
1275 kfree(fbi); 1274 kfree(fbi);
1276 release_mem_region(res->start, resource_size(res)); 1275 release_mem_region(res->start, resource_size(res));
1277 return ret; 1276 return ret;
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c
index 5fbb0c7ab0c8..a8c6c43a4658 100644
--- a/drivers/video/sh7760fb.c
+++ b/drivers/video/sh7760fb.c
@@ -571,7 +571,6 @@ static int sh7760fb_remove(struct platform_device *dev)
571 iounmap(par->base); 571 iounmap(par->base);
572 release_mem_region(par->ioarea->start, resource_size(par->ioarea)); 572 release_mem_region(par->ioarea->start, resource_size(par->ioarea));
573 framebuffer_release(info); 573 framebuffer_release(info);
574 platform_set_drvdata(dev, NULL);
575 574
576 return 0; 575 return 0;
577} 576}
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 6cad53075e99..8f6e8ff620d4 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -567,7 +567,6 @@ static int sh_mipi_remove(struct platform_device *pdev)
567 iounmap(mipi->base); 567 iounmap(mipi->base);
568 if (res) 568 if (res)
569 release_mem_region(res->start, resource_size(res)); 569 release_mem_region(res->start, resource_size(res));
570 platform_set_drvdata(pdev, NULL);
571 kfree(mipi); 570 kfree(mipi);
572 571
573 return 0; 572 return 0;
diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c
index b2b33fc1ac3f..e188ada2ffd1 100644
--- a/drivers/video/smscufx.c
+++ b/drivers/video/smscufx.c
@@ -1622,7 +1622,7 @@ static int ufx_usb_probe(struct usb_interface *interface,
1622{ 1622{
1623 struct usb_device *usbdev; 1623 struct usb_device *usbdev;
1624 struct ufx_data *dev; 1624 struct ufx_data *dev;
1625 struct fb_info *info = 0; 1625 struct fb_info *info = NULL;
1626 int retval = -ENOMEM; 1626 int retval = -ENOMEM;
1627 u32 id_rev, fpga_rev; 1627 u32 id_rev, fpga_rev;
1628 1628
diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
index 9ef05d3ef68a..44967c8fef2b 100644
--- a/drivers/video/ssd1307fb.c
+++ b/drivers/video/ssd1307fb.c
@@ -16,24 +16,50 @@
16#include <linux/pwm.h> 16#include <linux/pwm.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18 18
19#define SSD1307FB_WIDTH 96
20#define SSD1307FB_HEIGHT 16
21
22#define SSD1307FB_DATA 0x40 19#define SSD1307FB_DATA 0x40
23#define SSD1307FB_COMMAND 0x80 20#define SSD1307FB_COMMAND 0x80
24 21
22#define SSD1307FB_SET_ADDRESS_MODE 0x20
23#define SSD1307FB_SET_ADDRESS_MODE_HORIZONTAL (0x00)
24#define SSD1307FB_SET_ADDRESS_MODE_VERTICAL (0x01)
25#define SSD1307FB_SET_ADDRESS_MODE_PAGE (0x02)
26#define SSD1307FB_SET_COL_RANGE 0x21
27#define SSD1307FB_SET_PAGE_RANGE 0x22
25#define SSD1307FB_CONTRAST 0x81 28#define SSD1307FB_CONTRAST 0x81
29#define SSD1307FB_CHARGE_PUMP 0x8d
26#define SSD1307FB_SEG_REMAP_ON 0xa1 30#define SSD1307FB_SEG_REMAP_ON 0xa1
27#define SSD1307FB_DISPLAY_OFF 0xae 31#define SSD1307FB_DISPLAY_OFF 0xae
32#define SSD1307FB_SET_MULTIPLEX_RATIO 0xa8
28#define SSD1307FB_DISPLAY_ON 0xaf 33#define SSD1307FB_DISPLAY_ON 0xaf
29#define SSD1307FB_START_PAGE_ADDRESS 0xb0 34#define SSD1307FB_START_PAGE_ADDRESS 0xb0
35#define SSD1307FB_SET_DISPLAY_OFFSET 0xd3
36#define SSD1307FB_SET_CLOCK_FREQ 0xd5
37#define SSD1307FB_SET_PRECHARGE_PERIOD 0xd9
38#define SSD1307FB_SET_COM_PINS_CONFIG 0xda
39#define SSD1307FB_SET_VCOMH 0xdb
40
41struct ssd1307fb_par;
42
43struct ssd1307fb_ops {
44 int (*init)(struct ssd1307fb_par *);
45 int (*remove)(struct ssd1307fb_par *);
46};
30 47
31struct ssd1307fb_par { 48struct ssd1307fb_par {
32 struct i2c_client *client; 49 struct i2c_client *client;
50 u32 height;
33 struct fb_info *info; 51 struct fb_info *info;
52 struct ssd1307fb_ops *ops;
53 u32 page_offset;
34 struct pwm_device *pwm; 54 struct pwm_device *pwm;
35 u32 pwm_period; 55 u32 pwm_period;
36 int reset; 56 int reset;
57 u32 width;
58};
59
60struct ssd1307fb_array {
61 u8 type;
62 u8 data[0];
37}; 63};
38 64
39static struct fb_fix_screeninfo ssd1307fb_fix = { 65static struct fb_fix_screeninfo ssd1307fb_fix = {
@@ -43,68 +69,87 @@ static struct fb_fix_screeninfo ssd1307fb_fix = {
43 .xpanstep = 0, 69 .xpanstep = 0,
44 .ypanstep = 0, 70 .ypanstep = 0,
45 .ywrapstep = 0, 71 .ywrapstep = 0,
46 .line_length = SSD1307FB_WIDTH / 8,
47 .accel = FB_ACCEL_NONE, 72 .accel = FB_ACCEL_NONE,
48}; 73};
49 74
50static struct fb_var_screeninfo ssd1307fb_var = { 75static struct fb_var_screeninfo ssd1307fb_var = {
51 .xres = SSD1307FB_WIDTH,
52 .yres = SSD1307FB_HEIGHT,
53 .xres_virtual = SSD1307FB_WIDTH,
54 .yres_virtual = SSD1307FB_HEIGHT,
55 .bits_per_pixel = 1, 76 .bits_per_pixel = 1,
56}; 77};
57 78
58static int ssd1307fb_write_array(struct i2c_client *client, u8 type, u8 *cmd, u32 len) 79static struct ssd1307fb_array *ssd1307fb_alloc_array(u32 len, u8 type)
59{ 80{
60 u8 *buf; 81 struct ssd1307fb_array *array;
61 int ret = 0;
62
63 buf = kzalloc(len + 1, GFP_KERNEL);
64 if (!buf) {
65 dev_err(&client->dev, "Couldn't allocate sending buffer.\n");
66 return -ENOMEM;
67 }
68 82
69 buf[0] = type; 83 array = kzalloc(sizeof(struct ssd1307fb_array) + len, GFP_KERNEL);
70 memcpy(buf + 1, cmd, len); 84 if (!array)
85 return NULL;
71 86
72 ret = i2c_master_send(client, buf, len + 1); 87 array->type = type;
73 if (ret != len + 1) {
74 dev_err(&client->dev, "Couldn't send I2C command.\n");
75 goto error;
76 }
77 88
78error: 89 return array;
79 kfree(buf);
80 return ret;
81} 90}
82 91
83static inline int ssd1307fb_write_cmd_array(struct i2c_client *client, u8 *cmd, u32 len) 92static int ssd1307fb_write_array(struct i2c_client *client,
93 struct ssd1307fb_array *array, u32 len)
84{ 94{
85 return ssd1307fb_write_array(client, SSD1307FB_COMMAND, cmd, len); 95 int ret;
96
97 len += sizeof(struct ssd1307fb_array);
98
99 ret = i2c_master_send(client, (u8 *)array, len);
100 if (ret != len) {
101 dev_err(&client->dev, "Couldn't send I2C command.\n");
102 return ret;
103 }
104
105 return 0;
86} 106}
87 107
88static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd) 108static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd)
89{ 109{
90 return ssd1307fb_write_cmd_array(client, &cmd, 1); 110 struct ssd1307fb_array *array;
91} 111 int ret;
92 112
93static inline int ssd1307fb_write_data_array(struct i2c_client *client, u8 *cmd, u32 len) 113 array = ssd1307fb_alloc_array(1, SSD1307FB_COMMAND);
94{ 114 if (!array)
95 return ssd1307fb_write_array(client, SSD1307FB_DATA, cmd, len); 115 return -ENOMEM;
116
117 array->data[0] = cmd;
118
119 ret = ssd1307fb_write_array(client, array, 1);
120 kfree(array);
121
122 return ret;
96} 123}
97 124
98static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data) 125static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data)
99{ 126{
100 return ssd1307fb_write_data_array(client, &data, 1); 127 struct ssd1307fb_array *array;
128 int ret;
129
130 array = ssd1307fb_alloc_array(1, SSD1307FB_DATA);
131 if (!array)
132 return -ENOMEM;
133
134 array->data[0] = data;
135
136 ret = ssd1307fb_write_array(client, array, 1);
137 kfree(array);
138
139 return ret;
101} 140}
102 141
103static void ssd1307fb_update_display(struct ssd1307fb_par *par) 142static void ssd1307fb_update_display(struct ssd1307fb_par *par)
104{ 143{
144 struct ssd1307fb_array *array;
105 u8 *vmem = par->info->screen_base; 145 u8 *vmem = par->info->screen_base;
106 int i, j, k; 146 int i, j, k;
107 147
148 array = ssd1307fb_alloc_array(par->width * par->height / 8,
149 SSD1307FB_DATA);
150 if (!array)
151 return;
152
108 /* 153 /*
109 * The screen is divided in pages, each having a height of 8 154 * The screen is divided in pages, each having a height of 8
110 * pixels, and the width of the screen. When sending a byte of 155 * pixels, and the width of the screen. When sending a byte of
@@ -134,24 +179,23 @@ static void ssd1307fb_update_display(struct ssd1307fb_par *par)
134 * (5) A4 B4 C4 D4 E4 F4 G4 H4 179 * (5) A4 B4 C4 D4 E4 F4 G4 H4
135 */ 180 */
136 181
137 for (i = 0; i < (SSD1307FB_HEIGHT / 8); i++) { 182 for (i = 0; i < (par->height / 8); i++) {
138 ssd1307fb_write_cmd(par->client, SSD1307FB_START_PAGE_ADDRESS + (i + 1)); 183 for (j = 0; j < par->width; j++) {
139 ssd1307fb_write_cmd(par->client, 0x00); 184 u32 array_idx = i * par->width + j;
140 ssd1307fb_write_cmd(par->client, 0x10); 185 array->data[array_idx] = 0;
141
142 for (j = 0; j < SSD1307FB_WIDTH; j++) {
143 u8 buf = 0;
144 for (k = 0; k < 8; k++) { 186 for (k = 0; k < 8; k++) {
145 u32 page_length = SSD1307FB_WIDTH * i; 187 u32 page_length = par->width * i;
146 u32 index = page_length + (SSD1307FB_WIDTH * k + j) / 8; 188 u32 index = page_length + (par->width * k + j) / 8;
147 u8 byte = *(vmem + index); 189 u8 byte = *(vmem + index);
148 u8 bit = byte & (1 << (j % 8)); 190 u8 bit = byte & (1 << (j % 8));
149 bit = bit >> (j % 8); 191 bit = bit >> (j % 8);
150 buf |= bit << k; 192 array->data[array_idx] |= bit << k;
151 } 193 }
152 ssd1307fb_write_data(par->client, buf);
153 } 194 }
154 } 195 }
196
197 ssd1307fb_write_array(par->client, array, par->width * par->height / 8);
198 kfree(array);
155} 199}
156 200
157 201
@@ -227,16 +271,167 @@ static struct fb_deferred_io ssd1307fb_defio = {
227 .deferred_io = ssd1307fb_deferred_io, 271 .deferred_io = ssd1307fb_deferred_io,
228}; 272};
229 273
274static int ssd1307fb_ssd1307_init(struct ssd1307fb_par *par)
275{
276 int ret;
277
278 par->pwm = pwm_get(&par->client->dev, NULL);
279 if (IS_ERR(par->pwm)) {
280 dev_err(&par->client->dev, "Could not get PWM from device tree!\n");
281 return PTR_ERR(par->pwm);
282 }
283
284 par->pwm_period = pwm_get_period(par->pwm);
285 /* Enable the PWM */
286 pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period);
287 pwm_enable(par->pwm);
288
289 dev_dbg(&par->client->dev, "Using PWM%d with a %dns period.\n",
290 par->pwm->pwm, par->pwm_period);
291
292 /* Map column 127 of the OLED to segment 0 */
293 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SEG_REMAP_ON);
294 if (ret < 0)
295 return ret;
296
297 /* Turn on the display */
298 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_ON);
299 if (ret < 0)
300 return ret;
301
302 return 0;
303}
304
305static int ssd1307fb_ssd1307_remove(struct ssd1307fb_par *par)
306{
307 pwm_disable(par->pwm);
308 pwm_put(par->pwm);
309 return 0;
310}
311
312static struct ssd1307fb_ops ssd1307fb_ssd1307_ops = {
313 .init = ssd1307fb_ssd1307_init,
314 .remove = ssd1307fb_ssd1307_remove,
315};
316
317static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
318{
319 int ret;
320
321 /* Set initial contrast */
322 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CONTRAST);
323 ret = ret & ssd1307fb_write_cmd(par->client, 0x7f);
324 if (ret < 0)
325 return ret;
326
327 /* Set COM direction */
328 ret = ssd1307fb_write_cmd(par->client, 0xc8);
329 if (ret < 0)
330 return ret;
331
332 /* Set segment re-map */
333 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SEG_REMAP_ON);
334 if (ret < 0)
335 return ret;
336
337 /* Set multiplex ratio value */
338 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_MULTIPLEX_RATIO);
339 ret = ret & ssd1307fb_write_cmd(par->client, par->height - 1);
340 if (ret < 0)
341 return ret;
342
343 /* set display offset value */
344 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_DISPLAY_OFFSET);
345 ret = ssd1307fb_write_cmd(par->client, 0x20);
346 if (ret < 0)
347 return ret;
348
349 /* Set clock frequency */
350 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_CLOCK_FREQ);
351 ret = ret & ssd1307fb_write_cmd(par->client, 0xf0);
352 if (ret < 0)
353 return ret;
354
355 /* Set precharge period in number of ticks from the internal clock */
356 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PRECHARGE_PERIOD);
357 ret = ret & ssd1307fb_write_cmd(par->client, 0x22);
358 if (ret < 0)
359 return ret;
360
361 /* Set COM pins configuration */
362 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COM_PINS_CONFIG);
363 ret = ret & ssd1307fb_write_cmd(par->client, 0x22);
364 if (ret < 0)
365 return ret;
366
367 /* Set VCOMH */
368 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_VCOMH);
369 ret = ret & ssd1307fb_write_cmd(par->client, 0x49);
370 if (ret < 0)
371 return ret;
372
373 /* Turn on the DC-DC Charge Pump */
374 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CHARGE_PUMP);
375 ret = ret & ssd1307fb_write_cmd(par->client, 0x14);
376 if (ret < 0)
377 return ret;
378
379 /* Switch to horizontal addressing mode */
380 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_ADDRESS_MODE);
381 ret = ret & ssd1307fb_write_cmd(par->client,
382 SSD1307FB_SET_ADDRESS_MODE_HORIZONTAL);
383 if (ret < 0)
384 return ret;
385
386 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE);
387 ret = ret & ssd1307fb_write_cmd(par->client, 0x0);
388 ret = ret & ssd1307fb_write_cmd(par->client, par->width - 1);
389 if (ret < 0)
390 return ret;
391
392 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PAGE_RANGE);
393 ret = ret & ssd1307fb_write_cmd(par->client, 0x0);
394 ret = ret & ssd1307fb_write_cmd(par->client,
395 par->page_offset + (par->height / 8) - 1);
396 if (ret < 0)
397 return ret;
398
399 /* Turn on the display */
400 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_ON);
401 if (ret < 0)
402 return ret;
403
404 return 0;
405}
406
407static struct ssd1307fb_ops ssd1307fb_ssd1306_ops = {
408 .init = ssd1307fb_ssd1306_init,
409};
410
411static const struct of_device_id ssd1307fb_of_match[] = {
412 {
413 .compatible = "solomon,ssd1306fb-i2c",
414 .data = (void *)&ssd1307fb_ssd1306_ops,
415 },
416 {
417 .compatible = "solomon,ssd1307fb-i2c",
418 .data = (void *)&ssd1307fb_ssd1307_ops,
419 },
420 {},
421};
422MODULE_DEVICE_TABLE(of, ssd1307fb_of_match);
423
230static int ssd1307fb_probe(struct i2c_client *client, 424static int ssd1307fb_probe(struct i2c_client *client,
231 const struct i2c_device_id *id) 425 const struct i2c_device_id *id)
232{ 426{
233 struct fb_info *info; 427 struct fb_info *info;
234 u32 vmem_size = SSD1307FB_WIDTH * SSD1307FB_HEIGHT / 8; 428 struct device_node *node = client->dev.of_node;
429 u32 vmem_size;
235 struct ssd1307fb_par *par; 430 struct ssd1307fb_par *par;
236 u8 *vmem; 431 u8 *vmem;
237 int ret; 432 int ret;
238 433
239 if (!client->dev.of_node) { 434 if (!node) {
240 dev_err(&client->dev, "No device tree data found!\n"); 435 dev_err(&client->dev, "No device tree data found!\n");
241 return -EINVAL; 436 return -EINVAL;
242 } 437 }
@@ -247,6 +442,31 @@ static int ssd1307fb_probe(struct i2c_client *client,
247 return -ENOMEM; 442 return -ENOMEM;
248 } 443 }
249 444
445 par = info->par;
446 par->info = info;
447 par->client = client;
448
449 par->ops = (struct ssd1307fb_ops *)of_match_device(ssd1307fb_of_match,
450 &client->dev)->data;
451
452 par->reset = of_get_named_gpio(client->dev.of_node,
453 "reset-gpios", 0);
454 if (!gpio_is_valid(par->reset)) {
455 ret = -EINVAL;
456 goto fb_alloc_error;
457 }
458
459 if (of_property_read_u32(node, "solomon,width", &par->width))
460 par->width = 96;
461
462 if (of_property_read_u32(node, "solomon,height", &par->height))
463 par->width = 16;
464
465 if (of_property_read_u32(node, "solomon,page-offset", &par->page_offset))
466 par->page_offset = 1;
467
468 vmem_size = par->width * par->height / 8;
469
250 vmem = devm_kzalloc(&client->dev, vmem_size, GFP_KERNEL); 470 vmem = devm_kzalloc(&client->dev, vmem_size, GFP_KERNEL);
251 if (!vmem) { 471 if (!vmem) {
252 dev_err(&client->dev, "Couldn't allocate graphical memory.\n"); 472 dev_err(&client->dev, "Couldn't allocate graphical memory.\n");
@@ -256,9 +476,15 @@ static int ssd1307fb_probe(struct i2c_client *client,
256 476
257 info->fbops = &ssd1307fb_ops; 477 info->fbops = &ssd1307fb_ops;
258 info->fix = ssd1307fb_fix; 478 info->fix = ssd1307fb_fix;
479 info->fix.line_length = par->width / 8;
259 info->fbdefio = &ssd1307fb_defio; 480 info->fbdefio = &ssd1307fb_defio;
260 481
261 info->var = ssd1307fb_var; 482 info->var = ssd1307fb_var;
483 info->var.xres = par->width;
484 info->var.xres_virtual = par->width;
485 info->var.yres = par->height;
486 info->var.yres_virtual = par->height;
487
262 info->var.red.length = 1; 488 info->var.red.length = 1;
263 info->var.red.offset = 0; 489 info->var.red.offset = 0;
264 info->var.green.length = 1; 490 info->var.green.length = 1;
@@ -272,17 +498,6 @@ static int ssd1307fb_probe(struct i2c_client *client,
272 498
273 fb_deferred_io_init(info); 499 fb_deferred_io_init(info);
274 500
275 par = info->par;
276 par->info = info;
277 par->client = client;
278
279 par->reset = of_get_named_gpio(client->dev.of_node,
280 "reset-gpios", 0);
281 if (!gpio_is_valid(par->reset)) {
282 ret = -EINVAL;
283 goto reset_oled_error;
284 }
285
286 ret = devm_gpio_request_one(&client->dev, par->reset, 501 ret = devm_gpio_request_one(&client->dev, par->reset,
287 GPIOF_OUT_INIT_HIGH, 502 GPIOF_OUT_INIT_HIGH,
288 "oled-reset"); 503 "oled-reset");
@@ -293,23 +508,6 @@ static int ssd1307fb_probe(struct i2c_client *client,
293 goto reset_oled_error; 508 goto reset_oled_error;
294 } 509 }
295 510
296 par->pwm = pwm_get(&client->dev, NULL);
297 if (IS_ERR(par->pwm)) {
298 dev_err(&client->dev, "Could not get PWM from device tree!\n");
299 ret = PTR_ERR(par->pwm);
300 goto pwm_error;
301 }
302
303 par->pwm_period = pwm_get_period(par->pwm);
304
305 dev_dbg(&client->dev, "Using PWM%d with a %dns period.\n", par->pwm->pwm, par->pwm_period);
306
307 ret = register_framebuffer(info);
308 if (ret) {
309 dev_err(&client->dev, "Couldn't register the framebuffer\n");
310 goto fbreg_error;
311 }
312
313 i2c_set_clientdata(client, info); 511 i2c_set_clientdata(client, info);
314 512
315 /* Reset the screen */ 513 /* Reset the screen */
@@ -318,34 +516,25 @@ static int ssd1307fb_probe(struct i2c_client *client,
318 gpio_set_value(par->reset, 1); 516 gpio_set_value(par->reset, 1);
319 udelay(4); 517 udelay(4);
320 518
321 /* Enable the PWM */ 519 if (par->ops->init) {
322 pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period); 520 ret = par->ops->init(par);
323 pwm_enable(par->pwm); 521 if (ret)
324 522 goto reset_oled_error;
325 /* Map column 127 of the OLED to segment 0 */
326 ret = ssd1307fb_write_cmd(client, SSD1307FB_SEG_REMAP_ON);
327 if (ret < 0) {
328 dev_err(&client->dev, "Couldn't remap the screen.\n");
329 goto remap_error;
330 } 523 }
331 524
332 /* Turn on the display */ 525 ret = register_framebuffer(info);
333 ret = ssd1307fb_write_cmd(client, SSD1307FB_DISPLAY_ON); 526 if (ret) {
334 if (ret < 0) { 527 dev_err(&client->dev, "Couldn't register the framebuffer\n");
335 dev_err(&client->dev, "Couldn't turn the display on.\n"); 528 goto panel_init_error;
336 goto remap_error;
337 } 529 }
338 530
339 dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size); 531 dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size);
340 532
341 return 0; 533 return 0;
342 534
343remap_error: 535panel_init_error:
344 unregister_framebuffer(info); 536 if (par->ops->remove)
345 pwm_disable(par->pwm); 537 par->ops->remove(par);
346fbreg_error:
347 pwm_put(par->pwm);
348pwm_error:
349reset_oled_error: 538reset_oled_error:
350 fb_deferred_io_cleanup(info); 539 fb_deferred_io_cleanup(info);
351fb_alloc_error: 540fb_alloc_error:
@@ -359,8 +548,8 @@ static int ssd1307fb_remove(struct i2c_client *client)
359 struct ssd1307fb_par *par = info->par; 548 struct ssd1307fb_par *par = info->par;
360 549
361 unregister_framebuffer(info); 550 unregister_framebuffer(info);
362 pwm_disable(par->pwm); 551 if (par->ops->remove)
363 pwm_put(par->pwm); 552 par->ops->remove(par);
364 fb_deferred_io_cleanup(info); 553 fb_deferred_io_cleanup(info);
365 framebuffer_release(info); 554 framebuffer_release(info);
366 555
@@ -368,17 +557,12 @@ static int ssd1307fb_remove(struct i2c_client *client)
368} 557}
369 558
370static const struct i2c_device_id ssd1307fb_i2c_id[] = { 559static const struct i2c_device_id ssd1307fb_i2c_id[] = {
560 { "ssd1306fb", 0 },
371 { "ssd1307fb", 0 }, 561 { "ssd1307fb", 0 },
372 { } 562 { }
373}; 563};
374MODULE_DEVICE_TABLE(i2c, ssd1307fb_i2c_id); 564MODULE_DEVICE_TABLE(i2c, ssd1307fb_i2c_id);
375 565
376static const struct of_device_id ssd1307fb_of_match[] = {
377 { .compatible = "solomon,ssd1307fb-i2c" },
378 {},
379};
380MODULE_DEVICE_TABLE(of, ssd1307fb_of_match);
381
382static struct i2c_driver ssd1307fb_driver = { 566static struct i2c_driver ssd1307fb_driver = {
383 .probe = ssd1307fb_probe, 567 .probe = ssd1307fb_probe,
384 .remove = ssd1307fb_remove, 568 .remove = ssd1307fb_remove,
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
index dc4fb8620156..deb8733f3c70 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/tmiofb.c
@@ -794,7 +794,6 @@ err_hw_init:
794 cell->disable(dev); 794 cell->disable(dev);
795err_enable: 795err_enable:
796err_find_mode: 796err_find_mode:
797 platform_set_drvdata(dev, NULL);
798 free_irq(irq, info); 797 free_irq(irq, info);
799err_request_irq: 798err_request_irq:
800 iounmap(info->screen_base); 799 iounmap(info->screen_base);
@@ -823,8 +822,6 @@ static int tmiofb_remove(struct platform_device *dev)
823 if (cell->disable) 822 if (cell->disable)
824 cell->disable(dev); 823 cell->disable(dev);
825 824
826 platform_set_drvdata(dev, NULL);
827
828 free_irq(irq, info); 825 free_irq(irq, info);
829 826
830 iounmap(info->screen_base); 827 iounmap(info->screen_base);
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index ec03e726c940..d2e5bc3cf969 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -434,10 +434,10 @@ static void dlfb_compress_hline(
434 434
435 while ((pixel_end > pixel) && 435 while ((pixel_end > pixel) &&
436 (cmd_buffer_end - MIN_RLX_CMD_BYTES > cmd)) { 436 (cmd_buffer_end - MIN_RLX_CMD_BYTES > cmd)) {
437 uint8_t *raw_pixels_count_byte = 0; 437 uint8_t *raw_pixels_count_byte = NULL;
438 uint8_t *cmd_pixels_count_byte = 0; 438 uint8_t *cmd_pixels_count_byte = NULL;
439 const uint16_t *raw_pixel_start = 0; 439 const uint16_t *raw_pixel_start = NULL;
440 const uint16_t *cmd_pixel_start, *cmd_pixel_end = 0; 440 const uint16_t *cmd_pixel_start, *cmd_pixel_end = NULL;
441 441
442 prefetchw((void *) cmd); /* pull in one cache line at least */ 442 prefetchw((void *) cmd); /* pull in one cache line at least */
443 443
@@ -573,7 +573,7 @@ static int dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
573 return 0; 573 return 0;
574} 574}
575 575
576int dlfb_handle_damage(struct dlfb_data *dev, int x, int y, 576static int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
577 int width, int height, char *data) 577 int width, int height, char *data)
578{ 578{
579 int i, ret; 579 int i, ret;
@@ -1588,7 +1588,7 @@ static int dlfb_usb_probe(struct usb_interface *interface,
1588 const struct usb_device_id *id) 1588 const struct usb_device_id *id)
1589{ 1589{
1590 struct usb_device *usbdev; 1590 struct usb_device *usbdev;
1591 struct dlfb_data *dev = 0; 1591 struct dlfb_data *dev = NULL;
1592 int retval = -ENOMEM; 1592 int retval = -ENOMEM;
1593 1593
1594 /* usb initialization */ 1594 /* usb initialization */
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index e328a61b64ba..10138b60fd70 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -819,8 +819,8 @@ static int uvesafb_vbe_init(struct fb_info *info)
819 if (par->pmi_setpal || par->ypan) { 819 if (par->pmi_setpal || par->ypan) {
820 if (__supported_pte_mask & _PAGE_NX) { 820 if (__supported_pte_mask & _PAGE_NX) {
821 par->pmi_setpal = par->ypan = 0; 821 par->pmi_setpal = par->ypan = 0;
822 printk(KERN_WARNING "uvesafb: NX protection is actively." 822 printk(KERN_WARNING "uvesafb: NX protection is active, "
823 "We have better not to use the PMI.\n"); 823 "better not use the PMI.\n");
824 } else { 824 } else {
825 uvesafb_vbe_getpmi(task, par); 825 uvesafb_vbe_getpmi(task, par);
826 } 826 }
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 545faeccdb44..830ded45fd47 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -1269,7 +1269,6 @@ static void vga16fb_destroy(struct fb_info *info)
1269 iounmap(info->screen_base); 1269 iounmap(info->screen_base);
1270 fb_dealloc_cmap(&info->cmap); 1270 fb_dealloc_cmap(&info->cmap);
1271 /* XXX unshare VGA regions */ 1271 /* XXX unshare VGA regions */
1272 platform_set_drvdata(dev, NULL);
1273 framebuffer_release(info); 1272 framebuffer_release(info);
1274} 1273}
1275 1274
diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/vt8500lcdfb.c
index 9547e1831e03..897484903c30 100644
--- a/drivers/video/vt8500lcdfb.c
+++ b/drivers/video/vt8500lcdfb.c
@@ -448,7 +448,6 @@ failed_free_io:
448failed_free_res: 448failed_free_res:
449 release_mem_region(res->start, resource_size(res)); 449 release_mem_region(res->start, resource_size(res));
450failed_fbi: 450failed_fbi:
451 platform_set_drvdata(pdev, NULL);
452 kfree(fbi); 451 kfree(fbi);
453failed: 452failed:
454 return ret; 453 return ret;
diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c
index 01f9ace068e2..3072f30cad19 100644
--- a/drivers/video/wm8505fb.c
+++ b/drivers/video/wm8505fb.c
@@ -173,7 +173,7 @@ static ssize_t contrast_store(struct device *dev,
173 struct wm8505fb_info *fbi = to_wm8505fb_info(info); 173 struct wm8505fb_info *fbi = to_wm8505fb_info(info);
174 unsigned long tmp; 174 unsigned long tmp;
175 175
176 if (strict_strtoul(buf, 10, &tmp) || (tmp > 0xff)) 176 if (kstrtoul(buf, 10, &tmp) || (tmp > 0xff))
177 return -EINVAL; 177 return -EINVAL;
178 fbi->contrast = tmp; 178 fbi->contrast = tmp;
179 179
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index af0b4fdf9aa9..f3d4a69e1e4e 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/xilinxfb.c
@@ -44,7 +44,7 @@
44 44
45 45
46/* 46/*
47 * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for 47 * Xilinx calls it "TFT LCD Controller" though it can also be used for
48 * the VGA port on the Xilinx ML40x board. This is a hardware display 48 * the VGA port on the Xilinx ML40x board. This is a hardware display
49 * controller for a 640x480 resolution TFT or VGA screen. 49 * controller for a 640x480 resolution TFT or VGA screen.
50 * 50 *
@@ -54,11 +54,11 @@
54 * don't start thinking about scrolling). The second allows the LCD to 54 * don't start thinking about scrolling). The second allows the LCD to
55 * be turned on or off as well as rotated 180 degrees. 55 * be turned on or off as well as rotated 180 degrees.
56 * 56 *
57 * In case of direct PLB access the second control register will be at 57 * In case of direct BUS access the second control register will be at
58 * an offset of 4 as compared to the DCR access where the offset is 1 58 * an offset of 4 as compared to the DCR access where the offset is 1
59 * i.e. REG_CTRL. So this is taken care in the function 59 * i.e. REG_CTRL. So this is taken care in the function
60 * xilinx_fb_out_be32 where it left shifts the offset 2 times in case of 60 * xilinx_fb_out32 where it left shifts the offset 2 times in case of
61 * direct PLB access. 61 * direct BUS access.
62 */ 62 */
63#define NUM_REGS 2 63#define NUM_REGS 2
64#define REG_FB_ADDR 0 64#define REG_FB_ADDR 0
@@ -116,7 +116,8 @@ static struct fb_var_screeninfo xilinx_fb_var = {
116}; 116};
117 117
118 118
119#define PLB_ACCESS_FLAG 0x1 /* 1 = PLB, 0 = DCR */ 119#define BUS_ACCESS_FLAG 0x1 /* 1 = BUS, 0 = DCR */
120#define LITTLE_ENDIAN_ACCESS 0x2 /* LITTLE ENDIAN IO functions */
120 121
121struct xilinxfb_drvdata { 122struct xilinxfb_drvdata {
122 123
@@ -146,21 +147,40 @@ struct xilinxfb_drvdata {
146 container_of(_info, struct xilinxfb_drvdata, info) 147 container_of(_info, struct xilinxfb_drvdata, info)
147 148
148/* 149/*
149 * The XPS TFT Controller can be accessed through PLB or DCR interface. 150 * The XPS TFT Controller can be accessed through BUS or DCR interface.
150 * To perform the read/write on the registers we need to check on 151 * To perform the read/write on the registers we need to check on
151 * which bus its connected and call the appropriate write API. 152 * which bus its connected and call the appropriate write API.
152 */ 153 */
153static void xilinx_fb_out_be32(struct xilinxfb_drvdata *drvdata, u32 offset, 154static void xilinx_fb_out32(struct xilinxfb_drvdata *drvdata, u32 offset,
154 u32 val) 155 u32 val)
155{ 156{
156 if (drvdata->flags & PLB_ACCESS_FLAG) 157 if (drvdata->flags & BUS_ACCESS_FLAG) {
157 out_be32(drvdata->regs + (offset << 2), val); 158 if (drvdata->flags & LITTLE_ENDIAN_ACCESS)
159 iowrite32(val, drvdata->regs + (offset << 2));
160 else
161 iowrite32be(val, drvdata->regs + (offset << 2));
162 }
158#ifdef CONFIG_PPC_DCR 163#ifdef CONFIG_PPC_DCR
159 else 164 else
160 dcr_write(drvdata->dcr_host, offset, val); 165 dcr_write(drvdata->dcr_host, offset, val);
161#endif 166#endif
162} 167}
163 168
169static u32 xilinx_fb_in32(struct xilinxfb_drvdata *drvdata, u32 offset)
170{
171 if (drvdata->flags & BUS_ACCESS_FLAG) {
172 if (drvdata->flags & LITTLE_ENDIAN_ACCESS)
173 return ioread32(drvdata->regs + (offset << 2));
174 else
175 return ioread32be(drvdata->regs + (offset << 2));
176 }
177#ifdef CONFIG_PPC_DCR
178 else
179 return dcr_read(drvdata->dcr_host, offset);
180#endif
181 return 0;
182}
183
164static int 184static int
165xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, 185xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
166 unsigned transp, struct fb_info *fbi) 186 unsigned transp, struct fb_info *fbi)
@@ -197,7 +217,7 @@ xilinx_fb_blank(int blank_mode, struct fb_info *fbi)
197 switch (blank_mode) { 217 switch (blank_mode) {
198 case FB_BLANK_UNBLANK: 218 case FB_BLANK_UNBLANK:
199 /* turn on panel */ 219 /* turn on panel */
200 xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); 220 xilinx_fb_out32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
201 break; 221 break;
202 222
203 case FB_BLANK_NORMAL: 223 case FB_BLANK_NORMAL:
@@ -205,7 +225,7 @@ xilinx_fb_blank(int blank_mode, struct fb_info *fbi)
205 case FB_BLANK_HSYNC_SUSPEND: 225 case FB_BLANK_HSYNC_SUSPEND:
206 case FB_BLANK_POWERDOWN: 226 case FB_BLANK_POWERDOWN:
207 /* turn off panel */ 227 /* turn off panel */
208 xilinx_fb_out_be32(drvdata, REG_CTRL, 0); 228 xilinx_fb_out32(drvdata, REG_CTRL, 0);
209 default: 229 default:
210 break; 230 break;
211 231
@@ -227,33 +247,23 @@ static struct fb_ops xilinxfb_ops =
227 * Bus independent setup/teardown 247 * Bus independent setup/teardown
228 */ 248 */
229 249
230static int xilinxfb_assign(struct device *dev, 250static int xilinxfb_assign(struct platform_device *pdev,
231 struct xilinxfb_drvdata *drvdata, 251 struct xilinxfb_drvdata *drvdata,
232 unsigned long physaddr,
233 struct xilinxfb_platform_data *pdata) 252 struct xilinxfb_platform_data *pdata)
234{ 253{
235 int rc; 254 int rc;
255 struct device *dev = &pdev->dev;
236 int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL; 256 int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL;
237 257
238 if (drvdata->flags & PLB_ACCESS_FLAG) { 258 if (drvdata->flags & BUS_ACCESS_FLAG) {
239 /* 259 struct resource *res;
240 * Map the control registers in if the controller
241 * is on direct PLB interface.
242 */
243 if (!request_mem_region(physaddr, 8, DRIVER_NAME)) {
244 dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
245 physaddr);
246 rc = -ENODEV;
247 goto err_region;
248 }
249 260
250 drvdata->regs_phys = physaddr; 261 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
251 drvdata->regs = ioremap(physaddr, 8); 262 drvdata->regs_phys = res->start;
263 drvdata->regs = devm_request_and_ioremap(&pdev->dev, res);
252 if (!drvdata->regs) { 264 if (!drvdata->regs) {
253 dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", 265 rc = -EADDRNOTAVAIL;
254 physaddr); 266 goto err_region;
255 rc = -ENODEV;
256 goto err_map;
257 } 267 }
258 } 268 }
259 269
@@ -270,7 +280,7 @@ static int xilinxfb_assign(struct device *dev,
270 if (!drvdata->fb_virt) { 280 if (!drvdata->fb_virt) {
271 dev_err(dev, "Could not allocate frame buffer memory\n"); 281 dev_err(dev, "Could not allocate frame buffer memory\n");
272 rc = -ENOMEM; 282 rc = -ENOMEM;
273 if (drvdata->flags & PLB_ACCESS_FLAG) 283 if (drvdata->flags & BUS_ACCESS_FLAG)
274 goto err_fbmem; 284 goto err_fbmem;
275 else 285 else
276 goto err_region; 286 goto err_region;
@@ -280,13 +290,19 @@ static int xilinxfb_assign(struct device *dev,
280 memset_io((void __iomem *)drvdata->fb_virt, 0, fbsize); 290 memset_io((void __iomem *)drvdata->fb_virt, 0, fbsize);
281 291
282 /* Tell the hardware where the frame buffer is */ 292 /* Tell the hardware where the frame buffer is */
283 xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); 293 xilinx_fb_out32(drvdata, REG_FB_ADDR, drvdata->fb_phys);
294 rc = xilinx_fb_in32(drvdata, REG_FB_ADDR);
295 /* Endianess detection */
296 if (rc != drvdata->fb_phys) {
297 drvdata->flags |= LITTLE_ENDIAN_ACCESS;
298 xilinx_fb_out32(drvdata, REG_FB_ADDR, drvdata->fb_phys);
299 }
284 300
285 /* Turn on the display */ 301 /* Turn on the display */
286 drvdata->reg_ctrl_default = REG_CTRL_ENABLE; 302 drvdata->reg_ctrl_default = REG_CTRL_ENABLE;
287 if (pdata->rotate_screen) 303 if (pdata->rotate_screen)
288 drvdata->reg_ctrl_default |= REG_CTRL_ROTATE; 304 drvdata->reg_ctrl_default |= REG_CTRL_ROTATE;
289 xilinx_fb_out_be32(drvdata, REG_CTRL, 305 xilinx_fb_out32(drvdata, REG_CTRL,
290 drvdata->reg_ctrl_default); 306 drvdata->reg_ctrl_default);
291 307
292 /* Fill struct fb_info */ 308 /* Fill struct fb_info */
@@ -323,9 +339,9 @@ static int xilinxfb_assign(struct device *dev,
323 goto err_regfb; 339 goto err_regfb;
324 } 340 }
325 341
326 if (drvdata->flags & PLB_ACCESS_FLAG) { 342 if (drvdata->flags & BUS_ACCESS_FLAG) {
327 /* Put a banner in the log (for DEBUG) */ 343 /* Put a banner in the log (for DEBUG) */
328 dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, 344 dev_dbg(dev, "regs: phys=%x, virt=%p\n", drvdata->regs_phys,
329 drvdata->regs); 345 drvdata->regs);
330 } 346 }
331 /* Put a banner in the log (for DEBUG) */ 347 /* Put a banner in the log (for DEBUG) */
@@ -345,15 +361,11 @@ err_cmap:
345 iounmap(drvdata->fb_virt); 361 iounmap(drvdata->fb_virt);
346 362
347 /* Turn off the display */ 363 /* Turn off the display */
348 xilinx_fb_out_be32(drvdata, REG_CTRL, 0); 364 xilinx_fb_out32(drvdata, REG_CTRL, 0);
349 365
350err_fbmem: 366err_fbmem:
351 if (drvdata->flags & PLB_ACCESS_FLAG) 367 if (drvdata->flags & BUS_ACCESS_FLAG)
352 iounmap(drvdata->regs); 368 devm_iounmap(dev, drvdata->regs);
353
354err_map:
355 if (drvdata->flags & PLB_ACCESS_FLAG)
356 release_mem_region(physaddr, 8);
357 369
358err_region: 370err_region:
359 kfree(drvdata); 371 kfree(drvdata);
@@ -381,13 +393,11 @@ static int xilinxfb_release(struct device *dev)
381 iounmap(drvdata->fb_virt); 393 iounmap(drvdata->fb_virt);
382 394
383 /* Turn off the display */ 395 /* Turn off the display */
384 xilinx_fb_out_be32(drvdata, REG_CTRL, 0); 396 xilinx_fb_out32(drvdata, REG_CTRL, 0);
385 397
386 /* Release the resources, as allocated based on interface */ 398 /* Release the resources, as allocated based on interface */
387 if (drvdata->flags & PLB_ACCESS_FLAG) { 399 if (drvdata->flags & BUS_ACCESS_FLAG)
388 iounmap(drvdata->regs); 400 devm_iounmap(dev, drvdata->regs);
389 release_mem_region(drvdata->regs_phys, 8);
390 }
391#ifdef CONFIG_PPC_DCR 401#ifdef CONFIG_PPC_DCR
392 else 402 else
393 dcr_unmap(drvdata->dcr_host, drvdata->dcr_len); 403 dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
@@ -406,11 +416,9 @@ static int xilinxfb_release(struct device *dev)
406static int xilinxfb_of_probe(struct platform_device *op) 416static int xilinxfb_of_probe(struct platform_device *op)
407{ 417{
408 const u32 *prop; 418 const u32 *prop;
409 u32 *p; 419 u32 tft_access = 0;
410 u32 tft_access;
411 struct xilinxfb_platform_data pdata; 420 struct xilinxfb_platform_data pdata;
412 struct resource res; 421 int size;
413 int size, rc;
414 struct xilinxfb_drvdata *drvdata; 422 struct xilinxfb_drvdata *drvdata;
415 423
416 /* Copy with the default pdata (not a ptr reference!) */ 424 /* Copy with the default pdata (not a ptr reference!) */
@@ -424,34 +432,29 @@ static int xilinxfb_of_probe(struct platform_device *op)
424 } 432 }
425 433
426 /* 434 /*
427 * To check whether the core is connected directly to DCR or PLB 435 * To check whether the core is connected directly to DCR or BUS
428 * interface and initialize the tft_access accordingly. 436 * interface and initialize the tft_access accordingly.
429 */ 437 */
430 p = (u32 *)of_get_property(op->dev.of_node, "xlnx,dcr-splb-slave-if", NULL); 438 of_property_read_u32(op->dev.of_node, "xlnx,dcr-splb-slave-if",
431 tft_access = p ? *p : 0; 439 &tft_access);
432 440
433 /* 441 /*
434 * Fill the resource structure if its direct PLB interface 442 * Fill the resource structure if its direct BUS interface
435 * otherwise fill the dcr_host structure. 443 * otherwise fill the dcr_host structure.
436 */ 444 */
437 if (tft_access) { 445 if (tft_access) {
438 drvdata->flags |= PLB_ACCESS_FLAG; 446 drvdata->flags |= BUS_ACCESS_FLAG;
439 rc = of_address_to_resource(op->dev.of_node, 0, &res);
440 if (rc) {
441 dev_err(&op->dev, "invalid address\n");
442 goto err;
443 }
444 } 447 }
445#ifdef CONFIG_PPC_DCR 448#ifdef CONFIG_PPC_DCR
446 else { 449 else {
447 int start; 450 int start;
448 res.start = 0;
449 start = dcr_resource_start(op->dev.of_node, 0); 451 start = dcr_resource_start(op->dev.of_node, 0);
450 drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0); 452 drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0);
451 drvdata->dcr_host = dcr_map(op->dev.of_node, start, drvdata->dcr_len); 453 drvdata->dcr_host = dcr_map(op->dev.of_node, start, drvdata->dcr_len);
452 if (!DCR_MAP_OK(drvdata->dcr_host)) { 454 if (!DCR_MAP_OK(drvdata->dcr_host)) {
453 dev_err(&op->dev, "invalid DCR address\n"); 455 dev_err(&op->dev, "invalid DCR address\n");
454 goto err; 456 kfree(drvdata);
457 return -ENODEV;
455 } 458 }
456 } 459 }
457#endif 460#endif
@@ -478,11 +481,7 @@ static int xilinxfb_of_probe(struct platform_device *op)
478 pdata.rotate_screen = 1; 481 pdata.rotate_screen = 1;
479 482
480 dev_set_drvdata(&op->dev, drvdata); 483 dev_set_drvdata(&op->dev, drvdata);
481 return xilinxfb_assign(&op->dev, drvdata, res.start, &pdata); 484 return xilinxfb_assign(op, drvdata, &pdata);
482
483 err:
484 kfree(drvdata);
485 return -ENODEV;
486} 485}
487 486
488static int xilinxfb_of_remove(struct platform_device *op) 487static int xilinxfb_of_remove(struct platform_device *op)
diff --git a/include/linux/fb.h b/include/linux/fb.h
index d49c60f5aa4c..ffac70aab3e9 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -624,7 +624,7 @@ extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u3
624extern void fb_set_suspend(struct fb_info *info, int state); 624extern void fb_set_suspend(struct fb_info *info, int state);
625extern int fb_get_color_depth(struct fb_var_screeninfo *var, 625extern int fb_get_color_depth(struct fb_var_screeninfo *var,
626 struct fb_fix_screeninfo *fix); 626 struct fb_fix_screeninfo *fix);
627extern int fb_get_options(char *name, char **option); 627extern int fb_get_options(const char *name, char **option);
628extern int fb_new_modelist(struct fb_info *info); 628extern int fb_new_modelist(struct fb_info *info);
629 629
630extern struct fb_info *registered_fb[FB_MAX]; 630extern struct fb_info *registered_fb[FB_MAX];
diff --git a/include/video/of_display_timing.h b/include/video/of_display_timing.h
index 8016eb727cf3..79e6697af6cf 100644
--- a/include/video/of_display_timing.h
+++ b/include/video/of_display_timing.h
@@ -10,10 +10,13 @@
10#define __LINUX_OF_DISPLAY_TIMING_H 10#define __LINUX_OF_DISPLAY_TIMING_H
11 11
12struct device_node; 12struct device_node;
13struct display_timing;
13struct display_timings; 14struct display_timings;
14 15
15#define OF_USE_NATIVE_MODE -1 16#define OF_USE_NATIVE_MODE -1
16 17
18int of_get_display_timing(struct device_node *np, const char *name,
19 struct display_timing *dt);
17struct display_timings *of_get_display_timings(struct device_node *np); 20struct display_timings *of_get_display_timings(struct device_node *np);
18int of_display_timings_exist(struct device_node *np); 21int of_display_timings_exist(struct device_node *np);
19 22
diff --git a/include/video/omap-panel-data.h b/include/video/omap-panel-data.h
index 0c3b46d3daf3..6b2366fb6e53 100644
--- a/include/video/omap-panel-data.h
+++ b/include/video/omap-panel-data.h
@@ -27,6 +27,9 @@
27#ifndef __OMAP_PANEL_DATA_H 27#ifndef __OMAP_PANEL_DATA_H
28#define __OMAP_PANEL_DATA_H 28#define __OMAP_PANEL_DATA_H
29 29
30#include <video/omapdss.h>
31#include <video/display_timing.h>
32
30struct omap_dss_device; 33struct omap_dss_device;
31 34
32/** 35/**
@@ -147,4 +150,210 @@ struct panel_tpo_td043_data {
147 int nreset_gpio; 150 int nreset_gpio;
148}; 151};
149 152
153/**
154 * encoder_tfp410 platform data
155 * @name: name for this display entity
156 * @power_down_gpio: gpio number for PD pin (or -1 if not available)
157 * @data_lines: number of DPI datalines
158 */
159struct encoder_tfp410_platform_data {
160 const char *name;
161 const char *source;
162 int power_down_gpio;
163 int data_lines;
164};
165
166/**
167 * encoder_tpd12s015 platform data
168 * @name: name for this display entity
169 * @ct_cp_hpd_gpio: CT_CP_HPD gpio number
170 * @ls_oe_gpio: LS_OE gpio number
171 * @hpd_gpio: HPD gpio number
172 */
173struct encoder_tpd12s015_platform_data {
174 const char *name;
175 const char *source;
176
177 int ct_cp_hpd_gpio;
178 int ls_oe_gpio;
179 int hpd_gpio;
180};
181
182/**
183 * connector_dvi platform data
184 * @name: name for this display entity
185 * @source: name of the display entity used as a video source
186 * @i2c_bus_num: i2c bus number to be used for reading EDID
187 */
188struct connector_dvi_platform_data {
189 const char *name;
190 const char *source;
191 int i2c_bus_num;
192};
193
194/**
195 * connector_hdmi platform data
196 * @name: name for this display entity
197 * @source: name of the display entity used as a video source
198 */
199struct connector_hdmi_platform_data {
200 const char *name;
201 const char *source;
202};
203
204/**
205 * connector_atv platform data
206 * @name: name for this display entity
207 * @source: name of the display entity used as a video source
208 * @connector_type: composite/svideo
209 * @invert_polarity: invert signal polarity
210 */
211struct connector_atv_platform_data {
212 const char *name;
213 const char *source;
214
215 enum omap_dss_venc_type connector_type;
216 bool invert_polarity;
217};
218
219/**
220 * panel_dpi platform data
221 * @name: name for this display entity
222 * @source: name of the display entity used as a video source
223 * @data_lines: number of DPI datalines
224 * @display_timing: timings for this panel
225 * @backlight_gpio: gpio to enable/disable the backlight (or -1)
226 * @enable_gpio: gpio to enable/disable the panel (or -1)
227 */
228struct panel_dpi_platform_data {
229 const char *name;
230 const char *source;
231
232 int data_lines;
233
234 const struct display_timing *display_timing;
235
236 int backlight_gpio;
237 int enable_gpio;
238};
239
240/**
241 * panel_dsicm platform data
242 * @name: name for this display entity
243 * @source: name of the display entity used as a video source
244 * @reset_gpio: gpio to reset the panel (or -1)
245 * @use_ext_te: use external TE GPIO
246 * @ext_te_gpio: external TE GPIO
247 * @ulps_timeout: time to wait before entering ULPS, 0 = disabled (ms)
248 * @use_dsi_backlight: true if panel uses DSI command to control backlight
249 * @pin_config: DSI pin configuration
250 */
251struct panel_dsicm_platform_data {
252 const char *name;
253 const char *source;
254
255 int reset_gpio;
256
257 bool use_ext_te;
258 int ext_te_gpio;
259
260 unsigned ulps_timeout;
261
262 bool use_dsi_backlight;
263
264 struct omap_dsi_pin_config pin_config;
265};
266
267/**
268 * panel_acx565akm platform data
269 * @name: name for this display entity
270 * @source: name of the display entity used as a video source
271 * @reset_gpio: gpio to reset the panel (or -1)
272 * @datapairs: number of SDI datapairs
273 */
274struct panel_acx565akm_platform_data {
275 const char *name;
276 const char *source;
277
278 int reset_gpio;
279
280 int datapairs;
281};
282
283/**
284 * panel_lb035q02 platform data
285 * @name: name for this display entity
286 * @source: name of the display entity used as a video source
287 * @data_lines: number of DPI datalines
288 * @backlight_gpio: gpio to enable/disable the backlight (or -1)
289 * @enable_gpio: gpio to enable/disable the panel (or -1)
290 */
291struct panel_lb035q02_platform_data {
292 const char *name;
293 const char *source;
294
295 int data_lines;
296
297 int backlight_gpio;
298 int enable_gpio;
299};
300
301/**
302 * panel_sharp_ls037v7dw01 platform data
303 * @name: name for this display entity
304 * @source: name of the display entity used as a video source
305 * @data_lines: number of DPI datalines
306 * @resb_gpio: reset signal GPIO
307 * @ini_gpio: power on control GPIO
308 * @mo_gpio: selection for resolution(VGA/QVGA) GPIO
309 * @lr_gpio: selection for horizontal scanning direction GPIO
310 * @ud_gpio: selection for vertical scanning direction GPIO
311 */
312struct panel_sharp_ls037v7dw01_platform_data {
313 const char *name;
314 const char *source;
315
316 int data_lines;
317
318 int resb_gpio;
319 int ini_gpio;
320 int mo_gpio;
321 int lr_gpio;
322 int ud_gpio;
323};
324
325/**
326 * panel-tpo-td043mtea1 platform data
327 * @name: name for this display entity
328 * @source: name of the display entity used as a video source
329 * @data_lines: number of DPI datalines
330 * @nreset_gpio: reset signal
331 */
332struct panel_tpo_td043mtea1_platform_data {
333 const char *name;
334 const char *source;
335
336 int data_lines;
337
338 int nreset_gpio;
339};
340
341/**
342 * panel-nec-nl8048hl11 platform data
343 * @name: name for this display entity
344 * @source: name of the display entity used as a video source
345 * @data_lines: number of DPI datalines
346 * @res_gpio: reset signal
347 * @qvga_gpio: selection for resolution(QVGA/WVGA)
348 */
349struct panel_nec_nl8048hl11_platform_data {
350 const char *name;
351 const char *source;
352
353 int data_lines;
354
355 int res_gpio;
356 int qvga_gpio;
357};
358
150#endif /* __OMAP_PANEL_DATA_H */ 359#endif /* __OMAP_PANEL_DATA_H */
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index aeb4e9a0c5d1..b39463553845 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -23,6 +23,8 @@
23#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25 25
26#include <video/videomode.h>
27
26#define DISPC_IRQ_FRAMEDONE (1 << 0) 28#define DISPC_IRQ_FRAMEDONE (1 << 0)
27#define DISPC_IRQ_VSYNC (1 << 1) 29#define DISPC_IRQ_VSYNC (1 << 1)
28#define DISPC_IRQ_EVSYNC_EVEN (1 << 2) 30#define DISPC_IRQ_EVSYNC_EVEN (1 << 2)
@@ -68,6 +70,7 @@ enum omap_display_type {
68 OMAP_DISPLAY_TYPE_DSI = 1 << 3, 70 OMAP_DISPLAY_TYPE_DSI = 1 << 3,
69 OMAP_DISPLAY_TYPE_VENC = 1 << 4, 71 OMAP_DISPLAY_TYPE_VENC = 1 << 4,
70 OMAP_DISPLAY_TYPE_HDMI = 1 << 5, 72 OMAP_DISPLAY_TYPE_HDMI = 1 << 5,
73 OMAP_DISPLAY_TYPE_DVI = 1 << 6,
71}; 74};
72 75
73enum omap_plane { 76enum omap_plane {
@@ -169,6 +172,11 @@ enum omap_dss_audio_state {
169 OMAP_DSS_AUDIO_PLAYING, 172 OMAP_DSS_AUDIO_PLAYING,
170}; 173};
171 174
175struct omap_dss_audio {
176 struct snd_aes_iec958 *iec;
177 struct snd_cea_861_aud_if *cea;
178};
179
172enum omap_dss_rotation_type { 180enum omap_dss_rotation_type {
173 OMAP_DSS_ROT_DMA = 1 << 0, 181 OMAP_DSS_ROT_DMA = 1 << 0,
174 OMAP_DSS_ROT_VRFB = 1 << 1, 182 OMAP_DSS_ROT_VRFB = 1 << 1,
@@ -365,6 +373,7 @@ struct omap_dss_board_info {
365 int num_devices; 373 int num_devices;
366 struct omap_dss_device **devices; 374 struct omap_dss_device **devices;
367 struct omap_dss_device *default_device; 375 struct omap_dss_device *default_device;
376 const char *default_display_name;
368 int (*dsi_enable_pads)(int dsi_id, unsigned lane_mask); 377 int (*dsi_enable_pads)(int dsi_id, unsigned lane_mask);
369 void (*dsi_disable_pads)(int dsi_id, unsigned lane_mask); 378 void (*dsi_disable_pads)(int dsi_id, unsigned lane_mask);
370 int (*set_min_bus_tput)(struct device *dev, unsigned long r); 379 int (*set_min_bus_tput)(struct device *dev, unsigned long r);
@@ -512,7 +521,7 @@ struct omap_overlay_manager {
512 enum omap_dss_output_id supported_outputs; 521 enum omap_dss_output_id supported_outputs;
513 522
514 /* dynamic fields */ 523 /* dynamic fields */
515 struct omap_dss_output *output; 524 struct omap_dss_device *output;
516 525
517 /* 526 /*
518 * The following functions do not block: 527 * The following functions do not block:
@@ -526,7 +535,7 @@ struct omap_overlay_manager {
526 */ 535 */
527 536
528 int (*set_output)(struct omap_overlay_manager *mgr, 537 int (*set_output)(struct omap_overlay_manager *mgr,
529 struct omap_dss_output *output); 538 struct omap_dss_device *output);
530 int (*unset_output)(struct omap_overlay_manager *mgr); 539 int (*unset_output)(struct omap_overlay_manager *mgr);
531 540
532 int (*set_manager_info)(struct omap_overlay_manager *mgr, 541 int (*set_manager_info)(struct omap_overlay_manager *mgr,
@@ -569,33 +578,192 @@ struct omap_dss_writeback_info {
569 u8 pre_mult_alpha; 578 u8 pre_mult_alpha;
570}; 579};
571 580
572struct omap_dss_output { 581struct omapdss_dpi_ops {
573 struct list_head list; 582 int (*connect)(struct omap_dss_device *dssdev,
583 struct omap_dss_device *dst);
584 void (*disconnect)(struct omap_dss_device *dssdev,
585 struct omap_dss_device *dst);
574 586
575 const char *name; 587 int (*enable)(struct omap_dss_device *dssdev);
588 void (*disable)(struct omap_dss_device *dssdev);
576 589
577 /* display type supported by the output */ 590 int (*check_timings)(struct omap_dss_device *dssdev,
578 enum omap_display_type type; 591 struct omap_video_timings *timings);
592 void (*set_timings)(struct omap_dss_device *dssdev,
593 struct omap_video_timings *timings);
594 void (*get_timings)(struct omap_dss_device *dssdev,
595 struct omap_video_timings *timings);
579 596
580 /* DISPC channel for this output */ 597 void (*set_data_lines)(struct omap_dss_device *dssdev, int data_lines);
581 enum omap_channel dispc_channel; 598};
582 599
583 /* output instance */ 600struct omapdss_sdi_ops {
584 enum omap_dss_output_id id; 601 int (*connect)(struct omap_dss_device *dssdev,
602 struct omap_dss_device *dst);
603 void (*disconnect)(struct omap_dss_device *dssdev,
604 struct omap_dss_device *dst);
585 605
586 /* output's platform device pointer */ 606 int (*enable)(struct omap_dss_device *dssdev);
587 struct platform_device *pdev; 607 void (*disable)(struct omap_dss_device *dssdev);
588 608
589 /* dynamic fields */ 609 int (*check_timings)(struct omap_dss_device *dssdev,
590 struct omap_overlay_manager *manager; 610 struct omap_video_timings *timings);
611 void (*set_timings)(struct omap_dss_device *dssdev,
612 struct omap_video_timings *timings);
613 void (*get_timings)(struct omap_dss_device *dssdev,
614 struct omap_video_timings *timings);
591 615
592 struct omap_dss_device *device; 616 void (*set_datapairs)(struct omap_dss_device *dssdev, int datapairs);
617};
618
619struct omapdss_dvi_ops {
620 int (*connect)(struct omap_dss_device *dssdev,
621 struct omap_dss_device *dst);
622 void (*disconnect)(struct omap_dss_device *dssdev,
623 struct omap_dss_device *dst);
624
625 int (*enable)(struct omap_dss_device *dssdev);
626 void (*disable)(struct omap_dss_device *dssdev);
627
628 int (*check_timings)(struct omap_dss_device *dssdev,
629 struct omap_video_timings *timings);
630 void (*set_timings)(struct omap_dss_device *dssdev,
631 struct omap_video_timings *timings);
632 void (*get_timings)(struct omap_dss_device *dssdev,
633 struct omap_video_timings *timings);
634};
635
636struct omapdss_atv_ops {
637 int (*connect)(struct omap_dss_device *dssdev,
638 struct omap_dss_device *dst);
639 void (*disconnect)(struct omap_dss_device *dssdev,
640 struct omap_dss_device *dst);
641
642 int (*enable)(struct omap_dss_device *dssdev);
643 void (*disable)(struct omap_dss_device *dssdev);
644
645 int (*check_timings)(struct omap_dss_device *dssdev,
646 struct omap_video_timings *timings);
647 void (*set_timings)(struct omap_dss_device *dssdev,
648 struct omap_video_timings *timings);
649 void (*get_timings)(struct omap_dss_device *dssdev,
650 struct omap_video_timings *timings);
651
652 void (*set_type)(struct omap_dss_device *dssdev,
653 enum omap_dss_venc_type type);
654 void (*invert_vid_out_polarity)(struct omap_dss_device *dssdev,
655 bool invert_polarity);
656
657 int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
658 u32 (*get_wss)(struct omap_dss_device *dssdev);
659};
660
661struct omapdss_hdmi_ops {
662 int (*connect)(struct omap_dss_device *dssdev,
663 struct omap_dss_device *dst);
664 void (*disconnect)(struct omap_dss_device *dssdev,
665 struct omap_dss_device *dst);
666
667 int (*enable)(struct omap_dss_device *dssdev);
668 void (*disable)(struct omap_dss_device *dssdev);
669
670 int (*check_timings)(struct omap_dss_device *dssdev,
671 struct omap_video_timings *timings);
672 void (*set_timings)(struct omap_dss_device *dssdev,
673 struct omap_video_timings *timings);
674 void (*get_timings)(struct omap_dss_device *dssdev,
675 struct omap_video_timings *timings);
676
677 int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
678 bool (*detect)(struct omap_dss_device *dssdev);
679
680 /*
681 * Note: These functions might sleep. Do not call while
682 * holding a spinlock/readlock.
683 */
684 int (*audio_enable)(struct omap_dss_device *dssdev);
685 void (*audio_disable)(struct omap_dss_device *dssdev);
686 bool (*audio_supported)(struct omap_dss_device *dssdev);
687 int (*audio_config)(struct omap_dss_device *dssdev,
688 struct omap_dss_audio *audio);
689 /* Note: These functions may not sleep */
690 int (*audio_start)(struct omap_dss_device *dssdev);
691 void (*audio_stop)(struct omap_dss_device *dssdev);
692};
693
694struct omapdss_dsi_ops {
695 int (*connect)(struct omap_dss_device *dssdev,
696 struct omap_dss_device *dst);
697 void (*disconnect)(struct omap_dss_device *dssdev,
698 struct omap_dss_device *dst);
699
700 int (*enable)(struct omap_dss_device *dssdev);
701 void (*disable)(struct omap_dss_device *dssdev, bool disconnect_lanes,
702 bool enter_ulps);
703
704 /* bus configuration */
705 int (*set_config)(struct omap_dss_device *dssdev,
706 const struct omap_dss_dsi_config *cfg);
707 int (*configure_pins)(struct omap_dss_device *dssdev,
708 const struct omap_dsi_pin_config *pin_cfg);
709
710 void (*enable_hs)(struct omap_dss_device *dssdev, int channel,
711 bool enable);
712 int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
713
714 int (*update)(struct omap_dss_device *dssdev, int channel,
715 void (*callback)(int, void *), void *data);
716
717 void (*bus_lock)(struct omap_dss_device *dssdev);
718 void (*bus_unlock)(struct omap_dss_device *dssdev);
719
720 int (*enable_video_output)(struct omap_dss_device *dssdev, int channel);
721 void (*disable_video_output)(struct omap_dss_device *dssdev,
722 int channel);
723
724 int (*request_vc)(struct omap_dss_device *dssdev, int *channel);
725 int (*set_vc_id)(struct omap_dss_device *dssdev, int channel,
726 int vc_id);
727 void (*release_vc)(struct omap_dss_device *dssdev, int channel);
728
729 /* data transfer */
730 int (*dcs_write)(struct omap_dss_device *dssdev, int channel,
731 u8 *data, int len);
732 int (*dcs_write_nosync)(struct omap_dss_device *dssdev, int channel,
733 u8 *data, int len);
734 int (*dcs_read)(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
735 u8 *data, int len);
736
737 int (*gen_write)(struct omap_dss_device *dssdev, int channel,
738 u8 *data, int len);
739 int (*gen_write_nosync)(struct omap_dss_device *dssdev, int channel,
740 u8 *data, int len);
741 int (*gen_read)(struct omap_dss_device *dssdev, int channel,
742 u8 *reqdata, int reqlen,
743 u8 *data, int len);
744
745 int (*bta_sync)(struct omap_dss_device *dssdev, int channel);
746
747 int (*set_max_rx_packet_size)(struct omap_dss_device *dssdev,
748 int channel, u16 plen);
593}; 749};
594 750
595struct omap_dss_device { 751struct omap_dss_device {
596 struct device dev; 752 /* old device, to be removed */
753 struct device old_dev;
754
755 /* new device, pointer to panel device */
756 struct device *dev;
757
758 struct module *owner;
759
760 struct list_head panel_list;
761
762 /* alias in the form of "display%d" */
763 char alias[16];
597 764
598 enum omap_display_type type; 765 enum omap_display_type type;
766 enum omap_display_type output_type;
599 767
600 /* obsolete, to be removed */ 768 /* obsolete, to be removed */
601 enum omap_channel channel; 769 enum omap_channel channel;
@@ -616,9 +784,6 @@ struct omap_dss_device {
616 784
617 struct { 785 struct {
618 int module; 786 int module;
619
620 bool ext_te;
621 u8 ext_te_gpio;
622 } dsi; 787 } dsi;
623 788
624 struct { 789 struct {
@@ -639,10 +804,6 @@ struct omap_dss_device {
639 struct rfbi_timings rfbi_timings; 804 struct rfbi_timings rfbi_timings;
640 } ctrl; 805 } ctrl;
641 806
642 int reset_gpio;
643
644 int max_backlight_level;
645
646 const char *name; 807 const char *name;
647 808
648 /* used to match device to driver */ 809 /* used to match device to driver */
@@ -652,22 +813,40 @@ struct omap_dss_device {
652 813
653 struct omap_dss_driver *driver; 814 struct omap_dss_driver *driver;
654 815
816 union {
817 const struct omapdss_dpi_ops *dpi;
818 const struct omapdss_sdi_ops *sdi;
819 const struct omapdss_dvi_ops *dvi;
820 const struct omapdss_hdmi_ops *hdmi;
821 const struct omapdss_atv_ops *atv;
822 const struct omapdss_dsi_ops *dsi;
823 } ops;
824
655 /* helper variable for driver suspend/resume */ 825 /* helper variable for driver suspend/resume */
656 bool activate_after_resume; 826 bool activate_after_resume;
657 827
658 enum omap_display_caps caps; 828 enum omap_display_caps caps;
659 829
660 struct omap_dss_output *output; 830 struct omap_dss_device *output;
661 831
662 enum omap_dss_display_state state; 832 enum omap_dss_display_state state;
663 833
664 enum omap_dss_audio_state audio_state; 834 enum omap_dss_audio_state audio_state;
665 835
666 /* platform specific */ 836 /* OMAP DSS output specific fields */
667 int (*platform_enable)(struct omap_dss_device *dssdev); 837
668 void (*platform_disable)(struct omap_dss_device *dssdev); 838 struct list_head list;
669 int (*set_backlight)(struct omap_dss_device *dssdev, int level); 839
670 int (*get_backlight)(struct omap_dss_device *dssdev); 840 /* DISPC channel for this output */
841 enum omap_channel dispc_channel;
842
843 /* output instance */
844 enum omap_dss_output_id id;
845
846 /* dynamic fields */
847 struct omap_overlay_manager *manager;
848
849 struct omap_dss_device *device;
671}; 850};
672 851
673struct omap_dss_hdmi_data 852struct omap_dss_hdmi_data
@@ -677,17 +856,15 @@ struct omap_dss_hdmi_data
677 int hpd_gpio; 856 int hpd_gpio;
678}; 857};
679 858
680struct omap_dss_audio {
681 struct snd_aes_iec958 *iec;
682 struct snd_cea_861_aud_if *cea;
683};
684
685struct omap_dss_driver { 859struct omap_dss_driver {
686 struct device_driver driver; 860 struct device_driver driver;
687 861
688 int (*probe)(struct omap_dss_device *); 862 int (*probe)(struct omap_dss_device *);
689 void (*remove)(struct omap_dss_device *); 863 void (*remove)(struct omap_dss_device *);
690 864
865 int (*connect)(struct omap_dss_device *dssdev);
866 void (*disconnect)(struct omap_dss_device *dssdev);
867
691 int (*enable)(struct omap_dss_device *display); 868 int (*enable)(struct omap_dss_device *display);
692 void (*disable)(struct omap_dss_device *display); 869 void (*disable)(struct omap_dss_device *display);
693 int (*run_test)(struct omap_dss_device *display, int test); 870 int (*run_test)(struct omap_dss_device *display, int test);
@@ -753,7 +930,10 @@ bool omapdss_is_initialized(void);
753int omap_dss_register_driver(struct omap_dss_driver *); 930int omap_dss_register_driver(struct omap_dss_driver *);
754void omap_dss_unregister_driver(struct omap_dss_driver *); 931void omap_dss_unregister_driver(struct omap_dss_driver *);
755 932
756void omap_dss_get_device(struct omap_dss_device *dssdev); 933int omapdss_register_display(struct omap_dss_device *dssdev);
934void omapdss_unregister_display(struct omap_dss_device *dssdev);
935
936struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev);
757void omap_dss_put_device(struct omap_dss_device *dssdev); 937void omap_dss_put_device(struct omap_dss_device *dssdev);
758#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL) 938#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL)
759struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from); 939struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from);
@@ -761,8 +941,10 @@ struct omap_dss_device *omap_dss_find_device(void *data,
761 int (*match)(struct omap_dss_device *dssdev, void *data)); 941 int (*match)(struct omap_dss_device *dssdev, void *data));
762const char *omapdss_get_default_display_name(void); 942const char *omapdss_get_default_display_name(void);
763 943
764int omap_dss_start_device(struct omap_dss_device *dssdev); 944void videomode_to_omap_video_timings(const struct videomode *vm,
765void omap_dss_stop_device(struct omap_dss_device *dssdev); 945 struct omap_video_timings *ovt);
946void omap_video_timings_to_videomode(const struct omap_video_timings *ovt,
947 struct videomode *vm);
766 948
767int dss_feat_get_num_mgrs(void); 949int dss_feat_get_num_mgrs(void);
768int dss_feat_get_num_ovls(void); 950int dss_feat_get_num_ovls(void);
@@ -778,10 +960,17 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
778int omap_dss_get_num_overlays(void); 960int omap_dss_get_num_overlays(void);
779struct omap_overlay *omap_dss_get_overlay(int num); 961struct omap_overlay *omap_dss_get_overlay(int num);
780 962
781struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id); 963int omapdss_register_output(struct omap_dss_device *output);
782int omapdss_output_set_device(struct omap_dss_output *out, 964void omapdss_unregister_output(struct omap_dss_device *output);
965struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id);
966struct omap_dss_device *omap_dss_find_output(const char *name);
967struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node);
968int omapdss_output_set_device(struct omap_dss_device *out,
783 struct omap_dss_device *dssdev); 969 struct omap_dss_device *dssdev);
784int omapdss_output_unset_device(struct omap_dss_output *out); 970int omapdss_output_unset_device(struct omap_dss_device *out);
971
972struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev);
973struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev);
785 974
786void omapdss_default_get_resolution(struct omap_dss_device *dssdev, 975void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
787 u16 *xres, u16 *yres); 976 u16 *xres, u16 *yres);
@@ -832,7 +1021,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
832 bool mem_to_mem); 1021 bool mem_to_mem);
833 1022
834#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver) 1023#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
835#define to_dss_device(x) container_of((x), struct omap_dss_device, dev) 1024#define to_dss_device(x) container_of((x), struct omap_dss_device, old_dev)
836 1025
837void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, 1026void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
838 bool enable); 1027 bool enable);
@@ -883,6 +1072,11 @@ int omapdss_compat_init(void);
883void omapdss_compat_uninit(void); 1072void omapdss_compat_uninit(void);
884 1073
885struct dss_mgr_ops { 1074struct dss_mgr_ops {
1075 int (*connect)(struct omap_overlay_manager *mgr,
1076 struct omap_dss_device *dst);
1077 void (*disconnect)(struct omap_overlay_manager *mgr,
1078 struct omap_dss_device *dst);
1079
886 void (*start_update)(struct omap_overlay_manager *mgr); 1080 void (*start_update)(struct omap_overlay_manager *mgr);
887 int (*enable)(struct omap_overlay_manager *mgr); 1081 int (*enable)(struct omap_overlay_manager *mgr);
888 void (*disable)(struct omap_overlay_manager *mgr); 1082 void (*disable)(struct omap_overlay_manager *mgr);
@@ -899,6 +1093,10 @@ struct dss_mgr_ops {
899int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops); 1093int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops);
900void dss_uninstall_mgr_ops(void); 1094void dss_uninstall_mgr_ops(void);
901 1095
1096int dss_mgr_connect(struct omap_overlay_manager *mgr,
1097 struct omap_dss_device *dst);
1098void dss_mgr_disconnect(struct omap_overlay_manager *mgr,
1099 struct omap_dss_device *dst);
902void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 1100void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
903 const struct omap_video_timings *timings); 1101 const struct omap_video_timings *timings);
904void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, 1102void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
@@ -910,4 +1108,15 @@ int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
910 void (*handler)(void *), void *data); 1108 void (*handler)(void *), void *data);
911void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr, 1109void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
912 void (*handler)(void *), void *data); 1110 void (*handler)(void *), void *data);
1111
1112static inline bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
1113{
1114 return dssdev->output;
1115}
1116
1117static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev)
1118{
1119 return dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
1120}
1121
913#endif 1122#endif