Lines Matching +full:cs +full:- +full:extra +full:- +full:delay
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org> *
6 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
16 #include "hid-picolcd.h"
23 * a 1-bit wide vertical line of the tile.
28 * +----------------+----------------+----------------+----------------+
30 * +----------------+----------------+----------------+----------------+
32 * +----------------+----------------+----------------+----------------+
34 * +----------------+----------------+----------------+----------------+
36 * +----------------+----------------+----------------+----------------+
98 report1 = picolcd_out_report(REPORT_LCD_CMD_DATA, data->hdev); in picolcd_fb_send_tile()
99 if (!report1 || report1->maxfield != 1) in picolcd_fb_send_tile()
100 return -ENODEV; in picolcd_fb_send_tile()
101 report2 = picolcd_out_report(REPORT_LCD_DATA, data->hdev); in picolcd_fb_send_tile()
102 if (!report2 || report2->maxfield != 1) in picolcd_fb_send_tile()
103 return -ENODEV; in picolcd_fb_send_tile()
105 spin_lock_irqsave(&data->lock, flags); in picolcd_fb_send_tile()
106 if ((data->status & PICOLCD_FAILED)) { in picolcd_fb_send_tile()
107 spin_unlock_irqrestore(&data->lock, flags); in picolcd_fb_send_tile()
108 return -ENODEV; in picolcd_fb_send_tile()
110 hid_set_field(report1->field[0], 0, chip << 2); in picolcd_fb_send_tile()
111 hid_set_field(report1->field[0], 1, 0x02); in picolcd_fb_send_tile()
112 hid_set_field(report1->field[0], 2, 0x00); in picolcd_fb_send_tile()
113 hid_set_field(report1->field[0], 3, 0x00); in picolcd_fb_send_tile()
114 hid_set_field(report1->field[0], 4, 0xb8 | tile); in picolcd_fb_send_tile()
115 hid_set_field(report1->field[0], 5, 0x00); in picolcd_fb_send_tile()
116 hid_set_field(report1->field[0], 6, 0x00); in picolcd_fb_send_tile()
117 hid_set_field(report1->field[0], 7, 0x40); in picolcd_fb_send_tile()
118 hid_set_field(report1->field[0], 8, 0x00); in picolcd_fb_send_tile()
119 hid_set_field(report1->field[0], 9, 0x00); in picolcd_fb_send_tile()
120 hid_set_field(report1->field[0], 10, 32); in picolcd_fb_send_tile()
122 hid_set_field(report2->field[0], 0, (chip << 2) | 0x01); in picolcd_fb_send_tile()
123 hid_set_field(report2->field[0], 1, 0x00); in picolcd_fb_send_tile()
124 hid_set_field(report2->field[0], 2, 0x00); in picolcd_fb_send_tile()
125 hid_set_field(report2->field[0], 3, 32); in picolcd_fb_send_tile()
130 hid_set_field(report1->field[0], 11 + i, tdata[i]); in picolcd_fb_send_tile()
132 hid_set_field(report2->field[0], 4 + i - 32, tdata[i]); in picolcd_fb_send_tile()
134 hid_hw_request(data->hdev, report1, HID_REQ_SET_REPORT); in picolcd_fb_send_tile()
135 hid_hw_request(data->hdev, report2, HID_REQ_SET_REPORT); in picolcd_fb_send_tile()
136 spin_unlock_irqrestore(&data->lock, flags); in picolcd_fb_send_tile()
149 for (b = 7; b >= 0; b--) { in picolcd_fb_update_tile()
157 for (b = 7; b >= 0; b--) { in picolcd_fb_update_tile()
180 if (data->fb_info) in picolcd_fb_refresh()
181 schedule_delayed_work(&data->fb_info->deferred_work, 0); in picolcd_fb_refresh()
187 struct hid_report *report = picolcd_out_report(REPORT_LCD_CMD, data->hdev); in picolcd_fb_reset()
188 struct picolcd_fb_data *fbdata = data->fb_info->par; in picolcd_fb_reset()
193 if (!report || report->maxfield != 1) in picolcd_fb_reset()
194 return -ENODEV; in picolcd_fb_reset()
196 spin_lock_irqsave(&data->lock, flags); in picolcd_fb_reset()
198 for (j = 0; j < report->field[0]->maxusage; j++) in picolcd_fb_reset()
200 hid_set_field(report->field[0], j, i << 2); in picolcd_fb_reset()
202 hid_set_field(report->field[0], j, mapcmd[j]); in picolcd_fb_reset()
204 hid_set_field(report->field[0], j, 0); in picolcd_fb_reset()
205 hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); in picolcd_fb_reset()
207 spin_unlock_irqrestore(&data->lock, flags); in picolcd_fb_reset()
210 memset(fbdata->vbitmap, 0, PICOLCDFB_SIZE); in picolcd_fb_reset()
211 memset(fbdata->bitmap, 0, PICOLCDFB_SIZE*fbdata->bpp); in picolcd_fb_reset()
213 fbdata->force = 1; in picolcd_fb_reset()
216 if (fbdata->ready) in picolcd_fb_reset()
217 schedule_delayed_work(&data->fb_info->deferred_work, 0); in picolcd_fb_reset()
219 fbdata->ready = 1; in picolcd_fb_reset()
229 struct picolcd_fb_data *fbdata = info->par; in picolcd_fb_update()
232 mutex_lock(&info->lock); in picolcd_fb_update()
234 spin_lock_irqsave(&fbdata->lock, flags); in picolcd_fb_update()
235 if (!fbdata->ready && fbdata->picolcd) in picolcd_fb_update()
236 picolcd_fb_reset(fbdata->picolcd, 0); in picolcd_fb_update()
237 spin_unlock_irqrestore(&fbdata->lock, flags); in picolcd_fb_update()
249 if (!fbdata->force && !picolcd_fb_update_tile( in picolcd_fb_update()
250 fbdata->vbitmap, fbdata->bitmap, in picolcd_fb_update()
251 fbdata->bpp, chip, tile)) in picolcd_fb_update()
255 spin_lock_irqsave(&fbdata->lock, flags); in picolcd_fb_update()
256 data = fbdata->picolcd; in picolcd_fb_update()
257 spin_unlock_irqrestore(&fbdata->lock, flags); in picolcd_fb_update()
258 mutex_unlock(&info->lock); in picolcd_fb_update()
261 hid_hw_wait(data->hdev); in picolcd_fb_update()
262 mutex_lock(&info->lock); in picolcd_fb_update()
265 spin_lock_irqsave(&fbdata->lock, flags); in picolcd_fb_update()
266 data = fbdata->picolcd; in picolcd_fb_update()
267 spin_unlock_irqrestore(&fbdata->lock, flags); in picolcd_fb_update()
269 fbdata->vbitmap, chip, tile)) in picolcd_fb_update()
272 fbdata->force = false; in picolcd_fb_update()
274 spin_lock_irqsave(&fbdata->lock, flags); in picolcd_fb_update()
275 data = fbdata->picolcd; in picolcd_fb_update()
276 spin_unlock_irqrestore(&fbdata->lock, flags); in picolcd_fb_update()
277 mutex_unlock(&info->lock); in picolcd_fb_update()
279 hid_hw_wait(data->hdev); in picolcd_fb_update()
283 mutex_unlock(&info->lock); in picolcd_fb_update()
294 struct picolcd_fb_data *fbdata = info->par; in picolcd_fb_destroy()
300 WARN_ON(fbdata->picolcd != NULL); in picolcd_fb_destroy()
302 vfree((u8 *)info->fix.smem_start); in picolcd_fb_destroy()
308 __u32 bpp = var->bits_per_pixel; in picolcd_fb_check_var()
309 __u32 activate = var->activate; in picolcd_fb_check_var()
311 /* only allow 1/8 bit depth (8-bit is grayscale) */ in picolcd_fb_check_var()
313 var->activate = activate; in picolcd_fb_check_var()
315 var->bits_per_pixel = 8; in picolcd_fb_check_var()
316 var->red.length = 8; in picolcd_fb_check_var()
317 var->green.length = 8; in picolcd_fb_check_var()
318 var->blue.length = 8; in picolcd_fb_check_var()
320 var->bits_per_pixel = 1; in picolcd_fb_check_var()
321 var->red.length = 1; in picolcd_fb_check_var()
322 var->green.length = 1; in picolcd_fb_check_var()
323 var->blue.length = 1; in picolcd_fb_check_var()
330 struct picolcd_fb_data *fbdata = info->par; in picolcd_set_par()
332 if (info->var.bits_per_pixel == fbdata->bpp) in picolcd_set_par()
335 if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8) in picolcd_set_par()
336 return -EINVAL; in picolcd_set_par()
338 o_fb = fbdata->bitmap; in picolcd_set_par()
339 tmp_fb = kmalloc_array(PICOLCDFB_SIZE, info->var.bits_per_pixel, in picolcd_set_par()
342 return -ENOMEM; in picolcd_set_par()
344 /* translate FB content to new bits-per-pixel */ in picolcd_set_par()
345 if (info->var.bits_per_pixel == 1) { in picolcd_set_par()
356 info->fix.visual = FB_VISUAL_MONO01; in picolcd_set_par()
357 info->fix.line_length = PICOLCDFB_WIDTH / 8; in picolcd_set_par()
362 o_fb[i] = tmp_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00; in picolcd_set_par()
363 info->fix.visual = FB_VISUAL_DIRECTCOLOR; in picolcd_set_par()
364 info->fix.line_length = PICOLCDFB_WIDTH; in picolcd_set_par()
368 fbdata->bpp = info->var.bits_per_pixel; in picolcd_set_par()
374 if (!info->par) in picolcdfb_ops_damage_range()
376 schedule_delayed_work(&info->deferred_work, 0); in picolcdfb_ops_damage_range()
381 if (!info->par) in picolcdfb_ops_damage_area()
383 schedule_delayed_work(&info->deferred_work, 0); in picolcdfb_ops_damage_area()
407 .delay = HZ / PICOLCDFB_UPDATE_RATE_DEFAULT,
419 struct picolcd_fb_data *fbdata = data->fb_info->par; in picolcd_fb_update_rate_show()
420 unsigned i, fb_update_rate = fbdata->update_rate; in picolcd_fb_update_rate_show()
429 buf[min(ret, (size_t)PAGE_SIZE)-1] = '\n'; in picolcd_fb_update_rate_show()
437 struct picolcd_fb_data *fbdata = data->fb_info->par; in picolcd_fb_update_rate_store()
442 return -EINVAL; in picolcd_fb_update_rate_store()
446 return -EINVAL; in picolcd_fb_update_rate_store()
449 return -ERANGE; in picolcd_fb_update_rate_store()
453 fbdata->update_rate = u; in picolcd_fb_update_rate_store()
454 data->fb_info->fbdefio->delay = HZ / fbdata->update_rate; in picolcd_fb_update_rate_store()
464 struct device *dev = &data->hdev->dev; in picolcd_init_framebuffer()
467 int i, error = -ENOMEM; in picolcd_init_framebuffer()
470 /* The extra memory is: in picolcd_init_framebuffer()
471 * - 256*u32 for pseudo_palette in picolcd_init_framebuffer()
472 * - struct fb_deferred_io in picolcd_init_framebuffer()
481 info->fbdefio = info->par; in picolcd_init_framebuffer()
482 *info->fbdefio = picolcd_fb_defio; in picolcd_init_framebuffer()
483 info->par += sizeof(struct fb_deferred_io); in picolcd_init_framebuffer()
484 palette = info->par; in picolcd_init_framebuffer()
485 info->par += 256 * sizeof(u32); in picolcd_init_framebuffer()
488 info->pseudo_palette = palette; in picolcd_init_framebuffer()
489 info->fbops = &picolcdfb_ops; in picolcd_init_framebuffer()
490 info->var = picolcdfb_var; in picolcd_init_framebuffer()
491 info->fix = picolcdfb_fix; in picolcd_init_framebuffer()
492 info->fix.smem_len = PICOLCDFB_SIZE*8; in picolcd_init_framebuffer()
496 info->bl_dev = data->backlight; in picolcd_init_framebuffer()
501 info->lcd_dev = data->lcd; in picolcd_init_framebuffer()
504 fbdata = info->par; in picolcd_init_framebuffer()
505 spin_lock_init(&fbdata->lock); in picolcd_init_framebuffer()
506 fbdata->picolcd = data; in picolcd_init_framebuffer()
507 fbdata->update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT; in picolcd_init_framebuffer()
508 fbdata->bpp = picolcdfb_var.bits_per_pixel; in picolcd_init_framebuffer()
509 fbdata->force = 1; in picolcd_init_framebuffer()
510 fbdata->vbitmap = info->par + sizeof(struct picolcd_fb_data); in picolcd_init_framebuffer()
511 fbdata->bitmap = vmalloc(PICOLCDFB_SIZE*8); in picolcd_init_framebuffer()
512 if (fbdata->bitmap == NULL) { in picolcd_init_framebuffer()
516 info->flags |= FBINFO_VIRTFB; in picolcd_init_framebuffer()
517 info->screen_buffer = fbdata->bitmap; in picolcd_init_framebuffer()
518 info->fix.smem_start = (unsigned long)fbdata->bitmap; in picolcd_init_framebuffer()
519 memset(fbdata->vbitmap, 0xff, PICOLCDFB_SIZE); in picolcd_init_framebuffer()
520 data->fb_info = info; in picolcd_init_framebuffer()
546 data->fb_info = NULL; in picolcd_init_framebuffer()
550 vfree(fbdata->bitmap); in picolcd_init_framebuffer()
557 struct fb_info *info = data->fb_info; in picolcd_exit_framebuffer()
564 device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate); in picolcd_exit_framebuffer()
565 fbdata = info->par; in picolcd_exit_framebuffer()
568 spin_lock_irqsave(&fbdata->lock, flags); in picolcd_exit_framebuffer()
569 fbdata->picolcd = NULL; in picolcd_exit_framebuffer()
570 spin_unlock_irqrestore(&fbdata->lock, flags); in picolcd_exit_framebuffer()
572 /* make sure there is no running update - thus that fbdata->picolcd in picolcd_exit_framebuffer()
575 flush_delayed_work(&info->deferred_work); in picolcd_exit_framebuffer()
577 data->fb_info = NULL; in picolcd_exit_framebuffer()