Lines Matching +full:odd +full:- +full:numbered

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * DRM driver for Pervasive Displays RePaper branded e-ink panels
5 * Copyright 2013-2017 Pervasive Displays, Inc.
52 enum repaper_stage { /* Image pixel -> Display pixel */
53 REPAPER_COMPENSATE, /* B -> W, W -> B (Current Image) */
54 REPAPER_WHITE, /* B -> N, W -> W (Current Image) */
55 REPAPER_INVERSE, /* B -> N, W -> B (New Image) */
56 REPAPER_NORMAL /* B -> B, W -> W (New Image) */
112 return -ENOMEM; in repaper_spi_transfer()
122 ret = -ENOMEM; in repaper_spi_transfer()
130 ret = -ENOMEM; in repaper_spi_transfer()
200 /* pixels on display are numbered from 1 so even is actually bits 1,3,5,... */
207 for (b = 0; b < (epd->width / 8); b++) { in repaper_even_pixels()
219 case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */ in repaper_even_pixels()
222 case REPAPER_WHITE: /* B -> N, W -> W (Current) */ in repaper_even_pixels()
225 case REPAPER_INVERSE: /* B -> N, W -> B (New) */ in repaper_even_pixels()
228 case REPAPER_NORMAL: /* B -> B, W -> W (New) */ in repaper_even_pixels()
246 /* pixels on display are numbered from 1 so odd is actually bits 0,2,4,... */
253 for (b = epd->width / 8; b > 0; b--) { in repaper_odd_pixels()
255 u8 pixels = data[b - 1] & 0x55; in repaper_odd_pixels()
259 pixel_mask = (mask[b - 1] ^ pixels) & 0x55; in repaper_odd_pixels()
264 case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */ in repaper_odd_pixels()
267 case REPAPER_WHITE: /* B -> N, W -> W (Current) */ in repaper_odd_pixels()
270 case REPAPER_INVERSE: /* B -> N, W -> B (New) */ in repaper_odd_pixels()
273 case REPAPER_NORMAL: /* B -> B, W -> W (New) */ in repaper_odd_pixels()
286 /* interleave bits: (byte)76543210 -> (16 bit).7.6.5.4.3.2.1 */
296 /* pixels on display are numbered from 1 */
303 for (b = epd->width / 8; b > 0; b--) { in repaper_all_pixels()
305 u16 pixels = repaper_interleave_bits(data[b - 1]); in repaper_all_pixels()
309 pixel_mask = repaper_interleave_bits(mask[b - 1]); in repaper_all_pixels()
316 case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */ in repaper_all_pixels()
319 case REPAPER_WHITE: /* B -> N, W -> W (Current) */ in repaper_all_pixels()
322 case REPAPER_INVERSE: /* B -> N, W -> B (New) */ in repaper_all_pixels()
325 case REPAPER_NORMAL: /* B -> B, W -> W (New) */ in repaper_all_pixels()
345 u8 *p = epd->line_buffer; in repaper_one_line()
348 repaper_spi_mosi_low(epd->spi); in repaper_one_line()
350 if (epd->pre_border_byte) in repaper_one_line()
353 if (epd->middle_scan) { in repaper_one_line()
358 for (b = epd->bytes_per_scan; b > 0; b--) { in repaper_one_line()
359 if (line / 4 == b - 1) in repaper_one_line()
369 * even scan line, but as lines on display are numbered from 1, in repaper_one_line()
372 for (b = 0; b < epd->bytes_per_scan; b++) { in repaper_one_line()
383 * odd scan line, but as lines on display are numbered from 1, in repaper_one_line()
386 for (b = epd->bytes_per_scan; b > 0; b--) { in repaper_one_line()
387 if (0 == (line & 0x01) && line / 8 == b - 1) in repaper_one_line()
394 switch (epd->border_byte) { in repaper_one_line()
416 repaper_write_buf(epd->spi, 0x0a, epd->line_buffer, in repaper_one_line()
417 p - epd->line_buffer); in repaper_one_line()
420 repaper_write_val(epd->spi, 0x02, 0x07); in repaper_one_line()
422 repaper_spi_mosi_low(epd->spi); in repaper_one_line()
430 for (line = 0; line < epd->height; line++) in repaper_frame_fixed()
440 for (line = 0; line < epd->height; line++) { in repaper_frame_data()
442 &image[line * (epd->width / 8)], in repaper_frame_data()
446 for (line = 0; line < epd->height; line++) { in repaper_frame_data()
447 size_t n = line * epd->width / 8; in repaper_frame_data()
459 u64 end = start + (epd->factored_stage_time * 1000 * 1000); in repaper_frame_fixed_repeat()
470 u64 end = start + (epd->factored_stage_time * 1000 * 1000); in repaper_frame_data_repeat()
482 if (!epd->thermal) in repaper_get_temperature()
485 ret = thermal_zone_get_temp(epd->thermal, &temperature); in repaper_get_temperature()
487 DRM_DEV_ERROR(&epd->spi->dev, "Failed to get temperature (%d)\n", ret); in repaper_get_temperature()
493 if (temperature <= -10) in repaper_get_temperature()
495 else if (temperature <= -5) in repaper_get_temperature()
510 epd->factored_stage_time = epd->stage_time * factor10x / 10; in repaper_get_temperature()
517 struct repaper_epd *epd = drm_to_epd(fb->dev); in repaper_fb_dirty()
524 if (!drm_dev_enter(fb->dev, &idx)) in repaper_fb_dirty()
525 return -ENODEV; in repaper_fb_dirty()
529 clip.x2 = fb->width; in repaper_fb_dirty()
531 clip.y2 = fb->height; in repaper_fb_dirty()
535 DRM_DEBUG("Flushing [FB:%d] st=%ums\n", fb->base.id, in repaper_fb_dirty()
536 epd->factored_stage_time); in repaper_fb_dirty()
538 buf = kmalloc(fb->width * fb->height / 8, GFP_KERNEL); in repaper_fb_dirty()
540 ret = -ENOMEM; in repaper_fb_dirty()
549 iosys_map_set_vaddr(&vmap, dma_obj->vaddr); in repaper_fb_dirty()
554 if (epd->partial) { in repaper_fb_dirty()
555 repaper_frame_data_repeat(epd, buf, epd->current_frame, in repaper_fb_dirty()
557 } else if (epd->cleared) { in repaper_fb_dirty()
558 repaper_frame_data_repeat(epd, epd->current_frame, NULL, in repaper_fb_dirty()
560 repaper_frame_data_repeat(epd, epd->current_frame, NULL, in repaper_fb_dirty()
565 epd->partial = true; in repaper_fb_dirty()
567 /* Clear display (anything -> white) */ in repaper_fb_dirty()
579 epd->cleared = true; in repaper_fb_dirty()
580 epd->partial = true; in repaper_fb_dirty()
583 memcpy(epd->current_frame, buf, fb->width * fb->height / 8); in repaper_fb_dirty()
589 if (epd->pre_border_byte) { in repaper_fb_dirty()
592 for (x = 0; x < (fb->width / 8); x++) in repaper_fb_dirty()
593 if (buf[x + (fb->width * (fb->height - 1) / 8)]) { in repaper_fb_dirty()
595 epd->current_frame, in repaper_fb_dirty()
612 gpiod_set_value_cansleep(epd->reset, 0); in power_off()
613 gpiod_set_value_cansleep(epd->panel_on, 0); in power_off()
614 if (epd->border) in power_off()
615 gpiod_set_value_cansleep(epd->border, 0); in power_off()
618 repaper_spi_mosi_low(epd->spi); in power_off()
621 gpiod_set_value_cansleep(epd->discharge, 1); in power_off()
623 gpiod_set_value_cansleep(epd->discharge, 0); in power_off()
629 struct drm_crtc *crtc = &pipe->crtc; in repaper_pipe_mode_valid()
630 struct repaper_epd *epd = drm_to_epd(crtc->dev); in repaper_pipe_mode_valid()
632 return drm_crtc_helper_mode_valid_fixed(crtc, mode, epd->mode); in repaper_pipe_mode_valid()
639 struct repaper_epd *epd = drm_to_epd(pipe->crtc.dev); in repaper_pipe_enable()
640 struct spi_device *spi = epd->spi; in repaper_pipe_enable()
641 struct device *dev = &spi->dev; in repaper_pipe_enable()
645 if (!drm_dev_enter(pipe->crtc.dev, &idx)) in repaper_pipe_enable()
651 gpiod_set_value_cansleep(epd->reset, 0); in repaper_pipe_enable()
652 gpiod_set_value_cansleep(epd->panel_on, 0); in repaper_pipe_enable()
653 gpiod_set_value_cansleep(epd->discharge, 0); in repaper_pipe_enable()
654 if (epd->border) in repaper_pipe_enable()
655 gpiod_set_value_cansleep(epd->border, 0); in repaper_pipe_enable()
659 gpiod_set_value_cansleep(epd->panel_on, 1); in repaper_pipe_enable()
665 gpiod_set_value_cansleep(epd->reset, 1); in repaper_pipe_enable()
666 if (epd->border) in repaper_pipe_enable()
667 gpiod_set_value_cansleep(epd->border, 1); in repaper_pipe_enable()
669 gpiod_set_value_cansleep(epd->reset, 0); in repaper_pipe_enable()
671 gpiod_set_value_cansleep(epd->reset, 1); in repaper_pipe_enable()
675 for (i = 100; i > 0; i--) { in repaper_pipe_enable()
676 if (!gpiod_get_value_cansleep(epd->busy)) in repaper_pipe_enable()
715 repaper_write_buf(spi, 0x01, epd->channel_select, 8); in repaper_pipe_enable()
732 /* Charge pump positive voltage on - VGH/VDL on */ in repaper_pipe_enable()
736 /* Charge pump negative voltage on - VGL/VDL on */ in repaper_pipe_enable()
740 /* Charge pump Vcom on - Vcom driver on */ in repaper_pipe_enable()
770 epd->partial = false; in repaper_pipe_enable()
777 struct repaper_epd *epd = drm_to_epd(pipe->crtc.dev); in repaper_pipe_disable()
778 struct spi_device *spi = epd->spi; in repaper_pipe_disable()
791 for (line = 0; line < epd->height; line++) in repaper_pipe_disable()
796 if (epd->border) { in repaper_pipe_disable()
801 gpiod_set_value_cansleep(epd->border, 0); in repaper_pipe_disable()
803 gpiod_set_value_cansleep(epd->border, 1); in repaper_pipe_disable()
834 struct drm_plane_state *state = pipe->plane.state; in repaper_pipe_update()
838 if (!pipe->crtc.state->active) in repaper_pipe_update()
842 repaper_fb_dirty(state->fb, &fmtcnv_state); in repaper_pipe_update()
856 struct repaper_epd *epd = drm_to_epd(connector->dev); in repaper_connector_get_modes()
858 return drm_connector_helper_get_modes_fixed(connector, epd->mode); in repaper_connector_get_modes()
919 .desc = "Pervasive Displays RePaper e-ink panels",
946 struct device *dev = &spi->dev; in repaper_probe()
960 model = (enum repaper_model)spi_id->driver_data; in repaper_probe()
964 if (!dev->coherent_dma_mask) { in repaper_probe()
977 drm = &epd->drm; in repaper_probe()
982 drm->mode_config.funcs = &repaper_mode_config_funcs; in repaper_probe()
984 epd->spi = spi; in repaper_probe()
986 epd->panel_on = devm_gpiod_get(dev, "panel-on", GPIOD_OUT_LOW); in repaper_probe()
987 if (IS_ERR(epd->panel_on)) { in repaper_probe()
988 ret = PTR_ERR(epd->panel_on); in repaper_probe()
989 if (ret != -EPROBE_DEFER) in repaper_probe()
990 DRM_DEV_ERROR(dev, "Failed to get gpio 'panel-on'\n"); in repaper_probe()
994 epd->discharge = devm_gpiod_get(dev, "discharge", GPIOD_OUT_LOW); in repaper_probe()
995 if (IS_ERR(epd->discharge)) { in repaper_probe()
996 ret = PTR_ERR(epd->discharge); in repaper_probe()
997 if (ret != -EPROBE_DEFER) in repaper_probe()
1002 epd->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); in repaper_probe()
1003 if (IS_ERR(epd->reset)) { in repaper_probe()
1004 ret = PTR_ERR(epd->reset); in repaper_probe()
1005 if (ret != -EPROBE_DEFER) in repaper_probe()
1010 epd->busy = devm_gpiod_get(dev, "busy", GPIOD_IN); in repaper_probe()
1011 if (IS_ERR(epd->busy)) { in repaper_probe()
1012 ret = PTR_ERR(epd->busy); in repaper_probe()
1013 if (ret != -EPROBE_DEFER) in repaper_probe()
1018 if (!device_property_read_string(dev, "pervasive,thermal-zone", in repaper_probe()
1020 epd->thermal = thermal_zone_get_zone_by_name(thermal_zone); in repaper_probe()
1021 if (IS_ERR(epd->thermal)) { in repaper_probe()
1023 return PTR_ERR(epd->thermal); in repaper_probe()
1030 epd->channel_select = repaper_e1144cs021_cs; in repaper_probe()
1031 epd->stage_time = 480; in repaper_probe()
1032 epd->bytes_per_scan = 96 / 4; in repaper_probe()
1033 epd->middle_scan = true; /* data-scan-data */ in repaper_probe()
1034 epd->pre_border_byte = false; in repaper_probe()
1035 epd->border_byte = REPAPER_BORDER_BYTE_ZERO; in repaper_probe()
1040 epd->channel_select = repaper_e1190cs021_cs; in repaper_probe()
1041 epd->stage_time = 480; in repaper_probe()
1042 epd->bytes_per_scan = 128 / 4 / 2; in repaper_probe()
1043 epd->middle_scan = false; /* scan-data-scan */ in repaper_probe()
1044 epd->pre_border_byte = false; in repaper_probe()
1045 epd->border_byte = REPAPER_BORDER_BYTE_SET; in repaper_probe()
1050 epd->channel_select = repaper_e2200cs021_cs; in repaper_probe()
1051 epd->stage_time = 480; in repaper_probe()
1052 epd->bytes_per_scan = 96 / 4; in repaper_probe()
1053 epd->middle_scan = true; /* data-scan-data */ in repaper_probe()
1054 epd->pre_border_byte = true; in repaper_probe()
1055 epd->border_byte = REPAPER_BORDER_BYTE_NONE; in repaper_probe()
1059 epd->border = devm_gpiod_get(dev, "border", GPIOD_OUT_LOW); in repaper_probe()
1060 if (IS_ERR(epd->border)) { in repaper_probe()
1061 ret = PTR_ERR(epd->border); in repaper_probe()
1062 if (ret != -EPROBE_DEFER) in repaper_probe()
1068 epd->channel_select = repaper_e2271cs021_cs; in repaper_probe()
1069 epd->stage_time = 630; in repaper_probe()
1070 epd->bytes_per_scan = 176 / 4; in repaper_probe()
1071 epd->middle_scan = true; /* data-scan-data */ in repaper_probe()
1072 epd->pre_border_byte = true; in repaper_probe()
1073 epd->border_byte = REPAPER_BORDER_BYTE_NONE; in repaper_probe()
1077 return -ENODEV; in repaper_probe()
1080 epd->mode = mode; in repaper_probe()
1081 epd->width = mode->hdisplay; in repaper_probe()
1082 epd->height = mode->vdisplay; in repaper_probe()
1083 epd->factored_stage_time = epd->stage_time; in repaper_probe()
1085 line_buffer_size = 2 * epd->width / 8 + epd->bytes_per_scan + 2; in repaper_probe()
1086 epd->line_buffer = devm_kzalloc(dev, line_buffer_size, GFP_KERNEL); in repaper_probe()
1087 if (!epd->line_buffer) in repaper_probe()
1088 return -ENOMEM; in repaper_probe()
1090 epd->current_frame = devm_kzalloc(dev, epd->width * epd->height / 8, in repaper_probe()
1092 if (!epd->current_frame) in repaper_probe()
1093 return -ENOMEM; in repaper_probe()
1095 drm->mode_config.min_width = mode->hdisplay; in repaper_probe()
1096 drm->mode_config.max_width = mode->hdisplay; in repaper_probe()
1097 drm->mode_config.min_height = mode->vdisplay; in repaper_probe()
1098 drm->mode_config.max_height = mode->vdisplay; in repaper_probe()
1100 drm_connector_helper_add(&epd->connector, &repaper_connector_hfuncs); in repaper_probe()
1101 ret = drm_connector_init(drm, &epd->connector, &repaper_connector_funcs, in repaper_probe()
1106 ret = drm_simple_display_pipe_init(drm, &epd->pipe, &repaper_pipe_funcs, in repaper_probe()
1108 NULL, &epd->connector); in repaper_probe()
1120 DRM_DEBUG_DRIVER("SPI speed: %uMHz\n", spi->max_speed_hz / 1000000); in repaper_probe()