]>
Commit | Line | Data |
---|---|---|
5a714d33 TP |
1 | /* |
2 | * FB driver for the HX8353D LCD Controller | |
3 | * | |
4 | * Copyright (c) 2014 Petr Olivka | |
5 | * Copyright (c) 2013 Noralf Tronnes | |
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 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
5a714d33 TP |
16 | */ |
17 | ||
18 | #include <linux/module.h> | |
19 | #include <linux/kernel.h> | |
20 | #include <linux/init.h> | |
21 | #include <linux/delay.h> | |
fbf461d1 | 22 | #include <video/mipi_display.h> |
5a714d33 TP |
23 | |
24 | #include "fbtft.h" | |
25 | ||
26 | #define DRVNAME "fb_hx8353d" | |
27 | #define DEFAULT_GAMMA "50 77 40 08 BF 00 03 0F 00 01 73 00 72 03 B0 0F 08 00 0F" | |
28 | ||
29 | static int init_display(struct fbtft_par *par) | |
30 | { | |
5a714d33 TP |
31 | par->fbtftops.reset(par); |
32 | mdelay(150); | |
33 | ||
34 | /* SETEXTC */ | |
35 | write_reg(par, 0xB9, 0xFF, 0x83, 0x53); | |
36 | ||
37 | /* RADJ */ | |
38 | write_reg(par, 0xB0, 0x3C, 0x01); | |
39 | ||
40 | /* VCOM */ | |
41 | write_reg(par, 0xB6, 0x94, 0x6C, 0x50); | |
42 | ||
43 | /* PWR */ | |
44 | write_reg(par, 0xB1, 0x00, 0x01, 0x1B, 0x03, 0x01, 0x08, 0x77, 0x89); | |
45 | ||
46 | /* COLMOD */ | |
47 | write_reg(par, 0x3A, 0x05); | |
48 | ||
49 | /* MEM ACCESS */ | |
fbf461d1 | 50 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, 0xC0); |
5a714d33 TP |
51 | |
52 | /* SLPOUT - Sleep out & booster on */ | |
fbf461d1 | 53 | write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); |
5a714d33 TP |
54 | mdelay(150); |
55 | ||
56 | /* DISPON - Display On */ | |
fbf461d1 | 57 | write_reg(par, MIPI_DCS_SET_DISPLAY_ON); |
5a714d33 TP |
58 | |
59 | /* RGBSET */ | |
fbf461d1 | 60 | write_reg(par, MIPI_DCS_WRITE_LUT, |
5f10ef7d | 61 | 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, |
5a714d33 TP |
62 | 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, |
63 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | |
64 | 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, | |
65 | 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, | |
66 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, | |
67 | 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, | |
68 | 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62); | |
69 | ||
70 | return 0; | |
71 | }; | |
72 | ||
73 | static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) | |
74 | { | |
5a714d33 TP |
75 | /* column address */ |
76 | write_reg(par, 0x2a, xs >> 8, xs & 0xff, xe >> 8, xe & 0xff); | |
77 | ||
92def781 | 78 | /* Row address */ |
5a714d33 TP |
79 | write_reg(par, 0x2b, ys >> 8, ys & 0xff, ye >> 8, ye & 0xff); |
80 | ||
81 | /* memory write */ | |
82 | write_reg(par, 0x2c); | |
83 | } | |
84 | ||
e6ea2028 AB |
85 | #define my BIT(7) |
86 | #define mx BIT(6) | |
87 | #define mv BIT(5) | |
5a714d33 TP |
88 | static int set_var(struct fbtft_par *par) |
89 | { | |
e0246ea3 ERR |
90 | /* |
91 | * madctl - memory data access control | |
92 | * rgb/bgr: | |
93 | * 1. mode selection pin srgb | |
94 | * rgb h/w pin for color filter setting: 0=rgb, 1=bgr | |
95 | * 2. madctl rgb bit | |
96 | * rgb-bgr order color filter panel: 0=rgb, 1=bgr | |
97 | */ | |
5a714d33 TP |
98 | switch (par->info->var.rotate) { |
99 | case 0: | |
fbf461d1 PL |
100 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, |
101 | mx | my | (par->bgr << 3)); | |
5a714d33 TP |
102 | break; |
103 | case 270: | |
fbf461d1 PL |
104 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, |
105 | my | mv | (par->bgr << 3)); | |
5a714d33 TP |
106 | break; |
107 | case 180: | |
fbf461d1 PL |
108 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, |
109 | par->bgr << 3); | |
5a714d33 TP |
110 | break; |
111 | case 90: | |
fbf461d1 PL |
112 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, |
113 | mx | mv | (par->bgr << 3)); | |
5a714d33 TP |
114 | break; |
115 | } | |
116 | ||
117 | return 0; | |
118 | } | |
119 | ||
e0246ea3 | 120 | /* gamma string format: */ |
22eb36b8 | 121 | static int set_gamma(struct fbtft_par *par, u32 *curves) |
5a714d33 | 122 | { |
5a714d33 | 123 | write_reg(par, 0xE0, |
5f10ef7d ERR |
124 | curves[0], curves[1], curves[2], curves[3], |
125 | curves[4], curves[5], curves[6], curves[7], | |
126 | curves[8], curves[9], curves[10], curves[11], | |
127 | curves[12], curves[13], curves[14], curves[15], | |
128 | curves[16], curves[17], curves[18]); | |
5a714d33 TP |
129 | |
130 | return 0; | |
131 | } | |
132 | ||
5a714d33 TP |
133 | static struct fbtft_display display = { |
134 | .regwidth = 8, | |
135 | .width = 128, | |
136 | .height = 160, | |
137 | .gamma_num = 1, | |
138 | .gamma_len = 19, | |
139 | .gamma = DEFAULT_GAMMA, | |
140 | .fbtftops = { | |
141 | .init_display = init_display, | |
142 | .set_addr_win = set_addr_win, | |
143 | .set_var = set_var, | |
144 | .set_gamma = set_gamma, | |
145 | }, | |
146 | }; | |
1014c2ce | 147 | |
5a714d33 TP |
148 | FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8353d", &display); |
149 | ||
150 | MODULE_ALIAS("spi:" DRVNAME); | |
151 | MODULE_ALIAS("platform:" DRVNAME); | |
152 | MODULE_ALIAS("spi:hx8353d"); | |
153 | MODULE_ALIAS("platform:hx8353d"); | |
154 | ||
155 | MODULE_DESCRIPTION("FB driver for the HX8353D LCD Controller"); | |
156 | MODULE_AUTHOR("Petr Olivka"); | |
157 | MODULE_LICENSE("GPL"); |