[ARM] tegra: spdif/i2s audio: fixes
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-tegra / board-ventana-panel.c
1 /*
2  * arch/arm/mach-tegra/board-ventana-panel.c
3  *
4  * Copyright (c) 2010, NVIDIA Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20
21 #include <linux/delay.h>
22 #include <linux/gpio.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/resource.h>
25 #include <asm/mach-types.h>
26 #include <linux/platform_device.h>
27 #include <linux/pwm_backlight.h>
28 #include <mach/nvhost.h>
29 #include <mach/nvmap.h>
30 #include <mach/irqs.h>
31 #include <mach/iomap.h>
32 #include <mach/dc.h>
33 #include <mach/fb.h>
34
35 #include "devices.h"
36 #include "gpio-names.h"
37
38 #define ventana_bl_enb          TEGRA_GPIO_PD4
39 #define ventana_lvds_shutdown   TEGRA_GPIO_PB2
40 #define ventana_hdmi_hpd        TEGRA_GPIO_PN7
41 #define ventana_hdmi_enb        TEGRA_GPIO_PV5
42
43 static int ventana_backlight_init(struct device *dev) {
44         int ret;
45
46         ret = gpio_request(ventana_bl_enb, "backlight_enb");
47         if (ret < 0)
48                 return ret;
49
50         ret = gpio_direction_output(ventana_bl_enb, 1);
51         if (ret < 0)
52                 gpio_free(ventana_bl_enb);
53         else
54                 tegra_gpio_enable(ventana_bl_enb);
55
56         return ret;
57 };
58
59 static void ventana_backlight_exit(struct device *dev) {
60         gpio_set_value(ventana_bl_enb, 0);
61         gpio_free(ventana_bl_enb);
62         tegra_gpio_disable(ventana_bl_enb);
63 }
64
65 static int ventana_backlight_notify(struct device *unused, int brightness)
66 {
67         gpio_set_value(ventana_bl_enb, !!brightness);
68         return brightness;
69 }
70
71 static struct platform_pwm_backlight_data ventana_backlight_data = {
72         .pwm_id         = 2,
73         .max_brightness = 255,
74         .dft_brightness = 224,
75         .pwm_period_ns  = 5000000,
76         .init           = ventana_backlight_init,
77         .exit           = ventana_backlight_exit,
78         .notify         = ventana_backlight_notify,
79 };
80
81 static struct platform_device ventana_backlight_device = {
82         .name   = "pwm-backlight",
83         .id     = -1,
84         .dev    = {
85                 .platform_data = &ventana_backlight_data,
86         },
87 };
88
89 static int ventana_panel_enable(void)
90 {
91         static struct regulator *reg = NULL;
92
93         if (reg == NULL) {
94                 reg = regulator_get(NULL, "avdd_lvds");
95                 if (WARN_ON(IS_ERR(reg)))
96                         pr_err("%s: couldn't get regulator avdd_lvds: %ld\n",
97                                __func__, PTR_ERR(reg));
98                 else
99                         regulator_enable(reg);
100         }
101
102         gpio_set_value(ventana_lvds_shutdown, 1);
103         return 0;
104 }
105
106 static int ventana_panel_disable(void)
107 {
108         gpio_set_value(ventana_lvds_shutdown, 0);
109         return 0;
110 }
111
112 static int ventana_hdmi_enable(void)
113 {
114         gpio_set_value(ventana_hdmi_enb, 1);
115         return 0;
116 }
117
118 static int ventana_hdmi_disable(void)
119 {
120         gpio_set_value(ventana_hdmi_enb, 0);
121         return 0;
122 }
123
124 static struct resource ventana_disp1_resources[] = {
125         {
126                 .name   = "irq",
127                 .start  = INT_DISPLAY_GENERAL,
128                 .end    = INT_DISPLAY_GENERAL,
129                 .flags  = IORESOURCE_IRQ,
130         },
131         {
132                 .name   = "regs",
133                 .start  = TEGRA_DISPLAY_BASE,
134                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
135                 .flags  = IORESOURCE_MEM,
136         },
137         {
138                 .name   = "fbmem",
139                 .start  = 0x18012000,
140                 .end    = 0x18414000 - 1, /* enough for 1080P 16bpp */
141                 .flags  = IORESOURCE_MEM,
142         },
143 };
144
145 static struct resource ventana_disp2_resources[] = {
146         {
147                 .name   = "irq",
148                 .start  = INT_DISPLAY_B_GENERAL,
149                 .end    = INT_DISPLAY_B_GENERAL,
150                 .flags  = IORESOURCE_IRQ,
151         },
152         {
153                 .name   = "regs",
154                 .start  = TEGRA_DISPLAY2_BASE,
155                 .end    = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
156                 .flags  = IORESOURCE_MEM,
157         },
158         {
159                 .name   = "fbmem",
160                 .flags  = IORESOURCE_MEM,
161                 .start  = 0x18414000,
162                 .end    = 0x18BFD000 - 1,
163         },
164         {
165                 .name   = "hdmi_regs",
166                 .start  = TEGRA_HDMI_BASE,
167                 .end    = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
168                 .flags  = IORESOURCE_MEM,
169         },
170 };
171
172 static struct tegra_dc_mode ventana_panel_modes[] = {
173         {
174                 .pclk = 62200000,
175                 .h_ref_to_sync = 11,
176                 .v_ref_to_sync = 1,
177                 .h_sync_width = 58,
178                 .v_sync_width = 4,
179                 .h_back_porch = 58,
180                 .v_back_porch = 4,
181                 .h_active = 1366,
182                 .v_active = 768,
183                 .h_front_porch = 58,
184                 .v_front_porch = 4,
185         },
186 };
187
188 static struct tegra_fb_data ventana_fb_data = {
189         .win            = 0,
190         .xres           = 1366,
191         .yres           = 768,
192         .bits_per_pixel = 16,
193 };
194
195 static struct tegra_fb_data ventana_hdmi_fb_data = {
196         .win            = 0,
197         .xres           = 1280,
198         .yres           = 720,
199         .bits_per_pixel = 16,
200 };
201
202 static struct tegra_dc_out ventana_disp1_out = {
203         .type           = TEGRA_DC_OUT_RGB,
204
205         .align          = TEGRA_DC_ALIGN_MSB,
206         .order          = TEGRA_DC_ORDER_RED_BLUE,
207
208         .modes          = ventana_panel_modes,
209         .n_modes        = ARRAY_SIZE(ventana_panel_modes),
210
211         .enable         = ventana_panel_enable,
212         .disable        = ventana_panel_disable,
213 };
214
215 static struct tegra_dc_out ventana_disp2_out = {
216         .type           = TEGRA_DC_OUT_HDMI,
217         .flags          = TEGRA_DC_OUT_HOTPLUG_HIGH,
218
219         .dcc_bus        = 1,
220         .hotplug_gpio   = ventana_hdmi_hpd,
221
222         .align          = TEGRA_DC_ALIGN_MSB,
223         .order          = TEGRA_DC_ORDER_RED_BLUE,
224
225         .enable         = ventana_hdmi_enable,
226         .disable        = ventana_hdmi_disable,
227 };
228
229 static struct tegra_dc_platform_data ventana_disp1_pdata = {
230         .flags          = TEGRA_DC_FLAG_ENABLED,
231         .default_out    = &ventana_disp1_out,
232         .fb             = &ventana_fb_data,
233 };
234
235 static struct tegra_dc_platform_data ventana_disp2_pdata = {
236         .flags          = TEGRA_DC_FLAG_ENABLED,
237         .default_out    = &ventana_disp2_out,
238         .fb             = &ventana_hdmi_fb_data,
239 };
240
241 static struct nvhost_device ventana_disp1_device = {
242         .name           = "tegradc",
243         .id             = 0,
244         .resource       = ventana_disp1_resources,
245         .num_resources  = ARRAY_SIZE(ventana_disp1_resources),
246         .dev = {
247                 .platform_data = &ventana_disp1_pdata,
248         },
249 };
250
251 static struct nvhost_device ventana_disp2_device = {
252         .name           = "tegradc",
253         .id             = 1,
254         .resource       = ventana_disp2_resources,
255         .num_resources  = ARRAY_SIZE(ventana_disp2_resources),
256         .dev = {
257                 .platform_data = &ventana_disp2_pdata,
258         },
259 };
260
261 static struct nvmap_platform_carveout ventana_carveouts[] = {
262         [0] = {
263                 .name           = "iram",
264                 .usage_mask     = NVMAP_HEAP_CARVEOUT_IRAM,
265                 .base           = TEGRA_IRAM_BASE,
266                 .size           = TEGRA_IRAM_SIZE,
267                 .buddy_size     = 0, /* no buddy allocation for IRAM */
268         },
269         [1] = {
270                 .name           = "generic-0",
271                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
272                 .base           = 0x18C00000,
273                 .size           = SZ_128M - 0xC00000,
274                 .buddy_size     = SZ_32K,
275         },
276 };
277
278 static struct nvmap_platform_data ventana_nvmap_data = {
279         .carveouts      = ventana_carveouts,
280         .nr_carveouts   = ARRAY_SIZE(ventana_carveouts),
281 };
282
283 static struct platform_device ventana_nvmap_device = {
284         .name   = "tegra-nvmap",
285         .id     = -1,
286         .dev    = {
287                 .platform_data = &ventana_nvmap_data,
288         },
289 };
290
291 static struct platform_device *ventana_gfx_devices[] __initdata = {
292         &ventana_nvmap_device,
293         &tegra_grhost_device,
294         &tegra_pwfm2_device,
295         &ventana_backlight_device,
296 };
297
298 int __init ventana_panel_init(void)
299 {
300         int err;
301
302         gpio_request(ventana_lvds_shutdown, "lvds_shdn");
303         gpio_direction_output(ventana_lvds_shutdown, 1);
304         tegra_gpio_enable(ventana_lvds_shutdown);
305
306         gpio_request(ventana_hdmi_enb, "hdmi_5v_en");
307         gpio_direction_output(ventana_hdmi_enb, 0);
308         tegra_gpio_enable(ventana_hdmi_enb);
309
310         gpio_request(ventana_hdmi_hpd, "hdmi_hpd");
311         gpio_direction_input(ventana_hdmi_hpd);
312         tegra_gpio_enable(ventana_hdmi_hpd);
313
314         err = platform_add_devices(ventana_gfx_devices,
315                                    ARRAY_SIZE(ventana_gfx_devices));
316
317         if (!err)
318                 err = nvhost_device_register(&ventana_disp1_device);
319
320         if (!err)
321                 err = nvhost_device_register(&ventana_disp2_device);
322
323         return err;
324 }
325