1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/delay.h>
15#include <linux/err.h>
16#include <linux/fb.h>
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/gpio.h>
21#include <video/sh_mobile_lcdc.h>
22#include <cpu/sh7722.h>
23#include <mach/migor.h>
24
25
26
27
28
29
30
31
32
33static void reset_lcd_module(void)
34{
35 gpio_set_value(GPIO_PTH2, 0);
36 mdelay(2);
37 gpio_set_value(GPIO_PTH2, 1);
38 mdelay(1);
39}
40
41
42
43static unsigned long adjust_reg18(unsigned short data)
44{
45 unsigned long tmp1, tmp2;
46
47 tmp1 = (data<<1 | 0x00000001) & 0x000001FF;
48 tmp2 = (data<<2 | 0x00000200) & 0x0003FE00;
49 return tmp1 | tmp2;
50}
51
52static void write_reg(void *sys_ops_handle,
53 struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
54 unsigned short reg, unsigned short data)
55{
56 sys_ops->write_index(sys_ops_handle, adjust_reg18(reg << 8 | data));
57}
58
59static void write_reg16(void *sys_ops_handle,
60 struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
61 unsigned short reg, unsigned short data)
62{
63 sys_ops->write_index(sys_ops_handle, adjust_reg18(reg));
64 sys_ops->write_data(sys_ops_handle, adjust_reg18(data));
65}
66
67static unsigned long read_reg16(void *sys_ops_handle,
68 struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
69 unsigned short reg)
70{
71 unsigned long data;
72
73 sys_ops->write_index(sys_ops_handle, adjust_reg18(reg));
74 data = sys_ops->read_data(sys_ops_handle);
75 return ((data >> 1) & 0xff) | ((data >> 2) & 0xff00);
76}
77
78static void migor_lcd_qvga_seq(void *sys_ops_handle,
79 struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
80 unsigned short const *data, int no_data)
81{
82 int i;
83
84 for (i = 0; i < no_data; i += 2)
85 write_reg16(sys_ops_handle, sys_ops, data[i], data[i + 1]);
86}
87
88static const unsigned short sync_data[] = {
89 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
90};
91
92static const unsigned short magic0_data[] = {
93 0x0060, 0x2700, 0x0008, 0x0808, 0x0090, 0x001A, 0x0007, 0x0001,
94 0x0017, 0x0001, 0x0019, 0x0000, 0x0010, 0x17B0, 0x0011, 0x0116,
95 0x0012, 0x0198, 0x0013, 0x1400, 0x0029, 0x000C, 0x0012, 0x01B8,
96};
97
98static const unsigned short magic1_data[] = {
99 0x0030, 0x0307, 0x0031, 0x0303, 0x0032, 0x0603, 0x0033, 0x0202,
100 0x0034, 0x0202, 0x0035, 0x0202, 0x0036, 0x1F1F, 0x0037, 0x0303,
101 0x0038, 0x0303, 0x0039, 0x0603, 0x003A, 0x0202, 0x003B, 0x0102,
102 0x003C, 0x0204, 0x003D, 0x0000, 0x0001, 0x0100, 0x0002, 0x0300,
103 0x0003, 0x5028, 0x0020, 0x00ef, 0x0021, 0x0000, 0x0004, 0x0000,
104 0x0009, 0x0000, 0x000A, 0x0008, 0x000C, 0x0000, 0x000D, 0x0000,
105 0x0015, 0x8000,
106};
107
108static const unsigned short magic2_data[] = {
109 0x0061, 0x0001, 0x0092, 0x0100, 0x0093, 0x0001, 0x0007, 0x0021,
110};
111
112static const unsigned short magic3_data[] = {
113 0x0010, 0x16B0, 0x0011, 0x0111, 0x0007, 0x0061,
114};
115
116int migor_lcd_qvga_setup(void *board_data, void *sohandle,
117 struct sh_mobile_lcdc_sys_bus_ops *so)
118{
119 unsigned long xres = 320;
120 unsigned long yres = 240;
121 int k;
122
123 reset_lcd_module();
124 migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data));
125
126 if (read_reg16(sohandle, so, 0) != 0x1505)
127 return -ENODEV;
128
129 pr_info("Migo-R QVGA LCD Module detected.\n");
130
131 migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data));
132 write_reg16(sohandle, so, 0x00A4, 0x0001);
133 mdelay(10);
134
135 migor_lcd_qvga_seq(sohandle, so, magic0_data, ARRAY_SIZE(magic0_data));
136 mdelay(100);
137
138 migor_lcd_qvga_seq(sohandle, so, magic1_data, ARRAY_SIZE(magic1_data));
139 write_reg16(sohandle, so, 0x0050, 0xef - (yres - 1));
140 write_reg16(sohandle, so, 0x0051, 0x00ef);
141 write_reg16(sohandle, so, 0x0052, 0x0000);
142 write_reg16(sohandle, so, 0x0053, xres - 1);
143
144 migor_lcd_qvga_seq(sohandle, so, magic2_data, ARRAY_SIZE(magic2_data));
145 mdelay(10);
146
147 migor_lcd_qvga_seq(sohandle, so, magic3_data, ARRAY_SIZE(magic3_data));
148 mdelay(40);
149
150
151
152 write_reg16(sohandle, so, 0x0020, 0x0000);
153 write_reg16(sohandle, so, 0x0021, 0x0000);
154
155 for (k = 0; k < (xres * 256); k++)
156 write_reg16(sohandle, so, 0x0022, 0x0000);
157
158 write_reg16(sohandle, so, 0x0020, 0x0000);
159 write_reg16(sohandle, so, 0x0021, 0x0000);
160 write_reg16(sohandle, so, 0x0007, 0x0173);
161 mdelay(40);
162
163
164 write_reg(sohandle, so, 0x00, 0x22);
165 mdelay(100);
166 return 0;
167}
168