20 #include <linux/hid.h>
26 #include <linux/module.h>
50 #define PICOLCDFB_NAME "picolcdfb"
51 #define PICOLCDFB_WIDTH (256)
52 #define PICOLCDFB_HEIGHT (64)
53 #define PICOLCDFB_SIZE (PICOLCDFB_WIDTH * PICOLCDFB_HEIGHT / 8)
55 #define PICOLCDFB_UPDATE_RATE_LIMIT 10
56 #define PICOLCDFB_UPDATE_RATE_DEFAULT 2
111 if (!report1 || report1->
maxfield != 1)
114 if (!report2 || report2->
maxfield != 1)
119 spin_unlock_irqrestore(&data->
lock, flags);
139 tdata = vbitmap + (tile * 4 +
chip) * 64;
140 for (i = 0; i < 64; i++)
148 spin_unlock_irqrestore(&data->
lock, flags);
153 static int picolcd_fb_update_tile(
u8 *vbitmap,
const u8 *
bitmap,
int bpp,
158 u8 *vdata = vbitmap + (tile * 4 +
chip) * 64;
161 for (b = 7; b >= 0; b--) {
162 const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32;
163 for (i = 0; i < 64; i++) {
165 tdata[
i] |= (bdata[i/8] >> (i % 8)) & 0x01;
168 }
else if (bpp == 8) {
169 for (b = 7; b >= 0; b--) {
170 const u8 *bdata = bitmap + (tile * 256 + chip * 8 + b * 32) * 8;
171 for (i = 0; i < 64; i++) {
173 tdata[
i] |= (bdata[
i] & 0x80) ? 0x01 : 0x00;
182 for (i = 0; i < 64; i++)
183 if (tdata[i] != vdata[i]) {
200 struct picolcd_fb_data *fbdata = data->fb_info->par;
203 static const u8 mapcmd[8] = { 0x00, 0x02, 0x00, 0x64, 0x3f, 0x00, 0x64, 0xc0 };
205 if (!report || report->
maxfield != 1)
209 for (i = 0; i < 4; i++) {
210 for (j = 0; j < report->
field[0]->maxusage; j++)
213 else if (j <
sizeof(mapcmd))
219 spin_unlock_irqrestore(&data->
lock, flags);
237 static void picolcd_fb_update(
struct fb_info *
info)
241 struct picolcd_fb_data *fbdata = info->
par;
247 if (!fbdata->ready && fbdata->picolcd)
249 spin_unlock_irqrestore(&fbdata->lock, flags);
259 for (chip = 0; chip < 4; chip++)
260 for (tile = 0; tile < 8; tile++) {
261 if (!fbdata->force && !picolcd_fb_update_tile(
262 fbdata->vbitmap, fbdata->bitmap,
263 fbdata->bpp, chip, tile))
268 data = fbdata->picolcd;
269 spin_unlock_irqrestore(&fbdata->lock, flags);
278 data = fbdata->picolcd;
279 spin_unlock_irqrestore(&fbdata->lock, flags);
280 if (!data || picolcd_fb_send_tile(data,
281 fbdata->vbitmap, chip, tile))
284 fbdata->force =
false;
287 data = fbdata->picolcd;
288 spin_unlock_irqrestore(&fbdata->lock, flags);
299 static void picolcd_fb_fillrect(
struct fb_info *info,
310 static void picolcd_fb_copyarea(
struct fb_info *info,
335 size_t count, loff_t *ppos)
346 static int picolcd_fb_blank(
int blank,
struct fb_info *info)
352 static void picolcd_fb_destroy(
struct fb_info *info)
354 struct picolcd_fb_data *fbdata = info->
par;
372 *var = picolcdfb_var;
377 var->
green.length = 8;
378 var->
blue.length = 8;
382 var->
green.length = 1;
383 var->
blue.length = 1;
388 static int picolcd_set_par(
struct fb_info *info)
390 struct picolcd_fb_data *fbdata = info->
par;
392 if (info->
var.bits_per_pixel == fbdata->bpp)
395 if (info->
var.bits_per_pixel != 1 && info->
var.bits_per_pixel != 8)
398 o_fb = fbdata->bitmap;
404 if (info->
var.bits_per_pixel == 1) {
408 for (b = 0; b < 8; b++) {
410 p |= o_fb[i*8+
b] ? 0x01 : 0x00;
414 memcpy(o_fb, tmp_fb, PICOLCDFB_SIZE);
419 memcpy(tmp_fb, o_fb, PICOLCDFB_SIZE);
420 for (i = 0; i < PICOLCDFB_SIZE * 8; i++)
421 o_fb[i] = tmp_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00;
427 fbdata->bpp = info->
var.bits_per_pixel;
432 static struct fb_ops picolcdfb_ops = {
434 .fb_destroy = picolcd_fb_destroy,
436 .fb_write = picolcd_fb_write,
437 .fb_blank = picolcd_fb_blank,
438 .fb_fillrect = picolcd_fb_fillrect,
439 .fb_copyarea = picolcd_fb_copyarea,
440 .fb_imageblit = picolcd_fb_imageblit,
441 .fb_check_var = picolcd_fb_check_var,
442 .fb_set_par = picolcd_set_par,
447 static void picolcd_fb_deferred_io(
struct fb_info *info,
struct list_head *pagelist)
449 picolcd_fb_update(info);
452 static const struct fb_deferred_io picolcd_fb_defio = {
454 .deferred_io = picolcd_fb_deferred_io,
465 struct picolcd_fb_data *fbdata = data->fb_info->par;
466 unsigned i, fb_update_rate = fbdata->update_rate;
472 else if (i == fb_update_rate)
481 static ssize_t picolcd_fb_update_rate_store(
struct device *dev,
485 struct picolcd_fb_data *fbdata = data->fb_info->par;
489 if (count < 1 || count > 10)
492 i =
sscanf(buf,
"%u", &u);
501 fbdata->update_rate =
u;
502 data->fb_info->fbdefio->delay =
HZ / fbdata->update_rate;
506 static DEVICE_ATTR(fb_update_rate, 0666, picolcd_fb_update_rate_show,
507 picolcd_fb_update_rate_store);
514 struct picolcd_fb_data *fbdata =
NULL;
523 sizeof(
struct fb_deferred_io) +
524 sizeof(
struct picolcd_fb_data) +
525 PICOLCDFB_SIZE, dev);
527 dev_err(dev,
"failed to allocate a framebuffer\n");
531 info->fbdefio = info->
par;
532 *info->fbdefio = picolcd_fb_defio;
533 info->
par +=
sizeof(
struct fb_deferred_io);
535 info->
par += 256 *
sizeof(
u32);
536 for (i = 0; i < 256; i++)
537 palette[i] = i > 0 && i < 16 ? 0xff : 0;
539 info->
fbops = &picolcdfb_ops;
540 info->
var = picolcdfb_var;
541 info->
fix = picolcdfb_fix;
542 info->
fix.smem_len = PICOLCDFB_SIZE*8;
547 fbdata->picolcd =
data;
551 fbdata->vbitmap = info->
par +
sizeof(
struct picolcd_fb_data);
552 fbdata->bitmap =
vmalloc(PICOLCDFB_SIZE*8);
553 if (fbdata->bitmap ==
NULL) {
554 dev_err(dev,
"can't get a free page for framebuffer\n");
558 info->
fix.smem_start = (
unsigned long)fbdata->bitmap;
559 memset(fbdata->vbitmap, 0xff, PICOLCDFB_SIZE);
560 data->fb_info =
info;
564 dev_err(dev,
"failed to configure display\n");
570 dev_err(dev,
"failed to create sysfs attributes\n");
577 dev_err(dev,
"failed to register framebuffer\n");
586 data->fb_info =
NULL;
590 vfree(fbdata->bitmap);
597 struct fb_info *info = data->fb_info;
598 struct picolcd_fb_data *fbdata = info->
par;
605 fbdata->picolcd =
NULL;
606 spin_unlock_irqrestore(&fbdata->lock, flags);
613 data->fb_info =
NULL;