aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJakub Schmidtke <sjakub@gmail.com>2008-11-05 02:46:58 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-06 16:52:28 -0500
commitfb53440b187f0cfc1f116e580e9c7e9931191f9c (patch)
tree9498472816f700da34970982a7c7c90661e06bd9 /drivers
parenta8275fcaa7ca1f720f0c1b1c4c373964ffc9f72d (diff)
Staging: add asus_oled driver
Driver for the OLED tiny display on some Asus laptops. From: Jakub Schmidtke <sjakub@gmail.com> Cc: Cyrill Gorcunov <gorcunov@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/asus_oled/Kconfig5
-rw-r--r--drivers/staging/asus_oled/Makefile1
-rw-r--r--drivers/staging/asus_oled/README156
-rw-r--r--drivers/staging/asus_oled/TODO10
-rw-r--r--drivers/staging/asus_oled/asus_oled.c745
-rw-r--r--drivers/staging/asus_oled/linux.txt33
-rw-r--r--drivers/staging/asus_oled/linux_f.txt18
-rw-r--r--drivers/staging/asus_oled/linux_fr.txt33
-rw-r--r--drivers/staging/asus_oled/tux.txt33
-rw-r--r--drivers/staging/asus_oled/tux_r.txt33
-rw-r--r--drivers/staging/asus_oled/tux_r2.txt33
-rw-r--r--drivers/staging/asus_oled/zig.txt33
14 files changed, 1136 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 5474cb28f701..d8f26acf957b 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -73,5 +73,7 @@ source "drivers/staging/benet/Kconfig"
73 73
74source "drivers/staging/comedi/Kconfig" 74source "drivers/staging/comedi/Kconfig"
75 75
76source "drivers/staging/asus_oled/Kconfig"
77
76endif # !STAGING_EXCLUDE_BUILD 78endif # !STAGING_EXCLUDE_BUILD
77endif # STAGING 79endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 8948a0e575a8..dd9a625d46b9 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_OTUS) += otus/
19obj-$(CONFIG_RT2860) += rt2860/ 19obj-$(CONFIG_RT2860) += rt2860/
20obj-$(CONFIG_BENET) += benet/ 20obj-$(CONFIG_BENET) += benet/
21obj-$(CONFIG_COMEDI) += comedi/ 21obj-$(CONFIG_COMEDI) += comedi/
22obj-$(CONFIG_ASUS_OLED) += asus_oled/
diff --git a/drivers/staging/asus_oled/Kconfig b/drivers/staging/asus_oled/Kconfig
new file mode 100644
index 000000000000..2c10e1eb7266
--- /dev/null
+++ b/drivers/staging/asus_oled/Kconfig
@@ -0,0 +1,5 @@
1config ASUS_OLED
2 tristate "Asus OLED driver"
3 default N
4 ---help---
5 Enable support for the OLED display present in some Asus laptops.
diff --git a/drivers/staging/asus_oled/Makefile b/drivers/staging/asus_oled/Makefile
new file mode 100644
index 000000000000..e71f9aa9e037
--- /dev/null
+++ b/drivers/staging/asus_oled/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_ASUS_OLED) += asus_oled.o
diff --git a/drivers/staging/asus_oled/README b/drivers/staging/asus_oled/README
new file mode 100644
index 000000000000..96b9717f168f
--- /dev/null
+++ b/drivers/staging/asus_oled/README
@@ -0,0 +1,156 @@
1
2 Driver for Asus OLED display present in some Asus laptops.
3
4 The code of this driver is based on 'asusoled' program taken from
5 https://launchpad.net/asusoled/. I just wanted to have a simple
6 kernel driver for controlling this device, but I didn't know how
7 to do that. Now I know ;) Also, that program can not be used
8 with usbhid loaded, which means no USB mouse/keyboard while
9 controlling OLED display :(
10
11 It has been tested on Asus G1 and didn't cause any problems,
12 but I don't guarantee that it won't do anything wrong :)
13
14 It can (and probably does) have errors. It is usable
15 in my case, and I hope others will find it useful too!
16
17*******
18
19Building the module
20
21 To build the module you need kernel 2.6 include files and some C compiler.
22
23 Just run:
24 make
25 make install (as a root)
26
27 It will build (hopefully) the module and install it in
28 /lib/modules/'uname -r'/extra/asus_oled.ko.
29
30 To load it just use:
31 modprobe asus_oled
32
33 You can check if it has detected your OLED display by looking into dmesg output.
34 There should be something like this:
35 asus-oled 2-7:1.0: Attached Asus OLED device
36
37 If it doesn't find your display, you can try removing usbhid module.
38 If you add asus_oled into the list of modules loaded during system boot
39 before usbhid, it will work even when usbhid is present.
40
41 If it still doesn't detect your hardware, check lsusb output.
42 There should be similar line:
43 Bus 002 Device 005: ID 0b05:1726 ASUSTek Computer, Inc.
44
45 If you don't see any lines with '0b05:1726' it means that you have different
46 type of hardware that is not detected (it may or may not work, but the driver
47 knows only '0b05:1726' device).
48
49*******
50
51Configuration
52
53 There is only one option: start_off.
54 You can use it by: 'modprobe asus_oled start_off=1', or by adding this
55 line to /etc/modprobe.conf:
56 options asus_oled start_off=1
57
58 With this option provided, asus_oled driver will switch off the display
59 when it is detected and attached. It is nice feature to just switch off the 'ASUS'
60 logo. If you don't use the display, it is probably the good idea to switch it off,
61 to protect OLEDs from "wearing off".
62
63*******
64
65Usage
66
67 This module can be controlled with two special files:
68 /sys/class/asus_oled/oled_N/enabled
69 /sys/class/asus_oled/oled_N/picture
70
71 (N is the device number, the first, and probably the only, has number 1,
72 so it is /sys/class/asus_oled/oled_1/enabled
73 and /sys/class/asus_oled/oled_1/picture)
74
75 'enabled' files is for reading and writing, 'picture' is writeable only.
76
77 You can write 0 or 1 to 'enabled' file, which will switch
78 on and off the display. Reading from this file will tell you the last
79 status set, either 0 or 1. By default it is 1, so if the device was set to 'off',
80 and the computer was rebooted without power-off, this file will contain wrong
81 value - because the device is off, but hasn't been disabled this time and is
82 assumed to be on...
83
84 To 'picture' file you write pictures to be displayed by the OLED device.
85 The format of the file:
86 <M:WxH>
87 00001110010111000
88 00010101010101010
89 ....
90
91 First line is a configuration parameter. Meaning of fields in <M:WxH>:
92 M - picture mode. It can be either 's' for static pictures,
93 'r' for rolling pictures, and 'f' for flashing pictures.
94 W - width of the picture. May be between 1 and 1792
95 H - height of the picture. May be between 1 and 32
96
97 For example <s:128x32> means static picture, 128 pixels long and 32 pixels high.
98
99 The physical size of the display is 128x32 pixels. Static and flashing pictures
100 can't be larger than that (actually they can, but only part of them will be displayed ;) )
101
102 If the picture is smaller than 128x32 it will be centered. Rolling pictures wider than
103 128 pixels will be centered too, unless their width = n*128. Vertically they will be
104 centered just like static pictures, if their height is smaller than 32.
105
106 Flashing pictures will be centered horizontally if their width < 128, but they were
107 centered vertically in a different way. If their height < 16, they will be centered
108 in the upper half of the display (rows 0-15). This is because only the first half
109 of flashing pictures is used for flashing. When the picture with heigh = 32 is
110 displayed in flashing mode, its upper 16 rows will be flashing in the upper half
111 of the display, and the lower half will be empty. After few seconds upper part will
112 stop flashing (but that part of the picture will remain there), and the lower
113 half of the display will start displayin the lower half of the picture
114 in rolling mode, unless it is empty, or the picture was small enough to fit in
115 upper part. It is not mine idea, this is just the way Asus' display work ;)
116 So if you need just flashing, use at most 128x16 picture. If you need flashing and
117 rolling, use whole size of the display.
118
119 Lines following the first, configuration, line are picture data. Each '1' means
120 that the pixel is lit, and '0' means that it is not. You can also use '#' as ON,
121 and ' ' (space) as OFF. Empty lines and all other characters are ignored.
122
123 It is possible to write everything in one line <M:WxH>01010101010101010...,
124 and W*H characters will be used. If there is not enough characters, nothing will be
125 displayed. However, the 'line mode' is easier to read (and write), and it also
126 lets to omit parts of data. Whenever End-Of-Line character is found, but
127 the line is not W characters long, it is assumed that all missing characters
128 are equal to the last character in the line.
129
130 Following line represents '0', '1' and a lots of '0's, dependng on the width of the picture
131 provided in configuration data:
132 010
133
134 So if you need empty line, it is sufficient to write line with only one '0' in it.
135 The same works with '1' (or ' ' and '#').
136
137 If there are too many data in the file, they will be ignored. If you are not sure
138 how many characters you are missing, you can add few lines with one zero in each of them.
139
140 There are some example pictures in .txt format, that can be used as follows:
141 cat foo.txt > /sys/class/asus_oled/oled_1/picture
142
143 If the display is switched off you also need to run:
144 echo 1 > /sys/class/asus_oled/oled_1/enabled
145 To switch it off, just use:
146 echo 0 > /sys/class/asus_oled/oled_1/enabled
147
148
149*******
150
151 For any additional info please have a look at http://lapsus.berlios.de/asus_oled.html
152
153
154
155 Jakub Schmidtke (sjakub@gmail.com)
156
diff --git a/drivers/staging/asus_oled/TODO b/drivers/staging/asus_oled/TODO
new file mode 100644
index 000000000000..2514131670a3
--- /dev/null
+++ b/drivers/staging/asus_oled/TODO
@@ -0,0 +1,10 @@
1TODO:
2 - checkpatch.pl cleanups
3 - sparse fixes
4 - audit the userspace interface
5 - sysfs vs. char?
6 - Documentation/ABI/ needs to be added
7 - put the sample .txt files and README file somewhere.
8
9Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
10Cc: Jakub Schmidtke <sjakub@gmail.com>
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
new file mode 100644
index 000000000000..666a186e212b
--- /dev/null
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -0,0 +1,745 @@
1/*
2 * Asus OLED USB driver
3 *
4 * Copyright (C) 2007,2008 Jakub Schmidtke (sjakub@gmail.com)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 *
22 *
23 * This module is based on usbled and asus-laptop modules.
24 *
25 *
26 * Asus OLED support is based on asusoled program taken from
27 * https://launchpad.net/asusoled/.
28 *
29 *
30 */
31
32#include <linux/kernel.h>
33#include <linux/errno.h>
34#include <linux/init.h>
35#include <linux/slab.h>
36#include <linux/module.h>
37#include <linux/usb.h>
38#include <linux/platform_device.h>
39#include <linux/ctype.h>
40
41#define ASUS_OLED_VERSION "0.04-dev"
42#define ASUS_OLED_NAME "asus-oled"
43#define ASUS_OLED_UNDERSCORE_NAME "asus_oled"
44
45#define ASUS_OLED_ERROR "Asus OLED Display Error: "
46
47#define ASUS_OLED_STATIC 's'
48#define ASUS_OLED_ROLL 'r'
49#define ASUS_OLED_FLASH 'f'
50
51#define ASUS_OLED_MAX_WIDTH 1792
52#define ASUS_OLED_DISP_HEIGHT 32
53#define ASUS_OLED_PACKET_BUF_SIZE 256
54
55MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");
56MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION);
57MODULE_LICENSE("GPL");
58
59static struct class *oled_class = 0;
60static int oled_num = 0;
61
62static uint start_off = 0;
63
64module_param(start_off, uint, 0644);
65
66MODULE_PARM_DESC(start_off, "Set to 1 to switch off OLED display after it is attached");
67
68typedef enum {
69 PACK_MODE_G1,
70 PACK_MODE_G50,
71 PACK_MODE_LAST
72} oled_pack_mode_t;
73
74struct oled_dev_desc_str {
75 uint16_t idVendor;
76 uint16_t idProduct;
77 uint16_t devWidth; // width of display
78 oled_pack_mode_t packMode; // formula to be used while packing the picture
79 const char *devDesc;
80};
81
82/* table of devices that work with this driver */
83static struct usb_device_id id_table [] = {
84 { USB_DEVICE(0x0b05, 0x1726) }, // Asus G1/G2 (and variants)
85 { USB_DEVICE(0x0b05, 0x175b) }, // Asus G50V (and possibly others - G70? G71?)
86 { },
87};
88
89/* parameters of specific devices */
90static struct oled_dev_desc_str oled_dev_desc_table [] = {
91 { 0x0b05, 0x1726, 128, PACK_MODE_G1, "G1/G2" },
92 { 0x0b05, 0x175b, 256, PACK_MODE_G50, "G50" },
93 { },
94};
95
96MODULE_DEVICE_TABLE (usb, id_table);
97
98#define SETUP_PACKET_HEADER(packet, val1, val2, val3, val4, val5, val6, val7) \
99 do { \
100 memset(packet, 0, sizeof(struct asus_oled_header)); \
101 packet->header.magic1 = 0x55; \
102 packet->header.magic2 = 0xaa; \
103 packet->header.flags = val1; \
104 packet->header.value3 = val2; \
105 packet->header.buffer1 = val3; \
106 packet->header.buffer2 = val4; \
107 packet->header.value6 = val5; \
108 packet->header.value7 = val6; \
109 packet->header.value8 = val7; \
110 } while(0);
111
112struct asus_oled_header {
113 uint8_t magic1;
114 uint8_t magic2;
115 uint8_t flags;
116 uint8_t value3;
117 uint8_t buffer1;
118 uint8_t buffer2;
119 uint8_t value6;
120 uint8_t value7;
121 uint8_t value8;
122 uint8_t padding2[7];
123} __attribute((packed));
124
125struct asus_oled_packet {
126 struct asus_oled_header header;
127 uint8_t bitmap[ASUS_OLED_PACKET_BUF_SIZE];
128} __attribute((packed));
129
130struct asus_oled_dev {
131 struct usb_device * udev;
132 uint8_t pic_mode;
133 uint16_t dev_width;
134 oled_pack_mode_t pack_mode;
135 size_t height;
136 size_t width;
137 size_t x_shift;
138 size_t y_shift;
139 size_t buf_offs;
140 uint8_t last_val;
141 size_t buf_size;
142 char *buf;
143 uint8_t enabled;
144 struct device *dev;
145};
146
147static void enable_oled(struct asus_oled_dev *odev, uint8_t enabl)
148{
149 int a;
150 int retval;
151 int act_len;
152 struct asus_oled_packet * packet;
153
154 packet = kzalloc(sizeof(struct asus_oled_packet), GFP_KERNEL);
155
156 if (!packet) {
157 dev_err(&odev->udev->dev, "out of memory\n");
158 return;
159 }
160
161 SETUP_PACKET_HEADER(packet, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
162
163 if (enabl) packet->bitmap[0] = 0xaf;
164 else packet->bitmap[0] = 0xae;
165
166 for (a=0; a<1; a++) {
167 retval = usb_bulk_msg(odev->udev,
168 usb_sndbulkpipe(odev->udev, 2),
169 packet,
170 sizeof(struct asus_oled_header) + 1,
171 &act_len,
172 -1);
173
174 if (retval)
175 dev_dbg(&odev->udev->dev, "retval = %d\n", retval);
176 }
177
178 odev->enabled = enabl;
179
180 kfree(packet);
181}
182
183static ssize_t set_enabled(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
184{
185 struct usb_interface *intf = to_usb_interface(dev);
186 struct asus_oled_dev *odev = usb_get_intfdata(intf);
187 int temp = simple_strtoul(buf, NULL, 10);
188
189 enable_oled(odev, temp);
190
191 return count;
192}
193
194static ssize_t class_set_enabled(struct device *device, struct device_attribute *attr, const char *buf, size_t count)
195{
196 struct asus_oled_dev *odev = (struct asus_oled_dev *) dev_get_drvdata(device);
197
198 int temp = simple_strtoul(buf, NULL, 10);
199
200 enable_oled(odev, temp);
201
202 return count;
203}
204
205static ssize_t get_enabled(struct device *dev, struct device_attribute *attr, char *buf)
206{
207 struct usb_interface *intf = to_usb_interface(dev);
208 struct asus_oled_dev *odev = usb_get_intfdata(intf);
209
210 return sprintf(buf, "%d\n", odev->enabled);
211}
212
213static ssize_t class_get_enabled(struct device *device, struct device_attribute *attr, char *buf)
214{
215 struct asus_oled_dev *odev = (struct asus_oled_dev *) dev_get_drvdata(device);
216
217 return sprintf(buf, "%d\n", odev->enabled);
218}
219
220static void send_packets(struct usb_device *udev, struct asus_oled_packet *packet,
221 char *buf, uint8_t p_type, size_t p_num)
222{
223 size_t i;
224 int act_len;
225
226 for (i = 0; i < p_num; i++) {
227 int retval;
228
229 switch (p_type) {
230 case ASUS_OLED_ROLL:
231 SETUP_PACKET_HEADER(packet, 0x40, 0x80, p_num, i + 1, 0x00, 0x01, 0xff);
232 break;
233 case ASUS_OLED_STATIC:
234 SETUP_PACKET_HEADER(packet, 0x10 + i, 0x80, 0x01, 0x01, 0x00, 0x01, 0x00);
235 break;
236 case ASUS_OLED_FLASH:
237 SETUP_PACKET_HEADER(packet, 0x10 + i, 0x80, 0x01, 0x01, 0x00, 0x00, 0xff);
238 break;
239 }
240
241 memcpy(packet->bitmap, buf + (ASUS_OLED_PACKET_BUF_SIZE*i), ASUS_OLED_PACKET_BUF_SIZE);
242
243 retval = usb_bulk_msg(udev,
244 usb_sndctrlpipe(udev, 2),
245 packet,
246 sizeof(struct asus_oled_packet),
247 &act_len,
248 -1);
249
250 if (retval)
251 dev_dbg(&udev->dev, "retval = %d\n", retval);
252 }
253}
254
255static void send_packet(struct usb_device *udev, struct asus_oled_packet *packet, size_t offset, size_t len, char *buf, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6){
256 int retval;
257 int act_len;
258
259 SETUP_PACKET_HEADER(packet, b1, b2, b3, b4, b5, b6, 0x00);
260 memcpy(packet->bitmap, buf + offset, len);
261
262 retval = usb_bulk_msg(udev,
263 usb_sndctrlpipe(udev, 2),
264 packet,
265 sizeof(struct asus_oled_packet),
266 &act_len,
267 -1);
268
269 if (retval)
270 dev_dbg(&udev->dev, "retval = %d\n", retval);
271}
272
273
274static void send_packets_g50(struct usb_device *udev, struct asus_oled_packet *packet, char *buf)
275{
276 send_packet(udev, packet, 0, 0x100, buf, 0x10, 0x00, 0x02, 0x01, 0x00, 0x01);
277 send_packet(udev, packet, 0x100, 0x080, buf, 0x10, 0x00, 0x02, 0x02, 0x80, 0x00);
278
279 send_packet(udev, packet, 0x180, 0x100, buf, 0x11, 0x00, 0x03, 0x01, 0x00, 0x01);
280 send_packet(udev, packet, 0x280, 0x100, buf, 0x11, 0x00, 0x03, 0x02, 0x00, 0x01);
281 send_packet(udev, packet, 0x380, 0x080, buf, 0x11, 0x00, 0x03, 0x03, 0x80, 0x00);
282}
283
284
285static void send_data(struct asus_oled_dev *odev)
286{
287 size_t packet_num = odev->buf_size / ASUS_OLED_PACKET_BUF_SIZE;
288 struct asus_oled_packet * packet;
289
290 packet = kzalloc(sizeof(struct asus_oled_packet), GFP_KERNEL);
291
292 if (!packet) {
293 dev_err(&odev->udev->dev, "out of memory\n");
294 return;
295 }
296
297 if (odev->pack_mode==PACK_MODE_G1){
298 // When sending roll-mode data the display updated only first packet.
299 // I have no idea why, but when static picture is send just before
300 // rolling picture - everything works fine.
301 if (odev->pic_mode == ASUS_OLED_ROLL)
302 send_packets(odev->udev, packet, odev->buf, ASUS_OLED_STATIC, 2);
303
304 // Only ROLL mode can use more than 2 packets.
305 if (odev->pic_mode != ASUS_OLED_ROLL && packet_num > 2)
306 packet_num = 2;
307
308 send_packets(odev->udev, packet, odev->buf, odev->pic_mode, packet_num);
309 }
310 else
311 if (odev->pack_mode==PACK_MODE_G50){
312 send_packets_g50(odev->udev, packet, odev->buf);
313 }
314
315 kfree(packet);
316}
317
318static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
319{
320 while (count-- > 0) {
321 if (val) {
322 size_t x = odev->buf_offs % odev->width;
323 size_t y = odev->buf_offs / odev->width;
324 size_t i;
325
326 x += odev->x_shift;
327 y += odev->y_shift;
328
329 switch(odev->pack_mode)
330 {
331 case PACK_MODE_G1:
332 // i = (x/128)*640 + 127 - x + (y/8)*128;
333 // This one for 128 is the same, but might be better for different widths?
334 i = (x/odev->dev_width)*640 + odev->dev_width - 1 - x + (y/8)*odev->dev_width;
335 break;
336
337 case PACK_MODE_G50:
338 i = (odev->dev_width - 1 - x)/8 + y*odev->dev_width/8;
339 break;
340
341 default:
342 i = 0;
343 printk(ASUS_OLED_ERROR "Unknown OLED Pack Mode: %d!\n", odev->pack_mode);
344 break;
345 }
346
347 if (i >= odev->buf_size) {
348 printk(ASUS_OLED_ERROR "Buffer overflow! Report a bug in the driver: offs: %d >= %d i: %d (x: %d y: %d)\n",
349 (int) odev->buf_offs, (int) odev->buf_size, (int) i, (int) x, (int) y);
350 return -EIO;
351 }
352
353 switch (odev->pack_mode)
354 {
355 case PACK_MODE_G1:
356 odev->buf[i] &= ~(1<<(y%8));
357 break;
358
359 case PACK_MODE_G50:
360 odev->buf[i] &= ~(1<<(x%8));
361 break;
362
363 default:
364 // cannot get here; stops gcc complaining
365 ;
366 }
367 }
368
369 odev->last_val = val;
370 odev->buf_offs++;
371 }
372
373 return 0;
374}
375
376static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, size_t count)
377{
378 size_t offs = 0, max_offs;
379
380 if (count < 1) return 0;
381
382 if (tolower(buf[0]) == 'b'){
383 // binary mode, set the entire memory
384
385 size_t i;
386
387 odev->buf_size = (odev->dev_width * ASUS_OLED_DISP_HEIGHT) / 8;
388
389 if (odev->buf) kfree(odev->buf);
390 odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
391
392 memset(odev->buf, 0xff, odev->buf_size);
393
394 for (i=1; i < count && i<=32*32; i++){
395 odev->buf[i-1] = buf[i];
396 odev->buf_offs = i-1;
397 }
398
399 odev->width=odev->dev_width / 8;
400 odev->height=ASUS_OLED_DISP_HEIGHT;
401 odev->x_shift=0;
402 odev->y_shift=0;
403 odev->last_val=0;
404
405 send_data(odev);
406
407 return count;
408 }
409
410 if (buf[0] == '<') {
411 size_t i;
412 size_t w = 0, h = 0;
413 size_t w_mem, h_mem;
414
415 if (count < 10 || buf[2] != ':') {
416 goto error_header;
417 }
418
419 switch(tolower(buf[1])) {
420 case ASUS_OLED_STATIC:
421 case ASUS_OLED_ROLL:
422 case ASUS_OLED_FLASH:
423 odev->pic_mode = buf[1];
424 break;
425 default:
426 printk(ASUS_OLED_ERROR "Wrong picture mode: '%c'.\n", buf[1]);
427 return -EIO;
428 break;
429 }
430
431 for (i = 3; i < count; ++i) {
432 if (buf[i] >= '0' && buf[i] <= '9') {
433 w = 10*w + (buf[i] - '0');
434
435 if (w > ASUS_OLED_MAX_WIDTH) goto error_width;
436 }
437 else if (tolower(buf[i]) == 'x') break;
438 else goto error_width;
439 }
440
441 for (++i; i < count; ++i) {
442 if (buf[i] >= '0' && buf[i] <= '9') {
443 h = 10*h + (buf[i] - '0');
444
445 if (h > ASUS_OLED_DISP_HEIGHT) goto error_height;
446 }
447 else if (tolower(buf[i]) == '>') break;
448 else goto error_height;
449 }
450
451 if (w < 1 || w > ASUS_OLED_MAX_WIDTH) goto error_width;
452
453 if (h < 1 || h > ASUS_OLED_DISP_HEIGHT) goto error_height;
454
455 if (i >= count || buf[i] != '>') goto error_header;
456
457 offs = i+1;
458
459 if (w % (odev->dev_width) != 0)
460 w_mem = (w/(odev->dev_width) + 1)*(odev->dev_width);
461 else
462 w_mem = w;
463
464 if (h < ASUS_OLED_DISP_HEIGHT)
465 h_mem = ASUS_OLED_DISP_HEIGHT;
466 else
467 h_mem = h;
468
469 odev->buf_size = w_mem * h_mem / 8;
470
471 if (odev->buf) kfree(odev->buf);
472 odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
473
474 if (odev->buf == NULL) {
475 odev->buf_size = 0;
476 printk(ASUS_OLED_ERROR "Out of memory!\n");
477 return -ENOMEM;
478 }
479
480 memset(odev->buf, 0xff, odev->buf_size);
481
482 odev->buf_offs = 0;
483 odev->width = w;
484 odev->height = h;
485 odev->x_shift = 0;
486 odev->y_shift = 0;
487 odev->last_val = 0;
488
489 if (odev->pic_mode == ASUS_OLED_FLASH) {
490 if (h < ASUS_OLED_DISP_HEIGHT/2)
491 odev->y_shift = (ASUS_OLED_DISP_HEIGHT/2 - h)/2;
492 }
493 else {
494 if (h < ASUS_OLED_DISP_HEIGHT)
495 odev->y_shift = (ASUS_OLED_DISP_HEIGHT - h)/2;
496 }
497
498 if (w < (odev->dev_width))
499 odev->x_shift = ((odev->dev_width) - w)/2;
500 }
501
502 max_offs = odev->width * odev->height;
503
504 while (offs < count && odev->buf_offs < max_offs) {
505 int ret;
506
507 if (buf[offs] == '1' || buf[offs] == '#') {
508 if ( (ret = append_values(odev, 1, 1)) < 0) return ret;
509 }
510 else if (buf[offs] == '0' || buf[offs] == ' ') {
511 if ( (ret = append_values(odev, 0, 1)) < 0) return ret;
512 }
513 else if (buf[offs] == '\n') {
514 // New line detected. Lets assume, that all characters till the end of the
515 // line were equal to the last character in this line.
516 if (odev->buf_offs % odev->width != 0)
517 if ( (ret = append_values(odev, odev->last_val,
518 odev->width - (odev->buf_offs % odev->width))) < 0) return ret;
519 }
520
521 offs++;
522 }
523
524 if (odev->buf_offs >= max_offs) send_data(odev);
525
526 return count;
527
528error_width:
529 printk(ASUS_OLED_ERROR "Wrong picture width specified.\n");
530 return -EIO;
531
532error_height:
533 printk(ASUS_OLED_ERROR "Wrong picture height specified.\n");
534 return -EIO;
535
536error_header:
537 printk(ASUS_OLED_ERROR "Wrong picture header.\n");
538 return -EIO;
539}
540
541static ssize_t set_picture(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
542{
543 struct usb_interface *intf = to_usb_interface(dev);
544
545 return odev_set_picture(usb_get_intfdata(intf), buf, count);
546}
547
548static ssize_t class_set_picture(struct device *device, struct device_attribute *attr, const char *buf, size_t count)
549{
550 return odev_set_picture((struct asus_oled_dev *) dev_get_drvdata(device), buf, count);
551}
552
553#define ASUS_OLED_DEVICE_ATTR(_file) dev_attr_asus_oled_##_file
554
555static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO, get_enabled, set_enabled);
556static DEVICE_ATTR(asus_oled_picture, S_IWUGO , NULL, set_picture);
557
558static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO, class_get_enabled, class_set_enabled);
559static DEVICE_ATTR(picture, S_IWUGO, NULL, class_set_picture);
560
561static int asus_oled_probe(struct usb_interface *interface, const struct usb_device_id *id)
562{
563 struct usb_device *udev = interface_to_usbdev(interface);
564 struct asus_oled_dev *odev = NULL;
565 int retval = -ENOMEM;
566 uint16_t dev_width = 0;
567 oled_pack_mode_t pack_mode = PACK_MODE_LAST;
568 const struct oled_dev_desc_str * dev_desc = oled_dev_desc_table;
569 const char *desc = 0;
570
571 if (id == 0) {
572 // Even possible? Just to make sure...
573 dev_err(&interface->dev, "No usb_device_id provided!\n");
574 return -ENODEV;
575 }
576
577 for (; dev_desc->idVendor; dev_desc++)
578 {
579 if (dev_desc->idVendor == id->idVendor
580 && dev_desc->idProduct == id->idProduct)
581 {
582 dev_width = dev_desc->devWidth;
583 desc = dev_desc->devDesc;
584 pack_mode = dev_desc->packMode;
585 break;
586 }
587 }
588
589 if ( !desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) {
590 dev_err(&interface->dev, "Missing or incomplete device description!\n");
591 return -ENODEV;
592 }
593
594 odev = kzalloc(sizeof(struct asus_oled_dev), GFP_KERNEL);
595
596 if (odev == NULL) {
597 dev_err(&interface->dev, "Out of memory\n");
598 return -ENOMEM;
599 }
600
601 odev->udev = usb_get_dev(udev);
602 odev->pic_mode = ASUS_OLED_STATIC;
603 odev->dev_width = dev_width;
604 odev->pack_mode = pack_mode;
605 odev->height = 0;
606 odev->width = 0;
607 odev->x_shift = 0;
608 odev->y_shift = 0;
609 odev->buf_offs = 0;
610 odev->buf_size = 0;
611 odev->last_val = 0;
612 odev->buf = NULL;
613 odev->enabled = 1;
614 odev->dev = 0;
615
616 usb_set_intfdata (interface, odev);
617
618 if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled)))) {
619 goto err_files;
620 }
621
622 if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture)))) {
623 goto err_files;
624 }
625
626 odev->dev = device_create(oled_class, &interface->dev, MKDEV(0,0),
627 NULL,"oled_%d", ++oled_num);
628
629 if (IS_ERR(odev->dev)) {
630 retval = PTR_ERR(odev->dev);
631 goto err_files;
632 }
633
634 dev_set_drvdata(odev->dev, odev);
635
636 if ( (retval = device_create_file(odev->dev, &dev_attr_enabled))) {
637 goto err_class_enabled;
638 }
639
640 if ( (retval = device_create_file(odev->dev, &dev_attr_picture))) {
641 goto err_class_picture;
642 }
643
644 dev_info(&interface->dev, "Attached Asus OLED device: %s [width %u, pack_mode %d]\n", desc, odev->dev_width, odev->pack_mode);
645
646 if (start_off)
647 enable_oled(odev, 0);
648
649 return 0;
650
651err_class_picture:
652 device_remove_file(odev->dev, &dev_attr_picture);
653
654err_class_enabled:
655 device_remove_file(odev->dev, &dev_attr_enabled);
656 device_unregister(odev->dev);
657
658err_files:
659 device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
660 device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
661
662 usb_set_intfdata (interface, NULL);
663 usb_put_dev(odev->udev);
664 kfree(odev);
665
666 return retval;
667}
668
669static void asus_oled_disconnect(struct usb_interface *interface)
670{
671 struct asus_oled_dev *odev;
672
673 odev = usb_get_intfdata (interface);
674 usb_set_intfdata (interface, NULL);
675
676 device_remove_file(odev->dev, &dev_attr_picture);
677 device_remove_file(odev->dev, &dev_attr_enabled);
678 device_unregister(odev->dev);
679
680 device_remove_file(&interface->dev, & ASUS_OLED_DEVICE_ATTR(picture));
681 device_remove_file(&interface->dev, & ASUS_OLED_DEVICE_ATTR(enabled));
682
683 usb_put_dev(odev->udev);
684
685 if (odev->buf) kfree(odev->buf);
686
687 kfree(odev);
688
689 dev_info(&interface->dev, "Disconnected Asus OLED device\n");
690}
691
692static struct usb_driver oled_driver = {
693 .name = ASUS_OLED_NAME,
694 .probe = asus_oled_probe,
695 .disconnect = asus_oled_disconnect,
696 .id_table = id_table,
697};
698
699static ssize_t version_show(struct class *dev, char *buf)
700{
701 return sprintf(buf, ASUS_OLED_UNDERSCORE_NAME " %s\n", ASUS_OLED_VERSION);
702}
703
704static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
705
706static int __init asus_oled_init(void)
707{
708 int retval = 0;
709 oled_class = class_create(THIS_MODULE, ASUS_OLED_UNDERSCORE_NAME);
710
711 if (IS_ERR(oled_class)) {
712 err("Error creating " ASUS_OLED_UNDERSCORE_NAME " class");
713 return PTR_ERR(oled_class);
714 }
715
716 if ((retval = class_create_file(oled_class, &class_attr_version))) {
717 err("Error creating class version file");
718 goto error;
719 }
720
721 retval = usb_register(&oled_driver);
722
723 if (retval) {
724 err("usb_register failed. Error number %d", retval);
725 goto error;
726 }
727
728 return retval;
729
730error:
731 class_destroy(oled_class);
732 return retval;
733}
734
735static void __exit asus_oled_exit(void)
736{
737 class_remove_file(oled_class, &class_attr_version);
738 class_destroy(oled_class);
739
740 usb_deregister(&oled_driver);
741}
742
743module_init (asus_oled_init);
744module_exit (asus_oled_exit);
745
diff --git a/drivers/staging/asus_oled/linux.txt b/drivers/staging/asus_oled/linux.txt
new file mode 100644
index 000000000000..dc758b0eb379
--- /dev/null
+++ b/drivers/staging/asus_oled/linux.txt
@@ -0,0 +1,33 @@
1<s:74x32>
20
30
400000000000000000000000000000000000000000000000000000000000000000000000000
500000000000000000000000000000000000000000000000000000000000000000000000000
600000000000000000000000000000000000000000000000000000000000000000000000000
700000000000000000000000000000000000000000000000000000000000000000000000000
801111111111000000000000000000000000000000000000000000000000000000000000000
900011111100000000000000111000000000000000000000000000000000000000000000000
1000001111000000000000000111000000000000000000000000000000000000000000000000
1100001111000000000000000111000000000000000000000000000000000000000000000000
1200001111000000000000000000000000000000000000000000000000000000000000000000
1300001111000000000000000000000000000000000000000000000000000000000000000000
1400001111000000000000011100001111111111100000111110011111100011111101111000
1500001111000000000000111110000011111000111000111110000111100001111000110000
1600001111000000000001101110000011111000111000001111000111100000111100100000
1700001111000000000001001110000011110000111100001111000111100000111101100000
1800001111000000000100001110000011110000111100001111000111100000011111000000
1900001111000000000100011110000011110000111100001111000111100000001111000000
2000001111000000000100011110000011110000111100001111000111100000001111000000
2100001111000000000100011100100011110000111100001111000111100000001111100000
2200001111000000001100111100100011110000111100001111000111100000001111110000
2300001111000000001100111101100011110000111100001111000111100000011011110000
2400001111000000011100111101000011110000111100001111000111100000010001111000
2500011111000001111100111011000011110000111100001111001111100000110000111100
2611111111111111111100011110001111111011111110000111110111111011111011111110
2700000000000000000000000000000000000000000000000000000000000000000000000000
2800000000000000000000000000000000000000000000000000000000000000000000000000
2900000000000000000000000000000000000000000000000000000000000000000000000000
300
310
320
330
diff --git a/drivers/staging/asus_oled/linux_f.txt b/drivers/staging/asus_oled/linux_f.txt
new file mode 100644
index 000000000000..b4bb85cc6ebb
--- /dev/null
+++ b/drivers/staging/asus_oled/linux_f.txt
@@ -0,0 +1,18 @@
1<f:128x16>
200000000000000000000000000000000001111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000
300000000000000000000000000000000000011110000000000001110000000000000000000000000000000000000000000000000000000000000000000000000
400000000000000000000000000000000000011110000000000001110000000000000000000000000000000000000000000000000000000000000000000000000
500000000000000000000000000000000000011110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
600000000000000000000000000000000000011110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
700000000000000000000000000000000000011110000000000011000111111111100001111001111100111110111000000000000000000000000000000000000
800000000000000000000000000000000000011110000000000111100001111000110001111000111100011100010000000000000000000000000000000000000
900000000000000000000000000000000000011110000000001011100001111000111000111100111100001110110000000000000000000000000000000000000
1000000000000000000000000000000000000011110000000000011100001110000111000111100111100001111100000000000000000000000000000000000000
1100000000000000000000000000000000000011110000000100011100001110000111000111100111100000111100000000000000000000000000000000000000
1200000000000000000000000000000000000011110000000100011100001110000111000111100111100000111100000000000000000000000000000000000000
1300000000000000000000000000000000000011110000000100111001001110000111000111100111100000111110000000000000000000000000000000000000
1400000000000000000000000000000000000011110000001100111011001110000111000111100111100000111110000000000000000000000000000000000000
1500000000000000000000000000000000000011110000001100111010001110000111000111100111100000100111000000000000000000000000000000000000
1600000000000000000000000000000000000011110000111100110110001110000111000111100111100001000011100000000000000000000000000000000000
1700000000000000000000000000000000001111111111111100111100111111011111100011110111110111101111110000000000000000000000000000000000
18
diff --git a/drivers/staging/asus_oled/linux_fr.txt b/drivers/staging/asus_oled/linux_fr.txt
new file mode 100644
index 000000000000..f88e2b3bdd1b
--- /dev/null
+++ b/drivers/staging/asus_oled/linux_fr.txt
@@ -0,0 +1,33 @@
1<f:128x32>
200000000000000000000000000000000001111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000
300000000000000000000000000000000000011110000000000001110000000000000000000000000000000000000000000000000000000000000000000000000
400000000000000000000000000000000000011110000000000001110000000000000000000000000000000000000000000000000000000000000000000000000
500000000000000000000000000000000000011110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
600000000000000000000000000000000000011110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
700000000000000000000000000000000000011110000000000011000111111111100001111001111100111110111000000000000000000000000000000000000
800000000000000000000000000000000000011110000000000111100001111000110001111000111100011100010000000000000000000000000000000000000
900000000000000000000000000000000000011110000000001011100001111000111000111100111100001110110000000000000000000000000000000000000
1000000000000000000000000000000000000011110000000000011100001110000111000111100111100001111100000000000000000000000000000000000000
1100000000000000000000000000000000000011110000000100011100001110000111000111100111100000111100000000000000000000000000000000000000
1200000000000000000000000000000000000011110000000100011100001110000111000111100111100000111100000000000000000000000000000000000000
1300000000000000000000000000000000000011110000000100111001001110000111000111100111100000111110000000000000000000000000000000000000
1400000000000000000000000000000000000011110000001100111011001110000111000111100111100000111110000000000000000000000000000000000000
1500000000000000000000000000000000000011110000001100111010001110000111000111100111100000100111000000000000000000000000000000000000
1600000000000000000000000000000000000011110000111100110110001110000111000111100111100001000011100000000000000000000000000000000000
1700000000000000000000000000000000001111111111111100111100111111011111100011110111110111101111110000000000000000000000000000000000
1800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2300000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000
2400000000000000000000000000001111000000000000000000000000000000000000000000000000000000000000001111000000000000000000000000000000
2500000000000000000000000000011111100000000000000000000000000000000000000000000000000000000000011111100000000000000000000000000000
2600000000000000000000000000011111100000000000000000000000000000000000000000000000000000000000011111100000000000000000000000000000
2700000000000000000000000000001111000000000000000000000000000000000000000000000000000000000000001111000000000000000000000000000000
2800000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000
2900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
3100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
3200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
3300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/drivers/staging/asus_oled/tux.txt b/drivers/staging/asus_oled/tux.txt
new file mode 100644
index 000000000000..9d2052854b64
--- /dev/null
+++ b/drivers/staging/asus_oled/tux.txt
@@ -0,0 +1,33 @@
1<s:32x32>
200000000000001111111000000000000
30000000000001 100000000000
4000000000001 10000000000
5000000000001 10000000000
6000000000001 10000000000
7000000000001 1 111 10000000000
8000000000001 1 1 1000000000
9000000000001 111 1000000000
10000000000001 111111 1000000000
11000000000001 111111 1000000000
12000000000001 1 1 100000000
1300000000001 11 100000000
1400000000001 11111111 10000000
150000000001 11111111 1000000
16000000001 111111111 1000000
17000000001 1111111111 100000
1800000001 11111111111 100000
1900000001 111111111111 10000
200000001 111111111111 10000
210000001 111111111111 10000
220000001 111111111111 10000
230000001 111111111111 10000
24000000011 11111111111 10000
25000011 11 11111111111 100000
260001 1111 111111111111111 1000
27001 1111111 11111111111111 1000
28001 1111111 1111111 111111 100
29001 11111111 111111 1111111 10
30001 11111111 11111 100
31001 1111111 111 11100
32000111 111 11111 11 100000
33000000111 111111111 1000000
diff --git a/drivers/staging/asus_oled/tux_r.txt b/drivers/staging/asus_oled/tux_r.txt
new file mode 100644
index 000000000000..fd81a3e84949
--- /dev/null
+++ b/drivers/staging/asus_oled/tux_r.txt
@@ -0,0 +1,33 @@
1<r:32x32>
200000000000001111111000000000000
30000000000001 100000000000
4000000000001 10000000000
5000000000001 10000000000
6000000000001 10000000000
7000000000001 1 111 10000000000
8000000000001 1 1 1000000000
9000000000001 111 1000000000
10000000000001 111111 1000000000
11000000000001 111111 1000000000
12000000000001 1 1 100000000
1300000000001 11 100000000
1400000000001 11111111 10000000
150000000001 11111111 1000000
16000000001 111111111 1000000
17000000001 1111111111 100000
1800000001 11111111111 100000
1900000001 111111111111 10000
200000001 111111111111 10000
210000001 111111111111 10000
220000001 111111111111 10000
230000001 111111111111 10000
24000000011 11111111111 10000
25000011 11 11111111111 100000
260001 1111 111111111111111 1000
27001 1111111 11111111111111 1000
28001 1111111 1111111 111111 100
29001 11111111 111111 1111111 10
30001 11111111 11111 100
31001 1111111 111 11100
32000111 111 11111 11 100000
33000000111 111111111 1000000
diff --git a/drivers/staging/asus_oled/tux_r2.txt b/drivers/staging/asus_oled/tux_r2.txt
new file mode 100644
index 000000000000..e94d84eaab0b
--- /dev/null
+++ b/drivers/staging/asus_oled/tux_r2.txt
@@ -0,0 +1,33 @@
1<r:256x32>
2000000000000000000000000000000000000000000000000000000000000011111110000000000000000000000000000000000000000000000000000000000000
30000000000000000000000000000000000000000000000000000000000001 1000000000000000000000000000000000000000000000000000000000000
4000000000000000000000000000000000000000000000000000000000001 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
5000000000000000000000000000000000000000000000000000000000001 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
6000000000000000000000000000000000000000000000000000000000001 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
7000000000000000000000000000000000000000000000000000000000001 1 111 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
8000000000000000000000000000000000000000000000000000000000001 1 1 100000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
9000000000000000000000000000000000000000000000000000000000001 111 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111100000000000000111000000000000000000000000000000000000000000000000000000000000000000000000000
10000000000000000000000000000000000000000000000000000000000001 111111 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000000000111000000000000000000000000000000000000000000000000000000000000000000000000000
11000000000000000000000000000000000000000000000000000000000001 111111 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000000000111000000000000000000000000000000000000000000000000000000000000000000000000000
12000000000000000000000000000000000000000000000000000000000001 1 1 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1300000000000000000000000000000000000000000000000000000000001 11 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1400000000000000000000000000000000000000000000000000000000001 11111111 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000000011100001111111111100000111110011111100011111101111000000000000000000000000000000
150000000000000000000000000000000000000000000000000000000001 11111111 100000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000000111110000011111000111000111110000111100001111000110000000000000000000000000000000
16000000000000000000000000000000000000000000000000000000001 111111111 100000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000001101110000011111000111000001111000111100000111100100000000000000000000000000000000
17000000000000000000000000000000000000000000000000000000001 1111111111 10000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000001001110000011110000111100001111000111100000111101100000000000000000000000000000000
1800000000000000000000000000000000000000000000000000000001 11111111111 10000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000100001110000011110000111100001111000111100000011111000000000000000000000000000000000
1900000000000000000000000000000000000000000000000000000001 111111111111 10000000000000000000000000000000000000000000000000000000000000000000000000000000000011110000000001000111100000111100001111000011110001111000000011110000000
200000000000000000000000000000000000000000000000000000001 111111111111 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000100011110000011110000111100001111000111100000001111000000
210000000000000000000000000000000000000000000000000000001 111111111111 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000100011100100011110000111100001111000111100000001111100000000000000000000000000000000
220000000000000000000000000000000000000000000000000000001 111111111111 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000001100111100100011110000111100001111000111100000001111110000000000000000000000000000000
230000000000000000000000000000000000000000000000000000001 111111111111 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000001100111101100011110000111100001111000111100000011011110000000000000000000000000000000
24000000000000000000000000000000000000000000000000000000011 11111111111 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000011100111101000011110000111100001111000111100000010001111000000000000000000000000000000
25000000000000000000000000000000000000000000000000000011 11 11111111111 10000000000000000000000000000000000000000000000000000000000000000000000000000000000011111000001111100111011000011110000111100001111001111100000110000111100000000000000000000000000000
260000000000000000000000000000000000000000000000000001 1111 111111111111111 100000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111100011110001111111011111110000111110111111011111011111110000000000000000000000000000
27000000000000000000000000000000000000000000000000001 1111111 11111111111111 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
28000000000000000000000000000000000000000000000000001 1111111 1111111 111111 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
29000000000000000000000000000000000000000000000000001 11111111 111111 1111111 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
30000000000000000000000000000000000000000000000000001 11111111 11111 1000000000000000000000000000000000000000000000000000
31000000000000000000000000000000000000000000000000001 1111111 111 111000000000000000000000000000000000000000000000000000
32000000000000000000000000000000000000000000000000000111 111 11111 11 10
33000000000000000000000000000000000000000000000000000000111 111111111 10
diff --git a/drivers/staging/asus_oled/zig.txt b/drivers/staging/asus_oled/zig.txt
new file mode 100644
index 000000000000..31573d8f799a
--- /dev/null
+++ b/drivers/staging/asus_oled/zig.txt
@@ -0,0 +1,33 @@
1<r:128x32>
210000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000001
301000000000000000000000000000000000000000000000000000000000000100100000000000000000000000000000000000000000000000000000000000010
400100000000000000000000000000000000000000000000000000000000001000010000000000000000000000000000000000000000000000000000000000100
500010000000000000000000000000000000000000000000000000000000010000001000000000000000000000000000000000000000000000000000000001000
600001000000000000000000000000000000000000000000000000000000100000000100000000000000000000000000000000000000000000000000000010000
700000100000000000000000000000000000000000000000000000000001000000000010000000000000000000000000000000000000000000000000000100000
800000010000000000000000000000000000000000000000000000000010000000000001000000000000000000000000000000000000000000000000001000000
900000001000000000000000000000000000000000000000000000000100000000000000100000000000000000000000000000000000000000000000010000000
1000000000100000000000000000000000000000000000000000000001000000000000000010000000000000000000000000000000000000000000000100000000
1100000000010000000000000000000000000000000000000000000010000000000000000001000000000000000000000000000000000000000000001000000000
1200000000001000000000000000000000000000000000000000000100000000000000000000100000000000000000000000000000000000000000010000000000
1300000000000100000000000000000000000000000000000000001000000000000000000000010000000000000000000000000000000000000000100000000000
1400000000000010000000000000000000000000000000000000010000000000000000000000001000000000000000000000000000000000000001000000000000
1500000000000001000000000000000000000000000000000000100000000000000000000000000100000000000000000000000000000000000010000000000000
1600000000000000100000000000000000000000000000000001000000000000000000000000000010000000000000000000000000000000000100000000000000
1700000000000000010000000000000000000000000000000010000000000000000000000000000001000000000000000000000000000000001000000000000000
1800000000000000001000000000000000000000000000000100000000000000000000000000000000100000000000000000000000000000010000000000000000
1900000000000000000100000000000000000000000000001000000000000000000000000000000000010000000000000000000000000000100000000000000000
2000000000000000000010000000000000000000000000010000000000000000000000000000000000001000000000000000000000000001000000000000000000
2100000000000000000001000000000000000000000000100000000000000000000000000000000000000100000000000000000000000010000000000000000000
2200000000000000000000100000000000000000000001000000000000000000000000000000000000000010000000000000000000000100000000000000000000
2300000000000000000000010000000000000000000010000000000000000000000000000000000000000001000000000000000000001000000000000000000000
2400000000000000000000001000000000000000000100000000000000000000000000000000000000000000100000000000000000010000000000000000000000
2500000000000000000000000100000000000000001000000000000000000000000000000000000000000000010000000000000000100000000000000000000000
2600000000000000000000000010000000000000010000000000000000000000000000000000000000000000001000000000000001000000000000000000000000
2700000000000000000000000001000000000000100000000000000000000000000000000000000000000000000100000000000010000000000000000000000000
2800000000000000000000000000100000000001000000000000000000000000000000000000000000000000000010000000000100000000000000000000000000
2900000000000000000000000000010000000010000000000000000000000000000000000000000000000000000001000000001000000000000000000000000000
3000000000000000000000000000001000000100000000000000000000000000000000000000000000000000000000100000010000000000000000000000000000
3100000000000000000000000000000100001000000000000000000000000000000000000000000000000000000000010000100000000000000000000000000000
3200000000000000000000000000000010010000000000000000000000000000000000000000000000000000000000001001000000000000000000000000000000
3300000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000