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 *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
117{
118 unsigned long xres = 320;
119 unsigned long yres = 240;
120 int k;
121
122 reset_lcd_module();
123 migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data));
124
125 if (read_reg16(sohandle, so, 0) != 0x1505)
126 return -ENODEV;
127
128 pr_info("Migo-R QVGA LCD Module detected.\n");
129
130 migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data));
131 write_reg16(sohandle, so, 0x00A4, 0x0001);
132 mdelay(10);
133
134 migor_lcd_qvga_seq(sohandle, so, magic0_data, ARRAY_SIZE(magic0_data));
135 mdelay(100);
136
137 migor_lcd_qvga_seq(sohandle, so, magic1_data, ARRAY_SIZE(magic1_data));
138 write_reg16(sohandle, so, 0x0050, 0xef - (yres - 1));
139 write_reg16(sohandle, so, 0x0051, 0x00ef);
140 write_reg16(sohandle, so, 0x0052, 0x0000);
141 write_reg16(sohandle, so, 0x0053, xres - 1);
142
143 migor_lcd_qvga_seq(sohandle, so, magic2_data, ARRAY_SIZE(magic2_data));
144 mdelay(10);
145
146 migor_lcd_qvga_seq(sohandle, so, magic3_data, ARRAY_SIZE(magic3_data));
147 mdelay(40);
148
149
150
151 write_reg16(sohandle, so, 0x0020, 0x0000);
152 write_reg16(sohandle, so, 0x0021, 0x0000);
153
154 for (k = 0; k < (xres * 256); k++)
155 write_reg16(sohandle, so, 0x0022, 0x0000);
156
157 write_reg16(sohandle, so, 0x0020, 0x0000);
158 write_reg16(sohandle, so, 0x0021, 0x0000);
159 write_reg16(sohandle, so, 0x0007, 0x0173);
160 mdelay(40);
161
162
163 write_reg(sohandle, so, 0x00, 0x22);
164 mdelay(100);
165 return 0;
166}
167