ARM: DT: Add DT entry for PWMs and Backlight
[linux-3.10.git] / arch / arm / mach-tegra / panel-a-edp-1080p-14-0.c
1 /*
2  * arch/arm/mach-tegra/panel-a-1080p-11-6.c
3  *
4  * Copyright (c) 2012-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 <mach/dc.h>
20 #include <linux/delay.h>
21 #include <linux/gpio.h>
22 #include <linux/tegra_pwm_bl.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/pwm_backlight.h>
25 #include <linux/max8831_backlight.h>
26 #include <linux/leds.h>
27 #include <linux/ioport.h>
28 #include "board.h"
29 #include "board-panel.h"
30 #include "devices.h"
31 #include "gpio-names.h"
32 #include "tegra12_host1x_devices.h"
33
34 #define DC_CTRL_MODE    TEGRA_DC_OUT_CONTINUOUS_MODE
35
36 #define EDP_PANEL_BL_PWM        TEGRA_GPIO_PH1
37
38 static bool reg_requested;
39 static bool gpio_requested;
40 static struct platform_device *disp_device;
41
42 static struct regulator *vdd_lcd_bl;
43 static struct regulator *vdd_lcd_bl_en;
44 static struct regulator *avdd_lcd;
45 static struct regulator *vdd_ds_1v8;
46
47 static tegra_dc_bl_output edp_a_1080p_14_0_bl_output_measured = {
48         0, 0, 1, 2, 3, 4, 5, 6,
49         7, 8, 9, 9, 10, 11, 12, 13,
50         13, 14, 15, 16, 17, 17, 18, 19,
51         20, 21, 22, 22, 23, 24, 25, 26,
52         27, 27, 28, 29, 30, 31, 32, 32,
53         33, 34, 35, 36, 37, 37, 38, 39,
54         40, 41, 42, 42, 43, 44, 45, 46,
55         47, 48, 48, 49, 50, 51, 52, 53,
56         54, 55, 56, 57, 57, 58, 59, 60,
57         61, 62, 63, 64, 65, 66, 67, 68,
58         69, 70, 71, 71, 72, 73, 74, 75,
59         76, 77, 77, 78, 79, 80, 81, 82,
60         83, 84, 85, 87, 88, 89, 90, 91,
61         92, 93, 94, 95, 96, 97, 98, 99,
62         100, 101, 102, 103, 104, 105, 106, 107,
63         108, 109, 110, 111, 112, 113, 115, 116,
64         117, 118, 119, 120, 121, 122, 123, 124,
65         125, 126, 127, 128, 129, 130, 131, 132,
66         133, 134, 135, 136, 137, 138, 139, 141,
67         142, 143, 144, 146, 147, 148, 149, 151,
68         152, 153, 154, 155, 156, 157, 158, 158,
69         159, 160, 161, 162, 163, 165, 166, 167,
70         168, 169, 170, 171, 172, 173, 174, 176,
71         177, 178, 179, 180, 182, 183, 184, 185,
72         186, 187, 188, 189, 190, 191, 192, 194,
73         195, 196, 197, 198, 199, 200, 201, 202,
74         203, 204, 205, 206, 207, 208, 209, 210,
75         211, 212, 213, 214, 215, 216, 217, 219,
76         220, 221, 222, 224, 225, 226, 227, 229,
77         230, 231, 232, 233, 234, 235, 236, 238,
78         239, 240, 241, 242, 243, 244, 245, 246,
79         247, 248, 249, 250, 251, 252, 253, 255
80 };
81
82 static int laguna_edp_regulator_get(struct device *dev)
83 {
84         int err = 0;
85
86         if (reg_requested)
87                 return 0;
88
89         vdd_ds_1v8 = regulator_get(dev, "vdd_ds_1v8");
90         if (IS_ERR_OR_NULL(vdd_ds_1v8)) {
91                 pr_err("vdd_ds_1v8 regulator get failed\n");
92                 err = PTR_ERR(vdd_ds_1v8);
93                 vdd_ds_1v8 = NULL;
94                 goto fail;
95         }
96
97         vdd_lcd_bl = regulator_get(dev, "vdd_lcd_bl");
98         if (IS_ERR_OR_NULL(vdd_lcd_bl)) {
99                 pr_err("vdd_lcd_bl regulator get failed\n");
100                 err = PTR_ERR(vdd_lcd_bl);
101                 vdd_lcd_bl = NULL;
102                 goto fail;
103         }
104
105         vdd_lcd_bl_en = regulator_get(dev, "vdd_lcd_bl_en");
106         if (IS_ERR_OR_NULL(vdd_lcd_bl_en)) {
107                 pr_err("vdd_lcd_bl_en regulator get failed\n");
108                 err = PTR_ERR(vdd_lcd_bl_en);
109                 vdd_lcd_bl_en = NULL;
110                 goto fail;
111         }
112
113         avdd_lcd = regulator_get(dev, "avdd_lcd");
114         if (IS_ERR_OR_NULL(avdd_lcd)) {
115                 pr_err("avdd_lcd regulator get failed\n");
116                 err = PTR_ERR(avdd_lcd);
117                 avdd_lcd = NULL;
118                 goto fail;
119         }
120
121         reg_requested = true;
122         return 0;
123 fail:
124         return err;
125 }
126
127 static int laguna_edp_gpio_get(void)
128 {
129         int err = 0;
130
131         if (gpio_requested)
132                 return 0;
133
134         err = gpio_request(EDP_PANEL_BL_PWM, "panel pwm");
135         if (err < 0) {
136                 pr_err("panel pwm gpio request failed\n");
137                 goto fail;
138         }
139         gpio_free(EDP_PANEL_BL_PWM);
140
141         gpio_requested = true;
142         return 0;
143 fail:
144         return err;
145 }
146
147 static int edp_a_1080p_14_0_enable(struct device *dev)
148 {
149         int err = 0;
150
151         err = laguna_edp_regulator_get(dev);
152         if (err < 0) {
153                 pr_err("edp regulator get failed\n");
154                 goto fail;
155         }
156
157         err = laguna_edp_gpio_get();
158         if (err < 0) {
159                 pr_err("edp gpio request failed\n");
160                 goto fail;
161         }
162
163         if (vdd_lcd_bl) {
164                 err = regulator_enable(vdd_lcd_bl);
165                 if (err < 0) {
166                         pr_err("vdd_lcd_bl regulator enable failed\n");
167                         goto fail;
168                 }
169         }
170
171         msleep(20);
172
173         if (vdd_ds_1v8) {
174                 err = regulator_enable(vdd_ds_1v8);
175                 if (err < 0) {
176                         pr_err("vdd_ds_1v8 regulator enable failed\n");
177                         goto fail;
178                 }
179         }
180
181         if (avdd_lcd) {
182                 err = regulator_enable(avdd_lcd);
183                 if (err < 0) {
184                         pr_err("avdd_lcd regulator enable failed\n");
185                         goto fail;
186                 }
187         }
188
189         msleep(10);
190
191         if (vdd_lcd_bl_en) {
192                 err = regulator_enable(vdd_lcd_bl_en);
193                 if (err < 0) {
194                         pr_err("vdd_lcd_bl_en regulator enable failed\n");
195                         goto fail;
196                 }
197         }
198         msleep(180);
199
200         return 0;
201 fail:
202         return err;
203 }
204
205 static int edp_a_1080p_14_0_disable(void)
206 {
207         if (vdd_lcd_bl_en)
208                 regulator_disable(vdd_lcd_bl_en);
209
210         msleep(10);
211
212         if (avdd_lcd)
213                 regulator_disable(avdd_lcd);
214
215         if (vdd_ds_1v8)
216                 regulator_disable(vdd_ds_1v8);
217
218         msleep(10);
219
220         if (vdd_lcd_bl)
221                 regulator_disable(vdd_lcd_bl);
222
223         msleep(500);
224
225         return 0;
226 }
227
228 static int edp_a_1080p_14_0_postsuspend(void)
229 {
230         return 0;
231 }
232
233 static struct tegra_dc_out_pin edp_out_pins[] = {
234         {
235                 .name   = TEGRA_DC_OUT_PIN_H_SYNC,
236                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
237         },
238         {
239                 .name   = TEGRA_DC_OUT_PIN_V_SYNC,
240                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
241         },
242         {
243                 .name   = TEGRA_DC_OUT_PIN_PIXEL_CLOCK,
244                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
245         },
246         {
247                 .name   = TEGRA_DC_OUT_PIN_DATA_ENABLE,
248                 .pol    = TEGRA_DC_OUT_PIN_POL_HIGH,
249         },
250 };
251
252 static struct tegra_dc_mode edp_a_1080p_14_0_modes[] = {
253         {
254                 .pclk = 137986200,
255                 .h_ref_to_sync = 1,
256                 .v_ref_to_sync = 1,
257                 .h_sync_width = 16,
258                 .v_sync_width = 14,
259                 .h_back_porch = 152,
260                 .v_back_porch = 19,
261                 .h_active = 1920,
262                 .v_active = 1080,
263                 .h_front_porch = 16,
264                 .v_front_porch = 3,
265         },
266 };
267
268 static int edp_a_1080p_14_0_bl_notify(struct device *unused, int brightness)
269 {
270         int cur_sd_brightness = atomic_read(&sd_brightness);
271
272         /* SD brightness is a percentage */
273         brightness = (brightness * cur_sd_brightness) / 255;
274
275         /* Apply any backlight response curve */
276         if (brightness > 255)
277                 pr_info("Error: Brightness > 255!\n");
278         else
279                 brightness = edp_a_1080p_14_0_bl_output_measured[brightness];
280
281         return brightness;
282 }
283
284 static int edp_a_1080p_14_0_check_fb(struct device *dev, struct fb_info *info)
285 {
286         return info->device == &disp_device->dev;
287 }
288
289 static struct platform_pwm_backlight_data edp_a_1080p_14_0_bl_data = {
290         .pwm_id         = 1,
291         .max_brightness = 255,
292         .dft_brightness = 224,
293         .pwm_period_ns  = 1000000,
294         .pwm_gpio       = TEGRA_GPIO_INVALID,
295         .notify         = edp_a_1080p_14_0_bl_notify,
296         /* Only toggle backlight on fb blank notifications for disp1 */
297         .check_fb       = edp_a_1080p_14_0_check_fb,
298 };
299
300 static struct platform_device __maybe_unused
301                 edp_a_1080p_14_0_bl_device = {
302         .name   = "pwm-backlight",
303         .id     = -1,
304         .dev    = {
305                 .platform_data = &edp_a_1080p_14_0_bl_data,
306         },
307 };
308
309 static struct platform_device __maybe_unused
310                         *edp_a_1080p_14_0_bl_devices[] __initdata = {
311         &tegra_pwfm_device,
312         &edp_a_1080p_14_0_bl_device,
313 };
314
315 static int  __init __edp_a_1080p_14_0_register_bl_dev(void)
316 {
317         int err = 0;
318         err = platform_add_devices(edp_a_1080p_14_0_bl_devices,
319                                 ARRAY_SIZE(edp_a_1080p_14_0_bl_devices));
320         if (err) {
321                 pr_err("disp1 bl device registration failed");
322                 return err;
323         }
324         return err;
325 }
326
327 static int  __init edp_a_1080p_14_0_register_bl_dev(void)
328 {
329         int err = 0;
330         if (!of_have_populated_dt())
331                 err = __edp_a_1080p_14_0_register_bl_dev();
332         return err;
333 }
334
335 static void edp_a_1080p_14_0_set_disp_device(
336         struct platform_device *laguna_display_device)
337 {
338         disp_device = laguna_display_device;
339 }
340
341 static void edp_a_1080p_14_0_dc_out_init(struct tegra_dc_out *dc)
342 {
343         dc->align = TEGRA_DC_ALIGN_MSB,
344         dc->order = TEGRA_DC_ORDER_RED_BLUE,
345         dc->flags = DC_CTRL_MODE;
346         dc->modes = edp_a_1080p_14_0_modes;
347         dc->n_modes = ARRAY_SIZE(edp_a_1080p_14_0_modes);
348         dc->out_pins = edp_out_pins,
349         dc->n_out_pins = ARRAY_SIZE(edp_out_pins),
350         dc->depth = 18,
351         dc->parent_clk = "pll_d_out0";
352         dc->enable = edp_a_1080p_14_0_enable;
353         dc->disable = edp_a_1080p_14_0_disable;
354         dc->postsuspend = edp_a_1080p_14_0_postsuspend,
355         dc->width = 320;
356         dc->height = 205;
357         dc->hotplug_gpio = TEGRA_GPIO_PFF0;
358 }
359
360 static void edp_a_1080p_14_0_fb_data_init(struct tegra_fb_data *fb)
361 {
362         fb->xres = edp_a_1080p_14_0_modes[0].h_active;
363         fb->yres = edp_a_1080p_14_0_modes[0].v_active;
364 }
365
366 static void
367 edp_a_1080p_14_0_sd_settings_init(struct tegra_dc_sd_settings *settings)
368 {
369         settings->bl_device_name = "pwm-backlight";
370 }
371
372 struct tegra_panel __initdata edp_a_1080p_14_0 = {
373         .init_sd_settings = edp_a_1080p_14_0_sd_settings_init,
374         .init_dc_out = edp_a_1080p_14_0_dc_out_init,
375         .init_fb_data = edp_a_1080p_14_0_fb_data_init,
376         .register_bl_dev = edp_a_1080p_14_0_register_bl_dev,
377         .set_disp_device = edp_a_1080p_14_0_set_disp_device,
378 };
379 EXPORT_SYMBOL(edp_a_1080p_14_0);
380