0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/module.h>
0013 #include <linux/kernel.h>
0014 #include <linux/init.h>
0015 #include <linux/delay.h>
0016
0017 #include "fbtft.h"
0018
0019 #define DRVNAME "fb_s6d1121"
0020 #define WIDTH 240
0021 #define HEIGHT 320
0022 #define BPP 16
0023 #define FPS 20
0024 #define DEFAULT_GAMMA "26 09 24 2C 1F 23 24 25 22 26 25 23 0D 00\n" \
0025 "1C 1A 13 1D 0B 11 12 10 13 15 36 19 00 0D"
0026
0027 static int init_display(struct fbtft_par *par)
0028 {
0029 par->fbtftops.reset(par);
0030
0031
0032
0033 write_reg(par, 0x0011, 0x2004);
0034 write_reg(par, 0x0013, 0xCC00);
0035 write_reg(par, 0x0015, 0x2600);
0036 write_reg(par, 0x0014, 0x252A);
0037 write_reg(par, 0x0012, 0x0033);
0038 write_reg(par, 0x0013, 0xCC04);
0039 write_reg(par, 0x0013, 0xCC06);
0040 write_reg(par, 0x0013, 0xCC4F);
0041 write_reg(par, 0x0013, 0x674F);
0042 write_reg(par, 0x0011, 0x2003);
0043 write_reg(par, 0x0016, 0x0007);
0044 write_reg(par, 0x0002, 0x0013);
0045 write_reg(par, 0x0003, 0x0003);
0046 write_reg(par, 0x0001, 0x0127);
0047 write_reg(par, 0x0008, 0x0303);
0048 write_reg(par, 0x000A, 0x000B);
0049 write_reg(par, 0x000B, 0x0003);
0050 write_reg(par, 0x000C, 0x0000);
0051 write_reg(par, 0x0041, 0x0000);
0052 write_reg(par, 0x0050, 0x0000);
0053 write_reg(par, 0x0060, 0x0005);
0054 write_reg(par, 0x0070, 0x000B);
0055 write_reg(par, 0x0071, 0x0000);
0056 write_reg(par, 0x0078, 0x0000);
0057 write_reg(par, 0x007A, 0x0000);
0058 write_reg(par, 0x0079, 0x0007);
0059 write_reg(par, 0x0007, 0x0051);
0060 write_reg(par, 0x0007, 0x0053);
0061 write_reg(par, 0x0079, 0x0000);
0062
0063 write_reg(par, 0x0022);
0064
0065 return 0;
0066 }
0067
0068 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
0069 {
0070 switch (par->info->var.rotate) {
0071
0072
0073 case 0:
0074 write_reg(par, 0x0020, xs);
0075 write_reg(par, 0x0021, ys);
0076 break;
0077 case 180:
0078 write_reg(par, 0x0020, WIDTH - 1 - xs);
0079 write_reg(par, 0x0021, HEIGHT - 1 - ys);
0080 break;
0081 case 270:
0082 write_reg(par, 0x0020, WIDTH - 1 - ys);
0083 write_reg(par, 0x0021, xs);
0084 break;
0085 case 90:
0086 write_reg(par, 0x0020, ys);
0087 write_reg(par, 0x0021, HEIGHT - 1 - xs);
0088 break;
0089 }
0090 write_reg(par, 0x0022);
0091 }
0092
0093 static int set_var(struct fbtft_par *par)
0094 {
0095 switch (par->info->var.rotate) {
0096
0097 case 0:
0098 write_reg(par, 0x03, 0x0003 | (par->bgr << 12));
0099 break;
0100 case 180:
0101 write_reg(par, 0x03, 0x0000 | (par->bgr << 12));
0102 break;
0103 case 270:
0104 write_reg(par, 0x03, 0x000A | (par->bgr << 12));
0105 break;
0106 case 90:
0107 write_reg(par, 0x03, 0x0009 | (par->bgr << 12));
0108 break;
0109 }
0110
0111 return 0;
0112 }
0113
0114
0115
0116
0117
0118
0119 #define CURVE(num, idx) curves[(num) * par->gamma.num_values + (idx)]
0120 static int set_gamma(struct fbtft_par *par, u32 *curves)
0121 {
0122 static const unsigned long mask[] = {
0123 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
0124 0x3f, 0x3f, 0x1f, 0x1f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
0125 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x1f, 0x1f,
0126 };
0127 int i, j;
0128
0129
0130 for (i = 0; i < 2; i++)
0131 for (j = 0; j < 14; j++)
0132 CURVE(i, j) &= mask[i * par->gamma.num_values + j];
0133
0134 write_reg(par, 0x0030, CURVE(0, 1) << 8 | CURVE(0, 0));
0135 write_reg(par, 0x0031, CURVE(0, 3) << 8 | CURVE(0, 2));
0136 write_reg(par, 0x0032, CURVE(0, 5) << 8 | CURVE(0, 3));
0137 write_reg(par, 0x0033, CURVE(0, 7) << 8 | CURVE(0, 6));
0138 write_reg(par, 0x0034, CURVE(0, 9) << 8 | CURVE(0, 8));
0139 write_reg(par, 0x0035, CURVE(0, 11) << 8 | CURVE(0, 10));
0140
0141 write_reg(par, 0x0036, CURVE(1, 1) << 8 | CURVE(1, 0));
0142 write_reg(par, 0x0037, CURVE(1, 3) << 8 | CURVE(1, 2));
0143 write_reg(par, 0x0038, CURVE(1, 5) << 8 | CURVE(1, 4));
0144 write_reg(par, 0x0039, CURVE(1, 7) << 8 | CURVE(1, 6));
0145 write_reg(par, 0x003A, CURVE(1, 9) << 8 | CURVE(1, 8));
0146 write_reg(par, 0x003B, CURVE(1, 11) << 8 | CURVE(1, 10));
0147
0148 write_reg(par, 0x003C, CURVE(0, 13) << 8 | CURVE(0, 12));
0149 write_reg(par, 0x003D, CURVE(1, 13) << 8 | CURVE(1, 12));
0150
0151 return 0;
0152 }
0153
0154 #undef CURVE
0155
0156 static struct fbtft_display display = {
0157 .regwidth = 16,
0158 .width = WIDTH,
0159 .height = HEIGHT,
0160 .bpp = BPP,
0161 .fps = FPS,
0162 .gamma_num = 2,
0163 .gamma_len = 14,
0164 .gamma = DEFAULT_GAMMA,
0165 .fbtftops = {
0166 .init_display = init_display,
0167 .set_addr_win = set_addr_win,
0168 .set_var = set_var,
0169 .set_gamma = set_gamma,
0170 },
0171 };
0172
0173 FBTFT_REGISTER_DRIVER(DRVNAME, "samsung,s6d1121", &display);
0174
0175 MODULE_ALIAS("spi:" DRVNAME);
0176 MODULE_ALIAS("platform:" DRVNAME);
0177 MODULE_ALIAS("spi:s6d1121");
0178 MODULE_ALIAS("platform:s6d1121");
0179
0180 MODULE_DESCRIPTION("FB driver for the S6D1121 LCD Controller");
0181 MODULE_AUTHOR("Roman Rolinsky");
0182 MODULE_LICENSE("GPL");