ARM: tegra: loki: fix build error due to warning
[linux-3.10.git] / arch / arm / mach-tegra / panel-lgd-wxga-7-0.c
1 /*
2  * arch/arm/mach-tegra/panel-lgd-wxga-7-0.c
3  *
4  * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <linux/delay.h>
20 #include <linux/gpio.h>
21 #include <linux/tegra_pwm_bl.h>
22 #include <linux/regulator/consumer.h>
23 #include <linux/pwm_backlight.h>
24 #include <linux/max8831_backlight.h>
25 #include <linux/leds.h>
26 #include <linux/ioport.h>
27
28 #include <mach/dc.h>
29
30 #include "board.h"
31 #include "board-panel.h"
32 #include "devices.h"
33 #include "gpio-names.h"
34 #include "tegra11_host1x_devices.h"
35
36
37 #define DSI_PANEL_RESET         0
38 #define DSI_PANEL_BL_PWM        TEGRA_GPIO_PH1
39 #define DC_CTRL_MODE    TEGRA_DC_OUT_CONTINUOUS_MODE
40
41 static bool reg_requested;
42 static bool gpio_requested;
43 static struct platform_device *disp_device;
44 static struct regulator *avdd_lcd_3v3;
45 static struct regulator *vdd_lcd_bl_en;
46
47 static struct tegra_dsi_cmd dsi_lgd_wxga_7_0_init_cmd[] = {
48         DSI_CMD_SHORT(0x15, 0x01, 0x0),
49         DSI_DLY_MS(20),
50         DSI_CMD_SHORT(0x15, 0xAE, 0x0B),
51         DSI_CMD_SHORT(0x15, 0xEE, 0xEA),
52         DSI_CMD_SHORT(0x15, 0xEF, 0x5F),
53         DSI_CMD_SHORT(0x15, 0xF2, 0x68),
54         DSI_CMD_SHORT(0x15, 0xEE, 0x0),
55         DSI_CMD_SHORT(0x15, 0xEF, 0x0),
56 };
57
58 static struct tegra_dsi_cmd dsi_lgd_wxga_7_0_late_resume_cmd[] = {
59         DSI_CMD_SHORT(0x15, 0x10, 0x0),
60         DSI_DLY_MS(120),
61 };
62
63 static struct tegra_dsi_cmd dsi_lgd_wxga_7_0_early_suspend_cmd[] = {
64         DSI_CMD_SHORT(0x15, 0x11, 0x0),
65         DSI_DLY_MS(160),
66 };
67
68 static struct tegra_dsi_cmd dsi_lgd_wxga_7_0_suspend_cmd[] = {
69         DSI_CMD_SHORT(0x15, 0x11, 0x0),
70         DSI_DLY_MS(160),
71 };
72
73 static struct tegra_dsi_out dsi_lgd_wxga_7_0_pdata = {
74 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
75         .n_data_lanes = 2,
76         .controller_vs = DSI_VS_0,
77 #else
78         .controller_vs = DSI_VS_1,
79 #endif
80
81         .n_data_lanes = 4,
82         .video_burst_mode = TEGRA_DSI_VIDEO_NONE_BURST_MODE,
83
84         .pixel_format = TEGRA_DSI_PIXEL_FORMAT_24BIT_P,
85         .refresh_rate = 60,
86         .virtual_channel = TEGRA_DSI_VIRTUAL_CHANNEL_0,
87
88         .dsi_instance = DSI_INSTANCE_0,
89
90         .panel_reset = DSI_PANEL_RESET,
91         .power_saving_suspend = true,
92         .video_data_type = TEGRA_DSI_VIDEO_TYPE_VIDEO_MODE,
93
94         .video_clock_mode = TEGRA_DSI_VIDEO_CLOCK_CONTINUOUS,
95
96         .dsi_init_cmd = dsi_lgd_wxga_7_0_init_cmd,
97         .n_init_cmd = ARRAY_SIZE(dsi_lgd_wxga_7_0_init_cmd),
98
99         .dsi_early_suspend_cmd = dsi_lgd_wxga_7_0_early_suspend_cmd,
100         .n_early_suspend_cmd = ARRAY_SIZE(dsi_lgd_wxga_7_0_early_suspend_cmd),
101
102         .dsi_late_resume_cmd = dsi_lgd_wxga_7_0_late_resume_cmd,
103         .n_late_resume_cmd = ARRAY_SIZE(dsi_lgd_wxga_7_0_late_resume_cmd),
104
105         .dsi_suspend_cmd = dsi_lgd_wxga_7_0_suspend_cmd,
106         .n_suspend_cmd = ARRAY_SIZE(dsi_lgd_wxga_7_0_suspend_cmd),
107 };
108
109 static int tegratab_dsi_regulator_get(struct device *dev)
110 {
111         int err = 0;
112
113         if (reg_requested)
114                 return 0;
115         avdd_lcd_3v3 = regulator_get(dev, "avdd_lcd");
116         if (IS_ERR_OR_NULL(avdd_lcd_3v3)) {
117                 pr_err("avdd_lcd regulator get failed\n");
118                 err = PTR_ERR(avdd_lcd_3v3);
119                 avdd_lcd_3v3 = NULL;
120                 goto fail;
121         }
122
123         vdd_lcd_bl_en = regulator_get(dev, "vdd_lcd_bl_en");
124         if (IS_ERR_OR_NULL(vdd_lcd_bl_en)) {
125                 pr_err("vdd_lcd_bl_en regulator get failed\n");
126                 err = PTR_ERR(vdd_lcd_bl_en);
127                 vdd_lcd_bl_en = NULL;
128                 goto fail;
129         }
130         reg_requested = true;
131         return 0;
132 fail:
133         return err;
134 }
135
136 static int tegratab_dsi_gpio_get(void)
137 {
138         int err = 0;
139
140         if (gpio_requested)
141                 return 0;
142
143         /* free pwm GPIO */
144         err = gpio_request(DSI_PANEL_BL_PWM, "panel pwm");
145         if (err < 0) {
146                 pr_err("panel pwm gpio request failed\n");
147                 goto fail;
148         }
149         gpio_free(DSI_PANEL_BL_PWM);
150         gpio_requested = true;
151         return 0;
152 fail:
153         return err;
154 }
155
156 static int dsi_lgd_wxga_7_0_enable(struct device *dev)
157 {
158         int err = 0;
159
160         err = tegratab_dsi_regulator_get(dev);
161
162         if (err < 0) {
163                 pr_err("dsi regulator get failed\n");
164                 goto fail;
165         }
166
167         err = tegratab_dsi_gpio_get();
168
169         if (err < 0) {
170                 pr_err("dsi gpio request failed\n");
171                 goto fail;
172         }
173
174         /*
175          * Turning on 1.8V then AVDD after 5ms is required per spec.
176          */
177         msleep(20);
178
179         if (avdd_lcd_3v3) {
180                 err = regulator_enable(avdd_lcd_3v3);
181                 if (err < 0) {
182                         pr_err("avdd_lcd regulator enable failed\n");
183                         goto fail;
184                 }
185                 regulator_set_voltage(avdd_lcd_3v3, 3300000, 3300000);
186         }
187
188         msleep(150);
189         if (vdd_lcd_bl_en) {
190                 err = regulator_enable(vdd_lcd_bl_en);
191                 if (err < 0) {
192                         pr_err("vdd_lcd_bl_en regulator enable failed\n");
193                         goto fail;
194                 }
195         }
196
197         msleep(100);
198 #if DSI_PANEL_RESET
199 /*
200  * Nothing is requested.
201  */
202 #endif
203
204         return 0;
205 fail:
206         return err;
207 }
208
209 static int dsi_lgd_wxga_7_0_disable(void)
210 {
211         if (vdd_lcd_bl_en)
212                 regulator_disable(vdd_lcd_bl_en);
213
214         if (avdd_lcd_3v3)
215                 regulator_disable(avdd_lcd_3v3);
216
217         return 0;
218 }
219
220 static int dsi_lgd_wxga_7_0_postsuspend(void)
221 {
222         return 0;
223 }
224
225 /*
226  * See display standard timings and a few constraints underneath
227  * \vendor\nvidia\tegra\core\drivers\hwinc
228  *
229  * Class: Display Standard Timings
230  *
231  * Programming of display timing registers must meet these restrictions:
232  * Constraint 1: H_REF_TO_SYNC + H_SYNC_WIDTH + H_BACK_PORCH > 11.
233  * Constraint 2: V_REF_TO_SYNC + V_SYNC_WIDTH + V_BACK_PORCH > 1.
234  * Constraint 3: V_FRONT_PORCH + V_SYNC_WIDTH +
235                                 V_BACK_PORCH > 1 (vertical blank).
236  * Constraint 4: V_SYNC_WIDTH >= 1, H_SYNC_WIDTH >= 1
237  * Constraint 5: V_REF_TO_SYNC >= 1, H_REF_TO_SYNC >= 0
238  * Constraint 6: V_FRONT_PORT >= (V_REF_TO_SYNC + 1),
239                                 H_FRONT_PORT >= (H_REF_TO_SYNC + 1)
240  * Constraint 7: H_DISP_ACTIVE >= 16, V_DISP_ACTIVE >= 16
241  */
242
243 /*
244  * how to determine pclk
245  * h_total =
246  * Horiz_BackPorch + Horiz_SyncWidth + Horiz_DispActive + Horiz_FrontPorch;
247  *
248  * v_total =
249  * Vert_BackPorch + Vert_SyncWidth + Vert_DispActive + Vert_FrontPorch;
250  * panel_freq = ( h_total * v_total * refresh_freq );
251  * h_total = 40 + 8 + 800 + 16 = 864
252  * v_total = 2 + 1 + 1280 + 5 = 1288
253  * panel_freq = 864 * 1288 * 60 = 66769920  ==> let's set it to 67000000 !
254  */
255
256 static struct tegra_dc_mode dsi_lgd_wxga_7_0_modes[] = {
257         {
258                 .pclk = 67000000,
259                 .h_ref_to_sync = 10,
260                 .v_ref_to_sync = 1,
261                 .h_sync_width = 8,
262                 .v_sync_width = 1,
263                 .h_back_porch = 40, /*48 - 8(h_sync_width)*/
264                 .v_back_porch = 2, /*3 - 1(v_sync_width)*/
265                 .h_active = 800,
266                 .v_active = 1280,
267                 .h_front_porch = 16,
268                 .v_front_porch = 5,
269         },
270 };
271
272 static int dsi_lgd_wxga_7_0_bl_notify(struct device *unused, int brightness)
273 {
274         /*
275          * In early panel bring-up, we will
276          * not enable PRISM.
277          * Just use same brightness that is delivered from user side.
278          * TODO...
279          * use PRSIM brightness later.
280          */
281         if (brightness > 255) {
282                 pr_info("Error: Brightness > 255!\n");
283                 brightness = 255;
284         }
285         return brightness;
286 }
287
288 static int dsi_lgd_wxga_7_0_check_fb(struct device *dev, struct fb_info *info)
289 {
290         return info->device == &disp_device->dev;
291 }
292
293 static struct platform_pwm_backlight_data dsi_lgd_wxga_7_0_bl_data = {
294         .pwm_id         = 1,
295         .max_brightness = 255,
296         .dft_brightness = 224,
297         .pwm_period_ns  = 1000000,
298         .notify         = dsi_lgd_wxga_7_0_bl_notify,
299         /* Only toggle backlight on fb blank notifications for disp1 */
300         .check_fb       = dsi_lgd_wxga_7_0_check_fb,
301 };
302
303 static struct platform_device __maybe_unused
304                 dsi_lgd_wxga_7_0_bl_device __initdata = {
305         .name   = "pwm-backlight",
306         .id     = -1,
307         .dev    = {
308                 .platform_data = &dsi_lgd_wxga_7_0_bl_data,
309         },
310 };
311
312 static struct platform_device __maybe_unused
313                         *dsi_lgd_wxga_7_0_bl_devices[] __initdata = {
314         &tegra_pwfm_device,
315         &dsi_lgd_wxga_7_0_bl_device,
316 };
317
318 static int  __init dsi_lgd_wxga_7_0_register_bl_dev(void)
319 {
320         int err = 0;
321         err = platform_add_devices(dsi_lgd_wxga_7_0_bl_devices,
322                                 ARRAY_SIZE(dsi_lgd_wxga_7_0_bl_devices));
323         if (err) {
324                 pr_err("disp1 bl device registration failed");
325                 return err;
326         }
327         return err;
328 }
329
330 static void dsi_lgd_wxga_7_0_set_disp_device(
331         struct platform_device *display_device)
332 {
333         disp_device = display_device;
334 }
335
336 static void dsi_lgd_wxga_7_0_dc_out_init(struct tegra_dc_out *dc)
337 {
338         dc->dsi = &dsi_lgd_wxga_7_0_pdata;
339         dc->parent_clk = "pll_d_out0";
340         dc->modes = dsi_lgd_wxga_7_0_modes;
341         dc->n_modes = ARRAY_SIZE(dsi_lgd_wxga_7_0_modes);
342         dc->enable = dsi_lgd_wxga_7_0_enable;
343         dc->disable = dsi_lgd_wxga_7_0_disable;
344         dc->postsuspend = dsi_lgd_wxga_7_0_postsuspend,
345         dc->width = 94;
346         dc->height = 150;
347         dc->flags = DC_CTRL_MODE;
348 }
349
350 static void dsi_lgd_wxga_7_0_fb_data_init(struct tegra_fb_data *fb)
351 {
352         fb->xres = dsi_lgd_wxga_7_0_modes[0].h_active;
353         fb->yres = dsi_lgd_wxga_7_0_modes[0].v_active;
354 }
355
356 static void
357 dsi_lgd_wxga_7_0_sd_settings_init(struct tegra_dc_sd_settings *settings)
358 {
359         settings->bl_device_name = "pwm-backlight";
360 }
361
362 static void dsi_lgd_wxga_7_0_cmu_init(struct tegra_dc_platform_data *pdata)
363 {
364         pdata->cmu = NULL; /* will write CMU stuff after calibration */
365 }
366
367 struct tegra_panel __initdata dsi_lgd_wxga_7_0 = {
368         .init_sd_settings = dsi_lgd_wxga_7_0_sd_settings_init,
369         .init_dc_out = dsi_lgd_wxga_7_0_dc_out_init,
370         .init_fb_data = dsi_lgd_wxga_7_0_fb_data_init,
371         .register_bl_dev = dsi_lgd_wxga_7_0_register_bl_dev,
372         .init_cmu_data = dsi_lgd_wxga_7_0_cmu_init,
373         .set_disp_device = dsi_lgd_wxga_7_0_set_disp_device,
374 };
375 EXPORT_SYMBOL(dsi_lgd_wxga_7_0);
376