]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/staging/udlfb/udlfb.h
Staging: udlfb: add udlfb driver to build
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / udlfb / udlfb.h
CommitLineData
88e58b1a
RDI
1#define MAX_VMODES 4
2#define FB_BPP 16
3
4#define STD_CHANNEL "\x57\xCD\xDC\xA7\x1C\x88\x5E\x15\x60\xFE\xC6\x97\x16\x3D\x47\xF2"
5
6// as libdlo
7#define BUF_HIGH_WATER_MARK 1024
8#define BUF_SIZE 64*1024
9
10struct dlfb_data {
11 struct usb_device *udev;
12 struct usb_interface *interface;
13 struct urb *tx_urb, *ctrl_urb;
14 struct usb_ctrlrequest dr;
15 struct fb_info *info;
16 char *buf;
17 char *bufend;
18 char *backing_buffer;
19 struct mutex bulk_mutex;
20 char edid[128];
21 int screen_size;
22 int line_length;
23 struct completion done;
24 int base16;
25 int base8;
26};
27
28struct dlfb_video_mode {
29
30 uint8_t col;
31 uint32_t hclock;
32 uint32_t vclock;
33 uint8_t unknown1[6];
34 uint16_t xres;
35 uint8_t unknown2[6];
36 uint16_t yres;
37 uint8_t unknown3[4];
38
39} __attribute__ ((__packed__));
40
41struct dlfb_video_mode dlfb_video_modes[MAX_VMODES];
42
43static void dlfb_bulk_callback(struct urb *urb)
44{
45
46 struct dlfb_data *dev_info = urb->context;
47 complete(&dev_info->done);
48
49}
50
51static int dlfb_bulk_msg(struct dlfb_data *dev_info, int len)
52{
53
54 int ret;
55
56 init_completion(&dev_info->done);
57
58 dev_info->tx_urb->actual_length = 0;
59 dev_info->tx_urb->transfer_buffer_length = len;
60
61 ret = usb_submit_urb(dev_info->tx_urb, GFP_KERNEL);
62 if (!wait_for_completion_timeout(&dev_info->done, 1000)) {
63 usb_kill_urb(dev_info->tx_urb);
64 printk("usb timeout !!!\n");
65 }
66
67 return dev_info->tx_urb->actual_length;
68
69}
70
71void dlfb_init_modes(void)
72{
73
74 dlfb_video_modes[0].col = 0;
75 memcpy(&dlfb_video_modes[0].hclock, "\x20\x3C\x7A\xC9", 4);
76 memcpy(&dlfb_video_modes[0].vclock, "\xF2\x6C\x48\xF9", 4);
77 memcpy(&dlfb_video_modes[0].unknown1, "\x70\x53\xFF\xFF\x21\x27", 6);
78 dlfb_video_modes[0].xres = 800;
79 memcpy(&dlfb_video_modes[0].unknown2, "\x91\xF3\xFF\xFF\xFF\xF9", 6);
80 dlfb_video_modes[0].yres = 480;
81 memcpy(&dlfb_video_modes[0].unknown3, "\x01\x02\xC8\x19", 4);
82
83 dlfb_video_modes[1].col = 0;
84 memcpy(&dlfb_video_modes[1].hclock, "\x36\x18\xD5\x10", 4);
85 memcpy(&dlfb_video_modes[1].vclock, "\x60\xA9\x7B\x33", 4);
86 memcpy(&dlfb_video_modes[1].unknown1, "\xA1\x2B\x27\x32\xFF\xFF", 6);
87 dlfb_video_modes[1].xres = 1024;
88 memcpy(&dlfb_video_modes[1].unknown2, "\xD9\x9A\xFF\xCA\xFF\xFF", 6);
89 dlfb_video_modes[1].yres = 768;
90 memcpy(&dlfb_video_modes[1].unknown3, "\x04\x03\xC8\x32", 4);
91
92 dlfb_video_modes[2].col = 0;
93 memcpy(&dlfb_video_modes[2].hclock, "\x98\xF8\x0D\x57", 4);
94 memcpy(&dlfb_video_modes[2].vclock, "\x2A\x55\x4D\x54", 4);
95 memcpy(&dlfb_video_modes[2].unknown1, "\xCA\x0D\xFF\xFF\x94\x43", 6);
96 dlfb_video_modes[2].xres = 1280;
97 memcpy(&dlfb_video_modes[2].unknown2, "\x9A\xA8\xFF\xFF\xFF\xF9", 6);
98 dlfb_video_modes[2].yres = 1024;
99 memcpy(&dlfb_video_modes[2].unknown3, "\x04\x02\x60\x54", 4);
100
101 dlfb_video_modes[3].col = 0;
102 memcpy(&dlfb_video_modes[3].hclock, "\x42\x24\x38\x36", 4);
103 memcpy(&dlfb_video_modes[3].vclock, "\xC1\x52\xD9\x29", 4);
104 memcpy(&dlfb_video_modes[3].unknown1, "\xEA\xB8\x32\x60\xFF\xFF", 6);
105 dlfb_video_modes[3].xres = 1400;
106 memcpy(&dlfb_video_modes[3].unknown2, "\xC9\x4E\xFF\xFF\xFF\xF2", 6);
107 dlfb_video_modes[3].yres = 1050;
108 memcpy(&dlfb_video_modes[3].unknown3, "\x04\x02\x1E\x5F", 4);
109
110}
111
112char *dlfb_set_register(char *bufptr, uint8_t reg, uint8_t val)
113{
114
115 *bufptr++ = 0xAF;
116 *bufptr++ = 0x20;
117 *bufptr++ = reg;
118 *bufptr++ = val;
119
120 return bufptr;
121
122}
123
124int dlfb_set_video_mode(struct dlfb_data *dev_info, int width, int height)
125{
126
127 int i, ret;
128 unsigned char j;
129 char *bufptr = dev_info->buf;
130 uint8_t *vdata;
131
132 for (i = 0; i < MAX_VMODES; i++) {
133 printk("INIT VIDEO %d %d %d\n", i, dlfb_video_modes[i].xres,
134 dlfb_video_modes[i].yres);
135 if (dlfb_video_modes[i].xres == width
136 && dlfb_video_modes[i].yres == height) {
137
138 dev_info->base16 = 0;
139
140 dev_info->base8 = width * height * (FB_BPP / 8);;
141
142 // set encryption key (null)
143 memcpy(dev_info->buf, STD_CHANNEL, 16);
144 ret =
145 usb_control_msg(dev_info->udev,
146 usb_sndctrlpipe(dev_info->udev, 0),
147 0x12, (0x02 << 5), 0, 0,
148 dev_info->buf, 16, 0);
149 printk("ret control msg 1 (STD_CHANNEL): %d\n", ret);
150
151 // set registers
152 bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
153
154 // set addresses
155 bufptr =
156 dlfb_set_register(bufptr, 0x20,
157 (char)(dev_info->base16 >> 16));
158 bufptr =
159 dlfb_set_register(bufptr, 0x21,
160 (char)(dev_info->base16 >> 8));
161 bufptr =
162 dlfb_set_register(bufptr, 0x22,
163 (char)(dev_info->base16));
164
165 bufptr =
166 dlfb_set_register(bufptr, 0x26,
167 (char)(dev_info->base8 >> 16));
168 bufptr =
169 dlfb_set_register(bufptr, 0x27,
170 (char)(dev_info->base8 >> 8));
171 bufptr =
172 dlfb_set_register(bufptr, 0x28,
173 (char)(dev_info->base8));
174
175 // set video mode
176 vdata = (uint8_t *) & dlfb_video_modes[i];
177 for (j = 0; j < 29; j++) {
178 bufptr = dlfb_set_register(bufptr, j, vdata[j]);
179 }
180
181 // blank
182 bufptr = dlfb_set_register(bufptr, 0x1F, 0x00);
183
184 // end registers
185 bufptr = dlfb_set_register(bufptr, 0xFF, 0xFF);
186
187 // send
188 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
189 printk("ret bulk 2: %d %d\n", ret,
190 bufptr - dev_info->buf);
191
192 // flush
193 ret = dlfb_bulk_msg(dev_info, 0);
194 printk("ret bulk 3: %d\n", ret);
195
196 dev_info->screen_size = width * height * (FB_BPP / 8);
197 dev_info->line_length = width * (FB_BPP / 8);
198
199 return 0;
200 }
201 }
202
203 return -1;
204}