]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/staging/fbtft/fb_s6d1121.c
staging/fbtft : Add missing whitespace around operators
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / fbtft / fb_s6d1121.c
CommitLineData
7a39e965
TP
1/*
2 * FB driver for the S6D1121 LCD Controller
3 *
4 * Copyright (C) 2013 Roman Rolinsky
5 *
6 * Based on fb_ili9325.c by Noralf Tronnes
7 * Based on ili9325.c by Jeroen Domburg
8 * Init code from UTFT library by Henning Karlsen
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
7a39e965
TP
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/gpio.h>
25#include <linux/delay.h>
26
27#include "fbtft.h"
28
29#define DRVNAME "fb_s6d1121"
30#define WIDTH 240
31#define HEIGHT 320
32#define BPP 16
33#define FPS 20
34#define DEFAULT_GAMMA "26 09 24 2C 1F 23 24 25 22 26 25 23 0D 00\n" \
35 "1C 1A 13 1D 0B 11 12 10 13 15 36 19 00 0D"
36
37static int init_display(struct fbtft_par *par)
38{
39 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
40
41 par->fbtftops.reset(par);
42
43 if (par->gpio.cs != -1)
44 gpio_set_value(par->gpio.cs, 0); /* Activate chip */
45
46 /* Initialization sequence from Lib_UTFT */
47
48 write_reg(par, 0x0011, 0x2004);
49 write_reg(par, 0x0013, 0xCC00);
50 write_reg(par, 0x0015, 0x2600);
51 write_reg(par, 0x0014, 0x252A);
52 write_reg(par, 0x0012, 0x0033);
53 write_reg(par, 0x0013, 0xCC04);
54 write_reg(par, 0x0013, 0xCC06);
55 write_reg(par, 0x0013, 0xCC4F);
56 write_reg(par, 0x0013, 0x674F);
57 write_reg(par, 0x0011, 0x2003);
58 write_reg(par, 0x0016, 0x0007);
59 write_reg(par, 0x0002, 0x0013);
60 write_reg(par, 0x0003, 0x0003);
61 write_reg(par, 0x0001, 0x0127);
62 write_reg(par, 0x0008, 0x0303);
63 write_reg(par, 0x000A, 0x000B);
64 write_reg(par, 0x000B, 0x0003);
65 write_reg(par, 0x000C, 0x0000);
66 write_reg(par, 0x0041, 0x0000);
67 write_reg(par, 0x0050, 0x0000);
68 write_reg(par, 0x0060, 0x0005);
69 write_reg(par, 0x0070, 0x000B);
70 write_reg(par, 0x0071, 0x0000);
71 write_reg(par, 0x0078, 0x0000);
72 write_reg(par, 0x007A, 0x0000);
73 write_reg(par, 0x0079, 0x0007);
74 write_reg(par, 0x0007, 0x0051);
75 write_reg(par, 0x0007, 0x0053);
76 write_reg(par, 0x0079, 0x0000);
77
78 write_reg(par, 0x0022); /* Write Data to GRAM */
79
80 return 0;
81}
82
83static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
84{
7a39e965
TP
85 switch (par->info->var.rotate) {
86 /* R20h = Horizontal GRAM Start Address */
87 /* R21h = Vertical GRAM Start Address */
88 case 0:
89 write_reg(par, 0x0020, xs);
90 write_reg(par, 0x0021, ys);
91 break;
92 case 180:
93 write_reg(par, 0x0020, WIDTH - 1 - xs);
94 write_reg(par, 0x0021, HEIGHT - 1 - ys);
95 break;
96 case 270:
97 write_reg(par, 0x0020, WIDTH - 1 - ys);
98 write_reg(par, 0x0021, xs);
99 break;
100 case 90:
101 write_reg(par, 0x0020, ys);
102 write_reg(par, 0x0021, HEIGHT - 1 - xs);
103 break;
104 }
105 write_reg(par, 0x0022); /* Write Data to GRAM */
106}
107
108static int set_var(struct fbtft_par *par)
109{
110 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
111
112 switch (par->info->var.rotate) {
113 /* AM: GRAM update direction */
114 case 0:
115 write_reg(par, 0x03, 0x0003 | (par->bgr << 12));
116 break;
117 case 180:
118 write_reg(par, 0x03, 0x0000 | (par->bgr << 12));
119 break;
120 case 270:
121 write_reg(par, 0x03, 0x000A | (par->bgr << 12));
122 break;
123 case 90:
124 write_reg(par, 0x03, 0x0009 | (par->bgr << 12));
125 break;
126 }
127
128 return 0;
129}
130
131/*
132 Gamma string format:
133 PKP0 PKP1 PKP2 PKP3 PKP4 PKP5 PKP6 PKP7 PKP8 PKP9 PKP10 PKP11 VRP0 VRP1
134 PKN0 PKN1 PKN2 PKN3 PKN4 PKN5 PKN6 PKN7 PRN8 PRN9 PRN10 PRN11 VRN0 VRN1
135*/
94c0a544 136#define CURVE(num, idx) curves[num * par->gamma.num_values + idx]
7a39e965
TP
137static int set_gamma(struct fbtft_par *par, unsigned long *curves)
138{
139 unsigned long mask[] = {
153fe946
GU
140 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
141 0x3f, 0x3f, 0x1f, 0x1f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
142 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x1f, 0x1f,
143 };
7a39e965
TP
144 int i, j;
145
146 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
147
148 /* apply mask */
149 for (i = 0; i < 2; i++)
150 for (j = 0; j < 14; j++)
94c0a544 151 CURVE(i, j) &= mask[i * par->gamma.num_values + j];
7a39e965
TP
152
153 write_reg(par, 0x0030, CURVE(0, 1) << 8 | CURVE(0, 0));
154 write_reg(par, 0x0031, CURVE(0, 3) << 8 | CURVE(0, 2));
155 write_reg(par, 0x0032, CURVE(0, 5) << 8 | CURVE(0, 3));
156 write_reg(par, 0x0033, CURVE(0, 7) << 8 | CURVE(0, 6));
157 write_reg(par, 0x0034, CURVE(0, 9) << 8 | CURVE(0, 8));
158 write_reg(par, 0x0035, CURVE(0, 11) << 8 | CURVE(0, 10));
159
160 write_reg(par, 0x0036, CURVE(1, 1) << 8 | CURVE(1, 0));
161 write_reg(par, 0x0037, CURVE(1, 3) << 8 | CURVE(1, 2));
162 write_reg(par, 0x0038, CURVE(1, 5) << 8 | CURVE(1, 4));
163 write_reg(par, 0x0039, CURVE(1, 7) << 8 | CURVE(1, 6));
164 write_reg(par, 0x003A, CURVE(1, 9) << 8 | CURVE(1, 8));
165 write_reg(par, 0x003B, CURVE(1, 11) << 8 | CURVE(1, 10));
166
167 write_reg(par, 0x003C, CURVE(0, 13) << 8 | CURVE(0, 12));
168 write_reg(par, 0x003D, CURVE(1, 13) << 8 | CURVE(1, 12));
169
170 return 0;
171}
172#undef CURVE
173
7a39e965
TP
174static struct fbtft_display display = {
175 .regwidth = 16,
176 .width = WIDTH,
177 .height = HEIGHT,
178 .bpp = BPP,
179 .fps = FPS,
180 .gamma_num = 2,
181 .gamma_len = 14,
182 .gamma = DEFAULT_GAMMA,
183 .fbtftops = {
184 .init_display = init_display,
185 .set_addr_win = set_addr_win,
186 .set_var = set_var,
187 .set_gamma = set_gamma,
188 },
189};
1014c2ce 190
7a39e965
TP
191FBTFT_REGISTER_DRIVER(DRVNAME, "samsung,s6d1121", &display);
192
193MODULE_ALIAS("spi:" DRVNAME);
194MODULE_ALIAS("platform:" DRVNAME);
195MODULE_ALIAS("spi:s6d1121");
196MODULE_ALIAS("platform:s6d1121");
197
198MODULE_DESCRIPTION("FB driver for the S6D1121 LCD Controller");
199MODULE_AUTHOR("Roman Rolinsky");
200MODULE_LICENSE("GPL");