1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Custom FB driver for tinylcd.com display |
4 | * |
5 | * Copyright (C) 2013 Noralf Tronnes |
6 | */ |
7 | |
8 | #include <linux/module.h> |
9 | #include <linux/kernel.h> |
10 | #include <linux/init.h> |
11 | #include <linux/delay.h> |
12 | #include <video/mipi_display.h> |
13 | |
14 | #include "fbtft.h" |
15 | |
16 | #define DRVNAME "fb_tinylcd" |
17 | #define WIDTH 320 |
18 | #define HEIGHT 480 |
19 | |
20 | static int init_display(struct fbtft_par *par) |
21 | { |
22 | par->fbtftops.reset(par); |
23 | |
24 | write_reg(par, 0xB0, 0x80); |
25 | write_reg(par, 0xC0, 0x0A, 0x0A); |
26 | write_reg(par, 0xC1, 0x45, 0x07); |
27 | write_reg(par, 0xC2, 0x33); |
28 | write_reg(par, 0xC5, 0x00, 0x42, 0x80); |
29 | write_reg(par, 0xB1, 0xD0, 0x11); |
30 | write_reg(par, 0xB4, 0x02); |
31 | write_reg(par, 0xB6, 0x00, 0x22, 0x3B); |
32 | write_reg(par, 0xB7, 0x07); |
33 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, 0x58); |
34 | write_reg(par, 0xF0, 0x36, 0xA5, 0xD3); |
35 | write_reg(par, 0xE5, 0x80); |
36 | write_reg(par, 0xE5, 0x01); |
37 | write_reg(par, 0xB3, 0x00); |
38 | write_reg(par, 0xE5, 0x00); |
39 | write_reg(par, 0xF0, 0x36, 0xA5, 0x53); |
40 | write_reg(par, 0xE0, 0x00, 0x35, 0x33, 0x00, 0x00, 0x00, |
41 | 0x00, 0x35, 0x33, 0x00, 0x00, 0x00); |
42 | write_reg(par, MIPI_DCS_SET_PIXEL_FORMAT, 0x55); |
43 | write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); |
44 | udelay(250); |
45 | write_reg(par, MIPI_DCS_SET_DISPLAY_ON); |
46 | |
47 | return 0; |
48 | } |
49 | |
50 | static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) |
51 | { |
52 | write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS, |
53 | xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF); |
54 | |
55 | write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS, |
56 | ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF); |
57 | |
58 | write_reg(par, MIPI_DCS_WRITE_MEMORY_START); |
59 | } |
60 | |
61 | static int set_var(struct fbtft_par *par) |
62 | { |
63 | switch (par->info->var.rotate) { |
64 | case 270: |
65 | write_reg(par, 0xB6, 0x00, 0x02, 0x3B); |
66 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, 0x28); |
67 | break; |
68 | case 180: |
69 | write_reg(par, 0xB6, 0x00, 0x22, 0x3B); |
70 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, 0x58); |
71 | break; |
72 | case 90: |
73 | write_reg(par, 0xB6, 0x00, 0x22, 0x3B); |
74 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, 0x38); |
75 | break; |
76 | default: |
77 | write_reg(par, 0xB6, 0x00, 0x22, 0x3B); |
78 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, 0x08); |
79 | break; |
80 | } |
81 | |
82 | return 0; |
83 | } |
84 | |
85 | static struct fbtft_display display = { |
86 | .regwidth = 8, |
87 | .width = WIDTH, |
88 | .height = HEIGHT, |
89 | .fbtftops = { |
90 | .init_display = init_display, |
91 | .set_addr_win = set_addr_win, |
92 | .set_var = set_var, |
93 | }, |
94 | }; |
95 | |
96 | FBTFT_REGISTER_DRIVER(DRVNAME, "neosec,tinylcd" , &display); |
97 | |
98 | MODULE_ALIAS("spi:" DRVNAME); |
99 | MODULE_ALIAS("spi:tinylcd" ); |
100 | |
101 | MODULE_DESCRIPTION("Custom FB driver for tinylcd.com display" ); |
102 | MODULE_AUTHOR("Noralf Tronnes" ); |
103 | MODULE_LICENSE("GPL" ); |
104 | |